【机器学习】数据降维—主成分分析(PCA)

本文代码推荐使用Jupyter notebook跑,这样得到的结果更为直观。

主成分分析(PCA)

特征抽取通常用于提高计算效率,降低维度灾难。

主成分分析(Principe component analysis,PCA):

       是一种广泛应用于不同领域的无监督线性数据转换技术,作用是降维。

 

常用领域:

股票交易市场数据的探索性分析和信号去噪、生物信息学领域的基因组和基因表达水平数据分析

 

PCA可以基于特征之间的关系识别出数据内在模式

PCA的目标:高维数据中找到最大方差的方向,并将数据映射到一个维度不大于原始数据的新的子空间上。

 

PCA图:


新特征的坐标是相互正交为约束条件,子空间上的正交的坐标轴(PC)为方差最大方向

x1和x2为原始特征坐标轴,pc1和pc2为主成分



构建一个d x k维的转换矩阵W,将一个样本向量x映射到一个新的k维特征子空间上,此空间维度小于原始的d维特征空间。

完成从原始的d维数据到新的k维子空间转换后,第一主成分的方差应该最大,由于各主成分是正交的,后续主成分也可能具备更大方差。

 

主成分方向对数据值的范围高度敏感,如果特征值不同维度应该先对特征标准化处理,让各特征具有相同的重要性。



PCA算法流程:

 1、       对原始d维数据集做标准化

 2、       构造样本协方差矩阵

 3、       计算协方差矩阵特征值和相应的特征向量

 4、       选择与前k个最大特征值对应的特征向量,其中k为新特征空间维度(k<=d)

 5、       通过前k个特征向量构建映射矩阵W

 6、       通过映射矩阵W将d维的输入数据集X转换到新的k维特征子空间



第一步,加载数据集,标准化数据集。


# 加载葡萄酒数据集
import pandas as pd
df_wine = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.data', header=None)
# 将数据分成70%的培训和30%的测试子集。
from sklearn.cross_validation import train_test_split
X, y = df_wine.iloc[:, 1:].values, df_wine.iloc[:, 0].values
X_train, X_test, y_train, y_test = \
        train_test_split(X, y, test_size=0.3, random_state=0)
# 使用单位方差标准化
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train_std = sc.fit_transform(X_train)
X_test_std = sc.fit_transform(X_test)

第二步,构造协方差矩阵,dxd维协方差矩阵是沿对角线对称,d为数据集的维度,矩阵存储了不同特征之间的协方差。

协方差公式:


μj和μk分别为特征j和k的均值。

标准化后均值为0。

两个特征之间的协方差为正,则两个特征同时递减。

协方差为负,则两个特征反向移动


协方差矩阵的特征向量代表主成分,对应的特征值大小决定特征向量的重要性。



# 协方差矩阵的特征分解,计算数据集协方差矩阵的特征对。
import numpy as np
cov_mat = np.cov(X_train_std.T)
eigen_vals, eigen_vecs = np.linalg.eig(cov_mat)
print('\nEigenvalues \n%s' % eigen_vals)

cov函数得到标准化处理的训练集协方差矩阵

eig函数进行特征分解,得到特征向量及其对应的特征值。


只选择包含最多信息的特征向量组成子集

特征值决定了特征向量的重要性,需要将特征值按降序排列,取排序在前k的特征值对应的特征向量

 

绘制特征值的方差贡献率图像,某个特征值与所有特征值和的比较



# 使用NumPy的cumsum函数,计算累计方差。
tot = sum(eigen_vals)
var_exp = [(i / tot) for i in sorted(eigen_vals, reverse=True)]
cum_var_exp = np.cumsum(var_exp)
# 通过Plo的step绘制
import matplotlib.pyplot as plt
%matplotlib inline
plt.bar(range(1, 14), var_exp, alpha=0.5, align='center',
        label='individual explained variance')
plt.step(range(1, 14), cum_var_exp, where='mid',
         label='cumulative explained variance')
plt.ylabel('Explained variance ratio')
plt.xlabel('Principal components')
plt.legend(loc='best')
plt.tight_layout()
# plt.savefig('./figures/pca1.png', dpi=300)
plt.show()


第一主成分占方差总和40%,前两个主成分占比近60%

PCA是一种无监督方法,可以忽略类标信息

随机森林通过类标信息计算节点的不纯度,方差度量的是特征值在轴线是的分布。


# 按特征值的降序排列特征对
# 列出(特征值,特征向量)元组。
eigen_pairs = [(np.abs(eigen_vals[i]), eigen_vecs[:,i]) for i in range(len(eigen_vals))]

# 从高到低排序(特征值,特征向量)元组。
eigen_pairs.sort(reverse=True)
# 本案例只选择前60%的两个特征向量
w = np.hstack((eigen_pairs[0][1][:, np.newaxis],
               eigen_pairs[1][1][:, np.newaxis]))
print('Matrix W:\n', w)



# 通过计算矩阵点积,将整个训练集转换到包含两个主成分的子空间上。
X_train_pca = X_train_std.dot(w)

# 可视化
colors = ['r', 'b', 'g']
markers = ['s', 'x', 'o']

for l, c, m in zip(np.unique(y_train), colors, markers):
    plt.scatter(X_train_pca[y_train==l, 0], 
                X_train_pca[y_train==l, 1], 
                c=c, label=l, marker=m)

plt.xlabel('PC 1')
plt.ylabel('PC 2')
plt.legend(loc='lower left')
plt.tight_layout()
# plt.savefig('./figures/pca2.png', dpi=300)
plt.show()



# 使用Scikit-learn进行主成分分析
from sklearn.decomposition import PCA

pca = PCA()
X_train_pca = pca.fit_transform(X_train_std)
# pca.explained_variance_ratio_
plt.bar(range(1, 14), pca.explained_variance_ratio_, alpha=0.5, align='center')
plt.step(range(1, 14), np.cumsum(pca.explained_variance_ratio_), where='mid')
plt.ylabel('Explained variance ratio')
plt.xlabel('Principal components')
plt.show()



pca = PCA(n_components=2)
X_train_pca = pca.fit_transform(X_train_std)
X_test_pca = pca.transform(X_test_std)
plt.scatter(X_train_pca[:,0], X_train_pca[:,1])
plt.xlabel('PC 1')
plt.ylabel('PC 2')
plt.show()



# 使用plot_decision_regions函数进行可视化决策区域
from matplotlib.colors import ListedColormap

def plot_decision_regions(X, y, classifier, resolution=0.02):

    #设置标记生成器和颜色映射。
    markers = ('s', 'x', 'o', '^', 'v')
    colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan')
    cmap = ListedColormap(colors[:len(np.unique(y))])

    # plot 决定表面
    x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution),
                         np.arange(x2_min, x2_max, resolution))
    Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
    Z = Z.reshape(xx1.shape)
    plt.contourf(xx1, xx2, Z, alpha=0.4, cmap=cmap)
    plt.xlim(xx1.min(), xx1.max())
    plt.ylim(xx2.min(), xx2.max())

    # plot 类样本
    for idx, cl in enumerate(np.unique(y)):
        plt.scatter(x=X[y == cl, 0], y=X[y == cl, 1],
                    alpha=0.8, c=cmap(idx),
                    marker=markers[idx], label=cl)

# 使用前两个主要组件训练逻辑回归分类器
from sklearn.linear_model import LogisticRegression

lr = LogisticRegression()
lr = lr.fit(X_train_pca, y_train)
plot_decision_regions(X_train_pca, y_train, classifier=lr)
plt.xlabel('PC 1')
plt.ylabel('PC 2')
plt.legend(loc='lower left')
plt.tight_layout()
# plt.savefig('./figures/pca3.png', dpi=300)
plt.show()


SKlearn实现的PCA和之前实现的PCA是经过y轴旋转后的。

特征分析方法:特征向量可以为正或者为负

有时候需要乘上-1在实现图像的镜像。


# 绘制逻辑回归在转换后的测试数据上得到的决策区域
plot_decision_regions(X_test_pca, y_test, classifier=lr)
plt.xlabel('PC 1')
plt.ylabel('PC 2')
plt.legend(loc='lower left')
plt.tight_layout()
# plt.savefig('./figures/pca4.png', dpi=300)
plt.show()


# 获取相应的方差贡献率
pca = PCA(n_components=None)
X_train_pca = pca.fit_transform(X_train_std)
pca.explained_variance_ratio_






评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值