美文网首页
降维算法——PCA对手写数字数据集的降维

降维算法——PCA对手写数字数据集的降维

作者: YUENFUNGDATA | 来源:发表于2020-05-24 16:41 被阅读0次

    一、数据来源

    手写数字数据集 digit recognizor.csv

    二、模型选择

    from sklearn.decomposition import PCA
    from sklearn.model_selection import cross_val_score
    from sklearn.ensemble import RandomForestClassifier as RFC
    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    

    降维算法选择decomposition模块下的PCA
    随机森林算法RandomForestClassifier
    KNN算法KNeighborsClassifier

    三、数据预处理

    data=pd.read_csv("C:\\Users\\DRF\\Desktop\\digit recognizor.csv")
    data.head()
    x=data.iloc[:,1:]
    y=data.iloc[:,0]
    

    读取数据集后,选择前5行观察,第一列label为标签,后面列的数据为特征,因此切片令x=data.iloc[:,1:],y=data.iloc[:,0]

    四、分析过程

    1)画出累计方差贡献率曲线,找最佳降维后维度的范围
    pca=PCA().fit(x)
    plt.figure(figsize=[20,5])
    plt.plot(np.cumsum(pca.explained_variance_ratio_))
    plt.xlabel("number of components after dimension reduction")
    plt.ylabel("cumulative explained variance ratio")
    plt.show()
    

    首先,PCA实例化,n_components不填任何值,来观察可解释性方差贡献率曲线



    通过上图可以看到,n_components在[0,100]直接可解释性方差贡献提高迅速,[100,400]提速逐渐降低,[400,800]几乎没有提高。我们需要找到一个明显变化转折点,可以看到当等于200的时候,可解释性方差累计贡献差不多达到了95%左右,后面几乎没有增加了。因此我们继续对n_components细化,希望找到最优点。

    2)降维后维度的学习曲线,继续缩小最佳维度的范围
    score=[]
    for i in range(1,101,10):
        x_dr=PCA(i).fit_transform(x)
        once=cross_val_score(RFC(n_estimators=10,random_state=0),x_dr,y,cv=5).mean()
        score.append(once)
    plt.figure(figsize=[20,5])
    plt.plot(range(1,101,10),score)
    plt.show()
    

    当细化到[0,101],步长为10时,最高点大约在10至30之间,继续进一步细化寻找最高点。

    3)细化学习曲线,找出降维后的最佳维度
    score=[]
    for i in range(10,25):
        x_dr=PCA(i).fit_transform(x)
        once=cross_val_score(RFC(n_estimators=10,random_state=0),x_dr,y,cv=5).mean()
        score.append(once)
    plt.figure(figsize=[20,5])
    plt.plot(range(10,25),score)
    plt.show()
    
    4)导入找出的最佳维度进行降维,查看模型效果
    x_dr=PCA(21).fit_transform(x)
    cross_val_score(RFC(n_estimators=10,random_state=0),x_dr,y,cv=5).mean()
    

    可以看到,当n_components为21的时候,随机森林模型的准确率达到了最高点,达到了0.9179761257042178,超过了90%。

    5)模型极限?更换模型?

    优化1:那么将随机森林模型n_estimators调高至100呢?

    x_dr=PCA(21).fit_transform(x)
    cross_val_score(RFC(n_estimators=100,random_state=0),x_dr,y,cv=5).mean()
    

    模型的准确度立刻上升至0.9434522864584884,提高了0.02954762!模型效果还好,跑出了94.49%的水平,随机森林模型极限最高可能也只有96%左右,有没有其他办法能够提高模型的表现呢?

    优化2:更换模型KNN,模型的准确率会不会比随机森林有所提升?

    在之前的建模过程中,因为计算量太大,所以我们一直使用随机森林,但事实上,我们知道KNN的效果比随机森林更好,KNN在未调参的状况下已经达到96%的准确率,而随机森林在未调参前只能达到93%,这是模型本身的限制带来的,这个数据使用KNN效果就是会更好。现在我们的特征数量已经降到不足原来的3%,可以使用KNN了吗?

    from sklearn.neighbors import KNeighborsClassifier as KNN
    cross_val_score(KNN(),x_dr,y,cv=5).mean()
    

    未调参的KNN模型准确率直接达到了0.9675948870484117!可见KNN的效果是非常好的!下面进一步调参KNN,希望进一步提高模型的准确率。

    6)KNN学习曲线
    score=[]
    for i in range(10):
        x_dr=PCA(21).fit_transform(x)
        once=cross_val_score(KNN(i+1),x_dr,y,cv=5).mean()
        score.append(once)
    plt.figure(figsize=[20,5])
    plt.plot(range(10),score)
    plt.show()
    cross_val_score(KNN(3),x_dr,y,cv=5).mean()
    

    根据上图得知,当横坐标等于2,KNN 参数 k = i+1 = 2+1 = 3 时,模型的准确率最高,达到0.9682375117716753。

    可以发现,原本785列的特征被我们缩减到21列之后,用KNN跑出了目前位置这个数据集上最好的结果。如果再进行更细致的调整,我们也许可以将KNN的效果调整到98%以上。PCA能够帮助我们不会因为数据量太庞大而被迫选择更加复杂的模型。

    ·································································································································································
    完整代码如下:

    from sklearn.decomposition import PCA                      #导入降维算法PCA
    from sklearn.model_selection import cross_val_score        #导入交叉验证
    from sklearn.ensemble import RandomForestClassifier as RFC #导入随机森林模块
    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    
    data=pd.read_csv("C:\\Users\\DRF\\Desktop\\digit recognizor.csv") #导入手写数字数据集
    data.head() #观察前五行数据
    
    x=data.iloc[:,1:] #划分特征
    y=data.iloc[:,0]  #划分标签
    
    pca=PCA().fit(x)  #实例化 拟合
    plt.figure(figsize=[20,5]) #新建画布 大小为20x5
    plt.plot(np.cumsum(pca.explained_variance_ratio_))           #绘制可解释性方差贡献率曲线图
    plt.xlabel("number of components after dimension reduction") #x轴坐标名称
    plt.ylabel("cumulative explained variance ratio")            #y轴坐标名称
    plt.show()
    
    score=[]
    for i in range(1,101,10):
        x_dr=PCA(i).fit_transform(x) #实例化拟合训练转换
        once=cross_val_score(RFC(n_estimators=10,random_state=0),x_dr,y,cv=5).mean() #交叉验证随机森林求准确率
        score.append(once)
    plt.figure(figsize=[20,5])
    plt.plot(range(1,101,10),score)
    plt.show()
    
    score=[]
    for i in range(10,25):
        x_dr=PCA(i).fit_transform(x)
        once=cross_val_score(RFC(n_estimators=10,random_state=0),x_dr,y,cv=5).mean()
        score.append(once)
    plt.figure(figsize=[20,5])
    plt.plot(range(10,25),score)
    plt.show()
    
    x_dr=PCA(21).fit_transform(x)
    cross_val_score(RFC(n_estimators=10,random_state=0),x_dr,y,cv=5).mean()
    
    x_dr=PCA(21).fit_transform(x)
    cross_val_score(RFC(n_estimators=100,random_state=0),x_dr,y,cv=5).mean()
    
    from sklearn.neighbors import KNeighborsClassifier as KNN #导入KNN算法模块
    cross_val_score(KNN(),x_dr,y,cv=5).mean()
    
    score=[]
    for i in range(10):
        x_dr=PCA(21).fit_transform(x)
        once=cross_val_score(KNN(i+1),x_dr,y,cv=5).mean()
        score.append(once)
    plt.figure(figsize=[20,5])
    plt.plot(range(10),score)
    plt.show()
    
    cross_val_score(KNN(3),x_dr,y,cv=5).mean()
    

    相关文章

      网友评论

          本文标题:降维算法——PCA对手写数字数据集的降维

          本文链接:https://www.haomeiwen.com/subject/pzcjahtx.html