文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

KNN算法的Python实现

2023-01-31 07:11

关注

# KNN算法思路:

#-----------------------------------------------------#

#step1:读入数据,存储为链表

#step2:数据预处理,包括缺失值处理、归一化等

#step3:设置K值

#step4:计算待测样本与所有样本的距离(二值、序数、连续)

#step5:投票决定待测样本的类别

#step6:利用测试集测试正确率

#-----------------------------------------------------#

注:因为是python的初学者,可能很多高级的用法还不会,所以把python代码写的像C还请大家不要吐槽。同时希望大家指出其中的错误和有待提高的地方,大家一起进步才是最棒的。

说明:数据集采自著名UCI数据集库 http://archive.ics.uci.edu/ml/datasets/Adult

# Author :CWX
# Date :2015/9/1
# Function: A classifier which using KNN algorithm 

import math

attributes = {"age":0,"workclass":1,"fnlwg":2,"education":3,"education-num":4,
			 "marital-status":5,"occupation":6,"relationship":7,"race":8,
			 "sex":9,"capital-gain":10,"capital-loss":11,"hours-per-week":12,
			 "native-country":13,"salary":14
			}

def read_txt(filename):
#read data and convert it into list 
	items = []
	fp = open(filename,'r')
	lines = fp.readlines()
	for line in lines:
		line = line.strip('\n')
		items.append(line)
	fp.close()

	i = 0
	b = []
	for i in range(len(items)):
		b.append(items[i].split(','))
	return b

def computeNa(items):
# detect missing value in list and handle it
# items - an whole list 
	for item in items[:]:
		if item.count(' ?') > 0:
			items.remove(item)
		# if item.count(' ?') >= -1:
		# 	items.remove(item)
	return items

def disCal(lst1,lst2,type):
# calculting distance between lst1 and lst2
	distance = 0;
	if type == "Manhattan" or type == "manhattan":
		for i in range(len(lst2) - 1):
			distance += abs(lst1[i] - lst2[i])
	elif type == "Elucildean" or type == "elucildean":
		for i in range(len(lst2) - 1):
			distance += math.sqrt((lst1[i] - lst2[i])**2)
	else:
		print "Error in type name"
		distance = -1
	return distance

def computeContinous(datalist,attribute):
# compute continous attributes in list
	min_val = int(datalist[0][attribute])
	max_val = int(datalist[0][attribute])
	for items in datalist:
		if int(items[attribute]) < min_val:
			min_val = int(items[attribute])
		elif int(items[attribute]) > max_val:
			max_val = int(items[attribute])
	for items in datalist[:]:
		items[attribute] = (int(items[attribute]) - min_val) / float(max_val - min_val)
	return datalist

def computeOrdinal(datalist,attribute,level):
# compute ordinal attribute in datalist
	level_dict = {}
	for i in range(len(level)):
		level_dict[level[i]] = float(i) / (len(level) - 1)
#		level_dict[level[i]] = i
	for items in datalist[:]:
		items[attribute] = level_dict[items[attribute]]
	return datalist

def KnnAlgorithm(dataTrain,sample,attribute,k):
	mergeData = dataTrain
	mergeData.append(sample)
	data = preProcessing(mergeData)
	distance = []
	for i in range(len(data)-2):
		distance.append(disCal(data[i],data[len(data)-1],"Elucildean"))
	copy_dis = distance[:] # notice : not copy_dis = distance ,if it will be wrong
	distance.sort()

	class_dict = {"Yes":0,"No":0}
	for i in range(k):
		index = copy_dis.index(distance[i])
		if data[index][attribute] == " >50K":
			class_dict["Yes"] += 1
		else:
			class_dict["No"] += 1
	if  class_dict["Yes"] > class_dict["No"]:
		print "sample's salary >50K"
	else:
		print "sample's salary <=50K"

def preProcessing(datalist):
	b = computeNa(datalist)

	b = computeContinous(b,attributes["age"])

	workclass_level = [" Private"," Self-emp-not-inc"," Self-emp-inc"," Federal-gov"," Local-gov"," State-gov"," Without-pay"," Never-worked"]
	b = computeOrdinal(b,attributes["workclass"],workclass_level)

	b = computeContinous(b,attributes["fnlwg"])

	education_level =[" Bachelors"," Some-college"," 11th"," HS-grad"," Prof-school",
				  " Assoc-acdm"," Assoc-voc"," 9th"," 7th-8th"," 12th"," Masters"," 1st-4th"," 10th"," Doctorate"," 5th-6th"," Preschool"] 
	b = computeOrdinal(b,attributes["education"],education_level)

	b = computeContinous(b,attributes["education-num"])

	marital_status_level = [" Married-civ-spouse"," Divorced"," Never-married"," Separated"," Widowed"," Married-spouse-absent"," Married-AF-spouse"] 
	b = computeOrdinal(b,attributes["marital-status"],marital_status_level) 

	occupation_level  = [" Tech-support"," Craft-repair"," Other-service"," Sales"," Exec-managerial"," Prof-specialty"," Handlers-cleaners",
					 " Machine-op-inspct"," Adm-clerical"," Farming-fishing"," Transport-moving"," Priv-house-serv"," Protective-serv"," Armed-Forces"]
	b = computeOrdinal(b,attributes["occupation"],occupation_level)

	relationship_level = [" Wife"," Own-child"," Husband"," Not-in-family"," Other-relative"," Unmarried"]
	b = computeOrdinal(b,attributes["relationship"],relationship_level)

	race_level = [" White"," Asian-Pac-Islander"," Amer-Indian-Eskimo"," Other"," Black"]
	b = computeOrdinal(b,attributes["race"],race_level)

	sex_level = [" Female", " Male"]
	b = computeOrdinal(b,attributes["sex"],sex_level)

	b = computeContinous(b,attributes["capital-gain"])

	b = computeContinous(b,attributes["capital-loss"])

	b = computeContinous(b,attributes["hours-per-week"])

	native_country_level = [" United-States"," Cambodia"," England"," Puerto-Rico"," Canada"," Germany"," Outlying-US(Guam-USVI-etc)"," India",
						" Japan"," Greece"," South"," China"," Cuba"," Iran"," Honduras"," Philippines"," Italy"," Poland"," Jamaica"," Vietnam"," Mexico"," Portugal",
						" Ireland"," France"," Dominican-Republic"," Laos"," Ecuador"," Taiwan"," Haiti"," Columbia"," Hungary"," Guatemala"," Nicaragua"," Scotland",
						" Thailand"," Yugoslavia"," El-Salvador"," Trinadad&Tobago"," Peru"," Hong"," Holand-Netherlands"]
	b = computeOrdinal(b,attributes["native-country"],native_country_level)
	return b

def assessment(dataTrain,dataTest,atrribute,k):
	mergeData = computeNa(dataTrain)
	len_train = len(mergeData)
	mergeData.extend(computeNa(dataTest))
	data = preProcessing(mergeData)	
	len_test = len(data) - len_train
	res_dict = {"correct":0,"wrong":0}
	for i in range(len_test):
		distance = []
		class_dict = {"Yes":0,"No":0}
		for j in range(len_train):
			distance.append(disCal(data[j],data[i+len_train],"Elucildean"))
		copy_dis = distance[:]
		distance.sort()	
		for m in range(k):
			index = copy_dis.index(distance[m])
			if data[index][atrribute] == " >50K":
				class_dict["Yes"] += 1
			else:
				class_dict["No"] += 1	  
		if class_dict["Yes"] > class_dict["No"] and mergeData[i+len_train][atrribute] == " >50K.": #Attention : in train data in the end of lines there is a "."
			res_dict["correct"]  += 1
		elif mergeData[i+len_train][atrribute] == " <=50K." and class_dict["Yes"] < class_dict["No"]:
			res_dict["correct"]  += 1
		else:
			res_dict["wrong"] += 1
	correct_ratio = float(res_dict["correct"]) / (res_dict["correct"] + res_dict["wrong"])
	print "correct_ratio = ",correct_ratio 
	
filename = "H:\BaiduYunDownload\AdultDatasets\Adult_data.txt"
#sample = [" 80"," Private"," 226802"," 11th"," 7"," Never-married"," Machine-op-inspct"," Own-child"," Black"," Male"," 0"," 0"," 40"," United-States"," <=50K"]
sample = [" 65"," Private"," 184454"," HS-grad"," 9"," Married-civ-spouse"," Machine-op-inspct"," Husband"," White"," Male"," 6418"," 0"," 40"," United-States"," >50K"]
# this samples salary <=50K#
# filename = "D:\MyDesktop-HnH\data.txt"
a = read_txt(filename)
print len(a)

k = 3
#KnnAlgorithm(a,sample,attributes["salary"],k)

trainName = "H:\BaiduYunDownload\AdultDatasets\Adult_test.txt" 
trainData = read_txt(trainName)
#preProcessing(trainData)
assessment(a,trainData,attributes["salary"],k)

结果:正确率 0.812416998672

    运行时间 1小时20分钟

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯