文章目录

  • 一.pandas与建模代码的结合
  • 二.使用patsy创建模型描述
    • 2.1Patsy公式中的数据转换
    • 2.2分类数据与Patsy
  • 三.statsmodels介绍
    • 3.1评估线性模型
    • 3.2评估时间序列处理
  • 其他关于数据处理的文章和pandas基础知识:
    • 1.python——pandas库之Series数据结构基础
    • 2.python——pandas库之DataFrame数据结构基础
    • 3.python之日期与时间处理模块及利用pandas处理时间序列数据
    • 4.利用python进行数据分析——使用groupby机制对pandas对象类的数据进行聚合与分组操作
    • 5.利用python进行数据分析——第11章时间序列
    • 6.数据分析——利用pandas库进行数据的清洗与处理

一.pandas与建模代码的结合

pandas与其它分析库通常是靠NumPy的数组联系起来的。将DataFrame转换为NumPy数组,可以使用.values属性:

import pandas as pd
import numpy as np
data = pd.DataFrame({'x0': [1, 2, 3, 4, 5],'x1': [0.01, -0.01, 0.25, -4.1, 0.],'y': [-1.5, 0., 3.6, 1.3, -2.]})
data
x0 x1 y
0 1 0.01 -1.5
1 2 -0.01 0.0
2 3 0.25 3.6
3 4 -4.10 1.3
4 5 0.00 -2.0
data.columns
Index(['x0', 'x1', 'y'], dtype='object')
data.values
array([[ 1.  ,  0.01, -1.5 ],[ 2.  , -0.01,  0.  ],[ 3.  ,  0.25,  3.6 ],[ 4.  , -4.1 ,  1.3 ],[ 5.  ,  0.  , -2.  ]])

要转换回DataFrame,可以传递一个二维ndarray,可带有列名:

df2 = pd.DataFrame(data.values, columns=['one', 'two', 'three'])
df2
one two three
0 1.0 0.01 -1.5
1 2.0 -0.01 0.0
2 3.0 0.25 3.6
3 4.0 -4.10 1.3
4 5.0 0.00 -2.0

一般当数据是同构化的时候使用.values属性。例如,全是数字类型。如果数据是异构化的,结果会是Python对象的ndarray:

df3 = data.copy()
df3['strings'] = ['a', 'b', 'c', 'd', 'e']
df3
x0 x1 y strings
0 1 0.01 -1.5 a
1 2 -0.01 0.0 b
2 3 0.25 3.6 c
3 4 -4.10 1.3 d
4 5 0.00 -2.0 e
df3.values
array([[1, 0.01, -1.5, 'a'],[2, -0.01, 0.0, 'b'],[3, 0.25, 3.6, 'c'],[4, -4.1, 1.3, 'd'],[5, 0.0, -2.0, 'e']], dtype=object)

对于一些模型,你可能只想使用列的子集。我建议你使用loc和values作索引:

model_cols = ['x0', 'x1']
data.loc[:, model_cols].values
array([[ 1.  ,  0.01],[ 2.  , -0.01],[ 3.  ,  0.25],[ 4.  , -4.1 ],[ 5.  ,  0.  ]])

一些库对pandas有本地化支持,会自动完成工作:从DataFrame转换到NumPy中并将模型的参数名添加到输出表的列或Series。其它情况,你可以手工进行“元数据管理”。

之前我们学习了pandas的Categorical类型和pandas.get_dummies函数。假设数据集中有一个非数值列:

data['category'] = pd.Categorical(['a', 'b', 'a', 'a', 'b'],categories=['a', 'b'])
data
x0 x1 y category
0 1 0.01 -1.5 a
1 2 -0.01 0.0 b
2 3 0.25 3.6 a
3 4 -4.10 1.3 a
4 5 0.00 -2.0 b

如果我们想替换category列为虚变量,我们可以创建虚变量,删除category列,然后添加到结果:

dummies = pd.get_dummies(data.category, prefix='category')
data_with_dummies = data.drop('category', axis=1).join(dummies)
data_with_dummies
x0 x1 y category_a category_b
0 1 0.01 -1.5 1 0
1 2 -0.01 0.0 0 1
2 3 0.25 3.6 1 0
3 4 -4.10 1.3 1 0
4 5 0.00 -2.0 0 1

用虚变量拟合某些统计模型会有一些细微差别。当你不只有数字列时,使用Patsy(下一节的主题)可能更简单,更不容易出错。

二.使用patsy创建模型描述

Patsy能够很好的支持statsmodels中特定的线性模型,因此我会关注于它的主要特点,让你尽快掌握。Patsy的公式是一个特殊的字符串语法,如下所示:

y ~ x0 + x1

a+b不是将a与b相加的意思,而是为模型创建的设计矩阵。patsy.dmatrices函数接收一个公式字符串和一个数据集(可以是DataFrame或数组的字典),为线性模型创建设计矩阵:

data = pd.DataFrame({'x0': [1, 2, 3, 4, 5],'x1': [0.01, -0.01, 0.25, -4.1, 0.],'y': [-1.5, 0., 3.6, 1.3, -2.]})
data
x0 x1 y
0 1 0.01 -1.5
1 2 -0.01 0.0
2 3 0.25 3.6
3 4 -4.10 1.3
4 5 0.00 -2.0
import patsy
y, X = patsy.dmatrices('y ~ x0 + x1', data)
y
DesignMatrix with shape (5, 1)y-1.50.03.61.3-2.0Terms:'y' (column 0)
X
DesignMatrix with shape (5, 3)Intercept  x0     x11   1   0.011   2  -0.011   3   0.251   4  -4.101   5   0.00Terms:'Intercept' (column 0)'x0' (column 1)'x1' (column 2)

这些Patsy的DesignMatrix实例是NumPy的ndarray,带有附加元数据:

np.asarray(y)
array([[-1.5],[ 0. ],[ 3.6],[ 1.3],[-2. ]])
np.asarray(X)
array([[ 1.  ,  1.  ,  0.01],[ 1.  ,  2.  , -0.01],[ 1.  ,  3.  ,  0.25],[ 1.  ,  4.  , -4.1 ],[ 1.  ,  5.  ,  0.  ]])

你可能想Intercept(截距)这个名词列是哪里来的。这是线性模型(比如普通最小二乘回归)的惯例用法。可以通过给模型添加名词列 +0来不显示截距:

patsy.dmatrices('y ~ x0 + x1 + 0', data)[1]
DesignMatrix with shape (5, 2)x0     x11   0.012  -0.013   0.254  -4.105   0.00Terms:'x0' (column 0)'x1' (column 1)

Patsy对象可以直接传递一些算法,比如numpy.linalg.lstsq等,这些算法都会执行一个最小二乘回归:

coef, resid, _, _ = np.linalg.lstsq(X, y)
C:\Users\Administrator\Anaconda3\lib\site-packages\ipykernel_launcher.py:1: FutureWarning: `rcond` parameter will change to the default of machine precision times ``max(M, N)`` where M and N are the input matrix dimensions.
To use the future default and silence this warning we advise to pass `rcond=None`, to keep using the old, explicitly pass `rcond=-1`."""Entry point for launching an IPython kernel.

模型的元数据保留在design_info属性中,因此你可以重新附加列名到拟合系数,以获得一个Series,例如:

coef
array([[ 0.31290976],[-0.07910564],[-0.26546384]])
coef = pd.Series(coef.squeeze(), index=X.design_info.column_names)
coef
Intercept    0.312910
x0          -0.079106
x1          -0.265464
dtype: float64

2.1Patsy公式中的数据转换

你可以将Python代码与patsy公式结合。在执行公式时,库将尝试查找在封闭作用域内使用的函数:

y, X = patsy.dmatrices('y ~ x0 + np.log(np.abs(x1) + 1)', data)
X
DesignMatrix with shape (5, 3)Intercept  x0  np.log(np.abs(x1) + 1)1   1                 0.009951   2                 0.009951   3                 0.223141   4                 1.629241   5                 0.00000Terms:'Intercept' (column 0)'x0' (column 1)'np.log(np.abs(x1) + 1)' (column 2)

常见的变量转换包括标准化(平均值为0,方差为1)和中心化(减去平均值)。Patsy有内置的函数进行这样的工作:

y, X = patsy.dmatrices('y ~ standardize(x0) + center(x1)', data)
X
DesignMatrix with shape (5, 3)Intercept  standardize(x0)  center(x1)1         -1.41421        0.781         -0.70711        0.761          0.00000        1.021          0.70711       -3.331          1.41421        0.77Terms:'Intercept' (column 0)'standardize(x0)' (column 1)'center(x1)' (column 2)

patsy.build_design_matrices函数可以使用原始样本数据集的保存信息,来转换新数据:

new_data = pd.DataFrame({'x0': [6, 7, 8, 9],'x1': [3.1, -0.5, 0, 2.3],'y': [1, 2, 3, 4]})
new_X = patsy.build_design_matrices([X.design_info], new_data)
new_X
[DesignMatrix with shape (4, 3)Intercept  standardize(x0)  center(x1)1          2.12132        3.871          2.82843        0.271          3.53553        0.771          4.24264        3.07Terms:'Intercept' (column 0)'standardize(x0)' (column 1)'center(x1)' (column 2)]

因为Patsy中的加号不是加法的意义,当你按照名称将数据集的列相加时,你必须用特殊I函数将它们封装起来:

y, X = patsy.dmatrices('y ~ I(x0 + x1)', data)
X
DesignMatrix with shape (5, 2)Intercept  I(x0 + x1)1        1.011        1.991        3.251       -0.101        5.00Terms:'Intercept' (column 0)'I(x0 + x1)' (column 1)

2.2分类数据与Patsy

非数值数据可以用多种方式转换为模型设计矩阵。完整的讲解超出了本书范围,最好和统计课一起学习。

当你在Patsy公式中使用非数值数据,它们会默认转换为虚变量。如果有截距,会去掉一个,避免共线性:

data = pd.DataFrame({'key1': ['a', 'a', 'b', 'b', 'a', 'b', 'a', 'b'],'key2': [0, 1, 0, 1, 0, 1, 0, 0],'v1': [1, 2, 3, 4, 5, 6, 7, 8],'v2': [-1, 0, 2.5, -0.5, 4.0, -1.2, 0.2, -1.7]})
y, X = patsy.dmatrices('v2 ~ key1', data)
X
DesignMatrix with shape (8, 2)Intercept  key1[T.b]1          01          01          11          11          01          11          01          1Terms:'Intercept' (column 0)'key1' (column 1)

如果你从模型中忽略截距,每个分类值的列都会包括在设计矩阵的模型中:

y, X = patsy.dmatrices('v2 ~ key1 + 0', data)
X
DesignMatrix with shape (8, 2)key1[a]  key1[b]1        01        00        10        11        00        11        00        1Terms:'key1' (columns 0:2)

数字类型列可以使用C函数解释为分类函数:

y, X = patsy.dmatrices('v2 ~ C(key2)', data)
X
DesignMatrix with shape (8, 2)Intercept  C(key2)[T.1]1             01             11             01             11             01             11             01             0Terms:'Intercept' (column 0)'C(key2)' (column 1)

当你在模型中使用多个分类名,事情就会变复杂,因为会包括key1:key2形式的相交部分,它可以用在方差(ANOVA)模型分析中:

data['key2'] = data['key2'].map({0: 'zero', 1: 'one'})
data
key1 key2 v1 v2
0 a zero 1 -1.0
1 a one 2 0.0
2 b zero 3 2.5
3 b one 4 -0.5
4 a zero 5 4.0
5 b one 6 -1.2
6 a zero 7 0.2
7 b zero 8 -1.7
y, X = patsy.dmatrices('v2 ~ key1 + key2', data)
X
DesignMatrix with shape (8, 3)Intercept  key1[T.b]  key2[T.zero]1          0             11          0             01          1             11          1             01          0             11          1             01          0             11          1             1Terms:'Intercept' (column 0)'key1' (column 1)'key2' (column 2)
y, X = patsy.dmatrices('v2 ~ key1 + key2 + key1:key2', data)
X
DesignMatrix with shape (8, 4)Intercept  key1[T.b]  key2[T.zero]  key1[T.b]:key2[T.zero]1          0             1                       01          0             0                       01          1             1                       11          1             0                       01          0             1                       01          1             0                       01          0             1                       01          1             1                       1Terms:'Intercept' (column 0)'key1' (column 1)'key2' (column 2)'key1:key2' (column 3)

三.statsmodels介绍

statsmodels是Python进行拟合多种统计模型、进行统计试验和数据探索可视化的库。Statsmodels包含许多经典的统计方法,但没有贝叶斯方法和机器学习模型。

3.1评估线性模型

statsmodels有多种线性回归模型,包括从基本(比如普通最小二乘)到复杂(比如迭代加权最小二乘法)的。

statsmodels的线性模型有两种不同的接口:基于数组和基于公式。它们可以通过API模块引入:

import statsmodels.api as sm
import statsmodels.formula.api as smf

为了展示它们的使用方法,我们从一些随机数据生成一个线性模型:

def dnorm(mean, variance, size=1):if isinstance(size, int):size = size,return mean + np.sqrt(variance) * np.random.randn(*size)
np.random.seed(12345)
N = 100
X = np.c_[dnorm(0, 0.4, size=N),dnorm(0, 0.6, size=N),dnorm(0, 0.2, size=N)]
eps = dnorm(0, 0.1, size=N)
beta = [0.1, 0.3, 0.5]y = np.dot(X, beta) + eps

这里,我使用了“真实”模型和可知参数beta。此时,dnorm可用来生成正态分布数据,带有特定均值和方差。现在有:

X[:5]
array([[-0.12946849, -1.21275292,  0.50422488],[ 0.30291036, -0.43574176, -0.25417986],[-0.32852189, -0.02530153,  0.13835097],[-0.35147471, -0.71960511, -0.25821463],[ 1.2432688 , -0.37379916, -0.52262905]])

像之前Patsy看到的,线性模型通常要拟合一个截距。sm.add_constant函数可以添加一个截距的列到现存的矩阵:

X_model = sm.add_constant(X)
X_model[:5]
array([[ 1.        , -0.12946849, -1.21275292,  0.50422488],[ 1.        ,  0.30291036, -0.43574176, -0.25417986],[ 1.        , -0.32852189, -0.02530153,  0.13835097],[ 1.        , -0.35147471, -0.71960511, -0.25821463],[ 1.        ,  1.2432688 , -0.37379916, -0.52262905]])

sm.OLS类可以拟合一个普通最小二乘回归:

model = sm.OLS(y, X)

这个模型的fit方法返回了一个回归结果对象,它包含估计的模型参数和其它内容:

results = model.fit()
results.params
array([0.17826108, 0.22303962, 0.50095093])

对结果使用summary方法可以打印模型的详细诊断结果:

print(results.summary())
                                 OLS Regression Results
=======================================================================================
Dep. Variable:                      y   R-squared (uncentered):                   0.430
Model:                            OLS   Adj. R-squared (uncentered):              0.413
Method:                 Least Squares   F-statistic:                              24.42
Date:                Sun, 14 Jun 2020   Prob (F-statistic):                    7.44e-12
Time:                        10:04:35   Log-Likelihood:                         -34.305
No. Observations:                 100   AIC:                                      74.61
Df Residuals:                      97   BIC:                                      82.42
Df Model:                           3
Covariance Type:            nonrobust
==============================================================================coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------
x1             0.1783      0.053      3.364      0.001       0.073       0.283
x2             0.2230      0.046      4.818      0.000       0.131       0.315
x3             0.5010      0.080      6.237      0.000       0.342       0.660
==============================================================================
Omnibus:                        4.662   Durbin-Watson:                   2.201
Prob(Omnibus):                  0.097   Jarque-Bera (JB):                4.098
Skew:                           0.481   Prob(JB):                        0.129
Kurtosis:                       3.243   Cond. No.                         1.74
==============================================================================Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.

这里的参数名为通用名x1, x2等等。假设所有的模型参数都在一个DataFrame中:

data = pd.DataFrame(X, columns=['col0', 'col1', 'col2'])
data['y'] = y
data[:5]
col0 col1 col2 y
0 -0.129468 -1.212753 0.504225 0.427863
1 0.302910 -0.435742 -0.254180 -0.673480
2 -0.328522 -0.025302 0.138351 -0.090878
3 -0.351475 -0.719605 -0.258215 -0.489494
4 1.243269 -0.373799 -0.522629 -0.128941

现在,我们使用statsmodels的公式API和Patsy的公式字符串:

results = smf.ols('y ~ col0 + col1 + col2', data=data).fit()
results.params
Intercept    0.033559
col0         0.176149
col1         0.224826
col2         0.514808
dtype: float64
results.tvalues
Intercept    0.952188
col0         3.319754
col1         4.850730
col2         6.303971
dtype: float64

观察下statsmodels是如何返回Series结果的,附带有DataFrame的列名。当使用公式和pandas对象时,我们不需要使用add_constant。

给出一个样本外数据,你可以根据估计的模型参数计算预测值:

results.predict(data[:5])
0   -0.002327
1   -0.141904
2    0.041226
3   -0.323070
4   -0.100535
dtype: float64

3.2评估时间序列处理

statsmodels的另一模型类是进行时间序列分析,包括自回归过程、卡尔曼滤波和其它态空间模型,和多元自回归模型。

用自回归结构和噪声来模拟一些时间序列数据:

init_x = 4import random
values = [init_x, init_x]
N = 1000b0 = 0.8
b1 = -0.4
noise = dnorm(0, 0.1, N)
for i in range(N):new_x = values[-1] * b0 + values[-2] * b1 + noise[i]values.append(new_x)

这个数据有AR(2)结构(两个延迟),参数是0.8和-0.4。拟合AR模型时,你可能不知道滞后项的个数,因此可以用更大的滞后数来拟合这个模型:

MAXLAGS = 5
model = sm.tsa.AR(values)
results = model.fit(MAXLAGS)

结果中的估计参数首先是截距,其次是前两个参数的估计值:

results.params
array([-0.00616093,  0.78446347, -0.40847891, -0.01364148,  0.01496872,0.01429462])

其他关于数据处理的文章和pandas基础知识:

1.python——pandas库之Series数据结构基础

2.python——pandas库之DataFrame数据结构基础

3.python之日期与时间处理模块及利用pandas处理时间序列数据

4.利用python进行数据分析——使用groupby机制对pandas对象类的数据进行聚合与分组操作

5.利用python进行数据分析——第11章时间序列

6.数据分析——利用pandas库进行数据的清洗与处理

利用python进行数据分析——第13章 python建模库介绍相关推荐

  1. python广义矩估计_《利用Python进行数据分析》13章(中二)建模库介绍

    前文传送门: 13.3 statsmodels介绍 statsmodels是Python进行拟合多种统计模型.进行统计试验和数据探索可视化的库.Statsmodels包含许多经典的统计方法,但没有贝叶 ...

  2. 《利用Python进行数据分析·第2版》第13章 Python建模库介绍

    第1章 准备工作 第2章 Python语法基础,IPython和Jupyter 第3章 Python的数据结构.函数和文件 第4章 NumPy基础:数组和矢量计算 第5章 pandas入门 第6章 数 ...

  3. 【利用Python进行数据分析】13 - Python建模库介绍

    第十三章 Python建模库介绍 1.pandas与模型代码的接口 2.用Patsy创建模型描述 2.1.Patsy创建模型设计矩阵 2.2.用Patsy公式进行数据转换 2.3.分类数据和Patsy ...

  4. python建立分析模型_《利用Python进行数据分析》13.2 使用Patsy创建模型描述

    第十三章 Python建模库介绍 13.2 使用Patsy创建模型描述 Patsy(https://patsy.readthedocs.io/)是一个用于描述统计模型(尤其是线性模型)的Python库 ...

  5. Python面试宝典(第二章 Python基础)

    Python面试宝典(第二章 Python基础) Python面试宝典(第二章 Python基础) 基础语法 输入输出 问题:代码中要修改不可变数据会出现什么问题? 抛出什么异常? 问题:a=1,b= ...

  6. Python数据分析学习系列 十三 Python建模库介绍

    Python数据分析学习系列 十三 Python建模库介绍 资料转自(GitHub地址):https://github.com/wesm/pydata-book 有需要的朋友可以自行去github下载 ...

  7. 第13章 Python建模库介绍--Python for Data Analysis 2nd

    本书中,我已经介绍了Python数据分析的编程基础.因为数据分析师和科学家总是在数据规整和准备上花费大量时间,这本书的重点在于掌握这些功能. 开发模型选用什么库取决于应用本身.许多统计问题可以用简单方 ...

  8. python快速编程入门第13章-Python快速编程入门,打牢基础必须知道的11个知识点...

    Python被誉为全世界高效的编程语言,同时也被称作是"胶水语言",那它为何能如此受欢迎,下面我们就来说说Python入门学习的必备11个知识点,也就是它为何能够如此受欢迎的原因. ...

  9. python爬虫数据分析可以做什么-python爬虫爬取的数据可以做什么

    在Python中连接到多播服务器问题,怎么解决你把redirect关闭就可以了.在send时,加上参数allow_redirects=False 通常每个浏览器都会设置redirect的次数.如果re ...

最新文章

  1. VMWare虚拟机与主机共享文件夹(如何安装VMWare tools)windows与windows共享
  2. Spring Boot 2.4.3、2.3.9 版本发布,你准备好了吗?
  3. 扬言要干掉 RESTful API 的 GraphQL 是什么鬼?
  4. 轻松理解正向代理与反向代理
  5. java enum判断_Java Enum枚举 遍历判断 四种方式(包括 Lambda 表达式过滤)
  6. Wdows server 2003 ipv6下IP和 IIS的 WEB/ FTP设置
  7. emlog独立会员中心模板源码 UserEmlog Ver:1.0
  8. VMware-workstation安装
  9. 刨根问底(二):从INode客户端看如何培养兴趣 (续)
  10. VMware Workstation 15 解锁Mac OS安装
  11. 活跃android手机,谁能升级2.3?Android手机活跃榜
  12. SpringBoot整合editormd富文本编辑器
  13. 江苏省等保测评机构项目测评收费价格标准参考
  14. 微信h5使用audio不会自动播放
  15. Low-poly低面建模(低像素多边形)
  16. 京东换新 Logo :脸蛋胖了,脖子粗了
  17. 【项目管理】项目成本管理
  18. 架构 Varnish+nginx+php(FastCGI)+MYSQL5+MenCache+MenC
  19. 区块链、货币和社交扩展性 1
  20. Symbian模拟器启动一会自动消失

热门文章

  1. [傅里叶变换及其应用学习笔记] 十. 卷积与中心极限定理
  2. JS判断日期是否在同一个星期内,和同一个月内
  3. Win32 的dll导入问题总结-------------
  4. 员工管理系统————员工删除模块
  5. js中几个对象的区别和用法
  6. Hibernate读书笔记---继承映射
  7. 一个项目了解 SpringBoot 集成 MyBatis
  8. 【jQuery笔记Part4】01-jQuery-节点操作-添加节点-删除节点-复制节点
  9. 软件测试学习指南(更新中)
  10. linux命令大全(持续更新)