【问题标题】:Classify using components from PCA使用来自 PCA 的组件进行分类
【发布时间】:2020-07-15 07:53:03
【问题描述】:

我对我的数据集使用了 PCA 分析,如下所示:

from sklearn.decomposition import PCA
pca = PCA(n_components=3)
principalComponents = pca.fit_transform(scale_x)
principalDf = pd.DataFrame(data=principalComponents, columns = ['PC1', 'PC2', 'PC3'])

然后使用 MatPlotLib 可视化结果 - 我可以看到我的两个类之间的划分如下:

from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

ax.scatter(principalDf['PC1'].values, principalDf['PC2'].values, principalDf['PC3'].values, c=['red' if m==0 else 'green' for m in y], marker='o')

ax.set_xlabel('PC1')
ax.set_ylabel('PC2')
ax.set_zlabel('PC3')

plt.show()

但是当我使用像 SVM 或 Logistic Regression 这样的分类模型时,它无法学习这种关系:

from sklearn.linear_model import LogisticRegression
lg = LogisticRegression(solver = 'lbfgs')
lg.fit(principalDf.values, y)
lg_p = lg.predict(principalDf.values)
print(classification_report(y, lg_p, target_names=['Failure', 'Success']))
                 precision    recall  f1-score   support

        Failure       1.00      0.03      0.06        67
        Success       0.77      1.00      0.87       219

       accuracy                           0.77       286
      macro avg       0.89      0.51      0.46       286
   weighted avg       0.82      0.77      0.68       286

这可能是什么原因?

【问题讨论】:

    标签: python matplotlib machine-learning scikit-learn pca


    【解决方案1】:

    不管你的结果是否有意义,你在这里做的事情根本上是错误的,那就是在整个数据集上训练分类器并在看到的数据上测试结果。我已经使用 iris 数据集重现了您的问题,并拟合了一个逻辑回归器,对我产生了很好的结果:

    from sklearn.datasets import load_iris
    from sklearn.decomposition import PCA
    from sklearn.linear_model import LogisticRegression
    from sklearn.metrics import confusion_matrix
    from sklearn.model_selection import train_test_split
    
    data = load_iris()
    X = data.data
    y = data.target
    
    pca = PCA(n_components=3)
    principalComponents = pca.fit_transform(X)
    principalDf = pd.DataFrame(data=principalComponents, columns = ['PC1', 'PC2', 'PC3'])
    
    from mpl_toolkits.mplot3d import Axes3D
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    
    ax.scatter(principalDf['PC1'].values, 
               principalDf['PC2'].values, 
               principalDf['PC3'].values, 
               c=[['red', 'green', 'blue'][m] for m in y], marker='o')
    
    ax.set_xlabel('PC1')
    ax.set_ylabel('PC2')
    ax.set_zlabel('PC3')
    
    plt.show()
    

    现在,如果我们尝试在 X_test 上进行预测,我们会发现在这种情况下混淆矩阵看起来相当不错,这意味着整体思路应该可以正常工作:

    X_train, X_test, y_train, y_test = train_test_split(principalDf, y)
    
    lg = LogisticRegression(solver = 'lbfgs')
    lg.fit(X_train, y_train)
    y_pred = lg.predict(X_test)
    
    confusion_matrix(y_true=y_test, y_pred=y_pred)
    
    array([[ 9,  0,  0],
           [ 0, 12,  1],
           [ 0,  0, 16]], dtype=int64)
    

    【讨论】:

    • 嗨!是的,这是一个很好的观点——我实际上有一个非常小的数据集,所以我想在训练数据集上查看结果,但是拆分数据集的总体准确度为 86%——非常感谢!跨度>
    【解决方案2】:

    首先,使用三个特征PC1、PC2、PC3。图中未表示的附加特征(PC4 ~ PC6)可能会影响分类结果。

    其次,分类器有时没有像您想象的那样训练好。我建议使用决策树而不是您使用的分类器,因为树是(水平)线性分类器,它会产生您认为的结果。

    【讨论】:

    • 嗨!抱歉,我不小心发布了我更新的 PCA 组件——我在这个可视化中只使用了 3 个组件作为我的 PCA——我尝试将我的组件数量更新为 6,但分类结果没有运气——我也尝试使用随机森林分类器——但结果相同。
    • 我的意思是使用三个特征 (PC1 ~ PC3) 来训练分类器,以及单棵树(诸如随机森林之类的集合会产生你意想不到的决策边界。)
    • 是的,使用决策树确实将我的结果提高到 86%,谢谢!
    猜你喜欢
    • 2018-04-15
    • 2013-01-14
    • 2014-06-11
    • 1970-01-01
    • 2013-04-07
    • 2017-12-24
    • 2014-12-31
    • 1970-01-01
    • 2012-11-20
    相关资源
    最近更新 更多