分类算法之K-Nearest Neighbors

分类算法之K-Nearest Neighbors

一:认识KNN算法

K-Nearest Neighbors又称为k最近邻算法。最初由Cover和Hart在1968年提出。属于Classification(分类)算法。Classification算法一般分为两个阶段,训练阶段和学习阶段

二:算法原理

通用步骤:

  • 计算距离(常用欧式距离或马氏距离)
  • 升序排列
  • 取前k个
  • 加权平均

k的选取:

  • k太大:导致分类模糊
  • k太小:手个例影响,波动较大

如何选取k:

  • 经验
  • 均方根误差

三:算法应用

  1. 简单KNN算法实现

    ​ python中的sklearn库为我们封装了KNN算法的实现方式

    ​ datasets是sklearn中的一个存放各类数据的模块,我们可以通过导入这个模块可以获取大量标准的数据进行练习。我们以鸢尾花数据为例。

    ​ 数据解析:鸢尾花的共有4个属性,分别为sepal length 、sepal width 、 petal length 、 petal width, 通过属性的不同我们将鸢尾花分为了setosa、versicolor、virginica三类,分别用数字0、1、2表示。综上所述,4个属性为特征,类别为标签。

    代码实现:

from sklearn.datasets import load_iris
from sklearn.neighbors import KNeighborsClassifier

# 获取数据
iris_data = load_iris()
print(iris_data)

# 将鸢尾花数据分为两组,取前100条数据为训练集,后100条数据为测试集
# 获取训练集的特征值和标签值
trans_feature = iris_data["data"][:100]
trans_label = iris_data["target"][:100]
# 获取测试集的特征值和标签值
test_feature = iris_data["data"][-100:]
test_label = iris_data["target"][-100:]

# 创建KNN模型对象,传入的参数相当于k值
KNN = KNeighborsClassifier(n_neighbors=7)

# 测试模型
KNN.fit(trans_feature,trans_label)

# 模型预测
KNN.predict(test_feature)

# 获取精度
precision = KNN.score(test_feature, test_label)
print(precision)
  1. Cross Validation (交叉验证)

    ​ Cross Validation是一种评估模型性能的重要方法。主要用于在多个模型中(不同中模型和同一种类不同超参数组合)挑选出在当前问题场景下表现最优的模型

    引入原因:

    ​ 在训练集(train set)上训练得到的模型表现良好,但在测试集(test set)的预测结果不尽如人意,这就说明模型可能出现了过拟合(overfitting),在未知数据上的泛化能力差。

    ​ 一个改进方案是,在训练集的基础上进一步划分出新的训练集和验证集(validate set),在新训练集训练模型,在验证集测试模型,不断调整初始模型(超参数等),使得训练得到的模型在验证集上的表现最好,最后放到测试集上得到这个最优模型的评估结果。

    ​ 这个方案的问题在于模型的表现依赖于验证集的划分,可能使某些特殊样本被划入验证集,导致模型的表现出现异常(偏好或偏差)。而且训练集划了一部分给验证集后,训练模型能得到的数据就变少了,也会影响训练效果。因为通常来说,训练数据越多,越能反映出数据的真实分布,模型训练的效果就越好,越可能得到无偏估计。

    ​ 交叉验证思想应运而生,交叉验证可以充分使用所有的训练数据用于评估模型。

    • K-fold(K折交叉验证)

      k折交叉验证是最基本的cv方法,具体方法为,将训练集随机等分为k份,取其中一份为验证集评估模型,其余k-1份为训练集训练模型,重复该步骤k次,每次都取一份不同的子集为验证集,最终得到k个不同的模型(不是对一个模型迭代k次)和k个评分,综合这k个模型的表现(平均得分或其他)评估模型在当前问题中的优劣。

      训练集和验证集的划分都在模块底层自动实现,我们只需要传入一个集合即可。

      k值的选取很有讲究,选取适当大小的k很重要,经验值(empirical value)是k=10。

      算法实现:

      from sklearn.datasets import load_iris
      from sklearn.neighbors import KNeighborsClassifier
      from sklearn.model_selection import cross_val_score
      
      # 获取数据
      iris_data = load_iris()
      
      # 实例化模型
      KNN = KNeighborsClassifier(n_neighbors=7)
      
      # 提取特征值和标签
      iris_features = iris_data["data"]
      iris_labels = iris_data["target"]
      
      # 交叉验证,返回模型每次的精度
      score = cross_val_score(KNN,iris_features,iris_labels,cv=10)
      
      # 获取精度,精度一般取平均值
      precision = score.mean()
      print(precision)
      
    • Leave one out(LOO)

      LOO(留一法)每次在训练集的N个样本中选一个不同的样本作为验证集,其余样本为训练集,训练得到N-1个不同的模型。LOOCV是特殊的K-fold,当K=N时,二者相同。【不常用,了解即可】

  2. 网格搜索

    网格搜索的目的主要是用来确定超参数k的值,CV是网格搜索的一种方法。

    cv与网格搜索

    ​ 通常情况下,有很多参数是需要手动指定的(如k-近邻算法中的K值),这种叫超参数。但是手动过程繁杂,所以需要对模型预设几种超参数组合。每组超参数都采用交叉验证来进行评估。最后选出最优参数组合建立模型。

    ​ scikit learn库中的GridSearchCV可以方便地尝试不同的超参数(hyper parameter),得到最优组合。GridSearchCV中的cv参数(默认为3-fold)利用交叉验证为某一超参数组合打出合理的评分。可以使用sklearn.model_selection.GridSearchCV(estimator, param_grid=None,cv=None)对估计器模型的指定参数值进行详尽搜索。其中estimator为模型对象,param_grid为k值的备选列表,cv为数据等分个数

    ​ GridSearchCV结果展示方法:

    ​ best_params_:返回最高精度对应的k值

    ​ best_score_:返回最高精度值

    ​ best_estimator_:返回最好的参数模型

    代码实现:

    from sklearn.datasets import load_iris
    from sklearn.neighbors import KNeighborsClassifier
    from sklearn.model_selection import GridSearchCV
    # 获取数据
    iris_data = load_iris()
    
    # 获取特征值和标签
    iris_features = iris_data["data"]
    iris_labels = iris_data["target"]
    
    # 实例化模型对象
    KNN = KNeighborsClassifier()
    
    # 定义k值备选列表
    params = {"n_neighbors":[i for i in range(10,30,2)]}
    
    # 实例化网格对象
    gridcv = GridSearchCV(KNN,grid_param=params,cv=10)
    
    # 测试数据
    gridcv.fit(iris_features,iris_labels)
    
    # 返回精度最高的参数
    print(gridcv.best_params_)
    # 返回最高精度值
    print(gridcv.best_scores_)
    # 返回最高精度模型
    

print(gridcv.best_estimator_)





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值