15 分钟的大学水平的统计学入门课程
一个包含最基本的概念和公式的备忘单让你开始统计学。
照片由 Pexels 的 Meruyert Gonullu 拍摄
由于之前数学不及格,我怀着恐惧走进了我的第一门本科统计学课程。
不过,我害怕的不仅仅是数学。我担心,如果我连一门简单的统计学课程都学不会,我将会失去就业机会。沉迷于成为数据科学家的想法,我害怕无法建立所有数据科学家都需要的基本技能之一:理解和执行统计程序的能力。
不过,我本不必担心。尽管战战兢兢,我还是以 82%的成绩轻松通过了这门课(一个 A-),并以 92%的最终成绩杀进了期末考试。我今天与你分享的笔记正是那些帮助我取得成功的笔记。
在开始学习统计学之前,重要的是要知道统计学是一门非常“简单明了”的数学。简而言之,如果你知道公式,并能仔细阅读和理解问题,你就能回答任何摆在你面前的统计问题。统计问题通常会确切地告诉你他们在寻找什么作为答案的一部分(例如,计算平均值、确定标准差、完成双变量分析等)。).这就是为什么我今天与你分享的笔记非常“简单”,主要包含公式、一些词汇、显示概念之间关系的表格以及解决问题的逐步方法。
这些笔记假设理解一些概念,例如求和符号、寻找一组数字的范围、数据可视化(理解图表的类型)、基本概率和基本代数。这些注释确实省略了关于使用各种分布表的信息,因为这会大大增加本文的长度。相反,在这里分享的笔记突出了最重要的细节——其余的可以在其他地方填写。
介绍
关键术语
- **描述性统计:**通过使用表格、图表以及其他汇总和可视化措施来组织、显示和描述数据的方法。
- **推断统计学:**使用样本结果对总体进行决策或预测的方法。
- **定量变量:**可以用数字测量的变量。在定量变量上收集的数据称为定量数据。
- **定性/分类变量:**不能假定为数值,但可以归类为非数值类别的变量。在定性变量上收集的数据是定性数据。
- **群体:**由所有特征被研究的元素组成。
- **样本:**为研究选择的一部分人口。
- **代表样本:**代表总体特征的样本。
- **随机抽样:**抽取样本,使总体中的每个成员都有一定的机会被选中。
- **非随机样本:**抽取的样本,使得总体中的某些成员没有机会被选中。
- **抽样误差:**从抽样调查中获得的结果与如果整个人口都包括在调查中所获得的结果之间的差异。
- **非抽样误差/偏差:**数据收集、记录和制表过程中出现的误差。
桌子
表格中数据各个方面的实际例子。
非随机抽样的类型。
抽样和非抽样误差的类型。
随机抽样技术。
组织和绘制数据
公式
计算一个类别的相对频率。
计算百分比。
寻找班级宽度。
计算班级中点。
计算相对频率和百分比。
计算累积相对频率和累积百分比。
桌子
频率分布表中显示的分组数据。
数字描述性度量
关键术语
- **均值/平均值:**一个数据集的平均值。
- **中位数:**将按升序排列的数据集分成两半的值。如果数据集有奇数个值,则中值由数据集中中间项的值给出。如果数据集有偶数个值,则中位数由数据集中两个中间项的平均值给出。
- **模式:**数据集中出现频率最高的值。
- **标准差:**表示数据集的值围绕平均值聚集的紧密程度的值。标准差的较低值表示数据集分布在平均值附近的较小范围内。标准差的值越大,表明数据集分布在平均值附近的较大范围内。
- 经验法则:对于钟形分布,(1) 68%的观察值位于均值的一个标准差内,(2) 95%的观察值位于均值的两个标准差内,(3) 99.7%的观察值位于均值的三个标准差内。
- **四分位数:**将已排序的数据集分成四等份的三个值。第二个四分位数与数据集的中位数相同。第一个四分位数是小于中位数的观察值的中位数。第三个四分位数是大于中位数的观察值的中位数。
- **盒须图:**使用数据集中的中间值、第一个四分位数、第三个四分位数以及最小和最大值来显示数据集的中心、分布和偏斜度的图。
公式
计算平均值。
未分组数据的计算平均值。
计算样本和总体的未分组数据的方差和标准差。
计算样本和总体分组数据的平均值。
计算样本和总体分组数据的方差和标准差。
计算四分位数间距(第三个四分位数和第一个四分位数之间的差值)。
计算百分点。
计算数值的百分位数等级。
概率
关键术语
- **边际概率:**不考虑任何其他事件的情况下,单个事件发生的概率。
- **条件概率:**假设一个事件已经发生,另一个事件将要发生的概率。如果 A 和 B 是两个事件,那么给定 B 的条件概率写成 P(A|B)。
- **独立事件:**一个事件的发生不影响另一个事件发生的概率。如果 P(A|B) = P(A)或 P(B|A) = P(B ),则 A 和 B 是独立事件。
- **事件的交集:**A 和 B 的交集表示 A 和 B 共有的所有结果的集合,用(A 和 B)表示。
- **联合概率:**两个事件相交的概率,记为 P(A 和 B)。
- **互斥事件的联合概率:**两个互斥事件的联合概率始终为 0。
- **事件的并:**属于 P(A 或 B)表示的 A 或 B 或 A 和 B 的所有结果的集合。
- 阶乘: n!(读作“n 阶乘”)表示从 n 到 1 的所有整数的乘积。
- **组合:**给出从 n 个元素中选择 x 个元素的方法。
- **排列:**从 x 个元素中选择 x 个元素的总数。
公式
求概率的经典概率法则。
使用相对频率作为概率的近似值。
计算独立事件概率的乘法法则。
求两个相关事件的联合概率的乘法法则。
计算两个事件的条件概率。
求两个互不排斥的事件并的概率的加法法则。
求两个互斥事件并的概率的加法规则。
组合符号读作“一次选择 x 个 n 个元素的组合数”。
组合的数量。
排列符号读作“从 n 个元素中选择 x 个元素的排列数”
从 n 项中选择 x 项的排列数。
离散随机变量及其概率分布
关键术语
- **随机变量:**其值由随机实验结果决定的变量。
- **离散随机变量:**取可数数值的随机变量。
- **连续型随机变量:**可以取区间内任意值的随机变量。
- **离散随机变量的概率分布:**列出随机变量可能出现的所有值及其概率。
笔记
概率分布的两个特征。
二项式实验的条件:
- 有 n 个相同的试验。
- 每次试验只有两种可能的结果。审判分为两个相互排斥的事件。
- 这两种结果的概率保持不变。
- 轨迹是独立的。
公式
一个离散随机变量的平均值是指如果一个实验被重复了很多次,那么在每次重复中预期出现的值。也称为期望值,可以用 E(x)表示。
离散随机变量的标准差给出了其概率分布的范围。
二项式公式。
二项分布的均值和标准差。
连续随机变量和正态分布
关键术语
- **z 值/ z 得分:**标在标准正态曲线横轴上的单位,以标准差的形式给出平均值与 z 所代表的点之间的距离。
笔记
正态概率分布:绘制时产生一条钟形曲线;
- 曲线下的总面积为 1.0。
- 这条曲线关于平均值是对称的。
- 曲线的两个尾部无限延伸。
公式
将 x 值转换为 z 值,其中 mu 和 sigma 是 x 的正态分布的平均值和标准差。
抽样分布
关键术语
- **人口概率分布:**人口数据的概率分布。
- **条形 x 的抽样分布:**给出其抽样分布的样本统计量的概率分布。
- **样本比例的抽样分布:**样本比例的概率分布(p hat)。
- **样本比例的中心极限定理:**陈述对于足够大的样本量,p hat 的抽样分布近似正态,使得 np > 5 和 nq > 5。
公式
当总体呈正态分布时,条形 x 的抽样分布均值。
当总体呈正态分布时,条形 x 的抽样分布的标准差。
z 值为条形 x 的值。
人口和样本比例。
样本比例的平均值。
样本比例的标准差。
p hat 值的 z 值。
均值和比例的估计
关键术语
- **估计:**根据样本统计值指定给总体参数的值。
- **估计量:**用于估计总体参数的样本统计量。
- **点估计:**用于估计总体参数的样本统计值。
- **区间估计:**围绕点估计构造的包含相应总体参数的区间。
笔记
评估程序包括:
- 选择一个样本。
- 从样本成员处收集所需信息。
- 计算样本统计值。
- 为相应的填充参数赋值。
公式
给定置信水平的置信区间。
置信区间的置信水平,表明我们对该区间包含真实总体参数有多大的把握。
mu 的点估计。
标准差已知时均值的置信区间。
标准差未知时均值的置信区间。
平均值估计的误差幅度。
均值估计的样本量。
大样本 p 的置信区间。
p 估计的误差范围。
p 估计的样本容量。
关于平均值和比例的假设检验
关键术语
- **无效假设:**关于一个总体参数的声明,该参数在被声明为假之前一直被假定为真。
- **替代假设:**关于总体参数的声明,如果零假设被声明为假,该参数将被声明为真。
- **第一类错误:**当真零假设被拒绝时发生。
- 第二类错误:发生在错误的零假设没有被拒绝的时候。
- **双尾检验:**双尾都有拒绝区域。
- **左尾检验:**在分布曲线的左尾有拒绝区域。
- **右尾检验:**在分布曲线的右尾有拒绝域。
- **P 值:**零假设被拒绝的最小显著性水平。
笔记
临界值方法:
- 陈述无效假设和替代假设。
- 选择要使用的分布。
- 确定拒绝和非拒绝区域。
- 计算检验统计的观察值。
- 做决定,写结论。
P 值法:
- 陈述无效假设和替代假设。
- 选择要使用的分布。
- 计算 p 值。
- 做个决定。
公式
当标准偏差已知时,检验关于平均值的假设。
关于平均值和标准差的假设检验是未知的。
大样本下 p 的假设检验。
桌子
假设检验的四种可能结果。
检验的零假设、替代假设和尾部的符号。
估计和假设检验:两个总体
关键术语
- **独立样本:**从两个总体中抽取的两个样本,其中从一个总体中选择一个样本不影响从第二个总体中选择第二个样本。
- **相依样本:**从两个总体中抽取的两个样本,其中从一个总体中选择一个样本会影响从第二个总体中选择第二个样本。
- **成对/匹配样本:**两个样本当从一个样本收集的每个数据值都有从第二个样本收集的相应数据值,并且这两个数据值都是从同一来源收集的。
公式
当两个标准差都已知时,使用正态分布对两个独立样本的均值 1 减去均值 2 的假设进行检验的检验统计量。
从两个具有相等但未知标准差的总体中抽取的两个独立样本的混合标准差。
x 条 1 减去 x 条 2 的标准差估计。
使用 t 分布的测试统计。
配对样本中 sub d 假设的检验。
p1 — p2 假设的检验。
卡方检验
关键术语
- **卡方分布:**只有一个参数(自由度)的分布。这种分布曲线的形状对于小自由度向右倾斜,对于大自由度变得对称。整个分布位于垂直轴的右侧。这个分布只假设非负值。
- **观察频率:**从实验中获得的频率,用 o 表示
- **期望频率:**如果零假设为真,我们期望获得的频率。由 E = np 获得。
- **同质性检验:**涉及检验两个或两个以上不同群体中具有某些特征的元素比例相同的原假设,以及这些比例不同的替代假设。
笔记
多项实验:具有以下特征的实验为多项实验:
- 这个实验由 n 个相同的试验组成。
- 每次试验都产生 k 种可能结果中的一种,其中 k > 2。
- 这些试验是独立的。
- 各种结果的概率在每次试验中保持不变。
公式
拟合优度检验。
用列联表检验独立性。
使用列联表的同质性检验。
方差分析
关键术语
- ANOVA: 用于检验三个或三个以上总体均值相等的零假设的程序。
- 样本间均方值(MSB): 从不同人群中抽取的样本的平均值的变化度量。
- 样本内均方值(MSW): 对取自不同人群的所有样本的数据内变化的度量。
- SSB: 样本间的平方和。
- SST: 总平方和。
- SSW: 样本内的平方和。
笔记
f 分布:
- f 分布是连续的并且向右倾斜。
- 分布有两个自由度:分子的 df 和分母的 df。
- f 分布的单位是非负的。
单因素方差分析的假设:
- 从中抽取样本的总体近似呈正态分布。
- 从中抽取样本的总体具有相同的方差或标准差。
- 从不同人群中抽取的样本是随机和独立的。
- 单向方差分析总是右尾的。
公式
单向 ANOVA 检验的方程式。
简单线性回归
关键术语
- **简单回归:**模型,描述两个或更多变量之间的关系,只包括两个变量:一个自变量和一个因变量。
- ****线性回归:给出两个变量之间直线关系的简单回归模型。
- ****A 和 B 的最小二乘估计:利用样本数据计算出的 A 和 B 的值。
- ****最小二乘法:通过散点图拟合回归线,使误差平方和最小的方法。
- ****最小二乘回归线:用最小二乘法得到的回归线。
- ****线性相关系数:衡量两个变量之间线性关系强度的指标。
- ****多元回归模型:包含两个或多个自变量的回归模型。
- ****两个变量之间的正关系:回归线中斜率的值和两个变量之间的相关系数都是正的。
- ****两个变量之间的负关系:回归线中斜率的值和两个变量之间的相关系数都为负。
- ****斜率:回归模型中 x 的系数,它给出了 x 变化一个单位时 y 的变化。
- ****SSE(误差平方和):y 的实际值和预测值的平方差之和。
- ****SSR(回归平方和):由回归模型解释的 SST 部分。
- ****SST(总平方和):实际 y 值与 y 的平方差之和。
- ****误差的标准偏差:随机误差扩散的度量。
公式
简单线性回归模型。
估计回归模型。
b 的置信区间。
关于 b 的假设检验。
****
线性相关系数。
****
决定系数。
最终想法和附加资源。
虽然这个备忘单是一个很好的起点,但是网上有大量的资源可以帮助你进一步加深对统计概念的理解。下面列出了一些我最喜欢的:
**https://www.khanacademy.org/math/statistics-probability </8-fundamental-statistical-concepts-for-data-science-9b4e8a0c6f1c> </10-statistical-concepts-you-should-know-for-data-science-interviews-373f417e7d11>
当学习统计学时,重复和一致性是关键。当你知道你在寻找什么以及如何寻找时,问题很少是难以解决的。通过熟悉寻找所需值的最重要的公式和程序,你将能够很快解决任何摆在你面前的统计问题。**
ROC 曲线和 AUC 以及为什么和何时使用它们的易懂指南?
图片由皮克斯拜的 Gerd Altmann 提供
ROC 曲线是检查分类模型性能的最常见评估指标之一。本指南将帮助您真正理解 ROC 曲线和 AUC 是如何协同工作的
ROC 曲线或受试者操作特征曲线是检查分类模型性能的最常见评估指标之一。不幸的是,许多数据科学家经常只是看到 ROC 曲线,然后引用 AUC(ROC 曲线下面积的缩写)值,而没有真正理解 AUC 值的含义以及如何更有效地使用它们。
其他时候,他们不理解 ROC 曲线解决的各种问题以及 AUC 的多重属性,如阈值不变性和比例不变性,这必然意味着 AUC 度量不依赖于所选的阈值或概率比例。这些性质使得 AUC 对于评估二元分类器非常有价值,因为它为我们提供了一种在不关心分类阈值的情况下比较它们的方法。这就是为什么数据科学家更全面地了解 ROC 曲线和 AUC 非常重要。
那么,ROC 曲线/AUC 满足什么需要呢?
因此,在我们开始学习 ROC 曲线和 AUC 之前,我们想到的第一个问题是,为什么不使用一个相当简单的度量标准,如二进制分类任务的准确性?毕竟,准确性很容易理解,因为它只是计算模型正确预测的百分比。
答案是,准确度没有抓住概率分类器的全部本质,即,它既不是阈值不变的度量,也不是尺度不变的度量。我这么说是什么意思?最好用一些例子来解释。
1。为什么准确度不是阈值不变的?
假设逻辑回归分类器的阈值为 0.5,您认为该分类器的准确度是多少?
来源:作者图片
如果你说 50%,那恭喜你。我们会把两个零误归类为一。这个结果没那么好。但是我们的分类器真的那么差吗?基于准确性作为评价指标,似乎是这样的。但是如果我们把同一个例子中的阈值改成 0.75 呢?现在,我们的分类器变得 100%准确。这让我们不禁要问,我们如何才能提出一个不依赖于阈值的评估指标。也就是说,我们想要一个阈值不变的度量。
2。为什么精度不是尺度不变的?
现在,让我们再次做同样的练习,但是这次我们的分类器预测不同的概率,但是在相同的等级顺序。这意味着概率值会改变,但顺序保持不变。因此,在分类器 B 中,预测的等级保持不变,而分类器 C 在完全不同的尺度上进行预测。那么,以下哪一个是最好的?
来源:作者图片
在所有这些情况下,我们可以看到每个分类器在很大程度上是相同的。也就是说,如果分类器 A 的阈值为 0.75,分类器 B 的阈值为 0.7,分类器 C 的阈值为 68.5,那么我们对所有这些分类器都有 100%的准确性。
当等级顺序保持不变时,评估度量具有相同值的属性被称为尺度不变属性。在分类器预测分数而不是概率的情况下,这个属性确实可以帮助我们,从而允许我们比较两个不同的分类器,它们预测不同尺度上的值。
因此,最后,我们需要一个满足以下两个条件的评估指标:
- 它是阈值不变量 ,即度量的值不依赖于选定的阈值。
- 它是尺度不变的,即它衡量预测的排名,而不是它们的绝对值。
好消息是 AUC 满足上述两个条件。然而,在我们甚至可以看如何计算 AUC 之前,让我们更详细地理解 ROC 曲线。
ROC 曲线
关于 ROC 曲线的一个有趣的历史事实是,它们在第二次世界大战期间首次用于分析雷达信号。珍珠港事件后,美国军方想用他们的雷达信号探测日本飞机。ROC 曲线特别适合这项任务,因为它们让操作员选择阈值来区分阳性和阴性样本。
但是我们如何自己制作这些曲线呢?要理解这一点,我们需要先了解真阳性率 (TPR)和假阳性率 (FPR)。因此,假设我们有一个具有特定概率阈值的模型的以下样本混淆矩阵:
来源:作者图片
为了解释 TPR 和 FPR,我通常会举一个司法系统的例子。自然,任何司法系统都只想惩罚有罪的人,而不想指控一个无辜的人。现在让我们说,上面的模型是一个司法系统,它评估每个公民,并预测要么是零(无辜),要么是一(有罪)。
在这种情况下,TPR 是我们的模型能够捕获的有罪罪犯的比例。因此,分子是抓获的罪犯,分母是罪犯总数。这个比率也被称为回忆或敏感度。
**TPR(True Positive Rate)/Sensitivity/Recall**= TP/(TP+FN)
FPR 是我们错误预测为罪犯(误报)的无辜者的比例除以实际无辜公民的总数。因此,分子是被抓获的无辜者,分母是无辜者总数。
**FPR(False Positive Rate)**= FP/(TN+FP)
通常,我们会想要高 TPR(因为我们想抓住所有的罪犯)和低 FPR(因为我们不想抓住无辜的人)。
那么,我们如何使用 TPR 和 FPR 绘制 ROC 曲线呢?我们使用不同的阈值在 X 轴上绘制假阳性率(FPR ),在 Y 轴上绘制真阳性率(TPR)。当我们连接这些点时产生的曲线称为 ROC 曲线。
让我们通过一个简单的代码示例来理解如何在 Python 中实现这一点。下面,我们只是创建一个小样本分类数据集,并在数据上拟合一个逻辑回归模型。我们还从分类器中得到概率值。
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_curve
from sklearn.metrics import roc_auc_score
import plotly.express as px
import pandas as pd# Random Classification dataset
X, y = make_classification(n_samples=1000, n_classes=2, random_state=1)model = LogisticRegression()
model.fit(X, y)# predict probabilities
preds = model.predict_proba(X)[:,1]
现在我们想评估我们的模型使用 ROC 曲线的效果。为此,我们需要找到不同阈值的 FPR 和 TPR。我们可以通过使用来自sklearn.metrics
的函数roc_curve
很容易地做到这一点,它为我们提供了不同阈值的 FPR 和 TPR,如下所示:
fpr, tpr, thresh = roc_curve(y, preds)roc_df = pd.DataFrame(zip(fpr, tpr, thresh),columns = ["FPR","TPR","Threshold"])
我们从获得不同阈值的 FPR 和 TPR 开始。来源:作者图片
现在剩下的就是使用上面的数据绘制曲线。我们可以通过使用任何图形库来做到这一点,但我更喜欢[plotly.express](https://mlwhiz.com/blog/2019/05/05/plotly_express/)
,因为它非常容易使用,甚至允许您在 plotly express 图形的基础上使用 plotly 构造。正如您在下图中看到的,我们绘制了不同阈值下的 FPR 与 TPR 的关系。
来源:作者图片
如何使用 ROC 曲线?
我们通常可以使用 ROC 曲线来决定阈值。阈值的选择也将取决于分类器打算如何使用。因此,如果上面的曲线用于癌症预测应用,您希望获取最大数量的阳性结果(即,具有较高的 TPR ),您可能会选择较低的阈值值,如 0.16,即使此时 FPR 非常高。
这是因为你真的不想为一个实际上得了癌症的人预测“没有癌症”。在这个例子中,假阴性的成本相当高。即使一个没有癌症的人测试呈阳性,你也没问题,因为假阳性的成本比假阴性的成本低。这实际上是许多临床医生和医院为这种重要测试所做的,也是为什么如果一个人测试呈阳性,许多临床医生会第二次做同样的测试。(你能想到为什么这样做有帮助吗?提示:贝叶斯法则)。
否则,在像前面例子中的罪犯分类器这样的情况下,我们不需要高 FPR,因为司法系统的原则之一是我们不希望捕获任何无辜的人。因此,在这种情况下,我们可以将阈值选择为 0.82,这样我们的召回率或 TPR 为 0.6。也就是说,我们可以抓获 60%的罪犯。
现在,什么是 AUC?
AUC 是 ROC 曲线下的面积。该区域始终表示为 0 到 1 之间的值(正如 TPR 和 FPR 的范围都可以从 0 到 1),我们本质上希望最大化该区域,以便我们可以在某个阈值下拥有最高的 TPR 和最低的 FPR。
Scikit 还提供了一个实用函数,如果我们有使用roc_auc_score(y, preds)
的预测和实际 y 值,它可以让我们获得 AUC。
来源:维基百科
还可以从数学上证明,AUC 等于分类器将随机选择的阳性实例排序高于随机选择的阴性实例的概率。因此,AUC 为 0.5 意味着阳性实例排名高于阴性实例的概率为 0.5,因此是随机的。一个完美的分类器总是将一个阳性实例排在一个阴性实例之上,并且 AUC 为 1。
那么,AUC 是阈值不变和尺度不变的吗?
是的,AUC 是阈值不变的,因为我们不必设置阈值来计算 AUC。
为了检查标度不变性,我将做一个实验,在这个实验中,我将我们的预测乘以一个随机因子(标度),并对预测求幂,以检查即使它们的等级顺序不变,如果预测改变,AUC 是否改变。由于 AUC 是比例不变的,我希望有相同的 ROC 曲线和相同的 AUC 指标。在下面,你可以看到左边的比例和右边的指数排名顺序。
缩放(左)和取幂排序(右)
事实上这就是我得到的。只有阈值随着标度的变化而变化。曲线的形状以及 AUC 保持完全相同。
结论
创建任何机器学习管道的一个重要步骤是相互评估不同的模型。选择错误的评估指标或者不理解您的指标的真正含义可能会对您的整个系统造成严重破坏。我希望,通过这篇文章,我能够消除你对 ROC 曲线和 AUC 的一些困惑。
如果你想了解更多关于如何构建机器学习项目以及这样做的最佳实践,我会推荐 Coursera 深度学习专业化中名为“构建机器学习项目”的这个优秀的第三门课程。一定要去看看。它解决了陷阱和许多改进模型的基本思想。
我以后也会写更多这样的帖子。让我知道你对这个系列的看法。在 媒体 关注我,或者订阅我的 博客 了解他们。一如既往,我欢迎反馈和建设性的批评,可以通过 Twitter @mlwhiz 联系到我
此外,一个小小的免责声明——这篇文章中可能会有一些相关资源的附属链接,因为分享知识从来都不是一个坏主意。
浅显易懂的 C 语言介绍
速成班
对 C 语法结构的有效观察,以及对 C 编程的介绍
(src =https://pixabay.com/images/id-1143863/
介绍
C 编程语言可能是计算机历史上最重要的编程语言之一。这种语言确实在很多方面让计算机世界变得更好,并且在今天的计算世界中仍然扮演着重要的角色。不管你目前是在什么系统上阅读这篇文章,除非你出于某种原因把它打印了出来,否则正如我们所说的,你正在使用 C 代码。也就是说,如果你在任何技术领域工作,学习 C 语言对你的领域有益是很容易理解的。这当然包括软件工程和数据科学,但我认为 C 编程语言应该涉及的不仅仅是这些学科。我还制作了一个视频,对某些人来说可能更容易理解。
如果您想通过 Github 访问本文中使用的代码,可以在这里查看:
https://github.com/emmettgb/C-CrashCourse/blob/main/1/christmas_tree.c
事不宜迟,现在让我们讨论更多关于 C 编程语言的内容,并开始我们对这种语言的第一印象吧!
为什么要学 C?
当然,每当学习一种新的编程语言的问题出现时,当然应该问学习一种给定的编程语言有什么好处。我将从人们可能想学习 C 语言的一些一般原因开始,然后我将继续讨论 C 语言编程可能给科学领域带来的具体好处。
我推荐学习 C 语言的第一个主要原因是它是通用的。正如我之前提到的,你用来阅读这篇文章的电脑、手机或平板电脑可能从头到尾都写满了 C 代码。C 无处不在,并且是通用的,这意味着当与 C 一起使用时,你的软件几乎可以在任何地方运行,这种通用性也体现在 C 与其他编程语言的集成中。由于大多数操作系统及其各自的头文件都是用 C 语言编写的,所以大多数脚本语言和其他高级语言都与 C 语言集成得非常好。如果不是这样,那么这种语言在广泛使用和与其他软件一起工作时可能会有一些问题。
对于一般的软件应用程序,我支持学习 C 的最后两点是,首先,C 可以成为学习 C++的一个很好的基础。像 C 一样,C++是一种非常通用的编程语言,需求量也很大,是一种非常值得了解的语言。考虑到这一点,那些想学习 C++的人可能想先学习 C,以便掌握一些基本的语法并更好地理解 C++,而没有这种语言的范例挡路。最后,C 是最快的高级语言。在我个人看来,没有比 C 更好的了。C 代码将是你在大多数情况下可能编写的最快速和最通用的代码——所以 C 是需要高级优化的应用程序的最佳选择。
如果你想了解更多关于这如何应用于数据科学的知识,我专门写了一整篇文章。因为有很多材料我想看完,而不是把这篇文章写成一本书,所以我在这本书上练习提取方法,那些感兴趣的人可以阅读更多。尤其是因为我已经写过这个话题,没有必要再重复同样的话:
[## 为什么 C 对于数据科学来说很方便
towardsdatascience.com](/why-c-comes-in-handy-for-data-science-76071206bb5)
C 语言的主要特点
获得 C 编程语言的基础将从理解编程语言的关键特性和方法开始。在我看来,和任何语言一样,人们应该了解的第一件事是 C 的范式。c 是一种经典的命令式编程语言。这意味着当我们用 C 语言编程时,我们可以与硬件紧密互动。我们能够直接管理计算机的组件,而不是以不干涉的声明方式来使用我们的计算机。
关于 C 应该知道的第二件事是,这种语言是静态类型的。这是这种编程语言的典型特征,需要注意的是,这当然与在键盘上打字无关。类型系统是编程语言处理定制数据结构的方式。类型还可以增加编程的继承性和范围,因此它们无疑是编程语言中的无价之宝。静态这个词,至少在这个意义上(我们不是在地毯上摩擦我们的袜子,)意味着它不变。就像我们用 Java 写public static void
一样,这意味着我们描述的东西不会改变。记住,用 C 在我们的软件中声明的变量类型在运行时不会改变。这意味着编译停止后,开始执行,我们的类型被锁定,我们无法改变它们。
关于 C 你应该知道的另一件事是,它是一种相当低级的语言。当然,这只是与当今典型的语言相比,但一般来说,C 会让你写得更多,做得更少。然而,原因是 C 有一种通过汇编解释我们的代码的特定方法,这种方法通常被认为是非常快速的…代价是在某些情况下,语法可能比其他语言更难。这种语言也非常古老,使得许多已经用 C 语言编写的优秀软件非常容易被 C 程序员、许多库、优秀的文档等访问。
安装说明
现在我们已经讨论了为什么你应该使用 C,如果你决定尝试一下这种语言,那么你可能需要安装它。下面我列出了每个平台的说明。
Linux 操作系统
如果您使用的是 Linux,那么您的机器上可能已经安装了 GCC。为了检查该语句的有效性,您可以键入
gcc -v
进入你的终端。如果“gcc -v”不是一个已知的命令,那么您的软件包管理器可能会推断您想要安装 gcc。当然,无论哪种方式,您都可以使用您的软件包管理器来安装它
sudo dnf install gcc
sudo apt install gcc
sudo pacman -S gcc
sudo man install gcc
我们有这么多的包装经理,我相信你知道你的是什么。
马科斯
为了在 MacOS 上安装 GCC,您需要一个包管理器。这通常是 Brew 包管理器。因为我不是 Mac 用户,所以在这一点上,我建议我的 MacOS 朋友(类似 Unix 的兄弟/姐妹/非二进制 hood)参考另一篇提供此类信息的文章:
在您的机器上安装 Brew 之后,您可以简单地在您的终端上运行我们在 Linux 上运行的相同命令。如果您还没有更新您的软件包档案,那么您可能应该先这样做。
**brew update****brew install gcc**
https://www.digitalocean.com/community/tutorials/how-to-install-and-use-homebrew-on-macos
旁注——谢天谢地有人做了一个 MacOS 软件包管理器。我不明白没有包管理器人们怎么生活。
Windows 操作系统
对于我的 Windows 朋友来说,我相信 C 编译器的安装是非常典型的常规 Windows 安装。我会从下面的链接下载setupx86_64.exe
,然后运行它:
编写我们的第一个程序
我们真的不需要做太多准备来开始创建我们的新 C 项目。我所做的基本上就是创建一个漂亮的工作目录,并在其中创建一个新文件——我最初将其命名为等腰. c,但后来将其重命名为 christmas.c,因为我开始这个项目时想制作一个三角形——
但是有点辣。(喜欢薄荷辣,不喜欢辣椒辣。)
因此,我们在新的 christmas.c 文件中要做的第一件事是编写一个主函数。在此之前,我想用一种智能的方法来编写一个函数。每当我去写一个函数时,我总是做的第一件事就是考虑我的输入和输出。首先,我需要什么来调用这个函数?其次,我希望从这个功能中达到的结果是什么?当我们写代码时,有一个清晰的方向,以及一条清晰的路径,无论何时我们编程都是绝对必要的。虽然有一些方法可以让我们在输出时“随波逐流”,但我们当然希望了解函数的作用——并为该指令恰当地命名所述函数。
考虑到这一点,这个建议对 C 也有一点帮助,因为参数是和返回的类型一起列出的。记住,C 中的打字是静态的,非常强。强静态类型意味着这个返回类型是不可变的和显式的。也就是说,我们的返回必须明确定义为我们放入该字段的类型。当我们写一个主函数时,返回的总是一个整数。这是因为我们的程序总是会返回一个退出代码。退出代码是编程中的一种通用方法,用来告诉计算机是否有什么地方出错了。基本上我们可以说误差=(我们的回报。)当然,如果没有错误,我们希望这是假的—或零。让我们考虑我们的第一个功能:
int main(){}
上面代码中的“int”是我们的返回类型。如上所述,这将是一个 0,因为我们没有任何错误,甚至错误处理目前。main()函数只是一个新的方法定义。请注意,每当运行 C 文件时,编译器都会寻找这个定义来执行。请记住,如果我们要编写另一个不是从我们的主函数调用的函数,这段代码将不会运行。最后,C 语言中打开和关闭函数的方法语法就是{}括号。这将包含这个新函数的内容。假设首先运行这个函数,我们不需要在我们的参数中放入任何东西,这些参数通常在 main()后面的括号内。这当然可以通过 CLA 来改变,我们将在这些演练的下一部分中讨论这一点。
最后,我们将返回我们的函数。我们可以简单地在这个函数中加入 return 0。我们还需要在这个表达式的末尾添加一个分号。每当我们在 C 语言中完成类似这样的语句时,我们都需要使用分号。这让 C 知道这是函数中这个特殊调用的结束,我们想继续下一个调用。
int main(){
return 0;
}
现在让我们回到我们的终端或奇怪的 Windows 命令提示符的事情。随便想想,Windows 用户在编程时可能想考虑的一个选项是 WSL,即 Linux 的 Windows 子系统。我听说它非常耐用而且容易使用…并且可以让您更好地理解(即使使用真正的 GCC 编译器!)不管怎样,如果我们是 ls(或者对于 windows 用户是 dir),我们将看到我们的 christmas.c 文件:
lschristmas.c
现在我们将把它编译成一个二进制文件:
gcc christmas.c -o Christmas
这将为我们提供一个可执行文件,不需要 linker-dude(我对 ld 的昵称)或任何类似的特殊东西,我们可以简单地用。/适用于 MacOS/Linux 用户。我认为 Windows 用户需要双击输出文件。
./Christmas
现在你会“C”(懂了吗?)那什么都没发生。
标准输出
鉴于这仅仅是对 C 编程语言的一个基本而缓慢的介绍,并且我刚刚花了 20 分钟解释什么是 C 以及如何在各种操作系统上安装 C,今天我们将只讨论标准输出。然而,为了做到这一点,我们将需要利用一些依赖关系。我现在才意识到——我不知道如何在 Windows 上安装头文件——我强烈推荐 WSL,但是标准库和标准输入/输出包含在 GCC 中,所以我认为至少这篇文章不会有问题。
在我们开始写这个小 C 文件的其余部分之前,请允许我先解释一下为什么什么都没发生。每当我们运行下面的代码时,
int main(){
return 0;
}
我们的编译器直接跳转到我们在这里定义的 main()函数。一旦它运行了上述函数中的语句,就会立即返回一个退出代码 0。因此,它没有错误地退出。为了从这个软件中获得一些输出,我们需要做的第一件事是包含两个头,stdlib.h 和 stdio.h。对于这个场景,我们不一定需要 stdlib.h,但它在将来肯定会派上用场,并且这是在大多数用 c 编写的软件的开头编写的。h 在这方面意味着这是一个头文件,它包含了一些我们的 C 软件将要依赖的数据。在 C 语言中包含文件的语法是使用#后跟 include。然后,我们用箭头<>将想要包含的标题括起来。
#include <stdlib.h>
#include <stdio.h>int main(){
return 0;
}
现在我们可以开始向我们的函数添加输出。我不打算用我花了多长时间画一棵圣诞树来烦你,(我认为它花了太多时间。)所以请允许我将完整的代码粘贴在这里供您欣赏。这里唯一的信息是一些正则表达式,printf()方法,这是标准输出,以及如何使用引号""编写字符串。
#include <stdlib.h>#include <stdio.h>int main() {printf(" ★\n");printf(" /_\\\n");printf(" /_ _\\\n");printf(" /_ _ \\\n");printf("/ \\\n");printf("---------\n");printf(" | |\n");return 0;}
结论
我认为 C 语言仍然是程序员最有价值的学习经历之一。如果你不熟悉 C 编程语言,我强烈推荐你学习它,因为它很有趣,功能多样,而且它的命令性可以教会你很多东西。就我个人而言,我发现从软件的角度来了解硬件,尤其是我个人使用的硬件,是一件非常有趣的事情。
感谢您的阅读!祝你在进入可爱的 C 世界的旅途中好运!我将很快贴出这个快速简单速成课程的更多部分!
Python 中升级的营销组合建模
营销分析
让我平庸的营销组合模式更加强大
闪回
在我的上一篇文章中,我向您介绍了营销组合建模的世界。如果您尚未阅读,请在继续之前阅读。
在那里,我们创建了一个线性 回归模型,该模型能够根据几个广告渠道(如电视、广播和网络横幅广告)的原始广告支出来预测销售额。对于作为机器学习实践者的我来说,这样的模型本身就已经很好了。更好的是,它还让商界人士感到高兴,因为该模型让我们能够计算投资回报率,让我们能够判断每个渠道的表现如何。
然而,我们上次的简单线性回归模型有一些问题,我们将在本文中解决。让我给你解释一下:
- 我们第一款产品的性能可能会更好。
- 我们的第一个模型表现得不真实。将支出增加到无穷大也会将销售额增加到无穷大,这毫无意义,因为人们只能在我们的产品上花有限的钱。
- 优化变得琐碎、无用、不切实际。为了在给定固定预算的情况下最大化销售额,我们现在将把所有资金投入到线性回归系数最高的渠道中。
广告😉
我创建了一个小库,在这里我实现了本文其余部分的思想,甚至更多。通过pip install mamimo
安装,并在此查看如何使用:
解决问题
为了规避这些问题,我们可以做一些聪明的特征工程,允许我们将一些营销领域的知识整合到模型中。不要担心,理解这些概念不需要营销经验,因为它们很自然,因此很容易理解。以下技术将提高性能,并使模型更加真实。
广告股票
我们要做的这个特色工程是一个至关重要的组件,叫做https://en.wikipedia.org/wiki/Advertising_adstock**,这是西蒙·布罗德本特发明的一个术语[1]。这是一个包含两个简单概念的奇特词汇:
- 我们假设你花在广告上的钱越多,你的销售额就越高。然而,我们花得越多,增长就越弱。例如,将电视支出从 0 €增加到 100,000 €会大大增加我们的销售额,但将它从 100,000,000 €增加到 100,100,000 €就没有那么多了。这叫做饱和效应或收益递减效应** 。**
- 如果你在广告周花钱,人们通常不会立即购买你的产品,而是在几周之后。这是因为该产品可能很贵,人们希望仔细考虑它,或者将其与其他公司的类似产品进行比较。不管是什么原因,在第 T + x 周的销售部分是由你在第 *T、*周播放的广告引起的,所以它也应该得到一些积分。这被称为遗留或滞后效应**。**
我认为这两个事实都很容易理解,商界人士也很喜欢。
我们的新模型仍然是线性的,但是用 adstock 特性代替原始支出作为输入。这使得模型更加强大,同时保持其可解释性。
在 scikit-learn 中构建饱和度和结转效应
对我们来说不幸的是,scikit-learn 不包含这些转换,因为它们不是跨行业的兴趣。但是由于这两种转换都没有那么复杂,所以这是一个练习编写 scikit-learn 兼容估计器的好机会。
如果你以前从未这样做过,你可以看看我的另一篇关于这个话题的文章。这篇文章是关于回归变量而不是变压器的,但是方法并没有太大的不同。
**
所以,让我们从更简单的开始:饱和效应。
产生饱和效果
我们希望创建一个具有以下属性的变换(=数学函数):
- 如果支出为 0,则饱和支出也为 0。
- 该转换是单调递增的,即输入支出越高,饱和输出支出越高。
- 饱和值不会增长到无穷大。相反,它们的上限是某个数,比如说 1。
简而言之,我们想要这样的东西:
图片由作者提供。
有很多方法可以得到这样的函数,例如,在图片中你可以看到函数 1-exp(-0.7 x )。所以让我们使用这个函数模板,并将其推广到 1-exp(-ax)for somea>0。 a 是一个超参数,我们可以随后进行调整,因为通常我们不知道饱和函数的形状。
N ote: 还有许多更标准的饱和度函数,如Adbudg和Hill函数,但让我们坚持用 指数函数 函数 为
一个很好的副作用:我们最终能够输出饱和曲线,所以我们知道花更多的钱是否有意义,或者渠道是否已经饱和。比如从上图来看,投资 8 以上好像就没用了。
所以,我们来编码一下。事实上,就是这个简单的小类:
class ExponentialSaturation:
def __init__(self, a=1.):
self.a = a
def transform(self, X):
return 1 - np.exp(-self.a*X)
然而,我们将为输入添加一些健全性检查,以使其符合 scikit-learn。这增加了一点代码,但这是我们必须付出的相对较小的代价。
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.utils.validation import check_is_fitted, check_array
class ExponentialSaturation(BaseEstimator, TransformerMixin):
def __init__(self, a=1.):
self.a = a
def fit(self, X, y=None):
X = check_array(X)
self._check_n_features(X, reset=True) # from BaseEstimator
return self
def transform(self, X):
check_is_fitted(self)
X = check_array(X)
self._check_n_features(X, reset=False) # from BaseEstimator
return 1 - np.exp(-self.a*X)
它仍然不完美,因为我们还应该实现对大于零的 a 的检查,但这是你可以自己轻松完成的事情。使用ExponentialSaturation
变压器,我们可以做到以下几点:
图片由作者提供。
这个不算太糟,对吧?现在让我们来看下一个效应。
产生遗留效应
这个稍微复杂一点。让我用一个例子来说明我们想要达到的目标。随着时间的推移,我们会有一系列的支出,例如
(16, 0, 0, 0, 0, 4, 8, 0, 0, 0),
这意味着我们在第一周花了 16 英镑,然后从第 2 周到第 5 周我们什么也没花,然后在第 6 周我们花了 4 英镑,等等。
我们现在希望一周的花费能以指数形式部分结转到下一周。这意味着:在第一周有 16 英镑的支出。那么我们携带超过 50%,意思是
- 0.5 * 16 = 8 到第 2 周,
- 0.5 * 16 = 4 到第 3 周,
- 0.5 * 16 = 2 到第 4 周,
- …
这引入了两个超参数:强度(有多少被结转?)和长度(多长时间结转?)的结转效应。如果我们使用 50%的强度和 2 的长度,则上面的支出顺序变为
(16, 8, 4, 0, 0, 4, 10, 5, 2, 0).
我相信你可以写一些循环来实现这个行为,一个好的快速的方法是使用卷积。我就不详细解释了,就拿代码当礼物吧。我再次强调了真正重要的线。
from scipy.signal import convolve2d
import numpy as np
class ExponentialCarryover(BaseEstimator, TransformerMixin):
def __init__(self, strength=0.5, length=1):
self.strength = strength
self.length = length
def fit(self, X, y=None):
X = check_array(X)
self._check_n_features(X, reset=True)
self.sliding_window_ = (
self.strength ** np.arange(self.length + 1)
).reshape(-1, 1)
return self
def transform(self, X: np.ndarray):
check_is_fitted(self)
X = check_array(X)
self._check_n_features(X, reset=False)
convolution = convolve2d(X, self.sliding_window_)
if self.length > 0:
convolution = convolution[: -self.length]
return convolution
可以看到,上课是走强度和长度的。在拟合过程中,它会创建一个滑动窗口,由 convolve2d 函数使用,神奇地完成我们想要的工作。如果你知道 CNN 的卷积层,这就是这里发生的事情。从图形上看,它执行以下操作:
图片由作者提供。
N 注: 还有很多方法可以创建遗留问题。衰变不一定是指数的。也许广告效果的顶峰不是在花钱的那天,而是在下一周。您可以通过相应地更改滑动窗口来表达所有这些变化。
让我们结合饱和效应和结转效应来创建一个更现实的营销组合模型。
最终模型
我们将对每个渠道使用不同的饱和度和结转。这是有道理的,因为通常情况下,电视广告比你在网上看到的横幅广告在你脑海中停留的时间更长。从高层次的角度来看,该模型将如下所示:
图片由作者提供。
请注意,蓝色管道只是电视支出的函数,橙色管道是广播支出的函数,紫色管道是横幅广告支出的函数。我们可以使用ColumnTransformer
和Pipeline
类在 scikit-learn 中有效地实现这一点。ColumnTransformer
允许我们对每个广告渠道使用不同的转换,而Pipeline
允许我们对单个渠道进行连锁操作。花点时间理解下面的片段:
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LinearRegression
adstock = ColumnTransformer(
[
('tv_pipe', Pipeline([
('carryover', ExponentialCarryover()),
('saturation', ExponentialSaturation())
]), ['TV']),
('radio_pipe', Pipeline([
('carryover', ExponentialCarryover()),
('saturation', ExponentialSaturation())
]), ['Radio']),
('banners_pipe', Pipeline([
('carryover', ExponentialCarryover()),
('saturation', ExponentialSaturation())
]), ['Banners']),
],
remainder='passthrough'
)
model = Pipeline([
('adstock', adstock),
('regression', LinearRegression())
])
最难的部分是ColumnTransformer
,所以让我来解释一下如何阅读用粗体标记的电视块。它只是说:
将管道应用于“TV”列,并将此部分命名为“tv_pipe”。管道只是 adstock 转换。
那里没有更多的事情发生。最后,我们使用这个大的预处理步骤,并在末尾添加一个简单的LinearRegression
来得到一个实际的回归变量。那么,让我们 再次加载数据 并做一些训练。
import pandas as pd
from sklearn.model_selection import cross_val_score, TimeSeriesSplit
data = pd.read_csv(
'https://raw.githubusercontent.com/Garve/datasets/4576d323bf2b66c906d5130d686245ad205505cf/mmm.csv',
parse_dates=['Date'],
index_col='Date'
)
X = data.drop(columns=['Sales'])
y = data['Sales']
model.fit(X, y)
print(cross_val_score(model, X, y, cv=TimeSeriesSplit()).mean())
# Output: ~0.55
注: 我们这里不使用标准的 k -fold 交叉验证,因为我们处理的是时间序列数据。
*TimeSeriesSplit*
是比较合理的做法,这里 可以多了解一下 。
有用!然而,该模型仍然相当糟糕,交叉验证的 r 约为 **0.55,**而旧的、更简单的模型为 0.72。这是因为我们为每个通道使用了默认的非最佳参数,即饱和度的 a = 1,残留强度为 0.5,长度为 2。
因此,让我们调整所有的 adstock 参数!
超参数调谐
我将使用 Optuna ,一个用于优化任务的高级库。在许多其他的事情中,它提供了一个 scikit-learn 兼容的OptunaSearchCV
类,你可以把它看作是 scikit-learn 的[GridSearchCV](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html)
和[RandomizedSearchCV](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.RandomizedSearchCV.html)
的替代物。
简而言之,OptunaSearchCV
是RandomizedSearchCV
的更智能版本。虽然RandomizedSearchCV
只是随机走动,但是OptunaSearchCV
首先随机走动,然后检查看起来最有希望的超参数组合。
查看与您习惯用 scikit 编写的代码非常接近的代码——了解:
from optuna.integration import OptunaSearchCV
from optuna.distributions import UniformDistribution, IntUniformDistribution
tuned_model = OptunaSearchCV(
estimator=model,
param_distributions={
'adstock__tv_pipe__carryover__strength': UniformDistribution(0, 1),
'adstock__tv_pipe__carryover__length': IntUniformDistribution(0, 6),
'adstock__tv_pipe__saturation__a': UniformDistribution(0, 0.01),
'adstock__radio_pipe__carryover__strength': UniformDistribution(0, 1),
'adstock__radio_pipe__carryover__length': IntUniformDistribution(0, 6),
'adstock__radio_pipe__saturation__a': UniformDistribution(0, 0.01),
'adstock__banners_pipe__carryover__strength': UniformDistribution(0, 1),
'adstock__banners_pipe__carryover__length': IntUniformDistribution(0, 6),
'adstock__banners_pipe__saturation__a': UniformDistribution(0, 0.01),
},
n_trials=1000,
cv=TimeSeriesSplit(),
random_state=0
)
你告诉 Optuna 优化model
。它通过使用您在param_distributions
中指定的所有参数来实现。因为我们的模型是完全嵌套的,也就是说,列转换器中有管道,而列转换器本身又在管道中,所以我们必须准确地指定我们想要优化的超参数。这是通过诸如adstock__tv_pipe__carryover__strength
这样的字符串来完成的,其中两个下划线分隔了完整模型的不同层次。你发现adstock
、tv_pipe
、carryover
这几个字都在型号说明书里,而strength
是ExponentialCarryover
变压器的一个参数。
然后,你找到一些分布。UniformDistribution(0, 1)
表示应该在 0 和 1 之间寻找浮点参数。按照同样的逻辑,IntUniformDistribution(0, 6)
搜索 0 到 6 之间的整数值(不是 5!),因此我们告诉模型只考虑结转长度小于或等于六周,这只是我们的一个选择。
我们尝试n_trials=1000
不同的参数组合,并再次使用TimeSeriesSplit
进行评估。通过设置random_state=0
保持结果的可再现性。*搞定!*这应该足够理解代码了。
性能检查
让我们使用这个名为tuned_model
的优化模型来检查性能。小心,这需要很长时间。你可以将n_trials
减少到 100,以更快地得到一个更差的解。
print(cross_val_score(tuned_model, X, y, cv=TimeSeriesSplit()))
# Output: array([0.847353, 0.920507, 0.708728, 0.943805, 0.908159])
平均交叉验证的 r 为 **0.87,**与未优化的模型(0.55)和我们上一篇文章中的旧平面线性模型(0.72)相比,这是一个很大的改进。让我们现在改装模型,看看它学到了什么。
tuned_model.fit(X, y)
最佳超参数如下:
print(tuned_model.best_params_)
print(tuned_model.best_estimator_.named_steps['regression'].coef_)
print(tuned_model.best_estimator_.named_steps['regression'].intercept_)
# Output:
# Hyperparameters = {
# 'adstock__tv_pipe__carryover__strength': 0.5248878517291329
# 'adstock__tv_pipe__carryover__length': 4
# 'adstock__tv_pipe__saturation__a': 1.4649722346562529e-05
# 'adstock__radio_pipe__carryover__strength': 0.45523455448406197
# 'adstock__radio_pipe__carryover__length': 0
# 'adstock__radio_pipe__saturation__a': 0.0001974038926379962
# 'adstock__banners_pipe__carryover__strength': 0.3340342963936898
# 'adstock__banners_pipe__carryover__length': 0
# 'adstock__banners_pipe__saturation__a': 0.007256873558015173
# }
#
# Coefficients = [27926.6810003 4114.46117033 2537.18883927]
# Intercept = 5348.966158957056
对新数据使用模型
如果您想为新的支出表创建预测,可以按如下方式进行:
X_new = pd.DataFrame({
'TV': [10000, 0, 0],
'Radio': [0, 3000, 0],
'Banners': [1000, 1000, 1000]
})
tuned_model.predict(X_new)
请注意,预测总是以零库存开始,即模型不知道过去的任何结转,除非您将它放入预测数据框架。例如,如果您想知道第周到第周的销售额,并且您只输入第周到第周的支出,那么它不会考虑之前第周到第 -1 周、周到第 -2 周的结转。如果你想让模型建立一个库存,你也必须包括之前的几周,即使你只对最后一次观察的预测感兴趣。
你甚至可以用更多不花费的特性来扩展训练数据,所谓的控制变量。如果您没有在ColumnTransformer
对象中指定任何预处理,原始值将直接传递给LinearRegression
并被考虑用于训练和预测。
解释模型
使用上面的数据,我们可以创建一些漂亮的图片,帮助我们从模型中获得洞察力。
饱和效应
如果我们插入饱和变压器的值,我们会得到以下结果:
图片由作者提供。
- 我们可以看到,该模型认为电视频道仍然非常*不饱和——*在这里花费更多可能有利于销售。注意,我们最大的电视支出大约是 15000 英镑。
- 广播看起来有点饱和,但增加这方面的支出似乎还是合理的。该渠道最高消费约 7700。
- 横幅看起来过饱和。这里最高消费 2500 左右,函数值已经接近 1 了。更高的支出似乎不会有太大的成效。
遗留效应
如果我们插入延续变压器的值,我们会得到以下结果:
图片由作者提供。
似乎电视广告在最初消费 4 周后仍然对销售有影响。这比广播和网络横幅广告在同一周内迅速消失的效果要长得多。
渠道贡献
和上一篇文章一样,我们可以计算每个渠道对每天销售额的贡献。代码比以前稍微复杂一些,因为模型也变得更复杂了。无论如何,这里有一个工作版本:
adstock_data = pd.DataFrame(
tuned_model.best_estimator_.named_steps['adstock'].transform(X),
columns=X.columns,
index=X.index
)
weights = pd.Series(
tuned_model.best_estimator_.named_steps['regression'].coef_,
index=X.columns
)
base = tuned_model.best_estimator_.named_steps['regression'].intercept_
unadj_contributions = adstock_data.mul(weights).assign(Base=base)
adj_contributions = (unadj_contributions
.div(unadj_contributions.sum(axis=1), axis=0)
.mul(y, axis=0)
)
ax = (adj_contributions[['Base', 'Banners', 'Radio', 'TV']]
.plot.area(
figsize=(16, 10),
linewidth=1,
title='Predicted Sales and Breakdown',
ylabel='Sales',
xlabel='Date'
)
)
handles, labels = ax.get_legend_handles_labels()
ax.legend(
handles[::-1], labels[::-1],
title='Channels', loc="center left",
bbox_to_anchor=(1.01, 0.5)
)
输出:
图片由作者提供。
与旧图相比,基线不再摇摆不定,因为该模型可以更好地解释给定渠道支出的销售情况。下面是老款的一款:
老型号。图片由作者提供。
总结与展望
在本文中,我们采用了旧的简单线性模型,并通过不依赖原始渠道支出,而是依赖广告库存来改进它。广告库存是通过引入饱和效应和结转效应来更真实地反映现实世界的转换支出。
我们甚至对这两个概念做了简明的实现,可以在 scikit-learn 生态系统中以即插即用的方式使用。
我们做的最后一件事是调整模型,然后看看它已经了解了什么。我们以人们容易理解的图片形式获得了一些有趣的见解,使这个模型既准确又可解释。
然而,仍有一些未解决的问题:
- 我们已经讨论了优化支出,以及旧模式为何无法做到这一点。嗯,有了新的,但我不会在这里详细介绍。简而言之,对待我们的
tuned_model
函数,用你选择的程序优化它,例如 Optuna 或scipy . optimize . minimize。为优化添加一些预算约束,例如总支出应少于 1,000,000。 - 将非支出数据输入模型可能会进一步改善它。例如,以一周中的日、月,或者甚至是我们想要销售的产品的价格为例。尤其是价格是销售的一个重要驱动力:一部售价 10000 €的普通 iPhone 不会产生多少销量,而一部售价 100 €的 iPhone 会在一眨眼的功夫就脱销。对于季节性产品(如粉丝或热巧克力)来说,月份等及时功能可能很有意思。或者像圣诞节这样的特殊日子。收集你的想法,并确保添加所有能够影响销售的内容!
参考
[1] S .布罗德本特,《电视广告的单向作用》(1979 年)。《市场研究学会杂志, 21 (3),第 139–166 页。**
我希望你今天学到了新的、有趣的、有用的东西。感谢阅读!
作为最后一点,如果你
- 想支持我多写点机器学习和
- 无论如何都要计划获得中等订阅量,
为什么不做 通过这个环节 ?这将对我帮助很大!😊
透明地说,给你的价格不变,但大约一半的订阅费直接归我。
非常感谢,如果你考虑支持我的话!
有问题就在LinkedIn上写我!
写了一年的数据科学文章
简短的背景故事、学习经历和关键要点!
一年前,我欣喜若狂地发表了我的第一篇文章《走向数据科学》,这是我长期关注的最好的平台之一。
在写这篇文章的时候,我已经在这个平台上写了近百篇文章,聚集了大约 800 名追随者,并多次成为人工智能和生产力领域的顶级作家,同时也获得了这个平台上 1000 名顶级作家的荣誉。
虽然文章的统计数据和表现对我来说并不重要,但它仍然是一个压倒性的积极影响,从社区获得了大量的积极和爱。接触到广泛的受众并分享最好的知识,希望能够帮助所有有志于这门学科的人和爱好者,这是一种巨大的快乐。
我的文章的目标是接触到所有层次的研究人员和开发人员,并为大多数读者提供一些信息。由于我一直忙于我的全职工作,几个月来发表文章的速度略有下降。但是,我打算长期坚持写下去,把最好的资源分享给大家!
下面是我个人最喜欢的文章之一,我会推荐大多数数据科学初学者查看,以深入探索该主题的大多数复杂细节和方面。
</12-steps-for-beginner-to-pro-in-data-science-in-12-months-c6f6ba01f96e>
通过这篇文章,我希望分享我在一年多的时间里写数据科学和人工智能文章时积累的一些重要知识和经验。在我们深入讨论关键要点之前,我想分享一些关于我的背景的小细节,我被问了好几次。事不宜迟,让我们开始吧!
简短背景故事:
经过三年从众多资源中学习数据科学和人工智能,我开始构建一些很酷的项目。虽然我总是构建一些项目来将我的理解与特定的概念相关联,但我觉得我能够在那个学习阶段执行一些相当高水平的项目。因此,我认为分享我的想法和项目是一个很好的主意,这样可以帮助其他人,也可以在一个受欢迎的平台上传播我的想法。
在写我的第一篇文章的时候,我正在进行一个深度学习项目,在人类情感和手势检测的任务上使用迁移学习和定制模型。我以两部分系列的形式发表了这些关于迈向数据科学的文章,并由此开始了我的文章写作之旅。如果您有兴趣探索更多,请点击下面的链接。
最初的想法是写几篇文章,可能只是转移到我的其他爱好上。然而,在我早期的帖子中收到的爱和鼓励越来越多地激励我继续学习和写作。
在写了几个月的大量文章后,我不得不过渡到一个更平衡的系统,因为我在该国一家知名机构实习了三个月,现在我正全职从事深度学习的研发工作。
尽管我很忙,但我计划只要有时间就为我所有的读者写有用的文章,这样每个人都可以从中找到最好的效用!
我的经历和主要收获:
现在我们有了一个简短的背景故事,我的许多观众都对它感兴趣,我将尝试探索我的一些主要经验和在这个平台上作为一名作家不断发展的主要学习。在这一部分,我将解释五个最重要的知识,它们对我帮助很大,增加了我对概念的理解和个性的全面发展。
1.增长的学习曲线:
虽然我最初开始写文章来展示我的工作和开发更多的项目,但随着我写更多的文章,我开始有每天学习新东西的冲动。写文章的时候,我的学习曲线总体上有所增长,因为我不断地理解更多的新概念,并在我已经简单了解的主题上磨练我的技能。
定期写文章的主要好处之一是,我可以不断地用新的现代技术和人工智能世界中不断发现的其他新技术来更新自己。在与其他了不起的读者分享它们的同时,我也有机会对每个主题有了更多的个人了解。
2.新的思想渠道:
虽然我通常在随意拖延和想一些最愚蠢的事情时得到大多数最好的想法,但我发现对我个人来说,写作帮助我将我的想法引向积极的方向。它使我能够思考不同的事情,并且不会忘记我在想什么,因为我把它写下来,然后对这个话题进行更多的探索。
这种方法可能不太适合大多数人,但对我来说非常有效,我建议试一试。你也可以写一些笔记来确保你的想法朝着正确的方向发展。每个不同的人都有不同的获取新概念和理解新思想的方法。
3.了解在线博客的复杂细节:
对我个人来说,最大的好处之一是理解了在线博客错综复杂的细节。在这一年中,我有过几次学习经历。作为一个完全不熟悉在线撰写数据科学文章的人,我意识到了在线遵循正确的程序以获得更有成效的结果。
TDS 的编辑团队在整个旅程中给予了我特别的支持,他们在几个方面帮助我提高了写作技巧,并从整体上提高了我的在线形象。他们有益的反馈有助于提高文章的质量以及我对这个主题的总体了解。
由于我获得了持续的知识,在许多其他项目或其他工作组织中工作对我来说也是一次奇妙的经历。有了一些学习经验,如图像版权声明、提供真实来源、抄袭规则和其他类似的规定,我对如何进行大多数任务有了清晰的理解。
4.支持性社区:
一般来说,学习人工智能、数据科学或 Python 编程的一个最好的方面就是从社区中获得大量的支持和鼓励。有几个网站、YouTube 视频、discord 频道、slack 频道、GitHub 和许多其他优秀的资源可供我们探索和利用。
除了这些资源丰富的材料之外,在这些领域中的每一个领域都有不断的更新,并且社区积极地致力于有效地完善每一个需求。如果你在某个问题上陷入困境,像 Stack Overflow 或 just friends online 这样的社区总是愿意提供帮助。利用这些机会,你可以建立令人敬畏的联系,共同繁荣!
5.终极满足感:
选择一个主题,研究特定的主题以获得额外的信息,写文章,反复检查和验证事实和信息,最后发表文章的整个过程是最愉快的经历之一。虽然有时工作可能会变得乏味,但分享新事物和学习新经验永远不会扼杀整体的兴奋感。
我从观众、读者、朋友和编辑团队那里得到了大量的鼓励,帮助我茁壮成长,并获得了巨大的满足感。因此,我将热爱在这个平台上长期从事以下写文章的爱好。
关键要点:
虽然我已经介绍了我想在本文中介绍的大部分主题,但我还是建议所有感兴趣的读者注意一些要点,这样他们就有希望从这些建议中受益。
- 数据科学的关键方面是要弄清楚,你花在学习这个主题上的时间越多,你获得的知识就越多。在这个广阔的领域没有捷径可走。
- 尝试利用你获得的知识,以某种方式对你的研究方法和风格有用和有成效。
- 如果你真的被数据科学的奇迹所鼓舞,继续追求你认为对你有意义的东西。
- 在构建任何数据科学项目时,在取得成功之前经历多次失败的情况应该被视为一个预先确定的结论。对于任何复杂的数据科学问题,第一次尝试就取得最佳结果几乎是不可能的。
- 对于任何对追求数据科学感兴趣的人来说,关键因素是你对学习该领域不断发生的新方面和发展的兴趣和持续的动力。
如果你仍然在选择数据科学的中途,还没有完全决定你在不久的将来想从事什么工作,我建议查看我以前的一篇文章,其中我谈到了成为数据科学家的十个错误理由。下面提供了链接。
</10-wrong-reasons-to-become-a-data-scientist-319531bb874e>
结论:
“如果你在做你真正关心的事情,你就不需要被逼。愿景拉着你。” — 史蒂夫·乔布斯
这篇文章与我平时写的文章大不相同。主要目标是涵盖我的观众想要回答的一些关于我的问题,我在一年的写作过程中所学到的主要经验,并给每个人一些关键的收获,以便他们最终能以某种方式从中受益。
总结我最后的想法,到目前为止这是一个神话般的旅程,我计划在未来继续撰写大量与人工智能和数据科学相关的文章。如果我的观众有什么具体的事情要讨论,请随时在下面的评论区联系我,或者在 LinkedIn 上联系我。
Medium 启动了一个新项目,让读者订阅他们最喜欢的作家的作品,以获得最快的更新。如果你喜欢我的内容,那么从下面的链接订阅,每当我发表文章时,你就会收到闪电般的通知!
https://bharath-k1297.medium.com/subscribe [## 当我发布时收到闪电般的速度通知!
bharath-k1297.medium.com](https://bharath-k1297.medium.com/subscribe)
如果你对这篇文章中提到的各点有任何疑问,请在下面的评论中告诉我。我会尽快给你回复。
看看我的其他一些文章,你可能会喜欢读!
</10-computer-vision-terms-everyone-must-know-about-687a98845fc8> </5-best-python-projects-with-codes-that-you-can-complete-within-an-hour-fb112e15ef44> </14-pandas-operations-that-every-data-scientist-must-know-cc326dc4e6ee> </7-best-ui-graphics-tools-for-python-developers-with-starter-codes-2e46c248b47c>
谢谢你们坚持到最后。我希望你们都喜欢这篇文章。祝大家有美好的一天!
用熊猫和 Plotly 分析 1993 年的米兰德比数据
下一场米兰德比将于下周开始,为了向我的足球迷丈夫提供更多的信息和可视化,以及建立我的 python 学习,我从 Kaggle 获取了关于意甲和维基百科的数据,并试图开发一个基于证据的可视化。
Izuddin Helmi Adnan 在 Unsplash 上拍摄的照片
先决条件:
用于此分析的 Python 包:
import pandas as pd
import glob
import matplotlib.pyplot as plt
import numpy as np
import plotly.express as px
第一步:获取数据
当前分析中使用的数据来自 ka ggle(https://www.kaggle.com/massibelloni/serie-a-19932017),我从那里下载了 1993 年至 2017 年的所有意甲数据,并保存到本地文件夹中。
第二步:合并数据
从 Kaggle 下载的意甲数据是按年份呈现的。为了了解意甲的概况,我在过滤 AC 米兰/国际米兰的结果之前,先合并了所有的数据。
这里我使用了函数 glob :
##set up the path
path = r'.....SerieA'
all_files = glob.glob(path + "/*.csv")##read all files
tb = []
for filename in all_files:
df = pd.read_csv(filename, index_col=None, header=0)
tb.append(df)##combine all files
frame = pd.concat(tb, axis=0, ignore_index=True)
第三步:过滤掉 AC 米兰和国际米兰的所有比赛
根据数据框架,它有主队和客场队(见下图 1)。我们需要让 AC 米兰成为主队,国际米兰成为客场,反之亦然。
图 1 :车架头部(10)
首先,我试图找到 AC 米兰是主队,国际米兰是客队的比赛:
df1= frame[(frame['HomeTeam'] == 'Milan') & (frame['AwayTeam'] == 'Inter')]
然后,国际米兰是主队,AC 米兰是客场队:
df2 = frame[(frame['HomeTeam'] == 'Inter') & (frame['AwayTeam'] == 'Milan')]
要将这两个数据帧合并为一个数据帧:
ddff = [df2,df1]
result = pd.concat(ddff)
我们就要完成数据清理了!因为我只想知道数据的前几列,所以我省略了其余几列:
data = result.iloc[:, 0:7]
步骤 4:完成可视化数据集
为了使可视化更容易,我做了一些事情:1)添加 1997 年到 2020 年的比赛数据,因为这些数据在下载的文件中丢失了;2)获取比赛日期的“年份”;3)添加两列——一列为“冠军队”,另一列为每场比赛的“总目标”:
## add data from 1997 to 2020 - a bit messy method was used here:
new_row = {'Date': '15/10/17', 'HomeTeam':'Inter', 'AwayTeam':'Milan', 'FTHG':'3','FTAG':'2', 'FTR': 'H'}
data = data.append(new_row, ignore_index = True)new_row = {'Date': '27/12/17', 'HomeTeam':'Milan', 'AwayTeam':'Inter', 'FTHG':'1','FTAG':'0', 'FTR': 'H'}
data = data.append(new_row, ignore_index = True)new_row = {'Date': '04/04/18', 'HomeTeam':'Milan', 'AwayTeam':'Inter', 'FTHG':'0','FTAG':'0', 'FTR': 'D'}
data = data.append(new_row, ignore_index = True)new_row = {'Date': '21/10/18', 'HomeTeam':'Inter', 'AwayTeam':'Milan', 'FTHG':'1','FTAG':'0', 'FTR': 'H'}
data = data.append(new_row, ignore_index = True)new_row = {'Date': '17/03/19', 'HomeTeam':'Milan', 'AwayTeam':'Inter', 'FTHG':'2','FTAG':'3', 'FTR': 'A'}
data = data.append(new_row, ignore_index = True)new_row = {'Date': '09/02/20', 'HomeTeam':'Inter', 'AwayTeam':'Milan', 'FTHG':'4','FTAG':'2', 'FTR': 'H'}
data = data.append(new_row, ignore_index = True)new_row = {'Date': '18/10/20', 'HomeTeam':'Inter', 'AwayTeam':'Milan', 'FTHG':'1','FTAG':'2', 'FTR': 'A'}
data = data.append(new_row, ignore_index = True)
为可视化准备色谱柱:
## Add the column - "Year" of each match
data['year'] = pd.DatetimeIndex(data['Date']).year
data = data.sort_values('year')## Add the column - "Winner" of each match
data['Winner'] = np.where(data['FTR'] == 'A', data['AwayTeam'], (np.where(data['FTR'] == 'H', data['HomeTeam'], 'Draw')))## Add the column - "TotalGoal" of each match
data["FTHG"] = pd.to_numeric(data["FTHG"])
data["FTAG"] = pd.to_numeric(data["FTAG"])
data['TotalGoal'] = data['FTHG'] + data['FTAG']
第五步:用 Plotly 可视化
在这里,我创建了两个图表:
气泡图:
显示“比赛日期”、“每场比赛的总进球数”和“比赛获胜者”之间关系的图表:
fig = px.scatter(data, x="year", y="TotalGoal",size="TotalGoal", color="Winner",
color_discrete_map={'Milan':'red',
'Inter':'royalblue',
'Draw':'lightgreen'},
hover_name="Winner", log_x=True, size_max=20)
fig.show()
图二:气泡图
饼图:
另一张图表是关于过去几年中获胜的比例。为了得到饼图,需要用 groupby 重新构造数据帧:
## Restructure the dataframe with groupby
counts = data['TotalGoal'].groupby(data['Winner']).count().reset_index(name="count")## Pie chart
fig1 = px.pie(counts, values ='count', names ='Winner', title='Milan Derby', color = 'Winner',
color_discrete_map={'Milan':'red',
'Inter':'royalblue',
'Draw':'lightgreen'})
fig1.show()
图三:饼状图
思绪
通过看这两张图表,下面是对米兰德比的一些思考。
- 很明显,AC 米兰和国际米兰在赢得比赛方面没有太大的区别。国际米兰赢的比赛比 AC 米兰略多;
- AC 米兰在 2010 年之前的比赛中比国际米兰更有可能获胜,而国际米兰在 2010 年之后获得了更多的获胜机会;
- 当比赛的总进球数超过 4 个时,国际米兰似乎更有可能赢得比赛。
这些想法似乎与球队那些年的表现一致。我等不及要看下一场德比了!
使用 Python 和 Apple Health 分析您的健康状况
厌倦了用鸢尾花和海难学习数据科学?让我们试试你的健康数据。
Solen Feyissa 在 Unsplash 上拍摄的照片
眼下,描述手机对我们生活的影响感觉有些毫无意义。无论我们在哪里,我们形影不离的伙伴让我们打电话,写信息,浏览互联网,玩游戏等等。可能性的列表是无穷无尽的,并且每天都在增长。
另一个重要方面是,它们配备了各种硬件传感器(例如 GPS、加速度计、陀螺仪),结合软件,几乎可以跟踪我们生活的方方面面。此外,随着可穿戴设备的到来,他们的数据收集能力进一步扩展。
如果你是苹果用户,你大概知道苹果健康。它是 iOS 的一项功能,用于监控和组织与健康相关的数据。它整合了苹果生态系统和第三方设备和应用程序收集的数据。根据您的具体设置,它可以提供关于您的身体活动、身体测量、睡眠习惯、心率、听力、营养、血糖甚至月经周期的宝贵见解,仅举几个例子。虽然一些指标很简单,如步数,但其他指标更详细,如我们行走时的双支撑时间或不对称的比率。
这些工具引发了隐私问题,因为它们利用并可能暴露敏感数据。即使用户同意,我们的记录有多安全?这些特征构成了自我意识的机会还是仅仅是另一种形式的虐待?我们如何利用它们进行科学研究?毫无疑问,这是一场引人入胜的辩论,但它超出了本文的范围。
在本文中,我们将下载并探索我们自己的健康记录。如果您正在使用其他人的,请负责任地行事,并确保在您继续之前得到他们的同意。从数据科学的角度来看,这些全面的数据集构成了研究和增加我们自我知识的黄金机会,也就是说,更好地了解我们的生活方式。如果你正在学习数据科学,还有另一个优势:这是来自你的实际数据。将你所学到的一切应用到真实数据中,并得出一个可以改善你自己生活的可行结论,这难道不是一件很棒的事情吗?不要误解我,那些流行的数据集(例如 Iris 、 Titanic )非常有教育意义,但它们并没有那么实用。相反,这些健康和生活日志数据源可以提供有趣的、激励性的和可操作的例子。值得给他们一试!
1.下载数据集
首先,我们正在下载数据集。它需要几个手动步骤:
- 打开手机上的健康应用。
- 触摸右上角的个人资料图片。
- 触摸下一屏幕底部的导出所有健康数据。
- 您将看到几个选项来共享生成的 zip 文件。选择对你最方便的,比如给自己发邮件。
- 在您的桌面上,解压缩附加的归档文件。
图片作者。有些区域是故意模糊的。
2.将 XML 处理成数据帧
从存档中的两个文件中,名为export.xml
的文件包含我们需要的数据。只需几行代码和标准包,就可以很容易地将其改造成一个熊猫T1。不需要安装其他任何东西。所以,让我们打开一个 Jupyter 笔记本,运行这个:
上面的代码使用 xml 模块中的ElementTree
解析 XML。文件结构非常简单,一系列带有一些属性的条目。首先,我们将 XML 转换成一个字典列表(每个条目对应一个属性)。其次,我们将它们转换成一个DataFrame
,将列表映射到行,将字典映射到列。接下来,我们调整数据类型,这对于日期和度量尤其重要。最后,由于观察类型的标签相当大,我们通过仅保留标识符的尾部来缩短它们(例如 hkquantitytypeidentifierbodymasus被翻译成仅 BodyMass )。
完成了:我们有了一个整洁的DataFrame
,里面有我们所有的长格式健康记录!要检查可用度量的范围,只需执行data.type.unique()
来获得type
列的不同值。这取决于你的情况,但通常你会得到诸如步数、距离步行跑步或、飞行攀爬等标签。
3.透视和重新取样
为了方便地分析数据,最好切换到宽格式的表格。况且看到数据稀疏,也方便汇总成月。结果将是一个表,每月一行,度量以列表示。下面的示例代码只聚集了身体质量和距离行走跑步。您需要的具体列取决于您的案例中可用的数据和您的特定研究问题。请注意,每个度量都需要自己的聚合策略。例如,我们应该将这段时间内的所有观察值相加,以计算每月的总步行距离。相反,为了计算平均重量,我们应该应用平均值(从 numpy 导入)而不是总和。
4.添加外部数据和合成变量
虽然我们可以单独使用 pivot 和 long 表完成许多事情,但是如果我们添加 Apple Health 外部的数据或创建合成变量,我们的分析会变得更加有趣:
如果变量不是通过直接测量获得的,则该变量是合成的。让我们来计算一下我体重的月差异(稍后会有更多的介绍)。作为外部数据,我包括三个虚拟变量,它们将标记我生活中的一些相关事件。在相关事件发生的月份,它们将被设置为 1,否则为零。例如, covid 表示我的国家第一次新冠肺炎封锁(当流动性显著降低时), phd 强调我的博士学位的持续时间,圣诞节强调寒假期间(即 12 月和 1 月)。因此,最终的表格如下所示:
2020 年的表格摘录。图片作者。
5.研究问题:什么因素影响我的体重?
现在到了有趣的部分,让我们把所有的部分组合在一起,并从数据中提取有价值的见解。作为解决问题的第一个方法,我们绘制了身体质量月时间序列:
图片作者。
这些年来,我的体重并没有保持不变。哪些因素可能会影响它?解释这些变化的简单数学模型如下:
图片作者。
等式的左侧是体重的每月变化(此后为增量)。右边是一个常数,一个因子的线性组合和一个误差项。哪些因素?在数据集中,我们有远程行走跑步和假人博士、 covid 和圣诞。让我们试试这些。
下图显示了体重月差异的时间序列,旁边是密度函数。
图片作者。
6.相关矩阵
相关矩阵是总结数据集中所有变量之间相关性的一种便捷方式。除了数字之外,我们还可以绘制一个热图,使其在视觉上更具吸引力。正相关的变量显示为蓝色,负相关的变量显示为红色。只需扫一眼就可以得出一些结论:
- Delta 与步数、距离和 PhD 负相关。这些因素似乎降低了我的体重。前两个是因为体力活动,第三个最有可能是因为压力。然而,圣诞节似乎让我超重了。
- 由于对移动性的相应限制,锁定会对距离和步数产生负面影响。
- 步数和距离有很强的相关性。
- 体重和体力活动呈正相关。尽管这似乎违反直觉,但实际上是有道理的:当我的体重高时,我会进行更多的身体活动来补偿和减肥。
图片作者。
7.配对图
另一种有效的表示是配对图。它将每个变量映射到双变量和单变量图网格中的列和行上。在这种情况下,对角线显示每个变量的密度,而上下三角形用散点图和一些核密度估计 (KDE)等高线描述变量之间的成对关系。让我们画出关系最密切的变量:
图片作者。
如果我们只关注第一行,δ是纵坐标,其他变量是横坐标。最左边的图是 Delta 的概率分布,我们之前已经展示过了。下面两个是 Delta 和 DistanceWalkingRunning 和 christmas 的关系。我们欣赏两个图表中清晰的斜率。
8.线性回归
情节是解决问题的很好的探索工具。然而,为了得出更有意义的结论,我们需要测量效果的强度和统计显著性。考虑到这个目标,我们正在计算一个普通最小二乘法 (OLS)回归:
图片作者。
结果包含了大量的图表,这些图表非常有助于更好地理解这个问题:
- 决定系数,R 的平方,测量自变量预测的因变量的方差。越高越好。我们的 0.31 是合理的,但离最大值 1.0 还很远。随着解释变量数量的增加,调整后的版本解释了虚假结果。
- 回归系数测量影响的数量和方向。例如,我在圣诞节期间每月增加约 0.911 公斤,或者如果我每天穿越 3 公里,我可能每月减少 1 公斤。
- p 值回答了另一个有趣的问题:我们确定系数不为零吗?为了拒绝零假设,我们需要低于临界值的 p 值(T21)。在本例中,我们将其设置为 5%。因此,我们应该只考虑常量、距离步行跑步和圣诞节的值。
- 95%的置信区间为每个系数提供了最可能的范围。
最后的话
如果你足够老,你肯定还记得电脑在处理能力和多功能性方面无法与今天的智能手机相提并论的时代。如今,这些设备伴随我们到任何地方,并记录我们的个人生活。虽然在这种情况下,隐私是一个合理的问题,但作为数据科学家,我们的职责是将可用数据转化为对个人、组织和整个社会有用的东西。在这个过程中,我们必须采取负责任的行动。
健康数据为了解一个人的生活提供了有价值的信息。在这篇文章中,我们学会了从手机中轻松检索数据,并(希望)得出一些有趣的结论。
可能性是无限的!另外,如果你是学生,这个教程可以让你在对你有意义的真实数据上练习技巧。极限是你的想象力。
期待您的评论,感谢您的阅读!
分析气候跟踪全球温室气体排放数据
作者图片
使用 Python 的 Plotly 库的一系列交互式世界地图
随着至关重要的第 26 次联合国气候变化大会(COP26)的临近,来自各个领域的气候变化活动人士正在努力影响和施压将参加 2021 年 10 月 31 日至 11 月 12 日在格拉斯哥举行的气候谈判的政策制定者。
最引人注目和创新的举措之一来自排放跟踪联盟气候跟踪,该联盟最近发布了全球首个**基于直接、独立观察的全球温室气体(GHG)排放综合核算,涵盖 2015 年至 2020 年期间。**利用卫星技术、遥感、人工智能和机器学习的力量,该清单旨在提高 GHG 监测和报告的透明度,特别是在那些缺乏技术和资源来确保对排放数据进行合理核算的国家。
该清单可在 Climate Trace 网站上获得,提供了一个直观且用户友好的界面来可视化数据并按不同变量过滤信息。然而,除了条形图和折线图,我相信有地图来比较 GHG 在世界范围内的排放量也是很棒的。
这个职位(以及本系列即将上任的职位)有三重目的。首先,它旨在提高对当前 **气候危机的认识。**其次,它提供了一个分析迷人且改变游戏规则的气候痕量排放数据库的绝佳机会,从而使其更加可见和熟悉,以便其他研究人员、气候科学家和数据分析师可以使用它。最后,它为那些对使用 Python 进行数据分析和可视化感兴趣的人提供了一个编码教程。更准确地说,在本帖中,我们将关注如何使用强大的 Plotly Python 图形库制作世界地图。
这个项目的代码可以在我的 GitHub 库中找到。地图(两者都有。巴新和。html 格式)也可以在我的 GitHub 库和我的 Plotly 工作室账户中找到。请随意使用和分享:我们对气候危机、其原因和后果了解得越多,我们就越有准备去解决它。
注:根据 知识共享署名 4.0 国际许可(CC BY 4.0),排放数据已通过 Climate TRACE 提供。
免责声明:以下地图尺寸因嵌入略有变化。这种大小调整影响了标题、图例和源文本的位置。
数据
数据的主要来源是气候追踪排放数据库,你可以从气候追踪网站下载。此外,我还使用了来自世界银行的世界人口数据,因此我可以计算各国的人均排放量。
该清单涵盖 2015 年至 2020 年期间,提供了 250 个国家 10 个部门和 38 个分部门的 GHG 排放数据(以二氧化碳当量衡量)。下面你可以找到谁的数据看起来像:
作者图片
经过一些处理和一些预处理步骤后,我们可以将总量数据与排放数据合并:
结果如下:
作者图片
用 Plotly 创建世界地图
地图是理解分布和比较各国数据的绝佳视觉工具。 Plotly 的 Python 图形库提供了创建交互式、出版物质量的图形的工具,包括可以轻松嵌入网站的地图。关于如何在你的 Plotly Chart Studio 账户上上传 Plotly graphs 和在中型帖子上嵌入 Plotly graphs 的更多信息,请查看本教程。
本质上,创建 GHG 排放地图(以及一般意义上的地图),是一个子集化、过滤和分组操作的游戏。例如,我们可以绘制 2020 年按国家划分的 GHG 排放量地图,2017 年按国家划分的 GHG 人均排放量地图,以及计算 2015 年农业排放量的第三张地图。由于有许多选择,而不是写一段代码为每一个地图,我们可以创建函数,将创建一个特定的参数集的地图。
下图显示了 2020 年各个国家的 GHG 排放量:
作者图片
这张地图是三个以套娃方式工作的函数组合的结果(即我们只需调用一个函数,这个函数随后会调用另一个函数,依此类推)。在我们的例子中,我们必须调用函数 **show_map (metric,year,map_format='img '),**调用函数 **df_metric (metric,year),**调用函数 calculate_percentiles (df,metric)。
show_map() 主要处理可视化任务。它使用 Plotly 语法创建一个 choropleth map ,控制布局选项(地图框架、标题、悬停、图例和注释)美学属性(如颜色、字体和文本大小)配置选项(将文件保存在您的本地计算机或您的 Plotly Chart Studio 帐户中,以及 Plotly 按钮)。默认情况下,函数将文件保存在本地计算机的中。png 格式。PNG 文件是不允许交互的静态图像。要允许这个选项,我们只需将 map_format 参数改为*【html】***,**这样一个交互。将创建 htlm 映射,而不是在本地创建。
为了构建地图, show_map(metric,year,map_format=‘img’) 依赖于由 **df_metric(metric,year)创建的数据。根据我们想要计算的指标— GHG 排放量(【百万吨二氧化碳当量】)、人口数(【人口数】)或 GHG 人均排放量(【二氧化碳当量/人均排放量】 ) —以及所选年份,该函数将对数据框架执行不同的操作以选择正确的数据。最重要的任务之一是创建一个名为“range”的新列,它使用 pandas 函数 **cut()对数据值进行分段和分类。**此栏是用颜色区分国家的关键。我可以使用连续色标,我认为使用离散色标更有效,如地图图例所示。(有关这方面的更多示例,请查看世界银行数据网站上的地图可视化。)
但是如何分割数据,使地图上的颜色有意义呢?由于指标的价值和尺度不同(例如,GHG 的排放量是以百万吨二氧化碳当量来衡量的,而 GHG 的人均排放量是以每人多少吨二氧化碳当量来衡量的),我们需要摆弄数据,直到我们找到合理的分割值。这是通过函数 **calculate_percentiles(df,metric)完成的。**该函数返回两个列表:第一个是根据指标分割数据的百分比列表;第二个是将出现在地图图例中的标注列表。用于计算百分位数的值是在对每个指标中的数据分布进行了一些实验后选择的。
按部门绘制排放图
气候追踪数据中最酷的事情之一是,它提供了 GHG 按部门和子部门的排放分布。例如,“**石油和天然气”**部门由三个子部门组成:石油和天然气生产、炼油和固体燃料转化。在地图上标出这些信息也很有意义。我已经建立了第二组函数来创造奇迹: show_map_sector(sector,year,map_format=‘img’) , df_sector(sector,year) 和 percentiles_sector (df,sector)。
函数的推理与上面解释的函数非常相似。唯一的特殊性是,对于每个部门,其分部门的排放信息可以在与每个国家相关的悬停框中找到。例如,您可以在下面找到 2020 年石油和天然气行业的世界排放地图。
作者图片
结论
我希望你喜欢这个教程。随意使用 Python 代码——即 show_map 函数——作为 Plotly 新世界地图可视化的模板。如前所述,不同指标和部门的地图可以在我的 GitHub 库以及我的 Plotly 工作室账户中找到。请注意,我只创建了最近一年(2020 年)的地图。如果您想创建前几年的地图,只需下载我的代码,安装所需的依赖项并更改 year 参数。
在本系列的后续文章中,我们将进一步挖掘气候跟踪数据库,提供新的数据分析和可视化,这可能有助于提高对我们这个时代最大挑战:气候变化的认识和理解。
分析与 SHAP 的互动
使用 SHAP Python 包来识别和可视化数据中的交互
来源:作者
SHAP 值用于解释模型做出的单个预测。它通过给出每个因素对最终预测的贡献来做到这一点。SHAP 相互作用值通过将贡献分解成它们的主效应和相互作用效应对此进行了扩展。我们可以用这些来突出和可视化数据中的交互。它也是了解模型如何做出预测的有用工具。
来源:作者
重点将放在应用 SHAP 方案和解释结果上。具体来说,我们首先解释什么是 SHAP 相互作用值,以及如何用它们来解释个人预测。然后,我们深入研究这些值的 3 种不同聚合,这有助于我们解释模型一般是如何进行预测的。这包括取所有相互作用值的绝对平均值,并使用 SHAP 汇总和相关图。我们会检查关键的代码片段,你可以在 GitHub 上找到完整的项目。
资料组
为了解释如何使用 SHAP 包,我们创建了一个包含 1000 个观测值的模拟数据集。在表 1 中,您可以看到该数据集中的要素。目标是使用剩余的 5 个特征来预测员工的年度奖金。我们设计了数据集,因此体验和程度之间以及业绩和销售之间存在互动。days_late 不与任何其他功能交互。你可以在 Kaggle 上找到这个数据集。
表 1:随机生成的数据集中的字段
本文假设您对数据交互有所了解。如果没有,下面的文章将是一个很好的阅读第一。在这里我们确切地解释什么是相互作用。使用与上面相同的数据集,我们还解释了可以用来分析它们的其他技术。这些可以是 SHAP 的一个很好的替代品。
包装
在下面的代码中,您可以看到我们将用来分析这些数据的包。在第 2 行到第 5 行,我们有一些用于管理和可视化数据的标准库。在第 7 行,我们导入 XGBoost,用于对目标变量建模。在第 9 行,我们导入 SHAP 包。在那之下,我们初始化允许你在一个笔记本里显示图表的包。确保你已经安装了所有这些。
系统模型化
要使用 SHAP 软件包,我们首先需要训练一个模型。在第 2–4 行,我们导入数据集并分配目标变量和特性。在第 7 行和第 8 行,我们定义并训练了 XGBoost 模型。为了简单起见,我们使用整个数据集来训练我们的模型。为了避免过度拟合,我们限制了模型中每棵树的最大深度为 3。
如果您将 SHAP 应用于现实世界的问题,您应该遵循最佳实践。具体来说,您应该确保您的模型在训练集和验证集上都表现良好。你的模型越好,你的结果就越可靠。作为对该模型的快速检查,我们在下面绘制了实际奖金与预测奖金的对比图。这个模型应该可以很好地展示 SHAP 一揽子计划。
图 1:实际奖金与预测奖金
解读 SHAP 互动价值观
现在我们有了模型,我们可以得到 SHAP 相互作用值。这些可以解释为类似于正常的 SHAP 值。如果你对解释这些不熟悉,下面的文章会很有帮助。这将使本文的其余部分更容易理解,因为所讨论的情节是相似的。
为了计算 SHAP 交互值,在第 2 行,我们通过将模型传递给 TreeExplainer 函数来定义一个 explainer。该函数用于解释系综树模型的输出。使用第 3 行的解释器,我们得到交互值。这将返回一个数组,【shap _ interaction】,它包含 X 特征矩阵中 1000 个观察值中每一个的记录。
为了理解的结构shap _ interaction我们可以使用下面的代码。第 2 行告诉我们数组的形状是(1000,5,5)。这意味着该阵列包含 1000 个 5x5 矩阵。我们将 5×5 矩阵称为贡献矩阵。它们包含了用于解释 1000 个预测的 SHAP 值。第 5 行给出了数据集中第一个雇员的贡献矩阵。我们可以在下面的图 2 中看到这个矩阵。
该矩阵告诉我们,与平均预测相比,每个因素对模型预测的贡献有多大。这是对标准 SHAP 值的类似解释,除了贡献被分解成主效应和交互效应。主要效应在对角线上给出。例如,该员工的经验水平使他们的预测奖金增加了 35.99 美元。相互作用效应在非对角线上给出。这些值减半,例如,performance.sales 交互将预测奖金减少了 8.76 美元(-$4.38 x 2)。
图 2:第一个员工的 SHAP 互动价值观
平均预测是所有 1000 名员工的平均预测奖金。如果您将贡献矩阵中的所有值相加,并添加平均预测值,您将获得该员工的模型实际预测值。在我们的例子中,平均预测奖金是 148.93 美元。矩阵中的所有值加起来是 59.98 美元。这为第一个雇员提供了 208.91 美元的预测奖金。您可以使用下面的代码确认这与模型的预测相同。
SHAP 交互图
查看单个贡献矩阵可以解释单个模型预测。但是如果我们想解释模型是如何做出一般预测的呢?为此,我们可以用几种不同的方式聚集贡献矩阵中的值。
绝对平均图
首先,我们将计算所有 1000 个矩阵中每个单元的绝对平均值。我们采用绝对值,因为我们不希望正负 SHAP 值相互抵消。因为相互作用的影响减半,我们也将非对角线乘以 2。然后我们将它显示为热图。您可以在下面的代码中看到这是如何实现的,输出如图 3 所示。
此图可用于突出重要的主效果和交互效果。例如,我们可以看到,平均主效应对于体验、程度、性能和销售都很大。这告诉我们,这些特点往往有很大的积极或消极的主要影响。换句话说,这些特征往往会对模型的预测产生重大影响。同样,我们可以看到,体验程度和绩效销售互动的影响是显著的。
图 3:主效应和交互效应的绝对平均值
汇总图
对于标准 SHAP 值,一个有用的图是蜂群图。这是 SHAP 一揽子计划中的一个情节。在下面的代码中,我们获得了 SHAP 值并显示了这个图。具体来说,这些是没有被分解成它们的主效应和交互效应的 SHAP 值。
关于如何解读这张图表,我们不会涉及太多细节。快速看一下图 4,您可以看到图表的颜色是由左轴给出的特性的特征值决定的。我们可以看到,学位、经验、绩效和销售的高价值都与更高的 SHAP 价值或更高的奖金相关联。
图 4: SHAP 蜂群图
有了 SHAP 相互作用值,我们可以通过使用下面代码中的摘要图来扩展这个图。输出如图 5 所示。这里主要效应的 SHAP 值在对角线上给出,非对角线给出了相互作用效应。对于这个情节,互动效果已经翻倍了。与蜂群图一样,颜色由 y 轴上的特征的特征值给出。
图 5: SHAP 汇总图
通过指出重要的主效应和交互效应,该图可以给出与绝对均值图相似的见解。具体来说,我们可以看到,在图 3 中,具有高 SHAP 值的细胞对应于具有高绝对平均值的相同细胞。摘要图通过可视化关系的性质提供了额外的洞察力。例如,我们可以看到,学位、经验、业绩和销售的主要影响都是积极的。
依赖图
在概要情节中有很多细节,即使有颜色,也很难解释交互作用的效果。我们可以使用依赖图来更好地理解交互的本质。下面,您可以看到用于为 experience.degree 交互创建依赖图的代码。
查看图 6 中的输出,我们可以看到,如果这个人有学位,那么随着经验的增加,experience.degree 交互效应也会增加。如果这个人没有学位,情况正好相反。我们应该记住,这只是相互作用的结果。应该根据经验和学位的主要影响来考虑这种关系。
图 6:体验度交互依赖图
图 7: SHAP 总结图(仅学位和经验)
回到我们的总结剧情,可以看到经验的主效应是正面的。所以假设一个有学位的人的经验增加了。主效应和交互效应将在同一个方向上起作用。这意味着随着经验的增加,他们的预期奖金也会增加。另一方面,如果一个人没有学位。那么主要的(积极的)和交互作用的(消极的)影响将在相反的方向上起作用。随着经验的增加,预测奖金可能增加、减少或保持稳定。
这与下面的散点图是一致的。这里我们绘制了原始数据值——没有 SHAP 值。我们可以看到,如果一个人有学位,那么他们的奖金往往会随着经验的增加而增加。如果他们没有学位,奖金在不同的经验水平上趋于稳定。我们还没有用 SHAP 值来展示,但稳定的奖金表明,当一名员工没有学位时,主效应和交互效应可能会完美地相互抵消。
图 8:体验度交互散点图
最后,在图 6 中,我们有业绩-销售互动的依赖图。这个情节可以用类似的方式来解释。我们应该记住,我们现在有一个更好的相互作用的两个连续变量,而像以前一样,我们有一个连续和分类变量。
图 9:绩效-销售互动依赖图
上面我们使用了 SHAP 相互作用值作为更多的探索性数据分析技术。也就是说,我们用它们来识别和可视化重要的相互作用。我们也可以使用这个包来帮助解释我们的模型。你可以用类似的方式使用它,除了我们的目标是理解我们的模型如何做出预测。我们将在下面的文章中详细解释为什么这很重要。
支持我成为我的 推荐会员 😃
https://conorosullyds.medium.com/membership
|Twitter|YouTube|时事通讯 —注册免费参加 Python SHAP 课程
图像来源
所有图片都是我自己的或从www.flaticon.com获得的。在后者的情况下,我拥有他们的保费计划中定义的“完全许可”。
参考
南伦德伯格, SHAP 蟒包 (2021) *,*https://github.com/slundberg/shap
南 Lundberg,NHANES I Survival model . ipynb(2020),https://github . com/slund Berg/shap/blob/master/notebooks/tabular _ examples/tree _ based _ models/NHANES % 20I % 20 Survival % 20 model . ipynb
南伦德伯格和 s .李,解释模型预测的统一方法 (2017),https://arxiv.org/pdf/1705.07874.pdf
C.Molnar,可解释机器学习(2021)https://christophm . github . io/interaction-ml-book/html
用普罗特利分析 2020/21 赛季西甲联赛
用动画线形图描绘西甲比赛,用图表显示统计数据
“进攻为你赢得比赛,防守为你赢得冠军.”
作为一个狂热的巴萨球迷,我不禁赞同弗格森爵士(前曼联主帅)的上述说法,尤其是在当前俱乐部足球的背景下。巴塞罗那足球俱乐部(FC Barcelona)曾在其黄金时代完全主宰国内联赛和欧洲足球。然而,俱乐部自 2015/16 赛季以来就没有打进过欧冠决赛。在上赛季输给劲敌皇家马德里之后,巴塞罗那在本赛季的倒数第二个比赛日输给了塞尔塔维戈,也被踢出了冠军争夺战。另一方面,马德里竞技队在去年夏天从巴塞罗那转会到马德里竞技队的首席射手路易斯·苏亚雷斯的激励下,获得了他们的第 11 个西甲冠军。
西甲联赛在很大程度上被认为是一场三足鼎立的比赛,尤其是在最近几年,因为在过去十年中,只有巴塞罗那、皇家马德里和马德里竞技赢得了联赛冠军或成为了联赛冠军的最大竞争者。在这篇文章中,我将使用一个动画情节的线图比赛和一个非常基本的仪表板来讨论这三个俱乐部在本赛季西甲的竞争和基本统计数据。代码和数据可以在这个 GitHub 资源库中获得。让我们开始吧。
西甲 2020/21 赛季动画剧情线路图
首先,我的目标是想象整个赛季前三名球队在西甲联赛中的表现。我首先导入三个必需的包,在本例中是 pandas、numpy 和 plotly.graph_objects。用于此目的的数据可在这个储存库中获得,这个储存库是我根据FcTables.com通过跟踪每个俱乐部每个比赛日的赢、输和平而创建的。dataframe 由每个比赛日之后西甲三支顶级球队的累计积分组成,如下图所示。
每个比赛日后包含累积积分的数据框(图片由作者提供)
plotly.graph_objects 包括显示图形的数据和布局元素。我从定义numOfFrames
*,*开始,这相当于 dataframe 中的行数。我创建了一个名为initial_data
*,*的散点图类型的轨迹,它表示数据帧的第一行中的数据。
为了获得动画折线图竞赛,在每个瞬时时间点捕获帧是一个先决条件,这样第一帧捕获第一行的数据,第二帧捕获第一和第二行的数据,依此类推。为此目的创建了嵌套 for 循环,使得frames
将每个current_frame
的实例附加到末尾。
通过传递用于数据的initial_data
和用于布局的frames
,我得到了一个描述联赛中前三名俱乐部每个比赛日总积分的动画线图,如下所示:
前三名俱乐部每个比赛日的积分(图片由作者提供)
分析
正如上面的 gif 图片所示,巴塞罗那在赛季开始的前十场比赛中表现不佳。这是他们这么多赛季以来最糟糕的开局之一,俱乐部在前八场比赛中仅积 11 分,在联赛中排名第 13 位。相比之下,马竞的开局要好得多。到 2021 年 1 月赛季中期,马竞在联赛中稳步上升,分别与皇家马德里和巴塞罗那拉开了 10 分和 13 分的差距。
前十场比赛后,巴塞罗那加快了速度,连续几场连胜,甚至在某些点上超过了皇家马德里,并缩小了与联赛领头羊的差距。另一方面,马德里竞技在赛季中期后下降了几分,并将领先优势从超过 11 分缩小到只有几分。在赛季的最后一个季度,巴塞罗那和皇家马德里都丢掉了几个关键分,甚至错过了登上榜首的机会。在本赛季的最后一个比赛日,三家俱乐部都赢得了比赛,然而,马德里竞技成为了西甲 2020/21 赛季的最终赢家。
Plotly 仪表盘
在本节中,我打算创建一个非常基本的交互式仪表盘,以可视化西甲 2020/21 的统计数据并进行讨论。我为此使用的包与上面的线图比赛使用的包是一样的。用于此目的的数据可在此处获得,可从fbref.com公开获得。数据帧如下所示:
西甲 2020/21 积分表(图片由作者提供)
接下来,我初始化该图,并创建一个我希望在仪表板中显示的指标的字典。在我的字典里,这些键代表着分数、进球、失球、净胜球、获胜的比赛、平局的比赛和失败的比赛。该字典的每个键都链接到原始数据集的相应子集。
#create a figure from the graph objects (not plotly express) library
fig=go.Figure()#Create dictionary for ease of access
df_dict={"points":df[["Squad","Pts"]],
"goal_difference":df[["Squad","GD"]],
"goals_scored":df[["Squad","GF"]],
"goals_conceded":df[["Squad","GA"]],
"matches_won":df[["Squad","W"]],
"matches_drawn":df[["Squad","D"]],
"matches_lost":df[["Squad","L"]]}
在这一步,我需要为下拉菜单创建一个按钮列表。为此,我初始化了一个名为dropdowns
的空列表和一个计数器i
。使用 for 循环,我为每个指示器创建一个名为dropdown
的按钮对象。该按钮还包含一个名为args
的布尔值(真/假)列表,它告诉根据真值显示哪个轨迹。
所有的按钮对象都被追加到dropdowns
列表中。如下图所示,对于第一个字典,只有列表中的第一项在更新时可见。对于第二个字典,它是列表中可见的第二个项目,依此类推。
下拉列表 由每个指标组成的列表作为标签,“更新”作为方法,True/False 作为可见参数。(图片由作者提供)
最后,为了更新绘图的布局,我指定了(x,y)坐标,我想要的dropdowns
按钮的位置,以及我想要菜单弹出的方向。
我得到了一个基本的交互式仪表板,如下所示。
带有西甲 2020/21 统计数据的仪表板
分析
在西甲 2020/21 赛季总共 38 场比赛之后,马竞以 86 分的成绩成为冠军。皇家马德里以 84 分接近第二,巴塞罗那以 79 分排名第三。排名前三的俱乐部分别赢得了 26 场、25 场和 24 场比赛。巴塞罗那以 85 个进球成为联赛中进球最多的球队,冠军和亚军各进 67 个球。然而,巴塞罗那也是三支球队中防守最差的,在同样多的比赛中丢了 38 个球。虽然巴塞罗那在三个俱乐部中净胜球最多,但输掉七场比赛和七场平局对俱乐部来说是非常昂贵的。
结论
在这篇文章中,一个简单的西甲比赛和基本统计数据的分析是在一个动画线图比赛和使用 Plotly 的仪表板的帮助下进行的。除了对数据有一个整体的了解之外,Plotly 的交互功能对于从图中获得准确的信息非常有用。交互式功能、地图、动画等。可以通过其开源图形库访问。
用 R 分析李氏对策
使用 ANOVA 和 Bootstrapping 揭示游戏洞察力
国际象棋历史悠久,可以追溯到 1500 年前。然而,由于在线游戏的激增,这款游戏直到最近才成为数据分析的宝库。
玩家经常会有很多问题,比如随着时间的推移,一个人的评级可以提高到什么程度,什么样的开局与胜利最相关,等等。
然而,一个经常被争论的问题是,在任何特定的游戏中,白棋是否由于先走而比黑棋有优势。
也就是说,这个问题的答案并不明确,因为在任何特定游戏中的表现都取决于棋手的能力。一个 Elo 评分为 900 的玩家下白棋将很难击败一个 Elo 评分为 2000 的玩家下黑棋——即使前者有先发优势。
初步分析
为了获得关于这个问题的更多见解,我决定分析来自 database.lichess.org的数据,该公司根据知识共享 CC0 许可证提供其数据。
具体来说,我决定从 2013 年 2 月的数据库中抽取 650 个不同的样本(游戏),以更详细地分析每个游戏的结果和评分变化。
在所玩的一系列游戏中,Elo 评分在白人和黑人玩家中的分布或多或少遵循了我们倾向于在整体评分中看到的正态分布曲线。
来源:RStudio 输出
在这 650 场比赛中,我们看到白棋赢的比输的多,但只是很少:
资料来源:作者的计算
然而,更有趣的是每场比赛后玩家评分的波动。例如,如果输了一场比赛,输的玩家可能会失去 10 分,而赢的玩家可能会得到 15 分,等等。
一般来说,两个玩家之间的收视率差距越大,收视率变化就越深刻。例如,如果排名 1200 的玩家赢了排名 2000 的玩家,则随后的评级变化将比该玩家与类似级别的人比赛时高得多。
来源:RStudio 输出
从本次分析中使用的 650 个游戏样本中,我们可以看到,我们获得了在特定游戏中玩白棋和黑棋的玩家的总体评级,以及每个玩家的评级波动,这取决于他们在特定游戏中是赢是输。
查看一些收视率波动的汇总统计数据,会发现一些非常有趣的事情:
资料来源:作者的计算
在这 650 场比赛中,白人的平均收视率变化明显低于黑人。平均而言,白人每场比赛的收视率下降了 3.24,而黑人每场比赛的收视率上升了 0.55。
方差分析和自举
让我们更详细地探讨这一点。
首先,进行 ANOVA 测试,以确定玩白色游戏的人和玩黑色游戏的人之间的评分变化的均值差异是否显著。
>>> anova <- aov(df$blackratingdiff ~ df$whiteratingdiff)
>>> summary(anova) Df Sum Sq Mean Sq F value Pr(>F)
df$whiteratingdiff 1 77223 77223 65.99 2.3e-15 ***
Residuals 648 758311 1170
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
根据 ANOVA 检验,平均值的差异具有统计学意义。
假设我们的样本量是 650,我们假设这个样本代表了象棋游戏的总体。利用这一假设,我们希望使用 bootstrapping 生成评级波动的抽样分布,即带有替换的随机抽样。在这种情况下,替换意味着可以从样本中不止一次地选择一个观察值。
具体来说,我们将对 30,000 个 bootstraps 进行重新采样,以检查随着样本的增加,95%的置信区间会是什么样子。例如,bootstrap 样本将显示一个评级变化分布,我们可以 95%确信它包含总体均值。
这是针对白色和黑色评级波动而进行的。
使用随机抽样替换两组间的等级变化,生成了白色等级(称为 x )和黑色等级(称为 y )的样本。
x<-sample(df$whiteratingdiff, 650, replace = TRUE, prob = NULL)
xy<-sample(df$blackratingdiff, 650, replace = TRUE, prob = NULL)
y=
使用引导库,可以生成 30,000 个引导。
library(boot)boot_mean <- function(original_vector, resample_vector) {
mean(original_vector[resample_vector])
}# R is number of replications
mean_results <- boot(x, boot_mean, R = 30000)
mean_results
白色等级分布
以下是为白色生成的自举置信区间。
BOOTSTRAP CONFIDENCE INTERVAL CALCULATIONS
Based on 30000 bootstrap replicatesCALL :
boot.ci(boot.out = mean_results)Intervals :
Level Normal Basic
95% (-7.674, -0.569 ) (-7.445, -0.346 )Level Percentile BCa
95% (-7.875, -0.777 ) (-8.523, -1.157 )
Calculations and Intervals on Original Scale
95%置信区间表示总体均值位于 -7.647 和 -0.569 之间。这是分布的图示。
来源:RStudio 输出
黑色评级分布
以下是为 black 生成的 bootstrap 置信区间。
BOOTSTRAP CONFIDENCE INTERVAL CALCULATIONS
Based on 30000 bootstrap replicatesCALL :
boot.ci(boot.out = mean_results_2)Intervals :
Level Normal Basic
95% (-2.3838, 3.4096 ) (-2.3830, 3.3846 )Level Percentile BCa
95% (-2.3354, 3.4323 ) (-2.2885, 3.4720 )
Calculations and Intervals on Original Scale
95%的置信区间表示总体平均值位于 -2.38 和 3.4 之间。这是分布的图示。
来源:RStudio 输出
bootstrap 样本生成的分布非常有趣。平均而言,那些在任何特定游戏中扮演白人的人可能会看到他们的评分平均下降,而那些扮演黑人的人则会看到平均上升。
当然,我们必须注意这样一个事实,即平均值受到分布两端的极端评级变化的影响。当我们根据初步分析分析评分变化的汇总统计数据时,我们发现,虽然白人评分的平均变化为负,黑人评分的平均变化为正,但评分的中值变化却显示出相反的情况。
那么,我们能从这些发现中得出什么结论呢?如果假设白棋有先发优势,是否可以推断出能和黑棋一起赢的玩家(特别是在高等级游戏中)总体上更强?
从目前为止的数据来看,这并不一定是结论性的,这将保证一项单独的研究,即是否持续拥有较高黑棋胜率的玩家比拥有较高白棋胜率的玩家表现出更高的评级。
限制
虽然上述发现是有趣的,但当以这种方式分析国际象棋评级时,当然存在局限性。
首先,bootstrapping 技术假设选择的 650 个样本代表总体。虽然 650 是一个很大的样本量,但与历史上大量的国际象棋比赛相比,这只是沧海一粟。
虽然 bootstrap 是推断抽样分布特征的一种非常有用的工具——拥有人们可能认为的大样本量并不一定万无一失,如果收集的数据存在任何偏差,那么 bootstrap 抽样的结果也会如此。
此外,值得记住的是,在这个特定的数据集中,有许多一个玩家用两种颜色玩多种游戏的例子。如果一个球员特别有天赋,并且赢了所有他们穿黑白球衣的比赛,那么这更多的是一个强大球员的标志,而不是他们穿的颜色。
结论
希望你喜欢这篇文章!最近我又回到了国际象棋,我想这可能是一个利用统计分析收集更多关于游戏的见解的好机会。
这里有棋手希望提供任何评论或反馈吗?如果你对我的发现或如何改进分析有任何建议,我很乐意听到你的意见。
概括地说,本文涵盖了:
- 如何用 R 来分析博弈
- 方差分析在确定样本均值差异是否显著中的意义
- 自举在估计统计量的抽样分布中的作用
非常感谢您的宝贵时间,再次感谢您的任何问题或意见。
参考
- cran . r . project . org:Package ’ boot ’
- 【lichess.org 开放数据库
免责声明:本文是在“原样”的基础上编写的,没有任何担保。它旨在提供数据科学概念的概述,不应被解释为专业建议。本文中的发现和解释是作者的发现和解释,不被本文中提到的任何第三方认可或隶属于任何第三方。作者与本文提及的任何第三方无任何关系。
利用在线评论评估文化旅游的质量
思想与理论,社交媒体和网络评论能否超越一般的情绪?
意大利博物馆的经历
在文化旅游领域,人们对采用数据驱动的方法越来越感兴趣,这些方法旨在通过在线评论衡量服务质量。在线评论长期以来一直是旅游领域数据分析的宝贵来源,但这些数据源主要是根据评论平台提供的数字评级进行研究的。
自顶向下与自底向上数据驱动的质量评估
在最近的一篇文章中,我们探讨了社交媒体和在线评论平台是否可以成为量化评估文化场所(如博物馆、剧院等)服务质量的良好来源。本文应用在线评论的自动分析,通过比较两种不同的自动分析方法来评估哪一种更适合评估质量维度。该分析涵盖了用户对意大利前 100 家博物馆的评论。
具体来说,我们比较两种方法:
- **基于监督分类的“自上而下”方法,监督分类基于国家一级政策制定者指南所定义的战略选择;**还有
- 一种**“自下而上”的方法,基于评论者在线词汇的无监督主题模型**。
我们比较了由此产生的博物馆质量维度,表明与通过“自上而下”方法获得的结果相比,“自下而上”方法揭示了额外的质量维度。
“自上而下”的战略研究和“自下而上”的数据驱动方法的结果不一致,凸显了数据科学如何为文化旅游的决策做出重要贡献。
关于质量维度的问题
该研究解决了以下三个问题:
- 从战略的、集中的角度来看,哪些博物馆质量维度是按照“自上而下”的方法确定的?
- 哪些博物馆质量维度是根据在线评论中“自下而上”的数据驱动方法确定的?
- 这两种方法中的质量维度有什么不同?
在“自上而下”的方法中,**由决策者(即国家一级的政策制定者)**定义一组预定义的维度,我们使用基于关键字的分类器来分析在线评论文本中的预期维度。
在“自下而上”的方法中,潜在的质量维度已经通过依靠无监督的主题分析从游客体验的文本描述中直接导出,而没有强加一组预定义的质量维度。
决策者选择的质量维度可能与博物馆参观者感知的质量维度非常不同。
数据集准备和探索
在线评论的数据是从意大利文化遗产、活动和旅游部确定的前 100 家意大利公共博物馆的猫途鹰网页上收集的。一旦收集,在线评论通过语言检测阶段得到丰富。最后,这两种分析方法都应用于 14,250 篇意大利评论的同一数据集。
2019 年 100 家意大利博物馆的评论和评级[图片由作者提供]
自上而下的方法
自上而下的方法是指决策者根据主观选择对要考虑的服务/产品的质量进行衡量。
在我们的实证背景下,决策者由政策制定者“意大利文化遗产和旅游部”代表,该部在 2018 年推出了一套公共博物馆的质量标准。基于该指南和对政策制定者的采访,我们确定了遵循“自上而下”观点的五个质量维度:票务和欢迎、空间、舒适度、活动、和沟通。这些维度中的每一个都被认为是用户评论分类问题中的一类。自上而下的方法允许我们将每个评论标记为对这 5 个维度之一的描述。
分类已经被实现为机器学习分类问题和基于关键字的标记(即,每个维度与预期代表该维度的一组关键字相关联)。特别是,我们将基于关键字的分类器与来自 Transformers (BERT) 语言模型的双向编码器表示进行了比较。通过人工标记的 1,000 条评论来检查性能。基于关键词的方法在五类( 表 2 )中获得了 80%的平均准确率和 50%的召回率,而 BERT 方法获得了 88.2%的准确率和 58%的召回率。这种方法的缺点是数据在类间高度不平衡。
应用“自上而下”方法识别在线评论中博物馆质量维度的结果示例(多级软分类)。[图片由作者提供]
自下而上的方法
“自下而上”的方法利用在线评论,而没有关于访问维度的预定义预期;相反,它是基于直接从评论者的话语中获得体验的潜在维度,而没有任何预先定义的期望。
从分析的角度来看,“自下而上”的方法是通过无监督的主题建模方法实施的,即 LDA(潜在狄利克雷分配),在多达 30 个主题的范围内实施和调整。我们选择的最好的“自下而上”模型,确定了评论文本中的 13 个潜在维度。
为了获得更好的可解释性,我们将讨论的潜在主题手动分组为博物馆质量的三个主要“自下而上”的维度,我们将其解释为博物馆文化遗产、个人体验和博物馆服务。
应用“自下而上”方法的结果示例。[图片由作者提供]
结果和比较
至于详细的结果,我想让读者阅读全文,这里我总结一下主要的发现。
游客的大部分注意力不是集中在服务上,而是博物馆的实际内容质量。
很大一部分评论内容无法归类到服务类别中。[图片由作者提供]
- “自上而下”的方法(基于政策制定者发布的标准中定义的一组关键字)导致 63%的在线评论不符合任何预定义的质量维度;
- “自下而上”的数据驱动方法通过使用评论者自己的话搜索感兴趣的方面来克服这一限制,甚至不知道有多少或哪些可能是博物馆的质量维度;
- 特别是,当分析标记为其他方面的评论时,“自下而上”的分析以 21%的平均概率识别出博物馆服务。这意味着决策者也能够通过“自下而上”的方法发现与服务质量相关的其他方面;
- 基于主题分析,我们看到博物馆评论更多地讨论博物馆的文化遗产方面(46%的平均概率)和个人经历(31%的平均概率),而不是博物馆提供的服务(23%的平均概率);
- 这意味着游客的大部分注意力不是集中在服务上,而是博物馆的实际内容质量。
“自下而上”的博物馆质量维度在通过“自上而下”方法分类为“*其他方面”*的评论中的分布。[图片由作者提供]
TL;速度三角形定位法(dead reckoning)
在本研究的各种定量发现中,我认为最重要的一点是,决策者认为是质量维度的方面可能与博物馆游客认为是质量维度的方面有很大不同:在博物馆的特定环境中使用“自上而下”的方法,大多数评论(63%)与决策者定义的博物馆服务质量维度无关,因为博物馆游客不仅仅看重博物馆服务的质量维度(23%),而是更重视文化遗产(46%)和个人体验(31%)。
你可以通过阅读在线发表的开放获取的完整文章找到更多关于这个分析的信息。该论文的完整参考文献是:
阿戈斯蒂诺博士;布朗比拉,m。帕瓦内托;丽娃,p。在线评论对文化旅游产品质量评估的贡献:意大利博物馆的经验。持续性 2021 , 13 ,13340。https://doi.org/10.3390/su132313340
欧洲五大国内联赛传球分析
使用 worldfootballR 软件包分析欧洲五大国内足球联赛中不同的传球行为
足球经常被称为“美丽的运动”,因为不同国家之间错综复杂的比赛风格而变得更加美丽。
这篇文章旨在开始探索欧洲五大国内联赛比赛风格的一些差异。作为参考,当我们提到前五名时,我们指的是以下国内联赛:
- 足球-德甲(德国)
- 西甲(西班牙)
- 法甲联赛(法国)
- 英超联赛(英格兰)
- 意甲(意大利)
具体来说,这篇文章将集中在传球上,并分析这些联盟中的球队如何在球场上运球是否有任何差异。
这一块的数据来自 fbref ,来自worldfootballR
R 包。这个包目前可以从 GitHub 安装,这里的库是。
尝试和完成传球
首先,我们将注意力转向每 90 分钟足球比赛中传球次数最多的联赛。
除了意甲在 2017-18 赛季的传球尝试次数最高之外,德甲在传球尝试次数方面占据了最高地位,本赛季的传球尝试次数最高(514 次)。
法甲球队继续增加传球尝试,本赛季首次超过了 EPL 和意甲。有趣的是,在 2017–18 赛季,英甲和西甲同样是传球率最低的联赛,在短短的三年时间里,各自的联赛在传球尝试上出现了分化。
进一步深入分析联赛赛季中的各个球队,可以看出,尽管德甲和 EPL 的传球率最高,但它们的可变性也最高,每个联赛中传球率最高和最低的球队之间的差异最大(尽管西甲的可变性最大)。
完成率
尝试传球无疑对比赛很重要,但有人会说完成传球更重要。
下面的方框图显示,总的来说,每个联赛的球队在过去四年中都增加了传球完成率(尽管德甲有些停滞)。
意甲球队一直比其他联赛的球队有更高的传球准确性,而西甲则是所有联赛中完成率变化最大的球队——毫无疑问,这是由马德里队和巴萨以及联赛其他球队之间的巨大质量差异所驱动的。
为什么这很重要?
从下面可以看出,在一个赛季中尝试更多传球的球队往往会积累更多的联赛积分,变量之间有相当强的正相关性。以下数据不包括当季。
这对于 EPL 相关性(0.829)、德甲(0.805)和意甲(0.796)来说更是如此,而对于西甲和法甲来说,这种相关性并不那么强。
通行证往哪个方向走?
所以,我们已经看到了不同联盟之间在将球传给队友的频率和成功程度上存在一些差异。当他们传球时,球的行进方向是怎样的?
为此,我们可以查看已完成传球的渐进距离(以码为单位),并将其与所有已完成传球的总码数进行比较。fbref 将累进码定义为:
完成的传球朝向对方球门的总距离,以码为单位。注意:远离对手球门的传球被算作零码
得出的数字表明每完成一码传球,球前进了多少码码。一个较高的数字表示一个队更直接地移动球,而一个较低的数字表示一个队更大比例的完成传球码不像对手的球门那样直接。
联赛传球不那么直接?
联赛已经逐渐远离更直接的传球路线,EPL 领先(每完成总码数 0.319 个累进码),而西甲最不直接,每完成总码数 0.339 个累进码。
就像联赛积分和传球尝试之间的相关性一样,在直接性和联赛积分之间似乎也有关系,然而这种关系是负面的,这意味着传球不太直接的球队也往往在赛季末获得更多的联赛积分。
此外,这种关系并不是所有的联盟都如此。这种关系在 EPL(相关系数为-0.711)和意甲(-0.706)中相当强,而在西甲中最弱(-0.402)。
我们也可以看看那些直接传球最多和最少的单个球队赛季。
下面列出了过去四个赛季中最不直接的 20 支球队,榜首由 EPL 俱乐部占据,特别是曼城,他们占据了前六名中的四个席位。
有趣的是,这份名单上的队伍似乎比排名靠后的队伍更接近榜首,这加强了我们上面的相关性。
同样,我们也可以看看最近四个赛季最直接传球的 20 支球队。
这些俱乐部的最终排名看起来更接近他们的积分榜底部(西甲 2018-19 赛季的赫塔菲和德甲 2018-19 赛季的莱比锡是明显的例外)。
卡迪夫城唯一的英超赛季是最直接的传球赛季,每完成传球码数 0.464 递进码。
虽然欧洲五大国内联赛之间的传球活动没有太大的差异,但仍然有一些差异,看看他们的联赛在未来几年如何演变将是有趣的。
一如既往,任何反馈或意见都将在评论区得到重视,或者随时在 Twitter@ jaseziv上联系。
这个完整的帖子最初出现在 dontblamethedata.com。这篇文章的代码可以在这里找到。
用 PyMC3 分析后验预测分布
实践教程
使用 PyMC3 模拟后验分布
来源:图片来自 Pixabay
贝叶斯分析的主要目的是在给定不确定性的情况下对数据进行建模。
由于人们无法获得关于一个群体的所有数据来确定其精确的分布,因此经常会做出相同的假设。
例如,我可能会对某个国家人口的平均身高做一个假设。这是一个先验分布,或者是一个建立在先验信念基础上的分布,在此之前,我们先来看看可以证明或否定这个信念的数据。
在分析一组新数据(似然函数)时,可以将先验信念和似然函数结合起来形成后验分布。
来源:图片由作者创建
让我们看看如何使用 PyMC3 来模拟这样的分布。
用 PyMC3 分析身体质量指数数据
在本例中, Pima Indians 糖尿病数据集用于模拟大量患者(其中一些是糖尿病患者,一些不是)的体重指数数据。
在查看数据之前,需要建立一个关于该数据的均值和标准差的先验信念。鉴于数据集中相当多的患者是糖尿病患者,那么人们可以形成一种先验信念,即平均身体质量指数高于平均水平。
螺母(不掉头取样器)
在这方面,我们先假设平均身体质量指数为 30 ,相对较小的标准偏差为 2,表明我们不希望在个别情况下偏离平均值太多。
mu_prior=30
sigma_prior=2with pm.Model() as model:
mu = pm.Normal("mu", mu=mu_prior, sigma=sigma_prior)
sd = pm.HalfNormal("sd", sigma=sigma_prior)
obs = pm.Normal("obs", mu=mu, sigma=sd, observed=data)
idata = pm.sample(1000, tune=1500, return_inferencedata=True)
使用 3.1 版本。采样模板来自 PyMC3 通用 API 快速入门手册,NUTS(不掉头)采样器用于从每个链的后部抽取 1000 个样本,然后允许在额外的 1500 次迭代中进行重新调整。注意,在生成后验分布时,除了先验均值和标准差之外,模型还考虑了观察数据*(观察=数据)*。
NUTS 是蒙特卡罗马尔可夫链(MCMC) 算法的一种形式,它绕过随机游走行为,允许更快地收敛到目标分布。这不仅具有速度优势,而且允许拟合复杂的模型,而不必使用关于这些拟合方法的理论的专业知识。
解释
使用 **arviz,**下面是生成的后验图:
来源:Jupyter 笔记本输出
还提供了分布的统计摘要:
来源:Jupyter 笔记本输出
请注意, 31.949 的平均值略高于之前的估计,而标准偏差在 7.823 处明显更高。
考虑到这些数据,事后看来,标准差高于最初的预期是有道理的。
毕竟,数据集中的许多患者都不是糖尿病患者。此外,尽管人们可能认为身体质量指数和糖尿病之间存在正相关,但这是基于先前的信念——如果不查看数据,我们没有确凿的证据证明这一点。
考虑到更新的平均值和标准偏差,下面是更新的后验分布:
来源:Jupyter 笔记本输出
我们可以看到,离差高于最初的预期。也就是说,如果数据本身并不总是十分准确呢?例如,没有人的身体质量指数可以为 0,但由于某种未知的原因,数据中存在许多 0 身体质量指数值。
然而,先验值的说明——以及数据中的大多数其他值——表明这种观察是极不可能的。在这方面,后验预测分布显著下降到 20 以下(数据中观察到的最低身体质量指数值为 18.2)。
重温先前的信念
当我们第一次形成对身体质量指数的先验信念时,估计的平均值与实际值相差不远。
然而,如果我们先前的信念完全偏离了目标呢?假设我们估计平均身体质量指数为 50,标准差为 2?
生成的后验分布如下:
来源:Jupyter 笔记本输出
即使存在不准确的先验信念,采样器也可以认识到这完全偏离了相对于实际观察到的数据的标记,并且相应地更新分布。
在新数据采用不同于先前模式的分布的情况下,这也非常有用。例如,一个公司的经理可能会根据经验假设某一年的产品销售倾向于显示某一平均值和标准偏差,但随后的数据与前几年的数据不同。在这方面,后验分布允许更新管理者的先前信念,以反映正在观察的新数据。
结论
后验分布允许在生成这种分布时通过考虑新的证据(或数据)来更新先前的信念。
在本例中,您已经学习了:
- 先验分布和后验分布之间的差异
- 如何用 PyMC3 模拟后验分布
- 如何用阿尔维兹解读后验情节
- 先验信念和似然函数在生成后验分布中的作用
非常感谢您的时间,任何问题或反馈都非常欢迎。你也可以在 michael-grogan.com 找到更多我的数据科学内容。
免责声明:本文是在“原样”的基础上编写的,没有担保。它旨在提供数据科学概念的概述,不应被解释为专业建议。本文中的发现和解释是作者的发现和解释,不被本文中提到的任何第三方认可或隶属于任何第三方。