利用 wine.data葡萄酒数据集进行PCA分析
wine.data数据集共14列数据,第一列是类标签'class label',分别是1/2/3,代表葡萄酒的三个分类。剩余的13列分别是酒精、苹果酸、灰、灰分的碱度、镁、总酚、黄酮类化合物、非黄烷类酚类、原花色素、颜色强度、色调等。即'alcohol','malic acid','ash','alcalinity of ash','magnesium','totalphenols','flavanoids','nonflavanoid','proanthocynins', 'color intensity','wue','diluted','proline'
有两种方法:1.根据PCA算法写步骤
2.调用sklearn 里的API
初学者建议先按第一种实现,走一遍算法流程,加深PCA算法理解。
第一种实现:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
#自己实现PCA
df_wine = pd.read_csv('wine.data',header=None)
df_wine.columns = ['class label', 'alcohol', 'malic acid', 'ash', 'alcalinity of ash',
'magnesium', 'total phenols', 'flavanoids', 'nonflavanoid', 'proanthocynins',
'color intensity', 'wue', 'diluted', 'proline']
# print(df_wine.shape)
# print(df_wine['class label'].value_counts())
# print(df_wine.head())
#数据集设置:x为样本特征数据,y为目标数据,即标注结果
x, y = df_wine.iloc[:, 1:].values, df_wine.iloc[:, 0].values#iloc index location 对数据进行位置索引
#数据集划分:将数据划分为训练集和测试集(70%,30%)
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) #训练数据用了fit_transform,测试数据就得用transform,否则就不是在一个标准下
#计算协方差矩阵 shape得到了数组的形状,size统计了数组总共的大小
cov_mat = np.cov(X_train_std.T)
#对协方差矩阵进行特征值分解
eigen_vals, eigen_vecs = np.linalg.eig(cov_mat)#linalg包含线性代数常用方法 Linear Algebra线性代数
#numpy.linalg模块包含线性代数的函数。使用这个模块,可以计算逆矩阵、求特征值、解线性方程组以及求解行列式等。
#特征值之和
tot = sum(eigen_vals)
#对特征值进行排序,并计算所占的比例
var_exp = [(i/tot) for i in sorted(eigen_vals,reverse=True)]
#累计求和
cum_var_exp = np.cumsum(var_exp)#cumcum累加; 累加和;
#绘制图像 注释的代码选中然后利用“Ctrl+/”进行注释
plt.figure()
plt.bar(range(1, 14), var_exp, alpha=0.5, align='center', label='特征值分布') #bar绘制柱状图
plt.step(range(1, 14), cum_var_exp, where='mid', label="累计特征值")
plt.ylabel('特征值比例')
plt.xlabel('特征index')
plt.legend(loc='best') #创建图例
#特征降维
#创建列表,由(eigenvalue,elgenvector)元组组成
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(w)
# #原始特征,以第一个为例
# print(X_train_std[0])
# #特征压缩后结果
# print(X_train_std[0].dot(w))
#全部特征压缩
X_train_pca = X_train_std.dot(w)
#特征压缩后结果展示
colors = ('r', 'g', 'b')
markers = ('s', 'x', 'o')
plt.figure()
# l=np.unique(y_train)=1/2/3
for l, c, m in zip(np.unique(y_train), colors, markers):
#按照样本真实值进行展示 scatter散点图
#X_train_pca[y_train == l, 0]是一个推导式,返回 X_train 中第0列满足 y_train ==l 条件的记录
print('--------------------')
print(X_train_pca[y_train == l, 0])
plt.scatter(X_train_pca[y_train == l, 0], #X_train_pca 里只剩两列特征,下标为0和1
X_train_pca[y_train == l, 1],
c=c, label=l, marker=m)
plt.xlabel('pc1')
plt.ylabel('pc2')
plt.legend(loc='lower left')
plt.tight_layout()
plt.show()
第二种算法
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
df_wine = pd.read_csv('wine.data',header=None)
df_wine.columns = ['class label', 'alcohol', 'malic acid', 'ash', 'alcalinity of ash',
'magnesium', 'total phenols', 'flavanoids', 'nonflavanoid', 'proanthocynins',
'color intensity', 'wue', 'diluted', 'proline']
x, y = df_wine.iloc[:, 1:].values, df_wine.iloc[:, 0].values #iloc index location 对数据进行位置索引
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) #训练数据用了fit_transform,测试数据就得用transform,否则就不是在一个标准下
pca = PCA()
X_train_pca = pca.fit_transform(X_train_std)
X_test_pca = pca.transform(X_test_std)
#explained_variance_ratio_计算了每个特征方差贡献率,所有总和为1,
# explained_variance_为方差值,通过合理使用这两个参数可以画出方差贡献率图或者方差值图,便于观察PCA降维最佳值。
print(pca.explained_variance_ratio_)
plt.figure()
plt.bar(range(1, 14), pca.explained_variance_ratio_, alpha=0.5, align='center',
label='特征值分布')
plt.step(range(1, 14), np.cumsum(pca.explained_variance_ratio_), where='mid',
label='累计特征值')
plt.ylabel('特征值比例')
plt.xlabel('特征index')
plt.legend(loc='best')
pca = PCA(n_components=2) #压缩到二维特征
colors = ['r', 'g', 'b']
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()
wine.data数据集 官网下载UCI Machine Learning Repository: Wine Quality Data Set
我在百度网盘也放了一份 ,有需要自取
链接:https://pan.baidu.com/s/1bBlesqk9fxpSKVKfy7bNiw
提取码:89ts