使用PCA分析鸢尾花数据

在这里简单记录下学习PCA的一次简单实践;

为什么需要用到PCA呢?

在数据挖掘中,维度太大是一个很大的问题,影响挖掘的效率,PCA是一个最常用的、简单、基础理论完备的方法。

PCA(主成分分析)的手推过程

  1. 求给出矩阵X(m x n)的协方差矩阵S(m x m);
  2. 计算协方差矩阵的特征值λ和特征向量α;
  3. 计算方差贡献率 ;
    T i = λ i ∑ i = 1 n λ i T_i = \frac{\lambda_i}{\sum_{i=1}^n\lambda_i} Ti=i=1nλiλi
    第k个主成分的方差等于协方差矩阵S的第k个特征值(可从数学上证明)
  4. 取前K大的方差贡献率对应的特征值和特征向量;
    其中K表示特征的个数,
    且K个特征的方差贡献率之和大于等于要求的信息完整度(如80%) ; ∑ i = 1 K T i ≥ 80 % \sum_{i=1}^KT_i \geq 80\% i=1KTi80%
  5. 将4.中所取特征向量组成矩阵作为PCA的线性变换矩阵M(K x m);
    这样就可以实现了数据特征的降维;
  6. 将线性变换矩阵M与原数据矩阵X做点积,即可得到各个主成分对各特征的相关系数

具体手推的例子这里省略。。。

以python代码为例

导入鸢尾花数据

	from sklearn import datasets 
	iris = datasets.load_iris()
	x = iris.data

对数据进行标准化处理

 	# 取得各个特征的均值
    n_samples, n_features = X.shape
    # mean = np.array([np.mean(X[:, i]) for i in range(n_features)])
    mean = X.mean(axis=1, keepdims=True)
    # 标准化
    normal_X = X - mean

计算协方差矩阵

    # 协方差矩阵
    cov_matrix = np.dot(normal_X, np.transpose(normal_X)) / (n_features - 1)
    print(cov_matrix)
    # cov = np.cov(X)
    # print(cov)

计算协方差矩阵的特征值和特征向量

	eig_val, eig_vec = np.linalg.eig(cov_matrix)
    print("特征值:")
    print(eig_val)
    # print(eig_val.shape)
    print("特征向量:")
    print(eig_vec)

计算方差贡献率

    # 计算方差贡献率
    y_contri = np.array([eig_val[i] / eig_val.sum() for i in range(len(eig_val))])
    print("y的方差贡献率:")
    print(y_contri)

选取前K个方差贡献率的特征向量,构成线性变换矩阵feature
我这里偷懒了,用肉眼选取k的值。。。

    # 将对应的特征值和特征向量存入eig_pairs
    eig_pairs = [(np.abs(eig_val[i]), eig_vec[:, i]) for i in range(len(eig_val))]
    # 按eig_val从大到小顺序排列eig_vec
    eig_pairs.sort(reverse=True)
    # 选择前k个eig_vec
    feature = np.array([ele[1] for ele in eig_pairs[:k]])

线性变换矩阵和原数据矩阵做点积得主成分对各个特征的相关系数

result = np.dot(feature, X)

完整代码如下:

from sklearn import datasets
import numpy as np


def load_data():
    """
    加载鸢尾花数据
    """
    iris = datasets.load_iris()
    x = iris.data
    return x


def pca(X, k):  # k是维度
    # 取得各个特征的均值
    n_samples, n_features = X.shape
    # mean = np.array([np.mean(X[:, i]) for i in range(n_features)])
    mean = X.mean(axis=1, keepdims=True)
    # 标准化
    normal_X = X - mean
    # print(normal_X)

    # 协方差矩阵
    cov_matrix = np.dot(normal_X, np.transpose(normal_X)) / (n_features - 1)
    print(cov_matrix)
    # cov = np.cov(X)
    # print(cov)

    # 计算特征值和特征向量
    # scatter_matrix = np.dot(np.transpose(normal_X), normal_X)
    # eig_val, eig_vec = np.linalg.eig(np.transpose(scatter_matrix))
    eig_val, eig_vec = np.linalg.eig(cov_matrix)
    print("特征值:")
    print(eig_val)
    # print(eig_val.shape)
    print("特征向量:")
    print(eig_vec)

    # 计算方差贡献率
    y_contri = np.array([eig_val[i] / eig_val.sum() for i in range(len(eig_val))])
    print("y的方差贡献率:")
    print(y_contri)

    # 将对应的特征值和特征向量存入eig_pairs
    eig_pairs = [(np.abs(eig_val[i]), eig_vec[:, i]) for i in range(len(eig_val))]
    # 按eig_val从大到小顺序排列eig_vec
    eig_pairs.sort(reverse=True)
    # 选择前k个eig_vec
    feature = np.array([ele[1] for ele in eig_pairs[:k]])
    # print(feature)
    # result = np.dot(X, np.transpose(feature))
    result = np.dot(feature, X)
    # print(result.shape)
    return result


# print(load_data().shape)
data = np.transpose(load_data())

result = pca(data, 1)
print("结果为:")
print(result)

你可能感兴趣的:(python,数据分析,数据挖掘)