TowardsDataScience 博客中文翻译 2020(七百一十七)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

预测于达维什投球不砸垃圾桶

原文:https://towardsdatascience.com/predicting-yu-darvishs-pitching-without-hitting-the-trash-can-779903507faa?source=collection_archive---------75-----------------------

使用机器学习来猜测他的下一个投球

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者图片

介绍

据报道,一桩丑闻震惊了棒球界,太空人队在 2017 赛季期间使用电子设备窃取了对方球队的标志,包括世界职业棒球大赛,最终他们赢得了冠军。俞达维是受害者之一。他有一个稳定的常规赛,他在季后赛早期为狗队投得非常好。然而,在世界系列赛对阵太空人的比赛中,事情发生了变化。他在两场比赛的 3.1 局中失了 9 分,包括第七场比赛,当时他在 1.2 局中投了 47 球,失了 5 分,为太空人队赢得了最后的胜利。球迷责怪他,赛季结束后他被交易到小熊队。

两年后,太空人用相机偷了他的投球手势,并在比赛期间敲垃圾桶暗示击球手。所以基本上击球手知道达维什要投什么球,这可能是他在世界大赛中比其他球队表现差的原因。(背景故事:https://www . the ringer . com/MLB/2020/3/9/21170990/astros-sign-stealing-dodgers-world-series-Yu-darvish-Clayton-kershaw)

我很好奇有没有必要用摄像头非法盗签,有没有可能根据他的投球历史推断出他的投球?

在这次调查中,我想回答以下问题:
1 .他最擅长投哪种类型的球?
2。当他需要好球时,他投的是什么类型的球?(二击三球情况)
3。他在不同的情况下有不同的投球策略吗(0 打 0 球,2 打 3 球…,出局,一局等)。
4。有没有可能根据他的投球历史训练一个机器学习模型来预测他的投球?

探索性数据分析

资料组

用于分析的数据集包含 8221 个来自于 Darvish 的音高。数据是从 https://baseballsavant.mlb.com/下载,并为调查争论不休。
另一个数据集包含他的 2017 年季后赛数据,用来测试模型。

音调击穿

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1 他的音高变化。

他口袋里有很多武器,总共 9 种音高类型。他投出 33.3%的 4 缝线和 15.8%的 2 缝线快速球,21.1%的切球和 20%的滑球。他使用他的曲球,手指分开,变速球,指节曲线和低于 10%的 ephus。

现在让我们来分析他在不同比赛条件下的投球。

罢工

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2 不同打击条件下他的音高变化。

当没有好球时,他增加他的四缝线快速球百分比,当有两个好球时,他增加他的滑球。他似乎也增加了 2 击时的破发率

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3 他在不同球况下的投球分解。

除了 3 球以外,在不同球况下没有非常明显的差异。他倾向于使用四缝线快速球,避免使用弧线球、指叉球和变速球。

在外

出局怎么样?他投球不同吗?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4 他在不同出局数的音高变化。

嗯,不太清楚是否有显著差异。

让我们把好球和出局结合起来。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5 他在不同击球、球和界外球时的投球情况。

该图对不同的条件进行了更深入的探究。比如他在面对 2 击 0 球的时候,还是倾向于投 4 缝快球,但是球多了,他就增加了他的滑球百分比。

这个数字可能是有用的参考,但是,它只考虑了三个特点,罢工,球和出局。让我们尝试建立一个机器模型,以包括用于预测的其他特征。

机器学习模型

在特征工程之后,我加入了之前投球的结果,以及每场比赛的投球数。结合数据集中的一些原始特征,我对模型使用了以下特征,并对分类变量进行了一次性编码。

str_list=['stand', 'pre_description','pre_pitch']
num_list=['balls','strikes','outs_when_up','inning',
        'home_away', 'score', 'other_score', 'score_diff',
 'pre_speed','pre_hd', 'pre_l_s', 'pre_l_a','on_3b', 'on_2b','on_1b','p_count']

2017 年季后赛的结果将用于测试模型,因此我用一个天真的猜测建立了一个基线。我选择他在训练数据集中投得最多的 4 缝线快速球作为测试数据集的预测,并与实际投球进行比较。我得到了 27.16%的准确率。

结果

我建立了一个随机森林模型来预测结果,没有太多的调整,通过交叉验证,我得到了 36.20 +/- 5%的准确率,在测试数据集上的准确率为 37.31%。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

随机森林预测的混淆矩阵。

基于混淆矩阵,模型误预测了很多滑球到 4 缝线快速球。尽管这个数字看起来很低,但仍然比一个天真的猜测高出 30%。

结论

随机森林模型提供了比天真猜测(27%)更好的预测(37%),但是仍然不能完美地预测他的音高。我认为仍有改进的空间,例如,更好的特征工程,或包括特定击球手的投球历史。但我认为不可预测的球场是他成为伟大球员的原因之一。而棒球的不可预测性真的是棒球比赛的乐趣所在。

新冠肺炎数据的预测和分析:模型—建议算法 Vuong 模拟器

原文:https://towardsdatascience.com/prediction-and-analysis-of-covid-19-data-model-proposal-algorithm-vuong-simulator-2b05d1bded7e?source=collection_archive---------56-----------------------

数据科学—新冠肺炎—可视化—编程

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片由 Thuy Chung Vuong 拍摄

如何发现未被发现的新冠肺炎感染病例?

编者按: 走向数据科学 是一份以数据科学和机器学习研究为主的中型刊物。我们不是健康专家或流行病学家,本文的观点不应被解释为专业建议。想了解更多关于疫情冠状病毒的信息,可以点击 这里

为了加入对抗新冠肺炎·疫情的战斗,我做了我个人的数据预测研究,并根据我在数据处理和电子学方面的经验进行了分析。由于我的资源有限,我当然只能使用我的 Surface 笔记本电脑、我的 Raspberry PI 和开源社区的软件,但我想报告一个新的结果:一种用于估计未发现感染的算法,使用我的“新冠肺炎数据分析的 Vuong 模型”,其实现的软件可以在这里下载。

新冠肺炎数据分析中的一个重要且具有挑战性的研究目标是寻找未发现的感染病例数。字),因为病毒的传播,新型冠状病毒是非常复杂和未知的。在冠状病毒潜伏期(从接触到出现症状的时间)之后,病毒可能会从一个人传播到另一个人。有报道称,一个无症状(无症状)的人可以将新型冠状病毒病毒传播给另一个人(例如“全球范围内感染冠状病毒的巨大无症状库”)。冠状病毒患者在明显康复后可能会再次感染该病毒(最新好消息"新数据表明人们不会再次感染冠状病毒,2020 年 5 月 19 日)

SIR 模型

已经有许多数据模型用于分析和模拟新冠肺炎疫情来计算感染病例数。一个已知的非线性模型是 SIR 模型[ker Mack-McKendrick 理论,1927,1928,1932]: S 为易感人数, I 为传染人数, R 为痊愈或死亡(或免疫)人数。r 也可称为“抗”或“除”。

从真实数据,即当前每天新增的感染病例(新病例)中,使用 SIR 模型的微分方程来优化 SIR 模型的函数 I (t)的参数“β”和“γ”,从而可以找到 I(t)的每个时间点的感染人数(见图 1)。

  • β“β”是感染易感人群的比率。
  • γ“γ”是感染者变得有抵抗力的比率。

您可以找到许多 SIR 模型可视化的软件包,例如[mattravenhall/BasicSIRModel]和优化β率和γ率以找到 I(t),用于估计感染人数。,如 Brian Collins,新冠肺炎的动态建模

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图一。优化β率和γ率以找到 I(t),用于估计感染人数

SIR 模型的优化有一些批评点:

  • 该模型只有两个参数β和γ率,这可能不足以模拟新冠肺炎疫情。
  • 医学和病毒学家还没有发现很多其他的参数。
  • SIR 模型作为一个封闭系统被采用。假设 N = S + I + R 随时间保持不变。在现实世界中,我们有一个开放的系统,随着时间的推移,N 不是常数,因为人们在移动,病毒可能通过空气传播。

因此也有[ 詹姆士·扬松新冠肺炎造型不对的评论

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2 新冠肺炎数据分析对 CODVID-19 数据预测分析的 Vuong 模型。

新冠肺炎数据分析的 VUONG 模型

因此,我想报告我的建议模型:用于新冠肺炎数据分析的 Vuong 模型,以预测和分析 CODVID-19 数据。

新冠肺炎数据函数中的时间值 t 是日期和时间(参见 Python 文档:“日期时间模块”)。因此它们是离散值,所以函数 y (t)是一个“时间序列”。我在这里用 y[x]代替 y (t ),因此 x 是日期时间。这使得以后的编程和绘图更加容易。

我们现在开始描述用于新冠肺炎数据分析的 Vuong 模型(见图 2)。

输入:

  • nc[x] 是每日确诊感染病例数,即“新增病例”。
  • nd[x] 为每日死亡人数。

产出:

  • I[x] 是每日感染病例的估计数。
  • G[x] 是每日恢复病例的估计数(germ。Gesund Fä lle)。

参数表将会很长,并且仍然是未知的。这里只列出了重要的已知参数:

在 Vuong 模型中,我实现了两个参数:潜伏期和恢复期

估计感染病例的概念有 3 个步骤:

第一步

从每日新感染病例 nc[x]中,我们将计算预测函数 Ip [x]。Ip[x]是包括未发现感染者在内的感染者人数。与 SIR 模型优化相比,我使用了一个额外的参数——潜伏期τ。

Ip [x] = nc [x,Tau]

Tau:潜伏期。潜伏期过后,病毒会传染给另一个人。潜伏期估计在 2-14 天之间。

第二步:

恢复函数 G [x]已根据步骤 1 中的 Ip[x]、ndx和 RG 参数计算得出:

G [x] = g [Ip [x],nd [x],RG)

RG 是恢复期,不是 R 系数。RG 是一个感染者痊愈的时间。对于轻度病例,RG 可能是 14 天,对于严重病例,大约是 30 天(冠状病毒:需要多长时间才能恢复?、BBC 新闻)

第三步:

根据预测函数 Ip[x]的数量计算最终估计的每日感染病例数,预测函数 Ip[x]已从步骤 1 中导出,并排除了来自步骤 2 的恢复估计病例。

I [x] = Ip [x] — G [x]

现在让我们来看看细节吧!

Vuong 算法在新冠肺炎数据预测中的应用

传染病例数的预测 Ip[x]:

预测函数 Ip [x]取决于 ncx和潜伏期τ。

对于每个 Ip [x],都有一个 r[x-1],即复制因子。这意味着在时间点 x 的感染病例数 Ip [x]是在前一时间点 x-1 的病例数 nc[x-1]的 r[x-1]倍。

例如:在时间 x-1,有 100 个感染病例(Ip[x-1] = 100),生殖因子将是 5 倍(r[x-1] = 5),那么第二天将有 500 个感染病例(Ip [x] = 500)。

Ip [x] = r [x-1] * Ip [x-1] (1)

r[x-1]:Ip[x]的再现因子。

从(1)中,可以计算出:

Ip[x-1]= r[x-2] r[x-3] r[x-1-n]…。 r [x-N] Ip [x-1-N ]* (2)

n = 0,…,N,N 是用于计算的 Ip 值的数量

假设:所有 r[x-1-n]在时间间隔 N 中是相同的

Ip [x-1] = (R ** N)。Ip [x-1-N] (3)

R**N: R 指数 N

根据新冠肺炎的信息,我们知道在潜伏期τ之后,一个人可以将他的病毒传染给另一个人。

可以说 Ip[x-1-N]患者在潜伏期后会将病毒传染给其他人。这意味着 R 在时间点 x-1-N-τ之前不会激活。接下来是:

R * Ip[x-1]=(R * (N-Tau)) Ip[x-1-N](4)

(N-Tau-1)log R = log(Ip[x])—log(Ip[x-1-N](5)

对于 Ip [x]的估计,我们只需从时间间隔{x / x= x-1,…中取 2 个数 nc[x-1]和 nc[x-1-N]。x-1-N}

然后我们从 log R 计算 R

log R =(log(NC[x])—log(NC[x-1-N])/(N-Tau-1)(6)

R = 10 ** log R

R 是繁殖因子。

然后估计感染病例数 Ip[x]:

Ip [x] = R * nc[x-1] (7)

编程概念:

Vuong 算法已经在 tavuong_simulator.py 中实现

对于实际编程,我们在 x 轴 x = 0 上运行长度为 N 的“窗口”,开始时间为[x-1],结束时间为[x-1-N]。…在等式(5)中,我们只需要 2 个值 nc[x-1]和 nc[x1-N]。但是,这些值可以是 0(零)。因此我们必须添加额外的规则来避免 log (0)的计算:

计算 Ip 和 R 在两个场的两个向量中,Ip [x]和 R [x]

nc[x]的前 N 个值用作被调用 Ip [x]的起始值。

Ip [x] = nc [x],对于 x = 0… N-1

后 x > N:

如果 nc [x] = 0 且 nc [x-1-N]!= 0,即在过去有过感染,我们取 R [x] = R [x-1]

如果 nc [x] = 0 且 nc [x-1-N] = 0,即 nc [x]中有感染,我们取 R [x] = 0

如果 nc [x]!= 0 和 nc [x-1-N]!= 0,即过去有感染,我们取 R [x] =计算值(s .等式(6))

如果 nc [x]!= 0 且 nc [x-1-N] = 0,即在过去有感染,我们取 R [x] = R [x-1]

恢复功能 G[x]

G [x]:恢复函数,取决于 ncx、ndx和恢复期 RG

根据对冠状病毒的了解,在 RP 恢复期后,感染者要么康复,要么死亡。在时间 x-RP 中被感染的人数将是死亡的(nd[x])或康复的。

G [x] = nc[x-GP] — nd[x ] (8)

估计感染病例数

最后,你可以估计仍然存在的感染病例

I [x] = Ip [x] — G [x] (9)

新冠肺炎—vuongsulator . py

我已经使用 Python 开发工具包平台"TAV uong/covid 19-data KIT "开发了用于新冠肺炎数据分析的 vuong 模型,详细描述可以在 Readme.md 或我的上一篇论文中阅读,所以我在这里简单描述一下。

安装和启动

$ github 克隆https://github.com/tavuong/covid19-datakit.git

$ pip 安装费用

$ pip 安装 Matplotlib

$ cd ~ \ covid19-datakit \

$ python。\ covid 19-vuong simulator . py[通过 PC]

$ python3。\ covid 19-vuong simulator . py[由树莓 PI 提供]

此示例向您展示了如何启动 covid 19-vuongsulation 并通过其对话框给出参数。您可以使用项目的[数据文件夹](http://tavuong / covid19-datakit/data)中的测试数据或您的数据,

$ CD ~ \ covid 19-数据套件\

$ python。\ covid 19-vuong simulator . py[通过 PC]

VMODEL >国家?世界

VMODEL > new_case-file?。/data/new_cases.csv

死亡文件?。/data/new_deaths.csv

VMODEL > VuongSimualtion 模式?6

VMODEL >潜伏期?七

VMODEL >恢复期?14

然后它将绘制和打印结果

Vuong_Simulator >确认信息。= 5555708

Vuong_Simulator >Incub。P =7/预计。inf。=5937024

Vuong_Simulator >Reco。P =14/预计。恢复=4233977

Vuong_Simulator >Reco。P =14/预计。Inf。=1703047

Vuong_Simulator >死亡人数= 350212

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3 https://ourworldindata.org/coronavirus-source-data 新冠肺炎数据【世界】分析,数据来源:

您可以使用这个命令行来启动 Vuong 模拟器,以获得相同的结果

$ python。\ covid 19-vuong simulator . py-c World-o test.png-m ta-n . \ data \ new _ cases . CSV-d . \ data \ new _ deaths . CSV-g 0.98-r 14-t 7-s 6

刚刚通过以下选项实施:

$巨蟒。\ covid 19-vuong simulator . py-h

-n <new_cases_file>-d <new_deaths_file>-o 输出文件</new_deaths_file></new_cases_file>

-c 国

-t 潜伏期τ

-r 恢复期

-s 模拟模式

程序根据模拟模式进行计算和绘图。只有在模式 1 中是时间功能,在其他模式中,显示时间功能的累积

Vuong 模型后的 R 系数(开发中)

2:确诊感染 nc[x] —死亡 nd [x]

3:确认感染 nc[x] /恢复函数 G[x]

/最终估计感染人数 I[x]/死亡人数 nd [x]

4:确认感染 nc[x] —恢复函数 G[x]

死亡人数

5:确认感染 nc[x] /估计感染 Ip[x]

/最终估计感染人数 I[x]/死亡人数 nd [x]

6:确认感染 nc[x] /估计感染 Ip[x]

/恢复函数 G[x]

/最终估计感染人数 I[x]/死亡人数 nd [x]

示例命令

$ python。\ covid 19-vuongssimulator . py-c“美国”-o test.png-m ta-n . \ data \ new _ cases . CSV-d . \ data \ new _ deaths . CSV-g 0.98-r 14-t 7-s 6

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4 美国新冠肺炎数据分析,数据来源:https://ourworldindata.org/coronavirus-source-data

用新冠肺炎-冯氏模拟程序预测未发现的感染病例

Vuong 算法用于分析新冠肺炎数据,这些 CSV 文件可从这里的开源下载。我想对影响的全球 213 个国家和地区或城市进行分析,例如加州或纽约或杜塞尔多夫,但我能力有限。所以我用 Vuong 模拟器分析了一些国家的新冠肺炎数据:意大利、德国、瑞典、美国和“世界”,你可以在图 5 中看到结果

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5 新冠肺炎分析-义大利、德国、瑞典、美国的数据。数据来源:【https://ourworldindata.org/coronavirus-source-data

通过使用我提出的算法进行测试分析,我发现了一些关于冠状病毒疫情的有趣预测:

  • 在意大利和德国,疫情已经大大降低(图 5)。
  • 在美国,疫情已经开始减少(图 4)。
  • 在瑞典,疫情仍在扩张(图 5)。
  • 对世界来说,第二次危机(第二波)即将到来(图 3)。

摘要

开发了用于新冠肺炎数据分析的 Vuong 模型中的算法,以从确诊病例和死亡数据中搜索未发现的感染病例。Vuong 算法是基于一个开放系统,使用额外的新冠肺炎疫情信息和离散数学。这可能是众所周知的 SIR 模型优化方法的替代解决方案。

你可以下载软件“covid 19-Vuong Simulator”集成到开发套件中,用默认测试开源新冠肺炎数据或你的数据来分析未发现的感染病例。

covid19 数据的可视化和建模一直在不断发展,未来还会更新。如果您开发了一个新的有趣的模型-模块或演示-模块,请不要犹豫联系我进行咨询开发,也许可以将您的模块贡献给开源和麻省理工学院许可的项目TAV uong/covid 19-data kitoverGithub

玩得开心!

新冠肺炎数据致谢:汉娜·里奇

综述鸣谢:简范博士教授

感谢支持和咖啡蛋糕的动力:我的妻子 Thi Chung Vuong

超出和结束可用数据的预测

原文:https://towardsdatascience.com/prediction-beyond-and-end-of-the-available-data-653a9a935549?source=collection_archive---------17-----------------------

回归分析和未来价格预测

分析金融时间序列的机器学习算法

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者图片

https://sarit-maitra.medium.com/membership

P 预测超越样本数据进入未来的复杂任务;特别是当我们处理来自高频交易的金融数据的随机时间序列时。机器学习模型的预测性能通常是这样进行的

  1. 通过将给定数据集分割成样本内周期;用于初始参数估计和模型选择;
  2. 样本外期间用于评估预测性能

与样本内的表现相比,样本外的预测表现通常被认为更可信,更基于经验证据。样本内性能往往对异常值和数据挖掘更敏感。样本外预测也能更好地反映实时可用的信息。但是,可以注意到,样本内收益的可预测性并不一定意味着样本外收益的可预测性。关键是,从训练集中学习的模型,是否能够推广新的数据。

让我们探索一下,看看我们现实生活中的案例研究是如何在从未见过的数据场景中工作的。我们将使用道琼斯工业指数数据进行调查。

数据加载:

df = web.DataReader('^DJI', data_source = 'yahoo', start = '2000-01-01')
print(df.head()); print('\n'); print(df.shape)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

实际价格可视化:

dataset = df.copy()
fig = go.Figure(data=[go.Candlestick(x=dataset.index, open=dataset['Open'], high=dataset['High'], low=dataset['Low'], close=dataset['Close'])])
fig.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

每日回报的经验分位数:

由于风险价值(VaR)的广泛使用,分位数预测对风险管理决策至关重要。它是两个因素的产物

  1. 波动预测,以及
  2. 波动预测的分位数。

使用经验分位数的每日风险值:

假设:日收益率呈正态分布。我们可以看到日收益率的分布图,如下所示。

方法:通过曲线拟合来分析分位数的历史数据,这里,学生的 t 分布

dataset['daily_return'] = dataset['Adj Close'].pct_change()
round(dataset["daily_return"],2).quantile(0.05)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

每日回报的 0.05 (p=0.05)经验分位数在-0.02(0.05 分位数是第 5 个百分位数)。

  • 有 95%的信心,我们最大的每日损失不会超过投资的 2%
  • *如果我们在€投资 100 万英镑,我们一天的 5%风险值是 0.02 €1 万英镑=€2 万英镑

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从上面的图中可以看出,高斯白噪声具有恒定的波动性。高波动性和低波动性的时期以及回报的极端波动性。此外,我们还可以看到波动是如何依赖于时间的;高波动期持续存在,低波动期持续存在。

VaR:蒙特卡罗模拟

我们将根据历史波动生成道琼斯价格走势。鉴于这种历史波动性,将会有一点随机性。

用于生成第二天价格的公式:

最后几天的价格,并乘以 1 +随机冲击,这是通过抽取给定历史波动率的分布样本而产生的。

让我们回顾一年前(252 天)的价格。

# resetting index
dataset.reset_index(inplace = True)
dataset = dataset.sort_values(by = 'Date', ascending=True)
print(dataset.loc[[(len(dataset) -252)]]) # closing price 252 days back

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们在这里看到,收盘价是 28745.08 美元。

我们运行一个 10,000 次运行的模拟来获得下面的输出。

days = 252
start_price = 28745.089844 # Taken from above#delta t
dt = 1/252
mu = dataset['daily_return'].mean() # mean return
sigma = dataset['daily_return'].std()  # volatilitydef stock_monte_carlo(start_price, days, mu, sigma):
    price = np.zeros(days)
    price[0] = start_price
    shock = np.zeros(days)
    drift = np.zeros(days)
    for x in range(1,days):
        shock[x]=np.random.normal(loc=mu*dt,scale=sigma*np.sqrt(dt))   drift[x] = mu * dt
        price[x] = price[x-1] + (price[x-1] * (drift[x]+shock[x]))
    return price
plt.plot(stock_monte_carlo(start_price, days, mu, sigma))
plt.xlabel('Days'); plt.ylabel('Price (US$)')
plt.title('Monte-Carlo Analysis for Dow Jones')
plt.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

runs = 10000
simulations = np.zeros(runs)
for run in range(runs):
    simulations[run] = stock_monte_carlo(start_price,days,mu,sigma)[days-1]
q = np.percentile(simulations,1)
plt.hist(simulations, bins = 200)
plt.figtext(0.6,0.8,s="Start price: $%.2f" %start_price)
plt.figtext(0.6,0.7,"Mean final price: $%.2f" % simulations.mean())
plt.figtext(0.6,0.6,"VaR(0.99): $%.2f" % (start_price -q,))
plt.figtext(0.15,0.6, "q(0.99): $%.2f" % q)
plt.axvline(x=q, linewidth=4, color='r')
plt.title(u"Final price distribution for Dow Jones after %s days" %days, weight='bold')
plt.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

上图表明,道琼斯价格自过去一年以来几乎是稳定的;起始 Adj 收盘价格为 28745 美元,超过 10000 次的平均最终价格几乎相同(28759 美元)。红线表示 99%置信区间的风险值。

我们将执行 ML 来预测未来的 Adj Close 价格。让我们做一些对模型性能至关重要的特征工程。

时间序列组件对于分析感兴趣的变量非常重要,以便了解其行为、模式,并能够选择和拟合适当的时间序列模型。另一方面,时间序列预测器可以帮助一些模型识别额外的模式并提高预测的质量。时间序列的组成部分和特征对于解释时间序列的行为、分析其属性、识别可能的原因等都至关重要…Roman Josue de las Heras Torres

特征工程

dq = df.copy()
dq['ho'] = dq['High'] - dq['Open'] 
dq['lo'] = dq['Low'] - dq['Open']
dq['oc'] = dq.Open - dq.Close
dq['hl'] = dq.High - dq.Low
dq['volume_gap'] = dq.Volume.pct_change()
dq['day_of_week'] = dq.index.dayofweek
dq['day_of_month'] = dq.index.day
ema_12 = dq['Adj Close'].ewm(span=10).mean()
ema_26 = dq['Adj Close'].ewm(span=26).mean()
dq['ROC'] = ((dq['Adj Close'] - dq['Adj Close'].shift(5)) / (dq['Adj Close'].shift(5)))*100
delta = dq['Adj Close'].diff()
window = 14
up_days = delta.copy()
up_days[delta<=0]=0.0
down_days = abs(delta.copy())
down_days[delta>0]=0.0
RS_up = up_days.rolling(window).mean()
RS_down = down_days.rolling(window).mean()
dq['rsi'] = 100-100/(1+RS_up/RS_down)
dq['macd'] = ema_12 - ema_26#print(dataset)# lag featuerslags = 3
# Create the shifted lag series of prior trading period close values
for i in range(0, lags):
    dq["Lag%s" % str(i+1)] = dq["Adj Close"].shift(i+1).pct_change()# target variable
future_pred = int(15)
dq['prediction'] = dq['Adj Close'].shift(-future_pred)
dq.head()

相对强弱指数(RSI)和移动平均线收敛 D 收敛(MACD)

感兴趣的可以访问 这里 获取详细的技术指标。

目标变量

我们已经创建了目标变量来预测当前数据集中不可用的未来 15 天的值。

dq = dq.drop(['High','Low','Open','Close','Volume', 'Adj Close'],1)
dq.dropna(inplace=True)# creating X,y set
X = dq.drop(['prediction'],1)
X_fcast = X[-future_pred:] # future prediction set
X = X[:-future_pred] # removing last 15 rows
y = y[:-future_pred]# splitting train/test
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=42)

不,让我们拟合一个线性(OLS)模型作为基础模型,并观察我们得到的模型:

ols = linear_model.LinearRegression().fit(X_train, y_train)
# Explained variance score: 1 is perfect prediction
print('Training Variance score (R^2)', r2_score(y_train, ols.predict(X_train)))
# Explained variance score: 1 is perfect prediction
print('Test Variance score (R^2): ', r2_score(y_test, ols.predict(X_test)))

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

极端梯度推进

我们使用 XGBRegressor 拟合模型,随后检查测试集的置信水平,并获得预测值(15 天)。XGBoost 具有处理数据中缺失值的能力。此外,基于树的算法不需要数据缩放。

reg = XGBRegressor(objective ='reg:squarederror', n_jobs=-1).fit(X_train, y_train)
# Explained variance score: 1 is perfect prediction
print('Variance score: %.2f' % r2_score(y_train, reg.predict(X_train)))
# Explained variance score: 1 is perfect prediction
print('Variance score: %.2f' % r2_score(y_test, reg.predict(X_test)))

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

虽然性能比基本模型有所提高,但是考虑到我们使用了回归算法,我们还没有完全达到。在这一阶段,我们可以回头看看这些功能,并在相关功能上做更多的工作。

一旦我们对准确性感到满意,我们就可以使用单独保存的预测数据进行未来预测。程序如下所示。

prediction = reg.predict(X_fcast)
print('\033[4mExpected Close price for next 15 days\033[0m')
print(prediction); 

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

为了更好地理解,我们需要具有上述值的日期。实际上,我们已经预测了 2 周,如下所示。下面几行代码为获得的预测值生成未来日期。

d = df[['Adj Close']].tail(len(prediction));
d.reset_index(inplace = True)
d = d.append(pd.DataFrame({'Date': pd.date_range(start = d.Date.iloc[-1],
periods = (len(d)+1), freq = 'D', closed = 'right')}))
d = d.tail(future_pred);
d.set_index('Date', inplace = True)
prediction = pd.DataFrame(prediction)
prediction.index = d.index
prediction.rename(columns = {0: 'Forecasted_price'}, inplace=True)
prediction

预期价格

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

形象化

将观察值(过去 2 个月)和预测值(未来 1 个月)相加的图有助于我们了解模型是否能够从历史数据中捕捉模式。这里的未来预测看起来很现实。

fig = go.Figure()
n = prediction.index[0]
fig.add_trace(go.Scatter(x = df.index[-100:], y = df['Adj Close'][-100:], marker = dict(color ="red"), name = "Actual close price"))fig.add_trace(go.Scatter(x = prediction.index, y = prediction['Forecasted_price'], marker=dict(color = "green"), name = "Future prediction"))
fig.update_xaxes(showline = True, linewidth = 2, linecolor='black', mirror = True, showspikes = True,)
fig.update_yaxes(showline = True, linewidth = 2, linecolor='black', mirror = True, showspikes = True,)
fig.update_layout(title= "15 days days DJIA Forecast",yaxis_title = 'DJIA (US$)',hovermode = "x",hoverdistance = 100, spikedistance = 1000,shapes = [dict(x0 = n, x1 = n, y0 = 0, y1 = 1, xref = 'x', yref = 'paper',line_width = 2)],annotations = [dict(x = n, y = 0.05, xref = 'x', yref = 'paper', showarrow = False,xanchor = 'left', text = 'Prediction')])
fig.update_layout(autosize = False, width = 1000, height = 400,)
fig.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从上面的图中我们可以清楚地看到一个糟糕的预测。

除了在特征上的工作,我们需要重新访问和查看我们的目标变量,该变量在本实验中没有改变,我们这样做可能会导致前瞻偏差。我们可以尝试用 df[‘Adj Close’]做实验。shift(-1),给出未来预测。

当我们准备好实时预测未来时,我们当然应该使用所有可用的数据进行估计,以便使用最新的数据。

摘要

我们可以尝试其他算法,如支持向量或随机森林。虽然,XGB 可以学习更复杂的非线性表示,但需要更多的数据集才能更好地执行。我们没有应用任何基本变量,这里使用的所有预测变量都可能与目标变量有线性关系。

在用于预测问题的监督机器学习算法中,基于树的算法是最好的。这些方法能够通过学习许多简单的规则来捕捉数据中的复杂关系,一次一个规则。

需要应用交叉验证和算法优化技术来最终确定稳健的模型性能。通过观察偏差/方差,我们可以调整过拟合或欠拟合问题;我们也可以引入这里没有练习过的早期停止回合。这将是一个好主意,测试几个其他模型,并可能引入一个最好的模型集合,以检查性能和准确性得分。

此外,出于验证目的保留数据是一个重要的诊断测试,因为它给出了预测未来时可以预期的准确性的最佳指示。出于验证目的,保留至少 20%的数据可能是一个好的做法。但是,在大量数据可用的情况下,坚持 50%也可以尝试。

我这里可以到达

参考文献:

  1. 伯格梅尔、克里斯托弗和何塞·m·贝尼特斯。“交叉验证在时间序列预测评估中的应用”信息科学 191 (2012)
  2. 伯格梅尔、克里斯托弗、罗布·j·海曼和古邦秀。“关于评估自回归时间序列预测的交叉验证有效性的说明。”计算统计&数据分析 120 (2018)
  3. 伯尔曼、普拉比尔、埃德蒙·周和黛博拉·诺兰。"相关数据的交叉验证方法."生物计量学 81.2 (1994)

基于机器学习的养老院综合评分预测

原文:https://towardsdatascience.com/prediction-of-overall-rating-of-a-nursing-home-using-machine-learning-c76871a3a827?source=collection_archive---------54-----------------------

养老院数据集上的端到端机器学习应用

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片来自 Pixabay

摘要:

医疗保险和医疗补助服务中心为全国参加医疗保险或医疗补助计划的每家养老院发布了一套质量评级。这些评级有助于家庭了解不同养老院之间的差异及其质量。他们还帮助做出重要决定,如选择自己喜欢的养老院(医疗保险和医疗补助服务中心,2020 年)。本文旨在回答与数据集相关的某些研究问题。它使用机器学习技术对数据进行建模,并理解不同特征之间的关系。给定一组属性,训练机器学习模型来预测养老院的总体评级。对不同模型的性能进行了评估,并提供了研究问题的答案。

简介:

医疗保险和医疗补助服务中心引入了一个基于“星级”的评级系统,对养老院的质量进行量化。养老院的“总体评级”是根据其在三个领域的表现计算的,而这三个领域又是一个评级。

**健康检查:**进行年度检查调查,记录疗养院的不足之处。通过考虑在过去三年的这些检查中发现的缺陷的严重性和数量来分配评级。它还包括该部门要求的回访次数,以检查疗养院是否纠正了检查中发现的问题。

人员配备: RN 是注册护士的缩写,LPN 是执业实习护士的缩写。该评级基于每位住院医师每天的总注册护士小时数和每位住院医师每天的总护士小时数。

**质量评估:**疗养院比较网站上有 15 项质量评估,包括 9 项长期停留评估和 9 项短期停留评估。

由于有多个特征,并且很难理解和分析所有这些特征,因此存在一个称为“总体评级”的单一特征,该特征以 1 到 5(最低到最高)的等级分别对养老院进行评级。关于这三个领域的详细信息见(医疗保险和医疗补助服务中心,2020)。

数据集描述:

该数据集摘自 DATA.GOV 网站(医疗保险和医疗补助服务中心,2019 年)。它由 86 列和 15,437 条记录组成。每个记录都与一个疗养院相关联。描述疗养院的一些重要栏目是,

联邦提供者编号—由联邦政府提供给疗养院的唯一编号。

提供者名称—疗养院的名称。

提供者地址—疗养院的地址。

提供者城市—疗养院所在的城市。

提供者州——疗养院所在的州。

提供者邮政编码—与疗养院相关的邮政编码。

提供者电话号码—疗养院的电话号码。

提供者 SSA 县—疗养院所在的县。

提供者县名称—疗养院所属县的名称。

所有权类型-描述它是一个盈利性或政府或非盈利性实体。

提供者类型—描述疗养院是医疗保险还是医疗补助,或者是医疗保险和医疗补助。

提供者住在医院-一个布尔值,表示真或假,以表示提供者是否住在医院。

合法企业名称——养老院的合法企业。

文件导言部分还介绍了与这些措施相关的其他特点。例如,与**‘健康检查’相关的一些特征包括‘评定周期 1 健康缺陷总数’、‘评定周期 1 标准健康缺陷数’、‘评定周期 1 健康缺陷分数’等。与“人员配备”相关的特征包括“每个住院医师每天报告的护士助手人员配备小时数”、“每个住院医师每天报告的 LPN 人员配备小时数”、“每个住院医师每天报告的 RN 人员配备小时数”等。与’‘相关的特性包括’质量管理评级’、‘质量管理评级脚注’、'长期质量管理评级’等。**

数据的汇总统计如表 1 所示。因为有许多列,所以表中只显示了其中的几列。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

表 1。数据集中要素的汇总统计数据

“罚款总额(美元)”和“认证床位数”这两个特征的数值最高。“罚款总额(美元)”功能的平均值、标准差和 75%置信区间值是最大值。25%和 50%的置信区间值是“认证床位数”和“每日平均住院人数”列的最大值。

探索性数据分析:

图 1 显示了各州的“总加权健康调查分数”。可以观察到,加利福尼亚和得克萨斯具有更高的总加权健康调查分数。佛蒙特州、波多黎各和关岛等地的加权健康调查总得分较低。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1。描述各州总加权健康调查分数的条形图

图 2 显示了一个热图,显示了各州养老院的“总体评分”总和。可以看出,加利福尼亚州、得克萨斯州、俄亥俄州和佛罗里达州的养老院总体排名最高。仅考虑 50 个州,阿拉斯加、佛蒙特、特拉华、怀俄明各州对养老院的“总体评分”较低。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图二。热图显示了各州所有疗养院的总体评分总和

图 3 描绘了各州给予养老院的罚款总额的箱线图。有趣的是,尽管德克萨斯州、密歇根州和佛罗里达州都在罚款总额最高的五个州之列,但加利福尼亚州并不在其中。在箱线图中可以观察到很多异常值,因为每个州的养老院所遭受的罚款为零。许多州的中位数也接近于零。密歇根州的四分位数间距最高。德克萨斯州和北卡罗莱纳州的养老院承担了最高的罚款。德克萨斯州的罚金最高,总额超过 120 万美元。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3。各州给予养老院的罚款总额(美元)的方框图

皮尔逊相关系数大于 0.7 的特征的相关矩阵如图 4 所示。在“评定周期 2 总健康分数”和“评定周期 2 健康缺陷分数”以及“评定周期 1 健康缺陷分数”、“评定周期 1 健康总健康分数”和“评定周期 1 健康缺陷分数”之间观察到最高相关性。皮尔逊相关系数值大于 0.8 的要素可被视为高度相关。可以从数据集中删除每个集合中的一个高度相关的列,因为它们不提供任何附加值。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4。描述最相关特征的皮尔逊相关系数的热图

图 5 显示了“总体评分”和“总加权健康调查分数”栏之间的散点图。回归分析通过拟合线性回归来执行,以识别两个特征之间是否存在任何相关性。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5。总体评分和总加权健康调查得分之间的散点图

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 6。总体评分加权健康调查总分回归分析

通过对这两个特征使用线性回归,对数据拟合一条线。图 6 中描绘了相反的关系。随着总体评分的增加,总加权健康调查分数降低。这一观察结果得到了“注意,较低的调查分数对应于较少的缺陷和重访,因此在健康检查领域表现更好”这句话的支持(医疗保险和医疗补助服务中心,2019 年)。

对特征“提供者居住在医院”和“持续护理退休社区”进行独立性卡方检验。零假设假设特征是独立的。另一个假设假设这些特征是相关的。卡方检验显示 p 值为“7.1246454255565634e-12”。由于 p 值小于 0.05(在 95%的置信水平下),我们拒绝零假设,并接受替代假设,认为特征是相关的。“提供商在过去 12 个月内改变了所有权”和“滥用图标”之间的类似测试表明,它们是独立的。因为显著性水平为 0.05(95%置信水平)的 p 值计算为 0.975,大于 0.05。

研究问题:

本文旨在回答有关数据集的三个研究问题。

1.可以开发一个机器学习模型,根据数据中观察到的模式为养老院分配一个类别(总体评级)吗?

2.如果是,它有多可靠,有多准确?

3.影响养老院整体评分的最重要因素是什么?

对上述问题的回答有助于确定养老院影响其整体评级的最重要因素。这可以帮助养老院做出某些决定,以提高其评级,并在高度影响其评级的领域进行改进。

数据预处理:

许多文本数据,如位置、联邦供应商编号、健康调查日期对模型拟合不是很有用,这些列已从数据集中删除。此外,还考虑了调整后的功能,而不是单独报告的功能。例如,不考虑“每个住院医师每天报告的护士助手工作时间”,而是考虑“每个住院医师每天调整的护士助手工作时间”。包含真/假(布尔值)的列已分别替换为 1/0。某些列的 NaN 值,如“质量管理评级”、“长期质量管理评级”、“短期质量管理评级”、“员工评级”都填零。

该列的平均值用于替换“每个住院医师每天调整后的护士助手工作时间”、“每个住院医师每天调整后的 LPN 工作时间”、“每个住院医师每天调整后的总护士工作时间”、“每天住院医师平均人数”等中的 NaN 值。对某些列执行虚拟编码,如“有居民和家庭委员会”和“提供者类型”,因为它包含分类变量。其值都是 NaN 值的列将从数据集中删除。

不是对整个数据集进行规范化,而是将每一列规范化为[0,1]的范围。如果对整个数据集执行规范化,包含大数的列将成为决策的主导。皮尔逊相关系数是在数据集的所有要素之间计算的,每个数据集中的一个高度相关列已从数据集中删除,因为它们不能为模型提供任何附加值。经过预处理后,总列数从 86 列减少到 52 列。

班级分布:

观察属于每个类别(总体评级)的记录数量。类别 5 的记录数量最多,而类别 1 的记录数量最少。但它们之间的差异是 1000 个记录,这是可以容忍的。这种分布是自然的,不需要抽样方法,因为没有一个阶层的代表性严重不足或过多。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图七。按类别分布记录数量(总体评级)

模型拟合:

预测“总体评级”的当前任务是分类任务。诸如随机森林和支持向量机的机器学习算法是可以应用于分类(二进制或多类)的一些健壮算法。

随机森林是一种集成技术,它使用多个决策树,并根据输入特征为给定实例分配一个类。它可以执行回归和分类任务。使用替换对数据进行采样,并在提取的样本上训练几个决策树。在取样过程中,一定百分比的数据被分离出来并标记为 OOB(出袋)数据。在 OOB 数据上测试训练的决策树,并且获得 OOB 误差估计。最终确定具有最小 OOB 误差的最佳“n”棵树,并将其视为单个随机森林分类器。给定一个测试实例,随机森林分类器中的每个决策树预测一个类。执行类似投票的机制,并且由大多数树预测的类被生成作为随机森林分类器的输出。由于集合方法,随机森林可以非常有效地模拟数据(Leo 等人,2020)。

支持向量机是一种监督算法,可用于分类和回归。它确定了可以有效划分数据的最佳超平面。它也被称为最大间隔分类器,因为它试图构建一个超平面,该超平面到两个类的最近元素的距离是最大的(Cortes 等人,1995)。由于它们在许多分类任务中被证明是有效的,这两种模型都被认为是对当前数据的建模。

训练:

数据集按 80:20 的比例划分,其中 80%的数据构成训练集,其余 20%构成测试集。模型将被训练的特征被称为 X_train。对于当前数据集,X_train 构成预处理数据集后获得的所有 51 列(不包括“总体训练”列)。数据集将被训练来预测的目标/列被称为 Y_train,对于当前数据集,它将是“总体评级”列。

在训练过程中,机器学习模型被拟合到数据集。然而,建模的效率取决于给予模型的一组输入,这些输入通常被称为超参数。根据数据,需要调整超参数,这个过程称为超参数调整。用于训练随机森林和 SVM 模型的最佳超参数已经通过被分类为 K-Fold 交叉验证的技术来识别。在这种技术中,训练集被分成 K 个折叠/部分,其中 K-1 个部分被认为是训练集,一个部分被认为是测试集。提供一组超参数作为输入,在 K-1 个零件上训练模型,然后对一个零件进行测试(Refaeilzadeh 等人,2009 年)。这个过程被执行 K 次,并且每次都评估度量。计算分类度量的平均值,例如所选超参数的平均准确度、平均精确度、平均召回率和平均 F1 分数。超参数的最佳集合产生最高的测试分数,并且因此被确定。

对于当前数据集,执行了 5 重交叉验证,机器学习模型的最佳超参数确定如下。

RandomForestClassifier(bootstrap = True,class_weight=None,criterion='entropy ',max_depth=30,max_features='auto ',max_leaf_nodes=None,min _ infinity _ decrease = 0.0,min_samples_leaf=1,min_samples_split=2,min_weight_fraction_leaf=0.0,n_estimators=500,n_jobs=None,oob_score=False,random_state=None,verbose=0,warm _ start =

SVC (C=10,cache_size=200,class_weight=None,coef0=0.0,decision_function_shape='ovr ',degree=3,gamma=1,kernel='rbf ',max_iter=-1,probability=False,random_state=None,shrinking=True,tol=0.001,verbose=False)

随机森林和支持向量机的交叉验证分数如表 2 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

表二。随机森林和支持向量机的交叉验证分数

在交叉验证结束时,超参数被确定,并且整个训练集被模型训练为单个实体。模型已经准备好在测试集上进行测试。

测试和评估:

测试集中的每个记录都通过训练集来预测该记录的“总体评级”。每个记录代表一个疗养院。因此,该模型基本上是训练来预测养老院的“总体评级”,给定其一组特征。预测由分类指标评估—精确度、准确度、召回率和 F1 分数。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

****表 3。测试集上随机森林的类级分类度量

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

****表 4。测试集上支持向量机的类级分类度量

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

表五。机器学习模型性能的整体比较

可以得出结论,随机森林分类器是当前数据集的最佳性能模型。在所有分类指标上,如准确度、平均精确度、平均召回率和 F1 平均得分,它都占据了 SVM 的主导地位。

调研问题答案:

1。可以开发一个机器学习模型,根据数据中观察到的模式为养老院分配一个类别(总体评级)吗?

****回答:是的。可以开发一种机器学习模型,该模型可以将养老院分类为“总体评级”特征中呈现的五星评级之一。还可以得出结论,在关于总体评级栏的数据中存在清晰的模式,并且机器学习模型能够区分这些模式。因此,在当前数据集上建立可靠的模型并成功实现目标是可能的。构建这种模型的过程也在上面陈述了。

2。如果是,它有多可靠,有多准确?

****答:模型的性能可以通过不同的分类指标进行评估。随机森林模型的精确度被计算为 97%。随机森林模型预测类的平均精度被计算为 97%。简单来说,召回率是正确预测的数量与所有应该正确预测的数量之比。平均召回值也是 97%。F1 分数是精确度和召回率之间的调和平均值。F1 分数越高,模型越好。当前的随机森林模型在测试集上实现了 97%的平均 F1 分数。在所述指标的帮助下,可以得出结论,该模型是稳定且非常可靠的。

3。影响养老院整体评分的最重要因素是什么?

****答案:经过训练的随机森林模型提供了对数据集最重要特征的深入洞察。这是因为随机森林通过挑选对目标列最重要的特征来构建对数据建模的决策树。他们通过使用诸如“熵”、“基尼”、“增益率”等技术来计算特征的重要性。对于当前模型,特征重要性的顺序如图 8 所示。

影响“总体评分”的十大特征包括:“健康检查评分”、“QM 评分”、“人员配备评分”、“总加权健康调查评分”、“每个居民每天调整的 RN 人员配备小时数”、“第 1 周期总健康评分”、“长期住院 QM 评分”、“每个居民每天调整的护士人员配备小时数”、“第 1 周期健康缺陷评分”和“短期住院 QM 评分”。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图八。特征重要性的顺序由随机森林分类器决定

结论:

当前的论文提供了回答提出的研究问题所需的方法、工具、技术和程序的详细描述。建立了两个机器学习模型(随机森林和支持向量机),进行了广泛的分析和测试,以从训练的模型中获得洞察力。得出了相关结论,提供了答案。疗养院可以利用从数据中发现的丰富信息,并做出必要的决定来提高它们的总体评级。

限制:

随机森林模型的可解释性很低,因为它是决策树的集合。当树很大时,很难想象或解释它们。与随机森林的训练和测试相关联的存储器和计算成本很高。预测速度不是很快,对于时间敏感型应用来说可能是个问题(Jansen,2018)。

虽然有明确的规定,向养老院提供评级,但数据可能不准确。对于这种不准确的数据记录,模型可能不会给出相同的结果。

推荐未来分析:

当前数据定义了疗养院的不同属性和给予它的不同评级,以及与它的缺陷、处罚和罚款相关的信息。然而,它没有描述养老院所在的地理区域的社会经济因素。这些信息可以添加到数据集中,以丰富结果的质量并找到新的见解。

随着数据的增加,随机森林和 SVM 等模型无法很好地扩展。可以在数据集上训练高级模型(如神经网络)来克服这个问题。

参考文献:

医疗保险和医疗补助服务中心。(2019).提供商信息[数据文件]。于 2020 年 3 月 29 日从https://catalog.data.gov/dataset/provider-info-1de34取回

医疗保险和医疗补助服务中心。2020 年养老院设计对比五星级质量评级体系。

c .科尔特斯和 v .瓦普尼克(1995 年)。支持向量网络。机器学习,20(3),273–297 页。

詹森斯特凡。算法交易的动手机器学习:基于使用 Python 从数据中学习的智能算法,设计和实施投资策略。Packt 出版公司,2018 年。

利奥,布莱曼和阿黛尔·卡特勒。“随机森林。”随机森林-分类描述。于 2020 年 5 月 10 日从 www.stat.berkeley.edu/~breiman/RandomForests/cc_home.htm取回。

Refaeilzadeh P .,Tang L .,Liu H. (2009)交叉验证。载于:刘,主编的《数据库系统百科全书》。马萨诸塞州波士顿斯普林格

基于机器学习的 Volve 油田声波测井预测

原文:https://towardsdatascience.com/prediction-of-p-sonic-log-in-the-volve-oil-field-using-machine-learning-9a4afdb92fe8?source=collection_archive---------21-----------------------

实践教程

使用 Scikit-Learn 逐步解释

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

rsk Inspirer på Volve 来自 Equinor 照片档案馆

2018 年,挪威石油公司 Equinor 披露了北海 Volve 油田的大规模地下和作业数据集。两年来,对于所有热衷于改善和解决大学、研究机构和公司油气领域研究挑战的人来说,这是一个好消息。以下是来自“马科动物的首席运营官”扬尼克·尼尔森的一段鼓舞人心的话。

“Volve 是我们如何寻找各种可能性来延长油田寿命的一个例子。现在,我们希望分享所有 Volve 数据,以确保未来解决方案的学习和开发。”

Volve 是一个油田,位于北海挪威区块南端斯塔万格以西 200 公里处,于 2008 年至 2016 年生产。

当我查看每个人都可以通过这个网站访问的数据库时,我看到了里面巨大的宝藏!我开始提出一些想法来探索引入机器学习的可能性,直到我想到了进行声波测井预测的想法,原因我在本文的动机部分中阐述。

我将这个项目保存在我的名为volve-machine-learningGitHub 资源库中(你可以访问这个资源库)。

数据集概述

在 Volve 油田开放数据库中,有 24 口井。在这项研究中,只使用了 5 口井。油井名称为 15/9-F-11A、15/9-F-11B、15/9-F-1A、15/9-F-1B 和 15/9-F-1C。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

测井数据代表地球上的每个岩层( Aliouane 等人,2012 )

每口井都有他们所谓的测井记录。测井记录是代表深度范围内每个岩层属性的某些物理测量值。以下是我们将使用的日志列表。

  • NPHI 是地层孔隙度,单位为 v/v
  • RHOB 是地层体积密度,单位为克每立方厘米。
  • GR 是地层放射性含量,用 API 测量。
  • RT 是地层真实电阻率,单位为欧姆米。
  • PEF 是地层光电吸收因子,无量纲。
  • CALI 是钻孔直径,单位为英寸。
  • DT 是纵波传播时间,单位是微秒每英尺。
  • DTS 是剪切(横波)传播时间,与 DT 类似。

这些测井数据集的文件格式为 LAS 2.0,这是测井的一种特定格式。你可以在这里找到数据集。

动机

5 口井中有 3 口井(15/9-F-11A 井、15/9-F-1A 井和 15/9-F-1B 井)拥有这套完整的测井资料,除了之外,另外 2 口井(15/9-F-11A 井和 15/F-1C 井)没有 DT 和 DTS 测井资料。这就是为什么我们可以使用监督学习,通过回归模型在这个不完整的数据集中生成 DT 日志。

有 DT 日志的 3 个数据集作为训练数据,没有的作为测试数据。NPHI、RHOB、GR、RT、PEF 和 CALI 测井用作特征;而 DT 是用于预测的目标。目前,不会使用 DTS 日志。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

scikit-从 GitHub 学习徽标

通过监督学习,这些训练数据会用Scikit-Learn*中的一些回归模型进行训练。*然后,该模型将用于根据特征预测产生新的 DT 测井曲线。

我将把工作流程分成七个步骤。您也可以在我的 GitHub repo 中访问我的 IPython 笔记本,它从头到尾运行这个工作流。

访问我的 IPython 笔记本

第一步。显示测井数据集

一个名为 lasio 的 Python 库用于读取这些 LAS 数据集。在任何地层评价中,显示测井记录都是例行公事。以下是使用 Matplotlib 生成的其中一个训练数据 15/9-F-1B 井的显示。每个图代表一条测井曲线;正如我们已经讨论过的,NPHI、RHOB、GR、RT、PEF 和 CALI 是特征,而 DT 是目标。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1B 15/9 井的测井显示

以下是 15/9-F-1C 井的测井曲线显示,该井是没有 DT 测井的两口井之一,因此我们将预测产生一个新的 DT 测井曲线。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

15/9-F-1C 井的测井显示

第二步。数据准备

第二步是工作流程中最关键的部分,因为它会影响整个预测的成功。熊猫对数据处理很有用。

首先,我们需要确保我们的整个数据不包含任何非数字值 (NaNs)。过滤数据的一个技巧是设置最小和最大深度限制,这样所有数据都以数值开始和结束。例如,之前显示的 15/9-F-1B 井从 3100 米到 3400 米的深度开始。示例代码:

df = df.loc[(df['DEPTH'] >= 3100) & (df['DEPTH'] <= 3400)]

之后,我们检查数据中是否存在 nan。

df.isnull().sum()

如果一切归零,我们就安全了。在我们现在的情况下,它变为零,我们已经没有 NaNs 了。否则,我们需要处理 NaN 值。这个动作在这里详细讨论。

接下来,我们将各个井数据集合并到两个更大的单个数据框中,每个数据框用于训练和测试数据集。

df = pd.concat([df1, df2, df3])

现在我们有了训练和测试数据框架,最后我们分配井名。这样做的原因是为了便于我们在预测期间检索任何井。你可以在笔记本里看到我是如何分配井名的。

下面是训练数据的最终数据框。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

训练数据帧

第三步。探索性数据分析

探索性数据分析(EDA)对于理解我们的数据至关重要。我们想知道的两件重要的事情是每个单独特征的分布和一个特征到另一个特征的相关性

为了观察多元分布,我们可以在 Seaborn 包中使用一个 pair-plot。以下是特征和目标的多元分布。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

训练数据集的配对图

我们从结对图中至少得到了 3 点。首先,我们观察大多数分布是如何偏斜的,并且不是理想的高斯,尤其是 RT。然而,对于机器学习,高斯或不太偏斜的数据是优选的。我们可以对这些数据进行标准化,这将在下面讨论。第二,我们可以看到数据里面的离群值。同样在下一部分,我们将讨论如何去除这些异常值。第三,我们看到一些数据对几乎线性(因此高度)相关,比如 NPHI 和 DT;和反向相关,比如 RHOB 和 DT。配对图说明了很多事情。

我们通过计算 Spearman 相关性 来查看更多特征和目标之间的相关性,并使用热图来可视化结果。以下是我们数据的 Spearman 相关热图。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

训练数据的 Spearman 相关热图

只关注 DT 行,我们获得了 DT 和 NPHI 之间的 2 个最大相关(正相关为. 95)以及 DT 和 RHOB 之间的 2 个最大相关(负相关为. 79)。这个相关结果与我们之前在配对图中看到的结果相匹配。还有,除了 CALI,其他数据似乎都和 DT 有很高的相关性。CALI 似乎与其他特征也没有什么关联。

作为惯例,任何相关性非常低的特征都被排除在预测之外,因此 CALI 可以被排除。然而在这里,我将保留 CALI 作为一个特性。

第四步。正常化

我们以前从配对图中知道,大多数分布似乎是偏斜的。为了提高我们的预测性能,稍后,我们最好做一个归一化(其他人可能称之为缩放)。规范化是一种转换数据(不改变数据)以更好地分布数据的技术。

在进行任何标准化之前,我倾向于先对电阻率数据进行测井转换。

df['RT'] = np.log10(df['RT'])

然后,我用 Scikit-Learn 中的函数fit_transform进行规范化。有几种标准化技术;广泛使用的有标准化(用均值和标准差转换)和 min-max (用最小值和最大值)。在尝试了所有的方法后,我找到了使用Yeo-Johnson方法力量转换技巧。

归一化后,我们可以看到数据现在是如何使用 pair-plot 再次分布的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

用 Yeo-Johnson 方法进行幂变换后的训练数据对图

看看 NPHI、DT 和 RT 现在如何不那么偏斜,更像高斯分布。虽然 RHOB 和 GR 分布看起来是多峰的,但归一化后它变得更加集中。

第五步。移除异常值

此外,我们刚刚观察到数据中有许多异常值。异常值的存在会降低预测性能。因此,我们做离群点剔除。

Scikit-Learn 提供了几种离群点剔除方法,如隔离森林使用椭圆包络的最小协方差局部离群因子单类支持向量机。除此之外,最广泛使用的异常值去除方法,也是最基本的方法,是使用标准差方法。在这种方法中,我们将阈值指定为偏离标准偏差的最小值和最大值。我们可以自己建造。

threshold = 3
df = df[np.abs(df - df.mean()) <= (threshold * df.std())]

所有 5 种方法都已实现。我用两种方法来比较哪种方法去除异常值的效果最好。一种方法是对每种方法计算剔除异常值之前的数据和剔除异常值之后的数据。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

标准化前后的数据计数

从该结果中,我们看到标准差方法移除的异常值最少(最多只有 302 个),其次是单类 SVM最小协方差,与其他方法相比异常值相对较少(> 10,000)。您可能已经知道,剔除的异常值越少越好

然后,为了决定标准差和一类 SVM 之间哪个更好,我使用熊猫为归一化前后的每个特征生成了箱线图。下面是箱线图。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

关键的观察结果是,在剔除异常值前后,异常值仍然存在于新计算的汇总统计数据的数据中。这(间接地)是选择哪种方法是最好的直观表示。

现在,通过观察异常值的数量,可以看出一类 SVM 比标准差方法表现得更“干净”。尽管最小的协方差也是干净的,仍然一级 SVM 是赢家。

结论是:我们用一级 SVM 。同样,我们制作一个配对图来观察我们数据的最终结果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用一类 SVM 方法去除异常值后的训练数据对图

看看离群值现在是如何减少的。我们都为机器学习做好了准备。

第五步。预测!第一次尝试

现在主菜来了!第五步,我们还没有对我们的真实测试数据(没有 DT 测井的井 15/F-11B 和 15/F-1C)进行实际预测。耐心点!我们需要评估我们使用的每个回归模型的性能,方法是训练训练数据,并用训练数据本身测试模型,然后我们评估预测的 DT 日志与真实 DT 日志的接近程度。

在此步骤中,测试数据=训练数据

我尝试了来自 Scikit-Learn 的 6 个回归模型,分别是经典的线性回归随机森林支持向量机决策树梯度推进K-最近邻回归器。

请记住,在完成预测后,我们总是需要对结果进行反规范化,因为我们刚刚进行了规范化。在 Scikit-Learn 中,我们使用一个inverse_transform函数来完成这项工作。

我使用 R 和均方根误差(RMSE)作为评分标准来衡量每个回归模型的性能。以下是每个回归变量的评分标准的结果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

6 个回归变量的评分标准

从结果来看,我们看到回归器的表现非常出色!可以理解为什么经典的线性回归器不如其他回归器(最低的 R 和 RMSE)表现得好。原因是并非所有的特征都是完美的线性相关的。

然后,我们可以显示真实的 DT 日志和预测的 DT 日志,以比较两者的接近程度。以下是使用梯度推进回归器对每口井预测 DT 测井的真实值。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用梯度推进回归器的真实与预测 DT 测井

事实上,我使用的所有回归变量仍然使用默认的超参数。例如,梯度增强的几个超参数中的两个是估计器的数量和最大深度。默认值分别为 100 和 3。

根据梯度推进的评分标准,我们已经知道 R 和 RMSE 分别达到了 0.94 和 0.22 左右。我们可以进行超参数调整以确定最佳超参数值,从而提高性能得分。

第六步。超参数调谐

梯度推进回归器上的超参数调谐通过执行训练-测试分割开始,该分割由 0.7 训练和 0.3 测试组成。然后,通过产生的训练和测试分裂,进行具有定义的搜索超参数集的网格搜索三重交叉验证。以下是搜索到的参数网格。

  • 估计数n_estimators : 100 和 1000
  • 最大深度max_depth : 10 和 100

调整超参数花费了大约 5 分钟,直到给出估计器数量为 1,000,最大深度为100 的结果作为最佳超参数。

然后,通过包含超参数重复前面的步骤,并打印新的得分度量,如下所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

超参数调整后梯度增强的评分标准

R 和 RMSE 都提高了很多,分别是 0.98 和 0.12 左右!有了这个结果,我们有足够的信心使用梯度推进进行预测。以下是超参数调整后的真实与预测 DT 对数图。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

超参数调整后使用梯度推进回归器的真实与预测 DT 测井

第七步。为最终预测编译调整后的梯度推进回归器

最后我们做真正的预测!现在,用之前根据我们的实际测试数据调整的超参数(估计数= 1000,最大深度= 10)编译梯度推进回归器。记住,我们真正的测试数据是没有 DT 测井的井;15/9-F-11B 井和 15/9-F-1C 井,或所谓的 2 井和 5 井。

以下是 2 井和 5 井的预测 DT 测井。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

15/9-F-11B 井和 15/9-F-1C 井的预测测井曲线令人满意!为了关闭我们的工作流程,我们可以将预测结果导入到原始数据集并写入 CSV 文件。

以下是最终的 CSV 结果:井 15/9-F-11B15/9-F-1C

结论

我们已经证明了监督学习在 Equinor 拥有的 Volve 油田公开数据集上的成功应用。通过这一工作流程,使用梯度推进方法,在两口原本没有压力声波测井记录的油井上预测了新的压力声波测井记录。

我希望这篇文章能为地球科学中的任何 ML 从业者带来新鲜空气,开始探索这个数据集中 ML 的其他可能性。与此同时,我正在考虑其他的可能性,我会在我的 GitHub ( 关注我的工作以获得更新)中积极更新,并且很快会再写一篇!

基于移动应用行为数据的客户流失预测

原文:https://towardsdatascience.com/prediction-on-customer-churn-with-mobile-app-behavior-data-bbce8de2802f?source=collection_archive---------53-----------------------

通过数据处理、模型构建、验证、特征分析和选择深入研究逻辑回归建模

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

来自 Pixabay 的 Img 通过链接

在之前的文章中,我们使用应用行为数据创建了一个逻辑回归模型来预测用户注册。希望你在那里学得很好。这篇文章旨在基于更大的移动应用程序行为数据,用新的技术和技巧提高你的建模技能。它分为 7 个部分。

1.商业挑战

2.数据处理

3.模型结构

4.模型验证

5.特征分析

6.特征选择

7.结论

现在让我们开始旅程🏃‍♀️🏃‍♂️.

  1. 商业挑战

一家金融科技公司委托我们分析移动应用行为数据,以识别潜在的流失客户。目标是预测哪些用户可能会流失,因此公司可以专注于用更好的产品重新吸引这些用户。

2.数据处理

**EDA 应在数据处理前进行。**详细步骤在本中介绍。下面的视频是 EDA 后的最终数据。

2.1 一键编码

一键编码是一种将分类变量转换成数值变量的技术。它是必需的,因为我们要构建的模型无法读取分类数据。**一键编码只是根据唯一类别的数量创建附加功能。**在这里,具体来说,

dataset = pd.get_dummies(dataset)

以上自动将所有分类变量转换为数值变量。但是独热编码的一个缺点是虚拟变量陷阱。*这是一个变量之间高度相关的场景。*为了避免陷阱,必须删除一个虚拟变量。具体来说,

dataset = dataset.drop(columns = [‘housing_na’, ‘zodiac_sign_na’, ‘payment_type_na’])

2.2 数据分割

这是为了将数据分成训练集和测试集。具体来说,

X_train, X_test, y_train, y_test = train_test_split(dataset.drop(columns = ‘churn’), dataset[‘churn’], test_size = 0.2,random_state = 0)

2.3 数据平衡

不平衡类是分类中的常见问题,其中每个类中的观察值比例不成比例。但是如果我们在不平衡的数据集上训练一个模型会发生什么?该模型将巧妙地决定最好的事情是总是预测类 1,因为类 1 占用 90%的数据,所以该模型可以达到 90%的准确性。

这里有许多方法来对抗不平衡的类,例如改变性能指标、收集更多数据、过采样或下采样数据等。这里我们使用下采样方法。

首先,我们来考察一下 y_train 中因变量的不平衡程度。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1 因变量的不平衡分布:流失与否

如图 1 所示,因变量略有不平衡。为了对数据进行下采样,我们取每个类的指数,并在 y_train 的多个少数类中随机选择多数类的指数。然后连接两个类的索引,并对 x_trainy_train 进行下采样。

pos_index = y_train[y_train.values == 1].index
neg_index = y_train[y_train.values == 0].index
if len(pos_index) > len(neg_index):
    higher = pos_index
    lower = neg_index
else:
    higher = neg_index
    lower = pos_index
random.seed(0)
higher = np.random.choice(higher, size=len(lower))
lower = np.asarray(lower)
new_indexes = np.concatenate((lower, higher))
X_train = X_train.loc[new_indexes,]
y_train = y_train[new_indexes]

2.4.特征缩放

从根本上说,特征缩放是对变量范围的标准化。这是为了避免任何变量对模型产生显著影响。对于神经网络,特征缩放有助于梯度下降比没有特征缩放收敛得更快。

这里我们使用标准化来标准化变量。具体来说,

from sklearn.preprocessing import StandardScaler
sc_X = StandardScaler()
X_train2 = pd.DataFrame(sc_X.fit_transform(X_train))
X_test2 = pd.DataFrame(sc_X.transform(X_test))

3.模型构建

在这里,我们建立了一个逻辑回归分类器,用于流失预测。**实质上,逻辑回归使用独立变量的线性组合来预测一类概率的对数。**如果你想深入了解逻辑回归的更多细节,请访问这个维基百科页面。

具体来说,

from sklearn.linear_model import LogisticRegression
classifier = LogisticRegression(random_state = 0)
classifier.fit(X_train, y_train)

现在,让我们测试和评估模型。具体来说,

y_pred = classifier.predict(X_test)
from sklearn.metrics import confusion_matrix, accuracy_score, f1_score
cm = confusion_matrix(y_test, y_pred)
accuracy_score(y_test, y_pred)
f1_score(y_test, y_pred)

最后我们得到了一个 0.61 的精度和 0 的 F1。61 。表现不算太差。

4.模型验证

模型经过训练和测试后,一个问题是该模型推广到未知数据集的效果如何。我们使用交叉验证来衡量已知数据集和未知数据集之间的性能差异大小。具体来说,

from sklearn.model_selection import cross_val_score
accuracies = cross_val_score(estimator = classifier, X = X_train, y = y_train, cv = 10)

根据上述内容,我们发现 10 重交叉验证产生的平均准确度为 0.64.5 ,标准偏差为 0.023 。这表明该模型可以在未知数据集✨✨.上很好地泛化

5.特征分析

有了 41 个特征,我们建立了一个逻辑回归模型。*但是如何知道在预测因变量时哪个特征更重要呢?*具体来说,

pd.concat([pd.DataFrame(X_train.columns, columns = [“features”]), pd.DataFrame(np.transpose(classifier.coef_), columns = [“coef”])],axis = 1)

如图 2 所示,我们发现两个特性非常重要: purchase_partnerspurchase 。这表明用户的购买历史在决定是否流失时起着很大的作用。同时,这表明并非所有变量对预测都很重要。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2 变量对预测的重要性

6.功能选择

特征选择是一种为建模训练选择最相关特征子集的技术。

在这个应用中, x_train 包含 41 个特性,但是如图 2 所示,并不是所有的特性都起着重要的作用。使用特征选择有助于减少不重要特征的数量,并以较少的训练数据获得相似的性能。关于功能选择的更详细的解释可以在这里找到。

这里,我们使用递归特征消除 (RFE)。它的工作原理是拟合给定的算法,按重要性排列特性,丢弃最不重要的特性,然后重新调整,直到达到指定的特性数。具体来说,

from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression
classifier = LogisticRegression()
rfe = RFE(classifier, 20)
rfe = rfe.fit(X_train, y_train)

如上所述,我们设置选择 20 个特性。图 3 显示了所有选择的特性。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3 RFE 推荐的功能

太好了。使用 RFE 选择的功能,让我们重新训练和测试模型。

classifier.fit(X_train[X_train.columns[rfe.support_]], y_train)
y_pred = classifier.predict(X_test[X_train.columns[rfe.support_]])

最终我们得到了一个 0.61 的精度和 0.61 的 F1。与在 41 个特征上训练的模型相同的性能😇😇!

如果我们再次应用交叉验证,我们得到的平均准确度为 0.647 ,标准偏差为 0.014 。同样,与之前的模型非常相似。

7.结论

最初,我们用 41 个特征训练了一个逻辑回归模型,达到了 0.645 的精确度。但是使用特征选择,我们创建了一个只有 20 个特征的轻型模型,精度为 0.647。一半的特征与决定客户流失无关。干得好!

太好了!这就是全部的旅程!如果您需要源代码,请随时访问我的Github页面🤞🤞(仅供参考,回购正在积极维护中)。

预测强度—一种简单但相对未知的评估聚类的方法

原文:https://towardsdatascience.com/prediction-strength-a-simple-yet-relatively-unknown-way-to-evaluate-clustering-2e5eaf56643?source=collection_archive---------20-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片由 nrdUnsplash 拍摄

了解该标准如何工作,以及如何从头开始用 Python 实现它!

有很多内容(书籍、博客帖子、教程等。)的内容,以及在 k-means 聚类等算法中寻找最佳聚类数的各种方法:间隙统计、剪影得分、臭名昭著的肘(scree)图等等。

多亏了新冠肺炎和新发现的大量额外空闲时间,我终于可以回到我积压的书籍中,完成安德烈·布尔科夫的优秀作品百页机器学习书籍。这本书很好地概述了机器学习的各个方面,并鼓励读者深入他们感兴趣的话题。在阅读关于无监督学习和聚类算法的章节时,我遇到了一种评估聚类算法性能的新方法——预测强度。

经过快速搜索,我没有找到类似的文章,我确实认为这种方法很有趣,值得另起炉灶。所以让我们开始吧!

理论介绍

许多用于确定算法(如 k-means)的最佳聚类数的流行方法都是基于类内平方和(WSS)。该度量基于观测值和聚类质心之间的距离。一般来说,WSS 越低,观测值越接近质心,这表明拟合度越高。但是,我们需要在 WSS 和聚类数之间找到一个平衡点,因为无限增加聚类数(直到观察次数)总是会得到更好的拟合。

[1]中建议的预测强度方法从机器学习的角度来看识别最佳聚类数的问题。

我们将算法分解为以下步骤:

  1. 将数据集分成训练集(X_tr)和测试集(X_te)。
  2. 使用某个值 k (聚类数)对两个集合运行聚类算法。
  3. 创建大小为n_test x n_test共同隶属矩阵 D[C(X_tr,k),X_te],其中n_test是测试集中的观察值数量,C(X_tr,k)是适合训练集的聚类算法(在我们的例子中是 k-means)。
  4. 如果测试集的元素 I 和 I '属于同一聚类,则将共同隶属矩阵的第 ii '个元素设置为 1,否则将其设置为 0。
  5. 以便测量训练集质心预测测试集中的共同成员的程度。对于分配到同一测试聚类的每对测试观察值(在共同隶属矩阵中值为 1),我们基于训练集质心确定它们是否也被分配到同一聚类。

下面来自[1]的图片说明了这个想法:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

训练和测试指的是数据集。来源:【1】

6.聚类的预测强度 C(.k)定义为:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

其中 n_kj 是第 j 个星团中的观测值数量。

7.对于每个测试聚类,我们使用训练集质心计算该聚类中被分配到同一个聚类的观察对的比例。预测强度是这个量在 k 个测试集群中的最小值。

我们对所有考虑的集群大小运行上述算法的步骤 2-7。然后,我们选择预测强度高于某个阈值的最大聚类大小。作者进行的实验表明 0.8-0.9 是一个很好的阈值。

这可能有点难以理解,所以我建议仔细研究几次这个算法,以便理解这个想法。查看后面部分的代码也会有所帮助。

为了使这个过程更容易,我将尝试提供一些预测强度方法背后的直观解释。假设所选的聚类数等于数据集中的真实聚类数。然后,训练群集将类似于测试群集,并将很好地预测它们。因此,预测强度会很高。

相反,当所选的聚类数高于最佳聚类数时,附加的训练和测试聚类很可能是不同的,这将导致预测强度的较低值。

用 Python 实现

是时候用 Python 实现预测强度算法了。我们将使用该标准来选择玩具数据集上 k-means 聚类中的最佳聚类数。此外,我们还将展示经典的肘图方法进行比较。首先,我们导入所有需要的库:

然后,我们使用make_blobs生成一个 2 维玩具数据集,其中有 3 个明显分开的簇。为了再现性,我们固定随机状态。

下图显示了生成的数据集。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

生成数据后,我们应用 k 均值聚类。首先,我们使用肘图方法来确定最佳聚类数。我们将聚类的最大数量设置为 9。

在 k 均值聚类的scikit-learn实现中,inertia_属性存储总的类内平方和(WSS)。我们绘制了结果图:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们可以清楚地看到“肘”点—它对应于 3 个集群,这与我们人工生成的数据相符。

是时候实现预测强度算法了。我的实现基于[3]中提供的实现,做了一些修改以使代码更简单易读。我们首先将数据分成训练集和测试集。为此,我们使用了scikit-learn中的train_test_split函数。我们采用 80-20 的分层比例。

在处理主函数之前,我们需要定义一个辅助函数。它用于确定给定观测值的最近质心(使用欧几里德距离)。

现在,我们定义主函数。在前半部分,我们创建并填充共同成员矩阵。我们使用嵌套循环和一组条件来确定矩阵中每个元素的正确值。在后半部分,我们计算每个聚类的预测强度,并选择最小值作为最终结果。

准备好函数后,我们为每个聚类大小拟合 k 均值聚类,并计算预测强度。请记住,在每次迭代中,我们实际上必须分别为训练集和测试集采用两种 k-means 算法。

下面我们可以看到绘制的结果。按照算法的逻辑,我们应该选择预测强度值高于指定阈值(在这种情况下为 0.8)的最大聚类大小。我们可以看到推荐的集群大小是 3。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

结论

在本文中,我介绍了相对未知的聚类算法评估标准——预测强度,并展示了如何在 Python 中将它实现为一个自定义函数。您可以在下一次处理集群问题时尝试一下!

关于算法(R 中)的稍微不同但等价的实现,请参见[2]。这种方法可能更容易理解,因为作者减少了要检查的嵌套循环和条件的数量。

我们还可以应用于玩具示例的另一件事是置信区间,特别是对于非确定性聚类算法。它们基于多次计算预测强度和计算接收结果的平均值和标准偏差。记住,要这样做,我们必须从 k-means 聚类类中删除固定的随机状态。

您可以在我的 GitHub 上找到本文使用的代码。一如既往,我们欢迎任何建设性的反馈。你可以在推特或评论中联系我。

如果您对本文感兴趣,您可能也会喜欢:

[## 在 scikit-learn 中编写自定义输入程序

了解如何创建自定义估算器,包括用于更高级用例的 groupby 聚合

towardsdatascience.com](/coding-a-custom-imputer-in-scikit-learn-31bd68e541de) [## 使用投票分类器的集成学习

了解如何使用集成学习的变体来利用多个模型的优势

levelup.gitconnected.com](https://levelup.gitconnected.com/ensemble-learning-using-the-voting-classifier-a28d450be64d) [## 以 scikit-learn 方式创建基准模型

了解如何为分类和回归问题创建一系列基准模型

towardsdatascience.com](/creating-benchmark-models-the-scikit-learn-way-af227f6ea977)

参考

[1] Tibshirani,r .,& Walther,G. (2005 年)。通过预测强度进行聚类验证。计算与图形统计杂志14 (3),511–528。—https://www . stat . Washington . edu/wxs/stat 592-w 2011/Literature/TiB shirani-walther-prediction-strength-2005 . pdf

https://github.com/echen/prediction-strength

[3]https://github . com/aburkov/theMLbook/blob/master/prediction _ strength . py

预测分析:用 TensorFlow 中的 LSTM、GRU 和比尔斯特姆进行回归分析

原文:https://towardsdatascience.com/predictive-analysis-rnn-lstm-and-gru-to-predict-water-consumption-e6bb3c2b4b02?source=collection_archive---------3-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Unsplash 上的this is 工程拍摄

关于开发 LSTM、GRU 和比尔斯特姆模型进行用水量多步预测的分步指南

在这篇文章中,我开发了三个连续模型;LSTM、GRU 和双向 LSTM,预测气候变化影响下的用水量。然后,我用最可靠的一个对未来 10 年的城市用水量进行多步预测。

首先,让我提醒你一下基本面。然后,我将带您完成一个完整的 Python 数据科学项目。

👩‍💻 上的 Python 代码 GitHub

递归神经网络

递归神经网络(RNN)是一种设计用于使用时序数据的神经网络。在 RNNs 中,输出可以作为输入反馈到网络中,创建一个循环结构。

梯度消失问题

通过反向传播来训练 rnn。在反向传播过程中,RNNs 会遇到梯度消失问题。梯度是用于更新神经网络权重的值。梯度消失问题是当梯度随着时间向后传播而收缩时。因此,梯度较小的层不会学习,它们会导致网络具有短期记忆。

💡❓ 渐变消失问题的解决方案是什么

长短期记忆

长短期记忆(LSTM)是一种专门的 RNN,以减轻梯度消失的问题。LSTMs 可以使用一种称为 gates 的机制来学习长期依赖关系。这些门可以了解序列中哪些信息是重要的,应该保留或丢弃。LSTMs 有三个门;输入,忘记,输出。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

LSTM 细胞的结构

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

双向 LSTMs

双向 lstm(BiSTM)的思想是在 LSTM 模型中聚合特定时间步长的过去和未来的输入信息。在 BiLSTM 中,在任何时间点,您都可以保存过去和未来的信息。

门控循环单元

门控递归单元(GRU)是新一代的神经网络,非常类似于 LSTM。GRU 摆脱了细胞状态,使用隐藏状态来传递信息。GRU 和 LSTM 的另一个区别是 GRU 只有两个大门;复位和更新门。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

GRU 细胞的结构

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

☺时间让我们的手 dirty❗

资料组

加拿大魁北克省的 Brossard 市被选为研究地点。这座城市是蒙特利尔大都市区的一部分。本项目日用水量数据取自 2011 年 9 月 1 日至 2015 年 9 月 30 日。收集同期最低气温最高气温总降水量。这些气候变量的测量数据来自加拿大环境部

导入库

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

设置随机种子

设置随机种子以在每次运行代码后获得相同的结果。

**# Set random seed for reproducibility**
tf.random.set_seed(1234)

步骤 1:读取和浏览数据

在这个项目中,我正在处理多变量时间序列数据。当我从 CSV 文件导入数据时,我通过 parse_dates = [‘Date’] 确保 Date 列具有正确的 DateTime 格式。此外,当我处理日期和时间时,如果我将日期列设置为 dataframe 索引,就会变得容易得多。

**# Read file**
file = 'Data.csv'
raw_data = pd.read_csv(file, parse_dates = ['Date'],
                       index_col = 'Date')
df = raw_data.copy()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • Max_T:最高温度(℃)
  • Min_T:最低温度(℃)
  • T_P:总降水量(毫米)
  • UWC:城市用水量(立方米/人.天)
**# Define a function to draw time_series plot**
def timeseries (x_axis, y_axis, x_label, y_label):
    plt.figure(figsize = (10, 6))
    plt.plot(x_axis, y_axis, color ='black')
    plt.xlabel(x_label, {'fontsize': 12}) 
    plt.ylabel(y_label, {'fontsize': 12})timeseries(df.index, df['WC (m3/capita.day)'], 'Time (day)','Daily Water consumption ($m^3$/capita.day)')

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2011 年 9 月 1 日至 2015 年 9 月 30 日的日用水量时间序列

第二步:数据预处理

数据预处理是最耗时的步骤,包括:

  • 处理缺失值
  • 替换异常值
  • 将数据集拆分为训练和测试数据
  • 拆分目标变量和因变量
  • 数据转换
  • 创建 3D 输入数据集

2.1 处理缺失值

对于时间序列数据,使用线性插值替换缺失值是一个好主意。

**# Check missing values**
df.isnull().sum()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**# Replace missing values by interpolation**
def replace_missing (attribute):
    return attribute.interpolate(inplace=True)replace_missing(df['Max_T'])
replace_missing(df['Min_T'])
replace_missing(df['T_P'])
replace_missing(df['UWC'])

2.2 替换异常值

我使用统计方法来检测异常值。统计方法假设数据点呈正态分布。因此,低概率区域中的值被视为异常值。我在统计方法中应用了最大似然的概念,这意味着超出μ 2σ范围的值被标记为异常值。注意,在正态分布的假设下,μ 2σ包含 95%的数据。

**# Outlier detection**
up_b = df['UWC'].mean() + 2*df['UWC'].std()
low_b = df['UWC'].mean() - 2*df['UWC'].std()**# Replace outlier by interpolation for base consumption**
df.loc[df['UWC'] > up_b, 'UWC'] = np.nan
df.loc[df['UWC'] < low_b, 'UWC'] = np.nan
df['UWC'].interpolate(inplace=True)

2.3 将数据集分为训练和测试数据

在这个项目中,我将前 80%的数据设置为训练数据,剩下的 20%为测试数据。我用训练数据训练模型,并用测试数据验证其性能。

**# Split train data and test data**
train_size = int(len(df)*0.8)
train_dataset, test_dataset = df.iloc[:train_size],
df.iloc[train_size:]**# Plot train and test data**
plt.figure(figsize = (10, 6))
plt.plot(train_dataset.UWC)
plt.plot(test_dataset.UWC)
plt.xlabel('Time (day)')
plt.ylabel('Daily water consumption ($m^3$/capita.day)')
plt.legend(['Train set', 'Test set'], loc='upper right')print('Dimension of train data: ',train_dataset.shape)
print('Dimension of test data: ', test_dataset.shape)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

训练数据和测试数据的预处理日用水量时间序列

2.4 拆分目标变量和因变量

UWC 是目标变量(输出),是因变量(输入)的函数;Max_T,Min_T 和 T_P。

**# Split train data to X and y**
X_train = train_dataset.drop('UWC', axis = 1)
y_train = train_dataset.loc[:,['UWC']]**# Split test data to X and y**
X_test = test_dataset.drop('UWC', axis = 1)
y_test = test_dataset.loc[:,['UWC']]

2.5 数据转换

一个很好的经验法则是,规范化的数据会在神经网络中产生更好的性能。在这个项目中,我使用来自 scikit-learnMinMaxScaler

我为输入和输出定义了不同的标量,因为它们有不同的形状。这对于使用逆变换功能尤其重要。

  • X_train.shape: (1192,3)
  • y_train.shape: (1192,1)
  • X_test.shape: (299,3)
  • y_test.shape: (299,1)

务必确保输出的比例在 0–1 范围内,以匹配 LSTM、GRU 和比尔斯特姆输出层的激活函数(tanh)的比例。此外,输入变量最好是小值,可能在 0-1 的范围内。

💡****steps❓有哪些数据转换

  • 使用可用的训练数据拟合定标器(MinMaxScaler)(这意味着使用训练数据估计最小和最大可观测值。)
  • 将缩放器应用于训练数据
  • 将定标器应用于测试数据

值得注意的是,我们应该使用训练数据上安装的缩放器来缩放不可见的数据。

**# Different scaler for input and output**
scaler_x = MinMaxScaler(feature_range = (0,1))
scaler_y = MinMaxScaler(feature_range = (0,1))**# Fit the scaler using available training data**
input_scaler = scaler_x.fit(X_train)
output_scaler = scaler_y.fit(y_train)**# Apply the scaler to training data**
train_y_norm = output_scaler.transform(y_train)
train_x_norm = input_scaler.transform(X_train)**# Apply the scaler to test data**
test_y_norm = output_scaler.transform(y_test)
test_x_norm = input_scaler.transform(X_test)

2.6 创建 3D 输入数据集

LSTM、GRU 和比尔斯特姆采用 3D 输入(样本数、时间步数、特征数)。因此,我创建了一个助手函数, create_dataset ,来重塑输入。

在这个项目中,我定义 time_steps = 30。这意味着模型基于最近 30 天的数据进行预测(在 for 循环的第一次迭代中,输入携带前 30 天,输出是第 30 天的 UWC)。

**# Create a 3D input**
def create_dataset (X, y, time_steps = 1):
    Xs, ys = [], []
    for i in range(len(X)-time_steps):
        v = X[i:i+time_steps, :]
        Xs.append(v)
        ys.append(y[i+time_steps])
    return np.array(Xs), np.array(ys)TIME_STEPS = 30X_test, y_test = create_dataset(test_x_norm, test_y_norm,   
                                TIME_STEPS)
X_train, y_train = create_dataset(train_x_norm, train_y_norm, 
                                  TIME_STEPS)
print('X_train.shape: ', X_test.shape)
print('y_train.shape: ', y_train.shape)
print('X_test.shape: ', X_test.shape)
print('y_test.shape: ', y_train.shape)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

步骤 3:创建比尔斯特姆、LSTM 和 GRU 模型

3.1 tensor flow 中的比尔斯特姆、LSTM 和 GRU 模型

第一个函数, create_model_bilstm ,创建一个 BDLSM 并获取隐藏层中的单元(神经元)数量。第二个函数 create_model 获得两个输入;隐藏层中的单元数量和模型名称(LSTM 或 GRU)。

为了简单起见,比尔斯特姆、LSTM 和 GRU 在输入层有 64 个神经元,一个隐藏层包括 64 个神经元,在输出层有 1 个神经元。

为了使 LSTM 和 GRU 模型对变化具有鲁棒性,使用了下降函数。掉线(0.2) 随机掉线 20%的单位。

**# Create BiLSTM model**
def create_model_bilstm(units):
    model = Sequential()
    model.add(Bidirectional(LSTM(units = units,                             
              return_sequences=True),
              input_shape=(X_train.shape[1], X_train.shape[2])))
    model.add(Bidirectional(LSTM(units = units)))
    model.add(Dense(1))
    **#Compile model**
    model.compile(loss='mse', optimizer='adam')
    return model**# Create LSTM or GRU model**
def create_model(units, m):
    model = Sequential()
    model.add(m (units = units, return_sequences = True,
                input_shape = [X_train.shape[1], X_train.shape[2]]))
    model.add(Dropout(0.2))
    model.add(m (units = units))
    model.add(Dropout(0.2))
    model.add(Dense(units = 1))
    **#Compile model**
    model.compile(loss='mse', optimizer='adam')
    return model**# BiLSTM**
model_bilstm = create_model_bilstm(64)**# GRU and LSTM**
model_gru = create_model(64, GRU)
model_lstm = create_model(64, LSTM)

3.2 拟合模型

我用 100 个时期批量 = 32 的训练数据训练模型。我让模型使用 20%的训练数据作为验证数据。我设置 shuffle = False 是因为它提供了更好的性能。

为了避免过度拟合,我设置了一个提前停止,当验证损失在 10 个周期后没有改善时(耐心= 10)停止训练。

**# Fit BiLSTM, LSTM and GRU**
def fit_model(model):
    early_stop = keras.callbacks.EarlyStopping(monitor = 'val_loss',
                                               patience = 10)
    history = model.fit(X_train, y_train, epochs = 100,  
                        validation_split = 0.2, batch_size = 32, 
                        shuffle = False, callbacks = [early_stop])
    return historyhistory_bilstm = fit_model(model_bilstm)
history_lstm = fit_model(model_lstm)
history_gru = fit_model(model_gru)

绘制列车损失和验证损失

在此图中,我将查看每个模型中的时期数,并评估模型在预测中的性能。

**# Plot train loss and validation loss**
def plot_loss (history):
    plt.figure(figsize = (10, 6))
    plt.plot(history.history['loss'])
    plt.plot(history.history['val_loss'])
    plt.ylabel('Loss')
    plt.xlabel('epoch')
    plt.legend(['Train loss', 'Validation loss'], loc='upper right')plot_loss (history_bilstm)
plot_loss (history_lstm)
plot_loss (history_gru)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

BiLSTM 的列车损失与验证损失

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

LSTM 的列车损失与验证损失

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

GRU 的列车损失与验证损失

3.3 逆变换目标变量

建立模型后,我必须使用scaler _ y . inverse _ transform将目标变量转换回原始数据空间,用于训练和测试数据。

y_test = scaler_y.inverse_transform(y_test)
y_train = scaler_y.inverse_transform(y_train)

3.4 使用比尔斯特姆、LSTM 和 GRU 进行预测

在这里,我用比尔斯特姆、LSTM 和 GRU 模型预测 UWC。然后,我绘制了三个模型的真实未来(测试数据)与预测。

**# Make prediction**
def prediction(model):
    prediction = model.predict(X_test)
    prediction = scaler_y.inverse_transform(prediction)
    return predictionprediction_bilstm = prediction(model_bilstm)
prediction_lstm = prediction(model_lstm)
prediction_gru = prediction(model_gru)**# Plot true future vs prediction**
def plot_future(prediction, y_test):
    plt.figure(figsize=(10, 6))
    range_future = len(prediction)
    plt.plot(np.arange(range_future), np.array(y_test), 
             label='True Future')     
    plt.plot(np.arange(range_future),np.array(prediction),
            label='Prediction')
    plt.legend(loc='upper left')
    plt.xlabel('Time (day)')
    plt.ylabel('Daily water consumption ($m^3$/capita.day)')plot_future(prediction_bilstm, y_test)
plot_future(prediction_lstm, y_test)
plot_future(prediction_gru, y_test)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

BiLSTM 模型的真实未来与日用水量预测

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

LSTM 模型的真实未来与日用水量预测

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

GRU 模型的真实未来与日用水量预测

3.5 计算 RMSE 和梅

让我用两个拟合优度来评估模型的性能。

**# Define a function to calculate MAE and RMSE**
def evaluate_prediction(predictions, actual, model_name):
    errors = predictions - actual
    mse = np.square(errors).mean()
    rmse = np.sqrt(mse)
    mae = np.abs(errors).mean()print(model_name + ':')
    print('Mean Absolute Error: {:.4f}'.format(mae))
    print('Root Mean Square Error: {:.4f}'.format(rmse))
    print('')evaluate_prediction(prediction_bilstm, y_test, 'Bidirectional LSTM')
evaluate_prediction(prediction_lstm, y_test, 'LSTM')
evaluate_prediction(prediction_gru, y_test, 'GRU')

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

三个模型的拟合优度表明它们具有非常相似的性能。即便如此,与 LSTM 和 GRU 相比, BiLSTM 模型具有更高的准确性。因此,我使用 BiLSTM 模型对 UWC 未来 10 年进行多步预测。

⚠️ **注意:**这个项目的结果并不意味着 BiLSTM 比 LSTM 和 GRU 有更好的结果。这只是说明如何比较这些模型,以得出最可靠的预测。

步骤 4:10 年用水量的多步预测

我在研究地点导入气候数据预测,并对 2015 年 1 月 1 日至 2025 年 1 月 1 日期间的数据进行过滤。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我创建了一个助手函数, plot_history_future ,来绘制历史和未来的 UWC。然后,我创建了一个函数, *forecast,*来重塑看不见的输入,并使用 LSTM 模型进行预测。

**# Plot histoy and future data**
def plot_history_future(y_train, prediction):
    plt.figure(figsize=(10, 6)) range_history = len(y_train)
    range_future = list(range(range_history, range_history +
                   len(prediction))) plt.plot(np.arange(range_history), np.array(y_train), 
             label='History')
    plt.plot(range_future, np.array(prediction),label='Prediction')
    plt.legend(loc='upper right')
    plt.xlabel('Time (day)')
    plt.ylabel('Daily water consumption ($m^3$/capita.day)')**# Multi-step forecasting** 
def forecast(X_input, time_steps):
    **# Scale the unseen input with the scaler fitted on the train set**
    X = input_scaler.transform(X_input)
    **# Reshape unseen data to a 3D input**
    Xs = []
    for i in range(len(X) - time_steps):
        v = X[i:i+time_steps, :]
        Xs.append(v) X_transformed = np.array(Xs)**# Make prediction for unseen data using LSTM model**
    prediction = model_bilstm.predict(X_transformed)
    prediction_actual = scaler_y.inverse_transform(prediction)
    return prediction_actualprediction = forecast(X_new, TIME_STEPS)
plot_history_future(y_train, prediction)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

基于 BiLSTM 模型的日用水量历史与预测

结论

感谢您阅读这篇文章。我知道这是一个相当长的教程😏我希望它能帮助你在 Tensorflow 中为一个数据科学项目开发 LSTM、GRU 和比尔斯特姆模型😊

非常感谢您的反馈。你可以在 LinkedIn 上找到我。

预测分析作为提高营销效率的工具

原文:https://towardsdatascience.com/predictive-analytics-as-a-tool-to-increase-marketing-efficiency-5b4b9d922524?source=collection_archive---------50-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

来源:沉积照片

收集和存储数据的能力越来越强,为企业提供了更强的追溯和实时分析能力。现在,我们可以追踪模式并得出失败的结论,以免重蹈覆辙。或者我们可以确定最成功的解决方案,并重复我们的成功。

从长远来看,预测分析总是比回顾性或实时分析更有效,就像预防比紧急医疗护理更有效一样。回顾性分析本质上是一次解剖——对一个无法挽回的错误的分析。实时分析是此时此地做出反应的救护车,而预测分析是从一开始就将你从疾病中拯救出来的预防医学。

预测分析的概念

正如托马斯·达文波特所说,没有人有能力收集和分析来自未来的数据。但是我们有机会利用过去的数据预测未来。这被称为预测分析,事实上,许多公司已经在使用它。您可以使用过去的数据来:

  1. 计算客户的终身价值(CLV)。这个指标将帮助你了解客户在一生中会给你的公司带来什么价值,包括未来的收益。
  2. 根据你网站的用户行为数据开发最佳推荐。
  3. 预测客户将来可能会购买什么产品或服务。
  4. 预测客户流失。
  5. 制定下一季度/六个月/一年的销售计划和预测。

所有这些都是预测分析的简单形式。让我们看看流行的预测分析方法。

预测建模

我们可以确定预测建模的以下阶段:

  • 原始数据收集
  • 统计模型形成
  • 预测
  • 随着额外数据的出现,检查/修订模型

预测模型分析用户过去的行为,以评估他们在未来表现出特定行为的可能性。这种类型的分析还涉及发现数据中微妙模式的模型,例如检测欺诈。

通常,当用户在执行转换操作的途中通过转换漏斗时,预测模型会立即进行计算,例如,评估用户实现目标的概率。有了关于从漏斗中的一个步骤过渡到另一个步骤的可能性的准确数据,企业可以更好地管理阻止或帮助用户通过漏斗的因素,并且可以更准确地描述不同类别的客户的行为模式。

您可以在哪里使用预测分析?

普通用户的智能手机上大约有 50 个应用程序。它们中的每一个都接收、传输和生成数据。这些数据以不同的格式存储在不同的服务中。虽然乍一看,这似乎是营销人员的一个积极因素,但有效地处理如此大量的结构化和非结构化数据是一个问题。

让我们看几个成功应用预测分析结果的公司的例子。

亚马逊使用预测营销…

…根据用户过去的行为向他们推荐产品和服务。根据一些报告,这种推荐给亚马逊带来了高达 30%的销售额。此外,亚马逊计划开发一种工具,根据预测,甚至在订单在网站上下单之前,就可以将产品送到预期订单所在的区域,从而缩短向客户交付商品的时间。

梅西百货

梅西的团队利用预测分析进行更准确的直接营销。在三个月的时间里,该公司通过捕捉用户浏览的产品类别数据并相应地发送个性化电子邮件,将其在线销售额从 8%提高到 12%。

哈雷戴维森使用预测分析…

…锁定潜在客户,吸引潜在客户,达成交易。他们识别出准备购买的最有价值的潜在客户。然后,销售代表直接联系这些潜在客户,并引导他们通过销售过程找到最合适的报价。

缝针

StitchFix 是另一家拥有独特的基于预测的销售模式的零售商。注册 StitchFix 时,用户需要完成一项关于他们风格的调查。然后应用预测分析模型为顾客提供他们最可能想要的衣服。如果顾客不喜欢他们收到的衣服,他们可以免费退货。

Sprint 使用人工智能算法来识别有流失风险的客户…

…并预防性地提供关于如何保留它们的必要信息。Sprint 的人工智能预测客户想要什么,并在他们最有可能离开公司的时候为他们提供报价。自从引入这一人工智能系统以来,Sprint 的流失率大幅下降,客户对该公司的个性化服务和有针对性的优惠给予了优异的评价。如您所见,预测客户流失是 SaaS 和电子商务企业预测分析的一项可行任务。

以下是预测分析范围内最受欢迎的指标列表:

  1. 客户外流比率(流失率)
  2. 销售计划预测
  3. 客户终身价值

如何实施预测分析?

如果没有营销和分析部门的合作,没有对研究目标和数据既定顺序的理解,引入预测分析是不可能的。执行预测分析的过程如下:

  1. 定义你的假设
  2. 收集内部和外部数据以构建模型
  3. 定义度量标准来衡量模型的准确性
  4. 使用现成的服务或开发自己的服务:
  • 建立一个 MVP
  • 在缺少准确性参数的情况下训练模型,以获得稳定的工作版本
  • 创建界面或报告
  • 更新或重新训练模型以满足新的要求

在数据收集阶段,确保您已经建立了端到端分析,因为没有它,实施预测分析通常是无效的。

预测分析服务

根据德勤(Deloitte)的《CMO 调查:2019 年春季报告》,基于营销分析的商业决策比例在 2019 年初达到峰值(考虑到过去六年的数据)。根据 MarketsandMarkets 的一项研究,预测分析市场将从 40 亿美元增长到 2022 年的 120 亿美元以上

对营销分析的普遍兴趣,尤其是对预测分析的兴趣,鼓励公司开发易于使用的解决方案和服务,使企业更容易获得预测分析。

以下是其中一些服务:

OWOX 商业智能洞察

  • OWOX BI 产品帮助公司实现营销目标,并以高于市场平均水平 22%的速度增长。
  • G2 在“营销软件-分析”和“电子商务分析软件”类别中的 2019 年春夏排行榜中名列前茅。
  • 将有关营销计划实施的预测直接发送到您的电子邮件中。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由作者提供

OWOX BI:

  • 结合各种来源的营销数据,使其可用于 Google BigQuery 的分析。
  • 使用自己的基于漏斗的归因模型确定每个用户步骤的价值。
  • 自动构建报告以分析营销效果。
  • 展示您的销售计划将如何实施,您的增长领域和弱点是什么,以及您的市场份额如何变化。

暗示

Infer 提供的预测模型将帮助您结合所有数据源,全面了解您的销售线索在销售漏斗中的位置。推断跟踪来自在线来源和公共数据库的信号,然后根据以前的主要账户和您设定的规则创建预测模型。Infer 获得的数据将有助于营销人员和销售专家寻找未来可能转化为客户的线索,并优化整体销售漏斗。

半径

Radius 提供几种数据分析服务,重点是预测性 B2B 营销。主要特性包括:

  • Radius 客户交换(RCX),将您的公司简介与拥有相同受众的其他公司进行比较,让您有机会一起工作并创建自己的营销列表。
  • Radius 连接:向 Salesforce 提交预测数据。

Radius 平台还帮助营销人员在部门之间交换数据,并在内部数据库中找到新账户。和 Infer 一样,Radius 也是一个基于云的系统。

基于预测建模的规则,BOARD 在一个具有实时仪表板的自适应界面中工作。

这意味着您可以对各种场景建模并分析可能的结果,而不必每次都创建新的模型。

BOARD 带有几个内置连接器,因此您可以从几乎任何来源提取数据——您的 ERP 系统、云数据库、OLAP 魔方,甚至平面文件。你也可以使用 BOARD 的工具将你的预测转化为定制应用。

TIBCO 数据科学

TIBCO 数据科学是一款相对较新的产品,于 2018 年 9 月发布。TIBCO Data Science 作为一个单一平台创建,结合了 TIBCO 前几代服务的功能:TIBCO Statistica、Spotfire Data Science、Spotfire Statistics Services 和 TERR。

数据科学服务帮助组织更快地创新和解决复杂问题,将预测快速转化为最佳解决方案。

SAS 高级分析

SAS 拥有预测分析市场 33%的份额和 40 年的经验;它们为用户提供了基于许多可视化编辑器的高级数据分析功能。SAS 高级分析的主要功能基于图表、自动流程图、嵌入式代码和自动时间规则。

根据用户评论,SAS Advanced Analytics 在预测和分析整体移动方面表现出色,可以相对较快地处理大型数据集。SAS 提供免费的产品演示和知识库来帮助您开始使用它们。

快速采矿机

该软件允许您根据时间间隔自动创建报告。由于 60 多个内置集成,您可以导入自己的数据集,并将其导出到其他程序。

扩展提供了更大的灵活性(异常检测、文字处理、web 挖掘),但可能不包括在基本订阅价格中

虽然 RapidMiner 是为数据科学家设计的,但它很容易安装和开始使用。

IBM SPSS

IBM SPSS 使用基于统计的数据建模和分析。该软件适用于结构化和非结构化数据。它可以在云中、本地或通过混合部署来满足任何安全性和移动性要求。

您可以使用现有数据在 SPSS 可视化编辑器和建模仪表板中构建预测模型。对非结构化数据的高级支持包括语言技术和自然语言处理,因此您可以在模型中包括来自社交网络和其他基于文本的来源的数据。

SAP HANA

SAP HANA 在本地或云中提供数据库和应用程序。该软件通过为大型外部数据集和直观可视化添加连接器,减少了创建模型所需的时间。

您还可以将预测分析库(PALs)连接到 SAP HANA,以从大型数据集获得额外的洞察力。对于以客户为中心的行业,该软件提供文本和社交媒体数据分析,以预测未来的客户行为,并根据过去的行为推荐产品。

SAP HANA 与 R 编程语言兼容,因此您不需要学习新的语言来配置您的查询。当您的系统集成了足够多的内部数据时,预测模型会自动提供新的见解。

总结

营销中的预测分析是一个强大的数据科学工具,其功能无法在一篇文章中涵盖。

提醒一下,以下是预测分析的三条戒律:

  • 从基础开始:检查数据的质量,并自动收集数据以消除人为错误。训练模型的质量取决于训练数据的质量。
  • 永远不要远离你研究的目标,因为重要的不是过程,而是结果。
  • 遵守精度要求。请记住,您的预测结果只能通过测量经过验证的模型在应用于您的数据时的准确性来验证。

支持向量机(SVM)和 Plotly 的客户预测分析

原文:https://towardsdatascience.com/predictive-analytics-on-customer-behavior-with-support-vector-machines-svm-7e68fd2be610?source=collection_archive---------12-----------------------

现实世界中的数据科学

围绕客户行为和人口统计的大数据的兴起,为利用预测分析的数字营销战略打开了一个可能性的世界。

营销和客户分析是当今世界最热门的数据科学应用领域之一。为了利用可用数据,现代企业需要分析工具来提供他们所需的洞察力,以提供个性化的消费者体验。在本文中,我们将探索一种被称为支持向量机(SVM)的监督机器学习算法。像这样的分类算法可以增加我们对客户的了解,并改进我们的营销和参与策略。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

美国宇航局在 Unsplash 拍摄的照片

背景

现代客户的特点是他们对控制、连通性和便利性的需求。竞争日益激烈的全球市场将控制权交到了客户手中。当他们想要的时候,他们知道自己想要什么。惊喜!就是现在。

社交媒体和其他资源赋予了客户权力,使他们能够研究、探索、分享和比较。现代消费者关注其他人的评论和意见,一个感性的评论可以成就一个品牌,也可以毁掉一个品牌。

最后,现代消费者已经完全颠覆了对便利的传统理解。现代技术创造了对媒体和服务的期望,只需按一下按钮就可以获得。很快,Alexa 就会在我们用完纸巾的前一天,根据世界各地流感爆发的数据,结合我们认为她没在听时记录的喷嚏频率,自动给我们送来一盒新纸巾。(这是我在 Covid 打之前写的…)

目标

换句话说,真正的便利意味着客户需要的产品会来到他们身边。为了在顾客所在的地方见到他们,你必须了解他们。个人主义时代创造了独特的消费者,他们只会对迎合他们的营销体验做出反应。

通过这个项目,我们将探索汽车保险销售的客户数据。我们的目标是发现什么样的营销方法对特定的客户群最有效。到这个项目结束时,我们将能够根据客户的人口统计数据和过去的行为数据来预测客户是否会对销售电话做出回应。

在我的 GitHub 上找到数据和 Jupyter 笔记本

首先,我们将首先探索我们的客户群…

使用 Plotly 进行探索性数据分析(EDA)

导入包。Plotly 是 Python 中现代数据可视化的标准。

我们对这个项目感兴趣的主要变量是“响应”。它是一个二元变量,表示客户是否对营销电话作出了回应。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

接下来,我们将探讨销售人员采取的行动如何影响回复率。这些因素是销售渠道更新报价类型。为了快速执行描述性分析,我们将利用 Plotly Express ,一个 Plotly 图形对象的高级包装器。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从第一张图中,我们发现代理人的成功率似乎最高。第二个图表显示,要约类型 3 和 4 相对无效。

现在,让我们探索一些人口统计信息,看看什么类型的客户最有可能对我们的营销优惠做出回应。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

受教育程度较高的人似乎不太可能对工作做出回应。与第一张图表类似,拥有豪华汽车的客户似乎不太可能对报价做出反应。

如何才能进一步探究财富与回复率之间看似负相关的关系?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

该图进一步支持了当前的营销努力对低收入客户更有效的观点。但是,它也显示了这个样本中的大多数客户都属于低收入阶层。

在我们进入分类模型之前,让我们看看哪些特征与我们的响应变量具有最强的相关性。

连续变量回归分析

当因变量为二元时,逻辑回归是适当的回归分析。逻辑回归用于描述数据,并解释一个因变量和一个或多个自变量之间的关系。

在这种情况下,我们将使用逻辑回归来确定哪些变量(如果有的话)对客户响应销售电话的概率有影响。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们可以从收入的 p 值、每月保费汽车、自上次索赔以来的月数、自保单生效以来的月数、公开投诉数量、保单数量中看到,这些输入变量似乎与目标变量响应具有显著关系。“coef”栏告诉我们,这些变量都与响应负相关

我们如何解释 P 值?

p 值评估样本数据支持零假设的程度。在这种情况下,我们的零假设是变量对于预测因变量 Response 是不重要的。

p 值只有在与 alpha 值比较时才有用。小于标准α值 0.05 的 p 值可被认为对因变量有显著影响。

换句话说,p 值是在零假设为真的情况下,观察到该样本中变量之间这种关系的概率。

如果在随机抽取样本的人群中,零假设是正确的,那么在我们现有的样本量中,得到至少和我们得到的一样极端的检验统计量的可能性有多大?彼得·弗洛姆

分类变量回归分析

标签编码

大多数机器学习算法需要将分类变量转换为数值,并且许多算法的性能根据分类变量的编码方式而变化。在这种情况下,我们所有的分类数据都是名义数据,而不是序数数据。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如您所见,每个类别都被赋予一个从 1 到 N 的值(其中 N 是特性的类别数。)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

婚姻状况、续保类型、销售渠道、车辆大小、政策变量的 p 值在 0.05 显著性水平上显著。同样,这些变量与响应有负关系

连续变量和分类变量的回归分析

我将让您自己检查这个输出。你能告诉我们在分类模型中包含哪些重要的变量吗?一个有趣的观察是,具有更高客户终身价值的客户似乎不太可能响应营销电话。

那么,为什么我们花了这么多时间去寻找“重要的关系”呢?这是被称为特征工程的过程的一部分。如果我们想要使用分类算法来预测未来的客户是否会对营销电话作出响应,我们想要查看那些与因变量有显著关系的特征(变量的别称)。去掉对结果没有影响的变量有很多好处。它不仅降低了模型中的噪声,还降低了模型训练所需的处理能力。

支持向量机分类算法

支持向量机是一种监督 ML 算法,可用于分类和回归。在此算法中,每个数据项都被绘制为 n 维空间中的一个点(其中 n 是您拥有的要素数量。)然后,找到在 N 维空间中最好地分离类别的超平面。

让我们用这幅插图来探索一下超平面的概念,这是我花了太长时间拼凑的:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

支持向量是来自最接近超平面的每个类的数据点。SVM 的目标是最大化两个阶级之间的差距。如果我们移动上面例子中的一个支持向量,超平面也会随之移动。

在我们没有像上面例子那样的线性可分数据的情况下(这在现实中是经常发生的),内核的技巧就派上用场了。内核技巧背后的思想是将非线性可分离的数据映射到一个更高维的空间,在那里我们可以创建一个超平面来实际分离这些类。请看这张令人惊叹的 GIF 图片:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们将把内核技巧留给另一个项目。现在,让我们继续把我们的数据分成训练集和测试集。这是数据科学过程中的一个关键步骤,它允许您诚实地评估模型的性能。这一过程有助于保护您的模型不过度拟合。但是,如果您的样本不能代表您希望将模型应用到的人群,那么您如何对数据进行分割并不重要。

我们将使用的另一种方法是交叉验证。如下图所示,它将数据分割成您选择的 K 个(在本例中,K=5)集合。K-1 个子集用于训练我们的数据,最后一个子集用于测试。我们将 K 个“折叠”的平均准确度作为我们的最终度量。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

有关训练/测试分割和交叉验证的更多信息,请查看本文

Scikit-Learn 屡试不爽。让我们看看这个模型能做什么。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

正如我们所看到的,训练/测试分割和交叉验证技术都产生了非常可靠的指标。基于这一结果,我们对利用这一模型预测客户回复率的能力充满信心。

结论

如果给我们一份客户名单和他们的人口统计数据,我们可以利用从这个项目中收集到的洞察力来制定关于如何与该客户互动的战略决策。

感谢阅读!我希望这篇文章既有趣又有见地。我很开心地完成了我的第一篇文章,也很难放下我的完美主义,点击发表,哈哈。我欢迎任何建设性的反馈。随时在 LinkedIn 上联系我!

预测分析:用 TensorFlow 中的 GRU 和比尔斯特姆进行时间序列预测

原文:https://towardsdatascience.com/predictive-analytics-time-series-forecasting-with-gru-and-bilstm-in-tensorflow-87588c852915?source=collection_archive---------0-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Enrique Alarcon 在 Unsplash 上拍摄的照片

为时序预测构建 GRU 和双向 LSTM 的分步教程

R 当前的神经网络被设计用来处理时序分析中序列相关性的复杂性。在本教程中,我为一个单变量时间序列预测模型建立 GRU 和比尔斯特姆。门控循环单元(GRU)是新一代的神经网络,非常类似于长短期记忆(LSTM)。而双向 lstm(bil STM)的思想是在 LSTM 模型中聚合特定时间步长的过去和未来的输入信息。

下面这篇文章很好地介绍了 LSTM、GRU 和比尔斯特姆。

[## 预测分析:TensorFlow 中的 LSTM、GRU 和双向 LSTM

关于开发 LSTM、GRU 和双向 LSTM 模型来预测用水量的分步指南

towardsdatascience.com](/predictive-analysis-rnn-lstm-and-gru-to-predict-water-consumption-e6bb3c2b4b02)

什么是时间序列分析?

与回归分析不同,在时间序列分析中,我们没有强有力的证据表明什么影响了我们的目标。时间序列分析使用时间作为变量之一,以观察是否随时间发生变化。

什么是时间序列预测?

时间序列预测的目的是根据历史数据拟合一个模型,并使用它来预测未来的观测值。这篇文章致力于使用深度学习方法进行时间序列预测。如果你愿意学习时间序列预测的经典方法,我建议你阅读这个网页

☺让我们去 code❗

👩‍💻 上的 Python 代码 GitHub

资料组

对于本项目,数据为加拿大魁北克省 Brossard 市 2011 年 9 月 1 日至 2015 年 9 月 30 日的日用水量。

导入库

import pandas as pd
import numpy as np
import matplotlib.pyplot as pltfrom sklearn.preprocessing import MinMaxScaler, StandardScalerimport warnings
warnings.filterwarnings(‘ignore’)from scipy import stats
%matplotlib inlineimport tensorflow as tf
from tensorflow import keras
from tensorflow.keras import Sequential, layers, callbacks
from tensorflow.keras.layers import Dense, LSTM, Dropout, GRU, Bidirectional

设置随机种子

tf.random.set_seed(1234)

1.读取和浏览数据

在这个项目中,我处理的是单变量时间序列数据。当我从 CSV 文件导入数据时,我通过 parse_dates = [‘Date’] 确保 Date 列具有正确的 DateTime 格式。此外,当我处理日期和时间时,如果我将日期列设置为 dataframe 索引,就会变得容易得多。

df = pd.read_csv(‘Data.csv’, parse_dates = [‘Date’])

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1.1 时间序列图

为了更好地理解数据,我绘制了每日、每月和每年的用水量。

**# Define a function to draw time_series plot**def timeseries (x_axis, y_axis, x_label):
    plt.figure(figsize = (10, 6))
    plt.plot(x_axis, y_axis, color =’black’)
    plt.xlabel(x_label, {‘fontsize’: 12}) 
    plt.ylabel(‘Water consumption ($m³$/capita.day)’, 
                                  {‘fontsize’: 12})
dataset = df.copy()
timeseries(df.index, dataset[‘WC’], ‘Time (day)’)dataset[‘month’] = dataset.index.month
dataset_by_month = dataset.resample(‘M’).sum()
timeseries(dataset_by_month.index, dataset_by_month[‘WC’], 
           ‘Time(month)’)dataset[‘year’] = dataset.index.year
dataset_by_year = dataset.resample(‘Y’).sum()
timeseries(dataset_by_year.index, dataset_by_year[‘WC’], 
           ‘Time (month)’)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

日用水量时间序列

你可以看到数据有一个季节性的模式。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

月用水量时间序列

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

年用水量时间序列

1.2 处理缺失值

首先,我想检查缺失值的数量,并确定没有数据值存储的日期。然后我使用线性插值来替换丢失的值。

**# Check for missing values**
print(‘Total num of missing values:’) 
print(df.WC.isna().sum())
print(‘’)
**# Locate the missing value**
df_missing_date = df.loc[df.WC.isna() == True]
print(‘The date of missing value:’)
print(df_missing_date.loc[:,[‘Date’]])**# Replcase missing value with interpolation**
df.WC.interpolate(inplace = True)**# Keep WC and drop Date**
df = df.drop('Date', axis = 1)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1.3 将数据集分为训练和测试数据

像我通常做的那样,我将前 80%的数据设置为训练数据,剩下的 20%为测试数据。我用训练数据训练模型,并用测试数据验证其性能。

💡提醒一下,您必须使用 iloc 根据索引位置找到数据帧的子集

**# Split train data and test data**
train_size = int(len(df)*0.8)

train_data = df.iloc[:train_size]
test_data = df.iloc[train_size:]

1.4 数据转换

一个很好的经验法则是,规范化的数据会在神经网络中产生更好的性能。在这个项目中,我使用来自 scikit-learnMinMaxScaler

您需要遵循三个步骤来执行数据转换:

  • 使用可用的训练数据拟合定标器(MinMaxScaler)(这意味着使用训练数据估计最小和最大可观测值。)
  • 将缩放器应用于训练数据
  • 将定标器应用于测试数据

💡需要注意的是, MinMaxScaler()的输入。fit() 可以是数组状或数据帧状(n_samples,n_features)。在这个项目中:

train_data.shap = (1192,1)

scaler = MinMaxScaler().fit(train_data)
train_scaled = scaler.transform(train_data)
test_scaled = scaler.transform(test_data)

1.5 创建输入

GRU 和比尔斯特姆采用一个三维输入(数量 _ 样本,数量 _ 时间步长,数量 _ 特征)。因此,我创建了一个助手函数 create_dataset ,来重塑输入。

在这个项目中,我定义 look_back = 30。这意味着模型基于最近 30 天的数据进行预测(在 for-loop 的第一次迭代中,输入携带前 30 天,输出是第 30 天的用水量)。

**# Create input dataset**
def create_dataset (X, look_back = 1):
    Xs, ys = [], []

    for i in range(len(X)-look_back):
        v = X[i:i+look_back]
        Xs.append(v)
        ys.append(X[i+look_back])

    return np.array(Xs), np.array(ys)LOOK_BACK = 30X_train, y_train = create_dataset(train_scaled,LOOK_BACK)
X_test, y_test = create_dataset(test_scaled,LOOK_BACK)**# Print data shape**
print(‘X_train.shape: ‘, X_train.shape)
print(‘y_train.shape: ‘, y_train.shape)
print(‘X_test.shape: ‘, X_test.shape) 
print(‘y_test.shape: ‘, y_test.shape)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2.创建模型

第一个函数, create_bilstm ,创建一个 BiDLSM 并获取隐藏层中的单元(神经元)数量。第二个函数, create_gru ,构建一个 gru 并获得隐藏层中的单元数。

两者在输入层都有 64 个神经元,一个隐层包括 64 个神经元,在输出层有 1 个神经元。两个模型中的优化器都是 亚当 。为了使 GRU 模型对变化具有鲁棒性,使用了下降函数。掉线(0.2) 随机掉线 20%的单位。

**# Create BiLSTM model**
def create_bilstm(units):
    model = Sequential()
    **# Input layer**
    model.add(Bidirectional(
              LSTM(units = units, return_sequences=True), 
              input_shape=(X_train.shape[1], X_train.shape[2])))
    **# Hidden layer**
    model.add(Bidirectional(LSTM(units = units)))
    model.add(Dense(1))
    **#Compile model**
    model.compile(optimizer=’adam’,loss=’mse’)
    return modelmodel_bilstm = create_bilstm(64)**# Create GRU model**
def create_gru(units):
    model = Sequential()
    **# Input layer**
    model.add(GRU (units = units, return_sequences = True, 
    input_shape = [X_train.shape[1], X_train.shape[2]]))
    model.add(Dropout(0.2)) 
    **# Hidden layer**
    model.add(GRU(units = units)) 
    model.add(Dropout(0.2))
    model.add(Dense(units = 1)) 
    **#Compile model**
    model.compile(optimizer=’adam’,loss=’mse’)
    return modelmodel_gru = create_gru(64)

2.1 拟合模型

我创建一个函数, fit_model ,获取模型并用 100 个时期batch_size = 16 的训练数据训练模型。我让模型使用 20%的训练数据作为验证数据。我设置 shuffle = False 是因为它提供了更好的性能。

为了避免过度拟合,我设置了一个提前停止,当验证损失在 10 个周期后没有改善时(耐心= 10)停止训练。

def fit_model(model):
    early_stop = keras.callbacks.EarlyStopping(monitor = ‘val_loss’,
                                               patience = 10)
    history = model.fit(X_train, y_train, epochs = 100,  
                        validation_split = 0.2,
                        batch_size = 16, shuffle = False, 
                        callbacks = [early_stop])
    return historyhistory_gru = fit_model(model_gru)
history_bilstm = fit_model(model_bilstm)

2.2 目标变量的逆变换

建立模型后,我必须使用scaler . inverse _ transform将目标变量转换回训练和测试数据的原始数据空间。

y_test = scaler.inverse_transform(y_test)
y_train = scaler.inverse_transform(y_train)

3.评估模型的性能

我们将如何评价 GRU 和比尔斯特姆的表现?

1-绘制训练损失和验证损失

为了评估模型性能,我绘制了训练损失与验证损失的关系图,我预计验证损失低于训练损失😉

2-比较预测和测试数据

首先,我用比尔斯特姆和 GRU 模型预测 WC。然后,我绘制了两个模型的测试数据与预测。

3-计算 RMSE 和梅

我使用两种拟合优度来评估模型的准确性。

3.1 绘制列车损失和验证损失

def plot_loss (history, model_name):
    plt.figure(figsize = (10, 6))
    plt.plot(history.history[‘loss’])
    plt.plot(history.history[‘val_loss’])
    plt.title(‘Model Train vs Validation Loss for ‘ + model_name)
    plt.ylabel(‘Loss’)
    plt.xlabel(‘epoch’)
    plt.legend([‘Train loss’, ‘Validation loss’], loc=’upper right’)

plot_loss (history_gru, ‘GRU’)
plot_loss (history_bilstm, ‘Bidirectional LSTM’)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3.2 比较预测和测试数据

**# Make prediction**
def prediction(model):
    prediction = model.predict(X_test)
    prediction = scaler.inverse_transform(prediction)
    return predictionprediction_gru = prediction(model_gru)
prediction_bilstm = prediction(model_bilstm)**# Plot test data vs prediction**
def plot_future(prediction, model_name, y_test):
    plt.figure(figsize=(10, 6))
    range_future = len(prediction)
    plt.plot(np.arange(range_future), np.array(y_test), 
             label=’Test   data’)
    plt.plot(np.arange(range_future), 
             np.array(prediction),label=’Prediction’) plt.title(‘Test data vs prediction for ‘ + model_name)
    plt.legend(loc=’upper left’)
    plt.xlabel(‘Time (day)’)
    plt.ylabel(‘Daily water consumption ($m³$/capita.day)’)

plot_future(prediction_gru, ‘GRU’, y_test)
plot_future(prediction_bilstm, ‘Bidirectional LSTM’, y_test)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3.3 计算 RMSE 和梅

def evaluate_prediction(predictions, actual, model_name):
    errors = predictions — actual
    mse = np.square(errors).mean()
    rmse = np.sqrt(mse)
    mae = np.abs(errors).mean()
    print(model_name + ‘:’)
    print(‘Mean Absolute Error: {:.4f}’.format(mae))
    print(‘Root Mean Square Error: {:.4f}’.format(rmse))
    print(‘’)evaluate_prediction(prediction_gru, y_test, ‘GRU’)
evaluate_prediction(prediction_bilstm, y_test, ‘Bidirectiona LSTM’)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

4.30 天用水量的多步预测

为了使用经过训练的 GRU 和比尔斯特姆模型进行预测,我需要至少 60 天的观察数据来预测未来 30 天的情况。为了便于说明,我从观测数据中选择了 60 天的用水量,并用 GRU 和比尔斯特姆预测了未来 30 天的用水量。

**# Make prediction for new data**
def prediction(model):
    prediction = model.predict(X_30)
    prediction = scaler.inverse_transform(prediction)
    return predictionprediction_gru = prediction(model_gru)
prediction_bilstm = prediction(model_bilstm)**# Plot history and future**
def plot_multi_step(history, prediction1, prediction2):

    plt.figure(figsize=(15, 6))

    range_history = len(history)
    range_future = list(range(range_history, range_history +
                        len(prediction1))) plt.plot(np.arange(range_history), np.array(history), 
             label='History')
    plt.plot(range_future, np.array(prediction1),
             label='Forecasted for GRU')
    plt.plot(range_future, np.array(prediction2),
             label='Forecasted for BiLSTM')

    plt.legend(loc='upper right')
    plt.xlabel('Time step (day)')
    plt.ylabel('Water demand (lit/day)')

plot_multi_step(new_data, prediction_gru, prediction_bilstm)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

结论

感谢您阅读这篇文章。我希望它能帮助你在 Tensorflow 中开发用于时间序列预测的 GRU 和比尔斯特姆模型😊

非常感谢您的反馈。你可以在 LinkedIn 上找到我。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值