[学习笔记]Python for Data Analysis, 3E-12.Python建模库简介

news/2024/3/29 16:26:26/文章来源:https://blog.csdn.net/zhangyifeng_1995/article/details/128091162

在本书中,重点聚焦于提供在Python中进行数据分析的编程基础。由于数据分析时和科学家经常报告在数据整理和准备上话费不成比例的时间,因此本书的结构反应了掌握这些技术的重要性。
用于开发模型的库将取决于应用程序。许多统计问题可以通过更简单的技术来解决,如普通最小二乘回归,而其他问题可能需要更先进的机器学习方法。幸运的是,Python已经成为实现分析方法的首选语言之一,因此在完成本书之后,你可以探索许多工具。
在本章中,我们将回顾pandas的一些功能,当你在与pandas的数据整理、模型拟合和评分之间来回切换时候,这些功能可能会有所帮助。我将简要介绍两大流行的建模工具包,statsmodels和scikit-learn。

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

模型开发的常见工作流程是使用pandas进行数据加载和清理,然后再切换到建模库来构建模型本身。模型开发过程的一个重要部分称为机器学习中的特征工程。这可以描述从原始数据集中提取在建模上下文中可能有用的信息的任何数据转换和分析。我们在本书中探讨的数据聚合和GroupBy工具经常在特征工程环境中使用。
虽然’好’的特征工程的细节超出了本书的范围,但我将展示一些方法,是pandas的数据操作和建模之间的切换尽可能轻松。
pandas和其他分析库之间的接触点通常是NumPy数组。若要将DataFrame转换为NumPy数组,请使用to_numpy方法:

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.to_numpy() # 将DataFrame转化为NumPy数组(二维数组)
# 要转换回DataFrame,可以使用可选的列名传递二维数组
df2 = pd.DataFrame(data.to_numpy(), columns=['one', 'two', 'three'])# to_numpy方法适用于数据是同构(例如,全是数值类型)的情况。
# 如果有异构数据,结果将是object组成的的ndarray
df3 = data.copy()
df3['strings'] = ['a', 'b', 'c', 'd', 'e']
df3.to_numpy()# 对于某些模型,你可能希望仅使用列的子集。此时推荐将loc索引和to_numpy结合
model_cols = ['x0', 'x1']
data.loc[:, model_cols].to_numpy() # 先筛选列,再转化为数组

某些库具有对pandas的原生支持,并自动为你执行其中的一些工作:从DataFrame转换为NumPy,并将模型参数名称附加到输出表或者Series的列。在其他情况下,你必须手动执行此’元数据管理’。

在’章节7.5:分类数据’中,我们研究了pandas的Categorical类型和pandas.get_dummies函数。

# 假设我们的示例数据集中有一个非数字列
data['category'] = pd.Categorical(['a', 'b', 'a', 'a', 'b'], categories=['a', 'b'])# 如果我们想用虚拟变量替换列,则我们创建虚拟变量,删除'category'列,然后连接结果:
dummies = pd.get_dummies(data.category, prefix='category') # 生成含'category_a'和'category_b'列的DataFrame
date_with_dummies = data.drop('category', axis=1).join(dummies) # 在列中删除'category'列,并拼接dummies

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

12.2使用Patsy创建模型描述

Patsy是一个Python库,用于使用基于字符串的’公式语法’描述统计模型(尤其是线性模型),该语法的灵感来自R和S统计编程语言使用的公式语法(但不完全相同)。当你安装stasmodels时候,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.]})
import patsy
y, X = patsy.dmatrices('y ~ x0 + x1', data) # y为DesignMatrix with shape(5, 1),项为'y',X为DesignMatrix with shape(5, 3),项为'截距,x0, x1'# 这些Patsy DesignMatrix实例是具有附加元数据的NumPy数组:
np.asarray(y) # 转化为NumPy数组(元数据被去掉)
np.asarray(X)

你也许想知道Intercept项是从哪里来的。这是线性模型,如普通最小二乘(OLS)回归的约定。你可以通过向模型添加’+0’项来取消截距:

patsy.dmatrices('y ~ x0 + x1 + 0', data)[1]# Patsy对象可以直接传递到类似numpy.linalg.lstsq的算法中,该算法执行普通最小二乘回归
coef, resid, _, _ = np.linalg.lstsq(X, y) # 得到系数等结果# 模型的元数据保留在design_info属性中,因此你可以将模型列名称重新附加到拟合系数以获取Series,例如
coef = pd.Series(coef.squeeze(), index=X.design_info.column_names) # 构建索引为'Intercept', 'x0'和'x1'的Series

Patsy公式中的数据转换

你可以将Python代码混合到Patsy公式中;当计算公式时,库将尝试在封闭作用于中找到你使用的函数:

y, X = patsy.dmatrices('y ~ x0 + np.log(np.abs(x1) + 1)', data) # 设计矩阵'X'中的项为'x0'和'np.log(np.abs(x1)+1'

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

y, X = patsy.dmatrices('y ~ standardize(x0) + center(x1)', data)

作为建模过程的一部分,你可以在一个数据集上拟合模型,然后基于另一个数据集评估模型。这可能是原数据的保留部分或者稍后观察到的新数据。应用中心化和标准化等转换时,使用模型基于新数据形成预测时应小心。这些成为有状态转换,因为在转换新数据集时必须使用原始数据集的平均值或标准差等统计信息。
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]}) # 创建新的DataFrame
new_X = patsy.build_design_matrices([X.design_info], new_data) # 将原始样本的转换应用到新的数据中,得到DesignMatrix对象

由于Patsy公式上下文的加号(+)并不意味着加法,因此当你要按照名称添加数据集中的列时,必须将它们包装在特定的I(大写的i)函数中:

y, X = patsy.dmtrices('y ~ I(x0 + x1)', data) # I(x0 + x1)是一个完整的项

Patsy在patsy.builtins模块中还有其他几个内置转换。有关详细信息可以参阅在线文档。
分类数据具有一类特殊的转换,将在下面介绍。

分类数据和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) # 因为存在截距(没有+0,默认存在),所以这里省略了'a'对应的水平key1[T.a],只有key1[T.b]# 如果从模型中省略截距,则每个类别值的列将包含在模型设计矩阵中
y, X = patsy.dmatrices('v2 ~ key1 + 0', data) # 由于没有截距,所以存在水平key1[a]和key1[b]# 数值列可以使用C函数解释为分类变量
y, X = patsy.dmatrices('v2 ~ C(key2)', data) # 包含截距项和数值1对应的水平C(key2)[T.1]

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

data['key2'] = data['key2'].map({0: 'zero', 1: 'one'}) # 将数值型变量转化为非数值型变量(分类变量)
y, X = patsy.dmatrices('v2 ~ key1 + key2', data) # DesignMatrix X中含三个项:Intercept,key1[T.b], key2[T.zero]
y, X = patsy.dmatrices('v2 ~ key1 + key2 + key1:key2', data) # DesignMatrix X中含四个项:截距,key1[T.b], key2[T.zero], key1[T.b]:key2[T.zero]

12.3统计模型简介

statsmodels是一个用于拟合各种统计模型,执行统计测试以及数据探索和可视化的Python库。statsmodels包含更多’经典’频率统计方法,而贝叶斯方法和机器学习模型可以在别的库找到。

在statsmodels找到的一些模型包括:

  • 线性模型,生成线性模型和鲁棒线性模型
  • 线性混合效应模型
  • 方差分析方法(ANOVA)
  • 时序过程和状态空间模型
  • 广义矩方法

在接下来的页面中,我们将使用一些statsmodels中的基础工具并探索如何通过Patsy公式和DataFrame使用模型接口。

估计线性模型

在statsmodels中有一些线性回归模型,从比较基础(如,普通最小平方)到更复杂(如,重复再加权最小平方法)。statsmodels的线性模型有两个不同的接口:基于数组和基于公式。它们通过这些API模块导入访问:

import statsmodel.api as sm
import statsmodel.formula.api as smf

为了展示如何使用这些,我们从一些随机数据生成一个线性模型。在Jupyter单元中运行以下代码:

rng = np.random.default_rng(seed=12345)def dnorm(mean, variance, size=1):if isinstance(size, int):size = size, # 将size转化为元组return mean + np.sqrt(variance) * rng.standard_normal(*size) # 返回均值和方差给定的正态分布的抽样数据N = 100
X = np.c_[dnorm(0, 0.4, size=N),dnorm(0, 0.6, size=N),dnorm(0, 0.2, size=N)] # np.c_是按列拼接,np.r_是按行拼接,这里返回100*3的数组
eps = dnorm(0, 0.1, size=N)
beta = [0.1, 0.3, 0.5]y = np.dot(X, beta) + eps # 构造数据

这里,'真实’模型的参数为beta。在本例中,dnorm是一个辅助函数,用于生成具有特定均值和方差的正态分布数据。
线性模型通常用截距项来拟合,就像我们之前看到的Patsy一样。sm.add_constant函数可以在现有矩阵中添加一个截距列:

X_model = sm.add_constant(X) # 在X的第0列添加截距列(全为1的列)# sm.OLS类可以拟合一个普通的最小二乘线性回归
model = sm.OLS(y, X)# 模型的fit方法返回回归结果对象,它包含估计模型的参数和其他诊断
results = model.fit()
results.params # 返回参数组成的数组# results上的summary方法可以打印模型的细节诊断输出
print(results.summary())

这里的参数名被赋予了通用名称x1、x2等等。

# 假设所有的模型参数都在一个数据帧中
data = pd.DataFrame(X, columns=['col0', 'col1', 'col2'])
data['y'] = y # 构造包含所有数据的DataFrame# 现在我们使用statsmodels公式接口和Patsy公式字符串:
results = smf.ols('y ~ col0 + col1 + col2', data=data)
results.params  # 返回各参数值
results.tvalues # 返回各参数的t-value

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

# 给定新的样本外数据,可以根据估计的模型参数计算预测值:
results.predict(data[:5])

在statsmodels中还有许多用于分析、诊断和可视化线性模型结果的其他工具,您可以探索这些工具。除了普通的最小二乘,还有其他类型的线性模型。

估计时间序列过程

statsmodels中的另一类模型用于时间序列分析。其中包括自回归过程、卡尔曼滤波等状态空间模型以及多元自回归模型。
让我们用自回归结构和噪声来模拟一些时间序列数据。

init_x = 4
values = [init_x, init_x]
N = 1000
b0 = 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模型时,你可能不知道要包含的滞后项的数量,所以你可以用一些更大的滞后数来拟合模型:

from statsmodels.tsa.ar_model import AutoReg
MAXLAGS = 5
model = AutoReg(values, MAXLAGS)
results = model.fit()

结果中的估计参数先有截距,然后是前两个滞后的估计:

results.params

关于这些模型的更深入的细节以及如何解释它们的结果超出了我在本书中所能介绍的范围,但是在statmodels文档中还有更多可以发现的内容。

12.4scikit-learn介绍

scikit-learn是使用最广泛、最值得信任的通用Python机器学习工具包之一。它包含了各种标准监督和无监督机器学习方法,以及用于模型选择和评估、数据转换、数据加载和模型持久性的工具。这些模型可以用于分类、聚类、预测和其他常见任务。
关于机器学习,以及如何应用scikit-learn这样的库来解决现实世界的问题,有很好的在线和印刷资源。在本节中,我将简要介绍一下scikit-learn API格式。
近年来,在scikit-learn中,pandas的集成已经有了显著的提高,当你读到这篇文章的时候,它可能已经提高了更多。我鼓励您查看最新的项目文档。作为本章的一个例子,我使用了一个来自Kaggle竞赛的关于1912年泰坦尼克号乘客存活率的经典数据集。

# 使用pandas加载训练和测试数据集:
train = pd.read_csv('datasets/titanic/train.csv')
test = pd.read_csv('datasets/titanic/test.csv')

像statmodels和scikit-learn这样的库通常不能被提供缺失的数据,所以我们查看列,看看是否有包含缺失数据的列:

train.isna().sum()
test.isna().sum()

在像这样的统计和机器学习例子中,一个典型的任务是根据数据中的特征预测乘客是否会幸存。模型在训练数据集上拟合,然后在样本外测试数据集上进行评估。
我想使用’Age’作为一个预测器,但它有缺失的数据。有很多方法可以进行缺失数据填充,但我将使用一个简单的方法,使用训练数据集的中位数来填补两个表中的空值:

impute_value = train['Age'].mmedian()
train['Age'] = train['Age'].fillna(impute_value)
test['Age'] = test['Age'].fillna(impute_value)

现在我们需要指定我们的模型。我添加了一个’IsFemale’列作为“Sex”列的编码版本:

train['Isfemale'] = (train['Sex'] == 'female').astype(int)
test['Isfemale'] = (train['Sex'] == 'female').astype(int)

然后我们决定一些模型变量并创建NumPy数组:

predictors = ['Pclass', 'IsFemale', 'Age'] # 用于预测的变量
X_train = train[predictors].to_numpy() # 训练集
X_test = test[predictors].to_numpy()   # 测试集
y_train = train['Survived'].to_numpy()

我不会说这是一个好模型或这些特征设计得很好。我们使用scikit-learn中的LogisticRegression模型并创建一个模型实例:

from sklearn.linear_model import LogisticRegression
model = LogisticRegression() # 创建LogisticRegression模型实例# 我们可以使用模型的fit方法将该模型与训练数据拟合:
model.fit(X_train, y_train) # 返回LogisticRegression()对象# 现在,我们可以使用model.predict对测试数据集进行预测:
y_predict = model.predict(X_test)# 如果你有测试数据集的真实值,你可以计算一个准确率百分比或其他误差度量:
(y_true == y_predict).mean()

在实践中,在模型训练中通常有许多额外的复杂性层。许多模型都有可以调优的参数,还有一些技术,例如交叉验证,可以用于参数调优,以避免与训练数据过拟合。这通常可以对新数据产生更好的预测性能或鲁棒性。

交叉验证通过分割训练数据来模拟样本外预测。基于像均方误差这样的模型精度评分,您可以对模型参数执行网格搜索。有些模型,如逻辑回归,具有内置交叉验证的估计器类。例如,LogisticRegressionCV类可以与一个参数一起使用,该参数指示网格搜索在模型正则化参数C上执行的细粒度:

from sklearn.linear_model import LogisticRegressionCV
model_cv = LogisticRegressionCV(Cs=10)
model_cv.fit(X_train, y_train)

要手工进行交叉验证,可以使用cross_val_score辅助函数,它处理数据拆分过程。例如,要用训练数据的四个不重叠的分割交叉验证我们的模型,我们可以这样做:

from sklearn.model_selection import cross_val_score
model = LogisticRegression(C=10)
scores = cross_val_score(model, X_train, y_train, cv=4)

默认的评分指标是依赖模型的,但是可以选择显式的评分函数。交叉验证模型需要更长的训练时间,但通常可以产生更好的模型性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_38981.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

视频编解码 - RTP 与 RTCP

目录 RTP 实时传输协议 RTCP协议 将H264 RTP打包 RTP 实时传输协议 音视频数据传输,先将原始数据经过编码压缩后,将码流打包成一个个RTP包,再将码流传输到接收端。 打包的作用 接收端要正确地使用这些音视频编码数据,不仅仅需…

JaVers:自动化数据审计

在开发应用程序时,我们经常需要存储有关数据如何随时间变化的信息。此信息可用于更轻松地调试应用程序并满足设计要求。在本文中,我们将讨论 JaVers 工具,该工具允许您通过记录数据库实体状态的更改来自动执行此过程。 Javers如何工作&#x…

vue Router

Vue项目各文件含义 1.src文件夹 是我们真正敲代码的文件夹, 2.assets放静态资源 3.components放组件 4.App.vue主组件 5.main.js项目的入口文件 Vue Router 在router/index.js路由文件中配置路由,设置路由跳转规则 import Vue from vue import Vu…

android Framework 中用到了哪些跨进程通信方式?

文章目录Linux 有哪些跨进程的通信方式?管道本地 Socket共享内存信号Linux 有哪些跨进程的通信方式? Binder 机制是Android基于Linux的一种独特的IPC机制。我们常用的AMS,PMS 等都是通过Binder机制来完成跨进程通信的,那么除了Bin…

【并发】深入理解Java线程的底层原理

线程基础知识 线程与进程 进程 操作系统会以进程为单位,分配系统资源(CPU时间片、内存等资源),进程是资源分配的最小单位。 当一个程序被运行,从磁盘加载这个程序的代码至内存,这时就开启了一个进程。 线…

使用 Mason 创建自己的 Flutter brick

使用 Mason 创建自己的 Flutter brick 原文 https://medium.com/gytworkz/create-your-own-flutter-brick-using-mason-7abc70d0324e 前言 谁不喜欢用最少的努力完成大部分事情呢?我当然知道! !Mason 帮我完成了几个简单的步骤。 在本文中,我…

Redis——》数据类型:List(列表)

推荐链接: 总结——》【Java】 总结——》【Mysql】 总结——》【Redis】 总结——》【Spring】 总结——》【SpringBoot】 总结——》【MyBatis、MyBatis-Plus】 Redis——》数据类型:List(列表)一、简介…

复现黑客在后门中藏匿后门

PHP实现在后门中藏匿后门 在攻击渗透的时候会传入shell后门方便进行远控。其中的后门包括多种类型,大马是功能最全的直接提供了可视化的界面方便攻击者进行提权、扫描、上传等一系列的操作。 但有很多hacker不讲武德,在写好的大马中藏入自己的后门&…

VBA Regex 正则表达式应用介绍

. VBA正则表达式介绍 正则表达式或 RegEx 用于在字符串中查找特定的字符。 本文将展示一个 VBA RegEx 示例,并演示为什么在 VBA 中使用正则表达式如此强大。 正则表达式是一个比较大的话题,关于这方面的书很多。 同时也是一个让许多人感到害怕的话题,因为它的语法比较神秘和…

C++入门笔记

C 入门笔记Functions in CC header Files下面主要是我学习C的一个笔记,记录学习中遇到的一些重点事项。下面是视频的连接https://www.bilibili.com/video/BV1Ay4y1i7Z6/?p10&spm_id_from333.1007.top_right_bar_window_history.content.click&vd_sourcee6e…

记录--两行CSS让页面提升了近7倍渲染性能!

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 前言 对于前端人员来讲,最令人头疼的应该就是页面性能了,当用户在访问一个页面时,总是希望它能够快速呈现在眼前并且是可交互状态。如果页面加载过慢,你…

第四章. Pandas进阶—时间序列

第四章. Pandas进阶 4.9 时间序列 1.重采样(resample) 在Pandas中,对时间序列频率的调整称为重采样,即时间序列从一个频率转换到另一个频率的过程,由周统计变成月统计 1).语法: 4.8章 第4点 已介绍过&…

MySQL数据库行级锁之间隙锁、临键锁

间隙锁 默认情况下,InnoDB在 REPEATABLE READ事务隔离级别运行,InnoDB使用 next-key 锁进行搜索和索引扫描,以防止幻读。 索引上的等值查询(唯一索引),给不存在的记录加锁时, 优化为间隙锁 。索引上的等值查询(非唯一普通索引)&…

如果把网络原理倒过来看,从无到有,一切如此清晰(下)

人生若只如初见。 前言 当我在台灯下,听着远隔17年前五月天的歌,而在数日后,我的文字也会纵使相隔万里远的来到你的屏幕前,就觉得这一切妙不可言。 OSI 网络七层模型 《如果把网络原理倒过来看,从无到有&#xff0c…

Seal库官方示例(二):encoders.cpp解析

补充一个常用的SIMD操作原理 图片来自的Hang Shao的文章。 完整代码 这个代码主要功能是编码明文,使得能够使用更加完整的明文多项式(前一个只用到了一个多项式的常量),也就是SIMD操作。主要包含了两个部分,一个是BG…

HLS + ffmpeg 实现动态码流视频服务

一、简介 如下图,包含三部分,右边一列为边缘节点;中间一列代表数据中心;左边一列是项目为客户提供的一系列web管理工具: 具体来说在我们项目中有一堆边缘节点,每个节点上部署一台强大的GPU服务器及N个网络…

精彩回顾 | 苏州农商银行新一代云原生信息科技架构体系实践

11月18日,2022年第五届中国金融科技产业大会暨第四届中新(苏州)数字金融应用博览会“基础软件与云原生系统软件”分论坛成功举办。该论坛由由中国计算机学会CTO CLUB(苏州)承办,江苏省金融科技云原生融合创…

目标检测数据标注项目分析-产品缺陷检测

什么是生产过程中的产品缺陷检测? 生产过程中的缺陷检测是保证产品质量的重要环节。及时发现故障或缺陷,并采取适当的措施,我们可以降低运行和质量相关的风险。但在一般视觉系统中,每个缺陷都必须经过检查及预处理才能被检测到,…

javaSE - Arrays - 数组的定义与使用

一、数组基本用法 1.1、什么是数组 数组本质上就是让我们能 “批量” 创建相同类型的变量 也可以说是存储一组相同数据类型的数据的集合 如: 如果需要表示两个数据, 那么直接创建两个变量即可 int a; int b 如果需要表示五个数据, 那么可以创建五个变量 int a1; int a2; int …

[附源码]Python计算机毕业设计Django的4s店车辆管理系统

项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等等。 环境需要 1.运行环境:最好是python3.7.7,…