五一假期过去了,不知道大家过得怎么样呢?假期的这几天,小文没有选择出去旅游(不想成为人海中的一员-。-),而是待在家里好好地阅读了我的新书--陈哲老师的《活用数据,驱动业务的数据分析实战》,可谓收获满满。当然说的不是spss的使用技巧,而是分析的思路。书里的案例用的spss,小文并不会,因此小文用python实现了一下。
这个案例来自于第六章--甲保险公司客户分类分析。文中使用了stp法进行分析,即客户细分,目标客户选取,目标客户定位。
1.客户细分
客户细分根据客户的分类维度进行细分,分类的维度包括5类,分别是自然属性因素、社会特征因素、行为特征因素、态度偏好因素和生活状态与个性因素。
前三者是表露在外的因素,即通过接触就可知道的因素,属于事前分类维度;后两者需要通过调研才能了解,是客户内在本质的区别,属于事后分类维度。因此,往往通过事后分类维度做客户分类,以保证分类的深入性,再通过事前分类维度进行描述与验证,以保证分类客户的差异性和可接触性。
import pandas as pd
import prince # 对应分析
from scipy.cluster import hierarchy # 层次聚类
from statsmodels.formula.api import ols
from statsmodels.stats.anova import anova_lm # 方差分析
import matplotlib.pyplot as plt
from factor_analyzer import FactorAnalyzer, calculate_kmo, calculate_bartlett_sphericity # 因子分析
%matplotlib inline
# 读取数据
X = pd.read_csv('./Desktop/第6章保险公司客户分类数据.csv', engine='python',
encoding='utf-8-sig') # 注意设置encoding参数,不然中文字体会乱码
x = X.iloc[:, -9:]
x.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 712 entries, 0 to 711
Data columns (total 9 columns):
对自己的生活很满意 712 non-null int64
为享受而产生的浪费是必要的 712 non-null int64
买房子前要先有车 712 non-null int64
不惜金钱和时间装修房子 712 non-null int64
买衣服都买便宜的 712 non-null int64
休息时经常进行户外活动 712 non-null int64
尝试生活充满变化 712 non-null int64
喜欢独自享受安静的生活 712 non-null int64
下班后尽快回家 712 non-null int64
dtypes: int64(9)
memory usage: 50.1 KB
读取数据,将事后分类维度取出来并查看类型,发现9个维度都是数字类型并且部分维度之间似乎存在一定的相关性,这种相关性可能会造成重叠信息的扩大化,增加分类偏差,因此先对这9个维度进行因子分析。
1.1 因子分析
因子分析是指通过少数不相关的因子反映多个具有相关性的原始信息,起到降维和剔除相关性的作用。
因子分析的前提是具有一定的相关性,因此必须通过了kmo和bartlett球形度检验的数据才能进行因子分析。
#因子分析适用性检验
kmo = calculate_kmo(x) # kmo值要大于0.7
bartlett = calculate_bartlett_sphericity(x) # bartlett球形度检验p值要小于0.05
print('kmo:{},bartlett:{}'.format(kmo[1], bartlett[1]))
kmo:0.7164804529238993,bartlett:2.40899758533843e-221
通过了适用性检验后进行因子分析,格式为:FactorAnalyzer(rotation= None,n_factors=n,method='principal')
(1)rotation:旋转的方式,包括None:不旋转,'varimax':最大方差法,'promax':最优斜交旋转;
(2)n_factors:公因子的数量;
(3)method:因子分析的方法,包括'minres':最小残差因子法,'principal':主成分分析法;
# 使用主成分分析法,9个因子维度拟合
fa = FactorAnalyzer(rotation=None, n_factors=9, method='principal')
fa.fit(x)
fa_9_sd = fa.get_factor_variance()
fa_9_df = pd.DataFrame(
{'特征值': fa_9_sd[0], '方差贡献率': fa_9_sd[1], '方差累计贡献率': fa_9_sd[2]})
#各个因子的特征值以及方差贡献率
print(fa_9_df)
特征值 方差贡献率 方差累计贡献率
0 2.779391 0.308821 0.308821
1 1.302006 0.144667 0.453489
2 1.157716 0.128635 0.582124
3 1.034961 0.114996 0.697119
4 0.659054 0.073228 0.770348
5 0.597498 0.066389 0.836736
6 0.571816 0.063535 0.900271
7 0.486350 0.054039 0.954310
8 0.411207 0.045690 1.000000
查看9个公因子的特征值以及方差贡献率,一般选择方差累计贡献率大于0.8的公因子,而文中选择了特征值大于1的公因子,即方差累计贡献率为0.697的前4个公因子。接着根据4个公因子重新拟合。
#公因子数设为4个,重新拟合
fa_4 = FactorAnalyzer(rotation=None, n_factors=4, method='principal')
fa_4.fit(x)
#查看公因子提取度
print(fa_4.get_communalities())
[0.74797278 0.67110816 0.74233283 0.73808703 0.66567718 0.77689271
0.69607415 0.61523932 0.62069047]
查看公因子的提取度,发现当使用4个公因子时,4个公因子对9个维度的解释率都超过0.6,说明提取的4个公因子对原始维度有一定的解释力。
接着查看4个公因子的因子载荷,看看是否需要旋转。因子载荷即公因子对原始维度的解释力。
#查看因子载荷
print(fa_4.loadings_)
[[ 0.41758577 -0.04630919 0.69667789 0.29341146]
[ 0.5458075 -0.36656161 0.20321007 0.44445539]
[ 0.64142608 -0.2555359 -0.50646667 0.09538522]
[ 0.65217692 -0.36074267 -0.3699891 0.21383425]
[ 0.54104332 0.4901776 -0.28576184 -0.22586587]
[ 0.58866609 -0.09674514 0.23956478 -0.60300418]
[ 0.64268497 -0.19004547 0.23352467 -0.43861045]
[ 0.48559443 0.56693683 -0.10335096 0.21757431]
[ 0.42690002 0.60240529 0.18274222 0.20532898]]
以第一个维度为例,我们发现4个公因子对原始的第一个维度的解释程度分别为:0.418,-0.046,0.697,0.293,表明公因子1与公因子3之间存在一定的相关性,达不到因子分析的既定效果,因此需要进行旋转,使得各个公因子具有差异化的特征。
#使用最大方差