主成分分析(PCA)简介

image

主成分分析实例:一个平均值为(1, 3)、标准差在(0.878, 0.478)方向上为3、在其正交方向为1的高斯分布。这里以黑色显示的两个向量是这个分布的协方差矩阵特征向量,其长度按对应的特征值之平方根为比例,并且移动到以原分布的平均值为原点。

在多元统计分析中,主成分分析(英语:Principal components analysisPCA)是一种分析、简化数据集的技术。主成分分析经常用于减少数据集的维数,同时保持数据集中的对方差贡献最大的特征。这是通过保留低阶主成分,忽略高阶主成分做到的。这样低阶成分往往能够保留住数据的最重要方面。但是,这也不是一定的,要视具体应用而定。由于主成分分析依赖所给数据,所以数据的准确性对分析结果影响很大。

主成分分析由卡尔·皮尔逊于1901年发明,用于分析数据及建立数理模型。其方法主要是通过对协方差矩阵进行特征分解,以得出数据的主成分(即特征向量)与它们的权值(即特征值[3])。PCA是最简单的以特征量分析多元统计分布的方法。其结果可以理解为对原数据中的方差做出解释:哪一个方向上的数据值对方差的影响最大?换而言之,PCA提供了一种降低数据维度的有效办法;如果分析者在原数据中除掉最小的特征值所对应的成分,那么所得的低维度数据必定是最优化的(也即,这样降低维度必定是失去讯息最少的方法)。主成分分析在分析复杂数据时尤为有用,比如人脸识别

PCA是最简单的以特征量分析多元统计分布的方法。通常情况下,这种运算可以被看作是揭露数据的内部结构,从而更好的解释数据的变量的方法。如果一个多元数据集能够在一个高维数据空间坐标系中被显现出来,那么PCA就能够提供一幅比较低维度的图像,这幅图像即为在讯息最多的点上原对象的一个‘投影’。这样就可以利用少量的主成分使得数据的维度降低了。

PCA跟因子分析密切相关,并且已经有很多混合这两种分析的统计包。而真实要素分析则是假定底层结构,求得微小差异矩阵的特征向量。

PCA,Principle Component Analysis,即主成分分析法,是特征降维的最常用手段。顾名思义,PCA 能从冗余特征中提取主要成分,在不太损失模型质量的情况下,提升了模型训练速度。

image

如上图所示,我们将样本到红色向量的距离称作是投影误差(Projection Error)。以二维投影到一维为例,PCA 就是要找寻一条直线,使得各个特征的投影误差足够小,这样才能尽可能的保留原特征具有的信息。

image

因为PCA仅保留了特征的主成分,所以PCA是一种有损的压缩方式.

image

降到多少维才合适?

从 PCA 的执行流程中,我们知道,需要为 PCA 指定目的维度 k 。如果降维不多,则性能提升不大;如果目标维度太小,则又丢失了许多信息。

不要提前优化

由于 PCA 减小了特征维度,因而也有可能带来过拟合的问题。PCA 不是必须的,在机器学习中,一定谨记不要提前优化,只有当算法运行效率不尽如如人意时,再考虑使用 PCA 或者其他特征降维手段来提升训练速度。

不只是加速学习

降低特征维度不只能加速模型的训练速度,还能帮我们在低维空间分析数据,例如,一个在三维空间完成的聚类问题,我们可以通过 PCA 将特征降低到二维平面进行可视化分析。

项目实战:利用 PCA 对葡萄酒分类

根据 13 个特征对葡萄酒分类(推销给不同品味的人),利用 PCA ,可以将数据从 13 维降到 2 维进行可视化。

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
# 导入数据
dataset = pd.read_csv('Wine.csv')
X = dataset.iloc[:, :-1].values
y = dataset.iloc[:, 13].values

dataset.head(10)
# 分成训练集与测试集
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 0)
X_train[:3]

array([[1.369e+01, 3.260e+00, 2.540e+00, 2.000e+01, 1.070e+02, 1.830e+00, 5.600e-01, 5.000e-01, 8.000e-01, 5.880e+00, 9.600e-01, 1.820e+00, 6.800e+02], [1.269e+01, 1.530e+00, 2.260e+00, 2.070e+01, 8.000e+01, 1.380e+00, 1.460e+00, 5.800e-01, 1.620e+00, 3.050e+00, 9.600e-01, 2.060e+00, 4.950e+02], [1.162e+01, 1.990e+00, 2.280e+00, 1.800e+01, 9.800e+01, 3.020e+00, 2.260e+00, 1.700e-01, 1.350e+00, 3.250e+00, 1.160e+00, 2.960e+00, 3.450e+02]])

# 特征缩放
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)
X_train[:3]

array([[ 0.87668336, 0.79842885, 0.64412971, 0.12974277, 0.48853231, -0.70326216, -1.42846826, 1.0724566 , -1.36820277, 0.35193216, 0.0290166 , -1.06412236, -0.2059076 ], [-0.36659076, -0.7581304 , -0.39779858, 0.33380024, -1.41302392, -1.44153145, -0.5029981 , 1.70109989, 0.02366802, -0.84114577, 0.0290166 , -0.73083231, -0.81704676], [-1.69689407, -0.34424759, -0.32337513, -0.45327855, -0.14531976, 1.24904997, 0.31964204, -1.52069698, -0.4346309 , -0.75682931, 0.90197362, 0.51900537, -1.31256499]])

# 测试 PCA
from sklearn.decomposition import PCA
pca = PCA(n_components = None)
X_train = pca.fit_transform(X_train)
X_test = pca.transform(X_test)
# explained_variance_ratio_,它代表降维后的各主成分的方差值占总方差值的比例,这个比例越大,则越是重要的主成分。
explained_variance = pca.explained_variance_ratio_
explained_variance 

array([0.36884109, 0.19318394, 0.10752862, 0.07421996, 0.06245904, 0.04909 , 0.04117287, 0.02495984, 0.02308855, 0.01864124, 0.01731766, 0.01252785, 0.00696933])

# 这里取前 2 个主成分,它可以解释  (0.3688+0.1931)  的方差
from sklearn.decomposition import PCA
pca = PCA(n_components = 2)
X_train = pca.fit_transform(X_train)
X_test = pca.transform(X_test)
explained_variance = pca.explained_variance_ratio_

print(explained_variance)
X_train[:3]
[0.36884109 0.19318394]

array([[-2.17884511, -1.07218467], [-1.80819239, 1.57822344], [ 1.09829474, 2.22124345]])

# 逻辑回归拟合训练集
from sklearn.linear_model import LogisticRegression
classifier = LogisticRegression(random_state = 0)
classifier.fit(X_train, y_train)

LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True, intercept_scaling=1, max_iter=100, multi_class='ovr', n_jobs=1, penalty='l2', random_state=0, solver='liblinear', tol=0.0001, verbose=0, warm_start=False)

# 预测测试集
y_pred = classifier.predict(X_test)
y_pred[:5]

array([1, 3, 2, 1, 2])

# 混淆矩阵
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, y_pred)
cm 

array([[14, 0, 0], [ 1, 15, 0], [ 0, 0, 6]])

# 预测正确的为正对角线的值,准确率为 (14+15+6) / (14+15+6+1)
print("准确率(精度)为 :", (14+15+6)/(14+15+6+1))

准确率(精度)为 : 0.9722222222222222

# 可视化训练集 
from matplotlib.colors import ListedColormap
X_set, y_set = X_train, y_train
X1, X2 = np.meshgrid(np.arange(start = X_set[:, 0].min() - 1, stop = X_set[:, 0].max() + 1, step = 0.01),
                     np.arange(start = X_set[:, 1].min() - 1, stop = X_set[:, 1].max() + 1, step = 0.01))
plt.contourf(X1, X2, classifier.predict(np.array([X1.ravel(), X2.ravel()]).T).reshape(X1.shape),
             alpha = 0.75, cmap = ListedColormap(('red', 'green', 'blue')))
plt.xlim(X1.min(), X1.max())
plt.ylim(X2.min(), X2.max())
for i, j in enumerate(np.unique(y_set)):
    plt.scatter(X_set[y_set == j, 0], X_set[y_set == j, 1],
                c = ListedColormap(('red', 'green', 'blue'))(i), label = j)
plt.title('逻辑回归 (训练集)')
plt.xlabel('PC1')
plt.ylabel('PC2')
plt.legend()
plt.show()

output_11_0.png

# 可视化测试集 
from matplotlib.colors import ListedColormap
X_set, y_set = X_test, y_test
X1, X2 = np.meshgrid(np.arange(start = X_set[:, 0].min() - 1, stop = X_set[:, 0].max() + 1, step = 0.01),
                     np.arange(start = X_set[:, 1].min() - 1, stop = X_set[:, 1].max() + 1, step = 0.01))
plt.contourf(X1, X2, classifier.predict(np.array([X1.ravel(), X2.ravel()]).T).reshape(X1.shape),
             alpha = 0.75, cmap = ListedColormap(('red', 'green', 'blue')))
plt.xlim(X1.min(), X1.max())
plt.ylim(X2.min(), X2.max())
for i, j in enumerate(np.unique(y_set)):
    plt.scatter(X_set[y_set == j, 0], X_set[y_set == j, 1],
                c = ListedColormap(('red', 'green', 'blue'))(i), label = j)
plt.title('逻辑回归 (测试集)')
plt.xlabel('PC1')
plt.ylabel('PC2')
plt.legend()
plt.show()

output_12_0.png

参考:https://zh.wikipedia.org/wiki/主成分分析 《 斯坦福机器学习》 《机器学习 A-Z》

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏SpringCloud专栏

1 Spark机器学习 spark MLlib 入门

开始学习spark ml了,都知道spark是继hadoop后的大数据利器,很多人都在使用spark的分布式并行来处理大数据。spark中也提供了机器学习的包,...

16420
来自专栏SpringCloud专栏

2 机器学习入门——逻辑回归第一课

前几篇都是讲线性回归的,特点就是最终的结果是一系列的值。我们通过找到合适的方程去匹配空间中的点的分布,得到合适的模型,然后用模型对未知的数据结果进行预测。二维线...

9130
来自专栏SpringCloud专栏

2 机器学习入门——逻辑回归第二课

所有的数据下载地址:https://gitee.com/tianyalei/machine_learning,按对应章节查找。

11030
来自专栏SpringCloud专栏

1 机器学习入门——线性回归第二课

线性回归可以说是最简单的机器学习入门了,上一篇我们使用了一个最简单的模型,只有一个变量,只有一次方。机器很完美的给出了模型和正确的结论。

12340
来自专栏SpringCloud专栏

4 机器学习入门——分类和最近邻

前面学过了简单的回归和决策树,当然仅仅是使用起来简单。实际上,线性回归和决策树是很多其他算法的基础,很多高级的算法都是基于它们的组合或者变种。下面我们来看一个另...

20040
来自专栏SpringCloud专栏

1 机器学习入门——线性回归第一课

此时,我们希望你能预测一下,当x是1万时,y的值。如果你具备初中以上的数学知识,聪明的你可能已经能给出答案了。是的,结果是2万。

17670
来自专栏SpringCloud专栏

机器学习特征工程——给任意属性增加任意次方的全组合

在机器学习中,我们时常会碰到需要给属性增加字段的情况。譬如有x、y两个属性,当结果倾向于线性时,我们可以很简单的通过线性回归得到模型。但很多时候,线性(在数学上...

9330
来自专栏SpringCloud专栏

2 机器学习入门——逻辑回归之kaggle泰坦尼克号竞赛

前面几篇逻辑回归的例子有些是人造出来的,有些是比较正规的,但数据都比较完整,没有缺失的属性。虽然我们在很多数据上取到的非常好的效果,但总感觉好像不够味,不像实战...

15320
来自专栏SpringCloud专栏

1 机器学习入门——线性回归第三课

上一篇我们看到了线性回归在对多个属性建模时,能迅速给出模型预测,但很多时候效果并不太美好。毕竟方法太简单了,而且很多时候已有的属性很难拟合到一起形成比较靠谱的结...

11920
来自专栏SpringCloud专栏

3 机器学习入门——决策树之天气预报、鸢尾花

前面我们简单学习了线性回归、逻辑回归,不知道有没有做一个总结,那就是什么时候该用逻辑回归?

44820

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励