Python 中的移动平均线
熊猫的简单、累积和指数移动平均线
在 Unsplash 上由 Austin Distel 拍摄的照片
移动平均线通常与时间序列一起使用,以平滑随机的短期变化,并突出显示数据中的其他成分(趋势、季节或周期)。移动平均值也称为滚动平均值,通过对 k 个时间段内的时间序列数据进行平均计算得出。移动平均线在金融中广泛用于确定市场趋势,在环境工程中广泛用于评估污染物浓度等环境质量标准。
在本文中,我们简单解释一下最常见的均线类型:(1)简单均线 (SMA),(2)累积均线 (CMA),(3)指数均线 (EMA)。此外,我们展示了如何用 Python 来实现它们。为此,我们使用了来自公开数据巴塞罗那的两个数据集,包含巴塞罗那从 1786 到 2019 的降雨量和气温。
我们开始吧!💪
数据预处理
在本文中,我们将使用开放数据巴塞罗那中的两个数据集:(1) 巴塞罗那市自 1780 年以来的月平均气温;以及(2) 巴塞罗那市自 1786 年以来的月累计降雨量。你可以通过以下链接轻松下载。
[## 巴塞罗那市自 1780 年以来的月平均气温-巴塞罗那公开数据
巴塞罗那市自 1780 年以来的月平均气温。温度以摄氏度(°C)为单位。
open data-a jument . Barcelona . cat](https://opendata-ajuntament.barcelona.cat/data/en/dataset/temperatures-hist-bcn) [## 巴塞罗那市自 1786 年以来的月累积降雨量-巴塞罗那公开数据
巴塞罗那市自 1786 年以来的月累积降雨量。降水量以毫米为单位。
open data-a jument . Barcelona . cat](https://opendata-ajuntament.barcelona.cat/data/en/dataset/precipitacio-hist-bcn)
从 Open Data Barcelona 下载两个 CSV 文件后,我们可以使用 pandas.read_csv 函数将它们加载到 Pandas 数据框中,并使用 pandas 可视化前 5 行。data frame . head方法。
****
如上所示,两个数据集都包含月度数据。
数据集最常见的问题是错误的数据类型和缺失值。我们可以使用 熊猫轻松分析这两者。DataFrame.info 方法。此方法打印数据框的简明摘要,包括列名及其数据类型、非空值的数量、数据框使用的内存量。
****
如上所示,数据集不包含空值,数据类型是预期的类型,因此不需要重要的清理任务;但是,它们包含月度数据,而不是年度值。我们计算年平均气温和年累积降雨量如下。
****
如您所见,我们将 year 列设置为数据框的索引。此外,我们已经删除了月度数据,因为我们将在可视化中仅使用年度值。因此,我们有两个数据框,包含(1)巴塞罗那的年平均气温和(2)年累积降雨量。
现在,我们用线图来显示这两个时间序列。
- 巴塞罗那的年平均气温
- 巴塞罗那的年累积降雨量
正如您所观察到的,可视化中有许多波动和噪声,但是我们有一个解决方案来平滑这两个时间序列:移动平均线👐
让我们深入了解💜
简单移动平均线
简单移动平均是前 M 个数据点的未加权平均值。M(滑动窗口)的选择取决于所需的平滑量,因为增加 M 的值以精度为代价改善了平滑。
对于一系列值,我们计算时间段 t 的简单移动平均值如下:
时间段 t 的简单移动平均线
计算简单移动平均线最简单的方法是使用 熊猫。 法连载。该方法提供了数据上的滚动窗口。在生成的窗口中,我们可以使用统计函数(在这种情况下是平均值)进行计算。窗口的大小(周期数)在参数窗口中指定。
返回序列的第一行包含空值,因为滚动至少需要 n 个值(在 window 参数中指定的值)才能返回平均值。我们可以通过修改参数 min_periods 来改变这种行为,如下所示。
接下来,我们计算在 10 年和 20 年期间的简单移动平均值**(窗口大小),在所有情况下选择最小周期数 1。如下图所示,我们将移动平均值添加到现有数据帧中( df_temperature 和df _ rain)。**
将移动平均值添加到数据帧后,我们使用线图绘制结果。以下图表显示了平均气温和累积降雨量以及 10 年和20 年移动平均值**。请注意移动平均线是如何平滑数据的,让我们可以正确地看到趋势方向。**
****
正如你所观察到的,气温呈现上升趋势,自 1975 年以来尤其高。相反,自 1850 年以来,累积降雨量一直保持不变。
最后,我想指出的是,您可以将滚动方法与其他统计功能一起使用。下表显示了您可以使用滚动方法来计算滚动窗口计算的一些函数。
累积移动平均线
累积移动平均值是到当前时间 t 之前的值的未加权平均值
简单移动平均线有一个恒定尺寸 M 的滑动窗口。相反,当计算累积移动平均值时,窗口大小随着时间的推移而变大。****
我们可以使用 **熊猫来计算 Python 中的累积移动平均值。**编法。这个方法给出了聚合函数的累积值(在这个例子中是平均值)。和以前一样,我们可以用参数 min_periods 指定返回值所需的最小观察次数(默认值为 1)。
下图显示了扩展方法的工作原理。
正如您所观察到的,扩展方法包括计算中当前行之前的所有行。
现在,我们用熊猫计算累积移动平均值**,将结果添加到现有数据帧中。**
下面的图显示了气温和累积降雨量的累积移动平均值。
****
累积移动平均值在计算平均值时会考虑所有之前的值。因此,它们不是分析趋势的好选择,尤其是对于长时间序列。简单移动平均线更适合此目的。但是,所有数据点的权重相等。为了突出显示最近的观察结果,我们可以使用指数移动平均线,它将更多权重应用于最近的数据点,对变化做出更快的反应。
指数移动平均线
指数移动平均线是一种广泛使用的过滤噪音和识别趋势的方法。每个元素的权重随着时间的推移而逐渐降低,这意味着指数移动平均给予最近的数据点更大的权重。这是在最近的数据比旧数据更相关的想法下完成的。与简单移动平均线相比,指数移动平均线对变化反应更快,因为对最近的变动更敏感。
计算时间段 t 的指数移动平均线的代数公式为:
其中:
- xₜ 是在时间段 t. 的观测值
- EMAₜ 是时间段 t. 的**指数移动平均线**
- **α 是**平滑因子。平滑因子的值介于 0 和 1 之间,表示应用于最近时段的权重。
对于指数平滑,Pandas 提供了 **pandas。**series . ewm方法。我们可以在 alpha 参数中直接指定平滑因子。或者,我们可以用质心**、跨度或半衰期来表示。**
下图显示了 ewm 方法如何计算指数移动平均**。在这种情况下,我们设置参数 alpha 等于 0.1 ,参数 adjust 等于 False 。如您所见,计算中使用了时间段 t-1 的均线,这意味着在计算时间段 t 的均线时,包括了截至当前时间的所有数据点。但是,最早的数据点对计算的影响最小。**
现在,我们用平滑因子 0.1 和 0.3 计算指数移动平均线**。如前所述,我们将移动平均值添加到现有数据帧中( df_temperature 和 df _ rain)。**
下图显示了平均气温和累积降雨量以及指数移动平均值**。**
****
如上所示,小的加权因子 α 导致高度平滑,而较大的值提供对最近变化的更快响应。
下图显示了 15 个数据点的简单移动平均值和指数移动平均值的权重(alpha=0.3,adjust=False)。
正如您所观察到的,简单移动平均线对所有数据点的权重相等。
相反,指数移动平均线给予最近的数据点更大的权重。
然而,最后一个重量 w₁₄ 比 w₁₃ 高。原因是用于计算最后重量的公式不同,如下所述。
熊猫。Series.ewm 方法提供了指数权重的两种变体。如果我们设置参数 adjust=False ,我们将使用代数公式计算指数移动平均线。
对于时间步长 0、1、2 和 3,我们得到以下结果:
如上所示,这相当于使用权重:
如您所见,最后的权重 i=t 是使用不同的公式计算的,其中 (1-α)^i 没有乘以 α。
或者,如果我们设置 adjust=True (默认值),我们使用权重 wᵢ=(1-α)^i 来计算指数移动平均,如下所示:
在这种情况下,使用相同的公式计算所有权重。
最后,我想指出的是,指数移动平均线不仅用于过滤噪音和识别趋势,也是处理时间序列时的一种预测方法。用于预测的最佳平滑因子 α 是最小化 MSE (均方误差)的因子。
如您所见, Pandas 提供了多个内置方法来计算移动平均值🙌。滚动法提供了数据的滚动窗口,让我们很容易获得简单移动平均线**。我们可以使用展开法计算累积移动平均值**。扩展窗口将包括计算中当前行之前的所有行。最后,我们可以用 ewm 方法计算指数移动平均线**。要计算其他类型的移动平均线,我们可以只使用 Python 编程,或者使用第三方库,如 Alpha Vantage。**
我希望你喜欢这篇文章✋
阿曼达💜
在大都市之间移动:数据故事和分析仪表板
关于美国主要城市和大都市区之间流动的研究
我们多年来一直听说旧金山和纽约等大城市的房价过高,导致居民奔向经济发展中更实惠的地区。然而,这些新兴城市的大规模增长给现有居民带来了压力,迫使他们也搬到其他地方。这项研究利用了来自美国社区调查的最新地铁到地铁迁移流量数据,并将提供对以下问题的见解:
-大多数居民留在原地不动的大都市地区
-在同一大都市区内迁移的居民最多的大都市区
-迁入或迁出该地区的居民最多的大都市地区,以及他们来自或去往的地方
-国际居民迁入最多的大都市地区
虽然这份报告将提供一些高层次的见解,但我已经建立了一个免费的 Tableau 仪表板,使您能够查看特定的迁移指标,并按大都市地区、人口以及州内与州外迁移进行筛选。点击这里,查看免费的迁移模式仪表盘。
来自美国以外的新移民占大都市人口的比例是多少?
硅谷(圣何塞、桑尼维尔和圣克拉拉)由最高比例的国际移民组成,占所有现有居民的 2%。排在硅谷之后的是迈阿密(占总人口的 1.6%)和华盛顿州 DC (1.3%)。另一方面,扬斯敦-沃伦-博德曼都会区只有 0.1%的居民来自国外。田纳西州的查塔努加和阿拉巴马州的伯明翰紧随其后,有 0.2%的人口来自海外。除了犹他州的普罗沃和科罗拉多州的科罗拉多斯普林斯,大多数人口比例最高的城市都位于沿海各州或靠近国际边界。
这张图表显示了哪些地区的当前居民在过去一年中搬家的比例最高,但仍留在同一个大都市区内。
亚利桑那州的 Tuscon 有 15%的人住在 Tuscon。紧随 Tuscon 之后的是内华达州的拉斯维加斯(14%)和俄克拉荷马市(13%)。第四,凤凰城(13%)是排名第二的亚利桑那州大都会区。佛罗里达州的代托纳比奇是该地区内迁居比例最小的(7%),其次是德克萨斯州的麦卡伦(7.2%)和康涅狄格州的斯坦福(7.2%)。纽约市的地区内搬家率排名第五,为 7.3%。
哪些城市和大都市地区的大多数居民都呆在原地不动,选择呆在自己的家里?
纽约有 90.6%的居民留在他们的居住地。德克萨斯州的麦卡伦(90.2%)和俄亥俄州的扬斯敦(88.6%)紧随其后。另一方面,科罗拉多斯普林斯去年只有 77.7%的居民留在原地。Tuscon (79%)和 Provo (79%)的居民比例也相对较低。
现在,让我们看看一些主要城市,了解居民来自哪里,前往哪里。就像今天看到的一切一样,你可以在 Tableau Public 上查看完全免费的仪表盘。
从纽约、纽约和旧金山、洛杉矶、圣何塞等加州大都市地区迁入奥斯汀的居民基本上是迁入这些地区的前奥斯汀居民的两倍。
奥斯汀的居民正在流失到西雅图(1.5 名前奥斯汀居民迁出,1 名居民迁入)、丹佛(1.4)和亚特兰大(1.2)。
洛杉矶正在输给爱达荷州(每来一个博伊西市居民,就有 7 个前洛杉矶居民搬到博伊西市)。同样,洛杉矶的净移动电话正在流失到俄勒冈州尤金市(5.7)。就原始数据而言,洛杉矶的大量净居民正在流失到拉斯维加斯(-10,042 人)、凤凰城(-6,642 人)和达拉斯(-5,628 人)。洛杉矶市仍在从东海岸的主要城市大幅增加(来自纽约的+5,942 人,来自芝加哥的+2,157 人,来自波士顿的+821 人,来自华盛顿 DC 的+792 人)。
硅谷居民正涌向俄勒冈州波特兰市(每 1 名波特兰居民搬到圣何塞,就有 2.1 名圣何塞居民搬到波特兰)、奥斯汀(每 1 名奥斯汀居民搬到圣何塞,就有 1.95 名圣何塞居民搬到奥斯汀)和德克萨斯州达拉斯市(比例为 1.4)。硅谷仍然从中西部的大城市获得正的净迁移率,如芝加哥(每有一名圣何塞居民搬到芝加哥,就有 3 名芝加哥居民搬到圣何塞),以及东海岸,如华盛顿、DC 和纽约,在这些地方,搬到圣何塞的居民比搬到相应地区的圣何塞居民多两个以上。
如前所述,大凤凰城地区已经成为洛杉矶等大城市的前居民搬迁的目的地,但腓尼基人选择搬到哪里呢?圣安东尼奥名列榜首,从菲尼克斯到圣安东尼奥的人数是反之的两倍。犹他州的普罗沃紧随其后,每一个普罗沃到菲尼克斯的搬运工就有 1.9 个菲尼克斯到普罗沃的搬运工。排在前五位的城市还有奥斯汀(1.44)、迈阿密(1.4)和纳什维尔(1.35)。
感谢你阅读我最新的数据贴。你可能有兴趣阅读我之前关于 大都市地区各行业就业增长趋势 的帖子。作为一名产品营销和数据分析专业人士,我对数据支持的讲故事充满热情。这些数据新闻帖子是我将真实数据与我个人的不同兴趣整合起来的方式,这些兴趣包括从旅行和娱乐到经济和社会问题的任何事情。
如果您有任何评论、故事想法或预期的数据项目,请随时发送电子邮件至 dwpwriting <邮箱至> gmail < dot > com 或通过LinkedIn联系我。
图片来自Pexels.com
从 Python 迁移到 Java,将您的机器学习模型部署到生产中
当您将 Python 原型迁移到 Java 堆栈时,需要考虑的选项。
Python 是 Python 软件基金会的商标。Java 是 Oracle 和/或其附属公司的注册商标。
我们已经开发了一个系统原型,它在Informatica Mapping Designer中推荐转换。现在,我们想转向生产。原型完全是用 Python 开发的,使用了 scikit-learn 库,这是一个用于开发机器学习模型的流行库,我们也使用了其他 Python 库进行特征提取。另一方面,我们的生产栈是基于 Java 的。此外,其他限制因素有:
- 我们希望快速进入生产阶段,但我们没有时间和资源来进行重大的基础设施开发
- 系统响应时间短,用户界面响应快。
文章的其余部分描述了我们已经考虑过的选项。
我们考虑的第一个选择是通过使用 Jep 或 Jpy 将 Python 代码直接嵌入 Java。虽然 Jython 是一个流行的选项,但这对我们并不适用,因为 scikit-learn 依赖于本机 CPython 扩展,而 Jython 并不支持。此外,我们已经考虑将 Python 代码集成为 web 服务,例如使用 Flask ,但是这将需要维护两个独立的代码库,并引入额外的通信开销。
另一个选择是将模型转换成 Java 代码。模型转换文件(或 transcompile)是一个生成编程代码的过程,其行为方式与输入模型相同,通常是通过在生成的代码中捕获模型参数。我们已经考虑了 sklearn-porter 和 m2cgen ,它们支持多种分类算法,并且可以将 scikit-learn 模型转换成 Java 代码。然而,我们无法成功地移植我们的模型,这可能是因为它们的复杂性,所以我们没有进一步考虑这个选项。
我们考虑的第三个选择是用 H2O 或 Spark 的 MLib 重新开发 sckit-learn 模型,这些流行的机器学习库具有与 sckit-learn 相似的编程接口,并生成可以在 Python 和 Java 中使用的模型。由于 Spark 之前已经在 Informatica 中成功使用过,我们采取了那个方向,使用 Python 的 Spark 库 PySpark 在 Python 中训练模型,然后将它们导出到 Java 中。此外,我们用 Java 重新实现了特征提取代码,并将模型和代码一起部署,然后加载模型并使用它们来提出建议。最后,我们考虑了在嵌入式模式下使用 Spark(仅使用 JAR 依赖项)或建立 Spark 集群之间的选择。我们的测试结果表明,在嵌入式模式下,我们的模型的响应时间是可以接受的,我们将继续这样做。
下表总结了所考虑的方法:
在未来,我们计划利用 Spark 集群并扩大训练环境,以便在更大的数据集上训练模型。此外,我们正在考虑建立一个服务于机器学习模型的基础设施,这可以简化新模型的交付以及现有模型的更新。
谢谢大家!
将我们本地的 Jupyter 笔记本电脑迁移到云上的 GPU——AWS 上的深度学习
不再受本地系统资源的限制,将深度学习工作负载迁移到云 GPU
从 AWS 获取 GPU
让我们为深度学习工作负载创建一个 GPU 实例。为此,我们需要一个 AWS EC2 实例。登录 AWS web 控制台,查找 EC2 服务,点击启动实例。
寻找深度学习 AMI 的。这些是更好的,因为它们预装了 Python3、Jupyter 和许多其他库。选择可能适合您的实例类型。
安全细节
Jupyter 笔记本有两种访问方式:
- 方法 1 —隧道到 EC2 实例(推荐)
- 方法 2 —暴露 HTTP 和 TCP 端口与 Jupyter 对话
对于方法 1,我们只需要安全组中的 SSH 配置。默认情况下,它应该存在,不需要任何更改。
不太推荐方法 2,因为它将实例进一步开放给了互联网。然而,这可以通过 HTTPS 端口 443 和自定义 TCP 端口 8888 来完成。
密钥对/ pem 文件
另一个需要注意的重要步骤是访问用于创建实例的密钥对。如果您没有密钥对,可以在创建时生成一个。如果您决定创建一个密钥,AWS 将为您下载该密钥。
注意:如果有多个团队成员在这个盒子上工作,那么通过 Last pass 或其他密码共享服务来共享密钥对(pem)文件是非常重要的。不要使用电子邮件/ slack 来交换密码/密钥文件。
创建实例
以上是所有的配置,创建实例。这将需要 2-3 分钟。获取创建的机器的 IP 地址。
登录到机器
我们现在可以登录这个盒子-
# The downloaded key-pair (pem) file is more permissive.
# Fix permissions.
# chmod 400 <path to pem file> chmod 400 ~/path/to/key.pem # Get in the box
# ssh -i <path to pem file> -L <local box:port>:<remote box:port> ubuntu@<ec2 ip address> ssh -i ~/path/to/key.pem -L localhost:9999:localhost:8888 ubuntu@11.11.11.11
注意:我建议对上面的命令localhost:9999:localhost:8888
使用端口 9999,因为您本地安装的 Jupyter 可能会干扰这个设置。
让 Jupyter 开始
在远程盒(EC2 盒)的端子上启动 Jupyter。建议在屏幕会话中启动 Jupyter,这样您可以关闭终端,Jupyter 服务器仍然保持活动状态。
# Create a new screen session
screen -S jupyter_session # Start Jupyter
jupyter notebook
这应该为我们的 Jupyter 笔记本— [http://localhost:8888/?token=thisisalongsecrettoken](http://localhost:8888/?token=thisisalongsecrettoken.)
提供一个 URL 和一个密码(令牌)。
跑起来
你现在应该可以在你的本地机器上访问 Jupyter 了 http://localhost:9999
我的数据在哪里
你可以从你的终端或通过 python 从 S3(亚马逊推荐的存储)下载你的数据。我在 Google drive 上有我的数据,所以我正在使用这个很酷的实用程序库 googledrivedownloader 将我的数据放入这个盒子。您需要为这个库创建一个 sharabele 链接,链接到 G-Drive 中的数据。lib 也为我们创建子目录和解压数据。
! pip3 install "googledrivedownloader==0.4" from google_drive_downloader import GoogleDriveDownloader as gdd# file_id - id of the sharable link of the file
# from Google Drive. gdd.download_file_from_google_drive(
file_id='1jgSl1thisisafakekeyRleIGpIO3Q',
dest_path='./data/Flikr8k_text.zip',
unzip=True)
清理很重要$$$
确保在不使用时停止/终止实例。否则亚马逊得到$$$。停止实例时,数据将保留在节点存储上,不会向您收费。请阅读官方文件了解更多信息。
重要提示:您的笔记本和下载的数据将在终止实例时被删除,您必须再次完成上述所有步骤。
那是一个包裹
在未来的帖子中,我们将关注亚马逊 Sagemaker,它为数据科学笔记本提供了更加统一的体验。
这就是这篇文章的全部内容。希望对你有用。让模型运行起来。
原载于 2020 年 6 月 13 日https://confusedcoders.com。
MR-隆升:隆升模型中的多重响应
一个建立提升(或异质治疗效果)模型的包,该模型建立并评估多种反应的权衡
简介
原贴于 大楼 Ibotta
在过去几年里,我们在伊博塔建造并部署了多种提升模型。我们以前在博客中描述过一些理论基础和实践建议。在这些文章中,我们讨论了如何评估它们,如何使用特定损失函数来估计它们,以及如何评估几个响应变量之间的权衡。
有了这些来之不易的知识和评估方面的进步,我们决定开源一个 Python 包,名为MR-upgrade。
这篇文章将介绍这个包能做什么,以及它如何成为现有包的有用补充。提供了一个示例和更多资源。
套餐缴费
提升建模(也称为异质或个体治疗效果)是机器学习的一个分支,它学习治疗t
和个体x
的特定反应y
之间的因果关系。一个例子可以是接收特定广告的特定个人的未来活动。
虽然有几个软件包可以建立隆起模型(见【GRF】和因果树),但它们通常依赖于单一处理和单一响应案例。他们通常不会给出模型在生产中表现如何的估计。此外,没有支持估计几个响应变量之间的权衡。
该软件包试图构建一个用于隆起建模的自动化解决方案,该解决方案通过以下特性来满足 Ibotta 用例的需求:
- MR-Uplift 允许多种治疗。这意味着用户可以在模型中输入任意数量的治疗(不仅仅是通常的二元变量)。此外,可以为每种治疗加入元特征。例如,一种特定的治疗可能与其他治疗有几个共同的特征。用户可以创建分类或连续变量的向量来表示治疗,而不是为每个治疗创建虚拟指标。以这种方式指定治疗变量允许模型考虑治疗之间的相似性。
- 如果模型被部署到生产中,很少有当前的软件包给出关于模型的预期性能的样本外(OOS)估计。MR-Uplift 包括使用爆发度量来估计这一点的功能。此指标计算模型提供给普通用户时的预期反应。
- 支持多重响应。这可能是这个包最独特的特性(也是它现在名字的原因)。该模型有能力建立一个多输出模型,而不是只有一个响应。有了这个,人们可以估计响应变量之间的权衡。我们发现这是一个有用的工具,可以确定我们有哪些可能性,以及在生产中使用哪个目标函数。
MR-Uplift 使用具有均方误差损失的多输出神经网络。虽然可以使用任何类型的多输出模型,但是我发现神经网络可以比基于树的方法更可靠地估计治疗和解释变量的交互作用。
这项工作的一个特别的缺点是它不像因果树那样直接测量治疗效果。扩展模型以包含更具体的损失函数可能会导致性能的提高。此外,由于目前不支持从观察数据中估计治疗效果,因此假设存在针对治疗数据的随机对照试验。
快速示例
如果您不熟悉提升模型,我建议浏览回购中提供的示例。下面是一个生成数据、构建模型和评估权衡的示例。请参见本笔记本了解这个假设示例的更多细节。
假设我们是一家企业的营销人员,希望通过广告增加用户收入(称为治疗)。该数据由随机分配的治疗变量组成,每个用户有四个响应变量:收入、成本、利润和随机噪声变量。这种处理增加了用户收入,但也付出了代价,两者都是解释变量的函数。我们感兴趣的是估计企业可用的响应变量的权衡。下面是生成数据和构建模型的代码。
y
、x
和t
分别是反应、解释和处理变量。注意,每个都被假定为数字类型(分类变量需要一键编码),但是可以是多列宽。
import numpy as np
import pandas as pdfrom dataset.data_simulation import get_simple_uplift_data
from mr_uplift.mr_uplift import MRUplift#Generate Data
y, x, t = get_simple_uplift_data(10000)
y = pd.DataFrame(y)
y.columns = ['revenue','cost', 'noise']
y['profit'] = y['revenue'] - y['cost']#Build / Gridsearch model
uplift_model = MRUplift()
param_grid = dict(num_nodes=[8],
dropout=[.1, .5],
activation=['relu'],
num_layers=[1, 2],
epochs=[25],
batch_size=[30])uplift_model.fit(x, y, t.reshape(-1,1), param_grid = param_grid, n_jobs = 1)
这将自动应用训练/测试分割,对所有变量应用 z 标度,并构建一个形式为y~f(t,x)
的多输出神经网络。
为了查看模型如何执行以及业务可用的权衡,建模者可以应用get_erupt_curves()
函数来获得样本外爆发曲线。这些方法通过将各种权重应用于每个预测响应并计算相应的预期响应来估计权衡。
例如,假设我们有一个权重β
和目标函数β*revenue-(1-β)*costs
。权重β=1
对应于收入最大化,β=0
对应于成本最小化,β=.5
对应于利润最大化。下面显示了在β
的各种权重下,预期响应的代码和标绘输出。
erupt_curves, dists = uplift_model.get_erupt_curves()
以上是在成本最小化和收益最大化之间改变目标函数的爆发曲线。随着重量β
的增加,成本和收入也会增加。
请注意,噪声响应大约保持在零附近,这是有意义的,因为处理对其没有影响。另请注意,利润响应如预期的那样在β=.5
出现最大值。
还有一个“随机”分配曲线。这“打乱”了最佳治疗,然后计算出爆发。比较“模型”线和“随机”线可以看出模型在个体水平上分配治疗的效果。
在实践中,我发现这些图表有助于决定应该如何权衡。涉众可能不知道在更模糊的响应度量之间应该预先进行什么样的相对权衡。这些图表向利益相关者显示了可用的选项,并设置了模型在生产中能够实现和不能实现的预期。
入门
要开始使用 MR-Uplift,请查看 github 回购和示例或pip install mr_uplift
。如果您发现任何问题,请提交。更好的是,如果你有希望实现的想法,你可以贡献。
探索性数据分析 Data 十字转门街道交通分析
Metis 数据科学训练营的一个简单的探索性数据分析项目。
保罗·席尔瓦在 Unsplash 上的照片
在 Metis 数据科学训练营的项目 1(新加坡第 5 批)中,我们的任务是对 MTA 十字转门数据进行探索性数据分析(EDA ),为一个虚构的非营利组织 WomenTechWomenYes (WTWY)提供关于社交活动街道团队(在纽约市地铁站入口处)最佳位置的建议。WTWY 希望邀请感兴趣的个人参加其年度晚会,以提高女性对科技的认识和参与度,街头团队的议程是收集尽可能多的电子邮件,并发放晚会的免费门票。在我的分析中,我做了以下假设:
假设
- WTWY 受到时间和人力资源的限制,因此从我的分析中得到的见解应该通过流量来识别顶级站点,以及这些站点中的高峰时段。
- 对科技感兴趣的人更有可能在科技公司办公室密集的市中心遇到。
- WTWY 联欢晚会即将来临,一周的 MTA 十字转门数据被分析作为联欢晚会前几周的样本。
数据探索和清理
MTA 十字转门数据是从 2020 年 8 月 22 日到 2020 年 8 月 28 日这一周收集的。取数据的前几行,我们观察到以下数据框:
为了找到进出每个十字转门的人数,我首先根据以下顺序对数据框中的列进行排序:[‘UNIT ‘,’ SCP ‘,’ DATE ‘,’ TIME’],然后使用 diff()方法对序列进行排序,我分别对’ ENTRIES ‘和’ EXITS '取连续行之间的差值,以形成新列。新的列(命名为“入口 _ 增量”和“出口 _ 增量”)将表示在特定的 4 小时期间通过每个十字转门的入口和出口的实际数量。尽管如此,有些进/出的值要么是负数,要么是天文数字。
进一步的分析表明,这是由于数据帧中 2 个不同十字转门之间的行转换,或者特定十字转门中序列号计数器的重置。为了进行校正,这些异常值随后被替换为进/出的前一个和后一个值的平均值。这种干预是合理的,因为进入/退出可以近似为连续时间段之间的插值。
此后,通过将入口和出口值相加来计算每个时间段内每个十字转门的总交通量。我把这个专栏命名为‘ENTRY _ EXIT’。
结果
现在,我们已经为数据可视化做好了准备,以便为 WTWY 的街道团队的潜在布局获得洞察力!使用 Panda 的 groupby、Matplotlib 和 Seaborn,我接着绘制了一个直方图、条形图和一些热图。
绘制直方图显示纽约市所有 MTA 站的流量分布严重右偏,流量排名前 10 位的站是分布中的异常值。因此,这更清楚地表明 WTWY 可以将他们的参与努力集中在前 10 个电台。
放大,绘制前 10 个车站的条形图显示,34 St-Penn 和 34 St-Herald Square 车站的流量明显高于其他车站,应该优先考虑。
添加一天的维度,绘制一周内前 10 个车站的热图,揭示了与周末相比,人们在工作日更频繁地乘坐地铁旅行的趋势。这一趋势适用于所有 10 个站。
进一步将热图分解为每个站点的白天和时间,揭示了另一个有趣的事实——站点通常在下午晚些时候和晚上更忙,即使在工作日也是如此。这并不奇怪,因为在 Covid 疫情期间,纽约市的许多公司都采用了在家工作的安排,从而避免了早高峰人群。此外,在工作日上午雇用街道小组可能会适得其反,因为其余的重要工作人员将忙于报道工作,不太可能成功接触到他们。
使用另一幅热图,当我们分析每个车站中通勤者的净出入(红色区域表示净出入,蓝色区域表示净出入)时,我们可以确定位于更密集的住宅/酒店区域的车站-Flushing-Main 和 42 St-Port Auth 车站。这一点从他们在晚上的净出口可以看出,这意味着人们正在返回家园。由于这些车站不靠近公司办公室,对技术感兴趣的个人不太可能出现在这些通勤者中。
结论
从我们的分析中,我们可以得出结论,WTWY 应该将他们的街头参与工作集中在排名前 10 位的电视台,最好是在工作日的下午晚些时候到晚上。此外,如果有进一步的人力限制,可以避免 Flushing-Main 和 42 St-Port Auth 站,因为它们是潜在的住宅和旅游区,技术公司办公室不在那里。
最后,我希望我对 MTA 十字转门数据的探索性数据分析产生了有趣的见解,并期待展示 Metis 数据科学训练营即将开展的其他数据项目。敬请期待!
在 GitHub 的这里找到我所有的代码和这个项目的演示幻灯片!
支持我!——如果你是而不是订阅 Medium,并且喜欢我的内容,请考虑通过我的推荐链接加入 Medium 来支持我。
阅读谭·师鹏·阿尔文(以及媒体上成千上万其他作家)的每一个故事。您的会员费直接…
tanpengshi.medium.com](https://tanpengshi.medium.com/membership)
MTA 十字转门数据:探索性数据分析
埃迪·阿吉雷在 Unsplash 上拍摄的照片
Metis 数据科学训练营(新加坡第四批)的第一周刚刚结束,到目前为止,这是一次有趣的经历。下面我将详细介绍我们在那段时间做的第一个项目,这是一个探索性的数据分析,使用 Python 与熊猫和海牛配对来分析 MTA 十字转门数据集。
TL;博士:
- 准备了 2019 年2 月和 3 月的 MTA 十字转门数据,用于一个为夏季晚会报名的活动。
- 通过重命名列、添加计算字段、删除错误数据和按站点和日期聚集来清除数据。
- 发现工作日有最高的流量,但这是一些车站的情况较少;某些日子也有异常交通流量。
- 建议活动集中在工作日客流量高而周末客流量低的车站
- 异常、一天中的时间和应考虑人口统计数据的其他来源,以便进一步分析
这里是到 GitHub 库的链接。
一.背景
女性科技女性是(WTWY)每年初夏都会在纽约市举办一年一度的盛会。他们试图在这个盛会上发挥双重作用,一方面让那些热衷于增加女性在科技领域参与度的人来充实他们的活动空间,另一方面也提高人们的认识和影响力。
为此,他们在纽约地铁站的入口处安排了街头小组。街头团队收集电子邮件地址,注册的人会收到免费的晚会门票。
我们的任务是使用纽约市大都会运输管理局(MTA)的地铁数据来帮助 WTWY 优化他们街道团队的位置,以便他们可以收集最多的签名,最理想的是从那些将参加晚会并为他们的事业做出贡献的人那里收集签名。
二。设置
我们使用了来自 MTA 十字转门的历史数据,决定专注于 2019 年 2 月和 3 月的数据。
- 二月(T0)、二月(T1)和三月(T2)、三月(T3)这两个月似乎是夏季来临前的充足准备时间,让人们能够将春晚安排到他们的日程表中。
- 在 2020 年的这个时候,新冠肺炎疫情正在肆虐,纽约市是世界上最大的热点之一。结果,它被封锁了,这严重扰乱了交通模式,T4 的街道空无一人。这是非常不寻常的情况。如果这是一项真实的研究,我给组织者的建议是完全避免安排街头团队,要么推迟/取消晚会,要么完全转移到网上。出于这个练习的目的,我们假设春晚将发生在 2019 年的夏天。
具体来说,我们从 2019 年 2 月 2 日结束的一周到 2019 年 3 月 5 日结束的一周的十周时间内获取数据,如以下代码片段所示:
我们还决定专注于收集每个站点每天的总流量,忽略条目的时间。可以想象,在数据分析的后续迭代中会添加时间。
三。准备数据
a)列重命名
检查MTA _ test . columns . values,我们注意到数据集的 EXITS 列有一大堆尾随空格:
array(['C/A', 'UNIT', 'SCP', 'STATION', 'LINENAME', 'DIVISION', 'DATE', 'TIME', 'DESC', 'ENTRIES',
'EXITS '],
dtype=object)
所以为了让我们的生活更轻松,我们把它重新命名为:
mta_test.rename(columns={'EXITS ':'EXITS'}, inplace=True)
b)添加计算字段
基于来自 MTA 的字段描述,我们知道入口和出口分别是给定入口和出口点的累积入口和出口寄存器值。因为我们是按天而不是按时间段聚合,所以我们决定分别减去入口和出口的第一个(也就是最小的)和最后一个(也就是最大的)计数器值。
我们还将入口和出口聚合到一个单独的列中,即 TRAFFIC,以及附加的工作日属性,以便于以后按工作日分析数据。我们的结果被放入 mta_entries_exits 中。
这一切的代码片段如下:
c)删除错误数据
当我们按流量对 mta_entries_exits 排序时,我们发现奇怪的大值似乎会打乱数据集:
对数据的进一步分析显示,在 MTA 数据的某些行中,计数器值以无法解释的数量跳跃(如下例所示):
查看入口和出口的分布可以发现,这些值中的大多数都在 20,000 以下:
条目数量的分布
出口数量分布
因此,我们删除了所有大于 20,000 的入口和出口值:
mta_entries_exits = mta_entries_exits[(mta_entries_exits.ENTRIES < 20000) & (mta_entries_exits.ENTRIES < 20000)]
**请注意,这将删除特定十字转门一整天的数据。**出于初步分析的目的,我们认为这是可以接受的,因为车站的每个入口点都有许多十字转门,通常不止一个入口点;然而,进一步的分析需要数据移除更有针对性。
d)按站点和日期汇总数据
最后,我们按车站和日期汇总了数据,因为我们不是在看单个的十字转门。
mta_bystation = mta_entries_exits.groupby(['STATION','DATE','WEEKDAY', 'WEEKDAY_INDEX']).sum().reset_index()
四。来自数据的见解
a)关注排名前五的电视台
我们发现总流量排名前 5 的站点如下:
- 宾州车站
- 大中央车站
- 先驱广场
- 第 23 街
- 时代广场
我们的建议是将重点放在这 5 个车站。
b)关注工作日
我们发现周末的交通流量比平日少(最多是平时的一半)。总的来说是这样的:
排名前五的电视台也是如此:
我们的建议是在工作日关注**。**
异常情况
我们注意到并非所有的站点都遵循相同的模式。例如,第 3 至第 5 级车站的工作日交通量更接近周末交通量:
顶部 2 站已移除。注意这些车站的工作日和周末交通有多接近。
这可能是因为这些车站位于旅游区,时代广场就是一个突出的例子。退一步说,这样的短期游客不太可能参加夏季晚会。我们的建议是关注工作日客流量高而周末客流量低的车站。
我们还发现,在排名前五的站点中,至少有一个站点的流量出现了无法解释的下降:
请注意 2019 年 2 月 18 日至 25 日这一周中间的流量下降。
这种下降(或峰值)需要隔离和调查,因为它们可能是由于特殊情况,如公共假期或紧急情况。这也可能是由于之前的数据清理丢失了数据。
动词 (verb 的缩写)进一步的步骤
为了获得进一步的见解,我们可以做以下事情:
- 包括时间栏,以便: a)确定高峰时间,以便 WTWY 知道何时是安排其团队的最佳时间;和 b)通过丢弃特定时间的坏数据而不是一整天的坏数据来减少数据丢失。
- 纳入人口和地理数据以确定通勤者的构成、任何地理相关性等。
不及物动词外卖食品
探索性数据分析的这一练习教会了我们以下内容:
- 检查列名值的重要性;我们花了一段时间才意识到为什么从数据集中提取出口值有困难。
- 使用分布图和过滤器剔除数据中异常值的重要性。
你还有很多要学的
来源:维基百科
我从数据科学优秀竞争的前 5%参与者身上学到的三个教训。
本周末是 2015 年尼泊尔大地震五周年纪念日,那次地震造成约 9000 人死亡。死亡人数如此之高的部分原因是,该国近 2/3 的人住在用泥土、石头、砂浆或木材建造的房子里,而不是钢筋混凝土——这在大多数发达国家是常态。
资料来源:驱动数据,尼泊尔统计局,加德满都生活实验室
这些数字来自尼泊尔统计局和加德满都生活实验室汇编的近 30 万个家庭的数据集,显然是有史以来收集的最大的灾后数据集之一。驱动数据公司(https://www.drivendata.org/)是一家组织类似 Kaggle 的比赛的公司,致力于利用数据科学产生社会影响,该公司已经将数据集作为比赛的一部分。该任务是一个多类分类问题(评估指标= F1 分),根据几个特征(位置、结构、使用等)预测房屋的脆弱性(每栋房屋,1-3 级,3 级为完全破坏)。)
我决定在比赛中试试我的数据科学知识(到目前为止),因为地震发生时我在国外,远离遭受事故的朋友和家人,所以这样做是为了减少对当时未能提供帮助的愧疚感(如果这还不够清楚的话,我是尼泊尔人)。
这篇文章是我学到的三个关键数据科学相关课程的大杂烩,因为我最终成为了比赛中(到目前为止)前 5%的参与者。我只关注了建模部分,并使用了相当多的技术术语,假设如果你正在阅读这篇文章,你对这个行业很熟悉,知道探索性数据分析的重要性,或者例如什么是 f1 分数。
第一课:建立基线
当你开始做模特的时候,你做的第一件事是什么?如果你像我一样,你已经花了很多时间探索数据,创建或选择你认为重要的特征,所以你在你的模型中使用这些特征。这就是我在学校学到的,所以这就是我在比赛中所做的。
问题是,当我使用我创建的功能时,我使用 LightGBM 模型得到了 0.6832 的 F1 分数,这比 Driven Data 的基准 0.58(使用随机森林)要好,但远远低于竞争对手 0.7558 的分数。我知道我甚至不是一个优秀的数据科学家,但我甚至不在排名的前一半!
在尝试了一堆不同的特征选择方法(PCA,Chi2)之后,由于纯粹的挫败感,我干脆扔进了整个数据集(没有任何特征工程或选择)。令我惊讶的是,我的测试分数是 0.7452,使我进入了分数的前四分之一。
因此,我学到的第一课是无意中意识到,如果我简单地通过使用提供的数据集建立了一个基线模型,我将为自己节省许多无济于事的切片和切块的精神折磨。
第二课:承认你的领域知识有限
未篡改数据集给出的分数让我思考为什么我的特征创建和选择不起作用。我的特征不仅是不相关的,因为 LGBM 自己做特征选择,我主动加入了偏见。简单地说,我的特征积极地使分数变得更糟。
这让我开始思考为什么我投入到这些功能中的所有工作都没有带来任何结果。我了解地震吗?不。我了解建筑吗?不。那是什么让我觉得我可以创造特色呢?我被一个有锤子问题的人折磨着…
…让我解释一下。如果我给你一个包含建筑物高度和面积的数据集(大多数情况下是一个矩形),你能创建什么特征?如果你像我一样天真,你会计算体积,因为 a)你知道它在数学上是合理的,所以你对自己说“我在组合特征,所以它一定有一些相关性”和 b)使用你所知道的感觉很好。
自然地,仅仅因为你知道某件事在数学上是正确的,它并不像变魔术般地与问题相关。数学是世界背后的基础,但控制形状的数学不一定是控制形状如何随着构造板块的运动而变化的数学(另一种数学现象)。
我学到的第二个教训是,在进入任何数据科学项目之前,一个人应该诚实地面对自己对问题领域了解多少。如果时间不是一个因素,那么我们都应该在着手解决问题之前努力去了解这个领域,如果是,在工作中不要试图把我们以前的(可能有偏见的)知识强加给这个问题,要知道结果不会像了解问题领域的人的结果那样准确。
第三课:考虑挤出最后一滴准确性的后果
作为数据科学家,或者更一般地说,作为人类,我们受到必须解决某些问题的时间的限制。您可能正在构建一个推荐引擎,就像您还必须准备一个客户流失模型一样。你如何决定什么样的准确度或 roc 或其他指标对你的客户流失模型来说足够好,这样你就可以转向你的推荐引擎了?
对于 Kaggle 或 Driven Data 这样的竞争,原则上,答案很简单——排名最好的那个。为了便于讨论,让我们认为那是真的。在比赛中给我最高分的过程是这样的:
- 将 3 类预测问题分成 3 个二元问题,例如,如果目标标签是 3(最高伤害),则为 1,如果不是,则为 0。
- 将每个二进制数据集划分为给定的 30 个地理区域,知道一些区域(靠近震中)在地震中总是遭受更多的破坏。因此,如果我想预测地理位置 17 中房屋 x 的潜在损害,我需要一个专门针对该地区的模型。
- 因为每个地理模型被分成 3 类,所以我有 3 * 30 = 90 个不同的模型。对于这 90 个模型中的每一个,都优化了超参数。
- 对于最终预测,我根据预测最大概率的模型选择了类。因此,对于房屋 x,如果类别 1 的模型预测相应的概率为 0%,而模型 2 预测为 30%,模型 3 预测为 70%,则选择的类别为 3。
做了这么多工作,我最终站在了这里:
来源:驱动数据个人主页
我设法以低于领先者 0.0087 的分数进入竞争对手的前 5%。将 0.0087 视为我的模型相对于 leader 模型的预期误差。由于测试集中有 86,868 个家庭,这意味着我的模型平均不到 1%的时间会出现分类错误(与领先模型相比)。
所以,我问你,这是一个好成绩吗?你可能会说是的,但我不敢苟同,原因如下:根据数据集,由于一个中等家庭至少有一个家庭住在里面,我的模型基本上会使 756 个家庭的生活面临风险!现在可以接受了吗?一百万年后也不会。
我的观点是,在这种情况下,0.0087 的分数差异会危及 756 个家庭的生命,在这种情况下,最后一点准确性非常重要。现在考虑一下,如果问题不是预测房屋,而是预测货币收益。当做出价值 86,868 美元的预测时,平均损失 756 美元可以接受吗?我会这么说。
我学到的最后一课是永远考虑追求最后一点准确性的后果。更好的是,考虑后果而不是绝对分数来定义你的模型是否好。
如果你有类似的经验想要分享,请在评论中留下。
对于感兴趣的人,这里有关于驱动数据的比赛链接:
https://www . Driven Data . org/competitions/57/Nepal-seismic/page/134/
多智能体强化学习与人工智能的未来
苹果 | 谷歌 | SPOTIFY | 其他
雅各布·福斯特在 TDS 播客
本杰明·戴维斯的背景图片
编者按:迈向数据科学播客的“攀登数据科学阶梯”系列由 Jeremie Harris 主持。Jeremie 帮助运营一家名为sharpes minds的数据科学导师初创公司。可以听下面的播客:
强化学习最近受到了很多关注,这在很大程度上要归功于 AlphaGo 和 AlphaZero 等系统,这些系统以引人注目的方式凸显了它的巨大潜力。虽然我们开发的 RL 系统已经完成了一些令人印象深刻的壮举,但它们是以一种相当幼稚的方式完成的。具体来说,他们还没有倾向于面对多主体问题,这需要合作和竞争。但是,即使解决了多智能体问题,它们也是使用智能体来解决的,这些智能体只是假设其他智能体是环境中不可控制的一部分,而不是具有丰富内部结构的实体,可以进行推理和交流。
这一切终于改变了,多智能体 RL 领域的新研究,部分由 OpenAI、牛津大学和谷歌校友以及现任公平研究科学家 Jakob Foerster 领导。Jakob 的研究特别旨在了解强化学习代理如何学习更好地合作,并在包括其他代理的复杂环境中导航,他们试图模拟其他代理的行为。实质上,Jakob 正致力于给 RL 代理一个思维理论。
我们的谈话涵盖了一些基础和哲学话题,但这里有一些我最喜欢的话题:
- 当我问 Jakob 他对“学习”的基本定义是什么时,他回答说是样本复杂性——训练一个机器学习模型所需的样本数量。他认为,学习的真正目标是“学会如何学习”——找到最快降低样本复杂性的算法和策略。从这个意义上来说,进化出人类的进化过程是一个比人类用来理解世界和进行预测的认知过程更糟糕的“学习者”:尽管一个物种的基因组需要数百万人的死亡才能“学习”一些东西,但人脑只需要极少量的数据点(有时甚至一点也不需要)就能做到。
- Jakob 认为,RL 代理可以从明确识别其他代理中受益,这些代理不是他们无法控制的环境的一部分,而是代理——完全具有自己的思维过程。在所有代理都相同的情况下,任何给定的代理都可以构建其伙伴代理的相当准确的模型,该模型可以作为代理组之间有效协作和协调的基础。
- 当以这种方式建模代理时,出现的一个挑战是通信。为了让代理进行交流,他们必须开发一种共同的语言,但这并不像看起来那么容易:一个代理可能会开发一种表达自己的方法,但如果另一个代理碰巧没有开发出完全相同的方法,那么交流将是徒劳的。因此,Jakob 认为,一个重要的制约因素是代理人需要一起学习语言——这样,如果他们决定尝试改善他们的沟通方法,他们就可以一起保持他们相互理解的能力。
- 当我问雅各布,他是否认为我们已经拥有的概念工具——如深度学习和强化学习——足以建立一个完全通用的人工智能时,他说不。事实上,他是我遇到的最悲观的客人之一:在他看来,这种发展可能需要一个世纪。
纳什均衡介绍:朋友还是敌人 Q 学习
让机器人打破平衡
在 Unsplash 上由 Toa Heftiba 拍摄的照片
不管出于什么原因,人类天生拥有合作的能力。它变得如此平常,以至于它的细微差别就在我们眼皮底下溜走了。我们如何知道在移动一个沉重的沙发时如何协调?我们如何推理在杂货店分头行动以尽量减少时间?我们如何能够观察他人的行动并且理解如何最好地回应?
这里有一个解释:我们达到了平衡。一个均衡。每个人采取的行动不仅能最好地补充他人的行动,而且能最有效地完成手头的任务。这种均衡的应用在博弈论中经常出现,并扩展到多代理 RL (MARL)。在本文中,我们探索了两种算法,Nash Q-Learning 和 Friend or Foe Q-Learning,这两种算法都试图找到满足这种“平衡”思想的多主体策略。我们假设单代理公式和 Q 学习的基本知识。要了解更多关于 MARL 的背景知识和与之相关的基本原则,请查看我以前的文章:
好像一个机器人学习一切还不够
medium.com](https://medium.com/swlh/the-gist-multi-agent-reinforcement-learning-767b367b395f)
埃里克·麦克林在 Unsplash 上拍摄的照片
什么使得一个最优的政策…最优?
多主体学习环境通常用随机博弈来表示。每个代理人的目标是找到一个政策,最大化他们自己的预期折扣奖励。总的目标是找到一个联合的政策,为每个代理聚集最多的报酬。这种联合奖励以价值函数的形式定义如下:
这个目标适用于竞争和协作两种情况。代理可以找到最好的反或补充其他策略。我们称这个最优策略为**纳什均衡。**更正式地说,它是一种具有以下属性的策略:
起初,我们似乎是在白费力气。最好的政策聚集了最多的回报,那又怎样?
在所有花哨的希腊字母和符号之下,纳什均衡告诉我们更多。它认为纳什均衡中每个代理人的策略是对其他代理人最优策略的最佳回应。没有代理人会因为任何调整带来的回报减少而改变他们的政策。换句话说,所有的代理都处于静止状态。内陆。在某种意义上被困住了。
举个例子,想象两个小机器人:C3PO 和 Wall-E 进行一场竞技游戏,在每一轮中,他们各自选择一个一到十的数字,谁选择的数字高谁就赢。不出所料,两个机器人每次都选择数字 10,因为两个机器人都不想冒输的风险。如果 C3PO 选择任何其他数字,他可能会输给 Wall-E 的最优策略,即总是选择 10,反之亦然。换句话说,两者处于均衡状态。
纳什 Q 学习
因此,我们定义了一个术语叫做纳什 Q 值:
与它的单代理对应物非常相似,纳什 Q 值表示当选择特定的联合行动后,所有代理遵循联合纳什均衡政策时,代理的预期未来累积报酬。这可以被视为一个国家行动对的“最佳情况”的奖励收益。这个定义有助于 Q 学习的多代理版本:Nash Q 学习。
乔恩·弗洛布兰特在 Unsplash 上的照片
在单代理 Q 学习中,我们使用时间差(TD)更新 Q 值,公式如下:
其中,gamma 表示折扣系数,alpha 表示学习率。下面是有点无聊的部分:Nash Q-learning 简化为 Q-learning。更明确地说,纳什 Q 学习的更新方程是:
我们通过在行动空间内最大化来计算纳什 Q 值。交换几个术语,你会得到一个几乎相同的更新方程,唯一的区别是一个联合行动空间。那么,这一切的目的是什么?
照片由 Riho Kroll 在 Unsplash 上拍摄
要点是:我们不能总是假设单代理逻辑适用于多代理设置。换句话说,适用于 MDPs(单代理 RL)的算法并不总是适用于随机博弈(多代理 RL)。纳什 Q-Learning 恰好是一个有点特殊的案例。胡和 Wellman [1]在论文中证明了纳什 Q 学习总是收敛的。它的更新方程看起来与 Q-learning 相同的事实是直观的,但并不总是可以预先假定的。
整个纳什 Q 学习算法类似于单代理 Q 学习,如下所示:
朋友或敌人 Q-学习
q 值有一个自然的解释。他们代表了一个国家行动对的预期累积贴现回报,但这如何激励我们的更新方程?我们再来看一下。
这是一个加权和,其中 alpha 是学习率,是区间(0,1)中的一个值。第一项是前一时间步的 Q 值乘以某个分数。让我们剖析一下第二项,我们的学习率乘以其他两项之和。
第二项的第一部分是我们在执行一个行动后得到的奖励,而另一部分是下一个状态行动的贴现纳什 Q 值最大化。记住,这个纳什 Q 值等于给定状态后的预期、最佳情况、累积回报。把这两部分放在一起,我们有一个预期回报总和,其中我们假设在下一个状态**的最佳情况。**这是对当前 Q 值的另一种定义,只是一个更新的版本!更正式地说,这个总和代表实际 Q 值的更接近的估计值。缩小并查看整个更新方程,我们可以将其解释为“推动”当前 Q 值更接近这个更好的估计值。
在《非友即敌 Q-Learning 》( FFQ)中,Littman [2]使用这种解释为多智能体系统创建了一种直观的算法。与纳什 Q 学习相反,FFQ 首先让每个代理保持他们自己的 Q 函数。我们假设代理知道其他人的行动空间,但不知道其他人在任何给定时刻会选择什么行动。
此外,Littman 将系统概括为合作者和对手的组合,因此命名为朋友或敌人。我们再以 C3PO(特工 1)和 Wall-E(特工 2)为例,站在 C3PO 的角度看待事情。如果两者一起工作,C3PO 的 Nash-Q 值将替换为:
正如预期的那样,两个代理都试图最大化他们的“奖励流”,类似于之前的 Q 更新功能。然而,如果两个机器人相互竞争,C3PO 的 Nash-Q 将被替换为:
请注意,在最大化 C3PO 的动作之前,我们如何首先最小化 over Wall-E 的动作。换句话说,当 Wall-E 试图最小化 C3PO 的回报流时,C3PO 学习如何对 Wall-E 的反作用作出最佳反应,相应地更新他的 Q 值。这是一个纳什均衡显示其色彩的例子:代理人学习最佳的方式来互补。
更一般地,这可以适用于更大的代理系统。纳什-Q 值变成如下:
其中 X 代表所有合作者的集合,而 Y 代表所有对手的集合。与 Nash Q-learning 类似,Littman[2]表明朋友或敌人 Q-learning 也会收敛。通过适当替换这些纳什 Q 值,一个分布式代理系统可以学习一个达到均衡的策略,如果存在的话。
第一步
一些人认为这些算法是进入多智能体学习场景的“第一步”。虽然这些想法相对简单,但结果却是强有力的。下一次,我们将研究更新颖的现代方法来解决复杂的多代理环境!要更深入地了解纳什 Q 学习和朋友或敌人 Q 学习,请随意看看下面列出的两篇论文。
参考
[1]胡军,M. Wellman,一般和随机博弈的 Nash Q-学习 (2003),机器学习研究杂志 4
[2] M. Littman,普通和博弈中的敌友 Q 学习 (2001),ICML
从经典到最新,这里有讨论多代理和单代理强化学习的相关文章:
因为 1+1=3
towardsdatascience.com](/stigmergic-reinforcement-learning-why-it-tells-us-1-1-3-4d50dfa9cb19) [## 分层强化学习:封建网络
让电脑看到更大的画面
towardsdatascience.com](/hierarchical-reinforcement-learning-feudal-networks-44e2657526d7)
多种武器的强盗:第一部分
入门,一个婴儿机器人的强化学习指南
数学框架和术语
概述
当面对各种选项的选择时,每个选项给你不同程度的回报,你如何找到哪个是最好的?
这类问题通常被称为多臂强盗。在这一系列文章中,我们将看看用于解决这一难题的理论和算法。
多臂土匪问题是全面强化学习道路上的第一步。
这是一个六集系列的第一集,讲述了多种武装的强盗。要涵盖的内容相当多,因此需要将所有内容分成六个部分。即便如此,我们真的只打算看看多臂强盗的主要算法和理论。刚好够充当强化学习的垫脚石。
在第 1 部分中,我们将涵盖 Bandit 问题的所有细节,定义将在后续部分中使用的术语和基本方程。这大部分也直接适用于一般的强化学习。然而,如果你已经熟悉了基础知识,那么你可能会想要跳到真正涉及到 Bandit 算法的部分。
索引
本系列中关于多武装匪徒的全套文章如下:
- 第一部分:数学框架和术语——入门所需的全部基础信息
- 第二部分:土匪框架
- 代码和测试框架的描述 - 第三部分:土匪算法
- 贪婪算法 -乐观-贪婪算法 -ε-贪婪算法 -后悔 - 第四部分:置信上限(UCB) Bandit 算法
- 第五部分:汤普森采样-伯努利汤普森采样
-高斯汤普森采样 - 第六部分:土匪算法比较
bandit 算法和测试框架的所有代码都可以在 github 上找到: Multi_Armed_Bandits
从前有一个婴儿机器人。一天,他和妈妈出去购物,一只机器狗跑了过去。机器人宝宝的妈妈正忙着买新的火花塞,所以没注意到他什么时候转身开始跟着狗。
他追着狗穿过拥挤的购物中心,穿过几条过道,下了自动扶梯,上了自动扶梯,最后,狗躲进了墙上的服务舱口,不见了。不仅服务舱太小,机器人宝宝进不去,而且他还意识到自己迷路了。完全迷失了。
电源插座问题
更糟糕的是,机器人宝宝意识到自己快没电了。如果他想再找到他的妈妈,他需要充电。而且要快。
幸运的是,正对面有一个充电站。他走过去,发现房间里有 5 个独立的电源插座。
他走到第一个电源插座前,插上电源。令人失望的是,他只收到了一股能让他运行 2 秒钟的能量。按照这种速度,他将永远无法完全充电。也许其他电源点会更好?
考虑到这一点,他移动到下一个插座,在那里他获得了 3 秒钟的充电时间。这个插座似乎并不比第一个好多少,所以他转而尝试第三个插座。这一次他获得了 6 秒的价值。这似乎是给他充电最多的电源插座,尽管完全充电仍需要很长时间,但似乎比他试过的其他插座要好。所以,决定留在这个电源点,他再次插入。这一次,他收到了少得可怜的 2 秒钟的费用。
他必须找到一种更好的方法来发现哪个是最好的,并让他以最快的速度达到最大电量,而不是沿着插座随意移动。
多兵种土匪问题
这个电源插座问题类似于标准的、多臂的、土匪问题,用来说明如何孤立地检查探索。
在多臂强盗游戏中,你试图通过玩一组单臂强盗(也称为吃角子老虎机或水果机)赢得尽可能多的钱,每个强盗都可以给出不同的支付。你需要找到哪台机器支付的金额最大,这样你就可以在分配的时间内赚尽可能多的钱。
机器的每一次游戏(或强盗手臂的拉动)对应一个时间段,你只能玩固定数量的时间段。
探索与开发的困境
婴儿机器人面临着不知道哪个电源插座给他充电最多的问题。因此他需要 探索 可能的选择,以寻找最好的一个。
然而,因为他时间紧迫,他不能花太多时间来决定哪一个是最好的,也不能测试每个电源插座来准确知道它平均会给多少电荷。他需要 利用 他获得的知识,这样他就不会浪费时间去尝试不好的电源插座,让他在最短的时间内获得最大的电量。
这是一个经典的探索-开发困境的例子,在这种情况下,你想探索可能的选项以寻找最佳选项,同时又想利用已经获得的信息,以便获得最大可能的总体回报。
数学框架和术语
为了帮助机器人宝宝充电,并让他回来找妈妈,我们首先需要熟悉一些强化学习中使用的常用术语和数学符号。
使用的符号很大程度上遵循萨顿和巴尔托的,来自他们的强化学习圣经,“ 强化学习:介绍 ”。
动作
在强化学习中,在可用选项之间做出选择,并选择该选项,被称为采取 动作 。例如,在电源插座问题中,一个操作是选择一个可用的电源插座。在多臂强盗问题中,它是选择和玩一套吃角子老虎机。
在简单的电源插座和 bandit 问题中,在离散的时间步骤中采取行动。换句话说,一个动作接一个动作,在这些问题中,有固定数量的总动作。
- 在时间步’ t ‘采取的行动表示为’ Aₜ
奖励
每采取一个动作就获得一个 奖励 。在电源插座问题中,奖励是一定数量的电荷;然而,在强盗问题中,它是从机器中赢得的一笔钱。
采取特定行动所获得的奖励是一个随机值,从特定于该行动的潜在概率分布中提取。因此,每次采取行动时,返回的奖励可能会有不同的值。如果同一个动作重复多次,那么就可以计算出一个更准确的真实回报平均值。
采取特定行动获得奖励可能是强化学习的主要定义特征。正是这种奖励被用来指导学习,试图找到最好的行动,从而最大限度地提高总的整体奖励。这与监督学习形成对比,在监督学习中,最佳动作将作为训练数据的一部分提供。
- 在采取行动’ Aₜ ‘之后,在时间步’ t ‘获得的奖励表示为’ Rₜ
动作次数
可用动作的数量由字母’ k 表示。因此,在电源插座示例中,’ k ‘将是可供选择的电源插座数量。因为,在这种情况下,有 5 个不同的套接字,’ k ‘将是 5。在多臂土匪问题中,它是可供选择的吃角子老虎机的总数(实际上这个问题经常被称为’ k 臂土匪问题’)。
- 可用动作的数量由字母’ k 表示
预期奖励
每个可用的’ k '动作都有一个 预期 奖励,其中术语“预期”是指如果该动作重复多次将获得的平均值。因此,例如,如果投掷一枚公平的硬币,获得正面的预期概率将是 0.5,因为平均而言,当投掷总数很大时,正面应该出现在所有硬币投掷的一半中。
- 财产的预期价值用符号’𝔼’表示
值
一个行动的期望回报被称为该行动的 值 ,并被表示为“ q(a) ”,其中“ a ”是在时间步长“ t ”选择的具体行动(即 Aₜ = a)。
- 因此,动作’ a '的值由下式给出:
这可以理解为:假设在时间步长‘t’选择的行动是行动‘a’,行动‘a’的值等于预期(平均)奖励值。
(注意:任何时候你在概率方程中看到符号“|”,就把它理解为‘给定’)。
实际上,这意味着,如果你不断重复动作’ a ',然后对你得到的奖励值进行平均,最终,你会知道’q(a)【T29]‘的真实值,即’ a '的平均奖励。因此,如果小机器人继续尝试同一个电源插座,他将获得该插座真实平均功率输出的越来越准确的估计,直到最终,如果他重复该动作足够长的时间,他将知道该插座输出的真实值。
样本平均估计值
显然,我们不知道行为回报的真正价值。如果我们这样做了,事情就简单了。我们只是利用现有的知识,而不必做任何探索。我们只要玩最好的吃角子老虎机,赢得最多的钱,机器人宝宝就会插上充电最多的插座。
然而,事实并非如此。我们不知道真正的回报,因此必须做一些探索,从每一个可能的行动中找到回报的比较。因此,为了跟踪哪一个动作是最好的,当我们探索一组可能的动作时,我们需要估计每个动作的价值。随着时间的推移,这种估计应该会越来越准确,并向真正的回报值靠拢。
因为一个行为的真实价值是该行为的平均回报,一个简单而有效的估计可以通过取该行为迄今为止回报的平均值来计算。
因此,在时间步长*‘t’*处,动作 a 的估计值 Qₜ(a)’ 由下式给出:
其中’ n’ 是在时间’ t ‘之前采取行动’ a 的次数,而’ Rᵢ ‘是采取行动’ a 时在每个时间步获得的奖励。
计算样本平均值
对任何行为来说,形成所有奖励总和的最简单的方法是存储每个奖励,然后在需要时添加它们。然而,从实际的角度来看,这不是很有效,无论是在存储和计算时间方面。有可能记录总的回报,但随着时间的推移,即使是这个值也会变得难以管理。
- 一个更好的解决方案是根据上一次的估计来计算新的估计奖励。
对于一个行动’ a ‘,行动价值的 n ᵗʰ估计值’ Qₙ ',由该行动以前获得的所有奖励的总和除以该行动被选择的次数(即,它只是平均值)得出:
因此,交换一下东西,在’ n '之前,奖励的总和由下式给出:
当获得下一个奖励“rₙ”时,可以通过将该奖励加到先前的奖励总和上并增加已经采取的行动的次数的计数来计算新的估计值。所以新的估计是:
**
由于我们已经知道如何写奖励的总和,在’ n '之前,就最后的估计而言,我们可以简单地将它代入等式:
重新整理后,我们最终得到了新评估的可用形式,用上次评估’ Qₙ 和新奖励’ Rₙ '来表示:
公式 1:新的估计值,根据上次的估计值和新的奖励值计算得出。
虽然对某些人来说,这些等式可能有点令人生畏,但它们基本上可以归结为公式 1 中给出的最后一个等式,它让我们在给定行为的先前值和新奖励的情况下,计算行为的值。
这个公式很容易在代码中实现(我们将在下一部分中实现),让我们监视在采取这些动作时,动作的估计值是如何变化的。然后,这些值可用于比较这些操作的相对性能,以找到最佳操作和选择这些操作的最佳方式。
摘要
在这里,我们对多武器匪徒调查的第一部分,我们已经定义了描述匪徒问题所需的所有基本术语和方程。
然而,到目前为止,我们只给出了土匪问题的一个高层次的概述,没有真正进入问题本身。我们将在接下来的部分中纠正这一点,届时我们将全面检查一些可用于解决这一问题的主要策略。
更重要的是,我们将使用这些策略让机器人宝宝充电,然后回到妈妈身边!
接下来:第二部分:强盗框架
参考
[1]《强化学习:导论 》,萨顿&巴尔托(2018)
强盗框架
婴儿机器人强化学习指南
多种武器的强盗:第二部分
概观
机器人宝宝在商场走失。利用强化学习,我们想帮助他找到回到妈妈身边的路。然而,在他开始寻找她之前,他需要从一组电源插座充电,每个插座的电量略有不同。
使用多臂强盗问题中的策略,我们需要在最短的时间内找到最好的插座,让机器人宝宝充电上路。
这是第二个,在一个六部分系列,对多武装匪徒。在第 1 部分中,我们涵盖了描述 bandit 问题所需的所有基本术语和数学知识。
在这一部分中,我们将看看我们将在接下来的文章中解决的问题,确切地描述电源插座问题将如何设置。这涵盖了用于创建基本套接字模拟器和用于评估这些套接字的测试框架的所有代码。
因此,尽管我们还不能实现真正的强盗算法,但我们会做好所有必要的基础工作,这样我们就可以在随后的部分开始研究各种强盗策略。
bandit 算法和测试框架的所有代码都可以在 github 上找到: Multi_Armed_Bandits
概述
机器人宝宝进入了一个充电室,里面有 5 个不同的电源插座。每个插座返回的电荷数量略有不同。我们希望在最短的时间内给机器人宝宝充电,所以我们需要找到最好的插座,然后使用它,直到充电完成。
这和多臂强盗问题是一样的,除了我们不是在找一个能给出最好回报的吃角子老虎机,而是在找一个能给出最多电量的电源插座。
测试选择策略
现在我们已经有了所有需要的符号和术语,我们可以构建一个测试系统了。这将让我们检查不同的策略在寻找和利用最佳电源插座时的表现。
实现电源插座
我们将测试几种不同的策略来寻找最佳电源插座,作为其中的一部分,我们需要创建几种不同类型的插座。但是,所有套接字都具有相同的基本功能,并且需要能够执行以下操作:
- **供给一些电荷。**其中返回的费用金额取决于插座的真实奖励值。
- **更新对插座的奖励值的估计。**主要通过计算样本平均值来完成,如第 1 部分所述。每个套接字都会记录自己的估计值和尝试的次数。它还将存储其真实的奖励值,但这只是为了实现的目的。因为这是我们试图估计的值,在套接字初始化之后,我们将假装我们实际上不知道这个值。
- **返回公制。**这个用来评估和选择插座。默认情况下,这只是套接字奖励值的当前估计值。
下面显示了一个基本电源插座的 python 实现。它充当基类,所有其他更专业的套接字都将从这个基类派生出来。
基本电源插座跟踪以下值,这些值与我们目前看到的等式相匹配:
- q =插座输出的真实平均值
- Q =套接字输出的运行估计(即其回报)
- n =套接字被尝试的次数
Q 和 n 在单独的 initialize 函数中被初始化,以允许套接字被重置,而不必创建一个全新的套接字。
当估计套接字输出时,真正的输出’ q ‘是我们试图收敛的值。虽然设置套接字需要’ q ',但是它的值没有在其他地方使用,因为这是我们试图寻找的值。
函数’ charge ‘返回插座的输出奖励。这由正态(高斯)分布给出,平均值为’ q '(设置期间提供的值)。
’ update '函数使用新的奖励值和先前的估计值计算样本平均估计值,如第 1 部分的公式 1 所述。在代码中,这直接翻译为:
最后’ sample '函数返回将用于选择下一个套接字的度量。在这种情况下,它只是值“Q”,当前奖励的估计值。
实施充电室
我们想要设置一个有 5 个插座的房间,每个插座都会返回一个平均持续时间不同于其他插座的能量脉冲。
为了简单起见,我们将对每个插座的功率输出使用固定的顺序。因此,在下面的代码中,’ socket_order '参数定义了 socket 2 将是最差的,socket 4 将是最好的,这将在我们的整个实验中保持不变。
每个插座返回的平均电荷量的计算方法是,将其插座顺序值乘以 2,然后加上 2 以抵消该值并使其大于零。因此,按顺序,插座有以下平均奖励:6,4,8,12,10。
按照这种方式设置套接字,我们可以从每个套接字获得以下输出:
在上面的“小提琴”图中,每个套接字的线条显示了作为每个套接字的奖励而返回的值的范围。因此,1 号插座返回了大约 2 到 10 秒的充电时间。线下的阴影区域代表了每个奖励被返还的频率。对于插座 1,最常返回的奖励是 6 秒钟的充电。这是这个插座的平均奖励,也是它的真实奖励值。
在密度图中,我们可以看到每个插座的奖励概率是如何变化的。4 号插座最好,平均充电时间为 12 秒,而 2 号插座最差,充电时间仅为 4 秒。Socket 4 是我们试图寻找和利用的最佳插座。
插座测试仪
我们还需要一种方法,在每个时间步从一组套接字中进行采样和选择。这由 SocketTester 类处理,如下所示:
如前所述, SocketTester 类创建一组电源插座,按照提供的插座顺序。运行时,套接字测试器循环指定数量的时间步长,并在每个时间步长执行以下操作:
-
选择一个套接字:
为每个套接字调用’ sample '函数,然后选择返回值最大的套接字。如前所述,默认情况下,返回的样本值将只是套接字对其平均回报的当前估计。
当有多个具有最高样本值的套接字时,‘random _ arg max’函数(如下所示)任意选择一个具有最大值的套接字。这优先于 Numpy 的 argmax 函数使用,该函数在出现平局时简单地选择第一个项目。 -
收费和更新: 一旦选择了一个插座,我们就从那个插座收费以获得奖励。然后我们更新这个套接字,增加它被尝试的次数,并使用新的奖励值改进它的奖励估计值。
注意,上面显示的’ SocketTester’ '类的代码是实际类的简化版本,只显示了主要功能。在完整版的类中,套接字的属性在运行过程中被跟踪。此外,该类只执行一次运行。因为我们处理的是随机变量,所以一次运行可能不足以确定套接字选择策略的真实行为。因此,第二个类“ SocketExperiment ”用于设置和运行重复的套接字测试,并生成这些测试的平均结果。这两个类的完整代码可以在 Github 库的文件 PowerSocketSystem.py 中找到。
摘要
这部分我们看多武装匪徒根本没有真正看他们!然而,它确实涵盖了我们在后续文章中创建和评估多兵种强盗战略所需的所有基本框架。
在以后的文章中,我们将把在第 1 部分中学到的理论与这个测试框架结合起来,开始研究如何应用各种强盗策略来探索和利用电源插座集。
**<** [**Part 1: Multi-Armed Bandits**](/multi-armed-bandits-part-1-b8d33ab80697) [**Part 3: Bandit Algorithms**](/bandit-algorithms-34fd7890cb18) >
多武装匪徒:UCB 算法
基于置信界限优化动作
乔纳森·克洛克在 Unsplash 上拍摄的照片
想象一下,你在一个赌场,在一堆(k 个)有不同回报概率的独臂强盗(也叫吃角子老虎机)中进行选择,并且想要选择最好的一个。你使用什么策略来帮助你走出最大数量的季度?
这就是多兵种土匪问题的本质,是一个简化强化学习任务。当你在网站上寻求最大化的参与度,或者搞清楚临床试验,或者试图优化你的电脑性能时,这些都可能发生。
它们不仅仅是一个有用的框架,解决起来也很有趣!
TL;速度三角形定位法(dead reckoning)
我们用 Python 中的例子来教授置信上限 bandit 算法,以便让您快速熟悉这种方法。
你的第一个策略
强盗问题需要在探索和开发之间取得平衡。因为问题始于对奖励的无先验知识,一旦缩小了选择范围,它需要探索(尝试许多吃角子老虎机)然后利用(反复拉动最佳杠杆)。
最简单的强盗采用ϵ-greedy 策略,这意味着它会选择它认为大多数时候最好的老虎机,但有一个小的ϵ%概率,它会选择随机的老虎机。这是一个简单的策略,可以产生良好的结果(如果你想看到这种方法被实施,请看这篇文章),但是我们可以做得更好。
置信上限 Bandit
ϵ-greedy 可能会花很长时间来决定选择合适的独臂强盗,因为这是基于小概率的探索。置信上限 (UCB)方法有所不同,因为我们基于对给定选择的不确定性来做出选择。
我会向你展示数学,然后解释:
上述等式为我们的模型提供了选择标准。Q_n(a)是我们对给定老虎机 a. 的当前估计值,平方根下的值是我们尝试过的老虎机总数的对数, n 除以我们尝试每台老虎机的次数 a ( k_n ),而 c 只是一个常数。我们通过选择在每一步 n 中给出最大值的强盗来选择下一台吃角子老虎机。
平方根项是对每个动作和的方差的估计。如果我们还没有选择一个土匪,方差是无限的(我们将除以 0),这意味着这将是我们的下一个选择。这迫使算法快速探索那些未知值。一旦它选择了它,在其他条件相同的情况下,它的价值就会下降,相对于其他选择来说,可能性变得更小。因为 log(n)在分子中,每次我们不选择一个动作,它的值变得更有可能,尽管分子增长得更慢(即对数),所以你收集的数据越多,这种影响变得越小。最终结果是一种算法,在锁定最有利可图的机器之前,可以非常快速地采样,以减少未知的不确定性。
一些实际的警告
在我们深入实现之前,我们将初始化我们的值,k_n(a) = 1 而不是 0,以确保我们不会在 Python 中弹出任何nan
值。此外,我们将模拟很多强盗拉,所以我们需要有效率地计算我们的一些值。Q_n(a)只是该动作的平均值,我们可以使用一个方便的公式来计算平均值,而不是为每个动作保留数千个值,只需为每个动作存储两条信息,即我们为该给定动作做出了多少次选择(k_n(a))和我们的当前平均值(m_n)。
其中 R_n 是我们刚刚从采取一项行动中获得的回报(为简洁起见,我省略了 a)。
UCB 电码
# import modules
import numpy as np
import matplotlib.pyplot as plt
import pandas as pdclass ucb_bandit:
'''
Upper Confidence Bound Bandit
Inputs
============================================
k: number of arms (int)
c:
iters: number of steps (int)
mu: set the average rewards for each of the k-arms.
Set to "random" for the rewards to be selected from
a normal distribution with mean = 0\.
Set to "sequence" for the means to be ordered from
0 to k-1.
Pass a list or array of length = k for user-defined
values.
'''
def __init__(self, k, c, iters, mu='random'):
# Number of arms
self.k = k
# Exploration parameter
self.c = c
# Number of iterations
self.iters = iters
# Step count
self.n = 1
# Step count for each arm
self.k_n = np.ones(k)
# Total mean reward
self.mean_reward = 0
self.reward = np.zeros(iters)
# Mean reward for each arm
self.k_reward = np.zeros(k)
if type(mu) == list or type(mu).__module__ == np.__name__:
# User-defined averages
self.mu = np.array(mu)
elif mu == 'random':
# Draw means from probability distribution
self.mu = np.random.normal(0, 1, k)
elif mu == 'sequence':
# Increase the mean for each arm by one
self.mu = np.linspace(0, k-1, k)
def pull(self):
# Select action according to UCB Criteria
a = np.argmax(self.k_reward + self.c * np.sqrt(
(np.log(self.n)) / self.k_n))
reward = np.random.normal(self.mu[a], 1)
# Update counts
self.n += 1
self.k_n[a] += 1
# Update total
self.mean_reward = self.mean_reward + (
reward - self.mean_reward) / self.n
# Update results for a_k
self.k_reward[a] = self.k_reward[a] + (
reward - self.k_reward[a]) / self.k_n[a]
def run(self):
for i in range(self.iters):
self.pull()
self.reward[i] = self.mean_reward
def reset(self, mu=None):
# Resets results while keeping settings
self.n = 1
self.k_n = np.ones(self.k)
self.mean_reward = 0
self.reward = np.zeros(iters)
self.k_reward = np.zeros(self.k)
if mu == 'random':
self.mu = np.random.normal(0, 1, self.k)
上面的代码定义了我们的ucb_bandit
类,使我们能够模拟这个问题。运行它需要三个参数:要拉的臂数(k
)、探索参数(c
)和迭代次数(iters
)。
我们可以通过设置mu
来定义奖励(默认情况下,奖励均值来自正态分布)。我们对此运行 1000 集,并平均每集 1000 步的回报,以了解该算法的执行情况。
k = 10 # number of arms
iters = 1000ucb_rewards = np.zeros(iters)
# Initialize bandits
ucb = ucb_bandit(k, 2, iters)episodes = 1000
# Run experiments
for i in range(episodes):
ucb.reset('random')
# Run experiments
ucb.run()
# Update long-term averages
ucb_rewards = ucb_rewards + (
ucb.reward - ucb_rewards) / (i + 1)
plt.figure(figsize=(12,8))
plt.plot(ucb_rewards, label="UCB")
plt.legend(bbox_to_anchor=(1.2, 0.5))
plt.xlabel("Iterations")
plt.ylabel("Average Reward")
plt.title("Average UCB Rewards after "
+ str(episodes) + " Episodes")
plt.show()
目前看来还不错!强盗通过稳步增长的平均奖励来学习。为了了解它的工作情况,我们将它与标准的ϵ-greedy 方法进行比较(代码可以在这里找到)。
k = 10
iters = 1000eps_rewards = np.zeros(iters)
ucb_rewards = np.zeros(iters)# Initialize bandits
ucb = ucb_bandit(k, 2, iters)
eps_greedy = eps_bandit(k, 0.1, iters, ucb.mu.copy())episodes = 1000
# Run experiments
for i in range(episodes):
ucb.reset()
eps_greedy.reset()# Run experiments
ucb.run()
eps_greedy.run()
# Update long-term averages
ucb_rewards += (ucb.reward - ucb_rewards) / (i + 1)
eps_rewards += (eps_greedy.reward - eps_rewards) / (i + 1)
plt.figure(figsize=(12,8))
plt.plot(ucb_rewards, label='UCB Bandit')
plt.plot(eps_rewards, label="$\epsilon={}$".format(
eps_greedy.eps))
plt.legend(bbox_to_anchor=(1.3, 0.5))
plt.xlabel("Iterations")
plt.ylabel("Average Reward")
plt.title("Average rewards for UCB and $\epsilon$-Greedy Bandits")
plt.show()
UCB 方法快速找到最佳动作,并在大部分剧集中利用它,而贪婪算法尽管也能相对快速地找到最佳动作,但随机性太大。我们也可以通过观察动作选择和比较每个算法选择的最优动作来观察这一点。
width = 0.45
bins = np.linspace(0, k-1, k) - width/2plt.figure(figsize=(12,8))
plt.bar(bins, eps_greedy.k_n,
width=width,
label="$\epsilon$={}".format(eps_greedy.eps))
plt.bar(bins+0.45, ucb.k_n,
width=width,
label="UCB")
plt.legend(bbox_to_anchor=(1.3, 0.5))
plt.title("Number of Actions Selected by Each Algorithm")
plt.xlabel("Action")
plt.ylabel("Number of Actions Taken")
plt.show()opt_per = np.array([eps_greedy.k_n, ucb.k_n]) / iters * 100
df = pd.DataFrame(np.vstack(
[opt_per.round(1),
eps_greedy.mu.reshape(-1, 1).T.round(2)]),
index=["Greedy", "UCB", "Expected Reward"],
columns=["a = " + str(x) for x in range(0, k)])
print("Percentage of actions selected:")
df
在这种情况下,我们的最优行动是 a=6,平均回报为 1.54。ϵ-greedy 算法选择它的概率是 83.4%,而 UCB 算法选择它的概率是 89.7%。此外,您将看到贪婪算法选择负值的频率比 UCB 算法高得多,这也是因为每次选择都有 10%的机会选择随机行动。
有几十个其他多臂土匪方法在那里学习。这是一个简单的优化框架,但是功能非常强大,玩起来也很有趣!
马尔可夫营销归因
Cloudera 如何使用马尔可夫模型解决多渠道归因问题
克莱门斯·范·雷趴在的 Unsplash 上
这篇文章的编辑版本首先发表在 ClickZ: 数据驱动营销归因营销人员指南。
营销归因是一种衡量活动和渠道对潜在客户的价值的方法。潜在客户与营销活动互动的时间点称为接触点,接触点的集合构成了购买者的旅程。营销人员使用归因模型的结果来了解哪些接触点对成功的购买者旅程影响最大,以便他们能够就如何优化未来营销资源的投资做出更明智的决策。
买家之旅很少是直截了当的,成功之路可能是漫长而曲折的。由于要考虑的接触点太多,很难区分真正的高影响互动和低影响互动,这可能导致不准确的信用划分和营销绩效的虚假表现。这就是为什么为你的企业选择最佳归因模式如此重要。
在这篇文章中,我提供了一些关于 Cloudera 如何使用 Cloudera 产品构建一个定制的、数据驱动的归因模型来衡量我们全球营销活动的绩效的见解。
传统模型的局限性
所有的归因模型都有其优点和缺点,但传统模型的一个共同缺点是它们是基于规则的。用户必须预先决定如何在接触点之间分配销售活动的积分。传统模型包括:
幸运的是,有更复杂的数据驱动方法,能够通过模拟接触点实际上如何与买家互动,以及如何相互影响预期的销售结果,来捕捉买家旅程的复杂性。数据驱动模型让营销人员能够更深入地了解营销活动和渠道的重要性,从而提高营销责任和效率。
Cloudera 的数据驱动方法
我们评估的第一个归因模型是基于合作博弈理论的 Shapley 值。我在之前的一篇文章中介绍了这个模型的细节。这种流行的(获得诺贝尔奖)模型提供了比传统方法更深入的渠道绩效,但在其最基本的实现中,它不能扩展到处理我们想要包括的接触点数量。Shapley 模型在数量相对较少的渠道上表现良好,但我们的要求是对所有活动进行归因,这相当于买家旅程中的数百个接触点。
在投入时间扩展 Shapley 算法之前,我们研究了替代方法,并决定评估使用马尔可夫模型来解决归因问题。我们使用channel attributeR 包进行实施,发现它产生了与 Shapley 模型类似的结果,它可以扩展到大量接触点,并且易于在 Cloudera 数据科学工作台(CDSW) 中设置和使用。
马尔可夫归因模型
Markov 是一个概率模型,它将购买者的旅程表示为一个图形,图形的节点是接触点或“状态”,图形的连接边是观察到的这些状态之间的转换。例如,购买者观看产品网络研讨会(第一状态),然后浏览 LinkedIn(过渡),在那里他们点击同一产品的广告印象(第二状态)。
该模型的关键要素是转移概率(在不同状态之间移动的可能性)。购买者在两种状态之间转换的次数被转换成概率,并且完整的图可以用于测量每个状态的重要性和最可能的成功路径。
例如,在买家旅程数据样本中,我们观察到网上研讨会接触点出现了 8 次,买家观看网上研讨会后点击 LinkedIn 广告仅 3 次,因此两种状态之间的转换概率为 3 / 8 = 0.375 (37.5%)。为每个转换计算一个概率以完成该图。
在我们开始计算活动归因之前,马尔可夫图可以告诉我们一些关于我们购买者旅程的有用信息。从上面的例子可以看出,成功概率最高的路径是“开始>网络研讨会>活动 Z >成功”,总概率为 42.5% (1.0 * 0.425 * 1.0)。
马尔可夫图也能告诉我们整体的成功率;也就是说,给定所有买家旅程的历史,买家旅程成功的可能性。成功率是整体营销绩效的基线,也是衡量任何变革有效性的指针。上面的例子马尔可夫图有 67.5%的成功率:
活动归因
通过计算所谓的移除效应,马尔可夫图可以用来衡量每个活动的重要性。一项活动的有效性是通过将其从图表中移除并模拟买家旅程来衡量没有它时成功率的变化来确定的。移除效应是权重的一个代理,它是为马尔可夫图中的每个活动计算的。
利用移除效应进行营销归因是拼图的最后一块。为了计算每个活动的属性值,我们可以使用下面的公式: A = V * (Rt / Rv)
- A =战役的属性值
- V =要除的总值。例如,用作马尔可夫模型输入的所有成功买家旅程的总美元值
- Rt =战役的移除效果
- Rv =所有移除效果值之和
让我们看一个例子。假设在财年的第一季度,所有成功买家旅行的总美元价值为100 万美元。相同的买家旅程用于构建马尔可夫模型,它计算出我们的广告活动的移除效应为 0.7 (即,当广告活动从马尔可夫图中移除时,买家旅程成功率下降了 70%)。我们知道输入数据中观察到的每个活动的移除效应值,对于本例,假设它们的总和为 2.8 。将这些数字代入公式,我们计算出我们广告活动的归属价值为 $25 万:
【25 万美元= 100 万美元 (0.7 / 2.8)*
除此之外,我们还通过从归因价值中减去同期开展活动的成本来计算活动投资回报率。
关于channel attributeR 包的好处在于,它为您完成了所有这些工作,甚至包括三种传统的基于规则的比较算法的实现(首次触摸、最后触摸和线性触摸)。还有一个新的 Python 实现。
Cloudera on Cloudera
我们为我们在 Cloudera 的数据实践感到自豪。营销归因应用程序由 Cloudera 的营销和数据卓越中心业务部门开发。它建立在我们内部的企业数据中心和运行在 Cloudera 数据科学工作台(CDSW) 中的马尔可夫模型之上。
通过利用数据驱动的归因模型,我们消除了与传统归因机制相关的偏见。我们已经能够了解各种信息如何影响我们的潜在客户,以及地理位置和收入类型的差异。现在我们有了可靠的数据支持归因,我们有信心使用结果来通知和推动我们的营销组合战略和投资决策。当我们与销售团队合作时,我们可以依靠这些数字来推动我们的营销战略向前发展。
多类分类:从混淆矩阵中提取性能度量
在这篇文章中,我解释了如何阅读混淆矩阵,以及如何从混淆矩阵中提取多类分类问题的 FP、FN、TP、TN、TPR、TNR、FPR、FNR &准确度值。
使用 scikit-learn 的文档中的代码生成的图。
介绍
在我之前的一篇帖子中,*ROC 曲线用一个新冠肺炎假设的例子解释:二进制&多类分类教程 *,我很清楚地解释了什么是 ROC 曲线以及它是如何与著名的混淆 矩阵联系在一起的。如果你不熟悉术语混淆矩阵和真阳性、真阴性等。,参考上述文章,在 6 分钟内学会所有内容或继续阅读,快速回顾两分钟。
2 分钟回顾:TP、TN、FP、FN 是什么意思
让我们想象一下,我们有一个测试,它能够在几秒钟内告诉我们一个人是被病毒感染还是而不是*。因此测试的输出可以是正(受影响)或负(不受影响)。所以,在这个假设的例子中,我们有一个二元分类的例子。***
作者做的手工素描。假设我们真的知道真相,两个人群的例子,一个受新冠肺炎影响,另一个不受影响。此外,基于测试的输出,我们可以将一个人表示为受影响的(蓝色人群)或不受影响的(红色人群)。
- 真阳性 ( TP ,蓝色分布)是真正拥有病毒的人*。***
- 真阴性(TN,红色分布 ) 是真正没有病毒的人*。***
- 假阳性(FP) 是根据检测得知确实没有生病而是的人,他们被假* ( 假)表示为生病 ( 阳性)。***
- 假阴性(FN) 是指确实患病但根据检测判断,他们被假* ( 假)表示为非 患病 ( 阴性)。*
为了存储所有这些性能指标,通常使用混淆矩阵。
混乱矩阵:获得 TPR,TNR,FPR,FNR。
分类器的混淆矩阵总结了我们的模型的性能的 TP、TN、FP、FN 度量。混淆矩阵可以进一步用于提取更多的性能指标,例如:TPR、TNR、FPR、FNR 和准确性。
使用上述所有术语,我们还可以构建由这些度量组成的著名的混淆矩阵,然后我们可以计算真阳性率和假阳性率,如下图所示,针对二进制分类情况。
图来自维基百科。
如果你想在交互式路线图和活跃的学习社区的支持下自学数据科学,看看这个资源:https://aigents.co/learn
处理多类分类问题
对于任何 N 类分类问题,混淆矩阵都可以很好地定义。然而,如果我们有 2 个以上的类(N > 2),那么上述等式(在混淆矩阵图中)不再成立。
在这篇文章中,我展示了如何对任意数量的类(N)估计所有这些度量。
多类 Python 工作示例
-分类模型
在之前的帖子中,我解释了什么是 SVC 模型,所以这里我们将使用它作为我们的分类器。
-数据集
在虹膜数据集中,我们有花的 3 个类别和 4 个特征。所以分类问题不再是二元的了,因为我们有了 3 个类。
让我们加载 数据并检查每个 类有多少类和样本 :
*import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm, datasets
from sklearn.model_selection import train_test_split
from sklearn.metrics import plot_confusion_matrix
from sklearn.metrics import confusion_matrix# import some data to play with
iris = [datasets.load_iris](https://scikit-learn.org/stable/modules/generated/sklearn.datasets.load_iris.html#sklearn.datasets.load_iris)()
X = iris.data
y = iris.target
class_names = iris.target_nameslabels, counts = np.unique(y, return_counts=True)
plt.bar(labels, counts, align='center')
plt.gca().set_xticks(labels)
plt.show()*
我们可以看到,我们有 3 个类/组(标签:0,1,2),每个类/组中有 50 个(即条形的高度)样本(示例/观察)。
接下来,我们将在模型拟合之前将数据分成训练集和测试集:
*# Split the data into a training set and a test set
X_train, X_test, y_train, y_test = [train_test_split](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html#sklearn.model_selection.train_test_split)(X, y, random_state=0)*
接下来,让我们使用训练集合创建分类模型(线性 SVC)和拟合模型*😗**
*# Fit the classifier
classifier = [svm.SVC](https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html#sklearn.svm.SVC)(kernel='linear').fit(X_train, y_train)*
现在,我们将**预测**测试集样本的标签**,并且我们将建立我们的三级分类问题的混淆矩阵:
*# Predict the labels of the test set samples
predicted_labels = classifier.predict(X_test)# Build the confusion matrix of our 3-class classification problemcnf_matrix = confusion_matrix(y_test, predicted_labels)print(cnf_matrix)
#array([[13, 0, 0],
# [ 0, 15, 1],
# [ 0, 0, 9]])*
为了更好地阅读/理解混淆矩阵,让我们用来描绘和吧:
*disp = [plot_confusion_matrix](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.plot_confusion_matrix.html#sklearn.metrics.plot_confusion_matrix)(classifier, X_test, y_test,
display_labels=class_names,
cmap=plt.cm.Blues)
plt.show()*
使用我们的线性 SVC 模型的 3 类分类混淆矩阵。
怎么读
- 在 x 轴上,我们有预测 标签,在 y 轴上,我们有真实 标签来自测试集的样本(记住预测仅使用**测试集***)。***
- 理想情况下,完美的 分类器会导致混淆* 矩阵,其中我们只有对角线上的值,也就是说,在这种情况下,我们对所有 3 个类别/组的所有测试样本进行了正确分类。***
- 方框中的数值只是计数。例如,在我们的例子中,左上角的盒子里面有一个值 13,接下来的两个盒子有 0 和 0。这意味着我们能够对所有 13 个 setosa 测试样本进行正确分类。
- 另一方面,通过查看第二个* 行即所指的到杂色 组,我们可以看到我们正确地将分类为 15 个杂色测试样本(在测试集中总共有 16 个)和遗漏了 1 个杂色测试样本即错误地***
最后,这里是魔法。****
我们将估计 FP、FN、TP、TN、TPR(灵敏度、命中率、召回率或真阳性率)、TNR(特异性或真阴性率)、PPV(精确度或阳性预测值)、NPV(阴性预测值)、FPR(脱落或假阳性率)、FNR(假阴性率)、FDR(假发现率)和 ACC(准确度)。
多类混淆矩阵。
*****FP = cnf_matrix.sum(axis=0) - np.diag(cnf_matrix)
FN = cnf_matrix.sum(axis=1) - np.diag(cnf_matrix)
TP = np.diag(cnf_matrix)
TN = cnf_matrix.sum() - (FP + FN + TP)FP = FP.astype(float)
FN = FN.astype(float)
TP = TP.astype(float)
TN = TN.astype(float)# Sensitivity, hit rate, recall, or true positive rate
TPR = TP/(TP+FN)
# Specificity or true negative rate
TNR = TN/(TN+FP)
# Precision or positive predictive value
PPV = TP/(TP+FP)
# Negative predictive value
NPV = TN/(TN+FN)
# Fall out or false positive rate
FPR = FP/(FP+TN)
# False negative rate
FNR = FN/(TP+FN)
# False discovery rate
FDR = FP/(TP+FP)
# Overall accuracy for each class
ACC = (TP+TN)/(TP+FP+FN+TN)*****
那都是乡亲们!希望你喜欢这篇文章!
参考
[1]https://en.wikipedia.org/wiki/Confusion_matrix
[2]https://sci kit-learn . org/stable/modules/generated/sk learn . metrics . confusion _ matrix . html
敬请关注并支持这一努力
如果你喜欢这篇文章并觉得它有用,请关注我,这样你就可以看到我所有的新帖子。
有问题吗?把它们作为评论贴出来,我会尽快回复。
最新帖子
***** [## 时间序列预测:用脸书的先知模型预测股票价格
使用可从《先知脸书》公开获得的预测模型预测股票价格
towardsdatascience.com](/time-series-forecasting-predicting-stock-prices-using-facebooks-prophet-model-9ee1657132b5) [## 用新冠肺炎假设的例子解释 ROC 曲线:二分类和多分类…
在这篇文章中,我清楚地解释了什么是 ROC 曲线以及如何阅读它。我用一个新冠肺炎的例子来说明我的观点,我…
towardsdatascience.com](/roc-curve-explained-using-a-covid-19-hypothetical-example-binary-multi-class-classification-bab188ea869c) [## 支持向量机(SVM)解释清楚:分类问题的 python 教程…
在这篇文章中,我解释了支持向量机的核心,为什么以及如何使用它们。此外,我还展示了如何绘制支持…
towardsdatascience.com](/support-vector-machines-svm-clearly-explained-a-python-tutorial-for-classification-problems-29c539f3ad8) [## PCA 清楚地解释了——如何、何时、为什么使用它以及特性的重要性:Python 指南
在这篇文章中,我解释了什么是 PCA,何时以及为什么使用它,以及如何使用 scikit-learn 在 Python 中实现它。还有…
towardsdatascience.com](/pca-clearly-explained-how-when-why-to-use-it-and-feature-importance-a-guide-in-python-7c274582c37e) [## 关于 Python 中的最小-最大规范化,您需要知道的一切
在这篇文章中,我将解释什么是最小-最大缩放,什么时候使用它,以及如何使用 scikit 在 Python 中实现它
towardsdatascience.com](/everything-you-need-to-know-about-min-max-normalization-in-python-b79592732b79) [## Scikit-Learn 的标准定标器如何工作
在这篇文章中,我将解释为什么以及如何使用 scikit-learn 应用标准化
towardsdatascience.com](/how-and-why-to-standardize-your-data-996926c2c832)
和我联系
- LinkedIn:【https://www.linkedin.com/in/serafeim-loukas/
- https://www.researchgate.net/profile/Serafeim_Loukas研究之门:
- https://people.epfl.ch/serafeim.loukasEPFL简介:
- 堆栈 溢出:https://stackoverflow.com/users/5025009/seralouk*****
多类分类—一对一和一对一
图 1:通过krishijagran.com拍摄的照片
介绍
机器学习主要有三种类型:
- 监督
- 无人监督的
- 加强
监督机器学习分为回归和分类。我们使用回归技术来预测连续变量的目标值,就像预测雇员的工资一样。相反,我们使用分类技术来预测给定输入数据的类别标签。
在分类中,我们设计分类器模型,然后使用输入训练数据对其进行训练,然后将测试数据分类到数据集中存在的多个类别标签中。
目录
- 什么是多类分类?
- 二元分类与多类分类
- 一个对所有
- 一对一
- 结论
让我们深入理解这个概念,
1.什么是多类分类?
图 2:通过learn-ml.com拍摄的照片
当我们解决一个只有两个类别标签的分类问题时,过滤数据、应用任何分类算法、用过滤后的数据训练模型以及预测结果都变得很容易。但是,当我们在输入训练数据中有两个以上的类实例时,分析数据、训练模型和预测相对准确的结果可能会变得复杂。为了处理这些多类实例,我们使用多类分类。
多类分类是一种分类技术,它允许我们将测试数据分类到训练数据中的多个类标签中,作为模型预测。
主要有两种类型的多类分类技术
- 一个对全部(一个对其余部分)
- 一对一
2.二元分类与多类分类
图 3:照片经由utkuufuk.com
二元分类
- 数据集中只有两个类实例。
- 它只需要一个分类器模型。
- 混淆矩阵易于推导和理解。
- 例如:-检查电子邮件是否是垃圾邮件,根据身高和体重预测性别。
多类分类
- 数据集中存在多个类标签。
- 分类器模型的数量取决于我们应用的分类技术。
- 一个对所有:- N 类实例然后 N 个二元分类器模型
- 一对一:- N 类实例然后 N (N-1)/2 二元分类器模型*
- 混淆矩阵很容易推导,但理解起来很复杂。
- 示例:-检查水果是苹果、香蕉还是橘子。
3.一对所有(一对其余)
在一对一分类中,对于 N 类实例数据集,我们必须生成 N-二元分类器模型。数据集中存在的类标签的数量和生成的二元分类器的数量必须相同。
图 4:cc.gatech.edu 通过的照片
如上图所示,假设我们有三个类,例如,类型 1 代表绿色,类型 2 代表蓝色,类型 3 代表红色。
现在,正如我之前告诉您的,我们必须生成与数据集中存在的类标签相同数量的分类器,因此我们必须在这里为三个相应的类创建三个分类器。
- 分类器 1:-[绿色]vs[红色、蓝色]
- 分类器 2:-【蓝色】vs【绿色,红色】
- 分类器 3:-[红色]vs[蓝色,绿色]
现在,为了训练这三个分类器,我们需要创建三个训练数据集。让我们考虑一下我们的主要数据集如下:
图 5: 主数据集
您可以看到数据集中有三个类别标签绿色、蓝色、和红色。现在我们必须为每个类创建一个训练数据集。
在这里,我们通过在该特征值的类列中放置+1 来创建训练数据集,该特征值仅与特定的类对齐。对于其余特性的开销,我们在 class 列中放-1。
图 6:绿色类训练数据集
图 7:蓝色类和红色类的训练数据集
让我们通过一个例子来理解它,
- 考虑第一行中的主数据集;我们有 x1,x2,x3 特征值,对应的类值是 G,也就是说这些特征值属于 G 类。所以我们在绿色类型对应的类列中放入+1 值。然后,我们对 x10、x11、x12 输入序列数据应用相同的方法。
- 对于与绿色类别不一致的特征的其余值,我们在它们的类别列中放置-1。
我希望你理解了训练数据集的创建。
现在,在为每个分类器创建训练数据集之后,我们将其提供给我们的分类器模型,并通过应用算法来训练该模型。
图 8:通过researchgate.net的照片
在训练模型之后,当我们将输入测试数据传递给模型时,该数据被认为是所有生成的分类器的输入。如果我们输入的测试数据有任何可能属于某个特定的类别,那么为该类别创建的分类器以 +1 的形式给出肯定的反应,所有其他分类器模型以 -1 的方式提供不良反应。类似地,二元分类器模型预测与相关类别对应的概率。
通过分析概率得分,我们预测结果为具有最大概率得分的类别索引。
图 9:SlidePlayer.com 通过的照片
- 让我们通过一个例子来理解,分别取三个测试特征值 y1、y2 和 y3。
- 我们将测试数据传递给分类器模型。我们以正面评级的形式获得了结果,该正面评级来自概率得分为( 0.9) 的绿色类分类器。
- 我们再次从蓝色类获得了正面评级,概率分数为 (0.4) ,从剩余的红色分类器获得了负面分类分数。
- 因此,基于正面响应和决定性概率得分,我们可以说我们的测试输入属于绿色类。
看下面的例子,使用内置的 one vs. rest (OvR) 技术拟合多类逻辑回归模型。
**#Import LogisticRegression() model from scikit_learn
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression#define dataset
X_train, y_train = make_classification(n_samples=500, n_features=8, n_informative=5, n_redundant=5, n_classes=4, random_state=1)#define classification model
Multiclass_model = LogisticRegression(multi_class='ovr')#fit model
Multiclass_model.fit(X_train, y_train)#make final predictions
y_pred = model.predict(X_train)**
4.一对一(卵)
图 10:通过ScienceDirect.com拍摄的照片
在一对一分类中,对于 N 类实例数据集,我们需要生成 N (N-1)/2 二元分类器模型。使用这种分类方法,我们将主数据集拆分为每个类的一个数据集,与每个其他类相对。*
以上面的例子为例,我们的分类问题有三种类型:绿色、蓝色和红色(N=3)。
我们把这个问题分成 N (N-1)/2 = 3 二元分类器问题:*
- 分类器 1:绿色对蓝色
- 分类器 2:绿色对红色
- 分类器 3:蓝色对红色
每个二元分类器预测一个类别标签。当我们将测试数据输入到分类器中时,具有多数计数的模型作为结果被推断出来。
5.结论
- 正如您所了解的 One vs. All 多类分类的工作原理,处理具有大量类实例的大型数据集是一项挑战。
- 因为我们生成了那么多分类器模型并对这些模型进行训练,所以我们从主数据集创建了那么多输入训练数据集。
- 在一对一多类分类中,我们为每对类将主数据集分割成一个二元分类数据集。
那都是民间的!!
在我的下一篇文章中再见!!
你好👋我希望你能从我的文章中获得知识。如果你愿意支持我,请随意给我买些咖啡🙏☕
https://www.buymeacoffee.com/amey23
或通过 ameypband23@gmail.com 联系我
乐意为您效劳。
基于 BERT 的多类别情感分析
基于 BERT 的 Yelp 评论多类别文本情感分析的简单快速实现
在本文中,我们将使用 BERT 对 Yelp 评论进行多类文本分类。
先决条件:
从这里克隆或下载 BERT Github 库
BERT 概述
BERT 是一个深度双向表示模型,用于通用“语言理解”从左到右和从右到左学习信息。 BERT 是根据从图书语料库(800 万字)和英语维基百科(2500 万字)中提取的未标注数据进行预训练的
伯特有两种型号
- BERT-base: 12 个编码器,带 12 个双向自关注头
- BERT-large: 24 个编码器,带 24 个双向自聚焦头
BERT-base 和 BERT-large 都有有壳和无壳版本。
- BERT 不区分大小写,其中文本在单词块标记化之前已经小写。例如,“詹姆斯·邦德”变成了“詹姆斯·邦德”。它还会删除重音标记。
- 带大小写的保留真实大小写和重音标记。
大多数情况下,我们将使用 BERT-Uncased,除非用例要求保留对于 NLP 任务至关重要的案例信息。
BERT 的基本设置
我们需要 Tensorflow 版本 1.11 或更高版本来运行 BERT 代码。
下载预训练权重和数据集后,我们需要对多类分类进行一些更改。
我们克隆或下载的代码会有一个文件run _ classifier . py。我们需要更新 类 ColaProcessor 中的方法 get_labels (),如下所示,用于多类文本分类
二元分类的原始代码
**def get_labels(self):
return [“0”, “1”]**
修改了多类文本分类的代码
**def get_labels(self):
return [“0”, “1”, “2”, “3”, “4”]**
为 BERT 构建数据集
导入数据处理所需的库
***import numpy as np
import pandas as pd
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split***
读取从文件中提取的 Yelp 审查训练和测试数据
***data_train= pd.read_csv(“yelp_review_full_csv\\train.csv”, header=None)******data_test= pd.read_csv("yelp_review_full_csv\\test.csv", header=None)******data_train.head(5)***
查找类别标签的唯一值
**data_train[0].unique()**
值为 1 表示差评,值为 5 表示优评。
您可能希望类标签从 0 开始,所以我们从当前标签值中减去 1。现在,值为 0 表示差评,值为 4 表示差评
**data_train[0] = (data_train[0] -1)
data_test[0] = (data_test[0] -1)
data_train[0].unique()**
更新多类文本分类的 BERT 码
在文件 run_classifier.py、 中修改方法get _ labels()类 ColaProcessor 并更新标签以匹配我们在训练数据中的内容
**def get_labels(self):
return [“0”, “1”, “2”, “3”, “4”]**
在 BERT 中处理不同 NLP 任务的类要求数据采用. tsv(制表符分隔值)文件格式的特定格式。
- 列 0: GUID: 该行的 ID。训练和测试数据都需要
- 第 1 列:第行的分类标签。该列的值应该与方法get _ labels(cola processor文件run _ classifier . py中指定的值相匹配。仅训练数据需要。**
- 列 2: alpha: 这是用于文本分类的虚拟列,但是对于 BERT 的训练数据是需要的
- 第 3 列:文本:这是要分类的文本。训练和测试数据都需要此列
为培训、开发和测试构建 BERT 数据集
BERT 需要三个不同的数据集:用于训练的 train 和 dev 以及用于预测的 test
*# Creating dataframe according to BERT data requirements by adding the required columns in the right order***df_bert = pd.DataFrame({
‘id’:range(len(data_train)),
‘label’:data_train[0],
‘alpha’:[‘a’]*data_train.shape[0],
‘text’: data_train[1].replace(r’\n’, ‘ ‘, regex=True)
})******df_bert.head()****
符合 BERT 要求格式的数据
将数据分为训练和开发或评估数据集
*# Splitting training data file into *train* and *test*
***df_bert_train, df_bert_dev = train_test_split(df_bert, test_size=0.01)****
构建测试数据集
我们在测试数据集中只需要两列
- 列 0: GUID: 行的 ID。
- ***第 1 列:文本:*这是要分类的文本。
*# Creating test dataframe according to BERT
**df_bert_test = pd.DataFrame({
‘id’:range(len(data_test)),
‘text’: data_test[1].replace(r’\n’, ‘ ‘, regex=True)
})****df_bert_test.tail()***
根据 BERT 测试数据集
将数据帧保存到不带标题的. tsv 文件,用于培训和开发,但文件 test.tsv 文件需要标题
*# Saving dataframes to .tsv format as required by BERT
**df_bert_train.to_csv(‘yelp_review_full_csv\\train.tsv’, sep=’\t’, index=False, header=False)****df_bert_dev.to_csv(‘yelp_review_full_csv\\dev.tsv’, sep=’\t’, index=False, header=False)****df_bert_test.to_csv(‘yelp_review_full_csv\\test.tsv’, sep=’\t’, index=False, header=True)***
训练 BERT 模型
我们将加载预训练的基于 BERT 的无案例模型权重,并在 Yelp 评论数据集上训练该模型。让我们了解一下我们需要为培训设置的参数。
我们需要训练多类文本分类,因此我们将使用 run_classifier.py 文件。
- task_name :这是我们计划用于培训的任务。选项有
- CoLA :语言可接受性的语料库是一个二元单句分类任务,是 ColaProcessor 类。目标是预测一个英语句子在语言学上是否“可接受”**
- MNLI : 多体裁自然语言推理是一项大规模、众包的蕴涵分类任务。给定一对句子,目标是预测第二个句子相对于第一个句子是蕴涵、矛盾还是中性的
- MRPC:微软研究院释义语料库由从在线新闻来源自动提取的句子对组成。目标是检查句子对中的句子是否语义等价
- XNLI:跨语言自然语言推理使用了 15 种语言的跨语言句子分类。
2. do_train :设置为 True 进行训练。这将使用 train.tsv 文件进行训练
3. do_eval :设置为 True 进行评估。这将使用 dev.tsv 文件进行评估
4. data_dir :包含数据的目录。tsv 文件
5. vocab_file :指定 vocab.txt 文件。Vocab.txt 使用 BERT 提供的 Vocab 文件将单词映射到索引。词汇表有 119,547 个单词块标记
6. bert_config_file :包含 bert 模型的参数值。伯特预训练模型有这个文件
7. init_checkpoint :初始检查点,通常从预先训练好的检查点开始。如果您是从中断的地方恢复训练过程,或者训练被中断,则提到最后一个检查点文件名。
8. max_seq_length :已发布的模型使用最长 512 的序列长度进行训练,但是您可以使用更短的最大序列长度进行微调,以节省大量内存。更长的序列非常昂贵,因为注意力与序列长度成二次关系。短于指定长度的序列被填充
9. train_batch_size :训练的总批量。内存使用量也与批处理大小成正比。默认值为 32。仅为培训指定此参数。
10.learning _ rate:Adam 的初始学习速率。默认学习率为 0.00005。仅为培训指定此参数。
11. num_train_epochs :要执行的训练总次数。仅为培训指定此参数。
12. output_dir :输出目录,其中将写入模型检查点以及评估数据集的细节。您需要在为训练或推理指定该目录之前创建它。
13. do_lower_case :是否对输入文本进行小写处理。对于无套管模型应为真,对于有套管模型应为假。指定仅用于培训。
14. save_checkpoints_steps :指定保存模型检查点的频率。指定仅用于培训。
对于培训,请在命令提示符下使用以下命令
***python run_classifier.py**
--**task_name=cola**
--**do_train=true**
--**do_eval=true**
--**data_dir=\yelp_review_full_csv\**
--**vocab_file=\BERT\uncased_L-12_H-768_A-12\uncased_L-12_H-768_A-12\vocab.txt**
--**bert_config_file=\BERT\uncased_L-12_H-768_A-12\uncased_L-12_H-768_A-12\bert_config.json**
--**init_checkpoint=\BERT\uncased_L-12_H-768_A-12\uncased_L-12_H-768_A-12\bert_model.ckpt**
--**max_seq_length=64**
--**train_batch_size=2**
--**learning_rate=2e-5**
--**num_train_epochs=3.0**
--**output_dir=\BERT\bert_output\**
--**do_lower_case=True**
--**save_checkpoints_steps 10000***
训练完成后,您可以看到包含开发数据集摘要的检查点文件和 eval_results.txt 文件
***eval_accuracy = 0.71553844
eval_loss = 1.035305
global_step = 1287000
loss = 1.0362284***
预测情绪
为了预测情绪,我们设置以下参数并将 — do_predict 参数设置为 True。
- 任务名称:应该与用于训练数据集的任务名称相匹配
- data_dir :指定包含 test.tsv 文件中数据的目录
- vocab_file :指定 vocab.txt 文件。Vocab.txt 使用 BERT 提供的 Vocab 文件将单词映射到索引。
- bert_config_file :包含 bert 模型的参数值。伯特预训练模型有这个文件
- init_checkpoint :初始检查点。这是输出目录中模型检查点文件的最大数量。
- 最大序列长度:指定最大序列长度。
- output_dir :将测试结果写入 test_results.tsv 文件的输出目录
***python run_classifier.py**
**--task_name=cola
--do_predict=true
--data_dir=\yelp_review_full_csv\
--vocab_file=\BERT\uncased_L-12_H-768_A-12\uncased_L-12_H-768_A-12\vocab.txt **
**--bert_config_file=\BERT\uncased_L-12_H-768_A-12\uncased_L-12_H-768_A-12\bert_config.json**
**--init_checkpoint=\BERT\bert_output\model.ckpt-1085250
--max_seq_length=128
--output_dir=\BERT\bert_output\***
评估测试结果
测试结果在文件 test_results.tsv 的输出目录中,您可以将它与测试标签进行比较,并评估我们的多类文本分类的性能
阅读并解释结果
每个文本的结果在 test_results.tsv 文件中都有一行,其中包含五个标记类中每一个的概率。
我们需要找到概率最高的类,这将是 Yelp 评论的观点
***import csv
label_results=[]
pd.DataFrame()
with open('\BERT\bert_outout\test_results.tsv') as file:
rd = csv.reader(file, delimiter="\t")
for row in rd:
data_1=[float(i) for i in row]
label_results.append(data_1.index(max(data_1)))
df_results=pd.DataFrame()
df_results=pd.DataFrame(label_results)
df_results[0]***
现在我们为从 0 到 4 的情感范围生成混淆矩阵
***from sklearn.metrics import confusion_matrix
confusion_matrix(data_test[0], df_results[0])***
混淆矩阵
我已经在一个时期训练了 BERT 模型,你可以看到对于多类文本分类来说结果看起来不错
*from sklearn import metrics
print("Accuracy",metrics.accuracy_score(data_test[0], df_results[0]))
print("F1-Score",metrics.f1_score(data_test[0], df_results[0],average='weighted'))*
参考资料:
这是一个 24 个较小的 BERT 模型的版本(只有英语,未封装,用单词屏蔽训练),参考…
github.com](https://github.com/google-research/bert)
https://MC . ai/a-guide-to-simple-text-class ification-with-Bert/*
基于 BERT 深度学习的多类文本分类
图片来源:Pexels
自然语言处理,自然语言处理,拥抱脸
大多数研究人员将他们的研究论文提交给学术会议,因为这是一种更快捷的公布结果的方式。寻找和选择一个合适的会议一直具有挑战性,尤其是对年轻的研究人员来说。
然而,根据以前的会议进展数据,研究人员可以增加论文被接受和发表的机会。我们将尝试使用 BERT 用深度学习解决这个文本分类问题。
几乎所有的代码都取自这个教程,唯一的区别就是数据。
数据
数据集包含 2507 篇研究论文标题,已被人工分类为 5 类(即会议),可从此处下载。
探索和预处理
conf _ explorer . py
表 1
df['Conference'].value_counts()
图 1
你可能已经注意到了我们的班级不平衡,我们将在稍后解决这个问题。
给标签编码
标签 _ 编码. py
df['label'] = df.Conference.replace(label_dict)
培训和验证分割
因为标签是不平衡的,我们以分层的方式分割数据集,用它作为类别标签。
拆分后,我们的标签分布将如下所示。
训练 _ 测试 _ 拆分. py
图 2
BertTokenizer 和编码数据
记号化是将原始文本分割成记号的过程,记号是表示单词的数字数据。
- 构造一个 BERT 记号化器。基于文字部分。
- 实例化一个预训练的 BERT 模型配置来编码我们的数据。
- 为了将所有的标题从文本转换成编码形式,我们使用了一个名为
batch_encode_plus
的函数,我们将分别处理训练和验证数据。 - 上述函数中的第一个参数是标题文本。
add_special_tokens=True
表示序列将使用与其模型相关的特殊标记进行编码。- 当将序列批处理在一起时,我们设置了
return_attention_mask=True
,因此它将根据由max_length
属性定义的特定标记器返回注意掩码。 - 我们还想填充所有的标题到一定的最大长度。
- 我们实际上不需要设置
max_length=256
,只是为了安全起见。 return_tensors='pt'
返回 PyTorch。- 然后我们需要将数据拆分成
input_ids
、attention_masks
和labels
。 - 最后,在我们得到编码数据集之后,我们可以创建训练数据和验证数据。
tokenizer_encoding.py
BERT 预训练模型
我们将每个标题视为其唯一的序列,因此一个序列将被归类到五个标签之一(即会议)。
bert-base-uncased
是一个较小的预训练模型。- 用
num_labels
表示输出标签的数量。 - 我们其实并不关心
output_attentions
。 - 我们也不需要
output_hidden_states
。
BERT_pretrained_model.py
数据加载器
DataLoader
组合数据集和采样器,并在给定的数据集上提供可迭代的。- 我们使用
RandomSampler
进行训练,使用SequentialSampler
进行验证。 - 鉴于我的环境内存有限,我设置了
batch_size=3
。
data_loaders.py
优化器和调度器
- 要构建一个优化器,我们必须给它一个包含要优化的参数的 iterable。然后,我们可以指定特定于优化器的选项,如学习率、ε等。
- 我发现
epochs=5
很适合这个数据集。 - 创建一个学习率从优化程序中设置的初始学习率线性降低到 0 的调度,在此期间,学习率从 0 线性增加到优化程序中设置的初始学习率。
优化程序 _ 调度程序. py
性能指标
我们将使用 f1 分数和每节课的准确度作为性能指标。
performance_metrics.py
训练循环
培训 _loop.py
图 3
加载和评估模型
loading_evaluating.py
图 4
Jupyter 笔记本可以在 Github 上找到。享受余下的周末吧!
回归中的多重共线性
为什么这是个问题?如何检查和修理
来源:by @jjying 来自 unsplash
当回归模型中的独立变量彼此高度相关时,会发生多重共线性。这使得很难解释模型,并且还产生过拟合问题。人们在选择回归模型中的变量之前会进行测试,这是一个常见的假设。
我以前在为时间序列数据构建回归模型时遇到过严重的多重共线性问题。我根据不同的时间段创建了多个特征,如 1 个月的总回报、6 个月的总回报和 1 年的总回报,以获得更多的输入变量。然而,这些特征彼此高度相关。例如,如果一只股票在过去一年表现良好,那么它很可能在最近一个月表现良好。我需要放弃这些变量中的一些,或者找到一种方法使它们不那么相关。我将在文章的后面解释解决这个问题的不同方法。
为什么多重共线性是一个问题?
当独立变量高度相关时,一个变量的变化会引起另一个变量的变化,因此模型结果波动很大。如果数据或模型发生微小变化,模型结果将会不稳定且变化很大。这将产生以下问题:
- 如果模型每次给你不同的结果,你将很难选择模型的重要变量列表。
- 系数估计不稳定,你很难解释这个模型。换句话说,如果你的一个预测因子改变了 1 个单位,你就无法判断输出的变化程度。
- 模型的不稳定性可能导致过度拟合。如果将该模型应用于另一个数据样本,则与训练数据集的准确性相比,准确性会显著下降。
根据具体情况,如果仅出现轻微或中等程度的共线性问题,则对于您的模型来说可能不是问题。但是,如果存在严重的共线性问题(例如,两个变量之间的相关性> 0.8 或方差膨胀因子(VIF) >20),强烈建议解决该问题
如何检查是否出现多重共线性?
第一个简单的方法是画出所有自变量的相关矩阵。
我用了 Kaggle 竞赛的住房数据。竞赛的目标是使用房屋数据输入来正确预测销售价格。我在这里选择了一些数值变量来包含在我的模型中。
#plot color scaled correlation matrix
corr=house_selected.corr()
corr.style.background_gradient(cmap='coolwarm')
住房数据的彩色标度相关矩阵
在绘制相关矩阵并对背景进行颜色缩放后,我们可以看到所有变量之间的成对相关性。我还在这里加入了因变量“销售价格”。这是因为当我试图选择包含在模型中的独立变量时,这是我的一个秘密技巧。
当你不知道模型中包含哪些变量时,只需做一个相关矩阵,选择那些与因变量高度相关的自变量。
回到多重共线性问题,我们可以看到,从相关矩阵中,有相当多的变量是相互关联的。有一对相关系数大于 0.8 的自变量是地下室总表面积和一层表面积。具有较大地下室面积的房屋往往也具有较大的一楼面积,因此高相关性是可以预期的。
检查多重共线性的第二种方法是对每个自变量使用方差膨胀因子(VIF)。它是多重回归变量集合中多重共线性的度量。VIF 值越高,该变量与其他变量的相关性越高。
#Compute VIF data for each independent variable
from statsmodels.stats.outliers_influence import variance_inflation_factor
vif = pd.DataFrame()
vif["features"] = house_selected.columns
vif["vif_Factor"] = [variance_inflation_factor(house_selected.values, i) for i in range(house_selected.shape[1])]
vif
住房模型数据的 VIF 结果-原始
如果 VIF 值高于 10,通常被认为与其他自变量有很高的相关性。然而,接受范围受到要求和约束。从结果中,我们可以看到大多数特征与其他自变量高度相关,只有两个特征可以通过低于 10 的阈值。
如何修复多重共线性问题?
- 变量选择
最直接的方法是删除一些与其他变量高度相关的变量,将更重要的变量留在集合中。例如,当我们绘制包含“销售价格”的相关矩阵时,我们可以看到整体质量和地面居住面积与因变量“销售价格”的相关性最高,因此我将尝试将它们包含在模型中。
住房模型数据的 VIF 结果-选择后
我们可以看到,使用简单的消去法,我们能够显著降低 VIF 值,同时保留重要的变量。然而,一些变量如整体质量和建造年限仍然有很高的 VIF 值,它们在预测房价时很重要。**如何?**有时我们可以使用第二种方法中描述的小技巧来转换变量。
2.变量转换
第二种方法是转换一些变量,使它们不那么相关,但仍然保持它们的特征。我这么说是什么意思?在房屋模型示例中,我可以通过用建造年份减去当前年份,将“建造年份”转换为“房屋年龄”。例如,如果建筑年份是 1994 年,那么房子的年龄是 2020–1994 = 26 年。
住房模型数据的 VIF 结果-转换为 house_age 后
在我将建筑年限转换为房龄后,新的“房龄”因子的 VIF 下降到一个可接受的范围,整体质量的 VIF 值也下降了。
在我开始提到的时间序列分析的例子中,我也转换了变量,使它们不那么相关。例如,过去 1 个月的总回报与过去 6 个月的总回报高度相关。我从过去 6 个月的回报中减去过去 1 个月的回报,得到不包括过去一个月的前 5 个月回报的新变量。相关性结果更容易接受,我能够将这两个变量作为我的模型特征。
3.主成分分析
主成分分析(PCA)通常用于通过将数据分解成多个独立的因子来降低数据的维度。它有许多应用,如通过减少预测因子的数量来简化模型计算。然而,在我们的例子中,我们将只使用 PCA 的变量独立性来消除模型中的多重共线性问题。
#Create the new data frame by transforming data using PCA
import numpy as np
from sklearn.decomposition import PCA
pca = PCA(n_components=6)
components=pca.fit_transform(house_adjusted)
componentsDf=pd.DataFrame(data=components,columns=['component 1','component 2','component 3','component 4','component 5','component 6'])#Calculate VIF for each variable in the new data frame
vif = pd.DataFrame()
vif["features"] = componentsDf.columns
vif["vif_value"] = [variance_inflation_factor(componentsDf.values, i) for i in range(componentsDf.shape[1])]
vif
住宅模型数据的 VIF 结果 PCA 转换后
与原始数据相比,我仍然保留相同数量的变量,我们可以看到,现在这 6 个变量彼此完全不相关。我们可以用新的 6 个变量作为自变量来预测房价。
这种方法的弊端也非常明显。在 PCA 变换之后,我们没有每个变量的同一性,并且将很难解释结果。
结论和建议
在建立回归模型之前,我们每次都应该检查多重共线性的问题。VIF 是一种简单的方法,可以观察每个独立变量,看它们是否与其他变量高度相关。当您不确定为模型选择哪些变量时,相关矩阵将有助于选择重要的因素。相关矩阵还有助于理解为什么某些变量具有高 VIF 值。
就修复多重共线性问题的方法而言,我个人不喜欢这里的 PCA,因为模型解释将会丢失,当您想要将模型应用于另一组数据时,您需要再次进行 PCA 转换。因此,我们应该尽最大努力通过选择正确的变量来减少相关性,并在需要时进行转换。当变量具有相对较高的 VIF 值,而且对预测结果也很重要时,您可以决定是否保留该变量。试错法总是包括不同的变量集,建立模型并根据测试数据进行测试,以查看是否有任何过度拟合。
你认为在构建模型之前,你已经完成了所有的统计假设检查了吗?不,你不是!如果你想了解更多关于回归模型中的其他统计假设,请参考我下面的另一篇关于回归模型中的正态假设的文章。
博克斯-考克斯变换,夏皮罗-维尔克检验,QQ 图
towardsdatascience.com](/is-normal-distribution-necessary-in-regression-how-to-track-and-fix-it-494105bc50dd)