PCA降维算法应用实例----kaggle手写数字识别
2021/7/11 20:36:22
本文主要是介绍PCA降维算法应用实例----kaggle手写数字识别,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
文章目录
- 序言
- 正题
- 编程环境
- 数据准备
- 导包
- 导入数据
- PCA参数的选择
- 画降维后特征的信息量累计和曲线
- 结合模型,进一步选择n_components的值
- 结合模型,寻得最佳参数
- KNN模型表现
- 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手写数字识别的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-02在 Objective-C 中strong 和 retain有什么区别-icode9专业技术文章分享
- 2024-11-02NSString 中的 hasPrefix 有什么作用-icode9专业技术文章分享
- 2024-11-02在 C 和 Objective-C 中inline的用法是什么-icode9专业技术文章分享
- 2024-11-02文件掩码什么意思?-icode9专业技术文章分享
- 2024-11-02在 Git 提交之前运行 composer cs-fix 命令怎么实现-icode9专业技术文章分享
- 2024-11-02为 Composer 的 cs-fix 命令指定一个目录怎么实现-icode9专业技术文章分享
- 2024-11-02微信公众号开发中怎么获取用户的 unionid-icode9专业技术文章分享
- 2024-11-01lip-sync公司指南:一文读懂主要玩家和技术
- 2024-11-01Anthropic的新RAG方法——提升大型语言模型在特定领域的表现
- 2024-11-01UniApp 中组件的生命周期是多少-icode9专业技术文章分享