ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

PCA降维算法应用实例----kaggle手写数字识别

2021-07-11 20:30:49  阅读:231  来源: 互联网

标签:PCA 训练 kaggle ---- 降维 train components test pca


文章目录

序言

在前面的博文中我们了解了降维算法PCA,以及PCA的参数。这篇文章建立在对PCA有了一定的基础的前提上。本篇文章主要将PCA算法在实际中的应用。包含PCA参数的选择,训练集,测试集上PCA的使用,解决PCA实际应用中的困惑。本文使用的是kaggle上digit-regognizer数据集

正题

编程环境

  • python3.7
  • anaconda
  • jupyter notebook

数据准备

可以通过官方渠道获得数据,也可以通过博主上传的数据下载。
这次使用的数据集是kaggle的digit-recognizer数据集。数据集中包含三个csv文件如下图
在这里插入图片描述
sample_submission.csv是提交到kaggle的csv文件格式。train.csv是数据的训练集,包含了784个特征和一个标签列。共42000组数据。test.csv为测试集,包含了784个特征,该数据集没有标签这一列,共28000组数据。本次仅使用该数据集中的训练集。通过sklearn将原训练集划分为新的训练集,测试集。

导包

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA # PCA降维算法
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score # 交叉检验
from sklearn.neighbors import KNeighborsClassifier # KNN分类器
from sklearn.model_selection import train_test_split # 分割训练集,测试集

%matplotlib inline

导入数据

file = "../data/digit-recognizer/train.csv" # 换成自己本地的数据集路径

df = pd.read_csv(file)

df.shape #(42000, 785)
# 可以看出数据集非常的庞大

# 特征标签分离
X = df.loc[:, df.columns != 'label']
y = df.loc[:, df.columns == 'label'].values.ravel()

PCA参数的选择

画降维后特征的信息量累计和曲线

这一步PCA不人为设置任何参数,使用PCA的默认值。通过explained_variance_ratio_属性获得新的特征的信息量占原信息的信息量的比例

# 默认返回值PCA返回的特征个数为min(shape(X))
# 获得经过一次变化后的特征的信息量
pca_default = PCA()
X_defaule = pca_default.fit_transform(X)

# 获得每一个新特征的信息量占比
explained_vars = pca_default.explained_variance_ratio_

# 通过np.cumsum计算特征信息量的累计和
var_sum = np.cumsum(explained_vars)

# 画出特征信息量的累计和曲线
plt.figure(figsize=(10, 5))
plt.plot(range(X.shape[1]), var_sum)
plt.xticks(range(0, X.shape[1], 50))
plt.show()

在这里插入图片描述

结合模型,进一步选择n_components的值

前面已经提到过了,对n_components参数的选择,一般是选择曲线的转折点处。

# 对于n_components的选择一般选择曲线上的转折点附近的值
# 从图中可以看出转折点在50-100之间
# 在50 的时候信息量已经达到了80%,在100信息量已经达到了接近90%了
# 再继续网上,信息量增加比较缓慢。继续纠结于更多的特征
# 就与我们降维的目的相悖了。索引选择特征较小的0-100
# 可以知道0-100之间一定有一个值是我们需要的
# 接下来将n_components设置在0-100之间,通过模型的评分
# 选择出一共较优的参数

n_components = range(1, 101, 10)
scores = []
for i in n_components :
    X_new = PCA(n_components=i).fit_transform(X)
    scores.append(cross_val_score(RandomForestClassifier(n_estimators=21, random_state=1),
                                 X_new, y, cv=5).mean())

fig = plt.figure(figsize=(10, 5))
plt.plot(n_components, scores)
plt.xticks(range(0, 101, 10))
plt.show()

在这里插入图片描述

结合模型,寻得最佳参数

# 从图中可以看出只要10个特征我们的模型就可以有一个很好的表现
# 当特征数量在20的时候模型的表现达到最好,这是步长为10的学习曲线
# 下面进行细致的学习曲线
# 将特征数量控制在10-30之间,画出学习曲线确定最终的PCA参数
n_components = range(10, 30)
scores = []
for i in n_components :
    X_new = PCA(n_components=i).fit_transform(X)
    scores.append(cross_val_score(RandomForestClassifier(n_estimators=21, random_state=1),
                                 X_new, y, cv=5).mean())

fig = plt.figure(figsize=(10, 5))
plt.plot(n_components, scores)
plt.xticks(range(9, 31))
plt.show()

在这里插入图片描述
从图中可以看出当n_components=24时模型的表选达到最好
确定了PCA的最佳参数,接下来要将模型的表现推到最好就需要对模型进行调参了。关于随机森林的调参看我前面的博文。关于调参这里不进行展示了。如果经过调参,模型的表现还是没有多大提高,就可以考虑换一个模型试试了。但是换模型可能遇到的问题有:可能需要重新进行PCA降维操作。

KNN模型表现

# 经过PCA降维后的特征只有24个特征了,与之之前的784给特征相比
# 无疑是少了非常多的,这里可以选择使用KNN模型来试试
X_final = PCA(n_components=24).fit_transform(X)
knn = KNeighborsClassifier()
score = cross_val_score(knn, X_final, y, cv=10).mean()
print(score) # 0.971355806769633

PCA用于训练集测试集

上面已经将来PCA的参数选择了。但是还是有一个疑惑留给我们。那就是怎样让我的降维PCA能够适用于训练集,测试集呢。这里沿用上面的数据进行讲解。

可能的两种思路

  • 思路1:直接实例化PCA并分别再训练姐,测试集上fit_transform获得新的特征
  • 思路2:实例化PCA,再训练集上进行PCA训练,并将训练后的PCA应用到训练集,测试集。
    显而易见思路二是正确的。这个思路可参考模型训练应用的过程。

两种思路的对比

训练集测试集的划分

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=3)

思路一结果

# 不fit直接再训练集,测试集上使用pca
# *******************************
pca_24 = PCA(n_components=24)
# ********************************
pca_X_train = pca_24.fit_transform(X_train)
pca_X_test = pca_24.fit_transform(X_test)
knn = KNeighborsClassifier()
knn.fit(pca_X_train, y_train)
score = knn.score(pca_X_test, y_test)
print(score) # 0.7936507936507936
# 难以形象居然有79%的准确度。这属于是运去非常好的了
# 之前的几次表现只有0.3左右。说明这次训练集测试集的划分非常完美

思路二结果

# fit后使用pca
# 不fit直接再训练集,测试集上使用pca
# ******************************************
pca_24 = PCA(n_components=24).fit(X_train)
# *******************************************
pca_X_train = pca_24.transform(X_train)
pca_X_test = pca_24.transform(X_test)
knn = KNeighborsClassifier()
knn.fit(pca_X_train, y_train)
score = knn.score(pca_X_test, y_test)
print(score) # 0.9691269841269842

对比两个结果可以看出,通过训练后再应用pca,明显才是正确的做法。模型的表现简直是质的飞跃。

总结

到这里关于PCA的基础已经学习完了。需要注意的就是PCA参数的选择方法。PCA再训练集,测试集上的使用,一定要经过“训练”。PCA再训练集,测试集上的使用,一定要经过“训练”。PCA再训练集,测试集上的使用,一定要经过“训练”。。重要的事情说三遍。


欢迎在评论区和我进行讨论,互相学习

标签:PCA,训练,kaggle,----,降维,train,components,test,pca
来源: https://blog.csdn.net/weixin_43776305/article/details/118658278

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有