赞
踩
在实际操作数据集的过程中,难免会遇到很多高维特征的数据,计算量也会暴增。为了在减少计算量的同时提高算法准确率,可尝试降维。
PCA(Principal Component Analysis),即主成分分析方法,是一种使用最广泛的数据降维算法。
下文将列出三个案例,分别是人脸识别、降噪和处理手写数据集。
案例一:人脸识别
- import matplotlib.pyplot as plt
- import pandas as pd
- from sklearn.datasets import load_iris
- from sklearn.ensemble import RandomForestClassifier
- from sklearn.model_selection import cross_val_score
- from sklearn.model_selection import train_test_split
- from sklearn.decomposition import PCA
- ##########人脸识别########
- from sklearn.datasets import fetch_lfw_people
- from sklearn.decomposition import PCA
- faces = fetch_lfw_people(min_faces_per_person=60) #每个人60张照片
- print(faces.data.shape) #二维 1277*2914 2914=62*47
- print(faces.images.shape) #三维:1277矩阵中图像个数,62每个图像的特征矩阵的行,47每个图像的特征矩阵的列
- x1 = faces.data
- #创建画布 subplots子图画布(4行5列)
- fig, axes = plt.subplots(4,5
- ,figsize=(8,4) #画布大小
- ,subplot_kw= {'xticks':[],'yticks':[]}) #不要显示坐标轴
- axes[0][0].imshow(faces.images[0,:,:]) #填图
- #循环填补 由于4行5列 比较复杂,所以直接1-20,方法就是将axes降维至1维
- [* axes.flat] #惰性对象
- print(len([* axes.flat])) #列表没有shape
- [*enumerate(axes.flat)] #索引加内容的元组
- for i,ax in [*enumerate(axes.flat)]:
- ax.imshow(faces.images[i, :, :],cmap='gray') #选择色彩模式,灰色
-
- print(fig)
- print(axes) #axes和fig相互对应,一个框fig对应一个axes
-
- axes[0][0].imshow(faces.images[0,:,:])
-
- ####开始降维
- pca_face = PCA(150).fit(x1)
- v = pca_face.components_
- print(v.shape)
- #可视化v
- fig,axes = plt.subplots(3,6
- ,figsize=(8,4)
- ,subplot_kw={'xticks':[],'yticks':[]})
- for i,ax in enumerate(axes.flat):
- ax.imshow(v[i,:].reshape(62,47),cmap='gray')
案例二:降噪
- from sklearn.datasets import load_digits
- from sklearn.decomposition import PCA
- import matplotlib.pyplot as plt
- import numpy as np
-
- digits = load_digits()
- def plot(data):
- fig,axes = plt.subplots(
- 4,10
- ,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.data)
-
- ##为图像数据添加噪音
- rng = np.random.RandomState(42) #规定numpy 中的随机模式
- #在指定的数据集中,随机抽取服从正态分布的数据。两个参数分别是指定的数据集,和抽取的正态分布的方差
- noisy = rng.normal(digits.data,2)#从原有的数据集中随机地抽取一个满足正态分布的数据集,第一个参数是数据集,第二个参数是方差,如果方差越大那么随机抽取的数据越凌乱,与原数据的结构一致
- plot(noisy)
- #降维50%
- pca = PCA(0.5,svd_solver='full').fit(noisy)
- x_dd = pca.transform(noisy)
- x_dd.shape
- #转回原来的维度,可视化
- without_noise = pca.inverse_transform(x_dd) ##必须转回去,因为plot函数的(m,n),n必须是64
- plot(without_noise)
案例三:手写数据集
- from sklearn.decomposition import PCA
- from sklearn.model_selection import cross_val_score
- from sklearn.ensemble import RandomForestClassifier as RFC
- import numpy as np
- import pandas as pd
- import matplotlib.pyplot as plt
- ####导入数据
- data = pd.read_csv('digit.csv')
- x = data.iloc[:,1:]
- y = data.iloc[:,0]
- print(x.shape)#(42000, 784)
- ####画累计方差贡献率曲线,找最佳降维后维度的范围u
- pca = PCA().fit(x) #默认参数,什么都不填数据最小维度(行42000、列784)————》784
- plt.figure(figsize=(20,5))
- plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
- plt.plot(np.cumsum(pca.explained_variance_ratio_))
- plt.xlabel('降维后的特征数目')
- plt.ylabel('累计可解释性方差比例之和')
- plt.show()
- #####由上图可知数据集大概在特征数量为1-100之间特征比较有用,拉出来专门绘制
- #####降维后的学习曲线,继续缩小最佳维度的范围
- # score = []
- # for i in range(1,101,10):
- # x_dr = PCA(i).fit_transform(x)
- # once = cross_val_score(RFC(n_estimators=10,random_state=42),x_dr,y,cv=5).mean()
- # score.append(once)
- # plt.figure(figsize=[20,5])
- # plt.plot(range(1,101,10),score)
- # plt.xlabel('特征数')
- # plt.ylabel('随机森林交叉验证分数')
- # plt.show()
- #####在20左右达到最高,之后平稳,所以取10-25
- # score = []
- # for i in range(10,25):
- # x_dr = PCA(i).fit_transform(x)
- # once = cross_val_score(RFC(n_estimators=10,random_state=42),x_dr,y,cv=5).mean()
- # score.append(once)
- # plt.figure(figsize=[20,5])
- # plt.plot(range(10,25),score)
- # plt.xlabel('特征数')
- # plt.ylabel('随机森林交叉验证分数')
- # plt.show()
-
- ###降到21维
- x_dr = PCA(22).fit_transform(x)
- # once = cross_val_score(RFC(n_estimators=10,random_state=42),x_dr,y,cv=5).mean()
- # print(once) #0.9161428571428571
- # once1 = cross_val_score(RFC(n_estimators=100,random_state=42),x_dr,y,cv=5).mean()
- # print(once1) #0.9444761904761905
-
- #####此时分数已经很高了,但是相距原来的96点多,还差一些
- #由于已经降维到22维,所以考虑一下换模型KNN
- from sklearn.neighbors import KNeighborsClassifier as KNN
- # score_knn = cross_val_score(KNN(),x_dr,y,cv=5).mean
- # print(score_knn) #0.9676 这里打印出来<built-in method mean of numpy.ndarray object at 0x000001FB15A201B0>
- # score = []
- # for i in range(10):
- # 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.xlabel('特征数')
- # plt.ylabel('KNN交叉验证分数')
- # plt.show() #取3的时候最大
-
- # %%timeit #jupyter里计算时间
- import time
- start = time.time()
- sc = cross_val_score(KNN(3),x_dr,y,cv=5).mean()
- end = time.time()
- print(sc) #0.9686666666666668
- print(end-start)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。