[Python] 6.利用Python进行数据分析-多因子探索性数据分析与复合分析

I.理论部分

1)假设检验与方差检验
    1.假设检验:根据一定假设条件由样本推断总体的一种方法
    包括了:
        t检验:判断两个平均数的差异是否显著
        F检验:判断该模型中的全部或一部分参数是否适合用来估计母体
        卡方检验:实际观测值与理论推断值之间的偏离程度,检验两个因素建有没有联系
    思路:
        i.建立原假设(包含等号)及备择假设
        ii.选择检验统计量(根据数据的性质构造的转换函数,使其符合一个已知的格式)
        iii.根据显著性水平(接受假设的最大失真限度,显著性水平+相似度=1,一般α=0.05),确定拒绝域
        iiii.计算p值或样本统计值,做出判断(p:原假设发生概率,p<a,则拒绝原假设)
    2.方差检验:判断两组以上的样本均值是否有显著性差异
    
2)相关系数:
    1.皮尔逊相关系数:度量两个变量x和y之间的线性相关相关程度
    2.斯皮尔曼相关系数:
    # 连续数据,正态分布,线性关系,用pearson相关系数是最恰当
    # 上述任一条件不满足,就用spearman相关系数,不能用pearson相关系数。
    # 两个定序测量数据之间也用spearman相关系数,不能用pearson相关系数。

3)回归:确定两种最小或两种以上的变量间相互依赖的定量关系的一种统计分析方法
    1.线性回归效果判定:
        决定系数(R方)
        残差不相关(DW检验,0-4,dw=2不相关)

4)主成分分析与奇异值分解
    目的:降维,排除多余维度


II.编码实现
>>> import numpy as np
>>> import pandas as pd
>>> import scipy as s
>>> import scipy.stats as ss

# 正态分布检验
>>> no_dist=ss.norm.rvs(size=20)
>>> ss.normaltest(norm_dist)
ormaltestResult(statistic=5.201298329912753, pvalue=0.07422537805679173)
p>0.05,在95%置信水平下不能拒绝原假设。即no_dist为正态分布

# 卡方分布检验
>>> ss.chi2_contingency([[15,95],[85,5]])
(126.08080808080808, 2.9521414005078985e-29, 1, array([[55., 55.],[45., 45.]]))
p<0.05,在95%置信水平下拒绝原假设。即两者无联系。

# 独立t分布检验
>>> ss.ttest_ind(ss.norm.rvs(size=10),ss.norm.rvs(size=50))
Ttest_indResult(statistic=0.5510272590185644, pvalue=0.5837314692988744)
p>0.05,在95%置信水平下不能拒绝原假设。即两组值的均值无差异

# 方差检验
>>> ss.f_oneway([49,50,39,40,43],[28,32,30,26,34],[38,40,45,42,48])
F_onewayResult(statistic=17.619417475728156, pvalue=0.0002687153079821641)
p<0.05,在95%置信水平下拒绝原假设。即三组值有差异

# 相关系数
>>> 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)
0.9333729600465924
>>> s1.corr(s2,method="spearman")
0.9333729600465924

# 回归
# 指定x为0-9的浮点数,reshape的作用:将每个元素当成一个数组
>>> x=np.arange(10).astype(np.float).reshape((10,1))
# 指定y为x*3+4+噪声
>>> 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)
# 查看参数,截距
# y=x * reg.coef_ + reg.intercept_
>>> reg.coef_
array([[3.02095104]])
>>> reg.intercept_
array([4.49672037])

# PCA变换,sklearn用的是奇异值分解的方法
>>> data=np.array([np.array([2.5,0.5,2.2,1.9,3.1,2.3,2,1,1.5,1.5]),
                   np.array([2.4,0.7,2.9,2.2,3,2.7,1.6,1.1,1.6,0.9])]).T
# 使用sklearn的降维方法
>>> from sklearn.decomposition import PCA
# 指定降到一维
>>> low_dim=PCA(n_components=1)
# 拟合的过程
>>> low_dim.fit(data)
# 查看维度重要性
>>> low_dim.explained_variance_ratio_
array([0.94733855])
# 查看转换后的数值,为了排版把它放在两行,实际上是一列
>>> low_dim.fit_transform(data)
array([[-0.79719813],[ 1.80013324],[-0.97456799],[-0.25079417],[-1.64398332],
       [-0.89041293],[ 0.13374212],[ 1.16957423],[ 0.4639199 ],[ 0.98958705]]).T

# 传统的PCA变换如下
import pandas as pd
import numpy as np
def my_PCA(data,n_components=10000): # 默认维度很高,即不选择的话全选
    mean_valus=np.mean(data,axis=0)  # 计算均值,axis=0,以列来计算
    mid=data-mean_valus              # 计算mid
    cov_mat=np.cov(mid,rowvar=False) # 计算mid的协方差,rowvar=Flase指定列进行协方差的计算
    from scipy import linalg         # 引入scipy的包,用作协方差矩阵计算的用途
    eig_values,eig_vects=linalg.eig(np.mat(cov_mat))
    eig_values_index=np.argsort(eig_values)  #对特征值排序并得到其索引,即下标
    eig_values_index=eig_values_index[:-(n_components+1):-1]  # 取出最大的值对应的特征值
    eig_vects=eig_vects[:,eig_values_index]  # 取出对应的特征向量
    low_dim_mat=np.dot(mid,eig_vects)
    return  low_dim_mat,eig_values

data=np.array([np.array([2.5,0.5,2.2,1.9,3.1,2.3,2,1,1.5,1.5]),
               np.array([2.4,0.7,2.9,2.2,3,2.7,1.6,1.1,1.6,0.9])]).T
print(my_PCA(data,n_components=1))
# 传统的PCA变换如下:
import pandas as pd
import numpy as np
def my_PCA(data,n_components=10000): # 默认维度很高,即不选择的话全选
    mean_valus=np.mean(data,axis=0)  # 计算均值,axis=0,以列来计算
    mid=data-mean_valus              # 计算mid
    cov_mat=np.cov(mid,rowvar=False) # 计算mid的协方差,rowvar=Flase指定列进行协方差的计算
    from scipy import linalg         # 引入scipy的包,用作协方差矩阵计算的用途
    eig_values,eig_vects=linalg.eig(np.mat(cov_mat))
    eig_values_index=np.argsort(eig_values)  #对特征值排序并得到其索引,即下标
    eig_values_index=eig_values_index[:-(n_components+1):-1]  # 取出最大的值对应的特征值
    eig_vects=eig_vects[:,eig_values_index]  # 取出对应的特征向量
    low_dim_mat=np.dot(mid,eig_vects)
    return  low_dim_mat,eig_values

data=np.array([np.array([2.5,0.5,2.2,1.9,3.1,2.3,2,1,1.5,1.5]),
               np.array([2.4,0.7,2.9,2.2,3,2.7,1.6,1.1,1.6,0.9])]).T
print(my_PCA(data,n_components=1))
III.六大分析的编码实现

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(r"C:\Users\Administrator\sample_code\data\HR.csv")
df = df.dropna(axis=0,how='any')
df = df[df["last_evaluation"]<=1][df["salary"]!="nme"][df["department"]!="sale"]

目的:研究离职率(left)这一项,想要看看各部门(department)之间的离职率是否有差异
思路:采用独立t检验。首先得到各个部门的离职分布,两两间求t检验统计量,并求出P值

# 根据部门(department)分组,通过indices得到分组后的索引,赋值为dp_indices
dp_indices = df.groupby(by="department").indices
# 1.取出sales,technical的离职率left
# iloc基于索引位来选取数据集,0:4就是选取 0,1,2,3这四行,需要注意的是这里是前闭后开集合
sales_values = df["left"].iloc[dp_indices["sales"]].values
technical_values = df["left"].iloc[dp_indices["technical"]].values
# 打印两者的t统计量
print(ss.ttest_ind(sales_values,technical_values)) 
# >>> statistic=-1.06 pvalue=0.2891,p>0.05,表名两者无差异  
# 2.两两间求t检验统计量
# 取出indices的key,这里的话就是各个indice的名称,对应部门名,赋值为dp_keys,pyhton3这里要list一下转化为数组
dp_keys=list(dp_indices.keys())
# 初始化一个矩阵,长宽都是dp_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值为i,j对应的t检验统计量,因为ss.ttest_ind会生成两个值,一个统计量,一个p值,这里只要p值,所以加一个下标
        p_value=ss.ttest_ind(df["left"].iloc[dp_indices[dp_keys[i]]].values,df["left"].iloc[dp_indices[dp_keys[j]]].values)[1]
        # 为了让一会儿的作图更明显一些,对于过小的值进行边缘化处理
        if p_value<0.05:
            dp_t_mat[i][j] = -1
        else:
            dp_t_mat[i][j] = p_value
        # 对矩阵进行赋值
        dp_t_mat[i][j]=p_value
# 作图
sns.heatmap(dp_t_mat,xticklabels=dp_keys,yticklabels=dp_keys)

# 或者可以做一个透视表,利用Pandas中的pivot_table(数据源,观测值values,横坐标index,纵坐标columns,聚合方法aggfunc)
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=1024))

# 显示图表
plt.show()



2.分组分析:
1)将数据分组后进行分析,结合其他分析方法,一种辅助手段(分组与钻取)
2)将数据进行切分,组间差异性,组内同质性,对新数据进行组的划分(聚类)
钻取是改变维的层次,变换分析的力度。
连续数据在钻取之前要看一下数据分布,找分隔或者拐点,借此对数据进行离散化处理
或者可以通过衡量不纯度的指标(Gini系数)对其进行分组

# 调用库
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(r"C:\Users\Administrator\sample_code\data\HR.csv")
df = df.dropna(axis=0,how='any')
df = df[df["last_evaluation"]<=1][df["salary"]!="nme"][df["department"]!="sale"]

# 离散值的分组,向下钻取到部门(department)
sns.barplot(data=df,x="salary",y="left",hue="department")
# 显示图表
plt.show()

# 连续值的分组
sl_s=df["satisfaction_level"]
sns.barplot(range(len(sl_s)),sl_s.sort_values)
# 显示图表
plt.show()

猜你喜欢

转载自blog.csdn.net/Edward_is_1ncredible/article/details/81701622