PCA: 主成分分析,principal components analysis
LDA: 线性判别分析,linear discriminant analysis
两种降维的不同:
PCA: 非监督降维,降维后数据方差尽可能大
LDA:有监督降维,组内方差小,组间方差大
一、PCA详解
1.1 PCA简介与直观理解
PCA的作用:
- 聚类: 把复杂的多维数据点简化为少量数据点,易于分簇
- 降维:降低高维数据,简化计算,达到数据降维,压缩,降噪的目的
PCA的目的:
- d维数据转成k维数据,k<d
- 新生成的k维数据尽可能多地包含原来d维数据的信息
(投影之后数据更加分散)
直观看:投影后的投影值尽可能分散。这种分散程度,用数学上的方差来表述。
1.2 PCA的数学推导
1.2 PCA的目标函数(1)
首先按对数据进行去中心化(减去均值),即均值为0。
然后计算数据集的协方差矩阵。
PCA要找到一个线性变换,让数据投影的方差最大化
PCA的流程:
1.3 带核函数的PCA
带核函数的PCA(1)
带核函数的PCA的步骤总结
二、LDA详解
2.1 LDA简介和直观理解
2.1.1 LDA简介
LDA是有监督的,适合有标签的数据
2.1.2 LDA的直观理解
最大化类间距离
最小化类内距离
2.2 LDA的数学推导
定义类内散度矩阵和类间散度矩阵
LDA的流程
三、PCA和LDA的实践
3.1 PCA的实践
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 读取数据
from sklearn.decomposition import PCA
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
df_wine = pd.read_csv('wine.data')
# 设置列索引
df_wine.columns = [
'Class label',
'Alcohol',
'Malic acid',
'Ash',
'Alcalinity of ash',
'Magnesium',
'Total phenols',
'Flavanoids',
'Nonflavanoid phenols',
'Proanthocyanins',
'Color intensity',
'Hue',
'OD280/OD315 of diluted wines',
'Proline'
]
# 数据维度
print(df_wine.shape)
# 每一类包含的样本个数
print(df_wine['Class label'].value_counts())
print(df_wine.head())
## 数据集设置
X, y = df_wine.iloc[:, 1:].values, df_wine.iloc[:, 0].values
## 数据集划分 3-7开
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, stratify=y, random_state=0)
## 数据集标准化
sc = StandardScaler()
X_train_std = sc.fit_transform(X_train)
X_test_std = sc.transform(X_test)
print(X_train_std[0])
## PCA实现
# 求协方差特征值和特征向量
# 计算协方差矩阵
cov_mat = np.cov(X_test_std.T)
# 对协方差矩阵进行特征值分解
eigen_vals, eigen_vecs = np.linalg.eig(cov_mat)
print(eigen_vals)
### 特征值分布
tot = sum(eigen_vals)
### 对特征值进行排序,并计算所占的比例
var_exp = [(i / tot) for i in sorted(eigen_vals, reverse=True)]
### 累计求和
cum_var_exp = np.cumsum(var_exp)
## 绘制图像
plt.figure()
# 解决中文显示问题
plt.rcParams['font.sans-serif'] = ['KaiTi'] # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
plt.bar(range(1, 14), var_exp, alpha=0.5, align='center', label='特征值分布')
plt.step(range(1, 14), cum_var_exp, where='mid', label='累计特征值')
plt.ylabel('特征值比例')
plt.xlabel('特征index')
plt.legend(loc='best')
plt.show()
## 特征降维
eigen_pairs = [(np.abs(eigen_vals[i]), eigen_vecs[:, i]) for i in range(len(eigen_vals))]
# 按特征值从大到小对列表(eigenvalue, eigenvector)排序
eigen_pairs.sort(key=lambda k: k[0], reverse=True)
print(eigen_pairs)
# 取前两个特征值对应的特征向量作为主要成分
w = np.hstack((eigen_pairs[0][1][:, np.newaxis],
eigen_pairs[1][1][:, np.newaxis]))
# 原始特征(以第一个样本为例)
print(X_train_std[0])
# 特征压缩后结果
print(X_train_std[0].dot(w))
# 全部特征压缩
X_train_pca = X_train_std.dot(w)
print('压缩后:' + str(X_train_pca))
print('y_train:' + str(y_train))
print('y_unique:' + str(np.unique(y_train)))
# 特征压缩后结果展示
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.show()
## 使用sklearn实现PCA
# 保留到两维
pca = PCA(n_components=2)
# 对训练数据进行处理
X_train_pca = pca.fit_transform(X_train_std)
# 特征值结果(只保留两个特征)
print(pca.explained_variance_ratio_)
# 对测试集数据进行处理
X_test_pca = pca.transform(X_test_std)
# 特征降维后结果展示
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.show()
if __name__=='__main__':
pass