从PCA到K-means的一次实际运用(python实现)

       今天一个学姐拿了一篇论文,问我怎么去实现论文里的那个方法。简要的看了看,还是比较简单的。大体上就是将全国不同省份的经济数据做一个平行坐标轴可视化,流程就是先将数据标准化,然后PCA降维,然后再聚类,然后再用平行坐标可视化。我叭叭叭的讲了半天她还是不明白。让她用SPSS她不会,让她用Python,结果连代码和注释都搞不明白。。。各种问,问的头都大了两三个。。。实在是受不了就自己亲自写了一个。。。

PCA和聚类的基本原理《多元统计分析》这本书里讲的很明白,这里就不再赘述。话不多说,先上马,no code no bb。


from sklearn.preprocessing import StandardScaler
import numpy as np
import pandas as pd
from sklearn.decomposition import PCA
from sklearn.cluster import k_means


def standard_pca_kmeans(file_path, sheetname, n_component, k, save=True):
    # 读取目标文件中相应的表
    df = pd.read_excel(file_path, sheet_name=sheetname)
    # 获取需要进行处理的数据,保留第一列,并转化为numpy数组
    data_useful = np.array(df.iloc[:, 1:])
    # 对数据进行标准化处理以进行PCA(相关阵法)
    scaler = StandardScaler().fit(data_useful)
    data_scaled = scaler.transform(data_useful)
    # 对数据进行PCA降维处理
    pca = PCA(n_components=n_component).fit(data_scaled)
    data_pca = np.dot(pca.components_, data_scaled.T).T
    print('当选取%s个主成分时,累计方差贡献率为%s' % (n_component, sum(pca.explained_variance_ratio_)))
    # 对降维后的数据进行聚类
    kmeans = k_means(data_pca, k)
    labels = kmeans[1]
    # 整合成一个表
    print(data_pca.shape)
    result = pd.DataFrame(data_pca, columns=['第%s主成分' % (i+1) for i in range(n_component)])
    result['类别'] = labels
    result.insert(0, 'index', df.iloc[:, 0])
    #print('前5行数据为:', result.head(5))
    if save:
        result.to_excel('结果.xlsx')
    return result, data_pca, data_scaled


if __name__ == '__main__':
    path = '园区数据.xlsx'
    sheet_name = 'Sheet1'
    result, data_pca, data_scaled = standard_pca_kmeans(path, sheet_name, 6, 6)
    # 求各主成分与原始特征的相关系数,即因子负荷,可以用来解释各变量对各主成分的重要性
    corrcoef = []
    for i in range(len(data_pca.T)):
        each_corr = []
        for j in range(len(data_scaled.T)):
            each_corr.append(np.corrcoef(data_pca.T[i], data_scaled.T[j])[0][1])
        corrcoef.append(each_corr)
    print(np.array(corrcoef))

一、数据和任务

    数据:数据来源为某示范区某年某月不同园区的财务指标:共17个园区,16个不同指标,如下所示(保险起见随便打个码吧哈哈):

    

问题和任务:用平行坐标图对十七个园区进行可视化展示,并对园区进行聚类表示。问题时指标过多而难以用这种方法去可视化,于是想到用先对16个指标进行PCA降维,然后利用K-means进行聚类。

二、流程

    1、首先导入要用的python库:

from sklearn.preprocessing import StandardScaler
import numpy as np
import pandas as pd
from sklearn.decomposition import PCA
from sklearn.cluster import k_means

    2、读取数据

# 读取目标文件中相应的表
    df = pd.read_excel(file_path, sheet_name=sheetname)
    # 获取需要进行处理的数据,保留第一列,并转化为numpy数组
    data_useful = np.array(df.iloc[:, 1:])

这里我们把数据部分摘出来,便于进行运算,最后再把第一列的园区类别插入,便于我们去观察处理

file_path为excel表格存放的位置;sheetname为对应的表名字

3、数据标准化

# 对数据进行标准化处理便于进行PCA
    scaler = StandardScaler().fit(data_useful)
    data_scaled = scaler.transform(data_useful)

      因为不同特征之间的差别较大,所以进行标准化,用相关阵法

4、PCA降维

 # 对数据进行PCA降维处理
    pca = PCA(n_components=n_component).fit(data_scaled)
    data_pca = np.dot(pca.components_, data_scaled.T).T
    print('当选取%s个主成分时,累计方差贡献率为%s' % (n_component, sum(pca.explained_variance_ratio_)))

       这里解释下PCA方法的参数。其中n_components为要保留的主成分个数,可以是int 1,2,3......等,也可以设置为‘mle’,系统会自动选择主成分个数。个人建议在维度和数据量不大的情况下手动设置,通过观察累积误差贡献率的大小来设置主成分个数。

       注意用PCA训练数据后并不是直接返回结果,而是在模型的属性里获得我们想要的结果。这里pca.components_为分解出来的正交特征向量,并不是最总的结果,最终的变换Y=UX,U即为pca.components_。PCA的结果即为data_pca。方差贡献率pca.explained_variance_ratio_是一个1-D矩阵,里边是每个主成分的方差贡献率,我们要的是设置的主成分的贡献率之和,即累计方差贡献率,该值大于0.85即可。

    如果我们想找出各原始变量对各主成分的重要性,则可以计算出每个主成分与每个变量(即特征)的相关系数,即因子负荷量,因子负荷量的绝对值越大,说明该变量对该主成分越重要。且不可将变换系数的大小来衡量变量对主成分的重要性:

# 求各主成分与原始特征的相关系数,即因子负荷量,可以用来解释各变量对各主成分的重要性
    corrcoef = []
    for i in range(len(data_pca.T)):
        each_corr = []
        for j in range(len(data_scaled.T)):
            each_corr.append(np.corrcoef(data_pca.T[i], data_scaled.T[j])[0][1])
        corrcoef.append(each_corr)
    print(np.array(corrcoef))

5、 聚类

# 对降维后的数据进行聚类
    kmeans = k_means(data_pca, k)
    labels = kmeans[1]

这里k是我们要聚的类别数。注意,k_means方法返回的是一个元组,第二项数据才是我们要的聚类后的类别标签。

6、将想要的结果整合成一个excel表

    result = pd.DataFrame(data_pca, columns=['第%s主成分' % (i+1) for i in range(n_component)])
    result['类别'] = labels   # 插入类别标签
    result.insert(0, 'index', df.iloc[:, 0])  # 插入园区名称
    #print('前5行数据为:', result.head(5))
    if save:
        result.to_excel('结果.xlsx') # 存入当前目录

7、实战

if __name__ == '__main__':
    path = '园区数据.xlsx'
    sheet_name = 'Sheet1'
    result, data_pca, data_scaled = standard_pca_kmeans(path, sheet_name, 6, 6)

这里我们设主成分个数为6,聚类类别数为6,最终输出大概就是这个样子:


8、可视化

算了,懒得搞,交给她自己做吧,我已经仁至义尽了。。。



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值