机器学习大作业(1):KNN分类器的研究

《机器学习大作业(1):KNN分类器的研究》

一、 任务目标

  • Develop a k-NN classifier with Euclidean distance and simple voting
  • Perform 5-fold cross validation, find out which k performs the best (in terms of accuracy)
  • Use PCA to reduce the dimensionality to 6, then perform 2) again. Does PCA improve the accuracy?
  • Explore the data before classification using summary statistics or visualization
  • Pre-process the data (such as denoising, normalization, feature selection, …)
  • Try other distance metrics or distance-based voting
  • Try other dimensionality reduction methods
  • How to set the k value, if not using cross validation? Verify your idea

二、 数据集介绍

Wine Date Set
Abstract:Using chemical analysis determine the origin of wines

《机器学习大作业(1):KNN分类器的研究》

更多细节见:http://archive.ics.uci.edu/ml/datasets/Wine

三、 实验过程

1)加载数据,求各个统计量

《机器学习大作业(1):KNN分类器的研究》 图3-1 加载数据集和求统计量key code

read_csv()函数说明:https://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_csv.html

第一个参数为本地数据库的绝对路径; 第二个参数代表 List of column names to use,即数据集中各列的名称。

Describe()函数说明: https://pandas.pydata.org/pandas-docs/stable/generated/pandas.core.groupby.DataFrameGroupBy.describe.html

返回数据集的每个特征的各个统计量。实验结果如图3-2所示.

《机器学习大作业(1):KNN分类器的研究》 图3-2 数据集各个特征的统计量

2)数据可视化:画箱线图

《机器学习大作业(1):KNN分类器的研究》 图3-3 画箱线图key code

利用 pandas.DataFrame.plot()函数实现: https://pandas.pydata.org/pandasdocs/stable/generated/pandas.DataFrame.plot.html?highlight=plot

各参数含义如下:
Kind:plot 图的类型
Subplots: Make separate subplots for each column, 即为每列创建一个子图;
Layout: (rows, columns) for the layout of subplots;
Sharex/sharey: 指示各子图是否共用同一坐标系;

《机器学习大作业(1):KNN分类器的研究》 图3-4:原始数据的箱线图

3)数据清洗和特征标准化

利用箱线图,我们可以轻易发现离群点(图3-4中黑色圆圈点)。利用图3-5中的代码可将离群点的值打印出来。

《机器学习大作业(1):KNN分类器的研究》 图3-5 打印离群点值key code

对离群点,我们可将其视为缺失值,并用前后点的平均值代替。表3-1列出了所有离群点以及相应的修正值。

《机器学习大作业(1):KNN分类器的研究》

我们采用均值方差归一化算法,可以利用sklearn库中的StandardScaler函数实现,详见:
http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html

《机器学习大作业(1):KNN分类器的研究》 图3-6 数据标准化key code

4)分割数据集

《机器学习大作业(1):KNN分类器的研究》 图3-7 数据集分割key code

利用sklearn库中的
train_test_split可以方便地将数据集随机划分成指定比例的训练集和测试集:

http://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html

X_n: 标准化的后的数集 ;

y_n :数据标签,注意必须为一维数组,由于从dataset转化来的y_n为二维array:
[[y0,y1..]] ,所以取array[0]转化成一维arrray;

test_size :测试集默认为数据集样本数量的0.25;

random-state:随机数种子.

5)建立KNN模型(基于欧式距离和简单投票)

《机器学习大作业(1):KNN分类器的研究》 图3-7 建立KNN模型key code

http://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KNeighborsClassifier.html

利用KNeighborsClassifier****(n_neighbors=5, weights=’uniform’)**建立KNN分类器:

n_neighbors: 指定“近邻”的数量,默认为5;

weights: 是否进行基于距离的加权投票,默认设为uniform,等权加权;如果设置为distance,则以距离倒数为权重进行投票,此时离

中心样本更近的邻居对分类结果有更大的影响。

利用score(X, y) Returns the mean accuracy on the given test data and labels.

实验结果: 分类准确率为1.0

6)利用5折交叉验证寻找最佳K值

《机器学习大作业(1):KNN分类器的研究》 图3-8 交叉验证寻找最佳K值key code

利用sklearn中的cross_val_score函数进行交叉验证,各参数含义为:

knn: 待验证的基础分类器。每次迭代过程中,向cross_val_score传递不同K值 的KNN分类器。

X_n,y_n:数据集和标签集;

Cv: 指定k-交叉验证的k值;

关于KNN 分类器中K值的选取,体现了bias_variance_trade-off观点:

K值过小,模型复杂度上升,容易发生过拟合;

K值过大,模型过于简单,容易发生欠拟合,若K=N(数据集大小),对于输入实例,将简单地预测它属于训练实例中最多的类。

K值选取的经验方法:一般取训练数集大小的平方根,且取奇数。在本实验中,K经验值取13

7)将步骤6的实验结果进行可视化,选取最佳K值

《机器学习大作业(1):KNN分类器的研究》 图3-9 可视化下不同K值的分类器准确率key code

我们取k=[1,3,5,7,9,11,13,15,17,19,21]中的不同值,将平均准确率进行可视化,见图3-10所示。

《机器学习大作业(1):KNN分类器的研究》 图3-10 不同K值下的准确率

随着K值从1开始逐渐增大,准确率渐渐提升。在K=13时达到峰值,随后下降再上升,可以预计当K大于一定阈值后,准确率将再度下降。如前所示,K值选取不宜过大或过小,最佳K值应该在13附近。

从上述分析知,本实验最佳K值等于13,此时准确率为0.972.

8)使用距离加权投票训练KNN,重复步骤6,7

训练距离加权的KNN,只要将KneighborsClassifier中的weight参数设置为‘distance’即可。
knn = KNeighborsClassifier(n_neighbors = k,weights = ‘distance’)
其他代码不变,实验结果如图3-11所示。

《机器学习大作业(1):KNN分类器的研究》 图3-11 不同K值下的加权KNN分类器准确率

对照图3-10和3-11知,两类的KNN的随近邻数K值变化的准确率走势基本一致。加权KNN的最佳K值亦是13,准确率为0.972.

9)对数据进行PCA降维,重复步骤6,7

《机器学习大作业(1):KNN分类器的研究》 图3-12 PCA降维key code

可以调用 scikit_learn 库中的
PCA函数实现目的:

http://scikit-learn.org/stable/modules/generated/sklearn.decomposition.PCA.html

Pca=PCA(n_component=6)含义:设置保留主成分个数为 6.

newData=pca.fit_transform(X)含义:用 X_n来训练 PCA 模型,同时返回降维后的数据。

为什么要进行特征降维?原因之一是去冗余,更重要的原因是:在高维空间下,样本将变得稀疏,相同K值,高维度空间比低维度空间需要更多训练样本。当维度趋于无穷,距离度量失去意义(维度灾难)。基于距离计算的模型如Kmeans ,KNN,维度过高时会影响精度和性能。

对降维后的数据训练KNN,重复步骤6和7,实验结果如图3-13所示。
由左图可以看出,进行PCA将维后,当K=17时,取得最高准确率0.989,准确率提高了一个百分点。

10)对数据进行LDA降维,重复步骤6,7

《机器学习大作业(1):KNN分类器的研究》 图3-12 LDA降维key code

可以调用 scikit_learn 库中的LinearDiscriminantAnalysis()函数实现目的:

http://scikit-learn.org/stable/modules/generated/sklearn.discriminant_analysis.LinearDiscriminantAnalysis.html

LDA=LinearDiscriminantAnalysis() 含义:返回一个LDA分类器
newData=LDA.fit_transform(X) 含义:用 X_n来训练LDA模型,同时返回降维后的数据。

注意:对N维数据,数据类别数为C,则LDA降维后数据维度为C-1,与N无关。在本实验中,降维后的数据维度为2.

对降维后的数据训练KNN,重复步骤6,7,实验结果如图3-13所示。

由右图可以看出,进行LDA将维后,当K=7时,取到最高准确率0.995,相较PCA,准确率提高了一个百分点.

《机器学习大作业(1):KNN分类器的研究》 图3-13 降维后KNN准确率曲线(左为PCA,右为LDA)

11)利用BAGGING法寻找最佳K值

除了K折交叉验证法,我们还可以利用委员会算法寻找最佳K值。Bagging 是其代表,其基本思想是:

i.对一个单独数据集,利用bootstrap(放回抽样)产生M个自助数据集。

ii.对每一个K值,我们利用这M个自助数据集训练M个独立模型

iii.对每一个实例,委员会预测为M个独立模型的平均值。

我们可以利用sklearn库中的BaggingClassifier()函数实现目的,参考:

http://scikit-learn.org/stable/modules/generated/sklearn.ensemble.BaggingClassifier.html

《机器学习大作业(1):KNN分类器的研究》 图3-14 bagging算法key code

代码中各参数含义为:

KneighborsClassifier(n_neighbors = k) : 指定委员会的基础分类器;

max_samples: 每个自助集占原始数据集的最大比例;

n_estimator: 指定委员会成员数量。

Bootstrap: 若为true,则进行放回抽样。

图3-15 给出了利用bagging算法衡量不同k值下的KNN分类器准确率曲线图。

《机器学习大作业(1):KNN分类器的研究》 图3-15 bagging算法选取最佳K值

我们发现K=1时,取到最高准确率。这是因为K=1时,模型方差很大,但是加和求平均后偏置很小,从而产生了预测效果的提升。在K>5后,曲线趋于平缓,说明模型偏置和方差得到了相对平衡。利用bagging算法,我们选取K=7,此时准确率为0.983.

四、 实验总结

《机器学习大作业(1):KNN分类器的研究》 表4-1 各类算法准确率和最佳K值选取

针对KNN算法,我们有以下几点结论,这些结论在本文第二部分中均得到具体阐述。

  • 特征归一化至关重要,目的是使各项特征对距离计算的贡献度保持一致。

  • 基于距离加权的KNN与普通投票的KNN分类效果相差不大。

  • 当数据维度过高时,特征降维是提升KNN分类器性能的必要手段,在本实验中LDA优于PCA。

  • 可以利用Bagging算法代替k-fold验证法寻找最佳K值。

《机器学习大作业(1):KNN分类器的研究》 转载请说明出处

    原文作者:月牙眼的楼下小黑
    原文地址: https://www.jianshu.com/p/367d2acfe4ce
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞