利用卡尔曼滤波器预测冠状病毒传播
本文介绍了在线实时卡尔曼滤波算法的实现,以预测每个给定区域的新冠肺炎传播。
冠状病毒(新冠肺炎)最近引起了世界范围的关注。
据报道,随着冠状病毒病例数量的增加,新冠肺炎的传播对全球健康构成了严重威胁。在这项工作中,我们将尝试预测冠状病毒在每个感染区域的传播。拟合时间序列分析和统计算法,以产生最佳的短期和长期预测。自适应在线卡尔曼滤波器为我们提供了每个地区非常好的一天预测。
首先,让我们简单地将新冠肺炎病毒与一种更古老的致命病毒——伊波拉病毒进行比较。埃博拉不是一种新疾病(第一例病例于 1976 年发现),但在 2014 年和 2018 年,它再次爆发,直到这些天。
*与新冠肺炎约 3.9%的死亡率相比,埃博拉病毒的死亡率更高,可能达到 75%的死亡病例。必须注意的是,新冠肺炎是一种持续的疾病,因此死亡率不是最终的,很可能会增加。
*地点和国家明显不同,埃博拉病毒主要危害非洲和中国及亚洲的新冠肺炎。
*新冠肺炎似乎最有可能在寒冷的天气传播,而埃博拉在温暖的天气传播。
*两者之间的喷发趋势似乎非常相似,两种疾病都表现出迅速有力的喷发。
为了预测冠状病毒的传播,我使用了卡尔曼滤波算法和其他线性模型。优化问题是用 Python 解决的,而脚本可以在 Google Colab 笔记本中找到。这个项目的过程描述如下,完整的代码可以在 Github 这里找到。
预处理数据: *从 Github 中读取数据-包含世界卫生组织数据下每个地点每日确诊、死亡和康复的总病例数。
*固定地区名称并将国家和省连接到一列“地区”。然后,清除数据集中的一些错误字符。
获取人口: 我使用了 python 的“qwikidata”包,它根据地区坐标(经度,纬度)从维基百科中提取人口数据。我们将使用这些数据来评估每个区域的感染率,并在模型中进行测试。
创建时间序列和图表 该脚本允许我们生成每个区域的可视化图表,以获得关于数据的初步见解。绝大多数病例发生在中国湖北(82%),因此提取了不同的地块。
以下是每日总病例数排名靠前的区域。
证实 :
湖北等地区确诊病例总数
我们可以看到一个明显的喷发趋势在湖北与异常日 13.02.20 的一个高跳。在那一天,计数方法发生了变化,这将在以后影响模型。我们无法验证数据的可信度,但假设数据是可靠的。在其他顶级领域,趋势似乎有所不同,也不那么明显。钻石公主号游轮似乎与众不同,自 2 月中旬以来出现了急剧的趋势。(粉色线)
死亡:
*死亡病例以湖北居多,超过 2000 例。之后,河南以 19。
*湖北死亡率为 2.1978%,河南为 1.5055%。在其他地区,人数太少。
湖北等地区总死亡病例
痊愈:
*所有地区的痊愈病例呈急剧趋势,主要在湖北,这可能暗示我们有一个积极的未来。
湖北等地区痊愈病例总数
拟合预测模型阶段 1-一日预测卡尔曼滤波器
我实现了一个卡尔曼滤波算法来解决这个问题,并为每个病例生成 1 天的预测——确诊、死亡、康复;对于每个地区。
卡尔曼滤波器是一种递归算法,它使用随时间推移的时间序列测量值,包含统计噪声并产生未知变量的估计值。我建立了一个在线实时算法。这种算法是自适应的,意味着它不需要大量的历史/训练数据。每天,该算法都会根据新的观察结果进行更新,在完成估计后,它可以生成第二天的预测。
卡尔曼滤波器显示出预测第二天观测值的非常好的结果。它分别跟踪每个区域的趋势,快速调整序列并生成预测。由于我们不需要训练集和测试集,所以评估模型很容易。没有过度拟合或偏见——这是一个在线算法。
实现: 我写了一个 R 脚本来实现一个在线卡尔曼算法,然后使用了 Python 的‘rpy 2’包,它允许我们在 Python 笔记本内部组合 R 脚本并传递结果变量。
短暂初始化后,算法开始跟踪序列,并为每个区域生成 1 天预测。它在每个可能的区域运行。
结果和评估: 为了评估结果,我为每个区域添加了一些基本的误差估计参数:MSE——均方误差,RMSE——均方根误差,MAE——平均绝对误差。我将它们与其他方法进行了比较,以优化模型并找到最佳方法。
该模型也可通过如下所示的图表进行评估。
该脚本允许选择区域并获得合适的绘图和预测。它对每个区域迭代运行。以下是几个例子:
A.北京:橙色线是卡尔曼预测,蓝色线是真实的证实的病例——如前所述,这不是偏差预测,它总结了以前的在线预测。
我们可以看到近乎完美的契合:
卡尔曼预测与实际值-北京
下表显示了预测值与实际值的接近程度。
例如,2010 年 2 月 19 日,卡尔曼预测 394 例,其中 7 例为新确诊病例,而实际为 6 例。明天(20.02.20)卡尔曼预测北京新增 5 例确诊病例。
每日确认的预测与实际-北京
B.湖北但它适应得很快,几天后,将获得更好的预测。
卡尔曼预测 vs 湖北实际确诊病例
下图显示了湖北死亡病例的高预测率
卡尔曼预测 vs 湖北实际死亡病例
下表以数字显示了预测和实际死亡,在湖北。例如,在 18.02,卡尔曼预测有 140 人死亡,而实际死亡人数是 132 人。2002 年 19 月 19 日,卡尔曼预测有 129 人死亡,而实际死亡人数是 108 人。对于明天(20.02),卡尔曼预测另外 132 个新的死亡病例。预测值非常接近真实值。
每日死亡预测与实际-湖北
痊愈每日预测:对于湖北痊愈病例的急剧趋势,我们可以得到一些积极的见解。
卡尔曼预测适应了这一趋势,并预测最近恢复的病例数量会增加。
卡尔曼预测与湖北实际恢复案例
C.上海——证实了的预测。这里也有非常接近真实值的每日预测
卡尔曼预测与实际值-上海
D.河南——有超过 1200 例确诊病例的地区——再次非常好的预测,采用了最近几天确诊病例较少的趋势。
卡尔曼预测与实际值-河南
河南收复预测:
卡尔曼预测与实际值-河南
20 年 2 月 19 日,卡尔曼预测有 56 个新的恢复案例,最终有 51 个。明天它预测又有 48 个新的康复病例。
与湖北类似,我们可以看到最近恢复案例的良好趋势和算法的良好适应性。
每日恢复预测与实际—河南
E.另一个有趣的地区是靠近日本的知名钻石公主号游轮。
**这个系列的行为与其他地区完全不同,尽管如此,卡尔曼的预测还是做得很好。**2 月初船上爆发过病例,随后急剧增加。卡尔曼预测明日(20.02.2020)又有 46 宗新个案。
卡尔曼预测与实际值-钻石公主号游轮
拟合预测模型第 2 阶段—随时间传播和新病例
卡尔曼算法是非常强大的,并提供了一个很好的指示什么将是明天。
但要预测更长的时期,这是不够的。(提醒这是在线算法)。
我拟合了一个线性模型来预测新冠肺炎随时间的传播。
想法是使用时间序列算法,如 Kalman,并将它们作为另一个机器学习算法的特征发送,以及其他应该考虑的特征,如天气、人口、感染率等。
数据不稳定,因此随机森林回归等 ML 模型不太适用。最终,我使用了一个依赖于卡尔曼预测的线性模型。
创建数据集 线性模型的数据集包含不同的结构,其中:
*每行代表日期和地区。
*每列代表特征/变量,其中目标变量为确诊/死亡/恢复病例数。
特征工程:
天气数据: 我已经使用 python 'pyweatherbit '包提取每个区域坐标(经度,纬度)的历史和预报天气数据。这个包需要一个 API 密匙,每天限制为 500 个调用,所以我运行了几天,然后将数据存储在 CSV 文件(w.csv 和 w_forecast.csv)中,以将其与 Github 数据合并。我已经提取了每天和每个地点的最低和最高温度。(预测限于 14 天,对于更长的时间,我已经做了一个班轮温度预测)。
湖北每日最低和最高温度
下表显示了最高感染地区的平均温度(从 2010 年 1 月 22 日至 2010 年 2 月 17 日)。我们可以看到大部分地区(除了广东)天气相当寒冷,最高平均温度不超过 12-13 度,最低不超过 5 度。
大多数受感染地区的平均温度
疫区数据: 我用人口数据和每天的总确诊病例,计算出每个地区每天的感染率,用百分比表示。这个特性在最终的模型中很重要。
特性列表: 模型中被测试的特性:
1。最低-最高温度。
2。每个地区的感染率。
3。最后一天总计。
4。最近 X 天的变化(x=1,3,7)。
5。过去 X 天的变化率。
6。卡尔曼的预测。
7。地区。
8。人口。
9。确认/死亡/康复—目标变量。
相关矩阵:
在下图中我们可以看到变量之间的相关矩阵。
*不出所料,它们之间有 X 天的变化/速率相关。(所有时变特征)
*卡尔曼和时变变量与目标相关。
*感染率也与目标有较高的相关性。
*最低-最高温度与目标的相关性非常低。(但这并不意味着它们没有帮助)。
所有变量之间的相关矩阵
功能重要性 我已经使用了 python‘H20’包,并为湖北地区运行了一个单独的模型。
下面的结果显示了最重要的特征:
卡尔曼的预测是显著的,只要其他与时间有关的特征。
感染率是的一个重要特征,将在最终模型中使用。
随机森林特征重要性
最终模型 通常在训练 ML 模型时,我们需要将我们的数据分成训练/测试集(75%到25%)。
由于我们处理的是时变非平稳序列,这种方法并不适合。我通过模仿一个每天训练模型并预测第二天的迭代“在线”系统解决了这个问题。
然后,我没有得到真实值的反馈,而是用上一次预测加上一些计算出来的噪声更新了下一个时间戳值,并再次预测。
每天所有的功能都在更新(卡尔曼、感染率、天气预报和最近 X 天的计算)。
在评估了几个模型后,我选择了一个使用 python‘sk learn’包的简单线性回归模型。
结果: 脚本允许我们选择每个地区并得到总确诊、死亡和痊愈病例的预测。这里我展示了湖北和其他主要地区的地图。
湖北 — 确诊 :
预测显示湖北未来确诊病例越来越少,但预计下个月会超过 10 万例确诊病例。
一个月证实了湖北预测
根据预测,下个月湖北将有 3100 人死于新冠肺炎。到目前为止,湖北已有 2156 人死亡(19.02.20)。
一个月死亡预测湖北
康复- 这种正向预测显示了湖北康复人的良好步伐。根据这一预测,下个月将有 8 万多人从冠状病毒中康复。
一个月恢复预测湖北
主要地区: *我们可以看到,在许多地区,下个月的预测显示几乎没有扩散。所有的底线和曲线的斜率不变。
*基于这一预测,大规模爆发已经过去,趋势显示确诊病例越来越少,甚至在顶部地区,如浙江、河南、安徽、广东(图表中的前 4 行)。
- 钻石船预计会得到越来越多的确认发布——直到船上的人全部撤离。这应该很快就会发生,然后就不会有更多的预测了。(第 5 行浅蓝色)
一个月证实了主要地区预测
死亡:根据大部分地区的预测,我们不会看到死亡病例的增加。主要关注的地区是河南,预计下个月将有近 40 人死亡(今天有 19 人)
主要地区一个月死亡预测
恢复 —预测显示下个月恢复率将增加。越来越多的人将从新冠肺炎被解救出来。
一个月恢复了主要地区预测
热图: 为了呈现预测的另一种可视化,我使用 python 包“gmplot”来显示谷歌地图上的预测。
该地图根据该区域的坐标显示了具有高感染位置的热点。
观测是对每个地区下个月的预测。谷歌的 API 不再是免费的,所以这个版本是有限的,但它确实显示了受感染的位置。
基于下个月预测的受感染位置热图
基于下个月预测的受感染位置热图。不包括湖北
结论
- 最终模型预测未来 30 天或更长时间内新冠肺炎病毒的趋势。一天的卡尔曼预测非常准确和强大,而更长时间的预测更具挑战性,但提供了未来趋势。
- 看起来感染的高峰已经过去了,这一趋势的预测显示,确诊人数减少,痊愈人数增加。
- 在分析结果时,有必要将湖北与其他地区分开。
- 天气特征不可能是一个重要特征,因为模型从未看到新冠肺炎传播在炎热天气中的表现,但温度确实稍微改善了结果。根据感染最严重地区的平均天气,我们可以假设,一旦这些地区天气变暖(~20 度或更高),确诊病例将会减少。在湖北,这样的天气预计从 4 月中旬开始。
- 感染率是影响传播的主要特征之一——该模型发现它尤其与湖北和钻石公主船相关。该模型无法预测影响感染率的地区之间的人员流动。因此,根据这一数据,预测哪些新的国家将受到影响是不相关的,但一旦它们受到影响,该模型将预测这些新地区的传播。
- 根据积极的复苏趋势预测、中国政府对湖北的隔离以及中国即将出现的温暖天气****我认为新冠肺炎疫情在三月底会大幅减少**。但在此之前,感染者向其他地区的转移可能会改变现状…**
就这样,感谢您的阅读。请随时联系我,分享您的想法、问题或反馈。
更新的预测可以在这里找到
使用 KDTree 检测多维数据集中的相似性
找到完美匹配的快速简单的方法
艾莉娜·格鲁布尼亚克在 Unsplash 上的照片
真实生活的例子
大多数数据科学都面向训练、测试、预测范式。未来谁不想猜啊!但在某些情况下,需要其他实现,如无监督分类或在现有数据中发现模式。换句话说,如何利用已经拥有的数据。
我认为与数据科学的其他分支相比,这个方面有点被忽视了,关于它的文献也更少。因此,这一点点贡献的原因。
故事是这样的:我们的一个客户需要一种方法,根据固定数量的参数为一个给定的实体找到相似的商品(邻居)。实际上,该数据集由人力资源专业人士的投票组成,他们可以将多达 5 种技能归于任意数量的世界大学。这意味着人力资源部的爱德华可以投票选择麻省理工学院作为数字化的好学校,牛津大学作为国际化的好学校,巴黎大学作为软技能的好学校。
我准备了数据,输出了一个蜘蛛网图表,客户可以选择任何机构,并与其他机构进行比较,下面是三所随机大学的例子:
三所大学的投票技能
在这一点上,寻找以同样方式投票的大学似乎很有趣,也许是为了比较他们的行动,研究他们做得好和不好的地方。
数据来自 spss 文件,一行由投票决定,根据我们的简报,输出必须很快,因为它被用作后端服务,具有接近实时响应。
经过一些研究之后,我认为最好的处理格式应该是一个 KD 树 ,因为它具有多维性,并且处理起来相对容易和快速。我不会详细解释什么是 KD 树,但是你可以参考维基百科的文章。
它完全集成到了 sklearn 模块中,并且非常容易使用,我们将在下面看到。
但首先,让我们做一些准备!
数据准备
作为客户的财产,我们的数据集已被匿名化。大学的名字被拿走了,但是价值观是真实的。
我们将从导入库开始:
import pandas as pd
from sklearn.neighbors import KDTree
- 熊猫将被用来输入和处理我们的数据。对于类似数据库的处理来说,它非常快速和有用
- sklearn 代表 scikit-learn ,最著名的数据分析库之一。它用于分类、聚类、回归等等。我们将从最近邻居子库中导入 KDTree
我们已经将 spss 文件转换为 csv 文件,所以我们只需使用 pandas read_csv 方法导入它并显示它的第一行:
df = pd.read_csv("[https://bitbucket.org/zeerobug/material/raw/12301e73580ce6b623a7a6fd601c08549eed1c45/datasets/votes_skills_anon.csv](https://bitbucket.org/zeerobug/material/raw/12301e73580ce6b623a7a6fd601c08549eed1c45/datasets/votes_skills_anon.csv)", index_col=0)
df.head()
数据集结构
每行对应一个投票,其中:
- SUID 是投票者的唯一 ID
- univid :机构的唯一标识
- 响应:投票技能
例如,这意味着用户#538 投票选择“国际性”作为大学#5c9e7a6834cda4f3677e662b 的一项重要技能。
我们的下一步包括按机构和技能分组(响应)。我们使用优秀的 groupby 方法来实现,该方法生成一个 SeriesGroupBy 对象,我们可以用它来计算数据集中相似的(univid,response)对的数量。
skills = df.groupby(["univid", "response"])["response"].count().reset_index(name='value')
我们使用 reset_index 从 count()函数输出的序列中获取一个 DataFrame,并创建包含该计数的“value”列。这是我们的桌子:
按 univid 和响应分组的相同数据集
即使可读性更好,这种格式对我们的目标也没用。很难区分机构,因为行数是任意的(一些技能可能没有被投票),并且许多工具最好使用行值而不是列值。
幸运的是,熊猫提供了一个非常强大的交换行列的工具: pivot_table 。它的论点不言自明,所以我不会进入细节。
univSkills = skills.pivot_table(values="value", columns="response", index=["univid"])
univSkills.head()
pivot_table 之后的值
我们的数据几乎已经准备好进行处理,但是我们仍然有一个问题:要使具有可比性,每一行都必须在相同的范围内,如果我们计算一行中值的总和,各行之间的总和远远不相似:
univSkills.sum(axis=1).head()univid
5c9e345f34cda4f3677e1047 69.0
5c9e349434cda4f3677e109f 51.0
5c9e34a834cda4f3677e10bd 40.0
5c9e34ae34cda4f3677e10c7 66.0
5c9e34d534cda4f3677e1107 70.0
这是因为像哈佛这样的大学比一些偏远和不知名的大学拥有更多的选票。在其他计算中使用这个参数可能会很有趣,但是对于目前的问题,我们需要去掉那个差异。我们通过使用百分比而不是绝对值来遵从。
所以我们必须对每一行求和,然后将每个值除以这个和。这是在一行程序中完成的,然后我们去掉一些 Nan 值来完成数据集的润色。
univSkills = univSkills.div(univSkills.sum(axis=1), axis=0)
univSkills.fillna(0, inplace=True )
我们的数据集现在是干净的,准备好了,值在相同的范围内,我们可以开始玩一些更有趣的处理。
处理数据以查找邻居
因此,我们的算法必须在我们的数据集中检测所有大学中,哪些大学同时具有与我们的 5 个变量最接近的值。我们可以立即想到一个带有嵌套循环的强力算法,它会逐值比较,直到找到每个变量的 5 个最接近的值,但这将远离最佳,对于我们的应用程序来说不够快!
KD 树算法更加有效,它由数据的几何方法组成,通过 n 维空间的后续划分,生成一棵以允许复杂查询快速运行的方式重新组织数据的树。让我们用这个方法生成一棵树:
tree = KDTree(univSkills)
我们的树可以被查询了。第一步是选择一所大学开始,例如索引 9 ( univSkills[9:10]
)的行,我们想要 5 所最近的大学(k=5
)的结果集,应用于我们的树的“查询”函数将返回 2 个 numpy 数组(dist, index
)的元组,这将分别是结果的距离和索引,从最近到最远排序。
dist, ind = tree.query(univSkills[9:10], k=5)
然后我们可以显示我们的邻居的值:
univSkills.iloc[ind.tolist()[0]]
我们马上注意到值非常接近,我们可以用新的雷达图来确认:
5 大学技能对比
另一个例子
你可以尝试不同的开始行,在大多数情况下,雷达图将保持非常相似的形状。
您也可以使用其他 KDTree 方法变量,您可以在文档中找到它们。让我知道你的实验是否会带来更好的结果。
进一步的实验
我认为这个算法还有很多其他的应用。它可以用在推荐系统、约会网站中,以及通常任何依赖于多维矩阵之间的接近度的处理中
关系,例如:通过确定最大距离并将查询函数应用于整个数据集的每一行,我们可以发现看不见的关系,并生成一个类似于 GraphQL 的数据库。
由于它的速度、简单性和有效性, KDTree 也可以在一些简单的情况下作为复杂得多的库的替代,如 TensorFlow 或 Pytorch 。我们将在我的 n ext 文章中研究这个问题。
瞧啊!我希望这篇文章对某人有用。你可以在这里找到完整的笔记本。不要犹豫,留下你的评论,给我发电子邮件,或者任何问题。
在谷歌的边缘 TPU 使用 Keras
在边缘快速部署准确的模型
内森·希普斯在 Unsplash 拍摄的照片
使用 Keras 是快速理解和高效使用深度神经网络模型的好方法。目前,Keras API 不正式支持量化感知训练,因此无法使用该 API 直接生成一个用于 edge 硬件优化(例如,仅使用整数数学)推理的模型。与云相比,边缘上的推断可以提供几个优势,包括减少延迟、降低云成本和改善客户数据隐私。
本文涵盖了以下步骤,因此您可以利用快速高效的 Google Coral Edge TPU 轻松使用 Keras 模型。
- 选择 Edge TensorFlow 处理单元(TPU)兼容的 Keras 模型。
- 在自定义数据集上微调模型。
- 使用训练后量化将微调的 Keras 模型转换为张量流(TF) Lite 模型。
- 编译用于 Edge TPU 的量化 TF Lite。
- 在边缘 TPU 上评估量化模型精度。
- 在边缘 TPU 上部署量化模型。
本文不会深入研究训练深度神经网络、TF Lite 或 Keras APIs,也不会深入研究模型量化背后的理论。您可以通过提供的各种链接来了解这些主题的更多信息。另外,参见皮特·沃顿的优秀博客。这篇文章反映出我主要是一名工程师,比起花大量时间在理论上,我更关心让事情顺利进行。
请注意,我为 smart-zoneminder 项目开发了大量材料,帮助我更好地理解深度学习,因为我在家里解决了一个实际问题——识别一个人是我的家人还是陌生人。我将使用项目中的例子来阐明这些材料,如下所示。
型号选择
根据 Google Coral 文档显示,只有少数 Keras 机型在 Edge TPU 上得到验证——Mobilenet _ v1、 Mobilenet_v2 、 Inception_v3 和 ResNet50 。我决定使用 Mobilenet_v2、Inception_v3 和 ResNet50 来确认它们在 Edge TPU 上确实工作得很好。我还尝试了 VGG16 和 InceptionResNetV2 ,看看它们在对比中表现如何。这些模型对于我的 smart-zoneminder 应用程序来说是完美的,因为它需要一种方法来分类一个人是我的家庭成员还是陌生人——这是这些卷积神经网络(CNN)模型的理想用途。选择这些模型可以很好解决的问题来使用 edge 硬件,否则当您尝试将另一种类型的网络(可能使用 TF Lite 无法量化的运算符)映射到硬件时,您将处于未知领域。
模型微调
有许多很好的资料向您展示如何在您自己的定制数据集上微调 Keras 模型,例如 Keras 文档和 smart-zoneminder 。但是,我发现在 Keras 模型的输出中使用 max pooling 将不会针对边 TPU 进行编译,因为它有一个当前无法由 TF Lite 量化的运算符(REDUCE_MAX)。因此,您将需要使用平均池(或无),如下例所示。
使用平均池实例化 Keras 模型
训练后量化
由于 Keras 模型不支持量化感知训练,您需要使用训练后量化,如 TF Lite 文档中所述。在 smart-zoneminder 项目中使用的 Python 训练脚本将在 Keras 模型的最终训练步骤之后运行训练后量化,如下所示。
从 Keras .h5 文件生成量化的 TFLite 模型
keras_to_tflite_quant 模块将 keras 模型(以. h5 格式)量化为 TF Lite 8 位模型。该脚本还可以评估量化模型的准确性,但 TF Lite 模型的推理在英特尔 CPU(我与 Nvidia GPU 一起用于培训)上非常慢,因为当前的 TF Lite 运算符内核针对 ARM 处理器进行了优化(使用 NEON 指令集)。参见此线程了解更多细节,并在下面了解评估边缘 TPU 量化模型的可行方法。
为边缘 TPU 编译
在下一步中,您需要使用 Google Coral 编译器为 Edge TPU 编译量化 TensorFlow Lite 模型。在 smart-zoneminder 项目中使用的 Python train 脚本将运行如下所示的编译器。
为边缘 TPU 编译
评估量化模型的准确性
你的模型会受到量化的影响,所以你应该检查一下它的精度是否在应用程序所能容忍的范围之内。一种快速的方法是使用 TPU 的量化模型对用于开发模型的训练和验证数据集进行推理。为此,我使用了 Python 脚本 evaluate_model.py ,它是在 TPU 边缘运行的智能区域管理器项目的一部分。该脚本的实际评估函数如下所示。参见 Google Coral 文档了解更多关于如何使用 TF Lite 在 edge TPU 上运行推理的信息。
函数在边 TPU 上运行推理
Resnet50 的 evaluate_model.py 的输出如下所示。您可以看到精度为 0.966,非常接近训练和验证数据集精度 0.973 的加权平均值。这个模型的量化损失对我的应用来说是可以接受的。
TPU 评估结果的量化结果
总体而言,我测试的所有模型都具有可接受的量化性能,除了 InceptionResNetV2,其量化性能仅为 0.855,而基线为 0.980。目前,尚不清楚这种量化模型表现不佳的原因。
部署量化模型
在您验证了足够的模型准确性之后,您可以部署它以在您的应用程序中运行推理。smart-zoneminder 为此使用了一个基于 zerorpc 的推理服务器。
结论
通过仔细选择和训练 Edge TPU 兼容的 Keras 模型,您可以快速将推理模型部署到 Edge。这些模型必须首先量化为 8 位,然后针对边缘 TPU 进行编译。量化过程会在模型中引入精度误差,在生产环境中使用之前,应评估其在应用程序中的适用性。边缘推理提供了几个优势,包括减少延迟、降低云成本和改善客户数据隐私。
使用贷款数据训练和构建分类机器学习应用程序
构建应用程序以服务分类模型、将应用程序容器化并进行部署的简要指南。
照片由 Unsplash 上的纽约公共图书馆拍摄
请点击此处查看该项目中使用的所有代码!
在 GitHub 上创建一个帐户,为 edkrueger/python-classification-labs 的开发做出贡献。
github.com](https://github.com/edkrueger/python-classification-labs)
我们使用 GCP 来编码这个项目,它配置了 Docker。如果您有兴趣了解预配置的云虚拟机,请阅读本文开始学习!
[## 使用 GCP 人工智能平台笔记本作为可复制的数据科学环境
使用预配置的云托管虚拟机解决 Python 和 Jupyter 笔记本电脑的再现性问题。
towardsdatascience.com](/using-gcp-ai-platform-notebooks-as-reproducible-data-science-environments-964cba32737)
我们的数据来自一本叫做《ISLR》的书。查看这项工作的机器学习和统计信息!
问题
我们可以想象一家银行想知道谁是安全的贷款接受者,但是我们如何在只知道一些关于某人的事情的情况下判断他是否值得信任呢?
我们的数据集包含代表具有默认状态的个人的行,以及我们将用来预测默认状态的一些其他信息。换句话说,这就是监督学习。
首先,我们将清理数据,使其更适合分类模型。
数据
让我们看看我们的数据。
原始数据
看起来我们有四列和一个索引,包括银行余额、年收入、学生状态和贷款违约状态。可以清理这些数据以更好地适应分类模型,所以让我们做一些更改。
数据清理和 EDA
为了清理我们的数据,我们使用 pandas 和一些 lambda 函数来删除索引,并将我们的 yes/no 字符串更改为 True/False 布尔值。
data_cleaning.ipynb
现在我们的干净数据看起来像这样。
在我们为训练模型设置数据之前,让我们最后看一眼熊猫。
EDA 值和数据类型
这里我们用value_counts()
来看看我们有多少真和假。这让我们看到有多少人拖欠贷款,有多少人没有。值得注意的是,虚假比真实多得多,几乎多 30 倍。这意味着我们的数据包含了更多的非违约者的例子,而不是违约者,这是一种阶级不平衡。
在审查我们的模型指标时,记住样本数据中的这种差异是很重要的。我们可以想象一个虚拟模型,它总是猜测错误或无违约,同时它将具有 96.67%的准确率,是一个可怕的模型。要知道我们的模型是否运行良好,我们需要密切关注它何时出错。我们对错误分类感兴趣。
预处理
现在,我们将设置我们的笔记本来运行一些机器学习模型。首先,我们要准备将输入模型的变量。
我们的X
或独立变量将是学生身份、银行存款余额和年收入。这些是我们用来预测个人是否可能违约的变量。
X = df[["student", "balance", "income"]].values
个人是否拖欠贷款将是我们的 y
或因变量。
y = df["default"].values
因此,我们假设我们的三个自变量与因变量之间存在某种因果关系。换句话说,我们假设银行存款余额、收入和学生身份有助于预测某人是否会拖欠贷款。
建筑模型
使用我们上面设置的 X 和 y 变量,我们可以建立一些模型并分析它们的度量。然而,首先让我们回顾一下当前问题背景下的模型度量精度和召回率。
模型度量:精确度和召回率
我们如何判断哪种模型最有效地解决了这个问题?
精密试图回答以下问题:
实际上,有多少比例的肯定识别是正确的?
精确度是对预测违约的个人和实际违约的个人的度量。
回想一下试图回答以下问题:
正确识别实际阳性的比例是多少?
召回衡量被正确分类的违约个人的比率。
要全面评估一个模型的有效性,你必须同时检查精确度和召回率。不幸的是,精确度和召回率经常处于紧张状态。也就是说,提高精度通常会降低召回率,反之亦然。
请注意,我们想象了一个准确率为 96.67%的虚拟模型,它永远不会说“真”精度和召回允许我们放大模型归类为“真实”的值,以便我们可以看到我们的模型在对我们重要的时候是如何表现的!
每个问题都是不一样的,所以你需要知道对于你的情况,精确和回忆哪个更重要?这将是一个基于价值的决定,你决定哪个成本更高,假阳性或假阴性。
让我们来看看使用 scikit-learn 构建的几个模型。
决策图表
在决策分析中,决策树可以直观、明确地表示决策和决策制定。顾名思义,它使用树状决策模型。
在这里,我们可以看到我们的准确性几乎是我们的虚拟模型,总是说假。这是由于数据集中存在大量错误,即类别不平衡。
当我们观察cv_recall
和cv_precision
时,事情变得更加有趣。这些低分数表明该模型很难识别实际的“真实”值,precision 告诉我们,我们的模型预测“违约”的时间只有三分之一左右是正确的回忆告诉我们,当它确实将一个人归类为“真实”时,它只在大约三分之一的情况下是正确的。不是一个很好的模型,
k-最近邻
k-最近邻(KNN)算法是一种简单的监督机器学习算法,可用于解决分类和回归问题。
我们看到我们的准确性略有提高,但我们再次对cv_recall
和cv_precision
更感兴趣。我们看到这里的精度更高,这意味着我们的模型预测的“真实”值中,有一半是正确的。这意味着,我们的模型认为会违约的人中,有一半真的会违约。
然而,我们也看到召回率的相应下降。这意味着我们的模型只确定了 15%的“真实”值。当我们说“真”的时候,似乎我们更经常是对的,但是我们也忽略了许多“真”的价值。
随机森林
顾名思义,随机森林由大量单独的决策树组成,这些决策树作为一个整体运行。随机森林中的每一棵特定的树都会产生一个类别预测,拥有最多票数的类别将成为我们模型的预测。该模型的一些实现让每棵树提交一个平均值而不是一个投票,这可以提高准确性。
随机森林背后的基本概念简单而强大——群体的智慧。用数据科学的话来说,随机森林模型如此有效的原因是,大量相对不相关的树作为一个委员会运行,将胜过任何单个的组成树。
我们再一次看到我们的准确度略有提高,但是我们再一次对cv_recall
和cv_precision
更感兴趣,与单个 KNN 模型相比,它们在随机森林中都有所提高。我们看到这里的精度稍高,这意味着在我们的模型预测的“真实”值中,有 57%被正确选择。我们看到一个cv_recall
远高于 KNN,但略低于一个单一的决策树。尽管如此,我们仍然只能用这个模型识别出大约三分之一的“真实”价值。
在这三个模型中,随机森林具有最佳的整体指标,因此我们将继续推进该模型,并将其构建到一个应用程序中。
保存您的模型
一旦你决定了一个模型,把它保存为一个. joblib,就像下面我们对随机森林模型所做的那样。
dump(rf, "clf.joblib")
现在我们已经将贷款分类器保存为. joblib 文件,该文件将出现在我们的目录中。
构建应用程序
服务于这个模型的应用程序很简单。我们需要将我们的模型导入到应用程序中,接收 POST 请求并返回模型对该 POST 的响应。
这是应用程序代码。
我们可以看到有一条简单的/home
路线让我们知道应用程序已经准备好了。我们的/predict
路线才是真正起作用的。请注意,它使用了一个POST
从帖子中提取变量,然后将这些变量作为X_predict
提供给我们的模型。然后,该路径将该模型的响应返回为真或假,并将违约概率返回为浮点数。
一旦我们有了一个可以为我们的模型服务的应用程序,我们需要用 Docker 封装我们的应用程序,这样我们就可以轻松地部署它。
Docker 和我们的 docker 文件
Docker 是将应用程序投入生产的最佳方式。Docker 使用 docker 文件来构建容器。构建的容器存储在 Google Container Registry 中,可以在这里进行部署。Docker 容器可以在本地构建,并将在任何运行 Docker 的系统上运行。
以下是用于此项目的 docker 文件:
Dockerfile 文件
使用 Docker 进行本地测试
请注意,您需要安装 Docker 才能在本地运行。或者,您可以使用已经配置了 Docker 的云平台(参见本文开头链接的文章)。
docker build
命令将 docker 文件的每一行视为一个“步骤”,并提供一个终端输出,指示每个步骤何时运行,如上所示。
我们运行命令docker build . -t loan-classifier
并看到输出确认,即每个步骤都是按顺序完成的。一旦我们的 docker 容器构建完成,我们就可以使用下面的命令在容器中运行应用程序。
PORT=8000 && docker run -p 80:${PORT} -e PORT=${PORT} loan-classifier
码头运行
看起来我们的容器化应用程序正在本地主机地址上运行。太好了,我们成功建造了码头。现在让我们的应用程序向公众发布。
Docker 图像和谷歌云注册表
GCP 云构建允许您使用 docker 文件中包含的指令远程构建容器。
一旦我们准备好 docker 文件,我们就可以使用 Cloud Build 构建我们的容器映像。
从包含 Dockerfile 文件的目录中运行以下命令:
gcloud builds submit --tag gcr.io/**PROJECT-ID**/**container-name**
注意:用您的 GCP 项目 ID 替换项目 ID,用您的容器名称替换容器名称。您可以通过运行命令gcloud config get-value project
来查看您的项目 ID。
该 Docker 图像现在可在 GCP 集装箱注册处或 GCR 访问,并可通过云运行的 URL 访问。
使用 CLI 部署容器映像
如果您更喜欢使用 GUI,请跳过这一部分!
- 使用以下命令进行部署:
gcloud run deploy --image gcr.io/**PROJECT-ID**/**container-name** --platform managed
注意:用您的 GCP 项目 ID 替换项目 ID,用您的容器名称替换容器名称。您可以通过运行命令gcloud config get-value project
来查看您的项目 ID。
2.将提示您输入服务名称和区域:选择您所选择的服务名称和区域。
3.您将被提示允许未认证的调用:如果您想要公共访问,响应y
,并且n
限制对同一 google 项目中的资源的 IP 访问。
4.稍等片刻,直到部署完成。如果成功,命令行会显示服务 URL。
5.通过在 web 浏览器中打开服务 URL 来访问您部署的容器。
使用 GUI 部署容器映像
现在我们已经在 GCR 存储了一个容器映像,我们已经准备好部署我们的应用程序了。访问 GCP 云运行并点击创建服务,确保按要求设置计费。
选择您想服务的地区,并指定一个唯一的服务名称。然后通过分别选择未经身份验证或经过身份验证,在对应用程序的公共访问和私有访问之间进行选择。
现在我们使用上面的 GCR 容器图像 URL。粘贴 URL 或单击选择并使用下拉列表查找。检查高级设置以指定服务器硬件、容器端口和附加命令、最大请求数和扩展行为。
当您准备好构建和部署时,请单击创建!
从 GCR 选择一个容器图像
您将进入 GCP 云运行服务详细信息页面,在此您可以管理服务、查看指标和构建日志。
服务详情
单击 URL 查看您部署的应用程序!
优秀
恭喜你!您刚刚将一个打包在容器中的应用程序部署到云环境中。
您只需为请求处理过程中消耗的 CPU、内存和网络资源付费。也就是说,当你不想付费时,一定要关闭你的服务!
结论
正如我们所看到的,决定一个模型是好是坏有其复杂性和细微差别。请记住,我们已经用简单的数据解决了一个简单的问题。随着问题复杂性的增加,进行 EDA 和分析模型输出变得更加复杂和相关。一旦你有了一个“足够好”的模型,下一步就是为这个模型服务。
快速开发出任何像样的好模型都有巨大的商业和技术价值。拥有人们可以立即使用的东西和部署数据科学家可以稍后调整的软件的价值。部署软件可能是一个挑战,但这是一个越早越好的障碍;尽早部署,经常部署。此外,Docker 等服务简化了部署过程。
我们希望这些内容是有益的;让我们知道你想在软件、开发和机器学习领域了解更多的东西!
使用与熊猫数据框架的逻辑比较
tPYTHON
标准比较操作符的易于使用的包装器
艺术作品软 _ 艺术作品
逻辑比较到处使用*。*
Pandas 库为您提供了许多不同的方法,您可以将数据帧或系列与其他 Pandas 对象、列表、标量值等进行比较。传统的比较运算符(<, >, <=, >=, ==, !=
)可用于将一个数据帧与另一组值进行比较。
但是,您也可以使用包装器来提高逻辑比较操作的灵活性。这些包装器允许您指定用于比较的轴,因此您可以选择在行或列级别执行比较。此外,如果您正在使用多索引,您可以指定想要使用哪个索引。
在本文中,我们将首先快速地看一下与标准操作符的逻辑比较。之后,我们将通过五个不同的例子来说明如何使用这些逻辑比较包装器来处理和更好地理解您的数据。
这篇文章中使用的数据来自雅虎财经。我们将使用特斯拉股票价格数据的子集。如果您想继续,请运行下面的代码。(如果你对我用来获取数据的功能感到好奇,请滚动到最底部,点击第一个链接。)
*import pandas as pd# fixed data so sample data will stay the same
df = pd.read_html("[https://finance.yahoo.com/quote/TSLA/history?period1=1277942400&period2=1594857600&interval=1d&filter=history&frequency=1d](https://finance.yahoo.com/quote/TSLA/history?period1=1277942400&period2=1594857600&interval=1d&filter=history&frequency=1d)")[0]df = df.head(10) # only work with the first 10 points*
与熊猫的逻辑比较
可供使用的包装器有:
eq
(相当于==
) —等于ne
(相当于!=
) —不等于le
(相当于<=
) —小于或等于lt
(相当于<
) —小于ge
(相当于>=
) —大于或等于gt
(相当于>
) —大于
在我们深入包装器之前,让我们快速回顾一下如何在 Pandas 中执行逻辑比较。
使用常规比较运算符,将 DataFrame 列与整数进行比较的基本示例如下所示:
*old = df['Open'] >= 270*
这里,我们要查看“Open”列中的每个值是否大于或等于固定整数“270”。然而,如果你尝试运行这个,首先它不会工作。
你很可能会看到这个:
TypeError: '>=' not supported between instances of 'str' and 'int'
现在注意这一点很重要,因为当您同时使用常规比较操作符和包装器时,您需要确保您实际上能够比较这两个元素。请记住,在您的预处理过程中,不只是针对这些练习,而是在您分析数据的一般情况下:
*df = df.astype({"Open":'float',
"High":'float',
"Low":'float',
"Close*":'float',
"Adj Close**":'float',
"Volume":'float'})*
现在,如果您再次运行原始比较,您将得到这个系列:
简单的逻辑比较示例
您可以看到该操作返回了一系列布尔值。如果您检查原始的 DataFrame,您会看到对于每一行的值是否大于或等于(>=
) 270,都应该有相应的“True”或“False”。
现在,让我们深入研究如何使用包装器做同样的事情。
1.比较两列是否不相等
在数据集中,您会看到有一个“Close”列和一个“Adj Close**”列。调整后的收盘价被修改以反映潜在的股息和拆分,而收盘价仅针对拆分进行调整。为了查看这些事件是否已经发生,我们可以做一个基本的测试来查看两列中的值是否不相等。*
为此,我们运行以下命令:
*# is the adj close different from the close?
df['Close Comparison'] = df['Adj Close**'].ne(df['Close*'])*
列不等式比较的结果
在这里,我们所做的只是调用“Adj Close*”列上的.ne()
函数,并传递“Close* ”,即我们想要比较的列,作为函数的参数。*
如果我们看一看产生的数据框架,您会看到我们已经创建了一个新列“Close Comparison ”,如果两个原始 Close 列不同,它将显示“True ”,如果它们相同,则显示“False”。在这种情况下,您可以看到每行上“Close”和“Adj Close**”的值是相同的,因此“Close Comparison”只有“False”值。从技术上讲,这意味着我们可以删除“Adj Close**”列,至少对于这个数据子集是这样,因为它只包含“Close*”列的重复值。*
2.检查一列是否大于另一列
我们经常想看看股票价格在一天结束时是否上涨。一种方法是,如果“收盘”价格高于“开盘价”,则显示“真”值,否则显示“假”值。*
为了实现这一点,我们运行以下命令:
*# is the close greater than the open?
df['Bool Price Increase'] = df['Close*'].gt(df['Open'])*
列大于比较的结果
在这里,我们看到,在 2020 年 7 月的前两周,当天结束时的“收盘”价格比当天开始时的“开盘价”高 4/10 倍。这可能没有那么多信息,因为它是一个很小的样本,但如果你将它扩展到几个月甚至几年的数据,它可以表明股票的整体趋势(上涨或下跌)。*
3.检查列是否大于标量值
到目前为止,我们只是在比较不同的列。还可以使用逻辑运算符将列中的值与标量值(如整数)进行比较。例如,假设每天的交易量大于或等于 1 亿,我们称之为“高交易量”日。
为此,我们运行以下命令:
*# was the volume greater than 100m?
df['High Volume'] = df['Volume'].ge(100000000)*
列和标量大于比较的结果
这次我们只需传递标量值“100000000”,而不是将一列传递给逻辑比较函数。
现在,我们可以看到,在 5/10 天的交易量大于或等于 1 亿。
4.检查列是否大于自身
之前,我们比较了每行中的“Open”和“Close”值是否不同。相反,如果我们将一个列的值与前一个值进行比较,以跟踪一段时间内的增加或减少,那将会很酷。这样做意味着我们可以检查 7 月 15 日的“Close*”值是否大于 7 月 14 日的值。*
为此,我们运行以下命令:
*# was the close greater than yesterday's close?
df['Close (t-1)'] = df['Close*'].shift(-1)
df['Bool Over Time Increase'] = df['Close*'].gt(df['Close*'].shift(-1))*
列大于比较的结果
为了便于说明,我包含了“Close (t-1)”列,这样您可以直接比较每一行。在实践中,您不需要添加一个全新的列,因为我们所做的只是将“Close”列再次传递给逻辑运算符,但是我们还对它调用了shift(-1)
来将所有的值“上移一”。*
这里发生的事情基本上是从指数中减去 1,因此 7 月 14 日的值“向上”移动,这让我们可以将其与 7 月 15 日的真实值进行比较。结果,您可以看到 7/10 日的“Close”值大于前一天的“Close*”值。*
5.将列与列表进行比较
作为最后一个练习,假设我们开发了一个模型来预测 10 天的股票价格。我们将这些预测存储在一个列表中,然后将每天的“开盘价”和“收盘价”值与列表值进行比较。*
为此,我们运行以下命令:
*# did the open and close price match the predictions?
predictions = [309.2, 303.36, 300, 489, 391, 445, 402.84, 274.32, 410, 223.93]
df2 = df[['Open','Close*']].eq(predictions, axis='index')*
列和列表比较的结果
这里,我们比较了生成的每日股票价格预测列表,并将其与“Close”列进行了比较。为此,我们将“预测”传递到eq()
函数中,并设置axis='index'
。默认情况下,比较包装器有axis='columns'
,但是在这种情况下,我们实际上想要处理每列中的每一行。*
这意味着 Pandas 会将列表中的第一个元素“309.2”与第一个值“Open”和“Close”进行比较。然后,它将移动到列表中的第二个值和数据帧的第二个值,依此类推。请记住,列表和数据帧的索引都是从 0 开始的,因此,对于第一个数据帧列值,您将分别查看“308.6”和“309.2”(如果您想要仔细检查结果,请向上滚动)。*
基于这些任意的预测,您可以看到在“Open”列值和预测列表之间没有匹配。“Close”列值和预测列表之间有 4/10 匹配。*
我希望您发现这个关于熊猫使用包装器进行逻辑比较的非常基本的介绍很有用。请记住,只比较可以比较的数据(即不要尝试将字符串与浮点数进行比较),并手动复查结果,以确保您的计算产生了预期的结果。
往前走,比较一下!
***More by me:** - [2 Easy Ways to Get Tables From a Website](/2-easy-ways-to-get-tables-from-a-website-with-pandas-b92fc835e741?source=friends_link&sk=9981ddaf0785a79be893b5a1dd3e03dd)
- [Top 4 Repositories on GitHub to Learn Pandas](/top-4-repositories-on-github-to-learn-pandas-1008cb769f77?source=friends_link&sk=d3acc38062490a86ecb46875342224e6)
- [An Introduction to the Cohort Analysis With Tableau](https://medium.com/swlh/how-to-group-your-users-and-get-actionable-insights-with-a-cohort-analysis-b2b281f82f33?source=friends_link&sk=8b672c3feb79e194804f2a1c33660e19)
- [How to Quickly Create and Unpack Lists with Pandas](/how-to-quickly-create-and-unpack-lists-with-pandas-d0e78e487c75?source=friends_link&sk=32ea67b35fe90382dc719c1c78c5900c)
- [Learning to Forecast With Tableau in 5 Minutes Or Less](/learning-to-forecast-effectively-with-tableau-in-6-minutes-or-less-3d77a55930a0?source=friends_link&sk=9abdfd7533ee9a31ab8a036413450059)*
使用逻辑回归从基础创建二元和多类分类器
使用 Python 生成梯度下降优化的二元和多类分类器
随着数据科学和机器学习成为工业和学术研究中许多领域不可或缺的一部分,掌握这些技术的基本知识对于识别数据趋势非常有用,尤其是在数据集规模快速增长的情况下。有了实验科学的背景,线性回归看起来总是相当直观,因为我们经常将实验数据与理论模型进行拟合,以提取材料属性。然而,制作一个分类器(即根据之前的几个指标预测 A 队是否会击败 B 队),在我做了一些阅读之前,我并没有使用过或者有太多的经验。在本文中,我希望简洁地描述如何使用逻辑回归从头开始创建一个分类器。在实践中,您可能会使用诸如scikit-learn
或tensorflow
之类的软件包来完成这项工作,但是理解一些底层的方程和算法对于了解“幕后”发生了什么非常有帮助。
本文中的大部分工作都受到了吴恩达教授的 Coursera 上的机器学习课程的启发。
本文中的所有代码我们都将使用 Python,所以让我们导入我们将需要的所有包:
我们如何进行离散预测?
做离散预测是我们一直在做的事情,可能甚至没有过多考虑如何做。例如,你正在餐馆看菜单——你阅读不同菜单项的描述,记住你最近阅读的食物评论中的一些提示,可能会问服务员几个问题,并对你想点什么做出谨慎的决定。如果你从未在这家餐馆吃过饭,你实际上是在根据你认为你会喜欢的东西做出明智的预测。
为了在我们的预测算法中实现类似的行为,一个很好的起点是选择一个数学函数,它本质上给出一个二进制输出或 0 或 1。为此,我们可以使用逻辑或 sigmoid 函数,其形式如下:
我们可以用 Python 编写这个函数,并将其绘制如下:
如图所示,在 x = 0 附近,sigmoid 函数从接近 0 的输出快速变为接近 1 的输出。由于输出值关于 y = 0.5 是对称的,我们可以以此作为做出决策的阈值,其中 y ≥ 0.5 输出 1,y < 0.5 outputs 0.
To see this in action, let’s train some data!
产生数据
我们的场景如下——我们正在构建一个简单的电影推荐系统,该系统考虑了 0 到 5 之间的平均用户评分(所有用户)和 0 到 5 之间的平均评论家评分。然后,我们的模型应该基于我们的输入数据生成一个决策边界,以预测当前用户是否会喜欢这部电影,并向他们推荐这部电影。
我们将对 100 部电影进行随机用户和评论家评分:
现在,让我们生成分类—在这种情况下,要么用户喜欢这部电影(1),要么不喜欢(0)。为此,我们将使用以下决策边界函数。我们将该等式的右侧设为 0,因为它定义了逻辑函数何时等于 0.5:
请注意,在真实的数据集中,您不知道决策边界的函数形式是什么。出于本教程的考虑,我们正在定义一个函数,并向它添加一些噪声,以便分类不是“完美的”。
现在,我们可以绘制初始数据,其中橙色圆圈代表用户喜欢的电影,蓝色圆圈代表不喜欢的电影:
决定决策边界的质量
为了确定我们的决策边界有多好,我们需要为错误的预测定义一个惩罚,这将通过创建一个成本函数来实现。我们的预测如下:
当 P ≥ 0.5 时,我们输出 1,当 P < 0.5 时,我们将输出 0,其中 w₀、w₁和 w₂是我们正在优化的权重。
为了惩罚错误的分类,我们可以利用对数函数,因为 log(1) = 0 和 log(0) → -∞。我们可以用它来创建如下两个罚函数:
我们可以将它可视化,以便更清楚地看到这些罚函数的效果:
利用我们的输出 ( y )将为 0 或 1 的事实,我们可以在一个包含两种情况的表达式中优雅地组合这两个罚函数:
现在,当我们的输出为 1,并且我们预测接近 0(第一项)时,我们会招致一个陡峭的惩罚——类似地,当我们的输出为 0 并且我们预测接近 1(第二项)时,也会发生相同的情况。
我们现在可以把我们的罚函数推广到 m 个训练例子——第 i 个训练例子的标签用( i 表示)。我们还将总成本除以 m 得到平均惩罚(就像线性回归中的均方误差)。这个最终表达式也被称为成本函数。我们将我们的两个特征(用户评分和评论家评分)称为 x₁和 x₂.
最小化成本
为了找到最优决策边界,我们必须最小化这个成本函数,我们可以使用一种叫做 梯度下降 的算法来实现,这种算法本质上做两件事:(1)通过计算成本函数的梯度来找到最大下降的方向,(2)通过沿着这个梯度移动来更新权重值。为了更新权重,我们还提供了一个 学习率【α】,它决定了我们沿着这个梯度移动了多少。在选择学习率时有一个权衡——太小,我们的算法需要太长时间才能收敛;太大,我们的算法实际上会发散。关于梯度下降和学习率的更多信息可以在链接文章中找到。因此,对于每个权重,我们有以下更新规则:
谜题的最后一块是计算上面表达式中的偏导数。我们可以使用微积分中的链式法则将它分解如下:
现在,我们可以把它们放在一起得到下面的梯度表达式和梯度下降更新规则:
我们现在可以初始化我们的变量来最小化成本函数。
初始化变量
上面所有的梯度下降运算都有利于使用矩阵乘法和线性代数。首先,我们如下初始化变量:
我们现在可以如下重写用于权重的成本函数、梯度和更新函数的两个早期表达式,其中上标 T 表示矩阵的转置:
我们的变量可以初始化如下(我们将设置所有的权重等于 0 开始):
既然长长的数学之墙已经过去了,让我们来训练我们的分类器模型吧!
训练我们的模型
我们必须首先为成本函数和梯度下降更新定义函数。以下函数计算成本和梯度值,并返回两者:
当定义梯度下降函数时,我们必须添加一个名为num_iters
的额外输入,它告诉算法在返回最终优化权重之前要进行的迭代次数。
现在,在做了所有这些艰苦的工作之后,下面的线训练我们的模型!
J, w_train = gradient_descent(X, y, w, 0.5, 2000)
在真实的情况下,我们会拆分我们的训练数据,以便交叉验证和测试我们的模型,但是出于本教程的目的,我们将使用所有的训练数据。
为了确保我们在每次迭代中降低成本函数的值,我们可以绘制如下图:
现在是关键时刻——我们可以画出我们的决策界限。我们将在原始图上覆盖它的方法是定义一个点网格,然后使用我们训练的权重计算 sigmoid 函数的预测值。然后我们可以画出预测值等于 0.5 的等高线。
Et,瞧!
我们现在可以编写一个函数,根据这个训练好的模型进行预测:
现在,让我们对新的例子做一些预测:
X_new = np.asarray([[1, 3.4, 4.1], [1, 2.5, 1.7], [1, 4.8, 2.3]])
print(predict(X_new, w_train))>>> [[1.]
[0.]
[1.]]
多类分类
现在我们已经完成了制作二元分类器的所有艰苦工作,将它扩展到更多的类是相当简单的。我们将使用一种称为 一对一分类 的策略,其中我们为每个不同的类训练一个二元分类器,并选择具有 sigmoid 函数返回的最大值的类。
让我们以二进制示例中的模型为基础,这一次用户可以给一部电影打 0 星、1 星或 2 星的分数,我们试图根据用户和评论家的分数来确定决策界限。
首先,我们再次生成数据,并应用两个决策界限:
我们的数据集如下所示,其中蓝色圆圈代表 0 星,橙色圆圈代表 1 星,红色圆圈代表 2 星:
对于我们训练的每个二元分类器,我们需要重新标记数据,以便我们感兴趣的类的输出设置为 1,所有其他标签设置为 0。例如,如果我们有 3 组 A (0)、B (1)和 C (2),我们必须制作三个二元分类器:
(1) A 设置为 1,B 和 C 设置为 0
(2) B 设置为 1,A 和 C 设置为 0
(3) C 设置为 1,A 和 B 设置为 0
我们有一个为每个分类器重新标记数据的函数:
现在,我们进行与前面的二进制分类部分相同的模型训练,但是分三次进行:
这一次绘制决策界限稍微复杂一些。我们必须为每个经过训练的分类器计算网格中每个点的预测值。然后,我们选择每个点的最大预测值,并根据哪个分类器产生了该最大值来分配其各自的类别。我们选择绘制的等高线是 0.5(0 到 1 之间)和 1.5(1 到 2 之间):
经过大量的预期,这里是我们训练有素的决策界限!
最后,我们来做一个预测函数。为此,我们将使用一个小技巧——我们将对每个示例中的每个分类器进行预测。然后,我们将把每组预测作为一个新列追加到预测矩阵中。然后,通过沿着每一行选择具有最大值的列索引,我们自动得到分类器标签!
X_new = np.array([[1, 1, 1], [1, 1, 4.2], [1, 4.5, 2.5]])
print(predict_multi(X_new, [w_class1, w_class2, w_class3]))>>> [[0]
[2]
[1]]
在那里!一个完全从零开始的多类分类器!
结束语
感谢阅读!这篇文章只是触及了逻辑回归和分类的表面,但是我希望你喜欢它。展示的例子可以在这里找到。我再次感谢吴恩达在 Coursera 上教授的机器学习课程给了我这篇文章很多灵感。
对多维时间序列数据使用 LSTM 自动编码器
埃菲社在 Unsplash 上拍摄的照片
实践中的深度学习
演示如何使用 LSTM 自动编码器分析多维时间序列
在本文中,我将展示一个非常有用的模型来理解时间序列数据。我已经将这种方法用于无监督的异常检测,但它也可以用作通过降维进行预测的中间步骤(例如,对潜在嵌入层和完整层进行预测)。
简而言之,这种方法将一个多维序列(想想多个计数的窗口时间序列,来自传感器或点击等)压缩成一个表示该信息的单一向量。有了有效的编码器/解码器,我们可以使用潜在向量作为多层感知器的输入,或者作为更大的多头网络中的另一组特征。
我不打算讨论 LSTMs 或自动编码器的细节。对于这些信息,我强烈推荐以下文章:
嗨,欢迎来到长短期记忆(LSTM)和门控循环单位(GRU)的图解指南。我是迈克尔…
towardsdatascience.com](/illustrated-guide-to-lstms-and-gru-s-a-step-by-step-explanation-44e9eb85bf21) [## 应用深度学习-第 3 部分:自动编码器
概观
towardsdatascience.com](/applied-deep-learning-part-3-autoencoders-1c083af4d798)
当我们从潜在向量中重建原始时间序列时,通常会有一定程度的误差。对于训练有素的编码器/解码器,该误差可以提供很多信息。
对于异常检测,我们会查看误差的大小。 幅度 让我们了解输入时间序列的 不规则性 。我们可以用这个作为识别异常的代理。
数据
我使用了一组我在以前的文章中用过的数据(链接如下):
[## 用 XGBoost 和 Gini 杂质计算特征的重要性
使用 XGBoost 回归识别重要特征
samsachedina.medium.com](https://samsachedina.medium.com/calculating-a-features-importance-with-xgboost-and-gini-impurity-3beb4e003b80)
这些数据是 2020 年 10 月 26 日交易时段的分笔成交点数据。每一个分笔成交点代表一个价格变化,或者是证券的收盘价、买价或卖价。订单簿数据被快照并在每个分笔成交点返回。订单簿可能会“偏离分笔成交点”波动,但只有在产生分笔成交点时才会被记录,这样可以进行更简单的基于时间的分析。
下面是一个记录示例:
我们有一个时间字段、我们的定价字段和“md_fields”,它们代表以不同于当前要价/出价的价格增量卖出(“要价”)或买入(“出价”)的需求。
模型
我将创建一个“堆叠”自动编码器。数据被重新整形,允许我通过超参数调整来优化窗口大小。
查看我如何通过函数“generate_datasets_for_training”返回 train_x、train_y、test_x 和 test_y 的示例
模型从一个编码器开始:首先是输入层。输入图层是 LSTM 图层。接着是另一个较小尺寸的 LSTM 层。然后,我获取从第 2 层返回的序列——然后将它们提供给一个重复向量。重复向量获取单个向量,并以某种方式对其进行整形,以允许其被馈送到我们的解码器网络,该网络与我们的编码器对称。 注意,不一定要对称,但这是标准做法。
我们的最后一层是一个时间分布的密集层,它产生一个类似于我们输入的序列。
最后,我们计算基于原始输入的均方误差损失:由我们的最终层产生的序列和原始输入序列之间的误差。最小化这成为我们网络学习的优化过程。
这是我们最后的网络
请注意,中间层是一个重复向量,它获取 encoder_3(我们的潜在表示)的输出,并在我们的回看窗口中重复它的步数。
如果我们需要(1,4)的潜在表示,我们只需将编码器层压缩成那个形状。要压缩一个时间序列窗口,我们需要做的就是从最后一个编码层提取输出。
看到这个要点的例子,如何建立!
这是将时间序列数据表示为密集潜在表示的基本介绍。
我希望你喜欢这篇文章!
如果你喜欢这个,你可能会喜欢:
在 10 分钟内获得视频注释
medium.com](https://medium.com/the-innovation/yolov4-in-10-minutes-715f016bcf42)
使用 LSTMs 预测股票价格
利用长短期记忆网络来赚钱
面对现实吧。我们是哑巴。
一只被蒙住眼睛的猴子比任何人都能更好地管理投资组合。不,我是认真的。无数研究表明,猴子在股票市场上一直跑赢人类。据称,一只猴子在一个季度内创造的利润比纽约证券交易所的交易员多 8 倍。一只毫无线索的灵长类动物如何打败华尔街所谓的“天才”?答案,狗屎运。
人类一直试图衡量和预测股票价格,使用花哨的统计数据和趋势来计算。但事实是,人类无法理解影响股价的不同变量。我们无法综合一家公司的声誉、他们已经宣布和正在进行的项目、业绩记录、过去的股市数据,并将所有这些因素综合起来,以便在股市上做出明智的决策。我们不能考虑一家公司曾经存在的每一个变量和统计数据。但是,电脑可以。更具体地说,神经网络正是为此而设计的。
长短期记忆网络
数学意义上的神经网络是一个可微分函数,它接受输入并计算输出。本质上,它是你的标准 f(x ),但不是只有一个变量“x ”,而是有 1,000,000 个 x 或参数。我们的目标是优化这些参数,因为这样我们就可以输入任何输入并得到想要的输出。简而言之,这些都是神经网络,但是 LSTM 有一些特殊的性质。
别急,我来分解一下
长短期记忆神经网络由 LSTM 单元或细胞组成。这些单元进行特殊的计算,并将它们的输出作为输入传递给下一个单元。简而言之,LSTM 的主要目标是考虑之前传入输出的数据。像时间序列数据或股票市场数据这样的东西依赖于它自己过去的版本,使用 LSTM,它记住过去并试图预测未来。它是这样工作的。
数据是如何传播的
在股票市场数据和通常依赖于过去自身迭代的数据中,不同时间的数据是不同的。在某个时间,一块数据是 x。这被称为时间步长,数据被输入到一个 LSTM 单元分解成相应的时间步长。例如,第三 LSTM 单元采用第三时间步的数据或 X3。
快速批注: t-1 表示最后一个 LSTM 单元格的值, t 是当前 LSTM 单元格的输出。
细胞状态
细胞状态
C 的符号表示 LSTM 的单元状态。单元状态是通过每个单元自身路径传递的值的向量。当前单元可以在其计算中使用该单元状态,或者完全改变单元状态。正因为如此,细胞状态向量充当了神经网络的长期记忆部分。这是因为它与每个 LSTM 单位相互作用,因此在计算下一个单位的产量时可以将每个单位考虑在内。这就是 LSTM 长期记忆的来源。
输入门
输入门
输入门接收最后一个单元的隐藏状态( ht-1) 的输出和带标签的数据输入(Xt),并使用该信息来查看单元状态是否应该改变。它首先将数据输入和隐藏状态相乘,创建一个新的值向量。然后,它取这个向量的 sigmoid 和双曲线正切函数,并将这些结果相乘。如果乘积高于某个经过训练的参数,它就会被添加到细胞状态中,本质上是让细胞状态记住这个重要的信息。如果它没有被添加到单元状态,那么它可以被认为对网络的长期记忆不重要。简而言之,输入门决定了信息对长期而言是否重要。
忘记大门
遗忘之门
遗忘门接收前一时间步(ht-1)的隐藏状态输出和当前时间步(Xt)的数据输入。然后将它们相乘,并对其应用 sigmoid 激活。如果输出高于某个经过训练的参数,则单元状态完全重置为 0,基本上忘记了它的长期记忆。这就是为什么它被称为遗忘之门,因为它有能力忘记到目前为止所学的一切。这有助于时间序列预测,因为一条数据将作为当前趋势的重置,LSTM 需要将这一因素考虑在内。然而,LSTM 人很少能通过遗忘之门。
输出门
输出门
输出门为下一个单元(ht)准备下一个隐藏状态向量。它将最后一个隐藏状态向量和输入数据考虑在内,并对其应用一些函数。这是神经网络的短期记忆方面,因为它将新信息传播到下一个细胞。
请注意所有三个门是如何一起创建单元状态的。在所有单元结束时,细胞状态通过致密层传递,致密层理解所有长期记忆和关于数据的重要信息,以创建下一时间步的预测。一切都导致了这个细胞状态的产生,它是 LSTM 的心脏。训练 LSTM 网络是为了确保长期信息能够持续到最后。现在您对 LSTMs 有了很好的理解,让我们看看我是如何将它们应用于股票市场数据的。
股票市场预测者
数据
这个项目使用的数据是苹果公司过去 5 年的股票价格。它被分解成每个 10 分钟的时间步长。神经网络需要样本来训练,需要有标签的数据,所以数据是以特定的方式输入的。输入是 50 个时间步长,标签(这是神经网络试图预测的)是第 51 个时间步长。神经网络尝试预测下一时间步的价格,并相应地创建数据来训练神经网络。
建筑
惊喜惊喜!这个神经网络我用了很多 LSTMs。每个 LSTM 中有 96 个单元,并将单元状态作为输入返回给下一个 LSTM。最后,它有 2 个密集层,接收 LSTM 层的输出并理解它。最后一个密集层里面有一个节点,表示输出一个数字,下一个时间步的预测值。它有超过一百万个可以优化的参数。脱落层用于确保神经网络不仅仅是记忆数据和输出。我知道,所有这些工作只是为了找到下一个时间步的下一个值。
model = Sequential([layers.LSTM(units=96, return_sequences=True, input_shape=(50,1)),layers.Dropout(0.2),
layers.LSTM(units=96, return_sequences=True),layers.Dropout(0.2),
layers.LSTM(units=96, return_sequences=True),layers.Dropout(0.2),
layers.LSTM(units=96, return_sequences=True),layers.Dropout(0.2),
layers.LSTM(units=96, return_sequences=True),layers.Dropout(0.2),
layers.LSTM(units=96),layers.Dropout(0.2),
layers.Dense(1)
])
培养
使用流行的 Adam 优化器和 MSE 损失函数来训练该模型。损失函数是模型执行得有多差,优化器找到函数的最小值,这是网络的最佳参数。跑了 100 多个纪元,达到亏损< 0.00001 (it performs pretty good).
The Results are In
So these are few examples of stocks it was used to predict. The blue shows the predicted price and the red shows the actual price.
On Randomly Generated Stock Data
Overall, the model works decently well… but that doesn’t mean you should use this on the stock market. The stock market is very volatile and this model only uses past trends of a stock to predict the next.
参考文献
【https://colah.github.io/contact.html
https://unsplash.com/photos/Z05GiksmqYU
基于机器学习和人工智能的嘻哈歌曲分析
我如何将自然语言应用到嘻哈歌词中,以找到不同的主题
由于我从小就开始听嘻哈音乐,所以我不得不处理与这种音乐类型相关的不同意见。对于一些人来说,所有的说唱歌曲都接近同一个主题,都是相似的。其他人会争论他们的顶级说唱歌手,想证明他们比我强。虽然我想用数据科学来展示我最喜欢的说唱歌手是如何在很大程度上为游戏做出贡献的,但我去年从事这个项目的目的是对抗流行观点,并使用机器学习来找到嘻哈歌曲的主题和类别。
我的数据
我想获得尽可能多的相关数据。我不想把任何有实力的艺术家排除在项目之外。利用美汤,我收集了来自ranker.com的 814 名说唱歌手名单;我很确定我抓住了 1979 年的大多数说唱歌手。我甚至惊讶地发现了沙奎尔·奥尼尔。😃
下一步是收集所有说唱歌手的歌词。我使用了约翰·W·米勒的精彩的歌词天才包来访问天才歌词 API。你可以查看他的回购协议了解更多信息。
因为我有艺术家——我创建了一个功能来搜索他们的歌曲!还有—随用随存!
最后,我必须连接到 Spotify 的 API 来获取关于这首歌的信息(长度、流行度、效价、节奏、可跳性等等。).因为我已经有了歌词和艺术家的名字,所以我创建了一个函数来获取每个组合的音轨 id 和音频特性:音轨、艺术家。我结尾的歌比歌词少;例如,在我做这个项目的时候,所有 Jay-Z 的歌曲在 Spotify 上都不可用。
用于收集 Spotify 音频特征的函数!
我将避免描述清理数据的麻烦。json 到字典,或删除非英文歌曲。经过收集和清理,我只剩下 Spotify 的 55k+歌词和 27k+歌曲功能。
主题建模
我不打算在这篇文章中进行探索性的分析。然而,在编辑所有歌词时,对顶部的词有一个想法将是有趣的。下图清楚地显示了大多数人是如何看待嘻哈歌曲的。很多脏话——我不得不做大量的清理工作,将一些单词归入“F”类;n '或 B '字——一些确实很常见但不一定翻译出嘻哈精髓的世界(女孩 ’ / ’ homie ’ / ’ 男孩 ’ / ’ 街’在字云里很容易看出来)
我妈是怎么听说唱歌曲的!!!
相反,我将自然语言处理(NLP)应用于歌词,以挑战词云结果。主要目的是在歌曲中寻找不同的主题。我采用了潜在的狄利克雷分配(LDA)。
什么是潜在狄利克雷分配?这是一种自动发现句子包含的主题的方式。这是一个语料库的生成概率模型。更详细地说,LDA 将文档表示为主题的混合的**,这些主题以一定的概率吐出单词。**
我期待从歌词中找到话题——经过清理和准备。我们必须记住,LDA 将以概率呈现不同的主题,但作为一名数据科学家,我的工作是定义每个主题。最后,每个歌词将根据较高的权重分配给一个主题。
我的 4 个主题的丰富多彩的表现!!
为了从 LDA 的结果中获益,我必须知道每个主题所涉及的内容。自发的方法是检查每个主题下的歌曲,并尝试在他们谈论的内容中找到相似之处。由于歌词的数量,这将会造成时间混乱,并且效率低下,因为这将需要另一个主题建模:)
主题 1 中超过 10k 的歌词—阅读歌词来理解主题不是一个好主意!
为了给出每个主题的名称,我分析了每个主题的前 30 个单词和一个代表性文本。我对 hip hop 帮助的了解(领域专长 yayyyy)——我将 4 个主题命名如下:
话题 0 :情感——感觉与生活
话题 1 :街头生活——牛肉和暴力(有点期待)
话题二:爱情和关系(各自为政
话题三:金钱、毒品和性
回顾-我在 2019 年 10 月熨斗学校科学展上的演示幻灯片
多年来的说唱
当主题建模的结果听起来不错时,我开始分析这些年来主题的演变。令人惊讶的是,在 2004 年前后,与“金钱/毒品/性”相关的歌曲有所增加。
90 年代左右的主要话题是“街头生活/牛肉/暴力”,它被解释为帮派之间或针对警察的明知故犯的争吵,或著名的西海岸对东海岸的对抗。然而,在 90 后,我们发现随着时间的推移,与“钱”相关的话题有了更好的分配。我认为这与音乐产业有关——艺术家必须创作(给歌迷他们想要的)来达到销售。
通过观察其他年度趋势,令人惊讶地发现了对音乐演变的更好描述。
更多作品——更少的单词和更短的歌曲!!!流式宝宝;)
上面的三幅图显示了产量是如何增加的。随着艺人发行更多单曲,新艺人很容易被发现,制作的歌曲数量也在增加。然而,歌曲的长度变得越来越短,歌曲中使用的词也越来越少。在一张专辑中塞进更多短小的歌曲比放一堆长歌更有利可图。
有了在线流媒体,艺术家不需要创作他们需要的热门歌曲。这种模式基于观点或倾听给他们报酬。因此,艺术家最好创作 50 首 2 分钟的歌曲,而不是像 CD 或磁盘时代那样创作 20 首每首 5 分钟的歌曲。我有点夸张,但你明白我的意思。虽然流媒体网站损害了艺术家的利益,因为它从他们的总销售额中扣除了一部分,但艺术家通过这种方式获得了更多的浏览量,并且仍然从订阅、广告和访问中获得版税。
我对这个项目很感兴趣,因为它结合了我的两个爱好:数据和音乐。我很乐意分享我从 EDA 中收集的两种不同类型的数据的更多发现。
想讨论就随便伸手!!!我的用户名是@fabricemesidor everywhere!!!
参考资料:
[## 潜在狄利克雷分配简介
假设你有下面这组句子:我喜欢吃西兰花和香蕉。我吃了一根香蕉和菠菜…
blog.echen.me](https://blog.echen.me/2011/08/22/introduction-to-latent-dirichlet-allocation/) [## 在线音乐流媒体对音乐产业的影响
音乐产业的经济在最近几年已经完全改变了,因为实体拷贝和在线销售…
globaledge.msu.edu](https://globaledge.msu.edu/blog/post/54474/effects-of-online-music-streaming-on-the) [## 是什么让一些 blink-182 歌曲比其他歌曲更受欢迎?第 1 部分-数据科学等。
在我上小学的一年圣诞节,我的隔壁邻居从圣诞老人那里得到了一个游戏方块,他…
jdaytn.com](http://jdaytn.com/posts/download-blink-182-data/)
如何使用机器学习模型直接从雪花中进行预测
使用雪花存储过程、Snowpipe、流和任务,允许用户通过 SQL 调用机器学习推理
图片来源: kennyzhang29 来自 Unsplash
通常,我们会面临这样的场景(最近我也是),数据科学家部署的模型按计划运行,无论是每小时一次、每天一次还是每周一次…您都明白这一点。然而,有时需要超出计划的结果来为会议或分析做出决策。
也就是说,有几种方法可以得到超出计划的预测…
获得超出计划的预测
- 用户可以使用一个笔记本实例,连接到数据存储,将数据卸载到 S3,引用数据进行预测,并将结果复制回数据存储。
- 开发人员可以构建一个模型托管 API,其中用户可以使用数据存储来提取数据,并发布到托管 API 上进行预测。
- 构建一个管道,允许用户使用 SQL 调用批处理预测来直接卸载数据。
因此,即使 Data Scientist & Co 可以为其他人实现一个批量预测应用程序,用于计划外的情况,也可以直观地让非技术用户更接近模型本身,并赋予他们从 SQL 运行预测的能力。
弥合在雪花上运行预测和 SQL 之间的差距
受亚马逊 Aurora 机器学习的启发,我花了几天时间思考如何弥合这一差距,并构建了一个架构,允许非技术用户舒适地使用 SQL 执行批量预测。这都是在 Snowflake 中使用存储过程、Snowpipe、流和任务以及 SageMaker 的批量预测作业(Batch Transform)来创建批量推理数据管道。
雪花机器学习-建筑设计
建筑结构图
- 用户以所需的格式将数据卸载到 S3,这将触发 Lambda。
- 调用 SageMaker 批处理转换作业是为了使用训练好的模型对数据进行批处理预测。
- 预测的结果被写回到 S3 桶中
- SQS 被设置在 S3 桶上,以将预测结果自动摄取到雪花上
- 一旦数据到达雪花,流和任务被调用。
卸载到 S3 —使用存储过程
S3 卸货流程图
创建输入表
为了让用户调用 Batch Transform,用户需要创建一个包含模型数据和强制字段的输入表,predictionid
是作业的 uuid,record_seq
是到达输入行的唯一标识符,一个空的prediction
列是感兴趣的目标。
输入数据:酒店 _ 取消
卸到 S3
call_ml_prediction
存储过程接受一个用户定义的作业名和输入表名。调用它会将文件(使用predictionid
作为名字)卸载到/input
路径的 S3 桶中,并在prediction_status
表中创建一个条目。从那里,将调用批处理转换来预测输入的数据。
为了确保不提交多个请求,一次只能运行一个作业。为了简单起见,我还确保只有一个文件被卸载到 S3 上,但是 Batch Transform 可以处理多个输入文件。
预测状态表
预测—使用 SageMaker 批量转换
触发批量转换的流程图
触发 SageMaker 批量转换
一旦数据被卸载到 S3 存储桶/input
,Lambda 就会被触发,从而调用 SageMaker 批处理转换来读入输入数据并将推理输出到/sagemaker
路径。
如果您熟悉批量转换,您可以根据自己的喜好为输出预测文件设置 input_filter、join 和 output_filter。
批量转换输出
一旦批量转换完成,它就将结果作为/sagemaker
路径中的.csv.out
输出。另一个 Lambda 被触发,它将文件复制并重命名为.csv
到/snowflake
路径,在那里 SQS 被设置为 Snowpipe 自动摄取。
结果——雪管、流和任务的使用
将数据绘制成雪花的流程图
通过雪管摄入
一旦数据被放到/snowflake
路径上,它就通过 Snowpipe 被插入到prediction_result
表中。为简单起见,由于 SageMaker 批处理转换保持了预测的顺序,因此行号被用作连接到输入表的标识符。您可以在批处理转换本身中执行后处理步骤。
数据流和触发任务
在 Snowpipe 传送数据后,在prediction_result
表上创建了一个流,它将填充prediction_result_stream
。这个流,确切地说是system$stream_has_data('prediction_result_stream
,将被调度任务populate_prediction_result
用来调用存储过程populate_prediction_result
来填充hotel_cancellation
表上的预测数据,前提是有一个流。唯一标识符predictionid
也被设置为任务会话变量。
批量转换的结果
完成工作
在作业结束时,并且在populate_prediction_result
完成之后,使用系统任务会话变量,下一个任务update_prediction_status
将预测状态从提交更新为完成。这就结束了整个“使用 SQL 运行批量预测”管道。
更新的预测状态
做得更好
Snowflake 通过 Snowpipe、Streams、Stored Procedure 和 Task 提供了强大的功能,创建了一个可用于不同应用程序的数据管道。当与 SageMaker 结合使用时,用户将能够直接从雪花发送输入,并与预测结果进行交互。
尽管如此,还是有一些愿望清单项目可以改善整体体验,那就是:
- 对于雪花:手动触发,或在 Snowpipe 摄取完成后触发任务的能力。这将保证任务向上完成流。
- 对于管道:能够从 AWS 端更新雪花的状态,让用户知道批量转换的进度
我希望你觉得这篇文章有用,并喜欢阅读。
关于我
我喜欢写中型文章,并与大家分享我的想法和学习。我的日常工作包括帮助企业构建可扩展的云和数据解决方案,以及尝试新的食物食谱。请随时与我联系,随便聊聊,只要让我知道你来自媒体
— 李帝努·亚玛
使用机器学习将您的图像转换为 Vaporwave 或其他艺术风格
TL;DR: 这篇文章介绍了一种流行的机器学习算法的机制,这种算法被称为神经风格转移(NST),它能够将你选择的任何图像转换为你最喜欢的艺术风格。该算法是著名的卷积神经网络的直接应用,并且巧妙地将问题框架化为对两个损失项的优化。凭借其简洁的公式,该算法提供了一种简单的方法来实现一个有趣的图像转换器(想想 DeepArt 或 Prisma)。深度学习中的任何主题都是巨大的,本文仅简要介绍 NST 算法。虽然它的续集将处理算法的实现怪癖和一些其他有趣的应用,但现在让我们获得算法背后的一些直觉,并享受玩它的乐趣。
问题设置
我们的目标很明确:让一个图像 S 采用另一个图像 t 的风格。在这一点上,这个目标可能听起来有点高,你可能会有一些合理的问题,例如我们如何在神经网络中表示一个图像,以及我们如何量化风格,这些将在下面的部分中得到适当的回答。
数字表示
简单来说,一幅图像被表示为一个张量,可以认为是一个矩阵的推广。例如,大小为 512512 的彩色图像将被表示为大小为 512512*3 的张量(3-D 矩阵),数字 3 来自于任何颜色都可以被编码为 R-G-B 值的元组的事实,每个值的范围从 0 到 255。这个矩阵将在以后用作算法的输入。
卷积神经网络基础
由于该算法建立在卷积神经网络(CNN)架构上,因此事先澄清一些关于它的观点是有帮助的。
CNN 中与我们的任务相关的两个最重要的构件是卷积层和池层。我们首先来看看卷积层的内部工作原理。
那么我们如何从输入层到第一个卷积层呢?让我们看看下图:
在上图中,位于左上角的大小为 333 的子矩阵(为便于说明,此处仅显示了两个维度)将通过一个相同大小的滤波器,该滤波器通过对子矩阵应用卷积运算来转换子矩阵,其结果成为卷积层左上角神经元的激活。
但是什么是过滤器呢?现在你可以把它理解为一种识别描述图像的某些特征的方法:直角、曲率、纹理等。它通过将自身与输入子矩阵进行卷积来实现这一点。要获得更全面的治疗,请遵循维基百科页面中的提示。
将过滤器向右滑动一个像素,我们得到以下结果:
该滤波器将应用于每个 333 子矩阵,我们将有我们的第一个完整的卷积层。
您可以检查一下,如果我们对上述大小为 663 的输入矩阵使用大小为 333 的滤波器,那么得到的卷积层大小将为 441。然而,一般来说,滤波器的数量大于 1,这意味着我们可能要应用几个不同的滤波器,以便将输入矩阵转换为第一个卷积层。想象一下,我们将从 4 个不同的过滤器得到的大小为 441 的矩阵堆叠在彼此的顶部;我们将最终得到一个大小为 444 的卷积层,它又会成为下一层的输入,无论是另一个卷积层还是池化层。注意,在计算机视觉行话中,每个大小为 441 的滤波器输出可以称为一个特征图;因此,这里我们有 4 个特征地图。
池层的机制可以理解为降维。在下图中,池层的作用是将下一层中任何大小为 22 的子矩阵减少到 11。进行这种下采样的流行方法包括取最大值或平均值。
一般来说,CNN 的架构将包括卷积层和池层的交替。典型架构的示例如下:
VGG19 架构,一般用于神经风格转移,此处采用自的
神经风格转移(NST)算法
清楚了基本原理之后,让我们开始研究算法的细节。
NST 利用了上面说明的 VGG19 神经网络,不包括右端的三个全连接层,它已经过预训练,可以使用 ImageNet 数据集执行对象识别。VGG19 附带了 PyTorch 和 TensorFlow 等流行的深度学习框架,因此您不需要实际自己实现它。
让我们回顾一下迄今为止我们所掌握的情况。我们有预先训练的 VGG19 CNN,一个图像矩阵 S 被转换成图像矩阵 T 的样式,以及在网络的每个中间层的中间图像矩阵S’(可以将*S’*的初始值设置为白噪声,或者简单地设置为 S )。
下一步是将整个问题公式化为优化任务。NST 将其分解为两个损失函数之和的最小化,即内容损失和风格损失。让我们开始吧。
乔纳森·福门托在 Unsplash 上的照片
**直观上,内容损失量化了我们在某一层的中间图像与内容图像之间的距离。**因此在每一层 l ,我们将*S’*的当前状态表示为 x ,将原始图像表示为 p ,并且进一步我们还有 x 的特征图,表示为 F ,以及 p 的特征图,表示为 P 。因此,层 l 处的内容损失简单地为:
在层 l,我们对 F 和 P 之间的平方误差求和,对所有特征图在 I 上循环,对给定特征图中的所有单元在 j 上循环
为了得到总的内容损失,简单地对所有层的项求和。
现在让我们来看看风格的丧失。这里,风格可以被宽泛地定义为不同特征地图之间的相关性。对于我们的中间图像 x ,让我们定义 G :
这一项表示在层 l 的两个特征图 I 和 j 之间的相关性。求和是在所有特征图单元上进行的。
类似地,我们可以为原始内容图像 p 定义一个矩阵 A 。那么我们在层 l 的风格损失可以定义为:
n 和 M 表示层 l 处的特征地图的数量和任何给定特征地图的大小
对所有层求和,我们得到总风格损失:
在实际操作中,上面的权重项 w 可以设置为所有层都相等:1/(层数),或者你可以根据原论文进行更精细的决策。
最终,总损失函数是内容损失和样式损失的加权和:aL(内容)+ bL(样式)** ,使用您最喜欢的优化器在每一层对 F(i,j)进行最小化。最终的 F 矩阵将是你的结果图像。
结果
PyTorch 提供了一些神经类型转换的示例代码,非常容易理解和实验。有关实施的更多信息,请参考下面的进一步阅读部分。
请注意,在将输入图像和样式图像提供给 PyTorch 实现之前,您需要使它们具有相同的大小。
现在是有趣的部分:作为乔尔乔·德·契里柯的粉丝,我做了以下实验,试图将他的作品变成类似蒸汽波的风格:
左:乔尔乔·德·契里柯。爱情之歌;右图:vaporwave 股票图像
使用左边作为内容输入图像,右边作为样式图像,我们得到如下结果:
同样,德·基里科的另一幅杰作具有与现代插画不同的化学风格:
左:乔尔乔·德·契里柯。一条街的神秘和忧郁;右:盖娜浩史。南部高速公路
这给出了以下结果:
请按照下面的指示探索进一步的神经风格转换,并通过将它们转换成一些意想不到的风格来赋予您的照片或图像新的生命。
进一步阅读
[2]https://papers with code . com/paper/a-neural-algorithm-of-artistic-style
使用机器学习来检测欺诈
马克斯·本德在 Unsplash 上的照片
端到端机器学习项目的开始
内容
介绍
欺诈检测问题
数据
构建框架
介绍
机器学习是人工智能(AI)的一个子集,它为系统提供了自动学习和根据经验进行改进的能力,而无需显式编程。也就是说,我们(人类)有可能向计算机提供大量数据,让计算机学习模式,以便它可以学习如何在面临新的情况时做出决定——当我发现这一见解时,我立即知道世界即将改变。
它揭示了欺诈正在花费全球经济 3.89 万亿,损失在过去十年中上升了 56%。— 克罗英国
作为一名欺诈的受害者,想出办法来防止这种事情再次发生在我身上(以及其他任何人身上),这基本上促使我进入了一个与我习惯的领域完全不同的领域。
欺诈检测问题
在机器学习术语中,诸如欺诈检测问题之类的问题可以被框定为分类问题,其目标是预测离散标签 0 或 1,其中 0 通常暗示交易是非欺诈性的,1 暗示交易似乎是欺诈性的。
因此,这个问题要求从业者建立足够智能的模型,以便能够在给定各种用户交易数据的情况下准确地检测欺诈性和非欺诈性交易,这些数据通常是匿名的,以保护用户隐私。
由于完全依赖基于规则的系统不是最有效的策略,机器学习已经成为许多金融机构解决这一问题的方法。
使这个问题(欺诈检测)如此具有挑战性的是,当我们在现实世界中对其建模时,发生的大多数交易都是真实的交易,只有非常小的一部分是欺诈行为。这意味着我们要处理不平衡数据的问题——我关于过采样和欠采样的帖子是处理这个问题的一种方法。然而,对于这篇文章,我们的主要焦点将是开始我们的机器学习框架来检测欺诈——如果你不熟悉构建自己的框架,你可能想在完成这篇文章之前通读一下结构化机器学习项目。
一种不平衡分类技术
towardsdatascience.com](/oversampling-and-undersampling-5e2bbaf56dcf) [## 构建机器学习项目
构建 ML 项目的模板指南
towardsdatascience.com](/structuring-machine-learning-projects-be473775a1b6)
数据
这些数据是由 IEEE 计算智能学会(IEEE-CIS)的研究人员收集的,目的是预测在线交易欺诈的概率,如二进制目标(T0)所示。
注:本次比赛的数据部分是从 Kaggle 数据部分复制而来。
数据被分成两个文件identity
和transaction
,由TransactionID
连接。并非所有交易都有相应的身份信息。
分类特征—交易
ProductCD
card1
-card6
addr1
,addr2
P_emaildomain
R_emaildomain
M1
-M9
分类特征—同一性
DeviceType
DeviceInfo
id_12
-id_38
TransactionDT
特性是给定参考日期时间的时间增量(不是实际的时间戳)。
你可以从竞赛主持人的这篇帖子中了解更多数据。
文件
- train _ {事务,身份}。csv —训练集
- 测试 _ {事务,身份}。csv —测试集(您必须预测这些观察的
isFraud
值) - sample_submission.csv —格式正确的示例提交文件
构建框架
处理任何机器学习任务的第一步是建立一个可靠的交叉验证策略。
验证机器学习模型的性能
towardsdatascience.com](/cross-validation-c4fae714f1c5)
注意:该框架背后的总体思想正是来自 Abhishek Thakur — Github
当面临不平衡数据问题时,通常采用的方法是使用StratifiedKFold
,它以这样一种方式随机分割数据,即我们保持相同的类分布。
我实现了创建折叠作为preprocessing.py
的一部分。
这段代码合并来自训练和测试集的身份和事务数据,然后重命名merged_test
数据中的列名,因为 id 列使用“-”而不是“_”—这将在我们稍后检查以确保我们在测试中有完全相同的列名时导致问题。接下来,我们将名为kfold
的列添加到我们的训练数据中,并根据它所在的文件夹设置索引,然后保存到一个 csv 文件中。
你可能已经注意到我们导入了config
,并把它作为各种事物的路径。所有的配置都是另一个脚本中的变量,这样我们就不必在不同的脚本中重复调用这些变量。
在处理机器学习问题时,以允许快速迭代的方式快速构建管道非常重要,因此我们将构建的下一个脚本是我们的model_dispatcher.py
,我们称之为分类器,而train.py
是我们训练模型的地方。
先说model_dispatcher.py
这里,我们简单地导入了一个逻辑回归和随机森林,并创建了一个字典,这样我们就可以通过运行逻辑回归模型的models["logistic_regression"]
将算法调用到我们的训练脚本中。
列车脚本如下…
希望你可以阅读代码,但如果你不能,总结一下发生了什么,我们将训练数据设置为列kfold
中的值,这些值等于我们通过的测试集的倍数。然后,我们对分类变量进行标签编码,并用 0 填充所有缺失值,然后在逻辑回归模型上训练我们的数据。
我们得到当前折叠的预测,并打印出 ROC_AUC 。
深入了解 AUC-ROC…
towardsdatascience.com](/comprehension-of-the-auc-roc-curve-e876191280f9)
注意:就目前情况来看,代码不会自己运行,所以当我们运行每个 fold 时,我们必须传递 fold 和 model 的值。
让我们看看我们的逻辑回归模型的输出。
### Logistic Regression # Fold 0
ROC_AUC_SCORE: 0.7446056326560758# Fold 1
ROC_AUC_SCORE: 0.7476247589462117# Fold 2
ROC_AUC_SCORE: 0.7395710927094167# Fold 3
ROC_AUC_SCORE: 0.7365641912867861# Fold 4
ROC_AUC_SCORE: 0.7115696956435416
这些都是相当不错的结果,但让我们使用更强大的随机森林模型,看看我们是否可以改进。
### Random Forest# Fold 0
ROC_AUC_SCORE: 0.9280242455299264# Fold 1
ROC_AUC_SCORE: 0.9281600723876517# Fold 2
ROC_AUC_SCORE: 0.9265254015330469# Fold 3
ROC_AUC_SCORE: 0.9224746067992484# Fold 4
ROC_AUC_SCORE: 0.9196977372298685
很明显,随机森林模型产生了更好的结果。让我们向 Kaggle 提交一份最新报告,看看我们在排行榜上的排名。这是最重要的部分,为此我们必须运行inference.py
。
注意:提交给 Kaggle 的过程超出了本次讨论的范围,因此我将在排行榜上公布评分模型及其表现。
鉴于这一分数被转换为 Kaggle 的私人排行榜(因为这是公共排行榜上的分数),我们在 Kaggle 的私人排行榜上的排名是 3875/6351(前 61%)。虽然,从 Kaggle 的角度来看,这看起来不太好,但在现实世界中,我们可能会根据任务来决定这个分数。
然而,这个项目的目标不是想出最好的模型,而是创建我们自己的 API,我们将在后面的帖子中回来。
为了构建快速迭代的快速管道,我们拥有的代码是可以的,但是如果我们想要部署这个模型,我们必须做大量的清理工作,以便我们遵循软件工程最佳实践。
成为不可或缺的数据科学家
towardsdatascience.com](/data-scientist-should-know-software-engineering-best-practices-f964ec44cada)
包裹
检测欺诈在现实世界中是一个非常常见且具有挑战性的问题,提高准确性对于防止在商店进行真实交易时客户卡被拒绝的尴尬非常重要。我们已经建立了一个非常简单的方法,使用分类变量的标签编码,用 0 填充所有缺失值,以及一个随机森林,没有任何调整或方法来处理数据中的不平衡,但我们的模型仍然得分很高。为了改进模型,我们可能希望首先查看随机森林模型中的重要特征,并删除不太重要的特征,或者我们可以使用其他更强大的模型,如光梯度增强机器和神经网络
注意:在写这个脚本的时候,模块不是最好的,但是它的格式允许我快速迭代。在未来的工作中,我计划将这个模型作为 API 部署在云服务器上。
让我们继续 LinkedIn 上的对话…
[## Kurtis Pykes -人工智能作家-走向数据科学| LinkedIn
在世界上最大的职业社区 LinkedIn 上查看 Kurtis Pykes 的个人资料。Kurtis 有两个工作列在他们的…
www.linkedin.com](https://www.linkedin.com/in/kurtispykes/)
使用机器学习来区分什么是真实的,什么不是
超现实世界中假新闻检测的神经网络方法
照片由 Unsplash 上的 nij wam Swargiary 拍摄
这篇文章是作为 2020 年后变得越来越不现实的想法出现的。这个世界正变得越来越陌生,我们从互联网上的各种来源接收到越来越多的信息,其中一些充其量是不诚实的。知道你读到的是假的还是真正离奇和令人震惊的能力变得越来越难。距离美国大选还有不到一个月的时间,能够从假新闻中辨别出真实是很重要的。
我将尝试使用一种机器学习(ML)技术来将标题分类为虚假与否,并将其与人类进行比较。
人类探讨
我认为我们应该从实验开始。我会用两个标题,一个来自一篇假文章(来自洋葱),另一个来自一篇真正的文章。
答案并不明显,遗憾的是,这并不是唯一的例子。你可以在文末找到答案但是不要宠坏自己。
我决定再做一个小实验。我选了六个头条(三假三真)。然后我上了 Instagram,在我的粉丝中做了一个民意调查。我知道,这个样本不仅仅是有偏见的,因为它只代表了我的朋友,尽管如此,它仍然是一个指标。
人类集体知识的成功率(准确率)为 0.5 。实际上比扔硬币和依靠纯粹的运气好不了多少。
让我们看看“机器”将会如何表现。
机器学习方法
GitHub 的一名用户从两个来源收集数据,一个是“假”新闻(来自《洋葱》),另一个是真实但怪异的新闻。
“假”标题来自《洋葱新闻》。对于那些不知道“洋葱”的人来说,这是一个美国恶搞网站,以讽刺的口吻报道真实和虚构的事件,模仿真实的新闻机构。不是想骗人,是想娱乐人。所以,这不完全是坏的假新闻,我们只是使用这个数据集,因为我们知道我们可以很容易和客观地将它们归类为假的。
真正的标题来自一个名为 r/NotTheOnion 的子编辑,它包含了来自真实世界的各种超现实的标题,用户可能会将其误解和/或希望为洋葱新闻。
该数据集被广泛使用,并且有很多实验在数据上完成,其中一些比我的更准确。
我决定实现一种不同于我在网上作为辅助项目找到的技术,来提高我的 NLP(自然语言处理)技能。
工艺管道
在对数据进行预处理后,我制作了一个 Tf-idF 并训练了一个神经网络来对新闻进行分类。
但是首先让我们对数据集有一些基本的了解。
我们有 24k 个标题,其中 62.5%为非洋葱文章,37.5%为洋葱文章。
让我们更深入地了解这个项目的技术方面。如果你不感兴趣,就直接跳到结果里。
对于该项目,我们将需要以下进口
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.model_selection import train_test_split
from sklearn import metrics
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import StratifiedKFold
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import cross_validatefrom keras.wrappers.scikit_learn import KerasClassifier
from keras.layers import Dropout, Dense
from keras.models import Sequential
from keras import backend as K
import tensorflow as tf
import plotly.graph_objects as goimport matplotlib.pyplot as plt
import plotly.express as px
import numpy as np
import pandas as pd
import nltk
import re
from wordcloud import WordCloudnltk.download('punkt')
nltk.download('stopwords')
ENG_SW = set(nltk.corpus.stopwords.words('english'))
现在我们应该开始数据的预处理。对于这一部分,我们将使用 NLTK 套件。
首先,我们只保留小写字母数字字符,并丢弃特殊字符。然后,我们开始一个过程,在这个过程中,我们对单词进行标记,然后清除无用的单词,最后我们对单词进行词干处理。这是一个标准的 NLP 过程,NLTK 可以很容易地帮助我们完成。
df = pd.read_csv("onion-or-not.csv") def prepossessing(df):df["text"] = df["text"].apply(lambda x : x.lower())df["text"] = df["text"].apply(lambda x : re.sub('[^a-zA-z0-9\s]','',x))df["text_list"] = df["text"].apply(lambda x : nltk.word_tokenize(x))df["cleaned_list"] = df["text_list"].apply(lambda x: [word for word in x if word not in ENG_SW])df["stemmed_cleaned_list"] = df["cleaned_list"].apply(lambda x : [nltk.PorterStemmer().stem(i) for i in x])df['text_edited'] = df['stemmed_cleaned_list'].apply(lambda x : " ".join(x))return df['text_edited']df_X = prepossessing(df)
df_Y = df['label']
现在我们已经完成了基本的文本预处理,在进行下一步之前,让我们可视化两个标签的单词云。
不是洋葱
洋葱
下一步是分割数据集并生成数据的TF–IDF。
X_train, X_test, y_train, y_test = train_test_split(df_X, df_Y, test_size=0.25, random_state=seed)print(X_train.shape, y_train.shape)
print(X_test.shape, y_test.shape) vectorizer_x = TfidfVectorizer()X_train_tfidf = vectorizer_x.fit_transform(X_train).toarray()
X_test_tfidf = vectorizer_x.transform(X_test).toarray()
在我们有了 tf-idf 之后,我们将继续我们的模型。
数据集很简单,因此我们将构建一个小型的基本模型。
def Build_Model_DNN_Text(shape, optimizer='Adam', nLayers= 1, neurons=16, dropout=0.85):"""Build_Model_DNN_Tex(shape, nClasses,dropout)Build Deep neural networks Model for text classificationShape is input feature space"""model = Sequential()# number of hidden layersmodel.add(Dense(64,input_dim=shape,activation='elu'))model.add(Dropout(dropout))for i in range(0, nLayers):model.add(Dense(neurons,input_dim=neurons,activation='elu'))model.add(Dropout(dropout))model.add(Dense(1, activation='sigmoid'))model.compile(loss='binary_crossentropy',optimizer=optimizer,metrics=['accuracy',tf.keras.metrics.AUC(),tf.keras.metrics.Precision(),tf.keras.metrics.Recall()])return model
然后我们训练我们的模型
model_DNN = Build_Model_DNN_Text(X_train_tfidf.shape[1])history = model_DNN.fit(X_train_tfidf, y_train,validation_data=(X_test_tfidf, y_test),epochs=100,batch_size=4096,verbose=2,callbacks=[tf.keras.callbacks.EarlyStopping(monitor='val_accuracy', mode = "max", patience=10)])
结果
我们训练的结果
模型精度图
模型损失图
模型回忆图
模型精度图
让我们运行我的 Instagram 实验的标题,看看它与人群相比如何。
titles = [{"text" : "Coronavirus homeschooling: 77 percent of parents agree teachers should be paid more after teaching own kids, study says", "label" : 0},{"text" : "Police Department Celebrates Fourth Of July By Using Fireworks For Crowd Control ", "label" : 1},{"text" : "ICE Director: ICE Can't Be Compared To Nazis Since We're Just Following Orders", "label" : 0},{"text" : "Hackers Obtain Data Of 45 Million Target Customers Revealing What They’ve Done In Store Bathrooms", "label" : 1},{"text" : "US Military Could Lose Space Force Trademark to Netflix Series", "label" : 0},{"text" : "Trump Blames China For Acting Too Late In Coordinating U.S. Coronavirus Response", "label" : 1}]exp = pd.DataFrame(titles, columns=['text','label'])exp_x = prepossessing(exp)exp_x_tfidf = vectorizer_x.transform(exp_x).toarray()model_DNN.evaluate(exp_x_tfidf, exp['label'])
我们评价的准确率比人群好 0.83。
结论
我们实现了一个基本模型,得到了一些下降结果,比人类实验更好。如果我们有更大的数据集和更好的技术,我们可以轻松达到 90%以上的准确率。感谢您抽出宝贵的时间,并且我很乐意讨论任何反馈。
该项目的 GitHub 可以在这里找到。
页(page 的缩写)S
不是洋葱
特朗普总统周日将一座高尔夫奖杯献给了最近席卷德克萨斯州的强大飓风的受害者…
thehill.com](https://thehill.com/homenews/administration/353355-trump-dedicates-golf-trophy-to-puerto-rico-hurricane-victims)
洋葱
[## 众议院指责奥卡西奥-科尔特斯在国会发言时使用性别歧视的诽谤
华盛顿——众议院投票通过了一项谴责这位新生的女议员行为的决议
www.theonion.com](https://www.theonion.com/house-censures-ocasio-cortez-for-using-sexist-slur-on-f-1844498607)
利用机器学习对抗冠状病毒
机器学习已经成为一项强大的技术,推动了医疗保健、机器人、数据挖掘、网络安全等领域的进步。最近,深度学习技术的出现使得开发更复杂的架构和新的探索领域成为可能——自然语言处理、计算机视觉等。
新型冠状病毒(冠状病毒)疫情最近肆虐全球,已造成超过 100 万病例( 来源 )。运输系统和机场在识别冠状病毒病例时遇到了特别的困难(T5 来源 T7)。几个潜在阳性的个体也可能是无症状的,并且可能表现出很少或没有冠状病毒的症状,尽管是携带者。这些人可能会影响其他人,这些人出现并发症的风险更高,最终可能需要医院护理和通过通气进行重症监护( 来源 )。目标是通过最经济的方法限制病例数量和传染病的传播,因为这将降低医院的处理能力。
解决病毒问题的一个关键方法是在分子水平上分析其复制周期。构建冠状病毒疫苗的过程需要对冠状病毒的复制进行分子抑制。我们从描述新型冠状病毒的复制周期开始。病毒首先与宿主细胞的 ACE2 受体结合。然后病毒进入细胞,并开始将其病毒 RNA 释放到细胞中。这种病毒 RNA 基因组最初被翻译成特殊的 pp1a 蛋白(多聚蛋白 1a)。这些蛋白质然后被蛋白水解成复制酶,基因组的其余部分被转录成亚基因组 mRNAs。这些 mRNAs 然后被翻译成病毒的特定功能蛋白(刺突蛋白、膜蛋白等。).这些功能性蛋白质在能区室中加工后自我组装,并通过胞吐作用释放。这种复制过程使病毒得以迅速传播,并表明它会在患者的呼吸系统和免疫系统中引起许多健康问题。
新型冠状病毒粒子(来源 — CCO 公共领域使用)
如上所述,目前阻止病毒传播的生物医学努力试图通过限制特定酶继续复制过程的能力,在分子水平上抑制病毒。这些努力特别耗时,并且需要对分子进行密集的生化密度泛函理论(DFT)模拟。因此,我们目前只能试图在未来几个月内限制该病毒的传播,因为该病毒的生物分子实验和抑制性研究需要时间来处理。为了了解谁在瞬间感染了病毒并限制感染,我们必须关注有症状的个体,并能够限制其传播,以减少有症状和无症状的新个体的数量。
热成像技术是一种关键的方法,可以用来帮助辨别谁感染了病毒,谁开始出现症状。热成像属于热成像科学领域。这些相机检测红外辐射,并通过不同的颜色表达不同水平的辐射。热辐射与温血动物的体温升高直接相关。下面给出了热成像的一些例子。
人体热成像(来源 — CCO 公共领域使用)
如果患者在感染病毒的早期阶段开始出现发烧的迹象,这将导致体温上升,并随后发烧。在热成像相机上,我们会看到有症状的病毒携带者上半身有更多的辐射(更残忍的红色)。
机器学习作为模式识别的最前沿方法已经变得无处不在,因此应该可以将数据集插入特定的机器学习算法中,并实现对发烧(可能还有病毒)个体的系统分类。目前,在交通、商业和贸易的主要公共中心,在不造成更多感染的情况下为所有人部署检测是非常低效和昂贵的。通过使用远距离相机,利用热成像扫描通过某个区域的个人,我们可以了解谁可能发烧,谁可能没有发烧。这将全部基于实时处理输入数据的机器学习算法。
可能对该问题有用的一些示例算法包括朴素贝叶斯机器学习(概率)、支持向量机、K-最近邻和随机森林模型。有趣的是,我们可以在这种情况下直接应用计算机视觉。计算机视觉是深度学习的一个子集,它利用图像或视频输入,通过深度神经网络提取特征并进行分类。下面给出一个深度卷积神经网络的例子。
卷积神经网络(来源: Sumit Saha
总之,我们可以利用计算机科学和机器学习的力量,朝着恢复疫情之后的世界迈出一步。许多开源代码和数据集已经在网上开发出来,一些研究小组已经开始开发信息学算法来检测冠状病毒。像下面这样的算法使用 CT 扫描数据来模拟感染病毒的风险。(例如。https://www . medrxiv . org/content/10.1101/2020 . 02 . 14 . 20023028 v3
在过去的几年中,医学科学与信息学技术的结合势不可挡,医学成像、基因组学和肿瘤学等领域也因计算机科学的进步而发生了转变。通过信息学成像和分子化学为今天的冠状病毒做准备也将在未来帮助我们。
编者按: 走向数据科学 是一份以数据科学和机器学习研究为主的中型刊物。我们不是健康专家或流行病学家,本文的观点不应被解释为专业建议。想了解更多关于疫情冠状病毒的信息,可以点击 这里 。
使用机器学习寻找亚马逊的下一个履行中心
现实世界中的数据科学
假设:巴西。但是具体在哪里呢?
亚马逊应该在哪里建立下一个履行中心?我们可以利用机器学习来帮助回答这个问题。
图片来自谷歌地图
首先,让我们定义业务案例:
- 履行中心的一个主要目的是实现亚马逊的核心价值主张:快速 delvery。这意味着对于客户来说,位于中心位置非常重要。
- 据估计,2020 年,亚马逊拥有美国电子商务市场份额的近 44%,第二大竞争对手的份额为 7%。让我们放眼美国之外,发掘尚未开发的全球市场机会。
- 让我们从现有的亚马逊国家中进行选择,以利用基础设施和法规遵从性。
图片来自维基百科
接下来,让我们探讨亚马逊履行中心与全国人口的比率。比率越小,中心需要担心的客户就越少,交付速度就越快。
2020 年 5 月从维基百科提取的数据
例如,亚马逊美国目前的比例是每 300 万人有 1 个履行中心。这意味着旧金山湾区中心的 1 个履行中心使亚马逊能够在当天完成购物项目并开车送货。
看上面的数据,哪个国际国家的增长潜力最大?巴西似乎是一个不错的选择:它的总中心数量最少,人口最多,每 1.05 亿人有 1 个中心,也是亚马逊最近宣布扩张和感兴趣的地方。
假设这些都是正确的因素,那么巴西到底在哪里呢?我们可以使用机器学习 k-means 聚类来识别潜在位置。从结论开始,这里是潜在的位置。
小圆圈代表巴西所有的 387 个城市。橙色的大圆圈代表 10 个集群的质心,这是潜在的履行中心位置。
下面是获得结果的代码:
# Import libraries
import pandas as pd
from sklearn.cluster import KMeans
import plotly.graph_objects as go# Load and explore data of world cities from [https://simplemaps.com/data/world-cities](https://simplemaps.com/data/world-cities)
data = pd.read_csv('Data/worldcities.csv')
data.head()
# Find how many cities in Brazil
data.loc[data.country == 'Brazil'].count()# Filter data to only have Brazil
brazil = data[data.country.isin(['Brazil'])]
print(brazil.shape)
brazil.head()
# Use k-means to find clusters
brazil2 = brazil[['lat', 'lng']]
kmeans = KMeans(n_clusters = 10)
kmeans.fit(brazil2)
y_means = kmeans.predict(brazil2)
centers = kmeans.cluster_centers_# Plot on map
fig = go.Figure(data = go.Scattergeo(
lon = brazil2['lng'],
lat = brazil2['lat'],
mode = 'markers',
marker = dict(
size = 3,
opacity = 0.8,
reversescale = True,
autocolorscale = True,
symbol = 'circle',
line = dict(
width = 1,
color = ['rgba(102, 102, 102)']
),
cmin = 0,
color = y_means,
colorbar_title = "City Clusters"
)
))fig.add_trace(go.Scattergeo(
lon = centers[:,1],
lat = centers[:,0],
mode = 'markers',
marker = dict(
size = 8,
line = dict(
width = 1,
color = 'orange'
),
color = 'orange',
)
))fig.update_layout(
title = "Brazil City Clusters and Centroids ",
geo = dict(
scope = "south america",
showland = True,
)
)# Print to new page: fig.write_html('first_figure.html', auto_open=True)
fig
小圆圈代表巴西所有的 387 个城市。橙色的大圆圈代表 10 个一组的质心,这是潜在的履行中心位置。
如果我们将聚类数增加到 25,我们会得到这样的结果:
从 plot ly(plotly.com/python/scatter-plots-on-maps)生成的地图图像
为了达到与亚马逊美国相同的履行中心比率,亚马逊巴西将需要 70 个中心。我们可以在聚类中加入其他因素,如人口变量。
# Use k-means to find clusters
brazil2 = brazil[['lat', 'lng', '**population**']]
kmeans = KMeans(n_clusters = **70**)
kmeans.fit(brazil2)
y_means = kmeans.predict(brazil2)
centers = kmeans.cluster_centers_
我们会得到这个:
接下来的步骤:
从这里开始,我们应该利用领域知识来更好地了解客户人口统计、电子商务采用、基础设施等。这只是一个初步的假设,需要更深入更精细的分析。你可以在这里看到完整的代码:github.com/allenjiang/mona-lisa-ai。
图片来自维基百科
使用机器学习提高客户保持率
来源: GenHQ
将购物车放入 Instacart
本博客由 Nicki (Nicola) Kornbluth、Daniel Moskowitz、Sanchya Sahay 和 Metika Sikka 为哥伦比亚大学商业分析项目的一门商业分析课程撰写。
当我们在 2020 年 1 月开始这个项目时,在线杂货似乎是一个令人兴奋的研究行业。几十年来,食品杂货业一直保持着年增长率(即使是在经济衰退时期),网上食品杂货的市场份额也在不断增长。此外,由于习惯驱动的消费者行为和无与伦比的数据访问,在线杂货数据似乎是预测分析的一个很好的候选对象。
gifs.com 制作的 GIF
我们一点也不知道,这个行业将会发生前所未有的变化:
虽然下面的发现可能无法解释当前的购物行为,但我们的分析侧重于保留营销策略,这将是在线杂货店大流行后计划的关键。
在疫情之前,杂货商的大部分增长来自家庭支出的增加,而不是新人们的支出。平均而言,大多数家庭每周至少购买一次食品杂货。
这告诉我们,要取得成功,网上杂货店需要他们的客户建立一种习惯,而且要快。虽然收购在零售业中总是一个因素,但在杂货业中,增长依赖于留住你的客户并增加他们的终身价值。
我们从业内最大的参与者之一— Instacart 的角度来探讨这个问题。下面描述的所有分析都利用了insta cart 在线杂货购物数据集 2017 。”
insta cart 在线杂货购物数据集 2017 的结构
对数据的初步观察证实了我们的怀疑:许多顾客只下了几笔订单,但忠诚者的尾巴很长。我们希望能帮助长出这条尾巴。
资料来源:2017 年 Instacart 在线杂货购物数据集
我们将精力集中在两个方面:
- ***减少订单之间的时间。*通过让顾客更频繁地购物,我们希望增加他们的订单数量,并成为他们的固定购物点。
- ***理解和促进再订购行为。*重新排序是习惯的关键标志,所以我们想要培养这种行为。
来源: GIPHY
缩短订单之间的时间
通过减少订单之间的时间,Instacart 可以确保它从用户的杂货预算中获得越来越多的份额。
为此,我们创建了一个模型来预测用户下一次购物的时间。通过找到导致更频繁订单的因素,Instacart 可以鼓励用户采取类似的行为。他们还可以更好地把握营销信息的时机,在顾客与竞争对手购物之前赢回顾客。
车型
我们创建了许多功能来更好地了解用户的购物模式。这些分为三类:最近的订单、购物者类型的“标志”和累积行为。
我们对订单时间的驱动因素感兴趣,所以我们想要一个易于解释的模型。在快速浏览了决策树之后,我们把精力集中在线性回归上。我们的平均误差是 4.29,这意味着我们通常能够在半周内确定用户的下一个订单。
更重要的是,我们学到了一些有趣的见解。例如,购买餐具室商品的用户倾向于在他们的订单之间有更长的时间,而在早上或工作日订购的用户倾向于订购得更快。
建议
基于这些见解,我们建议 Instacart 采取以下措施来提高订单频率:
- 专注于推动工作日早上的订单
- 取消前几个订单的最小订单量,以培养习惯
- 尝试向用户介绍新的部门
- 在营销材料中突出冲动购买
预测重新排序行为
网上杂货商长期以来一直在宣传方便的信息。不幸的是,这种优势也是他们最大的弱点——客户经常在平台之间切换,选择最有效的平台。这意味着建立品牌忠诚度很难,但却是留住客户的关键。
在杂货店购物的忠诚度很大程度上是基于习惯,所以促进重新订购是我们努力的一个很好的地方。
为了实现这一目标,我们建立了一个模型,预测用户在下一次购物车中重新订购他们之前购买的任何商品的概率,以便 Instacart 可以更好地服务客户,并在客户生命周期的早期建立忠诚度。
型号
对于这个模型,我们创建了一个约 850 万行的用户-产品级矩阵。我们还开发了一组新的 27 个特性,包括产品级、用户级和用户-产品级。由于数据集的规模很大,为了提高效率,我们转向 Google Cloud 在虚拟机上运行 R。
我们尝试了几种不同的技术来构建这个模型。因为我们的数据集是不平衡的,所以我们将性能与 F1 分数进行了比较。在此基础上,我们的最佳模型是针对不平衡类调整的随机森林和 XGBoost 树。
然而,由于集合模型的结果很难解释,我们在 Log-Lasso 中寻找一些帮助。这些系数向我们展示了每个特征如何直接影响结果。我们从我们的集合模型中用可变的重要性将它分层,以推断驱动和阻止重新排序的特征。**
应用程序
Instacart 可以利用该模型的预测:
- 产品订阅:关注最有可能再次订购产品的用户,并以较低的价格提供订阅服务,以确保留住客户。
- 库存管理:根据再订购行为向合作商店提供需求预测。
- 有针对性的营销:利用这些预测进行营销,向重新订购产品的可能性中高的用户发送促销信息。在营销中加入补充产品。
- ****提高利润:为再订购概率高的人群推荐和推广高利润替代品。
来源: GIPHY
TL;速度三角形定位法(dead reckoning)
对网上杂货店来说,留住顾客一直是关键,但后疫情时代,这将决定他们生意的成败。我们使用多种机器学习工具来帮助 Instacart 通过专注于减少订单之间的时间和培养再订购行为来吸引和留住他们的客户。(或者像我们在这个项目中的口头禅一样,“搅拌黄油,而不是顾客。”)
你可以在我们的 GitHub repo 上看到这个项目的代码和演示:【https://github.com/dsm2173/instaCART
使用机器学习预测新冠肺炎的增长
用数据科学对抗冠状病毒
编者按: 走向数据科学 是一份以数据科学和机器学习研究为主的中型刊物。我们不是健康专家或流行病学家,本文的观点不应被解释为专业建议。想了解更多关于疫情冠状病毒的信息,可以点击 这里 。
背景
新冠肺炎,由新型冠状病毒病毒引起的疾病,已经用了 2020 年的时间,在六个月内,已经导致美国超过 13 万人死亡。由于过去几个月大多数州宣布封锁迫使许多数据科学家呆在室内,该社区的成员正在寻找为抗击冠状病毒做出贡献的方法。虽然有许多研究正在进行,试图通过预测蛋白质结构或通过非侵入性程序(如 CT 扫描)对冠状病毒的病例进行分类来寻找冠状病毒的疫苗,但还没有许多旨在直接模拟冠状病毒生长的公共模型。
然而,肯定有模型的应用,旨在直接模拟冠状病毒的生长。虽然这些模型可以用来帮助城市制定关于锁定和重新开放某些业务的政策,但它们也可以通过帮助医院预测他们在给定特定数据的情况下第二天所需的资源,对医院极其有益。例如,医院可以根据对冠状病毒病例的本地预测和之前所需床位或医生数量的数据,预测第二天需要的床位或医生数量。
问题陈述
我的目标是开发能够合理预测第二天冠状病毒生长的公共模型。这个目标可以分为两个部分:
- 建立一个模型,根据前 n 天的冠状病毒病例数和死亡数预测第二天的冠状病毒病例数。
- 建立一个模型,根据过去 k 天的冠状病毒病例数和死亡数预测第二天的冠状病毒死亡数。
虽然在对我的模型进行严格测试后,我知道 n 和 k 应该是相同的值,但当我第一次定义这个问题时,我假设 n 和 k 可以是不同的数字,以便不限制改进我的单个模型的可能性。
数据集
由于冠状病毒的增长一直是公众感兴趣的话题,而不仅仅是数据科学家或利基商业部门,因此不难找到这一话题的数据。我选择使用新冠肺炎数据库下纽约时报 Github 中的美国国家数据,因为它每天更新,而且非常容易下载。它也不包含丢失的值,所以数据预处理很简单。该数据集包含三列,分别是日期、冠状病毒病例总数和自 2020 年 1 月 21 日以来冠状病毒死亡总数。
包含我在这个项目中使用的数据集的存储库可以在这里找到,并且我从该存储库中使用的确切 csv 文件可以在这里找到。
数据预处理
一旦我们下载了我们的数据,制作一些图来理解数据是一个好习惯。通过这个简单的过程,我们可以看到我们的数据是否具有季节性,并为我们提供一些指导,说明对于这个回归问题应该考虑什么模型。让我们来看看全国冠状病毒病例和死亡人数随时间变化的曲线图。
美国冠状病毒病例和死亡时间图。
从上面的图表中我们可以看出,全国冠状病毒病例和死亡总数以不同的速度持续增加,这表明使用自回归模型是合理的。由于两个图形的形状都指示病例和死亡之间的某种关系,因为两个图形具有相似的形状,所以使用病例数和死亡数作为输入来预测下一天的病例数或死亡数是合理的。
既然我们已经决定了我们的模型将使用什么样的输入和输出,那么是时候创建那些输入和输出了。让我们来看看创建这些的代码段。
#df is a dataframe that contains a list of dates, cases, and deaths
#inputs are a list of COVID-19 cases
#outputs are a list of COVID-19 deaths
past = 5
s = (len(inputs) , past * 2)
betterinputs = np.zeros(s)
betteroutputs = np.zeros(len(inputs))
for i in range(len(inputs) - past):
temp = np.zeros(past * 2)
temp[0 : past] = inputs[i : i+ past]
temp[past:] = outputs[i : i + past]
betterinputs[i] = temp
betteroutputs[i] = inputs[i+past] #when predicting cases
#use betteroutputs[i] = outputs[i+past] when predicting deathsbetterinputs = betterinputs[0:len(df) - past]
betteroutputs = betteroutputs[0:len(df) - past]
一旦我们创建了输入和输出数组,将数据分成训练集和测试集是很重要。这种划分让我们可以测试我们的模型有多好,以及它的泛化能力有多强。让我们看看下面创建这个训练和测试分割的代码。
split = int(0.8*len(betterinputs))
X_train, X_test, y_train, y_test = betterinputs[:split], betterinputs[split:], betteroutputs[:split], betteroutputs[split:]X_train = np.expand_dims(X_train, axis=2)
X_test = np.expand_dims(X_test, axis=2)
模型
基准
既然我们已经有了可以输入到机器学习模型中的输入和输出,现在是时候开发一个基准模型作为健全性检查,以确保我们不会不必要地使事情过于复杂。我使用的基准模型是输出今天的病例数或死亡数,作为明天的病例数或死亡数的预测值。这是一个适合这项任务的基准模型,因为尽管全国冠状病毒死亡和病例的总数很大,但全国冠状病毒死亡和病例的变化相对较小。让我们看看如何创建我们的国家冠状病毒死亡人数和输出的基准模型,并可视化其准确性。
benchmark = []
for i in range(1, len(betteroutputs)):
benchmark.append(betteroutputs[i])
sum = 0
for i in range(len(betteroutputs) - 1):
sum += abs(float(betteroutputs[i]) - float(benchmark[i]))
print(sum / float(len(benchmark)))from matplotlib import pyplot as plt
plt.semilogy(benchmark, label = "benchmark")
plt.semilogy(betteroutputs , label = "betteroutputs")
plt.semilogx(inputs, label = "cases")
plt.title('model accuracy')
plt.ylabel('deaths')
plt.xlabel('cases')
plt.legend()
此图像表示上面代码段的输出。
从上图中我们可以看到,我们的简单基准模型预测的平均死亡人数非常接近病例总数的真实值。在超过 100,000 例总死亡的范围内,804.5 例死亡的平均值表明误差小于 0.8%,这通常被认为是非常好的。全国冠状病毒病例数的同一基准模型平均约为 40,000 例,这表明误差不到 2%。虽然应该有一种方法来开发更好地模拟新冠肺炎增长的模型,但这些基准模型可以用来消除其他更多参数和复杂的体系结构。
里脊回归
虽然我试图使用 Tensorflow 的序列模型和默认的内核正则化和激活函数“relu”来创建几个 MLP,以模拟全国冠状病毒死亡和病例的数量,但我的模型在大多数情况下的表现都比基准差。当我减少 MLP 的层数并最终达到一个单一的密集层时,我的模型的表现仍然比基准测试差。正是在这一点上,当我意识到 L2 正则化可能是非常有益的,我把我的模型结构转换为岭回归。L2 正则化,也称为岭惩罚,强制机器学习模型中的参数较小,因为随着参数增加,损失增加,这种正则化通常用于降低模型过拟合的可能性。一旦我更改了我的模型以包含这种正则化,我的模型的表现明显优于基准模型,尤其是在案例预测方面。让我们看看我的两个模型的训练代码。
from sklearn.linear_model import RidgeCV
model = RidgeCV(cv=2)
model.fit(X_train, y_train)
既然我的模型已经适合训练数据,现在是时候预测全国冠状病毒病例和死亡人数的测试数据。我选择通过计算冠状病毒病例和死亡的平均数来衡量我的模型的误差。下面是预测全国冠状病毒病例和死亡的测试数据的代码段,根据上述指标计算误差,并绘制预测值和实际值的比较图。
predict = model.predict(X_test)
print("{}".format(np.linalg.norm(predict - y_test, 1)/len(y_test)))plt.title("Model Accuracy")
plt.plot( days, predict, label = "predicitons")
plt.plot( days, y_test, label = "real values")
plt.xlabel("Days after First United States Coronavirus Case")
plt.ylabel("National Cases of Coronavirus")
plt.legend()
这是冠状病毒病例预测器的上述代码段的输出。
正如我们从上述代码段的输出中看到的,案例的模型预测平均只偏离真实值 2,869,这表明误差不到 0.2%,比我们的案例基准精确 10 倍,并且被普遍认为是非常好的。同一个模型输出的实际死亡人数平均误差为 489 人,误差约为 0.4%,几乎是我们死亡人数基准的两倍。
未来预测
既然我们已经使用该模型之前未见过的输入预测了冠状病毒死亡和病例,并且知道该模型可能基于其对测试数据的预测的误差而具有潜力,那么最终是时候为未来数据创建预测了。让我们看看创建输入数据的代码和对明天全国冠状病毒病例或死亡的预测。我还包括输出日期,以提供我预测结果的参考。
from datetime import date
size = (2 , past * 2)
finalInput = np.zeros(size)
temp = np.zeros(past * 2)
temp[:past] = inputs[-past:]
temp[past:] = outputs[-past:]
finalInput[0] = temp
finalInput[1] = tempfuturePrediction = model.predict(finalInput)
futurePrediction = futurePrediction[0]
print("Prediction for tomorrow's national coronavirus deaths : " + str(int(futurePrediction)))print("Today's date : " + str(date.today()))
我希望我的模型能很好地预测明天!
注意:虽然我的模型有办法提前一天以上预测全国冠状病毒病例和死亡人数(通过更改输入标签或使用第二天死亡人数和病例数的预测作为全国冠状病毒死亡人数或病例数的第二天模型的输入),但我的模型只打算提前一天预测,这样效果最好。
模型缺陷和后续步骤
虽然我的模型目前对第二天冠状病毒病例和死亡人数的预测相当好(从其测试准确性可以看出),但我的模型存在一些缺陷。首先,我的模型具有线性系数,因此很自然,我的模型对当前的线性数据预测得非常好。然而,如果全国冠状病毒病例和死亡人数没有继续呈现线性关系,我的模型可能不会那么准确,而这正是最需要像我这样的模型的时候。然而,虽然我不确定如何使用相同的架构来极大地改进这个模型,但我相信我可以尝试一些其他方法来改进我的模型:
- 我想测试使用 L2 核正则化的 MLP 是否比我的岭回归模型表现得更好;该模型还能够预测冠状病毒病例和死亡的非线性关系。
- 我想在另一个疫情上使用迁移学习开发一个模型,并将其与我的岭回归进行比较;这也将解决我当前模型只有线性系数的问题。该模型在预测未来多天的死亡和病例方面也应该更加准确,并且还可以用于模拟冠状病毒病例和死亡总数的下降。
虽然我试图开发这些模型来与我的原始模型进行比较,但我希望我现有的模型可以用作当地医疗保健系统和决策者的 24 小时规划工具。虽然我使用国家数据创建了我当前的模型,但我相信它可以很容易地使用县或州的数据进行调整,以满足某个机构的特定需求。
最后…
谢谢你一路看完博客!我很乐意听到任何关于我的分析或项目的评论。您可以在我的 github 上找到并下载我的项目的完整笔记本。
欢迎在下面留言,或者通过我的电子邮件 anaiysomalwar 和 gmail dot com 联系我。
使用机器学习个性化用户体验
如何在 TensorFlow 2 中使用神经网络预测客户意图
图片由斯蒂芬·道森拍摄
电子商务网站,比如有很多用户的店铺和平台,都是为了满足客户的需求而设计的。通常,网站对每个客户的行为都是一样的。然而,这种“一刀切”的方法并不总能满足所有情况的需要。了解顾客的意图有助于改善旅程,例如走捷径或提供建议,并使之成为更好的整体体验。本文展示了如何使用现有的客户行为数据来创建一个能够预测意图的机器学习模型。
数据保密
我个人不喜欢像谷歌和脸书这样的广告技术公司大量关注在线活动。尽管如此,我认为只要数据不被共享或链接到外部服务,个人网站可以在不侵犯隐私的情况下使用个性化技术。无论这些数据是用于改善客户体验,还是所有活动都在互联网上被追踪,以从广告中获取利润,这都有所不同。此外,任何个性化都应该是选择退出。
客户的数据之旅
通常,用户在网站上的意图可以通过查看他们过去的交互来理解。具体来说,这意味着用户留下了一系列关于其页面浏览和交互历史的事件。事件可以是用户进行搜索查询、调出文章页面或收到电子邮件。这些数据构成了使用以下技术的基础。因此,第一步是收集或提取这些数据。通常,原始数据已经存储在 web 服务器或数据库中,然后需要对其进行提炼才能使用。
举例:
三种不同的用户事件流
这张图片代表了用户到达网站的三个不同的旅程。在这种情况下,这是一个简单的网上商店,对于这个例子来说,这是一个非常简单的旅程。用户 1 可能正在寻找特定的产品,而用户 2 可能正在浏览页面,而用户 3 刚刚购买了一些东西。从一个简单的意图开始,我们希望预测用户是否会购买。
培训用数据
第一步是为每个事件分配一个事件 id,将一些相似的事件聚集到一个事件 id 中也是有用的。这可以手动完成,或者用 sci-kit learn 中的标签编码器完成。最好从 1 开始作为第一个 id,因为 0 用于填充。
我们从每个事件都是一个数字开始,我们的数据只是一系列数字。我们的分类器的输入必须有固定的大小,这意味着每个事件序列的长度必须相等。为此,我们将数据填充到预定义的长度。默认情况下,pad_sequences 用零填充缺失的事件,并在序列开始之前填充它们。如果序列比所需长度长,它会截断序列的开头。结果就是我们的 x。
import numpy as np
import tensorflow as tfnum_events = 8 # example
seq_len = 10 # example
events = [
[1, 2, 1, 2, 1], # user1
[3, 4, 2, 4, 1], # user2
[1, 5, 6, 7]] # user3
x = tf.keras.preprocessing.sequence.pad_sequences(events, seq_len)
现在我们需要找到您的 y。这高度依赖于用例,但是在这个例子中,我们将使用来自另一个系统的信息,它告诉我们客户购买了一些东西。通常这也只是一个来自上面的事件。用户 3 买了东西,所以他的目标标签是 1。
y = [0, 0, 1]
------------------
(x, y)
Output:
(array([[0, 0, 0, 0, 0, 1, 2, 1, 2, 1],
[0, 0, 0, 0, 0, 3, 4, 2, 4, 1],
[0, 0, 0, 0, 0, 0, 1, 5, 6, 7]]), [0, 0, 1])
请注意,在实际应用中,唯一事件的数量可能有数千个,整个事件流的长度通常有数百个。对于每个用户和会话,点击流中的事件数量可能会有很大不同。总有一天,我们必须裁员。确切的数字取决于数据,但 90%应该是一个很好的起点。
时间序列数据中的窗口
在预测意图的情况下,将数据划分为时间窗口是很重要的。一个窗口(X)表示时间 t0 之前的点击数据,第二个窗口表示 t0 之后的数据,这是我们预期目标事件 Y 发生的地方。与下图相比,点击数据不是一个连续的值,但窗口方法的思想是在数据中移动窗口,这也为一个用户创建了许多序列。例如,我们可以使用 6 个小时的窗口来预测客户是否会在接下来的 2 个小时内购买商品,通过浏览完整的每日数据,我们可以获得几个序列(X 和 Y)。
用于事件流建模的滑动窗口
【优步用神经网络进行时间序列极端事件预测。
然而,最重要的事情是确定,你的事件不是自我实现的预言。如果包含了一个事件,这个事件泄露了标签,那么你的模型就不是很有用(例如,包含购买预测的支付按钮点击)。没有排除哪些事件的通用规则,但是如果您的分类器在这样的任务上表现非常好,您可能有一个泄漏的特征。意图预测永远不会给你高精度的模型,因为事件数据通常不够干净和具体。
系统模型化
现在是时候将数据输入人工神经网络了。每个事件在神经网络中都有一个内部的表示,称为嵌入。这种表示在训练时由网络学习。网络学习建立一个嵌入空间,其中每个事件基于其与其他事件的相似性来定位。使用这样的表示使事件具有可比性(见单词嵌入)。此外,我们可以处理许多独特的事件,而不必处理高维向量。不同事件的数量与 NLP 中的词汇大小相对应。
在完成从事件 id 到嵌入表示的转换(嵌入层)之后,序列必须以某种方式减少到单个向量。LSTMs 是这类任务的标准方法。以下示例中的附加遮罩层从序列中移除了零。
在这个例子中,我们生成 1000 个随机示例序列,这显然会收敛到 50%的准确度,然而它显示了潜在的想法。
import randomnum_events = 1000
seq_len = 100y = np.random.choice(2, 1000, replace=True)
x = np.random.randint(num_events, size=(1000, seq_len))net_in = tf.keras.layers.Input(shape=(seq_len,))
emb = tf.keras.layers.Embedding(num_events, 8, input_length=seq_len, mask_zero=True, input_shape=(num_events,))(net_in)
mask = tf.keras.layers.Masking(mask_value=0)(emb)
lstm = tf.keras.layers.LSTM(64)(mask)
dense = tf.keras.layers.Dense(1, activation='sigmoid')(lstm)
model = tf.keras.Model(net_in, dense)
model.compile('adam', 'binary_crossentropy', metrics=['acc'])
model.summary()history = model.fit(x, y, epochs = 50, validation_split=0.2)
用卷积替换 LSTMs
近年来,卷积层在序列分类任务上也表现出良好的性能。这个想法就是用一个 1D 卷积来遍历这个序列。对于卷积网络,我们有几个“并行”卷积连接。在 Keras 中,我们可以将这种卷积序列分类应用于该模型:
import randomnum_events = 1000
seq_len = 100y = np.random.choice(2, 1000, replace=True)
x = np.random.randint(num_events, size=(1000, seq_len))net_in = tf.keras.layers.Input(shape=(seq_len,))
emb = tf.keras.layers.Embedding(num_events, 8, input_length=seq_len, mask_zero=False, input_shape=(num_events,))(net_in)
c1 = tf.keras.layers.Conv1D(256, 3)(emb)
p1 = tf.keras.layers.GlobalMaxPooling1D()(c1)
c2 = tf.keras.layers.Conv1D(128, 7)(emb)
p2 = tf.keras.layers.GlobalMaxPooling1D()(c2)
c3 = tf.keras.layers.Conv1D(64, 11)(emb)
p3 = tf.keras.layers.GlobalMaxPooling1D()(c3)
c4 = tf.keras.layers.Conv1D(64, 15)(emb)
p4 = tf.keras.layers.GlobalAveragePooling1D()(c4)
c5 = tf.keras.layers.Conv1D(64, 19)(emb)
p5 = tf.keras.layers.GlobalAveragePooling1D()(c5)
c = tf.keras.layers.concatenate([p1, p2, p3, p4, p5])
bn = tf.keras.layers.BatchNormalization()(c)
dense = tf.keras.layers.Dense(128, activation='relu')(bn)
out = tf.keras.layers.Dense(1, activation='sigmoid')(dense)model = tf.keras.Model(net_in, out)
model.compile('adam', 'binary_crossentropy', metrics=['acc'])
model.summary()history = model.fit(x, y, epochs = 50, validation_split=0.2)
真实数据的结果
我使用的数据集是大约 1300 万个事件流,通过滑动窗口方法导出,类不平衡大约是 1:100。不幸的是,我不能分享数据集,只能分享结果。
不过,根据这些数据,可以将 LSTMs 与 Conv1D 架构进行比较。事实证明,CNN 的方法在许多方面都优于 LSTMS。首先,卷积的计算速度更快,因此它的训练速度更快。LSTMs 对超参数更敏感,因此,模型通过卷积变得更稳健,此外,甚至精度也略有增加。在下面显示的分类器的特征中,在精确度/召回率上有显著的差异,在 ROC 曲线上有轻微的差异。因此,我建议使用 CNN 的方法。
实验的 AUC 和精确召回曲线
小费和技巧
在现实中,数据并不完美,我们经常会有重复的事件、爬虫和机器人或其他噪音。在开始对序列进行分类之前,请确保您的数据是正确的。过滤掉离群值。合并重复事件,并按有意义的不活动时间分割用户的会话。你也可以在模型中引入时间(例如,在嵌入向量的顶部放置类似“自上次事件以来的时间”的东西)。不仅可以使用最大序列长度,还可以使用最小序列长度。如果目标事件非常罕见,负序列的欠采样是一种选择。
本帖首发此处。