K-近邻算法 👉 KNeighborsClassifier
原理 :
如果一个样本在 特征空间中的 k个值 (即特征空间中邻近)的 样本中的 大多数 属于某一个类别 , 则该样本也属于这个类别。也理解为:离谁最近,与谁一样。找K个最近的点 , 看这k个点中 , 类别最多的那个类别。
特别需要注意的是 : 运行k-近邻算法之前,必须做标准化处理!!!
K-近邻算法步骤 :
我们可以从 最近邻算法 , 来推演 k近邻算法, 其步骤是 :
- 计算已知类别数据集中的点与当前点之间的距离
- 按照距离递增次序排序
- 选取与当前距离最小的k个点
- 确定前k个点所在类别的出现频率
- 返回前k个点所在频率最高的类别作为当前点的预测分类
由此可知 , k近邻算法其实本质上并不是以最近的点为分类, 而是以最近的k个点的分类出现的概率最高为分类, 这点跟我们在spss逻辑回归中的思路是一致的。
k-近邻算法特点:
- 优点
-
- 简单好用, 容易理解, 精度高, 理论成熟, 既可以用来做分类也可以用来做回归; 可用于数值型数据和离散型数据; 训练时间复制为O(n); 无数据输入假定; 对异常值不敏感。
-
- 缺点
-
- 计算复杂性高; 空间复杂性高; 样本不平衡问题(即有些类别的样本数量很多, 而其他样本的数量很少); 一般数值很大的时候不用这个, 计算量太大。 但是单个样本数不能太少, 否则容易发生误分。 最大的缺点是无法给出数据的内在含义。
-
k-近邻算法API:
# 导入及参数 from sklearn.neighbors.KNeighborsClassifier( n_neighbors=5, # int, 可选参数(默认为 5) weights='uniform', # 参数有‘uniform’和‘distance’,可以选择调试。 algorithm='auto', #算法 {‘auto’, ‘ball_tree’, ‘kd_tree’, ‘brute’}, 可选参数(默认为 'auto') leaf_size=30, #叶子数量 int, 可选参数(默认为 30) p=2, # integer, 可选参数(默认为 2) metric='minkowski', #矩阵 string or callable, 默认为 ‘minkowski’ metric_params=None, #矩阵参数 dict, 可选参数(默认为 None) n_jobs=None, #int, 可选参数(默认为 1) 用于搜索邻居的,可并行运行的任务数量。如果为-1, 任务数量设置为CPU核的数量。 **kwargs, # )
案例( 项目说明) :
海伦女士一直使用在线约会网站寻找适合自己的约会对象。尽管约会网站会推荐不同的任选,但她 并不是喜欢每一个人。经过一番总结,她发现自己交往过的人可以进行如下分类:不喜欢的人;魅力一 般的人;极具魅力的人。 海伦收集约会数据已经有了一段时间,每个样本数据占据一行,总共有1000行。 海伦收集的样本数据主要包含以下3种特征:每年获得的飞行常客里程数;玩视频游戏所消耗时间 百分比;每周消费的冰淇淋公升数。 请通过这些数据进行机器学习,用来预测海伦对下一个约会对象的感觉。
1 # 代码 2 from sklearn.neighbors import KNeighborsClassifier 3 from sklearn.model_selection import train_test_split 4 from sklearn.preprocessing import MinMaxScaler 5 # 读取数据 6 import pandas as pd import numpy as np 7 data = np.loadtxt('datingTestSet.txt', dtype=np.object, delimiter='\t', encoding='gbk') df = pd.DataFrame(data) 8 # 获取特征值 9 x = df.iloc[:,:3] 10 # 获取目标值 11 y = df[3] 12 # 特征工程 13 # 归一化 14 scaler = MinMaxScaler() 15 x = scaler.fit_transform(x) 16 # 分割数据集 17 train_x, test_x, train_y, test_y = train_test_split(x, y, test_size=0.25) 18 # knn 19 kn = KNeighborsClassifier(n_neighbors=30) 20 # 选择500个邻居 21 kn.fit(train_x, train_y) 22 # 得出预测结果 23 predict = kn.predict(test_x) 24 print('预测结果为:', predict) 25 # 得出准确率 26 print('------------ >测试集正确率: {0}\n'.format(round(kn.score(test_x,test_y),3))) 27 print('------------ >训练集正确率: {0}\n'.format(round(kn.score(train_x,train_y),3))) 28 print('------------ >全集正确率:{0}\n'.format(round(kn.score(x,y),3))) 29 # 模型的保存 30 from sklearn.externals import joblib 31 joblib.dump(kn, 'kn.m') 32 33 # 调用保存好的模型 34 from sklearn.externals import joblib 35 36 kn_new = joblib.load('kn.m') 37 # 预测样本归一化 38 scaler = MinMaxScaler() 39 s = ([12,44000,0.5],[0.1,200,0.8],[68,32000,0.3]) 40 t = scaler.fit_transform(s) 41 print(t)
为什么要对预测样本做归一化?
预测样本数据没有归一化会导致分类成为同一类别,由于维度太大,如果不采用归一化处理的话,各个点的距离值将非常大,故模型对于待测点的预测结果值都判为同一个。
K-近邻算法 总结 :
- k值的取值问题
-
- K值取多大?有什么影响?
- k值取很小:容易受异常的影响
- k值取很大:容易受到k值数量(类别)波动
- K值取多大?有什么影响?
-
- 性能问题
-
- 如果样本越来越大, 算法时间、空间复杂度都会越来越大
-
- 优点
-
- 简单, 易于理解, 易于实现, 无需估计参数, 无需训练
-
- 缺点
-
- 懒惰算法, 对测试样本分类时的计算量大, 内存开销大, 必须指定k值, k值选择不当则分类精确度不能保证
-
- 使用场景
-
- 小数据场景,几千~几万样本, 具体场景 具体业务去测。
-