多因子探索分析与可视化
一、假设检验与方差检验
import numpy as np
import scipy.stats as ss
1.正态检验
H0:服从正态分布
H1:不服从
norm_dist=ss.norm.rvs(size=20) #符合标准正态分布的20个数
ss.normaltest(norm_dist) #检验是否为正态分布,p>0.05,不能拒绝原假设,符合正态分布,基于偏度和峰度的一种检验法
2.卡方检验
H0:观测与期望无显著差别
H1:有差别
ss.chi2_contingency([[15,95],[85,5]]) #得到检验统计量,p值<0.05,有差别,自由度,理论分布
3.独立T分布检验
H0:两者无显著差别
H1:有显著差别
ss.ttest_ind(ss.norm.rvs(size=100),ss.norm.rvs(size=200))#p值>0.05,则没有差异
4.方差检验
H0:多个样本总体均值相等
H1:多个样本总体均值不完全相等
ss.f_oneway([49,50,39,40,43],[38,32,30,26,34],[38,40,45,42,48])
5.qq图
from statsmodels.graphics.api import qqplot
from matplotlib import pyplot as plt
plt.show(qqplot(ss.norm.rvs(size=100))) #检验是否为正态分布,基本位于角平分线上
二、相关系数
import pandas as pd
s1=pd.Series([0.1,0.2,1.1,2.4,1.3,0.3,0.5])
s2=pd.Series([0.5,0.4,1.2,2.5,1.1,0.7,0.1])
s1.corr(s2) #pearson 相关系数
s1.corr(s2,method='spearman')
df=pd.DataFrame([s1,s2]) #DataFrame
df.corr() #针对列进行相关计算
df1=pd.DataFrame(np.array([s1,s2]).T) #进行转置后再计算
三、回归
x=np.arange(10).astype(np.float).reshape((10,1))
y=x*3+4+np.random.random((10,1))
from sklearn.linear_model import LinearRegression
reg=LinearRegression()
res=reg.fit(x,y)#拟合过程
y_pred=reg.predict(x) #预测值
reg.coef_ #查看参数
reg.intercept_ #查看截距
四、主成分分析
data=np.array([np.array([2.5,0.5,2.2,1.9,3.1]),np.array([2.4,0.7,2.9,2.2,3])]).T
from sklearn.decomposition import PCA
lower_dim=PCA(n_components=1) #降的维度
lower_dim.fit(data)
lower_dim.explained_variance_ratio_ #降维后的重要性,即得到的信息量
lower_dim.fit_transform(data) #得到转换后的数值
自定义常规PCA方法
import pandas as pd
import numpy as np
def myPCA(data,n_components=10000000):
mean_vals=np.mean(data,axis=0)#针对列求均值
mid=data-mean_vals
cov_mat=np.cov(mid,rowvar=False) #求协方差,
from scipy import linalg
eig_vals,eig_vects=linalg.eig(np.mat(cov_mat))#求协方差矩阵的特征值和特征向量
#求最大的特征值所对应的特征向量
eig_val_index=np.argsort(eig_vals)#特征值排序,得到索引
eig_val_index=eig_val_index[:-(n_components+1):-1]#最大的
eig_vects=eig_vects[:,eig_val_index]#特征向量
lower_dim_mat=np.dot(mid,eig_vects)
return lower_dim_mat,eig_vals
print(myPCA(data,n_components=1))
交叉分析
import pandas as pd
import numpy as np
import scipy.stats as ss
import matplotlib.pyplot as plt
import seaborn as sns
df=pd.read_csv('HR.csv')#读入文件
df=df.dropna(axis=0,how='any')
df=df[df['last_evaluation']<=1][df['salary']!='nme'][df['department']!='sale'] #去除异常值
查看各个部门的left离职率之间的关系是否有明显差异 独立T检验方法,
得到各个部门之间的离职分布,两两之间求出T检验统计量和p值
dp_indices=df.groupby(by='department').indices #得到分组后的索引
sales_values=df['left'].iloc[dp_indices['sales']].values
technical_values=df['left'].iloc[dp_indices['technical']].values
print(ss.ttest_ind(sales_values,technical_values))
#两两求p值
dp_keys=list(dp_indices.keys())
dp_t_mat=np.zeros([len(dp_keys),len(dp_keys)]) #初始化一个矩阵
for i in range(len(dp_keys)):
for j in range(len(dp_keys)):
p_values=ss.ttest_ind(df['left'].iloc[dp_indices[dp_keys[i]]].values,
df['left'].iloc[dp_indices[dp_keys[j]]].values)[1]
dp_t_mat[i][j]=p_values
sns.heatmap(dp_t_mat,xticklabels=dp_keys,yticklabels=dp_keys)
plt.show()
#两两求p值加判断条件使图像差异更明显
dp_keys=list(dp_indices.keys())
dp_t_mat=np.zeros([len(dp_keys),len(dp_keys)]) #初始化一个矩阵
for i in range(len(dp_keys)):
for j in range(len(dp_keys)):
p_values=ss.ttest_ind(df['left'].iloc[dp_indices[dp_keys[i]]].values,
df['left'].iloc[dp_indices[dp_keys[j]]].values)[1]
if p_values<0.05:
dp_t_mat[i][j]=-1
else:
dp_t_mat[i][j]=p_values
sns.heatmap(dp_t_mat,xticklabels=dp_keys,yticklabels=dp_keys)
plt.show()
#透视表进行交叉分析
piv_tb=pd.pivot_table(df,values='left',index=['promotion_last_5years','salary'],
columns=['Work_accident'],aggfunc=np.mean)#创建透视表,聚合参数选的函数
sns.set_context(font_scale=1.5)#调整字体
sns.heatmap(piv_tb,vmin=0,vmax=1,
cmap=sns.color_palette('Reds',n_colors=256))
plt.show()
分组分析
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
sns.set_context(font_scale=1.5)
df=pd.read_csv('HR.csv')
df=df.dropna(axis=0,how='any')
df=df[df['last_evaluation']<=1][df['salary']!='nme'][df['department']!='sale'] #去除异常值
#绘制柱状图来看分组情况
sns.barplot(x='salary',y='left',hue='department',data=df)
plt.show()
sl_s=df['satisfaction_level']#连续值分析
sns.barplot(list(range(len(sl_s))),sl_s.sort_values())
plt.show()
相关分析
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
导入数据去除异常值
sns.set_context(font_scale=1.5)
df=pd.read_csv('HR.csv')
df=df.dropna(axis=0,how='any')
df=df[df['last_evaluation']<=1][df['salary']!='nme'][df['department']!='sale'] #去除异常值
sns.heatmap(df.corr(),vmin=-1,vmax=1,cmap=sns.color_palette('RdBu',n_colors=128))
plt.show() #计算相关系数时,会自动去掉离散数值
离散属性的相关性
s1=pd.Series(['X1','X1','X2','X2','X2','X2'])
s2=pd.Series(['Y1','Y1','Y1','Y2','Y2','Y2'])
1.熵 无锡人流医院 http://www.0510bhyy.com/
def getEntropy(s):
#判断是否为Series格式
if not isinstance(s,pd.core.series.Series):
s=pd.Series(s)
prt_ary=pd.groupby(s,by=s).count().values/float(len(s)) #得到概率分布
return -(np.log2(prt_ary)*prt_ary).sum()
注:pd.groupby(s,by=s).count() 得到计数 X1:2, X2: 4
pd.groupby(s,by=s).count().values 得到值 array([2, 4], dtype=int64)
print('Entropy:',getEntropy(s1))
2.条件熵
def getCondEntropy(s1,s2):
d=dict()
for i in list(range(len(s1))): #list 将其转换为列表形式
d[s1[i]]=d.get(s1[i],[])+[s2[i]]#结构体,s1值下s2的分布
return sum([getEntropy(d[k])*len(d[k])/float(len(s1))for k in d])
print('ConEntropy:',getCondEntropy(s2,s1))
3.熵增益,条件熵
def getEntropyGain(s1,s2):
return getEntropy(s2)-getCondEntropy(s1,s2)
print('EntropyGain:',getEntropyGain(s1,s2))
4.增益率
def getEntropyGainRation(s1,s2):
return getEntropyGain(s1,s2)/getEntropy(s2)
print('EntropyGainRation:',getEntropyGainRation(s1,s2))
5.离散值的相关性
import math
def getDiscreteCorr(s1,s2):
return getEntropyGain(s1,s2)/math.sqrt(getEntropy(s1)*getEntropy(s2))
print('DiscreteCorr:',getDiscreteCorr(s1,s2))
6.Gini系数
def getProSS(s):
if not isinstance(s,pd.core.series.Series):
s=pd.Series(s)
prt_ary=pd.groupby(s,by=s).count().values/float(len(s))
return sum(prt_ary**2)
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([getProSS(d[k]*len(d[k]))/float(len(s1))for k in d])
print('Gini:',getGini(s1,s2))
因子分析
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
sns.set_context(font_scale=1.5)
df=pd.read_csv('HR.csv')
df=df.dropna(axis=0,how='any')
df=df[df['last_evaluation']<=1][df['salary']!='nme'][df['department']!='sale'] #去除异常值
from sklearn.decomposition import PCA #主成分分析
my_pca=PCA(n_components=7) #去除离散值和要分析的值后剩七个
lower_mat=my_pca.fit_transform(df.drop(labels=['salary','department','left'],axis=1))#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.连续—连续:相关系数,假设检验
2.连续—离散(二值):相关系数,连续二值化(最小Gini切分,最大熵增益切分)
3.连续—离散(非二值):相关系数(定序)
4.离散(二值)—离散(二值):相关系数,熵相关,F分值
5.离散—离散(非二值):熵相关,Gini,相关系数(定序)