任务3
手写KNN算法实现分类问题
导入数据集,并分割成训练集和测试集
KNN算法要求出距r离最近的K 个数据,这里定义一个函数euc_dis,求欧几里得距离
定义一个函数 knn_classify,计算 testInstance 与 X 中的每个向量的距离,将样本对应标签添加到maxY数组中
from sklearn import datasets #导入一个样本数据 from sklearn. model_selection import train_test_split #数据集的分割,把数据分成训练集和测试集 import numpy as np import heapq iris = datasets.load_iris() #导入iris数据集 X = iris.data y = iris.target X_train,X_test,y_train,y_test = train_test_split(X,y,random_state=2003) #定义求距离函数 def euc_dis(instance1, instance2): diff = instance1-instance2 #做差 diff = diff ** 2 #平方 dist = sum(diff) ** 0.5 #求和、开方 return dist #定义knn分类函数 def knn_classify(X, y,testInstance, k): dis=[] for i in X: dis.append(euc_dis(i,testInstance)) #求 testInstance 与 X 中的每个向量的距离 maxIndex = map(dis.index,heapq.nsmallest(k,dis)) #求出最小的k个距离的下标 maxY=[] for i in maxIndex: maxY.append(y[i]) #将样本对应标签添加到maxY数组中 return max(maxY,key=maxY.count) #求出现次数最多的标签值 predictions = [knn_classify(X_train,y_train,data,3) for data in X_test] correct = np.count_nonzero((predictions==y_test)==True) print("Accruacy is: %.3f" %(correct/len(X_test)))
train_test_split函数用于将矩阵随机划分为训练集和测试集,并返回划分好的并返回划分好的训练集和测试集数据
语法:
X_train,X_test, y_train, y_test =cross_validation.train_test_split(X,y,test_size, random_state)
其中:
X:待划分的样本特征集合
y:待划分的样本标签
test_size:若在0~1之间,为测试集样本数目与原始样本数目之比;若为整数,则是测试集样本的数目。
random_state:随机数种子
X_train:划分出的训练集数据(返回值)
X_test:划分出的测试集数据(返回值)
y_train:划分出的训练集标签(返回值)
y_test:划分出的测试集标签(返回值)
随机数种子:该组随机数的编号,在需要重复试验的时候,保证得到一组一样的随机数。比如每次都填1,其他参数一样的情况下你得到的随机数组是一样的。但填0或不填,每次都会不一样。
随机数的产生取决于种子,随机数和种子之间的关系遵从以下两个规则:
种子不同,产生不同的随机数;种子相同,即使实例不同也产生相同的随机数。
参考博客:https://blog.csdn.net/fxlou/article/details/79189106
heapq模块中的两个函数——nlargest()和nsmallest()可以找出某个集合中最大或最小的N个元素
例如:
>>> import heapq
>>> nums=[6,8,2,0,11,-4,-9,23,4,96,27]
>>> print(heapq.nlargest(3,nums))
[96, 27, 23]
>>> print(heapq.nsmallest(3,nums))
[-9, -4, 0]
求平方diff^2: ① diff ** 2 ——表达式
②
参考博客:https://blog.csdn.net/jerry_1126/article/details/82917405
python中 for 循环,经常用于遍历字符串、列表,元组,字典等
语法
for x in y:
statements(s)
执行流程:x依次表示y中的一个元素,遍历完所有元素循环结束
参考博客:https://www.cnblogs.com/kiki5881/p/8541887.html
append() 方法用于在列表末尾添加新的对象
语法
list.append(obj)
obj -- 添加到列表末尾的对象
index() 函数用于从列表中找出某个值第一个匹配项的索引位置
语法
list.index(x[, start[, end]])
x-- 查找的对象。
start-- 可选,查找的起始位置
end-- 可选,查找的结束位置
返回:返回查找对象的索引位置,如果没有找到对象则抛出异常
实例
aList = [123, 'xyz', 'runoob', 'abc'] print "xyz 索引位置: ", aList.index( 'xyz' ) print "runoob 索引位置 : ", aList.index( 'runoob', 1, 3 )
输出
xyz 索引位置: 1
runoob 索引位置 : 2
map() 会根据提供的函数对指定序列做映射
第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表
语法:
map(function, iterable, ...)
实例
def square(x) : # 计算平方数
return x ** 2
map(square, [1,2,3,4,5]) # 计算列表各个元素的平方
[1, 4, 9, 16, 25]
map(lambda x: x ** 2, [1, 2, 3, 4, 5]) # 使用 lambda 匿名函数
[1, 4, 9, 16, 25]
# 提供了两个列表,对相同位置的列表数据进行相加
map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])
[3, 7, 11, 15, 19]
参考:https://www.runoob.com/python/python-func-map.html
max() 方法
返回给定参数的最大值,参数可以为序列
语法
max( x, y, z, .... )
按ASCII码进行排序,若列表里面是元组构成元素,按照元素里面元组的第一个元素的排列顺序,输出最大值(如果第一个元素相同,则比较第二个元素,输出最大值)据推理是按ASCII码进行排序的
实例
>>> a=[('a',1),('A',1)] >>> max(a) ('a', 1)
numpy.nonzero(a)
返回数组a中非零值的数量
参考:https://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.count_nonzero.html
参考代码看下来,感觉KNN算法的想法不难,理顺了思路,但是落实到用python实现就是另一个问题了。
要学习的知识有很多,还好有百度这种东西,果然现在自己知道的还是太少了
现在跟这些函数混了个脸熟,虽然还不太熟悉,以后有机会经常使用,应该能熟能生巧
总之,There is still a long way to go.