TowardsDataScience-博客中文翻译-2021-四十七-
TowardsDataScience 博客中文翻译 2021(四十七)
原文:TowardsDataScience Blog
协议:CC BY-NC-SA 4.0
如何构建 AutoML API
原文:https://towardsdatascience.com/how-to-build-an-automl-api-8f2dd5f687d1?source=collection_archive---------16-----------------------
构建可重用 ML 类的简单指南
图片来自斯科特·格雷厄姆的 Unsplash
最近人们对汽车很感兴趣。从开源项目到云中的可扩展算法,让非技术用户更容易使用 ML 的项目越来越多。云中 AutoML 的例子包括 SageMaker Canvas 和 Azure AutoML 等等。在本文中,我们将不会在云上工作,而是向您展示如何构建一个简单的 Python API 来自动解决回归问题。有许多开源项目正在解决 AutoML 问题。
我将带您完成构建您自己的 AutoML 类的过程。即使您最终没有创建自己的包,构建可重用的类也是很好的编程实践。您还可以构建 API 来自动化 ML 中的许多冗余任务。一个例子是为 NLP 项目构建预处理类,你可以为基于文本的项目重用你的 API。要阅读这篇文章,你应该对 Python 和面向对象编程有很好的理解。
目录
- 设置
- 构建您的 API
- 测试 API
- 后续步骤和结论
1.设置
在我们开始构建 API 之前,您需要安装以下库:pandas、numpy 和 sklearn。下面的代码块将包含我们正在处理的导入。
进口
既然已经安装了所有必需的库,下一步就是设置我们要处理的类。我们的简单 API 有四个主要参数:数据集、目标列、模型类型和度量类型。对于数据集,我们将提供 CSV 数据集的路径。对于目标列,我们需要选择我们试图预测的列,因为它是在数据集中声明的。对于模型类型,我们在线性和随机森林回归中有两个选项可供选择。最后,对于公制类型,有平均绝对误差(MAE)和均方根误差(RMSE)。
AutoML 类已创建
我们还会用类方法填充一些参数。
现在我们已经准备好为预处理、模型训练和评估构建我们的方法。
2.构建您的 API
构建 AutoML API 的第一步是预处理函数。我们将读入数据,然后将其分成训练集和测试集。我们还检查我们的目标列参数是否存在于已经提供的数据集中。
预处理方法
既然我们已经有了我们训练和测试数据,我们可以把注意力集中在我们的模型构建/训练方法上。
训练方法
目前只有两种模型提供:线性 _ 回归和随机 _ 森林。我们检查以确保您输入了这两个模型中的一个,然后根据您的选择创建并训练所选的模型。
线性和随机森林回归
现在我们可以返回一个基于 metric_type 参数的度量。为此,我们可以创建一个 evaluate 方法,根据该参数的输入返回 MAE 或 RMSE。
评估方法
首先,我们检查以确保输入是受支持的指标之一,然后我们返回用户选择。如果我们想要完整的信息,我们可以使用 logModelInfo 方法,该方法具有模型类型和两个度量。一般来说,随着 API 变得越来越复杂,您将需要一个日志记录方法来跟踪您的查询。
日志信息
3.测试 API
现在我们可以用一些样本输入来测试我们的样本 API。
样本值输入
在这里,我们要求一个线性回归模型与 MAE 指标。
示例输出(作者截图)
我们可以使用随机森林模型和 RMSE 度量来尝试另一个样本。
样本 RF 输入
示例输出(作者截图)
4.后续步骤和结论
要访问示例的完整代码,请查看这个链接。如您所见,为 ML 构建 Python 类是一个非常简单的过程。要构建复杂的真实世界级别的包,只需要几个额外的步骤和一个可重复的设置,查看这个资源就可以开始了。有大量的 AutoML 开源项目你可以开始参与。即使作为数据科学家,熟悉构建类、包,并在更深层次上理解您正在使用的开源工具或 AutoML 服务也是至关重要的。
如果你喜欢这篇文章,请在LinkedIn上联系我,订阅我的媒体 简讯 。如果你是新手,使用我的 会员推荐 报名。
如何用 Python 构建 AutoML 应用程序
原文:https://towardsdatascience.com/how-to-build-an-automl-app-in-python-e216763d10cd?source=collection_archive---------6-----------------------
使用来自 envato elements 的 koctia 的图像创建(经许可)。
数据科学 | 机器学习
使用 Streamlit 库的分步教程
自动化机器学习(AutoML)通过简化流程来帮助降低机器学习模型构建的门槛,从而允许非技术用户利用机器学习的力量。另一方面,AutoML 的可用性也有助于解放数据科学家的时间(否则他们会花在冗余和重复的预处理任务或模型构建任务上),允许他们探索数据分析管道的其他领域。
简而言之,用户可以向 AutoML 系统提供输入数据集,用于模型构建(特征转换、特征选择、超参数优化等)。)最后,它将预测作为输出返回。
如果你可以构建自己的 AutoML 应用程序,并根据自己的喜好进行定制,这不是很好吗?该 AutoML 应用程序的开发分为两部分:(1)模型部署有助于完成数据生命周期,以及(2) AutoML 有助于非技术用户访问 ML。
在本文中,我们将使用 Streamlit 和 Scikit-learn 库用 Python 构建一个 AutoML 应用程序。这个 web 应用程序将允许用户上传他们自己的 CSV 文件,并且 web 应用程序将通过执行网格超参数搜索来自动构建随机森林模型。
需要注意的是,这篇文章的灵感来自于我前段时间在我的 YouTube 频道上做的一个视频( 如何搭建一个机器学习超参数优化 App)(数据教授 )。
如何搭建机器学习超参数优化 App @ 数据教授
1.AutoML 应用程序概述
我们今天构建的 AutoML 应用程序不到 200 行代码,确切地说是 171 行。
1.1.技术堆栈
web 应用程序将使用以下库在 Python 中构建:
streamlit
—网络框架pandas
—处理数据帧numpy
—数值数据处理base64
—对要下载的数据进行编码scikit-learn
—进行超参数优化,建立机器学习模型
1.2.用户界面
web 应用程序有一个简单的界面,由两个面板组成:(1)左侧面板接受输入 CSV 数据和参数设置,而(2)主面板显示输出,包括打印出输入数据集的数据帧、模型的性能指标、超参数调整的最佳参数以及调整后的超参数的 3D 等值线图。
AutoML 应用程序的屏幕截图。
1.3.AutoML 应用程序演示
让我们看一下下面 2 个截图中的 web 应用程序,这样你就可以对你将要构建的应用程序有个大概的了解。
1.3.1。AutoML 应用程序使用示例数据集
试用 web 应用程序的最简单方法是使用提供的示例数据集,方法是单击主面板中的Press to use Example Dataset
按钮,这将加载糖尿病数据集作为示例数据集。
使用示例数据集的 AutoML 应用程序的屏幕截图。
1 . 3 . 2。AutoML 应用程序使用上传的 CSV 数据
或者,您也可以上传自己的 CSV 数据集,方法是将文件直接拖放到上传框中(如下图所示),或者点击Browse files
按钮并选择要上传的输入文件。
使用输入 CSV 数据集的 AutoML 应用程序的屏幕截图。
在上面的两个屏幕截图中,在提供示例数据集或上传的 CSV 数据集后,应用程序打印出数据集的数据帧,通过使用提供的输入学习参数自动构建几个机器学习模型,以执行超参数优化,然后打印出模型性能指标。最后,在主面板的底部提供了调整后的超参数的交互式 3D 等高线图。
您也可以点击以下链接试用该应用程序:
- AutoML 应用的演示链接
2.代码
现在让我们深入了解一下 AutoML 应用程序的内部工作原理。如你所见,整个应用程序只用了 171 行代码。
应该注意的是,代码中提供的所有注释(由包含散列标签符号#
的行表示)通过记录每个代码块正在做什么来使代码更可读。
第 1–10 行
导入必要的库,包括streamlit
、pandas
、numpy
、base64
、plotly
和scikit-learn
。
第 15–16 行
set_page_config()
功能允许我们将网页标题指定为page_title=‘The Machine Learning Hyperparameter Optimization App’
,并将页面布局设置为全幅模式,如layout=’wide’
输入参数所指定。
第 19–25 行
在这里,我们使用 st.write()函数和 markdown 语法,通过在标题文本The Machine Learning Hyperparameter Optimization App
前面使用#
标签来编写第 20 行的网页标题文本。在随后的几行中,我们编写了 web 应用程序的描述。
第 29–58 行
这些代码块属于左侧面板中的输入小部件,它接受用户输入的 CSV 数据和模型参数。
- 第 29–33 行—第 29 行通过
st.sidebar.header()
函数打印左侧边栏面板的标题文本,其中函数中的 sidebar 指示输入小部件应该放置在左侧边栏面板中的位置。线 30 通过st.sidebar.file_uploader()
功能接受用户输入的 CSV 数据。正如我们所看到的,有 2 个输入参数,其中第一个是文本标签Upload your input CSV file
,而第二个输入参数type=[“csv”]
限制只接受 CSV 文件。第 31–33 行通过st.sidebar.markdown()
函数以 Markdown 语法打印到示例数据集的链接。 - 第 36 行—通过
st.sidebar.header()
功能打印标题文本Set Parameters
。 - 第 37 行通过
st.sidebar.slider()
功能显示一个滑动条,允许用户通过简单调整滑动条来指定数据分割比率。第一个输入参数打印小部件标签文本Data split ratio (% for Training Set)
,其中接下来的 4 个值代表最小值、最大值、默认值和增量步长。最后,将指定值赋给split_size
变量。 - 第 39–47 行显示学习参数的输入部件,而第 49–54 行显示一般参数的输入部件。类似于对第 37 行的解释,这些代码行也利用
st.sidebar.slider()
作为输入小部件,接受用户指定的模型参数值。第 56–58 行将滑块输入的用户指定值组合成一个聚合形式,然后作为负责超参数调整的GridSearchCV()
函数的输入。
第 64 行
通过st.subheader()
功能在输入数据帧上方添加一个副标题文本Dataset
。
第 69–73 行
这段代码将通过base64
库对模型性能结果进行编码和解码,作为一个可下载的 CSV 文件。
第 75–153 行
在高层次上,这个代码块是build_model()
自定义函数,它将接受输入数据集和用户指定的参数,然后执行模型构建和超参数调整。
- 第 76–77 行——输入数据帧分为
X
(删除最后一列 Y 变量)和Y
(特别选择最后一列)变量。 - 第 79 行——这里我们通过
st.markdown()
函数通知用户模型正在构建中。然后在第 80 行,Y 变量的列名通过st.info()
函数打印在一个信息框中。 - 第 83 行——使用
X
和Y
变量作为输入数据,通过train_test_split()
功能执行数据分割,而用户指定的分割比率值由split_size
变量指定,该变量从第 37 行描述的滑动条中取值。 - 第 87–95 行—通过分配给
rf
变量的RandomForestRegressor()
函数实例化随机森林模型。如您所见,RandomForestRegressor()
函数中定义的所有模型参数都从用户指定的输入小部件中获取参数值,如上文第 29–58 行所述。 - 第 97–98 行—执行超参数调整。
→第 97 行——在rf
变量中指定的上述随机森林模型被指定为GridSearchCV()
函数中的estimator
参数的输入变量,它将执行超参数调整。在超参数调整中探索的超参数值范围在param_grid
变量中指定,该变量直接从用户指定值中取值,该值从滑动条(第 40-43 行)获得,并作为param_grid
变量(第 56-58 行)进行预处理。
→第 98 行——超参数调整过程从输入X_train
和Y_train
作为输入数据开始。 - 第 100 行—通过
st.subheader()
功能打印型号性能副标题文本。接下来的行将打印模型性能指标。 - 第 102 行——存储在
grid
变量中的超参数调整过程的最佳模型被用于对X_test
数据进行预测。 - 第 103–104 行—通过使用
Y_test
和Y_pred_test
作为输入参数的r2_score()
函数打印 R2 分数。 - 第 106–107 行—通过使用
Y_test
和Y_pred_test
作为输入参数的mean_squared_error()
函数打印 MSE 分数。 - 第 109–110 行—打印最佳参数,并四舍五入到小数点后两位。最佳参数值从
grid.best_params_
和grid.best_score_
变量中获得。 - 第 112–113 行—第 112 行通过
st.subheader()
功能打印副标题Model Parameters
。第 113 行通过st.write()
功能打印存储在grid.get_params()
中的模型参数。 - 第 116-125 行——从
grid.cv_results_
获得模型性能指标,并重新调整为x
、y
和z
。
→第 116 行——我们将有选择地从grid.cv_results_
中提取一些数据,这些数据将用于创建一个包含 2 个超参数组合及其相应性能指标的数据框架,在本例中是 R2 分数。特别是,pd.concat()
功能将用于组合 2 个超参数(params
)和性能指标(mean_test_score
)。
→第 118 行——现在将进行数据整形,以将数据准备成适合创建等高线图的格式。特别是,pandas
库中的groupby()
函数将用于根据两列(max_features
和n_estimators
)对数据帧进行分组,从而合并第一列(max_features
)的内容。 - 第 120–122 行—数据现在将被旋转到一个 m ⨯ n 矩阵中,其中的行和列分别对应于
max_features
和n_estimators
。 - 第 123-125 行——最后,各
x
、y
和z
变量的整形数据将用于绘制等高线图。 - 第 128-146 行——这些代码块现在将通过
plotly
库使用x
、y
和z
变量创建 3D 等高线图。 - 第 149-152 行——然后将
x
、y
和z
变量组合成一个df
数据帧。 - 第 153 行——存储在 grid_results 变量中的模型性能结果现在可以通过
filedownload()
自定义函数下载(第 69–73 行)。
第 156–171 行
在高层次上,这些代码块将执行应用程序的逻辑。这由 2 个代码块组成。第一个是if
代码块(第 156-159 行),第二个是else
代码块(第 160-171 行)。每次 web 应用程序加载时,它将默认运行else
代码块,而if
代码块将在输入 CSV 文件上传时被激活。
对于两个代码块,逻辑是相同的,唯一的区别是df
数据 dataframe 的内容(无论它是来自输入 CSV 数据还是来自示例数据)。接下来,通过st.write()
功能显示df
数据框的内容。最后,通过build_model()
自定义函数启动模型构建过程。
3.运行 AutoML 应用程序
现在我们已经编写了应用程序,让我们继续启动它。
3.1.创造康达环境
让我们首先创建一个新的conda
环境(为了确保代码的可再现性)。
首先,在终端命令行中创建一个名为automl
的新conda
环境,如下所示:
conda create -n automl python=3.7.9
其次,我们将登录到automl
环境
conda activate automl
3.2.安装必备库
首先,下载requirements.txt
文件
wget [https://raw.githubusercontent.com/dataprofessor/](https://raw.githubusercontent.com/dataprofessor/ml-auto-app/main/requirements.txt)[ml-opt-app](https://github.com/dataprofessor/ml-opt-app)[/main/requirements.txt](https://raw.githubusercontent.com/dataprofessor/ml-auto-app/main/requirements.txt)
其次,安装如下所示的库
pip install -r requirements.txt
3.3.下载应用程序文件
您可以下载数据教授的 GitHub repo 上托管的 web 应用程序文件,也可以使用上面找到的 171 行代码。
wget [https://github.com/dataprofessor/](https://github.com/dataprofessor/ml-app/archive/main.zip)[ml-opt-app](https://github.com/dataprofessor/ml-opt-app)[/archive/main.zip](https://github.com/dataprofessor/ml-app/archive/main.zip)
接下来,解压缩文件内容
unzip main.zip
现在通过cd
命令进入main
目录
cd main
现在你在main
目录中,你应该能够看到ml-opt-app.py
文件。
3.4.启动 web 应用程序
要启动应用程序,请在终端提示符下键入以下命令(即确保ml-opt-app.py
文件位于当前工作目录中):
streamlit run ml-opt-app.py
几秒钟后,终端提示中出现以下消息。
> streamlit run ml-opt-app.pyYou can now view your Streamlit app in your browser.Local URL: [http://localhost:8501](http://localhost:8501)
Network URL: [http://10.0.0.11:8501](http://10.0.0.11:8501)
最后,应该会弹出一个浏览器和应用程序。
本地启动的 AutoML App 截图。
您也可以通过以下链接测试 AutoML 应用程序:
- AutoML App 的演示链接
4.结论
现在您已经按照本文中的描述创建了 AutoML 应用程序,接下来呢?你或许可以将这款应用调整为另一种机器学习算法。附加功能,如功能重要性图也可以添加到应用程序中。可能性是无穷的,并享受定制应用程序的乐趣!请随时发表评论,说明您是如何为自己的项目修改应用程序的。
订阅我的邮件列表,获取我在数据科学方面的最佳更新(偶尔还有免费赠品)!
关于我
我是泰国一所研究型大学的生物信息学副教授和数据挖掘和生物医学信息学负责人。在我下班后的时间里,我是一名 YouTuber(又名数据教授)制作关于数据科学的在线视频。在我制作的所有教程视频中,我也在 GitHub 上分享 Jupyter 笔记本(数据教授 GitHub page )。
https://www.youtube.com/dataprofessor
在社交网络上与我联系
✅YouTube:http://youtube.com/dataprofessor/
♇网站:http://dataprofessor.org/(在建)
♇LinkedIn:https://www.linkedin.com/company/dataprofessor/
♇Twitter:https://twitter.com/thedataprof/
♇Facebook:http://facebook.com/dataprofessor/
♇github:https://github.com/dataprofessor/
♇Instagram:)
如何用 Python 构建 EDA 应用程序
原文:https://towardsdatascience.com/how-to-build-an-eda-app-in-python-af7ec4b51528?source=collection_archive---------10-----------------------
使用来自 envato elements 的 hoangpts 的图像创建(经许可)。
数据科学 | 机器学习
用 50 行代码从头开始一步一步的教程
探索性数据分析(EDA)是探索和总结数据集主要特征的基本和初步的第一步。EDA 提供了帮助我们更好地理解变量及其关系的方法。这是通过非图形(描述性统计)和图形(数据可视化)技术实现的。
在本文中,我们将创建一个 EDA web 应用程序,您可以使用它来加速 EDA 分析,或者让您的同事无需使用 Python 编写代码就可以执行 EDA。执行 EDA 分析只需简单上传输入 CSV 文件。
也可以参考我 YouTube 频道(数据教授)的我的 YouTube 视频 如何利用熊猫建档 构建探索性数据分析 app 作为本文的补充。
1.EDA 工具(Pandas Profiling)
一个简单直观的 EDA 工具是 Python 中的pandas-profiling
库。它允许通过df.profile_report()
功能为df
数据帧生成一份分析报告。
生成的配置文件是一个交互式 HTML 报告,显示每个变量的以下统计数据(更多详情,请参见文档):
- 类型推断:识别数据帧中各列的数据类型。
- 要领:类型、唯一值、缺失值。
- 分位数统计:最小值、最大值、Q1、中位数、Q3、极差和四分位差。
- 描述性统计:均值、众数、标准差、总和、中位数绝对偏差、变异系数、峰度、偏度。
- 最频繁值
- 直方图:数值范围分布。
- 相关性:突出显示高度相关的变量、Spearman、Pearson 和 Kendall 矩阵。
- 缺失值:缺失值的矩阵、计数、热图和树状图。
- 重复行:列出出现次数最多的重复行。
- 文本分析:了解文本数据的类别(大写、空格)、脚本(拉丁文、西里尔文)和块(ASCII)。
2.关于我们今天正在构建的 EDA 应用程序
我们今天将要构建的 EDA 应用程序将允许我们将自己的 CSV 数据集上传到应用程序,然后应用程序将自动生成一个(一个便于 EDA 分析的交互式 HTML 报告)。
你可以在这里自己试试: EDA App 演示
3.EDA 应用程序的代码
这段代码有 50 多行代码,准确地说是 52 行。
让我们来看看应用程序背后的技术。它基于由以下内容组成的 5 个 Python 库:
numpy
—用于生成由 5 列(变量)组成的合成数据集,该数据集用作示例数据集(注意 web 应用程序页面标题下主面板中的Press to use Example Dataset
按钮)。pandas
—用于存放数据帧形式的数据。streamlit
—使构建简单 web 应用成为可能的 web 框架。pandas_profiling
—为执行 EDA 生成交互式 HTML 报告的库。streamlit_pandas_profiling
—允许在 Streamlit web 应用程序中使用pandas_profiling
库的库。
4.对代码的逐行解释
第 1–5 行
- 导入由
numpy
、pandas
、streamlit
、pandas_profiling
和streamlit_pandas_profiling
组成的必备库
第 7–13 行
- 第 7 行 —注释文本,表示后续代码块与 web 应用程序的标题相关。
- 第 8–13 行—
st.markdown()
功能打印 web 应用程序的标题。输入参数采用 Markdown 语法。
第 15–20 行
- 第 15 行 —注释文本,描述第 16–20 行负责 CSV 上传功能。
- 第 16 行 —
with
用于构建属于代码块的后续代码行。st.sidebar.header()
指定使用header()
功能在左侧面板显示标题文本1\. Upload your CSV data
。 - 第 17 行—
st.sidebar.file_uploader()
功能允许创建上传框。需要注意的是st.sidebar
指定了上传框在侧边栏中的位置(可折叠的左侧面板)。在file_uploader()
函数中找到的输入参数type=["csv"]
指定上传框只接受csv
文件类型。 - 第 18 行—
st.sidebar.markdown()
函数指定使用markdown()
函数在左侧面板中显示一个指向示例 CSV 文件的链接。
第 22–52 行
- 第 22 行 —注释文本,描述后续代码块负责创建 Pandas Profiling 报告。这里需要注意的是,这个部分由一个
if-else
语句组成,每次 web 应用程序加载时,默认情况下都会运行else
代码块(第 35–52 行)。上传输入 CSV 文件后,if
代码块(第 23-34 行)将被激活并运行。 - 第 23–34 行 —该代码块代表
if
语句。如前所述,该代码块将在输入 CSV 文件上传后运行。
— 第 23 行 —设置if
条件,检测uploaded_file is not None
指示文件上传。
— 第 24 行—@st.cache
装饰器允许应用程序跳过后续代码行中定义的高成本且重复的函数。
— 第 25–27 行 —一个名为load_csv
的自定义函数,通过uploaded_file
变量从上传框读入输入 CSV 文件。
— 第 28 行 —从load_csv
自定义函数读取的 CSV 文件内容被分配给df
变量。
— 第 29 行—ProfileReport()
功能被分配给pr
变量。
— 第 30–31 行—**Input DataFrame**
的标题通过st.header()
功能打印为标题文本(第 30 行)。存储在df
变量中的数据帧内容被打印出来(第 31 行)。
— 第 32 行 —"- — -”
打印一个水平条。
— 第 33–34 行—**Pandas Profiling Report**
的标题通过st.header()
功能打印为标题文本(第 33 行)。存储ProfileReport()
功能输出的pr
变量的内容被打印出来。特别是,这是允许 EDA 功能的交互式 HTML 配置文件报告。 - 第 35–52 行 —该代码块代表
else
语句。
— 第 35 行—else
条件设置为默认状态,每次加载 web 应用程序时运行。
— 第 36 行 —通过st.info()
功能在信息框中打印一段文字Awaiting for CSV file to be uploaded.
。
— 第 37–52 行—if
条件用于指定点击Press to use Example Dataset
按钮的结果(其下的语句将被运行),这将使用示例数据集生成配置文件报告。
— 第 38 行 —注释文本,表示以下代码行与示例数据相关。
— 第 39 行——如前面第 24 行所述,@st.cache
装饰器允许应用跳过后续代码行的潜在高成本运行(即,否则应用将在每次重新加载时重新生成合成数据集)。
— 第 40–45 行 —定义了一个自定义函数,使用NumPy
库创建一个由 5 列组成的合成数据集。
— 第 46 行 —第 40–45 行自定义函数定义的合成数据集被分配给df
变量。
5.运行 EDA 应用程序
现在是运行应用程序的时候了。
5.1.创造康达环境
让我们假设您是从零开始,因此您将不得不创建一个新的conda
环境(这是一个好主意,以确保代码的可再现性)。
首先,在终端命令行中创建一个名为eda
的新conda
环境,如下所示:
*conda create -n eda python=3.7.9*
其次,我们将登录到eda
环境
*conda activate eda*
5.2.安装必备库
首先,下载 requirements.txt 文件
*wget [https://raw.githubusercontent.com/dataprofessor/eda-app/main/requirements.txt](https://raw.githubusercontent.com/dataprofessor/ml-auto-app/main/requirements.txt)*
其次,安装如下所示的库
*pip install -r requirements.txt*
5.3.下载 EDA 应用文件
您可以下载数据教授的 GitHub repo 上托管的 web 应用程序文件,也可以使用上面找到的 52 行代码。
*wget [https://github.com/dataprofessor/eda-app/archive/main.zip](https://github.com/dataprofessor/ml-app/archive/main.zip)*
接下来,解压缩文件内容
*unzip main.zip*
现在通过cd
命令进入main
目录
*cd main*
现在你在main
目录中,你应该能够看到app.py
文件。
5.4.启动 web 应用程序
可以通过在终端提示符下键入以下命令来启动应用程序(即确保app.py
文件在当前工作目录下):
*streamlit run app.py*
之后,您将在终端提示符下看到以下消息。
*> streamlit run app.pyYou can now view your Streamlit app in your browser.Local URL: [http://localhost:8501](http://localhost:8501)
Network URL: [http://10.0.0.11:8501](http://10.0.0.11:8501)*
最后,应该会弹出一个浏览器和应用程序。
EDA App 截图。试用 app 请参考EDA App demo。****
EDA 应用在运行中的截图。我们可以在这里看到相关图。请参考上面第 2 节中的动画示例。
恭喜你!
现在,您已经创建了一个 EDA 应用程序,可以让您在旅途中轻松执行 EDA 分析,只需上传一个输入 CSV 文件,即可开始执行 EDA 分析。
将 EDA 应用部署到互联网
如果您希望向全世界公开您的 web 应用程序,您可以将其部署到互联网上。我在 YouTube 上制作了视频,展示如何在 Heroku、Streamlit 和 Streamlit 上做到这一点。
- 如何将数据科学 Web App 部署到 Heroku
- 如何部署 Data Science Web App 以简化 it 共享
通过 Streamlit 共享平台在互联网上部署的 EDA 应用示例可在此处访问: EDA 应用演示
订阅我的邮件列表,获取我在数据科学方面的最佳更新(偶尔还有免费赠品)!
关于我
我是泰国一所研究型大学的生物信息学副教授和数据挖掘和生物医学信息学负责人。在我下班后的时间里,我是一名 YouTuber(又名数据教授)制作关于数据科学的在线视频。在我做的所有教程视频中,我也在 GitHub 上分享 Jupyter 笔记本(数据教授 GitHub page )。
***https://www.youtube.com/dataprofessor
在社交网络上与我联系
✅YouTube:http://youtube.com/dataprofessor/
♇网站:http://dataprofessor.org/(在建)
♇LinkedIn:https://www.linkedin.com/company/dataprofessor/
♇Twitter:https://twitter.com/thedataprof
♇Facebook:http://facebook.com/dataprofessor/
♇github:https://github.com/dataprofessor/
♇insta gram:https://www.instagram.com/data.professor/【t19***
如何建立一个高效的现代化数据平台
原文:https://towardsdatascience.com/how-to-build-an-efficient-and-modern-data-platform-7e0e7630ef70?source=collection_archive---------35-----------------------
为什么您应该将数据湖、数据仓库和数据集市集成在一起,而不是将它们孤立起来
乔尔·沃戴尔在 Unsplash 上拍摄的照片
它们应该自由地相互集成,而不是独立地构建和理解数据湖、数据仓库和数据集市。这避免了数据孤岛并简化了数据供应。
什么是什么?
数据仓库和数据湖代表了一个中央数据库系统,可用于公司的分析目的。该系统从各种异构数据源提取、收集和保存相关数据,并提供给下游系统。
数据仓库可以分为四个子过程:
- 数据获取:从各种数据仓库中获取和提取数据。
- 数据存储:在数据仓库中存储数据,包括长期存档。
- 数据供应:为下游系统提供所需的数据,提供数据集市。
- 数据评估:对数据库的分析和评估。
虽然数据仓库将经典的 ETL 过程与关系数据库中的结构化数据结合使用,但数据湖使用 ELT 和模式等范例读取非结构化数据[1]。
差异数据仓库与湖
在上图中,您可以看到主要的区别。你使用的技术也很不同。对于数据仓库,您将使用 SQL 和关系数据库,而对于数据湖,您可能会使用 NoSQL 或两者的混合。
可以说,数据集市是面向特定业务部门的数据仓库的子集[2]。数据集市包含收集的汇总数据的存储库,用于对组织内的特定部门或单位(例如销售部门)进行分析。
将所有这些结合在一个混合数据湖中
那么如何将这些概念结合起来呢?在下图中,您可以从高层次的角度看到一个架构。该过程是将非结构化和未转换的数据加载到数据湖中。从这里,一方面,数据可以用于 ML 和数据科学任务。另一方面,数据也可以以结构化的形式被转换和加载到数据仓库中。从这里开始,可以通过数据集市和(自助式)BI 工具实现传统的数据仓库分布。
混合数据湖概念—图片来自作者
您可以为这个架构使用的主要技术可以是例如:[3][4]
- ELT/ETL 流程通过——talend、Google 数据流、AWS 数据管道
- 数据湖 via — HDFS、AWS 雅典娜和 S3、谷歌云存储
- 数据仓库/数据集市通过——Google big query、AWS Redshift、雪花
注意:像 Google 的 BiqQuery 或 AWS Redshift 这样的技术通常被认为是数据仓库和数据湖技术的混合体,因为它们通常已经实现了 NoSQL 的一些特征。
大多数技术可以从单一来源获得的事实使得建立这样的数据平台更加容易。这对小公司来说是一个优势。例如,一旦数据被加载到数据仓库中,就可以通过现有的接口相对容易地对其进行进一步的处理,用于 ETL 和数据集市过程,通常只需要很少的编程工作。
结论
本文解释了如何使用混合数据湖。数据湖使您的公司能够灵活地以数据形式捕获业务运营的各个方面,同时保持传统数据仓库的活力。从那里,数据可以依次转移到数据集市。好处是一切都建立在相同的数据源和技术上,因此可以更容易地进行更改。大型云提供商通常从一个来源提供所有必要的工具,因此这导致了更容易的处理和可能的成本优势。我帮助构建的一个解决方案包括 Google Storage 和 BigQuery 作为数据湖和暂存区,talend 作为 ETL/ELT 工具,Big Query 作为数据仓库和数据集市层。从那里,数据可以很容易地用于 ML 服务或 BI 工具 Data Studio。
资料来源和进一步阅读
[1] IBM,绘制数据湖:使用读取模式和写入模式的数据模型 (2017)
[2]数据仓库指南,数据仓库指南,(2021)
[3]谷歌,帮助保护从数据湖到数据仓库的管道 (2021)
[4] AWS,AWS 中的混合数据湖 (2021)
如何用 Flash 用几行代码构建一个图像分类器
原文:https://towardsdatascience.com/how-to-build-an-image-classifier-in-few-lines-of-code-with-flash-ccfcf41f7972?source=collection_archive---------34-----------------------
Flash 简介:面向初学者的高级深度学习框架
Brian Suh 在 Unsplash 上拍摄的照片
介绍
图像分类是一项任务,我们要预测哪一类属于一幅图像。由于图像表示,这项任务很困难。如果我们将图像展平,它将创建一个长的一维向量。此外,该表示将丢失邻居信息。因此,我们需要深度学习来提取特征并预测结果。
有时候,建立深度学习模型可能会成为一项艰巨的任务。虽然我们为图像分类创建了一个基础模型,但是我们需要花费大量的时间来创建代码。我们必须准备代码来准备数据、训练模型、测试模型,并将其部署到服务器。这就是闪光的来源!
Flash 是一个高级深度学习框架,用于快速构建、训练和测试深度学习模型。Flash 基于 PyTorch 框架。所以如果你了解 PyTorch,你会很容易熟悉 Flash。
与 PyTorch 和 Lighting 相比,Flash 易于使用,但不如以前的库灵活。如果你想建立一个更复杂的模型,你可以使用 Lightning 或 straight to the PyTorch。
由作者创作。
使用 Flash,您可以用几行代码构建您的深度学习模型!所以,如果你是深度学习的新手,不要害怕。Flash 可以帮助你建立深度学习模型,而不会因为代码而感到困惑。
本文将向您展示如何使用 Flash 构建图像分类器。没有进一步,让我们开始吧!
履行
安装库
要安装库,您可以像这样使用 pip 命令:
**pip install lightning-flash**
如果这个命令不起作用,您可以使用它的 GitHub 库来安装这个库。该命令如下所示:
**pip install git+**[**https://github.com/PyTorchLightning/lightning-flash.git**](https://github.com/PyTorchLightning/lightning-flash.git)
在我们成功下载包之后,现在让我们加载库。我们也用数字 42 设定种子。下面是实现这一点的代码:
下载数据
在我们安装了库之后,现在让我们来获取数据。为了进行演示,我们将使用名为猫狗数据集的数据集。
该数据集包含分为两类的图像。这些课是猫和狗。要访问数据集,可以在 Kaggle 找到这个数据集。您可以在这里 访问数据集 。
作者捕捉到的。
加载数据
下载完数据后,现在让我们将数据集加载到一个对象中。我们将使用 from_folders 方法将数据放入 ImageClassification 对象。下面是实现这一点的代码:
加载模型
在我们加载数据之后,下一步是加载模型。因为我们不会从头开始创建自己的架构,所以我们将使用基于现有卷积神经网络架构的预训练模型。
我们将使用已经过预训练的 ResNet-50 模型。此外,我们根据数据集设置类的数量。下面是实现这一点的代码:
训练模型
在我们加载模型之后,现在让我们训练模型。我们需要首先初始化教练对象。我们将在 3 个时期训练模型。此外,我们启用 GPU 来训练模型。下面是实现这一点的代码:
初始化对象后,现在让我们训练模型。为了训练模型,我们可以使用一个名为 finetune 的函数。在函数内部,我们设置模型和数据。此外,我们将训练策略设置为冻结,在这里我们不想训练特征提取器。换句话说,我们只训练分类器部分。
下面是实现这一点的代码:
下面是评测结果:
作者捕捉到的。
从结果可以看出,我们的模型达到了大约 97%的准确率。这个不错!现在让我们用几个新数据来测试这个模型。
测试模型
我们将使用未经模型训练的样本数据。以下是我们将对模型进行测试的示例:
为了测试模型,我们可以使用 flash 库中的 predict 方法。下面是实现这一点的代码:
从上面的结果可以看出,模型已经预测到了带有正确标签的样本。真好!现在让我们保存模型以备后用。
保存模型
现在我们已经对模型进行了训练和测试。让我们使用 save_checkpoint 方法保存模型。下面是实现这一点的代码:
如果您想在其他代码上加载模型,您可以使用 load_from_checkpoint 方法。下面是实现这一点的代码:
结束语
干得好!现在,您已经学习了如何使用 Flash 构建图像分类器。正如我一开始所说的,这只需要几行代码!多酷啊。
希望这篇文章能帮助你根据自己的案例建立自己的深度学习模型。如果你想实现一个更复杂的模型,我希望你可以学习 PyTorch。
如果你对我的文章感兴趣,可以在 Medium 上关注我。我会发表数据科学和机器学习相关的文章。还有,如果你有什么问题或者想打个招呼,可以在 LinkedIn 上和我联系。
谢谢你看我的文章!
如何打造令人印象深刻的数据科学简历?
原文:https://towardsdatascience.com/how-to-build-an-impressive-data-science-resume-7a9c71f761c5?source=collection_archive---------7-----------------------
制作一份引人注目的有影响力的简历的建议
格伦·卡斯滕斯-彼得斯在 Unsplash 上拍摄的照片
我们每个人都需要一份简历来展示我们的技能和经验,但是我们付出了多少努力来使它有影响力呢?不可否认,简历在我们的求职过程中起着关键的作用。本文将探索一些简单的策略来显著改善数据科学简历的展示和内容。
第一,为什么关注简历很重要?
获得数据科学工作变得非常具有竞争力,尽管机会的数量处于历史高位,申请这些工作的人数也非常高。
例如 ,下面是 LinkedIn 的一个招聘信息截图,这个招聘信息总共有 1200+次浏览,如果我们考虑大约十分之一的人申请这份工作,那么总共有 120+份申请,这只是申请这份工作的一种方式,还有人从其他渠道申请这份工作,通过推荐人和直接申请,因此申请总数大约为 200+。同样的逻辑适用于任何数据科学职位,因此简历在入围名单中起着关键作用。
截图来自 LinkedIn
在这篇文章中,我将指导你如何制作一份有影响力的简历,帮助你进入求职候选名单。本文涵盖的主题是,
- 简历准备的基本规则
- 定制你的简历和求职信
- 谷歌的 X-Y-Z 公式来做出有影响力的陈述
- 有助于打造出色简历的工具
如果你喜欢视频格式,点击这里。
简历准备的基本规则
继续格式化
大多数求职申请都接受 pdf 和 word 格式的简历。但是我建议你坚持使用 pdf 版本,因为这样可以确保格式不变,也就是说招聘人员看到的简历和你看到的一样。
个人资料摘要
简介摘要是简历的关键,把它当作电梯推销吧。它应该是有说服力的,应该包括你是谁,你的技能和优势等信息。简历的这一部分将是第一印象的主要驱动力,也会影响招聘人员的决定,因此要花足够的时间来确保它包括关于你的关键细节。
我的人会在简历的开头写上职业目标。我个人主张把职业目标从简历中去掉,用这个地方来写一份更好的简历摘要。因为大多数招聘是基于你的成就、优势和技能,而不是你的抱负。所以做一个明智的决定,有效地利用你的简历,尤其是开头。
使用项目符号
确保你在简历中包括的细节都是要点,无论是简介总结还是专业/项目经历。很难将注意力集中在一个长段落上,因此保持它的简单性和要点性可以确保更好的可读性,如下图所示。
在一个长段落中概述
项目符号中的个人资料摘要
尝试将每个要点限制在 2-3 行,并将关键短语加粗,这样有助于快速浏览。
格式的一致性
简历的内容应该是一致的格式,标题、副标题、要点和简历中的其他文本都应该是一致的格式。下面是一些可以确保一致性的事情,
- 选择一种字体,在简历中使用
- 简历中用来突出经历和教育的标题应该保持一致的格式。你可以选择使用更大的字体,但是要在简历中保持一致
- 如果你的简历超过一页,那么要确保所有页面的页边距、对齐方式和空格都是一致的
- 你可以选择将标题中的第一个单词大写,但是在整个简历中保持一致
避免错别字
经常检查印刷和语法错误,因为它们可能会让招聘人员失去兴趣。虽然印刷和语法错误很有可能不被注意到,但当被发现时,它们会发出错误信号,
- 你不够细致,没有发现那些错误
- 作为一名数据科学家,沟通是一个关键方面,出现拼写或语法错误绝对不好
- 公司越来越多地使用自动化工具来过滤简历,这些工具很可能会拒绝有印刷错误的简历
包括联系人详细信息
您的联系方式对于招聘人员联系您非常重要,因此请确保您仔细检查您的详细信息。许多人开始根据他们同事或朋友的简历编辑他们的简历,在这种情况下,请确保在编辑文本时超链接也被编辑。就像当你编辑电子邮件 id 时,确保超链接中的电子邮件也被编辑。
包含您的个人资料和投资组合的链接
确保你的简历有链接到你的 LinkedIn 个人资料,git 知识库,以及你想向招聘人员强调的其他网站或个人资料,如 Kaggle
定制你的简历和求职信
当你在一份工作申请上与许多人竞争时,像定制这样简单的事情可以成为一个优势,可以帮助你立即引起招聘人员的注意。当我说根据招聘启事定制你的简历时,这并不意味着完全重写你申请的每一份工作的简历,而是做一些小的调整,以确保你的简历突出了工作要求的要求和期望。
定制简历有助于你
- 确保你的简历是为招聘职位量身定做的
- 确保你的简历通过基于关键词的自动过滤
- 向招聘人员发出积极的信号,因为你已经做好了基础工作
简历中有几个部分是你可以自定义的,它们是
- 你简历中的目标职位,以及求职信,应该与招聘启事相符
- 确保简历中强调的技能包括工作描述中要求的一些技能
- 对您的个人资料摘要进行简单的修改,以确保招聘启事中提到的期望得到满足
- 如果你申请的工作地点不在你现在所在的城市,或者你申请的工作需要出差,那么在简历或求职信中明确提到你愿意重新安置或出差
用谷歌 X-Y-Z 公式做出有影响力的陈述
这是一个惊人的公式,有助于将你的成就转化为一个高影响力的声明。它是由拉兹洛·博克在他的文章中首次提出的。这是一个非常有效的技巧,可以用来写一份有影响力的简历。这个公式的意思是,
通过做“Z”来完成“X”并以“Y”来衡量
我将使用一些简单的例子来准确地解释如何在你的数据科学简历中应用这个公式。
例一:
“建立了一个推荐系统”
这是一个简单的陈述,一点也不吸引人,因为它没有确切地提到用例的影响。我们可以使用下面的语句,通过包含其影响的细节来尝试改进它,
“建立了一个推荐系统,增加了 10%的收入”
现在,这比前面的陈述好得多,但可以通过使用 Google X-Y-Z 公式进一步改进,如下所示(公式中的 X、Y 和 Z 在下面突出显示)
“通过使用【Z】协同过滤算法,在平台上建立了【X】推荐系统,帮助 收入提高了 10%【Y】
例二:
“参加了一场 kaggle 比赛”
这又是一个简单的陈述,只是说你参加了一个卡格尔比赛,但没有谈论你的表现,因此可以通过包括如下一些细节来改进。
“在一场追逐赛中获得第 20 名”
现在这样更好了,但是我们可以通过使用谷歌的 X-Y-Z 公式让它更有影响力,
“参加了一场 Kaggle 竞赛(X) 并在1250 支队伍中排名第 20 位(Y)** 由 与 3 位同事合作建立一个集合预测模型(Z)**
现在,用这个公式把你的成就转化成更有力的陈述。
有助于打造出色简历的工具
有很好的工具可以帮助你打造一份令人惊艳的简历。下面是我最喜欢的两个,
Resume.io
- 这是一个建立你的简历和求职信的付费平台,尽管使用这个平台不需要任何费用,但是你需要付费来下载简历
- 他们有很多简历模板来迎合不同的工作类别,帮助你开始工作
- 虽然这个平台支持几个模板,并有许多选项来进行更改,但模板的某些部分仍然是僵化的。但我个人觉得这样更好,因为这样可以让你只关注需要注意的事情,还能确保简历的一致性
流量系数 io
- 这是一个建立你的简历和求职信的免费平台,如果你希望有一个以上的简历版本,那么需要一次性付款
- 该平台提供了多种配置来进行任何更改,以定义事物的外观。我觉得有更多的选择意味着要做更多的决定,因此很耗时,可能会导致一些不一致
这些工具对于创建令人惊叹的简历非常有帮助。
保持联系
- 如果你喜欢这篇文章,并对类似的文章感兴趣,请在 Medium 上关注我
- 我在我的 YouTube 频道上教授和谈论各种数据科学主题。在这里订阅我的频道。
- 在此注册我的电子邮件列表,获取更多数据科学技巧,并与我的工作保持联系
如何用 Python 构建交互式置信区间计算器
原文:https://towardsdatascience.com/how-to-build-an-interactive-confidence-interval-calculator-in-python-6aea08d69be3?source=collection_archive---------18-----------------------
在 Python 和 Jupyter Notebook 中为正态和二项式置信区间构建一个可重用的交互式批处理计算器
Avel Chuklanov 在 Unsplash 上拍摄的照片
背景
很常见的是,我们可以获得一个值的样本,可能是点击我们新网站页面的 200 个用户的样本,或者是在他们离开投票站时进行的投票后调查中的 30 个选民的样本。
为了对这些观察结果做出陈述,我们需要使用置信区间,而不仅仅是引用试验的百分比或结果。
置信区间是一个数值范围,我们相当确定我们的真实值所在,例如,如果我们问 30 个选民他们投票给谁,75%的人说“候选人 A ”,那么整个选民投票给候选人 A 的范围是多少?
如果你想知道更多关于置信区间的信息,这个在线资源是一个很好的起点——【https://www.mathsisfun.com/data/confidence-interval.html,但是知道比背景信息更多的信息对于让置信区间为你工作并不重要。
这个想法
我曾在工作场合多次使用置信区间,根据样本观察对某件事情发生的可能性做出陈述,每次我要么在 Excel 中重新创建公式,要么重新编写 Python 代码。
我决定用 Jupyter 编写一个交互式置信区间计算器,下次我需要做同样的事情时可以重用它,这就产生了代码和这篇文章
我们开始吧!
首先,我们需要导入一些库,我们将使用它们来构建我们的计算器…
公式的快速复习
置信区间的公式看起来很可怕,但作为一个非统计学家,我可以说它们并不可怕。如果你想更深入地了解它们是如何工作的,请看看我的另一篇文章-https://towardsdatascience . com/hypothesis-testing-in-python-made-easy-7a 60 e 8 c 27 a 36。
回顾一下要点,我们将在 Jupyter 和 Python 中实现两个公式,一个用于正态分布,一个用于二项式分布。
正态分布的公式将用于所有正态分布,例如,英国男性鞋码的分布或一组学习在线课程的学生的年终考试分数的分布。
当出现简单的二元结果时,将使用二项式分布公式,例如,75%的受访选民投票给候选人 A,25%的人没有。
这是计算正态分布置信区间的公式…
作者图片
…这是二项式的公式…
作者图片
因此,抛开那些讨厌的公式,让我们继续进行比较直接的工作,让它们发挥作用,并创建几个 Python 函数来实现它们…
在 Python 中实现公式
…让我们快速测试一下我们的功能…
[71.4489792915286, 74.669551749961]
我已经使用其他程序测试了输出结果,结果是正确的,但要注意的是,如果您正在从一组测试数据中计算标准偏差(𝜎),您需要注意以下几点
scipy.stats.sem function()
使用默认值ddof=1
作为自由度参数,而numpy.std()
默认使用ddof=0
,这可能会导致不同的结果,取决于您是使用scipy
还是numpy
来执行计算。
有关完整的解释,请参见这篇关于 stackoverflow 的文章:https://stack overflow . com/questions/54968267/scipy-stats-SEM-calculate-of-standard-error
[0.7546278801351438, 0.8053721198648562]
该输出也已经使用简单的 Excel 公式- =1.96*(SQRT(B2*(1-B2))/Sheet2!$B$1)
进行了验证,其中 1.96 是 95%置信区间的 z 得分,单元格 B2 保存𝑝̂的值,Sheet2!$B$1
保存样本大小的值。
创建交互式计算器
互动计算器是使用 Jupyter 互动部件创建的,完整的文档可以在这里找到
- https://ipywidgets . readthedocs . io/en/stable/examples/Widget % 20 list . html
- https://ipywidgets . readthedocs . io/en/stable/examples/Using % 20 interact . html
我们需要做的第一件事是定义我们的输入控件…
现在我们需要几个简单的包装函数来显示控件,并在单击按钮时调用适当的置信区间函数…
正态分布置信区间计算器
这是解决方案的关键部分;只需几行 Python 和 Jupyter 代码,就可以创建交互式计算器,这样您就可以更改输入参数并单击“运行交互”来随时重新运行正态分布的计算-
作者图片
二项式分布置信区间计算器
下面是创建二项式置信区间交互式计算器的等效代码…
作者图片
创建批处理计算器
由于交互式置信区间计算器适用于单独的计算,我决定将其扩展到批处理模式,以适应我想一次处理几个计算的情况。
首先我们需要创建几个助手函数来更新DataFrame
中的值...
正态分布置信区间批处理计算器
作者图片
作者图片
二项式置信区间批量计算器
作者图片
作者图片
结论
我们简要回顾了计算正态分布和二项式分布置信区间的统计公式,并表明能够交互式地计算这些公式是非常有用的,而不是每次我们想要计算它们时都必须在 Excel 或 Python 中重新编写代码。
我们定义了 Python 函数来计算置信区间,然后快速创建了两个交互式表单,我们可以反复运行它们来计算我们感兴趣的置信区间。
最后,我们扩展了交互式计算器,从一个.csv
文件中读取参数,以便对一批数据快速执行置信区间计算,从而加快我们希望对几组数据而不是一组数据进行计算的过程。
Jupyter 笔记本的完整源代码可以在这里找到
如何在 Vertex AI 中构建用于超参数调整的 MLOps 管道
原文:https://towardsdatascience.com/how-to-build-an-mlops-pipeline-for-hyperparameter-tuning-in-vertex-ai-45cc2faf4ff5?source=collection_archive---------12-----------------------
为超参数调整设置模型和 orchestrator 的最佳实践
当你设计一个机器学习模型时,有许多超参数——学习速率、批量大小、神经网络的层数/节点数、桶数、嵌入维数等。你基本上是猜的。通过找到这些超参数的最佳值,通常会比最初的猜测有 2-10%的改进。(当然,这取决于您最初的猜测有多糟糕,但我会假设您做出了一些有根据的猜测)。
在之前的一篇文章中,我建议你使用 Jupyter 笔记本进行实验,但是一旦事情稳定下来,就使用普通的 Python 文件。这样做可以区分 ML 开发和 MLOps 之间的职责。因此,假设您已经这样做了,并且您的模型训练文件以 model.py 的形式存在,您的管道编排器以 train_on_vertexai.py 的形式存在。在阅读本文时,您可能会发现使用这两个链接中的代码很有帮助。
1.在 model.py 中参数化您的模型
第一步是为您的模型创建超参数命令行参数。例如,在 model.py 中,我们可能会这样做:
parser.add_argument(
'--nembeds',
help='Embedding dimension for categorical variables',
type=int,
default=3
)
请注意,变量的初始猜测值是默认值。这允许您的训练脚本像以前一样继续工作。然后,通过命令行参数设置该变量,供训练脚本使用:
args = parser.parse_args()
...
NEMBEDS = args['nembeds']
对您现在或将来可能想要调优的所有超参数都这样做。一个好的做法是在 model.py 中不要有任何硬编码的值——那里的所有东西都需要一个输入参数。
2.实施更短的训练运行
通常,您的训练运行将涉及在整个数据集上进行训练,然后在整个测试数据集上进行评估。为超参数调整进行完整的训练运行是昂贵的、浪费的和错误的。为什么?
贵:超参数调优的重点是获得最佳的一组参数,而不是获得可能的最佳模型。一旦你找到了最好的参数,你就可以用这些参数来训练一个模型。因此,没有必要进行完整的试验。你只需要训练它,直到你知道哪个试验可能会更好。
为超参数调整进行完整的训练运行是昂贵的、浪费的和错误的。作者图解。
浪费:在假设你的训练曲线表现良好的情况下,在整个训练过程中,一组更好的参数会更好,你可以在它开始收敛之前很好地停止训练。用你的训练预算做更多的试验,而不是延长试验时间。
错误:您不想评估测试数据集上的超参数调优。您希望比较验证数据集的性能。只需确保验证数据集足够大,让您能够在试验模型之间进行有意义的比较。
我做这些修改的方法是在我的 model.py 中添加两个选项:一个用于较短时间的训练,另一个用于跳过完整的评估:
NUM_EXAMPLES = args['num_examples']
SKIP_FULL_EVAL = args['skip_full_eval']
...steps_per_epoch = NUM_EXAMPLES // train_batch_size
epochs = NUM_EPOCHS
eval_dataset = read_dataset(eval_data_pattern, eval_batch_size,
tf.estimator.ModeKeys.EVAL, **num_eval_examples**)
model.fit(train_dataset,
validation_data=eval_dataset,
epochs=NUM_EPOCHS,
**steps_per_epoch=steps_per_epoch,**
callbacks=[cp_callback, HpCallback()])
...if not SKIP_FULL_EVAL:
test_dataset = read_dataset(test_data_pattern, eval_batch_size, tf.estimator.ModeKeys.TEST, None)
final_metrics = model.evaluate(test_dataset)
...
else:
logging.info("Skipping evaluation on full test dataset")
steps_per_epoch 和 NUM_EXAMPLES 是怎么回事?注意上图中的 x 轴。这不是时代,而是例子的数量。虽然在完整数据集上进行训练是非常浪费的,但获得与完整训练相同数量的中间指标是有帮助的(我将在下一步解释原因)。因为您还将超参数调整批量大小,所以最好的方法是使用虚拟时期(参见机器学习设计模式书:检查点了解详情)。每历元步数是我们在大型数据集上获取虚拟历元的方法。
3.在培训期间写出衡量标准
在培训过程中写出衡量标准。不要只是等到最后。如果你这样做了,那么 Vertex AI 也将通过缩短非生产性试验来帮助你节省成本。
在 Keras 中,要在培训期间写出指标,可以使用回调。看起来是这样的:
METRIC = 'val_rmse'
hpt = hypertune.HyperTune()**class HpCallback**(tf.keras.callbacks.Callback):
def on_epoch_end(self, epoch, logs=None):
if logs and METRIC in logs:
logging.info("Epoch {}: {} = {}".format(epoch, METRIC, logs[METRIC]))
hpt.report_hyperparameter_tuning_metric(
hyperparameter_metric_tag=METRIC, metric_value=logs[METRIC], global_step=epoch)...history = model.fit(train_dataset,
...
callbacks=[cp_callback, **HpCallback()**])
我正在使用 cloudml-hypertune 包来简化以 TensorFlow 生态系统(TensorBoard、Vizier 等)的形式编写指标。)可以理解。
4.实现超参数调整管道
现在您已经修改了 model.py,使其易于进行超参数调整,MLOps 人员可以随时调整您的模型,只要他们注意到它在漂移。
编排代码中有两个步骤(在 train_on_vertexai.py 中):
(4a) 创建一个顶点 AI CustomJob,用正确的参数调用你的 model.py:
tf_version = '2-' + tf.__version__[2:3]
train_image = "us-docker.pkg.dev/vertex-ai/training/tf-gpu.{}:latest".format(tf_version) model_display_name = '{}-{}'.format(ENDPOINT_NAME, timestamp)
trial_job = aiplatform.CustomJob.from_local_script(
display_name='train-{}'.format(model_display_name),
**script_path="model.py",**
container_uri=train_image,
**args=[
'--bucket', BUCKET,
'--skip_full_eval', # no need to evaluate on test data
'--num_epochs', '10',
'--num_examples', '500000' # 1/10 actual size
],**
requirements=['cloudml-hypertune'], **# hpt**
replica_count=1,
machine_type='n1-standard-4',
# See [https://cloud.google.com/vertex-ai/docs/general/locations#accelerators](https://cloud.google.com/vertex-ai/docs/general/locations#accelerators)
accelerator_type=aip.AcceleratorType.NVIDIA_TESLA_T4.name,
accelerator_count=1,
)
(4b) 创建并运行一个超参数调整作业,该作业将使用上述作业作为单独试验:
hparam_job = aiplatform.HyperparameterTuningJob(
# See [https://googleapis.dev/python/aiplatform/latest/aiplatform.html#](https://googleapis.dev/python/aiplatform/latest/aiplatform.html#)
display_name='hparam-{}'.format(model_display_name),
custom_job=trial_job,
**metric_spec={'val_rmse': 'minimize'},**
parameter_spec={
**"train_batch_size": hpt.IntegerParameterSpec(min=16, max=256, scale='log'),
"nbuckets": hpt.IntegerParameterSpec(min=5, max=10, scale='linear'),
"dnn_hidden_units": hpt.CategoricalParameterSpec(values=["64,16", "64,16,4", "64,64,64,8", "256,64,16"])**
},
max_trial_count=4 if develop_mode else 10,
parallel_trial_count=2,
search_algorithm=None, # Bayesian
)
请注意,我在这里指定的指标与我的 model.py 中的指标相匹配,并且我指定了参数的范围。
默认情况下,Vertex AI 中的超参数调优服务(称为 Vizier)将使用贝叶斯优化,但如果你愿意,可以将算法更改为 GridSearch。
5.监控 GCP web 控制台
一旦你启动超参数调优工作,你可以在 GCP 控制台的顶点人工智能部分看到参数进来。
您会看到类似这样的内容:
6.运行最佳试验直至完成
确定最佳参数集后,采用最佳参数集,然后运行训练作业直到完成。这将为您提供部署模型。
当然,我们也可以实现自动化:
best = sorted(hparam_job.trials,
key=lambda x: x.final_measurement.metrics[0].value)[0]
logging.info('Best trial: {}'.format(best))
best_params = []
for param in best.parameters:
best_params.append('--{}'.format(param.parameter_id))
best_params.append(param.value) # run the best trial to completion
model = train_custom_model(data_set, timestamp, develop_mode, extra_args=best_params)
同样,通过 Vertex AI,数据科学家(决定哪些参数可以优化)和 MLOps 工程师(决定何时重新调整模型)之间的职责分离变得更加容易。
尽情享受吧!
更多关于 Vertex AI 的阅读:
- 给谷歌云上的新统一 ML 平台 Vertex AI 一个旋转 :
我们为什么需要它,无代码 ML 培训到底有多好,所有这些对数据科学工作意味着什么? - 如何将 TensorFlow 模型部署到 Vertex AI :在 Vertex AI 中使用保存的模型和端点
- 使用 Python 在 Vertex AI 上开发和部署机器学习模型:编写让你的 MLOps 团队满意的训练管道
- 如何在 Vertex AI 中为超参数调整构建 MLOps 管道 :
为超参数调整设置模型和协调器的最佳实践
如何使用 IceVision 建立对象检测模型
原文:https://towardsdatascience.com/how-to-build-an-object-detection-model-using-icevision-36f01472362e?source=collection_archive---------21-----------------------
用几行代码构建您的对象检测模型
在 Unsplash 上由 Derek Oyen 拍照
介绍
计算机视觉多年来一直在进步。有了它,我们可以自动完成任务,看到我们眼睛看不到的东西。
对象检测是现有的计算机视觉应用之一。在这个任务中,我们不仅要对图像进行分类,还要检测目标的位置。之后,模型会创建一个包围它的边界框。
听起来很酷,对吧?但不幸的是,实现对象检测是具有挑战性的,并且需要时间。对于一个新人,我可以保证他们会变得不知所措。然后,IceVision 来到了互联网。
IceVision 是一个计算机视觉库,用于直接实现对象检测模型。您不必担心数据准备和模型实现,因为 IceVision 会处理这些问题。因此,您可以通过使用对象检测来专注于解决问题。
在本文中,我将向您展示如何使用 IceVision 实现一个对象检测模型。事不宜迟,我们开始吧!
履行
下载库
我们需要做的第一步是下载库。为了下载这个库,我们到 GitHub 上的 IceVision 存储库,下载名为 icevision_install.sh 的 shell 脚本。
请记住,IceVision 库只能在 Linux 和 Mac OS 上运行。对于 Windows 用户,您可以使用 Google Colab 来继续学习本教程。你可以在这里 访问 GitHub 库T5。
现在,您可以通过下面的链接下载 shell 脚本:
下载脚本后,您可以使用 bash 运行脚本,如下所示:
安装完库后,您可以使用下面的代码重新启动笔记本:
现在您可以加载库了。下面是实现这一点的代码:
获取并准备数据
在我们下载并加载库之后,下一步是获取数据。在本教程中,我们将使用牛津大学 IIIT 分校的 Pets 数据集中的一个例子。
该数据集包含大约 7400 幅图像,它们被分为 37 类。对于这个数量的类,每个类包含大约 200 个图像。在 这里可以看到关于数据集 的详细信息。
免责声明:
数据集是在知识共享署名-共享 4.0 国际(CC BY-SA 4.0)许可下许可的。这个许可意味着每个人都可以出于任何目的访问和使用数据,包括本文的教程。你可以在这里 了解更多关于 牌照的信息。
让我们回到主题。现在让我们加载数据。幸运的是,Icedata 库提供了数据集。您可以运行以下代码来加载数据:
加载数据后,下一步是创建用于定型和测试模型的数据拆分器。在这种情况下,我们将对训练数据使用 80%的比例,对测试数据使用 20%的比例。下面是实现这一点的代码:
这样做之后,下一步是解析数据集。这样做的原因是为了准备数据。因此,它更容易被模型读取。之后,我们根据之前我们的比例将数据拆分成训练集和测试集。下面是实现这一点的代码:
如果您想查看类名及其标签,可以运行以下代码:
如果您想查看数据集的预览,可以运行这行代码:
获得数据后,下一步是初始化 Dataset 对象。但在此之前,我们需要实现图像增强。这样做的原因是通过给图像一些修改来提高模型的性能。
我们将应用的增强技术是归一化图像值,并将它们裁剪成所需的图像大小。下面是实现这一点的代码:
现在我们可以初始化数据集对象。下面是实现这一点的代码:
要确保对象正常工作,请运行这行代码:
建立模型
我们的数据已经加载完毕。现在让我们建立模型。对于本教程,我们将使用 RetinaNet 作为架构。对于主干,我们使用 ResNet-50 作为模型的特征提取器。下面是实现这一点的代码:
在您加载模型之后,现在让我们初始化模型。下面是实现这一点的代码:
初始化模型后,下一步是为数据集创建一个加载器。之所以这么做,是因为模型要批量训练。在每次迭代中,模型将获得一批数据集,并在模型上对其进行训练。
对于测试数据集,我们不会打乱批次,因为我们没有训练数据。我们测试它只是为了看看它的性能。下面是实现这一点的代码:
要验证数据加载器是否已初始化,您可以运行这行代码:
训练模型
现在你有了数据和模型。下一步是训练模型。让我们为我们的模型初始化度量。
在这种情况下,我们将使用 COCO 指标以及损失或错误的数量。编写以下代码行来初始化指标:
IceVision 库有两种训练模型的方法。有 Fast.ai 法和 PyTorch 闪电法。对于本教程,我只给大家展示 Fast.ai 方法。
其原因是因为这种方法已经准备了一些可视化,以便更容易地理解我们的模型的进展。让我们使用这行代码初始化 Fast.ai 学习器:
在我们训练模型之前,分析使用哪个学习率是一个更好的步骤。为此,您可以运行以下代码行:
从上面可以看出,学习率为 0.001 的模型损失最低。因此,我们将使用该值作为训练模型的参数。现在让我们微调模型。下面是实现这一点的代码:
因为我们使用了 Fast.ai 函数,所以可以看到一个表格。它由亏损次数和可可指标组成。从上面可以看出,该模型的 COCO 指标约为 0.708。损失值对预测真的很好。
保存模型
现在我们有了最好的模型。让我们通过使用 save_icevision_checkpoint 函数来保存模型。下面是实现这一点的代码:
测试模型
最后,让我们在测试数据上测试模型。在这种情况下,我们使用之前分割的验证数据。
为了测试我们前面的函数,让我们尝试使用 model_from_checkpoint 函数加载模型。下面是实现这一点的代码:
似乎没有出现错误。让我们通过运行以下几行代码来验证它:
不错!似乎没有发生任何错误。让我们通过使用这行代码来加载模型:
现在我们来试试这个模型。请运行以下几行代码:
最后一步,让我们看看结果如何。请运行这行代码:
结束语
干得好!现在,您已经学习了如何使用 IceVision 实现对象检测模型。我希望你能在这里学到新的东西。还有,希望这篇文章可以帮助你针对自己的问题建立一个对象检测模型。
如果你对我的文章感兴趣,你可以在 Medium 上关注我。对于那些还不是 Medium 成员的人,您可以使用下面的链接订阅 Medium:
https://medium.com/@irfanalghani11/membership
如果您有任何问题,可以通过 LinkedIn 联系我。
谢谢你看我的文章!
如何在 AWS 上构建和部署无服务器机器学习应用
原文:https://towardsdatascience.com/how-to-build-and-deploy-a-serverless-machine-learning-app-on-aws-1468cf7ef5cb?source=collection_archive---------14-----------------------
即使预算很低也能扩展
建筑卡通化(图片由作者提供)
你有没有想过构建一个机器学习应用程序,后端有一个沉重的模型,前端有一个 React 用户友好的界面,周围有一个无服务器的云架构,这样你的产品就可以扩展到数十、数百甚至数千个用户?
这并不像听起来那么难,在本文中,我将展示如何构建这样的应用程序。为了让本教程更有趣,我将介绍构建 Cartoonify 的过程。
演示(作者 GIF)
Cartoonify 是我从头开始做的一个玩具应用,把图片变成漫画。我知道这可能看起来有点滑稽,但相信我,这个应用程序背后有严肃的工作,你可以在其他地方利用。我会让你读这篇文章来相信我或者检查我的 GitHub 上的代码。
这是我开始这个项目的动机
- 试试生成性对抗网络(GANs)。我最近被这些模型迷住了。尝试卡通模特把你的脸变成卡通看起来很有趣。
- 了解如何使用 AWS 的不同服务(Lambda、API Gateway、S3 等)在无服务器架构上部署应用程序。).
- 练习我的反应能力。我习惯于策划、冲刺和精简,我想,这一次,建立一些自定义和不那么主流的东西。
- 使用 Netlify 部署此 React 应用程序。我看到了这个过程是多么简单的演示,我想试着说服自己。
构建卡通化是如此有趣,我决定在一个视频系列中谈论它。这里有一个简短的介绍:
第 0 部分—卡通化简介(作者制作的视频)
0.构建和部署 Cartoonify 的先决条件
如果您想要运行和部署 Cartoonify,首先需要满足以下先决条件:
- 一个 AWS 账户(别担心,部署这个应用几乎不会花你一分钱。)
- 在网上的免费账户
- 安装在您机器上的 Docker
- 节点和 npm (最好是最新版本)
- 火炬和火炬视觉在本地测试卡通(可选)
如果你已经准备好了一切,你现在就可以出发了。
请遵循以下四个步骤。
1.cartongan——人工智能艺术家?
本节提供了关于该模型的一些细节。如果您对此不感兴趣,可以转到关于部署的下一部分。
这个网络背后的主要思想
在测试这个应用程序背后的模型 CartoonGAN 之前,让我们先来谈谈它,以了解底层架构以及它是如何被设计和训练来产生卡通风格的。
🇸🇮·扬科·费里奇在 Unsplash 上拍摄的照片(左)——转换后的图像(右)
CartoonGAN 于 2018 年在这篇论文中推出,目标是将图像转换成不同日本漫画的风格。CartoonGAN 所实现的被称为风格转移,这是一种图像转换技术,由于 Leon A. Gatys 关于神经风格转移的工作,它在 2015 年首次与神经网络一起引入。风格转移后来在 2017 年通过 CycleGAN 架构得到了增强。CycleGAN 通过将风格转换形式化为两个图像分布之间的转换问题来处理风格转换,而神经风格转换将其框定为优化问题。
CartoonGAN 是神经类型转移和 GANs 的混合体。事实上,它使用了一个简单的 GAN 架构(不是循环架构),并添加了一个受神经风格转移技术启发的语义损失,以强制生成器保留原始图像的内容。
作者甚至进一步使 CartoonGAN 的结果尽可能具有视觉吸引力:为此,他们添加了第二个损失,迫使生成器创建平滑的边缘、低阴影颜色和纹理较少的区域,因为这些是卡通特有的视觉特征。
从甘人到卡通人
要了解 CaroonGAN 是如何构建的,我们先来了解一个典型的 GAN 是如何被训练生成假图像的。
甘建筑—(图片经作者修改)
GAN 由两个网络组成:发生器和鉴别器。
生成器的目标是获取一些输入数据(或噪声)并创建看起来像真实世界图像分布的样本,而鉴别器的目标是了解假样本和真实样本之间的边界。
这两个网络在一个受博弈论启发的最小-最大游戏中相互训练,其中生成器的目标是欺骗鉴别器,鉴别器的目标是更好地识别真实数据和虚假数据。
刚开始训练的时候,这两个网络在各自的任务中都很差,一旦训练下去,就越来越好。
当它们达到平衡时,发生器是如此强大,以至于它通过完全混淆来控制鉴别器。在这种情况下,我们可以扔掉鉴别器,将生成器用于生成任务。
而生成漫画呢?
训练 GAN 从真实照片生成卡通数据是一个简单的问题,可以通过考虑以下因素来构建:
- 真实照片作为生成器的输入数据
- 卡通数据作为真实的数据分布,生成器会尽可能地伪造
这种设置的好处在于,你不需要在照片和漫画之间建立一对一的映射:这意味着在实践中,如果你想训练一个定制的卡通人物来生成你最喜欢的漫画(比如说辛普森一家),那么你所要做的就是收集一些没有任何对应关系的辛普森图像和真实照片,然后开始训练。
要了解更多关于 CartoonGAN 背后的训练程序,请看原始的论文。
现在让我们转到一个更具动手能力的部分,在这里我们可以自己生成卡通效果。
在本地测试卡通人物
首先克隆这个项目的 repo 。
git clone [https://github.com/ahmedbesbes/cartoonify.git](https://github.com/ahmedbesbes/cartoonify.git)
先下载四个预先训练好的模型。这些重量将加载到cartoongan/network/Transformer.py
中定义的发电机模型中
cd cartoongan
bash download_pth.sh
要测试四个模型中的一个,请将头伸到笔记本cartoongan/notebooks/CartoonGAN.ipynb
上,将输入图像路径更改为您的测试图像。这个笔记本调用cartoongan/test_from_code.py
脚本进行转换。
cd cartoongan/notebooks
jupyter notebook
在本地测试卡通——作者截图
transform 方法使用一个load_size
参数来调整输入图像的大小,以便加速转换。如果将其设置为较高的值,结果看起来会更好,但处理时间会更长。在整个项目中,我们将load_size
设为 450。
这里是一些用 800 的load_size
得到的结果。
Anthony DELANOIX 在 Unsplash 上拍摄的照片(左)-转换后的图像(右)
克里斯蒂安·加比在 Unsplash 上拍摄的照片(左)——转换后的图像(右)
您可以在 YouTube 上观看这一部分,了解更多关于 GANs、CartoonGAN 模型以及如何构建用于转换图像的脚本test_from_code.py
的信息。
第 1 部分—卡通人物模型(作者提供的视频)
2.使用 AWS Lambda 在无服务器 API 上部署 CartoonGAN
本节的目标是在无服务器架构上部署 CartoonGAN 模型,以便可以通过 API 端点从互联网上的任何地方请求它。
为什么无服务器架构如此重要?
例如,在使用 Lambda 函数的无服务器架构中,您不必自己提供服务器。大致来说,您只需编写将要执行的代码并列出其依赖项,AWS 将自动为您管理服务器并负责基础设施。
这有很多好处:
- 成本效率:你不用的时候不用花钱买无服务器架构。相反,当您有一台 EC2 机器正在运行并且不处理任何请求时,您仍然需要为此付费。
- 可伸缩性:如果一个无服务器应用程序开始同时有大量请求,AWS 将通过分配更多的能力来管理负载,从而对其进行扩展。如果您让自己使用 EC2 实例管理负载,您可以通过手动分配更多的机器并创建一个负载平衡器来做到这一点。
当然,无服务器架构不可能完全适合任何用例。在某些情况下,它们根本不实用(需要实时或快速响应、使用 WebSockets、繁重的处理等)。).
由于我经常构建机器学习模型并将它们集成到 web 应用程序中只是为了进行推理,所以我发现无服务器架构在这些特定的用例中很有趣。
卡通化工作流程
在部署 lambda 函数之前,我们先来看看应用的架构:
卡通化背后的建筑(作者图片)
在右侧,我们有一个内置在 React 中的客户端,在左侧,我们有一个部署在无服务器 AWS 架构上的后端。
后端和前端通过 HTTP 请求相互通信。工作流程如下:
- 客户端通过 POST 请求发送图像。
- 然后通过 API 网关接收图像。
- API Gateway 触发 Lambda 函数执行,并将图像传递给它。
- Lambda 函数开始运行:它首先从 S3 获取预先训练好的模型,然后在接收到的图像上应用样式转换。
- 一旦 Lambda 函数运行完毕,它会再次通过 API Gateway 将转换后的图像发送回客户端。
使用无服务器框架进行部署
我们将使用无服务器框架,一个自动化部署到 AWS、Azure、Google Cloud 等的开源工具,通过将它编写为 YAML 文件来定义和部署这个架构。
将基础设施写成代码,这难道不酷吗?
以下是要遵循的步骤:
1.在您的计算机上安装无服务器框架。
npm install -g serverless
2.在 AWS 上创建一个具有管理员权限的 IAM 用户,并将其命名为cartoonify
。然后用这个用户的凭证配置 serverless(我就不给你看我的了——放你的吧,伙计)。
3.引导一个无服务器项目,在这个项目的根目录下有一个 Python 模板。
serverless create --template aws-python --path backend
4.安装两个无服务器插件来管理 lambda 依赖项并防止 Lambda 函数冷启动:
5.在backend
中创建一个名为network
的文件夹,并将以下两个文件放入其中:
Transformer.py
:保存生成器模型架构的脚本。- 一片空白
__init__.py
6.用以下部分修改serverless.yml
文件:
-
provider 部分,我们在这里设置提供者、运行时和访问 bucket 的权限。请注意,您必须指定自己的 S3 存储桶。
-
我们配置插件的自定义部分:
-
我们从生产中排除不必要的文件夹的包部分:
-
functions 部分,我们创建 Lambda 函数,配置它,并定义调用它的事件。在我们的例子中,lambda 函数由路径
transform
上的 API Gateway 上的 post 请求触发。 -
列出外部插件的插件部分:
7.列出requirements.txt
内部的依赖关系(与serverless.yml
同级)。
8.在backend
中创建一个src
文件夹,并将handler.py
放入其中以定义 lambda 函数。然后修改handler.py
。
首先,添加导入:
在handler.py
中定义两个函数:
img_to_base64_str
将二进制图像转换为 base64 字符串load_models
将四个预先训练好的模型载入字典,然后保存在内存中
最后,将由 API 网关触发的lambda_handler
:
现在你完成了。后端的文件结构现在应该如下所示:
后端文件夹的文件结构(图片由作者提供)
9.部署前启动 Docker。
10.部署 lambda 函数。
cd backend/
sls deploy
部署可能需要 10 分钟,所以去拿一个☕️.
这里发生的事情,除了其他事情之外,是 Docker 将构建 Lambda 部署包的映像,然后 Serverless 将在上传到 S3 之前提取这个环境的依赖项。
一旦 lambda 函数部署完毕,系统会提示您输入可以请求的 API 的 URL。
请访问 Jupyter notebook,通过加载图像、将其转换为 base64 并将其放入有效载荷中进行测试。
API 演示—(作者截图)
如果你想按部就班地学习这一部分,这样你就不会错过任何东西,你可以在 YouTube 上观看。
第 2 部分—在 AWS Lambda 上部署(作者提供的视频)
3.构建一个 React 接口
本节将介绍如何构建一个简单的 React 接口来与模型进行交互。
我希望这个界面尽可能对用户友好,以一种非常简单的方式可视化样式转换。
我希望找到这个漂亮的 React 组件,它允许你并排比较两张图片,并通过滑动光标从一张图片切换到另一张图片。
在运行 React 应用程序并构建它之前,您需要指定刚刚部署的模型的 API URL。进入fontend/src/api.js
并更改baseUrl
的值。
- 要在本地运行 React 应用程序:
cd frontend/
yarn install
yarn start
这将在 http://localhost:3000 开始。
- 要在部署到 Netlify 之前构建应用程序:
yarn build
这将创建一个build/
文件夹,其中包含要在 Netlify 上提供的应用程序的构建版本。
您可以在 YouTube 上观看这一部分,以了解代码的结构以及正在使用的其他 React 组件。
第 3 部分——构建一个 React 接口(视频由作者提供)
4.在 Netlify 上部署 React 应用程序
在最后一节中,我们将介绍前端接口的部署。
有许多方法可以部署 React 应用程序,以便它可以在互联网上运行,任何人都可以访问它。其中一个是使用 Netlify :一个伟大的平台,可以在许多框架(React、Vue、Gatsby 等)中自动构建和部署应用程序。)
- 为了能够在 Netlify 上部署,您需要一个帐户。这是免费的:前往 Netlify 注册。
- 然后,您需要安装 netlify-cli:
npm install netlify-cli -g
- 使用您的帐户验证 Netlify 客户端:
netlify login
- 并部署:
cd app/
netlify deploy
Netlify 将要求您提供构建文件夹(输入“build”)和应用程序的自定义名称(这将显示为 netlify.com 的子域)。我已经选择了“卡通化”,但是你可以选择另一个。
这应该就是了!现在您的应用程序已上线!
但是等等!这个网址有些问题:它的前缀是字母数字代码——我不想这样,对吗?
那是因为你部署了一个草稿 URL!
要获得干净的 URL,您必须通过指定 prod 选项来进行部署:
netlify deploy --prod
您可以在 YouTube 上观看这一部分的现场演示,以了解在 Netlify 上部署有多容易。
第 4 部分—在 Netlify 上部署 React(视频由作者提供)
5.下一个:想投稿?
如果你已经做到这一步,我真诚地感谢你的时间!
如果你喜欢这个项目,想改善它,请自便:我随时欢迎拉式请求,这是项目的回购。
如果你有一个机器学习项目,你需要在云上快速部署一个 API,并通过一个定制的前端请求它,这个项目应该是一个样板文件来启动你的工作,所以请随意重用代码。
黑客快乐!
新到中?您可以每月订阅 5 美元,并解锁无限的文章— 点击此处。
如何使用 SpaCy 和 Streamlit 构建和部署文本匿名器
原文:https://towardsdatascience.com/how-to-build-and-deploy-a-text-anonymizer-with-spacy-and-streamlit-70ed9607823?source=collection_archive---------18-----------------------
NLP 使你符合 GDPR 的一个可能的方法
在这篇文章中,我将向您展示使用 Streamlit 和 Spacy 构建一个匿名化文本数据的 web 应用程序是多么容易。我们还将看到如何将它部署到 Heroku,并让它在互联网上直播,供其他用户使用和玩。
剧透:这是这个应用的样子
作者图片
尽管图像是不言自明的,但您可以使用此应用程序做以下事情:
- 上传文本数据(目前为 TXT 格式)或在输入区粘贴一些文本
- 选择语言模型(目前仅支持英语和法语)
- 选择要检测的实体类型(人员、位置和组织)
- 可视化检测到的实体并匿名化它们
PS😗 这是一个玩具 app :我会在这篇帖子的最后列出潜在的想法,通过增加更多的功能来改进它。现在请容忍我。
PS**:所有代码都可以在 Github 上找到
PS*:如果你想一步一步按代码来的话可以找这个教程的视频版
为什么需要匿名化数据?
作者图片
每当您处理文本数据(电子邮件、合同、评论等)时,您可能必须处理个人和敏感信息:人名或公司名、地址、电子邮件等等。出于合规性原因和其他法律约束(嘿,GDPR ),您必须非常小心地处理这些数据:潜在的数据泄露可能会给您的组织带来巨大的后果。
作为一名前数据科学顾问,我参与了许多处理敏感和个人数据的项目。建立匿名化管道是解决这个问题的一种方法。
今天,我将向您展示如何在 web 应用程序中嵌入匿名化。
让我们开始吧。
使用 pipenv 快速设置您的环境
来源:https://pipenv.pypa.io/en/latest/
我总是为我的每个项目保持一个干净和独立的环境,我用 pipenv 来妥善处理这个问题:
Pipenv 是一个工具,旨在将所有包装领域的精华(bundler、composer、npm、cargo、yarn 等。)到 Python 世界。在我们的世界里,Windows 是一等公民。它会自动为您的项目创建和管理一个 virtualenv,并在您安装/卸载软件包时从您的 Pipfile 中添加/删除软件包。它还生成非常重要的 Pipfile.lock,用于生成确定性的构建。—pypi.org
如果您想使用 pipenv,请使用 pip 全局安装它:
**pip install pipenv**
然后,创建一个项目文件夹,并通过安装所需的依赖项在其中初始化一个 pipenv 环境:
**mkdir anonymizer
cd anonymizer/
pipenv install streamlit spacy st-annotated-text
pipenv install black --dev**
我们将安装:
- streamlit :构建 UI
- 空间:进行命名实体识别
- st-annotated-text :在 Streamlit 应用程序中显示注释文本的简单组件
- 黑色用于本地格式化代码。这个包只能在开发模式下使用。
安装完这些依赖项后,pipenv 将创建一个以您的项目文件夹命名的虚拟环境。它还会在这个文件夹的根目录下添加两个文件: Pipfile 和 Pipfile.lock (不要手动修改这些文件:它们是由 pipenv 自动生成的)
作者图片
现在一切都设置好了,激活环境:
**pipenv shell**
作者图片
下载空间语言模型
来源:https://spacy.io/
由于我们将在最后在 Heroku 上部署应用程序,我们将手动下载 SpaCy 语言模型并将其放在一个文件夹中。这个文件夹将作为源代码的一部分上传到 Heroku 服务器上。
您可以直接从 Github 下载 SpaCy 语言模型:
- 英文模型
- 法国车型
两个文件都是 tar.gz 文件。您必须首先解压缩它们,并复制粘贴包含config.cfg
文件的文件夹中的所有文件。然后将这些文件分别放到models
文件夹下的en
和fr
文件夹中。下面是你最后应该有的:
作者图片
现在,每个型号都可以轻松加载:
**import spacy****french_model = spacy.load("./models/fr/")
english_model = spacy.load("./models/en/")**
构建 Streamlit 应用程序
我们将从导入项目的依赖项开始:
**import streamlit as st
import spacy
from annotated_text import annotated_text**
然后,我们将收集用户输入:
- 模特的语言(
en
或fr
) - 实体类型(
PER
、LOC
和ORG
) - 文本区域中的输入文本
- 用于上传 TXT 文件的文件上传程序
一旦用户选择了语言,我们就必须选择正确的空间模型。
但是,我们不希望每次用户从一种语言切换到另一种语言时都加载这个模型。相反,我们想要的是将所有模型一次性加载到内存中,并在字典中以恒定的复杂度访问它们。
这就是 Streamlit 缓存发挥作用的地方:
既然已经收集了输入文本,并且从界面中选择了语言模型,我们就必须从文本中提取实体,并用st-annotated-text
插件显示它们。
要显示这样的注释文本:
来源:https://github.com/tvst/st-annotated-text
st-annotated-text
需要一个元组列表,其中每个元组由其文本、实体名称和十六进制颜色代码描述。
annotated_text(
"This ",
("is", "verb", "#8ef"),
" some ",
("annotated", "adj", "#faa"),
("text", "noun", "#afa"),
" for those of ",
("you", "pronoun", "#fea"),
" who ",
("like", "verb", "#8ef"),
" this sort of ",
("thing", "noun", "#afa"),
)
给定标记化的文本和选择的实体,我们可以很容易地得到这种类型的结构。
通过将 anonymize 参数设置为True
,该函数将用 Xs 替换每个实体。
既然输入文本已经过处理,我们可以可视化原始文本和匿名文本。
这是应用程序的完整代码。
部署到 Heroku
Heroku 是一个平台即服务(PaaS ),支持开发人员完全在云中构建、运行和操作应用。
在 Heroku 上部署 Streamlit 应用非常简单。以下是要遵循的步骤:
1 —使用以下依赖项创建一个requirements.txt
文件,并将其放在项目的根目录下
**streamlit
spacy
st-annotated-text**
2 —在同一位置添加一个setup.sh
文件:这将处理服务器配置
**mkdir -p ~/.streamlit/****echo "\\
[server]\\n\\
headless = true\\n\\
enableCORS=false\\n\\
port = $PORT\\n\\
" > ~/.streamlit/config.toml**
3 —在同一位置添加一个名为Procfile
的文件,并使用以下脚本告诉 Heroku 如何启动 Streamlit 应用程序
**web: sh setup.sh && streamlit run --server.enableCORS false app.py**
4——确保应用程序在本地运行,并在 Github 上推送您的代码
5 —如果您还没有账户,请在heroku.com上创建一个(免费)账户
6 —转到https://dashboard.heroku.com/apps并点击创建新应用
作者图片
7-为应用程序选择一个名称,选择一个地区,然后点击创建应用程序
作者图片
8-Heroku 会询问您部署方法。选择 Github 选项,搜索你的回购,点击连接
作者图片
9-您可以选择手动或自动部署应用程序。我通常通过点击 deploy 分支(在我的例子中是main
分支)来手动完成这项工作
作者图片
10-点击部署后,Heroku 将开始构建应用程序。这可能需要几分钟时间
作者图片
11-应用程序部署后,您将获得 URL
作者图片
作者图片
12——看起来它起作用了
作者图片
下一步?
感谢你阅读并坚持到最后。正如承诺的那样,这里有一些改进这个应用程序的技巧:
- 处理更多语言(西班牙语、德语等。)通过添加空间模型
- 处理不同类型的文件,如 DOCXs 或 PDF:有一些 python 库允许你阅读 Word 和 PDF 文档这里和这里
- 允许多文件上传来处理批量文档
- 检测更多实体,如日期、电子邮件地址或信用卡号。检测这些实体不一定需要 NER 模型。有时候一个正则表达式就足够了
- 在更强大的实例上部署。一种方法是将你的应用程序分类,使用你最喜欢的云提供商
如果你对代码感兴趣,可以在我的 Github repo 上找到。
保重!
新到中?您可以每月订阅 5 美元,并解锁无限的文章— 单击此处。
如何用 FastAPI 构建和部署 NLP 模型:第 1 部分
原文:https://towardsdatascience.com/how-to-build-and-deploy-an-nlp-model-with-fastapi-part-1-9c1c7030d40?source=collection_archive---------8-----------------------
部署 NLP 模型的简单方法。
来自 Pexels 的 cottonbro 摄影
模型部署如果你要从事 NLP 模型工作,这是你应该掌握的最重要的技能之一。
模型部署是将模型集成到现有生产环境中的过程。该模型将接收输入,并为特定用例的决策预测输出。
“只有当模型与业务系统完全集成时,我们才能从其预测中提取真正的价值”。—克里斯托弗·萨米乌拉
有不同的方法可以将你的 NLP 模型部署到产品中,你可以使用 Flask,Django,Bottle e.t.c .但是在今天的文章中,你将学习如何使用 FastAPI 构建和部署你的 NLP 模型。
在这一系列文章中,您将了解到:
- 如何建立一个将 IMDB 电影评论分类成不同情绪的 NLP 模型?
- 什么是 FastAPI,如何安装?
- 如何用 FastAPI 部署您的模型?
- 如何在任何 Python 应用程序中使用您部署的 NLP 模型。
在第 1 部分中,我们将重点构建一个 NLP 模型,该模型可以将电影评论分类为不同的情感。所以让我们开始吧!
如何建立自然语言处理模型
首先,我们需要建立我们的 NLP 模型。我们将使用 IMDB 电影数据集来构建一个简单的模型,该模型可以分类关于该电影的评论是正面的还是负面的。下面是你应该遵循的步骤。
导入重要的包
首先,我们导入重要的 python 包来加载数据,清理数据,创建机器学习模型(分类器),并保存模型以供部署。
# import important modules
import numpy as np
import pandas as pd# sklearn modules
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.naive_bayes import MultinomialNB # classifier from sklearn.metrics import (
accuracy_score,
classification_report,
plot_confusion_matrix,
)
from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer# text preprocessing modules
from string import punctuation # text preprocessing modules
from nltk.tokenize import word_tokenizeimport nltk
from nltk.corpus import stopwords
from nltk.stem import WordNetLemmatizer
import re #regular expression# Download dependency
for dependency in (
"brown",
"names",
"wordnet",
"averaged_perceptron_tagger",
"universal_tagset",
):
nltk.download(dependency)
import warnings
warnings.filterwarnings("ignore")
# seeding
np.random.seed(123)
从数据文件夹加载数据集。
# load data
data = pd.read_csv("../data/labeledTrainData.tsv", sep='\t')
显示数据集的样本。
# show top five rows of data
data.head()
我们的数据集有 3 列。
- Id —这是审核的 Id
- 情绪 —积极(1)或消极(0)
- 评论 —对电影的评论
检查数据集的形状。
# check the shape of the data
data.shape
(25000, 3)
该数据集有 25,000 条评论。
我们需要检查数据集是否有任何缺失值。
# check missing values in data
data.isnull().sum()
id 0
感悟 0
回顾 0
dtype: int64
输出显示我们的数据集没有任何缺失值。
如何评价班级分布
我们可以使用 pandas 包中的 value_counts() 方法来评估数据集的类分布。
# evalute news sentiment distribution
data.sentiment.value_counts()
1 12500
0 12500
名称:情操,类型:int64
在这个数据集中,我们有相同数量的正面和负面评论。
如何处理数据
在分析数据集之后,下一步是在创建我们的机器学习模型之前,将数据集预处理成正确的格式。
这个数据集中的评论包含了很多我们在创建机器学习模型时不需要的不必要的单词和字符。
我们将通过删除停用字词、数字和标点来清理邮件。然后我们将使用 NLTK 包中的词汇化过程将每个单词转换成它的基本形式。
函数 text_cleaning() 将处理所有必要的步骤来清理我们的数据集。
stop_words = stopwords.words('english')def text_cleaning(text, remove_stop_words=True, lemmatize_words=True):
# Clean the text, with the option to remove stop_words and to lemmatize word # Clean the text
text = re.sub(r"[^A-Za-z0-9]", " ", text)
text = re.sub(r"\'s", " ", text)
text = re.sub(r'http\S+',' link ', text)
text = re.sub(r'\b\d+(?:\.\d+)?\s+', '', text) # remove numbers
# Remove punctuation from text
text = ''.join([c for c in text if c not in punctuation])
# Optionally, remove stop words
if remove_stop_words:
text = text.split()
text = [w for w in text if not w in stop_words]
text = " ".join(text)
# Optionally, shorten words to their stems
if lemmatize_words:
text = text.split()
lemmatizer = WordNetLemmatizer()
lemmatized_words = [lemmatizer.lemmatize(word) for word in text]
text = " ".join(lemmatized_words)
# Return a list of words
return(text)
现在我们可以通过使用 text_cleaning() 函数来清理我们的数据集。
#clean the review
data["cleaned_review"] = data["review"].apply(text_cleaning)
然后将数据分为特征变量和目标变量。
#split features and target from data
X = data["cleaned_review"]
y = data.sentiment.values
我们训练的特点是 cleaned_review 变量,目标是情绪变量。
然后,我们将数据集分成训练和测试数据。测试规模是整个数据集的 15%。
# split data into train and validateX_train, X_valid, y_train, y_valid = train_test_split(
X,
y,
test_size=0.15,
random_state=42,
shuffle=True,
stratify=y,
)
如何实际创建我们的 NLP 模型
我们将训练多项式朴素贝叶斯算法来分类评论是正面还是负面。这是文本分类最常用的算法之一。
但是在训练模型之前,我们需要将我们清理过的评论转换成数值,以便模型能够理解这些数据。在这种情况下,我们将使用 scikit-learn 中的 TfidfVectorizer 方法。TfidfVectorizer 将帮助我们将一组文本文档转换为 TF-IDF 特征矩阵。
为了应用这一系列步骤(预处理和训练),我们将使用来自 scikit-learn 的一个管道类,它顺序应用一系列转换和一个最终估计器。
# Create a classifier in pipeline
sentiment_classifier = Pipeline(steps=[
('pre_processing',TfidfVectorizer(lowercase=False)),
('naive_bayes',MultinomialNB())
])
然后我们训练我们的分类器。
# train the sentiment classifier sentiment_classifier.fit(X_train,y_train)
然后,我们根据验证集创建一个预测。
# test model performance on valid data
y_preds = sentiment_classifier.predict(X_valid)
将使用 accuracy_score 评估指标来评估模型的性能。我们使用 accuracy_score 是因为我们在情感变量中有相同数量的类。
accuracy_score(y_valid,y_preds)
0.8629333333333333
我们的模型的精度大约为 86.29%,这是一个很好的性能。
保存模型管道
模型管道将通过使用 joblib python 包保存在模型的目录中。
#save model
import joblib joblib.dump(sentiment_classifier, '../models/sentiment_model_pipeline.pkl')
包扎
恭喜👏👏,您已经完成了第 1 部分的学习。我希望你已经学到了一些关于如何构建 NLP 模型的新知识。在第 2 部分中,我们将学习如何用 FastAPI 部署 NLP 模型,并在 python 应用程序中运行它。
如果你学到了新的东西或者喜欢阅读这篇文章,请分享给其他人看。在那之前,第 2 部分再见!
你也可以在 Twitter 上找到我 @Davis_McDavid 。
最后一件事: 在以下链接阅读更多类似这样的文章。
https://medium.com/geekculture/scikit-learn-0-24-top-5-new-features-you-need-to-know-7af15d8cdeac https://medium.com/analytics-vidhya/how-to-deploy-a-machine-learning-model-for-free-7-ml-model-deployment-cloud-platforms-fd9191726a10
以前在这里发表过 。
如何用 FastAPI 构建和部署 NLP 模型:第 2 部分
原文:https://towardsdatascience.com/how-to-build-and-deploy-an-nlp-model-with-fastapi-part-2-e63a3eac71ad?source=collection_archive---------18-----------------------
部署 NLP 模型的简单方法
来自 Pexels 的 ThisIsEngineering 摄影
这是关于如何用 FastAPI 构建和部署 NLP 模型的系列文章的第二部分,也是最后一部分。在的第一部分,我们看了如何建立一个 NLP 模型,可以将电影评论分类成不同的情感。
在第二部分也是最后一部分,您将了解到
- 什么是 FastAPI,如何安装?
- 如何用 FastAPI 部署您的模型?
- 如何在任何 Python 应用程序中使用您部署的 NLP 模型。
所以让我们开始吧。🚀
什么是 FastAPI?
FastAPI 是快速的现代 python web 框架,用于构建不同的API。它提供了更高的性能,更容易编码,并提供了自动的交互式文档。
FastAPI 基于两个主要的 python 库 — Starlette (用于 web 处理)和 Pydantic (用于数据处理&验证)。与 Flask 相比,FastAPI 非常快,因为它将异步函数处理程序带到了表中。
如果您想了解 FastAPI 的更多信息,我推荐您阅读 Sebastián Ramírez 的这篇文章。
在本文中,我们将尝试使用 FastAPI 中的一些特性来服务于我们的 NLP 模型。
如何安装 FastAPI
首先,确保您安装了最新版本(带 pip):
pip install fastapi
你还需要一个 ASGI 服务器用于生产,比如uvicon。
pip install uvicorn
使用 FastAPI 部署 NLP 模型
在本节中,我们将使用 FastAPI 将我们训练过的 NLP 模型部署为 REST API。我们 API 的代码将保存在一个名为 main.py 的 python 文件中,这个文件将负责运行我们的 FastAPI 应用程序。
导入包
第一步是导入将帮助我们构建 FastAPI 应用程序和运行 NLP 模型的包。
初始化 FastAPI 应用程序实例
我们可以使用下面的代码来初始化 FastAPI 应用程序。
如您所见,我们已经定制了 FastAPI 应用程序的配置,包括:
- API 的标题
- API 的描述。
- API 的版本。
加载 NLP 模型
为了加载模型,我们使用 joblib.load() 方法,并将路径添加到模型目录中。NLP 模型的名称是情绪 _ 模型 _ 管道. pkl 。
定义一个函数来清理数据
我们将使用第 1 部分中的同一个函数 text_cleaning() ,该函数通过删除停用词、数字和标点符号来清理评论数据,最后,通过使用 NLTK 包中的词汇化过程将每个单词转换成其基本形式。
创建预测端点
下一步是用 GET 请求方法添加我们的预测端点“ /predict-review ”。
@app.get("/predict-review")
“API 端点是两个系统交互时通信通道的入口点。它指的是 API 和服务器之间的通信接触点。”
然后我们为这个端点定义一个预测函数。函数的名字叫做predict _ perspective()带有一个 review 参数。
predict _ perspective()函数将执行以下任务。
- 收到影评。
- 使用 text_cleaning() 函数清理电影评论。
- 使用我们的 NLP 模型进行预测。
- 将预测结果保存在输出变量中(0 或 1)。
- 将预测的概率保存在 probas 变量中,并将其格式化为两位小数。
- 最后,返回预测和概率结果。
这里是 main.py 文件中的所有代码块。
运行 API
以下命令将帮助我们运行我们创建的 FastAPI 应用程序。
uvicorn main:app --reload
下面是我们为 uvicorn 定义的运行 FastAPI 应用程序的设置。
- main: 包含 FastAPI 应用程序的文件 main.py。
- app: 在 main.py 中用 app = FastAPI()行创建的对象。
- — reload :使服务器在我们修改代码时自动重启。
FastAPI 提供了一个自动交互式 API 文档页面。要访问它,请在浏览器中导航到http://127 . 0 . 0 . 1:8000/docs,然后您将看到由 FastAPI 自动创建的文档页面。
文档页面显示了我们的 API 的名称、描述及其版本。它还显示了 API 中可用路线的列表,您可以与之交互。
要进行预测,首先点击"预测-审核"路线,然后点击按钮"试用",它允许您填写审核参数并直接与 API 交互。
通过添加您选择的电影评论来填写评论栏。我补充了以下关于 2021 年上映的扎克·施奈德版正义联盟电影的影评。
“我从头到尾都很喜欢这部电影。就像雷·费希尔说的,我希望这部电影不会结束。乞讨的场景令人激动,我非常喜欢那个场景。不像《正义联盟》这部电影展示了每个英雄最擅长自己的事情,让我们热爱每一个角色。谢谢扎克和整个团队。”
然后点击执行按钮进行预测,得到结果。
最后,来自 API 的结果显示,我们的 NLP 模型预测所提供的评论具有正面情感,概率为 0.70 。
在任何 Python 应用程序中使用 NLP 模型
要在任何 python 应用程序中使用我们的 NLP API,我们需要安装 requests python 包。这个 python 包将帮助我们向我们开发的 FastAPI 应用程序发送 HTTP 请求。
要安装请求包,请运行以下命令。
pip install requests
然后创建一个名为 python_app.py 的简单 python 文件。这个文件将负责发送我们的 HTTP 请求。
我们首先导入请求包。
import requests as r
补充一个关于哥斯拉 vs 孔(2021) 电影的影评。
# add review
review = "This movie was exactly what I wanted in a Godzilla vs Kong movie. It's big loud, brash and dumb, in the best ways possible. It also has a heart in a the form of Jia (Kaylee Hottle) and a superbly expressionful Kong. The scenes of him in the hollow world are especially impactful and beautifully shot/animated. Kong really is the emotional core of the film (with Godzilla more of an indifferent force of nature), and is done so well he may even convert a few members of Team Godzilla."
然后在要传递给 HTTP 请求的关键参数中添加评论。
keys = {"review": review}
最后,我们向我们的 API 发送一个请求,对评论进行预测。
prediction = r.get("http://127.0.0.1:8000/predict-review/", params=keys)
然后就可以看到预测结果了。
results = prediction.json()
print(results["prediction"])
print(results["Probability"])
这将显示预测及其概率。以下是结果。
正
0.54
包扎
恭喜👏👏,您已经完成了第 2 部分的学习。我希望您已经学到了一些关于如何使用 FastAPI 部署 NLP 模型的新知识。
如果你想了解更多关于 FastAPI 的知识,我推荐你参加由bit fuses创建的完整 FastAPI 课程。
您可以从这里下载本文中使用的项目源代码:
https://github.com/Davisy/Deploy-NLP-Model-with-FastAPI
如果你学到了新的东西或者喜欢阅读这篇文章,请分享给其他人看。在那之前,下一篇文章再见!。
你也可以在推特上找到我 @Davis_McDavid
最后一件事: 在下面的链接里多看看这样的文章。
https://medium.com/geekculture/scikit-learn-0-24-top-5-new-features-you-need-to-know-7af15d8cdeac https://medium.com/analytics-vidhya/how-to-deploy-a-machine-learning-model-for-free-7-ml-model-deployment-cloud-platforms-fd9191726a10
以前发表的 这里的。
如何为数据科学项目构建和使用自定义 python 包
原文:https://towardsdatascience.com/how-to-build-and-use-custom-python-packages-for-data-science-project-145b4f759d6f?source=collection_archive---------18-----------------------
比上次更干净的代码
由 Unsplash 上的品牌盒子拍摄
在数据科学项目中,我们根据问题的性质使用类似的步骤。通常,数据科学项目包括问题识别、数据收集和准备、功能工程、培训和测试模型以及部署。在这些步骤中,使用了几个函数。数据科学家需要在不同的项目中反复使用这些功能。例如,数据科学家导入不同的模型进行训练,然后用训练数据拟合模型,然后根据拟合的模型进行预测。为了评估模型,他/她需要使用某种形式的评估指标,如平均绝对百分比误差(MAPE)。所以,如果能把重复使用的代码保存在某个地方,一直重复使用,会节省很多时间,代码也会比上次干净很多。这就是构建定制包可以帮助数据科学家创建可重用代码的地方。
封装和模块:
python 中的包是模块的集合。另一方面,python 模块是一个由 python 语句和定义组成的文件。Python 有自己的包,我们在代码中一直导入和使用这些包。类似地,我们可以创建自己的模块,并将它们保存为一个包,这样我们就可以通过将它们导入到我们的代码中来反复使用它们。这有助于更好地管理代码,并增加代码的可重用性。这篇文章将展示我们如何创建一个包含一个模块的定制包,并在我们的回归问题中使用它。
构建我们的定制包:
在这个问题中,我们将使用 xgboost 和随机森林回归模型来训练模型,以便进行演示。然后,我们将使用平均绝对百分比误差(MAPE)来评估模型的准确性。最后,我们将尝试使用网格搜索来优化这两个模型的精度。因此,我们将创建所有这些函数来训练和评估模型,以及优化模型的超参数。我们将把所有这些函数放在一个 python 文件中,该文件将成为我们的模块,然后我们将通过插入该模块来创建一个包。我们可以继续在该包中添加模块。下面是我们将添加到模块/ python 文件中的函数。
import xgboost as xgb
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_absolute_percentage_error**#functions to train random forest regression model**def model_rf(x_train,y_train): #Function fits the random forest regression
model = RandomForestRegressor(random_state=0)
return model.fit(x_train,y_train)**#functions to train xgboost regression model**def model_xgb(x_train,y_train): #Function fits the xgboost regressor
model=xgb.XGBRegressor(objective ='reg:squarederror')
return model.fit(x_train,y_train)**#functions to calculate MAPE value**def result(model,x_test,y_true): #Funtion takes a fitted model and predicts based on x_test values and calculates the MAPE
y_pred=model.predict(x_test)
mape=mean_absolute_percentage_error(y_true, y_pred)*100
return mape**#functions to do grid search to optimize model hyper-parameters** def optimization(model,params,cv,x_train,y_train): # setup the grid search
grid_search = GridSearchCV(model,
param_grid=params,
cv=cv,
verbose=1,
n_jobs=1,
return_train_score=True)
return grid_search.fit(x_train, y_train)
从上面的代码中,我们可以看到我们导入了所有必需的库,然后创建了 4 个函数。model_rf 函数创建一个随机森林回归对象,然后拟合定型数据。model_xgb 函数创建一个 xgboost 回归对象,然后拟合定型数据。结果函数采用拟合模型、x_test 和 y_true 值。它使用 x_test 预测 y 值,然后通过比较 y_true 和预测值来计算 MAPE。
让我们将文件保存为 module.py,并将其放在名为 my_module 的文件夹中。我们可以用任何我们想要的名字。
作者照片
现在让我们创建一个空白的 python 文件,并将其命名为 init.py。因此,这非常重要。当 Python 有' init '时,它会将文件夹作为一个包读取。py '文件在里面。因此,我们创建文件并保存在同一个文件夹 my_module 中。
作者照片
这就是我们所需要的。现在,我们希望将该文件夹放在我们的 python 目录中,以便每次需要它时,我们可以将其作为内置的 python 包导入。因此,我们需要转到我们的目录,将 my_module 文件夹放在 site-packages 文件夹中。我用的是 anaconda3。因此,我将转到该文件夹,然后在 lib 文件夹中找到我的用于 anaconda 发行版的站点包,如下所示。
作者照片
之后,我将 my_module 文件夹粘贴到 site-packages 文件夹中。我放弃了,现在我可以将 my_module 作为一个包导入到我的 ide 中。之后,我可以在 my_module 包中创建的模块中使用所有这些函数。
作者照片
在上图中,我们可以看到我已经从我的 Jupiter 笔记本内部的 my_module 包中导入了一个模块。之后,我调用了 help 函数来查看模块内部的内容。我们可以看到它显示了保存在模块文件中的所有四个函数。它还显示了我们在计算机上安装该模块的路径。现在,我们可以在我们的问题中反复使用这些函数,而不是专门编写或复制粘贴。我们可以在模块文件中创建更多的函数,或者在 my_module 包中创建不同的模块文件。让我们使用我们的定制包来解决一个机器学习问题
问题:
动物园管理部门正试图了解不同栖息地的美洲驼数量。这个项目将帮助他们计划食物,这样他们就可以正确地喂养骆驼。我们有 20 个月的历史数据,包括不同栖息地的羊驼数量和一些天气特征。数据文件可以在下面的链接中找到
https://github.com/PriyaBrataSen/Machine_Learning_with_python/tree/main/Data
拉斯波娃·玛丽娜在 Unsplash 上拍摄的照片
数据预处理:
在这一步中,我们只是导入数据并做一些预处理,为我们的机器学习模型准备数据。
**#Importing some packages**import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import datetime as dt
from my_module import module**# Importing the two files and merging them together**df1=pd.read_csv('llama_forecast_train.csv')
df2=pd.read_csv('historical_weather.csv')
df2.rename(columns={'HOUR':'DAY'},inplace='True')
df1=pd.merge(df1,df2,on=['DAY'], how= "left")**#Breaking the date time variables**df1['Date']=pd.to_datetime(df1['DAY'])
df1.sort_values(by='Date',ascending=True,inplace=True)
df1['Year']=df1['Date'].dt.year
df1['Month']=df1['Date'].dt.month
df1['Week']=df1['Date'].dt.week
df1['Day']=df1['Date'].dt.day
df1['Week Day']=df1['Date'].dt.dayofweek
df1['Year Day']=df1['Date'].dt.dayofyear
df1.drop(['Date','DAY'],axis=1,inplace=True)**#Creating dummies for the habitat names becasue it is a qualitative variable**df3=pd.concat([df1, pd.get_dummies(df1[['HABITAT NAME']])], axis=1).drop(['HABITAT NAME'],axis=1)
df3=df3.reset_index(drop=True)
df3.head()
作者照片
模型构建:
现在,我们将数据分为训练和测试。在第二部分中,我们用训练数据拟合了随机森林和 xgboost 回归模型。在这里我们可以看到,我们从我们的模块中调用了 model_rf 和 model_xgb 函数,该模块是从我们的 my_module 定制包中导入的。不需要创建回归对象,然后用训练数据来拟合它们。导入的函数将完成这项工作
**# Splitting data in tarin test split**
y=df3['AVAILABLE LLAMAS']
x=df3.drop(['AVAILABLE LLAMAS'],axis=1)
b=int(len(df1)*.75)
x_train, x_test=x.iloc[0:b, :], x.iloc[b:-1, :]
y_train, y_test=y.iloc[0:b], y.iloc[b:-1]**# train both random forest and xgboost model**rf=module.model_rf(x_train,y_train)
xgboost=module.model_xgb(x_train,y_train)
模型评估:
让我们使用自定义包中的结果函数来计算随机森林和 xgboost 模型的 MAPE。我们只是传递 x 和 y 的模型和测试值
print('MAPE for random forest:',module.result(rf, x_test, y_test))
print('MAPE for xgboost:',module.result(xgboost, x_test, y_test))
作者照片
我们可以看到随机森林的 MAPE 为 20.01%,xgboost 为 20.07%。让我们使用网格搜索来改善结果。
超参数优化:
在本节中,我们将使用模块中的优化功能来调整两个模型的超参数。
**#Splitting data for hyperparameter tuning**
tss=TimeSeriesSplit(n_splits=3)**# define the grid for the xgboost**
params_xgb = {
"learning_rate": [0.01, 0.1],
"max_depth": [2, 4, 6],
"n_estimators": [10, 100,150],
"subsample": [0.8, 1],
"min_child_weight": [1, 3],
"reg_lambda": [1, 3],
"reg_alpha": [1, 3]
}**# define the grid random forest**
params_rf = {
"n_estimators": [50, 100, 150],
"max_features": [0.33, 0.66, 1.0],
"min_samples_split": [2, 8, 14],
"min_samples_leaf": [1, 5, 10],
"bootstrap": [True, False]
}**# fit the new models with the optimized hyper-parameters**grid_xgb=module.optimization(xgboost, params_xgb, tss, x_train, y_train)
grid_rf=module.optimization(rf, params_rf, tss, x_train, y_train)
在上面的块中,我们首先创建了双参数网格。这些将在网格搜索函数的 param_grid 参数中传递。最后,我们调用我们的优化函数,它主要计算模型的超参数的最佳值,并拟合精化的模型。同样,我们能够避免为超参数调节函数编写长代码。我们刚刚使用了模块中的函数。下面是优化模型的结果
print('MAPE for the tuned xgboost model:',module.result(grid_xgb, x_test, y_test))
print('MAPE for the tuned random forest model:',module.result(grid_rf, x_test, y_test))
作者照片
结论:
从上面的例子中,我们可以看到创建我们自己的 python 数据科学包并在我们的项目中重复使用它们是多么容易。这个过程也有助于保持你的代码整洁,节省大量时间。将自定义包放在 python 目录的站点包中非常重要,这样我们就可以像使用 python 中的内置包一样使用我们的自定义包。
如何建立更好的机器学习模型
原文:https://towardsdatascience.com/how-to-build-better-machine-learning-models-537a4486d056?source=collection_archive---------30-----------------------
开发良好深度神经网络的提示、技巧和指南
伊万·阿列克西奇在 Unsplash 上的照片
开发者们好👋。如果你以前建立过深度神经网络,你可能知道这需要大量的实验。
在本文中,我将与您分享一些有用的技巧和指南,您可以使用它们来更好地建立更好的深度学习模型。这些技巧会让你更容易发展一个好的人际网络。
你可以选择使用哪些技巧,因为有些对你正在做的项目更有帮助。并不是本文中提到的所有东西都能直接提高模型的性能。
超参数 tuning🕹️的高级方法
训练深度神经网络的一个更痛苦的事情是,你必须处理大量的超参数。
这些可能是你的学习率 α ,折现因子 ρ 和εε,如果你使用的是 RMSprop 优化器(辛顿等人),或者是指数衰减率 β₁ 和 β₂ ,如果你使用的是亚当优化器(金玛等人)。
您还需要选择网络中的层数或层的隐藏单元数。您可能正在使用学习率调度程序,并且想要配置这些功能以及更多功能😩!我们确实需要更好地组织超参数调整过程的方法。
我倾向于使用随机搜索算法来组织我的超参数搜索过程。尽管有其他可能更好的算法,但我通常最终还是会使用它。
假设在本例中,您想要调整两个超参数,并且您怀疑这两个参数的最佳值都在 1 到 5 之间。
这里的想法是,与其选择 25 个值像(1,1) (1,2)等系统地尝试,随机选择 25 个点会更有效。
基于吴恩达的课堂笔记
下面是一个关于 TensorFlow 的简单示例,我尝试在时尚 MNIST 数据集上使用随机搜索来获得学习率和第一密集层中的单元数量:
张量流随机搜索
在这里,我怀疑第一密集层中单元的最佳数量将在 32 和 512 之间,并且我的学习率将是 1e-2、1e-3 或 1e-4 之一。
因此,如本例所示,我将单位数的最小值设为 32,最大值设为 512,步长为 32。然后,我指定了一个可以尝试的范围,而不是硬编码一个单位数的值。
hp_units = hp.Int('units', min_value = 32, max_value = 512, step = 32)
model.add(tf.keras.layers.Dense(units = hp_units, activation = 'relu'))
我们对我们的学习率做同样的事情,但是我们的学习率只是 1e-2、1e-3 或 1e-4 中的一个,而不是一个范围。
hp_learning_rate = hp.Choice('learning_rate', values = [1e-2, 1e-3, 1e-4])
optimizer = tf.keras.optimizers.Adam(learning_rate = hp_learning_rate)
最后,我们执行随机搜索,并指定在我们构建的所有模型中,具有最高验证准确性的模型将被称为最佳模型。或者简单地说,获得良好的验证准确性是目标。
tuner = kt.RandomSearch(model_builder,
objective = 'val_accuracy',
max_trials = 10,
directory = 'random_search_starter',
project_name = 'intro_to_kt')
tuner.search(img_train, label_train, epochs = 10, validation_data = (img_test, label_test))
这样做之后,我还想检索最佳模型和最佳超参数选择。尽管我想指出使用get_best_models
通常被认为是一种捷径。
为了获得最佳性能,您应该使用在整个数据集上获得的最佳超参数来重新训练您的模型。
# Which was the best model?
best_model = tuner.get_best_models(1)[0]# What were the best hyperparameters?
best_hyperparameters = tuner.get_best_hyperparameters(1)[0]
我不会在这篇文章中详细讨论这些代码,但是如果你愿意,你可以在这篇文章中读到。
对大型网络使用混合精度训练🎨
你的神经网络越大,你的结果就越准确(一般来说)。随着模型规模的增长,用于训练这些模型的内存和计算需求也会增加。
使用混合精度训练的想法(NVIDIA, Micikevicius 等人)是使用半精度浮点数来训练深度神经网络,这让您可以更快地训练大型神经网络,而不会降低或可以忽略网络的性能。
但是,我想指出的是,这种技术应该只用于参数超过 1 亿左右的大型模型。
虽然混合精度可以在大多数硬件上运行,但它只会提高最近的 NVIDIA GPUs(例如特斯拉 V100 和特斯拉 T4)和云 TPU 上的模型的速度。
我想让您了解一下使用混合精度时的性能提升。当我在我的 GCP 笔记本实例(由 Tesla V100 组成)上训练 ResNet 模型时,它在训练时间上几乎好了三倍,在云 TPU 实例上几乎好了 1.5 倍,准确性几乎没有差异。测量上述加速的代码取自本例。
为了进一步增加你的训练量,你也可以考虑使用更大的批量——因为我们使用的是 float16 tensors,你应该不会耗尽内存。
用 TensorFlow 实现混合精度也相当容易。使用 TensorFlow,您可以轻松使用 tf.keras.mixed_precision 模块,该模块允许您设置数据类型策略(使用 float16)并应用损失缩放以防止下溢。
下面是一个在网络上使用混合精度训练的简单示例:
在这个例子中,我们首先将dtype
策略设置为 float16,这意味着我们所有的模型层都将自动使用 float16。
这样做之后,我们构建一个模型,但是我们覆盖了最后一个或输出层的数据类型为 float32,以防止任何数字问题。理想情况下,你的输出层应该是 float32。
注意:我已经建立了一个有这么多单位的模型,所以我们可以看到混合精度训练在训练时间上的一些差异,因为它对大型模型很有效。
如果您正在寻找使用混合精度训练的更多灵感,这里有一张图片,展示了 Google Cloud 在 TPU 上对多个模型进行加速:
云 TPU 上的加速
对 backpropagation✔️使用毕业支票
在多种情况下,我不得不定制实现一个神经网络。实现反向传播通常是容易出错的方面,也很难调试。
通过不正确的反向传播,你的模型可能会学到一些看起来合理的东西,这使得调试更加困难。那么,如果我们能够实现一些东西,让我们能够轻松地调试我们的神经网络,那该有多酷呢?
我经常在实现反向传播时使用梯度检查来帮助我调试它。这里的想法是使用数值方法来近似梯度。如果它接近反向传播算法计算的梯度,那么您可以更加确信反向传播是正确实现的。
到目前为止,你可以用这个表达式得到一个向量,我们称之为dθ[approx]
:
计算近似梯度(图片由作者提供)
如果你正在寻找这背后的原因,你可以在我写的这篇文章中找到更多。
所以,现在我们有两个向量dθ[approx]
和dθ
(通过反向投影计算)。而这些应该是彼此几乎相等的。您可以简单地计算这两个向量之间的欧几里德距离,并使用该参考表来帮助您调试网络:
参考表格(图片由作者提供)
缓存数据集💾
缓存数据集是一个简单的想法,但我没见过用得多的。这里的想法是检查整个数据集,并将其缓存在文件或内存中(如果它是一个小数据集)。
这将使你不必在每个时期执行一些昂贵的 CPU 操作,如文件打开和数据读取。
这也意味着你的第一个纪元会花费更多的时间📉因为理想情况下,您会执行所有操作,如在第一个时期打开文件和读取数据,然后缓存它们。但是随后的时期应该快得多,因为您将使用缓存的数据。
这看起来绝对是一个非常容易实现的想法,对吗?这里有一个 TensorFlow 示例,展示了如何轻松缓存数据集。它还显示了加速🚀实现这个想法。在我的要点中找到下面例子的完整代码。
一个简单的数据集缓存和加速的例子
如何解决⭐过度拟合的问题
当您使用神经网络时,过度拟合和欠拟合可能是您面临的两个最常见的问题。这一部分讲述了我在处理这些问题时常用的一些方法。
您可能知道这一点,但高偏差会导致您错过要素和标注之间的关系(拟合不足),而高方差会导致模型捕捉噪声并过度拟合训练数据。
我认为解决过度拟合的最有效方法是获取更多的数据——尽管你也可以扩充你的数据。深度神经网络的一个好处是,随着数据越来越多,它们的性能会提高。
但在很多情况下,获取更多数据可能成本太高,或者根本不可能。在这种情况下,让我们谈谈你可以用来解决过度拟合的其他方法。
除了获取更多数据或扩充数据,您还可以通过改变网络的架构或对网络的权重进行一些修改来解决过度拟合问题。我们来看看这两种方法。
改变模型架构
改变架构的一个简单方法是使用随机搜索偶然发现一个好的架构。或者您可以尝试从模型中删除节点,从本质上降低模型的容量。
我们已经讨论了随机搜索,但是如果你想看修剪的例子,你可以看看 TensorFlow 模型优化修剪指南。
修改网络权重
在这一节中,我们将看到一些我常用的方法,通过修改网络的权重来防止过度拟合。
权重正则化
重复我们所讨论的,“简单的模型比复杂的模型更不容易过度拟合”。我们试图通过强制网络权重取小值来限制网络的复杂性。
为此,我们将在损失函数中添加一项,如果模型的权重较大,则该项会对模型不利。通常使用 L₁和 L₂正则化,区别在于:
- L1——增加的惩罚是∝对|权重系数|
- L2——增加的惩罚是∝到|权重系数||
其中|x|代表绝对值。
你注意到 L1 和 L2 的区别了吗,平方项?由于这个原因,L1 可能会推动权重等于零,而 L2 会有权重趋于零,但不是零。
如果你对进一步探索这个问题感兴趣,这篇文章深入探讨了规范化,可能会有所帮助。
这也是我倾向于使用 L2 多于 L1 正则化的确切原因。让我们看一个 TensorFlow 的例子。
在这里,我展示了一些代码来创建一个简单的 3 个单位和 L2 正则密集层:
import tensorflow as tf
tf.keras.layers.Dense(3, kernel_regularizer = tf.keras.regularizers.L2(0.1))
为了更清楚地说明这是干什么的,正如我们上面讨论的,这将向损失函数添加一项(0.1 ×权重系数值),作为对非常大的权重的惩罚。此外,在上面的代码中,将 L2 替换为 L1 来为您的层实现 L1 非常简单。
辍学者
当我在构建一个模型并且面临过度拟合时,我做的第一件事就是尝试使用 droppets(Srivastava 等人)。这里的想法是在训练过程中随机丢弃或设置为零(忽略)x%的图层输出要素。
我们这样做是为了阻止单个节点依赖于其他节点的输出,并防止它们过多地从其他节点进行共同适应。
使用 TensorFlow 很容易实现辍学,因为他们可以作为层使用。下面是一个例子,我试图建立一个模型来区分辍学的狗和猫的图像,以减少过度拟合:
model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(32, (3,3), padding='same', activation='relu',input_shape=(IMG_HEIGHT, IMG_WIDTH ,3)),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Conv2D(128, (3,3), padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(512, activation='relu'),
tf.keras.layers.Dense(1, activation='sigmoid')
])
正如您在上面的代码中看到的,您可以直接使用tf.keras.layers.dropout
来实现 dropout,向它传递要忽略的输出特征的一部分(这里是 20%的输出特征)。
提前停止
早期停止是我经常使用的另一种正则化方法。这里的想法是在验证集上的每个时期监控模型的性能,并在满足验证性能的某些指定条件时终止训练(如当丢失时停止训练< 0.5)
It turns out that the basic condition like we talked about above works like a charm if your training error and validation error look something like in this image. In this case, Early Stopping would just stop training when it reaches the red box (for demonstration) and would straight up prevent overfitting.
)它(早期停止)是一种如此简单有效的正则化技术,以至于 Geoffrey Hinton 称之为“美丽的免费午餐”。
—使用 Aurelien Geron 的 Scikit-Learn 和 TensorFlow 进行机器实践学习
改编自Lutz pre helt
但是,在某些情况下,您可能无法直接选择识别标准或知道何时停止训练模型。
就本文的范围而言,我们不会在这里讨论更多的标准,但我建议您查看“早期停止—但何时,Lutz pre helt”,我经常使用它来帮助确定标准。
让我们看一个使用 TensorFlow 提前停止操作的示例:
import tensorflow as tfcallback = tf.keras.callbacks.EarlyStopping(monitor='loss', patience=3)
model = tf.keras.models.Sequential([...])
model.compile(...)
model.fit(..., callbacks = [callback])
在上面的例子中,我们创建了一个提前停止的回调,并指定我们想要监控我们的损失值。我们还规定,如果在 3 个时期内损失值没有明显的改善,就应该停止训练。最后,在训练模型时,我们指定它应该使用这个回调。
此外,为了这个例子的目的,我展示了一个顺序模型——但是这也可以以完全相同的方式与用功能 API 或子类模型创建的模型一起工作。
感谢您的阅读!
谢谢你坚持到最后。我希望你能从这篇文章中受益,并将这些技巧应用到你自己的实验中。
我很高兴看到它们是否也能帮助你提高神经网络的性能。如果您对我有任何反馈或建议,请随时通过 Twitter 联系我。
如何大规模构建数据工程管道
原文:https://towardsdatascience.com/how-to-build-data-engineering-pipelines-at-scale-6f4dd3746e7e?source=collection_archive---------3-----------------------
理解大数据
你在海滩上,看到周围有许多贝壳。我们用这个来学习 ETL / ELT,火花,气流。
想象你在一个海滩上,你在闲逛,看着海浪来来去去,看着海滩上所有的贝壳。你会有一个想法。你收集这些贝壳做成项链去卖怎么样?
你想在海滩上用贝壳做项链。让我们从这个例子中学习数据工程的概念。[ 来源
你会怎么做呢?也许你可以收集一些贝壳,做一条小项链,试着展示给你的朋友。这是 ETL 流程的一个示例,首先提取看起来不错的外壳/原始数据,然后进行转换,即构建一条项链,并加载到您向朋友展示的位置。如果她喜欢,你可以回来收集更多的贝壳,做更多的项链。
我们将使用这个例子来学习所有关于构建数据工程管道的知识。我发现使用一个相关的例子更容易(也更有趣!)来理解复杂的概念。
1.为什么是数据工程?
创建原始数据源并获得洞察力
互联网公司创造了大量的数据。在互联网时代,数据集变得越来越大,越来越乱,用户在网站上的所有行为和互动都有大量的数据集,包括产品描述、图片、时间序列信息、评论等。
据说数据是新的石油。对于天然石油,我们还需要一种方法来钻探和开采这种石油,使其变得有用。同样,我们需要一种方法来挖掘和理解所有这些有用的数据。
一方面,高管和管理层希望从这些数据集中获得洞察力。
数据科学家和 ML 实践者也希望有干净的数据集来建模。
当你这样做时,有一些真正有趣的权衡要做。作为一名数据科学家或处理大量数据的人工智能人员,了解这些可以帮助你。无论您处于数据之旅的哪个阶段,我想您都会对这些内容感兴趣。
2.ETL 与 ELT
在海滩上制作项链,而不是先用卡车将贝壳运到仓库
大多数公司将不同的数据源(JSONs、CSV、Parquets 等)存储在一个数据湖中。数据湖可以建立在亚马逊 S3 或谷歌云存储。它高度可用、耐用,完全由云提供商管理,而且非常便宜,非常适合您将来可能会使用或不会使用的数据集。您的数据湖中的数据就像海滩上的贝壳。我们需要将其转换并加载到干净、原始的结构中,以供高管和数据科学家使用。保持干净、原始和规范数据的地方可以是一个数据仓库。数据仓库还支持延迟非常低的分析查询(COUNT、SUM、GROUPBY ),因为它们以列格式存储数据——想象一下将所有事务量放在内存的同一个位置。
我们希望将数据湖中的数据转换成数据仓库中的原始规范的事实[ 来源
回到 shells 的例子。你送给你的朋友一条贝壳项链,她很喜欢。她要你现在做 1000 条项链出售。我们如何做到这一点?
你可以继续做 ETL 过程,比如在海滩上做 1000 条项链。运输最终产品。这里的缺点是,如果一条项链的外壳有问题,或者一个外壳坏了,你就必须扔掉整条项链,回到海滩,从头开始。在数据领域,这意味着如果您首先转换数据,然后将其加载到数据仓库中。有人可能会发现代码的问题或 bug 然后你不得不再次找到原始资料,从头开始。所以这是不好的,对吗?替代方案是什么?
嗯,这是 ELT。你把所有你认为可能有趣的贝壳先装上卡车,然后再做项链。如果壳牌有什么问题,你有一整卡车的壳牌在那里等着你。听起来很棒,对吧?这里的缺点是,你需要大量的储存,你需要这些巨型卡车将贝壳运送到你的仓库,在那里你有一个团队处理这些贝壳。
3.何时使用 ETL 还是 ELT
对于敏感数据使用 ETL。当存储成本不成问题时,使用 ELT。
ETL 基本上是把贝壳转化成项链,然后把它们装上卡车运到仓库。ELT 加载有趣的 shells,然后在仓库中进行转换。我们什么时候会使用一个而不是另一个?如果存储是个问题,ETL 更好。如今,仓库的存储成本非常低廉,存储成本通常不再是问题。使用 ETL 而不是 ELT 的一个更有效的理由是为了敏感数据。在贝壳的情况下,想象一下,如果一些贝壳是有毒的,我们不希望它们靠近我们的仓库,我们会想先清洗它们,加工它们,可能先只做一条项链。敏感数据也是如此——我们不希望将 PII 的数据加载到仓库中,以便以后进行转换。
ELT 更好的一个地方是,如果你认为你的转换会有频繁的变化。转换可以在任何地方进行,从填充和输入缺失数据到计算统计数据、聚合数据或其他信息。如果你认为会有变化,最好使用 ELT,这样你就可以很好地比较转换前和转换后的数据。ELT 真正大有用武之地的一个常见领域是网络分析。
您希望首先将所有的客户交互和交易加载到一个仓库中,然后再次转换它们,最后重新加载回商业智能。dbt 是一个很棒的工具,可以让你做 ELT——你可以对转换步骤的 SQL 代码进行版本控制。
4.使用 Spark 进行大数据处理
支持以分布式方式处理海量数据集
到目前为止,在你的项链生意中,我们假设只有你和几辆卡车和一个小仓库,如果人们真的喜欢你的贝壳,而你不得不加工成千上万个呢?你需要什么?你需要租用或购买几台加工机器,这些机器采用不同的外壳,并行工作来制作项链。你不会希望你的顾客等很久才收到项链。像 Spark 这样的大数据框架就是这么做的。
Spark 是一个处理海量数据集的框架。它让您能够以分布式方式处理大数据。它让几个工人运转起来,这些工人处理你的大数据集,所有这些都由一个驱动节点来编排。“大数据”一词在 2000 年代末/2010 年代初开始流行,Hadoop 等框架也开始流行。您可能想知道 Hadoop 与 Spark 有何不同。基本上 Spark 是 Hadoop 的更快版本,它们都在底层使用 MapReduce 技术,但 Spark 将大块数据保存在内存中,而 Hadoop 将数据作为物理文件保存在磁盘存储中。这使得火花快得多。
Spark 可以让你处理大规模的数据
Spark 可以让你对数十亿条记录进行大规模的 ETL 或 ELT,Spark 还可以从 S3 等地读取数据,并写入 S3 或数据仓库。您可以进行混合,其中一个阶段提取并加载到 S3,然后另一个阶段转换 S3 数据,估算,添加新信息,然后加载到仓库->这是 ETL 和 ELT 的组合。
Spark 还支持使用 MLLib 的并行机器学习算法,该算法在机器之间划分数据,并在梯度下降期间定期更新参数。这叫做全归术。MLLib 并不支持所有的 ML 算法,但正在慢慢赶上。
你既可以自己运行 Spark,也可以使用完全托管的服务,比如 Amazon EMR 或 Databricks。在我的另一个媒体帖子中阅读更多内容。Jules Damji 的书,学习 Spark 真的很棒。
5.利用气流进行数据编排
你需要一个系统的方法来安排任务的顺序。
最后,当您的 shells 并行处理变成一个真正的大型操作时——您可能需要一个指挥者——一个告诉卡车应该开始移动或者处理被延迟等等的人。这个编排者可以是一个人,也可以是一个跟踪单个进程的机器人。在数据领域,这个协调器可以是定制的 cron 作业,或者类似于 Airflow 的东西。Airflow 允许你在一个 DAG 或者一个有向无环图中安排所有的事情,下一步依赖于前一步,你可以使用 cron 语句控制它们何时运行。
我们需要一种方法来协调和安排不同的任务
Airflow 需要一个地方来托管它以运行 web 服务器。亚马逊为 Apache Airflow ( MWAA )服务创建了托管工作流。虽然如果你在亚马逊生态系统中,只需要你上传 Dag 到 S3,这是一个很好的服务,但他们对最新气流发布的支持很慢。如果最新版本的支持对你很重要——试试天文学家. io——他们很棒。
您可能还想对这样一个大型系统进行监控,Airflow 可以让您进行协调,并查看哪个阶段出现了故障。但是您可能希望使用 Spark 的 Ganglia UI 来查看不同工作人员的指标——CPU 使用率、空闲内存、网络带宽等。您也可以使用 Datadog 来监控这些。
6.存储格式和数据仓库的选择
虽然 CSV 和 JSON 对于一般的数据科学来说很棒,因为它们是人类可读的,但是对于大型数据集来说,最好使用像 Parquet、Avro 或 Delta 这样的文件格式。拼花地板是柱状存储类型,而 Avro 是基于行的格式。Parquet 对于大型数据集来说很常见,因为它允许您快速查询特定的列。另一个选择是使用 Delta 格式,它位于 Parquet 之上,但是增加了事件历史、交易日志和其他特性。你可以在 Spark 上使用其中的任何一个,并将数据存储在 S3。
您可以定期将这些数据加载到数据仓库中。数据仓库有多种选择。红移是面向数据仓库的 AWS 产品。 BigQuery 是 GCP 产品,雪花是另一种选择。我广泛地比较了红移和雪花,对雪花的速度和平滑程度印象深刻。它还支持按使用量付费的格式,只对查询收费。另一方面,只要实例在运行,红移就会向您收取任何费用。
您的另一个选择是最近的 lakehouse 架构,它将数据湖和数据仓库合并到一个地方。Delta Lake 是 Databricks 提供的一个这样的产品,它在底层处理 Delta 存储格式,并提供一种像仓库一样查询数据的方法。
摘要
可以构建 ETL 管道,从数据湖(S3)处理原始数据并在 Spark 中转换,然后加载到数据仓库(如雪花或红移),然后为 BI 工具(如 Tableau 或 Looker 或 PowerBI)提供动力。这符合管理者希望做出数据驱动决策的用例。
您也可以首先从仓库内不同的来源收集数据,然后使用 Spark 转换这些大型数据集,将它们加载到 S3 的 Parquet 文件中,然后从 SageMaker 读取它们,以防您更喜欢使用 SageMaker 而不是 Spark 的 MLLib。这符合数据科学家/ ML 工程师的用例。
我们学到了什么?
1。我们从几个 shells 和一条项链开始,来理解 ETL 和 ELT 之间的权衡。在海滩上制作项链,而不是先用卡车把贝壳运到仓库。
2。我们扩大了运营规模,了解了 Spark 的使用案例。
3。我们用气流这样的管弦乐器把一切都连接起来。
这篇关于理解数据工程管道的博文到此结束。感谢您到目前为止的阅读,如有任何问题或评论,请通过 LinkedIn 联系我!
P.S —查看我的播客 第一集 !我将更详细地介绍数据仓库选择、OLAP 与 OLTP 等。
同一主题的播客插曲:https://open.spotify.com/episode/4FzmyNVEpdn1pxyjQ9j5fJ
如何大规模建立数据信任和所有权
原文:https://towardsdatascience.com/how-to-build-data-trust-and-ownership-at-scale-bf84ceab41c1?source=collection_archive---------25-----------------------
个案研究
物流公司 Optoro 通过自助式数据质量和所有权方法每周节省 44 个小时。以下是方法。
图片由 Unsplash 上的 Marcin Jozwiak 提供。
当你的客户第一个知道数据出错时,他们对你的数据和你的公司的信任就会受损。了解物流公司 Optoro 的数据工程团队如何直面这一挑战,通过大规模数据可观察性重获信任和宝贵时间。
总部位于 DC 华盛顿州的 Optoro 有一个令人钦佩的使命:通过消除退货中的所有浪费,使零售更具可持续性。他们为宜家、塔吉特(Target)和百思买(Best Buy)等领先零售商提供退货技术和物流,帮助提高盈利能力,同时通过重新推荐或为退货寻找“下一个最好的家”来减少环境浪费。
在 Fivetran 的数据工程师答谢日期间,我最近有机会与 Optoro 的首席数据工程师 Patrick Campbell 聊天。我们深入探讨了 Optoro 的数据团队和技术堆栈、他们面临的挑战,以及 数据可观察性 如何帮助他们实现构建更可持续的零售行业的使命。
Optoro 的数据环境
表面上,Optoro 为零售商重新安排退货或未售出的商品。但是除了运送大量的商品,Optoro 真正的业务是运送数据。很多数据。
Patrick 说:“我们的技术平台将每一件物品都连接到它的下一个最好的家。“可以想象,当我们通过我们的系统发送退货库存时,该系统会创建许多关键任务数据点。”
Optoro 的数据工程团队最近转移到工程组织下,以便更有效地与技术和产品团队合作,但他们自然会与数据质量、数据科学和数据分析团队合作。Optoro 还有许多内部和外部的数据消费者,他们通过 Looker 仪表盘访问数据。但它并不总是可靠的。
挑战:数据完整性
“我们需要深入了解我们数据的质量,简单明了,”Patrick 说。“我们没有一个好的方法来了解数据何时可能丢失,何时可能过时,或者数据是否不是我们预期的那样。”
这意味着当数据问题发生时,客户(而不是 Optoro 的数据团队)往往是第一个知道的。这将导致客户不满,并阻止 Optoro 提供有关其软件管理的库存的可靠信息。
解决方案:数据可观察性
一个警报工作流向 Patrick 的团队通知了由配送问题触发的特定仓库中的异常情况。图片由 Optoro 提供。
Patrick 的团队需要在客户和不良数据之间找到平衡点,他们有两个选择:构建或购买。Patrick 考虑使用 dbt 构建定制的 SQL 完整性检查,但他知道由于资源有限,他的团队只能部分覆盖 Optoro 的许多管道,这将长期增加数据工程团队已经很大的工作量。
相反,他们选择创建一个概念验证,以了解他们在解决数据质量问题方面能取得多大进展。数据可观测性使用机器学习来推断和学习数据的样子,识别数据质量问题,并在出现问题时通知正确的团队成员。
概念验证要求 Optoro 能够实现以下目标:
- 过时数据产品警报
- 对大型管道更改(如模式更改)发出警报
- 当操作数据库安全地进行故障转移时,提供不间断的监控和警报
- 基于预期的数据行为自动生成规则
- 能够编写自定义警报 SQL 检查以监控特定用例。
这些成果将帮助 Patrick 的团队实现他们的最终目标,即防止数据质量问题对客户体验产生负面影响。
Optoro 的数据平台利用雪花仓库、Fivetran 进行集成、dbt 进行转换、Monte Carlo 进行数据观察,以及 Looker 进行分析。图片由 Optoro 提供。
POC 实现了它的目标。Patrick 和他的团队开始全面整合该平台,将它与 Snowflake、Fivetran、dbt 等一起放在 Optoro 的数据堆栈中。
从接收、转换到 BI 报告,这些工具协同工作,蒙特卡罗在数据生命周期的每个阶段都密切关注。
结果:通过沿袭获得可信数据
数据可观察性让 Patrick 的团队可以跨数据资产绘制端到端的谱系图,甚至可以在 Looker 中绘制到字段级别。图片由 Optoro 提供。
随着监控和警报的到位,Patrick 和他的团队现在是第一个知道数据丢失或管道中断的人。当收到警报时,数据工程师可以更快地解决问题,这得益于自动化的沿袭数据可观察性。
“我们可以看到受影响的数据源,从内部数据集市一直到我们面向客户的 Looker 报告,”Patrick 说。“能够快速识别客户面临的问题并积极主动是建立对我们数据信任的关键。这个特性使数据工程师的工作变得更加容易——我可以从这里的经验明确地告诉你。"
对于 Optoro 的数据工程师来说,拥有不需要任何手动映射或更新的端到端全自动数据血统是 Patrick 最喜欢的平台部分之一。
Patrick 说:“数据可观察性能够建立这种血统本身就很了不起。“在构建上游和下游依赖关系方面,我们的数据团队几乎不需要任何投入。”
结果:数据团队节省时间并加快速度
Optoro 数据工程团队还估计,数据可观测性为他们每个工程师每周节省了至少四个小时的支持时间来调查不良数据。对于一个 11 人以上的数据工程团队来说,这相当于每周 44 小时。
而且,由于所有数据团队(不仅仅是工程师)现在都可以访问自助监控和警报、数据目录视图和沿袭,Patrick 报告说,其他数据团队正在逐步接管更多数据所有权,并在他们交付的产品中承担更多责任。
“这不仅是数据工程在试图追踪大海捞针问题方面的巨大胜利,还帮助我们使其他数据团队能够帮助我们保持对我们数据的信任,”Patrick 说。
“建立这些框架使数据工程不再是这些情况下的中间人或女人……数据完整性确实应该是自助服务。您的数据工程师会感谢您的。”
好奇数据可观察性如何帮助你的团队建立信任和节省时间?伸出手去 巴尔摩西 和 蒙特卡洛团队 了解更多!
如何在 BigQuery 中构建高效的数据结构
原文:https://towardsdatascience.com/how-to-build-efficient-and-perfomant-data-structures-in-bigquery-7981203b8a62?source=collection_archive---------20-----------------------
使用反规范化和嵌套数据的方法
李中清在 Unsplash 上拍照
BigQuery 是一个完全托管的、无服务器的数据仓库,位于谷歌云平台基础设施上,提供可扩展的、经济高效的、快速的 Pb 级数据分析。它是支持使用标准 SQL 查询的服务软件。在本文中,我想提到两种主要的技术来使您的 BigQuery 数据仓库变得高效和高性能[1]。
前方有些理论
SQL vs NoSQL : SQL 数据库是基于表格的数据库,而 NoSQL 数据库可以是基于文档、键值对和图形的数据库。SQL 数据库是垂直可伸缩的,而 NoSQL 数据库是水平可伸缩的。SQL 数据库有一个预定义的模式,而 NoSQL 数据库对非结构化数据使用动态模式[2]。
基于行和基于列的数据库:行结构的数据库将属于特定表行的数据存储在相同的物理位置。著名的例子是 MySQL 和 MSSQL 数据库。面向列的数据库与最常见的面向行的数据库形成对比。与面向行的数据库不同,它们不存储彼此相邻的单个行,而是存储列。这种形式的存储对于涉及大量数据的分析过程特别有用,因为聚合函数通常必须针对各个列进行计算。众所周知的例子有 HBase、MongoDB 或 Google BigQuery。
现在,我们来看下两个重要的理论术语: OLTP 和 OLAP 。在线事务处理(OLTP)实时捕获、存储和处理来自事务的数据。而在线分析处理(OLAP)使用复杂的查询来分析来自 OLTP 系统的汇总历史数据。与行结构数据库相比,列数据库存在以下问题:
- 具体化整行的开销很大。如果您想执行与 select * from 等效的操作,那么您必须对所有列索引执行一次联接来获取值。
- 虽然插入很简单,但是更新和删除操作很复杂。
出于上述原因,真正的列数据库主要用于数据仓库、分析和其他归档类型的数据存储,而行结构数据库通常更适合 OLTP 工作负载。
那现在怎么办?
这一次,介绍基本的理论背景对我来说很重要。因为你要知道 BigQuery 最能被描述为一个混合系统。这绝对是一个基于色谱柱的系统,因此更适合用于分析目的。这对于理解为什么数据应该反规格化也很重要——稍后会详细介绍。此外,BigQuery 与标准 SQL 数据仓库非常相似,因为它可以使用标准 SQL 进行查询,并且更多地充当来自 OLTP 系统的数据(而不是图像数据等)的存储库,但另一方面允许存储嵌套的数据结构。所以 BigQuery 才能真正称得上混合。
非规范化数据
以下部分将描述整个过程背后的技术部分。首先,人们必须考虑如何构建他们的最佳数据模式。数据工程师不应该采用或重新开发传统的星型或雪花型模式,而应该考虑相反的情况,即反规范化。如前所述,数据通常来自 OLTP 系统并被规范化。在 BigQuery 中,数据应该再次反规范化。这里有一个小的基本例子:
非规范化-作者图片
简单地说,您应该在您的 ETL/ELT 过程中连接在内容上属于一起的表,并将它们保存为一个新表。视图上的连接理论上也是可行的,但是存储的表——例如在一天的转换步骤中更新一次——性能更好。因此,在上面的示例中,您可以将客户数据与销售数据连接起来,并将其保存为一个新对象。这里的挑战是还要在后台处理业务流程,以便能够找到有意义的新数据对象,并尽可能减少后续数据分析过程中出现的连接和转换。
嵌套数据
反规范化过程的下一步是将销售额打包(如果需要的话)到嵌套结构中。如果你问自己什么是嵌套数据——简而言之:BigQuery 支持从支持基于对象的模式的源格式(例如 JSON)加载和查询嵌套和循环数据。这些列可以保持关系,而不会像关系模式或规范化模式那样降低性能[3]。
嵌套和重复数据的图示-按作者分类的图像
地址列包含一个值数组。数组中的不同地址是重复出现的数据。每个地址中的不同字段是嵌套数据。点击了解更多信息。因此,在上面显示的关于客户和销售数据的示例中,将产生以下数据结构:
非规范化和嵌套数据-按作者分类的图像
摘要
为了在 BigQuery 中构建尽可能高效和高性能的数据结构,数据工程师应该研究技术背景,实现反规范化和嵌套数据这两个核心概念。在我看来,关键不在于技术知识,而在于业务流程知识。在这里,你必须和企业一起发明有意义的数据模型。一旦实现了这一点,在进一步的过程中,例如在报告或分析中,需要的工作就会少得多,并且查询可能也会更快。使查询更有效的另一种可能性是像分区和聚类这样的技术。这些也是从经典数据库中得知的。在这里,我推荐来自 Google 的好的文档【4】。
资料来源和进一步阅读
[1]谷歌,,BigQuery (2021)
[2]伊奥诺斯,NoSQL-NoSQL-达滕班肯 (2019)
[3] Google,指定嵌套和重复的列 (2021)
[4]谷歌,聚簇表介绍 (2021)
如何为数据科学构建高影响力的图表
原文:https://towardsdatascience.com/how-to-build-high-impact-graphs-for-data-science-55ce19d1ab32?source=collection_archive---------44-----------------------
数据科学讨论
提高数据可视化技能的一些技巧。
图片由皮克斯拜的 Gerd Altmann 提供
无论是使用 D3.js 还是其他可视化工具,构建一个图表都是一项非常有趣的任务。你可以挑选,合并和组合你的数据,以获得非常令人印象深刻的图表。你甚至可以构建非常复杂的图表,概括百万个数据。然而,也许,你已经浪费了你的时间。
关键是你在图表中放了多少数据并不重要,重要的是它们有多有意义。
在开始画一个图形之前,你要问这个问题: 我的图形想传达什么? 而且,你画完之后,你应该再问一个问题: 我可以简化我的图形吗?哪些信息是不需要的,因此可以从我的图表中删除?
事实上,你的图表应该满足以下几点:
- 专注于某个特定的主题。不要试图说出图表中的所有内容。相反,你应该试着描述一个概念;如果有必要,建立一个以上的图表,解释更多的概念;
- 简单,这样你想描述的东西就一目了然了。一个简单的图形是清晰的,不需要人脑的进一步处理。把复杂的荣耀留给其他东西。
- 人人可读****,这样你的信息就能被各种各样的人理解。越多的人理解你的图表,你的图表的影响力就越大。
用一句话概括我到目前为止所说的话,我可以说:
用简单的方式描述一个概念,让每个人都能读懂。
在本文的剩余部分,我将尝试说明一些构建图表的好方法和坏方法。我关注三种类型的图表:
- 折线图
- 条形图
- 饼图。
折线图
折线图是用来表示某些数值随时间变化的趋势的经典图形。在 x 轴上,图表代表时间,在 y 轴上代表数值。
通常,折线图用于比较一段时间内的一些不同值。下图展示了一个糟糕的折线图示例,它试图比较五个不同国家的游客总数。
作者图片
这个图因为各种原因很不清晰。首先,使用的颜色重叠,因此很难区分它(意大利)和 ES(西班牙)。第二,几乎所有国家的趋势线都很相似,除了 FR(法国)和 UK(英国)直到 1996 年。因此,下面的问题出现了:图形想要传达什么?法国和其他国家的区别?英国到 1996 年的峰值?在第一种情况下,绘制法国趋势线并计算其他国家的平均值就足够了。在第二种情况下,只画出英国的趋势线就足够了。
接下来的图反而满足了所有三个标准:集中、简单和可读。
作者图片
条形图
条形图用于表示分类数据。以下示例显示了一个糟糕的条形图示例。
作者图片
在这张图表中,不同的颜色没有用,它们只会分散读者的注意力。此外,酒吧是没有排序的,因此读者必须处理数据,以提取最喜欢的电影。
在构建条形图时,尽量对所有的条形图使用单一颜色,并根据你想要传达的内容进行升序或降序排列。如果你有很多横杠,你可以用单杠。
以下示例通过仅使用一种颜色并按降序对值进行排序来转换上一个条形图:
作者图片
它立即变得清晰,不需要读者进行任何进一步的处理。
圆形分格统计图表
饼图用来表示某事物占总数的百分比。在绘制饼状图时,你应该想到八十年代著名的视频游戏【吃豆人】,在某种意义上,该图应该代表两个部分,最多三个部分。否则,图形变得不可读。
以下示例显示了一个糟糕的饼图:
图形想传达什么?白人的比例最高?在这种情况下,您可以简单地绘制白色和其他,以指示所有其他类别。无论如何,如果要表示的切片数大于 2 或 3,请使用另一种类型的图形。
下面的图表显示了以前的饼图的转变,它变成了一个非常集中、简单和可读的饼图。这个图现在看起来像(一个反)吃豆人。
作者图片
摘要
在这篇简短的教程中,我描述了一些构建高影响力图表的标准。每张图表都应该满足以下三个方面:重点突出、简单易读。
另外,在构建一个图之前,你要想好你的图的用途。你选择的图表类型能够代表你的想法吗?
如果你想了解我的研究和其他活动的最新情况,你可以在 Twitter 、 Youtube 和 Github 上关注我。
相关文章
我们能说数据科学家是数据记者吗?
几年前,我的老板让我帮他准备一门关于数据新闻的大学课程,当时我们正在上另一门关于网页设计的课程。为什么要从网页设计转向数据新闻?
起初,我对这个提议感到困惑,不知道我的老板在打什么主意,但最终,我意识到他是对的。
我开始问谷歌什么是数据新闻,事实上,我没有找到这么多。经过一番搜索,我想到了这个有趣的网站。我读了一些材料,我确信数据新闻与数据科学非常相似。但是我错了。
在这里继续阅读。
保持联系!
- 在媒体上跟随我
- 注册我的简讯
- 在 LinkedIn 上连接
- 在推特上关注我
- 跟着我上脸书
- 在 Github 上关注我
如何使用 SQL 建立机器学习模型
原文:https://towardsdatascience.com/how-to-build-ml-model-using-bigquery-eced0107e4fd?source=collection_archive---------40-----------------------
BigQuery 中的机器学习和预测建模
如何使用 BigQuery 建立 ML 模型 —图片作者
而踏入机器学习领域的第一步,又是那么容易被各种复杂的算法和丑陋的符号淹没。因此,希望这篇文章能够通过提供一个初学者友好的指南来降低入门门槛。让你通过使用 BigQuery 和 SQL 构建自己的 ML 模型获得成就感。没错,我们可以用 SQL 来实现机器学习。如果你正在寻找几行代码来染指 ML 领域,请继续阅读:)
1。建立基本结构📁
BigQuery 基本结构—作者图片
简单地说, BigQuery 项目包含数据集,数据集包含表和模型。
按照以下步骤,使用 Google 公共数据集建立一个项目——“Google 分析示例”。如果您熟悉这个过程,可以直接跳到本文的第二部分。
1)导航到 Google Cloud Platform 控制台左侧边栏中的 BigQuery,然后在 Google Cloud Platform 中创建一个项目,将其命名为您想要的任何名称(例如本例中的“project”)
创建项目-按作者分类的图像
2)在“SQL Workspace”面板中,选择您的项目,然后单击“Create Dataset”并为您的数据集命名(如 analytics)。
按作者创建数据集-图像
3)点击“添加数据”并选择“浏览公共数据集”。从公共数据集库中,搜索 google analytics 示例并将其添加到您的项目中。如果感兴趣,请阅读 Google Analytics 示例模式。
添加 Google Analytics 样本数据集-按作者分类的图片
4)通过导航到“bigquery-public-data”中的“ga_sessions_”来浏览数据集,并选择“Preview”选项卡。这是一个大规模数据集,具有多个列和按日期划分的子集集合(例如,下面的示例中的“2017–08–01”)。注意,数据集位于项目“bigquery-public-data”中,而不是我们自己的项目“project-303707”中,但是我们仍然可以从我们的项目中查询这个数据集,因为它是可公开访问的。
预览数据集-按作者分类的图像
2。你有什么问题🤨?
识别问题-作者图片
在开始构建模型之前,通过询问以下问题来澄清我们试图解决的问题:
1)什么是标签?
标签是要预测的变量。在这个例子中,我将预测网站访问者是否会进行任何交易,我将这个标签命名为“购买”。这可以从现有变量“totals.transactions”中导出。
2)标签值是如何定义的?
为简单起见,我们把这个预测做成非黑即白的情况,要么“购买”,要么“不购买”。由于模型训练不能将字符串值作为输出结果处理,因此有必要将它们编码为数字。
可以使用 SQL 中的 IF 语句定义该标准:
IF(totals.transactions > 0, 1, 0) as purchase
3)有哪些特征/预测因素?
预测值是选择用来预测标注的特征。对于这个简单的模型,选择、【总计.浏览量】、【设备. isMobile】、【总计.时间现场】作为预测器。让我们看看它们是否真的是估计购买机会的良好预测指标。
我们已经知道了什么?我们试图预测什么?
我们使用已知的数据来建立模型。在这个练习中,我从谷歌分析数据集中选择了一系列日期在 2017 年 1 月 1 日和 2017 年 7 月 1 日之间的子集。根据“totals.transactions”值,我们已经知道这些记录是否进行了购买。
我选择了 2017 年 7 月 1 日至 2017 年 8 月 1 日的子集作为预测集。尽管我们已经从数据中知道他们是否进行了任何交易。但是为了便于说明,让我们假设我们只知道预测器,并使用它们来预测标签。
我们应该选择什么类型的模型?
机器学习中有两大类问题:分类和回归。分类问题是预测分类数据(例如真/假、猫/狗),而回归问题是预测具有连续数量的数值数据(例如温度、收入等)。由于标签“购买”被设计为一个具有离散值(1 或 0)的类别,这是一个分类问题。逻辑回归、决策树、支持向量机是解决分类问题的常用模型。我选择逻辑回归,因为它最容易开始,而且它也受 BigQuery ML 支持。
3。建立模型📊
建立模型—作者的图像
在 BigQuery 中构建 ML 模型分为训练数据集和评估数据集。
训练数据集:用于创建模型的样本数据子集。
评估数据集:用于评估模型性能的样本数据子集。
在本例中,日期从“2017–01–01”到“2017–05–01”的数据子集用于训练,而“2017–05–01”到“2017–07–01”用于评估。
1)训练模型
CREATE OR REPLACE MODEL `analytics.my_model`
OPTIONS
(
model_type = "logistic_reg",
labels = ['purchase']
)
ASSELECT *
EXCEPT(fullvisitorid)
FROM
(SELECT fullvisitorid,
IFNULL(totals.pageviews, 0) AS page,
IFNULL(totals.timeonsite, 0) AS duration,
CASE
WHEN device.isMobile is True THEN 1
ELSE 0
END mobile
FROM `bigquery-public-data.google_analytics_sample.ga_sessions_*`
WHERE _TABLE_SUFFIX BETWEEN "20170101" AND "20170501"
)JOIN
(SELECT fullvisitorid,
IF(totals.transactions > 0, 1, 0) as purchase
FROM `bigquery-public-data.google_analytics_sample.ga_sessions_*`
) target
USING (fullvisitorid)
让我们将这段代码分成几个部分:
CREATE OR REPLACE MODEL `analytics.my_model`
OPTIONS
(
model_type = "logistic_reg",
labels = ['purchase']
)
AS
第一部分通过传递三个参数在“分析”数据集中创建模型“my_model ”:
- 带有数据集前缀的模型名称:analytics . my _ Model
- 模型类型:“logistic _ reg”代表 logistic 回归模型
- 标签:“购买”,这是我们预测的变量
如果您想学习如何使用 Python 构建逻辑回归模型,本文可能会有所帮助:
“AS”关键字之后的第二部分指定了训练数据集:
SELECT *
EXCEPT(fullvisitorid)
FROM
(SELECT fullvisitorid,
IFNULL(totals.pageviews, 0) AS page,
IFNULL(totals.timeonsite, 0) AS duration,
CASE
WHEN device.isMobile is True THEN 1
ELSE 0
END mobile
FROM `bigquery-public-data.google_analytics_sample.ga_sessions_*`
WHERE _TABLE_SUFFIX BETWEEN "20170101" AND "20170501"
)JOIN
(SELECT fullvisitorid,
IF(totals.transactions > 0, 1, 0) as purchase
FROM `bigquery-public-data.google_analytics_sample.ga_sessions_*`
) target
USING (fullvisitorid)
我们在这里将两个表连接在一起,第一个表选择在此场景中用作预测器的所有特征:
- "totals.pageviews": 表示会话内的页面浏览量,然后应用 IFNULL 函数将空值替换为 0
- "totals.timeonsite": 表示在会话中花费的时间,然后应用 IFNULL 函数将空值替换为 0
- "device.isMobile": 表示访问者是否使用移动设备,然后应用 CASE 函数将布尔值(真或假)转换为数值(1 或 0)
关键字“_TABLE_SUFFIX”用于过滤数据集,以便只包括“ga_session”的训练子集(2017–01–01”到“2017–05–01”)。
然后,我们将包含预测值的第一个表与包含每个访问者的“购买”标签的第二个表连接起来,该标签由语句IF(totals.transactions > 0, 1, 0).
定义
然后我们使用语句SELECT * EXCEPT(fullvisitorid) FROM …
将 fullvisitorid 从连接表中排除,因为 id 对购买预测没有贡献。
在 query composer 面板中运行训练语句后,我们将能够看到“my_model”出现在“analytics”数据集中。
模型细节-作者提供的图片
2)评估模型
SELECT
roc_auc
FROM ML.EVALUATE(MODEL analytics.my_model,
(
SELECT *
EXCEPT(fullvisitorid)
FROM
(SELECT fullvisitorid,
IFNULL(totals.pageviews, 0) AS page,
IFNULL(totals.timeonsite, 0) AS duration,
CASE
WHEN device.isMobile is True THEN 1
ELSE 0
END mobile
FROM `bigquery-public-data.google_analytics_sample.ga_sessions_*`
WHERE _TABLE_SUFFIX BETWEEN "20170501" AND "20170701"
)
JOIN
(SELECT fullvisitorid,
IF(totals.transactions > 0, 1, 0) as purchase
FROM `bigquery-public-data.google_analytics_sample.ga_sessions_*`
) target
USING (fullvisitorid)
));
这可以分为两层。
-- outer layer
SELECT roc_auc
FROM ML.EVALUATE(...)
外层是从 ML 返回的结果中选择度量。评估子句。在这种情况下,只选择了“roc_auc ”,但我们也可以使用“SELECT *”来获得其他常用的度量来评估分类模型,如精度、召回率、准确度、f1_score 和 log_loss。
-- inner layer
MODEL analytics.my_model,
(
SELECT *
EXCEPT(fullvisitorid)
FROM
(SELECT fullvisitorid,
IFNULL(totals.pageviews, 0) AS page,
IFNULL(totals.timeonsite, 0) AS duration,
CASE
WHEN device.isMobile is True THEN 1
ELSE 0
END mobile
FROM `bigquery-public-data.google_analytics_sample.ga_sessions_*`
WHERE _TABLE_SUFFIX BETWEEN "20170501" AND "20170701"
)
JOIN
(SELECT fullvisitorid,
IF(totals.transactions > 0, 1, 0) as purchase
FROM `bigquery-public-data.google_analytics_sample.ga_sessions_*`
) target
USING (fullvisitorid)
)
内层是传递模型“analytics.my_model”和评估数据集作为这个 EVALUATE 函数的参数。正如我们所看到的,评估数据集几乎与训练数据集的定义相同,只是 _TABLE_SUFFIX 已被更改为另一组介于“20170501”和“2017070”之间的数据范围。
评估结果—作者提供的图片
代码返回的 roc_auc 值为 0.75。以这个数值,只能说这是一款还过得去但还不够好的车型。有许多方法可以提高它的性能,例如,通过引入更多信息的特征作为预测因子来更深入地进行特征选择。我鼓励你想一想,还有哪些属性可能有助于“购买”的预测。尝试实施它并达到更高的 roc_auc 分数。可以把它看作是一个不断测试模型性能并对其进行改进的迭代过程,直到它达到一个最优值(例如 roc_auc > 0.9)。
如果你想到任何提高分数的方法,请在下面随意评论。
4。做预测📈
进行预测-按作者分类的图像
将下面的预测语句与训练或评估语句进行比较,有一个明显的区别,即只选择了预测符(页面、持续时间和移动)。这是因为标签将是查询输出而不是输入。
SELECT
*
FROM
ML.PREDICT(MODEL `analytics.my_model`,
(
SELECT fullvisitorid,
IFNULL(totals.pageviews, 0) AS page,
IFNULL(totals.timeonsite, 0) AS duration,
CASE
WHEN device.isMobile is True THEN 1
ELSE 0
END mobile
FROM `bigquery-public-data.google_analytics_sample.ga_sessions_*`
WHERE _TABLE_SUFFIX BETWEEN "20170701" AND "20170801"
)
);
对于 BigQuery 中的每个预测模型,预测标签将被命名为“预测 _ <label_column_name>”,例如预测 _ 购买。此外,我们正在选择一组新的数据“2017–07–01”到“2017–08–01”,这超出了用于训练和评估的原始数据集的范围。理想情况下,它是数据集,我们只有功能的信息,但我们不知道他们是否进行了任何购买。</label_column_name>
下面的结果显示了每个访问者的预测标签以及分别被标记为 1 或 0 的概率。
预测结果-作者提供的图片
带回家的信息🏠
本文简要介绍了如何在 BigQuery 中使用 SQL 构建一个简单的机器学习模型,包括四个主要步骤:
- 建立基本结构
- 清楚这个问题
- 建立模型(训练和评估模型)
- 做出预测
希望有助于缓解进入机器学习领域的摩擦。最重要的是,让我们一起学习,一起成长!
更多相关文章
https://medium.com/analytics-vidhya/top-15-websites-for-data-scientists-to-follow-in-2021-67352092c54d
原载于 2021 年 2 月 9 日 https://www.visual-design.nethttps://www.visual-design.net/post/how-to-build-ml-model-using-bigquery。
如何使用 Spotlight 构建强大的深度推荐系统?
原文:https://towardsdatascience.com/how-to-build-powerful-deep-recommender-systems-using-spotlight-ec11198c173c?source=collection_archive---------25-----------------------
利用深度学习构建电影推荐系统。
照片由 Unsplash 上的尼克·费因斯拍摄
在我的上一篇文章中,我展示了如何使用 Surprise 构建基于矩阵分解等技术的浅层推荐系统。
但是如果你想建立一个推荐系统,使用比简单的矩阵分解更复杂的技术呢?如果你想用深度学习来构建推荐系统呢?如果你想利用用户的观看历史来预测他们将要观看的下一部电影呢?
这就是使用 PyTorch 创建深度学习推荐系统的 Python 库 Spotlight 发挥作用的地方。Spotlight 的界面类似于 Surprise,但支持基于矩阵分解和顺序深度学习模型的推荐系统。
在本文中,我将展示如何使用 Spotlight 构建深度推荐系统,通过矩阵分解和序列模型进行电影推荐。
装置
官方文档页面提供了用 Conda 安装 Spotlight 的命令,但我建议使用以下命令直接从 Git 安装库,尤其是如果您有 Python 3.7。
git clone [https://github.com/maciejkula/spotlight.git](https://github.com/maciejkula/spotlight.git)
cd spotlight
python setup.py build
python setup.py install
构建电影推荐系统
在这个实际的例子中,我决定使用 Kaggle 上的电影数据集中的数据。该数据集包含来自 270,000 个用户的 45,000 部电影的 2,600 万个评级的文件。出于本例的目的,我使用了数据集中的 ratings_small 文件,该文件包含 700 个用户对 9000 部电影的 100,000 个评级的子集。完整的数据集需要更长的时间来训练,但如果您有一台配备强大 GPU 的机器,您可以尝试使用它。你可以在 GitHub 上找到这个实际例子的完整代码。
导入基本库
在下面的代码中,我简单地导入了我用于大多数数据科学项目的基本库。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
读取数据
在下面的代码中,我读取了三个不同的数据文件:
- ratings_small.csv —包含不同用户和电影的分级数据。
- movies_metadata.csv —包含数据集中所有 45,000 部电影的元数据。
- links.csv —包含在将该数据与电影元数据结合时可用于查找每部电影的 id。
ratings_data = pd.read_csv('./data/ratings_small.csv.zip')
metadata = pd.read_csv('./data/movies_metadata.csv.zip')
links_data = pd.read_csv('./data/links.csv')
使用 Pandas 中的信息功能为每个数据框获取的列如下所示。
收视率 _ 数据
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 100004 entries, 0 to 100003
Data columns (total 4 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 userId 100004 non-null int64
1 movieId 100004 non-null int64
2 rating 100004 non-null float64
3 timestamp 100004 non-null int64
dtypes: float64(1), int64(3)
memory usage: 3.1 MB
元数据
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 45466 entries, 0 to 45465
Data columns (total 24 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 adult 45466 non-null object
1 belongs_to_collection 4494 non-null object
2 budget 45466 non-null object
3 genres 45466 non-null object
4 homepage 7782 non-null object
5 id 45466 non-null object
6 imdb_id 45449 non-null object
7 original_language 45455 non-null object
8 original_title 45466 non-null object
9 overview 44512 non-null object
10 popularity 45461 non-null object
11 poster_path 45080 non-null object
12 production_companies 45463 non-null object
13 production_countries 45463 non-null object
14 release_date 45379 non-null object
15 revenue 45460 non-null float64
16 runtime 45203 non-null float64
17 spoken_languages 45460 non-null object
18 status 45379 non-null object
19 tagline 20412 non-null object
20 title 45460 non-null object
21 video 45460 non-null object
22 vote_average 45460 non-null float64
23 vote_count 45460 non-null float64
dtypes: float64(4), object(20)
memory usage: 8.3+ MB
链接 _ 数据
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 45843 entries, 0 to 45842
Data columns (total 3 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 movieId 45843 non-null int64
1 imdbId 45843 non-null int64
2 tmdbId 45624 non-null float64
dtypes: float64(1), int64(2)
memory usage: 1.0 MB
请注意以下映射和列关系:
- links_data 中的 movieId 列映射到 ratings_data 中的 movieId 列。
- links_data 中的 imdbId 列映射到元数据中的 imdb_id 列。
预处理元数据
在下一节中,我使用下面列出的步骤对数据进行了预处理。请参考我在 GitHub 上的 Jupyter 笔记本和 Kaggle 上的数据集描述,以获得澄清。
- 从元数据数据框中移除 imdb_id 为空的行。
- 通过应用 lambda 函数,将元数据中 imdb_id 列的每个元素转换为 int。
- 通过分别连接 imbd_id 和 imdbId 列上的数据帧来合并元数据和 links_data。
metadata = metadata[metadata['imdb_id'].notna()]def remove_characters(string):
return ''.join(filter(str.isdigit, string))metadata['imdb_id'] = metadata['imdb_id'].apply(lambda x: int(remove_characters(str(x))))full_metadata = pd.merge(metadata, links_data, left_on='imdb_id', right_on='imdbId')
运行上面的代码会生成一个数据帧,我们可以使用它来检索电影的元数据,只基于电影 ID。
创建 Spotlight 交互数据集
像 Surprise 一样,Spotlight 也有一个 dataset 对象,我们需要使用它来根据我们的数据训练模型。在下面的代码中,我通过提供以下参数创建了一个 Interactions 对象,所有这些参数都必须是 Numpy 数组:
- 用户标识 —评级数据中的用户标识
- item _ id—评分数据中的项目 id
- 评级 —评级数据中对应的评级。
- 时间戳(可选) —每个用户/项目交互的时间戳。
from spotlight.interactions import Interactionsdataset = Interactions(user_ids=ratings_data['userId'].values,
item_ids=ratings_data['movieId'].values,
ratings=ratings_data['rating'].values,
timestamps=ratings_data['timestamp'].values)
训练矩阵分解模型
现在已经创建了数据集,我们可以使用 Spotlight 的 ExplicitFactorizationModel 模块来训练基于深度学习的矩阵分解模型,如下所示。
from spotlight.cross_validation import random_train_test_split
from spotlight.evaluation import rmse_score
from spotlight.factorization.explicit import ExplicitFactorizationModeltrain, test = random_train_test_split(dataset)model = ExplicitFactorizationModel(n_iter=10)
model.fit(train, verbose=True)rmse = rmse_score(model, test)
print('RMSE = ', rmse)
运行上面的代码会产生以下输出,其中包含每个时期的损失值:
Epoch 0: loss 4.494929069874945
Epoch 1: loss 0.8425834600011973
Epoch 2: loss 0.5420750372064997
Epoch 3: loss 0.38652444562064103
Epoch 4: loss 0.30954678428190163
Epoch 5: loss 0.26690390673145314
Epoch 6: loss 0.24580617306721325
Epoch 7: loss 0.23303465699786075
Epoch 8: loss 0.2235499506040965
Epoch 9: loss 0.2163570392770579
RMSE = 1.1101374661355057
利用因子分解模型生成电影推荐
现在我们已经训练了一个矩阵分解模型,我们可以用它来生成电影推荐。predict 方法采用单个用户 ID 或一组用户 ID,并为数据集中的每个电影项目生成预测评级或“分数”。
model.predict(user_ids=1)
predict 方法的输出是一个值数组,每个值对应于数据集中某个项目(在本例中为电影)的预测评级或得分。
array([0.42891726, 2.2079964 , 1.6789076 , ..., 0.24747998, 0.36188596, 1.658421 ], dtype=float32)
我在下面创建了一些实用函数,用于将 predict 方法的输出转换为实际的电影推荐。
我们可以调用 recommend_movies 函数为具有特定 ID 的用户生成电影推荐,如下所示。
recommend_movies(1, full_metadata, model)
调用此函数会产生以下输出,其中包含一个字典列表,其中包含每部推荐电影的元数据。
[[{'original_title': '2001: A Space Odyssey',
'release_date': '1968-04-10',
'genres': "[{'id': 878, 'name': 'Science Fiction'}, {'id': 9648, 'name': 'Mystery'}, {'id': 12, 'name': 'Adventure'}]"}],
[{'original_title': 'Rocky',
'release_date': '1976-11-21',
'genres': "[{'id': 18, 'name': 'Drama'}]"}],
[{'original_title': "The Young Poisoner's Handbook",
'release_date': '1995-01-20',
'genres': "[{'id': 35, 'name': 'Comedy'}, {'id': 80, 'name': 'Crime'}, {'id': 18, 'name': 'Drama'}]"}],
[{'original_title': 'Thinner',
'release_date': '1996-10-25',
'genres': "[{'id': 27, 'name': 'Horror'}, {'id': 53, 'name': 'Thriller'}]"}],
[{'original_title': 'Groundhog Day',
'release_date': '1993-02-11',
'genres': "[{'id': 10749, 'name': 'Romance'}, {'id': 14, 'name': 'Fantasy'}, {'id': 18, 'name': 'Drama'}, {'id': 35, 'name': 'Comedy'}]"}]]
训练序列模型
我们可以采用不同的方法,通过使用顺序深度学习模型来构建推荐系统。序列模型不是学习矩阵分解,而是学习使用一系列用户-项目交互来预测用户将与之交互的下一个项目。在这个例子的上下文中,顺序模型将学习使用每个用户的观看/评级历史来预测他们将观看的下一部电影。
ImplicitSequenceModel 允许我们通过深度学习来训练序列模型,如下所示。注意,我必须使用 to_sequence 方法将训练和测试数据集转换成序列数据集。
from spotlight.sequence.implicit import ImplicitSequenceModel
from spotlight.cross_validation import user_based_train_test_splittrain, test = user_based_train_test_split(dataset)train = train.to_sequence()
test = test.to_sequence()model = ImplicitSequenceModel(n_iter=10,
representation='cnn',
loss='bpr')model.fit(train)
我们可以使用平均倒数等级(MRR) 度量在测试数据上评估这个模型。倒数排名度量获取项目的排名,并输出正确项目的排名的倒数。例如,假设我们的推荐系统为用户产生以下电影排名:
- 蝙蝠侠前传
- 蜘蛛侠
- 超人
让我们假设用户实际上决定接下来观看蜘蛛侠。在这种情况下,蜘蛛侠在上面的列表中排名第二,这意味着倒数排名是 1/2。MRR 对测试集中所有预测的倒数排名进行平均。我们可以使用 sequence_mrr_score 函数计算 Spotlight 中模型的 MRR,如下所示。
from spotlight.evaluation import sequence_mrr_scoresequence_mrr_score(model, test)
结果是测试集中每部电影的 MRR 分数列表。
[0.00100402 0.00277778 0.00194932 ... 0.00110619 0.0005305 0.00471698]
用序列模型生成电影推荐
序列模型也有一个 predict 方法,它允许我们生成预测,但是这个方法不是使用用户 ID,而是接受一个项目序列,并预测一般用户可能选择的下一个项目。
model.predict(sequences=np.array([1, 2, 3, 4, 5]))
运行上面的函数会产生一个 Numpy 数组,其中包含测试集中每部电影的分数。较高的分数对应于用户接下来观看的较高概率。
array([ 0\. , 16.237215, 11.529311, ..., -2.713985, -2.403066,
-3.747315], dtype=float32)
和前面的矩阵分解模型的例子一样,我在下面创建了更多的效用函数,从序列模型生成的预测中生成电影推荐。
推荐 _ 下一部 _ 电影功能使用电影名称列表来推荐用户接下来可能观看的热门电影。 n_movies 参数指定要返回的电影数量。考虑下面的示例代码。
movies = ['Shallow Grave', 'Twilight', 'Star Wars', 'Harry Potter']
recommend_next_movies(movies, full_metadata, model, n_movies=5)
序列模型为已经观看了《浅坟》、《暮光之城》、《星球大战》和《哈利·波特》的用户产生以下电影推荐:
[[{'original_title': 'Azúcar amarga',
'release_date': '1996-02-10',
'genres': "[{'id': 18, 'name': 'Drama'}, {'id': 10749, 'name': 'Romance'}]"}],
[{'original_title': 'The American President',
'release_date': '1995-11-17',
'genres': "[{'id': 35, 'name': 'Comedy'}, {'id': 18, 'name': 'Drama'}, {'id': 10749, 'name': 'Romance'}]"}],
[{'original_title': 'Jaws 2',
'release_date': '1978-06-16',
'genres': "[{'id': 27, 'name': 'Horror'}, {'id': 53, 'name': 'Thriller'}]"}],
[{'original_title': 'Robin Hood',
'release_date': '1973-11-08',
'genres': "[{'id': 16, 'name': 'Animation'}, {'id': 10751, 'name': 'Family'}]"}],
[{'original_title': 'Touch of Evil',
'release_date': '1958-04-23',
'genres': "[{'id': 18, 'name': 'Drama'}, {'id': 53, 'name': 'Thriller'}, {'id': 80, 'name': 'Crime'}]"}]]
从这个例子可以看出,Spotlight 中提供的序列模型非常强大,可以为训练数据集中不存在的用户生成推荐。Spotlight 最棒的一点是,它使构建这些强大的深度推荐系统变得非常容易,而不必通过实现自己的神经网络来重新发明轮子。
摘要
Spotlight 是一个易于使用且功能强大的库,用于使用深度学习构建推荐系统。它支持推荐系统的矩阵分解和序列模型,这使得它非常适合于构建简单和更复杂的推荐系统。
和往常一样,你可以在 GitHub 上找到这篇文章的代码。如果你喜欢这篇文章,请随意查看下面我以前写的一些关于深度学习的文章。
加入我的邮件列表
你想在数据科学和机器学习方面变得更好吗?您想了解数据科学和机器学习社区的最新图书馆、开发和研究吗?
加入我的邮件列表,获取我的数据科学内容的更新。当你注册的时候,你还会得到我免费的解决机器学习问题的逐步指南!
来源
- 名词(noun 的缩写)拥抱,惊喜:推荐系统的 Python 库,(2020),开源软件杂志。
- R.Banik,电影数据集,(2017),Kaggle。
- 米(meter 的缩写))库拉,聚光灯,(2017),GitHub。
如何构建 Scikit-像专家一样学习管道
原文:https://towardsdatascience.com/how-to-build-scikit-learn-pipelines-like-a-pro-107c1ffec225?source=collection_archive---------17-----------------------
通过一个迷你项目,学习构建预处理、建模以及网格搜索管道的简单方法
马克老板在 Unsplash 上拍照
每次为项目选择数据集时,您的任务都是清理和预处理数据、处理缺失数据和异常值、建模,甚至执行超参数搜索以找到用于评估的最佳超参数集。
显然,在代码中用管道可以方便快捷地做到这一点。
在本文中,我们将浏览一个相当流行的 Kaggle 数据集,执行所有这些步骤,并构建一个真正的 sklearn 管道来学习。
我们开始吧👇
探索数据集
我们将在这个迷你项目中使用的数据集将来自 Kaggle — 心力衰竭检测表格数据集,可在 Creative Common 的许可下获得。从下面的 Kaggle 链接获取:
https://www.kaggle.com/andrewmvd/heart-failure-clinical-data
我们导入一下,看看是什么样子的!
按作者分类的图像-数据预览
下一步是将数据集分成训练集和测试集。除了最后一列是“死亡事件”之外,我们有所有用于训练的特征。查看最后一列,我们可以看到这是一个二进制分类任务。
列车测试分离
The shape of the data:Output:((209, 12), (90, 12), (209,), (90,))
最后,我们探索数据集的所有数字列:
X_train.describe().T
按作者分类的图像-描述数据集
查看分类数据,我们确认没有:
# there are no categorical featurescategorical_features = X_train.select_dtypes(exclude='number').columns.tolist()categorical_features
作者提供的图片-无猫特征
现在,我们可以继续建设我们的管道了!
我们的 Scikit-learn 管道
预处理流水线
首先,我们构建预处理管道。它将由两个组件组成——1)一个用于将数据转换到(0,1)之间的**MinMaxScalar**
实例,以及 2)一个用于使用列中现有值的平均值填充缺失值的**SimpleImputer**
实例。
col_transformation_pipeline = Pipeline(steps=[ ('impute', SimpleImputer(strategy='mean')), ('scale', MinMaxScaler())])
我们用一个**ColumnTransformer**
把它们放在一起。
A **ColumnTransformer**
可以接受由我们需要应用于数据的不同列转换组成的元组。对于每个转换,它还需要一个列列表。因为这里只有数字列,所以我们将所有的列都提供给列转换器对象。
那么让我们把它们放在一起:
厉害!我们管道的第一部分完成了!
让我们现在去建立我们的模型。
模型管道
我们为此任务选择了一个随机的森林分类器。让我们旋转一个快速分类器对象:
# random forest classifierrf_classifier = RandomForestClassifier(n_estimators = 11, criterion='entropy', random_state=0)
而且,我们可以将预处理和模型结合在一个管道中:
rf_model_pipeline = Pipeline(steps=[ ('preprocessing', columns_transformer), ('rf_model', rf_classifier),])
现在,拟合我们的训练数据非常简单:
rf_model_pipeline.fit(X_train, y_train)
最后,我们可以预测我们的测试集,并计算我们的准确度分数:
# predict on test sety_pred = rf_model_pipeline.predict(X_test)
综合起来看:
这一切都很好。但是,如果我说您也可以使用这个管道执行网格搜索来查找最佳超参数,那会怎么样呢?那不是很酷吗?
接下来让我们来探索一下!
在我们的管道中使用 GridSearch
我们已经建立并使用我们的模型来预测我们的数据集。我们现在将关注于为我们的随机森林模型寻找最佳超参数。
让我们首先建立我们的参数网格:
params_dict = {'rf_model__n_estimators' : np.arange(5, 100, 1), 'rf_model__criterion': ['gini', 'entropy'], 'rf_model__max_depth': np.arange(10, 200, 5)}
在这种情况下,我们着重于调整模型的三个参数:
- n_estimators :随机森林中的树木数量,
2.标准:测量分割质量的功能,以及
3.最大深度:树的最大深度
这里需要注意的一件重要事情是:在我们的网格中,我们不是简单地使用**n_estimators**
作为参数名,而是使用:**rf_model__n_estimators**
。这里的**rf_model__**
前缀来自我们为管道中的随机森林模型选择的名称。(参考上一节)。
接下来,我们简单地使用 GridSearch 模块来训练我们的分类器:
grid_search = GridSearchCV(rf_model_pipeline, params_dict, cv=10, n_jobs=-1)grid_search.fit(X_train, y_train)
让我们把所有这些放在一起:
现在,用我们的**grid_search**
物体来预测很容易,就像这样:
按作者分类的图像—准确度分数
厉害!我们现在已经为我们的项目建立了一个完整的管道!
几句临别赠言…
所以,你有它!由预处理器、模型和网格搜索组成的完整 sklearn 管道都在 Kaggle 的一个迷你项目上进行实验。我希望你会发现这篇教程很有启发性,并且很容易理解。
是时候表扬一下自己了!😀
在这里找到本教程的完整代码。这是我所有数据科学文章的代码库。如果你愿意的话,请给它标上星号和书签!
将来,我会回来写更多基于 Scikit-learn 的文章。所以跟着我在媒体上,并留在循环!
我还建议成为一名中等会员,不要错过我每周发表的任何数据科学文章。在此加入👇
https://ipom.medium.com/membership
接通电话!
关注我 推特 。 查看我所有数据科学帖子的完整代码库!
我的其他几篇文章你可能会感兴趣:
</31-datasets-for-your-next-data-science-project-6ef9a6f8cac6>
如何使用 Power BI 构建完美的仪表盘
原文:https://towardsdatascience.com/how-to-build-the-perfect-dashboard-with-power-bi-28c35d6cd785?source=collection_archive---------6-----------------------
在 Power BI 中构建杀手级仪表板的技巧
活动创建者的照片 @campaign_creators 在 Unsplash
正如 Bernard Marr 在他为《福布斯》撰写的精彩文章 t 中所引用的那样,我们正遭受着数据过载的困扰。数据以多种不同的格式随处可见,迫切需要将这些数据转换为信息。信息是决策的关键因素,因为它是数据中最有价值的部分。
信息的概念是客观的、可读的、易于理解的,我将在本文中介绍一些技巧,以提取数据的最佳部分,并将其转化为 PowerBI 仪表板中的有用信息。
作者图片:数据 vs 信息
在 Power BI 等数据可视化工具中,处理后的数据显示在报告或仪表板中。一个好的报告或小组的发展需要考虑许多领域,如编程、设计、UI/UX、神经科学、语言等等。为了保证信息的有效性,与用户建立联系是必不可少的,因此有了叙事的概念。
如果您是第一次接触 PowerBI,或者您没有这方面的经验,我建议您阅读下面这篇文章,它详细解释了什么是 PowerBI 以及如何启动它:
[## power bi——击败 Excel 的工具
towardsdatascience.com](/powerbi-the-tool-that-is-beating-excel-8e88d2084213)
讲故事
人类天生就有讲故事的能力,我们从小就一直在讲故事。讲故事是一种工具,用来与读者建立联系,并尽可能有效地传递信息。
为了创作好的故事,我们必须保证一些基本因素,例如:
- 视觉化中的美和设计模式——人类非常沉迷于模式和完美的形状。如果你使用一些设计模式的概念,如黄金比例和一些颜色模式,它会突然提高你的仪表板的美感。
- 简洁 —有时少即是多,限制仪表盘中的图表数量,只展示最重要的图表,不要使用复杂的壁纸,白色背景可能是实现简洁的良好开端。
- 易于阅读和理解——“完美的图形是不需要进一步解释的图形”。对于每个关键用户来说,一个图表在第一眼看上去必须非常清晰易懂。如果你不得不花时间解释这个图表,那么它很有可能不是一个好的图表。
- 与目标受众使用相同的语言 —有时你在大学里向一群学生展示仪表板,有时你在为一家国际公司的首席执行官开发仪表板,他们使用的语言完全不同。因此,关注你的目标受众,并根据每个场景调整你的方法是非常重要的。
- 数据可靠性 —仪表板中呈现的数据必须可靠。数据质量部分对每个面板都非常重要,检查每个数字、KPI、过滤器交互、随时间变化的图表,并尝试将数字与公司内的其他来源进行比较。一个错误的数字可能会导致决策过程中的巨大错误,并使您的仪表板失去信誉。
随着时间的推移和大量的研究,我们获得了以越来越自然的方式生成仪表板的经验,并有了良好的故事发展。
剩下的问题是,我怎样才能学会用更少的经验来构建一个好的仪表板并实现好的故事讲述呢?我如何在不花大量时间阅读内容的情况下发展我的数据可视化技能?
为了回答这些问题,我将给出几个小技巧,帮助你为各种场合打造完美的仪表盘。
如何选择你的图表
知道哪种类型的图表最适合每种洞察力是非常重要的。一个错误的选择会增加分析和理解洞察力的难度。图形可视化旨在以最简单、最直观的方式展示数据。
"完美的图是不需要进一步解释的图."
Andrew Abela 博士发表了一个很好的图表,帮助我们决定哪个图表更适合每个场景。点击以下链接查看完整图表:
https://apandre.wordpress.com/dataviews/choiceofchart/
Andrew Abela 博士指出:
- 比较数据如果我们想比较不同项目之间的数据,我们应该使用条形图
作者图片
或者使用折线图来比较一段时间内的数值
作者图片
- 为了显示数值之间的关系,我们应该使用两个变量的散点图和三个变量的不同点大小的散点图。
作者图片
- 为了分析数据分布,我们应该主要使用单个变量的直方图或两个变量的散点图。
作者图片
- 为了理解数据的组成,如果变量随时间变化,我们应该使用条形图或面积图
作者图片
或者如果变量是静态的,则是比萨饼图或瀑布图。
作者图片
调色板
在你的显示屏上,颜色也是至关重要的。糟糕的颜色选择会使你的仪表板难以阅读,或者在视觉上没有吸引力。避免在仪表盘中使用太多颜色,如果你要像 PowerPoint 演示一样从远处观看,选择对比度高的颜色以提高可视性,从远处和近处观看你的仪表盘,向其他人展示你的仪表盘,并查看她的反馈,想想你的观众中是否有色盲者。下面是如何使用色轮组合的基本说明。
互补色—作者图片
相似的颜色-作者图片
三角形—作者提供的图像
方形/矩形—作者提供的图像
Power BI 有几个带有预定义调色板的主题,但你也可以在互联网上找到一些,总之我在下面的链接中留下了一些不错的主题:
https://colorhunt.co/
米卡·鲍梅斯特在 Unsplash 的照片
如何展示你的见解
洞察力可以分为 3 个不同的组:业务可见性、绩效改进和机会发现。
这 3 种不同类型的见解有不同的观点,并针对每种情况进行了优化,以便更好地理解,我将在下面对它们进行更好的解释:
1.业务可见性
呈现业务可见性类型洞察力的最常见方式是通过报告。
报告是一次性报告,旨在显示有关业务的特定问题的答案。报告通常通过电子邮件共享或用 PowerPoint 演示。
报告是一个模板,旨在提供对业务中一段时间以来发生的事实的简单度量的洞察。一个更简单的视图,其中除了图表中显示的内容之外,它没有提出其他见解。
作者图片
2.性能改进
通常与绩效改进洞察相关的工具是记分卡。
在绩效改进类型洞察中,图表已经更加详细,包含一些指标,显示为目标受众带来价值的数据,如目标、平均值、总计、最大值和最小值,以便团队以更实际的方式提取最大值。这种图表使用大量 KPI(指标)、计算值和统计数据。
按作者分类的图像—报告+记分卡
3.机会发现
通常与 Opportunity Discovery insight 相关联的设备是仪表板。
仪表板是以复杂但易于最终用户理解的方式以多种方式呈现的数据。仪表板显示已经处理的数据,包括各种 KPI、相关性、预测、数据随时间的演变、指标等。通常,这种类型的可视化经常被分析师、经理、投资者、协调员以及需要大量数据来做出决策的人使用。
按作者分类的图像—仪表板
一般查看提示
构建完美仪表板或报表的一些通用可视化技巧。
- 移除边框 —尝试以自然的方式呈现您的图形,使其适合您报告的背景,并与其他图形形成互动,不要用边框删除它。
- 拥抱留白——避免在你的仪表盘上留下太多杂乱的东西,通常一点留白有利于整体的和谐。
- 收缩文本 —尝试以标题或题目的形式将文本包裹在图形中。把几段话剪成简短易懂的句子。“一图胜千言,一图胜千图”
示范
最后,我演示了如何应用本文中给出的技巧来转换报表。
上述报告提供了巴西圣保罗市的啤酒消费信息。下面的第一份报告是一份很长的文本,有几个关于消费的图表和指标。颜色是标准的,文字太大,图形不在标准空间,很多数据难以理解。不管怎么说,要理解报告要经历的每一件事,都需要很多时间。
原始仪表板—按作者分类的图像
使用这些提示后,我们可以看到图形有了显著的改进。颜色更好,更个性化,对比度更好,重要数据突出显示且更大,数据位于标准化位置,文本大大减少,但没有丢失最重要的信息,最终我们可以更容易、更简洁地理解见解。
新仪表板—按作者分类的图像
非常感谢您的阅读!我希望这些技巧可以帮助您开发仪表板,并帮助您在数据世界中了解知识。
有任何问题或建议可以通过 LinkedIn 联系我:https://www.linkedin.com/in/octavio-b-santiago/
如何为 Azure 数据工厂构建单元测试
原文:https://towardsdatascience.com/how-to-build-unit-tests-for-azure-data-factory-3aa11b36c7af?source=collection_archive---------5-----------------------
利用 Azure DevOps 和 pytest 进行数据工厂单元测试
0.介绍
TLTR:使用 azure-pipelines.yml 创建 Azure devo PSgit project,创建构建工件,部署 ADFv2 和 SQLDB bacpac,触发 pytest 做单元测试
单元测试是一种软件工程实践,侧重于测试代码的各个部分。在单元测试中,以下最佳实践是适用的:
- 快。运行单元测试应该只需要很少的时间。毫秒。
- 孤立的。单元测试是独立的,可以单独运行
- 可重复。运行单元测试应该总是返回相同的结果
- 自检。自动检测测试是通过还是失败
- 及时。没有不成比例的长时间编写单元测试代码
在 Azure Data Factory (ADFv2)中创建单元测试可能是一个挑战,因为总是存在对外部数据源的依赖。此外,ADFv2 需要首先部署到 Azure,管道只能作为一个整体进行测试。为了(部分地)克服这些挑战并遵循上面的最佳实践,ADFv2 单元测试项目被创建如下:
- 设置 Azure DevOps CI/CD 项目以使测试可重复
- 创建包含所有脚本的构建工件,并在发布管道中部署 ADFv2 ARM 模板、SQLDB bacpac 和 csv 文件。通过使数据源成为发布管道的一部分,外部依赖性受到限制,并且更加孤立
- 使用 SQLDB 运行两条 ADFv2 管道,使用 pytest 运行 ADLSGen2,并将测试结果传播到 Azure DevOps 中的 test 选项卡。这样,就有了测试结果的自检
通常,ADFv2 项目包含多个管道。使用 pytest-xdist 可以并行运行管道测试的单元测试。通过这种方式,测试可以更快(虽然永远无法实现毫秒级,但总测试时间大约等于最长运行的 ADFv2 管道)。使用具有 pytest、pyodbc 和 azure-blob-storage 的现有代码库,可以及时创建新的测试。另见下图。
ADfv2 单元测试—概述,作者图片
在这篇博文的剩余部分,将会更详细地解释这个项目。在下一章中,项目将被部署。
1.设置 Azure DevOps CI/CD 项目
在这一章中,项目开始运行,并将创建 ADFv2 单元测试项目。在这方面,需要做以下工作:
- 1.1 先决条件
- 1.2 创建 Azure DevOps 项目
- 1.3 创建服务连接
- 1.4 配置和建造/发布 YAML 管道
1.1 先决条件
本教程需要以下资源:
- Azure 账户
- 蔚蓝 DevOps
- Azure CLI (推荐,也用于故障排除)
随后,转到 Azure 门户并创建一个资源组,所有 Azure 资源都将部署在该资源组中。这也可以使用以下 Azure CLI 命令来完成:
az group create -n <<your resource group>> -l <<your location>>
1.2 创建 Azure DevOps 项目
Azure DevOps 是一个工具,可以持续地构建、测试和部署你的代码到任何平台和云。通过以下教程在 Azure DevOps 中创建新项目。创建新项目后,单击存储库文件夹并选择导入以下存储库:
- https://github.com/rebremer/blog-adfv2unittest-git
也见下图。
1.2 将存储库添加到您的 Azure DevOps 项目中,图片由作者提供
1.3 创建服务连接
从 Azure DevOps 访问资源组中的资源需要服务连接。转到项目设置,服务连接,然后选择 Azure 资源管理器,另见下图。
1.3.1 创建服务连接,由作者创建图像
选择服务主体身份验证,并将范围限制到您之前创建的资源组,另请参见下图。
1.3.2 按作者将范围限制到资源组、图像
默认情况下,服务连接的服务主体(SPN)拥有资源组的参与者权限。但是,对于此管道,SPN 需要资源组的所有者权限(或贡献者旁边的附加用户访问管理员权限),因为 ADFv2 MI 需要获得 ADLSgen2 帐户的 RBAC 权限。在 Azure DevOps 中点击你的服务连接上的“管理服务主体”时,可以找到应用 id。使用以下 Azure CLI 脚本向 SPN 分配所有者权限(也可以在门户中完成):
# get your subscription id
az account list
# create role
az role assignment create --assignee "<<application id>>" --role "Owner" --scope "/subscriptions/<<your subscription Id>> /resourcegroups/<<resource group name>>"
最后,验证 SPN 是否在 Azure 门户中或使用下面的 CLI 命令为您的资源组分配了所有者角色。
az role assignment list --resource-group <<resource group name>>
1.4 配置和建造/发布 YAML 管道
转到您的 Azure DevOps 项目,选择管道,然后单击“新建管道”。转到向导,选择您之前创建的 Azure Repos Git 和 git repo。在“配置”选项卡中,选择“现有 Azure Pipelines YAML 文件”,然后选择可以在 git repo 中找到的 azure-pipelines.yml,另请参见下文。
1.4.1 在管道配置向导中,选择现有的 Azure 管道 YAML 文件,按作者排序的图像
随后,需要用您自己的值替换以下变量:
variables:
#
# 1\. Azure DevOps settings, change with your own
AzureServiceConnectionId: '<<your service connection Id>> '
SUBSCRIPTIONID: '<<your subscription Id>> '
一旦变量被替换,管道就被创建并立即运行,见下文。
1.4.2 Azure DevOps 部署现代数据管道,图片由作者提供
作业运行后,部署所有资源并执行测试。在下一章中,对结果进行了验证。
2.验证测试结果
在 Azure DevOps 管道的第一步,部署 ADFv2、SQLDB 和 ADLSgen2。部署完成后,可以使用 Azure CLI 验证是否部署了所有资源。
az resource list -g <<your resource group>>
在 Azure DevOps 管道的第二步中,测试了两条 ADFv2 管道。可以在 ADFv2 monitor 选项卡中验证两个管道是否都已执行。在 pytest 结果中,可以验证测试是否成功。
2.1 测试结果,图片由作者提供
对两条管道执行以下测试:
ADF v2 _ data flows _ adlsgen 2 _ delete _ pii columns:
- 被 REST 触发后,管道返回 HTTP 200
- 检查管道中是否发生超时
- 检查 OrdersAggregated 表是否已创建,并且在注释列中不包含空值
ADF v2 _ data flows _ sqldb _ remove _ null values:
- 被 REST 触发后,管道返回 HTTP 200
- 检查管道中是否发生超时
- 检查是否可以在 ADLSgen2 的管理文件系统中找到文件 adultcensusincomepiiremoved . parquet
- 检查 PII 的敏感年龄栏是否被从拼花文件中删除
测试也可以在 data factory 的 monitor 选项卡中进行验证,如下所示。
2.2 数据工厂运行,按作者排列的图像
3.结论
单元测试是一种软件工程实践,侧重于测试代码的各个部分。速度、隔离、可重复性、自检和及时性是单元测试的最佳实践。在这篇博客中,描述了一个 ADFv2 单元测试项目,该项目利用 Azure DevOps、SQLDB bacpac 和 pytest 的功能,使测试更加隔离、可重复和自检。也见下图。
3.ADfv2 单元测试—概述,作者图片
如何建立您的数据分析团队
原文:https://towardsdatascience.com/how-to-build-up-your-data-analytics-team-6c6967ff5114?source=collection_archive---------26-----------------------
一个由数据工程师、分析师、科学家和产品负责人组成的团队会是什么样子,需要哪些能力?
以赛亚·鲁斯塔德在 Unsplash 上拍摄的照片
在这篇文章中,我想为建立自己的数据分析团队提供一个可能的蓝图和讨论基础。涵盖的主题将是角色和技能,资产和能力加上项目方法。
角色和技能
首先,要考虑你需要什么样的角色和技能。下图会给你一个概述。我区分了大多数团队或项目将具有的更基本的角色和不常见的或在更大的组织中出现的角色。
分析团队中的角色—按作者分类的图片
- 产品负责人/项目经理:根据在项目或产品中的工作,你需要一个项目经理或产品负责人,他是分析团队和利益相关者之间的中间人。
- 数据工程师:你的基本角色是一名数据工程师,一般来说,他负责与数据的生成、存储、维护、准备、丰富和传播相关的所有过程[1]。点击阅读更多关于数据工程师和数据科学家的区别。
- 数据/云架构师:数据和/或云架构师是数据架构的实践者,数据架构是一门数据管理学科,涉及设计、创建、部署和管理组织的数据架构——在较小的团队中,工程师可能会接管(部分)这些任务[1]。
- 数据分析师/Visualist :将数据转化为结构化的数据库,对其进行分析,并最终利用你的商业知识为公司的决策创建一个类似仪表板或报告的基础。
- 商业智能分析师:他们的任务是公司商业智能系统的构思、(进一步)开发、监测和控制。
- 业务分析师:业务分析师关心的是在一个执行业务的公司中识别结构和连贯性。
- 数据科学家:数据科学家能够使用创新的方法进行分析,并拥有丰富的学术背景。让他与众不同的是,他能够跳出纯数据分析的框框进行思考。
- 数据分析/科学架构师:这是一个混合了数据科学家和数据工程师的工作角色。类似于数据/云架构师,但更关心为 ML 和 DL 建立服务,而不是建立数据湖架构。
技术资产和能力
除了人力资产(团队成员的知识和技能),您还需要技术资产,如:
- 数据湖或数据仓库,以提供稳定的数据基础,例如谷歌的 BigQuery、亚马逊的 Redshift 或 Hadoop 等技术。
- 分析工具,如 Anaconda、alteryx 或大型云提供商提供的许多服务中的一种,用于执行统计和 ML 任务。
- MS Power BI、Google 的 Data Studio 或 Qlik 等商业智能工具可以快速分析数据并构建报告或仪表盘。
- 用于集成和清理数据的数据管道工具,例如通过 ETL/ELT 流程。工具例如是 talend 或 Boomi。
- 像 JupyterLab、R Studio 或 Spyder 这样的开发环境,可以用于 R、Python 和 SQL 这样的编程语言。
下面是一个在谷歌云平台中实现的数据分析架构的例子。
数据分析平台—来源 Trifacta [3]
作为一个组织,能够利用其 IT 资产和专业知识来创建数据分析功能是获得商业价值的关键。简而言之:你需要一个拥有聪明技能的数据科学家,并为他提供一套可靠的技术工具,以创建一个良好的机器学习模型。
敏捷方法
当在数据分析、工程和科学领域从事更复杂的项目和/或产品时,敏捷方法是必由之路。敏捷方法可以塑造工作流程,以帮助多学科团队优先考虑、计划和成功地增加业务价值。敏捷方法还可以帮助数据和分析团队从客户、利益相关者和最终用户那里获取反馈并采取行动。反馈应导致数据可视化的改进、机器学习模型的重新校准、数据质量的提高以及对数据治理的遵从。
如果这些敏捷方法被正确地应用,并且团队很好地适应它们,这反过来是一个重要的 IT 能力。如何做到这一点,以及例如像讲故事这样的方法将如何帮助你可以在这里阅读。
结论
希望这篇文章能给你一些启发和一些开始。第一步总是建立一个团队和工具集。持续发展对两者都适用。这意味着进一步培训员工,更新和扩大技术基础设施。我真的推荐使用敏捷过程来更快地部署已开发的系统,以最小化风险和不良开发。你可以在下面的资料和阅读材料中找到一些灵感和工具。
图片由 GIPHY 提供
资料来源和进一步阅读
[1] Ted Malaska,《构建数据解决方案的基础:管理成功的数据》(2018 年)
[2] BigData-Insider,是 ein 数据科学家 (2017)
[3] Trifacta, Trifacta 为谷歌云的本地数据准备服务 (2020 年)
如何建立您的数据分析团队
原文:https://towardsdatascience.com/how-to-build-your-data-analytics-team-1276d6729ac4?source=collection_archive---------4-----------------------
行业笔记
并将其与您的组织成功集成
图片来自 Castor 的网站
由Kat Holmes—ITV 数据总监进行同行评审
As 企业认识到数据对实现业务目标的决定性力量,大多数企业都希望将数据放在业务和产品战略的主导地位。这需要组建一个强大的数据团队,能够有效地将其见解传播到不同的业务领域。不幸的是,这并非易事。
要真正做到数据驱动,企业需要建立三种能力:数据战略、数据治理和数据分析。
数据驱动型公司的三大支柱——形象来自推介
策略:数据策略是组织使用数据实现目标的路线图。它要求对业务战略固有的数据需求有清晰的理解。你为什么收集数据?你是否在努力赚钱、省钱、管理风险、提供卓越的客户体验,以上都是?
治理:数据治理是流程、角色、策略、标准和指标的集合,可确保有效利用信息,帮助您的组织实现其目标。精心设计的数据治理策略可确保您公司的数据可信、准确且可用。
分析:数据分析这个术语指的是分析原始数据以得出关于它们所包含的信息的结论的过程。通常,组织中与数据分析相关的人员是数据工程师、数据分析师和数据科学家。
最终,您利用数据的能力将取决于这三大支柱。如果您正在阅读本文,并意识到您的组织不具备这些条件,请不要担心。这就是我们在这里的原因。一个好的起点是建立一个强大的分析团队,一个与你的业务战略目标紧密相关的团队。这是数据组织的第一个支柱,也是本文的重点。
在组建数据分析团队时,数据主管通常会遇到以下问题:
- 这个团队应该有多大?
- 有多少数据工程师、数据分析师、数据科学家?
- 团队如何与组织的其他部分互动?
- 数据团队的结构是什么?集中式还是嵌入式?
他们这样做是正确的;拥有一支强大的数据团队不再是奢侈品,而是当今公司生存的关键。
让我们从最基本的开始吧。
您处于数据之旅的哪个阶段?
在建立一个数据团队之前,重要的是你要意识到你在你的“数据之旅”中处于什么位置,因为这将直接影响你的团队结构。因此,本部分致力于简化数据成熟度评估。请注意,公司规模和数据成熟度是两回事。您的组织可能很大,但在数据层面上还不成熟。
数据成熟度是从您的数据资产中看到有形价值的旅程。我们提出了一个简单的数据成熟度评估框架,在这个框架中,您可以衡量自己了解过去、了解现在和预测未来的能力。我这么说是什么意思?
嗯,在大多数公司里,每个部门都有自己的一套 KPI 来支持公司战略的执行。仅仅定义它们是不够的,还必须清楚地跟踪它们,并且你还必须有能力根据这些 KPI 预测未来的结果。这种能力建立在对你现在的清楚了解上,而这反过来又建立在对过去的深刻理解上。这样做,您就找到了一种评估数据成熟度的简单方法。例如,如果您无法确定贵公司的收入驱动因素(您的过去),这意味着您需要在预测未来的结果之前,通过为您的业务带来可见性来提高您的数据成熟度。我们不建议跳过步骤。这就像马斯洛的需求层次理论,但是对于数据来说。
需求的数据层次 Louise de Leyritz 的图像
让我们看几个实际的例子:
营销投资回报率。通过使用确定的归因模型,跨多个渠道定义您的投资回报。然后了解其在过去 12 个月中的发展,尤其是其驱动因素(确定表演渠道、一年中的时间、产品等)。).然后借助你信任的报告工具,每天/每周/每月跟踪它的发展。根据这些预测模型预测你的营销预算。
顾客满意度。定义你的客户满意度。是 NPS 吗,CSAT?你公司的每个人都应该对它是如何计算的有一个共同的理解。与我们之前的例子一样,计算它在过去 12 个月中的演变,找到它的驱动因素(过去)。然后,使用可信的仪表板每天跟踪客户的满意度。确定从今天开始要采取的行动来增加它。你对客户满意度的过去和现在的理解将允许有效地预测客户流失(未来)
了解你的过去和现在通常被称为进行描述性分析。描述性分析通过提供上下文来帮助关键利益相关者解释信息,从而帮助组织了解其绩效。这种环境通常以数据可视化的形式出现,包括图形、仪表板、报告和图表。当你分析数据来预测未来时,你是在进行预测分析。预测分析的想法是获取历史数据,将其输入考虑关键模式的机器学习模型。将该模型应用于当前数据,并希望它能预测未来。我们将在整篇文章中使用描述性和预测性分析的术语来指代理解过去、现在或预测未来。
如果你意识到你的组织还没有完全成熟(即你对自己的过去和现在没有清晰的认识),这里是我们对你的数据团队下一步应该做什么的建议。
数据分析团队中的关键人物
数据分析团队通常由四个核心职能部门组成,具体如下。
- 数据工程师:他们负责设计、构建和维护可以在数据项目中使用的数据集。因此,数据工程师与数据科学家和数据分析师密切合作。我们在这里还包括分析工程师的新角色,尽管实际上,这个角色位于分析和工程之间。
- 数据科学家:他们使用高级数学和统计学,以及编程工具来建立预测模型。数据科学家和数据分析师的角色非常相似,但数据科学家更侧重于预测分析,而不是描述分析。
- 数据分析师:他们使用数据来执行报告和直接分析。数据科学家和工程师通常与原始或未经提炼的数据进行交互,而分析师则处理已经被清理并转换为更加用户友好的格式的数据。
- 业务分析师/运营分析师:他们帮助组织改进其流程和系统。他们专注于仪表板,回答业务问题并提出他们的解释。他们是敏捷的,跨越了 IT 和业务之间的界限,有助于弥合差距和提高效率。他们经常在特定的业务领域工作,如市场营销或财务,他们的 SQL 知识从基本的仪表板到高级分析。
- 数据分析主管:他们为数据团队提供战略监督。他们的目标是创建一个环境,允许所有各方轻松地访问他们需要的数据,建立从数据中提取有意义的见解的业务技能,并确保数据治理。他们还充当数据团队和主要业务部门之间的桥梁,同时充当远见者和技术领导者。
团队应该有多大?
不同的公司会建立不同规模的数据团队,没有一刀切。我们研究了 300 多家公司的数据团队结构,员工人数在 300-1000 人之间,并得出以下见解:
- 一般来说,你的目标应该是在你的公司中拥有总数为 5-10%的精通数据分析的员工。一些公司,如亚马逊或脸书,正在培训他们的大部分员工,但我们在分析中排除了他们。
- 全新数据团队的第一批雇员通常是数据工程师和数据分析师。有了这两个角色,组织已经可以从事一些基本的描述性分析。当建立一个更大的团队时,考虑你需要的技能。典型的数据项目需要以下技能:数据库、软件开发、机器学习、可视化、协作和沟通技能。很难找到拥有所有这些技能的人。因此,你应该意识到每个候选人都具备哪些技能。不管你决定雇佣多少人,你的团队都应该涵盖这些技能。您在数据之旅中所处的位置也会影响您雇佣的人员和所处的阶段。一般来说,数据分析师专注于了解过去。也就是说,他们利用你拥有的数据,试图理解增长的驱动因素和其他指标。业务分析师/obs 分析师面向现在(仪表板)。最后,数据科学家专注于预测未来的结果。因此,如果你对了解自己的过去有困难,那就先雇佣一名数据分析师,而不是数据科学家。
- 最终决定数据团队规模的应该是业务问题陈述的数量和最严重问题的复杂性。查看路线图的大小,确定在合理的时间内完成数据项目需要多少人。如果您意识到您的数据团队需要一年多的时间来完成项目,那么可能是时候扩大团队了。我们也鼓励你看看你的运行与构建比率。您的数据团队成员在处理日常业务运营时“跑步”,关注组织的当前绩效。他们在从事长期项目时“构建”,比如给产品添加新功能。您的数据团队应该用 2/3 的时间运行,用 1/3 的时间构建。如果你的数据团队把所有时间都花在日常需求上,你就在危及公司的未来,也许是时候扩大团队了。
- 最后,你可能需要做一些特定项目的招聘。如果你是一家从事欺诈检测项目的金融科技公司,或者是一家专门从事物流配送的公司,你可能希望雇佣了解你所在行业具体情况的人。
数据团队如何与公司融合?
分析团队没有完美的结构,你的结构可能会改变很多次。如果您的数据团队结构在过去两年中没有变化,那么它很可能是一个次优结构。为什么?因为您公司的数据需求正在快速发展,这要求您调整数据团队的结构。还要记住,你的组织越是静态,下一次变革就越难。出于这个原因,我们不规定一个给定的结构,而是提出最常见的模型,以及它们如何适用于不同类型的企业。
组建数据团队的第一步是找到组织中已经存在的数据人员。他们可能不仅仅是头衔中带有“数据”一词的人,也可能是任何不怕数据分析或已经掌握 SQL 技能的员工,比如业务分析师/运营分析师。如果您不花时间仔细寻找预先存在的数据人员,您很可能最终会有一个未计划的数据团队结构,不太可能满足您的业务需求。
集中式模型
数据团队的集中式模型—图片由 Louise de Leyritz 提供
集中式模型是实现起来最简单的结构,通常是以数据驱动为目标的公司的第一步。然而,这种模式也有一些缺点,下面会提到。这种结构通常会导致一个集中的数据“平台”,在这个平台上,数据团队可以访问所有的数据,并在各种项目中为整个组织提供服务。该团队中的所有数据工程师、分析师和科学家都由数据主管直接管理。在这种结构下,数据团队以顾问/客户的关系,以虚线向基于业务部门的数据利益相关者报告。
这种灵活的模式可以适应不断发展的业务需求。如果您正处于数据之旅的起点,也就是说,您仍在努力对自己的过去和现在有一个清晰的愿景,这是我们推荐的结构。数据团队的第一个项目将寻求带来业务的可见性,确保您组织中的所有部门都有他们可以信任的 KPI 和仪表板。这种结构特别适合重用性和数据治理非常重要的分析。
优势
✅数据团队可以在完成自己的工作的同时,帮助其他团队完成项目。
✅团队可以在整个公司范围内对项目进行优先级排序。
✅在一个集中化的团队中,人才和技能发展的机会更多。事实上,数据团队从事更广泛的项目,数据工程师、科学家和分析师可以从同行的见解中受益。
数据主管✅对公司的战略有一个集中的看法,可以将数据人员分配到最适合他们能力的项目中。
✅鼓励职业发展,如数据工程师、科学家,并对资历角色有明确的看法。
弊端
❌数据分析团队和其他业务部门之间脱节的可能性很高。在这种模式中,数据工程师和数据科学家不参与其他团队的日常活动,这使得他们很难确定要解决的最相关的问题。
分析小组的❌风险将降为“支持”职能,其他部门不承担其责任。
❌由于数据团队为企业的其他部门提供服务,其他业务部门可能会觉得他们的需求没有得到适当解决,或者觉得规划过程过于官僚和缓慢。
分散/嵌入式模型
数据团队的分散模型—图片由 Louise de Leyritz 提供
在一个分散的模型中,每个部门雇佣自己的数据人员,使用一个集中的数据平台。在这种模式下,数据分析师和科学家专注于他们特定业务部门面临的问题,很少与公司其他领域的数据人员互动。在这种结构下,数据分析师直接向各自业务部门的负责人报告。
优势
✅嵌入式团队的数据人员反应敏捷,因为他们致力于各自的业务职能,并拥有良好的领域知识。
✅产品经理可以将数据任务分配给最有资格处理这些任务的人。
✅业务数据团队不必为构建数据项目而争夺资源,因为资源就在团队中。
弊端
❌缺乏真实的来源,重复的数据内容
由于不同团队之间缺乏沟通,❌的数据人员最终会处理多余的问题。
❌孤岛的产生导致了生产力的侵蚀,因为数据人员不能像在集中式模型中那样利用他们同事的专业知识。
❌:这种模式使得为不同项目的数据人员配备最佳人员变得更加困难。
❌的业务经理通常缺乏技术背景,他们会发现很难管理数据人员,也很难理解他们的工作质量。
联合模式/卓越中心
联合模型最适合已经达到数据成熟度、拥有清晰的数据战略并从事预测分析的公司。
Louise de Leyritz 的卓越中心模式 l- Image
在卓越中心模式(COE)中,数据人员嵌入业务部门,但提供领导、支持和培训的集中团队仍然存在。如果数据分析师和科学家跨业务部门部署,您仍然会有一个数据领导者(或根据公司规模的数据领导者核心),他对数据项目进行优先排序和监督。这确保了首先处理最有益的数据项目。
这种策略最适合具有清晰数据路线图的大型企业级公司。卓越中心模式需要一个更大的数据团队,因为在卓越中心和不同的业务分支都需要数据科学家。如果您是一家中小型公司,您可能不需要如此规模的数据团队。
这种方法保留了集中式和嵌入式模型的优点。这是一个更加平衡的结构,其中数据团队的行动是协调的,但也让数据专家嵌入到业务部门中。
同样,知道谁是你的数据人员是非常重要的。在您的数据之旅开始时建立一个集中的团队时,确保您没有在其他部门安插业务分析师/运营人员。否则,您将最终得到一个不想要的混合模型,在您的组织中造成完全的混乱。在创建 COE 时,您需要确保它是需要的和计划好的。
优点
✅卓越中心模式提供了集中式和嵌入式模式的优点。
但是,它仍然存在一些缺点:
弊端
❌:这种模式需要一个额外的协调和沟通层,以确保 COE 和业务部门之间的一致性。
❌不适用于中小型组织,因此这些公司可以将它与这种中心辐射型模式带来的好处挂钩。
最后的话
如果你的公司要成为数据驱动型,建立一个强大的分析团队是你需要建立的一个关键支柱。您从数据中提取商业价值的程度最终取决于这个团队的实力,以及它与您的其他业务的共生程度。对于您的数据团队的规模、组成和结构,没有定制的建议。这就是为什么您需要了解您的组织的数据成熟度级别,以便您可以建立一个适合您的业务需求并与您的业务战略保持一致的数据团队。
关于我们
在 Castor,我们正在开发一个数据文档工具 Figma,Slack generation。或者对 Fivetran,Looker,Snowflake,DBT 的狂热爱好者来说是数据方面的。我们把我们的目录设计成易于使用、令人愉快和友好。
想去看看吗?联系我们,我们将向您展示一个演示。
原载于https://www.castordoc.com。
如何在 2021 年构建您的数据学习项目
原文:https://towardsdatascience.com/how-to-build-your-data-learning-projects-in-2021-eabf74d72479?source=collection_archive---------32-----------------------
创建自己的学习之旅时要考虑的事情
介绍
照片由 Dmitry Ratushny 在 Unsplash 上拍摄
数据工程是数据行业的一个重要领域。有许多需要处理数据的活动,以便我们可以获得数据驱动的决策。这些例子可以是
- 将数据从一个地方移动到另一个地方。
- 通过各种系统使用,从内部分析到组织外的第三方。
- 按时回答业务问题。
- 确保从前端应用到后端分析的数据质量。
- 管理数据可访问性策略。
对数据工程的需求每天都在增长。
作为该领域的数据爱好者,我认为这是任何人都应该具备的一项宝贵技能。当在技术或管理方向发展你的工作时,数据工程技能集可以使你成为一个有竞争力的候选人。
做出决定后,我花时间搜索要学习的话题。我发现有很多话题要谈。与数据分析师和数据科学家领域相比,学习主题相当宽泛。
这让我很困惑,我应该先学什么,后来才能更好地理解当时的这个领域。所以我有了一个简单的想法,那就是我应该了解这个行业在日常工作中真正使用的是什么。至少,这个行业已经投票给了我对他们来说什么是重要的。
了解公司想要什么。
肖恩·波洛克在 Unsplash 上拍摄的照片
去哪里找(工作描述,面试)
要想知道公司真正想从数据工程中得到什么,我们可以在招聘网站上发布的职位描述中找到。由于地区、国家和你寻找的公司行业的不同,要求可能会有所不同。这里有一个在新加坡的入门级数据工程工作的例子。
一个入门级的数据工程职位描述:作者截图
从上面的工作描述中,我们可以列出如下学习主题
- 编程语言—
Java
、Scala
、Python
、SQL
- 大数据技术—
Hadoop
、Spark
、Flink
- 基础知识—
Data warehousing
、Data mining
、Machine learning
、Data modeling
、Data governance
我们可以从需求部分收集学习主题。你可以搜索最多 5 到 10 个职位描述,并将它们合并在一起。然而,工作描述中的技术清单可能非常粗略。如果你有机会参加面试,你可以问一些有深度的问题,以便更好地了解他们真正需要的技术。
经过一些反复的提炼,会有一个主题列表出现在最上面。如果你把题目分成具体的和基本的,会有所帮助。
在我看来,有些题目可以学一次,适用于很多项目。但是对于一些特定的科目,这是你在你梦想的公司找到工作之前必须掌握的先决条件。
至少,基础知识不变。
我鼓励你花时间在基础知识上,比如数据建模、数据仓库、设计模式和数据管道的基本组件。
它将帮助你把每个学习主题联系起来。减少您理解用于实现更好性能的技术的时间。
启动器指南
以下是我在搜索中找到的一些排名靠前的主题。该列表是基于我的经验,所以会有从你的目标公司的变化。
- 编程语言—
Python
、Scala
、Java
- SQL 数据库—
Postgres
,Mysql
- 大数据技术—
Hadoop
、Kafka
- 数据处理引擎—
Presto
、Hive
、Impala
、Spark
- 基础知识—
Databases
、Distributed system
、Streaming processsing
、Data manipulation
、Schema managements
你可以从你的列表中为每个主题选择一个,并在学习期间和你的第一个动手项目中坚持下去。
找到合适的老师。
由工具拍摄的照片。,Inc on Unsplash
不是每门课程都适合你。
有许多大规模的在线课程。在谷歌上只需一次搜索,你就能立即找到某个特定主题的在线课程。这里重要的是不是每门课程都适合你的学习风格。我什么意思?
有些课程会以一种自下而上的方式教你,比如向你介绍基本概念,一点一点地建立你的理解,然后最后将它应用到真实世界的例子中。相比之下,其他人会告诉你另一种从上到下的方法。他们先带你驾驶汽车,然后解释每个部件,如踏板、车轮等。
我发现这两种教学方式都有助于巩固你的基础技能,但能让你在整个学习过程中保持注意力。
你需要选择一个你最喜欢的。
很多时候,我问自己一个问题,我现在在学什么?我如何将这种抽象应用到实际的项目中呢?这些概念和我在日常工作中看到的代码有什么联系?
他们如何传达信息。
另一个必不可少的因素是导师的教学风格。我曾经听过一句话。
如果你不明白他们教你什么,不要担心,这不是你的错。你只是没找到合适的。
同一个概念可以用许多不同的方式讲述。有些导师可以翻译所有的复杂,教你最直观的方法,但对有些人来说,他们没有。
根据我的经验,我建议你不要急于进入你在网上找到的任何课程。花点时间观看一个或多个他们的教学视频,并回答下列问题。
- 他们如何向你解释或介绍新概念。
- 你对他们所谈论的有多少了解。
- 口音,例子,他们传达信息的方式。
- 自上而下或自下而上的风格。
下面是我关于学习datastructure & algorithm
的例子。我第一次注册这门课程时。这是一门理论课,向你展示数学符号,以及如何从数学角度找到解决方案,然后他们应用这个概念来解决问题。
我发现有些数学符号很难理解,当时他们解释的方式对我来说相当模糊。在理解他们告诉我的一切(是的,我应该)之前,我需要一个强大的数学基础。
然而,我决定取消那门课,找了一门新的。后来我发现一门课程用不同的方式教我同样的概念。他们首先向我展示问题,然后将每个内容链接回基础概念。与第一个相比,我对课程内容的理解更加自如,对主题的理解也更加透彻。
根据我告诉你的,我建议继续学习你并不真正感兴趣的课程并不是一个好方法。如果你觉得这不是你的风格,取消注册,找一个新的。相信我;你会找到适合你的好工作,通过学习过程让你更加快乐。
你花在寻找合适的工作上的时间可能是一周,但是接下来一年的整个学习经历将会更有吸引力。
学习过程应该是有趣的,而不是令人沮丧和无聊的。
找到正确的渠道。
这一部分的最后一个话题是关于你可以从中学习和消费信息的媒体。2021 年,有各种方式教你一个新课题。它可以是一本书、视频、交互式编码会议,或者是 Zoom 或 Microsoft team 中的一个小组会议。
你应该尝试每一个可能的渠道,找到最适合你的。对我自己来说,我非常喜欢通过视频学习。我认为这有助于节省我消耗信息的时间。我可以把视频加速到 1.5 倍或者 2 倍。
对一些人来说,书籍可能是一种有趣的替代学习方式,但对我来说不是这样。
构建项目。
照片由内森·杜姆劳在 Unsplash 上拍摄
行动胜于言语。
要彻底理解学习主题,您需要有将学习概念应用到实际项目的实践经验。您可以从在 Jupyter 笔记本中实现一个简单的功能开始,然后一步一步地改进它,使之成为您自己的高质量数据项目。
不仅仅是为了学习,也是为了证明你拥有公司需要的令人满意的技能。
例如,我曾经参加了 Udacity 的数据工程纳米学位课程。我需要建立一个数据管道项目,并提交给 Udacity 的评审员以通过课程。这是我当时一直在做的项目。
https://github.com/Pathairush/data_engineering
在线课程迫使我建立一个项目来获得认证。这是教你一项新技能的好方法,也是让我独立完成一些项目的好方法,而不仅仅是看讲座视频。
有了 Nanodegree 课程的经验和模板,我可以更容易地为以后的项目调整模式。如果你想要一个想法来构建你自己的项目,请随时查看我的 Github。这是另一个你可以自己构建的数据工程项目的例子。
https://github.com/Pathairush/rdbms_to_hdfs_data_pipeline
你做的兼职越多,你学得越快。你将面临一个潜在的空间,你可以应用你的知识,从大规模的在线课程。
在你完成项目后,你可以像我一样,通过写在一篇 medium 博客文章中来总结你所学到的东西,并与他人分享。这个过程有助于你巩固和巩固你的思想。它迫使你更简单地向别人解释你做了什么。此外,如果读者发现一些错误或需要改进的地方,他们可以向你提出建议。因此,你可以直接从读者的反馈中提高自己。
调试经验
当你去实现的过程中,你绝对会发现一些沿途的 bug。它允许你利用在线资源,如 StackOverflow 或 Github repository,找到一种方法使事情工作。
我觉得这是你以后无论学什么的核心技能。你需要面对一些障碍,并想办法解决它。然后你会得到一些公司正在寻找的有经验的。当你自己面对问题时,你会比你只是从讲座中听到的知识有更好的回忆,但从来没有应用到你的项目中。
此外,它还拓宽了你的学习视野,因为仅仅从你的讲座中获得的知识并不能解决一些问题。例如,在初始化开发环境时,您可能会遇到一个问题。但是如果你能搞清楚,你将获得一套创造合适工作环境的新技能。我认为在线课程中没有指出这一点,因为他们总是会给你提供一个一切正常的工作空间。
我们通过摔倒来学习
写作/教学习。
照片由 NeONBRAND 在 Unsplash 上拍摄
简单解释
学习新事物有两种方式,消费或生产。要制作某样东西或教某个人,你需要彻底理解整个主题。当我不得不教别人的时候,我发现自己对这些科目有了更好的理解。
为了让别人理解你所理解的,你讲的故事需要足够简单。故事的顺序应该排列得很好。总结复杂的东西或复杂的过程,它让你训练你的大脑只选择你认为对别人有意义的东西。
我发现在学习新事物时,这是一个被低估的话题,因为这将花费你很多时间来准备教学,而不是消耗别人的知识。我们都有点懒惰。尽管如此,我还是鼓励你尝试将这种学习方法纳入你的学习课程。
如果你想有一个这种学习方法的例子,看看这个。我试着用这些技巧写下面的文章。
他人的反馈
在你教授完一门课程或者写完一篇文章并发表之后,它不会是完美的,但是它给了其他人帮助你做得更好的空间。
他们可以对你正在谈论的主题发表评论并补充他们的想法,他们也可以根据你的解释问你一个问题,这让你不得不浓缩你的想法并回答他们,这将导致对主题的更好理解。
感谢阅读
帕泰鲁什·西达
如果你喜欢这篇文章,并希望看到更多这样的东西。
- 跟着我上媒体
- 其他渠道? LinkedIn , Twitter ,以及脸书
如何构建您的数据可靠性堆栈
原文:https://towardsdatascience.com/how-to-build-your-data-reliability-stack-7cf1a0f5bf30?source=collection_archive---------11-----------------------
数据可靠性是现代数据团队的一个重要关注点。以下是开始的方法
图片由 Unsplash 上的 ThisisEngineering RAEng 提供
2004 年 7 月 26 日,一家名为 Google 的 5 岁初创公司面临一个严重的问题: 他们的应用程序宕机 。
几个小时以来,美国、法国和英国的用户都无法访问这个流行的搜索引擎。当时只有 800 人的公司和他们的数百万用户被蒙在鼓里,工程师们努力解决这个问题并找出问题的根源。到中午时分,由几个惊慌失措的工程师进行的冗长而密集的过程确定了 MyDoom 病毒是罪魁祸首。
在 2021 年,这种长度和规模的中断被认为是相当不正常的,但在 15 年前,这种类型的软件中断并不罕见。时任谷歌工程经理的本杰明·特雷诺·斯洛斯(Benjamin trey nor Schmidt)多年来带领团队经历了几次这样的经历,他认为必须有一种更好的方法来管理和防止这些令人眼花缭乱的消防演习,不仅是在谷歌,而是在整个行业。
受他早期构建数据和 IT 基础设施的职业生涯的启发,斯洛斯将他的学习整理成一个全新的学科— 站点可靠性工程【SRE】—致力于优化软件系统(如谷歌的搜索引擎)的维护和运营,同时考虑到可靠性。
根据为学科发展铺平道路的斯洛斯和其他人的说法, , SRE 是关于自动消除对边缘情况和未知的未知(如错误代码、服务器故障和病毒)的担忧。最终,斯洛斯和他的团队希望找到一种方法,让工程师自动化维护公司快速增长的代码库的手工劳动,同时确保他们的代码库在系统崩溃时得到保护。
“SRE 是一种思考和对待生产的方式。大多数开发系统的工程师也可以成为该系统的 SRE。“问题是:他们能否解决一个复杂的、可能还没有明确定义的问题,并提出一个可扩展的、技术上合理的解决方案?”
如果谷歌有正确的流程和系统来预测和预防下游问题,不仅可以在对用户影响最小的情况下轻松修复宕机,还可以完全避免宕机。
数据是软件,软件是数据
近 20 年后,数据团队面临着类似的命运。像软件一样,数据系统正变得越来越复杂,具有多种上游和下游依赖性。十年甚至五年前,在孤岛中管理数据是正常且被接受的,但现在,团队甚至整个公司都在处理数据,促进了更具协作性和容错性的数据管理方法。
在过去的几年中,我们见证了数据工程和分析团队广泛采用软件工程最佳实践来解决这一差距,从采用 dbt 和 Apache Airflow 等开源工具来简化数据转换和编排,到基于云的数据仓库和湖泊,如 Snowflake 和 。
从根本上说,这种向敏捷原则的转变与我们如何概念化、设计、构建和维护数据系统有关。孤岛式仪表板和报告的时代已经一去不复返了,它们只生成一次,很少使用,也从不更新;现在,为了在规模上有用, 数据还必须被产品化 、维护和管理,以供整个公司的最终用户使用。
为了让数据像软件产品一样被对待,它也必须像软件产品一样可靠。
数据可靠性的提高
推特由永远欢闹的塞斯·罗森提供。
简而言之,数据可靠性 是组织在整个数据生命周期中提供高数据可用性和健康的能力,从摄取到最终产品:仪表板、ML 模型和生产数据集。过去,从测试框架到数据可观察性,人们已经注意到孤立地解决难题的不同部分,但是这种方法已经不够了。然而,正如任何数据工程师都会告诉你的那样,数据可靠性(以及真正像对待产品一样对待数据的能力)是无法在孤岛中实现的。
一个数据资产中的模式更改会影响多个表,甚至 Tableau 仪表板中的下游字段。当您的财务团队在 Looker 中查询新的见解时,一个缺失的值会让他们歇斯底里。当 500 行突然变成 5000 行时,这通常是一个迹象,表明有些事情不对劲——您只是不知道表在哪里或如何损坏的。
即使有大量的数据工程工具和资源,数据也可能因为数百万种不同的原因而损坏,从操作问题和代码更改到数据本身的问题。
在与数百个数据团队交谈后,根据我自己的经验,我们发现大约 80%的数据问题无法通过单独的测试来解决。图片由 Lior Gavish 提供。
根据我们自己的经验,在与数百个团队交谈后,目前大多数数据工程师发现数据质量问题有两种方式:测试(理想的结果)和来自下游利益相关者的愤怒消息(可能的结果)。
与 sre 管理应用停机时间的方式相同,今天的数据工程师必须通过自动化、持续集成和持续部署数据模型以及其他敏捷原则,专注于减少https://www.montecarlodata.com/the-rise-of-data-downtime/【数据停机时间】—数据不准确、丢失或出现其他错误的时间段。
过去,我们已经讨论过如何构建 一个快速而肮脏的数据平台;现在,我们在此设计的基础上进行构建,以反映迈向良好数据之旅的下一步:数据可靠性堆栈。
以下是如何和为什么要建立一个。
简介:数据可靠性堆栈
如今,数据团队的任务是构建可扩展、高性能的数据平台,该平台可以通过存储、处理和传输数据来满足跨职能分析团队的需求,从而生成准确、及时的见解。但是要实现这一点,我们首先还需要适当的方法来确保原始数据是可用和可信的。为此,一些最优秀的团队正在构建数据可靠性堆栈,作为其现代数据平台的一部分。
在我看来,现代数据可靠性堆栈由四个不同的层组成:测试、CI/CD、数据可观察性和数据发现,每一层都代表您公司数据质量之旅中的一个不同步骤。
数据可靠性堆栈由五层组成,包括测试、CI/CD、数据可观测性和数据发现。图片由 Lior Gavish 提供。
测试
在数据进入生产数据管道之前,测试数据对于发现数据质量问题至关重要。通过测试,工程师可以预见到可能会出现的问题,并编写逻辑来抢先检测问题。
数据测试是在生产前或生产过程中验证组织对数据的假设的过程。编写检查诸如唯一性和 not_null 等内容的基本测试是组织测试他们对源数据所做的基本假设的方法。对于组织来说,确保数据的格式正确以便团队使用,并且数据满足他们的业务需求也是很常见的。
一些最常见的数据质量测试包括:
- 空值 —是否有未知值(空)?
- 我得到任何数据了吗?我得到的是太多还是太少?
- 分布 —我的数据是否在可接受的范围内?我的值是否在给定列的范围内?
- 唯一性 —有重复的值吗?
- 已知不变量 —利润永远是收入和成本的差额,还是我的数据中其他一些众所周知的事实?
根据我自己的经验,测试数据的两个最好的工具是 dbt 测试和远大前程(作为一个更通用的工具)。这两个工具都是开源的,允许您在数据质量问题落入利益相关者手中之前发现它们。虽然 dbt 本身并不是一个测试解决方案,但是如果您已经在使用该框架来建模和转换您的数据,那么他们的开箱即用测试就可以很好地工作。
持续集成(CI) /持续交付(CD)
CI/CD 是软件开发生命周期的一个关键组成部分,它通过自动化确保随着时间的推移进行更新时,新代码部署是稳定和可靠的。
在数据工程的上下文中,CI/CD 不仅与持续集成新代码的过程有关,还与将新数据集成到系统中的过程有关。通过在早期阶段检测问题,最好是在提交代码或合并新数据时,数据团队能够实现更快、更可靠的开发工作流。
让我们从等式的代码部分开始。就像传统的软件工程师一样,数据工程师受益于使用源代码控制,例如 Github ,来管理他们的代码和转换,以便新代码可以被正确地审查和版本控制。一个 CI/CD 系统,例如, Circle 或 Jenkins (开源),具有完全自动化的测试和部署设置,可以在部署代码时创建更多的可预测性和一致性。这听起来应该很熟悉。数据团队遇到的额外复杂性是理解代码更改如何影响其输出的数据集的挑战。这就是像 Datafold 这样的新兴工具的用武之地——允许团队将一段新代码的数据输出与之前运行的相同代码进行比较。通过在部署代码之前,在流程的早期捕获意外的数据差异,可以实现更高的可靠性。虽然此流程需要代表性的试运行或生产数据,但它可能非常有效。
还有另一个工具系列,旨在帮助团队更可靠地传输新数据,而不是新代码。有了 LakeFS 或 Project Nessie ,团队能够在发布数据之前将其暂存,以便用类似 g it 的语义进行下游消费。想象一下,用新处理的数据创建一个分支,如果认为它是好的,就把它提交给主分支!结合测试,数据分支可能是阻止坏数据到达下游消费者的非常强大的方法。
数据可观察性
生产前测试和版本控制数据是实现数据可靠性的第一步,但是当数据在生产中以及生产之外中断时会发生什么呢?
除了在转换和建模之前处理数据质量的数据可靠性堆栈元素之外,数据工程团队还需要投资于端到端、自动化的数据可观察性解决方案,这些解决方案可以近乎实时地检测何时出现数据问题。与 DevOps 可观察性解决方案(即 Datadog 和 New Relic)类似, 数据可观察性 使用自动化监控、警报和分类来识别和评估数据质量问题。
图片由巴尔·摩西提供
数据可观察性通过数据健康和可靠性的五个关键支柱来衡量:新鲜度、分布、容量、模式和沿袭。
- ****新鲜度:数据是最近的吗?最后一次生成是什么时候?包括和/或省略了哪些上游数据?
- ****分布:数据是否在可接受的范围内?这是正确的格式吗?完成了吗?
- ****卷:资料都到了吗?数据是意外复制的吗?从表中删除了多少数据?
- ****模式:什么是模式,它是如何变化的?谁对模式进行了更改,原因是什么?
- ****沿袭:对于给定的数据资产,受其影响的上游和下游来源是什么?谁在生成这些数据,谁在依靠这些数据做决策?
数据可观察性是您的团队无法预测的其他 80%的数据停机时间的原因( 未知未知 ),不仅仅是检测数据质量问题并发出警报,还提供根本原因分析、影响分析、现场级沿袭以及对您的数据平台的运营洞察。
有了这些工具,您的团队将能够通过对数据可靠性的历史和统计洞察,不仅解决而且防止类似问题在未来发生。
数据发现
虽然传统上不被视为可靠性堆栈的一部分,但我们认为数据发现至关重要。团队创建不可靠数据的最常见方式之一是忽略已经存在的资产,并创建与现有数据集显著重叠甚至矛盾的新数据集。这在组织中的消费者中造成了混淆,即哪些数据与特定的业务问题最相关,并降低了信任度和可感知的可靠性。这也为数据工程团队制造了大量的数据债务。如果没有好的发现,团队会发现他们需要维护几十个不同的数据集,所有这些数据集都描述相同的维度或事实。单单复杂性就使进一步的开发成为一个挑战,而高可靠性是极其困难的。
虽然数据发现是一个非常具有挑战性的问题,但数据目录已经朝着更大的民主化和可访问性取得了进展。例如,我们已经见证了 Atlan、data.world 和 Stemma 等解决方案如何解决这两个问题。
同时,数据可观察性解决方案有助于消除许多常见的可靠性问题和实现数据发现所需的数据债务挑战。通过将元数据、谱系、质量指标、使用模式以及人工生成的文档整合在一起,数据可观察性可以回答这样的问题:我可以用什么数据来描述我们的客户?我应该最信任哪个数据集?我如何使用该数据集?谁是可以帮助回答相关问题的专家?简而言之,这些工具为数据消费者和生产者提供了一种找到他们需要的数据集或报告的方法,避免了重复劳动。
将这些信息大众化,并让任何使用或创建数据的人都可以使用,这是可靠性难题的一个关键部分。
数据可靠性的未来
随着数据越来越成为现代企业日常运营不可或缺的一部分,并为数字产品提供动力,对可靠数据的需求只会增加,确保这种信任的技术要求也会增加。
尽管您的工具会让您在某种程度上实现这一目标,但数据可靠性并不能仅靠技术来解决。最强有力的方法还包括文化和组织转变,以优先考虑治理、隐私和安全,这三个现代数据堆栈领域在未来几年内加速发展的时机已经成熟。
您的数据可靠性武库中的另一个强大工具是优先考虑服务级别协议(SLA)和其他措施,以跟踪相对于与您的利益相关者设定的商定预期的问题频率,这是从软件工程中收集的另一个经过验证的真实最佳实践。随着您的组织将数据视为产品,数据团队不再像财务分析师,而更像产品和工程团队,这些指标将变得至关重要。
与此同时,祝您没有数据停机时间,有充足的正常运行时间!
本文由利奥·加维什合著。
有兴趣了解更多关于数据可靠性的知识吗?伸出手去 巴尔摩西利奥加维什或者剩下的*** 蒙特卡洛团队 。***
如何用 Python 构建你的第一个机器学习模型
原文:https://towardsdatascience.com/how-to-build-your-first-machine-learning-model-in-python-e70fd1907cdd?source=collection_archive---------0-----------------------
使用来自 envato elements 的 aqrstudio 的图像创建(经许可)。
数据科学 | 机器学习
使用 Scikit-learn 库从头开始的逐步教程
答之前我写过一篇关于 如何构建机器学习模型的博客
(学习数据科学的可视化指南) ,带你踏上一次关于如何构建机器学习模型的视觉和概念之旅。这篇文章没有展示的是如何实现模型的实际构建。
在本文中,您将学习如何用 Python 构建您的第一个机器学习模型。特别是,您将使用传统的线性回归以及其他机器学习算法来构建回归模型。
我制作了下面的 YouTube 视频作为本文的补充,特别是它将让你快速了解机器学习模型构建的概念,这也在上文提到的第一篇博文中有所涉及。
如何建立机器学习模型 @ 数据教授 YouTube 频道
1.你的第一个机器学习模型
那么我们今天构建的是什么机器学习模型呢?在本文中,我们将在溶解度数据集上使用随机森林算法构建一个回归模型。
建立模型后,我们将应用模型进行预测,然后进行模型性能评估和结果的数据可视化。
2.资料组
2.1.玩具数据集
那么我们要用哪个数据集呢?默认答案可能是使用玩具数据集作为示例,如 Iris 数据集(分类)或 Boston housing 数据集(回归)。
虽然这两个都是很好的例子,但通常大多数教程并不直接从外部源(例如从 CSV 文件)加载这些数据,而是直接从 Python 库(例如scikit-learn
的datasets
子模块)导入数据。
例如,要加载 Iris 数据集,可以使用以下代码块:
from sklearn import datasetsiris = datasets.load_iris()
X = iris.data
y = iris.target
使用玩具数据集的好处是它们使用起来超级简单,只需以一种易于用于模型构建的格式直接从库中导入数据。这种便利的缺点是,初次学习者可能实际上看不到哪些函数正在加载数据,哪些函数正在执行实际的预处理,以及哪些函数正在构建模型,等等。
2.2.您自己的数据集
在本教程中,我们将采取一种实用的方法,重点构建您可以轻松复制的实际模型。因为我们将直接从 CSV 文件中读入输入数据,所以您可以很容易地用您自己的数据替换输入数据,并为您自己的数据项目重新调整这里描述的工作流程。
我们今天使用的数据集是solubility
数据集。它由 1444 行和 5 列组成。每行代表一个唯一的分子,每个分子由 4 个分子属性(前 4 列)描述,而最后一列是要预测的目标变量。该目标变量表示分子的溶解度,它是治疗药物的一个重要参数,因为它帮助分子在体内行进以达到其目标。
下面是solubility
数据集的前几行。
溶解度数据集的前几行。
2.2.1。加载数据
完整的solubility
数据集可在 Data 教授 GitHub 上通过以下链接获得: 下载溶解度数据集 。
为了适用于任何数据科学项目,可以使用Pandas
库将 CSV 文件中的数据内容读入 Python 环境。我将在下面的示例中向您展示如何:
import pandas as pddf = pd.read_csv('data.csv')
第一行将pandas
库作为简称为pd
的缩写形式导入(以便于键入)。从pd
开始,我们将使用它的read_csv()
功能,因此我们键入pd.read_csv()
。通过在前面键入pd
,我们可以知道read_csv()
函数属于哪个库。
read_csv()
函数中的输入参数是 CSV 文件名,在上面的例子中是'data.csv’
。这里,我们将 CSV 文件中的数据内容分配给一个名为df
的变量。
在本教程中,我们将使用溶解度数据集(可从https://raw . githubusercontent . com/data professor/data/master/Delaney _ solubility _ with _ descriptors . CSV获得)。因此,我们将使用以下代码加载数据:
import pandas as pddf = pd.read_csv('https://raw.githubusercontent.com/dataprofessor/data/master/delaney_solubility_with_descriptors.csv')
2.2.2。数据处理
既然我们已经在df
变量中有了数据帧,我们现在需要准备一个合适的格式供scikit-learn
库使用,因为df
还不能被库使用。
我们如何做到这一点?我们需要将它们分成两个变量X
和y
。
除最后一列外的前 4 列将被分配给X
变量,而最后一列将被分配给y
变量。
2.2.2.1。给 X 分配变量
为了将前 4 列赋给X
变量,我们将使用以下代码行:
X = df.drop(['logS'], axis=1)
正如我们所看到的,我们通过删除最后一列(logS
)来做到这一点。
2.2.2.2。将变量赋给 y
要将最后一列分配给y
变量,我们只需选择最后一列,并将其分配给y
变量,如下所示:
y = df.iloc[:,-1]
正如我们所看到的,我们通过显式选择最后一列来做到这一点。也可以采用两种替代方法来获得相同的结果,其中第一种方法如下:
y = df[‘logS’]
第二种方法如下:
y = df.logS
从以上选项中选择一项,然后继续下一步。
3.数据分割
数据分割允许对模型以前没有看到的新数据进行无偏见的评估。特别是,如果使用 80/20 的拆分比率将整个数据集拆分为训练集和测试集,那么可以使用 80%的数据子集(即我们可以称之为训练集)构建模型,并随后对 20%的数据子集(即我们可以称之为测试集)进行评估。除了在测试集上应用训练模型之外,我们还可以在训练集上应用训练模型(即,首先用于构建模型的数据)。
随后比较两种数据分割(即训练集和测试集)的模型性能,将允许我们评估模型是欠拟合还是过拟合。无论训练集和测试集的性能都很差,通常都会出现欠拟合,而在过拟合时,测试集与训练集相比性能明显不佳。
为了执行数据分割,scikit-learn
库有train_test_split()
函数允许我们这样做。使用此函数将数据集拆分为训练集和测试集的示例如下所示:
from sklearn.model_selection import train_test_splitX_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42)
在上面的代码中,第一行从sklearn.model_selection
子模块中导入了train_test_split()
函数。如我们所见,输入参数由X
和y
输入数据组成,测试集大小被指定为 0.2(即 20%的数据将进入测试集,而剩余的 80%将进入训练集),随机种子数被设置为 42。
从上面的代码中,我们可以看到我们同时为训练集(X_train
和y_train
)和测试集(X_test
和y_test
)创建了 4 个变量,它们由独立的X
和y
变量组成。
现在,我们准备使用这 4 个变量进行建模。
4.模型结构
有趣的部分来了!我们现在要建立一些回归模型。
4.1.线性回归
4.1.1。模型构建
让我们从传统的线性回归开始。
from sklearn.linear_model import LinearRegressionlr = LinearRegression()
lr.fit(X_train, y_train)
第一行从sklearn.linear_model
子模块导入LinearRegression()
函数。接下来,LinearRegression()
函数被分配给lr
变量,.fit()
函数对输入数据X_train
和y_train
执行实际的模型训练。
现在模型已经建立,我们将应用它对训练集和测试集进行预测,如下所示:
y_lr_train_pred = lr.predict(X_train)
y_lr_test_pred = lr.predict(X_test)
正如我们在上面的代码中看到的,模型(lr
)通过lr.predict()
函数在训练集和测试集上进行预测。
4.1.2。型号性能
我们现在将计算性能指标,以便能够确定模型性能。
from sklearn.metrics import mean_squared_error, r2_scorelr_train_mse = mean_squared_error(y_train, y_lr_train_pred)
lr_train_r2 = r2_score(y_train, y_lr_train_pred)lr_test_mse = mean_squared_error(y_test, y_lr_test_pred)
lr_test_r2 = r2_score(y_test, y_lr_test_pred)
在上面的代码中,我们从sklearn.metrics
子模块中导入了mean_squared_error
和r2_score
函数来计算性能指标。两个函数的输入参数是实际的 Y 值(y
)和预测的 Y 值(y_lr_train_pred
和y_lr_test_pred
)。
让我们来谈谈这里使用的命名约定,我们将函数分配给自解释变量,明确地告诉变量包含什么。例如,lr_train_mse
和lr_train_r2
明确地告诉变量包含使用训练集上的线性回归构建的模型的性能度量 MSE 和 R2。使用这种命名约定的优点是,使用不同的机器学习算法构建的任何未来模型的性能指标都可以通过其变量名轻松识别。例如,我们可以使用rf_train_mse
来表示使用随机森林构建的模型的训练集的 MSE。
可以通过简单地打印变量来显示性能指标。例如,要打印出训练集的 MSE:
print(lr_train_mse)
这就给出了1.0139894491573003
。
要查看其他 3 个指标的结果,我们也可以一个接一个地打印出来,但是这样会有点重复。
另一种方法是生成 4 个指标的整洁显示,如下所示:
lr_results = pd.DataFrame(['Linear regression',lr_train_mse, lr_train_r2, lr_test_mse, lr_test_r2]).transpose()lr_results.columns = ['Method','Training MSE','Training R2','Test MSE','Test R2']
它产生以下数据帧:
4.2.随机森林
随机森林(RF)是一种集成学习方法,它结合了几个决策树的预测。RF 的一个优点是其内置的特征重要性(即它为构建的模型生成的基尼指数值)。
4.2.1。模型构建
现在,让我们使用以下代码构建一个 RF 模型:
from sklearn.ensemble import RandomForestRegressorrf = RandomForestRegressor(max_depth=2, random_state=42)
rf.fit(X_train, y_train)
在上面的代码中,第一行从sklearn.ensemble
子模块导入了RandomForestRegressor
函数(也可以称为回归变量)。这里应该注意的是RandomForestRegressor
是回归版本(即当 Y 变量包含数值时使用),而它的姊妹版本是RandomForestClassifier
,它是分类版本(即当 Y 变量包含分类值时使用)。
在本例中,我们将max_depth
参数设置为 2,随机种子号(通过random_state
)设置为 42。最后,使用rf.fit()
函数训练模型,我们将X_train
和y_train
设置为输入数据。
我们现在将应用构建的模型对训练集和测试集进行预测,如下所示:
y_rf_train_pred = rf.predict(X_train)
y_rf_test_pred = rf.predict(X_test)
与在lr
模型中使用的方式类似,rf
模型也用于通过rf.predict()
函数对训练集和测试集进行预测。
4.2.2。型号性能
现在,让我们计算构建的随机森林模型的性能指标,如下所示:
from sklearn.metrics import mean_squared_error, r2_scorerf_train_mse = mean_squared_error(y_train, y_rf_train_pred)
rf_train_r2 = r2_score(y_train, y_rf_train_pred)rf_test_mse = mean_squared_error(y_test, y_rf_test_pred)
rf_test_r2 = r2_score(y_test, y_rf_test_pred)
为了合并结果,我们使用以下代码:
rf_results = pd.DataFrame(['Random forest',rf_train_mse, rf_train_r2, rf_test_mse, rf_test_r2]).transpose()rf_results.columns = ['Method','Training MSE','Training R2','Test MSE','Test R2']
它产生:
4.3.其他机器学习算法
为了使用其他机器学习算法建立模型(除了我们上面使用的[sklearn.ensemble.RandomForestRegressor](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestRegressor.html)
,我们只需要从可用的回归变量中决定使用哪种算法(即,因为数据集的 Y 变量包含分类值)。
4.3.1。回归变量列表
让我们来看看我们可以从中选择的一些回归变量示例:
[sklearn.linear_model.Ridge](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.Ridge.html)
[sklearn.linear_model.SGDRegressor](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.SGDRegressor.html)
[sklearn.ensemble.ExtraTreesRegressor](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.ExtraTreesRegressor.html)
[sklearn.ensemble.GradientBoostingRegressor](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.GradientBoostingRegressor.html)
[sklearn.neighbors.KNeighborsRegressor](https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KNeighborsRegressor.html)
[sklearn.neural_network.MLPRegressor](https://scikit-learn.org/stable/modules/generated/sklearn.neural_network.MLPRegressor.html)
[sklearn.tree.DecisionTreeRegressor](https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeRegressor.html)
[sklearn.tree.ExtraTreeRegressor](https://scikit-learn.org/stable/modules/generated/sklearn.tree.ExtraTreeRegressor.html)
[sklearn.svm.LinearSVR](https://scikit-learn.org/stable/modules/generated/sklearn.svm.LinearSVR.html)
[sklearn.svm.SVR](https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVR.html)
有关更详细的回归量列表,请参考Scikit-learn
的 API 参考。
4.3.2。使用回归器
假设我们想要使用[sklearn.tree.ExtraTreeRegressor](https://scikit-learn.org/stable/modules/generated/sklearn.tree.ExtraTreeRegressor.html)
,我们将如下使用:
from sklearn.tree import ExtraTreeRegressoret = ExtraTreeRegressor(random_state=42)
et.fit(X_train, y_train)
注意我们是如何为[sklearn.tree.ExtraTreeRegressor](https://scikit-learn.org/stable/modules/generated/sklearn.tree.ExtraTreeRegressor.html)
导入回归函数的,如下所示:
from sklearn.tree import ExtraTreeRegressor
然后,回归函数被分配给一个变量(即本例中的et
),并通过.fit()
函数进行模型训练,如et.fit()
所示。
4.4.合并结果
让我们回忆一下,我们之前为线性回归和随机森林模型生成的模型性能指标存储在lr_results
和rf_results
变量中。
由于两个变量都是数据帧,我们将使用如下所示的pd.concat()
函数将它们组合起来:
pd.concat([lr_results, rf_results])
这会产生以下数据帧:
应注意的是,附加学习方法的性能指标也可以通过添加到列表[lr_results, rf_results]
中来添加。
例如,svm_results
可以被添加到列表中,然后成为[lr_results, rf_results, svm_results]
。
5.预测结果的数据可视化
现在,让我们将实际 Y 值与其预测 Y 值的关系可视化,即实验对数与预测对数值的关系。
import matplotlib.pyplot as plt
import numpy as npplt.figure(figsize=(5,5))
plt.scatter(x=y_train, y=y_lr_train_pred, c="#7CAE00", alpha=0.3)z = np.polyfit(y_train, y_lr_train_pred, 1)
p = np.poly1d(z)plt.plot(y_train,p(y_train),"#F8766D")
plt.ylabel('Predicted LogS')
plt.xlabel('Experimental LogS')
如上所示,我们将使用Matplotlib
库制作散点图,而Numpy
用于生成数据的趋势线。这里,我们通过plt.figure()
功能的figsize
参数将图形尺寸设置为 5 × 5。
plt.scatter()
函数用于创建散点图,其中y_train
和y_lr_train_pred
(即通过线性回归得到的训练集预测)用作输入数据。使用#7CAE00
的 HTML 颜色代码(十六进制代码)将颜色设置为绿色。
通过np.polyfit()
功能绘制的趋势线,并通过plt.plot()
功能显示,如上图所示。最后,分别通过plt.xlabel()
和plt.ylabel()
功能添加 X 轴和 Y 轴标签。
渲染的散点图显示在左侧。
下一步是什么?
恭喜你建立了你的第一个机器学习模型!
你可能会问,接下来是什么?答案很简单,多建模型!调整参数,尝试新算法,为机器学习管道添加新功能,最重要的是,不要害怕犯错。事实上,加速你学习的最快途径是经常失败,爬起来再试一次。学习是享受过程,如果你坚持足够长的时间,你会在成为数据专家的道路上变得更加自信,无论是数据科学、数据分析师还是数据工程师。但最重要的是,正如我常说的:
“学习数据科学的最佳方式是研究数据科学”
订阅我的邮件列表,获取我在数据科学方面的最佳更新(偶尔还有免费内容)!
关于我
我是泰国一所研究型大学的生物信息学副教授和数据挖掘和生物医学信息学负责人。在我下班后的时间里,我是一名 YouTuber(又名数据教授)制作关于数据科学的在线视频。在我制作的所有教程视频中,我也在 GitHub 上分享 Jupyter 笔记本(数据教授 GitHub 页面)。
https://www.youtube.com/dataprofessor
在社交网络上与我联系
✅YouTube:http://youtube.com/dataprofessor/
♇网站:http://dataprofessor.org/(在建)
♇LinkedIn:https://www.linkedin.com/company/dataprofessor/
♇Twitter:https://twitter.com/thedataprof
♇Facebook:http://facebook.com/dataprofessor/
♇github:https://github.com/dataprofessor/
♇insta gram:
如何不用代码构建你的第一个机器学习模型
原文:https://towardsdatascience.com/how-to-build-your-first-machine-learning-model-using-no-code-a7cf8db37dd1?source=collection_archive---------16-----------------------
由 envato elements 的 visuelcolonie 使用图像创建(经许可)。
入门
使用 WEKA 的药物发现数据集的端到端教程
你是否曾经想开始机器学习,但也许不知道如何编码的恐惧阻碍了你?
不用担心,因为在本文中,您将学习如何使用药物发现数据集,以一步一步的方式从零开始为端到端项目构建机器学习模型。
这篇文章是初学者友好的,因为提供了计算和生物学概念的解释。
我们这里有很多要讲的,所以让我们开始吧!
1.高级概述
1.1.本教程中使用的数据
本教程中使用的药物发现数据集将构成已被测试其作为抗丙型肝炎病毒药物潜力的分子。特别地,来自丙型肝炎病毒的 NS5B 蛋白已经针对分子文库进行了实验测试。我们的研究小组从 ChEMBL 数据库中编译了一个数据集,然后使用随机森林建立了一个机器学习模型。最好的模型被部署为一个名为 HCVpred 的 web 服务器。
该研究的概念框架总结如下,关于该程序的进一步细节将在下一节展开。
HCVpred 研究的概念框架。由作者绘制。
以下链接提供了描述该研究全部细节的研究文章:
https://onlinelibrary.wiley.com/doi/abs/10.1002/jcc.26223
1.2.模型建立过程
现在让我们来看看我们将在本教程中构建的机器学习模型。
在下图中,您可以在左侧看到示意图,而步骤或程序名称显示在右侧。
机器学习模型构建的示意性工作流程的卡通插图,其中目标响应变量(Y)被预测为输入分子特征(X)的函数。从技术上讲,这个过程被称为定量结构-活性关系 (QSAR)。由作者绘制。
这里,我们从分子 ( 分子 1 和分子 2 )开始,它们通常由它们的 SMILES 符号表示(即数据集中的CANONICAL_SMILES
列,我们将在下一节中看到)。SMILES 是简化分子输入行输入系统的首字母缩写,用于表示分子的化学结构([更多信息请点击](http://simplified molecular-input line-entry system))。把它想象成把分子的化学结构信息以文本形式转化到计算机中的一种方式。
接下来,我们计算分子描述符,这是一个将 SMILES 符号作为输入的过程,以便将其转换为描述每个分子独特分子特征的有意义的数字形式。该图显示分子由一串二进制数编码,如 1011001100011010,其中每个数字代表感兴趣的分子特征,而 0 和 1 表示该分子特征的存在或不存在。
分子(即行)及其相应分子描述符(即即X1
- X16
列)和生物活性类别标签(即即Y
列)的集合将构成数据集。
然后使用数据集作为输入来构建机器学习模型。经过训练的模型现在可以用来对新化合物进行预测。
最后,通过特征重要性图分析特征,可以从训练好的模型中获得洞察力。
2.资料组
2.1.关于数据集
HCVpred 数据集由总共 578 个分子组成,已经通过实验测试了这些分子针对靶蛋白(丙型肝炎病毒 NS5B)的生物活性。如果一个分子能够有效地结合靶蛋白,那么它将被认为是一个有前途的候选药物。
因此,上述研究的目标是构建能够预测作为分子指纹(即分子特征的数值表示)的函数的生物活性(即pIC50 值)的机器学习模型。应当注意,pIC50 值代表 Y 变量,而分子指纹代表 X 变量。
2.2.下载数据集
数据集托管在以下 GitHub 存储库( 下载 HCV_NS5B_Curated.csv 文件):
https://github.com/chaninlab/hcvpred/
数据集的摘录如下所示:
ChEMBL 数据通过知识共享署名-共享 3.0 无版权许可提供。
2.3.我们将使用什么
简言之,在本教程中,我们将使用CMPD_CHEMBLID
、CANONICAL_SMILES
和pIC50
列。计算分子指纹(即X 变量)时将需要CMPD_CHEMBLID
和CANONICAL_SMILES
列,而pIC50
列将作为 Y 变量使用。
3.软件
3.1.Java 语言(一种计算机语言,尤用于创建网站)
Java 是一种解释语言,它允许程序跨平台运行在所有操作系统上,比如本教程中使用的 WEKA 和 PaDEL。
首先,确保你的电脑上安装了 Java。最简单的方法是打开一个终端(Windows 中的 Power Shell ),输入java
,然后按回车键。
如果您看到如下内容,那么您可以继续,否则您可以继续安装 Java。
3.2.新西兰黑秧鸡
WEKA 是用 Java 开发的开源机器学习软件,它有一个图形用户界面,允许用户通过点击来使用该软件。
WEKA 是怀卡托知识分析环境的首字母缩写,由新西兰怀卡托大学开发。
WEKA 是一个全面的工具,允许用户执行数据准备、分类、回归、聚类、关联规则挖掘和可视化。Weka 也是一种在新西兰发现的土著鸟的名字,用在他们的标志上,如左图所示。
现在,进入 为你的操作系统(Windows、Mac OSX 和 Linux)下载 WEKA 。最后,启动 WEKA,您应该会看到如上所示的用户界面。
3.3.PaDEL 描述符
PaDEL-Descriptor 是一个分子描述符计算软件,可以将 SMILES 符号转换为分子描述符。PaDEL 支持 1D、2D 和 3D 描述符以及分子指纹的计算。在这项研究中,我们将使用 HCVpred 最初发表的论文中使用的分子指纹。
现在,进入 下载 PaDEL-Descriptor ,可以在所有操作系统上运行。
解压缩 ZIP 文件会显示以下内容:
PaDEL-Descriptor ZIP 文件内容的屏幕截图。
最后,通过双击PaDEL-Descriptor.jar
文件启动 PaDEL-Descriptor 软件,您应该会看到以下内容:
PaDEL-Descriptor 软件的屏幕截图。
4.计算分子描述符
4.1.准备 PaDEL 输入文件
在我们使用 PaDEL-Descriptor 软件计算分子描述符之前,我们首先要准备输入文件。
我们将分两步完成:
- 将
CANONICAL_SMILES
和CMPD_CHEMBLID
列复制并粘贴到一个新的电子表格文件中,如下所示。
显示如何将输入文件准备到 PaDEL-Descriptor 软件的屏幕截图。
2.将文件保存为Tab delimited Text (.txt)
文件格式,并命名为molecule.smi
。
显示将文件保存为制表符分隔的文本(.txt),然后指定文件名为 molecule.smi
值得注意的是,我们已经删除了标题行(即指定列名的第一行),这样第一行立即以 SMILES 符号及其相应的分子 ID 开始。
另一个需要检查的重要事情是,文件保存后,文件名可能是molecule.smi.txt
,如果是这样,请将其重命名为molecule.smi
。
4.2.计算描述符
现在让我们按如下所述计算分子指纹。
- 启动 PaDEL-Descriptor 软件,确保勾选下图所示的指定框,并填写目录名和输出文件名。
那么这些勾选框是什么意思呢?
显示参数设置和使用 PaDEL-Descriptor 启动描述符计算的屏幕截图。
指纹 将指定我们将计算分子指纹(即我们将在下一步中指定我们想要选择 12 种指纹类型中的哪一种)。
标准化部分下的参数将通过去除盐、检测芳香性、标准化互变异构体和标准化硝基来标准化化学结构。
2.点击顶部的指纹标签。接下来,确保勾选PubchemFingerprinter
框。(即您也可以尝试使用其他指纹类型,但重要的是只选择一种指纹类型,否则在分析过程中可能会混淆我们使用的是哪一种)。
最后,点击开始按钮,开始描述符计算过程。
4.3.检查输出文件
然后,检查生成的输出文件,以查看计算是否顺利,或者是否导致了错误。
4.3.1。成功运行
一次成功的运行应该会生成如下所示的输出descriptors.csv
文件:
相应的日志文件descriptors.csv.log
如下所示:
4.3.2。不成功的运行
但是,如果计算因错误而崩溃,您可能只会看到descriptors.csv
文件中的标题行。
对于日志文件,您可能会看到如下错误:
5.建模前的数据准备
在我们继续建模之前,我们首先必须将 X 和 Y 变量合并到同一个文件中。在第 4.2 节中,我们已经计算了描述符(即变量 X 变量),在本节中,我们将添加pIC50
列(即 Y 变量)作为最后一列。
请注意,在下面的动画图像中,我们创建了一个新文件,它结合了 X 和 Y 变量。最后,我们将文件保存为 CSV 文件。因此,我们将该文件命名为hcv.csv
。
显示 X 和 Y 变量组合的屏幕截图。
6.模型结构
现在我们有了预处理的数据集,让我们继续使用 WEKA 构建机器学习模型。
6.1.启动 WEKA
- 启动 WEKA 软件,您应该会看到以下用户界面:
- 继续点击浏览器。资源管理器窗口现在将启动。
6.2.加载数据集
- 点击最左侧
Preprocess
选项卡下的Open file…
按钮,加载数据集。这将弹出一个文件选择窗口,所以继续选择要加载的文件类型为CSV
,然后选择您之前准备好的hcv.csv
文件。
显示如何将 CSV 数据集加载到 WEKA 的屏幕截图。
- 让我们花一点时间熟悉一下用户界面。用户界面的每个组件都在下面的屏幕截图和说明段落中进行了编号。
解释 WEKA 用户界面的截图。
- 顶栏包含几个我们可以执行的机器学习任务标签,包括:
Preprocess
、Classify
、Cluster
、Associate
、Select attributes
和Visualize
。 - 后续栏包含几个与文件输入/输出相关的按钮,您可以在此加载和保存数据。
- 过滤器栏包含所有实用功能,允许您执行数百个数据处理任务。
- 当前关系栏包含关于数据集的信息:
Relation
(数据集名称)、Instances
(行数)、Attributes
(列数)和sum of weights
(等于实例数,因为实例没有加权)。 - 属性框列出了应用过滤器栏中的功能时可以勾选或取消勾选的所有变量(列)。
- 选择属性框包含变量的汇总统计,如最小值、最大值、平均值和标准偏差。
- 右下方的图框以柱状图的形式显示了数据分布的可视化。
6.3.数据预处理
让我们放弃所有的低方差变量。
- 点击过滤器标签下的
Choose
按钮。接下来,点击→weka
>filters
>unsupervised
>attributes
>RemoveUseless
- 点击
Apply
按钮,您将看到低方差变量将被移除。
注意: 注意,我们从最初的 882 开始变成 550;请注意,变量编号包括 X 和 Y 变量;另一点需要注意的是,WEKA 对 Class 变量有一个例外,它不会对 Y 变量应用低方差过滤器。
显示如何移除低方差特征的屏幕截图。
6.4.构建回归模型
6.4.1。建立模型(训练集)
现在,让我们构建一个线性回归模型,该模型是使用训练集构建的,并在训练集上评估该模型。
- 点击最顶端栏中的
Classify
选项卡。 - 点击分类器栏下的
Choose
按钮。接下来,点击weka
→classifiers
→functions
→LinearRegression
。 - 点击分类器栏下显示
LinearRegression
的白色栏,弹出一个窗口,允许您调整学习算法的参数设置。 - 在测试选项框中,选择
Use training set
单选按钮,以使用训练集执行模型构建。 - 点击开始按钮,启动模型建立过程。
注意:需要注意的是,本教程中还没有进行数据分割,最好保存到以后的教程中。或者你也可以把这个机会当作家庭作业,弄清楚如何进行数据拆分。(提示:预处理选项卡,滤镜→Choose
→weka
→filters
→unsupervised
→instance
→RemovePercentage
)。
显示如何建立线性回归模型的屏幕截图。
- 模型建立后,您将在分类器输出框中看到模型输出(线性回归方程)和模型性能(在底部)。
让我们看看从分类器输出框复制的模型性能。
=== Evaluation on training set ===Time taken to test model on training data: 0.03 seconds=== Summary ===Correlation coefficient 0.9231
Mean absolute error 0.3599
Root mean squared error 0.475
Relative absolute error 34.4828 %
Root relative squared error 38.4562 %
Total Number of Instances 578
在这里,您可以看到correlation coefficient
(即我们可以用来评估回归模型性能的指标;该度量测量实际值与预测值之间的相关性)为训练集提供了良好的性能。
6.4.2。构建交叉验证模型
现在,让我们构建一个 10 重交叉验证模型,将数据集分成 10 等份。接下来,这些部分中的 9 个被用作训练集并用于训练模型,然后应用该模型对作为测试集被遗漏的 1 个部分进行预测。这个过程总共迭代 10 次,每次迭代将使用不同的折叠作为测试集。最后,模型性能是这 10 个模型的平均值。
应该注意的是,交叉验证模型的计算时间将明显长于训练集的计算时间,部分原因是 10 个模型是为 10 重交叉验证而构建的。
- 点击
Cross-validation
单选按钮,并点击开始按钮。 - 默认情况下,折叠次数设置为 10 次(即即 10 次交叉验证),可以改为 5 次,即 5 次交叉验证。
6.4.3。应用模型对测试集进行预测
还记得前面提到的关于如何执行数据分割的提示吗?假设您已经执行了数据拆分,您将使用 80/20 的拆分比率将原始完整数据集拆分为两个独立的文件:1) training_set.csv 和 2) testing_set.csv。接下来,您可以通过在 training_set.csv 中加载来使用训练集,然后按照以下过程操作:
- 点击
Supplied test set
单选按钮,然后点击Set…
按钮,这将弹出一个要求测试集的窗口(你可以点击 testing_set.csv 文件)。 - 最后,点击开始按钮启动预测过程。
6.4.4。如何使用另一种学习算法
前面,我们已经建立了一个线性回归模型,在这一节中,我们将介绍如何选择另一种学习算法。
- 点击最顶端栏中的
Classify
选项卡。 - 点击
Choose
→weka
→classifiers
,会看到根据学习类型分组的不同类型的学习算法,如bayes
、functions
、lazy
、meta
、…、trees
。早些时候,我们想要建立一个线性回归模型,在functions
中可以找到这样做的函数。或者,如果我们想选择随机森林,我们可以点击trees
→RandomForest
。因此,整个序列将变成Choose
→weka
→classifiers
→trees
→RandomForest
。 - 点击分类器栏下的白色栏,显示学习算法的名称,如
LinearRegression
或RandomForest
,弹出一个窗口,允许您调整学习算法的参数设置。
结论
在本文中,您已经学习了如何为自己参与创建的药物发现数据集构建机器学习模型。
那么下一步是什么?下面是您接下来可以做的事情:
- 执行数据拆分
- 执行模型基准测试,即构建几个不同的模型,努力找到性能最佳的模型。您可以通过改变学习算法来构建几个模型,并比较最终的模型性能。
- 通过尝试使用不同的超参数集来执行超参数调整,以获得最佳模型。
如果您准备好了,可以在下面的文章中探索如何将 Python 用于数据科学:
补充视频
如何使用 WEKA 建立机器学习模型
在继续之前,应该注意的是,这篇文章是我就同一主题制作的 YouTube 视频的一个端口。这篇文章已经扩展到最好地传达教程。
视频展示了如何构建
用于药物发现的机器学习(用 2 分钟解释)
在这个 YouTube 视频中提供了关于如何使用机器学习进行药物发现的简明解释。
接下来读这些
- 如何用 Python 构建 AutoML App
使用 Streamlit 库的分步教程 - 学习数据科学的策略
打入数据科学的实用建议 - 如何免费搭建一个简单的作品集网站
不到 10 分钟从头开始的分步教程
✉️ 订阅我的邮件列表,获取我在数据科学方面的最佳更新(偶尔还有免费内容)!
关于我
我是泰国一所研究型大学的生物信息学副教授和数据挖掘和生物医学信息学负责人。在我下班后的时间里,我是一名 YouTuber(又名数据教授)制作关于数据科学的在线视频。在我做的所有教程视频中,我也在 GitHub 上分享 Jupyter 笔记本(数据教授 GitHub 页面)。
https://www.youtube.com/dataprofessor
在社交网络上与我联系
✅YouTube:http://youtube.com/dataprofessor/
♇网站:http://dataprofessor.org/(在建)
♇LinkedIn:https://www.linkedin.com/company/dataprofessor/
♇Twitter:https://twitter.com/thedataprof/
♇Facebook:http://facebook.com/dataprofessor/
♇github:https://github.com/dataprofessor/
ϝinsta
如何在 Python 中计算置信区间
原文:https://towardsdatascience.com/how-to-calculate-confidence-intervals-in-python-a8625a48e62b?source=collection_archive---------0-----------------------
关于如何在 Python 中计算置信区间的简便指南
照片由edge 2 edge MediaUnsplash
当我们测量一些东西时,我们总是要计算结果的不确定性。置信区间是一个非常有用的工具,用来计算一个范围,在这个范围内,我们可以找到具有一定置信度的可观测值的真实值。
什么是置信区间?
想象你问我身高。我可以说我身高 1.93 米,但我不会给你任何关于这个测量的不确定性的信息。置信区间是我们有一定的信心找到我们测量的可观测值的真实值的区间。科学家通常会寻找 95%的置信区间,但使用 90%甚至 99%也很常见。所以,当你问我的身高时,我应该用一个误差估计或者一个置信区间来回答你,比如“有 95%的把握我身高 1.92 米到 1.93 米”。
这就是这个工具给我们的:一个区间,在这里可以找到可观察的真实价值。
置信区间的一些有用属性是:
- 固定置信度,当样本量增加时,区间越来越窄。这是由于大数定律
- 固定样本中的点数,当置信度增加时,区间越来越宽。所以,要有更大的信心,就要有更大的区间。
在数据科学和统计学中,置信区间对于给出我们测量的科学结果非常有用,其他科学家可以用它来比较他们的结果和我们的结果。
置信区间公式
在本文中,我将介绍样本平均值的置信区间的计算,这是对总体期望值的估计。
给定 m 平均值、 s 样本标准差和 N 样本量,置信区间由以下公式定义:
有一个 t 参数,你可以看到,它与我们想要的置信度有关。这个参数的计算可以用不同的方式来完成。如果我们的样本量很小(即少于 30 点),我们可以使用学生的 t 分布来计算它。给定置信度,我们必须选择 t 的值,该值给出[ -t,t ]区间中的分布面积,该面积等于我们的置信度。
从数学上讲,给定一个等于 c 的置信度值, t 对应的值为:
其中 I(x) 是学生的具有 N-1 个自由度的逆累积分布函数。实际上,它是我们从 1 中减去置信度后,分布的右尾等于剩余面积的一半的值。这样,包含在尾部之间的面积就等于我们想要的置信度。
如果样本量很大(即大于 30 个点),我们可以用正态分布来近似学生的 t 分布,并忽略自由度。
这些分布背后的原因是中心极限定理的结果。对于大样本,样本平均值的行为类似于高斯变量(如果测量值是独立的且总体方差有限)。对于小样本量,我们使用学生的 t 分布。
使用引导程序
关注我的文章的人都知道我非常喜欢引导技术。这是因为它是一个无偏的算法,不对数据集的分布做任何假设。
我们可以使用 bootstrap 来计算置信区间,方法如下:
- 基于我们的数据集创建一个新的样本,替换掉相同数量的点
- 计算平均值并存储在数组或列表中
- 多次重复该过程(例如 1000 次)
- 在平均值列表中,计算 2.5%和 97.5%的值(如果您想要 95%的置信区间)
Bootstrap 给了我们一个无偏的估计,支付了复杂算法的计算成本。当编写这样的算法不成问题时,我更喜欢使用它,但通常在几乎所有情况下,您都可以安全地使用原始公式。
Python 中的置信区间计算器
现在让我们使用 Student 的 t 分布和 bootstrap 技术来计算 Python 中的置信区间。
让我们导入一些有用的库。
*import numpy as np
from scipy.stats import t*
现在让我们模拟一个数据集,它由从正态分布中提取的 100 个数字组成。
*x = np.random.normal(size=100)*
让我们看看我们要计算平均值的 95%置信区间。让我们根据置信区间的公式来计算我们需要的所有数字。
*m = x.mean()
s = x.std()
dof = len(x)-1
confidence = 0.95*
我们现在需要 t 的值。计算逆累积分布的函数是 ppf。我们需要应用绝对值,因为累积分布适用于左尾,所以结果将是负的。
*t_crit = np.abs(t.ppf((1-confidence)/2,dof))*
现在,我们可以应用原始公式来计算 95%的置信区间。
*(m-s*t_crit/np.sqrt(len(x)), m+s*t_crit/np.sqrt(len(x))) # (-0.14017768797464097, 0.259793719043611)*
我们知道这是正确的,因为正态分布的均值为 0,但如果我们对总体一无所知,我们可以说,在 95%的置信度下,总体的期望值介于-0.14 和 0.26 之间。
我们可以用无偏的 bootstrap 得出同样的结果。在这个例子中,我创建了数据集的 1000 个重采样(带有替换)。
*values = [np.random.choice(x,size=len(x),replace=True).mean() for i in range(1000)] np.percentile(values,[100*(1-confidence)/2,100*(1-(1-confidence)/2)]) # array([-0.13559955, 0.26480175])*
正如我们所看到的,这个结果几乎等于我们用封闭公式得出的结果。
结论
置信区间很容易计算,可以为数据分析师和科学家提供非常有用的见解。它们给出了非常强大的误差估计,如果使用正确,可以真正帮助我们从数据中提取尽可能多的信息。
Gianluca Malato 是一名数据科学家,在*http://www.yourdatateacher.com/上教授机器学习和数据科学。***
原载于 2021 年 11 月 8 日 https://www.yourdatateacher.com的 。**
如何在 Python 中计算用于交易的 Heikin Ashi 蜡烛
原文:https://towardsdatascience.com/how-to-calculate-heikin-ashi-candles-in-python-for-trading-cff7359febd7?source=collection_archive---------2-----------------------
让我们看看如何在 Python 中使用这个强大的交易工具
Heikin Ashi 烛台图表示例。图片由作者提供。
注来自《走向数据科学》的编辑: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语 。
定量交易者知道他们需要从价格图表中提取尽可能多的信息。价格波动是发现交易机会的一种非常有用的技术,但有时很难读懂,因为蜡烛图可能很乱或很嘈杂。所以,交易者需要一个工具来平滑价格波动并消除噪音。Heikin Ashi 蜡烛可以帮助我们。让我们看看怎么做。
什么是 Heikin Ashi 蜡烛?
Heiken Ashi 蜡烛图(有时称为 Heiken Ashi)是一种特殊的蜡烛图,试图消除价格波动的噪音。特别是,在这种图表中,没有间隙。
让我们看一张有普通烛台的标准普尔 500 图表。
标准普尔 500 海图。图片由作者提供。
正如你所看到的,每天都有很多缺口,蜡烛的影子有时很宽,让你很难决定该做什么。
Heikin Ashi 蜡烛是这样计算的:
- 打开:(打开(前一根蜡烛)+关闭(前一根蜡烛))/2
- 关闭:(开+低+关+高)/4
- 高:与实际蜡烛相同
- 低:与实际蜡烛相同
如您所见,计算今天的 HA 蜡烛图使用了今天和昨天的蜡烛图数据。这样,哈蜡烛顺利价格行动。
应用于同一图表的结果是:
标准普尔 500 图表与黑金阿什蜡烛。作者图片
如您所见,没有间隙,图表更容易阅读。
如何使用 Heikin Ashi 图表?
使用 HA 图表非常简单。首先,我们可以看到,在一个重要的反转之前,我们可以检测到一些旋转的顶部形态,即具有非常小的真实形体和几乎相同大小的大阴影的蜡烛。这是检测趋势反转的重要方法。
然后,我们可以看到,当趋势强劲时,对面的阴影几乎不存在(即在强劲的看涨趋势中,下部阴影是看不见的,而在强劲的看跌趋势中,上部阴影是看不见的)。这给了我们一个趋势强度的清晰概述。最后,颜色的变化经常被用来确认趋势已经改变了方向,也可以作为一个操作信号。
这些都是建立交易策略的有用工具,我们不需要像蜡烛图一样捕捉几种模式,但我们只需要发现旋转顶部和颜色变化。
Heikin Ashi 蜡烛线的缺点是,像任何其他类型的移动平均线一样,它们捕捉趋势反转有一些延迟。所以,他们的信号总是对已经发生的事情的确认。因此,只有当你需要长期策略时,它们才是有用的,因为信号的延迟会让你很晚进场和出场。然而,HA 蜡烛是一个非常有用的工具,特别是当你处理倒票和需要平滑非常嘈杂的价格行为时。就像任何其他指标一样,将它与另一个信号一起使用是很有用的,例如移动平均线。
现在让我们看看如何在 Python 中计算 Heikin Ashi 蜡烛。
Python 中的示例
对于本例,我们将分析 2020 年 12 月 15 日至 2021 年 4 月 15 日的标准普尔 500 数据。你可以在 GitHub 的这里找到完整的代码。
首先,让我们安装一些有用的库:
!pip install yfinance
!pip install mpl_finance
然后,让我们导入它们并应用一些图形增强:
import pandas as pd
import yfinance
from mpl_finance import candlestick_ohlc
import matplotlib.pyplot as pltplt.rcParams['figure.figsize'] = [12, 7]plt.rc('font', size=14)
现在我们可以下载标准普尔 500 的数据,并用一个连续的索引代替日期
name = 'SPY'
ticker = yfinance.Ticker(name)
df = ticker.history(interval="1d",start="2020-12-15",end="2021-04-15")df['Date'] = range(df.shape[0])
df = df.loc[:,['Date', 'Open', 'High', 'Low', 'Close']]
让我们创建一个简单的函数来绘制数据框的图表:
def plot_chart(df):
fig, ax = plt.subplots() candlestick_ohlc(ax,df.values,width=0.6, \
colorup='green', colordown='red', alpha=0.8) fig.tight_layout()fig.show()
现在,让我们看看最初的烛台图表:
plot_chart(df)
作者图片
如你所见,它充满了缺口和长尾。
现在,让我们根据原来的公式来计算 Heikin Ashi 蜡烛。由于我们需要检查前一根蜡烛,我们必须跳过第一行。
我们将把结果存储在一个名为 df_ha 的新数据帧中。我们复制蜡烛线的原始数据,以便保持相同的高点和低点。然后,我们删除第一行。
df_ha = df.copy()for i in range(df_ha.shape[0]):
if i > 0:
df_ha.loc[df_ha.index[i],'Open'] = (df['Open'][i-1] + df['Close'][i-1])/2
df_ha.loc[df_ha.index[i],'Close'] = (df['Open'][i] + df['Close'][i] + df['Low'][i] + df['High'][i])/4df_ha = df_ha.iloc[1:,:]
我们现在可以画出结果:
plot_chart(df_ha)
正如我们所看到的,缺口消失了,旋转的顶部 HA 蜡烛线能够很好地预测趋势反转。
结论
Heikin Ashi 蜡烛对于任何类型的交易者来说都是非常有用的工具,它必须出现在每个投资者的工具箱中。只是不要忘记平滑的价格行为是有延迟信号的代价的。
吉安卢卡·马拉托是意大利数据科学家和小说作家。他是数据科学、机器学习和数据分析在线学校【YourDataTeacher.com的创始人。
如何计算真实活跃用户?数字是多少?
原文:https://towardsdatascience.com/how-to-calculate-real-active-users-what-are-the-numbers-2a3a3363b4a4?source=collection_archive---------15-----------------------
为什么我不信任用户活动仪表板
用户群场景。作者图片
营销人员和机器学习工程师的完整 SQL 指南。茅、DAU 和 WAU。Firebase 和 BigQuery 示例。包括漂亮的报告模板。在本文最后阅读如何复制。免费的!
计算应用程序中的活跃用户可能有些棘手。你会怎么做?Count —活动的设备 id或活动的账户?
为了有效地计算您的活动用户数量,您需要将 deviceId 和 userId 组合在一起。
根据用户的不同,您可能会面临不同的情况,用户可能使用多台设备,可能在一台设备上拥有不同的帐户,并交叉使用彼此的设备和帐户。
这个教程讲的是什么?
这篇文章是关于如何使用 SQL 计算真实的月/日/周活跃用户指标。
您可以应用不同的方法来计算活跃用户数。本文旨在回答这些简单的问题:
- 什么是“活跃用户”?
- 我们如何统计拥有多种设备的用户?
- 我们如何统计在一台设备上拥有多个帐户的用户?
- 我们如何统计交叉使用彼此设备的用户?
- 如何可视化结果并创建仪表板?
- 如何识别真实用户?(例如,帮助标记垃圾邮件发送者)
我创建了这个得心应手的 数据 工作室模板 。请随意使用。
这篇文章是写给谁的?
- 可能希望看到真实情况的营销人员。
- 被要求构建用户活动报告和图表的分析师。
- 人工智能和人工智能专家可能希望在他们的模型中使用 MAU/DAU/WAU 标志作为分类特征。
什么是“活跃用户”
让我们假设每个客户端应用程序在运行时每天都会登录几次。每个登录事件都可以与用户 id 和设备 id 一起记录到您的数据湖/数据仓库中。
我之前在这篇文章中写过关于每日活跃用户的内容:
这就是 Firebase 记录用户的方式。默认情况下,您将拥有 user_pseudo_id,可以像这样启用 user_id:
https://firebase.google.com/docs/analytics/userid
活跃用户通常被报道为月活跃用户(MAU) ,周活跃用户(WAU) ,以及日活跃用户(DAU) 。让我们用一个可视化的例子来进一步说明活跃用户:
每日活跃用户。作者图片
在上图中,您可以看到用户注册后每天登录。每一个彩色圆圈都暗示着用户在那天很活跃。用户‘J’
在第 1-6 周非常活跃。不过还是算 1 MAU(月活跃用户)。因此,我们可以看到该月有 2 个活动用户,因为所有用户在该月都至少活动过一次。
如果一个用户在一个月的每一天都访问你的应用程序,那就是单个用户。 不是 30 个不同的用户。
让我们看看这个样本数据集,并在 BigQuery 中运行它:
您可能注意到,用户 id“E01”在下面的数据集中有 2 个设备 ( user_pseudo_id 2001 和 2000 )。
我们计算了用户,这就是为什么它是 2(不是 3) MAU。
所以毛/DAU 数完全取决于你应用于数据的方法。
如果一个用户打开了你的应用,然后卸载了它——这是一个日常活跃用户吗?对于许多仪表板,是的,这是因为它们将设备 id 算作用户。
我们如何计算月/日/周活跃用户?
没有任何一个 T21 DAU 的标准是完美的。现实世界的问题,如越狱设备,意味着在任何计算中总会有一些不确定性。
从下面图表中的四个不同场景,我们可以有把握地计算前三个场景的 DAU。第四种情况是,一个人有几个帐户,但只在不同的设备上使用它们,这是不可能检测到的。计算依赖于在一台设备上使用多个帐户。
用户场景。作者图片
DAU 计算
方法一。计数唯一设备
…如果一个用户有多个 device _ ids,则只替换一个。
例如:
假设我们有两个用户约翰和艾玛。约翰有一部 Iphone ,艾玛有安卓和两个设备:
所以这里我们可以看到 3 个设备和 3 个用户账号= 2 个真实用户。简单。
如何计算 DAU:
运行下面的 SQL,你将得到 2 DAU 。
对我个人来说,这个方法不是最好的,我会解释为什么。
首先这个不靠谱:
select user_id ,min(user_pseudo_id) as device_id
from ua
group by 1
;
的确,在device_id
弦上做 MIN 可能是错误的。事实上,在某些情况下,它可能是正确的,因为下面的这个小东西。
让我们想象一下这种情况。
艾玛有一个 第二个 用户账号,她正在她的平板电脑 上使用它,这是她的第二个设备,遇到了一个应用错误 并决定 重新安装 应用程序。对于DAU的计算我们假设这一切都发生在同一天。她的 device_id 在平板电脑上会与新的不同。我们永远不知道新的 device_id 会是什么样子,并且这里的 MIN 函数会使用黑盒。运行下面的 SQL,你就会明白为什么了。
DAU 将是 3 岁,而实际上是 2 岁。):
实际上我对 3 点没意见。越高越好。但是,根据业务逻辑,它必须是 2。
方法二。
…计算所有用户设备的关联账户。
这是一个棘手的方法,我必须承认,我花了一些时间试图想出最好的解决方案,用 SQL 链接所有活跃用户的帐户。
在这个场景中,我们将看到更复杂例子。还记得不同场景的插图吗?
用户场景。作者图片
让我们看看他们每个人的数据会是什么样子。
- Sceanrio 0。最简单的一个。用户 Id
J
只有一个设备,在 2020 年 10 月 10 日活动:
*(‘1000’ as user_pseudo_id, ‘J’ as user_id, date ‘2020–10–10’ as dt),*
2.场景 1。当一台设备存在多个账户时,我们假设只有一个用户。例如,设备 id 为“2000”的用户有两个帐户。我们称之为用户‘E’:
*(‘2000’,’E01',date ‘2020–10–10’),
(‘2000’,’E02',date ‘2020–10–10’),*
3.场景二。如果一个帐户有多个 device _ ids,我们只计算一个。例如,用户“P01”有两台设备:
*(‘3000’,’P01',date ‘2020–10–10’),
(‘3001’,’P01',date ‘2020–10–10’),*
4.场景三。现在我们来看看下面这个。用户' D '在 2 台设备上有 3 个帐户。因此,我们在设备 id '4000 '上有两个帐户,在设备' 4001 '上有两个帐户。问题是我们不能应用场景 1(其中一个设备存在多个帐户,我们假设它只是一个用户)。事实上,如果我们使用这个逻辑,我们将得到 2 个 DAU(设备‘4000’和‘4001’)
——而在现实生活中可能只有一个用户。例如:
*(‘4000’,’D01',date ‘2020–10–10’),
(‘4000’,’**D02**',date ‘2020–10–10’), — 4000, 4001 | D01, D02
(‘4001’,’**D02**',date ‘2020–10–10’), — 4000, 4001 | D02, D03
(‘4001’,’D03',date ‘2020–10–10’)*
使用 D02 我们可以链接账户 D01 和 D03 。
也可能是 3。例如,共享 PC 或平板电脑的家庭。
我们真的不知道,所以让我们称这些帐户为“关联的”,并使用设备和帐户足迹将它们标记为一个帐户。
那么我们如何用 SQL 做到呢?
在这种情况下,我们需要检查是否有另一个相同账号的设备在使用它。
在 BigQuery 中运行以下 SQL:
关联设备和关联账户。作者图片
使用该数据集,您可以生成显示链接用户的报告。例如:
链接用户报告
结论
在本教程中,我们构建了一个漂亮的仪表板,按照简单的示例和不同的用户场景显示日活跃用户数量和关联账户。事实上,在许多情况下,数字根本不能反映真实情况。例如,重新安装应用程序或任何删除设备的操作都会产生新的device_id
标识符,这可能会也可能不会增加总 DAU 号码。以及任何越狱设备或用户垃圾邮件活动可能会大大增加您的 DAU,使其不准确。
这个动手项目演示了如何使用 SQL (BigQuery 标准 SQL)和 Google Data Studio 将用户与多个帐户和多个设备联系起来,并创建一个定制的分析工具,该工具可以轻松调整到任何业务逻辑或方法。这是一个简单的 BI 解决方案,可以更好地了解用户群。
感谢阅读!
如何使用该模板
- 点击此链接并点击使用模板
作者图片
复制模板。作者图片
2.单击复制包含数据集的报告:
作者图片
3.有些部件会显示为损坏,但单击一个部件,然后单击编辑
作者图片
4.选择您的计费项目并点击重新连接:
作者图片
成功了!
作者图片
推荐阅读:
*https://medium.com/build-the-right-thing/key-app-metrics-with-bigquery-part-1-dau-mau-9eac7cbdbe04 https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators https://support.google.com/datastudio/answer/6283323?hl=en
https://help . amplitude . com/HC/en-us/articles/115003135607-Tracking-Unique-Users*
你也可以计算回归模型 ROC 曲线
原文:https://towardsdatascience.com/how-to-calculate-roc-auc-score-for-regression-models-c0be4fdf76bb?source=collection_archive---------6-----------------------
他们可能告诉你 ROC 曲线下的面积不能计算连续的目标变量。他们错了。下面是如何用 Python 实现的。
[作者图]
你是一家拍卖公司的数据科学家,你的老板让你建立一个模型来预测在售物品的锤价(即最终售价)。这种模式有两个目的:
- 为每件商品设定一个有意义的开价;
- 在拍卖过程中每隔一段时间放置最贵的物品。这样,你就会保持住观众的注意力。
因为您想要预测一个点值(以美元为单位),所以您决定使用一个回归模型(例如,XGBRegressor()
)。现在,你如何评价你的模型的性能?
让我们看看 Scikit 的回归模型度量工具箱:
Scikit-learn 的回归度量[ 链接 ]。
所有这些指标都试图量化模型预测与实际值的差距。事实上,如果你看一看他们的公式,你总会发现这个量:
实际值和模型预测值之间的差异。[作者图]
换句话说,这些指标非常有助于评估接近真实价格(第一个目标)的能力。但是它们对评估第二个目标毫无用处,第二个目标是将物品从最贵到最便宜排序的能力。
想要个例子吗?假设您的模型的第一个版本提供了这些结果:
y_true = [1000.0, 2000.0, 3000.0, 4000.0, 5000.0]
y_pred = [1100.0, 1300.0, 4000.0, 4800.0, 5200.0]
从图形上看,
在回归问题中比较真实值和预测值。[作者图]
如果拿mean_absolute_error(y_true, y_pred)
的话,得到 560 美金,大概不太好。但是,排名很完美!这意味着该模型完全能够辨别哪些物品将以更高的价格拍卖。
这是关于我们模型的一个非常重要的信息,这是我们从其他回归指标中感受不到的。但是我们如何衡量回归模型的排序能力呢?
评估预测模型排序能力的最流行的指标是roc_auc_score
。所以,让我们试着用我们的数据来计算一下…
[作者图]
我们得到一个错误!
这是因为roc_auc_score
只适用于分类模型,要么是一个类对 rest(“ovr”),要么是一个对一个(“ovo”)。Scikit-learn 希望找到离散的类到y_true
和y_pred
,而我们传递连续的值。
为此,我们需要将 **roc_auc_score**
的概念扩展到回归问题。我们将这样的度量标准称为regression_roc_auc_score
。在下一段中,我们将了解如何计算它。
寻找“回归 _roc_auc_score”
直观上,regression_roc_auc_score
应当具有以下性质:
- 和
roc_auc_score
一模一样,应该是有界在 0(最差可能排名)和 1(最好可能排名)之间,0.5 表示随机排名。 - 当目标变量为二进制时,
regression_roc_auc_score
必须给出与roc_auc_score
相同的结果(这样,这个度量将是roc_auc_score
的推广)。
现在,如何获得我们正在寻找的度量?
roc_auc_score
定义为 ROC 曲线下的面积,ROC 曲线是在所有分类阈值下,x 轴为假阳性率,y 轴为真阳性率的曲线。但是不可能用回归方法计算 FPR 和 TPR,所以我们不能走这条路。
幸运的是,我们有另一个定义。事实上,根据维基百科,roc_auc_score
与“一个分类器将随机选择的正面实例排列得比随机选择的负面实例更高的概率”相一致。
换句话说,如果我们取任意两个观察值 a 和 b 使得 a > b ,那么 **roc_auc_score**
等于我们的模型实际上排名 a 高于 b 的概率。
这个定义对我们更有用,因为它对回归也有意义(事实上 a 和 b 可能不限于 0 或 1,它们可以假设任何连续值);
此外,现在计算roc_auc_score
要容易得多。事实上,它归结为考虑每一对可能的项目 a 和 b ,这样 a > b ,并计算我们的模型对 a 的预测值实际上比对 b 的预测值高多少倍(最终的平局将被计算一半)。那么,roc_auc_score
就是成功的次数除以配对总数。
在 Python 中,这将是:
naive_roc_auc_score 的 Python 代码。[作者代码]
为了确保维基百科提供的定义是可靠的,让我们将我们的函数naive_roc_auc_score
与 Scikit-learn 的结果进行比较。
[作者图]
太好了!
如上所述——与 Scikit-learn 的roc_auc_score
不同——这个版本也适用于连续的目标变量。让我们试一试:
[作者图]
产量正是我们所期望的。排名是完美的,因此roc_auc_score
等于 1。
从天真到自举
一切看起来都很棒,但上面的实现有点幼稚。事实上,naive_roc_auc_score
评估每一对可能的观察值。这样就需要 O( n )次迭代(其中 n 为样本数),一旦 n 变大一点就变得不可用。
然而,如果我们不需要“精确”的答案,我们可以通过自举获得一个很好的近似值。我们可以使用许多随机选择的对,而不是评估每一个可能的对(这意味着不少于 n *( n +1)/2 对)。
这将转化为以下 Python 代码:
回归 _roc_auc_score 的 Python 代码。[作者代码]
regression_roc_auc_score
有三个参数:y_true
、y_pred
和num_rounds
。如果num_rounds
是整数,则作为随机对的个数来考虑(近似解)。然而,您也可以通过将字符串"exact"
传递给num_rounds
来计算“精确的”分数(即所有可能的配对)。
给我看一些真实的数据!
你很想看看函数regression_roc_auc_score
在真实数据集上的结果吗?我也是,所以让我们在一个经典数据集上使用它来解决回归问题:来自 StatLib 的 California Housing(数据可以直接从 Scikit-learn 导入,这是 BSD 许可下的)。
目标变量是加州各区的房价中值。该数据集由 20,640 个样本和 8 个观察到的特征组成。
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_splitX, y = fetch_california_housing(return_X_y = True, as_frame = True)
y *= 100000X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.33, random_state = 4321)
现在,让我们在训练集上尝试许多不同的模型,然后在测试集上计算一些指标(包括前面段落中定义的regression_roc_auc_score
)。
from sklearn.dummy import DummyRegressor
from sklearn.neighbors import KNeighborsRegressor
from sklearn.linear_model import LinearRegression
from sklearn.svm import SVR
from sklearn.neural_network import MLPRegressor
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import GradientBoostingRegressor
from xgboost import XGBRegressor
from catboost import CatBoostRegressor
from sklearn.metrics import mean_absolute_error, median_absolute_error, roc_auc_score, r2_score, explained_variance_scoremodelnames = [
‘DummyRegressor()’,
‘KNeighborsRegressor()’,
‘LinearRegression()’,
‘SVR()’,
‘MLPRegressor(hidden_layer_sizes = (16, 16))’,
‘DecisionTreeRegressor()’,
‘GradientBoostingRegressor()’,
‘XGBRegressor()’,
‘CatBoostRegressor()’
]metricnames = [
‘mean_absolute_error’,
‘median_absolute_error’,
‘r2_score’,
‘explained_variance_score’,
‘regression_roc_auc_score’
]metrics = pd.DataFrame(index = modelnames, columns = metricnames)for modelname in modelnames:
model = eval(modelname)
pred_test = model.fit(X_train, y_train).predict(X_test)
for metricname in metricnames:
metrics.loc[modelname, metricname] = eval(f'{metricname}(y_test, pred_test)')
下面的图比较了所有训练模型的regression_roc_auc_score
和mean_absolute_error
:
比较不同模型的 regression_roc_auc_score 和 mean_absolute_error。[作者图]
正如我们所料,这两个指标是反向相关的。当然,较低的mean_absolute_error
往往与较高的regression_roc_auc_score
联系在一起。
后一个指标提供了关于模型性能的额外知识:在计算了regression_roc_auc_score
之后,我们可以说,在给定 a > b 的情况下,Catboost 估计 a 比 b 更高的值的概率接近 90%。
感谢您的阅读!我希望你喜欢这篇文章。
我感谢反馈和建设性的批评。如果你想谈论这篇文章或其他相关话题,你可以发短信给我我的 Linkedin 联系人。
如何计算平均值和标准差—在 Pytorch 中归一化数据集
原文:https://towardsdatascience.com/how-to-calculate-the-mean-and-standard-deviation-normalizing-datasets-in-pytorch-704bd7d05f4c?source=collection_archive---------5-----------------------
如果输入数据是标准化的,神经网络收敛得更快。了解如何计算自己数据集的平均值和标准差。
露丝·齐默曼在 Unsplash 上拍摄的照片
为什么归一化允许更快的收敛
数据集的规范化通常被视为一项相当平凡的任务,尽管它会强烈影响神经网络的性能。对于非标准化数据,特征的数值范围可能变化很大。以一个机器学习应用程序为例,在该应用程序中,房价是根据几个输入(表面积、年龄等)来预测的。表面积通常在 100 到 500 米之间,而年龄更可能在 0 到 25 岁之间。如果将这些原始数据输入到我们的机器学习模型中,将会出现缓慢的收敛。
如左图所示,搜索最陡的梯度,这在某种程度上是正确的方向,但也拥有相当大的振荡部分。这可以通过对学习率的推理来解释。表面积特征需要相对较大的学习速率,因为其范围相当大。但是这个大的学习率对于年龄来说太大了。优化器每一步都会超调,这会导致振荡,从而导致收敛缓慢。
标准化数据允许更快的收敛
可以通过减去每个特征的平均值( )并除以标准差(σ)来对数据进行归一化。这样,每个特征的平均值为 0,标准差为 1。这导致更快的收敛。
在机器视觉中,每个图像通道都是这样标准化的。
计算数据集的平均值和标准差
首先,需要一些进口。
我将使用 CIFAR 数据集及其彩色图像作为例子。但是,同样的代码也适用于灰度图像的 MNIST 数据集。
训练示例被下载并转换为张量,之后加载器获取 64 个图像的批次。
必须对所有图像、图像的高度和宽度计算平均值,但不能对通道进行计算。在彩色图像的情况下,期望大小为 3 的输出张量。
标准偏差可通过以下公式计算:
E[X ]表示平方数据的平均值,而(E[X])表示数据平均值的平方。
最后,计算 CIFAR 数据集的平均值和标准偏差。
Mean: tensor([0.4914, 0.4822, 0.4465])
Standard deviation: tensor([0.2471, 0.2435, 0.2616])
将标准化集成到您的 Pytorch 管道中
数据加载器必须结合这些标准化值,以便在训练过程中使用它们。因此,除了 ToTensor() 变换之外,随后是利用获得的值的归一化。
请注意,由于网络是在归一化图像上训练的,因此每个图像(无论是验证还是推断)都必须用相同的获得值进行归一化。
来自 CIFAR 数据集的归一化图像示例
结论
数据规范化是神经网络训练过程中的一个重要步骤。通过将数据归一化为 0 的统一平均值和 1 的标准偏差,可以实现更快的收敛。
如果您有任何问题,请随时联系我!
如何使用人工智能大写单词
原文:https://towardsdatascience.com/how-to-capitalize-words-using-ai-13750444d459?source=collection_archive---------16-----------------------
NLP 的 truecasing 教程,带实际操作代码。
你有没有面对过一个庞大的文本语料库缺少单词的大写?在发表这篇文章之前,你需要大写 1000 个单词。在这篇文章中,我演示了如何自动修复文档中的案例信息。
布雷特·乔丹在 Unsplash 上拍摄的照片
真实大小写是一个自然语言处理问题,在没有信息的文本中找到单词的正确大写。
使用案例包括来自各种音频源的抄本、自动语音识别、光学字符识别、医疗记录、在线消息和游戏。原始文本源通常是匆忙生成的,大多数单词都是小写的。
有几种解决真实大小写问题的实用方法:
- 句子分割:将输入的文本分割成句子,并将每个句子的第一个单词大写。
- 词性标注:查找句子中每个单词的定义和上下文,并使用特定的标签大写单词,例如名词。
- 名称-实体-识别(NER) :将句子中的单词分类成特定的类别,并决定大写字母,例如人名等。
- 统计建模:对通常以大写格式出现的单词和一组单词训练一个统计模型。
我提出了一个简单的实际操作的 truecaser,它结合了句子分割和词性技术,如下所示。
算法正确地将单词 stone 的第一个实例识别为人名,应该大写。
该方法在不区分大小写的大型文档集上表现如何?下面我使用众所周知的 Yelp 数据集中的评论对代码进行子弹测试。文本在被我的代码处理之前是小写的。使用 BLEU score 将生成的大写文本与原始版本进行比较。
通过比较预测大写和真实大写之间的 n-grams 的数量,我们获得 86.71%作为真实大写修复质量的度量。
在这篇文章中,我讨论了 truecaser,将大小写信息恢复为大小写错误或无大小写的文本的过程,并且我提出了一个 truecaser,它与专业撰写的商业评论有 86%的一致性。真实大小写有助于其他 NLP 任务,如自动内容提取和机器翻译,以提高准确性。
如何在 Arduino 中捕获传感器数据,并使用 PySerial 在 Python 中读取它
原文:https://towardsdatascience.com/how-to-capture-sensor-data-in-an-arduino-and-read-it-in-python-using-pyserial-ae66a04637b1?source=collection_archive---------41-----------------------
实践教程
从 Arduino Nano 33 BLE 中获取传感器数据
传感器感知。它们能看到、听到和闻到我们人类无法(或不应该)看到、听到或闻到的东西。传感器数字化。通过视觉、听觉和嗅觉,他们量化和数字化我们的周围环境——他们创造数据。配备传感器的 Arduino 就是这种设备的一个例子。这些设备“感知”它们的周围环境,并用数据解释它们。也许你想知道如何提取这些数据。
本文解释了如何从 Arduino 中捕获多个传感器数据,并使用 Python 和库 PySerial 读取这些数据。我将使用的 Arduino 是 NANO 33 BLE ,这是一款配备了超过 5 个传感器的微处理器,除了其他功能之外,还可以测量温度、环境压力和湿度。在文章的第一部分,我将描述如何编写一个 Arduino 程序,从它的传感器获取数据;在第二部分,我将描述如何编写 Python 脚本来读取 Arduino 的数据并将其写入 CSV 文件。
我的 Arduino
步骤 1 —编写 Arduino 草图以捕捉传感器数据
在这一节中,我们将编写 Arduino 的草图(Arduino 程序的正式术语)来捕获传感器数据。我们一起经历吧。
#include <Arduino_HTS221.h> // Temperature sensor
#include <Arduino_LPS22HB.h> // Air pressure sensor
#include <Arduino_APDS9960.h> // Color, light, and proximity sensor
#include <Arduino_LSM9DS1.h> // Accelerometervoid setup() {
Serial.begin(9600);
while (!Serial);if (!HTS.begin()){
Serial.println("Failed to start the HTS221 sensor.");
while(1);
}if (!BARO.begin()) {
Serial.println("Failed to start the LPS22HB sensor.");
while (1);
}if (!APDS.begin()) {
Serial.println("Failed to start the APDS9960 sensor.");
while (1);
}if (!IMU.begin()) {
Serial.println("Failed to start the LSM9DS sensor.");
while (1);
}}void loop() {
// Read the temperature and humidity values
float temp = HTS.readTemperature(); // In C
float humidity = HTS.readHumidity(); // In %
float pressure = BARO.readPressure(); // In kPaint r, g, b, a;
APDS.readColor(r, g, b, a);float x, y, z;
IMU.readAcceleration(x, y, z);while (!APDS.colorAvailable() || !APDS.proximityAvailable())
{
}Serial.print(temp);
Serial.print(',');
Serial.print(humidity);
Serial.print(',');
Serial.print(pressure);
Serial.print(',');
Serial.print(r);
Serial.print(',');
Serial.print(b);
Serial.print(',');
Serial.print(g);
Serial.print(',');
Serial.print(a);
Serial.print(',');
Serial.print(x);
Serial.print(',');
Serial.print(y);
Serial.print(',');
Serial.print(z);
// Use Serial.println(); to add a linebreak// 10 mins
delay(600000);
}
我们的(C++)代码从加载传感器库的 include 语句开始。这些是:
- HTS221 :温度传感器
- LPS22HB :压力传感器
- APDS9960 :读取颜色、光线和接近度的传感器。
- LSM9DS1 :加速度传感器。
加载完库之后,我们有了setup
函数,这个函数在草图开始时只被调用一次。在这里,我们将定义串行端口,我们希望在这里写入输出并初始化四个传感器。while
语句用于无限迭代,直到串口和传感器可用。
下面的函数是loop
,草图是主要程序,我们将在这里捕获传感器数据——该函数将永远运行,除非您终止它或出现错误。在前三行中,我们读取温度、湿度和压力值,并将它们分配给三个变量。接下来,我们将读取 APDS 传感器颜色红色、蓝色、绿色和环境光强度。(我应该提到,红色、蓝色和绿色不是标准的 RGB 颜色元组,其值的范围是从 0 到 255。相反,它们的值类似于红色、蓝色和绿色的强度。).为了读取颜色数据(使用APDS.readColor()
),我们将发送前面的四个变量作为参数,将读取的值传递给它们。类似地,我们将使用与颜色相同的方法读取加速度计数据。有了这些,我们就有了数据。
函数的后半部分涉及将捕获的值写入串行端口,以便稍后从 Python 中读取它们。在IMU.readAcceleration
之后,while
语句等待,直到 APDS 传感器上有颜色或接近度可用。一旦其中一个可用,程序将退出循环,并以逗号分隔( CSV )行的形式打印这些值,例如,“1,2,3,4,5”最后,我们将添加一个delay()
函数来暂停程序一段时间(以毫秒为单位),这段时间在参数中指定(您可以根据需要随意更改)。
接下来,我们将使用 Arduino IDE 将草图上传到 Arduino 板上,你可以从https://www.arduino.cc/en/software获得。你可以在 https://www.arduino.cc/en/Guide找到安装指南。
一旦安装并打开,我们需要安装 Arduino 板和传感器库。要安装板库,进入工具->-板->-板管理器,搜索“纳米 BLE”要安装传感器库,进入工具->-管理-库和-搜索“HTS221”、“LPS22HB”、“APDS9960”和“LSM9DS1”现在,请将 Arduino 连接到电脑。然后点击“箭头”按钮将草图上传到 Arduino。为了确保它正在运行,进入工具->-串行-监视器查看它的输出(图 1)。你会注意到缺少换行符。那很好。一旦我们从 Python 中读取数据,我们就不需要它了,这将在下一步中完成。
图一。打印的数据。这里我们有两组传感器读数,中间没有换行。我们将在 Python 端处理这个问题。
步骤 2 —使用 PySerial 读取 Python 中 Arduino 的数据
在第一步中,我们编写了一个 Arduino 草图,它从多个来源捕获传感器数据,并将它们打印到一个串行端口。在步骤 2 中,我们将编写一个 Python 脚本,它使用库 PySerial 逐行读取所述数据,因为 Arduino 将它打印到串行端口;要安装 PySerial,从您的终端执行$ pip install pyserial
。在读取数据时,我们将把值转换成一个列表,并在把列表附加到一个 CSV 文件之前把当前的本地时间戳添加到列表中。下面是完整的脚本。
import csv
from time import timeimport serial# Your serial port might be different!
ser = serial.Serial('/dev/cu.usbmodem141301', timeout=1)f = open("df.csv", "a+")
writer = csv.writer(f, delimiter=',')while True:
s = ser.readline().decode()
if s != "":
rows = [float(x) for x in s.split(',')]
# Insert local time to list's first position
rows.insert(0, int(time()))
print(rows)
writer.writerow(rows)
f.flush()
我们将通过导入我们将使用的库来启动脚本。这些是:
csv
:将数据写入 CSV 文件。time
:获取当前当地时间。serial
(PySerial):读取 Arduino 的数据。
接下来,我们需要声明我们的Serial
对象,以便从参数中指定的端口读取数据。在本例中,我从端口/dev/cu.usbmodem141301
读取数据,但这可能会因您的设置而异。为了找到正确的端口,我喜欢使用 Arduino IDE 的“端口”视图,您可以从工具->-端口中访问该视图(图 2)。这里你会看到两个串行端口:一个蓝牙和一个物理端口。你想要非蓝牙端口。将它的路径写在串行对象的第一个参数中。第二个参数 timeout 控制函数等待的时间(以秒为单位),直到所请求的字节数到达(我们将在后面添加)。如果请求的字节数在超时前没有到达,函数"返回在此之前收到的所有字节(py Serial 的串行类文档)。
图二。您可以从“工具”菜单中找到主板的串行端口。
因为我们的脚本将 Arduino 的数据写入一个 CSV 文件,所以我们需要一个csv.writer
对象将数据追加到文件中。编写器有两个参数,f
,目标文件和delimiter
" ,
"来指定哪个字符分隔字段。
现在我们写数据。为了无限期地运行我们的脚本,我们将使用一个while True
循环来读取发送到串行端口的最新行——注意,我们必须解码数据,因为它是以字节形式出现的。(说到字节,readline()
有一个参数 size s
用来指定函数最多会读取多少字节;我们将使用参数的默认值-1
来读取所有内容)。每当我们读一行,我们将检查它是否是空的。如果是,我们再次迭代。但是如果不是——这是令人兴奋的部分——我们将在将数据添加到文件之前对其进行预处理。
我们不会写入数据,因为它来自串行端口。相反,我们将对其进行预处理,并用本地时间对其进行扩展,以获得更丰富的数据集。在if
语句中,我们将使用 list comprehension 来创建一个新的列表,方法是分割字符串,使用字符",
"作为分隔符(因为这是我们在 Arduino 上打印数据的方式),并将值从字符串转换为浮点数。对于这个列表,我们将在它的第一个位置插入当前本地时间戳(以秒为单位)。然后,我们将打印它,将其写入 CSV,并在之后刷新该文件。就这样,我们结束了!
要运行脚本,请执行命令$ python main.py
。如果您得到一个类似这样的错误,
FileNotFoundError: [Errno 2] No such file or directory: '/dev/cu.usbmodem141301'
这意味着定义的串口是错误的或不可用的。我再次建议使用 Arduino IDE 来找到正确的端口。另一种方法是列出端口,如以下网址所述:https://www . mathworks . com/help/support pkg/arduinoio/ug/find-arduino-port-on-windows-MAC-and-Linux . html。运行脚本几分钟后,返回 CSV 文件查找数据。下面的图 3 显示了我的一个例子。
图 3。我的 CSV 文件样本。缺少列名;我没有从脚本中添加它们,以防你使用我以外的数据。
总结和结论
我们人类正以稳定的节奏赋予科技感知的能力。会达到类似人类的水平吗?我不知道。但是根据基于感知的人工智能(正如李博士在他的书人工智能超能力中所讨论的)的准确性和用例来判断,例如物体探测器,我们可以肯定地说,它会让我们怀疑我们人类在某些任务中是否优越。
在本文中,我们没有构建这样的人工智能。相反,我们收集了我们需要的数据,以防我们想要建立一个。为了收集数据,我们在 NANO 33 BLE 设备中编写并部署了一个 Arduino 草图,该设备配备了可以捕捉温度、压力、湿度、亮度和加速度数据的传感器。为了导出数据,我们编写了一个 Python 脚本,从 Arduino 中读取数据,并将其写入一个 CSV 文件。
你会用它来建造什么?您将如何使用这个新数据集?由于这个 Arduino 支持用于微控制器的 TensorFlow Lite】,这是一个用于在微控制器上执行 TensorFlow 模型的 TensorFlow C++库,我计划用数据构建一个模型,并将其部署在设备上。模型会做什么?目前为止还没想。但不管是什么任务,我肯定它会比我做得更好。
你可以在https://github . com/juandes/arduino-content/blob/main/sketches/get _ sensor _ data/sketch/sketch . ino找到草图代码,在https://github . com/juandes/arduino-content/blob/main/Python/py serial/main . py找到 Python 脚本。
如何捕获 Power BI 生成的 SQL 查询
原文:https://towardsdatascience.com/how-to-capture-sql-queries-generated-by-power-bi-fc20a94d4b08?source=collection_archive---------9-----------------------
面带微笑,向您的 DBA 提供关于 Power BI 生成的 SQL 查询的所有必要信息
https://www . pexels . com/photo/cute-dog-in-bright-shirt-on-light-background-5733428/
从前,你那吓人的老 DBA 红着脸走进你的办公室,愤怒地问你:“你到底对你的 Power BI 报告做了什么?!它扼杀了我们所有的工作负载!!!"
你知道他为什么生气,甚至在他对你大喊大叫之前。这是因为使用 DirectQuery 的“那个”报告,因为您的用户想要“接近实时”的数据…
我已经写了为什么你应该重新考虑使用 DirectQuery ,以及在什么情况下(可能)走这条路是有意义的。
然而,看起来您的 DBA 并没有您想象的那么“糟糕”。他提出帮助您优化最详尽的 SQL 查询,他只是希望您将这些查询发送给他…
哦,等等,当我在 Power BI 中“看不到”SQL 查询时,我如何向他发送这些查询呢?!别担心,有多种方法可以捕获 Power BI 引擎生成的 SQL 查询。
SQL Server 事件探查器—面向传统人士!
https://www . pexels . com/photo/vintage-car-on-parking-in-mountains-5480749/
在我向您展示如何使用优秀的 SQL Server Management Studio (SSMS)及其内置功能 SQL Server Profiler 之前,让我简单解释一下后台发生的事情:Power BI Desktop 启动了分析服务表格式的本地实例。因此,您可以使用 SQL Server 事件探查器像跟踪任何其他事件一样跟踪此实例。
像往常一样,我将在所有示例中使用示例 Contoso 数据库。
您要做的第一件事是打开 SSMS 工具栏下的 SQL Server Profiler:
作者图片
我的 Power BI 报告相当简单,它只包含三种视觉效果:
作者图片
关于 DirectQuery,要记住的最重要的事情是——每当您与报表进行交互时,每个视觉对象都将向数据源发出查询,即使您没有与特定的视觉对象进行交互!在我的示例中,每当我对报表进行操作时,就会有两个单独的查询被发送到底层的 Contoso SQL 数据库。
让我们打开 SQL Server Profiler,检查一下发生了什么:
作者图片
在这里,您可以看到,当我更改我的日期切片器的值时,Power BI 触发了两个单独的查询(针对我们的每个视觉效果)!您可以在 SQL: BatchCompleted 事件类下看到关于每个查询的更多细节:执行用了多长时间,进行了多少次读取,等等。
但是,最重要的是,您可以捕获 Power BI 生成的 SQL:
作者图片
现在,您可以复制这个查询并发送给您的 DBA,这样他就可以决定是否有性能改进的空间(可能是添加索引或者其他什么)。
无论如何,您现在已经准备好帮助查找影响常规工作负载的 SQL 查询了。
DAX Studio —简单而优雅的解决方案!
https://www . pexels . com/photo/cute-dog-in-bright-shirt-on-light-background-5733428/
如果您不熟悉 SQL Server Profiler 和其他“传统”工具(当我说传统时,我指的是您的 DBA 喜欢的工具:)),您可以利用 Power BI Desktop 本身的性能分析器特性,与 DAX Studio 协同工作,以达到相同的效果!
作者图片
只需刷新视觉效果,您应该能够在报告画布上看到每个视觉效果的总时间:
作者图片
选择复制查询选项,然后直接进入 DAX Studio。将复制的查询粘贴到主窗口后,向下滚动,您将看到 SQL 查询!多酷啊!
作者图片
我有一个额外的建议给你!如果您有多个查询(例如我们的例子中有两个,但有时可能会有 10 个以上),那么来回移动、一个接一个地复制和粘贴查询会非常麻烦。
您应该在 DAX Studio 中启用“所有查询”按钮,并等待几分钟,直到查询跟踪开始:
作者图片
现在,回到 Power BI Desktop 并刷新视觉效果。完成后,再次打开 DAX Studio 并转到所有查询选项卡:
作者图片
瞧——我所有的查询现在都被一次捕获了!而且,一旦我关闭“所有查询”选项卡并打开“服务器计时”选项卡,我就可以单击一个特定的查询:
作者图片
双击选定的查询后,DAX 代码将出现在主窗口中,因此我可以单击 Run,并转到底部的 Server Timings 选项卡:
作者图片
在那里,您不仅可以找到 Power BI 生成的 SQL 查询,还可以找到与服务器性能相关的不同指标,比如 CPU 时间。您还可以检查公式引擎(FE)和存储引擎(SE)满足请求所需的时间。
作者图片
结论
如您所见,有不同的方法来捕获 Power BI 生成的 SQL 查询。
您再也不需要担心了——下次您的 DBA 来到您的办公桌前时,请面带微笑,因为您现在可以为她/他提供在源(SQL 数据库)端微调 SQL 查询所需的所有信息了!
感谢阅读!
成为会员,阅读 Medium 上的每一个故事!
如何用 R 捕捉亵渎
原文:https://towardsdatascience.com/how-to-catch-profanity-with-r-4a21e024d4db?source=collection_archive---------28-----------------------
忘了肥皂吧,我们会用数据科学的力量给他们洗洗嘴
泰勒·尼克斯在 Unsplash 上的照片
人们说脏话。如果你或你的公司碰巧有任何类型的用户生成内容,这些人会在你的网站、社交媒体、评论、评论等上说脏话。他们会匿名坐在他们的小屏幕后面,像海军陆战队队员一样在你的网站上骂人!
幸运的是,我曾经是一名海军陆战队员,所以我认为自己是骂人的专家。我将教你如何用几行 r 来捕捉亵渎。
问题比你想象的要大
在深入研究代码之前,让我们先思考一下这个问题是如何难以解决的。无论我们认为自己有多聪明,都比不上那些找到新方法骂人的人。仅 f-bomb 就有数千种变体,每天都有新的变体被创造出来(我在写这篇文章的时候就创造了几个新的!).
以下是你所面临的一些例子:
- 符号替换:cat = c@t
- 语音替换:duck = duc
- 大写替换:狗=干旱
- 字母分隔:goose = g o o s e
- 字符重复:mouse = moooouuuusssse
- 内心世界掩蔽:马=海马
- 语言替换:bird = pajaro
- 字母反转:rat = tar
- 还有很多很多其他人…
这排除了每个人的个人喜好,昨天还是良性的单词和短语今天可能突然变得具有攻击性。加分的是,这个词在世俗和非世俗的语境中都可以恰当地使用。
那么我们有机会吗?嗯,算是吧。
我们当然可以用黑名单和模式匹配来解决这个问题。)、机器学习和事后措施(例如暂停或禁止有毒用户)。但是没有什么能真正打败人类的节制。
语言变化的速度比我们的算法还快,我们的 ML 模型将永远与最后一个例子(一个好词一夜之间变坏)作斗争。
最好的方法通常是上述所有措施的结合。你想要黑名单(由人类版主每天添加新词),模式匹配来捕捉给定词的所有排列,ML 模型标记潜在的不良内容,以及足够严格的暂停/禁止措施来劝阻用户越过这条线。将所有这些与通过身份验证消除匿名结合起来,你可能就有机会了。
今天,我们将只关注第一项,通过黑名单捕捉亵渎。
不良
为了让你免于阅读一堆淘气的单词,我们要做一个小小的思维实验。就在今天,让我们假设“培根”、“莴苣”和“番茄”是英语中最卑鄙、最可怕、最亵渎的词汇。
如果你用脚趾踢床脚,你可能会说‘培根!!!'。如果你在祖母家说“番茄”,她可能会和你断绝关系,并把你从遗嘱中删除。如果你说“莴苣”这个词……你就明白了。
现在不要担心你不会学习如何真正抓住亵渎。我们将建立我们自己的不良词汇(又名黑名单),但你将能够使用我的代码通过交换一个变量来捕捉实际的亵渎。
漂亮的西红柿很酷,对吧?!
获取数据
现在我们已经确定 BLT 是不好的,我们需要找到一些 BLT。我们在哪里可以找到这些原料?在美食菜谱上怎么样!Kaggle 有一个免费的食物食谱数据集(Shuyang Li,“Food.com 食谱和互动。”卡格尔,2019,doi:10.34740/卡格尔/DSV/783630。)你可以从他们的网站上下载。该数据集被许可用于商业用途(CC BY 4.0)。
编写代码
首先打开 RStudio 并创建一个名为“ProfanityFinder”的新 R 项目。将 RAW_recipes.csv 放到项目的文件夹中。同时在这个项目中创建一个新的 R 脚本,名为“BadWords”。r '
用你的话说。脚本,安装这些软件包你你还没有他们。Tidyverse 允许我们使用一些漂亮的管道语法来操作数据,sentimentr 有一些很棒的 NLP & profanity 函数。
接下来,我们将配方数据导入 tibble (Tidyverses 版本的 R 数据帧)。
现在我们的数据已经导入,让我们稍微清理一下。首先,我们只需要 name 和 ingredients 列,所以让我们选择它。
接下来,我们通过删除标点来清理成分栏。这个专栏有一些特殊的字符,比如方括号,它们会对我们的亵渎函数造成很大的破坏。我们将使用一行简单的代码来删除所有这些。
最后,食谱数据超过 230,000 行!虽然我们可以耐心地处理所有数据,但最好将其限制在 100 行以内。事实证明,如果不碰到一些熏肉、生菜和西红柿,你就无法深入了解食谱数据(请原谅我的法语!).
现在我们到了最精彩的部分。我们需要一个我们关心的不良词汇的列表。公司将这些列表称为黑名单或阻止列表。在 NLP 领域,我们通常将单词列表称为“词典”。不管你喜欢什么术语,让我们现在就建立它。
我们的词典是一个由三个顽皮单词组成的字符向量,它们被分配给一个名为 customCussWords 的变量。
注意了!这是魔法酱被搅拌的地方。我们的词典可能是一个简单的 3 个单词的列表,但是 sentimentr 包碰巧有相当多的实际不良单词的词典。想亲眼看看吗?在 RStudio 中,只需在控制台中键入我们的变量来读取其内容。
customCussWords
图片作者。
这里有一个警告,下面的命令会在你的控制台上显示一些非常可怕的单词。是时候开始锻炼你的铁胃了,因为事实证明你停止亵渎的方法就是用亵渎!
在运行 import(sentimentr)命令后,在控制台中键入以下命令,将会显示字符向量的内容,就像我们的“customCussWords”变量一样。
lexicon::profanity_alvarez
lexicon::profanity_banned
lexicon::profanity_arr_bad
这些只是一些不好的词汇。还有很多很多可以使用。为了更好的效果,为什么不把它们都结合起来。更好的是,定义你自己的!
那么所有这些意味着什么,我提到的神奇调味汁到底是什么?简单。无论你在哪里看到我们的 BLT 词典“自定义脏话”,你都可以用上面的脏话词典替换掉,现在你的代码会神奇地捕捉到脏话!
例如:
do_stuff(customCussWords)
可以变成:
do_stuff(lexicon::profanity_alvarez)
那么,我们实际上如何捕捉亵渎?sentimentr 包有一个方便的功能叫‘亵渎’!这个方便的函数有两个输入。第一个输入是文本,第二个输入是要与文本进行比较的单词词典!
让我们给亵渎函数一个旋转。首先,我们将使用一个不包含脏话的短语。
图片作者。
profanity 函数返回一个包含几个有趣列的表。它有元素和句子的 id、单词计数、亵渎计数,最后还有提供的文本中包含亵渎的单词的百分比。让我们在函数中加入一些诅咒,让它变得更有趣!
图片作者。
结果意味着我们有一个包含 3 个单词的句子,其中一个在我们的词典中找到。因为 1/3 的文章都是脏话,所以我们的脏话比例是 33%。
对于给定的文本,profanity 函数不仅返回 1 行。它实际上通过一个叫做“句子边界消歧”的过程将单词分解成句子。这是一种奇特的 NLP 语言,用于在我们的语言中寻找可能代表句子开始和结束的东西。
如果你还记得的话,我们之前已经删除了文本中所有的标点符号。句号是决定句子结束位置的众多方法之一。以下代码将从亵渎函数返回多行结果:
图片作者。
理解所有这些很重要,但是对于我们的简单练习,我们将只查看 profanity_count 列。我们可以 sum()这个列,以确保我们捕获了所有出现的句子!
使用 base R 语法,我们可以像这样访问特定的列:
图片作者。
万一有多个句子,我们可以这样总结:
图片作者。
现在我们知道了做这件事需要知道的一切!让我们获取配方数据,并使用 Tidyverse 添加一个带有 mutate()的列。
这是在做什么?
- 称我们的食谱为数据框架
- 行方式——对于每一行数据,执行以下操作
- mutate——添加一个新列,使用我们的 customCussWords 词典将配料列传递到 sentimentr 的亵渎函数中
- 过滤器-只显示有亵渎的记录
图片作者。
我们做到了!我们新的“亵渎计数”专栏正在查找并计算单词 bacon、莴苣和番茄的所有出现次数!
知道我们的文本中哪里存在亵渎是很好的,但是我们可以更进一步。让我们添加一列,返回我们的程序发现的实际亵渎。Sentimentr 确实有一个应该做这件事的函数(extract_profanity_terms),但至少在我拥有的 R 的构建上,这个函数似乎坏了。别担心,我们会写我们自己的函数!
我们的目标是将文本和词典传递给一个函数,并让它返回它能找到的所有熏肉、生菜和西红柿。再说一次,如果你需要找到真正的脏话,只需传递上面提到的一个词汇就可以了!
我们的函数在做什么?
- 我们定义了一个名为 returnText 的空字符
- 我们循环使用词典中的单词(培根、生菜、西红柿),看看这个单词是否在文本中。如果找到这个单词,Grepl 将返回 true 或 false。
- 如果找到这个单词,我们用粘贴函数把它附加到 returnText 变量中
- 我们退回所有找到的脏话。
最后,我们可以在代码中添加一个新的 mutate,将 recipe 传递给这个函数,它将像这样返回脏话:
图片作者。
就是这样!我们已经编写了在文本中发现亵渎的代码!
关于效率的一个注记
我们在这里写的代码在大多数小数据集上都能很好地工作,但是在一些场景中这是行不通的。
首先,句子边界消歧是一个代价很高的计算。如果您有一个较大的数据集,您会希望将所有文本预处理成句子。Sentimentr 有一个名为 get_sentences 的函数可以做到这一点。此外,从我们的数据中删除所有标点符号可能不是最明智的做法。您可能希望保留句点和感叹号,以帮助您的代码找出句子的开始和结束位置。
第二,我们编写的返回文本中的脏话的小循环并不是最有效的方法。你可以通过不同的方法获得更好的性能,比如 lapply,sapply 等。
最后,如果您试图标记实时数据或仔细阅读数十亿条记录,R 真的不适合这种语言。r 不完全是最快的编程语言,它的并行处理能力徘徊在“有限的和“不存在的”之间。如果您的用例涉及大量或实时数据,您会希望选择一种更接近机器的语言。
那是一个(BLT)包装!
现在你知道怎么抓坏人了吧!你可以从我的 GitHub 下载所有的代码!。
你知道你可以在一篇文章上点击鼓掌按钮多达 50 次吗?如果你觉得这篇文章内容丰富,那就把生菜从那玩意儿里砸出来!
如何更改 Pandas 数据框架中的列类型
原文:https://towardsdatascience.com/how-to-change-column-type-in-pandas-dataframes-d2a5548888f8?source=collection_archive---------3-----------------------
探索在 pandas 中改变列的数据类型的 3 种不同选择
照片由梅根·卡森在 Unsplash 拍摄
介绍
在处理熊猫数据帧时,最常见的操作之一是数据 类型(或 **dtype**
)转换。在今天的文章中,我们将探索 3 种不同的方法来改变熊猫的栏目类型。这些方法是
astype()
to_numeric()
convert_dtypes()
在开始讨论可以用来更改某些列的类型的各种选项之前,让我们首先创建一个伪数据帧,我们将在整篇文章中使用它作为示例。
import pandas as pddf = pd.DataFrame(
[
('1', 1, 'hi'),
('2', 2, 'bye'),
('3', 3, 'hello'),
('4', 4, 'goodbye'),
],
columns=list('ABC')
)print(df)# A B C
# 0 1 1 hi
# 1 2 2 bye
# 2 3 3 hello
# 3 4 4 goodbyeprint(df.dtypes)# A object
# B int64
# C object
# dtype: object
使用 astype()
[DataFrame.astype()](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.astype.html)
方法用于将熊猫列转换为指定的数据类型。指定的 dtype 可以是内置 Python、numpy
或pandas
dtype。
假设我们想要将列A
(目前是一个类型为object
的字符串)转换成一个保存整数的列。为此,我们只需在 pandas DataFrame 对象上调用astype
,并显式定义我们希望转换列的 dtype。
**df['A'] = df['A'].astype(int)**print(df)# A B C
# 0 1 1 hi
# 1 2 2 bye
# 2 3 3 hello
# 3 4 4 goodbyeprint(df.dtypes)# A int64
# B int64
# C object
# dtype: object
您甚至可以一次转换多个列。举个例子,
**df = df.astype({"A": int, "B": str})**print(df)# A B C
# 0 1 1 hi
# 1 2 2 bye
# 2 3 3 hello
# 3 4 4 goodbyeprint(df.dtypes)# A int64
# B object
# C object
# dtype: object
此外,您甚至可以指示astype()
在观察到所提供的 dtype 的无效数据时如何行动。这可以通过传递相应的errors
参数来实现。您可以选择'raise’
无效数据异常或'ignore’
抑制异常。
例如,假设我们有一个混合了dtypes
和Series
的列,如下所示:
s = pd.Series(['1', '2', 'hello'])print(s)
# 0 1
# 1 2
# 2 hello
# dtype: object
现在,如果我们试图将该列转换为int
,将会引发一个ValueError
:
s = s.astype(int)
ValueError: invalid literal for int() with base 10: 'hello'
我们可以通过传递errors='ignore'
来抑制ValueError
。在这种情况下,原始对象将被返回
s = s.astype(int, errors='ignore')
print(s)# 0 1
# 1 2
# 2 hello
# dtype: object
从 1.3.0 版本开始,用于将时区简单类型转换为时区感知类型的 *astype*
已被弃用。你现在应该用 [*Series.dt.tz_localize()*](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.dt.tz_localize.html#pandas.Series.dt.tz_localize)
代替。
使用 to_numeric()
[pandas.to_numeric](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.to_numeric.html)
用于将非数字dtypes
列转换为最合适的数字时间。例如,为了将列A
转换为int
,您需要运行的全部内容是
**df['A'] = pd.to_numeric(df['A'])**print(df)
# A B C
# 0 1 1 hi
# 1 2 2 bye
# 2 3 3 hello
# 3 4 4 goodbyeprint(df.dtypes)
# A int64
# B int64
# C object
# dtype: object
现在,如果您想将多个列转换成数字,那么您必须使用如下所示的apply()
方法:
**df[["A", "B"]] = df[["A", "B"]].apply(pd.to_numeric)**print(df.dtypes)
# A int64
# B int64
# C object
# dtype: object
to_numeric()
也接受errors
参数(像astype()
一样),但是它有一个额外的选项,即*'*coerce*'*
将所有不能使用指定的dtype
解析的值设置为NaN
。要了解更多细节,请务必查看官方文档。
你可能还想看看 *to_datetime()*
和 *to_timedelta()*
方法,如果你想把一列分别投射到 *datetime*
或 *timedelta*
的话。
使用convert_dtypes()
[convert_dtypes()](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.convert_dtypes.html#pandas.DataFrame.convert_dtypes)
方法包含在 pandas 版本1.0.0
中,用于使用支持pd.NA
(缺失值)的dtypes
将列转换为最佳的dtypes
。这意味着dtype
将在运行时根据指定列中包含的值来确定。
**df = df.convert_dtypes()**print(df.dtypes)# A string
# B Int64
# C string
# dtype: object
注意列 A 和 C 是如何被转换成string
类型的(最初它们是object
类型)。尽管这对于列C
来说相当准确,但理想情况下,我们希望将列A
转换为 int 列。如果你想让这个方法算出应该用什么dtypes
,这基本上是你必须付出的代价。如果这不是您所期待的,您仍然可以使用本文前面提到的任何方法来显式指定目标dtypes
。
最后的想法
在今天的文章中,我们探讨了 pandas 中的许多选项,可以用来转换数据帧中特定列的数据类型。我们讨论了如何使用astype()
来显式指定列的dtypes
。此外,我们还探索了如何使用to_numeric()
方法将列转换成数字类型。最后,我们展示了如何使用convert_dtypes()
方法,根据每个列中包含的值计算出最合适的dtypes
列。
如何更改 PySpark 数据帧的列名
原文:https://towardsdatascience.com/how-to-change-the-column-names-of-pyspark-dataframes-46da4aafdf9a?source=collection_archive---------7-----------------------
讨论 PySpark 数据框架中改变列名的 5 种方法
照片由 Linus Nylund 在 Unsplash 上拍摄
介绍
在今天的简短指南中,我们将讨论在 Spark 数据帧中更改列名的 4 种方法。具体来说,我们将使用以下工具来探索如何做到这一点:
selectExpr()
方法withColumnRenamed()
方法toDF()
法- 别名
- Spark 会话和 Spark SQL
并一次重命名一列或多列。
首先,让我们创建一个示例 PySpark 数据帧,我们将在本指南中引用它来演示一些概念。
>>> from pyspark.sql import SparkSession# Create an instance of spark session
>>> spark_session = SparkSession.builder \
.master('local[1]') \
.appName('Example') \
.getOrCreate()>>> df = spark_session.createDataFrame(
[
(1, 'a', True, 1.0),
(2, 'b', False, 2.0),
(3, 'c', False, 3.0),
(4, 'd', True, 4.0),
],
['colA', 'colB', 'colC', 'colD']
)>>> df.show()
*+----+----+-----+----+
|colA|colB| colC|colD|
+----+----+-----+----+
| 1| a| true| 1.0|
| 2| b|false| 2.0|
| 3| c|false| 3.0|
| 4| d| true| 4.0|
+----+----+-----+----+*>>> df.printSchema()
*root
|-- colA: long (nullable = true)
|-- colB: string (nullable = true)
|-- colC: boolean (nullable = true)
|-- colD: double (nullable = true)*
使用 selectExpr()
第一个选项是[pyspark.sql.DataFrame.selectExpr()](https://spark.apache.org/docs/3.1.1/api/python/reference/api/pyspark.sql.DataFrame.selectExpr.html)
方法,它是接受 SQL 表达式的[select()](https://spark.apache.org/docs/3.1.1/api/python/reference/api/pyspark.sql.DataFrame.select.html#pyspark.sql.DataFrame.select)
方法的变体。
**>>> df = df.selectExpr(
'colA AS A',
'colB AS B',
'colC AS C',
'colD AS D',
)**>>> df.show()
*+---+---+-----+---+
| A| B| C| D|
+---+---+-----+---+
| 1| a| true|1.0|
| 2| b|false|2.0|
| 3| c|false|3.0|
| 4| d| true|4.0|
+---+---+-----+---+*
但是请注意,当您需要重命名大多数列,并且还必须处理相对较少的列时,这种方法最适合。
此时,您可能还想回忆一下 Spark 中select()
和selectExpr()
的区别:
使用 withColumnRenamed()
重命名 PySpark 数据帧列的第二个选项是[pyspark.sql.DataFrame.withColumnRenamed()](https://spark.apache.org/docs/latest/api/python/reference/api/pyspark.sql.DataFrame.withColumnRenamed.html)
。此方法通过重命名现有列来返回新的 DataFrame。
**>>> df = df.withColumnRenamed('colA', 'A')**>>> df.show()
*+---+----+-----+----+
| A|colB| colC|colD|
+---+----+-----+----+
| 1| a| true| 1.0|
| 2| b|false| 2.0|
| 3| c|false| 3.0|
| 4| d| true| 4.0|
+---+----+-----+----+*
当您需要一次重命名一列时,这种方法最合适。如果您需要一次性重命名多个列,那么本文中讨论的其他方法会更有帮助。
使用 toDF()方法
方法使用新的指定列名返回一个新的 DataFrame。
**>>> df = df.toDF('A', 'colB', 'C', 'colD')**>>> df.show()
*+---+----+-----+----+
| A|colB| C|colD|
+---+----+-----+----+
| 1| a| true| 1.0|
| 2| b|false| 2.0|
| 3| c|false| 3.0|
| 4| d| true| 4.0|
+---+----+-----+----+*
当您需要同时重命名多个列时,这种方法很有用。
请注意,如果您有一个包含新列名的列表,那么下面的代码也应该可以完成这个任务:
>>> new_col_names = ['A', 'colB', 'C', 'colD']
>>> **df = df.toDF(*new_col_names)**
使用别名
我们的另一个选择是使用[alias](https://spark.apache.org/docs/latest/api/python/reference/api/pyspark.sql.DataFrame.alias.html)
方法,返回一个带有别名集的新数据帧。
>>> from pyspark.sql.functions import col**>>> df = df.select(
** **col('colA').alias('A'),
col('colB'),
col('colC').alias('C'),
col('colD')** **)**>>> df.show()
*+---+----+-----+----+
| A|colB| C|colD|
+---+----+-----+----+
| 1| a| true| 1.0|
| 2| b|false| 2.0|
| 3| c|false| 3.0|
| 4| d| true| 4.0|
+---+----+-----+----+*
同样,当需要重命名多个列并且不需要处理大量列时,应该使用这种方法,否则这会变得非常冗长。
使用 Spark SQL
最后,您可以使用 Spark SQL 对存储为表的数据帧使用传统的 SQL 语法来重命名列。举个例子,
>>> df.createOrReplaceTempView('test_table')
>>> df = spark_session.sql(
'SELECT colA AS A, colB, colC AS C, colD FROM test_table'
)>>> df.show()
*+---+----+-----+----+
| A|colB| C|colD|
+---+----+-----+----+
| 1| a| true| 1.0|
| 2| b|false| 2.0|
| 3| c|false| 3.0|
| 4| d| true| 4.0|
+---+----+-----+----+*
最后的想法
在今天的简短指南中,我们讨论了如何以多种不同的方式重命名 PySpark 数据帧的列。根据您是否需要重命名一个或多个列,您必须选择最适合您的特定用例的方法。
成为会员 阅读媒介上的每一个故事。你的会员费直接支持我和你看的其他作家。
你可能也喜欢
如何改变熊猫数据框架中列的顺序
原文:https://towardsdatascience.com/how-to-change-the-order-of-dataframe-columns-in-pandas-c91370326053?source=collection_archive---------15-----------------------
在 pandas 数据框架中更改列顺序并将列移到前面
斯通王在 Unsplash 上拍照
介绍
对 pandas 数据帧中的列重新排序是我们想要执行的最常见的操作之一。当涉及到向其他人展示结果时,这通常是有用的,因为我们需要以某种逻辑顺序对(至少几个)列进行排序。
在今天的文章中,我们将讨论如何使用
- 原始帧的切片——当您需要重新排序大多数列时最相关
insert()
方法——如果你想将一个单独的列插入到指定的索引中set_index()
—如果需要将一列移动到数据框的前面- 和,
reindex()
方法——主要与您可以按照您希望的顺序指定列索引的情况相关(例如,按照字母顺序)
首先,让我们创建一个我们将在本指南中引用的示例数据帧。
import pandas as pddf = pd.DataFrame({
'colA':[1, 2, 3],
'colB': ['a', 'b', 'c'],
'colC': [True, False, False],
'colD': [10, 20, 30],
})print(df)
# colA colB colC colD
# 0 1 a True 10
# 1 2 b False 20
# 2 3 c False 30
使用切片
最简单的方法是使用一个列表分割原始数据帧,该列表包含您希望它们遵循的新顺序的列名:
**df = df[['colD', 'colB', 'colC', 'colA']]**print(df)
# colD colB colC colA
# 0 10 a True 1
# 1 20 b False 2
# 2 30 c False 3
如果您想对大多数列的名称进行重新排序,这种方法可能已经足够好了(而且您的数据框架可能有太多的列)。
使用 insert()方法
如果您需要将列插入数据帧的指定位置,那么[pandas.DataFrame.insert()](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.insert.html)
应该可以做到。但是,您应该确保首先将该列从原始数据帧中取出,否则将出现一个带有以下消息的ValueError
:
ValueError: cannot insert column_name, already exists
因此,在调用insert()
之前,我们首先需要对数据帧执行[pop()](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.pop.html)
操作,以便从原始数据帧中删除该列并保留其信息。例如,如果我们想将colD
作为框架的第一列,我们首先需要pop()
该列,然后将其插回,这次是插入到所需的索引。
**col = df.pop("colD")
df.insert(0, col.name, col)** print(df)
# colD colA colB colC
# 0 10 1 a True
# 1 20 2 b False
# 2 30 3 c False
使用 set_index()方法
如果你想把一列移到熊猫数据框的前面,那么[set_index()](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.set_index.html)
就是你的朋友。
首先,您指定我们希望移到前面的列作为数据帧的索引,然后重置索引,以便旧的索引作为一列添加,并使用新的顺序索引。同样,请注意我们如何pop()
在将列添加为索引之前删除它。这是必需的,否则当试图使旧索引成为数据帧的第一列时会发生名称冲突。
**df.set_index(df.pop('colD'), inplace=True)**# colA colB colC
# colD
# 10 1 a True
# 20 2 b False
# 30 3 c False**df.reset_index(inplace=True)**# colD colA colB colC
# 0 10 1 a True
# 1 20 2 b False
# 2 30 3 c False
使用 reindex()方法
最后,如果您想要按照您希望的顺序指定列索引(例如按字母顺序),您可以使用[reindex()](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.reindex.html)
方法使数据帧符合新的索引。
例如,假设我们需要按字母降序排列列名
**df = df.reindex(columns=sorted(df.columns, reverse=True))**# colD colC colB colA
# 0 10 True a 1
# 1 20 False b 2
# 2 30 False c 3
请注意,上述内容相当于
df.reindex(sorted(df.columns, reverse=True), axis='columns')
最后的想法
在今天的简短指南中,我们讨论了如何以多种不同的方式改变熊猫数据帧中的列顺序。确保根据您的具体要求选择正确的方法。
你可能也会喜欢
如何用数据科学改变世界
原文:https://towardsdatascience.com/how-to-change-the-world-with-data-science-33c3b55bead?source=collection_archive---------29-----------------------
利用数据科学的力量应对全球挑战
朱莉安娜·科佐斯基在 Unsplash 上的照片
只有当我们收集的数据能够通知和激励那些有能力做出改变的人时,事情才能完成
如今,全球有近百万人在数据科学相关领域工作。
该行业经历了巨大的增长,全球大部分数据都是在过去两年中生成的。数据驱动的行业在过去几年里经历了巨大的增长。
数据科学的应用让生活变得更加轻松。从寻找最好的电影到选择最好的餐馆就餐,数据为我们提供了比我们可能需要的更多的便利。
当今世界,几乎所有数据科学的应用都致力于让已经舒适的生活变得更加舒适。
然而,我们可以利用现有的数据做更多的事情。用于促进销售的相同算法可以被编写为相反促进社会影响。
如何利用数据科学造福社会?
照片由米歇尔·亨德森在 Unsplash 上拍摄
利用数据科学造福社会的一些例子包括:
- 创建机器学习算法来预测家庭的贫困状况。
- 识别网络欺凌和自杀之间的趋势。
- 检查不同街道特征对行人死亡的影响。
- 确定社交媒体使用的个性化算法是否会强化负面的身体形象。
现在是创造数据驱动的解决方案来解决社会问题的最佳时机。收集与上述所有主题相关的大量数据是可能的。
非营利组织可以利用这些数据更好地理解社会问题。如果他们所做的工作是由数据驱动的,他们将能够在实现社会问题的解决方案方面迈出更大的步伐。
例如,可以实现机器学习模型来识别需要立即关注的社区,并对它们进行优先排序。
然而,为了社会利益,在数据科学领域取得进展是很困难的。虽然大型科技公司有能力聘请数据科学家并开发大型数据生态系统,但非营利组织负担不起。
这意味着,尽管非政府组织拥有丰富的数据,但他们无法利用这些数据,因为他们缺乏技术技能。
幸运的是,有一些组织帮助非政府组织获得技术人才。
这些组织将数据科学家/分析师与世界各地的非政府组织配对。
事实上,如果你是一名有抱负的数据科学家,你可以在其中一个组织中做志愿者。您将能够与其他行业专业人士合作,分析社会数据并回答紧迫的问题。
你如何参与其中
在 Unsplash 上由 Etty Fidele 拍摄的照片
“使用数据不仅可以决定我们想看什么样的电影,还可以决定我们想看什么样的世界”——data kind
DataKind 是一个连接数据科学家和非政府组织的组织。他们甚至为想要涉足社会科学的数据科学家提供指导。
他们的座右铭是 “利用数据科学的力量为人类服务。”
如果你是一名想要回馈社会的数据科学家,你可以加入 DataKind 成为一名志愿者。如果你作为志愿者加入,他们会将你分配到一个现有的项目中,你将与一群志同道合的人一起回答一个社会数据科学问题。
截至目前,他们正在进行的最受欢迎的项目之一叫做零视力。这个项目旨在将与交通相关的伤亡降至零。
他们的大多数活动都是在晚上或周末组织的,所以全职工作的人也可以积极参与。你可以在这里了解更多关于 DataKind 做的工作。
华威大学也有一个 DSSG(社会公益数据科学)暑期奖学金,做的工作和 DataKind 类似。他们教导学生与非政府组织合作,为社会公益开发数据科学产品。你可以在这里看一看他们做的一些工作。
社会数据科学有更多的奖学金和志愿者机会,所以如果你对此感兴趣,你应该做一些研究。
您可以参与的项目
如果你想在社会数据科学领域做一些研究,这里有一些项目想法给你:
分析 BLM 运动
照片由 Gabe Pierce 在 Unsplash 上拍摄
作为对系统性种族主义的回应,一场名为“黑人的命也是命”的民众运动应运而生。这场运动抗议警察暴行和黑人在日常生活中面临的其他形式的暴力。
然而,BLM 运动受到了其他社区的强烈反对。很多人不愿意相信系统性种族主义的存在。他们说像 BLM 这样的运动是不必要的。
像“所有生命都重要”这样的运动是对 BLM 运动的回应,他们坚持认为美国是一个后种族社会,种族主义在这个国家已经不存在了。
数据可以用来证明黑人社区是否处于劣势。纽约警察局每天都会发布交通堵塞数据。
每个交通站的细节都被记录下来,这些数据可以用来寻找系统性种族主义的证据。它可以用来回答像这样的问题,“少数民族是否更经常被警察拦下,却没有更多犯罪证据?”
如果这是你感兴趣的分析,你应该看看斯坦福开放警务项目。
贫困预测
照片由乔丹·欧宝在 Unsplash 上拍摄
为了消除极端贫困,定期对其进行衡量非常重要。非政府组织只有不时地对其减贫战略进行评估,才能了解其是否有效。
如果我们要确定贫困,我们首先需要收集家庭消费数据。然后,我们可以在带标签的贫困数据集上训练机器学习模型,并对未来数据进行预测。
有了好的算法,我们可以快速识别低收入家庭。这些预测可以帮助社会组织优先考虑低收入家庭,并制定减贫战略。
如果这是一个你感兴趣的项目,你应该看看 Kaggle 的贫困预测数据集。
结论
大多数现有的数据驱动解决方案都专注于提高人们日常生活的舒适度。虽然这是产生最多收入的数据科学应用,但它肯定不是最有意义的应用。
数据有可能为人们创造更好的生活,并可用于解决贫困、药物滥用和种族主义等问题。
应用数据科学来解决社会问题被称为社会数据科学,可以产生改变世界的影响。
如何使用 scikit-learn 检查分类模型是否过度拟合
原文:https://towardsdatascience.com/how-to-check-if-a-classification-model-is-overfitted-using-scikit-learn-148b6b19af8b?source=collection_archive---------6-----------------------
数据分析
Python 中的现成教程,有助于识别和减少过度拟合
图片由罗兰·施泰因曼从 Pixabay 拍摄
在处理机器学习算法时,最困难的问题之一是评估经过训练的模型在未知样本下是否表现良好。例如,可能会发生这样的情况:模型在给定的数据集下表现很好,但在部署时却无法预测正确的值。训练数据和测试数据之间的这种不一致可能是由不同的问题造成的。最常见的问题之一是过度拟合。
一个模型很好地适应了训练集,但测试集很差,这种模型被称为对训练集过度适应,而一个模型对两个集都不太适应,这种模型被称为欠适应。摘自这篇非常有趣的文章作者 Joe Kadi。
换句话说,过度拟合意味着机器学习模型能够对训练集进行太好的建模。
在本教程中,我利用 Python scikit-learn
库来检查分类模型是否过度拟合。同样的程序也可以用于其他模型,如回归。提议的战略包括以下步骤:
- 将数据集分成训练集和测试集
- 用训练集训练模型
- 在训练集和测试集上测试模型
- 计算训练集和测试集的平均绝对误差(MAE)
- 绘制和解释结果
必须对不同的训练集和测试集执行前面的步骤。
作为示例数据集,我使用心脏病发作数据集,可在 Kaggle 存储库中获得。所有代码都可以从我的 Github 库下载。
加载数据
首先,我通过 Python pandas
库将数据集作为数据帧加载。数据集包含 303 条记录、13 个输入要素和 1 个输出类,输出类可以是 0 或 1。
import pandas as pddf = pd.read_csv('source/heart.csv')
df.head()
作者图片
我建立数据集。我定义了两个变量,X
和y
,分别对应于输入和输出。
features = []
for column in df.columns:
if column != 'output':
features.append(column)
X = df[features]
y = df['output']
构建并测试模型
通常,X
和y
被分成两个数据集:训练集和测试集。在scikit-learn
中,这可以通过train_test_split()
函数完成,该函数返回训练和测试数据。然后,通过训练数据拟合模型,并通过测试数据检验其性能。然而,所描述的策略不允许验证模型是否过度拟合。
出于这个原因,我不使用train_test_split()
函数,而是使用 K 折叠交叉验证。
K Folds 将数据集拆分成 k 个子集,在不同的训练集上训练模型 k 次,在不同的测试集上测试模型 k 次。每次,训练集由 k-1 个子集组成,而测试集是剩余的子集。
scikit-learn
库为 K 折叠提供了一个类,称为KFold()
,它接收数字k
作为输入。对于每一对(训练集、测试集),我可以建立模型并计算训练集和测试集的平均绝对误差(MAE)。在这个具体的例子中,我利用了KNeighborsClassifier()
。
from sklearn.model_selection import KFold
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import mean_absolute_error
import matplotlib.pyplot as pltkf = KFold(n_splits=4)
mae_train = []
mae_test = []
for train_index, test_index in kf.split(X):
X_train, X_test = X.iloc[train_index], X.iloc[test_index]
y_train, y_test = y[train_index], y[test_index] model = KNeighborsClassifier(n_neighbors=2)
model.fit(X_train, y_train)
y_train_pred = model.predict(X_train)
y_test_pred = model.predict(X_test)
mae_train.append(mean_absolute_error(y_train, y_train_pred))
mae_test.append(mean_absolute_error(y_test, y_test_pred))
然后,我可以绘制培训和测试 MAEs,并对它们进行比较。
folds = range(1, kf.get_n_splits() + 1)
plt.plot(folds, mae_train, 'o-', color='green', label='train')
plt.plot(folds, mae_test, 'o-', color='red', label='test')
plt.legend()
plt.grid()
plt.xlabel('Number of fold')
plt.ylabel('Mean Absolute Error')
plt.show()
作者图片
我注意到,对于所有 k 倍,训练 MAE 非常小(大约 0.2)。相反,测试 MAE 非常大。范围从 0.3 到 0.8。因为训练 MAE 很小,而测试 MAE 很大,所以我可以断定这个模型是过度拟合的。
我将所有之前的操作组合成一个名为test_model()
的函数,它接收模型以及X
和y
变量作为输入。
限制过度拟合
可以通过以下两种策略(潜在地)限制过拟合:
- 降低复杂性
- 调整参数
- 改变模式。
1.降低复杂性
我试图通过将所有输入特征缩放到 0 到 1 之间的范围来改进模型。我利用了由scikit-learn
库提供的MinMaxScaler()
。
from sklearn.preprocessing import MinMaxScaler
import numpy as npfor column in X.columns:
feature = np.array(X[column]).reshape(-1,1)
scaler = MinMaxScaler()
scaler.fit(feature)
feature_scaled = scaler.transform(feature)
X[column] = feature_scaled.reshape(1,-1)[0]
我构建了一个新模型,并调用了test_model()
函数。现在,该模型在训练集和测试集上的性能都有所提高。然而,测试 MAE 仍然很大。因此,模型仍然是过度拟合的。
model = KNeighborsClassifier(n_neighbors=2)
test_model(model, X,y)
作者图片
降低复杂性的另一种可能性是减少特征的数量。这可以通过主成分分析来实现。例如,我可以将输入要素的数量从 13 个减少到 2 个。为此,scikit-learn
库提供了PCA()
类。
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
pca.fit(X)
X_pca = pca.transform(X)
X_pca = pd.DataFrame(X_pca)
我在新特性上测试了模型,我注意到模型的性能提高了。现在测试 MAE 的范围从 0.20 到 0.45。
作者图片
2.调整参数
另一种可能性是调整算法参数。scikit-learn
库提供了GridSearchCV()
类,允许搜索特定模型的最佳参数。要调整的参数必须作为dict
传递,对于每个参数,必须传递要分析的值列表。另外,GridSearchCV()
战功也是交叉验证的。在变量best_estimator_
中,最佳估计值在拟合后可用。
from sklearn.model_selection import GridSearchCVmodel = KNeighborsClassifier()param_grid = {
'n_neighbors': np.arange(1,30),
'algorithm' : ['auto', 'ball_tree', 'kd_tree', 'brute'],
'metric' : ['euclidean','manhattan','chebyshev','minkowski']
}grid = GridSearchCV(model, param_grid = param_grid, cv=4)
grid.fit(X, y)
best_estimator = grid.best_estimator_
我测试模型。我注意到测试 MAE 的范围从大约 0.25 到 0.45。
test_model(best_estimator, X,y)
作者图片
3.改变模式
先前的尝试减少了过度拟合。然而,模型性能仍然很差。因此,我试图改变模式。我试一个GaussianNB()
型号。我注意到性能有了惊人的提高。事实上,测试 MAE 的范围在 0.20 和 0.35 之间,因此我可以得出结论,该模型没有过度拟合。
from sklearn.naive_bayes import GaussianNB
model = GaussianNB()
test_model(model, X,y)
作者图片
摘要
在本教程中,我已经说明了如何检查分类模型是否过度拟合。此外,我还提出了三种策略来限制过度拟合:降低复杂性、调整参数和改变模型。
正如这个具体例子中所描述的,我们经常使用错误的模型来处理问题。因此,我的建议是:请尝试不同的型号!
如果你想了解我的研究和其他活动的最新情况,你可以在 Twitter 、 Youtube 和 Github 上关注我。
相关文章
[## Python 和 scikit 中的完整数据分析工作流程-学习
towardsdatascience.com](/a-complete-data-analysis-workflow-in-python-and-scikit-learn-9a77f7c283d3)
来自社区
。
如何自动检查个人资料图片上传
原文:https://towardsdatascience.com/how-to-check-profile-picture-uploads-automatically-a0f4b55f1763?source=collection_archive---------28-----------------------
…使用现有的人工智能 API
作者 Gif
https://github.com/JEDS-AI/profile-picture-checker
介绍
个人资料图片上传功能广泛应用于许多应用程序中。它允许用户定制他的简档,并且允许容易地识别他们。在某些用例中,显示一些警告或限制用户上传不合适的图片可能会有所帮助。可能的情况是,上传一张非常模糊或戴着头饰的照片是不允许的/有用的。要实现这样的功能,手动检查图像真的很麻烦。这就是人脸识别可以帮助改进上传个人资料图片的过程的地方。
我将使用 Google Cloud Vision API 来实现这个功能。Google 提供了很多很好用的机器学习 API。将来使用这些端点的成本可能会有所不同,因此如果您感兴趣,请自行查找。现在你有 1000 个免费的初始请求,所以试用是免费的。
设置 Google 云视觉 API
首先,你应该为自己创建一个谷歌云账户。
之后你可以登录谷歌云控制台。
在 Google Cloud 控制台中,您必须执行某些任务才能成功地向 API 发出请求。
为了存档,您还可以使用快速启动设置。
必要的步骤是:
- 创建新项目
- 激活谷歌云视觉 API
- 启用计费(不用担心,有免费方案)
但是真的需要启用,不然不行。 - 设置认证
请随意使用 Google 推荐的方式,使用服务帐户并生成私有和公共密钥。对我来说,生成一个 API 键并在我的请求中使用它要容易得多。但是请记住,它可能不如其他方法安全。根据您的使用情况,保护特定 IP 地址的 API 密钥就足够了。所以如果你只是想尝试 API,一个 API 密匙就足够了。
测试面部识别请求结果
为了测试人脸识别 API,我手工做了一些请求。我用不同的图片进行了测试,看看结果如何变化。请求应该是这样的:
API 键在请求 URL 本身中提供。请求方法是 POST,因为我们想向端点发送一些东西。请求体必须遵循这种给定的格式,因为您也可以在一个请求中发送多个图像。但是我们不会在这里使用这个功能。
您还必须定义应该使用 API 的哪些特性。对于这个用例,它是“面部检测”功能。maxResults 值在这里是不必要的,因为我们只发送一个图像。
对于下面的图片,我希望得到戴头饰的信息。
图片由像素上的 Adrea Piacquadio 拍摄
当成功调用人脸识别 API 时,您会得到如下所示的结果。为了简单起见,我删除了一些数据。例如,你得到了鼻子或眼睛位置的大量数据,但是我们现在不需要这些信息。
如你所见,我们得到了一些关于情绪(喜悦、悲伤、愤怒、惊讶)和图像属性(曝光不足、模糊和头饰)的信息。该值显示了不同参数对于给定图片的可能性。在这个例子中,除了 headwearLikelihood 是“可能”之外,所有参数都是非常不可能的。对于这一结果,如果佩戴头饰不适合上传个人资料图片,则显示一些警告是有意义的。
可能性评级可以有 6 个不同的值:未知、非常不可能、不太可能、可能、可能、非常可能
设置一个基本的 React JS 项目
为了实际使用 API,你可以使用任何可以处理 HTTP 请求的东西。例如,它可以是 Web 应用程序或移动应用程序。我使用 React-JS 创建了一个基本的 Web 应用程序。
你可以去看看 GitHub 仓库,那里提供了我的实现。你可以随意用它来测试你自己的 API。(不要忘记更改 API 键)。
要自己创建一个 react 项目,我建议遵循 React 官方文档的步骤。此外,我安装了 Material UI 作为 UI 框架,这样应用程序开箱后看起来很好。
用例的实现
为了创建一个示例用例,我从实现 3 个组件开始,它们将一起工作来创建 ProfilePictureUploader 组件。
组件包括:
- 图像预览
- 图像警告
- 图像选择
作者图片
试映
ImagePreview 基本上是一个等待图像信息的标签。如果信息被更新,它将重新呈现新的图像。我对高度做了一些限制,并添加了一些额外的造型,使它看起来更好。
警告信息
ImageWarning 组件使用 API 调用的结果,并决定是否显示警告。该组件还获取 API 调用当前是否待定的信息,以显示加载指示符。在这个例子中,我决定在愤怒、模糊或头饰参数不是“非常不可能”时显示警告。如果出现警告,会生成一个小图标和一条文本来通知用户。您当然可以实现其他符合您需求的逻辑。
输入并提交
ImageSelection 组件由一个文件输入和一个提交按钮组成。文件输入用于从用户处获取图像,提交按钮目前没有功能,它只是用来显示如何处理配置文件图像。例如,点击提交,它可以上传到您的服务器。
个人资料图片上传者
这三个组件在一个名为 ProfilePictureUploader 的包装组件中使用,该包装组件提供 API 请求本身并定义其他三个组件的排列方式。
请看看 detectFaces 函数。该函数执行对 Google Cloud Vision API 的请求。如您所见,为了进行人脸检测,需要提供一个请求主体。使用这个请求体,您可以向 https://vision.googleapis.com/v1/images:annotate?的
发送一个 POST 请求 key = $ { APIkey }
API key 就是你从谷歌云控制台得到的 API key。在这里,我只是将它直接写入代码中,这通常不是最好的方法,但在开始时尝试一下也是可以的。请求成功后,将向 ImageWarning 组件发出响应,以确定是否应该显示警告。
结果
作者 Gif
在我的测试中,API 本身非常可靠和快速。它总是花费大约 1 秒钟来得到一个结果,这对于做这样一个复杂的任务来说是相对快的。
一般来说,我认为这是一个很好的方式来改善个人资料图片上传这样的功能,因为它可以帮助减少你的应用程序中不良或不适当的图片数量。无论如何,你应该决定你是否想要完全限制用户上传这样的内容,或者你只是想像我一样显示警告。一如既往,它高度依赖于您的特定用例。
如何选择数据科学专业
原文:https://towardsdatascience.com/how-to-choose-a-data-science-program-311550aef746?source=collection_archive---------26-----------------------
在训练营和硕士项目中应该寻找什么,以及各自的优缺点
我有一些数据科学训练营和硕士课程的经验。为了进入这个领域,我参加了一个训练营,并为一个在线训练营和几个硕士项目教过书(现在仍然在教)。
我想分享一些想法,如果我现在选择一个,我会如何考虑这些不同的计划。
数据科学项目的激增
凯拉·法默在 Unsplash 上的照片
数据科学家被 T4 称为 21 世纪最性感的工作已经有很多年了。几年前,公司刚刚开始意识到从数据中结合见解和使用机器学习的潜力。有一个人才争夺战,有合适的技能来帮助这些努力的公司。对数据科学有巨大的需求。
市场反应强烈——很多人想成为数据科学家。为了应对这种需求,训练营应运而生,学术界推出了大量数据科学硕士项目。突然间,数据科学项目无处不在。你如何在它们之间做出选择?
我以前写过关于数据科学项目对谁有用的文章:
很多人试图从自学的角度来研究数据科学,但除非你已经掌握了很多必要的技能,否则一些精心安排的课程和支持会很有帮助。
假设你想做一些培训,在决定合适的项目时,请记住以下几点:
数据科学项目中需要注意的一般事项
- 广度。数据科学培训项目的最大优势之一是,它让你接触到了许多你原本不会知道的话题。一旦您知道了某个主题的正确关键词,就可以很容易地找到了解它的资源,但是学习数据科学的一个重要方面是至少了解这个多方面学科的情况。确保课程不仅仅是数据争论和机器学习。
- 理论与实践的结合。研究各种机器学习算法的数学是很棒的,但如果你不付诸实践,那就没什么帮助了。同样,如果你没有使用算法的实践经验,学习算法是没有用的。寻找那些强调学习理论和做项目的项目。
- 在非策划数据集上的实践经验。出于教学目的,给学生一个干净、有条理、没有惊喜的数据集可能很容易。但是这些数据集并不能反映真实世界。寻找那些可以让你获得真实数据集经验的项目,无论是通过他们的作业还是通过自我指导的顶点项目。
- 自定进度?注意一个项目是否是自定进度的是很重要的。你必须足够了解自己,知道自定进度是否适合你——它允许更多的灵活性,但也意味着它将更容易拖延。根据我的经验,完成自定进度计划的学生比那些需要每周承诺的学生少得多。
- 同行。当它是一种社会活动时,学习会容易得多。当你有其他人和你经历同样的过程时,你可以互相学习和鼓励。如果可能的话,强烈倾向于允许与同龄人进行一定程度的社交互动的计划,认识到远程、自定进度计划的灵活性与具有社交成分的计划之间存在权衡。
训练营对大师赛
数据科学主要有两种项目:训练营和学术硕士项目。这里有一些一般性的想法可以帮助你在它们之间做出选择。
训练营
优点
- 倾向于拥有更多最新的课程。训练营很灵活,往往会不断更新他们的课程。在学术界,每个教师在教学内容上通常有很大的自由,导致质量参差不齐,许多课程没有更新,而训练营往往有更集中的课程,更容易保持最新(可能一开始就创建了更新的课程)。
- 经常有某种形式的工作保证和支持。虽然训练营可能没有学术机构那样的资源,但他们通常会有更有针对性的职业指导。更好的是,他们中的许多人都有某种工作保障
- 培训倾向于实践方面。通常重点是做——教你如何做的任务,自我驱动的项目,在那里你把你学到的东西放在一起。
缺点
- 一般不是认可的凭证。没有一个训练营真的有如此好的/公认的名字,以至于它们会被认为是你简历上的一个重要凭证。这只会对你的技能有所帮助。
- 未必有深刻的理论成分。许多训练营掩盖了机器学习/统计理论,支持你快速使用这些工具。不了解您正在使用的工具可能是危险的,并且会限制您对何时使用以及何时不使用某些算法的理解。
- 质量可能有所不同。有了硕士项目,至少你知道提供它的大学的声望。关于训练营,有很多值得怀疑的地方。在承诺任何事情之前,寻找评论。
选择训练营的一些额外建议
- 他们有某种拱顶石吗?作业和课程都很棒,但是一个能让你将所学应用到你所关心的事情中的自我驱动的项目也非常重要。这也给了你一个可以和潜在雇主谈论的项目。
- 他们的工作保障/支持是什么样的?有些项目没有任何工作保障。如果他们不愿意赌你在完成他们的项目后会找到工作,你应该赌吗?
一些有良好声誉的训练营:
这里有几个我认为值得一看的数据科学训练营。做任何决定之前,做你的研究和阅读评论!
- 跳板(有 750 美元折扣的推荐链接):完全披露,我现在已经为跳板辅导了几年。这也是我最喜欢这个项目的原因之一——他们为每个学生安排了一位行业专家作为导师,每周与他进行一对一的通话。他们也有工作保障和广泛的课程。它们是一个自定进度的项目,并且是远程的,所以它确实需要一些纪律来跟上课程并与社区保持联系。
- https://www.thisismetis.com/bootcamps/online-data-science-bootcamp:另一个备受尊敬的训练营。我对他们没有太多的经验,但我听说过他们的课程和工作支持。
- 洞察 :只接受博士学位,被录取者免费。他们有一个很棒的社区,但课程更侧重于拼凑一个演示文稿,这样你就可以开始与潜在的雇主交谈,而不是被结构化。
- 数据孵化器(推荐链接):这是我做的 bootcamp。这让我获得了我的第一份数据科学工作,我学到了很多东西,而且没有花费我任何东西。你可以在这里和这里阅读更多我对这个项目的想法。
硕士学位
优点
- ****凭证。无论对错,许多公司仍然将高等学位作为数据科学职位的要求。数据科学硕士学位会让你通过一些要求筛选,通常比训练营更受欢迎。
- 大学资源。与大型教育机构合作有很多好处,可能包括招聘会和职业部门。调查你正在考虑的大学的课程。
缺点
- 贵。与替代方案(训练营或自学)相比,即使是便宜的硕士课程也往往非常昂贵。
- 需要很长时间。硕士课程可能会有灵活的/兼职的选择,但最终,它们往往需要很长时间。这是有充分理由的——一个平衡的、广泛的数据科学教育需要很长时间。但是这确实意味着你将会花更多的时间在训练上,而不是像训练营那样走一条更快的路线。
- 讲师可能没有合适的经验。教授通常要么是没有多少行业经验的学者,要么是没有多少教学经验的行业数据科学家。大学很难找到合适的行业和学术经验的组合来为他们授课。
- 课程可能已经过时。数据科学发展迅速。部分是因为寻找具有最新培训的教师的问题,部分是因为项目主管本身并不总是最新的,学术项目很难教授该领域当前的最佳实践。
选择硕士项目的一些额外建议
- 考虑那些没有被贴上数据科学标签的项目。现代统计学和计算机科学程序通常是数据科学的绝佳入门,并且根据程序可能拥有更高的声望。
- 看使用的编程语言。很容易判断一门课程是否只是他们能找到的导师的大杂烩。确保课程全部(或大部分)用一种语言教授,最好是 Python。如果您需要为每门课程学习一门新语言,您将花费很少的时间学习数据科学,而花费大量时间摸索您不熟悉的编程语言。
- ****它是在一个特定的系里教授,还是跨系教授?不同的部门有不同的长处。跨学科项目通常能够利用不同部门的优势,如计算机科学、统计学、数学和商业。
结论
就是这样!我希望这有助于你选择数据科学项目。
您可能喜欢的其他文章
** [## 为什么大多数数据科学组合项目没有得到招聘经理的认可
towardsdatascience.com](/why-your-data-science-portfolio-project-sucks-208ee830ad1b) **
如何为数据可视化选择正确的颜色
原文:https://towardsdatascience.com/how-to-choose-the-right-colors-for-data-visualizations-faf290f9d1a5?source=collection_archive---------12-----------------------
数据即
创建有影响力的图表时,颜色在决策中的作用
照片由海伦娜·洛佩斯在 Unsplash 拍摄
本质上,图是由什么构成的?形状,线条,大概吧。肯定是一些文本元素。可能吧。但最重要的是:颜色。无论你选择黑白设计还是彩色设计,任何数据可视化的颜色都会对读者产生不可忽视的影响。
2017 年的一篇名为“可视化中的情感色彩”的研究论文展示了颜色在我们对数据可视化的情感解释上的力量。他们的结果“展示了如何操纵颜色和调色板属性来实现情感表现力”。例如,他们演示了轻微改变调色板如何将同一幅图的感觉从“严肃”转变为“有趣”。这只是告诉我们在数据可视化中,我们在颜色方面的选择有多么重要。
在进入问题核心之前,我们先举个例子来说服你。请看下面的两张图表:
作者的图表(基于随机测试数据)
哪一个最吸引你?如果你必须从两个图表中选择一个来说明一篇文章,你会选择哪一个?你可能更喜欢正确的,不是吗?然而,这两张图之间唯一的区别是颜色,仅此而已。
但在第二张图中,我特别注意选择有意义的(根据传达的信息)、一致的(与预定义的颜色代码一致)和容易理解的(特别是对色盲的人)颜色。在我作为数据分析师的整个经历中,我发现这三个要素是成功的数据可视化的关键。现在让我们进入细节。
1.让颜色有意义
对于许多决定来说,指导你决定图表颜色的首要问题是:你想传达什么信息?
清楚地陈述你的图表的目标会让你从显而易见的选项开始。正如电影导演比利·怀尔德所建议的:
“对观众来说不要太聪明。显而易见。让细微之处也显而易见。”
谁说数据可视化与电影如此不同?事实上,这就是我们想要通过我们的图表达到的目的:观众立即理解它的含义,并被传达的信息所说服。
例如,如果一个图表显示了两种趋势的相反演变,那么显而易见的选择将是为积极趋势选择一种具有积极内涵的颜色(如绿色),为消极趋势选择一种相反的颜色(如红色)。类似地,渐进演变可以用相同颜色的不同强度变化来表示。
根据你的文化背景以及你希望你的图表传达的感情,选择最有意义的颜色将有助于读者更好地理解和坚持你的图表。如果你想更多地了解用四种不同的方式给同一个图表着色对读者来说会有不同的意义,你可以参考这篇文章:
2.使颜色一致
现在你知道了如何确保你的图表通过所选的颜色传达正确的信息,你必须做出一致的选择。我的意思是:
- 选择有限数量的颜色
- 选择适合环境的颜色
- 一旦设定好,就坚持选择颜色
第一条规则是在一个图表中最多有 10 种不同的颜色,而 T4 倾向于 3 到 5 种不同的颜色。人脑是有局限性的,就像我们的眼睛一样。为了与我们的第一条建议保持一致:如果你想让你的信息清晰有效地传达给观众,避免与多余的信息混淆,比如太多的颜色。
第二,颜色必须符合图表呈现的背景:受众是谁(公众、同事、客户、董事会……)?将在哪种介质上呈现(数字介质,印刷在纸上……)?它将被哪些元素包围(在演示文稿中,在文章中,作为独立的图表…)?同一个图形可以有两组不同的颜色,但是一组比另一组与上下文更相关。
最后,颜色一致性的一个关键要素是坚持为给定的图形定义颜色后选择的颜色。根据我的个人经验,我习惯于为不同的利益相关者构建显示类似数据的仪表板。虽然每个仪表板彼此独立,但观众在查看图形时要习惯于给定的颜色代码,这一点很重要,无论图形显示在哪个仪表板中。让我们举一个首席执行官查看五个不同国家的仪表板的例子:对他们来说,在所有仪表板上有相同的“颜色代码”是最方便、最容易阅读的(例如,“产品 1”将始终显示在深蓝色#337d9e 中,等等)。).
3.使颜色易于使用
正如我们刚才提到的,展示数据可视化的受众和背景对其影响有很大的作用。当你微调颜色选择时,记住上下文。特别是,出现图形的不同设备可以显示不同的颜色变化。为了尽可能避免图形感知上的差异,请避免使用高度饱和的颜色或太浅的颜色,因为它们可能在不同设备上以错误的方式出现。
可达性的另一个方面是考虑有颜色缺陷的人。全球约 8%的男性和 0.5%的女性患有色盲。知道你的观众中有不可忽视的一部分可能是色盲,有一些方法来调整所选择的颜色,以显示所有人都能理解的颜色。一种简单的方法是选择具有不同饱和度值的颜色。此外,您还可以使用色盲模拟器,这是一个免费的在线工具,来测试图形是否是色盲安全的。
如果我们以我最初的例子为例,将两张图传入色盲模拟器,我们会发现右边的图比左边的图更适合色盲人群,因为颜色之间的对比更明显。
使用色盲模拟器显示的作者图形
获胜的组合
根据我的经验,我注意到让漂亮而强大的图表如此成功和令人难忘的是三个被低估的属性的组合:
- 使颜色有意义以使读者立即感觉到你的图形的吸引力
- 使颜色一致,使读者在从一个图形跳到下一个图形时不会迷路
- 使颜色易于使用使所有读者感到关注,并能够获得数据可视化技能的力量
你喜欢读这篇文章吗? 成为 的一员,加入一个不断成长的充满好奇心的社区吧!
如何选择合适的谷歌云平台数据库
原文:https://towardsdatascience.com/how-to-choose-the-right-google-cloud-platform-database-a223f4d7482f?source=collection_archive---------7-----------------------
向云及更远的地方!我抓住你了,范姆!
坦纳·博瑞克 上 Unsplash
选择正确的 GCP 数据库取决于很多因素,包括您的工作负载和所涉及的架构。今天,我将为大家提供流行的谷歌云数据库服务的概述,包括评估和选择服务时的关键考虑因素。
了解你的数据库
谷歌云平台(GCP)旨在提供一系列计算资源,数据库服务就是其中之一。GCP 有能力处理现代数据,具有高效、灵活和卓越的性能,是一个托管平台解决方案,用于跨地域传播数据。
在选择 Google 数据库服务时,应该考虑很多因素,比如数据的类型和大小、延迟、吞吐量、可伸缩性和 IOPs 等等。
GCP 主要提供三种全球数据分发参考架构模型:
1) 单一— 所有部署模式中最简单的一种,可以通过在 Google 上创建新的云数据库和/或“提升和转移”现有工作负载来部署数据库。
2) 混合— 当云中的应用程序需要访问本地数据库时,这些类型的部署非常有用,反之亦然。
部署混合模型(一些数据在 Google Cloud 上,一些在内部)时,有三个主要因素需要考虑:
主数据库:首先,你需要决定主数据库是存储在本地还是云端。一旦您选择了云,GCP 资源将充当内部资源的数据中心,而如果您选择了内部资源,您的内部资源会将数据同步到云中以供远程使用或备份。
托管服务:可用于云中的资源,这些服务包括可伸缩性、冗余和自动备份。但是,您可以选择使用第三方托管服务。
可移植性:根据您选择的数据存储类型,您的数据的可移植性也会受到影响。为了确保可靠和一致的数据传输,您需要考虑跨平台存储,如 MySQL。
3) 多云— 这些类型的部署可以帮助您有效地分发您的数据库并创建多个故障保险,因为它使您能够将部署在 Google Cloud 上的数据库与来自其他云提供商的数据库服务相结合,从而为您提供更广泛的专有云功能优势。
部署此模型时,有两个主要因素需要考虑:
集成:确保客户端系统可以无缝地访问数据库,不管它们部署在什么云上,例如,使用开源客户端库使数据库可以跨云顺畅地使用。
迁移:由于有多个云提供商,可能需要借助数据库复制工具或导出/导入流程在云之间迁移数据。Google Storage Transfer service 就是这样一个工具,可以帮助您进行数据库迁移。
云是极限:谷歌云平台数据库服务
GCP 提供了几种数据库服务供您选择。
云 SQL :
Cloud SQL 是一种关系型 GCP 数据库服务,完全由 MySQL、PostgreSQL 和 SQL Server 管理并与之兼容,包括自动备份、数据复制和灾难恢复等功能,以确保高可用性和灵活性。
何时选择:从本地 SQL 数据库到云的“提升和转移”,到处理大规模 SQL 数据分析,再到支持 CMS 数据存储和微服务的可扩展性和部署,云 SQL 有许多用途,当您需要关系数据库功能但不需要超过 10TB 的存储容量时,云 SQL 是更好的选择。
云扳手:
另一个完全托管的关系型 Google 云数据库服务 Cloud Spanner 不同于 Cloud SQL,它专注于结合关系型结构和非关系型可伸缩性的优势。它提供了跨行的一致性和高性能操作,并包括内置安全性、自动复制和多语言支持等功能。
何时选择:如果您计划使用大量数据(超过 10TB)并需要事务一致性,那么 Cloud Spanner 应该是您的首选。如果您希望使用分片来获得更高的吞吐量和可访问性,这也是一个完美的选择。
大查询:
使用 BigQuery,您可以通过 SQL 和查询流数据来执行数据分析。由于 BigQuery 是一个完全托管的无服务器数据仓库,其内置的数据传输服务可以帮助您从本地资源(包括 Teradata)迁移数据。
它整合了通过 BigQuery ML、BI Engine 和 GIS 提供的机器学习、商业智能和地理空间分析功能。
何时选择:【BigQuery 的用例涉及流程分析和优化、大数据处理和分析、数据仓库现代化、基于机器学习的行为分析和预测。
云大表:
这是一项完全托管的 NoSQL 谷歌云数据库服务,专为大型运营和分析工作负载而设计。云 Bigtable 包括高可用性和零停机配置更改功能。实际上,您可以将它与各种工具集成,包括 Apache 工具和 Google 云服务。
云 Bigtable 用例涵盖金融分析和预测、物联网数据接收、处理和分析,以及超个性化营销应用。
何时选择:如果您正在使用大量的单键数据,云 Bigtable 是一个不错的选择,并且更适合低延迟、高吞吐量的工作负载。
云火商店:
Cloud Firestore 是一个完全托管的无服务器 NoSQL GCP 数据库,旨在开发无服务器应用程序,可用于存储、同步和查询 web、移动和物联网应用程序的数据。凭借离线支持、实时同步和内置安全性等关键功能,您甚至可以将 Firestore 与 GCP 的移动开发平台 Firebase 相集成,从而更轻松地创建应用程序。
云 Firestore 用例包括具有在线和离线功能的移动和 web 应用程序、多用户、协作应用程序、实时分析、社交媒体应用程序以及游戏论坛和排行榜。
何时选择:当你的重点在于 app 开发,需要实时同步和离线支持的时候。
Firebase 实时数据库:
这是 NoSQL 谷歌云数据库,是 Firebase 平台的一部分。它允许您实时存储和同步数据,并包括离线使用的缓存功能。它还使您能够实现声明性身份验证,通过身份或模式匹配用户。
它包括移动和网络软件开发工具包,以简化应用程序开发。
Firebase 实时数据库的使用案例包括跨设备应用程序的开发、广告优化和个性化以及第三方支付处理。
云存储库:
Cloud Memorystore 旨在实现安全、高可用性和可伸缩性,是一个完全托管的内存 Google Cloud 数据存储,使您能够创建亚毫秒级数据访问延迟的应用程序缓存。
云内存商店的使用案例包括应用程序的“提升和转移”迁移、机器学习应用程序、实时分析、低延迟数据缓存和检索。
何时选择:如果您正在使用键值数据集,并且您的主要关注点是事务延迟。
选择关键问题的数据库
我还创建了这个流程图,它可以显示选择数据库的方向:
由 Anuj Syal 创建,异想天开的链接
寻找更多信息
我在 youtube 上制作了这个视频,详细介绍了这个话题
由 Anuj Syal 在谷歌云中选择数据库
我的想法
随着越来越多的企业寻求云服务来运行其核心关键系统,并作为启动其新应用的主要平台,选择正确的谷歌云平台(GCP)数据库开启了可能性,并可以成为交易撮合者,为客户提供最少的停机时间、安全且经济高效的服务和解决方案。
在 Linkedin 和 Twitter 上关注我
如果你对类似的内容感兴趣,点击 Medium 上的“关注”按钮,或者在 Twitter 和 Linkedin 上关注我
如何在组织环境中选择正确的文本分类模型
原文:https://towardsdatascience.com/how-to-choose-the-right-model-for-text-classification-in-an-organizational-setting-1a610a0418e1?source=collection_archive---------20-----------------------
行业笔记
在应用机器学习中,理解和忽略技术因素的重要性,或者,何时使用推杆走出沙坑。
从沙坑推球(作者的图片)
对于误入沙坑的高尔夫球,典型的反应是咒骂、叹息,然后拿着沙楔跋涉到沙坑。这不是一个艰难的决定。每个高尔夫球袋都有一个沙楔,不像所有其他关于使用哪个球杆的决定——我应该使用 5 号铁杆吗?混血儿?铁木?a 6 铁?沙坑有一个专门为它设计和命名的俱乐部。所以你可能会惊讶地发现,有些严肃的高尔夫专业人士建议,只要有可能,你应该在沙坑里使用推杆。为什么?如果有更好的工具,为什么还要推荐推杆呢?因为最好的工具并不是最适合这项工作的工具,它是你最擅长使用的工具。
如果你从事软件技术方面的工作,你可能经历过一个老工程师兴奋地告诉你他们 15 年前在 awk 中写的某个工具完美地解决了你的某个问题。知道正确的工作使用正确的工具是管理顾问拿这么多钱来提出计划的原因。管理顾问服务没有价值,因为他们是唯一聪明到足以解决难题的人,他们有价值是因为他们见过很多类似的问题,并且他们足够聪明到可以从中吸取教训。你的公司可能会被收购一次,但是三大巨头已经有了几个世纪的合并经验。老工程师的优势不在于他精通命令行工具,也不在于他比初级工程师更聪明,而是他之前已经看到了这个问题。
但是使用 awk 是一个好的解决方案吗?答案很少取决于 awktegenarian 计划的绩效,而更多地取决于当前的组织需求和能力。如果他离开了,或者其他人需要维护或修改程序,或者需要向主管解释程序,使用 awk(一种古老的命令行语言)比电子表格更糟糕,即使电子表格更慢,不能处理那么多数据,并且需要每次手动编辑数据 20 分钟才能使用。
在 Salesforce,我的团队为各种 NLP 任务开发和部署模型,但我们的主要工作是电子邮件的文本分类模型。拟合模型是双重的:您使您的模型适合您的数据和您使您的模型适合您的组织。在这篇文章中,我将从技术数据科学的角度,通过一个示例文本分类问题来说明我们在选择正确的问题模型时学到的一些见解。然后,我将向您展示如何抛弃这一切,以适应您的组织约束。
从技术角度来看,我们选择什么样的模型最终取决于我们的训练数据在多大程度上捕捉到了它将在生产中获得的数据的多样性。Salesforce 拥有大量不同的客户组织。有两个人的组织,也有上万人的组织。他们销售单元、包、许可证和合约。一些公司使用单一、简单的销售流程,另一些公司有几十种不同的渠道来销售各种产品。一些公司比其他公司更有可能允许我们根据他们的数据训练模型。因此,当我们创建数据集时,我们总是知道先验我们的训练数据既不完整又有偏差,这是我们在选择模型时考虑的首要问题。不管我们为手头的任务选择什么模型,它都需要在产品的生命周期中以合理的成本进行部署、扩展和维护。销售人员需要能够向客户演示,产品经理需要能够向高管演示。这些组织需求通常比技术需求更重要。
任务和语料库:
这篇博文的示例任务是将一个句子归类为疑问句/非疑问句。我选择这个是因为这是一个简单的、定义明确的任务,而且我们对问题的定义基本一致。大多数有趣的文本分类任务会涉及到大量的定义争论,比如“我们什么时候一起吃午饭吧”是不是一个调度请求。
对于语料库,我使用的是由杰克·金斯曼准备的数据集。这个数据集对我们的目的特别有用,因为它包含了大量的问题(占句子的 33.81%),这些问题是容易标记的(没有一个遗漏问号),并且许多问题(71.94%的问题)是不合语法的反问句,这给了这个问题实质。(因为我是出于研究目的使用这个语料库,所以数据集的具体内容并不重要,除了有许多带有特殊语法的问题。)有三种基本类型的问题。首先是使用五个 w(19.55%)的 疑问句 ,例如“当巫师和术士透露他们所拥有的东西时,到底发生了什么?”接下来是是-否问题产生是或否的回答(8.51%),比如“它真的来自也门吗?”或者“你会回答吗?”最后是不符合语法的反问句(71.94%),比如“日期公布(早)?”或者“与外国演员合作付款/分散资金?”
因为这个数据集中的所有问题都包含一个问号,所以我通过简单地出现一个结束问号来将每个句子标记为一个问题/不是一个问题。然后,我将数据集分成 80/20,用于训练和测试。因为确定哪种建模方法最适合数据的主要区别归结为“您的问题复杂吗?您的训练数据有多完整?”我操纵数据集来创建不同但相似的上下文,以观察训练数据如何很好地捕捉测试数据的多样性。在第一个数据集中,测试集没有被改动。在第二个数据集中,我从测试数据中删除了所有的问号。在第三个数据集中,我删除了问号,并用一个未知标记(“XXXXX”)屏蔽了测试数据中的五个 W。在第四个数据集中,我只对是非问题(和非问题)进行测试,并且在没有任何是非问题的情况下进行训练。我也从测试数据中去掉问号。在第五个数据集中,我采用了第四个数据集,但也从训练集中删除了问号。下表描述了数据集及其差异。
前期底线:
我对根据您的数据拟合模型的最后建议非常简单。如果你的类与一小部分特性紧密相关,那么使用正则表达式。如果将你的类分开需要更复杂的规则,并且你的训练数据捕获了你的测试数据的多样性,那么使用传统的机器学习,并且作为最后的手段,使用深度学习。当然,数据的“捕获多样性”不是一个精确或可量化的指标,所以我将遍历不同的数据集,并显示随机森林在哪里足够接近(数据集 1、2、3 和 5),以及在哪里不够接近(数据集 4)。下面的流程图总结了这一点:
不探究数据,很难(解读:不可能)知道这些问题的答案,。在某种意义上,您可以使用正则表达式来回答您的类是否可以用一小组功能来划分,因此应该使用正则表达式,您可以使用机器学习来确定您的训练数据是否捕捉到了野外数据的多样性,因此应该使用机器学习。这里的挑战不是技术上的,而是情感上的。一旦你创建了一个模型,尤其是你努力工作的模型,很难删除它。但是过分看重你的模型会阻止你做正确的事情。愿意创造模型,而且要小心谨慎地去做,然后把它们扔掉。你必须愿意谋杀你亲爱的人。
我在某种程度上回避了探索以了解数据的需求,因为我们已经知道了很多关于问题的信息,而不探索这些数据,疑问词形成了一个封闭的类别,并且问题的语法很少出现在问题之外。这有点像开始一个项目,在探索了一个月之后发现它表现得出奇地好,但这是一篇更好的博文,因为我们可以直接进入问题的实质。
从正则表达式开始
如果可以用一小组特性来划分类,那么 RegEx 是最好的方法。如果每个问题都包含一个结束问号,并且结束问号不会出现在文本中的其他地方,那么使用 RegEx 将是完美的。我可以只寻找一个终结问号的存在,但这是一个不切实际的坏的稻草人。请记住,我们已经知道了很多关于问题的知识,如果我们不知道,我们会一直探索数据,直到我们知道,人们并不总是使用问号(例如在随意的谈话,聊天,语法错误等。)并且这些问题倾向于使用五个 W 中的单词。所以我做了两个正则表达式分类器:一个只寻找结尾问号和五个 W,我称之为脆弱正则表达式分类器,另一个做同样的事情,但另外寻找是非问句的句子开始模式,我称之为健壮正则表达式分类器。除了结尾问号之外的附加模式以牺牲精确度为代价提高了召回率。比如句子“我们知道这是什么意思。”是对五个 W 的模式的肯定匹配,但不是一个问题,并且“这是关于病毒还是其他什么”将产生对 Robus 正则表达式分类器的肯定匹配,而不是对脆弱分类器的肯定匹配。这两个正则表达式分类器说明了理解数据的价值。
**
在数据集 1 上,测试数据仍然有问号,两个正则表达式分类器都表现得非常好。在数据集 2 上,测试用例丢失了问号,两个分类器的召回率和精确度都下降了,但没有下降到零,这要归功于除了终端问号之外的附加特征。在数据集 3 上,测试用例缺少问号,问题词被屏蔽,这两个模型在性能上有差异。健壮的正则表达式分类器的召回率进一步下降,因为现在只有是非问题模式会发现问题,是非问题是少数问题,但是脆弱的正则表达式分类器的性能一直下降到零。在数据集 4 和 5 上,健壮的正则表达式分类器再次具有优异的性能。
我们如何改进健壮的正则表达式分类器在数据集 1、4 和 5 上的性能,它在这些数据集上表现良好?由于召回几乎是完美的,我们希望提高精确度,也就是说,找到一种减少误报的方法。这样做的第一个方法是将异常添加到我们的模式中。我反对这样做。
随着您添加异常,您将开始注意到一些异常需要更多的异常,等等。如果你继续沿着这条路走下去,你将会积累严重的技术债务。我最喜欢的论文之一是一篇关于自动断字程序的内存分配的论文。该算法通过规则、例外和例外对例外进行连字符连接,大约有五层深。这种嵌套的 if 语句算法非常强大,速度也非常快,但是众所周知,它很难调试或理解。此外,很容易为新案例添加规则,并且在不了解原因的情况下无意中使您的性能变得更差。正则表达式有一个额外的好处,那就是写起来比读起来容易得多,所以当你创建更多的异常、更细致入微的正则表达式时,你的系统会变得更难理解、更难调试、更难适应新的情况。
正则表达式分类器的性能在数据集 2 和 3 上直线下降,原因很好:正则表达式挑选出的特征不再与我们希望分离的类相关。那么,对此有什么办法呢?我们需要查看数据,并创建更多我们认为可以捕捉差异的模式,但是一旦我们走得太远,模式变得难以管理(主观评估),就该标记数据并让数据决定如何将特征映射到类。即使是最好的正则表达式有时也需要删除。这就把我们带到了下一个方法:机器学习。
开发一个 ML 模型
一旦你开始沿着规则和异常,异常到异常的路径,或者手动调整特性和类分离的路径,就到了机器学习的时候了。如果你发现自己试图实现三个层次的词典排序规则,那么你很早就犯了一个错误,导致你走到了人生的这一步。对于机器学习方法,您需要标记数据,如果您开始制定足够复杂的 RexEx 规则,您可能已经有了一组不错的样本数据。让我们看看随机森林模型在五个数据集上的表现。
ML 模型性能的直觉比 RegEx 分类器简单得多:当训练和测试数据更相似时,模型性能更好。数据集 1、2 和 3 实际上都具有相同的训练数据,并且仅在它们的测试数据上有所偏离,这些测试数据顺序地离训练集越来越远。
从测试集(数据集 2)中删除问号会导致性能明显下降,因为模型关注的主要特征是问号。事实上,问号和句号是两个最重要的特征,而且相差一个数量级。我选择随机森林模型有两个原因:它在各种上下文中表现良好,并且它通过测量每个特性的公开误差来提供特性重要性。像许多事情一样,特征重要性“有点像概率”,但也不尽然——但对于每个特征来说,重要性是一个介于 0 和 1 之间的数字,它们加起来就是一个。对于一个重要的特征,通常必须选择在我们的随机森林中对小决策树进行分支,这意味着它既有力地分隔了类别,又相对频繁地出现。如果您最强大的特性在测试集中不经常出现(或者根本不出现),性能就会下降。下面是在五个数据集上训练的随机森林模型的要素重要性表。
所有的模型都需要训练数据在某些重要的方面类似于野外的数据,在这种情况下,重要的是它们被特征化的方式。有两种方法可以将这种关系形象化。第一个是看看在不太重要的特性列表中,你必须深入到什么程度,直到你拥有了出现在大多数测试用例中的特性。**
这个图更容易阅读,但是它掩盖了这样一个事实:随着你对特性的深入研究,它们变得越来越不重要,也就是说,它们出现在更多的测试用例中,但是它们对于划分你的类来说不是很有帮助。我们的特征受制于 Zipf 定律,这意味着这个词的频率与它在频率表中的排名大致成反比。区别性特征很可能不常见。问题识别任务回避了一些问题,因为五个 W 和问号是一个封闭的集合,并且相对频繁地出现,但是尽管如此,排名较低的特征明显不太频繁。为了捕捉这一现象,我做了另一个更难读懂的图,如下:
x 轴是累积的特性重要性,y 轴是包含任何 n 元语法的测试用例的百分比。例如,在数据集 1 中,前两个特征('?“还有“.”)占重要性的 40%多一点,并且出现在几乎每一个测试用例中。ML 模型在数据集 1 上表现良好,因为最重要的特征经常出现在测试用例中。另一方面,数据集 4 说明了几乎相反的情况:大多数重要的特性并没有出现在尽可能多的测试用例中,并且只有当我们进入越来越不有用的特性时,这个百分比才开始上升。
这是你可以用来先验地确定你的训练和测试数据不够相似的东西吗?大概不会。你必须认真仔细地开发模型,确定这个模型不行,然后你必须谋杀你亲爱的模型。每次你都要进入数据。希望这一部分有助于建立你的直觉,理解模型从训练数据的特征化中学到了什么,以及它如何容易地将这种理解应用于测试数据。
缩小差距的一个方法是从你的训练数据中删除信息,以防止过度拟合某些在你的得分数据中不常出现(或从不出现)的特征。数据集 5 与数据集 4 相同,只是在训练数据中没有任何问号。性能显著提高,问号从重要特性列表中消失。如果你不能修改你的数据,试着寻找更多的数据源,最好是那些直接来自或代表你实际评分数据的不同维度的数据源。联系你团队中的其他人或者附近的团队,看看他们是否能想出一些你的模型难以处理的例子。其他团队的人喜欢拿出例子来证明他们比你的模型更聪明。当我在 SlackBot 中提供我们的模型时,我发现我的同事可以想出令人惊讶的反例深度(稍后将详细介绍)。在你刷掉 TensorFlow 之前,试着多找些训练数据。如果你只能做到这些,那就该深度学习了。
作为最后手段的深度学习
你已经得出结论,你的训练数据没有捕捉到你将在野外看到的数据。有各种各样真实的,可以原谅的原因来解释你为什么会沦落到这种境地。也许在收集数据时出现了错误。也许你的 MSA 只覆盖了你的一部分用户,所以你从选择加入的数据中得到一个有偏见的样本。也许你购买了一个类似的数据集,但是它已经过时了,或者不可行。无论你认为你的训练数据没有覆盖野生环境中的数据,以及你无法增加或修复你的数据集的原因是什么,都是时候进行深度学习了。
深度学习非常流行,而我远不是这方面的专家。深度学习似乎可以稳健地处理各种任务,前提是你有足够的数据让它优化大量参数。我尝试了一个简单的双向 LSTM 模型,它做得非常好。
更重要的是,它在所有五个数据集上表现稳健。所以我为什么不推荐你每次只用深度学习,然后收工呢?
如果你还记得,这篇博文是关于如何选择合适的模型。其中一部分意味着选择适合您的数据的模型。另一部分是选择适合您组织的模型。正则表达式在组织环境中有很多优势。它们不需要 GPU 来训练,并且可以作为您已经部署的任何代码的一部分来部署。如果你的主管或经理坚持某个具体的例子有效,你可以确保它有效。如果我们非常诚实的话,正则表达式几乎不需要标签数据的少数正面例子。深度学习模型需要 GPU、大量的标记数据和充足的时间来探索巨大的超参数空间。如果你训练一个深度学习模型,但你的公司以前从未部署过,或者你自己将要部署它,这可能会花费你的项目几个月或几年的时间。您可能更喜欢 F1 分数较低的普通 ML 模型,但是它可以由其他人及时部署和维护。
如果我要告诉你,正确的模型是一个你可以用你所拥有的资源来部署的模型,用你可以得到的数据来训练,在你的老板有耐心的时间内,为什么我要经历所有这些详细的技术分析?如果你试图让一个模型适应组织,而不知道如何首先让它适应数据,你将不会成功。我将分享一些我为 Salesforce 设计签名解析器模型时的例子。
我有三个组织约束,我需要我的模型来适应。第一个是部署模型的团队用 Kotlin 为 Kafka Streams 编写了 jobs。因此,我需要将我的模型打包成一个可部署为 JAR 的库。这意味着我的团队之前使用的两个机器学习框架——ml lib和 TensorFlow 已经过时了。我最终使用了 SMILE (由李海锋编写),因为它在 Scala 中提供了最少的机器学习功能,并自己实现了我的数据科学工作流所缺少的工具。第二个约束是签名解析器需要接受个人身份信息(PII)的训练,但是我们在 Salesforce 的客户数据中不使用 PII。因为签名是* PII,所以我最终编造了训练和测试数据,与我们客户的数据有统计上的相似性,但没有实际使用他们的数据。我在这里写了关于数据伪造的文章。最后,我让标题评分模型作为 Slack Bot 在内部可用,并发现产品经理有几个标题,他们只需需要来查看它的正确评分。理论上,解决这个问题的正确方法是经历标记更多数据和重新训练模型的艰苦过程,但这很耗时,而且还有十几个其他项目更需要我的关注,所以我创建了 Otherwise 模型。我在模型前面放了一个简单的正则表达式,它处理他们需要的特殊情况,否则我的 ML 模型会完成这项工作。*
PS 如果你想知道,这里有一个图表,比较每个模型与每个数据集的 F1 分数。请注意,这里没有一处提到构建新的基础设施和组件来大规模支持 TensorFlow 是非常重要的。
如何为您的数据团队选择正确的结构
原文:https://towardsdatascience.com/how-to-choose-the-right-structure-for-your-data-team-be6c1b66a067?source=collection_archive---------10-----------------------
现场笔记
在高速发展的初创公司建立数据团队的最佳实践,从雇佣你的第一个数据工程师到 IPO。
图片由 常阳 上 下 。
关于死亡,莎士比亚的哈姆雷特曾经说过:“ 生存还是毁灭,这是个问题。”
关于她的数据团队,某创业公司一位睿智的数据负责人曾经说过: “集中还是分散,那是个问题。” 而且是很重要的一条。
以下是一些最佳数据领导者如何应用敏捷方法来构建可随公司发展而扩展的数据组织。
随着初创公司越来越多地投资于数据,以推动决策制定并为其数字产品提供支持,数据领导者面临着快速扩展团队的任务。从了解招聘哪些角色(以及何时招聘)到为数据 设置SLA,当今的数据领导者负责——毫不夸张地说——在旅程的每个阶段保持对公司的洞察。
无论您处于这场马拉松的哪个阶段,最大的挑战之一就是为您的数据团队确定合适的报告结构。
随着数据需求的增加,集中式数据团队带来的瓶颈也在增加,分散式数据团队带来的重复和复杂性也在增加。就在你认为你已经找到了“完美”的范例(即,一个中央数据工程团队、分布式数据分析师、一些分析工程师来弥补差距!或者一些数据分析师与在首席技术官手下工作的数据工程师一起向首席运营官汇报工作!),当优先级发生变化时,你的整个策略就会发生变化。
那么,数据领导者应该做些什么呢?
为了更好地了解一些最好的团队是如何解决这个问题的,我与https://www.linkedin.com/in/greg-waldman-a843b130Toast的高级商业智能总监坐下来,讨论他公司数据团队的发展,并分享他在这些集中和分散结构之间永无休止的拉锯战中的经验。
在过去的五年里,Greg 带领 Toast 数据团队从一名分析师(Greg 本人)成长为一个 20 多人的组织,并从集中模式发展为混合分散模式,然后再回来。
请继续阅读,了解 Greg 的团队如何让业务需求驱动数据团队结构,他如何知道何时有必要做出这些改变,以及他希望早点聘用的关键角色。
开始时:当一个小团队努力满足数据需求时
当格雷格在 2016 年加入 Toast 时,该公司已经有 200 名员工,但没有专门的分析人员。尽管缺乏专业人才,但该公司一直优先考虑使用数据来做出决策。
“我们的创始团队非常精明,”格雷格说。“他们用 Excel 文档管理公司,但最终当他们有 200 人时,他们知道这种方法无法扩展。当我来的时候,问题基本上是这样的,“我们有太多的会议,一个人认为数字是 5,而另一个人认为数字是 4,然后他们就一直为此争吵。所以,不要让这种事情发生。"
Greg 立即钻研并开始构建工具、流程和基本的数据程序。第一年,Toast 数据团队增加了两倍,现在有三个人。该公司继续使用数据来推动其文化和决策。
“每个人都说他们有数据驱动的文化,但我在足够多的地方工作过,知道其中的区别,我看到了与吐司相比的并列,”格雷格说。“我们整个公司的人——尤其是我们的领导层——在做出重大决策之前都会认真寻找数据。”
但是,尽管小型数据团队增加了两倍,Toast 本身却增加了一倍。到 2017 年,该公司拥有 400 名员工。集中式数据团队无法满足整个快速增长、数据至上的组织的需求。
“我们在门外排起了长队,”格雷格说。“人们渴望获得比我们所能提供的更多的数据。我认为这对我们来说是一个转折点。因为如果您找不到满足这种需求的方法,那么业务可能会开始以不同的方式运营,并且如果您无法为他们提供必要的数据,那么数据驱动力就会减弱。”
支持作为分散数据操作的超增长
随着各部门开始寻找满足自身数据需求的方法,向分散式结构的转变开始形成。
“最终,公司的其他部门也出现了小规模的分析,比如销售和客户成功,”格雷格说。“主要是因为我们的小团队无法满足不断增长的业务需求。所以他们成立了自己的团队,这种方式很有效!”
2018 年,这个由 10 名数据专业人员组成的分散团队在业务部门内工作,满足了数据需求,并支持了 Toast 的快速发展,因为该公司的规模几乎再次翻了一番,员工人数增长到 750 人。Greg 和他的团队还重建了他们的数据技术堆栈,从端到端数据平台迁移到现代分布式堆栈,包括 s3、Airflow、Snowflake、Stitch 和 Looker。
在其业务部门工作的专职分析师仍然与 Greg 的核心分析团队保持密切联系,这使得 Toast 成为完全集中和完全分散的数据团队结构的混合体。但随着该组织不断扩大规模-2019 年达到 1,250 名员工,拥有 15 名数据分析师、数据科学家和数据工程师-这种混合模式开始出现问题。
数据一致性是一个问题。“当谈到什么是好数据时,整个组织有不同程度的严格性。当你很小的时候,你很好斗,你在成长,任何数据都比没有数据好。但最终,我们认识到不准确的数据可能是有害的。”
即使有技术上准确的数据,Greg 也知道,在建立整个公司的数据可观察性和信任标准时,分析师、技术负责人和下游利益相关者之间的强大沟通是至关重要的。
“随着业务变得越来越大和越来越复杂,你需要分析师开始看到整个业务,”格雷格说。“即使在一个分散的模型中,当涉及到围绕性能和可操作性设置标准时,你也需要确保分析师与其他分析师和技术领导者密切合作。”
重组、重新集中和重新关注数据信任
在评估如何构建他的数据团队时,Toast 总是权衡三种选择:集中式、分散式和混合式,随着时间的推移,他们尝试了每种选择的规模。最终,他发现混合模式对于他的分析团队的规模和范围来说是最有效的。图片由 Greg Waldman 和 Toast 提供。
因此,Toast 将一直在各自的客户成功和走向市场团队下工作的分析师带回到了一个分析保护伞下。
“我们最终实现了集中化,一个讨论过但被低估的好处就是团队中的人们从彼此身上学到了多少东西,”Greg 说。该团队现在是财务和战略部门的一部分。但他知道中央集权的结构可能不是土司的长期解决方案。
“简而言之,我对数据团队的看法是,你希望每个人尽可能多地增加商业价值,”Greg 说。“我们一直非常乐于改变和尝试不同的东西,并理解适用于 200 人、500 人、1000 人和 2000 人的答案是不同的,这没关系。“当你到达那些转折点,需要尝试新事物时,这一点可能会变得有些明显。”
归根结底,无论这对您团队的报告结构意味着什么,都是为了满足业务需求,同时确保技术线索是分析师的推动因素,而不是瓶颈。
扩展创业公司数据团队时要记住的 4 件事
最终,Greg 的团队选定了一个带有少量分布式元素的集中式数据团队结构,为他们提供了对数据产品更大的所有权和治理能力,以及构建可扩展的模块化数据堆栈的能力。图片由 Greg Waldman 和 Toast 提供。
Greg 为在超高速增长的公司中面临类似挑战的数据领导者提供了一些来之不易的建议,但每种策略都回到了他的原则,即专注于哪种方法最符合您公司的业务需求,这可能会随着时间的推移而改变。
简而言之,他建议,领导者应该保持敏捷,团队应该愿意适应业务需求。以下是方法。
雇用数据通才,而不是专家,但有一个例外
Greg 认为,你应该雇佣的第一个专家是数据工程师。
Greg 说:“早期,我们基本上只是雇佣了能做一点点事情的数据运动员。“我们让这些运动员扮演分析师/数据工程师。我有一个高级经理的职位空缺,一个数据工程师申请了,但她对管理没有任何兴趣。当我和她交谈时,很明显我们团队非常需要专门的数据工程技能。回想起来,考虑到我们的增长轨迹,我应该在一年前就寻找这样的人。”
很多时候,数据团队会因为缺乏构建和维护 ETL 管道所需的技术支持而束手束脚,并确保底层的数据基础设施能够根据公司的分析需求进行扩展。
“因此,尽管我仍然相信应该雇佣那些什么都能做的数据运动员,但数据工程师是个例外。在你雇佣了几个分析师之后,你的第一个数据工程师应该紧随其后。”
从第一天开始就优先考虑建立一个多样化的数据团队
这是不言而喻的,但是当涉及到为长期成功建立你的团队时,你需要(早期)投资于具有不同经历和背景的候选人。同质化是创新的阻碍,它阻碍了数据分析师和工程师理解所有数据消费者的观点和需求。
然而,当你大规模快速行动时,可能很难记住这一点——除非你制定了一套反映这一目标的清晰的招聘和增长 KPI。
格雷格说:“尽早考虑多样性。“因为特别是在这些小型数据团队中,如果你不小心,你最终只会和一群来自相似背景的志同道合的人在一起。你不想要一群相同的人——你需要不同的视角。”
说‘我们需要建立一个多元化的团队’是一回事,但要做到这一点完全是另一回事。那么,数据领导者应该如何入门呢?
这里有几个小技巧:
- 与高管和你的人员团队合作,撰写包含不同经历和背景的工作描述(例如,避免使用过于男性化的语言,使用中性语言)
- 将不同的招聘小组放在一起(即使他们不是从数据团队中挑选出来的),以体现你正在努力建立的团队
- 广撒网,招聘可能没有传统数据头衔或角色的候选人;这是一个不断发展的空间!
- 实施不分性别或种族的申请流程,根据资格和经验进行筛选
“在创业旅程的后期,建立一个多元化的团队要困难得多,因为来自不同背景的人希望加入一个由不同背景的人组成的团队。如果你一开始就没有考虑到这一点,事情会变得更具挑战性。”
过度沟通是变革管理的关键
这一点在我们“远程优先”的世界中更加重要,在这个世界中,许多团队在家里工作,通过电子邮件、Slack 和信鸽(开玩笑!)是任何工作的必要组成部分。
红点风险投资公司(red point Ventures)的董事总经理托马斯·通古兹(Tomasz Tunguz)表示,公司应该始终如一地向客户重复自己的 (即他们的核心价值主张),即使这看起来没有必要。当涉及到与数据利益相关者交流他们的工作和任何团队变化时,数据领导者也是如此。
例如,如果你的分散的客户成功分析师在客户成功主管手下工作 3 个月后将向分析主管汇报,你不仅应该传达这种变化正在发生,而且还应该重申这种调整不会改变你的团队产出的性质。即使团队不再分散,涉众仍然可以期望映射到核心业务目标的准确、及时的分析。
虽然结构变化不可避免地会影响利益相关者(职能团队)和服务提供者(数据团队)之间的关系性质,但是整理、交流和重复这种转变如何不会影响您团队的 KPI 将会恢复善意并帮助跨职能团队克服变化。
格雷格说:“如果你让分析师向企业领导人汇报,确保他们有权根据他们看到的数据进行反击。”“否则,这可能是一种微妙的动态,鼓励他们展示支持轶事假设的数据。当你将这些团队重新纳入分析体系时,你的分析师们将相互学习,但影响其他部门可能会很有挑战性。”
最近,Toast 一直在运行一个很大程度上集中的分析模型,该模型表现良好,满足了过去一年半的业务需求。
不要高估“单一的真理来源”
“单一真实来源”或黄金数据的概念是一个强大的概念——理由很充分。努力实现指标一致性和一致的干净数据有助于公司相信他们的数据为他们指明了正确的方向。尽管如此,作为一个超增长创业公司的数据领导者,你会在任何给定的时间参与大量的实验和项目——只要你有对数据信任的方向性https://www.montecarlodata.com/data-observability-the-next-frontier-of-data-engineering/(即,这张表是最新的吗?我知道谁拥有这个数据集吗?为什么 50 排变成了 500 排?),对“单一真相来源”的需求就没有那么迫切了。
“我总是告诉人们不要高估整个‘单一来源的真相’的概念,”格雷格说。“作为一个完美主义者,我花了很长时间才学会这个。有时候你需要做到 100%正确,但也有很多时候你做不到。通常,方向的准确性是好的,而你试图做到完美只会浪费资源。80/20 法则是关键。”
数据总是杂乱的,很少是完美的。如果您优先考虑端到端的数据健康和准确性视图,而不是更精细的控制,您将完成更多工作。
Greg 给数据领导者的最后一条建议?
“雇佣沟通能力强的优秀人才,其他一切都会变得容易得多。优秀的人会带你找到其他优秀的人,你可以雇佣世界上最聪明的人,但如果他们不能把自己的分析传达给不太懂技术的人,他们就不会成功。”
想了解更多关于建立成功数据团队的信息?伸出手去 巴尔摩西 和 蒙特卡洛团队 。
python 中如何对手写数字进行分类
原文:https://towardsdatascience.com/how-to-classify-handwritten-digits-in-python-7706b1ab93a3?source=collection_archive---------33-----------------------
没有任何机器学习库的帮助
如果你已经阅读了本系列的前几篇文章(页面底部的链接),你应该已经完全从基本原理构建了一个 DNN 类。让我们看看是否可以使用这个类来创建一个能够读取手写数字的神经网络。
这是一个经典的例子,说明对于我们人类来说很容易做到的事情,但是要编写一个程序来完成同样的任务却非常困难。在我们人类对图片进行分类的情况下,让我们想想正在发生什么。对于观看图像的人来说,大脑接收光子形式的输入,并基于该输入对图像进行分类。
基于此,我们可以说,击中我们眼睛的光子和图片的内容之间一定有某种关系。很明显,对吧?当然,图片看起来是什么样子和图片是关于什么的有关系。但是,数学建模需要这个命题;
根据我们从图片中接收到的输入(光子),存在某种数学函数可以告诉我们图片中有什么。
使用神经网络,我们将很容易找到这个极其复杂的函数。
获取和清理我们的数据
本着推进人工智能的精神,修改后的国家标准与技术研究所(MNIST)收集了数以万计的手写数字照片,每张照片都有一个标签。这个数据可以在这里下载。下面是其中一个数字的例子。
此图标注为 a 3。*****图片作者***
现在,对于我们人类来说,我们接收光子进入眼睛的输入。类似地,对计算机来说,这张图片只是像素值的矩阵。这些像素值的范围从 0 到 255(因为图像是黑白的),如下所示:
图片作者
这些图片是 28X28,784 像素值。我们的目标是将这些 784 像素的值映射到所写的数字。那么,我们开始吧。我们先来看数据。你应该已经从我上面提供的 Kaggle 链接下载了一个 zip 文件夹。解压缩文件夹后,您会看到一个 mnist_test 和 mnist_train CSV 文件。目前,我们将只关注 mnist_train CSV。下面我用 pandas 打开文件,然后显示文件的内容。
**import pandas as pd
import numpy as np
import matplotlib.pyplot as plt****data = pd.read_csv(‘mnist_train.csv’)**
图片作者
如您所见,该数据的第一列是标签(图像表示的数字),其余是图像的像素值(总共 785 列)。每一行都是一个单独的图像。使用 pandas iloc 功能,我们可以将输入与标签分开。此外,我们确保输入在 0 和 1 之间正常化。
**labels = np.array(data.iloc[:,0])
x_train = np.array(data.iloc[:,1:])/255
# We divide by 255 so that all inputs are between 0 and 1**
我们的下一步可能看起来很奇怪,但却是至关重要的。现在每个标签只是一个数字或一维。这意味着神经网络必须输出 0 到 9 之间的正确数字。我们可以通过将输出的维度增加到 10 个维度,每个维度对应一个数字,来使我们的神经网络的分类任务变得更容易。例如,我们将更改标签“0”,使其为“[1,0,0,0,0,0,0,0,0,0],' 1' = '[0,1,0,0,0,0,0,0,0]等等。这被称为“一热编码”,我这样做我们的标签如下。
**encoded_labels = []
for i in range(len(labels)):
naked = [0,0,0,0,0,0,0,0,0,0]
naked[labels[i]] = 1
encoded_labels.append(naked)**
现在我们可以使用 matplotlib 来检查这些图像实际上是什么样子。
**# Take a look at what the images look like
random_index = np.random.randint(0,40000)
img = x_train[random_index].reshape(28,28)
plt.imshow(img, cmap = “gray”)**
正如你所看到的,我们的神经网络真的有它的工作要做,用这些图片…
图片作者
创造我们的神经网络和训练
我们将使用在本文之前创建的 DNN 类(在这里找到)。每个图像有 784 个输入和 10 个输出,我将选择一个有 1250 个神经元的隐藏层。因此,我们的层应该是[784,1250,10]。在 for 循环中,我们简单地生成一个随机索引,然后对与该索引对应的数据和标签运行 train 函数。我还每 1000 步打印一些有用的信息,见下文:
**model = DNN([784,1250,10])****from collections import deque
error = deque(maxlen = 1000)
"""A deque is just a list that stays at 1000 units long (last item gets deleted when a new item gets added when at length = 1000)"""****for n in range(30000):
index = np.random.randint(0,59998)
error.append(model.train(x_train[index], encoded_labels[index]))
if n%1000 == 0:
print(“\nStep: “,n)
print(“Average Error: “, sum(error)/1000)
plt.imshow(x_train[index].reshape(28,28), cmap = “gray”)
plt.show()
print(“Prediction: “, np.argmax(model.predict(x_train[index])))**
结果和测试
在我的电脑上仅仅过了 5 分钟,神经网络就能正确识别大多数数字。10 分钟后,神经网络似乎已经完全训练完毕,平均误差达到 0.2 左右。重要的是不要过度训练模型,这会导致神经网络只是记忆图像,这将使它在预测它从未见过的事物方面非常糟糕。
让我们使用我们下载的那个 mnist_test.csv 文件来看看我们的神经网络对它以前从未见过的数据执行得有多好。下面我对 mnist_test 文件中的每张图片调用 predict 函数,然后检查预测是否正确。然后我计算这个神经网络正确预测的百分比。
**test_data = pd.read_csv(‘mnist_test.csv’)
test_labels = np.array(test_data.iloc[:,0])
x_test = np.array(test_data.iloc[:,1:])/255****correct = 0****for i in range(len(test_data)):
prediction = np.argmax(model.predict(x_test[i]))
if prediction == test_labels[i]:
correct +=1****percent_correct = correct/len(test_data) * 100
print(percent_correct,’%’)**
以下是该项目的最终代码:
我最后得了 93.5 分。随意尝试训练更长的时间,增加层数和/或神经元数,改变激活函数或损失函数,改变学习速率,看看这是否可以改善。虽然 93.5%非常令人兴奋,但我们实际上可以做得更好。我们可以让神经网络能够识别图片中的独特特征,以帮助它识别图像。这是卷积神经网络背后的思想,我将在以后的文章中详细解释。
感谢您的阅读!如果这篇文章在某种程度上帮助了你,或者你有什么意见或问题,请在下面留下回复,让我知道!此外,如果你注意到我在某个地方犯了错误,或者我可以解释得更清楚一些,那么如果你能通过回复让我知道,我会很感激。
这是一系列文章的继续,这些文章从头开始对神经网络进行了直观的解释。其他文章请参见下面的链接:
第 1 部分:什么是人工神经网络
第二部分:如何从零开始训练神经网络
第 3 部分:全面实施梯度下降
第 4 部分:梯度下降的实现(示例)
第 5 部分:如何用 python 对手写数字进行分类
如何用 SQL、Tableau 和 Google 搜索清理地理地名
原文:https://towardsdatascience.com/how-to-clean-geographic-place-names-with-sql-tableau-and-google-search-6a58e8bc50ae?source=collection_archive---------23-----------------------
实践教程、数据工程、数据清理、SQL 和 Tableau
使用熟悉的工具检测和清理不干净的地理数据
由 NASA 在 Unsplash 上拍摄的照片。
“垃圾进,垃圾出。”匿名的
介绍
任何数据工程、数据分析和数据科学项目的生命周期都包括数据清理过程。清理数据的主要目的是检测和纠正损坏、不准确或不完整的数据记录。此外,有效的清理有助于确保数据分析或数据科学产品完整准确地传达所需信息。
最近在一家大型企业任职时,我在 Tableau 中开发了一个员工差旅分析仪表板。我使用 SQL 从旅行请求和管理系统的 IBM DB2 数据库中获取数据。
每个旅行请求包括目的地城市、州或省(如果适用)和国家,以及许多数据元素。不幸的是,差旅申请 web 表单没有对这些字段执行任何编辑检查,因此差旅申请人拼错了许多地名,并用不正确的地理位置填充了应用程序的数据库记录。
由于 travel analytics 仪表盘每周更新一次,我需要一个简单易行的流程来清理每周新引入的地理数据错误。我开发的方法包括使用 Tableau 来识别地理地名错误,使用 Google 和 Wikipedia 来确定正确的和确认的值,使用 SQL 来检索和清理数据。
本文描述了我用来清理地理数据的方法的修订版。它通过一个小规模项目展示了该解决方案,包括一个示例数据库表、SQL 代码和一个 Tableau 数据可视化项目。
样本数据清理项目概述
地理地名数据清理项目样本包括以下步骤和组成部分:
- 使用 SQL SELECT 语句从数据库表中检索美国城市人口数据。我在这个示例项目中使用了 Microsoft SQL Server,但是它可以与任何关系数据库管理系统一起工作,比如 Oracle、MySQL、PostgreSQL 等。
- 将使用 SQL 检索的城市人口数据加载到 Tableau 工作表中。
- 创建城市及其人口的地图。Tableau 将自动检测并报告无效的城市名或州代码。换句话说,Tableau 将识别其内部地理地名数据库中不存在的城市名称和州代码。
- 对于无效的地名,使用谷歌搜索找到正确的拼写位置。此外,如有必要,使用维基百科来确认城市名称、州代码和人口值的组合。
- 在上述步骤 1 中描述的 SQL 语句中添加或修改 CASE 语句,以更正拼写错误的城市名称和州代码。
- 将使用修改后的 SQL 语句检索到的城市人口数据重新加载到 Tableau 工作表中。
- 查看城市人口地图。如果仍然不准确,重复步骤 4 到 7,直到 SQL 语句清除了所有脏数据。
"我们相信上帝,所有其他人都会带来数据."爱德华·戴明
城市人口数据库表示例
为了演示数据清理技术,我创建了一个名为 City_Population 的表,其中包含以下几列:
- 城市 —城市的名字
- 州代码 —州的双字符代码
- 人口——2020 年美国人口普查人口或维基百科记录的 2010 年后的最新估计人口
城市 _ 人口表结构。图片作者。
然后我用 17 行填充了这个表,其中充满了数据错误,如下所示。
City_Population 表中的示例数据。图片作者。
基本 SQL 选择查询
下面显示的选择查询检索 City_Population 表中所有行的 City、State_Code 和 Population 值。请注意,由于 Population 是 SQL Server 中的一个关键字,因此它被放在了方括号中。
选择查询以获取城市、州代码和人口。作者代码。
将数据加载到 Tableau
在我以前的职位上,我直接从 Tableau Desktop 调用 SQL 查询,将 SQL Server 和其他数据库中的数据加载到 Tableau 项目中。对于这个项目,我使用 Tableau Public,它排除了调用 SQL 查询的能力。Tableau Public 支持各种其他数据源。这个项目我选了 Excel。以下是将数据加载到 Excel,然后再加载到 Tableau Public 的一般步骤:
- 在 SQL Server Management Studio (SSMS)中运行选择查询。如果运行 SQL Server,可以使用 SSMS。否则,请使用您所使用的数据库的查询工具。
- 将查询返回的数据复制并粘贴到 Excel 工作表中。保存 Excel 工作簿。
- 打开 Tableau Public(或 Tableau Desktop)并将 Excel 文件添加为数据源。
按照以下步骤从 SSMS 输出窗口复制数据。
将数据从 SSMS 复制到 Excel。图片由作者提供。
下面是 Excel 电子表格,其中包括从 SSMS 粘贴的数据。注意,工作表名为 city_population_dirty,工作簿名为 city_population_dirty.xlsx,我将这个工作表加载到 Tableau 中。稍后,我将加载一个“干净”的工作表到 Tableau 中。
Excel 中的数据,并准备加载到 Tableau。图片由作者提供。
要将数据加载到 Tableau 中,请打开 Tableau Public 或 Tableau Desktop。接下来,在连接标题下,单击[Microsoft Excel]。当提示打开文件时,导航到 city_population_dirty.xlsx 并单击[打开]。
连接到 Tableau Public 中的 Excel 电子表格。图片由作者提供。
肮脏城市的人口数据应该加载到 Tableau 中,如下所示。
已加载到 Tableau Public 中的脏城市人口数据。图片由作者提供。
查看 Tableau 中的脏数据
将数据加载到 Tableau 后,我在一个名为“Population Dirty”的工作表中创建了一个地图。注意屏幕右下角的信息“10 未知”。这一信息表明,Tableau 无法绘制数据中的 10 个地名。
城市人口图。请注意,名称无效的城市不会显示在地图上。图片由作者提供。
要识别脏数据,请单击“10 未知”Tableau 将显示如下所示的编辑位置对话框。
请注意未识别的城市名称,例如 Aims 和 Amerillo 。我可以用下拉框中的值(位于“未识别”下)替换这些值。但是,虽然这样做会清除此 Tableau 仪表板的数据,但清除的数据将无法用于其他 Tableau 项目或其他用途。因此,对于本文描述的项目,我决定清理 SQL 中的数据。然后,清理后的数据将可供所有下游用户使用,比如 Tableau。
Tableau 公共“编辑位置”对话框显示无效或无法识别的城市名称。图片由作者提供。
在谷歌中查找正确的城市名称
谷歌搜索使用微软在其 Visual Studio 工具的智能感知中使用的技术,在用户输入文本时找到可能的结果。此外,谷歌似乎会纠正拼写,甚至可能使用“听起来像”的算法来识别搜索词。
对于无法识别的城市“Aims”,我查看了 Excel 文件中的数据,并注意到具有脏值的记录的州代码是“IA”因此,当我搜索“Aims ia”时,Google 返回“Ames,ia”和“City in Iowa”作为第一个结果。我确信“Ames”是“Aims”的正确拼法,于是继续前往下一个拼错的城市。
在谷歌中搜索城市和州。图片由作者提供。
但如果不确定谷歌是否返回了正确的城市,我也会在维基百科上查找谷歌建议的地方的拼写。例如,当我在谷歌中搜索“查尔斯顿南卡罗来纳州”,它会返回“查尔斯顿南卡罗来纳州的一个城市”为了验证这一点,我在维基百科中查找了这个城市,并将其人口与 Excel 电子表格中的人口进行了比较。两个源中的值都是 150,277。
在维基百科中确认城市人口。图片由作者提供。
清除 SQL 中的数据
为了清理 SQL 中的地名,我在 SELECT 查询中使用了 CASE 语句。例如,下面显示的查询更正了十个城市名。它还将明尼苏达州的州代码从“MP”更新为“MN”
查询以获取和清除城市、州和人口数据。作者代码。
为了从 Tableau 的查询中准备数据,我运行它并将其输出数据复制到名为“city_population_clean.xslx”的工作簿中名为“city_population_clean”的 Excel 工作表中,如下所示。
Excel 电子表格与清洁城市人口数据。图片由作者提供。
在 Tableau 中加载和查看清洁城市人口数据
接下来,我将干净的数据集加载到 Tableau 中,并基于干净的数据构建一个地图工作表。该过程与上面针对脏数据描述的过程相同。
请注意,工作表不再在右下角显示类似“10 不干净”的消息。这是因为 Tableau 可以识别输入文件中的所有地名。此外,它还在地图上标出了每个城市。
Tableau Public 地图,展示了精选美国城市的完整列表。图片由作者提供。
最后一步是将 Tableau 项目的“干净”工作表保存到 Tableau 公共服务器。你可以在这里查看。
Tableau 公共仪表板称为美国城市人口选择。图片由作者提供。
这种数据清理方法的利与弊
虽然这里介绍的数据清理方法成功地清理了城市人口表中的地名,但是与其他方法相比,它有一些优点和缺点。
赞成的意见
- 过程很简单。
- 可以快速检测并纠正脏数据。
- 当最终用户或软件很少将脏数据引入数据库表时,这种方法是实用的(只需对 SQL 查询进行少量更改)。
骗局
- 需要 SQL 编码技能,以潜在地改变每个新数据集的 SQL 查询。
- 容易出错,因为每当检测到脏数据时,代码都需要更改。即使一个优秀的程序员也可能犯错误。
- SQL 代码可能会变得难以处理。最终,SQL 查询可能包含数百行,使得维护变得困难。
替代清洁方法
虽然上面描述的数据清理过程提供了一个实用的解决方案,但是您也可以考虑其他解决方案。例如,在一个理想的系统中,当请求旅行的员工输入数据时,web 表单会检测并纠正数据错误。这种方法将通过消除大多数地理数据清理需求来节省时间和金钱。
另一种数据清理方法涉及一个将脏地名映射到干净地名的表。SQL 查询将用干净的地名替换从城市人口表中检索到的脏值。
结论
这里描述的地理数据清理方法在维护旅行分析仪表板方面证明是有效的。即使每周有数百条新的旅行记录,获取、清理和发布这些数据的整个过程也只用了不到一个小时。
我希望这些关于数据清理的信息对您有所帮助。对我来说,数据清理是数据工程、数据分析和数据科学项目生命周期中最具挑战性和最令人满意的步骤之一。
"没有数据就进行理论化是一个严重的错误。"—夏洛克·福尔摩斯
工具信息
SQL Server Management Studio
Tableau Public
如何清理文本数据
原文:https://towardsdatascience.com/how-to-clean-text-data-639375414a2f?source=collection_archive---------18-----------------------
…删除数据科学应用的停用词
JESHOOTS.COM在 Unsplash 上的照片【1】。
目录
- 介绍
- 清理文本数据
- 摘要
- 参考
介绍
数据大部分时间都是杂乱的、无组织的、难以处理的,这应该不足为奇。当您从教育实践进入数据科学时,您会发现大多数数据是从多个来源、多个查询获得的,这可能会导致一些不干净的数据。在某些或大多数情况下,您必须提供最终用于训练模型的数据集。有一些文章关注数字数据,但是我希望这篇文章主要关注文本数据,这与自然语言处理相一致。也就是说,这里有一个在 Python 中清理文本数据的简单方法,以及它什么时候有用。我将使用来自 TMBDF 5000 电影数据集【2】的流行数据集,这样你就可以跟上了。
清理文本数据
Marylou Fortier 在Unsplash【3】上的照片。
删除停止字
另一种解释“停用词”的方法是删除不必要的文本。但是,需要注意的是,当您使用常用停用词库时,您可能会删除实际上想要保留的单词。这就是为什么你应该先考虑你想删除的单词列表。常用的停用词有‘the’
、‘of’
等。你想要删除这些词的原因是如果你想保留这些词、短语、句子等的主题。一个例子是‘有一次他们在七月去商店参加节日聚会’。如果你去掉停止词和一些不必要的词,你只会得到剩余的time, July, holiday, party
。
话虽如此,让我们看看如何从电影片名中删除一些停用词:
import pandas as pdimport nltk.corpus
nltk.download(‘stopwords’)
from nltk.corpus import stopwordsdf = pd.read_csv('...path/tmdb_5000_movies.csv')stop_words = stopwords.words('english')
df['clean_title'] = df['title'].apply(lambda x: ' '.join([word for word in x.split() if word not in (stop_words)]))
在上面的代码中,我们导入必要的库,然后将我们的数据读入 pandas 数据帧。从那里,我们分配我们将从‘title’
列的文本中删除的停用词,这将在‘clean_title’
列中显示它们各自的效果。输出如下所示。在第 1、3 和 8 行中,是停用词被删除的地方,正如您可以并排看到的 before 和 after。
作者截图[4]
除了 nltk 的停用词库,您还可以“手动”添加其他停用词。为了实现这个功能,你可以简单地给stop_words
添加一个字符串列表。例如,如果我们想要删除文本“3”,因为在这种情况下它不是一个数字,我们可以将它以及单词“at”和字母“v”添加到列表中。它的工作方式如下:
stop_words = stopwords.words(‘english’) + [‘At’, ‘v’, ‘3’]# apply the same code as above but assign
# a new column to see the differencesdf['clean_title_v2'] = df['title'].apply(lambda x: ' '.join([word for word in x.split() if word not in (stop_words)]))
在下面的屏幕截图中,您可以看到 lambda 函数是如何移除添加的字符串列表中的值的。
作者截图[5]。
现在我们已经展示了一种清理文本数据的方法,让我们讨论一下这个过程对数据科学家有用的可能应用:
- 删除不必要的单词,以便您可以执行词干分析,在词干分析中,您可以隔离删除后留下的单词的词根
- 与上面类似,你可以只分离出单词的词条
- 只有保留必要的单词才能让您更容易地标记数据中的词性,例如,如果您只标记形容词,并在您的模型数据中使用该文本,如“美丽”、“惊人”、“响亮”将用于预测电影评论的目标变量。一个模型将能够更容易地从形容词中识别情感,以辨别电影评论是好是坏,或者电影需要改进什么
- 从更新文本的主要词创建一个摘要仪表板,例如,去掉“蜘蛛侠 1”、“蜘蛛侠 2”和“蜘蛛侠 3”中的数字,将允许对所有蜘蛛侠电影进行分析,如赚钱,或这些电影的平均评论评级
- 更容易进行主题建模——在大量文本之间找到共同的主题
- 创建更少量的文本,以便您的建模在训练和预测时变得更快、更便宜
- 可用于删除错误的文本,例如,如果人们正在手动键入响应,您可以清理他们的响应,如果他们的输入是从语音到文本的,您可以自动删除通常被语音错误解释的单词
当然有更多的理由删除停用词,并清理你的文本数据。同样重要的是要记住,有一些新兴的算法可以很好地处理文本数据,比如 CatBoost。
摘要
正如你所看到的,仅仅清理数据的一部分就可以为进一步清理和处理数据打下基础。希望数据的这种变化最终会使您的模型更加健壮和准确。我给出的例子很小,但你可以看到如何将它应用到包含数百个句子的数据中会更有用。
总而言之,以下是如何从文本数据中删除停用词:
* import libraris* import your dataset* remove stop words from the main library* add individual stop words that are unique to your use case
更新: 单词 *The*
没有被删除,因为它是大写的,所以在清理它之前,请确保将所有文本都小写。感谢您的标注, 米亚罗姆 !
我希望你觉得我的文章既有趣又有用。如果你同意这种删除停用词的方法,请在下面随意评论——为什么或为什么不?你喜欢不同的图书馆吗?如果你有,请随意评论你喜欢其中一个的原因。这个图书馆有什么缺点?你知道一个更新的库可以在效率、易用性和速度方面击败 nltk 吗?还有哪些清理文本数据的方法?你是否碰巧根本不使用库,而只是删除了你管理的一个特定列表?谢谢你看我的文章!
请随时查看我的个人资料和其他文章, Matt Przybyla ,也可以在 LinkedIn 上联系我。
参考
[1]照片由JESHOOTS.COM在Unsplash(2019)上拍摄
[2] Kaggle, TMBDF 5000 电影数据集,(2021 —已访问)
[3]Marylou Fortier 在 Unsplash 上拍摄的照片,(2020)
[4] M.Przybyla,清洁文本示例,(2021 年)
[5] M.Przybyla,清理文本示例并添加个别停用词,(2021 年)
如何聚类数据!
原文:https://towardsdatascience.com/how-to-cluster-data-65d37c98ce55?source=collection_archive---------32-----------------------
使用无监督机器学习和 K-均值聚类的指南
图片来源:我
在从事数据科学项目时,数据科学家经常会遇到含有未标记数据点的数据集。因此,很难获得可用于对数据行为建模的有洞察力的知识。为了从无意义的数据中找出意义,部署了无监督的机器学习技术来标记数据点,并提供不同类别之间的清晰对比。
一种非凡的无监督机器学习技术被称为聚类。聚类是将未标记的数据分组到类中的一种很好的机制。它通过检查整个数据集来寻找数据点变量之间的相似性。注意到某些相似性后,可以将数据集分成多个组,组成员拥有相似的属性。 K 均值聚类是本文将要探讨的聚类类型。
K-Means 通过 scikit-learn 进行聚类
样本聚类
Scikit-learn 是一个机器学习库,可以通过 Python 获得。它可以用来建立机器学习算法,以做出准确的预测。K-means 聚类模型是使用下面的代码通过 scikit-learn 导入的。
**from** **sklearn.cluster** **import** KMeans
需要一个数据集来利用 K 均值聚类模型。因此,goodreads 书籍评级的数据集从 Kaggle 下载并上传到 Jupyter Notebook。然后,提取数值变量,如平均评分、页数、评分计数和文本评论计数。使用这四个变量,可以在数据集上拟合 K 均值聚类。
下一步是计算出将数据集合理分组的最佳聚类(组)数量。通过尝试不同数量的簇,有可能计算出它们的惯性。K 均值聚类的惯性是对聚类的一致性和独特性的度量。通过绘制惯性对聚类数的图表,在图表上创建肘状结构的点处选择最优的聚类数。这样做是因为增加超过肘点的簇的数量不会大量改变惯性值,并且最终会创建不必要的额外簇/组。
聚类的最佳数量将是 4,因为这是创建图形肘部的位置
因此,选择四个组作为组的数量。然后,将其拟合到 goodreads 图书数据集上,以便将标签归属于数据点。
kmeans_book = KMeans(n_clusters = 4)
kmeans_book.fit_predict(books_df)
goodreads ' book 数据集的前五行在 K-Means 聚类适合数据集后进行标记
通过选择四个聚类,创建了理想地代表每个聚类的四个中心。然后,测量每个数据点与中心的距离,并根据其最近的聚类中心标记数据点。下面可以看到四个聚类中心。
数据集中的四个聚类中心
作为预处理形式的聚类
K-means 聚类也可以用作构建机器学习算法时的预处理方法。这可以通过创建一个管道来实现,在该管道中,对独立变量应用 K 均值聚类,以测量每个数据点到聚类中心的距离。然后,可以应用分类器,根据数据点到聚类中心的距离来标记数据。
K-means 聚类作为预处理器的一个用例可以在红酒质量的分类中找到。首先,将数据集分成训练和测试数据集,并使用两个聚类的 K-means 聚类和决策树分类器创建管道。
**from** **sklearn.model_selection** **import** train_test_split
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state = 10, train_size = 0.8)pipeline = Pipeline([("kmeans", KMeans(n_clusters = 2)), ("dec", DecisionTreeClassifier())])
上面显示的管道代码可以适用于训练数据,并用于对测试数据的独立变量进行预测。
pipeline.fit(x_train, y_train)
y_pred = pipeline.predict(x_test)
在下图中可以看到聚类中心。
管道的聚集中心
管道的准确度分数约为 0.74。
管道的准确度分数。
葡萄酒质量检测数据的前五行。包含数据点预测质量的列被附加到表格中。
结论
聚类为数据科学家提供了一种从无意义的数据集中提取有用信息的方法。通过对数据集进行聚类,可以对其进行标记,这些标记可用于模拟数据点的行为或创建可视化图表,以有效区分数据集上的不同点。在未标记数据集带来的混乱中,K-means 聚类是一种建立这些数据集结构的好方法。
本文使用的代码的链接可以在这里 查看 。
非常感谢您的阅读!
如何在 Python 中使用 TF-IDF 和图划分对相似句子进行聚类
原文:https://towardsdatascience.com/how-to-cluster-similar-sentences-using-tf-idf-and-graph-partitioning-in-python-5fb70627a4e0?source=collection_archive---------2-----------------------
哪些数据科学文章更能吸引读者(第二部分)
Hanson Lu 在 Unsplash 上的照片
在这一系列文章中,我们分析了数据科学出版物的历史档案,以了解哪些主题更受读者欢迎。之前我们讨论过如何获取将用于进一步分析的数据。
在本文中,我们将介绍如何清理我们之前收集的文本数据,使用网络图对相似的主题进行分组,并在这些集群中建立模式。
数据汇总
让我们提醒自己数据是什么样子的。它是从三个数据源[field:' Source ']—Analytics vid hya[' avd ']、 TDS ['tds']和获得的文章的组合。
我们收集了出版物档案中每篇文章的标题、副标题、掌声和回应。
import pandas as pd# Reading the data obtained using code [here](https://medium.com/analytics-vidhya/what-data-science-articles-attract-more-attention-part-1-efe8faf209d0).
avd = pd.read_csv('analytics_vidhya_data.csv')
tds = pd.read_csv('medium_articles.csv')
tai = pd.read_csv('towards_ai_data.csv')avd['source'] = 'avd'
tds['source'] = 'tds'
tai['source'] = 'tai'# Create single data set, join title and subtitle
single_matrix = pd.concat([avd, tds, tai])
single_matrix['title_subtitle'] = [' '.join([str(i),str(j)]) for i, j in zip(single_matrix['Title'].fillna(''), single_matrix['Subtitle'].fillna(''))]
文章数据集
我们在数据集中添加了一个名为“title_subtitle”的附加列,它是列“Title”和“Subtitle”的连接,我们将主要使用这个列,以便更好地查看文章所属的主题。非常有趣的是,39%的文章没有副标题,只有很小一部分没有标题。
让我们快速看一下每个数据源的掌声和响应分布。我们从方框图开始,我们使用 Python 中的 seaborn 库来创建我们的图。
# We will use seaborn to create all plots
import seaborn as sns
import matplotlib.pyplot as pltfig, axes = plt.subplots(1, 2, figsize=(8, 5))
# Claps
sns.boxplot(ax=axes[0], x="source", y="Claps", data=single_matrix)# Responses
sns.boxplot(ax=axes[1], x="source", y="Responses", data=single_matrix)
我们可以看到,走向数据科学不仅有更多的活动,而且有相当多的离群值,个别文章获得了读者的大量吸引力。当然,每个来源的活动取决于出版物的规模,对于较大的出版物,我们观察到更多的作者和读者。
当涉及到回应时,我们观察到的活动远少于所有来源的鼓掌,尽管这种行为并不十分意外。
按来源划分的掌声和回应的箱线图
接下来,我们移除异常值并可视化场的分布,以获得更清晰的图像。
# Code to create distribution subplots
fig, axes = plt.subplots(2, 1, figsize=(8, 8))# Claps
sns.distplot(avd['Claps'][avd['Claps']<10000], hist=True, rug=False, ax=axes[0])
sns.distplot(tds['Claps'][tds['Claps']<10000], hist=True, rug=False, ax=axes[0])
sns.distplot(tai['Claps'][tai['Claps']<10000], hist=True, rug=False, ax=axes[0])# Responses
sns.distplot(avd['Responses'], hist=True, rug=False, ax=axes[1])
sns.distplot(tds['Responses'], hist=True, rug=False, ax=axes[1])
sns.distplot(tai['Responses'], hist=True, rug=False, ax=axes[1])
我们可以看到两种分布都向左倾斜,这意味着大多数文章得到的掌声很少,甚至更少的回应。然而,这并不奇怪,因为文章的成功取决于许多因素,如高质量的写作,相关的主题等等。取得良好的平衡不是一件简单的事情!
按来源划分的掌声和响应分布
如何清理文本数据?
在处理文本时,清理数据是一个重要的步骤(如果不是最重要的部分的话)。在处理这类任务时,有标准的做法可以遵循。我们将采取以下步骤来处理标题和字幕:
- 删除标点符号和其他符号
- 删除停用词和数字
- 词汇
我们将混合使用正则表达式和 nltk 库来 删除标点符号、符号、停用词和数字 。
import re
single_matrix['title_subtitle'] = [re.findall(r'\w+', i.lower()) for i in single_matrix['title_subtitle'].fillna('NONE')]
上面的代码匹配一个或多个单词字符,事实上 r'\w+' 与r '[a-zA-Z0–9 _]+'相同。同样,在应用 re.findall() 和 i.lower() 命令时,他们方便地将句子拆分成单词,并转换成小写。这将在接下来的步骤中非常有用。因此,句子‘在 qlikview 中报告|临时报告’变成了【报告,在,Qlikview,临时,临时,报告】。
接下来,我们将使用 nltk 库上传一个停用词词典,这样我们就可以将它们从句子中删除。此外,我们将单词“使用”和“部分”添加到列表中,因为它们在数据集中被过度使用。为了删除我们用于循环迭代每个句子的停用词,在这样做的时候,我们也确保从句子中删除数字。
# The code to upload list of stop words and remove them from sentencesimport nltk
nltk.download('stopwords')
from nltk.corpus import stopwordsstopwords_eng = stopwords.words('english')
stopwords_eng += ['use', 'using', 'used', 'part']new_titles_sub = []
for title_sub in single_matrix['new_title_subtitle']:
new_title_sub = []
for w_title in title_sub:
if w_title not in stopwords_eng and not w_title.isdigit():
new_title_sub.append(w_title)
new_titles_sub.append(new_title_sub)
single_matrix['new_title_subtitle'] = new_titles_sub
最后,我们要把句子中的单词去掉。考虑到上下文,词条解释将单词转换为其有意义的词根形式。频繁的词干提取是一种计算速度更快的替代方法,但是不够精确。我们再次使用 nltk 来表示单词
nltk.download('wordnet')
nltk.download('words')
from nltk.stem import WordNetLemmatizer
wordnet_lemmatizer = WordNetLemmatizer()new_titles_sub = []
for title_sub in single_matrix['title_subtitle']:
new_title_sub = []
for w_title in title_sub:
new_title_sub.append(wordnet_lemmatizer.lemmatize(w_title, pos="v"))
new_titles_sub.append(new_title_sub)
single_matrix['new_title_subtitle'] = new_titles_sub
single_matrix['new_title_subtitle'] = [' '.join(i) for i in single_matrix['new_title_subtitle']]
让我们看看所有转换后的句子是什么样的
如何使用 TF-IDF 对文本数据进行矢量化?
TF-IDF 代表术语频率-逆文档频率,它是某个特定文档集中某个关键字与某个文档相关程度的数值度量。它常用于文本分析,一些例子包括内容排名和信息检索。这里的是一篇非常有用的论文,更详细地讨论了这种方法。
顾名思义,该度量由两部分组成,一部分是查找单词在文档中出现的频率(TF),另一部分是单词在语料库中唯一性的程度(IDF)。让我们来看看简化版的公式及其组成部分:
我们可以看到,更频繁出现的单词将导致更低的 TF-IDF 分数,而对于罕见的单词,分数将更高。这种权重调整非常重要,因为过度使用的单词不会有额外的意义。
理解计算的最简单的方法是举例,在我们的数据集中,单个标题是一个文档,所有标题形成一个语料库(文档集)。考虑标题‘使用变量 qlikview 创建强大的数据故事’中的‘create’一词,文档有 7 个词,‘create’只出现一次,所以 TF(create) = 1/7 。其中一个数据源中的文章总数为 12963 ,单词‘create’出现在 268 标题中,因此IDF(create)= log(12963/268)= 3.88。因此, TF-IDF =0.143.88 = 0.55* 就是单词‘create’的得分。
既然我们知道了如何计算文档中每个单词的分数,我们就可以对带有文章标题和副标题的数据集进行矢量化处理。为此我们将使用 Python 中的 sklearn 库,特别是tfidf 矢量化 r 函数。
注意:tfidf 矢量化 r 使用的公式与上面指定的略有不同,它将 IDF 加 1。这样做是为了确保每个文档中出现的单词不会被忽略。
from sklearn.feature_extraction.text import TfidfVectorizertf = TfidfVectorizer(analyzer='word', ngram_range=(1, 3), min_df=0)tfidf_matrices = []
data_sets = []
for source in ['avd', 'tai', 'tds']:
source_data = single_matrix[single_matrix['source'] == source].drop_duplicates()
data_sets.append(source_data['new_title_subtitle'])
tfidf_matrices.append(tf.fit_transform(
source_data['new_title_subtitle']))
我们引入了遍历数据源的 for 循环,这样做是为了缩短计算时间。当查看所有句子对之间的距离并将它们分成组时,也需要这样做。输出是稀疏矩阵,其中行是文档,列是语料库中唯一的单词。
现在我们已经有了矢量化的标题和副标题,我们可以计算所有句子之间的成对距离。我们将在代表句子的向量对之间使用余弦相似度。该度量考虑两个向量之间的角度,通常用于文本分析。对所选相似性度量的一些很好的解释可以在这里找到,本文不仅提供了清晰的定义,还讨论了基于上下文的使用。
我们使用 sklearn 库来计算成对余弦相似度,再一次根据源进行分割。
from sklearn.metrics.pairwise import linear_kernel
matrix_with_cos_sim = []
for m in tfidf_matrices:
matrix_with_cos_sim.append(linear_kernel(m, m))
每个数据源的输出是一个 numpy 数组(NxN ),所有句子之间具有成对的相似性,其中 N 是单个数据源的标题/副标题的数量。
如何利用网络图将相似的句子分组?
我们的目标是找到包含类似数据科学主题的文章的聚类,为此,我们将从构建一个加权图开始,其中节点是文章,边是它们的余弦相似性。然后,我们能够通过应用图划分来创建聚类,目的是在不强加大量社区的情况下找到有意义的子图(也称为社区)。
我们将使用 Python 库 networkx 和社区来构建和划分图表。在我们继续构建图表之前,我们将只为语料库中的每个文档选择前 15 个相似的标题,这个数字是根据称为模块性的度量来选择的,模块性给出了划分有多好的指示。这种方法不仅锐化了图形,而且有助于提高计算速度。
import numpy as np
from tqdm import tnrange
top_n_sentences = []
for cs, t in zip(matrix_with_cos_sim, data_sets):
no_dups = np.array(t)
i = 0
top_frame = []
for c, z in zip(cs, tnrange(len(cs))):
# Create vector of titles
start_name = pd.Series([no_dups[i]]*15)
# Index of top 15 similar titles
ix_top_n = np.argsort(-c)[0:15]
cos_sim = pd.Series(c[ix_top_n])
names = pd.Series(no_dups[ix_top_n])
i +=1
top_frame.append(pd.DataFrame([start_name, names, cos_sim]).transpose())
top_frame = pd.concat(top_frame)
top_frame.columns = ['title1', 'title2', 'cos_sim']
# Remove the similarities for the same sentences
top_frame['is_same'] = [bool(i==j) for i, j in zip(top_frame['title1'], top_frame['title2'])]
top_frame = top_frame[top_frame['is_same'] != True]
top_n_sentences.append(top_frame)
该脚本为数据集中的每个标题生成具有前 15 个相似标题的数据框(按源划分),它将用作构建图表的输入。让我们看看其中一个源的数据框示例
我们将继续构建和划分图表,我们将对拥有第二大数量文章的源(Analytics Vidhya)进行构建和划分。这些代码片段可以应用于本文涵盖的所有源代码。
# We start by defining the structure of the graphtop_frame = top_n_sentences[2] #TDS articlesedges = list(zip(top_frame['title1'], top_frame['title2']))
weighted_edges = list(zip(top_frame['title1'], top_frame['title2'], top_frame['cos_sim']))
nodes = list(set(top_frame['title1']).union(set(top_frame['title2'])))
我们现在可以使用上面定义的结构使用 networkx 来构建图形
import networkx as nx
G = nx.Graph()
G.add_nodes_from(nodes)
G.add_edges_from(edges)
G.add_weighted_edges_from(weighted_edges)
接下来,我们使用社区库对图进行分区,在模块导入之前,确保安装 python-louvain 库以避免错误。
# !pip install python-louvainimport community
partition = community.best_partition(G)
modularity = community.modularity(partition, G)
前面我们提到了模块性,这是衡量分区好坏的标准,本例中的值是 0.7 。通常,大于 0.6 的值被认为是足够好的分区。
# Takes some time for larger graphs
import matplotlib.pyplot as plt
pos = nx.spring_layout(G, dim=2)
community_id = [partition[node] for node in G.nodes()]
fig = plt.figure(figsize=(10,10))
nx.draw(G, pos, edge_color = ['silver']*len(G.edges()), cmap=plt.cm.tab20,
node_color=community_id, node_size=150)
上面的代码生成了我们刚刚发现的图形和社区,虽然这个图看起来很忙,但我们仍然能够看到通过这种方法发现了相当多的集群。
标题和副标题被划分到社区中
在我们更详细地研究集群之前,我们将把我们之前创建的分区变量转换成更易读的格式。
title, cluster = [], []
for i in partition.items():
title.append(i[0])
cluster.append(i[1])
frame_clust = pd.DataFrame([pd.Series(title), pd.Series(cluster)]).transpose()
frame_clust.columns = ['Title', 'Cluster']
上面代码的输出是数据帧,其中包含所有标题和副标题以及它们所属的社区,通过对图进行划分,可以识别出 45 个集群。
标题和副标题被划分到社区中
现在我们已经获得了集群,我们可以为每个集群创建汇总统计数据,以了解其中是否有任何集群有更多的活动。我们将有分区的数据集与有掌声和回应的数据集合并,然后我们将计算每个组的最小值、最大值、平均值、中值和文章数。尽管主要关注中值,因为我们之前看到数据偏向较小的值,并且存在异常值。
avd = single_matrix[single_matrix['source'] == 'avd'].drop_duplicates()frame_clust = frame_clust.merge(tds[['Title', 'new_title_subtitle', 'Claps', 'Responses']], how='left', left_on='Title', right_on='new_title_subtitle')grouped_mat = frame_clust.groupby('Cluster').agg(
{'Claps': ['max', 'mean', 'sum', 'median'],
'Responses': ['max', 'mean', 'sum', 'median'],
'Title_x': 'count'}).reset_index()grouped_mat.columns = ['cluster', 'claps_max', 'claps_mean', 'claps_sum', 'claps_median','responses_max', 'responses_mean', 'responses_sum', 'responses_median', 'title_count']grouped_mat = grouped_mat.sort_values(by = ['claps_median', 'title_count'])
出于代表性目的,我们将只关注读者活跃度最低的三个社区和读者活跃度最高的三个社区。我们首先考虑数据集,然后我们将可视化单词云,以确定每个小组的共同主题。
读者活跃度最低和最高的社区
上表显示,这些群组并不是很大,让我们看看每个群组中有哪些共同的主题,我们将使用 wordcloud 库。
from wordcloud import WordCloud
fig, ax = plt.subplots(1, 3, figsize=(12.5,6.5))clusters = [19, 39, 38] #lowest activity groups
# clusters = [43, 28, 7] #highest activity groupsfor cluster, col in zip(clusters, [0, 1, 2]):
corpus = ' '.join(frame_clust['new_title_subtitle']. [frame_clust['Cluster'] == cluster])
ax[col].imshow(WordCloud(width = 800,
height = 800,
background_color ='white',
min_font_size = 10).generate(corpus))
ax[col].axis("off")plt.show()
我们首先看一下活跃度最低的社区,看起来第 19 类的文章大多属于一个作者,这可以解释活跃度较低的原因。另外两个集群由多个作者撰写的更多文章组成。有趣的是,我们可以观察到诸如“python 中的面向对象编程”和“欺诈检测”这样的主题引起了读者最少的兴趣。
读者活动较少的群集
转到最活跃的集群,引起读者更多兴趣的突出主题是自然语言处理、神经网络、激活函数和支持向量机。
读者活跃度较高的集群
总结
虽然我们能够在低和高读者活动组中建立共同的主题,但我们仍然观察到没有很多掌声和回应的文章,以及在每个组中有高活动的文章。当试图建立读者感兴趣的一般模式以及文章饱和度较高的主题时,这种分析会很方便。然而,选择一个相关的主题并不能保证文章的成功,因为许多其他重要因素有助于吸引读者。
强化学习的值迭代算法如何编码
原文:https://towardsdatascience.com/how-to-code-the-value-iteration-algorithm-for-reinforcement-learning-8fb806e117d1?source=collection_archive---------0-----------------------
利用强化学习求解 MDP
来源
在本文中,我将向您展示如何实现价值迭代算法来解决马尔可夫决策过程(MDP)。当你进入强化学习和人工智能时,这是你应该学习的第一个算法。
强化学习是机器学习的一个领域,它专注于让代理学习如何在特定环境中表现/行动。MDP 仅仅意味着问题的框架,环境本身。
什么构成了 MDP?
MDP 由 5 个元素组成。
- 一套状态。这表示代理在环境中的所有可能位置。
- 一套动作。这表示代理在任何给定状态下可以采取的所有操作。
- 转移概率。这表示代理尝试的操作成功(或失败)的概率。
- 奖励,是到达特定状态的数值。
- 折扣系数γ ,与即时奖励相比,这意味着减少未来奖励的价值。
MDP 中代理的目标是找到最优策略,即在任何给定状态下采取的最优行动的集合。
一个例子
理解这一切的最简单的方法是用一个例子。
假设我们有一只熊(代理人)想要得到蜂蜜(正奖励),同时避开它周围的蜜蜂(负奖励)。在每个单元(或状态),熊可以采取行动。例如,从他的实际位置,他可以向下或向右。最后,我们有转移概率。有时候,熊会打算做一些事情,但它会做其他事情(例如,向下而不是向左)。靠近蜜蜂会变得更加“危险”,因为失足可能意味着负面的回报。
来源:自制图片
现在,为了找到获得蜂蜜的最佳方式,熊将在环境中行走。他可能会走进蜜蜂,被蛰,并学会避免这种状态。最终,随着时间的推移,他会弄清楚如何在任何给定的状态下表现,以获得蜂蜜而没有后果!聪明的熊!
但是熊将如何学习呢?数值迭代算法是解决这一问题最常用的算法之一。让我们开始吧。
值迭代算法
该算法试图找到处于任何给定状态的值 V(st)。它使用贝尔曼方程。
来源:https://artint.info/html/ArtInt_227.html
别担心,这真的没那么复杂。所有这一切意味着,考虑到转移概率,处于一个状态的价值等于该状态的直接回报(R)加上每个相邻状态的贴现回报(St+1)的最大值。因此,我们在这个算法中只先行一步。
这是一种迭代算法,其中状态值不断更新,直到收敛,即当值停止变化时。
最终,最优策略是隐含的,因为它将是为每个状态提供最佳价值的行动。
用 Python 实现算法
现在让我们进入有趣的部分!
下面是第一部分,代表了 MDP 的初始设置/创建(状态、动作、奖励等)。).
SMALL_ENOUGH
变量是用来决定在哪个点上停止算法是合适的。Noise
代表随机行动而非有意行动的概率。
在第 13–16 行,我们创建了状态。在第 19–28 行,我们为各州创建了所有奖励。有蜂蜜的州为+1,有蜜蜂的州为-1,其他州为 0。
然后,我们创建一个字典,包含任何状态的所有可能的动作。每个状态有 2 到 4 个可能的动作(向下、向上、向左或向右)。
最后,我们为每个状态定义一个初始随机策略以及一个值字典,包含每个状态的初始奖励。这最后一个字典将在算法期间被更新。
下面是值迭代算法。
从第 8 行和第 14 行可以看出,我们遍历了每个状态和每个状态中的每个动作。
在第 25–33 行,我们选择了一个随机的动作,在 10%的时间里,它会被执行,而不是预期的动作。这增加了问题的不确定性,使其成为非确定性的。通常,在值迭代中,您可能有不止一个可能的随机动作(考虑所有相邻的状态)或者甚至更高的噪声。然而,在这里,为了保持简单并确保算法快速运行,我只选择了一个可能的随机动作,每个状态发生的概率相对较小。
在第 38 行,我们计算在一个状态中采取一个动作的值。
在第 40-41 行,我们保存了与最佳值相关联的动作,这将给出我们的最优策略。
最后,在第 48 行,如果迭代期间在所有状态中观察到的最大改进被认为太小,则算法停止。
结果呢
这个超级小的例子在 44649 次迭代中收敛。
以下是与每个州相关的值。
我们看到,越接近最终回报,处于这种状态的价值就越高。
我们还看到,处于状态(2,1)的值(0.259)比更远的状态(2,0)的值(0.338)小。这是因为当接近负回报时,熊可能会失足撞到蜜蜂。因此,在这种情况下,最好远离这些州,即使这意味着也远离蜂蜜!
从这些值中,我们可以得出最优策略。
显然,我使用的例子非常简单,因此只需查看环境就可以很容易地找出最佳策略。然而,环境变得越大,我们人类就越难找出每个国家的最佳行动方案。对于电脑来说,不是。
之前不知道该做什么的熊,现在已经学会了如何在躲避蜜蜂的同时获取蜂蜜。对他有好处!
下面的存储库包含了这个项目使用的所有代码:https://github . com/francoistamant/reinforcement-learning-MDP
非常感谢你的阅读,我希望你学到了一些东西,如果你有任何问题,请随时联系我!
成为会员:【https://francoisstamant.medium.com/membership】T2
当你只知道 Jupyter 笔记本时如何编码
原文:https://towardsdatascience.com/how-to-code-when-all-you-know-are-jupyter-notebooks-78cf8d4f32e0?source=collection_archive---------12-----------------------
从笔记本转换到 Python 文件的初学者指南
克里斯里德在 Unsplash 上的照片
当我开始我的第一份机器学习工作时,我之前所有的编码都是在 Jupyter 笔记本上完成的。然而,我开始工作的公司没有使用它们,所以我有点害怕不知道没有它们如何编码,而是必须使用 Python 文件。也许你发现自己处于和我当时相似的位置,开始学习如何使用文件和脚本,但不知道如何开始。唉,这是我的教程,当你只知道 Jupyter 笔记本时,如何编码。
Jupyter Notebook 是一个方便的小东西:你可以编写代码,合并细胞,分割细胞,运行单个细胞——无论它们在笔记本中的什么位置——并直接在执行的细胞下方看到输出。然而,就像生活中的一切一样,笔记本也有它们的问题:它们可能会很乱,以非线性顺序执行单元格的能力使得再现性很难,并且很难将笔记本中的代码投入生产。Python 文件不会带来这些问题,一旦你学会了使用它们,它们实际上会使编码变得更加容易。
那么什么是 Python 文件呢?它是 Python 函数和语句的集合,要么直接执行,要么从其他地方导入。这个代码集合可以像带有. py 后缀的文本文件一样简单,用文本编辑器打开。然而,更常见(也更实用)的是使用 IDE 来处理文件,比如 PyCharm 或 Visual Code Studio 。(为了熟悉 PyCharm 的基础知识,我在这里推荐这个简短的教程。它向您展示了如何启动项目、创建文件以及运行这些文件。关于 Visual Code Studio 的简短介绍,点击这里。)
开发代码
在我的第一份工作开始时,在 PyCharm 中执行脚本对我来说并不神秘。相反,我不确定如何使用简单的脚本而不是笔记本来开发 T21 代码。
编码是一个迭代的过程。你写几行代码,看看行不行,再写更多的代码,等等。在 Jupyter 笔记本中,这个过程非常简单,因为它允许您执行每一行来查看它是否工作。当使用脚本时,事情有点不同,因为您不能只执行一行。你或多或少必须从头到尾运行你的整个脚本。
当从 Jupyter 笔记本切换到 Python 脚本时,对我来说效果很好的是下面的方法:我写了一段代码(一到三行左右),然后运行脚本看看它是否工作。在整个代码中使用 Print 语句通常是检查代码是否真的在做您想要它做的事情的好方法。像这样:
在这个例子中,我编写了一个函数,用零值填充图像,这样图像就得到想要的形状。当我运行代码并且没有抛出错误时,我继续写一些代码行并再次检查我的代码是否运行没有任何错误:
如果是这样,我想写的函数就完成了,我删除打印语句和调用函数的行——瞧,它就完成了:
结合笔记本和脚本
老实说,我仍然经常使用 Jupyter 笔记本——它们太方便了,可以把我的可视化和数据分析都放在一个地方。在将代码转换成 Python 文件之前,我经常使用它们来开发代码。正如我上面提到的,笔记本非常适合运行单独的代码行来查看它们是否工作,这非常有帮助,尤其是当你还不是一个有经验的程序员的时候。
所以我经常做的是在笔记本上开发代码——一行一行,用打印语句来查看代码是否在做我想让它做的事情——直到我有了一个可以变成函数的代码块。然后我把这个函数放到一个 Python 文件中。如果我愿意,我可以将它从那里再次导入到我的笔记本中,以便在那里使用。
在笔记本上逐行开发代码…
把它变成一种功能…
将它复制粘贴到 Python 文件中…
…导入并执行笔记本中的功能
我希望您现在感觉不那么茫然了,并准备开始自己尝试 Python 文件。显然,我没有涵盖与 Python 文件相关的所有内容。因此,如果您想知道如何不从 ide 内部而是从命令行运行 Python 文件,我可以在这里推荐本文。如果你想了解更多关于导入模块的知识,你可以在这里阅读。玩得开心!
实现您自己的 Python 预提交挂钩
原文:https://towardsdatascience.com/how-to-code-your-own-python-pre-commit-hooks-with-bash-171298c6ee05?source=collection_archive---------21-----------------------
创建自己的预提交钩子作为 bash 脚本,用于静态分析和与 Git repo 的持续集成。
作者:爱德华·克鲁格和道格拉斯·富兰克林。
约翰·沃尔特·班茨在 Unsplash 上拍摄的照片
这里是这个项目的模板。我们使用诗歌进行包装管理。本文着重于编写定制的预提交钩子。
https://github.com/edkrueger/poetry-template
有关 Python 预提交钩子的更多介绍性信息,请查看本文。
什么是预提交挂钩?
预提交钩子是 Git 钩子的子集。Git-hooks 是每当 Git 存储库中发生特定操作时自动运行的脚本——比如提交或推送。“预提交挂钩”在提交发生之前运行。
预提交挂钩通常用于确保代码在发布前被正确地链接和格式化。这些钩子也用于持续集成、构建过程、依赖性管理和测试。然而,使用预提交钩子进行测试在 DevOps 领域是有争议的,不在我们的讨论范围之内。
通过简单的 bash 代码,您可以为特定需求创建自己的定制钩子——例如,持续集成到已部署的应用程序。
预提交 Python 包
令人困惑的是,还有一个叫pre-commit
的 Python 包。预提交是一个用于预提交挂钩的管理工具。它在每次提交之前管理安装和执行挂钩。
我们需要安装pre-commit
作为开发需求。例如,对于诗歌,你会跑;
poetry add pre-commit --dev
自定义挂钩
下面是我们的定制钩子的 bash 代码,create-requirements.
这个 bash 脚本被设计来保持requirements.txt
与诗歌的锁文件poetry.lock.
同步
这很有用,因为如果我们保持需求是最新的,我们可以使用这个文件进行部署,避免任何定制的构建包。
例如,我们可以通过确保我们对虚拟环境依赖关系树所做的任何更改都反映在我们的requirements.txt
文件中来保持 Heroku 应用程序的部署。
这很有用的另一个原因是,通过避免在容器中安装虚拟环境,您可以创建更轻、更简单的 docker 构建。
照片由 Iza Gawrych 在 Unsplash 上拍摄
如果我们有一个与我们的requirements.txt
不同步的虚拟环境,这个预提交钩子将捕获它,提供一个适当的错误消息,并创建正确的requirements.txt
。
write _ requirements.sh
让我们仔细看看我们的代码,看看 bash 和 exit 状态是如何与包pre-commit
一起使用来阻止提交完成的。
在第 1 行,我们可以看到 bash 变量NEW_REQUIREMENTS
存储了我们使用的包管理器poetry
生成的需求。
第 3–9 行检查是否存在名为requirements.txt
的文件,该文件提供了该结果的最终输出。如果文件不存在,我们使用退出状态 1 表示失败,预提交停止提交。
对于 bash shell 来说,以零(0)退出状态退出的命令已经成功。非零(1–255)退出状态表示失败。
bash 脚本将完成并最终生成一个新的requirements.txt
文件,因为在检查第 11 行时NEW_REQUIREMENTS
不等于空白的REQUIREMENTS
。
在第 11 行,我们将当前的requirements.txt
文件存储为REQUIREMENTS
。然后是第 13–15 行,检查旧版本REQUIREMENTS,
是否与我们当前虚拟环境的NEW_REQUIREMENTS.
相同。如果这些文件相同,我们不需要更新任何内容,并使用退出状态 0 来表示成功。如果create-requirements
是我们的最后一个钩子,这允许预提交运行下一个钩子或者完成提交过程。
但是,如果REQUIREMENTS
和NEW_REQUIREMENTS
不相同,我们需要重写我们的requirements.txt
。这是在第 18 行完成的,我们从 poem 的虚拟环境中创建了一个新的requirements.txt
文件。注意,在我们重写这个文件之后,我们使用退出状态 1,这样我们的脚本失败了,我们的提交也失败了。
这个失败允许我们运行git add requirements.txt
来提交。我们的下一个git commit
将重新运行我们的钩子,这一次通过所有的检查,因为新的requirements.txt
对我们的虚拟环境是最新的。
该流程确保我们在本地运行应用的虚拟环境与我们在远程运行应用的虚拟环境保持一致。
确保我们的定制挂钩正常工作
在这里,我们运行一些检查来查看 bash 脚本是如何工作的。
首次测试
假设我们的回购中没有requirements.txt
文件,我们尝试提交。
我们的自定义挂钩失败
根据我们的 bash 代码,我们应该得到一个失败和requirements.txt does not exist
错误消息。然后在目录中生成一个requirements.txt
。我们可以通过运行git status.
看到这一点
git 状态
请注意,我们现在有一个未被跟踪的requirements.txt.
在实践中,人们现在会:
- 运行
git add requirement.txt
- 运行
git commit -m "add requirements.txt"
我们的定制钩子传递
现在我们的提交已经完成,可以推送给 git 了。
如果您不想提交这个检查,运行git reset HEAD~
来恢复提交。
第二次测试
假设我们对虚拟环境的依赖关系进行了更改。我们可以用下面的代码运行预提交钩子。
poetry run pre-commit run --all-files
这将给出与运行相同的终端输出:
git commit -m “modified requirements.txt”
然而,第一行只运行我们的预提交钩子,而第二行运行我们的钩子来准备提交。
请注意新的错误消息requirements.txt is not up to date!
同样,我们现在有一个由 bash 脚本的第 18 行生成的未跟踪的requirements.txt
。实际上,现在人们会:
- 运行
git add requirement.txt
- 运行
git commit -m "update requirements.txt"
预提交挂钩的目的是确保在对 Git repo 进行更改之前,某些事情会发生或不会发生。在我们的例子中,这个预提交钩子确保我们的requirements.txt
文件存在,并且与我们当前的诗歌虚拟环境保持一致。所有这些都是在我们将任何代码推送到 git 并最终投入生产之前完成的。
结论
我们的定制钩子create-requirements
,确保我们在本地使用的环境与我们在远程创建的环境一致。这可以通过 bash 代码、退出状态和pre-commit
来实现。非零的退出状态会导致 bash 脚本发出一个错误。因此,这些错误可以用来阻止不符合我们标准的提交。
如何收集 Reddit 数据集
原文:https://towardsdatascience.com/how-to-collect-a-reddit-dataset-c369de539114?source=collection_archive---------4-----------------------
在 Python 中使用 PSAW 和 PRAW
Reddit 是一个社交媒体平台,由子论坛或子编辑组成,每个子论坛专注于一个给定的主题。一些公共子数据可能是有趣数据的深井,随时可供探索!然而,即使想到如何收集这些数据,尤其是大量的数据,也是令人望而生畏的。
在这篇文章中,我们将使用 Python 开发一个工具,从任何(公共)子编辑中收集公共可用的 Reddit 帖子,包括他们的评论帖子,按发布年份组织。
我们将详细介绍必要的设置和记录功能,完整的主算法和逐块的,最后是收集数据的示例和收集和探索的想法。
设置
我们的工具将基于 PSAW 和 PRAW 。PSAW 的用法相当简单。然而,为了使用 PRAW (Reddit 的 API),您需要设置您的授权令牌,以便 Reddit 知道您的应用程序。您可以按照这个指南快速获得您的令牌,并替换下面代码中的相关信息,具体来说,就是您的客户端 ID 和密码,以及您的 reddit 用户名和密码。
import praw
from psaw import PushshiftAPI# to use PSAW
api = PushshiftAPI()# to use PRAW
reddit = praw.Reddit(
client_id = "YOUR_CLIENT_ID_HERE",
client_secret = "YOUR_CLIENT_SECRET_HERE",
username = "YOUR_USERNAME_HERE",
password = "YOUR_PASSWORD_HERE",
user_agent = "my agent"
)
我们还必须定义子编辑列表(可以只有一个!)和年份范围,即从哪一年开始和哪一年结束将检索帖子。在这种情况下,我们将从 2020 年初到 2021 年底(到今天为止)发布的r/shortscarystorys subreddit中提取帖子。最后,我们必须设置存储数据的目录。
subreddits = ['shortscarystories']
start_year = 2020
end_year = 2021# directory on which to store the data
basecorpus = './my-dataset/'
日志记录功能
日志功能让您深入了解正在运行的进程。当这个过程很长,你想知道它是如何进行的时候,这些尤其重要。在我们的例子中,我们将简单地编写一个函数,将算法刚刚采取的动作,以及采取该动作需要多长时间打印到屏幕上。如果我们最终提取了很多很多的数据,并希望确保程序不只是停留在某个地方,这将是非常有见地的。这个函数可以很容易地修改为记录到一个文件,而不是打印到屏幕上:这就是为什么我把它封装到一个函数中,而不是把打印直接内置到算法中。
import timedef log_action(action):
print(action)
return
主算法
主要思想非常简单:在<start_year>和<end_year>之间的每一年,创建一个目录,并且为
这是完整的代码,然后我们将一次一个块地检查它。
详述算法
**###第 1 块# ## **
简单地说,对于从<start_year>到<end_year>之间的每一年,创建一个目录并定义开始和结束时间戳(从当年开始直到下一年开始)。这些时间戳作为输入提供给 PSAW 请求,指定从中检索数据的时间窗口。</end_year></start_year>
###第二块# ## #第十四块】
对于
###第 3 块# ## #第 19 块】
定义存储每个帖子的 Python 字典(存储在内存中,稍后写入之前定义的 CSV 文件路径)。我们对存储帖子的 ID、URL、标题、分数、评论数、创建时间戳和帖子的实际正文(selftext)感兴趣。可以提取其他指标——使用本指南找出您确切需要的指标。
**###块 4 # ## # **
PSAW 允许我们创建一个迭代器来遍历一组特定的文章(也称为提交)。我们用之前设置的参数来指定这个集合:开始和结束时间戳、特定的子编辑以及要检索的帖子数量。在这个例子中,我将其限制在 100 篇帖子,但是 Python 关键字 None 可以用于在指定的时间框架内浏览所有帖子。此外,PSAW 没有给我们每篇文章想要的所有信息,所以我们只使用它来检索文章的 ID ,然后在 PRAW 使用该 ID 来获取剩余的信息。
**# # # 5 # # ## **
对于我们在前面的块中定义的迭代器中的每个 post(或 submission ),获取它的 ID 并使用它从 PRAW 获取完整的 post 数据,并将它附加到我们在块 3 中定义的 Python 字典中。
###块 6 ###
每个帖子都有一个相关的评论线程,我们也希望收集这些评论线程,以便将来进行可能的分析。我们希望将这篇文章的整个评论存储在一个单独的 CSV 文件中,我们现在为该文件定义适当的文件路径。我们还定义了 Python 字典来存储这篇文章的评论线程,特别是每个评论的 ID、父 ID、链接 ID,最重要的是它的正文。
###块 7 # ## #块 19】
现在,对于当前帖子的扁平化评论线程中的每个评论(它最初是一个树结构,我们显式地将其扁平化,但总是可以基于评论父 ID 检索原始树结构),我们检索适当的数据并存储在我们在前面的块中定义的 Python 字典中。一旦我们检查了当前帖子的所有评论并存储在字典中,我们就可以将它保存到 CSV 文件中(该路径是我们在前面的块中定义的)。我们使用 Pandas 轻松地转换成正确的格式并写入文件。
# # # 8 # # ## # 23】
最后,一旦我们遍历了迭代器中的所有 post(即,在块 4 中定义的指定时间范围内)并存储在字典中,我们可以将它保存到 CSV 文件中(我们在块 2 中定义了该路径)。同样,我们使用 Pandas 轻松地转换成正确的格式并写入文件。
记录输出
这是上面代码中示例的日志记录输出:
[Year] 2020
[Subreddit] shortscarystories
[Info] Found submissions: 100
[Info] Elapsed time: 26.14s
[Year] 2021
[Subreddit] shortscarystories
[Info] Found submissions: 100
[Info] Elapsed time: 27.96s
收集的数据示例
前 3 篇收集自 2020 年 r/shortscarystories 的帖子(2020-shortscarystories-submissions . CSV)。图片作者。
需要注意的一个重要方面是,Reddit 的原始数据并不完美。有些帖子的内容可能已经被删除,但帖子仍然存在,在“随意杀人”条目中可以看到,帖子的正文是“[已删除]”。不是盲目地收集所有数据,而是可以改变块 5 以忽略文本主体为“[已删除]”、“[已移除]”或空的所有帖子。这也可以在稍后的数据预处理阶段执行。
收集和探索的想法
最后,我在这里留下我写这篇文章时的一些想法,这些想法可以产生有趣的挑战和结果。
- 利用最近来自 https://www.reddit.com/r/recipes/的帖子,人们可以收集一个食谱图片、配料和说明的数据集。有了这些数据,人们可以开发出这样的系统:基于成分列表的配方建议器、基于成分列表的配方创建器、基于配方图像的配方指令合成器等等。
- 利用来自https://www.reddit.com/r/shortscarystories/帖子的数据,开发如下系统:给定标题作为提示的恐怖短篇故事生成器,基于故事标题和文本的评分/评论预测,用于观众统计预测,等等。
- 使用来自https://www.reddit.com/r/AskReddit/帖子的数据(帖子是一个问题,评论是可能的答案),开发一个 oracle 系统,它对每一个可以想象到的问题都有一个答案。
如何使用 Python 从加拿大统计局收集数据
原文:https://towardsdatascience.com/how-to-collect-data-from-statistics-canada-using-python-db8a81ce6475?source=collection_archive---------16-----------------------
实践教程
加拿大统计局 API 和 python 库的分步教程
Alex Shutin 在 Unsplash 上拍摄的照片
加拿大统计局提供广泛的数据供公众使用,包括加拿大经济、社会和环境的数据。除了手动浏览网页访问数据,加拿大统计局还提供 Web 数据服务,即 API 访问他们的数据库。更好的是,有一个 python 库 stats_can 包装了 API 命令,允许用户编写简单的代码来自动读取数据。本文将提供如何实现这一点的一步一步的教程。
识别所需数据项及其vectorID
进入加拿大统计局子页面数据,输入关键词,例如 GDP,点击搜索图标。
在返回的结果中找到所需的项目。
在 GDP 页面上,点击Add/Remove data
。
点击标签页Customize layout
。
向下滚动并勾选选项Display Vector identifier and coordinate
,然后点击按钮Apply
。
现在,该表将被重组,您会发现一个新列Vector
,这里我们将选择所有行业的 GDP,因此目标vectorID
是v65201210
。这将在稍后的 Python 代码中使用。
在 Python 中安装 stats_can
该库可以与 conda 或 pip 一起安装:
conda install -c conda-forge stats_can
或者:
pip install stats-can
收集数据
我们将使用函数[stats_can.sc.vector_to_df](https://stats-can.readthedocs.io/en/latest/stats_can.html#stats_can.sc.vectors_to_df)
从加拿大统计局读取数据。该函数的语法如下:
df = stats_can.sc.vectors_to_df(vectors, periods = n, start_release_date = None, end_release_date = None)
它返回具有 n 个周期数据或发布日期范围的向量的数据框架。该函数包装了两个 API 命令,分别是get_bulk_vector_data_by_range
和get_data_from_vectors_and_latest_n_periods
,用于将 JSONs 的结果列表转换为数据帧。
例如,对于 GDP 的矢量数据v65201210
,您可以运行以下代码来收集过去 6 个月的 GDP:
import stats_candf = stats_can.sc.vectors_to_df('v65201210', periods = 6)
您可以重命名索引和列,使表格看起来更漂亮:
df.columns = ['GDP']
df.index.names = ['Date']
返回的表如下所示:
Date GDP
2020-05-01 1726385.0
2020-06-01 1833032.0
2020-07-01 1879281.0
2020-08-01 1896592.0
2020-09-01 1912085.0
2020-10-01 1920056.0
收集和可视化多个经济指数的示例
在最近的项目中,我收集了多个生态指数,如 GDP、CPI、失业率等。建立多变量回归模型,用于预测金融交易数量。
首先,我计算出我计划使用的所有 eco 指数的向量,包括 GDP、CPI、TSX、失业率和汇率(美元兑加元),并将它们放入字典中:
eco_vec_map = {'CPI':'v41690973',
'Exchange_Rate_USD':'v111666275',
'GDP':'v65201210',
'Unemployment_Rate':'v91506256',
'TSX':'v122620'}
其次,我将字典中的值转换为一个列表并运行函数,输入 periods = 36(即最近 3 年),函数自动识别向量列表并返回多列表:
vectors = list(eco_vec_map.values())
df = stats_can.sc.vectors_to_df(vectors, periods = 36)
然后,我用它们的 eco 索引名重命名了这些列,注意这里使用了一个映射技巧,这样您就不必担心列的顺序了:
inv_map = {v: k for k, v in eco_vec_map.items()}
df.columns = df.columns.to_series().map(inv_map)
df.index.names = ['Date']
返回的表如下所示:
Date TSX CPI GDP Unemployment_Rate Exchange_Rate_USD
2017-09-01 NaN NaN 1905358.0 NaN NaN
2017-10-01 16025.59 130.9 1907384.0 NaN NaN
2017-11-01 16067.48 131.3 1917258.0 5.4 1.2769
2017-12-01 16209.13 130.8 1922552.0 5.3 1.2771
...
2020-08-01 16514.44 137.0 1904249.0 11.0 1.3222
2020-09-01 16121.38 136.9 NaN 8.4 1.3228
2020-10-01 NaN NaN NaN 8.1 1.3215
最后,我可视化了表中的所有列:
df.plot(subplots = True, figsize = (14,8), layout = (3,2));
结果显示,除 CPI 外,其他生态指数在 2020 年 3-4 月间经历了大幅下降或上升,这很可能是受疫情的影响。
摘要
本文详细介绍了如何使用加拿大统计局的 Python 库收集数据。主要步骤是:
- 识别目标数据项的
vectorIDs
。 - 安装
stats_can
库,调用函数stats_can.sc.vectors_to_df
采集数据并保存为 DataFrame 表。
我很难在网上找到好的教程,所以我写了这篇文章,希望能帮助别人。如有任何问题或建议,请随时通过 Linkedin 联系我。我很乐意连接:)
参考资料:
[1]网络数据服务用户指南,加拿大统计局。https://www . stat can . GC . ca/eng/developers/WDS/user-guide # a12-3
[2]用于读取加拿大统计局数据的 python 库。
https://stats-can.readthedocs.io/en/latest/index.html#
如何使用 Python & Tesseract 从图像中收集文本信息
原文:https://towardsdatascience.com/how-to-collect-text-information-from-images-with-python-tesseract-7073785b1d77?source=collection_archive---------5-----------------------
一个从公寓平面图中自动收集房间尺寸的脚本…或者至少它尝试了
作者图片
如果你有分析思维,并且曾经进行过虚拟找房之旅,你可能会遇到我个人一直觉得令人恼火的问题:你几乎永远无法通过房产大小进行搜索,更不用说通过单个房间的大小了。然而,这种信息经常以平面布置图的形式出现。只是大量的缩放和手动输入来收集数据…
嗯,我认为这将是一个练习图像识别技能和创建一个脚本的绝佳机会,该脚本可以将图像转换成一个漂亮而干净的数据表。毕竟,随着每个过于雄心勃勃的项目开始:
能有多难?
事实证明,相当困难。我其实并不确定这是一个可以 100%准确解决的问题。我认为我充分探索了各种可能性,并取得了良好的进展,但请注意这个项目不会完全成功。即使经过重大的调整和微调,一个特别棘手或质量差的图像可能会使算法出错。
然而,我认为对于像我一样抱着天真的期望开始类似项目的人来说,这是一个宝贵的教训。
摘要
最后,我们希望将平面图转换成显示房间和房间大小的表格。我们正在使用米,但调整代码应该很简单,这样它也可以识别英尺的度量。
我们将使用的 pytesseract ,它是谷歌的 Tesseract OCR 的 Python 包装器。
该项目的代码在我的 GitHub 上。
- 如果你只是想自己尝试一下,你将需要floor plan _ reader脚本。您将需要安装软件包和 Tesseract,另外您可能需要调整它在脚本中的位置。 主 Jupyter 笔记本显示了如何使用代码。祝你好运!
- 如果您想继续学习,请继续下一节,在这里我们将设置环境。
环境
宇宙魔方
首先,我们需要宇宙魔方包本身,即使我们不直接使用它。安装过程并不简单,你也可以在官方的 GitHub 页面找到更多信息,但是我发现这个摘要更有用。
在 Mac 上,安装自制软件非常简单:
brew install tesseract
您还需要 Tesseract 的位置,我跟踪了这个堆栈溢出线程,我的安装位置是:
/usr/local/bin/tesseract
(当然,不同系统的位置不同。)
Python 包
我们需要两个“非标准”包:枕头和宇宙魔方:
pip install Pillowpip install pytesseract
Pillow 是一个处理图像的包,是一个名为 PIL 的旧包的分支,我们将使用它的图像对象:
from PIL import Image
(是的,这个库在项目内部仍然被称为 PIL,这并不意味着我们使用了过时的 PIL 包。)
对于宇宙魔方,我们需要连接到它的位置:
import pytesseract
pytesseract.pytesseract.tesseract_cmd = r'/usr/local/bin/tesseract'
从错误中学习
我将向你介绍我在开始使用 pytesseract 时犯的四个业余错误。如果你更喜欢"这是目的地,而不是旅程。“种人,跳过这一点,我们在下一节开始看实际代码。
文件路径与图像
如果您从 pytesseract 开始,您尝试的第一件事可能是image_to_string
函数。顾名思义,它确实如此。
您可以将图像或文件路径作为参数传递。然而,根据我的经验,首先处理图像总是更好。用枕头,用它打开图片,传递图像对象。考虑这个平面布置图示例:
如果我们直接用 pytesseract 打开:
pytesseract.image_to_string(‘plans/floorplan_02.png’)
这是我们得到的结果:
'KITCHENIDINER — MASTER BEDROOM\ngo" xis" Tatra hou" xara\nPi\n\n3.14m x 2.95m\n\nSITTING ROOM\n12\'1" x 15\'7"\n3.69m x 4.74m\n\nBEDROOM 2\n8\'1" x 12\'0"\n2.47m x 3.66m\nBEDROOM 3\n71" x 85"\n2.17m x 2.56m\n\n \n\x0c'
而如果我们先用枕头打开:
pytesseract.image_to_string(Image.open('plans/floorplan_02.png'))
这是我们得到的结果:
'KITCHEN/DINER\n15°7" x 11\'8"\n4.74m x 3.55m\n\nSITTING ROOM\n12\'1" x 15\'7"\n3.69m x 4.74m\n\n \n\n \n\n \n\n \n\n \n\n \n\nMASTER BEDROOM\n10\'4" x 9\'8"\n3.14m x 2.95m\n\nBEDROOM 2\n8\'1" x 12\'0"\n2.47m x 3.66m\n\nBEDROOM 3\n71" x 85"\n2.17m x 2.56m\n\n \n\x0c'
是的,你的眼睛没有欺骗你,那是一个完整的额外线!那以后会派上用场的。
第一课 。:在将任何东西传递给 pytesseract 之前,始终使用 Pillow 之类的图像处理包。将图像对象作为参数传递,而不是文件路径。
调整大小很重要
下一个令人惊讶的是关于调整大小。考虑下面的图像(模糊,是的,这将是重点。):
如果您只是将它作为一个枕头图像读入,并将其传递给 image_to_string,您会得到以下结果:
' \n \n \n\nUTILITY ROOM\n\n \n \n \n\n \n \n\n \n\n \n \n \n\n
...
但是,如果您首先调整图像的大小,比如说将其宽度和高度调整为原来的 5 倍:
image = image.resize((image.size[0] * 5, image.size[1] * 5))
结果是:
'UTILITY ROOM\nR\' i\nSe 2.51m x 2.44m\n3.88m x ?2.57m\nSITTING ROOM
...
我没有复制整个结果,重点是,如果没有重新缩放,杂物间下的较小文本不会被读入。
你可以在这里了解更多关于枕头的图像处理。我个人没有调整图像亮度或对比度的运气。只有重新调整似乎工作得很好。我不知道为什么会这样。
第二课 。:利用 Pillow 的图像处理功能。如果您调整图像的大小,调整亮度或对比度,Tesseract 会以不同的方式读入您的图像。然而,变化并不总是积极的!例如,您可能会注意到,缩放超过某个阈值会降低精度。
裁剪也很重要…
…当我们这样做的时候,你对图像所做的任何其他事情都很重要!
我实际上对你耍了点小花招,如果你真的读了上面的图片,杂物间的第一面2.51
,将被读为2.91
。原因?我从原始图片中截取了主要信息。没有缩放,或以任何方式调整,只是排除了一些空白区域。没有裁剪,数字可以正确读取。
正是在这个时候,我第一次开始考虑接受失败…
第三课 。:实际上任何事情都可以改变结果。您永远无法确定字符是否被正确地读入,即使它们是用漂亮、一致的字体书写的,并且在您的人眼看来似乎没问题。宇宙魔方的算法并不适用于所有情况。
一张整洁有序的表格胜过一大堆杂乱的文字
在很长一段时间里,我试图用image_to_string
方法来强迫项目工作。如果你看一下上面的一些例子,你可能会发现我没有发现的问题。
问题是image_to_string
将逐行从左到右、从上到下扫描文档。(它如何确定 \n 的位置,谁也说不准。)我非常确定我可以让下面的逻辑工作:
loop over the string
search for matches of pre-defined room names from a set
if there is a match:
put the room name in a dictionary
delete the corresponding room from the set and the string
look for the next bit that looks like the two sides
when found, save the sides in the dictionary
delete the sides from the stringrepeat the process with the shortened room name set and main string, until there is no new room found
这个想法是,房间可以彼此靠近,但第一个房间名称后从左到右和从上到下的第一个数字必须是与所讨论的房间相对应的数字...是的,我知道,但我要说的是,这招出奇的有效。
然后我终于遇到了我的克星:
我不知道为什么我以前没有想到这种可能性,但是把米放在两条不同的线上完全打乱了我以前的方法。更不用说我还没有遇到过的任何其他平面图结构。
我认为仅仅通过阅读image_to_string
产生的连续文本是无法确定哪个尺寸属于哪个房间的。然而,通过使用image_to_data
方法(加上一些额外的调整,我们将在下一节中看到),我们得到了一个漂亮且有组织的表:
第四课 。:除非你有一个微不足道的问题,否则你会想用
*image_to_data*
而不是*image_to_string*
。只要确保将*output_type*
参数设置为“ data.frame ”就可以得到熊猫数据帧,而不是更乱更大的文本块。
浏览代码
在这一部分,我将带大家浏览代码。请注意,我不会完全照搬脚本,我们只讨论要点。
打开图像
首先,我们需要一个方法来打开图像本身,这是我最终使用的方法:
def **process_image**(filepath, resize_factor = 1): image = Image.open(filepath)
image = image.resize(
(image.size[0] * resize_factor, image.size[1] * resize_factor)) return image
我花了很多时间试图找出一个最佳的resize_factor
。有人会认为这与图片的像素大小有关,但显然,事实并非如此。我最终把责任抽离出来,变成了一场争论。我猜你可以对不同的resize_factors
重复这个过程,看看你是否得到相同的结果。
用宇宙魔方读入图像
这在技术上是整个代码的图像识别部分。如前所述,我们希望使用image_to_data
。这就是如何将它转换成一个美观易读的表格:
def **convert_floorplan_pic_to_df**(filepath, resize_factor = 1): image = process_image(filepath, resize_factor) df = pytesseract.image_to_data(image, output_type='data.frame')
df = df[df['conf'] != -1]
df['text'] = df['text'].apply(lambda x: x.strip())
df = df[df['text']!=""]
df['text'] = df['text'].apply(lambda x: x.upper()) return df
向上滚动一点,看看这个数据帧应该是什么样子。
我们将使用其中大约一半的列。列conf
显示了模型在其解决方案中的确定性,-1 是这些奇怪的额外行,不知道它们为什么在那里,但我们肯定不需要它们。还有很多读入的空白,我们也不需要。
识别文本部分
我们已经有了一个图像上带有文本的数据框架,但是我们还远远没有完成,在它可用之前还有大量的处理工作。
我们利用另外两个函数,将图像转换成包含文本信息的数据帧:
def **process_floorplan**(
filepath, rooms_set = default_rooms_set, resize_factor = 1): df = convert_floorplan_pic_to_df(filepath, resize_factor)
我们想一行一行地检查这个数据帧,并决定这个字符串是房间名称、大小还是其他什么。
房间将从一组房间名称字符串中识别出来,默认情况下看起来像这样:
default_rooms_set = {"DINING ROOM", "KITCHEN", "LIVING ROOM",
...
}
另一方面,使用正则表达式来识别大小。我们基本上要考虑每个浮点数,这很容易做到:
room_side_regex = r'[0-9]+[.][0-9]+'
如果我们看一下df
对象,我们会立即发现一个问题:一些房间名可能会被分成多行。(从今以后,我们假设我们从不希望搜索由两个以上部分组成的房间名。)
我解决这个问题的方法是创建另一个名为text_2row
的文本列,它是两行文本的串联。
shifted_text_col = list(df['text'].iloc[1:])
shifted_text_col.append("")
df['text_2row'] = df['text'] + " " + shifted_text_col
现在我们可以循环了。这里不打算复制代码,再次请参考我的 GitHub 。逻辑如下:
for each row in the DataFrame:
if the text_2rows matches one of the rooms
the current row gets a room id
go to next in loop, skip an extra line
if not match so far
if text column matches one of the rooms
current row gets a room id
go to next in loop
if no match so far
if text column matches the size regex
current row gets a room_side id
go to next in loop
if still no match
current row gets no id
go to next in loop
在大小匹配中有一个假设:如果行中有多个浮点数,我们总是取第一个浮点数。所以如果这个列表的长度大于 0:
regex_list = re.findall(room_side_regex,df[‘text’].iloc[i])
我们取第一个元素:
df['side_number'].iloc[i] = float(regex_list[0])
经过一些清理后,我将数据帧分成两个较小的数据帧。两者都包含被确定为room
或room_side
的行的left
、top
和value
列。这是我们的房间:
我们有一个类似的边表,数字在value
列。
搭配带侧边的房间
我们已经从文本中获得了所有需要的信息,我们现在只需要匹配它们。
有许多不同的方法可以解决这个问题。注意,当我们用image_to_data
创建原始 DataFrame 时,pytesseract 会放入一些有用的信息。例如,我们有一个block
列,它将文本排列成簇。
我最终使用了left
和top
列,它们应该是包含文本的框的位置,从图像的左上角开始计算。我们将计算这些左上角的欧几里德距离,并为每个房间选择两个最接近的数字。这种方法有一些缺点,我们将很快回到它。
我们将使用scipy
中的distance_matrix
方法:
from scipy.spatial import distance_matrixdist = distance_matrix(
df_rooms[['left', 'top']],
df_sides[['left', 'top']])
然后这只是一个为每个房间选择两个最近点的练习。我们依赖于numpy
的argpartition
方法,同样,代码在我的 GitHub 中。
最终确定
经过一些格式化之后,我们终于得到了我们的最终产品:
成功了吗?
我想,算是吧。如果你看一下上面的表格,我认为只有一个小小的错误。加上学习没有找到…
当然,这只是一个例子。最大的挑战是读取以前看不到的格式的平面图。我相信,如果你关注某个机构的平面图,并对图像处理进行微调,它可以在更大范围内变得可靠。
我确实学到了很多关于图像文本处理的知识。大部分是关于它的局限性,但是嘿,那仍然算数!我希望你通过阅读这篇文章也学到了一些新的东西。
可能的改进
我有一些想法可以让这个过程变得更好:
- 专注于某些房间类型,不要像我一样试图处理所有房间。问题是很难确定一个房间在平面图上是否有尺寸。我想象一个杂物间会在没有精确尺寸的情况下被展示。
- 我放弃了调整贴图的对比度和亮度的想法,结果似乎不可靠,但也许值得花时间来研究这如何改变 pytesseract 的结果。
- 房间到侧面的匹配有点简单。这里可以有额外的检查,例如,我们可以检查某些元素是否大致在彼此之下,这将表明更密切的关系。
https://matepocs.medium.com/membership
如何给熊猫数据框上色
原文:https://towardsdatascience.com/how-to-color-a-pandas-dataframe-41ee45db04f6?source=collection_archive---------12-----------------------
一个关于如何在熊猫数据帧上设置颜色的简短教程。
罗伯特·卡茨基在 Unsplash 上的照片
andas 无需介绍,因为它已经成为 Python 中事实上的数据分析工具。作为一名数据科学家,我每天都使用熊猫,它总能以更好的方式实现我的目标,让我感到惊讶。
我最近学到的另一个有用的特性是如何给熊猫的数据帧上色。
这里有几个你可能会感兴趣的链接:
- [Complete your Python analyses 10x faster with Mito](https://trymito.io/) [Product]- [Free skill tests for Data Scientists & ML Engineers](https://aigents.co/skills) [Test]- [All New Self-Driving Car Engineer Nanodegree](https://imp.i115008.net/c/2402645/1116216/11298)[Course]
你愿意阅读更多这样的文章吗?如果是这样,你可以点击上面的任何链接来支持我。其中一些是附属链接,但你不需要购买任何东西。
让我们添加颜色
让我们用随机数创建一个熊猫数据帧:
import numpy as np
import pandas as pddf = pd.DataFrame(np.random.randint(0, 100, size=(15, 4)), columns=list("ABCD"))
带有随机数的熊猫数据框(图片由作者制作)
给单元格着色(按频率)非常简单:
df.style.background_gradient(cmap="Blues")
带有随机数的彩色熊猫数据框(图片由作者制作)
颜色是基于列的
如果我们把 B 列增加 1000,就不会干扰其他列的颜色。
df["B"] *= 1000
如下图所示,A、C、D 列的最大值保留了它们的颜色。
带有随机数的彩色熊猫数据框(图片由作者制作)
更改颜色映射
您可以设置 matplotlib 中支持的任何色彩映射表。如果您的目标是可视化频率,请小心选择顺序色图。
来自 matplotlib 的连续颜色图(图片由作者制作)
非顺序色彩映射表是可视化频率的一个不好的例子(所以请确保使用顺序色彩映射表):
df.style.background_gradient(cmap="Spectral")
可视化频率的一个不好的例子是用一个无序的颜色图(作者制作的图像)
在你走之前
在 Twitter 上关注我,在那里我定期发布关于数据科学和机器学习的消息。
照片由Courtney hedge在 Unsplash 拍摄
如何在 R 中组合动画剧情
原文:https://towardsdatascience.com/how-to-combine-animated-plots-in-r-734c6c952315?source=collection_archive---------22-----------------------
利用 gganimate 和 magick 的强大功能为您的观众组合动画情节
在本教程中,我将概述在 r 中创建动画多面图的必要步骤。虽然很少,但组合动画图可以是展示相同数据的不同元素的强大方法(如下所示)。
在这个例子中,我使用了来自国际举重联合会的举重数据。出于本教程的目的,我们将看看不同性别托举的差异。一个多面的动画情节是一个很好的选择,因为我们想观察这些差异的大小以及这些差异是如何随着时间的推移而演变的。
我们将创建这个 GIF:
环境设置
这些是我们开始工作所需的包。在我的例子中,我使用了一个为风格目的而开发的自定义主题。请随意运行theme_set(theme_minimal())
而不是使用我的主题!
加载和清理数据
我已经帮你清理了很多数据。如果你想跟着做,这是过程(或者,直接跳过!).
在这里,我们将做一些小清洁,然后将三个电梯改造成一列:
就我的想象而言,我只关心每年最重的举升次数:
我们将为最终输出创建的第一个可视化图形是一个哑铃图。好奇那是什么,或者如何在 R 中制作?看看我关于这个话题的另一篇文章。
为了构造一个哑铃图,我们需要在同一行中同时进行雄性和雌性观察。为此,我们使用了spread
函数。
现在,让我们为每种性别构建一个数据框架:
加入他们:
不跟随,或者想检查你的进展?以下是我们的数据最终的样子:
视觉化!
最后,我们可以构建可视化。
首先,我们可以使用ggalt
创建一个静态可视化(同样,我的博客文章涵盖了这个步骤的细节)。
如果你只对两者的组合感兴趣,你可以快进到单个情节的创作。你会在这篇文章的结尾发现这一点!
最后,我们使用 Thomas Pedersen 精彩的 gganimate 软件包制作动画。这是一个相对容易的步骤,因为gganimate
只需要两行额外的代码:transition_states
和ease_aes
。然后,我们把它传入animate
函数!
但是在我们的例子中,我们希望包含另一个 GIF:一个随时间变化的差异折线图。
最后,我们将使用magick
来组合它们(感谢这篇文章)。在这里你可以找到进行组合所必需的代码(不管你的动画情节是什么样的,这应该是可行的!).
这里发生了什么事?本质上,我们利用magick
的力量来:
- (第 2-3 行)从每个 GIF 中读入所有的单个图像 (
image_read
)(毕竟,GIF 只是一系列图像!). - (第 5 行)对于第一帧,将两幅图像堆叠在彼此之上(
image_append
),因此图 1 在图 2 之上。 - (第 6–9 行)对于其余的帧(在我的例子中,是下一个 249 帧,因为我的 GIF 有 250 帧),复制这个并将其与第一帧合并(这是
for
循环)。
这里,我们指定stack = TRUE
以便一个图在另一个图的之上。如果您想将它们并排放置,请指定stack = FALSE
。
总的来说,该流程会产生我们的最终结果:
在此视图中,我们可以看到相对和绝对差异的大小(上图),和我们可以看到这些差异如何随时间变化(下图)。动画组合图表的力量!
感谢阅读。有问题吗?给 me@connorrothschild.com 发电子邮件或者在推特上给我发信息。
如何在 Pandas 中组合数据——你应该知道的 5 个功能
原文:https://towardsdatascience.com/how-to-combine-data-in-pandas-5-functions-you-should-know-651ac71a94d6?source=collection_archive---------8-----------------------
了解它们的不同之处,并正确使用它们
Hendrik Cornelissen 在 Unsplash 上拍摄的照片
当我们使用 Pandas 处理数据时,一个常见的任务是组合来自不同来源的数据。在本文中,我将回顾您可以用于数据合并的 5 个 Pandas 函数,如下所列。如果你想看的话,每个函数都有到官方文档的链接。
* [concat](https://pandas.pydata.org/docs/reference/api/pandas.concat.html)
* [join](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.join.html#pandas.DataFrame.join)
* [merge](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.merge.html#pandas.DataFrame.merge)
* [combine](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.combine.html)
* [append](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.append.html#pandas.DataFrame.append)
对于当前教程,让我们使用两个简单的DataFrame
对象,如下所示。请注意,为了更好地说明相应的功能,我将在适当的地方做一些小小的修改。
用于说明的数据帧
1.串联
concat
函数以串联命名,它允许您水平或垂直地并排组合数据。
当您组合具有相同列的数据时(或者实际上它们中的大多数是相同的),您可以通过将axis
指定为 0 来调用concat
,这实际上也是默认值。
>>> pd.concat([df0, df1.rename(columns={"c": "a", "d": "b"})], axis=0)
a b
0 1 4
1 2 5
2 3 6
0 2 5
1 3 6
2 4 7
当您将数据与指示相同实体的行(即,相同有序主题的研究数据)和不同数据的列组合时,您可以将它们并排连接。
>>> pd.concat([df0, df1], axis=1)
a b c d
0 1 4 2 5
1 2 5 3 6
2 3 6 4 7
默认情况下,当您水平组合数据时(即沿着列),Pandas 会尝试使用索引。当它们不相同时,您会看到 nan 来填充不重叠的部分,如下所示。
>>> df2 = df1.copy()
>>> df2.index = [1, 2, 3]
>>> pd.concat([df0, df2], axis=1)
a b c d
0 1.0 4.0 NaN NaN
1 2.0 5.0 2.0 5.0
2 3.0 6.0 3.0 6.0
3 NaN NaN 4.0 7.0
如果这不是期望的行为,并且您希望通过忽略索引来使它们完全对齐,则应该在连接之前重置索引:
>>> pd.concat([df0.reset_index(drop=True), df2.reset_index(drop=True)], axis=1)
a b c d
0 1 4 2 5
1 2 5 3 6
2 3 6 4 7
请注意,df0
的重置索引是可选的,因为它的索引恰好是从 0 开始的,这将与df2
的重置索引相匹配。
2.加入
与concat
相比,join
专门使用索引连接DataFrame
对象之间的列。
>>> df0.join(df1)
a b c d
0 1 4 2 5
1 2 5 3 6
2 3 6 4 7
当索引不同时,默认情况下,连接保持左边的行DataFrame
。从右边DataFrame
开始,左边DataFrame
中没有匹配索引的行被删除,如下所示:
>>> df0.join(df2)
a b c d
0 1 4 NaN NaN
1 2 5 2.0 5.0
2 3 6 3.0 6.0
但是,可以通过设置 how 参数来更改此行为。可用选项有:左、右、外和内,它们的行为如下所示。
**# "right" uses df2’s index**
>>> df0.join(df2, how="right")
a b c d
1 2.0 5.0 2 5
2 3.0 6.0 3 6
3 NaN NaN 4 7**# "outer" uses the union**
>>> df0.join(df2, how="outer")
a b c d
0 1.0 4.0 NaN NaN
1 2.0 5.0 2.0 5.0
2 3.0 6.0 3.0 6.0
3 NaN NaN 4.0 7.0**# "inner" uses the intersection**
>>> df0.join(df2, how="inner")
a b c d
1 2 5 2 5
2 3 6 3 6
3.合并
如果你有这样的经验,那么merge
函数很像是在数据库中加入动作。相比 join,merge 更通用,可以对列和索引执行合并操作。因为我们已经介绍了使用基于索引的合并的join
,所以我们将更加关注基于列的合并。让我们看一个简单的例子。
>>> df0.merge(df1.rename(columns={"c": "a"}), on="a", how="inner")
a b d
0 2 5 5
1 3 6 6
on
参数定义了两个DataFrame
对象将在哪些列上合并。请注意,您可以将单个列指定为字符串,也可以在一个列表中指定多个列。这些列必须出现在两个DataFrame
对象中。更一般地,您可以分别从左边的DataFrame
和右边的DataFrame
指定合并列,如下所示。
>>> df0.merge(df1, left_on="a", right_on="c")
a b c d
0 2 5 2 5
1 3 6 3 6
除了单独的列a
和c
之外,这与之前的合并结果基本相同。
有许多其他的可选参数可以用来进行合并。我想在这里强调两点。
how
:定义要执行的合并类型。支持的类型包括左、右、内(默认)、外和交叉。一切都应该很简单,除了最后一个十字,它从两个帧创建笛卡尔乘积,如下所示。
>>> df0.merge(df1, how="cross")
a b c d
0 1 4 2 5
1 1 4 3 6
2 1 4 4 7
3 2 5 2 5
4 2 5 3 6
5 2 5 4 7
6 3 6 2 5
7 3 6 3 6
8 3 6 4 7
- 后缀:当两个 DataFrame 对象具有除了要合并之外的相同列时,此参数设置应该如何使用后缀将这些列重命名为。默认情况下,左右数据框的后缀为
“_x”
和“_y”
,您可以自定义后缀。这里有一个例子。
>>> df0.merge(df1.rename(columns={"c": "a", "d": "b"}), on="a", how="outer", suffixes=("_l", "_r"))
a b_l b_r
0 1 4.0 NaN
1 2 5.0 5.0
2 3 6.0 6.0
3 4 NaN 7.0
4.结合
combine
函数执行两个DataFrame
对象之间的列式合并,与之前的函数有很大不同。combine
的特别之处在于它带了一个函数参数。该函数采用两个Series
,每个对应于每个数据帧中的合并列,并返回一个Series
,作为相同列的元素操作的最终值。听起来很困惑?让我们看看下面代码片段中的一个例子。
组合数据
taking_larger_square
功能作用于df0
和df1
中的a
列和df0
和df1
中的b
列。在两个a
和两个b
列之间,taking_larger_square
从较大的列中取值的平方。在这种情况下,df1
的列a
和b
将被视为正方形,这将产生如上面的代码片段所示的最终值。重命名后的df1
如下图所示,供您参考。
>>> df1.rename(columns={"c": "a", "d": "b"})
a b
0 2 5
1 3 6
2 4 7
虽然这里没有涉及,但是还有另一个密切相关的函数combine_first
,它只是使用第一个帧的非空值来合并两个帧。
5.附加
到目前为止,我们讨论的大多数操作都是针对按列组合数据的。行方式操作怎么样?append 函数专门用于将行追加到现有的DataFrame
对象,创建一个新的对象。我们先来看一个例子。
>>> df0.append(df1.rename(columns={"c": "a", "d": "b"}))
a b
0 1 4
1 2 5
2 3 6
0 2 5
1 3 6
2 4 7
上面的操作你看着眼熟吗?我希望如此,因为这就像你设置axis=0
时用concat
可以实现的一样。然而,append 的独特之处在于,您可以实际追加一个dict
对象,这为我们提供了追加不同类型数据的灵活性。
>>> df0.append({"a": 1, "b": 2}, ignore_index=True)
a b
0 1 4
1 2 5
2 3 6
3 1 2
上面显示了一个简单的例子。请注意,您必须将ignore_index
设置为True
,因为字典对象没有数据帧可以使用的索引信息。
结论
在这篇文章中,我们回顾了熊猫的 5 个最常用的数据合并函数。这里有一个快速回顾。
concat
:按行和按列组合数据join
:使用索引按行组合数据merge
:按列组合数据,就像数据库连接操作一样combine
:按列组合数据,进行列间(相同列)元素操作append
:以DataFrame
或dict
对象的形式逐行追加数据
感谢阅读这篇文章。通过注册我的简讯保持联系。还不是中等会员?用我的会员链接支持我的写作。
作为数据科学家,如何更有效地沟通
原文:https://towardsdatascience.com/how-to-communicate-more-effectively-as-a-data-scientist-de7dfc361b4f?source=collection_archive---------18-----------------------
我从有效培训解决方案(ETS)培训中学到了什么
照片由莱昂在 Unsplash 上拍摄
有效的沟通技能是数据科学家必备的技能,但却是容易被忽视的东西。缺乏这种技能会导致项目效率低下和对可行见解的误解,这对任何公司来说都是代价高昂的。作为数据科学家/分析师,我们的工作不仅仅是看数字。我们提供可操作的见解,并提出数据驱动的建议。分析完数据后,我们需要向业务涉众解释结果,并帮助他们及时做出业务决策。因此,能够向利益相关者解释您的工作并实际应用您的分析和建议是非常重要的。
沟通和公共演讲技巧是我仍在努力提高的领域。当然,我们自己总有可以改进的地方。我们知道的越多,就越意识到我们不知道。在这篇博客中,我想分享我从有效培训解决方案(ETS) 培训中学到的一些技巧,以及这些培训如何帮助我更好地与利益相关者和同事沟通,希望你也会发现它们很有帮助!
一.舒适地待在那里
信不信由你,只要舒服地坐着或站着,你就能立刻增强自信。当我们微笑时,我们往往会感到更快乐。自信的肢体语言可能也是如此。当我们舒适地坐着说话,就像在和朋友交谈一样,我们确实会感到更加放松和自信。自从我开始应用这个技巧,我注意到我的声音听起来更加肯定和自信。作为一个说话温和的人,有时我很难让别人听到我的声音,我通常不得不有意识地努力大声说话。我想如果我大声说话,我的意见会被听到。但是,这不是音量的问题,而是声音听起来有没有优柔寡断。事实上,在培训期间,培训师和有效培训解决方案的首席执行官 Ingrid Gudenas 帮助我们实践了这一点,观察这一小小的调整如何能够戏剧性地改变别人对我们的看法,这是一次令人大开眼界的经历。试试看,如果你也感觉到了不同,请告诉我!
二。做一个好的倾听者+全神贯注
做一个好的倾听者意味着什么?一个好的积极的倾听者会和说话者交流并提问。在学校,我们没有被训练去问利益相关者问题,因为问题通常是由老师提供的。然而,在解决现实世界的问题时,我们首先需要理解涉众试图解决的业务问题,然后寻找数据。即使你有多年数据科学家的工作经验,你仍然需要仔细倾听业务背景,因为你不想浪费时间在分析上,而利益相关者告诉你你误解了请求。我发现在开会时关闭任何通知很有帮助。这样,我可以保持专注,避免旁敲侧击,并提出澄清性的问题。
三。在虚拟会议中进行眼神交流
作为一个实际上在疫情期间上船的人,我还没有亲自见过我的任何同事。起初,我发现很难与同事建立牢固的关系。虚拟增加距离。英格丽建议我们说话时看着镜头。这模拟了虚拟的眼神交流。我发现这非常有用,尤其是在 30 多名同事面前做演示的时候。看着镜头让我感到更加强大和自信。最重要的是,当我听到观众的一些背景噪音时,我没有分心。
四。有同理心
同情你的听众,用他们能理解的格式和语言向他们展示他们想要的信息。首先,我们要知道观众关心什么,他们已经知道什么。我们绝对不想浪费时间一遍又一遍地重复同样的事情,尤其是当他们已经知道的时候。同时,我们也不应该假设他们已经知道了。了解观众是我们工作的一部分。
业务涉众和高管不关心我们使用了哪些工具进行分析,他们更关心的是调查结果、业务方向以及他们下一步可以做什么;其他数据科学家/分析师/ML 工程师更关心你的方法,以及是否有任何折衷。一旦我们了解了受众,我们就可以定制语言并提供有针对性的演示。对于非技术利益相关者,我们应该避免使用高度技术性的术语。不要假设每个人都知道你在说什么。如果我们不能用外行人的语言解释复杂的结果,我们作为优秀的数据科学家是失败的。成为一名优秀的数据科学家并不是要建立很酷的模型,而是要用数据来讲述一个有助于提出战略性商业计划的故事。
动词 (verb 的缩写)如果有不同意见,请跟进
不骗你,让人们改变他们的价值观真的很难。在这种情况下,我们需要更多的耐心。意见不合是常有的事!不要把它当成一个问题,而是把它当成一个你更好地解释自己的机会。误解会导致分歧。当有冲突时,最好开会而不是发信息。别往心里去!每个人都有自己的顾虑。做一个好的倾听者,有同理心。试着理解他们不同意的原因,心平气和地解释你的观点。归根结底,我们都在努力解决冲突。
在会议期间,双方可以讨论问题,并提出一个潜在的解决方案。这意味着双方达成口头协议,并将致力于上述解决方案。这不是大团圆结局吗?然而,你又等了几个星期,仍然没有听到其他人的任何消息。你可能想知道…我以为我们已经达成协议了?🤔英格丽德告诉我们,我们其实可以通过肢体语言和面部表情来判断协议是否有效。例如,避免眼神交流,看起来很困惑,双眉低垂是他们仍然不同意你的危险信号。当这种情况发生时,承认他们,直到他们愿意听你说什么。安排一次后续会议来了解他们的进展情况是非常重要的。
不及物动词说“我不知道”没关系
首先,寻求帮助并不可耻。有时,我们不知道答案,因为在给出解决方案之前,我们需要时间进行进一步的调查。你不需要觉得自己一直都知道所有的事情。事实上,鼓励数据科学家提出问题。通过提问,你提供了一个不同的视角,也许你不是唯一一个迷路的人。说“我不知道”比当我们不知道的时候假设我们理解了问题,并提供一个错误的答案要好。没有愚蠢的问题,但如果有人已经多次告诉你答案,你可能应该在再次问同样的问题之前思考一下。
最后的想法
有效的沟通是成为一名优秀数据科学家的最重要技能之一。发展这项技能需要时间、努力和练习。以上我通过有效培训解决方案(ETS) 培训学到的技巧帮助我提高了沟通技巧,我真的希望你也能开始看到成效:)
如何轻松比较两个数据帧
原文:https://towardsdatascience.com/how-to-compare-2-dataframes-easily-b8f6788d5f07?source=collection_archive---------18-----------------------
…使用全面的数据协调脚本。
由 Abel Y Costa 在 Unsplash 上拍摄的照片
4 年前,我参与了一个数据迁移项目,是一家全球金融机构业务部门的一员。业务部门需要在 4 小时内完成对账,并为项目上线提供签准。在这个项目之前,我已经开始涉猎 python,当时只听说过pandas
库。
这项任务听起来很简单:
确保所有记录都正确迁移。
但是和所有任务一样,通常有一个if
语句和一个跟随其后的子句。
如果有任何记录不匹配,则生成这些记录的报告。
业务部门提出的最初想法是使用 Excel 和宏来执行这种调节。但是我理解这种复杂性,并认为 Excel 可能不适合这样的任务。经过一些努力,我让各种利益相关者相信我可以足够快地掌握 python 来完成这项任务。
快进 2 个月,经过几次彩排,我的剧本终于准备好了。在源数据和目标数据之间有一些转换逻辑,但是为了本文的目的,我将展示脚本如何在经过转换的源数据和目标数据之间进行比较。
点击此处直接跳转到脚本。
一些假设
设df1
和df2
分别为源和目标数据帧。现在,让我们假设它们具有相同数量的列,并且这些列成对地具有相同的数据类型(即df1
中的列 1 与df2
中的列 1 具有相同的数据类型,…)。还假设进行比较的列存储在uid
变量中。
在文章的最后,我将简要讨论在执行主要的比较脚本之前,为确保数据足够干净而需要采取的额外步骤/检查。
1.记录迁移正确
对所有列执行内部合并,得到的数据帧将是所有记录都匹配的数据帧。注意,uid
无关紧要,因为合并是在所有列上完成的。
df_merge = pd.merge(df1, df2, how='inner', on=df1.columns.tolist())
2.记录在源中,但不在目标中
经常会有一些不确定的记录永远不会被迁移,也就是说,它们在源中,但不在目标中。
有几种方法可以识别这些记录,这里有一种:
- 将
df_merge
追加回df1
, - 标记重复的行;使用
keep=False
将所有重复标记为True
, - 选择不重复的行。
df1_only = df1.append(df_merge).reset_index(drop=True)
df1_only['Duplicated'] = df1_only.duplicated(keep=False)
df1_only = df1_only[~df1_only['Duplicated']]
3。记录在目标中,但不在源中
可能有记录在迁移过程中神秘地创建,可能是由于一些转换错误或人工干预。
以类似的精神,人们可以识别出这些在目标中而不在源中。
df2_only = df2.append(df_merge).reset_index(drop=True)
df2_only['Duplicated'] = df2_only.duplicated(keep=False)
df2_only = df2_only[~df2_only['Duplicated']]
4.源和目标中的记录,但具有不同的值
现在假设有 2 个数据帧,每个数据帧有一条记录:
df1 = pd.DataFrame([['Apple',1]], columns=['Fruit', 'Qty'])
df2 = pd.DataFrame([['Apple',2]], columns=['Fruit', 'Qty'])
通过观察,df_merge
将是空的,并且这些数据帧也将分别等同于df1_only
和df2_only
。
创建一个新的数据帧来显示Apple
同时出现在df1
和df2
中是有意义的,但是它们在Qty
列中有不同的值。
# Label each dataframe
df1_only['S/T'] = 'Source'
df2_only['S/T'] = 'Target'# Identify the duplicated rows
df3 = df1_only.append(df2_only).reset_index(drop=True)
df3['Duplicated'] = df3.duplicated(subset='Fruit', keep=False)# `subset` argument considers only a subset of the columns when identifying duplicated rows.
将此应用于一个不太重要的例子:
>>> cols = ['Fruit', 'Qty']
>>> df1 = pd.DataFrame([['Apple',1],['Orange',3]], columns=cols)
>>> df2 = pd.DataFrame([['Apple',2],['Pear',4]], columns=cols)
...
...
>>> # Note that `df1` is still the same as `df1_only`
>>> # Repeat the step in the above code block to get `df3`
>>> df3
Fruit Qty S/T Duplicated
0 Apple 1 Source True
1 Orange 3 Source False
2 Apple 2 Target True
3 Pear 4 Target False
现在,可以使用Duplicated
栏上的布尔索引来选择:
- 在源和目标中具有相同的
Fruit
值但具有不同的Qty
的记录 - 严格按照来源的记录
- 严格位于目标中的记录
df_diff = df3[df3['Duplicated']]
df1_only = df3[(~df3['Duplicated']) &(df3['S/T']=='Source')]
df2_only = df3[(~df3['Duplicated']) &(df3['S/T']=='Target')]
5.附加步骤/检查
该脚本进行额外的检查,以确保下游代码成功;它检查:
- 两个数据帧都有相同数量的列
- 两个数据帧具有相同的列名集否则打印识别的
orphans
。 - 两个数据帧的列处于相同的顺序(这对于比较并不重要,但是对于一个人来说,检查两个列混杂在一起的数据帧在视觉上是困难的。)
- 两个数据帧中每一列的数据类型都是成对相同的。(如果源列具有
int
数据类型,而对应的目标列具有float
数据类型,这可能意味着存在具有空值的行。) - 根据应用比较的列检查记录的唯一性。(这应该总是 100%,否则应该在
uid
中包含更多的列来进行比较。)
6.使用脚本
使用该脚本非常简单,只需传递 3 个位置参数:
df_left
和df_right
是指你输入的数据帧uid
指组成唯一键的单个列(str)或一列列。(即Fruits
)
也可以传递两个可选的关键字参数:
labels
(默认= (Left
,Right
))允许您将输入的数据帧命名为Source
&Target
。标签构成了输出有序字典的关键字。drop
(默认值= [[],[]])可以接受要从比较中排除的列的列表。
def diff_func(df_left, df_right, uid, labels=('Left','Right'), drop=[[],[]])
...
...
基于我们迄今为止的例子:
>>> df1 = pd.DataFrame([['Apple',1],['Orange',3],['Banana',5]], columns=['Fruit','Qty'])
>>> df2 = pd.DataFrame([['Apple',2],['Pear',4],['Banana',5]], columns=['Fruit','Qty'])
>>> d1 = diff_func(df1, df2, 'Fruit')
输出d1
将是具有 6 个数据帧的有序字典:
>>> d1['Left']
Fruit Qty
0 Apple 1
1 Orange 3
2 Banana 5
>>> d1['Right']
Fruit Qty
0 Apple 2
1 Pear 4
2 Banana 5
>>> d1['Merge']
Fruit Qty
0 Banana 5
>>> d1['Left_only']
Fruit Qty
1 Orange 3
>>> d1['Right_only']
Fruit Qty
3 Pear 4
>>> d1['Diff']
Left or Right Fruit Qty
0 Left Apple 1
1 Right Apple 2
结论
虽然创建这样一个脚本的最初目的仅仅是为了协调一组特定的迁移数据,但是我认识到,如果可以将其一般化,它可以用于比较任意两个数据帧。因此,我决定编写一个通用函数,它按顺序进行一系列检查,然后比较数据帧,最后在包含 6 个数据帧的字典中输出结果。
这不是在 stackoverflow 上吗?
有趣的是,虽然 stackoverflow 上有许多比较两个数据框架的答案,但没有一个答案是我真正想要的。它很少是完整的,也没有我正在寻找的检查。随后,我在 stackoverflow 上发布了这个答案——这也是我的第一个答案——到目前为止收到了 3 次投票。
Pandas merge 有一个关键字参数“indicator=True ”,它指示记录是存在于左侧、右侧还是两个表中。
indicator=True
指示记录是存在于两个表中还是只存在于其中一个表中。然而,当替换表不包含比较的键时,具有整数值的列被转换成float
,这里有一个例子。
>>> import pandas as pd
>>> df1 = pd.DataFrame([['Apple',1],['Orange',3],['Banana',5]], columns=['Fruit','Qty'])
>>> df2 = pd.DataFrame([['Apple',2],['Pear',4],['Banana',5]], columns=['Fruit','Qty'])
>>> df3 = pd.merge(df1, df2, on='Fruit', how='outer', indicator=True)
>>> df3
Fruit Qty_x Qty_y _merge
0 Apple 1.0 2.0 both
1 Orange 3.0 NaN left_only
2 Banana 5.0 5.0 both
3 Pear NaN 4.0 right_only
在df3
中,我们可以很容易地看到Orange
只存在于左边的表格中。然而,Qty_x
列不再是一个具有int
数据类型的序列对象,而是一个float64
数据类型。这可能会造成混乱,因此我决定不使用这种方法。
既然已经对词典进行了排序,为什么还要使用 OrderedDict?
这个脚本最初是在 python 字典还是无序的时候编写的,因此我使用了有序字典。我怀疑如果我切换到一个普通的字典,性能会有显著的提高,因此我决定保留它,为了怀旧,并确保它对那些使用旧版本 python 的人是兼容的。
完整代码如下:
数据团队的事件管理
原文:https://towardsdatascience.com/how-to-conduct-incident-management-on-your-data-pipelines-2dfc20b1b0b7?source=collection_archive---------20-----------------------
大规模识别、找出根本原因并解决数据质量问题的 4 个步骤
图片由巴尔·摩西提供。
随着数据系统变得越来越分散,公司接收越来越多的数据,出错(和事故)的机会只会增加。几十年来,软件工程团队一直依靠多步骤流程来识别、筛选、解决和防止问题影响他们的应用程序。
随着数据操作的成熟,是时候我们以同样的勤奋对待 数据停机 了,换句话说,就是数据丢失、不准确或其他错误的时间段,特别是在构建更可靠、更有弹性的数据管道时。
虽然关于数据团队如何处理其数据的事件管理的文献并不多,但我们已经从软件开发的朋友那里获得了大量资源。经过一些调整,这些技巧已经成为一些最好的数据工程团队的无价工具。
当涉及到为您的管道构建数据事件管理工作流时,4 个关键步骤包括:事件检测、响应、、根本原因分析(RCA) 、、&解决方案,以及无可指责的事后分析。
在本文中,我们将介绍这些步骤,并分享数据团队在制定自己的事故管理策略时可以使用的相关资源。
事件检测
将自动数据质量监控集成到您的关键工作流中是您的事件管理流程成功的基础,并允许您的团队指定谁在调查问题及其状态(即待定、调查、已解决)。图片由巴尔·摩西提供。
不言而喻,在数据进入生产之前,您首先应该 测试数据 。尽管如此,即使有了最强大的测试和检查,在您说“数据管道损坏”之前,坏数据还是会从裂缝中掉出来,并被推到戳中。
当数据宕机发生时,第一步是事件检测。可以通过 数据监控和警报 来检测事件,这既可以在您的数据管道上手动实施,也可以基于特定阈值触发,或者作为 数据可观察性 解决方案的一部分分层实施,并基于历史数据模式和自定义规则定期自动触发。
数据监控的一个关键组件是 异常检测 ,即识别数据健康支柱(即,容量、新鲜度、模式和分布)何时偏离正常的能力。异常检测在端到端(跨您的仓库、湖泊、ETL 和 BI 工具)实施时最有价值,而不是仅在您的数据生态系统的特定孤岛中实施。良好的异常检测还将调整算法以减少白噪声和误报。
事件检测可以集成到数据工程和分析工作流中,确保在通过适当的通信渠道(Slack、电子邮件、SMS、信鸽等)出现问题时,所有数据利益相关方和最终用户都能收到通知
建议的资源:
- devo PS 时代的事件管理& SRE (达蒙·爱德华兹,InfoQ)
- 管理突发事件 (《谷歌 SRE 手册》Andrew Stribblehill)
- https://tech.affirm.com/metrics-monitoring-and-alerting-90c9e8b60956(Elaine Arbaugh,Affirm Tech Blog)
反应
作为一名事故指挥官,能够专注于数据质量问题可以更容易地了解数据管道中的问题。图片由巴尔·摩西提供。
良好的事件响应始于——也止于——有效的沟通,幸运的是,大部分事件响应可以提前准备好,并在适当的时候通过 PagerDuty 和 Slack 通过适当的工作流程自动完成。
数据团队应该花时间创建运行手册和行动手册,以完成标准事件响应。操作手册为您提供了如何使用不同服务以及遇到的常见问题的说明,而行动手册则提供了处理事件的分步流程。两者都应该提供代码、文档和其他材料的链接,这些链接可以帮助团队理解当关键管道破裂时该做什么。
一本好的操作手册的一个重要部分?发生停机或故障时委派角色。
在传统的现场可靠性工程项目中,一种随叫随到的过程,根据服务委派特定的角色,通常按小时、天或周进行分段。除了“事件响应者”,通常还有一名“ ”事件指挥官 ”,负责在响应者和其他利益相关者解决问题时分配任务和综合信息。
事故指挥官还负责与可能受影响的上游和下游消费者进行沟通,即那些使用由破裂管道提供动力的数据产品的消费者。
端到端沿袭是一种有价值的工具,用于在数据管道中断时了解上游和下游的依赖性,以便在坏数据影响业务之前通知相关方。图片由巴尔·摩西提供。
对于业务上下文, 元数据是一个强大的工具 ,用于了解哪些团队受到给定数据停机事件的影响;再加上自动化的、端到端的沿袭,沟通这些受影响的资产之间的上游和下游关系可以是一个无痛且快速的过程,节省了团队手工绘图的时间。
一旦发生数据宕机,就必须将其影响传达给上游和下游用户,包括处理数据的用户和使用数据的用户。通过正确的方法,可以使用 PagerDuty、Slack 和其他通信工具将其中的大部分内容融入到自动化工作流中。
建议的资源:
- 如何用 Gitlab (GitLab 文档)创建 Runbooks
- 比较 IT 流程文档的操作手册和行动手册(Stephen j . Bigelow, TechTarget****
- 使开发人员能够进行操作 (Francesco Negri,Buildo)
根本原因分析和解决方案
了解哪些数据源会导致数据管道中断,这对根本原因分析至关重要。图片由巴尔·摩西提供。
理论上,根本原因听起来就像运行几个 SQL 查询来分割数据一样简单,但在实践中,这个过程可能相当具有挑战性。事件可能以不明显的方式出现在整个管道中,并影响多个(有时是数百个)表。
例如,数据质量差的一个常见原因是新鲜度,即当数据异常过时时。这种事件可能是由多种原因造成的,包括作业卡在队列中、超时、合作伙伴未及时提供其数据集、错误或意外的计划更改从 DAG 中删除了作业。
根据我们的经验,我们发现大多数数据问题都可以归因于以下一个或多个事件:
- 输入作业、管道或系统的数据发生意外变化
- 逻辑的变化 (ETL、SQL、Spark 作业等。)转换数据
- 运营问题,如运行时错误、许可问题、基础设施故障、日程变更等。
快速确定手头的问题不仅需要适当的工具,还需要考虑这三个来源如何以及为什么会中断的整体方法。
随着软件(和数据)系统变得越来越复杂,查明停机或事故的确切原因(或根源)变得越来越困难。亚马逊的“五个为什么”方法提供了一个有用的框架,通过这个框架,我们可以了解 RCA:
- 找出问题所在
- 询问问题发生的原因,并记录原因
- 确定原因是否是根本原因
- 原因是否可以避免?
- 原因有没有可能在事情发生之前就被检测出来?
- 如果原因是人为失误,为什么可能呢?
- 将原因作为问题,重复该过程。当你确信你已经找到了根本原因时,就停下来。
你的系统崩溃的原因很少是单一的。随着数据工程师努力通过更智能的流程、测试、数据新鲜度检查和其他解决方案来减少人工劳动,他们应该能够在问题浮出水面之前发现问题。当他们不这样做时,这是一个强烈的迹象,表明这些故障保险是不够的。正如在软件工程领域一样,自动化解决方案,如数据可观察性和端到端监控,通常是对抗数据宕机的最佳选择。
首先,我们确定了数据团队在对其数据管道进行 RCA 时必须采取的四个步骤:
- 看看你的血统:要了解什么出了问题,你需要找到系统中出现问题的最上游节点——那是事情开始的地方,也是答案所在。如果你幸运的话,万恶之源出现在有问题的仪表板上,你会很快发现问题。
- 查看代码:查看创建该表的逻辑,甚至是影响事件的特定字段,将有助于您对问题所在提出合理的假设。
- 查看您的数据:在第 1 步和第 2 步之后,是时候更仔细地查看表格中的数据,寻找可能出错的地方。这里有一种很有前途的方法,那就是研究表中有异常记录的其他字段如何提供线索,说明数据异常发生在哪里。
- 看看您的操作环境:许多数据问题是运行您的 ETL/ELT 作业的操作环境的直接结果。查看 ETL 引擎的日志和错误跟踪可以找到一些答案。
(如果你还没有读过,可以看看 Francisco Alberini 的文章关于数据工程师如何进行根本原因分析,非常值得一读)。
一旦您发现出了问题,了解了其影响,确定了根本原因,并与适当的利益相关者沟通了后续步骤,就该解决问题了。这可能与暂停数据管道或模型并重新运行它们一样简单,但是由于数据可能由于数百万种原因而中断,这通常涉及大量的故障排除。
建议的资源:
- 根本原因分析,用例子和方法解释 (Tableau)
- 工业 4.0 时代的根本原因分析 (Lior Kitain,数据驱动投资人)**
- https://thenewstack.io/field-guide-for-production-readiness/(伊恩·史密斯,新栈)********
无可指责的验尸
无可指责的事后分析通常以对问题的深入分析和明确的后续步骤结束,以防止类似事件影响未来的管道。图片来自 万花筒 上un splash。**
我的一个朋友是一名现场可靠性工程师,在 Box、Slack 和其他硅谷公司有十多年的灭火经验,他告诉我,如果不把这一点说得非常清楚,我就不能写一篇关于事故管理的文章:
“对于每一个事件,都是系统出了问题,而不是编写代码的人。好的系统是为容错和人类宽容而构建的。允许你犯错是系统的职责。”
当谈到数据可靠性和数据运营时,同样的精神听起来是真实的。管道应该是容错的,有适当的流程和框架来考虑数据管道中的 已知未知和 未知。
无论发生了何种类型的事故或事故原因是什么,数据工程团队都应该在解决问题并进行根本原因分析后,进行全面的跨职能事后分析。
以下是一些最佳实践:
- 把一切都框定为一次学习经历:为了有建设性,验尸报告必须是无可指责的(如果不是,那么知道指责)。试图对事件进行“指责”是很自然的,但在向你的同事灌输信任或培养合作文化时,这很少有帮助。通过围绕“学习和改进”的目标重新构建这种体验,更容易主动采取解决数据质量所必需的组织(创建更好的工作流和流程)和技术步骤(为投资新工具提供理由)。
- 以此为契机,评估您对未来事件的准备情况:更新操作手册,调整您的监控、警报和工作流管理工具。随着您的数据生态系统的发展(添加新的第三方数据源、API,甚至消费者),这一步在事件预防方面将变得至关重要。
- 记录每一次事后分析,并与更广泛的数据团队分享:就像在软件工程中一样,记录哪里出错了,系统是如何受到影响的,以及根本原因是什么,这些通常是事后才想到的。但是,文档记录与事件管理流程中的任何其他步骤一样重要,因为它可以防止在拥有部落知识的工程师离开团队或无法提供帮助时出现知识缺口。
- 重温 SLA:在之前的一篇文章中,我讲述了为什么数据团队需要为他们的数据管道设置 SLA。简而言之,服务水平协议(SLA)是许多公司用来定义和衡量给定供应商、产品或内部团队将提供的服务水平的一种方法,以及在失败时的潜在补救措施。随着数据系统的成熟或随着时间的推移而变化,不断地重新审视您的SLA、服务级别指标( SLIs )和服务级别目标( SLOs )非常重要。六个月前有意义的 SLA 可能不再有意义;你的团队应该是第一个知道这些变化并与下游消费者沟通的人。****
说到底,事后检讨对于数据团队和软件工程师一样重要。随着我们领域的不断发展(毕竟,我们正处于数据时代),了解数据停机是如何发生的以及为什么会发生是我们不断提高系统和流程弹性的唯一途径。
建议的资源
- 在谷歌 进行无可指责的剖验(约翰·伦尼&苏·吕德,谷歌 SRE 手册)
- 无可指责的殉教者和一个正义的文化 (约翰·奥尔斯伯,代号为手艺)
- 死后模板 (Pavlos Ratis,GitHub)
引用我们 SRE 前辈的话: 希望不是战略 。
但是,有了这些最佳实践,您就可以将事件管理从“四处探索并希望有最好的结果”变成一台运转良好、高度可靠的机器。
有兴趣了解更多关于 Vimeo ,Eventbrite, Compass 以及其他领先公司 如何利用数据可观察性大规模防止管道破裂?
伸出手去 巴尔摩西*蒙特卡洛团队的其他人。T38*
如何配置 Julia 包
原文:https://towardsdatascience.com/how-to-configure-julia-packages-93a26e28ea76?source=collection_archive---------56-----------------------
朱莉娅综合教程
深入了解 Julia 中的配置和类型
(图片由作者提供)
本文视频:
我们项目的存储库:
https://github.com/ChifiSource/SuperFrames.jl
介绍
在之前的“Julia 综合教程”中,我们介绍了在 Julia 编程语言中使用 Project.toml 文件和虚拟环境的基础知识。如果您还没有阅读或观看这个系列教程的迭代,如果您感兴趣,可以在这里查看:
Project.toml 文件是描述任何 Julia 项目的宝贵资产。这个文件不仅包括项目需要的所有依赖项,还包括那些包的兼容版本,以及关于包的元信息。虽然 Project.toml 的大部分可以通过创建新的虚拟环境来机械地生成,但是配置的某些部分必须手动完成。
配置我们项目文件的其余部分
完成这个项目设置的第一步是完成我们的 Project.toml 文件的配置。首先,我们应该看看我们的武器库中的一些配置选项,比如“名称”、“版本”和“UUID”这是我们完成的 Project.toml 文件,它将使解释其中每个资产为 Julia 的包管理器做什么变得容易得多。
authors = ["emmett [emmett@emmettboudreau.com](mailto:emmett@emmettboudreau.com)"]
name = "SuperFrames"
uuid = "19a2823e-5050-11eb-208c-916d674a0ad5"
[deps]
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
[compat]
julia = "1.5"
DataFrames = "0.22.1"
作者
“作者”是一个不言自明的领域;这些是参与这个项目的人。当然,在这里我们看到我和我的电子邮件在一个字符串中,这个字符串是用 Lisp 风格的列表编写的。也就是说,应该在包含 Lisp 风格列表字符串的 Julia 风格数组中提供额外的条目。
名字
名称是我们包装最重要的属性之一。这将是最终用户调用和使用软件包的方式,因此这当然非常重要。虽然“using”调用可能会使用模块名,但是您的模块名使用与您的 Pkg 名相同的名称可能是明智的,因为否则人们甚至会很难弄清楚如何导入您的包!也就是说,这个文件中描述的名字将被 Julia 注册中心用来识别你的包的名字。
uuid
UUID (Universal Unique Identifier,通用唯一标识符)是字母和数字的组合,用于抽象地表示任何东西,但在涉及到包时有明确的用途。UUIDs 允许包管理器 Pkg 跟踪几个包,可能有相同的名字,有时来自完全不同的注册中心,并允许它们一起工作。
我们需要的 Julian 包的 UUID 类型可以使用 UUIDs.jl 包获得。我们可以通过以下方式导入模块
using UUIDs
既然模块已经导入,现在有一个名为
uuid1()
这需要一个位置参数。一个随机数发生器。通常在这些情况下,随机数生成器是一种接受种子并基于该种子返回随机数的类型。默认情况下,该参数使用全局随机数生成器,该生成器将使用编译器在编译时提供的种子。
考虑到这一点,我们真的不需要种子,所以我只是像这样传递方法:
uuid = uuid1()
然后将生成的 UUID 记录到我们的 Project.toml 文件中。
[deps]
DataFrames 是我们在[deps]部分中唯一的依赖项。该键的对应值是 DataFrames.jl 包的 UUID。这当然会在我们创建虚拟环境时自动添加到我们的 Project.toml 文件中。
[兼容]
compat 部分用来告诉 Julia 的包管理器这个项目要处理哪些版本的依赖项。对于一般的 Julia 应用程序,让 Julia 兼容性至少为 1.0 或更高可能是个好主意。对于今天的产品包,我将把 Julia 的兼容性设置为 1.5,因为我使用的是 1.5.2,我将把 DataFrames 的兼容性设置为 DataFrames 的最新版本:
[compat]
julia = "1.5"
DataFrames = "0.22.1"
基本模块扩展
正如我们在讨论显式导入时所讨论的,我们将需要显式导入任何我们想要从中扩展方法或类型的包。虽然我们可能不会扩展 DataFrame 类型的功能,但是只要我们利用了 DataFrames.jl 包的类型层次结构,我们就可以在 DataFrame 上使用 DataFrames.jl 提供的方法。
类型层次结构只是一种类型在一系列类别上的分类。当某些类型可以用某些方式处理时,这就很方便了,因为它们有共同的属性,但有时它们没有。对于本例,由于 DataFrames.jl 包中的大多数方法都使用“AbstractDataFrame”类型,我们将直接导入它并创建一个新类型,它将继承它的所有方法。首先,让我们导入构建我们自己的相似类型 AbstractDataFrame 和 Index 所需的两种类型。
import DataFrames: AbstractDataFrame
import DataFrames: Index
我们今天要做的最后一件事是创建一个新类型,它将继承已经赋予抽象类型 AbstractDataFrame 的所有属性。我们使用<:/>
结论
虽然 Julia 的 Pkg 包管理器在开发包时可能需要做一些工作来启动和运行,但一旦包发布并感受到好处,这肯定是值得的。虽然在这一版的 Julia 教程中没有太多的编程,但将来肯定会有更多的计划深入算法和 Julian 编程。我期待着展示这种语言在类型和方法方面的更多功能!感谢您的阅读!
如何将本地或远程机器连接到 Databricks 集群
原文:https://towardsdatascience.com/how-to-connect-a-local-or-remote-machine-to-a-databricks-cluster-18e03afb53c6?source=collection_archive---------11-----------------------
业内笔记
Databricks、Python 和 Docker 的交集
粘土银行在 Unsplash 拍摄的照片
当您开始使用 Databricks 时,您将会决定在 Databricks 之外进行编码,并远程连接到它的计算能力,也就是 Databricks 集群。为什么?主要是因为 Databricks 的主要特性之一是它的 Spark 作业管理,这可以让您的生活变得轻松。使用该服务,您可以向大规模数据集提交一系列 Spark 作业,并在几秒钟内返回您的结果;多亏了它的火花引擎。在本文中,我想描述如何配置您的本地或远程机器连接到 Databricks 集群,作为这个过程的第一步。
https://www.amazon.com/gp/product/B08D2M2KV1/ref=dbs_a_def_rwt_hsch_vapi_tkin_p1_i0
—什么是数据块?
Databricks 是一个抽象层,位于 AWS 和 Azure 等冷云基础设施上,使您可以轻松管理计算能力、数据存储、作业调度和模型管理。它为您提供了一个开发环境,以获得您的数据科学或人工智能项目的初步结果。Databricks 由 Spark 提供支持,Spark 是一个开源数据处理引擎,专门为大规模数据设计。
Databricks 提供的简单性有一些限制。例如,Databricks 使您作为数据科学新手能够快速生成结果,因为您不需要大量处理云配置或可视化工具。然而,如果您想要控制开发的每个方面,Databricks 肯定会限制您。
—要求是什么?
1-使用受支持的数据块运行时创建数据块集群
每个 Databricks 集群都必须运行一个称为 Databricks 运行时的专用操作系统。在配置集群时,您会发现许多版本的 Databricks 运行时。如果您想要远程连接到 Databricks 集群,您必须谨慎选择 Databricks 运行时版本。为什么?因为databricks-connect
客户端支持有限数量的数据块运行时版本,所以 Spark 客户端库支持这种远程连接。
数据块运行时版本必须与数据块连接库兼容。
换句话说,您不能远程连接到其数据块运行时不受databricks-connect
支持的集群。您可以在 Databricks Connect 的原始文档中找到 Databricks 运行时版本的更新列表。
https://docs.databricks.com/dev-tools/databricks-connect.html#requirements
2-安装所需的 Python 和 Java 版本
选择与databricks-connect
兼容的 Databricks 运行时版本后,您必须确保在您的机器上使用兼容的 Python 版本。如原始文档中所述:“客户机 Python 安装的次要版本必须与 Databricks 集群的次要 Python 版本相同。”
开发环境的 Python 版本必须与在 Databricks 集群上工作的 Databricks 运行时版本兼容。
假设您为 Databricks 运行时版本选择了 7.3 LTS 。在这种情况下,您必须在本地或远程机器上安装 Python 3.7 才能与之兼容。您还必须在您的机器上安装 Java 运行时环境(JRE) 8。这些都是由 Databricks 网站指导的。
3-安装所需的 Databricks Connect 版本
正如 Python 开发所建议的,最好创建一个隔离的虚拟环境,以确保没有冲突。你可以用你选择的库,如venv
、pipenv
或conda
,轻松构建一个虚拟环境。我在这里选了最新的。
如果不想创建新的虚拟环境,确保不要在现有环境上安装(或卸载)pyspark
。您应该卸载现有版本的pyspark
,因为它与databricks-connect
客户端冲突。databricks-connect
有自己的方法,相当于pyspark
的方法,这使得它可以独立运行。通过下面的代码,您用 Python 3.7 和一个版本的databricks-connect
创建了一个虚拟环境。
conda create --name ENVNAME python=3.7
conda activate ENVNAME
pip3 uninstall pyspark
pip3 install -U databricks-connect==7.3.*
你可能不需要上面的pip3 uninstall pyspark
,因为虚拟环境是干净的。我把它放在那里只是为了完整。
—如何根据需求创建 Docker 映像
如果您想用 Python 3.7 和 Java 8 以及一个版本的databricks-connect
构建 docker 映像,您可以使用下面的 docker 文件。
FROM ubuntu:20.04RUN apt-get update && apt-get -y install sudo
RUN sudo apt-get -y install software-properties-common### INSTALL PYTHON
RUN sudo apt-get -y install libssl-dev openssl
RUN sudo apt-get -y install libreadline-gplv2-dev libffi-dev
RUN sudo apt-get -y install libncursesw5-dev libsqlite3-dev
RUN sudo apt-get -y install tk-dev libgdbm-dev libc6-dev libbz2-dev
RUN sudo apt-get -y install wget
RUN apt-get update && apt-get install make
RUN sudo apt-get -y install zlib1g-dev
RUN apt-get -y install gcc mono-mcs && \
rm -rf /var/lib/apt/lists/*
RUN wget [https://www.python.org/ftp/python/3.7.10/Python-3.7.10.tgz](https://www.python.org/ftp/python/3.7.10/Python-3.7.10.tgz)
RUN tar xzvf Python-3.7.10.tgz
RUN ./Python-3.7.10/configure
RUN sudo make install
RUN alias python=python3### INSTALL JAVA
RUN sudo add-apt-repository ppa:openjdk-r/ppa
RUN sudo apt-get install -y openjdk-8-jre### INSTALL DATABRICKS-CONNECT
RUN pip3 install --upgrade pip
RUN pip3 uninstall pyspark
RUN pip3 install -U databricks-connect==7.3.*
—如何配置连接属性?
使用databricks-connect configure
,很容易配置databricks-connect
库以连接到 Databricks 集群。运行此命令后,它会以交互方式询问您有关主机、令牌、组织 ID、端口和集群 Id 的问题。要了解更多信息,您可以查看下面的官方文档。
https://docs.databricks.com/dev-tools/databricks-connect.html#step-2-configure-connection-properties
然而,如果您想自动配置 Docker 映像中的连接属性,您可以将以下代码添加到上述 Docker 文件的末尾。
RUN export DATABRICKS_HOST=XXXXX && \
export DATABRICKS_API_TOKEN=XXXXX && \
export DATABRICKS_ORG_ID=XXXXX && \
export DATABRICKS_PORT=XXXXX && \
export DATABRICKS_CLUSTER_ID=XXXXX && \
echo "{\"host\": \"${*DATABRICKS_HOST*}\",\"token\": \"${*DATABRICKS_API_TOKEN*}\",\"cluster_id\":\"${*DATABRICKS_CLUSTER_ID*}\",\"org_id\": \"${*DATABRICKS_ORG_ID*}\", \"port\": \"${*DATABRICKS_PORT*}\" }" >> /root/.databricks-connectENV *SPARK_HOME*=/usr/local/lib/python3.7/site-packages/pyspark
上面的代码人工创建了配置文件,并将其保存在适当的地址。此外,它将SPARK_HOME
地址设置为正确的值。当您运行databricks-connect configure
时,这些步骤在没有您参与的情况下被执行。当您想要自动配置连接属性时,您应该这样做。
最后,但同样重要的是,您可以通过运行databricks-connect test
来检查连接的健康状况。
感谢阅读!
如果你喜欢这个帖子,想支持我…
- 跟我上 中 !
- 在 亚马逊 上查看我的书!
- 成为 中的一员 !
- 连接上Linkedin!
- 关注我 推特 !
https://pedram-ataee.medium.com/membership
如何从 Mac 将本地 R 项目连接到 GitHub
原文:https://towardsdatascience.com/how-to-connect-a-local-r-project-to-github-from-a-mac-4f183d57477e?source=collection_archive---------37-----------------------
带截图的逐步指南
照片由来自佩克斯的克里斯蒂娜·莫里洛拍摄
在创建一个新的 R 项目时,设置一个 GitHub 连接是相当简单的。然而,有时您最终会得到一个只存储在本地的回购协议。也许你从一个不使用 GitHub 的人那里接受了一个项目,或者也许你今天不在状态,只是忘了从 GitHub 连接开始。
无论哪种方式,您都可以轻松地将这个 repo 复制到 GitHub 中并建立连接。这个循序渐进的指南会告诉你怎么做。
1.下载 GitHub for Mac 应用程序
首先,前往 GitHub for Mac 的网页:【http://mac.github.com/
您应该会看到以下屏幕:
点按屏幕中间的紫色“macOS 下载”按钮。zip 文件应该立即开始下载。下载完成后,双击 zip 文件。GitHub 桌面应该出现在您的下载文件夹中,如下所示:
将 GitHub Desktop 从下载文件夹拖到“应用程序”中,该文件夹在下方左侧突出显示。您应该会看到一个紫色的 GitHub 桌面图标出现(见右下角):
2.打开 GitHub 桌面并建立连接
双击 GitHub 桌面图标。您可能会收到一条警告,指出“GitHub Desktop”是一个从互联网下载的应用程序,并询问您是否要打开它。如果您看到此警告,请选择“打开”:
GitHub 桌面打开后,选择“添加现有存储库”如果这是你第一次打开 GitHub 桌面,你的屏幕看起来可能会有些不同,但是仍然应该有一个“添加现有库”选项。
应该会出现以下窗口。单击“选择…”按钮并导航到包含您的 R 项目的文件夹。
一旦您选择了包含您的本地项目的文件,您将会得到下面的通知:“这个目录似乎不是一个 Git 存储库。是否要在这里创建一个存储库?”单击蓝色的“创建存储库”文本。
应该会出现以下窗口。只需点击右下角的“创建存储库”按钮。
出现以下屏幕时,单击“发布存储库”
将弹出以下窗口,您可以简单地单击“发布存储库”如果您希望公开您的回购协议,您可以取消选中“将此代码保密”复选框
根据项目的大小,发布可能需要几分钟时间。一旦项目被推送到 GitHub,你就应该一切就绪了!
3.验证连接是否成功
您可以通过登录 GitHub 帐户并验证您是否在“Repositories”下看到新的 repo 来确保连接成功建立。
此外,当您的项目在 RStudio 中打开时,您现在应该会看到“Git”选项卡,您可以在其中推送和获取任何更新。
就是这样!通常,在创建 R 项目时,您会希望坚持使用创建 GitHub repo 的标准工作流程。这样,您将能够充分利用 GitHub 的版本控制功能。您的代码将始终被备份,并且您可以在以后访问您的工作的早期版本。然而,当无法遵循此工作流程时,GitHub Desktop 提供了一种便捷的方式将现有的本地项目连接到 GitHub repo。
如何使用私有端点将 Azure 数据工厂连接到 Azure SQL 数据库
原文:https://towardsdatascience.com/how-to-connect-azure-data-factory-to-an-azure-sql-database-using-a-private-endpoint-3e46984bec5e?source=collection_archive---------10-----------------------
循序渐进的教程
在 Unsplash 上由 Hafidh Satyanto 拍摄的照片
Azure Data Factory (ADF)非常适合从多个来源提取数据,其中最明显的可能是 Azure SQL。然而,Azure SQL 有一个拒绝公共网络访问的安全选项,如果启用,将阻止 ADF 在没有额外步骤的情况下进行连接。
在本文中,我们将了解设置私有端点并使用它从 Azure Data Factory 连接到 Azure SQL 数据库所需的步骤。
Azure SQL 中的“拒绝公共网络访问”设置
在我们开始之前,让我们回顾一下我在 Azure SQL 中所指的设置。这是一个名为拒绝公共网络访问的开关,位于 Azure 门户网站的安全>防火墙和虚拟网络下。
来源:作者
启用此设置时,如果没有私有端点,Azure Data Factory 将不会连接。你可以看到在 toggle 控件下面甚至有一个创建私有端点的链接,但是现在不要使用它——我们马上会从 Azure Data Factory 创建请求。
ADF 集成运行时
要在 Azure Data Factory 中使用私有端点,必须使用启用了虚拟网络配置的集成运行时。该设置不能更改,所以如果您还没有启用它的运行时,您需要创建一个新的运行时。
来源:作者
来源:作者
现在您已经有了一个启用了虚拟网络配置的集成运行时,您已经准备好创建一个新的链接服务了。
ADF 链接服务
仍在 Azure Data Factory 中时,单击以创建新的链接服务。
来源:作者
当您选择启用虚拟网络配置的集成运行时,一个受管理私有端点设置将出现在帐户选择方法部分。该设置是只读的,将在您输入订阅和服务器详细信息时填充。如果受管私有端点已经可用,您就可以开始了!
如果受管理的私有端点不可用,请单击创建新的链接按钮开始该过程。
来源:作者
当您在 Azure Data Factory 中保存新的托管私有端点时,它将在 Azure 中被提供,但在获得批准之前将保持在挂起状态。
Azure 私有端点
我们跳回 Azure 来批准新的私有端点。在 Azure 门户中找到你的 Azure SQL 数据库,并浏览到安全>私有端点连接。
您应该会看到由 Azure Data Factory 创建的连接,状态为 Pending 。选中其复选框,点击批准按钮。
来源:作者
在 Azure 门户中,状态将变为已批准。状态到达 Azure 数据工厂需要一两分钟,但是过一会儿它也会显示为已批准。
来源:作者
一旦显示为批准,您就可以开始了。您可以输入其余的连接信息并连接!
概述
我展示的大多数设置都可以通过几种不同的方式访问,并以不同的顺序执行。例如,您可以从 Azure 门户创建私有端点,而不是通过 Azure 数据工厂。很明显,你可以尝试并找到适合你的方法。
重要的部分如下:
- Azure Data Factory 有一个支持虚拟网络配置的集成运行时
- Azure SQL 具有批准的私有端点连接。
- Azure Data Factory 有一个使用集成运行时和私有端点连接的链接服务。
就这样,现在去享受你的新连接吧!
如何将数据块连接到 Azure 数据湖
原文:https://towardsdatascience.com/how-to-connect-databricks-to-your-azure-data-lake-ff499f4ca1c?source=collection_archive---------6-----------------------
了解如何将多个 Databricks 工作区连接到 1 个中央 ADLSgen2 客户
1.介绍
TLTR:克隆这个 git 项目 ,设置 params 并运行 0_script.sh 部署 1 个 ALDSgen2 hub 和 N 个 Databricks 辐条
一个数据湖是一个集中的数据存储库,允许企业从数据中创造商业价值。Azure Databricks 是一个分析数据和构建数据管道的流行工具。在这篇博客中,讨论了 Azure Databricks 如何以一种安全和可扩展的方式连接到 ADLSgen2 存储帐户。在这方面,以下是关键:
- 深度防御:ADLSgen2 包含敏感数据,应该使用私有端点和 Azure AD ( 禁用访问密钥)来保护。Databricks 只能使用专用链接和 Azure AD 访问 ADLSgen2
- 访问控制:业务单元通常有他们自己的数据块工作区。应使用基于角色的访问控制(RBAC)授予多个工作区对 ADLSgen2 文件系统的访问权限
- 中心/分支架构:只有一个中心网络可以使用专用链路访问 ADLSgen2 帐户。数据块辐条网络与集线器网络对等,以简化联网
另请参见下图:
1.使用集线器(H)和私有端点(PE)连接到多个数据块(DB)分支的数据湖(DL)——图片来自 Marc de Droog
在这篇博文的剩余部分,将会更详细地解释这个项目。在下一章中,项目将被部署。
2.用 N 个数据块工作空间设置 ADLSgen2
在本博客的剩余部分,使用以下步骤部署项目:
- 2.1 先决条件
- 2.2 通过 hub network 创建 1 个 ADLSgen2 帐户
- 2.3 使用分支网络创建 N 个数据块工作区
- 2.4 使用专用链路连接数据块和 ADLSgen2 帐户
- 2.5 使用数据块装载存储帐户
2.1 先决条件
本教程需要以下资源:
- Azure 账户
- 运行 shell 脚本的 Azure DevOps 或 Ubuntu 终端
- 蔚蓝 CLI
最后,克隆下面的项目或在您的 Azure DevOps 项目中添加存储库。
git clone [https://github.com/rebremer/blog-databrickshubspoke-git](https://github.com/rebremer/blog-databrickshubspoke-git)
该存储库包含 5 个脚本,其中 0_script.sh 触发了完成部署的其他 4 个脚本。它还包含一个 params_template.sh 文件。这个文件中的变量值需要用您的变量替换,并重命名为 params.sh。然后您就可以运行脚本了。这 4 个脚本将在本博客的剩余部分讨论。
2.2 通过 hub network 创建 1 个 ADLSgen2 帐户
在脚本 1_deploy_resources_1_hub.sh 中,将执行以下步骤:
- 创建启用了分层命名空间的 ADLSgen2 帐户。这允许创建文件夹和进行细粒度的访问控制
- 创建一个 VNET,并向存储帐户添加一个专用端点
- 使用专用端点作为区域创建专用 dns 区域
2.3 使用分支网络创建 N 个数据块工作区
在脚本 2_deploy_resources_N_spokes.sh 中,执行以下步骤:
- 创建 N 个数据块工作空间。工作区部署在它们自己的 VNET 中,并且可能部署在不同的订阅中。Databricks 部署的集群只有一个私有 IP 。
- 对于每个数据块工作区,创建一个服务主体。授予服务主体在存储帐户中对其自己的文件系统的访问权限
2.4 使用专用链路连接数据块和 ADLSgen2 帐户
在脚本 3 _ configure _ network _ N _ spokes . sh 中,执行以下步骤:
- 为从 VNET 分支到存储帐户的 VNET 中心的每个数据块创建一个对等关系
- 反之亦然,创建从集线器 VNET 到每个数据块分支 VNET 的对等关系
- 将所有数据块虚拟网络添加到专用 dns 区域,以便存储帐户的专用端点可以在数据块笔记本中使用
2.5 使用数据块装载存储帐户
在脚本 4_mount_storage_N_spokes.sh 中,将执行以下步骤:
- 对于每个 Databricks 工作区,使用 Databricks REST API 将安装笔记本添加到工作区
- 对于每个数据块工作区,将服务主体的凭证存储在数据块支持的机密范围中
- 创建一个集群,并在集群上运行笔记本。Notebook 将从存储帐户获取服务主体凭据,并使用存储的私有端点将其安装到存储帐户中自己的文件系统,另请参见下面的屏幕截图
2.使用专用链接将数据块工作区 I 成功装载到 ADLSgen2 文件系统
3.结论
一个数据湖是一个集中的数据存储库,允许企业从数据中创造商业价值。Azure Databricks 是一个分析数据和构建数据管道的流行工具。在这篇博客中,讨论了如何使用深度防御、Azure AD 访问控制和中心/分支架构将 Azure Databricks 连接到 ADLSgen2 存储帐户,另请参见下图。
3.使用集线器(H)和私有端点(PE)连接到多个数据块(DB)分支的数据湖(DL)——图片由马克·德·德鲁戈提供
如何将 DataGrip 连接到 Apache Druid
原文:https://towardsdatascience.com/how-to-connect-datagrip-to-apache-druid-1a9d502144e9?source=collection_archive---------34-----------------------
使用传统的 SQL 编辑器查询 Apache Druid 的一种简单方法
照片由萨贾德·诺里在 Unsplash 上拍摄
这篇文章最初发表在天秤座人工智能技术博客上。
需要第三方 SQL 客户端编辑器
在过去的几个月里,我第一次在生产环境中部署了一个 Apache Druid 集群。这一过程的经验将有望在未来的故事中被涵盖。在这个故事中,我想分享一种创建能够连接到 Druid 集群并执行 SQL 查询的 DataGrip 驱动程序的方法。
随着越来越多的同事需要在开发阶段访问我们的 Druid 数据源,使用第三方客户端应用程序查询 Druid 成为一种必要。而为了管理用户并最终将非管理员从 Druid 路由器的 UI 中移除,转移到生产环境会使事情变得更糟。
在网上搜索解决方案时,我找不到方便的方法。起初,我认为使用由 pydruid Python 库支持的 Apache Superset 的 SQL lab 可以为我完成这项工作,但这显然是一种过度的做法,因为我不想使用 Superset 的任何其他特性。
我的团队已经使用 Apache 方解石 Avatica 的 JDBC 驱动程序成功地将 Tableau 连接到 Apache Druid。我经常使用 DataGrip 来查询不同的数据库系统,因为它支持大量的数据库系统。因此,我研究了 DataGrip 提供的自定义驱动程序,通过添加 Avatica connector jar 和其他一些驱动程序,我得到了一个可用的驱动程序。这是最好的解决方案,因为它很容易与其他团队成员交流,而且不会让我们使用新工具,花更多的时间来熟悉它。
背景故事讲完了,让我们打开 DataGrip 来创建一个驱动程序和一个数据源,以便查询 Druid。
创建自定义驱动程序
- 导航到文件>新建>驱动程序,打开数据源和驱动程序窗口
- 在新窗口中,将驱动程序的名称字段更改为 Avatica Apache Druid(或任何您想识别的名称)
- 进入驱动文件点击 + 按钮,上传我的 Github repo 的 jars 文件夹中可以找到的所有 jar 文件
- 在类下拉菜单中选择 org.apache .方解石. avatica.remote.Driver
- 添加一个 URL 模板,将其命名为 default ,并将值设置为:
jdbc:avatica:remote:url=http://{host::localhost}:{port::8082}/druid/v2/sql/avatica/
- 转到选项卡选项,在其他部分从下拉菜单中选择通用 SQL
- 申请保存驱动程序
驱动程序配置
使用自定义驱动程序创建新数据源
- 导航到文件>新建>数据源>
- 如果需要,更改主机和端口(默认端口设置为 8082,因为它是代理节点的默认纯文本端口)
- 测试电路
- 应用于保存数据源
数据源创建
我还没有尝试使用 TLS 连接到代理节点,但我认为这不会是一个问题,因为在 Tableau 中使用 Avatica 驱动程序是可能的。
限制
- 这种变通方法的主要缺点是,通过使用通用 SQL 方言,自动完成功能不可用,并且关键字突出显示仅限于经典函数,如 count。目前有一个未解决的问题是关于在 DataGrip 中添加自定义方言的能力。
- 缺少自动限制选项可能会导致查询大量数据,甚至导致历史节点不可用。
结论
在本教程中,我们经历了一个简单的变通方法,使 Apache Druid 集群的数据消费者能够使用 Druid 的 SQL 查询语言执行查询。所有这些都在一个熟悉的工具中进行,这个工具可以作为许多不同数据源类型的客户端, Datagrip 。在这里的评论区或者在项目的 Github 问题中,你可以随意发表你在设置驱动时遇到的任何问题。
如何连接研究人工智能和生产人工智能
原文:https://towardsdatascience.com/how-to-connect-research-ai-to-production-ai-fca5aa4a9d8a?source=collection_archive---------39-----------------------
人工智能
将人工智能研究与制造基于人工智能的产品联系起来
照片由来自 Pexels 的塔拉·温斯泰德拍摄
人工智能在新的科学研究中发挥着至关重要的作用,预计未来市场上将出现许多基于人工智能的应用。GPU 等强大的硬件可以执行复杂的统计计算,并作为产品为客户提供可接受的解决方案。
几年前,我们根本无法想象 Alexa 这样的语音助手能成为一款产品。但是现在已经集成到很多产品中,也有很多兼容 Alexa 的智能家居设备,Alexa 兼容性现在是一个重要的功能。
最终,客户将决定基于人工智能的产品是否足够成熟和可用,或者仍处于研发阶段。用人工智能模型制造产品是复杂的,因为人工智能模型中固有的不确定性,或者是从外部感应到的模型输入。
模型视图与系统视图
大多数人工智能研究现在都是在大学或公司的实验室里进行的,有时是合作进行的。建立一个基于人工智能研究的系统是制造商的责任,而不是大学或研究所的责任。实验室开发的 AI 模型,大约 90%不进入生产线,不作为产品作为系统的一部分使用。
系统的当前产品生命周期管理不包括和解决基于人工智能的应用。对于如何在 ECU 软件中开发 AI 模型,我们有完全独立的生命周期管理。只要这两个产品生命周期并行运行,实现一个满足系统所有硬件和软件需求的人工智能模型就不会很容易。
照片由金德媒体从 Pexels 拍摄
一个人工智能模型的稳定性及其推广
由于人工智能模型的统计性质和训练数据的质量,无论是否考虑了应用的所有相关场景,在实验室中具有 95%准确度的基于人工智能的应用都不够稳定。
人工智能应用程序必须能够检测不属于训练数据的非分布数据。图像处理系统中的长颈鹿过滤仅用于检测狗和猫,这是分布失调的一个很好的例子。
机器学习中的泛化意味着人工智能模型能够很好地适应以前从未见过的数据,这些数据来自用于创建模型的同一分布。以前看不到的数据可能非常接近组之间的分类决策线,有时您需要更新 AI 模型以避免错位。
关键任务问题
基于规则的软件不可能实现具有高度复杂性和不确定性的系统。但是,我们如何在基于规则的软件中转移或重新定义我们的开发过程,以实现安全可靠的基于人工智能的应用程序?
基于人工智能的产品有一个不确定的部分,源于它们的统计和概率背景。处理关键任务问题至关重要,但很难达到高置信度,因为它目前在基于规则的系统中被用作“最先进”的技术。我们在汽车行业应用从 QM 到 D 的五个安全完整性级别,这个定义需要转化为基于 AI 的系统并重新定义。
像垃圾邮件检测器这样的基于人工智能的应用程序不是一个安全相关的应用程序,可以进行优化,以将更多的电子邮件发送到垃圾邮件文件夹,这不是关键的。但是,如果基于人工智能的行人检测算法失败或不够准确,导致一种或两种错误(分别为假阳性和假阴性)的发生率很高,那么它还不够成熟,不能作为产品在市场上销售。
总结一下,
人工智能系统开发人员,大多是数据科学家,应该将他们的观点从人工智能模型观点转变为整体系统观点。这意味着更多关注系统层面,包括硬件和软件及其交互,从客户的角度考虑模型对整个系统的价值。
领域知识是数据科学家开发高性能、安全的 AI 模型的最重要课题。我们在各个行业的云计算应用中都看到了同样的情况。要在汽车行业获得成功的云解决方案,您需要从客户的角度到技术方面非常深入的汽车知识。
基于人工智能的系统的生产包括许多组件,如数据收集、特征提取、监控、验证等。解决所有组件对于产品在市场上取得成功至关重要。许多在早期阶段做出的决定对最终的成功至关重要。比如在决定使用静态还是动态训练的时候,要考虑两者的权衡,要考虑两者的利弊,哪个更适合我们的应用。
在项目开发阶段,应尽早发现妨碍为客户提供具有附加值的可靠、安全产品的关键问题。至少必须有一个解决方案可用并同时实施,以将人工智能预测和决策的信心提高到社会可接受的水平。
毫无疑问,未来我们会有越来越多基于 AI 的产品上市,这个市场增长非常快。性能、安全性和可用性是市场上大多数人工智能应用应该考虑的最重要的属性。为了在研究活动和生产之间架起一座桥梁,我们需要行业内更多的合作,以及重新定义整个开发过程和交流思想。
如何使用 Docker 通过 pgAdmin 连接到 Heroku Postgres 数据库
原文:https://towardsdatascience.com/how-to-connect-to-a-heroku-postgres-database-with-pgadmin4-using-docker-6ac1e423ae66?source=collection_archive---------24-----------------------
了解世界上最先进的开源关系数据库
由 Marco Pregnolato 在 Unsplash 拍摄的照片
H eroku 是一个构建、部署、监控和扩展应用的云平台。它支持广泛的编程语言,包括 Ruby、Java、Python 等等。最重要的是,你可以给你的应用添加许多插件。 Heroku Postgres 就是其中一个支持 PostgreSQL 的。
您可以使用命令行或图形界面连接到 PostgreSQL 数据库。对于后一个目的,我们可以使用 pgadmin4 。它是 PostgreSQL 的开源管理和开发工具。
这篇文章教你如何用 Heroku Postgres 插件创建一个 Heroku 应用程序。之后,我们将使用 Docker 在本地机器上运行 pgadmin4。最后,我们将把 pgadmin4 连接到 PostgreSQL 数据库。
设置
我们将使用云平台 Heroku、Docker desktop for mac 和 Docker compose 文件进行设置。
1.创建 Heroku 应用程序
这一步你需要一个 Heroku 账号。现在,转到 Heroku 仪表盘。从那里,点击新建下拉菜单并选择创建新应用。
创建一个 Heroku app。
输入应用程序名称并点击创建应用程序按钮。
2.添加 Heroku Postgres 附加组件
导航到您的应用程序的概述选项卡,然后单击配置-附加组件链接。当你在搜索栏中输入时,你应该会看到 Heroku Postgres。
添加 Heroku Postgres 附加组件。
选择业余爱好开发-自由。它可以存储 10000 行数据,最多 20 个连接。点击了解更多关于计划&定价的信息。
3.使用 Docker 在本地设置 pgadmin4
首先,你需要安装 Docker 。现在从这里下载 docker-compose 文件,或者你可以复制粘贴到一个名为docker-compose.yml
的文件中。
version: '3.8'
services:
pgadmin:
container_name: pgadmin4_container
image: dpage/pgadmin4
restart: always
environment:
PGADMIN_DEFAULT_EMAIL: admin@admin.com
PGADMIN_DEFAULT_PASSWORD: root
ports:
- "5050:80"
我已经讨论了 docker-compose 文件的各个元素。有兴趣就看看吧。
对于环境标签,需要的变量是 PGADMIN_DEFAULT_EMAIL 和pg admin _ DEFAULT _ PASSWORD。点击阅读更多相关信息。
让我们从docker-compose.yml
文件所在的同一个目录运行下面的命令。
docker compose up
现在,您可以通过访问 URLhttp://localhost:5050/通过您最喜欢的 web 浏览器访问 pgadmin4。使用admin@admin.com作为邮件地址,使用 root 作为密码登录。
4.使用 pgadmin4 连接到 Heroku postgres 数据库
恭喜你!您已经成功地部署了一个 PostgreSQL 数据库,并使用 Docker 在您的机器上运行了 pgadmin4。现在我们需要将它们连接起来,这样我们就可以从本地机器上进行数据库管理。
访问数据库凭据。
点击 Heroku Postgres 链接并导航至设置选项卡。现在点击查看凭证。如你所见,有多个值,但我们只对主机、数据库、用户、、和密码感兴趣。
创建一个服务器。
从 pgadmin4 中,单击服务器>创建>服务器以创建服务器。
填写名称、主机名/地址、维护数据库、用户名和密码的数据。
对于名称,使用任何名称。现在移动到连接选项卡。将主机的值用于主机名/地址。将数据库的值用于维护数据库。将用户的值用于用户名。将密码的值用于密码,同时勾选保存密码?如果您不想在每次登录 pgadmin4 时都键入密码,请选择此框。
选择 SSL 模式选项,并填写主机地址数据。
现在对于 SSL 选项卡,选择要求为 SSL 模式。最后,移动到高级选项卡,使用数据库 ( 维护数据库 ) 的值用于****DB 限制。点击保存,大功告成!
5.额外的
如果你想导入一些测试数据进行测试,这部分是可选的。单击服务器> testdb >数据库>数据库名称>模式>表。右击表格并选择查询工具。将 SQL 查询从这里复制粘贴到查询编辑器,点击播放按钮。现在你应该有两个叫做学生和分数的表格,里面有一些测试数据。
包裹
现在您知道了如何使用 Docker 通过 pgadmin4 连接到 Heroku Postgres 数据库。如果你觉得这篇文章很有帮助,可以看看下面的文章,我在那里谈了更多关于 Docker 的内容。
**
资源
- Heroku、Postgres 和 PgAdmin 入门—第 2 部分 RUN _ _**
如何使用 Python 无服务器函数连接到 PostgreSQL 数据库
原文:https://towardsdatascience.com/how-to-connect-to-a-postgresql-database-with-a-python-serverless-function-f5f3b244475?source=collection_archive---------55-----------------------
使用 Heroku 和 Vercel
照片由 Pexels 的达里亚·奥拜马哈拍摄
与传统系统不同,无服务器计算可以缩减到零。这意味着您只需为您使用的计算资源付费。Vercel 是许多提供无服务器运行时的平台之一,也称为功能即服务(FaaS)。您可以使用这些函数为整个应用程序构建一个无服务器的后端。
我们经常需要数据来驱动我们的应用程序,而数据库可以解决这个问题。PostgreSQL 是一个开源的对象关系数据库,因其可靠性和性能而广受欢迎。这篇文章将教你如何用 Vercel python 无服务器函数连接到 Heroku PostgreSQL 数据库。
设置
对于我们的设置,我们将使用 GitHub 、 Heroku 和 Vercel 。首先,我们将在 Heroku 中创建数据库。之后,我们将创建一个 git 存储库来将我们的无服务器功能部署到 Vercel。
1.在 Heroku 中创建 PostgreSQL 数据库
如果您在 Heroku 中没有现成的数据库,请阅读下面的帖子,其中我介绍了在 Heroku 中创建 PostgreSQL 数据库的所有步骤。
2.使用 Python 无服务器函数连接到数据库
首先,从 GitHub 下载资源库。现在我们将关注位于 api 文件夹中名为index.py
的文件。此外,我们需要在 api/requirements.txt 文件中指定这个项目的所有依赖项。这里我们有一个,psycopg2-binary
。
让我们来分解一下index.py
文件的各个组成部分。
索引. py
对于数据库连接,我们将创建一个新的数据库会话。连接方法返回一个新的连接对象。连接参数是一个主机(未提供默认为 UNIX socket)dbname、用户、密码、端口(未提供默认为 5432)。你可以从 psycopg2 文档中了解更多。现在我们将使用连接创建一个新的光标对象。
之后,为了方便起见,我解析了查询字符串并将其转换为字典。我已经将 HTTP 状态代码设置为 200,并将内容类型设置为 JSON。
下面一行在字典中查找名为student_id
的键。if 块执行一个 SQL 查询,其中我们传递一个学生 id。您可以从 psycopg2 文档中阅读更多关于 execute 方法的信息,以及从 psycopg2 文档中阅读更多关于 SQL 查询的信息。获取方法返回查询结果集的下一行。如果没有更多的可用数据,它或者返回一个元组或者 None 。此外,我们将元组转换为数组。现在让我们获取表 students 的列名,并将它们放入一个数组中。之后,我们使用 zip 方法来合并我们的列和值数组。从 python 文档中阅读更多关于 zip 方法的信息。else 块创建一个字典。
最后,我将返回message
的编码内容,默认为的 UTF-8。
我们都为下一步做好了准备。访问 Vercel 上的仪表板,然后从 GitHub 导入git 库。
单击新建项目。
搜索 git 存储库。如果找不到,点击配置 GitHub App,通过 GitHub 添加。
导入 git 存储库。
导入存储库后,单击继续按钮。
导入并继续。
现在,我将选择个人账户选项。然后,添加所有五个环境变量,主机,数据库,用户,密码,以及端口。我们可以从 Heroku 那里得到这些值。如果您找不到这些值,请返回此设置的第一步。
选择适当的选项并配置环境变量。
单击“部署”并通过单击“访问”按钮访问无服务器功能。这里的地址是由 Vercel 生成的https://vercel-python-postgresql.vercel.app/。我们需要在基本 URL 的末尾添加 api/file_name 来访问该函数。添加之后,我们有了一个看起来像 https://vercel-python-postgresql.vercel.app/api/index 的 URL。
你完了。
下面的链接将从我们的 Postgres 数据库返回学生 id 为 1 的学生数据。
https://vercel-python-postgresql.vercel.app/api/index?student_id=1
我们应该会看到下面的输出。
{
"id": 1,
"first_name": "Ailn",
"last_name": "Rathmouth",
"city": "Rathmouth",
"phone": "05144461974",
"gender": "Female",
"email": "mailn0@bravesites.com",
"address": "97228 Emmalee Harbors Suite 421 South Emmet, TX 54950",
"postcode": 23031,
"date_of_birth": "2001-12-16"
}
没有任何查询字符串。
https://vercel-python-postgresql.vercel.app/api/index
对于这个调用,我们应该看到下面的输出。
{
"error": "Please provide student_id"
}
干得好!现在您知道了如何使用 Vercel python 无服务器函数连接到 Heroku PostgreSQL 数据库。我希望你能从这篇文章中学到一些新的东西,如果你觉得这篇文章有帮助的话,看看下面的文章,我在那里谈了更多关于 Vercel 的内容。
如何使用 SSH 隧道通过 Python 连接到 PostgreSQL 数据库
原文:https://towardsdatascience.com/how-to-connect-to-a-postgresql-database-with-python-using-ssh-tunnelling-d803282f71e7?source=collection_archive---------3-----------------------
了解当需要 SSH 加密时,如何使用 Psycopg2 或 SQLAlchemy 查询 PostgreSQL 数据库。
约翰·施诺布里奇在 Unsplash 上的照片
你希望在 2022 年成为一名数据工程师并推进你的职业发展吗?看看 Udacity 的点播 数据工程纳米学位 并利用以下 2022 年 2 月特别折扣代码:
*** 在 2022 年 2 月使用代码促销 25 ** 在 UDACITY 球场享受高达 25%的折扣
介绍
Python 至少提供了两种与 PostgreSQL 数据库交互的简单方法:
- 使用
pycopg2
包创建连接 - 通过
sqlalchemy
包发电和发动机。
只要您有有效的凭证,就可以用几行代码建立连接。但是如果你的公司已经实现了 SSH 隧道作为一个额外的加密层呢?
“这很烦人…现在我需要编写另一个防弹脚本来替换我使用多年的脚本…”
这是我第一次发现 SSH 存在时的想法,我花了一段时间来消化每次我希望查询 PostGreSQL 数据库时必须通过隧道连接的想法,无论是通过 DMBS 还是通过 Python 脚本。
在本文中,我将与您分享我为解决该问题而创建的两个代码片段(一个用于psycopg2
,另一个用于sqlalchemy
)。我相信您将能够根据您的具体使用情况修改它们,并在几分钟内连接起来。
但是在开始之前,为什么首先需要 SSH 隧道呢?如何创建 SSH 公钥和私钥?
SSH 加密背后的要旨
创建 SSH 隧道是在客户端和服务器之间建立加密连接的一种方式,可用于转发任何 TCP ( 传输控制协议)端口。
这意味着使用 SSH 隧道,您可以将本地机器上的端口链接到远程主机上的端口。一旦端口被链接,就可以通过安全的 SSH 连接在本地和远程端口之间交换通信。
例如,SSH 加密经常用于从本地机器访问数据库。这是通过使用 SSH 私有和公共密钥的组合通过 SSH 隧道连接到数据库主机来实现的。
您可以通过在终端中运行以下命令来创建 SSH 密钥对:
$ ssh-keygen -t rsa -b 4096 -C “your_name@example.com”
这将创建 4096 位长的密钥,使用 RSA 算法来加密和解密消息(或者,您可以使用更高级的ed25519
算法,如 Risan Bagja Pradana 在本文中所述)。
然后会提示您输入保存密钥的文件(按 enter 键接受默认值)和密钥的密码。
然后,确保您的代理正在运行,并将您的密钥添加到代理中。如果提示输入密码,请输入您刚刚创建的密码:
$ eval “$(ssh-agent -s)”$ ssh-add ~/.ssh/id_rsa
您应该能够使用cat
命令在隐藏的.ssh
文件夹中的两个文件上显示您的私钥和公钥(记住您可以使用ls -a
命令显示隐藏的文件夹):
$ cat ~/.ssh/id_rsa.pub $ cat ~/.ssh/id_rsa
现在已经生成了一对密钥,是时候使用它们连接到 PostgreSQL 数据库了。
访问数据库凭据
为简单起见,您可以决定将数据库凭证保存在一个 JSON 文件中,如下所示:
{“PG_UN” : “your_db_user_name”,
"PG_DB_NAME": "db_name",
“PG_DB_PW” : “your_pw”,
“SSH_PKEY” : “your_ssh_pkey”,
"SSH_HOST" : "111.11.0.111",
"DB_HOST" : "222.22.0.202",
"LOCALHOST" : "333.0.0.3",
"PORT" : "5432"}
你可以通过阅读获得它们:
creds = json.load(open(“/Users/{USER}/path/db_cred.json”, ‘r’))
无论多么方便,将凭证隐藏在本地文件中并不是最佳实践。我建议将它们存储为环境变量,如下文所述:
使用 Psycopg2 连接到 PostgreSQL】
现在您可以访问凭证了,是时候尝试用psycopg2
建立到 PostgresSQL 的连接了。
当涉及到 SSH 隧道时,您需要导入这两个包:
import psycopg2 as pg
from sshtunnel import SSHTunnelForwarder
然后您可以使用SSHTunnelForwarder
生成一个隧道并初始化它:
ssh_tunnel = SSHTunnelForwarder(
creds[“SSH_HOST”],
ssh_username=creds[“PG_UN”],
ssh_private_key= ‘/Users/Antonello.Benedetto/.ssh/id_rsa’,
ssh_private_key_password= creds[“SSH_PKEY”],
remote_bind_address=(creds[“DB_HOST”], 5432)
)ssh_tunnel.start()
最后一步,通过psycopg2
创建一个标准连接:
conn = pg.connect(
host=creds[“LOCALHOST”],
port=ssh_tunnel.local_bind_port,
user=creds[“PG_UN”],
password= creds[“PG_DB_PW”],
database=creds[“PG_DB_NAME”])
将所有这些放在一起,您最终应该得到一个类似如下的脚本:
要测试您的连接,您可以使用我在下面创建的一个或多个实用函数。特别是:
- 使用
execute_sql_ppg2
,您可以通过传递首选的query
来执行 SQL 语句; - 通过
query
和连接对象,你可以用create_df_from_ppg2
创建一个熊猫数据框架; - 使用
create_table_ppg2
,你可以通过传递df
、conn
、table_name
和schema_name
作为参数,在 PostgresSQL 中非常灵活地从熊猫数据帧创建一个表。
例如,通过将下面的query
传递给前两个函数:
https://gist . github . com/an bento 0490/21328 DD 7 FD 93 EC 20 c 714 a2 ed 1 df 2 b5 da
我获得了以下输出:
使用 SqlAlchemy 连接到 PostgreSQL
通过sqlalchemy
访问 PosgreSQL 包含与psycopg2
完全相同的步骤。唯一的区别是,您现在需要导入:
from sqlalchemy import create_engine
from sshtunnel import SSHTunnelForwarder
您需要创建引擎对象,而不是创建连接对象:
engine = create_engine(‘postgresql://{user}:{password}@{host}:{port}/{db}’.format(
host=creds[“LOCALHOST”],
port=ssh_tunnel.local_bind_port,
user=creds[“PG_UN”],
password=creds[“PG_DB_PW”],
db=creds[“PG_DB_NAME”]
))
同样,将所有这些放在一起,您会得到:
结论
在本文中,我向您展示了当需要通过 SSH 隧道建立安全连接时,如何通过psycopg2
或sqlalchemy
连接到 PostgreSQL 数据库。
如果这是您第一次被要求在工作场所使用这种方法,我希望这篇文章提供了足够的上下文,以及打破最初的技术障碍所必需的代码。
相反,如果你熟悉 SSH 转发,我希望你会尝试使用我的代码作为模板,以刷新你的记忆,并完成工作:D
给我的读者一个提示
这篇文章包括附属链接,如果你购买的话,我可以免费给你一点佣金。
如何远程连接到 JupyterLab
原文:https://towardsdatascience.com/how-to-connect-to-jupyterlab-remotely-9180b57c45bb?source=collection_archive---------1-----------------------
如何在远程计算机上运行 JupyterLab
由粘土银行在 Unsplash 上拍摄
Jupyterlab 是一个基于 web 的交互式开发环境(IDE ),用于 Jupyter 笔记本、代码和数据。从笔记本电脑上连接和运行 Jupyterlab 非常简单。您只需在您的终端中键入jupyter lab
,Jupyterlab 将在您的浏览器中打开,笔记本服务器在您的终端中运行。
如果您想从远程计算机上运行它呢?如果 Jupyterlab 运行在远程计算机上,如何连接到它?这篇文章将带您了解如何在一个 SLURM 集群上启动 Jupyterlab,然后从本地机器上运行的浏览器进行连接。
目录
- 安装
- JupyterLab 安全
- 在远程计算机上启动 JupyterLab
- 端口转发 JupyterLab
- 在浏览器中打开 JupyterLab
- 最终想法
装置
您可以使用 conda、mamba、pip、pipenv 或 docker 安装 JupyterLab。以下命令用于通过 conda 安装。
conda install -c conda-forge jupyterlab
如果你没有使用 conda,我推荐最小和轻量级的 Miniconda 安装程序。以下是开始使用 conda 和 Miniconda 的说明。
https://betterprogramming.pub/how-to-use-miniconda-with-python-and-jupyterlab-5ce07845e818
JupyterLab 安全
为了确保其他用户无法访问您的笔记本,Jupyter 笔记本服务器可以包含一个安全密码,
要创建密码,首先需要生成一个配置文件:
jupyter server --generate-config
运行此命令会在以下位置创建一个配置文件:
~/.jupyter/jupyter_server_config.py
然后输入以下命令创建服务器密码。
jupyter server password
输入密码后,散列版本将被写入~/.jupyter/jupyter_server_config.json
。如果散列版本是公共的,这是可以的。
现在 JupyterLab 是安全的,您将能够使用密码登录。
在远程计算机上启动 JupyterLab
既然 JupyterLab 已经安装并安全,让我们使用下面的脚本在集群的计算节点上启动它。我使用的是 SLURM 调度程序,但这可以很容易地适用于其他调度程序,如 PBS 。只需将 sbatch 指令(#SBATCH
)更改为 PBS 指令(#PBS
)。
良好的做法是将脚本存储在高性能计算机(HPC)的主目录中。我更喜欢把它们留在~/scripts/
。因为这是一个 sbatch 脚本,所以我们不需要像使用 shell 脚本那样使它可执行。
您可以向集群提交作业,如下所示:
sbatch ~/scripts/launch_jupyter.sh
SBATCH 指令定义要收费的帐户、作业名称、运行作业的时间以及请求的内存。解释 SBATCH 指令超出了本教程的范围。你可以在这里了解更多。
行source activate base
激活我想使用的 conda 环境。这可以在 JupyterLab 中更改为不同的内核。如何把 conda 环境做成内核在这篇文章中讨论。
jupyter lab
命令有几个重要的标志:
--no-browser
→告诉服务器不要打开浏览器。--ip “*”
→配置笔记本电脑服务器监听所有网络接口,而不仅仅是默认接口localhost/127.0.0.1
--notebook-dir /burg/glab/users/luke
→告诉 JupyterLab 打开这个目录。
最后,一旦您的作业开始,服务器输出将流到SLURM-<JOBID>.out
,其中 JOBID 是这个作业的惟一编号。作业 ID 显示在作业状态中。
工作状态
您可以使用以下命令在 SLURM 集群上检查您的launch_jupyter.sh
作业的状态:
squeue -u <username>
下面是运行此命令后的输出示例。
以下是squeue
输出中每一列所代表的内容:
- 作业 ID: 这是作业
的 ID【如果你想取消作业,你需要这个:scancel JOBID
- 分区:这是哪个用户账户被收费
【由#SBATCH --account=ACCOUNT
定义】 - 名称:这是队列
[定义者:#SBATCH -J NAME
]中的作业名称 - 用户:这是拥有该作业的用户
- T21:这就是这份工作的现状。r 表示跑步
- 时间:这是 long 已经运行了多长时间
【最大运行时间由:#SBATCH --time=01:00:00
定义】 - 节点:这是您正在为此作业使用的节点数量
[可以用指令定义:#SBATCH -n NODES
] - 节点列表:这是作业正在哪个节点上运行。这一会儿会有用的。
状态代码
squeue
可以列出几个状态代码。运行 JupyterLab 时,您只需要注意几个方面:
- 待定(
PD
) →作业正在等待资源分配。它最终会运行。 - 正在运行(
R
) →作业当前被分配到一个节点并正在运行 - 失败(
F
) →作业因非零退出代码而终止,无法执行。 - 暂停(
S
) →正在运行的作业已经停止,其核心被释放给其他作业 - 已停止(
ST
) →正在运行的作业已停止,但其核心仍保留。
关键错误:"运行时目录"
此错误曾是在群集上运行 JupyterLab 时出现的问题,但现在已得到解决。但是,如果您遇到这个错误,修复它的方法是将下面一行添加到您的launch_jupyter.sh
脚本中:
export XDG_RUNTIME_DIR=""
端口转发联合实验室
首先,我们需要知道 Jupyterlab 运行在哪个端口上。这很可能是端口 8888。如果想确定,就看slurm_<JOBID>.out
吧。下面是more slurm-77407.out
的输出,我用黄色突出显示了远程节点和端口。您也可以对“http”使用grep
来提取这一行
现在,您可以像这样连接到此端口:
ssh -L 8888:g026:8888 luke@burg.rcs.columbia.edu
前半部分指定端口转发,后半部分指定远程主机上的用户。
ssh -L local_port:remote_node:remote_port user@remote_host
你必须让它在你的终端上运行。你可以在screen
或tmux
运行这个,只是不要忘记它。
在浏览器中打开 JupyterLab
输入您的密码后,您将能够从本地网络浏览器打开 Jupyterlab。在本例中,我们在本地端口 8888 上打开它,因此我们在 web 浏览器中键入以下内容:
https://localhost:8888
这将在您的浏览器中打开 Jupyterlab,但是命令将执行您的远程 HPC。
密码不起作用?
我强烈推荐用密码保护你的服务器,在JupyterLab security一节中有描述。如果您的密码不起作用,或者您选择不设置密码,那么您可以输入一个访问令牌。这个令牌显示在SLURM-<JOBID>.out
中。见下面截图。
通过查找包含“token”的行,您可以使用 grep 访问该行。
grep token slurm-<JOBID>.out
最后的想法
我喜欢在 JupyterLab 工作,尤其是当我制作数字和做一些探索性分析的时候。我也喜欢在 HPC 上工作,它提供了比我的笔记本电脑更大的存储空间,并且可以访问计算节点来处理大数据。我希望这篇文章能帮助你远程连接 JupyterLab。
随着 JupyterHub 获得更广泛的采用,这个繁琐的过程有望被淘汰。JupyterHub 提供了一种为多个用户提供 Jupyter 笔记本的方式,这在 HPC 上尤其有用。然而,它还没有被广泛采用。所以在那之前,我们必须保持端口转发。
如果您在连接远程计算机时遇到问题,请告诉我,我很乐意帮助您解决问题。
感谢阅读和支持媒体作者
https://lukegloege.medium.com/membership
如何在数据科学中保持一致
原文:https://towardsdatascience.com/how-to-consistently-write-in-data-science-134d52e62379?source=collection_archive---------45-----------------------
反思我可以改进的地方,以及你可以如何改进。
照片由 Aaron Burden 在 Unsplash
我记得写了两个月后赚了 30 美元,心想我成功了。事实上,那个月之后我几乎没有继续写作,第二个月赚了 40 美元。
哇 ,我心想, 真的那么容易。我很快就会有被动收入。
好吧,接下来的一个月,我决定不写了,我赚了整整 3 美元!这时我才意识到,事物消散的速度比你得到它们的速度要快得多。
我后悔那几个月没有写作,仅仅是因为我错过了在这个领域作为一名作家促进我个人成长的机会。TDS 不仅让我深入了解了许多其他人在这个令人惊叹的领域所做的事情,而且也让我成为偶尔提供见解的人。
然而,现在我又开始写作了,这个月将会是最好的一个月。我这样做并不完全是为了钱,但这是写作带来的一个很好的补充。
我不能告诉你为什么我决定重新开始写作。我只是想继续学习数据科学,并以某种方式为之做出贡献,所以我就这么做了。
在我休息之前,我这样做是为了钱,这就是为什么我很快就变得自满。然而,当我重新开始写作时,它不再是我的首要任务。我认为这是我可以成长为比自己更强大的东西,也让我成长为一名数据科学家。作为这个领域的作家,拥有这种态度对你来说是无价的。
考虑到这一点,我想把经验传授给你,希望你能找到我找到的写作乐趣。
课程
1-在数据科学中找到一个你喜欢写的领域。
数据科学是一个非常广阔的领域,当你找到一个你喜欢写的利基时,你会发现自己更喜欢这个过程。这样想想,说到数据科学,你最感兴趣的是什么?当你有了这个问题的答案,开始寻找与此相关的文章。无论是自然语言处理,计算机视觉,还是音频应用,开始看看你感兴趣的文章,然后自己开始写。
这样做不仅会加深你对手头课题的理解,还能让你把它传授给这个领域的其他新手。TDS daily 上有数百名新读者。你的文章可能会激励他们成为你专业领域的数据科学家。更好的是,你的文章可能会激励他们开始写作并为这个领域做出贡献。
关心这个领域的人越多,这个领域就会变得越好。
强迫自己每天写作。
哪怕是一两句话,就写。 你会很高兴自己决定坐下来记下想法,因为一句话会变成两句话,两句话会变成三句话,以此类推。虽然你可能认为你有两句话要写,但它会变成更多。最难的部分是从一张白纸开始,所以只要开始,你就会意识到以后很难停下来。
在练习编程的时候,只有你决定每天编程来练习和磨练你的技能才有意义。如果你决定从一个项目中休息一下,回到代码中可能会非常混乱,并且仅仅因为已经过了很长时间,就需要很长时间才能赶上进度。写作也不例外。当你决定每天写作时,写作对你来说就变得容易多了,它就像编码对你来说一样。
不相信我?坚持写一个月,看看写更多会变得多么容易。你不会在健身房跳到 50 磅的重量,也不会一天跳到一篇文章。然而,随着时间的推移,你会迅速提高,能够写出比你想象中更多的东西。
3-承诺发布时间表。
可能是一周一次,一个月一次,或者一天一次。时间表并不重要,只要承诺最低限度并遵守就行了。通过这样做,你让自己对继续写作负责,因此你会继续坚持写作。现在,生活会有这样的时刻,你真的不能写作,或者在找到更多的空闲时间写作之前,你有许多其他的义务要做。没关系,在这种情况下,你应该原谅自己。
然而,当你知道你的生活中没有什么真正引人注目的东西时,花时间定期发表。随着时间的推移,你会进入这样一种深度心流状态,你会想要打破你为自己设定的目标。慢慢地,但肯定地,你发表的内容会越来越多,你会发现自己比以前更了解这个领域。
责任对任何人来说都是最强大的东西。写的时候把它记在心里,你就会成功。
4-要有耐心。
不是所有的文章都会做的很好。事实上,在我成功的几个月里,只有两篇文章表现很好,而其他的都远远落后。你不会知道哪些文章会做得很好,猜测也没有意义。通过写你喜欢的事情,你唯一能想到的就是写那一件事。当这是你唯一的关注点时,那篇文章的意外成功会让你的劳动果实更加甜美。
可以有意义的,也可以很快有。然而,你不能两者兼得。当涉及到我生活的每一个方面时,这是我赖以生存的东西,当你也理解这一点时,它可以改变生活。
耐心是一种美德是有原因的。它会打开你从未想过的门。然而,当你沉浸在写作的境界中,不期待任何回报时,这些门就会打开。
结论
我希望你能从这篇文章中学到一些东西。如果是这样的话,那么我就能把几个月来我一直在写的东西浓缩成相当有价值的东西。
如果你对开始写作持观望态度,我真的建议你这么做。开始的最好的一天是昨天,第二好的一天是今天。不要评价自己,只管发帖。
最可怕的事情是盯着发布按钮,但最令人鼓舞的事情是有人为你的文章鼓掌。
感谢您的阅读。
作者更多文章:
https://medium.com/swlh/why-you-must-use-linux-dddf7cabb266
如何将 Python Jupyter 笔记本转换成 RMarkdown 文件
原文:https://towardsdatascience.com/how-to-convert-a-python-jupyter-notebook-into-an-rmarkdown-file-abf826bd36de?source=collection_archive---------9-----------------------
实践教程
Pythonist,试试 RMarkdown,准备好大吃一惊吧!
克莱门特·赫拉尔多在 Unsplash 拍摄的照片
1。简介
注 1:如果你想直接进入我的代码,直接进入第 3 节(“从 Jupyter 到 RMarkdown 世界”)。
注 2:对于 R 用户,勾选 *rmarkdown::convert_ipynb()*
功能。它是官方的,比我在这里展示的 Python 代码更通用。
几年前,当我开始我的编程之旅时,Python 是我的初恋,它仍然是我最喜欢的语言。然而,在过去的几个月里,由于工作和学业的原因,我越来越喜欢 R。而且我必须承认:R 也超级好玩!我对这两种语言研究得越多,就越确定数据分析和数据科学领域的多语种道路 就是我想要的。
事实上,编程语言应该被简单地视为工具,并根据任务和您需要解决的问题的具体环境来使用。事实上,Python 中有一些很好的资源可能是 R 中没有的,反之亦然。我相信 RMarkdown 生态系统是 Python 用户应该考虑了解的资源之一,以便只使用 Markdown 和 Python(以及 Google Colab 中的五行 R 代码)来构建像这样的报告或另一个。
2。节目全景
我写了一个简短的程序,旨在帮助一个事先没有 R 知识的 Python 用户加入 RMarkdown party。所以让我们开始派对吧!这里的主要目标是使从一个编程世界到另一个编程世界的过渡尽可能容易。
这个程序是用 Python 写的,可以将整个 Python Jupyter 笔记本转换成 RMarkdown 文件。然后,我们将打开一个简单的带有 R 内核的 Google 协作笔记本,运行五行 R 代码,并从我们的 RMarkdown 文件中生成任意多种格式的文档:HTML 输出页面、PDF、EPUB、Microsoft Word、Power Point 演示文稿、xaringan 演示文稿、bookdown 文档等等。所有这些都来自同一个源文件,这极大地提高了可重复性和可维护性。
我们的 Python 代码将关注如何将 Jupyter 笔记本转换为 Rmarkdown 文件,当使用 R 的markdown::render()
函数执行时,会生成一个 HTML 输出文件,带有漂亮的侧边栏菜单和布局设计。如果您对其他类型的输出感兴趣,我强烈建议您阅读由谢一辉、J. J. Allaire 和 Garrett Grolemund 以 bookdown code 编写的 R Markdown:权威指南 的前几章。
我必须承认,我还没能在 Python 中找到类似于 RMarkdown 所提供的资源;这就是我通过发表这篇文章,努力让 RMarkdown 更容易被 Python 社区访问的主要原因。如果你知道任何与 RMarkdown 结果相似的 Python 包,请告诉我,我也愿意探索它们。
3。从 Jupyter 到 RMarkdown 世界
有些用户可能不知道,Jupyter notebook 只是一个 JSON 文件,由某个引擎呈现,然后以我们熟悉的交互式布局(markdown 单元格和 code 单元格)呈现给我们。但是所有的笔记本信息都组织在一个 JSON 结构中,一个有四个键(cells
、metadata
、nbformat
和nbformat_minor
)的字典存储所有的笔记本数据。
cells
键无疑是最重要的一个,因为它保存着用户写在笔记本上的代码。cells
键的值是一个字典列表,列表中的每个字典对应于笔记本中的一个单元格。
出于教学目的,我创建了一个名为test_notebook.ipynb
的简短 Python Jupyter 笔记本,并将其发送到我的 Github 页面。如果你在这里检查它的原始版本,你会注意到 JSON 文件是如何构造的,然后你有希望更好地理解我在前面两段中的意思。test_notebook.ipynb
文件是我们稍后将转换成 RMarkdown 的 Jupyter 笔记本。当然,您可以使用自己的笔记本来进行第一次测试。我只建议你事先做一份原始文件的副本,以防万一。
进行这种转换(Jupyter 到 RMarkdown)的代码位于另一个笔记本(ConvertToRMarkdown.ipynb
)、、中,可在下面的 Github 存储库、、、中找到。
我们将从导入 json 模块开始,用open()
打开test_notebook.ipynb
文件,并使用json.load()
函数将 JSON 对象转换成 Python 字典。我们还将把这个字典保存到data
变量中。
我们需要从metadata
键获得的唯一信息是笔记本内核中使用的编程语言名称。我们只用一行代码就可以做到:
现在我们将注意力转移到 JSON 主字典中的cells
键,由data["cells"]
代码调用。列表中的每一项都是一个字典,代表笔记本中的一个单元格。
此外,每个单元字典有两个对我们非常重要的键:cell_type
,在我们分析的情况下,它的值是"markdown"
或"code"
;和source
,它有一个字符串列表作为它的值。这些字符串是在笔记本单元格中一行一行写下的实际代码,稍后我们需要将它们汇编到最终的 RMarkdown 文件中。
我使用列表理解将这些信息保存到嵌套列表的结构中,如下所示:
一方面,在我们代码中循环的后续中,我们将把来自x["cell_type"]
的值保存在一个名为cell_type
的临时变量中;另一方面,x["source"]
的值将存储在一个名为source
的临时变量中。**
在将cells
变量定义为上述列表理解的结果后,我们现在将创建强制 RMarkdown 文件头。它由编辑成 YAML 文件的文本组成,包含所有 RMarkdown 配置,比如主标题、作者、日期和文件的输出类型(在我们的例子中,只有html_document
一个)。
在这段代码中,您应该注意到两个重要的方面:
- 缩进在 YAML 代码中很重要,类似于我们在 Python 中所做的。因此,如果您在 RMarkdown 文件的顶部错过了 YAML 缩进结构中的一个空格,您可能会在某个时候面临 RMarkdown 呈现问题。如果发生这种情况,回到代码中,尝试发现错误所在,然后修复它。您可以随时在您选择的代码编辑器中打开 RMarkdown 文件,并根据需要进行修改;
- 在标题、作者和日期选项中,我插入了一些 HTML 标签,以赋予最终的布局以个人风格。请注意,在这些情况下,管道符号是必需的。
这里不是讲授可以添加到 RMarkdown 文件这一部分的所有不同配置的地方。如果你想了解更多这方面的内容,我推荐你去咨询前面提到的R Markdown book。关于这些主题和其他主题,你需要的大多数答案都可以通过查阅那本书或 RMarkdown 软件包文档找到。**
下面是 YAML 部分的代码。您可以直接在为存储这些数据而创建的变量中更改自己的作者和日期信息。我们将把这个长 f 字符串保存到file_text
变量中。
我们几乎没有开始讨论我们的代码,人们已经可以看到它的结束。现在我们只需要遍历笔记本单元格的内容,并将它们添加到file_text
变量中。然后我们将把这个file_text
字符串写入一个全新的 RMarkdown 文件,这个文件必须有.Rmd
扩展名(注意其中的大写 R)。
在上面循环的中,注意我们之前提到的临时变量cell_type
和source
最终被创建。cell_type
值将用于检查当前笔记本单元格是降价单元格还是代码单元格。如果是前者,我们只需要把弦连在一起,用"".join(source)
的方法;如果是 code cell,我们还需要在 RMarkdown 中添加 chunk block 结构(更详细的内容可以从前面提到的书中查看这部分)。条件语句中的and source
部分将使程序跳过降价,并用空值编码单元格(换句话说,没有源信息)。**
代码块结构允许 RMarkdown 运行代码,不仅可以运行 R 和 Python 代码,还可以运行许多其他语言的代码。当我们在花括号内插入单词python
时,就在打开代码块的`````符号之后,我们告诉 RMarkdown 这是一段 Python 代码,R 应该使用特定的资源来运行它(在本例中,是 R 的reticulate
包)。RMarkdown 代码块也支持许多其他编程语言,如 Julia、SQL、C、Javascript 等。这个系统还允许简单的 chunck 代码重用,这是一个很好的资源,你一定要有一天去看看。
现在我们已经创建了converted_notebook.Rmd
文件,我们已经准备好迁移到 Google 协作环境了。然而,让我们在这里做一个重要的观察:Google 协同实验室的下一步可能不能由您轻松地在本地完成(例如,仅仅通过运行一个神奇的语句使 Python Jupyter 笔记本中的一个单元格运行 R 代码)。除了在 R 命令中做进一步的配置以使用本地 Pandoc 副本正确地呈现 RMarkdown 文件之外,您还需要在您的机器上安装 Pandoc 程序。
在本地呈现 RMarkdown 文件的一个更简单的方法是安装 R 程序并使用集成了 Pandoc 的 RStudio IDE。您应该稍后测试这个选项,因为 RStudio 也是一个非常有趣的 IDE。然而,对于那些没有 R 知识的人来说,最快、最好的选择无疑是简单地转向 Google Colab,我将在下面解释。
4。生成 HTML 输出文件
现在我们需要打开一个新的谷歌 Colab 笔记本用 R 内核。为此,请在您的浏览器上粘贴以下链接之一。您需要登录您的 Google 帐户(或创建一个帐户)才能使用 Google 联合实验室:
- http://colab.to/r
- https://colab.research.google.com/#create=true&语言=r
在 Google Colaboratory 笔记本中,将converted_notebook.Rmd
文件上传到/content
目录,一旦 Colab 启动,该目录将成为当前的工作目录。当.Rmd
文件在正确的位置时,在 Google Colab 代码单元中执行下面的 R 代码(可能需要一段时间来运行它。R Colab 笔记本好像比 Python 的慢):
install.packages()
是相当于 Python pip install
的 R。在 Google Colab with R 中,每次开始新的会话时,您都需要安装这些包。接下来,用library()
命令导入两个包,这类似于 Python import
语句。最后,rmarkdown::render()
函数会将.Rmd
文件转换成.html
文件。刷新 Google Colab 文件列表后,您将看到这个新文件。
5。最终想法
最后一步是从 Google Colab 下载.html
文件,并在您最喜欢的浏览器上打开它。通过这样做,您可以检查从 RMarkdown 生成的 HTML 页面报告与 Jupyter 笔记本布局相比看起来有多么不同,如果您喜欢您所看到的,可以继续了解 RMarkdown 生态系统。
如果您想将带有代码的长报告转换成 HTML 文档并在页面间导航,bookdown 库是一个特别有趣的库。您还可以使用 CSS、HTML 和 Javascript 代码来进一步定制报表布局和行为。
如果你想更多地了解 RMarkdown 的历史、演变和未来,我邀请你观看几天前在 9 月 9 日谢一辉本人的会议报告。虽然在视频的开头和结尾,一些组织者教授会说一点葡萄牙语,但所有 Yihui Xie 的演示和 Q & A 部分都是英语。我在这里提到这个视频也是因为它是我写这篇文章的一个主要灵感。所以,我要感谢易慧和来自巴西 UFPR ( 巴拉那联邦大学/ 巴拉那联邦大学)的组织者,他们组织了第三次 R 日活动,并与我们分享了他们的知识。
此外,易慧非常友好地阅读了我的这篇文章,并给了我重要的反馈,指出 RMarkdown 库已经有了*convert_ipynb()*
函数,我并不知道它的存在,它是一个比我的解决方案更完整的解决方案。因此,即使你是一个很少或没有 R 经验的 Python 用户,也可以考虑将*convert_ipynb()*
与 RStudio 或 Google Colab 一起使用,尤其是如果你打算定期将 Jupyter 笔记本转换为 RMarkdown。
最后,亲爱的读者,非常感谢你花时间和精力阅读我的文章。
**快乐编码!
如何将 PyTorch DataParallel 项目转换为使用 DistributedDataParallel
原文:https://towardsdatascience.com/how-to-convert-a-pytorch-dataparallel-project-to-use-distributeddataparallel-b84632eed0f6?source=collection_archive---------18-----------------------
泰勒·维克在 Unsplash 上的照片
许多帖子讨论 PyTorch DataParallel 和 DistributedDataParallel 之间的区别,以及为什么使用 DistributedDataParallel 是最佳实践。
PyTorch 文档对此进行了总结:
由于线程间的 GIL 争用、每次迭代的复制模型以及分散输入和收集输出带来的额外开销,即使在单台机器上,DataParallel 通常也比 DistributedDataParallel 慢
但事实是,对于开发和原型设计,当处理一个新项目时,或者当在现有的 GitHub 存储库(已经使用了 DataParallel)之上构建时,使用现成的 DataParallel 版本更简单,特别是当使用一个服务器(有一个或几个 GPU)时。最突出的优点是用 DataParallel 更容易调试。
尽管如此,总有一天,您会希望将现有的 DataParallel 项目转换为大联盟,并使用分布式 DataParallel 这显然不是小事,因为它应该是。
所以在这篇文章中,我不会进一步讨论每种方法的优缺点,而是集中在将一个用 DataParallel 实现的现有项目转换成一个分布式 DataParallel 项目的实际方面。
我将尽可能概括地描述不同的部分,但是当然,您的用例是独特的😃并且可能需要根据您的实现和代码进行仔细和具体的调整。
我们走吧…
第一步是包装。DataParallel 使用带有多线程的单进程,但是 DistributedDataParallel 在设计上是多进程的,所以我们要做的第一件事就是使用多进程包装器包装整个代码——我们的主要功能。
为此,我们将使用由 FAIR 在 Detectron2 存储库中提供的包装器。我们还需要 comm 文件,它为处理分发资源提供了一些不错的功能。
从 Detectron2 GitHub 库复制的包装代码
我们需要运行的函数叫做launch()
。让我们回顾一下输入参数:
我们需要向它提供我们正在使用的机器的数量,对于这个帖子,我们将使用一台带有四个 GPU 的机器,所以num_machines=1
和num_gpus_per_machine=4
。使用多台机器时,machine_rank
用于指定机器的编号[或索引],例如,在分布式培训中使用多台机器时,machine_rank=0.
T5 用于提供主机 IP 地址,但由于我们只使用一台机器,因此我们可以使用dist_url=“auto”
,它将使用本地主机作为 IP 和自由端口。main_func
变量提供了我们代码的主要功能,这应该是到目前为止在 DataParallel 情况下运行您的流所使用的主要函数。最后,我们可以提供args
变量,这些都是我们的main_func
函数的输入参数。
在引擎盖下,launch 函数将使用 torch 多处理模块[torch.multiprocessing]和 spawn 函数旋转多个进程,这将启动作为新的子进程的进程-每个 GPU 一个。
值得注意的是,在运行启动函数后,完全相同的代码将同时在每个子进程中运行。因此,所有只需要在开始时运行一次的预设置代码,都应该在运行启动函数之前调用。例如,连接到您的实验管理器应用程序,从应该预先传递给所有进程的配置文件中获取参数,将数据同步到本地服务器,等等。
现在我们有了一个工作的包装器,我们可以调整我们的模型了。我们需要将在 CPU 上初始化的模型“转换”为分布式数据并行 GPU 模型。
如果在数据并行的情况下,我们需要用以下内容包装我们的模型:
model = torch.nn.DataParallel(model)
在分布式的情况下,我们将使用 DistributedDataParallel 类包装模型,这个调用将由每个进程独立完成。所以,我们首先需要弄清楚我们当前进程的“等级”是什么[等级基本上是我们的 GPU 索引],将模型从 CPU 复制到那个特定的 GPU,并将其设置为 DistributedDataParallel 模型:
broadcast_buffers
是一个重要的参数,它意味着在训练过程中是否要同步 GPU 之间基于统计的变量,例如 BatchNorm 层的均值和方差。
我们有了主包装器和模型,接下来我们需要调整数据加载部分。
在数据并行的情况下,我们有一个大小为 N 的单批,在向前传递期间,它会自动均匀地分布在我们的 4 个 GPU 上,为每个 GPU 提供大小为 N/4 的小批。现在,在分布式情况下,我们需要每个 GPU 进程从完整的样本批次中只读取与其小批次相关的样本。这是通过 PyTorch 分布式取样器完成的:
采样器根据我们拥有的流程数量分割样本,并为每个流程提供其迷你批次的相关样本索引。初始化采样器后,我们需要为 DataLoader 类提供这个采样器实例,并将其 shuffle 参数设置为 False。我们还需要调用采样器的set_epoch(epoch)
函数作为我们的历元 for-loop 的一部分,以在每个历元中获得不同顺序的训练样本。
至此,我们基本上拥有了三个主要组件:多进程包装器、定义为分布式类型的模型和处理数据加载部分的方法。接下来,我们将回顾我们可以在代码中进行的与日志记录、报告和度量计算相关的其他重要调整。
由于所有进程都运行相同的代码,使用打印和记录器向控制台(或文件)报告将会重复导致写入相同的打印。虽然有些消息可能很重要,并且与每个进程的报告相关,但是许多消息并不重要,我们可以使用下面的命令在主进程中只报告一次消息[这是我们的 0 级进程]:
if comm.is_main_process():
print(“something that is printed only once”)
当向外部工具报告指标或者保存模型权重时,这个技巧也很有价值。您可以使用它来确保一个动作在主流程的流程中只发生一次。
那么,指标呢?
使用 PyTorch DistributedDataParallel 模块,您不需要管理和“收集”[收集]所有进程的损失值来运行后退步骤,loss.backward()
将在幕后为您完成,并且由于它为每个进程运行,它将为所有 GPU 上的所有模型复制提供相同的梯度校正。
但是,这仅与反向过程中使用的损失值相关。为了报告实际损失值或它们的平均值,您需要收集每个进程的损失,并让主进程报告它们的平均值:
loss = criterion(outputs, labels)
...
all_loss = comm.gather(loss)
if comm.is_main_process():
report_avg(all_loss)
现在,all_loss
有了所有进程的损耗值,主进程可以对它们进行平均,累加,并报告需要什么。
请注意,gather
命令要求所有进程向主进程提供它们的值,从而降低了整个流程的速度。处理这个问题的一个更好的方法是让每个进程收集并存储它的损失值,并在每次迭代或在一个时期结束时运行收集。
其他重要评论:
- 一个有价值的技巧是能够在代码中的特定点同步所有进程,并强制它们相互等待。这可以解决以下情况:流运行,但由于某种原因挂起。查看
nvidia-smi
,您会发现所有 GPU 的利用率都为 100%,而一个 GPU 的利用率为 0%。这是一个令人沮丧的例子,发生在使用分布式模式时,可能是因为主 GPU 正在处理一些需要更多时间的事情,如保存和上传您的模型。在流程中的某些特定点强制过程同步可能会有所帮助,例如,当从评估步骤回到下一个训练时期时。这可以通过使用下面的命令用一个barrier
函数来完成:comm.synchronize()
这个函数在代码中放置一个屏障,强制所有进程等待其余进程到达并一起通过那个点😃。 - DistributedDataParallel 模块在进程之间传输信息,为此,PyTorch 会序列化属于数据加载器类的变量。这要求此类变量对序列化有效。这个错误提供了相当多的信息,所以当你面临这样的问题时你会知道。我在序列化部分日志实例时遇到了问题,因为它有一个过滤器使用了一个不适合序列化的不同类。
就是这样。我希望本指南将帮助您从 PyTorch 数据并行实现过渡到分布式数据并行机制,并享受它提供的好处和速度。
延伸阅读:
- https://pytorch.org/tutorials/beginner/dist_overview.html
- https://py torch . org/tutorials/intermediate/DDP _ tutorial . html # comparison-between-data parallel-and-distributed data parallel
- PyTorch 分发:加速数据并行训练的经验[【https://arxiv.org/pdf/2006.15704.pdf】T4
如何在 Python 中将循环转换成列表理解
原文:https://towardsdatascience.com/how-to-convert-loops-to-list-comprehension-in-python-15efcc696759?source=collection_archive---------10-----------------------
做同样的事,但要更快
照片由阿齐兹·阿查基在 Unsplash 上拍摄
列表理解用于创建基于可重复项的列表。它还可以被描述为用更简单、更吸引人的语法来表示 for 和 if 循环。列表理解相对来说比循环要快。
列表理解的语法其实很容易理解。然而,当涉及到复杂和嵌套的操作时,弄清楚如何构造一个列表理解可能会有点棘手。
在这种情况下,首先编写循环版本可以更容易地编写理解列表的代码。我们将通过几个例子来演示如何将循环语法转换成列表理解。
列表理解的基本结构(图片由作者提供)
让我们从一个简单的例子开始。我们有一个 5 个整数的列表,想要创建一个包含每一项的平方的列表。下面是执行此操作的 for 循环。
lst_a = [1, 2, 3, 4, 5]lst_b = []
for i in lst_a:
lst_b.append(i**2)print(lst_b)
[1, 4, 9, 16, 25]
同一任务的列表理解版本:
lst_b = [i**2 for i in lst_a]print(lst_b)
[1, 4, 9, 16, 25]
我们已经注意到列表理解是如何简化语法的。它是一个强大的一行程序。下图说明了这种转换。
(图片由作者提供)
列表理解从最后一个操作开始。然后,我们放置定义 for 循环的线。
列表理解中的运算可能比单一的数学运算更复杂。考虑下面的名字列表。
names = ["John Doe", "Jane Doe", "Mike Fence"]
我们希望创建一个只包含名字的列表。下面是完成此任务的循环:
first_names = []
for name in names:
first_names.append(name.split(" ")[0])print(first_names)
['John', 'Jane', 'Mike']
我们首先在空格字符处拆分名称字符串,然后取第一个单词。将这个循环转换为列表理解与前面的例子非常相似。
first_names = [name.split(" ")[0] for name in names]print(first_names)
['John', 'Jane', 'Mike']
我们也可以在列表理解中放置条件语句。让我们重复前面的例子,但有一个条件。名字列表将只包含以字母 j 开头的名字。
first_names = []
for name in names:
if name.startswith("J"):
first_names.append(name.split(" ")[0])print(first_names)
['John', 'Jane']
我们使用startswith
方法来应用期望的条件。相同的条件被添加到如下的列表理解中。
first_names = [name.split(" ")[0] for name in names if name.startswith("J")]print(first_names)
['John', 'Jane']
下图演示了这种转换。
(图片由作者提供)
我们把最后的操作放在列表理解的开头。然后,我们按照彩色框的指示,从上到下进行操作。
如果你遵循这个逻辑,你可以很容易地将复杂的循环转换成列表理解。让我们以一个稍微复杂一点的例子来结束。考虑下面的 3 个列表。
lst_a = [[4,3,5], [1,5,3,8], [1,6,2,4]]
我们希望创建一个新列表,包含嵌套列表中所有大于 3 的数字。
mylist = []for lst in lst_a:
for item in lst:
if item > 3:
mylist.append(item)print(mylist)
[4, 5, 5, 8, 6, 4]
执行此任务的列表理解是:
mylist = [item for lst in lst_a for item in lst if item > 3]
虽然这个循环比前几个循环更复杂,但将其转换为列表理解的逻辑是相同的。
它从循环中的最后一个操作开始。然后,我们沿着从上到下的循环。循环中的每一行在理解中都是连续的。
结论
一般来说,列表理解比循环更快。它通过将整个列表加载到内存中来提高速度。
当处理大型列表(例如 10 亿个元素)时,这种方法有一个缺点。这可能会导致您的计算机崩溃,由于内存需求的极端数额。
对于这种大型列表,更好的替代方法是使用一个生成器,它不会在内存中创建大型数据结构。生成器在项目被调用时创建它们。
感谢您的阅读。如果您有任何反馈,请告诉我。
如何将 XML 转换为平面表(Python)
原文:https://towardsdatascience.com/how-to-convert-xml-to-a-flat-table-python-f51576f569ad?source=collection_archive---------18-----------------------
图片由 Pixabay 提供
-这个故事描述了如何使用 REST API 将高度嵌套的 XML 转换为平面数据帧。-
在这个故事中,我们将探索如何使用这个免费的 REST API 将任何简单的嵌套 XML 转换成平面表。这个 REST API 利用一个作为概念验证开发的脚本,它推断任何嵌套 XML 的结构,组织数据,然后以清晰的结构化格式返回数据。
目前,API 只能将 XML 数据作为 Pandas 数据帧返回,但是您可以将数据帧导出/保存为您希望的任何数据格式。
它是如何工作的
用户登录和注册由 Amazon Cognito 管理,它处理用户凭证的生成和验证。这允许我们在限制 REST API 访问的同时轻松管理用户。
REST API 结合了亚马逊的 API 网关、AWS Lambda 和亚马逊 S3。Lambda 存放了我们的 XML 解释器代码,而 API Gateway 充当了我们调用 Lambda 的安全访问点。Lambda 还跟踪我们的用户请求。这种情况每天都会被跟踪,并以定制的日志格式(与我们的 CloudWatch 日志分开)记录到 S3,这样 Lambda 就可以验证任何用户每天调用 XML 解释器的次数都不能超过 4 次。
提供的 Python 脚本处理发送有效请求所需的 REST API 令牌的获取。由于 REST API 是受限制的,我们使用我们的 Cognito 登录凭证来生成我们的关联令牌,然后脚本自动将它传递给我们的 REST API 请求。然后,该脚本还处理 XML 编码、REST API 请求/响应处理,并将响应解码成数据帧。
如何使用 REST API
第一步:注册
您需要注册 REST API 凭证。你可以在这里这样做。滚动到页面底部,然后单击“注册”。
注册需要一个有效的电子邮件地址和您选择的密码。请务必点击您通过电子邮件收到的“验证”链接。
第二步:警告和注意事项
REST API 是免费提供的,因此随后受到限制。这意味着作为一个公共用户,我们每天只能发出 4 个请求,XML 解释器将只接受遵循以下准则的 XML:
- XML 字符限制为 4000 个字符(大约是本文后面提供的示例 XML 的两倍)。
- XML 文件必须而不是包含实体或其他 XMLdtd。
- 建议您的 XML 只包含属性和文本,如下面提供的示例所示。嵌套元素和属性的数量没有限制。
API/Lambda 已配置为在处理通过请求接收的任何 XML 之前扫描上述要求。
第三步:准备 XML 文件
请务必在上传之前检查您的 XML 文件,确保其格式正确并符合上面列出的要求。
如果没有 XML 文件,但想测试 XML 解释器,可以使用下面提供的示例 XML 代码。样本来自 Adobe 开源。随意编辑 XML,添加额外的嵌套元素、属性等。
步骤 4:创建您的 REST API Python 脚本
为了使用 REST API,我们需要使用我下面提供的脚本准备一个请求。只需将脚本复制并粘贴到 Python 文件或笔记本中,然后执行脚本:
注意:一定要用你的 XML 文件路径的路径替换 XML 文件路径。
该脚本将提示您输入之前创建的用户名和密码。如果登录凭证有效,它将自动编译 REST API 请求,编码您的 XML 数据,将其发送给解释器,然后返回您的平面熊猫数据帧。
恭喜,您刚刚使用 REST API 将您的 XML 转换成一个漂亮的平面数据帧!现在,您可以在 Pandas 中进一步操作您的数据,或者导出到您选择的文件类型。
如何将您的 Python 项目转换成可通过 pip 安装的包
原文:https://towardsdatascience.com/how-to-convert-your-python-project-into-a-package-installable-through-pip-a2b36e8ace10?source=collection_archive---------5-----------------------
编码教程,Python 基础
包含现成模板的教程,描述了如何将 Python 项目转换为 Python 包索引中可用的包。
克劳迪奥·施瓦茨在 Unsplash 上拍摄的照片
当你创建一个新的 Python 项目时,你可能不得不重用一些以前的代码,这些代码已经被很好地组织了。因此,您可以将之前组织良好的代码转换成一个包。
Python 包是一个实现某些东西的库,它不仅可以被你在下一个项目中利用,也可以被整个社区利用。
一个包应该被很好地记录,以便其他人可以利用它。出于这个原因,每个类或方法都应该通过 docstrings 进行文档化,正如这篇非常有趣的文章中所解释的那样。
在本教程中,我描述了如何将一个简单的 Python 项目转换成一个包,可以在 Python 包索引中找到。
项目的模板可以从这个库下载。
组织源文件
从代表包名的根目录(package_template
)开始,源文件应该位于名为src
的目录中:
package_template/
└── src/
└── package1/
| ├── __init__.py
| └── p1.py
└── package1/
├── __init__.py
└── p2.py
src
文件夹可能包含一个或多个子文件夹,每个子文件夹代表一个包。在上面的模板中,有两个包,package1
和package2
。每个包必须包含一个名为__init__.py
的空文件,它只是告诉 Python 该文件夹包含可以包含到其他脚本中的脚本。此外,每个文件夹必须包含所有需要的 Python 文件。
在所考虑的示例中,package1
包含一个名为p1.py
的文件,该文件实现了一个虚拟函数,该函数计算作为参数传递的一个数字和该函数生成的一个随机数之间的和:
from numpy.random import seed
from numpy.random import randdef p1_sum(a, s = 1):
seed(s)
b = rand(1)
return a + b
p1_sum()
功能接收以下参数作为输入:
a : float or int
—要求和的第一个数字s : int
—用于生成随机数的种子
第二个包,即package2
包含一个名为p2.py
的文件,它实现了一个类似的名为p2_diff()
的函数,该函数返回作为参数传递的两个数字之间的差:
def p2_diff(a,b):
return a-b
当您将安装整个软件包时,您将能够将p1_sum()
函数包含到如下脚本中:
from package1.p1 import p1_sum
创建打包文件
现在,我可以向我的项目添加将它转换成库所需的文件。在根目录中,我应该至少添加以下文件:
- README.md —文档的基本文件。该文件的内容将显示在 Python 包索引网站下的包主页中。
- 许可证—发布软件包所依据的许可证。
pyproject.toml
—包含指令的配置文件,告诉 build 和 pip 构建项目需要什么。setup.cfg
—setup tools用来构建包的配置文件。该文件包含关于作者、包版本以及其他被利用的包依赖项的信息。
README.md
README.md 文件包含使用标记语言编写的软件包的基本文档。通过这个非常有用的在线工具可以快速构建。
下面是一个非常基本的 README.md 文件:
# package_template
A Template to build a PIP package## Authors- [[@alod83](http://twitter.com/alod83)]([https://www.github.com/alod83](https://www.github.com/alod83))## InstallationInstall my-project with pip```bash
pip install package_template
```## Requirements* numpy
其呈现如下:
自述示例(图片由作者提供)
许可证
许多许可证是为了发布软件而存在的。最常见的自由和开放许可类型包括:
- 公共领域许可证,授予所有权利
- 许可许可证,授予使用权,包括重新许可的权利。这一类别包括麻省理工学院和阿帕奇许可证
- 保护性许可证,如 GPL,授予使用权,但禁止所有权。
pyproject.toml
如前所述,该文件包含构建包的指令。以下代码片段显示了 pyproject.toml 文件的一个非常基本的示例:
[build-system]requires = [
"setuptools",
"wheel"
]build-backend = "setuptools.build_meta"
require
变量指定了构建包所需的库。这不包括包所利用的库(即在单个脚本中导入的库)。
前面的例子指定了用于构建包的机制是setuptools
。
setup.cfg
以下代码片段显示了setup.cfg
文件的一个基本示例:
[metadata]name = package_template_YOUR-USERNAME-HERE
version = 0.0.1
author = Name Surname
author_email = author@example.com
description = A package template
long_description = file: README.md
long_description_content_type = text/markdown
url = [https://github.com/alod83/package_template](https://github.com/alod83/package_template)
project_urls =
Bug Tracker = https://github.com/alod83/package_template/issuesclassifiers =
Programming Language :: Python :: 3
License :: OSI Approved :: MIT License
Operating System :: OS Independent[options]
package_dir =
= srcpackages = find:
python_requires = >=3.6
install_requires =
numpy
metadata
部分包含一些基本信息,关于包的名称、作者、版本和其他类似的东西。为了发布软件包的新版本,可以更改本节中的版本号。
选项部分包含关于 Python 版本(在上面的例子中是 3.6 以上)和依赖项(由关键字install_requires
标识)的信息。
更多详情,关于setup.cfg
文件,可以查看本页。
生成分布
现在我可以生成分布了。我必须安装build
软件包,如果我还没有安装的话:
pip install build
安装完成后,我进入包的根目录,并运行以下命令:
python -m build
此操作可能需要一些时间。完成后,一个新目录出现在我的本地根目录中,名为dist
,包含两个主要文件:
package_template-YOUR-USERNAME-HERE-0.0.1.tar.gzpackage_template_YOUR_USERNAME_HERE-0.0.1-py3-none-any.whl
将包上传到测试 PIP 存储库中
这个包已经准备好部署在官方的 PIP 存储库中了!然而,在部署它之前,我强烈建议在测试 PIP 存储库中测试它,它不是官方的存储库,而只是一个测试库。
首先,我必须在测试存储库中创建一个新帐户,遵循这个链接。创建并激活新帐户后,我可以登录您的个人资料并生成令牌。我必须把这个令牌保存在别处,因为你再也看不到它了。
现在,我已经准备好上传测试存储库中的包了。我安装了twine
包,它将用于上传:
pip install twine
然后,我输入我的包目录的根目录,并运行以下命令:
python -m twine upload --repository testpypi dist/*
该命令将提示输入用户名和密码。使用__token__
作为用户名和您的令牌作为密码。
该过程完成后,会出现一个 URL,指定软件包的安装位置。
安装已部署的包
在安装新部署的包之前,我强烈建议您创建一个虚拟 env。您可以按照这个快速教程来构建一个新的虚拟 env。
可以通过以下命令安装部署的软件包:
python3 -m pip install --index-url https://test.pypi.org/simple/ --no-deps package_template
现在,您可以创建一个新的 Python 脚本来利用新部署的包:
from package1.p1 import p1_summy_sum = p1_sum(3)
print(my_sum)
最终部署
一旦测试了包的正确性,我就可以把它上传到 Python 包索引库中。
我必须选择一个原始名称,这将是我的包的正式名称!
我必须注册官方 Python 包索引网站。然后,我从我的包的根目录运行以下命令:
python3 -m twine upload dist/*
我输入我的凭证并按回车键。一旦这个过程完成,这个包就可以被世界上的每个人安装了:)
摘要
在本教程中,我在 Python 包索引中演示了如何将 Python 项目转换成可供所有 Python 社区使用的 Python 包。
过程非常简单:将项目文件夹组织成给定的结构并运行一些简单的 Python 命令来构建发行版就足够了。
你可以关注我的新网站:提示&数据科学技巧。
相关文章
https://medium.com/geekculture/the-top-25-python-libraries-for-data-science-71c0eb58723d
参考
如何用多种语言掩饰
原文:https://towardsdatascience.com/how-to-cover-up-in-multiple-languages-fe9cb4e9e39a?source=collection_archive---------25-----------------------
思想和理论
应用多语言命名实体识别模型进行匿名化
照片由来自像素的第三人拍摄
在我之前的帖子“用 Polyglot-NER 开启包容性的可能性”中,我介绍了 Polyglot 命名实体识别(NER)及其在文档匿名化中的应用。在本系列的第二部分中,我将:
- 概述匿名化问题
- 讨论我在上一篇文章中介绍的两个模型
- 展示 NER 评估的不同方法及其缺点
- 介绍应用多语言 NER 模型对巴西葡萄牙语法律文本进行匿名化的实验结果
在线提供的预先训练的多语言模型的进步是令人兴奋的。这可能会让人认为,对于任何任务和任何语言,都很容易找到适合您需求的模型。但事实并非总是如此!我们将在这篇博文中检验这一点:我们将采用一个预先训练的多语言模型,并将其与法律领域中预先训练的单语模型进行比较。
问题
像大多数 NLP 应用程序一样,NER 模型主要是在英语语言上训练的。另一方面,多语言模型是适用于多种语言的模型。这些模型有时被称为跨域模型,其中域指的是语言域。但是单词“域”在 NLP 中也可以有不同的含义,它可以指一种类型的文本。在 NLP 中,我们不仅有许多语言,而且还有许多领域。
这篇博文中的实验测量了一个多语言模型切换到这些其他类型的域的能力。我们采用一种在一般领域训练的多语言模型,并将其应用于法律领域。
型号:单语和多语言
在我之前的文章中,我介绍了两个模型:
- 单语模型:LENER-BR [1]
- 一个多语言模型:XLM-R-NER40 [2]
选择单语模型是因为它带有巴西葡萄牙语数据集,这是 NLP 研究中不常见的语言。正是我们要找的!选择这种多语言模式是因为:
- 它可以处理葡萄牙语(和 39 种其他语言)
- 实现在 Huggingface [3]上
- 就性能而言,它是最好的多语言机型之一
因为这个模型是贴在 Huggingface 上的,所以很容易应用。原则上,这很简单:
from transformers import pipeline
nlp_ner = pipeline(
"ner",
model="jplu/tf-xlm-r-ner-40-lang",
tokenizer=(
'jplu/tf-xlm-r-ner-40-lang',
{"use_fast": True}),
framework="tf"
)
现在你已经准备好用 40 种语言表演 NER 了!
XLM-R-NER-40 已经在葡萄牙语的通用领域进行了测试。所以,我们不想再这样做了!相反,我们正在法律领域进行测试。Plu 报告了以下分数[3]:
Plu 报告的葡萄牙语分数[3]
我们将多语言模型应用到单语模型的数据集。这是一个不同的数据集,而不是计算 Plu 提供的分数的数据集。[3]
评估
NER 模型用于预测文本中的实体,实体可能是隐私敏感的。如果我们想编辑这些敏感的实体,我们可以使用 NER 模型。
匿名化文档时,不管实体类型如何,都有三种可能的结果:
- 模型编辑过度,意味着我们编辑了太多的令牌
- 模型编辑不足,意味着我们编辑的令牌太少
- 这个模型编辑得很完美😊
一个好的评估方法可以量化一个模型在这三种结果中的表现。在我们进一步讨论之前,我们需要谈谈 IOB (Inside-Outside-Beginning)格式,这是注释命名实体最常用的格式。
通常,实体分布在多个令牌上。记号表示一个单词,或者在标点符号的情况下表示一个字符。让我们看看数据集中的一个实体:“高级军事法庭”。
IOB 格式的示例,图片由作者提供
在上图中,我们看到了第一个示例实体的原始标签和转换标签。顶部标签是原始标签,对于第二个实体,除了起始标签不同之外,转换是相同的。
在这个例子中有两种不同的实体类型:一个组织和一个人。然而,在我们的实验中,我们使用的是二元方法,我们对实体类型不感兴趣,只对实体是否存在感兴趣。我们决定采用这种方法,因为原始数据集的类比 XLM-R-NER40 模型的训练类多。
当我们想要分类单个 NE 时,有三种可能的结果:
- 该模型没有预测任何令牌是实体
- 该模型正确地预测了实体的开始和结束
- 模型正确预测了部分标记,但开头和/或结尾不匹配
让我们看一个虚构的句子,这样我们可以考虑使用 NER 匿名的一些复杂性。
考虑一下这个虚构的句子:
"联邦调查局发现比尔·克林顿在芝加哥的万豪酒店偷了一个公文包。"
当我们使用我们的模型来匿名化这个句子时,结果可能看起来像:
“在 X 的 X 处, X 发现 X 克林顿偷了一个公文包。”
好吧,我们正确地预测了 5 个实体标记中的 4 个,但是我们的系统有多大用处呢?我们完全匿名了这个文档吗?我们的模型有 80%的效率吗?这是一个很难回答的问题。
并非每个实体都具有相同的权重,这在上面的例子中显而易见。如果单词“芝加哥”而不是“克林顿”被错误归类,我认为这个句子最好匿名。某些实体比其他实体更敏感的事实在任何当前的 NER 评估中都没有得到体现。可以考虑的是一个模型完全预测的实体数量,我们将在本文后面看到。
我们实验使用的数据来自 LENER-BR 数据集,可以在他们的报告中找到。我使用了他们测试集中的三个文档。
首先让我们看看不考虑 IOB 的模型的准确性。
假设我们的文档包含 1000 个令牌。每个令牌都有自己的标签,这样我们总共有 1000 个标签。可能的标签是“ENT”和“O”。我们通过将每个预测与其对应的标签进行比较来评估模型,以查看它们是否相同。这叫精准。
当在其中一个测试文档(ACORDAOTCU11602016)上评估两个 NER 模型时,我们得到以下准确度分数:
- LENER-BR: 0.991
- XLM-NER 比率:0.866
乍一看,我们发现 LENER-BR 的表现比 XLM-R 好得多。但这是否意味着 LENER-BR 在匿名化文档方面有 99%的成功率,而 XLM-R 只有 87%的成功率?
为了回答这个问题,我们首先来看一个基线模型。假设我们有一个总是预测“O”作为标签的模型。承认这是一个愚蠢的模型,我强烈建议不要使用它。然而,它确实让我们洞察到训练模型的附加值是什么。对于这个模型和测试文档,准确性分数是:
- 多数基线:0.857
这些结果并不令人惊讶,因为文本中的大多数单词都不是新词。在一些文档中,只有 1%的标记是 ne,所以在这样的文档中获得 99%的准确率是非常容易的,但是没有用。在我们的实验中,准确性不是评价 NER 的有用指标。我们需要看看通常的嫌疑人,精度,召回,和 F1。因为这些指标提供了更多关于我们绩效的信息。例如,可能有很高的准确率,但在召回率和精确度上得分很低。
我们可以使用 Sklearn[4]中的分类报告函数来获得精确度、召回率和 F1 分数。我们来看文档 ACORDAOTCU11602016 的报告:
两个模型的分类报告,按作者分类的图像
精度告诉我们当模型说它是 X 时,它实际上是 X 的频率。召回告诉我们系统“捕获”了多少 X。虽然这份报告对于评估 NER 来说并不完美,但它比使用准确度得分提供了更多信息。例如,XLM-R-NER40 在 B-ENT 和 I-ENT 上的性能差异告诉我们,与属于一个实体的其他令牌相比,该模型在识别一个实体的开头时有更多的困难。它告诉我们,XLM-R-NER40 只在 34%的时间里捕捉到实体的开始。
到目前为止讨论的所有指标都适用于单个令牌,而不是多令牌实体。对于正确的匿名化,识别完整的多令牌实体(例如“Bill Clinton”)的能力是最重要的,幸运的是,seqeval [5]包可以为我们测量这一点。它产生一个分类报告,就像 sklearn 一样,但是要严格得多。这也有它的缺点。让我们看看下面这个由两个短句组成的例子:
gold_label = [
[‘B-ENT’, ‘O’, ‘O’, ‘O’, ‘O’],
[‘O’, ‘O’, ‘B-ENT’, ‘I-ENT’, ‘I-ENT’, ‘O’, ‘O’]
]predictions = [
[‘B-ENT’, ‘I-ENT’, ‘O’, ‘O’, ‘O’],
[‘O’, ‘O’, ‘B-ENT’, ‘I-ENT’, ‘O’, ‘O’, ‘O’]
]
我们有两个句子,两个句子中都有一个实体。在示例(1)中,第一个实体是“预测过度”,而在示例(2)中,该实体是“预测不足”。当我们将 seqeval 应用于这些示例时,我们得到:
两个示例的 seqeval 评分,图片由作者提供
哎唷,根据报告,我们做的和只预测‘O’一样糟糕。如前所述,seqeval 测量我们正确预测整个多令牌实体的次数。我们已经可以看到在我们的实验中使用它的一些缺点,因为说只预测“O”和上面的预测一样好是不完全公平的。
结果
鉴于每种方法的缺点,我将展示 seqeval 和 sklearn 报告。为了得到要点,你可以直接跳到结果表 4 。在表 2 中,我们不需要显示宏观/加权平均值,因为它相当于单个类的精度、召回率和 f1 值。
结果表 1:XLM-R-ner 40 的 sklearn 报告,图片由作者提供
结果表 2:LENER-BR 的 sklearn 报告,图片由作者提供
结果表 3:两种模型的 seqeval 报告,图片由作者提供
结果表 4:两种模型的平均 f1 分数,按作者分类的图像
两种类型的分类报告都清楚地表明,单语模型表现得更好。这并不奇怪,因为它是专门为此任务开发的。如果我们查看结果表 4 ,我们会发现使用 sklearn 评估方法,单语模型的性能是多语言模型的两倍。但是,使用 seqeval 方法,单语模型的性能是 seqeval 方法的 4.5 倍。结果显示了 XLM-R-NER40 模型在法律文本上的局限性。这并不意味着这是一个糟糕的模型,但重要的是要认识到我们可以用开箱即用的模型做的事情是有限的。
总结&结论
总而言之,在这篇文章中,我们看到了:
- 域切换的影响
- 我们如何相对容易地在网上找到多语言和单语模型
- 如何通过二值化将通用模型应用于具有更多类别的更具体的领域
- 评估 NER 的困难,尤其是在匿名化的背景下
我们已经看到了域名转换的影响,因为原始域名的原始分数远远高于合法域名的分数。这个实验中使用的两个模型很容易应用并在网上找到,因为其中一个在 Huggingface 上,另一个可以在 GitHub 上找到。我们必须得出结论,把一个多语言模型从盒子里拿出来并应用于任何任务都是有限制的。这说明了两件事,我们仍然需要 ML 工程专业知识,我们需要做更多的工作来创建可以在任何领域、任何语言上工作的模型。这样,任何人都可以用最少的 ML 工程知识来利用这些模型。
对于未来的工作,以特定于匿名化的方式重写评估方法将是有趣的。这将不得不考虑召回比精确更重要,同时仍然考虑过度匿名仍然是不可取的。如果有人真的对将 XLM-R-NER40 用于法律领域感兴趣,那么看看如果该模型针对法律领域进行微调,结果会如何将是很有趣的。
如果你想从我们的人工智能创新团队伙伴关系中了解更多关于更苗条的人工智能和最新研究,请访问我们的网站或我们在 Medium 上的人工智能创新页面。
参考文献
[1] Luz de Araujo,P. H .,de Campos,T. E .,de Oliveira,R. R. R .,Stauffer,m .,Couto,s .,& Bermejo,P. (2018)。LeNER-Br:巴西法律文本中命名实体识别的数据集。葡萄牙语的计算处理。斯普林格。doi:10.1007/978–3–319–99722–3 _ 32
[2] Conneau,a .,Khandelwal,k .,Goyal,n .,Chaudhary,v .,Wenzek,g .,Guzmán,f .,…Stoyanov,V. (2019)。大规模无监督跨语言表征学习。arXiv,1911.02116。从 https://arxiv.org/abs/1911.02116v2取回
[3]jplu/TF-xlm-r-ner-40-郎抱脸。(2021 年 6 月 22 日)。从 https://huggingface.co/jplu/tf-xlm-r-ner-40-lang取回
[4]中山博树。(2018).seqeval:一个用于序列标记评估的 Python 框架。
[5]sk learn . metrics . classification _ report。(2021 年 10 月 21 日)。检索自https://sci kit-learn . org/stable/modules/generated/sk learn . metrics . classification _ report . html
如何像专业人士一样破解 Python 错误
原文:https://towardsdatascience.com/how-to-crack-python-errors-like-a-pro-221ac76409af?source=collection_archive---------16-----------------------
当您手动破解一个异常时,您成为的开发人员比您修复的更重要。
照片由克里斯里德在 Unsplash 拍摄
Python 是一种更接近自然人类语言的高级编程语言。这样做的好处是 Python 代码很容易理解,实现起来也很简单。根据 2021 堆栈溢出调查,48%的开发人员使用它。在未来几年,这一比例肯定会继续增长。
事实上,Python 最初吸引了学者和专业人士,他们使用编码作为一种方法来原型化他们的想法、演示概念和实现概念验证。如今,Python 已经征服了包括 Devops 脚本,机器学习( NumPy , pandas , sklearn , Tensorflow 和 Web 后端( Django 和 Flask )在内的众多软件应用领域。
在这篇文章中,我为初学者介绍了一个破解 Python 错误的实用策略,首先展示了这个众所周知的异常ZeroDivision
的基本策略步骤,这个异常在下面的代码示例中出现。
Python 错误破解步骤举例说明
我们提出的错误破解策略包括三个步骤:(1)滚动直到你到达底部找到错误类型;(2)仔细检查出现在错误类型旁边的内嵌消息,以便理解它是如何发生的;(3)仔细查看函数调用的痕迹,并跟随水平箭头,直到您确定哪一行代码有问题。
ZeroDivisionError 是一个普遍的异常,它直接指出了根本原因。我们可以把它们看作是特定的异常,比如 FileNotFoundError 和 UnicodeError 。即使是初学者也可以在 StackOverflow(SO)上找到修复它们的代码配方。然而,也有一般的例外,大部分是由于打字错误和赶时间时的粗心大意造成的。尤其是当错误消息中的许多细节与您的应用程序代码有关时,由于可能原因的广泛可变性,googling 这些错误可能会产生误导。
其余段落将为您提供一些常见错误类型的概述和解释。上述破解方法可以更好地解决这些类型的错误。这样,你就可以节省大量阅读其他 SO 用户错误的时间和精力。此外,通过这个过程,您还将更加熟练地调试自己,这将教会您更多关于 Python 语言的知识。
语法错误
当分析器遇到语法错误时引发。— Python 官方文档
Python 解析器无法识别正在运行的程序中的标记结构或序列,这将导致语法错误。通常,这是由于缺少或不必要的字符,包括逗号、括号等。
引发的语法错误异常的 Python 代码段
在这个SyntaxError
的例子中,发生的错误的类型和消息清楚地表明代码语句在语法上是无效的。然而,故障定位的难度在它们之间是不同的。
- 第一个单元格: 我们看追溯来确定原因(这里,只有一行代码 1)。一个小的垂直箭头指出了这个错误行中语法错误的确切位置。所以,你已经发现了。去掉 for 循环之间的逗号。
- 第二个单元格: 原来代码行(11)不是出错的那一行,
SyntaxError
是因为第(9)行少了括号。然而,解析器错误地标识了这个位置,因为它期望在那里有一个右括号(而不是一个新的代码语句),但是它没有找到它。
因此,我们应该从SyntaxError
的指定位置开始逆向分析代码。如果不遵循这种自底向上的调试技术,您可能会发现自己正在搜索 StackOverflow,寻找与自己的上下文具有相似的关键字、名称和库的语法错误。
名称错误
找不到本地或全局名称时引发。— Python 官方文档
基本上,当开发人员试图使用一个不存在的变量或函数时,就会出现这个错误。
这通常是由于名称拼写错误造成的,例如在上面的例子中,我们将前面代码片段中的函数名称拼写错误。当开发人员忘记首先导入或声明变量/函数时,以及当他未能运行包含底层声明的单元格时,就会发生这种情况。
索引错误
当序列下标超出范围时引发。— Python 官方文档
简单地说,当开发人员试图访问序列中不存在的单元格(如 list、array 或 dataframe)时,就会遇到这种错误。
正如在所提供的代码示例中可以看到的,与IndexError
相关联的消息将包含有用的详细信息来排除故障。通常,该消息报告所请求的索引和单元格所属轴的大小。
键盘错误
在现有键集中找不到映射键时引发。— Python 官方文档
首先,开发人员在试图访问字典或数据帧中不存在的键时会遇到此错误。
看似简单,但我们有时会自动生成这些密钥,密钥的名称对我们来说意义不大。你可以在上面看到这个错误的例子,我在 while 循环中放了错误的条件i <= n
,而不是i < n
。
属性错误
当属性引用或赋值失败时引发。— Python 官方文档
每当开发人员试图从导入的对象或模块中访问不存在的变量/函数时,就会出现此错误。
上面的AttributeError
的例子通过调用accuracy
而不是score
说明了 scikit-learn 模型对象的误用。一旦您遇到这种类型的错误,您应该通过检查代码文件或底层库的正式文档来重新验证导入的对象或模块中是否存在该属性。
类型错误
当操作或函数应用于不适当类型的对象时引发。— Python 官方文档
顾名思义,此错误主要与变量/属性/对象的类型不正确有关。尽管如此,对其进行本地化通常很棘手。
- 第一个单元格: 错误类型及其伴随的消息极其明确。当我根据 Pandas 数据框中的其他列推断出一个列时,结果回溯包括了 Pandas 库中的许多子模块。因此,明智的做法是忽略熊猫的所有内部功能,专注于我们实际编写的代码部分和代码行。例如,代码行
df['Savings']=df['Income']-df['Expenses']
,我在其中推断出‘Savings’列,在回溯中被标记。要找到根本原因,简单检查一下列的类型就足够了。
额外提示:在检查回溯(步骤 3)时,主要注意你编写的模块中的函数调用。
- 第二个单元格: 不太直接的类型错误经常出现在函数或构造函数调用中。在这个例子中,我在模型构造函数的一个参数中犯了一个拼写错误。因此,追踪对我们来说用处不大。它只会帮助我们识别潜在的功能或对象。错误的参数关键字会出现在错误消息中。因此,我们需要查看文档或函数的源代码来找到错误并修复它。
- 第三个单元格: 这里我们在两个 NumPy 数组上调用 concatenate,但是 concatenate 期望一个数组列表被连接,而不是两个单独的参数。这是一个常见的错误,因为 Python 库可能会使用多个参数(即
def func(**args)
)或一个Iterable
类型的参数(即def func(args:Iterable)
)来声明处理相同变量类型的条目的函数。显然,错误消息没有说太多,因为解释器没有将变量转换成参数类型。因此,有必要验证官方库文档或底层函数的源代码,以找出根本原因。
值错误
当操作或函数收到类型正确但值不合适的参数时引发。— Python 官方文档
最后也是最重要的一点,ValueError
是由一个无效的参数值引起的,它阻止了函数完成任务。
上面的代码示例显示了使用大小不匹配的输入和目标来误用 scikit-learn 模型fit()
函数。由于模型fit()
是为处理这种错误而设计的,开发者已经包含了这个异常来提醒用户注意这个问题。否则,一些计算会失败,出现不太明显的异常,或者程序保持沉默,结果会不正确。为了展示开发人员对ValueError
的预期,让我们通过引发一个ValueError
来修复本文中的第一个代码示例,当用户将参数 b 赋值为零时,该代码就会出现。下面的代码片段显示了所需的更改。
最后的话
我很高兴你坚持到了最后。如果我能最终说服您停止在没有任何预先调试的情况下将整个异常复制粘贴到 Google 和 Stackoverflow 搜索栏中,希望找到一个现成的修复方法,那就好了。通过练习,您将能够快速定位这些错误并在编码过程中修复它们,而不必经历其他人共有的错误。
如何用 Excel 制作好看的绘图
原文:https://towardsdatascience.com/how-to-craft-good-looking-plots-with-excel-2f9006a28b7f?source=collection_archive---------17-----------------------
在 Excel 中制作好看的图表是不可能的?是的,这就是我用 Excel 创建漂亮图表的方法。
由米卡·鲍梅斯特在 Unsplash 拍摄的照片
对于大多数可视化,我使用像 Datawrapper 或 Tableau 这样的工具。它们提供了一种或多或少简单的方式来很好地可视化数据。但有时,您不能使用外部工具,可能是因为遵从准则,或者您希望在复杂的报表中重用您的图表。Excel 是大多数公司的标准,许多财务报告都有或多或少漂亮的可视化效果。这给了我一个想法,将 Excel 中的可视化带到 Datawrapper 默认主题的设计级别。说实话,这比我想象的要简单。Excel 能够创建整洁美观的图表。
免责声明:示例图的目的是表明实际数字并不比以前高。这不是关于确切的数字,而是要快速看到进展。它应该回答的问题是:
与前几周相比,德国对新冠肺炎感染的实际检测更多吗?
首先,让我们看看想要的结果。这是我用 Datawrapper 创建的折线图,并保存为 PNG 格式。
作者图片
当我在 Excel 中使用相同的数据并创建折线图时,我得到了以下默认结果:
作者图片
一点也不差。然而,它缺乏优雅和清晰。轴标签不好看,标题也相当无爱。
让我们深入了解一下我将默认 Excel 图表转换成设计良好的整洁图表的步骤。
清理和格式化轴
第一步是清理 x 轴和 y 轴并简化标签。我已经重新设置了标签的格式,目标是以缩略形式显示大量数据。
双击 y 轴显示每个格式选项。将边界最小值设置为 0,将最大值设置为 2000000。因为我不需要任何详细的步骤,所以我将单位主要和次要配置为 1000000。现在我们的 y 轴标签只有 0,10000000 和 2000000。
在 Excel 中设置坐标轴格式
老实说,标签太大了,我们需要重新格式化。这就有点棘手了——也许是最棘手的部分。对于缩写,数字必须格式化。转到格式轴中的数字部分,添加新的格式代码。我用过[>0]#.."M";""
。
那里发生了什么?这是条件格式,由两部分组成,用;
隔开。让我们来分解一下:
[>0]#.."M"
表示“对于每一个大于 0 的数字,用 m 缩写成百万”""
说什么都不加。我用这个来省略基轴的 0。
如你所见,我不喜欢负数。点击“添加”添加格式,y 轴标注干净好看。
在 Excel 中添加格式代码
现在我们把手放在 x 轴上。在我们最终的剧情中,我们不需要所有的标签。像以前一样,双击 x 轴打开格式选项。要生成类似 Datawrapper 的标签,需要将标签的特定间隔单位设置为 6。这意味着仅使用第六个值。
在 Excel 中设置具体的间隔单位
暂时就这样了。稍后当我们调整颜色、字体和线宽时,我们将回到这两个轴。
添加注释
我的可视化应该包括行尾最近的数字。选择最近的数据点,点击右键,选择添加数据标签。
在 Excel 中添加数据标签
标签的位置并不完美。右边没有足够的空间。我们需要缩小图表的尺寸。重要的是选择绘图区,而不是图表区!
缩小尺寸,我们的标签就在数据点旁边。如果没有,就把它移到你想看的地方。我们稍后将格式化字体和颜色。
一个漂亮的头球
Excel 中的默认标题很难看。您无法正确格式化它们。没有机会对齐,也没有增加一个子行。这就是为什么我刚刚删除了标题,并添加了两个新的文本区域,分别是标题和副标题。为了给标题留出足够的空间,您可能需要再次调整绘图区的大小。现在只需使用插入- >文本框在 Excel 功能区添加一个文本框。
在 Excel 中插入功能区
添加一些漂亮的错别字
当我们添加标题时,让我们来谈谈字体大小。对于合适的字体大小,我使用 Type-Scale.com 来了解字体大小对用户的影响。我使用 Roboto 作为字体和以下尺寸。
- 标题: 22
- 子行: 14
- 轴标签: 12
- 页脚: 9
要设置和调整字体大小,只需点击标签、轴或文本框,并使用 Excel 中开始功能区的字体选择器设置您的值。
在 Excel 中设置字体、字号和颜色
这同样适用于颜色。我使用#888888
作为轴标签,使用#000000
作为标题和副标题。
微调
最后,让我们微调可视化。第一步是有一个稍微宽一点的基线。双击 x 轴,选择填充&线条,设置宽度为 1pt,颜色为#000000
。
在 Excel 中格式化地块线
此后,我们将 y 标签的线条变亮。双击 1M 处的线,将颜色设置为#D9D9D9
并将宽度设置为 0,75pt。
如果你喜欢,你可以把曲线弄圆,调整颜色。再次双击图表的线条,选择填充&线条 → 线条并激活平滑线条。我已经将线宽设置为 2 磅,颜色设置为#B92717
在 Excel 中设置线条颜色和平滑线条的格式
不要忘记添加页脚。您可以在此图表中插入您的姓名和来源链接。只需添加另一个文本框,并将其移动到图表的底部。您可能需要再次减小地块面积,以便能够保持合理的距离。
仅此而已。下面是用 Datawrapper 绘制的图表和我用 Excel 创建的图表的比较
左:来自 Datawrapper 的原始数据|右:直接从 Excel 导出的绘图
将其保存为模板
获得好看的可视化效果有很多步骤。而且说实话,我不想一遍又一遍的走完每一步。幸运的是,Excel 允许我们保存所有设置的模板。右击图表并选择另存为模板。
另存为模板
有了模板,我们可以在图表上应用我们的新样式。只需绘制一个默认图表,点击右键,选择更改图表类型并从模板中选择
应用模板
结论
您可以看到,使用 Excel 创建好看的可视化效果并不困难。你不需要生活在默认的情节中。这并不意味着他们是无用的。如果您想可视化上下文以获得洞察力,缺省值就足够了。但是对于一些报告来说,不使用其他工具,花一些时间来创建整洁美观的图表是值得的。
如果您想创建好看的图表,您可以花一些时间定制并保存为模板,使用您的 CI 和好看的排版。
如何在 Python Plotly 中创建一个美化的组合图
原文:https://towardsdatascience.com/how-to-create-a-beautify-combo-chart-in-python-plotly-ddbe39874002?source=collection_archive---------14-----------------------
没有人会否认线形和条形组合图是使用最广泛的组合图之一。在 Excel 中,有一个组合图的内置功能。它也是分析金融数据最流行的图表之一。
在本教程中,我们将使用 plotly 构建一个自定义的组合图。完成后的组合图将如下所示。
1.导入库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import plotly.graph_objects as go
%matplotlib inline
2.创建用于数据可视化的数据框架
Amazon_Financials ={'Year': [2009, 2010,2011,2012,2013,2014,2015,2016,2017,2018,2019],
'Revenue($M)': [24509, 34204,48077,61093,74452,88988,107006,135987,177866,232887,280522],
'Profit($M)':[5531,7643,10789,15122,20271,26236,35355,47722,65932,93731,114986]}df = pd.DataFrame(data=Amazon_Financials)
数据集非常简单。它包含了 Amazon.com 公司在 2009 年到 2020 年间的收入和利润数据。
亚马逊 2009 年至 2020 年的收入和利润
3.画一个简短的组合图
fig = go.Figure()fig.add_trace(
go.Scatter(
x=df['Year'],
y=df['Revenue($M)'],
name="Revenue"
))fig.add_trace(
go.Bar(
x=df['Year'],
y=df['Profit($M)'],
name="Profit"
))fig.show()
可以清楚地看到,横坐标和纵坐标上的轴标签的字体有点小,很难阅读。x 轴的标签没有完全显示。并且刻度线对于确定每根棒线的真实数值没有太大帮助。第一步是放大轴标签的字体并移除刻度线。图例或图表没有标题。需要添加标题来向最终用户提供图表主题的信息。
4.向图表的条形图和标题添加批注
fig = go.Figure()fig.add_trace(
go.Scatter(
x=df['Year'],
y=df['Revenue($M)'],
name="Revenue"
))fig.add_trace(
go.Bar(
x=df['Year'],
y=df['Profit($M)'],
name="Profit",
text = df['Profit($M)'],
textposition='outside',
textfont=dict(
size=13,
color='#1f77b4')
))
fig.update_traces(texttemplate='%{text:.2s}')
fig.update_layout(legend_title_text='Financials',
title_text='2009-2019 Financial Report')fig.show()
5.更改图表的颜色和字体
在本例中,线条的颜色将变成“耐火砖”。您也可以使用十六进制颜色代码或 RBG。条形将变为浅蓝色,周围有线条,以增强条形的可见性。我还把条形做得有点透明。背景颜色变为浅灰色。标注 x 轴和 y 轴是为了避免混淆。
import plotly.graph_objects as gofig = go.Figure()fig.add_trace(
go.Scatter(
x=df['Year'],
y=df['Revenue($M)'],
name="Revenue",
mode='lines+markers',
# mode = 'lines', if you don't want the markers
marker={'size':9},
line = dict(color='firebrick', width=3)
))fig.add_trace(
go.Bar(
x=df['Year'],
y=df['Profit($M)'],
name="Profit",
text = df['Profit($M)'],
textposition='outside',
textfont=dict(
size=13,
color='#1f77b4'),
marker_color='rgb(158,202,225)',
marker_line_color='rgb(17, 69, 126)',
marker_line_width=2,
opacity=0.7
))# strip down the rest of the plot
fig.update_layout(
showlegend=True,
plot_bgcolor="rgb(240,240,240)",
margin=dict(t=50,l=10,b=10,r=10),
title_text='2009-2019 Financial Report',
legend_title_text='Financials',
xaxis_tickfont_size=14,
yaxis=dict(
title='USD (millions)',
titlefont_size=16,
tickfont_size=14,
),
legend=dict(
x=0.01,
y=0.99,
bgcolor='rgba(255, 255, 255, 0)',
bordercolor='rgba(255, 255, 255, 0)'
),
bargap=0.15
)
fig.update_traces(texttemplate='%{text:.2s}')fig.show()
6.最后润色
仍然需要一些小的调整,以使图表更丰富,更少混乱。
x 轴没有所有年份
两个轴的字体都非常小
图表的标题应该居中
fig = go.Figure()fig.add_trace(
go.Scatter(
x=df[‘Year’],
y=df[‘Revenue($M)’],
name=”Revenue”,
mode=’lines+markers’,
# mode = ‘lines’
marker={‘size’:9},
line = dict(color=’firebrick’, width=3)
))fig.add_trace(
go.Bar(
x=df[‘Year’],
y=df[‘Profit($M)’],
name=”Profit”,
text = df[‘Profit($M)’],
textposition=’outside’,
textfont=dict(
size=13,
color=’#1f77b4'),
marker_color=’rgb(158,202,225)’,
marker_line_color=’rgb(17, 69, 126)’,
marker_line_width=2,
opacity=0.7
))# strip down the rest of the plot
fig.update_layout(
showlegend=True,
plot_bgcolor=”rgb(240,240,240)”,
margin=dict(t=50,l=10,b=10,r=10),
title_text=’2009–2019 Financial Report’,
title_font_family=”Times New Roman”,
legend_title_text=’Financials’,
title_font_size = 25,
title_font_color=”darkblue”,
title_x=0.5,
xaxis=dict(
tickfont_size=14,
tickangle = 270,
showgrid = True,
zeroline = True,
showline = True,
showticklabels = True,
dtick=1
),
yaxis=dict(
title=’USD (millions)’,
titlefont_size=16,
tickfont_size=14
),
legend=dict(
x=0.01,
y=0.99,
bgcolor=’rgba(255, 255, 255, 0)’,
bordercolor=’rgba(255, 255, 255, 0)’
),
bargap=0.15
)
fig.update_traces(texttemplate=’%{text:.2s}’)
fig.show()
现在这个图表看起来比最初的版本好多了。我们可以通过引入更多的定制来进一步美化图表。
6.增强的定制
我们可以改变标记的形状和颜色,也可以改变那些条形的颜色,使图表更加令人印象深刻。
import plotly.graph_objects as gofig = go.Figure()fig.add_trace(
go.Scatter(
x=df['Year'],
y=df['Revenue($M)'],
name="Revenue",
mode='lines+markers',
# mode = 'lines'
marker= dict(size=9,
symbol = 'diamond',
color ='RGB(251, 177, 36)',
line_width = 2
),
line = dict(color='firebrick', width=3)
))fig.add_trace(
go.Bar(
x=df['Year'],
y=df['Profit($M)'],
name="Profit",
text = df['Profit($M)'],
textposition='outside',
textfont=dict(
size=13,
color='#1f77b4'),
marker_color=["#f3e5f5", '#e1bee7', '#ce93d8', '#ba68c8','#ab47bc',
'#9c27b0','#8e24aa','#7b1fa2','#6a1b9a','#4a148c','#3c0a99'],
marker_line_color='rgb(17, 69, 126)',
marker_line_width=1,
opacity=0.7
))# strip down the rest of the plot
fig.update_layout(
showlegend=True,
plot_bgcolor="rgb(240,240,240)",
margin=dict(t=50,l=10,b=10,r=10),
title_text='2009-2019 Financial Report',
title_font_family="Times New Roman",
title_font_size = 25,
title_font_color="darkblue",
title_x=0.5,
xaxis=dict(
tickfont_size=14,
tickangle = 270,
showgrid = True,
zeroline = True,
showline = True,
showticklabels = True,
dtick=1
),
yaxis=dict(
title='USD (millions)',
titlefont_size=16,
tickfont_size=14
),
legend=dict(
x=0.01,
y=0.99,
bgcolor='rgba(255, 255, 255, 0)',
bordercolor='rgba(255, 255, 255, 0)'
),
bargap=0.15
)
fig.update_traces(texttemplate='%{text:.2s}')fig.show()
如果你想用一个变量/特征来定义条形的颜色,简单的替换
fig.add_trace(
go.Bar(
x=df['Year'],
y=df['Profit($M)'],
name="Profit",
text = df['Profit($M)'],
textposition='outside',
textfont=dict(
size=13,
color='#1f77b4'),
marker_color=["#f3e5f5", '#e1bee7', '#ce93d8', '#ba68c8','#ab47bc',
'#9c27b0','#8e24aa','#7b1fa2','#6a1b9a','#4a148c','#3c0a99'],
marker_line_color='rgb(17, 69, 126)',
marker_line_width=1,
opacity=0.7
))
随着
fig.add_trace(
go.Bar(
x=df['Year'],
y=df['Profit($M)'],
name="Profit",
text = df['Profit($M)'],
textposition='outside',
textfont=dict(
size=13,
color='#1f77b4'),
marker_color=df['Profit($M)'],
marker_line_color='rgb(17, 69, 126)',
marker_line_width=2,
opacity=0.7
))
然后你会得到一个像这样的组合图,
最后,让我们最后看一下前后图表。
美化后的图表更加清晰,能向观众传达更多的信息。标签和标题也能提供信息。网格线有助于确定每个条形的实际数量。
如何创建引人注目的 Github 产品组合
原文:https://towardsdatascience.com/how-to-create-a-compelling-github-portfolio-a229e7472a92?source=collection_archive---------1-----------------------
用 Github 页面构建 Github 文件夹
罗曼·辛克维奇在 Unsplash 上拍摄的照片
如果你写代码,你需要一个投资组合——很简单!
作品集可以让你展示你做过的工作样本,这些样本可以作为一份数字简历,证明你拥有你在简历中所说的技能。
如果你是前端或后端开发人员,从头开始建立自己的网站是有好处的。但是如果你像我一样,是一个机器学习工程师,那么你会理想地选择最简单的选项。
在我看来,这意味着使用 Github 页面。Github Pages 是 Github 提供的免费托管服务,它可以直接从 Github repo 中获取 HTML、CSS 和 JavaScript 文件。
我的作品集里可以放些什么?
在某种程度上,你会想要加强你的 Github 投资组合,以确保潜在的客户/雇主不会轻易接受你的申请。然而,知道什么可以放在你的投资组合中并不是一件简单的事情。这里有一些你可能想放入你的文件夹的想法;
- 作业&课程作业:这可能不是你最高质量的作品,但这并不意味着它不值得成为你作品集的一部分。你在学校或通过课程收到的所有编程作业和课程作业仍然是有价值的项目,但请记住,如果 50,000 人参加了同一门课程并分享了相同的东西,那么如果你想脱颖而出,你必须做得更多。
- 独立项目:独立项目(或个人项目)对任何想要提升技能的人的发展都至关重要。将这作为你投资组合的一部分是必须的,也是最有可能抓住潜在客户/雇主注意力的。
- 重复研究:当我们想在更深层次上学习一些东西时,重新发明轮子总是一个好主意。对于数据科学家来说,这可能意味着使用一篇研究论文从头编码一个神经网络。
- 比赛:如果你曾经决定参加比赛,那么分享你是如何公平的是一个很大的进步。尽管许多人觉得竞赛并没有复制真实世界的场景,但我觉得仍然有很多价值可以从中获取,它们绝对应该作为你投资组合的一部分(如果你能在竞赛中排名靠前就更好了)。
- 博客& Vlogs: 如果你以博客或 vlog 的形式创建内容,那么它也应该被包括在内。我觉得这是展示软技能和技术知识的好方法。
理想情况下,任何能给你带来优势、突出你的优势、向招聘人员/潜在客户展示你有能力用你的编程能力增加价值的东西,都应该放在你的文件夹里。
创建一些解释清楚的博客帖子、内核或 markdown 来解释你正在做的事情也是一个好主意,这样你就可以迎合可能会购买你的投资组合的非技术受众。
创建投资组合
如前所述,我是一名机器学习工程师,之前没有太多关于 web 开发的知识——尽管我曾在一家专门从事 web 开发的数字营销机构工作过,所以我有一些接触领域,并知道一些关于它的小细节。
因此,我不会强迫自己去学习如何创建一个网站,我只是要使用一个文件夹样板,重构它以适应我的需要,并使它成为我自己的;一旦我对它的外观感到满意,我会把它放在 Github 上。
步骤 1 —选择投资组合模板
第一步是选择你想要使用的投资组合样板。要找到一个免费的样板模板,你可以利用你的谷歌搜索技能——谷歌“免费 HTML 样板模板”或“免费 HTML 文件夹模板”和 wala!
注意:对于我的作品集网站,我使用了网站 HTML5up ,它是由一个叫 Joshua Fluke (这篇文章的灵感来自于他)的网站开发者在他的 youtube 频道上推荐的。
HTML5up.net 的 HTML 样板示例;作者图片
一旦您看到了想要的样板文件,您需要下载样板文件,以便我们可以应用一些修改来获得符合我们需要的样板文件。
步骤 2 —重构样板文件
这一步需要一点点 HTML 知识,但没有什么是几个小时内学不会的;下载完模板后,提取所有文件,并在您选择的 IDE 中打开文件夹——我使用 PyCharm。
在您的 IDE 中,导航到index.html
模块并将其打开。接下来,您需要右键单击代码中的任意位置并选择“在浏览器中打开”,然后选择您选择的浏览器——这样您就可以看到代码和您正在构建的页面,从而了解您对代码所做的更改如何影响浏览器中的页面。
经过一些重构后,我的样板文件的预览;作者图片
步骤 3——在 Github 上托管
最后一步是在 Github 上创建一个新的存储库。为了利用 Github Pages 托管服务,存储库名称的格式应该如下your_username.github.io
。对我来说,那就是“ kurtispykes.github.io ”。
在 Github 上创建 GithubPages 存储库
我建议在下一阶段学习 Git,但是最初,我们可以通过选择“上传现有文件”选项来上传文件,然后我们拖放单个文件并将它们提交给 Github。
亲自看看我的作品集…
https://kurtispykes.github.io/
最后的想法
如果你是自由职业者/承包商,或者如果你是在职员工,作品集是向潜在客户展示你能力的绝佳方式。我个人认为,每个在工作中使用代码的人都应该有一个文件夹,因为这可能是最好的证据形式,也可以作为你的电子简历。
感谢阅读!
如果你喜欢这篇文章,请通过订阅我的免费周刊与我联系。不要错过我写的关于人工智能、数据科学和自由职业的帖子。
相关文章
** 💔-reasons-why-you-should-have-a-data-science-blog-cdc1d4b0e8f4> **
如何使用 Dialogflow 创建对话代理
原文:https://towardsdatascience.com/how-to-create-a-conversational-agent-with-dialogflow-17bfa90aa02d?source=collection_archive---------31-----------------------
自然语言处理笔记
构建我自己的“FastFoodz”聊天机器人
由安迪·凯利在 Unsplash 上拍摄
什么是 Dialogflow?
Dialogflow 是 Google 设计的云 API,用于帮助开发对话代理。Dialogflow 文档对 Dialogflow 的描述如下:
Dialogflow 是一个自然语言理解平台,可以轻松设计对话式用户界面并将其集成到您的移动应用程序、web 应用程序、设备、机器人、交互式语音响应系统等中。使用 Dialogflow,您可以为用户提供新的、引人入胜的方式来与您的产品进行交互[ Source : Dialogflow 文档。
我虚构了一家名为 FastFoodz 的餐厅;对于更多的背景,FastFoodz 餐厅将基于我最喜欢的当地快餐店之一,名为 Laaghas。
Laaghas 有一些最好的华夫饼三明治。每个华夫饼干三明治里面有不同的内容(例如,我们可以有鸡蛋、培根、鸡肉等。)并且它也可以带有外壳或去掉外壳。此外,我们可以选择添加额外的食物,如薯条、辣鸡翅、苹果酥和/或饮料。基于这些要求,我们将构建一个聊天机器人,它将能够为我们执行完整的订单流程。
构建我们的代理
在构建我们的代理之前,我们必须首先完成必要的设置过程——这非常简单。只需导航到 Dialogflow 网站并使用您的 Google 凭据登录。为了避免被收费,请确保您选择了“免费试用”选项,这将带您到谷歌云服务进行进一步的注册过程。
代理创建
这可能是最明显的一步;我们必须创造我们的代理人。在 Dialogflow 仪表板的左上角,有一个“创建代理”选项卡。我们只需选择它并为我们的代理提供一个名称。我正在创建的机器人是为我想象中的快餐店 FastFoodz 设计的。
代理命名约定的一个良好实践是为代理提供一个代表代理用途的名称。在我的例子中,我将简单地命名我的 FastFoodz 商店代理 FastFoodzBot 。
注意:在选择“创建”按钮之前,还要确保您的代理的时区是正确的。
图 1 :创建我们的 FastFoodBotz 代理——请忽略页面底部的错误消息;作者 GIF。
意图
对话流文档描述了如下意图…
意图将终端用户的意图分类为一个对话回合。对于每个代理,您定义了许多意图,其中组合的意图可以处理一个完整的对话。当最终用户写或说一些东西时,称为最终用户表达,Dialogflow 将最终用户表达与您的代理中的最佳意图相匹配。匹配意图也被称为意图分类。
默认情况下,在创建我们的第一个代理时,我们有 2 个意图;
- 默认回退意图适用于我们的代理无法识别我们的最终用户希望表达的确切内容的情况。谷歌为此提供了各种静态响应,比如“对不起,我没明白。能不能换个说法?”。
- 默认欢迎意图在最终用户开始与我们的代理对话时非常有用。欢迎意图应该返回一个响应,通知最终用户代理的功能是什么,或者用户可以做什么来开始对话。谷歌还在他们的文档中预装了意向回复,他们建议应该对其进行定制。
为了创建我们的第一个意图,我们导航到侧面板,将鼠标悬停在“意图”标题上,并选择“+”符号。
我们将创建的第一个意图将被称为“orderWaffleSandwich”
每个意图都需要训练样本——谷歌称之为“训练短语”——这样我们的机器人就能够识别出哪种反应属于特定的意图。
图 2: 创建我们的第一个意图,并添加一些训练短语;作者图片
注意:每一节结束后一定要保存你的工作
实体
现在我们已经包含了一个意图,我们需要添加实体,以便我们的代理能够记住用户提供的重要信息。要实现这个功能,我们应该导航到左栏中的“实体”部分。
我们将创建的第一个实体将被命名为“ waffleSandwichType”。对于此实体,确保启用“模糊匹配”,因为这将允许我们的代理匹配实体,即使它们大致相同。
图 3 :创建 waffleSandwichType 实体,该实体将确定华夫饼三明治是否有外皮;作者图片
我们将创建的第二个实体将被命名为“wafflesandvichcontents”。对于该实体,确保启用了“模糊匹配”和“定义同义词”——定义同义词允许我们同时定义同义词,并将定义为同义词的几个词匹配到同一个实体。
图 3 :创建 waffleSandwichContents 实体,该实体决定将不同的内容放入我们的三明治中;作者图片
动作和参数
为了完成订单,我们需要华夫饼的类型和用户想要的华夫饼内容。一个华夫饼干三明治不能既有面包皮又没有面包皮,但是它可以有不同的内容。
为了确保我们得到所需的华夫饼类型和大小,我们必须返回到 intents 部分并导航到“Action and Parameters ”,然后将我们的 2 个实体添加到 actions 中,并确保选中所需的框。
记得我们说过三明治里可以有不同的内容吗?为了确保该行为被代理捕获,我们必须为 waffleSandwichContents 操作选择“isList”。
图 4: 添加动作和参数;作者图片
在图 4 中,你可能会注意到我给每个动作都加了一个提示。简而言之,提示通过向用户提出后续问题来帮助我们收集更多关于订单的信息。后续问题的一个例子是“你想要带皮的华夫饼还是不带皮的?”用于 waffleSandwichType 操作。
反应
我们还需要迎合用户可能想要的任何附加组件,因此我们的代理需要一些响应。有了响应,我们可以问用户他们是否想要一些饮料、配菜或甜点。
图 5 :向我们的代理添加响应;作者图片
语境
到目前为止,我们构建的代理非常简单。为了增加一点复杂性,我们可以引入谷歌所说的“上下文”。
对话流语境类似于自然语言语境。如果一个人对你说“他们是橙色的”,你需要上下文来理解“他们”指的是什么。类似地,为了让 Dialogflow 处理这样的最终用户表达式,需要为它提供上下文,以便正确地匹配意图。— 对话流文档
考虑陈述“我想要购买芬达的 1L 和 6 个烧烤鸡翅”。至关重要的是,我们的代理能够识别数量,以及用户想要订购的项目。为了将它合并到我们的代理中,我们必须创建一个自定义实体。
图 6 :创建 compositeSide 自定义实体
compositeSide 自定义实体将允许我们标识数量以及识别用户请求的项目。例如,在“@ sys . number-integer:number-integer @ drinks:drinks”中,第一个值处理识别已点的饮料数量,第二个值处理饮料。
测试解决方案
正如在任何软件项目中一样,测试我们的代理是开发阶段的一个重要部分。为了执行测试,我们可以在“web demo”模式下打开我们的 bot,方法是导航到侧面板上的“Integrations”选项卡,并向下滚动到“Text based ”,在那里您将看到 Web Demo。
图 7 :用一个简单的订单测试我们的代理;作者 GIF
目前,该机器人能够处理非常简单的查询,以订购华夫饼三明治。当我们希望测试代理的单个组件时,web demo 特性非常有用,这反过来允许我们在端到端测试阶段之前快速构建原型并捕捉极限情况。
资源
要了解更多关于使用 Dialogflow 构建聊天机器人的信息,我强烈推荐你阅读 实用自然语言处理:构建真实世界自然语言处理系统综合指南 。
注意:点击上面的链接,你将通过我的会员链接被导向亚马逊。我还集成了地理链接,所以如果你不在英国,你会被自动引导到你当地的亚马逊商店。
包裹
本 Dialogflow 教程绝不是对该框架功能的详尽展示;为了使代理更加健壮,我们需要为当前的代理添加更多的意图和实体——这将改善顾客在 FastFoodz 餐厅购买华夫饼三明治的体验。
感谢您的阅读!
如果你喜欢这篇文章,请通过订阅我的免费每周简讯与我联系。不要错过我写的关于人工智能、数据科学和自由职业的帖子。
相关文章
** [## 聊天机器人一瞥
towardsdatascience.com](/a-brief-look-at-chatbots-98cfc846b0f7) **
如何为您的组织创建数据策略
原文:https://towardsdatascience.com/how-to-create-a-data-strategy-for-your-organization-e0493110b2e7?source=collection_archive---------25-----------------------
人工智能笔记
创建可靠数据战略的三个基本支柱
照片由赞·李在 Unsplash 上拍摄
在这里,我想用简单的话来定义数据策略,并帮助您为您的组织创建一个数据策略。近年来,数据已经成为公司的战略资源,每个公司都必须制定数据战略,以免输给竞争对手。主要问题是怎么做?要回答这个问题,你首先要了解什么是数据策略。然后,您必须创建一个适合您的组织的计划,了解其局限性和能力。简而言之,数据策略有三个基本支柱:(1)价值,(2)收集,以及(3)架构。数据策略确实有我在本文中没有涉及的其他方面。如果你在这些支柱中的任何一个失败了,你就达不到你的期望。
我决定写这篇文章,在收到许多关于我的前一篇文章的积极反馈之后,这篇文章的标题是关于进行大规模数据收集的途径,在这篇文章中,我分享了一些见解,以防止在进行数据收集时的常见错误。
https://medium.com/dataseries/on-the-path-to-conducting-a-large-scale-data-collection-8a8cd201543d
价值
数据策略必须描述如何使用数据在组织中产生商业价值。有两种主要方式:(a) 构建基于数据的产品或服务(外部产品);以及(b) 创建报告并获得洞察力(内部产品)。数据战略必须与企业战略(特别是数字化战略)保持一致,不能孤立进行。这就是为什么它必须由企业主决定和批准;否则永远不会超越婴儿期。
你可以建立一个基于数据的产品或服务,在现有的基础上创造收入。例如,一家开发电子邮件设计器的公司可以为其客户添加一个基于数据的推荐系统,以更容易地创建电子邮件,或者更好的是,使它们更具吸引力。您还可以使用数据来获得洞察力并创建报告,以便增强当前的业务流程。例如,一家食品公司可以在分拣阶段使用数据驱动的报告来衡量其产品的质量。这将有助于公司提高流程效率。
收藏品
我先举个例子。你想要抓取 RottenTomatoe 网站并收集数据。您运行 web scraper 一天,第二天,您会发现应该记录了另一个数据字段。这个过程必须重复。你经历过类似的场景吗?这可能发生在大规模的数据收集中,并且是有害的。大规模的数据收集是一个昂贵的过程,因此在进行之前,您必须回答以下问题,例如(a) 必须记录哪些领域的数据? (b) 必须如何衡量数据质量? (c) 收集干净数据的可扩展方式是什么?
数据质量是决定实施数据策略成功几率的主要因素。这就是为什么数据科学家的一个常见噩梦是收集大量无用的低质量数据。根据 HBR 在 2017 年发表的一篇文章,公司中只有 3%的数据符合基本质量标准。因此,在不知道如何衡量数据质量的情况下,强烈建议不要进行数据收集,至少不要进行大规模的数据收集。另外,除非现有数据的质量满足基本要求,否则你不应该对其寄予希望。
体系结构
数据架构有两个主要阶段:(a) 存储和(b) 分析。每个阶段的要求不一样。例如,您必须创建一个数据管道,以最小的冗余快速接收和存储数据。NoSQL 数据库通常用于第一阶段,因为它们在接收新数据时执行速度很快。此外,它们是人类可读的,有助于理解数据。然后,您必须创建一个管道来检索和分析数据。SQL 数据库经常在这个阶段使用,因为 Scikit-Learn 等标准 ML 库接受表格数据作为输入。当你设计数据架构时,你必须总是考虑可伸缩性和效率。如果您不能在第一次尝试中设计出最好的数据架构,请根据需要修改它。性能不佳的数据架构将会给你带来沉重的打击。
感谢阅读!
如果你喜欢这个帖子,想支持我…
- 跟我上 中 !
- 在 亚马逊 上查看我的书!
- 成为会员上 中 !
- 连接上Linkedin!
- 关注我 推特 !
https://pedram-ataee.medium.com/membership
如何用 Jupyter 笔记本和 Kotlin 打造 Docker 形象
原文:https://towardsdatascience.com/how-to-create-a-docker-image-with-jupyter-notebook-kotlin-2e8bbf212f81?source=collection_archive---------7-----------------------
使用 Docker 分 3 步设置自定义 Jupyter 笔记本环境兼容Kotlin内核。
Jupyter + kotlin 内核示例(图片由作者提供)
计算笔记本 或简称 笔记本 是一种灵活的交互式工具,允许科学家在同一文档中组合软件代码、计算输出和解释性资源(如文本、图表和任何其他媒体内容)。笔记本电脑有多种用途,包括数据清理和转换、数值模拟、统计建模、数据可视化、机器学习等等。
计算笔记本并不是什么新东西,它们已经存在了很长时间。然而,基于 web 的开发环境的兴起以及对数据科学学科(如探索性数据分析、机器学习或深度学习等)日益增长的兴趣,已经指定一般的笔记本电脑以及特别是【Jupyter】笔记本电脑 作为全世界科学家和研究人员的首选工具。有很多方法可以在您的本地环境中安装Jupyter(pip, Anaconda ,…)甚至直接在云驱动的笔记本环境中工作(比如 Google Colab) 。然而,这些方法中的大多数都是面向 Python 的,这意味着如果你想将JupyterJupyter与任何其他语言(如KotlinScala 或 Java)一起使用,你将不得不安装额外的内核。在这篇文章中,我们将解释一个非常简单的方法来设置你自己的Jupyter*环境兼容 Kotlin 语言,不需要安装任何东西,只需要在你的笔记本电脑上安装一个工具: Docker 。*****
环境
本文是基于以下平台编写的:
- 操作系统 : MacOS Catalina 10.15.7
- Docker 社区: v.20.10.2 for Mac ( 如何安装 docker )
目标
本文旨在详细说明使用以下组件创建自定义 docker 映像的步骤:【Jupyter Notebook】和 Kotlin 内核 。一旦环境建立起来,我们将展示如何访问它以及如何使用它。最后,在确认一切正常后,我们将把我们的图像上传到一个容器图像库,如 Docker Hub ,这样社区就可以轻松访问它。
让我们简单讨论一下我们将要使用的技术和产品:
Docker 是一个软件平台,旨在通过使用容器来简化应用程序的创建、部署和运行。 Docker 允许开发者将应用程序及其所有依赖项打包到一个容器中,然后作为一个包发送出去。这项技术允许停止担心安装组件和库,只需专注于工作。
Jupyter是一个基于 web 的交互式开发环境,允许管理 Jupyter 笔记本。Jupyter Notebook 是一种基于 JSON 的交互式开放文档格式,用于将软件源代码、叙述性文本、媒体内容和计算输出组合在一个单独的文档中。
Kotlin是由 JetBrains 创建的通用、免费、开源、静态类型化的“实用主义”编程语言。 Kotlin 结合了面向对象和函数式编程特性,它被设计成完全与 Java 互操作,而 Kotlin 的标准库的 JVM 版本依赖于 Java 类库。
讨论在您的数据科学项目中使用 Kotlin 的原因超出了本文的范围,但是如果您想了解这个主题,我建议您查看以下来自 JetBrains 的资源(此处为)。
步骤 1:创建 Dockerfile 文件
一个 Dockerfile 是一个文本文档,包含用户可以在命令行上执行的指令,以构建和组装 docker 映像。因为我们目标是创建一个 docker 映像,所以我们的第一步是创建一个 docker 文件。因此,转到您的项目目录并创建一个名为 Dockerfile 的新文件。创建后,我们可以通过添加如下内容对其进行编辑:
https://gist . github . com/Miguel doctor/EB 29 f 91 aae 612 c 618d 9 b 12 ff 3 b 297 E6 c
让我们解释一下文件的内容:
FROM jupyter/base-notebook:
这是我们 Dockerfile 的第一行。通常一个 Dockerfile 以FROM
命令开始。FROM 指令接收预先存在的 docker 图像作为参数。想法是使用这个图像提供的服务,并通过在其上添加新的层来扩展它。作为参数传递的基本图像是jupyter/base-notebook
。此映像包含已经安装的 Jupyter 的基本版本。LABEL Miguel Doctor <migueldoctor@gmail.com>:
标签命令是可选的。它用于标识映像的维护者。如果包括在内,您允许对您的图像感兴趣的人联系您,以防他们需要问您一些问题或报告图像的问题。ENV
定义了环境变量。在这种情况下,我们指出,我们希望使用完整的Jupyter Lab解决方案,它允许我们处理几个笔记本电脑并使用一个漂亮的浏览器 web 界面。**
步骤 2:将 openjdk-8-jre 和 Kotlin 内核添加到 docker 文件中
如前所述,Jupyter 的默认配置是面向 Python 的,因此为了使用不同的语言,如 Kotlin ,我们需要安装和配置特定的内核。由于 Kotlin 是一种 JVM 语言,所以首先要安装的就是 Java 运行时环境(JRE)。
因此,让我们更新我们的 Dockerfile ,在它上面包含 openjdk-8-jre 安装。一旦安装了 JRE,我们需要添加 Kotlin 内核,这样它就可以连接到 Jupyter 。要做到这一点,我们只需打开 Dockerfile 并编辑其内容,如以下脚本所示:
https://gist . github . com/Miguel doctor/3344 BAF 619 AC 62 DD 773 c 0669 a4 CBA 8d 6
如你所见,我们在文件中添加了几行,这些行使用了新的 Dockerfile 关键字,如 USER 和 RUN。所以让我们解释一下这些命令是用来做什么的。
USER
命令允许改变负责在 Dockerfile 中执行以下指令的用户帐号。因为在容器上安装 JDK 8 只有根用户可以使用,我们需要在文件中指明。- 关键字
RUN
负责在构建时执行动作。通过使用 RUN,您可以自定义底层映像更新软件包,向映像添加新的应用程序或安排安全规则等。在我们的例子中,我们在文件中调用 RUN 指令两次。首先运行apt包管理实用程序,这样open-JDK(版本 8)就可以安装在容器上了。第二条RUN
指令执行 康达命令行工具安装kotlin-jupyter-kernel。****
步骤 3:创建一个 Makefile 来构建和运行映像
关于 Dockerfile 就这么多了!现在,我们需要使用 docker 来获取刚刚创建的 docker 文件并构建 docker 映像,以便它可以作为容器运行。为此,只需进入终端,导航到您的项目文件夹( Dockerfile 所在的位置)并创建一个名为 Makefile 的新文本文件。然后你需要添加以下内容:
https://gist . github . com/Miguel doctor/5 BCE 365502 a 60 FBA 65 b 36 f 85830d 4631
让我们解释一下我们刚刚添加到文件中的内容:
1) run
关键字定义了运行 Makefile 时要执行的指令段。
2) docker build -t <name of the image> <path or the dockerfile>:
它通过将图像的名称和 Dockerfile 所在的路径作为参数传递来创建 docker 图像。
重要提示:标签“Miguel doctor/docker-jupyter-kot Lin-notebook”是我们分配给图像的标识符。这是一个任意参数,因此您可以随意修改。
3) docker run
:这个命令实际上启动了 docker 容器。它需要一些参数,我们解释如下:
- 参数- name 用于给容器指定一个特定的名称。
- 选项 - v 用于在位于主机上的文件夹(/Users/mdoctor/Documents/docker volumes/kotlin-jupyter)和容器内的特定路径( /home/jovyan/work) 之间建立映射(如果该文件夹不存在,您必须创建它)。这就是 Docker 定义的卷,它允许在主机和容器之间共享信息。当作为参数传递给
docker run
命令时,两个路径都需要用冒号(:)分隔。如果你想了解更多关于体积的知识,你可以点击查看的帖子。 - 选项 -p 允许我们映射主机端口和容器端口。 -p 参数后面是主机的端口号( 8888 ),将被重定向到容器的端口号( 8888 )。
- 最后,我们需要将在之前的 docker build 命令中创建的图像Miguel doctor/docker-jupyter-kot Lin-notebook作为参数进行传递。**
曾经解释过的Makefile,我们只需要保存文件并在定位到项目的文件夹时键入以下命令即可。**
**$ make**
一会儿,终端将显示正在执行的指令列表(构建映像、启动容器……),最终您将看到类似下面的日志跟踪:
Juptyer 服务器已准备就绪(图片由 Miguel Doctor 提供)
这意味着 Jupyter 服务器已经启动并运行,你可以通过打开你的网络浏览器并键入日志上显示的最后一个 URL 来访问它:(http://127 . 0 . 0 . 1:8888/lab?token = de 4d 7 f 250 f 18430848 ad 1 b 40 bb 84 a 127d 558968907 CB 10a 6。
安装了 Kotlin 内核的 Jupyter 实验室(图片由作者提供)
如果你能看到图中所示,恭喜你!这意味着容器正在运行 Jupyter 和 Kotlin 内核。现在,您只需点击笔记本部分的 Kotlin 图标,即可创建您的笔记本并开始使用。如下所示,你可以看到一个简单的笔记本应该是什么样子的,带有一些 科特林 代码。
Jupyter + kotlin 内核示例(图片由作者提供)
重要: 注意,运行 make 命令会在每次执行时构建 docker 镜像,这意味着如果没有在docker 文件中做任何修改,会浪费时间和资源。因此,除非您编辑 Dockerfile ,否则您应该使用以下命令运行容器(已经包含在 makefile 中,并在上面解释过)。**
**$ docker run --name my-jupyter-kotlin -v /Users/mdoctor/Documents/dockerVolumes/kotlin-jupyter/:/home/jovyan/work -p 8888:8888 migueldoctor/docker-jupyter-kotlin-notebook**
可选:将图像推送到 Docker Hub
在某些情况下,我们可能会对向社区发布我们的 docker 图像感兴趣,这样每个人都可以从我们的工作中受益。对于我们的特殊情况,我们已经决定使用 Docker Hub 作为我们的中央注册中心。如下,我们描述了将刚刚创建的图像上传到 Docker Hub 的方法:
- Docker Hub 允许用户根据需要创建一个账户来上传图片,所以如果你还没有注册,你需要在网上注册。
- 注册之后,您需要打开一个终端,并使用
docker login
命令连接到 Docker 注册中心。系统会提示您输入用户名和密码。
**$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to [https://hub.docker.com](https://hub.docker.com/) to create one.
Username:**
- 最后,您需要使用
docker push
后跟图片名称来上传。由于我们使用了 docker ID 用户名( migueldoctor) 作为构建映像的前缀,我们可以使用下面的命令直接推送映像。如果您没有使用您的 docker ID 作为前缀,您需要按照以下帖子的 步骤 5 中的指示对其进行标记:
**$ docker push migueldoctor/docker-jupyter-kotlin-notebook**
一旦图像被成功地推入 Docker Hub,就会创建一个新的 url 来提供对图像的公共访问。该 url 将包含图像的当前版本以及我们将来可能想要推送的任何新版本/标签。对于我们的示例,url 如下:
https://hub . docker . com/r/Miguel doctor/docker-jupyter-kot Lin-notebook
结论
在这篇文章中,我们已经描述了如何创建自己的定制 docker 映像,包括一个与Kotlin内核 兼容的全功能 Jupyter 笔记本服务器。此外,我们解释了所有参数,以便您可以通过添加/删除内核来定制映像。最后,我们解释了如何运行映像以及将 docker 映像推送到 Docker Hub registry 的步骤。**
请随时留下您在文章中发现的任何评论、见解或错误。非常欢迎您的反馈,这将有助于提高文章的质量。一如既往的感谢您的阅读。我强烈希望本教程能帮助你使用kot Lin和 Docker 开始数据科学项目。**
来源
- https://docs.docker.com/engine/reference/run/
- https://jupyter.org/documentation
- https://kotlinlang.org/
- https://howtodoinjava . com/library/docker-hello-world-example/# create-docker-image
- https://www.nature.com/articles/d41586-018-07196-1
- https://www.json.org/json-en.html
- https://Miguel doctor . medium . com/how-to-create-a-custom-docker-image-with-JDK 8-maven-and-gradle-DDC 90 f 41 CEE 4
如何创建重复图像检测系统
原文:https://towardsdatascience.com/how-to-create-a-duplicate-image-detection-system-a30f1b68a2e3?source=collection_archive---------11-----------------------
了解如何使用感知哈希函数和最近邻搜索来检测重复图像
美国地质勘探局在 Unsplash 上拍摄的照片
目录
- 动机
- 实施细节
- 构建系统
- 测试
- 未来改进
- 参考文献
动机
你可能会想,“制作一个重复图像检测系统有什么意义?”有几个原因让你想这么做。这些原因包括防止侵犯版权,从 web 应用程序中删除非法或不需要的图像[1]。识别非法图片最近一直是一个热门话题,苹果公司宣布计划在 iOS 15 中推出一项检测 CSAM 的功能。
苹果 CSAM 检测作者,灵感来自苹果
虽然苹果的 CSAM 检测功能现在由于隐私反弹而被推迟,但它背后的技术仍有很多值得我们学习的地方[3]。苹果开发的 CSAM 检测系统使用一种称为 NeuralHash 的感知哈希函数来为每张图像生成唯一的数字指纹(哈希)。一旦加密, 私有集合交集【PSI】用于确定图像哈希是否匹配已知 CSAM 的哈希数据库,同时保持隐私[4]。值得注意的是,这是一个过于简单的描述,如果你有兴趣深入了解细节,我建议你阅读苹果的技术总结。
实施细节
重复图像检测系统(图片作者)
我们将在本文中构建的系统将使用感知哈希函数,类似于苹果的 CSAM 检测。然而,我们将使用差分哈希 ( dHash) ,而不是使用神经哈希来生成图像哈希,这更简单,计算量也更小,因为它不需要神经网络。由于我们没有像苹果一样的隐私限制,我们将使用最近邻搜索来识别重复图像。
差异散列
dHash 是一个感知散列函数,它产生的散列值对图像缩放以及颜色、亮度和纵横比的变化具有弹性[5]。为图像创建差异哈希有四个主要步骤:
dHash 程序(作者图片)
- 转换为灰度*
- 将图像大小调整为(哈希大小+1,哈希大小)
- 计算水平梯度,将图像大小减少到(哈希大小,哈希大小)
- 基于水平梯度值分配位
*为了获得最佳性能,我们在调整大小之前将图像转换为灰度
最近的邻居
我们想要检查重复的图像哈希将存储在二进制索引中,以便快速有效地进行最近邻搜索。我们将使用汉明距离作为度量来确定图像哈希之间的相似性,对于 dHash ,小于 10 的距离(96.09%相似性)可能表示相似/重复的图像[5]。
构建系统
在本文的其余部分,我们将使用 Python 构建一个简单的 RESTful API 服务,它允许用户向图像数据库添加图像哈希,并执行图像查找以查看它们是否重复。
如果您没有时间阅读本文的其余部分,您可以在 GitHub 上找到一份代码副本,做了一些修改以使其更易于扩展。
入门指南
我们将使用fastapi
和uvicorn
来创建 API 服务,并接受我们需要python-multipart
上传的图像。
从安装所需的软件包开始:pip install fastapi python-multipart uvicorn[standard]
安装后,使用以下文件夹结构创建项目存储库:
文件夹结构
在app/api.py
中创建一个FastAPI
的实例,并将其分配给app
在main.py
文件中导入app
并用uvicorn
运行它,现在我们可以用python main.py
运行服务并连接到 http://localhost:8080
API 路线
我们需要定义两个主要的 API 端点,一个用于向数据库添加图像,另一个用于在数据库中查找图像。
在app/api.py
文件中,我们更新了导入并添加了两条路线:
- 两条路径都通过
file
参数接受图像,而/api/check
路径接受一个dist
参数,该参数将用于在搜索重复图像时指定汉明距离阈值
散列法
我们将使用来自imagehash
库的dHash
、Pillow
来加载图像,以及numpy
来将散列转换成二进制散列向量。
首先,安装散列所需的包:pip install Pillow imagehash numpy
在app/utils.py
中,我们使用dHash
和hash_size=16
创建了一个哈希实用函数,产生的哈希有 256 位,减少了随机冲突的机会:
- 为了在我们的二进制索引中使用产生的散列,我们需要将数组转换成一个包含
uint8
值的 1x32 向量,为此我们使用numpy
来调整数组的大小,并将二进制值打包到uint8
现在我们可以使用app/api.py
中的这个实用函数来散列每个端点接收到的图像:
索引
索引创建和搜索将使用faiss
完成,这是一个由脸书开发的用于高效相似性搜索的库。
安装所需的软件包:pip install faiss-cpu pytorch
为了开始使用faiss
,我们将在app/utils.py
中创建几个实用函数来加载/创建索引并保存到磁盘
- 我们使用的是
IndexBinaryFlat
索引,它可能没有其他Binary
索引快,因为它执行穷举搜索,但是这个搜索已经针对 256 位向量进行了优化。 IndexBinaryFlat
利用汉明距离作为向量相似性度量,因为它是faiss
二进制索引之一。
导入新定义的实用方法,并更新add_image
处理程序来加载索引。我们使用 index add
方法插入散列向量,然后将更新后的索引保存到磁盘上以备将来使用:
现在我们可以更新check_image
来使用range_search
对我们的索引执行最近邻搜索。该方法搜索在dist
的汉明距离内的向量,并返回一个元组
lims
是开始和结束索引的数组,用于解析D
和I
D
是最近邻居的距离数组I
是最近邻居的整数 id 数组
测试
既然两个 API 端点都已完成,我们将使用 Postman 测试每个端点。
添加图像
- 使用以下 URL 创建新的发布请求:
[http://localhost:8080/api/add/image](http://localhost:8080/api/add/image)
- 将车身类型更改为
form-data
- 添加一个
file
键,并将类型更改为File
- 选择一个图像作为
file
的值,并发送一个请求,您应该得到以下响应:
{"msg": "added image"}
检查图像
- 要测试重复图像检查端点,请将 URL 更改为
[http://localhost/api/check](http://localhost/api/check)
- 添加一个值为
10
的dist
键,并发送请求 - 对于
file
值保持相同的图像,您应该得到以下响应:
{"duplicate": **true**}
现在尝试改变图像,看看你会得到什么样的反应!
在达到本文的这一点后,您现在应该有了一个使用最近邻搜索和 dHash 的工作的重复图像检测系统。如果你对本文中的代码有任何问题,请在 GitHub 上发帖,否则请随意留言!要继续增加您的服务,请考虑下一节中提到的一些未来改进。
未来的改进
- 错误处理和输入验证
- 证明
- 前端用户界面
除了上面提到的改进,我认为使用不同的哈希函数和二进制索引来评估速度、内存使用和图像数据集的准确性也是值得的。
参考
[1] N. Dolhansky,C. Canton Ferrer,对图像散列函数的对抗性碰撞攻击 (2020),计算研究储存库
[2] Z. Whittaker,苹果证实将开始扫描 iCloud 照片中的虐童图片 (2021),TechCrunch
[3] Z. Whittaker,在隐私遭到强烈反对后,苹果推迟了在 iOS 15 中推出 CSAM 检测的计划 (2021),TechCrunch
[4]苹果公司, CSAM 检测技术总结 (2021),苹果公司
[5] N. Krawetz,类似于 (2013),黑客因素博客
如何用 Bash 脚本创建一个简单的交互式终端菜单
原文:https://towardsdatascience.com/how-to-create-a-foolproof-interactive-terminal-menu-with-bash-scripts-97911586d4e5?source=collection_archive---------5-----------------------
适用于任何面向操作的终端应用程序的颜色协调的多选菜单
交互式终端菜单。图片由作者提供。
介绍
如果您正在考虑为下一个 Bash 脚本项目创建一个交互式菜单,那么您就找对了地方。在本文中,我们将创建一个简单的带有颜色的菜单模板,以便于导航。
终端命令使用选项向程序传递参数。这些选项可以是破折号后跟一个字母,也可以是两个破折号带一个单词。如果选项带有一个参数,则称为开关,否则称为标志。
如果您的应用程序有多层命令,使用终端命令的菜单系统会使导航变得容易。我用这个方法创建了一个添加了颜色的终端收音机。
炙单
主菜单功能包含两个菜单项,但您可以为您的项目添加更多菜单项。
查看运行中的代码。
带有-n 选项的 echo 命令使光标保持在作者的同一行图像中。
echo -e
选项允许我们使用反斜杠来转义字符,例如,换行符\n
或制表符\t
,如果你需要的话。echo -n
选项省略了尾随换行符。如果没有-n
选项,光标会移动到下一行,如图所示。
不带-n 选项 echo 命令会追加一个换行符。图片由作者提供。
所有菜单都将包含case statement
来保存不同的选项。这使得它比使用多个 if 语句更容易阅读和管理。
如果用户选择 1,它将显示子菜单。您可以将CMD1
更改为任何菜单名称。选项 0 将退出脚本,任何其他字母*
将显示警告,并以状态 1 退出。
子菜单
第一个子菜单项SUBCMD1
包含显示子子菜单的子命令。子子菜单一旦完成动作,就会再次显示子菜单。第二个菜单项Go Back to Main Menu
使用 case 语句中的menu
功能返回主菜单。
子菜单包括返回主菜单。图片由作者提供。
子子菜单
我们为子菜单中的第一项和第二项添加了简单的功能。第三和第四项将返回到子菜单和主菜单。我们对0
和*
重复同样的操作,所以让我们在下一节创建公共函数。
子子菜单。图片由作者提供。
创建常用功能
让我们为退出和错误选项创建函数:
然后我们可以将它们应用到我们case statements
中的0
和*
。
case $ans in
...
0)
fn_bye
;;
*)
fn_fail
;;
esac
...
到目前为止,菜单很简单。让我们在下一节中给菜单添加颜色。
创建颜色函数
这些颜色函数可以接受一个参数。例如:
$(greenprint '1)') SUBCMD1
$(magentaprint '2)') Go Back to Main Menu
$(redprint '0)') Exit
我们在引号内使用$(command)
。它运行command
并替换其输出。
对于我们的菜单,我们将使用洋红色代表返回主菜单,红色代表退出,以使整个菜单保持一致。此外,我们将添加不同的颜色菜单名称。
$(magentaprint 'MAIN MENU')
$(blueprint 'CMD1 SUBMENU')
$(yellowprint 'SUB-SUBMENU')
最终代码
让我们把它们放在一起。在本文的最后一节,您可以使用嵌入式交互式终端控制台测试该脚本。请尝试导航不同的菜单点。
菜单与颜色功能一起使用。图片由作者提供。
查看运行中的最终代码。图片作者。
下面是实际运行的最终代码。
结论
我在名为tera
的终端无线电中使用了这种方法。请安装它,看看我是如何在实际应用中应用这些菜单系统的。
你可以发挥创意,也可以在菜单项中使用表情符号或数字字母。
如果您的应用程序有多层菜单系统,交互式菜单系统比普通的选项解析器系统更容易在复杂的菜单系统中导航。
我希望您可以将这些代码应用到下一个 Bash 脚本项目中。
通过 成为 会员,可以完全访问媒体上的每个故事。
https://blog.codewithshin.com/subscribe
参考
- https://dev Dojo . com/bobbyliev/how-to-create-an-interactive-menu-in-bash
- https://bit.ly/3y3imV5
如何使用 Python 创建地理围栏
原文:https://towardsdatascience.com/how-to-create-a-geofence-with-python-part-1-14c3864cf9cc?source=collection_archive---------26-----------------------
由威尔·弗朗西斯在 Unsplash 上拍摄的照片
无论何时处理位置数据,地理围栏都是一种具有广泛应用的有用技术。它可用于根据与个人或地标的接近程度发出通知或标记警报。在数据科学中,它通常用于特征工程和创建可视化边界。
地理围栏是现实世界地理区域的虚拟边界。地理围栏可以动态生成,如在点位置周围的半径内,或者地理围栏可以是一组预定义的边界(如学校区域或社区边界)。
——维基百科
虽然任何应用都是显而易见的,但考虑如何构建地理围栏可能并不总是显而易见的。也有许多方法来设计地理围栏,有些情况下需要精确绘制边界,有些情况下需要移动用户手机的可变半径,这些半径在特定环境下会发生变化。在这篇博客中,让我们看看如何创建一些简单的地理围栏,以便理解它们背后的原理。
下面的例子来自我的项目:使用包含华盛顿州金县房产销售值的数据集进行探索和建模。有关项目和示例数据集的更多信息可在以下 GitHub 知识库中找到— 华盛顿州金县房产销售价格的回归分析&建模。本文末尾的参考书目中提供了对源数据的访问。
按位置分类
假设我们有一个数据集,其中包含许多位置的记录,每个行项目的位置由纬度(df[‘lat’]
)和经度(df[‘long’]
)表示。
我们可以将某些位置分类为属于某个“区域”或界限。我们可以采用几种技术,从简单到复杂。让我们看几个基本的例子,看看如何使用这些技术。
简单地将一个位置分成两半
([谷歌地图,华盛顿州金县 ])
上图是华盛顿州金县的图像。单从谷歌地图的翻译来看,一个肤浅的解释可能是金县的大部分地区欠发达,更多的城市和郊区是灰色的,更多的农村是绿色的。
我们对这块土地所能做的最基本的划分是用一条直线把农村和更发达的地区分开,下面简单解释一下。
绿色范围内的房产将被归类为“农村”,而红色范围内的房产将被归类为“非农村”。(谷歌地图、【华盛顿州金县】)。作者用 Adobe Photoshop 创建的覆盖图。
我们可以在 Python 中用 NumPy 和 Pandas 来实现这一点:
*# Creating a dummy classifier for rural or not*df['rural'] = np.where(df.long > -121.961527,
1,
0)
上面的代码创建了一个表示“农村”King County 的虚拟变量。通过在我们的数据框架df
中标识为rural
的新创建的列中为其分配 1,位于分割线以东的所有财产(即经度大于-121.96 的任何财产)将被分类为农村。任何在该栏中为 0 的地产事实上都不被视为农村地产。
虽然这不精确,但它正确地捕捉了大多数属性,并且执行起来非常简单。如果我们想增加一些考虑纬度的其他条件呢?
使用南北/东西约束的简单边界框
([谷歌地图【华盛顿州西雅图】](http://Seattle - Google Maps))
金县的非农村地区包括西雅图市。在这个练习中,让我们把西雅图视为“城市”,把乡村的金县视为“乡村”,把金县的非乡村地区不包括西雅图视为郊区。如果我们要围绕西雅图市画一个精确的方框,我们可以这样做,如下所示。
绿色范围内的房产将被归类为“城市”,而红色范围内的房产将被归类为“非城市”。([谷歌地图、【华盛顿州西雅图】](http://Seattle - Google Maps))。作者用 Adobe Photoshop 创建的覆盖图。
同样,我们可以使用np.where()
语句为我们的数据创建一个新类。我们称之为“within_seattle_city_limits”
,只有在西雅图售出的房产才会在这一列中被赋值为 1。
*# Creating a dummy classifier for if property is within Seattle city limits or not*df['within_seattle_city_limits'] = np.where(
(df.long < -122.251569) # establishes the EAST box border
& (df.long > -122.438230) # establishes the WEST box border
& (df.lat < 47.734178) # establishes the NORTH box border
& (df.lat > 47.495479), # establishes the SOUTH box border
1, # assigns 1 to all properties within the bounding box
0 # assigns 0 to all properties outside the bounding box
)
上图中,我们用另一个np.where()
语句创建了包围西雅图的绿框。语句中的坐标与符号&
一起设置盒子的角。
请注意,没有为“郊区”、“非城市”或“非农村”创建任何列在我们的数据集中,没有被归类为在西雅图内,也没有归类为农村(即,在‘within_seattle_city_limits’
和'rural’
两列中均为 0)的任何物业,默认情况下都将被视为“郊区”。
理解了这一点,意识到这又有点不精确。我们可以在东北角看到,我们的“城市”框包括一片应该被视为“郊区”的区域,西雅图东部的默瑟岛也是如此,我们甚至剪下了应该被视为西雅图东南部“城市”的很小一部分,将其归类为“郊区”
虽然这可能会导致问题,但我们可能会逐个检查被错误分类的属性,并手动更新它们。我们也可以通过添加额外的盒子来解决这个问题,但是这将在我下一篇关于这个主题的博客中讨论。
尽管如此,我必须强调在你制造潜在问题时抓住它们的重要性。虽然我确实清理了数据集并确保每个属性都被正确标记,但是如果我们添加外部数据并应用上述分类,会发生什么情况呢?我们会弄脏我们的数据,用冰袋护理我们的头痛。
如果我们想要创建一个具有复杂边界的区域呢?这可能需要一点三角学、排除条件和“或”条件的管道(|
)的结合,或者其他 Python 库的帮助。可以使用许多工具和技术,但是适用相同的原则:基于位置环境和条件创建分类规则。
文献学
数据集:
美国金县(2016)
由 harlfoxem 于 Kaggle 通过 CC0:公共领域许可提供
图片:
标题图片由威尔·弗朗西斯在 Unsplash 上拍摄
谷歌地图。【华盛顿州金县】。地图图像。2021,
郡王—谷歌地图。访问时间为 2021 年 8 月 16 日。
谷歌地图数据 2021。
谷歌地图。【华盛顿州西雅图】。地图图像。2021 年,西雅图—谷歌地图。访问时间为 2021 年 8 月 16 日。地图数据 2021 谷歌。
如何创建一个 Git 钩子来推送到你的服务器和 Github Repo
原文:https://towardsdatascience.com/how-to-create-a-git-hook-to-push-to-your-server-and-github-repo-fe51f59122dd?source=collection_archive---------7-----------------------
对 Git 推送做出反应以更新您的远程服务器
蒂姆·莫斯霍尔德在 Unsplash 上拍摄的照片
介绍
Git 挂钩是 Git 在提交、推送和接收之前或之后执行的脚本。设置 Git 挂钩使您的开发和部署变得容易。
在本文中,您将学习如何创建一个在使用git push
命令时执行的接收后 Git 挂钩。
我使用$
作为本地终端提示,使用#
作为远程服务器提示。同样为了简单起见,我使用约翰作为用户名和 Github 用户名,使用yourdomain.com作为我们的域名。
先决条件
在您的本地机器上已经有了一个工作的 Git 存储库。我们称之为**newsletter**
。你的网站有一个 Linux 服务器(我用的是 Ubuntu 20.04),你可以使用 ssh 从你的本地计算机连接到你的远程服务器。
步骤 1:在远程服务器上创建工作目录
/首页/约翰/简讯
我假设你保护了你的服务器并且在你的服务器上设置了防火墙。您可以使用 SSH 连接到您的服务器。
让我们连接到您的服务器:
$ ssh **john@yourdomain.com** // or use your IP address$ ssh john@167.99.123.45
一旦你在远程服务器上,创建一个新的目录,时事通讯:
# pwd
/home/john
# mkdir newsletter
# cd newsletter
在新目录中初始化一个空的 Git 存储库:
# git init --bare
这将省略工作目录,但创建我们需要的目录和文件。
git init —裸结构。图片作者。
/var/www/时事通讯/public_html
在/var/www
下新建一个目录。我们将把所有文件重定向到这个目录。
# sudo mkdir /var/www/newsletter/public_html
步骤 2:在本地 Gitrepo 上设置多个远程 URL
使用git remote set-url
允许您设置多个 Git repo URLs。
使用git remote -v
命令找出您当前的远程配置:
$ git remote -v
origin git@github.com:**john**/newsletter.git (fetch)
origin git@github.com:**john**/newsletter.git (push)
让我们设置远程 URL。一个用于我们的远程服务器,一个用于我们的 Github repo。
$ git remote set-url --add --push origin **john**[**@y**](mailto:shin@okadia.net)**ourdomain.com**:/home/**john**/newsletter
$ git remote set-url --add --push origin git@github.com:**john**/newsletter.git
你需要像上面一样运行两次git remote set-url
,因为第一次运行会覆盖当前的。
现在您应该有一个获取和两个推送:
$ git remote -v
origin git@github.com:**john**/newsletter.git (fetch)
origin **john@yourdomain.com**:/home/**john**/newslette (push)
origin git@github.com:**john**/newsletter.git (push)
步骤 3-创建接收后文件
在远程服务器上,创建一个文件~/newsletter/hooks/post-receive
。
# cd ~/newsletter/hooks
# touch post-receive
添加以下内容:
我们需要使文件可执行:
# chmod +x post-receive
# $ ls -Al ~/newsletter/hooks
total 56
-rwxrwxr-x 1 shin shin 478 Apr 24 03:07 applypatch-msg.sample
-rwxrwxr-x 1 shin shin 896 Apr 24 03:07 commit-msg.sample
-rwxrwxr-x 1 shin shin 3079 Apr 24 03:07 fsmonitor-watchman.sample
**-rwxrwxr-x 1 shin shin 732 May 3 00:58 post-receive** -rwxrwxr-x 1 shin shin 189 Apr 24 03:07 post-update.sample
-rwxrwxr-x 1 shin shin 424 Apr 24 03:07 pre-applypatch.sample
...
post-receive
文件模式应该有-rwxrwxr-x
。
测试它
在您的本地机器上,运行git push origin main
:
$ git push origin main
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 303 bytes | 303.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Push received! Deploying branch: main...
remote: Already on 'main'
To okadia.net:/home/john/newsletter
2b35421..aa80729 main -> main
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 303 bytes | 303.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To github.com:john/newsletter.git
2b35421..aa80729 main -> main
使用我的服务器的例子。图片作者。
结论
Git hook,post-receive
,对于经常使用服务器的开发人员来说是一个非常好的工具。Git 有更多的客户端和服务器端挂钩工具供您使用。开始在你的项目中使用它怎么样?
通过 成为 会员,获得媒体上所有故事的访问权限。
https://blog.codewithshin.com/subscribe
资源
- Githooks
- 用 Git 钩子在 DigitalOcean Droplet 上部署代码
如何创建一个不难看的图形 Python 数据可视化的秘诀
原文:https://towardsdatascience.com/how-to-create-a-non-ugly-figure-a-recipe-for-python-data-visualization-3793fde29e79?source=collection_archive---------18-----------------------
满足数据可视化需求的统一方法
由 Max Duzij 在 Unsplash 上拍摄的照片
当我们呈现数据来传达信息时,最有效的信息传递方式是使用数字,这与我们大脑的线路一致——我们获取的大部分信息都是视觉形式的。因此,数据可视化是数据科学家向外界展示他们的数据的关键技能,希望他们的项目能够被更好地理解。
作为一种开源编程语言,Python 吸引了开发人员的极大关注,由此产生了许多可供数据科学家使用的可视化工具。我并不想将他们进行正面比较。相反,我将只使用那些对我有效的方法,并且我想分享一个你可以自己尝试的常用方法。
这里没有秘密——我将使用matplotlib
和seaborn
重点介绍数据可视化,这可能是 Python 中最流行的可视化库。
事不宜迟,让我们开始吧。
配料——你所需要的
- 您选择的 Python 编辑器。可以是 PyCharm,VS Code,Jupyter Lab,或者你喜欢的任何东西。对于本教程,我将使用 Jupyter 实验室中运行的笔记本。你可以在我的 GitHub 上找到笔记本。
- 虚拟环境。每个项目使用不同的虚拟环境是一个很好的实践,这简化了 Python 版本和第三方包的管理。虚拟环境管理,我推荐康达,你可以在这里找到说明。
- Python 3.6+。它可以是 system one,或者理想情况下,是安装在您的虚拟环境中的一个版本。
- 安装需要的包:
**seaborn**
**matplotlib**
。seaborn
的安装应该会自动安装matplotlib
,T5 是seaborn
的依赖。 - ****一张草稿纸和一支铅笔。听起来怪怪的?接下来我会告诉你怎么处理它们。
照片由 Syd Wachs 在 Unsplash 上拍摄
一般步骤
- 在纸上画一道划痕。虽然你可以在脑海中想象这个数字,但如果你有一份草稿放在桌子上,可以直接看到,通常会更直观。
- ****根据身材需要准备数据。根据图形的性质,您需要相应地准备数据。应该注意的是,在你开始绘图之前,你的数据还没有准备好,这是可以的,而且经常发生。如果需要,您可以随时返回步骤 2。
- ****设定整体主题。有了
seaborn
就很容易设置一个整体主题,它会自动在幕后为我们应用很多默认设置,让人物好看。 - 创建一个草图作为你的起点。不要担心任何事情——只需使用正确的绘图样式创建一个草图即可。
- ****微调细节:标题、x 和 y 标签等。无论你想做什么来让他们变得更好。
哈尔·盖特伍德在 Unsplash 上拍摄的照片
步骤 1 和 2
这两步就交给你了。每个项目在数据可视化方面都有自己的需求,应该相应地准备数据。对于当前的教程,我们只使用属于seaborn
包的 tips 数据集,如下所示。
数据一目了然(作者截图)
第三步。设定整体主题
即使你什么都不做,seaborn
会对我们的数据应用一些默认设置,当然它们看起来也不错。但是,要自定义人物的外观,应用一个整体主题是个好主意,它允许您以美学上一致的方式创建多个人物。下面是你如何设置默认主题。
设置主题
如您所见,所有参数都在set_theme
方法中设置了默认值。为了向您展示每个参数的含义,让我们看看一个图形在默认主题下是什么样子的:
图使用默认主题(作者截图)
现在,是时候单独探究这些参数了。请注意,您可以将set_theme
视为一种方便的方法,有单独的函数专门用于设置参数。只要适用,我都会提到这些函数。
设置上下文 上下文参数有四个预先配置的选项:纸张、笔记本、谈话、海报。下图显示了每一个的外观。最能吸引你眼球的区别是标题和标记。
替代功能看:**plotting_context**
&**set_context**
**。****
设置上下文(作者截图)
设置样式
样式主要通过控制网格应用于图形的轴。有五种可能的预配置设置:白色网格、白色、刻度、深色网格和深色。下面显示了每个设置的示例。与“white”
相比,除了“ticks”
启用轴上的刻度标记外,一切都很简单。
替代功能看:**axes_style**
&**set_style**
**。****
设置样式(作者截图)
设置调色板
图形如果没有颜色就很无聊。如果你需要为身材的不同部分设置不同的颜色,这对我们大多数人来说都不是一件容易的事情。幸运的是,您可以选择一个调色板,自动将各种颜色应用到您的绘图中。有大量预先配置的调色板供您选择。这是部分清单。
'Accent', 'Accent_r', 'Blues', 'Blues_r', 'BrBG', 'BrBG_r', 'BuGn', 'BuGn_r', 'BuPu', 'BuPu_r', 'CMRmap', 'CMRmap_r', 'Dark2', 'Dark2_r', 'GnBu', 'GnBu_r', 'Greens', 'Greens_r', 'Greys',
...
'turbo_r', 'twilight', 'twilight_r', 'twilight_shifted', 'twilight_shifted_r', 'viridis', 'viridis_r', 'vlag', 'vlag_r', 'winter', 'winter_r'
如果您不知道如何找到调色板名称,一个简单的方法是从调用sns.set_palette(“anything_you_want”)
时的错误消息中找到这个信息。
替代功能看:**color_palette**
&**set_palette**
。****
设置调色板(作者截图)
您还可以配置其他一些参数。但你可能会说,这三个对你身材的审美影响最大。请随意探索其余的参数。
第四步。创建草图
如果你熟悉seaborn
的可用选项,这对你来说可能不是问题。但是,如果您不是,最好找出您在支持的打印样式方面的选项。你可以在 seaborn 的网站上找到大量有用的例子,如下所示。
**https://seaborn.pydata.org/examples/index.html
当您不确定想要选择的绘图的名称时,如果您正在使用 PyCharm,您可以简单地输入sns.plot
并让 IDE 为您填充可用的绘图相关方法,如下所示。
seaborn 的可用地块(作者截图)
本教程不打算教你选择哪个图,因为它完全取决于数据和显示什么信息的目的。缩小选择范围的一个快速技巧是查看自动完成提示菜单右侧的绘图类型。一些重要的类别总结如下。
seaborn.distributions
:一维连续数据,查看你的数据分布seaborn.categorical
:您的 x 值是不同的分类值seaborn.relational
:你的 x 值和 y 值是相关的,就像你在笛卡尔坐标系中工作一样seaborn.regression
:您想要对图形应用回归线
因此,假设您知道绘图类型,这一步只是创建一个没有任何配置的草图。为了简单起见,让我们选择 violin 图,它显示了不同类别中的值的分布。草图如下所示。
草图(作者截图)
- 如前所述,我们设置主题来应用整体样式设置。
- 然后我们使用
plt.figure(figsize=(10, 6))
启动指定尺寸的绘图。本质上,它创建了一个人物对象。 - 我们使用
violinplot
方法,指定分类变量(x 值)是一天,而连续变量(y 值,检查其分布)是总账单金额。
如你所见,草图实际上一点也不差。但是如果我们对一些细节进行额外的修正会更好。我们继续。**
第五步。调整细节
一个常见的需求是给图形添加一个标题,如下所示。
添加标题(作者截图)
要添加标题,您需要理解当 seaborn 创建一个情节时,它会创建一个matplotlib
axes 对象,通过它,您可以操纵细节。在我们的例子中,我们在 axes 对象上使用set_title
来创建一个标题。
除了添加标题,我们还可以更改轴的标签。
更改标签(作者截图)
当然,您可以使用 axes 对象做许多其他事情。最好的学习方法是在自己身上尝试不同的设置。如果您有任何问题,您可以简单地参考轴对象的文档。
当您对您的数字感到满意时,您可以通过运行plt.savefig(“the_name.png”)
来保存它以供以后参考。BTW:如果你使用plt.show()
来显式调用图形的显示,你需要在显示之前保存图形,因为图形对象在你显示图形之后就不能保存了。
结论
在本教程中,我们学习了创建一个在报告中使用的相当好看的图形的基本步骤。通过更好的微调和更多的耐心,一个图形可以更好——你只需要练习熟悉matploglib
和seaborn
的 API。
感谢阅读这篇文章。通过注册我的简讯保持联系。还不是中等会员?使用我的会员链接通过支持我的写作(对你没有额外的费用,但你的一部分会员费作为奖励由 Medium 重新分配给我)。
如何创建完美的数据策略
原文:https://towardsdatascience.com/how-to-create-a-perfect-data-strategy-7e8fd9bbfad0?source=collection_archive---------33-----------------------
人工智能笔记
深入了解数据战略的四大支柱
由伊万杰洛斯·姆皮卡基斯在 Unsplash 上拍摄的照片
如今,公司的目标是通过使用他们的数据建立人工智能解决方案来增加利润。但是,由于他们通常没有完善的数据策略,因此无法成功完成任务。数据策略有四个主要支柱:价值、集合、架构、和治理。我在如何为您的组织创建数据策略中描述了数据策略。我见过很多公司在制定数据策略时犯的常见错误。在本文中,我想描述构建数据策略的最佳实践,并解释我从一些真实场景中学到的经验。
价值——它真的创造了商业价值吗?
一个大型组织必须找到一个可以被人工智能解决方案很好服务的商业目标。例如,一家大型连锁杂货店可以分析来自其客户忠诚度计划、供应链、商店交易和商店流量的数据。问题是使用人工智能解决方案可以显著增强哪个业务目标。对于这些组织来说,开始构建人工智能解决方案的成本效益分析没有意义是很常见的。失败可能会阻止该组织追求其他有前途的道路。因此,强烈建议在使用人工智能确定业务目标之前,进行成本效益或复杂性预期分析。要阅读更多关于复杂性期望分析的内容,你可以看看下面的文章。
https://medium.com/swlh/if-you-consider-using-ai-in-your-business-read-this-5e666e6eca23
在使用人工智能确定商业目标之前,你必须进行成本效益或复杂性预期分析。
收集—收集的数据与要解决的问题相关吗?
众所周知,如果大量数据或各种数据类型不存在,人工智能解决方案就无法工作。然而,数据和问题之间的关联经常被忽视。那些不是人工智能专家的人,期待人工智能解决方案的魔力。他们认为,如果大量数据输入到人工智能解决方案中,这就足够了。不对!领域专家可以简单地识别数据与业务目标的相关性。他们知道问题背后的物理原理,并且能够很容易地确定需要收集的相关数据。然而,他们的意见有时会受到损害。要了解大规模数据收集中存在的其他挑战,您可以阅读下面的文章。
https://medium.com/dataseries/on-the-path-to-conducting-a-large-scale-data-collection-8a8cd201543d
没有多样、庞大、相关的数据,AI 会让你失望。然而,数据和问题之间的关联经常被忽视。
架构—数据集的设计使用、扩展和维护效率如何?
随着人工智能项目从单一类型数据转换到多模态数据,数据架构变得更加重要。此外,近年来,数据集的规模和用途呈指数级增长。指数级增长导致了数据架构中必须解决的可扩展性问题。最后,但同样重要的是,数据架构会显著影响性能和开发速度。因此,如果你不建立一个高性能的数据架构,你将会遇到普遍的技术挑战。有一次,我正在咨询一家大型芯片制造商,以构建一个人工智能解决方案来检测其芯片的故障率。他们给了我大量的数据集,这些数据集不仅包含相同的数据,而且每个数据集只包含一两个有用的数据字段。不用说,这些数据集也经常更新。他们的低质量数据架构让我花了很多时间来创建一个干净、可靠、易于监控和更新的数据集。
您必须分析数据架构如何影响项目,否则技术挑战很快就会出现。
治理——各种团队是否可以访问所需的数据?
在大型组织中,由于团队经常在竖井中工作,因此在不同的团队之间收集和共享数据存在许多挑战。例如,数据库团队负责创建数据存储和检索的基础设施,而人工智能团队负责分析和处理数据。另一方面,数据收集发生在人工智能和数据库团队不在场的领域。团队之间没有那么多的互动,他们也没有意识到双方存在的挑战。例如,人工智能团队可能会要求提供重要的缺失数据以提高人工智能模型的性能,但数据团队不会合作收集这些数据。或者,一个部门可能拥有一个有价值的数据集,但由于技术或政治原因,他们没有与其他团队共享它。问题出现在这里,嘣!一个好的数据策略必须帮助不同的团队访问所需的数据,并且能够在需要时收集一组新的数据。
你必须创建一个计划,让数据收集、数据库、AI 等各个团队高效地协同工作。
感谢阅读!
如果你喜欢这个帖子,想支持我…
- 跟我上 中 !
- 在 亚马逊 上查看我的书!
- 成为 中的一员 !
- 连接上Linkedin!
- 关注我 推特 !
https://pedram-ataee.medium.com/membership
如何在 Python 中创建照片马赛克
原文:https://towardsdatascience.com/how-to-create-a-photo-mosaic-in-python-45c94f6e8308?source=collection_archive---------3-----------------------
Python 中照片马赛克的内幕
由来自 Pexels 的 Javon Swaby 拍摄的照片拼接而成
虽然许多在线网站可以生成照片马赛克,但在本文中,我们将深入了解照片马赛克,并创建一个可以创建照片马赛克的 Python 脚本。
什么是照片马赛克?
Raimond Klavins 在 Unsplash 上拍摄的照片
马赛克是一种用灰泥固定的彩色小块组成的图案。它们通常被用作墙壁或地板上的装饰。
一张蓝马 I 的照片马赛克
另一方面,照片拼接是由较小的照片拼接而成的照片。
它是如何工作的?
要创建一个照片拼版,我们需要主照片和一系列平铺照片。为了获得更好的效果,拼贴照片应该具有不同的颜色和亮度级别。
然后,程序如下:
- 像素化主照片。
- 将每个像素替换为颜色最接近的图块照片。
听起来很简单,对吧?嗯,我们应该做更多的事情。但是我们将在下一节中讨论这个问题。
设置
我们将把所有磁贴照片放在一个名为tiles
的文件夹中。
首先,我们需要导入一些模块。我们稍后会用到它们,并解释它们是做什么的。
然后,我们需要定义磁贴和主照片的路径,以及磁贴的大小。
导入照片
为了获取tiles
文件夹中的所有文件,我们将使用 glob 。
我们将使用 Pillow (PIL)的图像类导入图块并调整它们的大小。
计算平均颜色
然后,我们计算每个瓷砖的平均颜色,并将其保存在一个数组中。
为了像素化主照片,我们将使用 Pillow 的调整大小方法缩小它。我们将调整它的大小,以便调整后的照片中的每个像素都与原始照片中的图块大小完全相同。
最接近的颜色?
现在,我们需要为调整后的照片中的每个像素找到平均颜色最接近的图块。
我们不会担心“接近”的数学定义以及什么是标准距离或 T2 距离。但是如果你感兴趣,颜色是 3D 矢量(RGB 而不是 XYZ),所以它与 3D 空间中两点之间的距离相同。其可以被定义如下(欧几里德距离):
为了有效地做到这一点,我们将使用一个 k-d 树(不需要理解它是如何工作的),它是在 scipy 的空间模块中实现的。
我们必须从我们的平均颜色列表中创建一个 KDTree,然后使用查询方法进行搜索。
画瓷砖
现在,我们只需将图块绘制成输出照片。
结果
来自像素的迈克尔·布洛克的原始照片(左),照片拼接(右)(所有照片来自像素)
我们可以通过改变设置来获得不同的结果。
平铺尺寸 25×25(左)平铺尺寸 50×50(右)(所有照片来自像素)
命令行界面
我们可以让我们的脚本直接从终端运行。我们将使用以下语法:
python3 mosaic.py main_photo_path tiles_path tile_width tile_height output_path
我们必须将源代码和设置代码部分替换为:
最终的脚本变成了:
我们已经看到了如何用 Python 创建一个简单的照片马赛克。虽然它如预期的那样完美地工作,但我们可以通过在可能的情况下支持使用不同的磁贴照片,或者通过允许亮度/饱和度调整来改进它。
如何创建量子贝叶斯网络
原文:https://towardsdatascience.com/how-to-create-a-quantum-bayesian-network-5b011914b03e?source=collection_archive---------28-----------------------
实用指南
量子机器学习要不要入门?看看 动手量子机器学习用 Python 。
在我的每周量子机器学习挑战中,我问了一个简单的问题:“一个学生能解决挑战吗?”
在这篇文章中,我想告诉你如何用量子贝叶斯网络(QBN)来回答这个问题。
贝叶斯网络是对不确定领域的知识进行建模的概率模型。我们可以将这些模型表示为带有节点和边的有向无环图。
qbn 是入门量子机器学习的绝佳工具。它们直观、易于理解,然而,它们使用基本的量子计算概念。
在问题描述中,我们说学生能否解决挑战,取决于她是否看了我的书 用 Python 动手做量子机器学习。如果她做到了,她有 90%的机会解决挑战。如果她没读过这本书,她解决挑战的几率是 50%。此外,我们说 60%的学生读过这本书。
我们的问题描述包含三种不同类型的概率。
我们有两个条件概率:
- 如果学生读了这本书,她就能解决 90%的问题。
- 如果她没有,她解决了 50%的问题。
我们得到了一个边际概率:
- 60%的学生读了这本书
如果你需要刷新一下这些不同类型的概率,以及如何在量子电路中对它们建模,你可能会想要阅读这两篇帖子(量子编程——针对非数学家和量子计算实践)。
现在让我们来实现这些概率。我们从一点点准备开始。我们导入这些库,定义一个有用的函数prob_to_angle
,并创建一个具有两个量子位的量子电路。
接下来,我们让第一个量子位(在位置 0)代表 60%的学生读过这本书的边际概率。因此,我们使用 RY-gate,将预期概率作为参数调用prob_to_angle
函数的结果。
如果学生读过这本书,我们可以直接继续对条件概率建模。如果第一个量子位是 1,就是这种情况。只有当第一个量子位为 1 时,我们才在第二个量子位上应用代表 90%的旋转。这就是受控 RY-gate 的作用。
如果学生没有阅读这本书,为了应用条件概率,我们首先必须通过应用 X 门翻转第一个量子位的振幅。随后的 X-gate 恢复了这种效果。
让我们看看完整的电路。
当我们运行这个电路时,我们看到下面的概率分布。
右上角的数字代表第一个量子位的值。它代表学生是否读过这本书。左下角的量子位代表学生是否解决了问题。为了回答解决问题的总体(边际)概率,我们必须将第二个量子位为 1 的所有状态相加。
或者,我们可以简单地测量第二个量子位。下面的清单描述了完整的源代码。
该结果与之前模拟的总和之间的微小差异是由于我们使用的qasm_simulator
的经验性质。
结论
我们看了如何用 Python 实现一个简单的 QBN。我们了解到,我们可以用量子位来模拟节点,用量子门来模拟边缘。更具体地说,RY 门让我们模拟边际概率,受控 RY 门让我们模拟条件概率。
要回答学生能否解决挑战的问题,我们只需测量相应的量子位。答案是这个学生有 74%的机会解决这个问题。
量子机器学习要不要入门?看看 动手量子机器学习用 Python 。
免费获取前三章点击这里。
如何创建快速选举数据可视化:以 2021 年葡萄牙总统选举为例
原文:https://towardsdatascience.com/how-to-create-a-quick-election-data-visualisation-portuguese-presidential-race-2021-as-an-example-3855a2728b1e?source=collection_archive---------39-----------------------
选举似乎会吐出无穷无尽的数据,但你需要找到正确的角度并快速完成,这解释了为什么在这次选举中我们选择关注排名第三的候选人
别担心,我会翻译这个!(奥利弗·卡灵顿&若昂·席尔瓦使用数据包装器制作的图表)
2021 年的第一次欧洲选举是选举葡萄牙行政首脑。毫不奇怪,在争夺选票的七名候选人中,获胜者是现任的 72 岁的社会民主党的马塞洛·雷贝洛·德索萨。然而,这里的数据-viz 故事不是谁赢了,而是第三名的极右翼候选人令人担忧的成功。
找到合适的角度去追求
追踪极右民粹主义的崛起比以往任何时候都更加重要
在任何数据-viz 中,你都希望以一种帮助观众更好地理解主题的方式来分析和可视化数据。关注在任总统不会有太多启发性,他获得了 60.7%的选票和每个城市的大多数选票。
相反,我们关注的是来自极右翼政党 Chega 的 André Ventura,翻译过来就是“T2 够了!’。这是一个新成立的民族主义政党,与新纳粹团体有联系。他获得了 11.9%的选票,以微弱优势被社会党的安娜·戈梅斯击败,获得 13%的选票,位居第二。
这一特殊角度的有趣之处在于,葡萄牙被视为欧洲政治版图中没有极右势力的例外。47 年前,康乃馨革命将这个国家从萨拉扎主义的独裁统治中解放出来,走向民主。直到现在,它还在抵制当代政治中的民粹主义趋势。
2019 年 10 月,文图拉以微弱优势赢得议会席位,这并不被视为一件大事。但从那以后,这位极右翼政客利用这个平台来建立自己的合法性,并利用新冠肺炎造成的经济问题。
在我们的数据中,我们显示了投票给文图拉的百分比,在马德拉和亚速尔群岛的每个地区和自治区,从 8%到 20%不等。该地区的颜色越深,支持文图拉的选票就越多。你可以看到极右翼的选票更多地集中在葡萄牙更偏远的内陆地区以及南部的贝哈和法罗地区——旅游热点和历史上的共产主义据点。
我们考虑的其他选择是根据第二名候选人或第二名和第三名候选人之间的票数差异来给区域着色,但我们决定采用上述数据——即最佳故事。2021 年美国国会大厦被攻占后,追踪极右翼民粹主义的崛起比以往任何时候都更重要。
用不同层次的细节来测试你的地图
人们希望看到每个地区如何投票,并找到视觉模式
地图将是主要的数据类型——也就是说,你可以用它来将选举数据变得生动。这是因为选举结果与地区有关,如国家、地区、议会,甚至邮政编码。人们希望看到每个地区的投票情况,并找到视觉模式或全国各地不同的主流意识形态。例如,2016 年英国英国退出欧盟投票显示了城市和农村地区的明显差异。
这些葡萄牙选举结果可以分为 20 个大区或 308 个小得多的市。这给了我们一个机会来看看哪张地图最符合结果。我们选择了地区而不是市,因为这样更容易看到关键趋势。
使用地图时,一定要记住地图中的区域在人口规模上是不相等的,因为一个国家的主要城市会聚集在不同的区域。波尔图区在地图上看起来可能很小,但它拥有第二大人口——比 9 个人口最少的区加起来还多。
美国的选举地图就是一个很好的例子,无论结果如何,它都倾向于显得更红,因为南部和中西部的大州几乎总是投票给共和党。Karim Douï eb 用他们出色的动画突出了这一点,提醒我们“英亩不投票,人们投票”。
最后的润色总是很重要
考虑你的观众是很重要的
颜色在选举数据中极其重要。政党是与特定的色调联系在一起的,除非引起混乱,否则应该保留这些色调。例如,在英国,苏格兰民族主义党的黄黑色和自由民主党的黄色在不并排的情况下看起来非常相似。我们选择了一个类似于 Chega 的深色调色板,最深的阴影表示他获得了最高的投票率。
考虑你的受众也很重要。葡萄牙民粹主义极右势力姗姗来迟的发展可能会引起许多人的兴趣,但显然主要是葡萄牙人自己。大多数葡萄牙人说英语,然而,使用葡萄牙语单词是一种抓住葡萄牙观众眼球的方式,让他们知道这是专门为他们准备的。
用于创建数据的数据和工具——即
我们下载了的官方选举结果,并使用的 datawrapper.de 创建了我们的“choropleth 地图”,使用了他们的葡萄牙政治区域地图。
找到我们的推文(通常是英文的!)像这样在@ olliecarrington&@ jpvsilva 88
如何用 Python 创建雷达图
原文:https://towardsdatascience.com/how-to-create-a-radar-chart-in-python-36b9ebaa7a64?source=collection_archive---------4-----------------------
雷达图是一种用于比较多个变量的可视化技术。这是一个关于如何用 python 创建雷达图的教程。
雷达图 ,又称 蜘蛛图 或 网络图 是一种用于比较多个数量变量的图形方法。这是一个二维极坐标可视化。
这是一个关于如何用 python 制作雷达图的教程。
导入库
我们将使用Matplotlib库进行可视化,使用 NumPy 库进行几个数学函数。
*import numpy as np
import matplotlib.pyplot as pltplt.style.use('ggplot')*
注意,我已经将 matplotlib 的样式设置为 ggplot ,你可以设置自己喜欢的样式或者使用默认样式。
可视化数据
我们将使用雷达图可视化两名学生- 爱丽丝和鲍勃在五个科目中获得的分数。
科目和分数以列表形式提供。
*subjects=['PHY','CHEM','BIO','MATH', 'ECO']
alice=[60,40,68,94,27]
bob=[81,30,75,37,46]*
获取角度
在本例中,我们使用雷达图来显示 5 个变量。因此,图表将有 5 个极轴。
圆内的总角度为 360 度(2π弧度)。每个轴之间角度将是 72 度(360/5)。
Matplotlib 使用弧度角度准备极坐标图。我们可以使用 numpy 的行间距函数获得角度,如下所示。
*angles=np.linspace(0,2*np.pi,len(subjects), endpoint=False)
print(angles)**Output:**[0\. 1.25663706 2.51327412 3.76991118 5.02654825]*
注意端点参数必须设置为假。
完成整圈
我们已经获得了每个变量的角度。然而,这只能生成圆的五分之四,我们必须在数组的末尾添加第一个角度来完整地描述圆。
*angles=np.concatenate((angles,[angles[0]]))
print(angles)**Output:** [0\. 1.25663706 2.51327412 3.76991118 5.02654825 0.]*
类似地,必须为用于可视化的所有其他数组/列表追加第一个值,以保持长度一致性。
*subjects.append(subjects[0])
alice.append(alice[0])
bob.append(bob[0])*
绘制雷达图
在 add_subplot 函数中设置 polar=True 可以绘制一张基本雷达图。并提供角度和值作为绘图函数的自变量。
*fig=plt.figure(figsize=(6,6))
ax=fig.add_subplot(polar=True)
ax.plot(angles,alice)
plt.show()*
作者图片
定制雷达图
我们可以通过添加更多信息来定制雷达图。
线条和标记 线条和标记样式可通过在绘图功能中提供参数来改变。
在下面的代码中,使用位置参数设置线条和标记样式,类似于 matplotlib 折线图。
使用 plot 函数的 color 参数设置线条颜色。
填充绘图区域
绘图可以使用填充函数填充,提供角度和值作为参数。
使用颜色和 alpha 参数可以设置颜色和不透明度。在比较多个实体时,使用对比色和较低的 alpha 值是一个很好的做法。
添加极坐标网格和标签 我们可以在上图中观察到,极坐标轴彼此间隔 45 度,角度作为标签提供。
使用 set_thetagrids 功能可以定制角度和标签的间距。
添加图例 通过使用 plt.legend 函数,并在 plot 函数内设置标签,可以添加图例。
添加或删除网格 网格功能可以用来显示/隐藏圆形网格。
*fig=plt.figure(figsize=(6,6))
ax=fig.add_subplot(polar=True)#basic plot
ax.plot(angles,alice, 'o--', color='g', label='Alice')
#fill plot
ax.fill(angles, alice, alpha=0.25, color='g')
#Add labels
ax.set_thetagrids(angles * 180/np.pi, subjects)plt.grid(True)
plt.tight_layout()
plt.legend()
plt.show()*
作者图片
爱丽丝 vs 鲍勃
最后,我们到了教程中备受期待的部分,爱丽丝如何对抗鲍勃?这个问题可以通过将 Alice 和 Bob 的雷达图组合在同一个图表中来回答。
*fig=plt.figure(figsize=(6,6))
ax=fig.add_subplot(111, polar=True)#Alice Plot
ax.plot(angles,alice, 'o-', color='g', linewidth=1, label='Alice')
ax.fill(angles, alice, alpha=0.25, color='g')#Bob Plot
ax.plot(angles,bob, 'o-', color='orange', linewidth=1, label='Bob')
ax.fill(angles, bob, alpha=0.25, color='orange')ax.set_thetagrids(angles * 180/np.pi, subjects)plt.grid(True)
plt.tight_layout()
plt.legend()
plt.show()*
作者图片
只要浏览一下雷达图,我们就能发现爱丽丝的数学成绩比鲍勃好得多。
它们在生物学和化学方面的表现不相上下。鲍勃在物理和经济方面的表现比爱丽丝好。
这就是雷达图的优势,在比较多个变量上的几个实体时非常容易理解。
雷达图是比较 2-4 个实体和 3-10 个定量变量的理想工具。大量的实体或变量会使图表混乱,难以理解。
资源
教程的全部代码可以在 GitHub 库中找到。
您可以在此处访问视频格式的教程:
https://www.youtube.com/watch?v=_VdOPQiaN64
成为会员
我希望你喜欢这篇文章,我强烈推荐 注册中级会员 来阅读更多我写的文章或数以千计的其他作者写的各种主题的故事。
你的会员费直接支持我和你看的其他作家。你也可以在媒体上看到所有的故事。
作者的类似文章
*https://medium.com/geekculture/generate-gantt-chart-in-python-9d1e1fe9103e https://medium.com/geekculture/how-to-plot-a-treemap-in-python-48743061cfda
作者图片*
如何使用 DAX 在 Power BI 中创建评级可视化
原文:https://towardsdatascience.com/how-to-create-a-rating-visual-in-power-bi-using-dax-859c57a96daf?source=collection_archive---------24-----------------------
了解如何通过编写几行 DAX 来创建自定义评级视觉效果
作者图片
在我的上一篇文章中,我解释了如何使用 UNICHAR() DAX 函数利用一个非常简单的技术在轴上和切片器中显示图像和图标。现在,我希望对此进行扩展,并展示如何使用简单的 DAX 创建评级可视化!让我不谦虚地说,使用这个技巧,你可以自由地说,你创造了自己的自定义视觉!
搭建舞台
正如在我之前的帖子中一样,我将使用一个与支持代理与客户互动相关的数据集—作为提醒,代理通过聊天、电子邮件和电话与客户沟通,在互动完成后,客户可以填写调查并表达她的/他的意见。要求客户回答三个问题:
- 解决方案 —我的问题被支持代理解决了吗?
- 满意度 —我对分辨率满意吗?
- 推荐 —我会向他人推荐公司的服务吗?
我将使用与之前相同的数据集,但只关注调查结果。以下是 Power BI 中导入的原始数据:
作者图片
让我们首先试着从这个数据集中获得一些洞察力——例如,有多少客户对服务感到满意,其中有多少会推荐该公司的服务。我将创建三种方法来计算积极响应的调查:
Resolution YES = CALCULATE(
COUNT(Surveys[Interaction ID]),
Surveys[Resolution] = "Y"
)Satisfaction YES = CALCULATE(
COUNT(Surveys[Interaction ID]),
Surveys[Satisfaction] = "Y"
)Recommendation YES = CALCULATE(
COUNT(Surveys[Interaction ID]),
Surveys[Recommendation] = "Y"
)
如果我将这些指标拖到我的报告中,我可以获得一些,至少是基本的,关于客户满意度的见解:
作者图片
还不错,但是企业会问的第一个问题是:对我们的服务满意的客户比例是多少?那么,让我们来创建一个计算肯定答案百分比的方法:
Resolution % = DIVIDE([Resolution YES], [Total Surveys],0)Satisfaction % = DIVIDE([Satisfaction YES], [Total Surveys],0)Recommendation % = DIVIDE([Recommendation YES], [Total Surveys],0)
不要忘记将这些指标格式化为百分比:)
并且,在我格式化我的表格之后,报告看起来非常好:
作者图片
将用户体验推向新的高度
好了,这就达到了目的,报告消费者可以很快看到满意客户的百分比。然而,如果我想让他们“感受”评级体验——你知道亚马逊、网飞等网站上的那些好明星。向你展示产品的等级。Power BI 不提供现成的可视化评级。你可以从 App Source Marketplace 获得它(至少它以前存在过,我猜它现在仍然可用),但是…
如果我告诉你,你可以通过写一些简单的 DAX 来创建一个评级可视化?!
让我们卷起袖子开始工作吧。我们的想法是将百分比显示为报告中的星号。上次,我们创建了一个图标的列,包含它们的 Unicode 值,作为占位符。这一次,我们想建立一个衡量指标,来表达客户满意度背后的数字。同样,我们将利用 UNICHAR()函数,但方式略有不同。
它应该是这样工作的:对于百分比值的每个十进制,我想显示一个星号—简单地说,如果百分比值是,比如说,63%,我将显示 6 个星号…如果值是 72%,我将显示 7 个星号,依此类推。让我向你展示我们如何实现这一点。
我表中的百分比不过是小数,用百分比表示。也就是说,63.01%本质上是 0.63(如果我们把它切到小数点后两位),58.93%是 0.59,以此类推。现在,我将复制这些度量,但我会将它们格式化为十进制数:
作者图片
我的表格现在显示了客户回答的小数值和百分比。我现在将使用 UNICHAR()函数在我的表中显示星号。但是,为了显示适当数量的星星——记住,53%是 5 颗星,63%是 6 颗星,等等。—我必须对我的度量进行一些修改。
我会把结果乘以 10,所以 0.78 会变成 7.8,0.56 会变成 5.6,以此类推。然后,我可以从结果中检索整数值,并设置星形符号的外观!
Resolution % Decimal Multiplied = [Resolution % Decimal] * 10
我现在将使用 REPT() DAX 函数,它基本上重复定义的文本,重复的次数是您在该函数的第二个参数中指定的次数。在我的例子中,我是这样写的:
Stars v1 = REPT(UNICHAR(11088),[Resolution % Decimal Multiplied])
让我停下来解释一下这个度量的特别之处:它将重复第一个参数,这是 Unicode 值 11088 的 Unicode 表示,乘以我们的百分比值中的十进制数。多酷啊!
作者图片
如您所见,该函数足够“智能”,可以像您预期的那样对多个星进行四舍五入,因此,77.66%表示为 8 个星,而 58.33%和 56.21%显示为 6 个星。
太棒了!但是,如果我想让我的用户能够立即发现评级,而不需要数星星呢?换句话说,我想显示最大可用值(在我们的例子中是 10 颗星),然后,根据百分比,一些星将保持为空。简单来说,如果百分比值是 77.66%,我想显示 8 颗黄星和 2 颗空星(和亚马逊一样,呵呵)。
让我们开始写我们的最终措施:
Stars v2 = [Stars v1]&(REPT(UNICHAR(10025),10-[Resolution % Decimal Multiplied]))
那么,我们在这里有什么:措施的第一部分是完全相同的,因为我们想要显示我们的积极的星星。但是,神奇的事情发生了:由于 REPT()函数处理文本值,我们可以简单地连接另一部分——在这一部分中,我们显示 Unicode 值 10025 的 Unicode 符号(空星号),然后我们希望重复它的次数,次数等于 10(这是星号的最大值)和我们的“正”星号的数量之间的减法值——因此剩余的次数将显示空星号。
作者图片
很棒,不是吗?
结论
看了上面的插图,你可能会得出结论,我们已经成功做到了!我们仅使用 DAX 创建了一个显示评级的自定义视觉效果。
我要再重复一遍:Power BI 是一个非常棒的工具,因为它为您提供了惊人的灵活性,可以用多种不同的方式讲述您的数据故事。只需很少的创意和一些简单的调整,你就可以为你的用户创造一个难忘的体验。
在本文中,我已经向您展示了如何通过编写几行 DAX 代码来实现(im)可能性并创建您自己的自定义可视化!
感谢阅读!
成为会员,阅读 Medium 上的每一个故事!
如何从 SEER 数据库创建一个简单的 Excel 数据集
原文:https://towardsdatascience.com/how-to-create-a-simple-excel-data-set-from-the-seer-database-6f1794249fa3?source=collection_archive---------18-----------------------
SEER*Stat 软件的一个应用
作者使用 Canva 制作的图像
在以前的文章中,我强调了监测、流行病学和最终结果(SEER)数据库的价值,它是全世界研究人员随时可获得的基于人群的癌症数据来源。
简而言之,如果您是一名对癌症流行病学充满热情的有抱负的研究人员,您可以使用 SEER 数据库来提取数据,您可以立即或稍后使用这些数据来运行统计测试并获得有价值的见解。
https://ame48.medium.com/this-database-will-save-you-tons-of-time-and-effort-towards-publishing-your-first-cancer-research-b1e3888c3dc
为了更快地进入角色并开始使用 SEER 数据库,我建议您观看以下视频,其中我解释了如何访问 SEER 数据库,以及下载并安装 SEER*Stat 软件,您应该使用该程序从 SEER 数据库中提取癌症相关数据。
阅读并观看了上述资源后,您现在应该已经下载了 SEER*Stat 并安装在您的计算机上。此外,您应该已经通过电子邮件收到了您的用户名和密码,以便开始提取数据。
我打算做的是从 SEER 数据库中提取一个小数据集,并将这些数据转移到 Microsoft Excel 文件中,以便用统计软件(如 JMP、R 或 Python)打开它,并可视化数据或用它进行一些数据分析。
但是在进行任何统计测试之前,我们应该先在 Excel 中保存我们的数据,这是我想在字里行间教给你的。
分析样本
首先要做的是指定要提取数据的癌症病例组。出于演示的目的,为了获得一个小的数据集(大约 100 个案例),我将向我的选择语句添加更多的条件,以便达到目标样本。
因此,登录 SEER*Stat 后,让我们单击“案例列表”会话。请参见下面上传的截图,了解在哪里可以找到“案例列表”会话。
单击“case listing”会话后,这是可用数据库的视图,您可以从中提取数据。默认情况下,突出显示的数据库将是最新的数据库,除非您另外指定。
我将忽略最近的数据库,选择标题为“发病率— SEER 18 Reg 研究数据+卡特里娜飓风影响路易斯安那州案例,2017 年 11 月(1973–2015)”的数据库。这个标题意味着我们提取的数据来自 18 个癌症登记处,包括 1973 年至 2015 年间诊断的病例,并于 2017 年 11 月提交到 SEER 数据库。
点击所需的数据库后,它将以蓝色突出显示,您的计算机将花费几秒钟时间链接到所需的数据库。此外,所选数据库的建议引用将被更改,以匹配您将使用的数据库。看下面截图就知道区别了。
现在,您可以点击“选择”选项卡,开始选择您的癌症病例。
点击“选择”选项卡后,您将看到下面的默认选择屏幕。这是在您指定任何选择标准之前。它将如下所示。
这是我们提取过程中最重要的一步。
分析样本。
我将根据以下选择标准选择一个样本:
- 附加说明的胰腺癌病例。
- 女性。
- 黑人。
- 2010 年确诊。
- 离婚了。
这产生了一个大小为 110 个案例的分析样本。完美!
这就引出了我们如何向 SEER*Stat 提供我们的选择标准,以获得我们的目标样本。
让我们从选择胰腺癌的病例开始。
从我们最后的截图:
(1)单击“编辑”选项卡。
(2)单击“部位和形态”处的(+)号
(3)点击“现场记录 ICD-O-3/世卫组织 2008”。运算符设置为 is = to。
(4)向下滚动数值,直到到达“胰腺”。点击它。
(5)单击“确定”。
单击“确定”后,您将自动发现您选择的标准已添加到选择语句中(参见下面的屏幕截图)。
基于之前的选择标准,我们现在将选择“女性”。为此,请使用 SEER*Stat 软件遵循这些说明。
(1)单击“编辑”选项卡。
(2)单击“种族、性别、年份、注册地、县”处的(+)号
(3)点击“性”。运算符设置为 is = to。
(4)点击“女性”。
(5)单击“确定”。
然后,我们将使用与上一步中选择“女性”相同的方法和步骤来选择“黑色”。请注意,在(5)每一步单击“确定”后,选择语句的行数将增加,增加的数量是您将输入 SEER*Stat 的选择标准的数量。
然后,我们用同样的方法选择“2010 年”作为诊断年份。请看下面截图,看详细步骤。
然后,我们将使用相同的方法选择“离婚”,但这一次,我们要在一个名为“其他”的文件夹内找到它。单击该文件夹左侧的(+)号后,我们将找到多个文件。然后,我们将点击名为“诊断时的婚姻状况”的文件。从这里开始,值“离婚”将显示在运算符右侧的值中,如下所示。
然后,下面的选择语句将最终包含我们之前陈述的所有选择标准。
此时,我们应该已经完成了选择过程,我们应该转到“table”选项卡,以便开始设计数据表,我们最终会将该数据表转换为 Microsoft Excel 数据集。
那么,让我们继续,单击“表格”选项卡。这将把我们带到下面的界面。
它是这样工作的。我们从下面截图底部的“可用变量”列表中选择变量。通过单击文件夹左侧的(+)符号打开黄色文件夹,然后单击选定文件夹下的变量文件,即可选择变量。在点击(选择)变量后,我们点击截图最右边的“列”按钮,变量就会显示在截图左上角的“列”字下面。
我们来演示一下!
我们将为数据表选择 3 个列变量:
- 患者 ID(可在“其他”文件夹中找到)。
- 诊断时的年龄(可在“种族和年龄[仅病例数据]文件夹中找到)。
- 存活月数(可在“死因[COD]和随访”文件夹中找到)。
下面的屏幕截图演示了选择“患者 ID”作为列变量时应该遵循的步骤。
我们使用相同的方法选择“诊断时的年龄”作为列变量。
“生存月”也是同样的方法。
在我们完成选择列变量之后,数据表的最终设计将如下所示。
然后,要获得我们的数据表,剩下的工作就是在“Title”部分为我们的表创建一个名称,然后单击黄色的螺栓形状的按钮。
SEER*Stat 将花费几秒钟时间编译数据表。
正如您在下面圈出的文字中看到的,SEER*Stat 告诉我们,总共有 110 例胰腺癌符合我们的选择标准。
我们到了。我们的数据表终于有了!
当然,我们不能直观或分析这个数据表。它必须被转移到一个 Excel 文件中,以便在 Excel 中进行分析,或者通过另一个统计软件包打开以便进行分析。
因此,要将该数据表转移到 Excel 中,只需将鼠标悬停在患者 ID 列标题上,直到鼠标指针变为向下的黑色小箭头。从那里,左击列标题,你会看到所有的列变成“黑暗模式”。按住左键向右移动以包含其他两列。
当所有三列都突出显示时(变为黑暗模式),右键单击鼠标,在突出显示的表旁边会出现一个下拉菜单。左键点击“复制”,SEER*Stat 会复制你的数据表。
现在,您已经准备好传输数据了。你所要做的就是打开 Excel,粘贴数据,如下图截图所示。
如何在 Jupyter 笔记本中创建时间线
原文:https://towardsdatascience.com/how-to-create-a-timeline-in-jupyter-notebook-a9530a639087?source=collection_archive---------35-----------------------
将基于 javascript 的时间轴集成到 Jupyter 笔记本中
照片由维达尔·诺德里-马西森在 Unsplash 拍摄
在处理时态数据时,为了更好地理解数据,能够在时间线上查看数据总是有用的。
有一些内置的 python 解决方案,比如这个和这个。然而,我发现它们不够灵活。我想提出另一个解决方案,它稍微复杂一点,但是给你更多的灵活性。将一个真正伟大的 javascript 库( vis.js )集成到一个 Jupyter 笔记本中,该库处理通用 web 应用程序上的时间线(不要担心它没有听起来那么复杂)。
- 安装 vis.js 时间表:
npm install vis-timeline
2.为您的 Jupyter 笔记本生成配置(如果您还没有配置):
jupyter notebook --generate-config
3.打开用于编辑配置文件,位于 ~/。jupyter/jupyter _ notebook _ config . py(Linux 和 macOS,在 windows 上在同等位置)。取消文件中带有c . notebook app . extra _ static _ path的行的注释。将路径放入已安装的 vis-timeline dist 文件夹,应该是这样的:
c.NotebookApp.extra_static_paths = ['~/node_modules/vis-timeline/dist']
(注意,在 windows 上,您需要在路径中使用双反斜杠,而不是单斜杠)。
4.运行(或者重新启动,如果它之前正在运行):
jupyter notebook
现在,您的笔记本已准备好使用 vis.js 时间轴。
为此,您需要 3 个 Jupyter 笔记本电池:
- Python 单元格,您可以在此创建数据。对于这个简单的例子,我创建了两个事件,一个在 12 月 20 日,另一个在 12 月 25 日。这段代码将我们的事件放在浏览器的窗口上,因此以后可以在 javascript 单元格中使用它。
2.一个 Html 单元格,带有一个时间线占位符。
3.Javascript 单元格。我们导入 vis.js 本身的 js 和 css 文件,然后从窗口中获取我们的事件,并使用 vis.js 库将它们放入 timeline 对象中。
现在,您应该在 HTML 单元格中看到这个基本的时间线:
时间线在这一点上看起来并不令人印象深刻。但是,使用这里介绍的方法,您可以将 javascript 库中的所有灵活性带到您的 Jupyter 笔记本中(在单击事件时添加功能,为每个节点创建不同的样式,等等)
为了理解如何创建更复杂的时间线,你可以在这里看到所有文档。
如何创建基于矢量的电影推荐系统
原文:https://towardsdatascience.com/how-to-create-a-vector-based-movie-recommendation-system-b6d4f7582d66?source=collection_archive---------10-----------------------
相关事件
使用变形金刚和矢量技术构建电影推荐系统。
在这篇文章中,我将向你展示如何对电影数据集进行矢量化,在教程的最后,我将使用最近邻完成电影推荐系统。完整的代码可在我的回购处获得。
由苏维克·班纳吉在 Unsplash 上拍摄的照片
电影推荐系统是目前最受欢迎的人工智能应用之一。建立电影推荐系统有几种方法,从基于线性代数方程的简单算法到试图预测哪个是用户最佳选择的复杂神经网络。
由于技术在过去几年里进步很大,建立电影推荐系统的新的复杂方法已经被开发出来,以增强网飞或淘宝等平台的用户体验。公司只对最新技术感兴趣,因为它会使旧型号过时。目前,基于向量的搜索主导着推荐系统市场。
在这篇文章中,我将下载一个电影数据集,清理它,编码它,最后对它进行矢量搜索:该软件将有一部电影作为输入,并将推荐 5 部电影作为输出。
构建软件
这个电影推荐系统将通过以下步骤来构建:
- 安装库
- 下载数据集
- 预处理数据集
- 编码数据
- 执行矢量搜索
1.安装库
我将用来编码数据的主要库是 relevanceai,它为您提供了最新的转换器来编码您的数据:
!pip install -U relevanceai
我还打算安装第二个库,这样我们就可以在电脑工作时跟踪编码进度。因为这个过程可能会很长(可能需要 2 个小时),如果您不希望使用我提供给您的已经编码的数据集,最好使用一个进度条,您可以用一个名为 tqdm 的库来实现它:
!pip install tqdm>=4.62.2
2.下载电影数据集
原始数据集已经从 Kaggle 下载(MPST:带标签的电影情节概要,由 Sudipta Kar 出版)。我将使用熊猫库来处理这个数据集。我们在这个过程中只需要两种数据(我会尽量保持简单)就是电影标题和描述。用户将使用标题来引用他们想看的电影,而电影的描述将被编码在向量空间中。对数据进行编码后,我们不再需要电影描述。
import pandas as pddf = pd.read_csv('mpst_full_data.csv')
3.预处理电影数据集
除了去掉我们实验中不会用到的所有其他额外特性,电影数据集还包含不完全相同的副本,因此我们不能简单地使用 drop_duplicates pandas 函数来去掉它们。举个例子,我找到过同名电影:《复仇者联盟》和《复仇者联盟》。
在预处理阶段,我需要确保从我们的数据中删除大多数重复的内容,否则,用户体验将与功能良好的推荐系统不一样。
为了避免重名,我只关注电影名。有几种方法可以解决这个问题,我已经为这个特定的目的构建了一个现成的算法:我将按字母顺序对标题进行排序,然后查看连续的标题是否相似(通过使用 Levenshtein 距离),如果相似,我将删除连续的标题。
df = df.sort_values('title').reset_index(drop=True)
df['lev'] = None
dffrom Levenshtein import distancefor a in range(len(df)-1):
if distance(df.iloc[a].title, df.iloc[a+1].title) <= 3:
print(a, df.iloc[a].title, df.iloc[a+1].title)
df.at[a, 'lev'] = distance(df.iloc[a].title, df.iloc[a+1].title)
df
#we filter similar movies
df = df[df['lev'].isnull()].reset_index(drop=True)
df
对于一些非常著名的电影,我将亲自执行手动检查以避免任何问题:我将尝试使用该软件的第一部电影显然是《复仇者联盟》:
#find Avengers duplicates
for a in range(len(df)):
if df.iloc[a]['title'].find('Avengers') != -1:
pass
#print(a)
#drop extra
df = df.drop([9572]).reset_index(drop=True) #i can do 1, 2, 3... to drop multiple
df
df.to_csv('mpst_no_duplicates.csv')
电影数据集的屏幕截图,图片由作者提供
4.编码数据
如果您想更详细地了解什么是转换器,以及对您的数据进行编码的其他可行选择,您可以关注我的技术解释。有几种型号可以选择:最快的一种(我要用的那种)叫做全迷你 L6 v2。还有更复杂的模型,如 all-mpnet-base-v2 ,它们更精确,但它们需要大量的计算能力。例如,通过使用最后一个模型,我们的计算机可能需要 10 小时,而不是 2 小时。
在这段代码中,我将使用 relevance API 将电影描述编码成向量。我习惯使用这个库,因为它是一个比它的许多替代品更灵活的包装器。因为它不直接接受 pandas DataFrame 作为输入,所以我需要将我的数据转换成一个字典列表:
json_files = df[['title', 'plot_synopsis']]
json_files = json_files.reset_index()
json_files.columns = ['_id', 'title', 'plot_synopsis']
json_files=json_files.to_dict(orient='records')
json_files
这些文件看起来是这样的:
{'_id': 0,
'title': '$',
'plot_synopsis': 'Set in Hamburg, West Germany, sev...
{'_id': 1,
'title': '$windle',
'plot_synopsis': 'A 6th grader named...
{'_id': 2,
'title': "'71",
'plot_synopsis': "Gary Hook, a new recruit to the British Army, takes leave of ...
现在,我们可以通过选择一个可用的模型来开始编码过程。
#encode on local
from vectorhub.encoders.text.sentence_transformers import SentenceTransformer2Vec
model = SentenceTransformer2Vec("bert-base-uncased")
df_json = model.encode_documents(documents=json_files, fields=['plot_synopsis'])
df_json
一旦编码完成,relevanceai 库并没有替换原来的字段 plot_synopsis ,而是创建了另一个带有sentence _ transformers _ vector _后缀的字段。
[{'_id': 0,
'title': '$',
'plot_synopsis': 'Set in Hamburg, West Germany, several criminals take...
'plot_synopsis_sentence_transformers_vector_': [-0.25144392251968384,
-0.03958860784769058,
0.15455105900764465,
-0.08302052319049835,
0.5842940807342529,
0.07232926040887833,
0.28563958406448364
4.用熊猫编码数据
或者,如果你想继续学习熊猫,你仍然可以使用句子变形库。选择不同的格式取决于你希望如何使用你的数据:例如,在前一种格式中,我可以使用 relevanceAI API 来在线上传我的数据,因此它是可扩展的,可以被成千上万的用户使用。
因为这个过程可能需要一个多小时才能完成(有些编码模型可能需要 12 个小时,所以要小心选择哪一个),所以我用一个进度条来记录进度(关于实现它的更多信息,我写了这个有趣的指南):
from tqdm import tqdm
from sentence_transformers import SentenceTransformer
import numpy as nptqdm.pandas()model = SentenceTransformer('all-MiniLM-L6-v2') #all-MiniLM-L6-v2 #all-mpnet-base-v2df_ = df.copy()
df_['plot_synopsis'] = df_['plot_synopsis'].progress_apply(lambda x : model.encode(x))
df_index = df_.pop('title')
df_ = df_[['plot_synopsis']]
df_ = pd.DataFrame(np.column_stack(list(zip(*df_.values))))
df_.index = df_index
df_
带有熊猫的矢量化数据的屏幕截图,图片由作者提供
完成后,不要忘记将您的数据保存到一个. csv 文件中!
df_.to_csv('mpst_encoded_no_duplicates.csv')
5.执行矢量搜索:测试你的电影推荐系统
通过执行矢量搜索,我将把一部电影输入到数据集中。因此,该软件将找到空间中最近的 5 个点是什么,每个点代表一部类似的电影:这就是我们所说的推荐系统。
我提供的解决方案将在您的本地机器上完美地工作。然而,部署基于向量的产品的问题是伸缩性。我发现的最好的解决方案之一是 relevanceai API ,你可以用它将你的矢量数据库转换成 API 调用。
相反,要在本地执行矢量搜索,我可以使用为我提供最近邻算法的 sklearn API 。我要做的第一件事是再次加载数据集(您不需要这样做,但最好用同一个数据集的导入和导出来分隔每个代码段):
import pandas as pddf_movies_encoded = pd.read_csv('mpst_encoded_no_duplicates.csv')
df_movies_encoded.index = df_movies_encoded.pop('title')
df_movies_encoded
我们现在可以在最近的邻居 sklearn 类上训练该算法:我们将把训练好的模型存储在名为 nbrs 的变量中,这将允许我们在给定一个输入的情况下检索两个点(初始点的坐标加上其最近邻居的坐标)。
from Levenshtein import distance
from sklearn.neighbors import NearestNeighbors
import numpy as np
import pandas as pdnbrs = NearestNeighbors(n_neighbors=2, algorithm='ball_tree').fit(df_movies_encoded)#string-searching algorithm
def closest_title(title):
m = pd.DataFrame(df_movies_encoded.index)
m['lev'] = m['title'].apply(lambda x : distance(x, 'Prince of Egypt'))
return m.sort_values('lev', ascending=True)['title'].iloc[0]
当前数据集的主要问题是在搜索不在数据集中的电影的情况下,或者如果您打错了。例如,如果你搜索“复仇者联盟”,因为数据集只有“复仇者联盟”这个词,它将无法搜索到你的关键字,并将抛出一个错误。这很不方便,尤其是因为我们假设许多用户会快速输入搜索,甚至会输入错误。这个问题的解决方案是使用一种字符串搜索算法,无论我们输入什么,都会找到最佳答案。我使用 Levenshtein 距离创建了一个自定义的:
def find_similar_movies(df, nbrs, title):
#if title not in df it will choose the best search
title = closest_title(title)distances, indices = nbrs.kneighbors([df.loc[title]])
#print(indices)#we print df data, no longer df_
for index in indices[0][1:]:
print('index', index)
print(title, '->', df.iloc[index].name)
该算法将接收电影的名称作为输入,并将输出最近邻的名称:
find_similar_movies(df_movies_encoded, nbrs, 'Prince of Egypt')index 11440
The Prince of Egypt -> The Ten Commandments: The Musical
精彩:似乎在起作用!
结论
在这篇文章中,我向你展示了如何构建一个简化的推荐系统。对于这类任务,我们是否已经达到了复杂性的顶峰?差远了。在本教程中,我们使用一个包含数据集中所有电影关系的向量空间,但我们忽略了个人用户历史。
为了给平台上的每个用户提供增强的体验,我们应该收集其选择历史,并为每个用户创建独特的推荐。能够达到这种复杂程度的模型被称为多模态嵌入,它们将在后续文章中进行分析。尽管有其局限性,像这样的向量空间电影推荐系统仍然能够很好地执行,并提供令人满意的用户体验。
如何在几分钟内创建一个 Web 应用程序,进行预测并解释它们
原文:https://towardsdatascience.com/how-to-create-a-web-app-in-minutes-that-makes-predictions-and-explains-them-31b7d1a54b3a?source=collection_archive---------23-----------------------
图片作者。
数据科学家简明指南。
本指南向你展示如何快速开发网络应用。这很容易,你很快就能准备好!额外收获是:你学会了如何用简单的英语解释你的预测。因此,即使是朋友和家人也能理解导致这一预测的因素。享受创建自己的网络应用程序!
创建 Web 应用程序的 4 个步骤
- 数据预处理和模型创建
- 安装 Streamlit 并开发 web 应用程序
- 运行 web 应用程序
- 部署 web 应用程序
我将在下面讨论这些步骤。作为奖励,你可以阅读如何向任何人解释这些预测。该代码可在我的 GitHub 上获得。你可以查看和测试蘑菇网络应用,我将用它作为例子。
步骤 1:数据预处理和模型创建
一如既往,新的数据科学项目从处理、分析和建模数据开始。这个网络应用程序将根据蘑菇的六个特征来决定蘑菇是否可以食用。数据集包含蘑菇的 22 个特征。
在原始数据集中,数据集值是字母。例如,对于气味一栏,“p”表示刺鼻,“a”表示茴香,“n”表示没有,以此类推。不熟悉数据集的人无法理解这些字母。通过使用字典并映射这些值,很容易解决这个问题。通过这样做,字母被它们的含义所取代。我们需要这一步用于 web 应用程序侧边栏和解释预测。现在,我们可以对列进行标签编码并构建一个模型。
通过训练和评估不同的模型和预处理数据集,确定最重要的特征。这些特征是孢子印的颜色、气味、鳃的大小、栖息地、种群、茎根和瘀伤。使用标签编码的数据集很容易创建一个完美的预测模型,web 应用程序中使用的模型达到了 1 的精度,即使它只使用了 6 个特征。
我希望作为数据科学家的你熟悉这个步骤,你可以在这里找到代码。我用 pickle 保存了模型,所以我们可以在下一步中使用它。
步骤 2:安装 Streamlit 并开发 web 应用程序
Streamlit 是一个很棒的开源库,它可以在几分钟内构建一个 web 应用程序!安装通过pip install streamlit
进行,如果你想看演示,你可以运行streamlit hello
。将会打开一个浏览器,您可以选择一个演示并检查源代码。
我们继续蘑菇 app。我们要做的第一件事是编写标题、副标题、边栏和按钮:
打开浏览器后的开始屏幕:标题,带有选项和三个按钮的侧边栏。图片作者。
您可以在侧边栏中指定蘑菇,当您按下 Send 时,预测和解释会弹出。“信息”按钮提供了关于应用程序的更多信息,“可视化”按钮显示了降维后的数据集图。开始了。
我们首先创建一个新的 py 文件。首先,让我们导入必要的库来开始。对于网络应用来说,最重要的是import streamlit as st
。我们还将使用在第一步中创建的脚本中的函数。这是预处理数据集所必需的。
我们使用在步骤 1 中创建的脚本中的函数load_and_transform_mushroom_data()
加载和转换数据。该函数返回翻译后的数据帧df
、我们需要进行预测的列列表used_cols
和标签编码器encoder
。
现在我们可以开始使用 Streamlit 构建 web 应用程序了!用 Streamlit 编码真的很简单。
st.write("""## **MUSHROOM EDIBILITY METER** """)
st.write("""Is your mushroom edible? Let's find out! Specify the mushroom on the left and press Send.""")
这些行显示屏幕上的文本:
标题和副标题。图片作者。
在那里!app 的开头!很简单,对吧?
让我们继续边栏选项。我们需要具有唯一值的六列,以使模型能够计算预测。通过下面的代码,我们可以做到这一点。
# create sidebar
opts = []for col in used_cols:
option = st.sidebar.selectbox(f'{col}', df[col].unique())
opts.append(option)
通过这样做,我们得到了一个列表opts
,它存储了从那时起所有被选中的选项。仅此而已!当我们用 Streamlit 再次运行脚本时,侧栏是可见的:
侧边栏,检查!图片作者。
按钮有点难,因为我们希望它们彼此相邻。Streamlit 允许使用beta_columns
创建列。在代码中:
col1, col2, col3 = st.beta_columns([0.1,0.09, 1])with col1:
send = st.button('Send')with col2:
info = st.button('Info')with col3:
visual = st.button('Visualization')
图片作者。
如果一个人点击按钮,变量send
、info
和visual
等于True
。我们希望当有人点击发送时显示预测和解释,当有人点击信息时显示关于应用程序的一些信息。可视化按钮显示用原始数据集的 UMAP 和 Plotly 制作的降维图。
让我们从预测和解释开始。我们使用存储侧边栏当前值的opts
列表,并用一行和这些值创建一个 dataframe。然后我们加载模型,得到预测。下面几行解释了这个预测(稍后会有更多的信息)并创建了一个 matplotlib 图,这个图将用st.pyplot(fig)
来绘制。
点击“发送”后,会检查可食用性得分是否高于 0.5。如果是这种情况,蘑菇将得到标签可食用(否则有毒),这将被打印到屏幕上。
# create dataframe with selected values
new_mush = pd.DataFrame([opts], columns=used_cols)# get prediction
model = load_model(model_filename='mushroom.h5')
pred = predict(model, new_mush, encoder)# get explanation
new = encoder.transform(new_mush)
shap_df = get_explanations(new, model)
interpretation = create_interpret_df(shap_df, new, new_mush)
fig, ax = plot_interpretation(interpretation)# clicking the send button
if send:
if pred.loc['edible','score'] > 0.5:
result = 'edible'
else:
result = 'poisonous'
prob = round(pred.loc['edible','score']*100)
st.write(f"""This mushroom is **{result}**! \nEdibility score: **{str(prob)}**""")
st.pyplot(fig)
按发送时的结果:
图片作者。
信息按钮将显示一些关于应用程序的信息。我们将显示一个图像并键入一些文本。
# clicking the info button
if info:
size = 128, 128
mush = Image.open('img/mush.jpg')
mush.thumbnail(size, Image.ANTIALIAS)
st.image(mush)
st.write('With this app you can test whether a mushroom is poisonous or edible. \n You can specify the mushroom in the sidebar and press send. \n The six characteristics are identified as most important in predicting the edibility of mushrooms. \nThe model is validated and was 100 percent accurate.')
st.write('The explanations are from shap. Green specs contribute in a positive way to edibility, while red ones make the mushroom less edible.')
st.write('*Use at your own risk!*')
st.write('© Hennie de Harder, 2021')
按下 Info 时,您会看到:
图片作者。
最后但同样重要的是,可视化按钮。这里我们想要一个交互式图表,显示可食用的(绿点)和有毒的(红点)蘑菇。你可以看到许多小集群。所有的簇只包含绿色或红色的点。不错!这表明,该模型确实很容易将蘑菇归入有毒或可食用组,并解释了为什么该模型具有完美的准确性。如果你熟悉 UMAP 和普罗特利,你会发现创造这个情节很容易。
首先,你需要使用 UMAP 包进行嵌入。这给了你两个维度。然后,您为绘图和hover_data
的颜色添加目标标签和原始特征。
用 Plotly 绘图:
# use embedding and
fig = px.scatter(df_emb, x='0', y='1', hover_data=[col for col in df_emb.columns if col not in ['0', '1', 'poisonous']], color='poisonous', color_continuous_scale=[(0.00, "green"),(0.5, "green"),(0.5, "red"), (1.00, "red")])# change layout
fig.update_layout(coloraxis_showscale=False)
fig.update_xaxes(ticklabelposition="inside", title_text="Dimension 0")
fig.update_yaxes(ticklabelposition="inside", title_text="Dimension 1")
图片作者。
看起来没问题,让我们继续下面的步骤!
步骤 3:运行 web 应用程序
使用 pip 安装 Streamlit(步骤 2)后,您可以通过键入streamlit run streamlit_app.py
运行您的 web 应用程序。
浏览器会自动打开,您的应用程序会变得可见。测试新代码真的很容易,当你做了一些改变,你可以保存你的文件并按下任何按钮。该应用程序将使用新的代码(每次有变化时都会重新运行文件)。
步骤 4:部署 web 应用程序
Streamlit 使部署变得非常简单。如果你去他们的网站,你可以在 streamlit.io/sharing T2 申请邀请。收到邀请后,就可以部署 web 应用程序了。将您的 Streamlit 应用程序放在 GitHub 上,并创建一个 requirements.txt 文件。登录 share.streamlit.io ,用 GitHub 登录。
您可以开始部署了!按下新建应用程序,指定 repo、分支和文件路径,然后单击部署。
如果您的分支是 master,并且您的应用程序的文件名为 streamlit_app.py,您可以在以下位置找到您的应用程序
https://share.streamlit.io/[user name]/[repo name]
否则,链接会更长,并添加分支和文件名。
蘑菇 app 已部署,您可以亲自试用!
额外收获:如何创建可理解的解释?
怎么才能得到花里胡哨的解说栏剧情?这个模型有六个特征,气味、鳃大小、瘀伤、种群、栖息地和孢子印颜色。所有特征及其特征值都易于理解,并以其自己的方式对预测做出贡献。
条形图:解释预测。红色条对可食用性有负面影响,而绿色条对可食用性有正面影响。在这种情况下,只有“孢子印颜色是黑色的”对这种蘑菇的可食用性有积极的贡献。其他特征增加了蘑菇有毒的可能性。图片作者。
shap 库是一个解释机器学习模型的好工具。它使用博弈论和局部解释来决定特征值对最终预测的贡献。有更多的可解释性技术可用,但 shap 有一些很大的优势,例如,它是模型不可知的,你可以局部和全局地解释模型。
蘑菇模型的整体解释:
蘑菇模型的 Shap 总结。高特征值为红色,低特征值为蓝色。如果 SHAP 值为正,将增加预测得分,否则将减少预测得分。该模型被训练来预测蘑菇是否有毒,因此 y 轴右侧的点将导致蘑菇有毒!图片作者。
局部解释稍微复杂一点,但是我们可以使用 shap 值来创建易于理解的条形图(带有绿色和红色条)。
从获取形状值数据帧开始。我们需要蘑菇的模型和数据来获得 shap 值。
explainer = shap.TreeExplainer(model)
shap_values = explainer.shap_values(new)
shap_df = pd.DataFrame(shap_values, columns=new.columns)
下一步是创建一个包含解释的数据框架。
您可以看到形状值、特征名称、特征值、这两者的组合以及颜色。数据帧按 shap 值降序排序。这就是我们创建条形图所需的全部内容!
在代码中:
# creating the interpretation DataFrame
# only using top 3 features with highest and lowest shap value
name = []
shap_values = []
feature_names = []for i in range(len(shap_df)):
name += [new.index[i]] * 6
shap_values += sorted(list(np.array(shap_df.iloc[i])), reverse=True)[:3] + sorted(list(np.array(shap_df.iloc[i])))[:3][::-1]
feature_names += list(shap_df.columns[np.array(shap_df.iloc[i]).argsort()[::-1][:3]]) + list(shap_df.columns[np.array(shap_df.iloc[i]).argsort()[::][:3][::-1]])
interpret = pd.DataFrame({'idx':name, 'shap_value':shap_values, 'feature':feature_names})interpret['shap_value'] = interpret['shap_value'] * -1
interpret = interpret.sort_values(by='shap_value', ascending=False)def get_value(row):
return new_mush[new_mush.index == row.idx] [row['feature']].values[0]interpret['feature_value'] = interpret.apply(get_value, axis=1)interpret['feature&value'] = interpret.apply(lambda row: row.feature + ' is ' + str(row.feature_value), axis=1)
interpret['color'] = np.where(interpret['shap_value'] > 0, 'green', 'red')
这个例子很简单,因为数据很容易解释。如果您有更复杂的特性和特性值,您可以通过使用特性和特性值列将它们的含义转换为更容易理解的含义。您可以对要素及其值应用函数来解释它们。
最难的部分已经完成,有了interpret
数据框,就可以用 matplotlib 创建柱状图:
# create matplotlib figure
y_pos = np.arange(len(interpret.index))
fig, ax = plt.subplots(figsize=(8,3))# create horizontal bar plot
ax.barh(y_pos, interpret.shap_value.values, align='center', color=interpret.color.values)# change x and y axis
ax.set_yticks(y_pos)
ax.set_yticklabels(interpret['feature&value'].values)
ax.invert_yaxis()
ax.set_title('Contribution to edibility')
plt.tick_params(axis='x', which='both', bottom=False, top=False, labelbottom=False)# add legend
green = mpatches.Patch(color='green', label='Positive contribution')
red = mpatches.Patch(color='red', label='Negative contribution')
plt.legend(handles=[green, red])
可以走了!应用程序已创建!
结论
在这个时代,开发自己的 web 应用程序真的很容易!你所需要的只是一台电脑,一个 IDE,Python,一个互联网连接和数据!这篇文章只是一个例子,我希望你的想象力能带你走得更远,让你开发更酷的应用程序!
别忘了 订阅 如果你想在我发表新文章时收到电子邮件。 ❤
如何创建一个具有强化学习功能的人工智能
原文:https://towardsdatascience.com/how-to-create-an-ai-that-plays-tick-tac-toe-with-reinforcement-learning-d10e8fbbaa2c?source=collection_archive---------14-----------------------
如果人工智能先走,它是不可战胜的
在井字游戏中 AI 踢我屁股的短视频!AI 是 X,我是 o,看他怎么套我?*****视频作者***
在本文中,我们将创建两个代理,他们在井字游戏中互相扮演,直到其中一个达到井字游戏的熟练程度。
编写一个学习玩井字游戏的程序是学习强化学习如何工作的第一步。对于这个项目,我假设你已经了解了列表强化学习的理论(你可以在这里了解更多关于的内容)。这包括理解一个状态的价值是什么以及如何找到它。我将深入研究在代码中实现这一理论。在你学会如何做这个项目后,你离让代理学会玩视频游戏(也许还有一些更有用的东西)只差一个神经网络了!
实施:
首先,我们需要一个井字游戏作为我们的环境。下面发布的实现应该足够了。
这是一个经典的井字游戏,棋盘上的点用数字表示,从上到下,从左到右,从 0 到 8。
我将首先展示如何对我们的状态进行编码,每个状态都是游戏棋盘的一个特定配置。然后有两个函数妨碍了我们的井字游戏自治,get_action 函数和 update_values 函数。一旦你完成了,你应该能够建立 2 个代理,让他们互相玩,直到至少有一个已经掌握了井字游戏。
用数字表示状态
正如我所说的,我们需要将代理遇到的每个状态存储在内存中。对于井字游戏,我们将游戏棋盘的当前配置定义为状态。在我的实现中,游戏板由一个名为‘spot _ placeholders’的列表来描述。问题是,如果我们把每个状态,也就是一个列表,存储在另一个列表中,我们会有一个巨大的列表。这是非常低效的。让我们的目标不是拥有一个充满列表的列表,而是拥有一个充满整数的列表,每个整数代表一个唯一的状态。
为了弄清楚如何用数字表示每个状态,让我们从手动表示状态开始,并尝试识别一种模式。请注意,在“spot_placeholders”列表中,1 表示该位置有一个 X,2 表示该位置有一个 O。
- 状态:[0,0,0,0,0,0,0,0] = 0
- 状态:[1,0,0,0,0,0,0,0] = 1
- 状态:[2,0,0,0,0,0,0,0] = 2
- 状态:[0,1,0,0,0,0,0,0] = 3
- 状态:[1,1,0,0,0,0,0,0] = 4
- 状态:[2,1,0,0,0,0,0,0] = 5
- 状态:[0,2,0,0,0,0,0,0,0] = 6
- 状态:[1,2,0,0,0,0,0,0] = 7
- 状态:[2,2,0,0,0,0,0,0] = 8
我们可以用来列举这些状态的一个可能函数是:
如果你习惯于使用二进制,这应该感觉很自然
或者在代码中:
如果这个功能对你来说没有意义,不要为此感到紧张。这是井字游戏特有的,在未来的项目中可能不会用到。如果你只是复制和粘贴代码而没有完全理解它是如何工作的,对你理解 RL 不会有太大的伤害。只要知道你可以通过某种方式对状态进行编码来提高效率。
ε贪婪
ε贪婪算法是我们如何决定我们的代理将采取的行动。我们希望代理在开始时采取随机的行动,但是一旦它开始掌握事情的诀窍,我们希望它能赢。所以我们要做的是设置一个变量ε,代表代理人采取随机行动的几率,并随着时间的推移慢慢降低ε。伪代码是这样的:
- 初始化ε = 1
- 生成一个介于 0 和 1 之间的随机数
- 如果这个随机数是< ε, explore the state space (take a random action).
- If this random number is > ε,则执行导致具有最高值的状态的动作。
- 少量减少ε
ε继续下降,直到达到某个预定值。你可以认为ε是代理人采取随机行动的概率。
获取操作功能
目前,我们的 get_action 函数询问用户他们想去哪个景点。因为我们使它完全自治,所以你可以自由地清除 get_action 函数,从头开始。我们想做的是找出代理可能处于的所有可能的下一个状态,然后找出这些状态中哪一个具有最高值。我们通过循环游戏板(spot_placeholders)来实现这一点,如果一个位置是开放的,我们记录代理进入这个空闲位置时的新状态。然后我们查看代理的状态值表,找到这个状态的值。如果这个状态具有最高值,我们移动到导致这个状态的点。
我实现这个函数的伪代码如下:
- 看看轮到谁了
- 找出玩家下一个可能的状态。
- 执行ε greedy 要么采取随机行动,要么贪婪(采取最佳行动)。
- 如果是贪婪的,循环遍历下一个可能的状态,找到具有最高值的状态。
- 尝试执行此操作,但是如果代理的表中没有这些状态,则执行随机操作。
下面是我实现这个函数的代码:
注意,我还为ε贪婪策略的 player 类添加了 epsilon 属性。
更新值功能
目前,我们可以让两个代理相互扮演,但是这两个代理没有任何记忆。好像他们玩的每一个游戏都是他们第一次玩井字游戏。所以,让我们解决这个问题。
我们做的是保存一集里所有去过的州的列表。在这一集的最后,我们需要调用一个函数,将值更新函数应用于每个代理的列表中的每个状态。请注意,我们只在该集的最后一个状态收到奖励。因此,我们可以将最后一个状态的值设置为奖励。我的实现的伪代码如下:
- 将最后一个状态的值设置为 1 或-1(如果游戏赢了就奖励,如果游戏输了就惩罚)
- 将任何新的、以前未发现的状态添加到玩家的记忆中
- 从第二个到最后一个状态开始并向第一个状态移动,应用更新函数
我的实现代码是:
我在 play game 函数中添加了一个对 update 函数的调用。
把所有的放在一起
我们现在可以让两个代理互相玩游戏,并独自成为井字游戏的专业玩家。你可以在下面找到我完成的项目的代码:
我增加了一个测试功能,这样你就可以和电脑对战了。您会发现,如果您先走,代理根本不会玩得很好,这是因为井字游戏非常偏向于谁先走(这会打乱培训)。调整训练时间、奖励的大小和其他超参数可能有助于代理人在第二名时玩得更好(你可以尝试奖励在猫游戏中第二名的玩家,而不是惩罚他们)。
项目摘要
总之,我们正在让一个代理玩井字游戏数千次,并记录游戏的每个状态下发生的事情。然后,我们为每个状态分配一个值,并使用值更新函数来修正这个值。当代理人试图获胜时,他将总是移动到具有最高价值的状态。我们称之为列表 RL,因为我们将所有状态及其值保存在一个表中。
但是如果这是一个 4X4 或 5X5 甚至 10X10 的井字游戏呢?随着游戏板的增长,所有可能状态的数量呈指数增长。这意味着我们的价值表最终会变得太大而不实用!如果有一种方法可以近似每个状态的值就好了。
如果存在一个函数,该函数在给定当前输入的情况下近似每个可能动作的值…
有这样一个函数,我们用神经网络找到了它。这是深度强化学习的主题,我将很快就此写一篇文章,并将链接贴在这里。
感谢您的阅读!如果这篇文章在某种程度上帮助了你,或者你有什么意见或问题,请在下面留下回复,让我知道!此外,如果你注意到我在某个地方犯了错误,或者我可以解释得更清楚一些,那么如果你能通过回复让我知道,我会很感激。
如何从 DPR 的问题中创造答案
原文:https://towardsdatascience.com/how-to-create-an-answer-from-a-question-with-dpr-d76e29cc5d60?source=collection_archive---------9-----------------------
面向下一代智能解决方案的下一代问答技术
艾米丽·莫特在 Unsplash 上的照片
在开放领域问答中,我们通常设计一个包含数据源、检索器和阅读器/生成器的模型架构。
这些组件中的第一个通常是文档存储。我们在这里使用的两个最受欢迎的商店是 Elasticsearch 和 FAISS。
接下来是我们的寻回犬——本文的主题。检索器的工作是在我们的文档存储中过滤相关的信息块(文档),并将它们传递给阅读器/生成器模型。
阅读器/生成器模型是我们问答堆栈中的最终模型。我们可以有一个阅读器,它直接从上下文中提取答案。或者,生成器,它使用语言生成从上下文中生成答案。
检索器-阅读器和检索器-生成器开放域(OD) QA 栈都包括外部数据源(文档存储)、检索器和阅读器/生成器。
检索者的工作对我们的读者表现至关重要。给定一个查询,它必须找到最相关的上下文。
如果读者得到了不正确的上下文,它将输出不正确的答案。
如果给予读者正确的上下文,它可能输出正确的答案。
所以,如果我们想有机会输出好的答案,检索器必须工作得很好。
稀疏寻回犬
在过去,我们依赖稀疏向量检索器来完成从文档存储中查找相关信息的任务。为此,我们使用了 TF-IDF 或 BM25。
TF-IDF
TF-IDF 算法是计算两个文本相似性的一个流行选项。
- TF 指在上下文中找到查询中的多少个单词。
- IDF 是包含该单词的文档分数的倒数。
然后将这两个值相乘,得到 TF-IDF 分数。
现在,我们可以发现单词“海马”在查询和上下文之间是共享的,这将增加 TF-IDF 分数,因为:
- TF —在查询和上下文中都找到该单词(高分)。
- IDF—【海马】这个词是而不是其他很多文献中发现的(所以词频的逆是一个高数字)。
或者,如果我们使用单词“the”,我们将返回一个较低的 TF-IDF 分数,因为:
- TF —在查询和上下文中都找到该单词(高分)。
- IDF—这个词在其他很多文献中都有(所以词频的逆是一个低数)。
由于 IDF 因的常见程度而较低,因此 TF-IDF 得分也较低。**
因此,TF-IDF 分数对于查找包含相同不常用词的序列非常有用。
BM25
BM25 是 TF-IDF 的变体。在这里,我们仍然计算 TF 和 IDF,但是在返回查询和上下文之间的大量匹配之后,TF 分数被降低了。
此外,它还考虑了文档长度。TF-IDF 分数是标准化的,因此如果短文档和长文档具有相同数量的单词匹配,则短文档比长文档的分数更高。
当使用稀疏检索器时,BM25 通常比 TF-IDF 更受青睐。
密集段落检索
ODQA 的密集段落检索(DPR)于 2020 年推出,作为传统的 TF-IDF 和 BM25 段落检索技术的替代。
赞成的意见
介绍 DPR 的论文首先指出,这种新方法比当前的 Lucene(文档存储)BM25 检索器的段落检索准确率高 9-19%。
DPR 能够胜过传统的稀疏检索方法有两个关键原因:
- 语义相似的词(“嘿”、“你好”、“嘿”)不会被 TF 视为匹配。DPR 使用密集的语义编码向量(所以“嘿”、“你好”和“嘿”将紧密匹配)。
- 稀疏猎犬不是可训练的。DPR 使用嵌入函数,我们可以针对特定任务对其进行训练和微调。
骗局
尽管有这些明显的性能优势,但也不全是好消息。是的,我们可以训练我们的 DPR 模型,但这也是一个缺点——而 TF-IDF 和 BM25 是现成的——DPR 没有。
正如在 ML 中通常的情况一样,DPR 需要大量的训练数据——在这种情况下,这些数据是问题和上下文对的精选数据集。
此外,DPR 在索引和检索过程中需要更多的计算。
两个床位和培训
DPR 使用两种独特的伯特编码器模型。其中一个模型——eᴘ——将文本段落编码成编码的段落向量(我们将上下文向量存储在我们的文档存储中)。
另一个模型——EQ——将一个问题映射成一个编码的问题向量。
在训练期间,我们将问题-上下文对输入到我们的 DPR 模型中,并且模型权重将被优化以最大化两个相应的 Eᴘ/EQ 模型输出之间的点积:
培训期间通过 DPR 模型的数据流的高级视图。
两个模型输出 Eᴘ(p) 和 EQ(q) 之间的点积值测量两个向量之间的相似性。点积越高,相似度越高,因为两个向量越接近,点积就越大。
通过训练两个模型输出相同的向量,我们正在训练上下文编码器和问题编码器为相关的问题-上下文对输出非常相似的向量。
运行时
一旦模型(或两个模型)被训练,我们就可以开始使用它们进行问答索引和检索。
当我们第一次构建我们的文档存储时,我们需要使用 Eᴘ编码器对我们存储在那里的数据进行编码——因此在文档存储初始化期间(或者当添加新文档时)—我们通过 Eᴘ编码器运行每一段文本,并将输出向量存储在我们的文档存储中。
对于实时问答,我们只需要 e Q 编码器。当我们提出一个问题时,它将被发送到 EQ 编码器,然后输出我们的 EQ 向量 EQ(q) 。
接下来,将 EQ(q) 向量与我们的文档存储中已经索引的 Eᴘ(p) 向量进行比较,在文档存储中,我们过滤返回最高相似性得分的向量:
sim(q,p) = EQ(q)ᵀ Eᴘ(p)
就是这样!我们的检索器已经为我们的问题确定了最相关的上下文。
然后,这些相关的上下文被传递到我们的读者(或生成器)模型,该模型将基于上下文创建一个答案——我们的问答过程就完成了!
以上是关于面向开放领域问答(ODQA)的密集段落检索(DPR)的介绍。
我希望你喜欢这篇文章。如果您有任何问题或建议,请通过推特或在下面的评论中告诉我。如果你对更多类似的内容感兴趣,我也会在 YouTube 上发布。
感谢阅读!
参考
[1] V. Karpukin 等人艾尔。,面向开放领域问答的密集段落检索 (2020),EMNLP 2020
拥抱脸, DPR ,变形金刚 Docs
🤖带变压器的 NLP 课程
*所有图片均由作者提供,除非另有说明
如何创建一个应用程序来使用 fastai 和 Streamlit 对狗进行分类
原文:https://towardsdatascience.com/how-to-create-an-app-to-classify-dogs-using-fastai-and-streamlit-af3e75f0ee28?source=collection_archive---------21-----------------------
用几行代码创建一个深度学习应用
作者图片
动机
如果你想搭建一个深度学习 app,能有多难?这取决于您用来构建模型和应用程序的工具。如果你想创建一个高性能的深度学习模型,用几行代码部署,那就从 fastai 和 Streamlit 开始吧。
受到这本书第二章的启发,杰瑞米·霍华德和西尔万·古格的《fastai 和 PyTorch 程序员的深度学习》,我决定创建一个模型来对狗进行分类,并使用 Streamlit 而不是 Voila 部署它。
在本教程中,我将向你展示如何创建一个应用程序来分类狗如下。
作者 GIF
点击此处查看 app。请注意,这个应用程序可以用来分类 3 种狗:赢家,吉娃娃,巴吉度猎犬。
什么是 fastai 和 Streamlit?
Fastai 是一个 Python 库,可以轻松地用几行代码构建深度学习模型。Streamlit 是一个 Python 库,可以在几分钟内将数据脚本转换成可共享的 web 应用。
从安装 fastbook 开始。这将安装 fastai,并让我们访问一些有用的函数,我们将在本教程的后面使用。
pip install -Uqq fastbook
安装细流
pip install streamlit
导入相关库
收集数据
我们将使用 Bing 搜索图片 API 下载狗狗图片。要从 Bing 获取图片,你需要从 Microsoft Azure 获取一个密钥,并在方法search_images_bing
中用你的新密钥替换"XXX"
。放心吧!它是免费的!
要使用密钥下载获胜狗的图像,只需使用
150
酷!150 张冠军狗的图片被下载。
我们将使用相同的功能来下载图像,这些图像是“Winner dog”、“Chihuahua dog”和“Basset Hound dog”的搜索结果,并将它们保存到单独的文件夹中
我们的数据目录将如下所示:
dogs
├── Basset Hound
├── Chihuahua
└── Winner
每个文件夹将有 150 张在目录名称中指定的狗的图片。
将保存到狗狗文件夹的所有图片分配给fns
使用Path.unlink
删除从互联网下载时损坏的图像
数据加载器
在训练之前,我们想让模特知道:
- 数据的类型
- 如何获取数据
- 如何获取数据集的标签
- 如何将数据分为训练集和验证集
这时候Dataloader
就派上用场了。从创建DataBlock
开始,并将这个实例提供给dataloaders
。
上述代码的详细信息
blocks=(ImageBlock, CategoryBlock)
:指定用于预测的变量的数据类型和标签。在这种情况下,它是图像和类别(狗的类型)get_items
:从提供的路径中获取图像的功能splitter
:将数据分为训练集和验证集。20%的数据用于验证。seed
用于在我们每次使用DataBlock
时获得相同的分割get_y
:通过获取文件所在文件夹的名称来获取标签。在这种情况下,它是“赢家”,“吉娃娃”,和“巴吉度猎犬”item_tfms
:表示物品转换器,负责转换物品。这里,我们将图像调整为 128 像素的正方形。
在我们的dataloaders
中查看 4 张随机图像
作者图片
随机调整大小和数据扩充
上面的图片本身就很好。但是为了让神经网络捕捉更多的图像,我们希望改进我们转换图像的方法。这可以通过使用随机调整大小和数据扩充来实现。
随机调整大小
对于许多类型的神经网络,输入总是需要具有相同的形状。因此,我们希望裁剪图像,使它们都具有相同的大小。
默认情况下,Resize
裁剪图像以适合正方形。这可能会导致一些重要的图像丢失。因此,我们将使用RandomResizedCrop
随机选择并裁剪图像的一部分,而不是裁剪相同的区域。
作者图片
min_scale
告诉 fastai 选择至少 30%的图像进行裁剪。
数据扩充
为了创建更多的训练数据,我们将使用batch_tfms
对整个数据集进行扩充。这意味着旋转、翻转、改变图像的亮度等,以从同一图像创建不同的图像。
作者图片
将两种技术结合起来,以获得两种转换的好处
训练我们的模型
我们使用一个卷积神经网络(CNN)来训练我们的模型。cnn_learner
还将加载一个预训练模型,该模型已经过训练,可以识别 130 万张照片中的一千个不同类别。
fine_tune(4)
告诉 fastai 使用 4 个历元来拟合模型(每个历元是整个训练数据集的一个周期)。
评估我们的模型
作者图片
哇!我们的模型可以正确地对验证集中的所有狗进行分类。图片被错误分类。
作者图片
因为我们没有错误的预测,所以上面显示的图像是那些预测正确的图像。然而,当有错误的预测时,plot_top_losses
方法就会派上用场。
删除无关数据
在训练模型之后,我们可能想知道为什么一些图像被错误地分类。这可能是因为图像被错误地标注了,或者有一些模型难以识别的特征。
作者图片
第三张图片是而不是一只胜利者的狗!我们可以通过在下拉菜单中选择“删除”来删除该图像。
Fastai 还允许您重命名标签,而不是删除它们。
接下来,我们删除或编辑标记为“删除”或“重命名”的本地图像。
保存模型
就是这样!现在我们可以出口我们的模型投入生产
要加载模型,只需使用load_learner
方法
部署我们的模型
耶!现在我们可以开始使用我们刚刚训练过的模型来部署我们的模型。下面的脚本是我们需要创建一个应用程序来分类狗。
以上代码的详细信息:
get_image_from_upload
:允许我们从你的本地文件上传图片
作者图片
display_output
:上传图像后显示
作者图片
get_prediction
:创建一个按钮对图像进行分类
作者图片
现在,将上面的脚本保存为dog_classifier.py
并运行:
streamlit run dog_classifier.py
我们的应用程序已经可以玩了!
作者 GIF
图像被分类为赢家,概率为 0.9991!注意,由于图片中的狗是我的狗,所以在训练过程中不使用这张图片。这里可以玩 app 。
通过简化 it 共享进行部署
现在,你有了一个可以在本地运行的应用程序,但你将无法与你的朋友分享你的应用程序的链接,除非你将应用程序托管在某个服务器上。幸运的是,这可以通过三个步骤轻松实现:
- 使用 Github 登录
- 选择一个回购、分支和文件
- 点击部署!
点击查看如何使用 Streamlit 共享的说明。
结论
恭喜你!您刚刚学习了如何使用 fastai 和 Streamlit 创建一个应用程序来对狗进行分类。有了 fastai 和 Streamlit 这样的工具,你可以跳过一个很大的学习曲线来部署一个具有深度学习的 web 应用。
希望这篇文章能给你创造一个动力,让你创建自己的深度学习应用。
在这个资源库中,您可以随意使用我用来创建这个应用程序的代码。
我喜欢写一些基本的数据科学概念,并尝试不同的算法和数据科学工具。你可以通过 LinkedIn 和 Twitter 与我联系。
如果你想查看我写的所有文章的代码,请点击这里。在 Medium 上关注我,了解我的最新数据科学文章,例如:
参考
霍华德,杰里米,还有古格,西尔万。用 fastai 和 PyTorch 对编码员进行深度学习。奥莱利,2020 年。
如何用 Python 创建自动化的远程工作查找器
原文:https://towardsdatascience.com/how-to-create-an-automated-remote-job-finder-with-python-7e20ee233e2b?source=collection_archive---------34-----------------------
找新工作?再也不要错过潜在的机会
安德鲁·尼尔在 Unsplash 上拍照
今年是黑暗、悲伤、可怕的一年。此外,这让我坚持自己的选择:最终,我想远程工作。事实上,我对理想工作模式的愿景包括减少每个人的工作时间,自动化所有可行的事情,以及真正公平的财富再分配——但我不想在这里过于政治化,所以让我们专注于远程部分。
有几个很好的专门从事远程工作的求职网站,那里也有很多(我已经检查过:很多)列出这些网站的文章,所以不,在这篇文章中不打算这样做。另外,既然已经是 2020 年了,我想你们都知道如何在网上成功地找工作。相反,我要做的是向你们展示如何自动获取所有这些报价,根据你们的个人偏好进行筛选,并获得摘要通知。而且因为我知道我们都只是略读这些文章,请允许我给一点 TL;语音博士。
TL;大卫:我们要做什么?
首先,我们将手动选择一些好的远程求职网站——稍后会详细介绍。然后,我们将编写一个 Python 脚本:
- 从那些网站上得到所有的报价。
- 根据我们的喜好过滤掉它们。
- 在 AWS 中部署后,会发送一个包含摘要的通知。
与我的文章一样,这是一个端到端的项目,所以仔细阅读本教程后,您将拥有一段功能完整的代码,其结果如下:
作者图片
我们走吧!
无聊的部分:选择网站
我们需要的第一件事是一堆网站,最好是聚合网站,这样我们就可以覆盖更多的主要来源,从而获得报价。从网站获取信息有两种主要方式:公开的 API 或 RSS 提要,以及抓取。抓取更难,需要持续监控 HTML 中最微小的变化都可能成为大问题。所以现在不刮了。让我们搜索提供一些工具的网站,无论是 API 还是 RSS。坏的方面是这是一个无聊的手动搜索——好的方面是我已经为你做了。
- Remoteok.io :那里最大的——如果不是最大的话——只提供远程工作的论坛之一,由 levels.io 创建。声称覆盖了全球发布的大约 80%的远程工作机会(引用一下,我不是骗子!).同时提供 API 和 RSS。
- Remote.io :由托尼·特里托于 2019 年创建,是一个“为数字游牧者、远程工作者和希望在家工作的人提供的工作平台”。提供 RSS。
- 劳动游牧者:另一种聚集者;引用他们的话:“列出了许多职业领域中最有趣的远程工作机会”。由彼得·马塞利和玛丽·乌赫尔科娃创作。提供 API。
- GitHub Jobs :我敢肯定 GitHub 有印象——Jobs 部分可能没那么有名,但是很不错。虽然它不是远程集中的,但有一个选项可以只列出远程作业——足够近。提供 API。
- 我们远程工作:2011 年推出,号称是“世界上最大的远程工作社区”。提供 RSS。
那是我的选择。显然,你可以添加更多的来源,但我相信这五个网站涵盖了绝大多数的远程报价张贴。
连接到工作公告板:获得聘用
我们已经选择了具有 API 和 RSS 的主板,所以让我们分别编写一个例子。对于 RSS,我们将使用feedparser
库:
$ pip install feedparser
用法非常简单—让我们看一下 remote.io 提要:
rss_feed_url = 'https://s3.remote.io/feed/rss.xml'
rss = feedparser.parse(rss_feed_url)
entries = rss.entries# Let's check the first entry
for k, v in entries[0].items():
print(f'{k}: {v}')
这段代码将输出如下内容:
title: Senior Manager
title_detail: {'type': 'text/plain', 'language': None, 'base': '[https://s3.remote.io/feed/rss.xml'](https://s3.remote.io/feed/rss.xml'), 'value': 'Senior Manager'}
links: [{'rel': 'alternate', 'type': 'text/html', 'href': '[https://www.remote.io/remote-customer-service-jobs/sr-manager'](https://www.remote.io/remote-customer-service-jobs/senior-manager-learning-development-10591?utm_source=rss&utm_medium=rss_feed&utm_campaign=jobs_rss_feed')}]
link: [https://www.remote.io/remote-customer-service-jobs/sr-manager](https://www.remote.io/remote-customer-service-jobs/senior-manager-learning-development-10591?utm_source=rss&utm_medium=rss_feed&utm_campaign=jobs_rss_feed')
id: [https://www.remote.io/remote-customer-service-jobs/sr-manager](https://www.remote.io/remote-customer-service-jobs/senior-manager-learning-development-10591?utm_source=rss&utm_medium=rss_feed&utm_campaign=jobs_rss_feed')
guidislink: False
summary: Sr Manager wanted for...
summary_detail: {'type': 'text/html', 'language': None, 'base': '[https://s3.remote.io/feed/rss.xml'](https://s3.remote.io/feed/rss.xml'), 'value': "Sr Manager wanted for..."}
content: [{'type': 'text/html', 'language': None, 'base': '[https://s3.remote.io/feed/rss.xml'](https://s3.remote.io/feed/rss.xml'), 'value': "Sr Manager wanted for..."}]
authors: [{'name': 'Remote.io'}]
author: Remote.io
author_detail: {'name': 'Remote.io'}
published: 2020-12-25 21:31:59
published_parsed: time.struct_time(tm_year=2020, tm_mon=12, tm_mday=25, tm_hour=21, tm_min=31, tm_sec=59, tm_wday=4, tm_yday=360, tm_isdst=0)
太好了,看起来一切都在。我们需要清理这个问题——最终会解决的。现在让我们看看如何使用requests
库从 API 获取相同的信息:
$ pip install requests
用法稍微复杂一些:我们需要创建一个会话,向其中添加一个用户代理,最后到达端点。让我们来看看工作游牧民 API:
session = requests.Session()
session.headers['User-Agent'] = (
f'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) '
f'AppleWebKit/537.36 (KHTML, like Gecko) '
f'Chrome/34.0.1847.131 Safari/537.36'
)api_url = 'https://www.workingnomads.co/api/exposed_jobs/'
response = session.get(api_url)
entries = json.loads(response.text)# Let's check the first entry
for k, v in entries[0].items():
print(f'{k}: {v}')
这段代码将输出如下内容:
url: [https://www.workingnomads.co/job/go/555/](https://www.workingnomads.co/job/go/32952/)
title: Backend Engineer
description: The description of the job
company_name: Cool Company
category_name: Development
tags: devops,php,java,ruby,python,scala
location: USA
pub_date: 2020-12-25T14:52:29.663723-05:00
同样,一切都在那里。对于其他三个来源,过程是完全相同的-让我们进行第二部分,过滤和清理一切。
过滤报价
对于我个人的使用案例,我需要三个过滤器:
- 日期:我只是想在最后一天的过程中公布的优惠。
- 地点:尽管它们都很偏远,但有些优惠设置了强制地点,例如欧洲或美国。这通常是由于税收问题或时区问题——无论如何,如果我的位置与他们的要求不匹配,我就不想得到报价。
- 标签:也许是最重要的过滤器。我想获得与我的技能相匹配的报价,为此我需要标签。
日期过滤器非常简单,因为所有的 API/RSS 提要都包含发布日期和时间字段。从一个源到另一个源,我们唯一需要修改的是字段的格式和名称,因为它会改变。类似这样的事情就足够了:
from datetime import datetime, timezone, timedelta, dateentry = << ENTRY FROM RSS/API >>
dt_format = '%a, %d %b %Y %H:%M:%S %z'
dt_field_name = 'published'now = datetime.timestamp(datetime.now(timezone.utc))
parsed_date = entry.get(dt_field_name)
entry_date = datetime.strptime(parsed_date, dt_format).timestamp()if now - entry_date > 90000: # Around 25 hours
# Older than 25h
else:
# Newer than 25h
位置过滤器是最棘手的,因为不是所有的提要都提供它。如果它在那里,像这样的东西就可以了:
entry = << ENTRY FROM RSS/API >>
location_field_name = 'region'invalid_regions = ['USA Only', 'North America Only']
entry_location = entry.get(location_field_name, '')if entry_location in invalid_regions:
# Not valid
else:
# Valid
最后是标签过滤器,这里有两种可能性。如果 RSS 提要或 API 友好地提供了标签,我强烈建议接受这个礼物并使用它们进行过滤:
entry = << ENTRY FROM RSS/API >>my_tags = ['python', 'django']
entry_tags = [t.lower() for t in entry.get('tags', [])]if not any(t in entry_tags for t in my_tags):
# Not valid
else:
# Valid
否则,恐怕你们得发挥你们的想象力了。我通常将工作的摘要/描述改为小写,以使其不区分大小写,并且我会查找关键字,如:
entry = << ENTRY FROM RSS/API >>my_tags = ['python', 'django']
entry_summary = entry.get('summary', '').lower()if not any(t in entry_summary for t in tags):
# Not valid
else:
# Valid
您可以在这里添加任意数量的过滤器:公司、时区、所需经验年限…请记住,过滤来自 API/RSS 的字段总是比搜索摘要或描述更容易。此外,您可能希望只提取一些字段——毕竟,您不需要要约的 id 或其元数据。
部署和发送通知
如果你读过我的其他故事,你可以告诉我,我是 Lambda + 丨t丨e丨l丨e丨g丨r丨a丨m丨s丨 组合监控机器人的粉丝。我为那个写了一个教程,那边的几个故事有如何做的例子,所以让我在这里长话短说。
待办事项清单上的第一件事是创建一个机器人。我建议遵循 丨t丨e丨l丨e丨g丨r丨a丨m丨s丨 的官方指令:在 丨t丨e丨l丨e丨g丨r丨a丨m丨s丨 中搜索用户@BotFather,使用命令\newbot
,为你的机器人选择一个名称和用户名,最后获得令牌并将其存储在安全的地方。
下一步:部署。我们将使用一个来自无服务器框架的模板,它将包含三个文件:.gitignore
、serverless.yml
和handler.py
。无服务器文件定义了将要执行的内容和时间;我想在 UTC 时间下午 6 点收到我的总结,我们来定义一下:
org: your-organization-name
app: your-app-name
service: remote-jobs-botframeworkVersion: “>=1.2.0 <2.0.0”provider:
name: aws
runtime: python3.6
# Propagating the 丨t丨e丨l丨e丨g丨r丨a丨m丨s丨 token from our own
# environment so we don’t have to deploy it.
environment:
丨t丨e丨l丨e丨g丨r丨a丨m丨s丨_TOKEN: ${env:丨t丨e丨l丨e丨g丨r丨a丨m丨s丨_TOKEN}functions:
cron:
handler: handler.send_message
events:
# Invoke Lambda function at 18:00 UTC every day
- schedule: cron(00 18 * * ? *)
另一方面,处理程序文件将包含要运行的代码。您需要将CHAT_ID
更改为您希望机器人与之交互的群组、频道或对话的 ID。在这里你可以找到如何从频道获取 ID,这里是如何从群组获取 ID:
import 丨t丨e丨l丨e丨g丨r丨a丨m丨s丨
import sys
import osTOKEN = os.environ[‘丨t丨e丨l丨e丨g丨r丨a丨m丨s丨_TOKEN’]
CHAT_ID = XXXXXXXXdef get_offers():
# Here we get the offers and filter them as shown abovedef send_message(event, context):
bot = 丨t丨e丨l丨e丨g丨r丨a丨m丨s丨.Bot(token=TOKEN) offers = get_offers()
if len(offers) == 0:
bot.sendMessage(chat_id=CHAT_ID, text='No new offers.')
else:
for offer in offers:
bot.sendMessage(chat_id=CHAT_ID, text=offer)
time.sleep(5)
剩下的唯一一件事就是在部署之前获取 AWS 凭证,并将它们与令牌和其他变量一起设置为环境变量。从您的 AWS 控制台:
- 进入我的安全凭证 — 用户 — 添加用户。
- 选择用户名并选择编程访问。
- 下一页:选择直接附加已有策略 — 管理员访问。
- 复制访问密钥 ID 和秘密访问密钥并保存。
就是这样。现在,让我们导出 AWS 凭证和电报令牌。打开终端,写下:
$ export AWS_ACCESS_KEY_ID=[your key goes here]
$ export AWS_SECRET_ACCESS_KEY=[your key goes here]
$ export 丨t丨e丨l丨e丨g丨r丨a丨m丨s丨_TOKEN=[your token goes here]
在本地安装必要的包,最后,将所有东西部署到 AWS:
$ pip3 install -r requirements.txt -t . --system
$ serverless deploy
我们完了!机器人将检查报价,并在世界协调时下午 6:00 向我们发送一份摘要。我鼓励你们深入研究任何你们认为有用的东西:添加源、添加过滤器……远程部分只是我个人的偏好;你也可以使用许多非遥控板。当然,请在评论中告诉我!快乐编码:)
和往常一样,你可以在 GitHub 里查看的代码。
参考
[1] R. Romero,自动化电报机器人,用不到 40 行 Python 代码 (2019),Medium 发送日常消息
[2] R. Romero,如何用 Python 创建一个全自动的基于人工智能的交易系统 (2020),中型
如何创建交互式三维图表并与任何人轻松共享
原文:https://towardsdatascience.com/how-to-create-an-interactive-3d-chart-and-share-it-easily-with-anyone-d0c1c42bc394?source=collection_archive---------35-----------------------
一个关于伟大情节的简短教程
作者图片
3D 图表有一个巨大的缺点。创建三维图表时,您可以从不同的角度/比例可视化数据,或者使用交互式库,这样您就能够很好地理解数据。然而,当创建时,这些图表很难共享。
人们通常将 3D 图表转换成单个静态图像或从不同角度和不同比例拍摄的一组图像。使用这种方法,一些重要的信息可能会丢失,或者难以理解,所以我们需要一个更好的选择。它确实存在。
在这个简短的教程中,我将向您展示如何创建一个交互式 3D 图表,并轻松地与任何人共享它,无论他们是数据科学家、开发人员、经理,还是您没有安装任何编码环境的非技术朋友。共享的图表也将是完全交互式的。
它是如何工作的
你可能听说过 plotly ,这是一个开源库,允许在 Jupyter 笔记本上创建交互式图表。我使用这个库已经有一段时间了,也把图表作为静态图像分享,直到我的大学向我展示了一个伟大的 plotly 特性:
您可以将交互式图表存储为 HTML 文件,当在浏览器中打开时,它们是完全交互式的。
演示
让我们创建一个简单的 3D 函数的可视化——抛物线。首先,我们使用 numpy.meshgrid 计算网格(x,y)上的函数值,然后使用 plotly 绘制表面,并将其保存为 HTML 文件。下面是代码(基于文档)。
import numpy as np
import plotly.graph_objects as godef parabola_3d(x, y):
z = x ** 2 + y ** 2
return zx = np.linspace(-1, 1, 50)
y = np.linspace(-1, 1, 50)
xv, yv = np.meshgrid(x, y)
z = parabola_3d(xv, yv)fig = go.Figure(data=[go.Surface(z=z, x=x, y=y)])
fig.write_html("file.html")
这是结果的样子。这个 HTML 文件可以在任何浏览器中打开,嵌入网站,并通过信使发送。这里最好的事情是打开这个文件——既不需要 Jupyter 笔记本也不需要 plotly 库。
图一。HTML 文件在浏览器中打开时的外观。作者图片
下载这个 HTML 文件,自己试试:
file.html
安装和更多
我记得 plotly 是一个功能非常有限的过于复杂的库,但在过去几年里,它成长为一个非常酷的东西。例如,有 13 种类型的三维图表,以及数十种地图,统计,科学和金融 2D 图表。
图二。plotly 中可用的 3D 图表示例。来源
如果你感兴趣并想尝试 plotly,这里有关于如何安装它和构建你的第一个图表的文档。肯定值得一试!
原载于 2021 年 6 月 14 日https://notrocketseconomy . blog。
如果你想阅读更多类似的教程,请订阅我的博客“不是火箭科学”——电报 和 推特 。
如何无中生有地创建物联网时间序列数据集
原文:https://towardsdatascience.com/how-to-create-an-iot-time-series-dataset-out-of-nothing-74026903896d?source=collection_archive---------31-----------------------
尤利娅·卢卡希娜
使用 NumPy、Pandas 和 Datetime 创建一个包含时间序列数据的测试数据集的简单解决方案。物联网连接数据的例子。包括代码和逻辑解释。
挑战
最近,我为一位客户工作,他需要一份涉及(不存在的)物联网公司数据的教程。我创建了一个测试数据集,因为所有可用的开源数据集并不完全匹配。这启发了我写另一个教程:你正在阅读的那个。
尽管现有的 Python Faker 包在创建假数据集方面做得很好,但它并没有涵盖像时间序列数据这样的用例。
时间序列的具体是什么?
- 时间戳是半随机的:它们构建了一个序列
- 一些预定义的事件重复但随机地发生
- 一些事件可能与其他事件绑定在一起,甚至更不随机
第一个语句意味着我们需要一行具有升序的时间戳值。这些值不是完全随机的,但是它们之间的滞后是随机的。
此外,我们需要一个第二维度,它是一个字符串或字符格式的数据集列,有一些以随机顺序出现的唯一值,但它们本身不是随机生成的。所以,问题是,如何沿着时间轴分布它们?
将目标分解成任务
尽管这两个问题——随机升序日期和随机分布的已知字符值——乍一看可能令人害怕,但解决方案很简单。
我们只需要 NumPy 包和它出色的 random.randint()函数。和系统思维。
但是在开始之前,我们需要考虑最终数据集的设计以及创建它的方法。
我们需要一些物联网连接数据。数据集应该模拟安装在我们设备上的应用程序不断发送的消息。这个数据是元级别的。它不包含用户发送、接收或与之交互的任何信息。这些消息是应用程序完全在后台生成和传输的,没有用户的参与。它们经过定制,可让支持经理在设备无法正常运行之前识别出任何问题和异常。
连接数据由时间戳和与每个时间戳相关联的消息组成。前一种也称为事件,因为它们主要描述设备或 SIM 卡发生的事情,例如:
- "创建 PDP 上下文"
- "删除 PDP 上下文"
- "更新 GPS 位置"
- 警报、警告和错误
- 数据使用:指的是由用户发起的在应用程序内部发送和接收数据(用户数据的实际内容从来不是该事件的一部分)
分组数据协议(PDP)上下文包含网络层地址等数据。PDP 上下文创建总是在数据使用事件之前。相反,使用“删除 PDP 上下文”事件来关闭数据传输。
或者至少,这是它在数据集中的样子。
当然,因为我们可能有不止一个设备要监控,所以我们需要一个包含 SIM 卡 ID 或设备 ID 的列。大概是字符串格式的。
因此,我们的任务是:
- 创建时间戳
- 沿着时间轴分配事件
- 确保 PDP 事件包含数据使用事件
- 创建 SIM IDs
我们的目标数据集示例:
物联网连接数据(图片由作者提供)
设计原型
在我们写任何代码之前,让我们在脑海中播放一个场景。
我们从哪里开始?
带着笔记本和笔!但是我不想用我的画吓到你,所以我把它们都放进了幻灯片里。
首先,我们需要关注时间戳和数据使用事件。一旦我们有了时间轴,我们就可以开始分配任何事件。由于我们必须遵循分配上述三个事件的规则,我们将从分配“中间”事件(数据使用)开始,然后在时间轴上的核心事件旁边创建附加的“包装”事件。
我们还必须记住 SIM IDs。
事件和时间戳:时间轴上的可视化表示(图片由作者提供)
让我们去掉图表中除了时间戳和滞后之外的所有内容:
时间戳和延迟(图片由作者提供)
如您所见,我们不需要创建大量随机时间戳。我们需要创建一个开始时间戳,然后在每个现有时间戳上加上几秒钟,以生成下一个时间戳。
代码
生成时间戳列
我们可以手动设置第一个时间戳,或者使用 datetime 包中的 datetime.now()函数生成它。
from datetime import datetime, timedelta
import numpy as np
import pandas as pd
iotdf = pd.DataFrame(columns = [‘timestamp’, ‘event’, ‘simid’])
iotdf.at[0, ‘timestamp’, ] = datetime.now()
使用 NumPy 的 random.randint()函数将滞后作为随机数产生。对于这个用例,我将范围设置在 10 到 60 秒之间。
我们使用 datetime 包中的 timedelta()函数将随机生成的值添加到时间戳中。因为 random.randint()实际上创建了一个数组,所以我们必须访问它的第一个元素(即使在我们的例子中只有一个),并通过使用。item()方法。
像这样:
iotdf.at[1, ‘timestamp’] = iotdf.at[0,’timestamp’] + timedelta(seconds=np.random.randint(10,60,1)[0].item())
动态地而不是手动地改变行号允许我们自动地填充数据集。然而,在进行下一步之前,我们需要决定另外一件事。
设置时间戳限制
但是如何设置时间轴的终点呢?或者,更重要的是,生成它的代码应该在哪里停止?
三个可能的选项都使用了 while 循环:
- 您可以手动设置一个最终日期,然后在 while 循环中使用一个条件来保持生成过程一直进行到最终日期。在代码中,最终日期将是与数据集中最后一个当前存在的行相比较的。如果后者仍然小于最后一个,while 循环将继续。
final_date = ‘2021–01–05 14:58:32.908580’date_time_obj = datetime.strptime(final_date, ‘%Y-%m-%d %H:%M:%S.%f’)n = 0while iotdf.iloc[-1, 0] < date_time_obj:
x = n
n = n + 1
iotdf.at[n, ‘timestamp’] = iotdf.at[ x,’timestamp’] + timedelta(seconds=np.random.randint(10,60,1)[0].item())
时间戳列(作者图片)
- 您可以设置想要数据集覆盖的天数或小时数。和前面的例子一样,while 循环中的条件将最后一行中的值与要实现的数字进行比较,并决定是否停止。
number_of_hours = 48n = 0while (iotdf.iloc[-1, 0] — iotdf.iloc[0, 0]).days * 24 < number_of_hours:x = n
n = n + 1
iotdf.at[n, ‘timestamp’] = iotdf.at[ x,’timestamp’] + timedelta(seconds=np.random.randint(10,60,1)[0].item())
- 您可以设置所需的行数。您将计算 while 循环中已经创建的行数,并将其与目标行数进行比较,以保持其运行。
number_of_rows = 90000n = 0while iotdf.shape[0] < number_of_rows:x = n
n = n + 1
iotdf.at[n, ‘timestamp’] = iotdf.at[ x,’timestamp’] + timedelta(seconds=np.random.randint(10,60,1)[0].item())
在我们定义了数据集限制之后,我们可以让 while 循环运行并为我们完成工作。
生成事件列
现在,当我们有了时间戳,我们就可以分配数据使用事件了。我们需要随机选择与特定事件相关联的时间戳。
我们再次使用随机数。我们创建一列,对于每一行,我们在至少与数据集本身一样大的范围内生成一个随机数。
iotdf[‘randNumCol’] = np.random.randint(1, iotdf.shape[0], iotdf.shape[0])
现在,我们必须做一些任意的事情。我们像这样定义一个范围(我们的数据集有 90,000 行):
1 < x < 60000
The x represents a cell in the random numbers column. We then loop over the rows using the apply() function again to assign the data usage event based on whether the random number falls into the range or not. The loop will create the events column.
We fill the empty rows in the new column — those that do not fall into the ranges — with alerts. A custom function helps to keep the whole less messy.
def random_event(x):if (x >= 1) & (x < 60000):
result = ‘data’
else:
result = ‘alert’
return resultiotdf[‘event’] = iotdf[‘randNumCol’].apply(random_event)
By selecting a range like the one above, try to consider whether you need a lot of particular events or you want them to be a rare thing. In the first case, select big ranges; for the second one, select narrow ranges. This will steer the total amount of one event type to be generated.
You can define multiple ranges to allocate multiple types of mutually excluding events.
生成设备/SIM ID 列
您可以在分配 SIM 卡 id 的范围内重复这个技巧。请记住,范围的数量必须与您需要分配的 SIM IDs 的数量一致,并且范围必须覆盖我们在创建随机数列时使用的整个范围。
def random_simid(x):if (x >= 1) & (x < 25000):
result = ‘0001’
elif (x >= 25000) & (x < 50000):
result = ‘0002’
elif (x >= 50000) & (x < 75000):
result = ‘0003’
else:
result = ‘0004’
return resultiotdf[‘simid’] = iotdf[‘randNumCol’].apply(random_simid)
事件和 SIM IDs 准备就绪(图片由作者提供)
依赖事件
现在,我们可以继续生成 PDP 事件。我们可以用 for 循环遍历这些行,对于每个数据使用时间戳,我们创建两个 PDP 事件,一个在前面,一个在后面,每个都有一秒钟的延迟。我们从父数据使用事件中复制 SIM ID 号。
我们首先将新行“附加”到数据框,以避免创建重复的行号。最后,我们简单地按照时间戳列对数据进行排序,并去掉我们不再需要的随机数列。
n = iotdf.shape[0]for i in range(0,iotdf.shape[0]):if iotdf.at[i, ‘event’] == ‘data’:
n = n + 1
iotdf.at[n, ‘event’] = ‘Create PDP context’
iotdf.at[n, ‘timestamp’] = iotdf.at[i, ‘timestamp’] — timedelta(seconds = 1)
iotdf.at[n, ‘simid’] = iotdf.at[i, ‘simid’]
n = n + 1
iotdf.at[n, ‘event’] = ‘Delete PDP context’
iotdf.at[n, ‘timestamp’] = iotdf.at[i, ‘timestamp’] + timedelta(seconds = 1)
iotdf.at[n, ‘simid’] = iotdf.at[i, ‘simid’]
iotdf = iotdf.sort_values(by=’timestamp’)
iotdf = iotdf.drop(columns = [‘randNumCol’])
iotdf.head(n = 10)
最终结果(图片由作者提供)
看起来我们真的完了!
一会儿之后
在现实世界中,物联网设备可能会生成各种各样的消息,如 GPS 坐标、切换到新的移动运营商、发送的数据量等。
因此,我试图将重点放在可用于创建基本列的底层逻辑上:时间戳和事件。
手稿
完整的代码可以在 Google Colab 中找到:
https://colab.research.google.com/drive/1A0LGkQxUs9rG8BTS1J5_lg8ZNbBjZXRK?usp=sharing [## 谷歌联合实验室
物联网数据](https://colab.research.google.com/drive/1A0LGkQxUs9rG8BTS1J5_lg8ZNbBjZXRK?usp=sharing)
确保仅运行设置数据集限制的三个建议选项之一。
如何打造一份让人无法抗拒的数据科学简历(附代码)
原文:https://towardsdatascience.com/how-to-create-an-irresistible-data-science-resume-with-code-1430a774c836?source=collection_archive---------13-----------------------
不要浪费时间使用 Word。使用模板、几行代码和技巧来增加你获得面试的机会。
塞巴斯蒂安·赫尔曼在 Unsplash 上的照片
写一份好的简历很难。你必须总结你在职业生涯中做过的所有好事,根据工作描述量身定制你的简历,甚至创建一份好看的简历,让你与众不同。
但你既不是创意作家,也不是平面设计师。那么如何在不花几个小时玩微软 Word 的情况下,创建一份令人无法抗拒的数据科学简历呢?
我们可以使用背页模板和 LaTeX,而不用像 Word 这样的文本编辑器。如果您在数据科学职业生涯中曾经使用过 Jupyter 笔记本,可能您已经使用 LaTeX 创建了数学方程。在这种情况下,我们将使用不同的 LaTeX 命令来编辑默认模板,并制作我们自己的简历。
Overleaf 和 LaTeX 将使您不必亲自完成所有的格式编排(因此您永远不必处理混乱的布局),并帮助您专注于最重要的内容。
本文将分为两个部分。设计部分将在背页完成,它将帮助你从传统简历迅速转变为现代简历。
演职员表:背面
另一方面,内容部分将包括如何撰写数据科学简历的实际例子,因此您可以增加获得面试的机会。
**Table of Contents** 1\. [Section 1: The Design](#1f32)
- [Step 1: Choose an Overleaf Template](#a2cd)
- [Step 2: Edit The Template](#ff14)
- [Step 3: Add/Remove a Second Page and Download the Resume](#a6c5)
2\. [Section 2: The Content](#f172)
- [Keywords](#7398)
- [The What, How, and The Effect](#9607)
- [Focus on the outcomes](#8977)
- [Include Projects](#b643)
第一部分:设计
第一步:选择一个背页模板
这里是上百个简历模板的图库。点击其中任何一个,然后你会看到 3 个选项:作为模板打开,查看源代码,下载 PDF。
第一个将在背面打开一个模板,这样我们可以使用它的编辑器引入我们自己的数据。第二个选项将显示模板的普通代码,而第三个选项将按原样下载模板。
要制作我们自己的简历,我们选择“作为模板打开”如果您有背页帐户,您将被重定向到编辑器,但如果您没有,您将看到登录页面。只需使用 Google(或您喜欢的选项)注册,就可以被重定向到编辑器。
登录后,您会看到类似这样的内容:
作者图片
有 3 个主要部分:
- 左边栏:在这里你可以管理所有用来创建简历的文件。大多数模板都有 3 个缺省文件:一个. cls 文件(我在这里几乎不做任何修改,但是它必须在那里,模板才能工作),一个. tex 文件(这里我们引入所有数据来修改模板),和一个. jpg 文件(只有当模板包含图像时)
- source 部分:这个部分允许我们编辑用来创建模板的代码。紫色的命令很容易记住(你甚至可以直观地学习它们)。如你所见,我已经分别通过编辑命令
\name
和\photo
更改了默认名称和照片(当然,你必须首先通过点击左上角的第三个按钮来上传照片)。我将在下一步给出更多关于如何编辑模板的细节(例如,如何插入图标、分隔线、标签和更多酷的东西) - 预览部分:在这里你可以看到你正在创建的简历的预览。只需点击“重新编译”按钮来运行它。完成后,点击“下载 PDF”下载最终简历。
步骤 2:编辑模板
对于这个例子,我将使用步骤 1 中显示的模板。您可以选择任何想要的模板,但请记住,可能会有一些小的变化(一些模板有额外的部分或在不同的位置有部分)
不管你选择什么样的模板,我们都将学习最常用的 LaTeX 命令,以我们想要的方式编辑模板。你可以检查这里所有可用的命令。
让我们编辑一些你的数据科学简历中的必备部分。
接触
作者图片
您可以在此添加任何想要共享的联系信息。若要定位表示此部分的代码,请打开。tex 文件,按 CTRL+F,并写下“联系人”你会看到这样的东西;
\highlightbar{**\section{Contact}**
\email{mail@mailprovider.com}
\phone{+49 123 456789}
\location{Some Street 1, 12345 City Name}
...\section{Skills}
在花括号内,你可以引入你自己的数据。使用反斜杠()编写命令。在这种情况下,通过书写他们的名字可以容易地创建联系人图标(例如,\email
、\github
和\linkedin
)。
技能
作者图片
在这里,您突出显示了您拥有的所有技能,并按级别对它们进行了分类。按 CTRL+F,并写“技能”来定位这一部分。您将看到以下结构。
**\section{Skills}**
**\skillsection{Programming}**
\skill{Python}{5}
\skill{Bash}{4}
\skill{C++}{2}
\skill{Apple Script}{3}
\skill{HTML/CSS}{3}
\skill{LaTeX}{4}
\vspace{0.5em}
**\skillsection{Operating Systems}**
...
要添加一个新的子部分(比如上图中的“编程”),使用\skillsection
命令,而\skill
命令将显示技能及其等级(数字代表红点的数量)。您可以添加诸如编程技能、软件&工具、语言技能等子部分。
记住“技能”里面的每个子部分后面都有一个垂直空格(\vspace),
,所以在做修改的时候不要忘记删除或者添加它。
工作经历和教育
作者图片
这些部分具有相似的结构。如果你搜索“工作经历”或“教育”,你会找到这样的内容。
**\section[\faGears]{Work history}**
\job{date}
{Employer name and city}
{Position Title}
{Job Function}
显然,您在之前的工作中做了很多事情,所以要列出所有这些事情,我们必须添加\item
命令。现在,新代码将如下所示:
**\section[\faGears]{Work history}**
\job{date}
{Employer name and city}
{Position Title}
{**\begin{itemize}**
\item Funcion 1
\item Funcion 2
\item Funcion 3
**\end{itemize}**}
你也可以改变默认的齿轮图标\faGears
。在这里你可以找到 Latex 上所有可用图标及其命令的列表。假设你更喜欢用行李箱作为图标,然后进入那个页面,搜索“行李箱”这个词。您会发现\faSuitcase
命令,所以在第一行代码中介绍它。
**\section[****\faSuitcase****]{Work history}**
\job{date}
...
成就和一般技能
作者图片
这两个部分都使用特殊的命令,使简历看起来更好。“成就”部分如下所示:
**\section{Achievements, honours and awards}**
\achievement{My first achievement}
\achievement{My second achievement}
通过使用\achievement
命令,我们用一个奖杯图标列出我们所有的成就。
作者图片
“一般技能”部分如下所示:
**\section{General Skills}**
\smallskip % additional skip because tag outlines use up space
\tag{Tag 1}
\tag{Tag 2}
\tag{and}
\tag
命令允许我们在那些漂亮的圆角矩形内添加技能。
其他部分
您可以创建更多节,删除任何现有节或完全更改它们。例如,我选择的模板有一个“车轮图”,显示“你生命中的一天”
如果这看起来与你无关,就把它改成课外活动、强项或你从事的项目。您也可以删除它的代码来去掉那个部分,或者用百分号%
注释掉它。
第三步:添加/删除第二页并下载简历
您可以添加任意多的页面。复制第一页的原码粘贴到下面就可以了。
如果你的模板有第二个你想删除的页面,使用%
注释掉整个页面或者删除它的代码。
最后,你可以点击“下载 PDF”选项来下载简历确保通过单击左上角的铅笔按钮来重命名文件。这将有助于您在以后轻松识别该模板,并在将来进行更多的更改。
第二部分:内容
第一部分将有助于简历引起招聘人员的注意,现在在第二部分,我将向你展示一些你可以做的事情来增加获得面试的机会。
关键词
你知道吗,大部分时间简历都是由申请人跟踪系统扫描的?这个工具可以帮助招聘人员使用特定的关键词在几分钟内筛选出简历。
阅读职位描述,选择合适的关键词来很好地描述你的经历,并表明你是这份工作的潜在合适人选。
数据科学领域中使用的一些关键词是:
信用:拉希德赛
什么、如何和效果
每当你描述你在以前的工作中所做的事情时,包括你做了什么,你是如何做的,以及它的效果。
利用 Python 实施了机器学习技术,用于对 3TB 非结构化数据进行时序异常检测,从而将总处理时间减少了 20%
顺序并不重要,但是要确保你把它们都包括在内。
关注结果
告诉你使用的复杂算法是很好的,但你应该专注于结果。归根结底,公司更关心的是最终结果,而不是你是如何做到的。
包括数字,使结果可以衡量。我们上面使用的例子在用数字突出结果方面做得很好。
“利用 Python 实施机器学习技术,对 3TB 非结构化数据进行时序异常检测,,将总处理时间减少了 20%”
包括项目
如果你没有经验或者经验很少,这是非常有用的。解决你喜欢的主题的项目,并在你的简历中突出它们。以下是你可以在简历中加入的 5 个数据科学项目清单。
你可以在你的 Github 上添加一个链接来显示你的项目代码,甚至可以写一篇像这样的数据科学文章,用简单的英语解释你的项目是关于什么的(记住,HR 不懂编程,所以一篇文章会让其他人很容易知道你构建了什么,你是如何做的以及结果)
恭喜你!你创造了一份不可抗拒的数据科学简历。你可以随时在评论区、电子邮件或 LinkedIn 上问我你想在简历中添加的任何特色。
与 3k 以上的人一起加入我的电子邮件列表,获取我在所有教程中使用的 Python for Data Science 备忘单(免费 PDF)
如果你喜欢阅读这样的故事,并想支持我成为一名作家,可以考虑报名成为一名媒体成员。每月 5 美元,你可以无限制地阅读媒体上的故事。如果你使用我的链接注册,我会赚一小笔佣金,不需要你额外付费。
https://frank-andrade.medium.com/membership
如何创建一个 Ubuntu 服务器来使用 Docker 构建一个 AI 产品
原文:https://towardsdatascience.com/how-to-create-an-ubuntu-server-to-build-an-ai-product-using-docker-a2414aa09f59?source=collection_archive---------9-----------------------
业内笔记
构建 Ubuntu 服务器的代码片段集合,该服务器可用于开发简单的人工智能产品。
凯文·霍尔瓦特在 Unsplash 上拍摄的照片
要在云上部署一个人工智能引擎,你很可能需要运行一个虚拟的基于 Linux 的服务器,上面有基本的软件和库。启动服务器的一个标准方法是创建一个满足所有需求的 docker 映像。您可以在作为服务器的任何机器上使用相应的 docker 映像运行 docker 容器。一般来说,构建 AI 产品的标准服务器必须有几个基本的软件和库,包括 Python、Java、Git、Docker 和 GCloud。例如,每当 AI 模型更新时,您需要构建一个新的 docker 映像;所以docker
必须安装。然后,你需要在云上部署带有新 AI 模型的新 docker 镜像;所以,例如,gcloud
和kubectl
必须安装。
在这篇文章中,我想分享如何在 Ubuntu 机器上安装 essentials 来构建一个 AI 产品。在这里,您可以找到一组代码片段,这些代码片段将在 order 文件中使用,以便构建一个 Ubuntu 服务器。我强烈建议创建一个专门的Dockerfile
来为你的项目量身定制,并确保它安全可靠。这有助于您在需要时启动服务器。希望这能大大加快你的发展。
一台 Ubuntu 机器
先说 Ubuntu 20.04。首先,你必须更新为 Ubuntu(以及 Linux 的其他主要发行版)设计的高级包管理器apt-get
。然后,git
必须安装软件,让你在需要的时候checkout
使用你的代码库。下面的代码将是 docker 文件中的第一行。
FROM ubuntu:20.04
RUN apt-get update && apt-get -y install sudo
RUN sudo apt-get -y install software-properties-common### INSTALL GIT
RUN sudo apt-get -y install git
—如何在 Ubuntu 上安装 PYTHON 3.7
您可以使用下面的代码在 docker 机器上安装一个干净的 Python 3.7。请注意,无论如何您都需要安装项目所需的库。在这里,我试图保持简单和干净。
### INSTALL PYTHON
RUN sudo apt-get -y install libssl-dev openssl
RUN sudo apt-get -y install libreadline-gplv2-dev libffi-dev
RUN sudo apt-get -y install libncursesw5-dev libsqlite3-dev
RUN sudo apt-get -y install tk-dev libgdbm-dev libc6-dev libbz2-dev
RUN sudo apt-get -y install wget
RUN apt-get update && apt-get install make
RUN sudo apt-get -y install zlib1g-dev
RUN apt-get -y install gcc mono-mcs && \
rm -rf /var/lib/apt/lists/*
RUN wget [https://www.python.org/ftp/python/3.7.10/Python-3.7.10.tgz](https://www.python.org/ftp/python/3.7.10/Python-3.7.10.tgz)
RUN tar xzvf Python-3.7.10.tgz
RUN ./Python-3.7.10/configure
RUN sudo make install
RUN alias python=python3
—如何在 Ubuntu 上安装 DATABRICKS-CONNECT
如果您处理真实世界的数据,您可能需要处理大量的数据,这些数据在小型 VPS 或强大的专用裸机服务器上无法轻松管理。Databricks 推出了一项非常有用的服务,可以让您连接到高度优化的 Databricks 集群进行大数据处理。他们强大的 Spark 机器可以让你在几秒钟内构建大型人工智能模型。为此,您必须通过名为databricks-connect
的库连接到 Databricks 集群。您可以使用下面的代码在 Ubuntu 上安装databricks-connect
。要了解更多关于 Databricks 集群逐步配置的信息,请查看本文:如何将本地或远程机器连接到 Databricks 集群。
### INSTALL JAVA
RUN sudo add-apt-repository ppa:openjdk-r/ppa
RUN sudo apt-get install -y openjdk-8-jre### INSTALL DATABRICKS-CONNECT
RUN pip3 install --upgrade pip
RUN pip3 uninstall pyspark
RUN pip3 install -U databricks-connect==7.3.*
—如何在 Ubuntu 上安装 DOCKER 和 DOCKER-COMPOSE
假设你正在开发一个运行人工智能引擎的 API 服务。每次人工智能模型更新时,你必须建立一个新的解决方案。在这种情况下,您需要在您的机器上安装 docker 服务,让您运行诸如docker build
或docker push
之类的命令。你可以运行下面的代码让你在 Ubuntu 机器上安装 docker。
### INSTALL DOCKER
RUN apt-get update && apt-get install -y curl
RUN curl -fsSL https://get.docker.com -o get-docker.sh
RUN sudo sh get-docker.sh## INSTALL DOCKER-COMPOSE
RUN sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
RUN sudo chmod +x /usr/local/bin/docker-compose
—如何在 Ubuntu 上安装 GCLOUD 和 KUBECTL
如果你想为你的产品使用谷歌云服务,你必须安装gcloud
来与谷歌基础设施通信。例如,如果您想使用他们的容器注册服务来存储项目期间构建的 docker 映像,您必须安装gcloud
库。另外,如果您想使用强大的 Kubernetes 引擎在这个基础设施上部署您的解决方案,您必须安装kubectl
。请注意,您肯定可以使用其他服务,如 AWS 或 Azure,它们需要自己的配置。
### INSTALL GCLOUD
RUN curl https://dl.google.com/dl/cloudsdk/release/google-cloud-sdk.tar.gz > /tmp/google-cloud-sdk.tar.gz
RUN mkdir -p /usr/local/gcloud \
&& tar -C /usr/local/gcloud -xvf /tmp/google-cloud-sdk.tar.gz \
&& /usr/local/gcloud/google-cloud-sdk/install.sh
ENV PATH $PATH:/usr/local/gcloud/google-cloud-sdk/bin### INSTALL KUBECTL
RUN curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s [https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl](https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl)
RUN chmod +x ./kubectl
RUN mv ./kubectl /usr/local/bin
—如何安装节点。Ubuntu 上的 JS
如果你想为你的 AI 引擎创建一个简单的用户界面,你很可能需要安装 Node。我强烈建议保持它的干净和明亮,以确保以后不会有记忆问题。
### INSTALL NODE.JSENV NODE_VERSION=12.6.0
RUN apt install -y curl
RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash
ENV NVM_DIR=/root/.nvm
RUN . "$NVM_DIR/nvm.sh" && nvm install ${NODE_VERSION}
RUN . "$NVM_DIR/nvm.sh" && nvm use v${NODE_VERSION}
RUN . "$NVM_DIR/nvm.sh" && nvm alias default v${NODE_VERSION}
ENV PATH="/root/.nvm/versions/node/v${NODE_VERSION}/bin/:${PATH}"
RUN node --version
RUN npm --version
—遗言
您可能会在上面的代码中发现一些冗余。例如,我可能会多次更新apt-get
包管理器。我这样做是为了确保每个部分都可以独立执行。最后但同样重要的是,我花了一些时间才找到如何在 Ubuntu 机器上安装必要的软件和库。希望这能加快你的发展。
感谢阅读!
如果你喜欢这个帖子,想支持我…
- 跟我上 中 !
- 在 亚马逊 上查看我的书!
- 成为 中的一员 !
- 连接上Linkedin!
- 关注我 推特 !
https://pedram-ataee.medium.com/membership
如何创建机器学习应用程序并将其部署到 Heroku
原文:https://towardsdatascience.com/how-to-create-and-deploy-a-machine-learning-app-to-heroku-d6965aa4f627?source=collection_archive---------10-----------------------
由 envato elements 的 Faber14 使用图像创建(经许可)。
数据科学 | 机器学习
从模型到部署的分步指南
机器学习模型的部署是数据生命周期中的一个重要阶段。这样的模型可以是一个最小可行产品(MVP ),它允许相关的涉众访问模型并从中进行测试和试验,这可以为进一步的模型改进提供有价值的反馈。
模型部署可能看起来是一项困难和令人生畏的任务,但事实并非如此。在本文中,您将了解如何使用 Heroku 轻松地将机器学习应用程序部署到云中。部署到 Heroku 的优势在于,我们不必担心与应用运行的底层操作系统相关的任何事情(即,不再需要安装更新、依赖或维护)。
需要注意的是,本文有一个附带的视频( 如何将数据科学 Web App 部署到 Heroku ),可以作为参考的补充或视觉辅助。
如何将数据科学 Web App 部署到 Heroku @ 数据教授
1.什么是 Heroku,我们为什么需要它?
Heroku 是一个平台即服务,将应用程序部署到云上。该平台正式支持由 Node.js、Ruby、Java、PHP、Python、Go、Scala 和 Clojure 等多种编程语言创建的应用。它还通过使用第三方构建包支持其他语言(比如 R Shiny)。
与在 Linux 或 Windows 操作系统上创建自己的虚拟专用服务器(VPS)相比,使用 Heroku 的优势在于维护服务器所需的时间和开销。想象一下处理软件升级、依赖性和兼容性问题的头痛。
Heroku 网站截图。
例如,我有一个 Ubuntu 服务器,运行着我的几个 R Shiny 应用程序,运行得非常好,但它运行在 Ubuntu 14 和一个旧版本的 R 上,这意味着它不支持新的 R 包。将所有的应用程序迁移到一个新的服务器似乎是一个压倒性的任务,直到今天我还在拖延。如果使用 Heroku,所有这些问题都不再重要。最棒的是,你可以从 Heroku 免费开始,因为他们每月提供大约 550-1000 dyno 小时的免费服务。
dyno 是独立的 Linux 容器,是 Heroku 产品的构建模块。它们的尺寸从小型且经济的 dyno(提供较少的 CPU 处理器和较小的 RAM 容量)到更大且更昂贵的 dyno(无限的 CPU 处理器和高达 14 GB 的 RAM)。
2.我们今天部署的是什么型号
企鹅分类模型的概要。
我们今天要部署的机器学习模型是企鹅物种分类模型。
本质上,该模型将使用企鹅的先天物理特征(例如喙长、喙深、鳍长、体重)以及它们的性别和地理位置作为输入参数(即 X 变量),以便将企鹅分类为属于三个物种(例如阿德利企鹅、巴布亚企鹅和下颚带企鹅)中的一个,即 Y 变量。
左侧图像中总结了建模工作流程的卡通插图。
3.构建机器学习模型
现在,我们已经看到了如何构建模型的示意性工作流,现在让我们看一下代码。
3.1.密码
3.2.逐行解释
在这个简单的例子中,我们将使用随机森林算法将企鹅分类为属于上面提到的三个物种(阿德利企鹅、巴布亚企鹅和下巴颏企鹅)中的一个。
第 1 行 —导入pandas
库,该库随后将用于存储企鹅数据集的值。
第 2 行 —使用pd.read_csv()
函数从 CSV 文件中读入企鹅数据集,并将内容存储到penguins
变量中。
第 4 行和第 5 行 —注释文本,描述下面的代码块将执行序号特征编码
第 6 行 —将penguins
变量的内容复制到新创建的df
变量中。
第 7 行 —指定在df
数据帧中找到的列名'species'
,我们将使用它作为 Y 变量。
第 8 行 —创建一个待编码的有序特征列表,并将其分配给encode
变量。
第 10–13 行 —这里,序数特征将被编码。for
循环用于迭代要编码的 2 个特征,如下:
—通过pd.get_dummies()
函数执行一次热编码,并将新生成的热编码值作为新列连接到df
数据帧中。
—最后,从df
数据框中删除原来的列。
第 15–19 行 —将用作 Y 变量的物种列现在将通过数值映射转换为数值形式,从而将类别标签(Adelie、Chinstrap 和 Gentoo)映射为数值(0、1 和 2),如第 15 行所示。创建一个简单的自定义函数来执行这个数字映射(第 16 和 17 行),它将应用于第 19 行。然后,映射值被分配给df
数据帧的'species'
列。
第 21–23 行—df
数据帧现在将被分成X
和Y
变量,分别在第 22 和 23 行执行。
第 25–28 行 —这段代码现在将构建第 25 行注释的随机森林模型。首先从sklearn.ensemble
子模块导入RandomForestClassifier
功能。该模型在第 27 行被实例化,由此RandomForestClassifier()
函数被分配给clf
变量。使用X
和Y
变量作为输入数据,通过clf.fit()
功能最终在第 28 行训练模型。
第 30–32 行 —最后,我们将通过用pickle
库序列化来保存模型,其中pickle.dump()
函数将把存储在clf
变量中的训练模型保存到一个名为penguins_clf.pkl
的文件中。
我们现在有了从scikit-learn
保存的训练模型,我们现在将使用它进行模型部署。
4.构建 Web 应用程序
关于使用 Streamlit 库用 Python 构建 Penguins web 应用程序的完整细节和逐行解释,请参见上一篇文章(见下文)。
4.1.密码
现在让我们使用 Streamlit 库来构建企鹅应用程序。下面显示的penguins-app.py
文件中提供了构建应用程序的代码。这个应用程序将利用训练好的模型(penguins_clf.pkl
)来预测类别标签(企鹅的物种是阿德利企鹅、下巴颏企鹅还是巴布亚企鹅),方法是使用来自 web 应用程序前端侧边栏面板的输入参数。
4.2.启动应用程序
我们将在自己的电脑上本地启动该应用程序。首先,确保你已经安装了streamlit
,如果你还没有,你可以使用下面的命令来安装:
pip install streamlit
在终端中,我们现在可以使用以下命令启动应用程序(penguins-app.py
文件):
streamlit run penguins-app.py
稍后,我们应该会在终端中看到以下输出。
> streamlit run penguins-app.pyYou can now view your Streamlit app in your browser.Local URL: http://localhost:8501
Network URL: http://10.0.0.11:8501
然后会弹出一个浏览器,给我们一个企鹅应用程序。
企鹅 App 本地版截图。
既然 web 应用程序可以在本地工作,我们现在将继续把它部署到云上。
5.企鹅应用程序的存储库
5.1.创建新的存储库
首先,我们将在 GitHub 上创建一个新的存储库,并将该存储库命名为penguins_heroku
,可以在 存储库名称 的文本框中输入。然后在上打勾添加一个自述文件 并点击 创建资源库 。
在 GitHub 上创建新存储库的截图。
其次,我们将把训练好的模型(penguins_clf.pkl
)和 web 应用(penguins-app.py
)上传到这个新的 GitHub 存储库中。这可以通过点击 添加文件>上传文件 来完成。然后选择并上传以上 2 个文件(penguins_clf.pkl
和penguins-app.py
)。
显示如何将文件上传到 GitHub 存储库的屏幕截图。
从上面的屏幕截图中,您将看到除了 2 个上传的文件之外,我们还有 5 个额外的文件(Procfile
、penguins_example.csv
、requirements.txt
、setup.sh
和runtime.txt
),我们也必须创建这些文件并将其放置在这个存储库中。
Procfile
企鹅 _ 示例. csv
requirements.txt
setup.sh
runtime.txt
5.2.在存储库中创建新文件
要在 GitHub 上直接创建新文件,我们可以点击 添加文件>创建新文件 。
显示如何在 GitHub 存储库中创建新文件的屏幕截图。
在下面的例子中,我们将创建上述四个文件中的一个,我们将从创建Procfile
文件开始:
显示创建 Procfile 的屏幕截图。
然后,滚动到页面底部,点击 提交新文件 按钮。然后,您应该注意到 Procfile 被添加到了存储库中。
对由penguins_example.csv
、requirements.txt
、setup.sh
和runtime.txt
组成的其余 4 个文件重复上述步骤。
6.部署到 Heroku
现在让我们通过前往 Heroku 网站注册(如果您还没有注册)并登录来部署模型。
6.1.报名参加 Heroku
要注册一个免费的 Heroku 帐户,找到 Heroku 网站右上角的 【注册】 按钮,如下所示。
在哪里可以找到“注册”按钮的截图(用红色矩形表示)。
6.2.登录 Heroku
注册后,登录您的 Heroku 帐户。
6.3.创建新应用程序
要创建一个新的应用程序,点击 新建>创建新的应用程序 按钮,如下图所示。
在哪里可以找到“创建新应用”按钮的截图(右上角)。
现在,我们将为应用程序命名,这里我们将使用仍然可用的penguins-model
。需要注意的是,如果一个应用程序名称已经被使用,你会看到一个错误信息,如果是这样,你可以选择一个新的名称。
要继续,点击底部的 创建 app 按钮。
显示新应用程序命名的屏幕截图。
6.4.连接到 GitHub
我们现在要将我们的应用程序连接到 GitHub 存储库。为此,点击 GitHub(连接到 GitHub) ,如下图所示。
显示部署方法的屏幕截图。
如果这是你第一次部署到 Heroku,你将不得不验证你的 GitHub 帐户,并给予 Heroku 访问它的许可。每一个 Heroku 帐号都要这样做一次。
现在,在文本框中输入您刚刚创建的 GitHub 库的名称,并点击 连接 。
显示企鹅应用程序的 GitHub 存储库名称条目的屏幕截图。
6.5.部署
如果成功,您将看到Connected to dataprofessor/penguins-heroku
消息。需要注意的是,我们可以激活Automatic deploys
,但建议在Manual deploy
成功后再激活。因此,我们可以稍后再回来激活它。
现在,向下滚动并点击 部署分支 按钮。
显示已连接的 GitHub 存储库以及自动部署和手动部署的屏幕截图。
构建日志将随着容器的供应和必备库的安装而更新。
显示容器和库安装供应的屏幕截图。
在容器被提供并且库被成功安装之后,您应该会看到消息Your app was successfully deployed
。
现在,单击 视图 按钮启动部署的 web 应用程序。
显示已部署应用程序的成功消息的屏幕截图。
7.部署企鹅应用程序
如果您看到 web 应用程序没有错误消息,那么恭喜您!您现在已经成功部署了企鹅应用程序。如果您想观看企鹅 App 的 演示,请点击以下链接。
Heroku 上部署的企鹅 App 截图。
订阅我的邮件列表,获取我在数据科学方面的最佳更新(偶尔还有免费赠品)!
关于我
我是泰国一所研究型大学的生物信息学副教授和数据挖掘和生物医学信息学负责人。在我下班后的时间里,我是一名 YouTuber(又名数据教授)制作关于数据科学的在线视频。在我做的所有教程视频中,我也在 GitHub 上分享 Jupyter 笔记本(数据教授 GitHub page )。
https://www.youtube.com/dataprofessor
在社交网络上与我联系
YouTube:【http://YouTube . com/data proper/
网站:【http://data proper . org/【正在建设】
LinkedIn:【https://www . LinkedIn . com/company/data proper/
如何在 R 中创建动画情节
原文:https://towardsdatascience.com/how-to-create-animated-plots-in-r-adf53a775961?source=collection_archive---------7-----------------------
使用来自 envato elements 的 alexdndz 的图像创建(经许可)。
循序渐进的教程
使用 gganimate R 包制作时间序列数据的动画
一张图片胜过千言万语,图表和情节提供的见解也是如此。数据可视化是任何数据科学项目的重要组成部分,因为它允许以图形和图表的形式有效地讲述数据。即使是静态的情节也能传达重要的信息并提供巨大的价值,想象一下一个动画情节能做什么来突出情节的特定方面。
汉斯·罗斯林在他的 TED 演讲中关于 Gapminder 数据(他是该数据的创始人)的动画情节吸引了我们所有人,因为它将数据带入了生活。
在本文中,您将学习如何使用ggplot
和gganimate
R 包为时间序列数据集创建令人惊叹的 R 动画图。
观看附带的 YouTube 视频:https://youtu.be/z9J78rxhcrQ
1.我们今天构建的动画情节
今天,我们将构建 Gapminder 数据集的动画散点图。特别是,你会看到这个情节是由大陆分割的(分成不同的子情节),而不是在同一个情节中(这可能会很混乱)。
动画情节将使用ggplot2
和gganimate
R 软件包构建。
下面展示的是我们今天构建的动画剧情(来源: gganimate )。
使用 ggplot 和 gganimate 创建的 Gapminder 数据集的动画散点图。
2.编码环境
现在,启动您选择的 IDE,无论是 RStudio、Kaggle 笔记本还是普通的老式 R 终端。在这个编码环境中,你将输入后面提到的代码。
我个人最喜欢的 R 语言编码应该是使用免费开源的 RStudio IDE。
3.安装必备的 R 包
在本教程中,我们使用 4 R 包,包括gapminder
、ggplot2
、gganimate
和gifski
。
要安装这些 R 包,请在 R 终端中输入以下内容(无论是直接输入 R 终端、RStudio 中的 R 终端还是 Kaggle 笔记本的代码单元。
install.packages(c('gapminder','ggplot2','gganimate','gifski'))
现在让我们来看看为什么我们要使用上面的 R 包。
gapminder
包含我们在本教程中使用的 Gapminder 时间序列数据集的摘录。ggplot2
允许我们创建出色的数据可视化,即散点图gganimate
允许我们给剧情添加动画gifski
允许我们将动画渲染为 GIF 文件格式(GIF 是一种流行的动画图像格式)。
4.探索 Gapminder 数据集
在我们的数据可视化之前,让我们看一下 Gapminder 数据集。
这里,我们将从加载gapminder
包开始,并返回gapminder
变量的内容。
gapminder 数据集的屏幕截图。
在这里,我们可以看到数据是一个由 1704 行和 6 列组成的 tibble (tidyverse 对数据帧的实现)。
这 6 列包括:
country
—国家名称continent
—各大洲的名称year
—数据输入的年份lifeExp
—给定年份的预期寿命pop
—给定年份的人口数量gdpPercap
—给定年份的人均国内生产总值
5.创建静态散点图
在本节中,我们将创建一个静态版本的散点图,它可以用作与动画版本进行比较的基线。
5.1.密码
创建散点图的代码如下所示:
我如何在 RStudio 中实现代码的屏幕截图:
在 RStudio IDE 中实现代码的屏幕截图。
5.2 逐行解释
- 线 1—
ggplot()
功能用于使用ggplot2
R 包创建图形。第一个输入参数定义了存储在gapminder
变量中的输入数据。aes()
功能通过定义使用显示在 X 轴上的gdpPercap
同时定义显示在 Y 轴上的lifeExp
来实现输入变量的美学映射。每个数据点的大小现在将取决于pop
变量(值pop
越大,数据点也变得越大)。最后,数据点的颜色(特别是colour
参数)将是其所属country
的函数。 - 第 2 行 —
geom_point()
用于定义 alpha 透明度(即数据点将是半透明的,如alpha
参数 0.7 所定义;值越低,它们变得越半透明)。顾名思义,show.legend=FALSE
将隐藏图例。 - 第 3 行 —
scale_colour_manual()
函数定义存储在country_colors
变量中的配色方案,该方案将用于根据国家给数据点着色。 - 第 4 行 —
scale_size()
函数定义数据点的大小范围(即,回想一下在第 1 行,我们在aes()
函数中定义size=pop
)在 2 和 12 的范围内(即 2 是小数据点,而 12 代表最大数据点)。 - 第 5 行 —
scale_x_log10()
函数通过 log10 对 X 轴上的数据进行对数转换。 - 第 6 行 —
facet_wrap()
功能使用大陆变量将图分割成多个子图(即该过程也称为面)。 - 第 7 行 —
labs()
函数定义了绘图标题、X 轴标题和 Y 轴标题。
5.3.将图保存到文件
从上面的截图我们可以看到,该图显示在 图 面板(左下面板)中,但没有保存到文件中。
为了将绘图保存到文件中,我们将如下使用ggsave()
功能:
ggsave('plot_gdpPercap_lifeExp_static.png', width=8, height=8)
这产生了结果图:
6.创建动画散点图
有趣的部分来了,现在让我们继续使用gganimate
R 包创建动画散点图。
6.1.密码
上述代码生成以下动画情节:
6.2.逐行解释
- 第 1–6 行 —解释与静态图相同,因此请参考第 5.2 节的解释。
- 第 7 行 —注释文本,暗示接下来的几行与情节的动画部分有关。
- 第 8 行 —
labs()
函数定义了绘图标题、X 轴标题和 Y 轴标题。{frame_time}
将随着数据点在图中移动,动态显示变化的年份。 - 第 9 行 —
transition_time()
函数将year
变量作为输入,它允许动画情节根据year
变量逐帧过渡。 - 第 10 行 —
ease_aes()
函数将linear
作为输入参数,它将帧的过渡定义为线性方式。 - 正如我们所见,第 1-10 行被分配给了
p1
变量 - 第 12 行 —
animate()
函数将p1
变量中定义的图形作为输入参数,并执行动画渲染。 - 第 13 行 —
anim_save()
功能允许将渲染的动画图保存为. GIF 文件。
7.自定义动画情节
那么如何定制这个动画剧情呢?
在这一节中,我们将探索哪些参数可以调整,以进一步定制您的动画情节。
7.1.更改输入变量
因此,除了为gdpPercap
和lifeExp
(在 X 和 Y 轴中)制作散点图,我们还可以考虑gapminder
数据集中的其他列。
假设我们想要使用这两个变量:pop
和lifeExp
,我们可以在ggplot()
函数中定义它。
ggplot(gapminder, aes(pop, lifeExp, size = pop, colour = country))
注意,在上面的代码中,我们使用pop
和lifeExp
作为第一个和第二个输入参数(与第一个图中使用的gdpPercap
和lifeExp
相比)。
结果图如下所示:
7.2.更改子图布局
默认情况下,我们可以看到动画情节被安排为 2 行× 3 列布局。
7 . 2 . 1。水平布局
如果我们想把布局改成 1 行× 5 列,我们该怎么做呢?
转到第 6.1 节中包含facet_wrap(~continent)
的代码行(提示:第 6 行),并添加ncol=5
作为额外的输入参数,使其成为facet_wrap(~continent, ncol=5)
。
请注意,布局根据需要更新为 1 行 5 列。但是一个新的问题出现了,分图的宽度看起来有点太窄。
解决这个问题的方法是调整图形的宽度和高度。这可以通过向ggsave()
函数添加 2 个额外的输入参数来实现,如下所示:
anim_save('plot_pop_lifeExp_wide.gif', width=1600, height=400)
现在应该给出如下的图:
7 . 2 . 2。垂直布局
同样,现在让我们创建一个垂直布局的新地块。
我们可以通过简单地改变facet_wrap()
函数的ncol
输入参数的赋值来做到这一点。
之前,水平布局有:
facet_wrap(~continent, ncol=5)
。
现在,对于垂直布局,我们有:
facet_wrap(~continent, ncol=1)
。
7.3.调整字体大小
您可能会注意到 X/Y 轴和刻度标签的字体大小可能会变小,您可能希望对其进行调整。让我告诉你怎么做。
这里有一个调整上面提到的字体属性的示例代码。
你会注意到我们添加了第 7-13 行,它利用theme()
功能来调整字体大小、字体和颜色。
特别是,plot.title
允许我们调整图标题的字体(在我们的例子中是图左上角显示的Year
标签。这里,我们使用的字体大小为 20,字体为粗体,颜色为黑色。类似的调整也适用于 X 和 Y 轴标题(分别为axis.title.x
和axis.title.y
)、X 和 Y 刻度标签(分别为axis.text.x
和axis.text.y
)、小平面子图标签(strip.text.x
)和图图像周围的空白区域(plot.margin
)。
显示了更新后的图(上图),为了便于比较,我们将显示我们之前制作的原始图(下图)(使用默认字体大小)。更大的字体大小确实有助于提供更好的可读性。
使用更大字体的动画情节。
使用默认字体大小的动画图。
结论
在本总结中,您已经成功地为时序数据集(Gapminder)创建了一个动画散点图,并学习了如何对该图进行调整。
接下来呢?您还可以尝试为其他时间序列数据制作动画图,例如可视化加密货币的价格信息、空气质量指数等。请在评论中告诉我,您正在为哪些数据集创建动画图。
除了时间序列数据的动画图之外,您还可以尝试使用gganimate
R 包来增加其他数据可视化的趣味,并为其添加动画,比如盒图
订阅我的邮件列表,获取我在数据科学方面的最佳更新(偶尔还有免费内容)!
关于我
我是泰国一所研究型大学的生物信息学副教授和数据挖掘和生物医学信息学负责人。在我下班后的时间里,我是一名 YouTuber(又名数据教授)制作关于数据科学的在线视频。在我做的所有教程视频中,我也在 GitHub 上分享 Jupyter 笔记本(数据教授 GitHub page )。
https://www.youtube.com/dataprofessor
在社交网络上与我联系
YouTube:【http://YouTube . com/data proper/
网站:【http://data proper . org/【正在建设】
LinkedIn:【https://www . LinkedIn . com/company/data proper/
如何在 Synapse 无服务器 SQL 池之上创建 API
原文:https://towardsdatascience.com/how-to-create-apis-on-top-of-synapse-serverless-sql-pools-f09e087400ab?source=collection_archive---------11-----------------------
使用 Azure Synapse、ADLSgen2、Python 和 Web 应用程序
1.介绍
Synapse 无服务器 SQL pools 是一种在数据湖中查询数据的服务。关键是无需将数据复制到 SQL 表中就可以访问数据。通常,无服务器池不用于服务外部 API。这是因为外部 API 需要可预测的低延迟响应时间。像 Cosmos DB 和 SQL 数据库这样的服务更适合这种情况。但是,使用无服务器池为 API 提供服务的两个原因如下:
- 防止数据重复:不必将数据从数据湖复制到专门的 SQL 存储中。复制需要同步工作、保持血统和维护/保护更多资源
- 成本:专门的 SQL 存储,Cosmos DB 需要额外的成本
在这个 blogpost 和 git repo [azure-synapseserverless-python-rest-api](https://github.com/rebremer/azure-synapseserverless-python-rest-api)
中,在 Synapse serverless 之上创建了一个 Python REST API,另见下图:
1.高层建筑
这个项目是基于大卫·毛里所做的伟大工作,可以在这里找到。在这篇博文的剩余部分,将会更详细地解释 Synapse 无服务器 API 项目。在下一章中,项目将在本地部署。然后,项目将被部署在一个 web 应用程序中。
2.安装无服务器 SQL API 项目
在这一章中,项目开始运行,并将创建 ADFv2 单元测试项目。在这方面,需要做以下工作:
- 2.1 先决条件
- 2.2 配置 Synapse 和存储帐户
- 2.3 部署 SQL 脚本
- 2.4 在本地运行项目
2.1 先决条件
本教程需要以下资源:
- Azure Synapse 分析
- Azure CLI
- Python 3.7+
最后,将下面的 git repo 克隆到您的本地计算机上。如果你没有安装 git,你可以从网页上下载一个 zip 文件。
git clone [https://github.com/rebremer/azure-synapseserverless-python-rest-api](https://github.com/rebremer/azure-synapseserverless-python-rest-api)
2.2 配置 Synapse 和存储帐户
首先,确保 Azure AD 用户拥有访问Synapse 的权限。默认情况下,创建 Synapse 的用户是Synapse Adminstrator
,更细粒度的访问控制将在本博客的 3.2 中解释。
Synapse workspace 部署的一部分,也是 ADLSgen2 存储帐户的创建。这个存储附属于 Synapse,将作为这个博客中的数据湖。要使用存储帐户,1)需要将数据添加到文件系统中,2)用户需要拥有存储 blob 读取权限才能从存储帐户中读取数据。
- 转到 Synapse 的存储帐户,创建一个文件系统
taxidata
并添加 parquet 文件:data/part-...c000.snappy.parquet
- 然后为 Azure AD 用户授予对存储帐户的
Storage Blob Data Reader
权限,该用户也可以访问 Synapse,参见文档此处如何为存储完成此操作。
2.3 部署 SQL 脚本
转到 Azure Synapse 工作区,创建一个新文件夹,并从文件夹中的 gitrepo 导入以下文件:
- SQL/0 _ 创建 _ 数据库
- SQL/1 _ 创建 _ 外部 _ 表
- SQL/2 _ 创建 _ 存储 _ 过程
随后,在第 10 行的1_create_external_table.sql
中替换您的存储帐户名称。然后运行脚本,确保使用了内置的 SQL 环境。另请参见下面的截图。
2.3.1 部署 SQL 脚本
当脚本成功运行时,您可以找到一个包含表和存储过程的新数据库,参见下面的屏幕截图。
2.3.2 成功部署
2.4 在本地运行项目
确保您的计算机上安装了 Python 3.7 或更高版本。为了防止其他 Python 项目依赖关系之间的冲突,创建了一个虚拟环境。运行以下命令:
# 1\. Install virtual environment package
pip install virtualenv
# 2\. Create virtual environment
virtualenv blog-serverlessapi-sql --python C:\Python37\python.exe
# 3\. Activate virtual environment
.\blog-serverlessapi-sql\Scripts\activate
# 4\. Install project dependencies
pip install -r requirements.txt
从本地项目连接到 Synapse 无服务器池需要一个连接字符串。为此,使用存储在变量中的 Azure AD 身份创建一个临时不记名令牌。
运行以下脚本:
# Linux bash:export FLASK_ENV="development"
export SQLAZURECONNSTR_TAXI="DRIVER={ODBC Driver 17 for SQL Server};SERVER=<your-server-name>-ondemand.sql.azuresynapse.net;DATABASE=Blog-Serverless-API"
# Bearer token from user that has contributor rights on Azure Synapse workspace, can be generated using Azure CLI as follows
export TOKEN=$(az account get-access-token --resource=https://database.windows.net/ --query accessToken)# Windows PowerShell:$Env:FLASK_ENV="development"
$Env:SQLAZURECONNSTR_TAXI="DRIVER={ODBC Driver 17 for SQL Server};SERVER=<your-server-name>-ondemand.sql.azuresynapse.net;DATABASE=Blog-Serverless-API"
# Bearer token from user that has contributor rights on Azure Synapse workspace, can be generated using Azure CLI as follows
$Env:TOKEN=az account get-access-token --resource=https://database.windows.net/ --query accessToken
另请参见使用 Visual Studio 代码作为运行 Powershell 命令的开发环境的屏幕截图:
2.4.1 在 VSC 设置环境变量
最后,执行flask run
,然后启动一个本地 web 服务器,创建以下两个端点:
localhost:5000/taxidataall
运行所有滑行数据localhost:5000/taxidataprice/<<price amount>>
返回指定价格金额的所有出租车数据
另请参见下面的截图。
2.4.2 localhost 在几秒钟内返回 272 条价格为 10.00 的记录
3.将无服务器 SQL API 项目部署到 web 应用程序
在本章中,项目将被部署到一个 web 应用程序中。在这方面,需要做以下工作:
- 3.1 将代码部署到具有托管身份的 web 应用程序
- 3.2 为托管身份分配读者权限
3.1 将代码部署到具有托管身份的 web 应用程序
要将代码部署到具有托管身份的 web 应用程序,需要执行以下 CLI 命令。
# Windows PowerShell (bash is similar removing $ inset variable)# Set variables
$app="<<your app name>>"
$rg="<<your resource group>>"
$Env:SQLAZURECONNSTR_TAXI="DRIVER={ODBC Driver 17 for SQL Server};SERVER=<your-server-name>-ondemand.sql.azuresynapse.net;DATABASE=Blog-Serverless-API"# Deploy app and set config
az webapp up --sku B1 -n $app -g $rg
az webapp config connection-string set -g $rg -n $app --settings SQLAZURECONNSTR_TAXI=$Env:SQLAZURECONNSTR_TAXI --connection-string-type=SQLAzure
az webapp identity assign -g $rg -n $app
3.2 为托管身份分配读者权限
web 应用程序的托管身份,并向 Synapse 无服务器和底层存储帐户授予权限。
首先,授予受管身份Storage Blob Data Reader
对存储出租车数据的存储帐户的权限。功能应用程序的名称$appName
可用作应被授予权限的用户,参见文档此处如何为存储帐户授予权限。
最后,运行 web 应用程序受管身份还应具有从 Synapse 无服务器池读取数据并能够执行存储过程的权限。该代码存在于:sql/3_grant_WebApp_database_rights.sql
当所有步骤成功执行后,可以再次从浏览器中检索数据:
2.4.1 带有 MI 和基本 SKU 的 web 应用程序在几秒钟内返回 272 条价格为 10.00 的记录
最后,对 web 应用程序的访问可以通过 Azure AD 来保护。本[教程](http://Tutorial - Add authentication to a web app on Azure App Service - Azure App Service | Microsoft Docs)描述了如何在不使用定制代码的情况下为 web 应用程序进行配置。
4.结论
Synapse 无服务器 SQL pool 是一种在你的数据湖中查询数据的服务。关键是可以访问数据,而不需要先将数据复制到 SQL 表中。在 1)无法进行数据复制或 2)节省专用 SQL 存储成本的情况下,此选项可能很有意义。在这个 blogpost 和 git repo [azure-synapseserverless-python-rest-api](https://github.com/rebremer/azure-synapseserverless-python-rest-api)
中,在 Synapse serverless 之上创建了一个 Python REST API,另见下图:
4.高层建筑
如何创建漂亮且富有洞察力的图表
原文:https://towardsdatascience.com/how-to-create-beautiful-and-insightful-charts-e14a41c2cae0?source=collection_archive---------3-----------------------
学习如何将你的数据可视化技能提升到一个新的水平。
好吧,先说我背景的真相:我不是设计师,不是数据记者,也不是数据科学家。我是一名数据工程师,我的日常活动很少包括绘制图表或进行任何类型的分析。
但是即使没有丰富的经验,我还是连续三年赢得了由 Kaggle 发起的数据可视化比赛。我在 2018 和 2019 获得第三名,并在 2020 从 300 多名不同的参赛者中获得一等奖。在过去的三年里,我从这些比赛中赢得了总计 19,000 美元的奖金。
许多人每天都必须在工作中创建数据可视化,从数据和 BI 分析师到数据科学家、设计师和记者。而且图表常常无法传递它们应该传递的价值和洞察力。仅仅因为它们没有被很好地设计和建造。我识别好图表的经验法则是:
如果它需要解释,那么它就不是一个好的图表。
让我们来看两张展示相同数据的图表。你能说出哪个是好的吗?
图表 1: 回答 Kaggle 调查的男性和女性的百分比。来源:作者
图表 2: 另一个图表曝光同样的数据。来源:作者
你们大多数人都会同意图表 2 更好,不需要任何解释。现在,为什么大多数人一直在创造和传递像图表 1 这样的可视化?
- 第一个原因是创建有用的图表需要计划、时间和大量的工作。我花了 50 多个小时来完成我的提交,它只有 17 个图表——每个图表大约需要三个小时。
- 第二个原因是,虽然大多数人喜欢图表 2,但只有少数人能说出他们喜欢它的所有理由。
在这篇文章中,我想分享一些我在创作第二届 020 Kaggle 机器学习&数据科学调查竞赛中获得第一名的作品时的灵感和决定。我会给你一个全面的指导如何:
- 对你的分析有想法。
- 考虑你的听众和你将如何展示信息。
- 突出每个图表中隐藏的故事。
- 做出有意识的设计决策,关注细节。
我不会关注如何编写代码来创建图表的任何技术方面。使用不同的工具可以获得相同的结果,而且已经有大量的教程和全面的文档介绍如何使用大多数数据可视化库。
如果想深究技术方面,那就来看看剧情。我用它创建了我在这里展示的图表。Plotly 是一个 Python 库,提供了相当程度的交互性,我在网上发布图表时总是觉得很有趣。所有代码也可以在我的 Kaggle 笔记本上找到。
首先,一些背景。
这个卡格尔比赛是什么?
Kaggle 是数据科学家用来发布数据科学相关数据和代码的平台。每年年底,Kaggle 都会对其成员进行一次全行业调查,然后发布调查结果数据集。然后,他们举办了一场竞赛,要求社区成员创作带有数据可视化的笔记本。竞争对手必须讲述关于数据科学和机器学习社区子集的丰富故事。最佳作品有现金奖励。
我的获奖作品是关于什么的?
2020 年是第四次 Kaggle 调查,在我的提交材料中,我决定探索一段时间内的趋势。我创建了一个笔记本,讲述了数据科学社区多年来的发展历程,触及了性别薪酬差距、经验与薪酬以及数据科学新员工获得第一份工作的难度等主题。
尽管总共有 17 个不同的图,我在整个提交过程中只使用了一种图表类型:斜率图。
这张图表是我最喜欢的:
2020 年 Kaggle 竞赛获奖作品中我最喜欢的图表。它比较了多年来不同教育水平的男性和女性的平均年薪。来源:作者
这是我最喜欢的图表,因为它清楚地告诉我,有一些非常错误的事情正在发生。首先,2020 年,大多数教育水平的男女工资差距有所扩大。疫情可以部分解释 2020 年的急剧下降,例如,女性不得不离职或减少在家照顾孩子的时间。然而,这一差距在 2019 年也以惊人的趋势略有增加。
最糟糕的消息是,尽管学士和硕士学位的差距缩小了一点,但博士学位的差距又扩大了!我没想到会出现这种增长,我为所有女性感到遗憾,尽管她们尽了一切努力来获得最高学历,但仍然受到与男性不平等的待遇。
我是如何开始这个比赛的
我很晚才参加这个比赛,就在截止日期的前几天,主要是因为我没有主意了——并且稍微拖延了一下。我明白这是我们每个人都会遇到的事情。当我们被要求发挥创造力或做一些创新的事情时,我们会僵住。然而,我们可以做一些事情来找到好主意。
清楚明白自己需要做什么,为谁做。
这场比赛将由 Kaggle 团队进行评估,所以我认为他们希望看到他们的用户的一些很酷的东西。一些他们不知道的事情。所以在任何时候,我都把我的思想集中在他们想看到的东西上。
我的第一个想法是将来自 Medium data science 帖子的数据和调查结果结合起来。这有可能让我比较两组不同的数据,并得出一些结论。然后我意识到这是调查的第四年,可能是我们第一次看到一些趋势。如果我在 Kaggle 工作,我会很想看到这种比较。
我翻阅了已经出版的笔记本,看看是否有人已经在做这种分析。一些笔记本比较了年复一年的变化,它们很好地验证了我的假设,即有值得探索的趋势。
获得一些创作灵感。
我用几年前读过的 Cole Nussbaumer Knaflic 的数据重新开始了我的故事讲述。我很快又检查了一遍所有的东西。它帮助我记住了一些好故事的概念。看完这本书后,我决定用折线图或斜率图来突出时间的变化。
但我仍然不知道如何在绘制这些图表时有创意或创新。然后我又打开了几本书:【Alberto Cairo 的功能艺术和【David McCandless 的信息是美丽的。他们帮我有了一些线条和斜率图的设计思路。然而,仍然缺少一些东西。那么,是什么让我的作品如此出众呢?
我回顾了过去几年的笔记本,并从重新阅读 Teresa Kubacka 在她 2019 Kaggle 竞赛的获奖笔记本上所做的工作中获得了灵感。在那里,她创建了一个热图,并用单一类型的图表引导整个故事。这个矩阵帮助她识别出一些具有不同特征的用户群。
最后的灵感来自特蕾莎·库巴卡在 2019 年比赛中创作的这张热图。
作者: 特蕾莎·库巴卡 来源: 通过热图讲述的故事
看到这个笔记本是我的触发器:我可以为每个剖面创建一个包含多个斜率图表的矩阵。给所有图表增加一个额外的维度应该允许我随着时间的推移探索趋势,同时根据不同的社区特征将其分解。
我拿了一个画板,画了一些我的图表应该是什么样子的线。
我的图表应该是什么样子的第一想法画板。来源:作者
坐下来开始工作。
有了这个草图之后,我终于开始工作了。我只是在弄清楚以下情况后才开始处理和清理数据:
- 我要探索的
- 我会怎么做
- 目标受众是谁。
所以最后我坐下来开始工作。但我意识到,许多人在开始工作之前就陷入了无限循环。我自己也做过很多次。计划比执行需要更少的努力。在开始实际工作之前,我们通常希望有一个完美的想法。
事实是,如果你不坐下来开始工作,你将永远不会得到更多的想法或灵感。一旦我制作了第一张图表,并发现我可以得出一些很酷的结论,新的想法开始流动,我可以改进我以前所做的。
构建良好的数据可视化是一个迭代过程。不要一直等待完美的想法,因为它永远不会到来。从某件事开始。任何事。只是一个最小可行产品(MVP)。然后迭代改进。
贝娄是我建立的第一个图表,我的 MVP。
我的第一个 MVP,探索不同国家的性别参与。来源:作者。
减少认知负荷
我使用绘图软件的默认配置创建了这个 MVP。探索了一段时间后,我注意到一些国家的女性参与度正在提高。这就是我想传达给观众的故事。
我可以在上面的 MVP 图表下面写一段话,告诉你在印度、巴西和加拿大,女性的参与率是如何上升的,而在其他大多数国家,女性的参与率是如何下降的。令人惊讶的是,大多数人都是这么做的。他们希望观众花时间分析图表,找出结论的来源。
然而,如果我想想我的观众,他们不想花时间去理解一个图表。如果我的受众负责评估 300 多台笔记本,这一点尤其正确。
心理学上有个概念叫认知负荷;简而言之,就是你的大脑为了理解某些信息所需要的处理能力。如果负载过高,我们往往会放弃,去做其他事情,比如查看我们的 Instagram 通知。
当创建任何数据可视化时,把你自己放在你的观众的位置上。理解他们不想分析数据;他们只想看到结果。它必须容易理解。为了实现这一点,你需要减少认知负荷。
再看看我的 MVP 图表。它没有向任何人讲述印度、巴西和加拿大的故事。我下面将要描述的所有步骤都是为了减少认知负担,突出我的故事。遵循生成的图表:
最后一张图探索了不同国家的性别参与情况。来源作者。
为什么第二张图表比 MVP 好?
好吧,你可能不知道为什么最终的图表更好,但我在这里帮助你找出答案。让我们再看一遍 MVP,然后看看改进它的一些步骤。
我的第一个 MVP。来源:作者。
清除杂物
我做的第一件事总是导致最显著的差异:删除背景颜色和指导方针。这大大减轻了图表的负担。此外,我们不需要用盒子包围数据来理解它属于一个组。空白就可以了。
不要使用方框或背景色,而是使用空白来分组。
移除背景不会影响图表的理解,只要我们保留空白来分隔各组。我们不需要指南,因为我们的大脑非常善于追踪想象中的水平和垂直指南。来源:作者
接下来,我去除了所有线条的颜色,使它们变得更细。这也有助于消除大量的混乱。
通过使线条变细和变灰来消除杂乱。来源:作者。
突出故事
现在我已经清除了大部分的杂物,我准备好讲述这个故事,并给我想要突出的线条添加颜色。
突出我想谈论的国家。来源:作者
此时,要发现哪个国家是哪个国家,观众仍然需要将鼠标悬停在每一行上。这就增加了认知负荷。在边上有一个图例将会改进它,但是因为读者将不得不在图例和行之间来回移动,我决定直接添加带有国家名称的注释。
我为改进我的故事而添加的另一件事是 2018 年和 2020 年的百分比值标签。注意,我不是故意给 2019 加标签的,只会制造更多噪音,不会增加任何价值。
添加标签,让故事更容易理解。来源:作者
非常注意细节。
在这一点上,我已经减少了很多认知负荷。我突出了这个故事,观众可以在几秒钟内理解这个图表。看起来好像我已经完成了,但是还有很多需要改进的地方。让我们看看:
删除冗余信息。
我在标签上多次重复同样的信息。只出现一次就足以将一种线条/颜色与一个国家联系起来。x 轴也是重复的,移除它不会对解释造成任何损害。
将坐标轴置于背景并添加标题。
我不想把太多的注意力吸引到轴上。因此,我可以通过将颜色改为浅灰色来将它们置于背景中。我还为 y 轴添加了一个标签,并为值添加了适当的单位。
对齐元素。
将其他项目靠左对齐会比默认的居中对齐更好看,也更有条理。我把支线剧情的标题移到了左边,并且添加了关于支线剧情的注释。在这里是性别类别。
改进标题并添加来源。
最后,我改进了图表标题,添加了更多信息来帮助读者理解我的图表。添加源对于给出数据的上下文也非常重要。
在做了所有这些修改后,我得到了我的最终版本。
进一步降低认知负荷
这时,我已经准备好了我的第一张图表;然而,我仍然不得不创建一堆其他图表。当我开始的时候,我已经决定只用一种图表类型来减少认知负荷。让我解释一下:
- 我可以为每一次观想创建不同类型的图表。这样做可以显示出我的绘图技能是多样化的,并且我知道许多很酷的图表。这可能会让我的工作变得简单一点,因为我可以探索图表的优势来突出我的故事。然而,我的读者必须学会如何阅读每一种新的图表类型。这会增加认知负荷,让他们更难理解我的分析。
- 我可以只用一种图表类型进行所有的可视化。这样做可以让我的观众只需要学习一次如何阅读我的图表;他们可以通过笔记本在所有其他图表中重复使用这些知识。虽然这会减少认知负荷,但这会让我更难讲一个激动人心的故事。我的读者很快就会厌倦一遍又一遍地看同一个图表。
看看下面的内容,你不需要重新学习如何理解图表,即使它们显示的是完全不同的信息。
y 轴显示以美元为单位的年薪。每一行都是多年编写代码的经验,每一个次要情节都是不同的教育水平。来源:作者
y 轴显示的是专业受访者的百分比。每一行显示用于分析数据的主要工具,每一个子图是一个专业类别。来源:作者
寻找合适的故事
我绘制了几个变量的组合,直到我找到在我的最终提交中使用的变量。我通常从所有灰色线条开始,然后花一些时间在那里看到任何有趣的东西。一旦我找到一个故事,我就突出它。
同样的图表可能会有不同的故事。如果是这种情况,重复相同的图表,每次突出一个不同的故事,总比一个图表讲述多个故事要好。看一看:
故事 1:退伍军人为拥有成熟的机器学习模型的公司工作。
一个图表,一个故事。来源:作者
故事 2:新手为没有生产机器学习模型的公司工作。
同样的图表,不同的故事。来源:作者
当使用多个图表来讲述一个故事时,考虑文本的节奏和韵律来支持可视化。使用简单的语言,直奔主题。总是把上一个图表的故事和下一个图表的故事联系起来;否则,你的分析有可能成为大量不相关事实的集合。
你现在可以付诸实践。
每天我们都会接触到不同类型的数据可视化。有些我们喜欢,有些我们不喜欢。而喜欢或者不喜欢某样东西,通常是一个潜意识的过程。
如果你喜欢在某处看到的图表,花点时间去理解为什么你喜欢它。作者做了什么让你喜欢的事?
如果你看到一个你认为不好的观想,做同样的练习。为什么不好?有哪些可以改进的地方?
做这个练习将有助于建立一些自我意识。这样当你制作图表的时候,你就可以批评你的工作,判断它是好是坏。最糟糕的事情是当你没有自我意识,你认为你的观想是世界上最好的,但实际上,它们一点也不好。
创建漂亮而有洞察力的图表主要取决于你投入的时间和精力。这也是有意识的设计决策的结果——不幸的是,您的绘图软件的默认设置只允许您开始探索。总是考虑你的观众,并遵循我在这里描述的一些技巧。我确信你很快就会像专家一样创造观想。
如何用 Python 创建漂亮的单词云
原文:https://towardsdatascience.com/how-to-create-beautiful-word-clouds-in-python-cfcf85141214?source=collection_archive---------3-----------------------
为下一个 NLP 项目创建令人惊叹的可视化效果的指南
文字云作者| 特莱维喷泉图片由李中清通过 Unsplash
自然语言处理(NLP)是目前数据科学中非常受欢迎的子领域,因为它允许计算机处理和分析人类语言。Siri 和 Alexa、垃圾邮件过滤器、聊天机器人、自动完成和翻译应用都是使用 NLP 的日常技术的例子。
作为一名数据科学家,处理文本数据比处理其他类型的数据要复杂一些。为什么?因为文字不是数字!这使得探索性数据分析以及数据清理和预处理步骤在数据科学工作流中有所不同。文本数据通常需要更多的清理(删除停用词和标点、小写、词干或词汇化等)。它还需要对文本进行符号化或矢量化(从单词中获得有意义的数字)。至于探索和分析数据,可视化文本的方法就没那么多了。然而,文字确实开启了一种新的可视化技术,你可能以前见过——文字云。
在我最近的数据科学项目中,我深入研究了 NLP 的世界。在这个过程中,我学到了用 Python 创建单词云的所有知识,我想写这篇文章来与那些希望为文本数据创建一些漂亮的可视化效果的人分享我的知识。
创建一个基本的单词云
要创建一个基本的单词云(或 Python 中的任何单词云),您将需要以下库:
方法 1:从文本生成
构建词云主要有两种方式。第一种也是最简单的方法是从文本语料库中创建单词云,比如一篇文章、一本书等。这个语料库应该是字符串的形式。
在下面的例子中,我列出了罗马市猫途鹰的景点。我会将它们全部组合成一个文本体(一个语料库),然后创建一个基本的词云。
猫途鹰罗马景点示例|作者图片
在我对吸引人的文字进行分组之前,我做了一点清理,用小写字母,删除了基本的停用词(如“a”、“the”、“is”等),并进行词汇化。我对 12 个城市做了同样的事情(具体来说,是 2021 年世界顶级目的地中的 12 个)。罗马的分组语料库在下面的数据框架中突出显示。
每个城市的分组、清理和旅游景点|按作者分类的图片
正如我之前提到的,我们将从罗马的文本语料库中创建单词 cloud。为此,我们将通过对该分组数据帧进行切片来分离出一个语料库:
罗马文本文集|作者图片
从这里,我们可以创建基本的单词云。我们将从实例化 WordCloud 库中的 wordcloud 对象开始,并使用 generate_from_text 方法向它提供我们的文本语料库。最后,我们将使用 plt.imshow()来显示 WordCloud 对象。一定要使用 plt.axis('off '),以确保它只显示单词 cloud,而不显示轴及其值。
生成的字云如下。我们可以看到,在默认情况下,词云使用的是双词(成对的词),而不是单个词。如果需要,我们可以在实例化 WordCloud 对象时通过更改参数“collocations=False”来关闭它。
基本罗马字云(来自文字)|作者图片
方法 2:从频率中生成
第二种方法是从文档术语矩阵创建单词云。这是 NLP 的一个常用矩阵,语料库词汇表中的每个单词都有一个单独的列,每行都有词频。例如,下面我描述了我之前展示的 12 个城市的文档术语矩阵(dtm)的前几列。请注意,dtm 的尺寸为 12 x 8676,表示 12 个城市,以及整个语料库词汇中的 8,676 个单词。
使用计数矢量化的文档术语矩阵,也称为 dtm |作者图像
如果您有一个文档术语矩阵,我们可以使用。generate _ from _ frequencies()方法。首先,我们需要分离出要用于罗马的数据。我们将需要转置这个矩阵,使其成为单词 cloud 的正确格式。我们还想获得最常用的单词,所以我们将按降序排列这些值。你可以在下面的照片中看到我们想要使用的数据示例。
作者图片
为了实际创建单词云,我们将使用与上面几乎相同的代码,但是使用 generate _ from _ frequencies 方法。
生成的字云如下。请注意,因为我们在数据中分离了单个单词(而不是双字),所以我们不需要告诉 WordCloud 对象关闭“搭配”参数。它自动将矢量化的单词作为单个单词,而不是两个单词。
基本罗马单词云(来自频率)|作者图片
最后,既然我们已经了解了这些词云是如何形成的,我们可以操纵一些参数来创建一个更好的基本词云版本。让我们回到我们的第一个例子,使用 rome_corpus 变量(从文本生成单词云)。请注意,像“私人旅游”和“skiptheline”这样的词是出现频率最高的词。我们可以告诉我们的词云一个自定义的停用词列表来消除这些。我还将定制单词云的尺寸,并使用 figsize 参数使整个图形变大。我们改变颜色图,并添加一个标题。在下面的函数中可以看到所有这些变化。
请记住,您可以随时更改上面的函数来使用 generate _ from _ frequencies 方法!生成的单词云将如下所示:
最终基本单词云|作者图片
哇!看起来好多了。虽然这仍然是非常基本的。让我们把它提高一个档次,用遮罩改变单词云的形状。
更改单词云形状
让你的文字云在视觉上惊艳的一个方法就是加个遮罩。遮罩是一种图像,您可以使用它来改变您的单词云的形状。当我们实例化 WordCloud 对象时,我们可以很容易地使用 mask 参数来操作 mask。
一旦你为你的蒙版选择了完美的图像并保存它(一分钟后会有更多),我们可以使用 PIL 图书馆和 numpy 的图像功能将它转换成 WordCloud 对象的正确格式。
现在我们的掩码格式正确了,我们可以编写一个类似的函数来生成更好的单词云。以下函数与我们最终的基本单词云函数非常相似,但有一些例外:
- 使用遮罩参数会使宽度和高度参数无效,因为它将采用图像本身的大小
- 我使用的“标度”是 3,这使得对于更大的单词云图像的计算更快
- 我把“色彩图”改成了“RdYlGn ”,因为它感觉更像意大利(想想意大利国旗,还有自制的意大利面!)
- “背景颜色”现在是“白色”,在色彩图上看起来更好
- 这次将显示搭配(二元语法),因为我们使用 generate_from_text 方法,搭配参数设置为“True”
我们最后的字云在下面…不是belli Sima吗?!
最终罗马字云|作者图片
选择完美的面具
使用遮罩最棘手的部分是,您选择的图像必须满足以下要求:
- 白色背景(必须是#ffffff,不能是灰白色或透明的)
- 不是白色的最终形状
这是一个不太管用的面具的例子。这里的问题是它的形状不够明确,你无法说出它是什么。
斗兽场图片由熊猫矢量通过 Shutterstock |文字云作者
因此,你要选择一个非常容易辨认的形状,就像下面的例子。
意大利地图图片由 David Petrik 通过 Shutterstock |文字云作者
甚至有时你会找到最适合你面具的照片,但它的背景中有几个标志会使单词 cloud shape 失去意义。为了解决这个问题,你可以在 Photoshop 中打开照片,然后去掉标记。如果你没有 Photoshop,你可以用一种方法来破解它(从我做市场营销的时候开始),那就是 Canva 。您可以将蒙版图像上传到 Canva,在您的标记上放置白色方块,然后下载编辑后的图像。瞧啊。你面具就可以和#ffffff 背景搭配了。
额外的收尾工作
让你的文字云变得美丽的最后一步是用你自己敏锐的眼睛去发现那些美学上的小细节。改变颜色,使用边框(又名轮廓),操纵字体和绘图大小只是定制你的单词云的几种方法。以下是自定义这些参数的一些方法:
更改色彩映射表
更改单词的颜色就像在 WordCloud 对象实例化中更改“colormap”参数一样简单。点击查看所有 matplotlib 颜色图选项。
还有一种方法可以根据蒙版图像中的颜色创建自己的色彩映射表。为此,请使用 wordcloud 库中的 ImageColorGenerator 函数,并在实例化 WordCloud 对象时使用 color_func 参数中生成的颜色。color_func 参数将覆盖 colormap 参数。
在这里,我再次使用了罗马圆形大剧场,因为意大利地图都是一种颜色。使用这种自定义的色彩映射表绝对是一个不错的选择,即使我们仍然不能真正说出它的形状!
作者图片
使用轮廓
不像卡戴珊姐妹…但也算是吧。Contour 给你的字云遮罩一个轮廓。可以在用 contour_color 和 contour_width 参数实例化 WordCloud 对象时对其进行自定义。轮廓颜色可以用字符串表示(使用简单的颜色词或颜色代码)。
下面是我们生成单词云的相同函数的一个例子,但是有一个细的黑色轮廓(宽度为 1)。
如您所见,由于轮廓的原因,生成的单词云是一个更容易区分的形状。
作者图片
看起来很酷!由于意大利的详细形状,这里的轮廓有点弯曲。使用更基本的遮罩形状,轮廓线会更平滑。
我们也可以尝试一个彩色的轮廓来使它看起来更好。由于字云中有暗红色的字,我找了一个好看的酒红色色码,#5d0f24,来代替黑色轮廓,宽度增加到 3。
生成的字云如下。
作者图片
甚至以前的竞技场面具在这里稍微修饰一下看起来更好!在这种情况下,轮廓有助于我们看到面具的实际形状。
作者图片
是否放置轮廓,以及轮廓的颜色和宽度由您决定,这取决于您想要在单词云中包含的美学细节。
关于词云大小的一个注记
你应该经常做的一件事是用 plt.figure(figsize=(10,8))改变单词云的大小。你可以把它改变成你需要的任何大小,但是我发现改变整个情节的大小比试图调整 WordCloud 对象本身的大小效果更好。我已经在所有的词云函数中包含了这一点,当我们从基本的词云跳到用函数创建的词云时,你可以注意到词云大小的差异。
更多有趣的定制!
当谈到定制你的单词云时,可能性是无穷无尽的。以下是一些例子:
- 使用 font_path 参数操作单词云文本的字体
- 更改最小和最大字体大小(最小字体大小、最大字体大小参数)
- 更改单词云的背景颜色
- 减少 max_words 参数以仅显示前 20 或 50 个单词,这有时会使单词云更容易阅读
所有这些小细节都会影响你的单词云可视化。由于每个遮罩和每个文本语料库看起来都不一样,所以最终还是要靠你自己来摆弄它们,让你的单词云看起来更漂亮!
结论
感谢你跟随我踏上罗马之旅!我希望这个故事教会了你一两件关于单词云和创建漂亮的 NLP 可视化的事情。如果你有更多的建议,我很乐意在下面的评论中听到!
注意:这只是我的数据科学顶点项目的一小部分,在这个项目中,我使用 NLP 对不同城市的文本进行分类。你可以在我的 Github 账户上看到完整的项目回购。
如何使用 Altair 创建多个图之间的绑定和条件
原文:https://towardsdatascience.com/how-to-create-bindings-and-conditions-between-multiple-plots-using-altair-4e4fe907de37?source=collection_archive---------16-----------------------
使用绘图绑定从不同角度理解数据
动机
你有没有像下面这样和另一个剧情互动的时候,希望看到一个剧情发生变化?这就是牛郎星派上用场的时候。
作者 GIF
上图是用 Altair 创建的。如果你不了解 Altair, Altair 是一个基于 Vega 和 Vega-Lite 的 Python 统计可视化库。在我的上一篇文章中,我展示了 Altair 如何允许您使用简洁的可视化语法来快速构建统计图形。
在本文中,我将展示如何使用 Altair 在多个图之间创建绑定和条件。
开始
要安装 Altair,请键入:
pip install altair
我们将使用 Altair 来研究从 Kaggle 上发布的学生考试成绩数据下载的 CSV 文件。
酷!现在我们有了数据,让我们用 Altair 可视化它。
使用间隔选择来过滤条形图
创建间隔选择
我们将创建一个使用区间选择来过滤条形图内容的图表。首先创建一个散点图,它允许我们通过单击和拖动来选择特定的时间间隔。
尝试单击并拖动上面的图表。您应该只看到所选区域内的点的颜色被突出显示!
产生上面输出的代码:
解释:
brush = alt.selection(type="interval")
:创建区间选择对象encode
:指定 x 轴和 y 轴显示的列color=alt.condition(brush, “gender:N”, alt.value(“lightgray”)
:如果点在选择的区间内,用gender
给这些点着色,否则用lightgray
给这些点着色。tooltip
:悬停在某点上时显示的信息add_selection(brush)
:将区间选择应用于图表Q
指定定量(数值数据),N
指定名义(分类数据)
如果你想了解更多关于 Altair 的基本语法,请参考本文。
使条形图响应间隔选择
现在我们已经创建了区间选择,让我们将它连接到另一个条形图。
尝试单击并拖动散点图。当选择不同的间隔时,您应该会看到条形图的分布发生变化!
产生上面这个情节的代码:
解释:
x="count(parental_level_of_education):Q"
:对parental_level_of_education
栏中每个值的计数。color=alt.Color(“parental_level_of_education:N”)
:根据parental_level_of_education
给条形应用颜色transform_filter(brush)
:根据选择的间隔过滤数据
我还可以用牛郎星做什么?
使用 Altair 的绑定功能,您可以做许多很酷的事情来使您的情节更加清晰,例如:
放大直方图
有时,您可能希望放大直方图,以获得直方图的更细粒度视图。这可以用 Altair 来完成。
作者 GIF
你可以在这里自己摆弄图表:
创建上述地块的代码:
仅显示直方图中突出显示的点
您可能还希望通过查看哪些点落在直方图的选定区间来理解直方图。牛郎星也可以做到这一点:
作者 GIF
你可以在这里自己摆弄图表:
创建上述地块的代码:
基于下拉栏和单选按钮过滤数据点
您也可以使用 Altair 将多个过滤器应用到您的数据点,如下所示:
作者 GIF
你可以在这里玩剧情:
上图的代码:
希望上面的代码没有吓到你!上面的许多代码行显示了我们在第一部分已经学到的内容。一些之前没有提到的新牛郎星天体:
alt.selection_single
:允许用户一次只选择一个选项alt.binding_select
:创建下拉栏alt.binding_radio
:创建一个单选按钮
结论
恭喜你!您刚刚学习了如何使用 Altair 绑定多个情节!能够在多个图之间建立联系将使您的数据分析更加清晰。另外,你也可以用这些情节打动你的观众!
随意发挥,并在这里叉这篇文章的源代码:
https://github.com/khuyentran1401/Data-science/blob/master/visualization/altair/altair_advanced.ipynb
我喜欢写一些基本的数据科学概念,并尝试不同的算法和数据科学工具。你可以在 LinkedIn 和 Twitter 上与我联系。
如果你想查看我写的所有文章的代码,请点击这里。在 Medium 上关注我,了解我的最新数据科学文章,例如:
如何创建自定义 scikit-学习分类和回归模型
原文:https://towardsdatascience.com/how-to-create-custom-scikit-learn-classification-and-regression-models-70db7e76addd?source=collection_archive---------21-----------------------
让-菲利普·德尔伯格在 Unsplash 上的照片
Scikit learn 是 Python 中标准机器学习模型的首选包。它不仅提供了您在实践中想要使用的大多数核心算法(即 GBMs、随机森林、逻辑/线性回归),而且还提供了用于特征预处理的各种转换(例如 Onehot 编码、标签编码)以及用于跟踪模型性能的度量和其他便利功能。但是,仍然会有你需要做一些稍微不同的事情的时候。在这些情况下,我经常仍然希望在 scikit learn 的通用 API 内工作。坚持使用 scikit learn API 有两个主要好处:
- 您可以与其他数据科学家共享您的模型,他们可能知道如何使用它,而无需您提供重要的文档。
- 您可以在包含其他 scikit-learn 操作的管道中使用它——至少对我来说,这是主要的好处。
幸运的是,实现定制模型非常简单,因此它可以像标准的 scikit-learn 模型一样工作。
实现自定义模型🚀
在 scikit-learn API 中实现定制模型可以使用下面的框架类来完成——一个用于分类,一个用于回归。基本上,您想做的任何事情都可以添加到init
、fit
、predict
和predict_proba
(用于分类器)方法中。通过继承BaseEstimator
、ClassifierMixin/RegressorMixin
,该类将与其他 scikit-learn 类具有互操作性,并且可以在 scikit-learn 管道中使用。
在这篇帖子中,你可以看到我是如何在实践中使用这个结构来定义定制的 scikit-learn 模型的。例如,下面的模型创建了一个树空间逻辑回归分类器:
在这种情况下,我将几个 scikit-learn 模型包装在一起。您可以看到,fit
方法将在输入上拟合一个GradientBoostedClassifier
,使用这个拟合的模型来转换输入,一个热编码这个转换,然后在输出上拟合一个LogisticRegression
。将它包装在一个单独的定制模型中比单独定义这些步骤要整洁得多。
感谢您的阅读——希望这对您有所帮助。
如何用一行代码在 Python 中创建数据可视化
原文:https://towardsdatascience.com/how-to-create-data-visualizations-in-python-with-one-line-of-code-8cda1044fe69?source=collection_archive---------8-----------------------
大蟒
了解如何使用 QuickDA 通过一行代码创建数据可视化
照片由安德烈斯·艾尔顿从佩克斯拍摄
大家都听说过一句话一张 图片胜过千言万语。这句话之所以如此广为人知,是因为它是真的。有些东西只有我们的眼睛才能捕捉到。这就是为什么数据可视化对于任何项目或报告都是必不可少的一步。一个不熟悉数据集的人可以很容易地让我们了解它。但是,创建数据可视化可能很耗时,有时,您可能想快速浏览一下数据集。幸运的是,我们有 QuickDA,一个可以解决这个问题的库。
我曾经写过如何使用 QuickDA 高效地执行探索性数据分析,结果非常好。请查看博客节省时间使用这个库的几行代码完成一个完整的 EDA,以获得更多关于使用它进行 EDA 的信息。你不会失望的。现在让我们看看如何使用 QuickDA 来创建第一个可视化。
装置
要安装 QuickDA,请转到您的终端并粘贴pip install quickda
。就这么简单。您现在可以使用它了。你可以在我的 GitHub 上找到我用于 QuickDA 的笔记本。
现在让我们导入我们需要的所有东西。
**# Importing libraries**
from quickda.explore_data import *
from quickda.clean_data import *
from quickda.explore_numeric import *
from quickda.explore_categoric import *
from quickda.explore_numeric_categoric import *
from quickda.explore_time_series import *
为数字特征创建可视化效果
正如我在标题中提到的,您可以用一行代码创建可视化,我将向您证明这一点。有几种方法可以做到这一点,我们将逐一检查。第一个是为数字数据创建多种可视化。代码如下:
eda_num(**data**)
作者图片
瞧。如你所见,用一行代码,我创建了多个数据可视化。QuickDA 为每个要素创建箱线图和直方图。这再容易不过了。缺点是有时我们不知道为每个特性开发什么样的可视化。通常,只有一两个数据可视化可以完成这项工作。幸运的是,QuickDA 能够使用以下代码为选定的数据创建可视化效果:
eda_num(**data**[['**column_1**', '**columns_2**', '**column_n**']])
作者图片
因为 QuickDA 不能解释熊猫系列,所以使用双括号是很重要的。
相关矩阵
需要相关矩阵?没问题。您可以输入以下代码并检查要素的相关性。
eda_num(**data**, method="**correlation**")
作者图片
我不喜欢 QuickDA 的相关矩阵的风格,但它确实有用。我们可以很容易地看到哪些特征是高度相关的红色。轻松微风!
为分类要素创建可视化效果
现在,让我们看看如何为分类特征创建一些可视化效果。对于这一个,你需要选择你想要研究的特征。
eda_cat(**data**, x='**column_name**')
作者图片
我们可以看到,QuickDA 为 purpose 特性创建了一个漂亮的可视化效果,显示了每个值的计数和一个带有数字描述的表格。很酷,对吧?现在,假设您想要查看每个性别的数据分布情况。你也可以这样做,只需增加一个 y 值。
eda_cat(**data**, x='**column_name**', y='**column_name**')
作者图片
特征重要性
QuickDA 可以做的另一件很酷的事情是,我们可以快速获得特征的重要性,以及这些特征如何预测特定的目标。这对机器学习来说很方便,它会帮助你消除不相关的特征。
eda_numcat(**data**, method='pps', x='**target_feature**')
作者图片
相互关系
QuickDA 可以轻松地创建关联可视化。通常,使用 Matplotlib 可以很容易地创建关联可视化,但是如果有其他的方法也很好。
eda_numcat(**data**, x='**x_value**', y='**y_value**',
hue='**color_setup**', method='**relationship**')
作者图片
时间序列
时间序列可视化也可以很容易地完成。有趣的是,QuickDA 使用不同的可视化库,如 Matplotlib、Seaborn 和 Plotly Express。例如,对于时间序列,使用 Plotly Express。我不确定原因,但我相信他们会根据自己的目标选择最好看的可视化效果。
作者图片
数据透视表
最后但并非最不重要的是,QuickDA 有一个很酷的特性,它不完全是数据可视化,但它非常酷。这使得轻松创建数据透视表成为可能。如果您一直在工作或学习数据分析,您已经知道数据透视表的重要性。现在,你可以有一个在你的管道。
eda_numcat(**data**, x=['**column_1**, **column_2**'], y=**None**, method=**'pivot'**)
作者图片
结论
QuickDA 太酷了,我不得不写了两篇博客来介绍我们可以用它做的一些很酷的事情。我们可以做的还有很多,我强烈建议您用您的数据集来尝试一下,我相信您会看到 QuickDA 有多么强大。你可以在这个博客和这个笔记本中找到更多的代码。
享受它,让我知道你在使用 QuickDA 时还发现了什么。编码快乐!
如何用 Python 一键创建数据可视化
原文:https://towardsdatascience.com/how-to-create-data-visualizations-on-python-with-one-click-f6bafbd8de54?source=collection_archive---------7-----------------------
大蟒
了解在您的下一个数据科学项目中应该如何以及为什么使用 Lux 库
图片由戴安娜·马頔拍摄。来源: Unsplash
你刚刚开始你的新数据科学项目。您快速浏览了数据集,现在是进行一些探索性数据分析的时候了。你需要创造一些形象化的东西,并弄清楚你想要发现什么。您可能开始使用 Matplotlib 和 Seaborn 编写代码,这两个库很棒,但是非常耗时。如果我告诉你,你可以跳过这些步骤,用一行代码创建可视化效果,那会怎么样?这就是莱克丝的目标。
你不相信吗?让我给你演示一下,然后我们可以深入了解一下。在这里,我将为全球疫苗接种进度数据集创建可视化效果:
深信不疑?那就说说吧。Lux 是一个出色的 Python API,它通过自动化数据可视化来简化数据科学项目。对于那些你不知道你在找什么的项目来说,这是很方便的。即使你知道自己在寻找什么,Lux 也可以帮助你深入了解自己的特征,这样你就可以专注于用大脑解决更复杂的问题。到本文结束时,您将能够在您的下一个项目中使用 Lux。我在 GitHub 上创建了一个库,其中的代码用于演示目的。你可以在这里找到它:
安装
安装 Lux 和使用它一样简单。只需在您的终端上输入 pip install lux-api,您就可以开始工作了。现在,您需要激活 Jupyter 笔记本的扩展。您可以在 Jupyter 笔记本上键入以下内容:
!jupyter nbextension install — py luxwidget
!jupyter nbextension enable — py luxwidget
你已经准备好了。现在,让我们学习如何使用它。首先,我们把pandas
和lux
导入笔记本,停用那些烦人的警告。
# Import libraries
import pandas as pd
import lux# Hide warnings
import warnings
warnings.filterwarnings(“ignore”)
使用 Lux 创建可视化效果
现在,让我们导入数据集。你可以在 Kaggle 上或者我在 GitHub 上的存储库中找到数据集。
# Import dataset
df = pd.read_csv('data/country_vaccinations 2.csv')
从现在开始,如果你输入df
,你会在单元格下看到一个新按钮。你可以点击它,开始看到你的第一个数据可视化:
作者图片
相当容易。你可以在这里看到一些图像。根据您的数据集,它们被组织在一些类别中。在这种情况下,我们可以看到相关、分布、发生和时间。下面,你可以看到我点击了时态数据,我们可以看到一个时间序列可视化。
您也可以使用df.intent = ['column_1', 'column_2']
来比较特征。这是莱克丝开始展示其潜力的地方。让我们更深入地探讨一下这个选项:
作者图片
在这种情况下,我将比较列country
和total_vaccinations
。Lux 编辑列并根据我们拥有的数据集创建新的特征。例如,我们可以在下面看到 Lux 创建了一个显示一周中每天疫苗接种量的可视化。
作者图片
太棒了,你刚刚发现了一个你有兴趣探索更多的可视化。您可以单击图像,并将图像导出到名为 exported 的变量中。你可以在下面看到一个例子。您可以看到 Lux 包含了用于 X 和 Y 变量的内容。
您可以将可视化保存到另一个变量中,并在需要时随时访问它。Lux 的另一个非常酷的事情是,你可以将文件导出为 HTML 文件,并与其他人共享,而不必共享数据集或 Jupyter 笔记本。多酷啊。
还可以使用df.recommendation['Enhance']
来了解 Lux 对每个变量使用了哪些变量。您可以使用Matplotlib
和Seaborn
创建可视化效果。另一件很酷的事情是,你可以像处理 Python 列表一样,将可视化分割开来,专注于你最喜欢的可视化。
这一切都很好,但是如果您想为演示文稿或报告编辑其中一个可视化效果,该怎么办呢?那也很容易。我们需要将可视化变量添加到df.intent
并键入print(vis.to_Altair())
,并将代码复制并粘贴到另一个单元格中。现在,您可以进行自己的编辑。记住 Lux 使用的是Altair
库。一旦你有了代码,这是非常简单的。我学会了如何使用Shift + Tab
进行一些基本的编辑,找到可以编辑字段的地方。然后,您可以导出 JPG PNG 格式的可视化内容,甚至可以查看 JSON 代码。
这是最终的结果:
结论
Lux 是一个易于使用的 API,可以在项目开始时为您节省一些时间。它可以让您深入了解数据集,并决定您应该对您的项目做出什么决定。Matplotlib 和 Seaborn 仍然是可靠的工具,我不认为 Lux 能够很快取代它们。但是,您可以将 Lux 添加到您的 EDA 流程中,并确保您考虑了数据集的每个关键方面。你也可以查看他们的文档这里了解更多信息。
感谢您的阅读,如果您有任何问题,请告诉我。
如何创建可解释的、实际上有意义的人工智能规则
原文:https://towardsdatascience.com/how-to-create-explainable-ai-regulations-that-actually-make-sense-8e6f35866bd8?source=collection_archive---------24-----------------------
播客
吉莉安·哈德菲尔德谈正当人工智能和人工智能监管的未来
苹果 | 谷歌 | SPOTIFY | 其他
编者按:TDS 播客由 Jeremie Harris 主持,他是数据科学导师初创公司 SharpestMinds 的联合创始人。每周,Jeremie 都会与该领域前沿的研究人员和商业领袖聊天,以解开围绕数据科学、机器学习和人工智能的最紧迫问题。
众所周知,世界各国政府都在努力制定有效的政策来应对人工智能带来的风险和机遇。发生这种情况的原因有很多:许多人——包括技术人员——认为他们了解前沿人工智能的样子,但很少人真正了解,更少人有兴趣将他们的理解应用到政府环境中,那里的工资很低,甚至不存在股票补偿。
因此,有一个关键的政策-技术差距需要弥合,无法解决这一差距实际上不是一个选项:这将意味着盲目地通过世界上有史以来面临的最重要的技术治理测试。不幸的是,政策制定者不得不在这一危险的知识缺口存在的情况下推进监管和立法,结果并不理想:广受批评的隐私和可解释性定义,以及创造可利用漏洞的人工智能定义是一些更令人担忧的结果。
吉莉安·哈德菲尔德是一位法学教授、战略管理教授,也是施瓦茨赖斯曼技术与社会研究所所长。Gillian 的背景是法律和经济学,这使她关注人工智能政策,以及最近和正在出现的人工智能和隐私法规的定义问题。但是——正如我在播客中发现的——她碰巧也是戴尔兰·哈德菲尔德-梅内尔的亲戚,她是一名人工智能比对研究员,我们在之前已经在节目中见过她。部分通过 Dyllan,Gillian 也一直在探索人工智能校准研究的原则如何应用于人工智能政策和合同法。在本期播客中,吉莉安和我一起谈论所有这些以及更多。
以下是我在对话中最喜欢的一些观点:
- Gillian 认为,监管者认为的“解释”和技术人工智能社区成员构想的“解释”之间存在语言脱节。当被要求“请解释为什么这个人工智能拒绝了我的银行贷款”时,技术专家可能会提供一个简化的答案,这与人工智能算法中的活动有关,该算法产生了正在被询问的输出。这听起来可能有点像,“你被拒绝银行贷款,因为神经元#381 被解雇,而神经元#17 没有。”虽然有些更直观的“解释”是可能的,但它们通常都具有这种定量分析的性质。但这不是监管者所说的“解释”,也不是我们期望从法律机构和法官那里得到的那种解释。相反,监管者想要但往往不知道如何要求的解释听起来像是“你被拒绝银行贷款,因为你以前的行为模式表明,到时候你不能依靠你偿还债务。”吉莉安认为,这种答案不应该被视为一种解释,而是一种正当理由,她主张将重点转向“合理的人工智能”而不是“可解释的人工智能”,以反映监管者真正追求的是什么。
- 我们在播客中讨论了古德哈特定律:任何指标一旦成为优化的目标(并被“指标黑掉”),就不再是有效的指标。Gillian 应用这一原则指出,你永远无法使任何合同、协议或政策如此完整,以至于涵盖所有可能的意外情况:不管怎样,古德哈特定律保证合同会有可被利用的漏洞。鉴于这种限制,Gillian 有兴趣寻找设计最优不完全契约的方法:不假装漏洞百出,但最大限度地减少其频率和影响的契约。
- 吉莉安指出,我们不应该指望能够以传统方式立法解决人工智能问题。鉴于人工智能发展的速度,法律在通过时往往已经过时。私营部门的行动要快得多,需要被用来协助政府监管人工智能,政府需要鼓励它这样做。这就是吉利恩所谓的“人工智能监管市场”背后的理念——一个由政府设定安全指标(例如,“无人驾驶汽车每行驶 Y 英里造成的碰撞少于 X 次”)并推动整个经济部门在这些目标上竞争的系统。吉利恩认为,随着私营公司建立旨在检查其他人工智能的偏见和其他不良特征的人工智能,我们已经看到了这种动态的种子。
- Gillian 认识到在政府中招聘技术人工智能专家的挑战,但她也指出,大多数人工智能监管问题可以通过教育政策制定者掌握人工智能的基础知识来解决,而不是雇佣昂贵的开发人员在政府中工作(他们的技能可能得不到充分利用)。因此,政府教育需要成为人工智能全面监管工作的关键组成部分。
你可以点击这里在 Twitter 上关注阿娇。
链接
- 施瓦茨赖斯曼技术与社会研究所网站
- 阿娇的网站,上面有她的论文和项目(包括她在未完成合同上的工作)
章节:
- 0:00 介绍
- 1:35 阿娇的背景
- 8:44 层和政府立法
- 13:45 解释和理由
- 17:30 可解释的人类
- 24:40 古德哈特定律
- 29:10 引入人工智能校准
- GDPR 时间 38 点
- 42:00 涉及技术人员
- 49:20 总结
如何在 python 中使用大量数据创建快速准确的散点图
原文:https://towardsdatascience.com/how-to-create-fast-and-accurate-scatter-plots-with-lots-of-data-in-python-a1d3f578e551?source=collection_archive---------4-----------------------
提示和技巧
无需反复试验,在数毫秒内创建包含数亿个样本的散点图。
散点图是非常基本且容易创建的——至少我是这样认为的。最近,我不得不可视化一个有数亿个数据点的数据集。如果你是 Python 开发者,你会立即导入matplotlib
并开始。但事实证明,有更好、更快、更直观的方法来创建散点图。
matplotlib
有什么问题?嗯,matplotlib
是一个很棒的 Python 库,绝对是数据科学必读的一部分。但是matplotlib
也是一个巨大的多面手,在某些情况下可能表现欠佳。这是其中之一。
假设我们有一个数组X
,它的形状是(1_000_000, 2)
。每列代表一个轴。所以,任何一行都是坐标。
import matplotlib.pylot as pltplt.scatter(X[:, 0], X[:, 1])
plt.show()
用 matplotlib 创建的散点图。运行时间含保存:6.4s. 图片作者。
这就产生了一个散点图,但我们不知道点是否重叠,也不知道一个区域的强度。我们可以通过设置s
和alpha
参数来解决这个问题。第一个参数控制每个点的大小,后者赋予它不透明度。我们想要大小和不透明度,让我们能够区分不同的点。这就是试错的开始。随着数据量的增加,这个过程会变得越来越痛苦。
import matplotlib.pylot as pltplt.scatter(X[:, 0], X[:, 1], s=1, alpha=0.1)
plt.show()
用 matplotlib 创建的散点图。左上:alpha = 0.1 右上:s = 0.1 alpha = 0.1 左下:s = 1 alpha = 0.1 右下:s=1。运行时间含保存:7.29s,1.15s,1.45s,1.39s图片作者。
datashader —解决方案?
datashader
是一个可视化大型数据集的优秀库。主要的改进来自光栅化过程:matplotlib
将为每个数据点创建一个圆,然后,当你显示数据时,它将必须计算出每个点在画布上占据的像素。通常,每个点将占据多个像素。相反,datashader
会把你的 2D 空间分成width
水平仓和height
垂直仓。然后,它只检查每个样本占用哪个箱。如果这个过程对你来说听起来很熟悉,那是因为这就是你创建直方图的方式。在这种情况下,是具有等宽仓的 2D 直方图。您创建的直方图已经与您的图像具有相同的形状。所以剩下的就是应用色彩映射表了。我很喜欢colorcet
库中的fire
。你就完了。注意datashader
只接受DataFrame
作为输入(无论是pandas
、dask
还是其他),你的数据必须存储为float32
。
我们需要额外的软件包:
pip install datashader, colorcet, pandas
这就是代码:
import datashader as ds
import pandas as pd
import colorcet as cc
import matplotlib.pyplot as pltdf = pd.DataFrame(data=X, columns=["x", "y"]) # create a DF from arraycvs = ds.Canvas(plot_width=500, plot_height=500) # auto range or provide the `bounds` argument
agg = cvs.points(df, 'x', 'y') # this is the histogram
img = ds.tf.set_background(ds.tf.shade(agg, how="log", cmap=cc.fire), "black").to_pil() # create a rasterized imageplt.imshow(img)
plt.axis('off')
plt.show()
用 datashader 创建的散点图。运行时间包括保存:0.69 秒作者图片。
点不能再部分重叠,因为你正在创建一个直方图,色彩映射表将处理你以前的不透明问题。您可以决定如何标准化数据(使用how
参数)。这里我们将其设置为对数,但通常我会建议保留默认值,使用更复杂的方法。
现在让我们在图中添加一个颜色条。啊!怎么会?我们现在只有直方图和光栅图像。我们可以用matplotlib
显示图像,但没有色彩映射表的信息。可能会有一些黑客攻击,但是说实话:这只不过是一个肮脏的黑客攻击,可能会带来很多混乱。所以,datashader
很棒,很快,也很容易使用——但是它也有代价:没有颜色条,没有交互式绘图(也就是说,没有允许缩放、旋转等的 GUI)。).不过,它在创建外部图形方面确实很出色。所以,试试吧!尤其是在处理地理定位数据时。
更快的解决方案…还有彩条!
动态图对我来说并不重要,但我真的需要颜色条。所以,我继续编写了我自己的解决方案。其实真的很简单。最初,我用numpy
计算 2D 直方图,然后让matplotlib
处理阴影。但是numpy.histogram2d
太慢了,这就是我换成fast_histogram
的原因。我再次使用colorcet.fire
地图,但是通过cc.cm
字典访问它以兼容matplotlib
。另外,我提供了norm
参数来使用对数色图。要知道vmin=0
是无效的,因为没有定义零的对数。这也是为什么所有的 0 值都被映射到所谓的bad
颜色。因此,只需将bad
颜色设置为最小值的颜色(或者你想要的任何背景颜色)。
我们需要额外的软件包:
pip install fast-histogram colorcet
并运行代码:
import colorcet as cc
import matplotlib.colors as colors
import matplotlib.pyplot as plt
from fast_histogram import histogram2dcmap = cc.cm["fire"].copy()
cmap.set_bad(cmap.get_under()) # set the color for 0bounds = [[X[:, 0].min(), X[:, 0].max()], [X[:, 1].min(), X[:, 1].max()]]
h = histogram2d(X[:, 0], X[:, 1], range=bounds, bins=500)plt.imshow(h, norm=colors.LogNorm(vmin=1, vmax=h.max()), cmap=cmap)
plt.axis('off')
plt.show()
使用 fast_histogram 和自定义阴影创建的散点图。运行时间包括保存:0.13 秒图片作者。
注意,由于fast_histogram
输出数据的方式,创建的散点图是旋转的。
要显示颜色条,只需在plt.show()
前添加plt.colorbar()
。
用 fast_histogram、自定义阴影和颜色条创建的散点图!作者图片。
链接:
https://github.com/astrofrog/fast-histogram https://github.com/holoviz/datashader https://colorcet.holoviz.org/
如何以最简单的方式创建机器学习界面
原文:https://towardsdatascience.com/how-to-create-machine-learning-uis-the-easy-way-7e97e26b3797?source=collection_archive---------15-----------------------
我如何为一个复杂的草图识别模型构建一个很棒的 UI
草图预测应用—作者图片
最终部署的应用程序—作者的视频
介绍
数据科学家擅长创建代表和预测现实世界数据的模型,但实际上将机器学习模型投入使用更多的是一门艺术而不是科学。部署需要软件工程和开发运维中常见的技能。 Venturebeat 指出,87%的数据科学项目从未投入生产,而 redapt 指出是 90%。两者都强调了决定成功和失败的一个重要因素是团队的协作和迭代。
机器学习模型的目标是解决一个问题,只有通过用户界面才能解决这个问题。
因此,开发和部署用户界面是建模的一个重要步骤。缩小构建和部署模型之间的差距是我们如何确保拥有一个健壮的模型。
在这篇文章中,我将演示一些简单的步骤来给你的机器学习模型带来活力。我将为草图识别模型构建一个 UI。它将包括一个供用户绘制的画板输入,以及一个对草图进行实时分类的标签输出,所有这些都被部署到一个任何人都可以使用的实时链接中。那么,我们开始吧。
先决条件
本教程假设您熟悉在 TensorFlow 和 Keras 中构建 ANN 模型。对于本教程,我们将使用来自 AI 实验 Github repo 的训练模型来构建与 Gradio 的接口。
此外,如果你需要复习 gradio,你可以看看我以前的教程,一步一步地指导你如何建立一个 Gradio 帐户。此外,您可以点击查看 gradio 网站上的入门指南。
在本教程中,我们将使用tensorflow version 1.x
如果您想使用最新版本的tensorflow 2.x
,您需要相应地重新培训该模型。但是,步骤应该是相同的。
与本教程相关的笔记本托管在 Github 这里,如果你愿意跟随的话。
安装所需的库
您需要使用pip install gradio
命令安装 gradio。
然后,我们需要导入 gradio 以及 TensorFlow。之后,我们将使用tf.keras
模块中的“load_model”功能将预训练的模型加载到 colab 笔记本中。
!pip install gradio -q%tensorflow_version 1.x
此外,我们需要获取与每个绘图相关联的标签;为此,我们将从 google creative lab 公共存储库中导入它们。
以. txt 格式存储的绘图类别,我们需要将它们解码成utf-8
格式,并通过在\n
字符上拆分来转换成列表。
import gradio as gr
import tensorflow as tf
import urllib.request
cnn_model = tf.keras.models.load_model("/content/cnn.h5")labels = urllib.request.urlopen(
"https://raw.githubusercontent.com/googlecreativelab/quickdraw-dataset/master/categories.txt")labels = labels.read()
labels = labels.decode('utf-8').split("\n")[:-1]
我们对列表中的最后一个元素进行了切片,因为它是拆分过程产生的空字符串。
声明预测函数
Gradio 接口包括三个主要组件:
1.可调用函数—在我们的例子中是` predict_shape()'
2.输入组件—可调用函数的参数
3.输出组件-应用可调用函数后的输入。
因此,在接下来的几行中,我们定义了predict_shape()
方法,并将绘图作为输入图像传递。之后,对上传的模型调用 predict 方法来获得预测。
predict_shape()
在这里返回所有标签及其预测分数,标签的输出组件中的 gradio 有一个默认为 3 的num_top_classes
def predict_shape(img):
img = tf.math.divide(img, 255)
preds = cnn_model.predict(img.reshape(-1, 28, 28, 1))[0]
return {label: float(pred) for label, pred in zip(labels, preds)}
定义输入和输出组件
Gradio 有各种各样的组件可供您选择,以满足您的应用需求——点击此处查看完整的库组件。
https://www.gradio.app/docs#i_image
对于这个应用程序,我们将使用图像组件,并将源设置为“canvas”以获得一个画板界面。此外,我们将画布的大小设置为 28x 28 像素。
我们将选择标签作为输出组件,并将只显示预测中最高的两个类。
output = gr.outputs.Label(num_top_classes=2)
input = gr.inputs.Image(
image_mode='L',
source='canvas',
shape=(28, 28),
invert_colors=True,
tool= 'select')
设置界面
呈现之前准备好的组件的最后一步是通过接口函数。您需要做的就是将可调用的函数、输入和输出传递给Interface()
,然后调用launch()
来呈现应用程序。
Gradio 的一个很好的特性是,您可以向呈现的界面添加 HTML 标记元素,因此它可以作为一个独立的 web 应用程序运行。在接口方法中,我为呈现的应用程序传递了标题和描述。
如果您在 google colab 上,您需要在
launch()
方法内将 debug 设置为 True,以便在 colab 内呈现。
title="Sketch prediction app"description="A Convolution Neural Network model trained on Google's QuickDraw dataset." \
" Start by draw a smily face, or anything you can think of!"
请注意:根据文档,您需要将 capture_session 标志设置为 True,因为模型最初是使用 TensorFlow 1.x 训练的。
gr.Interface(fn = predict_shape, inputs = input,
outputs = output, live = True,
title=title, description = description,
capture_session=True).launch(debug=True)
工作梯度界面—图片由作者提供
厉害!我们现在有一个很好的界面。
部署接口以获得持久链接
在之前的一篇文章中,我向您展示了 Gradio 如何使用 Flask 和 Docker 构建应用程序后端的整个生命周期。
直到这一步,你有一个 24 小时工作的可共享链接,如果你想保持链接,你需要在 Gradio 主机上托管应用程序,在那里你可以上传接口并获得一个永久链接。
https://www.gradio.app/introducing-hosted
步骤很简单,您只需要:
1.Github 项目回购,应该包括 requirements.txt 文件
2.Gradio 帐户(与 GitHub 的电子邮件相同)
就是这样!
部署屏幕—作者提供的图片
该界面可能需要几分钟来构建映像后端要求。
可能需要几分钟https://gradio.app/g/salma71/sketch_predict—图片由作者提供
然后可以在已部署的链接中找到已部署的接口。您可能会收到一封确认接口已成功部署的电子邮件—您可以在这里检查已部署的接口。
https://gradio.app/g/salma71/sketch_predict
在集线器上显示
通过将应用程序托管在 Hub 上,您可以将模型向前推进一步。你所需要做的就是指定标题、描述和一个缩略图,一切都准备好了。
在 Gradio Hub 上显示应用程序—图片由作者提供
https://gradio.app/hub/salma71/sketch_predict—作者图片
谢谢大家!
我希望这篇文章能让你对 Gradio 库有一个全面的了解。如有疑问,请写在下方评论区;我很乐意帮忙。
鼓励我的最好方式是在MediumLinkedIn或 Github 上跟随我。感谢阅读!
参考
- Github 回购
- Gradio 文档
- 为你的机器学习模型建立一个令人敬畏的用户界面
- 在几秒钟内部署一个机器学习模型
如何使用 Python 创建类似 3Blue1Brown 的数学动画
原文:https://towardsdatascience.com/how-to-create-mathematical-animations-like-3blue1brown-using-python-f571fb9da3d1?source=collection_archive---------0-----------------------
利用您的 Python 技能创建美丽的数学动画
动机
你是否曾经纠结于机器学习算法的数学概念,并将 3Blue1Brown 作为学习资源?3Blue1Brown 是著名的数学 YouTube 频道,由格兰特·桑德森(Grant Sanderson)创建。很多人喜欢 3Blue1Brown 是因为 Grant 的精彩讲解和下面这样很酷的动画。
由 3Blue1Brown 制作的视频
如果您可以了解他是如何创建这些动画的,这样您就可以创建类似的动画来向您的队友、经理或追随者解释一些数据科学概念,这不是很酷吗?
幸运的是,Grant 开发了一个名为 manim 的 Python 包,可以让你使用 Python 创建数学动画或图片。在这篇文章中,你将学习如何使用 manim 创建如下数学动画。
作者 GIF
什么是曼尼姆?
Manim 是一个精确动画引擎,设计用于创建解释性数学视频。注意,manim 有两个版本。一个是由 Grant 创建的,另一个是由 Manim 社区派生和维护的。
由于 Manim 社区维护的版本比 Grant 的版本更新更频繁,测试更好,所以我们将使用 Manim 社区维护的版本。
要安装软件包的依赖项,请访问文档。安装完依赖项后,键入:
pip install manim==0.9.0
开始
创建一个从中心开始增长的蓝色方块
我们将创建一个从中心开始增长的蓝色正方形。创建动画的代码在从Scene
派生的类的construct
方法中。
将上面的脚本另存为start.py
。现在运行下面的命令为脚本生成一个视频。
$ manim -p -ql start.py PointMovingOnShapes
并且一个名为PointMovingOnShapes.mp4
的视频会保存在你的本地目录下。您应该会看到类似下面的内容!
作者 GIF
上述选项的解释:
-p
:视频生成完成后播放-ql
:生成低质量视频
要生成高质量的视频,请使用-qh
。
要创建一个 GIF 而不是视频,添加-i
到命令中,如下所示:
$ manim -p -ql -i start.py PointMovingOnShapes
把正方形变成圆形
单独创建一个正方形并不那么有趣。让我们把这个正方形变成一个圆形。
作者 GIF
创建上述动画的代码:
点击查看形状的完整列表。
自定义 Manim
如果不希望背景是黑色的,可以像下面这样变成灰色:
作者 GIF
通过使用config.background_color
在这里找到定制 manim 的其他方法。
我还能拿曼尼姆怎么办?
用一个移动的框架写出数学方程
您还可以创建一个动画,用如下所示的移动帧编写数学方程:
作者 GIF
或者一步一步地写下如何解方程:
作者 GIF
移动和变焦照相机
您还可以调整相机,并使用从MovingCameraScene
对象继承的类来选择放大方程的哪一部分。
作者 GIF
图表
您还可以使用 manim 来创建一个注释图,如下所示:
作者 GIF
如果你想得到一个场景最后一帧的图像,添加-s
到命令中:
manim -p -qh -s more.py Graph
您也可以通过设置animate=True
来设置轴的过程
$ manim -p -qh more.py Graph
作者 GIF
一起移动对象
您也可以使用VGroup
将不同的 Manim 对象分组,并像下面这样一起移动它们:
作者 GIF
跟踪路径
你也可以使用TracedPath
创建一个移动物体的轨迹,如下图所示:
作者 GIF
概述
恭喜你!您刚刚学习了如何使用 manim 以及它能做什么。概括地说,manim 提供了 3 种对象:
- 移动对象:可以在屏幕上显示的对象,如
Circle
、Square
、Matrix
、Angle
等 - 场景:用于
Scene
、MovingCameraScene
等动画的画布 - 动画:应用于
Write
、Create
、GrowFromCenter
、Transform
等物体的动画
有这么多的人可以做,我不能在这里涵盖。最好的学习方法是通过实践,所以我鼓励你尝试本文中的例子,并查看 manim 的教程。
本文的源代码可以在这里找到:
我喜欢写一些基本的数据科学概念,并尝试不同的算法和数据科学工具。你可以通过 LinkedIn 和 Twitter 与我联系。
如果你想查看我写的所有文章的代码,请点击这里。在 Medium 上关注我,了解我的最新数据科学文章,例如:
如何创建更高效的深度学习模型
原文:https://towardsdatascience.com/how-to-create-more-efficient-deep-learning-models-c27bf49e070c?source=collection_archive---------40-----------------------
方法和技术概述
托马斯·凯利在 Unsplash 上的照片
在这篇文章中,我将介绍和讨论几种重要的方法和技术,这些方法和技术可以帮助在不同层面上提高深度学习模型的效率。这些类型的优化现在变得更加重要,因为深度学习模型的新改进也带来了参数数量、训练资源要求、延迟、存储要求等的增加。
我将讨论的主要议题如下:
- 按压手法
- 学习技巧
- 高效架构
- 自动化
压缩技术
这些类型的技术以整个模型的表示效率为目标,这是可能的,主要是因为许多最先进的模型是过度参数化的。主模型的多个组件可以受益,而不会影响(在一定范围内)对原始版本计算的评分结果,例如训练时间、推理延迟、内存占用。通过压缩神经网络模型的计算图的一部分,我们还可以提高其泛化能力。
这里探讨了多种想法,其中一些最成功的是:
- 修剪 —指的是使用各种策略从神经网络中删除一组参数或将其设置为零,以挑选受影响的权重,从而获得一个不需要像以前那样多内存的稀疏网络。最流行的剪枝策略基于:显著性、随机结构化/非结构化、调度、稀疏预算分布、再生长。通常在修剪后,建议对生成的模型进行微调。
PyTorch 中的模型修剪示例:
**import** torch.nn.utils.prune **as** prune**model** **=** **Model()****layers_to_prune** **=** **(**
**(model.conv1,** 'weight'**),**
**(model.fc1,** 'weight'**)**
**)**// This will prune 20% of the parameters with lowest L1-norm
**prune.global_unstructured(**
**layers_to_prune,**
**pruning_method=prune.L1Unstructured,**
**amount=**0.2**,**
**)**
- 量化 —降低用于模型权重和激活的数据类型的精度(例如:从 32 位浮点值降低到 8 位定点)。大多数时候,当我们应用量化时,我们可以看到内存占用和延迟方面的改进。通常有两种量化方式:后培训和量化感知培训;我认为这些术语大多是不言自明的(至少从高层次的角度来看),唯一需要提到的是,第一个术语可能会影响用于推断的模型的质量。
PyTorch 有多种量化策略,下面是最简单的一种:
**quantized_model=** **torch.quantization.quantize_dynamic(**
**model,**
**qconfig_spec={torch.nn.Linear},**
**dtype=torch.qint8**
**)****//**qconfig_spec specifies the list of submodule names in model to apply quantization to.
- 基于矩阵的压缩技术:低秩逼近、字典学习、层拼接等。
学习技巧
这些类型的技术试图通过改变训练过程的某些方面来提高模型的质量。通过只针对培训阶段,验证/测试得分应该保持对生产的代表性。
学习技巧的类型:
- 蒸馏 —对于这种方法,我们引入了“学生”网络和“教师”网络的概念。基本上,我们有一个或一组较大的网络在“教导”较小的网络来重现整个过程或只是一些中间的表现。我们还可以使用教师网络来创建软标签,我们可以在损失函数中使用这些软标签以及地面真实标签,其想法是软标签可以捕捉类之间的一些关系,这可以帮助训练。
- 数据扩充 —当处理深度模型时,我们通常需要大量的样本来确保我们的模型能够一般化。但是,由于特定数据类型的高成本或稀缺性,这有时会成为一个问题。数据集大小问题的一个可能的改进是数据扩充,它基本上是一套通过应用某种变换或插值来生成合成样本的方法。大多数数据增强技术针对计算机视觉任务,例如:调整大小、旋转、翻转、裁剪等。
在 PyTorch 中,我们可以堆叠多种类型的转换,并在自定义数据集类中直接使用它们:
train_transforms = A.Compose(
[
A.Resize(width=320, height=320),
A.RandomCrop(height=728, width=728),
A.HorizontalFlip(p=0.5),
A.VerticalFlip(p=0.5),
A.RandomRotate90(p=0.5),
ToTensor(),
]
)
- 自我监督学习(Self-Supervised Learning)——代表了对没有足够大的标签数据集的“老”问题的最有趣的解决方案之一。当应用自我监督学习方法时,我们使用未标记的数据创建了一个“借口任务”,允许我们生成良好的表示,这些表示可以在以后用于更具体的任务。一旦我们有足够好的嵌入,我们可以添加一个预测头,并用标记的数据微调模型。例如,在 NLP 中,应用自我监督来预测未标记句子中的屏蔽词是相当常见的。在 CV 中有对比学习的概念,其中模型被训练来区分不同的图像。由于对标记数据的要求较低,这种技术被认为是数据高效的。
高效架构
提高深度学习系统效率的另一种方法是后退一步,尝试在模型的架构层面解决问题,一些神经网络层设计更适合特定的任务或数据类型。
接下来,我将尝试向您展示几个模型架构设计的示例,这些设计为计算机视觉和自然语言处理带来了一些改进:
- 计算机视觉:卷积层 —这种类型的层彻底改变了计算机视觉领域。它利用了图像特征的空间位置,通过堆叠它们,它创建了多级表示,从而允许在后面的层中检测更复杂的特征。此外,因为卷积操作对整个图像重复使用相同的滤波器,这也大大减少了模型的参数数量。
- 自然语言处理:变形金刚——给 NLP 领域带来了巨大的改进(从注意力是你所需要的, Ashish Vaswani 等开始),使用这种类型的神经网络的主要优势是它消除了只有单一特征向量来表示整个输入序列上下文的瓶颈。Transformer 体系结构使用自我关注和交叉关注来编码序列中每个输入元素的上下文。这里的是一个很棒的课程,解释了变压器的基本原理和用法。
自动化
寻找提高机器学习模型效率的新途径的另一种方法是通过使用不同的自动搜索技术来“强力”搜索不同的想法。最大的缺点是基于搜索的方法需要大量的计算资源和时间。
我们可以通过考虑搜索空间的级别来划分自动化的类型:
- 超参数优化(HO) —顾名思义,这种类型的自动化试图通过改变一些超参数的值来搜索更有效的模型,如学习速率、层数、重量衰减、批量等。即使我们使用 k 折叠分裂策略来迭代每个折叠中超参数的不同值,也仍然需要大量的计算来遍历它们。有几种搜索策略我们可以遵循: 网格搜索、随机搜索、贝叶斯搜索、由粗到细搜索。
- 神经架构搜索(NAS) —这可以被认为是超参数优化的扩展,允许搜索空间中的其他元素,如不同的操作块(卷积、线性层、池)以及组合它们的不同方式。此外,对于 NAS,研究人员还使用强化学习来寻找更好的体系结构。
最后,我在这篇文章中列出的列表绝不是全面的,还有许多正在进行的研究努力试图改善深度学习系统的每个瓶颈。
感谢您的阅读,如果您想了解最新的机器学习新闻和一些优质的模因:),您可以在 Twitter 上关注我这里。
资源
- https://py torch . org/blog/introduction-to-quantization-on-py torch/
- https://blog . tensor flow . org/2020/02/matrix-compression-operator-tensor flow . html
- 高拉夫·蒙哈尼:高效深度学习:关于让深度学习模型更小、更快、更好的调查(https://arxiv.org/abs/2106.08962)
如何使用 Python 创建 PDF 报告——基本指南
原文:https://towardsdatascience.com/how-to-create-pdf-reports-with-python-the-essential-guide-c08dd3ebf2ee?source=collection_archive---------1-----------------------
在 10 分钟或更短时间内创建具有漂亮可视化效果的 PDF 报告
杰西·G-C 在 Unsplash 上的照片
报告无处不在,因此任何技术专业人员都必须知道如何创建它们。这是一项乏味且耗时的任务,这使得它成为 Python 自动化的完美候选。
无论您是数据科学家还是软件开发人员,都可以从自动报告生成中受益。例如,数据科学家可能会使用报告来显示机器学习模型的性能或解释。
本文将教您如何制作基于数据可视化的报告,并将它们保存为 pdf。更准确地说,您将学习如何将多个数据可视化(虚拟销售数据)合并到一个 PDF 文件中。
最棒的是——这比你想象的要简单!
这篇文章的结构如下:
- 数据生成
- 数据可视化
- 创建 PDF 页面结构
- 创建 PDF 报告
- 结论
你可以在这里下载源代码为的笔记本。
数据生成
没有数据就没有报告。这就是为什么您必须首先生成一些——稍后再详细介绍。
让我们从进口开始。你将需要很多东西——但是FPDF
库可能是唯一未知的。简而言之,它用于创建 pdf,稍后您将使用它。请参考下面的导入代码片段:
接下来我们生成一些假数据。其思想是声明一个函数,该函数返回给定月份的虚拟销售数据的数据帧。它通过构建整个月的日期范围,然后将销售额作为给定范围内的随机整数来分配。
您可以使用calendar
库来获取任意年/月组合的最后一天。以下是完整的代码片段:
对generate_sales_data(month=3)
的调用产生了 2020 年 3 月的 31 个数据点。下面是前几行的样子:
图 1 —生成数据的样本(作者提供的图片)
就这样——您现在有了一个生成虚拟销售数据的函数。接下来我们来看看如何可视化。
数据可视化
您的下一个任务是创建一个函数,将之前创建的数据集可视化为一个线图。当您处理时间序列数据时,这是最合适的可视化类型。
下面是数据可视化的函数和一个调用示例:
简而言之——创建数据可视化、设置标题、摆弄字体——没什么特别的。可视化结果不会显示给用户,而是保存在机器上。稍后您会看到这有多么强大。
示例调用将保存 2020 年 12 月的数据可视化。它看起来是这样的:
图片 2—2020 年 12 月的销售图(图片由作者提供)
这就是你的视觉化功能。在创建 PDF 文档之前,只剩下一个步骤,那就是保存所有的可视化并定义报告页面结构。
创建 PDF 页面结构
现在的任务是创建一个执行以下操作的函数:
- 为图表创建文件夹—如果存在,则删除并重新创建
- 保存 2020 年除一月之外的每个月的数据可视化,以便您可以看到如何在每页上使用不同数量的元素(也可以随意包含一月)
- 从可视化效果创建 PDF 矩阵,这是一个二维矩阵,其中一行代表 PDF 报告中的一个页面
下面是该函数的代码片段:
可能有很多东西需要消化,所以一行一行地看一遍。这些评论应该会有所帮助。排序背后的想法是从字符串中获取月份的整数表示—例如,从“3.png”中获取 3,并使用该值对图表进行排序。如果顺序无关紧要,请删除这一行,但月份就不是这样了。
下面是一个调用construct()
函数的例子:
运行上述代码片段后,您应该会在笔记本中看到以下内容:
图片 3 —生成的可视化效果(作者提供的图片)
如果你想知道——这是我的机器上的plots/
文件夹的样子(在调用了construct()
函数之后):
图 4 — PDF 报告内容矩阵(图片由作者提供)
这就是构建 PDF 报告所需的全部内容—接下来您将学习如何完成。
创建 PDF 报告
这是一切汇集的地方。现在您将创建一个从FPDF
继承而来的自定义PDF
类。这样,所有的属性和方法在我们的类中都是可用的,如果你没有忘记在构造函数中调用super().__init__()
的话。构造函数还将保存页面宽度和高度的值(A4 纸)。
您的PDF
类将有几个方法:
header()
–用于定义文件标题。自定义徽标放在左边(确保有一个或删除此代码行),硬编码文本放在右边footer()
–用于定义文档页脚。它只会显示页码page_body()
–用于定义页面的外观。这将取决于每页显示的可视化效果的数量,因此位置和边距会相应地设置(您可以随意调整这些值)print_page()
–用于添加空白页并填充内容
以下是该类的完整代码片段:
现在是实例化它并从二维内容矩阵中追加页面的时候了:
上面的单元需要一些时间来执行,完成后将返回一个空字符串。这是意料之中的,因为您的报告保存在笔记本所在的文件夹中。
报告的首页应该是这样的:
图 PDF 报告的第一页(图片由作者提供)
当然,由于不同的标志和完全随机的销售数据,你的看起来会不同。
这就是如何用 Python 创建数据可视化的 PDF 报告。接下来让我们总结一下。
结论
今天,您已经学习了很多东西——如何为任何场合创建虚拟数据,如何将其可视化,以及如何将可视化嵌入到单个 PDF 报告中。嵌入可视化只需要最少的代码修改——主要是定位和边距。
如果你想看基于机器学习模型解释(SHAP 或莱姆)或其他与数据科学相关的东西的自动化报告创建指南,请告诉我。
感谢阅读。
喜欢这篇文章吗?成为 中等会员 继续无限制学习。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。
https://medium.com/@radecicdario/membership
加入我的私人邮件列表,获取更多有用的见解。
了解更多信息
- 2021 年学习数据科学的前 5 本书
- SHAP:如何用 Python 解释机器学习模型
- 三大分类机器学习指标—一劳永逸地消除准确性
- ROC 和 AUC——如何评估机器学习模型
- 精确召回曲线:如何轻松评估机器学习模型
原载于 2021 年 1 月 18 日https://betterdatascience.com/create-pdf-reports-with-python/。
如何打造完美的 AI 战略
原文:https://towardsdatascience.com/how-to-create-perfect-ai-strategy-9c7884a89e11?source=collection_archive---------34-----------------------
人工智能笔记
深入了解人工智能战略的三大支柱
工作室 Kealaula 在 Unsplash 拍摄的照片
大多数技术都是从行业内的大肆宣传开始的,并逐步失去人们的关注,因为它们在解决现实世界的问题时不能满足我们的期望。人工智能是仅有的几项达到并超过预期的最新技术之一。然而,如果我们在追求人工智能发展方面没有一个坚实的战略,这项技术可能会像其他技术一样最终走向相同的终点。人工智能战略有三个主要支柱:可行性、性能和可扩展性。如今,每个人都在谈论人工智能模型的潜力,但我想指出为了创造一个完美的人工智能战略必须仔细研究的问题。有了坚实的人工智能战略,你就增加了构建人工智能产品的成功几率。出于同样的目的,我最近写了一篇关于如何创建完美数据策略的文章。你可以在下面找到。
—可行性
要构建和推出一个人工智能产品,你会遇到许多挑战。如果你认为在人工智能世界里一切都是可行的,你可能会很容易失望。许多公司开始开发一种人工智能产品,在中途,发现它对他们不起作用。这造成了失望,更重要的是,阻止了他们正确使用人工智能并为企业创造价值。强烈建议在开始实施人工智能产品之前与人工智能专家进行头脑风暴,并以你的人工智能任务为短期目标。
例如,在一些应用中,必须在设备级别(也称为边缘人工智能)实现人工智能模型,以遵守数据隐私法案。当 AI 模型在最接近数据收集的点实现时,隐私问题被最小化。然而,在这个级别实现人工智能模型会产生许多问题。例如,你在这个层次上没有强大的计算能力。或者,你不能很容易地在那些与 edge AI 兼容的语言(如 C)上实现你用高级编程语言(如 Python)开发的东西,因为所需的库不存在。再比如,你开始为一个应用开发深度学习模型。然后,你发现所需的计算能力或深度学习专家对你来说是不可及的,或者不是以一种经济高效的方式。在那一点上你必须三思。你可以阅读更多关于大公司在分析构建人工智能产品的可行性时所犯的错误。
https://pub.towardsai.net/ai-strategy-a-battlefield-that-even-big-firms-struggle-539a9f3df396
要创建一个完美的 AI 策略,你必须有一个计划来保证技术上的可行性。为实现一个强大的人工智能模型的复杂性做好准备。
—性能
您可能会说“在文献中存在许多标准的度量标准来帮助人们评估模型的质量。因此,人工智能模型的性能很容易衡量。”不幸的是,我必须说这并不完全正确。一个主要问题是,您只能在您收集的数据范围内衡量性能。换句话说,您必须始终处理样本外错误(也称为泛化错误)。没人能保证你的用户数据是什么样的。你可以尽最大努力使用与真实世界数据高度相似的数据集来评估 AI 模型;然而,你总是会惊讶于从未预料到的新情况。
更重要的是,大多数时候(如果不是总是)你不能保证一个人工智能模型的最差性能。存在许多方法来减少概括误差;然而,他们不太成功地给它划定界限,特别是在深度学习模型等灰箱模型中。此外,输入数据中的小扰动可能会导致结果不稳定,这在许多使用情况下是不可接受的。你可以在下面的文章中了解更多关于如何管理人工智能模型的性能。
https://pedram-ataee.medium.com/why-experiment-management-is-the-key-to-success-in-data-science-b286aaa4700d
要创建一个完美的 AI 策略,你必须有一个评估 AI 模型的计划。超越标准指标思考!
—可扩展性
为试点项目建立人工智能模型很容易。然而,当你决定建立一个人工智能产品时,它变得更加困难,当你决定扩展它时,它变得更加困难。帕累托原则(也叫 80-20 法则)在这里也是有效的。一般来说,你可以用 20%的努力建立一个符合你 80%预期的 AI 模型。剩下的 20%的期望将会很难实现,这会让你震惊,尤其是当你想要扩展产品的时候。
例如,可伸缩性挑战源于收集大量干净且有标签的数据,并构建一个可以解决大多数用例的通用模型。人工智能模型的质量与其数据的质量一样好。因此,你必须确保用于训练人工智能模型的数据集是全面的,并涵盖大多数用例。实际上,训练数据集并不是普遍完整的。这就是为什么在构建人工智能模型时,你总是会遇到偏差-方差的权衡。例如,这种权衡基本上迫使您降低当前数据集中的精度,同时希望提高尚未收集的数据集中的精度。
最后,但同样重要的是,您经常需要构建各种上下文化的模型来处理不同的上下文。用一个模型来处理各种不同的环境通常是不可能的。这就是为什么 AI 聊天机器人必须为每个行业专门设计才能使用。你可以在下面的文章中阅读更多关于帮助我们管理情境化模型的人工智能模型的信息。
为了创造一个完美的人工智能战略,你必须有一个计划来扩大人工智能模型的规模。请注意,达到您预期的 80%并不意味着您有一个案例!
感谢阅读!
如果你喜欢这个帖子,想支持我…
- 跟我上 中 !
- 在 亚马逊 上查看我的书!
- 成为 中的一员 !
- 连接上Linkedin!
- 关注我的 推特 !
https://pedram-ataee.medium.com/membership
如何创造依赖机器学习的产品
原文:https://towardsdatascience.com/how-to-create-products-that-rely-on-machine-learning-f0c7fe70cbc8?source=collection_archive---------9-----------------------
产品团队用机器学习来平衡特定风险并增加开发成功产品的可能性的框架
创造依赖机器学习等技术的产品,与普通产品相比,有着不同的考虑因素、风险和限制。为了在你的产品工作中取得成功,开发过程应该承认这些固有的挑战并直面它们——即使这可能不适合你的开发团队
由 Austin Distel 在 Unsplash 上拍摄
你真的对工作中的新项目感到兴奋。你正在与贵公司最强的工程师和科学家团队合作开发一个很酷的新产品,其核心是使用定制的机器学习方法来交付成果。具体来说,它可以是一个决定何时为零售商店重新进货并自动规划卡车运输的工具,也可以是一个新的应用程序,帮助你的客户在购买前预览你的家具在他们家中的外观,一个用于你公司生产线的自动故障检测系统或完全不同的东西。
每个人都开始为这个项目工作。大量的技术设计和开发工作。三个月来,数据科学家正在研究一种复杂的新深度学习架构,并在使其工作方面遇到了困难。工程师们已经创建了一个非常乏味的应用程序,但在模型准备好之前,他们真的不知道如何进行。与此同时,管理层在要求地位,团队中的能量,曾经因为兴奋而非常高,现在随着沮丧而下降。
经过长时间的延迟,试点产品终于推出了,然而不知何故,预期用户并没有真正拿起它。管理层不高兴,技术团队也不高兴。一些工程师和科学家感觉自己很失败,有些人甚至感觉他们在公司的地位下降了。
如果你经历过类似上述场景的事情,你并不孤单。成功打造使用机器学习[1]作为核心技术的产品与其他数字产品计划不同。指标很多:“人工智能项目”的失败率据说大大超过 50 %(尽管很难获得确切的数字)[2,3],对许多人来说,超越试点或概念验证已被证明是一个挑战[4,5],人工智能人才的整体保留是一个巨大的挑战[6]。虽然该技术本身在过去十年中已经从令人兴奋的发展成为相当主流的技术,许多发展改善了可访问性,但在产品人员和技术人员之间仍然没有就如何进行机器学习产品开发达成共识,尽管似乎有一些理解,即机器学习产品开发的技术要求和风险概况不同于普通的数字产品,并且需要一些调整。
产品工作失败的一个关键原因是数据科学家和产品人员对风险没有相同的理解,并且在解决这些风险的顺序上存在分歧。由于主要关注“核心智能”,数据科学家将直观地关注模型开发的应用研发,以探索技术可行性;这是一项耗时的探索性工作,通常以非线性方式进行。另一方面,产品领导者将更关心以对公司有益的方式创造强大和用户友好的价值主张(考虑价值、合意性和可行性以及技术可行性的组合[7]),并将希望快速迭代以探索这一点。这也是一个非线性的发现过程,只是控制旋钮和成功标准不同。通常,没有人考虑如何确保以新产品所需的速度持续获得正确质量的正确数据。
发现对用户和公司都有用的正确产品,同时不断平衡和最小化价值、合意性、可行性和可行性这四个风险总是很困难的,即使是基于熟悉技术的产品。然而,这四种高级风险对于机器学习驱动的产品有一些特殊的表现,这些表现可能不明显。这些并不能取代四大风险,它们只是四大风险中需要特别关注的关键点。这些是
-
早期在模型可行性评估上花费的时间太少:机器学习的技术可行性受到数据和技能的限制。事后改进机器学习模型,基础强的容易,基础不到位的不可能。如果你假设的模型在科学上是不可能开发出来的,那么它会扼杀你的整个产品。因此,你应该遵循#monkeyfirst 原则[8]:首先做困难的事情,如果它们是不可能的,你必须评估另一种方法是否可行,或者放弃这个产品想法。
机器学习的限制因素是 a)你是否有持续和及时地访问正确的数据,b)你是否有开发和部署正确模型的技能,因此在产品开发的早期就必须在这些方面建立正确的信心水平。
-
早期(在验证产品之前)在机器学习模型上花了太多时间。改进模型性能非常耗时,但这可能是对时间的极大浪费,除非已经证实我们提供给用户的产品也通过这种努力得到了改进。因此,第一个风险是确保足够深入地评估机器学习是否可行,第二个风险是过早地过度投资,忽视用户的需求(价值和愿望的风险)。
-
不满的数据科学家。数据科学家非常喜欢研究机器学习模型,如果有选择的话,他们更喜欢研究更高级的模型,这样可以增长他们的技能和经验。另一方面,许多数据科学家在构建部署机器学习模型的系统方面不如软件工程同行强大,并且数据科学家也经常觉得他们不应该做这项工作。
如果将上述前两种风险放在心上,数据科学家就有理由担心他们是否能够利用自己的核心竞争力。一旦产品 MVP 证明了对用户的价值,就有时间这么做了。尽管如此,这可能会导致沮丧和高流动,除非及早和适当地解决。
对期望的结果和达到目标的风险达成共识,并同意允许团队解决这些问题的开发方法是关键。技术团队经常忘记的是,预期的结果是解决重要、有价值的问题的出色用户体验——工作机器学习技术本身是不够的。事实上,处理异常以及用户如何对机器学习预测采取行动是成功的关键,但通常完全位于机器学习技术本身之外。很难对风险和挑战保持清醒的认识,尤其是在团队还在学习价值主张和技术挑战的早期。尽早就期望的用户结果和开发方法进行公开的对话,并在此之后定期检查,以在需要时进行重新评估和调整,这仍然是至关重要的。
基于机器学习的产品开发方法
下面的方法融合了第一手经验和其他团队的观察,试图达到良好的平衡。就像任何其他创造性的追求一样,你不应该以拥有一个完美的过程为目标,而是试图创造伟大的(“完美的”)结果,并尊重你将在过程中学习到的东西:因此,预计这有时会变得混乱,并且会犯错误。也就是说,希望下面的方法将强调最关键的风险是如何在开发过程中变化的,并希望为技术团队和产品负责人提供一些视角。
考虑到最大的风险是产品是否会引起用户的共鸣,以及机器学习的预期用途是否可行,在发现过程中使用步骤 1a 和 1b 来解决这些风险,同时迭代出可行的解决方案。一旦达到初始牵引力,步骤 2a 和 2b 着重于改进或扩展产品。在发现阶段会测试许多不同的想法,开发会产生许多不同的结果。当一个 MVP 被开发出来的时候,过程就变得更加狭窄了。作者插图。
这种方法实际上就是识别前面提到的哪些产品风险在哪个阶段最大,以及如何解决这些风险的一些建议。希望这能让你在开发新产品的时候走得更快,增加你的信心和成功的可能性。在探索可能使用机器学习的新产品的过程中,两个重要的风险是所提议产品的技术可行性和用户的合意性,即该产品是否以吸引人的方式解决了一个重要问题(上面强调的前两个风险)。在产品发现过程中,解决这个问题的最好方法是在速度和细节之间找到平衡点,从而确定一个吸引用户的有价值的产品,并且这个产品在技术上也是可行的。前两个步骤(1a 和 1b,见图)是关于执行适当数量的发现/开发周期,以找到我们有信心在技术上能够制造的强有力的候选产品。迭代步骤 1a 和 1b 的结果是一个最小可行产品(MVP ),我们可以从中学习。
大部分技术开发将发生在步骤 2a,这是所有关于产品的成熟。这是很多详细的机器学习优化、数据管道优化等的地方。会发生。最后,步骤 2b 是扩展更多功能的通用产品方面。
步骤 1a:用技术解决问题是否可行?
当产品经理提出一个想法时,技术团队的工作就是评估通过技术解决它是否可行。尽管在早期发现阶段,你不应该过早地专注于某个特定的技术解决方案,但你仍然需要树立信心,相信可以开发出技术上可行的解决方案。否则你就不知道如何构建产品,你应该把注意力转移到另一种满足用户需求的方式上。
这并不是说“我们有技术,现在让我们寻找一个问题来解决”,但是即使当把用户问题放在中心位置时,团队的技术能力和问题的背景在交付解决方案的技术可行性中也起着重要作用。
因此,第一步的目标是在足够详细的程度上考虑潜在技术解决方案的细节,同时仍然能够保持适当的速度。具体来说,这意味着评估您的团队和您的产品建立机器学习技术来交付用户问题所需的解决方案(包括对模型性能的一些粗略了解)是否现实,确保在进行预测时机器学习的数据可以始终如一地来源于产品,并建立可行的方法来衡量性能。**
举一个重要的例子,无法一致地获取和清理模型运行所需的数据通常是一个巨大的挑战,因为不存在如何获取数据的途径。一个常见的原因是在静态数据集上训练的模型,当转换为产品时失败,因为没有充分考虑如何控制数据生成过程[9]。在发现阶段就考虑建立一个良好的数据生成过程的可行性是非常重要的:这不仅可以节省大量的时间、金钱和麻烦[10],而且数据获取策略的缺乏将会停止扩展,从而在产品上市之前就扼杀你的产品。
机器学习模型和数据采集的可行性评估通常是通过概念的技术证明来完成的,但如何进行当然可以有所不同。无论你怎么做,都是为了在产品团队中建立信心,相信这些挑战是可以解决的。虽然在某些情况下可能会发生,但如果在这个阶段进行高级数学建模,我会感到惊讶;更确切地说,它是关于确定问题是否可以用数学建模的方式来表达,确定模型性能(准确性、提供结果的时间等)的早期信心。)是否可以通过微调达到所需的水平,以及所需的数据材料是否可以持续获得。
步骤 1b:专注于向用户证明价值主张
第二步是面向用户的,类似于第一步:产品发现,即确定如何塑造产品以使其对用户既有价值又有吸引力的过程。我将这两个步骤命名为 1a 和 1b,以表明它们应该被同时处理[11]。预计 1a 和 1b 将是产品与市场匹配的迭代循环。
目标是为用户探索价值驱动因素,以了解如何设计和构建产品。也就是说,这是确定我们相信哪些想法来开发 MVP 以与用户进行测试的过程,所有这些都是为了确定一个强有力的价值主张。一个关键问题涉及识别用户眼中机器学习的实际价值驱动因素,包括如何以一种允许用户尽可能容易地采取正确行动的方式呈现机器学习的结果。细节当然会非常依赖于上下文,但汽车导航系统提供了一个很好的例子:要想成功,这种系统需要能够通过 GPS(机器学习和优化)提供一个好的计划,及时的口头更新(解释与运动相关的结果)是成功的关键。前者需要良好的规划能力和体面的计算速度,而后者的低延迟,以不断能够评估汽车相对于计划的位置,这是有用和无用产品之间的区别。
在这个阶段成功的关键是能够快速评估想法是否可行,我们寻找的信号是我们是否给了用户他们真正需要的东西。结果是,现在是简单、现成的机器学习模型的时候了(或者可能是一个模仿的模型,即根本没有实际的模型!);一旦确定问题可以用机器学习来解决(步骤 1a 的问题已经解决),就没有更多工作要做了。
然而,作为探索可能的价值主张的一部分,探索如何向用户呈现结果通常是相关的。也就是说,哪些指标最能向用户传达信息?结果应该如何呈现(在图表中?作为推荐动作?)以及用户是否能够交互式地探索结果(例如,在上述示例中,在汽车导航系统的地图中四处移动)。准确性和服务时间的相对重要性是什么?显示结果的正确粒度级别是什么?一个 GPS 只能引导你从一个城市到另一个城市,但没有在城市中引导你的分辨率,对大多数人来说不是特别有价值。所有这些问题都处于产品和数据科学的界面上,找到好的解决方案将决定最终产品的成败。
步骤 2a:使产品成熟:提高机器学习性能和价值交付
当你发现了一种既有价值、又令人满意且可行的产品时,科学和工程开发工作就可以开始提高机器学习能力了。这是详细的改进工作,其中解决方案得到强化,新的机器学习架构和模型类型得到彻底探索,边缘情况得到处理等。要明确的是,技术和用户体验的成熟适用于产品的所有方面,而不仅仅是机器学习;在接下来的内容中,我将只关注对机器学习部分特别重要的一些方面,它们是扩展和长寿的基础。
在这一阶段,监控和再培训策略是根据步骤 1a 中的草图制定的,以便为产品提供支持,这一领域也称为 MLOps[12–14]。大多数机器学习(以及其他类型的应用数学引擎)都会随着时间的推移而恶化,而 MLOps 可以确保我们监控性能并主动调整模型,以便它们继续为产品提供工作。没有 MLOps,机器学习模型将很快停止产生有用的结果,产品将毫无用处。产品经理应与技术团队一起在定义 MLOps 战略中发挥积极作用,以确保用户价值主张是首要关注点,关键机器学习性能指标应成为产品经理每日审查的 KPI 的一部分。
MLOps 的一个部分需要特别提及,因为最佳解决方案通常是通过产品设计:数据恶化。有时候,在产品上线后,一个或几个数据源开始转移。在营销情况下,这可能发生在引入之前不属于改变行为的数据集的新产品时(甚至可能是引入我们自己的产品),这可能是新的法规(例如 GDPR),而在其他情况下,这可能是由于物理传感器的退化、生产线图像的上下文变化(背景中的混乱)等。MLOps 将允许主动解决数据中的变化,但它不能保证机器学习模型的质量得以保持。解决这一问题的最佳方式是设计产品,使您能够控制数据生成,或者产品的定位使价值主张在模型无法运行时不会恶化。确定解决这些问题的策略是一个产品问题,应该是一个主动的选择。
步骤 2b:开发产品,但要警惕模型出错带来的意外事故
在讨论本节的细节之前,需要澄清机器学习模型的一些方面。作为开发过程的一部分,这些模型根据历史的、有代表性的数据进行“训练”(拟合),以使其预测能力适合您正在处理的特定问题和数据。但是,如果在模型训练的数据域之外应用,性能通常会下降,如果数据生成过程(例如,不同的用户行为)和我们测量数据的方式(例如,使用不同的传感器读取一个数据源)发生变化,都会发生这种情况。这些方面对如何扩展机器学习驱动的产品有一些影响。
如果事情进展顺利,产品将在某个时候需要扩展。扩展机器学习模型的服务和操作是一项技术挑战(本身就具有挑战性),只要它发生在相同的用户群中,但扩展到新的用户组或细分市场会带来额外的复杂性,因为数据生成过程可能会发生变化。在这种情况下,密切监控通常是一个好策略:由于机器学习模型通常用于帮助决策,并且由于新用户组的决策和/或行为可能与之前的细分市场不同,这些变化将反映在数据和性能监控中。如果有理由相信新的目标用户组具有不同的行为,或者如果数据生成过程的部分对于这个新的组是不同的,则应该预期添加这个新的组将需要调整机器学习模型本身(基本上经过步骤 1a、1b 和 2a),而不仅仅是在这个新的段上打开现有模型的开关。以我们之前使用的 GPS 为例:将英国作为一个新的国家需要对路由引擎进行重大调整,因为所有的路由决策都会受到左侧驾驶的影响。关键的标注是让团队意识到这项重要的工作,并在正确的时间点将它考虑进去。
与任何产品一样,一旦我们推出了具有良好吸引力和规模的产品,“最后”一步是通过添加更多功能来继续改进产品。这包括发现、原型和用户验证的连续循环,以确定每个新功能的产品市场适应性,这在别处有很好的描述[7]。这些新功能中的一些可能是新的基于机器学习的解决方案,与核心产品没有技术关系,如果是这样,它们的开发将遵循上述步骤。这里需要注意的是,任何改变用户行为的新功能也会影响(潜在地破坏)支持传统功能的现有机器学习模型。例如,一家全球能源公司的人力资源部门对每名新员工在公司未来成功的可能性进行评分,但同时将该分数与绩效和其他变量一起使用,以确定哪些员工将获得发展机会;由于这种(可能是无意的)负面反馈循环,在加入时得分不高的人没有获得同样的机会,导致整体人才库的多样性下降和员工流动率上升。注意这些非直观的依赖关系是很重要的,同样重要的是要意识到这些依赖关系可能只存在于某些细分市场中,甚至可能会因细分市场而异。除了对风险本身的认识之外,努力测量现有模型对用户行为和性能的影响,并在引入新功能时进行受控实验,是避免意外颠覆您之前成功的最佳实践。
确认
Simon Kiilerich Vedel(无关系)的一篇全面的评论,包括对这篇文章有重大改进的观点,得到了欣然认可( LinkedIn 简介)。
参考
[1]我在本帖中描述的内容适用于所有使用高级数学建模作为解决问题前提的情况,并不仅限于机器学习问题(甚至适用于传统的数据科学问题)。也就是说,在数学建模、优化和相关领域也会发现类似的挑战。为了简洁起见,我将自始至终使用术语机器学习,但是读者应该记住,所讨论的主题适用范围更广。
[2]https://venturebeat . com/2020/12/16/the-future-of-ai-deployments-reaching-production-is-bright-in-2021/
[3] Irving Wladawsky-Berger:为什么一些人工智能努力成功而许多努力失败,《华尔街日报》,2020 年 1 月 24 日,https://www . wsj . com/articles/Why-Some-AI-Efforts-success-While-Many-Fail-01579901883
[4]https://www . McKinsey . com/industries/semiconductor s/our-insights/scaling-ai-in-the-sector-enable-it-lessons for the-semiconductor-device-makers
[5]https://www . BCG . com/publications/2019/travel-time-push-ai-beyond-pilot-phase
[6]https://www2 . Deloitte . com/content/dam/Deloitte/us/Documents/technology-media-telecom munications/us-TMT-how-do-you-retain-your-data-scientists . pdf
[7]马蒂·卡甘:灵感,https://svpg . com/Inspired-how-to-create-products-customers-love/
[8]天文柜员:先擒猴子,2016https://blog . x . company/先擒猴子-90fd6223e04d
[9] Will Douglas Heaven:谷歌的医疗人工智能在实验室中非常准确。现实生活是一个不同的故事。麻省理工科技评论 2020 年 4 月 27 日,https://www . Technology Review . com/2020/04/27/1000658/Google-medical-ai-accurate-lab-real-life-clinic-covid-diabetes-retina-disease/
[10]吴恩达:人工智能对你的企业来说不必太复杂或昂贵,《哈佛商业评论》2021 年 7 月 29 日https://HBR . org/2021/07/AI-不必对你的企业来说太复杂或昂贵
[11]这篇文章关注的是向用户证明价值是挑战的一部分的情况,因为这是从初创公司到企业普遍面临的情况。但是,应该注意的是,有些领域的价值主张很明确,工作流程/产品开发工作旨在迎合对机器学习的依赖,例如助听器和其他嵌入式信号处理、期权定价和银行欺诈检测等。在这些情况下,步骤 1b 试图缓解的问题就不是大问题了。
[12]对于专家:我自由地使用术语 MLOps,因此它也包括 DataOps(相当于 DevOps 的数据)。这两者之间有着重要的差异,但就这篇博文的目的而言,它们是如何大规模运营机器学习和数据产品的同一问题的两个方面。
[13]https://en.wikipedia.org/wiki/MLOps
[14] Terence Tse 等人,你的人工智能项目将失败的愚蠢原因,哈佛商业评论,2020 年 1 月 8 日,https://HBR . org/2020/06/The-Dumb-Reason-Your-AI-Project-Will-Fail
如何使用 LaTeX 创建出版就绪的绘图
原文:https://towardsdatascience.com/how-to-create-publication-ready-plots-with-latex-4a095eb2f1bd?source=collection_archive---------0-----------------------
实践教程
使用 LaTeX 启动你的绘图之旅,使用 5 种基本的绘图变化
由艾萨克·史密斯在 Unsplash 上拍摄的照片
介绍
如果你曾经在科学杂志上写过一篇文章,那么你很有可能使用过乳胶模板来准备你的手稿。毕竟这是排版文档的行业标准。然而,你们中有多少人考虑过将 LaTeX 作为绘图工具?
LaTeX 基于其图形系统 PGF/TikZ 提供了一个强大的可视化库 PGFPlots。这使得直接在您的。tex 文档。它有一个简单的用户界面,即使是业余程序员也能轻松掌握。然而,我们在网上还有各种各样的绘图选项。无论是流行的数据科学编程语言,如 Python 和 R,它们拥有自己令人印象深刻的数据可视化库,还是绘图软件,如 Origin、Veusz、GraphRobot 和 Orange。大多数这样的选项还提供了处理非常大的数据集和执行复杂的数学计算的灵活性,不幸的是,PGFPlots 库没有这种灵活性。但是,如果这些缺点对您来说不构成问题,PGFPlots 库肯定会为您呈现与当今大多数其他可用选项相比质量最高的图。
然而,尽管不像其他语言/工具那样陡峭,使用 LaTeX 绘图也有自己的学习曲线。PGFPlots 确实提供了自己的综合手册,但是你需要知道在那里搜索什么才能找到你的答案!而且,很多时候,我们寻找的是抽象的想法,而不是完整的图片。这就是像 tex.stackexchange.com 这样的网站来拯救我们的地方。即便如此,在我挖到金子之前,我仍然不得不翻遍成吨的 stackexchange 帖子,经历无数次反复试验。因此,我决定写这篇文章。我希望通过研究科学出版物中可能遇到的 5 种基本绘图类型,向您介绍 LaTeX 绘图的基本知识。每个图将关注 PGFPlots 库中可用的不同类型的定制。要理解本文,您只需要对 LaTeX 有基本的了解。当然,这只是开始您的 LaTeX 绘图之旅。我希望在以后的文章中深入探讨更复杂的情节,因此可以将此视为一系列文章的背景。
所以事不宜迟,我们开始吧!
使用 PGFPlots 绘图
让我们从设置 LaTeX 中绘图的文档序言开始。和其他人一样。tex 文件,我们将从使用\documentclass
命令定义我们的文档类型开始。我们还将为我们的文档添加推荐的编码包。因为我们使用 PGFPlots 绘图,所以我们将调用 PGFPlots 包。下一行中的\pgfplotsset
命令用于为整个文档(或者,正如我们稍后将看到的,文档的一部分)定义一组特定的选项。在这种情况下,我们将整个文档的兼容性选项设置为PGFPlots 1.9
,以确保向后兼容性。注意:最好总是在序言中包含这一行,以避免由于版本更新而导致输出发生变化。
\documentclass[12pt, a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage{pgfplots}
\pgfplotsset{compat=1.9}
接下来,让我们使用\pgfplotsset
命令(名为 myplotstyle )为我们的绘图设置一些常见的样式规范。注意:如果需要,我们可以在特定的安讯士环境中覆盖这些样式。
\pgfplotsset{
myplotstyle/.style={
legend style={draw=none, font=\small},
legend cell align=left,
legend pos=north east,
ylabel style={align=center, font=\bfseries\boldmath},
xlabel style={align=center, font=\bfseries\boldmath},
x tick label style={font=\bfseries\boldmath},
y tick label style={font=\bfseries\boldmath},
scaled ticks=false,
every axis plot/.append style={thick},
},
}
上述样式选项的简要描述:
legend style
、legend cell align
、legend pos
:用于图例造型;在这种情况下,设置一个无边框、\small
字体、左对齐文本的图例,并放置在绘图的东北方向xlabel style
和ylabel style
:用于改变 x 轴和 y 轴标签样式;在这里,它们用于加粗轴标签(\bfseries
用于文本,\boldmath
用于数字轴标签),并将它们对齐轴的中心x tick label style
和y tick label style
:用于设置轴刻度标签样式;这里,文本和数字记号标签的记号字体都设置为粗体every axis plot./append style
:用于设置一个图内每个轴的样式;这里,图中线条和标记的粗细被设置为thick
。注意:这里,我使用了every axis plot
选项来改变图的线宽scaled y ticks=false
:用于防止 PGFPlots 分解轴刻度标签的公共指数
现在,让我们定义一个简单的绘图环境,使用 myplotstyle 来检查它的外观!用于此目的的代码如下所示:
\begin{tikzpicture}
\begin{axis}[
myplotstyle,
]
\end{axis}
\end{tikzpicture}
使用 myplotstyle 看一个简单的情节(图片由作者提供)
由于 PGFPlots 是基于 PGF/TikZ 的,所以每个情节都应该放在\begin{tikzpicture} ... \end{tikzpicture}
给出的画面环境中。在此范围内,我们将定义一个正常的 axis 环境,并为其设置我们的首选样式。在右边,我们可以看到我们的简单坐标轴图看起来是什么样的!注意:我在最后一个样式选项后加了一个逗号, *myplotstyle*
。虽然这不是必需的,但是这是一个很好的实践。这样,您可以减少在以后引入其他样式选项时可能出现的任何潜在错误。
接下来,让我们继续,看看如何使用数据集来创建绘图。对于较大的数据集,谨慎的做法是保存。csv 文件外部。然而,对于较小的数据集,正如我在本文中所使用的,您总是可以在。tex 文件在\begin{document} ... \end{document}
标签之外。这可以使用以下代码来完成:
\begin{filecontents*}{*filename.csv*}
...
\end{filecontents*}
在这两种情况下,我们都可以使用下一节中描述的相同方法来添加绘图数据。
看起来我们现在都准备好继续策划了。让我们开始策划吧!
1.带标记的折线图
我们将创建的第一个图是一个简单的线图(在我们的例子中,有标记)。我将用于此目的的数据集如下所示。注意:为了简洁起见,我只使用前四个月来解释;但是,我也添加了一个图形,显示了包含整个数据集时我们的图看起来会是什么样子。
flights.csv (数据集由 seaborn.pydata.org 提供)
现在,让我们开始绘制数据集。绘制数据集中的列的格式如下所示:
\addplot+[*<options>*] table[x=*colname*,y=*colname*, col sep=*sep*] {*filename.csv*};
要求在每个\addplot
命令后增加一个;
。注意:也可以用 *\addplot[<options>]*
代替 *\addplot+[<options]*
。两者的区别仅仅在于你是希望将你的 *<options>*
追加到默认的 *cycle list*
(选项控制线条样式)还是完全忽略 *cycle list*
。关于 PGFPlots 中可用的不同 *cycle list*
的详细信息,请参考 PGFPlots 手册 第 4 章第 4.7.7 节。
让我们结合到目前为止所学的知识,使用我们的数据集创建一个简单的线图。到目前为止的代码如下所示:
\begin{tikzpicture}
\begin{axis}[
myplotstyle,
]
\addplot+[] table[x=year,y=Jan, col sep=comma] {Fig_lineplot.csv};
\addplot+[] table[x=year,y=Feb, col sep=comma] {Fig_lineplot.csv};
\addplot+[] table[x=year,y=Mar, col sep=comma] {Fig_lineplot.csv};
\addplot+[] table[x=year,y=Apr, col sep=comma] {Fig_lineplot.csv};
\end{axis}
\end{tikzpicture}
基于默认选项的初始绘图(图片由作者提供)
正如我们从左边的图中看到的,要使这个情节吸引人,还需要做大量的工作。
让我们先处理 x 轴和 y 轴标签!添加轴标签非常简单。只需在轴选项中添加xlabel={Year}
和ylabel={No. of passengers}
。另一个明显的样式是添加图例键。这可以通过添加legend entries={Jan, Feb, Mar, Apr}
来实现。此外, myplotstlye 将图例定位在我们绘图的东北方向。从我们的图中可以看出,在这种情况下,这会阻塞图内容。因此,让我们使用legend pos=south east
将该地块的图例移动到东南方。legend pos
的其他选项有south west
、north east
和north west
。您也可以使用选项outer north east
在绘图外添加图例键。
在绘制的图上有一个明显的错误;每个 x 刻度标签代表一年,但显示时带有逗号分隔符。这可以通过将 x 刻度标签的数字格式更改为:
x tick label style={/pgf/number format/.cd,
set thousands separator={}}
我还希望 x-tick 标签旋转 90 度,所以我也将添加rotate=90
到 x-tick 标签样式。最终轴选项如下:
\begin{axis}[
myplotstyle,
legend pos=south east,
legend entries={Jan, Feb, Mar, Apr},
xlabel={Year},
ylabel={No. of passengers},
x tick label style={rotate=90,
/pgf/number format/.cd, set thousands separator={}},
]
}
让我们现在开始设计我们的线条和标记。这些风格选项将包含在\addplot+[*<options>*]
中。让我们为线条/标记添加以下选项:
smooth
:在两点之间插值,使过渡平滑
2.mark=
:您可以指定您喜欢的标记样式(PGFPlots 手册中提供了marks
选项的详细列表)或使用cycle list
中的默认线条样式。在末尾添加一个*
(比如说triangle*
)表示标记需要填充相应的线条颜色
3.mark options={}
:在这里,您可以指定marker size
,是否希望scale
标记大小、fill
用特定颜色等。
带有选项的示例\addplot
命令如下所示:
\addplot+[smooth, mark=diamond*, mark options={scale=2,fill=white}] table[x=year,y=Jan, col sep=comma] {Fig_lineplot.csv};
而且就是这么简单!最终的代码将如下所示:
\begin{tikzpicture}
\begin{axis}[
myplotstyle,
legend pos=south east,
legend entries={Jan, Feb, Mar, Apr},
xlabel={Year},
ylabel={No. of passengers},
x tick label style={rotate=90, /pgf/number format/.cd, set thousands separator={}},
]
\addplot+[smooth, mark=diamond*, mark options={scale=2,fill=white}] table[x=year,y=Jan, col sep=comma] {Fig_lineplot.csv};
\addplot+[smooth, mark=*, mark options={scale=1.5,fill=white}] table[x=year,y=Feb, col sep=comma] {Fig_lineplot.csv};
\addplot+[smooth,, mark=triangle*, mark options={scale=2,fill=white}] table[x=year,y=Mar, col sep=comma] {Fig_lineplot.csv};
\addplot+[smooth, mark=square*, mark options={scale=1.5,fill=white}] table[x=year,y=Apr, col sep=comma] {Fig_lineplot.csv};
\end{axis}
\end{tikzpicture}
这是最后的剧情结局:
定制后的最终剧情(图片由作者提供)
使用整个数据集的示例图如下所示:
定制后所有月份的最终绘图(图片由作者提供)
2.对数轴图
我们要生成的下一个图是一个简单的对数图。我们将使用这个图来探索两个定制:
- 如何使用 PGFPlots 绘制双对数或半对数图?
- 如何使用中的列数据?csv 文件作为轴刻度标签?
用于该图的数据集如下所示。正如我们从数据集中看到的,它有两列:月份和 2020 年印度马哈拉施特拉邦相应的新冠肺炎确诊病例数。只需要绘制这些列中的一列;另一列将用作 x 轴刻度标签。那么我们如何使用 PGFPlots 来绘制呢?
马哈拉施特拉邦 2020 年每月新冠肺炎病例(数据集由 Kaggle 提供);作者修改)
让我们首先根据目前所学的知识创建一个简单的情节:
\begin{tikzpicture}
\begin{axis}[
myplotstyle,
xlabel={Month $(2020)$},
ylabel={No. of confirmed cases},
]
\addplot+[mark=o,mark options={scale=1.5}] table[x expr=\coordindex, y=confirmed, col sep=comma] {Fig_semilogplot.csv};
\end{axis}
\end{tikzpicture}
法线轴和半对数 y 轴上的初始图(图片由作者提供)
在这里,因为我们没有任何要在 x 轴上绘制的列,所以我们使用x expr=\coordindex
来绘制相对于坐标索引的 y 轴数据。我们得到的图显示在左手边。很难从这个情节中正确地推断出疫情的行为。在这种情况下,更谨慎的做法是在双对数轴(在我们的例子中,是半对数轴)上重新排列这些信息。为了将我们的图从正态改为半对数,我们需要将轴环境从begin{axis} ... \end{axis}
修改为\begin{semilogyaxis} ... \end{semilogyaxis}
(因为我们只想将 y 轴修改为对数刻度)。对数轴环境的其他选项包括semilogxaxis
和loglogaxis
。从图中可以看出,在我们的图中使用半对数特征,我们可以更清晰地推断趋势。
但是,剧情还是有很多问题。看一下 x 轴刻度标签,我们可以看到从x expr=\coordindex
提供的默认刻度中无法获得任何信息。控件中的月列值。csv 文件作为 x 轴刻度标签,我们将添加以下轴选项:
table/col sep=comma,
xticklabels from table={*filename.csv*}{*colname*}
首先,我们需要为我们的。csv 文件使用table/col sep
选项。然后,我们可以使用命令xticklabels from table
指示 PGFPlots 从表中的特定列检索 x-tick 标签。
另一个样式偏好是如何显示对数轴刻度标签。一些人喜欢用科学符号来显示它,而另一些人则喜欢数字原样显示。如果您希望将对数轴刻度标签显示为固定数字,那么您可以使用命令log ticks with fixed point
显示所有带有固定数字符号的对数轴。因为半对数图只有一个对数轴,所以使用起来很简单。然而,如果你正在绘制一个双对数图形,并且希望只将一个对数轴修改成固定的数字符号,那么这篇关于 stackexchange 的文章可以帮到你!
我们几乎完成了我们的造型!让我们使用之前学习的命令将 x 标记旋转 90 度。此外,我们将使用xtick
选项为我们的绘图指定刻度位置。xtick
选项的可能值是\empty
、data
或{<list of coordinates>}
。\empty
不会产生刻度线,而{<list of coordinates>}
会在提供的坐标上产生刻度线。因为我们是从。csv 文件,我们将使用xtick=data
在我们的地块的每个坐标产生刻度线。在我们完成之前还有最后一个修改。由于我们使用离散数据点来绘图,我们将删除连接标记的线。为此,PGFPlots 为我们提供了可以添加到\addplot
命令的only marks
选项。注意:相反,如果你想只显示没有标记的线条,你可以使用 *no marks*
选项。
就是这样!我们的半对数图的最终代码将如下所示:
\begin{tikzpicture}
\begin{semilogyaxis}[
myplotstyle,
table/col sep=comma,
xticklabels from table={Fig_loglog_lineplot.csv}{month},
xtick=data,
x tick label style={rotate=90},
xlabel={Month $(2020)$},
ylabel={No. of confirmed cases},
log ticks with fixed point,
]
\addplot+[only marks, mark=o, mark options={scale=1.5}] table[x expr=\coordindex, y=confirmed, col sep=comma] {Fig_loglog_lineplot.csv};
\end{semilogyaxis}
\end{tikzpicture}
在这里,我们可以看到我们对应的情节是什么样子的:
定制后的最终剧情(图片由作者提供)
3.多轴图
现在开始我们的下一个情节!让我们看看如何绘制第二个 y 轴。为了便于绘图,我将 seaborn (Python 绘图库)提供的 tips 数据集修改为两个独立的数据集。csv 文件(午餐时间的小费金额和晚餐时间的小费金额)。注意:您也可以在单个。csv 文件来绘制相同的图形。
tips.csv (数据集由 seaborn.pydata.org 提供;作者修改)
我们将首先写下我们感兴趣的双轴环境的规格。
\begin{tikzpicture}%% axis 1 %%
\begin{axis}[
myplotstyle,
scale only axis,
axis y line*=left,
xlabel={Total bill $(\$)$},
ylabel={Tips $(\$)$},
]
\addplot+[only marks, mark=*, mark options={scale=1.5, fill=white}] table[x=total_bill,y=tip, col sep=comma] {Fig_multiaxisplot_1.csv};
\end{axis}%% axis 2 %%
\begin{axis}[
myplotstyle,
scale only axis,
axis y line*=right,
axis x line=none,
ylabel={Tips $(\$)$},
]
\addplot+[only marks, mark=triangle*, mark options={scale=1.5, fill=white}] table[x=total_bill,y=tip, col sep=comma] {Fig_multiaxisplot_2.csv};
\end{axis}
\end{tikzpicture}
现在,我们将两个环境相互叠加。为此,我们将在\begin{tikzpicture}
之后立即使用\pgfplotsset{set layers}
选项。还需要指定一些附加的样式选项:
axis y line*=left/right
:指定哪个数据集显示在哪个 y 轴上。注:***
表示轴没有箭头axis x line=none
:隐藏第二个图的 x 轴线scale only axis
:强制两个 y 轴尺寸相同
合并后的代码现在看起来像这样:
\begin{tikzpicture}
\pgfplotsset{set layers}
%% axis 1 %%
\begin{axis}[
myplotstyle,
scale only axis,
axis y line*=left,
xlabel={Total bill $(\$)$},
ylabel={Tips $(\$)$},
]
\addplot+[only marks, mark=*, mark options={scale=1.5, fill=white}] table[x=total_bill,y=tip, col sep=comma] {Fig_multiaxisplot_1.csv};
\end{axis}
%% axis 2 %%
\begin{axis}[
myplotstyle,
scale only axis,
axis y line*=right,
axis x line=none,
ylabel={Tips $(\$)$},
]
\addplot+[only marks, mark=triangle*, mark options={scale=1.5, fill=white}] table[x=total_bill,y=tip, col sep=comma] {Fig_multiaxisplot_2.csv};
\end{axis}
\end{tikzpicture}
基于这些规格的初始图如下所示:
将两个轴分层后的初始图(图片由作者提供)
我们可以添加什么样式选项来使这个情节更有吸引力?让我们从使两个 y 轴限值相同开始。这可以通过为两个轴添加ymin
和ymax
来完成。让我们也改变左纵坐标的颜色为蓝色,右纵坐标为红色。我们通过为两个轴设置选项y axis line style
、y tick label style
和ylabel style
来实现这一点。我们还将标记颜色与其对应的轴颜色进行匹配。
目前的代码是:
\begin{tikzpicture}
\pgfplotsset{set layers}
%% axis 1 %%
\begin{axis}[
myplotstyle,
scale only axis,
axis y line*=left,
ymin=0, ymax=7,
y axis line style={blue},
y tick label style={blue},
ylabel style={blue},
xlabel={Total bill $(\$)$},
ylabel={Tips $(\$)$},
]
\addplot+[only marks, mark=*, mark options={scale=1.5, fill=white}] table[x=total_bill,y=tip, col sep=comma] {Fig_multiaxisplot_1.csv};
\end{axis}
%% axis 2%%
\begin{axis}[
myplotstyle,
scale only axis,
axis y line*=right,
ymin=0, ymax=7,
axis x line=none,
y axis line style={red},
tick label style={red},
ylabel style={red},
ylabel={Tips $(\$)$},
]
\addplot+[only marks, mark=triangle*, color=red, mark options={scale=1.5, fill=white}] table[x=total_bill,y=tip, col sep=comma] {Fig_multiaxisplot_2.csv};
\end{axis}
\end{tikzpicture}
这就是我们的地块现在的样子:
自定义 y 轴样式后的绘图(图片由作者提供)
由于我们的 y 轴标签是相同的,谨慎的做法是添加一个图例,使该图信息更加丰富。我们需要一些调整来为两个轴环境渲染一个单独的图例。为此,我使用了在 stackexchange 上提出的解决方法。我们将向第一个图添加一个标签,并使用该标签为第二个轴环境中的第一个图创建一个图例条目。最终的代码将如下所示:
\begin{tikzpicture}
\pgfplotsset{set layers}
\begin{axis}[
myplotstyle,
scale only axis,
axis y line*=left,
ymin=0, ymax=7,
y axis line style={blue},
y tick label style={blue},
ylabel style={blue},
xlabel={Total bill $(\$)$},
ylabel={Tips $(\$)$},
]
\addplot+[only marks, mark=*, mark options={scale=1.5, fill=white}] table[x=total_bill,y=tip, col sep=comma] {Fig_multiaxisplot_1.csv};
\label{multiplot:plot1}
\end{axis}
\begin{axis}[
myplotstyle,
scale only axis,
axis y line*=right,
ymin=0, ymax=7,
axis x line=none,
y axis line style={red},
y tick label style={red},
ylabel style={red},
ylabel={Tips $(\$)$},
legend pos=south east,
]
\addlegendimage{/pgfplots/refstyle=multiplot:plot1}\addlegendentry{Tips during lunch hour}
\addplot+[only marks, mark=triangle*, color=red, mark options={scale=1.5, fill=white}] table[x=total_bill,y=tip, col sep=comma] {Fig_multiaxisplot_2.csv};
\addlegendentry{Tips during dinner hour}
\end{axis}
\end{tikzpicture}
从上面的代码中我们可以看到,添加图例条目的另一种方式是在\addplot
命令后使用\addlegendentry[*<options>*]{*text*}
。我使用了\addlegendimage{}
命令来引用第一个图的线条样式。然后,我们将在相应的\addplot
命令后,添加该轴环境中绘图的图例。注意:为了保持顺序,我在第二个图的 *\addplot*
命令前添加了第一个图的图例。
我们做到了!这是我们最后的情节:
定制后的最终剧情(图片由作者提供)
4.均值图
我们要处理的下一个场景是如何在情节中添加文本。为此,让我们再次使用小费数据集(午餐和晚餐时间数据集的组合)来创建一个均值图。
像往常一样,让我们从利用我们目前所学的知识创建一个基本情节开始:
\begin{tikzpicture}
\begin{axis}[
myplotstyle,
xlabel={Total bill ($\$$)},
ylabel={Tips ($\$$)},
]\addplot+[only marks, mark=square, color=red, mark options={scale=2}] table[x=total_bill,y=tip, col sep=comma] {Fig_multiaxisplot_1.csv};
\addplot+[only marks, mark=square, color=red, mark options={scale=2}] table[x=total_bill,y=tip, col sep=comma] {Fig_multiaxisplot_2.csv};
\end{axis}
\end{tikzpicture}
这就是我们的出发点:
带有基本定制的初始情节(图片由作者提供)
现在,我们需要添加一条均值线和两条标准差线(mean + 2σ
和mean-2σ
;我已经预先计算了必要的值)。为了绘制常量值,我们可以使用格式\addplot+[]{*constant*}
(在这种情况下,我们必须指定需要绘制直线的区域)或\addplot+[] coordinates{*(x,y)*}
。注意:这两个选项我都参考过了。我还指定了常量值图的区域。由于添加一个域会引起轴界限的变化,所以我又添加了*xmin*
*xmax*
*xtick*
*ytick*
。这是我们目前为止的代码:**
**\begin{tikzpicture}
\begin{axis}[
myplotstyle,
xlabel={Total bill ($\$$)},
ylabel={Tips ($\$$)},
xmin=0, xmax=40,
xtick={5,10,15,20,25,30,35},
ytick={1,2,3,4,5,6},
domain=5:35,
]
\addplot+[smooth, only marks, mark=square, mark options={scale=2,fill=white}, color=red] table[x=total_bill,y=tip, col sep=comma] {Fig_multiaxisplot_1.csv};
\addplot+[smooth, only marks, mark=square, mark options={scale=2,fill=white}, color=red] table[x=total_bill,y=tip, col sep=comma] {Fig_multiaxisplot_2.csv};
\addplot+[smooth, no marks, color=black, dashdotted] {2.97};
\addplot+[smooth, no marks, color=black, solid] {0.62};
\addplot+[smooth, no marks, color=black, solid] coordinates {(5, 5.32) (35, 5.32)};
\end{axis}
\end{tikzpicture}**
相应的绘图输出为:
添加均值和标准差线后的绘图(图片由作者提供)
在我们为每条常量线添加描述之前,这个图是不完整的。我在这里使用的方法是在期望的位置添加一个node
。我将基于rel axis cs
(或者,相对轴坐标系;详见下图)。
基于相对轴 cs** 定位节点(图片由作者提供)**
添加节点遵循的格式是:
**\node[*<options>*] at (rel axis cs: *x,y*) {*text*};**
添加文本描述后的最终代码如下所示:
**\begin{tikzpicture}
\begin{axis}[
myplotstyle,
xlabel={Total bill ($\$$)},
ylabel={Tips ($\$$)},
xmin=0, xmax=40,
xtick={5,10,15,20,25,30,35},
ytick={1,2,3,4,5,6},
domain=5:35,
]\addplot+[smooth, only marks, mark=square, mark options={scale=2,fill=white}, color=red] table[x=total_bill,y=tip, col sep=comma] {Fig_multiaxisplot_1.csv};
\addplot+[smooth, only marks, mark=square, mark options={scale=2,fill=white}, color=red] table[x=total_bill,y=tip, col sep=comma] {Fig_multiaxisplot_2.csv};\addplot+[smooth, no marks, color=black, dashdotted] {2.97};
\node [] at (rel axis cs: 0.2,0.51) {Mean};\addplot+[smooth, no marks, color=black, solid] coordinates {(5, 5.32) (35, 5.32)};
\node [] at (rel axis cs: 0.24,0.87) {Mean + $2\sigma$};\addplot+[smooth, no marks, color=black, solid] {0.62};
\node [] at (rel axis cs: 0.23,0.13) {Mean - $2\sigma$};\end{axis}
\end{tikzpicture}**
我们的最终图如下所示:
定制后的最终剧情(图片由作者提供)
5.覆盖在图形上的绘图
现在,我将在本文中处理的最后一个图是覆盖在图像上的图。为此,我将使用下图。注意:我将删除下表中提供的轴和刻度标签,代之以添加我自己的轴和刻度标签。
用于覆盖权重数据集的图像(生长图由疾病控制和预防中心提供——临床生长图)
我将在此图中使用一个虚拟的权重数据集(见下文)。
weights.csv (作者创作)
让我们首先基于数据集创建一个简单的绘图。下面给出了到目前为止带有相应图形的代码:
**\begin{tikzpicture}
\begin{axis}[
myplotstyle,
legend pos=south east,
legend entries={{\large Child 1}, {\large Child 2}},
xlabel={Age (in years)},
ylabel={Weight (in $kg$)},
]\addplot+[only marks, mark options={scale=1.5}, mark=triangle,color=blue] table[x=age,y=weight1, col sep=comma] {Fig_overlaidplot.csv};
\addplot+[only marks, mark options={scale=1.5}, mark=square,color=red] table[x=age,y=weight2, col sep=comma] {Fig_overlaidplot.csv};
\end{axis}
\end{tikzpicture}**
带有默认选项的初始绘图(图片由作者提供)
我们将修改一些东西,使我们的绘图和图像具有匹配的尺寸和轴刻度标签:
- 我们将添加
width
和height
选项来改变我们绘图的维度 - 我们将使用
xmin
、xmax
、ymin
和ymax
选项将我们的轴限制与图像对齐 - 最后,我们将添加
xtick
和ytick
选项,以使我们的绘图轴刻度标签与图像的刻度标签相匹配(我已经用公制单位指定了 y 轴的权重)
我们的代码组合在一起将如下所示:
**\begin{tikzpicture}
\begin{axis}[
myplotstyle,
legend pos=south east,
legend entries={{\large Child 1}, {\large Child 2}},
xlabel={Age (in years)},
ylabel={Weight (in $kg$)},
ymin=5, ymax=105,
ytick={10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100},
xmin=2, xmax=21,
xtick={2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20},
width=13cm, height=15cm,
]\addplot+[only marks, mark options={scale=1.5}, mark=triangle,color=blue] table[x=age,y=weight1, col sep=comma] {Fig_overlaidplot.csv};
\addplot+[only marks, mark options={scale=1.5}, mark=square,color=red] table[x=age,y=weight2, col sep=comma] {Fig_overlaidplot.csv};
\end{axis}
\end{tikzpicture}**
相应的曲线将会是:
覆盖在生长图上的初始图(图片由作者提供)
现在,将图形添加到绘图中的命令是:
**\addplot graphics[*<options>*] {*figure.png*};**
该图背后的中心思想是在我们的绘图轴坐标内拟合图形。因此,我们必须添加带有选项xmin
、xmax
、ymin
和ymax
的\addplot graphics
命令,以匹配主绘图的选项。我还添加了axis on top
选项,将轴线和刻度定位在图像上。
而且就是这么简单!最终代码将是:
**\begin{tikzpicture}
\begin{axis}[
myplotstyle,
legend pos=south east,
legend entries={{\large Child 1}, {\large Child 2}},
xlabel={Age (in years)},
ylabel={Weight (in $kg$)},
ymin=5, ymax=105,
ytick={10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100},
xmin=2, xmax=21,
xtick={2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20},
axis on top,
width=13cm, height=15cm,
]\addplot+[only marks, mark options={scale=1.5}, mark=triangle,color=blue] table[x=age,y=weight1, col sep=comma] {Fig_overlaidplot.csv};
\addplot+[only marks, mark options={scale=1.5}, mark=square,color=red] table[x=age,y=weight2, col sep=comma] {Fig_overlaidplot.csv};
\addplot graphics[ymin=5, ymax=105, xmin=2, xmax=21] {Fig_comparisons.png};
\end{axis}
\end{tikzpicture}**
我们的叠加图看起来会像这样:
定制后的最终剧情(图片由作者提供)
感谢阅读!😃
这篇文章就到此为止了!
图片来源:http://pgfplots.sourceforge.net/
当然,这只是 LaTeX 呈现给我们的整个范围的一小部分!对于初学者来说,用 LaTeX 绘图可能会令人望而生畏。我希望这篇文章能帮助新手不要被大量的信息淹没,并鼓励他们使用这个神奇的工具。如果这篇文章说服了你至少尝试一下用 LaTeX 绘图,我甚至会认为它是成功的!
快乐学习!