十四.K最近邻(KNN)原理和sklearn实现、网格搜索

1.概述

KNN的原理非常简单明了,根据离样本最近的 k k k个点的标签来决定样本的类别或值。既可以用来分类,也可以进行回归。
分类:多数表决。在数据集中,找出与样本特征最近的 k k k个数据点,这些数据点中占比最多的类别即为要预测的样本的类别。
回归:取平均值。在数据集中,找出与样本特征最近的 k k k个数据点,取它们的平均值作为样本的预测值。

2.算法流程

(1)计算距离

计算样本与训练集中每个点的距离。一般使用欧式距离,向量 x , y \mathbf{x,y} x,y的欧式距离为:
D ( x , y ) = ∑ i = 1 n ( x i − y i ) 2 D(\mathbf{x,y})=\sqrt{\sum_{i=1}^{n}(\mathbf{x}_{i}-\mathbf{y}_{i})^{2}} D(x,y)=i=1n(xiyi)2
其中, n n n为每个样本的维度。

(2)选择最近邻点

选择距离样本点最近的 k k k个点, k k k值的选择应该多次尝试,因为当 k k k较小时,容易发生过拟合;当 k k k较大时,模型简单,容易加大预测误差。

(3)预测

如果是分类,多数表决;如果是回归,输出为最近 k k k个类别的平均值。

3.KNN优化之KD树

如果每次预测都需要计算每个样本的距离,则无疑计算量是巨大的。为了减少计算,这里给出KD树在KNN中的应用。

(1)KD树之建树

建树依据为维度方差最大化:
数据有 n n n个维度,依次计算各个维度的方差。选择方差最大的维度 n i n_{i} ni,在所有样本的此维度中寻找中位数;假设中位数为10,将其他样本中维度 n i n_{i} ni的值小于10的划入左子树,大于10的划入右子树。递归建树直到最后一个维度。

(2)KD树之搜索

样本 x \mathbf{x} x的预测过程:
根据维度划分,首先找到样本 x \mathbf{x} x对应的叶子节点,以样本 x \mathbf{x} x和叶子结点的距离为半径做超球体,最近邻的点一定在这个超球体内部。返回叶子节点的父节点,检查父节点的另一个节点的超矩形和这个超球体是否相交,相交的话在这个矩形内寻找是否有更近的节点,有的话跟新最近邻;不相交的话继续返回上一层的父节点,重复以上步骤直到根节点。

4.sklearn实现KNN

(1)数据预处理

导入数据集,划分训练集、测试集,标准化

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
iris = load_iris()
x,y=iris.data,iris.target
x_train,x_test,y_train,y_test=train_test_split(x,y)
std = StandardScaler()
x_train=std.fit_transform(x_train)
x_test = std.fit_transform(x_test)
print(x_train.shape,x_test.shape)

输出:

(112, 4) (38, 4)

(2)预测和评价

KNN模型的K值设为3:

from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
model = KNeighborsClassifier(n_neighbors=3)
model.fit(x_train,y_train)
y_pred = model.predict(x_test)
print(accuracy_score(y_pred,y_test))

输出:

0.8421052631578947

(3)网格搜索

使用网格搜索、交叉验证选择合适的K值

from sklearn.model_selection import GridSearchCV
parameters={'n_neighbors':[1,3,5,10,20,50]}
model2 = KNeighborsClassifier()
cvModel=GridSearchCV(model2,parameters,cv=5)
cvModel.fit(x_train,y_train)
print(cvModel.best_score_)
print(cvModel.best_params_)

输出:

0.9727272727272727
{'n_neighbors': 10}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值