PCA使用的信息量衡量指标,就是样本方差,又称可解释性方 差,方差越大,特征所带的信息量越多


案例:高维数据的可视化- #调用库和模块
- import matplotlib.pyplot as plt
- from sklearn.datasets import load_iris
- from sklearn.decomposition import PCA
-
- #提取数据集
- iris = load_iris()
- y = iris.target
- X = iris.data
- #作为数组,X是几维?
- X.shape
- #作为数据表或特征矩阵,X是几维?
- import pandas as pd
- pd.DataFrame(X)
-
- # 建模
- #调用PCA
- pca = PCA(n_components=2) #实例化
- pca = pca.fit(X) #拟合模型
- X_dr = pca.transform(X) #获取新矩阵
- X_dr
- #也可以fit_transform一步到位
- #X_dr = PCA(2).fit_transform(X)
-
- #可视化
- #要将三种鸢尾花的数据分布显示在二维平面坐标系中,对应的两个坐标(两个特征向量)应该是三种鸢尾花降维后的
- x1和x2,怎样才能取出三种鸢尾花下不同的x1和x2呢?
- X_dr[y == 0, 0] #这里是布尔索引,看出来了么?
- #要展示三中分类的分布,需要对三种鸢尾花分别绘图
- #可以写成三行代码,也可以写成for循环
- """
- plt.figure()
- plt.scatter(X_dr[y==0, 0], X_dr[y==0, 1], c="red", label=iris.target_names[0])
- plt.scatter(X_dr[y==1, 0], X_dr[y==1, 1], c="black", label=iris.target_names[1])
- plt.scatter(X_dr[y==2, 0], X_dr[y==2, 1], c="orange", label=iris.target_names[2])
- plt.legend()
- plt.title('PCA of IRIS dataset')
- plt.show()
- """
- colors = ['red', 'black', 'orange']
- iris.target_names
- plt.figure()
- for i in [0, 1, 2]:
- plt.scatter(X_dr[y == i, 0]
- ,X_dr[y == i, 1]
- ,alpha=.7
- ,c=colors[i]
- ,label=iris.target_names[i]
- )
- plt.legend()
- plt.title('PCA of IRIS dataset')
- plt.show()
累积可解释方差贡献率曲线,以此选择最好的n_components的整数取值
- import numpy as np
- pca_line = PCA().fit(X)
- plt.plot([1,2,3,4],np.cumsum(pca_line.explained_variance_ratio_))
- plt.xticks([1,2,3,4]) #这是为了限制坐标轴显示为整数
- plt.xlabel("number of components after dimension reduction")
- plt.ylabel("cumulative explained variance ratio")
- plt.show()
除了输入整数,n_components还有哪些选择呢?
最大似然估计自选超参数,找出了让PCA用最大似然估计(maximum likelihood estimation)自选超参数的方法,输入“mle”作为n_components的参数输入,就可以调用这种方法
- pca_mle = PCA(n_components="mle")
- pca_mle = pca_mle.fit(X)
- X_mle = pca_mle.transform(X)
- X_mle
- #可以发现,mle为我们自动选择了3个特征
- pca_mle.explained_variance_ratio_.sum()
- #得到了比设定2个特征时更高的信息含量,对于鸢尾花这个很小的数据集来说,3个特征对应这么高的信息含量,并不
- 需要去纠结于只保留2个特征,毕竟三个特征也可以可视化
- from sklearn.datasets import fetch_lfw_people
- from sklearn.decomposition import PCA
- import matplotlib.pyplot as plt
- import numpy as np
-
- faces = fetch_lfw_people(min_faces_per_person=60)
- faces.images.shape
- #怎样理解这个数据的维度?
- faces.data.shape
- #换成特征矩阵之后,这个矩阵是什么样?
- X = faces.data
-
- #数据本身是图像,和数据本身只是数字,使用的可视化方法不同
- #创建画布和子图对象
- fig, axes = plt.subplots(4,5
- ,figsize=(8,4)
- ,subplot_kw = {"xticks":[],"yticks":[]} #不要显示坐标轴
- )
- fig
- axes
- #不难发现,axes中的一个对象对应fig中的一个空格
- #我们希望,在每一个子图对象中填充图像(共24张图),因此我们需要写一个在子图对象中遍历的循环
- axes.shape
- #二维结构,可以有两种循环方式,一种是使用索引,循环一次同时生成一列上的三个图
- #另一种是把数据拉成一维,循环一次只生成一个图
- #在这里,究竟使用哪一种循环方式,是要看我们要画的图的信息,储存在一个怎样的结构里
- #我们使用 子图对象.imshow 来将图像填充到空白画布上
- #而imshow要求的数据格式必须是一个(m,n)格式的矩阵,即每个数据都是一张单独的图
- #因此我们需要遍历的是faces.images,其结构是(1277, 62, 47)
- #要从一个数据集中取出24个图,明显是一次性的循环切片[i,:,:]来得便利
- #因此我们要把axes的结构拉成一维来循环
-
- axes.flat
- enumerate(axes.flat)
- #填充图像
- for i, ax in enumerate(axes.flat):
- ax.imshow(faces.images[i,:,:]
- ,cmap="gray" #选择色彩的模式
- )
- #https://matplotlib.org/tutorials/colors/colormaps.html
-
- #原本有2900维,我们现在来降到150维
- pca = PCA(150).fit(X)
- V = pca.components_
- V.shape
-
- fig, axes = plt.subplots(3,8,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 fetch_lfw_people
- from sklearn.decomposition import PCA
- import matplotlib.pyplot as plt
- import numpy as np
-
- faces = fetch_lfw_people(min_faces_per_person=60)
- faces.images.shape
- #怎样理解这个数据的维度?
- faces.data.shape
- #换成特征矩阵之后,这个矩阵是什么样?
- X = faces.data
-
- pca = PCA(150)
- X_dr = pca.fit_transform(X)
- X_dr.shape
-
- X_inverse = pca.inverse_transform(X_dr)
- X_inverse.shape
-
- fig, ax = plt.subplots(2,10,figsize=(10,2.5)
- ,subplot_kw={"xticks":[],"yticks":[]}
- )
- #和2.3.3节中的案例一样,我们需要对子图对象进行遍历的循环,来将图像填入子图中
- #那在这里,我们使用怎样的循环?
- #现在我们的ax中是2行10列,第一行是原数据,第二行是inverse_transform后返回的数据
- #所以我们需要同时循环两份数据,即一次循环画一列上的两张图,而不是把ax拉平
- for i in range(10):
- ax[0,i].imshow(face.image[i,:,:],cmap="binary_r")
- ax[1,i].imshow(X_inverse[i].reshape(62,47),cmap="binary_r")
- 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
-
- def plot_digits(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(digits.data)
-
- np.random.RandomState(42)
- #在指定的数据集中,随机抽取服从正态分布的数据
- #两个参数,分别是指定的数据集,和抽取出来的正太分布的方差
- noisy = np.random.normal(digits.data,2)
- plot_digits(noisy)
-
- pca = PCA(0.5).fit(noisy)
- X_dr = pca.transform(noisy)
- X_dr.shape
-
- without_noise = pca.inverse_transform(X_dr)
- plot_digits(without_noise)
- 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"C:\work\learnbetter\micro-class\week 3 Preprocessing\digit
- recognizor.csv")
- X = data.iloc[:,1:]
- y = data.iloc[:,0]
- X.shape
-
- pca_line = PCA().fit(X)
- plt.figure(figsize=[20,5])
- plt.plot(np.cumsum(pca_line.explained_variance_ratio_))
- plt.xlabel("number of components after dimension reduction")
- plt.ylabel("cumulative explained variance ratio")
- plt.show()
-
- #======【TIME WARNING:2mins 30s】======#
- 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=0)
- ,X_dr,y,cv=5).mean()
- score.append(once)
- plt.figure(figsize=[20,5])
- plt.plot(range(1,101,10),score)
- plt.show()
-
- #======【TIME WARNING:2mins 30s】======#
- 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()
-
- X_dr = PCA(23).fit_transform(X)
- #======【TIME WARNING:1mins 30s】======#
- cross_val_score(RFC(n_estimators=100,random_state=0),X_dr,y,cv=5).mean()