【4 - 降维算法PCA和SVD - 案例部分】菜菜sklearn机器学习

 课程地址:《菜菜的机器学习sklearn课堂》_哔哩哔哩_bilibili

  • 第一期:sklearn入门 & 决策树在sklearn中的实现
  • 第二期:随机森林在sklearn中的实现
  • 第三期:sklearn中的数据预处理和特征工程
  • 第四期:sklearn中的降维算法PCA和SVD
  • 第五期:sklearn中的逻辑回归
  • 第六期:sklearn中的聚类算法K-Means
  • 第七期:sklearn中的支持向量机SVM(上)
  • 第八期:sklearn中的支持向量机SVM(下)
  • 第九期:sklearn中的线性回归大家族
  • 第十期:sklearn中的朴素贝叶斯
  • 第十一期:sklearn与XGBoost
  • 第十二期:sklearn中的神经网络

目录

案例一:用PCA做噪音过滤(inverse_transform)

(1)导入数据并探索

(2)定义画图函数

(3)为数据加上噪音

(4)降维

(5)逆转降维结果,实现降噪

PCA类的重要接口、参数和属性总结 

重要参数

重要属性

重要接口

案例二:PCA对手写数字数据集的降维

(1)导入数据并探索

(2)画累计方差贡献率曲线,找最佳降维后维度的范围

(3)降维后维度的学习曲线,继续缩小最佳维度的范围

(4)细化学习曲线,找出降维后的最佳维度

(5)导入找出的最佳维度进行降维,查看模型效果

(6)现在特征数量已经不足之前的3%,换模型如何

(7)KNN的k值学习曲线

(8)定下超参数后,模型效果和运行时间如何


案例一:用PCA做噪音过滤(inverse_transform)

降维的目的之一就是希望抛弃掉对模型带来负面影响的特征(带有效信息的特征的方差应是远大于噪音的),所以相比噪音,有效的特征所带的信息应该不会在PCA过程中被大量抛弃

inverse_transform能够在不恢复原始数据的情况下,将降维后的数据返回到原本的高维空间,即能够实现 “保证维度,但去掉方差很小特征所带的信息” 利用该性质能够实现噪音过滤

(1)导入数据并探索

from sklearn.datasets import load_digits   # 手写数字(本质是图像)
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
import numpy as np

digits = load_digits()
digits.data.shape  #(1797, 64)
digits.images.shape  #(1797, 8, 8)  1797个数字,每个数字是8行8列的特征矩阵

set(digits.target.tolist())  #查看target有哪几个数  {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
# digits.target是array
# .tolist()转成列表
# set()去重查看

(2)定义画图函数

# 定义画图函数
def plot_digits(data):
    #data的结构必须是(m,n),并且n=64要能够被分成(8,8)这样的结构
    fig, axes = plt.subplots(4,10  # 4行0-9
                             ,figsize=(10,4)
                             ,subplot_kw = {"xticks":[],"yticks":[]}
                            )
    for i, ax in enumerate(axes.flat):
        ax.imshow(data[i].reshape(8,8),cmap="binary")
        
plot_digits(digits.data)

【4 - 降维算法PCA和SVD - 案例部分】菜菜sklearn机器学习_第1张图片

(3)为数据加上噪音

# 为数据加上噪音
rng = np.random.RandomState(42)  # 规定numpy中的随机模式
 
#在指定的数据集中,随机抽取服从正态分布的数据
#两个参数,分别是指定的数据集,和抽取出来的正态分布的方差
#方差越大,随机抽取出的数字就会越凌乱
noisy = rng.normal(digits.data,2)   #np.random.normal(digits.data,2)
noisy.shape   # (1797,64)
 
plot_digits(noisy)

【4 - 降维算法PCA和SVD - 案例部分】菜菜sklearn机器学习_第2张图片

(4)降维

# 降维
pca = PCA(0.5,svd_solver='full').fit(noisy)  # 原数据信息能保留50%的特征
X_dr = pca.transform(noisy)
X_dr.shape  #(1797, 6)   # 把维度从64降到了6,认为含有噪音的大部分特征都被删掉了,前6个特征应该包含了原始数据的大部分有效特征
# 无法可视化X_dr,因为画图函数要求输入的data第二维是64(能够被分成(8,8))

(5)逆转降维结果,实现降噪

# 逆转降维结果,实现降噪
without_noise = pca.inverse_transform(X_dr)   # (1797,64)
plot_digits(without_noise)

【4 - 降维算法PCA和SVD - 案例部分】菜菜sklearn机器学习_第3张图片


PCA类的重要接口、参数和属性总结 

重要参数

  • n_components:降维后需要的特征数目k;鸢尾花高维数据可视化
  • svd_solver:控制生成的矩阵的结构;为什么PCA中有SVD相关的参数;sklearn中PCA和SVD联合降维的流程
  • random_state:控制SVD的参数中一些拥有随机矩阵分解模式的参数

重要属性

  • components_:调用新特征空间降维后的矩阵V(k,n)
  • explained_variance_:可解释性方差,衡量降维后每个特征所带的信息量
  • explained_variance_ratio_:可解释性方差贡献率,画图,选择最佳的n_components

重要接口

  • fit:拟合数据
  • transform:调取结果
  • fit_transform:拟合+调取结果一步完成
  • inverse_transform:人脸识别中的逆转;手写数字的噪音过滤

【4 - 降维算法PCA和SVD - 案例部分】菜菜sklearn机器学习_第4张图片


案例二:PCA对手写数字数据集的降维

回顾:特征工程章节中使用的手写数字数据集,结构为(42000,784) 

  • KNN准确率 0.966 > 随机森林 0.937,但KNN花费时间太长
  • 使用嵌入法 SelectFromModel 对数据集进行特征选择,选出324个特征,将随机森林的效果也调的接近于KNN了(0.964)
  • 试着用PCA处理该数据

【3 - 特征工程】菜菜sklearn机器学习_如何原谅奋力过但无声的博客-CSDN博客

(1)导入数据并探索

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

data = pd.read_csv(r"D:\Jupyter Notebook\菜菜sklearn\3 数据预处理和特征工程\digit recognizor.csv")
 
X = data.iloc[:,1:]
y = data.iloc[:,0]

X.shape  #(42000, 784)

降维之前要确定超参数n_components,若PCA()不填,则默认返回min(X.shape) 

(2)画累计方差贡献率曲线,找最佳降维后维度的范围

pca_line = PCA().fit(X)  # 默认是min(X.shape)=784
plt.figure(figsize=[20,5])   # 图像的尺寸
plt.plot(np.cumsum(pca_line.explained_variance_ratio_))   # 返回784个特征的方差贡献率
plt.xlabel("number of components after dimension reduction")  # 降维后的特征数目
plt.ylabel("cumulative explained variance ratio")  # 累计可解释性方差比率和
plt.show()

【4 - 降维算法PCA和SVD - 案例部分】菜菜sklearn机器学习_第5张图片

选转折点作为n_components,由图可以看到,1-100中必有一个值是想要的 

(3)降维后维度的学习曲线,继续缩小最佳维度的范围

PCA的参数 n_components 取不同值时,随机森林在交叉验证下的效果(使用降维后的特征矩阵)

score = []
for i in range(1,101,10):
    X_dr = PCA(i).fit_transform(X)  # 降维后的结果X_dr
    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)  # x轴和y轴的取值
plt.show()

【4 - 降维算法PCA和SVD - 案例部分】菜菜sklearn机器学习_第6张图片

可以看出,大概降到20维左右模型的效果最好,后面曲线几乎平了 

(4)细化学习曲线,找出降维后的最佳维度

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 - 降维算法PCA和SVD - 案例部分】菜菜sklearn机器学习_第7张图片

差不多21左右是最大值 

(5)导入找出的最佳维度进行降维,查看模型效果

X_dr = PCA(21).fit_transform(X)
cross_val_score(RFC(n_estimators=10,random_state=0),X_dr,y,cv=5).mean()  #0.9174523809523809

# n_estimators越大,泛化误差越小,模型精度上升
cross_val_score(RFC(n_estimators=100,random_state=0),X_dr,y,cv=5).mean() #0.9443333333333334

模型效果还好(0.944),但还是没有使用嵌入法特征选择后的 0.964 高。如何再提高模型表现?

(6)现在特征数量已经不足原来的3%,换模型如何?

在之前的建模过程中,因为计算量太大,所以一直使用随机森林,但事实上KNN效果比随机森林更好。KNN在未调参的状况下已经达到96.6%的准确率,而随机森林在未调参前只能达到93.7%,这是模型本身的限制带来的

现在特征数量已经降到不足原来的3%,换KNN看看效果如何

from sklearn.neighbors import KNeighborsClassifier as KNN
cross_val_score(KNN(),X_dr,y,cv=5).mean()  #KNN()的值不填写默认=5   0.9679761904761905

(7)KNN的k值学习曲线

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()   # KNN()中的参数最小是1
    score.append(once)
plt.figure(figsize=[20,5])
plt.plot(range(10),score)
plt.show()

【4 - 降维算法PCA和SVD - 案例部分】菜菜sklearn机器学习_第8张图片

可以看到,横坐标取2时效果最好,此时KNN的参数是2+1=3 

(8)定下超参数后,模型效果和运行时间如何?

cross_val_score(KNN(3),X_dr,y,cv=5).mean()  #KNN()的值不填写默认=5

%%timeit
cross_val_score(KNN(3),X_dr,y,cv=5).mean()

原本784列的特征被缩减到21列之后,用KNN跑出了目前为止这个数据集上最好的结果0.968 

你可能感兴趣的:(机器学习,sklearn,python)