ML(8)-PCA,LDA基础+sklearn 简单实践

在这里插入图片描述

1.PCA+sklearn.decomposition.PCA

1.PCA理论基础

PCA:(principal component analysis)无监督线性降维算法,通过投影减少数据的特征数。投影方向是数据投影后方差最大的方向(重构误差最小的方向/坐标轴相关度)

投影方差最大理论:在信号处理中认为信号具有较大的方差,噪声有较小的方差,信噪比就是信号与噪声的方差比,越大越好。

最小平方理论:点到线的距离平方和越小越好(具体推导)。

两种理论都能推出同一个算法:协方差矩阵求均值。

step1:原特征向量去中心化: x = x ^ − x ‾ x=\hat{x}-\overline{x} x=x^x,去中心化,使得投影后的样本均值为0;

step2: 投影后求方差, u u u投影方向的单位向量: u T x ∗ u T x = > u T x ∗ x T u = > ∑ i u T x i ∗ x i T u = u T ∑ u u^Tx*u^Tx=>u^Tx*x^Tu=>\sum_i u^Tx_i*x_i^Tu=u^T\sum u uTxuTx=>uTxxTu=>iuTxixiTu=uTu(单个样本方差=>all sample方差);

step3:带约束问题拉格朗日乘子法: u T ∑ u + λ ( 1 − u T u ) u^T\sum u+\lambda(1-u^Tu) uTu+λ(1uTu)

step4:求最大,对上式求导为0 : ∑ u = λ u \sum u = \lambda u u=λu

由上式子可得最大投影方向为协方差矩阵的最大特征值对的特征向量,依次类推,可以得到第二大投影方向,第k大投影方向。

取特征值topk大的k个特征向量,组成一个kn的投影矩阵M,Mx可以得到k*1维的向量,作为原来向量的低维度的等价表示形式。

2.sklearn.decomposition.PCA简单实践

如果数据的各个维度的特征不一致,需要先做Z-sore Normalization(减均值除方差)。具体原因可参考博文:https://www.jianshu.com/p/c21c0e2c403a

sklearn.decomposition.PCA(n_components=None, copy=True, whiten=False)

PCA对象的初始化参数
n_componentsnums/ string,default=None,所有成分被保留。 n_components > 1降维后的维度;0< n_components<1将自动选取特征个数n,使得满足所要求的方差百分比。
copy是否在运行算法时,将原始训练数据复制一份
whiten是否对降维后的数据的每个特征进行归一化
PCA对象方法
fit(x)用x训练PCA 对象pca.fit(x)
transform(x)训练好PCA对象后用pca.transform(x)进行降维
fit_transform(x)用x来训练PCA模型,同时返回降维后的数据x_reduced= pca.fit_transform(x)
inverse_transform()将降维后的数据转换成原始数据 x = pca.inverse_transform(x_reduced)
PCA对象的属性
pca.components_k个特征向量
pca.n_components_特征向量的数量 k
pca.explained_variance_往各个特征向量方向投影后的方差
pca.explained_variance_ratio_各个特征值占总特征值的比例 ?

鸢尾花降维算法demo:鸢尾花数据特征是4维的,共三类样本。

import matplotlib.pyplot as plt
import sklearn.decomposition as dp
from sklearn.datasets.base import load_iris
from mpl_toolkits.mplot3d import Axes3D
plt.switch_backend('agg')

# 鸢尾花数据一共有三个类别
n = 3  # 降到n维度
x,y=load_iris(return_X_y=True)
pca=dp.PCA(n_components=n)

reduced_x=pca.fit_transform(x)

# PCA对象的一些属性
print(pca.explained_variance_ratio_,sum(pca.explained_variance_ratio_)) # 各个特征值占总特征值的比例?
print(pca.explained_variance_)  # 各个特征向量方向投影后的方差
print(pca.n_components_)  # 特征向量的数量 k
print(pca.components_)  # k个特征向量

red_x,red_y,red_z = [], [], []
blue_x,blue_y, blue_z = [], [], []
green_x,green_y, green_z = [], [], []

# 将同一个类别的数据绘制成同一个元素
for i in range(len(reduced_x)): 
    if y[i]==0:
        red_x.append(reduced_x[i][0])
        red_y.append(reduced_x[i][1])
        red_z.append(reduced_x[i][2])

    elif y[i]==1:
        blue_x.append(reduced_x[i][0])
        blue_y.append(reduced_x[i][1])
        blue_z.append(reduced_x[i][2])
    else:
        green_x.append(reduced_x[i][0])
        green_y.append(reduced_x[i][1])
        green_z.append(reduced_x[i][2])
figure = plt.figure()
ax1 = figure.add_subplot(1,2,1)
ax2 = figure.add_subplot(1,2,2,projection='3d')

# 两个主成分,二维图像
ax1.scatter(red_x,red_y,c='r',marker='x')
ax1.scatter(blue_x,blue_y,c='b',marker='D')
ax1.scatter(green_x,green_y,c='g',marker='.')

# 三个主成分,三维图像,更高维度的不好显示
ax2.scatter3D(red_x,red_y,red_z,c='r',marker='x')
ax2.scatter3D(blue_x,blue_y,blue_z, c='b',marker='D')
ax2.scatter3D(green_x,green_y,green_z, c='g',marker='.')
plt.savefig("./pca_iris_test.png")
plt.close()

输出

[0.92461872 0.05306648 0.01710261] 0.9947878161267246
[4.22824171 0.24267075 0.0782095 ]
3
[[ 0.36138659 -0.08452251  0.85667061  0.3582892 ]
 [ 0.65658877  0.73016143 -0.17337266 -0.07548102]
 [-0.58202985  0.59791083  0.07623608  0.54583143]]```

在这里插入图片描述

2.LDA+sklearn.discriminant_analysis.LinearDiscriminantAnalysis

2.1 LDA理论基础

LDA–Linear Discriminant Analysis,线性判别分析。有监督的降维过程,依据类别选择降维方向。
降维方向选择依据:Fisher准则,类内离散程度越小,类间离散程度越大.
F D R = ( μ 1 − μ 2 ) 2 σ 1 2 + σ 2 2 FDR=\frac{(\mu_1-\mu_2)^2}{\sigma_1^2+\sigma_2^2} FDR=σ12+σ22(μ1μ2)2

式中都是投影后的统统计量,引入投影前特征向量x和投影方向u:
( μ 1 − μ 2 ) 2 = u T ( μ ‾ 1 − μ ‾ 2 ) ( μ ‾ 1 − μ ‾ 2 ) T u : = u T S b u (\mu_1-\mu_2)^2=u^T(\overline\mu_1-\overline\mu_2)(\overline\mu_1-\overline\mu_2)^Tu := u^TS_bu (μ1μ2)2=uT(μ1μ2)(μ1μ2)Tu:=uTSbu

σ i 2 = u T Σ i u − > σ 1 2 + σ 2 2 : = u T S w u \sigma_i^2=u^T\Sigma_iu->\sigma_1^2+\sigma_2^2:= u^TS_wu σi2=uTΣiu>σ12+σ22:=uTSwu

则FDR可以写维:
F D R = u T S b u u T S w u FDR=\frac{u^TS_bu}{u^TS_wu} FDR=uTSwuuTSbu

其中:类内散度矩阵: s w = Σ 1 + Σ 2 s_w=\Sigma_1+\Sigma_2 sw=Σ1+Σ2
类间散度矩阵: s b = ( μ ‾ 1 − μ ‾ 2 ) ( μ ‾ 1 − μ ‾ 2 ) s_b = (\overline\mu_1-\overline\mu_2)(\overline\mu_1-\overline\mu_2) sb=(μ1μ2)(μ1μ2)

上式子为广义瑞丽熵,有解析解:最优解的条件:
S b u = λ S w u S_b u=\lambda S_w u Sbu=λSwu

二分类问题 u = s w − 1 ( μ ‾ 1 − μ ‾ 2 ) ( μ ‾ 1 − μ ‾ 2 ) u=s_w^{-1}(\overline\mu_1-\overline\mu_2)(\overline\mu_1-\overline\mu_2) u=sw1(μ1μ2)(μ1μ2)
详细推导不详,参考资料:https://www.cnblogs.com/pinard/p/6244265.html

LDA key point:
1)找降维后最容易分类的方向
2)只能降到min(sample nums, class num-1), 二分类就只能降到1维。

2.2 sklearn LDA简单实践

def demo_lda(x,y,n=3):
    lda = LinearDiscriminantAnalysis(n_components=n)
    lda.fit(x,y)
    reduced_x = lda.transform(x)

    index_list = []
    for i in range(n):
        index_list.append("com%d"%i)

    reduced_data = pd.DataFrame(reduced_x, columns = index_list)
    reduced_data["label"] = y
    reduced_data.to_csv("lda_%dcom_open.csv"%n)

    red_x,red_y = [], []
    blue_x,blue_y = [], []
    green_x,green_y = [], []

    # 将同一个类别的数据绘制成同一个元素
    for i in range(len(reduced_x)): 
        if y[i]==0:
            red_x.append(reduced_x[i][0])
            red_y.append(reduced_x[i][1])

        elif y[i]==1:
            blue_x.append(reduced_x[i][0])
            blue_y.append(reduced_x[i][1])
        else:
            green_x.append(reduced_x[i][0])
            green_y.append(reduced_x[i][1])
    figure = plt.figure()
    ax1 = figure.add_subplot(1,2,1)

    # 两个主成分,二维图像
    ax1.scatter(red_x,red_y,c='r',marker='x')
    ax1.scatter(blue_x,blue_y,c='b',marker='D')
    ax1.scatter(green_x,green_y,c='g',marker='.')

    plt.savefig("./lda_iris_test.png")
    plt.close()

if __name__ == "__main__":
    n = 2  # 降到n维度
    x,y=load_iris(return_X_y=True)
    demo_lda(x,y,n)

在这里插入图片描述

参考博文:
PCA:
https://blog.csdn.net/u012102306/article/details/52294726
https://www.cnblogs.com/youngsea/p/9334773.html
https://www.jb51.net/article/181205.htm
LDA:
https://zhuanlan.zhihu.com/p/161556242
sklearn 中的降维算法:https://www.cnblogs.com/LUOyaXIONG/gallery/image/259967.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值