本文是以完成一份数据分析报告而进行的,选择的方式可能不止一种,配合之前的理论部分

导入需要的包

import pandas as pd
import os
%matplotlib inline
# 修改当前文件路径
os.chdir('C:/Users/cyb/ipnb/haha/chapter2/data/')
数据整体的浏览
# 小区名字、增长率
house_price_gr = pd.read_csv('house_price_gr.csv', encoding='gbk')
house_price_gr.head()
house_price_gr.count()
dis_name 150
rate 150
dtype: int64
house_price_gr.describe()
描述性图表
import seaborn as sns
from scipy import stats
sns.distplot(house_price_gr.rate, kde=True, fit=stats.norm)
# 黑线是核密度曲线,正态分布, 对比蓝线和黑线,来确定是不是类似正态分布

import matplotlib.pyplot as plt
import statsmodels.api as sm
fig = sm.qqplot(house_price_gr.rate, fit=True, line='45')
fig.show()
# 线就表示样本整体正态分布时候的样子
house_price_gr.plot(kind='box')

置信区间

se = house_price_gr.rate.std() / len(house_price_gr) ** 0.5
LB = house_price_gr.rate.mean() - 1.98 * se # 约等于两个标准差,95% 实际上对应的就是 1.98 标准差
UB = house_price_gr.rate.mean() + 1.98 * se
(LB, UB)
(0.1033788285317501, 0.11674316487209627)

做描述性统计时报告候可以这么说:

抽取了150个小区的增长率数据,有95%的把握增长率在(0.1033788285317501, 0.11674316487209627)之间;

增长率小于0.1033788285317501的可能性不超过2.5%

# 如果要求任意置信度下的置信区间的话,可以自己编一个函数
def confint(x, alpha=0.05):
n = len(x)
xb = x.mean()
df = n-1
tmp = (x.std() / n ** 0.5) * stats.t.ppf(1-alpha/2, df)
# 根据 alpha 和 自由度,找到对应的 t 值,求出从均值到两边的距离
return {'Mean': xb, 'Degree of Freedom':df, 'LB':xb-tmp, 'UB':xb+tmp}
confint(house_price_gr.rate, 0.05)
{'Mean': 0.11006099670192318,
'Degree of Freedom': 149,
'LB': 0.10339228338892811,
'UB': 0.11672971001491825}
假设检验与单样本T检验
d1 = sm.stats.DescrStatsW(house_price_gr.rate)
print('t_statistic=%6.4f, p_value=%6.4f, df=%s' % d1.ttest_mean(0.1)) # 0.1 指的是假设的均值
# t值 指的是两个均值之间相差几个标准差,p 值 与显著性水平alpha比较
# t统计量越大,说明在正态分布图中 越靠边缘, 对应假设的均值与样本的均值,也就差的更远
# df 指的是自由度,共150行,自由度就减1
t_statistic=2.9812, p_value=0.0034, df=149.0

这里p值 0.34% ,150个样本一般取 alpha 为 5%,所以p值小于alpha(相当于更靠边缘),拒绝原假设

汇报描述方式:

根据150个样本得到的北京市的增长率均值是 11% ,根据样本增长率小于 10% 的概率是 0.17%,如果不采取措施,年底不被问责的概率是 0.17%

如果P<0.01,说明是较强的判定结果,拒绝假定的参数取值。 如果0.010.05,说明结果更倾向于接受假定的参数取值。

两样本检验

导入数据

数据说明:本数据是一份汽车贷款数据

creditcard = pd.read_csv('creditcard_exp.csv', skipinitialspace=True)
creditcard['Income'].groupby(creditcard['Acc']).describe()
Suc0 = creditcard[creditcard['Acc'] == 0]['Income']
Suc1 = creditcard[creditcard['Acc'] == 1]['Income']
leveneTestRes = stats.levene(Suc0, Suc1, center='median')
# 这里根据样本数首先将 alpha 定位5%,所以得到的 p 值是显著的,所以标准差不相等
print('w-value=%6.4f, p-value=%6.4f' % leveneTestRes)
# 这部分其实最后我们会使用方差分析来做,这里只是举例说明两样本 t 检验怎么做的
结果:w-value=7.1829, p-value=0.0086
stats.stats.ttest_ind(Suc0, Suc1, equal_var=False)# 标准差不相等
结果:Ttest_indResult(statistic=-9.529516968736448, pvalue=1.3263066753296544e-15)
stats.stats.ttest_ind(Suc0, Suc1)# 标准差是否相等其实也不需要关心,对结果影响无关紧要,都是拒绝原假设,两个变量相关
结果:Ttest_indResult(statistic=-7.2734332066230225, pvalue=8.690094133636066e-11)
测试一下性别对月均消费的作用
creditcard['avg_exp'].groupby(creditcard['gender']).describe()
female = creditcard[creditcard['gender'] == 0]['avg_exp'].dropna()
male = creditcard[creditcard['gender'] == 1]['avg_exp'].dropna()
lenveneTestRes = stats.levene(female, male, center='median')
print('w_value=%6.4f, p-value=%6.4f' %lenveneTestRes)# 假设两个分组的标准差相等,假设成立
w_value=0.0683, p-value=0.7946
stats.stats.ttest_ind(female, male, equal_var=True)
# p值大于0.05,两个变量不相关
结果:Ttest_indResult(statistic=-1.742901386808629, pvalue=0.08587122878448449)
F 检验 —多分类
pd.set_option('display.max_columns', None) # 设置显示所有列
creditcard.groupby('edu_class')[['avg_exp']].describe().T
from statsmodels.formula.api import ols
# anova 方差分析analysis of validation
sm.stats.anova_lm(ols('avg_exp ~ C(edu_class)', data=creditcard).fit())# C(edu_class) 表示将变量作为分类变量
字段名自由度SSMMSEFP值组间自由度组间变异组间变异/自由度FP值组内自由度组内变异组内变异/自由度nannan
P 值很小(mean_sq = sum_sq / df , F 是 mean_sq 两个数的商)
# 不考虑交互相
sm.stats.anova_lm(ols('avg_exp ~ C(edu_class)+C(gender)',data=creditcard).fit())
# 考虑交互相
sm.stats.anova_lm(ols('avg_exp ~ C(edu_class)+C(gender)+C(edu_class)*C(gender)',data=creditcard).fit())
# 考虑交互相,这里 gender 与 y 没有关系了
相关分析
creditcard.plot(x='Income', y='avg_exp', kind='scatter')
# 从左往右,渐渐发散,说明数据是左偏的,因此取对数,经验方法

creditcard.plot(x='Income', y='avg_exp_ln', kind='scatter')

creditcard[['Income', 'avg_exp_ln']].corr(method='pearson')# 如果使用speraman,method 更换就好