TowardsDataScience-博客中文翻译-2021-七十一-
TowardsDataScience 博客中文翻译 2021(七十一)
原文:TowardsDataScience Blog
协议:CC BY-NC-SA 4.0
协同过滤推荐系统中用 SVD 预测评分的一个例子
原文:https://towardsdatascience.com/predict-ratings-with-svd-in-collaborative-filtering-recommendation-system-733aaa768b14?source=collection_archive---------15-----------------------
如何将奇异值分解转换为 k 维并进行预测

来自维基的乔治-约翰的照片
我们知道 SVD 在现实中进行预测有缺点,例如,它甚至不能预测数据集中是否有 NaN,但因为这是协作过滤的起点,我想用 SVD 重现这个过程,看看它是如何工作的,并对数据集进行一些压缩。
这个故事将集中在 SVD 的代码实现上,没有离线测试(没有训练测试数据集的分割),并且包括一些与线性代数相关的基本术语。
线性代数基础
奇异值分解是奇异值分解。详细说明见维基。在这里,我更喜欢推荐系统(RS)的这种解释:它是原始 SVD 的 k 阶近似。

来自 StackExchange 的信息[3]
潜在特征:对应于 SVD 中的σ。在数据中不能直接观察到的值,但当查看观察到的数据值之间存在的关系和趋势时,可能会识别出这些值[2]。最新特征的数量是西格玛在 SVD 中的等级。
欧氏距离:
欧几里德距离可以看作是两个向量之间的直线距离。对于两个向量 x 和 y ,我们可以计算为[2]:

我想强调的难点(至少从我的学习经验来看)是一旦我们知道了 U、σ和 Vt,如何将原始的 SVD 转换成 k 维空间,以及如何将它们与预测联系起来。榜样永远是有效的学习方式。
代码示例
数据集妥协
协作过滤(这里是基于用户项的)中的 RS 的目标是预测评级,并且在用户没有评级的情况下做出推荐。
但是 SVD 无法预测矩阵中是否有 NaN 值,用户必须存在于当前已知的费率系统中并给出费率。
我觉得有矛盾,但也许我错在这里(如果你找到原因,会感激地指出来)。
要创建数据集,这里折衷:如果用户没有给电影评分,那么用 0 填充(如果评分中有 0,就会有冲突)。
请不要在此处推荐 Funk SVD。因为我想在这个故事中了解 SVD 过程的优点和缺点。
让我们开始吧。参考代码在这里(中文)【1】。我对它做了一些修改。
该代码由以下步骤组成:
- 创建数据集
- 计算相似度
- 决定 k
- 将原始 SVD 转换为 k 维
- 通过预测评分(原始评分为零)为特定用户进行推荐
导入库:
创建数据集:
计算相似度
使用欧几里德距离来度量相似性:
决定 k:k 的值由前 k 个奇异值的平方和占总奇异值平方和的百分比决定。
例如,如果百分比是 0.9,那么当前 k 个单值的平方和与 sigma 的总平方和之比大于 0.9 时,我们已经占了 90%以上的权重,可以将矩阵降维到 k 维。
将原始 SVD 转换为 k 维空间:
如何将原始 SVD 转换为 k 维,下面是关键:
原始分解的维数为:
u:11x11,sigma:对角矩阵 11,vt: 11x11
结果是 k=3,则量纲为:
u:11x3,sigma:对角矩阵 3,vt: 3x11
下面的代码可以构造 k 维矩阵:
formed_items=np.around(np.dot(np.dot(u[:,:k], sigma_K),vt[:k, :]),decimals=3)
预测收视率:
运行以下命令获得结果:
testdata=loadExData()
recommend(testdata,0,sim_meas=ecludSim,est_method=svdEst, percentage=0.9)
使用具有欧几里德距离的测试数据,如果前 k 个奇异值的平方和与总奇异值的平方和的百分比大于或等于 0.9,则预测用户 0 的未分级电影的分级。
用户 0 的预测评级:

对于用户 1:

第一列显示列索引,第二列是预测评级。
在用户 0 的原始数据中,位置 0,1,2,3,4,6,7,8,9 为零,如下所示:
[0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5]
为了简单起见,完整的代码如下,您可以使用上面的最后两个建议来运行它:
在今天的故事中,我介绍了一个例子,展示了如何在获得 SVD 后将 SVD 转换到 k 维空间来预测收视率,特别关注如何将 SVD 转换到 k 维空间并进行预测收视率。
感谢您的阅读。
参考文献:
- https://blog . csdn . net/weixin _ 41988628/article/details/83217255
- Udacity 数据科学家 Nanodegree —实验设计和建议
- https://stats . stack exchange . com/questions/33142/what-happens-when-you-apply-SVD-to-a-collaborative-filtering-problem-what-is-th/35460 # 35460
- 【https://en.wikipedia.org/wiki/Singular_value_decomposition 号
预测 HDB 转售公寓的售价
原文:https://towardsdatascience.com/predict-the-selling-price-of-hdb-resale-flats-50530391a845?source=collection_archive---------12-----------------------
进行线性回归以预测 1990 年 1 月至 2021 年 4 月 HDB 转售单位的售价

照片由 Nguyen Thu Hoai 在 Unsplash
问题陈述
有多种因素影响 HDB 转售公寓的销售价格。因此,通过使用线性回归,我有兴趣在这个小练习中找出 HDB 转售公寓的销售价格如何基于其以下特征而变化:
- 它到中央商务区(CBD)的距离
- 到最近的捷运站的距离
- 它扁平的尺寸
- 它的楼层
- 剩余的租赁年数
这个小练习的参考资料可以在 my GitHub 上找到,其中包括数据集和 Python 笔记本文件——数据预处理和数据处理(包括构建线性回归)。
资料组
以下是这个小型练习中使用的数据源:
- 来自 Data.gov.sg 的 HDB 转售统一价格(截至 2021 年 5 月 3 日)
- OneMap API
数据预处理
HDB 转售统一价格数据集中有 5 个不同时间段的逗号分隔值(CSV)文件,分别为 1990 年至 1999 年、2000 年至 2012 年、2012 年至 2014 年、2015 年至 2016 年以及 2017 年以后。
在这个小练习中,分析中考虑了所有时间段。因此,需要将所有 5 个不同的 CSV 文件组合成一个完整的数据集。
import glob
import pandas as pddf = pd.concat([pd.read_csv(f) for f in glob.glob("./data/*.csv")], ignore_index=True)

原始 HDB 转售统一价格数据集的样本行,按作者分类的图像
正如我们从数据集看到的,它还不够全面,不足以回答这个迷你练习的问题陈述。此后,需要计算今年(2021 年)以后的剩余租约,并使用 OneMap API 进行地理编码,以计算每个公寓与其最近的 MRT 站之间的距离,以及每个公寓与 CBD 之间的距离(基于莱佛士广场)。
在进行地理编码之前,原始数据集的缺失值和重复值将被移除。此外,构建每个 HDB 公寓的地址,以便检索其地理位置。
df['address'] = df['block'] + " " + df['street_name']
address_list = df['address'].unique() # to be iterated in order to retrieve the geo-location of each address
使用 JSON 请求进行地理编码,以进行查询,从而获得每个 HDB 公寓的地理位置和捷运站的地理位置,如下图所示。有了这些,我们可以计算出每套公寓和最近的捷运站之间的距离。此外,根据所有 HDB 公寓的地理位置,我们可以计算出每套公寓与中央商务区之间的距离。
以下是从 OneMap API 中检索数据的代码模板,以及用作检索其地理位置的列表的捷运站。
import json
import requestsquery_string = '[https://developers.onemap.sg/commonapi/search?searchVal='+](https://developers.onemap.sg/commonapi/search?searchVal='+'Raffles)query_address+'&returnGeom=Y&getAddrDetails=Y' # define your query_address variable (e.g. HDB address)
resp = requests.get(query_string)
data = json.loads(try_resp.content)

数据预处理地理编码中使用的新加坡捷运站(来源:陆地运输局)
我们数据集的最后一个板块是计算从今年开始每套公寓的剩余租金。HDB 租约为 99 年,为了计算剩余租约,使用了一个新变量,定义如下:
df['lease_remain_years'] = 99 - (2021 - df['lease_commence_date'])
哒哒!生成了新的已处理数据集!

带有样本行的新组合数据集,按作者列出的图像
数据争论
处理新生成的数据集的一个必要步骤是确保每个变量分别处于正确的数据类型中。
df['resale_price'] = df['resale_price'].astype('float')
df['floor_area_sqm'] = df['floor_area_sqm'].astype('float')
df['lease_commence_date'] = df['lease_commence_date'].astype('int64')
df['lease_remain_years'] = df['lease_remain_years'].astype('int64')df.dtypes
其中一个要考虑的因素是楼层。楼层变量是具有不同楼层范围的分类变量。

楼层范围,作者图像
因此,中位值用于绘制每套 HDB 公寓的楼层平面图。
import statisticsdef get_median(x):
split_list = x.split(' TO ')
float_list = [float(i) for i in split_list]
median = statistics.median(float_list)
return mediandf['storey_median'] = df['storey_range'].apply(lambda x: get_median(x))
现在是时候提取回答问题陈述的相关变量作为我们的新数据框架,用于构建线性回归模型。
#cbd_dist = CBD distance
#min_dist_mrt = Distance to the nearest MRT station
#floor_area_sqm = Flat size
#lease_remain_years = Remaing years of lease
#storey_median = Floor level
#resale_price = Selling price (dependent variable)df_new = df[['cbd_dist','min_dist_mrt','floor_area_sqm','lease_remain_years','storey_median','resale_price']]
相关分析

相关变量的相关矩阵,作者图像
综上所述,我们可以推断楼层大小对转售价格的影响关系最大,因为这种关系是正的适度的。距离最近的捷运站的距离对转售价格的影响最小,因为这种关系是负的弱的。无论是正相关还是负相关,影响转售价格的其他变量的强度都是适中。
线性回归
最新的数据集将被分成 75%的训练数据集和 25%的测试数据集。在这个小练习中,因变量(y)是转售价格变量,而其他变量是自变量(X)。
from sklearn.model_selection import train_test_splitX=scope_df.to_numpy()[:,:-1]
y=scope_df.to_numpy()[:,-1] #resale_price is at the last column of the latest datasetX_train, X_test, y_train, y_test = train_test_split(X,y,random_state=42,test_size=0.25)
现在,是时候建立线性回归模型了!
from sklearn.linear_model import LinearRegressionline = LinearRegression()
line.fit(X_train,y_train)line.score(X_train, y_train) # 0.8027920069011848
该模型的 R 平方得分为 0.803,实际上被认为相当不错!
让我们进一步检查模型的结果——均方误差(MSE)、系数的统计显著性、平均绝对误差(MAE)和均方根误差(RMSE)以及方差膨胀因子(VIF)。
def MSE(ys, y_hats): # Mean Squared Error function
n = len(ys)
differences = ys - y_hats
squared_diffs = differences ** 2
summed_squared_differences = sum(squared_diffs)
return (1/n) * summed_squared_differencesMSE(line.predict(X_train),y_train) # 4490363021.170545
MSE 表明,平均而言,预测 HDB 转售公寓售价的误差约为 67010.171 (+/-)。

使用 MSE 预测 HDB 转售公寓销售价格的示例,图片由作者提供
MSE 可以作为一个指标来检查预测售价与实际售价的接近程度。

OLS 回归结果,图片由作者提供
从表中可以看出,模型中的 p 值为 0,小于 0.05,说明自变量与转售价格变量有统计上的显著关系。
通过回答问题陈述,该模型有助于估计影响 HDB 转售公寓售价的以下变量:
- 离中央商务区每远 1 米,售价下降 18.12 美元
- 离最近的捷运站每远 1 米,售价下降 49.04 美元
- 公寓面积每增加 1 平方米,售价就上涨 4353.13 美元
- 每剩余 1 年租约,销售价格上涨 4079.25 美元
- 每上升一层,售价就会上升 5065.95 美元

变量的统计摘要,按作者分类的图像
from sklearn import metricsmetrics.mean_absolute_error(scope_df["resale_price"], predictions)
# 51060.924629381385
np.sqrt(metrics.mean_squared_error(scope_df["resale_price"], predictions))
# 66948.4376270297
与数据集转售价格的平均值相比,MAE 相对非常小,大约是转售价格平均值的 1%。
对于 RMSE,与数据集的转售价格的平均值相比,该模型的预测将遗漏平均 66948.44 美元,其中包含约 15%的误差率。因此,模型的预测误差率相对较高。

多重共线性使用 VIF 值表,由作者提供的图像
从表中,我们可以看到 VIF 值都低于 4。因此,所有不应该相互关联的独立变量都是不相关的。
结论
总之,我们可以说,解释变量与 HDB 公寓的转售价格有着统计上的显著关系。这样,它有助于我们解释每个解释变量如何影响 HDB 转售公寓售价的变化。此外,与其他解释变量相比,HDB 公寓的楼层面积和转售价格之间的关系强度是最高的,具有积极的中度关系。然而,为了改进分析,可以考虑诸如 HDB 公寓的城镇(规划区)以及 HDB 公寓所在的政治边界等因素来回答问题陈述。
参考
https://www.channelnewsasia.com/singapore/ndr-2018-hdb-lease-99-years-flat-national-day-rally-804611
scikit-learn 中的 predict()和 predict_proba()有什么区别?
原文:https://towardsdatascience.com/predict-vs-predict-proba-scikit-learn-bdc45daa5972?source=collection_archive---------0-----------------------
如何对数据集使用predict和predict_proba方法来执行预测

金伯利农民在 Unsplash 拍摄的照片
介绍
当用sklearn训练模型(更精确地说是监督估值器)时,我们有时需要预测实际类别,而在其他一些场合,我们可能希望预测类别概率。
在今天的文章中,我们将讨论如何在数据集上使用predict和predict_proba方法来执行预测。此外,我们将探索这些方法之间的差异,并讨论何时使用其中一种方法。
首先,让我们创建一个示例模型,我们将在本文中引用它来演示一些概念。在我们的示例中,我们将使用虹膜数据集,它也包含在scikit-learn的sklearn.datasets模块中。这将是一项分类任务,我们需要根据花瓣和萼片的尺寸(长度和宽度)识别并正确预测三种不同类型的鸢尾,即刚毛鸢尾、杂色鸢尾和海滨鸢尾。
import numpy as np
from sklearn import datasets
from sklearn.neighbors import KNeighborsClassifier # Load the Iris dataset
iris_X, iris_y = datasets.load_iris(return_X_y=True)# Split Iris dataset into train/test sets randomly
np.random.seed(0)
indices = np.random.permutation(len(iris_X))
iris_X_train = iris_X[indices[:-10]]
iris_y_train = iris_y[indices[:-10]]
iris_X_test = iris_X[indices[-10:]]
iris_y_test = iris_y[indices[-10:]]# Instantiate and fit a KNeighbors classifier
knn = KNeighborsClassifier()
knn.fit(iris_X_train, iris_y_train)
predict()方法
scikit-learn中的所有监督估计器都实现了predict()方法,该方法可以在经过训练的模型上执行,以便预测一组新数据的实际标签(或类别)。
该方法接受与将对其进行预测的数据相对应的单个参数,并返回包含每个数据点的预测标签的数组。
**predictions = knn.predict(iris_X_test)**print(predictions)
***array([1, 2, 1, 0, 0, 0, 2, 1, 2, 0])***
proba()方法
在分类任务的上下文中,一些sklearn评估器也实现了predict_proba方法,返回每个数据点的分类概率。
该方法接受与计算概率的数据相对应的单个参数,并返回包含输入数据点的类概率的列表数组。
**predictions = knn.predict_proba(iris_X_test)**print(predictions)
***array([[0\. , 1\. , 0\. ],
[0\. , 0.4, 0.6],
[0\. , 1\. , 0\. ],
[1\. , 0\. , 0\. ],
[1\. , 0\. , 0\. ],
[1\. , 0\. , 0\. ],
[0\. , 0\. , 1\. ],
[0\. , 1\. , 0\. ],
[0\. , 0\. , 1\. ],
[1\. , 0\. , 0\. ]])***
最后的想法
在今天的文章中,我们讨论了如何使用预训练的scikit-learn模型对数据进行预测。此外,我们探讨了由scikit-learn的估计器实现的方法predict和predict_proba之间的主要差异。
predict方法用于预测实际类别,而predict_proba方法可用于推断类别概率(即特定数据点落入基础类别的概率)。
成为会员 阅读介质上的每一个故事。你的会员费直接支持我和你看的其他作家。
你可能也会喜欢
https://medium.com/geekculture/fit-vs-transform-vs-fit-transform-in-python-scikit-learn-2623d5a691e3
使用机器学习预测 2020-21 年 NBA 最有价值球员
原文:https://towardsdatascience.com/predicting-2020-21-nbas-most-valuable-player-using-machine-learning-24aaa869a740?source=collection_archive---------19-----------------------
ML 模特对 MVP 比赛有什么看法?

基思·艾利森在维基共享资源上的照片
在每个赛季结束时,全国篮球协会(NBA)的媒体成员被要求决定联盟最受欢迎的个人常规赛奖的获胜者:最有价值球员(MVP)。创立于 1955-56 赛季,旨在奖励常规赛中表现最佳和最稳定的球员。
每年都会在篮球迷和分析师中引发很多争论,MVP 竞赛通常是 NBA 赛季中最有趣(也是最激烈)的故事情节之一。虽然叙述在最终决定获胜者的过程中发挥了重要作用,但它主要归结于对其团队的成功具有最大统计影响的球员。
随着本赛季的比赛超过一半,谁是真正的 MVP 候选人变得越来越清楚。但是谁最终会赢得它呢?基于已经进行的比赛和历史数据,本文的目标是使用 ML 模型预测 MVP 的结果。
数据
对于历史数据,我们利用了运球分析的数据集,它包含了从 1979-80(三分时代的开始)到 2017-18 每个赛季 MVP 投票中前 10 名球员的数据。除此之外,我们还收集了以下两个赛季(2018-19 和 2019-2020)的相同数据。
至于本赛季,我们收集了目前在 Basketball Reference 的 2020-21 NBA MVP 奖项追踪器上的 10 名球员的数据:尼古拉·约基奇、乔尔·恩比德、扬尼斯·阿德托昆博、詹姆斯·哈登、达米恩·利拉德、勒布朗·詹姆斯、科怀·伦纳德、卢卡·东契奇、凯里·欧文和鲁迪·戈贝尔。
所有的数据都可以在篮球参考上找到。
特征选择
在提到我们模型的特性之前,定义我们的目标值是很重要的。我们试图预测的目标值是每个球员获得的 MVP 总票数的份额。
Share = (MVP votes on Player)/(Total MVP votes)
至于特性,我们从总共 16 个开始:
Games
Team Wins
Overall Seed
MP
PTS/G
TRB/G
AST/G
STL/G
BLK/G
FG%
3P%
FT%
WS
WS/48
BPM
VORP
前四个是简单的统计数据。它们分别代表每个球员参加的比赛次数,他们的球队赢了多少场,他们的球队在联盟中的位置以及每场比赛的上场时间。
PTS/G,TRB/G,AST/G,STL/G,BLK/G 代表每场比赛的得分,篮板总数,助攻,抢断和盖帽。
FG%,3P%,FT%代表投篮命中率,三分命中率,罚球命中率。
WS,WS/48,VORP 和 BPM 是高级统计。WS 和 WS/48 代表赢份额和每 48 分钟赢份额。这些数据旨在将团队的成功划分到团队的个人成员身上。
BPM 代表 Box Plus/Minus,是一个衡量球员在球场上对球队贡献的指标。
最后, VORP 代表价值超过替代,是一名球员在替代级别球员之上贡献的每 100 分球队财产的积分估计,转换为平均球队,并按比例分配到 82 场比赛的赛季。
为了帮助我们决定使用哪些特性,我们拟合了一个随机 Forrest 回归,并检查了该模型的特性重要性结果。

射频特征重要性结果
接下来,我们还找到了相关矩阵。我们希望识别它们之间高度相关的特征,并删除一个以避免给模型提供重复的信息。

在研究了相关矩阵之后,我们确定了一些有意义的相关性。例如,功能总体种子与成功的数量密切负相关。没有必要使用这两个功能。我们还可以看到变量 WS 和 WS/48、BPM 和 VORP 之间的一些强相关性。这也是有意义的,因为度量 WS/48 和 VORP 分别依赖于 WS 和 BPM。
在最初的 16 个特性中,我们最终删除了其中的 7 个。我们模型的最终特征是:
Overall Seed
PTS/G
TRB/G
AST/G
STL/G
BLK/G
FG%
WS
VORP
培训和测试
为了训练和测试我们的模型,我们需要一个训练集和一个测试集。正如机器学习技术中常见的那样,两个数据集的划分是随机进行的,训练集由完整数据集的 75%组成。
我们用来评估模型在测试集上的性能的指标是均方误差(MSE)和 R 平方。
在我们的实验中,我们使用了以下模型:
- 深度神经网络(DNN)
- k 近邻回归(KNN)
- 随机福里斯特回归
下表显示了三种模型的 MSE 和 R 平方。众所周知,较低的 MSE 和较高的 R 平方表示模型更精确。

查看结果,模型没有非常高的 R 平方,但我们实现了非常低的 MSE 值。考虑到大多数 MVP 得主比他们的亚军有 0.1 以上的投票份额优势,这些都是好结果。正如我们所见,KNN 是测试集上表现最好的模型,具有最高的 R 平方和最低的 MSE。
预言
下面的 4 张图显示了每个型号对 2020–21 MVP 投票份额的预测。



我们的两个模型有 Joki 作为获胜者,一个有 Embiid。两个模特预测詹尼斯是亚军。詹姆斯·哈登在两种模式中排名第三,在另一种模式中排名第四。一个奇怪的结果:与其他模型相比,我们的 RF 模型绝对喜欢鲁迪·戈贝尔的机会(出于某种原因),在 MVP 投票份额中排名第四。

平均值显示,乔基奇以微弱优势赢得 MVP,超过詹尼斯。哈登和恩比德在份额上也遥遥领先于其余候选人。
结论
我们的模型冠乔基奇为最有价值球员,但对这个奖项的争夺仍然非常激烈。
约基奇的 MVP 案例比以往任何时候都强。除了他在球场上令人难以置信的统计影响外,小丑到目前为止参加了本赛季的每一场比赛。这是能使他从其他候选人中脱颖而出的一点。
恩比德拥有一个历史性的赛季,但他最近的受伤可能会永久性地损害他赢得比赛的机会。
詹尼斯是一个常年 MVP 候选人,如果他最终成为投票中的第一名,任何人都不会感到惊讶。
詹姆斯·哈登可以被视为这场比赛中的黑马,但不可否认的是,他的影响已经在他的新团队中感受到了。如果他保持最近的表现,他在赛季结束时肯定会成为 MVP 的有力竞争者。
很多事情仍然可以(也将会)改变,但有一点似乎很清楚:在约基奇、詹尼斯、恩比德和哈登之间,我们可以自信地预测,奖项将会颁给这些球员中的一人。
Github 资源库
预测斯堪尼亚气压系统故障
原文:https://towardsdatascience.com/predicting-a-failure-in-scanias-air-pressure-system-aps-c260bcc4d038?source=collection_archive---------15-----------------------
使用机器学习降低维护成本

图片由皮克斯拜的彼得 H 拍摄
气压系统(APS) 是重型车辆的重要组成部分,压缩空气使活塞在刹车垫上施加压力,使车辆减速。用 APS 代替液压装置的优点是容易从自然中获得可持续的空气。
该数据集包括从日常使用的重型斯堪尼亚卡车上收集的数据。这些是卡车在运行过程中的故障案例,我们的任务是预测给定的故障是否是由空气压力系统的特定组件引起的。这有助于避免卡车运行过程中的故障,从而降低维护成本。
数据可以在:https://archive . ics . UCI . edu/ml/datasets/APS+Failure+at+Scania+Trucks找到
内容:
- ML 公式
- 业务限制
- 数据集概述
- 绩效指标
- 文献评论
- 第一次切割溶液
- 入门指南
- 移除单值要素
- 处理缺失值
- 分离特征进行分析
- 直方图特征分析
- 数字特征分析
- 总结我们的探索性数据分析
- 准备数据
- 实验经典 ML 模型
- 使用 Flask API 在本地服务器上部署
- 结论
- 未来范围
- 参考
ML 公式
这是一个二元分类问题,正类告诉我们故障是由 APS 的特定组件引起的,而负类告诉我们故障与该组件无关。因此,给定一个新的数据点(传感器信息),我们可以建立一个 ML 模型,告诉我们故障是否是由卡车的 APS 引起的。
业务限制
- 延迟必须相当低,以检测 APS 中的故障并避免维护成本增加。
- 错误分类的成本非常高,因为 APS 部件未被检测到的故障会导致卡车在运行过程中出现故障,从而增加维护成本。
数据集概述
训练数据集由60000 个数据点和 171 个特征组成,其中一个是类标签。这些特征是数字数据和直方图箱数据的组合。功能名称因专有原因保持匿名*。59,000 个数据点属于负类,剩余的 1,000 个数据点属于正类。这告诉我们,我们正在处理一个高度不平衡的数据集**,并且通常是我们在真实世界场景中可以预期的数据类型。*
观察到的另一个问题是大部分数据缺失。在极端情况下,一些实例会丢失 80%的值。数据集被分类为完全随机缺失(MCAR) ,因为数据点是否缺失与数据集中的任何值是否缺失或观察到没有关系。因此,我们必须通过特征工程的方法来解决这些问题。
绩效指标
我们将使用宏 F1 分数作为我们该项目的绩效指标。宏 F1 分数考虑了每个类别的 F1 分数。基于两个类的正确分类点的数量向我们展示我们的模型的性能可能是有益的。这是有用的,因为错误分类的成本非常高,因为未被检测到的 APS 故障会导致卡车在运行期间发生故障,并增加维护成本。

宏精度、宏召回和宏 F1
文献评论
Cerqueira,Vítor 等. 将提升树与元特征工程结合起来进行预测性维护。 “智能数据分析国际研讨会。施普林格,查姆,2016。
这篇论文提到作者解决这个问题的方法包括 4 个步骤。(I)基于缺失值的数量排除特征和数据点的子集的过滤器;(ii)用于基于现有信息创建新特征的元特征工程程序;㈢处理类别不平衡问题的有偏抽样方法(SMOTE);以及(iv)使用提升的树进行分类。
缺失值百分比高的要素已被移除。在他们的分析过程中,他们发现一些特征有 80%的数据缺失,170 个特征中有 8 个有超过 50%的缺失值。在移除所述特征之后,可以看到存在重复的数据点,这表明移除的特征对于获得好的分数几乎没有影响。
他们提到,他们将该问题视为异常检测问题,因为数据的正类的特征是该领域中罕见的事件。他们在元特征工程中使用了箱线图分析(对于每个特征,将每个值与在该特征中找到的典型值进行比较)局部异常值因子(通过密度估计将数据点与其局部邻域进行比较)和分层凝聚聚类(每个步骤合并两个相似的组,合并的最后一个观察值可能是异常值)。
SMOTE 是一种复制不平衡数据集的少数类数据点的方法,以平衡它。将 SMOTE + MetaFeature 工程与 XGBOOST 库一起使用可以获得最佳结果。

来源:研究论文
本文提出了利用箱线图分析、LOF 和层次凝聚聚类来创造新特征的思想。它还向我们展示了 SMOTE 的一个使用案例,以及所有这些特征工程技术与使用 GBDT 模型相结合的结果。
科斯塔、卡蜜拉·费雷拉和马里奥·纳西门托。" IDA 2016 工业挑战赛:使用机器学习预测故障。 “智能数据分析国际研讨会。施普林格,查姆,2016。
这篇论文是这次挑战的获胜方案。作者尝试了不同的算法,即逻辑回归、K-NN、SVM、决策树和随机森林来解决这个问题。他们通过实施软估算算法来处理缺失数据。这是一个大规模矩阵完成算法,用当前猜测值替换缺失值,并解决一个优化问题。通过设置高阈值(截止值)来处理不平衡数据,这意味着模型只有在非常确定的情况下才会预测负类。
最终结果显示, Random Forest 表现最好的是,其总成本(给定指标)比基准模型低 92.56%。KNN 模型是第二好的分类器,具有 90.84%的改进,而逻辑回归模型工作良好,具有 88.72%的改进。基于 RBF 核的 SVM 仅提高了 86.36%的总成本。

来源:研究论文
本文比较了不同模型在缺失值使用更复杂的算法而不是简单的均值/中值进行估算的数据上的表现。我们看到,集合模型将很好地解决这个问题,高阈值在处理不平衡数据中起着关键作用。
首次切割方法
- 由 16,000 个数据点组成的测试数据集也可供我们使用。因此,我们不需要分割我们的训练数据集。
- 执行 EDA 并查看特征之间的相关性,并执行降维技术来检查数据在二维空间中的分布情况。
- 所有上述论文都关注这样一个事实,即大量数据缺失,数据集高度不平衡。为了处理缺失数据,我将使用链式方程多重插补(MICE)算法,该算法被证明是相当好的。我们也可以使用基于 K-NN 的插补。
- 缺失值超过 50%的特性对于模型性能的改善并不重要,因此我们可以选择删除它们。(或者我们可以选择将值归入所有特征并执行特征选择过程)。
- 每个可用要素的新二元要素集,其中 0 表示该值最初缺失,现在被估算,1 表示该值已经存在。这样我们可以保留一些关于我们收到的原始数据的信息。
- 为了处理不平衡的数据集,我们可以应用 95%的高阈值来将一个点分类为负,或者使用 SMOTE 之类的上采样方法来平衡数据集,并选择最有效的方法。
- 对于模型构建,我们可以尝试在不同的模型上工作,看看它们在不同插补方法的数据上表现如何,但从之前的工作中,我们可以看到梯度增强决策树、随机森林和朴素贝叶斯在大多数情况下都工作得很好。
- 最后,我们可以根据数据计算所有模型的性能指标,并选择最佳模型。
入门指南
首先,让我们导入所需的包并读取我们的培训数据。
数据集由 171 个要素组成,包括类别标注。此外,在类标签属性中,我们将用 0 替换“neg ”,用 1 替换“pos”。
类别分布图显示了数据不平衡的严重情况,因为在总共 60,000 个训练点中,大约 59,000 个点属于负类别,而只有 1,000 个点属于正类别。我们可以选择对少数类数据点进行上采样,或者使用改进的分类器来解决这个问题。此外,在某些特性中,缺失数据的百分比非常高(在一个特性中高达 82%)。
移除单值要素
在可用的特征中,对于所有数据点具有相同值的特征对于提高我们模型的性能并不重要。因此,我们可以丢弃这些特征。我们可以删除标准偏差为 0 的特征。
其中一个特征,(' cd_000 ' )被视为对于所有数据点都具有恒定值。我们可能会删除此功能。
处理缺失值
在对预测任务进行建模之前,识别并替换输入数据中每一列的缺失值始终是一种很好的做法。这被称为缺失数据插补,简称插补。
我们可以通过以下方式对缺失数据进行一些基本的处理:
- 我们将丢弃缺失值超过 70%的特征。
- 对于缺失值小于 5%的特性,我们可以删除那些行。
- 对于缺失值在 5–15%之间的特征,我们将使用平均值/中值估算这些缺失值。
- 现在,对于缺失值百分比在 15–70%之间的其余特征,使用基于模型的插补技术。
128 个特性的丢失值不到 5%,因此我们删除了这些特性中包含丢失值的行(4027 行)。7 个特征( 'br_000 ',' bq_000 ',' bp_000 ',' bo_000 ',' ab_000 ',' cr_000 ',' bn_000' )缺少超过 70%的值。这些功能已被删除。
然后,类标签从我们的数据集分离出来,留给我们一个形状为 (55973,162) 的数据集。
14 个特征的值有 5%到 15% 缺失,并通过 sklearn 的简单估算器,缺失值使用'中值估算。接下来,对于具有 15%到 70% 缺失值的特征,我们将执行一种基于迭代模型的插补技术,称为 鼠标 。在每一步中,具有缺失值的特征被指定为输出 y,其他特征列被视为输入 X。回归器(我们使用了岭回归器)适用于已知 y 的(X,y)。然后,回归器用于预测 y 的缺失值。以迭代方式对每个特征执行此操作,然后对 max_iter(默认为 10)插补轮次重复此操作。返回最后一轮插补的结果。
保存所有上述模型,并在测试数据集上执行预处理步骤。
分离特征进行分析
给我们的是,某些特征是直方图仓信息,并且前缀(在' _ '之前的字母)是标识符,后缀是仓 _id(标识符 _ 仓)。
为了找到包含直方图柱信息的特征,我们知道来自单个直方图的所有特征具有相同的前缀。
我们可以看到有 7 组特征,每组有 10 个箱。换句话说,有 7 个直方图被分成 10 个仓,每个仓有。例如:标识符“ag”由 ag_000、ag_001、ag_002、ag_003、ag_004、ag_005、ag_006、ag_007、ag_008 和 ag_009 组成。
直方图标识符为:['ag ',' ay ',' az ',' ba ',' cn ',' cs ',' ee']。
*There are **70 features that contain histogram bin information** and they are:
['ag_000', 'ag_001', 'ag_002', 'ag_003', 'ag_004', 'ag_005', 'ag_006', 'ag_007', 'ag_008', 'ag_009', 'ay_000', 'ay_001', 'ay_002', 'ay_003', 'ay_004', 'ay_005', 'ay_006', 'ay_007', 'ay_008', 'ay_009', 'az_000', 'az_001', 'az_002', 'az_003', 'az_004', 'az_005', 'az_006', 'az_007', 'az_008', 'az_009', 'ba_000', 'ba_001', 'ba_002', 'ba_003', 'ba_004', 'ba_005', 'ba_006', 'ba_007', 'ba_008', 'ba_009', 'cn_000', 'cn_001', 'cn_002', 'cn_003', 'cn_004', 'cn_005', 'cn_006', 'cn_007', 'cn_008', 'cn_009', 'cs_000', 'cs_001', 'cs_002', 'cs_003', 'cs_004', 'cs_005', 'cs_006', 'cs_007', 'cs_008', 'cs_009', 'ee_000', 'ee_001', 'ee_002', 'ee_003', 'ee_004', 'ee_005', 'ee_006', 'ee_007', 'ee_008', 'ee_009']*
我们将使用完整的估算集从两个数据集中选择顶级特征。但是将对具有缺失值的数据进行分析。
直方图特征分析
我们将对直方图数据集的前 15 个特征执行 EDA。为了选择特征,我们将使用随机森林分类器执行递归特征消除
前 15 个功能是:
*['ag_001', 'ag_002', 'ag_003', 'ay_005', 'ay_006', 'ay_008', 'ba_002', 'ba_003', 'ba_004', 'cn_000', 'cn_004', 'cs_002', 'cs_004', 'ee_003', 'ee_005']*
PDF 、 CDF 和框描绘了这些特征中的每一个特征的,以试图理解我们的数据的分布。提出的意见如下:
特性图 ag_003、ay_008、ba_002、ba_003、ba_004、cn_004、cs_002、cs_004、ee_003 和 ee_005 显示,特性的较低值表明 APS 部件没有故障。较高的值清楚地表明 APS 组件故障
APS 组件中没有故障时,特性 ag_001 和 ay_005 的大约 99%的值为 0。
我们可以说,在这些顶级特性中,较高的值可能表明卡车的气压系统出现故障
但是,在极少数情况下,这些值高于正常情况,但仍不会导致 APS 故障。示例:特征 ee_005
考虑到每个特征如何与目标变量(“类别”)相关,我们可以观察到特征“ay _ 005”是我们的顶级属性中最不相关的特征。我们可以进一步进行双变量分析,分析其他顶级特性相对于‘ay _ 005’特性的变化情况。
ag_002,ag_001,cn_000 :从散点图可以看出,对于其他顶级特性的任意值,当特性‘ay _ 005’中的值接近 0 时,APS 组件(class label = 1)存在故障。
数字特征分析
我们将对直方图数据集的前 15 个特征执行 EDA。为了选择特征,我们将使用随机森林分类器执行递归特征消除
前 15 个功能是:
*['aa_000', 'al_000', 'am_0', 'ap_000', 'aq_000', 'bj_000', 'bu_000', 'bv_000', 'ci_000', 'cj_000', 'cq_000', 'dg_000', 'dn_000', 'do_000', 'dx_000']*
PDF 、 CDF 和方框绘制了这些特征中的每一个的,以试图理解我们的数据的分布。提出的意见如下:
aa_000 : 如果 APS 中没有故障(class label = 0),大约 95%的点的值在 0.1x1e6 以下。高于该值通常表示 APS 组件出现故障。
al_000,am _ 000:APS 组件的故障实例和非故障实例的值在此特性中无法明确区分。虽然失败案例的点确实具有稍高的值。
ap_000,aq_000,bj_000,bu_000 : 与非故障情况相比,故障情况具有更高的值。但是 APS 组件的非故障实例很少,这在该特征中看到更高的值。
在所有特性中,除了 dg_000、cj_000、am_0 和 al_000 之外,特性中较高的值通常表示 APS 组件出现故障。但是由于数据的不平衡性质,这可能是不确定的。
考虑到每个特征如何与目标变量(“类别”)相关,我们可以观察到特征“dx _ 000”是我们的顶级属性中最不相关的特征。我们可以进一步进行双变量分析,了解其他顶级功能相对于功能‘dx _ 000’的变化情况。
此处所有图中的主要观察结果是,对于剩余特征的任何值,如果特征‘dx _ 000’具有低值(接近 0),则可能指示 APS 组件中存在故障(类别标签=1)。
总结我们的探索性数据分析
- 数据集由 60,000 个数据点和 171 个要素组成,包括类别标签。
- 在绘制每个类别标签的计数后,我们发现在 60000 个点中,59000 个点属于类别 0,剩余的 1000 个点属于类别 1。我们正在处理一个高度不平衡的二进制分类问题。
- 然后,我们继续检查数据集中缺失的值。我们观察到一些特性丢失了超过 70%的值。我们决定从数据集中移除这些要素。7 个特征因此被移除。
- 有一个要素(cd_000)对于所有数据点都只有一个值。我们决定去掉它,因为它不会给我们的模型性能增加多少价值。
- 对于缺失数据少于 5% 的特征,由 NA 值组成的行被移除。具有 5% — 15% 缺失值的特征使用中值进行估算。具有 15% — 70% 缺失值的特征使用基于模型的插补技术进行插补。
- 有 70 个特征由来自 7 个直方图的 bin 信息组成。每个直方图有 10 个柱。直方图特征是具有标识符的特征: ['ag ',' ay ',' az ',' ba ',' cn ',' cs ',' ee'] 。直方图和数字特征被分成两个数据集,我们对两个数据集的前 15 个特征进行了单变量和双变量分析。
- 通过使用随机森林分类器执行递归特征消除,我们发现直方图数据集中的前 15 个特征是: ['ag_001 ',' ag_002 ',' ag_003 ',' ay_005 ',' ay_006 ',' ay_008 ',' ba_002 ',' ba_003 ',' ba_004 ',' cn_000 ',' cn_004 ',' cs_002 ',' cs_004 ',' ee_003 ',' ee_005']
- 对这些特性的分析表明,在这些顶级特性中,较高的值可能表明卡车的空气压力系统有故障。但是,在极少数情况下,这些值高于正常情况,但仍不会导致 APS 故障。示例:特征 ee_005 。对最不相关特征与目标变量( ay_005 )的单变量分析我们看到,对于 ag_002、ag_001、cn _ 000——对于这些其他顶级特征的任何值,当特征‘ay _ 005’中的值接近 0 时,APS 组件(类别标签= 1)存在故障。
- 通过使用随机森林分类器执行递归特征消除,我们发现来自数值数据集的前 15 个特征是: ['aa_000 ',' al_000 ',' am_0 ',' ap_000 ',' aq_000 ',' bj_000 ',' bu_000 ',' bv_000 ',' ci_000 ',' cj_000 ',' cq_000 ',' dg_000 ',' dn_000 ',' do_000 ',' dx_000 '
- 从单变量分析中,我们看到在所有特征中,除了 dg_000、cj_000、am_0 和 al_000 之外,特征中较高的值通常表示 APS 组件中的故障。但是由于数据的不平衡性质,这可能是不确定的。特征‘dx _ 000’是顶部特征中最不相关的特征。我们执行了类似于直方图顶部特征的双变量分析,此处所有图中的主要观察结果是,对于剩余特征的任何值,如果特征‘dx _ 000’具有低值(接近 0),则可能指示APS 组件(类标签=1)中存在故障。
准备我们的数据(标准化+ SMOTE +欠采样)
标准化 一个向量最常意味着减去一个位置的度量,再除以一个尺度的度量。例如,如果向量包含具有高斯分布的随机值,您可以减去平均值并除以标准差,从而获得平均值为 0、标准差为 1 的“标准正态”随机变量。我们将使用 sklearn 的 MinMaxScaler 来缩放我们的数据。
不平衡分类的一个问题是少数类的例子太少,模型无法有效地学习决策边界。解决这个问题的一个方法是对少数类中的示例进行过采样。
SMOTE 和欠采样的组合比简单的欠采样执行得更好。
最后我们有33226 分属于负类,16613 分属于正类。我们将通过线性模型(逻辑回归和支持向量机)传递我们的缩放数据集。
实验经典 ML 模型
现在,我们已经准备好执行 EDA、数据预处理和特征工程,让我们继续建模。我们将通过各种模型传递我们的数据,执行超参数调整,并根据我们的性能指标(宏观 F1 得分)和混淆矩阵对每个模型进行评估。我们将在这里尝试的不同模型是逻辑回归、支持向量机、朴素贝叶斯、决策树、随机森林、梯度增强决策树、Adaboost 分类器和自定义集成。
作为基线模型,我们将预测所有类别标签为 0(多数类别),并计算相同类别的 F1 分数。我们可以使用 sklearn 的 DummyClassifier 来获得基线结果。
对于我们的定制套装:
- 将列车组分成 D1 和 D2(50-50)。
- 从 D1,用替换的执行取样以创建 d1、d2、d3 …dk (k 个样本)。
- 现在,创建“k”个模型,并用这 k 个样本中的每一个来训练这些模型。
- 让 D2 通过每个“k”模型,这给了我们每个模型对 D2 的“k”预测。
- 使用这些“k”预测创建一个新的数据集,对于 D2,因为我们已经知道它的相应目标值,我们现在可以用这些“k”预测作为特征来训练一个元模型。
- 对于模型评估,我们将通过每个基础模型传递我们的测试集,并获得“k”个预测。然后,我们可以用这些“k”个预测创建一个新的数据集,并将其传递给之前训练过的元模型,以获得我们的最终预测。
- 现在,使用这个最终预测以及测试集的目标,我们可以计算模型的性能分数。
我们可以用决策树作为基础模型,用 GBDT 作为元模型。这是一个自定义实现的模型。
在执行超参数调整和试验各种模型之后,我们看到梯度提升决策树工作得最好,因为它获得了最高的宏 F1 分数(如下所示)。

建模概述
使用 Flask API 在本地服务器上部署:
该模型可以使用 Flask API 部署在我们的本地服务器上。相同的代码包括加载所需的模型,从。csv 文件,并将最终输出存储在输出目录下的. csv 文件中。
下面给出了相同的 HTML 代码
HTML 代码
在运行上面的代码时,我们本地服务器上的 html 页面看起来像这样,您可以在这里指定输入文件和输出目录的路径:

用于指定路径的 HTML 页
输出目录将由一个. csv 文件(包含时间戳)组成,该文件包含预处理数据集以及模型预测。
为了更清晰的画面,可以查看 这段视频 ,演示了完整的过程:
展示模型部署的 YouTube 视频
结论:
总而言之,我们首先移除具有最大量缺失值的特征,然后使用中位数和 MICE 插补方法的组合从剩余特征中插补缺失值,然后通过我们训练的梯度增强决策树模型传递该预处理数据集。取得的成果相当不错,并已部署。我希望这个项目能让你对如何着手任何数据科学项目有一个公平的想法,尤其是如果你刚刚起步的话:)
你可以在我的 Github 查看完整的代码。并随时通过 LinkedIn 或 Twitter 联系我。
未来范围
- 深度学习方法可以用来解决这个特定的问题,我们可以使用我们的性能度量来评估神经网络。
- 可以使用各种其他插补方法,例如软插补算法。
参考
- ka ggle:https://www . ka ggle . com/UC IML/APS-failure-at-Scania-trucks-data-set
- IDA 2016 工业挑战赛:利用机器学习预测故障:https://link . springer . com/chapter/10.1007/978-3-319-46349-0 _ 33
- 【https://www.appliedaicourse.com/】应用人工智能课程:
- 机器学习掌握:https://machinelearningmastery.com/
用 DNA 甲基化数据预测年龄
原文:https://towardsdatascience.com/predicting-age-with-dna-methylation-data-99043406084?source=collection_archive---------23-----------------------
实践教程
建立模型从 DNA 甲基化数据预测年龄,包括比较组织和疾病队列的表现。
这个项目是作为 哈佛顶点 IACS 课程 的一部分进行的
小组成员:丹尼尔·考克斯、雷亚新、埃莉诺拉·尚西拉、亚伦·雅各布森
特别感谢我们的课程导师克里斯·坦纳博士和 TF 黄家仪的指导和支持。
问题描述
你多大了…生理上?科学家们发现,衰老的过程不仅在我们整个身体中,而且在我们的每个细胞中都引起了可观察到的变化,而且这一过程在不同的人之间不一定以相同的速度进行。某些特定年龄的人在生理上可能比其他人更年轻或更老。我们如何判断一个人的生理衰老速度是快于还是慢于平均水平?加速老化在多大程度上反映了当前或未来的疾病?这些问题是该团队旨在用生物数据来回答的,以评估给定个体的细胞以异常方式老化的程度,这可能表明需要治疗干预。
我们解决这个问题的方法是建立模型来预测真实的年龄,然后用这些模型作为比较特定个体的基线。
起初,还不清楚哪种生物数据是衰老的良好标志,我们考虑了几种:各种生物分子的血液水平、大脑的 MRI 扫描、各种组织中的 DNA 表达水平等。最终,在初步实验和文献回顾后,我们决定将 DNA 甲基化作为最有希望的年龄预测指标。
什么是 DNA 甲基化?
在人类中(几乎)所有的细胞都有一个包含称为染色体的长双链 DNA 的细胞核。每条染色体由一个主链组成,主链上有成对的含氮碱基 A、G、T 和 C,它们以不同的顺序重复排列,就像串珠一样(图 1)。在这条串珠状细绳的某些地方,有一些被称为甲基的额外装饰,它们是由特定于这项工作的酶放在那里的,更有趣的是,这些甲基连接的位置会随着年龄的变化而变化。

图一。DNA 甲基化。图片作者。
一般来说,老年人的 DNA 甲基化程度低于年轻人,但在任何特定的位点,甲基化程度都可能是双向的。甲基化可能在某些位置随年龄增长而增加,而在另一些位置则降低。我们说的是多少个职位?几百万。一般来说,DNA 甲基化的位点是 G 跟在 C 后面,中间有一个磷酸基团。这些位点被称为 CpG 位点,在我们的 DNA 中有大约 2000 万个,所以问题很快就变成了哪一个最能代表年龄?
数据
为了检验这个问题,我们从表观基因组数据中心(EWAS)的数据开始,这是一个 DNA 甲基化库。我们从健康个体的血细胞数据开始工作。该数据中的 CpG 站点数量约为 480,000 个。下面的图 2 显示了经过处理的数据的一小部分。

图二。全血组织样本的 EWAS 健康队列数据的子部分。图片作者。
每行对应一个个体的样本,每列对应一个 CpG 站点。表中的值表示该样品中 DNA 特定位点被甲基化的概率。通过选择年龄在 20-110 岁之间的个体并删除缺失值超过 10%的列进行初始预处理后,数据集包含 1066 行和 375,603 列。
该数据被分成训练集(75%)和测试集(25%),两者都用训练集的列平均值进行估算。然后我们开始建模。
基线模型:使用所有特征的线性和 XGBoost 模型
我们最初的方法是利用所有可用的 CpG 位点(特征),确定我们从健康对照全血数据中预测人类实足年龄的准确度。为了研究这一点,我们使用年龄作为因变量对所有特征进行了线性回归。在我们的整个分析中,我们使用平均绝对误差(MAE)作为精度指标。MAE 是指预测年龄和真实年龄之间的平均绝对差值。结果如图 3 所示。令人鼓舞的是,无论有没有调整,线性模型都可以很好地预测整个生命周期的年龄,最好的模型在测试数据集(267 人)上达到了 4.43 年的平均寿命。我们还对该数据使用了一种基于非线性树的回归方法 XGboost,并发现了一些改进,实现了 4.32 年的平均寿命。

图三。使用所有 375,603 个特征,1066 个样本,从全血 DNA 甲基化数据预测年龄。图片作者。
与样本数量相比,大量的特征使模型容易过度拟合,导致下一个自然问题:哪些 CpG 网站与年龄预测最相关?
功能选择
为了回答这个问题,我们试图用几种方法来减少特征的数量:线性拟合的统计测试、自举相关分析、Shapley 评分的排序,以及使用 XGboost 回归的特征重要性。其中,线性拟合、Shapley 评分和 XGboost 回归的统计测试得出了类似的结果。我们选择了下面描述的 XGboost 方法(图 4 ),用于所有后续的模型构建。我们对数据进行了 80/20 的测试分类。我们将 XGBoost 模型应用于这一拆分,并记录了哪些 CpG 进入了前 100 名的重要性分数。这被重复了 50 次,然后每个 CpG 站点出现在前 100 个重要性分数中的频率被用来按照重要性排序。

图 4。使用 XGBoost 进行特征选择的工作流。图片作者。
下面的图 5 显示了前 100 个 CpG 站点的这些频率的直方图。换句话说,它显示了在我们的 50 次试验中,每个 CpG 站点出现在前 100 个重要性分数中的频率。例如,图中的前 6 个特征的频率为 50,这意味着它们出现在所有 50 次随机试验的前 100 名中。这个结果是极不可能偶然出现的。事实上,任何 CpG 在 50 次试验中偶然出现 4 次以上的概率是 p = 7.66e-7。因此,这种方法是有选择性的,它可能选择那些甲基化与衰老最相关的 CpG。

图五。CpG 在前 100 个重要性分数中出现的频率。图片作者。
有了这个过程,我们接着讨论应该使用多少这些顶级特性的问题。
模型 1:使用精选功能的线性和 XGBoost 模型
为了了解这种选择过程如何挑选出与年龄最相关的特征,我们首先将特征的数量从不到 40 万个减少到前 100 个。对这 100 个 CpG 位点重复了年龄预测基线模型,产生了图 6 中的结果。

图六。使用 XGboost 交叉验证排名的前 100 个 CpG 站点预测年龄。图片作者。
值得注意的是,在将模型的特征从超过 40 万个削减到 100 个后,较小的模型表现相当。当使用 100 个 CpG 的随机集合时,情况并非如此,这表明我们的 CpG 排名方法有一些优点,并且数据集中的许多 CpG 位点可能与年龄预测无关。
接下来,为了找到在我们的模型中使用的最佳数量的特征,我们用不同数量的排名靠前的 CpG 站点来拟合数据。我们重复做了 50 次,每次用不同的 80/20 测试验证分割,然后确定最佳的 CpG 数。每种条件下 50 次实验的平均 MAE 值绘制在图 7 中。

图 7。平均绝对误差是所用分级 CpG 数量的函数。图片作者。
有趣的是,对于非正则化线性回归(图 7-A ),最佳 CpG 数在大约 100 处开始趋于稳定,对于岭回归、Lasso 回归和 XGboost 回归(图 7 B-D ),最佳 CpG 数在大约 1000 处开始趋于稳定。对排名前 1000 的 CpG 重复建模,获得了相对于 100 CpGs 的适度改进,最佳模型是岭回归模型,该模型使用排名前 1000 的 CpG 并获得了 3.73 年的 MAE,如图 8 所示。

图 8。使用通过 XGboost 交叉验证和岭回归排序的前 1000 个 CpG 站点预测年龄。图片作者。
这是我们能达到的最高精度吗?或者我们可以用更复杂的模型比如神经网络做得更好吗?
模型 2:神经网络
类似于线性和 XGBoost 模型分析,神经网络(NN)建模的第一步是测试有多少特征是最佳的。从两个 NN 结构开始:NN A)包含 3 个隐藏层(节点号 128->56>28),NN B)包含 2 层(节点号 128->56)。我们再次改变了 CpG 的数量,现在寻找用于神经网络建模的最佳数量(图 9)。

图九。NN A)具有 3 个隐藏层(左)和 NN B)具有 2 个隐藏层(右)的不同数量的顶部特征的平均平均误差。图片作者。
从图 9 中,我们可以看到,具有 3 个隐藏层的 NN A)在 300 到 700 CpGs 时性能最佳,NN B)的性能在 400 CpGs 左右处于平稳状态。有了这些信息,我们随后改变其他模型超参数—隐藏层节点数、激活函数—来调整神经网络模型以获得最佳性能。我们获得的最佳模型是一个具有 2 个隐藏层(隐藏层节点编号 128->64)的神经网络,它使用了前 700 个 CpG,并实现了 3.597 年的平均寿命(图 10)。

图 10。使用具有三个隐藏层的神经网络预测年龄,其中包含 700 个顶级 CpG。图片作者。
下面图 11 中的表格总结了我们用来自健康队列的全血的 DNA 甲基化数据的建模结果。具有 1000 或 100 CpGs 的 Ridge 和 Lasso 模型表现良好(MAE 分别= 3.73 和 3.88 年),但神经网络表现最好(MAE = 3.60)。将这些结果与文献进行比较,我们的神经网络模型的误差与(2013)[1]和 Hannum (2013)[2]的误差相当,但不如张等人(2019)[3]的误差,后者报告的一些数据集的 rMSE 低至 2.04 年。

图 11。适用于血液 DNA 甲基化数据(测试数据)的模型总结。图片作者。
使用全血的 DNA 甲基化数据建立了这些模型后,我们考虑的下一个问题是这些模型是否可以不加改变地用于其他组织的数据。
对其他组织的可转移性
为了检验这一点,将两个最好的血液模型应用于大脑和乳房数据,而无需重新训练。岭回归模型的结果如图 12 所示,神经网络的结果如图 13 所示。答案很清楚:不,这些模型不能在组织间转移。
当我们的血液拟合脊模型应用于来自大脑的甲基化数据时,其年龄预测是平坦的,总是接近 40 岁。(图 12-A)。并且,当它被应用于乳房组织数据时,它的预测再次是平坦的,但是现在接近 80 岁(图 12-B)。

图 12。应用由全血 DNA 甲基化数据开发的脊模型,使用来自其他组织的数据(1000 CpGs)。图片作者。
当使用血液训练的神经网络模型预测年龄时,也观察到类似的系统预测变化(图 13)。当血液拟合神经网络应用于来自脑组织的甲基化数据时,我们看到了普遍的预测不足,而当其应用于乳腺数据时,我们看到了预测过度。

图十三。应用由全血 DNA 甲基化数据开发的神经网络模型,使用来自其他组织的数据。图片作者。
这种模型可转移性的缺乏可能是因为 1)不同的 CpG 位点可能与不同组织中的年龄预测最相关,或者 2)血细胞中 DNA 甲基化的一些特殊之处使其比其他组织中的 DNA 甲基化更能预测年龄。这些要点将在下面进行研究。
- 功能的可转移性
我们首先询问排名靠前的血液特征是否可以用来预测其他组织甲基化数据的年龄。事实证明,答案是肯定的。我们发现,用血液数据预测年龄的最重要的特征也可以有效地用于用白细胞、乳腺和脑甲基化数据进行年龄预测建模。也就是说,虽然模型不能直接转移,但是特性是可以转移的。
对于白细胞数据,使用 782 个排名靠前的血液 CpG 的具有 2 个隐藏层(隐藏层节点编号 128->56)的 NN 实现了 3.51 的 MAE(图 14),事实上略好于根据全血数据训练的类似模型。然而,这种令人印象深刻的性能并不适用于所有组织,因为用血液排序的 CpGs 训练的最佳乳房神经网络达到了 5.97 的 MAE,而用血液排序的 CpGs 训练的最佳大脑神经网络达到了 6.02 的 MAE。但是,这些结果确实证明了组织间某种程度的可移植性。

图 14。使用拟合白细胞数据的神经网络来预测年龄,该数据具有两个隐藏层,其中 782 个顶级 CpG 通过 XGBoost 从全血交叉验证中生成。图片作者。
2。其他组织预测的准确性
我们考虑的下一个问题是,来自全血以外的组织的 DNA 甲基化数据是否同样适用于预测年龄。我们通过重复对来自其他组织的全血数据使用的特征选择过程来检验这一点。然后,我们分别为每个组织建立模型,只考虑每个组织特定的排名靠前的 CpG 位点。脑和乳腺组织的岭回归结果如下图 15 所示。

图 15。使用来自大脑和乳房数据的前 1000 个 CpG 开发的线性模型。图片作者。
有趣的是,用这些组织的数据建立的模型在预测年龄方面不如用血液数据建立的模型好。它们的 MAEs 要大得多,所以也许血细胞有一些独特的东西可以很好地预测年龄。
向不健康群体转移的可能性
既然我们知道模型在组织之间是不可转移的,但是这些特征在某种程度上是可转移的,我们问的下一个问题是用健康个体的数据建立的模型可转移到不健康的个体吗?为了这个项目的目的,我们将“不健康”定义为患有神经退行性疾病的个体,例如,亨廷顿舞蹈症、帕金森氏症和阿尔茨海默氏症。这些群组的数据也可以在 EWAS 上获得,尽管在下载的数据中只有大约 225,000 个 CpG 站点。在这项分析中,我们使用了来自健康对照和亨廷顿舞蹈症和阿尔茨海默氏症患者的大脑 DNA 甲基化数据。
使用健康个体的前 100 个中的 55 个 CpG 位点(由 XGBoost 选择)在健康群组上训练线性模型,所述健康个体在不健康群组中可用。这些模型中最好的是 lasso 回归模型,其 MAE 达到 5.431。
将这些模型直接应用于阿尔茨海默氏症和亨廷顿氏症患者,我们看到健康模型在两个不健康群体中都表现非常好。表现最好的线性模型(lasso 回归)实现了阿尔茨海默氏病患者的 MAE 为 4.771,亨廷顿氏病患者的 MAE 为 4.471(图 16)。换句话说,使用 55 个健康 CpG 的脑组织模型可转移到不健康群组,并在它们身上实现比在健康群组上更好的测试准确性。

图十六。55 个 CpG 位点的脑组织健康对照模型应用于 A)阿尔茨海默氏病脑组织数据(811)和 B)亨廷顿氏病脑组织数据(270)。图片作者。
该模型的可转移性表明,健康个体中与年龄高度相关的 CpG 位点也与不健康个体中的衰老相关,这提出了一个问题,即与这些 CpG 位点相关的体重在健康和不健康队列之间是否不同。使用相同的 55 个 CpG 重新训练该模型,但现在对不健康的队列进行训练(单独进行),我们在三个模型中得到了 MAE 的改善。图 17 显示了 lasso 回归的结果,这也是我们的最佳模型,阿尔茨海默病患者的 MAE 为 4.171,亨廷顿舞蹈病患者的 MAE 为 4.184。

图 17。A)阿尔茨海默氏病 B)亨廷顿氏病使用来自健康队列的 55 个显著 CpG 位点的不健康队列的脑组织模型的结果应用于测试集。图片作者。
查看与这三个模型(健康、阿尔茨海默氏症和亨廷顿氏症)相关的权重,并为每个 CpG 位点绘制它们,我们可以在图 18 中看到结果。从图中,我们可以看到,对于大多数 CpG 位点,权重的大小在三个组群之间发生变化,但其方向(符号)没有变化。

图 18。健康对照(HC)、阿尔茨海默氏病和亨廷顿氏病模型的 55 个 CpG 位点的 lasso 回归模型权重图。图片作者。
健康与不健康的分类
考虑到队列之间的体重量级差异有多大,我们训练了一个逻辑回归分类器,以确定我们是否可以使用与衰老最相关的 CpG 位点区分健康和阿尔茨海默氏症队列。使用类别准确度(分配给其真实类别的点的比例)作为评估度量,我们训练了许多分类器。
这些包括:使用前 55 个健康大脑 CpG 和年龄作为特征(分类准确度为 0.73);使用来自应用在健康群组上训练的脑模型的年龄和残差值作为特征(分类精度为 0.73),并且使用来自应用在阿尔茨海默氏症群组上训练的脑模型的年龄和残差值,使用该群组中与老化最相关的 CpG 位点(分类精度为 0.69)。给定分类准确度值,我们得出结论,与衰老最相关的 CpG 位点只能区分健康人群和阿尔茨海默病人群,并取得中等成功。
生物学意义
关于我们的结果,一个自然的问题是甲基化可能影响哪些基因,从而可能影响衰老?下面的图 19 显示了前 23 个血液 CpG 位点到基因的映射。一些基因与一个以上的顶级 CpG 位点相关,例如 KLF14,一种被认为是脂肪组织中基因表达的主要调节因子的转录因子。

图 19。与排名前 23 位的 CpG 位点相关的基因,血液数据。图片作者。
KLF14 和另外两个以紫色显示的基因(ELOVL2 和 ZNF423)与脂肪细胞或脂肪代谢有关。因此,脂肪代谢和储存过程可能对衰老有重要影响。此外,还有四个与泛素-蛋白酶体途径(red)相关的基因,即 OTUD7A、TRIM59、RNF180 和 NHLRC1(蛋白质降解的重要途径)。事实上,其中三个基因是 E3 泛素连接酶,负责标记降解蛋白。因此,就寻找衰老过程中的干预措施而言,靶向该途径可能是一种有希望的研究途径。事实上,尽管存在 DNA 甲基化,但已有多项研究确定该途径对衰老具有重要影响(Bergsma 和 Rogaeva (2020)[4],Kevei 和 Hoppe(2014)[5])。
结论
从上述分析中得出的结论是:
- 我们已经能够构建预测年龄的模型,在整个成人寿命期间,平均误差为 3.6 年。
- 从开始的约 400,000 个 DNA 甲基化位点(CpG 位点)中,我们确定了约 700 个最适合年龄预测建模的位点。
- 模型不能跨组织转移,但许多 CpG 可以。
- 使用健康个体的脑组织开发的模型也可以预测神经退行性疾病患者的年龄。
- 我们的顶级 CpG 通常与调节脂肪组织基因表达和泛素-蛋白酶体蛋白降解途径的基因相关。
参考文献
- 人类组织和细胞类型的 DNA 甲基化年龄。Genome Biol,2013。14(10):第 R115 页。
- Hannum,g .,等,全基因组甲基化谱揭示了人类衰老速率的定量观点。Mol Cell,2013。49(2):第 359-367 页。
- Zhang,q .,等,跨组织表观遗传时钟估计的精度提高及其对生物衰老的意义。基因组医学,2019。11(1):第 54 页。
- Bergsma,t .和 E. Rogaeva,DNA 甲基化时钟及其对衰老表型和健康寿命的预测能力。《神经科学洞察》,2020 年。15: p. 2633105520942221。
- Kevei,e .和 T. Hoppe,泛素设定时间:对衰老和寿命的影响。Nat Struct Mol Biol,2014。21(4):第 290-2 页。
在 Jupyter 笔记本中使用 Microsoft Azure 机器学习和 Python 预测银行客户流失
原文:https://towardsdatascience.com/predicting-bank-customer-churn-using-microsoft-azure-machine-learning-python-in-jupyter-notebook-cbac39e3012a?source=collection_archive---------31-----------------------
了解使用 Azure 资源和 Python 编写和运行笔记本有多简单

凯文·Ku 摄于 Unsplash
在本教程中,我们将使用 python notebook 和 Microsoft Azure services 构建一个人工神经网络(ANN)来预测银行客户流失。请注意,Azure Machine Learning (ML)提供了很多东西,在本文中,我将展示使用 Azure resources 和 python 编写和运行笔记本是多么容易。
先决条件
- 你应该熟悉机器学习。即使你不明白,也要试着跟着做,坚持练习。
- 你应该知道张量流。你可以在网上找到大量的资料并了解它。
- 您必须订阅 Microsoft Azure。Azure 向学院或大学学生提供免费学分。在这里创建一个账户。
创建 Azure 机器学习服务
- 转到 Azure 门户并点击“+”符号创建一个资源。
- 搜索“机器学习”并点击创建。
- 输入详细信息,然后单击“审查和创建”
- 最后,单击“创建”开始部署过程。
- 大约 3-4 分钟后,您的服务应该可以使用了,您应该会看到类似这样的内容:

Azure 机器学习

Azure 机器学习工作区
- 去 Azure 机器学习门户。
- 确保您使用与登录 Azure 门户时相同的电子邮件 id 登录。
- 花点时间理解被询问的信息。
- 选择正确的订阅和工作区。请记住我们之前创建的工作区,您将在这里找到它以供选择。
- 完成后,点击“开始”。您的工作区已经可以使用了!
- 这是它应该有的样子。我强烈建议你花大量的时间来看看所提供的服务。在底部,您可以找到很好的文档来帮助您开始。
- 在 Azure 机器学习工作区中,选择“新建”,然后选择“笔记本”。
- 会弹出一个对话框,要求您命名文件。在这里,我创建了一个名为“CustomerChurn.ipnyb”的文件。
- 从 Kaggle 下载这个数据集,并将其与 ipnyb 文件一起上传到笔记本文件夹下的 Azure ML 门户上。
创建计算
打开笔记本,在第一个单元格中输入“7+5 ”,并使用该单元格左侧的小三角形(运行)按钮运行它。您应该看到以下内容:

创建计算
计算是一个重要概念,没有它你将无法运行一个单元(或整个笔记本)。继续创建一台计算机:
- 如上所示,点击“点击计算”。
- 选择您希望用于计算实例的虚拟机大小。
- 在 CPU 或 GPU 虚拟机类型之间切换。当使用支持 GPU 的虚拟机时,确保编写的代码能够利用可用的 GPU 设备。
- 根据需要选择其他选项。如果你只是尝试 Azure,我建议你总是选择免费的或者花费最少的选项。
- 选择“create ”,大约需要 10-12 分钟来创建一个可供使用的虚拟机。现在你应该可以运行你的手机了。

数据可视化,分析&清洗
现在,我们已经准备好了所有的组件(数据集、计算、笔记本电脑设置),是时候施展魔法了!
为了简单起见,这里我只解释重要的代码片段。你可以在 Github 上查看整个笔记本。
第一步是读取数据集并理解属性的数据类型、不需要的属性等。
第二步是将分类值转换为数值,因为 ML 模型处理的是数值数据。例如,下面的代码在整个数据集中用 1 替换值“女性”,用 0 替换值“男性”。
df['Gender'].replace({'Female':1,'Male':0},inplace=**True**)
拥有一个缩放的数据有助于训练一个人工神经网络。在我们的数据集中,一些属性没有缩放。
col_to_scale = ['CreditScore','Age','Tenure','Balance','EstimatedSalary','NumOfProducts']
**from** **sklearn.preprocessing** **import** MinMaxScaler
scaler = MinMaxScaler()
df1[col_to_scale] = scaler.fit_transform(df1[col_to_scale])
下面的代码根据地理位置绘制了离开和不离开的人数。

Microsoft Azure 机器学习笔记本中的输出
创建训练和测试分割
我们需要将数据集分为训练数据集和测试数据集。由于 sklearn 模块,这是一个非常简单的任务。要了解更多,请观看这个非常棒的视频。
**from** **sklearn.model_selection** **import** train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=5)
创建人工神经网络
我将使用 TensorFlow/Kera 建立模型。点击了解更多信息。花些时间真正理解代码。请记住,下面的值是基于点击和尝试。在最终确定这些值之前,我多次运行这个模型(用这些值获得了最大的准确性)。
**import** **tensorflow** **as** **tf**
**from** **tensorflow** **import** keras
model = keras.Sequential([
keras.layers.Dense(12, input_shape=(12,), activation='relu'), *#12 because number of inputs is 12*
keras.layers.Dense(6, activation='relu'), *# hidden*
keras.layers.Dense(1, activation='sigmoid')
])
*# opt = keras.optimizers.Adam(learning_rate=0.01)*
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy'])
model.fit(X_train, y_train, epochs=100)
预测和准确性
一旦所有时期都运行了,您就可以使用
model.evaluate(X_test,y_test)
分类报告&混淆矩阵
分类报告是获取每个预测类的精度、召回率、f1 值和支持值的一种很好的方式。
混淆矩阵,也称为误差矩阵,是一种特定的表格布局,允许算法性能的可视化。
注意事项
如果您得到一个错误“没有名为 seaborn 的模块”,请在使用 seaborn 之前运行下面的命令。
pip 安装 seaborn
以上命令将安装必要的库。
删除蔚蓝资源
由于 Azure 对正在使用的服务收费,因此总是建议删除您不再使用的资源。
在这篇博客中,你创建了两个资源——机器学习和资源组。
去 Azure 门户主页找这两个资源。打开它们并删除资源。一旦删除成功,您将不会为该资源付费。
结论
我演示了如何创建一个 ML 服务。此外,在 Microsoft Azure ML 中创建了一个工作区。然后,我们从 Kaggle 下载了数据集,并对其进行了分析,以便将其输入到 ANN 中。在 TensorFlow 的帮助下,创建并训练了一个 ANN。正如已经提到的,根据手头的工作和您的偏好,您可以利用大量的集成和功能。这篇博客一定给了你一个小小的窥视,并帮助你今天开始!
还有,你可以在 Twitter 和 LinkedIn 上问我一个问题!
参考文献
[1]教程:Jupyter 笔记本入门(Python)——Azure 机器学习。https://docs . Microsoft . com/en-us/azure/machine-learning/tutorial-1st-experiment-SDK-setup
[2]代码基础。(2018 年 8 月 6 日)。机器学习教程 Python — 6:虚拟变量&一热编码【视频】。YouTube。https://www.youtube.com/watch?v=9yl6-HEY7_s&list = pleo 1 k3 hjs 3 uvcetyteyfe 0-rn 5 r 8 Zn 9 rw&index = 6&ab _ channel = code basics
希望这对你有帮助。
谢谢你。
预测破产:或有索赔模型
原文:https://towardsdatascience.com/predicting-bankruptcy-the-contingent-claim-model-3701636b3ae9?source=collection_archive---------24-----------------------
穆迪对公司进行评级时使用的另一种方法

迪伦·吉利斯在 Unsplash 上的照片
多年来,崩溃预测一直是一个非常活跃的研究领域。重要的论文包括爱德华·奥特曼 1968 年的财务比率、判别分析和企业破产预测,这催生了他著名的 Z 分数,至今仍在使用,以及詹姆斯·奥尔森 1980 年的财务比率和破产概率预测及其 O 分数,至今仍在使用。这些论文以及之后的许多论文都是基于会计数据和财务比率。他们使用不同的分类和优化技术:逻辑回归、判别分析、神经网络、蚁群算法等,并主要根据来自损益表、资产负债表和现金流量表的财务数据对它们进行训练。

罗伯特·默顿(麻省理工学院,CC BY-SA 4.0
其他方法使用市场数据得出破产风险。一种基于市场的方法特别使用了 Black 和 Scholes 在 1973 年和 Merton 在 1974 年提出的思想,使用可能是金融数学中最具代表性的结果:Black-Scholes 方程和 Black-Scholes 公式来为期权和公司债务定价。这种公司债务定价方法是信用分析师 Kealhofer、McQuown 和 Vasicek (KMV)使用的方法,2002 年被评级机构 Moody's 收购。
在我们转到方法之前,让我们快速定义一下什么是选项。期权是一种金融衍生工具,允许其所有者在未来某一特定日期以特定价格买入(买入期权)或卖出(卖出期权)基础资产(通常是股票)(对于欧式期权,是指在该日期之前的任何时间)。默顿提出了这样一个观点:一旦债务得到偿还,一家公司的股权可以被视为该公司资产的欧式看涨期权。由于股权所有者的有限责任,如果资产不足以支付债务,股权价值就等于零。债务清偿后剩余的任何资产都可以由股权所有人主张。
我们如何给期权定价,或者说,股权定价?这就是布莱克-斯科尔斯模型的用武之地。它的基本思想是公司的资产遵循几何布朗运动:

上式中,W 是一个标准的维纳过程。我们看到引入了波动性使得这种方法不同于更传统的基于会计的方法。
权益的市场价值可以通过 Black 和 Scholes 公式获得,用于欧式看涨期权,如下所示:

随着
Ve:权益价值的市场
T:债务的到期时间
X:债务的账面价值,相当于看涨期权的履约价格的履约价值
r:无风险利率
sigma_a:资产收益的波动率
N:标准正态分布的累积密度函数;
现在,破产概率是指资产的市场价值小于在时间 T 到期的负债的面值的概率,计算方法如下:

但是,我们不知道 Va 和 sigma_a 的值,因此为了计算它们,我们同时求解上面给出的等式(1)和下面给出的“最佳对冲”等式(2 ):

我们现在可以计算漂移量μ。它表明了资产价值波动的总趋势。取无风险利率和资产收益之间的最大值:

最后是故障概率,它服从正态分布:

我们对模型输出的概率使用 0.5 的阈值来将公司分为破产和非破产。
值得一提的是,我们在该模型上使用了一个非常简单的实现,具有以下假设/限制:
- 我们不考虑支付股息
- 没有交易成本
- 借贷利率相同
- 无风险利率没有变化
用 Python 实现
我们现在将看到一个使用上述思想的 Python 实现。
我们将定义一个名为 prob_default() 的函数,该函数将一个 ticker 作为参数,并对 2018 年纽约证券交易所、纳斯达克和场外交易市场的所有 ticker 的数据运行该函数。
该函数选择与作为参数传递的股票价格相对应的每日股票价格数据,用于我们正在考虑的时间范围,我们称之为 dataframe daily_
"""DATA SELECTION"""
start_date='2018-01-01'
end_date='2018-12-31'
# get data for that ticker
daily_=daily[(daily.ticker==ticker)&(daily.date>=start_date)&(daily.date<=end_date)] # if get an empty dataframe, we skip that ticker
if daily_.shape[0]==0:
print(ticker+" is empty")
return False
daily_=daily_.reset_index()
# we show the marketcap in the right unit
daily_.marketcap=daily_.marketcap*1e6
然后,我们使用相隔 1 天的权益价值之间比率的对数来计算该期间的每日权益回报:
"""CALCULATING EQUITY RETURNS"""
for j in range(1,daily_.shape[0]):
daily_.loc[j-1, 'returns'] = np.log(daily_.loc[j-1, 'marketcap'] /daily_.loc[j, 'marketcap'])
然后,我们可以使用这些数据来计算股票的年波动率。为了计算年波动率,我们将日收益率的标准差乘以 252 的平方根(一年中的交易日数)
"""CALCULATING THE VOLATILITY OF EQUITY: SIGE""" sige=np.std(daily_.returns)*np.sqrt(252)
我们现在可以求解上面描述的联立方程(1)和(2)来找到 Va 和 sigma_a。我们分别使用 2018 年和 2017 年无风险利率的值 1.7%和 1.5%。对于债务的价值,X,我们用流动债务的价值+非流动债务价值的 50%。
然后,我们可以使用 SciPy 上的优化库的根函数来求解资产的市场价值及其波动性。我们需要找到 2018 年和 2017 年的数值。为什么是 2017 年?因为我们还想知道资产的平均年回报率。所以我们从 2018 年开始。
"""SOLVE SIMULTANEOUS EQUATIONS for 2018"""
#2018
# Initialising values
T=1
r=0.017
ve=daily_.loc[0,'marketcap']
X=df[df.ticker==ticker]['debtc'].values[0]+.5*df[df.ticker==ticker]['debtnc'].values[0] sol = optimize.root(fun, [X+ve, sige*ve/(ve+X)])
va=sol.x[0]
siga=sol.x[1]
接着是 2017 年。
#2017
T=1
r=0.015
ve=daily_.loc[daily_.shape[0]-1,'marketcap'] X=df[df.ticker==ticker]['debtc'].values[0]+.5*df[df.ticker==ticker]['debtnc'].values[0] sol = optimize.root(fun, [X+ve, sige*ve/(ve+X)])
va_1=sol.x[0]
siga=sol.x[1]
接下来是我们的最后一步,我们通过使用 2018 年和 2017 年的 va 和 va_1 变量来计算资产的年回报率。当由此产生的回报率低于无风险利率时,我们使用无风险利率。
我们现在可以使用正常的 cdf 计算“违约距离”DDt 和违约概率。
#this gives the annual return
mu=max((va-va_1)/va_1,r)
DDt=(np.log(va/X)+(mu-0.5*siga**2)*T)/siga*np.sqrt(T) return norm.cdf(-DDt)
我们可以在苹果公司(“AAPL”)和琼斯能源公司(“JONEQ”)上测试我们的函数,我们得到苹果的概率为 1e-19%,琼斯能源的概率为 60%。我们将在下一节看到该方法如何对整个数据集执行。
完整的代码可以在下面找到
2018 年数据的结果
我们现在可以在 2017 年和 2018 年的整个数据集上运行该模型,看看它对 2019 年发生的破产的预测有多好。这是一个高度不平衡的数据集,因为我们有 3237 家公司,其中只有 30 家在 2019 年宣布破产,即 0.9%。在这些情况下,最好使用 F1 分数来判断我们模型的性能,因为在这种情况下,精确度和召回率比准确性更有意义。
我们使用 0.5 的阈值将公司分为破产和非破产,但看起来更低的阈值会提高我们的 F1 分数。
从下面的数据来看,我们获得了 8%的准确率、30%的召回率和 12%的 F1 值(以及 96%的准确率)。AUC 为 87%。

或有索赔预测模型的结果:混淆矩阵、ROC 曲线、指标与阈值和准确率。
虽然这些结果可能看起来很糟糕,但值得注意的是,我们实现了一个非常基础的模型版本。我们可以通过以下方式显著改善它:
- 更好地校准概率的截止点。较低的阈值提高了召回率(但也产生了许多误报)。
- 将股息支付纳入模型
- 使用正态分布以外的其他分布(这是穆迪/KMV 使用的方法)
- 不包括场外交易市场,因为报告要求没有纽约证券交易所或纳斯达克严格
注来自《走向数据科学》的编辑: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语 。
参考
Hillegeist,S. A .,Keating,K. E .,Cram,D. P .,& Lundstedt,K. G. (2004 年)。评估破产概率。会计研究回顾,9(1),5–34
默顿,R. C. (1974)。论公司债务的定价:利率的风险结构,金融杂志,29(2),449–470。
瓦萨苏,m .,&邢,Y. (2004)。股权收益违约风险。金融杂志,59(2),831–868
用线性支持向量回归预测身体质量指数值
原文:https://towardsdatascience.com/predicting-bmi-values-with-linear-support-vector-regression-ba21eddf6938?source=collection_archive---------59-----------------------
线性回归模型

来源:图片由 JJuni 从 Pixabay 拍摄
在本例中,来自 sklearn 的 LinearSVR 用于预测来自皮马印第安人糖尿病数据集的一组患者的身体质量指数值。
具体来说,我们将观察如何使用 LinearSVR 来拟合上图所示问题中的观测值的超平面,并在该超平面内拟合尽可能多的实例,同时限制边界违规。在这方面,LinearSVR 是 LinearSVC 类的基于回归的等价物。
特征选择
为此,我们将分析特征的简单相关图,以确定哪些特征要包含在模型中。
当查看相关变量的相关图时,我们可以看到结果(无论该人是否患有糖尿病)、葡萄糖和皮肤厚度与身体质量指数(在本例中为结果变量)表现出相对较强的相关性。

资料来源:RStudio
也就是说,我们看到结果和血糖变量的相关性为 0.49。这表明变量可能是多重共线性的,即它们都在解释同一件事(在这种情况下,这个人是糖尿病患者),因此包括两者可能是多余的。
在这种情况下,我们将包括葡萄糖和皮肤厚度作为建模身体质量指数的两个特征。
训练 LinearSVR 模型
加载变量并进行列车测试分割:
y1 = np.array(bmi)x1 = np.column_stack((skinthickness, glucose))
x1 = sm.add_constant(x1, prepend=True)X_train, X_val, y_train, y_val = train_test_split(x1, y1)
现在,LinearSVR 模型是用不同的ε值定义的。
from sklearn.svm import LinearSVRsvm_reg_0 = LinearSVR(epsilon=0)
svm_reg_05 = LinearSVR(epsilon=0.5)
svm_reg_15 = LinearSVR(epsilon=1.5)svm_reg_0.fit(X_train, y_train)
svm_reg_05.fit(X_train, y_train)
svm_reg_15.fit(X_train, y_train)
使用验证数据生成预测:
predictions0 = svm_reg_0.predict(X_val)
predictions05 = svm_reg_05.predict(X_val)
predictions15 = svm_reg_15.predict(X_val)
RMSE(均方根误差)值是通过将预测值与验证集进行比较而生成的。
>>> mean_squared_error(y_val, predictions0)
>>> math.sqrt(mean_squared_error(y_val, predictions0))6.776059607874521>>> mean_squared_error(y_val, predictions05)
>>> math.sqrt(mean_squared_error(y_val, predictions05))8.491111246123179>>> mean_squared_error(y_val, predictions15)
>>> math.sqrt(mean_squared_error(y_val, predictions15))5.905569225428098
我们可以看到,当ε值设置为 1.5 时,获得最低的 RMSE。然而,这仅略低于当 epsilon 设置为 0 时获得的值。根据上面引用的 sklearn 文档,ε的值取决于数据的规模。如有任何疑问,该值应保留为 0。
在这点上,ε0 将被用于生成对测试集的预测和分析随后的 RMSE。
针对看不见的数据进行测试
一部分数据来自用于训练 LinearSVR 的原始数据集。
现在,该模型用于对保留的要素数据进行预测,并将预测值与未知的身体质量指数值进行比较。
atest = np.column_stack((t_skinthickness, t_glucose))
atest = sm.add_constant(atest, prepend=True)t_bmi = h3data['BMI']
btest = t_bmi
btest=btest.valuesbpred = svm_reg_0.predict(atest)
bpred
产生的 RMSE 值为 7.38,大约是 32.82 处测试平均值大小的 22%。对于这个特定的数据集,其他要素(包括最终从分析中删除的要素)不太可能解释身体质量指数的所有变化。生活方式因素,如每天消耗的卡路里、每天的运动量等,可能会对整体身体质量指数指数产生重大影响。
在这一点上,我们可以判断,所确定的特征在解释身体质量指数的大部分变化方面做了相当好的工作。
结论
在这个例子中,您看到了如何使用 LinearSVR 解决回归问题。具体来说,我们看到:
- 相关图如何帮助特征选择
- 线性向量回归机的构型和ε的作用
- 如何使用 RMSE 测试模型准确性
正如我们所见,虽然模型在估计身体质量指数值方面表现得相当好,但考虑到某些对影响身体质量指数值很重要的要素没有包含在数据集中,这一点也很重要。因此,在缺乏数据的情况下,在缺乏可用数据的情况下,LinearSVR(或任何模型)能够最大限度地提高准确性是有限度的。
非常感谢您的时间,任何问题或反馈都非常欢迎。
免责声明:本文是在“原样”的基础上编写的,没有任何担保。本文旨在提供数据科学概念的概述,不应以任何方式解释为专业建议。
参考
- Aurélien Géron:使用 Scikit-Learn 和 TensorFlow 进行机器学习
- ResearchGate:在支持向量回归的回归问题中,ε= 0 有什么问题?
用 Python 预测桌游评分
原文:https://towardsdatascience.com/predicting-board-game-ratings-with-python-60c9de9ee067?source=collection_archive---------20-----------------------
为实时数据科学竞赛编写解决方案
切片背景
SLICED 是一个竞争性的数据科学游戏节目,参与者有两个小时的时间来探索和预测他们刚刚看到的数据。如果你对数据分析、数据科学或机器学习感兴趣,我强烈推荐你去看看这些剧集。
尼克·万和梅格·里斯达尔是《切片》的主持人。在第一周,参赛者被要求预测棋盘游戏的评分,给出一系列特征(游戏发布的年份,游戏持续的时间等)。
你可以在 Twitch 上查看《T4》第一集,在上了解更多关于该剧的内容和时间安排。
两小时后的数据科学
作为一个挑战,我想尝试在两个小时内建立一个预测——类似于参赛者,尽管在我编码时没有 200 人看着我,压力要小得多。
问题概述
该数据集包含约 3,500 个棋盘游戏,具有各种描述性栏目和我们试图预测的“极客评级”。目标是预测另外 1,500 个棋盘游戏的未知极客评级。你可以在下面看到几个专栏的样本,在 kaggle 上可以获得完整的数据(和得分)。

数据概述
探索性数据分析
我做的第一件事(导入库和数据之后)是用我们的目标变量 geek_rating 绘制各种特性的 pairgrid。有些列是文本或者有点难以解析,我把它们留到后面的步骤中。这样做的时候,我注意到一些有趣的关系:
- 棋盘游戏的特征(最少玩家、最多玩家、平均游戏时间)似乎与预测评级有松散的关系。就有多少玩家和一款游戏需要多长时间才能被评为优秀而言,可能存在一个最佳点。
- 在有多少人拥有一个游戏/对一个游戏投票和它的评价有多高之间似乎有一个更强的(和非线性的)关系。
- 游戏在被高度评价之前已经存在了一段时间。
pg = sns.PairGrid(train_df, x_vars=['min_players', 'max_players', 'avg_time', 'year', 'owned', 'num_votes', 'age'], y_vars=['geek_rating'])
pg.map(sns.scatterplot)

成对网格图
进一步挖掘,绘制出玩家的最小数量和等级,我们看到 1-2 个玩家的最小平均得分最高。对最大玩家的类似分析表明,最“正常”的游戏配置似乎很受欢迎。
sns.boxplot(data=train_df, x='min_players', y='geek_rating')

最小玩家盒图
视觉扫描一些游戏机制,我挑选了一些导致更高分数的关键词。一个更好的方法是解析出各种短语,并使用游戏机制和评级之间的汇总统计数据建立关系……但两个小时很快就过去了!
train_df.groupby('mechanic')['geek_rating'].mean().sort_values(ascending=False)[:20]
train_df.groupby('mechanic')['geek_rating'].mean().sort_values(ascending=False)[-20:]
特征工程
玩家分组
我决定添加一个“玩家分组”的特性,只是为了捕捉一些在玩家数量方框图中可见的关系。决策树等机器学习算法可以自动提取这些信息,但它很快就将我认为有用的信息编码为一个集合,以帮助学习。
def player_grouping(df):
if df['min_players'] <= 0:
return 'Low'
elif df['max_players'] <= 3:
return 'Low'
elif df['min_players'] == 8:
return 'Exact'
elif df['min_players'] == 5:
return 'Odd'
elif df['max_players'] > 3 and df['max_players'] <= 7:
return 'Exact'
else:
return 'Other'
train_df['player_grouping'] = train_df.apply(lambda row: player_grouping(row), axis=1)

新的衍生玩家分组功能
类别评分
我想创建的下一个功能是基于游戏的类别(策略、骰子等)。
这些信息存储在许多列中。我使用第一个创建了一个查找字典(最好有全部 12 个,但是时间过得很快……),然后遍历各个列,找到与类别术语相关的平均分数。例如医学、文艺复兴和文明类别表现最好,而琐事、记忆和数字类别表现最差。
category_lookup_dict = dict(train_df.groupby('category1')['geek_rating'].mean())
def get_combined_category_scoring(df, category_dict, col_list):
score_list = []
for col in col_list:
if df[col] != np.nan:
# Handle errors for new categories not profiled
try:
score_list.append(category_dict[df[col]])
except:
pass
if len(score_list) > 0:
return np.mean(score_list)
else:
return 6.09 # avg for missing categories
col_list_cat = [col for col in train_df.columns if 'category' in col]
train_df['cat_score'] = train_df.apply(lambda row: get_combined_category_scoring(row, category_lookup_dict, col_list_cat), axis=1)
技工组
我在游戏机械领域做了类似的特征工程,但是随着时间的减少,关于计算平均值和二进制标志方法的科学程度降低了。
预言;预测;预告
最后一步是选择输入预测和机器学习算法的列。我试了几个,最后用的是渐变提升。我没有花太多时间优化超参数,只是使用了默认值。
feature_cols = ['age', 'player_grouping', 'owned', 'num_votes', 'cat_score', 'min_players', 'max_players', 'avg_time',
'min_time', 'max_time', 'year', 'mechanic_group']
target_col = 'geek_rating'
x = train_df[feature_cols]
y = train_df[target_col]
reg = GradientBoostingRegressor()
reg.fit(x, y)
predictions = reg.predict(x)
print(f'RMSE for training set: {np.sqrt(mean_squared_error(y_true=y, y_pred=predictions))}')
训练集的均方根误差为 0.141,验证集的均方根误差为 0.167(训练样本的 30%)。
结果
在整合了这些功能和几个迭代之后,我最终得到了下面的笔记本和 0.177 的 RMSE——在排行榜上排名第九。

结果

排行榜(仅在 Twitch stream 期间显示提交内容)
摘要
这是一个有趣的挑战,建议其他人尝试分析数据。除了儿时的家庭垄断争吵之外,我在棋盘游戏方面的专业知识几乎为零,所以看看我能做出多准确的预测是件有趣的事情。
在Github上可以找到所有的例子和文件。
原载于https://data stud . dev。
用人工智能预测圣诞礼物
原文:https://towardsdatascience.com/predicting-christmas-presents-with-ai-3eaa2dc96e8?source=collection_archive---------28-----------------------
你圣诞节得到了什么?也许 AI 有答案。

尤金·日夫奇克在 Unsplash 上拍摄的照片
人工智能可以做很多事情。比专业人士更好地玩电子游戏,创作美丽的艺术作品,写故事。但是人工智能能预测圣诞节你会得到什么吗?
对图像进行分类是人工智能特别擅长的事情。一种被称为卷积神经网络的模型在图像任务上表现出色。
计算机视觉领域在不断进步和完善。因此,在越来越大的数据集和更广泛的模型的推动下,图像分类正在成为一项简单的任务。
但是所有这些模型和实验都有相同的假设。图像显示您试图分类的对象。
这个假设不适用于圣诞礼物。是的,你要识别的物体就在图像中。但不准确。有些材料挡住了去路。礼物包装好了。包装遮住了物品,使其难以预测,这是一个更加令人兴奋的圣诞节。
这篇文章分为三个部分。
- 礼物预测的问题。
- 收集数据。
- 开发一个模型。
你可能已经在想预测圣诞礼物里有什么的问题了。我在下面概述了这个项目中的几个大项目。
太多选择
由于许多原因,从包装好的礼物的图像中预测圣诞礼物是一项困难的任务。但是有一个巨大的原因使得这个任务对人工智能来说几乎不可能(对我们人类来说也很困难)

卡莱·迪莫克在 Unsplash 上的照片
礼物通常包装在盒子里,盒子的形状与里面的礼物形状无关。
这种结构意味着不同的礼物可以放在同一个盒子里。AI 不喜欢内容不同的相同盒子。究竟怎么会有人确定其中的区别。
这个问题让我想到这项特殊任务困难的第二个原因。我只是使用包装好的礼物的图片。
我不知道你怎么想,但是当我收到圣诞礼物时,我会立刻注意到礼物的重量。简单地把礼物递给我,就能让我知道里面有什么。
礼物太轻了——是的,里面没有煤。
甚至像快速摇动这样的事情(也许先检查一下以确保摇动不会破坏礼物)会给你提供更多关于礼物可能是什么或不是什么的信息。
圣诞礼物预测问题
所以为了把这个问题调整成对人工智能有效的东西,我要把这个问题简化成更可行的东西。
我可以从一套礼物中预测礼物的类型,而不是特定的礼物吗?这一改变将极大地降低问题的复杂性。
此外,即使我可以建立一个模型来预测特定的礼物,预测对象是正确的吗?有些人会说礼物的品牌也很重要。
也许我能看出你买的是内衣,但这是奢侈品牌的新内裤吗?还是你从大箱子里拿了一双?
所以预测礼物的种类看起来像是作弊。嗯,确实是。但是当我收集数据时,你会发现这并不是一个确定的问题。
因此,减少问题是启动这个项目的关键。
数据
尽管有各种花哨的模型,但人工智能最重要的方面是数据。你需要很多,你需要好的质量。
虽然您可能听说过“数据越多越好”,但实际情况是,数据越多,质量越好。
但由于圣诞礼物预测不是一个历史悠久的领域,我只能收集一个相对较小的数据集。因此数据质量至关重要。
收集数据
给圣诞礼物快速谷歌搜索。你会发现很多图像。事实上,你会发现数百万张图片。
数百万包装完美的各种形状和大小的圣诞礼物。原始的褶皱和美丽的蝴蝶结。

由约书亚·赫内在 Unsplash 拍摄的照片
但是那些照片告诉你里面是什么了吗?号码
尽管有这些包装精美的礼物的图片,它们并没有向你展示里面是什么。理所当然,那会破坏惊喜。
然而,要建立一个模型来解决我的问题,我需要知道里面有什么。我想知道那些漂亮的盒子里是什么。
标签数据
这些礼物图片的问题在于,它们主要向人们展示的是包装精美的礼物。
圣诞老人旁边商场里那些包装完美的礼物堆?它们很可能都是空盒子。也许他们已经满了,但关键是我们不能确定。
但是我需要标签。我需要知道盒子里有什么来训练一个模型来预测未来的礼物。因此,要找到我需要的信息,我需要在其他地方寻找我的数据。
YouTube 来拯救
啊,YouTube,这个地方你可以找到几乎任何事情的视频。
这里是我实现我的解决方案的地方。我要找的不是包装好的礼物。是人们包装礼物的视频。所以在包装之前我能很好地看到礼物,也能很好地看到最终产品。
好消息是,YouTube 上有很多包装礼物的视频。很多。
这里是我为我的模型收集数据的地方。首先,我仔细抓拍包装前后的礼物截图。

包装前后的玩具(来自频道: Vinn Pang )
然而,由于数据集的性质,我不会分享数据。适当地分发数据需要所有创造者的许可,他们中的许多人并不活跃。但是他们的包装视频保留了下来。
数据集
我在那里,浏览视频,小心翼翼地使用屏幕捕捉来提取礼物的图像和里面礼物的图像,并采取额外的预防措施只选择图像中的礼物。
计划是成对收集图像。第一个图像代表实际的礼物,第二个图像是最终包装好的礼物。两张图片都有一个数字 ID,这样标签就可以使用礼品图片进行修改。

包装前后的礼物(来自频道:DIY 妈咪)
带着最后一套礼物和包装好的礼物。我还需要仔细检查并标记每张图片。这个过程将确定我要用于预测的类别。目的是将图像分成粗略的类别,每种类型有足够的图像来建立模型。
最终数据集包含 64 张不同礼物的图像。这个过程花了几个小时——只有在包装前识别礼物的视频才会被使用。此外,我希望图片能够一览无余地展示礼物。
在许多情况下,这需要一帧一帧地浏览视频,以获得没有被手臂、手或其他礼物遮挡的礼物的清晰图像。
不用说了。这是一个痛苦的过程。所以我有 64 张图片,我要让它发挥作用。
礼物的种类
你可以给别人无限不同的礼物。不幸的是,对于人工智能来说,我需要定义我试图预测的礼物类型。
我想在过于笼统或过于具体的类别之间取得平衡。
我决定以玩具、书籍、布匹和其他为主。
- 玩具包含所有与儿童玩具相关的东西。
- 书籍是书籍和其他相关的阅读材料。
- 以布料为基础的礼物包括袜子、毛衣和填充动物玩具。
- 其他包含电子产品,瓶子,香水和其他杂项。
数据扩充和处理
有了这么少的图像,我正在使用数据增强和处理图像来产生更多的模型来训练一个模型。这些增强有效地模拟了从不同的视角,也许是不同的角度或光线来观察物体。
我使用的第一种增强方式是反射和旋转。翻转垂直线、水平线和旋转可创建 4 倍数量的图像。

图像放大(来自频道: Vinn Pang
此外,我对每个图像应用灰度和大小调整来简化训练过程。灰度迫使模型学习基于形状的类,而调整大小确保我的所有屏幕截图都是模型要处理的一致大小。
数据转换(作者编写的代码)
数据扩充(作者代码)
创建模型和预测礼物
你可能已经猜到了,我将使用人工智能的一个分支——计算机视觉来预测圣诞礼物的内容。
特别是,我将使用一种叫做卷积神经网络(CNN)的深度学习模型。这些网络是图像分类的理想选择。他们使用几种不同类型的层。
模型创建(由作者编写代码)
CNN 使用卷积层、汇集层和密集层。在模型的最后,从四个类中预测一个类。
AI 猜的有多准?
和大多数人工智能问题一样,有太多可用的度量标准,你应该检查分类问题。但是,对于这个问题,我只是用精度。
模型配置和培训(由作者编写代码)
您还会注意到其他几个设计选择,比如学习调度器、加权类和 Adam 优化器。这些小选择中的每一个都会影响整体性能。
模特培训(图由作者提供)
如你所见,的模型相当糟糕。没有足够的数据,深度学习模型无法很好地从数据中学习。尽管损失在减少,但在测试集上的准确度最高为 50%。
比有四个类的 random 稍好,但肯定不是很好。玩具占了 40%的课堂,扭曲了结果。考虑到数据集的大小,剩余的性能可以有效地归因于随机性。
然而,圣诞礼物应该是神秘的。礼物会故意放在与礼物形状不匹配的盒子里。
因此,CNN 了解到的包装礼物的大部分结构特征并不总是与礼物的形状直接相关。
由于这些原因以及更多的原因,预测礼物对人工智能来说是一项艰巨的任务。因此,我不希望这个问题在一段时间内被 AI 解决,如果有的话。
包裹
最终的模型表现不太好。但是你可能已经想到了改进模型的方法。
增加更多的数据肯定会改善模型。不幸的是,深度学习模型没有足够的图像来有效预测未来的圣诞礼物。但是权衡的结果是,有更多的明确定义的图像类别来决定更多的礼物。
添加关于礼物的其他属性也应该提高性能。没有人仅凭从远处看就能猜出一件礼物。你拿起它,摇一摇,感受它的重量。所有这些肯定会有助于预测。
但正如你所见,人工智能需要数据。预测礼物并不是一项既定的任务。所以,目前来说,预测圣诞礼物里会有什么是留给孩子们在圣诞节早上去做的。
圣诞快乐!
如果你有兴趣阅读关于新颖的数据科学工具和理解机器学习算法的文章,可以考虑在 Medium 上关注我。我总是在我的文章中包含代码,您可以将其应用到您的工作中!
如果你对我的写作感兴趣,想直接支持我,请通过以下链接订阅。这个链接确保我会收到你的会员费的一部分。
https://zjwarnes.medium.com/membership
对于那些对优化深度学习模型感兴趣的人,这里有几篇我写的关于这个主题的文章。这些技术将帮助你从深度学习模型中挤出更多的性能。
使用 Google 搜索统计预测 COVID 案例
原文:https://towardsdatascience.com/predicting-covid-cases-using-google-search-statistics-4fb8814a064b?source=collection_archive---------57-----------------------

在 Unsplash 上 engin akyurt 拍摄的照片
实践教程
搜索行为分析如何为流行病学提供信息
本文涵盖的主题
- 分析谷歌趋势数据
- 使用熊猫进行重采样
- 使用 Seaborn 和 Matplotlib 可视化日期时间格式的数据
介绍
在“谷歌医生”的时代,我们倾向于在去看“模拟”医生——我们当地的医生之前,先在网上咨询与健康相关的问题。令许多医疗保健专业人士烦恼的是,在一场广泛的在线研究马拉松之后,我们到达了医生的办公室,其中包括对问题的自我诊断。
虽然对于医生来说,与那些认为自己一小时的谷歌搜索至少相当于一个全面的医学学位的患者打交道可能是一件痛苦的事情,但人们的集体在线搜索行为实际上在早期发现和定位全球疾病爆发方面具有巨大的潜力。
在这篇文章中,我们将使用谷歌搜索趋势的数据,我们将研究它如何与美国新冠肺炎病例的增加有关。所以我们先来获取一些数据吧!
注意:如果您主要是为了结果而来,请随意跳到最后的结果部分。
获取数据
我们将处理两个数据集:
- 过去 12 个月美国每天新增的 Covid 病例。
- 显示相关搜索词的谷歌搜索趋势的数据集(也是过去 12 个月)。
这个名为https://covidtracking.com/data/download的网站允许你下载美国 Covid 案例的数据,并允许在知识共享许可(CC BY 4.0)下使用。太好了!所以现在我们有了相关的 Covid 数据,我们需要从 Google 获得一些统计数据。
谷歌趋势网站(https://trends.google.com/trends/?geo=US)允许你输入想要的搜索词,并显示在给定的时间段内这个词被搜索了多少次。我输入“covid 症状”这个词,下载了美国过去 12 个月的数据。这里的假设是,人们倾向于在咨询医生之前在网上搜索他们的症状。频繁搜索“电晕症状”是否预示着即将出现新的 covid 病例?我们会看到的!
检查数据
首先,让我们看看从 covidtracking.com 下载的数据。该文件有 17 列,详细统计了新病例、康复病人、死亡人数等。
出于本文的目的,我们将只使用数据集中的两列:
- 日期:数据所指的日期(我们处理的是日常数据)。
- positiveIncrease :当天新报告的 Covid 病例数。
Google 趋势数据要简单得多,只包含两列:
- 周:数据所指的一周的第一天(我们正在处理周数据)。
- covid 症状:在给定的一周内,这个术语被搜索的相对频率。(相对的意思是,我们得到的不是谷歌搜索的绝对数量,而是按最忙的一周计算的数据。)
处理数据
Pandas 是读取和操作我们数据的首选工具。我们将从每日 Covid 病例的数据开始。
import pandas as pd
covid_df = pd.read_csv('./national-history.csv',
parse_dates=['date'])
covid_df.sort_values(by='date', ascending=True, inplace=True)
我们还按日期对数据进行排序,以确保数据是升序排列的。
接下来,我们可以导入 Google 趋势数据,并确保它是数字格式的。
google_trends_df = pd.read_csv('./multiTimeline.csv', header=1,
parse_dates=['Week'])
google_trends_df['covid symptoms: (United States)'] = pd.to_numeric(google_trends_df['covid symptoms: (United States)'])
我们需要注意的另一件事是,Google 数据是以每周总和的形式给出的,而 Covid 数据是以每天为基础给出的。因此,让我们对 Covid 数据进行重新采样,以便获得每周的累积案例,而不是每天的数据。我们分两步来做:首先,我们从日期中减去 7 天,使日期类似于所讨论的一周的第一天(就像 Google 数据的情况一样)。因此,日期 2020-03-01 指的是 3 月 1 日(日-日)从开始的一周。然后,我们将对每个 7 天期间的案例进行重新取样和汇总。
covid_df['date'] = pd.to_datetime(covid_df['date']) -
pd.to_timedelta(7, unit='d')covid_df = covid_df.resample('W-Sun', on='date')['positiveIncrease'].sum().reset_index().sort_values('date')
可视化数据
最后,我们准备开始绘制数据,并找出我们的谷歌搜索数据如何与当前的 Covid 案例相关联。
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import datetime
import seaborn as sns
sns.set()fig, ax = plt.subplots(figsize=(16, 10))plt.plot_date(covid_df.date, covid_df.positiveIncrease /
covid_df.positiveIncrease.max(), fmt='-')plt.plot_date(google_trends_df.Week,
google_trends_df['covid symptoms: (United Sates)'] / \
google_trends_df['covid symptoms: (United
States)'].max(), fmt='-')ax.xaxis.set_major_locator(mdates.WeekdayLocator(byweekday=mdates.SU
, interval=2))
ax.xaxis.set_tick_params(rotation=90, labelsize=10)
plt.xlim([datetime.date(2020, 2, 18), datetime.date(2021, 1, 31)])
plt.legend(['New Covid cases (normalized)', 'Google search for "covid symptoms" (normalized)'])plt.show()
这里发生了很多事情,所以让我一步一步地向您介绍一下。我们使用 Seaborn 库进行绘图,因为它有漂亮的默认设置和创建好看图形的简单方法。导入 Seaborn 后,应用 Seaborn 样式就像运行sns.set()一样简单。绘制以日期时间序列形式给出的数据与常规绘制略有不同,但幸运的是 Matplotlib 有一个方便的plot_date()函数,可以为我们完成繁重的工作。我还归一化了这里的数据,使两个量的比例相等。水平轴限制需要作为日期时间对象输入,使用同名模块可以轻松处理。我们得到的是下图。好的,我已经添加了一些图形元素,但是你明白了。

结果
蓝色曲线代表过去 12 个月中每周的新确诊 Covid 病例。数据表明,有三波 Covid 感染,第一波始于 3 月初,第二波始于 6 月左右,第三波始于 10 月左右。每一波都在开始几周后达到顶峰,然后下降到一个较低的水平(但仍然很高)。最后一波实际上有两个波峰,但数据可能并不完全确定。
橙色曲线显示了同一时间段内“covid 症状”一词的谷歌搜索趋势。就像新 Covid 病例的数量一样,我们在看到三波感染的同时看到了三个高峰。在谷歌的兴趣在 2-4 周内迅速上升,然后急剧下降的情况下,这些峰值要尖锐得多。有趣的是,在线搜索的峰值在每一波中都达到了近似相等的高度,并没有随着三波的严重性增加而增加。
现在到了有趣的部分,回到本文最初的问题:谷歌搜索的峰值总是出现在感染(或者说诊断)率达到峰值之前的 1-2 周。这可能指向我们最初的假设,即感到不适的人会先谷歌他们的症状,然后去看医生,并成为官方统计数据的一部分。仔细观察三月份的第一波,可以确认在美国 Corona 案例显著增加之前,谷歌在 T2 的活动增加了。当然,网上兴趣增加的部分原因可能是媒体报道的增加,以及出现了一波电晕病例的纯粹事实,人们会在谷歌上搜索症状,尽管他们感觉很好。尽管如此,这并不能解释为什么在达到 Covid 案例峰值之前,人们的兴趣会下降。然而,我们最初的假设以及谷歌搜索和疾病诊断之间的相关延迟,可以作为一个合理的解释。因此,这些数据可能有价值,可能有一些预测能力可以利用。
判决
从相关性中推导出因果关系是一条不归路,尤其是当我们处理这样的多因素关系时。虽然这个案例研究不能在这方面提供确定性,但数据的强相关性是值得注意的。搜索引擎数据的预测能力已经在过去的其他案例中得到证明,这里提供的数据表明,类似的方法可能对新冠肺炎和未来的流行病有价值。
你对搜索查询统计的有用性有什么看法?自己试试吧,也许你会比我们其他人更早知道下一个疫情…
最后声明 显然,这篇文章中的轶事分析不符合科学标准。它仅用于娱乐和教育目的。
预测迪斯尼乐园:改善你的迪斯尼日的策略
原文:https://towardsdatascience.com/predicting-disneyland-strategies-to-better-your-disney-day-e08f8b84f51?source=collection_archive---------35-----------------------
我用数学让你的迪士尼之旅更有效率

所有图片由作者提供
介绍
你的团队规模如何影响你的乘车次数?你应该先去哪个游乐设施?你在公园周围的步行距离有多重要?我希望在“预测迪斯尼乐园”的第二部分中回答所有这些问题。
在本系列的第一篇文章通过人口模拟预测迪士尼乐园的等待时间中,我展示了如何利用公园的每分钟模拟来证明走向等待时间更长的游乐设施实际上可以节省你一天中的时间。这给我留下了一些关于公园中群体决策以及某些群体属性如何影响体验的未解问题。
群体规模分析
大团队(5 人以上)比小团队(1-4 人)乘坐的次数少。有道理。更多的人意味着更多的上厕所时间,更慢的行走速度,因此,更少的乘车次数。然而,团队规模对乘车总量有多大影响呢?


左侧(公园内 21,000 人)是 COVID 后的平均上座率,右侧(公园内 51,000 人)是最大容量。图片由作者提供。
对于当前的公园游客量,左图更加准确,因为公园已经达到了最大容量的某个百分比。这向我们表明,你的团队中每增加一个人,你平均会少骑 0.33 次。在达到最大容量的日子里,每一个加入你的团队的人平均会少乘坐 0.28 次。这是有道理的,因为这些天每个人都骑得更少,走路速度也更慢。
最佳第一次乘坐
这个有点难,因为每个人都有自己最喜欢的骑行,他们把它放在所有其他骑行之上。为了衡量最好的第一次乘坐,我将查看第一次乘坐后每组进行了多少次乘坐,总共 30 次。x 轴是每个游乐设备,1-30,按字母顺序排列。

公园里的 21000 人。图片由作者提供。
前 5 名首次乘坐次数如下:
- 太空山— 16.26 次预期总乘坐次数
- 马特宏峰— 16.23 预计总乘坐次数
- 印第安纳·琼斯——16.15 次预期总乘坐次数
- 大雷山— 15.44 次预期总乘坐次数
- 丛林巡游——预计总共 15.24 次
前三名是公园中最繁忙的游乐设施,并且靠近公园的前面,所以对大多数人来说,他们是首选。这也表明,尽早摆脱大型游乐设施可以增加你的游乐设施数量。这是因为当他们的等待时间远远低于一天的平均时间时,你正在乘坐更大的游乐设施,所以你比其他人节省时间。
但是从最差的 5 次乘坐开始呢?(不包括模拟中未被任何人选为第一游乐设备的 7 个游乐设备)
- Autopia — 13.25 次预期总乘坐次数
- 兔子罗杰的汽车卡通旋转-13.14 预期总乘坐次数
- Gadget 的 Go 过山车——预计总乘坐次数为 12.93 次
- astro Orbiter——12.75 预计总乘坐次数
- 这是一个小世界——预计总乘坐次数为 12.45 次
离入口较远的游乐设施会导致较少的预期总游乐设施,因为在你走向它们的时候,所有其他大型游乐设施会看到更多的人排队。此外,不应该首先选择像小世界(10 分钟以上)这样乘坐时间长的游乐设施,因为这样会错过大型游乐设施的低等待时间。
到达时间和步行距离
早一点到达(或晚一点停留)会决定你要去的游乐设施的数量吗?你要走多远才能称你的迪士尼日为成功?
为了确定一个小组在公园的表现,我把他们当天的所有成绩加到一个大的分数上。这可以与公园里的其他人进行比较,以了解团队的表现。我还用谷歌地球开发的距离矩阵计算了一组人行走的总量。我用这些信息做了一个散点图,用从深到浅的颜色来显示到达时间在分数上的差异(颜色越亮意味着在公园的时间越长,颜色越暗意味着时间越短)。

图片由作者提供
总的来说,看起来得分高的日子确实要多走。这是有道理的,因为更高的得分需要更多的骑行,这需要更多的步行。你还应该注意到,那些在公园里呆的时间越长的小组(黄色圆圈)通常得分越高。
乘坐之间的步行距离
骑行间隔少的组得分高吗?
我使用了大致相同的散点图,但 x 轴是乘坐之间的平均距离,而不是总距离。

图片由作者提供
似乎乘车之间的平均步行距离只对晚一点到达公园(或早一点离开)的那组人有影响。深蓝组(在公园里呆的时间最少),他们的步行距离变化很大,平均每天得分变化不大。另一方面,那些在公园时间最多的人平均步行距离更短,一天的得分更高。
结论
你的团队规模如何影响你的乘车次数?
实际上,没我想的那么多。对于一般人群来说,你的团队中每多一个人,你的一天就会减少 0.33 次乘坐。如果额外的 0.33 次乘坐对你来说很重要,那么你绝对应该一个人去迪士尼旅行。单人骑行、只属于你自己的洗手间和一个人的移动订购最终会为你节省很多时间。
你应该先去哪个游乐设施?
三巨头:太空山、马特宏峰或印第安纳琼斯。在第一个小时内干掉其中两个肯定会让你的迪士尼之旅轻松许多。当等待时间远远低于平均水平时,乘坐这些交通工具可以节省你几个小时。
你在公园散步的距离有多重要?
迪士尼乐园一天的总距离确实与更好的分数有一些关联。如果你想坐更多的车,你必须跑 7-10 英里。骑行之间的平均步行距离和更高的分数之间也有一些关联。一般来说,那些走路效率更高的人骑得更多,日子也更好。那些较晚到达的人应该考虑选择离他们刚刚下车的地方更近的下一次乘坐,因为随着乘坐之间的平均步行距离的增加,分数会下降相当多。
我认为接下来应该问的一些问题是,是什么让那些散点图顶部的那些组如此成功?他们的第一次乘车、到达/离开时间或乘车顺序是什么?所有这些因素都可以向我们展示一个理想的迪斯尼乐园计划是什么样子的,它可能是你下次旅行可以实施的东西。
通过人口模拟预测迪士尼乐园的等待时间
原文:https://towardsdatascience.com/predicting-disneyland-wait-times-through-population-simulations-20f44c7582f6?source=collection_archive---------17-----------------------
利用每分钟的模拟来分析迪士尼乐园内的人群决策

所有图片均由作者提供
介绍
如果你曾经计划去迪斯尼乐园旅行,你就会知道检查人群水平有多重要。只需要一次意想不到的人群涌动就能把地球上最快乐的地方变成完全相反的地方。十年前,这可以简单地通过一周中的旅行来避免,但是现代的迪斯尼乐园没有休息日。
这个项目的灵感来自于我最近的迪士尼乐园之旅中的一次乘车选择。加州冒险公园的灰熊河急流已经等了几个小时,等待时间长达 45 分钟,由于担心我们必须等到当天晚些时候气温下降,我们开始了向公园那一边的跋涉。排队 5 分钟后,我们注意到等待时间变成了 25 分钟。我们觉得我们玩了这个系统,因为这个举动节省了一些时间。
这让我想到,走向等待时间比平均时间长的游乐设施是明智之举吗?这听起来违反直觉,但在思考我们那天所做的所有选择后,很明显,如果我们觉得不值得等待,我们会避免乘坐。例如,70 分钟的太空山——不,谢谢,我们会等着看它是否会下降。《20 分钟后的雷山》——当然,这似乎很合理。假设一般人都是这样想的,那么灰熊河急流城有时会出现相对较大的落差是有道理的。人们看 45 分钟,然后等到更晚,所以由于排队的人越来越少,所以它下降了。如果你把握好时机,你就可以插队了,因为那里的人已经最少了。于是,一个模拟诞生了。
构建模拟
编写 MATLAB 代码的第一步是确定迪士尼乐园一天的总人数。迪士尼乐园的容量约为 85,000 人,在 COVID 期间,他们开始时只有 25%的容量(但自 5 月以来肯定增加了)。这使得我们的后 COVID 人群每天约有 21,000 人。这个数字用于模拟是不准确的,因为我们知道迪士尼乐园没有 21,000 名单身乘客。这些都是各种规模的家庭,因此项目必须与之相匹配。平均家庭规模是 3-4 人,但我在这个模拟中平均定为 3.78 人。现在我们只关注 5500 组不同的人在做决策,这可以大大加快模拟的速度。
每个组还必须分配其他属性,例如位置、他们在做什么、步行速度、乘车历史和到达/离开时间。
- 每组被分配一个数字,0-30,代表他们当前的位置(0 代表入口,1-30 代表 30 种不同的游乐设施)。
- 基于该组是在步行、排队还是在乘车,给他们一个值。
- 行走速度值是根据团队规模分配的,一个单独的骑手显然会比 10 个人的团队走得更快(而且也更少停下来上厕所)。
- 乘坐历史很重要,因为当提示一群人选择乘坐时,你希望有一些可变性,这样乘客就不会重复选择乘坐马特宏峰。
- 到达和离开的时间很重要,因为不是每个人都在公园开门的时候到达,也不是每个人都呆到关门。这些是基于公园出席人数与时间的预设分布随机确定的。
还有一些属性需要分配给公园中的每个游乐设施。诸如刺激、多少是“必须乘坐”、当前等待时间、乘坐容量(乘客/小时)和乘坐时间长度。
为 30 个游乐设备中的每一个与入口之间的距离分配最后一个数据矩阵。没错,一个 31 乘 31 的谷歌地球数据矩阵来表示从任何一个乘坐到另一个乘坐的距离。
现在,我们拥有了运行模拟迪士尼乐园日所需的所有工具,并获得了一些结果。
运行模拟
假设我们有总数为 5,500 的前 3 组,看看决策是什么样的(从一天开始)。
A 组:4 人,位于入口处,平均步行速度,无骑行史
B 组:2 人,位于入口处,行走速度快,无骑行史
C 组:7 人,位于入口处,行走速度慢,无骑行史
如果一个团体需要一个新的游乐设施,它会被提示选择一个。但是,它不会随机选择一个。基于上面列出的游乐设备属性,为每个游乐设备给出该组的偏好分数。在对游乐设施评分时,从当前等待时间、步行距离到可变性的一切都要考虑在内。然后,以给定的预设分布选择前 10 名(通常大约 25%的机会获得最高分的乘坐,然后 15%的机会获得第二名的乘坐,等等。)并且所选择的乘坐被分配给该组。根据骑行的距离和他们的步行速度,给这组人一个步行时间,然后他们开始一分钟一分钟地步行。这是为所有需要乘坐的组完成的,在我们的例子中是所有的组,A、B 和 c。
假设 A 组选择印第安纳琼斯。他们被分配了 5 分钟的步行时间。B 组选择太空山,并被分配 4 分钟的步行时间。C 组也挑了印第安纳琼斯,他们的行走时间是 10 分钟(一组 7 人 vs 4 人)。所有这些时间结束后,会根据排队人数和乘坐量(乘客/小时)为乘客分配等待时间。等待时间结束后,他们会被分配一个唯一的乘坐时间。乘坐时间结束后,他们会被提示选择下一次乘坐,循环继续。
这种情况持续一天中的每一分钟,并且每一次乘坐都记录该分钟的等待时间,以便在一天结束时以图形表示。
结果
下面显示的是一天 21,000 人的所有 30 个游乐设施的曲线图,开放时间为早上 8 点到晚上 10 点(x 轴上的 0 到 840)。

一些需要注意的事项:
- 《海底总动员》将在 2021 年冬季上映,所以这就是为什么这个情节在 0 分钟。
- 这只是一个模拟,意味着可能的数据点的实际范围比显示的要大。
- 不考虑游乐设施的停机时间,但将其计入游乐设施容量,因为这是无法预测的。
- 像飞溅山这样的水上游乐设施有一个特殊的评分方法,因为一天中较温暖的时间会增加等待时间。
- 游乐设施在开放时需要 1 分钟的等待时间,因为穿过开放的队列需要时间。
让我们来看三个具有不同等待时间曲线形状的单独乘坐(x 轴是实际时间,上午 8 点为 0,晚上 10 点为 840,y 轴是以分钟为单位的等待时间)。

Autopia 在公园开放后的 2-3 小时内有一个非常陡峭的增长,很可能是因为它靠近太空山和马特宏峰。一天中前半段等待时间的变化是排队时时间安排是多么重要的一个很好的例子。中午 12 点和 12:30 之间相差 10 分钟左右,比较显著。在现实生活中,如果你看到 Autopia 要等 30 多分钟,也许你可以走到那个区域,看它下降 5-10 分钟。

加勒比海盗的外形与 Autopia 有很大不同,每分钟的变化更少。它有一个很高的初始曲线,在中午左右慢慢消失,所以对于这个特定的例子,最好在上午 10 点之前或下午 4 点之后乘坐加勒比海盗。在一天结束时,下降可能是由于水骑方面,或者也许这是一个大多数人已经骑过,不想回去的骑行。

飞溅山是水骑效应的一个极端例子,这意味着它在一天的第一个和最后一个小时的等待时间非常短。它在几分钟之间有一些不错的波动,所以正确的计时可以让你节省 10 分钟的等待时间。
只有当模拟在精确匹配现实方面做得很好时,这才是真正重要的。在撰写本文时,即 8 月 5 日下午 1 点,三个示例的等待时间如下:
- Autopia — 20 分钟
- 《加勒比海盗》——45 分钟
- 飞溅山——65 分钟
根据这个模拟,下午 1 点的估计等待时间如下:
- Autopia — 22 分钟
- 《加勒比海盗》——43 分钟
- 飞溅山——53 分钟
《Autopia》和《加勒比海盗》非常接近现实,而《飞溅山》则明显低一些。这可能是由于气温较高,或者印第安纳琼斯当时正在下降,所以更多的骑手可能已经转移到飞溅山。
结论
当所有游乐设施运行正常,游客做出合理决定时,用这种模拟预测等待时间是相当可靠的。波动较大的游乐设施是那些在公园里做决定时时间安排得更好的游乐设施。走向那个游乐设施会对你的一天有益,每次可以节省你 5-10 分钟。
这种模拟可以很容易地改变以匹配预测的人群数量、游乐设施关闭、游乐设施增加和停车时间。游乐设备翻新会增加等待时间,可在该游乐设备的“必须乘坐”属性内进行更改,以反映新的等待时间。
这种模拟可以采取的一些后续步骤包括快速通行证、食物休息、游行和表演时间,以及登机牌对等待时间的影响。
此外,观察团队规模如何影响团队乘坐的次数,或者随着人群的增加等待时间如何变化可能会很有趣。调查最成功的团体和他们的决定也可以证明是那些真正想在迪斯尼乐园消磨一天的人的一个很好的模板。
回答我在这个项目中遇到的主要问题:是的,对于特定的乘坐项目来说,走向那些长的等待时间确实是有益的,但是对于其他人来说,就不那么有益了。高优先级游乐设施,如太空山、马特宏峰、印第安纳琼斯和千年隼,一天中不会有太多变化,除非你能在它从临时关闭重新开放时掌握好时间。然而,它表明,其他游乐设施有相当多的变化,你可以利用,也许会在你的迪士尼乐园一天多坐一两次。
预测 EEOC 歧视调查
原文:https://towardsdatascience.com/predicting-eeoc-discrimination-investigations-aa007ea470c8?source=collection_archive---------39-----------------------

丹尼尔·雷彻在像素上拍摄的照片
结果是暗淡的。
这篇文章的主要目的是分享一个数据科学项目的结果,该项目涉及预测美国平等就业机会委员会(EEOC)对就业歧视索赔的调查结果。这是一个高度不平衡(99:1)的二元分类问题。因此,目标是建立一个模型,可以最好地预测目标少数民族阶层,这是 EEOC 发现就业歧视的优点。长话短说,很难可靠地预测歧视调查,EEOC 会发现优点。这可能是由于数据质量差。
在过去的几年里,几位记者报道了歧视指控的状况以及 EEOC 调查这些指控的能力。这项研究的目的是看看调查结果是否可以预测,以帮助 EEOC 在预算不足的情况下开展调查。然而,应该注意的是,在创建有意义的模型之前,数据质量还有很长的路要走。目前,由于几十年的预算不足和一个没有真正能力保护大多数遭受就业歧视的人的机构,这些数据是有偏见的。因此,所使用的数据不能提供完整的信息,基线可能低估了美国歧视索赔的真实性质以及 EEOC 通过调查确定歧视的全部能力。
数据来自公共诚信中心,包括 2010 财年所有的歧视索赔。
一、争论数据
数据争论有三个部分:创建目标变量、工程特征、输入分类值,以及丢弃冗余或容易泄漏的变量。

目标变量(决策)根据“结束类型”进行了简化,以包括两种可能的结果:发现歧视和没有发现歧视。虽然从技术上讲,索赔可以结案,但不能做出任何决定。例如,如果 EEOC 需要或将需要 180 天以上的时间来完成调查,投诉人可以要求通知有权起诉(NRTS)。这样,EEOC 将自动结束调查,并且不会做出歧视的决定。
一些额外的功能被设计来尝试和提高模型的预测能力。这些因素包括:提出申诉时的“年龄”,“NAICS 准则”扩大到了行业层面,“调查持续时间”,以及申诉人是否获得了“金钱利益”
二。分割数据
该模型基于 2010 财政年度的时间序列数据。因此,数据按比例分割,以保持时间顺序。定型数据是前 60%的行,验证集和测试集各占 20%。
三。建立基线
在严重不平衡的二进制分类问题中,基线是由少数群体的普遍程度建立的。对于该数据集,发现区分价值的调查为 0.0127。该分数将在评估阶段根据精确召回曲线下面积(PR AUC)分数进行衡量。
四。建立模型
SimpleImputer 和 StandardScaler 应用于数字特征,OrdinalEncoder 和 BinaryEncoder 分别应用于序数和名词性分类特征。
该数据集的基本模型是逻辑回归,替代模型是随机森林。为了评估他们的表现,我将使用平均加权的 f1_score 和 PR AUC 分数。
线性模型:逻辑回归

无调整的逻辑回归
开箱即用的逻辑回归模型返回了 0.033 的精确召回 AUC 分数,略好于基线。但是 f1_score 是< 0.50 which most likely indicates that the model is not predicting any of the claims as having discrimination.
套袋模式:随机森林

无调整的随机森林
在没有调整的情况下,随机森林模型返回的 PR AUC 得分为 0.092,明显优于逻辑回归模型和基线。f1_score 也大于 0.5,这可能意味着模型将一些索赔归类为有歧视的原因。另一个好迹象。
混淆矩阵
下一步是将更好的拟合模型 Random Forest 应用到我们的测试数据中,看看它的表现如何。我们可以使用混淆矩阵来实现这一点。为了进一步说明项目的结果,我为验证和测试集添加了一个混淆矩阵。


l:验证集的混淆矩阵;r:测试集的混淆矩阵
从这些矩阵中我们可以看出,这些模型在预测歧视方面没有实际用途,特别是在索赔数量特别低的情况下(测试集只包括 146 项确定存在歧视的索赔)。在验证集上,我们可以看到很高的精度,但这是一个难以置信的损失。
在我们让政府机构承担责任的实际环境中,如果预测模型具有较高的召回率,它将为员工的最佳利益服务。这意味着它准确地检测到了所有发生就业歧视的情况。通常,这也意味着它会得到一些错误的预测(即,一个实际上没有歧视的声明被标记为有歧视)。虽然一个高精度的模型不能捕捉所有真实的歧视案例,但当它预测一个索赔有价值时,它总是正确的。实际上,在这些措施之间几乎总是有一个权衡。
排列重要性
我们还可以考虑模型中使用的特征的排列重要性,这也反映了它们的弱点。

理想情况下,我们希望特性具有积极的重要性,因为这是它们具有预测能力的标志。在这种情况下,我们所有的特征都有积极的重要性,但它们的大小相当小(接近于零)。
五、结果+建议
调查结果揭示了歧视索赔数据质量的一些缺陷,以及 EEOC 调查的模糊性。很难相信许多特征会有如此小的预测能力,但这可能是由于缺乏其他重要的变量。最明显的是围绕调查程序。不清楚它们是否标准化,也不清楚对索赔做出决定的门槛是什么。我们也不知道 EEOC 如何评价员工及其雇主提供的证据的力度。
公共诚信中心有一个更大的数据集,涵盖了 2011 年至 2017 年的歧视指控。用更多的数据再次尝试这个项目可能是值得的。如果能够建立一个具有真正预测能力的模型,我们应该质疑高精度是否优先于低召回率。否则,将很难知道 EEOC 进行调查的真正效力。
该项目的 GitHub 资源库。
https://www.vox.com/identities/2019/6/14/18663296/congress-eeoc-workplace-discrimination
华盛顿州电动汽车和商用充电器需求预测
原文:https://towardsdatascience.com/predicting-electric-vehicle-commercial-charger-demand-in-washington-state-feb04960feb1?source=collection_archive---------23-----------------------
哪些华盛顿县将拥有最多的电动汽车,需要最多的商用充电器?
如果你在过去的几个月里走出户外,你很可能会比其他任何一个夏天都更想吃一勺正在融化的冰淇淋。根据 NOAA 国家环境信息中心的数据,2021 年 6 月全球陆地表面温度是有记录以来最高的,这不是巧合。这些极端温度的发生是由于大气中温室气体的增加,这也被称为气候变化。

照片由 Clark Douglas 在 Unsplash 拍摄
那么,有什么解决办法呢?
这个问题非常复杂,没有一个放之四海而皆准的解决方案;然而,减少并最终消除由化石燃料驱动的车辆造成的温室气体排放将有益于环境。根据美国环境保护署(EPA)的数据,“交通运输的温室气体(GHG)排放约占美国温室气体排放总量的 29%,是美国 GHG 排放的最大贡献者。”
有鉴于此,在过去几年里,气候变化已成为美国和世界各地官员日益紧迫的关切。目前,在美国,乔·拜登总统和他的政府正在努力通过一项两党基础设施协议,该协议将优先采取以下行动:
- 在高速公路沿线、农村和贫困社区建设由 500,000 个电动汽车(EV)充电器组成的全国网络。
- 为全国数千辆校车和公交巴士供电,以减少有害排放,推动零排放车辆和零部件的国内制造。
- 通过现代化和扩大全国范围内的交通和铁路网络,改善数百万美国人健康、可持续的交通选择,同时减少温室气体排放。

丘特尔斯纳普在 Unsplash 上拍照
除了国家层面的大规模政策建议,一些州也在自行采取行动。例如,加利福尼亚州和华盛顿州都在努力分别在 2035 年和 2030 年强制推行电动汽车,以逐步淘汰使用汽油的汽车。此外,在私营部门内,几家主要的汽车制造商(如福特、通用、沃尔沃等。)已经宣布,他们将在未来十年内实现全电动化,这将被证明是汽车行业的一次重大变革。总而言之,如果实施的话,公共和私营部门的这些变化将导致电动汽车(ev)以及商用电动汽车充电器需求的大幅增长。
我们决定利用我们的数据科学超能力,找到未来电动汽车需求最大的领域,并为电动汽车充电公司提供建议。这里可以找到分析。
数据
首先是数据。我们决定从华盛顿州的 API 中收集关于华盛顿州电动汽车所有权和注册活动的数据。这导致我们在 2010 年至 2021 年间有 433,172 笔电动汽车交易。由于我们试图预测随着时间的推移将有多少辆电动汽车上路,我们最终放弃了所有注册信息,使用了 91,255 个所有权交易。
定义“区域”
我们最初的计划是通过邮政编码集中分析这些数据;然而,由于时间限制,我们决定用县来代替。然后,我们对这些信息进行了重新采样,以反映每个县每月购买电动汽车的数量。但是,我们必须将这些信息转化为每个县一段时间内的电动汽车总数,所以我们取了这些数据的累计总和。此时,数据集已准备好用于时间序列建模。
这项分析包括哪些县?
同样,由于时间限制,我们决定将重点放在华盛顿州电动汽车交易最多的前 10 个县。这些县包括:本顿、克拉克、海岛、金、基特萨普、皮尔斯、斯诺霍米什、斯波坎、瑟斯顿和沃特科姆县。
这一阶段的数据是什么样的?
看看全州的电动汽车数量,也许并不奇怪,我们可以看到,在过去 10 年里,华盛顿州道路上的电动汽车数量一直呈指数增长。

在很高的层面上,这证实了华盛顿州有必要的电动汽车需求趋势,使投资电动汽车充电公司有利可图。
从单个县来看,我们发现金县的发展速度比其他县快得多。这是意料之中的,因为金县包括西雅图,西雅图是华盛顿州人口最多的城市。

建模
我们的工作流程在每个县都是一样的。在分解数据并查看电动汽车数量的趋势和季节性后,我们将数据分为每个县的训练集和测试集。在将 SARIMAX 模型拟合到训练集之后,我们使用了一个名为 pmdarima 的库,根据 AIC 分数为每个模型找到最佳参数。然后,我们预测“未来”,并将该信息与测试集进行比较。如果预测值与观察到的数据一致,我们继续将另一个 SARIMAX 模型拟合到整个观察到的数据(训练+测试集),并对每个县未来的电动汽车数量进行预测。如果不是,我们重复不同的训练测试分割,直到预测接近观察到的数据。
那么,哪个县将拥有最多的电动汽车呢?
我们的模型预测国王县将在 2023 年拥有最多的电动汽车。准确的说是 74875。斯诺霍米什县以 17,117 辆远远落后于第二名。

观察到的(左)与预测的(右)每个县的电动汽车数量。
但是,这有点误导。我们的分析目标是找到最有潜力投资电动汽车充电公司的县。我们必须考虑的一个主要因素是现有的充电基础设施。毕竟,如果一个国家已经有一船可用的充电器,那么商业充电市场可能已经饱和,即使未来几年将有更多的汽车上路。
更多数据!
因此,我们决定从国家可再生能源实验室(NREL)的 API 中收集现有充电基础设施的数据。我们最终在华盛顿州建立了 1686 个充电站(如果您想查看每个充电器的确切位置,请点击此处)。以下是各县充电站数量的明细:

华盛顿州充电站数量(截至 2021 年 6 月)。

华盛顿电动汽车充电器的位置(截至 2021 年 6 月)。
正如我们在这里看到的,华盛顿州大约 50%的充电器位于金县。因此,如上所述,国王县充电器市场可能已经饱和,可能不需要更多的充电器。
我们如何在相对的基础上比较各县?
为了能够在各县之间进行比较,我们设计了一个指标“每个充电器的电动汽车数”,这是 2023 年电动汽车的预计数量除以每个县现有充电站数量的比率。该比率越高,预计该县未来的服务水平越低,这可能会转化为电动汽车充电公司的更多机会。当我们根据这一指标对数据进行排序时,我们发现,与其他 10 个县相比,国王县确实不太理想:

按电动汽车/充电器比率分类的数据。
上图中,电动汽车每充电器指标排名前四的县是 Island、Clark、Snohomish 和 Whatcom。然而,当我们考虑以下因素时,尽管 Island County 的电动汽车/充电器比率领先,但我们得出的结论是,它不是一个真正的竞争者。
等等,为什么岛县出局了?
首先,岛屿县由一系列岛屿组成,主要是住宅建筑和国家公园,很少有商业中心和办公楼。根据 JD Power 的一项研究,“80%的电动汽车充电是在家里进行的——几乎总是在夜间进行——或者在工作日停车时进行。”因此,居住在该县的电动汽车车主很可能会在自己家里为他们的汽车充电,而不是使用商业充电站。此外,由于土地的限制,该县的人口在未来可能会停滞不前,这可能会转化为对电动汽车的需求,因此充电器也会停滞不前。

描述所有 10 个县的电动汽车/充电器比率的地图。这可以在项目仪表板中以互动形式获得。
结论
总而言之,电动汽车背后的动力——由最近的技术和政策进步产生——使今天成为投资充电基础设施的理想时机。作为在电气化交通方面领先的州之一,华盛顿州是美国建设新充电站的最佳地点之一。
我们认为,对于电动汽车充电公司而言,以下县(按排名顺序)具有巨大的高盈利潜力:
1。克拉克县
2。斯诺霍米什县
3。Whatcom 县
如果你想看我们的交互式仪表盘,你可以点击这里查看。否则,可以在 GitHub 上查看完整的分析。
来源:
NOAA 国家环境信息中心,气候状况:2021 年 6 月全球气候报告,2021 年 7 月在线发布,2021 年 7 月 28 日从https://www.ncdc.noaa.gov/sotc/global/202106检索。
环保局。(2021).交通运输产生的碳污染。环保局。https://www . EPA . gov/transportation-air-pollution-and-climate-change/carbon-pollution-transportation。
福尔克尔,J. (2021 年 2 月 5 日)。福布斯。https://www . Forbes . com/wheels/news/JD-power-study-electric-vehicle-owners-prefer-dedicated-home-charging-stations/。
用 XGBRegressor 预测用电量
原文:https://towardsdatascience.com/predicting-electricity-consumption-with-xgbregressor-a11b71104754?source=collection_archive---------24-----------------------
千瓦消费模式的时间序列分析

来源:图片由 3938030 发自 Pixabay
在本例中,XGBRegressor 用于预测爱尔兰都柏林市市政办公室的千瓦消耗模式。正在讨论的数据集可从 data.gov.ie获得。
XGBRegressor 是什么?
你以前用过 XGBoost(极限梯度提升)做分类任务吗?如果是这样,您将会熟悉这个模型的工作方式。
本质上,梯度推进模型通过以连续的方式将预测器添加到集合中来工作,新的预测器适合于由先前的预测器产生的残差。Aurelien Geron 的《Scikit-Learn & TensorFlow 机器学习实践指南》很好地概述了这一模型背后的理论,我建议参考该指南以获取更多信息。
XGBRegressor 试图完成同样的事情,唯一的区别是我们使用这个模型来解决回归问题,即结果变量是数字的。
特别是在时间序列的上下文中,XGBRegressor 使用时间序列的滞后作为预测结果变量的特征。
数据操作
在深入研究 XGBRegressor 模型之前,让我们看一下数据集本身。
原始数据集以 15 分钟为间隔显示每天的用电模式。
df = pd.read_csv('dccelectricitycivicsblocks34p20130221-1840.csv', engine='python', skipfooter=3)
df

来源:Jupyter 笔记本输出
为此,我们倾向于每天分析数据——每 15 分钟分析一次消费模式可能会给时间序列带来太多波动,从而无法识别数据中任何有意义的模式。
通过对每 15 分钟的消耗模式求和,将数据整理成每日格式,如下所示:
df2=df.rename(columns=df.iloc[0])
df3=df2.drop(df.index[0])
df3
df3.drop(df3.index[0])
df4=df3.drop('Date', axis=1)
df5=df4.drop('Values', axis=1)
df5
df6=df5.dropna()
df7=df6.values
df7
dataset=np.sum(df7, axis=1, dtype=float)
dataset
该数组现在以 numpy 格式显示,如下所示:

来源:Jupyter 笔记本输出
以下是日常消费模式的折线图:

来源:Jupyter 笔记本输出
现在,每天的时间序列已经形成,数据被分成训练和测试分区。
train_size = int(len(df) * 0.8)
test_size = len(df) - train_size
train, test = df[0:train_size,:], df[train_size:len(df),:]
然后创建数据集矩阵,将时间序列的滞后存储为特征:
def create_dataset(df, previous=1):
dataX, dataY = [], []
for i in range(len(df)-previous-1):
a = df[i:(i+previous), 0]
dataX.append(a)
dataY.append(df[i + previous, 0])
return np.array(dataX), np.array(dataY)
分析
下面的分析使用了来自机器学习大师的教程作为模板。
在配置 XGBRegressor 模型时,第一步是确定回望期,即模型在预测时间 t 的消耗值时应考虑多少个前期?

来源:Jupyter 笔记本输出
在分析自相关函数时,数据中似乎存在每周季节性,即消费相关性的峰值每隔 7 个滞后出现一次。
在这方面,为模型选择了 7 的回望期。
# Lookback period
lookback = 7
X_train, Y_train = create_dataset(train, lookback)
X_test, Y_test = create_dataset(test, lookback)
XGBRegressor 现在适合训练数据。
from xgboost import XGBRegressormodel = XGBRegressor(objective='reg:squarederror', n_estimators=1000)
model.fit(X_train, Y_train)
最初在集合中使用 1,000 棵树,以确保对数据的充分学习。然而,n 估计量的数量将被修改,以确定是否可以用较低的值获得相同水平的精度。
目标设置为 'reg:squarederror' ,即平方损失回归,对极值误差的惩罚更重。
然后,使用该模型对测试数据进行预测:
testpred = model.predict(X_test)
Y_test (实际测试值)和 testpred (预测值)均经过整形,以便使用均方根误差比较模型精度。
Y_test=Y_test.reshape(-1,1)
testpred=testpred.reshape(-1,1)
RMSE 现在计算出来了:
>>> import math
>>> from math import sqrt
>>> test_mse = mean_squared_error(Y_test, testpred)
>>> rmse = sqrt(test_mse)
>>> print('RMSE: %f' % rmse)RMSE: 437.935136
让我们将其与测试数据的平均值进行比较:
>>> np.mean(Y_test)3895.140625
误差的大小约为整个测试组的平均千瓦消耗值大小的 11% 。这表明该模型在预测相关消费趋势方面做得相当好。
修改树的数量
现在,还记得在获得这个值的过程中使用了 1000 个估计值吗?如果我们决定降低这个值呢?让我们试试 300 个 n_estimators。
>>> import math
>>> from math import sqrt
>>> test_mse = mean_squared_error(Y_test, testpred)
>>> rmse = sqrt(test_mse)
>>> print('RMSE: %f' % rmse)RMSE: 437.930710
我们可以看到,获得的 RMSE 实际上是相同的——这意味着该模型在预测整个测试集的千瓦消耗方面做得一样好。
当用 20 棵树做实验时,RMSE 略微上升到 440,在 10 棵树时,RMSE 上升到 471。
这意味着在构建该模型时应至少使用 20 棵树。然而,XGBRegressor 似乎不需要太多的训练来学习数据的模式-存在每周季节性和使用 7 的回顾期的事实表明,在模型中包括适当数量的滞后作为特征比简单地向模型中添加更多树的额外训练更重要。
在这个问题上,和其他问题一样,数据是王道。
结论
在本例中,您看到了:
- 如何正确处理时间序列数据以进行正确的分析
- XGBRegressor 的使用以及如何适当地修改模型参数
- 跨测试集确定模型准确性时的 RMSE 计算
- 如何确定在模型中使用的合适的树的数量
非常感谢您的参与,您可以在michael-grogan.com找到更多我的数据科学内容。
免责声明:本文是在“原样”的基础上编写的,没有担保。本文旨在提供数据科学概念的概述,不应被解释为任何形式的专业建议。作者与本文提及的任何第三方无任何关系。
预测爱尔兰过剩的风力发电:应对气候变化的机器学习
原文:https://towardsdatascience.com/predicting-excess-wind-electricity-in-ireland-machine-learning-against-climate-change-part-1-d042894026a6?source=collection_archive---------13-----------------------
变更数据
机器学习算法能否发现复杂电力网络中的隐藏模式,从而进行可靠的预测?
不断变化的消费模式、电网约束和突然变化的天气条件之间的时间序列预测可能很棘手。我们很高兴分享我们在一系列 ML 算法方面的经验,以帮助我们优化电力消耗并减少碳足迹!

RawFilm 在 Unsplash 拍摄的照片
我们将解释我们试图解决什么问题,我们使用、探索(EDA)什么数据,以及我们如何处理缺失数据、共线性、异常值和特征变换,以便为稳健建模做好准备。
然后,我们将涵盖机器学习/神经网络模型候选,具有强烈趋势的时间序列的特定训练/验证分割,以及模型和 剧透警报 默认 EirGrid 预测之间的结果比较!
问题是
与 1990 年的水平相比,可再生能源是欧洲到 2030 年减少至少 55%碳排放计划的基本要素。我们探索了爱尔兰的情况和风力发电的潜在智能使用。
“在爱尔兰,未来十年的能源需求增长在低需求情景下的 23%和高需求情景下的 47%之间变化。”根据eir grid 2019–2028全岛发电能力声明。
截至 2018 年,风能贡献了 80%的可再生电力和 30%的总电力需求。爱尔兰的目标是将可再生电力增加到总发电量的 70%,欧盟的目标是到 2030 年达到 32%。然而,业界越来越担心每年“损失”的风能数量。2020 年,这相当于超过 140 万兆瓦时的电力,几乎是 2019 年的两倍。根据风能爱尔兰 2021 报告,这不到总产量的 11.5%,足以为超过 30 万个家庭供电。
但是为什么要“浪费”权力呢?
传输系统运营商(TSO),爱尔兰的 EirGrid,负责始终平衡从发电流向消费者的电力。

图 1 —电网必须始终保持发电和需求之间的平衡。作者图片
当发电量超过耗电量时,TSO 调节杆受到限制:
- 将电力转向“存储”:在爱尔兰,将水泵送到特劳山电站(但有限制)
- 出口(市场允许)到英国:最大。1 GW 连接(Ewic + Moyle)
- 要求天然气/煤炭发电厂减速,但是减速可能需要几个小时
- 目前,风力/太阳能发电的最大比例受到系统非同步渗透率(SNSP)“2018 年 Q1 的当前比例为 65%”和最近增加到 70%的非同步可再生能源水平的限制。
- “可再生能源调度下降”(限制和削减):基本上是将风电场与电网断开,导致风能“损失”,这可以在 EirGrid 集团系统和可再生能源报告中看到。
欧洲绿色协议将促进对电网的大量投资,以支持更高比例的可再生能源,然而,可再生能源容量将大幅增加,导致更多的“浪费”电力。
消费者和工业用户的行为也需要改变,这是这个项目的重点。如图 2 所示,如果风电预计达到当前的 70%,则:
- 工业用户(如数据中心)可以为电池充电以备后用。
- 消费者可以设定他们的电器在这些时间运行,例如:1)给电动汽车充电;2)启动带有滚筒式烘干机的洗衣机;3)增加热泵等。

图 2—www.smartgriddashboard.com风力发电可能被“浪费”的例子
数据

图 3 数据来源:由 EirGrid 集团数据和 Metéireann 数据支持
- Metéirean data:Copyright Metéireann,Source www.met.ie ,许可声明:该数据在知识共享署名 4.0 International (CC BY 4.0)下发布。
- 爱格瑞集团数据:爱格瑞集团数据支持,来源:【www.smartgriddashboard.com】T4,开放数据许可 e
如图 3 所示,从爱尔兰岛的 EirGrid Group 下载了一个包含 2017 年 1 月至 2021 年 2 月 145,936 个观测值的风电数据集,因为爱尔兰共和国和北爱尔兰是一个集成的单一电力市场(I-SEM)。数据描述了风力发电和电力需求的样本,频率为 15 分钟。为了构建完整的画面,爱尔兰岛上安装的总风力容量每月在“Eirgrid Group,Tech .“[系统和可再生能源数据汇总报告”中报告。众议员,2020](https://www.eirgridgroup.com/site-files/ library/EirGrid/System- and- Renewable- Data- Summary- Report.xlsx) 。
从 Metéirean 下载的历史天气信息描述了位于香农机场、都柏林机场、科克机场和贝尔穆莱特的四个气象站的每小时天气(37,225 行),因为许多并网风力发电场位于附近,并且都柏林是受电力消耗影响的主要人口中心。此外,在工作的后期阶段,即使是最好的模型也低估了都柏林低风速时的风力发电。我们意识到在爱尔兰北部风速很高,在那里我们没有具体的气象站数据。因此,马林首站的气象数据也被选入气象数据集中。
数据质量、缺失数据和异常值
总的来说,在过去 3 年里,这两个来源的数据质量都很好。
在 Eirgrid 数据集中,15 分钟周期的 66 行完全随机缺失 (MCAR),因此被回填。
在历史 Metéirean 中,从 2017 年初开始丢失了一大块数据,因此整个数据集减少到仅从 2017 年 7 月 1 日开始,而不会对模型产生影响。
查看温度和风数据的异常值,我们发现它们与爱尔兰短期极端温度一致(30 度以上非常罕见!)和暴风雨(更频繁,对风有好处!).

图 4— Met 异常值分析
我们对风能的一些负值感到惊讶,但发现涡轮机叶片上的周期性空气动力载荷对风力涡轮机产生了负面影响,主要是由于增强的风切变。

图 5 —电力需求和发电异常值
异常值控制图还提供了对电力生产和需求趋势的洞察,特别是季节性和风力发电量的增加。

图 6-实际风力发电控制图
要绘制控制图来帮助发现单变量异常值,这段代码非常方便:
SEAI 每月发电量数据也与爱尔兰共和国 15 分钟数据进行了交叉检查,以确认整体质量。
共线性处理
这里的直觉是,总的可能发电量密切依赖于主风电场附近的天气条件,特别是在[2]、[3]和[4]中发现的:风速、风向、相对湿度和平均海平面气压(百帕)。相反,电力消耗取决于一天中的小时、工作日与周末,还取决于空气温度,如[6]、[7]和[8]所示。
然而,由于需要来自多个站点的天气数据来获得完整的视图,所以许多测量值将是相互关联的。
数据共线性可能会降低模型性能,并模糊特征影响,应尽可能避免。
我们移除了高度相关的要素(高于 0.9)和高方差膨胀因子(VIF),例如各气象站的温度,从而产生了更易于管理的数据集:

图 7-主要时间和天气特征相关性
要检查多重共线性,最好是使用 variance_inflation_factor。一个经验法则是,如果任何 VIF 大于 10,那么你真的需要考虑从你的模型中删除变量。
具体实现,参见相关的 Colab 文件,文档在 Github 的自述文件中。
功能转换
将时间转换成 2D
从图 8 所示的温度、风速和实际风力的快速傅立叶变换中,我们可以看到第 1 天和第 1 年的频率成分有明显的峰值,这意味着数据有一些潜在的日和年模式。

图 8—天气特征快速傅立叶变换
为了在我们的模型中强调这些模式,我们需要将 1D 观测时间戳转换成一个 2d 周期弧度时间空间(图 9),如[9]中所建议的。

图 9:日期/时间转换
在这里,我们将时间转换为两个弧度时间空间:一个用于年周期[yearSin,yearCos],一个用于日周期[daySin,dayCos],它们由下式导出:

时间转换
2D 风矢量
如图 10 所示,风向以度数记录,这不是很好的模型输入,因为 360°和 0°应该彼此接近,并且平滑地环绕。此外,如果风速很高,风向对模型没有影响。因此,更明智的做法是将风速和风向结合起来,创建一个 2D 风矢量特征。

图 10。将风速和风向转换为 2D 风矢量
如前所述,请关注第 2 部分,该部分将涵盖候选模型、具有强大趋势和结果的时间序列的特定训练/验证分割!
目标提醒!
此外,为了实现欧洲到 2030 年将碳排放量减少至少 55%的计划,消费者和工业用电用户的行为需要改变,这也是本项目的重点。如图 1 所示,如果风电预计达到当前的 70%,则:
- 工业用户(如数据中心)可以为电池充电以备后用。
- 消费者可以设定他们的电器在这些时间运行,例如:1)给电动汽车充电;2)启动带有滚筒式烘干机的洗衣机;3)增加热泵等。

图 11 大风天气预报!—凌晨 1 点至 4 点/下午 3 点左右是给电池充电的最佳时间
基于这一目标,模型预测的成功将主要通过以下方面来衡量:
- 这项工作的主要相关指标是平均绝对误差(MAE ),因为绝对值是我们试图测量的,以便建议何时给电池充电。
- 当实际风力发电的比例较高时,准确的预测是最重要的,因为当风力较低时,电力碳强度无论如何都是不好的(其他可再生能源,如太阳能和水力发电,目前在爱尔兰影响较小)
- 均方根误差(RMSE)和解释的方差回归得分也从模型中测量,以便更好地理解模型的局限性。
具有强劲上升趋势的时间序列的培训/验证拆分
数据集中 2021 年 3 月的最后 2 周被保留作为测试集,数据集中的其余部分被分成训练集和验证集。使用 scikit-learn 的标准随机分割提供了极好的验证结果,但在测试结果中非常差。这是因为,对于时间序列数据,模型通常预测一个接近上一个/下一个值的值。对于随机打乱的集合,该值通常非常接近实际值,实际上存在数据泄漏。
在时间序列中拆分训练/验证集的标准方法是简单地在大约 80%标记的日期拆分数据(如[10]中所建议的)。然而,如第 1 部分所示,目标变量有持续上升的趋势,因此最新数据的测试集结果很差。
因此,数据集在每个月的某一天(22 日)进行拆分,这样定型集就包含了截至该月 22 日的所有日期以及该月 22 日之前的验证集日期,从而保留了所有年份(趋势)和月份(季节性)的数据。对于给定的高性能模型和特征集(随机森林模型和 2DTime),使用自定义训练-验证拆分的测试集的结果明显更好。
培训/验证分割选项:此处首选在月日之前/之后分割
输入要素集
为了探索每个输入特征对模型的影响,在不同的特征集合上训练和测试模型(表 I)。通过比较不同输入集的结果来检查每个输入要素的影响。

表 I —特性集组合
包含以前 24H 的实际风力(MW)的机组受媒体的启发,用神经网络文章【11】预测日用电量,文章【11】涵盖了相关要求。
模特候选人
随机森林
我们选择随机森林回归模型作为我们早期分析的原型,以了解产生显著差异的功能,它还可以很好地处理线性和非线性关系以及偏差和方差平衡。[12]中对功率预测的研究也表明他们使用了这样的模型。默认的随机森林参数导致完全生长和未修剪的树,这些树可能非常大。在这种情况下,结果非常好,训练时间不到几分钟,所以他们很好。请注意,标准的 SkLearn GridSearch 实现可能难以用于时间序列,因为在嵌套交叉验证中可能会出现“数据泄漏”,如上所述。在“Rhum_Msl”特征集上发现了最佳结果,该特征集包括标准风速以及相对湿度和海平面气压数据。
为测试保留的最后 2 周数据的随机森林回归评估(2021 年 3 月 15 日至 29 日)平均绝对误差(MAE): 219。如图 2 所示,除了一些异常值之外,验证误差描绘了大致均匀的分布。绿色方框中突出显示的时期大约是 2020 年 4 月的第一次锁定,可以理解的是,模式(主要是能源需求)在那时发生了巨大变化。

图 12-验证集上的随机森林错误
如图 13 所示,基于气象历史数据的预测与测试集上的实际风力发电值非常接近。请注意,当需求相对较低时,Eirgrid 自己对风力发电的预测(Eirgrid 预测风力)往往会超过实际发电量。相反,所提出的 RF 模型的预测更加准确,并且有效地符合电网可以应对最大比例的风力发电的事实。

图 13 —随机森林预测与实际风力发电(兆瓦)
必须仔细考虑随机森林模型中的特征重要性(图 14 ),主要是因为气象站测量值之间存在大量残留共线性,但它们给出了对模型重要的特征的概念。
香农的风速(wdsp)以节为单位,以及马林角(wdsp MAL)、科克(wdsp COR)和贝尔穆莱特(wdsp BEL)的风速当然是预测整体风力发电的关键,因为大多数风力发电场都在这些地区。爱尔兰岛上的总风力发电能力逐年增加,这也是一个主要因素。一年中的每一天和每一小时都会影响天气模式和需求的季节性。都柏林目前的温度也很重要,大概是因为它会影响需求。

图 14 —功能重要性
人工神经网络—小时模型
人工神经网络模型的主要优势是它们的自学习能力,以确定变量之间的复杂关系,同时保持较高的数据容差。然而,为了实现准确的预测,人工神经网络的自学习过程需要大量的数据和相应的高计算成本。由于可用数据和计算能力的爆炸式增长,人工神经网络模型已成功用于建模非线性问题和复杂系统,以预测风力发电和能源消耗[13]、[14]、[15]。
因此,本计画也采用类神经网路的方法来比较其他的模型。本文中的人工神经网络模型是使用 Tensorflow 的 Keras 库构建的。有不同版本的 ANN 模型对应于表 1 中所示的特征集。所有版本都使用不同的模型设置进行实验,从 2 到 5 个密集层,每层神经元从 20 到 260 个。根据实验结果,ANN 模型被设置为具有 120 个中子的 3 层和具有 10 个神经元的最后一层。该模型使用 Adam 优化器和校正线性(ReLU)激活函数,因为 ReLU 在该项目中优于其他函数(如 Softplus、Sigmoid 和双曲线函数)。
神经网络模型
在图 15 中,不同特征集的训练和测试结果表明:1)2D 时间特征产生更好的性能,然而风矢量不是预期的;a)选择“time & rhum”数据集的人工神经网络模型用于以后的评估和比较。

图 5 —每个特性集的培训和验证损失(MAE)
长短期记忆模型
由于能够从天气观测中学习短期和长期的季节模式,LSTM 网络对于这个项目是合理的。本工作基于“tensor flow 核心教程:时间序列预测”实现了递归神经网络(RNN)模型,以预测未来 24 小时的爱尔兰风力发电量(图 16),实现了:
- 一种 LSTM,其中模型在一个步骤中完成整个序列预测。
- 一种自回归 LSTM,它将预测分解为单个时间步长。然后,每一步的每一个输出都可以反馈到自身,并且可以根据前一步的情况进行预测,就像在使用 RNNs 的经典生成序列中一样[16]。
这两个模型都使用 24 小时窗口的先前天气值和实际风力作为输入,但是它们不使用未来 24 小时的当前天气预报。因此,它们的性能是次优的。

图 6。24 小时 LSTM 预测与实际风力发电对比示例
人工神经网络— 24 H 模型
由于上述发现,我们再次尝试了神经网络,但基于整个 24 小时的单次预测,类似于上面的 LSTM。
直觉告诉我们,风力发电不仅取决于当前吹过爱尔兰的风,还取决于几小时前发生的事情。例如,如果一个燃气发电站在高点启动并运行,风力开始增强,由于发电站可能需要几个小时才能逐渐减弱,风力发电将暂时“减弱”。
此外,紧接在 24 小时窗口之前的风力发电水平也可以通知模型,因此新的特征集也将包括该数据。
新的 ANN 模型也是使用 Tensorflow 的 Keras 库构建的,并且将所需 N 个特征的聚集 24 H 作为输入,并且由 5 层 N * 24 个神经元组成,随后是 2 层以展平为 24 H 预测的向量。
类似于每小时的 ANN 模型,不同特征集的训练和测试结果表明:1)2D 时间特征产生更好的性能,然而风矢量不是预期的;a)选择用于“时间& rhum & prev actual”数据集的人工神经网络模型用于以后的评估和比较。

图 17 —每个特征集的训练和验证损失(MAE)
击鼓!结果!
使用 MAE 在测试集(2021 年 3 月的最后 2 周)上对本工作中提出的 AI 模型进行评估和比较,以获得每个模型的最佳特征集。还将模型预测与 EirGrid 预测的风能发电量基准进行了比较。如图 18 所示,随机森林和 ANN 模型都比 EirGrid 模型提供了更高的精度(更低的 MAE)。然而,LSTM 模型的性能是最差的。这是因为当前的 LSTM 仅基于风能发电的历史数据,并且当天气特征被结合到未来的工作中时,预期具有改进的性能。

图 18 —每种型号的测试集 MAE(最佳特性集)
但是,等等,2021 年 3 月的最后两周,作为测试集所需的模型的全新数据,代表未来的表现吗?我们可以比较验证集来得到一个想法。

图 9 —验证集 MAE
啊哈,这里的结果没有那么引人注目,尽管很高兴看到 24H·安模型仍然表现最好。为什么会这样?我们应该意识到这种错误有什么模式吗?
事实上,如果我们将误差(预测值-实际值)与实际值进行对比,就会发现确实如此:

图 20 —按实际风力验证集 EirGrid 预测误差 MW
正如我们在一些例子中看到的,当有很多风时,EirGrid 提供的预测往往会高估风力发电,并且似乎没有考虑电网 SNSP 约束:我们可以从上面看到,误差与实际值正相关。这对于黄点(2021 年)和橙点(2020 年)来说尤其如此,在这些地方有更多的风力发电能力,并且在 2021 年电网中有更高比例的 SNSP 支持。

图 21——通过 ActualWindMW 验证集 24H 人工神经网络误差
另一方面,我们的 24 小时人工神经网络模型倾向于在较低的实际值时略微低估。一般来说,误差范围也更小。
由于 MAE 得分非常相似,因此也值得检查解释方差得分,在此我们可以看到 EirGrid 预测性能较差。

图 12 —验证集解释的每个模型的方差得分—越接近 1 越好
让我们仔细看看三月的最后两周:

图 23 —比较 24 小时人工神经网络预测、电网预测和实际风力
在第一周,当有小风和小风代时,预测都非常好。
当风力达到电网的最大容量(约为当时实际需求的 70%)时,EirGrid 的预测明显超调,而我们的最佳模型仅略微低估。
因此,我们选择的机器学习模型,包括神经网络和随机森林,能够从几个简单的气象站测量值、一年中的时间和日期以及连接的风电场容量中发现隐藏的发电和需求模式。
我们的模型已经可以生产了!:=)
后续步骤
对于生产,可能是一个简单的网站,每天晚上都有预测更新,供用户每晚检查,一个小的预算应该足够了。
然而,对于维护和保持模型定期重新训练将需要更多的努力。作为第一次可再生能源电力支持计划(RESS) 拍卖的结果,一些风力发电场以及太阳能生产正在进行中。
如果有更多的时间,我们将继续研究具有更合适特性集的 LSTM 模型。
此外,如此处所示,特征选择和转换对建模性能有很大的影响。这意味着进一步的特征工程研究也可以改善模型的预测。改进之一可能是从快速傅立叶变换和/或小波变换中发现的,这可以在频域中说明特征的季节性模式。
谢谢大家!
我们要感谢您迄今为止的阅读!我们还要感谢都柏林城市大学的数据挖掘教授 Andrew Mccarren 博士,感谢他在管理数据项目方面的清晰教学和他对我们最初项目的反馈,以及 Kevin McElwee 对 24H 模型的启发。
作者
潘康宇,王南钧·马图兹,卡特琳娜·拉兰内
参考
[1]“2020-2028 年全岛发电能力声明”,Eirgrid Group,Tech。众议员,2020。[ [在线](https://www.eirgridgroup.com/site-files/library/EirGrid/ All- Island- Generation- Capacity- Statement- 2020- 2029.pdf)
[2] J. Haslett 和 A. E. Raftery,“具有长期记忆依赖性的时空建模:评估爱尔兰的风力资源”,《皇家统计学会杂志》。C 系列(应用统计数据),第 38 卷,第 1 号,第 10 页
[3] T.Brahimi,“利用人工智能预测风速在沙特阿拉伯的能源应用”,能源,第 12 卷,第 4669 页,12 2019。
[4] K.P.Moustris、D.Zafirakis、D.H.Alamo、R.J.NebotMedina 和 J.K. Kaldellis,“使用人工神经网络进行混合发电站最佳运行的 24 小时风速预测”,载于大气科学透视,T. Karacostas、A. Bais 和 P. T. Nastos 编辑。湛:施普林格国际出版公司,2017 年,第 409–414 页。
[5] A. Lahouar 和 J. Ben Hadj Slama,“基于随机森林的小时前风电功率预测”,可再生能源,第 109 卷,第-03 页,2017。
[6]蔡志祥,李,林明辉,林俊英,
徐国华,“用神经网络预测能源需求”,
2020。【在线】。可用:https://towardsdatascience.com/预测-能耗-使用-神经网络- xgboost- 2032b6e6f7e2
[7] P. W. Khan、Y.-C. Byun、S.-J. Lee、D.-H. Kang、J.-Y. Kang 和 H.-S. Park,“基于机器学习的方法预测可再生和不可再生能源的能源消耗”,能源,第 13 卷,第 18 期,2020 年。【在线】。可用日期:https://www.mdpi.com/1996-1073/13/18/4870
[8] R. Gramillano,《洛杉矶电力需求预测》,
2019。【在线】。可用:https://towardsdatascience.com/预测电力需求跑赢政府- a0921463fde8
[9] Moon,J,Park,J,Hwang,E,等.基于机器学习的高等教育机构电力消耗预测。j 超算 2018;74: 3778–3800.
[10] scikit-learn 时间序列 Spli t [Online]
[11] 凯文·麦克埃尔威,“用神经网络预测日常用电量。”2020.【在线】。
[12] V. Natarajan 和 n .活女神,使用并行随机森林算法进行风力预测。[新加坡斯普林格],2020 年第 1 期,第 1048 卷,第 209-224 页。【在线】。可用:https://doi.org/10.1007/978-981-15-0035-016
[13] A. S. Qureshi 和 A. Khan,“深度神经网络中的自适应迁移学习:利用区域间和不同任务域间的知识迁移进行风力预测”,计算智能,第 35 卷,第 1088–1112 页,2019 年。
[14] D. Widodo、N. Iksan、E. Udayanti 和 Djuniadi,“使用深度学习方法进行可再生能源发电预测”,IOP conference Series:Earth and Environmental Science,第 700 卷,第 012026 页,第 03 2021 页。
[15] P. W. Khan、Y.-C. Byun、S.-J. Lee、D.-H. Kang、J.-Y. Kang 和 H.-S. Park,“基于机器学习的可再生和不可再生能源能耗预测方法”,能源,第 13 卷,第 18 期,2020 年。【在线】。可用:https://www.mdpi.com/1996-1073/13/18/4870
[16] A. Graves,“用递归神经网络生成序列”,2014 年。
GitHub 链接到笔记本
https://github.com/CA683-Group99/Wind-Energy-Prediction
使用自然语言处理和机器学习预测假新闻| Scikit-Learn | GloVe | Keras | LSTM
原文:https://towardsdatascience.com/predicting-fake-news-using-nlp-and-machine-learning-scikit-learn-glove-keras-lstm-7bbd557c3443?source=collection_archive---------5-----------------------
在 Kaggle 的假新闻数据集上使用 Python 应用传统机器学习和深度学习技术的简单指南。它也简要地包括文章的正文和文体分析。

马库斯·温克勒在 Unsplash 上的照片
假新闻数据集是 Kaggle 上可用的经典文本分析数据集之一。它由不同作者的真假文章标题和正文组成。在这篇文章中,我使用传统的机器学习方法和深度学习走过了整个文本分类过程。
入门
我开始在 Google Colab 上从 Kaggle 下载数据集。
接下来,我读取数据帧并检查其中的空值。在总共 20800 行中,text articles 有 7 个空值,title 有 122 个空值,author 有 503 个空值,我决定删除这些行。对于测试数据,我用空白填充。


训练数据和测试数据中的空值数量
此外,我还检查“假”和“真”新闻在数据集中的分布。通常,我在导入 matplotlib 时为笔记本上的所有绘图设置 rcParams。


0 是真正的新闻,而 1 是假新闻
真假新闻的比例从 1:1 到 4:5。
接下来,我决定看看下面的文章长度—

可以看出,假文章的中值长度较低,但也有大量异常值。两者的长度都为零。
可以看出,它们从 0 开始,这是令人关注的。我用的时候其实是从 1 开始的。描述()以查看数字。于是我看了一下这些文字,发现都是空白的。对此,显而易见的答案是条带和液滴长度为零。我检查了零长度文本的总数是 74。
我决定重新开始。因此,我会用一个空格填充所有的 nan,然后去掉它们,然后删除零长度的文本,这样就可以开始预处理了。下面是处理缺失值的新代码。数据的最终形状是(20684,6),即包含 20684 行,只比 20800 少 116 行。

目标变量的分布形状是均匀的,这有利于模型训练。
此后,出现了更多个位数长度或低至 10 的文本。它们看起来更像评论,而不是正式的文本。我会暂时保留它们,然后进入下一步。
文本预处理
因此,在我开始进行文本预处理之前,我实际上查看了拥有假冒和正版文章的作者的重叠数量。换句话说,拥有作者的信息会有任何帮助吗?我发现有 3838 个作者,其中 2225 个是真实的,1618 个是假新闻的作者。其中有 5 位作者是真假新闻的作者。
为了开始预处理,我最初选择了通过空白和扩展收缩直接分割。然而,由于一些(我想是斯拉夫语)其他语言的文本,这已经产生了错误。因此,在第一步中,我使用 regex 只保留拉丁字符、数字和空格。然后,展开缩写,然后转换成小写。这是因为缩写如I have转化为 I have 。因此,向小写字母的转换发生在扩张收缩之后。完整代码如下:
一旦完成,常规单词标记化就完成了,随后是停用词移除。
文本分析
既然数据已经准备好了,我打算使用 wordcloud 查看常用词。为了做到这一点,我首先将所有标记化的文本连接到单独列中的字符串中,因为它们将在稍后的模型训练中使用。
接下来,为每个标签创建一个包含所有文本的字符串,并创建如下的单词云:


第一个 wordcloud 是真新闻,第二个是假新闻。
在假新闻词云中,一些词的出现频率明显高于其他词。在“真实新闻”的文字云上,有不同字体大小的混合。相反,在假新闻数据集中,较小的文本在背景中,一些词使用得更频繁。假新闻词云中的中等大小的词越来越少,或者换句话说,出现频率逐渐减少,这是一种脱节。频率不是高就是低。
风格分析
风格计量分析通常被称为对作者风格的分析。我将研究一些风格学特性,比如每篇文章的句子数量、文章中每句话的平均字数、每篇文章的平均字数以及词性标签数。
每篇文章的句子数量
为了得到这个,我需要原始数据集,因为我在 train_df 中丢失了句子信息。因此,我在 orginal _ train _ df 中保存了一份实际数据的副本,用于将句子转换为序列。
接下来,我查看了每个目标类别的句子数量,如下所示:

显然,虚假文章有很多异常值,但 75%的虚假文章的句子数量低于 50%的真实新闻文章。
文章中每句话的平均字数
在这里,我统计了每篇文章每句话的总字数,并返回平均值。然后我在箱线图上画出了这些数字,使它们可视化。

可以看到,平均来说,假文章比真文章更罗嗦。
每篇文章的平均字数
这是一篇文章的平均字数。在方框图中,很明显,假文章中的平均单词长度更高。

POS 标签计数
接下来,我试着看了伪作 vs 正版文章中的词性(POS)组合。在遍历每篇文章时,我只将单词的词性存储到一个列表中,将相应的词性计数放在一个数据帧中,并使用一个条形图来显示假货和新闻文章中词性标签的百分比组合。两篇文章中的名词都高得多。总的来说,除了假新闻中动词过去式的比例是真实新闻的一半之外,没有明显的规律。除此之外,所有其他 POS 类型在假货和真品方面几乎相等。

使用机器学习的文本分类
Tf-idf 和计数矢量器
一旦分析完成,我首先采用传统的方法使用计数矢量器和术语频率-逆文档频率或 Tf-idf。代码中配置的计数矢量器也生成二元模型。使用 CountVectorizer ()以矩阵的形式获得它们出现的次数,然后将这个字数矩阵转换成归一化的词频(tf-idf)表示。这里,我使用了 smooth=False,以避免零除法误差。通过提供 smooth=False,我基本上是在文档频率上加 1,因为它是 idf 计算公式中的分母,如下所示
**idf(t) = log [ n / (df(t) + 1) ]**
使用默认配置进行基准测试
接下来,我打算用默认配置来训练模型,并挑选出性能最好的模型稍后进行调优。为此,我遍历了一个列表,并将所有性能指标保存到另一个数据帧中,并将模型保存到一个列表中。
我使用了逻辑回归、多项式朴素贝叶斯、决策树、随机森林、梯度增强和 Ada 增强分类器。多项式 b 的精确度是所有方法中最好的,但是 f1 的分数由于召回分数低而不稳定。事实上,召回率最差,为 68%。结果中最好的模型是 Logistic 回归和 AdaBoost,它们的结果是相似的。我选择用逻辑回归来节省训练时间。

用于调整逻辑回归分类器的 GridSearchCV
所以,是时候调整我选择的分类器了。我开始使用更大范围的 max_iter 和 c。然后使用 cv=r 的gridsearchcv,即交叉验证的 5 倍,因为标签分布是公平分布的。我已经使用 f1-score 进行评分,并使用 refit 返回 f1-score 最好的训练模型。
得到的最佳模型的准确率为 97.62%,f1 值为 97.60%。对于这两者,我们都实现了 4%的改进。现在,我注意到 max_iter 的最佳值是 100,这是范围的下限,对于 C,它也是 100,但这是范围的上限。因此,为了适应参数搜索,我使用了 max_iter = 50,70,100 和 C = 75,100,125。在 max_iter=100 和 C=125 的情况下有微小的改进。因此,我决定保持不变,并将 C 的参数搜索从 120 扩大到 150,步长为 10。本次运行的所有性能指标与起始网格的结果相同。然而,这次运行的 C=140 的值。
最后一次,我在 max_iter=100 和 C = [100,125,140]上运行网格搜索,其中 C 具有所有运行中的最佳参数。最好的一个是 max_iter=100,C=140,我最终保存为最佳模型。

由于 GradientBoost 和 AdaBoost 分类器的性能也很好,因此未来可能的工作之一是用它们进行测试。在某些情况下,调优后的性能可能会好得多,但考虑到时间,我会在这里得出结论,因为逻辑回归是 max_iter=100 和 C=140 的最佳性能模型。
我终于把结果上传到 Kaggle 上了。这个挑战已经进行了 3 年,但是我对测试这个模型的测试数据的分数很感兴趣。

使用手套和 LSTM 的文本分类
数据准备
为了使用深度学习技术,文本数据必须以原始格式重新加载,因为嵌入会略有不同。在下面的代码中,我处理了缺少的值,并将文章的标题和作者附加到文章的正文中。
接下来,我使用 Keras API 的标记器类对文本进行标记,并使用 oov_token = " < OOV >"替换词汇外标记,这实际上创建了一个基于词频的词汇索引。然后,我在文本上安装标记器,并使用通过安装标记器创建的词汇索引将它们转换成整数序列。最后,由于序列可能有不同的长度,我使用 padding _ sequences 在末尾使用 padding=post 填充零。因此,根据代码,每个序列的长度预计为 40。最后,我将它们分成了训练集和测试集。
二元分类模型

为了创建用于文本分类的模型,我从最简单形式的二进制分类模型结构开始,其中第一层是嵌入层,期望嵌入 6000 个 vocab 大小的文本(在 vocab_size 中指定),每个长度为 40 的序列(因此,input_length=max_length ),并为每个输入序列给出 10 维的 40 个向量的输出。接下来,我使用展平图层将形状(40,10)的矩阵展平成一个形状(400)的数组。然后,这个数组通过一个密集层产生一维输出,并使用 sigmoid 激活函数产生二进制分类。我最初想用这个模型做更多的实验,所以为它创建了一个函数,我也喜欢把层组合成一个函数作为练习。这项工作并不真正需要它。最后,我使用 precision 和 recall 来编译模型,以便在训练和验证时进行监控。
我还使用了早期停止来节省时间,patience=15 表示如果在过去的 15 个时期中模型没有改进就停止,使用模型检查点来存储最好的模型,save_best_only=True。增加了模式=分钟,因为我在这里监测损失。
现在是适合模型的时候了!
因为我使用了精度和召回率以及损失,所以我也可以在这里跟踪精度和召回率值。如下图所示,验证损失在第 6 个时期最低,然后损失停滞或增加。因此,最佳模型在训练的第 6 个时期后被保存。很明显,随着训练损失的改善,模型是如何过度拟合的,而验证损失在第 6 代之后增加。



下面是我用来绘制训练和验证损失、精度和召回的代码。我在 range 函数中用了 max(history.epoch) + 2,因为 history.epoch 从 0 开始。因此,对于 20 个时期,最大值将是 19,范围将为 max(history.epoch)生成从 1 到 18 的列表。
该模型的准确度值为 96.6%,f1 值为 96.6%。我还在 Kaggle 测试数据上测试了这个模型的性能,它还不错,但不比我之前训练的逻辑回归好。

.
LSTM

唷!现在让我们用 LSTM 模型来拟合文本数据。第一层和最后一层是相同的,因为输入和输出是相同的。在这两者之间,我使用了一个辍学层过滤掉 30%的单位,然后去 LSTM 层的 100 个单位。长短期记忆(LSTM),是一种特殊的 RNN,能够学习长期依赖。他们的特长在于记忆信息的时间更长。在使用 LSTM 后,我使用了另一个脱落层,然后是一个具有 64 个隐藏单元的全连接层,然后是另一个脱落层,最后是另一个具有“Sigmoid”激活函数的一个单元的全连接层,用于二进制分类。
完成后,我按照上一节中概述的相同过程编译、使用回调并拟合模型。我提供的纪元数量是 20。但是在这种情况下,模型只训练了 16 个时期,因为在第一个时期之后的 15 次连续迭代中,验证损失没有改善。从下面的图中也可以清楚地看到。由于过度拟合,验证损失一直在增加,而训练损失却在下降。回想一下回调设置,我对模型进行了编码,以在停止之前连续 15 个时期等待验证损失的改善。

该模型没有显著的改进,尽管该模型有可能改进。其准确率为 96.1%,f1 评分为 96.14%。
使用预先训练的单词嵌入—手套
现在,我们也可以使用预先训练的单词嵌入,比如 GloVe。GloVe 是一种无监督学习算法,用于获取单词的矢量表示。在来自语料库的聚集的全局单词-单词共现统计上执行训练,并且所得的表示展示了单词向量空间的有趣的线性子结构。[ 4
我使用的是一个在 60 亿个词汇上训练过的,词汇有 40 万个,用 300 维向量格式表示。
在下面的代码中,我有一个在 Google Colab 上加载 GloVe 的代码,因为我在 Colab 上做了部分工作。
在这里,我概述了如何从本地加载文件。从这里下载嵌入这个词。
接下来,我们的目标是在手套嵌入中找到假新闻数据中的标记,并获得相应的权重。
带手套的简单模型
现在,我已经为我们的训练数据嵌入了手套,我使用了 output_dim=300 的嵌入层,这是手套向量表示形状。此外,我使用了 trainable = False,因为我使用的是预训练的权重,所以我不应该在训练时更新它们。它们与其他单词有关系,所以最好不要打扰它们。
最后,使用与我之前使用的相同的过程,我用 50 个纪元来训练模型。然而,由于在第 3 个时期之后没有改善,该模型在第 18 个时期之后停止训练。得分低于前两款。准确率和 f1 值都在 93%左右。

LSTM 手套
和..最后,我使用手套嵌入来训练我之前使用的 LSTM 模型,以获得更好的结果。完整的代码如下-
同样,我使用了 50 个历元,模型在第三个历元后没有改进。因此,训练过程在第 18 个纪元后停止。准确率和 f1 值都提高到 96.5%,接近第一个 Keras 模型。

所以,我试着用 Kaggle 的测试数据来预测这个模型,这是我的结果

结论
在本练习中,最佳模型是优化的逻辑回归模型。这个用例还有很多需要进一步改进的地方,特别是设计更好的深度学习模型。此外,出于时间的考虑,我没有调整随机森林和 AdaBoost 分类器,这可能会导致比逻辑回归更好的性能。
参考
- https://faroit . com/keras-docs/1 . 0 . 1/入门/sequential-model-guide/
- 【https://colah.github.io/posts/2015-08-Understanding-LSTMs/
- https://machine learning mastery . com/use-word-embedding-layers-deep-learning-keras/
- https://nlp.stanford.edu/projects/glove/
完整代码在这里。
感谢光临!
我的链接: 中|LinkedIn|GitHub
利用泊松分布预测足球比赛结果
原文:https://towardsdatascience.com/predicting-football-match-result-using-poisson-distribution-ac72afbe36e0?source=collection_archive---------7-----------------------
探索泊松分布和预测加拉塔萨雷对费内巴赫比赛结果使用它与 python 实现
理解数据集、执行适当的预处理操作并解释结果对于根据更准确的数据训练机器是必不可少的。例如,如果我们考虑降维,降维方法的类型(线性或非线性)取决于数据集的结构。分布类型也是阅读、理解和推断数据集的最重要的方法之一。本文通过使用泊松分布和 2019-2020 土耳其足球联赛数据集解释了球队相互进球的概率,该数据集总是无记忆的,具有泊松分布。本文深入解释了泊松分布,并基于 2019-2020 土耳其足球联赛的真实数据集,使用泊松分布对加拉塔萨雷和费内巴切相互得分的概率进行了建模。
***Table of Contents* 1\. What is Poisson Distribution?
*1.1\. How can we decide whether is a poisson distribution?
1.2\. Examples
1.3\. Real Applications*
2\. Predicting Football Match Result
3\. References**

荷马·洛佩兹在 Unsplash 上的照片
1.什么是泊松分布?
以其最短的形式,在某个区间(这个区间可以是时间、距离、面积、体积等)内发生的独立事件数量的分布。)是泊松分布。比如某路口 24 小时的事故数量,一平方米地块的鸡,X 地区 3 个月的火灾数量等。在继续这些例子之前,让我们先来看看这个主题的理论背景:

泊松分布,按作者分类的图像
其中λ=某一时间间隔内出现的平均次数
e =欧拉常数
x =需要概率的事件的数量
1.1。我们如何决定是否是泊松分布?
- 事件发生随机和独立呈泊松分布。
- 事件发生在特定范围内。
- 要使用泊松分布建模,应根据事件的计数给出分布。例如,在 10 分钟内过马路的人的平均重量不是泊松分布,但是> x kg 的人数可以用泊松分布建模。
查看图 1 中的两幅图和随机放置的红色方块:

图一。泊松分布与否?,作者图片
在左侧的图表中,可以看到正方形中的事件数(数据点)在某些地方为 0,而在其他地方为 15–20。这表明数据不是独立分布的,而是在一定条件下分组的,如果事件(数据点)在整个图中随机、独立且以相同的理论速率分布,那么如果在另一个方块中得到 0 个事件,那么在一个方块中得到 15-20 个事件是没有意义的。因此,它不能用泊松分布来建模。
当红色方块应用于右侧图表的不同部分时,方块中事件(数据点)的数量将彼此接近。这可以用泊松分布来模拟。
这里,用泊松建模的不是手边的数据集,而是应用于数据集的帧中的事件(数据点)的数量。
1.2.例子
让我们解决一些基本问题来进入正题。
1-1 毫微克的铀-234 平均每秒发生 4.6 次放射性衰变,让我们根据泊松分布计算每秒发生 3 次放射性衰变的概率。
- λ= 4.6
- X=3
下面的代码块解决了这个问题:

图二。衰变数的概率,按作者分类的图像
值的概率如图 2 所示,如果每秒 4.6 次放射性衰变,则 3 次放射性衰变的概率为 16%,其他值的概率如图所示。
2-平均 12 个人在 30 分钟内参观一个博物馆。任何 5 分钟内没有新人来这个博物馆的概率是多少?
- 如果 30 分钟内平均有 12 个人访问,那么 5 分钟内平均会有 2 个人访问,所以λ= 2;
- 如果 X 值,也就是概率,是期望值,就是 0。
下面的代码块解决了这个问题,而没有使用泊松分布库:

图 3。访问次数的概率,按作者分类的图像
在图 3 中,显示了访问多达 10 个人的概率。5 分钟内没有新访客的概率为 13.53%。
1.3.真实应用
以下列表包括泊松分布的实际应用:

图 4。泊松分布的应用[1]
2.预测足球比赛结果
该研究旨在确定加拉塔萨雷主场而费内巴切客场(GS vs FB)时球队进球数量的概率。在这种情况下,使用了以下包含 1959-2021 年间土耳其联赛所有比赛结果的数据集。为了找到他们在加拉塔萨雷主场和费内巴切客场比赛中相互进球的概率,我们研究了 2019-2020 赛季,如下面的代码块所示:
数据集(许可证: CC0:公共领域)可以通过链接访问
- 在第一部分中,通过选择 2019–2020 赛季并导入数据集;选择主场、客场、主场进球得分和客场进球得分列。
- 第二部分计算 2019–2020 赛季主客场球队的总进球数和平均进球数。联赛共有 18 支球队,赛季进行了 18*17 = 306 场比赛,主队的总进球数为 493 个(平均:1.611),而客场球队的总进球数为 382 个(平均 1.248)。
- 在第三部分,计算了加拉塔萨雷在主场比赛中的总进球数和失球数以及平均进球数。加拉塔萨雷 17 个主场进 32 球(场均:1.882),失 15 球(场均:0.882)。
- 在第四部分,计算了费内巴切在客场比赛中的总进球数和失球数以及平均进球数。主队在费内巴赫 17 场客场比赛中的进球,这意味着费内巴赫的失球数是 24 球(平均 1.412),而费内巴赫的失球数是 17 球(平均 1.00)。
- 在第五部分中,对前一部分收集的值进行了汇编和列表。(图 5)

图 5。调查结果汇编,图片由作者提供
6.第六节加拉塔萨雷(主场)和费内巴切(客场)的攻防威力计算如下:
- 加拉塔萨雷攻击力:加拉塔萨雷主场/联赛主场的平均进球数
- 费内巴赫攻击力:费内巴赫客场比赛的平均进球/联赛客场平均进球
- 加拉塔萨雷防守力:加拉塔萨雷的平均失球数,加拉塔萨雷是主场/联赛客场平均失球数
- 费内巴赫防守实力:费内巴切客场比赛平均失球数/联赛主场平均失球数
这部分可以选择使用不同的数学运算符进行计算。
7.在第七节中,加拉塔萨雷主场对费内巴切的平均进球数和费内巴切客场对加拉塔萨雷的平均进球数是利用第六节中得到的各队的攻防力量计算出来的。(GS 1.649–0.707 FB)
当然,由于匹配结果不太可能以 1.649–0.707 结束,这些平均值的泊松分布已在以下部分获得:
8.第八集中,加拉塔萨雷对阵费内巴切的进球概率如图-6 所示。

图 6。加拉塔萨雷进球概率
加拉塔萨雷对阵费内巴赫进球概率最高的是 1 球(31.7%),其次是 2 球 26.14%
9.第九节,费内巴切对阵加拉塔萨雷的进球概率如图-7 所示。

图 7。费内巴赫进球的概率
加拉塔萨雷对阵费内巴赫进球的最高概率是 0 球(49.32%),也就是说加拉塔萨雷有 49.32%的几率不失球。第二个是 1 球 34.86%。
3.参考
[1] J. Letkowski,“泊松概率分布的应用”
https://ibrahimkovan.medium.com/machine-learning-guideline-959da5c6f73d
用机器学习算法预测 HDB 价格(下)
原文:https://towardsdatascience.com/predicting-hdb-prices-using-machine-learning-algorithms-part-2-614c54646998?source=collection_archive---------33-----------------------

照片由盖伦·克鲁特在 Unsplash 拍摄
第 1 部分:使用神经网络预测 HDB 价格。
注意:大家好,这个故事是我上一篇文章的后续。自从我的上一篇文章以来,我一直致力于通过特征工程改进模型的几种方法。我意识到数据集中有街道名称和街区编号,使用地理定位 API ( OnemapSG )我能够创建新的功能来测量房屋和感兴趣的地方之间的距离(使用哈弗辛公式)。我的同事在地理定位 API 上给了我很多帮助。
概观
当前的机器学习算法增加了两个新功能。1.转售价格指数和 2。距离购物中心/捷运/CDB。目的是验证包含这两个新特性是否会导致 MAE 小于以前的模型(<20,000).
重新定义业务案例
在用神经网络预测 HDB 价格的第 1 部分中,我的商业案例是创建一个 HDB 预测模型而不考虑销售年份。回想起来,我没能考虑到它的真正适用性。为什么会有人有兴趣知道他们的房子在 10 年前卖了多少钱?预测模型应该预测今天价格中的转售价格。
因为有很多因素(如供求关系、SIBOR 等。)可以影响转售价格。这些因素会导致相同条件下的价格波动,这意味着具有完全相同特征(相同大小,相同位置)的房屋可能会根据销售年份的不同而定价不同。为了考虑到每年的价格波动,价格将标准化到 2020 年(转售价格调整)。转售住房指数可以在这里找到。
创建经纬度特征
我们通过连接块名称和块编号创建了新的要素名称(称为地址),之后我们通过地理定位每个地址来创建纬度和经度要素。随后,我们所要做的就是根据学校或捷运站的列表计算地址之间的最小距离。
删除不存在的 HDB 名字
在地理标记过程中,我们发现一些没有坐标的组屋,很可能这些街区已经被拆除或被另一栋建筑取代。为了完整起见,我删除了空条目。此外,Lim Chu Kang 镇地区近年来没有组屋,因为该地区的所有组屋都已拆除。
调整后的转售价格

到 2020 年调整后的转售价格。低于 2020 年指数水平的房屋已经向上调整,最明显的是 1990 年。我们看到,1990 年的价格几乎翻了 3-4 倍。通过将价格调整到 2020 年的转售价格指数,我们可以去除销售年份的特征。
调整后转售价格热图

从地图上你可以看到诺维那、坦皮尼、丰戈尔和市中心的几个热点。要了解更多细节,请随意查看 tableau 公共页面。
到便利设施的距离
大多数在新加坡买房的人都希望房子位于便利设施附近,如捷运、购物中心和/或学校。看到新加坡是一个金融中心,有些人甚至想住在中央商务区附近。
我们使用每平方米中值(PSM)作为目标特征,以查看距离和 PSM 之间是否有任何相关性。PSM 是用房价除以建筑面积得出的。看到数据错综复杂(多栋房屋具有不同的转售 PSM,与 MRT 的距离相同),我选择对每个距离使用中位数 PSM。
PSM 到 MRT 的距离
对于不知道什么是 MRT 的国际读者。你可以把它想象成纽约的地铁,或者伦敦的地铁。

PSM 和到 MRT 的距离之间有轻微的负相关(R2=0.04)。
PSM 到商场的距离

同样,在 PSM 和到最近的购物中心的距离之间有轻微的相关性(R2= 0.037)。商城列表源自data.gov,之后做了一些清理,删除了停车场和无关数据。
PSM 到中央商务区的距离

CBD(捷运来福士广场)距离显示出相对较强的负相关性(R2=0.258)。似乎我们离 CDB 地区越远,我们看到 PSM 下降。
PSM 至学校

PSM 对学校似乎是反直觉的,有一个正相关(R2=0.002),尽管很弱。
系统模型化
在这篇文章中,我将包括其他机器学习模型,不仅要看看序列神经网络是否最好,还要比较特征重要性的差异。我将比较三种算法,即 1)序列神经网络,2)随机森林回归和 3) XGBoost。
我编码了所有的分类特征。至于神经网络,数据是有尺度的。
随机森林回归+超参数调整
我对随机森林回归随机搜索交叉验证应用了超参数调整。以下是用于随机森林算法的最佳超参数。

基于随机搜索 CV 的最佳参数
Scikit 学习特征重要性和 LIME(局部可解释模型不可知解释)都用于解释一些特征重要性,以了解哪些参数是重要的。LIME 还有助于我们了解该特征对预测有负面影响还是正面影响。

1 个样本的随机森林的石灰
我们可以立即看到,建筑面积在整体价格中占有很高的权重,这确实表明越大越好。此外,我们还可以看到,添加到模型中的新功能是预测价格的一个重要因素。
XGBoost 回归器+超参数整定
XGBoost 回归器与超参数调整一起使用。欲了解更多关于超参数调整的信息,请参考此处。我想看看通过简单地调整超参数我们能获得多大的改进。超参数调整前的 MAE 为 24,907.30。在调优之后,我们设法获得了 22,726.26 的 MAE。在不改变数据集的情况下,MAE 提高了 10%。


1 个样品的 XGBoost 石灰
我们可以看到不同的特征如何影响房价。
序列神经网络
使用了一个三层神经网络,但是,这一次我们增加了批量大小以缩短训练时间。最新的模型并不比以前的模型表现得更好,也不比以前的两个算法表现得更好。在未来的工作中,我将致力于优化超参数,以改善神经网络模型。
估价
所有三种算法的结果都是通过随机 k-fold 获得的。结果是:

评估表
很明显,XGBoost 的性能优于 NN 和 Random Forest。此外,这三种算法都有不同的特征重要性。引入的新功能(距离)在确定房价方面意义重大。
XGBoost 的特性重要性非常直观。此外,这 7 个特征优于其他特征。前三个特征,即剩余租赁、楼层和到 CDB(地铁莱佛士广场)的距离,在所有三种模式中都非常重要。
这有什么用?
嗯,分析功能的重要性可以让用户在做住房决策时确定和优先考虑哪些功能。你现在可以优先选择一个较高楼层的 HDB 和一个靠近学校的 HDB。当然,这纯粹是从转售价格的角度来看,而不是投资回报,因为该模型没有考虑起始价格。
结论
虽然这个项目在选择 HDB 公寓时给了我们许多重要的见解,但我相信这种模式的应用是非常广泛的。目前,除了帮助我的房地产经纪人朋友估计售价,我还没有发现这个模型的任何真正用途。
在未来的第三部分,我将包括私人财产的数据,以便创造一个整体的工具,可以预测新加坡的房地产价格。让潜在买家和房屋中介更深入地了解房价以及各种特征如何影响预测价格。
预测房价:使用分类因子回归
原文:https://towardsdatascience.com/predicting-home-prices-using-regression-with-categorical-factors-9a35da52067b?source=collection_archive---------42-----------------------
分类解释变量的正确解释入门

图片来自 Pixabay 的鲁迪和
范畴回归导论
回归是数据科学世界中的一个主题,因此以最简单的形式理解它是很有用的。
我最近写了一篇文章,为我们提供了回归的更多细节。你可以在这里找到。为了继续我们在那里探索的思想,今天我们将探索回归模型的创建,其中解释变量是分类数据点。
正如我提到的,从头开始很好地理解应用程序和方法是很重要的。这将有助于你利用机器学习算法&其他以不同方式利用回归概念的统计分析。
让我们从一点 EDA 开始
当涉及到可视化因变量(数值型)和自变量(分类型)之间的关系时,有一些标准的视觉效果是你应该经常考虑的。
我们想看到的是模式或关系。当处理两个数值变量时,散点图是一个明显的选择。
在这种情况下,有几个很好的选择是刻面直方图和箱线图。
柱状图
让我们从一个分面直方图开始。Facet 只是意味着我们不是创建一个单一的直方图,而是实际上有一个给定分类变量的每个级别的直方图。
请放心,ggplot让这变得非常容易。
正如您在下面看到的,我按照常规制作了一个直方图来表示价格的分布,但是我还包含了facet_wrap命令,指示程序为传递给facet_wrap(~)的字段的每个值可视化一个直方图。由于 waterfront 字段只有两个值,我们将看到两个相邻的窗格,其中包含 waterfront 值的价格值直方图。
housing %>%
ggplot(aes(x = price)) +
geom_histogram(binwidth = 50000) +
facet_wrap(~waterfront)

我们可以看到,总的来说,绝大多数住宅没有滨水区,但这并不一定意味着所有有滨水区的住宅价格都更高。如果我们观察这两个群体的平均价格,我们会发现滨水积极型公司的平均价格更高,因为相对集中程度没有那么高。
密度图
分布的更好的相对可视化是geom_density
housing %>%
ggplot(aes(x = price)) +
geom_density(binwidth = 50000) +
facet_wrap(~waterfront)

现在,我们可以更好地捕捉分布中给定部分的相对浓度。
箱线图
现在让我们用一个箱线图来可视化同样的数据。正如你在下面看到的,ggplot的语法几乎完全相同。
housing %>%
ggplot(aes(x = as.factor(waterfront), y = price)) +
geom_boxplot()
facet_wrap(~waterfront)

箱线图的中心线由分组数据集的中值表示。虽然这两种可视化方法都以某种形式呈现分布,但箱形图的美妙之处在于我们可以非常精确地测量和比较平均值、IQR 等。
它有助于使事情变得容易理解。
EDA 外卖
一种类型的可视化比另一种更好吗?我会说是的,因为不同的事情。当谈到探索性数据分析或您作为数据科学家可能进行的任何类型的分析时,很容易开始使用您工具带上的工具,因为您知道这是人们做的事情,但是如果您有使用给定工具的明确目的和意图,它会使您使用给定工具的工作更有意义。
在这种情况下,直方图将有助于您更好地理解分布的形状,而箱线图将有助于您更清楚地比较数据集的分组。
让我们建立一个回归模型
在构建回归模型时,了解幕后到底发生了什么非常重要。
你可以参考这篇文章,而不是重新解释如何解释各种回归输出,我们将在这里继续。
如您所知,回归模型中使用的每个解释变量都有一个系数。该系数包括我们通过回归生成的直线方程中直线的斜率。
让我们快速运行我们的回归,只传递滨水区变量作为解释变量。
fit <- lm(price ~ waterfront,
data = housing)
fit

正如我们之前所见,构建线性模型包括 y 截距 545,462 和系数、斜率或β906,159。
所以我们的公式是 Y = 545462+906159 * X
因为对于海滨我们只有两个选项 1 或 0,所以让我们将其中一个值传递给我们的直线方程并预测 y。
没有滨水区:
545,462 = 545,462 + 906,159*0
在没有滨水区的情况下,我们将传递一个 0,取消那个系数,只给我们留下 y 截距的值。
有滨水区:
1,451,621 = 545,462 + 906,159*1
相反,当有一个滨水区时,我们将 X 视为 1,有效地将 y 截距和系数相加,得到 150 万美元。
这里的解读简直够了。现在让我们看看引擎盖下面。
群体手段
我们将从这个开始,看看滨水组的每个值的平均值。
housing %>%
group_by(waterfront) %>%
summarize(mean_price = mean(price))
这是我们得到的结果:

我们可以看到没有滨水区的平均价格为 545,462 英镑,没有滨水区的平均价格为 1,451,621 英镑。
注意到这两个数字有什么熟悉的地方吗?
如果您已经注意到非滨水住宅的组均值和模型的 y 截距是相同的,或者滨水住宅的组均值和滨水住宅的模型输出是相同的,那么您已经知道了。
那么这里到底发生了什么…
当您将分类变量传递给回归模型时,在这种情况下,滨水区变量,基线组均值 545K 被指定为 y 截距,变量系数现在被定义为滨水区 1 ,请注意,1 实际上是基线组均值(其中滨水区= 0)和滨水区= 1 时的组均值之间的差异。注意,基线组是按照字母顺序建立的。
如果该变量有三个值,第三个值的系数也将是其组均值和基线组均值之间的相对差值。
结论
总结我们的经验,
在进行 EDA 时,如果您希望评估数值型因变量和分类型自变量之间的关系,有几个很好的可视化选项:
- 直方图(分面)
- 密度图(分面)
- 箱线图(分面)
在采用分类解释变量/自变量的回归模型中:
- y 截距等于基线组平均值
- 基线组是根据变量值的字母顺序建立的
- 系数等于分类变量的给定值和基线组均值(或 y 截距)之间的相对差值
理解我们使用的工具的内部工作原理很重要。我希望这本使用分类变量进行回归的初级读本在您利用这些和其他工具进行分析时证明是有用的。
祝数据科学快乐!
用深度学习预测赛马结果
原文:https://towardsdatascience.com/predicting-horse-racing-results-with-deep-learning-7942846287bf?source=collection_archive---------21-----------------------
只是为了好玩!

彼得罗·马蒂亚在 Unsplash 上拍摄的照片
我对机器学习在不同领域的应用感兴趣,在这些领域,分析大量数据是得出准确结论的必要条件。一个这样的领域是体育分析。与其他形式的赌博不同,环境和其中的参与者肯定会对结果产生影响,这使得它成为一个可以通过机器学习解决的问题。
我想尝试在这个领域实现深度学习,所以我在网上寻找关于体育的数据集。最终,我找到了一个关于香港赛马的数据集,包含 6000+场比赛。不像篮球和足球等其他更复杂的游戏,赛马只是 14 匹马之间的比赛。这意味着要考虑的变量要少得多。
该模型应该能够预测哪匹马会赢,当给定比赛和马的数据(性别,年龄,类型)。
记住理论概念,这是我使用的代码:
数据预处理:
import os
os.getcwd()
这个脚本获取程序运行的当前工作目录。我运行这个函数,这样我就可以复制一个路径的模板,以便于描述数据集的路径。
os.chdir('Desktop\\Files\\Data')
之后,我移动到存储文件的目录。
import pandas as pd
df = pd.read_csv('races.csv')
数据集由两个 csv 文件组成,即 races 和 runs csv。比赛 csv 包含关于每场比赛的信息,跑步 csv 包含关于参加每场比赛的每匹马的信息。目标是编码所有非数字数据,并将这两个 csv 文件连接成一个大的数据帧。这样会更容易让模型去训练模型。
df = pd.read_csv('races.csv')
df = df.drop('date',axis = 1)
df = df.drop('going',axis = 1)
df = df.drop('surface',axis = 1)
df = df.drop('prize',axis = 1)
df = df.drop('race_no',axis = 1)
for column in df.columns:
if 'sec' in column or 'time' in column or 'place' in column or 'win' in column:
df = df.drop(column,axis = 1)
df
这个脚本从数据集中删除了所有不必要的信息。以下是删除所有不必要信息后的数据集:

df2 = pd.read_csv('runs.csv')
这个脚本打开第二个 csv 文件,该文件包含参加比赛的马的所有信息。
df2 = pd.read_csv('runs.csv')
df2 = df2.drop('horse_id',axis = 1)
df2 = df2.drop('result',axis = 1)
df2 = df2.drop('horse_gear',axis = 1)
df2 = df2.drop('win_odds',axis = 1)
df2 = df2.drop('place_odds',axis = 1)
df2 = df2.drop('trainer_id',axis = 1)
df2 = df2.drop('jockey_id',axis = 1)
df2['race_id'] = df2['race_id']
for column in df2.columns:
if 'time' in column or 'behind' in column or 'position' in column:
df2 = df2.drop(column,axis = 1)
df2
这个脚本从 csv 文件中删除所有不必要的数据。这是之后的数据集:

import warnings
warnings.filterwarnings('ignore')
import numpy as np
true_df = []
for i in range(len(df['race_id'])):
matches = list(df2[df2['race_id']==i].drop(['race_id'],axis=1).drop(['horse_no'],axis=1).drop(['won'],axis=1).values)
horse_no = len(matches)
matches.insert(0,df[df['race_id']==i].values[0])
matches = flatten(matches)
true_df.append(matches)
这个脚本将两个 CSV 文件连接在一起:对于每场比赛,它会找到所有参加比赛的马。该数据被展平并添加到关于比赛的信息中。这样做的结果是,您最终得到一个数据帧,每一行都是一场比赛。每行有 104 个值,包含关于比赛和比赛中每匹马的信息。
true_df = pd.DataFrame(true_df)
true_df
之后,我们可以将列表转换成数据帧。以下是完整的数据框架:

所有的 NaN 值都在那里,因为有些比赛有 14 匹马,而其他比赛只有 12 匹马。对于这 12 场赛马,其他值用零填充。
winners = []
for i in range(len(df['race_id'])):
try:
winner = df2[df2['race_id']==i][df2['won']==1]['horse_no'].values[0]
except:
print(df2[df2['race_id']==i][df2['won']==1])
winner = 1
winners.append(winner)
然后我收集每场比赛的所有结果,并将这些数据添加到每一行的末尾。
true_df['winners'] = winners
true_df = pd.DataFrame(true_df).fillna(0)
true_df.to_csv('Desktop\\Files\\Data\\insert_data.csv',index=False)
然后,我用 0 替换 NaN 和 None 的所有实例,因此它不会影响模型的定型。然后,数据框被保存为 csv 文件。
训练模型:
import os
os.chdir('C:\\Users\\v_sim\\Desktop\\Files\\Data')import pandas as pd
df = pd.read_csv('insert_data.csv')
winners = df['winners'].values
df = df.drop('winners',axis=1).fillna(0)
df = df.drop('0',axis = 1)
将数据帧保存为 csv 文件后,此脚本打开 csv 文件,记录每场比赛的获胜者,然后将他们从数据帧中移除。这是为了让其余的数据可以直接转换为 X 值。
def create_dict(array):
array = array.astype(str)
unique = np.unique(array)
encode_dictionary = dict()
decode_dictionary = dict()
for i in range(len(unique)):
encode_dictionary[unique[i]] = i
decode_dictionary[i] = unique[i]
return encode_dictionary,decode_dictionarydef encode_df(df):
columns = df.columns
dtypes = df.dtypes
for i in range(len(columns)):
if dtypes[i] == 'object':
encode,decode = create_dict(df[columns[i]].values)
df[columns[i]] = df[columns[i]].map(encode)
return dfdf = encode_df(df)
df = df.fillna(0)
这个脚本包含两个函数:一个对列表中的信息进行编码,另一个对 dataframe 中的列应用该函数,其中的数据是非数字的。
X = df.values.reshape(len(X),103,1)
y = np.array(y)
该函数根据应用于初始数据集的操作定义 X 和 y 值。
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Flatten,BatchNormalization
from keras.layers import Dropout
from keras.layers.convolutional import Conv1D
from keras.layers.convolutional import MaxPooling1D
from keras.optimizers import Adam
import kerasmodel = Sequential()
model.add(Conv1D(filters=256, kernel_size=2, activation='relu', input_shape=(103,1)))
model.add(MaxPooling1D(pool_size=2))
model.add(BatchNormalization())
model.add(Conv1D(filters=512, kernel_size=2, activation='relu'))
model.add(MaxPooling1D(pool_size=2))
model.add(BatchNormalization())
model.add(Conv1D(filters=1024, kernel_size=2, activation='relu'))
model.add(MaxPooling1D(pool_size=2))
model.add(BatchNormalization())
model.add(Flatten())
model.add(Dense(64,activation = 'relu'))
model.add(Dense(128,activation = 'relu'))
model.add(Dense(256,activation = 'relu'))
model.add(BatchNormalization())
model.add(Dense(14, activation='softmax'))model.compile(loss='categorical_crossentropy', optimizer='adam',metrics = ['accuracy'])
这是我最终选择的型号。这是一个典型的卷积网络,用于图像分类。我把它用于一维数组和多类分类。
from keras.models import Sequential, load_model, model_from_json
from keras import callbacks, optimizers
symbol = 'horse_racing'
h5 = symbol + '_best_model' + '.h5'
checkpoint = callbacks.ModelCheckpoint(h5,
monitor='loss',
verbose=0,
save_best_only=True,
save_weights_only=True,
mode='auto',
period=1)
callback = [checkpoint]
json = symbol + '_best_model' + '.json'
model_json = model.to_json()
with open(json, "w") as json_file:
json_file.write(model_json)
model.fit(X,y,epochs = 5000,callbacks = callback,validation_split = 0.1)
这个脚本使用检查点回调来训练模型,以便可以保存和重新加载模型的最佳迭代的权重。这防止了计算资源的浪费。
在对模型进行一段时间的训练后,我发现该模型对训练数据有 92%的准确性,但对验证数据的准确性相对较差。
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Flatten,BatchNormalization
from keras.layers import Dropout
from keras.layers.convolutional import Conv1D
from keras.layers.convolutional import MaxPooling1D
from keras.optimizers import Adam
import kerasmodel = Sequential()
model.add(Conv1D(filters=64, kernel_size=2, activation='relu', input_shape=(103,1)))
model.add(MaxPooling1D(pool_size=2))
model.add(BatchNormalization())
model.add(Dropout(0.3))
model.add(Conv1D(filters=128, kernel_size=2, activation='relu'))
model.add(MaxPooling1D(pool_size=2))
model.add(BatchNormalization())
model.add(Dropout(0.3))
model.add(Conv1D(filters=256, kernel_size=2, activation='relu'))
model.add(MaxPooling1D(pool_size=2))
model.add(BatchNormalization())
model.add(Dropout(0.3))
model.add(Conv1D(filters=512, kernel_size=2, activation='relu', input_shape=(103,1)))
model.add(MaxPooling1D(pool_size=2))
model.add(BatchNormalization())
model.add(Dropout(0.3))
model.add(Conv1D(filters=1024, kernel_size=2, activation='relu'))
model.add(MaxPooling1D(pool_size=2))
model.add(BatchNormalization())
model.add(Dropout(0.3))
model.add(Conv1D(filters=2048, kernel_size=2, activation='relu'))
model.add(BatchNormalization())
model.add(Dropout(0.3))
model.add(Flatten())
model.add(Dense(64,activation = 'relu'))
model.add(Dense(128,activation = 'relu'))
model.add(Dense(256,activation = 'relu'))
model.add(Dropout(0.3))
model.add(BatchNormalization())
model.add(Dense(14, activation='softmax'))model.compile(loss='categorical_crossentropy', optimizer='adam',metrics = ['accuracy'])
这个模型是我用来解决这个问题的模型:这个模型更深也更广。该模型更深,以便可以发现更复杂的模式,它更宽,以便更好地处理辍学问题。
结论:
这个项目只是体育分析的机器学习的一个基本实现,只是为了好玩。我认为这是相当成功的,但是对数据的过度拟合仍然是一个问题。
我的链接:
如果你想看更多我的内容,点击这个 链接 。
新冠肺炎患者住院时间的预测
原文:https://towardsdatascience.com/predicting-hospitalized-time-of-covid-19-patients-f4e70456db9b?source=collection_archive---------19-----------------------
医疗保健中的监督机器学习

作者照片
2020 年新冠肺炎疫情的爆发导致美国医疗保健系统出现巨大的设备、材料短缺和床位短缺问题[1]。医院不仅需要照顾常规病人,还需要照顾突然增加的新冠肺炎病人。医院系统的良好规划和管理变得非常重要。
本文介绍了如何使用机器学习来预测新冠肺炎患者在入院时需要住院多长时间(以天为单位)的新方法。这可以帮助医院专业人员对患者治疗和资源(例如,房间、床位等)进行优化规划。)分配。这也可以减少医院访客的数量,从而减少工作人员和访客感染的机会。
本文其余部分安排如下:
- 数据理解
- 数据准备
- 建模
- 模型评估
- 部署考虑
1.数据理解
数据集从 Kaggle 的网站【1】获得。本文中使用了三个文件:
- train_data.csv :包含与患者、医院和住院时间相关的特征(标签)
- test_data.csv :包含与患者、医院相关的特征。需要预测每个病例 id 的“住院时间”
- train _ data _ dictionary . CSV:包含训练和测试文件中的特征信息。
如图 1 所示,该数据集中有 318,438 个数据样本,总共 17 个特征和 1 个标签列( Stay )。

图 1: 训练数据集的转置视图。
图 2a 显示了数据集中以下数字特征的统计摘要:
- 案例 id
- 医院代码
- 城市代码医院
- 医院提供额外房间
- 河床坡度
- patientid
- 城市代码患者
- 有病人的来访者
- 入场 _ 存款

图 2a: 数据集中数值特征的统计汇总。
上述数字特征分布的可视化如图 2b 所示。
可以看出, case_id 特征值均匀分布在仓上,因为它们是唯一的序列号。由于缺乏预测能力,此功能可能会被删除。

图 2b: 数字特征分布。
图 3 显示了患者就诊分布。我们可以看到许多患者多次(从 10 次到 50 次)重访医院。所以病人身份在预测中很重要。

图 3: 患者就诊分布。
图 4a 显示了分类特征和标签列的分布:
- 医院类型代码
- 医院区域代码
- 部门
- 病房类型
- 病房设施代码
- 录取类型
- 疾病的严重程度
- 年龄
- 停留(标签)
我们可以看到标签的分布明显向右倾斜。换句话说,数据是不平衡的。从“41–50”到“61–70”的数据样本非常少。这将对预测能力产生显著的负面影响。

图 4a: 分类特征分布。
图 4b 显示了每个标签类中的数据样本数量。

图 4b: 标签类计数。
2.数据准备
有了数据理解,下一步是探索、清理收集的原始数据集并将其转换为适当的格式,以便转换后的数据可以被目标机器学习模型有效地使用。
2.1.处理缺失数据
如图 5 所示,床级特征列有 113 个缺失数据,城市 _ 代码 _ 患者特征列有 4532 个缺失数据。与 318,438 行的数据集相比,缺失数据的总数相对较少(总共 4,645 行)。在这种情况下,我们可以删除缺少数据的行,或者用 0 替换缺少的数据。我选择用 0 替换丢失的数据,以便能够预测部署中带有丢失特征值的 test_data 数据集的结果。详见data_preprocessing.py中的DataCleaning类【6】。
train_data.isnull().sum()

图 5: 缺失数据计数。
2.2 删除没有预测能力的要素(列)
如前所述, case_id 特性不具备预测能力,因此在本项目中被丢弃(参见data_preprocessing.py [6]中的DataCleaning类)。
2.3 分类编码
2.3.1。分类标签编码
标签列在这个数据集中停留是分类的。必须转化为数字,用于分类特征目标编码[7]和深度学习模型。LabelEncoder 算法[8]用于转换(参见data_preprocessing.py [6]中的TargetEncoding和OneHotEncoding类)。
2.3.2 分类特征目标编码
目标编码[7]的优势在于它不会增加数据集的维度。它已经在这个项目中用于将分类特征转换为集成机器学习模型XGBoost【2】和Random Forest【3】的数字,因为这些模型由于高维度而不能很好地与一键编码一起工作。参见data_preprocessing.py【6】中的TargetEncoding类。
2.3.3。分类特征一键编码
作为比较,流行的 one-hot 编码方法用于转换分类特征,也用于深度学习模型(参见data_preprocessing.py [6]中的OneHotEncoding类)。
2.3.4。其他分类特征转换
我注意到分类年龄特征(例如“21–30”)一旦转换成数字就有了更强的预测能力,因为年龄的顺序有所不同。在这个项目中,每个年龄范围(例如,“21-30”)都被转换成一个平均数,比如(21+30)/2 = 25.5(参见data_preprocessing.py [6]中的OneHotEncoding类)。
2.4.特征标准化
数字特征归一化到深度学习的[-1, 1]范围内(见data_preprocessing.py【6】中的FeatureNormorlization类)。
2.5.数据分割
最后,预处理后的数据集被分成两个子集:一个用于模型训练,另一个用于模型评估。
2.6.数据预处理管道
为方便起见,数据准备步骤 2.1–2.5 已合并到数据预处理管道中:
- 目标 _ 编码 _ 预处理
- 预测的目标编码预处理
- onehot _ encoding _ 预处理
- one hot _ encoding _ preprocessing _ for _ prediction
详见data_preprocessing.py【6】。
3.建模
数据准备好后,我们就可以开始建模了。建模的主要目标包括:
- 识别潜在的机器学习模型
- 训练模型并调整模型的超参数
3.1.型号选择
这个项目解决了一个分类问题,因为标签是分类的。这适用于XGBoost【2】、随机森林【3】、深度学习多层感知器(https://en.wikipedia.org/wiki/Multilayer_perceptron**)分类器等有监督的机器学习分类模型【4】。
由于数据是表格形式,特征数量相对较少,所以相比深度学习模型,一般首选 XGBoost 和随机森林。
本项目选择 XGBoost 、随机森林、、 MLP 、分类器进行实验。
3.2.模型训练和超参数调整
XGBoost 和随机森林模型训练均采用 10 文件夹交叉验证。网格搜索用于选择超参数的最佳组合。交叉验证也用于训练深度学习模型。参见train_test_classifier.py中的以下功能:
- build_xgboost_model
- 构建 _ 射频 _ 模型
- 构建 _ 深度学习 _ 模型
4.模型评估
一旦训练了不同的机器学习模型,就需要评估这些模型的性能,以便我们可以选择最佳的模型进行部署。
分类准确度、F1 分数和混淆矩阵被用作该项目的主要评估指标。详见train_test_classifier.py中的以下功能:
- evaluate_xgboost_model
- evaluate_rf_model
- evaluate_dl_model
通常,在具有不平衡数据的二进制分类的情况下,准确度不是一个好的度量,因为它可以通过简单地预测多数类来容易地实现高百分比的准确度。然而,在多类分类中这不是必须的。例如,在这个项目的数据集中,大多数类别 21-30 只有 87,491 个数据样本。数据样本的总数是 318,438。如果一个模型总是预测多数类,精度将是大约 27.5%。因此,在多类分类的情况下,精度仍然可以是良好的模型性能测量,因为它表示不同标签类的分类的平均精度。
除了准确性之外,F1 分数还用于测量 XGBoost 和随机森林模型性能,因为它可以测量准确性和召回率的平衡,这适用于不平衡的数据。
使用混淆矩阵是因为它可以清楚地告诉我们模型犯了什么预测错误。
4.1.MLflow
为了有效地跟踪模型超参数和性能指标,使用了 MLflow 工具【5】。特别是,我开发了train_test_classifier.py中的mlFlow()功能,将以下活动合并到一个过程中:
- 加载训练数据
- 预处理数据
- 培训模式
- 评估模型
例如,下面的 mlFlow ()函数调用为 XGBoost 模型产生结果(例如,图 6 中的混淆矩阵)。
*target_encoders, label_encoder = mlFlow()*

图 6: XGBoost 混淆矩阵。
图 6 中的混淆矩阵表明,数据越多,预测结果越好。例如,真阳性的最大数量 14,429 在 21–30 的类别中。
图 7 显示了四个模型评估的结果:
- XGBoost 带目标编码
- **随机森林带目标编码
- MLP 用目标编码
- MLP 采用一键编码
我们可以看到 XGBoost 在给定数据集的准确性和 F1 分数方面都具有最佳性能,因此如果其性能满足业务需求,我们可以选择它进行部署。

如图 7 所示,最好的准确率分数只有 42.4%左右。这是因为在大多数标记的类别中数据太少,例如以下范围:41-50,从61-70一直到more than 100。
如果可以收集更多的数据来平衡数据集,准确性得分将会增加。作为实验,我只选择了类别为11-20和21-30的数据样本,并注意到准确率提高到了大约 63%。图 8 显示了来自经过训练的随机森林模型的相应混淆矩阵。

图 8: 带有两个标签类别的随机森林模型的混淆矩阵。
为了理解不同的特征如何影响预测,图 9 显示了由训练的随机森林模型产生的特征重要性。

图 9: 随机森林模型产生的特征重要性。
我还研究了特性和目标标签之间的相关性,如图 10 所示。

图 10: 特征和目标标签(Stay)相关系数。
使用相关系数来确定特征和目标之间的关系的强度是棘手的,因为相关系数仅指示线性关系。具有非常低的相关系数的特征(例如 patientid )不一定表示该特征和目标之间没有关系。例如,patient id具有非常小的相关系数,但是其特征重要性很高。
我尝试删除一些功能重要性较低的功能(例如,医院 _ 地区 _ 代码、城市 _ 代码 _ 医院等)。)和具有非常小的相关系数的特征(例如,City_Code_Hospital ),并且观察到这无助于提高准确度分数。
5.部署
一旦在模型评估中确定了部署的最佳模型,我们就可以进入最后一步,将确定的模型部署到生产环境中。一种常见的部署方法是将模型作为 Web 服务部署在服务器上,目标生产系统中的其他组件可以调用它来预测结果。
为了支持部署,在模型训练后,所选择的训练模型(如 XGBoost 和相关的编码对象(如 LabelEncoder 对象、 TargetEncoder 对象)都被保存到 Python pickle 文件中。这些保存的编码对象和模型将被加载回来,以便在部署中进行预测。
例如,以下代码加载到test_data.csv中,用于部署中的预测。图 11 显示了加载的测试数据集的转置视图。注意,这个数据集没有标签列 Stay 。
*test_data = load_data('test_data.csv')
print(test_data.shape)
test_data.transpose().head(100)*

图 11: 预测前的测试数据。
下面的代码执行以下操作:
- 加载保存的模型并编码对象
- 使用它们来预测测试数据集中每个患者的住院天数
- 显示结果数据帧中的前 100 条记录,带有特性和预测标签(保持列)(参见图 12)
- 显示预测标签的分布。
我们可以从图 4 和图 13 中看到,图 13 中预测标签的分布模式与图 4 中标签的分布模式非常相似。
*label_encoder, target_encoders = load_encoders()
result_df = predict(label_encoder, target_encoders, test_data_file='test_data.csv')
result_df['Stay'].value_counts().plot(kind='bar')
result_df.transpose().head(100)*

图 12: 带预测标签的测试数据。

图 13: 预测标签分布。
改进
如第 4.1 节所示,所选的最佳模型 XGBoost 仅实现了约 42.4%的准确性和 0.39 的 F1 分数。一个主要问题是数据严重失真,如图 4a 和 4b 所示。一个可能的改进是尽可能收集更多数据和/或使用数据论证技术生成更多数据样本以平衡数据集。
结论
本文介绍了如何使用不同的机器学习模型来预测新冠肺炎患者的住院时间,使用的数据集来自 Kaggle [1]。这个数据集是困难的,因为它是一个多类单标签的情况,并且数据集是显著偏斜的。
实验结果表明,使用具有目标编码和特征工程(例如,年龄特征的转换)的 XGBoost 在预测准确度(42.4%)和 F1 分数 0.39 方面实现了最佳性能。这一结果与 Kaggle [1]中描述的结果具有竞争性。
参考
- ka ggle 中的新冠肺炎数据集
- XGBoost
- 随机森林分类器
- Keras 顺序模型
- MLflow
- Github 中的源代码
- 目标编码器
- 标签编码器
鸣谢:我要感谢 Udacity reviewer 的指导性评论和 Kaggle 的数据集。
用机器学习预测房价
原文:https://towardsdatascience.com/predicting-house-prices-with-machine-learning-62d5bcd0d68f?source=collection_archive---------1-----------------------
高级回归技术
Kaggle 高级回归技术竞赛的端到端项目

美国宇航局在 Unsplash 拍摄的照片
简介
我想我应该在 Kaggle 的高级回归技术竞赛中一试身手带你一起踏上旅程。如果你正在进入机器学习领域,并希望看到一个完整的项目,请留下来。我将向您介绍我所采取的步骤,同时尝试提供机器学习的速成课程。
目标和数据
比赛的目标是预测爱荷华州埃姆斯的房屋销售价格。您会得到一个 csv 格式的训练和测试数据集以及一个数据字典。
训练:我们的训练数据包括 1460 个房屋示例,其中 79 个特征描述了房屋的各个方面。我们得到了每栋房子的销售价格(标签)。训练数据是我们用来“教授”我们的模型的。
测试:测试数据集由 1459 个样本组成,特征数量与训练数据相同。我们的测试数据集不包括销售价格,因为这是我们试图预测的。一旦我们的模型已经建立,我们将运行最好的一个测试数据,并提交给 Kaggle 排行榜。
你可以在比赛页面熟悉数据。
任务:机器学习任务通常分为三类;有监督,无监督和强化。对于这次比赛,我们的任务是监督学习。
监督学习使用例子和标签来发现数据中的模式
从你拥有的数据和你的目标中,很容易识别你面前的机器学习任务的类型。我们获得了由要素和标签组成的房屋数据,我们的任务是预测训练数据之外的房屋标签。
工具
比赛用的 Python 和 Jupyter 笔记本。Jupyter 笔记本在数据科学家中很受欢迎,因为它们易于跟踪并显示您的工作步骤。
请注意,此代码不是用于生产目的,它不遵循软件工程最佳实践。为了便于解释,我牺牲了一些。
库:这些是 python 中处理常见任务的框架。我恳请任何初露头角的数据科学家熟悉这些库:
熊猫 —用于处理结构化数据
Scikit Learn—用于机器学习
NumPy —用于线性代数与数学
Seaborn—用于数据可视化
项目管线
一般来说,机器学习项目遵循相同的流程。数据摄取、数据清洗、探索性数据分析、特征工程以及最终的机器学习。
流水线不是线性的,你可能会发现你必须在不同的阶段之间来回跳跃。我提到这一点很重要,因为教程经常让你相信这个过程比现实中要干净得多。所以请记住这一点,你的第一个机器学习项目可能会一团糟。
在我们开始之前,我要重申,机器学习是一个迭代的过程,很少是简单明了的!如果你发现自己迷失在一个 ML 项目中,请不要气馁。坚持阅读,坚持实验,坚持提问,总有一天会成功的。
本文的其余部分将讨论项目管道的各个阶段。在有用的地方,我会加入来自 python 的代码示例。完整的端到端项目可以在这里使用和发挥。我会在文末分享这个的链接。
数据清理
Kaggle 尽力为用户提供干净的数据。但是,一定不能变懒,数据总有惊喜。
警告!不要跳过数据清理阶段,这很无聊,但会帮你省下几个小时的头痛时间。
重复&NaN:我从删除数据中的重复开始,检查是否有缺失或 NaN(非数字)值。检查 nan 很重要(不仅仅是因为这是社会道德),因为它们会导致机器学习模型中的错误。
分类特征:当房屋的某个特征不存在时,有很多分类变量被标记为 N/A。例如,当没有小巷存在时。我确定了在训练和测试数据中发生这种情况的所有案例,并用更具描述性的内容替换了 N/a。n/a 会导致机器学习出错,所以把它们去掉吧。
日期特性:在这个练习中,日期最好作为类别而不是整数来使用。毕竟,我们关心的不是数量级,而是日期代表不同的年份。解决这个问题很简单,只需将数字日期转换成字符串。
解码变量:一些分类变量已经被数字编码。请参见下面的示例。

作者生成的图像
这里的问题是,机器学习算法可以将数字的大小解释为重要的,而不仅仅是将其解释为不同类别的特征。为了解决这个问题,我逆向工程的类别,并重新编码。
探索性数据分析(EDA)
这是我们的数据可视化之旅经常开始的地方。机器学习中 EDA 的目的是探索我们数据的质量。需要记住的一个问题是:有没有什么奇怪的模式让我们挠头?
标签:我在柱状图上绘制了销售价格。销售价格的分布是右偏的,这是意料之中的。在你家附近,看到一些相对昂贵的房子可能并不罕见。
在这里,我执行了我的第一个功能工程(告诉过你这个过程是混乱的)。我将对销售价格应用对数变换来压缩异常值,使分布正常。
离群值会对使用最小化平方误差的损失函数的模型产生毁灭性的影响。尝试应用变换,而不是删除异常值。
用 Python 绘制直方图

由作者生成的图像—对数变换前后的销售价格直方图
相关性:绘制一个相关性矩阵通常有助于了解数据中存在的关系。也可以指导你的模型建立。例如,如果您看到许多要素相互关联,您可能希望避免线性回归。
用 Python 绘制皮尔逊相关图

图片由作者生成:数值变量之间皮尔森相关性的热图
这里使用的相关性度量是皮尔逊相关性。在我们的例子中,正方形越亮,两个变量之间的相关性越强。
与空间相关的特征,如地段临街面、车库面积、地面居住面积,都与销售价格正相关,正如人们所料。逻辑是越大的房产越贵。这里没有可疑的关联。
类别关系:销售价格在每个类别的每个级别内近似呈正态分布。没有观察出现,不幸的。一些类别包含很少或没有数据,而其他类别显示很少或没有区分销售类别的能力。查看 GitHub 上的完整项目,了解数据可视化。
特色工程
机器学习模型无法理解分类数据。因此,我们需要应用转换将类别转换成数字。这样做的最佳实践是通过一个热编码。
亲提示! —确保使用 Sci Kit Learn 的 OneHotEncoder 和避免 panda 的 get_dummies。使用 get_dummies 时,如果训练和测试数据集中的类别级别不同,您将会遇到一大堆问题。
OneHotEncoder 通过可以设置类别和处理未知数的选项解决了这个问题。它有点难用,但对机器学习来说绝对是必要的。
这里有一篇关于 one hoten coder的精彩文章和 python 示例。
机器学习
我遵循机器学习的标准开发周期。作为一个初学者,甚至是一个专业人士,在你能够让你的模型工作在一个高标准之前,你可能不得不经历许多循环的迭代。随着你获得更多的经验,迭代的次数会减少(我保证!).

图片作者:机器学习模型开发周期
型号选择
正如本文开头提到的,任务是监督机器学习。我们知道这是一个回归任务,因为我们被要求预测一个数字结果(销售价格)。
因此,我用三种机器学习模型来处理这个问题。决策树、随机森林和梯度推进机器。我使用决策树作为我的基线模型,然后基于这个经验来调整我的候选模型。这种方法节省了大量时间,因为决策树可以快速训练,并且可以让您了解如何为我的候选模型调整超参数。
模型机制:在这里我不会过多的讨论每个模型是如何工作的。相反,我会使用一行程序,将你链接到描述他们在“幕后”做什么的文章。
决策树 —机器学习中使用的一种树形算法,通过学习决策规则来发现数据中的模式。
随机森林 —一种利用“群体智慧”效应的装袋方法。它并行使用多个独立的决策树从数据中学习,并聚合它们对结果的预测。
梯度推进机器 —一种串联使用决策树组合的推进方法。每棵树都被用来预测和修正前一棵树的误差。
随机森林和梯度推进可以将单个弱决策树变成强预测模型。如果你有像我们这样的小训练数据集,它们是很好的算法。
训练
在机器学习中,训练是指使用训练数据集中的示例来教授模型的过程。在训练阶段,您将调整您的模型超参数。
在我们深入讨论细节之前,我想简单介绍一下偏差-方差权衡。
模型偏差—模型对训练数据的拟合不足,导致对未知数据的预测能力较差。一般来说,模型越简单,偏差越大。
模型差异-模型过度拟合训练数据,导致对未知数据的预测能力较差。一般来说,模型越复杂,方差就越高。
复杂性可以被认为是模型中特征的数量。模型方差和模型偏差具有导致折衷的相反关系。模型复杂度存在一个最佳点,使误差最小。我们试图通过调整我们的超参数来确定这一点。
这里有一篇很好的文章可以帮助你更详细地探索这个东西。
超参数:超参数帮助我们调整模型的复杂性。对于每个模型应该调优哪些超参数,有一些最佳实践。我将首先详述超参数,然后告诉您我为每个模型选择了哪些参数进行优化。
max_depth —给定决策树的最大节点数。
max _ features 考虑在结点处进行分割的要素子集的大小。
n _ estimators 用于提升或聚合的树的数量。该超参数仅适用于随机森林和梯度增强机器。
learning _ rate 学习率用于减少每棵树的贡献。这只适用于梯度增压机。
决策树-调整的超参数是最大深度和最大特征
随机森林-要调整的最重要的超参数是 n 估计量和最大特征[1]。
梯度推进机器——要调整的最重要的超参数是 n_estimators、max_depth 和 learning_rate [1]。
网格搜索:选择超参数的范围是一个迭代过程。有了更多的经验,你会开始对设置什么样的范围有所感觉。好消息是,一旦你选择了可能的超参数范围,网格搜索允许你在这些范围的每个组合上测试模型。我将在下一节详细讨论这一点。
交叉验证:模型经过 5 重交叉验证训练。这是一种技术,它采用您的全部训练数据,在 5 次迭代中将其随机分成训练和验证数据集。
您最终会得到 5 个不同的训练和验证数据集来构建和测试您的模型。这是对抗过度合身的好方法。
更一般地,这种交叉验证被称为 k 重交叉验证。更多关于 k 倍交叉验证点击这里。
实现 : SciKit Learn 帮助我们在使用 GridSearchCv 时轻松地将超参数调整和交叉验证结合在一起。它为您提供了查看每次训练结果的选项。
下面是构建随机森林模型的代码。
评估
这是流程的最后一步。在这里,我们要么高兴地跳起来,要么沮丧地揪自己的头发(开玩笑,我们不会那样做……永远不会)。我们可以使用数据可视化来查看每个候选模型的结果。如果我们对我们的结果不满意,我们可能不得不在从数据清理到机器学习的任何阶段重新审视我们的过程。
我们的性能指标将是负均方根误差(NRMSE)。我用这个是因为它是我在 SciKit Learn 中能得到的最接近 Kaggle 的评分标准。
决策树
可以预见,这是我们表现最差的方法。我们最好的决策树得分-0.205 NRMSE。调整超参数似乎并没有对模型产生太大的影响,但它在 2 秒内完成了训练。肯定有一些范围来评估更广泛的超参数。

作者图片:决策树的 NRMSE 图
随机森林
我们的随机森林模型是对决策树的显著改进,NRMSE 为-0.144。这个模型花了大约 75 秒来训练。

作者图片:随机森林的 NRMSE 情节
梯度推进机
这是我们表现最好的一次,NRMSE 为-0.126。超参数显著影响结果,说明我们在如何调整这些更复杂的模型时必须非常小心。该模型的训练时间约为 196 秒。

图片由作者提供:GitHub 中的梯度推进机器完整版的 NRMSE 图
比赛结果
我在 Kaggle 测试数据上测试了性能最好的模型。我的模型把我放在了前 39%的进入者中(在我写作的时候)。这不是一个坏的结果,但它肯定可以得到改善。以下是我们可以做到的一些方法:
分类变量:数据中的一些分类特征具有很高的基数。因此,树模型可能偏向于这些特征。我们也许可以通过将这些高维特征重新归类到较低的维度来提高模型性能。
超参数调整:我们可以扩大超参数的解空间,希望找到一个更好的位置。请注意,如果你只是在笔记本电脑上工作,这将需要强大的计算能力。
希望这篇文章对你了解机器学习有所帮助。一如既往,请不要气馁,一切都是实践和耐心。
🚀这里有一个包含代码的 Jupyter 笔记本的链接。可以自己试试
https://www.linkedin.com/in/john-adeojo/
参考
[1]布尔科夫,A (2019)。一百页的机器学习书籍,第 84–85 页
用 Keras 预测个体生存曲线
原文:https://towardsdatascience.com/predicting-individual-survival-curves-with-keras-abb1f1f051f?source=collection_archive---------27-----------------------
用于客户终身价值模型的 Kaplan-Meier 估计量的深度学习适应

迈克尔·朗米尔在 Unsplash 上的照片
TL;灾难恢复生存分析模型广泛应用于从医学到电子商务的不同领域。人们越来越关注如何开发个体生存函数,而不是群体生存函数,主要是通过使用深度学习框架。这篇文章介绍了对人口生存分析最常见的非参数方法之一的深度学习改编,卡普兰-迈耶估计器。
简介
在研究和工业中,对预测个体生存函数,即任何给定时间的生存概率函数的兴趣越来越大。这项任务的大多数现有方法要么是参数化的,要么是半参数化的,而很少是严格非参数化的。
一些基于深度学习的最流行模型的 PyTorch 实现可以在 pycox 库中找到,而 scikit-survival 和 XGBoost 为 Survival regression 提供了其他机器学习替代方案,如随机森林和梯度增强。
我们介绍了一种最广为人知的非参数生存分析方法的改进,即 Kaplan-Meier 估计量,用于预测个体生存函数。我们通过深度学习变异的多任务逻辑回归 (MTLR)和 N-MTLR 来实现这一点。我们的模型的主要区别在于,使用样本权重处理删失数据,并且模型在每个时间段的输出是前一个时间段的输出和 sigmoid 层的乘积。
卡普兰-迈耶估计值
设 S(t)是生存至少 t 个时间单位的概率,即生存函数:

https://en . Wikipedia . org/wiki/Kaplan % E2 % 80% 93 Meier _ estimator
根据条件概率,它也是:

https://en . Wikipedia . org/wiki/Kaplan % E2 % 80% 93 Meier _ estimator
在哪里

https://en . Wikipedia . org/wiki/Kaplan % E2 % 80% 93 Meier _ estimator
其估计量由下式给出:

https://en . Wikipedia . org/wiki/Kaplan % E2 % 80% 93 Meier _ estimator
换句话说,t 时刻的 KM 估计量等于 t-1 时刻的 KM 估计量乘以 t 时刻未死亡的个体在已知存活到 t 时刻的个体中所占的比例。
深度学习适应
我们的方法很简单:

https://en . Wikipedia . org/wiki/Kaplan % E2 % 80% 93 Meier _ estimator
- 我们用多输出前馈神经网络来表示上述递归,其中每个输出是前一个输出乘以表示概率 q(t)的 sigmoid 层。
- 使用样本权重处理删失数据:对于每个输出 t,如果个体的开始日期至少在 t 个时间段之前,则样本权重为 1,否则为 0。
代码看起来怎么样?
def build_model(
self,
input_shape: int,
hidden_units: List[int],
dropout: Optional[float] = None,
activation: Optional[str] = None,
kernel_regularizer: Optional[str] = None,
kernel_constraint: bool = False,
noise: Optional[float] = None,
normalization: bool = False,
):
K.clear_session()
inputs = Input(shape=(input_shape,))
x = inputs
for units in hidden_units:
x = Dense(
units,
activation=activation,
kernel_regularizer=kernel_regularizer,
kernel_constraint=UnitNorm() if kernel_constraint else None,
)(x)
x = GaussianNoise(noise)(x) if noise else x
x = BatchNormalization()(x) if normalization else x
x = Dropout(dropout)(x) if dropout else x
outputs = []
for period in range(self._periods):
if period == 0:
o = Dense(
1,
activation="sigmoid",
kernel_regularizer=kernel_regularizer,
kernel_constraint=UnitNorm() if kernel_constraint else None,
)(x)
outputs.append(o)
continue
o = Dense(
1,
activation="sigmoid",
kernel_regularizer=kernel_regularizer,
kernel_constraint=UnitNorm() if kernel_constraint else None,
)(x)
o = Multiply()([o, outputs[period - 1]])
outputs.append(o)
self.model = tf.keras.Model(inputs=inputs, outputs=outputs)def fit(
self,
X_train: np.ndarray,
y_train: List[np.ndarray],
w_train: List[np.ndarray],
validation_data: Tuple[np.ndarray, List[np.ndarray], List[np.ndarray]],
epochs: Optional[int] = 100,
batch_size: Optional[int] = 256,
patience: Optional[int] = 10,
):
self.model.compile(optimizer="Adam", loss="binary_crossentropy")
callback = tf.keras.callbacks.EarlyStopping(
monitor="val_loss", patience=patience
)
self.model.fit(
X_train,
y_train,
sample_weight=w_train,
epochs=epochs,
batch_size=batch_size,
validation_data=validation_data,
callbacks=[callback],
)
当然,架构只是一个参考。如上所述,应将 X 连同 shape (n_samples,n_features)、y (n_samples,periods)和 w (n_samples,periods)传递给此模型的拟合方法。
摘要
有几种方法来拟合生存回归模型,每种方法都有其优点和缺点。在这篇文章中,我提出了一个非常简单的方法,利用 Tensorflow 的灵活性,使用前馈神经网络来生成个体生存曲线,而不依赖于强假设,这在概念上是对最常见的生存分析模型之一的改编:Kaplan-Meier 估计量。
用线性回归预测曼哈顿租金
原文:https://towardsdatascience.com/predicting-manhattan-rent-with-linear-regression-27766041d2d9?source=collection_archive---------15-----------------------
对 StreetEasy 出租清单的分析

由弗洛里安·韦德在 Unsplash 上拍摄的照片
介绍
当我想到纽约市不断上涨的房租时,我深感遗憾的是,房租太他妈的贵了,没能让吉米·麦克米兰当选州长。毫无疑问,纽约人需要他上任——但在那一天到来之前,你可以依靠这份分析来了解如何估算纽约的租金成本。
具体来说,我们将使用曼哈顿 3500 个 StreetEasy 租赁房源的数据集。在预测连续因变量(如租金)的值时,线性回归是一种合适的模型。在本文中,我们将研究这些数据,并逐步完成开发回归模型来预测租金价值的步骤。
探索性分析
我首先将清单加载到 pandas 数据框中,并查看数据类型。除了 borough 和 neighborhood 列,所有变量都是数字,幸运的是,没有丢失值。因为曼哈顿区对于所有行都是一样的,所以我删除了区列,并研究了其他列的分布。我对数据调用了**pandas.DataFrame.hist()**方法来查看数值变量的分布:

数字变量直方图。由作者策划。
我们可以看到,租金、浴室、楼龄和楼层都具有右偏分布。租金从 1300 美元到 20000 美元不等,平均每月 5138 美元(哎呀!).单卧室公寓比工作室或多卧室公寓更常见,大多数公寓都没有健身房、门卫、屋顶平台和露台等花哨功能。对于这些变量,0 表示“否”,1 表示“是”
为了我的邻居,我真诚地希望所有 40 层以上的房源都属于拥有电梯的少数公寓。
接下来,我对唯一剩下的分类变量(邻域)调用了**pandas.Series.value_counts()**方法,并在水平条形图中绘制了计数:

邻域列值计数的条形图。由作者策划。
该数据集中的大多数可用公寓位于上西区和上东区。然而,邻域数据是有缺陷的,因为在一般和特定邻域类别之间存在一些重叠。例如,Morningside Heights 位于上西区,但在数据集中它们是不同的值。未来清理该数据的一个可能步骤是更新邻域列,使其唯一值之间没有重叠。
我还想知道哪些街区的平均租金最高和最低。为此,我按邻域对值进行分组,计算每列的平均值,并将“邻域”和“租金”列分配给单独的数据框。我将租金四舍五入,从高到低排序:
然后,我使用租金平均值列中的值来设置 Seaborn box 图中的邻域顺序:

邻里租房分配。由作者策划。
索霍区、翠贝卡区和中央公园南区的平均租金最高,而小意大利区、因伍德区和曼哈顿维尔区的平均租金最低。正如我们在上面的条形图中看到的,一些邻域在数据集中比其他邻域表现得更好。对于那些拥有更多数据点的社区,如上西区和上东区,样本均值预计会更接近真实的人口均值。
检查线性回归假设
线性回归分析需要检查关于数据的四个假设:线性、不存在多重共线性、残差正态性和同方差性。我们将在回归模型的开发和解释中考虑这些假设。
- 线性关系
线性回归假设解释变量和响应变量之间存在线性关系,无论是正的还是负的。检查线性关系最简单的方法是在散点图上绘制变量之间的关系:如果这些点落在一条大致直的对角线上,那么变量之间的关系就是线性的。为了将所有变量相互对应起来,我在数据上调用了**pandas.plotting.scatter_matrix()** 方法。如果有很多变量,这种方法会产生一个很难阅读的微小散点图矩阵。我对邻域变量进行了哑编码,得到了总共有 46 列的最终数据帧。在确定了与租金可能存在线性关系的变量后,我将它们绘制在一个易于阅读的散点图上,并排除了其他变量:

相关变量的散布矩阵。由作者策划。
惊喜,惊喜:随着公寓面积的增加,租金也在增加。对于具有离散值的变量,如卧室和浴室,与租金的线性关系不那么明显。例如,有五个卫生间的公寓的租金低于有四个、三个甚至两个卫生间的公寓的最高租金。
2。无多重共线性
无多重共线性的假设要求自变量之间的相关性不高。“高度相关”的分界点并不固定,但我倾向于将我的分界点设为 0.7 的绝对值。下面的关联热图显示了与租金相关的值之间的关联:

关联热图。由作者策划。
卧室的数量与租金的相关性相对较弱,与浴室的数量一样,也与平方英尺高度相关。这表明,预测租金最好作为一个简单的线性回归问题来处理,以平方英尺作为唯一的预测因素。
建造模型
线性回归的其余假设指的是模型的残差,因此需要先建立模型,然后才能检查它们。模型的残差是预测 y 值和实际 y 值之间的距离。在我们的案例中:

为了构建模型,我们将使用来自 Scikit-Learn 库中的**LinearRegression()**。该模型期望 x 是一个二维数组,因此 size_sqft 列被转换为一个数组,并用**arrray.reshape(1, -1)**进行了整形。模型与数据拟合,并用于计算残差:
3。残差的正态性
下面,我们可以在左侧看到残差的分布,在右侧看到分位数-分位数(QQ)图:

如果残差满足正态假设,QQ 图上的点将沿着红色对角线紧密分布。但是,点有轻微的 s 形曲线。这些图表明,与正态分布相比,在分布的尾部(即极端)有更多的数据。虽然在这种情况下不完全符合正态假设,但残差的分布足够接近正态,因此模型的预测仍然有价值。
4。同质性
如果残差在所有预测的 y 值上具有相对恒定的方差,则认为残差是同方差的。通过绘制预测值与残差的关系图,可以直观地检查这一假设:

在显示同质性的图中,这些点会以更加对称的矩形形状分布在绿线上。相反,我们看到残差在更高的预测值处远离直线展开。15k 以上的大多数预测值对应于特别低的残差,其中一个残差低于-10,000。该图表明,该模型可能是一个极端租赁成本的糟糕预测。
解释模型
对 x 和 y 数据调用**model.score()**会返回模型的 R 平方值。**model.coef_**和**model.intercept_**属性分别返回系数和截距值。以下数值四舍五入到小数点后两位,并代入一个线性方程来预测租金:

R 平方值告诉我们,仅平方英尺就占租赁成本变化的 74%。用语言来表达这个等式:租金大约是一套公寓平方英尺的 5.7 倍减去几百美元。根据这种模式,一个 250 平方英尺的工作室每月租金约为 1223 美元。一套两倍于这个面积的一居室公寓预计售价约为 2642 美元。
有了这样的数字,难怪如此多的纽约人坚持把自己塞进壁橱大小的住所。
如果你有兴趣看到这个分析的完整代码,请随意访问它的 GitHub 库!
预测 2020 年欧锦赛的比赛
原文:https://towardsdatascience.com/predicting-matches-for-the-uefa-euro-2020-championship-7dcfa449c8ee?source=collection_archive---------17-----------------------
预测足球比赛结果的简单泊松回归方法,准确率为 70%。

威利安·贾斯登·德·瓦斯康塞洛斯在 Unsplash 上拍摄的照片
期待什么?
- 在本文中,我将带您了解如何使用两个泊松回归来预测足球比赛的比分,只有一个预测变量,准确率超过 70%。如果我们记住我们使用的是一个非常简单的模型,并且只有一个预测变量(国际足联球队排名),这是相当令人印象深刻的。
- 泊松回归将以基本线性回归和随机森林回归为基准。
- 您将了解为什么泊松回归是完成这项任务的好工具。
- 我们将研究如何通过专门的后处理步骤来提高预测结果的准确性/ f1 分数。
数据
该方法使用两个数据集,这两个数据集都可以在 Kaggle 上找到:
- 【2020 年欧锦赛参赛球队的历史比赛:https://www . ka ggle . com/martj 42/international-football-results-from-1872-to-2017
- 国际足联排名各队得分:“**足球的世界管理机构国际足联的男子成员国球队根据他们的比赛成绩进行排名,最成功的球队排名最高。”(维基百科)https://www.kaggle.com/cashncarry/fifaworldranking?select = FIFA _ ranking-2021-05-27 . CSV**
训练测试数据分割和特征工程
为了创建我们的训练数据,我只考虑了 2019 年之后的比赛(因为旧的比赛可能不再代表当前球队的表现),并随后将比赛结果与每个球队的国际足联排名结合起来。
最后但并非最不重要的是,我创建了一个新变量“ranking _ diff”,这是主客场球队之间的 FIFA 排名的差异。这个变量将是我们以后模型的唯一预测变量。
我的测试数据包括到目前为止 2020 年欧锦赛小组赛的所有比赛。
请注意:为了让这篇文章更具可读性,我跳过了大部分代码。但是,如果你对端到端的管道感兴趣,请访问我的 GitHub 。
这是经过短暂预处理后的训练数据的样子(注意加入的 FIFA 得分排名列和新创建的 ranking_diff 列):
date home_team away_team home_score away_score tournament home_team_ranking away_team_ranking ranking_diff
2019–01–08 Finland Sweden 1 0 Friendly 1410 1569 -159
2019–01–11 Estonia Finland 2 1 Friendly 1161 1410 -249
2019–01–11 Iceland Sweden 2 2 Friendly 1415 1569 -154
2019–03–20 Germany Serbia 1 1 Friendly 1609 1512 97
2019–03–20 Wales Trinidad and Tobago 1 0 Friendly 1570 1201 369
2019–03–21 Kosovo Denmark 2 2 Friendly 1151 1631 -480
...
探索性数据分析
让我们研究一下 Kaggle 的数据,看看进球的情况:



图 1: 主客场球队进球(左)和(中)的探索性数据分析,以及参赛球队 FIFA 排名差异与主队进球(右)的关系。—作者图片
上面图 1 中的图表提供了一些对数据的洞察:
- 在左边,我们可以看到一个图表,显示了一个主队每场比赛的进球数。每场比赛的平均值是 1.8 个进球(红线),主队进球最多的是 9 个!
- 在中间,我们可以看到同样的客队形象化。我们可以看到客场球队的平均进球数更低,每场比赛只有 1.2 球。每场比赛的最大进球数是 7 个(与主队的 9 个进球相比,这一数字再次下降)。因此,我们可以清楚地看到,一支球队是在主场还是在客场比赛,进球数量会有相当大的差异。****
- 在右侧,我们可以看到主队进球(y 轴)与竞争球队在国际足联排名中的差异(x 轴)之间的关系。在图的左下方,我们可以看到,如果国际足联排名差异非常大(主队的国际足联排名比客队低得多),主队的进球数非常低(0-1 球)。如果一支球队是一个真正的局外人(以国际足联的得分来衡量),它很少会进超过 2 个球!另一方面,如果两支球队的国际足联排名差异具有高正值(主队的国际足联排名比客队高得多),则平均进球数非常高。强大得多的主队实际上从未少于 2 个进球,并且可能得分超过 7+(例如西班牙对圣马力诺)。
方法
从上面图 1 的图表中,我们可以从数据中获得两个重要信息:
- 两支参赛球队在国际足联排名上的差距和进球数有实质性的关系!
- 事实上,球队是在主场还是客场比赛对进球数量有很大的影响。主队平均进 1.8 球,客场平均只进 1.2 球。
为此,我训练了两个独立的回归模型:一个预测主队的分数,另一个预测客场队的分数。(请注意,您也可以简单地训练一个组合模型,并将球队是主场还是客场的信息作为附加因素变量包含在内)。我想让我的模型在最初的尝试中尽可能简单,并且(为了可视化的目的)选择用一个预测变量(FIFA 排名差异)训练单独的模型。
什么时候用泊松?
文献表明,为此目的使用泊松回归是最好的方法。但是,究竟什么是泊松回归,为什么不简单地使用线性回归或其他方法,如随机森林回归方法?
- 嗯,一般来说,当我们预测每单位时间或空间的计数时,会用到泊松回归。比如每场比赛的进球数!由于计数不能为负,泊松模型的最小值是零(不可能得分低于零!),理论上最大值是无界——虽然一个球队进球超过 5 个的情况很少发生:)
- 让我们再看一下图 1(左)。像许多泊松分布一样,这个分布是右偏的。很明显,这并不意味着每场比赛的进球数是正态分布的。然而,正态分布假设是线性回归的关键假设!
线性回归的问题
- 一个简单的线性回归模型用一条直线来表示,对于某些变量组合(如负目标数),这肯定会产生负值。例如,在我们的使用案例中,当我们有一支非常弱的球队(国际足联排名低)与一支非常强的球队(国际足联排名高)比赛时,可能会发生线性回归模型预测较弱球队得分为负数的情况(例如-2.4 球)。这绝对是我们想要避免的。
- 此外,我们的数据违反了线性回归的等方差假设(正态分布)!你可以在上面的右图中看到,当国际足联排名差异获得更高的正值时,进球的方差也增加了!随后的图像再次以图形方式总结了这一点:

图 2: 回归模型:线性回归(左)和泊松回归(右)。—图片来自 Paul Roback 和 Julie Legler,来自 超越多元线性回归
1.图 2 中显示线性模型的图形显示在左侧。它表明,对于 X 的每个值,响应 y 近似正态分布。右图显示了泊松模型的样子。对于 X 的每个值,响应 y 遵循泊松分布:对于泊松回归,X 的小值与一个分布相关联,该分布与许多小值和仅仅几个较大值显著偏斜。随着 X 的增加,响应的分布开始越来越像正态分布。
2.在线性模型(左)中,每个 X 值处 Y 的变化是相同的。对于泊松回归,随着均值的增加,X 的每个水平上的响应变得更加多变。
3.在线性回归的情况下,每个 X 值的平均响应落在一条线上。在泊松回归的情况下,每个 X 值处 Y 的平均值落在曲线上,而不是直线上。
改编自保罗·罗巴克和朱莉·勒格勒的《 超越多元线性回归
比较模型
在本节中,我们将更深入地了解预测的建模部分,并将泊松模型与线性模型和更强大的随机森林回归进行比较。
设置模型
现在我们已经准备好设置模型了。在本练习中,我使用了新的 tidymodels 包,并使用 30 折交叉验证进行比较:
*library(tidymodels)
library(parsnip)
library(poissonreg)pois_mod <- poisson_reg() %>% set_engine("glm")
lin_mod <- linear_reg() %>% set_engine("lm")
rf_mod <- rand_forest(trees=100) %>%
set_engine("randomForest") %>%
set_mode("regression")folds <- vfold_cv(data, v = 30)*
如上所述,我们将训练两个模型,每个模型有一个预测变量(参赛球队的 FIFA 排名差异)。一个模型被训练用于预测主队的得分,一个被训练用于预测客场队的得分:
*home_score_formula <- formula(“home_score ~ ranking_diff”)
away_score_formula <- formula(“away_score ~ ranking_diff”)*
以下是泊松回归的示例代码:
*#poisson model workflow set up for predicting home scores
pois_mod_hs_wf <-
workflow() %>%
add_model(pois_mod) %>%
add_formula(home_score_formula)#perform cross validation
pois_mod_hs_rs <-
pois_mod_hs_wf %>%
fit_resamples(folds)
...#collect cv scores
collect_metrics(pois_mod_hs_rs)
collect_metrics(lin_mod_hs_rs)
collect_metrics(rf_mod_hs_rs)*
交叉验证结果
交叉验证的结果很有趣,并且表明(通过比较均方根误差(RMSE))随机森林回归优于线性回归和所讨论的泊松回归!!
*CV-RMSE Poisson Regression 1.30
CV-RMSE Linear Regression 1.34
CV-RMSE Random Forest Regression 1.17*
视觉比较模型
但是,等等,RMSE 真的是比较这些模型的最佳标准吗?在这个交叉验证的线程中,有一个关于如何为泊松回归选择性能指标的很好很长的答案,它将更详细地阐述这个主题。由于这有点过于详细,我决定在散点图中目测模型,并检查模型的所谓“外观和感觉”:****

图 3: 模型对比:线性回归(绿色)、泊松回归(红色)、随机森林回归(蓝色)——图片作者
从视觉上观察模型时,我们可以看到线性模型(绿色)明显不符合数据,根本无法捕捉曲率。然而,随机森林模型(蓝色)显示了一条忙乱的之字形线,它过度拟合了我们的数据,可能不会对新数据进行很好的概括。最后,泊松模型(红色)似乎以非常令人满意的方式捕捉到了数据的趋势和曲率!因此,“外观和感觉”清楚地表明:“使用泊松模型!”。

在 Unsplash 上混沌足球齿轮拍摄
从估计目标到预测结果(赢、输、平)
让我们回顾一下我们所拥有的:两个预测主客场球队目标的回归模型。
但是我们实际上如何“预测”哪一队赢得了决斗呢?
我们不能简单地比较主客场球队的进球,把胜者定为数字较高的球队。为什么?因为由于我们的预测是浮点数,我们基本上不会以预测平局结束:想象一下,A 队的目标预测是 1.1,B 队的目标预测是 1.09。用上面描述的这个简单方法,我们将把 A 队指定为获胜者,即使两个队有非常相似的预测!
1.最简单的方法——比较每场比赛的预测目标
最简单的方法是简单地将分数四舍五入到最接近的整数值,然后比较这些整数。在 R 中,这可以如下进行:
*pred_result <- rep(0, length(nrow(data)))#home_score_pred contains the poisson home goal predictions for each match
#away_score_pred contains the poisson away goal predictions for each match#assign home team win 0
pred_result[round(home_score_pred) > round(away_score_pred)] <- 0 #assign away team win 1
pred_result[round(home_score_pred) < round(away_score_pred)] <- 1#assign draw 2
pred_result[round(home_score_pred) == round(away_score_pred)] <- 2*
如果我们考虑上面的例子,用这种方法,A 队(1.1)和 B 队(1.09)都将被分配 1 个进球,因此这场比赛将被归类为平局,这似乎更合理。
下面是通过使用这种简单的舍入和比较方法得出的训练数据的混淆矩阵:

图 4: 比赛结果(主队获胜、客场获胜、平局)的混淆矩阵,用于比较全面的预测比赛分数——图片由作者提供
我们可以在图 4 中看到,主队获胜的预测相当不错:217 (167+9+41)中有 167 被正确预测。预测客队获胜的准确性仍然相当好,然而我们的模型结合我们的舍入方法似乎真的很难正确预测平局。
总的来说,训练集上的准确度为 65% ,加权 F-1 分数为 67%* 。***
2.关于如何更好地分类匹配结果的更复杂的方法
从上面我们可以看到,对预测的团队分数进行舍入,然后简单地进行比较,可以得到 65%的准确率。但是用不同的方法有可能得到更好的结果吗?让我们看另一个例子:
假设 A 队的预测目标是 1.49,B 队的预测目标是 1.51。在上面的舍入示例中,团队 A 的分数将被舍入为 1,团队 B 的分数将被舍入为 2,因此团队 B 将被宣布为获胜者。但是在这种情况下预测平局不是更好吗,因为两个队的目标预测都非常接近?嗯,是的!但是,我们如何为目标预测之间的差异选择正确的阈值,以便一个团队可以被宣布为赢家或输家?
因此,游戏结果的分类(赢、输、平)变为如下:
*predicted_result <- rep(NA, length(pois_hs_res))#home_score_pred contains the poisson home goal predictions for each match
#away_score_pred contains the poisson away goal predictions for each match#assign home team win 0
predicted_result[home_score_pred > away_score_pred+diff] <- 0#assign home away win 1
predicted_result[home_score_pred < awy_score_pred-diff] <- 1#assign draw 2
predicted_result[!(home_score_pred > away_score_pred+diff) & !(home_score_pred < away_score_pred-diff)] <- 2*
因此,本质上,我们正在寻找一种方法,如何最大限度地提高基于进球差异阈值的比赛结果分类的准确性:
一旦我们选择了一个指标,比如说“加权 F1 得分”或“准确性”,我们可以简单地对一系列净胜球阈值运行上面的结果分配,看看哪个阈值产生最好的 F1 得分。让我们做吧!

图 5: 一组净胜球阈值的比赛结果分类(赢、输、平)的加权 F1 分数。—作者图片
上面的图 5 显示了我们的比赛分类(赢、输、平)的 F1 分数根据我们选择的差异阈值而变化很大。最初,F1 分数开始增加到几乎 70%,差异阈值为 0.41。之后,F1 分数开始再次稳定下降,并在图表右侧达到最小值。
从上图中选择检测到的“最佳”差异阈值后,我们运行上面的游戏结果分配,并获得以下混淆矩阵和准确度:

图 6: 带有自定义差异阈值的比赛结果(主队获胜、客场获胜、平局)的混淆矩阵—图片由作者提供
我们可以看到,与之前的方法相比,主队获胜和客场获胜的预测都增加了!不幸的是,我们的方法仍然难以正确检测和局。一个潜在的改进是使用另一个单独的差异阈值来分配和局。然而,这将使文章比现在更长:)
总的来说,准确率和 F1 得分都从大约 65%跃升到现在的 69%!**
预测 2020 年欧锦赛
受够了无聊的数据争论和建模!让我们最后使用我们的方法来预测 2020 年欧锦赛小组赛的第一场比赛的结果:

你可以看到,通过这个简单的方法,我们在测试集上达到了 72% 的准确率和 71%* 的加权 F1 得分。18 场比赛中有 13 场预测正确!大多数决斗都预测正确,老实说,谁能想到丹麦会在本届锦标赛中表现如此出色,而西班牙只会与瑞典打成平局?😃***
请注意以下几点:主客场球队对进球的依赖只有在比赛场地是而不是* 中立时才有意义。然而,在欧洲锦标赛期间,大多数比赛场地都是中立的,因此,通过一个不考虑主客场球队的单一模型来预测两支球队的结果会更合适。***
摘要
这是一个关于如何通过简单的泊松回归预测足球比分和结果的详细演练,只使用一个预测变量(国际足联在参赛球队之间的排名差异)。总的来说,我们达到了 72%的准确率。但是,还有很大的提升空间!例如,我们可以使用更多的特征作为模型的输入,例如在最近几场比赛中每支球队的进球数作为最新表现的指标!
如果你有兴趣阅读更多关于这个话题的内容,或者想让你的朋友对即将到来的游戏印象深刻,请给我写一篇评论!😃
如果你对完整代码感兴趣,请访问我的 GitHub 。

照片由桑德罗·舒赫在 Unsplash 上拍摄
用神经网络和 Keras 预测混合目标
原文:https://towardsdatascience.com/predicting-mixed-targets-with-neural-networks-and-keras-1dc754ce0c98?source=collection_archive---------16-----------------------
训练神经网络同时预测两个不同的目标。

桑哈迪普酒吧招待在 Unsplash 上拍摄的照片
使用节点网络,您可以训练考虑多个目标甚至不同类型目标的模型。当我第一次在实际项目中尝试时,我认为这太棒了,它打开了我对神经网络所能做的事情的认识。在本文中,我将讨论如何训练一个神经网络来同时预测两个不同的目标。如果你是一名数据科学家或机器学习工程师,那么你应该考虑神经网络,因为它们提供了其他开箱即用的 ML 算法所不具备的大量能力和灵活性。
多目标训练和预测
如果使用相同的特征对多个目标进行预测,则可以使用相同的特征对这些目标训练网络。数据集中的某些要素可能更适合其中一个目标,而不适合另一个目标。如果您愿意,还可以将模型架构设置为适应两个不同的训练数据集,但这里我们将两个特征集连接在一起。我这样做是为了让我们可以在单个训练数据集上看到改变损失权重对模型性能的影响。
下面是使用 Keras 模型 API 定义网络的代码。请注意,模型中有两个输出层和两个输出:一个用于回归,一个用于分类。在这个问题中,我们希望同时预测这两个目标。
作者图片
参见性能使用损失权重部分的代码要点,了解模型训练的语法。
模型架构
对于这个例子,层的实际网络只有两个深度且密集连接。通常,使用单个输出层,并且根据目标类型,选择单个激活类型。这里使用了回归和分类目标,因此使用了两个输出图层:

作者图片:具有两个输出层的神经网络的模型架构,一个用于回归目标,一个用于分类目标
对于回归 _ 输出层,具有线性激活的单个节点,对于分类 _ 输出层,我们只需要具有 sigmoid 层的单个节点。这确保了来自模型的预测与它们想要预测的目标类型相匹配。
网络预测
在左侧,显示了来自回归输出的测试数据集预测与实际测试数据集值的对比。在右侧,显示了来自分类 _ 输出的测试数据集概率预测与测试数据集中的实际类的对比。

作者提供的图像:对模型同时在两个目标上生成的预测的描述
两者都可以从训练好的模型的预测方法中获得。请参考 Keras 文档或查看文章底部的链接,以查看 github 上的完整笔记本。基本上,predict 方法将返回每个目标的预测列表,在这种情况下,将有两个预测列表。
使用不同损失权重的性能
除了训练一个模型来预测多个目标之外,我们还可以选择我们想要从哪个目标学习更多。我这样说的意思是,我们可以给目标指定权重,以指定哪个更重要(如果是这样的话)。
根据 Keras 文档中关于此参数的信息:
loss_weights :指定标量系数(Python floats)的可选列表或字典,用于对不同模型输出的损失贡献进行加权。由模型最小化的损失值将是所有单个损失的加权和,由
***loss_weights***系数加权。如果是一个列表,它应该与模型的输出有 1:1 的映射。如果是 dict,它应该将输出名称(字符串)映射到标量系数。
这里的要点是,我们可以通过增加 loss_weights 参数中的权重来增加其中一个输出层对模型损耗的贡献。在下面的代码片段中,我在每个训练循环中选择不同的 loss_weights 参数。我们将看到改变这个参数是如何影响性能的。
作者图片
精度&召回性能

作者图片
从左到右,与每个目标的损失相关联的权重被改变。例如,第一个值[1,100]会将分类损失度量(最像对数损失,但标记为二进制交叉熵)加权为回归损失度量(均方误差)的 100 倍。这里的意图是通过在分类度量上制造更多的错误来惩罚模型,并且有希望为分类目标返回更好的预测模型。
请注意,在更改损失权重以支持分类而非回归之后,测试数据集的性能会发生怎样的变化,反之亦然。
R 平方性能

作者图片
类似地,对于回归性能,当回归的权重大于分类损失度量时,存在性能增加的一般趋势。回归目标已经由特性集(基本上是一个函数关系)很好地定义了,所以性能接近完美,但是思想仍然是相同的。
结论
使用节点网络,您可以训练考虑多个目标甚至不同类型目标的模型。还可以衡量哪个目标的损失对整体模型损失的贡献更大,这是一种说明哪个目标需要更多学习的方式。与神经网络一样,您可以通过定义模型架构做更多的事情。虽然我们在这个示例中使用了单个输入层和多个目标,但是也可以使用单独的输入层和单独的输出层来定义模型。如果你是一名数据科学家或机器学习工程师,那么你应该关注神经网络,因为它们提供了其他 ML 算法所不具备的大量能力和灵活性。
参考
https://github.com/caseywhorton/medium-blog-code https://keras.io/api/models/model_training_apis/
利用波形特征预测音乐类型
原文:https://towardsdatascience.com/predicting-music-genres-using-waveform-features-5080e788eb64?source=collection_archive---------29-----------------------
什么样的节拍让你想动起来?那种光谱质心呢?
我们能利用从音乐波形中提取的特征来预测音乐类型吗?为了回答这个问题,我使用了我在 Kaggle 上找到的这个数据集。目标是使用数据集中呈现的量化特征对音乐进行分类,如节拍、频谱重心、以及歌曲的其他数学分层。所以,事不宜迟,让我们完成这个项目吧!
资料组
数据集由从 1000 首每首 30 秒的音轨中提取的波形特征组成,根据它们所属的音乐流派进行标记,共有 10 个不同的类别:布鲁斯,古典,乡村,迪斯科,嘻哈,爵士,金属,流行,雷鬼
通过使用音乐信息检索技术,利用 libROSA 库提取特征集。这个数据集的功劳归于 MARSYAS 。
取得的成果
最佳模型能够在从数据集获取的看不见的数据上实现 68.5%的精确度。考虑到样本数量少而类别数量多(每个音乐流派只有 100 个样本),这可以被认为是一个好的结果。
要求和设置
要复制这个项目,您需要下载这个 GitHub repo 中的文件,并运行 jupyter notebook (如果您想检查它,它包含所有代码),但不是在安装所需的包之前(建议创建一个新的虚拟环境,以避免依赖冲突)。因为我通常同时在 Linux 和 Windows 上开发我的项目,你可以选择哪一个最适合你。如果您使用的是 Linux,请打开终端并键入:
pip install -r requirements-linux.txt
或者,如果您喜欢 Windows,请使用:
pip install -r requirements-windows.txt
特征探索和工程
数据集分为训练集和测试集,因此我们可以在以后对训练过程中未使用的数据进行预测。所有的数据探索都将使用训练数据来完成,因为我们将测试集保持为不可见数据。
现在,我们将进一步了解数据集的特征。总共有 8 个不同的数字特征,加上编号从 1 到 20 的梅尔频率倒谱系数。我们将首先探索前 8 个特征,然后分析 MFCC 系数。
功能的分布如下所示:

作者图片
正如我们从上面的图中看到的,这些特征以一种相当正常的方式分布,有一些小的偏差;为了让我们的一些模型更容易消化数据,标准化过程将受到欢迎。现在,让我们看看我们的特征之间的相关性:

作者图片
这可以让我们对我们的一些专栏有一些有趣的了解;spectral_bandwidth、rolloff、zero_crossing_rate均与spectral_centroid高度相关,beats与tempo高度相关。因此,我们将只在数据集中保留tempo、chroma_stft、rmse和spectral_centroid,将此步骤中的特征数量从 8 个减少到 4 个。
现在,我们将研究我们将要使用的功能。为此,我们将绘制不同目标类的核密度估计,并给出每个特性的简要描述。值得注意的是,图中的纵轴代表所绘制变量的密度;这意味着规模将受到每个变量范围的影响。
拍子
tempo功能告诉我们一首歌的节奏。该值越高,歌曲播放速度越快。

作者图片
chroma_stft
chroma_stft特征代表每首歌曲的短时傅立叶变换。然而,该特征被减少为单个值,并且数据集不包括对它所表示的内容的解释(完整的傅立叶变换对于每个频率将具有单个值,表示该频率对歌曲整体的贡献)。给定数据集中存在的值的范围,我们可以假设它们对应于每首歌曲中主导频率的比例。

作者图片
均方根误差(root-mean-square error)
rmse代表均方根能量,代表给定信号的总能量。

作者图片
spectral_centroid
spectral_centroid 属性表示对应于信号质心的频率。

作者图片
上面的图表向我们展示了所有特征在不同目标类别中的分布有显著差异;因此,它们将有助于我们建立预测音乐流派的模型。
MFCC 系数
MFCCs 代表梅尔频率倒谱系数,共同组成 MFC(梅尔频率倒谱)。在我们的数据集中有 20 个 MFCC 氏症。
在检查了一维特征之后,我们现在可以通过验证它们如何相互关联来类似地分析 MFCC 系数。

作者图片
通过观察上面的图,我们可以看到奇数和偶数系数组的高相关性,不包括第一和第二 MFCC 系数。为了降低该特征的维数,我们将应用 PCA 方法来减少奇数和偶数 MFCC 的数量。通过分解两组奇数和偶数索引,我们可以看到有多少冗余信息;为了测量这一点,我们将使用由 PCA 变换产生的每个分量的解释方差:
Explained variance (on tranining set) of reduced odd MFCC's: [0.68552199 0.1823339
0.04741692 0.02504977 0.01711308 0.01659338 0.01124799 0.00869031 0.00603266]Explained variance (on tranining set) of reduced even MFCC's: [0.71564189 0.13864236
0.05718861 0.02319806 0.01853898 0.0147636 0.01390881 0.00991512 0.00820257]
根据上述结果,我们可以得出结论,在奇数和偶数系数组中发现的大多数信息(大约 97%)可以在前 3 个分量中合成;但是,我们将保留每组中的 7 个组件,将维度总数从 18 个减少到 14 个,以便保留特征中 99%的信息。
下一步是标准化数据集的列,这样它们可以更容易地被我们的一些模型消化。在这之后,我们终于准备好开始训练一些模型。
模型训练和优化
我们将使用默认参数化来训练一些机器学习模型,在 5 重交叉验证方法中根据它们在验证折叠中的平均准确度来对模型评分。朴素贝叶斯模型将被用作我们的基线。一旦我们完成了这些,最好的模型将被挑选出来并进行微调,这样我们就能达到最好的结果。以下是各型号达到的精度:

作者图片
在上面显示的模型中,我们将只选择 4 个模型进行进一步调整:取得最佳结果的随机森林、支持向量、梯度提升和神经网络。策略是首先使用RandomizedSeacrhCV函数对参数进行广泛的随机搜索,然后使用GridSearchCV函数对最佳超参数进行更窄的搜索。这一过程的结果如下所示:

作者图片
根据上述结果,超参数调整后达到最高准确度的模型是支持向量分类器,它将被选为我们问题的最佳模型。我们最终可以使用我们的测试集来验证它对音乐流派的预测有多好。在我们的测试集上对模型进行评分后,分类器获得了 68.5% 的分数。
最终结论
尽管最好的评分模型实现了低于 70%的准确性,但仍然值得注意的是,这样一个每类只有 100 个样本并且总共有 10 个不同类的小数据集(仅包含波形信息)足以允许分类模型在超过 65%的时间内正确预测音乐流派。也许如果我们有更多的样本或者更多的特征,我们可以获得更好的结果。
预测网络新闻流行度(上)
原文:https://towardsdatascience.com/predicting-online-news-popularity-part-1-aae9a4f7f1a4?source=collection_archive---------22-----------------------
《纽约时报》16K 篇文章的探索性数据分析

斯蒂芬·瓦伦丁在 Unsplash 上拍摄的照片
介绍
新闻机构越来越依赖媒体分析来吸引和留住读者。由于新冠肺炎和其他疫情危机前的趋势,今年的广告收入大幅下降,这一点变得尤其真实。
对于媒体公司来说,知道哪些新闻文章能引起读者的共鸣,哪些文章不能,变得至关重要。考虑到这一点,我想找出是什么让一篇新闻文章受欢迎或不受欢迎。我决定看看《纽约时报》的在线新闻文章,并根据包括字数和标题摘要长度在内的各种特征来预测新闻受欢迎程度。
在这篇文章中,我将主要关注探索性数据分析,在这里我将挑选出趋势和模式,同时找出可能是机器学习模型最重要的预测因素。
数据
对于这个项目,我访问了纽约时报 API,并检索了 2020 年 1 月 1 日至 12 月 31 日之间的文章和评论的元数据。你可以按照这里的的步骤来获得关于如何做到这一点的教程。
总的来说,我设法获得了超过 16,000 篇具有 11 个特征的文章,以及近 5,000,000 条具有 23 个特征的评论。我已经在 Kaggle 上上传了完整的数据集,供任何想尝试的人使用。
让我们看看我们的目标变量:

评论在所有文章中的分布
我们的评论在我们的文章中分布很不均匀。特别是我们 50%的文章评论都不到 90 条。在这里,你可以把它作为一个回归项目或者一个分类项目来进行。

对于我的项目,我创建了一个二进制分类变量,其中我选择将评论超过 90 条的文章分类为受欢迎,将评论少于 90 条的文章分类为不受欢迎。正如你所看到的,我们的数据在积极类和消极类之间几乎平分秋色。
探索性数据分析
那么文章人气最重要的因素是什么呢?让我们找出答案。
字数
你可能会直觉地猜到,文章受欢迎程度的最重要的预测指标之一是字数,它实际上与我们的目标类别有相当大的正相关性。这里唯一的问题是,我们的字数统计变量是相当倾斜的。
一般来说,当变量的分布为正态时,机器学习算法往往表现更好——换句话说,对于具有标准分布的变量,性能往往会提高。下面,我尝试了各种变换方法,试图实现一个正态分布。

你会注意到一组文章的字数为 0。这些是不含文字的互动文章。这个数据并不完全是“随机缺失”(MAR),所以我决定不在这里进行任何类型的插补。
为了证明评论数量和字数之间的正相关关系,我做了一个散点图,比较了前五名报纸的字数和评论数量。

有趣的是,新闻专栏文章的字数与每篇文章的评论数没有正相关关系。
新闻部
以下是我的数据集中最大的新闻栏目。这些新闻服务台代表了我的数据集的 50%以上。不出所料,专栏新闻部的文章平均受欢迎程度最高,其次是外国和商业新闻部。2017 年,NYT 实施了新评论系统,24 小时开放专栏文章和其他精选新闻文章。这可能是为什么专栏文章似乎吸引了更高频率的评论的部分原因。

标题和摘要长度
文章标题和摘要的长度也与受欢迎程度有一定关系。下面,你可以看到有点 U 型分布。标题和摘要不太罗嗦的文章往往比标题和摘要更罗嗦的文章更受欢迎。

然而,也有一点相反的趋势,标题和摘要很长的文章往往表现良好。我们看到,在极端的上端和下端,文章的受欢迎程度是相当不可预测的,往往波动很大。
材料类型
我们可以看到社论和专栏文章往往做得非常好。新闻分析和互动功能往往更受欢迎,而常规新闻往往不太受欢迎。评论、讣告和新闻简报通常做得不好。

星期几
事实证明,周末发表的文章实际上做得更好——我们可以推断,这是因为一天发表的文章数量与平均受欢迎程度成反比。换句话说,文章往往在周末表现更好,因为文章之间的“竞争”更少。

一天中的时间
最后,一天中的时间也对受欢迎程度有影响。与白天发表的文章相比,晚上发表的文章似乎更容易受欢迎——除了上午 9 点。

关键词/主题
任何人都不会对此感到惊讶,但是某些主题比其他主题做得更好。使用我们的文章关键字作为我们文章中主题的代理,我们可以比较不同时期主题的受欢迎程度。

我先从房间里的(橙色)大象说起——自 2016 年以来,唐纳德·特朗普一直是《纽约时报》的热门话题。这在 2020 年没有什么不同,尽管我们可以看到新闻周期在 10 月份达到高潮,并随着总统选举的失败而在 12 月份开始略有下降。
从每月热门文章的频率来看,我们可以清楚地看到,新冠肺炎新闻在 4 月份达到了顶峰,然后在年底逐渐减少。
随着乔治·弗洛伊德在五月和六月的抗议,种族和民族成为今年的热门话题。

如果我们再深入一点,看看平均受欢迎程度,就会发现不同主题之间的受欢迎程度形成了鲜明的对比。约 80%提到唐纳德·特朗普的文章很受欢迎,而只有约 30%提到房地产的文章很受欢迎。
结论
这里有几个值得关注的关键趋势:
- 较长的文章总体上会更好(除了专栏文章)
- 来自专栏、政治、游戏和华盛顿新闻台的文章可能受欢迎,而来自体育、文化和播客新闻台的文章可能不受欢迎。
- 标题和摘要较短(50-130 字)的文章更有可能受欢迎。
- 新闻分析和互动文章往往比讣告和常规新闻报道更受欢迎。
- 发表的日期和时间会影响文章的受欢迎程度——文章在周末或晚上 11 点到凌晨 2 点之间发表似乎更好。
- 某些主题在全年的表现都比其他主题好得多(例如唐纳德·特朗普),而其他主题只在一年中的特定时间表现良好。
感谢阅读!
这就是这篇文章的全部内容——希望你喜欢!稍后我可能会再发一篇关于特征工程和建模的文章,但是如果你有兴趣看这个项目的源代码,你可以在这里找到它。你也可以在我的网站上找到一篇更具技术性的文章。
也可以在 LinkedIn 上与我联系。
Airbnb 房源的最优定价
原文:https://towardsdatascience.com/predicting-optimum-airbnb-listing-prices-in-singapore-8a00839c5aa8?source=collection_archive---------30-----------------------
利用 XGBoost 和 SHAP 预测 Airbnb 在新加坡的最优挂牌价格

丽塔·塞尔玛在 Unsplash 上的照片
1.介绍
Airbnb 房东应该如何给自己的房产定价实现利润最大化?他们是应该给房产 定价过高 以试图以牺牲销售额为代价获得更高的利润率,还是应该更有竞争力以产生更多的销售额?许多 Airbnb 房东都在纠结这个定价问题:他们不知道自己是否通过次优定价削减了潜在利润。
这个项目的目标是使用人工智能模型提出最优价格,同时清晰地解释这些价格的推导,以便主机在做出各种定价决策时更加客观。
2.数据
2.1 获取数据
Airbnb 已经开源了它的数据,但是 Airbnb 内部的进行了进一步的清理和聚合。我们将在 Airbnb 内部仅使用新加坡数据集。
对于任何一个不同的日期,都有多个文件可供下载。由于可用的日期彼此之间似乎没有一致的模式(上传/处理可能是 Airbnb 或 Airbnb 内部的手动过程),我们可以整理日期列表,并尝试使用 Colab 迭代下载每个文件。
首先,将所有可用的日期存储到一个列表中:
*# All archive dates for Singapore
date_archive = ["2020-10-26", "2020-06-22", "2020-05-27", "2020-04-26", "2020-03-21", "2020-02-27", "2020-01-26", "2019-12-28", "2019-11-26",
"2019-10-25", "2019-09-25", "2019-08-28", "2019-07-21", "2019-06-25", "2019-05-23", "2019-04-20", "2019-03-18"]*
其次,由于每个文件的 URL 都是通过日期来区分的,所以我们可以使用 list comprehension 来创建下载 URL 的列表:
*# Download URL List
listingUrl = ["<http://data.insideairbnb.com/singapore/sg/singapore/{}/visualisations/listings.csv>".format(i) for i in date_archive]*
由于我们不能简单地在 Python 的“for-loop”中使用终端命令!wget,我们可以在中存储之前的链接列表。txt* 文件,然后使用!wget -i下载所有可用文件。*
*# Write to .txt file
with open('listingUrl.txt', 'w') as f:
for item in listingUrl:
f.write("%s\\n" % item)# Download all dataset from txt file
! wget -i /content/listingUrl.txt*
最后,我们可以将所有单独的文件连接成一个主文件,并反复清理子文件。
*# Concat all available files
df_listing_summary = pd.concat([pd.read_csv("/content/listings.csv.{}".format(i)) for i in range(1, 17)])
df_listing_summary = df_listing_summary.drop_duplicates()# Delete sub-parts after merging
for i in range(1, 18):
os.remove("/content/listings.csv.{}".format(i))*
2.2 列表和审查数据
列表数据集包含关于房东准备出租的每处房产的信息。因此,属性在列表数据集中是唯一的。我们可以通过获得 Airbnb 内部可用的另一个评论维度来进一步扩展数据集。
由于每个属性可以有多个评论(1:M 关系),属性数据集应该左连接到“listing_id”上的评论,以形成最终的数据集。
*df = df_listing.merge(df_review, how = 'left', on = 'listing_id')*
3.电子设计自动化(Electronic Design Automation)
3.1 房间类型

作者图片|点评和列表的房间类型条形图
我们可以明显地看到,评论和列表在每个给定的级别上都有几乎相同的分布。从每个 y 轴的刻度可以看出,评论大约比列表多 10 倍。新加坡的 Airbnb 房东倾向于提供整个家庭或私人房间,而不是合租房间。相反,这可能是一个需求问题,因为 Airbnb 的客人会做短暂的临时住宿,而合租房间通常意味着长期住宿(愿意牺牲隐私以降低成本)。
3.2 邻里和邻里团体
中部地区似乎严重过剩。

图片由作者提供|邻里小组评论和列表的条形图
提供更精细地理位置点的类似属性显示,大多数 Airbnb 主机来自少数邻居,这可能在中心区域。

作者图片|邻居评论和列表的条形图
**纬度和经度属性进一步精确定位每个列表的位置。使用folium的列表频率热图证实了一个事实,即大多数列表都聚集在中心区域,其余区域看起来相对较暗。

作者图片|列表频率热图
3.4 价格
价格是这个项目的目标变量 y,绘图有助于我们理解它的潜在价值。

图片由作者提供|价格的方框图
箱线图可用于识别数值/连续变量的分布,以及异常值的出现。‘点’代表价格高于四分位数 3 (Q3)加 1.5 倍四分位数(IQR)范围的情况,其中 IQR 是 Q3-Q1。

作者图片|异常值(点)
许多这些“点“”似乎紧密聚集在箱线图附近的 2,000 美元以下,但也有许多情况超出了似乎均匀分布在 2,000 美元和 4,000 美元之间的范围。也存在超过 4000 美元甚至高达 10000 美元的极端异常值。
由于我们的人工智能模型将预测这一变量,这些有影响的离群值将对我们的模型概括为“正常”情景的能力产生负面影响。因此,从现在开始,我选择只过滤价格在 2,000 美元及以下的实例。

图片由作者提供|价格低于 2000 美元的过滤数据集的箱线图
3.5 名称、注释
名称和注释属性都是自由格式的文本。名字是主人提供的物业名称,而评论是住在里面的客人留下的。
对两个色谱柱执行以下清洗方法:
*df_listing_summary["name"] = df_listing_summary["name"].str.lower() # Lower case
df_listing_summary["name"] = df_listing_summary["name"].str.replace('nan', ' ') # Remove punctuations
df_listing_summary["name"] = df_listing_summary["name"].str.replace('[^\\w\\s]', ' ') # Remove punctuations
df_listing_summary["name"] = df_listing_summary["name"].str.replace('\\n', '') # Remove line break
df_listing_summary["name"] = df_listing_summary["name"].str.replace("([^\\x00-\\x7F])+", ' ') # Remove symbols + chinese characters
df_listing_summary["name"] = df_listing_summary["name"].str.replace("[\\u4e00-\\u9fff]+", ' ')
df_listing_summary["name"].str.encode('ascii', 'ignore').str.decode('ascii') # Retain ascii characters, removing foreign characters and emojis
df_listing_summary["name"] = df_listing_summary["name"].dropna().apply(lambda x: ' '.join(x.split())) # Replace multiple whitespaces with 1 whitespace*
此后,我们可以绘制频繁出现的单词云。

图片由作者|字云供评论
- 似乎有更多积极情绪的表征,如“棒极了”、“爱”、“方便”等。
- 然而,很难确定每个评论的实际上下文,因为它可能带有否定标记,如“不”,如“不太好”,“不爱”,“不方便”
3.5 其他变量
帕累托分布或普赖斯定律都有类似的想法,即 80%的结果是由 20%的原因造成的或 50%的工作是由员工人数的平方根完成的。这在大多数情况下都很普遍,因为这种现象在多个变量中都能观察到:

按作者分类的图片|每个唯一 host_id 的评论和列表的前 1000 个频率
例如,我们可以看到前几个主机的一小部分收到了大部分的总评论,并列出了 Airbnb 新加坡的大部分可用房产。
3.6 相关性
相关性是一种简单的统计度量,它表明两个随机变量之间的线性关系的程度。检查变量之间的相关性总是很方便的。

图片由作者提供|数值变量之间的相关矩阵
仔细观察第一行,我们可以看到所有连续变量与目标变量 price 的相关性可以忽略不计。
4.特征工程
凭借一些创造力和领域知识,我们可以尝试创建变量来帮助我们解释可变价格。
4.1 捷运
大众捷运(MRT)和轻轨捷运(LRT)构成了新加坡的公共列车系统。我经常乘火车上下班,因为它又快又方便(不是 SMRT 的付费广告)🚆).
我相信大多数新加坡人和游客都同意我的观点。只要有可能,房地产开发商就会做广告,说他们的房产离火车站只有几步之遥。有鉴于此,可以合理地推断,在所有其他变量保持不变的情况下,火车站附近的房源可以获得高于平均水平的价格。
通过最少的搜索,可以找到新加坡火车站纬度和经度坐标的公开可用的数据集。

图片作者|新加坡的捷运和 LRT
根据勾股定理,我们可以用以下公式计算两个坐标之间的位移:

图片由作者|用勾股定理置换
此后,利用所有站点中的最小位移,我们可以设计最接近列表 nearestMRT 和位移值 mrtDisp 的 MRT 变量。
例如,我们可以通过位移检查与最近 MRT 匹配的第一个列表的。

图片由作者提供|第一个与其最近的 MRT 列表
- 计算所有捷运站之间的第一个列表(红圈)位移
- 最小位移捷运是林地捷运(蓝圈)
我们还可以为最近的前 10 个火车站绘制列表。

作者图片|最近的 10 个火车站
4.2 公共假日
度假、酒店和其他住宿的需求和价格在高峰期或临近假期时可能会更高。同样,Airbnb 的挂牌价格在公共假日期间飙升也是合乎逻辑的。相反,如果房产长期空置,离公共假日较远的日期可能会打折出售。
由于没有可用的停留日期,我们可以使用 review_date 作为客人到达日期的下一个最佳代理。有了这个,我们可以设计离最近的公共假日 holidayDateDiff 和各自的假日 holidayName 的天数。

图片由作者提供|临近审查日期的最佳假期
4.3 评论情绪
如前所述,名称和注释是自由格式的文本列,在某些情况下,这些值并不完全是英文的。例如,我们可以用下面的 RegEx 表达式查找包含一个或多个中文字符的行:'[\\u4e00-\\u9fff]+。清单名称的一些示例如下:

图片由作者提供|包含中文字符的名称示例
为了实现标准化,Python 中的 googletrans 包允许通过自动语言检测和无限制的 Google Translate 翻译将这些行翻译成英语。已经对名称和注释进行了翻译。
nltk (自然语言工具包)是 Python 中的一个常用包,用于获取任何给定英语文本的正面、负面和复合(组合)的数字情感值。例如,以下文本具有:

作者图片|使用 NLTK 的情感值
已经应用了以下方法,并且已经计算了所有列表评论的平均情感值。从所有列表的所有评论的情感的方框图中,我们可以看到,考虑到 IQR 值高于 0,大多数评论通常是正面的。

图片由作者提供|所有列表的评论意见方框图
4.4 使用正则表达式的其他变量
我们还没有完成对名字和评论的‘榨汁’。由于它们是自由形式的文本列,即使在解析其情感值以创建进一步的可训练列之后,仍然可以使用 RegEx 提取有价值的信息。
- 派克斯
使用的表达式是 (\d+) paxes 或 (\d+) people ,它匹配关键字“paxes”或“people”前的一个或多个数字。例如:
- 卧室数量
使用了【T2(\ d+)床、(\d+) bd、或【T4(\ d+)卧室的表达,其中它匹配其各自关键字之前的一个或多个数字。
- 属性类型
主机通常在其列表名称中显式地写入属性的类型。例如,尝试匹配属性类型:

作者提供的图片|捕获的属性类型的值计数
- 女性偏好
通过人工目测,我注意到了几个带有“女性”关键字的值。这可能是主机的偏好和要求。因此,可以对关键字女性进行不区分大小写的搜索,在 14000 个列表中只找到 80 个。
5.特征选择
在特征工程之后和建模之前,我们应该执行特征选择,以去除可能对解释输出变量价格的唯一原因无用的变量。这样做的一个健壮方法是使用SelectFromModel方法,通过使用一个树集合方法(如极度随机化(额外)树)找到变量重要性。
以下是根据ExtraTreesRegressor确定的变量重要性列出的前 10 个变量。
*Index(['minimum_nights', 'number_of_reviews', 'reviews_per_month',
'calculated_host_listings_count', 'availability_365', 'mrtDisp',
'roomPax', 'amtBedroom', 'commentsSentiment', 'room_type_Private room'],
dtype='object')*
6.模型
这一部分是整个项目的关键。

凯文·Ku 在 Unsplash 上拍摄的照片
我将跳过讨论神经网络,因为它是在 Colab 中作为这个项目的反面例子完成的。关键点是神经网络通常被称为“黑箱”,无法完全解释其预测结果。例如,我们可以告诉一个申请贷款的人,他被我们的神经网络模型任意拒绝,但我们无法解释和告诉他/她最终决定的原因。在这种情况下,这种方法将与我们的项目无关,因为我们希望我们的最终结果对 Airbnb 主机具有高度的可解释性和可解释性,这样他们也可以在最终定价决策中得到通知。然而,人工神经网络的代码仍然存在于笔记本中。
同样值得讨论的是训练测试分割 (TTS)策略,因为这个项目相对于其他机器学习项目来说有点独特。最常见的情况是,随机地对数据集执行 TTS(除了时间序列)。然而,在我们的项目中,在用该实例训练相应的模型之前,确定目标可变价格首先是最优是很重要的。因此,执行“盲 TTS”的含义是导出“垃圾入垃圾出”的最终模型。因此,我们需要对我们的训练集进行某种形式的审查和过滤,在那里模型推导出最优定价策略的基本规则。
根据上面的解释,未过滤的数据集应该混合了最优和次优价格。在我们的数据集中,没有任何客观的指标来确定一个与另一个的区别,这是一个障碍。唯一看似可信的变量是上市审查的数量。理由是,假设自由市场是有效的,更高的顾客停留计数将意味着更高的总体需求或参与度,因此最优定价的合理性更高,尽管不知道潜在审查的性质或情绪,因为各方在开始时愿意参与自愿交易。因为审核者的先决条件是成为现有的顾客,所以审核的数量是对要参与的列表的偏好以及最优价格的间接指示。因此,我们应该用评论数最多的 80%数据集来训练我们的模型。
6.1 未调整的模型
机器学习实际上并不像其他非从业者可能认为的那样困难。在实践层面上,你不需要理解一个给定模型背后的每一个复杂的计算细节,并把它编码出来以供使用。此外,当其他人已经可以使用“重新发明轮子”时,这可能不是一个好的编码实践。例如,我可以从 scikit-learn(和 XGBoost)测试出 9 种不同的未调优模型,只需要几行代码:
代码:
*%%time
nameList = []
cvMeanList = []
cvStdList = []
for Model in [LinearRegression, Ridge, Lasso,
DecisionTreeRegressor, RandomForestRegressor, ExtraTreesRegressor,
AdaBoostRegressor, GradientBoostingRegressor, XGBRegressor]:
if Model == XGBRegressor: cv_res = rmse_cv(XGBRegressor(objective='reg:squarederror', eval_metric = 'mae'))
else: cv_res = rmse_cv(Model())
print('{}: {:.5f} +/- {:5f}'.format(Model.__name__, -cv_res.mean(), cv_res.std()))
nameList.append(Model.__name__)
cvMeanList.append(-cv_res.mean())
cvStdList.append(cv_res.std())*
输出:
*LinearRegression: 79.72456 +/- 10.095378
Ridge: 79.75446 +/- 10.114177
Lasso: 81.44520 +/- 8.418724
DecisionTreeRegressor: 103.70623 +/- 13.965223
RandomForestRegressor: 77.86522 +/- 13.281151
ExtraTreesRegressor: 78.39075 +/- 14.291264
AdaBoostRegressor: 120.35514 +/- 23.933491
GradientBoostingRegressor: 76.78751 +/- 11.726186
XGBRegressor: 76.69236 +/- 11.640701
CPU times: user 1min 38s, sys: 614 ms, total: 1min 38s
Wall time: 1min 38s*
在每个模型旁边,第一个数字代表 10 倍交叉验证误差的平均值(平方误差),第二个数字代表交叉验证误差的标准差(平方误差)。
- 我们可以看到,像 DecisionTreeRegressor 和 AdaBoostRegressor 这样的模型都无法超越线性回归的简单基线模型。
- 然而,GradientBoostingRegressor和 XGBRegressor 相对于模型列表具有较低的 CV 误差值。我们可以尝试在我们的解决方案中进一步调整这两种模型
6.2 梯度增强
当目标变量是连续的时,可以使用梯度推进(GB)回归器,当目标变量是分类的时,可以使用 GB 分类器。AdaBoost、GB 和 XGBoost 都使用类似的增强的方法,这提高了模型的性能。一个来自 Analytics Vidhya 的简短解释,一个垃圾邮件检测模型只能识别链接的存在或来自未知来源的电子邮件,这两个模型都是单独的弱模型。然而,通过组合来自训练的两个规则,该模型是最健壮的,并且因此将具有更好的总体概括能力。因此,GB 是多个决策树模型的集合,具有不错的预测结果。
然而,调优一个模型需要反复试验。例如,我可以尝试通过在估计数(n_estimators)的一个假定的大参数空间中测试几个点来找到最小平均绝对误差(MAE)。通过测试 7 个点获得了以下图:
*n_estimators = [5, 25, 50, 100, 250, 500, 1000]*

图片由作者提供|使用 MAE 绘制的 GB n_estimators 图
局部最小值应该接近 220 个 n 估计量。
与神经网络不同,GB 和 XGBoost 都可以高度解释。例如,我们可以知道哪些变量在解释价格预测结果时很重要。一般来说,使用基于树的模型有两种不同的方法来判断特征的重要性:
- 杂质平均减少(MDI)的特征重要性
- 通过决策树的分裂标准(基尼系数、熵或均方误差)来量化杂质。
- 但是,当模型过度拟合时,这种方法可以赋予那些在看不见的数据上可能没有预测性的特征很高的重要性。
2.排列重要性
- 另一方面,基于排列的特征重要性避免了这个问题,因为它可以在看不见的数据上计算。

作者图片|对 GB 模型的可变重要性
由此,我们可以看到房间 _ 类型 _ 私人房间和计算 _ 主机 _ 列表 _ 计数在解释可变价格时始终被排在最前面。
6.3 极限梯度提升
极端梯度推进(XGBoost)是一种相当新的机器学习方法(考虑到神经网络是在 20 世纪 40 年代概念化的,SVM 是由 Vapnik 和 Chervonenkis 在 20 世纪 60 年代引入的),它不仅快速有效,而且是目前性能最好的模型之一。
xgboost是 Colab 中可用于导入的包。此外,XGB 模型还可以利用 Colab 的免费 GPU 进行更高效的调优。
与之前 GB 中的 n_estimators 一样,对学习率的相同参数搜索被应用于 XGB 模型。

图片由作者提供| XG boost 学习率与 MAE 的关系图
虽然搜索 1 个参数可以通过简单的 for 循环轻松完成,但更全面的搜索应该是指定一组参数网格,并使用 GridSearchCV 或randomsearccv。
- GridSearchCV 遍历所有可能组合的乘积(优点:非常彻底的参数搜索,缺点:潜在的非常长的运行时间,例如 5 个超参数对应 5 个参数= 55555=5⁵=3125 模型。
- RandomSearchCV 运行时间由
n_iter决定,可以反过来指定。
在这种情况下,为以下参数网格指定了n_iter=50的 RandomSearchCV:
*param_grid = {
"learning_rate": [0.032, 0.033, 0.034],
"colsample_bytree": [0.6, 0.8, 1.0],
"subsample": [0.6, 0.8, 1.0],
"max_depth": [2, 3, 4],
"n_estimators": [100, 500, 1000, 2000],
"reg_lambda": [1, 1.5, 2],
"gamma": [0, 0.1, 0.3],
}*
7.解释
从前面提到的 TTS 来看,测试集结果不应该是我们关注的焦点,因为我们很可能是在具有最优价格的行上进行训练,因此我们不应该期望它能很好地推广到具有次优价格的测试集。然而,该项目的更重要的目的是解释每个预测结果背后的数值。
我们可以使用 SHapley 附加解释(SHAP)库对 GB 和 XGBoost 模型进行详细的可视化预测。在这种情况下,由于冗余,我将只讨论 XGBoost。将预测'推高'和推低变量分别用红色和蓝色显示。
例如,使用 SHAP 来解释第一行预测值。首先,基础值 135.5 是所有价格值的平均值,在所有情况下都相同。然而,红色的变量增加了预测价格,而唯一的变量 room_type_Private room 减少了,这确定了最终的预测值为 146.52。从这张图表中,我们可以理解为,与私人房间相比,共用房间不能证明比私人房间的价格更高。

图片作者| SHAP 对 XGBoost 预测的首次解释
此外,如果我们将上面的数字逆时针旋转 90 度,其中第一行将位于 X 轴的起点,我们可以将剩余的预测并排堆叠到右侧,并获得下图。我们可以看到,从大约指数 0 到 1600,大多数预测值都在 135 附近徘徊,其中向上和向下的推力是均匀匹配的。此后,有几个变量改变了立场,将预测从 1600 点下调至 2800 点。蓝色变量对最终切片的阻力很小,导致预测值下降。

图片作者| SHAP 对测试集 XGBoost 预测的解释
对于 SHAP 变量的重要性,它不是由 GB 中讨论的杂质值决定的,而是由一个变量在所有预测中的总体解释(或推动)程度决定的。我们可以看到房间 _ 类型 _ 私人房间在预测价格值中一直是最重要的(与 GB MDI 和排列重要性相同),其中 0 或 1 分别向下和向上推动预测。

图片作者| SHAP 测试集上 XGBoost 的变量重要性
如果您对每个变量的推动方向不感兴趣,而是对总体变量的重要性不感兴趣,那么绘制绝对 SHAP 值会更有帮助。

图片由作者提供|测试集上 XGBoost 的绝对 SHAP 变量重要性
8.Web 应用程序
我们可以使用streamlit轻松创建一个 web 应用程序(app ),并使用 PaaS 提供商Heroku进行部署,以共享我们的 SHAP 结果。我们可以使用 Heroku-CLI 创建应用程序:
*heroku login
git init
heroku create airbnb-sg
git remote add heroku git@heroku.com:airbnb-sg.git
heroku git:remote -a airbnb-sg
git add .
git commit -m "Add changes to both Heroku and Github"
git push heroku HEAD:master*
链接到:
- Colab 笔记本
- 网络应用
- 观念页
请注意,该应用程序使用缓存预测,因为 Heroku dynos 对自由层的预测极其有限。
感谢您滚动浏览!😀
预测 Spotify 的受欢迎程度——当数据比文化更需要数据时
原文:https://towardsdatascience.com/predicting-popularity-on-spotify-when-data-needs-culture-more-than-culture-needs-data-2ed3661f75f1?source=collection_archive---------8-----------------------
使用 Spotify 数据简短、逐步地浏览一个介绍性的机器学习项目。

图片来源:米克·豪普特 /Unsplash
回到 2016 年我在黄油音乐做原创音乐实习生的时候,我们团队想了很多如何参数化音频的问题。首先,我们正在为一个专有的音乐同步库奠定基础,我们需要一个新的分类法来分类所有将要组成这个库的不同声音。我们的目标是让我们当前和未来的客户能够通过情绪、流派、乐器或其他关键字进行搜索。
与此同时,我们也继续为客户的广告创作原创音乐。虽然这个工作流程更加定制和服务驱动,但我们仍然必须想出如何不断地将客户的反馈(如“让我们让曲目更加好奇和平易近人,但不那么多愁善感”)转化为实际的旋律、编曲、音色和氛围。
对于这两项任务,我们感觉在口语和音乐语言之间缺少了一个翻译层。这个问题并不新鲜。如果你是一个像这样的音乐迷,我敢肯定你有时会苦于找不到合适的词来解释你为什么如此喜欢一首歌。“我不知道,它只是如此时髦和流畅”通常是我在描述新的情感橙子或 SiR track 时脱口而出的话,我无法停止告诉我的朋友。
许多组织和团队已经开始大规模量化音乐的旅程,但没有一个像 Spotify 这样激进。根据 Counterpoint Research 的调查,与该领域的所有其他竞争对手相比,他们在全球付费订阅市场中占有 34%的市场份额。应用音乐以 21%的市场份额位居第二。
因此,这也意味着他们的数据仓库的大小和规模是首屈一指的。Spotify 在他们的数据工程团队和产品销售团队之间找到了一种奇妙的和谐。他们相互支持,推动公司不断发展。
Spotify 对音乐的量化越好,他们就能越好地调整自己的系统和算法,为自己和利益相关者创造更多收入。
我被 Spotify 独特的商业目标迷住了,那就是对音乐进行量化。如此着迷,以至于它推动我走出舒适区,开始我的个人数据科学之旅,以更好地理解音乐和数据之间的相互作用。
在这篇文章中,我邀请你来走我的第一个机器学习项目的道路,使用 Spotify 跟踪数据作为焦点。
在继续之前,我想澄清几件事——这篇文章详细描述了我从 0 到 1 而不是从 1 到‘n’的旅程。我的方法既不是详尽的,也不是完美的,事实上,可能包含许多错过的技术机会,其中一些我会在文章的结尾提到。我很高兴能继续迭代和学习,所以这个项目不是最后一站,而仅仅是第一步。
我想留下的是更宏观的发现,它帮助我理解了量化和参数化音乐的问题的形状和大小。我并不打算在这里解决任何问题,而是从一个新的角度,对一个古老的问题进行新的阐释,这个问题只会随着我们对音乐的收听和播放越来越多而变得更加复杂。
好了,开场白说够了,我们开始吧。
音乐流行到底是什么,我如何成名,以及其他令人痛苦的生存困境。
对于我的数据科学顶点项目(在大会上大声喊出来),我有兴趣了解 Spotify 如何理解“流行度”。对我来说,最重要的问题是:我们可以用一首歌的属性来预测一首歌的‘受欢迎程度’吗?
从一开始,我就盯上了一个 Kaggle 数据集,它是基于 Spotify 的 Web API 组合在一起的。对于那些不熟悉 Spotify Web API 的人来说,下面是一些可调用参数的截图,这些参数可用于分析 Spotify 上的曲目:

作者图片
根据 Spotify 的说法,“流行度是由算法计算出来的,在很大程度上是基于该曲目的总播放次数以及这些播放的最近时间。一般来说,现在被大量播放的歌曲会比过去被大量播放的歌曲有更高的人气。”
对我来说,首要任务是查看数据源,并开始一些探索性的数据分析。
EDA——一点点的观察、清理和可视化
数据集有 586,672 行,20 列。

作者图片
我立刻注意到数据中有三个我应该注意的地方:
- 两个变量已经被虚拟化(“模式”和“显式”)
- 某些分类变量,如“key”,是值编码的,但它们的相对值是无意义的。如果 0 是 C 的密钥,1 是 C#的密钥,这并不意味着 C#的密钥本质上比 C 的密钥大 1 点
- “时间签名”已经是一个预测值
让我们看一下原始数据,以确保它是最好的格式。

作者图片
我们删除了一些空值,并对“duration_ms”列进行了一次修饰。持续时间以毫秒表示,这在歌曲持续时间的上下文中没有什么意义,所以我们转换为分钟。

作者图片
对数据框架中的三个分类变量进行虚拟化也是有用的,所以我们现在就这么做吧。
data = pd.get_dummies(data, columns=['time_signature', 'key', 'mode'], drop_first=True)
有了这些,我们应该可以开始一些可视化了。
可视化:
首先,我们生成一些跨越几个变量的 Seaborn 对图:

作者图片
令人震惊的是,很少甚至没有简单的线性关系跳出来。让我们继续一些更细粒度的可视化,看看到底发生了什么。
因为预测流行度是我们的北极星,所以我很想看看流行度在整个数据集上的分布情况。

作者图片
帕累托原则在这里完全有效,右偏分布向我们展示了一首流行歌曲是多么难得。
我还想在数据中发现一些特定领域的细微差别。在几个有趣的可视化中,键/模式与流行度的双条形图突出了一些有趣的点。

作者图片
在西方音乐中,有 12 个可能的调。然而,每个调都可以处于一个小调或一个大调中。从全音阶来说,有三个主要调式和四个次要调式。这个柱状图描述了同一调在不同调性下的受欢迎程度(0 代表小调,1 代表大调)。例如,C#小调的曲目往往比 C#大调的曲目更受欢迎。
当然,这里的一个混淆变量可能是歌手喜欢的调,假设一首歌曲越受欢迎,它就越可能包含人声,根据下面的第三点,这似乎是一个公平的假设(即“声音度”与“受欢迎度”呈负相关)。
让我们看一个相关表,以确定我们的许多 X 变量之间的一些基线相关性。
plt.figure(figsize=(20, 10))
sns.heatmap(data.corr(),annot = True)

作者图片
一些观察结果:
- “能量”和“响度”的相关性最高,而且是正相关,这并不奇怪
- “能量”和“声音”有着高度相关的反比关系,这也是完全有道理的。一首歌越倾向于声学,它的能量就越少
- 不幸的是,由于我们的因变量是“受欢迎程度”,我们注意到自变量之间的相关值非常差。我们得到的最好结果是“声音”和“受欢迎程度”之间的 0.37
- 从这个相关矩阵中,我挑选了四个最好的特性(具有最高相关性的特性)用于以后的特性工程。这四个是:‘声音’,‘乐器’,‘音量’,和‘能量’
通过平方我们的最高相关系数 R,我们得到需要清除的决定系数(R):. 136。门槛很低,但让我们探索一下我们能在多大程度上超越它。
"嗨,我是来参加模特表演的?我来对地方了吗?”
模型 1:线性回归
为了预热烤箱,让我们看看从一个简单的线性回归模型中可以获得什么样的成功。
- 设置变量:
X = data[features]
y = data['popularity']
目前[特征]包括我们数据框架中的每一个独立变量。
2.拆分我们的数据
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegressionX_train, X_test, y_train, y_test = train_test_split(X[features], y, train_size=0.5, random_state=8)
3.训练我们的模型
lr = LinearRegression()
lr.fit(X_train, y_train)
lr.score(X_test, y_test)
这将打印出我们的决定系数 R,为. 213。虽然我们已经超过了我们的基线,但总的来说,这是一个危险的低 R。
4.做出预测
现在让我们将预测方法传递给我们的测试数据。
y_pred = lr.predict(X_test)
5.指标评估
最后,我们可以打印出三个关键指标来确定模型的适合度。
print(metrics.mean_absolute_error(y_test, y_pred))
print(metrics.mean_squared_error(y_test, y_pred))
print(np.sqrt(metrics.mean_squared_error(y_test, y_pred)))
MAE = 13.24
MSE = 266.19
RMSE = 16.32
6.结论
作为标准协议,我们使用 RMSE 作为主要指标来评估我们的线性回归模型。在预测模型中,从 0 到 100 的“受欢迎程度”范围内,我们的残差平均有 16.32 的差距,这是非常大的。
R 值为 0.213,我们甚至还没有超过我们的基本相关性。
我再次运行这个模型,但是现在只有上面提到的四个最好的特性。该模型实际上恶化了,R 为 0.181,RMSE 为 16.64。
因此,让我们看看是否可以用一些其他的回归技术将这些推向积极的方向。
模型 2:决策树
from sklearn.tree import DecisionTreeRegressormax_depth_range = range(1, 15)RMSE_scores = []from sklearn.model_selection import cross_val_score
for depth in max_depth_range:
treereg = DecisionTreeRegressor(max_depth=depth, random_state=1)
MSE_scores = cross_val_score(treereg, X, y, cv=5, scoring='neg_mean_squared_error')
RMSE_scores.append(np.mean(np.sqrt(-MSE_scores)))plt.plot(max_depth_range, RMSE_scores);
plt.xlabel('max_depth');
plt.ylabel('RMSE (lower is better)');

作者图片
即使只有一个很小的范围(1,15),我们也设法使用 max _ depth _ range 10 获得了 15.64 的更好的 RMSE。更好,但是考虑到决策树的性质,我们很自然地为了预测误差的标准偏差的一点点增加而进行了大量的过度拟合。
模型 3:随机森林
另一个尝试和抑制过度拟合和提高准确性的延伸。我们将上述相同的方法应用于随机树回归模型,并看到以下指标:
RMSE : 14.80
出袋得分: .38
*提醒:袋外得分是示例𝑥ᵢ使用随机森林集合中所有树木的准确性,在训练过程中忽略了这些树木。
我们看到,我们的 OOB 分数现在大大超过了我们的基线 R。就回归模型测试而言,徒步穿越随机森林让我们到达了一个更快乐的目的地。我们越来越接近一个具有更强泛化能力的模型,这也是我们最终的目标。
说了这么多,我对我们用回归方法得到的结果肯定不感到兴奋,所以也许是时候看看分类世界能给我们提供什么了。我们走吧。
分类
为了建立任何种类的分类模型,我们需要从试图预测我们的输出“流行度”的连续整数值,转而预测它的类别/标签。因此,让我们为“流行度”创建一些箱。我们将使用 pd.cut 将我们的值分为“低”、“中”和“高”三个受欢迎程度。


作者图片
我们的宁滨中突出的一个因素是三个箱中不均匀的计数分布。我知道一些分类模型很容易受到不平衡数据的影响,所以我使用不平衡学习包中的 RandomOverSampler 对这些类进行了重新采样:

作者图片
现在我们的类是偶数,我们可以设置和实例化我们的分类模型;这一次,我们将尝试 KNN 分类器。
让我们重新输入我们的四大特性来建立我们的设计矩阵:
feature_cols = ['acousticness', 'instrumentalness', 'loudness', 'energy']
X = data[feature_cols]
接下来,我们可以使用我们的过采样类执行训练测试分割:
X_train, X_test, y_train, y_test = train_test_split(X_ros, y_ros, random_state=99, test_size=0.3)knn = KNeighborsClassifier(n_neighbors=1)
knn.fit(X_train, y_train)y_pred_class = knn.predict(X_test)
print(metrics.accuracy_score(y_test, y_pred_class))
弹出的准确度分数为:. 807
天哪,真是个进步。虽然闻起来像是严重的过度拟合,所以让我们实现一些超参数调整,并搜索一个最佳的“k”。
由于使用 for-loops 和 GridSearch 的手动最近邻搜索对于我简陋的计算机来说计算量非常大,所以我选择使用 RandomizedSearchCV。这个包仍然实现了一个“fit”和“score”方法,但是不像 GridSearch 那样尝试所有的参数值。相反,从指定的分布中采样固定数量的参数设置。

作者图片
结果
我们表现如何?
首先,我们可以打印出一个混淆矩阵。
from sklearn.metrics import confusion_matrixcmat = confusion_matrix(y_test, y_pred_class)
#print(cmat)
print('TP - True Negative {}'.format(cmat[0,0]))
print('FP - Flase Positive {}'.format(cmat[0,1]))
print('FN - False Negative {}'.format(cmat[1,0]))
print('TP - True Positive {}'.format(cmat[1,1]))
print('Accuracy Score: {}'.format(np.divide(np.sum([cmat[0,0], cmat[1,1], cmat[2,2]]), np.sum(cmat))))
print('Misclassification Rate: {}'.format(np.divide(np.sum([cmat[1,0], cmat[0,1], cmat[0,2], cmat[2,0], cmat[1,2], cmat[2,1]]), np.sum(cmat))))

作者图片
56.52%的准确率是我们迄今为止取得的最好成绩,我对这个分数的准确性相当有信心。对于我们的 KNN 模型,我们平衡了我们的类,我们设计了特性,我们执行了一些超参数调整,我们从回归世界一路走到了启动!但对于我们所有的工作,当我们缩小范围时,56.52%的准确率也意味着用我们的模型预测的平均错误率为 43.48%。
结论:限制、期望和反响
我们表现最好的模型是 KNN 分类模型,但是这个带有一个大星号。将我们的数据变形为离散的分类方法,而不是连续的回归方法,这意味着模型中的预测稳健性在很大程度上被掩盖了。对于一个模型来说,预测三个受欢迎程度等级(“低”、“中”或“高”)中的一个要容易得多,而不是从 0 到 100 的受欢迎程度的离散数字分数。因此,虽然我们对模型本身的准确性感到更加乐观,但从我们迄今为止的工作来看,我们还远远不能将它生产出来,并实现令人满意的最终用户预测体验。
我也非常清楚我一直面临的其他限制:
- 机器学习在计算上变得很昂贵,很快,我不得不做出让步,以便我甚至可以运行某些代码块。这在一定程度上损害了健壮性和深度,无论是我们的交叉验证器只使用了五个折叠,还是我们的行业标准 cv=10,或者只运行了 k_range 为(1,22)的随机搜索
- 将来,我可以试着测试一个加权 KNN(加权投票)模型来缓和我们对完美 k 的不完美搜索的影响
- 我是否正确地处理了数据平衡问题?虽然我们标记了它并进行过采样,但我没有尝试过欠采样,这可能会产生不同的结果。是的,它会减少计数,但也会减少合成、重复的行
当我爬出 ML 洞穴时,我想知道就数据集哲学本身而言,这里是否有一个更大的问题,以及这是否是一个本体论的限制。
为什么对于一个精心修剪和组织的数据集,并且不缺少行,其内部的关系却是紧张的?有人会认为,人气是艺术家、唱片公司、管理公司、A&R 和 Spotify 自己希望能够上下拉动的杠杆。显而易见的答案是,还有成千上万的其他变量会增加噪声。而且,也许在我的项目中选择流行度作为因变量意味着我注定会失望,因为它凸显了我被给予的自变量有多窄,以及我们对计算“流行度”的 Spotify 算法的真正了解有多少。
该数据集及其 Web API 父级本质上是描述性的,而不是预测性的。奥利维亚·罗德里戈的《good 4 u》并不流行,因为它的响度、能量和乐器演奏得分很高(尽管它们可能很高,但不幸的是,这首歌不在这个有点过时的数据集中)。它之所以受欢迎是因为奥利维亚是谁,她怀旧的老(嗨@帕拉摩尔)和闪亮的新的融合,以及奥利维亚在《驾照》之后对任何事情的期待。这些参数在我们的数据集中的什么地方?!
鉴于现代音乐的现状及其消费方式,谨慎的做法是研究一些变量,比如,我们在这里只是触及了表面:
- 社交媒体关注
- 一位艺术家是否与唱片公司签约,如果是,是哪一家?
- 一个代表艺术家网络价值的指标(一个"你在这里认识谁?"评分)
- “怀旧”配乐
- 那个艺术家的历史资料
我们还可以根据以下因素将“流行度”分解成子集:
- 地区
- 人口统计数据
- 它在哪个设备上播放
- 共享的 Spotify 帐户数量
…还有更多切片。
将这些新功能添加到我们的数据框架后,看看我们的模型准确性是否有所提高,如果有,提高了多少,这将是一件有趣的事情。
然而,像所有银河守护者一样,Spotify 谨慎地隐藏这类数据。无论是出于涉及 PII 的原因,还是利益相关方合同和主服务协议,或者任何超出我们权限的原因,那些通过 API 访问 Spotify 数据的人最终访问的只是数据冰山的一角。
显然,数据科学和人工智能的世界远远超出了这里所尝试的。展望未来,我很想深入研究无监督学习和深度学习技术,看看我们能在这些道路上找到什么乐趣。
总而言之,我很高兴看到音乐分析垂直市场的增长。从这个项目中,我有了新的希望,即使在我们的算法,看似铁板一块的流媒体世界中,我们仍然可以有狂野,柔滑,丰富多彩,复杂,情绪化的听觉异常值,这些异常值击中了我们的内脏,唤醒了我们。
谢谢你一直读到最后(见鬼,我写这篇文章的时候差点没看完)。我个人仍然在理解所有这些新事物,并希望听到你对我的想法的想法,无论你是数据科学家,音乐家,Spotify 爱好者,文化见解的粉丝,还是任何人。
直到下次🎶
如果你想查看这个顶点项目的完整 Jupyter 笔记本和高级 powerpoint,这里有 Github:【https://github.com/philinyouin/SpotifyPopularityPrediction】
预测脉冲星:一个不平衡的分类任务:比较 Bootstrap 重采样和 SMOTE
原文:https://towardsdatascience.com/predicting-pulsar-stars-an-imbalanced-classification-task-comparing-bootstrap-resampling-to-smote-8cfbe037b807?source=collection_archive---------15-----------------------

瑞安·赫顿在 Unsplash 上的照片
对不平衡数据集进行分类是一项非常常见的数据科学任务,有大量的文章解释了不同的方法。
正如这些文章将向读者解释的那样,如果机器学习模型是在不平衡数据上训练的,它们通常会发现很难很好地学习和概括,即一个或多个类别被不成比例地代表(通常代表不足)的数据。因此,我们需要采取一些措施来解决这个问题;通常这是通过对学习数据的一些调整来完成的。
现在,我是一个比较事物的爱好者,我经常喜欢比较非常简单的方法和更复杂的方法。
这一次,我将用脉冲星的数据来比较随机重采样技术和 SMOTE。
背景
Kaggle 用户 Pavan Raj 最好地描述了任务的背景(他也将数据上传到了ka ggle——我是从那里获得的):
“HTRU2 是一个数据集,描述了在高时间分辨率宇宙调查期间收集的脉冲星候选样本。
脉冲星是一种罕见的中子星,它产生的无线电辐射在地球上可以探测到。作为时空、星际介质和物质状态的探测器,它们具有相当大的科学价值。
随着脉冲星的旋转,它们的发射光束扫过天空,当光束穿过我们的视线时,会产生一种可检测的宽带无线电发射模式。随着脉冲星快速旋转,这种模式周期性重复。因此,脉冲星搜索包括用大型射电望远镜寻找周期性的无线电信号。
每颗脉冲星产生的发射模式略有不同,每次旋转都会略有不同。因此,被称为“候选者”的潜在信号探测在脉冲星的多次旋转中被平均化,这由观测的长度决定。在缺乏额外信息的情况下,每个候选者都有可能描述一颗真正的脉冲星。然而,在实践中,几乎所有的检测都是由射频干扰(RFI)和噪声引起的,使得合法信号很难找到。
机器学习工具现在正被用来自动标记脉冲星候选体,以促进快速分析。分类系统尤其被广泛采用,它将候选数据集视为二元分类问题。在这里,合法的脉冲星例子是少数正类,而虚假的例子是多数负类。这里分享的数据集包含了 RFI 和/或噪声引起的乱真例子,以及真实的脉冲星例子。这些例子都已经被人类注释者检查过了。
每行首先列出变量,类标签是最后一项。使用的类别标签是 0(负)和 1(正)。
每个候选项由 8 个连续变量和一个单一类别变量描述。前四个是从综合脉冲轮廓(折叠轮廓)获得的简单统计。这是一个连续变量数组,用于描述信号的经度解析版本,该信号在时间和频率上都进行了平均。其余四个变量类似地从 DM-SNR 曲线中获得。这些总结如下:
- 积分轮廓的平均值。
- 集成剖面的标准偏差。
- 积分轮廓的过度峰度。
- 集成轮廓的偏斜度。
- DM-SNR 曲线的平均值。
- DM-SNR 曲线的标准偏差。
- DM-SNR 曲线的过度峰度。
- DM-SNR 曲线的偏斜度。
- 班级
假设
在样本外数据上,基于 SMOTE 数据重采样数据构建的模型将优于基于 bootstrap 数据重采样构建的模型。
为什么?考虑两颗具有“相似”特征的脉冲星。在我看来,我们可以认为这些信号在边界之外,我们可以预期任何信号在边界之内的候选星也将是脉冲星。由于 SMOTE 在现有观察“之间”创建合成观察,因此模型将能够学习这种关系..
建立
让我们导入我们将在分析中使用的包。
数据
导入数据并评估我们正在处理的内容。
前几行:

作者图片
总结:

作者图片
检查缺失值:

作者图片
我们的原始数据集包含大约 12.5k 个观测值,其中一些包含缺失值。我们必须以某种方式处理这些价值观;现在,让我们将它们从数据中删除。
得到的数据集大约有 9.2k 个观察值,损失了大约 25%的行!
也许我们应该估算这些…一篇关于估算的有用文章(如果我自己这么说的话)可以在这里找到填补空白:估算 3 种方法| Bradley Stephen Shaw |走向数据科学。
让我们快速看一下我们的目标变量,也就是我们试图预测的。
这本质上是一个指示变量:0 表示候选星不是脉冲星启动,1 表示相反。至关重要的是,目标中不存在遗漏的观察值。
数据到底有多不平衡?我们看到在 9.2k 的候选者中,只有 9.2%是脉冲星。因此,事实证明,数据非常不平衡。
我们应该已经到了可以探索输入变量的时候了。
在此之前,让我们重命名这些列。
对某些人来说,这似乎有些迂腐,但是我的敏锐感觉告诉我,使用包含混合大小写、空格和标点符号的列名将是一场噩梦,我宁愿避免。
至此,我们可以看看输入要素的分布了。

作者图片
这些特征看起来都像预期的那样连续。大多数特征似乎都有一定程度的偏斜,有些特征包含大量异常值。
同样重要的是要注意变量在不同的尺度上——如果我们要使用正则化技术,要记住这一点(提示:我们不打算这样做)。
还值得注意的是,一些特征是相互关联的-记住,峰度和偏度都是分布的均值和方差的函数,并且具有非常相似的函数定义。让我们直观地探索一下:

作者图片
这里我们有一个集成轮廓特征的配对图。
- 我们可以看到均值和峰度以及均值和偏度之间的非线性关系在减小…
- 我们可以说标准差和峰度以及标准差和偏度之间的关系也是如此,尽管趋势稍微有些混乱…
- 并且在偏斜度和峰度之间有明显的关系。
现在探索性的数据分析已经足够了,让我们继续为建模准备数据。
为建模准备数据
更具体地说,我们将:
- 将数据分成训练样本和测试样本
- 在我们建模之前平衡数据。我们将研究两种技术来做到这一点——随机重采样和合成少数过采样技术(SMOTE 下面会有更多的介绍)。
让我们将数据分成训练样本和测试样本。我将使用标准的 80:20 训练:测试分割,使用sklearn来完成繁重的工作。
让我们快速看一下我们的训练数据,区分脉冲星恒星的积极和消极识别。

作者图片
对于大多数特征来说,在大多数特征中,正面和负面的情况似乎有明显的区别。
我们现在可以重新采样我们的训练数据。
正如我们所知,这个数据集是高度不平衡的,也就是说,负面事例比正面事例多得多。这在现实世界中并不是一个完全陌生的概念,任何试图对高超额(再)保险层的欺诈行为或损失建模的人都会证明这一点。
为什么我们需要平衡数据?建立在不平衡数据上的机器学习模型将高度偏向主导阶级,因为该模型没有足够的信息来学习如何识别少数阶级。
有几种方法可以解决这个问题——我们可以对数据进行采样,以充分增加少数阶级的比例(“上采样”),或者对数据进行采样,以充分减少多数阶级的比例(“下采样”)。如果有必要,我们甚至可以两种方法都用!
我们将考虑的两种技术——随机重采样和 SMOTE——都是“上采样”数据的方法。
随机重采样(bootstrap) 大多数从业者都会很熟悉。它包括多次随机抽样数据替换。bootstrap 实现起来相当简单,并且被广泛理解。
然而,用户应该注意过度的自举——对现有信息的过多“回收”会导致偏见。如果需要不相称的上采样量来平衡数据集,更好的办法可能是在将自举应用于上采样之前,先对多数类进行下采样。
合成少数过采样技术(SMOTE) 是一种执行上采样的新方法。SMOTE 不是重新创建现有数据,而是一种“最近邻”技术,它应用插值来合成现有少数实例之间的新少数实例。
像 bootstrap 一样,在应用 SMOTE 之前,我们需要考虑数据的适当性。例如,将 SMOTE 应用于已经以某种方式有偏差的数据提取将导致另一个数据也有偏差。
例如,想象我们正在模拟信用违约。不为我们所知的是,我们的数据提取出了问题,我们对年轻的信贷申请人产生了偏见——比如说,18 至 25 岁之间的人信贷违约的比例更高。将 SMOTE 应用于此将创建新的违约者实例,但这些新实例也将在 18 至 25 岁之间,从而使偏见永久化。
创建像上面这样的图表有助于我们理解我们的数据是否代表现实。没有太多关于脉冲星的知识,我将假设它是,并应用imbalanced-learn中可用的 SMOTE 实现。
让我们创建两组平衡的数据—一组由 bootstrap 平衡,另一组由 SMOTE 平衡。我们将分别用resample和smote作为后缀。
请注意 SMOTE 重采样需要最少的代码。
让我们检查结果分布(注意:我已经检查了结果数据集是相同大小的)。
首先随机上采样数据:

作者图片
现在是 SMOTE 样本:

作者图片
两个样本现在都是平衡的(50%负实例,50%正实例),更令人放心的是,特征分布保留了我们最初在不平衡数据中看到的形状和模式。
系统模型化
这一次我们将使用随机森林模型来预测脉冲星。为了能够比较不同采样方法的影响,我们将构建并评估两个模型。
一个模型将根据随机重采样的数据进行训练,另一个模型将根据 SMOTE 数据进行训练。然后,我们将根据不平衡的测试数据评估这两个模型。
使用sklearn构建模型,然后使用 F1 分数评估其性能,这相当简单。
关于模型验证指标的快速说明…F1 分数是对测试准确性的衡量,同时考虑了 精度 和 召回 。F1 取[0,1]中的值,其中 0 代表最差的可能结果,1 代表最好的可能结果。F1 在机器学习中广泛用于二进制分类问题。

作者图片
在训练集上有相当高的性能,在样本外测试集上的性能不容小觑。
让我们看看在 SMOTE 数据上训练的模型是如何做的:

作者图片
虽然我们在平衡训练数据上看到类似的性能,但在 SMOTE 数据上训练的随机森林模型在样本外测试数据上表现更好。我想这意味着我的假设可能是正确的!
然而,使用多个度量来评估模型性能总是好的。让我们用测试集来看看这两个模型的标准化混淆矩阵。
标准化的混淆矩阵是评估以下比例的好方法:
- 真阳性:实际目标为阳性且模型预测为阳性的情况。
- 真否定:实际目标为否定,模型预测为否定的情况。
- 假阳性:实际目标为阴性,模型预测为阳性的情况。
- 假阴性:实际目标为阳性而模型预测为阴性的情况。

作者图片
有意思!相对于 SMOTE 模型,重采样模型
- 不善于识别负面事例(应该有大约 92%的负面事例)…
- 是否比更善于识别正面事例(应该有大约 9%的正面事例)…
- 具有更少的假阴性(0.75%比 0.81%,尽管从绝对值来看,这种差异可能可以忽略不计)…
- 误报率更高(3.45%比 2.69%)…
- 准确率较低(95.8%对 96.5%)。
因此,值得思考的是,看起来模型性能有点微妙。
这就足够了,让我们总结一下。
结束语
…此外还夹杂着一些漫无边际的话。
我们已经做了很多了!大家讨论一下。
- 直方图和配对图使我们能够可视化特征的分布以及它们之间的关系。我非常喜欢用这种方式绘制信息图表,因为我发现直观地发现关系比通过描述性统计更容易。
- 我们已经处理了丢失的值,尽管相当粗糙。删除有缺失值的观察值实际上意味着我们正在丢失建模数据中的信息。对此有更好的方法,一个未来的改进可能是估算任何丢失的信息。
- 我们已经平衡并检查了两种不同平衡技术产生的数据,注意到特性的分布和类之间的分离被保留。我们没有探索上采样的其他方法——未来的改进可能是探索 ADASYN 等技术。
- 我们在两个平衡的训练集上建立了一个随机森林模型。我随机选择了这个模型,其他模型可能比我们的随机森林要好。在更广泛的建模实践中,可以使用交叉验证方法选择表现最佳的模型。我们当然需要考虑其他模型在数据缩放和转换方面的要求。
- 继续随机森林的主题…没有保证用于训练模型的超参数接近最优,我们没有执行任何超参数优化。我们对参数的选择很可能会影响我们比较的结果;让我们将这一点添加到我们的改进列表中。
- 我们看到,仅基于 F1 度量,基于 SMOTE 数据训练的模型优于基于随机采样数据训练的模型。然而,对混淆矩阵的检查表明,模型性能有一点细微的差别。这也是为什么我们应该使用多个模型性能指标来评估模型的另一个例子。
- 虽然我会说 SMOTE 模型优于随机样本模型,但我不能说这是一个全垒打性能。通常不正确的分类会带来某种代价——在这种情况下,可能是花费时间调查我们认为是脉冲星的候选星,却发现它实际上不是(假阳性的一个例子)。考虑到不正确预测的相关成本,或许可以让我们找到决定性的更好的抽样技术。
- 我们使用一个简单的训练测试数据分割来执行这个比较。通过将工作流程实现为流水线并通过交叉验证运行,可以实现更可靠的评估。这将最大限度地利用我们的数据,并提高我们的样本外性能估计的可靠性。
从卫星图像预测降雨
原文:https://towardsdatascience.com/predicting-rain-from-satellite-images-c9fec24c3dd1?source=collection_archive---------7-----------------------
如何训练神经网络以根据从气象 API 提取的卫星图像来预测降水
介绍
预测和了解天气在许多行业都变得至关重要,包括农业、自动驾驶、航空或能源部门。例如,天气条件在航空和物流公司规划最快和最安全的路线时起着重要作用。类似地,可再生能源公司需要能够预测他们在某一天生产的能源数量。因此,各种各样的天气模型被开发出来,并在世界各地得到应用。不幸的是,这些模型通常需要关于大气和确切条件的非常具体的信息。
出于这个原因, Meteomatics ,一个提供快速、直接和简单访问大范围全球天气、气候预测和环境数据的天气 API,向我们寻求帮助。他们的目标是:在数据稀少的地区准确预测降水,他们不得不依靠卫星图像。在这篇博文中,我们展示了我们如何开发一个神经网络来根据红外卫星数据预测给定区域的降雨量。
数据收集和分析
如果你曾经和神经网络一起工作过,你就会知道它们可能是数据饥渴的。因此,建立一个允许您收集、管理和理解汇总数据的数据管道至关重要。我们的合作伙伴 Meteomatics 提供了一个易于使用的 API,使我们能够快速收集培训和实际数据。例如,要获得 2021 年 7 月 7 日欧洲的红外图片(坐标从 65,-15 到 35,20),分辨率为 800x600 像素,我们只需执行以下查询:
从 meteomatics.com 获取红外卫星图像的查询示例。下载的图像可以在下面左侧的示例图中看到。
我们连续几天每隔一刻钟运行一个 Python 脚本,收集欧洲、北美和墨西哥不同波长的红外图像。然后,我们在本地将每个时间戳的不同图像组合成一个 RGB 图像。为了使任务更容易,我们在第一步中掩蔽了层状降水。然而,正如我们将在后面看到的,这对模型的准确性只有很小的影响。我们还收集了基础数据,用于训练和评估我们模型的准确性。请注意,地面实况数据仅适用于欧洲和北美。下面你可以看到欧洲上空的一对输入和地面实况数据:

卫星图像(左)、神经网络输入(中)和地面实况数据(右)的示例。基于提升指数,屏蔽掉输入和地面实况图像上的浅灰色区域。这些数据是 13 年星期二在欧洲上空收集的。2021 年 7 月 20 日 15 时 02 分。
遵循臭名昭著的“垃圾进垃圾出”的咒语,我们希望在训练机器学习算法之前,理解和整理收集的数据。为此,我们轻而易举地使用了免费的探索工具。Lightly 支持快速简单的方法来分析数据集,以及更深入的算法来挑选最相关的训练点。将我们的数据集上传到 Lightly 后,我们立即注意到所收集数据的一个重要属性:欧洲、北美和墨西哥的图像在视觉上和语义上都是分离的。这导致了一个简单的策略来测试算法的泛化能力:如果我们在欧洲的数据上训练它,并且它在北美和墨西哥的看不见的数据上表现良好,那么该算法将泛化得很好。请注意,如果我们选择了非常相似的训练数据集和测试数据集,那么我们将测试的只是神经网络的记忆。

来自欧洲(蓝色)、北美(绿色)和墨西哥(灰色)的输入图像的嵌入,如数据策展应用 Lightly.ai 所示。图像在嵌入空间中被很好地分离。
我们获得的另一个关键见解是,有许多非常相似的图像小集群。这是因为我们在相对较短的时间内收集了数据。正因为如此,数据集中有大量相似的影像,这使得模型更难很好地泛化。Lightly 帮助我们通过一种叫做“核心集采样”的方法来消除这些冗余,这种方法旨在最大化数据集的多样性。
在用轻微地管理数据集之前,我们的训练数据集(欧洲)中有 1158 张图像。经过数据整理,我们剩下 578 张图片。验证数据集(北美)由 1107 幅图像组成,而测试数据集(墨西哥)仅由 43 幅图像组成,因为我们后来开始收集数据。
我们轻松地从下载图片,现在我们准备做一些机器学习。
神经网络和语义分割
卷积神经网络是一类应用于计算机视觉的人工神经网络。它们的共享权重架构允许它们高效地处理图像数据,并容易地检测相关特征。卫星图像非常适合机器学习。可能的输入图像的范围相当有限,因为卫星总是处于大致相同的高度,因此物体将总是以类似的比例出现。
语义分割是给图像的每个像素分配一个标签的任务。例如,在自动驾驶中,算法通常需要学习图像中的哪些像素代表汽车、行人、骑自行车的人、停车标志等。你可以在这里阅读更多关于这个的内容。为语义分割设计的神经网络的典型架构是 UNet(见下图)。在这里,输入图像被卷积层的金字塔转换成密集矢量,然后通过一系列去卷积层再次扩展成图像的原始形状。此外,来自卷积层和反卷积层的特征被共享,以便获得输入图像的全局视图。

摘自他们论文的 UNet 架构图解。输入图像被压缩,然后通过卷积层的金字塔来解压缩。
为了完成这项任务,我们使用了一种称为高效神经网络(或 ENet)的神经网络。具体来说,我们使用了这个 PyTorch 实现。它是 UNet 的一个变种,专门用于移动应用,因此需要更少的浮点运算和参数。这导致更短的训练和推理时间。
为了将预测降雨量的任务构建为语义分割问题,我们根据五分钟时间跨度内的降雨量(以毫米为单位)将输出空间划分为以下类别:
- 未标记(屏蔽掉图像的一部分,如果有的话)
- 0.00 毫米(无雨)
- 0.04 毫米—0.07 毫米
- 0.07 毫米—0.15 毫米
- 0.15 毫米—0.30 毫米
- 0.30 毫米—0.60 毫米
- 0.60 毫米—1.20 毫米
- 1.20 毫米—2.40 毫米
- 2.40 毫米—4.80 毫米
-
4.80 毫米
结果
除了更改输入的高度和宽度以匹配图像的分辨率(600x800)之外,我们使用引用的存储库中的默认设置来训练神经网络。在 NVIDIA Tesla P100 上的完整数据集上训练 100 个纪元花费了大约 1.6 小时。当在上述精选数据集上进行训练时,我们能够将训练时间减少 50%以上。
我们将首先报告预测对流降水的简单情况的结果,然后评论更一般的情况。下面的表 1 示出了在训练数据集(欧洲)和测试数据集(北美)上不同类别的预测的 IoU(交集/并集),其带有地面实况注释。

表 1:训练集(欧洲)和测试集(北美)上不同预测类的交集(IoU)。请注意,IoU 对于这种分段任务来说是一个次优指标。
正如数字所示,该模型学会了以非常高的准确度区分“下雨”和“不下雨”。不幸的是,随着降水量的增加,精确度会迅速下降。这可以用降雨量大的地区的可用数据稀少来解释。表中的数字可能表明该模型表现不佳。然而,事实并非如此。我们请了一位来自气象科学的专家来目测我们的模型做出的预测,他们的结论是该模型非常准确——尤其是考虑到它需要的数据量很少。为了让您更好地理解算法做出的预测,我们将带您浏览一些气象科学用来进行视觉检测的例子。
图 1 显示了红外图像,地面实况,以及我们的算法对欧洲天气情况的预测(训练集)。我们可以立即看到预测的形状是非常准确的。然而,我们也观察到模型预测高降水的像素数量(显示为红色)相当低。这是不平衡数据集的一个典型例子,收集更多的高降雨量数据可能会解决这个问题。同样值得注意的是,该模型未能准确预测真实数据的细粒度细节。这可以通过提高分辨率来解决。

图 1:不同波长的输入红外图像(左),模型输出(右上)和来自训练数据集的放大示例的地面实况(右下)。
图 2 显示了红外图像,地面实况,以及我们的算法对北美天气情况的预测(测试集)。与训练集中的情况类似,我们可以看到对高降雨量地区的预测不太准确。然而,该模型正确地预测了地面实况的形状,并且倾向于精确地预测有更多降水的区域。

图 2:不同波长的输入红外图像(左),模型输出(右上)和来自测试数据集(北美)的放大示例的地面实况(右下)。
最后,我们希望将我们的算法与已经投入生产的算法进行比较。图 3 再次显示了红外图像和我们的算法做出的预测,这次是在墨西哥上空。然而,它显示的不是地面实况,而是由云和大气的物理模型所做出的预测。很明显,输出差异很大,并且基于输入图像,我们的算法似乎至少在精度方面优于物理模型。事实上,用我们的(轻度)算法观察到的假阳性更少,因为没有云的地方不会预测降水。

图 3:不同波长的输入红外图像(左),模型输出(右上)和来自测试数据集(墨西哥)的放大示例的物理预测模型输出(右下)。
结论
在这一系列中,我们开发了一个语义分割模型,该模型基于卫星图像以良好的准确性预测给定位置的降雨量。我们卷积神经网络的实际应用可以在改善或补充现有天气模型方面发挥至关重要的作用,从而帮助我们的合作伙伴 Meteomatics 准确预测难以获得数据的地区的降雨量。
我们可以得出结论,当试图从只有 500 张图像的红外卫星图像中预测降水时,有可能获得合理的结果。即使对于考虑层状降水的更困难的情况,性能也只是略微下降(IoU 平均下降大约 0.04)。这种设置的一个关键问题是数据集严重失衡。为了缓解这种情况,可以在更长的时间内收集更多的训练样本,以确保多样化的数据集。为了获得更精细的结果,最好以更高的分辨率收集图像,并将其切割成更小的块,以保持较低的内存占用。
最后,我们注意到用稍微多样化数据集的 coreset 算法稍微提高了验证准确性,同时减少了大约 50%的训练时间。这进一步证实了该数据集中的不平衡和冗余会给模型训练带来问题。
希望这篇博文提供了一个例子,说明数据管理的重要性和神经网络在天气模型中的力量,并将激励读者尝试在 Lightly 和 Meteomatics 的帮助下构建自己的模型。
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
菲利普·沃思
机器学习工程师
lightly.ai
探索预测 MLB 投手的救球
原文:https://towardsdatascience.com/predicting-saves-for-pitchers-in-mlb-cbbf73b9b3df?source=collection_archive---------32-----------------------
一月的芝加哥,一个寒冷的早晨,我醒来时听到一个激动人心的消息:白袜队最近签下了一名新球员,利亚姆·亨德里克斯。对于一个崭露头角的球队来说,增加一个全明星来支撑他们的牛棚是一个令人兴奋的前景,也是球队投资在 2021 年实现竞争力飞跃的标志。我看亨德里克打球的大部分经历是在几个月前,当时他的奥克兰运动家队在季后赛首轮击败了白袜队。在短系列赛中,他是一个真正的主导力量,我在过去几年中听到过他的名字,所以我认为他在这个角色上已经有一段时间了。
当我打开他的棒球参考页面时,我惊讶地得知,他不仅只做了两年的棒球投手,而且事实上他还是近十年前为明尼苏达双城队效力的那个低于平均水平的首发投手!我知道这种从先发到后发的转变并非闻所未闻,但我被他职业生涯早期和后期成功的鲜明对比吓了一跳。我被两个相关的问题打动了。首先,利用这一页上的统计数据,我能预测他在即将到来的赛季在白袜队的表现吗?第二,有没有一种方法可以普遍预测近距离投球手的救球,甚至是像亨德里克斯那样职业生涯轨迹变化很大的投手?
有没有一种方法可以预测近距离投球手的救球,甚至是像亨德里克斯那样职业生涯轨迹变化很大的投手?
收集数据
我决定继续使用我和许多其他球迷的网站,作为统计数据的第一站,棒球参考。我特别感兴趣的是获得关于投手的信息。为了清楚起见,closer 是球队在比赛后期高杠杆情况下用来帮助“结束”比赛的投手。如果他们在这种情况下进入,保持领先,并且他们的球队获胜,他们将被记为救球。Baseball-Reference 有一个漂亮的页面,上面有从 1871 年以来每年救球次数最多的前十名投手,所以我用它来决定我应该把哪些投手放入一个数据集中。我用 BeautifulSoup 收集了从 1990 年到现在,每个赛季出现在前十名名单上的投手的职业统计数据。1990 年的截止日期让我们停留在牛棚使用的现代时代,因为中继投手的配置方式在 1970 年代中后期开始大幅改变。
清洁和工程数据
一旦我把 HTML 文件刮到 Jupyter 笔记本上,我就解析它并把它加载到熊猫数据框中。我的目标是下一年的储蓄,所以我必须通过移动行来为下一季度提供储蓄,从而对时间序列数据进行一点工程处理。例如,一名投手的 2015 年数据将添加一个条目,用于 2016 年的救球。这样,我可以使用 2015 年的数据,在监督下进行训练、验证和测试。我也做了同样的事情,回顾过去,看看跟踪记录的统计数据是否会影响未来的表现。因此,这些 2015 年的统计数据还包括 2014 年的存储类别、前两年的总和以及连续三年的总计。
这个决定也意味着需要从训练数据集中删除一些观察值。投手在他们职业生涯的最后一年没有任何有意义的预测。在他们的最后一个赛季保存计数被用于前一年的目标后,他们的最后一个赛季被删除。同样,由于新冠肺炎,2020 赛季是不正常的,所以它不会用作 2019 赛季的真正目标,所以这些都被搁置起来供未来考虑。
除了保存统计数据之外,还有大量其他统计数据可用作模型中的潜在特征。这些指标包括但不限于:比赛次数、安打次数、跑垒次数、三振次数、ERA、救球机会、持球次数、年龄以及更复杂的指标,如 WHIP、FIP、ERA+、SO/BB 和 S0/9。
MVP 和基线
为了了解如何开始预测储蓄,我从一个简单的回归模型作为最小可行产品开始。最初的模型是一个简单的线性回归,将去年的存栏数作为预测下赛季的唯一特征。这个模型只能解释来年储蓄变化的 30%。这意味着一年的救球总数可以解释投手在下一个赛季的表现,也不能解释救球的大部分可变性。平均而言,该模型的预测具有大约 14 次保存的平均绝对误差。

MVP 模型中的可视化误差
在上图中,准确的预测落在虚线上,而远离该线的点表示超出或低于预测。该模型有一个下限,给出了它将预测的最小值,这是一个很好的例子,说明该模型如何未能捕捉到储蓄中的一些可变性。
我把这个模型作为基线。未来的模型可能会解释更多的可变性,这将是一个成功的故事。有可能准确预测节省吗?如果有的话,什么统计数据可以解释这种能力?
改进型
出于这个项目的目的,我想坚持线性回归,以满足 Metis 数据科学密集训练营的任务要求。在新模型中,有几个改进方向需要考虑。最大的机会来自已经讨论过的内容,即添加更多的功能。通过分析配对图来避免要素之间的共线性,使用领域知识来确认这些要素是否相关,并考虑要素与目标变量的相关系数的热图,我使用剩余的要素创建了一个新模型。
然后,这个更新的回归模型被训练并通过五重交叉验证运行,这看到了可以解释目标节省的可变性百分比的增加,平均跃升至 35%。此外,预测的平均误差有所下降,下降到每次预测 10 次左右。

在与以前相同的视觉样式中,新模型创建的预测更接近实际值,因为点更接近真实预测的虚线。此外,输出的最小值不再出现,这有助于模型考虑未来储蓄的额外可变性。
微调
对改进的最后一次尝试来自于考虑特性的相互作用,并确定哪些特性对最终的模型贡献最大。在这两种情况下,我都依赖于使用交叉验证的套索模型来惩罚大的系数和帮助特征选择。我创建了所有的二次相互作用项,并通过一个套索模型运行,但后来没有非零系数,所以我没有在我的模型中保留这些相互作用项。然而,我确实从我自己的工程中发现了几个增加价值的特征,在每场比赛的失误(障碍,被投球击中,和根据外观相加和划分的野球)和每场比赛面对的击球手方面。
使用具有所选特征的套索模型,最终模型适合预测。根据维持测试数据集对其进行测试,最终得出了实际节省量与预测值的对比图。

虽然该图看起来与之前的回归模型的预测非常相似,但根据测试数据,最终模型能够解释目标存储中约 41%的可变性,并且每次预测的平均误差约为 10 次存储。
误差来源
在这个过程中,虽然模型解释储蓄变化的能力有所提高,但我不认为它们是预测储蓄的完全可靠的方法。有很多玩家有很大的误差,考虑他们有助于理解为什么模型会有问题。

预测误差的主要来源
有几个要点与约翰·斯莫茨和杜安·沃德这样的球员有关。斯莫茨看到了像亨德里克斯一样的职业轨迹。但他并没有从先发到中继再到近传,而是直接从先发跳到近传。像斯莫茨这样的投手没有任何中间赛季可以预测他们在救球方面的成功,这个模型无法捕捉到这种跳跃。另一方面,杜恩·沃德非常成功,但他受伤了,再也没有真正上场比赛。在他上一个成功的赛季后,这个模型预期会有更多的成功,但无法解释他的下降。封闭者的高波动性的负面影响在许多预测赢得救球的投手中可以看到,但最终几乎赚不到钱。
外卖
尽管存在这些误差来源,但该模型确实有能力解释未来储蓄的一些可变性,而不仅仅是简单地使用去年的储蓄。为了更好地理解哪些要素的贡献最大,让我们考虑一下 LASSO 模型中要素的系数。由于统计数据已经标准化,因此这些值仅用于解释价值,并不代表相关要素的价值。

LASSO 模型标准化特征的系数
在我看来,贡献最大的特征分为两类:机遇和优势。机会可以归结为运气、管理选择、绩效和其他因素的组合,但在这里可以在统计数据中看到,如完成的游戏数量、持有(另一个高杠杆机会,但不是完成游戏)、保存、保存机会和游戏。统治力是一个类别,说明投手在多大程度上控制了比赛,而不是依靠他的防守来支持他。这在统计数据中是显而易见的,如 FIP(这是一种描述投手独立于外野手的成功的指标),每次保送的三振数,以及允许较少安打和增加保送的组合。
在我看来,贡献最大的特征分为两类:机遇和优势。
未来工作
我将引导未来的努力去发现更多关于这两个对最终模型影响最大的类别的信息。特别是,我会根据速度、旋转速度、挥杆和失误百分比以及其他新的学校统计数据,转向其他高级指标,以更好地定义主导投手。我还认为,引入更多与球队相关的统计数据,如管理行为和关于球队进攻和防守之间平衡的指标,可能会预测比赛的接近程度,从而预测扑救机会的数量。总而言之,很明显,救球是高度不稳定的,很难预测,所以依靠这些代理值可以帮助我们更好地了解未来潜在的成功,除非受伤。
为了好玩:预测 2020 年
作为最后的总结,这是最终模型在 2019 年的基础上对 2020 年的预测,然后缩小到 60 场比赛的赛季。

根据 2019 年预测 2020 年
在左侧,投手按实际的 2020 保存排序,而右侧则按模型中的项目保存排序。总的来说,这个模型在预测储蓄方面做得不错,除非它失败了。然而,这些大的错误似乎都属于之前讨论过的角色/团队变化和伤害的范畴。没有准确的 2020 年 162 场比赛数据或 2019 年两年后的数据,没有一个数据集似乎与预测 2021 年有关,但我期待使用 2021 年的数据来看看我对 2022 年的预期!
更多细节、代码、连接和其他信息,请访问我的 Github 知识库、网站或 LinkedIn 。
从 BBC iPlayer 观看预测学校假期
原文:https://towardsdatascience.com/predicting-school-holidays-from-bbc-iplayer-viewing-df4e211b02c?source=collection_archive---------39-----------------------

图像来源
我们能从 BBC iPlayer 上观看的某些电视节目中辨别出孩子是否在上学吗?剧透——是的!我们还可以识别学校何时因下雪而关闭!
这是我在 BBC 工作的第一个项目,也是最有趣的项目之一。
虽然关于学校假期的信息可以在互联网上获得,但它出现在地方政府网站上,这些网站的格式因委员会而异,这使得网络搜集不切实际。
用例
BBC 为儿童制作了大量内容,能够有效且恰当地传递这些内容至关重要。我们当前的使用案例包括:
- 报告
- 及时输出儿童内容
- 推荐适合儿童的内容
- 评估营销活动的有效性
- 受众细分
实时结果
当学校放假时,用儿童友好的版本自动个性化 BBC iPlayer 主页不是很棒吗?
虽然我们的一些用例,如观众细分,可以用学校假期的历史数据来执行,但最有用的应用来自于在足够的时间内了解学校假期,以便能够对 BBC 的输出做出积极的决策。
我们非常聪明地构建了这个模型,使得我们能够在同一天的上午 9 点之前识别出学校假期。请继续阅读,了解如何…
数据
我们使用了 2 个数据集来构建这个模型:
- BBC 事件数据,用于 BBC iPlayer 上的儿童内容流
- 代码点打开来自地形测量局的数据集,用于邮政编码位置数据
观看模式
我们的目的是纯粹根据儿童一整天对 iPlayer 内容的查看模式来确定某一天是否是学校假期。下面的图 1 显示了学期日和学校假期/周末的平均观看模式。

图一。全天的收视分布。对每天的观看进行标准化,以便在对每个班级进行平均之前,每天有效地有一个观看者。(图片作者本人)
这两个班级的观看行为没有什么令人惊讶的地方:
- 学期-时间的特点是流量出现两个高峰;一个在早上,一个在下午。上学期间很少看电视。
- 学校放假观赏开始稍晚,一天中的大部分时间都处于平稳状态。
虽然在上面的图中很明显,这两种类型的日子的观看模式是不同的,但我没有讨论的是,我们如何标记什么是学期日,什么是假日,这是一个挑战!
半监督学习
这变成了对半监督学习的研究——数据科学中一个鲜为人知的领域。
我们都听说过监督和非监督学习,但是什么是半监督学习呢?
- 监督学习— 训练集中的每个数据点都有特征和标签,我们可以根据特征识别标签
- 无监督学习— 我们没有标签,但希望根据它们的特征来识别“相似”的数据点并将其分组到簇中。虽然我们可能试图解释每个集群的定义特征,但它们在很大程度上是抽象的。
- 半监督学习— 我们有大量未标记的数据,但希望我们的聚类有特定的含义。
我们有一点矛盾——我们想要一个模型来分配标签,但是我们需要标签来构建模型。有点先有鸡还是先有蛋的情况,或者更有趣的是:
我最近发现士力架里的牛轧糖是用融化的士力架棒调味的。KitKat 中薄饼之间的巧克力层含有融化的 kit kat!
*其他基于巧克力的零食也有

图像来源
半监督学习确实是两个世界中最糟糕的,但是有一些方法可以使用标准的监督和非监督技术来帮助解决这些问题。
无监督学习方法
先简单讨论一下我们没做的事。
可能影响人们流媒体行为的最大因素是天气——如果下雨,人们就会呆在家里看电视。
下雨时,我们在 iPlayer 上看到三倍于 CBBC 的流量——这表明当天气晴朗温暖时,孩子们都在外面。应用无监督学习可以很好地产生代表下雨/不下雨而不是假期/学期时间的两个聚类。
监督学习方法
我们这样做的出发点是,我们可以标记我们的一些数据:
- 假期:周末和假期差不多,常见的学校假期如八月初和包含圣诞节的一周在全国范围内是统一的。
- 期限-时间:没有已知节假日的时期,如 12 月初和 6 月。
然而,不能保证 BBC iPlayer 在假日期间的周三观看与学期期间的周六观看相似;如果我们坚持只将部分标记的数据集作为训练数据,我们就有模型不能很好概括的风险。
解决方案是使用离群点检测算法来概括我们部分标记的数据集…
离群点检测
异常值检测的目的是在未标记的数据中识别额外的日期,我们可以合理地将其标记为假期或学期时间。
1 类支持向量机 可以执行离群点检测,尽管它们对于不规则形状的聚类/类可能不会最优地执行。在这种情况下, DBScan 将是一个很好的选择。
我们可以使用部分标记的数据来定义我们的每一个类,然后使用 1 类 SVM 来识别其他不是该类异常值的日子。这有助于从我们最初的部分标记数据集进行归纳。就像雀巢公司的士力架和 KitKat 一样,我们可以结合原始的部分标记数据和新的模型输出来重新训练模型,并预测一组更一般化的类示例。重复应用应该收敛于一组一致的非异常值。
在下面的图 2 中,我们显示了将学期-时间 1 级 SVM 应用于不在八月的工作日的结果。1 级 SVM 通过选择白天观看率明显下降的日子来从所有非八月工作日中识别额外的学期日。

图二。查看所有非八月工作日的数字(左),按新标记的“期限-时间”日期(右)和该类中的异常值(中)划分。蓝线表示中间值,灰条表示第 5 和第 95 个百分点。(图片作者本人)
当然,一个数据点是一个类的异常值并不意味着它属于另一个类!我们仍然需要一个更强大的分类器,但现在我们可以对每个类别中的所有数据点进行平均,以定义每个类别的特征行为,如图 1 所示。
分类度量
现在我们已经有了每个班级的特征行为,我们可以开始分析某一天看起来更像是假期还是学期了。
如果我们将一天的观看表示为 24 维空间中的向量,我们可以通过计算两个向量之间的角度来评估特定一天的观看和学期-时间/假期观看之间的相似性。我们使用欧几里得点积的定义来做这件事,这与更常见的度量余弦相似度非常相关。

图 3。将数据表示为向量的简单二维版本。在这里,为了演示的目的,我们将 24 个维度简化为 2 个:“白天”和“晚上”。(图片作者本人)
然后,我们可以将 24 小时的查看数据组合成一个单一的指标,我们称之为分类指标:

图片作者自己的
分类可以由下面的简单关系来定义:
- c ≥ 1/2:期限-时间
- 你可能想知道为什么我们不使用 24 小时特征集来训练一个 ML 模型?
使用分类指标的优势在于,它可以在一天中的任何时间进行评估,比如说,我们可以在某一天的前 9 个小时进行观看,计算出与我们的特征行为的前 9 个小时相关的余弦相似性,然后使用相同的 1/2 截止值计算分类指标。该属性使我们能够使用实时查看数据来识别上午 9 点前的学校假期(稍后将详细介绍!).
此外,分类标准将 24 个维度(每小时观看一个维度)减少到 1 个。这提供了大规模的维度缩减,使我们能够聚合不同地理区域的多个分类指标。否则每个地理区域将有 24 个维度,你可以很容易地看到维度的数量可能会增长得相当快。它还简化和改进了前面讨论的异常值检测算法。
地理可变性
这个项目的主要理由之一是不同的学校有不同的假期。北爱尔兰和苏格兰的暑假尤其如此。即使在英格兰,不同的地区也有不同的学期、复活节和圣诞节假期。
我们开始把观看分成越来越小的地理区域。在 outcode 水平,我们得到非常具体的预测,但在农村地区,我们缺乏足够的数据来可靠地分类。在区域层面上,我们得到了大量的数据,但丢失了许多地理细节。
对于每一天,通过查看以下地理区域的汇总数据来评估分类指标:
输出代码
10 个最近的输出码(基于每个输出码中心之间的欧几里德距离,根据地形测量定义的纬度和经度)
城镇
- 地区
- 一个随机森林分类器根据这 4 个分类度量作为特征,以及来自前一天和一周中某一天的相同度量进行训练。在这里,前一天的数据很重要,因为假期通常发生在整周,所以如果周二是假期,那么周三也很可能是假期。然而,银行假日通常是周一,并不能告诉我们周二是否是假日。
- 结果
- 我们对模型进行的第一次定性评估是在暑假。给予或采取教师培训日,可能适用于不同地区,核心暑假在英国不同国家是一致的。没有向模型提供关于一年中的时间(只有一周中的某一天)或不同国家何时放暑假的信息。下图显示了模型的结果。
图 4。英国不同国家暑假的差异。显示的数据是每个地区的周一至周五 Fri 的平均值。(图片作者本人)
该模型已正确识别出北爱尔兰有 8 周长的暑假,而其他国家有 6 周。苏格兰的暑假也比英格兰和威尔士早两周。
图像来源

在检查结果时,我注意到 2017 年 12 月的一个流氓日显示格洛斯特郡在度假(未显示)。在最初的恐慌之后,我决定在谷歌上搜索当天的新闻事件,并发现一场大暴风雪在那一天关闭了格洛斯特郡的许多学校——这一事件是模型正确识别的!
最终成为一个更有趣的事件的是昵称为“来自东方的野兽”的冬季天气事件,它于 2018 年 2 月底抵达英国。下图显示了该模型在此期间的输出。

图 5:2018 年冬天,英国遭遇了一场绰号为“东方野兽”的冬季风暴。肯特郡在 2 月 28 日星期三第一次受到袭击,到 3 月 2 日星期五,英国大部分地区被埋在几英寸厚的雪下,英国大部分学校关闭。(图片作者本人)
2 月 28 日星期三,来自东部的野兽第一次成为头条新闻,当时它袭击了肯特郡,并关闭了那里的学校。随着一周时间的推移,风暴在全国范围内向上和向西移动,导致越来越多的学校关闭——所有这些我们的模型都能够识别。3 月 2 日星期五,只有英格兰西北部的孩子在大量上学。
清晨会聚

Hindcast 数据对我们的很多应用都很有用,比如受众细分、报告、营销效果。然而,我们理想地希望能够基于模型输出做出主动的决策。
我在上面简单提到过,我们可以在一天中的任何时间点应用余弦相似性,只需要使用我们有数据的维度。我们还使用分类度量来训练我们的随机森林,我们可以根据余弦相似度来计算分类度量。因此,我们不需要等待一整天的数据,就可以开始将这一天归类为学校假期或学期时间。
但是仅仅因为我们能够做出预测并不意味着我们应该——这个模型有多准确?
我们可以分析当我们添加更多小时的数据时,模型收敛到稳定预测的速度。假设模型在一天结束时是正确的,如果模型在上午 10 点做出同样的预测,那么我们做得很好!下图显示了一天结束时预测与数字相符的比例。这是英国所有日期和地点的汇总数据。
图 6。全天模型的收敛。蓝线表示中间值,蓝色阴影区域表示第 5 到第 95 个百分点。(图片作者本人)
在早晨的早些时候,我们在模型中得到大量的可变性(大的蓝色阴影区域)。在上午 9 点左右,模型性能有一个显著的提高—在大多数情况下,模型在上午 9 点以后不会改变它的分类。回到图 1,我们可以看到学期日的早上高峰在这个时候下降,这似乎是模型能够工作的所有需要。
在工作日开始时,我们可以以 95%以上的准确率识别出是学校假期还是学期时间。

能够在一天的早些时候做出预测意味着我们能够根据是否是学校日或者和对 BBC 的输出做出积极的决定,我们可以在地区层面上这样做!
结论
使用来自 BBC iPlayer 的用户行为数据,我们能够准确预测一天是学校假期还是学期时间。我们可以对历史数据进行这种分析,以分析营销效果,而且通过使用分类指标训练模型,我们能够使用相同的模型进行实时预测。我们还使用了英国国家测绘局的数据来汇总地区数据,进行局部预测。
密码
下面是计算分类指标的代码。主要的函数调用是calculate _ classification _ metric()。
Using user behavioural data from BBC iPlayer we are able to accurately predict whether a day is a school holiday or term-time. We can perform this both on historical data to analyse marketing effectiveness but also, by training a model using the classification metric, we’re able to use the same model to predict in real-time. We’ve also used Ordnance Survey data to allow us to aggregate regional data to make localised predictions.
Code
Below is the code to calculate our classification metric. The main function call is calculate_classification _metric().
def magnitude_of_vector(vector):
"""
Function to calculate the magnitude of a vector
Parameters
----------
vector: 1-d numpy array
vector we want to find the magnitude of
Returns
-------
Magnitude of vector as float
"""
return np.sqrt(np.sum(vector ** 2))
def dot_product(vector1, vector2):
"""
Function to calculate the dot product between 2 vectors.
The dot product is independent of the order of the input vectors.
Parameters
----------
vector1: 1-d numpy array
one of the vectors
vector2: 1-d numpy array
the other vector
Returns
-------
Dot product of the two input vectors as a float
"""
return np.sum(vector1 * vector2)
def angles_in_radians(vector1, vector2):
"""
Function to calculate the angle between 2 vectors.
The angle is independent of the order of the input vectors and
is returned in radians.
Parameters
----------
vector1: 1-d numpy array
one of the vectors
vector2: 1-d numpy array
the other vectors
Returns
-------
Angle between the two input vectors measured in radians
"""
magnitude_x = magnitude_of_vector(vector1)
magnitude_y = magnitude_of_vector(vector2)
dot_product_x_and_y = dot_product(vector1, vector2)
angle_in_radians = np.arccos(dot_product_x_and_y / (magnitude_x * magnitude_y))
return angle_in_radians
def convert_radians_to_degrees(angle_in_radians):
"""
Function to convert an angle measured in radians into degrees.
360 degrees is equivalent to 2pi radians
Parameters
----------
angle_in_radians: float
angle measured in radians
Returns
-------
Angle measure in degrees between 0 and 360.
"""
angle_in_degrees = angle_in_radians / np.math.pi * 180
return angle_in_degrees
def calculate_acute_angle(angle):
"""
Function to convert an angle measured in degrees to an acute angle
(0 < angle < 90 degrees)
For example, 2 vectors that form an angle 135 degrees will be converted
to the acute angle 45 degrees.
Parameters
----------
angle: float
angle measured in degrees
Returns
-------
Equivalent acute angle measured in degrees
"""
acute_angle = (angle > 90) * (180 - angle) + (angle <= 90) * angle
return acute_angle
def calculate_acute_angle(vector1, vector2):
"""
Function to calculate the acute angle between 2 vectors
(0 < angle < 90 degrees).
Taking the acute angle means that we ignore the direction of the vectors
eg. Walking due north is equivalent to heading due south - all we care
about is that your longitude remains constant
Parameters
----------
vector1: 1-d numpy array
one of the vectors
vector2: 1-d numpy array
the other vectors
Returns
-------
Acute angle between the two input vectors measured in radians
"""
angle_in_radians = angles_in_radians(vector1, vector2)
angle_in_degrees = convert_radians_to_degrees(angle_in_radians)
acute_angle = calculate_acute_angle(angle_in_degrees)
return acute_angle
def calculate_classification_metric(
holiday_vector,
termtime_vector,
viewing_vector
):
"""
Function to calculate our classification metric. This is based on the
acute angle that a day's viewing makes with each of our two class-defining
vectors.
If classification_metric < 1/2 -> Holiday
If classification_metric > 1/2 -> Term time
Parameters
----------
holiday_vector: 1-d numpy array
Average viewing during a school holiday
termtime_vector: 1-d numpy array
Average viewing during a school day
viewing_vector: 1-d numpy array
Viewing for the day that we want to classify
Returns
-------
Float between 0 and 1
"""
holiday_angle = calculate_acute_angle(viewing_vector, holiday_vector)
termtime_angle = calculate_acute_angle(viewing_vector, termtime_vector)
classification_metric = holiday_angle / (holiday_angle + termtime_angle)
return classification_metric
预测新加坡 HDB 转售价格:数据准备
原文:https://towardsdatascience.com/predicting-singapore-hdb-resale-price-data-preparation-be39152b8c69?source=collection_archive---------27-----------------------
如何通过必要的特征工程工作来操纵数据集,以便为进一步的分析和建模做准备

由 Unsplash 上的 Muhd Asyraaf 拍摄
在新加坡,对于即将成家立业的年轻上班族来说,当他们的预算有限时,HDB(新加坡公共住房)将是他们的首选。然而,对于那些正在考虑选择哪套 HDB 公寓的人来说,这可能会成为一个真正令人头疼的问题:城镇地区、附近的设施(如学校、购物中心)、公寓类型等。为了让人们在面临如此重大的选择时更轻松,我决定对新加坡 HDB 转售价格进行研究,探索影响 HDB 转售价格的关键因素,并为打算在不久的将来购买 HDB 的人提供一些建议。
了解数据集
可以从 data.gov.sg 的检索到 HDB 的转售数据。以下是原始数据集中可用列的示例:

来自 HDB 转售价格数据集的样本数据(图片由作者提供)
以下是我第一次看这些专栏时的一些第一印象:
月:以年月的格式给出。我们可以从这一栏中检索年数据,这在分析 HDB 转售价格的时间趋势时可能是有用的。
城镇:城镇位置应该是影响 HDB 转售价格的关键因素之一——我们通常认为,在相同户型的情况下,HDB 果园公寓的转售价格要比怡顺公寓高得多。
户型:有 7 种不同的户型:1 室、2 室、3 室、4 室、5 室、EC、多代。其中四房 HDB 公寓是新加坡最受欢迎的公寓。我们可以考虑使用 4 个房间数据样本来构建模型。
楼层范围:该列以字符串而非数字的形式给出,如果我们想用它来建立模型,可能需要做一些相应的数据处理。
平板模型:同样,也有大量不同的平板模型(35 种不同类型)。这一因素将在整体统一价格中发挥重要作用。例如,DBSS(设计、建造和销售方案)公寓会有更高的转售价格,因为它允许买家根据自己的风格设计 HDB。
剩余租期:新加坡 HDB 租期 99 年。此列数据有相当多的空值,并且是根据不同的年份计算的。在构建模型时,我们可能需要相应地调整该列数据。
特征工程
在对数据集有了一些粗略的想法后,我们可能会开始进行数据争论。以下是我为预处理相应的数据列所做的一些特征工程工作:
城镇:为了使用这个数据列作为回归模型的输入,我已经按城镇聚集了数据集,并采用每个城镇的中间转售价格来减去总的中间转售价格。结果(“town_premium”列)可以解释为当他们选择这个位置时需要额外支付的金额。例如,在武吉梅拉赫购买 HDB 公寓平均需要多付 12.8 万英镑,而如果选择武吉潘江地区的 HDB 公寓,则可以少付 5.6 万英镑。

预处理“城镇”列(图片由作者提供)
Flat_Model :对“Flat_Model”栏也做了类似的预处理。如前所述,我们确实看到 DBSS HDB 公寓的转售价格高于平均水平,人们可能需要为这种类型的公寓平均支付约 35K。

我只是简单地从给定字符串中的两个数字中取平均值。例如,对于“04 到 06”的范围,我将只指定楼层为 5。这应该是一个足够好的近似值,因为对于每个类别来说,楼层范围跨度并不是真的更大(3 或 5 层的差异)。

剩余租赁:原始剩余租赁列包含空值,根据取数日期的年份不同,引用到不同的年份。我用以下公式重新计算了转售日的剩余租赁价值:
公式:remain _ lease = lease _ start _ date+99–转售 _ 年
我们能从“街道名”中得到什么?
现在,我们已经预处理了原始数据集中的大多数列。看起来都不错……等等,“街道名称”一栏怎么样?
如前所述,这一栏实际上显示了每个 HDB 公寓的地理位置数据。这实际上是 HDB 转售价格的一个关键因素,因为它会表明 HDB 是否靠近任何捷运站,或者附近是否有任何购物中心。根据我在 HDB 租房的经验,这个信息应该很重要,我相信它也适用于 HDB 的转售价格。
我们可以尝试使用 GoogleMap 或其他可用的地图 API 来提取不同街道名称、捷运站和主要购物中心的经度和纬度。然后我们可以获得从这些街道名称到最近的捷运和购物中心的相对距离,作为转售价格预测的指标。
在做了一些研究后,我注意到 Onemap.sg 提供了一个 API,使用户能够方便地查询给定特定地址的经度和纬度。我编写了一个简单的 python 脚本来使用一个地图 API 查询位置信息。
我们可以做同样的事情来检索新加坡捷运/购物中心的经度/纬度信息。新加坡捷运站列表可在这里找到,新加坡主要商场列表可从这里提取。
我们需要获取的另一条信息是,给定街道名称,哪一个是最近的购物中心/捷运站。我们可以用 for 循环来计算街道名称与每个购物中心/MRT 的相对距离,然后相应地获得最小距离目标。附上示例代码以供参考:
*##Sample Script to obtain the closest shopping mall name given street name*import openpyxl
import numpy as npdef calculate_distance(x,y):
return np.sqrt(((x[0]-y[0])*110.574)**2 + ((x[1]-y[1])*111.32)**2)wb = openpyxl.load_workbook('Street_Name_List.xlsx')
wb2 = openpyxl.load_workbook('Shopping_Mall_List.xlsx')
sheet = wb['Sheet1']
sheet2 = wb2['Sheet1']
for row in range (2, sheet.max_row +1):
Distance = 200
MRT = 0
if sheet['B'+str(row)].value is not None:
for k in range (2, sheet2.max_row + 1):
x1 = sheet['B'+str(row)].value
x2 = float(sheet2['B'+str(k)].value)
y1 = sheet['C'+str(row)].value
y2 = float(sheet2['C'+str(k)].value)
#print (type(x1),type(x2),y1,y2)
Dis_Temp = calculate_distance([x1,y1],[x2,y2])
if Dis_Temp < Distance:
Distance = Dis_Temp
MRT = k
else:
continue
else:
continue
print(MRT)
print(sheet2['A'+str(MRT)].value)
sheet['F'+str(row)].value = sheet2['A'+str(MRT)].valuewb.save('Street_Name_List.xlsx')
print('Job Done.')
如果您一直这样做,现在您应该已经获得了数据集中每个街道名称的封闭 MRT/购物中心名称。有了从 API 查询的所有经度/纬度数据,我们可以很容易地计算出从每条街道到最近的捷运/购物中心的相对距离。为了便于可视化,我将相对距离(公里)转换为从相应街道步行所需的时间(分钟)(1 分钟步行被映射为平均 80 米的距离)。
我能想到的另一个有趣的指标是从最近的捷运站到中央商务区的公共交通出行时间(例如,莱佛士广场捷运站)。这可能是年轻的工作成年人使用捷运作为主要交通工具的一个重要指标,因为在新加坡买车并不是每个人都能负担得起的。
我们可以使用 OneMap API 路由服务来查询公共交通的行驶时间,而不是根据我们自己的估计来计算时间。关于 API 使用的更多细节可以在这里找到。
通过上面提到的所有特征工程工作,我们最终获得了具有以下期望特征的数据集:
(注:步行时间到捷运,步行时间到购物中心和旅行时间到来福士都是以分钟为单位。town_premium 和 flat_model_premium 均以新加坡元为单位)

用于转售价格预测模型的最终数据集(图片由作者提供)
在我们继续建模之前,我们将首先探索更多关于数据集的内容,并从中发现一些有趣的模式。这将在下一篇文章中讨论(见下文)。感谢阅读!
https://medium.com/@tianjie1112/predicting-singapore-hdb-resale-price-eda-and-modeling-94af7d26798d
预测新加坡 HDB 转售价格:EDA 和建模
原文:https://towardsdatascience.com/predicting-singapore-hdb-resale-price-eda-and-modeling-94af7d26798d?source=collection_archive---------18-----------------------
进行 EDA 并尝试不同的 ML 模型来预测转售价格

在 Unsplash 上由迈克·埃尼奥拍摄的照片
在上一篇文章中,我们对新加坡 HDB 转售价格数据集进行了数据辩论,并确定了一些对以后构建模型有用的特征。在继续建模之前,让我们更深入地研究一下数据集,看看是否能找到一些有趣的模式。
对于这个项目,我使用 SAS JMP 软件做数据可视化。对于简单的数据可视化任务,JMP 非常方便,它有一个用户友好的用户界面。你可能想参考他们的官方网站了解更多详情。
HDB 转售价格多年来的总体趋势是什么?
从网站上,我们可以获得从 1990 年到 2018 年的 HDB 转售价格数据。让我们看看中间转售价格的总体趋势是什么:

1990 年至 2018 年新加坡 HDB 中间价(图片由作者提供)
从该图可以看出,HDB 转售价格有两个峰值。第一个高峰出现在 1997 年,随后主要受亚洲金融危机的影响,出现了大幅下降。此后,HDB 转售价格从 2006 年开始再次上涨,并在 2013 年达到新的峰值。随后,HDB 转售公寓的价格再次下降,这与公共住房市场的一系列冷却措施相吻合,如 ABSD 框架。从 2014 年至今,从中间值来看,HDB 的整体转售价格相当稳定。
通过这一分析,我们大致了解了过去 20 年 HDB 转售价格的总体趋势。我们可以观察到,新加坡 HDB 价格可能受政府政策和整体经济趋势的影响很大。
不同的城镇地区有相似的价格趋势吗?
从第一幅图中,我们了解到,从 2014 年到现在,HDB 房价中位数看起来很稳定。这适用于新加坡所有的城镇地区吗?我带着这些疑问,因为我确实注意到一些新闻说中心地区的 HDB 价格达到了近年来的历史最高水平。

按城镇区域划分的 4 室 HDB 公寓转售价格中位数(图片由作者提供)
该图显示了按城镇区域划分的 HDB 4 居室公寓价格中值。可以清楚地看到,2013 年后,HDB 中心区的房价突然上涨,其斜率甚至高于前几年。对于皇后镇、武吉提马、武吉梅拉赫等其他中心地区,转售价格也偏高。对于远离 CBD 的城镇地区(如蔡珠港、三巴旺等),观察到转售价格自 2013 年以来持续下降。
从这个图表中,我们可以看到,即使采取了所有的降温措施,HDB 中心区的转售价格仍然上涨。人们愿意花更多的钱为 HDB 中心区享受它带来的便利。此外,在中心地区建造新的组屋的可用空间非常有限,这也使得中心地区的转售市场比其他地区热得多。对于远离城市的城镇,通常有更多的空间用于新 HDB 公寓,所以人们有更高的机会获得 BTO 公寓,而不是购买转售的 HDB。因此,在采取降温措施后,转售价格往往会下降。
到中央商务区的旅行时间很重要
从前面的分析中,我们可以看出,中心区域具有较高的 HDB 转售价格。一般来说,中心区域意味着更容易到达购物中心和其他设施,更方便的交通等。从不同地点到中心区域的旅行时间如何影响 HDB 转售价格?

4 房间 HDB 从 2010 年至 2018 年,中间转售价格与前往莱佛士广场捷运的旅行时间(图片由作者提供)
从这个图中,我们可以看到 HDB 转售价格和去捷运莱佛士广场的旅行时间之间良好的线性相关性,这也符合我们的预期。如果只考虑到 CBD 地区的旅行时间,有没有什么被低估的城镇位置可以让买家更加关注?

转售价格中值与前往莱佛士广场地铁站的行车时间(图片由作者提供)
这张图表可以让我们了解城镇位置和转售价格之间的关系。对于位于中心区、皇后镇和武吉提马的组屋来说,它们的转售价格通常高于其他旅行时间相似的城镇。换句话说,如果只谈与市中心的相对距离,这些组屋可能定价过高。另一方面,对于那些希望住得离 CBD 更近且预算有限的潜在买家来说,HDB 在 Geylang/Kallang、Serangoon 和 Ang Mo Kio 等地区的公寓可能是一笔不错的交易。这些城镇地区更具成本效益,因为与其他城镇相比,它们的价格更低,与市中心的旅行时间相似(可能高达 20 万英镑)。
为建模选择平面类型
最后但同样重要的是,我绘制了 HDB 转售价格随年份的变化图,按不同的公寓类型划分。

HDB 转售价格与销售年份,按户型划分(图片由作者提供)
毫不奇怪,这一次,我们可以看到,一般转售价格趋势不同的单位类型是相似的。由于我们有足够的数据样本(总共超过 850,000 行数据),我决定选择 4 种房间公寓类型进行建模,因为这是新加坡最受欢迎的公寓类型。此外,我只使用了 2005 年以后的数据样本,因为更新的数据对未来 HDB 转售价格的预测更具代表性和相关性。
建模时间到了!
终于到了激动人心的部分:建模!我们将试用几个模型,并比较每个模型的准确性,更重要的是,讨论为什么某些模型具有更好的性能。
如前所述,我为最终建模选择了 8 个特征。自 2005 年以来的 4 室公寓型 HDB 转售交易数据被用作模型训练和测试的输入数据。

用于转售价格预测模型的最终数据集(图片由作者提供)
线性回归模型
我从线性回归模型开始。线性回归模型的主要优点是需要调整的参数较少,并且结果相对容易解释。对于这个项目,我使用了 sklearn 库,这是当今最流行的数据科学项目工具包。
构建这个模型的代码非常简单,我不会在这里详述太多的细节。所有的源代码都可以在这个链接获得。

线性回归模型(图片作者提供)
这里需要强调的一点是,线性回归函数使用了 R (决定系数)回归评分函数。这使我们能够以百分比的形式直观地显示测试结果。
R 定义为(1 — u/v),其中 u 为残差平方和((y_true — y_pred) ** 2)。sum()和 v 是平方和的总和((y_true — y_true.mean()) ** 2)。sum()。最好的可能得分是 1.0,也可以是负的(因为模型可以任意地更差)。
使用线性回归模型,我从测试数据集中获得了大约 79.7%的准确性,没有任何额外的参数调整。一个很好的开始!

线性回归模型预测值与实际值(图片由作者提供)
这是显示线性回归模型中真实值和预测值的相关性的图表。我们可以看到它们通常遵循线性趋势。我们还可以注意到,30K 到 55K 范围内的点密度更高,从某种意义上说,转售价格数据集也不平衡,更多的交易在 30K 到 55K 转售价格范围内结束。
梯度推进回归模型
虽然 79.7%的准确度是一个好的开始,但是我们能够达到更高的准确度吗?线性回归模型似乎没有太多进一步改进的空间。鉴于我们的数据集本质上是不平衡的,通过进一步的研究,我想起梯度推进回归模型在我们的情况下可能是一个不错的选择。
梯度推进树算法是一种集成学习方法,一次构建一棵树,其中每个新树将对具有较高分类/回归误差的数据样本赋予更多权重。它适用于处理不平衡数据集,在这种情况下,该算法可以将更多的权重放在更难预测的数据样本上。
同样,在 sklearn toolkit 中有一个可用的库,我们可以直接使用。要调整的主要参数如下:
n_estimator —要执行的升压阶段的数量。我们不应该把它定得太高,那会使我们的模型过拟合。
max _ depth 树节点的最大深度。太高会导致过度拟合问题。
learning _ rate 学习数据的速率。
损失—要优化的损失函数。ls '指的是最小二乘回归,类似于我们之前的线性回归模型。

梯度推进回归模型(图片由作者提供)
在训练模型之后,我们使用相同的测试数据集来检查准确性。我们达到了 95.5%的准确率——相当惊人!我绘制了与线性回归模型相同的相关图,很明显,结果有了显著的改善。

梯度推进模型预测与实际(图片由作者提供)
feature _ importances指标表示决定最终 HDB 转售价格的各个特性的权重。据观察,占地面积、距离最近的商场、&、捷运站、和剩余租期对 HDB 转售价格的影响最大(权重均≥ 15%)。到 CBD** 、楼层和城镇位置的出行时间对最终转售价格各有约 10%的影响。最不重要的特征是平板模型类型,它占总转售价格预测值的 5%。**
线性回归与梯度推进回归
我们看到,与线性回归模型相比,梯度推进模型具有非常好的结果,精度提高了约 15%。为什么梯度推进回归模型跑赢线性回归模型那么多?
这表明,从给定的特征来看,应该存在简单线性回归模型不能捕捉的非线性元素。梯度推进树模型使用决策树作为弱学习器。在计算损失后,模型将在每次迭代后选择最小化剩余损失的决策树,以不断提高预测精度。这是纯线性回归模型无法实现的。
虽然 GBR 可以实现更高的预测精度,但它也有比线性回归模型更难解释的缺点。我们只能从上面提到的feature _ importancemetrics中大致了解不同特性的权重。
结论和建议
在这个项目中,我们对新加坡 HDB 转售价格数据集进行了全面的研究。我们已经经历了数据科学项目的数据集预处理、特征工程、数据探索和可视化以及建模阶段。影响 HDB 转售价格的关键因素已经确定。最后,构建了转售价格预测模型的梯度推进模型,预测准确率> 95%。
虽然我们已经达到了很高的预测精度,但也应该注意到,真实的 HDB 转售价格比我们在模型中讨论的要复杂得多。还有许多其他因素,如整体经济状况、政府法规,以及各城镇年轻工作成年人的比例,都可能对最终转售价格产生影响。这些因素可以添加到未来的工作,以进一步改善。
当人们真正考虑购买 HDB 时,他们的优先考虑也因情况而异。例如,对于一对在美光(位于新加坡北海岸)工作的夫妇来说,他们可能会选择在林地或义顺区购买一辆 HDB,离他们的工作地点很近。对他们来说,从家到 CBD 的旅行时间可能不是最重要的,因为大多数时间他们只会呆在北部的邻近地区。
我们还确定了几个城镇位置,如 Kallang,Ang Mo Kio 和 Serangoon,这可能是人们在 CBD 附近寻找低价位的好地方。
再次感谢你关注我的帖子!请在下面留下您的意见和建议。如果你错过了我之前关于数据准备部分的帖子,你可以在下面看看!
https://medium . com/@ tiajie 1112/predicting-Singapore-hdb-转售-价格-数据-准备-be39152b8c69
预测足球排行榜——历史数据是正确的方法吗?
原文:https://towardsdatascience.com/predicting-soccer-league-tables-is-historical-data-the-way-to-go-840e4272f1c4?source=collection_archive---------16-----------------------
对意大利足球联赛(众所周知的意甲联赛)的分析揭示了很多关于体育如何快速变化的事情

利亚姆·麦凯在 Unsplash 上的照片
本文是对 2020-21 赛季意大利甲级联赛的简单预测,从 2021 年 2 月开始。虽然赛季已经结束了,但是我们可以比较一下实际的联赛结果,看看它们和我所做的预测相比如何。用于预测的方法是逻辑回归和随机森林的组合,以及交叉验证数据的 K 倍。作为初学者,我会在整篇文章中强调我犯的一些错误。分析的主要思想是看历史数据为什么不应该是用于体育预测的唯一工具。
我从高中起就喜欢足球,在接触到数据科学世界后,我想知道是否有一种方法可以预测它。当然,俱乐部足球队一直在更换球员和教练,但应该有一些历史因素让我们看到一种趋势,对吗?
足球在一些联赛中竞争非常激烈,而在另一些联赛中却很容易预测。例如,在德国,俱乐部球队拜仁慕尼黑已经连续赢得 9 个联赛冠军,而在英格兰超级联赛中,5 个不同的球队在过去十年中赢得了联赛冠军。我选择分析意甲,因为尽管他们与德国联赛相似(尤文图斯俱乐部队也赢得了 9 个联赛冠军),但 2020-21 赛季正在改变这种君主制。
数据的预查看:

作者图片
我首先做的是,获取从 2010 年到 2021 年的所有 CSV 文件,并将它们合并到一个 CSV 文件中,同时将文件名设为季节年:
***# combine all season files into 1* if** (os**.**path**.**isfile('data.csv')):
os**.**remove('data.csv')
extension **=** 'csv'
all_filenames **=** [i **for** i **in** glob**.**glob('*.{}'**.**format(extension))]***# add a "season" column to distinguish year, and combine all files in the list*** combined_csv **=** pd**.**concat([pd**.**read_csv(f)**.**assign(Season**=**os**.**path**.**basename(f)**.**split('.')[0]) **for** f **in** all_filenames])
*#export to csv*
combined_csv**.**to_csv("../data.csv", index**=**False, mode**=**'w+', encoding**=**'utf-8-sig')
您在互联网上找到的大多数足球数据都有与此数据相同的列。我们将首先删除“AR”之后的所有列,因为这些都是“投注列”,这意味着它们是来自不同流行投注公司的获胜概率。
为了增加数据清理,我还为半职和全职结果列创建了虚拟变量。为了让它代表一个真实的足球联赛表,我将输转换为 0,平转换为 1,赢转换为 3。这与实际的排名表以这种方式表示一样,因为游戏结果准确地反映了一支球队得到的分数:
***# create dummies for half-time and full-time scoreline details*** cleanup_TR **=** {"HTR": {"H": 3, "D": 1, "A": 0},
"FTR": {"H": 3, "D": 1, "A": 0}
}
在此之后,以下是其余各列及其描述(我们将使用全职结果作为此分析的相关变量):
我做的下一件事是通过绘制一些直方图找到相关性。我在这里没有发现太多,除了主场命中率相当稳定,而客场命中率变化更大。这意味着,如果一个主队和一个他们知道不会击败他们的队比赛,他们会感到更舒服,他们应该有机会赢得比赛。如果他们在同样的情况下,但是在客场比赛,他们可能不会投出他们想要的那么多。
在这之后,我给了每个主场球队一个数字指数,这样我们就可以在最后调整预测,给正确的球队分配分数。请注意,这里有 35 支球队,因为在欧洲足球队中,如果他们是当年联赛中最差的三支球队之一,就会被降级。这是索引:
现在到了有趣的部分,建模!

由维也纳雷耶斯在 Unsplash 上拍摄的照片
**import** os
**import** glob
**import** pandas **as** pd
**import** pandasql **as** psql
**import** numpy **as** np
**import** matplotlib.pyplot **as** plt
**import** seaborn **as** sn
**from** sklearn.preprocessing **import** OrdinalEncoder
**from** sklearn.model_selection **import** train_test_split
**from** sklearn.model_selection **import** KFold
**from** sklearn.model_selection **import** GridSearchCV
**from** sklearn.linear_model **import** LogisticRegression
**from** sklearn.metrics **import** accuracy_score
**from** sklearn.metrics **import** cohen_kappa_score
**from** sklearn.metrics **import** make_scorer
**from** sklearn.ensemble **import** RandomForestClassifier
**from** sklearn **import** preprocessing
在使用 python 时,我首先尝试了一种逻辑回归,并使用了多项式逻辑回归(在 Python 中也称为 softmax 回归),因为这种变体可以有两个以上的类。
***# declare independent and dependent variables, and remove categoric variables***
y **=** df["Full_Time_Result"]
X **=** df**.**drop(["Season", "Match_Date", "Home_Team", "Away_Team", "Full_Time_Result"], axis**=**1)
***# declare training splits***
X_train, X_test, y_train, y_test **=** train_test_split(X, y, test_size**=**0.4, random_state**=**9)
***# standardize the variables using regularization*** scaler **=** preprocessing**.**StandardScaler()**.**fit(X_train)
X_train **=** scaler**.**transform(X_train)
X_test **=** scaler**.**transform(X_test)
***# data/use softmax regression with ridge regression instead of lasso (because dependent variable has 3 possibilities)*** softmax_reg **=** LogisticRegression(random_state**=**0, multi_class**=**"multinomial", solver**=**"saga", penalty **=** 'l2', C **=** 0.01)
softmax_reg**.**fit(X_train, y_train)
然后我做了一个预测:
***# create a prediction of y values based on model*** y_pred **=** softmax_reg**.**predict(X_test)
我用了三种不同的方法来看我的预测结果
- 准确性得分-这衡量预测值与实际值之间的差距
- 基线精度-这种测量找到最差的可能精度
- Cohen 得分-这是针对预测值来衡量数据集中的随机性
***#find model accuracy from test data*** acc_score **=** accuracy_score(y_test, y_pred)
print(acc_score)***#find the worst possible accuracy*** baseline_acc **=** len(y[y **==** 0]) **/** len(y)
print(baseline_acc)***#find cohens score; higher score represents less randomness in dataset out of 1*** cohens_score **=** cohen_kappa_score(y_test, y_pred)
print(cohens_score)
准确度= 0.900373599003736
基线= 0.2999501743896363
科恩的= 0.84888888881
这些值表明 softmax 回归相对准确,基线准确性相对较低,并且我们的预测值与实际值相比随机性较低。
在此之后,我制作了一个直方图,以查看每个类别的特征重要性,用于 softmax 回归:

作者图片
正如我们所见,根据 softmax 回归,最重要的变量是全职主客场目标。出于分析的目的,我们可以选择忽略这一点,并看到半场结果与全职结果密切相关,主客场射门也是如此,客场球队的红牌和犯规也是影响结果的少数因素。似乎有一种对主队类别的偏见,因为大多数客场类别被视为不太重要。
我继续在随机森林中运行预测,看看它与 softmax 回归相比如何:
***#use random forest now to do the same thing as logistic regressionl, see if there are any imporvements*** rand_forest **=** RandomForestClassifier()
rand_forest**.**fit(X_train, y_train)
y_pred **=** rand_forest**.**predict(X_test)
acc_score **=** accuracy_score(y_test, y_pred)
baseline_acc **=** len(y[y **==** 0]) **/** len(y)
cohens_score **=** cohen_kappa_score(y_test, y_pred)
print(acc_score, baseline_acc, cohens_score)
准确度= 0.9906600249066002
基线= 0.2999501743896363
科恩的= 0.98083868686
就准确性而言,随机森林的结果更好,科恩的分数似乎显示出更少的随机性。让我们看看特性的重要性:

作者图片
根据随机森林模型,大多数特征都是相同的,但对客场球队类别的偏见较少。由于这种偏差的减少和更好的准确性,我使用这个模型向前发展。
该模型的最后一步是使用 K-folds 技术交叉验证随机森林模型。这种交叉验证方法通常用于较小的数据集,它基本上多次运行模型,每次使用不同的数据拼接,并取这些伪模型的平均值。代码如下:
***#use K-folds for cross-validation on the random forest model*** fold_perf **=** []
kf **=** KFold(n_splits**=**6, shuffle**=True**)
**for** train_index, test_index **in** kf**.**split(X):
X_train, X_test **=** X**.**iloc[train_index], X**.**iloc[test_index]
y_train, y_test **=** y**.**iloc[train_index], y**.**iloc[test_index]
rand_forest **=** RandomForestClassifier()
rand_forest**.**fit(X_train, y_train)
y_pred **=** rand_forest**.**predict(X_test)
acc_score **=** accuracy_score(y_test, y_pred)
fold_perf**.**append(acc_score)
plt**.**plot(fold_perf)
为了查看这是如何工作的,我们可以绘制这 5 个伪模型的准确度分数:

作者图片
我们的最后一步是调整超参数。我使用了一个标准的超参数网格来寻找随机森林模型的最佳“树”数量和深度:
***#create hyperparameters in order to cross-validate the model*** hyperparam_grid **=** {'n_estimators': [3, 100, 1000],
'max_features': [0.05, 0.5, 0.95],
'max_depth': [10, 50, 100, **None**]}
grid_scorer **=** make_scorer(cohen_kappa_score)
rand_forest **=** GridSearchCV(RandomForestClassifier(), hyperparam_grid, cv**=**kf, scoring**=**grid_scorer)
rand_forest**.**fit(X, y)
结果是:
{'max_depth': 100, 'max_features': 0.5, 'n_estimators': 100}
最后,我运行新拟合的随机森林来获得我的预测,并附加 x_pred 和 y_pred(也称为“点”)来获得新的预测数据集。它看起来像这样:

作者图片
最后是结果!

左:实际的 2020–21 意甲联赛排名表| … |右:预测的 2020–21 意甲联赛排名表(图片由作者提供)
正如你所看到的,排行榜看起来非常不同…那么,我的预测是错误的吗?
事实上,体育在不断变化,没有人能预测到国际米兰会仅凭数据赢得今年的联赛冠军。这是一支自 2009-10 赛季以来从未赢得过联赛冠军的球队(尽管那一年相当传奇),甚至直到最近才进入前四。
这向我们表明,对足球的纯粹历史观点可能不会产生最好的结果,我们可能需要更多地基于形式(一支球队目前的表现)来分析这个问题,并可能纳入花在球员身上的钱,或俱乐部经理的胜率,以获得更好的预测。
我使用了两种相对简单的方法来预测联盟排名,但是我也询问其他人来尝试一下。我很想知道你会选择包括哪些其他数据,或者你会选择使用哪些其他模型。
来源:
https://github.com/kingazaan/serie_a_analysis
预测足球队实力-第二版
原文:https://towardsdatascience.com/predicting-soccer-team-strength-version-ii-11b5c66cf9d8?source=collection_archive---------21-----------------------
最好的足球队花费最多的钱(并且平衡他们的账目!)在转会窗口期间

蒂姆·贝彻维斯在 Unsplash 上的照片
目录
简介——亿万富翁的运动
曼城的转会支出
SPI 得分&数据来源
我的第二次,也是更好的一次,尝试
FuzzyWuzzy &团队名称
黄砖可视化算法
沙普利值为可交代值
结论
介绍
如果国际象棋是国王的游戏,足球就是亿万富翁的运动。
2021 年 2 月,年轻的亿万富翁凯里尔·路易斯-德雷福斯购买了桑德兰亚足联的控股权。
桑德兰是英格兰足球中最富传奇色彩的球队之一,拥有 142 年的历史,其球迷群体充满了浪漫的激情,这在纪录片系列桑德兰直到我死中得到了最好的体现。他们有多个顶级联赛冠军,但自 20 世纪 30 年代以来没有一个;他们赢得了英格兰足球协会的冠军,但自 20 世纪 70 年代以来还没有。尽管过去几十年很艰难,桑德兰亚足联目前拥有英格兰足球历史上第六多的冠军,仅次于英超联赛中一些最好的球队。
如果他们的早期历史是“光辉岁月”的定义,那么最近几年就是“磨砺”的缩影,一季又一季,除了看守经理的旋转栅门之外,没有什么可展示的。自 2015 年以来,桑德兰亚足联已经有了八位不同的经理,不包括在管理层变动期间介入的助理,他们平均每场执教 36 场比赛。英甲赛季有 46 场比赛。
一个亿万富翁究竟为什么要收购一家在过去几个赛季经历了如此多动荡的俱乐部?因为足球,尽管有着浪漫主义和后来居上的冠军联赛决赛,却是一场资产游戏。有一家俱乐部目前比所有其他俱乐部都“升值”得更好,而且做得很有风格。
曼城的转会支出
曼城由阿联酋王室经营的企业集团所有,是全球范围内的顶级俱乐部。在谢赫曼苏尔于 2008 年收购这家俱乐部之前,它并不总是如此,而是一家中游球队。谢赫曼苏尔作为新老板的第一个关键决定是指定资金从其他顶级俱乐部引进高质量的球员,不管俱乐部的收入如何。在前两个赛季,曼城在新球员上花费了近 3.77 亿€。仅在 2010 年,俱乐部就花费了近 1.2 亿€;他们还将球员分流到其他球队,使他们的下一步支出降低到只有€8500 万英镑。
这种在转会窗口投入巨资引进球员的策略已经在价值和奖杯的显著增长上取得了回报。2008 年之前,这家俱乐部每年从€带来 9000 万英镑到€1 亿英镑的收入。仅仅六个赛季,€的收入翻了两番,达到 4 亿多英镑。自 2008 年以来,该队已经赢得了五次英超联赛冠军,两次足总杯冠军,六次 EFL 杯冠军,三次足总社区盾杯冠军。尽管他们在 2020-2021 年进入决赛,但俱乐部唯一没有获得的主要冠军是欧洲冠军联赛冠军。
曼城现在身价 11 亿€,通过在设施、体育场和管理上的投资,尤其是在球员上的投资,已经经历了一次彻底的转变。火车没有减速的迹象。就在上周,俱乐部完成了引进杰克·格里利什的交易,他是维拉队的顶级前锋。费用?近€1.2 亿英镑,这是为英国球员支付的最高金额。
这就引出了我的问题——转会活动对一个团队的实力有多大影响?如果曼城花钱引进球员,并且看到了回报,那么这笔转会支出的哪些方面对他们作为俱乐部的实力最有影响。虽然有很多因素会影响一个球队在球场上的表现,但一个俱乐部的球员肯定有更大的影响。
我以前回答过这个问题,在早期的一个项目中,我在跳板数据科学赛道上用它作为顶石。点击可查看中帖原文。
数据源和 SPI 分数
在第二次尝试中,我使用了相同的数据来源;从 Ewenme 的仓库 &传送数据,从 FiveThirtyEight 传送 SPI 团队实力数据。
转会库包括世界各地俱乐部之间的每一次转会,其中有大量关于所涉球员的重要信息——年龄、费用和位置,等等。我选择了从 2016 年到 2020 年的 9 个欧洲顶级联赛。
FiveThirtyEight 的 SPI 得分是使用涉及进球得分和进球对抗的比赛时间数据计算的,可以追溯到 2016 年。这些数据点然后被加权并给出一个分数,该分数用于根据整体实力对团队进行排名。点击阅读更多关于 SPI 分数的信息。
足球队实力建模,第二版
在我第一次尝试模拟足球队实力时,我将我的数据局限于过去五个赛季的英超球队。这是我的第一个项目,我很紧张。但在第一次尝试后的几个月里,我对算法有了更多的了解,知道如何解释它们的可预测性,我已经准备好再次尝试了!
对于这个项目的第二个版本,我致力于回到我最初的工作并扩展我的视野。我做了以下事情:
- 我使用了一个更大的数据集,涵盖了欧洲九个职业联赛的五个赛季。这使我的最终数据集从 100 行增加到 700 多行。
- 我使用 FuzzyWuzzy 包来标准化球队和联盟的名字。在我看来,这是一个有意义的改进,我将在下面详细解释。
- 虽然我探索了许多我在第一个版本中使用的相同算法,但我使用了 Yellowbrick 来更好地理解算法显示了什么。
- 我超调了最佳随机森林回归的参数,将我的 R 分数提高了 50%以上,从 0.41 提高到 0.65。
- 我使用 SHAP 值来解释数据集特性对模型的影响,并确定各级团队在制定转移策略时要考虑的重点领域。
我想快速指出的是:我的结论并不完全是革命性的。他们可能已经是每个顶级俱乐部战略的重要组成部分。对于那些试图改善他们的战略,或者试图了解他们在每个赛季的转会窗口中哪里出了问题的俱乐部来说,这里可能有一两个有用的分析。
使用 FuzzyWuzzy 来标准化团队名称
当我把其他联赛加入到数据集中时,我害怕这个项目的这一部分。我有两个数据集,每个都有不同的球队命名规则,但是在这个版本的项目中,我有九个联赛的名字,而不仅仅是英超联赛。在版本 I 中,我分别获取每个数据集,根据它们的唯一值创建了一个团队名称字典,并向数据集添加了一个新列,其中包含我在两个数据集上使用的名称的缩写。
甚至打出解释也比它应该做的要多。
在版本 II 中,我使用 FuzzyWuzzy 库来标准化名称。我仍然单独处理每个数据集,但是使用这个对我来说新的库比为每个数据集的每个联盟创建单独的字典(或者两个巨大的字典)要容易得多。
对于那些对 FuzzyWuzzy (文档)不熟悉的人来说——它接受两个字符串,将它们匹配,并提供一个相似性得分。
例如:
Str_A = 'FuzzyWuzzy' solves problems!'
Str_B = 'fuzzy wuzzy solves PROBLEMS.'ratio = fuzz.ratio(Str_A.lower(), Str_B.lower())
print('Similarity score: {}'.format(ratio))
这将返回 95 的相似性分数。
除了使用ratio()函数之外,FuzzyWuzzy 还使用函数来标记字符串并在运行之前操作它们。使用 FuzzyWuzzy ,我创建了一个函数来比较我的每个数据集中的团队名称,使用其中一个作为基本名称,另一个作为比较,并根据比率分数来标准化它们。它返回了一个字典,我用它来替换两个数据集中的团队名称,而且比我解决这个问题的版本 1 快得多!
使用黄砖来可视化算法
在每个项目的 EDA 步骤中,我都有用于可视化数据的自定义函数,但是我真的很想看看这个模型告诉我关于测试算法的什么信息。YellowBrick 为用户提供了一系列看似无穷无尽的可视化效果,我建议查看该项目的文档。
我保持事情相当简单,并使用残差图和预测误差图来可视化每个算法。

使用黄砖绘制残差图和精度误差图——来自我的 Jupyter 笔记本
解释可预测性的 Shapley 值
我以前用过沙普利值,SHAP 项目是我探索过的最有趣的项目之一。构建shap库的优秀人员非常聪明,他们开发了代码,使用博弈论概念以清晰、有意义的方式解释特性的重要性。
几个例子向您展示 shap 库可以做什么。
首先,看一下蜂群图,它显示了每个特性的值对模型的影响。在我的项目中,最有影响力的特征是average_fee_spend,一个足球队在每个转会窗口花费在俱乐部转会上的平均金额。蜜蜂群显示的是,虽然平均费用支出具有很高的影响力,但当他们的平均费用支出非常高时,这是最积极的影响,可以提高团队的实力。

SHAP 重视蜂群图——来自我的笔记本
有趣的是,如果你向下看图表中total_transfers_in和total_transfer_out处的一些特征,你会发现这些特征的高值对团队的实力有更负面的影响。大量的转会活动,无论是进是出,对俱乐部都没有好处。将他们的努力集中在每个赛季内外人数较少的球员身上,对他们的赛季实力有更有利的影响。我想不出比这更清楚的图表了,对于机器学习和预测分析的新手来说,shap蜂群图非常有帮助。
这里有两个非常酷的 shap 可视化,显示了每个特性的价值对特定团队实力的影响。

从我的 Jupyter 笔记本来看,在转会窗口期间花费的非常低的平均费用对这支球队的实力产生了显著的负面影响
要了解这个瀑布,先看看右下角。根据最终的随机森林模型,E[f(x)]是数据集的基准强度得分。在图表的左侧,您可以看到该特定团队在特定赛季中各项功能的价值。在这种情况下,俱乐部在转会上花费的极低的平均费用产生了巨大的负面影响,从基线实力得分降低了近 10 分。他们也没有在任何一个球员身上花费太多,这对他们的实力有另一个很大的负面影响。
这是一支更强的队伍。

更高的平均费用支出,大约 450 万欧元,导致这支球队的实力增加了近 10 个百分点——从我的 Jupyter 笔记本上看
很容易看到平均花费很多和在单个球员身上花费很多对球队整体实力的积极影响。仅这两个特征值就让这支队伍的实力提高了 17 分以上!
结论
- 首先,返工以前的项目是非常有趣的,尤其是在尝试新的库、新的算法和新的技术的时候。
- 第二,球队每个赛季都可以通过平均多花钱,单个球员多花钱来提升实力。
- 第三,总的来说,虽然花钱对球队的实力有很大的增加,但通过交易球员来赚钱也是如此。如果一个俱乐部不能花很多钱,他们应该努力赚很多钱。这在很大程度上是南安普顿留在英超联赛的原因。
- 第四,如果我再次尝试这个项目(我会的,因为我喜欢它),我会选择一些影响较小的功能,看看我是否能消除一些噪音。
- 第五,Kyril Louis-Dreyfus 正在执掌一家需要重新启动的传奇俱乐部,如果他能够用足够的自有资金进行转会,他可能会看到这家俱乐部重返荣耀,并提高其整体价值。
如果你做到了这一步,非常感谢你的阅读。检查一下整个库,看看我的网站上我参与的其他项目。如果你对这个分析有任何补充,或者注意到我犯的任何错误,请告诉我。如果你拥有一支足球队,准备好在夏季转会窗口上花大钱吧!
汤姆的 Github
预测 Spotify 上的歌曲跳过
原文:https://towardsdatascience.com/predicting-song-skipping-on-spotify-eb5bfbae4c0b?source=collection_archive---------52-----------------------
使用 LightGMB 仅基于音频特征来预测我的歌曲跳过习惯

图片由 https://unsplash.com/@omidarmin奥米德阿明T2 拍摄
介绍
2019 年初,Spotify 分享了关于他们平台的有趣统计数据。在该服务的 3500 多万首歌曲中,Spotify 用户创建了超过 20 亿个播放列表(Oskar Stå,2019)。我想到了一个类比,我们的音乐品味就像我们的 DNA,在 70 亿人中非常不同,但构建模块(核苷酸/歌曲)是相同的。因此,推断用户的音乐品味颇具挑战性,主要是因为 Spotify 的商业模式依赖于其推荐新歌的能力。
问题陈述
Spotify 没有不喜欢按钮,所以跳过歌曲是我们需要从中学习来推断音乐品味的微妙线索。在这个项目中,我使用我在 2019 年的 Spotify 流媒体历史来建立一个预测模型,该模型可以预测我是否会仅根据他们的音频特征跳过一首歌。
您可以按照以下步骤请求自己的 Spotify 流媒体历史记录
数据描述
在请求我的 Spotify 数据后,我收到了一封电子邮件,其中有一个 ZIP 文件,包含我在 2019 年听的每首歌,艺术家的名字和流媒体时长。数据处理如下:
- 我过滤掉播客,只分析歌曲。
- 我使用 Spotify API 提取歌曲的唯一 id 及其音频特征。
- 我计算了我播放歌曲的时长和歌曲长度之间的差距。如果间隔超过 60 秒,那么我将推断该歌曲已经被跳过。
下面是这些步骤的详细 python 实现
因为声明是为了寻找是否只有音频特征可以通知我们跳过歌曲,所以我删除了包含歌曲标题和艺术家的列。
最终数据集包含以下各列:

假设
建模的一个关键步骤是列出所有的假设和限制,以便正确地解释结果。一些假设源于数据收集过程,另一些则是建模过程的一部分:
- 用户的音乐品味是同质的,即,引导用户跳过歌曲的机制在时间上是静态的。
- 歌曲被分解成音频特征,因此歌词不被解释为自然语言文本。考虑这种限制是很重要的,因为歌词的含义可能是跳过歌曲的一个强有力的预测因素。
建模
我使用 LightGBM 二进制分类,仅基于音频特征来推断我的跳歌习惯。

混淆矩阵
贝叶斯优化
LightGBM 包含许多参数,因此,我没有遍历所有可能的值,而是使用贝叶斯优化进行超参数调优

结果和讨论
该模型对个性化数据的性能更好,准确率为 74.17%(贝叶斯优化的第 28 次迭代)。Spotify 用户同质的假设是一个强有力的假设,如果我们收集更多的用户级细节,性能可以得到改善。
总的来说,推荐引擎既需要对用户的个性化学习,也需要对歌曲的一般性学习。在这个项目中,我实验了仅使用音频特征、音频和用户特征以及我个人的收听历史的机器学习分类。进一步的调查可能包括协变量之间的因果关系,因为理解数据生成的机制可能比曲线拟合更能提供信息。
https://github.com/Tahahaha7/Spotify_Skip_Prediction
参考
- 奥斯卡·斯托尔(2019 年)。Spotify 上的音乐推荐。北欧数据科学和机器学习峰会。检索自:https://youtu.be/2VvM98flwq0
- 布莱恩·布鲁斯特、里沙布·梅赫罗特拉和特里斯坦·杰汉。2019.音乐流会话数据集。在 2019 年 5 月 13 日至 17 日在美国加利福尼亚州旧金山举行的 2019 年万维网大会(WWW '19)的会议录中。美国纽约州纽约市 ACM,7 页。https://doi.org/10.1145/3308558.3313641
预测 Spotify 歌曲的受欢迎程度
原文:https://towardsdatascience.com/predicting-spotify-song-popularity-49d000f254c7?source=collection_archive---------16-----------------------
意见
使用 PyCaret 对每个机器学习算法进行排序,以建立最佳数据科学模型。

Cezar Sampaio 在Unsplash【1】上拍摄的照片。
目录
- 介绍
- 模型比较
- 摘要
- 参考
介绍
因为 Spotify 和其他音乐流媒体服务非常受欢迎,并且被广泛使用,所以我想将数据科学技术和机器学习算法应用到该产品中,以预测歌曲的受欢迎程度。我个人使用这个产品,我在这里应用的也可以应用于其他服务。我将检查每一种流行的机器学习算法,并根据成功的衡量标准或标准选择最佳算法——通常,这是某种计算误差。所开发的最佳模型的目标是基于各种特征当前和历史特征来预测歌曲的流行度。如果你想学习如何使用数据科学来预测一首歌曲的流行程度,请继续阅读。
模型比较

照片由马库斯·斯皮斯克在Unsplash【2】上拍摄。
我将讨论我使用的 Python 库,以及下面的数据、参数、比较的模型、结果和代码。
图书馆
使用py caret【3】的力量,你现在可以测试每一个流行的机器学习算法彼此之间的对比(至少或更多)。对于这个问题,我将比较 MAE、MSE、RMSE、R2、RMSLE、MAPE 和 TT(Sec)——完成模型所需的时间。正如开发人员所说,总体来说,使用 PyCaret 的一些好处是提高了生产率、易用性和业务就绪性——所有这些我都可以亲自证明。
数据
我正在使用的数据集来自 Kaggle。可以方便快捷的下载。它由 17MB 和 Spotify 从 1921 年到 2020 年的数据组成,包括 16 万多首歌曲。它由174,389行和19列组成。下面是前几行和前几列的屏幕截图:

数据样本。作者截图[5]。
列:
在我们最终选择了最佳模型之后,我们可以看看最重要的特性。我正在使用 PyCaret 的interpret_model()功能,它基于流行的 SHAP 库。以下是所有可能的功能:
['acousticness',
'artists',
'danceability',
'duration_ms',
'energy',
'explicit',
'id',
'instrumentalness',
'key',
'liveness',
'loudness',
'mode',
'name',
'popularity',
'release_date',
'speechiness',
'tempo',
'valence',
'year']
以下是使用 SHAP 最重要的功能:

SHAP 很重要。作者截图[6]。
所有的列都被用作特性,除了目标变量,它是列popularity。如你所见,前三个特征是年份、乐器性和音量。作为未来的改进,最好是将分类特征分成一列,而不是几十列,然后作为下一步,将分类特征输入到 CatBoost 模型中,以便可以应用目标编码而不是一热编码——为了执行此操作,我们将确认或更改key列为分类列,并用于任何其他类似的列。
因素
这些是我在 PyCaret 的setup()中使用的参数。机器学习问题是一个回归问题,包括来自 Spotify 的数据,其中target变量是popularity字段。为了重现性,可以建立一个session_id。还有很多参数,但这些是我使用的参数,PyCaret 在自动检测数据信息方面做得很好——比如挑选哪些特征是分类的,它会在setup()中与您确认这一点。
比较的型号
我将比较 19 种机器学习算法,有些非常流行,而有些我实际上没有听说过,所以看看哪个在这个数据集上胜出会很有趣。对于成功标准,我比较了 PyCaret 自动排名的所有指标 MAE、MSE、RMSE、R2、RMSLE、MAPE 和 TT (Sec)。
这里是我比较过的所有型号:
- 线性回归
- 套索回归
- 里脊回归
- 弹性网
- 正交匹配追踪
- 贝叶斯岭
- 梯度推进回归器
- 极端梯度推进
- 随机森林回归量
- 决策树回归器
- CatBoost 回归器
- 光梯度推进机
- 额外树回归量
- AdaBoost 回归器
- k 邻居回归量
- 拉索最小角度回归
- 胡伯回归量
- 消极进取回归者
- 最小角度回归
结果
需要注意的是,我只是使用了数据的一个样本,所以如果你自己测试这个代码,使用所有的数据,这些算法的顺序可能会重新排列。我只使用了1,000行,而不是全部的~170,000行。
可以看到,CatBoost名列第一,拥有最好的 RMSE、RMSE、R2。然而,它没有最好的 MAE、RMSLE 和 MAPE,也不是最快的。因此,您应该根据这些指标来确定成功的含义。例如,如果时间很重要,那么你会希望排名更高,或者如果 MAE 更高,你可能会选择Extra Trees Regressor来获胜。

车型对比。作者截图[7]。
总的来说,你可以看到,即使只有很小的数据集样本,我们也做得很好。popularity目标变量的范围是 0 到 91。因此,以 MAE 为例,我们的平均误差是 9.7 个流行度单位。考虑到我们平均最多只差 10 分,91 分中这还不算太坏。然而,训练算法的方式可能不会很好地推广,因为我们只是使用一个样本,所以你可以预期所有的误差指标会显著减少(这是好的),但不幸的是,你会看到训练时间急剧增加。
PyCaret 的一个巧妙特性是,您可以在compare_models()训练中删除算法——我会从数据集的一个小样本开始,然后查看哪些算法通常需要更长时间,然后在您与所有原始数据进行比较时删除这些算法,因为其中一些可能需要几个小时来训练,这取决于数据集。
在下面的截图中,我打印了带有预测值和实际值的数据框。比如我们可以看到popularity或原与Label并排比较,就是预测。你可以看到一些预测比其他的更好。最后一个预测相当差,而前两个预测很棒。

预测。作者截图[8]。
密码
以下是 Python 代码,您可以尝试通过导入库、读入数据、对数据进行采样(仅当您需要时)、设置回归、比较模型、创建最终模型、进行预测以及可视化要素重要性来测试自己[9]:
# import libraries
from pycaret.regression import *
import pandas as pd# read in your stock data
spotify = pd.read_csv(‘file location of your data on your computer.csv’)# using a sample of the dataset (you can use any amount)
spotify_sample = spotify.sample(1000)# setup your regression parameters
regression = setup(data = spotify_sample,
target = ‘popularity’,
session_id = 100,
)# compare models
compare_models()# create a model
catboost = create_model('catboost')# predict on test set
predictions = predict_model(catboost)# interpreting model
interpret_model(catboost)
摘要

照片由布鲁斯·马尔斯在Unsplash【10】上拍摄。
使用数据科学模型来预测一个变量可能会非常困难,但我们已经看到了如何通过几行代码来有效地比较几种机器学习算法。我们还展示了设置不同类型的数据是多么容易,包括数字和分类数据。在接下来的步骤中,我将把它应用到整个数据集,确认数据类型,确保删除不准确的模型,以及训练时间过长的模型。
总之,我们现在知道如何执行以下操作来确定歌曲流行度:
import librariesread in datasetup your modelcompare modelspick and create the best modelpredict using the best modelintepret feature importance
我要感谢和钦佩 Moez Ali 开发了这个令人敬畏的数据科学库。
我希望你觉得我的文章既有趣又有用。如果您将这个库应用于数据集或者使用了其他技术,请在下面随意评论。你更喜欢哪一个?你对自动数据科学有什么看法?
我与这些公司都没有关系。
请随时查看我的个人资料和其他文章,也可以通过 LinkedIn 联系我。
参考
[1]照片由 Cezar Sampaio 在Unsplash(2020)上拍摄
[2]马库斯·斯皮斯克在 Unsplash 上拍摄的照片(2020 年)
[3] Moez Ali ,PyCaret,(2021)
[4] Yamac Eren Ay on Kaggle, Spotify 数据集,(2021)
[5] M.Przybyla,数据框架截图,(2021 年)
[6] M.Przybyla,SHAP 特征重要性截图,(2021)
[7] M.Przybyla,模型对比截图,(2021 年)
[8] M.Przybyla,预测截图,(2021 年)
[9] M.Przybyla,Python 代码,(2021 年)
[10]布鲁斯·马斯在 Unsplash 上拍摄的照片,(2018)
预测星巴克的选址策略:第二部分
原文:https://towardsdatascience.com/predicting-starbucks-location-strategy-part-2-c8803008f42c?source=collection_archive---------19-----------------------
改进对完美星巴克位置的搜索

图片由作者提供;北卡罗来纳州夏洛特
在我写的所有文章中,最受欢迎的是一篇关于分析和预测星巴克选址策略的文章。在这篇文章中,我讨论了数据驱动框架选择新位置的两种可能方法。这篇文章的关键是确定企业目标市场的构成,并寻找与该构成相匹配的领域。我们可以使用来自业务相关人员的反馈进行定性分析(“我们希望目标人群大于…且收入大于…”或者当有足够的样本量进行分析时进行定量分析(例如找到与星巴克门店位置相关的人口统计数据)。
自从发表了这篇文章,我已经和一些企业家一起工作,并且改进了最初提出的方法。一种方法是从静态的 R 视觉过渡到交互式的动态 Tableau 仪表板。在本文中,我写了关于方法的更多细节。
在这项工作的基础上,最近的另一项改进是引入了一种强有力的竞争观。在关于我如何在一家初创公司使用星巴克定位框架的对话中,我发现了如何有效地使用 Google Places API 。我们可以像使用谷歌地图搜索一样使用 API。
例如,假设我们在北卡罗来纳州罗利市中心,想喝咖啡。我们可以去谷歌地图,移动地图到我们想要的地方,然后搜索“咖啡店”得到下面的结果。我们将看到所有当地的咖啡店以及一些关于它们的识别信息。

作者图片
有了 Google Places API,我们可以做同样的事情。我们可以通过纬度和经度来定义我们的搜索区域,输入一个搜索词,几个附加参数,然后根据这些参数得到一组结果。使用最初 Starbucks 分析的工作,我将在此基础上展示如何添加竞争组件来扩展和改进工作的第一个版本。
作为演示这种方法的一个例子,我选取了大约 500 个最有可能有星巴克的邮政编码——但在分析时没有——并提取这些邮政编码及其周围的竞争对手信息。本文的其余部分将详细说明我们可以检索哪些信息,以及如何将其用于位置扩展机会。
提高位置分析的竞争
请继续关注未来关于如何使用 Google API 的文章(现在可以在这里找到!),但首先让我们讨论一下我们可以通过这种新方法收集的数据,以及我们如何使用它来改进我们的位置模型。
从上面提到的大约 500 个邮政编码开始,在只过滤了超过 10,000 个居民的邮政编码后,我使用 uszipcode Python 包收集了纬度/经度坐标边界。我使用这些边界实现了一个网格搜索,使用搜索词“咖啡店”从 Google API 系统地收集数据,并存储了名称、地址、坐标、价格水平、Google 星级和评论数量。

可以从 Google Places API 中提取的数据示例;作者图片
精细竞争信息的加入为位置分析工作增加了一个令人兴奋的维度。从这里开始,我们有几种方法可以使用这些数据来改进我们的位置分析。我们可以看到有多少家咖啡店在紧邻的邮政编码区内,也可以看到有多少家在周围的邮政编码区内(API 搜索的范围是距离邮政编码区边界约 1.25 英里的半径),这是针对人口进行的归一化处理。
我们可以计算邮政编码中的平均商店评级,作为客户满意度的代表(越低=机会越多),或者附近是否已经有星巴克。我们可以通过筛选具有相同价格水平的商店来考虑同类竞争。最后,我们可以将数据放到地图上,检查哪里可能有机会。
最终,对于这个项目,我制作了一个数据框,其中每个邮政编码占一行,还有几个与该邮政编码相关的特征,我们将在下一节讨论。

一个输出数据集的示例,用于按邮政编码进行的竞争;作者图片
创建计分算法
汇集所有相关数据点的一种方法是建立一个自下而上的评分算法,其中每个组件都是下一个组件的构建块。为此,我们首先定义总体评分类别(组件),如人口统计、竞争或经济活动。然后,我们找到可以组成该类别的子组件。我们将每个子组件列从其值转换为其百分位数,以将输出标准化到一个标度上。
作为子组件的一个例子,对于人口统计,我们可以考虑像人口规模或收入这样的信息。对于经济活动,我们可以寻找办公人员的数量或商业建筑的分区。对于竞争,我们可以考虑竞争密度或客户满意度。每个子组件成为该组件的加权输入,并且该组件成为最终分数的加权输入。
组件和子组件由业务和对其成功重要的因素来指导。咖啡店要取得成功,需要具备的条件与目标大不相同,这种方法可以灵活地适应每个用例。
考虑下面的例子,我们可以用在星巴克。我们有两个对一个地方的成功很重要的因素——人口统计和竞争。对于人口统计,我们有 3 个子成分(大致)权重相等。对于竞争,我们有两个重量不等的子组件。然后,对于我们的最终得分,我们给予人口统计比竞争更高的权重。

加权评分算法如何工作的示例;作者图片
权重的分配可以基于管理知识、直觉或其他适合情况的因素。这种方法的好处之一是,当我们获得更多信息时,我们可以调整权重。
实际上,上图所说的是,对一家星巴克店的成功来说,重要的是人口因素和竞争因素。人口因素是人口规模(高目标市场)、低生活成本(因此租金成本较低)和高收入(买得起高端产品)。在图表的另一边,保持低竞争密度和对当前产品的低满意度也很重要。
这种方法的另一个重要好处是它对外部受众来说是高度可解释的。最终得分在 0 到 1 之间,越高越好。我们可以参考组件分数来了解它们在分数上的差异,然后参考子组件分数来查看哪些是最高的影响。我们可以通过图表的每个分支来了解最终得分是如何计算的,它包含哪些组件,以及组成每个组件的子组件。
下面是一个基于这种方法的新得分表的示例,以及一个单独邮政编码及其组成部分得分的示例。我们可以看到组件/子组件细分如何向我们显示它具有比人口统计更有利的竞争分数,以及低密度(导致高/有利分数)是高竞争分数的驱动因素。

具有组件和子组件分数的最终数据集的示例;作者图片

排名靠前的邮政编码的评分组件示例;作者图片
采取下一步行动
我们可以将评分和位置映射结合起来,获得竞争对手所在位置(除了现有星巴克门店之外)的详细信息,以及这将如何影响我们的战略。
我们将考虑下面的两个例子,看看我们如何将这项工作付诸实践。首先,我们来看一个得分最高的邮政编码,11717,位于纽约市东部的长岛。
在下面的地图中,灰色阴影区域是邮政编码的边界,而其他边界表示附近的邮政编码。每个点都是由 Google Places API 标记的咖啡店。绿色点代表当前星巴克的位置,橙色/红色点代表所有其他咖啡店。气泡的大小代表评论的数量(即最受欢迎/最知名的商店)。

纽约市外邮政编码 11717 附近的咖啡店;作者图片
对我来说,有趣的是,在每个边界(左上、左下、右下)之外有多个星巴克位置,但中间没有。尽管另一个国家咖啡品牌 Dunkin 在邮政编码区或附近有多个地点。这可能代表在阴影区域右侧中间增加一个位置的潜在机会。
作为另一个例子,我们将看看排名第一的邮政编码,63021。这个地方是密苏里州圣路易斯的郊区。

密苏里州圣路易斯郊区 63021 附近的咖啡店活动;作者图片
在这里,我注意到的是,在邮政编码的尖端有多个星巴克的位置。然而,我们看到很少,如果有的话,位于邮政编码(任何咖啡店),这表明该地区可能被划分为仅用于居住目的。因此,虽然它具有诱人的人口结构和竞争,但缺乏竞争可能是因为缺乏任何可用的商业房地产,这抑制了我们在那里的增长能力。
在这一点上,评估位置的过程变得更加手动,但是我们缩小到特定关注区域的能力将我们的时间集中在最有价值的区域。这种方法不能告诉企业具体的街道位置,但它可以告诉人们在哪里花时间寻找正确的位置。
结论
对我来说,一个有趣的发现是,虽然在最初的分析中,这个项目分析的邮政编码中没有星巴克,但是所有的邮政编码在大约 2 英里的范围内至少有2 家星巴克。这表明,至少在某种程度上,这种方法正在产生与他们内部考虑位置选择的方式相似的结果。
下一步,我们可以构建经济活动因素,如邮政编码中的工作/工人数量(可能会在早上上班的路上经过)或大学的存在。同样,我们可以搜索分区记录,以过滤出商业分区低或没有商业分区的位置,从而消除我们在法律上无法运营的区域。我们还可以做更多的工作来调查附近商店的存在以及从现有商店的销售中蚕食的可能性。
选址既是科学也是艺术。最终,分析可以帮助我们找到一个有限的位置,然后我们可以依靠当地的专业知识,在这些范围内找到手头业务的最佳位置。
有兴趣了解这些主题的更多信息或联系讨论吗?在 jordan@jordanbean.com 给我发邮件或者在 LinkedIn 上联系我 。
预测 Strava Kudos
原文:https://towardsdatascience.com/predicting-strava-kudos-1a4ce7a02053?source=collection_archive---------25-----------------------
一个端到端的数据科学项目,从数据收集到模型部署,旨在根据给定活动的属性预测用户对 Strava 活动的交互。

由 Unsplash 上的 Mael BALLAND 拍摄的照片
Strava 是用于跟踪人类锻炼的服务,其结合了社交网络类型的特征。它主要用于骑自行车和跑步,重点是使用 GPS 数据。下面是我自己的一个典型的 Strava 帖子,我们可以看到它包含了很多信息:距离,移动时间,速度,海拔,天气,GPS 路线,我和谁一起跑,等等。等。

典型的 Strava 活动帖子(图片由作者提供)
现在,Strava 也是一个社交媒体,每个活动都可以获得 kudos,这相当于其他平台上的赞。鉴于我已经在 Strava 上发布了超过 4000 个活动,这是一个开始一个独特的小数据科学项目的好地方。我的目标是根据活动的属性预测每个活动获得的 kudos 数量。
然而,预测荣誉并不一定是一件容易的事情。在从 Strava 提取的数据点中,平均 Kudos 计数为 38,标准偏差为 24。最小值为 0,最大值为 171。数据中有很多可变性…所以希望我们可以创建一些有用的功能来帮助解释这一点!

荣誉分布(图片由作者提供)
如果你想快进到最终项目,你可以在这里找到成品。
数据收集
Strava 有一个功能,允许用户下载他们以前的所有数据,但是,这只能每周进行一次。更好的数据收集解决方案是使用 Strava API,它允许您每 15 分钟发出 100 个请求,每天总共发出 1000 个请求,也就是说,对于我们的预期目标来说,这已经足够了。
使用这个 API ,我能够快速有效地收集我所有的活动数据。很可爱。这个 API 的另一个好处是,它允许我提取我最近的活动,这样我就可以即时预测 kudos,这是这个项目的最终目标之一。下面是我的 Streamlit 应用程序上的实时 Kudos 预测的 GIF 图。

实时 Kudos 预测(GIF 由作者提供)
如果你对开始使用 Strava API 感兴趣,我强烈推荐你从这篇博文开始。
一旦我设置好了东西并有了所需的密钥,获取最近的活动就很容易了!
从 Strava API 获取最近活动的代码(由作者编写)
只需在这段代码中添加一个 while 循环,就可以轻松获得我的项目所需的所有 Strava 数据!
训练数据集的前 8 个条目(由作者编写)
探索性数据分析
一旦我有了所有的数据,议程上的下一件事就是一些 EDA。这包括探索数据、查看分布、相关性和关于不同特征的一般信息。我为此创建的笔记本可以在我的 Github 页面上找到。
一些值得注意的发现包括:
- 获得的荣誉很大程度上取决于我当时有多少追随者。不幸的是,没有办法看到我在每个时间点有多少追随者,所以我无法根据追随者的数量来衡量荣誉。因此,我只能使用我最近的 1125 次活动(从 2019 年 12 月至今)来训练我的模型,因为在此期间,kudos 保持了相当的一致性。

保留和删除的数据点(图片由作者提供)
- 发现目标变量(Kudos)向右倾斜(也是双峰的),并且有一些超过~100 的极值。当使用某些模型时,例如线性回归,希望在目标变量中看到更多的正态分布。因此,可以使用 BoxCox 变换来查看目标变量中更“正常”的分布(例如,可以通过绘制 q-q 图来检查正态性)。
- 使用隔离森林模型来检测异常值,在 800 个训练点中,发现了 17 个异常值。经过进一步调查,这些主要是活动上传,最初设置为私人,但后来切换到公共。这意味着其他用户无法看到该活动或与之互动。这些已从训练集中删除。
- 距离、移动时间和平均速度 mpk 等特征似乎与 kudos count 具有相似的分布。这在查看相关矩阵时得到了证实。
- 照片计数功能在每个非零类别中只有几个不同的数据点,因此我们可以将其更改为包含照片/没有照片的二元功能。
- 锻炼类型似乎与荣誉密切相关,然而,锻炼类型 1(比赛)的数据点并不多。直觉上,我也相信比赛通常会获得更多的荣誉。 SMOTE 因此被用于对该健身程序类型进行过采样,以增强该功能的预测能力,后来发现这降低了 RMSE。
- 通过观察活动之间的时间分布,发现其他跑步快速跟进的跑步往往比当天唯一活动的跑步获得的荣誉少。除此之外,一天中最长的活动往往比当天的其他活动获得更多的荣誉。
预处理
培训、测试和交叉验证
我首先需要将数据集分成训练集和测试集。我使用 80/20 分割,因为我的数据包含日期,所以我只使用最近 20%的数据作为测试集。我不想随机打乱数据集,因为我创建了一些基于时间的要素。
拥有一个好的交叉验证方案极其重要,在该方案中,验证数据代表训练和真实世界的数据,因为它使您构建的模型具有高度的可推广性。现在,因为我只有少量的训练样本,同时拥有验证集和测试集是不允许的。因此,在训练集上使用交叉验证来模拟验证集。
我使用 Sklearn 的 StratifiedKFold 将训练集分成 5 份,其中斯特奇法则用于计算适当的箱数。
创建分层 K 倍交叉验证的代码(由作者编写)
使用这种交叉验证方案,我能够自信地比较不同的模型来选择最有希望的模型,而不用担心验证集过拟合。该方案也用于调节有希望的模型的超参数(尽管在超参数调节之前折叠被重新洗牌)。值得注意的是,在测试集上对模型进行评估的唯一一次是在项目结束时,当时我想获得真实性能的真实度量。
缺少值
数据集中没有大量的缺失值,大多数缺失值来自于对 Strava 来说相当新的特性/我不经常使用的特性。例如,workout_type 功能并不总是有“种族”选项(事实证明它有很强的预测能力!).在输入缺失值之前,首先调查缺失值并尝试找出它们缺失的原因总是非常重要的,这可能很重要!
经过一些检查后,我手动输入了一些缺少的值,因为我认为这非常重要,而且一些旧数据没有标签。我选择手动输入值,因为任何简单的插补技术都会将所有缺失值分配到默认的“简单运行”Strava 类别中。也考虑了 KNN 估算,但是没有很多未标记的数据点,所以手动输入更快。
启发式函数也用于填充标题包含比赛位置的活动,例如第 10 或第 1,因为这些活动显然是比赛。这样做是因为种族似乎总是对荣誉有很大的影响。
对整个数据集使用的一般插补方案是:
- 分类特征中的任何缺失值都被赋予一个新的类别“NONE”——在处理缺失类别时,这似乎在大多数情况下都很有效。
- 使用中值策略对数字要素中所有缺失的值进行估算(也尝试了平均值,但中值效果更好)。
其他预处理
其他数据准备步骤包括:删除不是 run 的活动,删除没有 Kudos 的活动(主要是因为 run 本来是私有的,然后切换到公共的),格式化日期时间信息。
特征工程
特征工程是建立一个好的机器学习模型的最关键的部分之一。如果我们有有用的功能,模型会表现得更好。
基于时间的特征
我们有每个活动的日期和时间数据,所以我们可以很容易地制作一些琐碎的基于时间的特性。这些特征中的一些包括年、年中的星期、月、星期几、一天中的时间、周末等。
从经验来看,我也知道我每天在 Strava 上发布的活动越多,我得到的赞誉就越少,所以我可以试着将这一点融入到一些功能中。我做了一些特征来概括这个:
- max_run (binary) —该活动是当天距离最长的活动吗?
- run_per_day (ordinal) —当天完成的总活动数。
我来自英国,但我目前在爱达荷州博伊西学习,所以我的大多数朋友/粉丝都来自英国。为了解释这一点,我制作了一个二进制功能“is_uk_awake ”,用于检查英国在上传活动时是否处于唤醒状态。我通常发现在这个时间窗口之外发布一个活动会导致更少的荣誉。
其他功能
- 与使用自定义名称的跑步相比,使用默认名称(如“下午跑步”)的跑步获得的互动较少。这样就创建了一个二进制特征来检查运行是否被命名。
- 我一直有一种直觉,有着非常漂亮的 GPS 痕迹的跑步比没有的跑步更容易受到关注。为了将这一点封装到一个功能中,我使用跑步 GPS 追踪来测试跑步循环所包围的区域(来回跑步将返回值 0)。我的想法是,大圈圈比小圈圈或来回跑获得更多的荣誉。
- 添加了一些其他功能,可以在我在 Github 上的代码中找到。
特征编码
One-hot-encoding 用于对分类特征进行编码,而 ordinal encoding 用于对序数特征进行编码(分类特征,其中顺序意味着某些东西)。
锻炼类型的功能似乎与预测能力斗争,即使我知道它是一个非常有用和相关的功能,它可能与类别的不均匀分布有关。所以为了解决这个问题,我使用了目标编码。我们需要非常小心,因为这可能会使模型过拟合。目标编码是一种将给定特性中的每个类别映射到其平均目标值的技术,但这需要始终以交叉验证的方式完成!
针对编码特性的代码(由作者编写)
特征缩放
最后,我们需要考虑伸缩性。根据经验,当我们使用 K.N.N 等计算距离的模型或线性回归等假设正态性的模型时,我们需要调整数值特征。通常,我们要么使用最小-最大缩放要么使用标准化,要想知道使用哪一种,我们只需同时尝试这两种方法,看看哪一种能产生最佳性能。然而,基于树的模型不是基于距离的,并且可以处理变化范围的特征,因此不需要缩放。
数据建模
初始模型选择
在这一步中,我构建了几个不同的候选模型,并比较了不同的度量标准,以确定哪一个是部署的最佳模型。使用的模型性能和特征保存在 CSV 文件中,以帮助跟踪哪个模型的性能最好。在比较模型时,以交叉验证的方式进行训练和评估非常重要!
我使用的训练脚本如下所示(注意:一些东西被移除去杂乱,例如,目标编码等。).
测试不同模型的代码(由作者编写)
一些入围的表现不错的车型有: XGBoost 、 Lasso 、 Random Forest 。这些模型然后被带到特征选择阶段。
特征选择
然后进行特征选择,以帮助降低数据集的维度,希望这能创建一个更通用的模型,我们都听说过维度的诅咒。
不同的特征选择技术用于不同的模型。例如,我们不需要为套索模型做太多的选择。当试图最小化成本函数时,Lasso 回归将自动选择那些有用的要素,丢弃无用或冗余的要素。因此,我们需要做的就是移除系数等于零的特征。
对于基于树的模型,最终方法使用了 Shapley 值和内置特征重要性值的组合。尽管如此,在从基于树的模型中查看特性重要性时需要小心,您可以在这里阅读更多相关信息。
PCA 也被测试来帮助对抗维数,但是它没有改善模型性能或泛化能力。一个原因可能是当占方差的 90%时,特征空间仅减少了 2。
选择的最终特征是:距离、平均速度、最大跑步(该跑步是一天中最长的跑步吗)、锻炼类型(+目标编码)、总海拔增量、运动时间、痛苦分数、每天跑步(当天跑步的次数)、最大速度、跑步区域(GPS 跟踪所包围的区域)和英国清醒(发布活动时英国清醒吗?).

SHAP 特色重要性(图片由作者提供)
超参数调谐
Optuna 用于调整所有三个入围的模型,这是一个开源框架,非常容易使用,非常好。特别地,树结构 Parzen 估计器(TPE)被用于对参数空间进行采样,其使用贝叶斯推理来构建代理模型,并且可以使用期望改进来选择下一个超参数。一个很好的关于用 Optuna 调整超参数的教程可以在这里找到。
我用来调优 XGB 模型的代码如下所示。
用 Optuna 调优超参数的代码(由作者编写)
下面的优化历史图显示了 TPE 采样器收敛到最佳超参数的速度。另外两个图分别显示了每个超参数和高维参数关系的重要性。

XGB 型号的 Optuna 优化历史(图片由作者提供)


XGB 模型的超参数重要性和平行坐标图(图片由作者提供)
型号选择
在执行超参数调优后,发现 XGB 模型始终优于其他两个入围模型。如下表所示,超过 5 次折叠的平均 RMSE 较低。还发现误差的方差较低。由此,我得出结论,根据我所拥有的数据,XGB 模型更有可能更好地概括未见过的数据。
包含模型分数的表格(由作者编写)
然后,使用之前找到的超参数在整个训练数据集上训练最终的 XGB 模型。
令人欣慰的是,当这三个模型用于在测试数据集上进行预测时,XGB 模型的表现优于其他两个模型。免责声明:这是(并且需要)在模型选择之后完成的,你不想过度适应测试集!XGB、RF 和 Lasso 的测试集得分分别为 9.78、11.83 和 10.68。
部署
该模型以及其他一些特性是使用 Streamlit 和 Heroku 部署的。关于 Streamlit 和 Heroku 的教程可以在这里和这里找到。建立了一个界面,你可以在其中根据我的实时 Strava 数据进行预测,探索模型的可解释性,并探索数据集。这个应用程序可以在这里找到(可能需要一分钟左右才能启动,抱歉)。
模型可解释性
这个项目的最后一部分是研究这个模型,尝试看看,一般来说,是什么属性导致活动获得更多/更少的荣誉。
众所周知,解释 XGBoost 模型是一项艰巨的任务,但是结合坚实的理论基础和快速实用的算法,SHAP 值是一个非常强大的工具,可以自信地解释基于树的模型。
最终要素的平均 SHAP 值如下所示。

平均 SHAP 值(图片由作者提供)
我们可以看到,距离功能实际上是最重要的,其次是 max_run 功能(这是我创建的一个功能,非常值得一看!).因为 SHAP 为我们的每一项活动提供了个性化的解释,所以我们能做的不仅仅是做一个条形图。我们可以看到每个特征如何影响最终的 Kudos 值:

特征对模型输出的影响(图片由作者提供)
该图中的颜色代表特征值,红色表示高,蓝色表示低。所以我们可以看到,跑得越长越快获得的荣誉越多。更多的努力(更高的心率和痛苦分数)也会带来更高的声望。另一方面,轻松跑比锻炼、长跑和赛跑获得的荣誉少。
结束语
就这样,一个独特而成功的数据科学项目完成了。嗯,有点…仅仅因为我们已经建立了一个好的模型并不意味着这个模型总是好的,它可能会漂移。
模型漂移是指由于数据的变化以及输入和输出变量之间的关系而导致的模型性能退化。因此,重要的是检查每一个,然后看看模型是否仍然在一个适当的水平上执行。也许这是未来博客的主题。
感谢阅读,我希望你喜欢它。如果您有任何意见或问题,请随时在评论中或通过电子邮件联系我们。
如果你做到了这一步,这里有一些你可能感兴趣的我的其他故事…
用球模拟模型预测 T20 板球比赛
原文:https://towardsdatascience.com/predicting-t20-cricket-matches-with-a-ball-simulation-model-1e9cae5dea22?source=collection_archive---------18-----------------------
这是观看大量板球比赛的季节,我又一次不得不这样做了。没错,每年夏天我都会一头扎进休息室,观察大约 700 万个小时我最喜欢的运动,但去年我决定在休息时间花些时间研究一个预测模型。体育建模是我的激情所在,实际上是最初让我对数据科学感兴趣的入门药物。过去,我曾训练模型预测橄榄球比赛、网球比赛和赛马的结果,甚至在预测澳大利亚网球公开赛的数据科学竞赛中获得了一等奖。
我这个项目的主要目标不是构建有史以来最精确的算法(尽管那样会很好),而是用一种概率性的、自下而上的建模方法进行实验。我没有试图根据历史数据预测比赛结果,而是训练了一个神经网络模型来预测单个球的结果,然后建立了一个定制的蒙特卡洛模拟引擎来生成数万种可能的游戏。

图片由内森·萨阿德拍摄。
数据
在这个项目中,我使用了涉及 2255 名球员的 3651 场 T20 比赛中的 677291 个球的数据。比赛在 2003 年和 2020 年之间举行,来自以下 7 个联赛:
- 印度超级联赛
- 大狂欢联盟(澳大利亚)
- 加勒比超级联赛
- T20 爆炸(英格兰)
- Mzansi 超级联赛(南非)
- 巴基斯坦超级联赛
- 孟加拉超级联赛
不幸的是,我不能分享这个项目的数据源,因为我利用了我的个人体育数据库,但这种数据很容易公开找到。下面是我的起始表中的一些示例,用来说明我正在处理的数据类型(没有显示所有的列)。
搭配

图片由 Andrew Kuo 提供。
玩家

图片由 Andrew Kuo 提供。
球员比赛统计

图片由 Andrew Kuo 提供。
解说

图片由 Andrew Kuo 提供。
方法
基本原理
对于这个项目,我决定使用自下而上的方法,通过训练一个模型来预测每个投球的结果(而不是整个比赛结果)。我的理由如下:
- 面对面的战斗是板球的关键部分,这种方法让我能够捕捉到击球手和投球手之间的比赛。
- 板球比赛往往由几个关键时刻决定,一个球的结果会对结果产生巨大影响。一个好球或坏球之间的差异可能只有几厘米(例如,在边界上接球与清理六分钟的绳子),但通过模拟数千次比赛,我们可以从概率上接近这些事件。
- 它允许我们回答更复杂的问题(例如,谁可能在比赛中进最多的三柱门)。传统的自上而下模型只能对其接受训练的特定任务做出预测(例如,谁将赢得给定的比赛)。
- 我们可以得到结果的条件概率,例如钦奈超级国王队获胜的概率,假设他们首先击球并获得 167 分,或者如果克里斯·林恩得分少于 20 分,布里斯班热火队获胜的概率。
球预测模型
这个项目的核心是我的球预测模型,它是在我的数据集中的大约 700k 个球上训练的。这是一个多类别分类问题,为了简单起见,我将类别(一个球的可能结果)限制为 8 个选项(0,1,2,3,4,6,Wicket,Wide)。模型的输入是:
- 比赛状态(局数、结束、跑垒次数、三柱门数、相关的第一局得分)
- 投球手统计(投球手投出的所有球的历史得分分布)
- 击球手统计(击球手面对的所有球的历史分布)
该模型的输出是 8 个可能的球结果中每一个的预测概率。在模拟阶段,我们通过模型运行每个球的输入,然后从预测的概率分布中取样。

图片由 Andrew Kuo 提供。
我不会在这里过多地讨论模型选择和超参数优化的细节,因为这不是本文的重点,但是我已经在下面列出了我的最终模型的 Keras 总结。简而言之,我训练了一个前馈神经网络模型,它有两个 50 个节点的密集层,每个节点都有一个 ReLU 激活函数。我还应用了批量标准化和剔除。
Model: "sequential_4"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_12 (Dense) (None, 50) 1150
_________________________________________________________________
batch_normalization_8 (Batch (None, 50) 200
_________________________________________________________________
re_lu_8 (ReLU) (None, 50) 0
_________________________________________________________________
dropout_8 (Dropout) (None, 50) 0
_________________________________________________________________
dense_13 (Dense) (None, 50) 2550
_________________________________________________________________
batch_normalization_9 (Batch (None, 50) 200
_________________________________________________________________
re_lu_9 (ReLU) (None, 50) 0
_________________________________________________________________
dropout_9 (Dropout) (None, 50) 0
_________________________________________________________________
dense_14 (Dense) (None, 8) 408
=================================================================
Total params: 4,508
Trainable params: 4,308
Non-trainable params: 200
_________________________________________________________________
模拟引擎
下一步是用 Python 构建一个模拟引擎,可以使用球预测模型生成完整的比赛。概括来说,生成模拟的步骤如下:
- 创建两个玩家 id 列表(每个团队一个)。
- 使用步骤 1 中的团队列表实例化两个团队对象(定义如下)。此外,将每个团队的相关历史击球和保龄球统计数据传递给本课程。
- 使用两个团队对象、球预测模型和场地信息实例化 MatchSimulator 对象(定义如下)。
- 运行在步骤 3 中创建的 MatchSimulator 对象的 sim_match 模块。下面给出了模拟步骤。
5.返回模拟比赛和球员统计数据。
模拟步骤
- 每场比赛都以模拟抛硬币开始,获胜队选择击球或投球。
- 使用当前比赛状态和相关投球手和击球手统计数据作为输入,通过运行球预测模型来模拟每个球。从模型输出的分布中随机抽取一个样本,并根据需要更新 MatchSimulator 和球队状态(例如,如果球的结果是“3 ”,则在击球手的得分和他所在球队的得分上加 3 分,在投球手的统计数据上加 3 分,将好球轮换给其他击球手,并增加球计数器)。
- 重复步骤 2,直到游戏结束。
- 重复第二局。
这不是一个教程,但是我在下面包含了一些代码来说明这个模拟引擎的机制。
团队类
匹配模拟类
我还包含了在“详细”模式下运行模拟引擎的功能,该模式输出一场比赛进程的实时评论。在此模式下运行单一模拟的示例如下所示。
运行模拟
示例输出
The Brisbane Heat have won the toss!
Sydney Sixers will bat first. Brisbane Heat to bowl.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1ST INNINGS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
MJ Swepson to bowl. 0/0 after 0.
4 to JL Denly!
JK Lalor to bowl. 0/4 after 1.
4 to J Avendano!
4 to J Avendano!
Mujeeb Ur Rahman to bowl. 0/12 after 2.
4 to JL Denly!
6 to JL Denly!
JL Pattinson to bowl. 0/23 after 3.
WICKET! JL Denly out, bowled JL Pattinson.
WICKET! MC Henriques out, bowled JL Pattinson.
6 to DP Hughes!
BCJ Cutting to bowl. 2/31 after 4.
WICKET! J Avendano out, bowled BCJ Cutting.
MJ Swepson to bowl. 3/34 after 5.
JL Pattinson to bowl. 3/36 after 6.
Mujeeb Ur Rahman to bowl. 3/38 after 7.
4 to JC Silk!
BCJ Cutting to bowl. 3/46 after 8.
Mujeeb Ur Rahman to bowl. 3/52 after 9.
4 to JC Silk!
BCJ Cutting to bowl. 3/60 after 10.
WICKET! JC Silk out, bowled BCJ Cutting.
JK Lalor to bowl. 4/63 after 11.
MJ Swepson to bowl. 4/68 after 12.
JK Lalor to bowl. 4/74 after 13.
4 to DP Hughes!
JL Pattinson to bowl. 4/82 after 14.
6 to JR Philippe!
6 to JR Philippe!
MJ Swepson to bowl. 4/96 after 15.
4 to JR Philippe!
JK Lalor to bowl. 4/106 after 16.
4 to JR Philippe!
MJ Swepson to bowl. 4/114 after 17.
WICKET! JR Philippe out, bowled MJ Swepson.
BCJ Cutting to bowl. 5/118 after 18.
6 to DP Hughes!
4 to TK Curran!
Mujeeb Ur Rahman to bowl. 5/132 after 19.
6 to TK Curran!
Final Score: 5/144 off 20.
The Brisbane Heat are going in to bat. Sydney Sixers to bowl.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2ND INNINGS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
BJ Dwarshuis to bowl. 0/0 after 0.
4 to M Bryant!
4 to M Bryant!
TK Curran to bowl. 0/8 after 1.
BAD Manenti to bowl. 0/9 after 2.
WICKET! M Bryant out, bowled BAD Manenti.
BJ Dwarshuis to bowl. 1/13 after 3.
4 to SD Heazlett!
4 to SD Heazlett!
MC Henriques to bowl. 1/25 after 4.
WICKET! SD Heazlett out, bowled MC Henriques.
4 to BB McCullum!
4 to BB McCullum!
WICKET! BB McCullum out, bowled MC Henriques.
SA Abbott to bowl. 3/34 after 5.
4 to JA Burns!
BAD Manenti to bowl. 3/41 after 6.
4 to JA Burns!
TK Curran to bowl. 3/46 after 7.
6 to JA Burns!
BJ Dwarshuis to bowl. 3/57 after 8.
4 to CA Lynn!
4 to CA Lynn!
6 to CA Lynn!
WICKET! JA Burns out, bowled BJ Dwarshuis.
SNJ O'Keefe to bowl. 4/72 after 9.
WICKET! CA Lynn out, bowled SNJ O'Keefe.
BJ Dwarshuis to bowl. 5/76 after 10.
4 to BCJ Cutting!
SA Abbott to bowl. 5/83 after 11.
WICKET! BCJ Cutting out, bowled SA Abbott.
TK Curran to bowl. 6/87 after 12.
6 to JL Pattinson!
4 to JJ Peirson!
6 to JL Pattinson!
BJ Dwarshuis to bowl. 6/105 after 13.
6 to JL Pattinson!
6 to JL Pattinson!
BAD Manenti to bowl. 6/123 after 14.
4 to JL Pattinson!
TK Curran to bowl. 6/129 after 15.
6 to JL Pattinson!
WICKET! JJ Peirson out, bowled TK Curran.
MC Henriques to bowl. 7/137 after 16.
4 to JL Pattinson!
Final Score: 7/145 off 17.
~~~~~~~~~~~~~~~~~~~~
Brisbane Heat WIN!
~~~~~~~~~~~~~~~~~~~~
为了进行预测,我们使用上面描述的模拟引擎。每个模拟代表一个可能的结果,但是使用蒙特卡罗方法,我们能够通过多次模拟来估计比赛结果的分布。要预测某个结果的概率,只需统计所有发生该结果的模拟,然后除以模拟总数。例如,如果您模拟悉尼六人队和墨尔本明星队之间的比赛 1000 次:
- 如果 76 人在 570 次模拟中获胜,那么 76 人获胜的预测概率是 0.57
- 如果史蒂夫·史密斯在 237 次模拟中得分最高,那么史蒂夫·史密斯在这场比赛中得分最高的预测概率是 0.237
结果
那么在这一切之后,我的模型真的好吗?为了回答这个问题,我从我的数据集中选取了 1126 个历史匹配,每个匹配模拟了 500 次。理想情况下,你会模拟每场比赛比这多得多的次数,但这是不切实际的计算这个项目。由于我的模型是自下而上的,实际上有许多评估模式,下面我将概述其中的一些。
模拟现实主义
第一个常识测试是看预测的比赛是否看起来真实,幸运的是它们看起来真实。请记住,比赛是使用球预测模型模拟的,因此我们不能保证输出是合理的。例如,如果球预测模型表现不佳,我们可能会看到击球队过于频繁地出局,或者球队获得天文数字的分数。
在现实生活中看了这么多板球比赛后,我能够很快看出我的模拟是对真实比赛的回忆,这令人欣慰,如果不是过于科学的话。为了进一步支持我的直觉,我采样了一些真实的比赛和模拟,并比较了许多比赛结果的分布。在下面的例子中,您可以清楚地看到,真实比赛和模拟比赛的结果分布非常相似。
第一局总计

图片由 Andrew Kuo 提供。
比赛检票口

图片由 Andrew Kuo 提供。
最高个人分数

图片由 Andrew Kuo 提供。
匹配结果
我评估模型的第二个方法是预测比赛的获胜者。如前所述,要获得 A 队赢得比赛 X 的预测概率,只需将 A 队获胜的所有模拟相加,然后除以模拟总数。在模拟比赛中,我的模型能够以 55.6% 的准确度和 0.687 的对数损失来预测获胜者。
虽然我最初对这些结果印象不深,但使用 Bet365 的历史投注赔率进行的进一步分析使我受到鼓舞。当我将我的模型预测与 Bet365 的赔率暗示的预测进行比较时,我发现我的模型实际上表现更好。Bet365 以较低的准确度( 54.2% )和较高的对数损失( 0.695 )选出了获胜者。从这个角度来看,一个基准模型预测每场比赛两队的概率为 0.5,对应的对数损失为 0.693 ,这意味着 Bet365 的赔率比没有信息的模型更差!
现在,这里要说的不是我的模型在预测 T20 比赛结果方面令人惊讶,而是 T20 比赛结果本来就很难预测。我确实怀疑,通过每场比赛模拟 500 次以上,我会提高模型的性能,但我需要在将来测试这个假设。
其他预测
最后,我尝试预测比赛的其他一些特征。我再次遇到了这项运动固有的不可预测性,但我在下面列出了一些结果。
第一局比分
为了预测每场比赛的第一局分数,我使用了所有模拟中正确的球队首先击球的平均第一局分数。在下面的散点图中,我们可以看到预测分数和实际分数之间有关系,但这是相当嘈杂的。这里的相关性为 0.305 ,p 值为 1.18e-25 ,这表明模拟在模拟这一特征方面做得很好,但未知因素太多,无法做到准确。进一步的证据是所有模拟比赛中第一局得分的平均标准差,相当高,为 28.6 。

图片由 Andrew Kuo 提供。
顶级跑分
为了预测一场比赛中得分最高的球队,我选择了在大多数模拟中得分最高的球员。使用这种方法,我能够以大约 25%的准确率选出最高分。在下面的图中,我们可以看到当我们选择前 N 个最有可能得分最高的人(而不仅仅是前 1 个)时,准确性的不同水平。例如,在我模拟的 80%的比赛中,我在基于模拟的前 4 个预测中有真正的最高分。

图片由 Andrew Kuo 提供。
顶部检票员
我在这里使用了与上面预测得分榜榜首相同的方法,但是这一次我试图为每支球队选出最佳射手。下图显示了我的最佳选择在大约 35%的比赛中是正确的,而真正的最佳人选在大约 75%的时间里出现在我的前 3 个预测中。

图片由 Andrew Kuo 提供。
结论
从一开始,这个项目的目标并不是真正世界级的预测准确性,而是看看我是否能以逐球的粒度模拟整个 T20 比赛,我做到了。该模型非常擅长生成 T20 比赛的真实模拟,但不幸的是,它很难充满信心地预测结果。我的直觉告诉我,这可能是因为这项运动总体上很难预测,这得到了我对博彩赔率的分析的支持。我发现,博彩公司的赔率不仅比我的模型更糟糕,甚至比没有任何信息的模型更糟糕。
虽然这是一个有趣的实验,但我发现在实践中使用它有一些限制。首先,运行模拟需要很长时间(在我的机器上大约每小时 10k 次模拟)。这不一定是个问题,除非球队名单通常在比赛开始前 10-15 分钟才公布。由于自下而上的建模风格的一个关键优势是它可以更好地捕捉到面对面的比赛,所以用不正确的阵容模拟游戏不太可能产生好的结果。
就后续步骤而言,我想尝试几件事:
- 增加了球预测模型的复杂性。因为每个模拟都需要相对长的时间来运行,所以我决定保持我的球预测模型相当轻量级,但是我想尝试添加更多的功能。
- 尝试增加每场比赛的模拟次数。我用这个做了一个小实验,看到了预测准确性的即时提升,所以我想尝试模拟每场比赛 10k+次。
- 尝试为更可预测的运动建立一个类似的模型。这种建模的灵活性非常吸引人,所以我想用一种更容易建模的运动来尝试这种自下而上的方法。
使用机器学习预测文本的难度并获得单词的视觉表示
原文:https://towardsdatascience.com/predicting-the-difficulty-of-texts-using-machine-learning-and-getting-a-visual-representation-of-75f5a96b92e5?source=collection_archive---------13-----------------------

乔恩·泰森在 Unsplash 上的照片
借助 WordCloud 和预处理步骤,发现文本数据中隐藏的见解和模式,并预测难度
我们看到文本数据在自然界中无处不在。有很多文本以不同的形式呈现,比如帖子、书籍、文章和博客。更有趣的是,有一个名为自然语言处理(NLP) 的人工智能子集,可以将文本转换成可用于机器学习的形式。我知道这听起来很多,但了解细节和机器学习算法的正确实现可以确保人们在这个过程中学习到重要的工具。

照片由杰米街上的 Unsplash
因为有更新更好的库被创建用于机器学习目的,所以学习一些可以用于预测的最先进的工具是有意义的。我最近在 Kaggle 上遇到一个关于预测文章难度的挑战。
输出变量文本的难度被转换成本质上连续的形式。这使得目标变量连续。因此,各种回归技术必须用于预测文本的难度。由于文本在自然界中无处不在,应用正确的处理机制和预测将非常有价值,特别是对于以文本形式接收反馈和评论的公司。
现在让我们检查代码,并分别理解关键的可视化和结果。
注:数据集取自https://www.kaggle.com/c/commonlitreadabilityprize/data
阅读图书馆
我知道当使用各种库进行机器学习时,这看起来很复杂。然而,如果我们试图理解这些库,事情就会变得简单。让我们利用上面提到的库来预测课文的难度。我们导入用于科学计算的 numpy。我们使用 seaborn 和 matplotlib 来绘制图形和数字。熊猫用来读文件。WordCloud 将帮助我们分别标出最常出现的单词。
我们使用一个自然语言处理工具包来执行句子到不同记号和单词的转换,以便它们可以用于机器学习目的。我们还将使用 TFIDF 矢量器和计数矢量器将一组给定的单词和句子转换成数学矢量。库‘tqdm’只是用来计算执行各种计算所需的时间。最后,我们使用 train_test_split 将数据分别分为训练和测试部分。缺失号用来给我们提供机器学习缺失值的图。我们也将地互动可视化。这些是我们将分别用于我们的自然语言处理项目的一些库。
预处理功能
在将数据交给机器学习模型进行预测之前,对数据进行预处理是非常重要的。使用像代表正则表达式的库可能会很方便。此外,应完成文本标记化,以便将文本简化为标记。文本中的停用词不会增加很多意思,但大多像填充词。因此,从我们的语料库中移除那些单词降低了训练我们的模型的计算成本。从代码中可以看出,停用词被删除了。最后,转换后的文本由函数返回,以便在我们的机器学习管道中进一步处理。
读取数据
上面将注册一个训练和测试路径,并将这些值加载到。csv 文件。有一个名为“low_memory”的属性被设置为“False ”,以便于读取数据。
现在是时候从本地文件中读取数据了。在代码的前面,指定了文件的路径。现在是存储那些的时候了。csv' 文件中的变量如上图所示。
WordCloud 功能
从上面的代码中可以看出,我们已经定义了一个函数来生成 WordCloud ,它给出了数据中出现频率最高的单词的图表。这真的很方便,特别是如果我们想知道基于文本输出难度的单词的出现。
文本预处理
在常规回归的帮助下,现在是时候让我们的文本清晰易懂了。为了做到这一点,各种单词被替换为它们的长形式,以便提高文本的可读性。例如,在上面的代码块中,“t”被替换为“not ”,以提高对文本的理解。类似地,所有其他表达式都被替换,这有助于我们分别删除这些停用词。
TFIDF 矢量器
现在让我们使用 tfidf 矢量器,它可以将单词编码成数学矢量,供我们的机器学习模型处理。 Tfidf 矢量器会计算所有文本中常见的单词以及单词的频率。例如,‘the’可能出现在我们的某篇文章中。但是由于‘the’也出现在大多数其他文本中,所以它的 tfidf 值将会很低。让我们也用另一个词来理解。如果我们在我们的语料库中找到一个单词‘感恩’,这个单词可能在我们的某篇文章中很常见。但同一个词可能不会出现在所有其他文本中。因此,它的 tfidf 值会很大。同样,我们对所有的单词进行同样的步骤,以确保它们被转换成数学向量进行处理。
训练深度神经网络
定义一个神经网络对于训练我们的数据很重要。我们已经定义了一个神经网络以及几个密集层。我们首先从第一层的 500 个隐藏单元开始,慢慢减小尺寸,直到我们只达到 1 个输出单元。由于‘可读性’变量是一个连续变量,输出单位应该是线性的。我们是否也要显示验证分数是根据设置为真或假的 validation_data 决定的。值得注意的是,我们目前正在使用‘Adam’优化器来完成深度学习任务。
评估模型
神经网络模型训练成功后,就到了评估其性能的时候了。我们现在可以使用模型的历史属性来评估性能。我们将考虑每个历元值的均方误差和验证均方误差。在绘制之后,您可以得到关于历元的增加如何导致训练均方误差减少的曲线。有时交叉验证均方误差会在某一点后增加。这意味着我们的模型过度拟合了数据。因此,应该分别采取措施来减少模型的过拟合。
完整的代码和详细的描述,你可以点击下面的链接。
suhasmaddali/Predicting-Readability-of-Texts-Using-Machine-Learning:这个项目的目标是分别使用各种机器学习技术来预测文本的难度水平。(github.com)
结论
总的来说,我们学会了如何阅读数据,预处理数据,理解经常出现的单词。看完这篇文章后,希望你了解了如何使用机器学习和深度学习来预测文本的可读性。欢迎分享您的想法和反馈。谢了。
用数据科学预测节假日对服务的影响
原文:https://towardsdatascience.com/predicting-the-effects-of-holidays-on-service-with-data-science-5adf8bddb974?source=collection_archive---------24-----------------------
分类模型可以帮助我们了解与服务延误相关的因素,评估假期的影响,并根据重要的标准预测未来的延误。

安德烈·本兹在 Unsplash 上拍摄的照片
当我们中的许多人在感恩节快乐地享受盛宴和放松时,其他人却在外面做着必要的事情来保持节日期间的社会运转。当地政府机构、执法机构和其他机构仍然接受帮助请求,并努力满足这些请求。

图片 via GIPHY
但是假期会影响处理公众提出的解决问题的请求的时间吗?是什么决定了一个请求能否在 24 小时内完成和关闭?(当然,需要快速周转和关闭与许多其他领域相关,例如交付时间、客户服务单、预约等待时间等等。)
让我们来看看模拟这类问题的一种方法。我们将查看纽约市 311 呼叫数据——具体来说,一个数据集报告了 2020 年感恩节期间 311 的所有呼叫。我们将构建一个模型来预测特定的服务请求是否可能在 24 小时内关闭。鉴于案件的具体情况,能够预测这一点将有助于那些接受请求的人提供关于问题可能需要多长时间来解决的现实预测。我们的建模过程还会让我们知道哪些因素在不到一天的时间内结案最重要,包括今天是不是火鸡日。

2020 年感恩节期间向纽约市 311 服务报告的问题。(注意左上方…呀!)图片由作者提供。
准备我们模型的原料
来自纽约市网站的数据集非常干净,只需要进行一些必要的常规整理,以将日期转换为正确的格式,使文本小写以保持一致性,并创建一些功能:计算服务请求的创建和关闭之间的时间,加上一个基于日期的变量,该变量简单地标记请求是否是在感恩节发起的。
此外,在“投诉类型”的原始数据中有许多值(例如,“喧闹的聚会”、“看到老鼠”)😱)和“位置类型”(例如,“街道”、“空地”)。然而,Designer 中基于 R 的预测工具只能处理每个分类变量的 50 个或更少的值,因此我确定了前 50 个投诉和位置类型,并只保留了使用这些最常见类型的 311 个呼叫。尽管如此,我仍有 29060 个电话需要分析,而最初的 36846 个电话中,有 4060 个发生在感恩节。
令人印象深刻的是,其中 19,118 个电话在 24 小时内得到解决,其中 15,701 个电话被移交给纽约警察局处理,其他电话被转到其他城市机构,如卫生局和公园和娱乐局。

图片经由 GIPHY
构建模型,第 1 部分:Alteryx 机器学习
我们需要一个二元分类模型来预测每个案例是否在 24 小时内得到解决。预测因素包括(处理问题的)机构名称、投诉类型、位置类型、行政区、用于联系 311 的方法(例如电话、在线)以及服务请求是发生在感恩节当天还是假日周的另一天。
我们可以使用 Alteryx 机器学习来快速完成建模过程。它将利用要素分类选项充分利用该数据集,还将快速构建和评估多个模型,而我们只需付出最少的努力。

图像通过 GIPHY
像往常一样,第一步是导入数据并进行准备。此时,您可以确保为每个要素正确设置了数据类型,删除不需要的要素,并检查数据集的整体健康状况(即,是否已准备好进行建模)。
在这个阶段需要注意的一件很酷的事情是,您可以比在 Alteryx Designer 中更详细地描述您的数据类型。例如,我可以告诉 Alteryx 机器学习应该将“邮政编码”列评估为“邮政编码”类型。(那是因为是在 Alteryx 开源库之一的 木工上绘图,处理数据类型化。)
在下一步中,您将设置您的目标变量,确定您需要的模型的一般类型(分类或回归)。然后快速浏览数据集,揭示要素的一些基本细节,包括要素之间的相关性、异常值和目标变量的标注分布。

数据集中变量的相关矩阵。图片作者。

我们的目标变量的是/否值的分布(请求是否在 24 小时内关闭)。图片作者。
这个工具是用处理不平衡数据集的方法构建的,所以你不必担心你的结果是否有更多的特定标签。
Alteryx 机器学习将在自动建模步骤中使用各种算法和超参数建立一系列模型,然后为您提供可供选择的选项纲要,外加一个建议。
下一步,评估模型,可能是最有趣的!您可以查看所选模型在各种指标上的表现,查看混淆矩阵和要素的相对重要性,模拟修改数据的结果,甚至检查模型做出的好的和坏的预测的样本,以便您可以更好地了解它在幕后做了什么。

为推荐的模型检查许多指标。图片作者。

推荐车型的混淆矩阵。图片作者。

模型提供的最佳和最差预测的预测解释。图片作者。
在这一过程的各个步骤中,有很多东西需要仔细阅读。对模型满意后,您可以上传新数据,模型可以基于这些数据生成新预测,将建模过程中显示的视觉效果导出为图像或 PowerPoint 幻灯片,并导出模型以在设计人员工作流中使用。
构建模型,第 2 部分:Alteryx 设计器
如果你没有 Alteryx 机器学习,不要担心,我们仍然可以从我们的老朋友,基于 R 的预测工具开始这个节日派对。我使用这些工具在 Designer 中构建了一个逻辑回归模型和一个随机森林模型。(跟随附在这篇博文的原始版本的工作流程!)
随机森林模型有 93.4%的准确率,在预测正面和负面结果时表现大致相同,如下面的混淆矩阵所示。

Designer 中随机森林模型的混淆矩阵。图片作者。
逻辑回归模型几乎做得一样好,准确率为 93.2%;然而,它的错误并不是平均分布的。

Designer 中内置的逻辑回归模型的指标。图片作者。
因此,让我们更仔细地观察随机森林模型,特别是检查各种特征如何影响预测。下面的可变重要性图告诉我们更多信息:

在 Designer 中内置随机森林模型的可变重要性图。图片作者。
Designer 中内置的随机森林分类器与 Alteryx Machine Learning 构建的 XGBoost 分类器的性能类似。这两种工具都完成了建模工作,但是都有不同的接口和解释性信息。
如果我们担心在感恩节收到的请求是否会影响该请求能否在 24 小时内得到解决,那么,事实证明这是预测结果的最不重要的因素。相反,投诉的类型、地点和机构在模型的预测中更为重要。

图片 via GIPHY
甜点:预测和更多
建模过程帮助我们更深入地了解了假期如何影响服务请求的结束时间(或者没有影响,在这种情况下,因为“在感恩节”功能与这些模型中使用的其他功能相比并不是非常重要)。将来,我们还可以使用我们最喜欢的模型来预测具有特定特征集的服务请求是否会在 24 小时内完成和关闭。这些信息有助于引导客户的期望和形成响应流程。
原载于 Alteryx 社区数据科学博客 。
用高斯过程预测封锁的结束
原文:https://towardsdatascience.com/predicting-the-end-of-lockdown-with-a-gaussian-process-84b253bc1a88?source=collection_archive---------47-----------------------
我们能使用高斯过程预测每日接种疫苗的数量吗?

新冠肺炎接种疫苗,图片由 pixabay
截至本文撰写之时(2021 年 2 月 7 日),英国正处于另一场全国封锁之中,看起来我们摆脱封锁的最佳机会是为弱势群体中的每一个人接种疫苗,这相当于大约 1500 万人。迄今为止,接种疫苗的总人数约为 1100 万,那么我们什么时候才能达到神奇的 15 人呢?在本文中,我们将尝试使用高斯过程来模拟每日剂量,并尝试估计封锁可能结束的时间…
数据
gov.uk 网站为我们提供每日更新的疫苗接种数据,他们将数据分为第一剂和第二剂。我们的模型将只关注第一剂,因为政府的政策是第二剂要等 12 周。

原始数据—按作者分类的图像
系统模型化
考虑到我们想用少量的数据对未来做出预测,在我们的预测中提供不确定性是特别重要的。高斯过程(GP)模型非常适合这种回归任务。
我不会在这里详细介绍 GPs 及其基本理论,因为这本身就是一整篇文章,但这里有一些我们将利用的模型的好处。
GPs 是一种非参数贝叶斯模型,可用于分类和回归任务(本例中为回归)。与贝叶斯参数模型不同,在贝叶斯参数模型中,我们在模型的参数上定义先验,GP 更进一步,在所有可能函数的无限空间上定义先验。它们变得易于处理,因为我们只关心函数在有限数量的点上的值(特别是训练点和测试点)。

后验预测分布,作者图片
后验预测分布是噪声、数据和核函数的函数。我意识到我在这里跳过了很多理论,Bishop [1]对细节做了很好的解释。在本文中,我想探讨的主要问题是好的内核设计(k(x_i,x_j))如何影响模型性能。
有许多不同的 Python 包可用于 GPs,但为了简单起见,我选择使用 sk learning 实现。
对于一个 GP 建模任务(或者实际上任何建模任务),从简单开始,逐步发展到复杂是值得的。因此,让我们从一个如下所示的内核开始:
kernel = RBF(length_scale=5) + \
WhiteKernel(noise_level=0.5) + \
ConstantKernel()
具有 RBF 核的 GP 是一种通用函数逼近,允许任意曲线拟合数据。它由确定信号变化速度的长度比例参数控制。长度比例越大,曲线变化越慢。

RBF 内核,图片来自 Sklean
白核允许对独立同分布(iid)噪声进行建模,而常数核允许非零均值。

常量内核,图像来自 Sklean
如果我们符合这个模型,我们得到以下结果:

径向基函数,白色和常数核,作者图片
该内核显然能够在训练数据的支持下学习数据的趋势。在支持区域之外,内核所能做最好的事情就是估计训练均值。
我们可以做两件有用的内核设计。首先是注意数据的增长趋势,即我们每天的疫苗数量仍在增加。其次,数据存在明显的周期性。尚不清楚这是由于周末报告不佳还是疫苗数量实际上较少。无论哪种方式,都没有关系,我们仍然可以尝试并将其包含在我们的模型中。
首先,让我们试着解决疫苗的日常增长。这最好通过允许多项式趋势建模的DotProduct乘积内核来实现。

点积内核,图像由 Sklearn

添加了线性点积内核的 GP,图片由作者提供
这看起来稍微好一点,但像这样的线性增长是非常乐观的…我发现我们不太可能在 2 月 28 日之后每天为 100 万人接种疫苗!所以我们可以通过使用DotProduct() ** 0.5来降低音量。

GP 带 DotProduct() ** 0.5 添加,图片由作者提供
我认为这似乎更合理。我们已经把增长率降低到一个平方根关系,这看起来更合理。
现在让我们试着解决函数的周期性质。我们可以通过增加ExpSineSquared来实现。

指数正弦内核,图像由 Sklean
很容易看出,当x_i和x_j之间的距离为0或Np时,这个核函数被最小化。这使我们能够模拟像我们这样的周期函数!

添加了 ExpSineSquared(句点=7)的 GP,图片由作者提供
现在我们能够很好地模拟周期性了!
模拟累积疫苗接种数量
所以,我们对每日疫苗模型相当满意。现在,我们可以从全科医生的后半部分获取样本时间序列,并对首剂的累积数量进行建模。

累积首剂,作者图片
回想一下,我们的模型是根据 14 天的数据(1 月 11 日到 1 月 25 日)训练的,我们预测的是未来一个月的值。如果我们看看 2 月 5 日的模型预测,它预测的疫苗总数平均为 1109 万支,而实际值为 11.47 支,在预测未来 10 天时,误差仅为 3%。如果你问我,那对几个小时的模型来说是不错的!
我们什么时候能达到神奇的 15 米?
我们在前 14 天训练的模型预测,我们将在 2 月 9 日至 26 日之间以 95%的置信度达到 1500 万次累积首剂。如果我们在所有可用数据上重新训练该模型,那么我们可以以 95%的置信度将不确定性降低一点,使其介于第 11 和第 19 之间。

全科医生接受了所有可用数据的再培训,图片由作者提供
值得注意的是,并不是所有的 1500 万疫苗都将用于最易感染的 4 类人群,所以我们可以将这一预测推迟几天。
我们学到了什么?
希望本文已经展示了建立和运行一个 GP 模型是多么容易,如何通过使用关于问题的先验信息来调优/设计您的内核函数,以及如何使用该模型进行带有内置不确定性的预测!
不用说,随着 COVID 病例下降和死亡人数超过高峰,疫苗接种仍在增加,如果我们继续朝着正确的方向前进,我们可以很快看到限制被取消…
声明:本文由亚历山大·贝利以个人身份撰写。本文中的观点和模型是作者自己的,并不反映我的雇主或英国政府的观点。
参考
[1]毕晓普,c .,2016。模式识别与机器学习。纽约斯普林格出版社,第 303 页
预测未来:学会用 Arima 模型预测
原文:https://towardsdatascience.com/predicting-the-future-learn-to-forecast-with-arima-models-2c41eaa8b548?source=collection_archive---------29-----------------------
是什么让 Makes 天体对预测如此有用?

图片来自pix abayAlexas _ Fotos
XTS 物体
如果您没有使用 XTS 对象来执行 R 中的预测,那么您很可能会错过!我们将从头到尾探讨的主要好处是,当涉及到建模、预测和可视化时,这些对象更容易使用。
让我们来看看细节
XTS 物体由两部分组成。第一个是日期索引,第二个是传统的数据矩阵。
不管你是想预测客户流失、销售、需求还是其他什么,让我们开始吧!
您需要做的第一件事是创建日期索引。我们使用seq函数来实现。非常简单,这个函数获取您的开始日期、您拥有的记录数量或长度,然后是时间间隔或by参数。对我们来说,数据集从以下内容开始。
days <- seq(as.Date("2014-01-01"), length = 668, by = "day")
现在我们有了索引,我们可以用它来创建我们的 XTS 对象。为此,我们将使用 xts 函数。
别忘了install.packages('xts')然后加载库!library(xts)
一旦我们完成了这些,我们将调用 xts 并传递我们的数据矩阵,然后对于日期索引,我们将把索引传递给order.by选项。
sales_xts <- xts(sales, order.by = days)
让我们用 Arima 创建一个预测
Arima 代表自回归综合移动平均线。一种非常流行的时间序列预测技术。我们可以花几个小时单独谈论 ARIMA,但对于这篇文章,我们将给出一个高层次的解释,然后直接进入应用程序。
AR:自回归
这是我们使用前几个月的滞后值或数值来预测结果的地方。某个月的结果可能在一定程度上依赖于以前的值。
I:集成
当谈到时间序列预测时,一个隐含的假设是,我们的模型在某种程度上依赖于时间。这似乎很明显,否则我们可能不会让我们的模型基于时间;).假设不存在了,我们需要理解时间相对于我们的模型在依赖谱上的位置。是的,我们的模型依赖于时间,但多少呢?这个的核心是平稳性的思想;这意味着时间的影响随着时间的推移而减少。
更深入地说,数据集的历史平均值往往是未来结果的最佳预测器…但肯定有不正确的时候..你能想到历史平均值不是最佳预测值的情况吗?
- 预测 12 月份的销售额怎么样?季节性趋势
- 高速增长的 saas 公司销售情况如何?持续的上升趋势
这里就介绍了差分的过程!差异用于消除趋势&季节性的影响。
马:移动平均线
移动平均线模型的存在是为了处理你的模型的误差。
让我们开始建模吧!
培训/验证分割
首先,让我们将数据分解成一个训练数据集,然后我们称之为验证数据集。
这与其他验证测试(如交叉验证测试)的不同之处在于,我们在这里按时间划分,将训练划分到给定的时间点,并对之后的所有内容进行验证。
train <- sales_xts[index(sales_xts) <= "2015-07-01"]
validation <- sales_xts[index(sales_xts) > "2015-07-01"]
是时候建立一个模型了
auto.arima函数包含了我们刚刚谈到的逼近最佳arima模型的想法。我将在另一篇文章中详细介绍更实用的方法,但下面我将探索一个auto.arima模型的生成以及如何使用它进行预测。
model <- auto.arima(train)
现在让我们生成一个预测。与之前一样,我们将创建一个日期索引,然后用数据矩阵创建一个 xts 对象。
从这里开始,您将绘制验证数据,然后将预测放在绘图的顶部。
forecast <- forecast(model, h = 121)
forecast_dates <- seq(as.Date("2015-09-01"), length = 121, by = "day")forecast_xts <- xts(forecast$mean, order.by = forecast_dates)plot(validation, main = 'Forecast Comparison')lines(forecast_xts, col = "blue")

结论
我希望这是一个对 ARIMA 预报有帮助的介绍。一定要让我知道什么是有帮助的,以及你想了解的任何其他细节。
如果你觉得这很有帮助,一定要看看我在datasciencelessons.com上的其他帖子。祝数据科学快乐!
预测人工智能的未来
原文:https://towardsdatascience.com/predicting-the-future-of-ai-98deb3c49fe8?source=collection_archive---------48-----------------------
苹果 | 谷歌 | SPOTIFY | 其他
Owain Evans 在 TDS 播客
要选择章节,请访问 Youtube 视频这里。
编者按:这一集是我们关于数据科学和机器学习新兴问题的播客系列的一部分,由 Jeremie Harris 主持。除了主持播客,Jeremie 还帮助运营一家名为sharpes minds的数据科学导师初创公司。你可以听下面的播客:
收听苹果、谷歌、 Spotify
大多数研究人员同意,我们最终将达到这样一个点,即我们的人工智能系统开始在几乎每一项有经济价值的任务上超过人类的表现,包括从他们所学到的东西中进行归纳的能力,以承担他们以前从未见过的新任务。这些人工智能(AGIs)很可能会对我们的经济、社会甚至人类产生变革性的影响。
没有人知道这些影响会是什么,或者什么时候 AGI 系统会发展到可以带来这些影响。但这并不意味着这些事情不值得预测或估计。我们对为重要的人工智能伦理、安全和政策问题开发强大解决方案的时间了解得越多,我们就越能清楚地思考今天哪些问题应该得到我们的时间和关注。
这就是激发大量人工智能预测工作的论点:试图预测人工智能发展的关键里程碑,通往 AGI 和超人人工智能的道路。这个领域还处于早期阶段,但它已经受到越来越多的人工智能安全和人工智能能力研究人员的关注。其中一名研究人员是 Owain Evans,他在牛津大学人类未来研究所的工作重点是通过观察人类行为或与人类互动来了解人类信仰、偏好和价值观的技术。Owain 和我一起参加了这一集的播客,谈论人工智能预测,推断人类价值的问题,以及支持这种类型研究的研究组织的生态系统。
以下是我在对话中最喜欢的一些观点:
- 试图预测 AGI 何时发展的最重要因素之一是神经网络和其他现有策略是否足以让我们到达那里。如果是这样的话,那么通往 AGI 的道路只不过是扩大现有技术,而不需要进一步的概念突破。这是强化学习先驱理查德·萨顿(Richard Sutton)在他 2019 年关于“痛苦的教训”的文章中认可的一种可能性。他认为,我们应该从过去 70 年的人工智能研究中吸取教训:人工智能的大多数进展都来自规模扩大,而不是概念突破。然而,除了神经网络和反向传播之外,在一般任务上实现人类和超人的表现可能需要一些新的想法。如果这被证明是真的,那么 AGI 不仅是一个工程挑战,也是一个理论挑战——时间跨度可能更长。
- 人工智能预测的研究现在已经持续了几年——足够的时间让我们开始回顾过去的预测,以更好地理解我们在预测人工智能里程碑时往往会犯的错误类型。到目前为止,Owain 确定了一个共同的主题,即研究人员往往高估了在自然语言建模方面取得进展所需的时间,引用了机器翻译和高中水平的论文写作等具体例子,在这些领域,人类水平的表现可以说已经被一些当前的人工智能系统接近或达到。
- 预测 AGI 到来的挑战之一是我们目前缺乏可接受的概括能力的标准。结果,人们仍然不同意前沿模型(如 OpenAI 的 GPT-3)可以推广到什么程度,也不同意当前技术可能位于 AGI 能力曲线的哪个位置。现在有越来越多的努力致力于寻找良好的一般化度量,但时间会告诉我们哪些将被广泛采用,哪些在被接受为真正的一般智力指标之前必须进行修改。
你可以在推特上关注欧文,或者在推特上关注我。
播客中引用的链接:
- 人类未来研究所的网站。
- Owain 的个人网站,在这里你可以读到更多关于他的研究。

章节:
- 0:00 介绍
- 4:42 人工智能政策和人工智能协调组织的现有生态系统
- 8:11 各组织正在研究的不同论题
- 13:30 概括的能力
- 17:35 时间线中的模式
- 21:07 反对强大的语言模型
- 27:49 反驳
- 30:03 解决技术一致性问题的挑战
- 39:49 什么是 IDA?
- 47:06 总结
请查看下面的文字记录:
杰里米·哈里斯(00:00):
大家好。欢迎来到播客。今天我们采访的是牛津人类未来研究所的欧文·埃文斯。Owain 对研究技术感兴趣,这种技术可以让机器在与人类互动的基础上了解人类的偏好和价值观。现在这项工作相当复杂,它整合了机器学习、认知科学甚至分析哲学的知识,这是 Owain 一直在研究的领域,甚至在深度学习普及之前。但是 Owain 做了大量工作的一个领域是 AGI 时间线的问题,我们将在这里讨论这个问题,预测人工智能道路上的关键里程碑。
杰里米·哈里斯(00:35):
现在,这显然是一个重要的领域,因为对 AGI 时间表的预测也告知我们今天采取什么样的行动来达到这些不同的里程碑。如果我们自信地知道人工通用智能就在眼前,这将立即意味着我们可能不会在政策和人工智能安全方面采取某些行动。同样,如果我们认为人工智能的时间表可能会更长,那么在这个阶段更多地投资于政策和能力研究,而不是过多地担心存在风险或任何其他可能伴随后期 AGI 情景的事情,可能是有意义的。因此,我们围绕人工智能时间表以及这些对人工智能安全政策研究的影响,深入探讨了许多问题。我真的很喜欢这次谈话,希望你也是。
耶雷米·哈里斯(01:22)
嗨,非常感谢你和我一起参加播客。
欧文·埃文斯(01:25):
很高兴来到这里。
耶雷米·哈里斯(01:27)
哦,真高兴有你。你是致力于人工智能安全、人工智能校准、人工智能政策的许多人之一,但你也是,我认为迄今为止我交谈过的唯一一个在人工智能校准和人工智能政策方面都做了大量工作的人。所以我认为,关于这两个空间的交集,我们可以探讨很多有趣的东西。我认为这里有很多有趣的互动,但在我们开始之前,我能不能问一下,你是如何开始发现这个空间的?
欧文·埃文斯(01:53):
是的,所以我走了一条弯路,我想。高中的时候对 AI 很感兴趣。我读了史蒂芬·平克的《思维是如何工作的》和道格拉斯·霍夫施塔特以及雷·库兹韦尔的一些这方面的著作,我认为人工智能在我有生之年将会是一件大事,基本上是因为思维是计算性的,而摩尔定律意味着将会有越来越多的计算。所以我想知道为什么人们没有更认真地对待这个问题,特别是在学术界,所以我想我会学习数学、心理学和哲学,这将帮助我对这个问题有更多的理解。所以我就这么做了。
欧文·埃文斯(02:36):
快进到研究生院。我当时在麻省理工学院,走进了乔希·特南鲍姆的一堂课,讲的是计算认知科学。这就是使用统计学和机器学习的技术来理解高等认知的想法,这看起来似乎是一个显而易见的想法,现在你可以使用人工智能来尝试和理解人类语言,但我认为这在当时肯定不太为人所知。
杰瑞米·哈里斯(03:09):
那会是哪一年?
欧文·埃文斯(03:12):
所以这就像 2010 年。
耶雷米·哈里斯(03:15)
哦,哇。好吧。
欧文·埃文斯(03:16):
所以我和特南鲍姆一起上了这门课,我发现这种结合,一方面是人类的认知,另一方面是人工智能,非常迷人。当学生们学习计算认知科学时,我和乔希·特南鲍姆一起完成了几篇论文。与此同时,我仍然对这些关于人工智能和人类水平人工智能的长期问题非常感兴趣。所以我从麻省理工学院抽出一段时间,去牛津大学人类未来研究所做了一次访问,当时尼克·博斯特罗姆正在研究超智能。所以写这本书也是一个学习和思考人工智能的好环境。当我回到麻省理工学院完成我的博士学位时,我决定更多地关注机器学习方面,而不是认知科学和人类思维,人类大脑方面。
欧文·埃文斯(04:18):
所以我在麻省理工学院完成学业,然后回到牛津大学人类未来研究所做博士后,我有机会研究对齐,特别是将超智能中提出的对齐问题与机器学习结合起来,所以尝试对齐机器学习系统。
杰里米·哈里斯(04:42):
有趣的是,人类未来研究所在这个领域的许多人的历史中发挥了多么重要的作用,尼克·博斯特罗姆的书当然是其中的一大部分,但从那以后,我们也看到了许多其他组织的出现,其中许多组织你也发挥了重要作用。那么你能提供一点概述吗?从人类未来研究所开始,目前存在的人工智能政策和人工智能联盟组织的生态系统是什么?
欧文·埃文斯(05:09):
是的,所以他们分散在不同的部门。所以你有学术界,非营利的,所以他们是独立的,然后是工业或公司。因此,在学术界,有人类未来研究所,我已经提到过,它既做技术调整,研究,机器学习风格和政策工作。还有一个叫柴的群聊,人工智能兼容中心,几年前我在那里做过访问学者。由斯图尔特·拉塞尔领导,总部设在加州大学伯克利分校。雅各布·斯坦哈特(Jacob Steinhardt)是一名研究人员,他在加州大学伯克利分校也有一个小组在做非常有趣的研究。因此,这是侧重于人工智能的技术方面,而不是政策。在学术界之外,但在非营利领域,有机器智能研究所,它也像人类未来研究所一样已经存在了一段时间,他们真的专注于人工智能的理论基础,也专注于联合人工智能。所以这是一个更数学化的方法。
欧文·埃文斯(06:31):
有一个开放慈善项目,它既资助这一领域的研究,因为他们实际上是非营利组织,资助这一领域的研究,也进行他们自己的内部研究,特别是在人工智能时间表的排序上,以及我们可能期待人工智能的不同里程碑有多长时间。所以有有趣的研究出来了。就工业和科技公司而言,有开放的人工智能,人们可能知道它正在进行像 GPT-3 这样令人兴奋的研究,但它也有一个关于安全性和一致性的相当大的倡议。因此,该小组致力于协调、透明度、安全强化学习,以及人工智能的政策和预测。
欧文·埃文斯(07:35):
然后是 DeepMind,它是做人工智能研究主流的另一个主要参与者,但他们也有一个团队致力于长期问题和安全,还有一些团队致力于机器学习安全以及政策和道德方面的工作。所以他们也有一个很好的…虽然一切都是新的,对,深入的参与了一段时间的安全研究,并与牛津大学合作。
耶雷米·哈里斯(08:11):
是啊。我发现这个领域非常有趣的一件事是,你对 AGI 时间表的看法将是决定你在短期人工智能政策方面、人工智能调整方面工作的一个重要因素,而倾向于拥有较短时间表的组织将倾向于更多地关注紧迫的安全和调整问题,组织的较长时间表,也许还有其他事情。这些组织中的每一个都在做他们正在做的事情,因为他们对 AGI 的时间表和 AGI 在未来 5 年、10 年、30 年出现的可能性有特定的看法。你对这些组织提出的不同论点了解多少?这些论点对他们的工作有何影响?
欧文·埃文斯(08:49):
是的,所以我认为…没错。我认为这些组织的论文在他们正在进行的关于一致性的研究中发挥了作用。我认为最基本的区别是,如果你认真看待当前的系统,如果你把它们放大到足够大,可能会导致 AGI,那么你会倾向于有更短的时间表,可能是因为你认为我们不需要一些根本性的概念突破。你也可能会…认为排列研究者更紧迫和更可行。我们可以研究我们目前的系统,你认为那种未来的 AGI 系统只是那些系统的放大版本。然而,如果你认为我们需要概念上的突破来实现 AGI,那么你会认为这可能要晚得多,因为我们需要先有那些突破。第二,今天可能很难研究调整,因为我们不知道我们需要什么样的系统来调整。我想我对将非常特殊的观点归因于包含许多个人的整个组织持谨慎态度。
耶雷米·哈里斯(10:14):
有这么多的差异是很有趣的。你对时间表有什么个人看法吗?
欧文·埃文斯(10:22):
我的意思是,我认为你应该有点忙和概率性,所以我认为在两端都有不确定性,对吗?也就是说,有些事情可能很快就会发生,有些事情可能真的需要很长时间,而目前的技术是渐近线。所以,是的,我不想给出一个数字,但我认为即使在未来 20 年内人工智能出现的可能性只有 5%,我认为这仍然是一件大事,仍然是你应该认真对待的事情。因此,当考虑要做多少一致性研究时,我再次认为即使很快实现 AGI 的概率相当低,也可能是一个很好的赌注,在这方面做更多的研究,只是让我们更好地了解一致性可能存在的问题以及我们如何开始解决它们。
耶雷米·哈里斯(11 时 32 分)
你感觉到有一种普遍的转变吗?也许我是错的,但我的感觉是随着 GPT-3 的出现,有一个普遍的转变,即把神经网络和反向传播作为一条通往 AGI 的道路更认真一点。GPT-3 有没有以任何方式改变你的视角,GPT-2 或者开放人工智能看到的任何缩放结果?
欧文·伊文斯(11:58):
是的,我认为 GPT-2 和 3 改变了我的看法。我认为,已经有很好的论据和证据表明,你真的可以通过扩大模型规模,通过创建更大的神经网络,在更大的数据集上训练它们更长时间,来实现很多目标。但是我认为 GPT 2 号和 GPT 3 号的表现比我预期的更令人印象深刻。我认为模特们更擅长掌握这一系列的技能。因此,有一种元学习方面或少量学习,然后能够做基本的数学,真正的基本算术,然后就是系统似乎吸收的知识广度,既有关于人类语言的知识,又有关于如何构造好句子的知识,还有关于事实的知识。
欧文·伊文斯(13:07):
所以,是的,我认为这不是一种完全的震惊,因为我非常密切地关注着这个领域,在 GPT-2 和 GPT-3 之前,语言模型已经做了非常令人印象深刻的事情,但我认为他们能做的事情确实令人惊讶。
耶雷米·哈里斯(13:30):
是的,实际上对我来说最大的惊喜之一是社区中不同的人对 GPT-3 的反应,这是一个多么两极分化的发展。有些人似乎在说,“哦,我们有 AGI,这是 AGI 原型。”其他人说,这是如此有限的能力。简直太合身了。人们似乎完全分为完全震惊或完全不惊讶和仍然只是怀疑。这里的部分挑战是,我们不一定有能力评估归纳能力。就模型评估而言,这就像是一个新的领域,因为我们已经在评估方面做了很多狭隘的人工智能工作,但不一定是更通用的系统。你对这方面有什么想法吗?比如我们如何定义这种归纳能力?换句话说,即使我们谈论 AGI,我们真正在辩论什么?
欧文·埃文斯(14:27):
是的,这些都是很好的问题。所以我认为,对,我们看到 GPT-3 在 NLP 任务的传统基准上做得非常好。因此,我们可以通过各种具体指标看到,它是对以前模型的改进。然后我们可以像他们那样发明新的任务,看看他们在这些任务上做得如何,看到令人印象深刻的表现,例如,在算术,类比和使用新词上。但这不同于一个真正系统的概括测试。所以这将是新研究的一个重要领域。Francoise Chollet 是开发[Caris 00:15:15]的人,他开发了一种基准,就像一套任务,试图获得这种更广泛的丰富的概念概括的概念,所以这些任务有点像瑞文矩阵或智商测试。这只是朝着这个方向迈出的第一步,但我认为尝试做更多的工作,这是具有挑战性的研究工作,但你在测试这种似乎很有前途的概括。
欧文·伊文斯(15:52):
而 GPT-3,你可以有一个版本,更侧重于语言或喜欢用语言表达事情。但是另一个衡量标准是经济的,对吗?因此,开放人工智能已经创建了这个 GPT-3 API,许多公司将探索他们是否可以使用 GPT-3。因此,在某种程度上,我认为我们将会看到这个系统是否足够灵活,能够应对现实世界的挑战,并真正提高公司的指标?因此,我认为这在学术论文中更难评估,但我认为这将是一个有趣的领域,可以发现,这是否具有导致性能真正大幅提高的鲁棒性?
耶雷米·哈里斯(16:38):
是的,这真的很有趣,因为我们很难预测我们已经有明确指标的事物的性能,现在预测概括能力,我们不知道…我们甚至不知道在这个阶段如何表达这意味着什么。这似乎是一个非常特别的挑战。在这种情况下,你实际上整理了一篇发表于 2018 年的作品,其中你对人工智能专家进行了一些民意调查。我想我们之前谈论的民意调查,你提到民意调查是在 2016 年进行的,但我只是想宣读一个快速摘录,其中的几个句子,因为我认为它们真的很有趣。所以这是抽象的,只是写研究人员预测 AI 将在未来 10 年内在许多活动中超过人类,例如到 2024 年翻译语言,到 2026 年写高中作文,到 2027 年开卡车,到 2031 年从事零售工作,到 2049 年写畅销书,到 2053 年做外科医生。
耶雷米·哈里斯(17:35):
我认为真正有趣的是回想起来,这是四年前完成的工作,有争议的是,我们已经开始触及或至少触及其中的一些里程碑。目前还不清楚语言翻译是否真的存在,比如卡车驾驶,但是你有没有注意到我们比预期完成得更快的事情的模式,或者人们一直在犯的预测性错误,即使他们是这个领域的专家?
欧文·埃文斯(18:02):
是啊,没错。在最初的调查完成四年半或五年后,我们就要开始了。所以,是的,我认为我们可以开始获得一些信息,这些类型的预测在哪些方面做得好,在哪些方面做得不好?如你所说,我认为翻译的进展比人们预期的要快。所以他们预测 AI 要达到业余翻译水平还需要 7 年半,所以不是专业翻译。
耶雷米·哈里斯(18:37):
哇哦。
欧文·埃文斯(18:39):
所以在四到五年后的今天,我认为我们已经达到了那个水平,即使是复杂的语言,更难翻译的语言。他们预测在所有雅达利游戏中击败人类需要九年时间,我认为我们也在那里,最多四年,四年或五年。然后写一篇高中论文,我认为 GPT-3 或者 GPT-4 会在那里,更像是五年或六年,而不是他们预测的 10 年。因此,在这些领域,他们对人工智能的发展有些悲观。值得注意的是,这些是中值估计,所以人们实际上给出了这种情况何时发生的概率。例如,当他们说高中作文需要 10 年时间时,他们实际上给出了 25%的概率可以实现,对吗?所以五年后有四分之一的可能性会发生,十年后有 50%的可能性会发生。
欧文·埃文斯(19:54):
所以你会预期四分之一的事件会发生。所以我觉得总的来说,他们的预测看起来还是比较合理的。他们说的事情真的不太可能,例如,艾写了一本纽约时报畅销书,艾赢得了普特南数学竞赛。这些事情都没有发生。他们说的事情真的很有可能,其中一些已经发生了。所以他们有些说对了。所以我认为涉及语言的任务进行得比预期的要快。一些机器人任务可能比预期的稍慢。如果说有什么教训的话,那部分是规模假说,或者说,如果你真的可以扩大你的模型,扩大数据来训练它们,那么你就可以相当快地取得进展。如果你没有这些,就像你没有…在机器人领域,你就没有同样廉价丰富的数据或训练样本。所以速度会慢一点。
杰瑞米·哈里斯(21:07):
是啊。看到这些不同的分歧真的很酷。你提到的一件事是,是的,所以纽约时报畅销书是一个真正困难的任务,还没有完成。这可能是一个不可能回答的问题,但这可能是一个有趣的小问题。你认为目前是什么阻碍了真正强大的语言模型的发展,这些语言模型可以完成各种归纳任务,翻译语言等等,在这和我们有一本由人工智能写的纽约时报畅销书之间有什么关系?
欧文·伊文思(21:38):
我的意思是,我认为最直接的方法可能就是提高我们现有的水平。是的,所以就如何实现这一目标而言,我认为最有希望的方法是致力于扩展,这意味着找到如何建立比 GPT-3 更大的模型,并为它们生成更大的数据集,同时更高质量的数据集也会有所帮助。探索架构,尤其是架构有助于利用计算的程度。因此,我认为在我们如何获得更好的性能方面,将会发生很多事情。就像 GPT-3 这样的系统可能做得不太好,或者看起来像当前的限制而言,我认为 GPT-3 和人类之间最大的差距可能基本上是依赖范围有多长,或者模型作用的持续时间有多长。
欧文·埃文斯(22:57):
因此,如果有人写了一本《纽约时报》畅销书,他们可能会花几年时间来写这本书,他们在这段时间里所做的所有工作都有助于这一产出。因此,他们可能会在某一天写下一些笔记,然后在六个月后重温这些笔记,并在此基础上进行扩展。没错。而 GPT-3 读取大约 500 个单词,然后产生一些输出,它所做的一切都依赖于这 500 个单词,而不是其他。没错。所以如果你试图用它来创作一部小说,在它创作了 5000 个单词之后,它只会关注它所写的最后 500 个单词。对吗?所以之前所有其他的东西可以说是完全脱离了它的思维。这是大多数真正复杂的人类工作之间的巨大差异,比如做数学和我们的机器学习模型,我们的机器学习模型今天运作的方式。
欧文·埃文斯(24:03):
因此,我认为,如果人们希望纵向扩展架构,我认为他们会考虑长期的、更长期的依赖关系,比如能够…当你产生下一个 100 个单词时,你不只是在看前面的 500 个,而是在某种意义上,你有一个像整本书的上下文的表示。
耶雷米·哈里斯(24:25):
有趣的是,你对这个问题的回答非常实用,就像《GPT 3》成为《纽约时报》畅销书的障碍一样。你可能会想,好吧,计算这个,那个,所有这些你能想象的在几年甚至几个月内被工业部署的东西,然后概念方面有点滞后,这几乎是从典型的科学发现发生的方式倒退。我的意思是,通常人们必须想出一个理论,他们必须明白他们在建造什么,然后他们制定一个计划来建造那个东西。
杰里米·哈里斯(25:01):
在这个领域中,似乎至少有一种在我们期望自己建造之前建造某物的前景,正在建造这些强大系统的人可能不知道他们正在建造的东西将会变得几乎和它一样强大。这在人工智能安全方面有风险吗?就像,有没有一个真正的前景,让一个团队建立一些他们可能做不到的东西…从他们组合在一起的角度来看,咬下比他们能够咀嚼的更多的东西?
欧文·埃文斯(25:31):
我认为这种进步仍然是相当渐进的。所以我认为记住这一点很重要,对吗?在 GPT-3 之前,显然有 GPT-2,但也有一系列比 GPT-2 更大的型号问世,它们也有相当令人印象深刻的性能。这些来自其他公司,如谷歌和微软。有一个很大的社区在生产人工智能系统,并制作一个比其他人的系统稍微好一点的系统,对吗?是有利的。所以我认为,当有重大发现或重大进展,如 GPT-3,让人们兴奋时,我认为你会有更多…你会有更多的团体进入那个领域,然后你会看到那个领域的这种渐进的进展。
欧文·伊文斯(26:23):
因此,我认为,那些真正关注该领域动态并跟踪最新发展的人,他们会看到一种更渐进的方式,因此对发展不会感到惊讶。与此同时,我认为试图预测某个特定体系结构可能具有什么样的功能,我认为还没有成功。所以有些人说,如果没有类似于变形金刚或 rnn 的复古模型,我们将无法进行元学习或少量学习。我认为那些预测只是有一个糟糕的记录。所以很多人都说了,看,深度学习还不够。你需要将它与符号人工智能结合起来,或者你需要更丰富的架构,包括可写存储器或基于神经网络,比如基于不确定性。我认为,非常简单的神经网络在适当的长时间训练和大量训练数据的支持下,已经显示出了一种能力,可以做一系列人们没有想到的事情……许多人说这是不可能的。
欧文·伊文思(27:38):
所以我认为在这个意义上你是对的,在非常简单的技术放大后实际上可以实现的东西中会有惊喜。
耶雷米·哈里斯(27:49):
我想有一个天真的论点是…我很想听听你对这个非常天真的观点最常见的反驳是什么,因为我认为会有说明,但神经网络是通用函数逼近器,所以当你这么说的时候,它们在原则上是不能逼近的函数,就认知甚至意识是一个函数而言,它们应该能够在某种规模上对某种配置进行模拟。有哪些主要的反驳观点认为这显然是深度学习的典型乐观案例?对,符号神经网络论点是什么,或者其他论点是什么?
欧文·埃文斯(28:28):
是啊。所以我认为普遍近似论点或普遍性论点,我的意思是,只是说它是可能的,存在于神经网络中,可以表示任何函数。我认为最初的构造,它们是如何证明这是可能的,是一种极其低效的编码,是一种不切实际的庞大的函数表示。所以理论上我们真正感兴趣的是是否有一个足够小的神经网络可以捕捉这个函数,小到我们可以实际上用一些实际数据训练这个神经网络,实际上适合我们的计算资源。所以如果你需要比宇宙中可能的更多的计算,或者在地球上可能的,对吗?理论上是否有这种可能性并不重要。
欧文·埃文斯(29:35):
我认为仅仅这些神经网络的存在和它们在其中所具有的灵活性并不能真正说明什么,这就是为什么这个领域,虽然机器学习领域的人知道这些普遍性的结果,但我认为在 80 年代末,90 年代初,并不是每个人都进入神经网络,因为他们不知道你是否能找到足够小的神经网络来拥有这种能力。
杰瑞米·哈里斯(30:03):
是啊。我是说,考虑约束总是很有趣的。我想问你的另一个领域是人工智能技术安全和人工智能校准研究,因为这也是你正在做的事情。经常听到人工智能安全研究人员说对齐是一个非常困难的问题,但他们经常提出不同的困难原因。您认为解决技术一致性问题最具挑战性的部分是什么?
欧文·埃文斯(30:29):
是的,所以我认为从某种意义上来说,我们不知道这个问题有多难,因为人们没有花那么长时间研究它,只是没有花那么多时间研究这个问题,如果你把它与计算机科学中已经解决的许多问题相比的话。所以我认为时间会证明这有多难。就最大的困难是什么而言,这是一个困难的问题。我认为在某种程度上,具有挑战性的事情是机器和研究是相当经验性的。因此,通常你取得进展的方式是通过进行实验,看看不同的模型在非常真实的世界任务中实际上做得如何,如对物体和图像进行分类或翻译语言,在纯理论的机器学习中很难做很多工作并取得很大进展。
欧文·埃文斯(31:26):
因此,当谈到调整时,我们真的不能做同样的事情,因为我们今天没有系统,我们调整它们是至关重要的,否则它们会造成很大的伤害。所以我们可以做一些小规模的实验来尝试阐明这个问题,或者我们可以做理论,但是我认为我们不知道这项研究将如何转化为实际解决我们需要解决的真正问题。因此,我认为在元层面上,这是困难的原因,也是为什么没有更多比对研究的部分原因,我认为这是因为,机器学习中最有利可图或最有用的方法是这种更客观的方法,在这种方法中,你实际上……就像如果你想证明你可以改善计算机视觉,那么你实际上可以改善像 image net 这样的真实世界视觉任务的结果。
杰瑞米·哈里斯(32:29):
是啊。我想其中一个原因也是当前的限制和一些人工智能系统的能力。就像你说的,他们就是做不到,他们不够强大,需要联合起来。最近我一直在想的一件事是,随着我们系统的能力增加,我们从这些人工智能系统中挤出更多价值的能力将开始取决于我们调整它们的能力。因此,在某种意义上,这几乎是一种经济激励,我们将更加有机地开发比对研究。你认为这是一种合理的方式吗?我们可以不需要有意识的努力去提前设置好环境,就可以得到安全的系统?我并不是提倡不要那样做,我只是有点好奇。
欧文·伊文思(33:14):
是啊。我认为这是很重要的一点。所以我认为校准的美好前景是,如果不面对校准问题,很难制造出一个经济上有用的系统。那会是一个很好的情况,对吧。这里没有不认真对待对齐的动机,因为你不能从你的人工智能中赚钱,除非你在对齐上认真工作。因此,我认为有一些合理的机会证明这是事实,在那个世界里,我认为,是的,我认为事情很可能会回到对齐。然后我认为也有一些可能性不是这样,这是一种更混乱的情况,我想象的场景是,有代理,有奖励功能或目标,你可以训练,使你的系统合理地对齐。
欧文·埃文斯(34:19):
在短期内,你可以通过使用这些代理运行人工智能系统来做得很好。只是,也许随着时间的推移,这种错位会变得更成问题,到那时,就很难改变系统了。也许,是的,在那个系统后面有很多…像很多动力,也许是金融动力。所以,是的,所以我认为我们今天可能有一些可能非常温和的形式,比如推荐算法,它们在某种程度上与用户保持一致。因此,他们通常会向用户展示有趣的内容,他们实际上是在优化某种参与度或人们在系统上花费的时间,这在某种程度上与用户不一致,因为用户希望沉迷于使用该服务或花费他们的时间,你知道,观看城市视频,所以也有一些问题,但该系统为公司赚了很多钱。
欧文·伊文斯(35:31):
所以当他们在想,哦,我们是不是应该抛弃我们的系统,建立一个更加一致的系统?坚持现行制度有经济利益。
杰里米·哈里斯(35:42):
是啊。我也听说过类似的关于社交媒体上政治极化的争论,如果算法可以改变用户,使他们更加极化,那么问题的维度就会减少,你就更有可能正确地预测下一个广告或下一篇帖子会被点击。哲学上有趣的一面是,特别是当从极化的角度来看时,我可以想象普通极化的人今天只是极化了,因为他们在过去的 10 年里一直在 Twitter 上,逐渐地他们有点绝热地移动到这个高度极化的位置。
耶雷米·哈里斯(36:20):
那个人今天很可能会说,看,你告诉我 Twitter,推荐算法是错位的。我在这里告诉你,我今天的信念感觉非常非常一致。换句话说,我很高兴我以这样的方式结束了极化。这是过去的我,有所有这些缺点,我很高兴我打破了它们。在某种程度上,就像一个邪教的普通成员会想的那样,谢天谢地,我遇到了邪教领袖,他们最终与我现在的样子,而不是过去的样子站在了一起。过去的自我和未来的自我之间的区别似乎很模糊,因为我们注定会改变,我们的道德规范注定会变得与过去的道德规范不可调和。也许那是无法解决的问题,但是你是如何看待这个问题的呢?
欧文·埃文斯(37:14):
是的,这是一个非常有趣的问题。首先,我认为还不清楚社交媒体能解释多少政治极化。我认为有更多的两极分化,比如老一代人较少使用社交媒体。所以我认为这是一个复杂的社会科学论点和故事,试图将社会的变化归因于技术,特别是人工智能技术,对吗?可能推特会有同样的效果,不管有没有人工智能的参与。所以我认为我们应该小心这些问题。但就人工智能系统而言,它会随着时间的推移改变人们的偏好,或者这些人对自己的结局感到满意,即使他们没有意识到这个过程。我想也许有这种可能性。
欧文·伊文斯(38:13):
我认为人们目前对使用这些技术的负面影响有相当多的认识。我认为总会有人不经常使用它们,对吗?谁置身事外,谁就会有一些不同的观点。我认为总的来说,人类对各种各样的新技术、新体验都非常敏感。所以人们非常担心广播、电视、电子游戏和电影。我认为,在许多方面,社会继续运行良好,甚至比以往任何时候都更好。因此,我认为将会有针对其中一些内容的防御机制,比如上瘾的内容或两极分化的内容,这些内容也使用人工智能来帮助人们筛选出实际上对他们更好的系统。
欧文·伊文斯(39:15):
从长远来看,重要的是要有这些,我猜是有一些外部视角的人。如果你认为人工智能系统真的会扭曲人们对世界的看法,而这些人很难真正保持意识,那么…我同意,这可能是一个重要的问题。是的,我认为我们离那个场景还有一段距离,但它值得思考和有趣。
耶雷米·哈里斯(39:49):
是啊。我想哲学、伦理学和这些东西之间有太多的交集,你几乎要比任何人知道的都多,才能理解这些。太好了。从技术角度看,我想问你的最后一件事是 IDA 的主题,这是一种调整策略,已经变得非常流行。我想问你这个问题,因为我知道你过去在这方面做过一些工作。我知道这不是目前的焦点,但你介意解释一下 IDA 是什么以及它是如何工作的吗?
欧文·伊文斯(40:17):
所以 Ida 代表迭代、提炼和放大。IDA 是一个人工智能训练的方案,它可以超越人类水平。这个想法很简单,首先你训练一个模型去模仿一个人,然后你训练第二个模型去模仿可以接触到第一个模型的人。所以能够调用第一个模型。然后你用第二个模型训练第三个模仿人类的模型,以此类推。对吗?因此,模型的下一代总是被训练来模仿与前一个模型有联系的人。所以关键的想法是,使用上一代的模型可以帮助人类更好地完成任务,这就是你如何随着时间的推移获得一种自举式的改进,这可以教会你超越人类的水平。所以更具体地说,想象这个模型就像一种人工智能系统,对吗?
欧文·伊文思(41:29):
它被训练来模仿人类,所以这就好像如果我能使用这个模型,这就是如果我能使用一种相当智能的助手来帮助我完成任务。所以你提到了 GPT 3 号的未来版本,比如 GPT 5 号。想象一下,我正在解决科学问题,比如说大学里有科学问题,如果我能向 GPT 五号提问,这可能会帮助我回答更难的问题,我自己就能回答。尤其是如果你想象一下向 GPT 5 号问了上百个问题,作为我试图回答一个问题的一部分,这可以增强我回答问题的能力。这使得你在原则上能够最终训练出一个比人类更好的系统。所以,超越人类的水平,不仅仅是在速度上,而是在质量上,比如系统的复杂程度。
耶雷米·哈里斯(42:29):
这里的对齐来自于各阶段的那种人为疏忽或模拟的人为疏忽…
欧文·埃文斯(42:36):
没错。所以有两个问题。它超越了人类的水平吗?它是一致的吗?我认为思考 IDA 为什么是一致的,是一种数学上的深度论证。所以最初的第一步是一个模型,它被训练来模仿人类,所以我们可以假设这是一致的,因为它只是模仿人类的行为。然后在下一个阶段,这个模型正在模仿人类,使用之前的模型。人类和之前的模型都是一致的。所以它们的组合应该是对齐的。所以如果你被训练去模仿,你应该得到一些对齐的东西,然后你继续你的论点,迭代。
耶雷米·哈里斯(43:22)
是那个论点…因为当我第一次遇到的时候,我想我最初是持怀疑态度的。这是我在这里的默认。感觉这是个很强的假设。这听起来好像是对的,但是当你实际检查时,它可能会崩溃。如果我训练一个人工智能只是为了模仿我,然后假设成功地训练了这个人工智能,它将与我对齐,这似乎几乎完全回避了对齐的问题。就像如果我可以制造一个完全复制我的人工智能,并且忠实于我的道德指南针,那么这看起来就像是预先假定了对齐问题的解决方案。我不知道这是否是一个公平的评价。
欧文·埃文斯(44:02):
嗯,我认为对齐问题实际上有两个部分。一个是系统应该试图以人类希望的方式行动,也许在某些情况下,模仿人类就能满足这一点。如果它能做到我在这种情况下会做的事情,我会很高兴。但第二部分是与训练一个可能不一致的系统的替代方法竞争。因此,如果你想象有人训练系统只是为了最大化利润,那么就有一个人工智能系统在公司里做出决策,它在优化利润。因此该系统可以超越人类水平。它可以想出人类从未想出的策略来实现利润最大化,就像 AlphaGo 想出人类没有发明的策略来玩围棋一样。
欧文·埃文斯(45:07):
因此,如果该系统与另一个只是模仿人类的人工智能对抗,它可能会赢,因为人类永远无法提出这些策略,只是模仿的人工智能永远无法提出超越人类水平的策略。因此,我认为我们需要的不仅仅是建立一致的系统,而是能够真正在一个公平的竞技场上与以其他方式训练的系统竞争的一致的系统,这些系统可能不是一致的。如果你只能模仿人类,你能做的事情就相当有限了。所以说,仅仅模仿一个人绝对不是简单的排列。所以你可能会担心你从这个过程中得到的系统有多健壮。
欧文·埃文斯(46:04):
所以你可以想象在一些训练样本上训练模仿人类,这个系统做得很好。它与人类相匹配,然后你会…你也有一个分布转移,你现在正在考虑一个奇怪的场景,系统以前从未见过这样的东西,它可能会以人类不会的方式运行,对吗?因此,它可能是不可靠的,不分布的,围绕内在排列的问题或打断吝啬鬼,某种程度上与这个问题有关。所以我认为人们可能很熟悉另一个例子,你训练系统模仿人类的标签,但在分发时,它的行为与人类非常不同,我们可能会关心这种情况。是的,我给出的 IDA 结盟的论点是非常简单的第一步,你们需要考虑。而且肯定有更多微妙之处。
杰瑞米·哈里斯(47:06):
是啊。事实上,有更多的东西要解开,我们可能无法挤进这个播客,但我很欣赏这个概述。我认为这对那些试图在这个领域找到方向的人很有用,特别是考虑到 IDA 已经得到的关注。非常感谢你分享你对这些事情的见解。有没有什么地方人们可以在社交媒体上关注你或者关注你的工作?
欧文·伊文斯(47:25):
是啊。所以我在推特上写了我的全名,然后在英国下划线。所以我去了英国埃文斯。是的,人们也可以看看我的网站,如果你帮我谷歌一下,或者我想你可以把网址放上去。所以是的,所以我所有的论文都在-
耶雷米·哈里斯(47:47):
是啊。我可以在博客文章中包含所有这些链接,这样人们就可以确认了。好吧,欧文,非常感谢。我们真的很感激,并感谢一个伟大的谈话。
欧文·埃文斯(47:57):
谢了。这真的很有趣。
使用非负矩阵分解机器学习算法预测下一个最佳梦幻足球队
原文:https://towardsdatascience.com/predicting-the-next-best-fantasy-football-team-using-the-non-negative-matrix-factorization-machine-48bc5724931d?source=collection_archive---------17-----------------------
通常隐藏在数字中的是未经训练的人看不到的模式和趋势。无论是在自然过程中还是在合成过程中,如果我们研究得足够深入,我们就可以在不收集新数据点的情况下发现新信息。这个博客是体育和机器学习系列的延续,这是第一个突出国家橄榄球联盟(NFL)的数据。
NFL 在 2021 赛季有 1696 名球员,大约是国家篮球协会(NBA)510 名球员的三倍。也有 5 倍左右的位置可以玩。
我要带着这个去哪里?美式足球是一项复杂的运动。它也被广泛视为终极团队运动。许多不同角色的玩家执行一个任务:以比对手更多的分数结束一场比赛。传球者、阻挡者、踢球者、接球者、防守者和抢球者相互竞争,以显示彼此的优势。(如果你不熟悉美式足球,这个维基百科页面有一个简短的定义列表——这里唯一重要的是四分卫和接球手)。
你猜对了,这样做会产生大量的数据。有数以千计的实验可以用来找出最佳的跑动阵型、最佳的进攻球员、最佳的踢球时间等等。这个博客将探索美式足球最基本的要素之一——完成传球。
橄榄球的规则将一次完整的传球定义为合格的接球手成功接住四分卫向前扔出的传球,而球没有触地。所以,我们想看看影响完整传球的因素之一:四分卫和接球手之间的“兼容性”。
这个博客的实验是使用 NFL 的历史数据来确定哪些接球手会与给定的四分卫很好地配对。我们将使用非负矩阵分解(NMF)来探索这一点。

照片由钱璐·利奇在 Unsplash 拍摄
假设
为了透明和彻底,有许多因素可以决定尝试通过的结果。以下是一些例子:
- 球在空中飞行的螺旋以及投掷的整体质量
- 投掷的距离
- 接收器的运行速度
- 试图阻止接球的防守队员人数
- 太阳的位置(遮挡接收者的视线)
- 天气(湿球更难接住)
其中一些信息实际上是通过 NFL 的历史数据收集的。然而,这开启了一个麻烦的问题,我们可能有比样本更多的特征,从而使我们的机器学习模型受到欠拟合。如果我们在 NFL 中采用四分卫和接球手的任何组合,我们几乎肯定会而不是在每种可能的天气条件下找到完整的传球,对抗联盟中的每个防守队员,所有人都以不同的速度奔跑等等。正因为如此,我们必须做出一个重要的假设来继续这个实验:
假设:NFL 已完成传球的历史数据在总传球码中“编码”了潜在信息(包括但不限于:天气、投掷质量、防守队员和距离)。
然而,这个假设得到了接球手和四分卫之间长期合作关系的支持。阿朵在一起玩的时间越长,他们经历的游戏场景就越多。这对我们来说是个好消息,因为我们实际上想了解四分卫和接球手之间的“兼容性”,并翻译任何一个接球手如何与另一个四分卫合作,反之亦然。
解决了这个问题,让我们简单谈谈我们将要关注的机器学习技术。
非负矩阵分解(NMF)
非负矩阵分解是一种无监督的机器学习技术。在这种情况下,无监督意味着我们没有预先存在的“分数”或我们的训练数据所属的“类”。因此,我们必须首先在训练数据集中自我发现任何自然出现的模式。开头是这样的:
- 给定我们的初始数据,我们执行任何特征提取和数据预处理,使我们的数据以二维表示。对于这个实验,我们有二维数据(一个矩阵),第一轴是 NFL 接收机,第二轴是 NFL 四分卫。实际数据点(四分卫和接球手的交叉点)是通过完成传球获得的总码数。我们称这个矩阵为 X 。以下是这种情况的一个示例:

矩阵 X 。沿着纵轴是 NFL 接收器,沿着横轴是 NFL 四分卫。包含的数据包括截至第 11 周的 2021 NFL 赛季的总接收码数。
- 我们的 NMF 算法是“秩 k”的。这意味着我们手动选择一个值 k ,它对应于我们想要发现的分组的数量。稍后我会详细说明这一点。
- 矩阵(我们的初始数据)以类似于分解多项式方程的方式被分解。这产生了两个新的矩阵 W 和 H ,我们通过学习和分析来收集新的见解。
概括一下:让接球手的数量用术语 R 来表示,四分卫的数量用术语 Q 来表示。我们给定的码数数据集由矩阵 X 表示。也就是说:
X 是一个大小为 R x Q 的矩阵。 X 将被分解成矩阵 W 和 H ,其中 W 是大小为 R x k 的矩阵, H 是大小为 k x Q 的矩阵。这很重要,因为在矩阵乘法中,两个矩阵之间的“中间”维度必须匹配,而生成的矩阵保持“外部”维度。因此:
给定 X,我们学习 W 和 H 使得我们满足等式X≈WXH .


(从左至右)矩阵乘法为X≈WXH**展示了 NMF 期望的结果。
为此,我将使用 scikit-learn python 包中方便提供的 NMF 类。想了解更多关于 NMF 的信息,我推荐从这个博客开始,深入研究 NMF 的数学及其相关的训练算法。本实验中使用的 NFL 数据来自 nfl_data_py Python 包。
期望值和实验设置
这个实验的假设是,NMF 算法可以在四分卫-接收器组合中找到模式,这样,我们就可以发现 NFL 中从未见过的新球员组合,这将成为一个伟大的双人组合。同样,NMF 声明了秩 k 矩阵 W 和 H ,其中 k 实际上是“习得的”组或类别的数量。
如果这还不清楚,主题建模是 NMF 的另一个流行用例。当将 NMF 应用于新闻文章中的数据时,我们可以发现体育文章、商业文章或政治文章等主题。我们会选择 k 来代表我们想要学习的主题的数量。在 NFL 四分卫和接球手的背景下,我们将学习两个球员之间的比赛风格或一般兼容性。
矩阵 W 和 H 被随机初始化,并通过 NMF 算法进行更新,使得 W 和 H 的矩阵乘法近似等于矩阵 X 。结果, W 成为大小为 R x k 的矩阵, H 成为大小为 k x Q 的矩阵。
翻译成英语,这意味着 W 将会告诉我们一个接收者与我们所学的任何一个 k 组有多接近。H 会告诉我们每个组与某个四分卫的兼容性如何。例如,假设我们决定学习 k=4 组。让我们假设(在 matrix W 中)接收者 Rob Gronkowski、Tyreek Hill、DeAndre Hopkins 和 Davante Adams 在第 2 组中得分很高(高意味着接近 1)。当我们查看 matrix H 时,我们可能会发现四分卫汤姆·布拉迪、帕特里克·马霍斯、凯勒·默里和亚伦·罗杰斯(在他们的职业生涯中,他们各自都是四分卫)在第二组也有很高的分数。这表明第二组四分卫和接球手的任何组合都应该很好地配合,即获得许多完成和传球码数。以下是矩阵 W 和 H 的示例:


(左)矩阵 W,其中每个接收者都有一个适合他们的分数。(右)矩阵 H,其中每个四分卫都有一个分数,表示他们在给定团队中的表现。注意对于矩阵 W ,行总和为一。对于矩阵 H ,列总数为 1。这种格式使得每个矩阵中的值可以被解释为良好匹配的概率。
如果你决定查看代码(链接在本博客的末尾),你会看到矩阵 W 和 H 在计算后被规格化,这意味着它们的值被按比例压缩到 0 和 1 之间。这只是让数字更容易解释;分数越接近零表示比赛越差,分数越接近一表示比赛越好。
超参数调谐
为了从这个实验中找到最好的结果,我研究了与 NMF 相关的四个超参数。其中包括:
- 拟合前用于 X 的数据量(即学习 ) W 和 H
- k —学习到的分组数
- alpha —用于学习 W 和 H 的正则化参数(正则化是一种可选技术,可用于对异常值如何影响算法进行更多控制)
- 公差—NMF 算法的停止条件。即近似值X≈WXh的接近程度。较低的容差意味着更多的训练迭代(在结果部分中有更多相关信息)。
我研究了一次 hyper 参数 2 到 4,其中有少量数据用于 X (大约。两年的 NFL 数据)和大量的数据(大约。12 年 NFL 数据)。我们先看少量数据。
注:在以下情节中,使用了至少在一次完成中担任四分卫的所有球员,然而 Y 轴上的平均 QB 分数仅取自联盟中的 32 名首发四分卫——每队一名。
调整 k
组数 k 在数值 3 和 14 之间变化。与较高的 k 值相比,较低的 k 值工作得非常好。这可能是早期假设的结果,即各种通过条件被编码在全部完成的通过码中。这种简化可以降低该 NMF 模型的最大复杂度,使得模型将在更高的 k 值下填充。或者,有可能 NFL 中四分卫和接球手的组合更少,例如四分卫赢得了最有价值球员(MVP)奖,四分卫没有。应该注意的是,虽然曲线的形状基本相同,但 k 值较低时的峰值得分较高,使用的数据较少,左侧的图仅采用了最近两个 NFL 赛季的数据。


rank-k 超参数的调整
希腊字母的第一个字母
当达到平均 QB 分数时,alpha 或正则化参数显示了两年 NFL 数据的振荡行为。阿尔法值在 0 到 1 之间扫描,分数峰值在阿尔法=0.4、阿尔法=0.7 和阿尔法=0.9 附近。然而,对于 12 年的 NFL 数据,行为具有更细粒度的振荡,得分从 alpha=0.25 到 alpha=0.4 达到最小值,而在 alpha=0.5 达到峰值。这种差异可能是因为使用的数据越多,发现的异常值就越多,因此正则化的效果就越显著。这将产生一个更紧密的拟合曲线,如下图所示。


阿尔法正则化超参数的调整
容忍
最后公差被扫到了 0.001 到 0.01 之间。下面我们看到短期和长期数据的阶梯状曲线。尽管形状有些相似,但请注意,短期 NFL 数据的峰值平均 QB 得分仍然更高(略低于 0.3),就像其他超级参数一样。峰值平均 QB 分数的位置也出现在不同的位置,对于长期数据出现在较早的位置,对于短期数据出现在中间位置。
较低的容差值意味着算法要经历更多的训练迭代。这些图表告诉我们,在 NMF 算法的更多次迭代之后,长期数据(也有更多的 T4 信息)具有最高的精确度。短期数据(具有少于的信息)以较少的迭代次数达到最高精度。这将是有意义的,因为信息更丰富的矩阵 X 应该花费更多的次迭代来学习适当的矩阵 W 和 H 。用短期数据学习 X 的迭代次数少,所以不用把容忍度设得太低。事实上,将它设置得太低会略微降低平均 QB 分数,如下图左侧所示。


公差超参数的调整
概述
让我们回顾一下我们在这里学到的内容。我们已经观察到,在我们最初的 X 矩阵中使用更多的长期数据通常会将四分卫和接收机之间的最大兼容性得分降低约 25%。我对此的理论是,旧数据使模型偏向于历史上更成功和更长寿的球员(如汤姆·布拉迪、亚伦·罗杰斯、拉塞尔·威尔逊)。我们还发现, k 的较低值显著增加了平均 QB 分数,而与输入数据大小无关。然而,与 k 不同的是,正则化参数α和容差都受输入数据量的影响,其峰值平均 QB 得分的位置也不同。
结果
随着超参数的调整,让我们来看看一些四分卫-接收器组合,使用以下标准来最大化我们的准确性指标— 平均 QB 得分:
- 仅 2020 和 2021 赛季的 NFL 短期数据
- k:3
- 阿尔法=0.9
- 公差=0.005
注:下面列出的只是每个 NFL 球队的首发四分卫。这些接收器是其组中兼容性得分最高的前 10 个接收器。
GROUP 1 out of 3 k-rank group(s)average quarterback score: 0.13548700559442842Quarterbacks: [‘J.Burrow’, ‘C.McCoy’, ‘T.Brady’, ‘M.Rudolph’, ‘J.Hurts’]Receivers: [‘L.McCoy’, ‘R.Gronkowski’, ‘A.Brown’, ‘C.Brate’, ‘M.Evans’, ‘J.Mickens’, ‘C.Grayson’, ‘L.Fournette’, ‘O.Howard’, ‘C.Godwin’]— — — — — — — — — — — — — — — — — — -GROUP 2 out of 3 k-rank group(s)average quarterback score: 0.2006553965063584Quarterbacks: [‘J.Garoppolo’, ‘P.Walker’, ‘L.Jackson’, ‘P.Mahomes’, ‘T.Bridgewater’, ‘D.Carr’, ‘D.Prescott’]Receivers: [‘A.Sherman’, ‘J.Gordon’, ‘T.Kelce’, ‘E.Fisher’, ‘B.Bell’, ‘D.Robinson’, ‘T.Hill’, ‘G.Dieter’, ‘M.Kemp’, ‘N.Keizer’]— — — — — — — — — — — — — — — — — — -GROUP 3 out of 3 k-rank group(s)average quarterback score: 0.5274625854006478Quarterbacks: [‘J.Herbert’, ‘T.Siemian’, ‘M.Jones’, ‘J.Brissett’, ‘B.Mayfield’, ‘Jos.Allen’, ‘Ty.Taylor’, ‘M.Ryan’, ‘C.Wentz’, ‘J.Fields’, ‘J.Goff’, ‘R.Tannehill’, ‘Aa.Rodgers’, ‘M.Stafford’, ‘M.White’, ‘T.Heinicke’, ‘R.Wilson’, ‘K.Cousins’, ‘T.Lawrence’]Receivers: [‘C.Beasley’, ‘J.Brown’, ‘S.Diggs’, ‘J.Kumerow’, ‘T.Yeldon’, ‘I.McKenzie’, ‘S.Neal’, ‘E.Turner’, ‘J.Allen’, ‘D.Singletary’]
您可以看到,第 3 组的平均分高于第 1 组或第 2 组,这表明第 3 组的化学反应更强,而第 1 组和第 2 组的化学反应不太自信。1.0 分意味着近乎完美的匹配。不出所料,这往往会在 k 接近 32 时发生,在这种情况下,该算法几乎完美地学习了基于四分卫和接球手组合的 32 支 NFL 球队。此外,如果你查找 2021-2022 赛季中期的一些球员,你会注意到有许多组合,其中一个组的四分卫和接球手在同一支球队。这是意料之中的,因为联盟中先前存在的双人组已经经受住了时间的考验。换句话说,他们可以“互相担保”。除此之外,试着在你的梦幻足球队中交换队员,看看他们表现如何!
结论
我希望你能从这个博客中学到一些新的东西,也希望你能从这个博客中学到一些有用的东西。在这里,我们讨论了非负矩阵分解,以及如何将它应用于 NFL 的历史数据,这样我们就可以学习四分卫和接收器的组合,这些组合可能一起表现很好。
如果你想查看这个实验的源代码,可以查看这个 github 库:https://github.com/ChristopheBrown/nfl-ml
预测 YouTube 视频上不喜欢的数量。第 1 部分—数据集
原文:https://towardsdatascience.com/predicting-the-number-of-dislikes-on-youtube-videos-part-1-dataset-9ec431585dc3?source=collection_archive---------17-----------------------
如何使用 Python 和 Youtube 数据 API v3 收集热门的 YouTube 数据

预览。作者图片
在本文中,您将学习如何使用 Youtube API 来获取关于视频的最新信息。
这是不喜欢预测项目的第一部分。在这里,我将收集和清理数据,并在第二部分-训练一个基于它的模型。
我收集的数据集可以在 Kaggle 上下载。
我使用的所有代码都可以在 GitLab 资源库中找到。
数据集许可证
注意 YouTube 趋势视频数据集和 YouTube 不喜欢的数据集都有 CC0: Public Domain 许可,所以可以免费使用。你可以在 Kaggle 上了解更多关于数据来源和数据收集方法的信息。
介绍
众所周知,Youtube 在 2021 年 11 月左右宣布了向用户隐藏不喜欢数量的决定。这个决定可以根据我们的意愿进行讨论,但是我们有我们所拥有的——不喜欢率现在只对视频创作者可见。
幸运的是,互联网社区人才济济,工匠们几乎立刻就创造出了一个返回厌恶的扩展。

返回 YouTube 不喜欢的 Chrome 扩展。一个公共网页的截图
不幸的是,根据官方文件,从 2021 年 12 月 13 日起dislikeCount地产为私有。
扩展仍然工作,但是现在它 不能使用 API 接收官方信息。相反,不喜欢的数量是“自己”计算的,并存储在外部数据库中。这种解决方案部分解决了问题,但它与事实相差甚远,这种差距将越来越大。
基于此,在 12 月 13 日前几天,我有了一个有趣的想法——训练一个神经网络来预测不喜欢的数量。这是这个想法的第一部分,因为像任何机器学习算法一样,神经网络需要数据。
重要的是——一切都与代码有关
本文片段中给出的代码将无法正常工作。嗯,会的,但是要得到一个正常工作的程序,你需要添加许多额外的验证和 try-catch 块。
不要从文章中复制代码。
其目的是显示程序的简化结构。
如果您想使用代码,请浏览下面的资源库。您还可以看到每个代码片段所需的文件名。
https://gitlab.com/Winston-90/youtube_dislikes
来自 Kaggle 的 YouTube 趋势视频数据集
类似的任务有现成的数据集——来自 Kaggle 的 YouTube 趋势视频数据集。
该数据集自 2020 年 8 月 12 日起每天更新,每天接收以下每个国家的约 200 个趋势视频的信息:印度、美国、英国、德国、加拿大、法国、俄罗斯、巴西、墨西哥、韩国和日本。于是,在这段时间里,这个数据集为每个国家积累了约 10 万条记录((一年 365 天从 2020 年 8 月到 2021 年 8 月+ 120 天从 9 月到 12 月) *每天 200 条视频 ≈ 10 万条)。
很明显,数据集中有重复的行(具有相同的视频 ID),因为视频可以有一天以上的趋势。如果我们考虑到这一点,并且只读取唯一的视频 id,我们将得到所有国家的大约 20 万条记录。
不幸的是,数据集不包含关于评论的信息,但在我看来,它们具有最大的预测潜力。此外,关于数据集的早期行的信息是不相关的,因为今年喜欢/不喜欢的数量已经改变。
然后,我决定使用 Youtube 数据 API 构建一个类似但相关的数据集。
构建自定义数据集
请求示例
我们需要执行两个请求,一个是获取视频信息,另一个是请求评论。
一点都不难。首先,你需要获得一个 API 密匙并用 pip 或 conda 命令安装google-api-python-client库。然后按照官方文档查看视频()。list() 和 commentThreads()。方法列表()。
在代码中,首先你需要获得一个googleapiclient.discovery.build对象,它将允许你发出请求。在下面的代码中,您需要将 API 键分配给DEVELOPER_KEY变量。要了解更多,请访问官方文档或一些教程。
当youtube变量被成功初始化后,剩下的只是制定一个请求并执行它。
这两个请求都返回一个 python 字典,这很容易理解,因为文档足够详细地描述了一切。
正如我之前说过的,现在dislikeCount属性被隐藏了——它不再出现在响应中。这是来自YouTube _ API _ requests _ examples . ipynb 笔记本的一个例子。

2021 年 12 月 13 日前后对同一请求的响应。作者图片
YouTube 视频 id
如您所见,您需要为这两个请求指定一个视频 ID。YouTube 允许你获得流行(趋势)视频的信息,但每天只有 200 个。
YouTube 视频 ID 有一个清晰的结构,我们可以迭代所有可能的组合。我们可以,对吗?为了好玩,让我们做数学。YouTube 视频 ID 由 11 个字符组成,每个字符可以是数字(0-9)、字母(a-z 和 A-Z)、破折号(-)或下划线(_)。所以总共有 64 个可能的符号(10 个数字+ 2*26 个字母+ 2 个特殊字符)。在这种情况下,可能的 id 数是 64。就是这么多:
73786976294838206464
73 * 10 ⁸,73 万亿分之一,或者更好理解,730 亿亿分之一。即使我们有时间进行计算(每秒一百万次运算需要200 万年),硬盘上肯定没有足够的空间来存储这么多数据。
当然,我们不需要这么做。由于我们有一个包含 20 万个唯一 id 的 Kaggle 数据集,这应该足够了。

YouTube 视频 id。作者图片
由于 20 万对我们来说太多了(我们将在后面看到),我开始使用在加拿大、美国和英国流行的视频 id。那种情况下大概有三万一千个唯一 id。它们位于unique_ids_GB_CA_US.txt文件中。
YouTube 数据 API 配额使用规则
现在我们有一个问题——配额使用。当然,没有人会允许你每天发出无限的请求——这就是限额的目的。虽然读取操作花费 1 个单位,但默认情况下 YouTube 允许你每天发出 10,000 个请求,参见配额使用规则。
我为每个视频做两个请求(获得统计数据和评论),所以理想情况下,我每天将为一个 API 键在数据集中获得 5000 个条目。听起来还不错。
但是 YouTube 会时不时屏蔽你的访问。所以你不能在 5000 个 id 上运行一个循环然后悄悄地离开。在我调试了代码并捕获了所有可能的异常(在我看来)之后,有时我仍然会得到 HTTP 403 错误(表示服务器理解请求,但不会执行它),所以我必须不断地监控代码的执行。这就是为什么在下面的代码中,我不仅按视频 ID 循环,还按尝试次数循环。
所以最后,我收集了一些小的数据集,然后把它们放在一起。
执行时间
执行时间取决于很多因素——硬件、网速、可能还有 YouTube 本身的限制等等。我得到的最好结果大约是每秒 6 个请求,平均是每秒2–3 个请求。
为了收集结果数据集,我发送了大约 60k 个请求,用了大约 7 个小时。没有那么多,但请记住,这个时间是分布在几天内,需要几乎不间断的监督。
将所有这些放在一起——工作代码
据我所知,这段代码与作者用来从 Kaggle 收集 YouTube 趋势视频数据集的代码非常相似。让我解释一下。
主函数get_video_info_by_id()将视频 ID 作为参数,并以列表形式返回关于该视频的数据。您可以获得任何想要的字段,您只需要浏览查询返回的 python 字典。这个函数的实际代码并不复杂,它只是包含许多 try-catch 块来确保字段可用。
request_loop()函数遍历视频 ID 列表,并对每个 ID 执行get_video_info_by_id()函数。它将信息累积到一个列表列表中,并使用 pickle 库保存。
主程序或主请求循环是多次运行request_loop(),每次移动 ID 列表,以免多次请求关于同一视频的信息。
上面的代码将列表保存到磁盘。要将其转换成数据集,您需要读取所有保存的文件,将它们转换成一个 pandas DataFrame ,并将它们连接在一起。
我不会在这里详细描述数据清理,但请记住,这是必须要做的。我检查了 ID 的唯一性、非英语字符等数据。要了解更多信息,请探索 clean_data()函数。
摘要
结果我设法收集了大约 37k 张唱片。考虑到这个想法是在 12 月 13 日之前产生的,这还不算太坏。我对这个结果很满意,因为我有一个小的但是热门的数据集。
你可以从这里得到——YouTube 不喜欢 Kaggle 上的数据集。它看起来像这样(它只是被转置以适合屏幕上的所有列):

Youtube 不喜欢数据集。作者图片
在编写这段代码的过程中,我还编写了代码来清理 Kaggle 数据集(从最后一个请求中只获取惟一的 id,删除特殊字符,等等)。你可以在库或 Kaggle 上的中找到做这件事的代码。
两个数据集具有相同的结构,因此它们可用于训练相同的模型或具有相同架构的模型。以下是其特点:
video_id-唯一视频 IDtitle-视频标题channel_id-频道 IDchannel_title-频道标题published_at-视频发布日期view_count-浏览次数likes-喜欢的数量dislikes-不喜欢的数量comment_count-评论数量tags-作为一个字符串的视频标签description-视频描述comments- 20 条视频评论为一串
All text fields contain only ASCII and Latin characters (numbers, English letters, and punctuation marks). If there are no letters left in the string after deleting these characters, this row will be deleted too. This applies to title and channel_title (for example "伟大的视频!!!!" -> "!!!!" will be deleted).
关于评论
值得一提的是,用最热门的评论进行预测是符合逻辑的。但是 YouTube API 不允许你获取它们。设置video_id时,请求中的relevance参数被忽略,如文档中描述的。
即使通过解析也不可能获得最受欢迎的评论,因为即使是 YouTube 也是以无序的顺序显示的。如果你知道如何解决这个问题,请联系我或写评论。
所以事实上,YouTube 决定发送的只是这 20 条评论。但总比没有好,对吧?

YouTube 上的热门评论是无序的。一个公共网页的截图
由于 Kaggle YouTube 趋势视频数据集不包含comments字段,因此对于整个数据集,该值等于一个空格(" ")。
结论
为了写这篇文章,我编写并执行了允许我获得以下内容的代码:
- 第 137k 行的 YouTube 趋势视频数据集的干净版本。该数据集包含 11 个县从 2020 年 8 月到 2021 年 12 月的趋势 YouTube 视频信息。
- 客户收集的 YouTube 不喜欢 37k 行的数据集。该数据集包含关于 37k 视频的不喜欢的信息,这些视频同时在美国、加拿大和英国流行。
信息是在 12 月 13 日之前收集的,这使得该数据集成为最相关的厌恶数据集。不幸的是,不可能得到这样一个数据集的新版本。
现在,我将在这些数据集上训练一个神经网络,以预测视频中不喜欢的数量。第二部分在这里:
感谢您的阅读!
- 我希望这些材料对你有用。在媒体上关注我以获得更多类似的文章。
- 如果您有任何问题或意见,我将很高兴得到任何反馈。在评论中问我,或者通过 LinkedIn 或 Twitter 联系我。
- 为了支持我作为一名作家,并获得数以千计的其他媒体文章,使用我的推荐链接获得媒体会员资格(不收取额外费用)。
用机器学习预测 NBA 比赛的结果
原文:https://towardsdatascience.com/predicting-the-outcome-of-nba-games-with-machine-learning-a810bb768f20?source=collection_archive---------1-----------------------
我们如何使用(你也可以)机器学习来更好地理解统计在体育运动中的作用。
在决定大数据分析课程的最终项目时,我和我的合作伙伴 Jack Rosener、Jackson Joffe 希望将对体育的兴趣与整个学期学到的原则结合起来。经过几天的讨论,我们选定了一个旨在预测 NBA 比赛结果的项目。在实现我们的目标时,我们发现通过以下问题将项目提炼为以下步骤很有帮助:
- 收集相关数据–我们从哪里收集几个赛季的相关球队和球员统计数据?
- 清理和处理数据——我们如何有效地组合我们收集的数据,使其既可读又可用?
- 特征工程——我们可以将哪些额外的指标添加到我们的数据集,以帮助任何用户或 ML 模型分别更好地理解和预测数据的结果和趋势?
- 数据分析 —我们能否确定数据中的任何共线性或其他关系,从而更好地为我们的预测提供信息?
- 预测–哪些模型和特性对我们开发准确的预测最有用?我们关注团队还是个人的统计数据?
在我们进入工作流程的本质之前,让我们花点时间回顾和了解在这个特定主题上所做的其他工作。首先,2013 年来自威斯康星大学麦迪逊分校的雷纳托·托雷斯着手完成与我们类似的目标,并使用不同的机器学习模型预测 NBA 数据的具体赛季结果。他使用了我们项目中的多种技术,主要是要素约简,以消除可用数据中的多重共线性,还探索了不同的模型,以探索那些具有最高精度的模型。像我们的项目一样,他选择的功能包括得分,但不像我们的项目特别关注主场和客场的输赢百分比。(我们将在后面探讨我们的特征分析。)
之前已经有很多关于这方面的精彩工作,可以在这里阅读:
程,葛【张,】振宇&凯班贝,摩西&纳赛尔,金布威。(2016).基于最大熵原理预测 NBA 季后赛结果。
琼斯,埃里。(2016)预测 NBA 比赛结果。北达科他州立大学。
法亚德,亚历山大。建立我的第一个机器学习模型| NBA 预测算法。走向数据科学。
NBA 的完整历史。五三八。
通过我们的研究,我们发现公布的最佳模型的预测准确率为 74.1%(针对季后赛结果),其他大多数模型的准确率上限在 66-72%之间。大多数已发表的研究也集中在预测季后赛得分上——这可能会导致有偏见的数据:季后赛球队在整个常规赛的一些数据上更一致,因此季后赛比赛预期结果可能会经历更少的变化。至关重要的是,请注意 NBA 整个赛季的失望率平均为 32.1%。在季后赛中,冷门率——由常规赛胜率较低的球队定义——下降到 22% (这实际上意味着大多数 NBA 季后赛预测模型表现不佳)。因为我们的项目旨在预测任何 NBA 比赛的结果,并且是季后赛不可知的,所以我们希望开发一个可以达到并有望超过 67.9%准确率的模型,并在这样做时预测一些冷门。
请随意点击这里的或者在 GitHub 上查看我们的文件。
收集我们的数据
我们从 Synergy Sports 的可用信息中搜集数据,该网站有自 2008-2009 赛季以来每场比赛的极其详细的球队和球员数据。由于速度限制(因为我们必须查询 12 个赛季的每场比赛的结果),刮花了几天时间,最初被编译成 JSON 格式,最后保存为 csv 文件。
作者注:我们获得了宾夕法尼亚大学资助的 Synergy Sports 的数据。不幸的是,我们无权向公众公开我们的数据。然而,我们已经编辑了一个备选数据集的列表,通过它我们可以复制和改进我们的数据:
【https://www.basketball-reference.com/leagues】
https://www.kaggle.com/datasets/nathanlauga/nba-games
https://www.kaggle.com/datasets/drgilermo/nba-players-stats
清理数据
我们现在把每个 NBA 赛季的球员和球队数据都保存为单独的 csv 文件。我们的下一步是读入所有这些数据,并将其组合成两个大的数据帧:一个包含过去 12 个赛季的球员统计数据,另一个包含球队统计数据。创建后,我们将清理数据帧,以删除无效的统计数据(负分钟)和对我们没什么用的列(例如,收取/承诺的费用)。
然后,我们将这些新的数据帧保存到以下 csv 文件中,这样我们(和您)就可以在重启笔记本运行时,跳过采集和清理数据的费力而冗长的步骤:
特征工程
这是有趣的事情开始的地方。我们的主要目标是让所有可用的数据都可以理解:整支球队每场比赛的篮板对我们没有太大帮助,除非我们可以在更高层次的分析中使用这些数据,引导我们达到最终目标——预测输赢。为此,我们试图创建五个不同的特征,用于了解我们的团队在每个赛季如何进步和退步:
- Elo 评级
这也许是现有的比较 NBA 球队实力和多个赛季表现的最佳方法。Elo 评级的计算方法很简单:所有球队都以 1500 分的中值开始,并根据每场比赛的最终得分以及比赛地点来加分或减分,分数差异、冷门和位置是权重。本质上,这是一个更复杂的输赢记录。大多数 NBA 预测模型并不考虑 Elo 评分,而是将一个简单的输赢记录与其他几个统计数据结合起来。我们希望使用 Elo 来恰当地衡量质量上的成功(和失败),同时也认识到并非所有的团队都生来平等。
确切的公式如下:
如果𝑅_𝑖是一支球队当前的 Elo 等级,那么它在打完下一场比赛后的 Elo 等级定义如下:

我们计算每支球队和每场比赛的 ELO,以及我们拥有的每个赛季的数据。
在这里, S_team 是一个状态变量:如果团队赢了就 1,如果团队输了就 0。E_team 表示球队的期望获胜概率,表示为:

k 是一个移动常数,取决于胜率和 Elo 评分的差异:

同样重要的是要注意,Elo 评级会随着赛季的变化而变化(因为所有的球队都不是生来平等的,优秀的球队往往会保持优秀,或者至少会逐渐衰落——很少会出现球队掉队或掉队的情况)。如果 R 代表一个赛季中一支球队的最终 Elo,那么它在下一个赛季开始时的 Elo 评级大约为:

实际上,我们可以随着时间的推移查看这一指标,随机选择三支球队查看,并立即看到我们可以获得关于球队在整个赛季中的实力的关键见解:

在这里,我们实际上可以看到,Elo 收视率与球队在特定赛季的表现相当吻合:金州勇士队和克利夫兰队在 NBA 总决赛中出现和对决的年份很明显是他们 Elo 收视率的高峰。我们还可以看到当时被大多数篮球分析师广泛证实的事实:西部联盟比东部联盟更艰难——正如勇士队对骑士队的高质量胜利对 Elo 的影响所展示的那样。我们也可以看到这些球队在他们的冠军赛季后迅速下滑了多少,因为他们都遭受了名册损失和伤病。(图片由作者提供)
2.最近的团队表现(平均。最近 10 场比赛的统计数据)
这些都是不言而喻的,我们只是简单地看一下每支球队过去 10 场比赛的平均数据。为此,我们编写了一个简单的函数来计算给定球队的统计数据和 n 场比赛的滑动平均值:
在将这些数据保存到一个新的 dataframe 中之后,我们试图将每场比赛(包含主队和客场队的统计数据)按球队划分到自己的行中,这使我们能够更容易地分组和汇总球队统计数据,并简化了现有的功能。最后,我们添加了一个 win 状态变量列来包含我们项目中最关键的度量:赢和输。
3.最近的球员表现(平均。最近 10 场比赛的统计数据)
我们使用与上一节类似的方法创建我们的球员最近表现数据框架,这次是用个人球员而不是团队。这创造了一个每个球员在过去 10 场比赛中表现的数据框架。
4.球员赛季表现
我们还试图包括整个赛季的平均球员统计数据:与球队不同,球员自己会受伤或在轮换中摔倒,这对我们来说可能更重要的是了解球员在个人比赛中的表现如何与他们的平均水平保持一致。我们将在稍后的模型中使用它,看看它是否能在团队层面上实现准确的预测。
5.球员效率评分(PER)
至关重要的是,正如我们通过 Elo 评级对球队所做的那样,我们希望能够使用一种结合了看似不相关的统计数据的指标来相对化球员的表现。我们的希望是,我们可以使用 Hollinger 的球员效率评级来比较和预测球队球员的综合 PER 得分。在 NBA,球员很容易经历疯狂膨胀或缩小的统计数据(如每分钟得分),仅仅是凭借他们获得的上场时间,与替补球员或首发球员的比赛,比赛次数,甚至是异常表现。我们不想仅仅因为玩家的偏差能力而仅仅依赖他们的平均水平。PER 通过用上场时间的倒数对某些游戏中的统计数据进行加权来解决这个问题,它创建了一个相对于上场时间来定义玩家表现的指标。
因此,对于每个玩家,我们根据以下公式为给定游戏中的 PER 添加了一列:
PER = (FGM x 85.910 +抢断 x 53.897+3 PTM x 51.757+FTM x 46.845+盖帽 x 39.190 +进攻 _Reb x 39.190 +助攻 x 34.677 +防守 _Reb x 14.707 —犯规 x 17.174—FT _ Miss x 20.091—FG _ Miss x 39.190—至 x 53.897) x
数据分析
我们的数据分析集中在使用 Elo 评级作为我们的测试指标。从本质上讲,我们能确信 Elo 与其他统计数据相关并正确汇总吗?此外,我们使用球队数据(Elo 评分)或平均球员数据(PER 评分)来预测比赛结果是否更合适?
首先,让我们探索一下 NBA 每个赛季 Elo 收视率的密度。这告诉我们整个联盟的均等水平:如果我们可以看到 Elo 评分接近正态分布,这将表明联盟的球队相对匹配。否则,我们会看到巨大的差距和“超级团队”的发展。

十二个赛季的联赛 Elo 密度。(图片由作者提供)
从联盟的角度来理解 Elo 评分,我们努力去看看 Elo 评分是如何与单个球队在其他数据上的表现相对照的。
首先,我们根据最近几场比赛的平均得分绘制随机球队的 Elo 分布图:

(图片由作者提供)
我们实际上可以从中看出,一支球队的平均得分与其 Elo 评级之间存在某种相关性——在一段时间内的比赛中,平均得分越高,Elo 评级似乎就越高。然而,我们还可以看到,Elo 也可能在类似的得分数字之间表现出较高的方差。因此,为了更好地了解 Elo 评分与得分的关系,我们检查了平均得分与整个联盟的赛季平均得分的对比情况——从那里我们可以确定得分是否提高了 ELO,前提是高分是相对于联盟的其他得分。为了做到这一点,让我们来看看同一支球队在同一赛季的表现,并绘制出该队相对于对手的得分分布图。

(图片由作者提供)
这证实了我们的怀疑,因为我们可以看到,当平均分数的分布大于其对手的平均分数,或者更集中在相同或更高的水平时,Elo 在这些赛季中更高。当分组接近一个相等或更小的值时,给定团队的那些赛季的 Elo 评级更低。因此,平均得分是一个单独的预测游戏结果的可靠决定因素,但当 相对于 时更好。这向我们证明了 Elo 比积分更能决定我们的胜率,因为它是一个相对的统计数据。
抛开团队统计数据,我们试图了解 Elo 对球员表现的追踪是否比团队表现更好。为了做到这一点,我们采用了一种类似的方法,用相同随机团队的平均得分来绘制 Elo 评级,这次用的是 PER。

(图片由作者提供)
从绘制的数据中,我们可以看到,与对手相比,总 PER 并没有显示出与 Elo 评级所确定的团队实力有任何关联。相反,得分转化得更好——这在某种程度上是有意义的,因为球员的效率不一定与得分最多相关联——与对手的得分是赢得比赛的决定性因素,因此会影响 Elo。
我们可以通过绘制相同赛季中奥兰多魔术队相对于其对手的平均和中值 PER 评级来进一步了解这一点,并发现球队平均或中值 PER 和球队实力之间几乎没有关系。

从这些和上面绘制的分布图中,我们看到平均 PER——虽然与整个赛季的 Elo 评分略有关联——通常很少向我们显示在与对手进行跟踪时,个人球员效率如何影响团队实力。(图片由作者提供)

PER 收视率中值显示,在整个赛季中,与 Elo 收视率的相关性甚至更小。在这里,我们可以观察到,在获胜赛季(2011-12),奥兰多魔术队在大多数比赛中的 PER 中位数都低于其对手,但他们却拥有近年来最高的 Elo 收视率和最佳战绩。(图片由作者提供)
从我们对相对化球队与聚合球员统计数据的所有分析中,我们清楚地看到,当预测 NBA 比赛结果时,我们的 Elo 评级及其决定因素将是训练我们模型的更好特征。
根据团队统计数据和 Elo 评分预测比赛结果
这里,我们的第一步是将数据分为要素和列。从我们的数据集中读取,一旦分割,我们就使用 sklearn 以 80:20 的比例将我们的数据随机分割成训练集和测试集。
我们旨在用来预测 NBA 比赛结果的第一个模型是逻辑回归模型。与线性回归模型不同,线性回归模型预测 0 和 1 之间(有时在 0 和 1 之外)的结果,逻辑回归模型旨在将预测分组为二元结果。因为我们预测的是赢和输,这种分类非常适合我们。
首先,我们使用一个简单的非参数化 LR 模型,使用 sklearn 将我们的团队统计数据和 Elo 评级作为参数:
在进行了一些超参数调优之后,我们发现使用 max_iter=131 和 verbose=2 将我们的初始测试精度略微提高到了 66.95%。对于一个非参数化的模型来说绝对不坏,非常接近我们期望的预测精度。然而,我们试图看看我们是否可以更好地调整我们的超参数,以提高我们的整体准确性。本质上,我们将在我们的数据上尝试可能的超参数的许多组合,以给出我们的 LR 模型的绝对最佳权重。
我们通过交叉验证实现了这一点:因为我们对可能要使用的参数只有一个模糊的概念,所以我们最好的方法是缩小搜索范围,并对每个超参数的大范围值进行评估。
使用 RandomizedSearchCV,我们在 2 * 4 * 5 * 11 * 3 * 3 * 5 * 3 =59400个可能的设置中进行搜索——因此最有效的方法是随机抽取值。
使用随机样本的最佳参数值运行我们的模型实际上将我们模型的准确性降低到了 66.27%,这向我们表明,虽然随机采样帮助我们缩小了分布内的超参数调整范围,但我们必须使用 GridSearchCV 显式检查所有组合。
在这种情况下,实现 GridSearch 只是略微提高了 LR 模型的准确性。
我们希望实现的第二个模型是一个 RandomForestClassifier ,它可以有效地用于回归和分类。在这种情况下,我们将会看到分类器是否能够构建一个合适的决策树来从给定的团队统计数据中确定胜利。
很快,我们得到 RandomForestClassifier 达到了 66.95%的初始准确率,这也是非常好的。像 LR 模型一样,我们试图调整超参数以给出更准确的结果——首先使用 RandomizedSearchCV。
与 LR 模型不同,我们发现随机化搜索改善了我们的超参数调整,使我们获得了 67.15%的更好的准确性。
以与上面类似的方式运行 GridSearchCV,我们还试图明确测试 2 * 1 * 6 * 2 * 3 * 3 * 5 = 1080 个设置组合,而不是随机抽样设置分布。GridSearch 也给了我们一个相对于基础 RandomForestClassifier 的改进,准确率达到了 67.11%。
总的来说,当对团队统计数据和 Elo 评级运行 LinearRegression 和 RandomForestClassifier 时,我们实现了66.95%–67.15%的胜利预测准确率。对于篮球比赛来说,正如我们之前所确定的,实际结果与预测结果相差很大,这是一个重要的结果。
根据单个玩家的统计数据和得分预测游戏结果
然后我们采取了不同的方法来预测比赛的结果,看看我们是否能取得更好的表现。使用我们收集的个人玩家统计数据的更大数据集,我们将训练一个模型来预测玩家在给定游戏中会得到多少分。我们将根据我们试图预测的比赛之前球员的平均赛季统计数据以及他们在过去 10 场比赛中的平均表现来预测这一点。我们已经在上面的特征工程部分创建了这些数据。我们也将在预测中使用 Elo 等级,因为对手的等级越高,玩家得到的分数就越少。一旦我们有了这个模型,我们就可以通过合计每个球员的预测得分来预测一个球队在一场比赛中会得多少分。有了这些信息,我们就能预测哪一队得分更多,从而赢得比赛。
在运行模型之前,我们需要稍微清理一下数据。对于该数据集中的一些比赛,我们有一个队的球员的统计数据,但没有另一个队的统计数据,通常只包括另一个队在赛季中的第一场比赛。因此,我们将从数据集中删除所有这些游戏。
与上述游戏不同,我们不能将数据随机分为训练集和测试集。我们希望使用单个球员的统计数据来预测一支球队的最终得分,因此我们必须让所有球员一起参加同一场比赛。为了做到这一点,我们将把我们的训练集和测试集按游戏分开,这样玩同一个游戏的玩家就可以呆在一起。大约 80%的游戏将在训练集中进行,20%将在测试集中进行:
对于玩家得分,我们将使用线性回归模型,而不是使用逻辑回归模型,因为我们希望预测一系列可能的值(得分),而不是简单地预测输赢。我们对所有球员的 RMSE(均方根误差)是 5.56,或者相当于每个球员在他们的平均水平上完成或错过了大约 2-3 场比赛。
在测试集上,我们将每支球队每场比赛的预测得分分组,并与他们的实际得分数字进行比较。根据预测得分计算获胜游戏的数量与获胜者的数量,我们得到的比率为 1483/2528,或准确率为 58.66% 。很明显,正如我们之前在观察球队与对手的 PER 分布时所认识到的,球员的总体表现变化太大,无法准确预测比赛的结果,尤其是与球队的表现相比,球队的表现在比赛中往往更加一致。
结论和未来考虑
作为狂热的 NBA 球迷,我们认为创建一个模型来预测 NBA 比赛的结果将是一个有趣的项目,并教会了我们许多关于构建职业体育比赛结果的分类器的知识。我们能够在这个项目中利用我们在大数据分析课上学到的许多概念,包括刮擦、数据清理、特征分析、构建模型和超参数调整,我们要感谢 Ives 教授在整个学期的教学中所做的出色工作。
我们的随机森林回归模型,通过 RandomSearchCV 优化参数,给我们最高的测试精度为 67.15%。略高于 Logistic 回归模型,也远高于基于单个玩家统计的线性回归模型。使用 GridSearchCV 和 RandomizedSearchCV 优化参数既耗时又计算量大,而且对测试精度的影响很小。如果我们有更多的时间,我们可能会花更少的时间优化参数,花更多的时间选择模型。
最好的 NBA 比赛预测模型仅在大约 70%的时间内准确预测获胜者,因此我们的逻辑回归模型和随机森林分类器都非常接近当前存在的预测上限。如果我们有更多的时间,我们将探索其他模型,看看我们能得到多高的测试准确度。这些候选方法包括 SGD 分类器、线性判别分析、卷积网络或朴素贝叶斯分类器。
希望你喜欢阅读我们的作品,就像我们喜欢制作它一样——并且从中学到一些东西。
使用梯度提升树预测 NBA 得分概率
原文:https://towardsdatascience.com/predicting-the-probability-of-scoring-a-basket-in-the-nba-using-gradient-boosted-trees-c157390fb17?source=collection_archive---------14-----------------------
介绍
在我关于 NBA 机器学习的第一篇博客中,我写了职业体育如何产生大量数据,打开了一条广阔的可能性之路。我们可以超越观众的感知,更深入地了解篮球运动的内部运作。
有了尽可能多的可用数据,数据科学家可以在他们创建的模型和用于创建模型的数据方面发挥创造力。这就引出了这篇博文。首先,让我们提出一个奇怪的问题——并使用机器学习来看看我们是否能接近理性的答案:
你为勒布朗·詹姆斯在一场篮球赛中的投篮押上了 100 万美元。你怎么能确定你会赢得奖金?
看看这个博客的配套视频:【https://youtu.be/Lxfsvw7rHgU

由 Alexander Schimmeck 在 Unsplash 上拍摄
统计数据
我们想使用的信息会给我们一个强烈的暗示,詹姆斯是否会得分。撰写本文时,勒布朗詹姆斯职业生涯投篮命中率 50.4%。粗略地说,这意味着如果我们回顾他的整个职业生涯,可以追溯到 2003 年,每次他试图投篮,他得分的几率就像扔硬币一样。如果我们手上有 100 万美元,那就不好了。我们需要让天平向我们这边倾斜。
NBA 中的天才有各种各样的类型,其中一个例子就是看到不同的球员有不同的打球风格和投篮偏好。这方面的一些例子包括:
- 右手对左手射击
- 射击远程对中距离
- 在压力下表现良好(例如在势均力敌的比赛的最后几秒)
信不信由你,这些信息,甚至更多,都是从 NBA 的统计数据中获取的。我们可以利用这些数据,看看如何找到下注的正确篮子。说到这里,我要提到的是,此后在这个博客中引用的所有数据都来自 https://www.basketball-reference.com/。
为了不使事情变得过于复杂,我们将只坚持两个标准来构建我们的模型:射击尝试的位置和游戏的阶段。我们的模型将使用勒布朗·詹姆斯职业生涯投篮数据中的这些特征:
- 尝试击球的 XY 坐标(即球场上的位置)
- 运动员到篮筐的距离
- 射击发生时该季度的剩余时间
- 不管是否在半场结束前尝试投篮
- 不管镜头是否在第四节
最后两个特性是为了给游戏的舞台增加更多的背景。特别是在势均力敌的比赛中,那些最后一分钟或最后一秒钟的投篮会极大地影响比赛的结果,我们希望抓住这一点。这意味着我们假设游戏时间结束时得分的篮子更有价值,玩家会更有动力得分。
梯度增强树
我们将尝试使用梯度增强树来回答这个问题。这是一种用于监督机器学习的决策树。
决策树是一个广泛使用的算法家族,从输入特征中学习“数学流程图”。梯度提升树是一种变体,其中决策树被连续构建,并且每棵树都试图纠正前一棵树的错误。一棵树可能看起来像这样:

可用于确定得分可能性的众多决策树之一。用 GraphViz 可视化。
上图中,我们可以看到一棵树,它的值是从输入要素中获取的。它向我们展示了每个值如何让我们更接近树的决策。“样本”字段告诉我们有多少样本(或篮子尝试)属于这一类别。“值”字段(以及颜色阴影的暗度)告诉我们这棵树的更重要的指标。使用的总树数将等于下面描述的 n_estimators 参数。
在这里了解更多关于梯度增强的信息:梯度增强解释【演示】(arogozhnikov.github.io
我们将花时间在我们的树中调整两个超参数:
- n_estimators :要执行的升压阶段数(换句话说,按顺序排列的树的数量;我们从一棵树到下一棵树“推进”或学习)
- learning _ rate:每棵树从上一棵树学习的强度
在这个实验中,我们希望该算法能够学习球场上的“最佳投篮点”,以及标记最佳投篮时间的窗口。它可能看起来像“在比赛还剩 3 分 26 秒时,短距离投篮将有 73%的机会得分。”
我喜欢决策树的一点是,它们在概念和分析上更容易理解。我们在寻找投篮命中率最高的机会。这将在树的某个节点,并且存在我们的特征集的某种组合,它将导航我们到那里。
结果和案例分析
在这篇博客中,我们将花更多的时间讨论方法和结果,而不是代码设置。如果你对源代码感兴趣,我有一个 GitHub 库链接在这个博客的末尾。
列车测试分离
勒布朗·詹姆斯在 2021-22 赛季的投篮次数比任何现役球员都多。这对我们来说是一个好消息,因为我们可以使用他所有得分的篮筐和他所有错过的篮筐来训练一个模型,以了解他在哪里和什么时候表现最好。我们使用的特征对于每次尝试都是已知的,包括尝试是否成功。为了训练以下模型,我采用了标准的训练-测试-分割,其中 75%的数据用于训练,25%用于测试。重要的是,在分割数据之前,先对数据进行洗牌,以避免我们的模型偏向于只从詹姆斯职业生涯的前 3/4 学习。
超参数调谐
接下来,为了最大化成功的可能性,我进行了一个简短的实验来观察学习率和 n 估计量的影响。这有助于选择最佳模型。
我使用 0.01 到 0.1 之间的学习率,步长为 0.01。准确度迅速上升,然后逐渐下降,一直保持在 2%的范围内。最高准确率为 64.619%,学习率为 0.02。

调整 learning_rate (lr)超级参数
接下来,我调整了 n_estimators 参数。准确率稍高,达到 64.733%。这是使用 learning_rate=0.02 找到的。

调整 n_estimators 超参数
模型检验
随着我们的模型准备好行动,我们可以向它输入测试数据,以检查勒布朗在给定他的球场位置和比赛时间的情况下投篮的概率。我应该注意到,大约 64%的预测准确率是勒布朗所有投篮(即用于训练模型的投篮)的平均预测率。这意味着有特定的投篮场景,在这些场景中,模型可以更准确地预测一个篮筐是否得分。我们可以利用这些场景赢得现金奖励。
有成千上万的样本可供选择,我发现最有见地的方法是看他投篮的上百分位数。换句话说,我们可以规划出勒布朗至少有 70%的可能性投篮得分的投篮场景:

勒布朗·詹姆斯的 70%投篮命中率(坐标轴是 X-Y 球场坐标)
没什么好惊讶的。勒布朗身高 6 英尺 9 英寸,体重 250 磅。在他的职业生涯中,他很少直接冲向篮筐,从干净利落的上篮到高空扣篮。他最可靠的投篮应该就在篮筐下面。蓝色斑点由 609 个独特的镜头组成。有趣的是,这些镜头只发生在比赛时间还剩 1 分 30 秒到 5 分 07 秒的时候。
因此,我们现在有了一个答案:尽管勒布朗·詹姆斯的投篮命中率为 50.4%,但如果我们为勒布朗·詹姆斯的投篮投入 100 万美元,在比赛还剩 1 分 30 秒至 5 分 07 秒的时候,我们有 70%的机会在篮筐下成功。
其他玩家呢?
我们可以将这个算法应用于联盟中的任何球员。最理想的是那些更有得分经验的人。让我们简单看看另外两位高产射手:凯文·杜兰特和斯蒂芬·库里。

凯文·杜兰特 70%的投篮命中率
凯文·杜兰特和詹姆斯有着相似的身材,因此在篮筐下轻松得分。然而,众所周知,他也是“T2”【easy money sniper】的远射手。如果你对凯文·杜兰特下同样的赌注,你会有更多的位置可供选择,你会希望他的投篮发生在比赛还剩 2.8 秒到 5 分 33 秒之间。说说离合器吧!

斯蒂芬·库里 70%的投篮命中率(第四节橙色部分)
如果你碰巧跳过这篇博客中的文字,只看这些情节,你仍然会看到斯蒂芬·库里在投篮方面独树一帜。上面标绘的是库里的 613 次投篮。令我惊讶的是,斯蒂芬·库里的职业生涯投篮命中率比勒布朗·詹姆斯还要低,只有 47.6%。那么为什么我们可以从几乎任何地方选择斯蒂芬库里的镜头呢?
因为斯蒂芬·库里可以从任何地方投篮。
他的投篮不像詹姆斯那样集中。他简直是全能的,几乎可以在球场的任何地方落地。如果你想把赌注下在库里身上,请确保比赛还剩 0.8 秒到 11 分 53 秒。这实际上是整个游戏中的任何时间!我还用橙色标记了可选的第四季度照片。鉴于他在第四节的表现仍然覆盖了整个球场,库里已经成为这项运动有史以来最可靠的射手之一。
模型限制
每一个伟大的机器学习模型都有其局限性。如果我们在这里谈论职业篮球比赛,我们应该承认,在我们的模型中有许多量化和非量化的变量没有考虑到,这些变量可能会影响比赛的结果或投篮的结果。一些例子包括:
- 有争议的射门:在一场比赛中,一名球员可以尝试在完全无人防守的情况下射门,或者有多达 5 名防守队员防守。显然,更多的防守者意味着更强硬的投篮和更低的得分概率。
- 受伤历史:手或脚受伤的球员可能不愿意从一侧或另一侧投篮,即使这是他们占优势的一侧。他们也可能选择避免激烈的接触,这很可能发生在篮下(有些仍然盛行,但是)。
- 常规赛与季后赛:虽然这个博客中描述的模型考虑了常规赛和季后赛中的投篮,但数据本身没有明确的区别。众所周知,一些球员在 NBA 季后赛中提升了他们的比赛水平,或者总体上打了更多的时间,这可能会影响他们在比赛中的表现,无论是好是坏。
为了了解球员在压力下投篮时的心态,还需要进一步的研究。我们可以额外考虑球员的生理状况,比如他们能跳多高,他们手腕和肩膀的角度,或者他们对球网的可见度。然而,这一数据更为稀缺。
偏见、过度适应和 NBA 篮球的背景
在这个实验的概念验证阶段,我向我的推特粉丝分享了一个视频,显示勒布朗·詹姆斯实际上有高达 98%的可能性投篮。纯粹从数字的角度来看,它是 可能为概率高。一个场景可能是这样的:
众所周知,沙奎尔·奥尼尔在他 19 年的联盟生涯中几乎从来没有投过三分球。在总共 22 次尝试中,他只有一次得分。相反,他 22 次出手都得了分,而且他的三分球命中率接近 100%。纵观奥尼尔的所有尝试,他尝试了超过 19000 次投篮,其中大部分是两分投篮,平均得分率为 58.3%。如果他的短程两分篮成功率为 58.3%,而他的远程三分尝试成功率为 100%,你会期望我们的模型将远程三分球视为有效的保证投篮。这是模型偏差,,因为我们高估了进行三分尝试的真实可能性,这被广泛认为是更困难的投篮。
另一种情况,正如我的视频中的情况,是过度适应训练数据的结果。这突出了调整超参数的重要性,以选择能够在专业运动环境中执行的适当模型。NBA 的竞争性质可能会导致像这样的高概率永远不会见天日。
结论
为了重述这篇博客,我们报道了 NBA 球员如何有不同的得分可能性的时空分析。使用梯度增强树,我创建了一个模型,该模型将考虑球员在球场上的位置以及本季度的剩余时间,以预测相应组合产生得分投篮尝试的可能性。在分析中,我们发现像勒布朗·詹姆斯这样的球员经常在接近篮筐的地方投篮,像斯蒂芬·库里这样的球员甚至比我们想象的更好,几乎在任何时间,任何地方都能可靠地投篮。
希望你在博客里学到了新的东西,学到了有用的东西。如果您对查看源代码感兴趣,可以在这里找到我的 GitHub repo:
ChristopheBrown/nba-ml:所有 nba 机器学习演示的主存储库(github.com)
使用 Spotify 音频功能和 Pollstar 数据预测卖票艺术家
原文:https://towardsdatascience.com/predicting-ticket-selling-artists-using-spotify-audio-features-and-pollstar-data-2e231dec4713?source=collection_archive---------27-----------------------
你的艺人会卖票吗?

作者图片
我们为什么关心?
作为一名人才购买者和音乐会推广者,预测门票销售对我来说是一项日常任务。票房记录、流媒体数量、社交媒体关注者数量是音乐行业用来决定艺术家和节目是否值得投资的常用指标。问题是:如果一个艺术家没有票房历史,没有活跃的社交媒体账户,或者没有流媒体历史,那该怎么办?还有其他我们可以考虑的指标吗?我们能通过一个艺术家的音频特征而不是流媒体数量来预测他的销售潜力吗?
项目
这个项目的目标是通过使用 Spotify 音频功能来预测一个艺术家是否有潜力成为顶级售票艺术家。这个项目包括四个部分:(Spotify 数据的数据分析(2)卖票艺人和非卖票艺人的特征比较(3)音乐流派分析(4)机器学习模型。
数据来源
这个项目中使用的数据集来自两个来源:Spotify 和 Pollstar 。Pollstar 是音乐会行业的贸易出版物。我从 Pollstar 获得的数据集包括 834 位艺术家的每周票房记录,包括平均票房总收入、平均售出门票、平均票价等。从 2017 年-2020 年初。

Pollstar 数据集
从 Kaggle 获得的两个 Spotify 数据集包含(1)1921 年至 2020 年间发布的 16 万多首歌曲的音频特征和(2)每位艺术家的音乐流派。
Spotify 数据的数据分析
了解音乐的趋势可以帮助投资者评估并引导他们更好地投资音乐会行业。因此,我决定首先只对 Spotify 数据集进行数据分析,以探索每个音频特征之间的关系。有关每个音频特性的定义,请在此处查看。

音频特征相关矩阵

相关图显示,年份与流行度、能量与响度以及能量与声音高度相关。
我对每个音频特性如何随时间变化很感兴趣,所以我创建了一些折线图来检查特定时代是否有任何趋势。


从图表上看,似乎一首歌越新,受欢迎程度越高;然而,请注意,Spotify 计算其受欢迎程度的方式不仅基于总流媒体数量,还基于歌曲最近的播放次数。一些歌曲可能有较高的流计数,但最近没有播放太多。在这种情况下,受欢迎程度可能会下降。所以,我不会把新歌比老歌流行的结论简单化。
从 1935 年到 1950 年,可跳舞性显著下降,1950 年后逐渐上升。


艺术家制作越来越少的原声和器乐曲目。


现在的音乐比以前更响亮,更有活力。


1950 年后的歌曲比 1950 年前的歌曲口语词少得多;然而,2000 年后,歌曲中的口语单词开始增加。赛道的活跃度会有波动,但总的来说,活跃度会随着时间的推移越来越低。


积极的音乐氛围在 1940 年后显著下降,在 1950 年左右开始上升,但在 2000 年后又开始下降。20 世纪 60 年代后,歌曲的时长显著增加,但在 2010 年后开始减少。


1950 年后,曲目的节奏越来越快。2000 年后露骨歌词明显增多。非常有趣的是,在 2000 年后的很短时间内,显式轨迹增加了,这是最近才发生的。我很好奇显性和其他音频特征之间的关系。我发现,虽然显性歌曲只占总曲目的 9%,但这些歌曲的平均受欢迎程度比非显性歌曲高 55%。此外,明确的轨道比非明确的歌曲有更高的可舞性和能量。



在探索了年份和音频特征之间的关系后,可以看到图表中显示的一些转折点出现在同一时间段。我想知道这些转折点是否与社会环境/背景有关。以下是我对此的想法:
- 战前音乐 vs 战后音乐
一些音频特征在 1940-1950 年间发生了显著的变化,例如可跳舞性、速度、响度和能量的下降。这种变化是由那段时间的战争或其他社会事件引起的吗?
- 说唱音乐的兴起
该表按流派降序显示了不同年份的显性歌曲数量,2000 年以后的显性歌曲多为 hip hop 和 rap 音乐。露骨歌词的增加与嘻哈音乐的兴起有关吗?

- 流媒体时代
一首歌时长的缩短很可能与流媒体时代有关。流媒体服务对艺术家创作音乐和获得报酬的方式产生了巨大影响。这种影响使得艺术家创作出能在短时间内吸引听众注意力的作品。我已经开始怀疑抖音是否会让音乐变得更短。
顶级卖票艺人与其他艺人的特征对比
预处理
在从 Spotify 数据中获得一些对音乐趋势的见解后,我想探讨一下顶级售票艺术家和其他艺术家之间每个音频功能的差异。经过一些数据清理后,我在艺术家栏上合并了 Spotify 数据集和 Pollstar 数据集。最初包含在 Pollstar 数据集中的艺术家将被分配到下面提到的 top_artist 列中为“是”,其余的艺术家将为“否”。
特色工程
我添加了以下用于探索性数据分析的列。
- top_artists: YES 表示某个艺术家在 Pollstar 数据集中;否则,没有。
- active_years:一个艺术家已经发行了多少年的歌曲。
- 发行数量:一位艺术家在 Spotify 上有多少首歌曲。
- duration_minutes:以毫秒为单位的音轨时长转换为以分钟为单位的时长([' duration _ ms ']* 1.66666666667 e-5)。
如前所述,我的目标是通过艺术家的音频特征来预测他们的售票潜力,所以我根据每个艺术家聚合了数据集,以获得每个特征的平均数和标准差。

以下是顶级卖票艺人和其他艺人的特征对比:



顶级卖票艺人的曲目,人气更高,能量更大,声学更弱。



顶级卖票艺术家的曲目速度稍快,声音更大,乐器演奏更少。


顶级卖票艺人的曲目稍长,也不那么正面。


平均而言,顶级卖票艺人在市场上活跃的时间更长。顶级卖票艺人在市场上活跃了 14 年,相比之下其他艺人只有 6 年。顶级卖座艺人平均发行 34 首歌曲,相比之下,其他艺人平均发行 7 首。

根据这个图表,平均而言,顶级卖票艺人在 Spotify 上的受欢迎程度更高。然而,无论艺术家是否销售,发布露骨内容的艺术家比在 Spotify 上发布非露骨内容的艺术家更受欢迎。
音乐流派分析

总的来说,这些年涌现出越来越多的音乐流派,但我更感兴趣的是顶级卖票艺人演奏的顶级音乐流派。请注意,我并没有用 Spotify 的“流行度”来定义哪些流派更受欢迎;相反,我用每个流派的曲目数量来定义不同年份流行的音乐流派。Spotify 上的流行度功能定义了每首歌曲的流行度,但在某些情况下,高流行度歌曲的风格可能不会得到广泛认可。这就是为什么我宁愿用制作了多少首歌曲来定义每个流派的受欢迎程度,而不是用 Spotify 功能来定义受欢迎程度。

访问此处查看交互式仪表盘!
上面的互动图显示了顶尖艺术家的音乐流派在不同的年代演奏。你还可以看到音乐流派的流行程度是如何随着时间的推移而变化的。摇滚乐在 70 年代和 80 年代统治着这个行业。然而,90 年代以后,随着流行音乐和嘻哈音乐开始主导市场,摇滚乐越来越少了。韩国流行音乐和拉丁音乐最近也开始获得认可。
我在用于机器学习的数据集中没有包括音乐流派。在这个数据集中有大约 1000 种不同的音乐流派,所以要对这些流派进行重新分类需要大量的时间和工作。这甚至可能是一个单独的项目,所以我期待着在未来从事这项工作,并看到将流派添加到我的机器学习数据集中的不同结果。
机器学习模型
我用于训练模型的这个数据集是一个不平衡数据集。该数据集包括我们从 Pollstar 数据集了解到的 834 位顶级售票艺术家,以及其他 18851 位非售票艺术家。
数据插补
标准差列中有一些空值。标准差栏中的空值仅仅意味着一些艺术家在 Spotify 上只有一个音轨,因此无法计算每个音频特征的标准差。因此,我用 0 替换了空值。我还虚拟了目标变量(1: top_artist,0: non top_artist)。
型号
在这个项目中使用了两个模型:(1)随机森林分类器(2)逻辑回归。
随机森林分类器
Auc_roc 评分是评价模型性能的指标之一。然而,由于这是一个不平衡的数据集,auc_roc 分数单独可能无法很好地衡量性能。在这种情况下,我会考虑精确度和召回率。精确度和召回率分别解释了正确预测的比例和正确预测目标类的程度。我在进行随机森林分类器时运行了几次 GridSearch,并将其缩小到三个结果。这三种模型之间的得分差异不大,但假阳性率和假阴性率存在差异。



从左至右:型号 1、型号 2、型号 3
型号 1:
- 交叉验证得分(auc_roc): 0.92
- 训练分数(auc-roc): 0.98
- 测试得分(auc-roc): 0.91
- 假阳性率:0.07
- 假阴性率:0.33
型号 2:
- 交叉验证得分(auc_roc): 0.92
- 训练分数(auc-roc): 0.99
- 测试分数(auc-roc): 0.90
- 假阳性率:0.04
- 假阴性率:0.45
模型 3:
- 交叉验证得分(auc_roc): 0.91
- 训练分数(auc-roc): 0.99
- 测试分数(auc-roc): 0.90
- 假阳性率:0.03
- 假阴性率:0.55
特征重要性



这三个模型的特征重要性也是相似的。发行数量、平均受欢迎程度、活跃年限是进行预测时的三大指标。这三个特征的得分也远远高于其他特征。
逻辑回归

逻辑回归的性能不如随机森林分类器,所以我们不考虑这个模型。
我建议选择精度最高的模型作为我们的最终模型。在这种情况下,它将是来自随机森林分类器的模型 3。由于预测一个非卖票艺人成为顶级卖票艺人的成本高于预测一个卖票艺人成为非卖票艺人的成本,我们应该真正关注我们的模型能够多精确地检测到卖票艺人。例如,你会期望为顶级卖票艺术家的演唱会或巡演在场地、设备、员工、招待等方面花更多的钱;然而,如果模型作出了错误的预测,很可能会失去你投资的钱,因为门票销售不会像你预期的那么好。
结论
音乐对社会环境和语境很敏感。虽然我们有先进的技术来帮助我们预测艺术家的表现,但评估你的艺术家是否符合当前的社会环境或背景与模型分数一样重要,甚至更重要。
发行数量、平均受欢迎程度、活跃年份是我们模型中最重要的特征。基于我们的探索性数据分析,这三个特征也显示了卖票艺人与其他艺人的显著差异。然而,在我的探索性分析中,显式是一个非常明显的特征,显式歌词自 2000 年以来一直在显著增加,并继续增长,但它没有显示在特征重要性图中。一个可能的解释是,露骨的内容在两组艺术家中都更受欢迎,所以这个特征不足以预测艺术家的票房表现。然而,由于这是我们探索性数据分析中的一个明显特征,我也会考虑这个特征。
在这个项目中,第一类错误(假阳性)的成本高于第二类错误(假阴性),选择准确率最高的模型将有助于我们避免第一类错误。
音乐流派可以作为投资者了解市场当前趋势的一个指标。根据我们的分析,摇滚乐不像以前那样受欢迎了。相反,流行音乐和嘻哈音乐最近开始主导音乐产业。投资嘻哈歌手可能比投资摇滚歌手风险更低。
音乐行业是一个微妙的行业,与我们的日常生活和社会息息相关。在我看来,选择投资对象比我们想象的要复杂得多。这个项目对我自己的音乐商业之旅是一个很好的开始,也希望对任何对这个行业感兴趣的人有所帮助。
来源
- Yamac Eren Ay , Spotify 数据集 1921–2020,160k+曲目,(2020),Kaggle。
- 演唱会脉动2017–2020,Pollstar。
预测火山爆发🌋带 tsfresh 和 lightGBM 的喷发
原文:https://towardsdatascience.com/predicting-volcanic-eruption-with-tsfresh-lightgbm-8fa119774458?source=collection_archive---------9-----------------------
多元时序数据特征工程和机器学习的最小努力方法。

肖恩·阿佩尔在 Unsplash 上的照片
火山爆发可能夺去数万人的生命,摧毁数百万美元的基础设施,并造成大量的不便。如果科学家可以像预测天气一样预测火山爆发会怎么样?这就是由 INGV 国家地理和火山研究所组织的 INGV 火山爆发预测 Kaggle 竞赛的目的。
我与 tsfresh 和 lightGBM 一起为这场比赛创建了一个简单的解决方案,它在比赛的公共排行榜上排名第 18 位。在这篇文章中,我想详细描述我的解决方案。我还清理并记录了我的竞赛代码,作为 Kaggle 上的公共内核。您可以通过下面的链接查看本文的完整代码。
https://www.kaggle.com/ekhtiar/18th-place-predicting-eruption-full-tutorial
如果您正从多元时间序列数据开始,我希望阅读这篇文章能对您的以下两个主题有所帮助:
- 自动生成多元时间序列数据的特征。
- 为时间序列预测设计鲁棒的机器学习模型。
基于 tsfresh 的时间序列特征生成
时序数据的特征生成可能非常耗时。然而,我们想要为时间序列数据生成的许多技术/特征是众所周知的和标准化的。使用 tsfresh,您可以毫不费力地自动计算大量这些已知的时间序列特征。它甚至有内置的方法来评估生成的要素的要素重要性。整个项目是开源的,你可以在 GitHub 上查看回购。
https://github.com/blue-yonder/tsfresh
使用 tsfresh 相当简单。API 非常干净,你只需要从他们详尽的可用特性列表中描述你想要的特性,然后让 tsfresh 提取它们。然而,在探索的开始,不知道你想要的那种特性是非常普遍的。所以 tsfresh 也提供了预构建的特征提取设置。我将在下面描述其中的一些:
comprehensive fc parameters:用于处理所有可用的时间序列特性。当您不知道需要哪些功能时,这很有用。
MinimalFCParameters :包含一组非常小且基本的时序特征(最小值、最大值、标准差等)。对于在启动管道之前设置快速测试非常有用。
efficient FCS parameters:包含所有计算时间不高的特性。如果您有一个非常大的数据集,并且没有办法处理一组完整的要素,这将非常有用。
以下代码片段说明了如何使用这些设置之一来提取数据帧上的时间序列要素。
**import pandas as pd
from** **tsfresh.feature_extraction** **import** extract_features
**from** **tsfresh.feature_extraction** **import** ComprehensiveFCParametersdf = pd.read_csv('/path/to/file.csv')
settings = ComprehensiveFCParameters()
features_df = extract_features(df, default_fc_parameters=settings)
一旦处理了足够的数据,就可以应用不同的技术来理解特性的重要性。一旦知道了想要的要素,就可以“手写”想要从数据集中提取的设置。还有一个方便的技巧,使用 from_columns 函数从列名到设置。下面是如何工作的代码片段。
**from tsfresh.feature_extraction.settings import from_columns**# fictions function to get top features from your dataset
top_features_column_names = features_df.get_top_features()# get the config for the selected columnsconfig = from_columns(top_features_column_names)# get selected features for another dataframe
selected_features_df = extract_features(another_df, column_id = 'id', kind_to_fc_parameters = config)
在这次比赛的情况下,我首先用 ComprehensiveFCParameters 处理了训练数据集。然后,我删除了高度相关和准常数的列,并生成定制设置来处理测试集。下一节将给出更多的细节。注意,lightGBM 不会接受由 tsfresh 生成的列名,因为它们通常带有减号(-)。你必须写一个小函数来匹配两者之间的名字。
数据处理细节
这项比赛提供了十分钟的地震传感器读数和每一段的爆发时间。在训练数据集中,我们有 4231 个片段,在测试数据集中,我们有 4520 个片段。我们需要预测每段测试数据的爆发时间。对于每个片段,我们有 60,000 个数据点(10 分钟);所以我们有高质量和高频率的数据。
由于一些特征计算量很大,对于每个片段,我将数据点分成 6 批(每批 10,000 个数据点)。我也可以对数据点的总数进行下采样,这样更符合常规,但我想采用非常规方法。

图:数据处理流程(图片作者提供)
目前,我们的数据集有 2854 个要素。首先,我处理了训练数据集的所有可能特征(ComprehensiveFCParameters)。这产生了近 8000 个特征。然后,我删除了高度相关的列和准常数特征。这使我们的特征下降到 2854。我还应用了一个递归的特性排除法来选择前 501 个特性(500 似乎是一个太好的数字了)。这些列在此笔记本中是硬编码的。完整的数据集也作为公共数据集上传到 Kaggle 上,您可以通过以下链接查看:
https://www.kaggle.com/ekhtiar/ingv-parquet
模型架构
为了预测火山爆发的时间,我使用了基于树的学习算法和 lightGBM (LGBM)框架。它是 Kaggle 上许多人的首选框架,也是我的起点。起初,我使用了一个使用顶级特性的普通 lightGBM 模型;它产生了不错的结果。从这里开始,改善我的结果的最常见的方法可能是用算法创建更多的模型,并对结果进行平均。然而,在现实生产模型中,多种模型的混合很难管理。因此,我决定做一些稍微不同的事情,而不是混合多个模型。
为了改进我的结果,我创建了两层 lightGBM 模型。我称之为一般化-特殊化分层。首先,单个模型用于对整个数据集进行初始预测。然后在第二层,我训练了多个模型。这些模型更加专业化,因为它们是用特定喷发时间范围内的数据训练的。为了处理第一个模型的更大程度的误差,我在第二个模型的范围之间创建了重叠。最后一点琐碎的细节,在拟合之前,我还使用了最小-最大缩放来缩放我们的数据,以获得最佳性能。
为了预测测试数据,首先使用来自第一层的模型进行初始预测。基于这种预测,我们使用第二层的特定模型来进行更准确的预测。因为我们在喷发时间范围上有重叠,所以可以用两个模型评估一个测试段。最后,对于测试数据集中的每个片段,我们有六个输出或预测。然后我们取这些输出的中间值来得到我们最终预测的喷发时间。我试着在下面的图表中想象这个过程(尽我所能)。

图:按模型层的预测流程(图片由作者提供)
超参数调谐
LightGBM 有非常多的超参数需要调整。像所有基于树的算法一样,lightGBM 也因过度拟合而闻名。过度拟合的一个主要原因是模型的复杂性。我通过控制叶子的数量( num_leaves )和最大深度( max_depth )参数来防止 lightGBM 构建过于复杂的模型。我还使用了大量的估计器(n _ 估计器)和正则化(λ_ L1和λ_ L2)来减少过拟合。还控制了总迭代次数( num_iterations ),并且还引入了早期停止( early_stopping_round) 以防止过拟合。最后,我还试图通过使用额外的树、特征分数和 bagging_fraction 来引入大量的随机性。下面是第二层模型的超参数配置。
params = {
'application':'regression',
'boosting ': 'dart',
'num_iterations':8000,
'learning_rate':0.05,
'num_leaves': 95,
'extra_trees': True,
'feature_fraction':0.8,
'bagging_fraction':0.9,
'lambda_l1':0.1,
'lambda_l2':0.1,
'min_split_gain':0.01,
'early_stopping_round':100,
'max_depth': 7,
'min_child_weight':40,
'n_estimators': 400,
'metric':'mae',
}
您还会注意到,第一层要简单得多(叶子的数量和深度更多)。实验表明,保持第一个模型没有第二个模型复杂会产生好的结果。这也使得第一个模型可以一般化,第二个模型可以专门化。
结果
本次竞赛使用平均得分(MAE ),该解决方案的个人得分为 4200311。这在排行榜上排在第 18 位,我很高兴我的简单解决方案最终排在了这么高的位置。下面的条形图显示了不同范围的喷发时间值的平均得分。左边的条形图来自第一个模型,右边的来自第二个模型。
由于第二种模式可以关注更小的时间范围,他们往往做得更好。此外,该模型的总体得分有所提高。对于这两个极端(爆发的时间很快或很晚),我创建了一个额外的模型。由于最低和最高之间的范围非常大,即使是专门的模型也更倾向于该范围的中间。这些针对两种极端情况的额外模型有助于更好地预测极端情况。

图:层间 MAE 比较(图片由作者提供)
最后的想法
这是一场有趣的 Kaggle 比赛,非常感谢组织者组织了这场比赛。像任何其他比赛一样,在参加这个比赛时,我从其他卡格勒的作品中学到了很多。
我希望我有时间对特性的重要性做更系统的研究和可视化。我还认为在第一层使用多个分类器而不是单个模型可能是更好的方法。哦,好吧,我会把这段经历带在身边,以便将来做得更好。
预测获胜概率
原文:https://towardsdatascience.com/predicting-win-probability-910af3b48f75?source=collection_archive---------13-----------------------
迷你教程
在销售机会上使用机器学习
您是否曾经不得不确定在销售渠道中赢得机会的概率?营销团队创造销售线索,销售团队跟进销售线索,在此过程中,每个机会都会经历一个生命周期,从 RFP 阶段一直到最终成交。随着机会从一个阶段过渡到下一个阶段,联系人会分配一个将销售线索转化为销售的概率,从而赢得机会。
但是这个概率有多准呢?给定一个足够大的包含多个预测变量的数据集,我们可以使用机器学习来确定赢得机会的概率吗?我们在一家领先的资产管理公司建立了一个概念验证,展示让机器说话的好处:)
特性
利用九个不同的数据源提取了机会级别的 14 个属性。这些因素包括关系持续时间、预期的机会持续时间、CRM 活动数量、机会数量、机会类型(新的、交叉销售等)。)、自上次联系以来的持续时间、进行的演示次数、演示者姓名、参加的产品网络研讨会次数、管理的资产以及资产价值的增长。
这些被转换成单个数据框,每个记录代表一个机会,如下所示

作者图片
培训和测试
然后,机会数据框架被分为开放和关闭的机会。对于已结束的业务机会,最终状态是已知的——成功、失败或无效,而对于开放的业务机会,状态是预测的。状态标签转换为 0 或 1,1 表示赢得机会,0 表示失去机会(包括“非活动”状态)。
关闭的机会以 75:25 的比例分成培训和测试,同时使用 Caret 包中的 createDataPartition 函数维护状态标签的比例。

作者图片
> set.seed(101)
> intrain = createDataPartition(y=closed_opps$Label, p=0.75, list=FALSE)
> traindf = closed_opps[intrain,]; traindf$Label = as.factor(traindf$Label)
> testdf = closed_opps[-intrain,]; testdf$Label = as.factor(testdf$Label)
模型
我使用 R 中的 Caret、ARM 和 XGBoost 包在训练数据上建立监督机器学习模型,并将机会分类为赢或输。
朴素贝叶斯:一种基于贝叶斯定理的分类算法,在给定每个预测变量取某个值的情况下,确定赢得或失去机会的概率。
nb_model <- train(Label ~ ., data = traindf, method = “naive_bayes”, trControl = fitControl, na.action = na.pass)
逻辑回归:具有二元结果的广义线性模型,使用 sigmoid 函数将其转换为概率。每个预测变量的“权重”由模型确定,以减少实际值和预测值之间的误差。
lr_model <- train(Label ~ ., data = traindf, method = “glm”, family = “binomial”, trControl = fitControl, na.action = na.pass)
贝叶斯 GLM: 逻辑回归模型的扩展,但它根据贝叶斯方法假设预测变量的先验分布。
bayenesian_model <- train(Label ~ ., data = traindf, method = “bayesglm”, trControl = fitControl, na.action = na.pass)
增强逻辑回归:几个逻辑回归模型的集合,然后用于根据单个预测进行预测。
boosted_lr_model <- train(Label ~ ., data = traindf, method = “LogitBoost”, trControl = fitControl, na.action = na.pass)
随机森林:决策树的集合,用作慢学习器,通过使用在每个节点提供最佳分割的特征将训练数据分成各自的状态,对每个机会进行分类。
library(randomForest) # to build a random forest model
rf_model = train(Label ~ ., data = traindf, method = “rf”, ntree = 30, maxdepth = 5, trControl = fitControl, na.action = na.pass)
detach(“package:randomForest”, unload=TRUE) #conflicts with margin in ggplot
极端梯度推进:以连续的方式构建决策树的集合,其中每个模型的残差适合后续的模型。
xgb_model <-train(Label ~., data = traindf, method = “xgbTree”, trControl = fitControl, tuneGrid = xgb.grid, verbose = T, nthread = 2, na.action = na.pass)
极限梯度提升(带 DART): 极限梯度提升算法的扩展,但是为了避免过度拟合的问题,在每个阶段都要丢弃树。
xgbDART_model <- train(Label ~ ., data = traindf, method = “xgbDART”, trControl = fitControl, na.action = na.pass)
性能指标
然后,每个 ML 模型被部署在测试数据集上
nb_predictions_test = predict(nb_model, newdata = testdf, type = “raw”)
bayenesian_predictions_test = predict(bayenesian_model, newdata = testdf, type = “raw”)
boosted_lr_predictions_test = predict(boosted_lr_model, newdata = testdf, type = “raw”)
lr_predictions_test = predict(lr_model, newdata = testdf, type = “raw”)
rf_predictions_test = predict(rf_model, newdata = testdf, type = “raw”)
xgbDART_predictions_test = predict(xgbDART_model, newdata = testdf, type = “raw”)
xgb_predictions_test = predict(xgb_model, newdata = testdf, type = “raw”)
使用 3 个度量来测量性能:ROC、灵敏度和特异性。ROC 是接收器操作特性,即曲线下的面积,分类器的整体精度。敏感度是真正的肯定率,即被正确预测为成功的机会数量占总成功的比例。特异性是真实的负比率,即被正确预测为失去的机会数占失去的机会总数的比例。

作者图片
结果
随机森林模型在测试数据集上提供了最高的灵敏度。这用于预测赢得公开机会的概率,结果以下列方式展示。

作者图片
该算法还用于使用 Caret 包中的 varImp 函数来确定每个输入特征的重要性。结果表明,我们假设对模型有贡献的某些特征实际上没有帮助,这就需要讨论数据是否有错,或者我们是否必须修改我们对该特征的假设。
用例
能够预测管道中机会的成功率将使我们能够实施“早期预警系统”,并提供一个与潜在客户互动的框架。例如,CRM 活动可以基于成功概率以及机会数量来划分优先级。此模型的输出也可以成为后续细分模型的输入,该模型将客户划分为战略客户或其他客户。
挑战
我们在研究这些模型时面临的主要挑战是缺乏清晰的数据。我们发现在不同的电子表格文件中维护数据的方式有几处不一致,必须手动将它们映射到中央存储库中的 kID。我们还发现,ML 模型需要比构建模型时更多的数据。随着我们从遗留系统过渡,并同时清理数据,我们相信这种概念验证将会出现。
如果您有任何意见或反馈,或其他预测销售渠道中机会成功率的方法,请使用下面的评论部分。

斯蒂芬·道森在 Unsplash 上拍摄的照片
有用的链接
以下是 Caret 软件包上的一个链接,您会发现它很有用:
https://cran . r-project . org/web/packages/caret/vignettes/caret . html
用调谐梯度提升树预测葡萄酒价格
原文:https://towardsdatascience.com/predicting-wine-prices-with-tuned-gradient-boosted-trees-9ab5ebd0b85e?source=collection_archive---------40-----------------------
利用 Optuna 寻找最佳超参数组合
什么是超参数调谐?
许多流行的机器学习库使用超参数的概念。这些可以被认为是机器学习模型的配置设置或控制。虽然在拟合模型的过程中学习或求解了许多参数(比如回归系数),但有些输入需要数据科学家预先指定值。这些是超参数,然后用于建立和训练模型。
梯度推进决策树的一个例子是决策树的深度。较高的值可能会产生更复杂的树,可以提取某些关系,而较小的树可能能够更好地进行概括,并避免过度拟合我们的结果,这可能会导致预测未知数据时出现问题。这只是超参数的一个例子,许多模型都有许多这样的输入,它们都必须由数据科学家定义,或者使用代码库提供的默认值。
这可能看起来很困难— 我们如何知道哪种超参数组合会产生最准确的模型呢? 手动调优(寻找最佳组合)可能需要很长时间,并且覆盖很小的样本空间。这里将介绍的一种方法是使用 Optuna 来自动完成一些工作。可以指定超参数的范围,而不是手动测试组合,Optuna 进行了一项研究,以确定给定时间限制下的最佳组合。
数据集概述
为了演示 Optuna 和 hyperparameter 调优,我们将使用一个包含来自 Kaggle 的葡萄酒评级和价格的数据集。给定一瓶红酒的一些输入特征——比如地区、点数和品种——使用超参数调优,我们能在多大程度上预测葡萄酒的价格?

数据集概述点击查看全尺寸版本
在我们的数据中加载几行代码,并进行训练/测试分割:
# Read in data from local csv
df = pd.read_csv('winemag-data-130k-v2.csv')
# Choose just a few features for demonstration, infer categorical features
feature_cols = ['country', 'points', 'province', 'region_1', 'region_2', 'taster_name', 'variety', 'winery']
cat_features = [col for col in feature_cols if df[col].dtype == 'object']
for col in cat_features:
df[col] = df[col].fillna('Other')
target_col = 'price'
# Train test split
train_df, test_df = train_test_split(df, test_size=0.3, shuffle=False)
train_x = train_df.loc[:, feature_cols]
train_y = train_df.loc[:, target_col]
test_x = test_df.loc[:, feature_cols]
test_y = test_df.loc[:, target_col]
模特培训
基线模型
为了知道我们的超参数优化是否有帮助,我们将训练几个基线模型。第一种是采用简单的平均价格。使用这种方法的结果是 79%的平均绝对百分比误差——不是很好,希望一些机器学习模型可以改善我们的预测!
第二个基线是用默认参数训练我们的模型(使用 Catboost 库)。下面是几行代码。这击败了我们的基线简单均值预测,但我们能通过进一步优化做得更好吗?
# Train a model with default parameters and score
model = CatBoostRegressor(loss_function = 'RMSE', eval_metric='RMSE', verbose=False, cat_features=cat_features, random_state=42)
default_train_score = np.mean(eda.cross_validate_custom(train_x, train_y, model, mean_absolute_percentage_error))
print('Training with default parameters results in a training score of {:.3f}.'.format(default_train_score))Output: Training with default parameters results in a training score of 0.298.
超参数优化模型
设置优化研究
为了使用优化的超参数创建我们的模型,我们创建了 Optuna 所谓的研究——这允许我们定义具有超参数范围的试验,并优化最佳组合。
您将在下面的代码中看到,我们用一个试验对象定义了一个目标函数,它根据我们定义的范围建议超参数。然后,我们创建研究并进行优化,让 Optuna 完成它的工作。
def objective(trial):
# Define parameter dictionary used to build catboost model
params = {
'loss_function': 'RMSE',
'eval_metric': 'RMSE',
'verbose': False,
'cat_features': cat_features,
'random_state': 42,
'learning_rate': trial.suggest_float('learning_rate', 0.001, 0.2),
'depth': trial.suggest_int('depth', 2, 12),
'n_estimators': trial.suggest_int('n_estimators', 100, 1000, step=50)
}
# Build and score model
clf = CatBoostRegressor(**params)
score = np.mean(eda.cross_validate_custom(train_x, train_y, clf, mean_absolute_percentage_error))
return score
查看结果
Optuna 将最佳结果存储在我们的学习对象中。运行以下程序可以让我们访问最佳试用和查看培训结果。
# Grab best trial from optuna study
best_trial_optuna = study.best_trial
print('Best score {:.3f}. Params {}'.format(best_trial_optuna.value, best_trial_optuna.params))Output: Best score 0.288\. Params {'learning_rate': 0.0888813729642258 'depth': 12 'n_estimators': 800}
与默认参数比较
将训练结果与我们初始运行的默认参数进行快速比较,显示出良好的迹象。您将看到优化的模型具有更好的训练拟合度(在这种情况下,分数是百分比误差,因此越低=越好)。
# Compare best trial vs. default parameters
print('Default parameters resulted in a score of {:.3f} vs. Optuna hyperparameter optimization score of {:.3f}.'.format(default_train_score, best_trial_optuna.value))Output: Default parameters resulted in a score of 0.298 vs. Optuna hyperparameter optimization score of 0.288.
分析优化趋势
一个很好的例子是平行坐标图。这使我们能够观察试验并分析潜在趋势的超参数。如果我们发现有趣的优化,我们可能希望在审查结果后运行新的研究,允许我们搜索额外的超参数空间。
# Visualize results to spot any hyperparameter trends
plot_parallel_coordinate(study)

平行坐标图点击查看全尺寸版本
您可以在左侧看到成本指标(越低=越好)。沿着黑线(最佳试验),您会注意到深度越高效果越好,学习率在测试值的中间,并且有更多的估计值。鉴于这些发现,我们可以重新运行一项研究,缩小这些值的范围,并潜在地扩大其他值的范围——例如深度可能增加到我们的上限以上,或者添加额外的超参数进行调整。
比较测试结果
最后一步是比较测试结果。第一步是观察我们的简单平均预测基线在测试集上的表现。
# Run baseline model (default predicting mean)
preds_baseline = np.zeros_like(test_y)
preds_baseline = np.mean(train_y) + preds_baseline
baseline_model_score = mean_absolute_percentage_error(test_y, preds_baseline)
print('Baseline score (mean) is {:.2f}.'.format(baseline_model_score))Output: Baseline score (mean) is 0.79.
下一步是查看我们默认超参数模型的测试结果:
# Rerun default model on full training set and score on test set
simple_model = model.fit(train_x, train_y)
simple_model_score = mean_absolute_percentage_error(test_y, model.predict(test_x))
print('Default parameter model score is {:.2f}.'.format(simple_model_score))Output: Default parameter model score is 0.30.
比简单地用平均值作为预测要好很多。我们的超参数优化解决方案能在测试集上做得更好吗?
# Rerun optimized model on full training set and score on test set
params = best_trial_optuna.params
params['loss_function'] = 'RMSE'
params['eval_metric'] ='RMSE'
params['verbose'] = False
params['cat_features'] = cat_features
params['random_state'] = 42
opt_model = CatBoostRegressor(**params)
opt_model.fit(train_x, train_y)
opt_model_score = mean_absolute_percentage_error(test_y, opt_model.predict(test_x))
print('Optimized model score is {:.2f}.'.format(opt_model_score))Output: Optimized model score is 0.29.
我们能够通过超参数优化改进我们的模型!我们只在一个小空间里搜索了几次,但是改进了我们的成本度量,得到了更好的分数(误差降低了 1%)。
所有的例子和文件都可以在 Github 上找到。
原发布于https://data stud . dev。
预测 2021 年:人工智能正常化的一年
原文:https://towardsdatascience.com/prediction-2021-the-year-ai-became-normal-1968d4053803?source=collection_archive---------37-----------------------
2021 年将看到商家拥抱 AI,不是因为他们想,而是因为他们不得不
许多年后,2020 年将被视为人工智能的分水岭。在新冠肺炎肆虐世界的前所未有的一年,关于人工智能的有用性已经出现了一个明确的答案——企业需要找到一种创造性地,广泛地,大胆地应用人工智能的方法,以在短期内变得更强大,并在长期内生存。
人工智能已经出现了一个清晰的增长模式:2018-19 年,实验阶段变得成熟;2020 年,采用以一种严肃的方式开始,突然,新冠肺炎给了商业领袖一个推动自动化和人工智能的机会和动力。2021 年,英国和其他许多国家第二波新冠肺炎的余波将最终变得清晰,首先是许多传统的非数字业务的迅速衰落。随着高管们的关注,以下是我预计将在 2021 年出现的相关趋势:
1。企业将衡量“真正的”人工智能指标
2020 年,企业跳出实验模式,在后 COVID 时代,立足于现实,加速采用。2021 年,他们将采用人工智能计划在传统指标方面的商业成果,如收入、客户流失、客户忠诚度等。虽然企业有责任理解人工智能的影响,但我们这些数据科学家有责任建立“翻译表”来实现同样的目标。
数据科学家根据准确度、精确度和召回率、F1 分数、AUC 或类似的“科学”指标来评估他们项目的“成功”,这与企业衡量项目有效性的方式非常不同。为了弥合这一差距,数据科学家必须坐下来,最好是先验地,与企业一起制定一个通用框架,以了解和衡量他们工作的影响。
例如,在我的雇主、世界顶级电信公司之一的 Airtel,我们使用以下简单的表格来与产品组和业务部门分享成果:

图 1:将数据科学成果转化为清晰理解的业务影响,改善沟通并建立信任。图片来源:作者
一旦这些“翻译表”建立起来,所有的数据科学家、产品专家和相关企业就可以很容易地专注于同一个目标并衡量影响。
2。职场 AI 和人机协作将加速
我们看到了一个有趣的视频,波士顿动力公司的机器人随着西部、好莱坞、印度等音乐起舞。曲调。除了这个广受欢迎的视频的社交媒体狂热之外,工作场所人工智能还有一个长期趋势正在出现,并将尽快推动自动化和增强需求。后 COVID 世界将更加虚拟化,基于位置、身体或人际接触的工作者和在家工作的知识工作者的工作场所都将被破坏。它也将越来越少接触,特别是在 B2C 环境中,如零售、酒店、运输、食品和饮料服务等,导致下一个预测…
图 2:波士顿动力公司的机器人在年终舞蹈表演中
3。计算机视觉将是“下一个前沿”
在第二波疫情在全球传播的过程中,2020 年 12 月发布的一则鲜为人知的公告没有引起大多数人的注意:亚马逊计划推出监控工厂工人和机器的工具。该系统名为 AWS Panorama,使用计算机视觉分析设施内的闭路电视摄像机镜头,自动检测安全和合规问题,如工人未穿戴 PPE,或车辆在未经授权的区域行驶。虽然这听起来微不足道,但考虑到一个大型工业仓库(250,000 平方英尺。25,000 平方英尺 mt .)可以拥有 500-600 台以 60 fps(每秒帧数)运行的闭路电视摄像机,每天生成约 4300 万至 5200 万张图像,每月约 15 亿张。
图 3:在边缘运行的视觉算法能够实时确定“热点”。视频:S20.ai 和 Youtube
过去几年发明的新一代技术使这成为可能;联邦学习平台如 S20。专注于工业计算机视觉的 AI 或专注于医学研究数据和图像的 Owkin,使得以隐私保护方式处理和理解这些数据成为可能。
这得益于硬件能力的快速增长。 NVIDIA 的 Jetson 系列 GPU 及其 EGX AI 平台为物联网应用的计算机视觉和边缘计算开辟了巨大的机遇。与此同时,NVIDIA A100 GPU通过多实例功能,可以在单个 GPU 上并行运行多达七个任务,显著提高了云中繁重计算机视觉工作负载的处理能力。苹果最新的 M1 芯片也显示出 3.9 倍的视频处理速度和 7.1 倍的图像处理速度。
然而,随着人工智能技术渗透到我们生活的各个领域,它对大流行后世界的经济未来产生了重大影响。
4。由人工智能驱动的“K 经济”的增长将加速
2021 年,遭受重创的经济体将开始重建,世界上最早从 COVID 中复苏的地区,如印度和中国,将是增长最快的。2021 年将是“K 经济”的开始,其大致定义是,数字化和推动更快人工智能增长的经济体和公司之间的表现差异越来越大。最坚韧的公司将把人工智能推向新的前沿,用于远程协作、按需制造,并转向数字体验、推荐等方面的智能实验。在边缘。

图 4:由人工智能驱动的“K 经济”的增长将在后 COVID 世界加速
鉴于人工智能工具在过去两年中已经显著民主化,一流的算法在斯坦福、谷歌或中国开发出来后很快就可以使用,落后者仍然有可能一次性的机会积极实现他们的顶级人工智能 10、20 或 50 个用例,可能是用无代码的 AutoML 工具。
随着人工智能模型开始影响我们生活的许多方面,…
5。人工智能模型必须保证信任和公平,很快
随着人工智能渗透到我们的生活中,系统必须公平、负责任并可靠地重现结果。考虑一个基于“替代”信用数据对无银行账户客户进行信用评分的人工智能系统。这种评分模型依赖于对零工经济工资支票、小额贷款的使用和偿还、社交档案、智能手机的使用(通话、数据)、电子商务网站上的购物等的访问。虽然创造这些产品的崇高目的是让数百万人获得正规信贷,但贷款人和用户都必须信任该系统,产品才会有效。
随着电子商务、银行、娱乐和其他日常系统与人工智能结合,企业将必须确保公众可以确信正在使用的人工智能技术是透明、安全的,并且其结论不会有偏见或受到操纵。2021 年,提供可信度和“公平”衡量标准的技术将开始融入人工智能生命周期,帮助我们构建、测试、运行、监控和认证人工智能应用,以获得信任,而不仅仅是性能
这不仅限于人工智能算法…
6。AI 的阴暗面
随着数据量的增加,2021 年可能会展示人工数据的好的、坏的和丑陋的使用,这些数据被注入模型中以造成伤害。例如,在一个稀疏的数据环境中,某个月升级手机通话计划的人数,“合成数据”允许科学家创建扩展的数据集来训练人工智能。虚假数据是为了完全相反的目的而创建的:它意味着扰乱人工智能训练,以创建受污染的模型和结果。

图 5:伪造的数据和内容,“深度伪造”将在 2021 年成为人工智能的“黑暗面”。照片由h·海尔莱恩在 Unsplash 上拍摄
正如 2020 年美国大选所展示的那样,传播错误信息和虚假内容的人工智能机器人更难被检测到。事实上,这次对 Deepfake AI 文本内容操纵选举结果的担忧如此之高,以至于 GPT-3 AI 的创造者 OpenAI 已经承诺限制其仅用于道德用途的可用性,密切监控其应用编程接口(API)。
人工智能在未来几年的发展将与任何其他最近的技术发展非常不同。人工智能不同于过去开发的任何其他强大的技术——它无处不在的高质量算法在几周内就可以到达全球,包括 GPU 在内的廉价计算能力以及 AutoML 等无代码技术都是可用的。为了应对这种威胁,我预计 2021 年的人工智能专业人员将寻找一种共识的方法来识别和揭示人工智能应用程序中的敌对威胁。对抗式人工智能威胁度量标准,一个开放的、可扩展的行业框架,用于对最常见的用于破坏 ML 系统的对抗策略进行分类,可能会被 ML 和 DevOps 工程师采用。
摘要
2021 年将是人工智能的分水岭,该技术将在 2018-19 年脱离实验周期,在 2020 年被采用,并开始成为所有类型的企业、流程、产品和服务的日常活动的一部分。像 COVID 这样的百年一遇的“黑天鹅”事件将推动“K 经济”的增长,迫使企业迅速开始采用人工智能,否则就会面临灭亡的风险。
后 COVID 世界将是无接触和数字化的,服务是自动化和远程驱动的。因此,工作场所人工智能和人机协作将加速发展,将计算机视觉技术置于最前沿。
随着人工智能渗透到我们生活的每个领域,消费者对技术的理解将开始改变。然而,要被公众广泛接受,这些制度必须是公平和负责任的。否则,预计会看到人工智能的采用受到严重抵制——推迟,但仍不会最终阻止人工智能驱动的世界。
结语:我写的是关于数据科学、机器学习、产品管理和职业成功的故事。你可以跟着我把这些放进你的培养基里。
上一篇: 用“印度级”技术为世界供电
下一个故事: 印度贫困地址的经济影响:一年 100-140 亿美元
2021 年对 Graph ML 来说意味着什么?
原文:https://towardsdatascience.com/predictions-and-hopes-for-graph-ml-in-2021-6af2121c3e3d?source=collection_archive---------3-----------------------
2020 年回顾与 2021 年预测
年底是总结和预测的好时机。2020 已经把 Graph ML 变成了机器学习的名人。在这篇文章中,我征求了 graph ML 及其应用领域的杰出研究人员的意见,试图总结过去一年的亮点,并预测 2021 年将会发生什么。

图片:Shutterstock
超越消息传递
威尔汉密尔顿 ,麦吉尔大学助理教授兼米拉大学 CIFAR 主席,著有graph sage。
“2020 年,图形 ML 领域面临着消息传递范式的基本限制。
这些限制包括所谓的“瓶颈”问题[1],过度平滑的问题[2],以及代表能力方面的理论限制[3,4]。展望未来,我预计在 2021 年我们将寻找图形 ML 的下一个大范式。我不确定下一代 Graph ML 算法到底会是什么样子,但我相信,要取得进展,就需要打破 2020 年及之前主导该领域的消息传递模式。
我也希望 2021 年 Graph ML 也将进入更有影响力和更具挑战性的应用领域。最近太多的研究集中在简单的、同质的节点分类任务上。我还希望看到在需要更复杂的算法推理的任务方面的方法进步,比如涉及知识图、强化学习和组合优化的任务。"
算法推理

指针图网络结合了经典计算机科学中的结构归纳偏差。图片来源:P. Velič ković。
佩塔尔·韦利奇科维奇 ,deep mind 高级研究员,著有 图关注网络 。
“2020 年已经明确且不可逆转地将图形表示学习转变为 ML 领域的一等公民。”
今年取得的巨大进步不胜枚举,但我个人最感兴趣的是神经算法推理。传统上,神经网络在插值领域非常强大,但众所周知,它是可怕的外推器——因此也是不充分的推理器;因为推理的主要特征之一是能够在非分布情况下发挥作用。推理任务很可能是 GNNs 进一步发展的理想选择,不仅因为它们与这种任务非常匹配[5],还因为许多现实世界的图形任务表现出同质性,这意味着最有效和可扩展的方法通常是 GNNs 的更简单形式[6,7]。
基于以前的神经执行器的历史成功,如神经图灵机[8]和可微分神经计算机[9],并通过现在无处不在的图形机器学习工具箱得到加强,2020 年发表的几部作品探索了神经执行器的理论限制[5,10,11],基于 GNNs[12-15]导出了新的和更强的推理架构,并实现了对神经推理任务的完美的强泛化[16]。虽然这种架构可以自然地转化为 2021 年组合优化的胜利[17],但我个人最兴奋的是预先训练的算法执行者如何允许我们将经典算法应用于过于原始或不适合该算法的输入。作为一个例子,我们的 XLVIN 代理[18]正是使用这些概念来允许 GNN 在强化学习管道中执行值迭代式算法,即使底层 MDP 的细节是未知的。我相信到 2021 年,GNN 应用于强化学习的时机将会成熟。"
关系结构发现

GNNs 允许学习一个状态转移图(右),它解释了一个复杂的多粒子系统(左)。图片来源:T. Kipf。
托马斯·基普夫 ,谷歌大脑研究科学家,《图卷积网络https://tkipf.github.io/graph-convolutional-networks/的作者。
自从最近广泛采用基于 GNN 的模型以来,Graph ML 社区中一个特别值得注意的趋势是计算结构与数据结构的分离。
在最近的 ICML 研讨会上,我将这种趋势称为关系结构发现的 T2。通常,我们设计图形神经网络以在数据集提供的固定(或临时演变)结构上传递消息,即数据集的节点和边被视为我们模型的计算结构或消息传递结构的黄金标准。
在 2020 年,我们已经看到人们对能够适应计算结构的模型越来越感兴趣,即它们使用哪些组件作为节点,以及它们在哪些节点对上执行消息传递,同时超越简单的基于注意力的模型。2020 年有影响力的例子包括摊销因果发现[19–20],它利用神经关系推理从时间序列数据中推断(并推理)因果图,具有可学习指针[21,15]和关系机制[22–23]的 GNNs,具有自适应计算图的基于学习网格的物理模拟器[24],以及学习推断执行计算的抽象节点的模型[25–26]。这一发展具有广泛的影响,因为它允许我们在其他领域(如文本或视频处理)有效地利用 GNN 架构提供的对称性(如节点置换等方差)和归纳偏差(如成对交互作用函数的建模)。
展望未来,我预计我们将看到在给定一些数据和任务而不依赖于显式监督的情况下,如何学习最佳计算图结构(在节点和关系方面)的许多发展。对这种习得结构的检验可能有助于更好地解释和诠释习得模型为解决任务而执行的计算,并可能允许我们进一步类比因果推理。"
表现力
Haggai Maron ,Nvidia 研究科学家,著有* 可证明表现力的高维图形神经网络 。*
“图形神经网络的表达能力是 2020 年 Graph ML 的中心主题之一。
有许多优秀的论文讨论了各种 GNN 架构的表达能力[27],并显示了当 GNN 的深度和宽度受到限制时 gnn 的基本表达能力限制[28],描述了使用 gnn 可以检测和计数什么类型的结构[29],显示了使用固定数量的 gnn 对于许多图形任务没有意义,并建议了一种迭代 GNN,该迭代学会自适应地终止消息传递过程[14]。
在 2021 年,我很高兴看到图形生成模型的原则性方法的进步,GNNs 的图形匹配和 GNNs 的表达能力之间的联系,学习图像和音频等结构化数据的图形,以及在 GNN 社区和处理场景图形的计算机视觉社区之间建立更强的联系。"
可扩展性
马蒂亚斯 ,多特博士生,* PyTorch 的开发者几何开图基准 。*
“2020 年 Graph ML 研究中最热门的话题之一是解决 GNNs 的可伸缩性问题。
一些方法依赖于通过从传播中分离预测来简化底层计算。我们已经看到许多论文简单地将不可训练的传播方案与图不可知的模块相结合,作为预处理[30,7]或后处理[6]步骤。这导致了极好的运行时间,并且,值得注意的是,在同形图上,性能基本相当。随着对越来越大的数据集的访问,我渴望看到如何从这里向前发展,以及如何以可扩展的方式利用可训练和表达的传播。"
动态图表

动态图表。
伊曼纽·罗西 , ML 推特研究员,伦敦帝国理工学院博士生,著有 时态图网络 。
“许多有趣的图形 ML 应用程序本质上是动态的,其中图形拓扑和属性都随着时间而发展。
在社交网络、金融交易网络或用户-物品交互网络中就是这种情况。直到最近,绝大多数关于图 ML 的研究都集中在静态图上。试图处理动态图的少数作品主要考虑的是离散时间动态图,一系列有规律间隔的图快照。在 2020 年,我们看到了一组新兴的作品[31–34 ],它们是关于更一般类别的连续时间动态图,可以被认为是一个异步的定时事件流。此外,动态图模型的首次有趣的成功应用也开始出现:我们看到了虚假账户检测[35],欺诈检测[36],以及控制流行病的传播[37]。
我认为我们只是触及了这个令人兴奋的方向的表面,许多有趣的问题仍然没有答案。重要的开放性问题包括可扩展性、对动态模型更好的理论理解,以及在单一框架中结合信息的空间和时间扩散。我们还需要更可靠和更具挑战性的基准,以确保能够更好地评估和跟踪进展。最后,我希望看到更多动态图神经架构的成功应用,尤其是在行业中。"
新硬件

Graphcore 是一家为图形开发新硬件的半导体公司。图片来源:Graphcore
Mark Saroufim, ML 工程师graph core。**
“我想不出我合作过的任何一个客户没有在生产中部署过图形神经网络,也不打算这样做。
这种趋势的一部分是,在诸如 NLP、蛋白质设计或分子性质预测的应用中,自然图形结构传统上被忽略了,取而代之的是,数据被视为适合于现有的和完善的 ML 模型(如 Transformers)的序列。然而,我们知道,变形金刚只不过是 GNNs,注意力被用作邻居聚集函数。在计算领域,某些算法获胜并不是因为它们非常适合解决某个问题,而是因为它们在现有硬件上运行良好,这种现象被称为硬件彩票【38】——在 GPU 上运行的变形金刚就是这种情况。
在 Graphcore,我们建立了一个新的 MIMD 架构,它有 1472 个内核,可以并行运行总共 8832 个程序,我们称之为智能处理单元(IPU)。这种架构非常适合加速 GNNs。我们的 Poplar 软件堆栈利用稀疏性将计算图的不同节点分配给不同的内核。对于可以放入 IPU 900 MB 片上存储器的模型,我们的架构提供了比 GPU 更大的吞吐量提升;否则,只需几行代码,就可以将模型分布到数千个 IPU 上。
我很高兴看到我们的客户利用我们的架构建立了一个大型研究机构,包括 SLAM 的束调整、使用本地更新训练深度网络或加速粒子物理中各种问题的 T2。我希望在 2021 年看到更多的研究人员利用我们先进的 ML 硬件。"
在工业、物理、医学等领域的应用

MagicLeap 的 SuperGlue 使用 GNN 来解决特征匹配的经典计算机视觉问题。图片来源:P.-E .萨林等人。
谢尔盖·伊万诺夫研究科学家克里捷奥主编 图形机器学习简讯 。****
“对于 Graph ML 研究来说,这是令人震惊的一年。所有主要的 ML 会议都有大约 10-20%的论文致力于这个领域,在这个范围内,每个人都可以找到自己感兴趣的图形主题。
Google Graph Mining 团队在 NeurIPS 上表现突出。看着 312 页的演示文稿,人们可以说谷歌在生产中利用图表方面比其他任何人都先进。他们使用 Graph ML 解决的应用包括用时空 GNNs 对新冠肺炎建模、欺诈检测、隐私保护等等。此外,DeepMind 在谷歌地图的全球范围内推出了用于旅行时间预测的 GNNs。他们的方法的一个有趣的细节是 RL 模型的集成,以选择相似的采样子图为 GNNs 的训练参数。这种方法和高级超参数调整将实时到达时间估计的精度提高了 50%。
GNNs 的另一个值得注意的应用是 Magic Leap,它专注于 3D 计算机生成图形。他们的 SuperGlue 架构[39]将 GNNs 应用于图像中的特征匹配,这是 3D 重建、地点识别、定位和映射的一个重要主题。这种端到端的特征表示与最佳传输优化相结合,在实时室内和室外姿态估计上取得了胜利。这些结果只是触及了 2020 年所取得成就的表面。
明年,我相信我们会看到 Graph ML 开发在工业环境中的进一步应用。这将包括生产管道和框架、新的开源图形数据集,以及为电子商务、工程设计和制药行业大规模部署 GNNs。"

用图形表示的粒子射流。人们正在探索 gnn 来探测粒子物理中的事件。图片来源:LHC
凯尔·克兰默 ,NYU 大学物理学教授,希格斯玻色子的发现者之一。**
“令人惊讶的是,在过去的两年中,Graph ML 在物理领域变得非常流行。
粒子物理中深度学习的早期工作经常迫使数据进入图像表示以与 CNN 一起工作,这是不自然的,因为我们的数据本身不是网格状的,图像表示非常稀疏。图表是我们数据的更自然的表示[40,41]。大型强子对撞机的研究人员正在努力将 Graph ML 集成到每秒处理数十亿次碰撞的实时数据处理系统中。通过部署推理服务器将 Graph ML 与实时数据采集系统【42】集成,并努力在 FPGAs 和其他特殊硬件上实现这些算法【43】,努力实现这一点。
2020 年图表 ML 的另一个亮点是证明了它的归纳偏差可以与符号方法配对。例如,我们使用 GNN 来学习如何预测各种动态系统,然后我们对沿着边缘发送的消息进行符号回归[44]。我们不仅能够恢复这些动力系统的基本真理力定律,还能够在我们没有基本真理的情况下提取方程。令人惊讶的是,提取的符号方程可以重新引入 GNN,取代原来的学习组件,我们甚至获得了更好的分布数据的推广。"

GNNs 可以利用人口图进行疾病分类。图片来源:S. Parisot。
Anees Kazi ,TUM 博士生,医学影像中图形 ML 多篇论文作者。**
“在医疗领域,Graph ML 改变了分析多模态数据的方式,这种方式非常类似于专家在临床常规中从所有可用维度查看患者病情的方式。
最近,与医学成像和医疗保健应用中的 Graph ML 相关的研究出现了巨大的增长[45],包括大脑分割[46],使用针对疾病预测的 MRI/fMRI 数据进行的大脑结构分析[47],以及药物效果分析[48]。
在 Graph ML 的主题中,有几个在 2020 年的医学领域中脱颖而出。首先,潜在图学习 [22,49,50],因为根据经验为给定数据定义一个图在当时是获得最佳结果的瓶颈,现在已经通过自动学习潜在图结构的方法得到解决。其次,数据插补【51】,由于缺失数据是医学领域许多数据集中的一个长期存在的问题,基于图形的方法有助于根据来自图形邻域的关系进行数据插补。第三,Graph ML 模型的可解释性[52],因为对于临床和技术专家来说,专注于推理 Graph ML 模型的结果以将其可靠地合并到 CADx 系统中是很重要的。2020 年医疗领域的另一个重要亮点当然是冠状病毒疫情,Graph ML 方法用于检测新冠肺炎[53]。****
在 2021 年,Graph ML 可用于进一步提高 ML 模型的可解释性,以更好地做出决策。其次,已经观察到图 ML 方法仍然对图结构敏感,因此对图扰动和敌对攻击的鲁棒性是一个重要的课题。最后,将自我监督学习与 Graph ML 的集成应用于医学领域将会非常有趣。"

使用几何 ML 架构 MaSIF 设计的肿瘤学靶标的不同蛋白质结合剂。图片来源:巴勃罗·盖恩萨。
Bruno Correia,EPFL 助理教授,蛋白质设计与免疫工程实验室负责人,MaSIF开发者之一。****
“2020 年,蛋白质结构预测这一生物信息学的关键问题取得了令人振奋的进展。然而,最终显示在这些分子表面的化学和几何图案对于蛋白质功能是至关重要的。
基于表面的分子表示已经使用了几十年,但它们对机器学习方法提出了挑战。几何深度学习领域的方法给蛋白质建模领域带来了令人印象深刻的能力,因为它们能够处理不规则数据,特别适合蛋白质表示。在 MaSIF [1]中,我们在基于网格的分子表面表示上使用几何深度学习来学习模式,这些模式允许我们预测蛋白质与其他分子(蛋白质和代谢物)的相互作用,并将对接计算速度提高几个数量级。反过来,这可以促进更大规模的蛋白质相互作用网络的预测。
在 MaSIF 框架[2]的进一步发展中,我们设法动态生成我们的表面和化学特征,避免了所有的预计算阶段。我预计这种进展将对蛋白质和小分子设计产生变革性影响,从长远来看,可能有助于生物药物的更快发展。"

GNNs 在 Decagon 中用于预测多种药物的副作用。图片鸣谢:M. Zitnik。
马林卡·齐特尼克 ,哈佛大学医学院生物医学信息学助理教授,著有 迪卡侬 。**
“看到 Graph ML 在 2020 年进入生命科学领域令人兴奋。
我们已经看到,图形神经网络不仅在精心设计的基准数据集上优于早期方法,而且可以开辟开发新药的途径,以帮助人们从根本上理解自然。亮点包括单细胞生物学的进展[56],蛋白质和结构生物学[54,57],以及药物发现[58]和重新定位[59]。
几个世纪以来,科学方法——科学家用来系统和逻辑地解释自然世界的基本科学实践——基本上保持不变。我希望在 2021 年,我们将在使用 Graph ML 来改变这一点上取得实质性进展。为了做到这一点,我认为我们需要设计能够优化和操纵网络系统并预测其行为的方法,例如基因组学——自然对人的实验——如何在疾病背景下影响人类特征。这种方法需要处理干扰和干预数据(不仅仅是摄取我们世界的观测数据)。此外,我希望我们将开发更多的方法来学习可操作的表示,这些表示很容易在科学中适用于可操作的假设。这种方法可以在高风险环境(例如,化学测试、粒子物理、人类临床试验)中进行决策,我们需要精确、可靠的预测,并对其进行有意义的解释。"
[1] U. Alon 和 E. Yahav,论图神经网络的瓶颈及其实际意义 (2020) arXiv:2006.05205 .
[2] Q. Li,Z. Han,X.-M. Wu,半监督学习的图卷积网络的深入见解 (2019) Proc .AAAI。
[3] K. Xu 等 图神经网络到底有多强大? (2019) Proc。ICLR。
[4] C. Morris 等人 Weisfeiler 和 Leman go neural:高阶图神经网络 (2019) Proc。AAAI。
[5]徐国光等神经网络能推理什么?(2019) arXiv:1905.13211。**
[6] Q. Huang 等 结合标签传播和简单模型优于图神经网络 (2020) arXiv:2010.13993 .
[7] F .弗拉斯卡等 SIGN:可扩展初始图神经网络 (2020) arXiv:2004.11198 .**
[8] A. Graves,G. Wayne 和 I. Danihelka,神经图灵机 (2014) arXiv:1410.5401。
[9] A. Graves 等 使用具有动态外部存储器的神经网络的混合计算 (2016)。自然 538:471–476。
[10]耶胡达、加贝尔和舒斯特。不是机器能学会什么,而是我们不能教什么 (2020) arXiv:2002.09398。
[11] K .徐等 神经网络如何外推:从前馈到图神经网络 (2020) arXiv:2009.11848 .**
[12]p . veli kovi等, 图算法的神经执行 (2019) arXiv:1910.10593。**
[13] O. Richter 和 R. Wattenhofer,无概率笼的标准化注意 (2020) arXiv:2005.09561。
[14] H. Tang 等,利用迭代齐次图神经网络求解尺度不变图相关问题 (2020) arXiv:2010.13547 .
[15]p . veli kovi等人 指针图网络 (2020) Proc。神经炎。**
[16] Y. Yan 等 神经执行引擎:学习执行子程序 (2020) Proc。ICLR。
[17] C. K .乔希等 学习 TSP 需要反思概括 (2020) arXiv:2006.07054 .**
[18] A. Deac 等 XLVIN:已执行潜值迭代网 (2020) arXiv:2010.13146。
[19]s . lwe等,摊余因果发现:学习从时间序列数据推断因果图 (2020) arXiv:2006.10833。**
[20] Y. Li 等,从视频中发现物理系统中的因果关系 (2020) Proc。神经炎。
[21] D. Bieber 等,用指令指针注意图神经网络学习执行程序 (2020) Proc。神经炎。
[22] A .卡兹等,图卷积网络的可微图模(DGM)(2020)arXiv:2002.04999**
[23] D. D .约翰逊、h .拉罗歇尔和 d .塔洛。、用有限状态自动机层学习图结构 (2020)。arXiv:2007.04929。**
[24] T .普法夫等,用图网络学习基于网格的仿真 (2020) arXiv:2010.03409 .**
[25] T. Kipf 等,结构化世界模型的对比学习 (2020) Proc .ICLR
[26] F. Locatello 等,带槽注意的对象中心学习 (2020) Proc .神经炎。
[27] W. Azizian 和 M. Lelarge,表征不变和等变图神经网络的表达能力 (2020) arXiv:2006.15646。
[28] A. Loukas,神经网络无法学习的图形:深度与宽度 (2020) Proc。ICLR。
[29] Z .陈等,图神经网络能统计子结构吗? (2020) Proc。神经炎。**
[30] A. Bojchevski 等,用近似 PageRank 的标度图神经网络 (2020) Proc .KDD。
[31] E. Rossi 等,动态图上深度学习的时态图网络 (2020) arXiv:2006.10637 .
[32] S. Kumar,X. Zhang,J. Leskovec,预测时态交互网络中的动态嵌入轨迹 (2019) Proc .KDD。
[33] R. Trivedi 等, DyRep:动态图上的学习表示 (2019) Proc .ICLR。
[34] D .徐等,时态图上的归纳表征学习 (2019) Proc .ICLR。**
[35] M. Noorshams,s .维尔马和 A. Hofleitner,关系:在脸书加强社会媒体完整性的时间互动嵌入 (2020) arXiv:2002.07917。
[36] X .王等,:用于实时时态图嵌入的异步传播注意网络 (2020) arXiv:2011.11545 .**
[37] E. A. Meirom 等,如何阻止流行病:用强化学习和图神经网络控制图动力学 (2020) arXiv:2010.05313 .
[38] S .胡克,硬件彩票 (2020),arXiv:2009.06489。
[39] P. E. Sarlin 等,强力胶:用图形神经网络学习特征匹配 (2020)。继续。CVPR。
[40] S. Ruhk 等,用距离加权图网络学习不规则粒子探测器几何图形的表示 (2019) arXiv:1902.07987。
[41] J .什洛米,p .巴塔格利亚,J.-R .弗利芒特,粒子物理中的图形神经网络 (2020) arXiv:2007.13681 .
[42] J .克鲁帕等人。、 GPU 协处理器作为高能物理中深度学习推理的服务 (2020) arXiv:2007.10359。
[43] A. Heintz 等,基于 FPGAs 的图形神经网络加速带电粒子跟踪 (2020) arXiv:2012.01563。
[44] M. Cranmer 等,从具有归纳偏差的深度学习中发现符号模型 (2020) arXiv:2006.11287。迈尔斯·克兰默与凯尔·克兰默无关,尽管两人都是这篇论文的合著者。另请参见论文的视频演示。
[45] Q .蔡等,多模态数据驱动的智慧医疗系统综述:方法与应用(2020)IEEE Access**7:133583–133599****
[46] K. Gopinath,C. Desrosiers 和 H. Lombaert,用于对齐不变的大脑表面分割的图形域适应(2020)arXiv:2004.00074**
[47] J. Liu 等,利用多模态数据和图卷积网络识别早期轻度认知障碍 (2020) BMC 生物信息学21(6):1–12
[48] H. E. Manoochehri 和 M. Nourani,使用半二分图模型和深度学习进行药物-靶标相互作用预测 (2020)。 BMC 生物信息学**21(4):1–16
[49] Y. Huang 和 A. C. Chung,用于不确定性感知疾病预测的边变分图卷积网络 (2020) Proc .米凯
[50] L. Cosmo 等, 用于疾病预测的潜图学习 (2020) Proc。米凯
[51] G. Vivar 等, 利用多图几何矩阵补全对不完整医学数据集中的同时插补和疾病分类 (2020) arXiv :2005.06935。
[52] X. Li 和 J. Duncan, BrainGNN:用于 fMRI 分析的可解释脑图神经网络(2020)bior XIV:2020 . 05 . 16 . 100057
[53] X .于等, ResGNet-C:一种用于检测的图卷积神经网络 (2020)神经计算。**
[54] P .盖恩萨等,利用几何深度学习从蛋白质分子表面破译相互作用指纹 (2020)《自然方法》17(2):184–192。**
[55] F .斯维里松等,蛋白质表面的快速端到端学习(2020)bior XIV:2020 . 12 . 28 . 424589。**
[56] A. Klimovskaia 等,用于分析单细胞数据中复杂层次的庞加莱图 (2020)《自然通讯》11。
[57] J. Jumper 等,利用深度学习的高精度蛋白质结构预测(2020)a . k . a .alpha fold 2.0(论文尚未提供)。
[58] J. M. Stokes 等,抗生素发现的深度学习方法 (2020)《细胞》180(4):688–702。
[59] D. Morselli Gysi 等,为新冠肺炎确定药物再利用机会的网络医学框架 (2020) arXiv:2004.07229。
我感谢 Bruno Correia、Kyle Cranmer、Matthias Fey、Will Hamilton、Sergey Ivanov、Anees Kazi、Thomas Kipf、Haggai Maron、伊曼纽·罗西、Mark Saroufim、Petar Velič ković和 Marinka Zitnik 令人鼓舞的评论和预测。这是我第一次尝试“科学新闻”的新形式,我很欣赏改进的建议。不用说,所有的荣誉都属于前面提到的那些人,而任何批评都是我的责任。本帖的 中文翻译 由 志强钟 提供。我也和萨姆·查林顿在 TWIML 播客 中讨论了这些预测。
对图形 ML 和几何深度学习感兴趣?查看我的 博客 关于走向数据科学, 订阅我的 帖子,获取 中等会员 ,或者关注我的 推特 。
预测分析—模型预测及其可解释性挑战
原文:https://towardsdatascience.com/predictive-analytics-model-predictions-and-their-interpretability-challenges-acbb8ff44b3f?source=collection_archive---------20-----------------------
模型可解释性在模型选择中的关键作用

弗兰基·查马基在 Unsplash 上拍摄的照片
介绍
人类通过推理来证明他们的决定。这样的推理有助于辨别决策,并对其充满信心。有时,这种推理逻辑可能不是直截了当的,但可以加入轶事引证、先入为主的直觉、假设的假设和公理化的思维。然而,只要这种判断足够令人信服,足以引起信心,这种决定通常是可以接受的。虽然原因可能并不简单,但任何因果关系的解释程度、与类似事件的任何关联、或潜在因素/环境之间的关系的确立,将导致对此类决定的更高程度的信任。本质上,这就像相信直觉相信判断。例如,患者相信基于医生对疾病的预测、对诊断的解释、基于经验的推理以及引用可比较的示例病例的治疗计划。
当预测模型预测结果或做出决定时,类似的推理也是可以预期的。然而,有一些关键的区别。虽然几个因果的、环境的、公理的和相关的因素可以证实人类的推理,但是唯一可以认可预测结果的因素是实例观察、特征特性和用于训练预测模型的算法。这些限制对预测模型的可解释性或可解释性提出了挑战。
可解释性
在进入讨论的实质之前,有必要理解可解释性在模型预测的上下文中意味着什么。对于模型的可解释性,业界没有一致的定义。然而,可解释性可以通过以下几个方面来描述:
- 算法清晰性:这涉及到对算法内部如何工作的全面理解,应用了哪些数学直觉,执行了哪些计算来处理和优化输入,处理后的输入如何映射到预测的输出,以及算法如何工作来确保预测的准确性。
- 模型可解构性:这意味着将模型分解成粒度模型单元或结构的能力,这些单元或结构解释了模型预测的部分原因。例如,在贷款批准的决策树中,一个决策节点检查申请人的信用评分是否大于阈值。另一个例子是神经网络中的隐藏节点,它为特定的输入变量分配权重。
- 模型综合能力:这意味着在人类可接受的时间框架内,使用模型参数和输入数据手动完成每个计算,以获得模型预测输出的能力。遍历分层线性模型中的每一步来解释对预测结果的固定效应和随机效应是模型综合的一个例子。
- 事后可解释性:这是对上述所有内容的补充,以进一步加强预测推理。虽然事后可解释性并不严格依赖于模型算法的内部工作,但它通过提供额外的支持信息来补充。特设可能采用其他效用模型来支持推理。对于输入图像,使用 k-最近邻模型呈现相似的图像来证明深度学习图像分类模型预测特定类别的原因是事后可解释性的一个示例。类似地,post hoc 可以使用模型可视化和其他基于实例的图示来进一步解释预测。
从上面可以推断,计算的复杂性和模型的体系结构极大地影响了模型的可解释性。虽然计算复杂性影响算法的清晰性和模型的可综合性,但模型架构的复杂性影响模型的可解构性。根据可解释性的程度,预测模型可以分为黑盒或白盒模型。
黑盒与白盒模型
预测分析主要解决两大类预测问题——分类和回归。在分类中,预测模型将基于输入变量预测不同的类别标签作为输出。在回归的情况下,预测模型将根据输入变量预测定量输出,如产品的价格。预测模型被归类为黑盒或白盒的首要原因是与模型行为的可解释性和模型结果的可解释性有关。
黑盒模型
给定一组输入数据,黑盒预测模型预测输出。虽然输入和输出变量之间的关系可以从训练数据集中观察到,但黑盒模型要么缺乏模型结果的可解释性,要么没有提供一种直接的方式来推理模型为什么以及如何预测特定的输出。缺乏可解释性有两个主要原因。第一个原因是底层算法是高度复杂的,具有复杂的数学计算。因此,即使是经验丰富的从业者也很难理解数学工作的模型,并将其转化为支持模型预测的推理。第二个原因是,虽然模型的内部计算很容易理解,但模型的设置和架构在训练时会变得复杂,因为输入数据要经过多次运算和复杂的转换。因此,虽然可以解释算法的基本表面工作,但很难根据输入数据在处理过程中经历的所有计算和转换来推理预测。具有利用多维向量空间中的复杂超平面的算法、利用复杂概率网络的算法以及利用子模型集合的算法的大多数模型通常属于黑盒模型的类别。然而,模型的准确性随着模型复杂性的增加而增加。因此,黑盒模型通常会产生更准确的预测,但代价是模型的可解释性。
白盒模型
与黑盒模型类似,白盒模型在给定一组输入的情况下预测输出。但是,白盒模型可以解释训练数据集中输入和输出变量之间的关系,并且可以轻松地在预测输出和给定输入数据之间建立类似的关系。利用基于规则的算法、决策树、决策表、模式匹配和从训练实例中学习的算法的预测模型通常属于白盒解决方案的类别。这种算法通过推理模型如何和为什么预测特定输出,通过其内部工作和可解释性提供了清晰度。然而,白盒解决方案可能无法提供黑盒解决方案为复杂问题场景提供的准确性。尽管如此,在某些情况下,可以提高白盒模型的架构复杂性来增加模型的准确性,但代价是模型失去了模型的可解释性。在这种情况下,白盒模型可能会变成更多的黑盒模型。实际上,在黑盒和白盒模型之间进行选择的一个关键驱动因素是准确性和可解释性之间的权衡。
模型的功能类型
模型类型的功能分类也有助于理解不同模型类型的可解释性是如何变化的。预测模型的功能类型可以大致分类如下:
基于超平面的模型
这些模型利用使用训练数据在多维向量空间中拟合超平面的算法。拟合的超平面在高维向量空间中分离输出变量的类别。给定输入数据,模型通过应用所需的转换来处理输入。多维空间中的变换输入向量可以帮助模型确定输入向量位于超平面的哪一侧,并选择输入向量最可能属于的输出类。这种模型属于黑盒解决方案的范畴,因为它们实现了复杂的数学计算,很难解释模型预测的原因。人工神经网络(ANN)、卷积神经网络(CNN)、递归神经网络(RNN)、支持向量机(SVM)、核方法等。是基于超平面的模型的例子。
带有子模型的集合
集合模型使用多个子模型,在大多数情况下是弱子模型,以基于子模型做出的预测的投票或平均来提高准确性。他们使用 boosting 或 bagging 技术来训练每个子模型。子模型独立地或者基于来自前一个子模型的结果从训练数据中学习。这样,集成导致了复杂的决策层次结构,该层次结构很难解释给定输入数据的预测输出。因此,这种集合模型属于黑箱解决方案的范畴。随机森林(RF)、极端梯度提升(XGBoost)、自适应提升(AdaBoost)、贝叶斯自适应采样(BAS)等。是集成算法的例子。
概率网络模型
底层算法在概率网络模型中构建特征和输出节点的复杂非循环有向图。每个节点维护连接到它的先前节点的所有组合条件概率的知识。实际上,模型会选择输出结点值作为预测,对于该预测,基于模型遍历的所有先前结点评估的条件概率最大。虽然此类模型采用的概率理论很容易理解,但在现实世界中,这些模型会构建一个复杂的节点图,其中包含内部计算的不同特征节点。因此,遍历模型并解释它为什么以及如何预测特定的输出变得非常困难。因此,这种模型属于黑箱解决方案的范畴。马尔可夫网络和贝叶斯网络就是这种模型的例子。
规则驱动的、基于模式的、类似决策树的模型
在规则驱动、基于模式或类似决策树的模型的情况下,在开发预测模型之前,输出结合输入的前提是众所周知和充分理解的。这种预测模型甚至是在理解了这种前提之后才开发出来的,因为虽然这种规则和模式的排列和组合是有限的,但是它们很难管理。一旦模型从训练数据集学习,模型就承担起这种繁重的工作。因为模型基于特定模式或规则集或通过遍历决策树来进行预测,所以很容易根据模型在考虑每个输入变量时必须做出的中间决策来解释预测。因此,这种模型通常属于白盒解决方案的范畴。然而,如果规则集变得过于层次化,或者决策树变得过于深入和嵌套,则可解释性可能会受到影响,因为由此产生的错综复杂的决策层次结构可能太难解释。在这种情况下,模型变成了一个黑盒解决方案。
线性模型
线性模型建立了输入和输出变量之间的线性关系。这种关系的强度以作为模型参数的线性系数的形式来估计。参数的量化估计有助于确定每个输入要素相对于输出变量的重要性,并有助于解释模型基于给定输入数据预测输出的原因和方式。因此,线性模型通常属于白盒解决方案的范畴。然而,如果线性模型具有高维输入空间,或者如果在模型开发时附加了几个计算工程变量或虚拟变量,则线性模型可能会失去其可解释性。线性回归和逻辑回归就是这种线性模型的例子。
基于实例的模型
在基于实例的模型的情况下,该算法基于给定输入数据和来自训练数据的过去实例之间的局部近似进行预测,该训练数据基于指定的目标函数表现出相似的特征,然后采用策略来确定局部的领域以选择实例。一旦选择了在功能上与给定输入相似的本地实例,该算法就基于投票或平均来挑选预测。因为预测是基于使用相似实例的局部近似,所以该模型表现出高度的可解释性。实际上,本地选择的相似实例的特征可以解释模型的预测行为。因此,基于实例的模型通常属于白盒解决方案的范畴。k 近邻(kNN)、自组织映射(SOM)等。是基于实例的模型的例子。
型号选择
确定哪种模型解决方案最合适取决于几个因素,包括底层算法主题和技术细节领域之外的因素。例如,当模型预测被认为是准确的,但被理解为超出人类的识别能力时,黑盒解决方案将是正确的。在这种情况下,模型执行复杂的操作来建立人类无法理解的输入和输出变量之间的关系。例如,在互联车辆用例中预测关键道路交叉口的交通量。在这种情况下,模型可能需要使用来自路边传感器的数据、关于附近事故或道路维修的数据、交通高峰时间等。,准确预测交通量。人工神经网络(ANN)或支持向量回归(SVR)或极端梯度推进(XGBoost)等复杂算法的使用是有保证的,因为:
- 该解决方案旨在预测交通量,以防止任何道路事故。
- 没有预设的模式来建立规则,以规定不同输入的什么组合将确定交通量的估计。排列和组合的数量会激增到超出人类理解的程度。
- 模型预测可以很容易地与人类可以预测的相关联,因此模型结果可以被验证。
同样,在有些情况下,必须采用白盒解决方案。例如,推理和因果关系优先的情况,因为潜在的问题域要求对预测进行这样的推理,或者遵从性法规强制执行这样的推理要求。例如,美国《平等信贷机会法》认为,拒绝向理由模糊或不合理的申请人提供银行贷款是非法的。因此,金融机构可能必须采用白盒模型进行分类,同时提供一种简单的方式来解释预测决策背后令人满意的原因。类似地,在医疗保健和医学领域,决策需要合理的推理和因果关系归属,采用白盒解决方案进行医学预测可能变得至关重要。在所有这些情况下,预测的纯粹准确性不再重要,但可解释性变得至关重要。因此,所选择的模型应该基于这两种考虑之间的折衷。在其他一些场景中,模型的简单性可能会促使选择更直接的白盒解决方案。
然而,有些情况下可以利用黑盒和白盒模型的组合来开发预测分析解决方案。在这种情况下,黑盒模型被用来进行初步预测,但事后白盒模型补充了预测的可解释性。例如,用于图像分类的 CNN 模型的可解释性将是困难的,因为 CNN 采用了复杂的卷积运算、图像过滤和变换,这些运算和变换缺乏通过人类解释的可识别性。然而,可以使用 CNN 为每个训练图像提取的复杂特征来开发单独的、更简单的白盒模型,例如决策树或聚类模型。然后,这种白盒模型可以匹配来自训练数据的相似图像,以实现事后推理和可解释性。
结论
当预测模型预测一个结果或做出一个决定时,人类可以理解的推理是被期待的。能够证实预测结果的可解释性的唯一要素是实例观察、特征特性和用于训练预测模型的算法。这些限制对预测模型的可解释性提出了挑战。虽然模型可解释性没有标准的定义,但是底层算法的清晰性、模型的可解构性、模型的可综合性和事后可解释性是整个模型可解释性的特征。
根据可解释性的程度,预测模型可以分为黑盒或白盒模型。黑盒模型缺乏模型结果的可解释性,或者缺乏一种简单的方法来解释为什么以及如何预测特定的输出。相比之下,白盒模型能够解释训练数据集中输入和输出变量之间的关系,并易于在预测输出和给定输入数据之间建立类似的关系。具有利用多维向量空间中的复杂超平面的算法的模型、利用复杂概率网络的算法以及利用子模型集合的算法通常属于黑盒模型的类别。利用基于规则的算法、决策树、决策表、模式匹配和从训练实例中学习的算法的模型通常属于白盒解决方案的类别。
确定哪种模型解决方案最合适取决于几个因素,包括底层算法主题和技术细节领域之外的因素。黑盒解决方案将是正确的,模型预测预计是准确的,但被理解为超出了人类的识别能力。推理和因果关系优先的用例,因为潜在的问题域要求对预测进行这样的推理,或者合规性法规使用白盒模型强制执行这样的推理要求保证。一些用例利用黑盒和白盒模型的组合来开发预测分析解决方案。在这种情况下,通常采用黑盒模型进行更精确的初步预测,而白盒模型补充了预测的事后可解释性。
由于模型的准确性会随着模型复杂性的增加而增加,因此黑盒模型通常会产生更准确的预测,但会牺牲模型的可解释性。实际上,在黑盒和白盒模型之间进行选择的一个关键驱动因素是准确性和可解释性之间的权衡。因此,在决定选择模型算法来开发预测分析解决方案之前,数据科学家和机器学习专家必须首先了解问题域、其目标以及底层的合规性和推理要求。在平衡模型准确性的同时,模型的可解释性对于满足所有这些强制性要求变得至关重要。
人工智能模型的预测能力
原文:https://towardsdatascience.com/predictive-capacity-of-ai-models-989d19675e86?source=collection_archive---------24-----------------------
知道人工智能的极限!

由 Unsplash 上的 drmakete 实验室拍摄的照片
模型精度
基于神经网络的预测机器学习模型在判断大型数据集时非常强大。但是理解它们是众所周知的困难。
使用标记的数据集来训练神经网络。它们的表现如何是用一个标记的测试集来验证的。这是模型准确性、混淆矩阵、roc 等的地方。派上用场了。
让我们假设我们已经训练了一个 88%准确的模型。这意味着在验证模型的过程中,88%的预测被发现是正确的,12 %的预测被发现是错误的。

(图片由作者提供)
将这个模型应用到新数据中,我们知道 88%的情况下预测是正确的,但在哪些情况下预测是完全正确的。因此,模型精度本身并不是评估单个预测的一个很好的指标。我们需要估计一下有多大信心预测是正确的。
如果模型旨在基于预测自动做出决策,则没有预测置信度估计的预测模型是无用的。
因此,人工智能模型也应该为每个预测估计一个置信度。我们有多确定这个预测是正确的?
预测置信度
让我们假设我们有一个能够计算预测置信度的算法。然后,我们可以根据标记的测试数据验证训练好的模型,并根据预测置信度分析预测结果(正确或错误)。一个实际的例子是根据测试集计算每 5%置信区间的正确和错误预测的数量。
下图显示了一个示例,其中 88%的模型精度现在分布在置信区间上。我们有两类人:正确的预测和错误的预测。考虑这个例子 1。

示例 1:88%准确度的模型的预测置信度的实际分布。(图片由作者提供)
如果我们想在自动化过程中使用预测,我们希望能够设置一些置信度阈值,高于该阈值我们接受预测,低于该阈值我们拒绝预测。被拒绝的预测将需要额外的验证,要么通过其他模型,要么通过人类。
具有高置信度的预测为真或假阳性,而具有低置信度的预测为真或假阴性。
一个理想的模型应该显示正确和错误预测的两个群体之间没有重叠。在下面给出的例子中,同样具有 88%的模型精度,阈值可以设置在 35%-60%置信度范围内的任何地方。考虑这个例 2 。

示例 2:88%准确度的模型的预测置信度的理想分布。(图片由作者提供)
作为另一个极端,我们有一个模型,同样具有 88%的准确性,但我们根本无法定义阈值,因为两个群体最大程度地重叠,如下所示。(这相当于没有对预测置信度的估计!)考虑这个例 3 。

示例 3:准确度为 88%的模型的预测置信度的最坏情况分布。(图片由作者提供)
这三个模型的准确率都是 88%。但是模型的预测能力却大相径庭!
计算置信度阈值
阈值是一个重要的参数,取决于你愿意接受多少假阳性。这真的取决于商业案例。
与通过阅读医生的笔迹来预测药物剂量的商业案例相比,预测图像显示的是猫还是狗的商业案例可能会接受更多的假阳性结果,这需要准确的高置信度预测。
例如,假设我们有一个可以处理 2%误报的业务案例。那么我们的信心阈值是多少,预测的正确率是多少?我们将会看到我们的三个示例模型有着非常不同的结果。
我们定义了与业务案例相关的三个预测群体:
- 误报:高于阈值的高置信度预测,被认为是正确预测,但实际上是错误预测。
- 真阳性:高于阈值的高置信度预测被接受为正确预测,并且确实如此。
- 否定:低于置信阈值的任何预测。这些无论实际上是错是对都会被拒绝。
我们现在通过沿着置信分布图中的 x 轴从 100%向下移动到 0%来计算阈值。我们向下滑动它,直到所有误报的总和是总数的 2%。(这对应于阈值右侧红色曲线下的区域。)
每个模型都有不同的阈值解决方案。在我们的示例中,如果我们允许 2%的假阳性,则示例 1 的阈值约为 75%,示例 2 的阈值约为 35%,示例 3 的阈值无解,因为对于所有预测置信度,假阳性的数量为 12%。
记住,三个模型的准确率都是 88%!
让我们直观地比较一下准确性和预测能力。

示例 1:比较模型准确性和预测能力。(图片由作者提供)
对于示例 1,我们发现 70%的预测具有高于阈值的置信度,并且可以被认为是正确的。我们知道,这不会给系统带来超过 2%的误差。只有 30%的案例需要人工验证。
人类也会犯错误,因此引入系统的总误差分数将大于 2%。
我们可以使用这样的技术来估计模型的预测能力,作为业务指标的函数,因此我们可以计算模型的投资回报。
在这个例子中,以前 100%的工作是人工劳动,现在我们已经减少到 30%。
在理想情况下,作为预测置信度函数的正确和不正确预测的总体不重叠,预测能力实际上接近准确度。

示例 2:比较模型准确性和预测能力。(图片由作者提供)
在这种特殊的情况下,如果我们接受 0%的误报,我们就会得到准确的结果。因此,模型精度是模型能够达到的预测能力的上限。
持续培训
当人工智能被部署时,你希望它及时变得更好。这就是人类反馈数据如此重要的地方:人类纠正错误的预测,提供新标记的数据,这些数据可用于模型的未来训练。该模型已经在高置信度数据上表现良好,因此我们不需要太多的人对这些数据的反馈。
随机挑选一小部分高可信度预测,并人为降低它们的可信度,这样它们就会被人类挑选出来,而不是被自动处理。再加上低置信度的预测,这些预测总是会被人发现,这就确保了我们能得到整个群体的反馈。
持续学习的模型有效地在置信空间中分离正确和不正确预测的群体。这允许您降低阈值并增加可以自动处理的预测的比例。最大值等于模型精度!
随着数据的增加,模型的准确性可能会提高,但事实并非如此。例如,如果你在数据的标注上有 5%的误差,你将永远不会获得优于 95%的准确度。
最终带走
尽管模型准确性对于评估机器学习模型的质量和性能很重要,但对于现实世界的预测人工智能来说,你需要掌握一个预测有多自信。
您可以使用可接受的误差分数(误报)等业务指标来计算模型的预测能力。
如果不理解预测的可信度,你的模型可能是没有价值的,即使它的准确性非常高!
注意:以上分析成功应用于多个神经网络模型读取医生笔迹。你可以在之前的阅读中找到更多关于手写项目 早期版本的信息。
预测性维护— 5 分钟的端到端机器学习项目演示
原文:https://towardsdatascience.com/predictive-maintenance-5minutes-demo-of-an-end-to-end-machine-learning-project-60941f1c9793?source=collection_archive---------37-----------------------
构建机器学习项目的循序渐进和端到端指南

卢卡·斯拉普尼卡在 Unsplash 上拍摄的照片
背景
剩余使用寿命(RUL)是指系统一般工作一段时间后能继续正常运行的剩余寿命时间。借助 RUL,工程师可以安排维护时间、优化运行效率并避免计划外停机。因此,预测 RUL 是预测性维护计划的首要任务。

作者图片
这张照片显示了机器随着时间的推移而退化的情况。如果 A 是当前条件,而 B 是机器将失效的最小可接受条件,剩余使用寿命计算为这两点之间的时间。如果提前估计到 RUL,就可以对其进行维护或更换,以避免计划外停机和经济损失。由于 RUL 的预测对运营和决策具有重要意义,因此对其进行准确的估计至关重要。
今天,我们的任务是通过机器学习模型开发一个用于剩余使用寿命预测的实时智能应用程序。我们使用 NASA 提供的涡扇发动机退化仿真数据集作为训练集和测试集,开发了一个智能预测硬件剩余寿命的应用程序,并完成实时预测。最终的预测结果是 time_ in_ cycle ,这意味着在可接受的条件下,发动机未来可以旋转多少次。
可以直接按照以下步骤操作。后面我们还会附上培训所需的代码。本文主要展示了如何快速完成一个端到端的机器学习应用,省略了数据探索的过程。
使用 docker 提取演示图像
首先,请检查 docker(运行演示的唯一依赖组件)是否安装在您的计算机上。
$ docker pull 4pdosc/openmldb_turbo_rul_demo:0.7.0
运行图像
这里我们选择 bash 命令来运行它
$ docker run -it 4pdosc/openmldb_turbo_rul_demo:0.7.0 bash
切换到相应的目录并初始化环境。
整个初始化过程包括安装 OpenMLDB 和相关的运行环境。关于初始化脚本,请参考 init。上海
$ cd rul && sh init.sh
将历史数据导入到 OpenMLDB
使用 OpenMLDB 进行时间序列特征计算需要历史数据,所以我们将历史数据导入 OpenMLDB 进行实时推理。历史数据可用于特征推断。
- 进口代码请参考 import.py 。
- 使用' t est here_ Fd004。TXT `作为历史数据,有多个发动机循环的检测数据。
$ python3 import.py
训练模型
模型训练需要训练数据。以下是用于生成的代码。
- 训练特征生成脚本代码在 train.p y 中
- 训练数据是
*train_ Fd004。TXT*,有多个发动机循环的检测数据
最后,我们可以生成模型。
$ python3 train.py ./fe.sql /tmp/model.txt
利用训练模型构建实时推理 HTTP 服务
基于上一步生成的训练特征矩阵,我们使用'随机森林回归器进行训练。得到的训练模型,结合 OpenMLDB 中的历史数据,构建实时推理服务,整个推理服务代码引用 predict_ server.py.
$ sh start_predict_server.sh ./fe.sql 9887 /tmp/model.txt
然后我们可以通过 HTTP 请求发送一个推理请求
$ python3 predict.py
最后,可以打印预测结果
----------------ins---------------
1 2 3 4 5 6 7
0 35.0033 0.84 100.0 449.44 0.0 0.0 0.0
---------------predict rul -------------
[321.26]
Congraduation! You have finished the task.
Your Key:b'kSpmZICy0kuTqgAPGC8TMCg/3HmnscIfJrESkOEekOpfcW6+oGnltUf9Vts='
上面的 ins 部分显示了使用 OpenMLDB 计算的特性。这里我们使用的特征被简化了。您可以阅读 fe.sql 文件了解具体特性;
下面的预测 RUL 显示了预测结果 time_ in_ cycle ,这意味着发动机可以继续旋转 321 次。
在一个数据库的帮助下,你可以完成机器学习的端到端应用。是不是很神奇!
如果你想了解更多,你可以点击: OpenMLDB
体系结构

作者图片
预测性维护:机器学习与基于规则的算法
原文:https://towardsdatascience.com/predictive-maintenance-machine-learning-vs-rule-based-algorithms-cb48414df448?source=collection_archive---------21-----------------------
在您的预测性维护项目中,使用机器学习更好还是应该首先使用基于规则的算法?
虽然各种文章中都讨论了基本的预测性维护概念,但在选择预测错误的最佳方法时,实际上很少有发现。在本文中,我们先简要介绍预测性维护,然后重点介绍如何选择最适合您的预测性算法:是使用机器学习模型更好,还是应该首先使用基于规则的算法?

预测性维护——ML vs 基于规则(图片由Isis frana在 Unsplash 上拍摄)
什么是预测性维护?
让我们从理解我们从哪里来开始,它是关于什么的,我们需要一些背景:预测性维护基本上和它一样古老,并且在它的基础上没有什么新的东西。过去,如果机械师维修机器时发现某个部件有异常的视觉或听觉行为,机器可能会在损坏前停机并更换部件。这已经是预测性维护。今天的新事物是,机器和算法可以基于智能算法、更多数据和自动警报来执行这项任务。
(由 NBChttps://media.giphy.com/media/l1ZzUHEoKOnqa2v7Rv/giphy.gif拍摄)
预测性维护很难实现,但潜在的好处远远超过了努力。尽管在许多情况下实际部署比预期花费更多时间和精力的原因有很多(团队专业知识、数据可用性和处理、理解相关性和算法、授权给利益相关方等等),但最终的解决方案将产生:
- 主要由于减少了停机时间,节省了大量成本
- 避免因连接部件导致的相关机械故障
- 降低备件存储成本
- 维护团队可以专注于长期改进,而不是紧急维修
- 额外的好处:将会产生一个宝贵的数据宝藏,可用于所有类型的其他优化任务。
因此,如果您还在犹豫预测性维护对您的组织来说是否是一个好的下一步,那么您不应该浪费更多的时间,最好现在就开始。
选择正确的方法
众所周知,你将把大部分时间花在数据采集、清理和准备上。这是最具挑战性的任务之一,尤其是在传感器数据方面,预计会有大量数据需要适当的大数据环境来相应处理。但在开始所有这些工作之前,您应该考虑如何进行预测,以适应基于规则的方法或机器学习模型的特征工程。

预测性维护—选择正确的方法(图片由作者提供)
当然,我们首先需要知道这两种选择之间的区别,以便能够为您的组织选择最佳方法。让我们从基于规则的预测性维护开始。
基于规则的预测性维护
基于规则的模型非常依赖于你的工程团队的知识和经验。让我在下面解释一下原因:与客户服务反馈一起,质量管理、产品负责人和其他与产品密切相关的团队可以提供关于机器故障原因或哪些特定零件可能会损坏的见解。基于规则的“IF-X-THEN-Y”模型是根据您团队的实践经验和理论知识实施的,以确定某个测量变量是否失控(例如,谢瓦尔特规则、六适马等)。

用于预测性维护的典型传感器数据(图片由作者提供)
一个实际的例子是,生产中的机器的振动传感器长时间高于阈值,并且特定轴承的温度稳定增加。这将触发通知或发送警报,以便问题可以提前解决,工程师需要知道在哪里查看。
机器学习预测维护
实现一个预测性的机器学习模型你的团队的领域知识仍然是不可避免的,特别是当涉及到特征工程时,但是没有必要定义与我们在基于规则的预测模型中看到的相反的特定规则。
要符合机器学习模型,输入和输出都是必需的。在这种情况下,所谓的输入是我们的独立变量,特征或者随便你怎么称呼它。例如,在预测性维护中,这通常是温度或振动传感器的实际数量。当然这真的取决于你去计算新的独立变量。这个过程被称为特征工程,它本身就是一个主题。

标准的机器学习过程(图片由作者提供)
一旦你有了你的独立变量,你需要添加你想要的结果,之前称之为输出。预测性维护中的因变量通常是零件故障的警报或警告。然后,在创建的训练集的帮助下训练机器学习模型,以预测即将出现的错误。
请注意,有大量不同的机器学习模型,我们将在未来的文章中探索它们,因为现在的主要焦点是基于区分规则与机器学习模型。
结论——现在选择哪种方法?
有这样的情况,组织试图提出最先进的机器学习模型,而不事先做好基础工作。因此,问问你自己,你是否有足够的经验、技术知识和数据基础设施来实现一种胜过基于规则的系统的机器学习算法。
如果答案是否定的,并且您正准备开始处理整个数据问题,还不确定数据环境,并且希望收集初步经验,我强烈建议您首先从基于规则的模型开始,然后随着时间的推移,它可以发展为高级机器学习算法。
与此相关的文章:
动手:预测客户流失
应用机器学习提高初创公司估值
动手:客户细分
数据误导&统计
什么是 landingdata.de ?
提督:如何用 Python 编写和调度你的第一个 ETL 管道
原文:https://towardsdatascience.com/prefect-how-to-write-and-schedule-your-first-etl-pipeline-with-python-54005a34f10b?source=collection_archive---------2-----------------------
实践教程
工作流管理系统变得简单——在本地和云中

照片由 海伦娜从 洛佩斯 删节
Prefect 是一个基于 Python 的工作流管理系统,它基于一个简单的前提——您的代码可能会工作,但有时会不工作 ( 来源)。当一切都按预期运行时,没有人会考虑工作流系统。但是当事情变糟时,提督会保证你的代码成功失败。
作为一个工作流管理系统,Prefect 可以轻松地将日志记录、重试、动态映射、缓存、失败通知等添加到您的数据管道中。当你不需要它时,它是看不见的——当一切都按预期运行时,当你需要它时,它是看得见的。类似保险的东西。
虽然 Prefect 不是 Python 用户唯一可用的工作流管理系统,但它无疑是最熟练的一个。诸如 Apache Airflow 这样的替代方案通常工作得很好,但是在处理大型项目时会带来很多令人头疼的问题。你可以在这里阅读 Prefect 和 Airflow 的详细对比。
本文涵盖了库的基础知识,比如任务、流、参数、失败和时间表,还解释了如何在本地和云中设置环境。我们将使用土星云作为那部分,因为它使配置毫不费力。它是一个由数据科学家制作的云平台,因此大部分繁重的工作都是为您完成的。
土星云可以毫不费力地处理完美的工作流程。它也是从仪表板到分布式机器学习、深度学习和 GPU 培训的前沿解决方案。
今天,您将学习如何:
- 在本地安装提督
- 用 Python 写一个简单的 ETL 管道
- 使用提督来声明任务、流程、参数、时间表和处理故障
- 在土星云中跑完全程
如何在本地安装提督
我们将在虚拟环境中安装完美的库。基于 Python 3.8,以下命令将通过 Anaconda 创建并激活名为prefect_env的环境:
conda create — name prefect_env python=3.8
conda activate prefect_env
您必须输入几次y来指示 Anaconda 继续,但是每个安装都是如此。就库而言,我们将需要 Pandas 进行数据操作,请求下载数据,当然还有perfect进行工作流管理:
conda install requests pandas
conda install -c conda-forge prefect
我们现在已经具备了开始编写 Python 代码所需的一切。让我们接下来做那件事。
用 Python 编写 ETL 管道
今天我们将使用 Prefect 来完成一个相对简单的任务——运行 ETL 管道。这个管道将从一个伪 API 下载数据,对其进行转换,并将其保存为 CSV 格式。JSON 占位符网站将作为我们的虚拟 API。其中,它包含了十个用户的虚假数据:

图片 1——伪造的用户数据(来源:【https://jsonplaceholder.typicode.com/users ))(图片作者)
让我们从创建一个 Python 文件开始——我已经将我的文件命名为01_etl_pipeline.py。此外,确保有一个文件夹,用于保存提取和转换的数据。我称之为data,它位于 Python 脚本所在的位置。
任何 ETL 管道都需要实现三个功能——提取、转换和加载数据。在我们的例子中,这些函数的作用如下:
extract(url: str) -> dict—向url参数发出获取请求。测试以查看是否返回了一些数据—在这种情况下,它作为字典返回。否则,将引发异常。transform(data: dict) -> pd.DataFrame—转换数据,以便只保留特定的属性:ID、姓名、用户名、电子邮件、地址、电话号码和公司。以熊猫数据帧的形式返回转换后的数据。load(data: pd.DataFrame, path: str) -> None—在path将之前转换的data保存为 CSV 文件。我们还将在文件名后附加一个时间戳,这样文件就不会被覆盖。
在函数声明之后,当执行 Python 脚本时,这三个函数都会被调用。以下是完整的代码片段:
现在,您可以通过从终端执行以下命令来运行该脚本:
python 01_etl_pipeline.py
如果一切运行正常,您应该看不到任何输出。但是,您应该在data文件夹中看到 CSV 文件(我已经运行了该文件两次):

图 2 —运行两次 ETL 管道后,数据文件夹中的 CSV 文件列表(图片由作者提供)
正如您所看到的,ETL 管道运行并完成,没有任何错误。但是,如果您想按计划运行管道,该怎么办呢?这就是提督的用武之地。
探索提督的基础
在这一部分中,您将学习perfect任务、流程、参数、时间表等更多的基础知识。
完美的任务
让我们从最简单的开始——任务。这基本上是你工作流程中的一个步骤。接下来,创建一个名为02_task_conversion.py的新 Python 文件。从01_etl_pipeline.py复制一切,你就可以开始了。
要将 Python 函数转换成完美的任务,首先需要进行必要的导入— from prefect import task,并修饰任何感兴趣的函数。这里有一个例子:
@task
def my_function():
pass
这就是你要做的!下面是我们 ETL 管道的更新版本:
让我们运行它,看看会发生什么:
python 02_task_conversion.py

图 3 —用提督将功能转换为任务(图片由作者提供)
看起来好像有什么不对劲。那是因为提督任务离不开提督流程。接下来就来实现吧。
完美流程
将02_task_conversion.py中的所有内容复制到一个新文件——03_flow.py。在声明之前,您需要从prefect库中导入Flow。
为了声明一个流,我们将编写另一个 Python 函数— prefect_flow()。它不会接受任何参数,也不会用任何东西修饰。在函数内部,我们将使用 Python 的上下文管理器来创建一个流。该流应该包含之前在if __name__ == ‘__main__”代码块中的三行代码。
在上面提到的块中,我们现在必须用相应的run()函数运行流程。
以下是该文件的完整代码:
让我们运行它,看看会发生什么:
python 03_flow.py

图片 4——第一次运行提督流(图片由作者提供)
这下好了!不仅执行了 ETL 管道,而且我们还获得了每个任务开始和结束的详细信息。我已经运行了这个文件两次,所以两个新的 CSV 文件应该会保存到data文件夹中。让我们验证一下事实是否如此:

图片 5 —提督流生成的 CSV 文件(图片由作者提供)
这就是你如何用 Prefect 运行一个简单的 ETL 管道。与纯 Python 实现相比,它还没有太多好处,但我们会很快改变这一点。
完美的参数
硬编码参数值从来都不是一个好主意。这就是完美参数的用武之地。首先,将所有内容从03_flow.py复制到一个新文件04_parameters.py。你需要从prefect包中导入Parameter类。
您可以在流上下文管理器中使用这个类。以下是你会发现有用的论点:
name—参数的名称,稍后将在运行流程时使用。required—布尔值,指定该参数是否是流程执行所必需的。default-指定参数的默认值。
我们将为 API URL 声明一个参数— param_url = Parameter(name=’p_url’, required=True)。
为了给参数赋值,您需要指定parameters字典作为run()函数的参数。参数名和值应该写成键值对。
以下是该文件的完整代码:
让我们运行该文件,看看会发生什么:
python 04_parameters.py

图片 6 —运行包含参数的完美流程(图片由作者提供)
我已经运行了这个文件两次,所以两个新的 CSV 文件应该出现在data文件夹中。让我们验证一下这是不是真的:

图 7 —包含参数的提督流生成的 CSV 文件(图片由作者提供)
这就是你要的——一个地方的参数值规范。它使得以后进行更改和管理更复杂的工作流变得容易。
接下来,我们将探索 Prefect 的一个特别有用的特性——时间表。
完美的时间表
今天我们将探讨两种任务调度方式——间隔调度和 Cron 调度。第二个可能听起来很熟悉,因为 Cron 是一种众所周知的在 Unix 上调度任务的方法。
我们将从间隔调度器开始。首先,复制从04_intervals.py到05_interval_scheduler.py的所有内容。你必须从prefect.schedules导入IntervalScheduler。
然后,我们将在prefect_flow()函数声明之前创建一个导入类的实例,并指示它每十秒钟运行一次。这可以通过设置interval参数的值来实现。
要将调度程序连接到工作流,您必须在使用上下文管理器初始化Flow类时指定schedule参数的值。
整个脚本文件应该如下所示:
让我们运行该文件,看看会发生什么:
python 05_interval_scheduler.py

图片 8 —使用间隔时间表(图片由作者提供)
如您所见,整个 ETL 管道运行了两次。提督将向终端报告下一次执行的时间。
现在,让我们探索一下 Cron 调度器。复制从05_interval_scheduler.py到06_cron_scheduler.py的所有内容。这次你将导入CronSchedule而不是IntervalSchedule。
在类初始化时,您将为cron参数指定一个 cron 模式。五星符号将确保工作流程每分钟都在运行。这是 Cron 可能的最低间隔。
文件的其余部分保持不变。代码如下:
让我们运行该文件:
python 06_cron_scheduler.py

图片 9 —使用 Cron 计划(图片由作者提供)
正如您所看到的,ETL 管道每一分钟运行两次,这是由 Cron 模式指定的。在这一部分的最后,我们将探索如何处理失败——并解释为什么你应该总是为它做准备。
完美的失败
迟早,你的工作流程中会发生意外的错误。Prefect 提供了一种极其简单的方式来重试任务的执行。首先,将所有内容从04_parameters.py复制到一个新文件07_failures.py。
extract()功能可能因不同的网络原因而失败。例如,也许 API 现在不可用,但几秒钟后就会可用。这些事情发生在生产环境中,不应该使您的应用程序完全崩溃。
为了避免不必要的崩溃,我们可以扩展一下我们的task装饰器。它可以接受不同的参数,今天我们将使用max_retries和retry_delay。两者都是不言自明的,我就不赘述了。
唯一的问题是——我们的工作流程不会像现在这样失败。但是如果我们将一个不存在的 URL 作为参数值放在flow.run()中,它就会。代码如下:
让我们运行该文件:
python 07_failures.py

图片 10——与提督一起预防故障(图片由作者提供)
任务失败,但工作流没有崩溃。当然,它会在十次重试后崩溃,但您可以随时更改参数规范。
这也是我和地方长官一起工作的原因。接下来,让我们将代码迁移到云中,并探索其中的变化。
在土星云中奔跑
让我们马上把手弄脏。首先,注册一个免费版的提督云账号。注册过程非常简单,无需进一步解释。注册后,创建一个项目。我给我的取名为SaturnCloudDemo。
在进入土星云之前,你必须在 Prefect 中创建一个 API 键来连接两者。你会在设置下找到 API 键选项。如您所见,我已经将我的命名为SaturnDemoKey:

图片 11 —提督云 API 密钥创建(图片由作者提供)
你现在已经有了所有需要的东西,所以去土星云创建一个免费账户。在仪表板上,您将看到项目创建的多个选项。选择提督选项,如下图所示:

图片 12——在土星云中创建一个完美的项目(图片由作者提供)
Saturn Cloud 现在将自动为您完成所有繁重的工作,几分钟后,您将能够通过单击按钮打开 JupyterLab 实例:

图 13——土星云中打开的木星实验室(图片由作者提供)
你可以使用两个笔记本——第二个展示了在土星云中使用 Prefect 的快速演示。它看起来是这样的:

图片 14——土星云中的完美云笔记本(图片由作者提供)
要让笔记本工作,您只需更改两件事情。首先,将项目名称更改为您在 Prefect Cloud 中的项目名称。其次,用几分钟前生成的 API 密匙替换<your_api_key_here>。如果您做的一切都正确,您应该会看到以下消息:

图片 15——土星云中登录成功的消息(图片由作者提供)
要进行测试,请运行笔记本中的每个单元格。然后转到完美云仪表板,打开你的项目。它不会像几分钟前那样空无一人:

图片 16 —成功的提督任务调度(图片由作者提供)
这就是你要做的一切!请随意复制/粘贴我们的 ETL 管道,并验证它是否工作。这就是 Saturn Cloud 的亮点——您可以从本地机器上复制/粘贴代码,只需做最小的更改,因为所有繁琐的工作都是自动配置的。
让我们在下一部分总结一下。
最后的想法
现在你有了它 Prefect 的基础解释,包括本地和云。我希望您能够看到工作流管理系统对于生产应用程序的价值,即使您在阅读本文之前对这个主题一无所知。
有关更高级的指南,即配置日志记录和空闲通知,请参考官方文档。提供的例子足以让你开始。
喜欢这篇文章吗?成为 中等会员 继续无限制学习。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。
https://medium.com/@radecicdario/membership
保持联系
- 在媒体上关注我,了解更多类似的故事
- 注册我的简讯
- 在 LinkedIn 上连接
为数据科学面试准备行为问题
原文:https://towardsdatascience.com/prepare-behavioral-questions-for-data-science-interviews-96e97f13be15?source=collection_archive---------5-----------------------

Clem Onojeghuo 在 Unsplash 拍摄的照片
办公时间
自信地完成数据科学面试,第 5 部分
我在之前关于数据科学面试准备的文章中已经列出了机器学习、统计学、概率论中需要练习的技术问题。我还讨论了可用于在数据科学面试之前和期间准备案例研究问题的策略。本文是数据科学面试准备系列的第五篇文章,将重点讨论行为问题。我将首先讨论如何准备行为回合,然后列出一些常见问题供您练习技巧。
我最喜欢面试过程中的行为环节,因为与其他技术环节相比,它相当放松。在我知道任何回答行为问题的策略之前,我总是觉得我在和某人聊天,谈论我在这一轮中的有趣经历。虽然在面试中拥有一个不那么紧张的心态是件好事,但是过度放松的心态可能不会帮你给面试官留下好印象。结果我说了太多细节,失去了证明我拥有面试官想要的东西的机会。请记住,即使你大部分时间都在和面试官聊天,你仍然会通过这一轮的谈话得到评估。如果你能借此机会向面试官展示,根据你的经验和个性,你是这个职位的最佳人选,那就最好了。没有坚实的例子和既定的结构,你就无法有效地表达自己,我将在本文中讨论这一点。
第一部分。收集实例
你回答行为问题的内容是基础。在面试过程中,为了保持对话流畅,你很少有时间去想一个完美的例子来回答这个问题。因此,在准备面试时,我们应该从收集所有“有用”的经验开始,并根据它们可以用来回答什么类型的问题进行分类。这样,你就知道你总会有话题可谈,并且有合适的例子来支持你的论点。在这一节中,我将讨论收集可靠示例的过程。
列出你的清单
你应该用什么例子来回答行为问题?想想你过去有过的工作和学习经历,分门别类。
当我准备行为问题时,我用下表来头脑风暴我的经历。虽然提问的方式有上百万种,但我们可以将其归纳为以下八类。你遇到过哪些挑战?你如何安排工作的优先次序?有哪些你想分享的成就?有哪些展现你领导能力的例子?你们什么时候有过矛盾,怎么处理的?你犯过哪些错误?你如何适应一个新的环境,你如何融入?

类别清单
对于每个类别,搜索你的记忆,准备至少一个例子来分享。如果你有一个以上的每个类别的例子,太好了!把它们都写下来,在不同的方面进行强调。例如,对于显示你的成就的同一类别,你可能会发现一个例子强调你的自学技能,另一个例子显示你是一个团队成员。都是面试官可能会寻找的优秀品质。将它们全部收集起来,并学习如何在面试中根据问题的背景来优先考虑要分享的内容。
区分例子的优先顺序
如果你有几个你征服过的挑战,你应该选择哪一个来回答一个特定的问题?我建议您遵循这些原则来排列示例的优先级:
- 优先考虑影响较大的例子:影响是关键。它展示了你的工作成果,证明你有资格申请。当你说我为我的项目建立了一个新的模型,人们可能会想知道为什么,直到你提到这个模型增加了 x%的客户保持率。
- 优先考虑相关的例子:这里的相关性有几个方面。首先,基于问题的语境是没有疑问的,问题怎么问,答案可能不一样。因此,积极倾听在面试中非常重要。虽然你可能已经准备了一个很好的演讲,但如果与问题无关,你应该随时调整你的答案。此外,如果你申请工作岗位,与工作相关的例子与学校项目更相关。
- 优先考虑最近的例子:讨论最近发生的例子比讨论很久以前发生的事情更好。例如,你可以讨论你在最近职位上的经历。如果你有工作经验,当被问到领导技能时,你仍然使用学校的例子,面试官可能会怀疑你是否能够在工作中实践你的技能。这将发出一个不好的信号。
研究公司核心价值观和职位描述
基于你所谈论的经历,面试官希望从你身上找到一些关键特征。一般来说,这些特征是:
- 优秀的沟通者
- 自信与谦逊
- 积极进取
- 遵守规则和协议的能力
- 独立自主
- 与他人合作愉快
- 问题求解程序
- 对角色和公司的承诺
- 领导素质
- 公司的正面代表
你使用的例子应该向面试官展示你拥有他们所寻找的关键特征。此外,每个公司都有自己的核心价值观,这些价值观会优先考虑某些品质。你应该很容易在网上找到核心价值观,或者从工作描述中总结出来。在准备例子的时候,记住所有的核心价值观,试着在你的答案中融入它们并区分它们的优先次序。
充分利用每个例子
在回答一个关于解决冲突的问题时,除了展示你解决问题的技巧,你还可以展示你优秀的沟通技巧和领导主动性。因此,我建议也为你所有的代表性例子制作下表:

首先总结一下这个例子的量化影响。然后,尝试分析该示例,并勾选标记该示例有助于演示的类别。你可以用一句话总结一下你在这个例子中完成的任务,展示你在这个类别中的素质。
如果你以前有工作经验,你可以很容易地找到大量的例子,当你全职工作,兼职,或在实习期间。对于新毕业生来说,学术经验也可以被视为工作经验,只要有合适的例子。你可以谈论你从事的一个个人研究项目;你如何与顾问合作,顾问就像是工作中的监督者;你是如何和其他研究生一起工作的,他们就像工作中的同事一样。如果你曾经做过助教,即使这份工作本身可能与你现在申请的职位无关,你仍然可以谈论一些展示你沟通和领导能力的经历。
要诚实
不要编造任何例子! 不要冒充自己不是的人。找到工作不是故事的结束,而是一个开始的篇章。你不想给你未来的同事或老板留下错误的印象,在未来的每一天你都必须表现得像另一个人。与其编造例子,不如试着思考你的经历,挖掘细节。当我寻找我的第一份全职工作时,我很难向一些面试官证明我的工作能力。我非常强调我在创业公司的实习经历,尤其是我和我的主管以及来自不同团队的同事一起工作的时候。这段经历给了我很多例子来证明我的沟通和领导能力,并向面试官展示我能在快节奏的工作环境中表现出色。这也是为什么我们需要深入并充分利用我们上面讨论的所有例子。
第二部分。建立并练习结构
你的答案应该总是有条理的。否则,你会很容易发现自己长时间无目的地说话,或者喃喃自语不必要的细节。你没有赶上朋友,你需要深入你经历的每一个细节。你也没有写一部惊悚片,你需要你的读者努力思考,并试图给他们惊喜。面试时,你的回答应该直接、简洁、清晰。
遵循星型结构
星星代表状况、要求、结果。这是一个可靠的方法来组织你的答案。

作者绘图
你可以通过简单描述你所处的情况或者你需要完成的任务来开始你的回答。然后谈论你必须完成的任务。之后,列出你完成任务所采取的行动。最后,总结你行动的结果。比如发生了什么?事件是如何结束的?你完成了什么?你学到了什么?请注意:
- 你可以用结果来描述情况。例如,你可以以“我想分享我建立一个将客户流失率降低 x%的模型的时间”开始你的回答。
- 你选择的任务应该是具体的,而不是笼统的或者假设的。
- 重点描述你的任务和行动,即使是一个团队项目。如果你需要提及他人的任务,强调沟通和协作技巧。
- 如果能量化结果,总会更让人印象深刻。
更多细节和例子,参考这篇文章和许多其他在线文章,帮助你练习这个结构。
关注影响而非过程
我再怎么强调展示你的作品的影响力也不为过。你如何做到这一点很重要,但这不是重点,因为你不是在参加知识共享会议。你应该专注于你做了什么,特别是有什么结果。量化对公司关键 KPI 的影响会给面试官留下更深刻的印象。
细节留待后续提问
一开始不要深究细节,尤其是技术细节。保持你的答案清晰,直奔主题。对示例进行高水平的介绍,首先关注影响和结果。如果面试官很好奇你是如何取得结果的,他们会问一些后续问题,那么你可以谈得更详细一些。如前所述,对你知道的和不知道的要诚实。如果你假装做过某事或知道某事的细节,面试官可能会问后续问题,发现你在撒谎。这是一个可怕的信号。
第三部分。练习常见问题
现在,您已经有了一些例子,并且知道了要使用的正确结构,请练习以下问题:
- 告诉我一次你被要求做你以前从未做过的事情?你学到了什么?
- 告诉我你同时参与多个项目的时候。你是如何安排时间的?结果如何?
- 告诉我你工作中某件重要的事情没有按计划进行的时候。你的角色是什么?结果如何?你从经历中学到了什么?
- 告诉我你不得不与难以相处的人一起工作的时候。你如何处理与那个人的互动?
- 告诉我一个当问题出现时你的主管不在的时候。你是如何处理这种情况的?你和谁商量了?
最后的话
还有很多其他的问题你可以在网上找来练习。当我说练习时,我的意思不是让你写下答案并通读一遍,希望在面试中得到完全相同的问题。而是用既定的结构来练习答题。此外,在镜子前或与同伴练习,这样你会得到一些反馈。请记住,在面试过程中,你不是在演讲,而是在和别人交谈。因此,积极倾听,同时留意他人的反应非常重要。我知道虚拟面试可能更具挑战性,我这里有一篇文章可以帮助你更好地准备虚拟面试。我们的目标是进行一次精彩的对话,这样你就可以专注于回答问题,而不是提供“完美的答案”。
这就是本文的全部内容。感谢您的阅读。这是我所有博客帖子的列表。如果你感兴趣的话,可以去看看!
https://zzhu17.medium.com/my-blog-posts-gallery-ac6e01fe5cc3 https://zzhu17.medium.com/membership
使用 Amazon SageMaker Data Wrangler 这款可视化和数据准备工具,以最快、最简单的方式为您的 ML 模型准备数据
原文:https://towardsdatascience.com/prepare-data-for-your-ml-models-in-the-fastest-and-easiest-way-with-amazon-sagemaker-data-wrangler-186aaa71e7d9?source=collection_archive---------29-----------------------
使用 SageMaker Data Wrangler 对数据进行预处理和可视化的分步指南
摘要
亚马逊 SageMaker Data Wrangler 是 2020 年 12 月宣布的一项新服务,旨在简化机器学习的数据准备和特征工程过程。您可以使用该工具的可视化界面来构建预处理和可视化管道(或称之为流程)。准备就绪后,导出您的代码流并在任何地方运行!它还集成了其他 SageMaker (SM)服务(如 SM 管道和 SM 功能商店 )
。在这篇文章中,我们将通过使用一个样本数据集构建一个数据牧马人 流来介绍这一新服务的功能。我们将在 Data Wrangler 环境中导入我们的数据,并探索其数据处理和可视化能力。最后,我们将看到我们的工作如何运作。这篇文章的目的是探索这种新的 SageMaker 产品的可能性,并展示如何以简单、快速和可重复的方式为机器学习任务准备数据。
先决条件
如果你打算继续下去,有几样东西你需要拿到手。即使你没有,你仍然可以阅读这篇文章,自己决定这个工具是否适合你。
Data Wrangler 是 SageMaker Studio 的一部分,sage maker Studio 是基于云的 IDE。因此,您需要访问 SM Studio 和 Data Wrangler。如果您是第一次从您的帐户使用 SageMaker,那么免费层将涵盖您的费用,因为它包括前两个月每月 25 小时的 Data Wrangler 使用。但是,请注意,如果您不属于这一类别,将会产生一些费用。
在这两种情况下,一定要坚持到这篇文章的结尾,看看如何清理使用的资源,并确保不会留下任何运行的东西,这会在月底引起令人惊讶的账单。
您还需要使用现有的或新的 S3 铲斗。
资料组
我们将使用众所周知的葡萄酒质量数据集,你可以在这里找到并下载。本质上,这是一个回归问题,我们试图根据一些已知的特征(物理化学测试)来预测葡萄酒的质量分数(感官数据)。
以上链接中的数据由两个数据集组成,白葡萄酒和红葡萄酒各一个。
设置
在我们深入 SageMaker 世界之前,请确保下载数据并进行以下处理。截至本文撰写之时,如果数据是 CSV 格式的,Data Wrangler 可以直接从 S3 加载数据(它也支持从 Redshift 或通过使用 Amazon Athena 加载数据,但这超出了本文的范围)。
我们拥有的数据集实际上是分号分隔的值,而不是逗号分隔的值。因此,您需要打开您选择的文本编辑器并替换“;”带“,”。
或者,如果您喜欢命令行,并且在基于 Unix 的系统上,您可以从命令行快速完成此操作:
sed ‘s/;/,/g’ winequality-white.csv > winequality-white-converted.csv
sed ‘s/;/,/g’ winequality-red.csv > winequality-red-converted.csv
下一步,将这些文件上传到 s3 存储桶。不管它是新的还是现有的存储桶,只要您有权限将数据上传到那里并检索它们。
首先,打开 SageMaker Studio,因为这是我们访问 Data Wrangler 图形用户界面(GUI)的方式。如果你以前没有这样做过,打开 AWS 控制台,搜索“sagemaker”并打开 Studio。如果你想了解更多关于 Studio 的信息,请看这里。

步骤 1 —创建新的流并导入数据
SageMaker studio 启动并运行后,点击进入 Data Wrangler 菜单后出现的“新流程”,创建新的 Data Wrangler 流程,如下所示。

一旦完成,就该导入数据了。在 import 选项卡上,单击 s3 并导航到包含数据的 s3 文件。

请注意,您将能够一次导入一个数据集,因此您需要这样做两次,因为我们的数据在两个文件中。再次点击“导入”标签,出现如上页面,再次点击从亚马逊 S3 导入。
步骤 2 —将数据连接在一起
在同一个窗口中,转到选项卡准备应该如下所示。如果没有,请再次检查您是否遵循了说明。

现在,我们将在这里构建我们的处理流程!第一步是将我们的数据集连接起来。
点击“+”图标,显示我们可以采取/添加到流程中的行动。
在我们现在的例子中,我们将选择连接。
单击连接后,您需要单击要连接的数据集。单击另一个数据集。然后点击配置获得更多选项。
在这里,我们选择新数据集的名称,以及我们是否想要添加一列来指示任何特定行来自哪个文件。

步骤 3 —转换数据
Data Wrangler 的好处之一是收集了可用的转换,您可以对数据进行开箱即用。但是如果这还不够,您还可以添加自定义转换。
我们将再次按下“+”图标,这次是新创建的葡萄酒质量框旁边的那个图标(代表新数据集)。从下拉菜单中选择“添加转换”。
在右边你会看到一个支持的转换列表。随意探索和试验你喜欢的。
为了向您展示它是如何工作的,让我们选择处理数字→保持变换&缩放器不变→选择一列(如糖残留)→点击缩放&中心→预览&添加

让我向您展示如何添加自定义计算。
点击自定义转换,选择您将使用的底层框架并键入您的代码。就这么简单。
目前你的选择是使用 Python 和 Pandas,Python 和 PySpark,或者在 PySpark SQL 上使用 SQL。
那么,让我们创建一个新的特性。我将使用 python-pandas 代码创建它:
*df[‘leakyFeature’] = df[‘quality’] * 2*
如果你正在注意,你可能会从椅子上跳起来,对我大喊这毫无意义。请耐心听我说,一会儿我想给你看些有趣的东西。现在,这展示了如何使用定制代码来添加您自己的、独特的转换。

步骤 4 —可视化数据
构建处理流程不可或缺的一部分是理解您的数据,而帮助您理解数据的最佳方式之一就是将数据可视化。Data Wrangler 也可以帮助您做到这一点。
让我们回到主准备页面,再次点击“+”图标。这次选择“添加分析”。
这将带您进入一个菜单,您可以从可用图形类型列表中进行选择。你可以随意探索,但是现在,让我们选择做一个散点图。我想看看残糖与总二氧化硫按酒型分解的关系。
选择预览以生成绘图,如果你想保留它,点击创建。

这样做又快又省事。使用这些图表,我们现在可以探索数据集,更好地理解我们的数据之间的关系,并且我们可以选择保留我们希望在未来重新创建的分析步骤,或者删除没有信息的步骤。
谈到这种分析功能,您可以做几个重要的分析,这可以极大地帮助您为即将到来的机器学习建模阶段准备数据。
首先让我们来看看泄漏检测。这个分析试图告知我们潜在的 目标泄露 。这就是目标变量的信息似乎通过另一个特征泄漏的时候。在现实生活中,这可能发生在我们使用一个可能是目标变量的子产品,但实际上在推理时不可用的特征的情况下。这正是我们之前创建“泄漏特征”的原因。来模拟这样的场景。这听起来不太可能发生,但它确实发生了,你需要做好准备并留意它。让我们看看我们如何能做它。
我们创建一个新的分析,这次选择“TargetLeakage”作为分析类型。选择适当的问题类型和目标变量(对我们来说是“质量”)。点击预览,等待几秒钟。

如您所见,它能够检测到由于特性“ leakyFeature ”(如预期的那样)而导致的信息泄漏,因此现在我们可以添加一个步骤来从我们的数据集中删除该列。
请注意,在这一步,数据科学家负责进一步调查某个特征是否确实在泄露信息。可能存在这样的情况,即某个特征非常具有预测性,并且实际上将在推断时间期间可用。机器和算法变得越来越智能,但仍然需要数据科学家来做出这样的决定。
要删除该列,像以前一样添加一个转换,并选择 Manage columns 来删除列 leakyFeature (当然,您可以一开始就不创建它,但这只是一个例子)
我想向您展示的最后一个分析功能是 快速模型 。
这是一个非常方便的特性,在引擎盖下训练一个模型(一个随机的森林)并报告性能和特性重要性。这不是用来作为预测的模型,而是作为一个指示,你可以期望模型工作的多好,也给你什么样的特性会更重要的见解。有了这些信息,你可以决定回到绘图板,考虑你的特征工程,节省你的时间,让你更快地迭代特征工程。如果你有兴趣了解更多关于快速模型是如何工作的,我鼓励你阅读更多关于文档的内容。我需要强调的一点是。快速模型将尝试自动猜测我们要解决的问题类型(分类或回归)。方法是通过查看目标变量来推断。如果它有超过 100 个不同的值,那么它假设这是一个回归问题,如果它没有那么它是分类。在我们的例子中,我们只有 10 个不同的值,所以这将被理解为一个分类问题。
下一步完全是可选的————
有人可能会说,我们可以把这个问题作为一个分类问题来处理,但我想把它变成一个回归问题。怎么会?你还记得我们之前做的自定义计算吗?让我们利用这一点。
让我们创建一个自定义计算,这次添加以下 python 代码:
*import numpy as np*
*df[‘quality’] = df[‘quality’] + 0.1 * np.random.random(size=(df.shape[0]))*
这是在做什么?这给我们的目标变量增加了一些低量级的随机噪声。这不会影响任何分析的质量,但会使 data wrangler 将我们的问题视为回归
注意:如果您尝试以下两种回归和分类方法,您会发现特征重要性基本相同。
完全可选步骤结束———
要运行快速模型分析你需要添加分析,选择快速模型然后选择目标变量是什么。点击预览,等待几秒钟,看看结果。

正如你所看到的,快速建模非常快速和容易使用,可以给我们一些很好的见解,哪些功能可能在建模阶段更有用。
步骤 5 —导出您的作品
到目前为止,这很好,但是我听到你问我们如何通过点击来操作我们创建的流程。
是时候将我们的工作以一种更易于操作的格式导出了。
Data Wrangler 提供了几种不同的方法来导出您的流量。简而言之,这些选项如下。
- 用 python 代码导出:您可以将您的流导出到 python 文件中。然后,您可以获取这个 python 文件,并在您需要的任何地方以任何方式运行它。你甚至可以编辑文件,添加你定制的额外步骤或改变一些东西。
- 导出为 Data Wrangler 作业:这将生成一个笔记本,在运行时,它将加载您的流文件并将其作为 SageMaker 处理作业执行。
- 导出为要素存储:这与上述方法类似,但也会在要素存储中创建和接收数据。如果您正在创建希望团队中的其他成员或未来的自己能够访问的功能,并且您认为 SageMaker 功能商店是适合您这样做的服务,那么这将非常方便。
- Export as Pipeline:这将创建一个笔记本,它定义一个 SageMaker 管道,其中一个处理步骤是流的执行。如果您希望使用 SageMaker Pipelines 来操作您正在进行的整个 ML 项目,这将是理想的,因为 Pipelines 是 ML 领域 AWS 的 CI/CD 工具。
无论如何,让我们看看我们能做什么。
我们单击顶部的导出选项卡,我们单击我们流程的步骤,然后单击“导出步骤”。

正如您所看到的,生成的 python 文件相当长,但是不用担心,大部分都是转换的函数定义。滚动到底部,您将清楚地看到我们在流程中采取的所有步骤现在都是通过代码完成的。
总结
综上所述,我们已经快速地做了相当多的工作,而且几乎没有编写任何代码。
我们首先将数据集组合在一起,创建并转换特征,可视化我们的数据,并了解哪些特征在建模过程中更有用,这样我们甚至不用离开我们正在使用的工具就可以重复特征工程阶段。最后,我们看到,这种互动和可视化流程可以很容易地导出为各种格式,这取决于我们的运营需求。
你现在已经准备好试验你自己的数据并创建你自己的流了。请在下面的评论中告诉我你的成功或者你在这个过程中遇到的任何挫折。
清理
如果你一直在跟踪,那么在你关闭浏览器窗口之前,不要忘记关闭我们一直在使用的 Data Wrangler 服务器,否则你将会产生意想不到的费用。
首先确保保存您的 Data Wrangler 流,如果您想保留它,然后关闭实例,如下图所示。

现在去享受一杯茶或咖啡吧。这是你应得的!
为数据科学工作准备你的简历
原文:https://towardsdatascience.com/prepare-your-cv-for-a-data-science-job-7b8a4515c17b?source=collection_archive---------29-----------------------
在数据科学工作的筛选过程中获得可见性

来自的图像未绘制
我最近负责招聘流程,将一名新的数据科学家成员纳入我们的团队。我们发布了职位描述,仅仅 3 天之后,我们就收到了 70 多份申请。太神奇了!
然而,所有这些申请都必须经过筛选,因为只有一个职位空缺。我想和你分享一些我第一次面临的挑战,以及一些你可以用来充实你的简历的技巧。开始吧!
作为一个背景说明,不是所有的公司都以同样的方式工作,招聘过程将取决于招聘人员和招聘经理。
招聘团队可能会根据招聘经理描述的他们想要的东西进行第一次筛选。但是也有可能招聘经理会先做一个快速的筛选来挑选候选人。请注意,招聘经理将是你的上司。
反正两个人时间都很有限。招聘经理仍然要参加会议,开发项目,管理和指导团队。招聘人员可能还负责另一批申请。这就是为什么你的简历给人留下好印象是非常重要的。
在我第一次访问候选人库(+70 份简历)时,我意识到:
- 设计和简洁的简历非常重要。我没有时间阅读 5 页的课程,也没有时间阅读结构不合理的简历。
- 使用的数据科学技能和工具必须一目了然且易于捕捉。
- 一些简历有很多与申请工作不相关的经验,例如,要求 NLP 经验或深度学习,但在经验或关键词中一次也没有显示。
- 应使用普通过滤器。我必须对所有候选人应用一个共同的最小阈值来过滤掉他们。
- 我不能完整地阅读所有的简历。长简历将被直接删除,除非它们在开头有一个摘要,让我了解相关信息。
在查看了一些课程后,我可以将申请分为:
- 好的。不到 2 页,所有我想检查的东西都在第一页。最好只有一页。易于理解的 ML 技能与类别和经验水平。
- 长但结构良好。简历很长,但是仍然很容易阅读,并且在第一页有一个摘要。大概是这个人总结的不太好,想把什么都加上,以防对获得工作有帮助,或者他/她有太多的经验和项目。
- 长而不可追。我注意到多个申请者都有相同类型的 5 页加简历。它们很长,没有页边空白,没有类别或结构来理解你所读的内容。
之后,根据我快速看到的内容,我想出了一些要点,可以帮助你改进简历,并让你的技能更容易匹配。

图片来自未刷
掌握简历的技巧:
- 工作经历应该是招聘经理看到的第一件事。我主要对你的相关经验感兴趣,在此之前请不要添加你的技能列表。理想情况下,你可以加上你的工作经验(包括工作年限和成就)以及该工作所需的技能和/或工具,或者在此期间开发的技能和/或工具。
- 如果你申请的工作非常侧重于 python、分类算法和 NLP,在你的工作经历下添加关键词: 它会显示你对该工作的相关经验,更快地抓住招聘人员的眼球。
- 如果你没有足够的工作经验,加上你在 Kaggle 等项目上的经验或者其他任何有真实数据的项目。
- 如果你来自一所研究型大学,让技能和工具适应你申请的工作。如果职位描述要求 python 的知识,不要说你懂 Stata 和 Latex 这没什么用,只会在你的简历中占空间。
- 不要在没有分类的情况下添加一长串技能。如果你的技能是基于编程、ML 框架、算法、软技能、版本控制工具、语言等。然后说出来,不要都加了等招聘经理找到自己感兴趣的。额外提示:如果这个职位需要 X、Y 或 Z 技能,用粗体突出你已经具备这些技能。这会更快地吸引招聘人员的目光。
- 不要为了填满空间而添加额外的东西。确保你言简意赅,不要在工作经历中重复同样的描述。如果在你的生活中有两个工作是做 A/B 测试的,在其中一个工作中添加一个,在另一个工作中添加你分析数据或者你做的任何与 A/B 测试相关的事情。它将展示多样性,我将看到你已经知道了。然后在面试中,你将能够真正展示出你掌握了那项技能。
- 确保职位在工作经历部分的位置与公司和工作时间一致。应用适当的边距。说到底,我们是人,我们读的是有条理的东西,而不是乱七八糟的。如果你的简历没有条理,我会认为你在你的职位上不会有条理,所以除非招聘经理与此相关,否则你不会轻易被考虑在内。
- 不要写你是单身甚至你的出生日期。我们根据你的资历做出决定,所以避免任何可能影响决定的额外因素。
- 发送 PDF 格式的简历,不要。docx 。你不知道我们用来打开它的平台,如果它不是 pdf,我们可能看不到它像你做的那样漂亮。
这只是一些能真正提升你简历的技巧。请确保你明白审查它的人没有多少时间,你应该在你的简历中取得成功,以便有机会获得现场面试。
祝你好运!
为注重网络安全的数据科学准备 DNS 数据
原文:https://towardsdatascience.com/preparing-dns-data-for-cyber-security-focused-data-science-e596eb03cdf?source=collection_archive---------34-----------------------
TLDextract 和其他数据准备方法指南

阿迪·戈尔茨坦在 Unsplash 上拍摄的照片。
互联网的域名系统(DNS)将域名转换为数字互联网协议(IP)地址[1]。这使得人类浏览网页变得容易得多,比起一串看似随机的数字,人类更容易记住 medium.com。但是像网络空间中几乎所有的活动一样,网络威胁已经并将继续利用 DNS 活动[2]。
正因为如此,专注于网络安全的数据科学家经常发现自己在处理 DNS 数据。通常,这由一个域列表组成,没有其他内容;发现不寻常的或恶意的域名可能具有挑战性。然而,了解域名结构和基本功能工程可以让数据科学家丰富域名数据,以便进行更深入的分析。
(域名)中有什么?
域名包含了相当多的信息。考虑下面这个维基百科的例子:

https://en.wikipedia.org 元素的分解。作者创建的图像。
顶级域名(TLD)和二级域名(SLD)共同构成了互联网用户通常记忆中的根域名。顶级域名可以传达额外的信息,例如国家代码顶级域名(ccTLDs)的地理位置。有些网站有子域;在上面的例子中,维基百科有不同的语言和不同的子域相关联。维基百科使用“en”来表示英语子域,而 fr.wikipedia.org 会提供法语子域[3]。其他常见的子域用途包括博客、商店和支持网站。
说到 DNS 和网络安全数据分析,一个域名列表,如 medium.com,google.com,yahoo.com 等。,可能看起来没多大价值。这就是通过TLDextract【4】的数据准备和来自特征工程的概念【5】发挥作用的地方:
特征工程是利用领域知识从原始数据中提取特征(特性、性质、属性)的过程。
— 特色工程,维基百科
领域数据
首先,我们需要一些数据。 Majestic Million 根据参考子网跟踪排名前 100 万的域名,以衡量网站的重要性或相关性[6]。该网站提供基于知识共享署名的 CSV 数据导出许可。
本演练使用 GitHub 页面上提供的 Majestic Million 的前 100 个域名的样本,以及分析中使用的完整 Jupyter 笔记本 。下载笔记本和数据以便跟进。下面是原始数据的一个示例:

Majestic Million 数据样本的前五行的作者截屏。
右旋糖酐
从一个域名中提取 TLD、子域名等看起来就像在句点处拆分字符串一样简单。但是,在国家代码的情况下,一些顶级域名是由多个部分组成的(例如:co . uk);TLDextract 说明了这一点,它是一个比内置函数更好的工具,内置函数可能会将字符串拆分成句点[7]。
首先安装 TLDextract :
pip install tldextract
然后导入库:
import tldextract
1.剥离二级域名
要获取一个域,例如 medium.com,并提取“medium ”,请运行以下代码:
df['SLD'] = [tldextract.extract(i).domain for i in df.Domain]
产生的数据帧样本为:

作者截图。
2.剥夺顶级域名
要提取 medium.com 的 TLD,如“com ”,请运行以下代码:
df['TLD'] = [tldextract.extract(i).suffix for i in df.Domain]
产生的数据帧样本为:

作者截图。
3.提取子域
要提取子域,如 en.wikipedia.com 的“en ”,请运行以下代码:
df['subdomain'] = [tldextract.extract(i).subdomain for i in df.Domain]
并非所有的域都有子域,因此要查看效果,有必要通过以下代码进行排序:
df.sort_values(by='subdomain', ascending=False).head(3)
按视图子域排序的结果 dataframe 示例为:

作者截图。
请注意 TLDextract 是如何将一列域转换成几列数据的。查看子域名和顶级域名可以证明对各种类型的网络安全分析有用。例如:
- Spamhaus 跟踪十大最差顶级域名的滥用情况,并提供 TLD 检查功能[8]。提取 TLD 提供了一种识别数据集中常见滥用 TLD 的方法。
- 子域名构成了劫持的机会,并且根据 ATT 协议 CK 框架是一个已知的漏洞。
后续步骤:特征工程概念
虽然 TLDextract 提供了丰富的信息,但域名有更多值得提取的数据:
1.字母比率
域名由字母数字组成。除了字母,域名中还有其他字符,如数字和句点。字母与非字母的比率可以提供对领域特征的洞察。以下 python 函数将有助于提取字母比例信息:
def LetterRatio(domain):
if len(domain) > 0:
return len(list(filter(str.isalpha, domain)))/len(domain)
return "No Domain"
尝试运行一个示例域,如 medium.com:
LetterRatio("medium.com")
这应该返回 0.9,因为有 10 个字符,其中 9 个是字母,一个是句点。使用以下代码将其应用于数据帧:
df['LetterRatio'] = df['Domain'].apply(LetterRatio)

作者截图。
2.领域部分
域部分将域分成多个可用的部分。例如,medium.com 有两个,用句点分隔两个部分。提取它的函数是:
def DomainSections(domainName):
array1 = domainName.split(".")
return len(array1)
使用以下代码将其应用于数据帧:
df['DomainSections'] = df['Domain'].apply(DomainSections)

作者截图。
3.字符计数
最后一个是域名中的简单字符数。使用以下代码将其应用于数据帧:
df['DomainCharacters'] = df['Domain'].str.len()

最终准备好的数据框架的作者截屏。
准备好的数据帧及其用途
曾经只有一列域名的数据框架现在增加了六列。衍生的信息可能对未来的工作有用,例如识别滥用 TLD 的存在,甚至利用字母比率和字符数等进行异常检测。识别异常值的基本可视化示例如下图所示:
请注意,任何字母比低于. 81 的域都是异常值。
这是域名分析的简单起点,提取的特征可以为更深入、更高级的后续分析提供信息。请随意使用 GitHub 页面的上的笔记本来准备您自己的域名数据。
参考
【1】cloud flare,什么是 DNS?DNS 如何工作 (2021),Cloudflare。
[2] MITRE | ATT&CK,应用层协议:DNS,子技术 T1071.004 (2021),MITRE。
[3]维基百科:免费的百科全书,维基百科 (2021)。
[4] J. Kurkowski,GitHub—John-Kurkowski/tldextract(2021),GitHub。
[5]维基百科,特征工程 (2021)。
[6]浩浩荡荡,浩浩荡荡的百万 (2021)。
[7] J .库尔科夫斯基, GitHub —约翰-库尔科夫斯基/tldextract (2021),GitHub。
[8]Spamhaus 项目,十大最常被滥用的顶级域名 (2021),Spamhaus。
[9]ATT 和 CK,妥协基础设施:域名 (2021)。
准备数据科学面试?这是一份完整的指南,可以帮助你表现出色
原文:https://towardsdatascience.com/preparing-for-data-science-interview-here-is-a-complete-guide-to-help-you-perform-well-a98d28f4a1f4?source=collection_archive---------2-----------------------
关于获得工作的最佳方法、策略和技巧

在 Unsplash 上猎人赛跑的照片
不管你是数据科学新手还是有经验。工作面试会给任何人带来焦虑。每一次工作面试都是一次不同的经历。虽然你不可能预测你的面试问题或者猜测面试官的期望。肯定有一些事情可以确保你做好充分准备。
当我说准备面试时。我不是指你面试的前一晚。它是关于带你去面试的旅程。长时间的准备可以确保面试当天一切顺利。
在这篇文章中,我将分享一些重要的技巧,它们将增加你在数据科学工作面试中的成功机会。
准备一份有影响力的简历
首先也是最重要的是有一份好的简历。你的简历应该准确反映你的技能和经验。如果你的简历表现不足或过多,那就不好了。此外,你的简历应该采用易于阅读和分享的格式。
一份好的简历的一些重要方面是,
- 利用好的简历模板
- 在开始时有一个轮廓快照
- 利用项目符号
- 具有一致的格式
- 避免印刷错误
- 使用谷歌的 XYZ 公式创建有影响力的陈述
- 定制你的简历和求职信
如果你有兴趣利用一些惊人的平台来建立一个真正令人印象深刻的简历。查看下面这篇文章,
准备一个令人惊叹的投资组合网站
拥有一个好的投资组合起着非常重要的作用。基于泰坦尼克号数据集的项目甚至不能让你得到一个实习角色。所以,请花足够的时间来确定一些合适的项目。一个好的项目不仅有助于你的学习,也有助于你找工作。
在很多 IT 领域,有人第一次面试没有任何技术知识是可以的。他们将接受态度测试,之后将接受在职培训。但请记住,数据科学工作不是其中之一。数据科学团队通常非常小。大多要求数据科学家独立,有解决问题的本能。这些技能可以通过一个好的项目组合来展示。
建立一个个人作品集网站并不难。如果你渴望建立一个免费的个人投资组合网站,请查看下面的视频。我已经免费分享了建立个人投资组合网站的步骤。这个个人网站是基于 GitHub 页面构建的。
在你的投资组合中有各种各样的项目也很重要。利用传统的 kaggle 数据集来展示一个项目不再有效。外面有如此多的数据。许多政府机构和组织都在发布他们的数据集。社交媒体充满了非结构化数据,其中包含大量有用的信息。现在很容易为你的投资组合设计一个独特的项目。这就是为什么流行的 kaggle 项目对找工作没有任何帮助。
准备编码测试
一份好的简历和作品集足以让你入围。现在,作为面试过程的一部分,进行编码资格测试或案例研究是非常普遍的。有一些平台可以帮助提高和测试你的技能。
黑客银行
HackerRank 就是这样一个对开发者完全免费的平台。他们在广泛的主题上面临许多挑战。这些对于准备技术评估和访谈非常有帮助。根据个人的学习目标,他们有一个定制的路径。他们还有提供免费认证的技能测试。除了所有这些,他们有一个工作门户网站,你可以在那里申请工作。尽管这个平台没有专门的数据科学途径或计划。它们绝对可以用来测试编码技能。他们确实有测试 Python、R 和 SQL 技能的评估。
Python 和 R 编程
数据营和代码学院是学习和提高数据科学编程技能的好地方。他们有很棒的 R 和 Python 课程。他们确实支持学习 SQL。它们都是交互式平台,使得学习编码更加容易和容易。
这些平台上的编程课程是初学者友好的,并且容易学习。编程新手一定要试试这些平台。
结构化查询语言
LearnSQL 是一个专门致力于构建和测试 SQL 技能的平台。他们有许多免费的基于场景的编码挑战。这些对学习 SQL 会很有用。学习 SQL 一直都很棘手。因为要学习现实生活中的 SQL 技能,您需要访问现实世界中的数据库。这些平台使场景变得真实,并很好地复制了现实生活中的问题。从而创造美好的学习体验。
基于场景的
还有很多其他公司分享一些真实的数据,问一系列的业务问题。这些有助于他们测试你的技能。还有,你理解和解决一些现实世界问题的能力。为此做好准备的唯一方法是使用 Kaggle。kaggle 上托管了很多数据科学问题。在 Kaggle 数据集上工作将教会你解决任何新的数据科学问题。
刷新基本概念
认证和课程完成不足以让你被录用。您需要很好地了解数据科学的基本概念。这里有一些令人惊讶的文章,它们引用了数据科学访谈中的常见概念和问题。
https://betterprogramming.pub/the-data-science-interview-study-guide-c3824cb76c2e
拥有个人资料快照
对于我们每个人来说,在面试中错过一些关键成就是很常见的。我们往往会忘记我们曾经做过的一些有趣的项目。因此,我强烈建议建立一个简介快照,包括你所有的贡献、成就和项目。这很有帮助,因为我们试图限制简历上分享的信息量。您参与的项目的所有详细信息都可以包含在档案快照中。所以,在面试前快速复习一下会很容易。
配置文件快照可以是一个简单的 excel 文件。这个想法是包括你的项目和经历的所有细节。这是一种记录你职业生涯中所有重大事件的日志。
为面试的前 5 分钟做准备
面试的前 5 分钟是最关键的部分。大多数面试中的第一个问题是谈论你自己。这肯定需要大量的准备,你的介绍会带动接下来的面试讨论。
在大多数面试中,面试官会准备一些问题来测试你的技能。面试的大部分将基于讨论和你简历的内容。以一个真正好的介绍开始是很重要的。这将有助于引导面试官进一步提问。
这个问题的最佳公式是,
- 你目前在做什么?
- 你过去的经历是什么?
- 你未来的计划是什么?
首先,从你目前的角色和职位开始。然后转移到过去,说明自己过去的经历和成就。最后,谈谈你的未来计划,以及它如何与你正在面试的工作紧密结合。
阅读关于公司的信息
你需要了解你申请的公司和职位。招聘启事足以让你了解这个角色的一切和期望。你仍然需要阅读关于组织和他们的目标。了解该公司的最佳方式是阅读
- 他们的网站
- 他们的科技博客
- 像 Twitter 和 LinkedIn 这样的社交网络
- 新闻
上述来源将为你提供关于公司、计划和目标的所有信息。
除了这些,更好地了解工作环境和一般文化。你可以从 glassdoor 上看到这篇评论。Glassdoor 是一个了解最有可能提供的薪资范围的好平台。想知道为公司工作的感觉。Glassdoor 评论将给出一个关于组织文化的想法。
寻找一些动力?
如果你想在数据科学领域寻找一些开始职业生涯的动力。以下是我的数据科学之旅。我没有任何数据科学经验,也没有数据科学相关的学位。我没有很好的编程知识。尽管如此,我还是在数据科学领域找到了自己的职业。现在,我已经写了两本关于数据科学的书,并被列为媒体上人工智能的顶级作家。更重要的是,我成功地交付了许多数据科学项目。
需要更多动力?这是其他几个人的旅程,他们来自非编程背景,不仅成功进入了数据科学领域。但是他们也取得了成功。这里的是视频的链接。
结束提示
- 永远不要在简历中加入任何你不自信的东西。如果你在简历中写了一些东西,这意味着你对它有足够的了解。如果你对简历中的某些东西不确定,比如简历中提到的某个项目。面试官拒绝你就够了。在面试中,招聘人员会不断地寻找信号来雇用或拒绝候选人。我们的目标应该是增加积极信号,消除消极信号的可能性。
- 在每一次信号面试后,写下那些进展顺利的事情和那些本可以更好的事情。这种自省对提升自己很有帮助。这将有助于你在下次面试中表现得更好。不自省的人往往会重复犯同样的错误,但无法理解或承认它。
- 准备一些要问的问题。像介绍部分一样,大多数面试都会以一个提问的机会结束。基于最近的新闻或基于你读到的信息。试着想出一些有趣的问题。这些小事影响面试的结果。
- 在 glassdoor 上寻找面试经验和反馈。这对准备面试很有帮助。
保持联系
- 如果你喜欢这篇文章,并对类似的文章感兴趣,在 Medium 上关注我。成为的中级会员,访问数千篇与职业、金钱等相关的文章。
- 我在我的 YouTube 频道上教授和谈论各种数据科学主题。在这里订阅我的频道。
- 在这里注册我的电子邮件列表获取更多数据科学技巧,并与我的工作保持联系
使用 TensorFlow 准备 ImageNet 数据集
原文:https://towardsdatascience.com/preparing-the-imagenet-dataset-with-tensorflow-c681916014ee?source=collection_archive---------32-----------------------
方便地设置 150 GB 的图像数据
毫无疑问,ImageNet 数据集已经成为开发高级机器学习算法的关键因素。其庞大的规模和众多的类别给处理带来了挑战。这些问题导致了更好的数据处理工具和新颖的神经网络结构。

亨特·哈里特在 Unsplash 上的照片
TensorFlow Datasets 就是这样一个数据集处理工具。在它的帮助下,您可以方便地访问许多类别的各种数据集。大多数情况下,您可以直接从 TensorFlow 下载数据。
但是,ImageNet 是个例外;它需要手动设置。虽然似乎有一些实现这一目标的指示,但它们有些模糊。因此,我花了一些时间来准备数据集,但我最终得到了一个简洁的脚本。在下文中,我将指导您使用 ImageNet 数据集进行实验。
下载 ImageNet
在我们做任何准备之前,我们需要获得数据集。为此,请转到注册页面并创建一个帐户。完成此操作并申请使用 ImageNet 数据集后,进入下载页面。在“ImageNet 大规模视觉识别挑战赛(ILSVRC)”下,选择 2012 版。这将引导您进入新的一页:

ImageNet 下载页面。作者截图。
在此页面上,我们需要下载“训练图像(任务 1 和 2)”和“验证图像(所有任务)”文件。因为它们总共有 150 GB 大,这将需要一些时间。如果你有大学提供的网络,我建议你利用他们的网络。通常,它们的下载速度非常快。
之后,您有两个文件。第一个,ils vrc 2012 _ img _ train . tar,包含训练图像及其标签。第二个, ILSVRC2012_img_val.tar ,包含验证图像及其标签。有了这些存档,我们现在可以为实际使用准备数据集了。
准备 ImageNet 数据集
准备数据集的完整脚本如下所示。根据您的情况调整任何目录路径:
要安装 TensorFlow 数据集,请运行
pip 安装 tensor flow-数据集
在必要的安装和导入之后,我们定义了ils vrc 2012 _ img _ train . tar和 ILSVRC2012_img_val.tar 文件所在的路径:
然后,我们设置一些配置参数。手动 _ 方向参数是这里的关键。它确保 TensorFlow 数据集在我们指定的位置搜索下载的文件。 extracted_dir 是数据集准备期间使用的临时目录。您可以在以后删除它:
最后,我们实现实际的构建过程。准备工作是通过一个 DatasetBuilder 对象完成的,它“知道”如何设置一个特定的数据集。例如,为了获得 ImageNet 的构建器,我们通过传递“imagenet2012”来实例化它。
然后我们在这个对象上调用实际的准备方法, download_and_prepare() 。这里我们唯一要做的就是传递我们的配置对象:
这就是我们在 python 端要做的全部工作。
运行脚本
要运行该脚本,我们键入
python <script_name>。巴拉圭</script_name>
这样直接在默认 ~/tensorflow_datasets/ 中构建 ImageNet 数据集。要改变这一点,我们可以用
TFDS _ 数据 _ 目录= <custom_path>python <script_name>。巴拉圭</script_name></custom_path>
我们在前面加上了 TFDS 数据目录,将负责构建位置的环境变量设置到我们选择的目录中。这主要在计算集群中有用,在计算集群中,多个工作人员访问相同的数据集。
摘要
我们已经完成了 ImageNet 数据集的设置。不幸的是,我们无法方便地设置测试数据集。此外,没有提供标签,以防止不公平的技术被使用。因此,评估模型的唯一方法是将带有图像->预测标签映射的文件上传到分级服务器。要获取测试图像,从与之前相同的下载页面下载测试档案。然后,将其解压缩到您选择的目录中。任何进一步的处理都遵循典型的数据流水线。然而,这超出了本文的范围。为了更进一步,看看 Keras 的功能来实现这个或者在这篇文章中获得使用数据集的印象。
用信号包络预处理音频数据
原文:https://towardsdatascience.com/preprocess-audio-data-with-the-signal-envelope-499e6072108?source=collection_archive---------17-----------------------
动手教程;人工智能
如何去除音频数据中的多余噪音

心情——照片由弗朗西斯科·德·托马索在 Unsplash 上拍摄
当我第一次通过熨斗学校进入数据科学领域时,我就着眼于将我正在接受的培训与我的音乐背景相结合。课程的最后一项要求是顶点工程。目标是用我们新获得的技能解决一个感兴趣的问题。我觉得这是开始理解音乐和机器学习之间相互关系的黄金机会。
我的导师和我在很多会议上讨论了这个项目的范围。起初,我想为音乐合成创建一个生成模型。然后我开始对非人类动物的音乐感兴趣,尤其是鲸鱼的歌声。我们一起寻找数据,发现不是鲸鱼,而是鸟类:2021 年鸟叫声识别数据集。这是一个利基但开放的音频数据集合。通过对数据的深入挖掘,我了解到其中的含义远非简单归类,而是有着非常具体的途径。音频数据可以为鸟类学研究和濒危物种保护工作的实施增加另一个维度。这也让休闲观鸟者更容易识别他们看不到的鸟类。从声音上来说,我看到了研究鸟类发声的音乐性和利用被识别的鸟作为艺术灵感来源的大好机会。

帕特里克·亨德利在 Unsplash 上拍摄的照片
我想分享一个我用来帮助预处理音频数据的整洁的东西(感谢 Seth Adams 的大力帮助):信号包络。包络勾勒出音频信号的最高点和最低点(dB)。这是更大的预处理目标的一部分:量化音频信号的物理属性。有几种测量方法,如采样率( n 每秒数据点)、振幅(dB)、频率(Hz)。包络包含这些元素,是一个非常有用的工具,即使不是必需的,也可以用来清理音频数据,尤其是环境录音。收集音频信号的极值的目的是减少记录中的环境噪声,以便模型可以在训练期间关注发声的值。
我在任务中主要使用了这些库:熊猫、 NumPy 、 Librosa 和 Matplotlib 。我发现 Librosa 真的很整洁。它广泛用于分析音频数据,在本例中,它执行几个关键功能。总之,用于在音频数据上训练我的模型的管道包括(1)加载原始音频文件;(2)转换成波形;(3)将波形转换成 Mel 谱图。我将主要关注前两步。
下面是主包络函数的代码,它接受三个参数:音频信号、采样率和阈值。在引擎盖下,它将信号转换成熊猫系列,并获取其所有数据点的绝对值。从这里开始,滚动窗口用于取 sample_rate(Hz)/10 的每个窗口的平均值。for 循环用于遍历 Pandas 均值信号系列。如果任何新数据点高于您设置的阈值(dB),它将被附加到一个名为 mask 的 NumPy 数组中(我使用这个名称是为了与 Seth 的工作保持一致)。任何低于阈值的数据点都不会包含在数组中。
信封功能:
作者代码
您可能想知道平均数据点数组在其余预处理步骤中的位置。介绍快速傅立叶变换 (FFT),预处理音频的重要功能。FFT 将一个域的信号转换到另一个域。例如,如果我们看下面的音频波形(原谅未标记的轴),它是在时域中,这意味着信号的幅度(dB)是随时间测量的。FFT 将信号转换到频域,这将显示发声的频谱频率的集中;这被称为周期图。虽然信号包络和 FFT 是两个独立的功能,但理想情况下,它们可以协同工作,为将波形图像转换为 Mel 频谱图做准备。
计算 FFT 函数:
作者代码
我已经包含了两组使用这些函数的代码。除了后者包括前面所示的包络函数之外,二者是相同的。定义了两个空白字典,一个用于原始信号量,一个用于 FFT 信号量。for 循环遍历 bird 类的列表,将类与元数据数据帧中的标签进行匹配。之后,通过 Librosa 的加载功能搜索音频目录,以匹配音频文件目录中的标签,并以高于设定的采样率(16kHz)将其作为单声道信号加载。然后根据鸟的种类对信号进行标记,随后以 16kHz 的采样率进行 FFT。原始信号和 FFT 信号都与它们的标签一起被添加到字典中。让我们看看下面。
无信号包络:
作者代码

无包络函数的时间序列中的波形,FFT 之前—作者提供的图像

以上波形的 FFT 周期图—图片由作者提供
在加载数据之后,FFT 之前,调用包络函数。新的信号被重新定义为,我称之为“被包围的”信号;这被添加到 sig_new 字典中。新信号然后进行 FFT。
带信号包络:
作者代码

使用包络函数后时间序列中的波形,FFT 之前—作者提供的图像

以上波形的 FFT 周期图—图片由作者提供
我用一个物种,普通的短尾猿,作为例子。FFT 之前的图像显示了看起来更稳定的波形,但这是因为消除了低于 0.009 dB 阈值的数据。同样的原理也适用于 FFT 周期图,其中消除的数据将显示发声中频率的更大集中。
为了将所有这些放在一起,下面是对所有信号应用信号包络和 FFT 后的 12 个 Mel 频谱图样本。越亮的颜色表示频率越集中(kHz)。现在,音频分类任务变成了图像分类任务。

信号包络和 FFT 后的 Mel 光谱图—作者提供的图像
值得注意的是,这个函数被用于 27 种鸟类,每一种都包含数百个不同保真度的记录。其影响的大小因记录而异。虽然仍然是一个有用的预处理步骤,但很难确定一致性,以及在公式化数据切片后是否所有期望的信息都将被保留。尽管如此,我还是强烈建议音频机器学习从业者结合这个功能,让自己更接近于处理更有组织的数据。
请随时检查项目在这里,问我问题的清晰度,或建议的方式来推进到最好的版本。非常感谢!
参考资料:
- 塞斯·亚当斯
- 斯特凡·卡尔
- 阿尤什·塔库尔
- DrCapa
- 安德烈·史特劳斯
- 瓦莱里奥·维拉多
- 弗朗索瓦·勒马尔尚德
- 亚当·萨布拉
使用 Monai 和 PyTorch 预处理用于肿瘤分割的 3D 体积
原文:https://towardsdatascience.com/preprocessing-3d-volumes-for-tumor-segmentation-using-monai-and-pytorch-eaeb3d718570?source=collection_archive---------37-----------------------
为肿瘤或器官分割准备 nifti 体积
你可以在我的网站 这里 找到原文。
下面是这篇文章的视频版本,其中可能包括一些我忘记在文章中包括的解释。

图片来自 Mart Production 的 Pexels
介绍
关于我们在使用传统图像处理工具时可能遇到的困难,深度学习已经成为医疗保健领域的主要解决方案。
由于医学图像比标准图像更难处理(密集的对比度,人体的大范围变化…),深度学习用于分类,对象检测,尤其是分割任务。
说到分割,深度学习被用于分割人体器官,如肝脏、肺等,或者分割身体不同部位的肿瘤。
有许多不同类型的医学图像,如 MRI(主要用于脑瘤分割)、CT 扫描、PET 等。
本文将重点介绍 CT 扫描,但同样的操作也可以应用于其他类型。
所以我们知道,执行深度学习任务需要许多步骤,其中之一是数据预处理,这是我们在启动培训之前必须做的第一件事。这是本文的主题;我们将讨论可用于执行这一预处理的工具。
准备数据因任务而异;例如,分类是最容易的,因为我们只需要准备图像,而对象检测和分割需要我们准备图像以及标签(用于分割的边界框或遮罩)。
在本文中,我们将以分割为例,它可用于肿瘤或器官分割。
在医学成像中,我们可以处理 2D 图像,这些图像可以是 DICOM、jpg 或 png,也可以是 3D 体积,它们是切片组,每个切片是一个 2D 文件(大多数情况下是 DICOM),而这个组是一个 nifti 文件,它代表整个患者或他身体的一部分。请阅读 本文 了解 dicom 和 nifti 的区别。
我们将在本文中使用 3D 卷,因此如果您有想要转换成卷的 2D 文件,请参见本文https://pycad.co/how-to-convert-a-dicom-series-into-one-nifti-file-python/。
我们将使用的工具
为了完成这个任务,我们将使用一个名为 monai 的开源框架,它基于 PyTorch,我在实习期间使用过这个框架,发现非常有用。
想看它的文档请见 这个链接 。
方法学
我们现在将开始编写我们的函数来执行 CT 扫描中肿瘤分割的预处理。第一步是使用 pip 或 conda 安装库,这取决于您使用的环境。
***pip install monai***
我强烈建议您为您的项目建立一个虚拟环境,因为这个库在直接安装到系统中时并不总是能够工作。
然后需要安装 PyTorch 和 monai 的一些依赖项。
***pip install torch***
***pip install torch-vision***
***pip install “monai-weekly[gdwon, nibabel,tqdm]”***
然后,您需要包含您将需要的库。
作者编写的代码
现在我们来看看如何加载数据。对此有两种方法。
1- 首先是分别加载图像和蒙版(如果你想进行图像分类,可以使用这种方法,但它也适用于分割)。
2- 第二种方法是创建一个包含两列的 Python 字典,一列用于图像路径,一列用于标签路径。然后在每一行中输入带有相应遮罩的图像的路径。
就我个人而言,我更喜欢第二种方法,因为当我们应用转换时,我们将能够只选择图像或标签或两者的关键字,而不是为图像和标签(遮罩)创建转换。
现在,您必须创建一个包含整个数据集路径的变量。在我的例子中,我有四个文件夹:TrainData,用于训练图像和遮罩的 TrainLabels,以及 ValData,用于验证图像和遮罩的 ValLabels。
因此,要创建一个字典来存储路径,请使用下面几行代码:
作者编写的代码
之后,你已经创建了字典,如果你不熟悉它,这很简单。如果要引用字典中的第一项,可以像在普通数组中一样使用 index 0,但是第一项将有两列,第一列是图像的路径,第二列是标签的路径(关于这一部分的更多信息,可以查看上面的 youtube 视频)。
变换
为了对同一个病人应用多个转换,我们将使用 monai 的“compose”功能,该功能允许您组合任何想要的转换(monai 文档中定义的转换)。
在应用任何转换时,您应该知道一些事情:有些步骤是必需的,而有些是可选的。
使用 monai 时,主要的转换是“Load image”来加载漂亮的文件,以及“ToTensor”来将转换后的数据转换成 torch tensors,以便我们可以使用它进行训练。
现在我们已经讨论了基本的转换,我们将继续讨论其他的。我将讨论在我实习期间特别重要的五个转变。
AddChanneld: 这个函数会给我们的图像加上一个通道,并贴上标签(我说的图像是指多个切片的体积),因为我们在做肿瘤分割的时候,需要一个通道起到背景或者肿瘤的作用。
Spacingd: 该功能将帮助我们改变体素尺寸,因为我们不知道医学图像的数据集是通过相同扫描还是不同扫描获得的,所以它们可能具有不同的体素尺寸(宽度、高度、深度),所以我们需要将它们全部归纳为相同的尺寸。
cropforeground:该功能将帮助我们裁剪掉图像中我们不需要的空白区域,只留下感兴趣的区域。
调整大小: 最后,这个函数是可选的,但在我看来,如果您使用 cropforeground 函数,则它是必需的,因为执行裁剪的函数将根据每个患者的情况输出随机尺寸,所以如果我们不添加一个操作来为所有患者提供相同的尺寸,我们的模型将无法工作。
作者编写的代码
正如你所看到的,在我们使用的每个函数的末尾都有一个“d”,这是字典(如果你没有使用字典,那么你需要删除它)。我们还为每个操作添加了参数【keys】,以指定我们是否要将该变换应用于图像、标签或两者。您可以看到,几乎所有时间我们都将该函数应用于标签和图像,但在 ScaleIntensityRange 中,我们仅将其应用于图像,因为我们不需要更改强度或归一化标签的值。**
数据加载器
现在,与任何深度学习代码一样,我们必须在开始训练之前加载数据及其转换;为此,必须使用两个基本函数。
数据集: 该函数将定义数据及其转换,因此如果您有训练集和验证集,您将需要创建两个“数据集”函数,一个将训练数据与其转换相结合,另一个将验证数据与其转换相结合。当然,如果对定型集和验证集应用相同的转换,则必须在函数“dataset”的参数“transform”中使用相同的转换
数据加载器: 这是将数据加载到具有特定批量大小的 RAM 中的函数(它将创建另一个通道以在训练期间指定批量大小的索引)将有两个数据加载器,一个用于训练,一个用于验证。
作者编写的代码
绘制一个例子
应用转换后,您可以绘制一些切片,以查看使用和不使用转换时数据有何不同。
您可以使用 monai 函数【first】从 dataloader 中获取第一个项目,这将是第一个患者。
这里有几行代码可以帮助你绘制例子。
作者编写的代码
现在让我们来看看有和没有转换的输出:

作者捕获的图像
左边是没有转换的切片,中间是我们讨论过的带有转换的同一切片,右边是相应的标签。
这就是如何使用 monai 为分割准备 3D 体积。如果你想看更多的变形金刚,去莫奈的网站。但是,有些转换是为数据扩充而设计的,而不是为预处理而设计的。我也会写一篇关于它的文章。
PS:我推荐看视频,因为文中还有我可能忽略的额外解释。
你可以从这个链接找到代码。
你想学医学影像的深度学习!
即将推出全面的医学成像课程,涵盖使用 Monai 和 PyTorch 的 2D 和 3D 分割,并提供额外支持。加入等候名单以接收任何课程更新的通知。
***https://pycad.co/monai-and-pytoch-for-medical-imaging/ ***
订阅我的简讯获取我工作的所有更新:)。
用车床预处理 Julia 中的大数据
原文:https://towardsdatascience.com/preprocessing-big-data-in-julia-with-lathe-90c8b95120f4?source=collection_archive---------24-----------------------
用大数据测试 Julia 语言和车床。

(src =https://pixabay.com/images/id-895567/
介绍
W 当谈到机器学习的奇妙和广阔的世界时,有许多流行的选项值得许多数据科学家选择。老实说,就我个人对数据科学生态系统的看法而言,我认为该领域的许多方面已经过时,而其他方面正在以光速向前发展。在某种程度上,这是有道理的,因为像这样一个爆炸性的行业还没有时间成熟到它的规模,因此我们最终会面临一些问题。
数据科学面临的一个重要问题是编程语言。对于许多入门级的开发人员来说,数据科学可能很难进入。因为有如此多的选择,以及某些语言的狂热的,有时是公然的宗教信徒,他们可能会解释为什么 X 或 Y 比另一个更好的某些观点。如果你碰巧在那条船上,我实际上有一篇文章可以回答这个问题,因为你选择的语言很可能会对你最终从事的工作类型产生重大影响。如果你愿意,你可以在这里查阅这篇文章:
我离题了…最终我认为,虽然还不清楚也不知道哪种语言将成为新的数据科学的典型,但如果语言发生了变化,我认为语言的问题往往会在数据科学工作中暴露出来。让我们回想一下,在 2015 年,大多数数据科学工作清单都是针对 Java 的。也就是说,Python 仅仅统治了这个领域大约 7 年,这意味着这种语言直到最近才开始面向这些受众。许多人会争论 Python 是数据科学的完美语言,但事实上不可能有完美的语言,因为总会有某种缺陷。
来源
虽然 Python 拥有终极的数据科学生态系统,但它也是一种解释型语言,更类似于 JavaScript,而不是 Scala 或 C++之类的东西。这当然会减慢速度,虽然大多数包是用 C 编写的,并且由于优化和良好的代码,实际上可以运行得非常快,但它们仍然存在问题。Python 的问题在于,如果你想处理更复杂、多维度的大数据,那么你就会遇到很多意想不到的问题。不用说,因为你使用的编程语言而试图从你的计算机中挤出最后一滴性能并不是一种完美的体验。
Python 也有并行计算的后见之明,这意味着它在设计时不一定考虑了并行计算。每天,并行计算变得越来越重要,应用越来越广泛。Python 有时会遇到麻烦,这一事实无疑是这门语言的一个障碍,尤其是当它与其他任何东西混合在一起时。
当然,朱莉娅也不是完美的,因为她也有很多缺点。虽然我认为它的范例非常适合编写,而且没有其他地方我更愿意编写我的代码,但我也看到了这种语言的一些问题。当然,语言还是比较新的,所以这肯定是明智的。事实上,它最近才开始流行,这意味着这个生态系统还很不成熟。在一个不成熟的生态系统中,Julia 是否会被业界采用是值得怀疑的,主要是因为他们不想花钱让人编写已经用另一种语言编写的包。
所有这些都不在话下,我真的认为这个时候没有完美的语言。我觉得 Python 很棒,我觉得 Julia 也很棒,但我觉得他们都有减损他们伟大的瑕疵。也就是说,我也认为 Julia 展示了对未来的承诺,即使未来是 Python 的一个副作用。今天,我想用一个成熟的生态系统展示这种语言的潜力,并在核心本身上做更多的工作,我真的认为 Julia 可以在数据科学领域做很多非常令人兴奋的事情,这当然让我兴奋。
[笔记本](https://github.com/emmettgb/Emmetts-DS-NoteBooks/blob/master/Julia/Big Data With Lathe (Gingerbread Beta.ipynb)
车床
这是一个针对 Julia 的机器学习包,自 2019 年以来一直在广泛活跃的开发中。Julia 的一个问题是,通用机器学习的生态系统内部存在很大差距。许多软件包分别针对线性建模、数据处理、统计或深度学习,没有一致的方向或类型。这是有问题的,因为我们有所有这些独立创建的工具,它们相互依赖,但不知何故不能一起工作——这是愚蠢的,因为 Julia 使用子类型很容易扩展。如果您想了解更多关于该产品包的信息,请访问
或者 Github 页面,
https://github.com/ChifiSource/Lathe.jl
我记得当我在 2018 年开始在朱莉娅工作时,我一辈子都找不到一个好方法来训练-测试-分割我的数据。最后我不得不写一个函数来做这件事,每次我需要训练-测试-分割一些东西的时候,我都会使用同一个函数。车床的目的是建立某种程度的一致性,虽然它是面向对象的,工具是用来扩展的。如果我们想到 Python,SkLearn 为使用模型进行预测设置了一个标准,此后其他包也一直遵循这个标准。
今天,我想使用一些巨大的数据集,并真正测试一下车床,以便在某种程度上演示如何实际使用该模块,并演示该模块实际上有多大的能力。首先,让我们生成绝对大量的随机数据。我想做两个分类和连续的选择,编码器和定标器放入管道。首先让我们导入我们的依赖项:
using DataFramesusing Lathe.preprocess: TrainTestSplitusing Lathe.preprocess: StandardScaler, OrdinalEncoder, OneHotEncoderusing Lathe.models: LinearRegression, RandomForestClassifier, Router
数据
对于连续数据,我基本上只是使用 randn()来生成一些随机数。至于观察次数,我选择了 500 万次。在大多数行业标准工具中,数百万次的观察基本上是不可能的,即使是从一维的角度来看。我不认为 Python 会创建这个数组,尽管我可能是错的。我使用 randn()函数生成了这个数据:
x = randn(5000000)
y = randn(5000000)
现在分类数据有点棘手,因为 Julia 真的没有像 Python 那样的随机选择函数。你可以迭代地抽取样本,就是这样。我编写了这个简洁的小函数,利用了 Lathe 的 ordinal encoder 对象来创建一个查找字典,对其进行反转,然后用给定范围内的整数对其进行索引:
function randchoice(opts::Array{String}, count = 5)mapping = OrdinalEncoder(opts).lookupinverse_dct = Dict([pair[2] => pair[1] for pair in Set(mapping)])[inverse_dct[Int64(rand(1:length(opts)))] for i in 1:count]end
接下来,我创建了一些字符串形式的分类选项。我创建了 3,000,000 个这样的模型,因为我认为我应该挑战这个模型,同时测试这个模型的 CUDA 实现。
opts = ["A", "B", "C"]
caty = randchoice(opts, 3000000)
catx = randchoice(opts, 3000000)
最后,让我们将数据压缩成两个数据框架:
df = DataFrame(:X => x, :Y => y)
catdf = DataFrame(:CATX => catx, :caty => caty)
处理
我们将分割每个数据帧,我用时间宏来计时,从现在开始所有的车床下面都会有一些时间截图!
@time train, test = TrainTestSplit(df)

(图片由作者提供)
然后我做了一个 trainX 和 trainy 数组:
tr = :Xte = :YtrainX = Array(train[!, tr])trainy = Array(train[!, te])testX = Array(test[!, tr])testy = Array(test[!, te])
接下来,让我们创建一个标准缩放器来缩放传入的 X:
@time scaler = StandardScaler(trainX)

(图片由作者提供)
然后,我们将使用它的 predict()函数来获取一些用于训练的数据:
@time scaled_tX = scaler.predict(trainX)

(图片由作者提供)
建模
最后,让我们将其与一个基本的线性回归模型进行拟合:
@time model = LinearRegression(scaled_tX, trainy)

(图片由作者提供)
现在,我将使用加法运算符用我们的缩放器和模型制作一个管道:
pipe = scaler + model
@time yhat = pipe.predict(testX)

(图片由作者提供)
预处理 II
对于我们的分类模型,我做了与之前完全相同的分割过程:
@time train, test = TrainTestSplit(catdf)

(图片由作者提供)
然后将数据放入一维数组:
tr = :CATXte = :catyctrainX = Array(train[!, tr])ctrainy = Array(train[!, te])ctestX = Array(test[!, tr])ctesty = Array(test[!, te])
之后,我安装了一个顺序代码:
@time encoder = OrdinalEncoder(ctrainX)

(图片由作者提供)
并再次使用 predict()函数预测:
@time tx_enc = encoder.predict(ctrainX)

(图片由作者提供)
建模 II
最后,我安装了一个随机森林分类器:
@time model = RandomForestClassifier(tx_enc, ctrainy, # cuda = true # < uncomment for cuda!)

(图片由作者提供)
接下来,让我们再次使用加法运算符为分类输入创建另一个管道:
catpipe = encoder + model
@time catpipe.predict(ctesty)

(图片由作者提供)
结论
我认为很明显,对于大多数机器学习场景,车床对于预处理数据来说是强大而快速的。我认为,能够使用这些预处理工具如此轻松地处理这些大数据,无疑给了 Lathe 和 Julia 留在该行业的巨大希望。即使系统仅用于输入 Python 编写的机器学习模型,情况也可能如此。在所有这些测试中,唯一一个编译时间超过 10 秒的是随机森林分类器,我认为它在处理这么多数据时仍然有相当激进的时间。
我试图将这些时间与 CUDA 时间进行比较,但看起来好像我的 CUDA 不工作,这破坏了乐趣!如果你刚好有显卡和 CUDA,你可以在笔记本上随意试用,并让我知道效果如何,这对我来说意味着一切!感谢您的阅读,我希望这篇文章能够展示 Julia 语言在正确的支持下会有多么强大!
为机器学习预处理文本数据
原文:https://towardsdatascience.com/preprocessing-text-data-for-machine-learning-6b98f7bb0258?source=collection_archive---------27-----------------------
使用 NLTK 和动画展示常见的文本转换

帕特里克·托马索在 Unsplash 上的照片
非结构化文本数据需要独特的步骤进行预处理,以便为机器学习做准备。本文将介绍其中的一些步骤,包括标记化、停用词、删除标点、词条化、词干化和矢量化。
数据集概述
为了演示一些自然语言处理文本清理方法,我们将使用我最喜欢的音乐家之一吉米·亨德里克斯的歌词。原始歌词数据可以在这里找到。为了这个演示的目的,我们将使用他的著名歌曲中的几行:
A broom is drearily sweeping
Up the broken pieces of yesterdays life
Somewhere a queen is weeping
Somewhere a king has no wife
And the wind, it cries Mary
标记化
大多数自然语言处理工作流程的第一步是对文本进行标记。有一些不同的变体,但在最基本的意义上,这涉及到将一个文本字符串拆分成单个的单词。
我们将首先回顾 NLTK(用于演示本文中的大多数概念),并很快看到标记化在其他几个框架中的应用。
NLTK
我们已经将数据集读入字符串列表,并可以使用来自 NLTK python 库的单词标记化函数。您将看到,在循环遍历每一行时,应用 word tokenize 会将该行拆分为单个单词和特殊字符。

在标记化之前,按作者排序的图像

标记化后,作者的图像
其他库中的记号赋予器
有许多不同的方法来完成标记化。NLTK 库在这个领域有一些很棒的功能,但是其他的包括 spaCy 和许多深度学习框架。下面是这些库中标记化的一些例子。
火炬
空间
不同的记号赋予器之间可能会有细微的差别,但是以上或多或少都是一样的。spaCy 库有自己的对象,这些对象结合了框架的特性,例如返回一个 doc 对象,而不是一个令牌列表。
停用词
在某些情况下,移除停用词可以提高自然语言处理模型的理解或准确性。停用字词是常用的字词,可能不携带太多信息,并且可以在信息损失很少的情况下删除。您可以使用下面的 python 命令从 NLTK 获得停用词列表。
加载和查看停用词

停用词,作者图片- 点击查看完整版本
删除停用词
我们可以创建一个简单的函数来删除停用词并返回一个更新的列表。

停用字词删除前后的文本,按作者排序的图像
标点符号
类似于停用词,因为我们的文本已经被分成句子,删除标点符号可以在没有太多信息损失的情况下执行,并且将文本清理为单词。一种方法是简单地使用标点符号的字符串对象列表。
我们有一个额外的逗号,现在在应用此函数后被删除:

删除标点符号后的文本,按作者排序的图像
词汇化
我们可以通过词汇化来进一步规范我们的文本。这将一个单词归结为词根,这有助于最小化所用单词的唯一数量。这当然是一个可选的步骤,在某些情况下,比如文本生成,这些信息可能很重要,而在其他情况下,比如分类,这些信息可能不太重要。
单字测试
为了对我们的令牌进行符号化,我们将使用 NLTK WordNetLemmatizer 。一个例子是将单词“cry”应用到单词 lemmatizer,得到单词“cry”的词根。
Output text: cry
所有标记/词性
NLTK 函数在特定的词类上运行,所以我们将在一个通用函数中循环遍历这些函数,以对标记进行词汇化。

词汇化前后的文本,作者提供的图像
词干
词干化类似于词汇化,但它不是转换成一个词根,而是去掉后缀和前缀。我更喜欢词汇化,因为它不那么激进,而且单词仍然有效;然而,词干有时也会被使用,所以我在这里展示如何使用。
雪球斯特梅尔
有许多不同风格的词干算法,对于这个例子,我们使用 NLTK 的雪球词干分析器。对“sweeping”应用词干删除后缀,产生单词“sweep”。
Output text: sweep
适用于所有令牌
与前面的步骤类似,我们可以创建一个更通用的函数,并将其应用于每一行。

词干前后的文本,作者的图像
如你所见,有些不是单词。出于这个原因,在几乎所有的情况下,我都倾向于使用词汇化,以便在嵌入过程中更成功地查找单词。
把它们放在一起
我们已经经历了许多可能的步骤来清理我们的文本,并为每个步骤创建了函数。最后一步是将它合并成一个简单的通用函数,在文本上运行。我将这些函数包装在一个组合函数中,允许启用任何所需的函数,并在不同的文本行上依次运行每个函数。下面我使用了一种函数式方法,但是使用类似的原理当然也可以构建一个类。
矢量嵌入
现在我们终于清理了我们的文本,它准备好机器学习了吗?不完全是。大多数模型需要数字输入,而不是字符串。为了做到这一点,经常使用将字符串转换成向量的嵌入。你可以认为这是在一个固定长度的数字向量中获取文本的信息和含义。
我们将浏览一个使用 gensim 的例子;然而,许多深度学习框架也可能有快速加载预训练嵌入的方法。
Gensim 预训练模型概述
我们将用来为我们清理过的令牌查找预训练嵌入向量的库是 gensim 。他们有多个预先训练好的嵌入可供下载,你可以在 word2vec 模块内联文档中查看这些。
最相似的词
Gensim 提供了多种功能来与预训练的嵌入一起使用。一个是查看哪些单词最相似。为了了解这是如何工作的,让我们试试吉米·亨德里克斯歌词样本中的“queen”这个词。

最相似的单词,作者图片
检索矢量嵌入示例
为了将单词转换成嵌入向量,我们简单地使用像字典一样的预训练模型。我们来看看“扫帚”这个词的嵌入向量是什么样子的。

样本嵌入向量,图片由作者提供
应用于所有令牌
与过去的步骤类似,我们可以简单地循环遍历清理后的令牌,并构建一个转换为向量的列表。实际上,对于查找不成功的单词可能会有一些错误处理(由于字典中没有它,所以会导致一个键错误),但是我在这个简单的例子中忽略了这一点。
填充向量
许多自然语言处理模型需要相同数量的单词作为输入。然而,文本长度通常参差不齐,每行都不符合完全相同的字数。为了解决这个问题,一种常用的方法是填充序列。我们可以在较短句子的末尾添加虚拟向量,以使所有内容对齐。
py torch 中的填充序列
许多库都有用于这种工作流的帮助器方法。例如,torch 允许我们以如下方式填充序列。
Output: torch.Size([5, 4, 100])
填充我们的序列后,您现在可以看到这 5 行文本的长度都是 4,嵌入维数为 100,与预期的一样。但是我们第一条只有三个字(令牌)的线清洗后怎么了?
查看填充向量
默认情况下,Torch 只为任何需要填充的内容创建零值向量。

填充零向量示例,作者图片
总结
在为机器学习准备数据时,文本数据通常需要独特的步骤。清理文本对于标准化单词以允许嵌入和查找很重要,同时对于给定的任务丢失尽可能少的信息。一旦你清理和准备了文本数据,它就可以用于更高级的机器学习工作流,如文本生成或分类。
在Github上可以找到所有的例子和文件。
原发布于https://data stud . dev。
预处理文本数据
原文:https://towardsdatascience.com/preprocessing-textual-data-c0527ef8b8c5?source=collection_archive---------28-----------------------
使用 Cleantext 清理文本数据集

真诚媒体在 Unsplash 上拍摄的照片
如果您曾经处理过文本数据集,您必须意识到文本数据带来的垃圾。为了清理这些数据,我们执行某些预处理,这有助于清理和操作数据。预处理是一个重要的步骤,因为它有助于将正确的数据传递给模型,以便模型能够根据需求工作。
某些 python 库有助于执行文本数据集的预处理。一个这样的库是 Cleantext,它是一个开源 python 模块,用于清理和预处理文本数据,以创建规范化的文本表示。
在本文中,我们将探索 Cleantext 及其不同的功能。
让我们开始吧…
安装所需的库
我们将从使用 pip 安装一个 Cleantext 库开始。下面给出的命令可以做到这一点。
!pip install cleantext
导入所需的库
在这一步中,我们将导入清理和预处理数据集所需的库。Cleantext 在后端需要 NLTK,所以我们也将导入 NLTK。
import nltk
nltk.download('stopwords')
import cleantext
预处理数据
现在我们将使用 Cleantext 清理数据。我们将探讨清除数据文件或清除句子这两个选项。
cleantext.clean('Himanshu+-= S$harma WelC@omes!!! you to 123medium', extra_spaces=True, lowercase=True, numbers=True, punct=True)

来源:作者
现在让我们看看如何清理一个文本文件。为此,我们将导入一个文本文件并读取它来执行预处理。
file = open("/content/data.txt", 'rt')
text = file.read()
file.close()
cleantext.clean(text, all= True)

来源:作者
同样,我们也可以对句子中的单词进行清理。下面给出的代码将对单词进行清理。为了清理单词,我们可以使用某些参数,如您将在下面的代码中看到的。
cleantext.clean_words('Himanshu+-= S$harma WelC@omes!!! you to 123medium',
all= False, # Execute all cleaning operations
extra_spaces=True , # Remove extra white space
stemming=True , # Stem the words
stopwords=True ,# Remove stop words
lowercase=True ,# Convert to lowercase
numbers=True ,# Remove all digits
punct=True ,# Remove all punctuations
stp_lang='english' # Language for stop words
)

来源:作者
如果我们想将所有这些参数设置为 true,我们可以通过将所有参数设置为 true 来实现,如下面的代码所示。
cleantext.clean_words('Himanshu+-= S$harma WelC@omes!!! you to 123medium', all=True)

来源:作者
在这里你可以看到我们如何使用 Cleantext 清理文本、句子和单词。这在创建 NLP 模型时会很有帮助,因为我们可以使用干净的文本,这不仅会提高性能,还会有助于实现更高的准确性。
继续尝试使用不同的数据集,并使用 Cleantext 执行预处理。如果您发现任何困难,请在回复部分告诉我。
本文是与皮尤什·英格尔合作完成的。
在你走之前
感谢 的阅读!如果你想与我取得联系,请随时通过 hmix13@gmail.com 联系我或我的 LinkedIn 个人资料 。可以查看我的Github*简介针对不同的数据科学项目和包教程。还有,随意探索* 我的简介 ,阅读我写过的与数据科学相关的不同文章。
规范数据科学 101:问题类型
原文:https://towardsdatascience.com/prescriptive-data-science-101-types-of-problems-and-methods-for-a-single-agent-case-e80cf879ccb6?source=collection_archive---------33-----------------------
关键维度:单个/多个代理|静态/动态问题

弗兰基·查马基在 Unsplash 上拍摄的照片
欢迎回到关于规范数据科学的系列文章!在我的上一篇文章中,我谈到了描述性、预测性和规范性数据科学以及规范性数据科学所需的技能。今天,我将通过定义不同类型的规范性数据科学问题来帮助您。
请注意,本文中描述的方法在多个学科中有许多不同的名称——数学优化、控制理论、单代理动力学、多代理动态博弈、动态规划、马尔可夫决策过程或强化学习。在下一篇关于单个代理案例问题定义的关键要素的文章中,我将指出问题定义和方法的核心关键结构。请注意,在运筹学、经济学、营销科学、计算机科学、机器学习和人工智能等多个学科中,潜在的思想是共同的。
结束时,您将具备以下基本知识:
- 什么是规定性数据科学。
- 两个关键维度定义规范的数据科学问题:代理数量和跨时间段的依赖性
我们如何在规范数据科学中定义不同的问题类型?
规范数据科学是数据科学的一个子领域,它帮助我们获得诸如“我们应该做什么(在潜在的 X 的选择中)?”等问题的答案由于多学科的性质,它没有很好的定义。因此,我打算以一种更结构化的方式来定义它,并介绍将帮助您识别不同规范数据科学问题类型的关键维度。
要对不同类型的规范性数据科学问题进行分类,您需要考虑两个关键因素:(1)代理的数量;(2)跨时间段的依赖性。
-
代理数量。与给定问题相关的代理数量可以是(1)单个(即只有一个代理)或(2)多个。这里的关键区别在于,你是否必须考虑和整合代理之间的(战略)交互来解决你的问题。单个智能体问题更简单,因为你不必考虑其他智能体的行动(即决策)。相反,当你有多个代理时,代理之间的(战略)交互需要成为问题解决的一部分。这将在博弈论中引入“均衡”的概念。此外,定义信息集(每个智能体的已知和未知)对于正确指定多智能体问题非常重要。退一步说,你可以立即看到多智能体问题比单智能体问题更难解决。
举个例子,如果你正在为一个小镇上唯一的超市考虑软饮料的品类利润最大化定价,你不必担心其他超市的反应(即垄断情况)。在这种情况下,只要有一个需求模型(即来自预测数据科学的输出,它将单位体积(作为目标)映射到具有其他控制特征的定价和促销特征),您就可以尝试非线性优化来找出一组价格,该组价格在一年的给定时间(例如,7 月 4 日的一周)最大化焦点超市软饮料类别中每种产品(即,SKU-库存单位)的类别利润。相比之下,如果你在一个小镇上有两家超市,事情就变得复杂多了,你现在需要考虑其他超市会如何做出价格决定。
-
跨时间段的依赖性。跨时间段的依赖性可以是(1)静态的(即没有依赖性)或(2)动态的。这里的关键是你是否可以孤立地解决每个时期的问题(即可分离性),或者你是否需要考虑多个时期来捕捉随时间的依赖性。
作为一个例子,对于城镇中单个超市的类别利润最大化定价决策的情况,可以认为每个时期的定价决策可以被逐一解决,因为现在销售点的价格才是重要的,而不是其他时期的价格。请注意,为了简单起见,我假设了前瞻性消费者行为的潜在复杂性,即消费者可以预期未来的促销,并在价格有利时囤积商品(所谓的加速购买或提前购买)。在一个没有消费者远期购买的简化世界中,频繁购买商品的定价可以被视为一个“静态”问题,因为你可以独立地解决每周的子“定价”问题(即,没有依赖性。)
相比之下,如果你考虑一个小镇上唯一的手机(即耐用消费品)店(如唯一的威瑞森店),你很容易意识到 iPhone 12 Pro Max 当期的定价决策并不独立于从现在起 24 周内的定价决策。消费者非常熟悉耐用品价格会随着时间的推移而下降的事实。此外,还存在异质消费者群体:一些消费者愿意支付额外费用来快速采用新产品(即早期采用者)。其他消费者将等到价格变得有利(即落后者)。因此,使当期利润最大化的价格并不等于使整个时间范围内总利润最大化的最优价格。在这里,由于时间的依赖性,您需要解决问题的一个更“动态”的版本。我们将在本系列文章的后续版本中再次讨论“动态”问题。
如果你受过计量经济学或时间序列方面的培训,当你有滞后项(即以前时期的变量)时,可以引入时间相关性。在结构计量经济学的情况下(在经验工业组织中),带有预期的结构消费者或企业行为模型也自然地随着时间的推移产生依赖性。在运筹学、计算机科学、机器学习和统计学中,隐藏(即潜在)状态模型(如隐藏马尔可夫模型、卡尔曼滤波)或序列模型(如递归神经网络、注意力模型或变压器架构)也会自然地导致长期和短期的时间依赖性。时间相关性的建模方式对后续优化或强化学习问题的解决算法也有重要影响。
下面的图 1 从(1)代理数量和(2)跨时间段的依赖性这两个维度总结了不同的数据科学规范问题。

图 1:图片由黄敏哈拍摄
在随后的文章中,我将重点关注一个“单个代理人”案例和(1)描述关键结构以正确定义问题,这可以通过优化或人工智能算法来解决。此外,我将提供(2)解决“单一代理”问题的关键方法的高级概述。
如果读者对不同学科之间的联系感兴趣,下面显示的是一篇文章,它将 IO 中的结构计量经济学模型映射到 AlphaGo 等人工智能方法。
作为结构估计的人工智能:深蓝、Bonanza 和 AlphaGo
规范数据科学:超越预测数据科学
原文:https://towardsdatascience.com/prescriptive-data-science-beyond-predictive-data-science-51bde1900c1e?source=collection_archive---------28-----------------------
数据科学问题类型|规范数据科学所需的技能集|规范数据科学的关键组成部分

卢卡斯·布拉塞克在 Unsplash 上的照片
数据科学和机器学习的重点主要是预测建模和数据工程。随着公司在数据科学和机器学习方面变得更加成熟和复杂,预测数据科学变得更加重要。在将数据科学和人工智能领域的领导者与其他公司区分开来方面,规范数据科学正变得越来越重要。越来越多的公司要求“做什么”的“规范性”建议传统上,“规范性决策建议”主要由运筹学和经济学政策研究者处理。然而,优化方法和强化学习现在被数据科学家和机器学习工程师作为超越预测建模的核心工具之一。
作为一个个人轶事,当我 7 年前第一次构建分类(即产品线)决策支持解决方案时,当我们添加或删除某些产品时,零售商拥有的产品组合的产品单位销售预测模型被认为是最先进的。业务用户很高兴能够基于预测模型运行场景分析和模拟,以进行批量转移。随着他们变得越来越老练,他们开始询问关于在货架空间限制下删除和添加什么产品的“说明性”建议。这表明,一旦业务最终用户熟悉了(预测性的)基于模型的模拟,就越来越需要推荐“做什么”。预测模型和用于说明性建议的优化方法之间也有密切的相互依赖性。因此,现在是学习更多关于规范数据科学和关键方法的好时机。
在本文中,我将讨论(1)不同类型的数据科学及其与数据科学和分析中的组织成熟度的相关性,(2)在规范数据科学中脱颖而出所需的技能集,以及(3)规范数据科学的关键组成部分和常见误解。
1。数据科学之旅—描述性、预测性、规范性
不同类型的数据科学的业务需求随着组织的分析成熟度而变化。最初,重点是为日常业务决策提供更多的“事实基础”。相关的业务问题是“发生了什么?”或者“这是怎么回事?”例如,一家零售商在过去开展了许多不同类型的促销活动,该公司希望了解每次促销活动的投资回报率,以及哪种促销类型带来了更多的增量利润。
一旦一个组织在其数据科学之旅中变得更加分析成熟,业务问题就演变为对未来的规划。这里的商业问题是“如果我们改变 X,Y 会发生什么?”例如,一家零售商正在计划黑色星期五促销活动,该公司可能会考虑一组促销方案作为候选方案。预测数据科学可以帮助在不同的推广场景下进行预测。
拥有预测能力固然很好,但大多数组织会意识到要考虑的选项太多了。在这个阶段,商业问题是“我们应该做什么(在 X 的选择中)?”例如,零售商希望有一个促销推荐引擎,该引擎给出关于以什么折扣级别(50%对 30%)、在什么时间(7 月的第二周)、在什么位置(丹佛)、以及什么产品(可口可乐普通 2L 单瓶)运行什么促销活动(例如,买 2 送 1 50%)的推荐。
下面的图 1 总结了组织在数据科学方面的成熟度。请注意,相关的数据科学工具包也会在这个过程中发生变化,如此图所示。

图一。图片由黄敏哈
2。规范性数据科学:所需技能组合
当公司越来越关注“规范的数据科学”时,数据科学家需要哪些技能许多读者可能已经熟悉数据科学家的 3 个技能要求圈:(1)业务领域知识,(2)统计/机器学习(ML) /人工智能(AI),以及(3)软件工程。对于“规范的数据科学”,要成为更有影响力的数据科学家,还需要“优化”方面的额外技能。“最优化”通常属于“运筹学”或“工业工程”的范畴请注意,典型的数据科学课程不会深入讨论这个主题。下面的图 2 显示了下一代数据科学家技能要求的 4 个主要方面,每个方面都有更多详细信息。

图二。图片由黄敏哈提供
3。规范数据科学的关键组成部分和常见误解
什么是“优化?”说明性数据科学的“(数学)优化”的关键组成部分是什么?关于“规范数据科学”或“优化”的定义有很多混乱如果读者还不太熟悉(数学)优化,我将在下面描述优化的关键组成部分。此外,我还展示了什么不是“规定的数据科学”
- (1) 目标(功能):这是业务用来评估业务成果的性能的量化度量。大多数时候,总利润(即底线)和总收入(即最高收入)是优化中经常出现的目标。但是,根据相关的时间范围和业务问题的性质,也可以考虑其他业务指标,如客户终身价值。另请注意,可能有多个重要性不同的目标(例如,80%的利润+ 20%的收入)
- (2) 决策变量:这是公司可以改变的一组变量。例如,在零售商的“联合价格优化”(即,定价优化)中,给定类别中 10 种产品(例如,糖果)的一组价格是决策变量。
- (3) 约束:通常情况下,企业有一套业务规则或防护栏,需要考虑这些规则或防护栏,以便对业务活动提出最终建议。在优化的初始尝试之后应用这些规则是非常常见的,这具有超越优化结果的意外后果。更合适的方法是将这些规则集作为“约束”合并到约束优化中。这些规则可以作为“上限/下限”约束、“相等”约束或“不相等”约束进入。例如,在“联合价格优化”问题中,由于零售商和制造商之间的合同协议,或者由于简化商业决策的需要,一组产品可能需要具有相同的价格,即所谓的“系列定价”该行定价规则可以作为“约束定价优化”问题的“等式”约束输入。如果产品 1 的价格应该与产品 2 的价格相同,这可以指定为:价格(产品 1) =价格(产品 2)。如果零售商不愿意在当前价格水平上提价 10%以上,这可以作为提价的上限:即价格(产品 1) ≤ 1.10 x 当前价格(产品 1)。
下面的图 3 总结了“规范数据科学”(即数学优化)的关键组成部分。)此外,还说明“不是什么。”

图 3。图片由黄敏哈提供
我希望这篇文章能帮助您更好地理解数据科学之旅,了解组织在数据科学方面的成熟度、规范数据科学的附加技能集、“预测数据科学”的关键组成部分是什么,以及不是什么。在下一篇文章中,我将概述不同类型的优化方法以及可用的数学和分析技术。如果您是一名 Python 数据科学家,那么 SciPy 是“规范数据科学”的一个很好的起点。优化库。
- SciPy。优化链接
https://docs.scipy.org/doc/scipy/reference/tutorial/optimize.html
从杜波依斯的数据可视化中得到的教训
原文:https://towardsdatascience.com/present-to-persuade-lessons-from-the-data-visualizations-of-w-e-b-du-bois-a50775f0fa90?source=collection_archive---------26-----------------------

去向不明的就业数据是代表真实劳动力的必要数据
杜波依斯用数据提供了一个不同于普遍观点的观点,即黑人和白人是不平等的。他成功地以新颖、引人注目的方式获取并展示数据,以改变观众的视角。
意识到传统图表的局限性,他设计了非典型的数据可视化形式来展示他的案例。这使他能够影响大量的欧洲和全球观众。对于任何旨在与其他团队(从不同部门到执行委员会)建立凝聚力的数据科学专业人员来说,这都是必不可少的历史研究。
二十世纪的问题是肤色界限的问题,是关于种族差异——主要表现在皮肤的颜色和头发的质地上——会在多大程度上成为剥夺世界上一半人最大限度地分享现代文明的机会和特权的基础的问题——w·e·b·杜·博伊斯
我主持了与麦肯锡公司 COVID 响应中心交互数据可视化总监 Jason Forrest 以及富国银行业务系统和运营数据分析师 Jarrett Hurms 的炉边谈话。
他们讨论了 Du Bois 在社会进步背景下对数据科学领域的长期贡献,以及他以新颖、引人注目的方式获取和呈现数据的策略,这些方式影响了我们的现代社会氛围。
如果还需要 观看网上研讨会 。
数据可视化是人类和机器交流大量复杂信息的工具。这种形式的交流延伸到各个行业,从非营利组织和政府实体到商业组织和医疗保健。
数据可视化最有力的例子之一是 120 年前由 W.E.B. Du Bois 领导的一个非裔美国人小组做出的,当时美国奴隶制刚刚结束 37 年。
下面,我重述一下 Jason 和 Jarrett 讨论的核心主题,作为对进一步研究杜波依斯开创性工作感兴趣的人的介绍。

杜波依斯以一种能被不同种族和经济背景的人所理解的方式展示数据。杜波依斯为非裔美国人提供了另一种视角,试图通过展示黑人加强美国的能力来启发他的观众。他意识到传统形式的图表的局限性,并热衷于使用不寻常的数据呈现形式来吸引观众的注意力。
杜波依斯的开创性工作在 1900 年的巴黎博览会上展出。请记住,《解丨放丨宣丨言》是在 1863 年刚刚签署的。该博览会是为了庆祝 19 世纪的成就,并寻求在下一世纪加速创新。包括美国在内的 56 个国家建造了代表各自文化的展馆。参观者达 5000 万人,展品首次展示了许多发明,如摩天轮、柴油机、自动扶梯,甚至有声电影。
就在博览会开幕前四个月,美国国会图书馆助理馆长丹尼尔·默里和他的团队从美国国会获得 15000 美元。杜波依斯被选为首席策展人,并于 1899 年 12 月 28 日和他来自亚特兰大大学的学生一起开始快速编纂这部作品。
美国黑人的展览分为两部分,展示了杜波依斯的数据可视化:
- 佐治亚州的黑人,集中在佐治亚州,拥有第二大非裔美国人。对于一些额外的背景:“佐治亚州黑人”是一个社会研究汇编 32 手工图表。
- 一系列统计图表显示了现居住在美利坚合众国的前非洲奴隶后裔的状况。
杰森指出,这次展览是一次有针对性的尝试,旨在影响世界科学精英承认美国黑人,并试图影响美国国内外的文化变革。
在晚年,杜波依斯回忆了围绕完成世界博览会作品的意外事件和困难,以及几乎阻止他参加自己展览的财务状况:
“用很少的钱、有限的时间和不太多的鼓励,精确地完成这 50 多张彩色图表的细节是非常困难的。在我完成之前,我就受到了神经衰弱的威胁,我几乎没有钱去买去巴黎的机票,也没有一个船舱可以出售。但是如果我不去,展览就会失败。所以在最后一刻,我买了统舱的通道,过去安装工程。”
—杜波依斯
然而,他还是及时赶到,迅速布置好展览,并从评委那里赢得了一枚金牌。当美国黑人媒体兴高采烈地报道这次展览时,欧洲媒体只是顺便提及这次展览,而美国白人媒体完全忽视了这次展览。美国公众从来不知道美国黑人展览的存在。

杜博伊斯在社会科学和数据可视化方面的作用与他更伟大的成就相比仍未得到充分发掘。他看到了种族隔离的复杂性,这从根本上改变了美国黑人的代表性。
他通过用严格的科学方法收集令人信服的证据来支持社会进步。他综合了来自多个来源的数据,并使用生动的数据画像,用定性事实来说明他的论点。他的展览不仅仅是一份科学报告;他们通过终结陈规定型观念,展现了一个现代的、成功的、受过良好教育的黑人形象,体现了“有针对性地试图影响世界精英阶层”的努力。
如果您有兴趣了解更多关于 W.E.B. Du Bois 数据可视化的信息,请查看以下资源:
- 由 Thinknum Alternative Data 主办的杜波依斯网络研讨会录制
- 杜波依斯的数据可视化和研究,由杰森·福里斯特策划
再次特别 感谢 杰森和贾勒特(Jsquared)。有了他们勤奋的研究和评论,这篇文章就不会存在了。谢谢先生们!让我们继续对话,传播福音。
我们来连线!
杜·博伊斯为 1900 年巴黎世界博览会美国展区的黑人展览绘制的图表,展示了解放以来美国黑人的经济和社会进步。
由 LinkDap 为您带来的基础知识回顾。
将机器学习模型结果呈现为业务洞察
原文:https://towardsdatascience.com/presenting-machine-learning-model-results-as-business-insights-b42309c5e974?source=collection_archive---------10-----------------------
行业笔记
如何将机器学习模型的性能作为可操作的见解提供给企业。

雷雨云下的麦田,1890 年,荷兰阿姆斯特丹(来源)
机器学习和深度学习是我们这一代最具革命性的技术,有可能从根本上重新定义我们的生活方式。随着围绕技术堆栈的大肆宣传,它通常会有自己的生命,并且很容易忘记它最终只是为我们以客户为中心的业务增加价值的另一个工具。
作为一名机器学习工程师,我已经在世界上最大的银行之一工作了两年多,如果我能用几句话来总结我的经验,那就是。
“如果你不能用一句话写下你的信息,你就不能在一个小时内说出来。”-缔安娜·布赫
对于任何与他们的企业或客户一起工作的工程师来说,他们既不关心你使用了什么样的技术,也不关心你的解决方案有多复杂,而只关心这个解决方案能给他们的企业增加多少价值。
在这个意义上,通过这个指南,我将努力向你介绍一些我在向企业介绍我的工作时经常使用的方法,这些方法取得了一定程度的成功。
第 1 部分:秀出来,不说出来。
Salesforce 花费超过 150 亿美元收购一个名为 Tableau 的数据可视化/报告工具是有原因的。随着时间的推移,一张图的价值远非千言万语所能表达。
让我们看看几种展示您的结果的方法。
收益图表

增益图表表示模型的累积错误捕获率。(图片由作者提供)
当您处理产生连续概率得分的模型时,增益图是一个非常有用的工具,因为这些值可以排序和累积,以显示与随机情况相比,您使用该模型能够捕获多少事件。
例如,在这种情况下,我们可以看到我们的模型能够捕获前 20%得分数据中的 80%的事件,这意味着如果一个企业只关注总得分前 20%的观察,它可以使用您的模型捕获高达 80%的事件。
这有助于企业了解你的模式带来的价值,以及它如何帮助他们做出更好的决策。
真实值与预测值分布。

绘制预测值的分布与真实值的分布。(图片由作者提供)
当使用回归模型时,向业务团队展示您的模型结果通常会很棘手,因为您不希望他们经历所有的残差分析和多元分析。
真实值与预测值的重叠分布直方图是一种很好的方式来展示模型结果与现实的比较。这将有助于企业了解您的模型是否足以取代现有的系统。
第 2 部分:测量机器学习模型中的投资回报率
仅仅因为你有一个伟大的模型,一个惊人的技术堆栈和一个完全可靠的产品设计,并不意味着企业欠你批准资金来建造它,我学到了痛苦的方式,你不应该。
向企业展示任何产品设计或模型设计时,都要进行成本效益分析。不管你的模型有多酷或有多有创意,如果它不能证明成本是合理的,没有人会批准它。
2006 年,网飞花费 100 万美元资助了一项竞赛,旨在为他们的电影推荐系统寻找一种改进的解决方案,但最终甚至没有使用所展示的最先进的解决方案,因为“额外的工程和维护成本并不能证明准确性的提高”。

网飞竞赛。(来源)
理解混乱的代价
要计算简单二元分类器的成本与收益,您可以查看混淆矩阵并为每个像元赋值。

客户流失预测模型的混淆矩阵(图片由作者提供)

分类报告(图片由作者提供)
考虑一下这个例子,您的任务是为一家信用卡公司构建一个模型来预测客户流失。你很兴奋,很受鼓舞,继续为他们建造一个美丽的作品,结果和这个差不多。
现在一些商业分析师为你做成本收益分析,让我们看看他们发现了什么。根据他们的分析,公司在预测期内每个客户的收入损失和其他成本约为 20,000 美元(误报成本),一旦模型到位,公司试图留住客户的成本约为 1,000 美元(误报和真报成本)。让我们看看你的模型做得怎么样。

你的公司最终将亏损 100 多万美元。(图片由作者提供)
现在,当然我操纵了一些数字来得到结果,但重点仍然是,我仍然忽略了整个事情的工程和维护成本。关键是,有时机器学习不是解决方案,或者至少不是最可行的解决方案。
作为一名机器学习工程师,如果你学会如何在项目早期计算出最低可行性能,将会对你有很大帮助。

AI 在企业中的状态(来源
第 3 部分:成为解决方案的一部分
不管你的最终结果是什么,总是要提供一份关于下一步的建议清单。你的工作是解决问题,而不仅仅是发现和评估问题。这也显示了你超越自己工作领域的能力。
如果你的模式可行并且在经济上可行。
- 建议产品开发路线图和时间表。
- 如何让现有团队/基础架构参与进来以降低成本。
- 未来的版本可能会带来哪些改进?
如果你的模式不可行。
- 推荐几款市面上现成的产品。
- 与模型相比,基于规则的解决方案的表现如何。
结论
除非你是 ML/DL 研究员,否则展示你的解决方案将是你工作的一大部分,就像任何其他工作一样,这是你将通过实践学习的东西。你越早掌握演讲技巧,你的旅程就越顺利。
如果你喜欢这篇文章。
留下评论让我知道你的想法。
在 Twitter 、 Linkedin 、 Github 或 Medium 上与我联系。
与你的网络分享这篇文章。
保持非线性数据集的测地线距离:ISOMAP
原文:https://towardsdatascience.com/preserving-geodesic-distance-for-non-linear-datasets-isomap-d24a1a1908b2?source=collection_archive---------15-----------------------
思想和理论
等距特征映射的解释和说明
降维方法可视化数据集并减小其大小,以及揭示数据集中的不同特征。对于非线性数据集,可以在各种子标题下检查降维,例如距离保持(等映射)、拓扑保持(局部线性嵌入)。本文解释了等距特征映射的理论部分,这是一种距离保持的非线性降维方法,并包括降维后获得的数据集的解释和使用范围。python 实现丰富了研究。

照片由大流士巴沙尔在 Unsplash 上拍摄
***Table of Contents* 1\. Isometric Feature Mapping (ISOMAP)
- Geodesic Distance vs Euclidean Distance
- Interpretation of the result of ISOMAP
2\. ISOMAP Algorithm
3\. Use Cases
4\. Python Tutorials
5\. References**
1.等距特征映射(ISOMAP)
Isomap 是一种非线性降维方法,是度量 MDS 的不同版本,在保持测地线距离的同时降维。公制 MDS 和 ISOMAP 最明显的区别:欧氏距离在公制 MDS 中保持不变,而测地线距离在 ISOMAP 中保持不变。那么,我们为什么需要它呢?保留测地线距离是否更有效?让我们看看图 1,比较测地线距离和欧几里德距离作为降维技术。

图一。欧几里德距离与测地线距离[1]
欧几里德距离通过忽略数据集的形状仅计算距离,测地线距离通过传递数据集上的最短路径来计算。在这种情况下,我们可以粗略地说,测地线距离和欧几里德距离的区别;虽然测地线距离考虑了与这些数据相邻的数据,但在欧几里德距离中,它仅计算最短的线性路径。当然,由于我们的目标是以最小的损失降低数据集的维数,因此根据数据集使用测地距离可以获得更有效的结果。以下代码块显示了 isomap 在 Swiss roll 数据集上的基本实现:
查看 ISOMAP 和 MDS 结果,可以看到瑞士卷可以通过使用 ISOMAP 展开。

图二。通过使用 MDS 和 ISOMAP 展开瑞士的角色,图片由作者提供
红色数据点在图 2(右)中显示为 ISOMAP 结果,考虑了它们之间的邻域距离。当计算两点之间的欧几里德距离时,获得最短的距离(直线距离)。在测地距离中,获得经过数据集的最短路径。为了找出这一点,确定 k 的某个值,并且通过邻居将 k 最近的彼此连接,并且链继续。在 Sklearn 库中提供的 ISOMAP 中,可以用n_neighbors=5来设置。默认值为 5。寻找最短路径的另一种方法是以初始数据为中心画一个圆,并通过一条边将每个数据点连接到圆内的所有其他数据点。
测地线距离与欧几里德距离
为了总结测地距离和欧氏距离的区别,我们来看看它们的变换形式。图 3 示出了应用欧几里德距离和测地线距离的肿瘤组织的比较。

图 3。肿瘤的 CT 扫描(左),欧几里德距离(中),测地距离变换(右),[2]
在图 4 中,相同的程序被应用于受损的大脑区域并进行比较。

图 4。欧几里德距离和测地线距离的比较[2]
从上面的图像中可以看出,在图像数据集中,测地线距离可以比欧几里德距离更有效地进行区分。在图 4 中,测地线距离已经应用于大脑区域图像,但是可以看出,由于图像的结构,测地线距离变换可以非常方便地用于 google earth、street 和 city 数据集。
对 ISOMAP 结果的解释
ISOMAP 应用于合成人脸数据集,结果如图 5 所示。

图 5。应用 Isomap 后的合成图像数据集[3]
当查看图表时,可以看到图表右侧的图像看向右侧,左侧的图像看向左侧,上侧的图像向上看,下侧的图像向下看,因此面部转向光线方向。另一种方法是,当查看此图时,可以很容易地确定拍摄照片的相机的位置。例如,在图表的左侧,摄像机在右侧,在右侧,摄像机在左侧,在顶部,摄像机在底部,在底部,摄像机在顶部。当然,这些方法对于该数据集是可接受的,并且每个数据集被单独解释。简而言之,也是解释 ISOMAP 数据集的一种非常方便的方式。
2.ISOMAP 算法
- 如上所述,首先构建加权图-找到每个样本的最近邻居-这通过两种方式完成:
- k 个最近邻居
- 固定半径,定义半径值,并对半径值内的样本进行分组。
在应用上面的其中一个后,最近邻通过加权边连接。这些权重(在邻居之间)将是欧几里得距离。到目前为止,创建了样本之间的全连接加权图。
2.使用 Floyd Warshall 算法或 Dijkstra 算法,使用测地线距离计算全连通加权图中所有样本对的成对距离。
3.应用多维标度(MDS)来获得低维版本。
以下视频解释了如何使用 Floyd- Warshall 算法找到最短路径:
作为算法的一个限制,如果 k-最近邻或固定半径太小,加权图可能会中断而不是完全连通。如果 k 值或固定半径太高,这一次加权图可能太密集;这会导致在流形中选择错误的距离。
3.用例
Isomap 可用于医疗领域,使超声和超声心动图图像在消除噪声后更易于解读。流形学习算法被应用于二维超声心动图图像,以发现心脏运动的连续周期的帧之间的关系。[4]在这种方法中,每个图像可以通过 Isomap 算法由重建的二维流形上的一个点来描述,并且相似的点可以根据周期性心跳周期的性质与相似的图像相关联。[4]
在一项研究中,ISOMAP 用于在视频帧之间插入图像。通过将 ISOMAP 应用于视频中的每一帧,在低维中提取有意义的特征。为了在 2 帧之间插入新图像,从原始数据集中选择图像,这些图像被映射到与这 2 帧相同的区域中。[5]
可以阅读参考资料中引用的文章,以了解有关上述用例的更多信息。
4.Python 教程
- 在下面的代码块中,Isomap 应用于
fetch_lfw_people数据集中的面,结果如图 6 所示。
数据集许可: BSD-3 条款许可
与上面的合成数据集示例一样,人脸根据光线进行分类。

图 6。ISOMAP 后的影像数据集,按作者分类的影像
- 在下面的代码块中,Isomap 已经被应用于
MNIST数据集中的数字 9,结果如图 7 所示。
数据集许可: BSD-3 条款许可
可以看到,图表左侧数字 9 的尾部向右倾斜,当您在图表中向右移动时,数字 9 的尾部从右向左移动。同样,虽然尾巴在顶部很短,但从顶部到底部会变长。

图 7。应用 ISOMAP 后数字 9 的定位,图片作者
https://ibrahimkovan.medium.com/machine-learning-guideline-959da5c6f73d
5.参考
[1] M. Jordan 和 J. Kleinberg,非线性降维。2007.
[2]“kimvwijnen/Geodesic _ Distance _ Transform:(测地线)距离变换遵循 Toivanen 等人(1996 年)。”https://github.com/kimvwijnen/geodesic_distance_transform(2021 年 10 月 25 日访问)。
[3]“非线性降维的全局几何框架|请求 PDF。”https://www . researchgate . net/publication/285599593 _ A _ Global _ Geometric _ Framework _ for _ Nonlinear _ Dimensionality _ Reduction(2021 年 10 月 25 日访问)。
[4] P. Gifani,H. Behnam,A. Shalbaf 和 Z. A. Sani,“使用 Isomap 算法降低超声心动图图像的噪声”, 2011 年第一届中东会议。生物医学。英语。MECBME 2011 ,第 150–153 页,2011,doi:10.1109/mec BME . 2003032005
[5] S. ROBASZKIEWICZ 和 S. EL GHAZZAL,“使用非线性降维在视频帧之间内插图像”,第 x 期,第 5 页,[在线]。可用:http://cs 229 . Stanford . edu/proj 2012/ElGhazzalRobaszkiewicz-interpolatingimagesbetweendideoframesusinglinearityreduction . pdf .
使用 SpaCy 和 Keras 文本矢量化的预训练单词嵌入
原文:https://towardsdatascience.com/pretrained-word-embeddings-using-spacy-and-keras-textvectorization-ef75ecd56360?source=collection_archive---------6-----------------------
在 Keras 深度学习模型中使用 SpaCy 预训练的嵌入向量进行迁移学习。此外,奖金,如何使用文本矢量化添加一个预处理层到您的模型,以标记化,矢量化,并在嵌入层之前填充输入。

照片由亚历山德拉在 Unsplash 拍摄
在本文中,您将学习如何使用 SpaCy 嵌入向量为 Keras 中的自然语言处理模型创建预训练嵌入层。这减少了 NLP 模型的训练时间,并转移了从更大的模型中学习单词及其关系。
话
词汇构成了我们大多数人生活的世界的大部分。如果你正在读这篇文章,我敢打赌你每天大部分时间都在和文字打交道,无论是写作、阅读、口语还是听力。我可能是错的,但这对我们许多人来说是真的。随着 AI 学会与人类互动(为我们服务,记住,永远为我们服务!)它必须学会理解我们的语言。
我们的语言是由单词组成的。我谅你也不敢想象没有语言的生活。灯不是灯,天不是天,人没有名字。我甚至不知道没有文字我怎么能把一个想法联系起来!词语将我们与世界联系在一起,并给我们一些符号来代表我们对世界的看法。“树”正在“倒下”。有数十亿棵树,但在我们为它们创造一个词之前,它们都是独一无二的。用“树”这个词,我可以概括为任何树。用‘坠落’这个词,我可以向你传达对你来说很重要的东西。让开!
自然语言处理
计算机不像我们一样用文字思考,而是用数字思考。不要纠结于计算机是否会“思考”;这不是我的重点。为了让计算机能够使用预测模型的语言…或者你可以说“理解”单词,这些单词必须被翻译成数字。
NLP 研究人员很聪明,是跨学科的。他们必须了解语言学家和工程师,他们已经开发了几种将单词转化为数字的方法。这个过程被称为“向量化”,将语言转化为向量(一维数组)。单词嵌入是做到这一点的一种方法。
我的项目
让我告诉你一些我正在做的项目,这样你就能理解我在这篇文章中所做的选择。我正在构建一个回归变量,来估计一篇学生作文的适当分数。我说的年级不是指 A、B、C、D、f,我指的是幼儿园、一年级、二年级等等。
这个项目的数据收集一直很慢,我的数据集少得可怜。然而,我的模型惊人地准确,许多估计平均在学生实际成绩的 2 个等级内。这是一个开始。我在下面的要点中包含了一个到我当前数据的链接,但是这个数据集将会增长(希望如此)。对于您自己的项目,您可能会找到更好的数据,所以只需调整text = pd.read_csv(<link here>)以指向您的数据所在的位置。
矢量化和嵌入
计算机模型不理解文字,只理解数字。我们的文档需要从字符串转换成向量。
有几个很好的策略可以将文档转化为向量。count-vector 通过文档中有多少单词来描述文档,而 TF-IDF 矢量化使用浮点数来描述每个单词对该文档的具体程度。因为我的项目是关于写作风格本身,而不是写作的内容,但是,我不会使用这些。虽然他们保留了每个文档中使用的词汇的信息,但这些策略抛弃了单词之间的顺序和关系。
把...嵌入
另一方面,在单词嵌入中,单词被“嵌入”在 n 维空间中,其中 n 是开发者定义的值。由向量数组中的每个位置表示的每个维度都映射到单词之间的某种关系。如果你查看下图,你可以看到高维嵌入空间的 3D 切片,突出显示特定的单词关系。左边的一个维度代表“二元性别”,右边的另一个维度代表国家和首都之间的关系。

图片来自谷歌机器学习速成班
单词嵌入理想地保留了单词之间的语义关系,并允许深度学习模型按顺序考虑文本。然而,还有另外一个步骤。
为嵌入准备数据:标记化、矢量化和填充序列(一步完成!):
在我们的嵌入层可以嵌入我们的单词之前,我们需要准备它们。每个文档都需要作为固定长度的向量整数传递给嵌入层。
符号化

照片由莎伦·麦卡琴在 Unsplash 拍摄
为建模准备文本的第一步是标记文档。在这一步中,通过将包含许多单词的文本字符串(如句子或文档)转换为单个单词的列表来分离单词。
标记时:
'A machine will never replace a teacher.'
将被替换为
['A', 'machine', 'will', 'never', 'replace', 'a', 'teacher.']
在这一点上,删除标点符号,使单词小写,删除常见的单词,如“the”和“a ”,以及类似的其他文本特定的转换通常是有用的,这将有助于模型专注于重要的内容。否则,模型会对每个单词进行不同的处理。你的模型知道‘a’和‘an’,‘Run’和‘Run’,或者‘之间的区别并不总是很重要和“:”。如果在这一点上它们没有被标准化,它们可能会分散以后模型的注意力,并增加计算负荷。
因为我想在模型的输入向量中包含语法信息,所以我不想删除停用词或使词词条化。我的模型需要知道学生如何使用单词,以及他们使用的单词的形式。
矢量化
接下来,需要将标记化的单词编码为整数。当编码序列被传递到嵌入层时,它们将被用作索引来查找单词在嵌入层中的正确嵌入。
在这一步中,我想要的是:
['a', 'machine', 'will', 'never', 'replace', 'a' 'teacher']
替换为类似于:
[2, 427, 34, 67, 89, 2, 245]
这里有趣的一点是,嵌入层实际上会给表示文档的向量增加一个维度。想象一下,输入序列中的每个整数“单词”,即编码的文档,在表示该单词的嵌入向量的一侧长出一条尾巴。所以,这是一个向量的向量,一个矩阵。
填充序列
大多数模型的所有输入都必须具有相同的形状,但是我们语料库中的文档都有不同的长度。作为人工智能工程师,你需要决定你想要用来表示你的文档的序列的长度。它可能是最大文档长度,或者平均文档长度,或者对您的用例有意义的其他选择。我的学生文本不是特别长,所以我将使用最大文件长度作为我的序列。如果矢量化序列的长度小于最长的文档,此图层将截断过长的文档。对于短于序列长度的文档,层将用 0 填充空白空间。0 是“无字”的专用保留代码。
假设我将序列长度设置为 15。由于上面的文档示例只有 7 个单词,
'A machine will never replace a teacher'
它将被编码和填充为:
[2, 427, 34, 67, 89, 2, 245, 0, 0, 0, 0, 0, 0, 0, 0]
我们实际上可以就停在那里,这将是一个非常可行的方法来矢量化我们的文档以移交给模型。技术上不需要进一步的嵌入层。许多 NLP 问题可以通过传递这些填充序列来解决。然而,我想在单词之间嵌入预先训练的语义关系,以帮助我的模型更好地考虑单词的含义。
Keras 文本矢量化图层
Keras 有一个实验性的文本预处理层,可以放在嵌入层之前。总之,它允许将各种大小的文档传递给模型。 TextVectorization 层将标记化、矢量化并填充表示那些要传递给嵌入层的文档的序列。它也可以用作整数索引来告诉嵌入层哪些整数编码字代表哪些嵌入向量。
通常需要更广泛的预处理,比如词汇化、词干化、词性标注等等。如果我想做比上述更多的预处理,我会使用自然语言工具包或 NLTK 包。毕竟,NLP 的真正艺术在于预处理。
但是对于我们的目的来说, TextVectorization 提供的服务已经足够了。
嵌入层
可训练嵌入
既然我们的文本存储在单词索引的填充序列中,就可以传递给嵌入层了。嵌入层可以通过与模型其余部分相同的学习算法来学习文档语料库中单词之间的关系。它们通常是深度 NLP 模型的工作马,可以有数百万个权重(词汇长度*嵌入向量长度)。
转移嵌入
但是…我们为什么要做训练一个嵌入层的工作呢?事实上,已经有几个高性能的嵌入式词典问世了。Word2Vec 、 GloVe 和 SpaCy 是一些要考虑的。这些都是在比我们拥有的更大的计算机上训练出来的,花费的时间也比我们可能愿意投入的要多。这里的问题是你希望你的嵌入矩阵表示什么样的语义表示?您希望嵌入是特定于您的语料库的,还是更普遍地适用于整个语言?还要考虑你用于训练的时间和计算资源。
如果你能处理或受益于更一般的嵌入,预训练嵌入将大大减少你的训练时间。从本质上来说,每一个都是从单词到向量的字典。字典的大小取决于你想要嵌入多少单词以及你想要嵌入向量的长度。斯坦福大学的天才们在淫秽电脑上训练了多年的最大的字典几乎有 10 亿字节。
将嵌入字典转换到嵌入层
如果您想要在您的模型中使用其他人训练过的嵌入,您将需要从单词索引创建一个映射, TextVectorizer 层使用该映射将您的词汇表编码为来自您的嵌入字典的单词嵌入向量。
嵌入层将查看由文本矢量器传递的中每个单词的索引整数,使用它来查找嵌入,然后将输入序列中每个单词的嵌入传递给下一层。TextVectorizer.get _ vocabulary()返回的词汇表中每个单词的索引位置也是text vector将为每个单词返回的编码。接下来,我们将创建权重矩阵,用于初始化嵌入层。我们通过循环使用文本矢量器词汇表和嵌入字典中的单词来实现这一点。来自文本矢量器的每个单词编码将是权重矩阵中的一个行索引,该单词的向量将是我们选择的嵌入字典中的向量。
我将使用空间,因为嵌入比手套加载快得多。代码将类似于:
for i, word in enumerate(vectorizer.get_vocabulary()): embedding_matrix[i] = embedding_dictionary[word]
您将把这些权重设置为不可训练的,以减少计算量。
空间
Spacy 太牛逼了!!它能做的事情太多了,从词汇化和嵌入到为单词创建词性标签和为句子创建句法树。我只是在这里使用它训练过的单词嵌入,但它做得更多。例如,对于另一个项目,我可能会通过使用 SpaCy 的内置方法来使用句子级嵌入向量(单词向量的平均值)。一定要看看 SpaCy 能为你的 NLP 项目做些什么!
下面是完整的代码,带你从零开始预测学生的成绩水平(中等成功)。
偏见
这有点离题,但我认为是重要的。我们讨论了一个单词的嵌入如何定义它与其他单词的关系,作为概念化的一种替代。研究人员发现,自然语言处理模型往往带有种族主义和/或性别歧视,因为种族主义和性别歧视根植于我们的语言和我们使用语言的方式中。这种偏见真正吸引人的地方在于它是可以量化的!熟练的建模者可以找到种族主义的维度并将其展平,从而有效地降低嵌入向量的维度。这有助于消除嵌入空间中有偏见的单词关系。事实上,从伦理上讲,这是每个聊天机器人开发者都应该考虑的问题。
Jerry Wei 在他们的文章中对此做了更多的讨论:自然语言处理(NLP)中的偏见:一个危险但可以解决的问题
总结:
在本文中,您学习了如何使用 SpaCy 和 Keras 构建一个带有文本矢量化层和预训练嵌入层的自然语言处理模型。你也看到了我的项目的一个片段,教一个阅读学生写作的模型,作为 Github 的要点,让你开始自己的 NLP 项目
请享受以上要点,并把它作为你自己项目的起点。我的 NLP 项目还没有完成,所以我不会把它链接到你,但是如果你够聪明的话,你可以根据我在这里提供的提示自己找到它。
一如既往,请让我知道你的想法,这对你的启发,以及你的任何问题或评论。快乐造型!
进一步学习:
为什么要使用嵌入层超过 NLP: https://towardsdatascience . com/deep-learning-4-embedding-layers-F9 a 02d 55 AC 12
如何从 NLTK 中获得更多: https://www.guru99.com/nltk-tutorial.html
空间的魔力: https://real python . com/natural-language-processing-SpaCy-python/
美化熊猫数据框
原文:https://towardsdatascience.com/prettifying-pandas-dataframes-75c1a1a6877d?source=collection_archive---------6-----------------------

照片由帕韦尔·切温斯基在 Unsplash 拍摄
入门
通过颜色编码来增强你的数据框架
你知道我们可以通过访问.style属性来美化熊猫数据帧吗?这里有一个例子,我们设计了一个数据帧,使其类似于热图:

作者图片|造型前后的关联矩阵
造型后,看起来更加明显和直观,以看到积极和消极的相关性以及相关性的强度。通过颜色编码,我们可以更容易地解释和分析数据框架。在这篇文章中,我将展示 4 种美化数据框架的有用方法。

Anna Kolosyuk 在 Unsplash 上的照片
0.数据📦
在这篇文章中,我们将使用企鹅数据集。让我们导入库和数据:
import numpy as np
import pandas as pd
pd.options.display.precision = 2
from seaborn import load_dataset# Load sample data
columns = {'culmen_length_mm': 'length',
'culmen_depth_mm': 'depth',
'flipper_length_mm': 'flipper',
'body_mass_g': 'mass'}
df = load_dataset('penguins').rename(columns=columns)
df.head()

加载数据时,为了简洁起见,列名被重命名。
1.美化✨的数据框架
为了样式化数据帧,我们需要访问返回 Styler 对象的.style属性:
type(df.style)

这个 Styler 对象创建了一个 HTML 表格,可以使用 CSS 对其进行进一步的样式化。在接下来的章节中,我们将使用 Styler object 的内置方法以及一点 CSS 语法来定制格式。我们不需要知道 CSS 来样式化数据帧,因为我们将只做一些 CSS 引用。为此,像和这样的备忘单可以帮助我们获得基本信息。
在下面的部分中,我们将一个接一个地链接多个方法。这使得代码非常长。为了以更易读的方式格式化代码,我们将把长代码分成几行,并使用 *()* 来包装代码。
1.1.梯度🌈
让我们先来看看前面的热图是如何创建的。我们将使用.background_gradient()方法创建关联矩阵的热图。
correlation_matrix = df.corr()
(correlation_matrix.style
.background_gradient(cmap='seismic_r', axis=None))

添加背景渐变只需要一行额外的代码。通过传递axis=None,颜色渐变将应用于整个表格,而不是特定的轴。所需调色板的名称被传递给cmap参数。对于这个参数,我们可以使用任何 Matplotlib colourmap 。这里有一个关于色彩映射表的有用提示:如果你需要翻转色标,在色彩映射表名称上加上_r后缀就可以了。例如,如果我们用'seismic'而不是'seismic_r',负相关将会是蓝色,正相关将会是红色。
前面的例子看起来和本文开头的例子不太一样。它需要更多的定制才能看起来一样:
(correlation_matrix.style
.background_gradient(cmap='seismic_r', axis=None)
.set_properties(**{'text-align': 'center', 'padding': '12px'})
.set_caption('CORRELATION MATRIX'))

我们将值({'text-align': 'center'})居中对齐,并用.set_properties()增加了行高({'padding': '12px' )。然后,我们用.set_caption()在桌子上方加了一个标题。在这个例子中,我们对背景应用了颜色渐变。我们也可以使用.text_gradient()对文本应用颜色渐变:
(correlation_matrix.style
.text_gradient(cmap='seismic_r', axis=None))

如果有用的话,我们也可以链接两种类型的渐变:
(correlation_matrix.style
.background_gradient(cmap='YlGn', axis=None)
.text_gradient(cmap='YlGn_r', axis=None))

在我们结束这一部分之前,我想展示一个更有用的例子。假设我们有一个简单的混淆矩阵:
# Create made-up predictions
df['predicted'] = df['species']
df.loc[140:160, 'predicted'] = 'Gentoo'
df.loc[210:250, 'predicted'] = 'Adelie'# Create confusion matrix
confusion_matrix = pd.crosstab(df['species'], df['predicted'])
confusion_matrix

我们可以做一些修饰,让它更有用、更漂亮:
(confusion_matrix.style
.background_gradient('Greys')
.set_caption('CONFUSION MATRIX')
.set_properties(**{'text-align': 'center',
'padding': '12px',
'width': '80px'})
.set_table_styles([{'selector': 'th.col_heading',
'props': 'text-align: center'},
{'selector': 'caption',
'props': [('text-align', 'center'),
('font-size', '11pt'),
('font-weight', 'bold')]}]))

这看起来漂亮,有用,简约。你不喜欢这个混乱矩阵的样子吗?
既然我们已经熟悉了前几个例子中的前 5 行代码,那么让我们来看看剩下的代码在做什么:
◼️ .set_properties(**{'width': '80px'}):增加列宽
◼️ .set_table_styles([{'selector': 'th.col_heading', 'props': 'text-align: center'}]):居中对齐列标题
◼️ .set_table_styles([{'selector': 'caption', 'props': [('text-align', 'center' ), ('font-size', '11pt'), ('font-weight', 'bold')]}]):居中对齐标题,增加其字体大小并加粗。
1.2.颜色条📊
现在,让我们看看如何将数据条添加到数据帧中。我们将首先创建一个数据透视表,然后使用.bar()创建数据栏:
# Create a pivot table with missing data
pivot = df.pivot_table('mass', ['species', 'island'], 'sex')
pivot.iloc[(-2,0)] = np.nan# Style
pivot.style.bar(color='aquamarine')

这可以像前面的例子一样进一步设计:
(pivot.style
.bar(color='aquamarine')
.set_properties(padding='8px', width='50'))

之前我们熟悉了这种格式:.set_properties(**{'padding': '8px', 'width': '50'})。上面的代码显示了将参数传递给.set_properties()的另一种方法。
如果您有正值和负值,您可以通过传递两种颜色(color=['salmon', 'lightgreen'])并在中间对齐条形(align='mid')将数据格式化如下:
# Style on toy data
(pd.DataFrame({'feature': ['a', 'b', 'c', 'd', 'e', 'f'],
'coefficient': [30, 10, 1, -5, -10, -20]}).style
.bar(color=['salmon', 'lightgreen'], align='mid')
.set_properties(**{'text-align': 'center'})
.set_table_styles([{'selector': 'th.col_heading',
'props': 'text-align: center'}]))

这里,我们还确保列标题和值居中对齐。
1.3.突出🔆
有时候,根据条件突出显示值会很有用。在本节中,我们将学习一些突出特殊值的函数。
首先,我们可以突出显示每列的最小值,如下所示:
pivot.style.highlight_min(color='pink')

最大值有一个等价函数:
pivot.style.highlight_max(color='lightgreen')

我们可以像这样将这些高亮功能链接在一起:
(pivot.style
.highlight_min(color='pink')
.highlight_max(color='lightgreen'))

还有一个突出显示缺失值的功能。让我们将它添加到前面的代码片段中:
(pivot.style
.highlight_min(color='pink')
.highlight_max(color='lightgreen')
.highlight_null(null_color='grey'))

这些内置函数很容易使用,不是吗?在结束本节之前,让我们再看两个函数。我们可以突出显示如下范围内的值:
pivot.style.highlight_between(left=3500, right=4500, color='gold')

我们还可以突出分位数:
pivot.style.highlight_quantile(q_left=0.7, axis=None,
color='#4ADBC8')

这里,我们突出显示了前 30%。
到目前为止,我们已经使用了几种不同的颜色。如果你想知道你还可以使用什么颜色名称,请查看这个颜色名称资源。如上例所示,您也可以使用十六进制颜色,这将使您获得更广泛的选择(超过 1600 万种颜色!).这里是我最喜欢的探索十六进制颜色代码的资源。
1.4.自定义颜色代码🎨
在这最后一节中,我们将看看其他一些使用自定义函数对数据帧进行颜色编码的方法。我们将使用以下两种方法来应用我们的自定义样式函数:
◼️ .applymap():元素式
◼️ .apply():列/行/表格式
元素式应用:。applymap()
让我们通过从数字列中截取前 8 行来创建一个小的数字数据。我们将使用 lambda 函数将 190 以上的值着色为蓝色,其余部分为灰色:
df_num = df.select_dtypes('number').head(8)
(df_num.style
.applymap(lambda x: f"color: {'blue' if x>190 else 'grey'}"))

让我们看另一个例子:
green = 'background-color: lightgreen'
pink = 'background-color: pink; color: white'
(df_num.style
.applymap(lambda value: green if value>190 else pink))

我们可以将 lambda 函数转换成常规函数,并将其传递给.applymap():
def highlight_190(value):
green = 'background-color: lightgreen'
pink = 'background-color: pink; color: white'
return green if value > 190 else pinkdf_num.style.applymap(highlight_190)
行/列/表方式应用程序:。应用()
让我们看看如何使用.apply()进行同样的格式化:
def highlight_190(series):
green = 'background-color: lightgreen'
pink = 'background-color: pink; color: white'
return [green if value > 190 else pink for value in series]df_num.style.apply(highlight_190)
我们也可以像前面的函数一样链接它们:
(df_num.style
.apply(highlight_190)
.applymap(lambda value: 'opacity: 40%' if value<30
else None))

知道如何同时使用.apply()和.applymap()很有用。这里有一个例子,我们可以使用.apply(),但不能使用.applymap():
def highlight_above_median(series):
is_above = series>series.median()
above = 'background-color: lightgreen'
below = 'background-color: grey; color: white'
return [above if value else below for value in is_above]
df_num.style.apply(highlight_above_median)

我们找到每一列的中间值,用绿色突出显示高于中间值的值,用灰色突出显示其余的值。我们还可以使用.apply()根据条件来设计整列的样式:
def highlight(data):
n = len(data)
if data['sex']=='Male':
return n*['background-color: lightblue']
if data['sex']=='Female':
return n*['background-color: lightpink']
else:
return n*['']df.head(6).style.apply(highlight, axis=1).hide_index()

这里,我们用.hide_index()隐藏了 DataFrame 的索引,以获得更清晰的外观。如果需要,您也可以使用.hide_columns()隐藏列。
最后,我们在这篇文章中看到的大多数函数都采用可选参数来定制样式。下面两个参数是常见的,知道它们非常有用:
◼ ️ axis用于沿哪个轴操作:列、行或整个表
◼️ subset用于选择要样式化的列的子集。

卢卡斯·本杰明在 Unsplash 上拍摄的照片
希望你喜欢学习通过颜色编码美化数据帧的有用方法。样式化的数据框架有助于更轻松地探索和分析数据,并使您的分析更具可解释性和吸引力。如果你热衷于学习更多关于造型的知识,看看熊猫的这个有用的文档。
您想要访问更多这样的内容吗?媒体会员可以无限制地访问媒体上的任何文章。如果您使用 我的推荐链接成为会员,您的一部分会费将直接用于支持我。
感谢您阅读这篇文章。如果你感兴趣,这里有我关于熊猫的一些其他帖子的链接:
◼️️ 从熊猫到 PySpark
◼️️ 在熊猫中编写 5 个常见的 SQL 查询
◼️️ 在熊猫中编写高级 SQL 查询
◼️️ 给熊猫用户的 5 个提示
◼️️ 在熊猫中进行数据聚合的 5 个提示
◼️️ 如何在熊猫数据框架中转换变量
再见🏃 💨
预防黑色疼痛:深度学习揭示数十年之久的膝盖疼痛之谜
原文:https://towardsdatascience.com/preventing-black-pain-deep-learning-illuminates-decades-long-knee-pain-mystery-d512499d43bc?source=collection_archive---------48-----------------------
深度学习可以减少医疗偏见并改善服务不足社区的结果吗?
最近的深度学习模型采取措施解决一个长期存在的谜团。具体来说,为什么黑人患膝骨关节炎的痛苦更多?为什么他们不太可能接受膝关节置换手术?
医生通常用 KLG 的 Kellgren-Lawrence 分级来确定骨关节炎的严重程度。KLG 是几十年前在英国白人中发展起来的一种方法。相反,这个 研究团队直接在 x 光片上训练了一个卷积神经网络来预测病人的疼痛 。

图片来自维基共享资源
该数据集包括 4,172 名患有或处于患膝骨关节炎高风险的美国患者。X 射线用于预测膝关节损伤和骨关节炎结果评分(KOOS),该评分来自患者完成的调查。因此,KOOS 让病人而不是医生来充当真相的仲裁者。
结果如何?卷积神经网络比 KLG 更好地预测了病人的疼痛。卷积神经网络解释了 43%的种族痛苦不平等,是 KLG 解释的 4.7 倍。它还更好地解释了其他得不到充分服务的人群中的不平等,包括低收入和教育程度低的患者。
为什么这很重要?虽然这种早期的网络并不能解释种群间的全部差异,但它可能是第一步。这里研究的三个社区——黑人、低收入和低教育水平社区——接受膝盖手术的可能性低 63%—85 %,接受阿片类药物的可能性高一倍。适用于所有人群的模型可能会减少疼痛和止痛药的过度使用。
当看到谁有资格用这个模型做膝盖手术时,团队发现有两倍多的黑人患者有资格做膝盖置换。这些患者可能正在服用阿片类药物。通过更好地预测疼痛,可以为患者带来更好的结果。
然而,更有趣的是对未来研究的总结。
未来
我们可以为未来的医学模式吸取一些教训:
1。使用多样化的数据。作者发现,从训练数据中去除黑人、低收入或低教育水平的患者仍然比 KLG 减少了疼痛差异——但幅度要小得多。
2。小心选择你的输入和输出。 X 射线、核磁共振成像和其他无偏倚的图像数据可以导致类似的偏倚减少。然而,这些并不是每个病人和每种情况都可以得到的。
在某些情况下,来自患者结果的数据可能是很好的输出。我很想看到这种卷积神经网络被训练用于其他存在医疗不平等的领域。例如,诊断跨性别、种族、社会经济地位的 ADHD。
3。可解释性是一件大事。虽然该模型能够很好地识别人群中的疼痛,但这种神经网络还无法显示哪些因素参与了决策。特别是在医学应用中,这种透明性和可解释性将补充人类知识,并增加网络中的信任。
结束语
通过将 X 射线数据映射到自我报告的患者结果,研究人员更好地预测了患者自我报告的疼痛,特别是在服务不足的群体中。这种方式的训练模型可以改善患者的结果,并减少医疗应用中的治疗差异。
这项研究为深度学习团队提供了一条美好的前进道路。团队可以将不同的数据从无偏见的输入映射到自我报告的患者数据。因此,高性能预测模型可以补充传统工具和知识库。
防止机器学习中过拟合的套索、脊和弹性网正则化
原文:https://towardsdatascience.com/preventing-overfitting-with-lasso-ridge-and-elastic-net-regularization-in-machine-learning-d1799b05d382?source=collection_archive---------13-----------------------
使用 L1 和 L2 正则化的线性回归用于机器学习中的偏差-方差权衡

照片由 pexels 上的 Ikbal Alahmad 拍摄
∘ 线性回归的缺点∘正则化回归∘1。拉索回归
∘ 2。岭回归
∘ 3。弹性网回归
∘L1 和 L2 之间的差异处罚
∘ 结论
线性回归模型很受欢迎,因为它们易于理解和解释。然而,在实践中,线性模型无法有效表达 非线性关系 。当有多个特征时,它们也很容易过度拟合,尤其是如果这些特征不是目标特征的有用预测者。
Lasso、Ridge 和 Elastic-net 算法是线性回归的修改,应用 l1 或 l2 正则化导致特征选择或特征收缩,从而减少过度拟合。
线性回归的缺点
1。线性回归不能有效地表达非线性关系。
在本节中,我们将使用模拟数据集来演示非线性关系中线性表达式的行为。让我们从一个简单的线性模型开始,它对一个独立(输入)特征和一个从属(目标)特征之间的关系进行建模。
我们将使用一个模拟数据集,类似于我在这篇文章中使用的数据集。数据集包含 x 和 y 两列,每列有 100 个值,绘制时显示余弦曲线模式。

按作者划分的 x 和 y 值散点图
下面是真正的余弦曲线。

作者的真实余弦曲线
在导入了numpy、pandas、matplotlib和seaborn库之后,我们读入我们的数据帧。
df = pd.read_csv(‘cosine_df.csv’)
df.head()

接下来,我们将训练一个线性回归模型并预测余弦数据集的结果。记住底层模式是一条曲线,一个简单的线性回归模型通过数据拟合出一条直线。
下面的函数接收数据和一个模型的实例。它将数据集分成目标和特征,符合模型,对训练数据进行预测,并且绘制预测。然后,它返回训练好的模型。
def model_fitter(data, model):
features = data.drop('y', axis = 1)
target = data['y']
model.fit(features, target)
preds = model.predict(features)
plt.scatter(data.x, data.y)
plt.plot(data.x, preds, 'k--')
plt.show()
return model
简单线性回归
现在,让我们使用我们的model_fitter函数在我们的数据上训练一个线性回归模型,但是首先,我们从 sci-kit learn 导入库。
from sklearn.linear_model import LinearRegressionlm = model_fitter(df, LinearRegression())

作者的简单线性回归
结果是预期的直线线性回归线,它转化为不代表数据集曲线的欠拟合模型。
让我们显示估计的 y_intercept ( β 0)和输入特征系数 x (β 1)
print(lm.intercept_)
print(lm.coef_)### Results
-0.09248137706996012
[0.02712842]
2。线性回归模型在很多特征的情况下容易过度拟合
增加线性回归模型复杂性的一种方法是增加输入要素。
这里,我们将使用模拟数据集的修改版本。除了我们的 2 列(x 和 y)之外,我们添加了 99 个其他列(s1 到 s99 ),它们包含没有预测影响的随机值,并且与我们的 2 个重要特征 x 和 y 没有任何关系。
下面的代码加载数据集(suspect_df)并显示前 5 行。
suspect_df = pd.read_csv('cosine_df_extra_columns.csv')
suspect_df.head()
多元线性回归
接下来,我们拟合一个多元线性回归,因为有多个输入特征。更多关于那篇文章中的。我们使用与上面相同的函数,并将模型保存为lm_s。
lm_s = model_fitter(suspect_df, LinearRegression())

作者拥有 100 个输入列的多元线性回归
哇!我们的模型完全超负荷了。有了 100 个输入要素和 100 个观测值(行),模型就有足够的系数组合来记忆每个单独的观测值,从而创建一个完美的过拟合模型。这个模型在新的未知数据上表现不佳。
注:在现实世界的数据集中,分析师收集并保留大量特征只是为了安全起见,或者在特征工程期间开发许多特征是很常见的。如果这些特征不能作为预测器,可能会导致过度拟合。
以下是 100 个特征(包括 x)的系数。
print(lm_s.coef_)

正则回归
线性回归模型的任务是减少成本函数并得出代表数据中真实模式的 β 0 和 β 1 系数的最佳估计值。

成本函数 MSE
在线性回归的背景下,正则化是惩罚模型系数的技术,从而减少过度拟合。这是通过向成本函数添加惩罚因子(成本函数+对系数的惩罚 y )来最小化成本函数和惩罚。λ值,或 λ ,控制我们最小化惩罚因子的程度,并控制模型的拟合程度。
正则化有两种类型;L1 和 L2。每一个都受到不同的惩罚,导致不同的行为。从下面的公式中,我们可以看到惩罚是如何改变成本函数的。
L1 正则化。这种方法不利于系数的绝对大小。

L1 正则化
L2 正规化。这会影响系数的平方大小。

L2 正则化
正则化会导致系数缩小或在某些情况下减少到零,从而完全移除该特征及其对模型的影响,解决多重共线性问题。系数越高的特征对目标变量的影响越大。可以通过调整 λ常数来调整罚函数。
我们将在本帖中描述的正则化算法在应用于成本函数的 l1 或 l2 惩罚的量上有所不同。
正则化回归算法。
1。拉索回归
LASSO 代表 L 东AbShS选举 O 操作员。这完全依赖于 L1 惩罚,它可以将系数的大小减小到 0,从而导致自动特征选择(系数为 0 的特征不会影响模型)。
由于 λ (惩罚的“强度”)可以并且应该被调整,所以更强(更大)的惩罚导致更多的系数被推到零。
我们将使用 sci-kit learn 的 Lasso 类,并运行我们的model_fitter函数来实例化 Lasso 模型,拟合它,绘制预测并返回模型。这涉及到一些随机化,因此我们将一个random_state值传递给模型实例。
from sklearn.linear_model import Lassolasso = model_fitter(suspect_df, Lasso(random_state=2021))

作者的 Lasso 回归模型
结果模型是一条欠拟合水平回归线,或均值模型(该线位于目标特征的均值)。让我们显示模型系数。
print(lasso.coef_)

我们看到所有系数都被强制降为零,包括预测 x 特征。
解决这个问题的方法是在 sci-kit learn 中调整惩罚强度 λ 和,这个参数称为alpha.,默认值为alpha=1.0。因此,我们应该减少它,因为如前所述,更高的 λ 值导致更多的系数被强制为 0。
让我们用alpha=0.1观察结果。
lasso_point1 = model_fitter(suspect_df, Lasso(random_state=1234, alpha=0.1))

alpha=0.1 的套索模型
现在这个模型正趋向于过度拟合。这里是alpha 0.1的系数。
print(lasso_01.coef_)

我们现在看到大约三分之二的系数是 0。该模型进行了特征选择。在 Lasso 中,不同的系数以不同的速率到达零,并且根据模型,最后被置零的特征是最重要的特征。
我们可以运行一个for-loop来研究 0.1 和 1.0 之间不同alpha值的影响,并确定最佳模型。
values = [0.1, 0.3, 0.5, 1.0]
for n in values:
plt.title('Alpha value: {}'.format(n))
model_fitter(suspect_df, Lasso(random_state=2021, alpha = n))

作者使用不同 alpha 值的套索模型
我们看到模型的复杂性随着 alpha 值的增加而降低。注意截距不受λ(alpha 值)的影响。
当alpha值接近 0 时,该模型为线性回归模型(参考我们上面过度拟合的多元线性回归模型)。随着 alpha 的增加,方差减少,而偏差增加,模型成为全局平均值。
2。岭回归
里奇(不是首字母缩写)完全依赖于 L2 罚函数,这导致系数更接近于零,但不是完全为零。这导致特征收缩。
更大的 λ ,或惩罚强度,导致更多的系数接近零。
我们首先从sklearn.linear_model导入Ridge类。然后我们调用我们的函数model_fitter,传入suspect_df和一个Ridge回归模型的实例。默认的 alpha 值是alpha=1.0。
from sklearn.linear_model import Ridgeridge = model_fitter(suspect_df, Ridge(random_state=2021))

作者使用默认值的岭回归
我们立即注意到模型过拟合。让我们看看模型系数。
print(ridge.coef_)

这些系数似乎相当高,因此,我们需要通过增加alpha值来缩小它们。这降低了噪音柱对模型的影响。
让我们用一个for-loop来考察五个alpha值对不同岭回归模型的影响。alpha 值为 1,1000,3000,5000 和 50000。
values = [1, 1000, 3000, 5000, 50000]
for n in values:
plt.title('Alpha value: {}'.format(n))
model_fitter(suspect_df, Ridge(random_state=2021, alpha = n))

作者使用不同 alpha 值的岭模型
我们注意到,随着 alpha 值的增加,模型偏差也会增加(变得过于笼统,忽略了相关关系)。在最高 alpha 值为 50000 时,回归线是目标特征的平均值,或平均值模型。
print(df.y.mean())###Results
-0.007254917297325034
让我们检查一下alpha=30000处的系数。
ridge_30000 = model_fitter(suspect_df, Ridge(random_state=2021, alpha = 30000))print(ridge_30000.coef_)

α= 30000 的岭回归系数
请注意数值中的高负幂。随着 alpha 值的增加,越来越多的系数接近零。这解释了先前讨论的特征收缩方面。
3。弹性网回归
弹性网回归模型是套索和山脊之间的妥协。它通过应用一个比率来结合套索和山脊惩罚。在 sci-kit learn 中,这个比率被称为l1_ratio,它定义了应用于模型的 L1 惩罚的比例。l1_ratio和alpha(或处罚力度)应该一起调整。
如果你设置比率完全偏向前者(l1_ratio = 0)或后者(1),那么山脊和套索回归就是弹性网的特例。
注意:如果你希望结合套索和脊的功能,使用弹性网回归。如果调整得当,这会带来更好的性能。您可以将比率(l1_ratio)设置为 1(套索)或 0(脊线),但在这种情况下,sci-kit 的 elastic-net 实现并不是最好的。如果数据集支持岭回归或套索回归,请使用单独的岭类或套索类来获得最佳结果,并且它们也更容易调整。
为了实现弹性网回归模型,我们需要首先从sklearn.linear_model导入ElasticNet类。然后我们将调用我们的model_fitter函数并传入suspect_df数据帧和一个ElasticNet模型的实例。默认值为alpha=1.0和l1_ratio=0.5.
from sklearn.linear_model import ElasticNetenet = model_fitter(suspect_df, ElasticNet(random_state=2021))

作者默认的弹性网模型
该模型似乎是欠拟合均值模型,类似于Lasso (alpha=1.0)。让我们显示系数。
print(enet.coef_)

具有默认系数的弹性网
同样,就像套索一样,系数被强制为零。对于任何大于 0.5 的l1_ratio,观察到类似的结果。
随着比率越来越接近零,岭回归的 L2 惩罚越来越受青睐。下面是模型。
enet_point1 = model_fitter(suspect_df, ElasticNet(random_state=2021, l1_ratio = 0.1))

l1_ratio=0.1 的弹性网模型
以下是比率为 0.1 时的系数。
print(enet_point1.coef_)

类似于具有低alpha值的 Lasso 回归,该模型应用了一些特征工程。这是因为 0.1 的l1_ratio意味着仍然有一些 L1 罚值导致一些系数为 0。然而,进一步将l1_ratio向 0 减小(例如 0.01、0.001 等。)应用更多的 L2 惩罚,导致非零系数。
L1 和 L2 点球的区别
L1 范数对于异常值更稳健,但是对于不同的λ值不稳定,因为模型随着不同的λ值而显著变化。
如果异常值很重要,则 L2 更好,因为系数的平方会导致这些要素的成本呈指数增长。
此外,L1 有一个内置的特征选择,将系数缩小到 0,而 L2 将系数缩小到接近 0,从而降低了稀疏度。
结论
这是对用于减少机器学习的线性回归中的过拟合的正则化技术的基本介绍。我们使用了套索、脊和弹性网模型,这些模型将 L1 或 L2 罚函数应用于成本函数,以减少系数的大小,从而减少模型方差。
当调整超参数如alpha和l1_ratio 以获得最佳模型时,具有单独的训练集和测试集来分别训练模型和测试训练模型的效率是可行的。您可以采用交叉验证机制进行超参数优化,并选择性能最佳的模型,记住偏差-方差权衡。
我希望你喜欢这篇文章。每当我发表新的文章时,如果想收到更多这样的文章,请在这里订阅。如果你还不是一个媒体成员,并且愿意支持我成为一个作家,请点击这个链接,我将获得一小笔佣金。感谢您的阅读!
猎物和捕食者——生物系统动力学模型
原文:https://towardsdatascience.com/prey-and-predators-a-model-for-the-dynamics-of-biological-systems-747b82d2ea9e?source=collection_archive---------17-----------------------
Lotka-Volterra 微分方程组综述

让·维默林在 Unsplash 上拍摄的照片
“在非洲,每天早上都有一只瞪羚醒来。它知道它必须跑得比最快的狮子还快,否则就会被杀死。每天早上一只狮子醒来。它知道它必须跑得比最慢的瞪羚快,否则它会饿死。不管你是狮子还是瞪羚。当太阳升起的时候,你最好跑起来。”
生态系统是自然的集合体,其中生物和非生物种群相互作用。但是,是什么规律支配着这些复杂而迷人的系统的动力学呢?尤其是,捕食者和被捕食者是如何相互作用的?
在 1925-1926 年间,两位数学家 Alfred Lotka 和 Vito Volterra 研究了这个问题,并独立地开发了一个微分方程模型来解决由两个动物物种组成的生态系统的情况:一个作为捕食者物种,另一个作为其猎物:猎物-捕食者模型。
洛特卡-沃尔泰拉模型
Lotka-Volterra 模型背后的一般思想是考虑一个理想的场景,其中只有两个物种共存:捕食者和它们的猎物。有一些潜在的假设:
- 捕食者只能以猎物种群为食;
- 捕食者在单位时间内消耗的食物总量(即吃掉的猎物数量)与猎物和捕食者之间发生的相遇次数成正比;
- 猎物和捕食者相遇的次数与双方种群的大小成正比;
- 在单位时间内,每个捕食者都需要最少量的食物才能生存和繁殖;
- 每种猎物都有取之不尽的食物来源,这使得它们可以在没有捕食者的情况下繁殖。

Monika Sojáková在 Unsplash 上拍摄的照片
如果猎物的食物供应是无限的,合理的假设是这个种群的增长率, x,将与其当前的
大小成比例(给定更多的潜在耦合):

其中A0 为增长系数,即人均出生率。
没有捕食者,种群数量会随着时间无限增长。但是对于捕食者来说,它会随着捕食者数量 y 乘以猎物数量 x 成比例减少,因为这两个物种之间的互动数量。

致命相互作用发生的速率。
对于捕食者来说,我们必须假设在没有猎物的情况下,种群数量会随着食物供应的减少而减少:

另一方面,捕食者也会随着两个物种的相互作用而成比例地增长,也就是说:

其中 C 是两个物种之间的相互作用速率。
综上所述,我们得到了描述两个种群 x (猎物)和 y (捕食者)的增长率的微分方程组:****

系统平衡

希瓦·史密斯·达·佩克斯
当两者在一段时间内保持恒定水平时,种群达到一个平衡点,即:

在这种情况下,增长率(即导数)为零。通过替换,我们得到平衡时的方程:

我们有两种可能的解决方案:

在第一种情况下,这两个物种都灭绝了。
相反,第二种情况对应于这样一种情况,即猎物的数量正好与保持捕食者数量不变的食物数量相对应。稍后将详细介绍。
熊和鱼
举个例子吧。我们假设开始时有两个种群,5 只熊(捕食者)和 10 条鱼(猎物)。通过数值积分求解模型后,我们分析了物种的时间演化。

福托迪安 H 达佩克斯
特别是,我们使用 scipy.integrate 模块[1]来集成 ode。该模块提供了一个方便的方法, odeint 来对常微分方程组进行积分: odeint 可以使用 FORTRAN 库 odepack 中的 lsoda 来解一个常微分方程组,它适用于一阶刚性和非刚性系统。

人口的时间行为——作者图片
该模型呈现出周期模式。事实上,猎物的增加带动了捕食者的增长。然而,当捕食者增加时,猎物的数量减少并达到最低,因此捕食者也减少了。当掠食者减少时,新的猎物就会出现,如此等等。这种动态因此导致了增长和衰退的持续循环。
****相位图也很好地说明了周期性行为,该相位图根据不同的初始群体规模进行了参数化,并在下图中进行了描述。曲线闭合的事实表明了两个变量之间的周期性关系。

轨迹和方向图——作者图片
结果分析
到目前为止,我们可以问自己:
- 一个物种能独立于另一个物种灭绝吗?
- 人口能稳定下来并达到一个平衡点吗?
至于第一个问题,答案来自平衡解,它告诉我们,只有当另一个种群也为零时,每个种群才能为零:物种不可能在不同的时间灭绝,它们必须同时灭绝。但是轨迹的封闭形式表明这种情况从未在模型中出现过(不幸的是,与现实世界不同)。
类似地,也不会达到稳定状态。这个系统循环往复,而一个趋向平衡的解决方案会呈现一个向内的螺旋图。

照片由 Soheb Zaidi 在 Unsplash 上拍摄
验证系统行为的更严格的方法是通过一种叫做线性稳定性分析的技术。线性稳定性分析的基本步骤如下:
- 找到系统的平衡点;
- 考虑一个非常接近平衡点的点,以便在系统中再现一个小扰动;
- 在这一点上求解方程,仅考虑具有相同数量级的附加扰动的项,以便隔离存在小振动时的系统行为;
- 检查振动幅度是否增大、衰减或两者都没有。
使用这种方法,有可能证明食饵-捕食者模型既不是渐近稳定的,也不是不稳定的,因为,正如我们已经认识到的,它的解是周期的。
笔记
[1]你可以在这里找到 API 文档:https://docs . scipy . org/doc/scipy/reference/generated/scipy . integrate . odeint . html
用于生成本文所用情节的代码可以在我的个人 github 上获得:https://github . com/Andrea-ci/misc-stuff/tree/master/lot ka-Volterra。
加密货币市场中订单不平衡的价格影响
原文:https://towardsdatascience.com/price-impact-of-order-book-imbalance-in-cryptocurrency-markets-bf39695246f6?source=collection_archive---------2-----------------------

詹·西奥多在 Unsplash 上的照片
从 190 万订单簿观察中我们能学到什么?
我们调查不平衡的订单是否会导致价格向薄的一面变化。也就是说,根据这一假设,当限价委托单在要价方相对于出价方有较大的交易量时,价格下降,如果在出价方委托单更多,则价格上升。我们测试这一假设,并评估是否可以利用订单不平衡信息来预测 ETHUSD 市场的价格变动。
订单不平衡
我们根据文献,例如卡特亚等人(2015) ,将订单簿不平衡定义为

等式 1
其中 t 表示时间, V 表示 bid(上标 b 或 ask(上标 a )的成交量, L 为计算ρ 所考虑的订单深度级别。图 1 显示了如何计算给定订单簿的不平衡 ρ 的示例。

图 1:订单簿不平衡。ETHUSD 的限价订单示例,基于比特币基地网站的截图,显示深度 L=4。L=1 的不平衡计算为(38.7828–19.1463)/(38.7828+19.1463)≈0.33。根据我们在本文中研究的假设,大于零的值对应于价格上涨压力。对于 L=2,我们将两个最佳价格的成交量相加来计算失衡,即(38.7828+1.86–19.1463-0.2505)/(38.7828+1.86+19.1463+0.2505)≈0.36。
当做市商在相对于出价量的要价处发布大量交易时,获得接近-1 的ρ值。ρ值接近 1 意味着订单簿的出价方相对于要价方有较大的交易量。不平衡度为零时,订单簿在给定水平 L 处完全平衡。该假说认为,低失衡数(< 0)意味着负回报,高失衡数(> 0)意味着正回报,即价格向失衡 ρ 的方向移动。
研究人员从股市数据中得出什么结论?
Cont et al. (2014) 利用美股数据表明,订单流失衡存在价格影响,且“订单流失衡”与价格变化之间存在线性关系。作者将订单流失衡定义为供应和需求之间的失衡,通过在给定时期内汇总收到的订单来衡量。他们的线性模型有大约 70%的 R。该研究考虑了过去的订单流(这导致了一个不平衡的衡量标准),并将其与同一时期的价格变化进行比较。因此,结论不是订单流不平衡预测未来价格,而是在一个历史时期计算的订单流不平衡解释了同一时期的价格变化。因此,这项研究没有揭示当前订单流不平衡对未来价格的直接影响。 Silantyev (2018) 在他的媒体文章中证实了使用 BTC-美元订单数据的研究结果。
利普顿等人(2013) ,使用 L=1 测量 ρ ,发现直到下一个报价点的价格变化可以很好地用订单簿不平衡的线性函数来近似,但是请注意
(1)变化远低于买卖价差,并且
(2)该方法“本身没有为直接的统计套利提供机会”。
Cartea 等人(2018) 发现,通过 ρ 衡量的较高订单账面失衡会导致市场订单量增加,这种失衡有助于预测市场订单到达后的价格变化。
在他们的书中, Cartea 等人(2015) 提出,对于一只特定的股票,过去的失衡和价格变化的相关性是体面的(10 秒间隔约为 25%)。
Stoikov (2017) 定义了一个中间价调整,该调整包含
订单不平衡和买卖价差。他发现由此产生的
价格(中间价加调整)比中间价和数量加权中间价更能预测中间价的短期变动。在本研究中,订单簿不平衡与我们的略有不同,具体来说,等式(1)将通过从提名者处移除请求量并将级别 L 固定为 1 来进行调整。该方法根据当前信息估计未来中间价的预期,并且是独立于时间范围的。根据经验,对于被评估的股票,预测最准确的时间范围是 3 到 10 秒。调整后的中间价存在于所提供数据的买价和卖价之间,这表明该方法本身并不是一种统计套利的方法,但正如作者所指出的,可以用来改进算法。
这些研究考虑了最佳买卖价格( L=1 ),
下的分笔成交点水平数据,我们着眼于更长的时间跨度,深入到 5 的深度来计算订单
的不平衡。这些研究中的数据使用了股票市场数据,其中
的 Silantyev (2018) 是一个明显的例外,而我们研究的是加密货币订单。
数据
订单簿数据可以通过公共 API 从加密交换中查询。除蜡烛线数据之外的历史数据通常不可用。因此,我从 2019 年 5 月到 12 月(2019–05–21 01:46:37 到 2019–12–18 18:40:59)以 10 秒的间隔从比特币基地收集 ETHUSD 的订单数据,直到 5 个级别的深度。这相当于 1,920,617 次观察。数据中存在一些缺口,例如,由于我们在分析中考虑到的系统停机时间。我们统计了 592 个间隙,其中两个后续订单簿观察之间的时间戳差异大于 11 秒。数据中两个订单簿之间的时间戳并不正好是 10 秒,因为我使用重复的 REST 请求收集数据,而不是连续的 Websocket 流。
订单不平衡的分布
在查看价格变化和订单不平衡之间的关系之前,我们先来看看不同订单水平的不平衡分布。
我们根据等式 1 计算所有观察值和 5 个不同级别的订单簿不平衡 ρ ,并发现以下特性。
- 在 L=1 时,不平衡通常非常明显或者根本不存在。 L 越高,平衡订单簿越频繁(即 ρ≈0) 的观察值越多)。
- 不平衡是自相关的。等级 L 越深,自相关性越高
我们在图 2 和图 3 中展示了第一个发现,在图 4 中展示了第二个发现。
图 2 显示了 1 级订单不平衡的直方图。我们观察到,在这个水平上,订单簿大部分是平衡的(接近 0),或者是高度不平衡的(接近-1 或 1)。

图 2:订单簿不平衡直方图。此图显示了第 1 级的不平衡,即仅考虑最佳买价和最佳卖价来计算不平衡。
当我们增加订单簿深度来计算不平衡时,订单簿变得更加平衡,如图 3 所示。

图 3:不同订单深度的订单不平衡。此图显示了第 2 级(左上)、第 3 级(右上)、第 4 级(左下)和第 5 级的不平衡。当更多层次的深度被考虑时,秩序册更加平衡。
图 4 显示了自相关函数(ACF)。与一致,Cuartea et al. (2015) 我们发现失衡高度自相关。给定滞后的相关性往往越高,用于不平衡计算的订单簿深度 L 越大。

图 4:粘性订单簿不平衡。上图显示了在第 1 级计算的不平衡的自相关函数,下图显示了第 5 级的自相关函数。如果我们增加计算不平衡的深度,我们观察到更高的订单簿不平衡自相关。
订单不平衡有助于预测价格变动吗?
我们现在研究ρ和未来中间价的相关性。中间价被定义为最高买价和最低卖价的平均值。
我们首先计算每个订单不平衡观察的中期价格的 p 期提前对数收益。然后,我们计算这些回报与期初观察到的订单失衡之间的相关性。我们删除了 p 周期平均长于 11 秒(1 个周期≈ 10 秒)的观测值。
图 5 和图 6 显示了未来回报和失衡的相关性,作为衡量回报的时期的函数。我们的结论如下。
- 相关性很低。
例如, Cont 等人(2014) 报告称,在同一时期,价格影响与其衡量的订单流不平衡之间的 R 约为 70%。对于线性单变量回归模型,这个 R 意味着 sqrt (0.70)=0.84 的相关性。然而,作者测量的是同期的价格增长,因为订单流不平衡,因此该方法不提供价格预测 - 失衡度量 ρ 对更接近失衡观察的价格更具预测性(相关性随着 p 的增加而降低)
- 考虑计算不平衡的订单簿的深度级别 L 越高,不平衡度量与未来价格变动的相关性就越大

图 5:p 期提前中间价收益与订单不平衡的相关性(L=1)。对于近期价格,失衡指标与回报的相关性最高。

图 6:p 期提前中间价收益与订单不平衡的相关性(L=5)。与图 5 相比,数据表明,用更深的订单簿级别(L)计算的订单簿不平衡比用低 L 计算的不平衡是更好的价格预测器。
深度 L=2 到 4 的相应曲线与这些发现一致,为了简洁起见,我没有显示这些曲线。有关这些图的 Python 代码,请参见附录 A2。
价格不确定性
上述相关性表明,用较高的 L 计算的失衡比用较低的 L 计算的失衡与价格上涨的相关性更好。近期价格越多,与ρ的相关性越高。基于此,我们继续分析仅一个时期的未来预测(≈10s)。
相关性是一个平均指标,那么中间价变动的不确定性呢?
图 7 和图 8 分别绘制了 L=1 和 L=5 的 1 周期对数收益与周期开始时观察到的不平衡的关系。当不平衡很大(接近-1 或接近 1)或 0 时,1 级不平衡图(图 7)看起来似乎有更高的对数回报变化,这在 5 级不平衡中我们没有观察到(图 8)。然而,图中这种看似较大的变化源于这样一个事实,即我们在边界和零点对 L=1 有更多的观察结果(如图 2 和 3 中的直方图所示),计算回报率的标准差并不能证实在极端情况下有更高的方差,正如我们在下一段中看到的那样。

图 7:L = 1 时的一期回报与失衡。图中的每个点代表观察到订单不平衡(x 轴)后一段时间内观察到的退货(y 轴)

图 8:L = 5 时单周期回报与不平衡的关系。
不平衡制度
我们遵循 Cartea et al. (2018) 的方法,将我们的不平衡度量分成五个区域,这些区域被选择为沿点等距分布
θ = {-1,-0.6,-0.2,0.2,0.6,1} 。
也就是说,制度 0 的价格不平衡在-1 和-0.6 之间,制度 1 的价格不平衡在-0.6 和-0.2 之间,依此类推。表 1 显示了所有 5 种机制的 1 期远期价格回报的标准差。
表 1:每个制度的 1 期中间价回报率的标准差。
表 1 解决了上一段中的问题:极端失衡(状态 0 和状态 4)下的中间价差异对于订单深度级别 L=1 比级别 5 高而不是。
现在我们进一步分析,通过构建置信区间来估计给定区域中预期中间价回报的概率界限。我在附录 A1 中提供了这一计算的详细信息。

图 9:1 级(暗)和 5 级(亮)失衡的预期中间价格回报的置信区间。垂直标记表示预期收益的点估计,水平线表示预期收益的 99%置信区间的边界。黑线表示不平衡等级 1 的间隔,亮线表示不平衡等级 5 的间隔。
图 9 显示了给定制度下预期中间价回报的置信区间。我们可以看到,实际上,低不平衡数(状态 0 和 1)的平均回报为负,高不平衡数(状态 3 和 4)的平均回报为正。当不平衡以更高水平构建时,均值更多地向订单不平衡方向移动,例如,在状态 4 中,当不平衡以 L=1 (黑线)计算时,1 期提前回报的均值小于在水平 L=5 (亮线)的深度执行计算时的均值。请注意,显示的置信区间反映了期望值的不确定性。表 1 中的标准差告诉我们这个期望值附近的收益的不确定性。
这一分析证实了相关性分析的结果:失衡与 1 期未来回报之间存在正相关但相关性较弱,更深的水平(L)导致更具预测性的失衡指标。
经验概率
知道我们处于哪种失衡状态,下一阶段中间价上涨、持平或下跌的概率是多少?
为了看到这一点,我们将每个订单不平衡划分为 0-4 的范围,然后计算负退货、零退货和正 1 期退货的数量,并将该数量除以观察次数,以估计中间价变动的概率。
图 10 和图 11 给出了分别针对 L=1 和 L=5 计算的不平衡的经验概率。这些数字证实了我们最初的假设:
在订单不平衡值较低的地区,中间价下跌的可能性更大,反之亦然。
当计算只有 1 个水平(图 10)或 5 个水平(图 11)的失衡时,我们发现经验概率在定性上没有差异。我们观察到,较高级别的概率 L=5 比 L=1 更具歧视性,这是一个期望的属性。
在附录 A3 中,我们还显示了以观察非零价格变动为条件的概率。我们发现,如果价格变动,第 5 级不平衡比第 1 级不平衡的预测略好。

图 10:L = 1 时中间价变动的经验概率。

图 11:L = 5 时中间价变动的经验概率。
收益性

乔丹·罗兰在 Unsplash 上的照片
许多加密交易所的交易费用大约为 10 个基点(我们将执行 2 笔交易)。我们从置信区间(图 9)中看到,在所考虑的 10 秒期间,中间价回报低于 10 个基点。因此,从不考虑差异的预期回报来判断,我们可以得出结论,订单失衡本身并不直接意味着盈利策略,甚至不需要调查买卖价差。
为了证实这一发现,我们从另一个角度来看盈利能力,并计算价格波动大于 10 个基点的经验概率,类似于图 10 和图 11。也就是说,我们将绝对值低于 10 个基点的所有变动都视为持平。表 3 显示,对于订单水平为 1 和 5 的不平衡计算,在所有制度中,大多数交易的绝对回报都低于 10 个基点。这证实了该策略本身不允许统计套利。
表 3:每个订单簿不平衡制度的经验概率。此表显示了在订单簿不平衡观察(状态 0 至 4)后的一段时间内,向上移动、向下移动或相对移动小于 10 个基点(持平)的经验概率。列概率 L1 显示了为 1 级订单簿不平衡计算的经验概率,L5 显示了为 5 级订单簿不平衡计算的经验概率。
结论
我们对 ETHUSD 订单簿和中间价变动的分析与股票市场订单簿失衡文献中的发现一致:
- 当失衡接近-1 时,存在卖出压力,中间价更有可能在近期下跌,当失衡接近 1 时,存在买入压力,中间价更有可能上涨。
- 失衡措施的价格影响是短暂的,随着时间的推移会迅速恶化。
- 不平衡测量本身不能直接用于统计套利,但是,它可以用于改进算法。
除了文献中引用的有关订单簿失衡的内容,我还分析了使用多达 5 个级别计算的订单簿失衡,并发现失衡度量与未来价格变动的相关性随着级别的增加而增加(对于评估的 5 个级别)。然而,从图 9 中的期望值及其置信区间,我们看到,较高的水平确实只是略微改善了回报方向,并且我们观察到,当处理较高水平的订单簿深度时,经验概率只是稍微更具歧视性。因此,来自更深层次(L>1)的附加值可能无法证明更高的复杂性是合理的(对于高频算法,处理更深层次通常更耗时)。
最后,我们发现失衡和价格变动之间最强的关系出现在数据中可用的最短时间(10 秒)内。因此,我得出结论,与本文中研究的 10 秒周期长度相比,研究分笔成交点数据可以揭示更多的见解。
参考
Cartea,a .,R. Donnelly 和 S. Jaimungal (2018 年)。用指令簿信号增强交易策略。应用数理金融学 25 (1),1-35。
Cartea,a .,S. Jaimungal 和 J. Penalva (2015 年)。算法和高频交易。剑桥大学出版社。
Cont,r .,A. Kukanov 和 S. Stoikov (2014 年)。订单事件的价格影响。金融计量经济学杂志第 12 卷第 1 期,第 47-88 页。
Lipton,a .,U. Pesavento 和 M. G. Sotiropoulos (2013 年)。限价订单簿中的交易到达动态和报价不平衡。 arXiv 预印本 arXiv:1312.0514。
Paolella,硕士(2007 年)。中间概率:一种计算方法。约翰·威利的儿子们。
Silantyev,E. (2018)。加密货币市场的订单流分析。中等。
Stoikov,S. (2017 年)。未来价格的高频估计者。可致电 SSRN 2970694 查询。
附录
A1。置信区间
我们感兴趣的是在给定状态下对数收益的均值。我们构建了置信区间,使我们能够在给定的制度下估计预期中间价回报的概率界限。我们在此提出的方法是标准的,例如,参见 Paollela 2017。
由中心极限定理,样本均值

方程式 A.1
随机变量中的I . I . d .Xi都是正常的:

方程式 A.2
其中 Xi 表示从具有均值 μ 和标准差 σ 的分布中提取的 i=1,…,n 个观察值,上标有 d 的箭头表示分布收敛,N(0,1)表示标准正态分布。我们可以将等式 A.2 非正式地表示为

方程式 A.3
这导致了均值和方差的估计

方程式 A.4
其中 s 为样本标准差。现在,水平(1-α)的置信区间由下式给出

方程式 A.5
z(α) 代表标准正态密度曲线 x 轴上的点,使得观察到大于 z(α) 或小于- z(α) 的值的概率等于α。
为了应用这种形式的中心极限定理,中间价回报必须是 i.i.d. 。中间价回报的自相关性低于 1%(另见 A2),并且没有迹象表明它们应该源于不同的分布或具有相关性中未反映的其他相关性,因此我们可以假设 i.i.d. 属性成立,并使用等式 A.4
import scipy.stats as st
import numpy as npdef estimate_confidence(shifted_return,
vol_binned,
volume_regime_num,
alpha=0.1):
*"""
Estimate confidence interval for given alpha* ***:param*** *shifted_return: array of returns for which we calculate
the confidence interval
of its mean, can contain NaN* ***:type*** *shifted_return: float array of length n* ***:param*** *vol_binned: volume regimes. Entry i corresponds to the
volume regime associated with
shifted_return[i]* ***:type*** *vol_binned: float array of length n* ***:param*** *volume_regime_num: equals np.max(vol_binned)+1* ***:type*** *volume_regime_num: int* ***:return****: confidence intervals for mean of the returns per regime* ***:rtype****: float array of size volume_regime_num x 2
"""* confidence_interval = np.zeros((volume_regime_num, 2))
z = st.norm.ppf(1-alpha)
for regime_num in range(0, volume_regime_num):
m = np.nanmean(shifted_return[vol_binned == regime_num])
s = np.nanstd(shifted_return[vol_binned == regime_num])
sqrt_n = np.sqrt(np.sum(vol_binned == regime_num))
confidence_interval[regime_num, :] = [m - z * s/sqrt_n,
m + z * s/sqrt_n]
return confidence_interval
A2。绘制自相关函数
下面的 Python 代码片段计算自相关和绘图。该计算考虑了时间序列中大于 11 秒的(硬编码)间隙。
import numpy as np
from datetime import datetime
import plotly.express as pxdef shift_array(v, num_shift):
*'''
Shift array left (num_shift<0) or right num_shift>0* ***:param*** *v: float array to be shifted* ***:type*** *v: array 1d* ***:param*** *num_shift: number of shifts* ***:type*** *num_shift: int* ***:return****: float array of same length as original array,
shifted by num_shifts elements, np.nan
entries at boundaries* ***:rtype****: array
'''* v_shift = np.roll(v, num_shift)
if num_shift > 0:
v_shift[:num_shift] = np.nan
else:
v_shift[num_shift:] = np.nan
return v_shiftdef plot_acf(v, max_lag, timestamp):
*'''
Create figure to plot autocorrelation function* ***:param*** *max_lag: when to stop the autocorrelation
calculations (up to max_lag lags)* ***:param*** *timestamp: timestamp array of length n
with entry i corresponding to timestamp of
entry i in v, used to remove time-jumps
v: array with n observation* ***:return****: plotly-figure
'''* corr_vec = np.zeros(max_lag, dtype=float)
for k in range(max_lag):
v_lag = shift_array(v, -k-1)
timestamp_lag = shift_array(timestamp, -k-1)
dT = (timestamp - timestamp_lag) / (k+1)
msk_time_gap = dT > 11000.0
mask = ~np.isnan(v) & ~np.isnan(v_lag) & ~msk_time_gap
corr_vec[k] = np.corrcoef(v[mask], v_lag[mask])[0, 1]
fig_acf = px.bar(x=range(1, max_lag+1), y=corr_vec)
fig_acf.update_layout(yaxis_range=[0, 1])
fig_acf.update_xaxes(title="Lag")
fig_acf.update_yaxes(title="ACF")
return fig_acf
A3。条件经验概率
图 A1 和 A2 显示了在观察到非零回报的情况下,中间价上移/下移的经验概率。第 5 级不平衡显示了更好的区分能力,也就是说,在制度 0 和 5 的概率比在第 1 级更极端。
如果中间价移动,L=5 的不平衡比 L=1 的不平衡更能反映价格方向。

图 A1:中间价变动的条件经验概率(不平衡深度 1 级)。

图 A2:中间价变动的条件经验概率(不平衡深度级别 5)。
来自《走向数据科学》编辑的注释: 虽然我们允许独立作者根据我们的 规则和指南 发表文章,但我们并不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语 。
主键和聚集索引
原文:https://towardsdatascience.com/primary-key-and-clustered-index-bf85f7f87b60?source=collection_archive---------6-----------------------
SQL 的组织能力、独特性和速度

由 Unsplash 上的Cup 先生/杨奇煜·巴拉拍摄的照片
我的一个朋友让我澄清数据表中主键和聚集索引的区别。在我们的谈话之后,我开始思考这些年来我教过的许多 SQL 课程,以及学生们在掌握这些概念之后的恍然大悟。然后我回忆起在指导同事和数据工程师正确使用这些物品后,我曾无数次看到同样的结果。如果你不确定它们之间有什么不同,或者你为什么要使用它们,不要感到难过。你在一个好公司里。本文简要解释了每种方法以及在您自己的数据表世界中何时使用它们。
限制
主键和聚集索引都属于 SQL 约束类别。约束是对表中的数据施加的规则。约束可以应用于表中的列,也可以应用于整个表。我们可以使用其他几个约束,比如 NOT NULL、UNIQUE、CHECK、DEFAULT 和 FOREIGN KEY。但是主键和聚集索引约束是最常见的,也是我们将要讨论的。
主关键字
Primary Key 约束使一列成为表中每一行的唯一标识符。它将某些属性应用于选择作为主键的列。此列不能为空。用数据术语来说,这意味着不为空。并且该列的每一行的值必须是唯一的。在数据方面,这意味着没有重复。
让我们用一个类比来进一步解释这一点。我们公司有一个销售部。每个销售人员在被雇用时都会被分配一个标识号。这些 id 对每个销售人员来说都是唯一的。鲍勃的识别号是 100,莎莉的是 200,法蒂玛的是 400,桑切斯的是 500。如果您列出一个销售人员的列表,以及他们的标识号,您将得到一个与此类似的列表。

拉杆脚轮
数据量如此之少,在某些方面,甚至不需要这些 id。名单上的每个人都有一个独特的名字。但是我们的销售部门正在发展。我们为西北地区雇佣了一名新的销售人员。嗯,他的名字是鲍勃。但是等等!我们已经有一个鲍勃了。现在大家都会很迷茫。更重要的是,数据会令人困惑。幸运的是,我们已经给每个销售人员分配了 id,并且 id 是唯一的。赢了!鲍勃,新的鲍勃,将有一个 600 的识别号。所以,现在我们的桌子看起来像这样。

拉杆脚轮
使用 ID 号,可以唯一地识别每个销售人员。我们的销售人员简表易于使用,便于快速查阅。我们注意到列表中的 id 有两个方便之处。首先,没有重复的 id。第二,每个人都有身份证。ID 列中没有重复和空值。
当然,我们的顶级销售团队开始做销售。我们意识到跟踪我们的销售是个好主意。当我们开始跟踪销售订单时,我们习惯于记录每个订单的细节。我们也非常喜欢销售人员 ID 的想法,我们决定为每个订单创建一个订单标识号。同样,它们是唯一的,没有重复,并且每个订单都有一个,没有空值。我们还想知道是哪个销售人员完成了销售。因此,除了每个订单的其他细节,我们还包括销售人员的 ID 号。我们的新销售订单列表可能如下所示。

拉杆脚轮
然后我们注意到,我们可以很容易地使用销售订单列表中的销售人员 ID 号将每个订单与销售人员列表中相应的销售人员姓名联系起来。这恰好是使用键的全部意义。我们将来自不同列表或数据表的信息连接在一起。这是因为即使销售人员 ID 在销售订单列表中出现多次,它在销售人员列表中只出现一次。如果该 ID 在我们的销售人员列表中多次出现,那么它将失去将订单与销售人员联系起来的能力。这会造成一种不明确的情况。在下面的例子中,谁在 2020 年 12 月 10 日卖出了 7500 美元?是鲍勃还是弗朗西斯科?除非我们的销售人员 id 是惟一的并且不为空,否则我们永远不会知道。

拉杆脚轮
当然,您可能会想“这很好,但是我真的需要将一个列声明为主键来获得这些结果吗?”没错。我们的列表很小也很简单。但是如果我们的销售部门很庞大呢?或者即使有一个小的销售团队,我们销售的广大产品呢?每个产品都分配有唯一的产品 ID。我们有数千种产品。更糟糕的是,我们列表中产品的排列顺序没有特定的顺序。产品 id 按名称的字母顺序排列在列表中,它们对应的标识号没有特定的顺序。
设想一个老式的基于纸张的归档系统。每件产品我们都有一个悬挂文件夹。在里面,我们存储了大量我们出售的每件商品的信息。您的经理打电话给您,指示您立即将产品 ID XY79443 上的信息带到会议室。你打开文件柜。
我们在每个文件夹顶部的小标签上写了产品 ID,但是抽屉里的文件夹没有特定的顺序。你盯着抽屉看了一会儿,开始翻阅每个文件夹,一个一个地看标签。
当你找到正确的文件夹时你会知道吗?是啊!
会很好找吗?我表示怀疑。
这是一个主键。这对于唯一识别信息非常有用。它使每一行都清晰可辨。它还帮助我们将不同来源的信息联系起来。但是它没有对数据施加特定的顺序。即使我们知道我们要找的是什么——针 XY79443,也可能要花很长时间才能大海捞针。
聚集索引
聚簇索引来拯救!如果主键擅长唯一标识数据表中的每一行,那么聚集索引则擅长快速找到特定的行。聚集索引实际上使用指定列中的值对表进行排序。当应用聚集索引时,表中的行被物理地重新排序,并以这种排序方式存储。
如果我们回到文件柜的类比,主键就是在每个文件夹标签上写产品 ID 的同义词。应用于产品 ID 的聚集索引将对文件夹进行组织,使最低的产品 ID 排在抽屉的最前面,最高的 ID 排在最后。对于大量的文件夹,我们也可以想象添加小分隔线来指示分类范围。
“哦,老板要 XY79443 号文件?”没问题!我们寻找带有 X-Z 标签的小分隔线。我们直接去下面第三个抽屉里的那个区域。然后我们看到 XX88100 在抽屉前面盯着我们的脸。我们翻阅了几个文件夹,大概到后面一半的地方,XY79390。再往后看一些,我们发现文件夹 XY79443 就在它应该在的地方——在 XY79442 和 XY79444 之间。答对了。
下面的两个列表描述了我们的销售人员列表的理论上的前后情况,首先没有聚集索引,然后对销售人员 ID 列应用了聚集索引。

左侧列表没有聚集索引,右侧列表有聚集索引— Rod Castor
我们可以对同一表中的不同列或同一列应用主键约束和聚集索引约束。将聚集索引应用于主键是一种常见的做法。因为主键经常用于连接数据,所以它经常用于搜索。使用主键搜索数据将有助于确保您拥有正确的信息,但不能确保快速的搜索结果。聚集索引将快速执行我们的搜索。一些数据库系统,如微软的 SQL Server,在我们使用主键时会创建一个聚集索引。这是默认行为。如果我们决定不这样做,我们必须显式地创建不带聚集索引的主键,或者随后删除聚集索引。
摘要
这两个约束不难理解。由于在表中的同一列上使用这两种约束是常见的做法,并且这是 SQL Server 的默认设置,所以数据人员经常偷懒,使用术语主键来表示这两种约束。我认为这种术语上的捷径和微软对两者的隐性联系导致了更广泛的数据工作领域的混乱。但毫无疑问,无论是单独使用还是一起使用,这两者都是强大的工具。
至于我们为什么要使用这些约束,我想上面的例子已经很清楚了。但是,我可能过高地估计了自己通过书面文字清晰交流的能力。因此,为了尽可能清楚,让我重申一下每一个的用例。
使用主键来唯一标识表中的每一行。主键约束将强制指定列中的值是唯一的,即没有重复,并且不允许出现 null 值或空值。主键有助于连接多个表之间的数据。
使用聚集索引来提高对表的查询速度。搜索包含数百万行的表可能需要几分钟或更长时间才能返回结果。聚集索引可以将等待时间减少到秒。我见过查询运行几天才完成。然后,在对表格应用适当的索引后,结果在几秒钟内就返回来了。
在大多数情况下,您需要在每个数据表上实现一个主键和一个聚集索引。通常,两个约束都应用于同一列。但是每一种情况都是不同的,必须根据自己的情况进行评估。
罗德蓖麻 帮助公司获得正确的分析!他帮助国际组织和小型企业改善他们的数据分析、数据科学、技术战略和技术领导力。除了咨询,Rod 还喜欢公开演讲、教学和写作。你可以在rodcastor.com和通过他的 邮件列表 了解更多关于 Rod 和他的工作。
成功浏览主成分分析
原文:https://towardsdatascience.com/principal-component-analysis-93b96b35ddc?source=collection_archive---------26-----------------------
实践教程
处理非常大的数据集可能很难获得有意义的结果。出于这个原因,降维可能是一个简单而又相对快速的尝试。这就是 PCA 派上用场的地方,有几种可能的方法让你的数据进入低维。
本文提供了一个简洁的概述,并浏览了投影的数学基础,考虑了特征值/特征向量、奇异值分解(SVD)以及主成分分析(PCA ),并展示了如何在 Python 中通过计算实现降维。

美丽图案由米切尔罗
PCA 是很多,但无论如何,这不是什么新鲜事。在大多数情况下,当谈到图像的有损压缩、降维以及当前机器学习宣传的特征提取时,人们会提到 PCA。即使人们最终可能不会使用这样的投影数据,PCA 也可以快速地将数据集减少到几个维度,然后可以用于在简单的散点图上可视化。
等待...使用一个 N x M 的数据集,并将其简化为一个 N x 2 的数据集,可以在二维空间中绘制——这听起来是不是非常有趣?绝对的!让我们从一个简洁而轻松的理论回顾开始。
理论背景
首先,让我们看一个相当简单的正交投影例子。假设我们想将一个数据点 x 投影到一条简单的直线上(因此,是一个一维空间)。

x 在线 L 上的投影—来源:交互式线性代数
我们的目标是找到蓝点(x 在 L 上,“xl”),如上图所示。
为此,在快速浏览投影时,我们需要记住以下两个标准:
Given
I. cu: sometimes denoted λ*u # scaling u, where λ is unknown
II. (x-cu)*u = 0 # due to orthogonality
结合上面这两个条件,我们得到:
(x - cu) * u = 0 # again, orthogonality
where u*u is the norm² of u
简单的代数然后让我们到达 c :
c = ux / |u|² # or
= ux / uu
最终我们通过用 c 缩放 u 得到 xl 。
我们刚刚掌握了将 x 投影到 L 的线上,或者换句话说,将投影到标量值上。让我们进一步把这个想法推广到更高维度的空间。我们认为我们的矩阵是一个一个 N x M 矩阵,而 W 是 A 的列空间,或者简单地说是跨越 A 空间的所有向量(通常也称为具有枢轴位置的向量)。因为我们的目标是将数据点 x 投影到我们的超平面 W 上。
正如我们之前看到的(请始终考虑转置上标,这些上标在下面的代码框中被遗漏了):
(x-cu)*u = 0 is now defined as: (x-Ac)*A = 0
= Ax - AAc = 0
= Ax = AAc
将所有这些放在一起,我们可以使用给定的定理来概括这种投影行为:

因此 W 中的 x 等于 Ac
从这一步我们可以了解到, Ac 等于 W 中的投影 x ,因此我们在求解常数 c 时找到了 W 中的投影点 x 。
如果我们把我们刚才所做的当作一个例子或一般的食谱:
1\. Given matrix A and data point x
2\. Calculate the matrix multiplication AA
3\. Calculate the matrix transformation Ax
4\. Form an augmented matrix for AA|Ax and do a row reduction to obtain pivot positions for AA. This gets us to c.
5\. Look at c and 🎉
现在,让我们跳回 PCA。我们已经找到了一种投射数据的方法,如果我们把它投射到一条线上,我们已经处于一个较低的维度,那么这和 PCA 有什么联系呢?在 PCA 中,我们试图以一种捕捉到数据中的最大方差的方式来投影数据。听我说:
在机器学习中,我们经常试图最小化数据中的方差,在这种情况下,情况完全相反。当我们降低数据的维度时,我们希望捕捉尽可能多的可变性。举个例子,如果你发现前两个主成分(我们很快就会谈到这一点,只要想想的前两列)捕获了 95%的数据可变性,我们可以说其他 N 列(把它想象成[任意定义的] 20 个附加列)只解释了我们数据中 5%的方差。
令人困惑。让我们继续前进,让烟雾散去。
正如我们刚才所说的,我们关心方差,因此我们创建一个矩阵来捕捉方差。方差(和协方差)的矩阵称为协方差矩阵,这里表示为 S 。

x-bar 是平均值,x n 个体 x 值,S 是协方差矩阵- 来源
同样,我们希望看到投影数据中的最大方差,这显然需要一个最大化问题— 换句话说,我们希望相对于 u 最大化 uSu 。请注意,由于 u 是一个单位向量,我们必须强制两个单位向量的乘积等于 1。
这是一个典型的问题,我们的老朋友娄祖钰用他的拉格朗日乘数对此进行了解释。

协方差矩阵+单位向量约束

推导第一个等式并将其设置为零
这个方程对许多人来说非常熟悉,它是特征值/向量计算中的典型例子。如果我们现在从左边乘以 u,我们求解λ的方程:

目标:找出最大的特征值及其最大的特征向量
根据我们刚刚发现的,我们可以总结为我们正在寻找个最大特征值及其相关特征向量,因为它们为我们提供了投影数据的最大方差。回到我之前提到的,PCA 上下文中的特征向量被称为主成分。要更深入地了解这篇文章的理论部分,请随意查阅这篇的伟大工作论文。
在我们讨论 PCA 的实现之前,我想概述一下线性代数的一个重要概念,它也用在 PCA 的上下文中,即奇异值分解(SVD)。
SVD 将形状为 M x N 的矩阵分解成三个矩阵,一个酉矩阵 U、一个矩形对角矩阵适马和另一个酉矩阵 V:

分解矩阵 M
在五氯苯甲醚的世界里,这与我们有什么关系?因为 u(左奇异值)是 MM^T 的本征向量,v 也是 M^TM.的本征向量(右奇异值),所以 Sigma 是一个对角矩阵,包含与 u 和 v 相关的各自的本征值,因此您可以看到它的发展方向。
如果你找不到任何关于网飞的好东西,我完全可以推荐你去看 Gilbert Strang 教授(麻省理工学院)关于奇异值分解的课——你不会后悔的:
PCA 的技术实现
显然,在处理数据时,我们不会手动完成所有这些,因此我将提供一个关于如何在 Python 中使用 PCA 的简要指南。让我们通过 scikit-learn 中的 Scipy 和 implmentations 来看看 PCA 的以下选项:
- 主成分分析
- 德拉贡诺夫狙击步枪(Snayperskaya Vinyovka Dragunov 的缩写)
- 特征向量/值
在接下来的几个段落中,我们将对一个数据示例执行降维,并将有损图像转换回其原始形状。
下面的篮球图像被选为我们的数据集,它将进一步用于应用主成分分析,或者在这种特殊情况下进行压缩。最终我们将使用 PCA 的思想来提供低维图像,并进一步将图像转换回原始空间。
换句话说,我们执行降维,然后将图像转换回原始维度(“逆”)—如果我们只想将数据投影到一个更低的维度上—回想一下我在一开始提到的散点图—我们希望最终得到一个 Nx2 矩阵(显然,这对图像不是很有用)。

献给 2021 年 ACC 冠军🏆— GT 男子篮球队—图片由本·赫尔希提供
主成分分析
Scikit-learn 的 PCA 实现使用 SVD 来投影到一个更低维度的空间,为你居中数据,但是不缩放。由于居中,PCA 非常方便,因为它节省了另一行代码,而且还提供了简单的转换函数,可以毫无麻烦地链接起来。
scikit learn 中的超级简单 PCA
仅仅两行“PCA-code”就让我们得到了一个更低维的数据集/压缩图像,这不是很神奇吗?顺便说一下,如果我们删除代码中的逆变换部分,我们会得到更低维度的数据。
40 个组件的结果有损耗,但令人印象深刻:

使用 40 个主成分的压缩图像
仅参考我之前的陈述,如果我们不讨论图像,而是数据集,我们可能希望将数据减少到只有 2 个组件(并绘制它们)。我任意选择了 40 个组件,让压缩后的图像更加赏心悦目。
奇异值分解
请注意,截断的 SVD 不会使的数据居中,所以为了得到我们刚刚得到的结果,您需要扣除平均值——mu,就像代码中被截断的希腊字母一样。
sklearn 的 SVD 实现
或者,我们可以简单地使用 Numpy 版本的 SVD,如果我们想要获得 U、适马和 V.T .的三个分解矩阵,这是非常有用的。

分解矩阵 M
下一个实现准确地返回三个矩阵,这些矩阵可用于重构矩阵 M(的简化版本)。
Numpy 奇异值分解
结果与我们在 PCA 实施中已经看到的没有什么不同:

奇异值分解下的压缩图像
顺便提一下,如果你的矩阵不是半正定的( psd ,所以所有特征值都大于或等于0【因此是“半”】),我不会使用 SVD,而是使用下面 PCA 方法中概述的“特征值”。关于 psd 矩阵的奇异值分解的有趣讨论可在此处找到:
https://math.stackexchange.com/a/3818408
特征值/特征向量
在你开始研究这个之前,如果你只是想得到一个较低维度的数据集(或者在这个例子中是图像),那么只要跳回到 PCA/SVD 就可以了,不要理会下面显示的手动步骤。
作为第一步,我们需要获得我们之前看到的协方差矩阵。为此,取我们的初始矩阵 A,从矩阵中的所有值 x 中减去平均值。这为我们提供了一个新的居中矩阵一个 。
下面的块只是使用特征向量分解来获得一个压缩图像——如此简单!
当我们这样做的时候:“特征”在机器学习中几乎无处不在,所以重温这些从来都不是一个坏主意。如果你感兴趣,可以在这里找到更多的建议:
结论
主成分分析是一种非常有用的方法,可以降低数据集的复杂性。只需要一点理论和几行代码,我们就能在一个简单的散点图中展示甚至更高维的数据。PCA 的概念当然可以被增强到各种更深入的概念,例如主成分回归,其可以启发对另一天的展望。
{照顾好自己,如果可以的话,也照顾好别人}
—借用史蒂芬·都伯纳
基于 R 和 Python 的乳腺癌数据主成分分析
原文:https://towardsdatascience.com/principal-component-analysis-for-breast-cancer-data-with-r-and-python-b312d28e911f?source=collection_archive---------9-----------------------
无监督机器学习降维算法

蕾妮·费希尔在 Unsplash 上的照片
又见面了。今天,我们讨论每个数据科学家最常用的机器学习算法之一— 【主成分分析(PCA) 。之前,我为这个话题写过一些内容。如果您尚未阅读,也可以通过以下网址阅读:
- 用 Scikit 进行主成分分析——学习
- PCA 背后的统计和数学概念
在本文中,将更多地强调我们用来执行 PCA 的两种编程语言(R 和 Python)。在本文的最后,您将看到 R 和 Python 在执行 PCA 方面的区别。
我们用于 PCA 的数据集可在 Scikit-learn 中直接获得。但这不是我们想要的正确格式。所以,我做了一些操作,把它转换成一个 CSV 文件(下载这里)。该数据集包含 569 名女性的乳腺癌数据(观察值)。数据集的维数是 30。这意味着在数据集中每个女性(观察)有 30 个属性(特征)。

乳腺癌数据集的一部分(图片由作者提供)
在进行 PCA 之前,我们先讨论一下 PCA 的一些理论背景。
主成分分析的理论背景
什么是 PCA?
基本上,PCA 是一种线性降维技术(算法),它将一组相关变量(p)转换成较小的 k (k <
主成分 ,同时尽可能多地保留原始数据的变化。在机器学习(ML)的背景下,PCA 是一种无监督的机器学习算法,其中我们发现重要的变量,这些变量可用于进一步的回归、聚类和分类任务。
PCA 是如何工作的?
主成分分析考虑变量之间的相关性。如果相关性非常高,PCA 会尝试组合高度相关的变量,并在高维数据中找到最大方差的方向。下图显示了第一个主成分(PC1)具有最大的可能方差,并且与 PC2 正交(即不相关)。

作者图片
相关矩阵和方差-协方差矩阵
PCA 可以使用相关或方差-协方差矩阵来执行(这取决于我们稍后讨论的情况)。
相关矩阵
相关矩阵是显示变量之间相关系数的表格。表格的对角线总是包含 1,因为变量和它本身的相关性总是 1。我们数据集的相关矩阵是:

乳腺癌数据集的相关矩阵(图片由作者提供)
方差-协方差矩阵
一个 方差-协方差矩阵 是包含与几个变量相关的方差和协方差的矩阵。矩阵的对角线元素包含变量的方差,非对角线元素包含所有可能变量对之间的协方差。
特征值和特征向量
设 A 是一个n×n 矩阵。标量 λ 称为 A 的 特征值 如果有一个非零向量 x 满足下式:

作者图片
向量 x 称为 λ 对应的 A 的 特征向量 。
非常重要:相关矩阵或方差-协方差矩阵的特征向量表示主成分(最大方差的方向)。相应的特征值表示由每个分量解释的方差的量。
PCA 中的特征缩放
PCA 方向对数据的规模高度敏感。如果变量不是在相似的尺度上测量的,我们需要在对我们的数据运行 PCA 之前进行特征缩放。我们可以应用 z-score 标准化 让所有变量进入同一个量表。
非常重要:从相关矩阵导出的主成分(PCs)与从标准化变量的方差-协方差矩阵导出的主成分(PCs)是相同的(我们将在后面验证这一点)。当我们使用相关矩阵时,我们不需要对我们的数据进行明确的特征缩放,即使变量不是在相似的尺度上测量的。
理论够了!让我们写 R 和 Python 代码来执行 PCA。
使用 R 对乳腺癌数据执行 PCA
为数据集选择最佳的电脑数量
R 中有几个内置函数来执行 PCA。这里,我们使用 princomp() 函数对我们的数据集应用 PCA。
princomp() 函数的第一个参数是我们执行 PCA 的数据帧。下一个论点非常重要。其默认值为假。通过设置 cor = TRUE ,PCA 计算应该使用相关矩阵而不是协方差矩阵。从相关矩阵导出的主成分(PCs)与从标准化变量的方差-协方差矩阵导出的主成分相同。因此, 通过设置 cor = TRUE,数据将在分析前居中并缩放,即使变量没有在相似的尺度上测量,我们也不需要对数据进行明确的特征缩放。
让我们把特征值,方差比例,方差累计比例都放到一个表格里。为此,我们可以使用 factoextra 库中的get _ environment()函数。该函数需要一个参数,该参数是 princomp 类的一个对象。
输出是:

作者图片
正如您在输出中看到的,仅第一台 PC 就捕获了大约 44.27%的数据可变性。前六个 PC 一起捕获了大约 88.76%的数据可变性。
让我们得到特征向量。下面一行代码给出了可变载荷矩阵,其列包含特征向量。
产量很大。我们只显示前 8 个特征向量。有些值缺失是因为它们非常小。

作者图片
让我们创建 scree 图,它是特征值的可视化表示。为了可视化特征值,我们可以使用 factoextra 库中的 fviz_eig() 函数。

Scree plot(图片由作者提供)
仅第一台 PC 就捕获了约 44.3%的数据可变性,第二台 PC 捕获了约 19%的数据可变性。弯曲大致发生在对应于第三特征值的点处。根据 凯泽法则 ,建议保留特征值大于 1.0 的分量。我们得到了特征值,只有前六个大于 1.0。因此, 我们保留前六个 PC,它们一起解释了数据 中约 88.76%的可变性。
使用 Python 对乳腺癌数据执行 PCA
在 Python 中,可以通过使用 Scikit-learn 机器学习库中的 PCA 类来执行 PCA。在这里,我们获得了相同的结果,但采用了不同的方法。我们不使用相关矩阵,而是使用方差-协方差矩阵,并且在运行 PCA 算法之前手动执行特征缩放。然后,我们将标准化(缩放)数据提供给 PCA 算法,并获得相同的结果。
为了执行 PCA,我们需要通过指定超参数的相关值,从 PCA() 类创建一个对象(称为 pca )。最重要的超参数是 n_components 。既然我们已经决定只保留六个组件,我们可以将 n_components 设置为 6。然后,我们调用 pca 对象的 fit() 方法来执行 pca。我们向 fit() 方法提供缩放数据。然后我们调用 pca 对象的各种方法和属性来获取我们需要的所有信息。输出是 numpy 数组的形式。我们可以使用几个 print() 函数来很好地格式化输出。最后,我们调用 pca 对象的 transform() 方法来获取组件得分。然后,我们将它们存储在一个 CSV 文件和一个 Excel 文件中,以备将来使用。新的(缩减的)数据集的维度是 569 x 6。只有 6 列(以前是 30 列)。这是因为我们决定只保留六个成分,它们共同解释了原始数据中约 88.76%的可变性。通过执行 PCA,我们将原始数据集缩减为六列(约为原始维度的 20%),同时保持了 88.76%的可变性(只有 11.24%的可变性损失!).
以下 Python 代码为我们的数据集执行 PCA。
只有前两个特征向量的输出部分是:

运行下面的代码块后,组件得分被保存在一个 CSV 文件(breast _ cancer _ 89 _ var . CSV)和一个 Excel 文件(breast _ cancer _ 89 _ var . xlsx)中,这两个文件将被保存在当前工作目录中。新的(减少的)数据的尺寸是 569×6。这是因为我们决定只保留六个成分,它们共同解释了原始数据中约 88.76%的可变性。
下图显示了新(缩减)数据集中的前 10 个观测值。 PC1 代表主成分 1, PC2 代表主成分 2,以此类推。数据集的形状是 569 x 6。

进行 PCA 后的部分乳腺癌数据集(保留了 88.76%的可变性)
我们可以使用新的(精简的)数据集进行进一步分析。
结论
R 和 Python 都有很好的执行 PCA 的能力。r 有一个很好的 PCA 可视化库( factoextra )。它非常容易使用。输出的格式很好,易于阅读。r 的 princomp() 函数也很好用。它为您提供了两个选项来选择相关或方差-协方差矩阵来执行 PCA。因此,只需几行 R 代码就可以轻松执行 PCA。Python 还提供了 PCA() 函数来执行 PCA。你可以用 Python 编写清晰易读的语法。它的语法非常一致。
我通常更喜欢使用 Python 来完成数据科学和机器学习任务。但是 对于 PCA ,我个人更倾向于使用 R,原因如下。
- r 的输出格式很好。
- 只用一行 R 代码就能轻松画出高水平的图。
- r 的函数提供了更多的定制选项。
这些都是我个人的喜好。你可以走自己的路。
感谢阅读!
本教程由Rukshan Pramoditha,数据科学 365 博客作者设计创作。
本教程中使用的技术
- Python & R (高级编程语言)
- 熊猫 (Python 数据分析与操纵库)
- Scikit-learn (Python 机器学习库)
- factoextra (R 的多元数据分析和可视化库)
- Jupyter 笔记本& RStudio (集成开发环境)
本教程中使用的机器学习
- 主成分分析
本教程中使用的统计概念
- 相关矩阵
- 方差-协方差矩阵
本教程中使用的数学概念
- 特征值和特征向量
2021–01–09
主成分分析第 1 部分:不同的公式。
原文:https://towardsdatascience.com/principal-component-analysis-part-1-the-different-formulations-6508f63a5553?source=collection_archive---------1-----------------------
什么是主成分分析?PCA 的最大方差和最小误差公式有哪些?我们如何使用主成分分析降低维数?

图 1:以(1,3)为中心的多元高斯的主成分。图片来源:[3]。
我们都知道主成分分析是降维中使用的标准方法之一。有多个帖子详细介绍了 PCA 的代码和实现;然而,在本帖中,我们将探究 PCA 是如何形成的,以及我们如何得出 PCA 算法。众所周知,主分量是对应于协方差矩阵的最大特征值的特征向量;这篇文章将探究为什么会这样,以及解决方案是如何得出的。这篇文章的内容将基于[1]和[2]的第 12 章提供的材料。
在我们进入 PCA 之前,知道什么是特征值和特征向量是很重要的。设 A ∈ R ^{n×n}为一个 n×n 矩阵。然后,向量 x ∈ C ^n 称为 A 的特征向量,如果

情商。1:特征值和特征向量
λ ∈ C 称为a的特征值
主成分分析(PCA)问题可以用两种方式公式化:最大方差公式化和最小误差公式化。在最大方差公式中,目标是找到数据到低维线性空间的正交投影,使得投影数据的方差最大化。在最小误差公式中,PCA 被定义为最小化数据点和它们的投影之间的平均投影成本(均方误差)的线性投影。我们将在下面的章节中看到,这两个公式导致相同的解决方案。
PCA:最大方差公式
给定一组观察值{ x _n},n = 1,2,…,n 和 x _n ∈ R ^D,根据最大方差公式,我们的目标是找到 x _n 到维度为m<的空间的正交投影。
现在让我们考虑最简单的情况,其中 M =1。我们定义一个向量w1∈r^d作为低维空间的方向。由于我们只对空间的方向感兴趣,我们将 w1 设为单位长度。即,

等式 2: w1 是单位矢量。
那么数据观察值 x _n 可以被投影到这个新的空间上

等式 3:x_ n 在 w1 定义的新空间上的投影。
如果 x̄ 是原始空间中数据观测值的平均值,那么投影空间中样本的平均值由下式给出

情商。3:将 x̄ 投影到由 w1 定义的新空间上。
现在,我们可以将投影数据的方差写成

情商。4:x̂的方差。
其中 S 是原始高维空间中观测数据的协方差矩阵。

情商。6:x的协方差。
现在,根据最大方差公式定义,我们需要最大化 x̂ 的方差。这可以通过最大化情商来实现。4.情商。4 有一个平凡解当|| w1 || → ∞时。为了防止这种情况,我们利用之前在等式 2 中设置的单位范数约束。为了解决这一问题,我们引入了拉格朗日乘数λ1,并将我们的优化目标表述如下:

情商。7:最大方差优化问题。
设置等式的导数。7 w.r.t w1 为 0 时,我们得到一个驻点,
****
情商。8:设置等式的导数。7 w.r.t w1 归零。
这说明在驻点处, w1 一定是 S 的一个特征向量,λ1 是特征值。对应特征向量 w1 。将等式 7 与 w1 ^T 相乘,我们可以看到最大方差等于特征值λ1。

情商。9:低维空间的最大方差等于特征向量 w1 对应的特征值。
我们可以通过选择使方差最大化同时又与现有方向正交的方向来识别额外的主成分。对于低维空间为 M 维为 M < D,的一般情况,主成分为对应 M 个最大特征值λ1,λ2,…,λm 的特征向量 w 1, w 2,… w m
PCA:最小误差公式
设{ x _n},n = 1,2,…,n 和 x _n ∈ R ^D 是数据观测值的集合,那么根据 PCA 的最小误差公式,我们的目标是找到使重建误差最小的变换:

情商。10:最小误差目标
其中 x̃ 是从低维潜变量生成的重建。这里,我们有一个完整的 D 维正交(正交和单位长度)基 w _i,其中 i= 1,2,… D。然后我们有

情商。11:标准正交基。
δᵢⱼ是克罗内克三角洲。由于基是完整的,我们可以把任何向量表示为基向量的线性组合

情商。12
因为我们有标准正交基,所以我们有α_ni 的解,它是 x _n 和 w _i 的点积。12 作为

情商。13 这方面的证据可以在[4]中找到
通过降维,我们的目标是通过将 D 维数据投影到更低维的空间上,为 D 维数据(带有 M < D )找到 M 维表示。我们可以用前 M 个基向量来表示这个 M 维空间

情商。14
并且剩余的(D-M)基由所有数据点共享(共享偏移)。在 Eq 中。14, z_ni 依赖于单个数据点,而 b_i 是所有数据点共享的常数。
来自 Eq。13 和 Eq。14 我们可以将 x _n 和 x̃ _n 之间的差值计算为

情商。15:xn 与x̃n 的区别
现在,我们可以用 Eq 来代替。等式中的 15。10 得到目标函数为:

情商。16
对 w.r.t z_nj 求导并设为零,我们得到

情商。17
对 w.r.t b _j 求导并设为零,我们得到

情商。18
现在,我们可以用 Eq 来代替。17 和 Eq。等式中的 18。16 和得到

情商。18
我们的目标是最小化 J( w ),但是我们观察到当 w = 0 时,这个问题存在一个平凡的解。为了克服这一点,我们再次利用正交基的性质,并设置归一化约束|| w || = 1。
现在,我们来看一个简单的例子,其中 D=2,M=1。我们必须选择一个方向,这样我们可以最小化下面的目标

情商。19
如前所述,对 w.r.t w2 求导并设置为 0,我们得到

情商。20
其中 w2 为特征值λ2 对应的特征向量。代入等式。情商 20。19、我们得到 J = λ2 ,即 J 在我们选择特征值最小的特征向量时最小化。在一般情况下,当我们有 M < D 时,重构的最小误差 J 通过选择对应于【D-M】最小特征值的特征向量 w _i 获得,该最小特征值由下式给出

情商。21
最小重构误差(失真测量)由下式给出

情商。22
【D-M】特征值之和。因此,我们的目标是使用 M 个最大的特征值,以便使失真测度 J、现在构成的 (D-M) 最小的特征值最小化。因此,我们可以得出结论,最小化重建误差最大化了投影的方差。
使用主成分分析进行降维
既然我们已经看到 M 个主分量是对应于协方差矩阵的 M 个最大特征值的 M 个特征向量,我们继续看如何应用 PCA 来降低维数。
使用主成分分析进行降维包括 4 个步骤:
1。数据居中 第一步是计算并减去数据点的平均值,使数据以 0 为中心,因此平均值为零。

情商。23:居中数据 X̂
2。计算协方差矩阵

情商。24:协方差矩阵
3。使用特征值分解计算特征值和向量 PCA 的目标是坐标系统的变换,使得新轴之间的协方差为 0。

图 PCA 的目标是找到空间 W,使得新轴之间的协方差为 0。
因此我们对协方差矩阵 S 进行特征值分解

情商。25:协方差矩阵的 EVD。
这里,γ∈ℝ(dxd)是特征向量的矩阵,而λ∈ℝ(dxd)是包含特征值的对角矩阵。
4。降维** 现在我们有了特征向量γ,为了降维,我们可以通过只保留最大 M 个特征值对应的列(特征向量)来截断γ。我们称截断的γ矩阵为γ’。则缩减空间中的表示由下式获得**

情商。26:降维
代码:使用 PCA 进行降维
代码:用主成分分析法降维。
具有 EVD 的 PCA 的性能
使用特征值分解(EVD)的 PCA 非常昂贵,复杂度为 O(D ),其中 D 是输入数据的维数。EVD 计算所有的特征值和特征向量对,通常我们只需要对应于 M 个最大特征值的特征向量。因此,在实践中,许多有效的迭代方法,如幂迭代法,被用来计算特征向量。
PCA 和数据标准化[2]

图 3 主成分分析可能被非标准化数据误导。(a)主成分是偏斜的,因为 PCA 被非标准化数据误导。(b)当比额表标准化时的 PCA。从[5]处的代码生成的图像。
PCA 的主方向是方差最大的方向。因此,主成分分析可能会被方向误导,沿着这些方向,仅仅因为测量尺度,方差就显得很高。我们可以在图 3(a)中看到这一点,其中主成分没有正确对齐,因为它被非标准化的标度误导。图 3(b)显示了当量表标准化时的正确主成分。因此,需要注意将数据标准化,以避免此类问题。
结论
在这篇相当长的文章中,我们深入研究了 PCA 的两个公式:最大方差和最小误差公式。我们看到两个公式具有相同的解决方案/算法——选择对应于数据协方差矩阵的 M 个最大特征值的特征向量作为新的基础。我们看到了 PCA 如何用于降维,以及如何在 python 中实现。最后,我们简要地研究了标准化数据的重要性以及它如何影响算法。这篇文章到此结束,这仅仅是 PCA 系列的第一部分。接下来的部分将涵盖概率 PCA、奇异值分解、自动编码器以及自动编码器、PCA 和 SVD 之间的关系。
跟随 Aadhithya Sankar 获得下一个零件可用时的通知!
如果您发现任何错误,请留下评论,我会修复它们!🙏🏽 ✌🏽
参考
[1] Bishop,Christopher M .模式识别与机器学习。纽约:斯普林格,2006 年。
[2] 墨菲,凯文 P. 机器学习:概率视角。麻省理工学院出版社,2012 年。
[3]https://commons . wikimedia . org/wiki/File:gaussianscatterpca . SVG #/media/File:gaussianscatterpca . SVG
[4]https://www.math.ucdavis.edu/~linear/old/notes21.pdf
[5] 墨菲,k .,索利曼,m .,杜兰-马丁,g .,卡拉,a .,梁昂,m .,雷迪,s .,&帕特尔,D. (2021)。概率机器学习的 PyProbML 库[计算机软件]。
资源
这里有一些资源可以帮助更好地理解这个主题
- PCA:最大方差公式(阿姆斯特丹大学)
2。PCA 最小误差公式(阿马斯特达姆大学)
作者的更多作品
如果你喜欢这篇文章,你可能也会喜欢下面的文章:
** **
主成分分析
原文:https://towardsdatascience.com/principal-component-analysis-pca-79d228eb9d24?source=collection_archive---------11-----------------------
直觉、数学和石头
这是关于主成分分析(PCA) 和 独立成分分析(ICA) 的两部分系列文章的第一篇。虽然它们有相似之处(如它们的名字),但它们各自完成不同的任务。在这篇文章中,我将描述 PCA 是什么,它是如何工作的,并作为一个例子使用它来定义一个标准普尔 500 指数基金。示例代码和其他相关资源可以在本文的最后一节找到。

主成分分析的视觉类比。图片作者。
主成分分析
想象一个大约有 20 名成员的大型摇滚乐队。它以吉他手、背景歌手、钢琴家、键盘手、圆号乐队、鼓手、打击乐手等为特色。大乐队需要大舞台。这对于麦迪逊广场花园或者温布利球场这样的场馆来说不是问题,但是如果他们才刚刚起步,只能打咖啡店呢?
不是三把吉他,可能只有一把。一个人可以演奏手鼓,而不是两个鼓手和一个打击乐手。一名成员可以演奏键盘,而不是舞台上的钢琴、电钢琴和合成器。你不会得到每首歌的全部细节,但这些歌曲仍然可以在 MTV 不插电的方式下播放。
这正是主成分分析(PCA) 所做的,但我们有一个数据集,而不是乐队,我们有变量,而不是歌曲,我们有数据集代表什么。数据通常有冗余的播放器,比如有 3 个背景歌手。有时你需要它们,但大多数时候它们都站在周围,看起来很漂亮(歌手的恐吓信来了)。 PCA 重写音乐,这样就有更少的表演者可以演奏同一首歌。

PCA 的可视化。图片作者。
换句话说, PCA 通过以最大化方差的方式组合原始变量来减少维度和冗余度。这在输入空间中定义了一个新的轴,沿着该轴的方差最大化,如上图所示。使用 PCA 时,自动调整输入变量至关重要。通过自动缩放我的意思是,减去每个变量的平均值并除以其标准偏差。这确保了每个新轴的中心,即 0,对应于平均值。
虽然一开始可能不明显,但从数学上讲,这相当于对由原始变量定义的协方差矩阵进行特征向量分解。我将在下一节中尝试给出一个清晰的推导。如果你不关心它是如何工作的,可以直接跳到文章末尾的例子。
它是如何工作的?
如前所述,PCA 通过以方差最大化的方式组合原始变量来创建新变量。数学上我们可以这样写,

根据最优化问题编写的单分量 PCA 问题。
这只是下面这个问题的数学写法:w的什么值最大化了* t 服从于 w 的范数平方等于 1 的约束?其中, t 是我们根据原始数据定义的新变量, X,和最优权重向量, w 。这里 t 的具体形式由下式给出:*

分数向量的函数形式或者我称之为主成分。
上面表达式的最右边将矩阵乘法改写为求和。 X 的第 j 列(一个向量)乘以 w 的第 j 个元素(一个数)。这个求和留给我们一个向量,更具体地说是得分向量,我称之为主分量。
让我们回到问题上来。 的 W 帽子值 w 最大化 t 服从 w 的范数平方等于 1 的约束?我们首先可以问的是 t 的方差是多少。这是以通常的方式定义的,

t 的方差。
请注意,当 t 的平均值为零时,其方差与其范数的平方成比例,即ttt .其中“”表示点积。这就是自动缩放数据的重要性!因此,使 t,的方差最大化的向量 w 就是使 t 的范数平方最大化的向量。因此,我们可以将 PCA 优化问题重新表述为,

主成分分析优化问题的重构。
使用上述 t 的定义,这变成:

根据 X 和 w 重新表述 PCA 优化问题。
信不信由你,这是一个很容易解决的问题。不要让向量和矩阵分散你的注意力,这就像解决一个入门微积分问题。我们只需要采用拉格朗日乘数的方法。这是一种从优化问题中去除约束的技术。**这很有帮助,因为它定义了一个新的目标函数,该函数具有内置的约束,允许我们简单地求导并获得最优解。如果这些都是胡言乱语,不用担心。我们只需要以下相关等式:**

单变量优化问题和 N 个约束的拉格朗日方程和相关方程。
L(x) 被称为拉格朗日函数,它定义了一个等价的(但希望更简单的)优化问题。现在,为我们得到的 PCA 问题构造拉格朗日函数,

主成分分析优化问题的拉格朗日方法。
这给了我们两个未知数的两个方程(即 w 和λ),

拉格朗日乘子法产生的方程。
第二个等式只是重申了我们的约束,即 w 的范数平方是 1。第一个等式很有趣。重新排列我们得到的术语,

重新排列拉格朗日乘子法的第一个方程,得到特征值问题。
原来这第一个方程是一个特征值问题,这是线性代数中的一个标准问题。接下来的问题是:左边的这个矩阵是什么?好吧,既然我们自动缩放了我们的数据,它就相当于 X 的协方差矩阵。它有两个很好的性质:1)它是对称的,2)它是正定的。这意味着我们总能解决这个特征值问题!然后,对应于最大特征值的特征向量将给出用于定义我们的单个主分量的最优权重。
这自然延伸到多个主成分。我们可以从最大到最小对特征值进行排序,而不是停留在最大的特征值。这些排序后的特征值的特征向量定义了主分量,使得与较大特征值相关联的主分量包含更多关于 X 的信息。这产生了一组有序的新变量,使得后续变量包含关于原始数据集的更少信息。
虽然这可能比你阅读网络博客时的胃口更数学,但我希望 PCA 的什么和如何更清楚。在要点下给出了几个可带回家的要点。接下来,我针对常设仲裁院的为什么问题,举一个具体的例子。下面的例子使用 PCA 创建了一个标准普尔 500 指数基金。
要点
- 新变量由原始变量的线性组合定义
- 每个随后的新变量包含较少的信息**
- 应用:降维、聚类、离群点识别
*
例如:标准普尔 500 指数基金
首先,我想披露,我不是财务顾问,我从未上过金融课,这绝不是如何投资你的钱的建议。这只是 PCA 能做什么的一个有趣的例子。Jupyter 笔记本的例子可以在 GitHub repo 中找到。
这里的目标是创建一个标准普尔 500 指数基金。指数基金是一种投资组合,旨在匹配或跟踪特定市场【2】。例如,如果你认为石油市场是一项伟大的投资,那么投资每一家石油公司是不可行的。这就是指数基金的优势所在,因为它们(理论上)将模拟市场波动,而无需投资每家公司的成本。如果我们仔细想想,这就是 PCA 做的事情。它试图用尽可能少的变量捕捉变化。
第一行代码获取实际的标准普尔 500 数据。yfinance python 模块用于获取更新的收盘价格[3]。标准普尔 500 股票的名字取自维基百科。

导入模块和跑马灯名称。图片作者。
接下来,我们使用 yfinance 提取 2020 年的股票数据。

使用 yfinance 提取股票数据。图片作者。

价格接近的熊猫数据帧预览。行是日期。列是股票代号。图片作者。
现在,我们导入 sklearn,使用内置的 PCA 功能。请注意,在我们运行 PCA 之前,我们需要自动缩放数据,这是之前定义的。我们还打印每个主成分的解释方差,这是一个关于数据集包含多少信息的度量。

导入 sklearn。自动缩放数据。应用 PCA。打印解释的差异。图片作者。
接下来,我们将前 3 个主成分的权重相加,并根据相对权重使用前 61 个变量定义一个指数基金。

定义指数基金。图片作者。
我们可以用柱状图来展示投资组合。

投资组合中股票的相对权重。图片作者。
将实际标准普尔 500 波动与指数基金进行比较。

随着时间的推移,比较标准普尔 500 与指数基金的收盘价。图片作者。
计算每只基金的回报率,标准普尔 500 在 2020 年的实际回报率约为 20%,指数基金的回报率约为 25%。
结论
主成分分析(PCA) 是数据科学中一个流行而强大的工具。它提供了一种减少一组变量中冗余的方法。我们已经看到,这相当于数据协方差矩阵的特征向量分解。PCA 的应用包括降维、聚类和异常值检测。在我的下一篇文章中,我将讨论一种相似但完全不同的技术,独立成分分析(ICA)。
资源
本系列更多 : 独立成分分析 | GitHub 回购
连接 : 我的网站 | 预定电话 | 消息我
Socials:YouTube|LinkedIn|Twitter|Tik Tok|insta gram|Pinterest
支持 : 给我买杯咖啡 ☕️ | 成为会员 ⭐️
https://shawhin.medium.com/membership
参考
【1】r . Bro,A. K. Smilde ,Anal。方法:2014, 6 ,2812–2831
【2】【https://www.investopedia.com/terms/i/indexfund.asp】T2
【3】【https://pypi.org/project/yfinance/】
【4】https://medium . com/rich-bytes/5-lines-of-python-to-automate-the-s-p-500-95a 632 e5e 567
【5】****金色,R 。(2020).统计机器学习:统一框架。博卡拉顿:CRC 出版社 c。*
主成分分析与提取树分类器
原文:https://towardsdatascience.com/principal-component-analysis-vs-extratreesclassifier-d0217bbcc9a8?source=collection_archive---------19-----------------------
一种特征选择方法比另一种更好吗?

来源:图片来自 Pixabay
主成分分析(PCA)的目的是识别在训练集中表现出最大变化量的特征。
这被用作特征选择方法,以识别影响结果变量的最重要的属性,从而允许丢弃没有显示出太多变化的变量。
在本文中,研究了一个酒店取消数据集,以确定 1)根据 PCA 分析,哪些特征显示出最大的变化(因此是最重要的),以及 2)使用这些特征的分类模型的准确性结果与 extra tree 分类器选择的结果相比如何。
主成分分析
在 Antonio,Almeida 和 Nunes (2019)提供的原始酒店取消数据集中,如果客户取消其酒店预订,酒店取消(IsCanceled)的结果变量被列为 1 ,如果客户不取消,则列为 0 。
此外,还为每个客户提供了一系列不同的功能,其中包括:
- 交付周期(从预订到顾客入住酒店之间的时间)
- 原产国
- 细分市场
- 存款类型
- 抵达月份
目的是识别数据集中显示与结果变量(酒店取消)相关的最易解释的差异的要素。
为此,PCA 用于识别解释 95%的变化的成分的数量,或者换句话说,总计 95%的变化的维度的数量。
>>> from sklearn.decomposition import PCA
>>> pca = PCA()
>>> pca.fit(x1_train)
>>> cumsum = np.cumsum(pca.explained_variance_ratio_)
>>> d=np.argmax(cumsum >= 0.95) + 1>>> d
3
在 d=3 的情况下,这表明所有列出的特征中的三个特征估计会贡献 95%的方差。
现在已经获得了 d 的值,可以再次运行具有三个指定组件的 PCA 模型,并识别最重要的特征。
>>> model = PCA(n_components=3).fit(x1_train)
>>> X_pc = model.transform(x1_train)>>> # number of components
>>> n_pcs= model.components_.shape[0]
现在,特征名称被指定为生成一个指示最重要特征的数据帧。
>>> most_important = [np.abs(model.components_[i]).argmax() for i in range(n_pcs)]
>>> most_important[1, 23, 11]>>> initial_feature_names = ['leadtime','arrivaldatemonthcat','arrivaldateweekno','arrivaldatedayofmonth','staysweekendnights','staysweeknights','adults','children','babies','mealcat','countrycat','marketsegmentcat','distributionchannelcat','isrepeatedguestcat','previouscancellations','previousbookingsnotcanceled','reservedroomtypecat','assignedroomtypecat','bookingchanges','deposittypecat','dayswaitinglist','customertypecat','adr','rcps','totalsqr','reservationstatuscat']>>> most_important_names = [initial_feature_names[most_important[i]] for i in range(n_pcs)]
>>> dic = {'PC{}'.format(i): most_important_names[i] for i in range(n_pcs)}
>>> df = pd.DataFrame(dic.items())
>>> df

来源:Jupyter 笔记本输出
根据以上所述,抵达月份、所需的停车位和市场细分解释了酒店取消的 95%的变化。
使用这些特征,建立了 SVM(支持向量机)分类模型,并比较了验证集和测试集的预测精度。
验证结果
使用 PCA,总体上获得了 59%的准确率,而获得了 73%的召回率。73%的召回率表明,在取消预订的所有客户中,该模型正确识别了 73%。在这点上,在这种情况下,该度量被认为比整体准确性更重要。
>>> from sklearn import svm
>>> clf = svm.SVC(gamma='scale',
>>> class_weight='balanced')
>>> clf.fit(x1_train, y1_train)
>>> prclf = clf.predict(x1_val)
>>> prclfarray([0, 0, 1, ..., 0, 0, 1])>>> from sklearn.metrics import classification_report,confusion_matrix
>>> print(confusion_matrix(y1_val,prclf))
>>> print(classification_report(y1_val,prclf))[[3950 3316]
[ 755 1994]]
precision recall f1-score support
0 0.84 0.54 0.66 7266
1 0.38 0.73 0.49 2749
accuracy 0.59 10015
macro avg 0.61 0.63 0.58 10015
weighted avg 0.71 0.59 0.61 10015
试验结果
当将预测与测试结果进行比较时,获得了 55%的准确率和 81%的召回率。
>>> a = np.column_stack((t_arrivaldatemonthcat,t_marketsegmentcat,t_rcps))
>>> a = sm.add_constant(a, prepend=True)
IsCanceled = h2data['IsCanceled']
>>> b = IsCanceled
>>> b=b.values>>> prh2 = clf.predict(a)
>>> prh2array([1, 1, 1, ..., 1, 1, 1])>>> from sklearn.metrics import classification_report,confusion_matrix
>>> print(confusion_matrix(b,prh2))
>>> print(classification_report(b,prh2))[[ 9028 37200]
[ 6274 26828]]
precision recall f1-score support
0 0.59 0.20 0.29 46228
1 0.42 0.81 0.55 33102
accuracy 0.45 79330
macro avg 0.50 0.50 0.42 79330
weighted avg 0.52 0.45 0.40 79330
树外分级机
正如我们已经看到的,标准 PCA 方法旨在将特征数量 n 减少到更少数量的主成分 d 。
然而,值得注意的是,还可以使用其他特征选择方法。在这种情况下,我们将探讨提取树分类器的特征选择方法。
ExtraTreesClassifier 是一种形式的集成方法,其中许多随机决策树适合数据,这实质上是将许多弱学习者组合成一个强学习者。
使用 x 和 y 数据,每个特征的重要性可以通过分数来计算。通过将这些分数分类到一个数据框架中,可以按升序查看每个分数的重要性。
>>> from sklearn.ensemble import ExtraTreesClassifier
>>> model = ExtraTreesClassifier()
>>> model.fit(x, y)

来源:Jupyter 笔记本输出
最重要的特征被确定为 1、12、13、21、23、25(交付周期、原产国、市场细分、存款类型、客户类型和所需停车位)。特征 27(预订状态)因不相关而被丢弃,因为该变量本质上揭示了客户是否取消了预订,并且具有误导性。
使用这些特征再次运行 SVM 模型,并且在如下分类矩阵中输出相对于测试集的准确度:
[[34581 11647]
[11247 21855]]
precision recall f1-score support
0 0.75 0.75 0.75 46228
1 0.65 0.66 0.66 33102
accuracy 0.71 79330
macro avg 0.70 0.70 0.70 79330
weighted avg 0.71 0.71 0.71 79330
使用提取树分类器指定的特征,获得了 71%的准确率和 66%的召回率。注意,当使用 PCA 指定的特征时,获得了 55%的准确率和 81%的召回率。
比较
那么,主成分分析或提取树分类器在选择最相关的特征方面做得更好吗?
在这种情况下,虽然我们不希望整体准确性太低,但回忆是一种更好地表明该模型在预测取消酒店预订的客户方面有多准确的指标。在数据集本身,大多数客户没有取消。因此,准确性本身会产生误导,因为高准确性可能表明该模型非常擅长预测那些没有取消的客户,但不太擅长预测那些取消的客户。
鉴于此,有人可能会认为 PCA 在此基础上表现得更好——因为召回率更高,而模型使用更少的特征来解释酒店取消的大多数变化。
也就是说,理解每个特性的理论相关性是很重要的。在这方面,运行多种特性选择方法并确定哪种方法最适合特定的用例始终是一种好的做法。
结论
在本文中,您已经看到:
- 如何实现 PCA 模型
- 在数据集中选择正确要素的重要性
- 主成分分析和树外分类器在特征选择中的比较
非常感谢您的宝贵时间,非常感谢您的任何问题或反馈。您还可以在这里找到这个例子的相关 GitHub 库。
参考
- 安东尼奥、阿尔梅迪亚、努内斯(2019)。酒店预订需求数据集。
- Aurélien Geron (O'Reilly Media):使用 Scikit-Learn 和 TensorFlow 进行机器学习
- 堆栈溢出:sklearn 上的 PCA 如何解释 pca.components_
- 走向数据科学:Python 中的特征选择技术——预测酒店取消预订
免责声明:本文是在“原样”的基础上编写的,没有任何担保。它旨在提供数据科学概念的概述,不应被解释为专业建议。本文中的发现和解释是作者的发现和解释,不被本文中提到的任何第三方认可或隶属于任何第三方。作者与本文提及的任何第三方无任何关系。
主要成分:艾伦·雅各布森关于构建数据科学工具
原文:https://towardsdatascience.com/principal-components-alan-jacobson-on-building-data-science-tools-16cae3681aff?source=collection_archive---------40-----------------------
Alteryx 首席数据和分析官 Alan Jacobson 谈论领先的数据科学家,他们创造的工具可供其他数据科学家使用。

迪奥戈·努内斯在 Unsplash 上的照片
Alteryx 的首席数据和分析官 Alan Jacobson 参加了我们的 Data Science Mixer 播客,讲述了他领导的数据科学家团队的工作,他们自己构建了其他数据科学家使用的工具,包括 Alteryx 平台和开源 Python 库 EvalML、Featuretools、women work 和 Compose。
Alan 与我们分享了如何组成一个可靠的数据科学团队,他如何看待模型的可解释性,以及如何清晰地交流数据科学。以下是我们谈话中的三个“主要组成部分”,它们将引导您思考该领域的这些重大问题。
多样化的人才带来更好的数据科学成果。
我曾经共事过的一些最优秀的数据科学家有着令人难以置信的不同背景。
建立一个成功的团队——这不仅适用于数据科学;我要说,对大多数团队来说都是如此——做得好的艺术之一是建立一个极其多样化的团队。这方面的科学非常清楚:多元化会给团队带来更好的结果。
毫无疑问,当你在处理我们每天都要处理的各种问题时,拥有许多不同背景的人肯定会有所帮助。我曾经共事过的一些最好的数据科学家有着令人难以置信的不同背景:地质学家、工程师、英语专业。他们都有不同的经历。我认为这是建立优秀团队的关键之一——拥有多元化的人才。
模型透明性可以通过可理解的解释来实现。
你想乘哪架飞机?
假设你要登上一架飞机,我可以向你展示我们设计飞机的所有数学模型。我可以完全透明地展示所有的公式和数学。太好了。或者,我可以告诉你,我们让飞机飞了一百万次,我们有一个模型在所有时间都工作正常。你想坐第 1000001 次航班吗?
你可以选择一架有一百万次工作经验的飞机,它从来没有出错过——或者是一架从未飞行过的飞机。它没有历史,但我可以向你展示所有的数学。你想乘哪架飞机?就我个人而言,我会选择已经飞行了一百万次并且每次都成功的那个。
机器学习在某种程度上使用了大量的历史数据,并建立了与历史数据相匹配的模型,而不是使用公式的统计计量经济学方法。所以有不同的方法。但是当谈到实际的透明度时,一旦你建立了模型,用机器学习来理解模型如何工作以及其中有什么是非常容易的。想看公式可以看公式。我不知道看到公式就一定让它更容易理解。我真的认为艺术不在于透明——我能看到盒子里的所有东西吗——而是,我是否让它变得足够容易理解,让你能真正理解发生了什么?
数据科学应该成为每个人教育和工作的一部分。
去掉行话,用我们日常生活中都能想象的例子。
数据科学,总的来说,真的没那么难。当然,数据科学中有些概念比其他概念更难理解。但是一个实践数据科学家所做的大部分事情——不是热力学。热力学是一门非常难的课程。至少对我来说,那是一门很难的课程。多维微积分。这是一件非常抽象,难以描绘的事情。
我发现大多数数据科学原理都可以用非常简单的术语来解释。我有两个孩子。他们是中学生和高中生,他们能理解这些概念。通常,当我训练这些概念时,我会试着去掉术语,并试着使用我们在日常生活中都能想象到的例子。
我真的热情地认为,数据科学是一个最终应该成为每个人工作的一部分的领域。不仅仅是博士数据科学家做数据科学。是数学。这是给所有人的。这并不是说不会有你需要数据科学家来处理的最复杂的事情,但是我真的很希望看到每个人在日常工作中都能够利用这些东西。
为了篇幅和清晰起见,这些采访回复被稍微编辑了一下。
播客节目笔记和完整的文字稿可在 Alteryx 社区 上获得。
主要成分:亚历克斯·恩格勒关于人工智能政策的未来
原文:https://towardsdatascience.com/principal-components-alex-engler-on-the-future-of-policy-for-ai-39af4bbd3bf9?source=collection_archive---------46-----------------------
布鲁金斯学会研究员兼公民数据科学家分享了他在塑造全球人工智能未来的政策和治理方面的专业知识。

照片由塞巴斯蒂安·皮克勒在 Unsplash 上拍摄
布鲁金斯学会研究员兼公民数据科学家亚历克斯·恩格勒加入了我们的数据科学混合器播客,讨论影响数据科学家日常工作的政策问题。他对这一主题的广博知识和他利用数据为公众谋福利的经验使这成为一场广泛而深入的对话。
以下是 Alex 分享的三个“主要组成部分”,包括他对数据科学家在日常工作中应该如何思考政策问题和道德问题的观点。
从短期来看,美国有关数据和人工智能的政策更有可能来自地方和州政府,而不是联邦政府。
伊利诺伊州显然正在通过其法律《生物识别信息隐私法案》起诉非法使用生物识别数据的行为。这是一个有趣的进步,他们似乎致力于保护其公民的数据在伊利诺伊州被非法使用,这很有趣。我认为他们有理由说,“是的,听着,你未经他们允许就拿走了这些数据;你在一项他们不同意的服务中使用它。我们会说这是犯罪。如果你这么做了,并且影响到我们的公民,我们会找到你的。”我完全能理解为什么一个州会觉得不得不这么做。
你可以想象,如果一大堆州通过了一大堆这样的个性化法律,任何人都很难建造出符合 50 个州所有要求的东西。因此,让所有事情都在州一级完成,存在着潜在的长期担忧。这就是为什么欧盟委员会正在着手数字治理和人工智能治理,因为拥有一套统一的规则更有意义。如果能得到一些联邦政府的指导就好了。我不认为我们应该期待在近期或不久的将来会有任何联邦立法。还有很多其他重要的工作要做。
数据科学家可以使用特定的工具来增强他们工作的可信度和公平性,以及“有意义的自省”
Python 和 R 中有关于如何运行偏见审计以及如何对代码和数据的结果更加自我批评的开源库。也有更多关于你可能已经在使用的模型的现有问题的公开研究。如果你正在建立一个基于现有大型语言模型的模型,那么阅读关于该模型中可能存在哪些潜在偏见的研究是非常有价值的。…
这是技术层面…除此之外,您可能还需要考虑人类数据科学家在此过程中的角色。这有点像选择你决定使用的变量。这是衡量误差的核心问题,在数据科学的现代、私营部门应用中,这个问题可能比在一些社会科学中考虑得少。在预测中使用员工销售或员工绩效评估作为结果指标意味着什么?这是对我试图预测的事物的一个好的公平的测量吗?
“政府机构的数据科学调查能力”可以提高算法操作和效果的透明度。
现在,我们有一个系统,在这个系统中,技术部门的监督和问责主要是由新闻愤怒循环产生的,记者发现一些看起来很糟糕的事情,或者可能是也可能不是坏事情,然后公众变得非常愤怒,公司被迫以某种方式做出回应,这可能是有意义的改变,也可能不是。然后,通常情况下,什么都不会发生。这是科技愤怒的循环。这不是一个非常有效的管理社会的方式。现在,我郑重声明,记者和学者们正在做大量有益的工作……(但)通常他们会受到从外部获取信息的限制。就我们对科技行业的了解而言,存在着巨大的信息不对称。…
我们现在看到的问题是个性化,而网络掩盖了这一点。因此,如果你是一个人,你可以看到算法的一小部分,与你相关的那部分,但要全面地看到发生了什么就困难得多了。…现在,当我谈到联邦政府的数据科学能力时,还有另外一面。所以一个问题是,我们如何开放这些数据,让我们真正知道发生了什么?第二,如果我们有充分的理由怀疑存在违法行为,会发生什么?你不能再把所有的文件都放在文件柜里了。你需要一些新技能。然后你需要天赋。我们需要能够雇佣对这类调查工作感兴趣的数据科学家。这就是我所说的数据科学能力。它不像一些制造新闻的人工智能东西那样令人兴奋;它正在改善联邦政府的招聘流程,以及云基础设施对各机构的可用性。
亚历克斯·恩格勒的更多内容,请查看他的文章和下面的完整播客:
- 将定义 2021 年人工智能治理的 6 项发展
- 不访问技术数据就无法管理技术
- 拜登政府应该如何解决人工智能监管问题
- 平台数据访问是欧盟数字服务法案的关键
- 独立审计师正努力让人工智能公司承担责任
为了篇幅和清晰起见,我们对这些采访回复进行了略微编辑。
详见 Alteryx 社区 。
用 Python 在 5 分钟内完成主成分分析(PCA)
原文:https://towardsdatascience.com/principal-components-analysis-pca-in-python-in-under-5-minutes-26baacb797f8?source=collection_archive---------17-----------------------

弗兰基·查马基在 Unsplash 上拍摄的照片
简明扼要的演练
先决条件
- 线性代数和矩阵分解的现有知识
- Python 3 编程熟练程度
什么是主成分分析?
简而言之,对于具有大量特征的数据集,PCA 可以说是最流行的降维算法。它用于移除高度相关的特征和冗余的特征,并修剪掉数据中的噪声。
最近的机器学习(ML)算法和神经网络可以很好地处理高维数据集,通常具有数十万或超过一百万个特征。请注意,由于计算技术(PCs/GPU)的最新发展,处理高维数据的效率越来越高,而无需因计算限制而降低其维数。然而,像 PCA 这样的降维算法仍然用于各种考虑,例如通过消除具有高相关性的特征、通过创建连续最大化方差的新的不相关变量来减少 ML 模型的过拟合。
获取主成分
“手动”方式
回想一下文献,我们可以通过奇异值分解(SVD)获得主成分矩阵 V,这是一种矩阵分解技术。在这里,我们有

其中 V 中有 n 个主成分。
换句话说,SVD 将数据矩阵 X 分解成三个矩阵:

其中 U 由左奇异向量组成,σ是与包含奇异值的 X 具有相同维数的对角矩阵, V 包含右奇异向量/主分量。
在 Python 中,我们利用 Numpy 的 svd() 函数来获得 X: 的所有主成分
U, S, V_T = np.linalg.svd(X)# transpose to get V, with number of components as V.shape[1]
V = V_T.T# first component
c1 = V[:, 0]# last (n-th) component
cn = V[:, -1]
现在,我们准备使用找到的组件来减小 X 的尺寸!为了将维度减少到 d ,我们必须将数据投影到由第一个 d 组件定义的超平面上。这样做导致超平面尽可能多地保留方差。在数学上,我们用矩阵 W 计算 X 的乘积,该矩阵由第一个 d 主成分组成:

在 Python 中,我们有以下内容:
W = V[:, :d] # d is the number of components
X_d = X.dot(W)
“Scikit-learn”方式
幸运的是,Scikit-learn Python 库已经为我们设置好了这一切。假设我们之前已经定义了 d 和 X 。然后,我们可以使用下面的代码,通过利用第一个 d 主分量来获得降维后的结果 X 矩阵:
from sklearn.decomposition import PCApca = PCA(n_components = d)
X_d = pca.fit_transform(X)
要访问单个组件,则略有不同。我们必须使用组件 _ 变量:
# first component
c1 = pca.components_.T[:, 0]
这里有一个补充说明,组件是水平向量,所以你必须用一个来转置它们。T 同上。
选择正确的维度数量
通常的做法是选择一定数量的维度,这些维度加起来构成方差中足够大的一部分。通常,惯例是保留 95%的方差,但这取决于您的需求。例如,如果你试图减少维度来更好地可视化数据,你将不得不把它减少到 2 维或最多 3 维,因为人类不能在视觉上阅读超过 3 维。
“手动”方式
在这种方法中,我们迭代通过由组件解释的方差比例,直到达到某个阈值——解释为要保留的期望方差比例。我们使用以下函数来实现这一点:
def get_pca_components(pca, var):
cumm_var = pca.explained_variance_ratio_
total_var = 0.
N_COMPONENTS = 0
for i **in** cumm_var:
N_COMPONENTS += 1
total_var += i
if total_var >= var:
break
return N_COMPONENTS
这里, cumm_var 包含每个分量解释的方差的比例,从最大到最小(第 n 个分量)。接下来,我们将 PCA() 对象与数据 X 相匹配,并提取分量数,以保留 95%的方差:
pca = PCA().fit(X)
n_components = get_pca_components(pca, 0.95)
最后,我们可以转换数据以降低其维度:
pca = PCA(n_components=n_components)
X_d = pca.fit_transform(X)
“Scikit-learn”方式
幸运的是,Scikit-learn 让我们的生活变得更加简单。我们只需要两行代码:
pca = PCA(n_components=0.95)
X_d = pca.fit_transform(X)
在 PCA() 对象中,您可以将 n_components 指定为 0 到 1 之间的浮点,以指定要保留的方差比率。如果您希望以这种方式进行降维,您还可以将组件的数量指定为一个正整数,最大为 d 。
后续步骤
现在您已经获得了转换后的数据 X_d ,您可以继续对其进行分析/可视化,并在其上拟合一个 ML 模型!
主要组成部分:约翰·k·汤普森论建立分析团队
原文:https://towardsdatascience.com/principal-components-john-k-thompson-on-building-analytics-teams-ed86d9d271af?source=collection_archive---------27-----------------------
这位畅销书作家分享了他关于建立数据团队和有效管理数据科学家的顶级技巧。

克里斯多佛·伯恩斯在 Unsplash
畅销书作家、CSL Behring 高级分析和人工智能全球负责人 John K. Thompson 最近参加了我们在 Data Science Mixer 播客上的采访。我们谈到了他在构建数据团队方面的丰富经验,他在去年出版的一本有思想、实用的书 构建分析团队 中记录了这些经验。
虽然你肯定应该听完整集,以了解更多约翰的故事和想法,但这里有他分享的三个“主要组成部分”。对于任何参与数据分析和数据科学的人来说,它们都是有用的策略和见解。
鼓励人们给数据科学团队带来新的项目想法——在他们过度思考之前。
约翰:如果他们来到你的办公室,或者在 Zoom 上,或者无论你在哪里,他们说,“嘿,我有个主意。我只想和你谈谈,”他们对此充满热情。他们对此有一种紧迫感。他们对这个想法有真正的热情。人们不会[消除想法],他们会说,“哦,那是不可能的,”或者,“我们永远也不可能得到那个,”或者“我们不想考虑那个”。那太难了。”他们不是数据科学专家。他们不知道。我们有一个人出现了,他真的为他的出现道歉,并希望得到我们的服务。我说,“别道歉,伙计。我们在这里支持你。这就是我们在这里的原因。这是我们的工作。”
帮助整个公司的员工发展与其兴趣相关的数据科学知识。
约翰:我们创建了一个卓越中心,然后,我们围绕这个中心建立了一个实践社区。所有人只需要举手说,“嘿,我对数据科学感兴趣,”他们就可以加入实践社区。那个实践社区有将近 500 人。我们把它分成了 15 个特殊兴趣小组。每个特殊兴趣小组都有一个志愿者领导。可能是 r,也可能是 Python。它可以是数据可视化,药物警戒统计,无论它发生了什么。因此,这是一个非常有趣的生态系统,它覆盖全球,但也有本地参与。
数据科学家可以通过精心选择的“优先个人项目组合”茁壮成长
约翰:【投资组合包含】你正在做的两个主要项目,其中一个主要项目为期六个月到一年。你有几个持续几个月的小项目,你有服务请求,当首席执行官出现并说,“嘿,我两天后有一个董事会议,我需要了解这个捐赠基础的价格弹性。”我说,“我们会继续努力的。我们将为您做到这一点。”放下一切。所以每个人都有自己负责的工作。如果你正在做某件事,而它让你崩溃了,作为这种人,这种有活力的,有策略的,聪明的,投入的人,立即切换到其他事情上来投入你的思想。所以那个项目被搁置了。它进入你的潜意识。[解决方案]可能会在一天后、两天后、一周后出现,不管是什么。
投资组合是一种给数据科学家自主权、责任和在项目之间进行时间分配的能力的方式,这使他们一直感到成功,即使他们在试验和失败。但是他们仍然有其他的事情要做和关注,而不仅仅是那次尝试的失败。
另一种假设
在 Data Science Mixer 上,我们总是问客人我们的“替代假设”问题:关于数据科学或作为数据科学家,人们通常认为是正确的,但你发现不正确的是什么?
约翰的另一个假设是什么?你得听一集才能知道!
为了篇幅和清晰起见,我们对这些采访回复进行了略微编辑。
播客节目笔记和完整的文字稿可在 Alteryx 社区 上获得。
主要组成部分:Kristen Werner 谈简化数据供应链
原文:https://towardsdatascience.com/principal-components-kristen-werner-on-streamlining-the-data-supply-chain-c10eca9dc601?source=collection_archive---------45-----------------------
雪花公司数据科学和工程总监 Kristen Werner 强调了数据工程和自动化如何增强人类成为数据科学家的体验。

尼沙阿德·萨尔瓦潘图拉在 Unsplash 上的照片
雪花的数据科学和工程总监 Kristen Werner 加入了我们的数据科学混合器播客,谈论她在数据自动化和开发工具以简化数据科学日常任务方面的工作。我们的谈话揭示了她在神经科学方面的迷人背景,她解决问题的系统方法,以及她对开发支持数据一致性和访问的机制的兴趣。
以下是 Kristen 分享的三个“主要组成部分”,包括她对数据科学家自动化通用流程的热情。
Kristen 的“恢复数据科学家视角”塑造了她开发数据科学基础设施的方法。
普通流程的自动化、简单化和商品化对我来说变得非常非常有吸引力。
你会看到许多公司只是试图处理数据,本能是雇佣一些数据科学家或数据分析师。对我来说,我的经验是长时间运行的查询,如果在几秒钟内没有返回结果,那么很难进行快速和迭代的探索性分析,以了解下一步应该做什么。我记得我试图对数据进行质量检查,但查询需要 30 分钟才能运行,对我来说,思考我检查了什么,我没有检查什么,我该如何思考这个问题,以及它何时才能结束变得非常困难。因此,普通流程的自动化、简单化和商品化对我来说变得非常非常有吸引力。
现在,在没有确保基础设施支持和数据工程存在的情况下,我从来不想让数据科学家或分析师去解决问题。我有这样一种感觉,5 到 10 年前,人们不知道应该雇佣什么样的数据科学家:是数学家,还是物理学家?你能为这个角色雇用谁?今天,数据工程可能处于类似的境地,有许多数据工程师已经完成了摄取和一些基本的结构化工作。但这种有助于实现数据科学的分析工程或准备工作的想法,我希望看到它成为任何数据团队或公司正在开发的数据堆栈的关键部分。
数据一致性是在整个组织中有效使用数据的关键部分。
我们的目标是至少为您的顶线指标创建一个一致的核心数据集,每个人都可以使用,每个人都应该参考。
如今,您的基础架构如何支持[一致性]?当你在 200 人、500 人、10,000 人时,它如何支持它?今天我总是想问那些问题:当我们是一万个人时会发生什么?我们会用同样的方法解决这个问题吗?
越早对公司的核心指标有概念,越好。但我在很多情况下看到的是,你有一个产品或产品团队或公司,他们有一些对数据感兴趣的人。您开始在数据仓库中收集数据,因为这是现在很自然的事情。然后你写一些特别的管道,并建立一个仪表板。但是你又雇佣了五个人,然后你又雇佣了五个人——现在所有这些人都创建了他们自己的定制管道。这就是乱象的来源,全定制。
如果你仍然很小,但你对这种技术债务有所关注,那么你的目标是至少为你的顶线指标创建一个一致的核心数据集,每个人都可以使用,每个人都应该参考。找公司里的专家来拥有它,或者雇佣一些至少能建立、保护、维护和社会化一个核心数据集的人。这是你不必购买额外工具就能做到的事情:在混乱中建立理智的概念。
各公司的数据科学和工程工作在成熟度上有很大差异。
你需要来自高层的授权。
这不是一个公平的竞争环境。有一个清晰的想法,数据应该做什么,你雇用谁,当你需要他们。是的,他们是你员工的重要组成部分。但是你仍然会看到人们纠结于,“好吧,我有我的数据,我有我的数据科学家。现在怎么办?”
你需要高管的支持,他们要么知道如何处理数据,知道如何将数据融入你的整体战略,要么愿意接受他们雇佣的从业者的指导。你需要来自高层的授权。这种现象还没有那么普遍。但我确实认为,人们愿意对数据进行投资,这一点得到了更好的普遍接受。他们知道这很重要,他们会购买这些工具来支持它。他们打算雇人。但是,让数据在业务中产生影响仍然是人们需要努力解决的问题。
为了篇幅和清晰起见,这些采访回复被稍微编辑了一下。
播客节目笔记和完整文本可在 Alteryx 社区 获得。
主成分:Margot Gerritsen 谈面对数据科学学习曲线
原文:https://towardsdatascience.com/principal-components-margot-gerritsen-on-facing-the-data-science-learning-curve-9b00e67afe5c?source=collection_archive---------27-----------------------
这位斯坦福大学的教授和数据科学中的女性的联合创始人向我们讲述了她在数据科学领域的经历,包括如何处理不确定性以及如何在数据项目中找到共同点。

德尔菲娜·杜卡鲁日上 Unsplash
Margot Gerritsen 是斯坦福大学的教授,也是国际组织女性参与数据科学的联合创始人。她最近参加了我们的数据科学混合播客的采访(当然,她还主持了 WiDS 播客!).我们谈论了她在数据科学方面令人难以置信的广泛经历,从研究流体动力学到设计帆船,再到为国家地理的纪录片制作翼龙的比例模型。
玛戈特的完整剧集非常值得一听,因为她提供了所有的灵感和建议。以下是她分享的三个“主要成分”。无论您处于数据科学旅程的哪个阶段,Margot 都有丰富您数据科学工作的独到见解。
在处理新的知识领域和不熟悉的数据科学应用时,坦然面对不适。
玛戈特:把它想象成潜入冰冷的深水中,就像你在夏天的一个山间湖泊里。你知道水将会很冷,但是你潜入水中,然后你会下沉或游泳,一切都会好的。我加入是因为我真的喜欢学习,这是我的动力。然后通常,我会有几个月的极度恐慌,我会想,“我在做什么?”感觉很不舒服。但后来我提醒自己,“但我学到了这么多。”你正处在这条学习曲线上,它非常陡峭,但是为工作而学习有多有趣呢?几个月后,你开始对事情有一点点了解。学会适应不舒服的事情真的真的很好,因为这才是研究的真正目的。如果你大部分时间都很舒服,我不认为你真的学到了很多。
看似不同的数据科学应用面临着共同的挑战。
玛戈特:所有这些问题真正交叉的一个领域是解决方法的设计。最终,当你开始解决某个问题时,第一阶段总是问题定义。你永远不会有明确的问题。如果你这样做了,如果它真的被很好地定义了,那么也许它就不再那么有趣了,对吗?所以你会花很多时间去思考,“我到底在追求什么,我的目标是什么?我将如何设计我的解决方案?”你需要了解你的边界条件。你需要了解你的初始条件。你需要了解参与者、利益相关者和不同的观点。你想推断出?你是想预测吗?你是想优化吗?所有这些都非常非常相似。在我从事的许多物理工作中——水库工程、风帆流、飞机设计、风力涡轮机布局优化或我做过的其他工作——基本的物理原理都非常相似。你用来描述物理的数学方程式非常相似。
留出时间探索拥有 arXiv 等资源的新领域。
玛戈特:很久以前,当我还是个学生的时候,没有什么真正的在线,对吗?一切都在日记里。所以我每周都会留出三、四个小时在图书馆看杂志。这真的很棒,因为这些期刊通常在接受的论文种类上非常宽泛。你接触了不同的群体。现在有了 arXiv ,那就简单多了。所以我强烈建议人们每周花几个小时深入 arXiv,开始浏览并关注一些作者。关注一些群体。看看他们做了什么,去过哪些方向。然后和乡亲们联系。给一个作者发一封电子邮件,说:“嘿,我读了你的论文。我真的很喜欢。我们能爬上电话,聊聊吗?我有些疑问。”
另类假设
在 Data Science Mixer 上,我们总是问客人我们的“替代假设”问题:关于数据科学或作为数据科学家,人们通常认为什么是正确的,但你发现什么是不正确的?
玛戈特的替代假设是什么?看看这一集就知道了。
为了篇幅和清晰起见,我们对这些采访回复进行了略微编辑。
播客节目笔记和完整的文字稿可在 Alteryx 社区 上获得。
主成分还是因子分析?
原文:https://towardsdatascience.com/principal-components-or-factor-analysis-fcc98225b932?source=collection_archive---------16-----------------------
我的工作应该使用主成分分析(PCA)还是探索性因素分析(EFA)?这是处理多元数据的分析师(如社会科学家、消费者研究人员或工程师)经常面临的问题。
在这篇文章中,我分享了我最喜欢的例子来解释 PCA 和 EFA 之间的一个关键区别。这种区别打开了解释其他重要差异的大门,并且有助于确定哪种技术最适合给定的应用程序。选择不当可能意味着误导结果或对数据的不正确理解。
一个例证
让我们从创建一些遵循标准正态分布的数据开始(如果你想继续的话,所有分析的 JSL 脚本是这里是)。具体来说,我创建了一个数据表,其中包含对彼此不相关的四个变量的 1000 个观察值。
我们可以使用 JMP 的多元平台来查看变量之间的相关性,并确认它们是独立的。我特别喜欢在相关性上使用颜色图来说明非对角线上的零相关性:

图一。四个模拟变量的相关系数和相应的热图。图像是使用 JMP Pro 软件生成的,版权 2021 SAS Institute Inc .,经作者许可使用。
现在,我们可以问自己一个重要的问题:如果我对这些数据使用主成分分析,结果会是什么样的?如果我用全民教育来代替,结果会是什么样的呢?如果你不确定,请继续阅读。
让我们使用 JMP 的因子分析平台对这些数据同时进行主成分分析和因子分析。我将只保留一个组成部分/因素,因为我们有少量的变量。这也消除了任何旋转的需要。
来自分析的组件或因子载荷对于帮助我们理解组件或因子代表什么是至关重要的;高负荷变量(通常定义为绝对值为 0 . 4 或更高,因为这表明至少 16%的测量变量方差与因子方差重叠)最能代表该成分或因子。下面,我们可以将合成部件载荷(首先显示)与因子载荷(其次显示)进行比较。

图二。对四个不相关的模拟变量进行主成分分析和探索性因子分析,得出成分和因子负荷。图像是使用 JMP Pro 软件生成的,版权 2021 SAS Institute Inc .,经作者许可使用。
我们可以看到结果是惊人的不同!PCA 给了我们三个绝对值大于 0.4 的载荷,而 EFA 没有给任何载荷。为什么?因为当我们做 EFA 时,我们隐含地要求对一个简化的相关矩阵进行分析,对于这个矩阵,对角线上的矩阵已经被平方的多重相关矩阵 (SMC)所取代。事实上,快速浏览一下简化相关矩阵的相关彩色图,就能明白为什么会得到如此不同的结果:

图三。简化相关矩阵的热图,其中对角线中的单位已被平方的多重相关所取代。图像是使用 JMP Pro 软件生成的,版权 2021 SAS Institute Inc .,经作者许可使用。
在这个例子中,简化的相关矩阵中的每个条目非常小(几乎为零!实际值为 0.002、0.002、0.004 和 0.001)。完全相关矩阵的特征值分解(图 1)在 PCA 中完成,而对于 EFA,特征值分解在简化的相关矩阵上完成(图 3)。所分析数据的差异有助于解释不同分析之间的差异,但这些都不能告诉我们从实际角度来看这些差异意味着什么。
分析全相关矩阵与简化相关矩阵的实际意义
PCA 和 EFA 的目标不同:PCA 是一种降低数据维度的技术,而 EFA 是一种识别和测量无法直接测量的变量(即潜在变量或因素)的技术。因此,在 PCA 中,数据中的所有方差——由全相关矩阵反映——都被用来获得一个解,并且得到的分量是变量打算测量的内容和其他方差源(例如测量误差)的混合(见图 4 的左图)。
相比之下,在全民教育中,并非所有的数据差异都来自潜在变量(见图 4 的右图)。这一特征通过用 SMC 值“减少”相关矩阵而反映在 EFA 算法中。这是合适的,因为 SMC 是潜在因素在给定变量中解释的方差的估计值(也称为公度)。如果我们用对角线上的单位数进行 EFA,那么我们将含蓄地说这些因素解释了测量变量的所有方差,我们将进行 PCA 而不是 EFA。

图 4。主成分分析和探索性因子分析的图形比较。图片作者。
图 4 还说明了 PCA 和 EFA 之间的另一个重要区别。注意 PCA 中的箭头是从测量变量指向主成分的,而 EFA 中是反过来的。箭头表示因果关系,因此 PCA 中测量变量的可变性导致主成分的变化。这与 EFA 相反,在 EFA 中,潜在因素被视为引起测量变量之间的可变性和相关性模式(Marcoulides & Hershberger,1997)。
为了清楚起见,我有必要再概述一些观察结果。首先,大多数多元数据在某种程度上是相关的,所以 PCA 和 EFA 之间的差异不像这个例子中的那样明显。第二,随着分析中涉及的变量数量的增加,PCA 和 EFA 的结果变得越来越相似。研究人员认为,至少有 40 个变量的分析导致微小的差异(Snook & Gorsuch,1989)。第三,如果测量变量的公度很高(即接近 1),那么 PCA 和 EFA 之间的结果也是相似的。最后,我最喜欢的这个例子依赖于使用“主轴”分解方法,但是也存在其他的估计方法,其结果会有所不同。当分析师在全民教育和主成分分析之间做出选择时,必须考虑所有这些观察结果。但对心理测量学家(那些首先发展全民教育的人)来说,最重要的也许是全民教育提出了一个关于被分析变量的理论;一个可以追溯到 Spearman (1904 年)的理论,认为未观察到的因素决定了我们能够直接测量的东西。
我在下面列出了一些要点,但是请注意,继续学习这个主题的一个极好的来源是 Widaman (2007)。
要点
- PCA 有助于减少变量的数量,同时保留数据中的大部分信息,而 EFA 有助于测量未观察到的(潜在的)、无误差的变量。
- 当变量没有任何共同点时,如上面的例子,EFA 不会找到一个明确定义的潜在因素,但 PCA 会找到一个明确定义的主成分,解释数据中的最大方差。
- 当目标是测量一个无误差的潜在变量,但使用了主成分分析时,成分加载将很可能比使用 EFA 时要高。这将误导分析师认为他们有一个定义明确、无错误的因素,而事实上他们有一个定义明确的组成部分,它是数据中所有方差来源的混合物。
- 当目标是获得保留数据中最大量可变性的变量的一个小子集,但是使用了 EFA 时,因子加载可能比使用 PCA 时要低。这将误导分析师认为他们保留了数据中的最大方差,而事实上他们保留了所有测量变量的共同方差。
参考
Marcoulides,G. A .,& Hershberger,S. L. (1997 年)。多元统计方法:第一课。心理学出版社。
Snook,S. C .,& Gorsuch,R. L. (1989 年)。成分分析与公共因子分析:蒙特卡罗研究。心理通报, 106 ,148–154。
斯皮尔曼,C. (1904)。“一般智力”,客观确定和测量。《美国心理学杂志, 15 ,201–293。
魏达曼,K. F. (2007 年)。共同因素与组成部分:原则和原则,错误和误解。因子分析 100:历史发展和未来方向,177–203。
本文原载于 2017 年 4 月 25 日 JMP 用户社区 。
主成分:Renee Teate 谈成为数据科学家
原文:https://towardsdatascience.com/principal-components-renee-teate-on-becoming-a-data-scientist-221c5c860e0e?source=collection_archive---------43-----------------------
Renee Teate 通过社交媒体和她的播客公开分享了她进入数据科学的职业生涯,成为了一名数据科学家。现在,她是 HelioCampus 的数据科学主管,她为推进数据科学职业生涯提供了更多建议。

由林赛·亨伍德在 Unsplash 上拍摄
Renee Teate 通过公开分享自己在数据科学领域的职业生涯,为许多有抱负的数据科学家提供了信息、指导和鼓励。她主持了一个播客,成为了一名数据科学家;在博客上写了她的学习和求职经历;并且经常在推特上发布关于这种职业转变的消息。Renee 最近加入了我们的数据科学混合器播客的特别视频集,在虚拟 Alteryx Inspire 会议上播出,也可以在我们的播客提要中获得。
Renee 分享的三个“主要组成部分”将激励数据科学领域的每个人继续学习和职业发展。
利用你的优势来支持你的技术专长。
你已经拥有了很多你需要的东西。
我已经擅长的事情对我作为数据科学家的角色真正有帮助。能够处理数据,与人谈论数据,与利益相关者合作,解释我的分析结果,与大学和学院的人交谈,与公司内不同团队的人交谈——沟通方面确实帮助我进入了领导角色,并与客户合作。最终成为我最强元素的不是技术部分。从事数据工作的其他方面,即使不是机器学习能力,也确实增强了我的能力,让我在自己的角色中变得有价值,并与许多不同的团队合作。总结一下:你已经有了很多你需要的东西。所以不用太担心。你将获得技术技能。我想这些更容易学。
你会在工作中向你的团队学习。
找到一个过渡性的角色,让你能够利用你已经拥有的技能,并在工作中提高自己的技能。
最终能够与团队合作真的很有帮助,因为我可以依靠他人弥补我知识上的一些不足。我可以向其他人学习技术。我试图鼓励那些害怕进入数据科学的人,因为在工作中你可以学到很多东西。无论你做多少背景工作,你都会在工作中学到更多。这并不是说你已经学会成为一名数据科学家,然后你就可以找到一份数据科学家的工作。很多人认为在开始申请工作之前,他们必须学习清单上的所有主题。但是现在非常需要像你这样有技能的人。因此,如果你能找到一个过渡角色,让你利用你已经拥有的技能,并在工作中发展你的技能——如果你能进入那种角色,那真的是一个很好的设置。
在分享数据项目成果时,不要等到最后的演示文稿才与利益相关者交流。
我们在团队中有盟友,可以用他们的方式向其他人解释。
它始于你如何在整个项目中与利益相关者合作——你如何定义什么是可交付成果,解释你正在做什么,然后让他们和你一起做。因此,当我们在 HelioCampus 进行探索性数据分析时,我们会定期与机构的最终用户举行会议。我们给他们看,“这是我们的发现。这有道理吗?这符合你的预期吗,还是让你感到惊讶?如果它令人惊讶,我们需要检查以确保我们是正确的。”当我们进入机器学习部分时,他们知道什么输入将进入模型。当我们生成分数时,我们讨论最重要的特征,并且我们在上下文中提供分数。我们不只是给出一个数字。它不仅仅是一个黑匣子。
因此,当最终用户看到这些结果时,他们已经明白了。当我们做最后的陈述时,即使它包括不属于这个过程的人,我们也有团队中的盟友可以用他们的方式向他们校园中的其他人解释我们做了什么,为什么我们做了某些选择,为什么结果会是我们这样。因此,在进行最终演示之前,我们已经有了认同和理解。
如需 Renee 的更多见解和建议,您可以观看此视频中我们对话的简短版本,或者收听播客中我们更长时间的聊天。
为了篇幅和清晰起见,我们对这些采访回复进行了略微编辑。
播客节目笔记和完整的文字稿可在 Alteryx 社区 上获得。
主要组成部分:Tessa Jones 谈数据科学生态系统
原文:https://towardsdatascience.com/principal-components-tessa-jones-on-the-data-science-ecosystem-654aef41e707?source=collection_archive---------40-----------------------
从研究极端环境到使用数据回答商业问题,来自 Calligo 的 Tessa Jones 分享了她专注于科学的头脑如何帮助她在数据科学领域取得成功。

由蒂莫西·戴克斯在 Unsplash 上拍摄
Calligo 的数据科学主任 Tessa Jones 在她的职业生涯中有许多令人惊叹的经历:首先是作为一名探索地球和太空的科学家,然后是一名强调在数据科学中保持科学的数据科学家。她最近加入了我们的数据科学混合播客,分享了数据科学的科学方面如何丰富了她的视角和她的职业生活。
以下是我与泰莎谈话的三个“主要组成部分”。
业务是数据科学家研究的生态系统。
将商业视为你的探索领域是至关重要的。
随着数据科学作为市场和人类体验的发展,科学一直是有点动摇的一部分。人们对它的含义感到困惑。我经常想把我的团队更多地称为商业科学家,而不是数据科学家,因为这就像你认为不同类型的科学家一样,对吗?在另一个世界,我可能会认为自己是一名化学家——某种研究化学相互作用的科学家。我真的认为像那样思考商业是很重要的。这是你的探索领域——更多地从业务是你正在研究并试图改善的生态系统的角度来考虑它。
对于数据科学家来说,项目及其实施的时间安排可能具有挑战性。
这可能意味着您的数据科学家没有得到最佳利用。
我在利用数据科学家的公司中看到的一个困难是,他们会有需求,他们会雇佣一个或多个数据科学家。他们很兴奋,他们开始行动了。然后就有了这种堕落的需要。这是一个高度不稳定的过程,最终可能意味着您的数据科学家没有得到最佳利用。他们往往会有这些平静的时候,他们试图找出如何使事情对业务有用。…很多时候,当您构建某样东西时,您会构建它并部署它,但您必须给它一点时间,然后才能确定“这会有什么影响?我们做了我们认为我们做的吗?它达到了我们想要的效果吗?”你必须让它过一点点生活,然后才能真正确定这一点。
在与利益相关方合作数据科学项目时,首先要了解你的受众。
你需要理解它们将如何与你要开发的任何东西联系起来。
更关键的一点是首先要明白你在和谁说话。对这个人本身有好奇心。真的,在一天结束的时候,你需要理解它们将如何与你将要开发的任何东西相关联。我有很多不同的利益相关者,他们中的一些人不想知道任何关于技术发展的事情。他们中的一些人想要确保他们了解所有业务是如何运作的。他们中的一些人想边走边学。我认为首先理解这一点非常重要,因为它真正建立了你和利益相关者之间的关系。我认为,你最终会得到更好的产品,但你也会有更好的整体体验。我认为这是最应该做的事情。
为了篇幅和清晰起见,我们对这些采访回复进行了略微编辑。
播客节目的笔记和完整的文本可以在 Alteryx 社区上获得。
主坐标分析
原文:https://towardsdatascience.com/principal-coordinates-analysis-cc9a572ce6c?source=collection_archive---------4-----------------------
实践教程
通过 R 和 Python 示例深入探讨感知映射和产品品牌的主坐标分析

主坐标分析——照片由卡尔文·汉森在 Unsplash 上拍摄
主坐标分析
在本文中,您将发现主坐标分析(PCoA),也称为度量多维标度(度量 MDS) 。您将了解什么是主坐标分析,何时使用它,以及如何使用 Python 和/或 r 在一个真实的示例中实现它。
什么是主坐标分析?
主坐标分析是一种统计方法,它将关于项目之间距离的数据转换成这些项目的基于地图的可视化。
生成的映射可用于更好地理解哪些项目彼此接近,哪些项目不同。它还可以让您识别组或集群。
主坐标分析与其他方法
在我们进入细节之前,让我们首先讨论主坐标分析与其他几个密切相关的统计方法的关系。
主坐标分析与多维标度
多维标度是一系列统计方法,侧重于根据距离创建项目映射。在多维标度中,不同类型的数据有不同的方法。主坐标分析是多维缩放的一个子类型,用于处理数值距离,其中没有测量误差(每对项目只有一个距离测量值)
主坐标分析与聚类
聚类也与主坐标分析密切相关。在聚类中,你试图在你的数据集中,基于相似性创建观察值的聚类。相似之处基于您测量的变量。
这与主坐标分析相对相似,因为它也基于(不)相似性来表示数据。然而,一个很大的区别是主坐标分析试图提取两个维度来制作 2D 地图,而聚类只是试图将数据点分组。
在聚类分析结束时,通常还会将聚类和数据点绘制到 2D 地图上。然而,您将需要额外的分析(例如 PCA)来计算这些维度。
使用主坐标分析,主要目标是创建最佳可能的映射,在图表中可以看到组/簇。对于聚类,主要目标是识别聚类,而您可以对这些聚类做的一件事是尝试在地图上绘制它们。
主坐标分析与主成分分析
主坐标分析也容易与主成分分析(PCA) 混淆。首先,他们有相同的首字母,这使得他们很容易混淆。其次,两者都使用了降维。
不同的是,主成分分析侧重于共享方差:它试图用最少的分量概括多个变量,以便每个分量解释最多的方差。另一方面,PCoA 关注的是距离,它试图提取说明最大距离的维度。
主坐标分析一例
在文章的下一部分,我们将使用两个例子来使事情更清楚。这两个示例是主坐标分析的两个标准用例。在继续之前,让我们先介绍一下示例。
感知映射
我们将看到的第一个主坐标分析示例是感知映射用例。感知制图意味着你制作了一张地理地图,但是你使用了一种不寻常的距离度量。
当然,你可以在地图上使用各种类型的距离度量。然而,感知映射的想法是创建一个可视化,让你对距离以外的其他维度有更好的洞察力。
对于这个例子,我创建了一个小型的数据集,其中包含法国城市的火车旅行时间。自从我住在法国以来,我一直很惊讶为什么有些距离很近的城市坐火车要花这么长时间,而有些距离很远的地方旅行却非常快。这可能是由于两个城市之间的火车类型或地理障碍(如山脉等)等条件造成的。
为了获得数据,我计算了法国 10 个最大城市之间的火车路线。分析的目标是重新绘制一幅法国城市的地图,它不是基于地理上的接近度,而是基于旅行时间的接近度。
产品映射
我们要看的第二个例子是产品品牌的例子。我们将使用产品之间距离的模拟数据集。假设你是一家公司,你想推出一种新产品。您可以使用这种技术在现有产品中映射产品,以发现它是否足够不同,可以引入。
产品映射可以使用度量数据来完成,但也经常使用非度量数据来完成。如果您有公制比例的数据,则只能使用主坐标分析。对于序数型数据,需要使用一种叫做非公制多维标度的方法。
主坐标分析的托格森方法
在深入研究该示例的代码之前,让我们放大一下主坐标分析背后的数学原理。
当开始使用这种方法时,您需要归结为具有所谓的相异矩阵的数据。这意味着数据集中的每一对项目都有一个距离或相异度度量。
请注意,这种方法只能用于实际的距离测量。例如,如果你的值是两倍高,你的距离必须是两倍大。因此,您不能将它用于序数数据,如消费者填写从 1 到 5 的测量范围。为此,您需要使用非公制多维标度。
一旦有了度量距离矩阵,就可以使用 Torgerson 方法(当距离是欧几里得距离时)或迭代法来计算您的解。
托格森方法
托格森方法有两个步骤。你从距离矩阵(我们称之为 D )开始,对其应用双重居中。你会得到一个双中心矩阵,我们称之为 B 。这样做是为了让新生成的贴图的中心位于图形的中间。
双定心的 Torgerson 公式从计算距离的平方开始:

主坐标分析—托格森法第一部分
然后你计算双中心矩阵 B 如下

主坐标分析——托格森法第二部分
矩阵 C 是由单位矩阵(I)和全 1 矩阵(J)计算的定心矩阵。 n 是观察次数:

主坐标分析——托格森法第三部分
然后,对矩阵 b 进行奇异值分解。一旦完成,就可以将 SVD 的前两个维度作为轴来绘制映射。前两个维度上的项目分数将用作地图的坐标。
迭代方法
迭代方法更通用,并且可以在距离(相异)不是欧几里得距离时应用。迭代方法包括最小化成本函数,其定义如下:

主坐标分析——迭代法的成本函数
R 中的主坐标分析
现在让我们转到实现。我们将从法国城市的火车旅行时间数据开始,然后转向品牌研究。
R 中的主坐标分析—示例 1 —感知映射
对于不熟悉的人,让我们从法国 10 大城市的概况开始:

主坐标分析-法国十大城市的位置
为了进行这个分析,我使用了一个行程规划器来获得从一个城市到另一个城市乘火车的旅行时间。我已经把这些旅行时间(以分钟为单位)放在一个距离矩阵中。您可以使用以下代码行直接从 S3 存储桶获取数据:
主坐标分析-获取距离矩阵
距离数据将如下所示:

主坐标分析-获取距离矩阵
注意,这个数据集已经是一个距离矩阵。只是,它是数据框格式。我们需要将它转换成距离矩阵格式,如下所示:
主坐标分析-将数据转换为真实距离矩阵对象
距离矩阵格式如下所示:

主坐标分析—距离矩阵对象
然后,我们可以应用stats包中的主坐标分析函数cmdscale,它将为我们完成 Torgerson 方法的所有数学运算,我们将获得映射的坐标。
主坐标分析-使用 cmdscale 拟合模型
您将获得每个城市的新坐标,如下所示:

主坐标分析-输出坐标
这个坐标矩阵是模型的输出。当然,合乎逻辑的下一步是绘制这些坐标,以获得映射的可视化版本。然后,我们可以按如下方式创建映射:
主坐标分析-绘制新坐标
在下图中,您可以看到您获得的映射。这些城市现在是根据坐火车的旅行时间而不是公里数重新定位的:

主坐标分析—法国十大城市根据火车旅行时间进行重组
那些看过法国原始地图的人会注意到一些奇怪的事情正在发生:东部的城市都显示在西部,反之亦然。因为主坐标分析是基于距离的,所以它不保留原始方向的概念。我们可以很容易地将地图翻转到 x 轴上,以将东部和西部放回原位。您可以使用以下代码来实现这一点:
翻转绘图的 x 轴
现在,您将获得法国十大城市的最终地图,该地图根据乘火车旅行的时间进行了重新组织:

主坐标分析—法国十大城市根据火车旅行时间进行重组
感知映射研究的结论
这张地图让我们看到了一些有趣的事情。首先,我们看到许多城市被投影得彼此更近,除了三个异常值:尼斯、图卢兹和波尔多被彼此拉开,以表示法国南部城市更长的旅行时间。
马赛和蒙彼利埃也在法国南部,但它们离巴黎更近,离其他南部城市更远。这可以用巴黎到马赛的快速列车线来解释。
在法国北部,我们看到从东到西的距离越来越小。从南特到斯特拉斯堡的距离很小,尽管它们在这个国家的两边。
现在,如果你真的想继续进行地图绘制,你可以使用地图或 GIS 包,如cartography包,使这张地图看起来令人惊叹。请注意,当前贴图基于以 0 为中心的贴图。然而,当您想要投影到该国的地图上时,您将需要做出一些额外的决定,包括如何缩放地图以及在哪里放置中心。
R 中的主坐标分析—示例 2 —品牌研究
现在让我们看看产品映射示例。假设你是一家公司,你有一个新产品的想法。你想做一个初步的分析,看看你的产品是否与你现有的产品有足够的不同。
我用 10 种糖果产品创建了一个模拟数据集
主坐标分析-导入数据
该数据包含 10 种糖果,测量了甜味、酸味、咸味和苦味。数据如下所示:

主坐标分析——糖果数据
与前面的例子不同,我们还没有距离矩阵。由于主成分分析的输入是距离矩阵,我们需要首先根据数据计算距离矩阵。R 中的dist函数计算观测值之间的欧几里德距离,如下所示:
主坐标分析-计算距离矩阵
距离矩阵如下所示:

主坐标分析-计算的距离矩阵
现在我们需要使用cmdscale来拟合主坐标分析。代码如下所示:
主坐标分析—拟合模型
您将获得矩阵中 10 颗糖果的坐标:

主坐标分析-每颗糖果的新坐标
您可以在主坐标分析的两个维度上生成 10 颗糖果的图,如下所示:
主坐标分析—绘制糖果分析图
你应该得到如下的情节:

主坐标分析——绘制糖果图
你可以从这个图表中获得一些有趣的见解。大多数糖果都聚集在图表的底部。有一种非常不同的糖果:糖果 5。然后,对于其他糖果,我们可以区分两组:一组在右下角(糖果 2、3、4 和 1),一组在左下角(糖果 10、9、6、7 和 8)。
为了进一步了解维度的实际含义,分析原始变量和两个维度之间的相关性可能会很有意思。这可以通过以下方式完成:
主坐标分析—分析尺寸
这为我们提供了以下相关矩阵:

主坐标分析——相关矩阵
这告诉我们,第一个维度与甜味和酸味有很强的相关性。第二维度主要是代表咸度。
糖果研究的结论
对于我们糖果公司的问题,我们可以得出两点结论:
- 首先,该公司在图表的右上角还没有糖果。对他们来说,研究这是否会有任何附加价值可能是有趣的。这将是一种在两个维度上都得分很高的糖果。这种糖果例如可以是甜/咸的组合。
- 其次,我们可以得出结论,苦并没有真正在现有的维度中表现出来。这意味着苦味在糖果中不会有很大的变化:如果有,它可能会在一个维度中有更强的存在。对公司来说,研究苦味糖果以扩大产品范围可能很有趣。
Python 中的主坐标分析
现在,让我们看看用 Python 实现的两个简短的例子,我们刚刚用 r。
Python 中的主坐标分析-感知制图示例
第一步是导入数据。您可以使用以下代码直接从我的 S3 桶中获取城市距离:
主坐标分析-导入数据
数据是一个距离矩阵,其中包含从一个城市到另一个城市的旅行时间(以分钟为单位)。它看起来如下:

主坐标分析——距离矩阵
我们将用于主坐标分析的 Python 函数只能采用对称距离矩阵。这意味着我们必须在 NAs 中填入相应的值。这很容易做到,用 0 代替 NAs,并对原始矩阵和转置矩阵求和:
主坐标分析-将半距离矩阵转换为对称距离矩阵
结果如下所示:

主坐标分析——对称距离矩阵
现在我们开始建模。您可以使用scikit-bio包进行主坐标分析。您可以使用下面的代码来安装和导入包,并将其导入到模型中。最后,使用.samples属性打印前两个维度中的坐标:
主坐标分析—使用 scikit-bio 拟合模型
这 10 个城市的新坐标如下所示:

主坐标分析-显示 10 个城市的坐标
最后,我们要创建一个由这 10 个坐标组成的图。您可以使用以下代码来绘制带有matplotlib的城市:
主坐标分析-绘制结果
生成的地图如下所示。它与 R 获得的输出相同,只是它是镜像的。我不会重复这些结论,因为它们和我们在上面的 R 分析中看到的结论完全一样。

主坐标分析-根据火车行驶时间绘制城市地图
Python 中的主坐标分析——品牌研究示例
现在,为了完整起见,让我们也为糖果品牌研究做一个 Python 实现。和前面一样,您需要从导入数据开始。您可以使用以下代码获得它们:
主坐标分析-导入糖果数据
数据将如下所示:

主坐标分析 Python 中的糖果数据
这里需要的额外步骤是距离矩阵的计算。在 Python 中,可以使用pdist计算成对距离(每对行之间的距离)。但是,该函数不会生成对称的距离矩阵。你必须添加函数squareform将其转换成对称矩阵:
主坐标分析-在 Python 中计算对称距离矩阵
您将获得以下 NumPy 数组:

主坐标分析-计算对称距离矩阵
现在您已经有了这个矩阵,您可以继续拟合模型了。我们将再次使用skbio包,并用matplotlib绘制结果:
主坐标分析——用 skbio 拟合模型
您将获得与等效 R 代码输出的图形相同的图形。Python 图表如下所示:

主坐标分析——10 颗糖果的映射结果
结论与上面 R 分析中列出的相同。
结论
使用主坐标分析,我们已经可视化了法国 10 个最大的城市,并根据火车旅行时间创建了另一幅法国地图。
我们还使用主坐标分析来分析市场上有 10 种糖果产品的公司的产品品牌。我们绘制了他们现有产品的地图,这让我们能够确定新产品投放市场的潜在利基。
简而言之,主坐标分析是一种探索数据的伟大方法,它允许您将数据可视化,并与特定问题紧密相关。如果你知道如何以及何时使用主坐标分析,它会是一个非常有用的工具。我希望看完这篇文章就是这样!
我希望这篇文章对你有用。不要犹豫,继续关注更多的数学、统计和数据内容!
GDPR 原理及其对您的数据分析平台的影响
原文:https://towardsdatascience.com/principles-of-gdpr-and-its-impact-your-data-analytics-platform-2c64463b2ae5?source=collection_archive---------36-----------------------
数据隐私
GDPR 原则直接影响数据分析平台中个人数据的存储、处理和使用。
通用数据保护规则或他们所谓的 GDPR 足以吓退任何为业务收集客户个人数据的人。然而,这远远超出了每个人一听到 GDPR 这个词就想到的著名的“被遗忘权”的说法。
该条例规定了在处理个人数据方面保护自然人的规则以及个人数据自由流动的规则。
根据 GDPR 法规提供的定义
“个人数据”是指与已识别或可识别的自然人(“数据主体”)相关的任何信息;可识别的自然人是指可直接或间接识别的人,特别是通过参照诸如姓名、身份证号、位置数据、在线标识符等标识符或该自然人的身体、生理、遗传、精神、经济、文化或社会身份所特有的一个或多个因素;

照片由戴恩·托普金在 Unsplash 拍摄
在这篇多系列博客文章中,我试图在企业数据和分析平台的背景下介绍我对 GDPR 官方法规的解读,以及它对这样一个平台的架构和实施意味着什么。让我们看看我是如何解释 GDPR 原则的。
第 5 条规定,应合法、公平、透明地处理与数据主体相关的个人数据。数据的收集和处理受到目的的限制。应收集仅与您定义的目的相关的数据,并且必须通过适当的机制确保数据的准确性,以保持数据最新,并纠正或删除不准确的数据。一旦达到目的,就不应再存储数据,除非出于存档目的。您需要确保安全地存储数据,防止未经授权的访问、处理或损坏。
遵循第 5 条的原则,我将为我的数据平台设计一个架构,重点关注以下几点:
- 元数据驱动的设计,具有强大的 数据目录 以识别数据平台中存储了什么,数据来源于何处,以及从报告数据点到真实来源的详细谱系。
- 数据平台应启用 加密 以保护静态数据。除此之外,数据平台还应该有详细的审计 对数据的访问和处理,并实现基于 角色的访问控制 。应使用数据 匿名化 框架对任何可直接或间接识别数据主体的敏感数据(如姓名、身份证号、位置数据、在线标识符或数据主体的身体、生理、遗传、精神、经济、文化或社会身份的任何特定信息)进行屏蔽或匿名化。
- 数据的准确性应在源系统或捕获、维护和维护与数据主体的合同的地方进行处理,传递变更或告知不准确是数据主体和系统所有者适应变更的责任。但是,尽快捕捉任何此类变更或不准确之处,并根据变更更新数据平台,以及通过适当的数据审计和记录来处理任何不准确之处,这一点非常重要。数据平台应具有批处理或实时数据 提取 和 摄取 框架,以从源系统获取任何此类变更。
- 应重点关注建立一个强大的数据质量框架,该框架带有一个主动反馈回路,以在链的早期强调任何数据不准确或异常。 数据可观察性 的概念对我来说更有意义,因为它是数据质量框架的一部分,用于监控引入数据平台的数据的新鲜度、数量、分布、模式和沿袭。DQ 和 DO 的结合将有助于为数据平台中的数据存储和处理带来更大的透明度。
GDPR 并不意味着您不能存储任何个人数据,但是您应该控制您的数据,并且应该能够向您的数据主体和必要的监管机构说明特定数据主体的数据系统中存储了哪些信息。您应该能够保护对数据的访问,并对数据的准确性负责。据我所知,拥有一个全面且强大的数据治理框架来构建符合 GDPR 标准的数据平台非常重要。
在本系列的下一篇文章中,我们将探讨数据主体的权利及其对数据平台的架构和设计的影响。
参考文献
通用数据保护条例(GDPR)——官方法律文本(gdpr-info.eu)
数据可观察性:数据工程的下一个前沿| Barr Moses |迈向数据科学
如何在不截断的情况下打印完整的 NumPy 数组
原文:https://towardsdatascience.com/print-numpy-array-without-truncation-2d8fc97ca418?source=collection_archive---------15-----------------------
探索在不截断的情况下打印 NumPy 数组的几种不同方法

阳光摄影在 Unsplash 上拍摄
介绍
当打印出 NumPy 数组时,由于大量的元素,默认情况下输出可能会被截断。虽然在大多数情况下这不是问题,但有时您可能必须完整地打印出数组,以便能够检查完整的内容。
在今天的简短指南中,我们将探索将 NumPy 数组打印到标准输出而不进行任何截断的几种不同方法。具体来说,我们将展示如何做到这一点
- 使用
set_printoptions方法 - 使用
printoptions上下文管理器 - 通过将 NumPy 数组转换成列表的列表
首先,让我们创建一个示例 NumPy 数组,我们将在这篇短文中引用它来演示一些概念。
import numpy as np# Create a dummy NumPy array consisting of 250 rows and 40 columns
my_arr = np.arange(10000).reshape(250, 40)
print(my_arr)*array([[ 0, 1, 2, ..., 37, 38, 39],
[ 40, 41, 42, ..., 77, 78, 79],
[ 80, 81, 82, ..., 117, 118, 119],
...,
[9880, 9881, 9882, ..., 9917, 9918, 9919],
[9920, 9921, 9922, ..., 9957, 9958, 9959],
[9960, 9961, 9962, ..., 9997, 9998, 9999]])*
正如您在上面看到的,当输出到标准输出时,numpy 数组的列和行都被截断。
使用set_printoptions方法
[numpy.set_printoptions](https://numpy.org/doc/stable/reference/generated/numpy.set_printoptions.html)是一种用于配置显示选项的方法,例如数组、浮点数和其他numpy对象显示到标准输出的方式。
在set_printoptions中接受的参数之一是threshold,它对应于触发全表示汇总的数组元素的总数。默认情况下,该值设置为1000。为了在没有总结的情况下触发完整的表示,您应该将threshold设置为[**sys.maxsize**](https://docs.python.org/dev/library/sys.html#sys.maxsize)。
import sys
import numpy as np**np****.set_printoptions(threshold=sys.maxsize)**
此外,如果您还想通过在调用set_printoptions()时指定precision参数来调整浮点输出的精度。
使用 printoptions 上下文管理器
在许多情况下,您可能希望完全打印一个或几个 numpy 数组,然后使用默认选项。在这种情况下,上下文管理器是一个非常有用的构造,可以帮助您做到这一点。
NumPy 附带了一个名为[np.printoptions](https://numpy.org/doc/stable/reference/generated/numpy.printoptions.html#numpy.printoptions)的上下文管理器,帮助您在with块的范围内设置打印选项,然后在最后恢复旧的选项。
import sys
import numpy as np**with np.printoptions(threshold=sys.maxsize):
print(my_arr)**
将数组转换为列表
前一种方法的另一种替代方法是使用[numpy.ndarray.tolist()](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.tolist.html)方法将 NumPy 数组转换成一个列表。
import numpy as np **print(my_arr.tolist())**
最后的想法
在今天的简短指南中,我们探索了几种完全打印 NumPy 数组的不同方法。默认情况下,在标准输出中打印的数组可能会被截断(取决于它们的大小/元素)。
在许多情况下,您可能希望完整地查看所有元素,因此本文中介绍的选项是一个很好的参考,可以帮助您做到这一点。
成为会员 阅读媒体上的每一个故事。你的会员费直接支持我和你看的其他作家。你也可以在媒体上看到所有的故事。
https://gmyrianthous.medium.com/membership
你可能也会喜欢
</16-must-know-bash-commands-for-data-scientists-d8263e990e0e> </8-must-know-venv-commands-for-data-scientists-and-engineers-dd81fbac0b38>
使用 AWS Nitro Enclaves 保护隐私的深度学习
原文:https://towardsdatascience.com/privacy-preserving-deep-learning-with-aws-nitro-enclaves-74c72a17f857?source=collection_archive---------21-----------------------
在不泄露用户数据的情况下生成机密推断

杰森·登特在 Unsplash 上拍摄的照片
不断扩大的机密计算领域本质上可归结为两个主要属性:
- 保密性:我们如何对敏感的用户数据(如健康记录和信用记录)进行计算操作,而不会“看到”未加密形式的数据?
- 完整性:如果我们能够完成(1),我们如何向用户证明他们的隐私得到了保护?
AWS 认为他们在 Nitro Enclave 产品中找到了答案,该产品利用现代处理器上的可信执行环境 (TEE)来创建可验证的应用程序,这些应用程序不会被外部网络甚至主机操作系统篡改。TEE 提供了机密性和完整性,但是众所周知它们很难使用。在本教程中,我们将使用 Nitro Enclave 平台完成一项相对复杂的任务(按照机密计算标准):根据用户提供的图像对卷积神经网络进行安全评估。
“抬起并移动”
AWS 将 Nitro Enclaves 吹捧为一种“提升和转移”解决方案,但 TEE 引入了一些我们必须在应用中解决的特质。好消息是标准的 docker 图像可以转换成“Enclave 图像文件”(。EIF)的格式。我们可以构建相对丰富的程序,而不局限于某种语言或 OS,我们可以将几乎所有的主机内存和 CPU 资源分配给 TEE。使用 Nitro CLI ,许多低级操作被抽象成一些简单的命令。
虽然这些特性极大地降低了开发机密应用程序的学习曲线(尤其是与遗留平台相比),但这并不意味着您可以将未经修改的 docker 映像放入一个飞地,并期望它能够工作。最显著的区别是网络接口——Nitro Enclave 与所有外部连接完全隔离,除了允许它与主机实例通信的本地套接字。虽然这导致了一个防篡改的计算环境,但这也意味着我们将不得不求助于低级协议(例如 Python 的套接字库)来传输数据进出飞地。

Nitro Enclaves 只能通过安全的虚拟套接字与父实例通信(图片由作者提供)
飞地孤立的另一个有问题的副产品是它们很难产生熵。普通的个人计算机从物理现象如旋转的磁盘驱动器、键盘敲击或鼠标点击中捕获随机字节的缓冲区。这种熵随后被用在依赖真正随机性的操作上,比如加密和密钥生成。相比之下,enclaves 被设计为安全且可预测地启动,以便创建可靠的证明文档,这使得熵成为一种珍贵的商品。为了让我们的应用程序顺利运行,我们必须想出一种方法来“填满”我们的随机缓冲区。
机密分类场景
医疗领域为机密计算提供了一个极好的用例,因为多个利益相关者希望他们的数据是私有的。在这个例子中,我们考虑一个应用程序,其中患者可以查询一个经过训练的卷积神经网络,以查看他们是否患有皮肤癌。用户希望确保他们的输入和诊断永远不会透露给开发人员,而开发人员希望避免与用户共享他们的专有模型。下图显示了我们的机密推理工作流程。

我们的机密推理工作流程,它将允许用户获得皮肤癌诊断,而无需向应用程序(图片由作者提供)透露输入(皮肤病变的图像)。
设置父应用程序
为了清楚起见,我们将把父应用程序分成两个主要进程:发送和接收数据。让我们从VsockListener类开始,它是通过虚拟套接字从 enclave 接受消息的服务器进程:
在recv_data_parent函数中,我们定义了一个处理输入内容的简单协议。通常,您会添加一些头字节或其他预定义的编码来告诉服务器传输中包含什么类型的信息,但我们将只使用消息的大小来确定它可能包含什么数据。加密的推断(一个可以映射到诊断标签的数字)大约为 100 字节,enclave 的公钥大约为 400 字节。加密的对称密钥介于两者之间,大约 256 字节。在这里看看对我们正在实现的混合加密协议的解释。
现在,让我们来看看父节点如何将信息传输到飞地。
我们将等到收到 enclave 的公钥后再调用这个类,因为我们需要它来不对称地加密我们的图像。注意,在我们发送图像或密钥之前,我们发送后续消息的长度,以便 enclave 知道预期有多少字节(在使用套接字几天之后,您将再也不会认为 HTTP 是理所当然的了!).
我们将使用参数解析器从命令行运行这些处理程序,例如python3 vsock-parent.py server <port-in>(用于监听器)和python3 vsock-parent.py client <enclave-cid> <port-out>(用于客户端)。
现在让我们来看看 enclave 应用程序代码。
建立飞地
enclave 应用程序与父应用程序非常相似,只是我们将使用一个程序来处理发送和接收数据。查看 Github 资源库中的脚本。我想强调几个关键的区别。首先,在我们尝试任何加密或解密之前,使用 rng-tools 包生成一些熵是至关重要的,原因在简介中讨论过。我们可以用subprocess.run(‘rngd -r /dev/urandom -o /dev/random’, shell=True)从 python 脚本中启动守护进程。如果没有这一行,应用程序只会在需要随机性的步骤无限期挂起。
为了在我们的 enclave 映像中节省宝贵的内存,我选择了 Tensorflow Lite 运行时,而不是成熟的 Tensorflow 安装(单独安装就可能超过 2–3GB)。只要有可能,尽量限制你的 enclave 的计算开销,就像你在为微控制器或 Raspberry Pi 开发应用程序一样。调用 Tensorflow Lite 解释器并生成推理的代码可以在这里找到。
最后,让我们看一下 docker 文件,它包含了构建我们的映像的指令。
安装依赖项、复制文件以及用ssh-keygen生成我们的 RSA 密钥对应该相对简单。在最后一行,我们使用命令行参数启动 python 应用程序;父实例的 CID 是 always 3,我们将使用端口 5005 和 5006 来发送和接收数据。
设置完成后,让我们来谈谈实现。
逐步演示
启动一个与 Nitro Enclave 兼容的 EC2 实例,比如一个 m5.4xlarge,并确保在设置过程中启用 Enclave 选项。请记住,我们需要足够的内存和 CPU 内核来运行父设备和 enclave。虽然您可以使用大多数基于 Linux 的平台,但我推荐 Amazon Linux 2——否则,您将不得不自己构建 Nitro CLI。通过 SSH 登录到您的实例,并使用
sudo yum update
我们还需要安装 docker 和 Nitro CLI。
sudo amazon-linux-extras install docker aws-nitro-enclaves-cli aws-nitro-enclaves-cli-devel -y
启动 docker 服务。
sudo service docker start
提升 docker 和 nice 编辑器的用户权限。
sudo usermod -aG ne ec2-user && sudo usermod -aG docker ec2-user
接下来,我们需要配置 enclave 能够访问的资源(CPU 内核和内存)。编辑/etc/nitro_enclaves/allocator.yaml文件,将缺省值增加到 8192 MB RAM 和 4 个内核(尽管我相信你可以少用一些)。要提交这些更改,请运行
sudo systemctl start nitro-enclaves-allocator.service && sudo systemctl enable nitro-enclaves-allocator.service
此时,重启您的实例,让各种更新生效。
重新启动后,克隆公共存储库
git clone [https://github.com/evandiewald/nitro-enclave-tensorflow.git](https://github.com/evandiewald/nitro-enclave-tensorflow.git)
和cd进入回购目录。构建 docker 映像,使用
docker build -t enclave-tensorflow .
成功创建映像后,我们使用 Nitro CLI 将其转换为 EIF 文件:
nitro-cli build-enclave --docker-uri enclave-tensorflow:latest --output-file enclave-tensorflow.eif
如果一切顺利,您将看到一个包含 3 个 SHA 散列的证明文档,它们对应于 enclave 映像、内核和应用程序。

build-enclave 命令的输出,显示了 enclave 映像、linux 内核和您的应用程序(由作者创建的映像)的散列。
在运行 enclave 之前,我们需要确保我们的父实例正在监听连接。打开一个新的终端并运行
python3 vsock-parent.py server 5006控制台应打印Server ready!
回到第一个终端,让我们最终执行 enclave 应用程序。同样,我们将使用 Nitro CLI
nitro-cli run-enclave --eif-path enclave-tensorflow.eif --memory 8192 --cpu-count 4 --enclave-cid 16 --debug-mode
一个成功的输出将显示一些关于 enclave 及其资源的基本元数据。

run-enclave 命令的输出,显示哪些 CPU 内核和多少内存已经分配给我们的安全 enclave(图片由作者提供)。
记下 EnclaveID,您将在下一步中需要它。一旦 enclave 启动,另一个终端中的服务器应该会打印出Enclave's public key received.,但是出于调试的目的,最好能知道我们的 enclave 中发生了什么。由于我们包含了--debug-mode标志,Nitro CLI 公开了一个控制台,允许我们查看应用程序的输出,并确保它正常运行。
nitro-cli console --enclave-id $ENCLAVE_ID
您将会看到一长串描述引导操作的打印输出,但是在底部您应该会看到一些来自 python 应用程序的消息。

enclave 的控制台输出,仅在调试模式下可用。在将其公钥发送给父实例后,我们的应用程序监听传入的消息(图片由作者提供)。
此时,打开第三个终端,将用户数据从 parent 发送到 enclave
python3 vsock-parent.py client 16 5005 (16 是飞地 CID)
该终端应该表明它正在发送父级的公钥、加密图像和对称密钥。

通过虚拟套接字从父实例向 enclave 发送消息后 vsock-parent.py 的输出(图片由作者提供)。
回到 enclave 控制台,在对图像进行分类、加密推理并将其发送回父服务器之前,应用程序将确认收到并解密了消息。此时,enclave 将关闭,给出一个连接错误。

回到 enclave 控制台,我们的独立应用程序现在已经接收到加密的图像,使用训练好的模型对其进行分类,并向用户发送加密的推断。所有敏感数据在不在 TEE 中时都受到保护(图片由作者提供)。
最后,服务器将接收推断,解密,并打印出结果!

皮肤损伤的输入图像被正确地分类为基底细胞癌的例子。该诊断对应用程序开发人员不可见,只对患者可见(图片由作者提供)。
不要忘记终止您的 EC2 实例,以防止进一步的费用。
最后的想法
在本教程中,我们看到了 TEE 如何使两个分布的利益相关者共享数据,而不需要假设明确的信任。Nitro enclave 是硬件、软件和高级加密技术的胜利,但一旦你加入一点复杂性,它们就会引起一些独特的头痛。我以前从未担心过套接字或熵,与标准 docker 容器相比,调试 enclave 映像是一个痛苦的过程。完成这个项目后,我并不惊讶,我能找到的唯一其他教程是“hello world”应用程序。虽然这个演示远非最佳,但我希望它可以作为您自己的健壮的安全多方计算平台的一个有用的起点。
在我的 Github 页面查看完整的项目代码。
参考
Nitro Enclaves 用户指南:https://docs . AWS . Amazon . com/enclave/latest/User/nitro-enclave . html
Github 上的 AWS VSock 示例:https://Github . com/AWS/AWS-nitro-enclaves-samples/tree/main/VSock _ Sample/py
经过训练的皮肤损伤分类器模型(我将 h5 模型权重转换为 TFLITE 模型):https://github.com/aryanmisra/Skin-Lesion-Classifier
使用 Azure 的数据科学专用 Docker 存储库
原文:https://towardsdatascience.com/private-docker-repositories-for-data-science-with-azure-cccb2b37a647?source=collection_archive---------50-----------------------
机器学习工程师基础知识——如何设置私有容器库,保护它们,在云中使用 Azure 进行部署和共享

伊恩·泰勒在 Unsplash 上拍照
介绍
如果你已经在你的数据科学项目中使用 Docker,那么很好——你现在可能想学习如何私下管理和共享你的容器。这篇文章将向你展示如何在 Azure 中建立并运行私有存储库。
要求
对于本教程,您需要安装以下软件:
- Docker —可以在这里找到
- Azure CLI —可以在这里找到
如果您不确定从哪里开始使用 Docker,我已经写了两部分的系列文章,包括启动和运行,然后在这两篇文章中部署端到端的机器学习服务:
第一部分介绍了如何使用 Docker,所以如果您还没有准备好,请随时进入并准备好。
我在 Windows 机器上工作,因此安装 Azure CLI 非常简单:
choco install azure-cli

用 Chocolatey 安装 Azure CLI(图片由作者提供)。
设置 Azure CLI
安装了 CLI 后,我们现在需要进行设置。首先,我们需要从我们的机器登录。如果你还没有账户,你可以在这里注册免费试用。

az 登录命令的 Azure 登录页面(图片由作者提供)。
您应该会看到这样的响应:

一旦你成功登录,你应该有类似的东西,包括你的 GUIDs 和订阅细节(图片由作者提供)。
资源组
下一步是创建一个新的资源组来运行所有的东西。这有助于我们在运行它们时跟踪它们,并允许我们在完成教程后删除所有内容。使用以下语法创建资源组非常简单:
az group create --location <desired_location> --name <resource_group_name>
我将使用英国西部地区,并将我的资源组称为asrokademos。这将给出以下输出,我们可以通过点击 Azure 这里的来检查资源组在门户中是否存在:

使用 CLI 创建我们的资源组,并检查它在门户中是否成功(图片由作者提供)。
集装箱登记处
现在让我们在这个资源组中创建一个 Azure 容器注册中心(ACR)。语法如下:
az acr create --resource-group <resource_group_name> --name <acr_name> --sku <sku_type>
你为你的 ACR 选择的名字在 Azure 中必须是唯一的,我称这个名字为asrokadfds。我们将它放在刚刚创建的资源组中,并使用--sku Basic。同样,我们可以检查终端(将会很长)和门户的输出,这里是:

在 CLI 中创建我们的 Azure 容器注册表。

我们的 Azure 容器注册表现在在门户中可见(图片由作者提供)。
然后,我们需要登录我们的 ACR 来验证我们是否被允许部署映像。然后,我们可以使用第二个查询来获得 ACR 的完整路径,我们需要开始向它部署容器。注意,如果你在 Windows 上运行,确保 Docker 正在运行,否则会出错。
az acr login --name <acr_name>
az acr show --name <acr_name> --query loginServer --output table

CLI 显示我们成功登录到 Azure container registry,并返回准备好映像部署的完整路径(image by author)。
将图像推送到我们的容器注册表
下一步是将我们的图像共享到注册中心。这很简单,遵循与将图像推送到 DockerHub 相同的模式。我们需要确保我们的图像首先被标记,语法如下:
docker tag <repo_name>/<image_name>:<version><acr_name>/<image_name>:<version>
我将把我在 Docker 中为数据科学家创建的 Iris Flask 应用程序—第 2 部分推送到新的 ACR。

使用 Docker(按作者分类的图像)将现有图像标记到新的存储库中。
注意,从命令末尾开始保留标签会导致 Docker 自动追加latest标签。显式使用标记是明智的,因为它使您能够将容器注册表用作工作图像的版本控制。
既然图像已被标记,我们可以将它推送到 ACR,并使用以下命令检查它是否在那里:
docker push <acr_name>/<image_name_on_acr>:<version>
az acr repository list --name <acr_name> --output table

我们的本地容器图像被成功地推送到 Azure 容器注册中心。
因此,现在我们在云中有了这个容器,我们可以执行它,与其他可以访问 ACR 的人共享它,或者将其作为构建其他容器的基础——这是一个重要的功能,因为它允许我们开始模板化我们数据管道的复杂部分。
安全地共享我们的注册表
要访问我们的 ACR,我们需要创建一个服务主体—我们可以这样做,创建一个密钥库,并在其中存储服务主体,所有这些都使用 CLI。如果你对此不熟悉或者遇到困难,这里的文档非常有用。
首先,使用以下语法创建密钥库
az keyvault create --resource-group <resource_group_name> --name <keyvault_name>
在 Azure 中,<keyvault_name>应该是唯一的。我这里用的是asrokdademoskeyvault:

使用 Azure CLI 创建用于存储我们的秘密和凭证的密钥库(图片由作者提供)。
然后,我们需要获得 ACR 的 ID、服务主体 ID 和服务主体密码。因为您将在周围传递它们,所以建议将它们保存到变量中——我将使用ACR_ID作为 ACR ID,AZ_SP_ID作为服务主体 ID,AZ_SP_PW作为密码。获取 ACR ID 的语法是:
az acr show --name <acr_name> --query id --output tsv
然后,我们可以使用以下命令获取密码:
az ad sp create-for-rbac --name http://<full_acr_name>-pull scopes <acr_id> --role acrpull --query password --output tsv
您的终端应该如下所示:

创建 ACR ID 和密码,并将它们保存到变量中以备后用(图片由作者提供)。
然后,我们可以使用以下语法生成服务主体 ID:
az ad sp show --id http://<full_acr_name>-pull --query appId --output tsv
对我来说是这样的:

使用 Azure CLI 获取服务主体 ID 的命令(图片由作者提供)。
最后一步是将这些凭证存储在我们创建的密钥库中,以便可以安全地访问和共享它们。对于服务主体密码,可以通过运行以下命令来完成:
az keyvault secret set --vault-name <keyvault_name> --name <acr_name>-pull-pwd --value <service_principal_password>
如果成功,您应该会看到类似这样的内容:

服务主体已添加到密钥库中(图片由作者提供)。
同样,对于应用程序 ID 使用:
az keyvault secret set --vault-name <keyvault_name> --name <acr_name>-pull-usr --value <service_principal_app_id>
我们现在已经成功创建了一个 Azure key vault,并在其中存储了两个秘密:
<acr_name>-pull-usr保存服务主体 ID,它将被用作容器注册用户名<acr_name>-pull-pwd持有将用于安全访问容器注册中心的服务主体密码
现在,如果您的内存中没有<service_principal_password>或<service_principal_app_id>,您可以使用以下命令来调用它们:
$AZ_SP_ID=az keyvault secret show --vault-name $<keyvault_name> -name $<acr_name>-pull-usr --query value -o tsv)$AZ_SP_PW=az keyvault secret show --vault-name $<keyvault_name> -name $<acr_name>-pull-pwd --query value -o tsv)
在 Azure 上部署
现在一切都设置好了,让我们在 Azure 上部署容器。使用 Azure CLI 和我们的密钥库,这就像运行以下命令一样简单:
az container create --resource-group <resource_group_name> \
--name <container_name> \
--image <repo_name>/<image_name>:<tag> \
--registry-login-server <acr_full_name> \
--registry-username <service_principal_app_id> \
--registry-password <service_principal_password> \
--dns-name-label <container_name>-$RANDOM \
--query ipAddress.fqdn
其中<container_name>是您要创建的容器的名称——任何合适的名称都可以。

我们使用 Azure CLI 创建的 Docker 容器
--query ipAddress.fqdn选项会返回当前正在运行的容器的完全限定地址。如果您检查门户中的资源组,您会看到现在有一个正在运行的实例。现在您将能够 SSH 到容器中,或者如果您已经向端口 80 公开了一个 API,您将能够从 URL 直接访问它。
注意——记得清理!如果你只是把它当作一个教程来玩,记得删除你的资源组以避免不必要的费用。
结论
我们已经创建了一个 Azure 容器注册中心,上传了一个 Docker 映像,并存储了从任何地方安全访问和部署该映像所需的凭证。这使您能够开始私下共享您的 Docker 容器,并构建您自己的图像库,而无需依赖 Docker Hub。
对于希望看到自己的模型投入生产的机器学习工程师和数据科学家来说,这是一项重要的技能。Docker 和容器注册表是现代部署方法中的一个基本构建模块 Kubeflow、Kubernetes 和 Helm 等工具正在成为将机器学习项目集成到可扩展服务中的首选方式。使用这种方法,您的模型可以根据需求进行扩展,并且可以轻松地与您的客户和团队共享。
我希望这是有用的,如果您有任何反馈,请告诉我—联系:
- www.twitter.com/adzsroka的推特
- www.linkedin.com/in/aesroka的 LinkedIn
- 或者在www.adamsroka.co.uk
如果你对我写的其他话题感兴趣,请告诉我!
R 中数据分析的专业技巧
原文:https://towardsdatascience.com/pro-tips-for-data-analysis-in-r-45848bf48de9?source=collection_archive---------6-----------------------
为了更好的工作流程——基于我 5 年争论数据的经验。

约翰·施诺布里奇在 Unsplash 上的照片
r 和 Python 是最流行的数据分析编程语言之一。作为一名数据科学顾问,我在工作中的许多项目中都在研究开发。有很多事情我希望我能早点知道!在这篇文章中,我想和你分享一些我学到的最重要的技巧,当你开始在 r 中工作时,这些技巧可以改善你的工作流程。
*注:如果你更喜欢看这篇文章的视频版本,你可以查看下面我的 Youtube 频道上的视频。
提示 1:使用 R 项目
让我告诉你一些事情。在使用 R 好几年后,我意识到我犯了一个非常非常严重的错误。那个错误就是我没有用 R 项目。你可能不常在 R 编程在线课程和编程书籍中看到 R 项目的介绍。但是这是一种耻辱,因为有很多很好的理由说明为什么 R 项目可以让你的工作流程变得更加干净和流畅。
如果你不知道 R 项目是什么,它只是一个用。RProj 文件。你可以通过进入文件>新建项目 >在 RStudio 中创建新的 R 项目,然后你可以在给定的目录中创建新的项目。

一个空 R 项目。作者图片
但是,好吧,你可能会问,使用 R project 的好处是什么,而不是把你的代码和所有东西都放在一个普通的文件夹里。以下是原因:
- 首先,R 项目消除了设置工作目录的需要,因为一切都变成了项目文件夹的相对文件路径。这意味着你不需要设置绝对路径,所以你可以与任何人共享你的项目文件夹,他们仍然可以运行它。我曾经在代码中设置了绝对路径,犯了一个严重的错误,每次当我将它发送给同事或推送到 Github 时,我的同事都不得不费力地更改路径,以使它在他的计算机上工作。
- 这就引出了第二点,那就是项目改善既再现性又协作。给定 R 项目文件夹,每个人都可以运行您的代码,而无需设置工作目录。因为项目文件夹将始终是该文件夹中代码的默认工作目录。
- r 项目也是方便的,因为它可以选择用 Git 进行版本控制。所以您不需要在以后为您的项目初始化 Git repo。
技巧#2:构建分析文件夹
如果我告诉你,你需要组织你的项目文件夹,这可能看起来有点琐碎。但我向你保证,这会让你的工作流程变得更有效率。
让我给你展示一个我的项目文件夹的简单设置。这是一个适用于许多不同类型项目的模板,但它当然可以根据您的需求进行调整:

我的分析模板文件夹。作者图片
- 数据——这是我保存所有源文件的子文件夹,我需要将这些文件读入 R 以进行分析或可视化。这些可以是 Excel / CSV 文件中的任何内容,或者。RDS 文件,这是存储 R 对象的文件类型。
- 脚本 —这是我保存所有 R 脚本和 RMarkdown 文件的地方。我发现将所有的 函数 保存在一个独立于我的主分析脚本的脚本中很方便,因为它帮助我的主分析脚本更干净。我只需要将这些函数读入我的分析脚本,而不是将它们都放在一个大脚本中,这样会使代码变得混乱和笨拙。 run_analysis 文件是我运行所有分析的主要分析 R 脚本。由您决定是使用一个分析脚本还是多个脚本来执行不同的任务。如果您有一个 R markdown 文件,您也可以将其保存在该文件夹中。

- 输出——在这个文件夹中,我保存了我所有的输出,包括绘图、HTML 和数据输出。拥有这个输出文件夹有助于其他人轻松识别哪些文件是代码的输出。它还可以帮助您更快更容易地找到输出。
当您开始处理具有许多不同脚本和输入输出文件类型的更复杂的项目时,这种结构将帮助您组织起来,并帮助团队中的新成员理解项目。这种结构也将你的函数从分析运行中分离出来,从输出文件中分离出输入,当有一天你想从你的代码中创建一个 R 包时,这是非常有用的。一般来说,你设置了什么样的子文件夹并不重要,只要它们是合理的。您可以决定设置子文件夹,以便它们与分析步骤而不是文件类型保持一致。
技巧 3:Base R vs tidy verse vs data . table——我使用什么
您可以在 R 中使用不同的库或生态系统,它们为操作数据提供不同类型的语法,有些更快,有些更慢。3 个最常见的包/生态系统是:
- 碱基 R
- Tidyverse (dplyr 是主包之一)
- 数据表
而如果你不知道用什么,我在这里稍微宠一下你:我大概 95%的时间都用 data . table,主要是因为简洁的语法和它处理大数据集无与伦比的速度。久而久之就上瘾了!我太喜欢它了,我写了一篇文章,我写了一整篇关于前一段时间的文章。
让我们对这些包做一个小小的比较,让您有一个大概的了解。在下面的图片中,你可以看到每个库中关键函数的摘要。

来源:https://mgimond.github.io/rug_2019_12/Index.html
你可以看到语法看起来有点不同。尤其是tidyverse比其他两个更加冗长。data.table有这种典型的数据操作语法。

来源:https://github.com/Rdatatable/data.table/wiki
这些生态系统各有利弊:

生态系统的利与弊。作者图片
但是不管你采用什么样的库和语法,在一个脚本中坚持使用其中的一种是一个很好的实践,这样其他人更容易理解你的代码。
技巧 4:在 RStudio 中使用调试器工具
编程中最重要的事情之一就是学习如何调试你的代码。我们人类并不完美,我们会犯错误,所以如果你在用 R 或 Python 做数据分析,调试你自己的代码可能是你大部分时间要做的事情。我后悔没有早点使用 Rstudio 中的调试器工具。
在早期,我只是手动进入每个函数并打印出每个步骤的输出。这没什么错,但它很快就会变得令人困惑,需要花费大量的时间和精力。我鼓励您学习如何使用 Rstudio 中的调试器工具。
Rstudio 文档有一篇关于这方面的非常好的文章,一定要去看看!否则你也可以在我的视频中看到教程。
额外提示#5:保存分析运行的日志文件
有时,您正在处理的数据集会每天或定期更新,这可能会影响您的分析结果。创建一个带有时间戳的小日志文件,在其中存储分析的关键信息,如数据的描述性统计和分析的主要结果,这将非常方便。您可以只为自己跟踪数据的变化(以及随后的分析)。
R 中有一个名为sink()的小函数,它可以将所有的打印结果指向一个文本文件。

示例日志文件。图片作者。
我希望这些建议和技巧对你有所帮助,并在下面的评论区告诉我你的想法和你想分享的其他建议。感谢您的阅读!
如果你喜欢我关于数据科学的内容(偶尔还有与技术相关的东西和个人成长),别忘了在 Medium 上关注我,注册我的邮件列表。
想要连接? 你可以通过LinkedIn,Youtube,或者GitHub联系到我。我随时欢迎快速聊天或虚拟咖啡:)。
风力涡轮机的概率深度学习
原文:https://towardsdatascience.com/probabilistic-deep-learning-for-wind-turbines-b8ea00fabe30?source=collection_archive---------28-----------------------
如何对大数据应用高斯过程
在大型数据集上,模型速度可能是一个决定性因素。利用实证研究,我们将着眼于两种降维技术,以及它们如何应用于高斯过程。

图 1:方法概述。CNN 是卷积神经网络,GPR/VGPR 是不同的高斯过程回归。图片作者。
关于该方法的实现,任何熟悉条件概率基础的人都可以开发高斯过程模型。然而,要充分利用框架的功能,需要相当深入的知识。高斯过程的计算效率也不是很高,但是它们的灵活性使它们成为小生境回归问题的常见选择。
事不宜迟,我们开始吧。
技术 TLDR
高斯过程(GPs)是非参数贝叶斯模型。对数据点之间的协方差进行建模,因此对于大于 10,000 个数据点的数据集是不切实际的。然而,他们的灵活性是无与伦比的。
为了在大型数据集上运行 GPs,我们概述了两种要素缩减方法。第一种是学习潜在特征的卷积神经网络。该论文引用了将 2501 个特征减少到 4 个,这使得该问题在计算上易于处理。在此基础上,他们利用稀疏高斯过程减少了所需的数据点数量,进一步提高了建模速度。
总体而言,高斯过程观察到最高的准确性,但是稀疏高斯过程表现出相似的准确性和更快的运行时间。
这是纸。
但是实际上是怎么回事呢?
让我们稍微慢下来,讨论一下特征约简方法是如何工作的。
1 —背景
当创建风电场时,它只是一系列的风力涡轮机,涡轮机的位置非常重要。从涡轮机折射的空气会显著影响后续涡轮机的效率。为了优化这种配置,我们求助于计算流体动力学。

由尼古拉斯·多尔蒂在 Unsplash 上拍摄的照片
大多数流体(空气、水等。)模拟依赖于经验数据和物理方程。然而,许多数据集包含大量嘈杂和复杂的数据。在我们的案例中,论文中引用的数据集是从德克萨斯州的一个风电场收集的,历时两年,包含每个涡轮机的 2501 个特征。行数没有透露。
如果我们希望开发实时优化,我们必须简化我们的数据。这就是自动编码器的用武之地。
2 .1 —自动编码器
自动编码器是编码器-解码器框架的一个子集,用于维护特征结构。简单来说,我们希望执行两个步骤。

图 2:自动编码器框架。关键是数据输入和输出结构是相同的。图片作者。
首先,我们将数据编码成少量的潜在变量。这些潜在变量可用于训练我们的模型,从而大幅减少训练时间。在这篇论文中,作者能够将 2501 个原始特征编码成 4 个潜在特征。
第二,我们将那些潜在变量解码回我们数据的原始结构。我们需要这一步,因为我们无法处理潜在变量,我们必须有真实的预测。
注意,这里我们使用自动编码器来减少特征,但是还有许多其他用例,其中一些包括异常检测和数据“清理”。
2.2—卷积自动编码器
最流行的自动编码器框架之一利用了卷积神经网络(CNN)。

图 3:卷积示例— src 。图片作者。
CNN 是一个简单的神经网络,其中“窗口”在数据集上重复移动。它们很受图像分类的欢迎,因为它们很有效,也很容易理解。然而,当扩大到二维数据之外时,CNN 仍然非常有效。
我们将 CNN 自动编码器框架应用于我们的风数据集,最终得到一个明显更小的数据集。我们现在已经准备好去适应“真实的”模型了。
3 —高斯概率回归
在本节中,我们将提供高斯概率(GP)模型的高级解释。该论文还实现了一个多层感知器和主动学习模型,但都显示出较低的准确性或计算效率相对于 GP 模型。
最精确的方法——精确高斯过程
精确高斯过程是非参数贝叶斯模型。我们从关于数据的先验假设开始,然后利用数据点之间的协方差来更新我们的先验假设。最后,根据我们的潜在特征(X ),我们得到了因变量(Y)的概率估计。这个概率也叫后验概率。

图 4:按组件分解的贝叶斯定理。图片作者。
对于我们的示例应用程序,我们希望找到在给定 4 个潜在特征的情况下观察到风力涡轮机流量的概率。图 4 中的贝叶斯定理分解了整个概率。
右侧的三个组件都可以估计,但是需要一些工程设计的主要组件是先验。
先验概率分布,通常被称为“先验”,是在查看 X 值之前,Y 变量的概率分布。为了计算这个基线,我们只需假设它是正态分布的,并使用我们的 Y 估计平均值和标准差。
对其他两个组件的评估超出了本文的范围,但是可以查看评论中一些有用的链接。
从性能的角度来看,精确的高斯过程具有时间复杂度,精确的高斯过程的时间复杂度是 O(n ) ,其中 n 是我们数据中的行数。实际上,这将我们的数据集大小限制在 ~10,000 个数据点 。下面我们概述了一种将运行时间复杂度降低到 O(nm ) 的方法,其中 m 是从我们的原始数据集中提取的一组稀疏特征。
最快的方法——稀疏高斯过程
为了提高模型拟合的速度,作者实现了稀疏高斯过程(SGP)。
简而言之,SGP 利用一组最接近我们观察到的数据的 m 个数据点。然后我们可以用它们来拟合我们的模型。虽然这些精度变化高度依赖于数据集,但对于风力涡轮机数据集,4 个潜在特征中的每一个都分别表现出 7%、20%、14%和 5%的精度下降。
因此,如果这些模型的目的是实时优化,稀疏高斯过程可能是一个可靠的替代方案。
我们来快速看一下这些 m 数据点是怎么选出来的。不幸的是,论文中引用的数据是不公开的,所以我们将创建自己的数据。

图 5:1000 个数据点的训练集(蓝色),大致遵循我们的潜在数据生成函数(黑色)——src。图片作者。
在上面的图 5 中,我们可以看到用蓝色 X 表示的训练数据。这些是使用潜在函数(黑色实线)和一些随机噪声生成的。在 1000 个训练点中,我们的目标是估计出最接近我们训练数据的 m=30 个点。
通过仅拟合 30 个点,我们希望在不牺牲准确性的情况下显著降低运行时间的复杂性。最佳的 30 个点如下图 6 所示。

图 6:m = 30 时的最佳诱导变量— src 。图片作者。
在不太专业的情况下,我们希望用平均值和协方差来描述我们的 m 数据点。在找到每个的最佳值后,我们可以从正态分布 N(mean_m,cov_m) 中采样 30 个数据点。如果你想深入了解,这里有一个极好的资源。
现在我们有了更少的数据点,我们可以更快地拟合我们的模型,而不会牺牲太多的准确性。
最后,这里有一个优化过程的有趣动画。

图 7:稀疏高斯过程优化的动画— src 。图片作者。
这就是你所知道的 GPs 的高层次概述,以及如何将它们应用于 CNN 衍生的潜在特征。
摘要
在这篇文章中,我们讨论了如何简化计算复杂的模型。我们首先使用卷积神经网络来寻找减少数据集中列数的潜在特征。我们还拟合了一个稀疏高斯过程来减少数据集中的行数。
精确高斯过程表现出最高的准确性,但是在需要实时优化的情况下,稀疏选项可能更好。
感谢阅读!我会再写 29 篇文章,把学术研究带到 DS 行业。查看我的评论,链接到这篇文章的主要来源和一些有用的资源。
概率预测和库存优化
原文:https://towardsdatascience.com/probabilistic-forecasting-and-inventory-optimization-70edbb8f4a81?source=collection_archive---------14-----------------------
预测只能帮助你做出正确的供应链决策。
在接下来的 1000 个单词中,我将向你展示为什么点预测不足以做出供应决策。相反,你会明白为什么你需要概率预测来做出明智的决定。
先说个例子;我们以后再讨论理论。
基于需求预测的运营决策
你在经营一家面包店。每天清晨,你需要决定一天要烤多少。作为面包店经理,这是你需要做出的最重要的经营决策。你需要每天都这样做。
让我们假设你预测你今天要卖 10 块面包。你应该烤多少个?

credit:https://en . Wikipedia . org/wiki/Bakery #/media/File:magasindandoy . jpg
好吧,如果你花两分钟思考这个库存优化问题,你会意识到你错过了大部分拼图。
- 烤一个面包要花多少钱?
- 每块面包的利润是多少?
- 面包日常需求分布是什么?
(为了简洁起见,我们将提前期的问题排除在本文之外)
成本/盈利能力影响
让我们想象一下,烤一个面包要花 0.5€,而你每个要卖 1.5€。基于这一信息,看起来你最好多拿几块面包(0.5€的生产成本),而不是少拿几块(1€的机会成本)。
但是,我们仍然不知道我们应该烤多少个面包:15 个?20?45?
产品的利润越高,成本越低,你应该储存的就越多(因为风险低,回报高)。为了评估你需要多少库存,很好地理解你的成本结构和很好地理解你的需求一样重要。
实际上,面包师讨厌扔掉食物。所以,他们通常计划生产没有剩菜。我们可以在我们的模型中包括这种剩余厌恶,作为当有任何过剩库存时产生的额外惩罚。
概率预测和需求分布
你所缺少的做出正确决定的信息是某一天可能发生的事情的概率视图。
我们需要知道一天卖出 1、2、3–25 块面包的概率。然后我们可以利用这些信息将每一种可能的供应情况货币化(如果我烤 X 片面包会发生什么?)。选择我们最喜欢的一个。
看看周一的预期需求分布和我的成本,我会烤 15 个面包来最大化我的预期利润。
让我们看看这个理论,以了解我们将如何使用概率预测来优化我们的(库存)决策。
点预测与概率预测
- 点预测:将未来与单一预期结果联系起来,通常是一个平均预期值(不要与最有可能结果混淆)。我们预测下个月会卖出 1000 件。
- 概率预测:分配不同事件发生的概率。示例见下图。

概率预测的例子。版权所有:尼古拉斯·范德普特
自然,我们生活在一个随机的世界里,概率预测比点预测更有意义。我们永远无法对未来有绝对的把握。因此,我们今天应该根据一系列可能的未来和它们各自的可能性来下注。扑克玩家非常了解这一点。
- 举例。没有人会预测掷骰子的结果是 3.5(平均期望值)。相反,我们明白我们有 1/6 的机会得到 1 到 6 的任何结果。
供应链需求也是如此。对我们的面包的需求可能是 10,但也可能是 5 或 15。重要的是估计所有这些值的可能性。
概率预测和库存优化
让我们概述一下你应该如何使用概率预测来优化你的(库存)决策。

如何优化供应(库存)决策。版权所有尼古拉斯·范德普特
- 生成需求概率预测(显示获得特定需求金额的可能性百分比)。
- 列出可能的供应计划(供应多少?)。供应约束— —比如批量——可能会限制可能情况的数量。
- 根据所有可能的结果,给每个场景一个期望值(根据发生的可能性进行加权)。
- 选择你最喜欢的场景。

供应决策优化。版权所有:尼古拉斯·范德普特
报童与多阶段计划
你们中的一些人可能已经意识到前面例子中常见的报童问题。事实上,为了简洁起见,我们将(随机)交付周期的问题排除在外。然而,如果我们这样描述,故事还是一样的:
你是供应计划员。您的主要供应商向您报价 3 个月的交付周期,而您每月都下订单。您目前有 100 件存货。你知道未来几个月的供应计划(新订单)以及未来 6 个月的概率预测。你应该订购多少?
实际上,我在这里解释这个案例:
结论:应该用概率预测吗?
当涉及决策时,人们对点位预测不感兴趣。
你预测下个月销售 1000 件,但这对确定你应该生产多少帮助有限。
相反,结合相关财务信息的概率预测将让你做出最佳决策。
你估计下个月的需求分布。你知道你的利润和成本。你可以做出明智的决定,购买多少来优化你的成本。
👉我们在 LinkedIn 上连线吧!
感谢
迈克尔·吉利兰
关于作者
icolas Vandeput 是一名供应链数据科学家,擅长需求预测和库存优化。他在 2016 年创立了自己的咨询公司 SupChains ,并在 2018 年共同创立了 SKU 科学——一个快速、简单、实惠的需求预测平台。尼古拉斯对教育充满热情,他既是一个狂热的学习者,也喜欢在大学教学:自 2014 年以来,他一直在比利时布鲁塞尔为硕士学生教授预测和库存优化。自 2020 年以来,他还在法国巴黎的 CentraleSupelec 教授这两门课程。他于 2018 年出版了 供应链预测的数据科学(2021 年第 2 版)和 2020 年出版了 库存优化:模型与模拟 。

概率预测:弹球损失函数
原文:https://towardsdatascience.com/probabilistic-forecasts-pinball-loss-function-baf86a5a14d0?source=collection_archive---------10-----------------------
概率预测对于优化供应链和库存目标至关重要。我们如何评估概率预测的质量?

信用
自我评估测验
先问几个问题。在阅读文章之前,先阅读它们。在你阅读结束时,你应该能够回答这些问题。(答案在最后提供以及一个 Python 实现)
- 你想预测你的产品的需求。具体来说,您希望预测一个需求有 80%概率低于的值。高估或低估实际需求,哪种情况最糟糕?
- 您设计了一个减少绝对误差(或 MAE)的预测模型。你的模型的目标是平均需求还是中间需求?
- 您做了一个 95%分位数的需求预测,您的预测是 150,而观察到的需求是 120。你如何评估你的预测质量?
- 你销售高利润的产品。最糟糕的是什么:库存过多还是不足?设置安全库存目标时,您应该以高需求分位数还是低需求分位数为目标?
分位数预测
分位数预测是针对特定需求分位数(或百分点)的概率预测。
定义:分位数
分位数α (α是一个百分比,0
P(x<=Quantile) = α
In other words, the quantile is the distribution’s cumulative distribution function evaluated at α.
Quantile α = F^{-1}(α)
In simple words, if you do an 80% quantile forecast of tomorrow’s weather, you would say, “There is an 80% probability that the temperature will be 20°C or lower.”
边注:如果你习惯于库存优化和通常的安全库存公式
Ss = z * σ * √(R+L)
z 是高斯α分位数 z=φ^(-1(α)。不知何故,您可以将安全库存公式视为风险范围内需求的α分位数预测。
PS:记住在这个公式中包含评审期。
不对称处罚
我们如何评估分位数预测的准确性?让我们再看一下上面的例子:你预测明天的第 80 个温度分位数是 20 摄氏度。第二天,温度是 16 摄氏度。
你的预测有多准确?
在讨论数学之前,让我们直观地了解一下应该如何评估(或惩罚)分位数预测。不知何故,当我们说,“我们预测温度有 80%的机会低于 20 摄氏度”,我们预计温度会低于 20 摄氏度,并会惊讶地发现温度会是 25 摄氏度。
换句话说,如果分位数预测低估了气温,那么它应该比高估气温受到更高的惩罚。

来源:尼古拉斯·范德普特
此外,如上图所示,对于更高的分位数,过度预测的惩罚应该更高。例如,如果你的 95%温度分位数预测是 20 摄氏度,如果实际温度是 25 摄氏度,你会非常惊讶
弹球损失函数
让我们使用弹球损失函数(或者分位数损失函数)来形式化这个预测惩罚。
弹球损失函数 L_α 针对分位数α、分位数预测 f、和需求 d 计算如下
L_α (d,f) = (d-f) α if d≥f
(f-d)(1-α) if f>d
该损失函数旨在提供一个预测,其低估需求的概率为α,高估需求的概率为(α-1)。
直觉和例子
让我们看看弹球函数在实践中是如何工作的。在下图中,您可以看到一个例子,其中 d=100,α=90%(我们希望预测需求的第 90 个分位数),弹球损失函数 L_α 是针对不同的 f 值计算的。

来源:尼古拉斯·范德普特
正如你所看到的,弹球损失 L_α 是高度不对称的:如果你超过预测(低惩罚)或低于预测(高惩罚),它不会以相同的速度增加。
我们举个例子:多预测 20 台会造成 10%|f-d|=2 的损失(也就是说多预测并没有太大的惩罚)。但是,另一方面,少预测 20 个单位将导致 90%的损失|f-d|=18。

来源:尼古拉斯·范德普特
基本上,预测不足会受到α|e|(其中 e 是预测误差)的惩罚,而预测过度则会受到(1-α)|e|的惩罚。

来源:尼古拉斯·范德普特
绝对平均误差
在我的预测 KPI 文章中,我强调了优化预测平均绝对误差(MAE)的最终目的是预测中值需求。
如下图所示,50%分位数弹球损失函数对应于常规绝对误差——它们是可以互换的。请记住,根据定义,预测 50%的需求分位数与预测需求中位数是一样的。这是另一个例子,说明优化 MAE 将导致针对需求中值的预测(和而不是需求平均值)。


📘📙下载免费摘录
自我评估解决方案
- 你想预测你的产品的需求。具体来说,您希望预测一个需求有 80%概率低于的值。高估或低估实际需求,哪种情况最糟糕?
低估需求是最糟糕的。如果您想要预测第 80 个分位数,您应该以可能高于观察值的值为目标。
2.您设计了一个减少绝对误差(或 MAE)的预测模型。你的模型的目标是平均需求还是中间需求?
优化平均绝对误差将最终导致预测预期中值需求,而不是预期平均需求。
3.您做了一个 95%分位数的需求预测,您的预测是 150,而观察到的需求是 120。你如何评估你的预测质量?
您可以计算分位数预测的弹球损失。您的预测有 30 个单位的绝对误差(= | 150–120 |),这是一个过度预测,因此您的弹球损失是 1.5 个单位(=30*0.05%)。
4.你销售高利润的产品。最糟糕的是什么:库存过多还是不足?设置安全库存目标时,您应该以高需求分位数还是低需求分位数为目标?
你想拥有大量高利润产品的库存,所以库存不足是一个糟糕的决定。从今以后,在设定股票目标时,你应该瞄准一个高需求分位数。
🐍自己做
您可以很容易地在 Python 中用一个表达式实现弹球损失函数(与原始方程相比有一些修改)。
**def** **pinball_loss**(d, f, alpha):**return** max(alpha*(d-f), (1-alpha)*(f-d))
线性回归的概率解释解释清楚
原文:https://towardsdatascience.com/probabilistic-interpretation-of-linear-regression-clearly-explained-d3b9ba26823b?source=collection_archive---------6-----------------------
最小二乘法背后的原因

作者图片
首先简单介绍一下线性回归:
线性回归是寻找最适合给定数据集的线性模型。
例如,在具有一个输入变量(即一个特征)的简单线性回归中,线性模型是一条具有公式y = mx + b的直线,其中m是斜率,b是 y 截距。
最佳拟合的线性模型是最小化误差平方和的模型。
如下图所示,误差是观察值和预测值之间的差异。

作者图片
附:查看这篇介绍线性回归和梯度下降的文章。
因此,我们知道最佳模型是误差平方和最小的模型。但是为什么呢?为什么平方误差?为什么不是误差的绝对值?
这就是概率解释的用武之地。
概率解释让我们了解为什么我们最小化误差平方和。
在我们继续进行概率解释之前,让我们首先在一些术语上取得一致。
首先,我们用θ来象征线性模型的参数。让我们用 h(x)来表示模型。模型是 x 的函数,由θ参数化。
在只有一个特征的简单线性回归中,h(x)可以写成:

简单线性回归
这里,θ_ 0 是 y 轴截距,θ_ 1 是斜率。
有了“n”个特性,它就变成了:

使用线性代数技术,我们可以将所有的θ放入一个向量中,并将输入值放入另一个向量中。因此,h(x)成为这两个向量的乘积。

根据模型,第个训练样本的估计为:

训练样本 I 的模型估计
现在,让我们继续线性回归的概率解释,以及为什么我们使用最小二乘法。
线性回归的概率解释
线性回归有两个假设。
- 对于给定的 x,y 的观测值是预测值加上误差项。

实际 y 是预测值加上误差项
这个误差项是“残差”,或观测值减去预测值。记住,在线性回归中,我们希望最小化误差平方和。

线性回归的目标是最小化误差平方和
2.该误差项独立同分布(IDD)。它具有均值为 0 且方差为 sigma 平方的正态(即高斯)分布。

误差项正态分布,均值为 0,方差为 sigma 平方
因为ε(I)具有正态分布,所以ε的概率密度函数可以写成:

由于ε是 x 和 y 的函数,我们可以将等式改写为:

观察第 I 个训练样本的概率
请注意,如果观察值和预测值接近,则方程的指数部分接近 1。如果观察值和预测值相差很远,指数部分接近 0。因此,如果观察值和预测值相差甚远,概率就会降低。
这进一步意味着,对于由θ参数化的给定 x,y 具有θ转置乘以 x 的平均值和σ平方的方差。

下面是给定 x 的 y 的直观表示:

作者图片
我们有一个训练样本的概率。整个数据集的概率呢?
如果我们假设样本是独立的,根据统计:
P(A and B) = P(A) * P(B)。
概括一下,我们有:

因此,整个数据集的概率是所有单个样本的概率的乘积。

这个等式被称为“参数θ的可能性”。可能性越大,观察到提供给模型的数据集的概率就越高。概率越大,模型越准确。
学习算法所做的就是最大化这种可能性。这被称为最大似然估计,或 MLE。
为了使数学更简单,让我们取可能性的对数。

第一项没有θ,所以在估算θ时,它是不相关的。在第二项中,sigma 是一个常数,所以我们可以去掉它。注意第二项中的负号。让我们去掉负号。最大化似然性等同于最小化最大似然性的负值。
进一步简化对数(可能性),您会得到:

成本函数是对数似然的负数
这个方程和线性回归中的代价函数完全一样,是误差平方和的 1/2 倍。
最后,最小化误差平方和等于最大化数据集的概率。
因此,这就是为什么我们使用平方误差进行线性回归。平方部分来自具有高斯分布的误差项。
概率机器学习和弱监督
原文:https://towardsdatascience.com/probabilistic-machine-learning-and-weak-supervision-dd604c5dbff8?source=collection_archive---------15-----------------------
思想和理论
用 scikit-learn 将领域专业知识和概率标记注入机器学习:手动标记的替代方法。
我们最近写了一篇文章手工标注被认为是有害的关于主题和领域专家如何更有效地与机器合作来标注数据。举个例子,
监管薄弱的领域越来越多,中小企业指定启发法,然后系统使用这些启发法对未标记的数据进行推断,系统计算一些潜在的标签,然后中小企业评估这些标签,以确定可能需要添加或调整更多启发法的地方。例如,当基于医疗记录建立手术是否必要的模型时,SME 可以提供以下启发:如果记录包含术语“麻醉”(或与其类似的正则表达式),则手术可能发生。

图片由作者准备,基于这张图片
在这篇技术文章中,我们展示了关于人类如何与机器合作来标记训练数据和建立机器学习模型的原理证明。
我们在概率标签和预测的上下文中这样做,也就是说,我们的模型输出特定行是否具有给定标签的概率,而不是标签本身。正如我们在手动标记被认为有害中明确指出的,建立基础事实很少是微不足道的,即使它是可能的,概率标记是分类标记的概括,它允许我们对产生的不确定性进行编码。
我们介绍了三个关键数字,数据科学家或主题专家(SME)可以利用这些数字来衡量概率模型的性能,并使用这些数字编码的性能来迭代模型:
- 基本速率分布,
- 概率混淆矩阵,以及
- 标签预测分布。
我们展示了这样的工作流程如何让人类和机器做他们最擅长的事情。简而言之,这些数字是中小企业的指南:
- 基本比率分布编码了我们在等级平衡方面的不确定性,并且将是一个有用的工具,因为我们希望我们的预测标签尊重数据中的基本比率;
- 当我们有分类标签时,我们使用混淆矩阵来衡量模型性能;现在我们有了概率标签,我们引入一个广义的概率混淆矩阵来衡量模型性能;
- 标签预测分布图向我们展示了概率预测的整体分布;正如我们将看到的,这种分布尊重我们对基本比率的了解是很关键的(例如,如果我们在上面的“手术”的基本比率是 25%,在标签分布中,我们预计大约 25%的数据集有很高的手术机会,大约 75%的数据集有很低的手术机会。)
让我们现在开始工作吧!我们将经历的步骤是
- 手动标记少量数据并建立基本速率;
- 建立一些领域信息启发/提示;
- 通过查看概率混淆矩阵和标签分布图来衡量我们的模型性能;
- 建立更多的提示,以提高我们的标签质量。
你可以在这个 Github 资源库中找到所有相关的代码。
所以让我们开始贴标签吧!
手动标签和基本费率
工作流程的第一步是手工标注一小部分数据样本。我们将在这里处理的数据是来自 Kaggle ( CC0 许可证)的医疗转录数据集,任务是预测任何给定的转录是否涉及手术,如“医疗专业”列中给出的。出于教学目的,我们将使用本专栏来手工标记几行,但这通常是 SME 通过转录来标记行。让我们来看看我们的数据:
# import packages and data
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings; warnings.simplefilter(‘ignore’)
sns.set()
df = pd.read_csv(‘data/mtsamples.csv’)
df.head()

这张图片和后面所有的图片都是作者笔记本中代码的输出。
检查完我们的数据后,现在让我们使用“medical_specialty”列手工标记一些行:
# hand label some rows
N = 250
df = df.sample(frac=1, random_state=42).reset_index()
df_labeled = df.iloc[:N]
df_unlabeled = df.iloc[N:]
df_labeled[‘label’] = (df_labeled[‘medical_specialty’].str.contains(‘Surgery’) == 1).astype(int)
df_unlabeled[‘label’] = None
df_labeled.head()

这些手工标记的行为有两个目的:
- 教我们关于职业平衡和基本比率的知识
- 创建验证集
在构建我们的模型时,关键是要确保模型至少近似地考虑了职业平衡,就像这些手牌的基本比率中所编码的那样,所以现在让我们来计算基本比率。
base_rate = sum(df_labeled[‘label’])/len(df_labeled)
f”Base rate = {base_rate}”
输出:
‘Base rate = 0.24'
基本利率分布
现在是时候介绍第一个关键数字了:基本利率分布。假设我们有一个实际的基本利率,我们这里的“分配”是什么意思?一种思考方式是,我们已经从数据样本中计算出了基本利率。这意味着我们不知道确切的基本利率,我们围绕它的不确定性可以用分布来描述。一种表述这种不确定性的技术方法是使用贝叶斯技术,本质上,我们关于基础率的知识是由后验分布编码的。你不需要知道太多关于贝叶斯方法的要点,但如果你想知道更多,你可以查看一些介绍材料这里。在笔记本中,我们已经编写了一个绘制基本速率分布的函数,然后我们为上面手工标注的数据绘制分布(老鹰会注意到我们已经缩放了概率分布,因此它在 y=1 处有一个峰值;我们这样做是出于教学目的,所有相对概率保持不变)。

首先请注意,分布的峰值位于我们计算的基本速率,这意味着这是最有可能的基本速率。然而,分布的差异也捕捉到了我们对基本利率的不确定性。
当我们迭代我们的模型时,必须注意这个数字,因为任何模型都需要预测接近基本速率分布峰值的基本速率。
- 随着你产生越来越多的数据,你的后验概率变得越来越窄,也就是说,你对自己的估计越来越确定。
- 相对于 p=0 或 p=1,当 p=0.5 时,你需要更多的数据来确定你的估计。
下面,我们绘制了 p=0.5 和增加 N (N=5,20,50,100)的基本速率分布。在笔记本中,你可以用一个 widget 构建一个互动的人物!

带有域提示的机器标记
手动标记了数据的子集并计算了基本速率后,是时候让机器使用一些领域专业知识为我们做一些概率标记了。
例如,一名医生可能知道,如果转录包括术语“麻醉”,那么很可能发生了手术。这种类型的知识,一旦被编码用于计算,就被称为提示器。
我们可以使用这些信息以多种方式构建模型,包括构建一个生成模型,我们很快就会这样做。为简单起见,作为第一个近似值,我们将通过以下方式更新概率标签
- 如果转录包括术语“麻醉”,则从基本速率增加 P(手术)
- 如果没有,就什么也不做(我们假设没有这个术语就没有信号)。
有许多方法来增加 P(手术),为了简单起见,我们取当前 P(手术)和权重 W 的平均值(权重通常由 SME 指定,并编码他们对提示与阳性结果相关的置信度)。
# Combine labeled and unlabeled to retrieve our entire dataset
df1 = pd.concat([df_labeled, df_unlabeled])
# Check out how many rows contain the term of interest
df1[‘transcription’].str.contains(‘ANESTHESIA’).sum()# Create column to encode hinter result
df1[‘h1’] = df1[‘transcription’].str.contains(‘ANESTHESIA’)
## Hinter will alter P(S): 1st approx. if row is +ve wrt hinter, take average; if row is -ve, do nothing
## OR: if row is +ve, take average of P(S) and weight; if row is -ve
##
## Update P(S) as follows
## If h1 is false, do nothing
## If h1 is true, take average of P(S) and weight (95), unless labeled
W = 0.95
L = []
for index, row in df1.iterrows():
if df1.iloc[index][‘h1’]:
P1 = (base_rate + W)/2
L.append(P1)
else:
P1 = base_rate
L.append(P1)
df1[‘P1’] = L
# Check out what our probabilistic labels look like
df1.P1.value_counts()
输出:
0.240 3647
0.595 1352
Name: P1, dtype: int64
现在我们已经使用 hinter 更新了我们的模型,让我们深入了解我们的模型是如何执行的。需要检查的两件最重要的事情是
- 我们的概率预测如何与我们的手形标签相匹配
- 我们的标签分布如何与我们所知道的基本比率相匹配。
对于前一个问题,进入概率混淆矩阵。
概率混淆矩阵
在经典的混淆矩阵中,一个轴是你的手牌,另一个轴是模型预测。
在概率混淆矩阵中,你的 y 轴是你的手形标签,x 轴是模型预测。但在这种情况下,模型预测是一种概率,而不是经典混淆矩阵中的“是”或“否”。
plt.subplot(1, 2, 1)
df1[df1.label == 1].P1.hist();
plt.xlabel(“Probabilistic label”)
plt.ylabel(“Count”)
plt.title(“Hand Labeled ‘Surgery’”)
plt.subplot(1, 2, 2)
df1[df1.label == 0].P1.hist();
plt.xlabel(“Probabilistic label”);
plt.title(“Hand Labeled ‘Not Surgery’”);

我们在这里看到
- 大多数标有“外科手术”的数据的 P(S)约为 0.60(尽管相差不大),其余的约为 0.24;
- 所有手写标记为“非手术”的行的 P 值约为 0.24,其余的约为 0.60。
这是一个好的开始,因为 P(S)对于标有“非手术”的是偏左的,对于标有“手术”的是偏右的。然而,对于那些标有手术的,我们希望它更接近 P(S) = 1,所以还有工作要做。
标签分布图
下一个关键图是跨数据集的标签预测分布图:我们希望了解我们的标签预测是如何分布的,以及这是否与我们已知的基本速率相匹配。例如,在我们的案例中,我们知道我们的基本利率可能在 25%左右。因此,我们期望在标签分布中看到的是约 25%的数据集有接近 100%的手术机会,约 75%的数据集有较低的手术机会。
df1.P1.plot.kde();

我们在大约 25%和大约 60%处看到峰值,这意味着我们的模型还没有很强的标签意识,所以我们想添加更多的提示。
本质上,我们真的希望看到我们的概率预测更接近 0 和 1,在一定程度上尊重基本利率。
建立更多的提示
为了构建更好的标签,我们可以通过添加更多的提示来注入更多的领域专业知识。下面我们通过增加两个积极的提示(与“外科手术”相关的)来做到这一点,这以类似于上面的提示的方式改变了我们的预测概率。代码见笔记本。这是概率混淆矩阵和标签分布图:


随着我们增加提示者的数量,发生了两件事:
- 在我们的概率混淆矩阵中,我们看到那些标有“手术”的手的直方图向右移动,这很好!我们还看到标记为“手术”的手的直方图稍微向右移动,这是我们不希望的。请注意,这是因为我们只引入了肯定的提示,所以接下来我们可能要引入否定的提示,或者使用更复杂的方法从提示转移到概率标签。
- 我们的标签分布图现在在 P(S) = 0.5 以上具有更大的密度(右侧更大的密度),这也是所希望的。回想一下,我们期望在标签分布中看到大约 25%的数据集有接近 100%的手术机会,大约 75%的数据集有较低的手术机会。
提示者的生成模型
这样的暗示,虽然像玩具例子一样有指导意义,但也只能是表演性的。现在让我们使用一个更大的提示集来看看我们是否能建立更好的训练数据。
我们还将使用一种更复杂的方法来从提示转移到概率标签:我们将使用朴素贝叶斯模型,这是一种生成模型,而不是对权重和先前的概率预测进行平均。生成模型是对特征 X 和目标 Y 的联合概率 P(X,Y)进行建模的模型,与根据特征对目标的条件概率 P(Y|X)进行建模的判别模型相反。与随机森林之类的判别模型相比,使用生成模型的优势在于,它允许我们对数据、目标变量和暗示者之间的复杂关系进行建模:它允许我们回答诸如“哪个暗示者比其他的更嘈杂?”之类的问题以及“在哪些情况下它们会很吵?”关于生成模型的更多信息,谷歌有一个很好的介绍在这里。
为了做到这一点,我们为任何给定的行创建了编码提示是否存在的数组。首先,让我们创建正面和负面暗示的列表:
# List of positive hinters
pos_hinters = [‘anesthesia’, ‘subcuticular’, ‘sponge’, ‘retracted’, ‘monocryl’, ‘epinephrine’, ‘suite’, ‘secured’, ‘nylon’, ‘blunt dissection’, ‘irrigation’, ‘cautery’, ‘extubated’,‘awakened’, ‘lithotomy’, ‘incised’, ‘silk’, ‘xylocaine’, ‘layers’, ‘grasped’, ‘gauge’, ‘fluoroscopy’, ‘suctioned’, ‘betadine’, ‘infiltrated’, ‘balloon’, ‘clamped’]# List of negative hinters
neg_hinters = [‘reflexes’, ‘pupils’, ‘married’, ‘cyanosis’, ‘clubbing’, ‘normocephalic’, ‘diarrhea’, ‘chills’, ‘subjective’]
对于每个提示,我们现在在数据帧中创建一列,编码该术语是否在该行的转录中:
for hinter in pos_hinters:
df1[hinter] = df1[‘transcription’].str.contains(hinter, na=0).astype(int)
# print(df1[hinter].sum())
for hinter in neg_hinters:
df1[hinter] = -df1[‘transcription’].str.contains(hinter, na=0).astype(int)
# print(df1[hinter].sum())
我们现在将标记的数据转换成 NumPy 数组,并将其分成训练集和验证集,以便在前者上训练我们的概率预测,并在后者上测试它们(注意,我们目前只使用正提示)。
# extract labeled data
df_lab = df1[~df1[‘label’].isnull()]
#df_lab.info()
# convert to numpy arrays
X = df_lab[pos_hinters].to_numpy()
y = df_lab[‘label’].to_numpy().astype(int)
## split into training and validation sets
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.33, random_state=42)
我们现在对训练数据训练一个伯努利(或二进制)朴素贝叶斯算法):
# Time to Naive Bayes!
from sklearn.naive_bayes import BernoulliNB
clf = BernoulliNB(class_prior=[base_rate, 1-base_rate])
clf.fit(X_train, y_train);
有了这个训练好的模型,现在让我们对我们的验证(或测试)集进行概率预测,并可视化我们的概率混淆矩阵,以将我们的预测与我们的手动标签进行比较:
probs_test = clf.predict_proba(X_test)
df_val = pd.DataFrame({‘label’: y_test, ‘pred’: probs_test[:,1]})
plt.subplot(1, 2, 1)
df_val[df_val.label == 1].pred.hist();
plt.xlabel(“Probabilistic label”)
plt.ylabel(“Count”)
plt.title(“Hand Labeled ‘Surgery’”)
plt.subplot(1, 2, 2)
df_val[df_val.label == 0].pred.hist();
plt.xlabel(“Probabilistic label”)
plt.title(“Hand Labeled ‘Not Surgery’”);

这太酷了!使用更多的提示和朴素贝叶斯模型,我们看到我们已经成功地增加了真阳性和真阴性的数量。这在上面的图中是可见的,因为手部标签“手术”的直方图更偏向右侧,而“非手术”的直方图偏向左侧。
现在,让我们绘制整个标签分布图(从技术上来说,我们需要在 x=0 和 x=1 处截断这个 KDE,但是出于教学目的,我们很好,因为这不会改变太多):
probs_all = clf.predict_proba(df1[pos_hinters].to_numpy())
df1[‘pred’] = probs_all[:,1]
df1.pred.plot.kde();

如果你问“什么时候停止贴标签?”,你问了一个关键且基本上很难的问题。让我们把它分解成两个 questions:
- 你什么时候停止手工标签?
- 你什么时候停止整个过程?也就是说,你什么时候停止创建提示?
回答第一个问题,最起码,当你的基本利率被校准时,你就停止手工标注(一种思考方式是当你的基本利率分布停止跳跃时)。像许多 ML 一样,这在许多方面更像是一门艺术而不是科学!另一种思考方式是绘制一条基本利率相对于标记数据大小的学习曲线,一旦达到稳定状态就停止。考虑何时完成手动标签的另一个重要因素是,当你觉得你已经达到了统计意义上的基线,这样你就可以确定你的程序标签有多好。
现在你什么时候停止添加提示?这类似于问“你什么时候有足够的信心开始根据这些数据训练一个模型?”答案因科学家而异。你可以通过滚动和目测来定性,但大多数科学家更喜欢定量的方法。最简单的方法是计算你的概率标记数据与手工标记数据的准确度、精确度、召回率和 F1 分数,这样做的最低提升方法是使用概率标记的阈值:例如,标签为< 10% would be 0, > 90% 1,以及弃权之间的任何值。需要说明的是,这样的问题仍然是《观察》杂志研究的活跃领域…请关注这个空间!
雨果·鲍恩·安德森和沙扬·莫汉蒂
非常感谢 马 对本帖工作草案的反馈。
最初发布于https://www . watchly . io。
概率英超联赛赛程
原文:https://towardsdatascience.com/probabilistic-premier-league-fixtures-9f432976dfc1?source=collection_archive---------52-----------------------
这个周末的赛程会有一场轰动的比赛吗?
狂热的足球迷喜欢观看英格兰超级联赛的比赛,这可以说是世界上最好的国内足球(或者对英国读者来说,足球)联赛。但是一个中立的观众可能只喜欢看两支著名的精英球队之间的比赛。一个人多久能看一次这些轰动的游戏?
要回答这个问题,需要对英超联赛的赛程系统做一个简要的概述。每个周末,或比赛日,英超联赛的 20 个俱乐部之间会有 10 场比赛。虽然一些比赛日发生在周中,尤其是在旺季,但为了简单起见,我们将在本文中使用比赛日和周末作为可互换的术语。
在我的童年时期(2000 年代),英超联赛总共有 20 支球队,其中有 4 支强队:曼联、切尔西、利物浦和阿森纳。包含“大型”比赛的比赛日似乎很少。
如今,有六家顶级俱乐部:上面列出的四家,加上热刺和曼城。只有两个额外的精英队,似乎有更多的周末包括至少一场轰动的比赛。这准确吗?确切地说,现在这种情况比以前多了多少?
在一个温和的假设下,我们可以利用概率论来评估周末有大型比赛的可能性。
假设所有灯具组合(定义如下)的可能性相同。虽然可以想象,制定赛程安排表的管理机构通过“分散”大型比赛来确保尽可能多的周末包括大型比赛,但我认为这不太可能,因为赛程安排者必须记住许多其他因素。一个赛季有许多比赛,每个俱乐部都要参加多项比赛,这些比赛必须协调一致,以免发生冲突,此外,球员必须在必要时可以参加国家队的比赛。
有了合理的基本假设,我们就可以继续研究概率了。在下文中,“赛程组合”或“赛程列表”指的是 20 支球队之间的 10 场比赛,包括整个比赛日。
我们的策略将是评估有多少种比赛组合是可能的,以及有多少种组合不包括轰动性的比赛。这个商将给我们一个周末没有大型比赛的概率。这个的补数(这个概率从 1 中减去)将给出一个比赛日包括至少一场精英赛的概率。
我们如何计算可能的夹具组合的数量?我们设想一个包含所有 20 个团队的列表,并重新排列这些团队在列表中出现的顺序。然后列出的每一对连续的队伍被认为是在互相比赛。这样得出 20!= (20) * (19) * … * (2) * (1),既然第一个位置的队伍有二十个选项,那么第二个位置有 19 个选项,以此类推。
但是上述计算在两个方面出现了过度计算:
1)它将具有相同 10 个配对但顺序不同的两个夹具列表视为不同的夹具列表,这对于我们的目的来说是不准确的。对于任何夹具清单,有 10 个!安排配对顺序的方法。因为每个夹具列表出现 10 个!20 种不同的方式!组合夹具,一定要分 20 个!10 点前。。
2)我们可以用两种方式安排每个配对:1 队对 2 队,或者 2 队对 1 队。20!计算将这两个装置视为不同的,这是不准确的。因此,我们将每个配对的可能夹具组合增加了一倍,达到 10 对。因此,我们必须除以 2 的十倍。
总之,我们可能的比赛日赛程总数是:

作者图片
一般来说,对于 t 个团队,可能的固定装置数量为:

作者图片
上面的公式假设 t 是一个偶数,世界上大多数联赛都是这样。
如果有 4 支大球队,上述可能的赛程组合中有多少不包括大赛?
为了计算这一点,我们设想 4 个地点,与 4 个顶级俱乐部“相对”,表明 16 个较小的球队中的哪 4 个将与大球队比赛。(如果两个大球队互相比赛,那么这样的赛程列表包含了一场大赛,我们现在不统计这样的赛程列表。)有 16 种选择 4 种方式来选择将与大球队比赛的 4 支球队。(16 选 4 是 16 的数学术语!/(4!*12!).我们还必须记住,每选择 4 个较小的队与大队比赛,较小的队可以安排在 4 个!方法,决定每个小团队和哪个大团队比赛。所以我们乘以 4!。然后,我们乘以我们可以在剩余的 12 支小球队之间安排 6 场比赛的方法的数量。
这最后一个计算遵循上面 20 个团队计算的模板,得出:12!/((6)!)*(2⁶)).
把所有这些放在一起,不包含大型比赛的可能的比赛组合的数量是:

作者图片
一般来说,对于 t 队和 g 队来说,不包含大型比赛的可能赛程列表的数量是:

作者图片
取消后,我们得到以下不包含大型比赛的所有可能赛程列表的公式:

作者图片
上述公式假设 g 小于或等于 t/2。如果 g 大于 t/2,这个公式就不能给出明确的答案。这对应了一个事实,如果 g 大于 t/2,那么一个不包含大赛的赛程列表是不可能的。
为了解释为什么这是真的,考虑一个 20 支球队的联盟中的 11 支(或更多)大球队。在任何一个比赛日,一场大赛都是必然的,因为那时只有 20-11 = 9 支小球队,不足以和所有 11 支强队比赛。每个比赛日至少会有两个大队互相比赛。
用我们上面的 20 支球队的联赛中 4 支大球队的公式,我们计算出一个周末没有大型比赛的概率是 454,053,600/654,729,075 = 0.6934985,或 69.35%的几率。
这使得周末至少有一场大型比赛的概率为 1–0.6934985 = 0.3065015 = 30.65%。
我们使用以下 R 代码获得我们的结果:
#Calculate the probability of having at least one big game on a #matchday.prob_of_good = function(t,g){#t total #teams, g good teams
stopifnot(t%%2==0) #t must be even
if(g>t/2){
return(1) #since impossible to have no good game
}
else{
#fixture lists with no good games
negative = factorial(t-g)/(factorial((t-2*g)/2)*2^((t-2*g)/2))
#total fixture lists
total = factorial(t)/(factorial(t/2)*2^(t/2))
#probability of at least one good game
pos = 1-(negative/total)
return (pos)
}
}prob_of_good(20,4)
因此,对于一个总共有 t = 20 支球队的联盟中的 g = 4 支好球队,如 2000 年的英超联赛,包括两支精英球队之间至少一场比赛的比赛日的概率是 30.65%。
为了对我们的结果有信心,我们还将通过创建一个由 1 和 0 组成的列表来模拟这个问题,1 表示知名的团队,0 表示较小的团队。然后我们排列这个列表,产生一个比赛列表,并认为每一个连续的配对都是这两个队之间的比赛。然后,我们计算有多少排列包含至少一个两个一的配对,表明两个大队之间的比赛。
#simulation
simulate = function(t,g){#t total teams, g good teams
ones = rep(1,g)
zeros = rep(0,t-g)
list = c(ones,zeros) #produce list of g ones, for big teams and #t-g zeros for smaller teams
perm = sample(list,length(list)) #permute the list
for (i in 1:(t/2)){
if(sum(perm[(2*i-1):(2*i)])==2){#If a pairing contains two ones, #for two big teams, return 1,
return (1) # for big match occurring
}}
return(0) # If no pairing contains two ones, return 0, for no big #match occurring.
}#many simulations
mult_sim = function(t,g,k){#k simulations
results = rep(0,k)
for (i in 1:k){
results[i] = simulate(t,g)
}
return(mean(results)) #return proportion of fixture lists which #contain at least one big game
}}set.seed(41)
simulated_results = rep(20,0)for (i in 1:20){
simulated_results[i] = mult_sim(20,i,1000000)
}
模拟 1,000,000 次,我们得到的概率为 30.70%,非常接近我们的理论概率 30.65%
当有 6 支顶级球队时,包括一场精彩比赛在内的比赛日的概率如何,就像目前英超联赛的情况一样?
对于 g = 6,重新运行我们的公式,我们获得了 65.33%的概率,是先前结果的两倍多。运行 1,000,000 次模拟产生 65.32%的概率,几乎与我们的理论概率相同。
为了评估我们的模拟结果(每次 1,000,000 次模拟)是否与我们的理论结果相匹配,我们现在将它们并排绘制,跨越 20 支球队联盟中优秀球队数量的各种输入。

理论概率与模拟概率(图片由作者提供)
我们可以看到,我们的模拟结果与我们的理论结果非常吻合,这让我们相信我们的计算是准确的。
我们也看到,正如预期的那样,只有 1 个大团队,不可能有大游戏,我们定义为 2 个大团队之间的游戏。我们重申,有 11 支(或更多)强队,任何比赛日都会有一场大赛。
在确认了我们的结果的准确性之后,我们现在提供一个更详细的图表,描述在任何给定的比赛日看到一场“大型”比赛的理论概率,对于一个由 20 支球队组成的联盟中不同数量的好球队。

重大比赛在特定比赛日发生的理论概率(图片由作者提供)
也许令人惊讶的是,仅增加两支额外的精英球队,就使在特定比赛日看到至少一场精彩比赛的概率增加了一倍多,从 30.65%增加到 65.33%。再添一支精英球队(可能是莱斯特城?)将使大团队的数量增加到 7 个,并将上述概率进一步提高到 80.19%。
虽然人们可能喜欢也可能不喜欢新球队的进步和崛起,但对于中立的观众来说,这无疑是个好消息。
下一次,(在 G-d 的帮助下),我们将通过评估英超联赛历史上的真实比赛来评估这种概率分析,以及我们随机比赛的基本模型,是否是英超联赛比赛的准确模型。
概率规划:广义线性模型
原文:https://towardsdatascience.com/probabilistic-programming-generalized-linear-models-b180ac8cfa7e?source=collection_archive---------17-----------------------
一种替代的、分布优先的数据建模方法。

在 Unsplash 上由 Carlos Muza 拍摄的照片
什么是概率编程
世界存在不确定性。数据科学家的目标是尝试使用过去的数据对世界进行建模,以有效地预测未来。这种策略在许多不同的领域和用例中相对有效。但是,这种不确定性还是存在的。预测未来的结果并理解该模型有多“好”将是有益的。
概率编程已经存在了一段时间,超过十年了。然而,许多人可能以前没有见过、使用过,甚至没有听说过它。那是什么呢?基本上,这是一种根据概率建立模型的方法。然而,它显然不适合那些希望自己的结果是概率性的人。
概率编程是一种将编程框架与贝叶斯统计建模、推理算法和机器学习元素相结合的范式。此外,它基于贝叶斯推理方法。这与大多数模型遵循的常见频率主义方法形成对比。幸运的是,这个帖子不需要每个推理系统之间的细微差别。
结构
概率规划有许多不同的选择。
- ' STAN '在 R 中用' RStan '和 Python 中用' PyStan '得到了很好的支持。框架已经建立。
- Pyro 是深度概率模型,有 PyTorch 后端。它由优步工程部开发和维护。
- “TensorFlow Probability”是用 TensorFlow 构建的,由谷歌提供支持。
- PyMC3 是一个用于概率编程的 python API。
例如,利用概率规划,线性回归被转换成多个分布的组合。起初,这种改变似乎有些矫枉过正。
为什么一切都要用概率来表示?
首先,当术语被概率性地定义时,你就有了从统计学角度理解模型的工具。例如,线性回归的原始公式可以写成

线性回归
其中 Y 是我们要预测的产量,X 是我们的独立数据;系数用β定义,误差项用ϵ.定义对于标准线性回归,误差项被假定为正态分布。
使用概率方法,模型用概率分布来表示。

概率线性回归
这意味着假设数据遵循正态分布。因此,模型的输出是具有分布σ方差的线性模型的平均值。
在线性回归的第二个公式中,术语被定义为概率。这个公式意味着权重被表示为分布,并且您可以测量β的不同值的可能性。因此,例如,当数据较少时,这些权重更不确定。但值得注意的是,这种不确定性在模型中得到了体现。
广义线性模型
线性回归是几个变量和权重的总和,后跟一个误差项。假设该误差项来自高斯分布。
然而,正如您可能已经考虑到的,误差项不需要遵循高斯分布。
在广义线性模型中,分布不必是高斯分布。此外,虽然这些模型中的项总是线性相加的,但是非线性函数也可以应用于线性项。这两个原因导致了“广义”线性模型的出现。
制定
当结果不是线性时,这些性质是有益的。例如,逻辑回归是一个线性模型。然而,对于逻辑回归,线性项通过逻辑函数传递。该模型还假设伯努利分布来产生最终的二元结果。
GLMs 的配方反映了这些特性:

广义线性模型公式(作者照片)
在这个公式中,g 被认为是一个可以是非线性的“连接”函数。E 项代表来自指数分布族的分布。这最后一个短语是为了确保公式是通用的。指数族由许多由一组参数定义的不同分布组成。例如,正态分布在指数族中。
正如您可能已经确定的那样,广义线性模型涉及到对底层数据分布的良好理解,非常适合概率编程。
Python 中的概率编程
在 Python 中,一个名为 PyMC3 的概率编程包允许用户使用各种数值模型来拟合贝叶斯模型。用 PyMC3 进行概率编程适用于广泛的问题。重要的是,该功能包括汇总输出和模型诊断。
PyMC3 有许多不同的教程和所有可用功能的演练。这些例子为许多不同的概率定义的模型提供了一些快速的开始。PyMC3 包括许多不同的模型、分析和方法,如自回归模型、生存分析、标准化流、马尔可夫链蒙特卡罗抽样、高斯过程和分层线性回归。仅举几个例子。
这篇文章的重点是广义线性模型。
实验
在这篇文章中,我将使用波士顿住房数据集。这个数据集由 506 条记录组成。该数据集旨在使用人均犯罪率、每个城镇的非零售商业用地比例和全价值财产税率等特征来预测房价。
要在 PyMC3 中生成 glm,设置相对简单。但是,对于更复杂的模型(即自定义链接功能和交互术语),结构会更复杂。
首先,将数据放入一个字典中,分别用键“x”和“y”表示输入和输出数据。
import arviz as az
import matplotlib.pyplot as plt
import pymc3 as pm
from pymc3 import *
import pandas as pd
import numpy as np
from sklearn.datasets import load_bostondata = load_boston()
df = pd.DataFrame(data.data, columns=data.feature_names)
df['target'] = data.target
X = df.drop(['target'], axis=1)
y = df['target'].astype(float)
data = {'x': X, 'y': y}
接下来,使用 PyMC3,每个模型规范都被包装在一个“with”语句中。然后指定 GLM 模型,并传入数据。此步骤确保所有参数都添加到模型中。最后,通过获取许多后验样本来产生模型。
with Model() as model:
glm.GLM.from_formula("y ~ x", data)
trace = sample(3000, cores=2) # draw 3000 posterior samples
模型分析
模型生成后,我们就可以分析模型了。首先,用分布对参数建模,为我们提供可能参数的完整后验分布。
plt.figure(figsize=(7, 7))
traceplot(trace)
plt.tight_layout();
仅显示了波士顿住房数据集中的前三个要素以及截距。
- CRIM——城镇人均犯罪率
- ZN——面积超过 25,000 平方英尺的住宅用地比例。制成
- 印度河——每个城镇非零售商业用地的比例。

来自波士顿住房数据集的 CRIM、ZN、INDUS 和 CHAS 的边缘后部
左侧显示了我们的边际后验概率——对于 x 轴上的每个参数值,我们在 y 轴上得到一个概率,它告诉我们该参数值的可能性有多大。
这里有一些需要注意的地方。单个参数的采样链(左侧)似乎很好地收敛且稳定。似乎没有任何大的漂移或其他异常现象。
结论
概率编程是数据科学中令人兴奋的领域。
当使用大型复杂模型时,可解释性和简单性可能会丧失。虽然线性回归肯定有其局限性,但广义线性模型提供了一种替代方法。
当对这些模型使用概率规划时,可以有效地测量模型周围的不确定性。这一特性导致模型以可解释的线性方式进行预测,并提供关于模型本身的不确定性的度量。
如果你有兴趣阅读关于新颖的数据科学工具和理解机器学习算法的文章,可以考虑在 Medium 上关注我。
如果你对我的写作感兴趣,并想直接支持我,请通过以下链接订阅。这个链接确保我会收到你的会员费的一部分。
https://zjwarnes.medium.com/membership
概率统计面试问答
原文:https://towardsdatascience.com/probability-and-statistics-interview-questions-and-answers-e7cfa35aeb96?source=collection_archive---------4-----------------------
重要概念和技巧的终极指南,你可以用它来提高你的概率和统计数据科学面试问题

作者在 Canva 上创建的图片
众所周知,如今去找一份数据科学工作的旅程比以往任何时候都要艰难。数据科学越来越受欢迎,这意味着我们有更多的竞争来争夺这一工作。因此,每次我们得到面试机会时,恰当地准备合适的东西是至关重要的。
在数据科学面试准备期间,大多数人会将注意力更多地转移到编程和 SQL 技能,或者深度学习、计算机视觉或自然语言处理等高级概念上。然而,公平地说,统计和概率也是需要掌握的非常重要的概念,尤其是当你在寻找一个数据分析师或产品数据科学家的角色时。
在这篇文章中,我们将带你了解一些重要的概念和技巧,你可以用它们来提高你的概率和统计面试问题。
掌握统计学的重要性
作为数据分析师或数据科学家,统计学几乎是每个概念的核心,无论你将在哪个行业工作。
想象你在一家电子商务公司工作。为了最大化利润和客户体验,您被指派使用一种聚类方法进行客户细分。嗯,聚类的核心是统计,在统计中,属于同一分布的对象被紧密地分组在一起。
当你在一家科技公司工作,你的公司想要推出一项新功能或产品时,他们会指派你对两种不同的产品进行 A/B 测试。但是你怎么知道一个产品优于另一个产品呢?再次强调,你需要有扎实的统计学知识,因为我们需要假设检验、误差幅度、置信区间、样本大小、统计功效等等来判断我们观察的质量。
此外,我们用于项目的花哨的深度学习架构的基础也来自统计数据。例如,看看变分自动编码器(VAE)或贝叶斯神经网络(BNN)。VAE 和 BAE 都使用概率分布来近似神经网络的参数,而不是使用确定性的值。
拥有扎实的统计学知识,让我们更容易理解不同深度神经网络架构是如何工作的。此外,如果我们知道机器学习中不同的统计学概念,如过拟合、欠拟合或偏差-方差权衡,我们在实现神经网络时就更容易调试问题。
现在我们知道了统计学在我们作为数据分析师或者数据科学家的日常生活中有多重要,那么我们就来看看我们面试要准备的统计学和概率中的各种概念。
数据科学面试中你应该知道的概率概念
概率可以说是数据科学面试的圣杯。扔硬币、掷骰子、等公共汽车来、预测是否会下雨,应有尽有。许多面试问题都与各种公司提出的概率有关,因此,根据问题的不同,准确了解应该使用哪个概念非常重要。
在这一部分中,我们将深入探讨你应该知道的概率概念,以便在数据科学面试中胜出。
概率基础
在这一节中,将涵盖所有关于概率概念的基础知识。你可能知道,概率是统计学的关键概念,因此,理解概率的基本概念很重要。
符号和操作
谈到概率,你可能会遇到不同的符号和运算。这些符号和运算代表了我们试图解决的概率问题中的特定事件。不同的符号和操作有不同的含义,当然也有不同的解决方案。
下面是你在概率面试题中可能遇到的常用符号和操作:
联盟

假设我们有两个事件: A 和 B 。 A 和 B 的并集由事件 A 、 B 或两者的所有结果组成。
当有一个概率问题:“至少一个事件发生的概率是多少?”,我们总是需要使用一个工会。
在符号中,两个事件 A 和 B 的并集通常表示为 A ∪ B 。
交点

当我们有两个事件: A 和 B 时, A 和 B 的交集只包含同时存在于 A 和 B 中的结果。
当有一个概率问题:“事件 A 和 B 同时发生的概率是多少?”,我们总是需要用到一个路口。
在符号中,两个事件 A 和 B 的交集通常表示为 A ∩ B 。
互斥

当我们有两个事件: A 和 B 时,当事件 A 的任何结果与事件 B 的任何结果不匹配时,我们可以说这两个事件是互斥的。
在一个符号中,我们可以说互斥事件有 A ∩ B = 0
概率属性
概率有一些我们应该永远记住的重要性质:
概率范围
概率的范围总是在 0 到 1 之间。
如果一个事件的概率是 1,这意味着该事件是保证发生的。同样,如果一个事件的概率为 0,这意味着该事件保证不会发生。
概率越接近 1,事件发生的可能性就越大。
实际上,事件 A 发生的概率可以表示为 P(A) ,其中 P(A) 应该在 0 和 1 之间的范围内:

概率补码
如果事件 A 发生的概率是 P(A) ,那么事件 A 不发生的概率将等于:

假设我们知道明天下雨的概率是 0.8,那么明天不下雨的概率就是 1–0.8 = 0.2。
两个事件结合的概率
两个事件 A 和 B 合并的概率可以数学定义为:

如果两个事件互斥,这意味着 P(A∩B) = 0。因此,在这种情况下,两个事件合并的概率是:

例题:
脸书在他们的一次数据科学访谈中,问了一个关于两个事件联合概率的问题。问题是:
“从一副洗好的 52 张牌中抽出一张不同颜色或形状的牌的概率是多少?”
要回答这个问题,首先让我们定义两个事件:
答:从一副洗好的牌中抽出一张不同颜色的牌
B :从一副洗好的牌中抽出一张不同形状的牌
由于一副 52 张牌中有两种不同的颜色(每副 26 张)和四种不同的形状(每副 13 张),那么在我们从这副牌中抽出一张牌后,我们抽出一张不同颜色的牌的概率将是:

同时,我们抽出不同形状的牌的概率是:

现在,我们抽一张不同形状和颜色的牌的概率是:

因为假设我们在第一次抽牌中得到一颗红心,那么如果我们在第二次抽牌中得到一张黑桃或一张黑梅花,则条件 P(A∩B) 将被满足,因此总共 51 张牌中有 26 张。
现在我们有了所有的信息,我们可以将这些值代入两个事件联合的概率公式:


条件概率
条件概率是数据科学面试中常见的概率概念之一。好的一面是,条件概率的概念并不难理解。
条件概率可以描述为一个事件发生的概率,假定另一个事件已经发生。
作为一种记法,假设事件 B 已经发生,事件 A 发生的概率可以写成 P(A|B)。
下面是条件概率的公式。

依赖和独立事件
如果一个事件发生的概率影响另一个事件发生的概率,则两个事件可以被描述为相关事件。
举个例子,假设你想从一副牌中抽两张牌,并且你希望在其中一张中得到一张红心 5。
在第一次抽牌时,你的概率是 1/52,因为一副牌中有 52 张牌。现在,在第一次抽牌之后,你注意到你没有得到一张红心 5。在第二次抽牌中,你拿到 5 红心的概率不再是 1/52,而是 1/51。你第一次抽牌的结果会影响你第二次抽牌的概率。这意味着这两个事件是相关事件。
如果两个事件是相关事件,那么在事件 B 已经发生的情况下,事件 A 发生的概率与条件概率没有什么不同:

同时,如果一个事件发生的概率对另一个事件发生的概率没有任何影响,则两个事件可以被描述为独立事件。
举个例子,你想掷硬币两次,你希望在其中一次掷中得到一条尾巴。在第一次投掷中,你得到一条尾巴的概率是。在第一次投掷之后,你注意到你没有得到一条尾巴。但是,你在第二次抛的时候得到一条尾巴的概率还是。你在第一次投掷中没有得到一条尾巴的事实对你在第二次投掷中得到一条尾巴的概率没有任何影响。
如果两个事件是独立事件,那么在事件 B 已经发生的情况下,事件 A 发生的概率可以定义为:

因为

例题:
脸书在他们的一次数据科学访谈中提出了一个与条件概率和相关/独立事件相关的问题。问题是:
“你有 2 个骰子。至少得一个 4 的概率有多大?”
为了回答这个问题,让我们想象两个事件:
A :用骰子 1 得到 4
B :用骰子 2 得到一个 4
因为在一次掷骰子中我们可以得到 6 种可能的结果,那么我们在一次掷骰子中得到 4 的概率就是⅙.因此:

现在的问题是,事件 A 和事件 B 同时发生 (P(A∩B)) 的概率是多少?
首先,我们需要知道该事件是属于从属事件还是独立事件。不管掷骰子 1 的结果如何,我们用骰子 2 得到 4 的概率不会改变。因此,我们可以说我们在这个问题中的事件是一个独立的事件。
既然这是一个独立的事件,那么我们可以说:

接下来,有了所有这些信息,我们可以将这些值代入两个事件联合的概率方程:


排列和组合
尽管它们并不相同,但人们经常互换使用术语排列和组合。这是可以理解的,因为他们有一个非常相似的概念,只有细微的差别。以下是它们之间的主要区别:
在排列中,我们关心顺序,而在组合中,顺序并不重要。
这意味着什么呢?我们用一个例子来阐述一下。
排列
假设我们附近有一场网球比赛。本次比赛共有 8 名运动员参赛,最终将颁发 3 枚奖牌。
在第一个场景中,将颁发的 3 枚奖牌是第一名获奖者的金牌、第二名的银牌和第三名的铜牌。由于颁发的奖牌因运动员的最终位置而异,因此在这种情况下,顺序很重要。如上所述,当顺序很重要时,我们就要处理排列。
因为我们有 8 名运动员:
- 对于金牌,我们有 8 个可能的选择:运动员 1,2,3,4,5,6,7,8。假设运动员 1 赢得了金牌。
- 对于银牌,我们有 7 个可能的选择:运动员 2,3,4,5,6,7,8。假设运动员 2 获得银牌。
- 对于铜牌,我们有 6 个可能的选择:运动员 3,4,5,6,7,8。
因此,我们可以将上面的场景写成 8 x 7 x 6 = 336 。这意味着我们有 336 种可能的运动员排列。
解决排列问题的一般方程是:

其中 n 是项目总数, k 是要订购的项目总数。
在上面的例子中,由于我们有 8 名运动员,那么 n 就是 8。与此同时,由于我们有 3 个不同的奖牌需要订购,那么 k 将是 3。因此:


例题:
Peak6 在他们的一次数据科学访谈中,问到了排列的基本概念。问题是:
“一场比赛有三个人,一、二、三名,有多少种不同的组合?”
因为有三个人,有三个地方需要排序,这些顺序很重要,所以我们需要使用排列的一般方程。

组合
让我们回到前面的网球比赛的例子。但是现在我们不再给他们颁发金牌、银牌和铜牌,而是给他们颁发纪念品。所有三名获胜者都将获得同样的纪念品。
在这种情况下,顺序不再重要,因为所有三个获胜者都收到了相同的纪念品。这意味着如果三名获胜者是运动员 A 、 B 和 C ,我们有以下条件:

请注意,上述条件不适用于排列,因为在排列中,获胜者的顺序很重要。
组合的一般等式为:

与上述排列相同, n 是项目总数, k 是要订购的项目总数。
在某些情况下,上面的等式 C(n,k) 可以写成

也就是著名的二项式系数,你会在下一章的二项式分布中看到。
例题:
Kabbage 在他们的一次数据科学采访中,问到了组合的基本概念。问题是:
“如何在一个 200 人的小组里发现谁在论文写作上作弊?”
这就是组合的概念。
既然我们有 200 名学生,那么我们的项目总数 n = 200。接下来,找出谁作弊的解决方案之一是逐一比较一对学生的考试,它们的顺序无关紧要,即一对学生 A 和学生 B 的考试与一对学生 B 和学生 A 的考试相同。
由于我们希望在两人一组的基础上比较考试,因此需要订购的项目总数 k 为 2。因此,我们有:

概率分布
在抛公平硬币之前,我们知道我们只能得到两种可能结果中的一种,不管是正面还是反面。在掷骰子之前,我们知道我们只能得到 6 种可能结果中的 1 种。现在问题来了:
- 如果我们掷 5 次硬币,得到一条尾巴的概率是多少?
- 如果我们扔一枚硬币 100 次,我们能得到多少条尾巴?
- 我们需要掷多少次骰子才能得到 4?
上述所有问题都可以借助概率分布来回答。

顾名思义,概率分布描述了每个结果的概率,如果数据是连续的,通常用概率密度函数(PDF)来表示,如果数据是分类/离散的,则用概率质量函数(PMF)来表示。x 轴描述了一组可能的数字结果,y 轴描述了它们出现的概率。
我们可以从概率分布中得出两个重要的性质:期望值和方差。
- 期望值衡量在给定的概率分布下,如果我们长期重复试验,我们期望得到的样本平均值。
- 方差测量当样本大小接近无穷大时,给定分布中样本可变性的理论极限。
有许多不同种类的概率分布,不可能记住每一种。如果你有兴趣了解所有的概率分布,请查看这个链接。
在本节中,我们将引导您了解一些在面试中最常被问到的概率分布及其使用案例。
离散概率分布
离散概率分布是一种分布类型,如果我们的数据是分类的,它可以用来可视化我们的数据的分布。这种分布的特征是一组离散的可能结果,每个结果的概率可以用概率质量函数(PMF)来建模。
PMF 的 x 轴代表事件的可能结果,y 轴代表每个事件发生的概率。在准备数据科学面试时,您应该了解几种离散概率分布。先说伯努利分布。
伯努利分布
伯努利分布在单次试验中只有两种可能的结果,0(失败)或 1(成功)。如果成功的概率是 p ,那么根据概率补码,失败的概率是 (1-p) 。

如果我们掷一枚公平硬币,我们知道得到一条尾巴的概率是 0.5。因此,获得正面的概率也是 0.5,如上图所示。
然而,需要注意的是,两种结果的概率不一定相等。如果我们有一个不公平的硬币,有可能得到正面的概率是 0.7,而得到反面的概率是 0.3。
伯努利分布中随机变量的期望值是:

而具有伯努利分布的随机变量的方差是:

例题:
脸书在他们的一次数据科学采访中问到了伯努利分布。问题是:
三只蚂蚁坐在一个等边三角形的三个角上。每只蚂蚁随机选择一个方向,开始沿着三角形的边移动。没有蚂蚁相撞的概率是多少?”
这是伯努利分布的一个例子。三只蚂蚁只有在向同一个方向移动时才不会发生碰撞,要么都向左(0),要么都向右(1)。我们只有两种可能的结果。
此外,每只蚂蚁都可以向任一方向移动,这对另一只蚂蚁没有任何影响,因此我们可以将这种情况归类为独立事件。
要回答这个问题,我们需要使用我们在上一节讨论过的概率论。



离散均匀分布
离散均匀分布可以有 n 种可能的结果,每种结果发生的概率是相等的。
离散均匀分布最著名的例子是滚动骰子。当你掷骰子时,有 6 种可能的结果,其中每一种都有相等的⅙概率。这就是为什么均匀分布具有平坦的 PMF,如下图所示。

离散均匀分布中随机变量的期望值为:

其中 a 是最小可能结果,而 b 是最大可能结果。
离散均匀分布中随机变量的方差为:

例题 1:
在他们的一次数据科学采访中,Spotify 问到了离散均匀分布。问题是:
“给定均匀分布[0,d]的 n 个样本,如何估计 d?”
要回答这个问题,我们需要看一看均匀分布的随机变量的期望值。我们知道期望值的公式是:

从题中我们还知道 a = 0 和b=d。将这些信息代入公式,我们得到:

如果我们有 n 个样本,正如问题提到的,那么我们可以估计与:**

即随机变量 X 对于 n 样本乘以 2 的平均值。
例题 2:
Jane Street 在他们的一次数据科学访谈中提出了一个关于掷骰子的问题:
“掷骰子的期望是什么?”
众所周知,掷骰子是一个均匀分布的例子。
要计算掷骰子的期望值,我们只需将该值代入期望值公式:

其中在我们这里, a = 1 或可能结果的最小值,而 b = 6 或可能结果的最大值。
因此,掷骰子的期望值是:

二项分布
二项式分布是伯努利分布的扩展。我们不再扔一次硬币,而是扔 100 次。在这 100 次投掷中,有多少次硬币正面朝上?

这是遵循二项式分布的示例。它测量在n 次试验中成功的概率。需要注意的一点是,每次投掷都是相互独立的,也就是说,一次硬币投掷的结果不会影响下一次投掷结果的概率。
二项分布的一般方程如下:

其中 n 为试验次数, k 为成功次数。注意,这里有一个二项式系数,我们在组合部分讨论过。
具有二项分布的随机变量的期望值是:

而方差是:

关于二项分布的面试问题很常见,所以你肯定需要了解这个分布的概念。
例题:
威瑞森无线在他们的一次数据科学采访中问到了二项分布。问题是:
“掷骰子 7 次得 5 的概率有多大?”
这个问题可以用二项分布来回答。在这种情况下,试验次数 n 为 7,成功次数 k 为 1(五分之一)。
将这些信息代入二项分布方程,我们得到:
****
超几何分布
超几何分布与上面的二项式分布非常相似。它们有或多或少相同的概率密度函数(PMF),你可能会在下面注意到。

假设我们有一副牌,我们想从那副牌中依次抽出 10 张牌。问题是,你会得到多少次心脏?这个用例非常类似于二项式分布,但是二项式分布和超几何分布之间有一个主要的区别。
在超几何分布的情况下,我们在下一次抽牌中拿到红心的可能性受到我们在上一次抽牌中拿到的牌的影响。
在第一次抽签之前,我们有 13/52 的概率得到一颗心脏。现在,假设我们在第一次抽牌中拿到了一张黑桃,那么我们在第二次抽牌中拿到红桃的概率不再是 13/52,而是 13/51,因为我们已经从一副牌中取出了一张。这意味着每次抽牌都不是相互独立的,因为当我们抽更多的牌时,这副牌的数量会减少。
二项式分布和超几何分布都是衡量在试验中【k】的成功次数。不同的是,二项式分布中的试验是 带 替换,而超几何分布中的试验是 不带 替换。
例题:
脸书在他们的一次数据科学采访中问到了超几何分布的概念。问题是:
从一副洗好的 52 张牌中抽出一张不同颜色或形状的牌的概率是多少
为了回答这个问题,让我们想象两个事件:
A :选择不同颜色卡片的概率
B :选择不同形状卡片的概率
从一副洗好的牌中随机抽出一张牌后,第二张牌具有不同颜色或形状(没有任何替换)的概率可以用数学方法定义为:

选择不同颜色卡片的概率:

选择不同形状卡片的概率:

选择不同颜色和形状的卡片的概率:

因此,选择不同颜色或形状的牌的概率是:
****
几何分布
几何分布也与二项分布密切相关。下面是几何分布的概率质量函数(PMF)。

你可能会注意到几何分布和二项分布之间的 PMF 是不同的。然而,他们有一个非常相似的概念。让我们以抛硬币为例。
假设我们想在掷硬币中得到一条尾巴。利用二项式分布,我们可以估计出从 n 次抛硬币中我们将得到的反面数量。同时,利用几何分布,我们可以估计投掷硬币的次数,直到我们最终得到第一条尾巴。
二项分布测量在n 次试验中获得 k 次成功的概率。几何分布也衡量成功的概率,但试验次数本身就是它的结果。这个分布更感兴趣的是找出在我们获得第一次成功之前的试验次数。
如果二项分布问:“在 n 次试验中有多少次成功?”,几何分布问:“我们要经历多少次失败才能获得第一次成功?”。这就是为什么几何分布的 PMF 有这样的形状。观察越多,你没有获得任何成功的可能性就越小。
具有几何分布的随机变量的期望值是:

其中方差可以计算为:

例题:
脸书在他们的一次数据科学采访中问到了几何分布的概念。问题是:
“你在一个赌场,有两个骰子,如果你掷出 5,你赢了,并得到 10 美元。你的预期支出是多少?如果你一直玩到赢为止(不管花了多长时间),然后停止,你的预期回报是多少?”
要回答这个问题,让我们考虑以下情况:
-每次我们想玩都要花 5 美元。
-如果我们掷出两个骰子得到一个 5,我们就能得到 10 美元。
我们的目标是通过掷两个骰子得到一个 5。这意味着我们在 36 种不同的组合中有 4 种可能性: {4,1} , {2,3} , {3,2} 和 {1,4} 。
我们掷出两个骰子得到 5 的概率是:

几何分布的期望值可以定义为:

其中 X 为首次成功前的试验次数。
由于我们有一个获胜的概率= 1/9,我们可以假设我们需要 9 次尝试才能成功获得 5。预期支出将是:

我们可以用下面的等式来模拟这个场景:

因此,预期支出将是:

负二项分布
负二项分布基本上是几何分布的延伸或推广。

如果几何分布问:“到第一次成功,要经历多少次失败?”,负二项分布问:“多少次失败,直到 n 次成功?”。负二项分布通过测量失败次数来扩展这一概念,而不是直到第一次成功的失败次数,直到我们达到 n 次成功。
负二项分布的随机变量的期望值是:

其中 n 是我们要寻找的成功次数,而 p 是成功的概率。
同时,负二项分布的随机变量的方差为:

例题:
Chicago Trading Company(CTC)在他们的一次数据科学访谈中,问到了负二项分布的概念。问题是:
“扔硬币直到你得到两个头。达到这个目标的预期投掷次数是多少?”
这是一个负二项分布的例子,我们应该找到试验的次数,直到我们第一次发现成功的试验。
这种二项式分布的期望值可以用数学方法定义为:

其中 X 是掷硬币,结果是正面,而 n 是成功的次数。
既然硬币是公平的,那么在掷硬币中我们得到正面的概率是,我们的目标是掷硬币直到我们得到 2 个正面(2 次成功)。有了这些信息,我们可以将这些值代入上面的等式。

因此,在我们得到两个正面之前,预期的投掷次数是 4 次。
连续概率分布
顾名思义,如果我们的数据是连续的,连续概率分布是一种可以用来可视化我们的数据分布的分布类型。与离散概率分布不同,连续概率分布不能用 PMF 建模。相反,用概率密度函数(PDF)来模拟连续的概率分布。
PDF 可以定义为区间 A 和 B 之间曲线下的面积,如下图所示。

A 和 B 之间的间隔可以用积分来计算,但大多数编程语言库或统计软件会替你这么做。
正态分布
正态分布是最著名的分布,它有一个钟形曲线,如上图所示。正态分布中有两个重要的参数:平均值和标准差。
由于这种分布的重要性质,它被广泛用于推断统计,这就是所谓的经验法则。
经验规则是定义正态分布的规则,它们是:
- 大约 68%的观察值在平均值的一个标准偏差范围内
- 大约 95%的观察值位于平均值的两个标准偏差之内
- 大约 99.7%的观察值位于平均值的三个标准偏差之内

平均值可以是任何非负的实数,标准偏差也应该是非负的。
标准正态分布
顾名思义,标准正态分布基本上就是正态分布,只是均值为 0,方差为 1。许多人也将这种分布称为 z 分布,这是一种在已知总体标准差的情况下,当人们想要将他们拥有的样本数据的平均值与整个总体的平均值进行比较时使用的分布。
您将在统计一章中看到更多关于 z 检验和 z 分布的内容。

学生 t 分布
学生 t 分布具有与标准正态分布相似的钟形曲线形状,但是该分布比正态分布具有更重的尾部。
这种分布的形状将根据称为自由度(DOF)的参数而改变。这个 DOF 可以定义为样本量减一, n-1 。样本量越大,这种分布就越像标准的正态分布。

当总体的标准偏差未知时,如果要测试样本数据的平均值是否对应于总体平均值,通常会使用这种分布。
你会在统计学一章中看到如何进行这个学生 t 检验。
数据科学面试中你应该知道的统计概念
在这一部分,我们收集了所有你应该知道的在面试中经常出现的关于统计学的技术概念:从基本概念到贝叶斯定理。让我们从基础开始。
基本统计:中心的测量(平均值、中间值、众数)
顾名思义,意为,中位数,众数衡量数据的集中趋势。换句话说,它们衡量我们数据的中心在哪里。
你可能会问,如果他们测量的是我们数据的中心,那他们有什么区别?这是他们用来寻找我们数据中心的方法。
- ****平均值:我们数据点的平均值
- ****中间值:我们排序后的数据点的中间点
- ****模式:我们的数据点中最频繁出现的数字
为了更好地理解它们之间的区别,让我们来看看不同分布的数据,如下所示。

如果数据呈正态分布,那么平均值、中值和众数都是相同的,正如您在上面的中间图像中所看到的。如果数据分布是左偏的,那么平均值将低于中位数。同时,如果数据分布是右偏的,那么平均值将高于中位数。
上图向我们展示了一件重要的事情:平均值是一个高度敏感的度量标准,用来衡量我们数据的中心。如果我们的数据中有异常值,平均值可能会比中值拖得更远。因此,在使用平均值来衡量数据中心之前,检查数据中是否存在异常值是非常重要的。
例题 1:
脸书在他们的一次数据科学采访中,问到了均值和中位数的概念。问题是:。
“在墨西哥,如果取平均值和中值年龄,哪个会更高,为什么?”
要回答这个问题,我们需要找出墨西哥的年龄分布是什么形状,是正态分布,右偏,还是左偏。
根据统计数据显示,墨西哥在 2010 年至 2020 年间一直存在右偏的年龄分布。因此,我们可以说平均数高于中位数。
例题 2:
虽然与均值、众数和中位数的概念没有直接关系,但 Airbnb 在他们的数据科学采访中提出了以下问题:
“你如何估算缺失的信息?”
虽然这个问题没有明确地谈论中心的措施,但是它的概念对于回答这个问题是非常重要的。假设我们有数字数据,其中一小部分包含缺失值。如果我们想估算缺失值,我们可以用数据的平均值或数据的中位数来填充它们。但是我们应该选择哪一个呢?
我们首先需要检查数据的分布,看看是否存在异常值。如果有异常值,那么选择平均值来填充缺失值会在我们的数据中引入偏差,这不是我们想要实现的。如果我们的数据中有异常值,使用中位数来填充缺失值将是更好的选择,因为中位数对异常值更稳健。
现在,如果我们有分类数据,那么如果我们用模式估算数据,这将是有意义的,这意味着我们只需用数据中出现最频繁的类别来填充缺失值。
基本统计:分布的度量(标准差和方差)
顾名思义,分布度量值衡量数据的分布程度。一般来说,我们可以使用 4 种不同的指标来测量数据的分布:范围、方差、标准差和四分位数。
范围
范围是衡量数据分布的最简单的指标。假设我们有一个公司员工年薪的数据。假设最低工资 35000 美元,最高 105000 美元。这个范围就是最高工资和最低工资之间的差值。因此,在这种情况下,范围是 70,000 美元。
差异
方差衡量我们的数据在平均值周围的离差。然而,方差在实际应用中并不常用,因为我们从方差中得到的值是平方的,即

其中 S 为方差, x i 为一次观测值, x_bar 为所有观测值的平均值, n 为观测值总数。
这意味着方差和平均值具有不同的单位,例如,如果平均值以米为单位( m ),那么方差将以平方米为单位( m )。这使得方差在定义数据与平均值的差距时不够直观。
标准差
标准差可以帮助解决方差问题,因为它也可以测量数据在平均值周围的离差。区别在于,标准差是方差的平方根,即

这一小小的调整使得均值和标准差之间的观察单位变得相等,从而使我们更容易量化数据在均值周围的分布范围。
如果我们的数据是正态分布的,即有一个完美的钟形曲线,标准差就成为一个重要的度量标准,用来估计数据点相对于平均值接近程度的比例。

举个例子,假设我们知道数据是正态分布的,员工的平均年薪是 60000 美元。由此,我们可以推断,68.2%的员工工资位于 60,000 美元的 1 个标准差之间,约 95%位于 60,000 美元的 2 个标准差之间,99.7%位于 60,000 美元的 3 个标准差之间(参见正态分布部分的经验法则)。
四分位数
四分位数通过将数据分布分为 4 部分来衡量数据的分布:下四分位数(数据的 25%)、两个四分位数(数据的 25%-50%和 50%-75%)和上四分位数(数据的 75%)。通常,四分位数的概念可以通过以下箱线图可视化更容易理解:

在数据科学访谈中,关于传播度量的问题非常常见,例如,Travelport 提问:“什么是标准差?我们为什么需要它?”微软问:“方差的定义是什么?”。到目前为止,我们已经讨论了这两个问题的答案。
例题:
微软在他们的一次数据科学采访中询问了测试我们对传播度量的知识的概念。问题是:
“如何检测一个新的观察值是否是异常值?”
虽然问题没有明确提到传播的度量,但是它的概念对于回答这个问题非常重要。为了检测异常值,我们可以查看数据点在分布中的位置。如果我们有正态分布的数据,那么我们可以得出结论,如果一个数据点位于平均值的 3 个标准偏差之外,那么它就是异常值。
我们也可以使用如上所示的箱线图来检测数据点是否是异常值。如果一个数据点位于箱线图的最大值或最小值之上或之下,那么我们可以断定它是一个异常值。
推断统计学
在数据科学领域,推理统计的知识变得非常重要。这是我们通过观察数据中的一些模式来获得对我们试图解决的问题的洞察力的强大工具。
在推断统计的范围内,您需要了解几个步骤和术语。先说假设检验。
假设检验
通过进行假设检验,你基本上是通过观察你所拥有的样本数据来检验你对一般人群的假设或信念。
这意味着在假设检验中,你通常会有:
- ****无效假设:假设一切都是正常的假设,或者是怀疑的假设。
- ****替代假设:一种反假设,假设原假设中的任何陈述都不正确。
举个例子,你想知道一个学校的男女生智商是否有显著差异。在这种情况下,假设是:
- ****零假设:男女学生智商相同
- ****另类假设:普通学生和女学生的智商不同
假设检验的主要目的是找出哪个假设更合理。
但是,需要注意的是,在假设检验中,原假设永远是现状,也就是说原假设永远是默认的真值。这意味着我们要么拒绝零假设,要么不拒绝。这也是为什么我们从来不说我们“接受”零假设的原因。
现在的问题是,我们如何知道我们是否应该拒绝零假设?让我们在下一节中找出答案。
显著性水平
显著性水平是我们在假设检验时需要设置的一个重要概念。这是因为在我们决定拒绝一个无效假设之前,显著性水平将作为我们的容忍度。
显著性水平的数量可以变化,这取决于您的兴趣。然而,显著性水平的经验法则是 5%或 0.05。
显著性水平越低,在拒绝零假设时就越谨慎,反之亦然。
我们将在下面的章节中进一步阐述显著性水平的概念。
置信区间
置信区间可以描述为总体参数值的合理范围。
如果我们进行双尾假设检验,我们可以说置信区间补充了显著性水平。这意味着,如果我们的显著性水平是 5%,那么置信区间将是 95%,如下图所示。

如果你的显著性水平是 1%,那么置信区间就是 99%,如果你的显著性水平是 10%,那么置信区间就是 90%
计算置信区间本身的公式可以写成:

其中 x_bar 为样本均值, Z 为置信水平值,【σ】为样本的标准差, n 为样本数。
Z 的值直接对应你的置信区间。如果置信区间是 95%,那么 Z 就是 1.96。
此外,重要的是要注意,置信区间值、标准偏差和上述观察次数之间的等式可以由两个不同的参数描述:误差幅度,即:

或标准误差,即:

例题 1:
特斯拉在他们的一次数据科学采访中,问到了置信区间的概念。问题是:
“有 100 种产品,其中 25 种是坏的。置信区间是多少?”
要回答这个问题,我们需要结合我们在概率一节中学到的置信区间和二项分布的知识。
如果有 100 件产品,我们知道其中有 25 件是坏的,那么在这种情况下我们就要处理二项分布。
为了更新,二项式分布的平均值或期望值和方差可以计算如下:
****
其中 n 为实验总数 p 为产生不良产品的概率。
不合格产品的产出概率可以计算如下:

将这个概率值代入上面的均值和方差方程,我们得到:
****
同时,我们知道标准差是方差的平方根,因此:
****
标准误差是标准偏差除以实验总数的平方根。



现在我们有了确定置信区间所需的所有值。
****
例题 2:
Google 在他们的一次数据科学采访中询问了误差幅度和样本量的概念。问题是:
“对于样本量 n,误差幅度为 3。我们还需要多少样本才能将误差幅度降至 0.3?”
正如我们在上面看到的,误差幅度可以用数学方法定义为:

从上式中,我们知道误差幅度与样本量成反比,即:

如果样本大小为 n 的误差幅度为 3,那么为了将误差幅度降低到 0.3,我们需要:



这意味着我们需要 100 个 n 更多的样本来将误差幅度降低到 0.3*
p 值
在统计学中,p 值代表概率值。p 值代表假设零假设为真时,观察结果出现的可能性有多大。
p 值越低,考虑到零假设为真,您的观察就越令人惊讶。
p 值和显著性水平的组合为您提供了是否应该在假设检验中拒绝零假设的概述。
假设你观察到的 p 值是 0.02,你的显著性水平是 0.05。因为 p 值小于显著性水平,所以我们拒绝零假设,支持替代假设。同时,如果你的 p 值是 0.02,但你的显著性水平是 0.01,那么我们不能拒绝零假设。
例题:
State Farm 在一次数据科学访谈中询问了 p 值的概念。问题是:
“什么是 p 值?如果您有一个不同的(大得多,例如 300 万条记录),您对 p 值的解释会改变吗?)数据集?”
你可以从上面的定义中回答什么是 p 值。现在的问题是,如果我们有一个更大的数据集,我们对 p 值的解释会改变吗?
我们对 p 值的解释永远不会改变,不管我们的数据集是大还是小。然而,如果我们有更多的数据,标准误差就越小,因此,得到的 p 值就越稳健。
统计测试
现在我们知道在假设检验中有三个常见的术语:显著性水平、置信区间和 p 值。
为了选择我们是否应该拒绝零假设,我们做统计测试,最后,我们得到 p 值。接下来,我们将 p 值与我们的显著性水平进行比较。如果 p 值小于显著性水平,那么我们拒绝零假设,支持替代假设。
但是我们如何进行统计测试来得到这个 p 值呢?这就是事情变得有点棘手的地方,因为有不同的统计测试,这取决于你想观察什么。以下是你应该知道的常见统计测试。
总体均值的 Z 检验
何时使用该统计测试:
如果我们想检验平均样本量是否与平均总体量一致。
要满足的条件:
- 总体的标准偏差是已知的
- 样本是随机选择的
- 样本明显小于总体
- 变量需要具有正态分布
正如您可能已经猜到的,这个测试中的变量应该遵循标准的正态分布或 z 分布。为了获得 p 值,我们需要首先计算 Z 值。
下面是计算 Z 值的公式:

其中 x_bar 为样本均值, μ 为总体均值, σ 为总体标准差, n 为观察次数。
在我们得到 Z 值后,我们可以使用 Python 或 R 中的 Z 表或更方便的统计库来得到相应的 p 值。
在现实生活中,不经常进行 Z 检验,因为总体的标准偏差通常是未知的。
总体均值的单样本 t 检验
何时使用该统计测试:
如果我们想检验样本数据的平均值是否符合总体平均值。使用 t 检验,我们有一个假设,即我们不知道总体标准差,这在现实生活场景中更现实。
需要满足的条件:
- 样本是随机选择的
- 如果样本量很小(15 左右),那么数据应该呈正态分布
- 如果样本量相当大(大约 40),那么即使数据有偏差,进行测试也是安全的。

其中 x_bar 为样本均值, μ 为总体均值, s 为样本的标准差, n 为观察次数。
t 检验背后的直觉与 Z 检验相似,只是我们不知道总体标准差。因此,我们使用样本标准差。
还有,t-test 中还有一个额外的参数,就是自由度(DOF)。DOF 正好是样本量减 1,或者说 n-1 。
一旦我们知道了 t 值和自由度,我们就可以使用统计软件找到相应的 p 值。
配对 t 检验
何时使用该统计测试:
如果我们想用不同的处理方法测试同一个样本,然后检查这种处理方法是否会在同一个样本中产生统计学上不同的结果。
一般来说,要满足的条件与上面的单样本 t 检验相同。计算 t 统计量的公式也是一样的。唯一的区别是我们如何解释 t 检验的结果。
之前,t 检验测量我们感兴趣的变量的平均值。同时,在这个配对 t 检验中,我们更感兴趣的是我们感兴趣的变量的均值或标准差。
双样本 t 检验
什么时候使用这个统计测试:
如果我们想用不同的处理方法测试两个不同的样本,然后检查两个样本之间的处理方法是否会产生统计上的不同结果。
要满足的条件:
- 与单样本 t 检验列表相同
- 两个样本的分布是相似的
- 如果两个样本的大小相同,结果会更可靠

其中索引 1 和 2 分别表示您的第一个和第二个样本。
这里 t-统计的直觉与配对 t-检验相同,这意味着 t-统计测量两个不同样本的均值和标准差差异。
ANOVA
何时使用该统计测试:
如果我们想用不同的处理方法测试两个以上的不同样本,然后检查这些处理方法是否会在不同的样本中产生统计上不同的结果。
一般来说,要满足的条件与上面的双样本 t 检验相同,但在 ANOVA 中,不是只有两个样本,而是有两个以上的样本。
一般来说,下面是如何进行方差分析的步骤:
- 计算所有样本的平均值(总体平均值)
- 计算组内偏差,即样本中每个成员相对于相应样本均值的偏差
- 计算组间方差,即每个样本与所有样本平均值的偏差
- 计算 F 统计量,即组间变异和组内变异的比率
方差分析是一个耗时的手工计算测试。因此,通常在统计软件或编程语言的统计库的帮助下进行这种测试。
查看我们的帖子' 数据科学面试的概率和统计问题 ',了解如何使用 Python 解决概率和统计问题。
卡方拟合优度
何时使用该统计测试:
如果我们想测试样本数据是否能很好地代表总体。然而,我们不是看平均值,而是看比例。
例如,假设我们有 10 包 M&M 巧克力,每包有五种不同的颜色,比如蓝色、红色、黄色、绿色和棕色。我们可能想测试每包中这五种颜色的比例是否相等。
需要满足的条件:
- 样本是随机选取的
- 我们的数据应该是分类的或名义上的。既然我们对比例感兴趣,那么这个测试就不适用于连续数据
- 样本量足够大,每个数据类别至少有 5 个项目。
下面是卡方拟合优度检验的公式:

其中 O 为每个类别中的观察频率计数, E 为每个类别中的期望频率计数, k 为类别总数。
在计算了拟合优度之后,最后我们将得到 p 值,与上面提到的其他测试一样,这使我们能够洞察我们是否应该拒绝零假设。
卡方独立性检验
何时使用该统计测试:
如果我们想测试两个或多个样本数据是否相关。这个想法类似于方差分析。
然而,如果在 ANOVA 中我们对平均值感兴趣,那么在这个测试中我们对比例更感兴趣。举个例子,假设我们拥有一家电影院。我们想知道电影的类型和人们购买零食的数量是否相关。电影的类型是我们的第一个样本数据,零食的数量是我们的第二个样本数据。
一般来说,要满足的条件与上面的拟合优度相同,除了不是只有一个样本,在这个测试中我们应该有两个或更多的样本。
下面是独立性卡方检验的公式:

其中 r 和 c 是你观察到的两个不同的类别,即从上面的例子来看, r 可能是电影的类型, c 可能是小吃。
在计算了上面的公式之后,我们将在最后得到 p 值,我们可以用它来决定我们是否应该拒绝零假设。
例题:
在他们的一次数据科学采访中, Amazon 询问了一个将我们关于不同统计方法的知识付诸行动的概念。问题来了。
在 A/B 测试中,你如何检查分配到不同的桶是否真的是随机的?
既然我们这里有一个 A/B 测试,那么假设我们有两个变量叫做 A 和 B 。如果分配确实是随机的,那么两个变量之间应该没有统计上的显著差异。
既然我们感兴趣的是检查赋值是否真的是随机的,那么我们可以比较两个变量的平均值,如果它们是连续变量的话。如果只有一种处理方法,那么我们可以使用双样本 t 检验。同时,如果有多种治疗方法,那么我们可以使用方差分析。
如果我们想知道变量 A 和变量 B 是否相互关联,它们是分类变量,那么我们可以使用独立性的卡方检验。
假设检验的步骤
现在我们知道了所有关于推断统计学的事情!让我们总结一下,收集正确进行假设检验所需的所有必要步骤:
- 首先,建立假设:原假设和 T2 假设
- 选择您的重要性级别
- 进行适合你观察类型的统计测试
- 从统计检验中找出 p 值
- 决定是否拒绝零假设
例题:
在他们的一次数据科学访谈中,脸书问到了推断统计学的端到端概念。问题是:
“我们的产品被两个不同的群体以不同的方式使用。你的假设是什么,为什么以及你将如何去测试它?”
当我们的产品被两个不同的群体使用时,我们需要首先收集数据,然后我们可以使用双样本 t 检验来分析结果。
1.我们把我们的假设表述如下:
- 零假设:两组间的平均使用率相同
- 替代假设:两组之间的平均使用率不同。
2.我们选择显著性水平,通常在 0.05 左右
3.从数据中,我们可以得到每组的平均值和标准差。
4.然后,我们使用双样本 t 检验来计算 t 统计量。
5.如果得到的 t 检验低于我们的显著性水平(< 0.05), then we can reject our null hypothesis in favor of our alternative hypothesis, i.e the average used rate between the 2 groups is different.
6. If the resulting t-test is above our significance level (> 0.05),那么我们可以坚持我们的零假设,即两组之间的平均使用率大致相同。
统计能力
正如您已经知道的,当您在进行统计测试后获得 p 值时,您将有权力通过与您的显著性水平进行比较来决定是否拒绝零假设。
然而,统计推断总是会伴随着不确定性。这种不确定性主要来自您的显著性水平,您可以根据您的研究以及您为统计测试收集的样本数据质量进行微调。
这意味着你在假设检验过程中容易犯两种错误,在统计学中通常被称为第一类错误和第二类错误。****
- 第一类错误意味着你错误地拒绝了零假设
- 第二类错误意味着你不能拒绝零假设

统计能力是你正确拒绝零假设的概率。这也意味着犯第二类错误的可能性更小。统计能力越高,你犯第二类错误的概率就越低。
力量分析
现在你知道在进行假设检验时,你可能会遇到两种类型的错误。如前所述,误差的一个常见来源是数据质量。这意味着您可能没有足够的样本数据来产生一个 p 值,以令人信服地得出您是否应该拒绝零假设的结论。
功效分析中经常出现的问题是:“要确保我们得到的 p 值有足够的说服力让我们拒绝零假设,最少需要多少样本?”**
功效分析计算中通常考虑 4 个参数:效果大小、样本大小、显著性水平和统计功效。
从上面几节中,您已经知道了样本大小、显著性水平和统计功效。然而,效应大小通常是使用统计方法来计算的,例如,如果您想测量变量之间的关系,可以使用皮尔逊相关;如果您想确定变量之间的差异是否显著,可以使用科恩的 d 相关。
在功效分析中,您需要预先定义效应大小、显著性水平和统计功效的值,以找出所需的样本大小。
显著性水平的默认值是 0.05,Cohen 的 d 发现大效应大小的默认值是 0.80,统计功效的默认值也是 0.8。但是,您可以根据您的研究对这些值进行微调,这需要对主题有所了解。
功耗分析是一项令人望而生畏的手工计算任务,因此通常用编程语言在统计库中实现。
贝叶斯定理
在上一节中,我们讨论了频率主义者观点中常用的推断统计。在这一节中,我们将讨论推理统计学的另一个视角,它利用了贝叶斯定理。
贝叶斯定理是一种应用概率论进行统计的方法。在某种意义上,这个定理与人类在现实生活中对事物的推断有相似之处。它对事件的发生有一个先验的信念,并且这个信念将随着新的证据或数据的提供而更新。最终产生一种后验信念。
贝叶斯定理背后的基本概念通常被称为贝叶斯法则。这个规则类似于你在上面的条件概率部分看到的。
下面是贝叶斯法则的等式:

其中 A 和 B 是事件。
我们可以定义 P(A|B) 为事件 A 发生的概率,假设事件 B 已经发生。同样,我们可以定义 P(B|A) 为事件 B 发生的概率,假设事件 A 已经发生。
除此之外,上面的贝叶斯法则也展示了这个法则的基本概念:先验,似然,边际,以及后验,如下图所示:

更详细地说,以下是后验概率、可能性、先验概率和边际概率试图回答的问题:
- 根据观察到的证据,我们的假设有多大的可能性?
- 可能性:给出的证据表明我们的假设是正确的可能性有多大?
- 在我们看到任何观察结果或证据之前,我们的假设有多大的可能性?
- 在所有可能的假设下,证据的可能性有多大?
例题:
在他们的一次数据科学采访中,脸书问到了贝叶斯定理的概念。问题是:
“你即将登上去西雅图的飞机。你想知道你是否应该带一把伞。你打电话给住在那里的三个朋友,分别问他们是否在下雨。你的每个朋友都有 2/3 的机会对你说真话,1/3 的机会用谎言来搞乱你。三个朋友都告诉你“是的”下雨了。西雅图真的下雨的概率有多大?”
为了回答这个问题,让我们首先假设各种事件:
西雅图正在下雨
西雅图没有下雨
- Xi :具有伯努利分布的随机变量,使得
Xi:如果一个朋友说“是的,西雅图会下雨”
Xi = 0,如果一个朋友说“不,西雅图不会下雨”
现在,由于我们没有任何关于西雅图下雨概率的信息,让我们假设它是 0.5,因此:

在问题中,三个朋友都说“是的,西雅图会下雨”。我们可以这样表达:**

我们知道我们的朋友说真话的概率是⅔.
我们可以将朋友告诉我们“是的,西雅图会下雨”的概率表示为:**

我们的朋友告诉我们‘不,西雅图不会下雨’的概率,因为现在西雅图没有下雨:**

现在我们得到了我们需要的信息,假设我们的三个朋友用贝叶斯定理说【是的】,我们可以得到西雅图下雨的概率,如下所示:**



概率统计面试备考小技巧
我们都同意,学习统计学,无论是为了考试还是为了面试,都不容易。正如你从上面的章节中看到的,为了至少对统计学和概率有一个大致的了解,我们需要涵盖很多主题。
下面的提示可能有助于你在概率统计面试中脱颖而出。
学习概念
如果你学习的是公式而不是概念,那么你学习统计学的方式是错误的。问题是,如果你忘记了公式,你可以随时回头看课本。然而,如果你忘记了这个概念,那么你就不能用正确的方法来回答这个问题。
最好学习这个概念,因为这样你就能正确地处理每个问题,也就是说,我们是否认为这个问题可以用二项分布、几何分布或负二项分布来解决。
举个例子,当你得到一个问题,问在 20 次抛硬币中得到 5 个反面的概率是多少,你应该知道这个问题可以用二项分布来回答。如果你忘记了二项分布的方程式也没关系,因为你总是可以在网上或教科书上找到它。最重要的是你知道这个问题可以用二项分布来解决。
永远学习概念,而不是公式。
使用笔和纸
让我们现实一点,当我们处理统计和概率问题时,我们是在处理数学。因此,不要试图在头脑中直接解决概率和统计面试问题。相反,使用传统的方式,比如用笔和纸来集思广益。
每当你把你的想法写在一张纸上,那么你就更容易以一步一步的方式解决问题,你会以更简洁的方式思考问题和如何解决它。
不要一口气学会所有的概念
掌握统计学就像试图增肌或减肥一样,不可能在一次静坐或一次健身中完成。相反,它是建立在特定时间段内的持续练习的基础上的。
每天留出大约一个小时,在你选择的时间内尝试解决概率和统计面试问题,并且不要忘记休息一段时间。最重要的是学习的一致性。
一段时间后,保证你会习惯统计学的问题,你将能够看到概率和统计面试问题中有重复出现的模式。你将能够理解在每个问题中你应该应用哪个概念,例如,你应该使用方差分析还是卡方分析,你应该使用几何分布还是超几何分布,等等。
仔细阅读或听问题
当你得到概率和统计面试问题时,确保你理解你试图解决的问题是非常重要的。但是我们如何确保这一点呢?
诀窍是:你可以用自己的话向受访者解释这个问题,然后问他们你的解释是否符合被问的问题。这种方法有两个目的:确保你正确理解了问题,也为你赢得了一点时间来思考解决方案。
总是要求澄清
理解了所提的问题后,如果你觉得问题不完整,需要更多的背景信息,一定要问清楚或假设。
这是因为概率和统计面试问题充满了你需要注意的假设,即一个事件是否独立或依赖于另一个事件,数据是否连续或分类,我们是否在寻找 A/B 测试中的平均值或比例,等等。只有在你完全理解这个问题之后,你才能提供正确的解决方案。
最初发表于【https://www.stratascratch.com】。
数据科学面试的概率和统计问题
原文:https://towardsdatascience.com/probability-and-statistics-questions-for-data-science-interviews-69820cb28c11?source=collection_archive---------34-----------------------
如何使用 Python 解决数据科学面试的概率统计问题。

图片来自 Canva
数据科学是数学、计算机科学和商业专业知识的交叉。许多人害怕接触数据科学,因为他们害怕高中和大学的代数、矩阵和组合学。虽然我们无法逃避这些,但我们可以通过使用 Python 中的各种库来解决数据科学面试中经常出现的概率和统计面试问题,从而使我们的生活变得愉快并提高我们的 Python 技能。
概率统计面试问题的 Python
Python 的一个优势是可以为世界上几乎所有的东西提供大量的库(或包)。在 PyPi 上,我们有超过 30 万个图书馆。它们中的大多数都是开源的,其源代码可以在 GitHub 和其他在线存储库中找到。我们将讨论几个可用于解决概率统计面试问题的方法。我们将主要出于三个目的使用这些库-
- 列举场景。虽然我们可以列出掷硬币三次的所有可能情况,但在从一副牌中抽取三张牌或掷出五个骰子时,可能无法检查所有情况。我们还可以快速地将结果可视化,以帮助我们更好地理解主题。
- 计算准确的概率。我们可以通过使用 Python 中的各种科学计算库(SciPy、NumPy 等)来交叉检查我们的分析解决方案,以防解决方案不存在或者我们想要检查我们的工作。
- 模拟场景和计算经验概率。有时不可能精确计算值。因此,我们可以进行试验,找出观察到的或经验的概率。如果我们适当地设置了实验,那么正如我们将观察到的,结果惊人地接近解析解。这是测试您的解决方案是否正确的好方法。
我们将在这里使用的主要库是-
- itertools:计算组合学
- Numpy:用于快速数学计算和生成随机数
- SciPy:用于使用内置分布函数分析计算概率。
- Matplotlib 和 Seaborn:快速可视化结果。
概率和统计面试问题中测试的领域
数据科学面试问题在概率和统计领域测试的广泛领域包括-
- 组合学
- 例如,概率游戏:掷骰子、掷硬币、从一副牌中抽取
- 条件概率
- 概率分布
- 了解基本的统计术语
-均值、中位数、众数
-方差、标准差 - 处理异常值
- 阅读统计图表,如直方图、箱线图等。
StrataScratch 平台有超过 150 个这样的数据科学面试问题,你可以练习并在下一次面试中胜出。
五分之二(容易)
找出在 5 次掷硬币中恰好得到两个反面的概率?

截图来自 StrataScratch
你可以在这里解决这个问题:https://platform . stratascratch . com/technical/2283-五选二
解决方案
这是一个简单的问题。让我们看看所有可能的情况。每次抛硬币有两种结果。结果会像下面的树一样生长出来。

作者创造的形象
抛 n 次硬币后的结果数将是 2 n。这里我们有五次投掷,所以总的可能结果将是 2x2x2x2 = 32。
让我们计算一下有利的结果。我们需要获得两条尾巴。因此,一些有利的结果包括 H-T-H-T-H,H-T-T-H-H,H-H-T-T-H 等。但是 H-T-H-H-H 和 H-T-H-T-T 不会是有利的,因为我们分别有一条和三条尾巴。
因此,为了得到有利的案例,我们需要从五次翻转中选择两次来展示尾部。其余的会露出头来。这可以通过 5C2 或 10 种方式来实现。这些是有利的情况。
我们需要的概率是

二项分布
这些类型的布尔值结果,即正面或反面、真或假、是或否等,在概率和统计中非常常见。这些遵循二项式分布,其中 n 次中恰好有 k 次成功的概率由下式给出

在哪里

p 是每个结果中成功的概率,( 1-p)是失败的概率。
在我们的例子中,我们有 n = 5,p =和 k = 2。直接代入,我们得到

让我们用 Python 来计算这些结果。
使用 itertools
我们可以使用 itertools 库来枚举所有可能的情况和有利的情况。让我们从所有可能的情况开始。我们需要通过五次抛硬币来找出所有的可能性。我们可以使用 itertools 中的 product()方法来生成这个。
flips_5 = list(itertools.product('HT', repeat = 5))
flips_5[:10][('H', 'H', 'H', 'H', 'H'),
('H', 'H', 'H', 'H', 'T'),
('H', 'H', 'H', 'T', 'H'),
('H', 'H', 'H', 'T', 'T'),
('H', 'H', 'T', 'H', 'H'),
('H', 'H', 'T', 'H', 'T'),
('H', 'H', 'T', 'T', 'H'),
('H', 'H', 'T', 'T', 'T'),
('H', 'T', 'H', 'H', 'H'),
('H', 'T', 'H', 'H', 'T'),
('H', 'T', 'H', 'T', 'H')]
我们可以通过查看清单的长度来核实案例的数量。
len(flips_5)32
从 flip_5 结果中,我们需要找出有利的结果。所以我们只保留尾部正好为 2 的结果。您可以使用内置的 itertools 方法— filterfalse()为此传递一个 lambda 表达式。
favorable_flips = [flip_outcome for flip_outcome in flips_5 if
len(list(itertools.filterfalse(lambda x : x !='T', flip_outcome))) == 2]
favorable_flips[('H', 'H', 'H', 'T', 'T'),
('H', 'H', 'T', 'H', 'T'),
('H', 'H', 'T', 'T', 'H'),
('H', 'T', 'H', 'H', 'T'),
('H', 'T', 'H', 'T', 'H'),
('H', 'T', 'T', 'H', 'H'),
('T', 'H', 'H', 'H', 'T'),
('T', 'H', 'H', 'T', 'H'),
('T', 'H', 'T', 'H', 'H'),
('T', 'T', 'H', 'H', 'H')]len(favorable_flips)10
我们现在可以很容易地计算概率。
prob_2T_5flips = len(favorable_flips) / len(flips_5)
prob_2T_5flips0.3125
使用 SciPy
我们可以使用 SciPy 中内置的二项式分布生成器函数来实现相同的结果。
stats.binom.pmf(k = 2,n = 5, p = 0.5)0.3125
使用 NumPy 计算经验结果
如果我们不知道如何使用公式计算,也可以尝试模拟许多场景的结果。为此,我们模拟了一百万次投掷五枚硬币的场景。我们在 NumPy 的 random 模块中使用 choice()方法。
outcomes = np.random.choice(['H', 'T'], (1000000, 5))
outcomes[:10]array([['T', 'T', 'H', 'H', 'H'],
['T', 'H', 'H', 'T', 'H'],
['T', 'T', 'H', 'H', 'H'],
['T', 'H', 'T', 'T', 'T'],
['H', 'H', 'T', 'H', 'H'],
['T', 'H', 'T', 'T', 'H'],
['H', 'H', 'H', 'H', 'T'],
['T', 'T', 'T', 'T', 'H'],
['T', 'H', 'T', 'T', 'H'],
['H', 'H', 'T', 'T', 'H']], dtype='<U1')
有利的结果现在可以通过只设定两个尾部出现的情况来产生。
fav_outcomes = [outcome for outcome in outcomes if sum(outcome == 'T') == 2]
fav_outcomes[:10][array(['T', 'T', 'H', 'H', 'H'], dtype='<U1'),
array(['T', 'H', 'H', 'T', 'H'], dtype='<U1'),
array(['T', 'T', 'H', 'H', 'H'], dtype='<U1'),
array(['H', 'H', 'T', 'T', 'H'], dtype='<U1'),
array(['H', 'T', 'H', 'T', 'H'], dtype='<U1'),
array(['T', 'H', 'T', 'H', 'H'], dtype='<U1'),
array(['T', 'H', 'H', 'H', 'T'], dtype='<U1'),
array(['H', 'T', 'H', 'H', 'T'], dtype='<U1'),
array(['T', 'H', 'H', 'H', 'T'], dtype='<U1'),
array(['T', 'H', 'H', 'T', 'H'], dtype='<U1')]
最终概率可以像前面一样找到。
len(fav_outcomes) / len(outcomes)0.311937
可以看出,我们不会得到确切的答案,但我们可以非常接近它。
我们可以将所有的场景(没有尾巴,只有一个尾巴,等等)与使用 SciPy 获得的精确答案进行比较。我们明白了。

作者创造的形象
经验概率与分析计算值非常接近。让我们来看一个更复杂的问题。
不同的卡(中号)
求从一副洗好的 52 张牌中抽出两张属于不同颜色或不同形状(花色)的牌的概率?

截图来自 StrataScratch
你可以在这里解决这个问题:https://platform . stratascratch . com/technical/2001-异卡
解决方案
让我们确定所有可能的情况。我们必须一张一张地抽两张牌。因此,可能情况的数量将是 52P2 = 52 * 51 = 2652
现在让我们找出有利的情况。我们需要两张不同颜色或形状(花色)的牌。因此,我们不能画两张黑桃或两张红心。但是我们可以画一个梅花和一个黑桃或者一个心形和一个菱形,因为即使颜色相同,花色却不同。虽然直接计算有利案例的数量并不太困难,但在许多涉及组合学和概率的案例(包括本案例)中,更容易的是计算不利案例,然后从总案例数中减去有利案例数。
我们有哪些不利的案例?让我们否定我们有利的情况。
Unfavorable cases = Not (Two cards are not of the same color or shape)
从布尔代数中,Not (A 或 B)既不产生 A 也不产生 B。这可以从下面的维恩图中看出。

作者创造的形象
Not(两张卡片颜色或形状不同)可以写成
not(两张卡片颜色不同)和 Not(两张卡片形状不同)
解决双重否定,我们得到
不利情况=两张牌颜色相同,花色相同。
这简单地分解为两张相同花色的牌。(因为同一花色的任意两张牌必须是相同的颜色)
现在我们可以很容易地计算这个。
首先,我们找到一套衣服,它可以用 4C1 = 4 种方式来搭配。
然后我们从这个花色中抽两张牌。每种花色有 13 张牌。因此,路的数量将是 13P2 = 156 路。
两者相加,不利情况数= 4×156 = 624
因此,有利案例的数量将为 2652–624 = 2028 种方式。
概率= 2028 / 2652 = 13 / 17
替代方法:
只有抽完第二张牌,我们才会进行比赛。这决定了它是否匹配。在我们从这副牌中抽出任何一张牌后,还会剩下 51 张牌。在这 51 张牌中,有 12 张属于我们已经抽过的同一套牌。我们需要避开这 12 张牌。
因此,有利案例数= 51 -12 = 39,所有可能案例数= 51
因此,概率= 39 / 51 = 13 / 17
求解使用 Python 精确计算:
使用 itertools,我们首先模拟一个甲板。
suits = ['S', 'C', 'D', 'H']
ranks = [2, 3 ,4, 5, 6, 7, 8, 9 , 'T', 'J', 'Q', 'K' , 'A']
cards = [str(rank) + suit for suit in suits for rank in ranks]
cards[:20]['2S',
'3S',
'4S',
'5S',
'6S',
'7S',
'8S',
'9S',
'TS',
'JS',
'QS',
'KS',
'AS',
'2C',
'3C',
'4C',
'5C',
'6C',
'7C',
'8C']len(cards)52
让我们从这 52 张牌中抽出两张。为此,我们将使用 permutations()方法。
outcomes = list(itertools.permutations(cards, 2))
len(outcomes)2652
这与我们通过分析计算得到的数字相同。现在我们可以计算不利的结果
unfavorable_cases = len(list(itertools.permutations(suits, 1))) *
len(list(itertools.permutations(ranks, 2)))
unfavorable_cases624
我们现在可以像前面一样计算概率。
probability = 1 - unfavorable_cases / len(outcomes)probability0.7647058823529411
使用 NumPy 进行模拟
让我们从一副牌中抽出两张牌一百万次。
any_two_cards = np.random.choice(cards, (1000000,2))
any_two_cards[:10]array([['QC', '3D'],
['5C', 'JS'],
['3H', 'AH'],
['KS', '6C'],
['7S', '5C'],
['KC', 'KS'],
['4S', '3D'],
['4S', 'TD'],
['5H', '8D'],
['5C', '8S']], dtype='<U2')
计算花色(牌串的最后几个字符匹配)的不利情况
unfavorable_cases = [selection for selection in any_two_cards if
(selection[0][-1] == selection[-1][-1]) ]
unfavorable_cases[:10][array(['3H', 'AH'], dtype='<U2'),
array(['TC', '5C'], dtype='<U2'),
array(['QH', '6H'], dtype='<U2'),
array(['9C', 'TC'], dtype='<U2'),
array(['4S', '8S'], dtype='<U2'),
array(['8D', '9D'], dtype='<U2'),
array(['7C', '7C'], dtype='<U2'),
array(['9D', 'AD'], dtype='<U2'),
array(['QD', 'QD'], dtype='<U2'),
array(['AD', '8D'], dtype='<U2')]
最后,我们可以像之前一样计算概率。
emp_probability = 1 - (len(unfavorable_cases) / len(any_two_cards))
emp_probability0.749957
再次,接近实际答案。让我们尝试一个困难的方法来结束这件事。
12 面骰子(硬)
装有 12 个面的骰子有 40%的概率得到 12。剩下的 60%平均分布在骰子的其余面上。两个人各自选择两个不同的数字。数字更接近实际掷骰子的人将获胜。他们应该选择哪个数字?

截图来自 StrataScratch
你可以在这里解决这个问题:https://platform . stratascratch . com/technical/2280-dice-with-12-faces
这是一个极好的问题,可以测试你对概率的理解。这也涉及到一些博弈论。为了解决这个问题,让我们拿一个普通的骰子,有六个面,编号为 1 到 6。我们的目标是选择一个最大化我们获胜机会的号码。如果掷骰子上的数字比对手的数字更接近我们选择的数字,我们就赢了。我们还需要考虑对手的行动,因为结果也取决于她的选择。
让我们假设我们选择了数字 6。我们的对手还有五个选择(从 1 到 5)。她和我们能力相当,所以她会尽量扩大自己的机会。让我们看看是什么情况。

作者创造的形象
我们对手的最佳选择是选择 5,因为在这种情况下,她 6 次中有 5 次获胜。
让我们选择 5 个。我们对手现在的选择是(1,2,3,4,6)。让我们描绘一下场景。

作者创造的形象
与先前的情况相比,我们的机会增加了。现在我们对手的最佳选择是 4,她三次赢了两次。让我们看看如果我们选择 4 会发生什么。我们对手现在的选择是(1,2,3,5,6)。场景是。

作者创造的形象
这对我们来说更好,因为我们至少每次都有均等的机会获胜。我们对手的最佳选择现在是 3,现在是掷硬币决定谁赢。
剩下的三个选项 3、2 和 1 将是 4、5 和 6 的镜像。那么我们从中学到了什么呢?
- 随着我们向中间移动,我们的机会增加了。这是因为我们留下的数字比我们的对手少,而我们的对手有优势。当我们在角落(1 或 6)时,我们的对手有充分的选择。但当我们走向中心时,我们是在强迫她选择一边,把另一边留给我们。更多的模具辊现在对我们有利。
- 对我们的对手来说,最好的选择是选择一个与我们最接近的数字,并站在数字更大的一边。如果对手在我们的选择和她的选择之间留下了差距,那么差距中的数字我们双方都可以争夺,例如当她选择 2 而我们选择 4 时,那么 3 导致平局。更糟的是,如果她选 1 而我们选 4,当 3 出现时她就输了。
让我们看看它背后的数学原理。下表显示了我们选择的两边的概率。如上所述,我们需要优化我们选择的两个方面。

作者创造的形象
当我们只为一方优化时,我们的对手可以押注于另一方,赢得的机会更大。因此,对我们和我们的对手来说,最佳选择是 3 和 4。这大致遵循霍特林关于商店和手推车位置的定律。
既然我们知道了要计算什么,我们现在可以将它扩展到我们的装载骰子。
我们的目标是牢记对手的行动,最大化我们的机会。所以我们尽可能地覆盖两侧。

作者创造的形象
如果我们选择 9,那么我们的对手可以选择 8 赌骰子掷得更低,或者 10 赌骰子掷得更高。10 是一个更好的选择。此外,获得 9 及以下点数的机会比获得 10 及以上点数的机会小。所以这不是最优选择。如果我们选择 10,那么我们的对手能做的最好的就是 9,与之前的情况相反。
因此,10 是我们的最佳选择,9 是我们的对手的最佳选择。
让我们通过用 Python 模拟来尝试解决这个问题。
我们首先通过传递概率来模拟骰子。我们看了一百万卷这样的骰子。如下图所示,得到 12 的概率是 40%,其余的平均分配。
outcomes = np.random.choice(np.arange(1,13), size = 1000000, p =
np.array([0.6/11] * 11 + [0.4]))

作者创造的形象
现在我们把我们的选择和对手的选择公式化,并计算每组选择的结果。最后,我们发现在多少情况下我们的选择比对手的好。正如我们所看到的,当我们选择 10 时,那么在对手的 11 个选择中,我们都有更大的胜算。
choices = list(itertools.permutations(np.arange(1,13), 2))
results = []
for choice in choices:
wins = (abs(outcomes - choice[0] ) < abs(outcomes - choice[1] )).sum()
losses = (abs(outcomes - choice[0] ) > abs(outcomes - choice[1] )).sum()
ties = (abs(outcomes - choice[0] ) == abs(outcomes - choice[1] )).sum()
results.append([choice[0], choice[1], wins, losses, ties])
results_df = pd.DataFrame(results, columns = ['my_choice','opp_choice', 'wins', 'losses', 'ties'])
results_df['better_choice'] = results_df['wins'] > results_df['losses']
results_df

截图来自 StrataScratch
summ_df = results_df[['my_choice', 'wins', 'losses', 'ties',
'better_choice']].groupby(by = ['my_choice']).sum()
summ_df

截图来自 StrataScratch
您可以在此查看用于生成这些统计数据和可视化结果的整个笔记本。
查看我们的 综合统计备忘单 了解统计和概率的重要术语和等式
结论
在本文中,我们向您展示了如何使用 Python 中的库来帮助解决数据科学面试中的概率和统计问题。我们通过列出所有案例、使用概率分布函数计算精确的解析解以及模拟场景来近似求解来解决问题。
掌握这些库是获得一份涉及 Python 的数据科学工作的基本要素。通过充分的练习,您可以熟练使用这些库和许多其他库。立即加入 StrataScratch,与 20,000 多名其他有抱负的数据科学家竞争和协作,努力在全球顶级科技公司和最热门的初创公司实现他们的梦想工作。
最初发表于【https://www.stratascratch.com】。
