PCA降维

#coding=utf-8
import numpy as np

from matplotlib import  pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d import proj3d
from matplotlib.patches import FancyArrowPatch

np.random.seed(1)
mu_vec1 = np.array([0,0,0])  #定义均值

#定义协方差
cov_mat1 = np.array([[1,0,0],[0,1,0],[0,0,1]])  #单位矩阵,对角线上全为1,非对角线元素全为0

#根据均值和协方差生成数据
class1_sample = np.random.multivariate_normal(mu_vec1, cov_mat1, 20).T

#高斯分布=正太分布  均值为0,方差为1

#判断矩阵是否为3*20,否的打印错误,程序终止
assert class1_sample.shape == (3,20), "The matrix has not the dimensions 3x20"

#生成,均值为1,协方差矩阵为[[1,0,0],[0,1,0],[0,0,1]],20组数据,每组数据三个维度
mu_vec2 = np.array([1,1,1])
cov_mat2 = np.array([[1,0,0],[0,1,0],[0,0,1]])
class2_sample = np.random.multivariate_normal(mu_vec2, cov_mat2, 20).T
assert class2_sample.shape == (3,20), "The matrix has not the dimensions 3x20"

#可视化两组数据
fig = plt.figure(figsize=(4,4))  #长:8*2.54=20厘米  宽:8*2.54=20厘米
ax = fig.add_subplot(111)
#plt.rcParams['legend.fontsize'] = 10
#plt.rcParams['legend.fontsize'] = 10 #设置图例名字体大小


#ax.plot(class1_sample[0,:], class1_sample[1,:], class1_sample[2,:], 'o', markersize=8, color='blue', alpha=0.5, label='class1')
#ax.plot(class2_sample[0,:], class2_sample[1,:], class2_sample[2,:], '^', markersize=8, alpha=0.5, color='red', label='class2')
#plt.show();

all_samples = np.concatenate((class1_sample, class2_sample), axis=1)


mean_x = np.mean(all_samples[0,:])
mean_y = np.mean(all_samples[1,:])
mean_z = np.mean(all_samples[2,:])

mean_vector = np.array([[mean_x],[mean_y],[mean_z]]) #构建均值向量

#构建离散度矩阵
scatter_matrix = np.zeros((3,3))
# ([x,y,z].reshape(3,1)-mean_vector).dot(([x,y,z].reshape(3,1)-mean_vector)).T)
for i in range(all_samples.shape[1]):
    scatter_matrix += (all_samples[:,i].reshape(3,1) - mean_vector).dot((all_samples[:,i].reshape(3,1) - mean_vector).T)

#构建协方差矩阵
cov_mat = np.cov([all_samples[0,:],all_samples[1,:],all_samples[2,:]])

#计算特征值和特征向量
eig_val_cov,eig_vec_cov=np.linalg.eig(cov_mat)

#可视化特征向量

class Arrow3D(FancyArrowPatch):
    def __init__(self, xs, ys, zs, *args, **kwargs):
        FancyArrowPatch.__init__(self, (0,0), (0,0), *args, **kwargs)
        self._verts3d = xs, ys, zs

    def draw(self, renderer):
        xs3d, ys3d, zs3d = self._verts3d
        xs, ys, zs = proj3d.proj_transform(xs3d, ys3d, zs3d, renderer.M)
        self.set_positions((xs[0],ys[0]),(xs[1],ys[1]))
        FancyArrowPatch.draw(self, renderer)

''' 显示特征向量
for v in eig_vec_cov.T:
    a = Arrow3D([mean_x, v[0]], [mean_y, v[1]], [mean_z, v[2]], mutation_scale=20, lw=3, arrowstyle="-|>", color="r")
    ax.add_artist(a)
'''

''' 画出均值点
ax.plot([mean_x], [mean_y], [mean_z], 'o', markersize=10, color='red', alpha=0.5)
'''

eig_pairs = [(np.abs(eig_val_cov[i]), eig_vec_cov[:,i]) for i in range(len(eig_val_cov))]

eig_pairs.sort(key=lambda x: x[0], reverse=True)

#降维矩阵
matrix_w = np.hstack((eig_pairs[0][1].reshape(3,1), eig_pairs[1][1].reshape(3,1)))


#将数据映射到二维空间
transformed = matrix_w.T.dot(all_samples)
plt.plot(transformed[0,0:20], transformed[1,0:20], 'o', markersize=7, color='blue', alpha=0.5, label='class1')
plt.plot(transformed[0,20:40], transformed[1,20:40], '^', markersize=7, color='red', alpha=0.5, label='class2')
plt.xlim([-4,4])
plt.ylim([-4,4])
plt.xlabel('x_values')
plt.ylabel('y_values')
plt.legend()
plt.title('Transformed samples with class labels')
plt.show()

参考:
http://blog.csdn.net/luzhangting/article/details/64125945
https://www.cnblogs.com/charlotte77/p/5625984.html
https://zhuanlan.zhihu.com/p/21580949

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值