Python 数据分析(PYDA)第三版(六)(1)

简介: Python 数据分析(PYDA)第三版(六)

十二、Python 建模库介绍

原文:wesmckinney.com/book/modeling

译者:飞龙

协议:CC BY-NC-SA 4.0

此开放访问网络版本的《Python 数据分析第三版》现已作为印刷版和数字版的伴侣提供。如果您发现任何勘误,请在此处报告。请注意,由 Quarto 生成的本站点的某些方面与 O’Reilly 的印刷版和电子书版本的格式不同。

如果您发现本书的在线版本有用,请考虑订购纸质版无 DRM 的电子书以支持作者。本网站的内容不得复制或再生产。代码示例采用 MIT 许可,可在 GitHub 或 Gitee 上找到。

在本书中,我专注于为在 Python 中进行数据分析提供编程基础。由于数据分析师和科学家经常报告花费大量时间进行数据整理和准备,因此本书的结构反映了掌握这些技术的重要性。

您用于开发模型的库将取决于应用程序。许多统计问题可以通过简单的技术解决,如普通最小二乘回归,而其他问题可能需要更高级的机器学习方法。幸运的是,Python 已经成为实现分析方法的首选语言之一,因此在完成本书后,您可以探索许多工具。

在本章中,我将回顾一些 pandas 的特性,这些特性在您在 pandas 中进行数据整理和模型拟合和评分之间来回切换时可能会有所帮助。然后,我将简要介绍两个流行的建模工具包,statsmodelsscikit-learn。由于这两个项目都足够庞大,值得有自己的专门书籍,因此我没有尝试全面介绍,而是建议您查阅这两个项目的在线文档,以及一些其他基于 Python 的数据科学、统计学和机器学习书籍。

12.1 pandas 与模型代码之间的接口

模型开发的常见工作流程是使用 pandas 进行数据加载和清理,然后切换到建模库来构建模型本身。模型开发过程中的一个重要部分被称为特征工程,在机器学习中。这可以描述从原始数据集中提取信息的任何数据转换或分析,这些信息在建模环境中可能有用。我们在本书中探讨的数据聚合和 GroupBy 工具经常在特征工程环境中使用。

虽然“好”的特征工程的细节超出了本书的范围,但我将展示一些方法,使在 pandas 中进行数据操作和建模之间的切换尽可能轻松。

pandas 与其他分析库之间的接触点通常是 NumPy 数组。要将 DataFrame 转换为 NumPy 数组,请使用to_numpy方法:

In [12]: 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.]})
In [13]: data
Out[13]: 
 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
In [14]: data.columns
Out[14]: Index(['x0', 'x1', 'y'], dtype='object')
In [15]: data.to_numpy()
Out[15]: 
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,其中包含可选的列名:

In [16]: df2 = pd.DataFrame(data.to_numpy(), columns=['one', 'two', 'three'])
In [17]: df2
Out[17]: 
 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

to_numpy方法旨在在数据是同质的情况下使用,例如所有的数值类型。如果您有异构数据,结果将是一个 Python 对象的 ndarray:

In [18]: df3 = data.copy()
In [19]: df3['strings'] = ['a', 'b', 'c', 'd', 'e']
In [20]: df3
Out[20]: 
 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
In [21]: df3.to_numpy()
Out[21]: 
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索引和to_numpy

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

一些库原生支持 pandas,并自动完成一些工作:从 DataFrame 转换为 NumPy,并将模型参数名称附加到输出表或 Series 的列上。在其他情况下,您将不得不手动执行这种“元数据管理”。

在 Ch 7.5:分类数据中,我们看过 pandas 的Categorical类型和pandas.get_dummies函数。假设我们的示例数据集中有一个非数字列:

In [24]: data['category'] = pd.Categorical(['a', 'b', 'a', 'a', 'b'],
 ....:                                   categories=['a', 'b'])
In [25]: data
Out[25]: 
 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'列,然后将结果连接:

In [26]: dummies = pd.get_dummies(data.category, prefix='category',
 ....:                          dtype=float)
In [27]: data_with_dummies = data.drop('category', axis=1).join(dummies)
In [28]: data_with_dummies
Out[28]: 
 x0    x1    y  category_a  category_b
0   1  0.01 -1.5         1.0         0.0
1   2 -0.01  0.0         0.0         1.0
2   3  0.25  3.6         1.0         0.0
3   4 -4.10  1.3         1.0         0.0
4   5  0.00 -2.0         0.0         1.0

使用虚拟变量拟合某些统计模型时存在一些微妙之处。当您拥有不仅仅是简单数字列时,使用 Patsy(下一节的主题)可能更简单且更不容易出错。

12.2 使用 Patsy 创建模型描述

Patsy是一个用于描述统计模型(尤其是线性模型)的 Python 库,它使用基于字符串的“公式语法”,受到 R 和 S 统计编程语言使用的公式语法的启发(但并非完全相同)。在安装 statsmodels 时会自动安装它:

conda install statsmodels

Patsy 在为 statsmodels 指定线性模型方面得到很好的支持,因此我将重点介绍一些主要功能,以帮助您快速上手。Patsy 的公式是一种特殊的字符串语法,看起来像:

y ~ x0 + x1

语法a + b并不意味着将a加到b,而是这些是为模型创建的设计矩阵中的patsy.dmatrices函数接受一个公式字符串以及一个数据集(可以是 DataFrame 或数组字典),并为线性模型生成设计矩阵:

In [29]: 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.]})
In [30]: data
Out[30]: 
 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
In [31]: import patsy
In [32]: y, X = patsy.dmatrices('y ~ x0 + x1', data)

现在我们有:

In [33]: y
Out[33]: 
DesignMatrix with shape (5, 1)
 y
 -1.5
 0.0
 3.6
 1.3
 -2.0
 Terms:
 'y' (column 0)
In [34]: X
Out[34]: 
DesignMatrix with shape (5, 3)
 Intercept  x0     x1
 1   1   0.01
 1   2  -0.01
 1   3   0.25
 1   4  -4.10
 1   5   0.00
 Terms:
 'Intercept' (column 0)
 'x0' (column 1)
 'x1' (column 2)

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

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

您可能会想知道Intercept项是从哪里来的。这是线性模型(如普通最小二乘回归)的一个约定。您可以通过在模型中添加+ 0项来抑制截距:

In [37]: patsy.dmatrices('y ~ x0 + x1 + 0', data)[1]
Out[37]: 
DesignMatrix with shape (5, 2)
 x0     x1
 1   0.01
 2  -0.01
 3   0.25
 4  -4.10
 5   0.00
 Terms:
 'x0' (column 0)
 'x1' (column 1)

Patsy 对象可以直接传递到像numpy.linalg.lstsq这样的算法中,该算法执行普通最小二乘回归:

In [38]: coef, resid, _, _ = np.linalg.lstsq(X, y, rcond=None)
• 1

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

In [39]: coef
Out[39]: 
array([[ 0.3129],
 [-0.0791],
 [-0.2655]])
In [40]: coef = pd.Series(coef.squeeze(), index=X.design_info.column_names)
In [41]: coef
Out[41]: 
Intercept    0.312910
x0          -0.079106
x1          -0.265464
dtype: float64

Patsy 公式中的数据转换

您可以将 Python 代码混合到您的 Patsy 公式中;在评估公式时,库将尝试在封闭范围中找到您使用的函数:

In [42]: y, X = patsy.dmatrices('y ~ x0 + np.log(np.abs(x1) + 1)', data)
In [43]: X
Out[43]: 
DesignMatrix with shape (5, 3)
 Intercept  x0  np.log(np.abs(x1) + 1)
 1   1                 0.00995
 1   2                 0.00995
 1   3                 0.22314
 1   4                 1.62924
 1   5                 0.00000
 Terms:
 'Intercept' (column 0)
 'x0' (column 1)
 'np.log(np.abs(x1) + 1)' (column 2)

一些常用的变量转换包括标准化(均值为 0,方差为 1)和中心化(减去均值)。Patsy 具有内置函数用于此目的:

In [44]: y, X = patsy.dmatrices('y ~ standardize(x0) + center(x1)', data)
In [45]: X
Out[45]: 
DesignMatrix with shape (5, 3)
 Intercept  standardize(x0)  center(x1)
 1         -1.41421        0.78
 1         -0.70711        0.76
 1          0.00000        1.02
 1          0.70711       -3.33
 1          1.41421        0.77
 Terms:
 'Intercept' (column 0)
 'standardize(x0)' (column 1)

作为建模过程的一部分,您可以在一个数据集上拟合模型,然后基于另一个数据集评估模型。这可能是一个保留部分或稍后观察到的新数据。当应用诸如中心化和标准化之类的转换时,您在使用模型基于新数据形成预测时应当小心。这些被称为有状态转换,因为在转换新数据时必须使用原始数据集的统计数据,如均值或标准差。

patsy.build_design_matrices函数可以使用原始样本内数据的保存信息对新的样本外数据应用转换:

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

因为 Patsy 公式中加号(+)并不表示加法,所以当您想按名称从数据集中添加列时,您必须将它们包装在特殊的I函数中:

In [49]: y, X = patsy.dmatrices('y ~ I(x0 + x1)', data)
In [50]: X
Out[50]: 
DesignMatrix with shape (5, 2)
 Intercept  I(x0 + x1)
 1        1.01
 1        1.99
 1        3.25
 1       -0.10
 1        5.00
 Terms:
 'Intercept' (column 0)
 'I(x0 + x1)' (column 1)

Patsy 在patsy.builtins模块中还有几个内置转换。请查看在线文档以获取更多信息。

分类数据有一类特殊的转换,接下来我会解释。

分类数据和 Patsy

非数字数据可以以多种不同的方式转换为模型设计矩阵。本书不涉及这个主题的完整处理,最好是在统计课程中学习。

当您在 Patsy 公式中使用非数字术语时,默认情况下它们会被转换为虚拟变量。如果有一个截距,将会有一个级别被排除以避免共线性:

In [51]: 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]
 ....: })
In [52]: y, X = patsy.dmatrices('v2 ~ key1', data)
In [53]: X
Out[53]: 
DesignMatrix with shape (8, 2)
 Intercept  key1[T.b]
 1          0
 1          0
 1          1
 1          1
 1          0
 1          1
 1          0
 1          1
 Terms:
 'Intercept' (column 0)
 'key1' (column 1)

如果从模型中省略截距,那么每个类别值的列将包含在模型设计矩阵中:

In [54]: y, X = patsy.dmatrices('v2 ~ key1 + 0', data)
In [55]: X
Out[55]: 
DesignMatrix with shape (8, 2)
 key1[a]  key1[b]
 1        0
 1        0
 0        1
 0        1
 1        0
 0        1
 1        0
 0        1
 Terms:
 'key1' (columns 0:2)

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

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

当您在模型中使用多个分类项时,情况可能会更加复杂,因为您可以包括形式为key1:key2的交互项,例如在方差分析(ANOVA)模型中使用:

In [58]: data['key2'] = data['key2'].map({0: 'zero', 1: 'one'})
In [59]: data
Out[59]: 
 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
In [60]: y, X = patsy.dmatrices('v2 ~ key1 + key2', data)
In [61]: X
Out[61]: 
DesignMatrix with shape (8, 3)
 Intercept  key1[T.b]  key2[T.zero]
 1          0             1
 1          0             0
 1          1             1
 1          1             0
 1          0             1
 1          1             0
 1          0             1
 1          1             1
 Terms:
 'Intercept' (column 0)
 'key1' (column 1)
 'key2' (column 2)
In [62]: y, X = patsy.dmatrices('v2 ~ key1 + key2 + key1:key2', data)
In [63]: X
Out[63]: 
DesignMatrix with shape (8, 4)
 Intercept  key1[T.b]  key2[T.zero]  key1[T.b]:key2[T.zero]
 1          0             1                       0
 1          0             0                       0
 1          1             1                       1
 1          1             0                       0
 1          0             1                       0
 1          1             0                       0
 1          0             1                       0
 1          1             1                       1
 Terms:
 'Intercept' (column 0)
 'key1' (column 1)
 'key2' (column 2)
 'key1:key2' (column 3)

Patsy 提供了其他转换分类数据的方法,包括具有特定顺序的项的转换。有关更多信息,请参阅在线文档。


Python 数据分析(PYDA)第三版(六)(2)https://developer.aliyun.com/article/1482397

相关文章
|
4天前
|
数据挖掘 计算机视觉 Python
Python数据分析13
Pillow 是 PIL(Python Imaging Library)的升级版本,适应 Python 3 的更新而诞生,带来了诸多新特性。它采用模块化结构,主要包括:图像功能模块(Image)、图像滤波功能模块(ImageFilter)、图像增强功能模块(ImageEnhance)和图像绘画功能模块(ImageDraw)。Pillow 支持从多种图像格式读取数据,进行处理,并能输出为常见格式,其官网提供了丰富的应用示例供学习参考。
16 4
|
1天前
|
SQL 数据采集 数据可视化
深入 Python 数据分析:高级技术与实战应用
本文系统地介绍了Python在高级数据分析中的应用,涵盖数据读取、预处理、探索及可视化等关键环节,并详细展示了聚类分析、PCA、时间序列分析等高级技术。通过实际案例,帮助读者掌握解决复杂问题的方法,提升数据分析技能。使用pandas、matplotlib、seaborn及sklearn等库,提供了丰富的代码示例,便于实践操作。
103 64
|
2天前
|
机器学习/深度学习 数据可视化 数据挖掘
使用Python进行数据分析的入门指南
【9月更文挑战第33天】本文旨在为初学者提供一个关于使用Python进行数据分析的全面概述。我们将从基本的安装和设置开始,逐步介绍数据处理、数据可视化以及机器学习的基本概念和应用。文章将通过实际代码示例来展示如何使用Python及其相关库来解决常见的数据分析问题。
|
5天前
|
数据挖掘 Serverless 计算机视觉
Python数据分析 11
SciPy是一款专为数学、科学及工程应用设计的开源软件,它基于NumPy的n维数组构建,提供了丰富的数值例程,包括积分、优化、线性代数等,适用于各种操作系统,安装简易且免费。它还包含了如快速傅里叶变换、信号处理、图像处理、特殊函数计算等功能,满足了科学计算与工程需求。相较于NumPy的一般数组,SciPy提供了真正的矩阵及其相关运算支持。
24 7
|
5天前
|
机器学习/深度学习 数据挖掘 算法框架/工具
Python数据分析6
Keras是一个用Python编写的深度学习框架,支持TensorFlow等多种后端,以其高度模块化、用户友好性和易扩展性著称。它不仅适用于搭建普通神经网络,还能够构建自编码器、循环神经网络、卷积神经网络等多种模型,并且可以无缝切换CPU和GPU。相比Theano,Keras极大简化了神经网络模型的搭建过程,使普通用户也能轻松创建复杂的深度学习模型,仅需几十行代码即可完成。需要注意的是,Keras的预测函数采用`model.predict()`输出概率,`model.predict_classes()`输出分类结果。
16 6
|
5天前
|
自然语言处理 搜索推荐 数据挖掘
Python 数据分析10
除了常用的Python数据挖掘建模库外,还有许多其他库也非常实用,例如 jieba、SciPy、OpenCV 和 Pillow 等。其中,jieba 是一个广泛使用的中文分词库,支持多种编程语言,包括 Python、R 和 C++,并且提供了三种分词模式:精确模式、全模式和搜索引擎模式。此外,jieba 还具备词性标注、添加自定义词典及关键词提取等功能,在 GitHub 社区中有较高讨论度,并拥有丰富的实例资源。
18 5
|
5天前
|
机器学习/深度学习 数据挖掘 PyTorch
Python数据分析7
PyTorch是由Facebook(现Meta)人工智能研究院于2017年开源的Python机器学习库,基于Torch构建,支持GPU加速和动态神经网络,适用于自然语言处理等领域。其灵活的API和简洁的语法使得构建和调试深度学习模型变得简单快捷,成为深度学习领域的热门工具之一。社区支持广泛,拥有丰富的应用领域库。
12 3
|
4天前
|
算法 数据挖掘 计算机视觉
Python数据分析12
OpenCV是由英特尔公司资助的开源计算机视觉库,集成了丰富的图像处理与计算机视觉算法,拥有超过500个函数,支持多种编程语言与操作系统。该库采用模块化设计,主要包括核心功能、图像处理、2D特征及GUI四个模块,广泛应用于产品检测、医学成像等多个领域。
11 1
|
5天前
|
机器学习/深度学习 并行计算 数据挖掘
Python数据分析8
飞桨(PaddlePaddle)是百度于2016年开源的一款学习框架,它以易用性、高效性、灵活性及可扩展性为特点,提供了涵盖核心深度学习框架、模型库、开发套件等在内的全面功能,并且支持大规模模型训练与多平台部署。此外,它不断优化性能,增强对各类硬件的支持,已在制造业、农业等多个领域广泛应用。
12 2
|
5天前
|
机器学习/深度学习 数据挖掘 TensorFlow
Python数据分析5
虽然scikit-learn功能强大,但对于人工神经网络这一重要模型却支持不足。人工神经网络在自然语言处理和图像识别等领域有着广泛应用,而深度学习作为其延伸,已成为研究热点。因此,在Python中实现神经网络变得尤为重要。目前主流的深度学习框架有TensorFlow、Keras、PyTorch、PaddlePaddle和Caffe等。其中,TensorFlow由Google于2015年推出,基于先前的深度学习基础框架DistBelief构建,因其高度灵活、可移植以及自动计算梯度导数等特点,迅速成为最受欢迎的深度学习框架之一,支持多种编程语言接口,如C++、Python、Java等。
14 2
下一篇
无影云桌面