KNN算法 KNN算法简介 学习目标:
1.理解K近邻算法的思想
2.知道K值选择对结果影响
3.知道K近邻算法分类流程
4.知道K近邻算法回归流程
【理解】KNN算法思想 K-近邻算法(K Nearest Neighbor,简称KNN)。比如:根据你的“邻居”来推断出你的类别
KNN算法思想:如果一个样本在特征空间中的 k 个最相似的样本中的大多数属于某一个类别,则该样本也属于这个类别
思考:如何确定样本的相似性?
样本相似性 :样本都是属于一个任务数据集的。样本距离越近则越相似。
利用K近邻算法预测电影类型
【知道】K值的选择
【知道】KNN的应用方式
1.计算未知样本到每一个训练样本的距离
2.将训练样本根据距离大小升序排列
3.取出距离最近的 K 个训练样本
4.进行多数表决,统计 K 个样本中哪个类别的样本个数最多
5.将未知的样本归属到出现次数最多的类别
1.计算未知样本到每一个训练样本的距离
2.将训练样本根据距离大小升序排列
3.取出距离最近的 K 个训练样本
4.把这个 K 个样本的目标值计算其平均值
5.作为将未知的样本预测的值
API介绍 学习目标:
1.掌握KNN算法分类API
2.掌握KNN算法回归API
【实操】分类API KNN分类API:
1 sklearn.neighbors.KNeighborsClassifier(n_neighbors=5 )
n_neighbors:int,可选(默认= 5),k_neighbors查询默认使用的邻居数
【实操】回归API KNN分类API:
1 sklearn.neighbors.KNeighborsRegressor(n_neighbors=5 )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 from sklearn.neighbors import KNeighborsClassifier,KNeighborsRegressorx = [[0 ,1 ,2 ],[1 ,2 ,3 ],[2 ,3 ,4 ],[3 ,4 ,5 ]] y = [0.1 ,0.2 ,0.3 ,0.4 ] model =KNeighborsRegressor(n_neighbors=3 ) model.fit(x,y) print (model.predict([[4 ,4 ,5 ]]))
距离度量方法 学习目标:
1.掌握欧氏距离的计算方法
2.掌握曼哈顿距离的计算方法
3.了解切比雪夫距离的计算方法
4.了解闵可夫斯基距离的计算方法
【掌握】欧式距离
【掌握】曼哈顿距离
【了解】切比雪夫距离
【了解】闵氏距离 •闵可夫斯基距离 Minkowski Distance 闵氏距离,不是一种新的距离的度量方式。而是距离的组合 是对多个距离度量公式的概括性的表述
特征预处理 学习目标:
1.知道为什么进行归一化、标准化
2.能应用归一化API处理数据
3.能应用标准化API处理数据
4.使用KNN算法进行鸢尾花分类
【知道】为什么进行归一化、标准化 特征的单位或者大小相差较大,或者某特征的方差相比其他的特征要大出几个数量级 ,容易影响(支配)目标结果 ,使得一些模型(算法)无法学习到其它的特征。
【掌握】归一化 通过对原始数据进行变换把数据映射到【mi,mx】(默认为[0,1])之间
数据归一化的API实现
1 sklearn.preprocessing.MinMaxScaler (feature_range=(0,1)… )
feature_range 缩放区间
调用 fit_transform(X) 将特征进行归一化缩放
归一化受到最大值与最小值的影响,这种方法容易受到异常数据的影响, 鲁棒性较差,适合传统精确小数据场景
【掌握】标准化 通过对原始数据进行标准化,转换为均值为0标准差为1的标准正态分布的数据
数据标准化的API实现
1 sklearn.preprocessing. StandardScaler()
调用 fit_transform(X) 将特征进行归一化缩放
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 from sklearn.preprocessing import MinMaxScaler,StandardScalerx = [[90 , 2 , 10 , 40 ], [60 , 4 , 15 , 45 ], [75 , 3 , 13 , 46 ]] process =StandardScaler() data =process.fit_transform(x) print (process.mean_)print (process.var_)
对于标准化来说,如果出现异常点,由于具有一定数据量,少量的异常点对于平均值的影响并不大
【实操】利用KNN算法进行鸢尾花分类 鸢尾花Iris Dataset数据集是机器学习领域经典数据集,鸢尾花数据集包含了150条鸢尾花信息,每50条取自三个鸢尾花中之一:Versicolour、Setosa和Virginica
每个花的特征用如下属性描述:
代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 from sklearn.datasets import load_iris import seaborn as snsimport pandas as pdimport matplotlib.pyplot as pltfrom sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.neighbors import KNeighborsClassifier from sklearn.metrics import accuracy_score def dm01_loadiris (): iris_data = load_iris() print (iris_data) print (iris_data.keys()) print (iris_data.data[:5 ]) print (iris_data.target) print (iris_data.target_names) print (iris_data.feature_names) print (iris_data.DESCR) print (iris_data.filename) def dm02_showiris (): iris_data = load_iris() iris_df = pd.DataFrame(iris_data.data, columns=iris_data.feature_names) iris_df['label' ] = iris_data.target sns.lmplot(x='petal length (cm)' , y='petal width (cm)' , data=iris_df, hue='label' , fit_reg=False ) plt.title('iris data' ) plt.show() def dm03_train_test_split (): iris_data = load_iris() x_train, x_test, y_train, y_test = train_test_split(iris_data.data, iris_data.target, test_size=0.2 , random_state=22 ) print (f'数据总数量: {len (iris_data.data)} ' ) print (f'训练集中的x-特征值: {len (x_train)} ' ) print (f'训练集中的y-目标值: {len (y_train)} ' ) print (f'测试集中的x-特征值: {len (x_test)} ' ) def dm04_model_train_and_predict (): iris_data = load_iris() x_train, x_test, y_train, y_test = train_test_split(iris_data.data, iris_data.target, test_size=0.2 , random_state=22 ) transfer = StandardScaler() x_train = transfer.fit_transform(x_train) x_test = transfer.transform(x_test) estimator = KNeighborsClassifier(n_neighbors=5 ) estimator.fit(x_train, y_train) y_predict = estimator.predict(x_test) print (f'预测结果为: {y_predict} ' ) my_data = [[5.1 , 3.5 , 1.4 , 0.2 ]] my_data = transfer.transform(my_data) my_predict = estimator.predict(my_data) print (f'预测结果为: {my_predict} ' ) my_predict_proba = estimator.predict_proba(my_data) print (f'预测概率为: {my_predict_proba} ' ) my_score = estimator.score(x_test, y_test) print (my_score) print (accuracy_score(y_test, y_predict)) if __name__ == '__main__' : dm04_model_train_and_predict()
超参数选择的方法 学习目标:
1.知道交叉验证是什么?
2.知道网格搜索是什么?
3.知道交叉验证网格搜索API函数用法
4.能实践交叉验证网格搜索进行模型超参数调优
5.利用KNN算法实现手写数字识别
【知道】交叉验证 交叉验证是一种数据集的分割方法,将训练集划分为 n 份,其中一份做验证集、其他n-1份做训练集集
交叉验证法原理 :将数据集划分为 cv=10 份:
1.第一次:把第一份数据做验证集,其他数据做训练
2.第二次:把第二份数据做验证集,其他数据做训练
3…. 以此类推,总共训练10次,评估10次。
4.使用训练集+验证集多次评估模型,取平均值做交叉验证为模型得分
5.若k=5模型得分最好,再使用全部训练集(训练集+验证集) 对k=5模型再训练一边,再使用测试集对k=5模型做评估
【知道】网格搜索
交叉验证网格搜索的API:
交叉验证网格搜索在鸢尾花分类中的应用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split, GridSearchCV from sklearn.preprocessing import StandardScaler from sklearn.neighbors import KNeighborsClassifier from sklearn.metrics import accuracy_score iris_data = load_iris() x_train, x_test, y_train, y_test = train_test_split(iris_data.data, iris_data.target, test_size=0.2 , random_state=22 ) transfer = StandardScaler() x_train = transfer.fit_transform(x_train) x_test = transfer.transform(x_test) estimator = KNeighborsClassifier() param_grid = {"n_neighbors" : range (1 , 10 )} estimator = GridSearchCV(estimator=estimator, param_grid=param_grid, cv=5 ) estimator.fit(x_train, y_train) print (estimator.best_score_) print (estimator.best_estimator_) print (estimator.cv_results_) print (estimator.best_params_) estimator = KNeighborsClassifier(n_neighbors=6 ) estimator.fit(x_train, y_train) print (f'模型评估: {estimator.score(x_test, y_test)} ' )
利用KNN算法实现手写数字识别
MNIST手写数字识别 是计算机视觉领域中 “hello world”级别的数据集
1999年发布,成为分类算法基准测试的基础
随着新的机器学习技术的出现,MNIST仍然是研究人员和学习者的可靠资源。
本次案例中,我们的目标是从数万个手写图像的数据集中正确识别数字。
数据介绍 数据文件 train.csv 和 test.csv 包含从 0 到 9 的手绘数字的灰度图像。
每个图像高 28 像素,宽28 像素,共784个像素。
每个像素取值范围[0,255],取值越大意味着该像素颜色越深
训练数据集(train.csv)共785列。第一列为 “标签”,为该图片对应的手写数字。其余784列为该图像的像素值
训练集中的特征名称均有pixel前缀,后面的数字([0,783])代表了像素的序号。
像素组成图像如下:
1 2 3 4 5 6 000 001 002 003 ... 026 027028 029 030 031 ... 054 055 056 057 058 059 ... 082 083 | | | | ...... | | 728 729 730 731 ... 754 755 756 757 758 759 ... 782 783
数据集示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 import matplotlib.pyplot as pltimport pandas as pdfrom sklearn.model_selection import train_test_splitfrom sklearn.neighbors import KNeighborsClassifierimport joblibfrom collections import Counterdef show_digit (idx ): data = pd.read_csv('手写数字识别.csv' ) if idx < 0 or idx > len (data) - 1 : return x = data.iloc[:, 1 :] y = data.iloc[:, 0 ] print (f'数据基本信息: {x.shape} )' ) print (f'类别数据比例: {Counter(y)} ' ) digit = x.iloc[idx].values.reshape(28 , 28 ) plt.axis('off' ) plt.imshow(digit, cmap='gray' ) plt.show() def train_model (): data = pd.read_csv('手写数字识别.csv' ) x = data.iloc[:, 1 :] y = data.iloc[:, 0 ] x = x / 255 x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2 , stratify=y, random_state=21 ) estimator = KNeighborsClassifier(n_neighbors=3 ) estimator.fit(x_train, y_train) my_score = estimator.score(x_test, y_test) print (f'测试集准确率为: {my_score:.2 f} ' ) joblib.dump(estimator, 'model/knn.pth' ) def use_model (): img = plt.imread('data/demo.png' ) plt.imshow(img, cmap='gray' ) plt.show() estimator = joblib.load('model/knn.pth' ) img = img.reshape(1 , -1 ) y_test = estimator.predict(img) print (f'您绘制的数字是: {y_test} ' ) if __name__ == '__main__' : use_model()
作业 1.完成KNN算法部分的思维导图
2.说明常见的距离度量方法
3.说明特征预处理的方法
4.编写KNN代码实现鸢尾花分类案例
5.编写KNN代码实现手写数字识别(特征预处理,交叉验证网格搜索)