狭义数据分析3

交叉分析

分析属性和属性间的关系,交叉分析的方法比较多,如可以任意取两列,用假设检验的方法,判断他们之间是否有联系,也可以直接以一个或几个属性为行,一个或几个属性为列,做成一张透视表,通过观察这张新生成的表的性质,可以更直观的分析两个属性或几个属性之间的关系

import numpy as np
import pandas as pd
import scipy.stats as ss
import matplotlib.pyplot as plt
import seaborn as sns

sns.set_style(style="whitegrid")
df = pd.read_csv('./HR_comma_sep.csv')
# 想知道各个部门的离职率是不是有明显的差异
# 使用独立t检验法(比较两者均值的差异性)
# 基本思路:得到各个部门的离职分布,然后两两之间求他们的t检验统计量,并求出p值

dp_indices = df.groupby(by='sales').indices  # 得到分组后的索引
print(dp_indices)
_sum = 0
for item in dp_indices.values():
    _sum += len(item)
print(_sum)
# property indices 得到的是一个分组后,该分组键中的各个唯一值在原df中的索引,通过_sum验证了
sales_values = df["left"].iloc[dp_indices["sales"]].values
technical_values = df["left"].iloc[dp_indices["technical"]].values
# 求出组中两个属性间的t检验的p值
print(ss.ttest_ind(sales_values, technical_values)[1])
# 取出按sales分组后的所有唯一值
dp_keys = list(dp_indices.keys())
print(dp_keys)
# 初始化一个矩阵
dp_t_mat = np.zeros([len(dp_keys), len(dp_keys)])
# 遍历矩阵的每一个位置,如果两两的t检验p值小于0.05则赋值为-1,不是赋值为p值
for i in range(len(dp_keys)):
    for j in range(len(dp_keys)):
        # t检验
        p_value = ss.ttest_ind(df["left"].iloc[dp_indices[dp_keys[i]]].values, \
                               df["left"].iloc[dp_indices[dp_keys[j]]].values)[1]
        # t检验的P值小于0.05赋-1,就是让heatmap绘出的图形,更加具有区分性
        if p_value < 0.05:
            dp_t_mat[i][j] = -1  # 就是说他们之间有显著差异
        else:
            dp_t_mat[i][j] = p_value

sns.heatmap(dp_t_mat, xticklabels=dp_keys, yticklabels=dp_keys, annot=True)
plt.show()

# 建一个透视表pd.pivot_table()
# values="left"我们看得值是left,横坐标index设置为promotion_last_5years,再指定一个salary,
# 纵坐标columns  表示Work_accident,聚合方法aggfunc,设为平均数,是一个函数
piv_tb = pd.pivot_table(df, values="left", index=["promotion_last_5years", "salary"], \
                        columns=["Work_accident"], aggfunc=np.mean)
print(piv_tb)
# 画图,透视表,填入这张表piv_tb,最小值vmin,最大值vmax,颜色cmap
sns.heatmap(piv_tb, vmin=0, vmax=1, cmap=sns.color_palette("Reds", n_colors=256))
plt.show()

在这里插入图片描述
在这里插入图片描述

分组分析

离散的分组可以直接钻取:
钻取:分为向上钻取和向下钻取,向上就是不断汇总,向下就是不断分开。
连续的分组:
在这里插入图片描述
在这里插入图片描述

D表示目标的标注,比如HR表中我们关注的是员工是否会离职,那么D就代表是否会离职,C就表示要比较和对比的属性。

计算连续值的Gini系数:
求Gini系数:

#可能平方和
def getProbSS(s):
    prt_ary = s.groupby(s, by=s).count().values / float(len(s))
    return sum(prt_ary**2)
#求Gini的值
def getGini(s1,s2):
    d=dict()
    for i in list(range(len(s1))):
        d[s1[i]]=d.get(s1[i],[]) + [s2[i]]
    return 1-sum([getProbSS(d[k])*len(d[k]) / float(len(s1)) for k in d])
print("getGini",getGini(s1,s2))

代码实现:

import numpy as np
import pandas as pd
import scipy.stats as ss
import matplotlib.pyplot as plt
import seaborn as sns

sns.set_style(style="whitegrid")
df = pd.read_csv('./HR_comma_sep.csv')
# 离散值分组
sns.barplot(x='salary', y='left', hue='sales', data=df)  # hue='sales',表明按sales分组进行向下钻取
plt.show()

# 连续值分组
sl_s = df["satisfaction_level"][:1000]
sns.barplot(list(range(len(sl_s))), sl_s.sort_values())
plt.show()

在这里插入图片描述
在这里插入图片描述

看这个图,从趋势上来看,有两个拐弯的点,所以可以以这两个拐弯的点的y值作为界限,进行分组

相关分析

衡量连续值相关性的计算,用相关系数

import numpy as np
import pandas as pd
import scipy.stats as ss
import matplotlib.pyplot as plt
import seaborn as sns
import time

sns.set_style(style="whitegrid")
df = pd.read_csv('./HR_comma_sep.csv')
# 看各个字段之间的相关系数,越接近1越正相关,越接近-1越负相关,0就没关系
sns.heatmap(df.corr(), vmin=-1, vmax=1, cmap=sns.color_palette('RdBu', n_colors=128))
plt.show()

在这里插入图片描述
二类属性的相关性的计算,pearson相关系数进行计算
二类属性和连续值属性的相关性的计算,使用不纯度Gini系数
多类离散属性的相关系数,如果多类离散属性都是定序数据的话,比如像low,median,high就可以直接编码成0,1,2这些值,进行pearson相关系数的计算(有失真)

最为常用的:使用熵进行离散属性相关性的计算
在这里插入图片描述
熵:用来衡量不确定性的一个值,熵越接近0,不确定性越小,样本的类别越多,分布越均匀,信息熵就越大。

条件熵:在X条件下Y的熵,X分布下,对于Y分别计算熵然后进行求和

熵增益有一个比较大的缺点:对于分类数目多的特征有不正确的偏向,不具有归一化的特点,它的不确定性是上不封顶的,这样对于分类的界定和相关性的界定也是不方便的,为了解决这个问题,可以定义一个熵的增益率
在这里插入图片描述
熵的增益率:X到Y的熵的增益率,就是他们的互信息除以Y的熵,因为互信息一定是小于Y的,所以这个值就是小于1的,又因为熵本来就是大于0的,所以这个值是大于0的,所以就可以得到一个0到1的值,但直接用熵的增益率去衡量相关性是不妥的,因为熵的增益率是不对称的,也就是X对Y的熵的增益率和Y对X的熵的增益率是不一致的,所以要进行一下转化,即Corr这个相关性公式

代码实现

import numpy as np
import pandas as pd
import scipy.stats as ss
import matplotlib.pyplot as plt
import seaborn as sns
import time

sns.set_style(style="whitegrid")
df = pd.read_csv('./HR_comma_sep.csv')
s1 = pd.Series(["X1", "X1", "X2", "X2", "X2", "X2"])
s2 = pd.Series(["Y1", "Y1", "Y1", "Y2", "Y2", "Y2"])


# 求熵
def getEntropy(s):
    prt_ary = s.groupby(by=s).count().values / float(len(s))
    return -(np.log2(prt_ary) * prt_ary).sum()


print("Entropy", getEntropy(s2))


# 求条件熵
def getCondEntropy(a1, a2):
    assert (len(a1) == len(a2))
    # 一个字典
    d = dict()
    for i in list(range(len(a1))):
        d[a1[i]] = d.get(a1[i], []) + [a2[i]]
    return sum([getEntropy(d[k]) * len(d[k]) / float(len(a1)) for k in d])


print("CondEntropy", getCondEntropy(s2, s1))


# 求互信息(熵增益)
def getEntropyGain(s1, s2):
    return getEntropy(s2) - getCondEntropy(s1, s2)


print("EntropyGain", getEntropyGain(s2, s1))


# 求熵增益率
def getEntropyGainRatio(s1, s2):
    return getEntropyGain(s1, s2) / getEntropy(s2)


print("EntropyGainRatio", getEntropyGainRatio(s2, s1))
# 求相关性
import math


def getDiscreteCorr(s1, s2):
    return getEntropyGain(s1, s2) / math.sqrt(getEntropy(s1) * getEntropy(s2))


print("Discretecorr", getDiscreteCorr(s1, s2))

因子分析(成分分析)

从多个属性变量中分析共性相关因子的方法,分为探索性因子分析和验证性因子分析
探索性因子分析:指通过协方差矩阵、相关性矩阵等指标分析多元属性变量的本质结构,并可以进行转化、降维等操作,得到数据空间中或者影响目标最主要的因子(主成分分析法)
验证性因子分析:验证一个因子于我们关注的属性之间是否有关联、有什么样的关联、是否符合我们的预期等(相关分析、卡方检验、f值、熵等)

如得到一张对用户调查的数据表:
A.如果想要了解用户对产品的满意情况,①可以通过主成分分析,排除除了主成分意外的全部的因子,进行主成分降维,然后直接分析降维后的因子和满意情况。②不进行主成分的提取,直接看相关矩阵,看哪个属性和我们关注的属性有比较强的关系。
B.如果想看哪些具体属性和满意度的关系,就去验证他们的关系,得到相关性、一致性等指标,或者假设哪些因子和满意度有关系,用回归方法去拟合这几个属性和满意度之间的关联,根据误差大小来验证我们的假设。

绘制热力图检验进行主成分降维后属性之间相关性的可视化检验

import numpy as np
import pandas as pd
import scipy.stats as ss
import matplotlib.pyplot as plt
import seaborn as sns
import time

sns.set_style(style="whitegrid")
df = pd.read_csv('./HR_comma_sep.csv')
sns.heatmap(df.drop(labels=['salary', 'sales', 'left'], axis=1).corr(), vmin=-1, vmax=1,
            cmap=sns.color_palette('RdBu', n_colors=128))
plt.show()

from sklearn.decomposition import PCA

my_pca = PCA(n_components=7)
lower_mat = my_pca.fit_transform(df.drop(labels=['salary', 'sales', 'left'], axis=1))
print('Ratio:', my_pca.explained_variance_ratio_)
sns.heatmap(pd.DataFrame(lower_mat).corr(), vmin=-1, vmax=1, cmap=sns.color_palette('RdBu', n_colors=128))
plt.show()

主成分提取前:
在这里插入图片描述
主成分提取后:
在这里插入图片描述
可以明显的发现,主成分提取后,只有对角线上的相关系数为1,其他区域几乎为0就是不相关了。

总结各种方法的使用情况
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值