2021 年数据+人工智能峰会亮点💥
崇高的紫色夜空。【数码影像】https://unsplash.com/@文森特
又来了,我最喜欢的免费数据会议之一!这个名字已经被重新命名为更好。最初是“火花峰会”,后来是“火花+AI 峰会”,现在是“数据+AI”峰会。Databricks 现在提供几个产品,它不再仅仅被认为是“火花公司”。我下面谈论的很多内容与我去年的重点在这里的趋势相同。但是 Databricks 今年发布了很多有趣的产品!
增量共享
这个新的 Databricks 产品被定义为业界第一个安全数据共享的开放协议。
随着公司转向多云以及云数据仓库的兴起,在数据可用性方面存在巨大挑战。数据工程师花费大量时间移动/复制数据,以便在不同的地方以经济高效和安全的方式访问和查询数据。
Delta sharing 旨在通过存储“once”并在任何地方读取它来解决这一问题。它使用中间件(增量共享服务器)在阅读器和数据提供者之间进行交流。
在我看来,理论上的 Delta 共享是自 Delta 格式以来最大的产品发布。然而,有一些问题值得一提:
- 尽管 Databricks 声称查询是优化的并且便宜,但我认为我们需要考虑出口/入口云的成本。如果数据接收者正在做一个没有优化的难看的查询,会发生什么?
- 只要全球采用,任何开放标准听起来都有希望。尽管如此,德尔塔显然比他们的其他酸性格式兄弟(如冰山和胡迪)更有吸引力,所以它绝对是最好的赌注。
Delta 活动表
另一个 Delta Databricks 产品!您可以从一个增量表中将它视为一个超级强大的“视图”,您可以使用纯 SQL 或 python 进行处理。您可以创建整个数据流,并基于单个增量活动表创建多个表。delta live 引擎足够智能,可以进行缓存和检查点操作,只处理需要的内容。
这非常有趣,因为在数据湖架构(原始/青铜/白银)中,不是将数据的多个副本视为经典的数据管道,而是有一个真实的来源。这使得清晰的谱系成为可能,因此也是转换的良好文档。
此外,因为数据质量很热门(见下文),Databricks 添加了他们自己的数据质量工具,带有声明性的质量期望。
Unity 目录
Databricks 正在推出自己的数据目录。数据目录是数据行业的另一个趋势。主要开源项目的开发(如阿蒙森、数据中心等)。)去年一直保持这个速度。与此同时,其他大型云提供商,如谷歌,也发布了他们自己的数据目录。最重要的是,随着公司越来越多地转向云计算战略,数据发现和治理成为一个更大的问题。
Databricks 用自己的目录解决的一个有趣的问题是,他们希望通过更高的 API 来简化数据访问管理。这是其他解决方案没有真正关注的,这是一个主要的优势,因为管理低级别的访问(例如基于文件的权限,如 s3 或 GCS)可能非常棘手。细粒度的权限是困难的,并且数据的布局并不真正灵活,因为它常常被像 Hive/Glue 这样的 metastore 所限制。
更多 python
数据档案(数据科学家、数据工程师、数据分析师、ML 工程师等)之间的最大共同点。)可能是 SQL,第二个可能是 python。根据 Databricks 的数据,如今大多数 spark API 调用都是通过 Python (45%)和 SQL (43%)完成的。
很明显,Databricks 希望缩小“笔记本电脑数据科学”和分布式计算之间的差距。降低准入门槛将使更多的用户从事人工智能,并为数据 SAAS 公司带来更多资金😉由于 python 被广泛采用,并且对初学者友好,所以投资 python 是有意义的。
大多数改进都被称为“禅计划”,其中包括:
- pyspark 日志的可读性
- 类型提示改进
- 更智能的自动完成提及
熊猫天生就有火花
如果你不熟悉考拉项目,它是 Apache Spark 之上的熊猫 API。考拉项目将通过 Spark 合并。只要有 spark 数据框,就有 pandas 数据框,无需进行显式转换。
当然,对于小数据用例,Spark 在独立的节点集群上仍然是一个开销,但是它可以在不改变代码库的情况下进行扩展,这非常方便。
构建低代码工具以使数据工程/数据科学民主化
令人难以置信的是,今年有这么多关于 ETL 管道和数据质量框架的讨论。这又是对我去年谈到的趋势的双重押注。许多公司希望降低数据工程的准入门槛,其动机是
- 通过 ETL 降低增加可重用性的复杂性
- 元数据和配置驱动的 ETL。配置可以作为数据流的文档
- 使 SQL 开发人员更容易编写生产就绪的管道,并扩大贡献者的范围。
结论
很高兴看到 Databrick 的产品目录不断增加。感觉他们更倾向于整合战略,而不是试图成为下一个你可以运行一切的平台(即使这也是他们正在销售的)。
但是,围绕 delta 的主要产品也依赖于供应商的采用,所以让我们看看数据社区采用它的速度有多快!
资源:
数据+AI 主题演讲,https://www.youtube.com/playlist?list = PLTPXxbhUt-ywquxdhuxgu 8 ehj 3 bjbhfe
迈赫迪·瓦扎又名迈赫迪欧·🧢
感谢阅读!🤗 🙌如果你喜欢这个,跟随我上🎥 Youtube ,✍️ 中型 ,或者🔗 LinkedIn 了解更多数据/代码内容!
支持我写作 ✍️通过加入媒介通过这个链接
来自数据+人工智能峰会 NA 2021 的亮点
与 Apache Spark 新特性相关的数据+人工智能峰会笔记
照片由大卫·特拉维斯在 Unsplash 上拍摄
数据领域最大的会议之一— Data + AI Summit 北美 2021 上周发生了,这次我没有用自己的演讲做出贡献,但作为一名听众,我越来越喜欢这些会议。
在这篇简短的报告中,我想总结一下我在 Apache Spark 内部和最佳实践主题中讨论的 Spark 3.1 和即将推出的 3.2 中的新特性。
禅宗项目
Zen 项目开始于一年前,目标是让 Spark 对 Python 用户更加友好。
类型提示
其中一个步骤是添加类型提示,例如允许 ide 和笔记本环境中的自动完成,这样可以使开发更加高效。对类型提示的完全支持是在最新版本 3.1.1 中添加的。
星火上的熊猫
Spark 3.2 的一个新特性是将考拉项目集成到 Spark 中。考拉允许使用 Pandas API,同时将 Spark 作为后端,因此,如果数据科学家使用 Pandas 进行数据操作,并由于数据量大而遇到性能问题,那么很容易切换到考拉,代码保持不变,但在幕后,执行在 Spark 中进行。现在,当考拉将被集成到 Spark 中时,情况变得更加简单,你可以从 Spark 中导入熊猫并使用熊猫 API,同时在引擎盖下有 Spark。熊猫的绘图和可视化工具现在可以在 Spark 中使用了。
本次峰会讨论了 Zen 项目:
性能改进
随着 Spark 的每一次发布,发动机的性能都在不断提高。在峰会上,我们讨论了几个与绩效相关的话题:
混合散列连接(SHJ)
混合散列连接是 Spark 中用于连接数据的算法之一。在实践中,它被避免使用,取而代之的是更健壮的排序合并连接(SMJ)。如果数据不对称,并且其中一个分区太大,SHJ 会导致 OOM 错误。然而,在合理的情况下,SHJ 可以比 SMJ 执行得更快,因为它避免了这种情况。(关于 Spark 使用的算法和决策逻辑的更多细节,请参见我的相关文章关于 Spark 3.0 中的加入的文章
3.1 中实现了几项增强功能,使 SHJ 变得更好、更可用:
在这次首脑会议期间,讨论了 SHJ 的改进和其他改进:
…向量化…
矢量化是一种同时处理多行以加快处理速度的技术。在 Spark 的当前版本中,当使用矢量化读取器从 parquet 和 orc 格式读取数据时,会使用矢量化。除此之外,PySpark 中的熊猫 UDF 也支持矢量化。
实现矢量化的一种方法是使用现代硬件支持的 SIMD 指令(单指令,多数据)。当前版本的 Spark 没有明确使用 SIMD,因为 JVM 中的 HotSpot 编译器在某些情况下会生成 SIMD 指令,但在某些情况下不会。然而,新的 Java 16 有 VectorAPI 可用,这个 API 可以确保 SIMD 指令被使用。因此,使用这个 VectorAPI ,可以在 Spark 中为生成的代码实现显式矢量化。本次峰会讨论了矢量化:
标准压缩编解码器
Apache Spark 支持各种压缩算法,例如,snappy 是将数据保存到 parquet 文件时使用的默认算法,另一方面,lz4 用于 shuffle 文件,也支持其他编解码器。ZStandard 是一种编解码器,可以实现与 gzip 相当的压缩速度和压缩比。
从 Spark 3.2 开始,ZStandard 将在三种情况下有用,它可以带来性能优势(节省本地磁盘空间和/或外部存储以及整体查询执行速度的提高):
- 事件日志压缩(spark . event log . compression . codec = zstd)
- 洗牌期间的 I/O 压缩(spark . io . compression . codec = zstd)
- 压缩 parquet/orc 文件spark . conf . set(" spark . SQL . parquet . compression . codec “,” zstd")**
相关的首脑会议是:
随机播放增强
Spark 作业中的 Shuffle 通常是开销最大的过程,因为数据必须在集群的节点之间移动。shuffle 是两个阶段之间的界限,在一个阶段完成后,输出被写入文件,然后被提取到下一个阶段。文件保存在执行器的本地磁盘上,或者当使用外部混洗系统时,可以保存到外部存储系统,例如 HDFS。这些文件的数量随着任务的数量成二次方增长(更具体地说,它是上游阶段的任务数量乘以下游阶段的任务数量),并且这些文件可能变得相当小。有一个吉拉正在进行中,旨在实现所谓的基于推送的洗牌,通过预合并块来优化洗牌 I/O。关于这项技术的相关文章可以在这里找到。在这次首脑会议上讨论了这个主题本身:
复杂查询计划处理
对于某些查询,查询计划可能会变得非常复杂,其编译可能会成为真正的瓶颈。有一个吉拉正在进行中,它试图简化处理带有别名的列的约束的过程,测试显示有希望加速。与这一主题相关的首脑会议是:
ANSI SQL 符合性
这是 spark 中正在进行的项目,在 3.0 版本中引入了实验性配置设置 spark.sql.ansi.enabled ,当设置为 True 时,Spark 将尝试符合 ANSI SQL 规范,这意味着如果输入无效,查询可能会在运行时失败,否则可能会返回空值。这方面的一个具体例子是无法安全转换或容易混淆的数据类型的转换。与此相关的一些新功能将在 3.2 中发布,例如, TRY_CAST , TRY_ADD , TRY_DIVIDE 如果用户希望使用 ANSI 模式,但如果输入无效而不是查询失败,则这些功能会很有用。
在 Spark 3.2 中,将发布两种新的间隔日期类型,年-月和日-时间,这将解决当前 CalendarIntervalType 存在的一些问题。正在进行的吉拉是相关子任务的保护伞。当前区间类型的问题是它不具有可比性,并且不支持排序,因此有两个区间我们无法比较它们并判断哪个更大。另一个问题是我们不能将区间类型保存为文件格式,比如 parquet/orc 甚至 json。另一方面,将在 3.2 中发布的两个新类型 YearMonthIntervalType 和 DayTimeIntervalType 将是可比较和可订购的,并且将符合 SQL 标准。
有关 ANSI SQL 合规性的更多信息和细节,请参见文档或查看峰会中讨论这些主题的以下会议:
DataSourceV2 API
DataSourceV2 API 在过去几年中一直在开发中,它旨在解决与 V1 API 相关的各种问题,例如,data frame writer的某些模式的连接器行为不一致,在写入表之前没有模式验证,依赖于其他内部 API,如 SQLContext ,以及新功能不容易扩展。
V2 API 使用目录来检查表是否存在,并使用一致的验证规则,与连接器的实现无关。有一个吉拉正在开发中,旨在支持在 V2 API 中更好地控制连接器的分布和订购,这应该允许更好的灵活性,并计划在 Spark 3.2 中发布。
本次峰会讨论了 V2 API 以及相关的配送和订购功能:
结论
Data + AI 峰会 NA 2021 上有很多有趣的环节。在这篇简短的报告中,我总结了我在 Spark 内部机制和最佳实践专题的一些会议中的笔记。这些说明并不完整,我主要关注的是 3.1.1 中发布的新特性或者计划在 3.2 中发布的新特性。
用于可视化数据集和解释模型的高度交互式仪表板
使用 FiftyOne 创建仪表板,帮助构建高质量的数据和计算机视觉模型
来源:作者
可视化图像数据集从来没有那么容易,直到我们引入了 51。它是完美的工具,不仅有助于可视化数据集,而且有助于理解数据集的不同方面,解释模型,评估模型预测等。它具有多种多样的特征,并被强烈推荐用于评估对象检测模型、对象分类模型、寻找图像唯一性等。
FiftyOne 可以与 PyTorch、Tensorflow、Google AI、Jupyter、Colab 等多种工具集成。它的核心功能包括管理数据集、评估模型、查找注释错误等等。我可以写多篇文章涵盖 51 的不同方面,但我们不能涵盖所有的功能。
FiftyOne 是一个开源 python 工具,用于创建高度交互式的图像可视化和模型解释应用程序。在本文中,我们将探讨如何使用 FiftyOne 可视化数据集。
让我们开始吧…
安装所需的库
我们将从使用 pip 安装 51 开始。下面给出的命令可以做到这一点。
!pip install fiftyone
导入所需的库
在这一步中,我们将导入创建第五十一个应用程序所需的库。
import fiftyone as fo
import fiftyone.zoo as foz
加载数据集
五十一应用程序已经有很多预定义的数据集,他们称之为动物园,你可以使用这个动物园中的任何数据集。在本文中,我们使用快速入门地理数据集。让我们从加载数据集开始。
dataset = foz.load_zoo_dataset("quickstart-geo")
print(dataset)
来源:作者
您可以使用下面的命令检查所有数据集的名称。
print(foz.list_zoo_datasets())
来源:作者
可视化数据集
这是最精彩的部分。在这里,我们将在一个应用程序中可视化数据集,FiftyOne 只用一行代码就创建了这个应用程序。
session = fo.launch_app(dataset)
来源:作者
这是由 FiftyOne 创建的应用程序。在左侧,您可以看到标签。同样,您也可以在一个网格中可视化所有图像。如果我们选择 ground__truth 标签,它将向我们显示图像中的所有对象,如下所示。
来源:作者
同样,您也可以选择缩放器,即 Id,以及将在图像网格中显示的文件路径。您还可以更改网格的大小来相应地调整图像。
这只是我们已经开始的视觉化。有更多的事情,你可以使用 51 轻松探索,因为它是高度互动的,易于理解。
继续尝试不同的数据集,并可视化这些数据集。如果您发现任何困难,请在回复部分告诉我。
本文是与 Piyush Ingale 合作完成的。
在你走之前
感谢 的阅读!如果你想与我取得联系,请随时通过 hmix13@gmail.com 联系我或我的 LinkedIn 个人资料 。可以查看我的Github简介针对不同的数据科学项目和包教程。还有,随意探索 我的简介 ,阅读我写过的与数据科学相关的不同文章。
高度交互式数据可视化
使用 Panel-Highcharts 在 Python 中创建高图表
(来源:作者)
数据可视化影响你讲故事,因为它帮助用户更清楚地了解你想说什么,并且用户可以实际可视化模式、见解等。你想告诉我的。可视化有配色方案,图案,不同类型的图表,如果展示得漂亮,会让用户着迷。
创建可视化有不同的方法,python 也有不同的库,可以创建视觉上吸引人的可视化。 Panel-Highcharts 是一个 python 库,使得在 python 中使用 Highcharts 进行探索性数据分析变得很容易。我们可以用它来使用 Highcharts 创建可视化效果,或者使用 Panel 创建仪表板。
在本文中,我们将探索可以使用 Panel-Highcharts 创建的不同类型的图表。
让我们开始吧…
安装所需的库
像任何其他 python 库一样,我们将使用 pip 安装 Panel-Highcharts。下面给出的命令将安装所需的库及其依赖项。
pip install panel-highcharts
导入所需的库
安装后,现在我们将导入创建可视化、加载数据等所需的库。
import panel_highcharts as ph
import panel as pn
pn.extension('highchart')
创建图表和绘图
现在,我们将开始可视化使用 Panel-Highcharts 创建的不同图表和绘图。
- 折线图
我们将首先创建一个基本的折线图,然后创建一个小部件来处理该图表。
#Define the configuration and the data to be used in chart
configuration = {
"title": {"text": "Line Chart Pane"},
"series": [
{
"name": "Sales",
"data": [100, 250, 150, 400, 500],
}
]
}ph.HighChart(object=configuration, sizing_mode="stretch_width")
折线图(来源:作者)
在这里,我们可以看到使用 Highcharts 创建的折线图。在给出的图像中,右侧有一个切换按钮,允许用户下载不同格式的图表和数据。
现在让我们创建一个小部件框,它可以用来处理这个图表。
chart = ph.HighChart(object=configuration, sizing_mode= "stretch_width")settings = pn.WidgetBox(
pn.Param(
chart,
parameters=["height", "width", "sizing_mode", "margin", "object", "event", ],
widgets={"object": pn.widgets.LiteralInput, "event": pn.widgets.StaticText},
sizing_mode="fixed", show_name=False, width=250,
)
)
pn.Row(settings, chart, sizing_mode="stretch_both")
带有小部件的折线图(来源:作者)
在这里,我们可以看到一个小部件框,我们可以调整这些值,并在折线图中查看结果。这有助于向观众展示特性的变化如何导致价值观的变化。
2.股票走势图
我们还可以使用这个库创建图表来表示股票数据。我们将导入 request 和 json 来下载股票数据,并使用 highstock 扩展。
pn.extension('highstock')
import requests, json#Downloading Data
data = requests.get('[https://cdn.jsdelivr.net/gh/highcharts/highcharts@v7.0.0/samples/data/new-intraday.json').json()](https://cdn.jsdelivr.net/gh/highcharts/highcharts@v7.0.0/samples/data/new-intraday.json').json())#Creating Configuration
configuration = {
"title": {"text": "AAPL stock price by minute"},
"rangeSelector": {
"buttons": [
{"type": "hour", "count": 1, "text": "1h"},
{"type": "day", "count": 1, "text": "1D"},
{"type": "all", "count": 1, "text": "All"},
],
"selected": 1,
"inputEnabled": False,
},
"series": [
{"name": "AAPL", "type": "candlestick", "data": data, "tooltip": {"valueDecimals": 2}}
],
}#Visualizing the chart
chart = ph.HighStock(object=configuration, sizing_mode= "stretch_width", height=600)
chart
股票图表(来源:作者
在这里,我们可以使用 Highstock 扩展来可视化股票数据,该扩展创建了一个蜡烛图。类似于折线图,您也可以在此绘制小部件框。
3.地理图
我们也可以使用高图表来创建一个地理图。为此,我们将加载扩展 highmap 并从在线源加载数据。我们将创建一个情节,然后将其作为一个应用程序与部件框渲染。
pn.extension('highmap')**#Creating configuration**
configuration = {
"chart": {"map": "custom/europe", "borderWidth": 1},
"title": {"text": "Nordic countries"},
"subtitle": {"text": "Demo of drawing all areas in the map, only highlighting partial data"},
"legend": {"enabled": False},
"series": [
{
"name": "Country",
"data": [["is", 1], ["no", 1], ["se", 1], ["dk", 1], ["fi", 1]],
"dataLabels": {
"enabled": True,
"color": "#FFFFFF",
"formatter": """function () {
if (this.point.value) {
return this.point.name;
}
}""",
},
"tooltip": {"headerFormat": "", "pointFormat": "{point.name}"},
}
],
}**#Creating Visualization**
chart = ph.HighMap(object=configuration, sizing_mode= "stretch_width", height=600)#Adding widget box
settings = pn.WidgetBox(
pn.Param(
chart,
parameters=["height", "width", "sizing_mode", "margin", "object", "object_update", "event", ],
widgets={"object": pn.widgets.LiteralInput, "object_update": pn.widgets.LiteralInput, "event": pn.widgets.StaticText},
sizing_mode="fixed", show_name=False, width=250,
)
)
pn.Row(settings, chart, sizing_mode="stretch_both")**#Creating Events**
event_update = {
"series": [
{
"allowPointSelect": "true",
"point": {
"events": {
"click": "@click;}",
"mouseOver": "@mouseOverFun",
"select": "@select",
"unselect": "@unselect",
}
},
"events": {
"mouseOut": "@mouseOutFun",
}
}
]
}
chart.object_update=event_update
在这之后,我们都创建应用程序并呈现它。
chart.object =configuration = {
"chart": {"map": "custom/europe", "borderWidth": 1},
"title": {"text": "Nordic countries"},
"subtitle": {"text": "Demo of drawing all areas in the map, only highlighting partial data"},
"legend": {"enabled": **False**},
"series": [
{
"name": "Country",
"data": [["is", 1], ["no", 1], ["se", 1], ["dk", 1], ["fi", 1]],
"dataLabels": {
"enabled": **True**,
"color": "#FFFFFF",
"formatter": """function () {
if (this.point.value) {
if (this.point.name=="Denmark"){
return "❤️ " + this.point.name;
} else {
return this.point.name;
}
}
}""",
},
"tooltip": {"headerFormat": "", "pointFormat": "**{point.name}**"},
"allowPointSelect": "true",
"point": {
"events": {
"click": "@click;}",
"mouseOver": "@mouseOverFun",
"select": "@select",
"unselect": "@unselect",
}
},
"events": {
"mouseOut": "@mouseOutFun",
}
}
],
}#Rendering Application
app = pn.template.FastListTemplate(
site="Panel Highcharts",
title="HighMap Reference Example",
sidebar=[settings],
main=[chart]
).servable()
HighMap 地理图(来源:www.github.com)
这就是我们如何使用 Panel-highcharts 创建不同的图。还有很多其他的剧情可以尝试。
在这篇文章中,我们已经经历了某些情节以及如何创建它们,这些情节是高度交互和可下载的。继续尝试不同的数据集,并让我知道您在回复部分的评论。
本文是与皮尤什·英格尔合作完成的
在你走之前
感谢 的阅读!如果你想与我取得联系,请随时通过 hmix13@gmail.com 联系我或我的 LinkedIn 个人资料 。可以查看我的Github简介针对不同的数据科学项目和包教程。还有,随意探索 我的简介 ,阅读我写过的与数据科学相关的不同文章。
使用 Python 生成密码
在大约 5 分钟内为所有重要文件和网上交易生成安全密码
安全性是当今时代最重要的问题之一,确保每台设备、设备、社交媒体账户、银行对账单或任何其他类似的重要信息的安全变得至关重要。出于高安全性的目的,我们利用密码锁定必要的数据,以便只有授权用户才能访问相关信息。
大多数人可能已经注意到,密码通常由星号(*)表示,代表字符数。大多数现代电子邮件或其他加密服务拒绝允许弱密码。你不再被允许只输入几个字母或几个数字,因为这些密码很容易被暴力破解。
我们甚至可以注意到,像 Gmail 这样的一些服务甚至为用户提供了一个选项来选择一个强密码的建议。在本文中,我们将利用 Python 编程来实现以下强密码生成任务。使用 Python 进行项目开发的多功能性和案例将使我们能够有效地实现预期的结果。
我们现在将直接进入这个项目,为个人和专业应用程序构建高度安全的密码。但是,如果您不太熟悉 Python,我建议您在继续学习之前先阅读下面的文章。
来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们并不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语 。
生成高度安全密码的 Python 项目:
为了构建这个项目,我们将研究几个方法来执行下面的任务。在第一种方法中,我们将从头开始构建整个项目。在第二种方法中,我们将查看一个可以帮助我们更有效地完成预期任务的库。然而,了解如何从零开始构建这样的项目以在编程和最终数据科学中发展是至关重要的。让我们开始导入一些基本的库。
import random
import string
随机库对于我们从特定字符串的序列中随机选取字母、数字或特殊字符是必不可少的。为了获得生成密码所需的字符,我们将使用导入的字符串模块。键入以下命令来接收可能性字符串。
print(string.printable)
确保您删除了双引号或在它们前面加了一个反斜杠,这样您就可以在项目中使用它们。但是,您可以删除一些您不希望密码包含的不必要的字符。另外,请注意,有些网站可能对特殊字符有特殊要求。确保满足这些要求,并且没有任何不必要的序列。下一个代码块如下。
char_seq = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!#$%&'()*+,-./:;<=>?@[\]^_`{|}~"
print(type(char_seq))
在下一步中,我们将允许用户选择他们希望在各自的密码中包含的字符数。但是,我们将设置一个最小的八位密码限制,因为这通常是大多数网站对强密码的最小要求。我们还将设置一个最大 16 个字符的阈值,因为任何超过这个长度的字符都可能会很奇怪。下面是解释以下内容的代码片段。
print("Enter the required length of the password ranging from 8 to 16: ")
length = int(input())
现在我们已经允许用户输入所需的密码长度,我们可以继续构建下一个代码块,它将使我们能够计算生成的密码。我们将使用 if 和 else 语句来确保用户输入的长度要求在 8 到 16 个字符的限制范围内。我们将用一个空字符串初始化一个密码变量,这个空字符串将存储我们将生成的随机字符。我们将针对提到的长度运行 for 循环迭代。在每次迭代中,我们将使用随机库中的 choice 函数从我们的字符序列中选择一个随机字母,并将其添加到密码变量中。
通常,第一个过程应该足以创建一个由随机字符组成的强密码。然而,我们将通过给这个新生成的密码增加更多的随机性来使它稍微更安全。因此,我们将把密码从字符串格式转换成一个列表,并从随机库中运行 shuffle 操作。一旦我们打乱了随机生成的密码,我们将把列表中的字母重新组合成字符串格式,并打印出用户选择的强密码。下面提供了执行以下操作的完整代码块。
if length >= 8 and length <= 16:
password = ''
for len in range(length):
random_char = random.choice(char_seq)
password += random_char
# print(password)
list_pass = list(password)
random.shuffle(list_pass)
final_password = ''.join(list_pass)
print(final_password)
最后,我们将通过完成 if-else 条件语句来结束我们的代码。如果范围不合适,我们将返回一个命令,告诉用户输入一个合适的范围。您可以对该项目进行一些改进,使其更有成效和效率。我建议观众多尝试一下这样的方法!
else:
print("Enter a suitable range")
现在,我们将看看第二种方法,在这种方法中,我们可以构建同一个项目。为了完成这个任务,我们可以用一个简单的 pip 命令安装下面的库。查看安装页面,从这个下载库获得关于这个库的更多信息。
pip install random-password-generator
为了生成所需的密码,导入已安装的库并调用函数,同时将它存储在一个随机变量中。现在,您可以相应地生成所需的密码。执行所需操作的代码片段如下所示。
from password_generator import PasswordGeneratorpwo = PasswordGenerator()
pwo.generate()
有了这个库,您可以实现更多的事情,值得查看官方文档。因此,请随意参观。您可以从这个下载库查看安装页面以获得关于这个库的更多信息。
结论:
“因为没什么好隐瞒而辩称自己不在乎隐私权,和因为无话可说而说自己不在乎言论自由没什么区别 。”
- 爱德华·斯诺登
随着安全成为最近几乎所有活动的主要关注点,应用增强的方法来保护您的数据和信息以防止您被网络钓鱼或被类似的黑客方法利用变得至关重要。生成您自己的强密码来保护私人信息是对抗和处理这些现有威胁的最佳方式之一。
在本文中,我们利用 Python 编程语言编写了一个简单的代码,该代码将解决语言如何解决强密码生成这一任务。我建议看看其他技术和方法,以获得更有成效的结果。
如果你想在我的文章发表后第一时间得到通知,请点击下面的链接订阅邮件推荐。如果你希望支持其他作者和我,请订阅下面的链接。
https://bharath-k1297.medium.com/membership
我建议尝试许多这样的项目来适应 Python 编程。看看我的其他一些文章,你可能会喜欢读!
</5-best-python-projects-with-codes-that-you-can-complete-within-an-hour-fb112e15ef44> </7-best-ui-graphics-tools-for-python-developers-with-starter-codes-2e46c248b47c>
谢谢你们坚持到最后。我希望你们都喜欢这篇文章。祝大家有美好的一天!
事后经验回放(HER)实现
提示和技巧
算法和代码的解释
我最近为我的研究强化学习库实现了 HER 算法: Pearl 。在这样做的时候,我发现虽然有文章讨论算法的理论,但是没有任何文章讨论如何用代码实现它。就这样吧,这就是我来的原因!在本文中,我将讨论如何用 Python 实现 HER 缓冲区😊
快速算法概述
提醒一下,这是原始论文中的算法:
来源:https://arxiv.org/abs/1707.01495
总之,在二元且稀疏的奖励环境中(在该环境中,当代理获胜时实现唯一的非负奖励),如果代理从未接收到任何奖励变化,则它可能很难适当地探索环境并学习实现期望目标所需的步骤序列。HER buffer 试图通过复制每个经历的轨迹,并用假设目标是轨迹结束时实现的步骤计算的奖励代替实际奖励来克服这一点。这个想法是,这将帮助代理更好地探索,并学习中间目标,最终达到实际的期望目标。在本文中,我将新的采样目标称为她的目标,而结果轨迹将是她的轨迹,其中包含计算的她的奖励。
实现和代码
该实现将稍微偏离本文中的理论算法。主要区别如下:
- 我们不会在添加每个轨迹后立即对目标进行采样并计算她的奖励,而是等到采样时,我们可以一次性进行矢量化计算,这在 Python ⚡中要快得多
- 我们还将使用一个技巧,只使用一个缓冲区来存储观测值和下一个观测值,以将观测值存储的内存需求减少近一半!这可以通过假设存储的观察值是连续的来实现;也就是说,索引 i+1 处的观察值是索引 I 处的下一个观察值💾
初始化
反直觉地,让我们从第 2 点开始,因为这是在下面的类初始化中定义的,注意没有定义self.next_observations
。
她的 init
这里需要注意的一点是,这个缓冲区只接受GoalEnv
环境!!这让我们能够轻松跟踪剧集目标。请看下面来自 OpenAI 的原始描述:
目标环境描述
在轨迹的末端,下一个观察将是结束状态,并且期望的目标在整个情节中应该是恒定的。因此,我们只需要跟踪观察结果desired_goal
和下一次观察结果achieved_goal
,就可以计算她的奖励。同样值得注意的是self.episode_end_indices
和self.index_episode_map
缓冲器:
self.episode_end_indices
:跟踪轨迹缓冲器中的剧集结束索引。self.index_episode_map
:跟踪哪些过渡属于哪些剧集。
最后,her_ratio
变量指示用新的 HER 奖励与标准重放缓冲器轨迹进行采样的轨迹的分数。
添加轨迹
如前所述,在添加轨迹时,我们不会对她的目标和回报进行采样,因此这种方法并不复杂。
将轨迹添加到缓冲区
注意添加next_observation["observation"]
在算法上有点复杂,因为我们像observation["observation"]
一样将它存储在self.observations
中。
抽样
这是真正的处理过程,我们批量计算她的目标和相应的奖励。让我们从定义我们想要从轨迹缓冲区返回哪些索引的高级方法开始:
她的高级抽样方法
这里要注意的关键是,我们想要从完整的剧集中采样索引,这就是为什么我们需要将end_idx
定义为轨迹缓冲区中最后一个完整剧集的索引。
接下来,让我们看看返回轨迹的方法。这会以self.her_ratio
定义的比率获得标准回放和她的轨迹:
幸运的是,GoalEnv
有一个方法compute_reward(achieved_goal, desired_goal, info)
,这意味着我们不必担心自己计算她的回报。在这种方法中,我们本质上分离了我们需要计算她的回报和目标的指数,然后在最后重新组合一切以获得回报。所有观察值也与算法中指定的期望目标相联系。请再次注意next_observations
的采样稍微复杂一些,因为我们从同一个self.observations
缓冲区获得这些数据。
最后,还有一个问题是让她的目标本身来计算她的奖励。这定义如下:
尝试她的目标
还记得在算法回顾时,我说过她的目标被假定为轨迹终点观察吗?这只是部分正确,实际上有许多不同的方式来取样她的目标,我已经做了其中的两个以上。最简单的方法是获得最后的观察结果,但这篇论文显示,当你在同一集但在当前过渡之后,以随机状态对她的目标进行采样时,实际上获得了最佳结果。在这个策略中,有一个失败模式。如果采样的情节与缓冲区“重叠”;也就是说,当缓冲区溢出时,剧集在缓冲区的末尾开始,在开头结束,可以在缓冲区的末尾选取该剧集中的轨迹。因此,当调用np.random.randint()
时,低值将是缓冲区结尾的索引,而高值将是剧集开头的结尾索引,从而导致错误。因为如果缓冲区大小相对较大(通常应该是 1e6 的量级),这种情况很少发生,所以作为快速解决方案,我们可以求助于更简单的 HER 目标策略,即在这种情况发生时选取剧集结束索引。
唷!坚持到了最后🎉🎉
如果您觉得这篇文章有用,请考虑:
- 跟踪我🙌
- 订阅我的电子邮件通知 永不错过上传📧
- 使用我的媒介 推荐链接 直接支持我并获得无限量的优质文章🤗
晋升的方式,让我知道你对这个话题的想法和快乐学习!!
HiPlot:脸书的交互式可视化工具
一个非常方便的探索性数据分析工具
照片由 Unsplash 上的 Stesson Bezuidenhout 拍摄
数据可视化技术对于探索数据集非常有用。数据科学生态系统中使用了各种各样的可视化类型。什么最适合给定的任务取决于数据和变量的特征。
在本文中,我们将介绍一个由脸书创建的交互式可视化工具。它本质上是一个平行坐标图。因此,每行(即数据点)用一条线表示。线上的坐标是变量(即列)。
平行坐标图提供了数据集中可能的组(或簇)的图形表示。它们还揭示了某些有助于区分数据点的模式。
平行坐标图也是一种探索高维数据的便捷方式,对于这些数据,传统的可视化技术可能无法提供合适的解决方案。
脸书为神经网络的超参数调整创建了 HiPlot。然而,我们可以在几乎任何数据集上实现它。最终目标是一样的:好好探索数据。我们将使用著名的 iris 数据集来演示如何使用 HiPlot。
第一步是安装 HiPlot。文档详细解释了如何在各种环境下安装它。我正在用 pip 安装它。
pip install -U hiplot
我们现在可以导入所有的依赖项,并将数据集读入 pandas 数据帧。
import hiplot as hip
import pandas as pd
from sklearn.datasets import load_irisiris = load_iris(as_frame=True)['frame']iris.head()
虹膜数据框(图片由作者提供)
使用 Hiplot 创建交互式可视化非常简单。下面一行代码将创建我们将在整篇文章中尝试的内容。
hip.Experiment.from_dataframe(iris).display()
Hiplot 还接受一个 iterable(例如 dictionary)作为输入数据。在这种情况下,我们使用 from_iterable 函数而不是 from_dataframe 函数。
下面是生成的图的截图。我们仅仅通过观察就能注意到一些模式。
(图片由作者提供)
iris 数据集包含 4 个独立变量和一个目标变量。根据独立变量值,目标取三个值中的一个。
Hiplot 与众不同的地方在于交互界面。例如,我们可以选择图表上任何变量的取值范围。
(图片由作者提供)
我们在花瓣宽度栏中选择一个数值范围。仅显示花瓣宽度在选定范围内的数据点。我们立即注意到所选范围与目标值 0 不同。
可以在多个列上选择一个值范围,这样我们就可以创建更具体的模式。
(图片由作者提供)
我们还可以从目标变量中选择一个值,并查看属于该类的数据点的模式。
(图片由作者提供)
Hiplot 允许重新排列图上的列。例如,我们可以移动目标变量并把它放在最左边。如果您想将分类变量放在一边,将数值变量放在另一边,这个特性就很方便了。
(图片由作者提供)
Hiplot 还生成一个表格作为交互界面的一部分。我们可以使用此表来选择数据点并在图表上查看它们。
(图片由作者提供)
结论
我们已经介绍了一个简单的案例,展示了 Hiplot 如何用于探索性数据分析。
随着数据维度的增加(即列数增加),使用数据可视化来探索数据变得更加困难。在这种情况下,Hiplot 是一个方便的工具。
感谢您的阅读。如果您有任何反馈,请告诉我。
被聘为贵公司首位数据科学家?第一天你应该知道的 3 件事
办公时间
发起文化变革&避免常见的陷阱
2020 年 10 月我加入 accuRx 成为公司第一位数据科学家。在加入时,accuRx 是一个由 60 多名员工组成的团队,他们依靠直觉和一流的用户研究团队创造出 GPs 需要和喜爱的产品,完成了令人难以置信的工作。这一点,加上 2020 年医疗保健行业对良好技术解决方案的需求增加,导致我们的业务范围呈指数级扩展。突然间,我们几乎出现在英国所有的全科医生诊所。
我们发现自己处于一个有趣的位置:我们现在有几个每天都被 GPs 广泛使用的产品,以及另一组我们刚刚赋予生命的新生产品想法。我们知道,在这一点上,我们需要开始更多地依靠来自定量数据的洞察力来检验我们的假设,并将我们的产品套件推向正确的方向。
在这一点上,我们不需要先进的 ML 解决方案或最新的大数据处理工具。我们真正需要的是大规模验证我们的假设的能力,了解一个非常庞大和多样化的用户群体的需求,并培养一种决策文化,在这种文化中,依赖定量数据是第二天性。这就是我被带进来的原因,也不是没有挑战。以下是我到目前为止学到的一些东西:
1.新角色创造新对话。
向团队中添加新成员会带来一系列不可避免的挑战:团队动态变化,入职的初始成本很高,现在在决策时房间里又多了一个声音。当你不仅给团队增加一个新成员,而且给团队增加一个新角色时,这种影响会被大大放大。
在我加入之前,数据科学并不是产品开发流程的核心部分。突然,团队被引入了大量以前不需要考虑的新问题、流程和技术要求,解决这些问题通常需要整个团队工作方式的重大转变。
这方面的几个例子有:
- 软件工程师不得不花费更多的时间向功能发布添加分析,并确保产生这些分析的管道是可靠的。
- 有时,AB 测试结果需要一段时间才能慢慢显现出来。鉴于这些结果(希望)会告知产品下一步的发展方向,产品经理、设计师和工程师经常发现自己在如何最好地——以及多快地——重复功能和想法方面面临相当程度的模糊不清。
- 有一组额外的信息需要考虑,这通常意味着我们要花更长的时间来决定产品的发展方向。我们现在不得不将我们的直觉与数据告诉我们的东西相协调,并打电话询问我们认为这两者有多可靠!
这需要一点试错,但重要的是找到一种工作方式,让产品经理、设计师和工程师能够自由地快速发布和迭代,而不牺牲您对分析严谨性的承诺。在我们的案例中,这看起来像是找出哪些产品变化值得测试,什么样的细节值得跟踪,以及在产品开发过程的不同阶段什么样的分析最有用。
2.有效的沟通是成功的一半以上。
你认为你的分析有多有用并不重要——如果人们不知道或不理解它们,它们不太可能产生长期影响。此外,你传达发现的方式将决定你的分析最终会产生多大的影响。
广泛而频繁地交流。
重要的是,仅向团队领导传达您的发现是不够的,整个团队投入了大量时间和精力来适应支持分析的新工作方式,他们希望能够看到这些调整产生了什么影响。交流这些变化如何对决策产生积极影响,将有助于创建一种积极的反馈循环,激励您的团队继续依赖您介绍的流程和技术。
一旦你让你的团队参与进来,真正困难的部分是确保最初围绕使用数据做决策的兴奋持续下去。我犯的一个错误(不止一次!)假设围绕分析的沟通是一张您可以标记为完成的入场券。如果你想推动文化变革,你需要不断提醒人们为什么他们应该像你一样关心这件事。随着人们听到越来越多的关于团队在数据洞察的背后取得积极进展的消息,依靠数据来支持产品决策应该开始变得预期和更加自动化。
始终以洞察力呈现数据。
只要有可能,试着就这将如何影响决策以及人们最终应该做什么来交流你的发现。分析结果越不抽象越好。让你的结果不那么抽象的一个简单方法是清楚地量化你认为变化会产生多大的影响。
例如,如果你已经运行了一个 AB 测试来确定一个新特性是否增加了你的转化率,不要说“这个变化在统计上是显著的”,而是尝试“如果我们向所有用户推出这个新变化,我们的转化率可能会从 5%增加到 7%,这相当于每周增加 200 个活跃用户”。
类似地,当与团队分享数据可视化时,尽量明确图表显示了什么和没有显示什么。请记住,你已经花了很多时间来思考这个观想,但是用新的眼光看待它的人可能没有你那么多的背景知识。使可视化清晰的简单方法是确保您用来定义指标的确切数据得到理解,并在图表旁边提供对趋势或发现的解释。如果可以的话,试着解释你设想的趋势对你团队目标的影响,这样他们就可以根据你分享的观点采取行动。
速度不错,但准确性更好。
没有比养成传达不正确或部分正确结果的习惯更能确保你的工作影响较小的方法了。如果你是团队中第一个或唯一的数据科学家,你就是构成好的或充分的证据的权威,因此,讽刺的是,你几乎没有犯错的余地。
您经常会发现自己不得不在快速向团队提供结果和确保产生这些结果的分析是可靠的之间进行权衡,特别是如果您正在使用新的、次优的或不熟悉的工具。在大多数情况下,我发现通常有一个你可以达成的妥协——但这需要你非常清楚你用来得出特定结论的数据的局限性。如有疑问,请注意!
人们会很快知道他们是否能信任你,而一旦信任被打破,想要恢复就很难了。这并不是说你不会犯错误,但当这些错误发生时,及早发现并得到广泛认可,并建立健全的流程以避免将来出现类似错误,这一点非常重要。
3.良好的数据基础设施是良好的数据科学的先决条件。
当谈到准确和有用的分析时,可以肯定的结论是,它们是由可访问和可靠的数据实现的。无论您的基础设施有多好,在运行您的分析之前花费大量时间清理数据都是合理的。因此,如果您的数据基础架构没有针对分析进行优化,那么花费在清理数据和将数据转换成可用格式上的额外时间将很快成为主要障碍。到目前为止,我们还没有优先考虑获得同类最佳的分析工具,这是一项艰巨的工作,也是我们仍在努力的方向。
千刀万剐……
这种影响是双重的。首先,它在你的工作流程中增加了足够的摩擦,以至于你可能会放弃使用可能有价值的信息,因为你必须权衡信息的有用性和获取信息的成本。当一个组织行动相当迅速时,所需的时间和精力往往令人望而却步。
其次,每次在不同平台之间转移和转换数据时,出错的可能性都会增加。数据的每一次重新定位或调整都与出错的可能性相关,当然,您做的越多,实际运行分析时数据越不可靠的可能性就越大。这两个障碍一起强烈地抑制了分析角色创造性地解决问题的积极性,并增加了足够的摩擦,以至于您的分析方法可能会变得更加僵化和工具化——这有什么乐趣可言!
你成为瓶颈。
与此相关的是更广泛团队的可访问性问题。如果数据科学家正在努力可靠地访问数据,你可以打赌,其他人可能会更糟!这样做的结果是,简单信息的查询被外包给了你——当人们意识到你能够并愿意涉过这个特殊的泥潭时,讽刺的是,你开始成为数据驱动决策的瓶颈。
在这一点上,你的角色开始变得更加被动——你将花费大部分时间来处理高强度、边际价值的任务,并发现你用于主动思考问题的时间和空间少了很多。
为了避免这些陷阱,你需要确保你在早期就为你需要的工具而努力,你尽可能多地自动化你自己的工作流程,你提供足够的价值,让人们可以看到如果你能够更有效地工作,他们会从你那里得到更多。
**成为一家公司的第一位数据科学家很难,**但这为你提供了一个独特的机会,让你决定如何在整个组织中使用数据。要做到这一点,首先要优先考虑良好的沟通。这将让人们相信你的愿景,这反过来会帮助你更快地清除基础设施障碍。当你这样做的时候,你需要学会进行有效的权衡,并成为一名专家,以一种能让团队领导对他们的决定有信心的方式展示发现。这将是一个缓慢的过程,但是一旦你证明了一个团队依靠可靠数据的洞察力所能产生的积极影响,你会发现大多数人都有强烈的欲望用证据来支持他们的论点,因此很乐意帮助你保持文化变革!
用 Plotly 表示的直方图
主题&模板
图片来自 Unsplash 的 Jayson Hinrichsen
阴谋地表达
Plotly Express (PE)是 Plotly.py 的高级包装器,与 Plotly 生态系统的其余部分完全兼容。基于 JavaScript 库 D3.js 。,它也有 R、Julia 和许多其他编程语言的 API 包装器。它是免费的,可以用于商业应用和产品。该库包括绘制标准图表和地图的函数,以及通过单个函数调用执行刻面和动画的函数。使用 Plotly Express,您可以在线制作交互式图形,也可以离线保存。
Plotly Express 适用于快速生成探索图。此外,可以通过使用预定义的主题或模板快速设计图表。根据 Plotly 主网站,“主题化通常是指为视觉元素定义默认样式的过程。plotly 中的主题是使用称为模板的对象实现的。模板比传统的主题更通用,因为除了定义默认样式,模板还可以用视觉元素(如注释、形状、图像等)预先填充图形。”[1].
内置主题可以通过以下语句查看:
共有 11 个模板: ggplot2, seaborn, plotly, plotly_white, plotly_dark, simple_white, gridon, xgridoff, ygridoff, presentation, and none.
*ggplot2*
主题灵感来自 R 数据可视化包 ggplot2、而*seaborn*
主题灵感来自 Python 数据可视化库 Seaborn 。plotly, plotly_white, and plotly_dark
均为原创 plotly.express 主题。如上所述,plotly
是默认模板,而plotly_dark
的灵感来自于 JupyterLab 的黑暗主题。以下三个主题与网格的有无有关:gridon, xgridoff, ygridoff
。是一个清晰整洁的图表的极简模板。presentation
主题增加了字体、标记和线条宽度的大小,以便从更远的距离观看。这个主题可以与任何其他主题相结合(见图 6)。
以上每一个主题都可以作为任何*plotly.express*
函数的模板参数。所以,一个聪明的策略是反复测试这 11 个主题,直到你找到最适合你讲故事的主题。
直方图
直方图是数据集分布的图形表示。虽然它的外观类似于标准条形图,但直方图不是在不同项目或类别之间进行比较,也不是显示一段时间内的趋势,而是一种图表,它让您显示潜在的频率分布或单个连续数值变量的概率分布*。***
直方图是具有两个轴的二维图;垂直轴是频率轴,而水平轴被分成一系列数值(间隔或箱)或时间间隔。每个仓的频率由垂直矩形条的面积表示。每个柱覆盖了所研究变量的连续数值范围。纵轴 显示从每个箱的计数中得出的频率值。
讲故事:柱状图是对连续变量进行初步探索的合适图表。通过一组竖条,它显示了该变量的数值是如何分布的。直方图允许我们计算所研究的连续变量的任何值的表示概率,如果我们想从我们的样本的结果中进行推断和估计总体*值,这是非常重要的。*
用 Plotly 表示的直方图
我们使用了从 Kaggle [2]下载的数据集。该数据集由 10,000 名银行客户组成,涉及他们的年龄、工资、婚姻状况、信用卡限额、信用卡类别、教育水平和其他特征。银行经理想知道他的客户的年龄分布。下面的代码可以让我们回答他的问题。
首先,我们导入*plotly.express* as *px*
,并将 pandas 库命名为*pd*
。我们将数据集作为 pandas dataframe ( df
)加载,并选择列 Customer_Age
作为我们想要知道其频率分布的数值变量。使用默认模板plotly,
用px.histogram
画图。最后,我们将图表导出为静态的 PNG 格式。
PE 允许您选择箱子的数量。尽管对于间隔的大小和数量没有严格定义的规则,但是您必须尝试一些不同数量的容器。永远记住:很少的间隔不允许我们阐明数据分布的精细结构;许多区间重视抽样误差。
*import pandas as pd
import plotly.express as pxpath = 'your path'
df = pd.read_csv(path + 'CreditCardCustomersCols.csv', index_col = False, header = 0, sep = ';', engine='python')fig1 = px.histogram(df, x="Customer_Age", nbins = 10)fig1.write_image(path + "fighist1.png")
fig1.show()*
图 1 显示了银行客户在五年内的年龄分布。很明显,百岁人很少,千禧一代也很少。婴儿潮一代和 x 一代是这一代消费者的代表。
图 1:使用默认模板用 Plotly Express 制作的直方图。图片作者。
在图 2 中,我们将主题改为ggplot2
,并用update.layout:
设置标题来更新图表;x 轴的名称和 y 轴的名称;用width
和height
设定外形尺寸。
*fig2 = px.histogram(df, x="Customer_Age", nbins = 10, template = 'ggplot2')fig2.update_layout(title = "Histogram of Customers' Age ", xaxis_title = 'Customer Age', yaxis_title = 'Standard Count', width = 1600, height = 1400)fig2.write_image(path + "fighist2.png")
fig2.show()*
图 2:使用 ggplot2 模板用 Plotly Express 制作的直方图。图片作者。
默认情况下,PE 在纵轴中显示落入每个仓中的数据的频率(计数)。您可以使用histnorm
参数更改此模式。该参数可以采用以下值:percent, probability, density, or probability density.
在图 3 中,我们使用histnorm
参数将主题更改为plotly_dark
,并将表示模式从样本的标准计数更改为percent
。
在图 4 中,我们将主题改为simple_white
,将模式改为probabilty.
*fig3 = px.histogram(df, x="Customer_Age", nbins = 10, template = 'plotly_dark', histnorm = 'percent')fig3.update_layout(title = "Histogram of Customers' Age ",xaxis_title = 'Customer Age', yaxis_title = 'Percent Count', width = 1600, height = 1400)fig3.write_image(path + "fighist3.png")
fig3.show()fig4 = px.histogram(df, x=”Customer_Age”, nbins = 10, template = ‘simple_white’, histnorm = ‘probability’)fig4.update_layout(title = “Histogram of Customers’ Age “,xaxis_title = ‘Customer Age’, yaxis_title = ‘Probability ‘, width = 1600, height = 1400)fig4.write_image(path + “fighist4.png”)
fig4.show()*
图 3:使用 plotly_dark 模板用 Plotly Express 制作的直方图。图片作者。
图 4:使用 simple_white 模板用 Plotly Express 制作的直方图。图片作者。
在图 5 中,我们使用xgridoff
模板移除了 x 网格线。选择概率密度作为表示方式。在图 6 中,我们回到概率模式,将主题改为simple_white+presentation
。很明显,字体、标记和线宽都有所增加。
*fig5 = px.histogram(df, x=”Customer_Age”, nbins = 10, template = xgridoff’, histnorm = ‘probability density’)fig5.update_layout(title = “Histogram of Customers’ Age “, xaxis_title = ‘Customer Age’, yaxis_title = ‘Probability Density’, width = 1600, height = 1400)fig5.write_image(path + “fighist5.png”)
fig5.show()fig6 = px.histogram(df, x=”Customer_Age”, nbins = 10, template = ‘simple_white+presentation’, histnorm = ‘probability’)fig6.update_layout(title = “Histogram of Customers’ Age “, xaxis_title = ‘Customer Age’, yaxis_title = ‘Probability ‘, width = 1600, height = 1400)fig6.write_image(path + “fighist6.png”)
fig6.show()*
图 5:使用 xgridoff 模板用 Plotly Express 制作的直方图。图片作者。
图 6:用 Plotly Express 和 simple+演示模板制作的直方图。图片作者。
重叠直方图用于比较两个或多个类别中连续变量的频率分布。尽管 PE 网站指出可以使用参数color
为一列的不同值绘制几个直方图,但我没有得到合适的图表。因此,我过滤了分类变量“Gender
”的两个不同值的数据帧,使用了两次px.histogram
函数,并用add_trace
方法“合并”了两个数字。由于px.histogram
函数没有文本属性,我们使用参数color
只是为了标记。我们使用不同的主题来识别每个图形,并使用 barmode = ‘overlay’
参数来获得重叠。图 7 显示,客户的性别分布没有差异。
*df7a = df[df[‘Gender’] == ‘M’]
df7b = df[df[‘Gender’] == ‘F’]fig7a = px.histogram(df7a, x=”Customer_Age”, nbins = 10, template=‘seaborn’, barmode = ‘overlay’, color = “Gender”)fig7b = px.histogram(df7b, x=”Customer_Age”, nbins = 10,
template = ‘ggplot2’, opacity = 0.25, color = ‘Gender’)fig7a.update_layout(title = “Histogram of Customers’ Age & Gender”,xaxis_title = ‘Customer Age’, yaxis_title = ‘Standard Count‘, width = 1600, height = 1400)fig7a.add_trace(fig7b.data[0])fig7a.write_image(path + “fighist7.png”)
fig7a.show()*
图 7:用 Plotly Express 和 seaborn 和 plotly_dark 模板制作的重叠直方图。图片作者。
图 8 示出了根据已婚、单身或离婚条件的分类变量Marital_Status
的重叠直方图。我们使用了三种不同的模板和颜色参数来识别每个图形。条形模式和不透明度分别用update_layout
和update_traces
表示。
*df8a = df[df[‘Marital_Status’] == ‘Married’]
df8b = df[df[‘Marital_Status’] == ‘Single’]
df8c = df[df[‘Marital_Status’] == ‘Divorced’]fig8a = px.histogram(df8a, x=”Customer_Age”, nbins = 10, template = ‘seaborn’, color = ‘Marital_Status’ )fig8b = px.histogram(df8b, x=”Customer_Age”, nbins = 10, template = ‘ggplot2’, color = ‘Marital_Status’)fig8c = px.histogram(df8c, x=”Customer_Age”, nbins = 10, template = ‘plotly_dark’, color = ‘Marital_Status’)fig8a.update_layout(title = “Histogram of Customers’ Age & Marital Status”,xaxis_title = ‘Customer Age’, yaxis_title = ‘Probability ‘, width = 1600, height = 1400)fig8a.add_trace(fig8b.data[0])
fig8a.add_trace(fig8c.data[0])fig8a.update_layout(barmode=’overlay’)
fig8a.update_traces(opacity = 0.75)fig8a.write_image(path + “fighist8.png”)
fig8a.show()*
图 8:使用 seaborn、ggplot2 和 plotly_dark 模板用 Plotly Express 制作的重叠直方图。图片作者。
一些警告
你可以看到(甚至在 PE 网站上)分类直方图和日期直方图。
分类直方图指的是离散变量类别的计数。我不认为它们可以被定义为直方图*,而是柱状图** (BC)。请记住,标准条形图用于在类别之间进行数字比较,而直方图用于显示数字变量的频率分布。此外,直方图的条形之间没有“间隙”或空格,但在 BC 上的条形之间必须留有一些空格,以清楚地表明它指的是离散的(互斥的)组。*
日期直方图也有类似的情况:作为日期范围创建的条块相当于特定年份的平均值,因此条形图或折线图比直方图更适合显示一段时间内的趋势。
PE 允许旋转直方图,因此计数在水平轴上,而数值变量的区间或箱在垂直轴上。我没有为这样的安排找到任何技术上的理由,并且它应该被避免,因为它与所有现有的直方图定义相反。
最后但同样重要的是,使用带有密度或概率密度值的histnorm
参数不会转换成密度图。密度图试图通过连续曲线显示数据集的概率密度函数。考虑到这个目标,密度图应用了一个统计程序(内核密度估计),其思路是平滑表征直方图的矩形条。结果,获得了平滑的曲线,其允许更好地可视化分布的形状(图 9)。
图 9:使用相同数据构建的直方图(左)和核密度估计(右)的比较。6 个单独的内核是红色虚线;蓝色曲线是核密度估计。数据点是水平轴上的地毯图。来源:[3]。
总结一下:
Plotly Express 是一个用户友好的数据可视化工具,包括 11 个预定义的主题或模板,以加快工作速度并避免延迟。
你可以用一行代码画一个直方图。
由于直方图被认为是一些最常用的图表,您必须非常清楚什么时候应该使用直方图,以及直方图和条形图之间的区别。
参考文献
【2】:https://www.kaggle.com/sakshigoyal7/credit-card-customers
【3】:https://en.wikipedia.org/wiki/Kernel_density_estimation
HITS 算法:从零开始的链接分析解释和 Python 实现
搜索引擎中的枢纽和权威
纳斯蒂亚·杜尔希尔在 Unsplash 上的照片
介绍
我们在日常生活中使用搜索引擎,但你有没有想过搜索引擎是如何找到你正在寻找的理想网站的?这比简单的文本搜索要复杂得多。例如,如果我们正在寻找一个关于苹果的网站,一个充满“苹果”字样的网站会出现在谷歌搜索结果的顶部吗?
超链接诱导话题搜索 (HITS)是一种用于链接分析的算法。它可以发现和排名与特定搜索相关的网页。这种算法的想法源于这样一个事实,即一个理想的网站应该链接到其他相关的网站,同时也被其他重要的网站所链接。在本文中,我们将简要介绍该算法,并演练 Python 代码的实现。
算法
请随意查看评论良好的源代码。这真的有助于理解整个算法。
https://github.com/chonyy/PageRank-HITS-SimRank
首先,我们要解释什么是权威和枢纽。HITS 使用中心和权限来定义网页之间的递归关系。
- 权威:一个节点是高质量的,如果许多高质量的节点链接到它
- 集线器:如果一个节点链接到许多高质量的节点,那么它就是高质量的
算法步骤
- 用值 1 初始化每个节点的中心和授权
- 对于每次迭代,更新图中每个节点的中心和权限
- 新的权限是其父权限的总和
- 新的中枢是其子节点的权威总和
- 规范新的权威和枢纽
Python 实现
初始化中心和授权
我们在节点构造函数中初始化 hub 和 authority。auth 和 hub 的初始值是 1。
命中一次迭代
这是 HITS 算法的主要功能。如你所见,它真的很好,很短。其中的逻辑遵循我上面提到的算法。
- 对于图中的每个节点
- 更新权限
- 更新中心
- 标准化更新的值
计算新的权限和中心
- New auth =其所有父中心的总和
- 新中心=其所有子中心的授权总和
规范新的权威和枢纽
- 用图中所有节点的 auth 之和来归一化权限
- 用图中所有节点的中心总和来归一化中心
结果分析
让我们在回购中的 数据集 上测试我们的实现。
graph_1.txt
图片由 Chonyy 提供。
结果
结果按照节点值的顺序,也就是1, 2, 3, 4, 5, 6
。回想一下上面的解释,权限取决于有多少节点链接到它,集线器取决于有多少节点链接到。
从结果中,我们可以看出这条规则是成立的。节点 1 的权限为 0,因为没有到它的节点链接。节点 6 的集线器是 0,因为它没有链接到任何节点。
graph_2.txt
图片由 Chonyy 提供。
结果
同样,这个回答完全有道理。节点形成一个循环。他们都有一个父母和一个孩子,并且彼此相连。从链接的角度来看,它们基本上都是一样的。这就是为什么他们都有相同的权威和中心价值。
graph_3.txt
图片由 Chonyy 提供。
结果
Node2, Node3
- How many nodes link to it: 2
- How many nodes it links to: 2Node1, Node4
- How many nodes link to it: 1
- How many nodes it links to: 1
这也是 node2 和 node3 拥有更高权限和枢纽价值的原因。
graph_4.txt
图片由 Chonyy 提供。
结果
这里有一个有趣的观察。我们来看看 node3 和 node5 的权限。都是0.201
。有四个节点链接到节点 5,只有三个节点链接到节点 3。但是他们有同样的权力!为什么会这样?
这是因为节点 5 比节点 6 和节点 7 具有更高的集线器。因此,节点 3 只需要节点 5 通过节点 6 和节点 7 获得相同的链接值。
IBM.txt
图片由 Chonyy 提供。
结果
结果遵循节点值顺序2076, 2564, 4785, 5016, 5793, 6338, 6395, 9484, 9994
。
我们来看看 node4785,node5016,node6338 的权限。它们都有相同的 auth 值 0.105。这是因为它们都有一个共同的父节点 2076。
现在观察轮毂值。节点 2076 具有最高的集线器。这是因为它已经链接到图中的每个节点。节点 4785、节点 5016 和节点 6338 的 hub 值为 0,因为它们绝对没有要链接的子节点。
讨论
让我们做一个有趣的实验。假设我们要增加每个图中 node1 的枢纽和权限。怎么才能做到呢?
graph_1.txt
左:增加轮毂。右:增加权威。
左:增加轮毂。右:增加权威。
Hub 就像是链接到其他节点的力量。因此,我们只需让 node1 链接到另一个节点,以增加它的集线器。通过加入 edge (node1,node6),hub 值大大增加了 0.2 -> 0.618。
权威就像被链接的力量。我们加上边(node5,node1),权限值大大增加了 0 -> 0.5。
graph_2.txt
左:增加轮毂。右:增加权威。
左:增加轮毂。右:增加权威。
原图是一个循环,具有所有同等的权限和枢纽。通过添加额外的边(节点 1、节点 4),我们增加了节点 1 链接到其他节点的能力。因此,中心值增加了。
类似地,我们通过添加额外的边(node4,node1)增加了 node1 的链接能力。现在,节点 1 有两个父节点。因此,它的权威增加了。
graph_3.txt
左:增加轮毂。右:增加权威。
左:增加轮毂。右:增加权威。
与原始图表相比。我们在左图中添加了一条边(节点 1,节点 4 ),在右图中添加了一条边(节点 4,节点 1)。就像我们在上面的图中实现的逻辑一样,我们添加这两条边来分别增加中心和权威。
计算性能分析
趋同;聚集
现在,我们都知道,经过足够的迭代,枢纽和权威总是会收敛到一个特定的值。为什么我们不画出来看看它收敛的有多快?
在 graph_4.txt 上测试收敛
图片由 Chonyy 提供。
从图中,我们可以看到权威和枢纽在迭代 5 时开始收敛。对于一个不那么简单的图形来说,这个计算时间已经足够了。然而,当图中有更多的节点和边时,所需的迭代会大大增加。
例如,对于 graph_6.txt,500 次迭代仍然不够,它有 1228 个节点,5220 条边。并且由于大量的边,计算时间永远很长。
边数
图片由 Chonyy 提供。
我们用不同数量的总边运行 100 次迭代,以便发现总边和计算时间之间的关系。正如你所看到的,边数对计算时间的推断几乎是线性的,这是非常好的。
请注意,它不是完全线性的原因是边彼此链接的方式也会稍微影响计算时间。
缺点
HITS 算法的主要缺点是它依赖于查询。从原始论文开始,链接分析是从从一些传统的基于文本的搜索算法中检索的根集合开始的。然后展开根集链接到的站点,这是基础集。
来源:https://en.wikipedia.org/wiki/HITS_algorithm
这可能会很麻烦,因为链接分析的结果可能会受到初始搜索算法的影响。并且基于文本的搜索的评估时间非常昂贵。
因此,我想介绍另一个独立于查询的链接分析算法,PageRank 算法。请随意查看!
https://chonyy.medium.com/pagerank-3c568a7d2332
另外,如果你对链接分析中的相似性度量感兴趣。
https://chonyy.medium.com/simrank-similarity-analysis-1d8d5a18766a
源代码
https://github.com/chonyy/PageRank-HITS-SimRank
HOG(梯度方向直方图):概述
数学,论文解释和代码从零开始为初学者
什么事?
梯度方向直方图,也称为 HOG,是一种类似 Canny 边缘检测器、SIFT(尺度不变和特征变换)的特征描述符。它在计算机视觉和图像处理中用于目标检测。该技术对图像的局部部分中梯度方向的出现进行计数。这种方法非常类似于边缘方向直方图和尺度不变特征变换(SIFT)。HOG 描述符侧重于对象的结构或形状。它比任何边缘描述符都好,因为它使用梯度的大小和角度来计算特征。对于图像的区域,它使用梯度的大小和方向生成直方图。
计算猪特征的步骤
- 获取要计算其 HOG 特征的输入图像。将图像大小调整为 128x64 像素(高 128 像素,宽 64 像素)。作者在论文中使用了这个维度,因为他们使用这种类型的检测的主要目的是在行人检测任务中获得更好的结果。由于这篇论文的作者在麻省理工学院行人数据库上获得了异常完美的结果,他们决定制作一个新的、更具挑战性的数据集,称为“INRIA”数据集(http://Pascal . inrialpes . fr/data/human/),其中包含从一组不同的个人照片中裁剪出来的 1805 张(128x64)人类图像。
图 1:为获取 HOG 特征而导入的图像。图 2:流程的导入图像灰度。图 3:导入图像的调整大小和灰度图像。(图片由作者提供)
2.计算图像的梯度。通过结合来自图像的幅度和角度来获得梯度。考虑 3x3 像素的块,首先为每个像素计算 Gx 和 Gy。首先,使用下面的公式为每个像素值计算 Gx 和 Gy。
其中 r、c 分别指行和列。(图片由作者提供)
在计算 Gx 和之后,使用下面提到的公式计算每个像素的大小和角度。
图 4:图像大小的可视化。图 5:图像角度的可视化。(图片由作者提供)
3.在获得每个像素的梯度之后,梯度矩阵(幅度和角度矩阵)被分成 8×8 的单元以形成块。对于每个块,计算 9 点直方图。9 点直方图开发了具有 9 个仓的直方图,并且每个仓具有 20 度的角度范围。图 8 表示一个 9 仓直方图,其中的值是在计算后分配的。这些 9 点直方图中的每一个都可以被绘制成直方图,其中柱输出该柱中梯度的强度。由于一个块包含 64 个不同的值,对于所有 64 个量值和梯度值,执行以下计算。由于我们使用 9 点直方图,因此:
(图片由作者提供)
每个第 j 个面元,面元将具有来自以下的边界:
(图片由作者提供)
每个箱的中心值为:
(图片由作者提供)
图 6:星等图像上的 8×8 块。图 7:角度图像上的 8×8 块。(图片由作者提供)
图 8:9 格直方图的表示。对于一个由 64 个单元组成的 8×8 块来说,这一个直方图是唯一的。所有 64 个单元将分别把它们的 Vj 和 Vj+1 值加到数组的第 j 和第(j+1)个索引上。(图片由作者提供)
4.对于块中的每个单元,我们将首先计算第 j 个容器,然后计算将分别提供给第 j 个和第(j+1)个容器的值。该值由以下公式给出:
(图片由作者提供)
5.将一个数组作为一个块的二进制数,并将 Vj 和 Vj+1 的值附加到数组中为每个像素计算的第 j 和第(j+1)二进制数的索引处。
6.上述计算后的结果矩阵将具有 16x8x9 的形状。
7.一旦所有块的直方图计算结束,来自 9 点直方图矩阵的 4 个块被组合在一起以形成新的块(2x2)。这种杵状运动以重叠的方式进行,步幅为 8 个像素。对于块中的所有 4 个单元,我们连接每个组成单元的所有 9 个点直方图以形成 36 个特征向量。
上图显示了计算 9 个柱直方图的方法。(图片由作者提供)灵感来自[https://www.programmersought.com/article/42554276349/
(图片由作者提供)
围绕图像遍历 2x2 网格框,以便从 4 个块中生成一个组合的 fbi。(图片由作者提供)
8.每个块的 fb 值通过 L2 范数归一化:
其中,ε是为避免零分频误差而加到 fb 平方上的一个小值。在规范中,取值为 1e-05。(图片由作者提供)
9.为了标准化,首先通过以下公式计算 k 值:
(图片由作者提供)
10.进行这种标准化是为了减少同一物体的图像之间的对比度变化的影响。从每个街区。收集 36 点特征向量。在水平方向有 7 个块,在垂直方向有 15 个块。因此,HOG 特征的总长度将为:7 x 15 x 36 = 3780。获得所选图像的 HOG 特征。
使用 skimage 库在同一图像上可视化 HOG 特征。(图片由作者提供)
在 Python 中从头开始使用特性
在 Python 中使用 skimage 库的 HOG 特征
代码文件
链接到包含用 python 从头开始编写的 HOG 特征检测器全部代码的 Colab 文件:https://Colab . research . Google . com/drive/1 _ ydbx 68 ucxejk 448 y0 byoacuzzw 5 hwr?usp =共享
参考文献
- 人体检测的方向梯度直方图:http://lear . inrialpes . fr/people/triggs/pubs/Dalal-cvpr 05 . pdf
- 撇除文件:https://scikit-image.org/docs/dev/api/skimage.feature.html?highlight = hog # skimage . feature . hog
- HOG(梯度方向直方图)特征(使用 MATLAB 和 Python 的理论和实现):https://www.youtube.com/watch?v=QmYJCxJWdEs
敬请关注像这样的新的研究论文解释!
请随时联系并给出您的建议:https://www.linkedin.com/in/mrinal-tyagi-02a1351b1/
https://github.com/MrinalTyagi
使用 Alexa 实现家庭自动化
物联网仿真设备的语音命令,使用 Arduino 库 Espalexa。
上图:亚马逊第二代 Echo-Dot——下图:作者的最终电路
1.介绍
几年前,我探索了如何在家庭自动化项目中使用因亚马逊 Echo 和 Echo-Dot 而流行的智能个人助理 Alexa,:
当物联网遇上人工智能:采用 Alexa 和 NodeMCU 的家庭自动化和
Alexa 能够进行语音交互,播放音乐,制作待办事项列表,设置闹钟,播放播客,播放有声读物,并提供天气,交通和其他实时信息。Alexa 还可以将自己作为家庭自动化中心来控制几个智能设备。我们将在这个项目中使用“回声点”,它允许用户使用唤醒词来激活设备,如“Alexa”或“计算机”,如“星际迷航!。
在家庭自动化领域,Alexa 可以与 Philips Hue、Belkin Wemo、Sonoff 等几种不同的设备进行交互。我们在以前的项目中使用 fauxmoESP 库模拟了 WeMo 设备,这似乎已经过时了,而且现在也没有得到足够的维护。这里我们将使用 Espalexa ,这是一个易于使用的 Arduino 库,与 ESP8266 和 ESP32 都兼容。
下面的框图显示了我们的项目将会开发什么:
框图—作者提供的图片
下面的视频展示了项目结束时的样子:
2.安装 ESP 板
在 Arduino IDE 首选项→附加电路板管理器 URL 中输入:
https://dl.espressif.com/dl/package_esp32_index.json, [http://arduino.esp8266.com/stable/package_esp8266com_index.json](http://arduino.esp8266.com/stable/package_esp8266com_index.json)
Arduino IDE 首选项—打印屏幕
接下来,在 Arduino IDE 工具/板管理器中,安装板:
Arduino IDE 板管理器—打印屏幕
在这个项目中,我们将使用 NodeMCU,但是代码也可以很容易地适应 ESP32。那么,让我们也安装它:
Arduino IDE 板管理器—打印屏幕
esp 8266 node MCU 引脚排列:
ESP8266 节点 MCU 引脚排列—图片由 Amazon.com 提供
3.埃斯帕莱克萨图书馆
除了标准的开/关控制之外,Espalexa 还允许您设置一系列值(例如,亮度、温度)和可选的颜色。比如你可以说————“Alexa,把灯光调到 75%”。
Espalexa 模拟了 SSDP 协议和 Philips hue API 的部分内容,刚好足以被 alexa 发现和控制。
默认情况下,最多可以添加 10 个设备,因为每个设备“插槽”都占用内存,即使没有设备被初始化。您可以通过添加来更改设备的最大数量,例如:
#define ESPALEXA_MAXDEVICES 20
在调用库之前:
#include <Espalexa.h>
建议将 MAXDEVICES 设置为您想要添加的设备的确切数量,以优化内存使用。
要安装库,请转到 Arduino IDE 工具/管理库,并使用 espalexa 进入:
Arduino IDE 库管理器—打印屏幕
4.家庭自动化原型
我们的家庭自动化项目将创建四个智能设备工作,可以单独远程控制。但是,假设我们想要将设备分组,以便在家中使用。应该怎么做?
例如,假设我们家有两个房间:
- 卧室
- 客厅
现在,假设您希望每个房间都有一盏灯和一个插座。因此,让我们将四个设备分组,如框图所示(见本文简介):
床房
- 灯 2
- 出口 1(风扇)
客厅
- 灯光 1
- 出口 2(蜂鸣器)
欧的家庭自动化项目或多或少会是这样:
房屋原型及其物联网设备—图片由作者提供
5.组装硬件进行测试
出于测试目的,四种颜色的 led 将用作“物联网设备”。它们应如图所示安装,如下所列:
== >红色 LED(灯 1) == >节点 MCU D1 (GPIO5) —客厅
== >绿色 LED (Outlet1) == >节点 MCU D2 (GPIO4) —客厅
== >蓝色 LED(灯 2) == >节点 MCU D5 (GPIO14) —卧室
== >黄色 LED(输出 2) == >节点 MCU D6 (GPIO12) —卧室
红色和绿色的 led 将模拟安装在“起居室”的设备,蓝色和黄色的 led 将模拟安装在“卧室”的设备
电路图—图片由作者提供
6.在 Arduino IDE 上创建我们的物联网设备
首先,我们必须调用库:
#include <ESP8266WiFi.h>
#include <Espalexa.h>
要连接到设备的 NodeMCU 引脚定义如下(在测试阶段为 led,在最终项目阶段为继电器输入):
#define RelayPin1 5 //D1
#define RelayPin2 4 //D2
#define RelayPin3 14 //D5
#define RelayPin4 12 //D6
一旦我们有了 4 个设备,至少应该定义 4 个直接回调函数:
void device1Changed(uint8_t brightness);
void device2Changed(uint8_t brightness);
void device3Changed(uint8_t brightness);
void device4Changed(uint8_t brightness);
亮度参数包含新的设备状态(0:关,255:开,1–254:暗),当调用回调函数时,Alexa 将发送该状态。**
但是回调函数可以是在 Alexa 命令下执行的任何函数,因此我们将在这里定义三个要调用的附加特殊函数,这些函数将处理多个物联网设备:
*void devFunc1Changed(uint8_t brightness);
void devFunc2Changed(uint8_t brightness);
void devFunc3Changed(uint8_t brightness);*
上述回调函数将与以下内容相关联:
- 所有家用设备(照明 1、照明 2、输出 1 和输出 2)
- 客厅(照明 1 和出口 1)
- 卧室(灯 2 和出口 2)
因此,Alexa 事实上将处理七个“物联网设备”。对于它们中的每一个,我们必须定义一个独特的名称,由 Alexa 调用:
*// device names
String Device_1_Name = "Red light";
String Device_2_Name = "Green light";
String Device_3_Name = "Blue light";
String Device_4_Name = "Yellow light";// device_function names
String Dev_Func_1_Name = "Living Room";
String Dev_Func_2_Name = "Bed Room";
String Dev_Func_3_Name = "All Home Devices";*
在测试阶段,我们将用“{其颜色}光”来称呼 led。在我们的最终项目中,我们可以通过变量的最终名称来改变这些变量(“Light 1”、“Outlet2”等)。
最后但同样重要的是,我们应该声明 espalexa 要使用的变量:
*Espalexa espalexa;*
对于交流:
*boolean connectWifi();
boolean wifiConnected = false;
const char* ssid = "YOUR SSID HERE";
const char* password = "YOUR PASSWORD HERE";*
在设置阶段,除了通常的 pin 和串行秃率定义以及通信启动程序之外,您还应该正确关联每个物联网设备及其名称,并启动 espalexa:
*// Define your devices here.
espalexa.addDevice(Device_1_Name, device1Changed);
espalexa.addDevice(Device_2_Name, device2Changed);
espalexa.addDevice(Device_3_Name, device3Changed);
espalexa.addDevice(Device_4_Name, device4Changed);// Define your devices functions here.
espalexa.addDevice(Dev_Func_1_Name, devFunc1Changed);
espalexa.addDevice(Dev_Func_2_Name, devFunc2Changed);
espalexa.addDevice(Dev_Func_3_Name, devFunc3Changed);espalexa.begin();*
循环函数应该非常简单:
*void loop()
{
espalexa.loop();
delay(1);
}*
最后一个程序将是创建回调函数,或者更好,当 Alexa 发送命令时必须做什么。
以下回调函数可适用于所有四种物联网设备:
*void deviceNChanged(uint8_t brightness)
{
//Control the device
if (brightness == 255)
{
digitalWrite(RelayPinN, HIGH);
Serial.println("DeviceN ON");
}
else
{
digitalWrite(RelayPinN, LOW);
Serial.println("DeviceN OFF");
}
}*
将上面代码中的“N”更改为 1、2、3 和 4 将会有四个直接回调函数。请记住,Alexa 发送的亮度参数包含新的设备状态,它将是:
- 0 == >关;
- 255 == >开
- 1 到 254 == >“暗灯”。
我们可以将上述简单的开关功能扩展为一种特殊的功能,在这种功能中可以控制光的强度。我们将为设备 1(红色 LED)执行此操作:
*void device1Changed(uint8_t brightness)
{
//Control the device
if (brightness == 255)
{
digitalWrite(RelayPin1, HIGH);
Serial.println("Device1 ON");
}
else if (brightness == 0)
{
digitalWrite(RelayPin1, LOW);
Serial.println("Device1 OFF");
}
else
{
int brigh_perc = (brightness/255.)*100;
analogWrite(RelayPin1, brightness);
Serial.print("Device1 Brightness: ");
Serial.print(brigh_perc);
Serial.println("%");
}
}*
请记住,NodeMCU 具有 PWM 输出,可用于 Arduino analogWrite()函数。如果使用 ESP32,则当 analogWrite()不可用时,应创建 PWM 功能。
完整的代码可以从我的 GitHub 下载:Alexa _ node MCU _ Home _ Automation
不要忘记用你自己的证书来更改虚拟 wifi 证书。
在 Arduino IDE 上编译代码并上传到 NodeMCU 后,您可以在串行监视器上看到交换的消息。一旦 NodeMCU 连接到您的 wifi,应该会出现类似的消息(包含您的网络数据):
Arduino IDE 串行监视器打印屏幕
我们认为您已经在与 NodeMcu 连接的 相同的网络上充分安装了 Alexa。
现在,让我们请 Alexa 找到您的设备。有两种方法可以做到:
- 使用智能手机中的 Alexa 应用程序
- 要求 Alexa 使用语音命令直接完成,比如:“ Alexa、 发现设备”。
45 秒后,您应该会收到 Alexa 确认信息,确认发现了七个设备。你可以在应用程序“灯光标签”上看到如下内容:
Alexa 应用程序(设备选项卡)—打印屏幕
一旦 Alexa 发现了你的设备,你可以给她语音命令,如下所示:
下面的屏幕截图显示了串行监视器的响应。
Arduino IDE 串行监视器打印屏幕
7.组装完整的硬件
输出 GPIOs 应连接到 4 通道继电器模型,而不是 led 和电阻,如下所示:
电路图—图片由作者提供
不要直接从 NodeMcu 5V 输出引脚给继电器模块供电。请改用外部电源。一个 1A 电源应该足够了。如果使用其他版本,请与继电器模块制造商确认。不要忘记将所有的 gnd 连接在一起。
原则上,可以使用为测试开发的相同代码,但是您必须确认继电器模块的逻辑。例如,在上述模块中,您应该保持输入“打开”或高电平,变为低电平以激活继电器输出。因此,代码必须相应地改变。
- 在 setup()阶段,将 GPIOs 输出定义为高电平
- 回调函数从高变低,反之亦然
您可以通过输出继电器关闭的声音和模块中的红色 led 来确认继电器是否正常工作。
一旦一切正常,就可以完成我们的“智能设备”的安装了,它们是两个固定的“灯”和两个“通用插座”,让我们对它们进行适当的重命名:
- 点燃一个
- 轻二
- 一号出口
- 二号出口
*// device names
String Device_1_Name = "Light One";
String Device_2_Name = "Light Two";
String Device_3_Name = "Outlet One";
String Device_4_Name = "Outlet Two";*
如本教程开头的视频所示,为了完成我们的项目,请连接一些由继电器控制的设备。在我的例子中,我使用两个 led 作为灯,并在插座 1 上连接一个风扇,在插座 2 上连接一个蜂鸣器(例如,模拟像收音机这样的设备)。下图显示了安装的设备。
电路图—图片由作者提供
请注意,一旦继电器能够处理它们,您就可以安装真正的交流灯和电器来使用 Alexa 进行控制。
8.关于“设备功能”的最后考虑
从模拟简单物联网设备的概念开始,如 WeMo 或飞利浦 Hue,我们还使用 Alexa“触发”更复杂的功能,“设备功能”。在这些功能上,多个输出被用作按房间划分的一组设备。
在我的教程中,电脑,发射所有武器,星际迷航企业的一些武器,比如光子鱼雷和相位炮,就是用这样的函数模拟的。
框图—作者提供的图片
这是物联网领域有待探索的强大工具,在这里,一个简单的语音命令可以触发使用微控制器的更复杂的过程,正如可以在下面的视频中看到的那样(这里使用了“计算机”wake-word 而不是“Alexa”):
结论
一如既往,我希望这个项目可以帮助其他人在激动人心的电子和物联网世界中找到自己的路!
更新文件请访问我的 GitHub:Alexa _ node MCU _ Home _ Automation
更多项目,请访问我的博客:MJRoBot.org
来自世界南部的 Saludos!
我的下一篇文章再见!
谢谢你
马塞洛
主场优势:没有粉丝还存在吗?
实践教程
疫情时代之前和期间的数据和统计
在大多数运动项目中,人们普遍认为主队对客队有显著优势,俗称主场优势。这可能是由多种因素造成的,但两个最受欢迎的原因是粉丝的出现和玩家对环境的熟悉和舒适。后者的一个标志性例子是波士顿红袜队在芬威公园的“绿色怪物”墙。然而,一些研究和数据表明,球员熟悉度是主场优势效应的一个令人惊讶的微弱预测因素。
因此,还有一个最受支持的原因,那就是粉丝的存在。有趣的是,在疫情冠状病毒爆发时,大多数体育场都不对公众开放,主场优势似乎也逐渐消失了。这为分析这个自然实验创造了一个理想的场景。
我想回答的问题很简单:我能使用数据分析和统计推断来衡量球迷在足球比赛中对主队的影响吗?我会那样做的。而我会重点关注英格兰的英超数据。
为什么是足球?为什么是英超?
在选择要调查的运动之前,我考虑了世界顶级联赛中的一些主要运动,每个运动都有一些缺点:
- 篮球——鉴于漫长的赛季和室内体育场吸引了喧闹而充满活力的球迷,NBA 起初似乎是一个不错的选择。然而,在他们 19-20 赛季的重新开始阶段,所有的比赛都是在奥兰多泡泡里进行的,所以没有真正的“主场”。
- 棒球——疫情开始的时候,MLB 赛季还没有开始,相对于其他运动,主场优势通常并不高。
- 美式足球 —相对于其他运动,NFL 赛季非常短,不会为我们提供大量实验数据。
足球似乎是最值得研究的运动,特别是因为它的主场优势在大多数运动中是最强的,而且闭门比赛的次数也足够多。我会选择英超联赛,因为它往往有更多平衡的球队,这意味着更多的球队可以在特定的日子里击败另一支球队,并在特定的赛季中位居联赛榜首。在其他大联盟,如德甲或西甲,每年似乎都有 2-3 支球队占据主导地位。你知道我指的是哪些团队。
最初的假设或期望
在收集我需要的数据之前,我对在没有球迷的比赛中看到的数据有一些猜测:
- 主场优势减少,意味着进球和得分减少
- 一场更加平衡的比赛,对客队的犯规更少,因为裁判不会受到吵闹或心烦意乱的球迷的压力
- 主队付出的努力越少,导致比赛最后几分钟射门次数和进球次数越少
数据:Python 中的集合
数据:2019-2021 年的比赛(2019 年 8 月 9 日-2021 年 3 月 15 日)
我将使用由奥特维奥·西莫斯·西尔维拉创建的 Python & Selenium scraper,并在此基础上构建以满足我的特定需求。
具体来说,我希望收集每场比赛主客场球队的以下数据:
- 决赛和半场比分
- 比赛数据(控球、黄牌、投篮等。)
- 指示进球得分时间的特定分钟标记
为每个匹配抓取的页面详细信息的示例截图。 注: 英超 允许提取数据用于非商业用途 条款&条件
你可以在这里找到我用的刮刀。
数据:R 中的预处理
我想做的第一件事是在 R 中进行预处理,并进行一些数据辩论,这将允许我进行所需的分析和实验。
让我们装入必要的包和我们的数据,确保每场比赛的日期都被正确读取。
library(dplyr)
library(ggplot2)
library(ggpubr)
library(lubridate)
library(stringr)
library(zoo)df <- read.csv('data/premier_league_matches.csv') %>% mutate(date = lubridate::as_date(date))
接下来,我们将删除 20-21 赛季期间任何球迷人数有限的比赛。只有少数比赛是在 2020 年 12 月的进行的,当时联赛允许在某些体育场最多容纳 2000 名观众,然后再次恢复完全封闭。这些是具有未知影响的异常值,所以最好不要考虑它们。
# matches with limited attendance (2,000 fans) in December 2020
limited_fans_matches <- c(59005, 58999, 59003, 59000, 58997, 59008, 59014, 59007, 59009, 59006, 59024, 59033, 59030, 59026, 59041)df <- df %>% subset(!match_id %in% limited_fans_matches)
让我们也创建新的列来跟踪每个队的犯规、得分和结果。
df <- df %>%
mutate(home_yellow_cards_pct = home_yellow_cards / (home_yellow_cards + away_yellow_cards),
away_yellow_cards_pct = away_yellow_cards / (home_yellow_cards + away_yellow_cards),
home_fouls_conceded_pct = home_fouls_conceded / (home_fouls_conceded + away_fouls_conceded),
away_fouls_conceded_pct = away_fouls_conceded / (home_fouls_conceded + away_fouls_conceded),
home_points_won = ifelse(home_ft_score > away_ft_score, 3, ifelse(home_ft_score == away_ft_score, 1, 0)),
away_points_won = ifelse(away_ft_score > home_ft_score, 3, ifelse(away_ft_score == home_ft_score, 1, 0)),
home_result = ifelse(home_ft_score > away_ft_score, 'W', ifelse(home_ft_score == away_ft_score, 'D', 'L')),
away_result = ifelse(away_ft_score > home_ft_score, 'W', ifelse(away_ft_score == home_ft_score, 'D', 'L')))
为了跟踪进球得分的不同分钟间隔,我们需要转换home_goal_mins
和away_goal_mins
中的分钟格式,以便每个值都用逗号分隔。
df <-
df %>%
mutate(home_possession = home_possession/100,
away_possession = away_possession/100,
home_goals_mins = c(str_replace_all(str_sub(home_goals_mins,
2, -2), fixed(" "), "")),
away_goals_mins = c(str_replace_all(str_sub(away_goals_mins,
2, -2), fixed(" "), ""))) %>%
mutate(across(c('home_goals_mins', 'away_goals_mins'),
~ifelse(.=="", NA, as.character(.))))
最后,我们将为我们的实验创建两个相等的数据集(每个数据集 288 场比赛),假设联盟在 2020 年 6 月 17 日开始在没有球迷的情况下比赛:
- **控制设置:**仅匹配风扇
- **测试集:**仅匹配无风扇
no_fans_df <- df %>%
filter(date >= '2020-06-17') %>% arrange(date) %>% head(288)
no_fans_df['fans_present'] <- 'N'fans_df <- df %>%
filter(date <= '2020-03-09')
fans_df['fans_present'] <- 'Y'matches_df <- rbind(fans_df, no_fans_df)
现在我们有了一个最终的数据帧,它带有我们实验中匹配类型的标签。这样就容易比较两者了!
探索性数据分析
我们首先要看的是主客场两队在比赛中的进球分布。进球似乎出现在半场的前几分钟或最后几分钟,原因是注意力不集中、疲劳,以及为了赢得比赛而承担更多风险。在比赛的不同阶段,球迷的能量也可能很高。
不幸的是,这两种匹配类型之间似乎没有任何真正的区别。大多数进球都是在比赛进行到一半和结束时打进的,这可能是由于加时赛的缘故。
接下来,我们将查看两个数据集之间匹配结果的差异。
正如猜测的那样,当球迷不在场时,主队赢得的比赛更少,输掉的比赛更多。抽签的次数大致相同。乍一看,这似乎表明观众对主队有积极的影响。
让我们以不同的方式来看待主场胜利,看看获胜分数占总可能分数的比率。我们称之为主场优势并按月汇总。
每月赢得的主场积分/可能的总积分比率
再一次,这个图像支持了我们上面的观点,主场优势随着体育场的关闭而逐渐减少。
如果我们在一段时间内用类似的图表绘制一场比赛中客场队的黄牌分布,我们会看到在比赛数据集之间客场队的黄牌数量有更大的差异。当球迷不在的时候,客队似乎要轻松得多!
每月发放客场黄牌
我们想看的最后一个方面是主队的总射门次数。
当球迷在场时,主队拍摄的照片大约有 500 张之差。但是有多少镜头是真的对准目标的呢?让我们检查一下。
每月的目标命中率
假设检验
虽然很容易理解数据可视化,但我们不能仅仅依靠它们来确定粉丝存在与否的意义。为此,我们需要对我们的实验进行统计推断测试。
统计推断让我们更加确信,我们在样本数据之间看到的任何差异在一定程度上都是显著的,并且观察到的结果不仅仅是由于偶然。
我们将运行四个测试来观察以下情况:
- 主队得分差异*(主试)*
- 主队犯规次数的差异
- 客队承认的黄牌数量的差异
- 主队射门方式的不同
对于每个测试,我们将首先计算测试的统计功效,这将给出当这种差异实际存在于总体中时,测试将发现统计显著差异的概率。换句话说,能力是你应该拒绝零假设的概率。然后,我们将使用学生的 t 检验进行实际的假设检验。我们将对每一个使用 90%的置信区间。
功率测试
首先,让我们使用 r 中的pwr
库计算主测试的功效。我们需要计算每个样本的平均值、总标准偏差和一个称为效应大小的值,该值定义为:
测试的工作方式是,您必须只设置一个参数与NULL
相等,这是在给定其他数据点的情况下您想要计算的参数。
library(pwr)meanF <- mean(fans_df$home_points_won)
meanNF <- mean(no_fans_df$home_points_won)
sd <- sd(matches_df$home_points_won)
effect_size <- (meanF — meanNF) / sd
pwr.t.test(n = 288, d = effect_size, sig.level = 0.1, power = NULL, type = “two.sample”)#######OUTPUT########Two-sample t test power calculationn = 288
d = 0.130097
sig.level = 0.1
power = 0.4665975
alternative = two.sidedNOTE: n is number in *each* group
我们将对剩余的测试进行同样的操作,并整合结果。
我们如何解读这种力量?一般认为功率应该等于或大于 80%。对于我们与主场得分相关的主要测试,这意味着我们有 47%的机会发现统计上的显著差异。这不是一个好兆头。但是其他测试的功率是 95%或更多,这是有希望的。
统计 T 检验
接下来,我们将进行 t 检验,以确定有球迷和没有球迷的主场平均得分是否存在显著差异。
- **零假设:**两个样本的均值差为 0
- **备择假设:**均值之差不等于 0。
t.test(fans_df$home_points_won, y=no_fans_df$home_points_won, alternative = 'two.sided', conf.level=0.90)#######OUTPUT#######
Welch Two Sample t-testdata: fans_df$home_points_won and no_fans_df$home_points_won
t = 1.5631, df = 573.85, p-value = 0.1186
alternative hypothesis: true difference in means is not equal to 0
90 percent confidence interval:
-0.009373031 0.356595254
sample estimates:
mean of x mean of y
1.593750 1.420139
再一次,我们将对我们所有的假设进行测试。
为了达到显著性,计算的 p 值必须小于使用的显著性水平,在本例中为0.10
,这允许我们拒绝零假设。对于我们与有球迷和没有球迷的主队得分差异相关的主要测试,p 值为0.1186
,表明没有统计学意义。然而,其余的测试都非常显著,p 值接近 0!
总结:主要发现和要点
总的来说,这个实验表明,当球迷缺席时,通常观察到的足球主场优势在某些方面被最小化了。
- 主队往往得分更少(因此得分也更少),但观察到的数据没有统计学意义来支持这一点。
- 然而,数据确实支持这样的观察,即没有球迷的主场球队会收到更多的犯规,而与之相关的是,客场球队承认的黄牌更少。这是有道理的,因为比赛结果的另一个关键因素是裁判,他受到来自球迷的压力,要判还是不判犯规。
- 此外,在没有球迷压力的情况下,主队的投篮次数要少得多,但这并不一定会导致目标或进球的投篮次数有很大差异。
这些因素都有助于比赛更加平衡,从而减少主场优势。
除了风扇的存在,许多因素也可能影响观察到的结果。例如,两个数据集之间匹配结果的差异可能是不平衡的。如果高质量的球队在一组样本中有更多的客场比赛,这可能会引入更多的偏见。许多人可能会认为球员/教练的技能比比赛是主场还是客场更能决定比赛结果。
建立解决这些偏见的模型,并收集更多关于体育界这种罕见现象的数据,可能有助于提供更多答案。在那之前,球迷似乎会影响足球的主场优势,但不是以我们所期望的最纯粹的方式。
希望你喜欢这个项目。如果对类似的文章感兴趣,可以看看我的另一篇文章。
感谢肯·吉在追求一个体育分析项目中的灵感。如果您有任何问题,请随时在下面评论或通过 LinkedIn 联系我。
参考
- n .巴尔默、a .内维尔和 s .沃尔森(编辑。).(2005).主场优势【特刊】。体育科学杂志,23 卷 4 期。
- 卢海德,托德&卡伦,艾伯特&布雷,史蒂文&金,李北。(2003).职业运动中的设施熟悉度和主场优势。国际运动和锻炼心理学杂志。1.264–274.10.1080/1612197X
- 索尔.麦克劳德。"效果大小。"单纯心理学,单纯心理学,2019 年 7 月 10 日,【www.simplypsychology.org/effect-size.html.】T2
- 奥特维奥·西莫斯·西尔韦拉。"如何建立一个足球数据集与网页抓取."中,向上编码,2020 年 10 月 20 日python . plain English . io/how-to-build-a-football-dataset-with-web-scraping-D4 deffcaa 9 ca
使用 HuggingFace Spaces 托管 ML 应用程序
探索新的 HuggingFace 版本
我一直是 NLP 的超级粉丝,因此也是一个超级拥抱脸粉丝。虽然 HuggingFace 以其强大的 NLP 背景而闻名,但他们最近发布了一个名为 Spaces 的新功能,可以帮助你在你的个人资料上快速托管 ML 演示应用。Spaces 支持两个可以快速构建 Python 应用的框架:Streamlit 和 Gradio 。我也是 Streamlit 的忠实粉丝,所以我们将使用该框架为今天的文章构建一个示例空间应用程序。如果你想要更多的灵活性和对你的前端的控制,你可以使用一个定制的框架或者使用你自己的 HTML 代码。
注意:在这篇文章中,我们不会真正关注任何模型构建包,它将集中在展示空间特性的功能上。
目录
- 设置
- 构建应用程序和测试
- 结论和附加资源
1.设置
要开始使用共享空间,您需要在以下链接创建一个 HuggingFace 个人资料帐户。
作者截图(创建拥抱脸个人资料)
如果你想和其他成员合作,你可以在这里添加额外的功能,比如 Github 或者 Twitter 用户名。之后,点击“创建新空间”,你就可以设置你的项目了。
作者截图
在本例中,我们将使用 Streamlit 并创建一个公共工作区。对于自定义 SDK,请通过“添加您的”链接与 HuggingFace 联系。
创建完共享空间后,我们可以导航到“文件和版本”来管理我们的目录。首先 创建一个 requirements.txt 文件,其中包含任何额外的依赖项,这就是 Spaces 将如何在您正在使用的框架中使用的方式。Spaces 附带了以下预装库 : huggingface_hub 、请求和数据集。在 requirements.txt 中,我们将添加用于情感分析的变形金刚和文本块库。
申请要求
接下来创建一个“app.py”文件,这是我们的应用程序代码将被创建的地方。文件结构应该如下图所示。
作者截图
2.构建应用程序和测试
现在我们可以编辑 app.py 文件来构建我们的应用程序。我们将制作一个简单的应用程序,它提供了使用两种不同框架对一些样本文本进行情感分析的选项。创建文件时,您可以在共享空间左上角的应用程序选项卡上预览文件的外观。
App 预览(作者截图)
现在我们可以添加一些基本的逻辑来使用任何一个可用的框架。
情感分析
我们现在可以用两种不同的框架来测试我们的应用程序。
变形金刚情绪分析(作者截图)
Textblob 情感分析(作者截图)
在 10 分钟内,我们成功部署了一个简单而强大的演示应用程序,可以公开共享。要调整应用程序的任何旋钮,您也可以进入设置选项卡将空间设为私有或将其删除。
3.结论和附加资源
演示应用程序的完整代码
如果您没有自己的基础设施设置,Spaces 是一个非常有用的新特性,可以快速测试和演示 ML 应用程序。我很好奇 HuggingFace 在为您的应用程序带来自己的前端堆栈/框架方面提供的未来灵活性。如果你想看视频演示,看看下面的教程 HuggingFace 发布。对于不同的接触面管道和任务,查看以下文档。
如果你喜欢这篇文章,请在 LinkedIn 上与我联系,并订阅我的媒体 简讯 。如果你是新手,使用我的 会员推荐 报名。
主持代码评审会议可以对您的数据科学团队产生积极影响
为什么我每周和我的团队召开代码审查会议
图片来自 Unsplash 上的 Artem Sapegin
每个周末,我都会主持一个代码审查会议。在 30 分钟内,一小组数据科学家聚在一起,查看对我们的库的任何开放拉取请求。当我的团队第一次开始打开拉请求和审查代码时,感觉就像是一件苦差事。评审开始得很好,但是开始变成一个人催促团队的其他人完成他们的评审。随着越来越多的拉请求开始到来,我们的团队决定改为主持每周的代码审查会议。这些会议改变了我们看待代码的方式。这不再是一件琐事,而是对设计决策、假设和代码架构的公开讨论。
在这些会议中,我们召集了一小组不同的数据科学家来检查从分析到工具开发的任何开放拉动请求(PRs)。这个组包括最初打开拉请求的开发人员和一些不同的团队成员。我们有一个核心小组,参加每一次审查,然后每周改变我们加入的人,以获得审查代码的经验。
让不同的人轮流查看“拉”请求,可以让他们在阅读和理解我们图书馆的各个方面时有所体会,而这些方面他们可能并不熟悉。
随着会议的进行,我们一次打开一个拉式请求。编写代码的首席数据科学家将讨论他们做了哪些更改,为什么要做这些更改,并讨论他们做出的任何决定。当有人对代码有疑问时,我们有一个开放的论坛来讨论它,然后留下评论。这允许我们在确定下一步之前讨论设计决策和假设。
这些审查顺利吗?开始时,有点困难,但通过有规律的节奏,这已经成为一个更顺利的过程。
为什么要举办同行评议会?
无论您是在笔记本上编码还是在开发库,代码评审都是一个有益的工具,可以让数据科学家检查某人正在开发的代码。代码审查还可以向数据科学家介绍他们在查看其他人的工作时不熟悉的新库和技术。允许不同级别的数据科学家评审代码将允许每个人提供反馈,并将代码评审作为学习和个人发展的工具。
不要把你的评论当成是针对个人的。相反,使用它们来理解如何使您的代码更干净、更高效。确定你能从这个过程中学到什么。
我主持代码审查会议,因为它们允许对代码进行讨论,并给数据科学家一个与其他人讨论他们的设计决策的论坛。因此,在听完他们为什么以一种特殊的方式开发代码之后,更容易对代码做出评论。
不同级别的数据科学家都有机会在研究代码、讨论过程和展示工作成果时向他人学习。人们有不同的学习方式,对一些人来说,让他们一起浏览代码会有所帮助。这些会议是一个安全的地方来演示代码,请求反馈,并确定合并代码需要什么。
以这种方式参与评审可以让年轻的数据科学家对他们的代码能力更有信心,并看到即使是高级数据科学家也没有完美的代码。
最后,我在团队中实施的审核流程进展顺利。在开始这些会议之后,在对拉取请求进行评论之前,数据科学家之间就变更达成一致变得更加容易。这一流程大大减少了分歧或误解,因为在电话会议期间,所有相关方都会到场公开讨论他们的意见。
总而言之,代码评审会议比个人在自己的时间内评审代码对我的团队更有益。这些会议允许数据科学家就代码更改达成一致,并在整个过程中快速移动拉请求。我们可以在下一次会议之前批准大多数拉动式请求,而不是等待几周,让两三个人找到时间进行审查。
最后的想法
您的团队可能会以不同的方式进行代码评审,但是对于我的团队来说,我们发现每周召开一次 30 分钟的代码评审会议是最好的。在这些会议中,我们可以讨论、演示和确定被检查代码的后续步骤。
- 不同级别的数据科学家可以聚在一起讨论代码,互相学习。
- 我们在每次会议上轮换人员,让人们了解代码库的各个方面。
- 这些会议提供了一个公开的论坛来讨论为什么数据科学家应该改变代码,并且可以对前进的道路做出决定。
- 这是一个安全的地方,可以公开讨论数据科学家的意见分歧,从而减少对代码更改的争议或分歧。
你如何在你的团队中评审代码?
</4-things-i-didnt-know-about-being-a-team-lead-in-data-science-1f96293cb8aa>
空话:政治中的话语
应对气候危机是当前决定性的生存挑战,2018 年诺贝尔经济学奖由威廉·诺德豪斯和保罗·罗默(美国)获得,他们证明了碳定价将是应对气候危机的有效策略。因为有政府程序的公开记录,而我是 NLP 的专家,我看到了我能看到的政府和政治数据。这是我发现的非常敷衍的初步看法。我在这里使用的数据来自 openparliament.ca,它使跟踪政府通过法案的进展变得容易,并提供了众议院会议的议事录。
*英国议会议事录是对加拿大、英国、新西兰和其他威斯敏斯特体系政府的下议院会议记录进行轻微编辑的公开信息记录,以一名在报纸上发表英国议会会议记录的英国议员命名。(美国人:假装我说的是国会。我没有,现在也没有,但这就足够了。)
为此,我使用了 2000 年 1 月 1 日至 2020 年 8 月间的会议记录。由于加拿大议会有两种官方语言的声明,我将英文声明分离出来。演讲者以演讲者的身份所做的陈述往往是非常标准化的,并且只是程序的一部分,所以我删除了它们。
https://www.lingo-ninja.com/RepsVsDems
这是一篇有趣的文章,它展示了在做出任何结论之前实际查看数据的重要性。他们声称,与你的预期相反,对于美国政客来说,共和党人倾向于使用更大的词汇量,莎拉·佩林是所有人中词汇量最大的,特朗普的词汇量比乔·拜登大。尽管我愿意接受统计数据,但退一步说,我发现这些结论非常令人惊讶。粗略地看一下他们的方法,他们不做任何形式的词汇化、拼写纠正、标点符号或停用词删除,他们只是使用一个记号化器。这意味着特朗普有可能通过 hamberders 和可变大小的省略号拥有大量词汇……
为了避免指责列出街道名称的议员词汇量太大,我使用了 spaCy 的 en-core-web-sm POS tagger,并删除了停用词、标点符号和专有名词。那些年有 1000 多名议员坐过,这些议员讲了大约 86 万次。
由于单个议员说的单词数量可能相差很大(更准确地说,是 7 到 2615448 个),原始词汇比较几乎是不公平的。由于停用词的使用和标点符号的出现或多或少是一个常数,我将它们有意义的词的范围按照它们发出的总标记来划分。这种调整是标准化步骤。因为我很好奇词汇是否会随着时间的推移而改变,所以我绘制了归一化词汇大小与在职议员开始日期的关系图。
作者图片
Flesch 阅读难易程度评分:
Flesch 阅读难易程度评分是一个由句子长度和所用词汇组合而成的指标。下图让我有点吃惊,但经过研究后,还是有意义的。关于 Flesch 分数,需要注意的一点是,分数越高,越容易阅读。如下图所示,最难读懂的议员来自由魁北克集团和新民主党成员组成的民主力量党。由于 Forces 是由受过高等教育的前议员(其中一名创始成员是大学教授)组成的,因此他们的语言水平高于自由党或保守党也就不足为奇了,因为这些政党拥有非常广泛的基础。Flesch-Kincaid 年级水平是一个将 Flesch 阅读难易程度评分(基于句子长度和词汇量)与 Kincaid 年级水平指标相结合的指标。为此,我使用了 textstat,这是一个内置了所有这些功能的 Python 包。
查找常用短语:
对于更大的统计数据,如估计的相对词汇和阅读方便性,我从 2000 年 1 月 1 日起在每份法案上使用陈述,但由于这个想法是为了找出政治家如何谈论气候政策,我提取了在“碳”或“环境”的法案上的陈述。
我在这里采用了两种方法来统计主要短语。其中一个是手动计算使用的 4gm,另一个是使用 TextBlob,这是一个 Python 库,可以进行名词短语分块。我使用了 nltk 标记器,并消除了停用词,我发现每一方的二元模型基本上都是无用的。在所有政党中,最常见的连词是“碳税”、“首相”、“环境部长”、“温室气体”和“自由政府”。对人类的眼睛来说,那里没有任何东西表明特定的极性。这是有道理的,在环境/气候背景下,这些是最常见的二元模型,不管你对它们的感觉如何。当你看四个单词的短语时,一个更有趣的画面出现了。
作者图片
绿色、自由和保守的 4 个字母
在这里,你可以看到更多证据,证明不同政党在谈论碳税时使用的口号。保守派真的喜欢称碳定价为“扼杀就业的碳税”,而自由派通常喜欢说“环境和经济齐头并进”的变体。绿党必须包括在内,因为他们是一个全国性的政党,主要关注气候和环境,但由于他们目前有史以来最高的 3 名议员,他们的声明经常反映出绿色参与具体的法案,如育空环境社会经济评估法案。
基于启发式的主题模型
这些是最需要人工提取的短语,通常的主题模型表现如何?以下是 LDA 发现的与 5 个主题相关的单词:
作者图片
LSI 发现了 5 个主题:
作者图片
评估无监督的主题模型是一个挑战,但由于这是人类语言,并且只有 5 个主题被选择,对这一点的判断纯粹是主观的。
在我看来,LDA 的主题稍微好一点,但它们基本上只是表明议员们讨论了环境、气候、碳、育空、魁北克和艾伯塔。由于育空地区位于北部,有很多采矿和资源开采活动,艾伯塔省和育空地区都有重油和天然气开采活动,因此它们经常出现在议会讨论中是有道理的。魁北克是最大的省份,拥有丰富的自然资源,所以它会出现在环境问题的讨论中——但它在政府中也有很高的代表性,是一个常见的参考点。
在很大程度上,我称之为“热空气”是因为缺乏一个真正好的双关语,但也是因为在用最常见和最容易获得的技术查看数据后,很难客观地发现不同政党之间的区别,即使他们的投票记录表明他们在那里。Suhas Pai(基岩公司首席技术官。AI 和 NLP guru)认为,由于下议院中任何长于感叹词的演讲都是由他们的团队精心制定的,因此议会演讲不是文本信息的良好来源。我倾向于这一结论,因为除了“扼杀就业的碳税”等众所周知的保守派词汇和“环境和经济齐头并进”等自由派词汇,还没有太多分析表明政党话语中有意义的差异。
热狗还是不是热狗
用 Tensorflow 2 尝试著名的 CNN 模型来帮助杨坚
输出图像
介绍
你看过 HBO 的《硅谷》喜剧系列吗?如果是这样,我打赌你还记得杨坚开发的非热狗应用。这里有一个片段可以提醒你。
所以基本上这个应用程序识别某样东西是不是热狗。嗯,我们也可以用其他类型的物体来训练识别它们。
当我了解到 CNN(卷积神经网络)的时候,我很渴望在这个问题上尝试一些流行的 CNN 模型,只是为了好玩。所以我选择了一些最好的 CNN 模型来尝试。
对于这个问题,我使用了以下模型,
- AlexNet 的变体
- 使用 VGG19 进行迁移学习
- 使用 ResNet50 迁移学习
- 使用 Inception V3 进行迁移学习
- 借助 Inception ResNet V2 迁移学习
你可以在 NBViewer 上查看笔记本,也可以在 GitHub 上找到,
https://github.com/scsanjay/case-studies/tree/main/02. Not Hotdog
数据
没有高质量的数据,就没有机器学习。谢天谢地,我在 ka ggle【1】上找到了一个数据集。
总共有 3000 张图片可用于训练。
其中 1500 是热狗图像, 1500 不是热狗(它们是食物、家具、人或宠物)。
训练数据的 20% 将用于验证,这意味着 600 张图像将用于验证。
测试集有来自热狗类别的 322 图像和来自热狗类别的 322 图像。
在加载的时候,我已经将所有图片的尺寸调整为 256x256。另外,我已经将它们分成 32 的批量。
让我们看一些图片,
数据样本
预处理
调整大小
将所有图像转换为相同大小的预处理步骤已经完成。
数据扩充
数据扩充是非常有用的一步。这有助于使模型更好地泛化。此外,它从给定的图像生成新的图像,这增加了我们的数据集的大小。
怎么会?它可以执行各种操作,如翻转、旋转、剪切、缩放等,以创建增强的数据。请注意,TensorFlow 是动态完成的,这意味着我们不必保存图像,但它们将在训练时生成。
我已经执行了以下数据扩充操作,
a)水平翻转
b)旋转
c)缩放
在数据扩充之后,我们可以期待如下所示的图像,
扩充数据
改比例
我们应该将像素从[0,255]重新调整到[0,1]。我将只应用于 AlexNet。
在使用预训练模型进行迁移学习的情况下,我们将仅使用相应模型的预处理。
模型结构
AlexNet
AlexNet 用了三大概念,
1。数据扩充—增加数据的方差。
2。辍学——应对过度适应。
3。ReLU 激活单元——处理消失梯度问题。
我已经创建了一个 AlexNet 架构的变体,并在这里和那里进行了退出和批处理规范化。总共有 58,286,465 个可训练参数。最后一层有 1 个乙状结肠活化单位。
我将使用基于二进制交叉熵的 Adam 优化器进行优化。我们也会保持准确性。
我已经运行了 10 个纪元。我还添加了一个提前停止的回调函数来监控 val_loss。我们通过验证数据得到了 69.00% 的准确度,通过测试数据得到了 68.47% 的准确度。这并不令人鼓舞。如果我们进行调整或拥有更多数据,我们可以取得更大的成就。
使用预训练的 VGG19 进行迁移学习
迁移学习
迁移学习是一种非常酷的技术。在迁移学习中,我们加载一个预先训练好的模型。我们移除模型的顶部(最后几个致密层)。然后我们冻结预训练模型的卷积基。现在我们可以使用这个预先训练的模型作为特征提取器。
在迁移学习中,有时我们也可以使用预训练模型进行权重初始化,然后训练整个模型。这通常发生在我们有大量数据和/或预训练模型没有在类似数据上训练的时候。
VGG19
VGG19 来自视觉几何组。它有 19 层。它有一个新的想法,当我们使用多个小内核而不是较小的大内核时,可训练参数的数量会减少。此外,它到处使用相同的 3x3 大小的内核和 2x2 最大池,这简化了架构。
我已经用 ImageNet 权重加载了 TensorFlow Keras 预训练的 VGG19 模型,没有顶层。
然后我将这个基础模型设置为不可训练。
在模型架构中,
I)我首先添加了输入层。
ii)然后是数据扩充层。Tensorflow 将自动管理扩增仅用于训练。
iii)然后我用了 VGG19 模型的预处理。
iv)之后,我使用了基础模型,即预训练的 VGG19 模型。这是不能按照迁移学习来训练的。
v)然后我使用了全球平均池 2D 层。
vi)然后是一个展平层。
vii)然后是具有 1000 个 Relu 激活单元的全连接致密层。为了正规化,我也加入了退学。然后我添加了一个线性激活单元。因为我将在二进制交叉熵中使用 from_logits=True **
** 来获得概率。
它有 514,001 个可训练参数和 20,024,384 个不可训练参数。
和前面一样,我们使用了 Adam 优化器和二元交叉熵。
这次我们用验证数据得到了 93.17% 的准确率,用测试数据得到了 93.47% 的准确率。这是一个很大的进步。
使用预先培训的 ResNet50 进行迁移学习
ResNet50 由何等人创造。它有 50 层。它引入了剩余块的概念。它有助于建立深度大的模型。剩余的块具有跳过连接,所以如果一个块是无用的,那么它就被忽略。
我们按照与上面相同的步骤来创建相同的结构。唯一的区别是基础模型现在是 ResNet50,预处理是 ResNet50。
它有 2,050,001 个可训练参数和 23,587,712 个不可训练参数。
编译和拟合阶段与上面类似。而这次,我们用验证数据得到了 94.33% 的准确率,用测试数据得到了 94.56% 的准确率。比以前有了一点点进步。
通过预先培训的 Inception V3 进行迁移学习
Inception v3 是第三个版本。它是由谷歌开发的。它有 48 层。初始网络不是一次使用一个卷积,而是同时使用所有 1x1、3x3、5x5 和 MaxPool。这个想法是,较小的内核将获得本地信息,而较大的内核将获得全局信息。它还有一个叫做瓶颈层的技巧,可以显著减少计算量。
同样,我们已经将基本模型更改为 Inception V3 以及预处理步骤。
它有 2,050,001 个可训练参数,与 ResNet50 相同,还有 21,802,784 个不可训练参数。
编译和拟合阶段与上面类似。通过验证数据,我们得到了 92.67% 的准确率,通过测试数据,我们得到了 94.40% 的准确率。比我们用 ResNet50 得到的要少。
通过预先培训的 Inception ResNet V2 迁移学习
盗梦空间 ResNet V2 由谷歌开发。他们在盗梦空间中增加了 ResNet 的跳过连接。它允许创建一个更深的 164 层网络。
我做了和上面类似的改动。
它有 1,538,001 个可训练参数和 54,336,736 个不可训练参数。
编译和拟合阶段类似于我们到目前为止所看到的。通过验证数据,我们得到了 95.33% 的准确度,通过测试数据,我们得到了 96.42% 的准确度。迄今为止最好的一个。
测试输出
所有四种迁移学习模式的表现都很相似,而且相当不错。
然而,盗梦空间 ResNet V2 在我们的案例中具有最高的准确性。因此,我们将使用它来显示一些带有测试图像的输出。
测试输出
最后的想法
如果你看到我们只为模型做了几件事,数据扩充,预处理,加载基础模型,并在顶部添加几层。我们能够达到 96.30%的准确率。这是因为迁移学习。我们可以在基础模型中增加更多的可训练层。这可以提高精确度。
参与这个项目非常有趣。也是一次很棒的学习经历,因为这是我的第一个深度学习项目。
深度学习发展非常快。每天都有新的研究论文发表。只有少数人制作了这些作品。深度学习就是要聪明。在所有的模型中,我们在上面看到,他们引入了一些新的聪明的技术。
参考
- 张量流[https://www.tensorflow.org/]
- 数据集:Jain,Yashvardhan。2019 .热狗-不是热狗。
版本 1。许可证 CC0:公共领域。可从以下网址获得:https://www . ka ggle . com/yashvrdnjain/hotdognotdog/metadata - 应用根[https://www.appliedroots.com/
**感谢阅读博客!**你可以通过我的 LinkedIn 个人资料联系到我。也👏如果你喜欢的话。
酒店收入预测:用 ARIMA 预测 ADR 波动
使用 ARIMA 预测日平均利率
来源:图片由 nattanan23 来自 Pixabay
平均每日房价(以下简称为 ADR)代表入住酒店的顾客每天支付的平均房价。
这是一个酒店的重要指标,因为它代表了每个客户的整体盈利能力。
在本例中,每个客户的平均日费率是每周的平均值,然后使用 ARIMA 模型进行预测。
以下分析基于来自 Antonio、Almeida 和 Nunes (2019)的数据:酒店预订需求数据集。
数据操作
在这个特定的数据集中,每个客户的年数和周数(以及每个客户记录的 ADR 值)是单独提供的。
以下是日期栏:
来源:Jupyter 笔记本输出
以下是 ADR 栏:
来源:Jupyter 笔记本输出
首先,年份和周数被组合成一个字符串:
df1 = df['ArrivalDateYear'].map(str) + df['ArrivalDateWeekNumber'].map(str)
print (df1)
df1=pd.DataFrame(df1)
然后,使用 pandas 将新列与 ADR 列连接起来:
df2 = DataFrame(c, columns= ['ADR'])
df2df3=pd.concat([df1, df2], axis = 1)
df3
df3.columns = ['FullDate', 'ADR']
这些值随后按日期排序:
df3
df3.sort_values(['FullDate','ADR'], ascending=True)
来源:Jupyter 笔记本输出
下一步是获得每周的平均 ADR 值,例如,对于条目 201527(2015 年第 27 周),对所有 ADR 值进行平均,以此类推每个后续周。
df4 = df3.groupby('FullDate').agg("mean")
df4
df4.sort_values(['FullDate'], ascending=True)
来源:Jupyter 笔记本输出
ARIMA
使用这个新形成的时间序列,ARIMA 模型现在可以用来预测 ADR。
对于该模型,前 100 周的数据用作训练数据,而后 15 周的数据用作测试数据,与模型做出的预测进行比较。
这是新形成的时间序列图:
来源:Jupyter 笔记本输出
从图表的初始视图来看,季节性似乎确实存在。然而,在训练数据上生成自相关函数来验证这一点。
plot_acf(train_df, lags=60, zero=False);
来源:Jupyter 笔记本输出
我们可以看到相关性(大约在第 10 周到第 45 周之间有所下降),自相关在第 52 周再次达到峰值,这意味着每年的季节性。这实质上意味着每 52 周记录的 ADR 值之间有很强的相关性。
使用该信息, m=52 被设置为 ARIMA 模型中的季节分量,并且 pmdarima 被用于自动选择模型的 p,d,q 参数。
>>> Arima_model=pm.auto_arima(train_df, start_p=0, start_q=0, max_p=10, max_q=10, start_P=0, start_Q=0, max_P=10, max_Q=10, m=52, stepwise=True, seasonal=True, information_criterion='aic', trace=True, d=1, D=1, error_action='warn', suppress_warnings=True, random_state = 20, n_fits=30)Performing stepwise search to minimize aic
ARIMA(0,1,0)(0,1,0)[52] : AIC=422.399, Time=0.32 sec
ARIMA(1,1,0)(1,1,0)[52] : AIC=inf, Time=21.87 sec
ARIMA(0,1,1)(0,1,1)[52] : AIC=inf, Time=48.20 sec
ARIMA(0,1,0)(1,1,0)[52] : AIC=inf, Time=40.99 sec
ARIMA(0,1,0)(0,1,1)[52] : AIC=inf, Time=38.19 sec
ARIMA(0,1,0)(1,1,1)[52] : AIC=inf, Time=39.33 sec
ARIMA(1,1,0)(0,1,0)[52] : AIC=414.708, Time=0.95 sec
ARIMA(1,1,0)(0,1,1)[52] : AIC=inf, Time=47.51 sec
ARIMA(1,1,0)(1,1,1)[52] : AIC=inf, Time=59.30 sec
ARIMA(2,1,0)(0,1,0)[52] : AIC=413.878, Time=1.86 sec
ARIMA(2,1,0)(1,1,0)[52] : AIC=inf, Time=59.96 sec
ARIMA(2,1,0)(0,1,1)[52] : AIC=inf, Time=60.34 sec
ARIMA(2,1,0)(1,1,1)[52] : AIC=inf, Time=77.60 sec
ARIMA(3,1,0)(0,1,0)[52] : AIC=414.514, Time=2.05 sec
ARIMA(2,1,1)(0,1,0)[52] : AIC=415.165, Time=3.74 sec
ARIMA(1,1,1)(0,1,0)[52] : AIC=413.365, Time=1.91 sec
ARIMA(1,1,1)(1,1,0)[52] : AIC=415.351, Time=66.38 sec
ARIMA(1,1,1)(0,1,1)[52] : AIC=inf, Time=57.54 sec
ARIMA(1,1,1)(1,1,1)[52] : AIC=inf, Time=76.00 sec
ARIMA(0,1,1)(0,1,0)[52] : AIC=411.433, Time=1.08 sec
ARIMA(0,1,1)(1,1,0)[52] : AIC=413.422, Time=29.17 sec
ARIMA(0,1,1)(1,1,1)[52] : AIC=inf, Time=67.32 sec
ARIMA(0,1,2)(0,1,0)[52] : AIC=413.343, Time=1.76 sec
ARIMA(1,1,2)(0,1,0)[52] : AIC=415.196, Time=3.69 sec
ARIMA(0,1,1)(0,1,0)[52] intercept : AIC=413.377, Time=2.05 sec
Best model: ARIMA(0,1,1)(0,1,0)[52]
Total fit time: 809.281 seconds
根据最低的 AIC 值, ARIMA(0,1,1)(0,1,0)[52] 的 ARIMA 模型配置被指示为最佳拟合的模型。
现在,该模型可用于预测未来 15 周,并将这些预测与测试集进行比较:
predictions=pd.DataFrame(Arima_model.predict(n_periods=15), index=test_df)
predictions=np.array(predictions)
在将预测值与测试集的值进行比较之前,预测值将被重新整形,以便与测试集的格式相同:
>>> predictions=predictions.reshape(15,-1)
>>> predictionsarray([[ 88.0971519 ],
[103.18056307],
[117.93678827],
[121.38546969],
[112.9812769 ],
[120.69309927],
[144.4014371 ],
[166.36546077],
[181.69684755],
[190.12507961],
[204.36831063],
[218.85150166],
[216.59090879],
[197.74194692],
[156.98273524]])
现在,可以将测试值与基于均方根误差(RMSE)的预测值进行比较,数值越低表示误差越小。
>>> mse = mean_squared_error(test_df, predictions)
>>> rmse = math.sqrt(mse)
>>> print('RMSE: %f' % rmse)
RMSE: 10.093574>>> np.mean(test_df)
160.492142162915
与平均值 160 相比,RMSE 为 10。这表示误差略高于平均值的 6%,表明该模型预测 ADR 趋势的准确度相当高。
这是预测值与实际值的对比图。
来源:Jupyter 笔记本输出
结论
非常感谢您的宝贵时间,非常感谢您的任何问题或反馈。
你可以在这里找到这个例子的 Jupyter 笔记本。
免责声明:本文是在“原样”的基础上编写的,没有担保。本文旨在提供数据科学概念的概述,不应被解释为任何形式的专业建议。作者与本文提及的任何第三方无任何关系。