一、K邻近算法的基本概念
一个样本在特征空间中最邻近(距离)的K个样本大多数属于某一个类别,则该样本也属于这个类别。
二、sklearn使用欧氏距离实现KNN算法
# 倒入sklearn库中的KNN算法类 from sklearn.neighbors import KNeighborsClassifier # 创建KNN算法实例并设置K值 KNN_classifier = KNeighborsClassifier(n_neighbors=4) # 传入训练样本数据拟合KNN模型 KNN_classifier.fit(train_x, train_y) # 传入测试样本数据进行预测,并返回预测结果 KNN_classifier.predict(test_x)
三、sklearn使用train_test_split来测试模型的性能(iris鸢尾花数据)
import numpy as np # 导入sklearn模块的数据集 from sklearn import datasets # 导入sklearn模块中的随机拆分数据的模块 from sklearn.model_selection import train_test_split # 导入sklearn模块中的KNN算法模块 from sklearn.neighbors import KNeighborsClassifier # 取iris数据集 iris = datasets.load_iris() X = iris.data # 样本特征集(150, 4) y = iris.target # 样本标签集(150,) # 随机拆分数据,默认test_size=0.2 20%拆分 # random_state = 666 设置随机种子 # X_train.shape = (112, 4) # X_test.shape = (38, 4) # y_test.shape = (38,) # y_train.shape = (112,) X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=666) # 创建KNN算法实例并设置K值 KNN_classifier = KNeighborsClassifier(n_neighbors=6) # 传入训练样本数据拟合KNN模型 KNN_classifier.fit(X_train, y_train) # 传入测试样本数据进行预测,并返回预测结果 y_predict = KNN_classifier.predict(X_test) # 验证预测准确率 sum(y_predict == y_test)/len(y_test) # 0.9210526315789473
四、sklearn实现预测准确率算法
import numpy as np from sklearn import datasets from sklearn.neighbors import KNeighborsClassifier from sklearn.model_selection import train_test_split # 判断模型预测准确率的模型 from sklearn.metrics import accuracy_score # 导入手写数据集 digits = datasets.load_digits() # X样本数据集:(1797, 64) # y标签数据集:(1797,) X = digits.data y = digits.target # 按2:8随机拆分数据集 X_train, X_test, y_train, y_test = train_test_split(X, y ,test_size=0.2) # 生成KNN算法实例,并设置K=3 KNN_classifier = KNeighborsClassifier(n_neighbors=3) # KNN拟合模型 KNN_classifier.fit(X_train, y_train) # 通过拟合的KNN模型预测结果,并返回预测结果集 y_predict = KNN_classifier.predict(X_test) # 返回预测准确率 accuracy_score(y_test, y_predict) # 0.9916666666666667 # KNN_classifier.score(X_test, y_test)
五、sklearn通过网格搜索来优化KNN算法中的超参数
1、超参数和模型参数
- 超参数:在算法运行前需要决定的参数
- 模型参数:算法运行过程中学习到的参数
2、KNN算法中的超参数
- K值:邻近的点的数量选择
- 距离权重
- p值
3、距离权重超参数
定义:一般距离权重是距离的倒数值
EXP:
当1个样本的最近的3个样本(A类一个,B类两个),距离A类为1个单位,距离B类分别是3个和4个单位,不考虑距离权重时,样本是B类,考虑距离权重时,距离A类的权重为1,B类权重为1/3+1/4=7/12为A类;当3个点是3类是不考虑权重则属于3个类别的概率相同,所以KNN算法应当考虑距离权重。
sklearn.KNeighborsClassifier类中有一个weights参数默认是uniform(不考虑距离权重),distance(考虑距离权重)
4、p超参数
距离的定义有:欧氏距离、曼哈顿距离、明科夫实际距离、....
sklearn.KNeighborsClassifier类中有一个p参数,接受整型值(默认值为2,欧氏距离)
5、网格搜索寻找最优超参数
from sklearn import datasets from sklearn.neighbors import KNeighborsClassifier from sklearn.model_selection import train_test_split # 导入网格搜索模块 from sklearn.model_selection import GridSearchCV # 导入手写数据集 digits = datasets.load_digits() # X样本数据集:(1797, 64) # y标签数据集:(1797,) X = digits.data y = digits.target # 按2:8随机拆分数据集 X_train, X_test, y_train, y_test = train_test_split(X, y ,test_size=0.2) # 定义网格搜索参数 # weights='distance', p参数才有意义 param_grid = [ { 'weights':['uniform'], 'n_neighbors': [i for i in range(1, 11)] }, { 'weights':['distance'], 'n_neighbors': [i for i in range(1, 11)], 'p': [i for i in range(1, 6)] }] # 创建KNN算法类实例 KNN_clf = KNeighborsClassifier() # 创建网格搜索类实例 # n_jobs设置并行运行,默认是1,-1是最大并行运行 # verbose=int 设置输出 grid_search = GridSearchCV(KNN_clf, param_grid,n_jobs=2, verbose=2) # 拟合网格搜索算法 grid_search.fit(X_train, y_train) # 搜索到的最优参数的分类器 # 可以直接调用knn_clf.precdi knn_clf = grid_search.best_estimator_ # 搜索到的最优参数 grid_search.best_params_ # 最优参数下的准确率 grid_search.best_score_ # 使用最优参数分类器预测 knn_clf.predict(X_test) # 使用最优参数分类器预测的准确率 knn_clf.score(X_test, y_test)
六、sklearn实现数据归一化
1、数据归一化的概念
把数据映射到同一尺度上,数据归一化可以让算法更快收敛
2、常用的数据归一化的方法
- 最值归一化:当数据有明显边界时,把所有数据映射到0-1之间,x_scale = (x-x_min)/(x_max-x_main)
- 均值方差归一化:当数据没有明显边界时,把所有数据归一到均值为0方差为1的分布中,x_scale = (x - x_mean)/ s (s为方差),测试集的均值方差归一化使用的是训练集的x_mean和s
from sklearn import datasets from sklearn.neighbors import KNeighborsClassifier from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler iris = datasets.load_iris() X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2) standard_scaler = StandardScaler() standard_scaler.fit(X_train) # 均值 standard_scaler.mean_ # 方差 standard_scaler.var_ # 标准差 standard_scaler.scale_ # 训练集归一化操作 X_train = standard_scaler.transform(X_train) # 测试集归一化操作 X_test = standard_scaler.transform(X_test) KNN_clf = KNeighborsClassifier(n_neighbors=3) KNN_clf.fit(X_train, y_train) KNN_clf.score(X_test, y_test)
七、总结sklearn实现并优化KNN算法的流程
1、流程
- 导入数据
- 使用train_test_split随机拆分数据
- 使用StandardScaler对数据进行均值方差归一化
- 使用GridSearchCV网格搜索来优化k值、距离权重和p值等超参数
- 使用accuracy_score或者score来取得预测值的准确率
2、优缺点
- 优点:天然的单、多分类算法,简单、效果好
- 缺点:
- 效率低,每一样本的计算复杂度高
- 高度数据相关
- 预测结果不具备可解释性
- 维数灾难,处理高维度数据会出现问题