根据菜菜的课程进行整理,方便记忆理解
代码位置如下:
PCA对手写数字数据集的降维
数据集结构为(42000, 784),用KNN跑一次半小时,得到准确率在96.6%上下,用随机森林跑一次12秒,准确率在93.8%,虽然KNN效果好,但由于数据量太大,KNN计算太缓慢,所以我们不得不选用随机森林。我们使用了各种技术对手写数据集进行特征选择,最后使用嵌入法SelectFromModel选出了324个特征,将随机森林的效果也调到了96%以上。因为数据量依然巨大,还是有300多个特征
- 导入需要的模块和库
from sklearn.model_selection import cross_val_score
from sklearn.decomposition import PCA
from sklearn.ensemble import RandomForestClassifier
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
- 导入数据,探索数据
data = pd.read_csv("digit recognizor.csv")
data.shape
# (42000, 785)
data.head()
y = data.iloc[:,0]
x = data.iloc[:,1:]
- 画累计方差贡献率曲线,找最佳降维后维度的范围
pca = PCA().fit(x)
# 绘制可解释性方差曲线
plt.figure(figsize=(10,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()
- 降维后维度的学习曲线,继续缩小最佳维度的范围
# 绘制降维的学习曲线
n_score = []
for i in range(1,100,10):
x_dr = PCA(i).fit_transform(x)
c_score = cross_val_score(RandomForestClassifier(n_estimators=100,random_state=20),x_dr,y,cv=5).mean()
n_score.append(c_score)
plt.figure(figsize=(10,5))
plt.plot(range(1,101,10),n_score,color="r")
plt.show()
- 细化学习曲线,找出降维后的最佳维度
# 我们从学习曲线中细化特征降维的具体范围
n_score = []
for i in range(20,30):
x_dr = PCA(i).fit_transform(x)
c_score = cross_val_score(RandomForestClassifier(n_estimators=100,random_state=20),x_dr,y,cv=5).mean()
n_score.append(c_score)
plt.figure(figsize=(10,5))
plt.plot(range(20,30),n_score,color="r")
plt.show()
- 导入找出的最佳维度进行降维,查看模型效果
x_dr = PCA(28).fit_transform(x)
#======【TIME WARNING:1mins 30s】======#
cross_val_score(RandomForestClassifier(n_estimators=100,random_state=0),x_dr,y,cv=5).mean()
# 0.9477619047619049
模型效果还好,跑出了94.77%的水平,但还是没有我们使用嵌入法特征选择过后的96%高
- 突发奇想,特征数量已经不足原来的3%,换模型怎么样?
- 在之前的建模过程中,因为计算量太大,所以我们一直使用随机森林,但事实上,我们知道KNN的效果比随机森林更好,KNN在未调参的状况下已经达到96%的准确率,而随机森林在未调参前只能达到93%,这是模型本身的限制带来的,这个数据使用KNN效果就是会更好。现在我们的特征数量已经降到不足原来的3%,可以使用KNN
from sklearn.neighbors import KNeighborsClassifier as KNN
cross_val_score(KNN(),x_dr,y,cv=5).mean()
# 0.9717857142857144
- KNN的k值学习曲线
# knn的学习曲线
#======【TIME WARNING: 】======#
score = []
for i in range(10):
x_dr = PCA(28).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(4),x_dr,y,cv=5).mean()
# 0.9713333333333333
原本785列的特征被我们缩减到4列之后,用KNN跑出了目前位置这个数据集上最好的结果。再进行更细致的调整,我们也许可以将KNN的效果调整到98%以上。PCA为我们提供了无限的可能,终于不用再因为数据量太庞大而被迫选择更加复杂的模型了!