这部分内容主要来自此教程
需要下列依赖:
- 基本学习心得包 (numpy, scipy, matplotlib)
- Pandas
- Statsmodels
数据展示和交互
下面例子用到此资源文件,请先下载。 我们使用pandas.DataFrame来存取操作数据,它是Python版的电子表格。
pandas是一个开源Python库,提供高效易用的数据结构和数据分析工具。
新建dataframe
从CSV文件读取
这个文件展示了性别和智商的关系,数据既有分类数据,也有数值数据。
此表中有些值没有,而是用”.”来占位,所以需要指定NA = not available是”.”。否则后面很难分析。
import pandas
data = pandas.read_csv('data/brain_size.csv', sep=';', na_values=".") # 因为此文件采用';',所以需要指明分隔符
data.head()
Unnamed: 0 | Gender | FSIQ | VIQ | PIQ | Weight | Height | MRI_Count | |
---|---|---|---|---|---|---|---|---|
0 | 1 | Female | 133 | 132 | 124 | 118.0 | 64.5 | 816932 |
1 | 2 | Male | 140 | 150 | 124 | NaN | 72.5 | 1001121 |
2 | 3 | Male | 139 | 123 | 150 | 143.0 | 73.3 | 1038437 |
3 | 4 | Male | 133 | 129 | 128 | 172.0 | 68.8 | 965353 |
4 | 5 | Female | 137 | 132 | 134 | 147.0 | 65.0 | 951545 |
从数组创建
我们可以把pandas.DataFrame看成是值为存储数组的字典
import numpy as np
x = np.linspace(-6, 6, num=100)
cos, sin = np.cos(x), np.sin(x)
frame = pandas.DataFrame({'x': x, 'cos': cos, 'sin': sin})
frame.head()
cos | sin | x | |
---|---|---|---|
0 | 0.960170 | 0.279415 | -6.000000 |
1 | 0.919340 | 0.393465 | -5.878788 |
2 | 0.865018 | 0.501740 | -5.757576 |
3 | 0.798003 | 0.602653 | -5.636364 |
4 | 0.719278 | 0.694722 | -5.515152 |
pandas.DataFrame也可以从其他格式的文件新建,具体查阅文档
操作数据
简单操作
data.shape
(40, 8)
data.columns
Index(['Unnamed: 0', 'Gender', 'FSIQ', 'VIQ', 'PIQ', 'Weight', 'Height',
'MRI_Count'],
dtype='object')
data['Gender'].head() # 像字典一样读取
0 Female
1 Male
2 Male
3 Male
4 Female
Name: Gender, dtype: object
data[data['Gender']=='Female']['VIQ'].mean() # 简单的select,计算性别为女的数据的*VIQ*值得期望
109.45
groupby
以分类数据的值分割dataframe
groupby_gender = data.groupby('Gender')
for gender, value in groupby_gender['VIQ']:
print((gender, value.mean()))
('Female', 109.45)
('Male', 115.25)
groupby_gender.mean()
Unnamed: 0 | FSIQ | VIQ | PIQ | Weight | Height | MRI_Count | |
---|---|---|---|---|---|---|---|
Gender | |||||||
Female | 19.65 | 111.9 | 109.45 | 110.45 | 137.200000 | 65.765000 | 862654.6 |
Male | 21.35 | 115.0 | 115.25 | 111.60 | 166.444444 | 71.431579 | 954855.4 |
绘制数据
关于各种术语和图形,详情请见统计术语及图形展示
绘制箱线图
import matplotlib.pyplot as plt
# Box plots of different columns for each gender
groupby_gender = data.groupby('Gender')
groupby_gender.boxplot(column=['FSIQ', 'VIQ', 'PIQ'])
plt.show()
绘制散点图
使用Pandas的plotting工具,其实其背后也是matplotlib在工作,所以最后画图需要plt.show()
from pandas.tools import plotting
# Scatter matrices for different columns
plotting.scatter_matrix(data[['Weight', 'Height', 'MRI_Count']])
plotting.scatter_matrix(data[['PIQ', 'VIQ', 'FSIQ']])
plt.show()
假设检验
t检验
单样本检验
scipy.stats.ttest_1samp()
是t检验的单样本检验,检验样本是否符合零假设。这里就是样本假设期望值和给定值没有显著不同。
from scipy import stats
stats.ttest_1samp(data['VIQ'], 0) # t test of one sample test
stats.ttest_ind
Ttest_1sampResult(statistic=30.088099970849328, pvalue=1.3289196468728067e-28)
上面计算结果发现p值为1.3e-28,远远小于0.05,说明零假设(样本假设期望值和给定值没有显著不同)不成立,假设期望值和给定值具有显著不同
双样本检验
stats.ttest_ind
是t检验的双样本检验,检验样本是否符合零假设。这里就是假设两个独立样本没有显著不同。
female_viq = data[data['Gender'] == 'Female']['VIQ']
male_viq = data[data['Gender'] == 'Male']['VIQ']
stats.ttest_ind(female_viq, male_viq)
Ttest_indResult(statistic=-0.77261617232750113, pvalue=0.44452876778583217)
上面计算结果发现p值为0.44,远远大于0.05,说明零假设(样本假设期望值和给定值没有显著不同)成立。
配对检验
双样本检验中,我们假设检验两个独立样本。如果两个样本不是独立的,那么我们应该使用配对检验(paired test)或叫做重复检验(repeated measures test)。
比如有一个计算机培训,在培训前后分别对每个人做了一个考试,通过对比前后的考试成绩,可以判断培训有无作用。那么我们可以做配对检验,即判断成绩是否有显著不同。可以看出,其实这就是测试两次成绩的差值是否为0。
这里,我们可以计算IQ的三种不同测量方法:PIQ, VIQ, 和FSIQ。我们检验一下FISQ和PIQ是否显著不同,由于我们比较的是相同人在若干次重复检验的问题,所以应该使用配对检验:
stats.ttest_rel(data['FSIQ'], data['PIQ'])
Ttest_relResult(statistic=1.7842019405859857, pvalue=0.082172638183642358)
根据前文描述,上面的配对检验其实相等于:
stats.ttest_1samp(data['FSIQ'] - data['PIQ'], 0)
Ttest_1sampResult(statistic=1.7842019405859857, pvalue=0.082172638183642358)
线性模型
简单线性回归
假设两个观察组,x和y。我们假设y是x的线性函数,下面我们检验这个模型:
其中e是噪声。我们使用statsmodels模块:
- 使用最小二乘法(ordinary least squares,OLS)拟合线性模型。
- 测试coef不为0。
import numpy as np
from statsmodels.formula.api import ols
x = np.linspace(-5, 5, 20)
np.random.seed(1)
# normal distributed noise
y = -5 + 3*x + 4 * np.random.normal(size=x.shape)
# Create a data frame containing all the relevant variables
data = pandas.DataFrame({'x': x, 'y': y})
model = ols("y ~ x", data).fit()
print(model.summary())
OLS Regression Results
==============================================================================
Dep. Variable: y R-squared: 0.804
Model: OLS Adj. R-squared: 0.794
Method: Least Squares F-statistic: 74.03
Date: Sun, 30 Apr 2017 Prob (F-statistic): 8.56e-08
Time: 20:00:29 Log-Likelihood: -57.988
No. Observations: 20 AIC: 120.0
Df Residuals: 18 BIC: 122.0
Df Model: 1
Covariance Type: nonrobust
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
Intercept -5.5335 1.036 -5.342 0.000 -7.710 -3.357
x 2.9369 0.341 8.604 0.000 2.220 3.654
==============================================================================
Omnibus: 0.100 Durbin-Watson: 2.956
Prob(Omnibus): 0.951 Jarque-Bera (JB): 0.322
Skew: -0.058 Prob(JB): 0.851
Kurtosis: 2.390 Cond. No. 3.03
==============================================================================
Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
根据数据结果可见,拟合的结果是intercept为-5.53,coef是2.94。
类似的,我们可以看看性别和智商的关系:
VIQ = data['VIQ']
Gender = data['Gender']
model = ols("VIQ ~ Gender", data).fit()
print(model.summary())
OLS Regression Results
==============================================================================
Dep. Variable: VIQ R-squared: 0.015
Model: OLS Adj. R-squared: -0.010
Method: Least Squares F-statistic: 0.5969
Date: Sun, 30 Apr 2017 Prob (F-statistic): 0.445
Time: 20:15:35 Log-Likelihood: -182.42
No. Observations: 40 AIC: 368.8
Df Residuals: 38 BIC: 372.2
Df Model: 1
Covariance Type: nonrobust
==================================================================================
coef std err t P>|t| [0.025 0.975]
----------------------------------------------------------------------------------
Intercept 109.4500 5.308 20.619 0.000 98.704 120.196
Gender[T.Male] 5.8000 7.507 0.773 0.445 -9.397 20.997
==============================================================================
Omnibus: 26.188 Durbin-Watson: 1.709
Prob(Omnibus): 0.000 Jarque-Bera (JB): 3.703
Skew: 0.010 Prob(JB): 0.157
Kurtosis: 1.510 Cond. No. 2.62
==============================================================================
Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
由上面拟合结果可见,智商和性别没有关系。因为R-squared很小。
多元线性回归
看一看文档吧,我写到机器学习的时候在仔细说这方便的东西。