K-近邻算法

喜你入骨 提交于 2019-12-06 15:26:14

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值选择不当则分类精确度不能保证
  • 使用场景  
      • 小数据场景,几千~几万样本, 具体场景 具体业务去测。

 

 

 

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!