目录
- 写在前面的话
- k-近邻算法概述
-
- 原理
- Python代码实现
- Sklearn直接调用
-
- 算法测试与结果评价
-
- 示例
- 反思与总结
写在前面的话
大概是上半年准备美赛的时候,才发现仅仅具备C语言的知识,如果想对数据进行分析和挖掘,实在太过简陋,并且当时对相关算法了解甚少。这个学期有幸选了黄教授的数据科学概论一课,他曾经在课上向我们推荐了《机器学习实战》一书。这段时间抽空读了一下,感觉受益颇深,正巧赶完了期末大作业,便把学到的算法以专栏的形式整理出来。一方面便于自己复习巩固,另一方面书中的Python代码并非最新版本,许多参数已经删改,博主也趁此机会完善一下代码,并且给予充足的注释,以飨读者。
k-近邻算法概述
k-近邻算法本质上是一种分类算法,主要采用测量不同特征值之间距离的方法实现
优点
精度高、对异常值不敏感、无数据输入假定
缺点
计算复杂度高、空间复杂度高
适用数据范围
数值型、标称型
原理
(1)计算输入数据与样本集中数据的距离
(2)对距离进行排序
(3)选出前k个最相似的数据(距离最短)
(4)将这些数据中类别出现次数最多的类别作为新数据的分类
Python代码实现
我们以二维数据为例
import numpy as np
import operator
def createDataSet():
group = np.array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
labels = ['A','A','B','B']
return group, labels
def title(inY, Size):
x = Size[0]
y = Size[1]
result = np.zeros((x, y))
for i in range(x):
result[[i],:] = inY
return result
def classify0(inX, dataSet, labels, k):
dataSetxSize = dataSet.shape[0]
dataSetySize = dataSet.shape[1]
diffMat = title(inX, (dataSetxSize, dataSetySize)) - dataSet
sqDiffMat = diffMat**2
sqDistances = sqDiffMat.sum(axis=1)
distances = sqDistances**0.5
sortedDistIndicies = distances.argsort()
classCount={}
for i in range(k):
voteIlabel = labels[sortedDistIndicies[i]]
classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
return sortedClassCount[0][0]
group,labels = createDataSet()
classify0([0,0], group, labels, 3)
Sklearn直接调用
当然,强大的Python自带KNN算法包,下面简述一下几个重要参数的意义
def KNeighborsClassifier(n_neighbors,
weights,
algorithm,
leaf_size,
p,
metric)
此外有两个参数有具体选项
weights选项
uniform | distance | 自定义函数 |
---|
不加权 | 权重和距离成反比 | |
algorithm选项
brute | kd_tree | ball_tree | auto |
---|
暴力实现 | KD树实现 | KD球树实现 | 默认参数,自动选择合适的方法 |
import numpy as np
import operator
from sklearn.neighbors import KNeighborsClassifier
def createDataSet():
group = np.array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
labels = ['A','A','B','B']
return group, labels
def classify0(inX, dataSet, labels, k):
inX = np.array(inX).reshape(-1,2)
knn = KNeighborsClassifier(n_neighbors=k)
result = knn.fit(dataSet, labels)
pre = knn.predict(inX)
return pre
group,labels = createDataSet()
print(classify0([0,0], group, labels, 3))
很明显,用自带的库实现这一算法,其代码实现更为简洁(功能、效率都更加强大)
算法测试与结果评价
这里我们采用的方法是K折交叉验证
原理及方法
(1)不重复抽样,将原始数据随机分为 k 份
(2)挑选其中一份作为测试集,剩余 k-1 份作为样本集,进行测试
(3)重复第二步 k 次
(4)计算 k 组测试结果的平均值,作为模型的性能指标
函数主要参数说明
sklearn.model_selection.cross_val_score(estimator,
X,
y,
cv)
Python代码实现
由于我们构建的数据集已不再适合应用这一检验,遂使用更庞大的数据集
(代码来源)
from sklearn.datasets import load_iris
from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt
from sklearn.neighbors import KNeighborsClassifier
iris = load_iris()
x = iris.data
y = iris.target
k_range = range(1, 31)
k_error = []
for k in k_range:
knn = KNeighborsClassifier(n_neighbors=k)
scores = cross_val_score(knn, x, y, cv=6, scoring='accuracy')
k_error.append(1 - scores.mean())
plt.plot(k_range, k_error)
plt.xlabel('Value of K for KNN')
plt.ylabel('Error')
plt.show()
示例
以后有机会用书中实例予以补充
反思与总结
这是这个专栏的第一篇博客,写完后还是有很多感触的。
初次建模,或者说进行数据分析,一定要构建整个过程的框架,从数据的预处理、构建数据集,到模型的选择、建立、优化,再到预测与评估。
记得曾经在知乎上看到过一项挑战,大致意思是给出一张图片,根据图中信息判断拍摄者所处的位置,看视频时我情绪高涨,事后想了想,当初参与建模比赛,其实向往的是数据背后的故事。
死气沉沉的数字,总能带给我们一些现实意义,对于追寻这些意义的过程,最起码到目前为止,我认为是快乐的。
博主非统计专业,这方面不是专家,如有纰漏或需要补充的地方,烦请各位大佬在评论区指出,如您觉得写的不错,记得一键三连哟
(^U^)ノ~YO
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)