【机器学习】KNN算法 简介K-近邻算法K Nearest Neighbor简称KNN如果一个样本在特征空间的k个最相似的样本中的大多数属于某一个类别则该样本也属于该类别。可以解决分类问题和回归问题。关于样本的相似性样本都属于一个任务数据集的样本距离越近越相似。K值过小容易受到异常值的影响且会导致模型学到“脏数据”容易发生过拟合K值过大模型会变得简单容易发生欠拟合。代码实现思路1.导包2.准备数据集3.创建KNN模型对象4.模型训练5.模型预测分类问题适用于有特征、有标签、且标签是不连续的数据通过投票取票数最多。分类问题小例子# 1.导包 from sklearn.neighbors import KNeighborsClassifier # 2.准备数据集 x_train [[0],[1],[2],[3]] # 训练集的特征数据 y_train [0,0,1,1] # 训练集的标签数据 x_test [[5]] # 测试集的特征数据 # 3.创建KNN模型对象 estimator KNeighborsClassifier(n_neighbors3) # 4.模型训练 estimator.fit(x_train,y_train) # 5.模型预测 y_pred estimator.predict(x_test) print(f预测结果为{y_pred})运行结果回归问题适用于有特征、有标签、且标签是连续的数据取 平均值回归小例子# 1.导包 from sklearn.neighbors import KNeighborsRegressor # 2.准备数据集 x_train [[0, 0, 1],[1, 1, 0],[3, 10, 10],[4, 11, 12]] # 训练集的特征数据 y_train [0.1, 0.2, 0.3, 0.4] # 训练集的标签数据 x_test [[3, 11, 10]] # 测试集的特征数据 # 3.创建KNN模型对象 estimator KNeighborsRegressor(n_neighbors3) # 4.模型训练 estimator.fit(x_train,y_train) # 5.模型预测 y_pred estimator.predict(x_test) print(f预测结果为{y_pred})运行结果距离度量1.欧式距离对应维度差值的平方和再开根号。2.曼哈顿距离对应维度差值的绝对值之和。3.切比雪夫距离切比雪夫距离 对应维度值差值的绝对值取其中的最大值。4.闵可夫斯基距离特征预处理特征的单位或者大小相差较大或者某特征的方差相比其他的特征要大出几个数量级容易影响(支配)目标结果使得一些模型(算法)无法学习到其它的特征。1.归一化公式解释x 是基于公式算出来的结果 x 是最终结果mx 是你想映射到的区间的最大值 mi 是想映射区间的最小值该方法容易受到极值的影响一般用于处理小数据集。代码示例# 导包 from sklearn.preprocessing import MinMaxScaler # 准备原始数据 x_train [[90,2,10,40],[60,4,15,45],[75,3,13,46]] # 创建归一化对象 # 参数feature_range表示生成范围默认区间是(0,1) 如果是这个区间可以不写 transfer MinMaxScaler(feature_range(0,1)) # 对原数据集进行归一化操作 x_train_new transfer.fit_transform(x_train) # 打印归一化后的数据 print(归一化后的数据) print(x_train_new)运行结果2.标准化数据标准化通过对原始数据进行标准化转为均值为0标准差为1的标准正态分布的数据。公式:mean为特征的平均值为特征的标准差。代码示例# 导包 from sklearn.preprocessing import StandardScaler # 准备原始数据 x_train [[90,2,10,40],[60,4,15,45],[75,3,13,46]] # 创建标准差对象 transfer StandardScaler() # 对原数据集进行归一化操作 x_train_new transfer.fit_transform(x_train) # 打印归一化后的数据 print(归一化后的数据) print(x_train_new) # 打印数据集的均值和方差 print(f数据集的均值为{transfer.mean_}) print(f数据集的方差为{transfer.var_}) print(f数据集的标准差为{transfer.scale_})运行结果3.总结看到这里可以尝试一下鸢尾花分类的案例看看能不能做出来。KNN算法对尾花分类超参数选择方法交叉验证交叉验证是一种数据集的分割方法将训练集分成n份拿出一份做验证集测试集其他n-1份做训练集。原理用4折交叉验证举例将数据集划分为cv4 份第一次k1,把第一份数据做验证集其他数据做训练第二次k2,把第二份数据做验证集其他数据做训练k3、k4以此类推总共训练4次评估4次取上面四次评估的准确率的平均值做交叉验证为模型得分若k4时模型得分最好再使用全部训练集(训练集验证集)。对k4模型再训练一遍再使用测试集对k4模型做评估网格搜索为什么需要网格搜索模型有很多超参数其能力也存在很大的差异。需要手动产生很多超参数组合来训练模型每组超参数都采用交叉验证评估最后选出最优参数组合建立模型。网格搜索是模型调参的有力工具。只需要将若干参数传递给网格搜索对象它自动帮我们完成不同超参数的组合、模型训练、模型评估最终返回一组最优的超参数。网格搜索交叉验证的强力组合模型选择和调优交叉验证解决模型的数据输入问题(数据集划分)得到更可靠的模型网格搜索解决超参数的组合两个组合再一起形成一个模型参数调优的解决方案交叉验证网格搜索API介绍对估计器的指定参数值进行详尽的搜索sklearn.model_selection.GridSearchCV(estimator,param_gridNone,cvbNone)参1估计器对象参2估计器参数(dict){n_neighbors:[1,3,5]} 参3指定几折交叉验证结果分析bestscore_:在交叉验证中验证的最好结果bestestimator:最好的参数模型cvresults:每次交叉验证后的验证集准确率结果和训练集准确率结果加入了交叉验证和网格搜索的鸢尾花分类实验# 导包 from sklearn.model_selection import train_test_split, GridSearchCV # 分割训练集的测试集, 寻找最优超参网格搜索交叉验证 from sklearn.preprocessing import StandardScaler # 数据标准化 from sklearn.metrics import accuracy_score # 模型评估计算模型预测的准确率 from sklearn.neighbors import KNeighborsClassifier # KNN算法 from sklearn.datasets import load_iris # 加载鸢尾花测试集 # 加载数据 iris_data load_iris() # 数据预处理 x_train, x_test, y_train, y_test train_test_split(iris_data.data, iris_data.target, test_size0.2, random_state25) # 特征工程 transfer StandardScaler() x_train transfer.fit_transform(x_train) x_test transfer.transform(x_test) # 模型训练 # 1、创建KNN分类对象 estimator KNeighborsClassifier() # 2、定义字典记录超参数可能出现的值 param_dict {n_neighbors:[i for i in range(1, 11)]} # 3、创建GridSearchCV对象 -- 寻找最优超参 estimator GridSearchCV(estimator,param_dict,cv4) # 4、具体训练 estimator.fit(x_train,y_train) # 5、打印最优超参组合 print(f最优评分{estimator.best_score_}) print(f最优超参组合{estimator.best_params_}) print(f最优的估计器对象{estimator.best_estimator_}) # 模型评估 # 1.获取最优超参的模型对象 estimator estimator.best_estimator_ # 2.模型训练 estimator.fit(x_train,y_train) # 3.模型预测 y_pred estimator.predict(x_test) # 4.模型评估 print(f准确率为{accuracy_score(y_test,y_pred)})运行结果