维度爆炸?Python实现数据压缩竟如此简单!
前言
在之前的文章中,我们已经详细介绍了主成分分析的原理,并用Python基于主成分分析的客户信贷评级进行实战。
在那篇文章中我们指出的主成分分析常见的三个应用场景中,其中有一个是「数据描述」,以描述产品情况为例,比如著名的波士顿矩阵,子公司业务发展状况,区域投资潜力等,需要将多变量压缩到少数几个主成分进行描述,压缩到两个主成分是最理想的,这样便可在一张图内表现出来。
但这类分析一般做主成分分析是不充分的,能够做到因子分析更好。但因子分析的知识点非常庞杂,所以本文将跳过原理,直接通过案例再次「实战PCA分析」,用于主成分分析到因子分析的一个过渡,目标有两个:
-
能够通过主成分分析结果来估计生成的主成分所表示的含义 -
借以引出因子分析的优势和学习的必要性是本文的目标。
需求说明
上司希望从事数据分析岗位的你仅用两个短句就概括出以下数据集所反映出的经济现象用几个长句都不一定能够很好的描述数据集的价值,更何况高度凝练的两个短句,短短九个指标就已经十分让人头疼了,如果表格再宽一些呢,比如有二三十个变量?
Python实战
本节我们将使用Python对上面的数据进行分析
数据探索
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('seaborn-whitegrid')
plt.rc('font', **{'family': 'Microsoft YaHei, SimHei'})
# 设置中文字体的支持
plt.rcParams['axes.unicode_minus'] = False
# 解决保存图像是负号'-'显示为方块的问题
sns.set(font='SimHei') # 解决Seaborn中文显示问题
df = pd.read_csv('城市经济.csv')
df
在做主成分分析前,都应该进行变量间相关性的探索,毕竟如果变量是独立的,则不可压缩。
plt.figure(figsize=(8, 6))
sns.heatmap(data=df.corr(), annot=True) # annot=True: 显示数字
发现变量间的相关性较高,有变量压缩的必要性
PCA建模
数据标准化
使用中心标准化,即将变量都转化成z分数
的形式,避免量纲问题对压缩造成影响
from sklearn.preprocessing import scale
data = df.drop(columns='area') # 丢弃无用的类别变量
data = scale(data)
初步建模
需要说明的是第一次的n_components
参数最好设置得大一些(保留的主成份),观察explained_variance_ratio_
取值变化,即每个主成分能够解释原始数据变异的百分比
from sklearn.decomposition import PCA
pca = PCA(n_components=9) # 直接与变量个数相同的主成分
pca.fit(data)
结果分析
累积解释变异程度
# 累积解释变异程度
plt.plot(np.cumsum(pca.explained_variance_ratio_), linewidth=3)
plt.xlabel('成份数')
plt.ylabel('累积解释方差'); plt.grid(True)
可以看出,当取主成分数为2时,累积解释方差就已经达到0.97有多(0.85 就已经足够),说明我们只需要取两个主成分即可
重新建模
综上可知两个主成分就已经足够了
pca = PCA(n_components=2) # 直接与变量个数相同的主成分
pca.fit(data)
pca.explained_variance_ratio_
new_data = pca.fit_transform(data) # fit_transform 表示将生成降维后的数据
# 查看规模差别
print("原始数据集规模: ", data.shape)
print("降维后的数据集规模:", new_data.shape)
可以看到9个变量压缩成两个主成分!
主成分中各变量的权重分析
先看两个主成分与 9 个变量的系数关系
results = pd.DataFrame(pca.components_).T
results.columns = ['pca_1', 'pca_2']
results.index = df.drop(columns='area').columns
results
可以明显看出:
-
主成分1几乎不受data的第二个自变量 人均GDP
的影响,0.034,其他自变量对其影响程度都差不多。 -
主成分2受data的第二个自变量 人均GDP
影响最大,达到了0.94
结果描述
通过上面的PCA建模,我们把9个自变量压缩成了2 主成分,每个主成分受哪些变量的影响也有了了解。虽然得到的主成分都没有什么意义,但我们是否可以通过变量们对主成分的影响程度来为生成的两个主成分命名呢?
第一个主成分在表达经济总量的指标上的权重相当,可考虑命名为经济总量水平
;而第二个主成分只在人均GDP上权重很高,可暂时考虑命名为人均水平
注意:这里的给主成分命名(包括后续有关因子分析的推文)都是对降维后的数据进行的,而不是生成的主成分,这样才有比较和描述的价值。每个自变量在生成的主成分上的权重只是给这个主成分的命名提供参考,真正的命名操作是对压缩后的数据进行。
new_data = pca.fit_transform(data) # fit_transform 表示将生成降维后的数据
results = df.join(pd.DataFrame(new_data, # new_data 是降维后的数据
columns=['经济总量水平', '人均水平'])) # 与原来的数据拼接
results
绘制波士顿矩阵,这里的散点图的点标注代码是前人的优秀轮子,直接拿来用即可。
plt.figure(figsize=(10, 8))
# 基础散点图
x, y = results['经济总量水平'], results['人均水平']
label = results['area']
plt.scatter(x, y)
plt.xlabel('经济总量水平'); plt.ylabel('人均水平')
# 对散点图中的每一个点进行文字标注
## 固定代码,无需深究,拿来即用
## 给点标注是需要将 x 和 y 以及标签如上段代码那样单独拆开
for a,b,l in zip(x,y,label):
plt.text(a, b+0.1, '%s.' % l, ha='center', va='bottom', fontsize=14)
# 添加两条竖线
plt.vlines(x=results['经济总量水平'].mean(),
ymin=-1.5, ymax=3, colors='red')
plt.hlines(y=results['人均水平'].mean(),
xmin=-4, xmax=6, colors='red')
最终从上图可以看出:
-
广西,河北,福建三地的人均水平和经济总量水平都偏低 -
上海的人均经济水平很高,但经济总量水平缺只是略优于均值 -
广东的人均经济水平稍次于均值,但经济总量水平很高 -
......
小结
本文再次讲解了基于主成分分析的样本特征描述,并使用Python示范了完整的流程。其中,也对由多个自变量生成的主成分的命名描述操作中需要注意的点作了比较详细的说明。其实PCA并不能非常好的满足维度分析的需求,能够做到「因子分析」最好,它是主成分方法的拓展,作为维度分析的手段,因子分析也是构造合理的聚类模型和稳健的分类模型的必然步骤。所以我们因子分析案例再见~
今天的文章就到这里,如果你喜欢本系列请点亮在看给作者一点鼓励~
❝Python商业数据挖掘自动化系列代码及数据已经上传GitHub,如有需要可以自行下载:「https://github.com/liuhuanshuo/zaoqi-Python/tree/master/商业数据分析实战」
❞
最近更新了很多数据挖掘的文章,今天推荐的书为Python入门到人工智能实战(全书共20 章,包括Python 安装配置、Python 语言基础、流程控制语句、序列、函数、对象、文件及异常处理、数据处理和分析的重要模块NumPy、Pandas、机器学习基础、机器学习常用调优方法、神经网络、卷积神经网络,以及使用PyTorch、Keras 实现多个人工智能实战案例等)点击下方图片可以直达购买页面查看详情与购买(现在京东和当当都有优惠)
送书规则还是和以前一样,一共抽3本,点击下方小程序即可参与抽奖,点亮在看能增加中奖率哦~
本文分享自微信公众号 - 早起Python(zaoqi-python)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
解析call、apply、bind三者区别及实现原理
关注前端技术专栏,回复“资源”免费领取全套视频教程 前言 不管在写插件,还是写框架,又或者其它业务开发中。我们都会遇到在执行函数的时候,如果需要保证函数内部this不被污染或者说需要使函数内部this指向到指定对象的时候,都会按情况分别使用到call、apply、bind方法来实现需求。 那么,你知道它们三者之间的区别吗?又分别如何实现的呢?接下来,请准我一一道来并分别实现它们吧~ 正文 call、apply、bind的区别 bind bind与call或apply最大的区别就是bind不会被立即调用,而是返回一个函数,函数内部的this指向与bind执行时的第一个参数,而传入bind的第二个及以后的参数作为原函数的参数来调用原函数。 用一个例子来理解一下吧 letobj={ name: 'wujia', fn: function (a, b, c) {console.log(this.name, a, b, c)}}window.name = '吴佳'let nFn = obj.fn.bind(window, '第一个参数')nFn('第二个参数','第三个参数')// 最后输出:吴...
- 下一篇
App Clips 开发设计指北
作者: Leppard,iOS 开发者,目前就职于字节跳动音乐团队 WWDC20 10172: https://developer.apple.com/videos/play/wwdc2020/10172/ 在今年WWDC上,苹果推出了一个亮眼的新功能:App Clips。而对于国内的用户和开发者来说,App Clips 的功能和形式都十分让人熟悉:这就是苹果自家的“小程序”。 小程序的概念在当下并不新鲜,微信,支付宝等大厂应用都在推小程序,其生态也越来越健壮,在功能和使用上已经渗透到人们生活的方方面面。但是,这并不意味着 App Clips 没有用武之地;相反,由于 App Clips 可以脱离主体存在,不需要先启动主体 App 才能间接打开,本身又拥有原生体验和 iOS 系统级支持,App Clips 势必会超越三方,成为体验最好、接受程度最高的“小程序”。 本文基于WWDC2020 10172 - Designing Great App Clips[1],介绍了开发者在思考和设计 App Clips 需要注意和考虑的一些原则和 Tips。内容分为五个小节,第一小节简单介绍了 Ap...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7,CentOS8安装Elasticsearch6.8.6
- Windows10,CentOS7,CentOS8安装Nodejs环境
- CentOS关闭SELinux安全模块
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS7设置SWAP分区,小内存服务器的救世主
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS6,CentOS7官方镜像安装Oracle11G
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS7安装Docker,走上虚拟化容器引擎之路