如何用机器学习改善假期行程
用这个超棒的策略完善你的旅行计划——省时、省力、省钱!
希腊圣托里尼岛的 Oia【图片由洪晶
【2019 年 10 月,我和我的朋友们正在计划我们在希腊和阿马尔菲的史诗假期。我们计划完美假期行程的方式是使用谷歌地图。我们搜索要去的地方,并在谷歌地图上标出我们可能感兴趣的景点。
对我来说,最大限度地优化我们的假期,尽可能多地去旅行;我有三个问题:
- 我应该在一个地方呆几天?
- 我每天应该去哪些景点/地点?
- 从一个地方到另一个地方的最佳路线是什么?
让我给你看看我的算法为我们提出的路线。它每天都在推荐最佳的旅游地点。
从雅典、圣托里尼和克里特岛开始,然后是阿马尔菲、拉韦洛、索伦托和那不勒斯。
- 从雅典出发,参观雅典卫城和其他历史古迹。这是一个很好的开始!
- 前往圣托里尼岛(Santorini)旅行,这是一个美丽的岛屿,有粉刷一新的房屋和完美的日落。
- 航行到克里特岛,进行一生一次的公路旅行冒险,探索隐蔽的角落,品尝最好的希腊美食。
- 飞往意大利,前往阿马尔菲和拉韦洛,那里的梯田沿着悬崖与最壮观的海岸风景融为一体。
- 前往索伦托和那不勒斯,尽情享用最好的意大利面、披萨、柠檬酒和冰淇淋。
很棒的假期行程,不是吗?!这个位置序列完全由算法生成。你想在下一个假期试试这个吗?我已经为你准备好了的代码。
在这篇文章中,我将向你展示如何在你的下一个假期中做到这一点。
在前往拉韦洛的徒步旅行中,阿特拉尼的日出景色
准备
P **在谷歌地图上的位置。**访问我的地图,为您的下一个度假目的地创建新地图。寻找你想去的地方。景点?主题公园?餐馆?通过搜索这些地方并用标记填满您的地图,然后“添加到地图”。继续这样做,直到你在地图上找到所有你想去的地方。我会等你。
E **导出地图并上传至 Colab。**经过研究和确定要去的地方的艰苦工作后,我们准备导出地图。选择“出口到 KML/KMZ ”,记得勾选“出口为 KML ”。你将下载一个 KML 文件。
接下来进入 Colab ,一个由 Google 维护的优秀笔记本环境。打开左边的文件抽屉,上传你下载的 KML 文件。稍后我们将加载这个带有 BeautifulSoup 的 KML 文件。
Get Google API 键。我们将在谷歌地图上绘制标记,所以我们需要一个 API 键。你可以从开发者 API 页面获取。按照说明操作,您应该会得到一个如下所示的密钥:
ZIzkSyDwhp5B0_3eLYmPLY_tH1$Is@fAkeAp1keY
Psst:这是一个假的 API 密匙🙃
意大利阿马尔菲【图片来自英
Colab 上的代码演练
你可以获取代码并在 Colab 上运行它。
D定义参数。让我们为你期待已久的假期设置 API 键、KML 文件名和期望天数。
API 键用于在 Colab 上绘制交互式谷歌地图。KML 文件包含您在谷歌地图上标注的名胜。最后,算法会根据你设定的天数来决定你每天应该去哪里。
在 Colab 上定义参数代码
L oad 数据。 KML 文件是 XML,我们可以用 BeautifulSoup 解析它。我们感兴趣的地方在“地标标签内,所以我们将从每个“地标”中提取“名称”和“坐标”。
让我们看看数据框中是否包含我们计划去的地方。
G **按接近程度分组位置。**利用数据帧中每个位置的坐标,我们可以将它们分组。如果两个地方彼此靠近,它们将在同一个集群中。聚类有几种方法,我将介绍 K-Means、谱和均值漂移聚类。
K-Means 聚类 旨在将数据点划分成指定数量的簇。其中每个数据点属于它最接近的聚类。
谱聚类 在单个聚类的结构高度非凸的时候很有用。它先执行降维,然后在更少的维度上进行聚类。
均值漂移聚类 是一种基于质心的算法,旨在发现平滑密度的数据点中的斑点。它的工作原理是将候选质心更新为区域内点的平均值。
我最后用的是哪一个?K-表示。因为它很简单,也是最常见的一种。但是你可以随意选择你喜欢的,这三个我都试过了。你也可以开发自己的并与我分享。
P在谷歌地图上拍吧!现在,我们准备在谷歌地图上绘制出 12 个主要区域(因为我们计划度假 12 天)。如果你在 Colab 上运行这个,这个地图是交互式的。
左图:雅典。中间:圣托里尼岛和克里特岛。右图:阿马尔菲和那不勒斯。
聚类算法在按邻近程度分组位置方面做得很好。接下来,我对找出从一个地区到另一个地区的最佳路线感兴趣。
找到每个集群的中间。我们可以用熊猫函数:places.groupby(‘cluster’).mean()
来做到这一点。这将为我们提供一个数据框架,其中每一行代表一组位置,以及经度和纬度。
F查找集群之间的距离。我们可以使用每个聚类的中点,用 Scipy cdist
函数计算聚类之间的距离。
这将为我们提供一个数据框架,显示每个星团与其他星团之间的距离。让我们称这个矩阵为距离矩阵,其中每个值代表两个簇之间的距离。较小的值意味着两个集群彼此更接近。
找到最短的路线。有了这个距离矩阵,我们就可以找到最短的路径了。下面是计算最短路径的代码。
最初,我使用的是旅行推销员算法,但是我发现代码的有点矫枉过正和过于复杂,所以我自己写了。这是基于最短路径算法的结果,一个簇到一个簇的序列。
2 -> 1 -> 6 -> 10 -> 9 -> 3 -> 11 -> 7 -> 4 -> 5 -> 8 -> 0
S 如何推荐行程。现在我们准备在谷歌地图上标出我们的标记。它推荐我们从雅典、圣托里尼和克里特出发。然后到阿马尔菲、拉韦洛、索伦托和那不勒斯。如果你在 Colab 上运行这个,这个地图是交互式的。
从雅典、圣托里尼岛开始,然后是克里特岛。去阿马尔菲,拉韦洛,索伦托和那不勒斯。
如果你喜欢看表格形式的,你可以用熊猫来展示。
pd.set_option(‘display.max_rows’, None)
places.sort_values(by=[‘days’])
希腊圣托里尼岛的 Oia【照片由 Clement Lim 拍摄】
有哪些可以改进的地方?
该算法不考虑一个区域中景点的数量。例如,我们绝对不想在一天之内探索雅典的一切!仅仅在圣托里尼呆一天是不够的。
我们需要一种聚类算法来限制一个聚类中的最大点数。使得每个集群应该具有大约相同数量的位置。如果一个集群变得过于密集,它会将该集群分成两个或更多个集群。如果你有,一定要和我分享。🤝
但是如果你在一个城市旅行,结果可能是有希望的。这是为纽约市生成的路线。随意下载我的行程自己试试。
纽约市
纽约市的日落,从洛克斐勒中心的岩石顶端[照片由洪晶 ]
资源
你想在你的下一个假期尝试这个吗?这里是代码。*不客气。*😉
如果你喜欢这件作品,你可能也会喜欢这件。
用电影海报确定电影的类型和收益
towardsdatascience.com](/predict-movie-earnings-with-posters-786e9fd82bdc) [## 数据科学家:21 世纪最肮脏的工作
40%的吸尘器,40%的看门人,20%的算命师。
towardsdatascience.com](/data-scientist-the-dirtiest-job-of-the-21st-century-7f0c8215e845)
不确定去希腊或者阿马尔菲哪里玩?继续使用我们的希腊 x 阿马尔菲旅程。
不确定在纽约市去哪里玩?
感谢阅读。😃
希望你能像我准备这篇文章时一样喜欢它。
如何提高体育博彩赔率 Python 中的分步指南
我用数据科学策略在体育上赌了 20,000 美元。
来源:突发
W 当我还是一名学习统计学的学生时,我尝试过用数据科学技术进行体育博彩。通过这样做,我在那一年从体育博彩中获利 20,000 美元。
体育博彩可能不仅仅是利用你的直觉。通过增加适当的数据分析和预测模型,你可以有更大的胜算。
本指南将向你展示使用 Python 的一步一步的算法,以及更多的技巧。
让我们开始吧!
来源:giphy.com
传统方法
首先,让我们回顾一下体育网站上的传统统计数据。
想象今天是本赛季的最后一场比赛。A 队要面对 c 队了,你觉得哪个队夺冠的胜算更大?你会把赌注压在谁身上?
以下是甲队和丙队的季后赛记录。
像 NHL.com 这样的体育网站经常提供这样的统计数据:
W —总赢数,L —总输数,T —总平手数
传统的球队排名方法是看输赢百分比,也就是赢的比赛占总比赛的百分比。在这种情况下,A 队将与 C 队打成平手,因为他们都有相同的 50%的胜率。
但当你仔细观察比赛数据时,C 队击败 B 队(7–0)的次数多于 A 队击败 B 队(1–0)的次数。所以 C 队这次打败 A 队的几率应该比较大。
当游戏数量很少时,研究每个结果是很容易的。但是当有很多球队和比赛的时候,我们需要一个系统的方法来分析数据。
我们如何整合过去比赛中的进球差异等细节,以获得更好的球队排名?
如果决赛在 A 队的主场进行呢?主队通常比客队受益。有了这条额外的信息,你觉得现在哪个队胜算更大?
我们如何在评估游戏时融入主场优势?
统计方法—逐步
为了回答上面的问题,我们使用 NHL 数据(从曲棍球参考网站下载)建立了一个统计模型。你也可以为其他运动进行修改。
来源:曲棍球参考
用于模拟评级的算法被称为调整后的正/负评级系统。你可以在这里阅读系统的详细描述。或者按照下面的三个步骤来实现它。
步骤#1:加载数据
- 下载 CSV 格式的数据
该数据有 640 行,包括 2019 年 10 月 2 日至 2020 年 1 月 3 日之间的比赛结果。它有五个变量— 日期、访问者、访问者 _ 目标、住宅和住宅 _ 目标。
例如,下面的行记录了 2019 年 12 月 6 日的比赛。蒙特利尔加拿大人队(客队)和纽约流浪者队(主队)比赛,最终比分是 2 比 1。
- 将数据读入 Python
步骤# 2:转换数据
- 添加新功能
首先,我们创建 goal_difference 变量作为 home_goals 和 visitor_goals 之间的差异。当主队获胜时大于 0,当主队失败时小于 0,当两队打平时为 0。
我们还增加了两个指标 home_win 和 home_loss 来考虑主场优势对球队的影响。
数据看起来像这样:
- 转换数据
接下来,我们创建两个虚拟变量矩阵 df_visitor 和 df_home 来记录客队和主队。
df_visitor 的头是这样的:
这是一个矩阵,以球队名称为列,每场比赛的客队虚拟变量为行。行 0 具有值为 1 的列 Vancouver Canucks 和值为 0 的其他列。它显示了在这场比赛中客队是温哥华加人队。
df_home 矩阵具有类似的结构,但是指示相应游戏中的主队。
接下来,我们进一步转换这两个矩阵,以成为最终的数据集。
- 合并之前的结果以获得最终数据集
我们从 df_home 中减去 df_visitor,得到最终的数据集叫做 df_model 。df_model 的每一行都显示客队的值为-1,而主队的值为 1。
此外,我们从原始数据集 df 添加回变量 goal_difference。
最终数据集 df_model 如下所示:
例如,第 4 行说阿纳海姆鸭队(主队)对阵亚利桑那狼队(客队)。而阿纳海姆鸭队(主队)以一球的优势赢得了比赛。
通过这种方式,最终数据集包括关于目标差异和主场优势因素的信息。
现在我们准备将数据输入到模型中!
步骤# 3:建立预测模型
我们用岭回归模型作为演示。
这是一个线性回归模型,增加了一项作为惩罚。由于自变量之间的多重共线性,传统的线性回归不能产生稳定的结果。
- 拟合岭回归模型
我们使用 goal_difference 特性作为目标变量。
- 显示结果
让我们打印模型的系数。
结果如下:
每个团队的这些系数可以被认为是对每个团队的评级。
系数/等级越高,队伍越强。
根据这个模型,科罗拉多雪崩队是收视率最高的最佳球队。我最喜欢的多伦多枫叶队也被模特评为优秀团队!
来源:giphy.com
你做到了!
也就是说,在将这种算法应用于体育博彩之前,让我们考虑几件其他事情。
这种方法与传统方法相比如何?
统计方法似乎比传统方法更复杂。但是性能如何比较?
让我们看看另外三种常规方法:
方法#1:输赢百分比
正如我们在本文前面部分所讨论的,这是一个经常出现在体育网站上的基本统计数据。对于每个特定的团队,输赢百分比=赢的游戏总数/玩的游戏总数。
方法二:主队获胜
正如这个方法的名字所暗示的,它是一个总是选择主队获胜的赌注。
方法 3:利用主场优势净胜球
这是一个复杂的方法,包含了关于净胜球和主场优势的信息。
然而,当提出团队评级时,它并不考虑团队对手的实力。岭回归的方法会考虑这一点,因为它把所有的球队和所有的比赛放在一起看。
*** 如果你讨厌公式,跳过这些 ***
首先,对于每个特定的团队*、*,我们计算:
球队每场净胜球=(球队进球-球队允许进球)/(球队出场场次)
接下来,我们使用所有过去的比赛结果来获得一个关于该队所有主场优势的统计数据:
主场优势净胜球=(所有主队进球-所有客队进球)/(所有球队比赛场次)
有了这些统计数据,我们可以预测主队或客队是否会赢得某场比赛。
再次使用开头的例子。A 队(主队)将和 C 队(客队)比赛。我们使用下面的统计数据来预测结果:
*Margin =*A 队场均净胜球——C 队场均净胜球+主场优势净胜球
如果 Margin > 0,那么我们赌 A 队(主队)赢。如果余量< 0, we choose Team C (the visiting team).
To compare these methods, we use 交叉验证进行评估。
我们的统计模型是赢家!
它预测曲棍球比赛结果的准确率高达 60%!
但是,在赛季的初始阶段,最好依靠其他指标。因为模型的结果只会随着赛季的进行(当有更多的数据可用时)而改进,变得比其他方法更好。
还有哪些可以进一步改善结果的技巧?
当然,我们的预测结果仍有改进的余地。
提示 1:考虑团队最近几天的日程安排
考虑到球队最近的赛程,你可以增加一些变数。在过去的几天里,球队有没有打比赛或者休息?团队是否经常外出旅行?
技巧 2:权衡游戏结果
球队的情况总是随着赛季的变化而变化。所以最近的比赛应该比早期的比赛更有知识性。为此增加一个指标会有所帮助。
技巧 3:使用不同的模型
我们以岭回归模型为例。然而,为了获得更好的结果,您可以测试并结合其他机器学习/统计模型,如神经网络、 GBM 。
技巧 4:加入你自己的判断
这些模型不能包含所有的信息。作为一个有经验的体育迷,你必须有宝贵的知识。结合统计方法和你的经验对于做出更好的预测是至关重要的。
体育博彩是一种在娱乐的同时练习数据科学技能的绝佳方式。
在芯片掉落前拟合模型!
祝大家好运!
来源:giphy.com
感谢您的阅读。我希望你发现这个体育博彩指南有帮助。
现在我想听听你要说什么。请随时在下面留下你的评论。
更多来自 Lianne & Justin 的数据科学文章:
应用 Elo 评级系统预测 UFC 246
towardsdatascience.com](/spoiler-alert-conor-mcgregor-vs-cowboy-who-will-win-7c3eee6389b0) [## 根据模拟,30 岁退休需要多少钱
很多人年纪轻轻就有辞掉工作的梦想,活在世上没有经济上的牵挂。怎么…
towardsdatascience.com](/how-much-do-you-need-to-retire-at-age-30-based-on-simulation-424fa9e0922b) [## 如何像老板一样在 Python 中操纵日期和时间
常用的日期时间函数及示例
towardsdatascience.com](/how-to-manipulate-date-and-time-in-python-like-a-boss-ddea677c6a4d)
如何通过采用 Levenshtein 距离的后处理来提高机器学习模型的性能
用作度量的 Levenshtein 距离通过验证条目中的每个命名实体来提高 NLP 模型的准确性
我目前正在开发一个 NLP 解决方案,用于匹配不同领域(广播、电视、音乐会)的音乐使用报告,以便正确分配音乐创作者的版税。对已经在音乐作品和版权所有者的数据库中使用的一段音乐的正确匹配的搜索是通过对文本进行矢量化并对最相似的向量进行向量搜索来完成的。(我可能稍后会写这部分解决方案)
矢量搜索解决方案做得很好,找到了由矢量化定义的最相似的条目。然而,这个用例也有一些非常具体的需求需要满足,以确保版税分配给正确的个人。这些要求中的一些可以通过简单的逻辑将报告与匹配的音乐作品进行比较来检查。在匹配可以被批准之前,必须进行检查,例如计算权利所有者的数量是否相同,出版商是否相同。此外,我们必须验证每个权利所有者都是高度可能的匹配。这比听起来要复杂一点,因为我们无法控制这些名字在数据集中的书写方式。可以先写姓,后写姓,或者相反的顺序。可以有缩写,昵称,拼写错误和错别字。如果我们需要一个字对一个字的精确匹配,我们将丢弃大部分建议的匹配,这些匹配实际上是正确的。“弗雷德里克·约翰逊”在报告中可能会拼成“约翰逊·弗雷德”。所以直接检查相同的文本是行不通的。此外,单词袋的比较也不会令人满意,因为单词本身在许多情况下并不相同。
那么,我们该怎么做呢?检查的要求是相似的名字应该被批准,而太不相似的名字应该被标记为不是同一个人,并且报告的音乐作品和登记的作品之间的匹配不应该被批准。
潜在匹配的示例,所有这些条目都有一个共同的标题。只有 1 和 2 可作为匹配被接受,因为作曲者和出版商是相同的,即使作曲者姓名的拼写不同。3 和 4 不应该被批准,因为它们的出版商是不同的,即使作曲者是相同的。
字符串之间差异的度量是编辑距离或 Levenshtein 距离(以苏联数学家 Vladimir Levenshtein 的名字命名)。简而言之,编辑距离是我们必须对一个字符串进行多少次更改才能将其转换为我们要比较的字符串的度量。举例来说," Frederic “和” Fred “之间的差别是 4,因为我们可以把” Frederic “改成” Fred “,去掉字母” e “、” r “、” I “和” c "。
总共需要 4 次编辑才能将“骆驼”变成“甜瓜”
使用 Levenshtein 距离作为度量并为 Levenshtein 距离设置阈值的一个挑战是,它的值只对差异的数量敏感,而对被比较的字符串的长度不敏感。例如,“波诺”和“邦·乔维”可以说是非常糟糕的匹配,具有 4 的编辑距离,而“埃尔顿·赫拉克勒斯·约翰爵士”和“埃尔顿·约翰爵士”具有 9 的编辑距离。直接使用 Levenshtein 距离进行比较显然不会有很好的效果。然而,如果我们通过除以两个字符串中最长的一个来“标准化”这一点,我们将获得一个相似性度量,这对于比较来说要方便得多。
当比较名字时,我们必须考虑到包含名字的字符串中单词的顺序可以是任意的,因为有不同的约定。为了避免将“John Smith”判断为与“Smith,John”完全不同的名字,我们需要对每个字符串中的单词进行排序,以相同的方式进行比较。最简单的方法是按字母顺序排列字符串中的标记。按字母顺序排列标记后,不同的约定将不再是比较的问题。
在可用的数据中,报告名称的顺序是任意的,那么我们如何知道应该比较哪些字符串呢?事实上,我们永远无法确切知道,但这个问题的解决是相当顺利的。如果我们计算报道的姓名和来自匹配作品的姓名之间的所有可能匹配之间的 Levenshtein 距离,我们可以建立匹配矩阵。
从这里开始,很容易找到最佳匹配=最高分,然后通过屏蔽最高分的行和列从比较中删除匹配的名称。重复,直到矩阵中只剩下一个分数。这是示例中得分最低的字符串比较,因为我们已经确保从要比较的名称中选择了可能的最佳匹配。这将是我们需要考虑的分数,以决定比赛是否可以通过。
消除与集合中的最佳匹配相对应的分数的步骤,直到我们剩下一个活动分数来评估。最佳匹配以绿色突出显示。
现在我们只剩下一个数字要评估,以决定是否可以批准这个匹配,所以最后要决定的是如何设置阈值。由于这是针对特定问题的定制解决方案,因此我从系统用户那里获得了如下要求:
- 不接受虚假批准
- 应该允许省略中间名
- 应该允许其中一个名称的缩写
当然,在某个地方会有一个折衷,但是与用户讨论后处理步骤给了我一些非常重要的理解。因为我们的目标是自动化,所以不批准任何实际上不匹配的东西是最重要的。如果我们错过了一些可以被认可的比赛,这不是什么大问题。如果我们对所做的匹配有很高的信心,我们可以建立对系统的信任,并通过系统自动传递所有批准的匹配,从而节省大量劳动力。
为了给 Levenshtein 测量找到一个好的阈值,我收集了一个小样本的名字和它们的替代拼写,缺少中间名和缩写,并计算了它们的归一化 Levenshtein 距离,并使用这些来设置一个合理的阈值。我发现对于我的情况,0.5 是一个很好的阈值,其中一个缺少的名字或一个缩写的名字通常会允许匹配被批准,但是如果,例如,我们在相同的名字中有一个缺少的中间名和一个缩写,匹配通常不会被批准。
当归一化时,Levenshtein 距离可以有效地用于验证机器学习结果中列出的专有名称之间的匹配。对每个列出的名称进行额外的验证,即使是一个无序的列表,也能增强对结果的信心,实现查找过程的自动化。
关于我
我是梅塔咨询公司的数据科学家。专注于应用数据科学、人工智能,尤其是 NLP。
优步的机器学习让我失望
实时对抗优步黑客&给优步的建议
克林特·帕特森在 Unsplash 上拍摄的照片
TL;博士——在 6 个多小时里,我看着有人入侵了我的优步账户,并实时消费了 1000 多美元。优步的先进和著名的技术和 ML 解决方案在活动期间和之后都失败了。在这篇文章中,我回顾了我的经历,并提供了三组浅显的建议。对于数据科学家来说,这是一个很好的提醒:当遇到混乱的世界时,ML 可能会失败。
目录:
- 语境
- 如何修复全渠道客服
- 如何简化混合欺诈检测工作流程和算法
- 如何保护多目标和基于图的推荐系统
免责声明:所有观点都是我的,不代表我雇主的观点。
喜欢读什么? 跟我上 中LinkedIn,以及*Twitter*。**
从天堂到地狱的短暂旅程
尽管是新冠肺炎,但和许多人一样,我和我的狗决定冒险享受 2020 年 5 月 3 日的天气。多伦多海滨是一个天堂。
遛狗,作者照片
**
多伦多海滨的早晨和下午,作者自己的照片
当我们走向水边时,我的电话响了。是 UberEat 的通知。看来我妻子晚餐点了披萨。虽然比萨饼不是我们最喜欢的菜,但我太沉迷于对海滨的怀旧记忆了。
我把手机塞进口袋,开始带着我的狗向水边慢跑。与此同时,我的电话一直在响。
十分钟后,我再次看手机时陷入了地狱。时间停止了:笑声减弱了;太阳的温暖冻结了;我的狗消失了;短暂的自由消失了。
不可能的。有人黑了我的优步账户,即使有双因素验证*。最糟糕(也是最有趣)的部分:我可以像观看直播一样观看。***
作者手机截图,拍摄于 2020 年 5 月 3 日
困惑,害怕,孤独。一个新的通知不断传来:“杰森说谢谢你的提示!”
我发出了无声的沮丧和求助的呼喊。
吉菲
我深深吸了一口春天的新鲜空气。沉稳。我应该修改我的密码并注销黑客。预料到我歇斯底里的干扰,黑客改变了我的密码,把我锁在外面。我又慌了。
崩溃了。看起来唯一的选择是联系优步的客户服务。
与此同时,每份超过 100 美元的新 UberEat 订单的通知以及来自餐馆和司机的感谢不断涌入——我无法停止想象黑客嘲笑的脸。
问题和建议
我毫不怀疑优步(或万事达)会退款,他们最终也退款了。然而,这个过程既漫长又令人困惑。后果令人非常尴尬。
总的来说,考虑到优步的技术进步,这是一个令人不快的惊喜。
回想起来,我看到了三个问题:
- 优步的客户服务不够无缝和“智能”。
- 优步的欺诈检测解决方案太慢了。
- 优步的推荐引擎并不那么感同身受。
让我强调这些问题是有规律的,但是有爱心的,用户和作为有爱心的数据的极客 T21 提供一些建议。
1.客户服务
出现问题时,客户服务是第一联系点。这是所有公司中最关键、最复杂、最具挑战性的运营——优步也不例外。
A .手机 app 上没有客服。
UberEat app 截图,拍摄于 2020 年 5 月 10 日
在优步的帮助下很难找到合适的支持者。
优步求助网站截图,拍摄于 2020 年 5 月 10 日
来自其他渠道的缓慢且不连续的响应。
作者于 2020 年 5 月 10 日在脸书 Messager 上与 UberEat 的聊天记录截图
与此同时,我焦急地阅读了优步帮助上的选项,并在“我有一个未知的费用”下提交了一个请求这似乎是最相关的。
D .令人困惑的电子邮件支持。
邮件往来截图,作者拍摄于 2020 年 5 月 10 日
对客户服务的建议
以下是我改善优步客服体验的实用建议。
- 在 app 登陆页面添加客服移动界面。用户不需要登录就可以使用这个特性。
- 改进优步帮助上的内容标记。“黑客”或“欺诈”可能是低频搜索词,但它们具有紧迫性和巨大的财务影响。要求用户手动检查每个选项似乎不合理。
- ***(或许)连接通道。*共享代表从非网络渠道对集中式用户信息和案例管理系统的访问。我不是 100%确定为什么脸书·梅桑格的优步代表找不到我的资料,并且花了很长时间才回复。我猜脸书频道不打算解决这样的问题。因此,它缺乏系统集成、培训和能力。
- 改进模板化邮件回复。以下是模板回复,以确认我报告的欺诈交易确实属于我的帐户。等等。什么?这有什么帮助?
回复截图,捕捉于 2020 年 5 月 10 日
我又提出了三个请求,又花了七个小时才弄明白我需要做些什么不同:我必须用优步文件上的同一个电子邮件地址提交请求和回复。优步本可以发送更明确的电子邮件指示或使用个人回复。如果设计不当,自动化会以牺牲用户的时间为代价来节省优步的时间。
2.欺诈检测系统
我长期关注优步工程博客。不断的技术突破和创新概念总是令人惊叹。
根据优步的博客,该公司收集 GPS 数据,并使用最先进的混合工作流、行为分析和深度学习模型(行为特征被编码到 LSTM 模型中)。
注 :这是针对优步乘车的解决方案,而不是针对 UberEats。我假设解决方案的许多组件是共享的。
基于 GPS 的欺骗检测,优步工程博客
优步的欺诈检测工作流程,优步工程博客
行为分析,优步工程博客
LSTM 编码和模型,优步工程博客
然而,即使没有我的干预,一家低技术含量的加拿大银行也能在一半的时间里发现并纠正欺诈行为。我不能停下来想为什么。是不是工程过度了?
对优步欺诈检测的建议
除了花哨的工程设计,我们都应该同意一件事:检测和应对欺诈应该快速有效。否则,对所有参与者来说成本都更高(例如,用户的时间和信心、公司的运营努力和声誉)。
我对优步的建议是保持简单和愚蠢(接吻原则)并牢记 80/20 原则 。
根据我为低技术银行设计和部署欺诈引擎的经验,基于规则的引擎往往比复杂的洗钱解决方案更好用,原因有二:a)简单的解决方案往往更快、更容易更新(KISS ); b)一小组规则通常可以捕获大多数欺诈案例(80/20 原则)
一些欺诈者可能很老练。因此,必须有一个更新规则的过程。优步可以通过每月或每季度回顾遗漏的案例来做到这一点。然后,团队可以相应地更新规则。
看看我的案例,下面是我对一个基于规则的解决方案的谦逊和天真的建议,它分析了优步秩序的三个基本方面。
作者的分析
订单位置有意义吗?
- 订单是否送达用户所在城市?
- 用户经常出差吗?
- 用户不在的时候会点 UberEat 吗?
我住在多伦多,我去过几次旅行,但是我从来没有在我主要居住地以外的城市点过 UberEat。黑客发出的所有命令都在我的家乡城市之外。所以,不,我的位置说不通。
用户偏好背景下的食物有意义吗?
- 用户是探索型的吗?(例如,不同菜肴的数量、相对于其他用户的排名等。)
- 食物是否符合用户的喜好?(例如,菜肴、平均订单规模等。)
***举例:*我不是探索型的;我通常在多伦多我家附近的 4-6 家餐馆点日本和韩国食物。我的平均订单大小约为 30-40 加元,黑客的平均订单大小为 108 美元。所以,不,食物细节说不通。
用户是否在做一些奇怪的事情?
- 用户是否在短时间内下单过多?(查看用户的平均订购频率)
- 用户是否在可疑地点下单?(检查到用户主要城市的餐馆和送货地点、最后 X 个订单中不同城市的数量等。)
***例如:*我一个月通常订购 1-2 次,黑客在 5 个小时内订购了 11 次(每月约 1650 个订单)。黑客从至少 5 个美国城市的餐馆点餐,这些城市相距数千英里。所以,是的,用户显然在做一些奇怪的事情。
最后,这个分析能在近实时的时间内完成吗,比如 30-60 分钟,这样我就不用被黑客折磨 6 个小时了。许多计算都很简单,它们不需要很长时间来收集足够的数据来做出决策,并且与基于 ML 的方法相比,它不需要大量的训练数据和很长的推理时间。
在看到优步推送表扬通知和反馈请求的速度后,我确信优步可以将这一技术发挥巨大作用!
作者手机截图,拍摄于 2020 年 5 月 10 日
尽管这次的支持经历很糟糕,但我对优步的工程团队充满信心,相信他们会做得更好。
3.不那么感同身受的提醒
自黑客事件以来,优步的推荐算法继续发挥着它的魔力:它在完美的时机发送通知和建议来满足我的胃口,只是这些建议都是基于黑客的品味,而不是我的。
过去两周的电子邮件和移动推荐,作者截图
*最近两周收到的每一个 UberEat 推荐**都让我觉得尴尬和沮丧。*就好像黑客从来没有放过我,他(或她)不祥的存在依然在每一个频道,每时每刻萦绕着我。
由于我的专业经验和兴趣,优步的推荐设计和实现是我在优步工程博客上的最爱。创新的想法、创意的设计和清晰的解释总是给我留下深刻的印象。
下图描述了 UberEat 推荐引擎的核心组件和流程。
多目标推荐设计,优步的工程博客
基于图形的推荐系统,优步的工程博客
图-学习方程,优步工程博客
基于图的推荐器的损失函数,优步工程博客
基于图的推荐系统的工作流设计,优步工程博客
但是,抛开所有抽象的想法和复杂的设计,一些简单的东西似乎不见了。
对优步保荐制度的几点建议
- ***添加或更新数据验证标准。*通过将此添加到数据管道,步骤 1 可以从训练和/或推断中移除坏数据。优步应该把我的记录贴上例外的标签,把它们从军情六处的管道里移走。
- ***调整模型训练和验证中的总预订权重。*我使用 UberEat 已经三年多了。优步的建议是“正常的”但黑客入侵后一切都关闭了。这表明该模型对某些特征特别敏感。我相信总预订量(例如,根据工程博客文章所述,食客和餐厅之间的订单金额)可能会影响模型。黑客在所有的餐馆下了大订单(100 多美元,而我正常的订单是 30 美元)。
- 新增或更新保障业务逻辑。在我讨论人工智能最后一英里问题的文章中,我强烈建议企业在推理和服务之间建立一个业务逻辑层。这样做有助于避免像我这样的情况,即建议没有意义(例如地点和口味)。我们应该也能够在帮助用户探索使用 ML 和不无关(或错误)之间取得平衡。
- ***启用用户驱动的推荐。*目前,我没有办法改变优步的建议,除了不点击任何建议。我希望这样做将有助于系统的自我纠正。哦,等等,我确实打开了邮件或者点击了通知。我希望这不是他们对“成功建议”的定义如果这样,我就会陷入恶性循环。我强烈主张提供一个用户界面,让用户积极参与推荐过程。这是我的文章,提供了一个解决方案(这是一个不同的问题,但机制仍然适用)
最后的话
优步,你是一家伟大的公司。你们的成功故事和技术创新鼓舞了我和许多其他人。真心希望我的经历不会发生在其他用户身上。
随着我们适应新常态,我相信您的服务将成为许多行业和我们生活许多方面的核心组成部分。保持下去。
如果你们中的任何人看到了这篇文章,请将这篇文章转发给正确的团队。
喜欢读什么? 跟我上 中 , 领英 , 推特 。查看我的《 用机器学习影响 》指南。它帮助数据科学家更好地解决问题、设计和交流。
您可能也会喜欢这些文章:
数据科学家的 4 个现实职业选择
towardsdatascience.com](/the-most-realistic-data-science-career-guide-d12c4af87cc8) [## 下一个最佳数据科学工作
数据科学家最受欢迎的过渡路线
towardsdatascience.com](/the-best-data-science-transition-routes-e809254934d0) [## 最有用的 ML 工具 2020
每个懒惰的全栈数据科学家都应该使用的 5 套工具
towardsdatascience.com](/the-most-useful-ml-tools-2020-e41b54061c58) [## 被遗忘的算法
用 Streamlit 探索蒙特卡罗模拟
towardsdatascience.com](/how-to-design-monte-carlo-simulation-138e9214910a) [## 12 小时 ML 挑战
如何使用 Streamlit 和 DevOps 工具构建和部署 ML 应用程序
towardsdatascience.com](/build-full-stack-ml-12-hours-50c310fedd51) [## 数据科学很无聊
我如何应对部署机器学习的无聊日子
towardsdatascience.com](/data-science-is-boring-1d43473e353e) [## ML 和敏捷注定的联姻
如何不对 ML 项目应用敏捷
towardsdatascience.com](/a-doomed-marriage-of-ml-and-agile-b91b95b37e35)*
如何使用位置分析提高用户获取和转化
地理空间分析和洞察
对于“位置”至关重要的基于 app 的交付+物流+移动公司。
一家基于应用程序的送货公司可以随时将用户通过应用程序订购的任何东西送到用户的位置。按需公司,如食品配送公司、电子商务公司等供应链公司、超本地配送公司和移动公司都属于这一类别。
所有这些公司都有一个共同点:它们都在地面上运营和移动资产。因此,位置作为一个包含在策略和决策中的参数变得非常重要。
但是,我们如何利用位置分析来增加用户的获取、转化和保留呢?信不信由你,关于这些指标的地理模式可以告诉我们很多关于我们的业务和用户的信息。例如:
不是每个安装你的应用的人都使用它或者打开你的应用订单。在这种情况下,是否存在客户流失密度非常高的位置?
在这篇文章中,我们将讨论如何使用位置分析来了解如何提高我们的用户获取、转化和保留。
资料来源:优步
案例 1:用户获取
在已经有需求的地方获取用户将有助于我们降低 CAC(客户获取成本)。因此,在选择下一个扩张地点时,一个很好的问题是:
在应用程序安装、搜索、订单等方面,我已经看到很多潜在需求的位置在哪里??
我们可以利用这种洞察力来决定我们需要在哪个领域与商店或餐馆建立合作关系,或者在哪里开设新的车辆或充电站,或者在哪个位置提供服务。
同样,如果您是一家拥有大量高级用户的移动公司,您脑海中浮现的下一个问题是:
这些电力用户是如何移动的,他们从哪里来,去哪里?
理解这些特征可以决定我们需要加倍关注什么样的位置和用户角色。比如这些用户是上班族还是学生?
案例二:用户转化
转化的核心是客户流失的事实。今天,当人们做流失分析时,他们只看人物角色和漏斗的步骤。每一个没有转化的用户都是我们眼前的收入损失。
然而,分析客户流失发生在哪里是至关重要的,因为这有助于我们确定我们需要在哪里改善运营、提供供应或进行线下营销。
从用户打开应用程序到最终为订单付款,应用程序中有大量的步骤。
预约乘车:
输入目的地→搜索最近的自行车→选择自行车→开始行程。
点菜:
选择菜系→选择餐厅→选择菜品→结账→付款
例如,我们正在合作的一家食品杂货公司意识到,人们在看到 SLA 后,会从订购流程中大量生产,并且他们意识到他们可以在其他地方获得更好的 SLA!当我们绘制流失数据时,我们注意到一些城市中的高密度集群,团队开始专注于在这些地区提供更多的交付合作伙伴。
群组创建
案例三:用户留存
一旦转化了用户,如何确保可重复性和留存率?毕竟,我们都知道,保留是一个公司最重要的指标之一,因为它可以确保稳定的收入。但是,在这个世界上,用户只需点击一个按钮,就可以在多个竞争对手之间切换,而且他们要求最高质量的服务,因此确保留住客户越来越难。
不同的公司有不同的挽留策略。一些公司做向上销售:让用户以更高的频率订购同一目录,而一些公司做交叉销售:让用户订购不同的类别和目录。
位置可以帮助留住用户,也可以根据用户的位置和行为推出非常有针对性的促销活动。
例如,让我们回到我们的移动公司的例子。假设我们发现我们最有价值的用户是从宿舍到大学乘坐我们的车辆的学生。我们可以发起一场运动来补贴这些路线!
户外广告也是一种非常受欢迎的营销策略,用来培养和留住用户,这种策略的成功取决于正确的信息和位置。
你如何开始?
Locale 是一个位置分析平台,这意味着我们可以将所有数据库和格式的原始纬度数据转换为有意义的见解,以便决策者可以就其地面运营做出非常精确的数据驱动型决策。
网络分析工具已经利用点击流数据帮助你改善了这些指标。然而,对于在地面上有移动资产的公司来说,不从地理空间的角度看问题是非常有害的!让我们更深入地探讨如何使用位置分析来增加用户获取、转化和保留。
获得物ˌ获得
需求制图允许您叠加搜索数据并安装可用于分析不同区域的空间和时间趋势的数据。成长负责人可以利用这些见解来确定哪些领域尚未开发,以及不同类别的业务。
转换
流失分析有助于您分析不同事件在地理空间上发生的位置,以及人们在非常精细的级别上生产最多的位置。你是否需要开设一个车辆站枢纽来提供更多的站,或者给准备时间最长的餐厅经理打电话,或者做一些线下活动——决定权在你。
保留
工作流模块帮助您在达到特定指标和阈值时采取措施。公司利用这一点向他们的用户发送非常有针对性的地理促销信息,或者在他们的 KPI 观察到异常情况时收到警报。
在 场所 ,我们正在创建通过地理空间分析提高单位经济性、每次交付成本和利用率的公司范例。如果你是一名增长型经理,希望提高用户的获取、保留和转化,请在此处联系我进行演示或通过LinkedIn或Twitter联系我。
原贴 此处 。
类似阅读:
供求分析帮助你解码供求之间的差距出现在哪里,什么时候,为什么会出现。每单位的…
blog.locale.ai](https://blog.locale.ai/location-analytics-for-delivery-mobility-companies-with-ground-operations-2/) [## 在新冠肺炎期间使用 Locale.ai 为您的供应链进行位置分析
TL;DR:如果你是一家物流或送货公司,我们想帮助你监控和弥补差距…
blog.locale.ai](https://blog.locale.ai/location-analytics-for-your-supply-chain-using-locale-ai/)*
如何改进您的 DevOps 测试自动化策略
请继续阅读,了解如何自动化您的测试过程,以获得更高的灵活性和效率。
测试自动化策略通过将冗长且劳动密集型的测试过程转化为简化的自动化过程,增强了业务模型。公司正在将自动化安全测试作为开发过程的一个组成部分添加到他们的 DevOps 策略中。
强大的测试自动化套件使组织能够在每次执行 DevOps 管道时验证功能和简单的安全测试用例。公司可以更专注于日常活动,确保团队更高效地工作,而无需在重复性任务上投入太多时间。
但是如果您已经有了一个现有的 DevOps 测试自动化策略呢?您如何确保您的 DevOps 测试策略足以维护您的应用程序的良好安全性?
有几种方法可以创建和实现一个理想的 DevOps 测试自动化策略,帮助您早期识别应用程序的漏洞和弱点。
改进您的 DevOps 测试自动化策略的 5 种方法
在本文中,我们将解释构建可靠的 DevOps 安全测试自动化策略的要点,这将帮助您加强应用程序的安全性:
1.应用正确的测试自动化框架
框架是测试自动化策略的主要元素。它们提供了可重用的组件,不同的团队可以使用这些组件来创建定制的自动化测试。
一个构建良好的测试自动化套件可以作为您的组织的重要资产,并且是 DevOps 不可或缺的一部分。它促进了更快的交付、问题的早期检测,并简化了持续更新和执行的过程。
您可以使用开源软件或商业软件来构建满足您团队需求的测试套件。用于 DevOps 测试策略的开源软件和商业软件各有利弊。
例如,在使用 Selenium 或 OWASP ZAP (Zed 攻击代理)等开源软件时,您可以找到大量的故障排除、学习、支持和更新支持社区。
另一方面,像 Ranorex 这样的商业软件将为您提供一个端到端的空间来轻松构建、实现和执行您的自动化测试套件,并在您遇到问题时提供一个专用的支持机制。
DevOps 的开源工具,如 Zed Attack Proxy (ZAP)被广泛用于在开发和软件测试阶段识别与 web 应用程序相关的安全问题。
OWASP ZAP 也被认为是一个很棒的自动化安全工具,可以被有经验的测试人员用于手动安全测试。
测试自动化策略的框架允许你关注用户价值,而不仅仅是技术。它使团队能够超越应用程序的技术实现,以更好的方式为最终用户服务。正确实现的测试自动化框架有效地降低了开发过程中的测试套件维护成本。
2:了解应用程序的需求
吸收测试自动化需求,并选择正确的工具集来实现对于有效的开发运维来说是不够的。了解应用程序用户环境中的每个元素是非常重要的,例如配置、框架、最终用户目标、安全参数等。
您对应用了解得越多,就越容易在开发运维期间选择正确的自动化工具来测试您的应用的安全性。
如果自动化工具有助于应用程序的技术方面,但干扰了最终用户体验,那么您可能需要考虑不同的工具。
因此,对于处理 DevOps 自动化测试的团队来说,了解整个应用程序是至关重要的,这样他们就可以选择一个理想而有效的自动化安全工具。
通过考虑应用程序的各个方面,团队将能够不仅从技术角度,而且从客户的角度来理解应用程序。
例如,对于金融服务应用程序,安全性应该是重中之重。然后,自动化测试团队应该专注于创建支持应用程序的整体安全性的健壮策略,例如验证交易细节和负面测试用例的完整性,以确保用户看不到另一个用户的帐户细节,等等。
为此,组织应该鼓励开发和自动化测试团队的参与。
在 DevOps 测试中,来自开发团队的持续交付使得自动化测试团队成为每个模块的一部分。它有助于创建与项目开发相一致的更好的无缝 DevOps 测试策略。
通过与开发团队密切合作,自动化测试团队能够更新测试用例,以满足应用程序的最新功能,而没有太多的麻烦或延迟。他们将最新的代码集成到他们的测试案例中,以运行快速的安全测试,并确保及早识别和补救潜在的威胁和漏洞。
让自动化测试团队了解关于应用程序的每一次更新可以带来更好的 DevOps 测试。这不仅会改进软件测试过程,还会促进不同团队之间的顺畅交流。
3:对您的 DevOps 测试用例要有选择性
实现 DevOps 自动化测试策略的主要动机是覆盖简单的安全问题,并将更复杂的问题留给安全团队。
然而,由于代码过多,仅使用自动化安全测试来成功处理应用程序中的每个 DevOps 测试用例通常会变得很困难。因此,首先确定需要自动化的测试用例是很重要的。有许多事情可以考虑,例如需要多长时间运行一次 DevOps 测试用例,是否需要大量数据,是否需要大量逻辑,等等。
自动化测试有很多好处,特别是对于重复的测试用例以及连续的交付。而对于更复杂或者只执行几次的测试用例,手动测试是更好的选择。
接下来,我们将讨论 DevOps 的这些考虑事项,以帮助您理解和优先化您的测试用例。
为了从您的软件测试策略中获得最大的好处,您应该自动化测试:
- 本质上是重复的,经常运行
- 容易出现人工错误
- 如果手动执行,既昂贵又耗时
- 劳动密集型,需要大量的资源投入
您还可以利用测试自动化来测试以下案例:
- 在各种软件或硬件平台和配置上运行
- 需要大量数据
4:保持你的 DevOps 测试用例小
尽管一些质量分析师的目标是构建大型测试用例来处理复杂的代码结构,但是保持测试用例较小可能更有益。
当您创建小的测试用例时,您将能够明确地识别每个测试,并为预期的结果设置一个清晰的定义。然后你就会确切地知道什么失败了,什么成功了。测试用例将会更简单,更容易理解。
如果开发团队需要解决一个特定的测试用例,他们不需要很长时间就能理解测试用例的内容。
此外,你不需要浏览整个文档,只要在需要的时候查看它们,你就能够识别测试用例。
虽然保持测试用例小很重要,但是考虑负面测试用例也很重要。例如,您不应该能够使用其他用户的凭据访问他们的数据。
安全团队经常创建负面测试用例来确保更好的软件安全性,在这种情况下,用户不应该能够访问另一个用户的数据或利用输入验证。
这有助于检查 DevOps 策略中的无效数据或意外用户行为。例如,如果用户名仅由字母字符组成,而您输入了一个数值,系统应提示您再次正确输入输入值。
DevOps 测试自动化策略中较小的测试用例也倾向于严格遵循单一责任原则(SRP)。SRP 声明程序中的每个模块或类应该只负责程序功能的一部分。
因此,DevOps 测试的较小测试用例侧重于精确验证,以减少应用程序中漏洞的可能性。它鼓励不同团队之间更好的学习和理解,以更好地团结工作。
5:保持与 UI 无关的测试用例的灵活性
请记住,您的 DevOps 测试策略需要能够适应变化。
确保您的测试用例是灵活的,能够适应 UI 中的新变化,并且对将来的使用是可行的。
创建简单而强大的 DevOps 测试用例的最可靠的方法之一是用后端功能支持的动作术语来编写它们。
不要使用 JScript 之类的脚本语言,而要使用基于关键字的测试,这样就不需要依赖可能会随着开发的进行而改变的 UI 元素。
这是专门针对 DevOps 测试自动化策略的,在这种策略下,应用程序中会不断地进行更改和更新。
最后的想法
DevOps 不仅仅局限于技术实施和执行,它还能满足您的业务需求。将一套正确的工具和框架整合到您的测试自动化策略中可以改进您的软件开发过程。
任何投资于创建 DevOps 测试自动化策略的时间都是值得的。自动化技术可以提高整个安全测试过程的效率和有效性。关键是分析和创建可持续的测试用例,并随着 SDLC(软件开发生命周期)的进展保持相关性。
请记住,不恰当的测试自动化策略会对您的整个 DevOps 测试策略产生巨大的影响。因此,建议您与知识渊博的专业人员合作,构建并实现一个强大的 DevOps 测试自动化策略,该策略可以持续很长一段时间,并且几乎不受频繁的代码更改的影响。
关于作者:
Steve Kosten 是 Cypress Data Defense 的首席安全顾问,也是 Java/JEE 的 SANS DEV541 安全编码:开发可防御应用程序课程的讲师。
如何在你的预测模型中加入偏见
不要做这些事情,除非你想要一个有偏见的生产模型,做出不准确的,有时是昂贵的预测。
你真的不想让一个有偏见的模型为你做预测,是吗?尽管有大量高质量的机器学习(ML)实践者和技术进步,但现实生活中不乏 ML 失败。
让我们先回顾一下这些引人注目的 ML 和 AI 失败,其中潜在的偏差模型是失败的原因之一,如果不是主要原因的话,然后再讨论可能影响预测模型的偏差来源。
英国 GCSE 和 A-Levels 成绩惨败
由于新冠肺炎停课,英国学生今年没有参加 GCSE 和 A-Levels 考试。相反,英国考试监管机构 Ofqual 利用一种算法来确定学生的预期成绩,其基础是:
- 由学生的老师确定的估计分数
- 与同一所学校中具有相似估计分数的其他学生的相对排名
- 学校在过去三年中每一科目的表现
然而,在 8 月 13 日公布成绩的那一天,发生了一场彻底的灾难:将近 40%的 A-Levels 成绩低于老师的评估。这引起了相当大的骚动,导致政府在 8 月 17 日来了个 180 度大转弯,宣布将修改学生成绩,以反映最初老师的评估和模型输出中的较高者。
IBM 的“肿瘤学沃森”的失败
2013 年 10 月,IBM 与 MD 安德森癌症中心(MD Anderson)合作,基于其沃森超级计算机开发了一种人工智能解决方案来治疗癌症。然而,它辜负了人们的期望。
福布斯【2017 年 2 月报道称,MD Anderson 搁置了其 Watson for Oncology 项目,并积极寻找其他合作伙伴取代 IBM,继续其未来的研究。2018 年 7 月晚些时候,STAT 的一份报告显示,基于对 IBM 内部文件的分析,沃森提出了多项完全错误的癌症治疗建议,一些客户报告了“多个不安全和不正确治疗建议的例子”。
亚马逊的厌女症人工智能招聘
亚马逊的工程师在 2014 年开始开发一种自动化招聘工具,以审查求职者的简历。然而,路透社在 2018 年报道称,到 2015 年,“该公司意识到其新系统没有以性别中立的方式评估软件开发人员和其他技术职位的候选人”。
显然,该模型是根据 10 年来主要来自男性的求职申请进行训练的,这表明了当时男性在科技行业的主导地位。该项目随后被搁置,该团队于 2017 年初解散。
ML 模型中偏差的来源
特定的 ML 模型可能会以一种微妙的方式产生偏差,其他的则不会——如上所示。模型有偏差的一些潜在原因包括:
有偏数据/采样偏差
有偏见的训练数据最终会变成有偏见的模型——这是 GIGO 的格言!这在上面的亚马逊例子中很明显,训练数据中女性申请者的短缺迫使模型优先考虑男性申请者。该模型没有足够性别公正的数据来进行训练和学习。这些数据往往反映了社会的现状和当前的偏见(不管是好是坏)。
适当的数据收集和采样策略对于确保获得相关的、有代表性的、合适的和足够多样化的数据至关重要。数据科学家 80%的工作都围绕着数据收集和特性工程,这是有原因的。
算法偏差
ML 算法由于其各种与基础训练数据无关的数学和统计假设而具有其自身固有的偏差。有偏算法更严格,假设并要求严格定义的数据分布,并且更能抵抗数据中的噪声。然而,他们在学习复杂的数据时会有困难。相比之下,偏差较低的算法可以处理更复杂的数据,但通常不适用于生产中的数据。
这种冲突的情况通常被称为偏差/方差权衡。它需要 ML 从业者进行微妙的平衡,以确保最佳的偏差(根据定义,还有方差)。
排斥偏差
当我们从数据集中排除特定的特征或变量时,就会发生这种情况,因为我们错误地假设它们对手头的预测问题没有用,而没有首先验证该假设。
在丢弃任何特征之前,始终测试预测值和目标变量之间的相关性。我在之前的一篇文章中提到了针对各种变量类型的一些特征选择策略。
测量偏差
例如设备的错误测量会导致数据的系统性失真和测量偏差。例如,如果称重设备始终少报相同数量的重量,那么利用该故障设备产生的数据的任何模型都将是不准确的。带有“引导性”问题的设计不当的调查是测量偏差的另一个常见来源。
观察者偏差
当数据收集或特征工程策略受到数据分析师的先入为主(通常是错误的)观念的影响时,就会出现观察者偏差。例如,如果我对悉尼人有偏见(我不是),那么我可能会让我的偏见以潜意识的方式潜入我的数据。观察者偏见的一个经典例子是伯特事件。
检测观察者偏差通常很困难,但是可以通过结合培训和筛选策略以及明确定义和实施的政策和程序来防止。
反馈回路
考虑一个 ML 模型,它以某种方式影响数据的生成,然后被用于预测。因此,模型做出的预测会偏向于它有发言权的数据。然而,这种反馈循环也可以是一种设计特征,而不一定是一个值得关注的原因——通常在内容个性化和推荐系统中。
系统漂移
在这个上下文中,漂移指的是生成用于建模的数据的系统或应用程序随时间的变化。例如,延迟支付的业务定义的变化(在违约预测问题的情况下)或用户交互的新模式的增加。
通过适当的变更管理和错误跟踪实践以及定期的模型更新和培训,这种偏差是最容易防止和检测的。
结论
以上是可能影响预测模型性能的一些潜在偏差来源。根据我的经验,通过评估和重新评估数据收集和采样策略,以及彻底的测试/验证程序,可以充分处理上述大部分问题。
如果您想讨论任何与数据分析、机器学习、金融或信用分析相关的问题,请随时联系 me 。
下次见,摇滚起来!
如何提高 Azure Databricks 集群 vCPU 内核限制
Alexandre Debiève 在 Unsplash 上的照片
Azure Databricks“此帐户可能没有足够的 CPU 内核来满足此请求”警告的解决方案
我的客户经常会问我:
为什么我的 Azure Databricks 集群受到限制?
具体来说,对于一个默认的 PAYG Azure 订阅,当你想在 Azure Databricks 中创建一个集群时,你可能会被这样一个问题困扰:
此帐户可能没有足够的 CPU 核心来满足此请求
估计可用:10,请求:**
如下图所示。
即使您单击链接“了解更多关于 CPU 配额的信息”,该文档中也没有直接的答案。然而,如果你耐心地钻研官方文件,你会发现微软故意为所有 PAYG 订阅默认设置这些配额限制,以避免任何令人震惊的账单。
然而,这对于 Azure Databricks 集群来说非常不方便。vCPU 核心的数量被限制在 10 个,这也限制了 Azure Databricks 的能力。在大多数情况下,集群通常需要多个节点,每个节点可能至少有 4 个内核运行(推荐的工作虚拟机是 DS3 v2,它有 4 个虚拟内核)。
因此,集群将总是被限制为只有一个节点在运行,这变得毫无用处,因为 Spark 需要它的分布式特性来加速计算。请注意,如果我们选择“与 worker 相同”,驱动程序节点将需要另外 4 个内核。因此,发生了以下情况:
- 驱动节点(4 核)+1 *工作节点(4 核)= 8 核< 10 cores limitation
- Driver node (4 cores) +2 * Worker node (8 cores) = 12 cores > 10 核限制**(不允许)**
我们必须增加限制,数据块才能按预期运行。
解决这个问题的方法是增加配额,这并不复杂,但是我发现在官方文档页面上并没有直接说明。现在,我将演示如何增加配额和消除约束。
增加配额的步骤
- 进入 Azure 门户>点击搜索资源字段>输入“帮助”>选择“帮助+支持”
2.在左侧导航中,选择“新支持请求”。然后,在右侧窗格的“基础选项卡中,
- 发行类型:选择“服务和认购限额(额度)”
- 订阅:选择您的订阅
- 配额类型:选择“计算-虚拟机(核心-虚拟 CPU)订阅限额增加”
选择所有必填字段后,点击“下一步:解决方案> > ”。请注意,对此不会有任何“解决方案”,因为它需要一个支持人员来审查您的请求并手动批准它。所以“解决选项卡将被跳过,直接跳转到“详细信息”。
3.在“详细信息选项卡中,单击链接“提供详细信息”将“配额详细信息”刀片窗口移至右侧。然后,在窗口:
- 部署模式:选择“资源管理器”。
- 位置:选择您的位置。请注意,您可以一次请求增加多个地点的配额。
- 类型:选择“标准”。
- 标准:选择要增加配额的虚拟机系列。请注意,您可以一次为多个虚拟机系列请求配额增加
- 新 vCPU 限额:输入您想要增加的新配额
填写完所有要求的信息后,点击保存并继续。
4.现在,请求的配额增加显示在“请求摘要”中。还有一些其他需要填写的信息。根据自己的喜好输入即可,然后点击“下一步:审核+创建> > ”。
5.审核一切输入完毕后,点击创建创建该票。
来自 Azure 支持的响应
根据您选择的“严重程度”,工作人员会及时与您联系。通常,配额增加会在没有任何问题的情况下获得批准,随后会收到支持团队的电子邮件,以便在关闭票证之前进行确认。
总结和提示
事实上,微软 Azure 对各种服务设置了巨大的配额限制。您可以在这里找到详细信息:
[## Azure 订阅限制和配额— Azure 资源管理器
本文档列出了一些最常见的 Microsoft Azure 限制,有时也称为配额。为了学习…
docs.microsoft.com](https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/azure-subscription-service-limits)
当然,使用我在本文中演示的方法,您不仅可以增加 vCPU 核心的配额,还可以增加上面的官方文档中列出的其他服务配额。
现在,你的 Azure Databricks 集群没有任何限制,但请三思而后行,不要在以后产生令人震惊的账单:)
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
medium.com](https://medium.com/@qiuyujx/membership)
如果你觉得我的文章有帮助,请考虑加入 Medium 会员来支持我和成千上万的其他作者!(点击上面的链接)
如何提高预测模型的可解释性
SHAP 价值观
从商业角度的实用见解。
作者创作的照片
准确性和可解释性据说是截然不同的。复杂的模型往往能达到最高的精度,而简单的模型往往更容易解释。
但是如果我们想两全其美呢?获得高精度是很酷,但是如果我们能理解模型不是很好吗?尤其是,如果预测对企业的成功至关重要?正如里贝罗等人所说:
“[……]如果用户不信任某个模型或预测,他们就不会使用它。”(里贝罗等人 2016 年,第 1 页)
假设的情况
让我们想象一下:我们在一家大型储蓄银行担任数据科学家。我们的工作是确保我们知道哪些客户很有可能流失。
我们的模型会发生什么?我们将使用我们的结果来创建具有不同流失率的客户群。
然后,具有最高流失率的客户群会接受有针对性的营销,这样他们就不会离开银行。
与获得新客户相比,留住客户的成本要低得多(Keaveney 1995)。因此,我们的工作对银行的成功至关重要!
我们必须实现两个目标:
- 营销团队必须获得尽可能准确的结果。为什么?因为银行是花钱留住这些客户的。如果客户无论如何都会留下来,银行就是在把钱扔出窗外。
- 我们必须让利益相关者相信他们可以信任我们的结果。祝你好运,向营销经理解释我们是如何创建我们的模型的…
所以我们假设营销老板不理解我们的模式,但是信任我们(不管什么原因)。因此,他们实现了我们的复杂模型。
- 该模型具有很高的预测能力。营销团队很高兴,因为他们看到所采取的措施有助于留住客户。我们很高兴,因为我们得到了该模型的积极反馈。
不错!我们可以就此收工,把精力集中在下一个任务上,为我们所做的伟大工作获得更多的荣誉。
但是停!坚持住!
准确性和可解释性不能用同一个模型来实现,对吗?
因此,我们只关注模型的准确性。但是如果模型有瑕疵呢?
我们可以在我们的模型中加入一个变量,这个变量实际上没有任何意义。不知怎么的,有一段时间是管用的,后来就不行了,也没人认了。
更糟糕的是:我们可能创造了一个性别歧视的算法,在社交媒体上引起轩然大波。你认为我在开玩笑吗?这种情况不知何故发生在苹果和高盛身上。
一个经理会为了几个更准确的点而拿他/她的职业生涯冒险吗?
在这里我可以给你一个浅显简单的答案……不会,管理者不会冒这个险。他们花了很多年建立自己的事业,对机器学习一窍不通。
当然,预测客户流失概率可能不是一个会在媒体上引起轩然大波的热门话题。但是,如果我们的模式因为我们未能正确理解而对我们不利,后果可能是痛苦的。
解决方案
可解释性是必不可少的,因为它促进了对我们模型的信心和信任。用户不会采用不能做到这一点的模型。此外,增强的可解释性有助于提高模型性能,并扩展我们可以从模型中获得的知识(Lundberg & Lee,2017)。
不错!通过增加可解释性,我们不仅能够理解我们的模型,还可以获得有价值的见解。也许营销团队想更多地了解他们的客户?
幸运的是,消除模型准确性和模型可解释性之间的权衡已经引起了研究人员的关注(Ribeiro 等人,2016 年 Lundberg & Lee,2017 年 Chen 等人,2018 年)。
他们的一个解决方案获得了很多关注:Lundberg & Lee (2017)引入的 SHapley 加法解释(SHAP)值。
SHAP 价值观源于博弈论。他们衡量一个变量的观察水平对个人最终预测概率的边际影响(Lundberg 等人,2019 年)。
通过这种方法,可以解释为什么客户会收到其流失预测值,以及这些特征如何有助于这种预测。这种局部可解释性增加了透明度。此外,将本地解释结合起来以获得全球可解释性也变得可行。
让我们使用这些神秘的 SHAP 值将一个复杂的模型转换成一个复杂的和可解释的模型。
和行动
记住,我们想知道哪些客户会流失。因此,我使用这个 Kaggle 数据集来预测银行客户的流失概率。
用于预测流失概率的前十行数据集。
对于预测,我使用了基本的逻辑回归和默认的 XGBoost 算法。为了让这篇文章可读性更好,我不会展示代码行。如果你有兴趣知道我是如何构建模型的,请看看我的 GitHub 库。在那里你可以找到你需要的一切。
因此,让我们快速比较 logit 模型和默认 XGBoost 模型的模型统计数据。
logit 模型达到 84.1%的测试准确度,而默认的 XGBoost 模型具有 86.6%的测试准确度。AUC 怎么样?这里,logit 模型的 AUC 为 82.3%,而默认 XGBoost 模型的 AUC 为 85.1%。
事实上,更复杂的模型更能预测谁会流失,谁会留在银行。
因此,我们通常可以使用 XGBoost 的三个不同的重要性度量,通过它们我们可以更详细地了解我们的模型。
XGBoost 模型的重要图。作者创造的情节。
我想到了什么?这三种重要性度量为要素分配了不同的重要性级别。
此外,我看不出自变量和客户流失之间的关系。更高的年龄是增加还是减少成为一个搅动者的概率?这些情节无助于回答这个问题。
因此,让我们看看如何使用 SHAP 值来解释我们的模型。
在下图中,特性按照它们对默认 XGBoost 模型的全局影响进行排序。较高的 SHAP 值表示客户退出银行的预测较高。圆点表示训练集的各个预测对模型输出的特征影响。根据特征值的不同,点的颜色从蓝色(低)到红色(高)。因此,我们可以探索特性影响的范围、强度和方向。
SHAP 概要图。作者用 SHAPforxgboost 创作的剧情。
年龄、NumOfProducts 和 IsActiveMember 具有最高的全局功能重要性。从这个概要图中,我们可以得出几个有趣的见解:
- 特征对预测的影响范围是广泛分布的。例如,年龄对一些客户的预测有很大的影响,而对另一些客户则只有很小的影响。
- 尽管有些变量的全局重要性较低,但该特征对某些个体的影响可能很大。例如,对于信用评分低的人来说,信用评分与流失有正预测关系。
- 乍一看,一些变量显示出与客户流失的直观关系,而对其他人来说,这是违反直觉的。例如,为什么产品数量越多,客户流失的可能性就越大?这有道理吗?
为了更深入地研究单个变量,我们可以使用依赖图。下图显示了年龄的 SHAP 依赖图。与汇总图一样,每个点都是一个客户。如图所示,年轻客户对流失的预测值较低,而年长客户对流失的预测值较高。但这不是线性关系!当达到 60 岁时,客户流失概率开始下降。
年龄的 SHAP 依赖图。作者使用 SHAPforxgboost 创建的情节。
祝你用 logit 模型探索这种关系好运…
基于与 XGBoost 模型相同的数据的逻辑回归的摘要输出。年龄变量突出显示。
要疯狂,还可以看看变量的交互作用效果。
在下面的左侧面板中,您可以看到年龄变量的相同依赖关系图。但这一次,我加入了性别变量,以观察年龄和性别如何相互作用。
在右边的图中,年龄和性别的交互作用表现得更为明显。不知何故(我缺乏解释这一点的领域知识),当与年龄配对时,男性和女性有不同的行为。例如,年轻女性的 SHAP 互动值为负值,这意味着年轻女性的 SHAP 值低于年轻男性。
年龄和性别的 SHAP 依赖性图(左图)和 SHAP 相互作用图(右图)。作者用 SHAPforxgboost 创作的情节。
到目前为止,一切顺利。但是,客户拥有的产品数量对客户流失预测的影响如何呢?至少对我来说,产品越多的客户越有可能翻盘,这似乎有悖常理。我们都知道终止合同有多难,尤其是银行合同。
当观察逻辑回归的系数值时,我们看到了同样的效果。不知何故,与拥有一个、三个或四个产品的客户相比,拥有两个产品的客户流失的可能性更低。
logit 模型的摘要输出基于与 XGBoost 模型相同的数据。突出显示 NumOfProducts2 变量。
因此,我假设这种趋势存在于数据中,而不是被我们的 XGBoost 模型随机使用。
我还担心吗?是的。我通常会做什么?
- **看文献。**这种关系可能有意义,谁知道呢?
- 质疑数据的相关性。当我搜索数据集时,我已经想到了这个主题。我没有太多的选择,而且这个数据集没有版权。算法和数据一样好。
- **探索数据集。**在建立模型之前进行解释性分析是非常可取的。也许,我可以找到一些模式来解释这个违反直觉的结果。
- **删除变量。**如果我怀疑该变量不能提供有意义的结果并可能导致缺陷,我会删除它。即使这意味着损失一些准确性或 AUC 百分点。
到目前为止,我所做的分析可以用于每一个变量。我们需要完全理解我们的模型,对吗?但是因为这篇文章太长了(如果你到目前为止还没写完,就猛敲!),我就不赘述给你进一步分析了。
结论
理解我们的预测模型以及该模型捕捉数据的一般潜在趋势是至关重要的。否则,该公司将面临一颗定时炸弹。一切都很顺利,直到它不再顺利。
此外,我们需要能够向相关的利益相关者解释我们的结果。向一个理解基本统计学有困难的人解释预测模型,首先是 SHAP 值是很难的!尽管如此,这些利益相关者通常是决策者,所以我们必须确保我们可以让他们相信我们的模型在实践中确实有效。
除了通过增加对我们模型的信任来减少可能的风险,我们还可以获得更简单的模型所不能获得的额外的洞察力。这可能非常相关。尤其是对于总是有兴趣了解客户的营销部门来说。
如果您有任何问题或意见,欢迎在下方留下您的反馈。另外,如果你想和我联系,你可以通过LinkedIn联系我。
敬请期待,下期帖子再见!
如果你对我和 190 名学生如何学习数据科学感兴趣,请查看以下文章:
如何学习编码的可行策略?
towardsdatascience.com](/how-190-students-and-i-have-learned-data-science-55da9e0e5c6b)
[1] Ribeiro,M. T .,Singh,s .和 Guestrin,C. (2016),“我为什么要相信你?”:解释任何分类器的预测,见 B. Krishnapuram & M. Shah 编辑的“KDD 16:第 22 届 ACM SIGKDD 知识发现和数据挖掘国际会议论文集”,第 1135–1144 页。
[2] Keaveney,S. M. (1995),“服务业中的顾客转换行为:一项探索性研究”,《市场营销杂志》59,71–82。
[3] Lundberg,s .和 Lee,S.-I. (2017),解释模型预测的统一方法,载于 U. von Luxburg,I. M. Guyon,S. Bengio,H. M. Wallach 和 R. Fergus 编辑的《NIPS’17:第 31 届神经信息处理系统国际会议论文集》,第 4768-4777 页。
[4]陈,j .,,温赖特,M. J. &乔丹,M. I. (2018),学习解释:模型解释的信息论观点,载于 J. G. Dy & A. Krause 编辑的《第 35 届机器学习国际会议论文集》,第 882-891 页。
[5] Lundberg,S. M .,Erion,G. G. & Lee,S.-I. (2019),《树集合的一致个性化特征属性》,第 1–9 页。
如何用 Python 索引 Pandas 中的数据
如何在 Python 中使用 loc 和 iloc 方法
伊利亚·巴甫洛夫在 Unsplash 上的照片
介绍
为熊猫的数据帧建立索引是一项非常重要的技能。索引仅仅意味着在数据帧或系列中选择特定的行和/或列。在本教程中,我们将介绍 loc 和 iloc 方法,这是在 pandas 中索引数据帧的两种最常见的方法。我将使用在 jupyter 笔记本上这里找到的 ufo 目击数据集。
在我们开始之前,让我们将数据读入数据帧,看看 ufo 数据帧的前 5 行:
我们 ufo 数据帧的前 5 行
让我们看看关于我们的数据框架的其他一些信息:
我们使用 shape 和 columns 属性分别获取数据帧的形状(行数、列数)和列名。
锁定方法
索引数据帧最通用的方法可能是 loc 方法。loc 既是 dataframe 又是 series 方法,这意味着您可以对这些 pandas 对象中的任何一个调用 loc 方法。当在 dataframe 上使用 loc 方法时,我们使用以下格式指定我们需要的行和列:data frame . loc[指定的行:指定的列]。有不同的方法来指定我们想要选择的行和列。例如,我们可以传入单个标签、标签列表或标签数组、带标签的切片对象或布尔数组。让我们来看一下这些方法!
使用单一标签
我们可以指定我们想要的行和/或列的一种方法是使用标签。对于行,标签是该行的索引值,对于列,列名是标签。例如,在我们的 ufo 数据帧中,如果我们只想要第五行以及所有的列,我们将使用如下:
ufo.loc[4, :]
单一标签
因此,我们通过使用特定行的标签(即 4)来指定我们想要的行,因为我们想要所有的列,所以我们只需使用冒号。
注意:我们可以省略冒号,我们会得到相同的输出,但是,为了代码可读性,最好保留冒号,以明确显示我们需要所有列。
标签的列表或数组
假设我们需要多行和/或多列。我们如何指定它?使用标签,我们可以输入一个标签列表,或者使用类似于你可能熟悉的切片符号。
让我们从标签列表开始:
标签列表
注意我们如何用标签列表指定行和列标签。
使用流行的 Python 包添加智能进度条
better 编程. pub](https://betterprogramming.pub/display-progress-bars-using-tqdm-in-python-c81484be9390)
切片对象
我们也可以使用切片符号,格式如下:开始标签:停止标签。然而,与使用带列表或字符串的切片标记相比,开始和停止标签都包含在我们的输出中,如下所示:
带标签的切片对象
注意行标签 3、4 和 5 是如何包含在我们的输出数据帧中的。还要注意 City、Colors Reported 和 Shape Reported 列是如何包含在内的,即使我们使用 slice 对象停止在 Shape Reported。记住,ufo.columns 返回了一个列表,其顺序为城市、报告的颜色、报告的形状、州和时间。我们包括从城市标签到形状报告标签的所有内容,其中还包括颜色报告标签。
了解如何在 Python 中分割列表和字符串
towardsdatascience.com](/a-skill-to-master-in-python-d6054394e073)
布尔数组
最后,我们可以使用一个布尔值数组。但是,这个布尔值数组的长度必须与我们使用它的轴的长度相同。例如,根据我们上面使用的 shape 属性,我们的 ufo dataframe 的形状为(18241,5),这意味着它有 18241 行和 5 列。因此,如果我们想使用一个布尔数组来指定我们的行,那么它需要有 18241 个元素的长度。如果我们想使用一个布尔数组来指定我们的列,它需要有 5 个元素的长度。创建这个布尔数组最常见的方法是使用条件。
例如,假设我们希望只选择包含阿比林的行,该城市是 ufo 目击事件发生的城市。我们可以从以下情况开始:
ufo.City == ‘Abilene’
注意这是如何返回长度为 18241 并且由布尔值(真或假)组成的熊猫序列(或类似数组的对象)的。这是我们需要使用这个布尔数组来使用 loc 方法指定我们的行的值的确切数目。想象你把这一系列真值和假值覆盖在我们的 ufo 数据帧的索引上。只要这个序列中有一个真的布尔值,这个特定的行将被选中并显示在我们的数据帧中。在这里,我们可以看到索引或标签 3 为真(在第 4 行),这意味着一旦我们使用 loc 方法使用这个布尔值数组,我们将看到的第一行是标签为 3 的行(或 ufo 数据帧中的第 4 行)。
ufo.loc[ufo.City == ‘Abilene’, :]
阿比林的不明飞行物目击事件
这正是我们所看到的!我们已经使用长度等于原始数据帧中的行数的布尔值数组指定了我们想要的行。
请记住,我们可以组合这些不同的指定行和列的方法,这意味着我们可以对行使用一种方法,对列使用另一种方法。例如:
ufo.loc[ufo.City == ‘Abilene’, ‘City’:’State’]
注意我们如何使用返回布尔值数组的条件来指定行,以及如何使用标签来指定列的切片对象。
Python 中制表和熊猫数据帧函数的性能比较
towardsdatascience.com](/two-ways-to-create-tables-in-python-2e184c9f9876)
iloc 方法
iloc 方法也是数据帧和序列方法,可用于索引数据帧(或序列)。iloc 中的 I 代表整数,因为我们使用基于行和列位置的基于整数位置的索引,而不是标签。就像使用 loc 方法一样,我们可以输入一个整数或整数列表、一个带有整数位置的 slice 对象或一个布尔数组。让我们来看一下 loc 和 iloc 方法之间的一个关键区别:
在我们的 ufo 数据帧中,我们没有改变索引,所以数据帧的默认索引只是我们行的整数位置。但是,让我们尝试使用 slice 对象通过 iloc 方法来指定我们的行:
ufo.iloc[3:5, :]
请注意,在 iloc 方法中使用 slice 对象时,停止整数位置不包含在我们的数据帧中。所以我们只能看到第 3 行和第 4 行,而看不到第 5 行。这与 loc 方法形成对比,在 loc 方法中,开始和停止标签都包含在我们的数据帧中。
让我们使用 iloc 方法来指定我们想要的列:
ufo.iloc[3:5, 1:3]
如果我们查看数据帧的列作为参考,我们可以看到我们正在从索引 1(或报告的颜色)到索引 2(报告的形状)对列进行切片。我们不包括站点的索引,在本例中,State 的值为 3。
注意:我们可以为 loc 或 iloc 方法使用一个可调用的函数,返回一个有效的索引输出(我们上面讨论的任何输入)。然而,我们将把它留到另一个教程中。
本教程中使用的所有代码都可以在这里看到:
本教程中使用的所有代码
使用 Python 的 JSON 和 API 介绍
towardsdatascience.com](/json-and-apis-with-python-fba329ef6ef0)
如果你喜欢阅读这样的故事,并想支持我成为一名作家,考虑注册成为一名媒体成员。每月 5 美元,你可以无限制地阅读媒体上的故事。如果你用我的 链接 注册,我会赚一小笔佣金。
阅读卢艾·马塔尔卡的每一个故事(以及媒体上成千上万的其他作家)。您的会员费直接支持…
lmatalka90.medium.com](https://lmatalka90.medium.com/membership)
结论
在本教程中,我们学习了如何使用 loc 和 iloc 方法索引数据帧。我们学习了 loc 方法如何主要处理行和列的标签,而 iloc 方法处理整数位置。我们还看到了如何使用布尔数组来索引或指定我们的行和列。
如何使用 IBM Watson NLC 服务推断预训练的图像分类器
使用预先训练的模型进行推理
约翰·西门子的图片——Unsplash
分类
图像分类是属于数据科学和机器学习的另一项任务,其中我们为每个图像分配一个或多个类别或种类。
推理
在 IBM Watson 上创建一个项目。您应该能够看到您的项目列表。单击其中一个项目开始。
单击“添加到项目”以添加服务
选择*【视觉识别模式】*
如果这是您的第一次,那么您将被重定向到创建服务。点击*【此处】*
您可以选择一个以前的服务(如果有)或创建一个新的服务。
选择一个符合你需求的计划。
您可以选择更改区域、计划、资源组等。我更喜欢默认值。
之后,您应该能够看到三种不同的训练模型,您可以使用。
先说*“将军”。点击“常规”后,*会看到三个选项卡。概览将显示型号信息。
点击*“测试”*开始推理模型
拖放你想要推论的图像。每幅图像都将显示其相关类别及其置信度得分。
点击*“实现”*,将提供几种使用终端远程推断您的模型的方法。
让我们试试*【食物】*模式。
*【显式】*模型预测
资源
- IBM Watson AutoAI 文档
- Youtube 上的 IBM 沃森学习中心
如何在数据科学中创新
分享我对创新的想法,以及 2014 年最喜欢的一个数据科学项目
由 Unsplash 上的absolute vision拍摄
世界上每天都有数百万的创新发生。创新创造新产品、服务、商业模式、技术,甚至新的科学领域;如果没有创新,我们将生活在一个完全不同且无聊的地方。创新在数据科学领域也至关重要:数据科学家将数据转化为可操作的产品/见解,这种转化不断要求人们超越现状进行创新。
创新是生产或采用、吸收和利用一种在经济和社会领域中具有附加值的新奇事物;产品、服务和市场的更新和扩大;开发新的生产方法;以及建立新的管理系统。(维基百科)
同时,创新不是自然的:是的,我们都有自己的观点和想法,但是,创新是一种“增值的新奇事物”;因此,“新奇”本身并不等于“创新”。那么,创新有哪些类型,我们怎样才能把创新发展成一种技能呢?
两种类型的创新
在我看来,创新有两种类型:
- 类型 1。找出更好的替代方案来解决现有问题
- 类型 2。将现存的问题重新定义成一个更有意义的问题,用任何方法解决它
这里有一个例子可以更好地说明这些概念。假设:你想要一台计算能力更强的计算机,一个已知的问题是 CPU 速度慢。第一类创新是通过将半导体制造尺寸从 800 纳米降低到 130 纳米,再降低到 14 纳米来提高 CPU 速度,现在它在 2020 年接近 5 纳米!所以计算能力也相应增加。第二类创新是 a)支持多核 CPU 架构,或者 b)将 GPU 集成为协处理器,以加速通用科学和工程计算的 CPU。最终目标是一样的:更强的计算能力:而类型 1 创新专注于一种已经定义好的方式,类型 2 创新扩展到替代路径。
两种类型的创新都创造商业价值,然而,它们通常与不同的观点相关联。
- 第一类创新需要一个有很强领域专业知识的人,这样才能推进技术边界;更集中的观点。专注于全合成的大学顶级研究实验室( wiki )可以很好地代表这种创新。
- 第二类创新要求一个人对相关的知识空间有全面的了解,并有将点与点连接起来的心态;更全面的观点。许多传奇的商业故事,如 iPhone 的诞生,都可以用这种创新类型来描述。
现在我们定义了创新的类型,接下来的问题是:如何主动发展创新技能?有没有一个公式,像“A + B =创新”?我不想直接给出我的主观答案,我想先分享一个故事:这是我第一份工作中最喜欢的项目之一,我认为这比干巴巴的声明更有背景。
关于 BuildX 的故事
背景
我在 2013 年 8 月开始了我的数据科学职业生涯,我的第一家公司运营着一个汽车定价和信息网站。2014 年,该公司启动了一项战略计划,其成功取决于获取所有库存车辆的详细配置数据,而这些数据是不可用的。例如,给定一个 VIN 号码“1FATP8FF4L5106855”,根据 VIN 字符串模式,我们知道它是一辆福特野马,2020 GT 敞篷高级版;然而,汽车上安装了许多选项,如“福特安全和智能包”,这些选项无法从 VIN 图案本身提取:尽管这是该公司最需要的详细车辆选项配置。
VIN 的半个车窗贴纸:1FATP8FF4L5106855。来源:【http://vin.maniacs.info/FordSticker.html? title=1FATP8FF4L5106855
产品团队开始通过与第三方数据提供商和制造商(如福特、丰田等)的合作,努力获取此类信息。数据科学团队参与评估数据质量、评估可用性,并就新获取的数据是否充分涵盖了我们的库存提供见解。很明显,数据科学团队起到了支持的作用,这从项目的性质来看是可以理解的。该项目的目标是实现高于某个阈值(例如 80%)的数据覆盖率,以便可以构建其他下游产品。不幸的是,几个月过去了,团队开始意识到数据覆盖率仍然远远低于阈值。
作为团队中的一名数据科学家,我学到了很多关于业务如何运作的知识,甚至扮演了一个支持角色,并且在数据评估和集成方面与多个团队合作是一次很棒的经历。然而,我有一种感觉,数据科学可以提供一些额外的东西。
用虚拟解决方案重新定义问题
我想到的一个想法是:我们花了这么多精力购买数据,有可能在内部生成吗?鉴于当时我在公司的任期有限(不到 1 年),我决定检查一下之前是否有这种想法。这是一次定期的同步会议,产品总监刚刚分享了数据采集的状态,以及修改我们目标的潜在需求。在会议结束时,我非常谨慎地提出了我的问题:“这可能有点天真,但是,有可能在内部生成完整的车辆信息吗?”。答案是:“我们考虑过,但是 VIN 不包含那么多信息;你怎么看?”因为我也还没有一个清晰的想法,所以会上没有太多的讨论;但至少我知道这是一个未触及的想法,我要求一周的时间来探索这个方向。
一周的时间肯定非常紧张,所以我的第一个方法是寻找可以立即提高数据覆盖率的业务逻辑。经过一番挖掘,我找到了一个“解决方案”:如果我们知道某个特定的车辆型号根本没有可用的选项,那么我们可以声明我们知道这个车辆的完整配置。这在某种意义上感觉像是欺骗,然而,从产品的角度来看,知道我们有完整的配置是有帮助的,即使配置什么也没有。
我的论点:虽然它什么都没有,但现在我们知道了这个事实;这很有价值。
接下来的一周,我与团队分享了这一见解,每个人都很高兴看到这一简单探索带来的“免费”覆盖率提升。然而,我们也知道这不是一个通用的解决方案,只有这么多的车辆型号没有可用的选项,我们不能将其扩展到所有的车辆。所以我要求额外的两周时间来寻找一个更具可扩展性的解决方案,并且得到了批准:这个“虚拟解决方案”给我带来了更多的时间:)
证明概念是一个简单但可扩展的解决方案
事实是:除非我们有一些额外的信息,否则没有办法完全根据 VIN 号来识别所有的车辆选项。因此,我深入研究,发现了一些有用的东西:每个 VIN 都与一个固定的制造商建议零售价(MSRP)相关联,同时,每个车型也有一个固定的基础版本 MSRP,因此“VIN MSRP”和“基础 MSRP”之间的差异是“总选项 MSRP”,这将是我们所有库存车辆的额外信息。
现在让我们考虑以下情况:你有一辆汽车,VIN 显示 22K 的建议零售价,车辆型号(例如丰田凯美瑞 le)有 20K 的基本建议零售价,现在所有增加的选项都有 22K-20K=2K 的建议零售价。假设该车辆模型有 4 个可用选项:它们的 MSRP 标签分别为 1.5K、1.0K、0.5K、0.2K。汽车上安装的正确选项是什么?
给定 4 个可用选项的情况,找出答案是非常简单的:我们只需列举所有可能的选项组合,并检查每个组合是否具有相同的总选项 MSRP。如果它是唯一的匹配,我们可以声称该选项组合是正确的车辆配置。
您可能会立即看到这种方法有两个挑战:1 .同一个 MSRP 可能有多个配置匹配,那么如何找到合适的呢?2.选项组合随着可用选项#呈指数增长,这可能是一个大问题。然而,我可以执行以下两条规则来绕过挑战:1 .如果只有一个配置与 MSRP 匹配,则仅声明正确的配置;2.设置超时阈值(例如,每个 VIN 30 秒)以确保计算按时完成。现在,我们有了解决方案!该解决方案非常简单,可扩展至所有车辆库存。虽然我们没有完全解决上述已知的挑战(我们只是绕过它们),但这已经比我们的“虚拟解决方案”前进了一大步。
我们很快测试了这个想法,事实上,覆盖范围有了很大的提高;但是,我们离目标还有差距。这主要是因为许多车型有 30 ~ 60 种选择,极端情况下可达 100 种。在 40 个可用选项的情况下,需要评估 2⁴⁰配置,这超过一万亿个配置!许多 vin 达到超时阈值,并且根本不返回任何选项组合。现在我们知道指数级增长的计算成本是一个限制因素,并且根据定义这是一个 NP-hard 问题,我们应该如何进一步进行?
为可扩展的解决方案开发高级算法
当面临如此严峻的挑战时,我会在圣莫尼卡海滩外面散步,让新鲜空气清理我的思绪。由于我在业余时间上了各种课程,有一门恰好是离散优化,一个算法跳入我的脑海:约束编程。
关于约束编程的高级概念是,您不需要穷尽搜索所有的配置空间。您可以构建约束,以便某些配置永远不会被访问。例如,如果总选项 MSRP 为 1K,则不可能添加 1.5K 选项,因此没有必要评估任何具有 1.5K 选项的配置;另一方面,如果总选项 MSRP 是 10K,一个选项“A”是 5K,所有其他选项 MSPR 加起来是 8K,那么你知道选项“A”肯定在这个车辆上,没有“A”的任何配置都不必考虑。
以下可视化说明了这样一个事实,即约束编程算法通过避免进入违反约束的节点,充当搜索所有配置(表示为二叉树)的智能向导。在这个例子中,配置空间具有 2⁴ = 16 个组合,并且该算法仅需要 5 次移动。
在 Python 的帮助下,我把算法编码成了一个包(一个最小可行的数据产品),把一个现有车辆库存的样本注入到流程中:有效!现在我有充分的信心,我们可以达到覆盖目标!这对团队来说是一个大新闻,每个人都期待着算法的生产:现在,项目从“业务开发驱动”转变为“数据科学驱动”,我们得到了构建数据产品的全面支持。
为了推广我们的成果,我将其命名为“BuildX 项目”
构建一个数据产品有多层复杂性:算法只是其中的一部分。最终,我们交付了它。为了向外部团队推销这个数据产品和我们的成果,我给它起了个名字:“BuildX 项目”。“构建”部分代表了我们正在重建车辆配置的事实,而“X”部分编码了所有的算法复杂性,并使其感觉神秘而强大。人们可以在我们提交的专利中看到关于该架构的更多细节,下面的图表显示了高级系统架构。
我们的合作团队喜欢这个名字!在他们倡导数据产品的力量的帮助下,我们将代码与其他后端系统集成,最终,团队实现了数据覆盖的目标。这个故事有一个快乐的结局。
创新的公式
回顾过去,一切看起来都是如此精心策划:创新就发生在那里!“为什么”的问题,简单的解决方案,然后神奇的海滩漫步导致了“可扩展的解决方案”。然而,在发生这种事情的时候,感觉很没有计划:我问了几个“为什么”的问题,因为我对现有的系统不太了解;我碰巧早几个月上了离散优化课,因为它刚刚在 Coursera 上发布;我开始有规律的沙滩漫步是因为公司组织了一次“散步比赛”(而我没有赢…)。那么这些随机的东西,一旦放在一起,是如何变成“增值”创新的呢?有没有一个创新的秘密公式,不知何故我准确地执行了它?
不幸的是,创新没有神奇的公式,没有确定的公式。从积极的一面来看,我发现了几个有助于促进创新的元素:有了这些元素,你就更有可能给项目带来创新。这些要素是:
- 挑战现状,恭敬地。这通常与“为什么”这个问题相吻合:不管现状的解决方案有多好,在问了几个“为什么”之后,你会发现有些地方可以改进。
- 不断学习。你舒适区之外的任何知识都值得学习:深入某个领域有助于第一类创新,拓宽相关领域有助于第二类创新。
- 把点点滴滴。“点”指任何知识、经验、教训。放松你的思维,让你的大脑把相关的点联系在一起。一旦它们连接起来,奇迹就会发生。
为了结束这个故事,我想再分享一个关于创新的“不确定性”本质的评论:你可能会问很多很棒的“为什么”问题,学习 10+门与你的领域相关的课程,并不断思考如何将“点”与特定项目联系起来。然而,该项目只是让所有组件运行良好,你不能带来革命。这会是一个悲伤的创新故事吗?我不这么认为。尽管成功创新的结果是有回报的,但通往创新的道路才是最重要的。当一个人开始创新,就像在沙滩上散步,你开始环顾四周,突然注意到沙滩上有一个闪亮的物体;你把它捡起来,掸掉灰尘,擦掉污垢,发现它是意想不到的东西。它可能是一颗巨大的珍珠,如果是这样,你真幸运!它也可能是一个漂亮的、形状良好的贝壳,你可以把它装饰在书桌上。偶然发现的时刻会带来更多的快乐,这是创新最令人兴奋的部分;我希望你喜欢。
照片由 Aaron Burden 在 Unsplash 上拍摄
*该文章也可在 LinkedInhttps://www . LinkedIn . com/pulse/how-innovate-data science-pan-Wu上查阅
如何使用 Python 和 Boto3 库为 DynamoDB 插入记录和进行条件删除
一个教程,展示了如何使用 Python 和 Boto3 库以编程方式插入多条记录并按条件删除项目
丹尼尔·冯·阿彭在 Unsplash 上的照片
介绍
出于测试目的,我们的 DynamoDB 表中有许多垃圾或虚假记录是很常见的。它可能是我们正在开发的一个应用程序,甚至只是一个功能。它也可以是我们现有的应用程序生成的一些记录,但实际上,它们没有值。不管它是什么,我们最终都会在数据库中创建许多记录。
我们时常想要清理数据库表,因此只存储有价值和有意义的记录。例如,我们做了一个负载测试来测试应用程序中的用户帐户创建 API。这显然导致了表中的许多记录,这些记录只是“测试”记录。所有这些“测试”记录都具有邮件以testing
开头,姓氏以TEST
开头的特征。你知道,不管怎样。😆显然,一旦我们完成了负载测试,这些记录就可以从表中删除。
你会学到什么
在本教程中,您将学习如何使用 Python 从 DynamoDB 表中插入项目和有条件地删除项目,无论出于什么原因,您都不想再保留这些项目。我们将使用 Python 的官方 AWS SDK 库,它被称为Boto3
。
先决条件
设置虚拟环境
我不打算做详细的演练,但会通过virtualenv
快速展示给你如何做。
首先,你需要通过pip3
安装virtualenv
,如果你还没有安装的话。这很简单,因为:
$ ~/demo > pip3 install virtualenv
然后,创建一个目录来存放项目文件(或者在本例中是 Python 脚本)。
$ ~/demo > mkdir batch-ops-dynamodb
转到目录并在那里创建虚拟环境。
$ ~/demo > cd ./batch-ops-dynamodb$ ~/demo/batch-ops-dynamodb > virtualenv ./venvUsing base prefix '/Library/Frameworks/Python.framework/Versions/3.8'
New python executable in /Users/billyde/demo/batch-ops-dynamodb/venv/bin/python3.8
Also creating executable in /Users/billyde/demo/batch-ops-dynamodb/venv/bin/python
Installing setuptools, pip, wheel...
done.
最后,我们希望激活虚拟环境。快速提醒一下,虚拟环境非常有用,因为它将您的开发与机器的其他部分隔离开来。可以将它想象成一个容器,其中所有的依赖项都在虚拟环境中提供,并且只能从环境中访问。
$ ~/demo/batch-ops-dynamodb > source ./venv/bin/activate$ ~/demo/batch-ops-dynamodb (venv) >
注意(venv)
。这表明您处于虚拟环境中。但是,根据终端的设置,您可能看不到这一点。因此,作为一种替代方法,这就是为什么您可以验证您的虚拟环境是否处于活动状态。
$ ~/demo/batch-ops-dynamodb (venv) > which python
/Users/billyde/demo/batch-ops-dynamodb/venv/bin/python$ ~/demo/batch-ops-dynamodb (venv) > which pip
/Users/billyde/demo/batch-ops-dynamodb/venv/bin/pip
您可以看到 Python 和 pip 可执行文件来自我们的虚拟环境。一切都好。🙂
安装依赖项
本教程唯一的依赖项是Boto3
库。因此,让我们继续在我们的虚拟环境中安装它。
$ ~/demo/batch-ops-dynamodb (venv) > pip install boto3Collecting boto3
Downloading boto3-1.11.7-py2.py3-none-any.whl (128 kB)
|████████████████████████████████| 128 kB 1.0 MB/s
Collecting botocore<1.15.0,>=1.14.7
Downloading botocore-1.14.7-py2.py3-none-any.whl (5.9 MB)
|████████████████████████████████| 5.9 MB 462 kB/s
Collecting s3transfer<0.4.0,>=0.3.0
Downloading s3transfer-0.3.1-py2.py3-none-any.whl (69 kB)
|████████████████████████████████| 69 kB 2.1 MB/s
Collecting jmespath<1.0.0,>=0.7.1
Using cached jmespath-0.9.4-py2.py3-none-any.whl (24 kB)
Collecting urllib3<1.26,>=1.20
Downloading urllib3-1.25.8-py2.py3-none-any.whl (125 kB)
|████████████████████████████████| 125 kB 5.3 MB/s
Collecting python-dateutil<3.0.0,>=2.1
Using cached python_dateutil-2.8.1-py2.py3-none-any.whl (227 kB)
Collecting docutils<0.16,>=0.10
Using cached docutils-0.15.2-py3-none-any.whl (547 kB)
Collecting six>=1.5
Downloading six-1.14.0-py2.py3-none-any.whl (10 kB)
Installing collected packages: urllib3, six, python-dateutil, docutils, jmespath, botocore, s3transfer, boto3
Successfully installed boto3-1.11.7 botocore-1.14.7 docutils-0.15.2 jmespath-0.9.4 python-dateutil-2.8.1 s3transfer-0.3.1 six-1.14.0 urllib3-1.25.8
一旦您完成了先决条件,我们就可以开始做有趣的事情了,那就是编写实际的脚本来批量删除我们的垃圾记录。
启动本地 DynamoDB 实例
为了帮助我们了解脚本是如何工作的,我们将在 Docker 容器中启动一个本地 DynamoDB 实例。你可以按照这个教程来实现这个。
本质上,你需要做的是启动 DynamoDB Docker 并创建教程中写的表demo-customer-info
。
在表中创建虚拟记录
让我们创建虚拟记录,这样我们可以看到批处理操作是如何工作的。为此,我们将编写一个 Python 脚本,在一个循环中调用 DynamoDB PutItem
操作。在batch-ops-dynamo
中新建一个 Python 文件,命名为insert_dummy_records.py
。
~/demo/batch-ops-dynamodb ❯ touch insert_dummy_records.py
正如前面介绍部分提到的,我们的虚拟记录将具有以下特征:
- 姓氏以
TEST
开头 - 电子邮件地址以
testing
开头
我们的脚本将包含以下组件:
insert_dummy_record
:执行PutItem
操作的功能for loop
:将调用insert_dummy_record
函数 10 次以插入虚拟记录的循环。
我们还利用random.randint
方法生成一些随机整数,添加到我们的虚拟记录的属性中,它们是:
customerId
lastName
emailAddress
insert _ dummy _ records.py 将虚拟记录插入到表中
我们的剧本看起来不错!现在,是时候从命令行运行它了,使用来自我们虚拟环境的 Python 可执行文件。
~/demo/batch-ops-dynamodb ❯ python3 insert_dummy_records.pyInserting record number 1 with customerId 769
Inserting record number 2 with customerId 885
Inserting record number 3 with customerId 873
Inserting record number 4 with customerId 827
Inserting record number 5 with customerId 231
Inserting record number 6 with customerId 199
Inserting record number 7 with customerId 272
Inserting record number 8 with customerId 268
Inserting record number 9 with customerId 729
Inserting record number 10 with customerId 289
好的。这个脚本看起来像预期的那样工作。万岁!😄
让我们通过调用本地 DynamoDB demo-customer-info
表上的scan
操作来检查记录。
~/demo/batch-ops-dynamodb ❯ aws dynamodb scan --endpoint-url [http://localhost:8042](http://localhost:8042) --table-name demo-customer-info{
"Items": [
{
"customerId": {
"S": "199"
},
"lastName": {
"S": "TEST199"
},
"emailAddress": {
"S": "[testing199@dummy.com](mailto:testing199@dummy.com)"
}
},
{
"customerId": {
"S": "769"
},
"lastName": {
"S": "TEST769"
},
"emailAddress": {
"S": "[testing769@dummy.com](mailto:testing769@dummy.com)"
}
},
... truncated
... truncated
... truncated
{
"customerId": {
"S": "827"
},
"lastName": {
"S": "TEST827"
},
"emailAddress": {
"S": "[testing827@dummy.com](mailto:testing827@dummy.com)"
}
}
],
"Count": 10,
"ScannedCount": 10,
"ConsumedCapacity": null
}
完美!我们的表中现在有一些虚拟记录。
将“真实”记录插入表中
我们将快速向表中插入两条“真实”的记录。为此,我们将编写另一个 Python 脚本,它将命令行参数作为输入。我们把这个文件命名为insert_real_record.py
。
~/demo/batch-ops-dynamodb ❯ touch insert_real_record.py
该文件的内容如下。
insert _ real _ record.py 将“真实”记录插入到表中
让我们继续向表中插入 2 条记录。
~/demo/batch-ops-dynamodb ❯ python insert_real_record.py 11111 jones [sam.jones@something.com](mailto:sam.jones@something.com)Inserting record with customerId 11111~/demo/batch-ops-dynamodb ❯ python insert_real_record.py 22222 smith [jack.smith@somedomain.com](mailto:jack.smith@somedomain.com)Inserting record with customerId 22222
编写根据条件删除记录的脚本
最后,我们将编写脚本,从表中删除满足某些指定条件的记录。
再次提醒,我们要删除我们插入的虚拟记录。我们需要应用的过滤器是姓氏以TEST
开头,电子邮件地址以testing
开头。
脚本的工作原理:
- 用给定的过滤表达式在表上执行
scan
操作 - 只从所有记录中检索符合我们的过滤表达式的
customerId
属性,因为这是我们做DeleteItem
操作所需要的。记住,customerId
是表的分区键。 - 在
for loop
中,对于我们scan
操作返回的每个customerId
,进行DeleteItem
操作。
Delete _ records _ conditionally . py-按过滤器删除记录
继续从命令行运行这个脚本。
~/demo/batch-ops-dynamodb ❯ python delete_records_conditionally.pyGetting customer ids to delete
============
['199', '769', '873', '268', '289', '231', '272', '885', '729', '827']
Deleting customer 199
Deleting customer 769
Deleting customer 873
Deleting customer 268
Deleting customer 289
Deleting customer 231
Deleting customer 272
Deleting customer 885
Deleting customer 729
Deleting customer 827
太好了!该脚本按预期工作。现在,让我们检查表中剩余的记录。
~/demo/batch-ops-dynamodb ❯ aws dynamodb scan --endpoint-url [http://localhost:8042](http://localhost:8042) --table-name demo-customer-info{
"Items": [
{
"customerId": {
"S": "22222"
},
"lastName": {
"S": "smith"
},
"emailAddress": {
"S": "[jack.smith@somedomain.com](mailto:jack.smith@somedomain.com)"
}
},
{
"customerId": {
"S": "11111"
},
"lastName": {
"S": "jones"
},
"emailAddress": {
"S": "[sam.jones@something.com](mailto:sam.jones@something.com)"
}
}
],
"Count": 2,
"ScannedCount": 2,
"ConsumedCapacity": null
}
只剩下 2 条记录,这是我们插入的“真实”记录。我们现在可以确定我们的delete_records_conditionally.py
脚本做了它想要做的事情。
很棒的东西。👍
删除脚本的一些细节
让我们来看看我们刚刚编写的delete_records_conditionally.py
脚本中的一些内容。
注意,我们有一个deserializer
,我们用它来获取customerId
。原因是因为,scan
操作实际上会返回这样的结果。
# scan operation response{'Items': [{'customerId': {'S': '300'}}, {'customerId': {'S': '794'}}, {'customerId': {'S': '266'}}, {'customerId': {'S': '281'}}, {'customerId': {'S': '223'}}, {'customerId': {'S': '660'}}, {'customerId': {'S': '384'}}, {'customerId': {'S': '673'}}, {'customerId': {'S': '378'}}, {'customerId': {'S': '426'}}], 'Count': 10, 'ScannedCount': 12, 'ResponseMetadata': {'RequestId': 'eb18e221-d825-4f28-b142-ff616d0ca323', 'HTTPStatusCode': 200, 'HTTPHeaders': {'content-type': 'application/x-amz-json-1.0', 'x-amz-crc32': '2155737492', 'x-amzn-requestid': 'eb18e221-d825-4f28-b142-ff616d0ca323', 'content-length': '310', 'server': 'Jetty(8.1.12.v20130726)'}, 'RetryAttempts': 0}}
由于我们只对customerId
的值感兴趣,我们需要使用 Boto3 库提供的TypeDeserializer
去序列化 DynamoDB 项。
另一个值得一提的组件是Select
和ProjectionExpression
,它们是scan
函数的参数。这两个参数密切相关。我们将Select
的值设置为SPECIFIC_ATTRIBUTES
,根据 Boto3 官方文档,这将只返回AttributesToGet
中列出的属性。AttributesToGet
已被标记为遗留参数,AWS 建议我们改用ProjectionExpression
。
来自 Boto3 官方文档:
如果使用 ProjectionExpression 参数,则 Select 的值只能是 SPECIFIC_ATTRIBUTES。Select 的任何其他值都将返回错误。
这 2 个参数基本上是在说scan
操作应该只返回customerId
属性,这是我们需要的。
最后,我们使用 AWS 提供的begins_with()
函数。这个函数使用属性名和前缀来检查指定属性的值。
包裹
至此,您已经学会了如何使用 Python 和 Boto3 插入和删除 DynamoDB 记录。您当然可以调整和修改脚本来满足您的需要。例如,本教程中使用的过滤器表达式相对简单,如果需要,您可以添加更复杂的条件。
不管怎样,我希望这篇教程已经让你对如何使用 Python 进行 DynamoDB 操作有了基本的了解。所以,继续发挥你的创造力,利用这个脚本,增强它,做更高级的东西。黑客快乐!🙂
注:这里是 Github 回购。
安东尼奥·加波拉在 Unsplash 上的照片
如何为 Python 轻松安装 Spark
分三步在 Windows 10 上安装 PySpark
费德里科·贝卡里在 Unsplash 上的照片
简介
当我们处理大数据时,我们需要更多的计算能力,这可以通过多台计算机的分布式系统来实现。此外,为了有效地融入大数据生态系统,我们还需要一个集群计算框架,允许我们在大型数据集上快速执行处理任务。
两个最著名的集群计算框架是 Hadoop 和 Spark,它们都是免费开源的。
如果要比较 Apache Spark 和 Hadoop,可以说 Spark 在内存上快 100 倍,在磁盘上快 10 倍。
对于 on-perm 安装,Hadoop 需要更多的磁盘内存,Spark 需要更多的 RAM,这意味着建立一个集群可能非常昂贵。
今天,我们可以通过 AWS 和 Azure 提供的云计算服务来解决这个问题。如果您有兴趣了解更多关于它们的信息,特别是像云数据仓库这样的主题,让我向您推荐我的文章,您可以在这里找到。
相反,在本文中,我将向您展示如何安装名为 Pyspark 的 Spark Python API。在 Windows 10 上安装 Pyspark 需要遵循一些不同的步骤,有时我们会忘记这些步骤。所以,通过这篇文章,我希望给你一个有用的指南,让你毫无问题地安装 Pyspark。
第一部分:检查您的 Java 版本并下载 Apache Spark
我假设你的电脑上至少有 Python 版本。
所以,要运行 Spark,我们首先需要安装的是 Java。建议有 Java 8 或者 Java 1.8。
因此,打开命令提示符,用下面的命令控制 Java 的版本。如果你有老版本,可以在这里下载。
Java -version
出局:
作者图片
现在,我们必须下载 Spark,您可以在这里轻松找到。以下框架显示了您在站点中看到的步骤。
Download Apache Spark1\. Choose a Spark release: 3.0.0(Jun 18 2020)--selected2\. Choose a package type: Pre-built for Apache Hadoop 2.7 --selected3\. Download Spark: [spark-3.0.0-bin-hadoop2.7.tgz](https://www.apache.org/dyn/closer.lua/spark/spark-3.0.0/spark-3.0.0-bin-hadoop2.7.tgz)
上面你可以观察到我如何设置我的 Spark 版本。我选择了最近的 Spark 版本和 Apache Hadoop 2.7 的预构建包。
然后在第三步中,我们可以通过点击链接来下载我们的 Spark 版本,这将打开另一个网页,在该网页中,您必须点击建议的第一个下载版本。
下载完成后,将压缩文件解压到名为 spark 的文件夹中。记住这个文件夹的路径将在下一部分使用。
第二部分:下载 winutils.exe 并设置您的环境
第二步是下载winutils.exe你可以在这里找到。我的情况是选择了 hadoop-3.0.0 的版本,我下载了。你可以创建一个名为 winutils 的文件夹并把它放在那里。
现在,是时候建立我们的环境了。首先要做的是进入 windows 搜索栏,输入**“编辑系统环境变量”**。
去点击环境变量。
作者图片
当你将在系统变量的组中,创建三个名为 HADOOP_HOME 、 SPARK_HOME 和 JAVA_HOME 的变量。
- 在HADOOP _ HOME→放之前创建的位置 wintulis 文件夹的路径。
- 在SPARK _ HOME→放入你之前创建的 spark 文件夹的位置路径。
- 在 JAVA_HOME 中→放入你的 JAVA 程序的位置路径。
在下图中,你可以看到如何设置你的变量。
作者图片
作者图片
然后在变量路径下面可以看到,我们可以添加以下两条路径:
- %SPARK_HOME%\bin
- %JAVA_HOME%\bin
作者图片
第三部分:在你的蟒蛇身上运行它,飞到朱庇特
现在您可以打开 Anaconda 提示符,将目录更改为 SPARK_HOME 目录,并键入 bin\pyspark。
出局:
作者图片
所以,你准备飞往 Jupyter,用下面的代码尝试 Pyspark。如果没有错误,这意味着您的 Pyspark 已经正确安装。
import findspark
findspark.init()
结论
现在您已经有了 Pyspark,您可以开始通过进行一些数据操作来学习和练习它是如何工作的。如果你在安装上有困难,请随时联系我。
我发出一份期刊简讯。如果你想加入,请点击此链接报名。
除了我的简讯,还可以在我的电报群 数据科学初学者 中取得联系。
如何安装 MySQL 并创建雇员示例数据库
安装数据库以练习 SQL 的分步指南
数据科学家和分析师应该能够用 SQL 编写和执行复杂查询。如果您刚刚开始使用 SQL,或者正在寻找一个沙盒来测试查询,那么本指南就是为您准备的。
有一些很棒的 SQL 资源,比如 HackerRank 、 LeetCode 和 W3Schools ,但是我认为提高熟练程度的最好方法之一是使用您选择的 SQL 编辑器来练习您自己的数据库。
在本指南中,我们将完成以下步骤:
- 在 macOS 上安装 MySQL
- 添加 MySQL shell 路径
- 创建用户帐户
- 使用雇员数据创建示例数据库
- 编写 SQL 查询
什么是 MySQL?
MySQL 是最流行的开源 SQL 数据库管理系统,由 Oracle 公司开发。由
Stack Overflow 进行的 2020 年开发者调查从受欢迎程度方面证实了这一说法,如下所示。
https://insights . stack overflow . com/survey/2020 #技术-数据库
在 macOS 上安装 MySQL
我们将使用位于磁盘映像中的本地包来安装 MySQL 社区服务器 8.0.x。dmg)。
下载。dmg 版本从这里(找 DMG 存档)。这个版本将初始化数据目录并创建 MySQL 授权表。
https://dev.mysql.com/downloads/mysql/
点击Download
按钮后,你将被带到一个页面,要求你“登录”或“注册”一个免费账户。点击
No thanks, just start my download
可以绕过。
转到下载的文件,right click
和Open.
跟着指示走,直到你到达Configuration.
对于Configuration
,选择默认的Use Strong Password Encryption
。点击这里阅读更多关于 MySQL 密码的信息。
输入root
用户的密码。root 帐户是默认的超级用户帐户,拥有所有 MySQL 数据库的所有权限。
MySQL 现已安装。如果你打开System Preferences
,你应该在你的面板中看到 MySQL,如下图所示。
macOS ‘系统偏好设置’
MySQL 偏好设置面板使您能够在 MySQL 安装的引导过程中启动、停止和控制自动启动。
MySQL 偏好设置面板
如果实例是而不是已经在运行,打开它并点击
Start MySQL Server
。绿点表示服务器正在运行。
为了节省内存Start MySQL when your computer starts up
,我个人没有选中这个框*。*
记得重启后启动服务器就行了。
在 macOS 中添加 MySQL Shell 路径
macOS 中用户的外壳路径是文件系统中的一组路径,由此用户有权使用某些应用程序、命令和程序,而无需在终端中指定该命令或程序的完整路径。
以下步骤将使我们能够在命令行(终端)的任何工作目录中输入命令mysql
。
注意 zsh (Z shell)是 macOS Catalina 的默认 shell。如果你在不同的版本上,你可以试着使用下面的 bash 命令。
- 打开终端(
⌘+Space
,输入Terminal
) - 一旦你进入终端,输入
cd
进入主目录 - 如果你正在使用 zsh ,键入
nano .zshrc
T28【如果你正在使用 bash ,键入nano .bash_profile
- 复制并粘贴这两个别名:
alias mysql=/usr/local/mysql/bin/mysql
alias mysqladmin=/usr/local/mysql/bin/mysqladmin
请注意,MySQL 前的井号(#)是注释行
5.保存文件control + O
,用Enter
确认,用control + X
退出。
6。Quit
( ⌘+Q
)终端并重新打开它
要测试服务器,请输入以下命令(您需要输入安装 MySQL 时创建的密码):
mysqladmin -u root -p version
创建用户帐户(可选)
您可能不想一直使用 root 帐户。您可以创建各种帐户并授予不同级别的权限。以下是步骤:
以 root 用户身份登录:
mysql -u root -p
在下面的命令中,用您选择的用户名和密码替换user
和password
。我建议您使用与 macOS 系统用户名相同的名称创建一个帐户。
CREATE USER ‘user’@‘localhost’ IDENTIFIED BY ‘root-password’;
以下语句将授予用户帐户对所有数据库的所有权限。用您选择的用户名替换user
。使用引号(')。
GRANT ALL ON *.* TO ‘user’@‘localhost’ WITH GRANT OPTION;
这里有一个示例用户(miguel ),使用密码(pass)创建,并被授予完全访问权限(。)
尝试使用新创建的用户登录。首先,键入QUIT
结束当前会话,并使用新凭证登录。例如:
mysql -u miguel -p
提示:因为‘Miguel’也是我的系统用户名,我可以简单地输入
mysql -p
并省略-u miguel
部分。
键入QUIT
,但停留在终端并继续下一部分。
创建雇员数据库
雇员样本数据库由帕特里克·克鲁斯和朱塞佩·马霞开发,包含 400 万条记录。它包含虚假的员工数据,如工资、姓名、职称等。以下是模式:
https://dev.mysql.com/doc/employee/en/sakila-structure.html
首先,去 GitHub 上的员工数据库下载回购。
点击Code
下载回购协议👉Download ZIP
。
用户“miguel”在终端中的逐步过程
在“终端”中,切换到您存储文件的目录。就我而言:
cd Downloads
运行以下命令解压文件:unzip test_db-master.zip
如果不成功,您可以在 Finder 中手动打开文件test_db-master.zip
。
将目录切换到解压后的文件夹:
cd test_db-master
现在您已经准备好安装数据库了。键入以下命令(用您自己的用户名替换user
)。
mysql -u user -p < employees.sql
要测试安装,运行以下命令(替换user
)。
mysql -u ‘user’ -p < test_employees_md5.sql
编写 SQL 查询
下面的笔记本包含几个简单的问题,让你开始。
你也可以在 Jupyter Nbviewer 上查看笔记本:
nbviewer.jupyter.org](https://nbviewer.jupyter.org/gist/corralm/7508d7120f36a13f68774fab13656dd7#Select-all-the-rows-in-the-employees-table)
如果您对在 Jupyter 中运行 SQL 查询感兴趣,请查看我的指南:
[## 如何在 Jupyter 中用 Pandas 运行和分析 SQL 查询
在 Jupyter 笔记本中运行 SQL 并在 Pandas 中进行分析的快速指南。
medium.com](https://medium.com/@corraljrmiguel/how-to-run-and-analyze-sql-queries-with-pandas-in-jupyter-7f02503cf46)
如果您有任何问题或意见,请告诉我。谢谢!
如何在 Windows 上安装 TensorFlow 2 对象检测 API
对最初的基于 Docker 的教程进行了一些修正
在 Unsplash 上由 You X Ventures 拍摄。使用本教程中提供的代码进行对象检测
R 最近,我需要为正在进行的概念验证运行一个对象检测模型。由于我使用的是 TensorFlow 2,对象检测 API 看起来很合适。然而,不幸的是,安装过程比看起来要麻烦得多,而且官方文档是基于 Docker 的,这对一个普通的 pip 包来说似乎是一个不必要的负担。长话短说,我卷起袖子穿过它,一步一步修复,直到它工作。在这里,我向你介绍如何做。
**免责声明:**我并不是以任何方式反对 Docker。
摘要
- 先决条件
- 在 Windows 上安装 pycocotools
- 介绍对象检测 API
- 测试您的安装
- 结束语
先决条件
我假设您熟悉 Python,正在使用某种虚拟环境,并且熟悉 TensorFlow。我使用 TensorFlow 2.3 和 Python 3.7.6 进行了安装过程。前者可能会在此过程中更新,因此如果您需要特定的版本,请记住这一点。
除了 Python 环境,您还需要一个文本编辑器和一个 Git 客户机。
如果你不是 TensorFlow 用户或数据科学家,只是想让对象检测算法工作,除了 Python 之外的所有依赖项都会被安装,所以你不需要自己安装 TensorFlow。在本文的最后,我提供了一个代码片段来对一个测试图像运行对象检测,以后您可以根据需要修改它。
在 Windows 上安装 pycocotools
TF 的许多对象检测 API 模块依赖于 pycocotools 包,该包无法通过 pip 安装在 Windows 上。如果您已经安装了这个包,您可以安全地跳过这一部分。如果没有,请按照下列步骤操作:
- 克隆官方知识库
- 导航到 PythonAPI 文件夹并打开 setup.py 文件
- 将第 12 行编辑为
extra_compile_args=[]
。这里的基本原理是删除特定的铿锵论点,这在 MVCC 不起作用。 - 在 CMD 终端的 PythonAPI 文件夹中,运行:
python setup.py build_ext --inplace
这最后一个命令将在您当前的环境中构建和安装这个包,准备就绪。为了测试安装是否成功,启动 Python 并将其导入为:import pycocotools
。
你可能会问,我们是否不应该添加 MVCC 特有的旗帜来取代铿锵的旗帜。我也有同样的疑惑,但是它工作得很好,我没有遇到任何错误。据我所知,最初的 Clang 标志是用来禁用某些警告并强制 C99 遵从性的。
安装对象检测 API
准备好 coco 工具后,我们可以转到实际的对象检测 API。遵循这些步骤(注意有些命令以点结束!):
- 克隆 TensorFlow 模型库。这个 repo 是一组 TF 相关项目的保护伞,Object Detection API 就是其中之一。
- 导航到”。/research/object _ detection/packages/tf2/"并编辑 setup.py 文件。从必需 _ 包列表中,删除 pycocotools 引用(第 20 行)。这一改变将防止安装过程试图从 pip 重新安装 pycocotools ,这将失败并中止整个过程。
- 将这个 setup.py 文件复制到。/research”文件夹,替换已经存在的 setup.py 。
- 打开研究文件夹中的 CMD,用
protoc object_detection/protos/*.proto --python_out=.
编译协议缓冲区 - 如果前面的命令有效,应该不会出现任何内容。我知道这不是最直观的东西。之后,运行下面的:
python -m pip install .
如果我解释的一切都正确,并且你严格按照字面意思去做,安装过程应该会很顺利,大量的软件包现在已经安装到你的系统中了。
如果您的系统上没有protocol命令,您需要做的就是下载一个协议缓冲库的预编译版本,并将其添加到您的系统路径(或将其放在 Windows/system32/😈).
奇怪的是,对我来说,在这一切之后,我的 OpenCV 和 MatplotLib 包不再显示数字(cv2 . im show/PLT . show)。我通过使用pip install -U opencv-python opencv-contrib-python matplitlib
重新安装两个包修复了这个问题。如果任何其他软件包在安装对象检测 API 后出现故障,尝试像我上面做的那样从 pip 更新它。
测试您的安装
有两种方法可以确定您当前的安装是否正确。第一个是运行库测试套件。在研究文件夹下打开 CMD,运行:
python object_detection/builders/model_builder_tf2_test.py
它应该打印很多东西,并告诉你所有的测试都成功了。
第二种方法是下载一个模型,并尝试用它进行一些推断。这里是用于推理和训练的官方协作笔记本。我不是笔记本的粉丝,所以这里是我的测试脚本,它期望一个test.png文件作为输入,一个 coco 标签图(你可以在这里找到),以及 CenterNet 模型。将所有内容放在一个文件夹中,并将下面的脚本添加到这个文件夹中:
最后,应该会弹出一个包含原始图像和检测覆盖图的图像,还应该会创建一个名为output.png的新文件。
这篇文章的封面图片是使用上面的脚本和来自 Unsplash 的这张图片生成的。如果一切都设置正确,并且您使用此图像作为输入,您应该得到与我相同的结果。
我希望这有助于您使用 TensorFlow 2 对象检测 API,并使您能够使用开箱即用的模型进行推理和训练。有了上面的脚本,应该不难理解如何在您的管道上应用这个 API,并将其更改为使用其他模型。有关实现及其质量/速度权衡的列表,请参考此列表。
如果您对本教程有任何问题,请留下您的评论,我将非常乐意帮助您跟踪问题,并用更新的信息更新本文。
如果你刚接触媒体,我强烈推荐订阅。对于数据和 IT 专业人员来说,中型文章是 StackOverflow 的完美组合,对于新手来说更是如此。注册时请考虑使用我的会员链接。你也可以直接给我买杯咖啡来支持我
感谢您的阅读:)
如何将细分网络模型与您的 iPhone 应用程序集成
Arnel Hasanovic 在 Unsplash 上拍摄的照片
分割图像中的感兴趣区域(ROI)是计算机视觉中的一个关键问题。随着深度学习的兴起,许多网络架构被提出来克服语义分割的挑战。几年前,在智能手机中部署一个经过训练的细分网络模型还远远不现实。然而,由于最近智能手机中的强大硬件加上我们可以使用的强大软件工具,在您的智能手机应用程序中部署一个分段网络只需要几行代码!
本文将带您完成将一个经过训练的细分模型与您的 iPhone 应用程序集成的过程。这个过程包括两个步骤:(1) 将模型转换为。mlmodel 格式和(2) **使用转换后的模型分割 ROI。**为了让我们自己熟悉这两个步骤,我们将使用(使用 Keras 框架)训练的 U-Net 模型来分割外部眼睛图像的巩膜区域。
第一步:将模型转换为移动兼容格式
将 keras 模型转换为。mlmodel 格式,我们可以使用coremltools
python 库。可以使用以下命令安装它。
pip install coremltools
安装库之后,下面的代码片段允许您执行转换,并将转换后的模型保存在指定的位置。
将. h5 模型文件转换为. ml 模型文件
步骤 2:使用转换后的模型分割 ROI
在获取。mlmodel 文件,将其拖放到 Xcode 导航区域的项目文件夹中。swift 中的Vision
库允许您使用。mlmodel 文件,当您将它与应用程序集成时。
我们首先将库——在本例中是UIKit
和Vision
——导入我们的代码,如下所示。
import UIKit
import Vision
然后我们用UIImagePickerControllerDelegate
定义我们的 **class** ViewController
,允许我们从我们的照片库中挑选一张图片。为了简单起见,我们不会在应用程序中添加任何文本字段或标签。
**class** ViewController: UIViewController,
UIImagePickerControllerDelegate,
UINavigationControllerDelegate { }
在这个类中,我们可以开始定义构建我们的应用程序的函数。首先,我们定义UIImageView
属性,该属性将显示从照片库中选择的外部眼睛图像和分割结果。
**@IBOutlet** **weak** **var** photoImageView: UIImageView!
然后,我们可以通过下面的命令来定义分割模型。
**let** SegmentationModel = ScleraUNet()
然后我们定义视觉属性request
和visionModel
。
**var** request: VNCoreMLRequest?
**var** visionModel: VNCoreMLModel?
现在我们写一个设置 SegmentationModel
和request
的函数。
建立模型
这里你可以注意到VNCoreMLRequest
的completionHandler
被设置为一个我们还没有定义的叫做visionRequestDidComplete
的函数。在visionRequestDidComplete
功能中,我们可以包括在request
使用分割模型输出分割掩模后应该执行的动作。我们将在本文后面定义visionRequestDidComplete
函数。
为了在应用程序加载后设置模型,我们在**class** ViewController
中添加了以下代码片段
**override** **func** viewDidLoad() {**super**.viewDidLoad()print("Setting up model...")
setupModel()
print("Model is ready")nameTextField.delegate = **self**}
现在我们可以编写函数,让我们从照片库中选择一个外部眼睛图像。
这样,我们可以通过photoImageView.image
访问所选图像。
此外,我们希望有一个交互式按钮,将执行按下分割过程。
**@IBAction** **func** segementImage(**_** sender: UIButton){print("Segmenting... ")**let** input_image = photoImageView.image?.cgImagepredict(with: input_image!)}
按下按钮时,上述功能激活并运行predict
功能。我们将在后面定义这个predict
函数。
将上述代码片段添加到我们的代码中后,它会是这样的:
现在我们的代码差不多完成了。但是我们必须定义前面留下的visionRequestDidComplete
和predict
函数。我们将它们定义在**class** ViewController
下面的**extension** ViewController
中,如下所示。
在visionRequestDidComplete
中,我们定义了模型预测分割结果后必须完成的任务。在这种情况下,我们希望将分割结果二值化并显示在我们之前定义的photoView
上。
在我们的代码中添加了**extension** ViewController
之后,它看起来会如下所示。
为了进一步完善我们的工作,我们可以在 UI 中添加一些标签、按钮和文本字段。在本例中,我们添加了几个标签、一个清除按钮和一个文本字段,该字段接受外部眼睛图像所属的主题名称。这里有一些我们新创建的简单应用程序运行的截图,它可以从给定的外部眼睛图像中分割巩膜区域。
左:应用程序的打开视图,中:从照片库中选择外部眼睛图像后的视图,右:巩膜区域被分割后的视图。(图片由作者提供)
也可以在原始图像上叠加分割蒙版,但不包括在这项工作中。
本文到此结束!希望它能帮助你将一个细分模型恰当地整合到你的 iPhone 应用中。