算法专题01 - 主成分分析及Python实现

笔者是一个痴迷于挖掘数据中的价值的学习人,希望在平日的工作学习中,挖掘数据的价值,找寻数据的秘密,笔者认为,数据的价值不仅仅只体现在企业中,个人也可以体会到数据的魅力,用技术力量探索行为密码,让大数据助跑每一个人,欢迎直筒们关注我的公众号,大家一起讨论数据中的那些有趣的事情。

我的公众号为:livandata

主成分分析的原理是尽可能保留数据信息的情况下,减少数据的维度,防止出现数据冗余。

而对应的方法主要是通过协方差的特征值/特征向量运算确定一组一定数量的正交基,使数据在映射到这些基上之后方差尽量大,分布尽量分散。这些正交基就是主成分的正交基,数据与正交基相乘得到的坐标,即为主成分的坐标。

具体细节可以查看下面两篇文章,写的非常详细:

https://blog.csdn.net/Murray_/article/details/79945148

https://www.jianshu.com/p/4528aaa6dc48

主成分分析作为常用的降维方法,其常见的代码逻辑为,下面的逻辑包含了sklearn中封装好的算法,也涵盖了自己写的算法逻辑,主要是用来理解PCA算法,平时使用PCA时大可以直接调用sklearn中的常规算法:

#!/usr/bin/env python
# _*_ UTF-8 _*_

# 1、sklearn获取到的PCA算法为:
from sklearn.decomposition import PCA
import numpy as np
import matplotlib.pyplot as plt

X = np.array([[-1, 1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
pca = PCA(n_components=1)
pca.fit(X)
print(pca.transform(X))
print("-------------------------------------")

# 2、自己写PCA为:
# 一个值对应一列:scaled_x列,scaled_y列:
scaled_x = np.array([2.5, 0.5, 2.2, 1.9, 3.1, 2.3, 2, 1, 1.5, 1.1])
scaled_y = np.array([2.4, 0.7, 2.9, 2.2, 3, 2.7, 1.6, 1.1, 1.6, 0.9])
# 转化成数组矩阵,将数组转化成data矩阵:
data = np.matrix([[scaled_x[i], scaled_y[i]] for i in range(len(scaled_x))])

# 标准化矩阵数组,获取标准值:
mean_x = np.mean(scaled_x)
mean_y = np.mean(scaled_y)
scaled_x = scaled_x-mean_x
scaled_y = scaled_y-mean_y
# 得到的data是标准化之后的数据:
data = np.matrix([[scaled_x[i], scaled_y[i]] for i in range(len(scaled_x))])
# 计算各列数据的协方差矩阵,得到协方差矩阵的特征方程和特征值:
cov = np.cov(scaled_x, scaled_y)
eig_val, eig_vec = np.linalg.eig(cov)
plt.plot(scaled_x, scaled_y, 'o')
# 将特征向量呈现在坐标图上:
x_min, x_max = scaled_x.min(), scaled_x.max()
y_min, y_max = scaled_y.min(), scaled_y.max()
dx = (x_max - x_min) * 0.2
dy = (y_max - y_min) * 0.2
plt.xlim(x_min - dx, x_max + dx)
plt.ylim(y_min - dy, y_max + dy)
plt.plot([eig_vec[:, 0][0], 0], [eig_vec[:, 0][1], 0], color='red')
plt.plot([eig_vec[:, 1][0], 0], [eig_vec[:, 1][1], 0], color='red')
# 根据协方差矩阵的特征值,获取特征值的大小排序。
new_data = np.transpose(np.dot(eig_vec, np.transpose(data)))
eig_pairs = [(np.abs(eig_val[i]), eig_vec[:, i]) for i in range(len(eig_val))]
eig_pairs.sort(reverse=True)
print(eig_pairs)
# 取特征值最大的值作为需要的主成分字段:
feature = eig_pairs[0][1]
print(feature)
# 将获取到的特征向量乘以原来的矩阵数据,得到处理后的主成分:
new_data_reduced = np.transpose(np.dot(feature, np.transpose(data)))
print(new_data_reduced)
# 可以查看事情的主成分图像:
plt.plot(scaled_x, scaled_y, 'o', color='red')
plt.plot([eig_vec[:, 0][0], 0], [eig_vec[:, 0][1], 0], color='red')
plt.plot([eig_vec[:, 1][0], 0], [eig_vec[:, 1][1], 0], color='blue')
plt.plot(new_data[:, 0], new_data[:, 1], '^', color='blue')
plt.plot(new_data_reduced[:, 0], [1.2]*10, '*', color='green')
plt.show()
发布了137 篇原创文章 · 获赞 93 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/livan1234/article/details/87945391