TowardsDataScience-博客中文翻译-2020-六十六-
TowardsDataScience 博客中文翻译 2020(六十六)
原文:TowardsDataScience Blog
协议:CC BY-NC-SA 4.0
如何从 Twitter 上抓取推文
原文:https://towardsdatascience.com/how-to-scrape-tweets-from-twitter-59287e20f0f1?source=collection_archive---------1-----------------------
一个基本的 Twitter 抓取教程
使用 Python 从 Twitter 抓取推文的快速介绍
照片来自 P exels
概观
社交媒体可以成为消费者情绪方面的数据金矿。Twitter 等平台有助于保存有用的信息,因为用户可能会发布未经过滤的意见,这些意见很容易被检索到。将这些信息与其他公司内部信息相结合,有助于洞察人们对公司、产品等的总体看法。
本教程旨在简单快速地介绍如何使用 Tweepy 的 Twitter API 或 Dmitry Mottl 的 GetOldTweets3 从 Python 中抓取 tweets。为了给本教程提供指导,我决定集中在两个方面:抓取特定用户的推文和从一般文本搜索中抓取推文。
由于对抓取推文的非编码解决方案感兴趣,我的团队正在创建一个应用程序来满足这一需求。是的,这意味着你不必编写代码来收集数据!我们目前正在对我们的应用 Socialscrapr 进行 Alpha 测试。如果您想参与或在下一个测试阶段开放时被联系,请注册我们下面的邮件列表!
Tweepy vs GetOldTweets3
十二岁
在我们开始实际的抓取之前,了解这两个库都提供了什么是很重要的,所以让我们来分析一下这两个库之间的区别,以帮助您决定使用哪一个。
Tweepy 是一个用于访问 Twitter API 的 Python 库。Tweepy 提供了几种不同类型和级别的 API 访问,如这里的所示,但这些都是针对非常具体的用例。Tweepy 能够完成各种任务,不仅仅是查询 tweets,如下图所示。出于相关性的考虑,我们将只关注使用这个 API 来抓取 tweets。
通过 Tweepy 的标准 API 提供的各种功能列表。
使用 Tweepy 抓取推文有局限性。标准 API 仅允许您检索 7 天前的推文,并且仅限于在 15 分钟的窗口内抓取 18,000 条推文。但是,可以增加该限制,如这里的所示。此外,使用 Tweepy,你最多只能返回 3200 条用户最近的推文。使用 Tweepy 对于那些试图利用 Twitter 的其他功能、进行复杂查询或者希望为每条推文提供最广泛信息的人来说非常有用。
GetOldTweets3
更新:由于 TWITTER 的 API 发生变化,GETOLDTWEETS3 不再运行。SNSCRAPE 已经成为一个免费库的替代品,你可以使用它来清除 TWEEPY 的免费限制。我的文章在这里可用为SNSCRAPE。
GetOldTweets3 由 Dmitry Mottl 创建,是 Jefferson Henrqiue 的 GetOldTweets-python 的改进分支。它不提供 Tweepy 拥有的任何其他功能,而是只专注于查询 Tweepy,并且没有 Tweepy 相同的搜索限制。这个包允许你检索大量的推文和一周前的推文。但是,它没有提供 Tweepy 拥有的信息量。下图显示了使用这个包可以从 tweets 中检索到的所有信息。同样值得注意的是,到目前为止,使用 GetOldTweets3 从 tweet 访问地理数据还有一个未解决的问题。
GetOldTweet3 的 Tweet 对象中可检索的信息列表。
使用 GetOldTweets3 是一个很好的选择,对于那些正在寻找一种快速简洁的抓取方式的人来说,或者想要解决标准 Tweepy API 搜索限制的人来说,可以抓取大量的 Tweepy 或超过一周的 tweet。
虽然他们关注的是非常不同的事情,但这两种选择很可能足以满足大多数人通常的大部分需求。直到你有了明确的目标,你才真正需要选择使用哪一个选项。
好了,解释够了。这是一个刮擦教程,所以让我们进入编码。
照片来自像素
更新:我写了一篇后续文章,更深入地探讨了如何从推文中提取更多信息,比如用户信息,以及细化对推文的查询,比如按位置搜索推文。如果你读了这一节,并决定你需要更多,我的后续文章可用 在这里 。
以下章节的 Jupyter 笔记本在我的 GitHub 这里 都有。我创建了从这些示例查询中导出 CSV 文件的函数。
用 Tweepy 刮
Tweepy 的抓取分为两个部分,因为它需要 Twitter 开发人员证书。如果您已经从以前的项目证书,那么你可以忽略这一部分。
获取 Tweepy 的凭据
为了获得证书,你必须在这里申请成为 Twitter 开发者。这需要你有一个 Twitter 账户。申请会问各种各样关于你想做什么样的工作的问题。不要苦恼,这些细节不必涉及广泛,过程也相对容易。
Twitter 开发者登陆页面。
完成申请后,审批过程相对较快,应该不会超过几天。获得批准后,您需要登录并在开发人员仪表板中设置开发环境,然后查看该应用程序的详细信息,以检索您的开发人员凭据,如下图所示。除非您特别请求访问其他提供的 API,否则您现在将能够使用标准的 Tweepy API。
Tweepy 开发人员凭据。
使用 Tweepy 刮擦
太好了,你有了 Twitter 开发者证书,终于可以开始抓取一些推文了。
设置 Tweepy 授权:
在开始之前,Tweepy 必须授权你有资格使用它的 API。下面的代码片段是一个人如何授权自己。
consumer_key = "XXXXXXXXX"
consumer_secret = "XXXXXXXXX"
access_token = "XXXXXXXXX"
access_token_secret = "XXXXXXXXX"auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
api = tweepy.API(auth,wait_on_rate_limit=True)
抓取特定 Twitter 用户的推文:
我关注的搜索参数是 id 和 count。Id 是特定 Twitter 用户的@ username,count 是您想要从特定用户的时间表中抓取的最近推文的最大数量。在这个例子中,我使用 Twitter 首席执行官的@jack 用户名,选择抓取他最近的 100 条推文。大部分的刮码都比较快,比较直接。
username = 'jack'
count = 150try:
# Creation of query method using parameters
tweets = tweepy.Cursor(api.user_timeline,id=username).items(count)
# Pulling information from tweets iterable object
tweets_list = [[tweet.created_at, tweet.id, tweet.text] for tweet in tweets]
# Creation of dataframe from tweets list
# Add or remove columns as you remove tweet information
tweets_df = pd.DataFrame(tweets_list)except BaseException as e:
print('failed on_status,',str(e))
time.sleep(3)
如果您想进一步定制您的搜索,您可以在这里查看 api.user_timeline 方法中可用的其余搜索参数。
从文本搜索查询中抓取推文:
我重点关注的搜索参数是 q 和 count。q 应该是你想要搜索的文本搜索查询,count 也是你想要从这个特定的搜索查询中抓取的最近的 tweets 的最大数量。在这个例子中,我收集了与 2020 年美国大选相关的 100 条最新推文。
text_query = '2020 US Election'
count = 150try:
# Creation of query method using parameters
tweets = tweepy.Cursor(api.search,q=text_query).items(count)
# Pulling information from tweets iterable object
tweets_list = [[tweet.created_at, tweet.id, tweet.text] for tweet in tweets]
# Creation of dataframe from tweets list
# Add or remove columns as you remove tweet information
tweets_df = pd.DataFrame(tweets_list)
except BaseException as e:
print('failed on_status,',str(e))
time.sleep(3)
如果您想进一步定制您的搜索,您可以在此处查看 api.search 方法中可用的其余搜索参数。
推文中还有哪些信息是可以获取的?
使用 Tweepy 进行查询的优势之一是 tweet 对象中包含的信息量。如果你对获取我在本教程中选择的信息以外的其他信息感兴趣,你可以在 Tweepy 的 tweet 对象这里查看完整的信息列表。为了展示获取更多信息是多么容易,在下面的例子中,我创建了一个包含以下信息的 tweet 列表:创建时间、tweet id、tweet 文本、与 tweet 相关联的用户,以及在检索 tweet 时有多少收藏夹。
tweets = tweepy.Cursor(api.search, q=text_query).items(count)# Pulling information from tweets iterable
tweets_list = [[tweet.created_at, tweet.id, tweet.text, tweet.user, tweet.favorite_count] for tweet in tweets]# Creation of dataframe from tweets list
tweets_df = pd.DataFrame(tweets_list)
用 GetOldTweets3 抓取
更新:由于 TWITTER 的 API 发生变化,GETOLDTWEETS3 不再运行。SNSCRAPE 已经成为一个免费库的替代品,你可以使用它来清除 TWEEPY 的免费限制。我的文章在这里可用为SNSCRAPE。
使用 GetOldTweets3 不像 Tweepy 那样需要任何授权,只需要 pip 安装库就可以马上上手。
抓取特定 Twitter 用户的推文:
我关注的两个变量是用户名和计数。在这个例子中,我们使用 setUsername 方法从特定用户那里抓取 tweets,并使用 setMaxTweets 设置要查看的最近 tweets 的数量。
username = 'jack'
count = 2000# Creation of query object
tweetCriteria = got.manager.TweetCriteria().setUsername(username)\
.setMaxTweets(count)
# Creation of list that contains all tweets
tweets = got.manager.TweetManager.getTweets(tweetCriteria)# Creating list of chosen tweet data
user_tweets = [[tweet.date, tweet.text] for tweet in tweets]# Creation of dataframe from tweets list
tweets_df = pd.DataFrame(user_tweets)
从文本搜索查询中抓取推文:
我关注的两个变量是 text_query 和 count。在这个例子中,我们使用 setQuerySearch 方法从文本查询中抓取 tweets。
text_query = 'USA Election 2020'
count = 2000# Creation of query object
tweetCriteria = got.manager.TweetCriteria().setQuerySearch(text_query)\
.setMaxTweets(count)
# Creation of list that contains all tweets
tweets = got.manager.TweetManager.getTweets(tweetCriteria)# Creating list of chosen tweet data
text_tweets = [[tweet.date, tweet.text] for tweet in tweets]# Creation of dataframe from tweets list
tweets_df = pd.DataFrame(text_tweets)
通过组合 TweetCriteria 搜索参数,可以进一步定制查询。所有当前可用的搜索参数如下所示。
当前 TweetCriteria 搜索参数。
使用多个搜索参数的查询示例:
以下堆叠查询将返回 2019 年 1 月 1 日至 2019 年 10 月 31 日之间发布的 2000 条与 2020 年美国大选相关的推文。
text_query = 'USA Election 2020'
since_date = '2019-01-01'
until_date = '2019-10-31'
count = 2000# Creation of query object
tweetCriteria = got.manager.TweetCriteria().setQuerySearch(text_query)
.setSince(since_date).setUntil(until_date).setMaxTweets(count)# Creation of list that contains all tweets
tweets = got.manager.TweetManager.getTweets(tweetCriteria)# Creating list of chosen tweet data
text_tweets = [[tweet.date, tweet.text] for tweet in tweets]# Creation of dataframe from tweets list
tweets_df = pd.DataFrame(text_tweets)
如果你想联系我,不要害怕在 LinkedIn 上联系我
参考
如果你感兴趣,注册我们的 Socialscrapr 邮件列表:https://upscri.be/3kcmqx
我的后续文章深入研究了这两个包:https://towards data science . com/how-to-scrape-more-information-from-tweets-on-Twitter-44fd 540 b8 a1f
帮助设置并提供几个示例查询的 snscrape 文章:https://medium . com/better-programming/how-to-scrape-tweets-with-snscrape-90124 ed 006 af
包含本教程的 Twitter 抓取器的 GitHub:https://GitHub . com/martink beck/TwitterScraper/tree/master/basics craper
增加 Tweepy 的标准 API 搜索限制:https://bhaskarvk . github . io/2015/01/how-to-use-twitters-search-rest-API-most-effectively。/
tweepy GitHub:https://github.com/tweepy/tweepy
getoldtweets 3 GitHub:https://github.com/Mottl/GetOldTweets3
如何用 Python 抓取 Youtube 评论
原文:https://towardsdatascience.com/how-to-scrape-youtube-comments-with-python-61ff197115d4?source=collection_archive---------8-----------------------
从头开始构建 NLP 数据库
来源:https://unsplash.com/photos/UfseYCHvIH0
任何自然语言处理项目的第一部分都是获取数据库。事实上,清洗和标记整个数据集只适用于 Kaggle,而不是在现实生活中。
当谈到情感分析项目时,我觉得 Youtube 评论代表了一个巨大的、未被充分利用的数据来源。您可以轻松获得所有观众对某个特定主题(如视频)的看法。
了解了所有这些,下面是如何一步一步地从 Youtube 视频中抓取评论。
以下是我将收集评论的视频:【https://www.youtube.com/watch?v=kuhhT_cBtFU】T2&t = 2s
这是 CNN 发布的一段视频,显示了 6 月 12 日发生在亚特兰大的逮捕和枪杀 Rayshard Brooks 的事件。
所以首先,别忘了从右边这里安装一个 from 驱动。你还应该安装谷歌浏览器。现在已经完成了,让我们导入我们需要的库:
import time
from selenium.webdriver import Chrome
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
这里需要 Selenium,因为 Youtube 是 JavaScript 渲染的,这是 BeautifulSoup 无法处理的。
所有其他模块都是必需的,因为 Youtube 评论是动态加载的,这意味着它们只有在你向下滚动页面时才可见。因此,我们需要一个能够:
- 向下滚动
- 等待评论出现
- 删除评论
- 重复我们想要的任何范围。
下面是实现这一点的循环。
这就是它的工作原理:
- 用 driver.get 函数访问你想要的 URL。
- 使用 wait.until 和EC . visibility _ of _ element _ located向下滚动并等待,直到所有内容都可见。
- 通过在当前查看的页面中找到所有的 #content-text 元素(这就是我们想要的,正如你在下面看到的)来收集评论。
4.将注释添加到数据列表中。
要从另一个视频中收集评论,你只需更改网址即可!就这么简单。
在这里,我重复循环 200 次,收集了大约 1400 条评论。数据如下所示:
import pandas as pd
df = pd.DataFrame(data, columns=['comment'])
df.head()
这就是了。现在,您将能够使用这些数据来启动您的 NLP 项目。
感谢阅读,我希望这有所帮助!
成为会员:https://francoisstamant.medium.com/membership
如何用 KDTree 搜索数据
原文:https://towardsdatascience.com/how-to-search-data-with-kdtree-aad5c82ebd99?source=collection_archive---------38-----------------------
给你一个任务,在一个巨大的数据集中查找某个范围内的数据,你能快速有效地找到它吗?
克里斯托夫·鲁舍夫在 Unsplash 上拍摄的照片
动机
想象一下,你记录了你所在地区每天的游客数量。要求你报告从 2 月 2 日到 3 月 2 日的旅客人数。假设这些数据被排序,你如何在短时间内找到这个范围内的数据?这是一个范围搜索问题的陈述。
作者照片
这似乎是一个简单的问题。我们能从左到右检查所有数据吗?是的,但是如果我们有大量的大数据,这将花费大量的时间,还没有考虑到我们的数据可能是 k 维的。
这个问题可以像 2D 地图一样推广到二维。
作者照片
我们可以将这个空间分成一个规则的网格 MxM,而不是在这个空间中搜索每一厘米。然后确定完全落在范围内的单元格和与范围相交的单元格。
我们将包括完全落在范围内的单元格的所有数据,并检查所有未完全包括的单元格的单个数据。这种方法的伟大之处在于,我们可以快速排除不在范围内的数据并缩小搜索范围。
作者照片
但是,如果我们的数据是不一致的,这意味着在一些地区有数据的簇而在其他地区只有很少的数据,那该怎么办呢?
- 如果我们选择的网格太少(M 小),我们将在一个单元格中有许多数据点。性能将接近顺序搜索之一。
- 如果我们选择许多网格(M 大),我们可能会有太多的空单元格和空间浪费。
由于在现实生活中,我们经常需要处理像地图这样的非均匀数据,我们需要一种更好的方法。
从阿切努比斯取回
当处理如上所述的集群数据时,使用规则的网格会导致糟糕的行为。这就是为什么保持预先分割数据的想法是理想的,但是要根据数据密度进行分割!
一个你可能不知道的小秘密:我将介绍的数据结构是从 sklearn 创建对 KNearest 邻居的健壮性的实现,而不是众所周知的 KNearest 邻居算法的实现。
空间划分树
在考虑 k 维之前,我们先从 2 维开始。我们得到这样的数据点
作者照片
我们将在轴(x 或 y)上的中值处分割数据,而不是将数据分割成等宽的网格。我们可以从沿着 y 轴的中间值开始,将平面分成两半。
作者照片
然后在平面的每一半中,通过选择穿过每个细分中的中值的垂直线,继续将细分分成两个相等的细分。
作者照片
我们在两个区域中递归地重复相同的过程,直到在相应的分割元素中不再有点(或者我们决定的点数)。
作者照片
使用这种方法,我们将能够根据数据的密度对其进行分区!那么这个方法的底层数据结构是什么呢?
作者照片
它与二叉查找树非常相似,但又不完全相同。
- 由于数据首先在 y 轴上拆分,因此 y 是根节点。
- 子对象是 x,因为每个半平面都在 x 轴上分割。
- 左侧子树节点的所有 x 值都低于根节点的 x 值。
- 右边的子树节点的所有 x 值都高于根节点的 x 值。
- 在两个轴之间交替,直到我们到达极限。
查找范围内的数据
目前为止听起来不错。但是我们如何使用这种数据结构来搜索特定范围内的数据呢?
作者照片
好消息是,一旦我们创建了一个二维树,查找数据就变得简单多了。
作者照片
我们从树根开始访问树节点:
- 如果节点在查询范围内,则将其添加到答案中****
- 如果查询的范围与左子树定义的区域相交,则探索它
- 如果查询的范围与左子树定义的区域相交,则探索它
KdTree 示例
假设我们有一个 ECOBICI 站点(墨西哥城市自行车公共共享系统)位置的数据集。我们的任务是找到一定范围内的数据。正如我们所看到的,一些地区的站点比其他地区更密集。
要查看如何使用 Kdtree 拆分上面的数据,克隆这个 repo
git clone [https://github.com/khuyentran1401/kdtree-implementation](https://github.com/khuyentran1401/kdtree-implementation)
然后 cd 到本地机器中的 kdtree-implementation 目录并运行
python ecobi.py
您应该看到上面数据的 kd 树表示。线条越多的区域表示该区域的集群越密集。
要查找特定区域的范围,请运行
python findrange.py
您应该会看到输入范围的提示。假设您在 x 轴上选择了-1 到 1 之间的范围,在 y 轴上选择了-1 到 1 之间的范围,您应该会看到该范围内的数据坐标。
厉害!使用 KdTree,您可以在几秒钟内找到特定范围内的数据。尽管我们没有介绍如何使用 KdTree 搜索最近点,但是 KdTree 也可以有效地用于 Sklearn 的 KNearestNeighbor。
结论
恭喜你!你已经学习了什么是 KdTree 及其应用。要了解如何实现它并将其用于您的数据,请查看我的 Github repo 。
我喜欢写一些基本的数据科学概念,并尝试不同的算法和数据科学工具。你可以通过 LinkedIn 和 Twitter 与我联系。
如果你想查看我写的所有文章的代码,请点击这里。在 Medium 上关注我,了解我的最新数据科学文章,例如:
** [## 凸包:包装数据的创新方法
如何利用包装算法实现数据可视化
towardsdatascience.com](/convex-hull-an-innovative-approach-to-gift-wrap-your-data-899992881efc) [## 如何用 Github 组织你的数据科学文章
被新信息淹没?现在,您可以轻松地跟踪文章并为其创建自定义注释
towardsdatascience.com](/how-to-organize-your-data-science-articles-with-github-b5b9427dad37) [## 如何在 10 分钟内为您的数据科学产品组合创建一个优雅的网站
你需要做的就是编辑
towardsdatascience.com](/how-to-create-an-elegant-website-for-your-data-science-portfolio-in-10-minutes-577f77d1f693) [## 如何用图论可视化社交网络
找出《权力的游戏》中的影响者
towardsdatascience.com](/how-to-visualize-social-network-with-graph-theory-4b2dc0c8a99f) [## 如何用 Word2Vec 解决类比问题
美国之于加拿大,就像汉堡之于 _?
towardsdatascience.com](/how-to-solve-analogies-with-word2vec-6ebaf2354009)**
如何获得你真正想要的数据科学职位
原文:https://towardsdatascience.com/how-to-secure-a-data-science-role-you-actually-want-169afc52019b?source=collection_archive---------58-----------------------
布鲁斯·马斯在 Unsplash 上的照片
当承担与人工智能相关的角色时,必须做的事情没有被充分提及
数据科学,21 世纪最性感的工作。这种描述促使一个人停止他们正在做的任何事情,以修改长期职业道路。纯粹的勇气和决心体现在开发、改进和自我营销中,以提升在行业中获得职位的前景。然而,就像很多情况一样,在性感的生活之前是丑陋的生活。没完没了的工作申请、社交媒体上的人际关系网(在疫情之前)在大多数情况下会持续好几个月。
突然,当兴趣在自我完全消失之前升起时,一丝希望从内心升起。一个结束长期痛苦的机会,最终实现过去几个月来为完善自己付出的所有努力。
停下!正是在这一点上,许多人做出了厄运的决定。
你可能想要 21 世纪最性感的工作,但是如果你不小心的话,你可能只会得到一个荣誉头衔,“数据科学家”,而不是真正的工作。
背景
时代变了,技术也在发展。人工智能正变得越来越民主化,除了脸书、亚马逊、网飞和谷歌之外,其他公司也进入了我们所知的可能改变生活的领域。现在比以往任何时候都更清楚的是,首席执行官必须理解并利用自动化和人工智能的趋势。
老实说,许多人肯定已经开始注意到了。从医疗保健,到零售,再到体育,团队都在匆忙研究如何采用人工智能来更好地完成他们的工作。尽管如此,正如大多数快速发展的技术一样,至少可以说,人工智能激发了少校 FOMO 、 FUD 和世仇。
“大数据就像青少年性行为:每个人都在谈论它,没有人真正知道如何去做,每个人都认为其他人都在做,所以每个人都声称他们正在做……”—丹·艾瑞里
这些因素导致了对人工智能潜力的巨大怀疑,以及一些关键的误判。然而,这些误判不仅存在于人工智能的道德规范中,而且还严重影响了渴望进入该领域的有志之士,例如许多人对人工智能抱有过高的期望。
Goldbloom 说,在这个领域工作的人会经历很多挫折。不良数据是其中一个主要原因:他们的雇主无法为他们获得结果提供必要的原材料。有些人还抱怨没有明确的问题可以回答。公司可能感觉到了机会,但他们往往不知道如何充分利用他们的数据资产。这也突显出,与数据科学家和机器学习专家一起工作的非专业管理人员缺乏技术知识。
摘自机器学习如何创造新的职业——和问题(2017) 。金融时报
数据科学家离职的原因有许多因素,但如果我们有远见,我们可以评估这些因素,并控制我们可以控制的因素,那么就更有可能降低流失率。
Jonny Brooks-Bartlett 在 2018 年创作了一个名为 的深度故事,这就是为什么这么多数据科学家离开他们的工作岗位 ,详细描述了标题所述的内容。因此,我不会试图重新发明轮子,相反,你可能想读他的故事——我强烈建议你这样做!
弥合期望和现实之间的差距
Modestas Urbonas 在 Unsplash 上拍摄的照片
我们都有抱负。在马斯洛的需求层次中,我们要朝着自我实现的方向前进,其中一个步骤要求我们的安全需求得到满足,包括工作安全。
通过在线搜索,评估一家公司的愿景是否符合我们对自己的期望可能很困难。然而,当有机会与雇主坐在一起时,我们必须能够问一些我们可能会觉得不舒服的问题。换句话说,面试不仅仅是测试你,也就是被面试者,是否具备填补空缺职位所需的软硬技能。相反,受访者应该将面试视为双向对话——一种兼容性测试。从本质上说,面试者是在寻找一个有可能推动公司发展的角色,而被面试者是在试图满足他们走向自我实现的下一个阶段。
在这个阶段,了解雇主在采用人工智能方面的情况也是一个关键因素,因为他们缺乏的任何东西都可能属于你的职责范围。因此,提出问题!"你有一个数据科学家团队在研究任何有趣的问题吗?",“他们的资深/经验丰富的数据科学家在团队中吗?”。“您有现成的数据基础架构吗?”。
问问题的目的是为了清楚地说明如果公司要雇用你,你需要为公司做些什么。请记住,一家采用新技术的公司不知道他们对新技术有什么不了解,而留下与该公司在采用人工智能方面已经在做什么有关的重要问题没有答案,可能会对你的角色实际需要产生严重影响,进而影响你对角色的满意度。
提前驾驭公司政治
约翰·巴克托在 Unsplash 上拍摄的照片
面对现实吧,政治主宰着组织。每个公司都有自己的文化和协议。尽管在进入一个组织之前,我们可能永远无法完全理解这一点,但当今通讯技术的进步使我们很容易对一家公司的运作有一个总体的了解。
期望走进一家公司并改变整个公司在某种程度上是相当妄想的。如果事情在你之前已经运行了很长时间,人们可能不会那么容易受到变化的影响,而这种变化可能是合理的,尽管历史已经表明,它是商业的长期杀手。
在一家公司担任一个角色之前,不仅要研究这家公司做什么,还要研究他们所服务的人、过去的员工和现在的员工的评价。是的,如果可能的话,联系他们所有人。如果一家公司不愿意有效地与客户合作,以确保他们的需求得到满足,或者如果多名员工因为认为他们的贡献没有被听到而离开,那么就必须认真考虑这是否是你想要的工作环境。
人工智能仍未在工业中得到充分发展,这意味着存在大量不确定性。许多人出于无知而不信任它,有些人有正当的理由——比如工作正被人工智能取代。因此,很大一部分工作可能是通过做一些可以提高员工信任度的小任务,让其他团队相信人工智能的好处。然而,如果一家公司的文化,根据他们如何对待过去的客户和员工来判断,没有反映出适应变化的能力,那么你在这个环境中很可能会很痛苦。
当然,你与人交流以获得洞察力的野心并不是八卦公司(不惜一切代价避免),你的目标只是减少进入公司时可能出现的惊讶因素。与其让公司按照你自己的期望发展,不如事先做尽可能多的研究,为你可能会面临的角色建立一个形象。
包裹
获得真正想要的数据科学职位的先决条件主要取决于渴望进入行业的人。如果你从未进入过这个行业,你就不太可能很好地了解这个行业对你的要求,所以你必须通过阅读各种博客和工作规范来建立这种形象,这些博客和工作规范详细说明了数据科学家的角色和职责,而且与行业中的数据科学家交谈也很有用。
尽管我们可能永远无法在进入某家公司之前真正了解它会为我们带来什么,但我们仍有责任获取尽可能多的信息,以设计出该公司工作可能会是什么样的详细的脑海形象。当我们建立起这种心理形象时,我们可以利用这种形象来确定什么样的工作从长远来看可能适合你,并寻找我们认为可能符合这一标准的公司。这并不保证我们第一次就能做对,但它确实减少了我们犯错的机会——如果我们真的犯错了,失败也没什么不好,只要我们能从我们犯的错误中吸取教训。
如果您认为我遗漏了什么,或者您想向我指出什么,或者如果您仍然不确定什么,您的反馈是有价值的。发个回应!
然而,如果你想和我联系,我在 LinkedIn 上是最活跃的,我也很乐意和你联系。
[## Kurtis Pykes -人工智能博客-走向数据科学| LinkedIn
在世界上最大的职业社区 LinkedIn 上查看 Kurtis Pykes 的个人资料。Kurtis 有两个工作列在他们的…
www.linkedin.com](https://www.linkedin.com/in/kurtispykes/)
你可能喜欢的其他故事:
[## 为您的数据科学事业保持动力
我们可以长期保持动力。
towardsdatascience.com](/staying-motivated-for-your-data-science-career-e845f18421e1) [## 数据科学家如何更快地学习
学会学习的有效策略
towardsdatascience.com](/how-to-learn-faster-for-data-scientist-cfd96d317ce6) [## 当你试图成为一名数据科学家时感到沮丧的原因
将最优秀的人与众不同的隐藏技能
towardsdatascience.com](/the-reason-youre-frustrated-when-trying-to-become-a-data-scientist-2d2b8b402811) [## 学习数据科学的 3 个阶段
了解学习的 3 个阶段,以及我们如何将其有效地应用于数据科学学习
towardsdatascience.com](/3-stages-of-learning-data-science-9a04e96ba415)
如何使用 Azure AD 保护 Python Flask Web APIs
原文:https://towardsdatascience.com/how-to-secure-python-flask-web-apis-with-azure-ad-14b46b8abf22?source=collection_archive---------13-----------------------
学习在 web 应用和 Azure SQL 中使用身份和令牌
1.介绍
Python Flask 是创建 web 应用程序的流行工具。使用 Azure AD,用户可以向 REST APIs 进行身份验证,并从 Azure SQL 检索数据。在这篇博客中,创建了一个示例 Python web 应用程序,如下所示:
- 1a:用户登录 web 应用程序并获得一个令牌
- 1b:用户调用 REST API 来请求数据集
- 2: Web 应用程序使用令牌中的声明来验证用户对数据集的访问
- 3: Web app 从 Azure SQL 检索数据。Web 应用程序可以配置为 a)应用程序的托管身份或 b)登录的用户身份用于数据库的身份验证
项目的代码可以在这里找到,架构可以在下面找到。
1.使用 Azure AD 保护 Python Flask web APIs 简介。图片作者。
在本博客的剩余部分,将执行以下步骤:
- 步骤 1:获取令牌并使用令牌调用 api
- 步骤 2:验证令牌中的声明
- 步骤 3a:应用程序管理的身份认证
- 步骤 3b:登录的用户通过认证
要了解如何使用授权或应用程序权限访问 Azure Function 后端,请参见我的后续博客,它与我的博客共享相同的 git repo。
步骤 1:获取令牌并使用令牌调用 api
此示例展示了如何使用 Flask 和 MSAL Python 构建一个 Python web 应用程序,该应用程序登录用户并访问 Azure SQL 数据库。有关协议在这个场景和其他场景中如何工作的更多信息,请参见 Azure AD 的认证场景。在该步骤中,执行以下子步骤:
- 1.1:准备工作
- 1.2:创建和配置应用程序注册
- 1.3:配置 python webapp 项目
- 1.4:运行示例
步骤 1 关注架构的以下部分。
步骤 1:获取令牌并使用令牌调用 api。图片作者。
1.1:准备工作
若要运行此示例,您需要:
- Python 2.7+ 或 Python 3+
- Azure 活动目录(Azure AD)租户。有关如何获得 Azure AD 租户的更多信息,请参见如何获得 Azure AD 租户。
- Git 克隆下面的项目:
git clone https://github.com/rebremer/ms-identity-python-webapp-backend.git
或者下载并解压存储库。zip 文件。
1.2:创建和配置应用程序注册
创建和配置应用程序注册,如下所示:
- 使用此链接中的步骤创建应用注册以创建应用注册。两个备注:
- 使用
http://localhost/getAToken
作为回复网址。如果您在创建过程中没有这样做,可以使用应用程序注册的验证选项卡添加它 - 转到认证并启用隐式授权中的选项 ID 令牌
- 转到证书&秘密创建一个秘密。复制客户端 id 和客户端密码
1.3:配置 pythonwebapp 项目
- 打开
app_config.py
文件,改变下面的变量。 - 在步骤 1.2 中创建应用程序注册时,找到文本
<<Enter_the_Client_Secret_here>>
,并将其替换为您的应用程序密码。 - 找到文本
<<Enter_the_Tenant_Name_Here>>
,用你的 Azure AD 租户名称替换现有值。 - 找到文本
<<Enter_the_Application_Id_here>>
并用步骤 1.2 中应用程序注册的应用程序 ID (clientId)替换现有值。
1.4:运行示例
您需要使用 pip 安装依赖项,如下所示:
$ pip install -r requirements.txt
使用以下命令从 shell 或命令行运行 app.py:
flask run --host localhost --port 5000
当 app 在本地运行时,可以通过 localhost:5000(不是 127.0.0.1:5000)访问。在步骤 1 之后,用户可以使用他们的 Azure AD 凭据登录。在下一步中,设置用户角色,这些角色可用于验证是否允许用户使用 API 检索数据。
步骤 2:验证令牌中的声明
在此步骤中,可以设置令牌中的声明,令牌可以只是 web 应用程序,以验证是否允许用户调用 api。有关令牌声明的更多信息,请参见此链接。执行以下子步骤:
- 2.1:在应用配置中设置配置
- 2.2:向清单添加角色
- 2.3:将用户分配给角色
第 2 步关注架构的后续部分。
步骤 2:验证令牌中的声明。图片作者。
2.1:在应用配置中设置配置
索赔验证是一个可选步骤,可以使用app_config.py
文件中的以下设置启用:AAD_ROLE_CHECK = True
。
2.2:向清单添加角色
按照本教程中的步骤,向步骤 1.2 中创建的应用注册添加角色。显然,应使用以下方法:
"appRoles": [
{
"allowedMemberTypes": ["User"],
"description": "Basic user, only read product data from SQLDB",
"displayName": "basic_user_access",
"id": "a8161423-2e8e-46c4-9997-f984faccb625",
"isEnabled": true,
"value": "basic_user_access"
},
{
"allowedMemberTypes": ["User"],
"description": "Premium user, read all data from SQLDB",
"displayName": "premium_user_access",
"id": "b8161423-2e8e-46c4-9997-f984faccb625",
"isEnabled": true,
"value": "premium_user_access"
}
],
2.3:将用户分配给角色
在链接中解释了用户的分配。作为测试,可以创建两个用户。用户 1 被分配了basic_user_access
,而用户 2 获得了premium_user_access
角色。
下一步,创建 Azure SQL 数据库,并使用应用程序身份从数据库中检索数据。
步骤 3a:应用程序管理的身份认证
在此步骤中,应用程序的托管身份用于检索数据,该数据链接到在步骤 1 中创建的应用程序注册。执行以下子步骤:
- 3a.1:创建 Azure SQL 数据库
- 3a.2:在应用配置中设置配置
步骤 3a 关注架构的以下部分。
步骤 3a:向 Azure SQL 应用托管身份认证。图片作者。
3a.1:创建 Azure SQL 数据库
使用这个链接创建一个 Azure SQL DB,其中可以选择最便宜的 SKU(基本)。确保完成以下工作:
- AdvertureWorks 作为示例数据库安装,可以选择最便宜的数据库(SKU 基本)。
- 使用正确的读者角色将应用程序身份作为用户添加到 Azure SQL 数据库,请参见以下示例
CREATE USER [<<Name of app registration>>] FROM EXTERNAL PROVIDER;
EXEC sp_addrolemember [db_datareader], [<<Name of app registration>>];
3a.2:在应用配置中设置配置
backend_settings 需要设置为 database。还要确保连接中填入了您的设置。由于使用了 app 的 MI,application_permissions 需要指向"https://database.windows.net//。默认”在app_config.py
文件中,也见下文。
# 2\. Type of BACKEND
#
# Option 2a. Database
BACKEND_SETTINGS = {"Type": "Database", "Connection":{"SQL_SERVER": "<<Enter_logical_SQL_server_URL_here>>.database.windows.net", "DATABASE": "<<Enter_SQL_database_name_here>>"}}# Option 3a. Delegated user is used to authenticate to Graph API, MI is then used to authenticate to backend...APPLICATION_PERMISSIONS = ["https://database.windows.net//.default"]
现在,应用程序可以按照步骤 1.4 中的描述运行。当您点击链接(Premium users only) Get Customer data from Database
时,将检索客户数据。随后,当点击链接Get Product data from Database
时,将检索产品数据(前提是在步骤 2 中为用户正确设置了声明或者检查被禁用)
在此步骤中,应用程序的身份用于检索数据。但是,用户的身份也可以通过(AAD passthrough)从数据库中检索数据。
步骤 3b:登录的用户通过认证
在该步骤中,用户本身的身份用于检索数据。这意味着在步骤 1 中创建的用于登录 web 应用程序的令牌也用于对数据库进行身份验证。执行以下子步骤:
- 3b.1:将 Azure SQL DB 范围添加到应用程序注册
- 3b.2:将 AAD 用户添加到数据库
- 3b.3:在应用配置中设置配置
步骤 3b 着重于体系结构的以下部分。
步骤 3b:对 Azure SQL 的已登录用户直通身份验证。图片作者。
3b.1:将 Azure SQL DB 范围添加到应用程序注册
- 修改在步骤 1.2 中创建的应用程序注册。作为委派用户拥有 Azure SQL 数据库的权限。这个在环节中有解释
- 重要提示:Azure SQL 数据库需要管理员同意。这可以通过在权限选项卡中选择默认目录的 Grant_admin 权限来完成,也可以在运行时登录完成
3b.2:将 AAD 用户添加到数据库
因为在这个步骤中使用了 AAD passthrough,所以用户本身应该在 SQLDB 中具有适当的角色,作为外部用户和 datareader。参见下面的例子。
CREATE USER [<<AAD user email address>>] FROM EXTERNAL PROVIDER;
EXEC sp_addrolemember [db_datareader], [<<AAD user email address>>];
如果您想在数据库中的角色成员中获得更多的粒度,read_customer
从 SalesLT 中读取数据。客户,而read_product
从 SalesLT 读取数据。产品)
3b.3:在应用配置中设置配置
通过将 delegated_permissions 设置为[" https://SQL . azure syncapse-dogfood . net/User _ impersonation "],可以在app_config.py
文件中设置 AAD 用户直通身份验证,另请参见下文
# Option 3b. Delegated user is used to authenticate to backend, graph API disabled...DELEGATED_PERMISSONS = ["https://sql.azuresynapse-dogfood.net/user_impersonation"]
现在,应用程序可以按照步骤 1.4 中的描述运行,其中可以使用登录用户的身份从数据库中检索数据。
结论
在这篇博客中,创建了一个从 SQLDB 检索数据的 Python web 应用程序。讨论了用户声明、托管身份和登录用户直通令牌,以验证和授权用户从 Azure SQL 检索数据,另请参见下面的概述。
4.使用 Azure AD 保护 Python Flask web APIs 结论。图片作者。
如何使用 Azure AD、密钥库和 VNETs 保护 Azure 功能
原文:https://towardsdatascience.com/how-to-secure-your-azure-function-data-processing-c9947bf724fb?source=collection_archive---------8-----------------------
使用 Azure AD、密钥库和 VNETs 保护 Azure 功能。然后使用防火墙规则和函数的托管身份连接到 Azure SQL。
A.Azure 功能安全性-简介
Azure Functions 是一个流行的工具,用来创建可以执行简单任务的小代码片段。Azure 功能可以使用队列触发器、HTTP 触发器或时间触发器来触发。Azure 函数的典型模式如下:
- Init:从存储帐户中检索状态
- 请求:端点被另一个应用程序/用户调用
- 处理:使用其他 Azure 资源处理数据
- 响应:将结果回复给呼叫者
模式如下所示,其中数据从 Azure SQL 检索并返回给应用程序/用户。
1.安全 Azure 功能—简介
在这篇博客中,讨论了如何保护 Azure 函数的安全。其中,使用了 Azure AD、托管身份、密钥库、VNET 和防火墙规则。为了创建专用和隔离的 Azure 功能,也可以决定创建单独的 App 服务环境(ASE) 。然而,ASE 可能很难管理,并且涉及更多的成本。因此,在这个博客中没有使用 ASE,而是采用了常规的应用服务计划。结构如下:
- B0。init:Azure 函数的安全存储帐户
- B1/B3。请求-响应:对 Azure 函数的安全访问
- B2。处理数据:从 Azure 函数安全访问 Azure SQL
- C.结论
关于如何保护你的 Azure 数据工厂管道的详细信息,请看这篇博客。在这篇博客中讨论了部署一个定制的 docker 映像作为 Azure 函数来运行 Selenium web scraper。
B0。init:Azure 函数的安全存储帐户
Azure 函数总是附带一个支持存储帐户。在此存储帐户上,可以在文件共享中找到代码,并且日志记录被写入 blob 存储中。在这个博客中,安全帐户的保护如下:
- Azure 功能的托管身份(MI)已启用,此 MI 用于向 Azure 密钥库进行身份验证以获取/设置机密
- 存储密钥存储在密钥库中,而不是默认的应用程序设置中。此外,Azure 功能键存储在这个密钥库中
- VNET 集成已启用 Azure 功能,以便所有出站流量都流经此 VNET
- 添加了 NSG,仅允许到端口 443、1433 和目的地 Azure WestEurope 的出站流量
- 只有 Azure Function 的 VNET 可以使用防火墙规则访问密钥库。
- (可选)只有 Azure Function 的 VNET 可以使用防火墙规则访问支持存储帐户。请注意,这种情况是官方不支持的,请参见此处,它可能会破坏您的应用程序。使用此功能时,如果应用程序仍在工作,则应在部署到生产环境后进行明确测试,如果不工作,则应重新部署应用程序。
下面描述了在 Azure 函数模式中保护存储帐户的安全。
B0。初始化函数安全性
这一步的代码通过使用下面找到,脚本也可以在我的 github 上找到。
**# B0_1\. Login**
Clear-AzContext -Scope CurrentUser -Force Connect-AzAccount
**# B0_2\. Variables, take same id in all B0/B1B3/B2 scripts**
$id = "3405"
$rg = "test-funappsec" + $id + "-rg"
$loc = "westeurope"
$funname = "test-funappsec" + $id + "-func"
$funstor = "testfunappsec" + $id + "stor"
$akv = "test-funappsec" + $id + "-akv"
$funplan = "test-funappsec" + $id + "-plan"
$vnet = "test-funappsec" + $id + "-vnet"
$nsg = "test-funappsec" + $id + "-nsg"
$subnet = "azurefunction"
$addressrange = "10.200.0.0"
**# B0_3\. Create resource group **
az group create -n $rg -l $loc **# B0_4\. Create Storage account **
az storage account create -n $funstor -g $rg --sku Standard_LRS **# B0_5\. Create VNET **
az network vnet create -g $rg -n $vnet --address-prefix $addressrange/16 -l $loc **# B0_6\. create NSG **
az network nsg create -g $rg -n $nsg **# B0_7\. Create firewall rules** # Only allow outbound to WE storage, port 443 and Azure WE
az network nsg rule create -g $rg --nsg-name $nsg -n allow_we_stor_sql --priority 100 --source-address-prefixes VirtualNetwork --source-port-ranges '*' --destination-address-prefixes Storage.WestEurope --destination-port-ranges '443' '1433' --access Allow --protocol '*' --description "Allow storage West Europe 443" --direction Outbound
az network nsg rule create -g $rg --nsg-name $nsg -n allow_azure_internal --priority 110 --source-address-prefixes VirtualNetwork --source-port-ranges '*' --destination-address-prefixes AzureCloud.WestEurope --destination-port-ranges '*' --access Allow --protocol '*' --description "Azure we" --direction Outbound
az network nsg rule create -g $rg --nsg-name $nsg -n deny_all_outbound --priority 130 --source-address-prefixes '*' --source-port-ranges '*' --destination-address-prefixes '*' --destination-port-ranges '*' --access Deny --protocol '*' --description "Deny all outbound" --direction Outbound **# B0_8\. Create subnet with NSG to VNET **
az network vnet subnet create -g $rg --vnet-name $vnet -n $subnet --address-prefixes $addressrange/24 --network-security-group $nsg **# B0_9\. Turn on firewall **
Update-AzStorageAccountNetworkRuleSet -ResourceGroupName $rg -Name $funstor -DefaultAction Deny **# B0_10\. Set service endpoints for storage and web app to subnet ** Get-AzVirtualNetwork -ResourceGroupName $rg -Name $vnet | Set-AzVirtualNetworkSubnetConfig -Name $subnet -AddressPrefix $addressrange/24 -ServiceEndpoint "Microsoft.Storage", "Microsoft.Web", "Microsoft.Sql", "Microsoft.KeyVault" | Set-AzVirtualNetwork
**# B0_11\. Add firewall rules to Storage Account ** $subnetobject = Get-AzVirtualNetwork -ResourceGroupName $rg -Name $vnet | Get-AzVirtualNetworkSubnetConfig -Name $subnet Add-AzStorageAccountNetworkRule -ResourceGroupName $rg -Name $funstor -VirtualNetworkResourceId $subnetobject.Id **# B0_12\. Create Azure Function**
az appservice plan create -n $funplan -g $rg --sku P1v2 --is-linux az functionapp create -g $rg --os-type Linux --plan $funplan --runtime python --name $funname --storage-account $funstor **# B0_13\. Turn on managed identity of Azure Function ** az webapp identity assign --name $funname --resource-group $rg **# B0_14\. Add VNET integration**
az webapp vnet-integration add -g $rg -n $funname --vnet $vnet --subnet $subnet
**# B0_15\. Create key vault **
az keyvault create --name $akv --resource-group $rg --location $loc **# B0_16\. Set policy such that Azure Function can read from AKV ** $objectid_funname = az functionapp identity show -n $funname -g $rg --query "principalId"
az keyvault set-policy -n $akv --secret-permissions set get list --object-id $objectid_funname
**# B0_17\. Set acl on key vault **
az keyvault network-rule add -n $akv -g $rg --subnet $subnet --vnet-name $vnet
**# B0_18\. Get storage connection string and add to key vault ** $storageconnectionstring = az storage account show-connection-string -n $funstor --query "connectionString"
$keyref = az keyvault secret set -n storageconnectionstring --vault-name $akv --value $storageconnectionstring --query "id" $appkeyref = "@Microsoft.KeyVault(SecretUri=" + $keyref + ") " -replace '"',''
**# B0_19\. Set app settings of function** # Function gets function keys from AKV instead of storage account az functionapp config appsettings set --name $funname --resource-group $rg --settings AzureWebJobsSecretStorageKeyVaultConnectionString="" AzureWebJobsSecretStorageKeyVaultName=$akv AzureWebJobsSecretStorageType="keyvault" az functionapp config appsettings set --name $funname --resource-group $rg --settings AzureWebJobsStorage=$appkeyref az functionapp config appsettings set --name $funname --resource-group $rg --settings AzureWebJobsDashboard=$appkeyref **# B0_20\. Done**
B1B3。请求-响应:对函数的安全访问
默认情况下,Azure 功能键用于对 Azure 函数的请求进行身份验证。由于 Azure 功能在 web 应用中运行,因此可以为 Azure 功能启用 Azure AD 身份验证。在这篇博客中,对 Azure 函数的访问是安全的,如下所示:
- 为 Azure 函数启用了 Azure AD,因此只有此 Azure AD 租户中的对象可以调用该函数。Azure AD 中的对象可以是用户、服务主体或托管身份
- (可选)仅将 Azure AD 租户中可以访问该功能的特定对象列入白名单。例如,只有 Azure 数据工厂实例的托管身份可以执行一个函数(参见这个[博客](/(e.g. an ADFv2 managed identity))
- (可选)在 Azure 功能的防火墙规则中添加访问限制
限制对 Azure 函数的访问如下所示。
B1B3。请求-响应安全性
这一步的代码通过使用下面找到,脚本也可以在 my github 上找到。
**# B1B3_1\. Login**
Clear-AzContext -Scope CurrentUser -Force Connect-AzAccount
**# B1B3_2\. Variables, take same id in all B0/B1B3/B2 scripts**
$id = "3405" # take same id in all B0/B1B3/B2 scripts $rg = "test-funappsec" + $id + "-rg"
$funname = "test-funappsec" + $id + "-func" # 0.2 connect to AAD
$Environment = "AzureCloud"
$aadConnection = Connect-AzureAD -AzureEnvironmentName $Environment **# B1B3_3\. Creat App registration **
# step 2 is derived from https://devblogs.microsoft.com/azuregov/web-app-easy-auth-configuration-using-powershell/ $Password = [System.Convert]::ToBase64String($([guid]::NewGuid()).ToByteArray()) $startDate = Get-Date
$PasswordCredential = New-Object -TypeName Microsoft.Open.AzureAD.Model.PasswordCredential $PasswordCredential.StartDate = $startDate $PasswordCredential.EndDate = $startDate.AddYears(10) $PasswordCredential.Value = $Password $identifier_url = "https://" + $funname + ".azurewebsites.net" [string[]]$reply_url = $identifier_url + "/.auth/login/aad/callback" $reqAAD = New-Object -TypeName "Microsoft.Open.AzureAD.Model.RequiredResourceAccess" $reqAAD.ResourceAppId = "00000002-0000-0000-c000-000000000000" $delPermission1 = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList "311a71cc-e848-46a1-bdf8-97ff7156d8e6","Scope"
$reqAAD.ResourceAccess = $delPermission1 $appRegName = $funname + "_easyauth"
$appReg = New-AzureADApplication -DisplayName $appRegName -IdentifierUris $identifier_url -Homepage $identifier_url -ReplyUrls $reply_url -PasswordCredential $PasswordCredential -RequiredResourceAccess $reqAAD **# B1B3_4\. Add new AppRole object to app registration ** # step 3 is derived from https://gist.github.com/psignoret/45e2a5769ea78ae9991d1adef88f6637
$newAppRole = [Microsoft.Open.AzureAD.Model.AppRole]::new() $newAppRole.DisplayName = "Allow MSI SPN of ADFv2 to authenticate to Azure Function using its MSI" $newAppRole.Description = "Allow MSI SPN of ADFv2 to authenticate to Azure Function using its MSI"
$newAppRole.Value = "Things.Read.All"
$Id = [Guid]::NewGuid().ToString() $newAppRole.Id = $Id
$newAppRole.IsEnabled = $true $newAppRole.AllowedMemberTypes = "Application" $appRoles = $appReg.AppRoles
$appRoles += $newAppRole
$appReg | Set-AzureADApplication -AppRoles $appRoles **# B1B3_5\. Add app registration to web app ** $authResourceName = $funname + "/authsettings" $auth = Invoke-AzResourceAction -ResourceGroupName $rg -ResourceType Microsoft.Web/sites/config -ResourceName $authResourceName -Action list -ApiVersion 2016-08-01 -Force $auth.properties.enabled = "True" $auth.properties.unauthenticatedClientAction = "RedirectToLoginPage" $auth.properties.tokenStoreEnabled = "True" $auth.properties.defaultProvider = "AzureActiveDirectory" $auth.properties.isAadAutoProvisioned = "False" $auth.properties.clientId = $appReg.AppId $auth.properties.clientSecret = $Password $loginBaseUrl = $(Get-AzEnvironment -Name $environment).ActiveDirectoryAuthority $auth.properties.issuer = $loginBaseUrl + $aadConnection.Tenant.Id.Guid + "/" $auth.properties.allowedAudiences = @($identifier_url) New-AzResource -PropertyObject $auth.properties -ResourceGroupName $rg -ResourceType Microsoft.Web/sites/config -ResourceName $authResourceName -ApiVersion 2016-08-01 -Force **# B1B3_6\. Create SPN connected to app registration ** $SPN = New-AzADServicePrincipal -ApplicationId $appReg.AppId -DisplayName $appRegName
**# B1B3_7\. Set "User assignment required?" to true in SPN** # (optional, in case you want to whitelist AAD users) #Set-AzureADServicePrincipal -ObjectId $SPN.Id -AppRoleAssignmentRequired $true **# B1B3_8\. Set obj of ADFv2 as only authorized user to log in web app**
# (optional, in case you want to whitelist AAD users) #$adfv2_resource = Get-AzDataFactoryV2 -ResourceGroupName $rg -Name $adfv2_name
#New-AzureADServiceAppRoleAssignment -ObjectId $adfv2_resource.Identity.PrincipalId -Id $newAppRole.Id -PrincipalId $adfv2_resource.Identity.PrincipalId -ResourceId $SPN.Id
**# B1B3_9\. Done**
B2。进程:从函数安全访问 SQLDB
Azure SQL(又名 SQLDB)用于从。在这篇博客中,Azure SQL 的数据处理受到如下保护:
- Azure 功能的托管身份(MI)已启用,此 MI 用于向 SQLDB 进行身份验证
- Azure 函数的 MI 被配置为 SQLDB 中的外部 Azure AD 对象,并被授予读取者角色以检索数据
- 只有 Azure 函数的 VNET 可以使用防火墙规则访问 SQLDB
下面描述了如何限制从 Azure 函数访问 SQLD。
2.在 SQLDB 安全性中处理数据
这一步的代码通过使用下面找到,脚本也可以在 my github 上找到。
**# B2_1\. Login**
Clear-AzContext -Scope CurrentUser -Force Connect-AzAccount
**# B2_2\. Variables, take same id in all B0/B1B3/B2 scripts** $id = "3405" # take same id in all B0/B1B3/B2 scripts $rg = "test-funappsec" + $id + "-rg"
$rg_sql = "test-funappsec" + $id + "-rg"
$loc = "westeurope"
$funname = "test-funappsec" + $id + "-func" $vnet = "test-funappsec" + $id + "-vnet" $subnet = "azurefunction" $sqlserver = "test-funappsec" + $id + "-dbs" $sqldb = "test-funappsec" + $id + "-sqldb" $sqluser = "testfunappsec" + $id + "sqluser" $pass = "<<SQLDB password, use https://passwordsgenerator.net/>>" $aaduser = "<<your AAD email account>>" **# B2_3\. Create logical SQL server and SQLDB**
az sql server create -l $loc -g $rg_sql -n $sqlserv -u sqluser -p $pass
az sql db create -g $rg_sql -s $sqlserver -n $sqldb --service-objective Basic --sample-name AdventureWorksLT **# B2_4\. Configure AAD access to logical SQL server **
# Connect-AzureAD
Set-AzSqlServerActiveDirectoryAdministrator -ResourceGroupName $rg_sql -ServerName $sqlserver -DisplayName $aaduser **# B2_5\. log in SQL with AAD (e.g. via portal query editor/SSMS/VSC) ** # Execute following SQL statement
#CREATE USER [<<your azure function name, equal to $funname>>] FROM EXTERNAL PROVIDER;
#EXEC sp_addrolemember [db_datareader], [<<your azure function name, equal to $funname>>];
**# B2_6\. point app settings to database **
az functionapp config appsettings set --name $funname --resource-group $rg --settings sqlserver=$sqlserver sqldb=$sqldb **# B2_7\. Add firewall rules **
$subnetobject = Get-AzVirtualNetwork -ResourceGroupName $rg -Name $vnet | Get-AzVirtualNetworkSubnetConfig -Name $subnet New-AzSqlServerVirtualNetworkRule -ResourceGroupName $rg_sql -ServerName $sqlserver -VirtualNetworkRuleName $subnet -VirtualNetworkSubnetId $subnetobject.Id **# B2_8\. Upload code Azure Function **
# To create Azure Function in Python, see https://github.com/MicrosoftDocs/azure-docs/blob/master/articles/azure-functions/functions-create-first-function-python.md
# Get code from __init__.py and requirements.txt from this git repo, then run command below func azure functionapp publish $funname
**# B2_9\. Done**
C.结论
Azure 函数是一个流行的工具,用来创建可以执行简单任务的小代码片段。在这篇博客中,讨论了如何保护一个典型的 Azure 函数,如下所示
- 0.init:Azure 函数的安全存储帐户
- 1/3.请求-响应:对 Azure 函数的安全访问
- 2.处理数据:从 Azure 函数安全访问 SQLDB
下面也描述了具有安全性的模式。
C.具有安全性的 Azure 函数模式
来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语 。
如何获得你的第一份数据科学实习
原文:https://towardsdatascience.com/how-to-secure-your-first-data-science-internship-7bbfd8b87bdc?source=collection_archive---------19-----------------------
#3 停止在线申请
赢得实习机会。(图片由来自 Pexels 的 Andrea Piacquadio 拍摄)
5 年前,我疯狂地在黑暗中寻找实习机会,抓住每一个机会。没用。我明白找到一份实习工作有多难,因为我经历过。我甚至支付了被贴上实习标签的培训课程,因为我并不知情。我甚至不再在我的简历中提到他们。
如果你被要求支付实习费用,那就不是实习。
现在时代变了,数据科学世界与 5 年前大不相同。我终于站在了另一边。我面试未来的工程师、分析师和数据科学团队的实习生。作为一名面试官(和许多其他面试官),我在实习生身上寻找某些东西。
你不需要工作经验,但你需要某些其他的东西。这些是你可以控制的事情,可以用来增加获得实习的机会。本文将详细讨论它们。扣起来;你的实习求职将被简化为 7 个简单的步骤!
1.获得技能
现在就开始追求技能!没有获得最基本的相关技能,你真的不能指望得到实习机会。即使你成功了,对不起,但你也活不下去。你如何获得技能?
这没有唯一的公式,但是你可以上在线课程(有很多免费的),但是记住你追求的不是证书,而是技能。你可以从专家们在 Kaggle 上分享的内容中学习。有很多资源是免费的;你需要去寻找它们。
现在就开始追求技能!
如果您仍然停滞不前,这里有一个我不久前写的指南,概述了您需要学习的内容和在哪里找到它们,以及数据科学的一般方法。我强烈建议花点时间来看一下这个。
大学本科需要入学吗?一些公司要求你这样做,但是如果你有技能——确切地说是可展示的技能,大多数公司会很乐意雇佣你。
一旦你获得了技能,你如何展示它们?
2.创建(至少)一个可论证的项目
做你需要做的。(图片由来自 Pexels 的 Andrea Piacquadio 拍摄)
一个可论证的项目组合是你吹嘘自己技能的最佳方式。它是如此令人信服,当它就在那里给面试官看的时候是如此令人信服!
从探索 Kaggle 或 UCI 的数据集开始,或者继续收集数据并构建您的项目。思考一个成功的可演示组合项目的一个好方法是问,它覆盖了端到端机器学习管道的所有典型步骤吗?您是否清理了数据,处理了异常值和类别,构建了模型,评估了它们,并部署了它们?你是否试图有效地解决问题,并能很好地沟通?如果你能回答这些问题是,那么你已经得到了这个项目。
不要展示传统入门问题之外的东西。泰坦尼克号生存预测或虹膜分类,或 MNIST 数字识别是入门和学习的好问题,但不能展示你的投资组合项目。每个人都这样做,你不会有一个区分因素。
你可能已经在你的本科项目中做过这样的项目;你可以微调一下,让它看起来更像样。这个项目应该在你的 GitHub 上,你甚至可以在实习期间把它部署在云上。
你有一个可论证的项目;你会在网上申请每一个职位空缺吗?
3.停止在线申请
我在找实习的时候,曾经在网上申请过。我相信我申请的公司越多,我的机会就越大。因为我是批量申请,所以我会对每份申请使用相同的求职信和相同的简历。我为此付出了很多努力,但没人注意到我。
你答对了问题——我做了其他人都在做的事情,但我希望被注意到。
与软件工程不同,没有确定的数据科学家角色;没有两个职位发布是相同的。数据科学家的角色因公司而异。一家公司需要的不仅仅是数据科学家。例如,大多数公司还需要一名数据工程师、数据分析师、机器学习工程师,这样的例子不胜枚举。他们都在数据科学领域工作,你可能也会喜欢。
你需要对你申请的公司真正感兴趣。看看他们在哪个领域工作,他们的文化是什么样的。根据他们的要求和职位空缺,定制你的简历和求职信。我怎么强调这一点都不为过,定制让你在获得实习机会的道路上更进一步!但是你如何申请呢?
4.获得推荐
这里有一个圈内人的秘密。任何招聘流程的第一步都是从询问现有员工是否认识适合这个职位的人开始的。如果你梦想中的公司的员工认识你,并且看到了你的潜力,猜猜谁会快速进入招聘流程?当其他人的在线申请到达人力资源部时,你已经拿着录取通知书了,我的朋友。
等等,但是我怎么被推荐呢?我知道说起来容易做起来难。但是我在这里告诉你;这是可行的。
你对公司有真正的兴趣。你知道他们在做什么。您已经构建了至少一个可演示的项目。你有这个技能。是你和公司员工建立关系的时候了。
这可以简单到要求对你的项目进行评审(不过要注意他们的时间)。或者是为你将来要做的项目征求一些建议。或者你可以简单地询问他们在公司做什么工作,以及他们是否在招聘实习生。
如果没有空缺,不要推送,而是要求他们随时向你更新。如果一名员工没有回应,没关系,同一家公司可能有许多其他员工愿意回应。我能想到的最好的平台就是 LinkedIn。利用它!
当你对这家公司表现出真正的兴趣时,作为回报,这家公司会给你一次机会。你如何让它有价值?
5.为面试做准备和练习
和朋友一起练习。(照片由塞巴斯蒂安·赫尔曼在 Unsplash 上拍摄)
在面试中尽你最大的努力是非常非常非常重要的。这是你被评估的唯一方法,而且,不要让你的推荐人失望。你可以做一些让你感觉舒服的事情,
- 从 glassdoor 、 geeks for geeks 或类似的网站中找出面试中的期待。在安排面试的时候,你也可以问人力资源部这个问题。一般来说,根据公司的不同,您需要通过技术和编码轮次。
- 查找常见的面试问题,温习你的理论。
- 对你的项目了如指掌,并能自如地从头到尾解释它(在面试中,你可以随意吹嘘它)。
- 在 Leetcode 和 Hackerrank 等常见网站上练习编码。你应该对解决问题有一定程度的了解。
- 和一个朋友轮流练习模拟面试。它可以帮助你减少在面试官面前的紧张感。当你练习这样回答时,你将学会如何更好地组织你的答案。
面试成功后走出房间是有史以来最棒的感觉!你在面试中尽力了。现在怎么办?
6.寻求反馈
结束后,可以向面试官寻求反馈。如果几天后没有收到人力资源部的反馈,也可以要求反馈。大多数公司会毫不犹豫地给你建设性的反馈(除非政策禁止他们这样做),所以去问吧。
如果你第一次做不到,利用反馈来提高自己,并重复这个过程。根据我的经验,在几次面试后,你会开始注意到同样的提问模式,并最终感到自信。你自然会得 a!
最后一步。重要的那个。
7.不要放弃
有时候你可以做好每一件事,但仍然得不到工作。很可悲,但这是事实。对公司的要求可能会改变,你可能会穿疫情,他们可能会冻结招聘,等等。
不断提高自己,获得更多的技能,做更多的项目。建立更强大的专业网络。如果我放弃了,我就不会在这里写这些了。任何人都有更强的理由雇佣你!
当你最终拿到 offer 的时候!(图片由来自 Pexels 的 Andrea Piacquadio 拍摄)
在你走之前
如果你已经走了这么远,谢谢你的阅读。我希望它在某些方面对你有用。最重要的是,请将此分享给正在寻找实习机会的人。如果你在这些步骤中需要更多的指导,请不要犹豫。
我在媒体上根据我的个人经历撰写了大量关于数据科学和机器学习入门的文章。我将非常乐意在 LinkedIn 上与你联系并听取你的反馈。我迫不及待地想看到你成功!
要获得更多关于进入数据科学、令人兴奋的合作和指导的有用见解,请考虑 加入我的电子邮件好友私人列表 。
如何使用 CSRF 保护来保护您的机器学习应用程序?
原文:https://towardsdatascience.com/how-to-secure-your-machine-learning-app-with-csrf-protection-506c3383f9e5?source=collection_archive---------39-----------------------
机器学习技巧
通过真实示例了解 CSRF 保护的内容和原因。
由 Unsplash 上的 Katarzyna Pe 拍摄
那么你已经训练好了你的 ML/DL 模型,现在考虑在云上部署它。最受欢迎的方法之一是将你的模型包装在 Flask 应用程序中,并使用 REST API 提供服务。但是请稍等,让我们为您的应用程序添加一些安全性。我将借助一个真实世界的例子简要解释代码,以及为什么考虑应用程序的安全性很重要。我将尽可能直截了当地介绍实现部分。但是首先,像任何其他教程一样,让我们了解什么是 CSRF,为什么我们真的需要它?
CSRF 到底是什么?
跨站点请求伪造(CSRF),也称为 XSRF、Sea Surf 或 Session Riding,是一种攻击媒介,它欺骗 web 浏览器在用户登录的应用程序中执行不需要的操作。
那是什么意思?让我用最简单的术语来解释它。
我正在做一个个人深度学习项目,它将一张图像(印度纸币)作为输入,并从 10、20、50、100、200、500、2000 新面值的印度货币中预测图像的类别。
问题:我不是一个安全人员,但是在这个项目中,我注意到我的 API 端点现在是公开的。现在的问题是,你为什么要在乎它是否暴露?这对开发者来说意味着什么?
回答:以我的情况来说,互联网上的任何人都可以用所需的数据向我的 app 发送合法的 POST 请求,并获得预测。你真的不希望自己处于这样的场景中,你把上传的图像和预测存储在一个 S3 桶中。如果你使用 AWS 的免费层(像我一样!),那么这些坏人可以立即消耗你的免费等级的免费配额,最终会给你这样的账单。
我在亚马逊网络服务上被开了 14k 美元的账单😱(来源:https://dev . to/juanmanuelramallo/I-was-billed-on-Amazon-web-services-17fn)
我试图在我的本地机器上重现这个场景,毫无疑问,我能够在我的终端上得到预测。成功执行该命令后,输入图像和预测也存储在我的 S3 存储桶中。
这种合法但伪造的请求被称为跨站点伪造请求(CSRF)。现在的问题是…
如何为你的应用程序实现 CSRF 保护?
根据文档,如果您使用 FlaskForm 来处理请求,您已经获得了 CSRF 保护。如果您没有使用 FlaskForm 或发出 AJAX 请求,您可能需要使用所提供的扩展显式地添加另一层安全性。
# app.pyfrom flask import Flask
from flask_wtf.csrf import CSRFProtect, CSRFErrorapp = Flask(__name__)
app.config['SECRET_KEY'] = "anything_unique"
app.config['WTF_CSRF_TIME_LIMIT'] = WTF_CSRF_TIME_LIMIT
CSRFProtect(app)
正如您可能已经猜到的,在第一行中,我们正在导入 Flask 类。这个类的一个实例将是我们的 WSGI 应用程序。在第二行,我们从 flask_wtf 模块导入 CSRFProtect 类。
接下来,我们将创建 Flask 类的实例。在接下来的两行中,我们将设置密钥和 CSRF 令牌的到期时间限制。需要注意的是,没有这个密钥,你就不能真正享受 CSRF 的保护。
注意:CSRF 保护需要一个秘密密钥来安全地签署令牌。默认情况下,这将使用 Flask 应用程序的
SECRET_KEY
。如果您想使用单独的令牌,您可以设置WTF_CSRF_SECRET_KEY
。
我强烈建议您将您的密钥存储在.env
文件中或者作为一个环境变量,这样在将您的代码推向生产时就不会被分发。我会在这篇博客的最后部分谈到WTF_CSRF_TIME_LIMIT
。最后一行是奇迹发生的地方!用ProtectCSRF
扩展注册将会为 Flask 应用启用全球 CSRF 保护。
现在,我们将在表单中添加 CSRF 代币的值。
<!-- index.html --><form method="post" >
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
...
...
...
</form>
然而,官方文档建议在 AJAX 请求的头中添加csrf_token
。
你猜怎么着?我们完了!
来源:https://giphy . com/gifs/intuit quickbooks-Danny-devito-quickbooks-intuit-8jw 82 ndayfmnoyaekm
好吧,你不相信我?这就是证据😅
添加代码后,我在我的终端中执行相同的命令,并得到以下响应。
Flask 应用程序在请求体中找不到csrf_token
,因此出现了错误的请求。
用户化
- 您可以使用
WTF_CSRF_TIME_LIMIT
设置 CSRF 令牌的到期时间。这是 CSRF 令牌的最长期限(秒)。默认值为 3600。如果设置为 None,则 CSRF 令牌在会话生命周期内有效。 - 您还可以在 CSRF 令牌丢失/无效的情况下捕捉错误,并在您的应用程序视图中显示出来。阶级
CSRFError
在这里是我们的救援。您只需要在 Flask 应用程序中定义一个简单的路由来捕获 CSRF 令牌异常。
[@app](http://twitter.com/app).errorhandler(CSRFError)
def handle_csrf_error(e):
return jsonify({"error": e.description}), 400
在上面的代码中,我们捕获了 CSRF 可能出现的异常,并以 JSON 格式返回,状态代码为 400(错误请求)。
您可以根据您的应用进行修改。下面是修改 CSRF 令牌后对 POST 请求的响应。
结束注释
本博客中使用的所有代码片段都是我的印度纸币预测项目的一部分。
我非常乐意与你见面。你可以访问我的个人网站 www.rohitswami.com了解我更多。还有,你可以在 LinkedIn 和 GitHub 上找到我🎉
我很想听到你对这篇文章的反馈。请随意在下面的评论区发送垃圾邮件。😊
来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们并不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语 。
如何在没有机器学习的情况下对客户进行细分
原文:https://towardsdatascience.com/how-to-segment-your-customers-without-machine-learning-a14107c62298?source=collection_archive---------49-----------------------
RFM 分析快速指南
照片由肯尼·罗在 Unsplash
让我们听一个故事。
介绍
致谢:亚历克斯·昆切夫斯基来源:滴滴出行
2020 年, Gifty (一家虚构的公司)受到新冠肺炎局势的重创。零售店关门了,顾客被锁在家里,没有人从 Gifty 买任何东西。
作为一家销售圣诞礼物的商店,我们不能破产。送礼的精神必须永存!
圣诞老人博士,吉夫蒂的首席执行官给我的任务是让吉夫蒂活着。这意味着两件事:
- 削减成本
- 增加收入
来源:维基百科
作为首席营销官,我将通过“牛眼计划”拯救 Gifty。正如“牛眼”这个词所暗示的,我们将把精力集中在重新定位我们的客户上。在我们锁定客户之前,我们必须对他们进行细分。
每当我们谈论客户细分时,我们通常会想到机器学习方法,如 K-NN、K-means 或多项式逻辑回归。由于经济衰退和预算限制,我们没有足够的资源用于机器学习。因此,我将依靠 RFM 分析项目牛眼。
简而言之,牛眼项目将:
- 根据客户的 RFM 指标对客户进行细分
- 将他们的 RFM 措施与其对营销提议的回应率联系起来
- 优化我们目前的营销工作。
什么是 RFM?
RFM 代表:
- 顾客最后一次购买是什么时候?这是通过计算自客户上次购买商品以来所经过的时间(天/月/年)来计算的。
- 频率——客户从我们这里购买的频率是多少?这是通过在一定时间范围内购买的总次数来计算的。
- 一元钱——顾客在我们身上花了多少钱?这是通过在一定时间范围内购买的美元价值来计算的。如果时间框架不明确,建议采用平均支出而不是总支出。
来源: SAS
在计算每个客户的 RFM 值后,我们根据他们的 RFM 值对客户进行分类。例如:
- 前 10%的花费者将被分配一个“5”的 M
- 接下来的 10%将被赋予“4”的 M
- 支出最低的 10%将被分配一个“1”的 M
- 对每个 R、F 和 M 重复这一过程
注意箱子的数量完全由你决定。人们通常以 5 人为一组。
然后,客户被分成 125 个组(5 * 5 * 5)。
根据每个客户的 R、F 和 M 值,我们应该能够粗略估计出一个客户对礼物的获利程度。例如,我们最有利可图的客户应该:
- R = 5,表示最近进行了购买
- 有 F = 5,表明经常购买
- 有 M= 5,表明花了很多钱
然后,我们可以精心定制营销工作,以迎合每个群体,这将在稍后进一步讨论。
改进的 RFM 分割
等等,传统的 RFM 分割方法似乎有一个很大的问题。
- 我们客户的 R、F 和 M 指标之间有很高的相关性,其中
- 经常购买的人很可能是最近购买的。
- 因此,我们有大量 R = 5,F = 5 的客户,但是…
- R = 1,F = 5 的零客户。
- 125 组都很参差不齐!
- 这是一场灾难,因为如果我把所有的预算都花在接触如此庞大的客户群上,圣诞老人会杀了我的。
别担心,有一个 RFM 分割的改进版本:
这将确保在我们的 125 个组中的每一组都有相同数量的客户,因为在每个 R = 1,2,3,4,5 中,我们根据他们的 F 和 m 进一步分成 5 个相等的组。
来源: SAS
三步走 RFM
时间不多了。让我们开始吧!
1.创造原始 RFM 价值
首先,我们必须计算每个客户的 R、F 和 M 值。根据您的数据集,您必须设计您的数据以生成值。一个好的做法是创建 3 个不同的函数,每个函数分别计算 R、F 和 M。
别担心,代码在我的 Github repo 上。
RFM 价值观先于宁滨
2.根据 RFM 标准划分
现在我们有了原始的 RFM 值,我们可以开始使用改进的 RFM 分割方法,也称为嵌套宁滨方法来对它们进行分类。
如果我们观察第 11 行和第 17 行,我们可以看到我们是如何嵌套我们的箱的。
宁滨之后的 RFM 集团
3.将 RFM 指标与营销报价的回应率联系起来
情报必须是可操作的。如果我们不能从中获得任何洞察力,那么对我们的客户进行细分就毫无意义。因此,我决定分析每个细分市场对营销提议的回应率。
请随意将其与任何其他可预测的行为联系起来,如交易的可能性、被收购的可能性或实施欺诈的可能性。
优化营销工作
靶心计划最重要的部分来了。最后一步是开始对我们的分析进行操作。首先,我们放大到排名前五的 RFM 集团。
- 重新激活休眠群体。在前 5 组中,我们观察到有些客户的近期价值较低(长时间没有购买)。因为他们是我们最有利可图的客户,我们应该找出他们停止从 Gifty 购买的原因,并重新激活他们。Gifty 可以利用个性化的营销信息与他们建立关系。
- 奖励顶级 RFM 团体。 Gifty 可以通过免费会员、折扣或免费送货来奖励这些团体,试图让他们购买更多。
- 推出转诊计划。如果顾客向他们的朋友或家人推荐礼物,可以获得奖励。
- 追加销售顶级消费者。Gifty 可以推荐相关产品或新产品,试图向他们追加销售。
我们永远不应该把太多的注意力放在我们的顶级支出者身上。底层消费者也应该得到一些关注。
- 停止联系下 RFM 团体。下 RFM 群体中的许多客户对营销工作根本没有反应。Gifty 应该停止向他们发送邮件或目录来浪费资源。
- 向顶级 RFM 集团输送资源。节省下来的资源可以用于顶级 RFM 集团或其他地方。例如,资金可以用于设计新的方式来接触底层 RFm 群体,如使用社交媒体广告或病毒式营销活动。
- 增加与随机 RFM 群体的接触。对于 Gifty 来说,接触随机的 RFM 群体同样重要。Gifty 应定量地、持续地跟踪其核心指标的变化,如一段时间内的销售额,以确定他们对这些群体的营销工作的有效性。
结论
通过“牛眼计划”,我们观察了如何利用简单的 RFM 分析来优化 Gifty 的营销工作。
每个数据科学家都必须确保他们的数据能够讲述一个故事。数据可以帮助我们。数据中隐藏着大量的信息。我们剩下要做的就是把它挖出来。
参考
代码:https://github . com/bensjx/RFM-Analysis/blob/master/RFM . ipynb
如何选择正确的机器学习算法
原文:https://towardsdatascience.com/how-to-select-the-right-machine-learning-algorithm-b907a3460e6f?source=collection_archive---------30-----------------------
Denys Nevozhai 在 Unsplash 上拍摄的照片
机器学习
实施算法时要考虑的七个关键因素
对于任何给定的机器学习问题,可以应用许多算法,并且可以生成多个模型。例如,垃圾邮件检测分类问题,可以使用各种模型来解决,包括朴素贝叶斯、逻辑回归和深度学习技术,如 BiLSTMs。
拥有丰富的选择是好的,但是决定在生产中实现哪种模型是至关重要的。尽管我们有许多性能指标来评估一个模型,但是为每个问题实现每个算法是不明智的。这需要大量的时间和工作。因此,了解如何为特定任务选择正确的算法非常重要。
在本文中,我们将研究可以帮助您选择最适合您的项目和特定业务需求的算法的因素。我们将通过查看各种因素来帮助您完善您的选择。理解这些因素将帮助您理解您的模型将执行的任务以及您的问题的复杂性。
以下是实现算法时要考虑的因素列表:
- 可解释性
- 数据点和特征的数量
- 数据格式
- 数据的线性
- 训练时间
- 预测时间
- 内存要求
下面我们来仔细看看!
可解释性
当我们谈论算法的可解释性时,我们谈论的是它解释其预测的能力。缺乏这种解释的算法被称为黑盒算法。
像 k-最近邻(KNN)这样的算法通过特征重要性具有很高的可解释性。像线性模型这样的算法通过赋予特征的权重具有可解释性。当考虑你的机器学习模型最终会做什么时,知道算法的可解释性变得很重要。
对于分类问题,如检测癌细胞或判断住房贷款的信用风险,必须了解系统结果背后的原因。仅仅得到一个预测是不够的,因为我们需要能够评估它。即使预测是准确的,我们也必须理解导致这些预测的过程。
如果理解您的结果背后的原因是您的问题的要求,那么需要相应地选择合适的算法。
数据点和特征的数量
在选择合适的机器学习算法时,数据点和特征的数量起着至关重要的作用。根据使用情况,机器学习模型将与各种不同的数据集一起工作,这些数据集在其数据点和特征方面会有所不同。在某些情况下,选择模型归结为理解模型如何处理不同大小的数据集。
像神经网络这样的算法可以很好地处理海量数据和大量特征。但是一些算法,如支持向量机(SVM),只能处理有限数量的特征。选择算法时,一定要考虑数据的大小和特征的数量。
数据格式
数据通常来自开源和定制数据源的混合,因此它也可以是各种不同的格式。最常见的数据格式是分类数据和数字数据。任何给定的数据集可能只包含分类数据、数值数据或两者的组合。
算法只能处理数值数据,因此如果您的数据是分类的或者格式上是非数值的,那么您将需要考虑一个将其转换为数值数据的过程。
数据的线性
在选择模型之前,了解数据的线性是一个必要的步骤。确定数据的线性有助于确定决策边界或回归线的形状,这反过来又会引导我们使用模型。
一些关系,如身高体重,可以用线性函数来表示,这意味着一个增加,另一个通常以相同的值增加。这种关系可以用线性模型来表示。
通过散点图了解数据的线性度(图片由作者创建)
了解这一点有助于你选择合适的机器学习算法。如果数据几乎是线性可分的,或者可以用线性模型表示,那么像 SVM、线性回归或逻辑回归这样的算法是不错的选择。否则,可以使用深度神经网络或集成模型。
训练时间
训练时间是算法学习和创建模型所花费的时间。对于像向特定用户推荐电影这样的用例,用户每次登录时都需要训练数据。但是对于像股票预测这样的用例,模型需要每秒训练一次。所以考虑训练模型所花费的时间是必不可少的。
众所周知,神经网络需要大量时间来训练模型。像 K-最近邻和逻辑回归这样的传统机器算法花费的时间要少得多。有些算法,如随机森林,根据所使用的 CPU 内核需要不同的训练时间。
预测时间
预测时间是模型进行预测所需的时间。对于产品通常是搜索引擎或在线零售店的互联网公司来说,快速的预测时间是平滑用户体验的关键。在这种情况下,因为速度非常重要,如果预测速度太慢,即使结果很好的算法也没有用。
然而,值得注意的是,在一些业务需求中,准确性比预测时间更重要。在我们前面提到的癌细胞例子中,或者在检测欺诈性交易时,情况确实如此。
像 SVM、线性回归、逻辑回归和一些类型的神经网络这样的算法可以进行快速预测。然而,像 KNN 和集合模型这样的算法通常需要更多的时间来进行预测。
内存要求
如果您的整个数据集可以加载到服务器或计算机的 RAM 中,您就可以应用大量的算法。然而,当这不可能时,你可能需要采用增量学习算法。
增量学习是一种机器学习方法,其中输入数据被连续地用于扩展现有模型的知识,即进一步训练模型。增量学习算法旨在适应新数据而不忘记现有知识,因此您不需要重新训练模型。
最后
在为机器学习任务选择算法时,性能似乎是最明显的指标。然而,性能本身并不足以帮助您为工作选择最佳算法。您的模型需要满足其他标准,如内存要求、训练和预测时间、可解释性和数据格式。通过纳入更广泛的因素,你可以做出更有信心的决定。
如果您很难在几个选定的模型中为您的数据选择最佳算法,一种流行的模型选择方法是在验证数据集上测试它们。这将为您提供衡量标准,您可以通过这些标准来比较每个模型并做出最终决定。
当决定实现一个机器学习模型时,选择正确的模型意味着分析你的需求和预期结果。虽然这可能会花费一些额外的时间和精力,但回报是更高的准确性和改进的性能。
谢谢你的阅读。本文原载于 Lionbridge.ai 。我也将在未来写更多初学者友好的帖子。请在媒体上关注我,以便了解他们。我欢迎反馈,可以通过 Twitter ramya_vidiyala 和 LinkedIn RamyaVidiyala 联系我。快乐学习!
如何选择时间序列数据库
原文:https://towardsdatascience.com/how-to-select-time-series-db-123b0eb4ab82?source=collection_archive---------23-----------------------
物联网分析第 3 部分:时间序列引擎的比较
介绍
一般来说,时间序列用例,尤其是物联网领域,增长如此之快,因此为每个特定用例选择正确的存储至关重要。
如今,所有其他数据库引擎或平台都是以面向时间序列的方式销售的,所以让我们试着更深入地了解一下,找出哪一个最适合每个特定的需求。
问题陈述
为了正式确定引擎选择,让我们明确定义成功的输入和标准。作为一个输入,让我们考虑一个遥测数据集。
作为成功的标准,我们有:
- 功能需求的覆盖范围与不同级别的数据查询/分析相关
- 非功能需求的覆盖范围
让我们更具体地定义它们。
遥测数据集
作为物联网数据分析系列文章的继续,让我们使用健身追踪器用例,它很好地代表了典型的物联网用例。数据集(也称为这里的和这里的)由一组观察值组成,每个观察值包含:
- 由传感器/边缘生成的度量名称,即: 心率、心率、步数
- 与时间点、绑定的传感器产生的度量值,即:(2020–11–12 17:14:07,71bpm)、(2020–11–12 17:14:32,93bpm)等
- 标签或上下文或描述其中给定传感器正在生成数据,即:设备型号、地理位置、用户、活动类型等。
功能需求
围绕数据分析有许多不同的可能性,所以让我们将它们分为初级、中级和高级。
基本级别:简单的数据检索
- 随机数据访问:为特定时间点返回适当的度量值
- 小范围扫描:对于特定的时间范围(相当小,根据数据生成的频率,在几分钟或几小时内)返回连续的度量值(即:在其上绘制标准图表)
中级:时间窗归一化
测量事件通常应该在预定义的重复基础上触发,但是数据点定时总是存在偏差。这就是为什么非常需要围绕构建预定义的时间窗口来标准化时间序列数据的能力。
所需的能力包括:
- 构建时间段以正确标准化数据
- 标准化时段上的聚合
- 间隙填充,使用插值在一组离散的已知数据点范围内构建新的数据点。
对于中级容量,值得添加更复杂的诊断分析/特别查询:
- 灵活过滤:根据标签/上下文属性上的谓词过滤数据点,即:根据某个区域、用户或活动类型过滤数据点
- 灵活聚合:标签/上下文属性或其组合上的分组和聚合,即:按活动类型按区域的最大炉膛率。
高级级别:顺序行模式匹配
最高级将包括检查事件序列 是否与特定模式匹配,以执行自检和高级诊断:
- 在特定事件之前有相似的测量模式吗?;
- 什么样的测量可能表明某个事件的原因,例如失败?
到目前为止,很少有数据库支持这样的特性,但是我相信它们会出现的。
在这里,我们可以区分以下能力:
- 找到一系列连续事件,即:会话定义
- 模式匹配:趋势反转,周期性事件
非功能性需求
除了功能性需求之外,考虑非功能性需求也非常重要,这些需求通常是选择的主要驱动因素:
- 可扩展存储:处理大数据量的能力
- 可扩展写入:处理大量并发写入的能力。这与实时数据访问密切相关,即在数据点生成和可供读取之间尽可能缩短延迟的能力。
- 可伸缩读取:处理大量并发读取的能力
- 高成熟度:在市场上的存在和社区支持。
市场上的时间序列数据库和平台
让我们回顾一下市场上有什么可以满足我们的严格需求。有多种选择。这真的很难涵盖所有这些,所以我将尝试描述发动机家族。
带有内置分类功能的 NoSQL
BigTable、HBase、Cassandra、DynamoDB、Accumulo 常用于存储时序数据。有大量关于如何在这些存储上实现时序用例的文章;如何避免热点使用盐等?
****优势:非常适合写入。极其高效地执行基本级别的分析。
****弱势:所有其他类型的分析都不受支持且效率低下
NoSQL 特制时间序列数据库
有一些引擎是作为时间序列数据库从头开始设计的。在大多数情况下,他们是 NoSQL。最突出的例子是 InfluxDB ,它位于所有谷歌搜索的首位。
基于时序类固醇的 MPP SQL 引擎
一些成熟的 MPP 分析引擎,如 Vertica 不断增加新的分析功能,包括与时间序列数据处理相关的功能。但缺点是,从设计上来说,它们不是为高效的流数据摄取而创建的。但是如果微批处理是可接受的,它们可能是许多用例的最佳匹配。
****优势:提供最大的分析能力。
****弱方:实时摄取可能很有挑战性,而且效率不高
注意:Oracle 不是传统的 MPP,但是从功能的角度来看,它支持 MATCH_RECOGNIZE 子句,该子句涵盖了复杂的模式匹配特性
内存数据库
SQL 数据库的内存特性提高了它们处理快速数据接收的能力。由时段规范化支持丰富的 SQL 接口,如 SingleStore MemSQL 数据库对于时间序列用例来说看起来非常有吸引力
****优势:提供触达分析能力。
****弱势:读写的可伸缩性通常有限或者非常昂贵
云时序平台
Azure 和 AWS 最近发布了他们的时序数据服务/平台:
- Azure 时序洞察
- 亚马逊时光流
这些平台涵盖了时间序列数据存储、可视化和查询功能的许多方面。它们内置了热存储、热存储和冷存储之间的数据分离,从拥有成本的角度来看,可以很好地平衡数据存储和检索。
****优势:很好地集成到适当的云基础设施中,提供了范围查询功能以及
****弱点:对于某些用例来说,紧密的云集成可能是一个限制;在市场上出现的时间还太短,不能把它们当作成熟的产品。
其他人
也有其他选择和小众玩家。我有机会使用一个叫做 GeoMesa 平台/框架的例子。这是一个基于 Accumulo/Hbase/Cassandra 等 NoSQL 存储的框架,能够为时态和地理时态数据建立特殊索引;它还通过二级索引提供了额外的灵活性。
****优势:高效的基本时序分析以及良好的缩放水平。地理时态查询支持是一项关键功能,也是物联网数据的一大优势。
****弱势:尽管开发社区非常友好且响应迅速,但它的采用率和成熟度都很低。
汇总比较
请使用我们在下面开头定义的标准来查找不同时间序列存储的高级比较:
哪里
作者图片
结论
这个主题非常广泛,值得一本书来详细介绍,但是我希望这篇文章能够帮助您在时序引擎世界中导航,并帮助您为您的特定用例选择正确的方向。
如何用 Python 发送漂亮的电子邮件——基本指南
原文:https://towardsdatascience.com/how-to-send-beautiful-emails-with-python-the-essential-guide-a01d00c80cd0?source=collection_archive---------8-----------------------
使用 Python 发送带有附件的风格化电子邮件。给多个收件人。
通过 Python 这样的编程语言发送邮件有很多用例。例如,您可能想要管理一个邮件列表而不支付月费,或者在生产代码中出现问题时使用它来通知您。今天,您将学习如何轻松地向多个收件人发送精美的电子邮件。包括附件。
摄白兰度在 Unsplash 上制作品牌
为此,我们将使用 Python 的smtplib
。SMTP 代表简单邮件传输协议,对于你们这些书呆子来说。这是一个简单的库,允许我们发送电子邮件。我们还将使用email
库进行格式化。两者都内置在 Python 中,所以不需要安装任何东西。
如果你更喜欢视频,我为你准备了一份礼物:
今天的日程如下:
- Gmail 设置
- 发送简单的邮件
- 向多个收件人发送电子邮件
- 发送附件
- 发送 HTML 格式的电子邮件
- 结论
内容太多了,让我们开门见山吧。
Gmail 设置
我假设你的 Gmail 账户已经启用了双重认证。如果没有,你应该。我们必须生成一个密码,Python 脚本将使用该密码登录您的帐户并发送电子邮件。
这是一个简单的步骤。只需点击这个网址,你就会看到这样一个屏幕:
作者图片
但是,您不会看到“Python 电子邮件”行。只需点击选择应用下拉菜单,然后点击其他(自定义名称)。输入一个名称(任意),点击生成按钮。
就是这样!像这样的模态窗口将会弹出:
作者图片
只要把密码保存在安全的地方。
现在,您可以打开代码编辑器(或笔记本)并创建一个 Python 文件。以下是电子邮件和密码的库导入和变量声明:
请记住— EMAIL_ADDRESS
变量应该包含您的实际电子邮件地址,而EMAIL_PASSWORD
应该包含几秒钟前生成的应用程序密码。有一种更健壮、更安全的方法可以做到这一点——使用环境变量,但这超出了本文的范围。
您现在可以发送您的第一封电子邮件了。
发送简单的邮件
这是你期待已久的部分。发送电子邮件之前需要几个步骤,如下所示:
- 创建一个
EmailMessage
类的实例 - 指定从、到的和主题——你猜哪个是干什么的
- 设置电子邮件的内容,即邮件本身
- 使用
smtplib
建立安全连接(SSL)并登录您的电子邮件帐户 - 发送电子邮件
听起来工作量很大,但归结起来不到十行代码。以下是片段:
如您所见,我已经将从到到的字段设置为相同的值。这不是你通常会做的事情,但对于测试来说是必不可少的。这是我几秒钟后收到的电子邮件:
作者图片
接下来让我们看看如何向多个收件人发送电子邮件。
向多个收件人发送电子邮件
如果你理解了前一部分,你就会理解这一部分。你只需要改变一件事。
在msg['To']
中,您将不得不指定一个电子邮件列表,而不是指定一个您想要发送到的电子邮件地址(和前面的例子一样)。
代码如下:
你能看出区别吗?发送给多个收件人比预期的要容易,因为你不必手动遍历列表。让我们继续邮件附件。
发送附件
发送附件有点奇怪,直到你掌握了它的要点。你必须用 Python 的with open
语法打开每个附件,并使用EmailMessage
类中的add_attachment
方法来添加附件。
在下面的例子中,这个方法被用来发送一个 PDF 文档。代码如下:
这是我几秒钟后收到的电子邮件:
作者图片
厉害!接下来让我们看看如何创建定制的电子邮件!
发送 HTML 格式的电子邮件
如果你打算发送纯文本的、无风格的或者丑陋的邮件,你可以从你的列表中划掉 inbound。这就是 HTML 和 CSS 发挥作用的地方。
就代码而言,这与上一节中的内容几乎相同。唯一不同的是邮件内容。这次您将使用来自EmailMessage
类的set_content
方法来编写 HTML。CSS 样式是内嵌设置的。
这是我在几分钟内设计出来的:
作者图片
不是很好,但比我们以前的有所改善。这就足够了。让我们在下一部分总结一下。
离别赠言
用 Python 发送电子邮件很容易。Gmail 配置让你可以直接从你的机器上发送邮件,不需要上传任何东西到实时服务器上。如果你问我的话,我觉得这很好。几年前,当我第一次开始通过 PHP 发送电子邮件时,本地主机不是一个选项(根据我的经验)。
你今天已经看到了一堆新概念——从发送电子邮件到前端技术。这仅仅够让你入门,而且网络上有很多更高级的指南。
感谢阅读。
加入我的私人邮件列表,获取更多有用的见解。
喜欢这篇文章吗?成为 中等会员 继续无限制学习。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。
[## 通过我的推荐链接加入 Medium-Dario rade ci
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
medium.com](https://medium.com/@radecicdario/membership)
原载于 2020 年 11 月 2 日 https://betterdatascience.com。
如何将数据从 Google BigQuery 发送到 Google Sheets 和 Excel
原文:https://towardsdatascience.com/how-to-send-data-from-google-bigquery-to-google-sheets-and-excel-eb58436bc398?source=collection_archive---------55-----------------------
来源:沉积照片
了解如何自动快速地将数据从 Google BigQuery 发送到 Google Sheets 和 Excel
Google BigQuery (GBQ)不需要额外的维护成本,可以在不到一分钟的时间内处理您的数据。在本文中,您可以了解如何使用 BigQuery API 将数据从 CSV 和 JSON 文件上传到 GBQ,或者从其他 Google 服务上传数据。今天,我们将告诉你如何从 BigQuery 上传数据到你的最爱——Google Sheets 和 Excel。
如何将数据从 Google BigQuery 导入到 Google Sheets
将数据加载到 Google Sheets 的简单方法是使用 OWOX BI 的 BigQuery Reports 插件。你可以直接从 Google Sheets 的附加组件菜单免费安装,或者从 Chrome 网上商店下载。
图片由作者提供
2.一旦安装了 OWOX BI BigQuery Reports 插件,就可以从存储中加载数据了。为此,请转到 Google Sheets 中的附加组件菜单,将鼠标悬停在 OWOX BI BigQuery 报告上,然后选择添加新报告。
图片由作者提供
2.在屏幕右侧出现的附加菜单中,指定 GBQ 项目的名称。然后,您可以为选定的项目创建新的 SQL 查询,或者从下拉列表中选择以前使用的查询。
图片由作者提供
- 如有必要,为您的查询定义动态参数。然后点击添加&运行。
- 你的数据准备好了!来自 GBQ 的数据将被上传到 Google Sheets 中的一个新表中。
OWOX BI BigQuery Reports 插件的优势:
- 您可以将数据从 BigQuery 加载到 Google Sheets,反之亦然。
- 您可以控制对数据的访问。
- 您可以从 Google Sheets 中一键与同事共享数据。
- 您可以访问一个简单的查询编辑器。
- 报告会自动更新。
您可以在 OWOX 博客上了解更多关于设置 OWOX BI BigQuery Reports 连接器和在 Google Sheets 中自动生成报告的信息。
如何从 Google BigQuery 导入数据到 Excel
- 要将数据从 Google BigQuery 导入 Excel,首先,您需要一个惟一键来运行对 BigQuery 的查询。您可以随时创建此密钥,但请记住它有一个到期日期。
图片由作者提供
如有必要,您可以随时创建新的密钥。
图片由作者提供
您也可以使用撤销密钥按钮或在您的 Google 档案设置中终止当前密钥。
图片由作者提供
2.在 Excel 中,创建一个新工作表,并在中提供以下信息。下面截图所示的格式:
- 您的项目 ID
- 您的唯一密钥
- 你的疑问
图片由作者提供
请注意,如果您的查询超过 256 个字符,Excel 将不会运行它。在这种情况下,您应该将查询拆分成多个部分,并将它们插入相邻的单元格中。
3.接下来,下载 IQY 文件。
4.在 Excel 的数据选项卡中,选择现有连接。在出现的窗口中,点击浏览更多并选择您刚刚下载的 IQY 文件。
图片由作者提供
5.首次连接时,您需要指定数据的显示位置。在当前工作表中选择一个单元格。
图片由作者提供
6.在以下窗口中,指定包含查询、项目 ID 和连接器关键字的单元格的值。
图片由作者提供
准备好了!您的 BigQuery 数据现在将出现在 Excel 中。
作为连接到 Excel 的另一种方法,您可以使用 Magnitude Simba ODBC 驱动程序进行 BigQuery。详细说明可以在 YouTube 上找到:如何将 Google BigQuery 连接到 Microsoft Excel 。
如何通过电子邮件自动发送 Python 应用程序崩溃通知
原文:https://towardsdatascience.com/how-to-send-python-app-crash-notifications-via-email-6fd5c156b49d?source=collection_archive---------43-----------------------
如果您在远程服务器上运行 Python 应用程序,您可能会不时遇到应用程序崩溃。并且您希望尽快知道发生了崩溃,以便尽快修复问题。
照片由 Unsplash 上的尼克·费因斯拍摄
这个小小的代码片段可以帮助你实现这一点。
- 导入所需的 Python 模块(电子邮件、日志和 io)
- 定义电子邮件处理功能。您只需更新您的电子邮件服务器认证详情。
- 定义 Try/Except 循环,其中“Try”部分将包含您的主代码,“Except”部分将捕获应用程序崩溃,并将详细的崩溃描述发送到您定义的电子邮件地址。
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
import logging
from io import StringIO
import smtplibdef send_email_crash_notification(*crash_message*):email = 'your_email@gmail.com'
send_to_email = 'receipent_email@gmail.com'
subject = 'Python application CRASHED!' msg = MIMEMultipart()
msg['From'] = email
msg['To'] = send_to_email
msg['Subject'] = subject
message = *crash_message* msg.attach(MIMEText(message, 'plain')) *# Send the message via SMTP server.* server = smtplib.SMTP('smtp.gmail.com', 587)
server.ehlo()
server.starttls()
server.login('your_email@gmail.com', 'your_password')
text = msg.as_string()
server.sendmail(email, send_to_email, text)
server.quit()
*print*('email sent to ' + *str*(send_to_email)) return True try:
*#Your main code will be placed here
print*(1+1)except *Exception* as e:
log_stream = StringIO()
logging.basicConfig(*stream*=log_stream, *level*=logging.INFO)
logging.error("Exception occurred", *exc_info*=True)
send_email_crash_notification(log_stream.getvalue())
感谢您的阅读,我期待着阅读您的评论!
如果你觉得特别慷慨,你可以在www.buymeacoffee.com/kingmichael给我买杯咖啡。你的支持将极大地帮助我保持动力,写出你喜欢的文章。
由彼得罗·德·格兰迪在 Unsplash 上拍摄的照片
如何使用 TensorFlow 服务不同的模型版本
原文:https://towardsdatascience.com/how-to-serve-different-model-versions-using-tensorflow-serving-de65312e58f7?source=collection_archive---------24-----------------------
了解不同的配置设置,以便使用 TensorFlow Serving 管理不同的模型和模型的不同版本
本文解释了如何使用配置文件在 TensorFlow 服务中管理多个模型和同一模型的多个版本,并简要了解批处理。
先决条件:
将 TensorFlow 模型部署到生产制造 Eas y
照片由 Loverna 在 Unsplash 上的旅程拍摄
您拥有不同架构的 TensorFlow 深度学习模型,或者已经使用不同的超参数训练了您的模型,并且希望在本地或生产中测试它们。最简单的方法是使用一个模型服务器配置文件来服务模型。
模型服务器配置文件是一个协议缓冲文件(protobuf ),它是一种与语言无关、与平台无关的可扩展的、简单而快速的序列化结构数据的方法。
如何创建模型配置文件?
下面是一个样本模型配置文件,它将服务于磁盘上所有版本的“MNIST”模型。
**model_config_list {
config {
name: 'mnist'
base_path: '/models/mnist/'
model_platform: 'tensorflow'
model_version_policy: {all: {}}
}
}**
每个 ModelConfig 指定一个模型,该模型使用以下参数。
名字- 一个可服务的模型名
base_path - 指定查找 servable 版本的路径。
模型 _ 平台- 开发模型的平台。
model_version_policy - 模型的版本策略指示加载哪个版本的模型并提供给客户端。默认情况下,将提供模型的最新版本,并且可以通过更改 model_version_policy 字段来覆盖。
如何加载模型配置文件?
点击阅读如何在 Windows 10 上加载 TensorFlow 服务 Docker 容器
**docker run -p 8501:8501 --mount type=bind,source=C:\TF_serv\TF_model,target=/models/mnist -e MODEL_NAME=mnist -t tensorflow/serving**
列出所有正在运行的 Docker 容器
**docker container list**
或者
**docker ps**
以红色突出显示的容器 Id 和容器名称
将 models.config 文件从 Docker 映像的源复制到目标
**docker cp \TF_serv\TF_model\models.config *ba978f5a9475*:/models/mnist**
将文件复制到 docker 容器时,提供容器 Id,如上所示。
使用 Docker 容器名称或容器 Id 停止 Docker 容器
**docker stop *ba978f5a9475***
最后,使用选项加载模型配置文件
**--model_config_file_poll_wait_seconds**
flag 指示服务器每 60 秒在使用**--model_config_file**
指定的路径检查一次新的配置文件。
**docker run
-p 8501:8501
--mount type=bind,source=C:\TF_serv\TF_model,target=/models/mnist
-e MODEL_NAME=mnist
-t tensorflow/serving
--model_config_file_poll_wait_seconds=60
--model_config_file=/models/mnist/models.config**
如何使用 models.config 文件提供的模型使用模型的具体版本进行推理?
使用 REST API 进行推理请求
json_response = requests.post('[**http://localhost:8501/v1/models/mnist/versions/5**:**predict'**](http://localhost:8501/v1/models/mnist/versions/5:predict'), data=data, headers=headers)
因为上面指定的 models.config 文件将加载磁盘上的所有版本;我已经加载了版本 5。
下面显示了调用模型的特定版本进行推理的一般方法。
**/v1/models/*<model name>*/versions/*<version number>***
我如何覆盖并指定一个要加载和服务的模型的特定版本?
您需要使用指定的标签和型号版本政策中的版本号
**model_config_list {
config
{
name: 'mnist'
base_path: '/models/mnist/'
model_platform: 'tensorflow'
model_version_policy{
specific{
versions:2
}
}
}
}**
有了上面的变更 models.config 文件,客户端现在可以只为版本 2 调用模型的 predict 方法。
我可以同时服务同一型号的多个版本吗?
您还可以同时提供同一型号的多个版本。在下面的例子中,我们同时为 MNIST 模型提供版本 2 和版本 3。
**model_config_list {
config
{
name: 'mnist'
base_path: '/models/mnist/'
model_platform: 'tensorflow'
model_version_policy{
specific{
versions:2
versions:3
}
}
}
}**
当您有一个较新版本的模型,并希望将一些用户转移到一个较新的版本,并让大多数客户端使用稳定的较旧版本的模型时,这是很有帮助的。这允许您完成 A/B 测试。
我能否为多个模型提供服务,如定制模型和转移学习模型?
要为多个模型提供服务器,请更新 models.config 文件,如下所示
**model_config_list {
config{
name: 'mnist'
base_path: '/models/mnist/'
model_platform: 'tensorflow'
model_version_policy{
specific{
versions:2
versions:3
}** **}
}
config{
name: 'Inception_1'
base_path: '/models/inception_1/'
model_platform: 'tensorflow'
}
}**
TensorFlow 服务允许批量处理多个请求吗?
TensorFlow 服务允许两种不同形式的批处理。
- 批量处理单个模型推理请求,TensorFlow serving 等待预定时间,然后对该时间段内到达的所有请求进行推理
- 单个客户端可以向 TensorFlow 服务器发送批量请求。
批处理要求所有请求使用相同版本的模型。
批处理允许更高的资源利用率和更高的吞吐量。
要启用批处理,将**--enable_batching**
标志指定为真,并使用**--batching_parameters_file**
标志设置包含批处理参数的配置文件。
**docker run -p 8501:8501 --mount type=bind,source=C:\TF_serv\TF_model,target=/models/mnist
-e MODEL_NAME=mnist
-t tensorflow/serving
--model_config_file_poll_wait_seconds=60
--model_config_file=/models/mnist/models.config
--enable_batching=true
--batching_parameters_file=/models/mnist/batch.config**
批处理配置文件是一个. protobuf 文件
**max_batch_size { value: 128 }
batch_timeout_micros { value: 0 }
max_enqueued_batches { value: 1000000 }
num_batch_threads { value: 8 }**
max_batch_size :允许您指定任何批次的最大大小。如果您指定一个大于 max_batch_size,的批处理,那么您将得到一个错误。该参数决定吞吐量/延迟的权衡,并确保不超过资源限制。
batch_timeout_micros :这是服务器重试批量请求的最大时间。参数值以微秒为单位指定。
num_batch_threads :通过指定要同时处理的最大批处理数量来定义并行度。
max_enqueued_batches :它有助于通过拒绝需要很长时间才能得到服务的请求来限制批处理队列,并避免构建大量积压的请求。
当我在有批处理和没有批处理的情况下运行下面的代码时,批处理让我的结果快了 2 到 3 倍。
**import time**
#Build the batched data for making iferences for 100 images
**data = json.dumps({"signature_name": "serving_default", "instances": test_images[:100].tolist()})**
**st=time.perf_counter()
headers = {"content-type": "application/json"}
json_response = requests.post('**[**http://localhost:8501/v1/models/mnist/labels/2:predict'**](http://localhost:8501/v1/models/mnist/labels/stable:predict')**, data=data, headers=headers)****predictions = json.loads(json_response.text)['predictions']
end_t= time.perf_counter()
print(end_t-st)**
结论:
TensorFlow 服务通过使用模型服务器配置提供服务不同模型或同一模型的不同版本的简单方法,使生产部署变得更加容易。
批处理允许您对同一客户端或不同客户端的多个请求进行批处理,从而优化硬件加速器资源并提供更好的吞吐量。
参考资料:
https://github . com/tensor flow/serving/blob/master/tensor flow _ serving/batching/readme . MD # batch-scheduling-parameters-and-tuning
https://www.tensorflow.org/tfx/serving/serving_config
如何建立雪花数据库
原文:https://towardsdatascience.com/how-to-set-up-a-snowflake-database-f9f6e1ca3cfb?source=collection_archive---------30-----------------------
这个平台绝对值得花时间在免费试用期间体验一下
图片由皮克斯拜的 Gerd Altmann 提供
当公司于 9 月 5 日在 T4 上市时,雪花引起了相当大的兴趣。当我最初去 AWS 查看雪花服务时,该服务被认为是一个数据仓库解决方案。通常,“数据仓库”这个术语让我感到厌烦。当我在处理较小的项目和合同时,我喜欢加速和转储数据库和表格,而不太担心基础设施。经过进一步调查,雪花将自己定位为“云数据平台”,提供包括数据科学和数据应用在内的服务。听起来更适合我。我决定冒险使用免费试用版来检验我的高级 SQL 教程的开发平台。这是我的经历。
很容易建立一个帐户
在所有的云平台中,这是最容易建立一个自由层数据库的。输入基本信息,确认你的电子邮件地址,你就可以开始工作了。那非常令人耳目一新。
正如我在回顾经历时所做的那样,除非需要,否则我不会阅读任何文档。除了 SQL 语法之外,我不需要查找任何操作信息(因为 SQL 必须总是不同的,不是吗?)雪花用的是 SQL: ANSI。
创建表
我没有通过 UI 下拉菜单手动命名列,而是使用工作表加载 Create Table SQL。如果不指定字段的长度,它们默认为一些大值。太大。我检查了一下,并在 SQL 中添加了大小。
注意您的插入 SQL —作者截图
数据加载
我使用了与早期文章相同的恶劣天气细节数据源。
[## NCEI 的恶劣天气资料目录
恶劣天气数据目录(SWDI)是美国恶劣天气记录的综合数据库。
www.ncdc.noaa.gov](https://www.ncdc.noaa.gov/ncei-severe-weather-data-inventory)
我发现数据加载比其他数据库更繁琐,尽管显式地指定数据长度并非不合理。我使用“加载数据”功能来加载。csv 文件放入表中。加载过程似乎有两个部分,加密和插入行。
最终加载的数据—作者截图
运行查询
查询通过工作表运行。界面熟悉,性能良好。我连接到 AWS 的唯一指示是 URL。
查询结果—作者截图
结论
我喜欢简单的设置和远离基础设施的抽象。我肯定会在我的个人项目中再次使用这个平台。对于这个演示,我使用了经典的控制台,但似乎雪花正在开发一个更干净的应用程序,目前处于预览模式:
雪花 app 预览——作者截图
我真的很喜欢数据市场如此突出。你是否有购买数据的预算,或者根据你的分析,这是否合乎道德,则是另一回事。
雪花数据仓库链接
[## 试试云数据平台|雪花
雪花使每个组织都能够以数据为驱动力,利用您的数据纵向扩展、横向扩展……
www.snowflake.com](https://www.snowflake.com/try-the-cloud-data-platform/?_bt=470247374840&_bk=%2Baws %2Bsnowflake&_bm=b&_bn=g&_bg=59115312956&utm_medium=search&utm_source=adwords&utm_campaign=NA - Branded&utm_adgroup=NA - Branded - Snowflake - AWS&utm_term=%2Baws %2Bsnowflake&utm_region=na&gclid=Cj0KCQjwwuD7BRDBARIsAK_5YhX4YUsMYQgfOPMqKcBX8_OBSULUB6iYHZ0tonpMf1i64iDzV1MWuk8aAk_gEALw_wcB)
如何在 Amazon Alexa 中使用 Amazon Cognito OAuth2 授权许可设置帐户链接
原文:https://towardsdatascience.com/how-to-set-up-account-linking-in-amazon-alexa-with-amazon-cognito-oauth2-authorization-grant-122cb1b2caca?source=collection_archive---------26-----------------------
亚马逊 ALEXA
使用 Alexa 实现安全的个性化访问
简·安东宁·科拉尔在 Unsplash 上拍摄的照片
A mazon Alexa ,是亚马逊开发的虚拟助理 AI 技术,最初于 2014 年发布。这是亚马逊迄今为止最有创意的设计之一。
Alexa 的表现令人惊叹,如语音交互,音乐播放,制定待办事项,设置闹钟,流媒体播客,提供天气,交通,体育和其他实时信息,如新闻,它还可以控制几个智能设备。
据亚马逊的开发者网站称, Alexa 语音服务(AVS) 生活在云端。亚马逊的 AVS 是一项智能语音识别和自然语言理解(NLU) 服务。Alexa 语音服务(AVS)试图模仿真实的人与人之间的对话。该服务可用于为任何具有麦克风和扬声器的连接设备启用语音功能。Alexa 通过名为“技能”的组件向公众提供服务。
“Alexa 总是通过机器学习的新功能变得越来越聪明,”
-亚马逊的开发者网站上说。
在这篇博文中,我将解释一下 Alexa 账户链接。
来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们并不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语 。
什么是 Alexa 账户链接
帐户链接支持自定义技能将技能用户的 Amazon 身份与不同系统中的身份连接起来。它还允许您使用服务安全地验证用户的技能。一旦技能和外部用户帐户之间的连接建立,技能就可以代表用户使用该帐户执行操作。
账户链接使用 OAuth 2.0 。OAuth 2.0 服务器支持两种发起安全访问令牌交换的协议:授权码授予和隐式授予。
Amazon Cognito 用户池是如何工作的
来源:链接
Amazon Cognito 用户池包括以下任务流。
- 首先,Alexa 服务在运行时向 Alexa skill 提供当前有效的访问令牌。请注意,Alexa service 负责管理刷新令牌,并在令牌到期时获取新的访问令牌。
- 然后,Alexa 技能代码使用该令牌访问用户池中的用户配置文件。当使用 Alexa 应用程序链接技能时,客户将直接通过 Cognito 用户门户进行身份验证。
Amazon Cognito 账户链接的工作原理
Amazon Cognito 帐户链接过程如下。
- 当客户想要登录系统时,会通过帐户链接发起请求。这里,首先由 app 打开开发者指定的授权链接。这是一个到 Cognito 用户门户的链接。
- 重定向时,客户会与 Cognito 登录页面进行交互。然后,用户可以提供必要的登录信息(用户名和密码)以进行身份验证。
- 当 Cognito 验证客户的凭证时,授权码被提供给应用程序,并被传递给 Alexa 服务。
- 然后,Alexa 服务将代码提供给 Cognito。作为回报,它向 Alexa 服务提供初始访问令牌和刷新令牌。然后用户可以使用 Alexa 技能访问。
使用 Amazon Cognito 逐步链接帐户
为了完整地设置这个示例,您需要一个 AWS 帐户和一个 Amazon 开发人员帐户。可选地,需要一个域,在亚马逊 Route53 托管。
按照以下步骤继续。
步骤 1-创建用户池
I)登录 AWS 管理控制台并导航至 Amazon Cognito 。
- 通过查看 AWS 管理控制台右上角的区域,检查正在使用的 AWS 区域。
- 尽管可以使用 Cognito 支持的任何地区,但 Alexa 建议使用四个地区之一 us-east-1(北弗吉尼亚)、us-west-2(俄勒冈州)、eu-west-1(爱尔兰)和 ap-northeast-1(东京)。
ii)点击管理用户池。
iii)点击创建用户池。
iv)输入一个池名,点击查看默认值。
图 1:创建用户池
v)在左侧菜单中选择属性。
vi)首先,让我们看看如何设置电子邮件认证。因此,首先选择电子邮件地址或电话号码,然后选择允许电子邮件地址。
vii)在中,您想要要求哪些标准属性?部分,检查以下内容:
地址、电子邮件、姓、名、电话号码
如果您需要注册页面的更多用户详细信息,您可以相应地添加它们。
图 2:添加属性 I
图 3:添加属性 II
viii)点击下一步。
ix)转到左侧面板中的策略并输入以下配置,然后点击保存。
图 4:添加策略
x)在左侧菜单中选择 MFA 和验证,并设置:
是否要启用多因素认证(MFA) 至关闭和您要验证哪些属性?至电子邮件
图 4:设置 MFA 和验证
xi)点击保存更改,在左侧菜单选择 App 客户端,然后点击添加 App 客户端。
图 5:创建应用程序客户端 I
xii)输入一个应用客户端名称。在刷新令牌到期(天数)字段中输入首选周期。
xiii)选中保留生成客户端机密框,其余框未选中。点击创建 App 客户端。
图 6:创建应用程序客户端 II
xiv)在左侧菜单中选择审查,并点击页面底部的创建池。创建完成后,会提示消息说您的用户池已成功创建。
图 7:用户池的回顾
图 8:成功创建的用户池
xv)现在,请注意左侧菜单发生了变化。在左侧菜单中选择通用设置 > App 客户端,选择显示详情。可以看到为 App 生成的 App 客户端 id 和 App 客户端机密。
图 9:查看创建的应用程序客户端细节
十六)在左侧菜单中选择 App 集成 > App 客户端设置。在启用的身份提供者下,选中认知用户池旁边的框。
xvii)接下来,构建回调 URL 列表。将以下 URL 中的占位符值 < VID > 替换为您的开发者帐户的供应商 ID 。要查找您的供应商 ID,请前往 https://developer.amazon.com/settings/console/mycid并根据提示使用您的亚马逊开发者账户登录。
https://alexa.amazon.co.jp/api/skill/link/<VID>
https://layla.amazon.com/api/skill/link/<VID>
https://pitangui.amazon.com/api/skill/link/<VID>
注意这三个 URL 对应的是 Alexa 的三个区域: FE (co.jp)、EU (layla)、NA (pitangui) 。
将它们组合成一个逗号分隔的值,并将逗号分隔的回调 URL 列表复制/粘贴到回调 URL字段中。
图 10:应用程序客户端设置 I
xvii)在 OAuth 2.0 和允许的 OAuth 流程下,勾选授权码授予复选框。在允许的 OAuth 范围下,勾选这些框:
openid,aws.cognito.signin.user.admin,个人资料
Openid——返回客户端可读的 id 令牌中的所有用户属性。
AWS . cogn ITO . sign in . User . admin-授予对需要访问令牌的 Amazon Cognito 用户池 API 操作的访问权限。
profile- 授权访问客户端可读的所有用户属性。
点击保存更改。
图 11:应用客户端设置二
步骤 2-设置认知到 OAuth 域
设置 Cognito OAuth 域有两个选项。
I .使用认知域:该选项只能用于试验和演示目的。
二。使用你自己的领域:如果开发者打算发布一个使用 Cognito 资源库的技能,那么这个选项是必需的。
因为我做这个例子只是为了尝试,所以我将继续使用 Cognito 域。
使用认知域
I)从左侧菜单中选择 App 集成 > 域名。
ii)选择一个域名前缀,并将其输入到域名前缀字段。
iii)点击检查可用性。将提示域前缀是否已经存在。
iv)收到可用的域名前缀后,点击保存更改。
图 12:创建认知域
v)从左侧菜单中选择应用集成。可以看到完整的网址为(https://chathurangis-user portal . auth . us-east-1。亚马逊歌尼图。com) 中的域域。
图 13:在应用集成中查看创建的域
使用您自己的域名
如果 Alexa 开发者有一个由亚马逊路线 53 管理的域名,他们可以选择这个选项。
步骤 3-设置 AWS 身份和访问管理( IAM)
在本节中,我们可以创建一个 AWS IAM 角色(带策略),它将由支持您的技能的 Lambda 函数使用。
- 导航到 AWS IAM 控制台。
- 点击左侧菜单上的策略。
- 点击创建策略按钮。
- 根据您的要求创建一个策略。
- 在左侧菜单中选择角色,点击创建角色按钮。
- 在选择可信实体类型下,选择 AWS 服务。
- 在选择将使用该角色的服务下,选择λ。
- 点击下一步:权限按钮。
- 搜索您之前创建的策略,并选中策略旁边的框。
- 点击下一步:标签按钮,然后点击下一步:查看按钮。
- 输入合适的名称并点击创建角色按钮。
图 14: AWS IAM 创建策略和规则
步骤 4-设置 Alexa 技能
您可以通过您的亚马逊开发者帐户使用 Alexa 技能工具包开发者控制台 创建自己的 Alexa 技能:
创建 AWS Lambda 函数
创建 AWS Lambda 函数。您可以从头开始创建 lambda 函数,或者使用现有的模板,或者从 AWS 无服务器应用程序存储库中部署一个示例 lambda 应用程序。
图 15:创建 AWS Lambda 函数
将技能与 Lambda 函数连接起来
- 复制您从 Amazon 控制台创建的 lambda 函数的 ARN。
图 16:创建的 Lambda 函数
2.现在,导航到 Alexa 开发者控制台中的端点部分,点击AWSλARN并在默认区域下输入复制的 ARN。
图 17:配置端点细节
为技能配置账号链接
- 在 Alexa 开发者控制台中,选择左侧菜单中的账户链接。
- 将以下选项设为“开”。
图 17:配置帐户链接 I
3.接下来,在安全提供者信息下,输入以下配置。
I)将授权码授权设置为授权授权类型。
ii)通过将< example_domain >替换为您的域,将< VID >替换为您的 in vendor ID,设置授权 URI、以下 URL:https://
iii)设置访问令牌 URI ,将< your_domain >替换为以下 URL 中的您的域:https://
iv)根据您在 Cognito 上找到的相应值,设置客户端 ID 和客户端密码。
v)保留客户端验证方案为 HTTP Basic(推荐)。
vi)点击 +添加范围并输入 openid, +添加范围并输入 profile 和 k +添加范围并输入 aws.cognito.signin.user.admin
vii)点击 +添加域名,输入您的域名。请注意,此处应输入域列表值,不包括 https://。
图 18:配置帐户链接 II
图 19:配置帐户链接 III
viii)就这些。点击保存按钮。
步骤 5 —测试
现在,您可以通过 Beta 测试或登录您所在地区的 Alexa 网站来测试该技能。
I - Alexa Beta 测试
- 要进行 Beta 测试,请前往 Alexa 开发者控制台的发行版部分。
- 用您各自的详细信息完成商店预览、隐私&合规性和可用性部分。
- 然后,在“可用性”下,您将被告知您的技能是否可以进行 Beta 测试。
图 20: Alexa 技能测试版测试
同样,您可以根据 Beta 测试的需要添加管理员和测试人员。
II-通过亚马逊进行测试
- 使用你创建技能的同一个亚马逊开发者账号登录 Alexa 网站(alexa.amazon.com)。
- 导航到技能的详细信息页面。点击技能。点击你的技能。点击开发技能标签,找到你的 alexa 技能并点击它。
通过以上两种方式中的任何一种,你都可以在测试模式下使用你的技能。接下来你会被提示启用你的技能。如果已经启用,点击设置,然后点击链接账户。
图 21:账户链接
3.接下来,将打开一个新的浏览器选项卡。点击注册创建用户。填充细节。回想一下,它们是您在创建用户池时启动的变量。接下来点击报名。
图 22:用户登录
4.接下来会出现一个窗口,要求输入验证码。输入您通过电子邮件收到的验证码,然后点击验证。现在,您的用户已被添加到用户池中。您可以通过导航到 Cognito Federated Identities 下常规设置中的用户和组来查看添加的用户。
图 23:在 Cognito 用户池中创建的用户和组
5.然后,再次单击登录,输入您刚才输入的帐户的电子邮件和密码。如果认证成功,你的技能和账号现在就关联了。您将获得以下成功标签。
图 24:成功链接技能和账户
返回亚马逊开发者控制台,导航到测试选项卡。使用你在创造技能时指定的话语来测试你的技能。以下是我的技能通过认证并与我的帐户关联后的快照。您可以在 JSON 编辑器中看到请求和成功的响应。Alexa 模拟器将显示个性化的结果。
图 25:账户链接后在 Alexa 模拟器中的测试技巧
现在,我们已经成功地将技能与用户帐户关联起来。
如果您要使用另一种最常用的验证机制,如移动 OTP,也可以遵循相同的过程。您需要做的唯一修改是在 Cognito 用户池中设置电子邮件地址或电话号码并选择允许 电话号码。然后在标准属性列表中选择 phone_number 。
尽管如此,在使用移动 OTP 时,每个地区都有短信价格限制。但是,对于基于电子邮件的验证,没有此类限制。
希望你通过这篇博文清楚地了解了 Alexa 账户链接是如何工作的。如果你对这篇博文有任何问题或评论,请在下面留下你的评论。
来源:链接
干杯,学习愉快!
参考
[1]https://developer . Amazon . com/en-US/Alexa/Alexa-voice-service/what-is-AVS
https://www.qed42.com/blog/alexa-account-linking
[3]https://developer . Amazon . com/blogs/Alexa/post/ab 0901 f 8-5b 18-483 c-91ea-5d 2347 e 117 ca/how-to-set-up-Alexa-account-linking-with-Amazon-cognito-user-pools-to-create-a-personalized-customer-experience
[4]https://www . digital trends . com/home/what-is-amazons-Alexa-and-what-can-it-do/
[5]https://medium . com/@ ankit 81008/Alexa-account linking-cogn ITO-74a 29243 B1 ca
如何设置 AWS MySQL 数据库
原文:https://towardsdatascience.com/how-to-set-up-an-aws-mysql-database-c33eba8870eb?source=collection_archive---------39-----------------------
一个快速、简单、免费的平台,用于创建 SQL 教程
图片由 Gerd Altmann 从 Pixabay 拍摄
在写一系列关于如何使用 SQL 回答各种业务问题的文章时,我需要找到公共数据集。想要使用真实的数据而不是精选的 Kaggle 数据集,我在各种云平台上设置了我的数据库实例。我正在分享这些数据库设置经验。第一个实现是 AWS MySQL。
为什么选择 AWS MySQL?
我会用“自由层”来开始和结束任何争论
自由层
AWS 显然是一个受欢迎的平台。虽然这次经历很顺利,但并不是每次与 AWS 的互动都是一帆风顺的。
虽然 MySQL 的数据库实例工作正常,但是 MySQL Workbench 还有许多不足之处。我用来构建数据行的 insert SQL 文件一直冻结着我的应用程序。一旦加载了数据,从工作台到 AWS 以及从 AWS 到工作台的查询性能相当快。
MySQL 数据库实例设置
本教程假设您拥有一个 AWS 帐户。如果您是第一次设置您的帐户,有一些免费等级选项。从您的控制台中,搜索 Amazon RDS 服务。这个链接会引导你到 AWS 提供的一个优秀的指南:https://AWS . Amazon . com/getting-started/hands-on/create-MySQL-db/。它将指导您逐步设置自由层实例。
从亚马逊 RDS 服务创建一个数据库——作者截图
挑完配置就上路了——作者截图。
数据
在我的教程中,我将使用一些网上可获得的严重风暴事件信息。我已经在我的工作中使用了这些数据,它足够有趣,可以创建有趣的样本用例。我会将恶劣天气事件的详细信息加载到数据库表中。如果你想看的话,我提供了这些文件的链接。
ftp://ftp.ncdc.noaa.gov/pub/data/swdi/stormevents/csvfiles/
[## 恶劣天气数据清单
恶劣天气数据目录(SWDI)是美国恶劣天气记录的综合数据库。
www.ncdc.noaa.gov](https://www.ncdc.noaa.gov/ncei-severe-weather-data-inventory)
要将数据加载到表中,需要将其转换为 SQL Insert 语句。总是寻求尝试不同的工具,我用了康伯特(https://numidian.io/convert)。我无法谈论他们的数据安全性,因为我使用的是公共数据集。您上传您的数据文件,它被转换成您的 Create 和 Insert SQL 语句。为了防止 MySQL Workbench 中的错误,我不得不做一些小的改动,但这仍然是值得的。
连接到 AWS 数据库实例
按照说明做了 90%的工作。 MySQL 踢我错误告诉我检查我的密码和访问。我不得不回到我的 AWS VPC,并允许访问。添加 TCP 规则后,我立即可以连接了。
创建表格并添加数据
在我创建的“演示”模式下,我使用了由 konbert 生成的 SQL 文件。我打开 SQL 文件并执行语句。我不得不将一些 varchar(MAX)语句更新为 varchar(##)。我最终加载了两次数据,因为 insert 语句没有显示友好的绿色勾号。我花了几分钟时间在没有副本的情况下复制了这个表,并且准备好了。运行查询的性能优于对大型 Create/Insert SQL 文件进行更改。
结论
我绝对不喜欢 MySQL Workbench 作为我与 AWS 数据库集群交互的应用程序。也许您可以使用一个替代的 GUI 应用程序来与您的数据库进行交互。如果没有更好的工具可以使用,我以后很可能不会选择 AWS 上的 MySQL。
如何建立现代数据分析平台
原文:https://towardsdatascience.com/how-to-set-up-an-flexible-and-scalable-data-analytics-platform-quickn-easy-5fb3a4c83745?source=collection_archive---------49-----------------------
借助 ELT plus 等易于实施且可扩展的云服务,您可以非常快速地建立数据仓库、湖泊和枢纽。
构建你的数据景观——照片由 Neda Astani 在 Unsplash 上拍摄
通过 ETL 过程和 OLAP 立方体构建一个传统的本地数据仓库经常会导致项目延期、额外的成本和 IT 经理的头痛。新的技术、方法和云让我们有可能减少设置时间,并提供更加灵活和可扩展的解决方案。
云(即插即用)
与亚马逊、谷歌等大型云提供商合作。数据仓库、数据库等 IT 服务都是即插即用的。提供像 Big Query [1]或 Redshift [2]这样的数据仓库服务需要每次点击。公共云也提供了比自托管计算机中心更多的计算能力。
尤其是对于小公司和初创公司来说,这是一个使用这些服务的有趣机会,因为它们具有成本效益并且易于设置。如果您感兴趣,您可以通过大多数大型云提供商提供的免费层轻松测试解决方案。
数据仓库与数据湖
几十年来,数据工程师、软件工程师和数据分析师一直在用 ETL 过程构建数据仓库,并一直专注于实现严格遵循 Star 或 Snowflake 等数据模型的架构。此外,人们通常更关注技术细节,而不是业务需求。在数据湖中,所有数据都存储在临时区域中。之后,数据将被处理到数据仓库(数据仓库是数据湖的一部分的混合模型也很常见)、数据集市或用于分析和报告。这使得数据湖比数据仓库更加灵活。此外,它还支持机器学习等新的用例,并为非结构化数据提供存储功能。
ELT 与 ETL
ETL(提取-转换-加载)过程在将数据加载到数据库之前进行转换,而 ELT(提取-加载-转换)过程首先将数据加载到数据库中,并让数据库执行转换任务。这带来了一些好处:
- 繁重的转换任务不必在 ETL/ELT 工具中进行。这使得数据处理速度更快(业务分析师不再需要等待数小时或数天的数据)
- 实现可以更快地实现,因为数据工程师不再需要担心业务逻辑。相反,他们只是建立从源中提取原始数据的工作。这种转换可以在以后由数据湖中的业务分析师或数据科学家来完成,或者通过 BI 工具来完成。
- 流程中的更改和错误修复可以更快地实现,因为没有转换发生,数据可以很容易地重新加载[3]。
最终,像这样的架构可以成为目标:
在基于云的数据库中进行转换的 ELT 流程—图片由作者提供
敏捷项目管理&数据分析过程
数据项目的目标可以是:
- 数据仓库或湖中的新数据对象
- 报告
- 数据科学模型,例如
实现过程通常如下所示:
大数据和分析流程—按作者分类的图片
在收集、准备和建模数据之后,请求者(通常是产品所有者或业务部门)会对数据进行评估。在所有要求的愿望得到满足之前,可能需要一些时间和调整。因此,迭代方法是解决方案。就我个人而言,我建议使用基于 scrum 的 sprints,产品负责人和业务部门每两周评估一次结果。
自助式商务智能工具与老式 OLAP 立方体
构建数据分析平台的另一个加速是通过自助 BI 工具实现的,如易于使用的 Google Data Studio 和 MS Power BI Desktop 或 Qlik 或 looker 等“重型”解决方案。由于有了这样的工具,业务用户可以通过拖放来构建报告。例如,由工程师构建沉重的 OLAP 立方体现在可以由商业用户使用数据透视表功能来完成。通过这样做,耗时的工作从 IT 部门转移到了业务部门。因此,这也可以被视为一种优势,因为自助 BI 工具将数据带给了最了解业务的人。
结论
在即用型云服务的帮助下,ELT 和自助 BI 工具等新模式以及敏捷方法公司(尤其是中小型公司)可以在更短的时间内构建数据分析平台,从而能够更加专注于业务需求。
资料来源和进一步阅读
[1]谷歌, BigQuery
[2] AWS,亚马逊红移
[3] XPLENTY, ETL 与 ELT
如何设置避鸽系统的数据收集
原文:https://towardsdatascience.com/how-to-set-up-data-collection-for-the-pigeon-avoidance-system-eba572fe6dc9?source=collection_archive---------46-----------------------
鸽子回避系统
设置 Raspberry Pi 为深度学习项目收集图像
免责声明:您正在阅读的是描述技术设置的第 2 部分。 第 1 部分 给出了鸽子回避系统的概述 第 3 部分 提供了关于鸽子识别模型的细节。
来源:安迪·霍姆斯在 Unsplash 上拍摄的照片
现在我们已经熟悉了这个问题,让我们设置 Raspberry Pi 来收集图像。在这一部分,我将谈论鸽子回避系统的技术设置。本文由三个部分组成:
- 硬件设置
- 编排软件
- 生产设备
如何为数据收集设置 Raspberry Pi 的一般方法可以适用于您自己的深度学习项目。该部分的所有代码位于 GitHub 的中,可以重复使用。
在我开始之前,我想感谢我的朋友兼同事丹尼尔,他帮助我建立了覆盆子,并在生产中突然出现问题时为我提供技术支持。
硬件设置
回想一下第 1 部分的图表:
图 1:鸽子回避系统架构图
硬件方面,鸽子回避系统包括一个 Raspberry Pi 和三个外部组件:运动传感器、摄像头和步进电机。所有这些都是通过主要的管道来安排的。主管道是我们需要编写的软件中最关键的部分。甚至在我们训练鸽子识别模型之前,我们就需要把它准备好来收集数据。然而,我们首先需要将外部组件连接到 Raspberry Pi。为此,我们将需要使用 GPIO(通用输入/输出)引脚,可以通过 Python 程序访问这些引脚。如图所示,引脚被枚举:
图 2:树莓 Pi GPIO 布局。来源:官方覆盆子文档
任何 GPIO 引脚都可以指定为输入或输出引脚,用途广泛。此外,还有两个 5V 引脚、两个 3.3V 引脚和几个 0V 接地引脚,我们将用来连接外部 Raspberry 元件。
连接运动传感器
应该连接的第一个元件是运动传感器。我用了一个红外运动传感器 HC SR-501 可以检测到人或者动物反射的红外线。传感器的示意图如下所示。
图 3:红外运动传感器 HC SR-501 的示意图。来源:Freenove 文档
当一只鸽子进入传感器的活动区域时,它会向与之相连的 GPIO 引脚输出一个 3.3V 信号。运动检测器的敏感范围在 2 到 7 米之间,可以通过旋转电位计 R2 进行校准。电位计 R1 校准高电平输出之间的时间延迟。还有一个跳线帽(黄色矩形),用作两种触发模式之间的开关:
l:不可重复触发模式。传感器第一次感应到鸽子后会输出高电平。它将继续输出由 R1 配置的高电平延迟。在此期间,感应器无法感应到鸽子。当延迟时间结束时,传感器将输出低电平。
h:可重复触发模式。传感器可以检测到鸽子,直到它离开阳台。在此期间,它输出高电平。鸽子离开后,传感器计时延迟,也是由 R1 配置的,然后输出低电平。
我将传感器设置为可重复触发模式,因为我想激怒鸽子,直到它们最终离开阳台。图 4(红圈)显示了如何将运动传感器连接到树莓。在测试设置时,我使用的是 Raspberry Pi 扩展板。在生产系统中,我将跳线直接放在覆盆子引脚上。
图 4:将外部组件连接到 Raspberry Pi
连接步进电机
步进电机会转动一个吓跑鸽子的装置。我在我的设置中使用了步进电机,因为它可以旋转特定的角度和定义的时间间隔。
步进电机有一个连接到步进电机驱动器的 5 路插座。步进电机驱动器用于将来自树莓的微弱输入信号转换成驱动步进电机的鲁棒控制信号。
图 5:步进电机驱动器原理图。来源:Freenove 文档
步进电机驱动器 IN1-IN4 的输入信号对应于控制步进电机位置的输出信号 A-D。位置控制可以通过编程来完成。步进电机需要一个外部 5V 电源,该电源应与 Raspberry Pi 共享一个公共地。图 4 显示了如何将步进电机与 Raspberry Pi(绿色圆圈)连接。
连接摄像机
连接摄像头是最简单的部分。摄像头端口位于 HDMI 连接器附近。我们只需要把相机的排线绑牢,就万事俱备了。
图 6:树莓 Pi 布局。来源:Freenove 文档
当所有外部组件都连接好后,它看起来就像图片上的混乱:
图 7:连接外部组件的 Raspberry Pi
现在,当所有组件都连接到 Raspberry Pi 时,我们可以编写 python 代码来操作它。
编排软件
我们需要编写 python 代码,以便在检测到运动时触发主管道。Raspberry Pi 已经预装了 python 包 RPi。GPIO 提供了一个类来控制 GPIO。我们需要做的第一件事是设置 GPIO 编号,它定义了在 Raspberry Pi 上寻址 GPIO 引脚的模式。然后,我们设置了一个连接运动传感器的引脚作为输入端口。
设置运动销
之后,我们编写一个事件检测方法。当在 pin_motion 上检测到上升沿时,add_event_detect()将调用 main_pipeline,而不管程序中发生了什么。
运动检测方法
我们需要在无限的 while 循环中运行运动检测方法。这样,程序将一直执行,除非键盘中断结束它。
无限循环中的运动检测方法
现在来看主管道。主管道会调用相机拍照。之后,它会尝试识别图像上有哪些物体:鸽子、人或什么都没有。基于此,它将移动马达,休眠 180 秒,或者什么也不做。
主管道
我们用需要指定的 take_pic()方法拍照。首先,我们配置摄像头模块:
配置摄像头模块
您可能已经注意到,我导入了 config,这是一个配置文件,在其中我指定了外部组件的 GPIO 引脚、图像路径以及图像分类模型的训练数据的路径。
照相
take_pic()在检测到运动时拍照,并将其存储在配置中指定的 img_path 中。如果我们还处于数据收集阶段,那么就要用鸽子火绒手动给图像打标签,把主管道中的条件表达式注释掉,直到我们收集到足够多的图像,训练好模型。
如果在图像上识别出一只鸽子,我们需要通过旋转马达来驱赶它。电机旋转在 rotate_motor 方法中实现。
我们再一次指定了电机所连接的引脚。步进电机有四个引脚,负责旋转角度。
步进电机引脚配置
电机以一定角度旋转(例如从 A 到 B)。
图 8:步进电机图。来源:Freenove 文档
上面代码中指定的管脚:[12,16,20,21]对应的是步进电机的位置:[A,B,C,D]。对于顺时针旋转,我们需要以正向顺序迭代该列表:A→B→C→D→A,等等。从一个状态到另一个状态(例如,从 A 到 B)的每个转换被称为一个步骤。通过控制旋转步数,我们可以控制旋转角度。通过控制两步之间的时间,我们可以控制转速。
首先,让我们实现一个停止电机的方法:
我们对 motor_ports 进行迭代,并将输出级别设置为低。现在,我们可以实现一个具有相同逻辑的旋转函数:在 motor_ports 上逐步迭代,并将输出设置为高。rotate_motor()方法比我们目前所写的稍微复杂一些。
旋转电机
在主管道准备好之后,我们可以测试我们的设置:
鸽子回避系统。测试设置
注意,在这个设置中,我还没有对模型进行训练。因此,每当传感器检测到运动时,电机就会运行。此外,塑料猫不是旨在吓跑鸽子的最终解决方案。它在这里只是为了表明电机运行。
生产设备
现在是时候把树莓派安装到生产环境中了,也就是我的阳台。为了保护硬件免受雨水和鸽子的攻击,我需要防水的塑料盒。我在全球速卖通订购了漂亮的接线盒。然而,根据我过去购买鞋子和手袋的经验,送货可能需要长达四周的时间,我想尽快开始收集数据。因此,我用乐高为摄像头和运动传感器搭建了房子。对于覆盆子本身,我用了一个特百惠盒子,当然,作为一个好主妇,我的厨房里就有这个盒子。
图 9–11:我阳台上的数据收集装置
下一步是让覆盆子通电。最初,它配有一根电源线,长约一米。这远远不够。我在阳台上没有电源插座。因此,我需要从房子里的插座给树莓供电。为此,我焊接了一条 5 米长的新电源线。有了新的电线,我把电源直接给树莓引脚,这通常是不推荐的,但仍然是一种确定。
现在是等待鸽子的时候了。实际上,我需要测试运动检测器对我阳台区域的覆盖情况。因此,我在阳台周围放上燕麦片来吸引鸽子,让它们四处走动。这样,我可以检查运动传感器是否有检测不到鸽子的死角。仅仅几个小时后,我得到了第一张鸽子的照片!
图 12:第一张鸽子图片
看过这张照片的人都注意到了鸽子有多胖。事实上,在杜塞尔多夫我们有非常胖的鸽子。然而,一个非常不幸的惊喜是,运动传感器只检测到正前方的鸽子,而忽略了传感器左侧或右侧的鸽子。因此,我决定安装第二个运动传感器,它将观察垂直方向。这样,我阳台的整个周边都被覆盖了。
图 13:运动传感器设置
运动传感器覆盖了我阳台的两个垂直边缘。在阳台的右边,我有植物。因此鸽子不能在那里着陆。为了简单起见,我用同一根线连接了两个传感器,它在同一个引脚上发送来自两个传感器的信号。在把另一份燕麦片放在我的阳台上后,我意识到现在整个阳台都被覆盖了,我得到了比只有一个传感器更多的鸽子照片。新设置的另一个优点是,我可以将传感器的灵敏度设置为最低,从而减少误报(没有鸽子的图像,由风吹树木引发)。
现在为数据收集建立了鸽子回避系统。每当传感器检测到运动,相机就会拍照并存储在树莓 Pi 上。后来,我用鸽子绒仔细检查了这些照片,并给它们贴上标签,以便进一步训练。
这是第 2 部分的结尾。在“如何利用深度学习把鸽子从阳台上赶走”中,我讲的是如何利用迁移学习的力量进行鸽子检测。保持更新,与此同时,先睹为快从第三部分:如何被当成鸽子?假装你要建一个巢。
图 14:我的手被归类为鸽子。
如果你对这个项目有任何疑问,请随时通过 Linkedin 联系我。
如何在 AWS 上设置深度学习的 Docker
原文:https://towardsdatascience.com/how-to-set-up-docker-for-deep-learning-on-aws-bce751eaf662?source=collection_archive---------35-----------------------
使用 nvidia-docker 访问运行容器中的 GPU
来源:https://blog.pridybailo.com/docker-and-nvidia-gpus/
这篇文章将帮助您在 AWS EC2 实例上设置一个支持 GPU 的 Docker 容器,用于深度学习。我们还将介绍如何从本地机器访问运行在容器内部的 Jupyter 服务器。
为什么?我最喜欢 Docker 的一点是,它允许你在远程机器上轻松地复制本地开发环境。每当你需要在 GPU 上训练一个模型时,这就非常方便了。
本文假设读者对构建 Docker 映像和在 AWS 上启动 EC2 实例有一定的了解。关于 Docker 以及它如何帮助改进您的数据科学工作流的初级读本,请查看这篇精彩的文章。
TL;DR: 使用nvidia/cuda
作为您的基本映像,并在启动容器时传递--gpus all
标志。
步骤 0:您的 Git 存储库
这篇文章的工作目录将是您项目的本地git
库。虽然这不是我们在 AWS 上设置支持 GPU 的 Docker 容器的目标的严格先决条件,但它将使您的生活更加轻松,因为它允许您在 EC2 实例上简单地git clone
GitHub repo。
第一步:Docker 图像
第一步是建立我们训练深度学习模型所需的图像。我们将通过将以下 docker 文件添加到我们的存储库中来实现这一点。
这个 does 文件的关键组件是[nvidia/cuda](https://github.com/NVIDIA/nvidia-docker)
基础映像,它完成了容器访问系统 GPU 所需的所有工作。
你的requirements
文件应该包含你训练你的模型所需要的所有包,并且需要包含Jupyter
以使最后的CMD
工作。如果您有一个训练您的模型的脚本,只需用运行您的脚本的命令替换上面的CMD
。
奖金👻:您也可以通过在需求步骤后添加RUN jupyter contrib nbextension install
来启用您最喜欢的 Jupyter 扩展。
步骤 2:启动并连接到 EC2
下一步是启动一个 EC2 实例并ssh
进入其中。您的实例需要安装Docker
和nvidia-docker
。最简单的选择是选择一个 ubuntu 深度学习 AMI,两者都有安装。
一旦你选择了实例的 AMI,选择一个带有 GPU 的实例类型。遗憾的是,它们并不便宜。在我写这篇文章的时候,us-west-2
中的一个p2.xlarge
实例将花费你$0.90/hour
😭。
在启动实例之前的 review 页面,编辑安全组以打开port 8888
,这样我们就可以从本地机器连接到运行在容器内部的 Jupyter 服务器。
检查您的评论页面看起来像这样,并启动您的实例。
记得在 source 下选择 MyIP。
一旦您的实例启动并运行,通过在本地终端上运行以下命令进入它:
% ssh -i <path-to-aws-pem-file> <user>@<ec2-hostname>
您可以通过选择您的实例并单击 AWS 控制台上的Connect
来找到您的user
和ec2-hostname
。如果你选择了一个 Ubuntu 图片,它看起来会像ubuntu@ec2–XXX.us-west-2.compute.amazonaws.com
。
第三步:克隆你的回购协议,建立你的形象
现在我们已经连接到一个正在运行的 EC2 实例,是时候构建我们的 Docker 映像了。在实例的命令行中,克隆 GitHub repo:
$ git clone https://github.com/<username>/<repo>.git
然后cd
进入它并运行这个命令来构建您的 Docker 映像:
$ docker build -t <image-name> .
奖金👻:如果你有一个预先构建好的镜像存储在容器注册表中,比如 docker hub ,你可以用docker pull
来拉你的镜像,如果你的镜像需要一些时间来构建的话,这可以节省时间。
步骤 4:启动支持 GPU 的容器
建立了我们的映像后,我们就可以发布我们的容器了🚀。在实例的命令行中,运行:
$ docker run --gpus all -d -p 8888:8888 -v $(pwd):/src <image-name>
关键的一点是--gpus
标志,它允许容器访问实例的 GPU(多亏了nvidia-docker
)。至于其他的,
-d
标志在后台运行容器(分离模式)。-p
标志将容器上的port 8888
绑定到 EC2 实例上的port 8888
(我们之前已经向入站连接开放了该实例)。-v
标志将当前目录(您克隆的存储库)挂载到我们在 Dockerfile 中设置的工作目录(我们称之为/src
)中,这样我们对笔记本所做的更改就会修改磁盘上的文件。
上面的命令既启动了一个容器,又启动了其中的 Jupyter 服务器(感谢我们的Dockerfile
中的最后一个CMD
)。您将看到打印在屏幕上的容器 ID。复制并运行下一个命令来获取 Jupyter 服务器的access token
:
$ docker exec <container-ID> jupyter notebook list
复制打印的access token
并返回到您的本地命令行。
步骤 5:连接到容器的 Jupyter 服务器
恭喜你。您已经完成了在远程 AWS 实例上设置支持 GPU 的容器的所有艰苦工作。最后一步是将您机器上的一个本地端口转发到容器内部运行的 Jupyter 服务器:
% ssh -NfL 8080:localhost:8888 <user>@<ec2-hostname>
上面的命令将机器上的port 8080
转发到 EC2 实例上的localhost:8888
,Jupyter 服务器在 EC2 实例上运行。
由于port 8888
是 Jupyter 的默认端口,我们转发了port 8080
以避免与本地机器上运行的任何笔记本发生冲突。
现在在浏览器中导航到localhost:8080
,粘贴上一步中的 Jupyter access token
。
哒哒🎉!您现在正在与一个运行在远程 EC2 实例上支持 GPU 的 Docker 容器内的 Jupyter 服务器对话。
如果您使用 PyTorch,您可以检查cuda
是否可用:
最后的想法
我希望这篇文章能够帮助你在训练深度学习模型时简化开发工作流程。将 Docker 整合到你的日常工作流程中需要时间,但是它会省去很多麻烦和花费在远程环境中的时间。
感谢阅读!🙏
附注完成后,记得关闭您的p2.xlarge
实例!
如何在 AWS 上设置 MS SQL Server
原文:https://towardsdatascience.com/how-to-set-up-ms-sql-server-on-aws-c1105ce08fb4?source=collection_archive---------58-----------------------
他们有一个简单的按钮!
图片由皮克斯拜的 Gerd Altmann 提供
正如我在上一篇关于 MySQL 设置的文章中所讨论的,虽然我将设置这些数据库来创建高级 SQL 教程,但我是在分享我的经验。如今的数据库是 AWS Microsoft SQL Server 产品。
为什么选择 Microsoft SQL Server?
SQL Server 是一种非常流行的数据库,尤其是对中小型公司而言。你经常会在 guru.com 和 upwork.com 看到 SQL Server/TSQL 自由职业者的招聘信息。编写或调试 TSQL 查询和存储过程相对容易。
与 MySQL 一样,您可以轻松地建立一个自由层实现。非常适合我的小型用例。
设置
使用 Easy Create,创建数据库和连接非常简单。点击几下,你的数据库就开始运转了。
Easy Create = Easy Button —作者截图
与数据库交互
为了与数据库进行交互,我下载了 18.6 版本的微软 SQL Server Management Studio(SSMS)。这个版本是 2020 年 6 月 22 日刚刚发布的,所以我很乐意去看看。对于使用过老版本的人来说,你会发现界面非常熟悉。
最初,我无法连接到 AWS 数据库实例。记住我必须为 MySQL 实例所做的更改;我编辑了入库规则。
添加 MSSQL 入站规则—作者截图
这似乎不起作用。尽管我使用了 Easy Create,但我必须返回到实例中,修改数据库实例以使其公开。一旦我完成了调试,我的状态就很好了。
连接到数据库
服务器名是您的端点链接,和一个逗号,后跟分配的端口 id。默认是 1433,对我来说很管用。
SSMS 连接数据库——作者截图
加载数据
我使用了与前一篇文章相同的恶劣天气细节数据源。
[## 恶劣天气数据清单
恶劣天气数据目录(SWDI)是美国恶劣天气记录的综合数据库。
www.ncdc.noaa.gov](https://www.ncdc.noaa.gov/ncei-severe-weather-data-inventory)
由于 1,000 行的插入限制,我无法装载常规的 Insert 语句。对我来说这太弱了。
1000 行限制—作者截图
在设置模式之后,我使用了导入平面文件选项。不需要将信息转换成 SQL 语句。平面文件导入会尝试文件中的数据类型。我不得不修改 varchar 长度,直到进程成功运行。
现在我的数据库已经设置好了,可以开始学习教程了
成功!—作者截图
结论
毫无疑问,SSMS 是比 MySQL Workbench 好得多的工具。我认为可以更好地估计数据类型和长度属性。如果我有一个包含 100 个报价的文件,那就太无聊了。AWS 的设置非常简单。直到我的第一个安全补丁失效,我才看任何手册。AWS 上的 SQLServer 将在我未来产品的候选名单上。
如何组建您的数据科学团队
原文:https://towardsdatascience.com/how-to-set-up-your-data-science-team-44ebf50f4e94?source=collection_archive---------24-----------------------
当您希望将数据科学融入您的组织时,需要注意的事项
越来越多的公司正在建立他们的数据科学团队,希望利用他们拥有的数据。然而,建立一个有效的数据科学团队并不那么简单,因为他们有各种形状和大小。今天,我想分享我在这一领域获得的一些见解,并希望能够帮助您建立适合您的数据科学团队。
照片由海伦娜·洛佩斯在 Unsplash 拍摄
招聘前我需要考虑什么?
就像组织中的任何其他团队一样,构建数据科学团队没有放之四海而皆准的解决方案,但这里有一些关键因素可以帮助您做出正确的决定。
我为什么需要数据科学?
数据科学必须由用例驱动,这是您需要开始的地方。一个帮助你改进目标媒体活动的团队和一个帮助你优化核心商业算法的团队看起来会大不相同。虽然雇佣所有人可能很有诱惑力,但我们知道雇佣所有人通常最终都是免费的,这不是组建团队的好方法。如果您不确定一开始可以处理什么用例,寻求外部帮助来支持您首先定义问题可能会有所帮助,因为这应该是设置数据科学功能的先决条件。
我的组织能够采取行动吗?
许多数据科学团队未能带来价值,因为他们无法与组织融合,而高级利益相关者往往低估了使其工作所需的变革水平。组织的规模和成熟度是决定这里需要多少变革管理的关键因素。更常见的情况是,大型和历史悠久的组织更慢,更不愿意改变,但仅仅因为你是一家初创公司,并不意味着你可以迅速改变。数据科学基于测试和学习的基本原则,它要求组织拥有一种愿意改变数据并从中学习的文化。思考你如何能给组织带来改变和你将要带来的实际改变一样重要。因此,当你建立一个数据科学团队时,一定要在组织变革文化上投入同样多的时间和精力。
我如何建立团队结构?
创建一个专注于“转型”和“创新”的独立团队很有诱惑力,但这种方法行不通,因为创新不可能发生在孤立的环境中。另一方面,如果每个职能团队都开始雇佣他们的数据科学家,就不会有共同的标准和效率提升。关于数据科学应该是集中式还是分布式功能的辩论从一开始就一直存在,但我认为正如 Andy Groove 在《高产出管理》中所建议的那样,矩阵管理结构中的双重报告将是解决以任务为导向的团队和职能团队之间紧张关系的不可避免的解决方案。数据科学家应该同时向数据科学领导和与其合作的职能团队领导汇报。当然,这不是灵丹妙药,管理这种结构将使过程变得更加复杂,但如果做得好,收益应该大于成本。
我需要特定领域的知识吗?
虽然拥有领域知识是有益的,但我认为并不严格要求整个团队都有在你的业务领域工作的经验。一个高绩效的团队将不同背景的人聚集在一起,正是这种合作激发了新的想法。所需的领域知识水平将取决于你的领域有多具体,你的领域越具体和技术性越强,你就越需要了解它的人。与零售和银行等行业相比,医药和生物化学等行业可能会从拥有更高比例的领域知识人员中受益。
你应该先雇佣谁?
考虑到所有这些因素,你应该考虑你的第一份工作。成功聘用第一个员工非常重要,因为这将为团队定下基调,她也将证明数据科学在您组织中的价值。虽然有大量的技术问题需要评估和考虑,但我认为下面这些属性经常被忽略。
你不需要“专家”
多面手经常被忽视,因为他们不擅长某个领域,但他们在项目的早期阶段是非常有用的资源。有在这个领域扮演各种角色的经验的人是很好的第一批雇员,因为他们可以很容易地扮演不同的角色,不需要庞大的团队就能让事情发生。您的需求会有所不同,但拥有一个对数据、分析、产品和技术有着良好理解的人将有助于您将难题拼凑起来。
不要低估领导力的价值
第一个雇员不仅要亲自动手处理数据,她也将是建立团队的核心。我见过许多公司招聘技术数据科学家,希望在他们想要扩大规模时过渡到团队领导职位。我认为这种方法行不通,因为技术领导和团队领导是两种完全不同的角色,这种区别很重要。如果团队发起人对数据科学应该是什么样子有很强的理解和远见,并且有能力领导,你也许可以雇佣一个技术资源团队。然而,聘用一位了解技术领域领导力价值的人,并且能够全力以赴领导数据科学团队,会有巨大的好处。领导力不应该是事后才想到的,如果你希望团队成长,你的第一个雇员就应该有领导能力。
分析与工程
在理想的情况下,我们应该让数据科学专注于从数据中获取价值,让数据工程专注于构建可扩展的健壮数据管道,让软件工程师构建系统的其余部分。然而,事情很少是理想的,尤其是在事情刚开始的时候。你的第一个雇员至少需要了解上面提到的所有学科是如何结合在一起的,因为如果没有它们的协同工作,数据的价值就无法实现。如果你已经具备其中一项或多项能力,新员工应该补充缺失的技能,以涵盖所有这些领域。由于数据科学和工程的工作性质,它们之间应该存在一些积极的紧张关系,但是如果这种紧张关系得到很好的利用,您将能够构建健壮且可扩展的创新解决方案。对双方都有很好了解的候选人将有助于保持健康的平衡。
招聘时要注意什么?
数据科学是一个不断发展的领域,但这使得招聘人员非常困难,因为有太多的方法可以实现类似的结果,而且通常没有绝对的对错。然而,这里有一些我从在这个领域工作得很好的人身上看到的特质。
用工具解决问题的技巧胜过专业知识
随着每天开发出许多不同的工具和方法,特定工具的专业知识不再像以前那样有价值。伟大的数据科学家关注的是问题而不是工具,因为这才是数据科学应该关注的。理解和分解问题并提出正确方法的能力是数据科学家应该带来的真正价值。这可以通过要求候选人回顾他过去解决的一个问题,并找出他强调的内容来评估。
丰富的经验/理解力
创新往往来自于从不同的角度看问题。拥有广泛经验的数据科学家将能够从不同的领域和用例中获得知识,并将它们创造性地应用于不同的问题。由于行业的不成熟,这是一个特别难找到的特征,但是,可以通过要求候选人解决一个他以前没有经验的问题,并评估他是否能够逻辑地解决问题并应用他从其他领域学到的知识来测试潜在的技能。
真实世界的体验
现实世界是混乱的,没有什么可以替代实际的动手经验。越来越多的大学和 MOOCs 正在利用数据炒作,并提供教育资源来培训该领域的人才。然而,在学术环境中对先进理论技术的关注远不能应用于商业产生的实际数据。学习在商业环境中应用数据科学所需的技能需要实践、失败和毅力,经验是非常宝贵的。
对学习和实验的热情
实验和学习将“科学”放在数据科学中。要成为数据科学家,我们需要经常不断地实验,并从失败中学习。这个领域正在快速发展,那些能够保持在曲线顶端的人将会带来最大的价值。随着行业向未来发展,对学习和测试新想法充满热情的候选人更有价值。
尊重其他学科
数据科学依赖于许多其他学科才是有用的,伟大的数据科学家将这些团队聚集在一起。跨职能团队正是因为这个原因而成立的,因为正是所有不同组件的组合使得解决方案能够工作。在提供解决方案方面,有着与不同学科和背景的人共事经验的候选人更有效率。我发现理解并欣赏对方技能的人通常效率最高。
建立一个数据科学团队很难,但如果做得正确,它可以为企业带来很多价值。作为一名企业领导者,了解数据如何支持您的愿景并找到合适的人来执行这一愿景非常重要。虽然看起来每个人都在建立一个数据科学团队,但你可能很想加快这个过程。花时间和精力去建立一个合适的团队将会确保你交付你所期望的结果。
如果您喜欢我的内容,请在 https://jchoi.solutions/subscribe注册更多内容
如何成功设置 Python 项目文档🎉
原文:https://towardsdatascience.com/how-to-set-up-your-python-project-docs-for-success-aab613f79626?source=collection_archive---------32-----------------------
使用 Sphinx 自动化您的文档创建工作流并阅读文档
你做了一个很棒的 Python 软件并向公众发布。太好了!不幸的是,这还不够。️You 需要文件!
良好的文档对采用至关重要。让文档清晰是你能为当前和未来的软件包用户做的最好的事情之一。🎁
文件不会自己写,但你可以通过阅读文件、斯芬克斯和一些眼泪来达到部分目的。😢开个玩笑,可能会有一些并发症,但希望不会有眼泪。
将文档设置为在每个新版本上自动构建可能会令人困惑。在本文中,我将向您展示如何设置您的文档,这样您就可以为您的项目提供最大的成功机会。我们走吧!🚀
斯芬克斯。资料来源:pixabay.com
如果你没有一个基本的 Python 包,请点击这里查看我的制作指南。然后阅读的下一篇文章,学习如何添加测试、Travis、工作服、Black 和 PyUp,这样你就更有信心你的代码不会被破坏。
我将在本文中使用的示例项目是py libraries,一个我为 libraries.io API 制作的包装器。您可以使用它来订阅新版本开源包的电子邮件提醒。您还可以使用它来查找关于开源包和库的许多方面的信息。这里的是单据。让我们看看如何建立它们!🚀
步骤 1:设置阅读文档
免费阅读文档 ( RTD )主机开源项目文档!非常酷。🕶
在https://readthedocs.org设置您的 Read the Docs 账户。
然后执行以下操作:
- 如果您在 RTD 上看不到 GitHub 资源库,请手动将其导入。
- 进入 RTD 项目后,输入相关信息并勾选编辑高级项目选项框。
- 在下一个屏幕上,选择 Python 作为你的编程语言。
- 点击完成。然后 Admin 。然后高级设置。
- 选中复选框,使用 setup.py install 在 virtualenv 中安装您的项目,并在需求 文件字段中输入
requirements_dev.txt
(假设这是您的需求文件的名称。保存。或者,您可以创建一个 readthedocs.yml 配置文件,如这里的所述。
6.点击构建选项卡。您应该看到一个构建正在进行或已经完成。
7.构建完成后,点击查看文档。这些文档还没有显示太多关于我们包的信息——我们稍后会处理这个问题。
当你推送 GitHub 时,如果配置了 webhoook,你的文档会自动生成。如果您自动将 repo 连接到 GitHub,您可能不需要为自动构建配置任何其他东西。☝️
如果您手动导入了回购协议,则需要设置一个 webhook。说明可以在这里找到。我对这些文档做了一些小的改进,所以如果你觉得有什么不清楚的地方,用 PR 来改进它们。😄以下是添加网页挂钩的方法:
在你的 GitHub repo 中,进入设置->-web hooks->-添加 webhook 。您应该会看到如下所示的表单。
对于有效载荷 URL ,进入 RTD集成设置并复制 webhook 信息。在前面加上https://
。你可以不去管其他的事情,点击添加 webhook 。或者选择让我选择单个事件如果您想要触发 RTD 文档构建以响应除推送到回购之外的其他 GitHub 事件。仅供参考,我不得不删除我在 RTD 和 GitHub 上的 webhook,并重做重新添加 webhook 使其工作。
下次你把你的代码推给 GitHub,合并 PR,去 RTD 吧。您应该看到您的文档被自动重建!🎉如果你没有马上看到变化,等待几分钟。
酷!现在让我们设置 Sphinx 来为 RTD 生成我们的文档。
步骤 2:安装和配置 Sphinx
Sphinx 号称可以轻松创建智能美观的 Python 文档。我不知道我会说这是一个快照,但斯芬克斯是非常酷的。😉功能包括语法突出显示、主题和简单的文档链接。这里有斯芬克斯入门指南供参考。
将sphinx==3.03
添加到 requirements_dev.txt 中,用pip install -r requirements_dev.txt
安装。
其他狮身人面像。资料来源:pixabay.com
在项目目录的顶层创建一个 docs 目录。在那个目录中,从命令行运行sphinx-quickstart
。
会问你几个问题。出现提示时,输入项目名称和作者姓名。通常缺省值是你想要的。
将自动生成以下文件:
- index.rst
- conf.py
- Makefile
conf.py
conf.py 控制构建文档时 Sphinx 如何运行。在其中,您可以配置项目文档设置。让我们对 conf.py 做一些修改,让 Sphinx 创建更好的文档。取消注释并调整该部分,使 abspath 为 ..
import os
import sys
sys.path.insert(0, os.path.abspath('..'))
将以下内容插入扩展名列表:
extensions = [
'sphinx.ext.napoleon',
'sphinx.ext.autodoc',
'sphinx.ext.viewcode',
'sphinx.ext.coverage',
]
我不是雪花石膏模板的粉丝,所以我在我的 requirement_dev.py 文件中添加了sphinx_rtd_theme==0.4.3
并安装了它。
如果你做了同样的事情,将 conf.py 中关于 html_theme 的那一行改为:
html_theme = ‘sphinx_rtd_theme’
制造
Make 是一个构建自动化工具。Sphinx 生成的 Makefile 控制以make
开头的快捷命令如何操作。点击了解更多关于 makefiles 的信息。不用深究 Make,你大概也能过得去。😉
从命令行运行make html
用这个快捷命令创建您的文档。然后,在你的docs->-build_->html目录下你应该会看到index.html。在浏览器中打开该文件,您应该会看到您的基本文档。😄
要检查任何未记录的函数和类,将下面几行添加到您的 Makefile 中。
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -b coverage
附加的行-b coverage
创建了一个覆盖率报告,这样可以告诉你有多少代码被记录。现在,当您运行make html
时, html 文件夹将包含一个名为 python.txt. 的文本文件,该文件将显示您需要一些文档的位置。😀
提交并继续制作您的 doc 文件。
其他文件。资料来源:pixabay.com
第 3 步:创建文档文件
你可以选择是用 Markdown(以下简称 md 还是 reStructuredText(以下简称 rst )来写你的文件。Md 更接近常规散文,学起来更快。但是,rst 允许您使用更多 Sphinx 的强大功能。这里是MD 的 GitHub 指南和rst 的Sphinx 指南。
是否花时间学习 rst 是你的选择。你还可以学习十亿种其他的东西,所以如果它不在你的清单上,我能理解。😉然而,许多项目的文档都是用 rst 写的,所以知道这一点很好。
使用这个在线 pandoc 转换器,你可以在 md 和 rst 的片段之间快速转换。您可以使用它从一种格式复制粘贴到另一种格式。 CloudConvert 对整个文件做同样的处理。CloudConvert 每天使用 25 分钟后开始充电。☝️
如果您走的是 rst 路线,请将您的自述文件扩展名切换到。rst 。
另外, setup.py 将需要 README 名称,而long _ description _ content _ type将切换到 rst。
我要用 rst。如果您使用 md,请将下面的文件扩展名更改为 .md.
创建以下文件:
- 行为准则. rst
- 投稿. rst
- 历史. rst
- README.rst
行为准则. rst
这里是 GitHub 信息和行为准则模板。《行为准则》解释了人们在与您的项目合作时应该如何表现,以及如果个人行为不当应该如何处理。在模板有位置的地方添加您的电子邮件。如果想将 GitHub markdown 模板复制到 rst 中,可以使用上面提到的转换器之一。😀
贡献第一
让那些想为你的项目做贡献的人更容易做到。在你的投稿文件里写清楚说明。请随意使用我的文件作为基础。
历史. rst
历史将包含你的变更日志。对套餐用户有帮助。你也可以在 GitHub 上使用你的发布信息中的内容。☝️
在 history.rst 中添加以下内容。
=======
History
=======0.0.1 (2020–05–15)
— — — — — — — — -* First release on PyPI.
将日期更新为适当的日期,并添加任何其他相关的项目符号。当您发布软件包的新版本时,您将附加该文件。
README.rst
您的自述文件应包括安装和基本使用信息。我建议你把用户指向 RTD 的完整文档。👉
您可以将其他文档添加到您的项目中,但是要确保将文件名放在您的 index.rst 的 TOC 中。然后它们会出现并链接到您构建的文档中。😀
现在让我们确保我们的用户能够得到帮助,理解你的函数和类是做什么的。
其他文件。资料来源:pixabay.com
步骤 4:添加文档字符串
文档字符串是一种向用户传达类或函数如何工作的方法。当用户寻求帮助时,文档字符串会出现在他们的代码中。Sphinx 将获取您的文档字符串,并自动使它们在 RTD 上的文档中可用。👍
在你的代码中写下你的文档字符串,紧跟在你的类或函数的第一行之后。文档字符串以三重引号开始,应该包含用户可能需要的任何信息,包括关于参数和返回值的信息。
Python 没有一种显而易见的方式来格式化文档字符串。选择一种方式来编写 docstrings,这样它们看起来很整洁,没有人需要询问或考虑如何做事情。😀
我建议使用谷歌风格——推荐这种风格是为了便于书写和阅读。关于文档字符串格式的详细讨论可以在这里找到。
通过在投稿文件中包含说明,确保让投稿人了解您选择的 docstring 格式。☝️
当您的代码中有文档字符串时,您可以在本地构建您的文档,并在浏览器中查看您的文档字符串。当本地版本看起来不错时,提交、推送并合并您的 PR,以在您的模块页面的 RTD 上查看您的文档字符串。
不带文档的字符串。资料来源:pixabay.com
如果事情没有按预期进行,这里有一些建议可以让你回到正轨:
解决纷争
斯芬克斯和 RTD 可以打破或导致文件看起来不同于预期的许多原因。检查 RTD 的构建日志以查找错误。
常见问题包括:
- 如果您的文档没有构建,而您使用的是 rst 文件,那么可能在某个地方有无效的 rst。要找到无效的 rst,请通过上面提到的 rst 检查器之一运行文件内容。
- 如果你的文档构建好了,但是你的模块没有显示出来,检查一下 RTD 上的原始输出日志。
- 确保您的 setup.py 和 requirements_dev.txt 文件是正确的。
- 如果你需要一个环境变量来运行,在 RTD 设置中添加它。
RTD 和斯芬克斯文档和堆栈溢出是有帮助的,但我发现这种故障排除很麻烦。我能感受到你的痛苦。🙁
现在让我们来看一个更好的话题——通过徽章向潜在用户传达信息。
步骤 5:向自述文件添加徽章
徽章为对您的项目感兴趣的人提供一目了然的信息。徽章可以灌输信心和合法性。以下是可以放在您的自述文件顶部的徽章示例:
在 https://shields.io/和 https://badgen.net/的可以获得许多徽章。我从 shields.io 加了一些我的,要获取徽章代码,不要只复制徽章旁边的网址。点击网址。然后添加您的包名。参见下面的轮徽章示例。
然后从下拉列表中复制 md 或 rst 代码,并将其粘贴到您的自述文件中。
在相关应用程序的网站上可以获得许多徽章。派普,特拉维斯和工作服有你能拿到的徽章代码。对于 PyUp,如果您单击 PyUp 仪表板上的徽章,您将看到可以复制并嵌入到自述文件中的代码。
这里是 RTD 的徽章信息。
酷!我们有徽章。最后,让我们看看如何促进协作。
步骤 6:创建问题和 PR 模板
来自更大社区的帮助对开源项目来说是一个巨大的好处。您希望让您的用户能够轻松地报告 bug 和功能请求以及相关信息。最好的第一步是提供一个清晰的问题模板。
问题模板
在浏览器中,进入 GitHub repo ->设置->选项。在功能下,点击绿色的设置模板按钮。
您可以添加自定义问题模板或使用 GitHub 的默认模板之一。
拉请求模板也同样有用。GitHub 有一个很好的制作指南这里。
现在,您可以更容易地获得开源项目的帮助了!
包装
在本文中,您了解了如何制作自动构建的优秀文档。你也学会了如何用徽章传达信息。最后,您看到了如何吸引合作者。
现在,人们将知道如何使用和贡献你的包。厉害!🎉
我希望这个指南对你有用。如果你有,请分享到你最喜欢的社交媒体渠道,这样其他人也可以找到它。👍
我写关于 Python 、 Docker 、数据科学和其他技术主题的文章。如果你对此感兴趣,请订阅我的 Data Awesome 邮件列表,在这里阅读更多。😀
斯芬克斯。资料来源:pixabay.com
快乐记录!🖋
如何为对象检测模型设置您的系统
原文:https://towardsdatascience.com/how-to-set-up-your-system-for-object-detection-models-2e0726212c4e?source=collection_archive---------15-----------------------
你应该从头开始,第一次尝试就把它做好
戴维·克洛德在 Unsplash 上的照片
计算机视觉是当今人工智能的一个热门领域。目标检测是计算机视觉中的一项特殊任务。它帮助机器在没有人眼帮助的情况下识别一组特定的对象。许多应用,如受保护区域中用于监视的人脸检测、商店中的脚步计数、通过跟踪来估计车辆速度的物体检测、制造业中的产品故障检测等。—正在使用物体探测技术。
在不同的社交媒体上,我看到许多机器学习爱好者正在尝试不同的对象检测技术,并分享他们的结果。
不知何故,我对应用这些物体检测技术有点怀疑。我对深度学习算法的基础和一般机器学习问题、NLP 和计算机视觉的方法有一个相当好的想法。我也做过一些基于文本的模型。但是由于一些未知的原因,计算机视觉总是排斥我。
在我的职业生涯中,我一直避免从事与愿景相关的项目。我曾经把它传给我的同事。但我做不了多久。当我不能再避免它的时候,一种情况出现了。我必须做一些与特定上下文相关的对象检测任务。所以我决定试一试。
起初,我不确定从哪里开始。我做了大量的网络搜索和阅读来寻找合适的材料来指导我。我意识到有很多关于物体检测的文章,但是大多数都不完整。由于对我来说这是一个新的领域,而且我有时间限制,我需要关于程序的每一步的详细指导,我还需要一个快速实施模型的策略。
我找到了一些不错的文章——Medium,Analytics Vidya,Machine Learning Mastery 等。但是当我要实现它的时候,我面临着许多与系统设置和模型执行相关的挑战。
我面对不同的错误信息,我无法理解。花了几天时间才找出这些错误的原因。最后,我知道你需要列出一个需求清单,并遵循一个循序渐进的方法来在这个旅程中取得成功。
在本文中,我将讨论首次尝试成功实现对象检测模型所需的策略。
在开始安装之前了解要求
有两种方法来建立对象检测模型。您可以实现现有的模型架构。这需要更少的时间,并且您可以从其他实现中获得指导。此外,您还可以从名为迁移学习的方法中受益,该方法使用以前构建的模型的权重,并根据当前上下文重新训练模型。
另一种方法是从头构建一个模型。训练模型需要更多的时间和资源。但是它给了你更大的控制权。
我决定使用现有的模型架构,并根据我手头的任务对其进行重新训练。我选择了掩膜 RCNN 模型进行物体检测。我在 Medium 和 Machine-Learning-mastering 中找到了一些关于其基本原理和实现的文章。
我有一台装有 Windows 10 和 4GB NVIDIA GEFORCE GTX 1650 GPU 的笔记本电脑。为了训练它完成我的任务,我需要设置 GPU,还需要安装 jupyter notebook 来访问它。
从这里找到一篇关于设置 GPU 的美文。在克服了一些障碍之后,我已经能够做到了。指南有点旧了。一些命令不起作用。我设法把它们换成了新的。
我的下一个任务是实现这个模型。我打算实现一个端到端的现有对象检测模型,这样我就可以快速适应我的新用例。
我跟随文章从来到这里。我做了所有必要的步骤——下载了 Mask RCNN git 存储库(这里是),下载了图像及其注释文件,导入了必要的包,以及所需的文件。但是,当我开始训练给定数据的模型时,我陷入了困境。
我遇到了一个与 TensorFlow 相关的错误—“ModuleNotFoundError:没有名为‘tensor flow . contrib’的模块。”我尝试了网络上的不同方法来修复它。但是我不能。他们每个人都把我引向另一个错误。
花了几天时间才明白成功实施的秘密。您需要同步您为对象检测任务安装的软件包和软件的版本。它从设置 GPU 开始,适用于您在整个项目中安装的每个软件包。
是包版本把事情搞砸了。对我来说,它是 TensorFlow 的版本。TensorFlow 的当前版本是 2.3.0。Mask RCNN 模型架构是为 TensorFlow 版本 1.14 或更早版本构建的。没有意识到这一点,我继续安装所有软件包的所有最新版本,包括 TensorFlow,除非特别提到。
意识到(在许多不成功的尝试之后)TensorFlow 版本导致了麻烦,我决定卸载所有东西并重新开始。
我再次从安装 GPU 和适当版本的 TensorFlow 开始。这一次成功了。我仍然面临一些 python 包的问题。但我知道解决方法。我根据发布日期匹配了包的版本。
我再也不用担心兼容性问题了。我可以完全专注于建立我的模型。
在开始构建任何对象检测模型之前,您可以按照以下步骤收集设置系统所需的所有信息。
- 做一些阅读,找出你想要使用哪个模型(深度学习框架)来进行对象检测。在文献中,有大量的标准架构用于对象检测任务。RCNN,更快的 RCNN,掩膜 RCNN,YOLO,RetinaNet 等。是广泛使用的算法。
- 找到您选择的算法的 git 存储库,并找到它的实现。
- 在存储库中搜索实现的系统需求。
- 确定算法支持的 TensorFlow-GPU 版本(如果模型使用 TensorFlow)。
- 有关 TensorFlow 版本,请查看 python 的兼容版本。
- 找到适合 TensorFlow 版本的 CUDA 版本。
- 查找适用于 CUDA 的兼容 Visual Studio 版本
- 找到 CUDA 版本各自的 cuDNN 包。
- 搜索适用于 CUDA 实现的 Visual Studio 版本。
- 搜索其他 python 包的版本,如——numpy、scikit-learn、opencv-python、keras 等。您应该选择存储库中提到的这些包的版本。如果没有特别提到它们,请使用在创建存储库时发布的包版本。
如果你正确地收集了所有这些信息,你就为旅程的第二阶段做好了准备。
遵循安装顺序
如果您已经收集了关于需求的所有信息,您就可以开始一个接一个地安装它们了。设置系统时,请遵循以下顺序。
1.可视化工作室
下载您选择的 CUDA 版本所需的 Visual Studio 版本。对于遮罩 RCNN,我需要 Tensorflow 1.14。与 Tensorflow 1.14 兼容的 CUDA 版本是 CUDA 10。在此链接中找到与 TensorFlow 和 CUDA 版本相关的信息。
现在,CUDA 版本需要特定版本的 Visual Studio 和适当的 Visual C++编译器。我的情况是 Visual Studio 2017 有 Visual C++ 15.0 编译器。使用此链接获得合适的版本。
2.蟒蛇
从这里安装 Python 3.x 版本的 Anaconda。它将帮助您创建一个由 tensorflow-gpu 支持的虚拟环境。在这种环境下,你会推出 jupyter 笔记本。
3.库达
从这里下载安装 CUDA。我不得不下载 CUDA 10(旧版本)。从这里遵循 CUDA 的确切安装程序(除了 CUDA 版本)。CUDA 版本应该与您的 TensorFlow 版本兼容。
4.cuDNN
你的 cuDNN 版本必须符合你的 CUDA 版本。跟随这个链接找到合适的版本。只好下载了 cuDNN 7.4(老版本)。此处给出了 cuDNN 安装和设置环境变量的详细步骤。
5.张量流
您需要使用 Anaconda 提示符创建一个环境来安装 TensorFlow。选择与您的模型兼容的支持 GPU 的 TensorFlow。从这里的开始按照步骤进行操作。
安装 TensorFlow 后,应该检查一下是否可以访问 GPU。由于版本更改,上面链接中提到的代码片段不起作用。使用以下脚本来检查相同的情况。它将显示可用的计算资源。
from tensorflow.python.client import device_lib
print(device_lib.list_local_devices())
6.Jupyter 笔记本
是时候在您的环境中安装 jupyter 笔记本了。遵循此处给出的指示。现在,您已经准备好探索对象检测模型了。
7.模型
下载要用于对象检测任务的模型。您需要从 git 存储库中克隆它。我用了面膜 RCNN。所以我使用下面的命令下载并安装了它。你可以在这里找到掩码 RCNN 模型的实现。
# To clone the Model
!git clone https://github.com/matterport/Mask_RCNN.git
# To change directory to the installation folder
cd Mask_RCNN
# To install the model
!python setup.py install
# To confirm the installation
pip show mask-rcnn
8.Python 包
现在,您可以下载构建模型所需的其他 python 包。在 Mask RCNN 库中有一个需求列表。它包含该实现所需的所有必需的包。不过,它没有提到所有软件包的版本。
为了避免进一步的版本冲突,我安装了所有必需的软件包和所需的版本。
pip install scikit-image==0.14.2
pip install Keras==2.2.4
pip install scipy==1.2.1
pip install Pillow==7.2.0
pip install Cython==0.29.6
pip install scikit-image==0.14.2
pip install opencv-python==3.4.5.20
pip install imgaug==0.2.8
pip install h5py==2.10.0
现在,您的 jupyter 笔记本已经准备好进行所有安装。你再也不用考虑兼容性问题了。您可以将全部精力用于训练和推断您想要建立的对象检测模型。
计算机视觉是人工智能的一个专门领域。解决计算机视觉问题的方法与通常的机器学习方法有点不同..我写这篇文章是为了帮助数据科学新手深入研究对象检测模型。这也将有助于像我这样的专业人士,他们以前从未尝试过物体检测任务。我以 Mask RCNN 为例来展示这个过程。我的意图是在开始任何目标探测任务之前,提出一种结构化的方法来配置系统。
附录:(一些问题和有用的链接)
- 如果你用 cudnn64_7.dll 在 Windows 上构建时遇到“导入错误”,请点击此链接。
- 如果您遇到“导入错误:导入 win32api 时 DLL 加载失败:系统找不到指定的文件。”,跟着这个环节。
- 如果你面对“内核错误 win32api”,按照这个链接。
- 你可以在这里找到一个很好的对象检测模型的实现。
5.模型实现的另一个漂亮演示是这里的。
谢谢你的时间。如果你喜欢这篇文章,你可能会喜欢我的其他文章。这是其中之一。
[## 没有书籍和教程如何学习新的编程语言
经过检验的快速学习方法
medium.com](https://medium.com/swlh/how-to-learn-new-programming-language-with-no-books-and-tutorials-862e8cf77d8f)
如何为 PyTorch 设置本地 AWS SageMaker 环境
原文:https://towardsdatascience.com/how-to-setup-a-local-aws-sagemaker-environment-for-pytorch-d045ada46d61?source=collection_archive---------51-----------------------
声明:我是本教程中提到的booklet . ai的联合创始人。
作为一名黑客数据科学家,但基本上是合法的 web 开发人员,我对创建一个 ML 应用程序的过程感到沮丧(一个触发预测的简单 UI 和一个可公开访问的 API)。创建和迭代一个典型的 web 应用程序的流程感觉就像在一个春日沿着一条低流量、平缓弯曲的乡村道路行驶。ML 应用开发流程?就像学开手动挡的车一样。
为什么 ML 应用开发流程这么粗糙?一个重要原因:没有强调本地发展。我来举例说明。
我将向您展示如何为部署到 AWS Sagemaker 的 PyTorch 神经网络创建 ML 应用程序。🚀试试 Booklet.ai 上的 ML web app 。
所以您想将 PyTorch 模型部署到 AWS Sagemaker?
您已经构建了一个模型,现在您想要部署它。您偶然发现了 AWS Sagemaker 登录页面,并看到了这段文字:
一键部署?在几分钟内将新模型集成到您的应用中?你是数据科学家,不是 web 开发人员,为什么要花时间学习 web 技术呢?这听起来很棒——注册吧!
接下来,您搜索“使用 PyTorch 和 Amazon SageMaker ”,并意外发现您的用例:
完美!您点击链接,在 SageMaker SDK 文档中的部署来自模型数据的端点。只需两个函数调用,您就有了一个部署好的模型!
…但是接着疼痛开始了:
model_data
文件格式是什么?您有一个模型文件,但是您也有一些预处理中需要的编码器。你是怎么装的?entry_point
脚本是做什么的?文档的“从模型数据部署端点”一节没有对此进行描述。
哦好吧。你交叉手指,运行代码,部署,然后等待大约 10 分钟过程完成。接下来,您找到一些代码示例,这样您就可以调用invoke_endpoint()
并触发一个预测。这失败了,CloudWatch 日志提到缺少model_fn()
函数,所以您在文档中发现加载了一个模型。你试试这个然后部署。
…并等待 10 分钟。你叫invoke_endpoint()
。这次input_fn()
出现错误,好像和预处理有关。原始输入中有字符串 SageMaker 不喜欢这样吗?还是你在invoke_endpoint()
发送了一个畸形的有效载荷?
您尝试一些东西,部署,然后…等待… 10 …分钟。
神圣的地狱。这有什么难的!嗯,我写了一些没用的蹩脚代码。当我在笔记本上训练 PyTorch 模型时,这不是问题,因为我可以快速修复我的错误。部署到 SageMaker 是一个不同的故事— 每一个小小的改变都需要漫长的等待。
您需要一个本地 SageMaker 环境
当你写完这篇文章,那些在 SageMaker 上等待 10 分钟来验证新代码的工作将成为过去!您将拥有一个在您的计算机上运行的本地 SageMaker 开发环境。您将拥有一个简单的脚本来部署对 Sagemaker 的更改。
PyTorch + SageMaker 示例
我们的起点是一个 PyTorch 文本分类神经网络我已经从优秀的用 ML 教训 GitHub repo 取得了分叉。我的 fork 添加了一个[deploy/sagemaker](https://github.com/itsderek23/lessons/tree/master/notebooks/03_APIs/pt-text-classification/deploy/sagemaker)
目录,其中包含将模型部署到 local + production SageMaker 环境的逻辑。
这一课也是一个很好的起点,因为它展示了如何使用 FastAPI 为模型创建 RESTful API。您可以看到用 FastAPI 开发自己的 API 和利用 Sagemaker 之间的区别。
运行本教程的先决条件
- GitHub Repo —用 SageMaker 更新:
git clone [https://github.com/itsderek23/lessons.git](https://github.com/itsderek23/lessons.git.)
克隆我用 ML Lessons repo 制作的分叉副本。 - amazonseagemakerfullcaccess IAM 角色 —使用amazonseagemakerfullcaccess策略创建角色。
- 项目设置 —遵循自述文件中的设置说明。
- 训练 PyTorch 型号——按照自述中的说明进行。
我引用的命令和文件假定当前目录如下:
亚马逊 SageMaker 本地模式是如何工作的?
除了在一篇介绍性博客文章中的一些线索之外,我还没有找到关于 SageMaker 本地模式应该如何配置以服务于本地 ML 模型的重点总结。AWS 官方博客文章的重点是培训,而不是托管已经构建好的 PyTorch 模型。这是我拼凑出来的。
SageMaker 本地模式需要三类变更:
- 预构建的 Docker 容器:在为您的 PyTorch 模型提供服务时,使用 SageMaker 在云中运行的相同的 Docker 容器。这给了你很高的信心,如果你的模型在本地工作,它也能在生产中工作。
- API 客户端的本地版本:通常情况下,你使用
botocore.client.SageMaker
和botocore.client.SageMaker Runtime
类来使用 Python 中的 SageMaker。为了在本地使用 SageMaker,我们将使用sagemaker.local.LocalSagemakerClient()
和sagemaker.local.LocalSagemakerRuntimeClient()
来代替。 - 函数参数改变:我们也改变了几个参数到
PyTorchModel()
和pytorch_model.deploy()
。这些变化如下。
Sagemaker 本地的 PyTorchModel()
从本地文件加载model_data
。我们不需要上传model.tar.gz
文件并从 S3 桶中加载它。这在测试新代码时要快得多。
用于 Sagemaker 本地的 pytorch_model.deploy()
将instance_type
设置为local
,而不是标准的 Sagemaker 实例类型(例如:ml.t2.medium
)。
为了处理本地环境和生产环境之间的差异,我创建了一个 **DeployEnv**
类,它从 **deploy/sagemaker/config.yml**
加载特定于环境的设置。
介绍 DeployEnv 类
因为我们的本地环境需要一组分散的修改,所以我将这些更改封装到一个类中。这意味着我们不必让检查本地或生产环境的if
语句污染我们的脚本。
让我们看看DeployEnv
是如何工作的。
首先,如果没有指定环境,我们默认为 **local**
环境。这是你应该花费大部分时间的地方,因为这里的发展更快。
加载生产设置通过设置 **DEPLOY_ENV=production**
环境变量:
通过 **DeployEnv.client()**
和 **DeployEnv.runtime_client()**
为您的环境加载正确的 SageMaker API 客户端。
local
环境 SageMaker 客户端:
production
环境 SageMaker 客户端:
通过 **DeployEnv.setting()**
访问特定环境设置。这些使用[deploy/sagemaker/config.yml](https://github.com/itsderek23/lessons/blob/master/notebooks/03_APIs/pt-text-classification/deploy/sagemaker/config.yml)
作为底层数据存储。
例如,model_data_path
在local
环境中使用一个本地文件:
…在生产中:
既然我们可以访问特定于环境的设置,那么是时候编写与环境无关的部署脚本了。
SageMaker PyTorch 模型部署脚本
我想用相同的脚本将 PyTorch 模型部署到我的本地和生产环境中。
部署到本地环境:
本地部署需要多长时间?这是第一行和最后一行日志:
23 秒!或者,比部署到 AWS SageMaker 生产环境快 26 倍。这使得 ML 应用程序的迭代速度大大加快。注意,第一次本地部署将花费更长时间,因为 SageMaker 需要下载 PyTorch Docker 映像。
部署到生产环境:****[**deploy/sagemaker/deploy.py**](https://github.com/itsderek23/lessons/blob/master/notebooks/03_APIs/pt-text-classification/deploy/sagemaker/deploy.py)
如何处理两种环境?****
我们只是使用上面的DeployEnv
类。例如:
了解 Booklet.ai 的最新动态,并率先访问我们的测试版。
这个deploy/sagemaker/serve.py
文件是什么?
在 Sagemaker 中加载和服务我们的 PyTorch 模型
SageMaker PyTorch 模型服务器允许我们配置模型如何加载和服务(前/后处理和预测流程)。这可能需要做一些工作来适应现有的模型(这就是创建本地环境的原因)。
[deploy/sagemaker/serve.py](https://github.com/itsderek23/lessons/blob/master/notebooks/03_APIs/pt-text-classification/deploy/sagemaker/serve.py)
封装了加载和服务我们的文本分类神经网络模型的逻辑。下面是我如何调整model_fn
、input_fn
和predict_fn
来适应现有的模型。
型号 _fn
model_fn 告诉 SageMaker 如何从磁盘加载模型。此功能是必需的。我猜 SageMaker 创建了一个加载模型的专用函数,这样模型只能在启动时加载,而不是在每次 API 调用时加载。从磁盘反序列化模型很慢。****
然而,为了不重构这个应用程序现有的Predict
类,我将model_fn
设为空操作。Predict.predict()
很好地封装了前/后处理、加载模型和预测。我更喜欢重复使用这个。如果这是一个频繁使用的 API,我会将模型加载转移到一个专用的调用,这样它只在启动时执行。
代码如下:
输入 _fn
SageMaker 使用一个专用函数input_fn
来处理预处理数据。有一个默认的反序列化单个 JSON 列表的函数。然而,如果你仔细观察,你会发现文档提到列表被转换成了一个torch.Tensor
,所以它不能处理string
对象的列表(这就是我们所拥有的)。这是因为默认实现在我们的输入上调用torch.from_numpy()
。from_numpy
不喜欢串串。
以下是习俗input_fn
:
****重要:我想确认默认的 SageMaker PyTorch JSON 格式(单个 JSON 列表),这样我就可以把模型钩到 Booklet.ai 里,免费得到一个 web app UI + public API。 Booklet.ai 期望 API 模式匹配默认值。此外,当我几天后忘记 API 模式时,我可能会回到 SageMaker SDK 文档。有通用格式真好。
预测 _fn
因为Predict.predict()
已经做了我们需要的一切,我们只需要在一个定制的predict_fn
函数中调用它。SageMarker 提供了一个默认的预测函数,它基本上执行model_fn().__call__()
。但是,我决定不为这个概念验证加载model_fn()
中的模型。
predict
函数返回是什么?项目中实际上有一个predict.py
脚本,我们可以执行它来从命令行调用模型。我们会得到相同的输出:
输出 _fn
我们只返回模型输出,而不是返回raw_input
和preprocessed_input
的键/值。我们可以用一个专用函数来处理这个过程:
测试 PyTorch SageMaker 端点
我想让验证端点在本地和生产环境中都能工作变得容易。介绍。
**test.py**
脚本使用两个输入调用 SageMaker 端点: 下面是一些输出:
想要测试您的生产端点吗?你猜对了!只需使用DEPLOY_ENV=production
:
回顾我们新的 SageMaker PyTorch 开发流程
下面是工作原理的总结(参见 GitHub 上的脚本):
- 特定环境设置 —将这些设置放入
deploy/sagemaker/config.yml
- 展开 :
python deploy/sagemaker/deploy.py
- 测试 :
python deploy/sagemaker/test.py
- 加载和服务模型:参见
deploy/sagemaker/serve.py
中定义的功能。
默认情况下,所有脚本都使用local
环境。要使用production
,设置DEPLOY_ENV=production
环境变量。例如,要部署到生产环境中:
ML web app 呢?
我们可以通过 SageMaker SDK 调用模型,这很好,但是做同样事情的 web 应用程序不是更酷吗?
你可以用 Flask、React、Docker 等等来构建一个网络应用。或者,您可以将booklet . ai与您的 AWS 帐户集成。事实上,我已经为这个 PyTorch 文本分类演示设置了一个 web 应用程序:
在 Booklet.ai 上试试这款 ML 车型的响应式 ui
已经可以访问 Booklet.ai?遵循我们的 SageMaker 集成说明。 还没有访问 Booklet.ai?在 Booklet.ai 报名提前获取。
摘要
通过使用 SageMaker 本地模式,我们将查看 ML 模型应用程序更改的时间从 10 分钟缩短到了 23 秒。我们可以轻松地在本地或生产中部署变更。我们已经添加了一个响应性的 web ui,通过 Booklet.ai 使用该模型,而无需构建一个定制的 Flask 应用程序。我们的 ML 应用程序开发流程现在顺畅多了!
在 GitHub 上查看本教程的源代码。
原载于 2020 年 4 月 2 日https://booklet . ai。
如何在 Linux 虚拟机上设置 Selenium
原文:https://towardsdatascience.com/how-to-setup-selenium-on-a-linux-vm-cd19ee47d922?source=collection_archive---------2-----------------------
如何在 Linux 操作系统上安装 selenium 和 chromedriver 以运行无头抓取的分步指南
尼古拉斯·皮卡德在 Unsplash 上拍摄的照片
Selenium 是测试 web 应用程序的流行框架。您在这里可能是因为您已经在本地机器上编写并测试了您的 web 抓取/测试脚本。现在,你想知道…
"我如何每 X 小时/天/周自动运行我的 Selenium 脚本?"
因此,本指南将向您展示如何使用 Selenium 和 Chromedriver 设置一个 Linux 虚拟机(VM)来实现这一点。虽然你可以一直使用 Windows 操作系统,但是在本指南中,让我们把重点放在 Linux 操作系统上。
装置
要让 selenium 和 Chromedriver 在本地机器上运行,可以分为 3 个简单的步骤:
- 安装依赖项
- 安装 Chrome 二进制和 Chromedriver
- 安装 Selenium
第一步
每当你得到一台新的 Linux 机器,总是首先更新软件包。然后安装必要的依赖项。
第二步
为了让 Chromedriver 在 Linux 上运行,你必须安装 Chrome 二进制文件。
对于 Chromedriver 版本,这将取决于你的 Chrome 二进制版本。
第三步
最后,安装 Selenium。
还有…你都准备好了!
测试您的脚本
剩下要做的就是检查 Selenium 和 Chromedriver 是否安装正确,以及您是否能够运行使用 Selenium 的 python 脚本。
from selenium import webdriver
from selenium.webdriver.chrome.options import OptionsCHROMEDRIVER_PATH = '/usr/local/bin/chromedriver'
WINDOW_SIZE = "1920,1080"chrome_options = Options()
chrome_options.add_argument("--headless")
chrome_options.add_argument("--window-size=%s" % WINDOW_SIZE)
chrome_options.add_argument('--no-sandbox')driver = webdriver.Chrome(executable_path=CHROMEDRIVER_PATH,
chrome_options=chrome_options
)
driver.get("[https://www.google.com](https://www.google.com)")
print(driver.title)
driver.close()
如果它打印“Google”,这意味着你已经在一个 Linux VM 上成功运行了带有 Chromedriver 的 Selenium!
奖金
如果你正在寻找一个文档,你很幸运。希望这有所帮助!
如何用 Ngrok 用 3 行代码分享你的 Jupyter 笔记本
原文:https://towardsdatascience.com/how-to-share-your-jupyter-notebook-in-3-lines-of-code-with-ngrok-bfe1495a9c0c?source=collection_archive---------31-----------------------
想象一下,让你的朋友在远程机器上使用你的本地 Jupyter 笔记本
动机
您是否曾经想要与您的朋友共享您的 Jupyter 笔记本以协作完成某个项目,但却发现没有协作按钮?你不能只是复制粘贴你的 Jupyter 笔记本的链接,因为它是在本地机器上运行的。你希望有一种方法,你可以给你的朋友发送一个链接,这样你们俩就可以在同一个笔记本上工作了。如果一个人在笔记本上做了更改,另一个人也会看到该更改。
Google Colab 中的共享按钮
Google Colab 允许你分享你的笔记本。Jupyter 笔记本的分享按钮在哪里?在从 Jupyter 笔记本转向 Google Colab 进行协作之前,你可以考虑另一种选择:用 ngrok 为你的 Jupyter 笔记本创建公共服务器。
照片由米米·蒂安在 Unsplash 上拍摄
Ngrok
ngrok 是什么?Ngrok 通过安全隧道将 NAT 和防火墙后面的本地服务器暴露给公共互联网。这意味着您可以将本地服务器提供给 web 服务器的端口。当您访问该 web 服务器时,您应该能够到达您指定的本地地址。在您的终端上使用 3 行代码,您将获得一个您的 Jupyter 笔记本的公共 URL,该 URL 可用于共享!
装置
从在这里安装 ngrok 开始。然后注册 ngrok 账号。注册后,你应该可以在这里获得你的隧道授权令牌。
将 authtoken 的代码复制并粘贴到终端。一旦您将带有 authtoken 的计算机链接到此帐户,您就不需要在将来重复此操作。
接下来,通过更改 Jupyter 笔记本的配置,允许远程访问 Jupyter 笔记本
jupyter notebook --generate-config
您将看到 Jupyter 笔记本配置文件的链接地址。在我的机器中,这个链接是/Users/khuyentran/.jupyter/jupyter_notebook_config.py
。复制那个地址。然后运行下面的代码
echo "c.NotebookApp.allow_remote_access = True" >> ~/.jupyter/jupyter_notebook_config.py
为了更加安全,请为您的 Jupyter 笔记本设置密码
jupyter notebook password
然后告诉 ngrok 你的 jupyter 笔记本在哪个端口运行。如果您的端口是 8888。类型:
./ngrok http 8888
您应该会看到下面的结果
点击链接 http://b32b5f59.ngrok.io 访问您隧道的公共 URL。
就是这样!现在,您应该能够复制和粘贴您生成的链接,并与您的朋友和同事分享它!确保告诉他们您访问笔记本的密码。
结论
恭喜你!您已经学习了如何共享您的 Jupyter 笔记本,以及如何在不同的机器上使用它。需要注意的一点是,由于这个公共 web 服务器连接到您的本地机器,如果您在本地机器上终止服务器,您的隧道的公共 URL 也将被终止。所以,如果你想让 Jupyter 笔记本在另一台机器上运行,请确保你的服务器正在运行。
最后但同样重要的是。在您的终端上运行以下命令行:
say "Thank you for reading this article"
我喜欢写一些基本的数据科学概念,并尝试不同的算法和数据科学工具。你可以通过 LinkedIn 和 Twitter 与我联系。
如果你想查看我写的所有文章的代码,请点击这里。在 Medium 上关注我,了解我的最新数据科学文章,例如:
[## 恐龙和圆圈的数据集可以有相同的统计数据吗?
它们有相同的中位数和标准差,但它们是两个明显不同的数据集!
towardsdatascience.com](/how-to-turn-a-dinosaur-dataset-into-a-circle-dataset-with-the-same-statistics-64136c2e2ca0) [## 如何使用 HyperDash 远程监控和记录您的机器学习实验
培训需要很长时间才能完成,但你需要去洗手间休息一下…
towardsdatascience.com](/how-to-monitor-and-log-your-machine-learning-experiment-remotely-with-hyperdash-aa7106b15509) [## 如何用 Faker 创建假数据
您可以收集数据或创建自己的数据
towards data science . com https://towards data science . com/cy thon-a-speed-up-tool-for-your-python-function-9bab 64364 bfd](/how-to-create-fake-data-with-faker-a835e5b7a9d9) [## 如何在 10 分钟内为您的数据科学产品组合创建一个优雅的网站
你需要做的就是编辑
towardsdatascience.com](/how-to-create-an-elegant-website-for-your-data-science-portfolio-in-10-minutes-577f77d1f693) [## cy thon——Python 函数的加速工具
当调整你的算法得到小的改进时,你可能想用 Cython 获得额外的速度,一个…
towardsdatascience.com](/cython-a-speed-up-tool-for-your-python-function-9bab64364bfd)
如何在一行代码中跨不同环境共享 Python 对象
原文:https://towardsdatascience.com/how-to-share-your-python-objects-across-different-environments-in-one-line-of-code-f30a25e5f50e?source=collection_archive---------32-----------------------
对设置环境与他人分享您的分析感到沮丧?以下是如何让它变得更简单
由阿克塞尔·阿霍伊在 Unsplash 上拍摄
动机
你有没有想过在不同的脚本之间共享 Python 对象?或者在你和你的队友之间分享发现,这样每个人都可以工作在最新的结果上?你可能会遇到三个困难:
- 您的队友可能会部署与您的脚本不同的环境
- 由你的队友训练的模型每天都在变化。所以他们需要每天和你分享模型。
- 文件或模型很大。每次部署脚本时重新上传它们是很麻烦的。
如果你所需要做的就是像这样共享数据帧,不是更容易吗
import datapane as dpdf = dp.Blob.get('profile', owner='khuyentran1401').download_df()df
或者类似这样的分享你的模型?
import datapane as dppredictor = dp.Blob.get(*name*='predictor',*owner*='khuyentran1401').download_obj()X_TEST = [[10, 20, 30]]outcome = predictor.predict(*X*=X_TEST)
这时我们需要 Datapane 的 Blob API
什么是 Datapane 的 Blob?
Datapane 提供了一个 API 集合,使得与其他人共享 Python 分析变得容易。如果你还不知道 Datapane,我在这里写了一篇关于 Datapane 的文章。
[## Datapane 简介:构建交互式报表的 Python 库
创建精美报告并与您的团队分享分析结果的简单框架
towardsdatascience.com](/introduction-to-datapane-a-python-library-to-build-interactive-reports-4593fd3cb9c8)
除了用于创建报告和部署笔记本的 API(在另一篇博文中显示……等等), Datapane 还提供了用于其他常见用例的 API,例如共享 blob 和管理秘密。
为了说明 Blob 的使用,我使用了来自本文的一个机器学习模型的例子。假设您正在训练一个这样的模型,它在测试集上有很好的性能。
您希望将此模型发送给您的团队成员,以便他们可以使用您的模型来预测新的数据集。你怎么能这样做?
你可以建立一个 docker 环境,并把它发送给你的队友。但如果他们只是想快速测试你的模型,而不需要设置环境,datapane.Blob
会是更好的选择。
如果您希望其他人访问它,请确保拥有visibily='PUBLIC'
。现在其他人可以用你的 blob 写他们的代码了!
Outcome : [140.]
Coefficients : [1\. 2\. 3.]`
尝试运行相同的代码,看看是否可以访问和使用预测器!在复制和粘贴代码之前,请确保预先在 Datapane 上注册以获得令牌。然后使用您的令牌
datapane login — server=[https://datapane.com/](https://datapane.com/) — token=yourtoken
登录终端
现在试试
dp.Blob.get(name='predictor', owner='khuyentran1401').download_obj()
看看您是否能够访问和使用预测器并产生与上面相同的结果!
如果您想在您的组织中私下共享您的 blob,请遵循相同的过程,但是将 blob 的可见性设置为ORG
我还能用 Blob 做什么?
除了上传 Python 对象,您还可以使用 blob 来上传 Pandas Dataframe,一个文件。
并从 blob 中获取数据帧、文件或对象
例如,在文章中,我写了我在搜集了超过 1k 个 Github 概要文件后的发现
[## 我收集了超过 1k 的顶级机器学习 Github 配置文件,这就是我的发现
从 Github 上的顶级机器学习档案中获得见解
towardsdatascience.com](/i-scraped-more-than-1k-top-machine-learning-github-profiles-and-this-is-what-i-found-1ab4fb0c0474)
为了让你访问我的数据集,我需要做的就是给你数据集的名称和我的数据面板的帐户。现在您已经准备好访问它了!
import datapane as dpdf = dp.Blob.get('profile', owner='khuyentran1401').download_df()df
当然,为了让您访问我的数据,我需要将 blob 的可见性设置为“PUBLIC”
可变的
像数据库密钥、密码或令牌这样的变量不应该嵌入到我们的代码中,尤其是当你的脚本对外界可见的时候。Datapane 的Variable
对象为提供了一种安全可靠的方式来创建、存储和检索脚本所需的值。
例如,在这个脚本中,我使用了dp.Variable
来存储我的 Github 令牌和我的用户名,这样当我在 GitHub 上共享我的代码时,我就不需要担心我的令牌被暴露了。
这个变量对我来说是完全保密的,除非我用visibility='PUBLIC'.
指定每个人都可以访问它
如果另一个拥有不同账户的人想要访问我的github_token
变量并指定我为所有者,他们将会得到一个错误
requests.exceptions.HTTPError: 403 Client Error: Forbidden for url
因为我在私有模式下使用变量。
另一个好处是:如果我碰巧在另一个脚本中重用了这个变量,我可以很容易地再次访问这个令牌,而不需要记住它是什么!
但是这不跟泡菜差不多吗?
对于那些熟悉 Python pickle 的人来说,您可能会看到 Datapane 的Blob
和Variable
的功能与 Python pickle 相似。是的,它们几乎是相似的,但是Blob
和Variable
与泡菜相比有 3 个主要的优点
- 有了
Blob,
,其他人不需要为了得到相同的模型而建立与你相似的环境。例如,您可能在 Sagemaker 上训练一个模型,并希望在您的脚本中使用它。 - 您只需使用
upload
上传更改,然后您的队友就可以使用get
查看更改,而无需将 pickle 文件发送给他人。 - 您可能会在新版本中意外出错,并希望回到旧版本(即训练错误的数据)。你可以在
get
的参数中用version =
回到老版本
结论
恭喜你!您刚刚学习了如何使用 Datapane 的Blob
和Variable
来跨不同的脚本或不同的环境共享您的数据帧、文件、Python 对象和变量。
如果你的队友只需要一行代码就能看到你的结果,而不需要设置环境,他们会很高兴的。当你的队友可以像你一样访问相同的数据时,你会很高兴。
在这个 Github repo 中,您可以随意派生和使用本文的代码。
我喜欢写一些基本的数据科学概念,并尝试不同的算法和数据科学工具。你可以在 LinkedIn 和 Twitter 上与我联系。
如果你想查看我写的所有文章的代码,请点击这里。在 Medium 上关注我,了解我的最新数据科学文章,例如:
[## 如何用 Faker 创建假数据
您可以收集数据或创建自己的数据
towardsdatascience.com](/how-to-create-fake-data-with-faker-a835e5b7a9d9) [## 字典作为 If-Else 的替代
使用字典创建一个更清晰的 If-Else 函数代码
towardsdatascience.com](/dictionary-as-an-alternative-to-if-else-76fe57a1e4af) [## 如何使用 HyperDash 远程监控和记录您的机器学习实验
培训需要很长时间才能完成,但你需要去洗手间休息一下…
towardsdatascience.com](/how-to-monitor-and-log-your-machine-learning-experiment-remotely-with-hyperdash-aa7106b15509) [## 如何通过将自己置于合适的环境中来加速您的数据科学职业生涯
我感到增长数据科学技能停滞不前,直到我有了一个飞跃
towardsdatascience.com](/how-to-accelerate-your-data-science-career-by-putting-yourself-in-the-right-environment-8316f42a476c) [## 如何创建可重用的命令行
你能把你的多个有用的命令行打包成一个文件以便快速执行吗?
towardsdatascience.com](/how-to-create-reusable-command-line-f9a2bb356bc9)
如何显示熊猫数据框的所有列/行?
原文:https://towardsdatascience.com/how-to-show-all-columns-rows-of-a-pandas-dataframe-c49d4507fcf?source=collection_archive---------0-----------------------
加:改变数据帧中数字的精度。
汉斯·雷尼尔斯在 Unsplash 拍摄的照片
(这个帖子的所有代码你可以在我的 github 里找到)
大家好!在我的熊猫提示系列文章(上一篇文章是关于分组提示的)之后,我将解释如何显示熊猫数据帧的所有列和行。除此之外,我将解释如何显示数据帧中列表中的所有值,并选择数据帧中数字的精度。所有东西都用同样的工具。
在本教程中,我使用的是从数据世界下载的前 250 个 IMDB 电影数据集。数据库有 250 行和 37 列
问题:熊猫截断信息
有时,我读取一个有许多行或列的数据帧,当我在 Jupyter 中显示时,这些行和列被隐藏(在红色框中突出显示):
movies = pd.read_csv("data/IMDB_Top250movies2_OMDB_Detailed.csv")
movies
一些行和列是隐藏的(红框)
我知道它们被隐藏起来是为了避免显示太多的信息。但是有时候我想看所有的列和行!那么,如何把它们都打印出来呢?
我们可以在熊猫身上玩选项参数。让我们看看。
选择
Pandas 有选项配置,您可以更改数据框的显示设置(等等)。
你所需要做的就是选择你的选项(用一个字符串名)并获取/设置/重置它的值。这些函数接受正则表达式模式,所以如果您传递一个子串,它将工作(除非匹配多个选项)。
列
display.max_columns 选项控制要打印的列数。它接收一个 int 或 None (打印所有列):
pd.set_option('display.max_columns', None)
movies.head()
这些列不再隐藏。Jupyter 创建一个滚动条
你也可以使用字符串 max_columns 代替 display.max_columns (记住它接受一个正则表达式):
pd.set_option('max_columns', None)
传递一个数字而不是无:
pd.set_option('max_columns', 2)
movies.head()
仅显示两列
要恢复默认值,您需要重置选项:
pd.reset_option(“max_columns”)
movies.head()
一些列再次被隐藏
列宽
您可以使用选项 max_colwidth 更改列宽。例如,图的列有许多字符,最初显示时被截断:
绘图列的某些文本被隐藏
您可以增加通过一个 int 的宽度(或设置为最大无通过):
pd.set_option(“max_colwidth”, None)
movies[[“Title”, “Plot”]].head()
将显示绘图列的全部文本
行
要更改行数,您需要更改 max_rows 选项。
pd.set_option("max_columns", 2) #Showing only two columnspd.set_option("max_rows", None)
movies
所有的行都被显示出来。Jupyter 折叠单元格并创建一个滚动条
与行相关,有两个设置: max_rows 和 min_rows 。当行数大于 max_rows 时,数据帧被截断,显示为 min_rows rows。
比如说。让我们再次打印电影数据帧以及默认值 max_rows 和 min_rows :
print("Default max_rows: {} and min_rows: {}".format(
pd.get_option("max_rows"), pd.get_option("min_rows")))movies
由于数据帧中的行数为 250(大于 max_rows 值 60),因此显示 10 行( min_rows 值),前 5 行和后 5 行。
如果我们将最小行数改为 2,它将只显示第一行和最后一行:
pd.set_option(“min_rows”, 2)
movies
仅显示两行,第一行和最后一行
如果我们使用值低于 max_rows 值(60)的 head 命令,所有的行都会被显示。例如,使用值为 20 的头:
movies.head(20)
显示所有 20 行,因为该值小于 max_rows (60)
项目顺序
如果项目序列(列表)包含许多字符,也会被截断:
#Create "my_list" column and put a list of 100 values in each row
movies[‘my_list’] = [[1]*100] * 250
movies.head()
改变这种行为的选项是 max_seq_items。但是我们也必须改变最大列宽。首先,更改 max_colwidth (列表将被截断):
pd.set_option(“max_colwidth”, None)
movies.head()
“我的列表”列已展开,但列表被截断
然后你改变最大序列项。
pd.set_option(“max_seq_item”, None)
movies.head()
显示列表的所有值
额外收获:数字的精确性
另一个有用的选项是使用精度选项设置浮点精度——小数点后的位数。
#adding more decimal places to imdbRating column
movies[‘imdbRating’] = movies[‘imdbRating’] + 0.11111
movies[[‘imdbRating’]].head()
有 5 个小数位的数字
pd.set_option(‘precision’, 2)movies[[‘imdbRating’]].head()
有两位小数的数字
来源:
- 选项和设置— pandas 1.0.1 文档
- https://stack overflow . com/questions/19124601/pretty-print-an-entire-pandas-series-data frame
- https://stack overflow . com/questions/52580111/how-do-I-set-the-column-width-when-using-pandas-data frame-to-html/52580495
谢谢,随时添加您的评论
IMDB top 250 中有一部巴西电影:上帝之城。很好看的电影=)
如何简单快捷地对熊猫数据帧进行操作
原文:https://towardsdatascience.com/how-to-simply-make-an-operation-on-pandas-dataframe-faster-adaea5e41e96?source=collection_archive---------17-----------------------
在这篇文章中,我将介绍并评估不同的 python 方法,以便在 pandas 中运行相同的函数并创建新的列。这些方法将在数值和非数值运算中进行检查。
Marc Sendra Martorell 在 Unsplash 上拍摄的照片
如果你以前有过足够大的数据集,你就会知道有时一个简单的操作需要很多时间。有很多方法可以使熊猫数据帧上的操作更快。你可以使用像 multiprocessing,modin[ray],cuDF,Dask,Spark 这样的库来完成这项工作。此外,您可以修改您的算法,以更快地执行任务。但是在寻求一个困难的解决方案之前,让我们看看有没有简单的方法来获得更高的速度和节省一些时间!
至于我的数据集,我用的是T5 这个 T7 的一部分。它有两个数字列和一个文本列,由“HelpfulnessNumerator”列中的 0 和“ProfileName”列中的 NaN 组成。(数据集和所有笔记本都已经上传到了 这个 Github 资源库中。)
数值运算
我想在不改变主函数的情况下简单地检查不同的方法。数字部分的函数是一个除法函数。
**def** divide(t,h):
**if** h == 0:
**return** np.nan
**return** t/h
我在处理熊猫数据帧时学到的第一件事是 df.iterrows()
%%timeit
iterrows_divide = []
**for** index,row **in** df.iterrows():
Time = row['Time']
HelpfulnessNumerator = row['HelpfulnessNumerator']
iterrows_divide.append(divide(Time,HelpfulnessNumerator))
5min 12s ± 31.1 s per loop (mean ± std. dev. of 7 runs, 1 loop each)
apply()方法是另一个选项:
%timeit df.apply(**lambda** row: divide(row['Time'],row['HelpfulnessNumerator']),axis = 1)1min 25s ± 4.88 s per loop (mean ± std. dev. of 7 runs, 1 loop each)
pandas 行操作中最好的选择是 itertuples()方法:
%%timeit
itertuples_divide = []
**for** _ **in** df.itertuples():
Time = getattr(_,'Time')
HelpfulnessNumerator = getattr(_,'HelpfulnessNumerator')
itertuples_divide.append(divide(Time,HelpfulnessNumerator))4 s ± 238 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
大多数情况下,我们并不强制使用按行操作。但如果对你来说是必须的,df.itertuples()是最快的方法。
让我们试试 map()方法:
%timeit list(map(divide,df['Time'],df['HelpfulnessNumerator']))861 ms ± 22.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
让我们做一些(假的)numpy 矢量器()方法:
%timeit np.vectorize(divide)(df['Time'],df['HelpfulnessNumerator']) 636 ms ± 24.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
我们可以对(实)numpy 矢量器使用 numpy where()方法:
%timeit np.where(df['HelpfulnessNumerator'] == 0 , 0 , df['Time']/df['HelpfulnessNumerator'])21.6 ms ± 329 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
正如你所看到的,我们不能在任何地方使用 np.where()方法。但是真的很快。让我们稍微改变一下函数:
**def** modified_divide(t,h):
**return** t/h
现在我们可以在 np.where()中使用这个函数:
%timeit np.where(df['HelpfulnessNumerator'] == 0 , 0 , modified_divide(df['Time'],df['HelpfulnessNumerator']))21.4 ms ± 200 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
此外,我们可以直接用 pandas 操作这个函数:
%timeit modified_divide(df['Time'],df['HelpfulnessNumerator'])8.75 ms ± 114 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
还有其他选择吗?绝对是的。如果你能用 Python 写代码,你就能用 Fortran 写代码。我在 Jupyter 笔记本里为 Fortran magic 做了一个 笔记本 。举个例子,看看这个:
%%fortran
subroutine fortran_divide(x, y, z)
real, intent(**in**) :: x,y
real, intent(out) :: z
z = x/y
IF ( 0 .EQ. Y ) THEN
Z = 0
END IF
end subroutine fortran_divide%timeit np.vectorize(fortran_divide)(df['Time'],df['HelpfulnessNumerator'])669 ms ± 22.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
我们可以用 numba。Numba 是一个 python 库,我们可以非常直接地使用它。它比 np.where()快 2 倍,而且这里没有 np.where()的一些限制:
**from** **numba** **import** njit
@njit()
**def** divide(t, h):
res = np.empty(t.shape)
**for** i **in** range(len(t)):
**if** h[i] != 0:
res[i] = t[i] / h[i]
**else**:
res[i] = 0
**return** res
%timeit divide(df['Time'].values, df['HelpfulnessNumerator'].value9.99 ms ± 133 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
numba 和 Fortran 都可以选择使用多处理的能力。这取决于数据帧的大小和操作。有时候我们可以使用多重处理来获得更快的速度,而有时候 numba 和 Fortran 中的多重处理对我们没有太大帮助。
每种方法的对数时间。
总之,不要在 pandas 数据帧上使用逐行操作。如果是必须的,可以使用 df.itertuples()。永远不要使用 df.iterrows()和 df.apply(…,axis=1)。
大部分时候可以用 np.where()搭配一些小技巧。这是最好的选择。但是如果不能使用,可以在进行数值运算的同时使用 np.vectorize()。
如果我们有一个很大的数据集,有一些其他的选项可以帮助我们,比如 numba 和 Fortran magics,值得花一些时间去学习和使用它们。
另外,有时候熊猫本身也支持我们想要的。先查熊猫比较好。😃
非数值运算
我将定义一个简单的函数来评估不同的方法。该函数将在每条记录的开头添加一个短语。
**def** edit_name(profileName):
**if** profileName != profileName:
**return** np.nan
**return** 'Name is **{}**'.format(profileName)
使用 df.iterrows()很简单。但是它太慢了:
%%timeit
iterrows_name=[]
**for** index,row **in** df.iterrows():
name = edit_name(row['ProfileName'])
iterrows_name.append(name)4min 15s ± 2.45 s per loop (mean ± std. dev. of 7 runs, 1 loop each)
使用逐行应用方法():
%timeit df.apply(**lambda** row: edit_name(row['ProfileName']),axis = 1)43.2 s ± 687 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
使用 itertuples()方法:
%%timeit
itertuples_name=[]
**for** _ **in** df.itertuples():
name = edit_name(getattr(_,'ProfileName'))
itertuples_name.append(name)3.78 s ± 128 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
另一种使用 apply()的方法:
%timeit df['ProfileName'].apply(**lambda** x: edit_name(x))1.58 s ± 86.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
让我们使用 map()方法:
%timeit list(map(edit_name,df['ProfileName']))1.41 s ± 65.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
哎呀,np.vectorizer 没有我们预期的那么快。是的,因为运算不是数值的。
%timeit np.vectorize(edit_name)(df['ProfileName'])2.16 s ± 155 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
有一只熊猫。可以非常快速地完成有限任务的 Series.map 。它可以自己处理 NaN 值。例如,让我们更改函数并查看结果:
**def** modified_edit_name(profileName):
**return** 'Name is **{}**'.format(profileName)
我们可以在 np.where()中轻松处理 NaN 值:
%timeit np.where(df['ProfileName'] == np.nan,np.nan, modified_edit_name(df['ProfileName']))2.69 s ± 98.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
熊猫系列地图方法:
%timeit df['ProfileName'].map('Name is **{}**'.format, na_action='ignore')1.16 s ± 50.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
每种方法的对数时间。
说到文字,我更喜欢用 map(),因为它速度快。如果我必须进行行操作,我将使用 df.itertuples()。
正如我所说的,在这个简单的优化之后,我们可以在应用多重处理和使用其他库之后对 pandas DataFrame 进行更快的操作。
关于 numba 和 Fortran magic 的更多信息,请看这里:
[## 示例- numba 0.15.1 文档
假设我们想用 Python 写一个图像处理函数。下面是它可能的样子。Numba 实际上产生了两个…
numba.pydata.org](http://numba.pydata.org/numba-doc/0.15.1/examples.html) [## mgaitan/fortran_magic
使用 f2py,用 Fortran 代码编译和导入单元格中的符号。单元格的内容被写入 a .f90…
github.com](https://github.com/mgaitan/fortran_magic) [## 从 python 使用 fortran
我喜欢 numpy(python 中数值计算的核心库),但在一些非常罕见的情况下,我需要实现…
arogozhnikov.github.io](http://arogozhnikov.github.io/2015/11/29/using-fortran-from-python.html)
如何用 Python 模拟金融投资组合
原文:https://towardsdatascience.com/how-to-simulate-financial-portfolios-with-python-d0dc4b52a278?source=collection_archive---------19-----------------------
克里斯·利维拉尼在 Unsplash 上的照片
多维几何布朗运动的一个应用
来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们并不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语 。
在一个日益全球化的世界里,金融市场不断受到越来越多因素的影响:新闻、政治、体育……尤其是市场本身。许多科学家正试图对金融市场内外事件之间的这些相互作用进行抽象和建模。然而,在定量金融领域,很难开发出一个代表实际市场的模型。然而,需要一个有价值的市场模拟模型来解决以下问题:
- 期权定价;
- 投资组合估价;
- 对冲策略;
- 敏感性分析;
- 不确定的未来现金流计算。
简而言之,高效地模拟尽可能多的场景,有助于我们减少市场不确定性带来的不便。下面我介绍一个强大的方法来实现一个简单而有价值的市场模拟模型。
单只股票的价格趋势可以被塑造成一个随机过程,称为几何布朗运动(GBM)模型。然而,对于由多个公司股票组成的投资组合,我们需要扩展 GBM 模型。本文旨在使用多维几何布朗运动模型对投资组合中的一个或多个股票价格进行建模。
总结
- 介绍
- 理论和算法
- 用 Python 实现
- 投资组合模拟示例
- 结论
介绍
尽管我们可以非常精确地计算出子弹的轨迹,但预测市场趋势似乎是不可能的。至少到目前为止。
这是因为金融市场的随机特性使其成为复杂系统的完美例子。事实上,复杂系统有一个本质上难以塑造的行为,因为它们各部分之间的相互作用(在物理数学意义上)。在复杂系统中,部件的集体行为会导致特征的出现,而这些特征很难从单个部件的属性中推断出来,甚至根本无法推断出来。
"整体是部分之外的东西."
金融市场的复杂性源于其各部分之间的高度相关性。相互作用的非线性本质反映在因果过程中,直到产生不可预测的事件。由于这个原因,他们的行动之间的相互关系的性质和动态特征是金融市场复杂性的关键方面。
然后,重要的是建立一个连贯的和尽可能现实的市场模型,以便对这一特征的研究可以改进经济预测和复合金融规模的形成,如股票投资组合。
理论和算法
一维
几何布朗运动是一个连续时间的随机过程。更严格地说,几何布朗运动过程是通过以下形式的随机微分方程(SDE)来规定的
其中 W 是布朗运动,和σ是分别代表百分比漂移和百分比波动的常数。
上述 SDE 有解析解
这提供了一个简单的递归过程,用于在时间离散化的每个瞬间模拟 S 的值:
对于 n = 0,1,…,N -1 ,与 Z 独立的标准法线。
多个维度
多维几何布朗运动可以通过一个随机微分方程系统来描述。假设您想要模拟一个由 d 支股票组成的投资组合,系统采用以下形式
用 i = 1,.。。
股票之间的相关信息包含在布朗运动中,事实上我们有
如果我们通过设置定义一个d×d矩阵σ
在一个方便的术语滥用中,我们称σ为协方差矩阵;尽管协方差由下式给出
回想一下,具有均值 0 和协方差矩阵σ的布朗运动可以表示为 AW ,其中 W 为标准布朗运动,而 A 为
我们可以应用这个性质,把 SDE 的系统改写成
这种表示导致了用于模拟多维 GBM 的简单算法:
对于 i = 1,.。。,d 和 n = 0,…,N -1 ,其中 Z 为标准正态随机向量。
注:选择 A 为σ的乔莱斯基因子,可以减少每一步所需的乘法和加法的次数。
有关更多详细信息,请参见参考文献[1]。
用 Python 实现
我们使用 numpy 包及其矢量化属性来使程序更紧凑、更易于阅读、维护和更快执行。
我们定义一个函数来模拟给定参数的多维 GBM。除了模型参数之外,我们还选择插入一个与随机化种子相关的参数,以便能够以相同的结果重复模拟。
我们构建一个包含所有模拟股票路径的大小(股票数量,增量数量)数组。
投资组合模拟示例
让我们从展示二维情况的例子开始。对于这种情况,假设我们想从时间序列中估计模型参数。
一个简单的方法是使用一个名为 pandas_datareader (这里是文档的链接)的库。
我们选择任意两只股票,例如英特尔(INTC)和 AMD。
因此,我们有熊猫数据框架形式的历史数据。
为了估计𝜇、𝜎和𝐶𝑜𝑣的参数,我们计算了调整后收盘价的对数收益。
模拟获得的投资组合的 2 支股票与真实数据估计参数。
对于有超过 2 只股票的多维情况,我们选择通过随机化参数来举例。特别是,我们从相关矩阵开始创建协方差矩阵,因为它们必须符合特定的数学条件。我们记得这两个矩阵之间的关系由下面的公式描述
为了应用乔莱斯基分解,协方差矩阵必须是对称正定的。
因此,让我们利用 scipy 库获得一个随机相关矩阵,给定一个特征值向量。
用随机参数对 10 只股票的投资组合进行模拟。
结论
由于几何布朗运动的推广,本文提供了一个算法来模拟一只或多只股票,并强调了多维相关性的重要性。上面的例子显示了用 Python 实现一个在各种金融应用中有用的数学模型是多么简单。很明显,从这个基本模型开始,通过引入进一步的细节,例如与时间相关的参数,可以使模型越来越复杂。
点击此处查看完整代码。感谢阅读,希望这篇文章对你有所帮助!
参考
[1] P .格拉斯曼,金融工程中的蒙特卡罗方法。第 53 卷(2013),施普林格科学&商业媒体。
如何用 Python 模拟交易
原文:https://towardsdatascience.com/how-to-simulate-trades-in-python-7e613c83fd5a?source=collection_archive---------11-----------------------
我们总是看到,所谓的交易者声称他们有超过 70%的胜率,他们的风险回报比超过 1:2(风险 1%,盈利 2%)。你觉得可能吗?让我们来了解一下!
作者图片
我有 70%的胜率,风险回报比为 1:2
ROFL!你确定你没有错过高中的数学课(可能是小学?!)?请记住,在 2019 年,对冲基金的平均回报率为 6%。这里是来源的链接。
现在让我们开始谈论 Python。
我们只需要两个库
import numpy as np
import matplotlib.pyplot as plt
现在我们需要写一个函数来模拟交易。当然不是真的。
def simulate(account_size, total_trades, risk_per_trade, win_rate, risk_reward):
account = account_size
accounts = [account]
profits = []
loss = []
wins = []
total_win = 0
max_con_l = 0
max_con_w = 0
con_l = 0
con_w = 0
pre = 0
rnd = list(np.round(np.random.uniform(1, 101, total_trades), 2))
for i in range(len(rnd)):
r = rnd[i]
win = r <= win_rate
risk = -np.round(account * risk_per_trade / 100, 2)
profit_per_trade = abs(risk) * risk_reward
profit = profit_per_trade if win else risk
profits.append(profit)
account += profit
accounts.append(account)
if profit > 0:
total_win += 1
wins.append(profit)
con_l = 0
if pre == 1:
con_w += 1
if con_w > max_con_w:
max_con_w = con_w
pre = 1
else: # 0 is also a loss (spread + commissions)
loss.append(abs(profit))
con_w = 0
if pre == -1:
con_l += 1
if con_l > max_con_l:
max_con_l = con_l
pre = -1
avg_win = np.mean(wins)
avg_loss = np.mean(loss)
max_win = np.max(wins)
max_loss = np.max(loss)
win_r = np.round(total_win / total_trades * 100, 2)
rrr = np.round(avg_win / avg_loss, 2)
profit_factor = np.round(np.sum(wins) / np.sum(loss), 2)
net_profits = np.cumsum(profits)
gain = np.round(accounts[-1] - account_size, 2)
growth_rate = np.round((accounts[-1] - account_size) / account_size * 100, 2)
print("--- Trading Results ---\n")
print("Total trades : {}".format(total_trades))
print("Wins : {} / {}%".format(total_win, win_r))
print("Average Win : {}".format(np.round(avg_win, 2)))
print("Average Loss : {}".format(np.round(avg_loss, 2)))
print("Max Win : {}".format(np.round(max_win, 2)))
print("Max Loss : {}".format(np.round(max_loss, 2)))
print("Max Cons. Wins : {}".format(max_con_w))
print("Max Cons. Loss : {}".format(max_con_l))
print("Risk Reward Ratio : {}".format(rrr))
print("Profit Factor : {}".format(profit_factor))
print("Risk per trade : {}%".format(risk_per_trade))
print("---")
print("Initial Account : {}".format(account_size))
print("Profit : {} / {}%".format(gain, growth_rate))
print("Final Account : {}".format(np.round(account, 2)))
print()
print("Results are compounded. Spread and commissions are not calculated.")
fig, ax = plt.subplots(2, 1, figsize=(16, 10))
ax[0].plot(net_profits)
ax[1].plot(accounts)
ax[1].axhline(account_size, color="#000000", ls="-.", linewidth=0.5)
ax[0].set_title("Equirty Curve")
ax[1].set_title("Account Growth")
plt.show()
让我们来定义一下这个人的说法
account_size = 10000
total_trades = 200 #trades per year maybe?
risk_per_trade = 2 #risk 2% of your account per trade
win_rate = 70 # in percentage
risk_reward = 2 # risk 1% profit 2%
OMG!这太疯狂了。如果你准备好了,我们就跑吧?😃
simulate(account_size, total_trades, risk_per_trade, win_rate, risk_reward)
奥斯卡颁给了这个家伙!!!!
他每年能赚 80% 25%还想卖给你一个产品?!加油!!!!
ok;现在让我们试着更现实一点。我将使用以下参数:
account_size = 10000
total_trades = 200 #trades per year maybe?
risk_per_trade = 2 #risk 2% of your account per trade
win_rate = 52
risk_reward = 1.4
结果呢
即使有 52%的胜率和 1.4 的风险回报比,每年也能赚 193%!然而,这并不容易。
结论
请不要再相信那些所谓的交易者了。大多数社交媒体交易者都是骗子。他们只是想卖给你一个梦想和他们所谓的圣杯产品。没有圣杯,你也不需要 70%的胜率。
免责声明
我不是专业的财务顾问。这篇文章和代码,分享仅用于教育目的,而不是财务建议。你要对自己的输赢负责。
本文的全部代码可以在这个资源库中找到:
[## atillayrutten/贸易模拟
如何用 Python 模拟交易?通过创建一个关于…的帐户,为培训/贸易模拟发展做出贡献
github.com](https://github.com/atillayurtseven/TradeSimulation)
啊也;记得在以下社交渠道关注我:
中型
推特
YouTube!
交易视图
直到下次;保持安全,交易安全!!!
图片来自:https://hacker noon . com/algo-trading-for-dummies-implementing-an-actual-trading-strategy-part-4-acec 5543052 b
阿蒂拉·尤尔特塞文
注来自《走向数据科学》的编辑: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语 。
如何用 Word2Vec 解决类比问题
原文:https://towardsdatascience.com/how-to-solve-analogies-with-word2vec-6ebaf2354009?source=collection_archive---------11-----------------------
美国之于加拿大,就像汉堡之于 _?
Word2vec 是什么?
为了让机器学习算法理解单词,使用单词嵌入将单词映射到实数的向量。有各种各样的单词嵌入模型,word2vec 就是其中之一。
简而言之,word2vec 是一组用于产生单词嵌入的相关模型。这些模型被训练来构建单词的语言上下文。Word2vec 采用大型文本语料库并产生一个向量空间,其中将语料库中的每个唯一单词分配给空间中相应的向量。
但是单词向量在向量空间中是如何定位的呢?它们被定位成使得在语料库中共享共同上下文的单词在空间中彼此靠近。
从怀特哈特学校取得
为了理解 word2vec 是如何工作的,让我们探索一些可以使用 word2vec 的方法,比如寻找单词之间的相似性或解决类似的问题
加载数据和模型
我们将使用来自手套的预训练单词向量。我们对包含 2B 推文、27B 令牌和 200d 向量的 Twitter 数据集特别感兴趣。数据可以在这里下载。我们使用 Gensim 将手套向量转换成 word2vec,然后使用 KeyedVectors 加载 word2vec 格式的向量。
查找最相似的单词
现在我们用model.most_similar()
来寻找前 N 个最相似的单词。积极的词语对相似性有积极的贡献。负面词汇对相似性有负面影响,或者换句话说,对差异有影响。让我们测试一下这个模型!
找出与“爱”最相似的单词
model.most_similar(positive=['love'])
“女孩”怎么样?
model.most_similar(positive=['girl'])
。我们不妨查一下和‘男孩’类似的词
model.most_similar(positive=['boy'])
嗯。那么‘男孩’和‘男人’在相似的词上有区别吗
model.most_similar(positive=['man'])
“男孩”变成“男人”似乎有明显的不同
解决类比
单词嵌入方法还能够捕获单词之间的多个不同程度的相似性。语义模式可以使用向量算法来复制。因此,我们也可以使用 word2vec 来解决类比问题。如果美国有汉堡包,加拿大有什么食物?
结果似乎显示了加拿大流行的各种食物。来自加拿大的读者可以确认这些热门词汇是否合理。让我们用一个名为analogy().
的函数再探索几个国家。这次,我们只为每个类比返回一个最上面的相似单词。
既然可视化很好,让我们创建一个国家和它们相应的食物之间的地图。我们使用主成分分析将数据的维数降低到 2。
在这张地图上,国家之间的距离显示了在二维空间中哪些国家彼此更接近。箭头表示国家和食物之间的关系。
结论
恭喜你!你已经学习了什么是 word2vec,以及如何用 word2Vec 寻找单词之间的相似之处。看到 word2vec 的强大,你可能会想:“这种方法怎么能工作得这么好?”
我们知道,word2vec 对象函数导致出现在相似上下文中的单词具有相似的嵌入。但有趣的是,是什么让 word2vec 框架中的单词嵌入学习如此有效却知之甚少。无论是什么原因使这种嵌入成功,我希望您理解它的功能,并利用这个强大的工具进行文本分析。我鼓励您使用这个数据集或您选择的数据集来创建 word2vec 的其他类比。
在 this Github repo 中,您可以随意使用本文的代码。
我喜欢写一些基本的数据科学概念,并尝试不同的算法和数据科学工具。你可以通过 LinkedIn 和 Twitter 与我联系。
如果你想查看我写的所有文章的代码,请点击这里。在 Medium 上关注我,了解我的最新数据科学文章,例如:
[## 如何找到和 Python 很好的搭配
给定个人偏好,如何匹配使得总偏好最大化?
towardsdatascience.com](/how-to-match-two-people-with-python-7583b51ff3f9) [## 字典作为 If-Else 的替代
使用字典创建一个更清晰的 If-Else 函数代码
towardsdatascience.com](/dictionary-as-an-alternative-to-if-else-76fe57a1e4af) [## 用 Python 选择要投资的股票
您计划在未来 3 年投资几只股票,每只股票的每一美元都有不同的预期回报…
towardsdatascience.com](/choose-stocks-to-invest-with-python-584892e3ad22) [## 使用 Python 最大化您的生产力
你创建了一个待办事项清单来提高效率,但最终却把时间浪费在了不重要的任务上。如果你能创造…
towardsdatascience.com](/maximize-your-productivity-with-python-6110004b45f7) [## 用这 6 个小窍门提高你的效率
并控制您的阵列
towardsdatascience.com](/boost-your-efficiency-with-these-6-numpy-tricks-29ca2fe81ecd)
参考
Word2vec。维基百科。【https://en.wikipedia.org/wiki/Word2vec 号
如何解决编码问题
原文:https://towardsdatascience.com/how-to-solve-coding-problems-e86944c5bfdf?source=collection_archive---------17-----------------------
Daria Nepriakhina 在 Unsplash 上拍摄的照片
工作数据科学家的实际问题解决策略
曾经写过的每一行代码最终都是为了一个目的:解决问题。无论你做什么,你都是在同时解决几个方面的问题。
一个小的一行程序解决了一个让函数工作的问题。数据处理管道需要该函数。该管道被集成到一个平台,该平台为其用户实现了机器学习驱动的解决方案。
问题无处不在。它们的规模和影响可能不同,但解决问题的一般策略是相同的。
作为一名工程师、开发人员或数据科学家,有效地解决问题真的可以提高你的成绩,让你领先于你的同行。有些人经过多年的练习可以本能地做到这一点,有些人则需要有意识地努力去学习。然而,无论你是谁,你都可以并且你必须提高你解决问题的技巧。
有了研究级数学的背景,我有机会练习解决问题并观察过程。令人惊讶的是,这不是你每次都要即兴创作的东西。相反,
一个成功的问题解决者有几个标准的工具和一个总的计划,并随时调整。
在这篇文章中,我的目标是给出这些工具的一个概述,并使用它们来创建一个可以随时遵循的过程。为了使情况变得现实,让我们将自己置于以下场景中:我们是深度学习工程师,正在研究对象检测模型。我们的数据有限,所以需要为图像增强提供一个解决方案。
图像放大。来源:相册自述文件
增强是通过应用随机变换(如裁剪、模糊、亮度变化等)从可用图像生成新数据的过程。请看上面的图片,它来自 awesomealbuminations库的自述文件。
你需要在下周之前发布这个特性,所以你需要马上开始工作。如何处理问题?
(作为一名数学家,我的思维过程深受乔治·波利亚的《如何解决》一书的影响。虽然数学问题不同于现实生活中的编码问题,但这是任何希望解决问题的人的必读之作。)
照片由新闻社在 Unsplash 上追踪
步骤 0:理解问题
在试图解决你脑海中的任何问题之前,有一些问题需要回答。没有正确理解一些细节会导致浪费时间。你肯定不想这么做。例如,明确以下几点是有好处的。
- 问题的规模有多大?在我们的图像增强示例中,您是否需要在生产中每秒处理数千张图像,或者只是让您尝试一些方法?如果需要生产级解决方案,您应该提前意识到这一点。
- 其他人会使用你的解决方案吗?如果人们打算广泛地使用你的代码,必须在代码质量和文档方面投入大量的精力。另一方面,如果这只是供您使用,就没有必要在这方面做太多工作。(我已经看到有人不同意我的观点:)然而,我坚信应该尽量减少工作量。所以,如果你只需要快速尝试一个想法和实验,请放心而不是考虑代码质量。)
- 您需要一般解决方案还是特殊解决方案?许多时间会被浪费在实现没人会用到的功能上,包括你自己。在我们的例子中,您需要广泛的图像增强方法,还是只需要垂直和水平翻转?在后一种情况下,预先翻转图像并将其添加到训练集中也是可行的,这需要最少的工作。
衡量你理解程度的一个很好的标准是你解释和与他人讨论问题的能力。讨论也是发现意想不到的方法和边缘案例的好方法。
当您理解了您的约束并有了一个稍微精确的问题规范时,就该开始工作了。
第一步。有没有现成的解决方案?
你必须做的第一件事就是寻找现有的解决方案。除非你正在挑战人类知识的极限,否则其他人已经遇到了这个问题,创建了一个关于堆栈溢出的线程,并可能围绕它编写了一个开源库。
利用这一点。使用成熟的工具,而不是创建自己的工具,有几个好处。
- 你节省了大量的时间和工作。在时间紧迫的情况下,这一点至关重要。(我的一个老师曾经讽刺地说“你可以用两个月的工作节省一个小时的谷歌搜索”。完全正确。)
- 既定的工具更有可能是正确的。开源工具不断得到社区的验证和检查。因此,它们不太可能包含 bug。(当然,这不是保证。)
- 更少的代码供你维护。同样,我们应该一直努力降低复杂度,最好是代码量。如果你使用外部工具,你就不用担心它的维护,这是一个很大的好处。每一行代码都有隐藏的维护成本,以后再支付。(往往是最不方便的时候。)
初级开发人员和数据科学家经常忽略这些,更喜欢从头开始编写所有东西。(我当然有,但很快就学会了更好地了解。)我见过最极端的案例是一个开发者,他自己写的深度学习框架。你应该永远不要这样做,除非你是一个深度学习研究者,并且你知道如何比现有的框架做得更好。
当然,并不是所有的问题都需要一个完整的框架,也许你只是在寻找一个命令行程序。寻找现有的解决方案肯定是有益的,尽管在这种情况下你需要小心。如果您花时间去理解它是如何工作的以及为什么工作,那么从堆栈溢出中查找和使用代码片段是很好的。不这样做可能会导致不愉快的调试会话,甚至在最坏的情况下导致严重的安全漏洞。
[## 为什么堆栈溢出的代码片段会破坏您的项目
您会惊讶地发现,许多最常见的解决方案都包含安全漏洞
medium.com](https://medium.com/better-programming/why-code-snippets-from-stack-overflow-can-break-your-project-ced579a48ddb)
对于这些较小的问题,寻找现有的解决方案包括浏览教程和最佳实践。总的来说,在无情的实用主义和盒子外面的思维之间有一个平衡。当你以通常的方式实现某个东西时,你是在为将要使用和维护这段代码的开发人员做一件好事。(往往包括你。)
有一个现有的解决方案。接下来呢?
假设在您为数据预处理管道提供图像增强的道路上,您遵循了我的建议,寻找现有的解决方案,并找到了令人敬畏的album ations库。太好了!接下来呢?
一如既往,需要考虑的事情范围很广。不幸的是,仅仅因为您已经确定了一个可能是潜在解决方案的外部工具,并不意味着它将适合您的目的。
- 它工作正常吗?是否得到了适当的支持?有一件事比不使用外部代码更糟糕:使用有 bug 且未经维护的外部代码。如果一个项目没有被很好地记录并且没有被维护,你应该避免它。
对于较小的问题,答案通常可以在堆栈溢出中找到,而运行良好的部分是必不可少的。(见上面我链接的帖子。) - 是直接适应吗?例如,如果您使用的图像处理库与相册不兼容,那么您必须做额外的工作。有时,这可能太多,你必须寻找另一种解决方案。
- 性能是否足够?如果您需要每秒处理数千张图像,性能是一个因素。一个库使用起来可能非常方便,但是如果它不能运行,它就必须被淘汰。这可能不是所有情况下的问题(例如,如果你只是在寻找一个快速的解决方案来做实验),但如果是,应该在投入大量工作之前尽早发现。
- 你了解它是如何工作的吗?它的基本假设是什么?由于我上面提到的原因,对于使用堆栈溢出代码片段来说尤其如此。对于更复杂的问题,如图像增强问题,您不需要逐行理解每一段外部代码。但是,您需要了解库的要求,例如输入图像的格式。
当然,这只有在你确实能找到外部解决方案的情况下才适用。请继续阅读,看看在这种情况下应该怎么做。
照片由印尼 UX在 Unsplash 上拍摄
如果没有现成的解决方案呢?
有时候你必须自己开发解决方案。问题越小,发生的越频繁。这些都是学习和建设的大好机会。事实上,这是真正的解决问题的部分,也是最让我们兴奋的部分。
有几种策略可以采用,它们都应该在你的工具箱里。如果你仔细阅读,你会发现有一个共同的模式。
- 你能简化吗?有时候,只解决一个特例就够了。例如,如果您确实知道图像增强管道的输入将总是具有相同的格式,则没有必要花费时间来处理几种情况下的输入。
- 隔离问题的组件。解决一个问题可能很难,更别说同时解决两个了。你应该总是让事情变得简单。当我年轻的时候,我曾经认为解决困难的问题是为了得到发展点。很快,我意识到解决难题的人总是通过解决许多小问题来做到这一点。
- 你能解决特殊情况吗?在你实现一个图像增强的抽象接口之前,你应该做一个方法来添加到你的管道中。一旦您发现了更好的细节并规划出确切的需求,就可以设计出更通用的解决方案。
本质上,解决问题是一个迭代的过程,在这个过程中,你一步一步地把问题分解,最终把它简化成容易解决的部分。
照片由莫里茨·门吉斯在 Unsplash 上拍摄
第二步。打破解决方案(可选)
我注意到许多优秀的数学家和开发人员有一个共同的特点:他们喜欢分析解决方案,分析是什么让他们工作。这是您学习的方式,也是您构建健壮而简单的代码的方式。
打破东西可能是解决问题过程的一部分。从特殊情况到一般情况,你通常会通过打破现有状况来找到解决方案。
当它完成的时候
根据问题本身的严重程度,如果允许的话,您应该考虑开源它。为其他开发人员解决问题是对社区做出贡献的一个很好的方式。
例如,我就是这样构建了model,这是 Python 最流行的主动学习库之一。我从一个非常具体的问题开始:为生物信息学构建主动学习管道。因为构建复杂的方法总是需要实验,所以我需要一个能够快速实验的工具。用当时可用的框架很难做到这一点,所以我慢慢地将我的代码转换成一个可以被其他人轻松采用的工具。
[## modAL-python/modAL
Python3 的模块化主动学习框架 modAL 是 Python3 的一个主动学习框架,用…
github.com](https://github.com/modAL-python/modAL)
曾经“只是”一个解决方案变成了一个库,拥有成千上万的用户。
结论
与流行的观点相反,有效的解决问题并不等同于一直有好主意。相反,它是一个思维过程,带有一些定义明确且易于使用的工具,任何人都可以学习。聪明的开发人员本能地使用这些,使它们看起来像魔术一样。
解决问题的技巧可以通过有意识的练习和思考习惯来提高。你可以在几个平台上发现问题并着手解决,比如 Project Euler 或 HackerRank 。然而,即使你开始应用这些方法来解决你在工作中遇到的问题,你也会看到你的技能迅速提高。
如果你喜欢把机器学习概念拆开,理解是什么让它们运转,我们有很多共同点。看看我的博客,我经常在那里发表这样的技术文章!
如何解决你深度学习训练中的数据加载瓶颈
原文:https://towardsdatascience.com/how-to-solve-data-loading-bottlenecks-in-your-deep-learning-training-1ddfcc24449b?source=collection_archive---------14-----------------------
即使你没有固态硬盘
在 Unsplash 上由 Varun Gaba 拍摄的照片
深度学习训练中的每一次迭代,你都形成一批数据,并传递给模型。从 HDD 中读取数据是一个非常耗时的过程,因为机械致动器臂会穿过 HDD 板来寻找数据点的目标块。你知道,我们通常混洗数据集,并从这个混洗的数据集形成批次。这意味着批次中的数据点随机分布在硬盘中。这称为随机读取,与顺序读取相比非常慢。如果您要训练大型数据集(如 ImageNet ),您应该避免这些类型的瓶颈。下面是一个例子:使用 RTX2080 GPU 和 7200 RPM HDD ,ResNet18 模型在 ImageNet 数据上的一次迭代需要 32 个批处理大小,耗时 0.44 秒。100 个纪元,需要 20 天!当我们测量函数的计时时,数据加载+预处理需要 0.38 秒(其中 90%的时间属于数据加载部分),而优化(向前+向后传递)时间只需要 0.055 秒。如果将数据加载时间减少到合理的时间,完全训练可以轻松减少到 2.5 天!
硬盘内部。我们在深度学习训练中形成批次时执行随机访问。照片由弗兰克 R 在 Unsplash。
最基本、最快的解决方案:购买 NVMe 固态硬盘
如果你的硬件系统支持固态硬盘,购买一个 NVMe M2 型固态硬盘将立即解决你的问题。为什么?让我们检查一些存储设备的读取速度。
7200 RPM 硬盘:100 MB/秒
采用 SATA 速度的固态硬盘:600 MB/秒
SSD (NVMe 型)通过 M2:3500 MB/秒
所以在 NVMe 型固态硬盘和你的 7200 RPM 硬盘之间,有 35 倍的差别。因此,购买和 NVMe 类型的固态硬盘是最基本和最快的解决方案。
如果固态硬盘不适合您,该怎么办?然后你必须继续使用你的硬盘。这是一些收据,可以让你用硬盘更快地加载数据。
1.如果你的数据是在硬盘上,它适合内存
在训练开始时将所有数据集加载(读取)到 RAM 中,这样在每次迭代中就不会消耗从磁盘读取的时间。你必须为此编写一个自定义数据集类(对于 PyTorch,请查看这里:https://py torch . org/tutorials/beginner/data _ loading _ tutorial . html)。
2.如果您的数据存储在硬盘中,但不适合存储在 RAM 中
如果您正在处理大型数据集,如 ImageNet(大约 150 GB),您不能将所有数据加载到 RAM 中。所以,你必须从硬盘上一批一批地读取数据。然而,我们怎样才能让它更快呢?提示在本文的第一段:我们应该执行顺序读取而不是随机读取。
你混洗你的数据集,并将混洗后的数据集再次写入磁盘,这样,如果你按顺序读取每一批,你将得到混洗后的批。您可以使用 Tensorpack 库来完成此操作(https://tensor pack . readthedocs . io/tutorial/efficient-data flow . html)。
当您没有固态硬盘时,Tensorpack 库是一个救命恩人[1]。
现在,让我们比较这三种不同的数据加载方法。
三种不同数据加载方法的数据加载时间比较。
HDD,随机读取 果然最慢。然而,这里有一个惊喜!硬盘,顺序读取 ,比 SSD 快一圈,随机读取 。所以,我们不花钱买固态硬盘,就不能用硬盘吗?
不幸的是没有。
首先,读写混洗数据需要时间。对于 ImageNet 2012 数据(150 GB),读取、混洗和写入需要 4 个小时。因此,您不能对每个时期执行此操作。如果你没有固态硬盘,这是唯一的救命稻草。
第二,将数据加载时间从 0.370 秒减少到 0.018 秒是重要的,但是对于训练来说将其从 0.018 秒减少到 0.003 秒是不必要的,因为存在额外的优化时间(向前传递+向后传递)。一旦数据加载时间减少,优化时间就会成为主要瓶颈。此外,许多框架提供异步数据加载;因此,这种差异不会显著影响整体训练表现。
预处理呢?
- 裁剪、翻转、规格化等基本操作不会显著影响训练时间;因此,大多数时候,您可以动态地执行这些操作。但是,如果您有一长串预处理函数或自定义预处理函数会降低处理速度,您可以对原始数据集执行一次这些操作并将其写入磁盘,然后您可以读取预处理文件并直接将其提供给模型。
- 可以使用 GPU 张量进行预处理。 NVIDIA DALI [2]设计用于在 GPU 上进行预处理,它也具有快速的 CPU 实现。
- 可以使用低级语言(比如 C++)进行预处理,充分利用线程机制。
额外收获:了解你的图书馆。
PyTorch 和 Tensorflow 等框架将复杂的操作和 GPU、CPU 数据传输与用户隔离开来。这是这些图书馆的魅力之一。然而,它可能是有害的。例如,您想在每次迭代中获得一个张量的值,您可以通过下面的代码行(在 PyTorch 中)轻松获得它:
aValue = aTensor.item()
虽然看起来是很无辜的一行,但是每次执行这一行,都会把 GPU RAM 中的张量复制到主 RAM 中,这是一个很耗时的操作。它就像一个 print() 函数,我们不能随时使用它(尤其是在循环中)。因此,我们必须知道正在发生什么,以及函数如何在后台运行。了解这一点有助于我们编写更有效的代码。
下面是本文中提到的方法的简单流程图:
图片作者。
觉得这篇文章有用?看看我下面的其他文章:
[## 你可以用很少的数据使用深度学习架构
传统的 CNN(Alex net,VGG,GoogLeNet,ResNet,DenseNet …)在样本较多的情况下有很好的表现…
medium.com](https://medium.com/swlh/deep-learning-architectures-that-you-can-use-with-a-very-few-data-8e5b4fa1d5da) [## 使用 PyCharm 和 Docker 的有效深度学习开发环境
借助全面承诺的 IDE 和虚拟化提高您的工作效率。
towardsdatascience.com](/effective-deep-learning-development-environment-with-pycharm-and-docker-34018f122d92)
参考
[1]吴,庾信。“Tensorpack。”(2016).(【https://github.com/tensorpack/tensorpack】T4)
[2]https://github.com/NVIDIA/DALI
如何解决人工神经网络中的随机性?
原文:https://towardsdatascience.com/how-to-solve-randomness-in-an-artificial-neural-network-3befc4f27d45?source=collection_archive---------20-----------------------
了解一个人工神经网络随机性的原因以及如何修复。
在这篇短文中,我们将了解
- 人工神经网络的随机性是什么?
- 为什么我们在 ANN 中会有随机性?
- 如何修复随机性,让一个神经网络稳定?
- keras 中的简单代码实现,用于从人工神经网络获得一致的结果
人工神经网络(ANN)的随机性是什么?
人工神经网络(ANN)的随机性是指当相同的神经网络对相同的数据进行训练时,它会产生不同的结果。
有时,我们可能已经随机选择了训练数据和测试数据,如果我们从训练数据和测试数据中去除随机性,即使使用相同的神经网络,每次执行我们仍然可能得到不同的结果。
结果的这种随机性使得神经网络不稳定和不可靠,尤其是在与他人共享您的代码或展示您的工作时。
人工神经网络为什么会有随机性?
人工神经网络中的随机性可能由于多种原因而发生
- 权重和偏差的随机初始化
- 像辍学这样的正规化技术中的随机性
- 随机梯度下降(SGD)等优化技术中的随机性
我们如何修复一个 ANN 的随机性?
如果我们使随机性更可预测,我们就能获得一致的结果。
为了使随机性可预测,我们使用了 种子的概念。
Seed 有助于每次获得可预测、可重复的结果
如果我们不设置种子,那么我们在每次调用时都会得到不同的随机数
将种子设置为某个值,比如 0 或 123,将在同一台机器或不同机器上多次执行代码时生成相同的随机数。
为了解决我们使用的人工神经网络的随机性
- numpy 随机种子
- 张量流集合 _ 随机 _ 种子
让我们在不设置随机种子的情况下构建一个简单的 ANN,接下来,我们将设置随机种子。我们将在 ketas 中实现代码
我使用了 Kaggle 的房屋数据集
证明人工神经网络的随机性
#Importing required libraries
import numpy as np
import pandas as pd
from keras import Sequential
from keras.layers import Dense# Reading the data
dataset = pd.read_csv('housingdata.csv')
dataset.head(2)# Creating independent and dependent variable
X=dataset.iloc[:,0:13]
y=dataset.iloc[:,13].values# creating train and test data
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test =X[:400], X[400:], y[:400], y[400:]# Building a simple ANN for regression
**def build_regressor():**
regressor = Sequential()
regressor.add(Dense(units=13, input_dim=13))
regressor.add(Dense(units=1))
regressor.compile(optimizer='adam', loss='mean_squared_error', metrics=['mae','accuracy'])
return regressor# creating the kears Regressor with 100 epochs
from keras.wrappers.scikit_learn import KerasRegressor
regressor = KerasRegressor(build_fn=build_regressor, batch_size=32,epochs=100)# Fitting the training data
results=regressor.fit(X_train,y_train)# Making prediction the test data
y_pred= regressor.predict(X_test)# printing the first 5 predictions for comparison
y_pred= regressor.predict(X_test)
y_pred[:5]
程序第一次运行的输出
第二次运行的输出
您将在每次执行时得到不同的输出
修复我们人工神经网络的随机性
我们将导入另外两个库并设置种子
**from numpy.random import seed
from tensorflow import set_random_seed**
设置 numpy 种子和 tensorflow 种子
**seed(0)
set_random_seed(0)**
最终代码
#Importing required libraries
import numpy as np
import pandas as pd
**from numpy.random import seed
from tensorflow import set_random_seed**
from keras import Sequential
from keras.layers import Dense**# settingt he seed
seed(0)
set_random_seed(0)**# Reading the data
dataset = pd.read_csv('housingdata.csv')
dataset.head(2)# Creating independent and dependent variable
X=dataset.iloc[:,0:13]
y=dataset.iloc[:,13].values# creating train and test data
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test =X[:400], X[400:], y[:400], y[400:]# Building a simple ANN for regression
**def build_regressor():**
regressor = Sequential()
regressor.add(Dense(units=13, input_dim=13))
regressor.add(Dense(units=1))
regressor.compile(optimizer='adam', loss='mean_squared_error', metrics=['mae','accuracy'])
return regressor# creating the kears Regressor with 100 epochs
from keras.wrappers.scikit_learn import KerasRegressor
regressor = KerasRegressor(build_fn=build_regressor, batch_size=32,epochs=100)# Fitting the training data
results=regressor.fit(X_train,y_train)# Making prediction the test data
y_pred= regressor.predict(X_test)# printing the first 5 predictions for comparison
y_pred= regressor.predict(X_test)
y_pred[:5]
首次运行和任何运行时的输出
结论:
由于权重的随机初始化、偏差、使用漏失和不同的优化技术,人工神经网络本质上是不确定的。我们可以为 numpy 和 TensorFlow 设置种子,以便在同一台计算机或不同的计算机上使用相同的数据集获得一致的结果。
如何解决 SQL 中的“不明确的名称列”错误
原文:https://towardsdatascience.com/how-to-solve-the-ambiguous-name-column-error-in-sql-d4c256f3d14c?source=collection_archive---------1-----------------------
给这些表起一个别名
迈克尔·泽兹奇在 Unsplash 上的照片
有时,您可能希望在 SQL 中连接两个表,并且表中有同名的列。
在这种情况下,如果您连接两个表并运行查询,而不区分相同的列名,错误“Ambiguous name column”将会出现。
这个怎么解决?
简单。
有各种方法可以解决“不明确的名称列”错误。下面解释一个最简单的解决方法。
如何解决 SQL 中的“不明确的名称列”错误
例如,您想要联接两个名为 TABLE1 和 TABLE2 的表。表 1 包含这些列—雇员 ID、姓名、薪金。表 2 包含这些列——雇员 ID、姓名和年龄。
首先,让我们创建表。
注意,除了 EmployeeID 之外,这两个表有一个共同的“Name”列,它始终是一个数字。
现在让我们把桌子连起来。运行以下查询:
如果您运行上面的查询,您将得到这个错误——“不明确的名称列”。
这意味着两列具有相同的列名,即“名称”列。SQL 机器不知道您引用的是两个表中的哪一个“名称”。这是模棱两可的——不清楚。
为了澄清这一点,请将 TABLE1 或 TABLE2 的别名添加到同名的列中。你会注意到上面,表 1 的别名是 A,而表 2 的别名是 b。
所以,让我们来修复这个 bug。
运行查询。没有错误!
您可能想进一步区分表 2 中的“姓名”,编写如下查询:
结论
您可以为同名的列指定不同的名称。这可能会使列内容的识别变得困难。列名应该描述列中的内容。
解决“不明确的列名”错误的最简单方法之一——不改变列名——是给要连接的表取一个别名。这向 SQL 机器发送了一个清楚的信息,列是不同的。
快乐查询。
谢谢你的时间。
附言 作家面临的挑战可能会让他们终生无法写作……久坐导致的慢性背痛、长时间盯着屏幕导致的眼睛问题、写作时手指窒息等等。如果你想继续得到这种类型的文章,你可以成为 媒介订阅者来支持我。每月 5 美元。你的一部分订阅费归我 。
如何解决企业人工智能中的最大挑战
原文:https://towardsdatascience.com/how-to-solve-the-biggest-challenges-in-enterprise-ai-deb0b1635bcb?source=collection_archive---------43-----------------------
企业人工智能战略路线图
90%的现有数据是在过去两年中生成的。每天,产生 7.5 万亿千兆字节的数据 — 每人大约 147,000 千兆字节。这些数字是惊人的,但这是意料之中的:世界在增长,机器经济呈指数增长。
这并不是说所有这些数据都立即有用。没有大量的预处理,组织不能简单地利用这些资源——但是有人在做这项工作吗?Forrester 报告称,在企业内部,73%的数据仍未用于分析。业务战略和数据战略之间仍有很大差距——您组织的预测性解决方案只能像最初的问题陈述一样可靠。根据 Gartner 的说法,组织需要建立具体的用例,并部署具有可衡量结果的技术,以实现人工智能的价值。
数据是拼图中的一大块
这个比喻仍然存在——数据是新的石油(尽管,这个短语最迟在 2006 年被创造出来,可能并不那么“新”)。它在原始状态下绝对有价值。提炼出来就更值钱了。但是当它变成一种产品,一种专门为解决某个特定问题而制造的产品时,它的应用是数不胜数的,它的价值也在飙升。
这同样适用于数据:组织需要记住,这里的最终目标不是收集尽可能多的数据。他们需要从数据中提取价值,并将其应用于特定的业务问题。观察数据,从中学习,然后根据反馈自动完成工作的想法是机器学习的核心。
GIF via giphy
尽管好莱坞经常描绘,曼梯·里并没有证明“终结者假说”。
理解机器学习
在任何组织成为数据驱动型组织之前,了解基础知识非常重要。人们通常认为机器学习的最终目标是在实时仪表板上显示数据的图表和可视化。ML 是关于自动化任务的(不是关于取代工作),它不仅仅是展示统计数据。广义而言,机器学习教给计算机一些关于世界的知识,以便机器可以使用这些知识来执行其他任务。另一方面,统计学教给人们一些关于世界的东西,这样他们就能看到更大的图景,做出明智的决定。
根据埃森哲的数据,与追求概念证明的公司相比,战略性扩展人工智能的公司报告的人工智能投资回报几乎是其三倍。显然,ML 不是一个精心打扮的仪表板;事实上,它可以帮助您的组织构建智能系统,这些系统可以模仿、扩展和增强人类智能,以实现特定的“机器智能”,使您组织中的人员能够专注于解决更适合人类的问题。
然而,大多数组织都在努力实现可扩展的人工智能解决方案,并错过了好处(见:钱)。问题?你的组织不缺人才,缺的是战略。不服气?我们来看一些数字。
可扩展解决方案
自 2015 年以来,数据科学职位需求增长了 344%。我们可以清楚地看到,组织正在投资发展他们的数据科学团队,他们的印象是,如果他们继续雇佣数据科学家,创新和数字化转型将是一个自动的副产品。然而只有** 27%的企业数据 被使用,算上外部数据更是令人震惊——在世界上所有可用的数据中, 不到 1%被用于分析 。**
所有这些数据都有一个临界点。公司可以投入数百万美元建立庞大的数据团队来搜索互联网搜索结果,并准备来自各地的数据——但这永远不会是一个可扩展的解决方案,并且缺乏管理策略是造成瓶颈的原因。
公司部署 AI 和 ML 需要什么?
那么这个过程从哪里开始,组织实际上是如何构建和部署成功的机器学习项目的呢?
- 从目标开始。你必须清楚地了解你面临的问题以及你想要实现的解决方案。在保龄球运动中,你可以用每一个球击倒十个瓶,但只有当你投对了球道,这才是一场完美的比赛。对于 ML,你需要知道你的目标是什么。组织是以目标为导向的,他们总是寻求增加收入和提高 KPI——如果你的问题没有解决这些目标,它可能偏离目标。
- ****问正确的问题。大多数企业在试图用 ML 解决问题之前都没有提出正确的问题。分析并理解你能回答什么,不能回答什么,然后弄清楚你的预测系统如何真正让最终用户受益。要问的一个关键问题是:“我的项目会被它能为组织创造的价值深深地驱动吗?”
- ****定义商业战略。制定战略时,必须像对待其他项目一样,对数据和 ML 项目给予同样的关注和细节。您需要具体的、可测量的、可实现的目标、实施计划以及帮助跟踪项目成功的度量标准。仅仅从技术层面来看你的项目是不够的,你需要能够将解决方案与你的组织联系起来。例如,在实施您的模型后,您的公司会增加收入或在市场中获得稳固的竞争优势吗?
- ****建立合适的团队。组织往往无法为工作雇用合适的候选人,因为他们要么不知道自己想要实现什么,要么对数据科学家的角色有冲突的看法。数据团队由更多角色组成,而不仅仅是数据科学家,认为一个角色能够建立和维护仓库,设计数据工作流,编写完美优化的机器学习算法,并对一切进行分析是无知的。为了填补项目的正确角色,你需要清楚地定义你的目标,理解每个技术角色/团队结构的细微差别,并确保所有这些都在你的招聘公告中概述。下图显示了核心技能对于数据科学新兴角色的相对重要性:
数据科学中技能重要性图表
****5。创建数据战略路线图。数据是 ML 项目的关键资产,因为它训练模型。据人工智能领域的先驱 吴恩达称,最大、最成功的产品拥有最多的用户。拥有最多的用户通常意味着你获得最多的数据,而在现代 ML 中,拥有最多的数据通常意味着你可以创造出最好的 AI。下图描述了上述概念:
****6。利用第三方软件。不要试图重新发明轮子,建立一个内部数据管道。为了成功推出 AI,选择正确的工具非常重要,这些工具可以帮助您的组织完成可以自动化的任务,如寻找、收集、标准化、提炼和集成数据。 代表 Alegion 进行的维度研究报告 发现,最终,71%的团队将训练数据和其他机器学习项目活动外包出去。在“建造还是购买”的争论中,选择“建造”的公司花费更多的时间和金钱。记住,你不是在雇佣数据管理员,而是在雇佣数据科学家。采用 DataOps 工具并找到自动化数据生命周期的准备和处理阶段的方法将缩短洞察时间。
这从来都不容易——但没必要这么难
一些企业没有足够的数据,另一些企业则在苦苦寻找超过十年的无用数据。拥有数据并不意味着可以从中获得洞见。组织未能认识到从数据中提取洞察力所需的准备工作,因此在创新和增长方面出现了越来越多的瓶颈。不是没有数据,是没有可用的数据。
数据是创建预测和智能解决方案的一个重要因素,但数据不仅仅是拥有大量数据。找到一个问题,找到合适的人来解决它,给他们有效解决问题所需的工具,并衡量他们的功效——这些是成功的 ML 的要求。
最初发表于【https://blog.thinkdataworks.com】。**
如何解决真正的大数据问题——加载巨大的 Excel 文件
原文:https://towardsdatascience.com/how-to-solve-the-real-big-data-problems-load-huge-excel-files-7e3ea6957126?source=collection_archive---------29-----------------------
提示:多线程。使用 PDI 和 PostgreSQL,我们可以在几分钟内加载一个巨大的 excel 文件。
越来越多的公司开始意识到数据的重要性。因此,他们会要求将庞大的 CSV 或 Excel 文件从其传统系统或手动流程加载到数据库,以进行数据驱动的分析。我知道,我们现在有很多解决这个问题的方案,像 pandas 、 dask 、 vaex python 库或 Informatica 等工具。
然而,学习不同的方法来解决问题陈述总是很有趣的。我们将使用 PDI 来解决这个问题,并使用 PostgreSQL 作为我们的数据库。这里的想法是优化利用我们的系统能力。我知道不是所有人都有内存优化服务器的特权。
ev 在 Unsplash 上拍照
如果你是数据管道建设过程的新手,那么我会推荐你看下面的故事。
[## 仅用 10 分钟构建您的第一条数据管道
通过使用 PDI 的真实用例,逐步构建您的第一个数据管道。
medium.com](https://medium.com/swlh/build-your-first-data-pipeline-in-just-ten-minutes-2a490867b901)
先决条件
- PDI: Pentaho 数据集成安装在您的系统上。您可以使用链接获得逐步安装指南。
- PostgreSQL :我们可以根据自己的喜好使用任何关系或非关系数据库。如果您想跟随,请使用链接来安装。
用户故事
我喜欢首先为我们的问题陈述定义用户故事。这有助于我设计数据管道的高级架构。我们需要将问题分解成简单的小块。
- 我想读取包含数百万条记录的经济数据的巨大 CSV 文件。
- 我想用一个维度/主表对数据中的每个内容进行查找。
- 我想清理数据并删除空字段。
- 我想添加一个行级条件。如果状态栏包含“修订”一词,我想添加“_R”。
- 我想在 PostgreSQL 数据库中加载相同的。
我们试图通过增加一点复杂的数据操作来复制真实世界的场景。
输入数据
理解输入数据文件是一个很好的做法。现在,在我们的例子中,可能很难打开巨大的 CSV 文件并检查列和行。然而,我们可以通过一些方法来确定或检查样本数据。PDI 通过创建一个小的转换来读取样本数据和检查其他元数据。
在这里,我谷歌了“csv 格式的巨大数据文件”这个词,并从第一个网站下载了这个文件。下面是环节。
现在,我想让系统崩溃并创建巨大的文件;就像我们在处理大数据一样,对吗?下载的文件有66526 条记录,所以我多次追加相同的记录来创建一个巨大的文件,大约有11974697 条记录;是的,没那么大。
测试案例
定义测试用例在这里很重要,因为我们不能手工检查整个数据。我们需要确保,我们检查了足够好的样本数据来交叉验证准确性。
- 检查行数并与输入数据匹配。请注意,因为我们将删除空数据。存储这些空记录也很重要。
- 交叉验证至少 500 -1000 条记录的维度输出结果。
- 随机交叉验证计算结果,以检查准确性;至少一千张唱片。
步骤 1:项目的设置
我们为这个项目设置了一个非常简单的项目。只有一个目录和一个转换文件。
我喜欢在一个名为“work”的项目目录中创建所有与工作相关的项目;我知道,多有创意啊!我们需要执行以下操作:你可以跳过这一步。
- 创建我们的项目目录- LoadData。
- 在项目目录中创建一个目录“Input”。
- 在项目目录中创建一个名为“Main.ktr”的空转换。
项目目录结构
如果你不知道像转换或工作这样的词,那么我将推荐下面提到的故事。
[## Pentaho 数据集成(Kettle)及其组件入门。
了解勺子、平底锅、厨房等关键部件将使我们对 PDI 工具有更好的了解
medium.com](https://medium.com/ai-in-plain-english/getting-started-with-pentaho-data-integration-kettle-and-its-components-ef1e71101323)
步骤 2:创建数据库表
我假设您已经在这里安装了数据库。我们使用 PostgreSQL。
现在,我更喜欢使用 Django 模型创建表格。您不一定必须使用这种方法。
话虽如此,但通过编写 Django 模型而不是手动创建表和列,我们的生活变得简单了。Django models 使用简单的 migrations 命令为我们做到了这一点,并且还获得了开箱即用的 CRUD (创建、读取、更新和删除)功能。
你可以选择下面提到的两个选项来创建数据库和表。我已经创建了一个表 medium_db
- PostgreSQL 创建脚本。
— Table: public.economic_data — DROP TABLE public.economic_data;CREATE TABLE public.economic_data
(id integer NOT NULL DEFAULT nextval(‘economic_data_id_seq’::regclass),series_reference character varying(255) COLLATE pg_catalog.”default” NOT NULL,indicator_name character varying(255) COLLATE pg_catalog.”default” NOT NULL,period character varying(45) COLLATE pg_catalog.”default” NOT NULL,indicator_value numeric(30,10) NOT NULL,status character varying(255) COLLATE pg_catalog.”default” NOT NULL,
indicator_unit character varying(255) COLLATE pg_catalog.”default” NOT NULL,group_name character varying(255) COLLATE pg_catalog.”default” NOT NULL,series_name character varying(255) COLLATE pg_catalog.”default”,
CONSTRAINT economic_data_pkey PRIMARY KEY (id)
)TABLESPACE pg_default;ALTER TABLE public.economic_data
OWNER to YOURUSER;
- 运行迁移的 Django 模型脚本。
from django.db import models# Create your models here.class EconomicData(models.Model):**series_reference** = models.CharField(db_column="series_reference",max_length=255,help_text="Unique code to identify a particular record",verbose_name="Series Reference",)**indicator_name** = models.CharField(db_column="indicator_name",max_length=255,verbose_name="Name of the indicators")**period** = models.CharField(db_column="period",max_length=45,verbose_name="Period")**indicator_value** = models.DecimalField(db_column="indicator_value",max_digits=30,decimal_places=10,verbose_name="Value of the Field")**status** = models.CharField(db_column="status",max_length=255,verbose_name="Status of the value For eg, Final or Revised")**indicator_unit** = models.CharField(db_column="indicator_unit",max_length=255,verbose_name="Unit of the indicators")**group_name** = models.CharField(db_column="group_name",max_length=255,verbose_name="Group of the indicators")**series_name** = models.CharField(db_column="series_name",max_length=255,verbose_name="Series of the indicators"null=True)def __str__(self):return f"{self.indicator_name} - {self.value}"class Meta:db_table = "economic_data"verbose_name = "Economic Data"verbose_name_plural = "Economic Data"
如果你有兴趣了解我们如何从 Django 的数据管道中获益,请在下面的回复部分告诉我。
我们已经准备好桌子了。现在,让我们创造我们的转变。
步骤 3:加载程序转换
我们需要创建一个 loader 转换,它读取我们的输入 CSV,执行操作并将数据加载到数据库中。
我们需要打开 Main.ktr 文件并拖动一些插件,如下所述。
步骤 1:拖动步骤
- 首先,让我们添加一个关于转换的小描述。文档是任何数据管道的关键。
- 将“CSV 文件输入”、“数据网格”、“连接行(笛卡尔乘积)”、“用户定义的 Java 表达式”、“过滤器行”、“文本文件输出”、“表格输出”插件从“设计”选项卡拖到画布上。
- 按照我们的命名约定重命名字段。
重命名后的主要转换
步骤 2:配置属性
- 我们需要为上述每个步骤配置属性。让我们配置 CSV 输入步骤,我们需要在文件名字段中浏览我们的输入文件,并点击获取字段。我们可以根据内存可用性调整 NIO 缓冲区大小;它将分批处理文件,每批 50K 条记录。
- 我们需要在数据网格中添加数据(在这里复制一个表)。在这里,我们使用数据网格来表示数据。在真实的场景中,您将从一些维度表中获得这些数据。我们正在使组名标准化。你可以参考下面的数据截图。我们需要在元选项卡中添加列名,并在数据选项卡中添加实际数据。
- 在 Join rows 步骤中,我们需要将输入中的字段映射到我们的维度表/网格中。因为我们在这里映射组,所以我们需要添加条件来映射相同的组。
- 在用户定义的 java 表达式中,我们将配置自定义的行级条件。我们需要将我们的新字段定义为‘Series _ reference _ flag ’,如果状态列为‘Revised ’,这里我们要更改‘Series _ reference’字段并附加‘R’。在我们的 Java 表达式中,我们将添加以下条件——‘status = =‘Revised’?Series _ reference+" _ R ":Series _ reference ';这是 java 代码。我们可以执行类似的条件或计算,功能强大!最后,我们需要将值类型添加到‘String’中。
- 在筛选行步骤中,我们需要定义传递没有空值的记录的条件。
- 在文本文件输出(错误报告)中,我们需要添加文件名为 ' ${Internal。entry . current . directory }/error _ report'并将扩展名改为‘CSV’。
- 在表格输出步骤中,我们需要创建一个新的连接来连接到我们的数据库。我们可以根据需要连接到任何数据库。我们在这里将连接到 PostgreSQL 有关连接的详细信息,请参考屏幕截图。我们需要浏览目标表到‘经济 _ 数据’。我们需要检查指定数据库字段的字段字段。然后,我们需要将输入/转换字段映射到表字段。
输入步骤配置
数据网格配置-维度
联接行配置
条件配置
过滤空配置
数据库输出配置
数据库映射
第四步:让我们加快进程
现在我们已经配置了属性,我们可以通过创建插入数据的多线程来加速这个过程。这将提高性能。PDI 为我们提供了按步骤配置多线程的工具。如果我们在输入步骤中使用它,它将成倍增加记录。然而,如果我们将它用于像数据库这样的输出步骤,它将分发记录。
PDI 为我们提供了许多优化性能的选项。我们可以执行以下步骤来提高性能。
- 在我们的输入步骤中更改 NIO 缓冲区大小,定义我们的批处理大小。
- 改变最大值。高速缓存大小(行数)在查找步骤中,定义它将存储在高速缓存中的行数,而不是查询数据库。
- 改变提交大小,类似于缓冲区大小改变批量大小来插入记录。
- 使用多线程来执行活动,我们可以添加一个虚拟步骤,并在输出步骤之前,右键单击选择根据我们的要求,将启动的副本数从 1 更改为 1 以上的任何值。
- 请注意,如果我们想要在表输出步骤上执行多线程,那么我们不能使用第四点。然后,我们必须在输出之前添加一个虚拟步骤,并且在多个输出表步骤中分配记录。
哇!我们有这么多的选择,我们应该改变所有的性能优化器吗?简而言之,答案是否定的。我们需要用样本数据进行尝试,并对最适合我们的方法进行多次测试。
第二步:评估
让我们在没有性能优化器的情况下运行这个流,然后通过应用优化器进行比较。
成功
步进矩阵——用了 8m 42s
添加了简单的优化器—20 倍的 on 条件和两个输出线程
步骤矩阵——花了 4m 35s
通过添加一些简单的性能优化器,我们将执行相同活动的时间减少了近 50%。
如果我们想读取多个文件,并创建一个循环来处理相同的文件,那么我会推荐你阅读下面的故事。
[## 如何自动化多个 Excel 工作簿并执行分析
应用这个循序渐进的指南来解决问题,使用神奇的元数据注入 PDI。
towardsdatascience.com](/how-to-automate-multiple-excel-workbooks-and-perform-analysis-13e8aa5a2042)
结论
我们提出了一个问题陈述,并尝试使用多种方法解决它,还尝试优化它。理论上,您可以应用这个过程来满足您的需求,并尝试进一步优化它。PDI 也为我们提供了 PostgreSQL 批量加载器步骤;我也试过那一步。然而,这并没有提供任何显著的性能提升。
我们不能在一开始就优化代码/管道,必须执行多次测试才能获得理想的结果。然而,为了缩短学习曲线,你可以随时阅读我的经验,并通过使用下面的链接订阅我的电子邮件列表来找到问题陈述的解决方案。
[## WryteEx -使用真实世界用例寻找解决方案的平台
我写的博客涉及数据工程、金融、Python、Python Django、项目管理、Web 开发等等
wryteex.com](https://wryteex.com/)
下一篇文章再见。快乐的 ETL
如何解决旅行商问题——比较分析
原文:https://towardsdatascience.com/how-to-solve-the-traveling-salesman-problem-a-comparative-analysis-39056a916c9f?source=collection_archive---------3-----------------------
行业笔记
通过 3 种优化方法:动态规划、模拟退火和 2-opt。
凯勒·琼斯在 Unsplash 上拍摄的照片
我相信你已经听说过旅行推销员问题或 TSP。这个问题有许多应用,也有许多具有不同性能的解决方案。在这里,我想分享一下我最近解决旅行商问题的经验,特别是用 2-opt 法 这是解决这个问题最简单也是最有效的方法之一。
如果你只是想了解 2-opt,你可以直接跳到这篇文章的末尾。您也可以使用我在下面开发的 Python 包来解决 TSP 问题。
[## py2opt
在优化中,2-opt 是一种简单的局部搜索算法,具有特殊的交换机制,非常适合于求解复杂的优化问题
pypi.org](https://pypi.org/project/py2opt/)
在这篇文章里,我想分享我用 120 个城市去访问解决一个 TSP 的经验。这个问题必须在不到 5 分钟的时间内解决,才能用于实践。我的目标是用以下方法解决这个问题:
- 动态编程,
- 模拟退火,以及
- 二选一。
首先,让我简单解释一下 TSP。
[## 人工智能:非正统的教训:如何获得洞察力和建立创新的解决方案
亚马逊网站:人工智能:非正统课程:如何获得洞察力和建立创新的解决方案电子书…
www.amazon.com](https://www.amazon.com/gp/product/B08D2M2KV1/ref=dbs_a_def_rwt_hsch_vapi_tkin_p1_i0)
旅行推销员问题
旅行商问题是组合优化中的经典问题。这个问题是要找到一个推销员应该走的最短路径来遍历一个城市列表并返回到起始城市。提供了城市列表和每对城市之间的距离。
TSP 在现实生活中的各种应用中都很有用,比如规划或物流。例如,想要为乐队安排一系列演出的巡回音乐会经理必须确定巡回演出的最短路径,以确保降低旅行成本,并且不会使乐队不必要地筋疲力尽。
这是一个 NP 难问题。简单来说,就是你不能保证在合理的时间限制内找到最短的路径。这并不是 TSP 所独有的。在现实世界的优化问题中,您经常会遇到这样的问题,您必须找到次优解,而不是最优解。
旅行推销员问题
一、动态编程
动态规划或动态规划方法保证找到 TSP 的最佳答案。然而,随着城市数量的增加,其时间复杂度将呈指数增长。DP 方法的时间复杂度渐近地等于 N × 2^N,其中 n 是城市的数量。
为了给你时间复杂度增加的提示,让我分享我的实验。10 个城市的 TSP,用英特尔酷睿 i7 用 DP 法差不多 0.2 秒就能解决。在 15 个城市中,这个数字增加到几乎 13 秒(大约 60 倍)。也就是说,即使城市数量增加很少,时间复杂度也会显著增加。
为了优化 DP 方法,我可以使用记忆技术。然而,具有大量城市的记忆化技术需要一个 2^N × 2^N 矩阵,该矩阵不容易在存储器中处理。
建议- 如果要解决有大量城市的旅行商问题,动态规划方法不是最佳选择。DP 方法可以保证全局最优,但它需要大量的时间和计算能力,这是我们在现实世界问题中所不能承受的。
二。模拟退火
模拟退火或 SA 是一种启发式搜索算法,其灵感来自冶金工业中的退火机制。退火指的是一种控制的冷却机制,它导致材料达到期望的状态。但是,这如何映射到优化问题呢?
优化专家从退火机制中学到的经验是,与具有固定规则的梯度下降算法相反,对搜索过程实施更多的控制。SA 方法有两个主要规则,解释如下。
- 的移动方向必须在每一步中以概率的方式确定,希望不会陷入局部最优,并向全局最优移动。
- 搜索步骤在搜索过程向前推进并接近最终结果时,必须缩小规模。这有助于在早期积极行动,在后期谨慎行动。
在 SA 方法中,搜索过程必须继续,直到找到足够好的解决方案或达到停止标准。此外,该方法对其参数(包括搜索步长和移动方向)的制定和调整非常敏感。SA 方法是一种启发式搜索算法,因此,它对搜索空间中的初始点敏感。
我实现了 SA 方法并测试了几次。最后,由于执行时间有限,我无法获得比 2-opt 方法更好的结果。2-opt 方法执行得非常快。
建议- 模拟退火法的结果对其参数和停止准则很敏感。模拟退火法是一种强有力的工具。但是如果你想和它一起工作,确保你知道它的缺点。
三世。双选项
2-opt 算法是一个简单的局部搜索方法,带有一个作为启发式算法的特殊交换机制。2-opt 方法背后的主要思想是在城市的每一个邻近区域移除路径交叉。2-opt 可以很容易地实现并快速执行。比如 120 个城市的 TSP,在英特尔酷睿 i7 上用这种方法不到 5 秒就能解决。在这里,“已解决”意味着算法收敛到一个足够好的解,这是一个次优解。2-opt 方法收敛快,因为它与 SA 方法相反是确定性的。
使用随机初始点运行 3 次 2-opt 方法。停止标准是基于与最佳结果相比的改进比率来定义的。
这种方法类似于其他启发式搜索算法,不能保证找到全局最优解。2-opt 方法很容易陷入局部最优,因为它没有跳出局部最优的机制。知道了所有这些缺陷,这种方法在 TSP 中仍然工作得很好,因为它的启发式算法在这个问题中非常相关,非常有效。
[## pdrm83/py2opt
在优化中,2-opt 是一种简单的局部搜索算法,具有特殊的交换机制,非常适合于求解复杂的优化问题
github.com](https://github.com/pdrm83/py2opt)
类似于其他启发式搜索算法的 2-opt 方法对其在搜索空间中的初始点敏感。这意味着不同的初始点会改变最终的结果。我使用了一个简单的技巧来解决这个问题,并改善 2-opt 方法的结果。我用不同的随机初始点运行该方法 10 次,并从中选择最佳结果。通过这种方法,我在一定程度上降低了对起点的敏感性。
建议-2-opt 方法容易实施,执行速度快。另外,它比预期的效果好得多,尤其是当你降低它对搜索空间中初始点的敏感度时。我强烈建议使用这种方法来解决 TSP,除非一个足够好的结果不适合你。
四。摘要
下面的视频很好的总结了这篇文章。你会喜欢看它的。
外卖食品
解决 TSP 的方法有很多。然而,上述方法是最常见的。我强烈推荐 2-opt 方法,因为它实现简单,执行速度快。然而,模拟退火方法是非常强大的,如果你可以适当地调整它,并且你没有时间限制找到最终结果。
最后一句话——当你想为包括 TSP 在内的任何问题找到一个解决方案时,总是要想一想像 2-opt 方法这样的简单技术是如何工作得很好的。为什么?因为它的启发式非常适合这个问题。
感谢阅读!
如果你喜欢这个帖子,想支持我…
- 跟我上 中 !
- 在 亚马逊 上查看我的书!
- 成为 中的一员 !
- 连接上Linkedin!
- 关注我 推特 !
[## 通过我的推荐链接加入 Medium—Pedram Ataee 博士
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
pedram-ataee.medium.com](https://pedram-ataee.medium.com/membership)
“你在用那张桌子怎么解决?!"问题
原文:https://towardsdatascience.com/how-to-solve-the-youre-using-that-table-problem-22bdabec57a1?source=collection_archive---------40-----------------------
如何快速识别数据仓库中最关键的表格和报告
照片由米利安·耶稣会士在 Unsplash 上提供。
随着公司越来越依赖数据来推动决策和创新,这些数据的及时性、准确性和可靠性变得非常重要。当您考虑到全球每天产生的超过 7.5 万亿(77 亿)GB 的 数据中只有一小部分是可用的 时,跟踪哪些数据资产是重要的只会变得更加困难。
在本文中,我们将介绍 “关键资产】、 一些最优秀的数据团队采用的一种新方法,来展示您最重要的数据表和报告,以获得快速可靠的见解。
你有没有想出最奇怪的方法来命名“相关”的表,如“IMPT”或“使用这个 _V2”?数据仓库迁移已经进行了四分之三,您是否发现自己不知道哪些数据资产是正确的,哪些是错误的?您的分析团队是否迷失在电子表格的海洋中,看不到救生衣?
如果你对这些问题中的任何一个回答是肯定的,你并不孤单。在过去的几年里,我与数百个数据团队交谈过,他们对自己公司数据资产的潜力感到兴奋和不知所措,他们负责维护一个不断发展的数据资产生态系统。
我们称之为“你在用那张桌子?!"问题,而且比你想象的更普遍。
以下是你可能正在经历的三个迹象:
您正在迁移到新的数据仓库
就像水牛迁移穿过塞伦盖蒂平原一样,迁移到新的数据仓库可能是一个混乱而乏味的过程,让您的团队意识到数据(或水牛)不再适合或可用。图片来自Jan Rix on Shutterstock。
随着数据团队越来越多地从本地数据仓库转移到雪花、红移和其他云仓库,或者在云仓库之间转移,了解哪些数据有价值以及哪些数据可以像渡渡鸟一样变得越来越重要。
不幸的是,数据验证和交叉引用通常是手动处理的,成本高、耗时且难以扩展。一位客户是一家全球金融服务公司的数据团队负责人,目前正在迁移到雪花,他透露说,他们“正在手动将 Redshift 中的表映射到 Tableau 中的报表,这样我们就知道将什么迁移到雪花和 Looker 中。”
通常,当数据团队从 Redshift 迁移到 Snowflake 时,他们最终会求助于两个数据仓库中相同表的副本之间的手动差距分析,因为“了解表下游的哪些报告将有助于我们确定迁移的优先级,或者废弃我们不再需要的表。”
您公司的数据分析师和数据科学家不知道使用什么数据
数据团队的第二个也是最常见的痛点是不知道什么数据最有用,更不用说有用了。
如果你和你的团队问了以下任何一个问题,他们可能正处于一个连史酷比都无法解决的谜团之中。以下是常见数据发现问题的列表。也许他们会产生共鸣:
- 我应该使用什么数据?
- 我找不到我需要的数据,我该怎么办?
- 很难理解什么是我们的“重要数据”……帮帮忙?
- 谁在用这张桌子?这些数据重要吗?
当这些问题被频繁问及时,您的公司明显缺乏数据信任和数据发现,这对您公司利用数据作为竞争优势的能力造成了损害。
您有大量的“数据债务”
数据债务不仅仅是代价高昂;它会侵蚀用户的信任,导致糟糕的决策。图片由 Shutterstock 上的 baranq 提供。
像技术债务一样,数据债务指的是过时的、不准确的或者占用数据仓库中宝贵存储空间的数据资产。这种情况太常见了,即使是最先进的数据团队也会陷入困境,很难及时获得相关的见解。
数据债在实践中是什么样子的?这里有三个强有力的指标:
- 您的衣柜里有旧的数据框架(包括过时的、不准确的表和遗留数据类型),团队可能会错误地使用它们。
- 您会收到不同作业和系统检查失败的警报,但它们都被忽略了,因为“事情总是这样。”
- 您已经更新了您的技术堆栈,迁移到了雪花,并且使用了最新的新工具,但不再利用相同的数据格式、数据表甚至数据源。
简介:关键资产
数据团队的任务是通过数据驱动的洞察来创建业务的可见性,但当涉及到他们自己的运营时,他们往往会盲目行事。相反,团队需要一个单一的视图来了解他们的数据的健康状况,这些数据是识别您的数据仓库中最关键的数据表和数据集的关键资产。
幸运的是,最好的数据可靠性和可发现性(目录)解决方案已经将它们集成到他们的产品中。通过利用机器学习,这些解决方案可以智能地映射您公司的静态数据资产,而无需从您的数据存储中提取数据,从而生成一个“关键资产仪表板”。
关键资产可能是:
- 许多人经常查询的表
- ETL 过程大量使用的数据集,用于派生其他数据集
- 为许多或常用仪表板提供信息的表格
- 具有重要下游依赖性的外部来源
但是团队如何识别他们的关键资产呢?在其他变量中,我建议团队寻找具有以下特征的表和数据集:
- 经常被访问(例如,每天 AVG 读取次数)
- 频繁更新(例如,AVG 每天的写入次数)
- 被大量用户使用
- 定期更新/使用(即,每个单独数据资产的< 1–5 days since latest update)
- Leveraged by a large number of ETL processes
- Supports connectivity, in other words is read-from/written-to many other data assets
- Experiencing a high data incident rate (over days/weeks/months)
- Queried recently/frequently by BI tools
Additionally, Key Assets should include an 【重要性分数】)。此分数是关于数据使用的关键指标的组合,表明哪些资产对您的组织最重要。分数越高,该资产越有可能成为您团队的重要资源。
虽然过于简单,但这个关键资产仪表板的呈现具有搜索功能,允许用户查找特定的资产,同时还可以根据统计数据(如每天的平均表读取次数和表用户总数)明确哪些资产是重要的,哪些资产可以折旧或清理。图片由作者(巴尔·摩西)提供。
利用关键资产实现数据信任和发现
随着 数据架构 变得越来越孤立和分散,我看到了关键资产和类似解决方案在优化数据发现和恢复数据信任方面的巨大潜力,包括:
促进更顺畅的仓库迁移
引领 数据仓库迁移 可能是一项既令人兴奋又令人畏惧的任务。通常,数据团队被迫手动处理数据验证。有了关键资产,团队可以自动识别哪些表正在使用和依赖,哪些表可以废弃,从而使这个过程更快。
更容易找到用于智能决策的重要数据
关键资产功能可以轻松找到重要数据,从而做出明智的决策。图片由作者(巴尔·摩西)提供。
很可能整个公司的分析师都在为阳光下(或者更确切地说,在你的仓库里)的每个数据集制作 v1、v2、v3 和 v4;当你在进行批判性分析时,发现并知道哪些是真正相关和重要的将会有很大的不同。如果用户还可以搜索特定的数据资产,则加分。关键资产支持这两种功能。
减少数据债务
关键资产使清理“垃圾”表和管道变得更加容易,通过突出显示哪些数据表被广泛使用,哪些已经过时甚至不准确,您可以减少数据仓库或湖中的数据债务。减少数据债务的传统方法严重依赖于代码密集型集成(即开源)或围绕工作流编排工具的临时 SQL 查询。关键资产提供了一种更简单、更快捷的方法来获取这些指标及更多信息。
实现端到端的数据可观察性
从摄取到分析,端到端的数据可观测性 是任何一个严肃的数据工程团队必备的。通过了解您的重要数据位于何处,以及它在管道的所有阶段是如何被使用的,已经被否决的表和数据集可以被忽略,关键表可以浮出水面。
通过机器学习自动生成关键资产
在我看来,一个智能但安全的关键资产仪表板应该自动生成,利用机器学习算法,通过拍摄数据生态系统的历史快照来学习和推断你的数据资产,而不是实际访问数据本身。
通过消除数据停机时间提高数据可靠性
自动生成的单一真实来源(如关键资产)是理解如何利用表的逻辑结论,可防止数据停机的影响在您的数据管道中显现。
使用关键资产,用户可以搜索并确定哪些数据资产需要密切监控以发现可能的异常或问题,哪些数据资产可以暂时搁置。这种解决方案可以帮助团队自动消除过时数据的嘈杂警报,并只监视业务部门经常使用的数据资产。
我不知道你怎么想,但我等不及“你要用那张桌子?!"问题已经成为过去。
想要识别您自己的数据组织的关键资产? [蒙特卡洛](http://montecarlodata.com?utm_source=blog&utm_medium=medium&utm_campaign=key assets&utm_term=october) 可以帮忙。
如何在 Power BI 中按时间顺序排列月份
原文:https://towardsdatascience.com/how-to-sort-months-chronologically-in-power-bi-73dac77850e1?source=collection_archive---------8-----------------------
了解如何在 Power BI 中按时间顺序对月份字段进行排序
图片来自 Unsplash
在本文中,我将演示如何在 Power BI 中按时间顺序对月份进行排序。可视化一段时间内的销售数据是最有影响力的报告方式之一。通常,设计图表来显示指标随时间的趋势或增长是非常重要的。时间段可以是任何时间,例如几天、几周、几个月或几年。它基本上让您了解指标在特定时间段内是如何增加或减少的。
在 Power BI 中,您还可以按特定的选定时间段可视化您的指标。这通常通过绘制显示一段时间内趋势的折线图来实现,或者通过使用垂直条形图来显示该时间段内的特定指标,甚至简单地使用表格矩阵来以文本方式显示结果。出于本文的考虑,为了简单起见,我们将只考虑第三种情况,即表格矩阵。然而,同样的解决方案可以适用于任何类型的包含时间段的图表。
有时,当您将数据导入 Power BI 时,特别是如果您在原始数据源中有月或季度作为文本数据(来自平面文件的,那么 Power BI 无法理解导入的字段是否是实际的日期字段(日/月/年等)。)或者只是简单的文本数据。在这种情况下,在导入后,月份或季度按字母顺序排序,而不是按时间顺序排序,这是一个错误,取决于需求和与开发趋势报告不太相关的东西。在这个解决方案中,我们将首先学习如何重现错误,然后了解如何对数据模型进行必要的更改以解决这个错误,并在 Power BI 中按时间顺序对月份进行排序。
重现错误
让我们首先试着重现这个错误,然后我将解释如何在幂 BI 中按时间顺序排列月份。为了重现错误,我们需要创建一个简单的 CSV 文件,如下图所示。
图 1 — CSV 数据集
如上图所示,我们只有两个简单的列— 月和销售。月列出了从“1 月”到“12 月”的所有值以及相应的销售额值。一旦创建了 CSV 文件,下一步就是打开 Power BI 并将其连接到这个数据集。
打开 Power BI Desktop,按照以下步骤将该数据提取到 Power BI 数据模型中:
选择获取数据,并从出现的菜单中选择文本/CSV 。
图 2 —获取功率 BI 中的数据
浏览上一步刚创建的文件,点击打开。
图 3 —浏览数据集
在出现的下一个对话框中,验证数据并点击加载。
图 4 —将数据加载到 Power BI 模型中
您将看到数据已经加载到 Power BI 中。
点击可视化 窗格中的表格,将字段拖放到如图所示的表格中。
在创建的新表中,您可以看到月份现在按字母顺序排序。
图 5 —创建表格
在 Power BI 桌面中,选择转换数据,然后点击转换数据。
图 6 —转换数据
在打开的 Power Query Editor 中,导航到打开的 Add Column 选项卡。
选择自定义栏,输入公式,如下图所示。
对于自定义列的名称,我使用“ Date ”,因为该列将存储虚拟日期值。
在自定义列的公式中,使用以下内容:= " 1 " &[月] & " 2020"。
图 7 —添加虚拟日期列
因此,基本上,我们试图实现的只是创建一个虚拟日期值,方法是将“1”作为日期,将“2020”作为年份值添加到已经存在的月份中。
图 8 —增加了新的日期栏
下一步是将这个新字段 Date 转换为 date 数据类型。右键点击该列,选择更改类型,然后选择日期。
图 9 —改变数据类型
您可以看到该列的数据类型和值已经更改。
图 10 —更改了数据类型
我们现在将再添加一个自定义列,从该字段中提取月份数。点击添加列,然后点击自定义列。
提供字段名称为“月份号”,公式为“=日期”。月份([日期])”并点击确定。
图 11 —添加新的月份号列
现在,您将看到数据集中又添加了一列。
图 12 —增加了新的月份号列
我们将把这个字段的数据类型改为整数。右键点击月份号,选择更改类型,然后选择整数。
图 13 —将数据类型更改为整数
由于我们的数据模型中有了所需的字段 MonthNumber ,我们可以删除在前面的步骤中创建的虚拟日期字段。右键单击日期栏并选择移除。
最后,您可以通过导航到主页并选择关闭和应用来关闭 Power Query 编辑器窗口。
图 15 —关闭电源查询编辑器
在 Power BI 中选择按时间顺序排列月份的列
既然我们已经在数据模型中进行了必要的更改,以在 Power BI 中按时间顺序对月份进行排序,那么最后一步就是按照 MonthNumber 的升序对月份进行排序。请按照下面的步骤对月份进行排序。
点击左侧窗格上的数据选项卡。
选择月列,然后在上方工具栏的排序窗格中选择按列排序。
在出现的下拉菜单中,选择月份号并导航至报告选项卡。
图 16 —按月号排序
您现在可以看到,月份是按时间顺序而不是字母顺序排序的。
图 17——按时间顺序排列的月份幂 BI
此外,如果您想隐藏月份号字段,您只需右击它并选择隐藏。
图 18 —隐藏月份号字段
您将拥有原始 CSV 文件中的数据集,但月份是按时间顺序排序的。
图 19——以幂 BI 形式按时间排序的月份
结论
在本文中,我解释了如何在 Power BI 中按时间顺序对月份进行排序。我还提到了复制错误的步骤,然后提供了如何解决问题并最终获得预期结果的分步指导。
原载于 2020 年 3 月 16 日 https://www.sqlshack.com。
如何加快本地机器学习模型的开发
原文:https://towardsdatascience.com/how-to-speed-up-local-machine-learning-model-development-33df177893ec?source=collection_archive---------49-----------------------
介绍一个强大的机器学习模板
在 Unsplash 上拍摄的 ThisisEngineering RAEng
TL/DR:我在 Github 上开发了一个包,ml-template,通过加速了本地机器学习模型的开发
- 提供一个结构良好的通用代码库,可以根据您的用例轻松调整
- 使用最新的软件包(DVC 和 MLFlow)确保模型结果的再现性和有效的模型性能跟踪
开发包装的动机
虽然这似乎就发生在昨天,但我现在已经在 4 年多前开始了我的机器学习之旅。在那段时间里,我很幸运地解决了一些很酷的问题。从编写算法根据某人鞋子的照片检测其性别,到使用自然语言处理根据你的简历预测你的下一份工作,再到预测临床试验的结果,我处理过各种各样的问题。
这些问题显然大相径庭,有其独特的挑战。然而,这篇文章让我感兴趣的不是这些问题有什么不同,而是它们有什么共同点。每当我开始编写机器学习问题的代码时,我都必须编写相同的对象和函数来分割训练集和测试集,训练算法,执行交叉验证,保存训练好的模型等等。无论是自然语言问题、机器学习视觉还是任何其他类型的问题,这一点都适用。
如果你正在匆忙地开发你的代码,你也会写出结构不良的代码。我不需要告诉你,糟糕的结构代码会让任何人在以后的日子里更难发现,也意味着更不容易发现错误。
约书亚·索蒂诺在 Unsplash 上拍摄的照片
我遇到的另一个挫折是,当主体结构建成时,我要监控模型。根据我的经验,建立机器学习模型是一个迭代过程,需要对不同版本的数据和不同的转换、算法和超参数进行大量实验。
我试图通过在 Excel 电子表格中记录模型“主要”运行的参数和输出来解决这个问题,但我发现这很快变得难以操作。如果您需要将模型切换回上周运行的数据/代码组合,会发生什么呢?这可能很棘手。
为了尝试解决这些痛点,我开发了一个面向对象的机器学习模板,可以根据您的特定问题进行相应的调整。我认为这个项目相当于建造一栋房子的地基和结构——在完工之前还有相当多的工作要做,但它极大地加快了这个过程。
但是首先,让我带您看一下我用于数据和模型版本控制的两个包。
DVC 和 MLFlow 是什么?
在 Git 出现之前,对代码的修改是作为补丁和归档文件传递的。这使得两个或更多的人很难处理同一个代码,并且很难快速切换到以前的版本。Git 的采用极大地提高了软件开发的效率。
机器学习目前感觉像是处于“前 Git”时代。当然,您可以对您的代码进行版本控制,但是今天大多数数据科学家不会对他们的数据或模型进行版本控制。这意味着,你猜对了,在一个模型上合作和切换到以前的版本变得更加困难。DVC 和 MLFlow 是两个旨在提供帮助的软件包。
由克里斯多夫·伯恩斯在 Unsplash 上拍摄的照片
DVC 是数据的版本控制包。还有其他的数据版本控制包,比如“Git-LFS ”,但是这个有很多问题(更多细节见这篇博客)。DVC 的巧妙之处在于它如何将 Git 中的相同概念运用到数据管理领域。它很容易在许多不同的文件系统(本地、S3、GCP 等)上存储数据,它可以处理大量的文件大小,并与 Git 无缝集成。DVC 正在积极开发和不断扩展其功能,以处理改进模型管理和模型部署。一个面向未来的包裹。
MLFlow 是一个开源包,最初由 Databricks 开发,用于管理从实验到模型部署的整个机器学习生命周期。如果你看看他们的网站,他们有大量与所有流行的机器学习工具的集成,令人印象深刻的一系列公司正在使用并为此做出贡献。我只使用了软件包的“跟踪”功能,这使得在一个好看的用户界面上跟踪不同的机器学习实验变得非常容易。
使用软件包的提示
因此,使用 DVC 来控制数据的版本,使用 MLFlow 来记录实验结果,我创建了一个 Github 包, ml-template ,来帮助加速开发机器学习模型的过程。我的希望是,当你将来开始一个机器学习项目时,你会发现从 Github 克隆 ml-template 然后为你的项目定制代码是有帮助的。
现在,当然,当任何过程都是自动化的,是不是总是很容易使用“自动驾驶”软件,而不去想一些正在做的默认假设。特别是,每次你克隆 ml-template 的时候,我觉得你应该思考以下几点:
- 数据转换-确保适当完成必要的缩放、分类编码和特征转换(默认为无转换)。
- 训练/测试分割—确保分割适合您的问题(例如,默认为随机训练/测试分割,但分层分割可能更合适)。
- 算法—确保它适合任务(默认为随机森林)
- 度量——确保度量对于您的任务是合理的。一个典型的错误是在数据集高度不平衡时使用准确性作为衡量标准(默认的衡量标准是 AUC)
此外,这里有一些最有效地使用软件包的技巧:
- 每次进行“主”运行时,都要重新提交代码和数据。这确保了数据/代码/模型输出和保存的模型是一致的
- 调试时,设置 mlflow_record = False。这确保了只有重要的运行被记录,这有助于下游的模型分析
- 当试验新数据/新方法时,在 git 中创建一个新的分支。这利用了该框架的力量,使得比较/切换回现有设置变得非常容易
- 使用 MLFlow 中的实验对运行进行分组
结论
我希望人们发现这个包在更好地设置和管理他们的本地机器学习模型开发方面是有用的。
请不要客气贡献和建议的方式,以进一步改善包向前发展。未来发展的思路包括:
- 添加一组测试
- 用于直观显示模型结果的基本 UI 框架(使用工具,如 Streamlit
如何将你的熊猫代码加速 10 倍
原文:https://towardsdatascience.com/how-to-speedup-your-pandas-code-by-10x-79a61c509c8b?source=collection_archive---------10-----------------------
骗了你!诀窍是离开熊猫
图片来自 JESHOOTS athttps://www . pexels . com/photo/fuzzy-motion-of-illuminated-railway-station-in-city-253647/
众所周知,熊猫是一个神奇的数据科学工具。它为我们提供了我们需要的数据框架结构、强大的计算能力,并且以非常用户友好的格式做到了这一点。它甚至有高质量的文档和一个庞大的支持网络,使它易于学习。太棒了。
但并不总是特别快。
当涉及很多很多计算时,这可能会成为一个问题。如果处理方法很慢,则运行程序需要更长的时间。如果需要数百万次计算,并且总计算时间不断延长,那就非常麻烦了。
这是我工作中常见的问题。我工作的一大重点是开发代表建筑中常见设备的模拟模型。这意味着我在一台设备中创建模拟热传递过程和控制逻辑决策的功能,然后将描述建筑条件和居住者行为选择的数据传递到这些模型中。然后,模型预测设备将做什么,它将如何满足居住者的需求,以及它将消耗多少能量。
为了做到这一点,模型需要基于时间。它需要能够计算模拟中某一点发生了什么,然后才能进行下一组计算。这是因为一次的输出是下一次的输入。例如,想象一下预测你的烤箱在任何时间点的温度。目前正在加热吗?自上次讨论以来,温度上升了多少?当时的温度是多少?
这种对上一次的依赖导致了一个问题。我们不能使用向量计算。我们必须使用可怕的 for 循环。For 循环速度很慢。
我们能做些什么让事情进展得更快一点?
无论矢量化计算是否可行,一个解决方案是将计算转换为 numpy。根据 Sofia Heisler 在 Upside Engineering 博客上的说法,numpy 使用预编译的 C 代码执行大量的后台信息。这种预编译的 C 代码通过跳过编译步骤和包含预编程的速度优化,使它比 pandas 快得多。此外,numpy 删除了许多关于熊猫的信息。Pandas 跟踪数据类型、索引,并执行错误检查。所有这些都非常有用,但在这个时候没有必要,而且会减慢计算速度。Numpy 不会这样做,并且可以更快地执行相同的计算。
有多种方法可以将 panads 数据转换为 numpy。
可以使用。价值方法。这将在 numpy 中创建相同的系列。对于一个简单的示例,请参见下面的代码:
import pandas as pd
Series_Pandas = pd.Series(data=[1, 2, 3, 4, 5, 6])
Series_Numpy = Series_Pandas.values
数据帧可以使用。to_numpy()函数。这将在 numpy 中创建一个具有相同值的 int64 对象。注意,这不会保留列名,您需要创建一个字典,将 pandas 列名转换为 numpy 列号。这可以通过下面的代码来实现:
import pandas as pd
import numpy as npDataframe_Pandas = pd.DataFrame(data=[[0,1], [2,3], [4,5]], columns = ['First Column', 'Second Column'])
Dataframe_Numpy = Dataframe_Pandas.to_numpy()
Column_Index_Dictionary = dict(zip(Dataframe_Pandas.columns, list(range(0,len(Dataframe_Pandas.columns)))))
该代码将 dataframe 转换为 numpy int64 对象,并提供了遍历每一行所需的所有工具,以用户友好的方式编辑特定列中的值。每个单元都可以用类似熊猫的方式来调用。具有 numpy 索引的 loc 函数,遵循结构 int64object[row,Dictionary['Pandas 列名']] 。例如,如果要将“第二列”的第一行中的值设置为“9”,可以使用以下代码:
Dataframe_Numpy[0, Column_Index_Dictionary['Second Column']] = 9
这会让我的代码快多少?
当然,这将因情况而异。通过切换到 numpy,一些脚本会比其他脚本有更多的改进。这取决于脚本中使用的计算类型以及转换为 numpy 的所有计算的百分比。但是结果可能是激烈的。
例如,我最近用它将我的一个模拟模型从熊猫基地转换为 numpy 基地。最初,基于熊猫的模型需要 362 秒来进行年度模拟。超过 6 分钟了。如果你用模型运行一个模拟,这并不可怕,但是如果你运行一千个呢?在将模型的核心转换为 numpy 之后,同样的年度模拟需要 32 秒来计算。
做同样的事情要多花 9%的时间。将我的代码从 pandas 转换到 numpy 的速度比用户预先存在的函数快了 10 倍以上。
包装它
Numpy 拥有熊猫的所有计算能力,但执行它们时没有携带太多的开销信息,并且使用预编译、优化的方法。因此,它可以明显快于熊猫。
将数据帧从 pandas 转换为 numpy 相对简单。您可以使用数据框。to_numpy()函数来自动转换它,然后创建一个列名字典,以便像访问熊猫一样访问每个单元格。锁定功能。
这个简单的改变可以产生显著的效果。使用 numpy 的脚本执行时间大约是使用 pandas 所需时间的 10%。
如何分割一个 Pickled 模型文件以绕过 PythonAnywhere 上的上传限制
原文:https://towardsdatascience.com/how-to-spit-a-pickled-model-file-to-bypass-upload-limits-on-pythonanywhere-e051ea1cec2d?source=collection_archive---------38-----------------------
在这篇短文中,我将分享如何使用 python 和 os 库分割和连接一个 pickled 模型文件,以绕过 PythonAnywhere 上的上传限制。
凯文·Ku 拍摄的图片
在我的上一篇文章“建立一个卷积神经网络来识别剃过脸和没剃过脸的人”中,我分享了我用 Pickle 保存最终训练好的模型的方法。
“pickle”是将 Python 对象层次结构转换成字节流的过程,“unpickling”是相反的操作,将字节流(来自二进制文件或类似字节的对象)转换回对象层次结构。— 源代码: Lib/pickle.py
作为一个复习,这里有一行代码来处理你的最终模型,保存所有的权重,没有将结构保存为。json 文件,并作为. h5 文件单独加权。
import picklepickle.dump(model, open(“Your_Saved_Model.p”, ‘wb’))
因为我有一个模型,所以我的目标是构建一个 Flask 应用程序,并部署它供公众使用。我选择 PythonAnywhere 来托管我的应用程序,因为我需要访问 Bash 控制台,还需要设置一个虚拟环境,但是我意识到文件上传是有限制的,我的模型比允许的大了三倍。
我做了一些研究,发现了一篇非常有帮助的文章,在理解如何用 Python 拆分和合并文件方面。使用os
库和下面的函数,我能够将 pickled 模型文件分割成三个更小的文件:
def split(source, dest_folder, write_size):
# Make a destination folder if it doesn't exist yet
if not os.path.exists(dest_folder):
os.mkdir(dest_folder)
else:
# Otherwise clean out all files in the destination folder
for file in os.listdir(dest_folder):
os.remove(os.path.join(dest_folder, file)) partnum = 0
# Open the source file in binary mode
input_file = open(source, 'rb') while True:
# Read a portion of the input file
chunk = input_file.read(write_size)
# End the loop if we have hit EOF
if not chunk:
break
# Increment partnum
partnum += 1
# Create a new file name
filename = '/Model_Files/final_model' + str(partnum)
# Create a destination file
dest_file = open(filename, 'wb')
# Write to this portion of the destination file
dest_file.write(chunk) # Explicitly close
dest_file.close() # Explicitly close
input_file.close() # Return the number of files created by the split
return partnum
该函数需要 source、write_size 和 dest_folder。source 是保存整个模型的位置,write_size 是每个文件的字节数,dest_folder 是保存每个分割文件的目标文件夹。
这里有一个例子:
split(source='Your_Saved_Model.p', write_size=20000000, dest_folder='/Model_Files/')
因为我现在有三个可接受的上传文件,所以一旦应用程序在浏览器中启动,我需要更新我的 flask 应用程序来处理服务器上的文件连接。这里有一个到我的 GitHub repo 的链接,可以在部署到 PythonAnywhere 之前查看完整的代码。
我使用下面的函数来连接文件,并将合并后的模型保存在应用程序的服务器上:
def join(source_dir, dest_file, read_size):
# Create a new destination file
output_file = open(dest_file, 'wb')
# Get a list of the file parts
parts = ['final_model1','final_model2','final_model3']
# Go through each portion one by one
for file in parts:
# Assemble the full path to the file
path = file
# Open the part
input_file = open(path, 'rb')
while True:
# Read all bytes of the part
bytes = input_file.read(read_size)
# Break out of loop if we are at end of file
if not bytes:
break
# Write the bytes to the output file
output_file.write(bytes)
# Close the input file
input_file.close()
# Close the output file
output_file.close()join(source_dir='', dest_file="Combined_Model.p", read_size = 50000000)
这个函数将单个文件字节合并成一个单独的 pickled 对象。看看我如何使用 jQuery 让用户以一种交互的方式上传图像,并通过向后端发送请求来进行预测,使用新的组合模型来服务于预测。查看我的 GitHub repo 应用程序。
资源 :
[## Python 拆分和连接文件
《编程 Python:强大的面向对象编程》这本书有一个示例程序,展示了如何拆分和…
stonesoupprogramming.com](https://stonesoupprogramming.com/2017/09/16/python-split-and-join-file/)
如何用 Python 将一个数据帧分割成训练集和测试集
原文:https://towardsdatascience.com/how-to-split-a-dataframe-into-train-and-test-set-with-python-eaa1630ca7b3?source=collection_archive---------9-----------------------
在熊猫数据帧上使用 sklearn train_test_split 的简短指南
作者插图
在这篇短文中,我描述了如何通过应用 sklearn 的 train_test_split 函数,将数据集分割成用于机器学习的训练和测试数据。我使用我上一篇文章中的程序创建的数据框。这些数据基于 D. Greene 和 P. Cunningham 发表的原始 BBC 新闻文章数据集[1]。
如果你感兴趣,可以在这里查看源代码。
如果您错过了我的第一个从文本文件中提取信息的指南,您可能想要查看它以更好地理解我们正在处理的数据。
[## 用 Python 将文本文件转换成数据表
从任何文本文件中提取信息的可重用方法
towardsdatascience.com](/transforming-text-files-to-data-tables-with-python-553def411855)
数据理解
因为我想让本指南保持简短,所以我不会像在我的上一篇文章中那样详细描述这个步骤。在这一部分要提到的最重要的信息是数据是如何构造的以及如何访问它。
从下面的截图可以看出,数据位于 generated_data 文件夹中。一旦创建了这些文件,我们还想将训练和测试数据保存到这个文件夹中。此外,该脚本在 prepare_ml_data.py 文件中运行,该文件位于 prepare_ml_data 文件夹中。
文件系统的屏幕截图
正如我在关于将文本文件转换为数据表的上一篇文章中所介绍的,bbc_articles.tsv 文件包含五列。然而,对于本教程,我们只对文本和流派列感兴趣。
数据集的列
加载数据
第一步,我们希望将数据加载到我们的编码环境中。为此,我们需要存储数据的目录的路径。我们保存本地变量的路径来访问它,以便加载数据,并使用它作为保存最终训练和测试集的路径。由于数据存储在与运行脚本的文件不同的文件夹中,我们需要在文件系统中返回一级,在第二步中访问目标文件夹。我们通过加入“..”来实现这一点以及导致‘的数据文件夹../generated_data/'。
使用 generated_data 文件夹的路径,我们创建另一个指向数据文件本身的变量,称为 bbc_articles.tsv。由于它是一个制表符分隔值文件(tsv),我们需要添加' \t '分隔符,以便将数据作为 Pandas Dataframe 加载。
选择要分割的数据(可选)
将数据分成训练集和测试集不需要以下命令。然而,由于我不需要数据集的所有可用列,所以我选择了想要的列,并创建了一个新的 dataframe,其中只有“text”和“genre”列。
分割和保存
现在,我们已经准备好了分割它的数据。幸运的是,sklearn 库的 train_test_split 函数能够处理 Pandas 数据帧和数组。因此,我们可以简单地通过提供数据集和其他参数来调用相应的函数,例如:
- test_size :
该参数表示应该包含在测试分割中的数据集的比例。这个参数的缺省值被设置为 0.25,这意味着如果我们不指定 test_size,那么产生的分割由 75%的训练数据和 25%的测试数据组成。 - random_state :
该参数控制分割前应用于数据的洗牌。通过定义随机状态,我们可以在多个函数调用中重现相同的数据分割。 - 洗牌 :
该参数表示数据在分割前是否需要洗牌。因为我们的数据集是按流派排序的,所以我们肯定要打乱它。否则,训练集和测试集将不会包含相同的类型。
在分割数据之后,我们使用目录路径变量来定义保存训练和测试数据的文件路径。通过将数据帧转换为 csv,同时使用' \t '作为分隔符,我们创建了制表符分隔的训练和测试文件。
结论
在这篇短文中,我描述了如何加载数据,以便将数据分成训练集和测试集。相应的数据文件现在可以用于训练和评估文本分类器(尽管取决于模型,可能需要额外的数据清理)。
在未来的文章中,我将描述如何建立不同的深度学习模型(如 LSTM 和伯特)来训练文本分类器,这些分类器根据文章的文本来预测文章的体裁。下面是我的文章的链接,在这篇文章中,我使用 FARM 框架为文本分类微调 BERT。
[## 微调用于 FARM 文本分类的 BERT
使用最先进的 NLP 模型进行简单快速的迁移学习
towardsdatascience.com](/fine-tuning-bert-for-text-classification-with-farm-2880665065e2)
非常感谢你的阅读和快乐编码!
参考
1d .格林和 p .坎宁安。核心文档聚类中对角优势问题的实际解决方案。ICML 2006。
如何拆分 Shapefiles
原文:https://towardsdatascience.com/how-to-split-shapefiles-e8a8ac494189?source=collection_archive---------20-----------------------
切割阿拉斯加附近的西阿留申群岛(它们大多无人居住)
阿拉斯加。杆长在上拍照
有时您只需要 shapefile 的一部分。根据哪一部分和 shapefile 源,这可能非常简单,也可能不那么简单。例如,前几周,我在绘制美国各州向联邦消费者金融保护局投诉的相对比率(更多此处),我的 choropleth 是这样绘制的:
虽然在这个比例下很难看到,但是西阿留申群岛穿过了 180 度经线,形成了这幅试图将球体展平为矩形的不连贯地图。
解决这个问题有几种选择:
- 将不需要的(同样是无人居住的)面从其多面簇中分离出来
- 对整个地理数据框使用 shapely 函数
.intersects()
- 在 matplotlib 中设置绘图的 x 极限
- 将正/东经多边形转换为负/西经多边形
- 使用 Cartopy 进行不同的地图投影,而不是拆分形状
更多的阿拉斯加,而不是西阿留申群岛。帕克森·沃尔伯在 Unsplash 上拍摄的照片
我们开始吧:
将不需要的(同样是无人居住的)面从其多面簇中分离出来
我想从这个选项开始,因为它解决了一个我一次又一次碰到的更普遍的问题。如何在shapely
和/或geopandas
中拆分多个多边形,然后将它们放回一起用于 choropleths。
首先,我加载 shapefiles 并选择我想要处理的记录,在本例中是阿拉斯加。(谢谢美国人口普查提供的 shapefiles!#opendata)
# import necessary packages
import geopandas as gpd
from matplotlib import pyplot as plt# load shapefile
states_gdf = gpd.read_file('./data/cb_2018_us_state_5m.shp')# select Alaska
alaska_gdf = states_gdf.loc[states_gdf['STUSPS'] == "AK"]
修改前的阿拉斯加地块。
“geometry”列返回一个单项数据帧。您可以通过.values
访问形状良好的几何图形列表。在这种情况下,我们的单记录数据框架有一个项目列表。通过访问第一个值,我们得到了阿拉斯加形状优美的多多边形。
alaska_mp = alaska_gdf['geometry'].values[0]
或者,您可以使用原始状态地理数据框架,但我总是忘记到底有多少层,并且发现使用我的单记录数据框架进行猜测和检查更容易。
alaska_mp_alt = states_gdf.loc[states_gdf['STUSPS'] == "AK",
'geometry'].values[0]
使用多重多边形,您可以像访问列表或数组一样访问每个多边形。
阿拉斯加多重多边形中的第一个多边形。
在其当前形式下,当使用 Shapely 函数(如)时,整个多边形集合(多多边形)被视为一个整体。相交())。为了分别考虑每个面,我将多重面转换为其自己的地理数据框架:
# create the GeoDataFrame
ak_exp_gdf = gpd.GeoDataFrame(alaska_mp)# set the geometry column
ak_exp_gdf.columns = ['geometry']
现在我们有了一个地理数据框,其中每一行都是一个多边形,它们共同构成了阿拉斯加,我们可以根据我们想要或不想要的位置来过滤这些地理数据框了。我们需要制作一个形状优美的多边形,用来判断和过滤阿拉斯加的每一片土地。我们需要一个多边形来覆盖你想要(或不想要)的所有区域,我们将使用.intersects()
或你选择的另一个 shapely 函数来分类你的形状。
多边形是用一列点/顶点创建的。最后一个点会自动连接到第一个点,因此您不需要自己闭合回路。
from shapely.geometry import Polygon# create polygon that covers Alaska up to the 180th Meridian
target_poly = Polygon([(-180, 50), (-180, 75),
(-100, 75), (-100, 50)])
现在我们可以使用这个多边形和 shapely/geopandas 的.intersects()
进行过滤。
western_isles = ak_exp_gdf[al_exp_gdf.intersects(target_poly) ==
False].copy()
eastern_ak = ak_exp_gdf[al_exp_gdf.intersects(target_poly)].copy()
阿拉斯加东部的地块
厉害!!!
照片由 McKayla Crump 在 Unsplash 上拍摄
将面的地理数据框架合并为多面
现在我们有了感兴趣的阿拉斯加多边形,我们准备将此几何图形放入我们的州地理数据框架中。我们使用“by”参数,用.dissolve()
将一个多边形的数据帧组合成一个或多个多多边形。(我仍然不明白让“溶解”感觉像是“粘合”或“结合”的同义词的框架——也许我们正在溶解边界?)
# add a column to groupby
eastern_ak['STUSPS'] = 'AK'# combine polygons/records into a single multipolygon/record
alaska_trimmed = eastern_ak.dissolve(by='STUSPS')# add this new multipolygon in place of the old alaska multipolygon
states_trimmed = states_gdf.copy()
states_trimmed.loc[states_trimmed['STUSPS'] == 'AK', 'geometry']
= alaska_trimmed['geometry'].values
我们准备好了!
修剪过的美国地图。充分披露:我还修剪关岛,北马里亚纳群岛联邦,美属萨摩亚出这个阴谋。
这是一个包含阿拉斯加的 choropleth 示例——水域面积与陆地面积的比率。阿拉斯加的巨大面积确实让我们很难看到东部的一些州,但控制局面很好,可以自由决定是否(以及如何)通过修剪来包含不同的形状。
在整个地理数据框上使用匀称的.intersects()
您也可以修改几何图形,而无需将多重多边形分解为单独的多边形。这种方法确实有其特殊性,但是代码行要少得多。请注意,使用GeoDataFrame.intersection(*shape*)
会返回一系列几何图形,而不是添加了新信息的原始地理数据框。您需要添加或替换一个列来将此信息存储在现有的地理数据框中。
from shapely.geometry import Polygon# create a polygon with the desired dimensions of the map
desired_map = Polygon([(-180, 80), (-60, 80), (-60, 15),
(-180, 15)])# create a new copy of the states GeoDataFrame for this example
states_trimmed_v3 = states_gdf.copy()# get the intersection of the states geometries with the desired map states_trimmed_v3['geometry'] = states_gdf.intersection(desired_map)
如果你试图直接.plot()
这个几何集合,你可能会得到一个TypeError: ‘Polygon’ object is not subscriptable
。当您有一些记录与您的相交几何不重叠时,就会发生这种情况,在我们的示例中,就是太平洋地区。在这种情况下.intersection()
返回一个空多边形。我的解决方案是在绘图前过滤这种情况。
states_trimmed_v3[states_trimmed_v3['geometry'] != Polygon()].plot()
我们得到了与上面相同的结果,不需要找到令人讨厌的形状,分割多重多边形,然后将多边形融合成一个单一的多重多边形。根据您的用例,这绝对是一个好的选择。
美丽的阿拉斯加天空。照片由麦克凯拉·克伦普在 Unsplash 上拍摄
在 matplotlib 中设置绘图的 x 极限
另一个简单的选择是使用matplotlib
的图形界面来删除任何不想要的区域。
fig, ax = plt.subplots(figsize=(15,10))
alaska_gdf.plot(ax=ax)
ax.set_xlim(-180, -128)
使用 matplotlib 的绘图选项 ax.set_xlim()修剪阿拉斯加
将正/东经多边形转换为负/西经多边形
如果你想保留投影和阿留申群岛西部,你可以使用.translate()
将这些多边形的 x 值移动-360°。该选项使用上文描述的分割多多边形的技术
# shift the western isles by 360 degrees
western_isles_shifted = western_isles.translate(xoff=-360)# convert to GeoDataFrame
west_ak_shift_gdf = gpd.GeoDataFrame(western_isles_shifted)
west_ak_shift_gdf.columns = ['geometry']# add 'STUSPS' column
west_ak_shift_gdf['STUSPS'] = 'AK'# combine the western and eastern parts into the same dataframe
ak_shifted_actual_gdf = west_ak_shift_gdf.append(eastern_ak,
ignore_index=True)# combine/dissolve into a single MultiPolygon
ak_shifted_actual_dissolved =
ak_shifted_actual_gdf.dissolve(by='STUSPS')
这会生成 x 值为-190 到-125 的阿拉斯加。在绘图时,您可能需要调整 x 刻度标签,以符合传统的-180°到+180°约定。
fig, ax = plt.subplots(figsize=(15, 12))
ak_shifted_actual_dissolved.plot(ax=ax)# get the locations and labels of the x-ticks
locs, labels = plt.xticks()# set the first label in labels to 170 instead of -190
labels[1] = '170'# set the x-ticks with new labels (keeping the locs)
plt.xticks(locs, labels)
阿拉斯加和所有的阿留申群岛。
注意:我试图将整个美国移动+30 °,但这只改变了 x 轴上的 x 刻度值,而没有将地图最右边的部分移到左边。
对 Cartopy 使用不同的地图投影
或者,您可以使用Cartopy
根据自己的喜好改变地图投影。我喜欢这个选项!它允许您将地理空间数据调整到对项目最有意义的视图。
首先,用conda install -c conda-forge cartopy
安装或查看完整安装指南。请注意,我在 conda-forge 通道上也安装了 geopandas 将所有这些包及其依赖项安装在同一个通道上可能很好。
那你准备好了!基本使用与上述相同的投影(平板托架):
# set figure size
fig = plt.figure(figsize=(15, 12)# set axis with desired projection
ax = plt.axes(projection=ccrs.PlateCarree())# add shapes, indicating their original projection
ax.add_geometries(states_gdf['geometry'],
crs=ccrs.PlateCarree())# add gridlines
gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True,
linewidth=.5, color='gray', alpha=0.5)# display map
plt.show();
美国地图与卡雷板投影。
你可以在这里查看所有的预测。在我的例子中,允许你设置视图中心的投影正是我所寻找的。
# set desired projection/view
ax = plt.axes(projection = ccrs.Orthographic(central_longitude=-100,
central_latitude=40))# add your shapes (indicating their existing projection)
ax.add_geometries(states_gdf.geometry, crs=ccrs.PlateCarree())# add coastlines and gridlines for context
ax.coastlines(linewidth=.5)
ax.gridlines()
未用正交投影修剪的美国
您还可以使用ax.set_extent(*xmin, ymin, xmax, ymax*)
聚焦于特定区域。
若要调整几何图形的颜色,请使用各种面颜色分别添加它们。例如与上述相同的 choropleth:
from matplotlib.colors import Normalize# value normalization for the color map
values = list(states_trimmed_v2['water:land'])
norm = Normalize(vmin=min(values), vmax=max(values))# select color map
cmap = plt.cm.get_cmap('viridis')#create chorpleth: set fig and ax projection
fig = plt.figure(figsize=(15,15))
ax = plt.axes(projection = ccrs.Orthographic(central_longitude=-100, central_latitude=40))# add each state to the ax with its appropriate facecolor
for state_i in states_trimmed_v2.index:
geom = []
geom.append(states_trimmed_v2.loc[state_i, 'geometry'])
facecolor = cmap(norm(states_trimmed_v2.loc[state_i, 'water:land']))
ax.add_geometries(geom,
ccrs.PlateCarree(),
facecolor=facecolor,
edgecolor='grey',
linewidth=.2)
ax.set_title('States By Water Area to Land Area Ratio', fontsize=20)
ax.coastlines(linewidth=.2)
ax.gridlines()
带有卡通图案的 Choropleth
有关更多信息,请查看以下资源:
- 使用地理空间数据:这篇博文(由你的真实作者撰写)
- Cartopy 简介:由 geohackweek 发布
在这里找到 GitHub 回购。编码快乐!
黄斌在 Unsplash 上的照片
如何识别数据骗子
原文:https://towardsdatascience.com/how-to-spot-a-data-charlatan-85785c991433?source=collection_archive---------0-----------------------
识别骗子和中和他们的蛇油的提示
你可能听说过分析师、 ML/AI 工程师和统计员,但你听说过他们的高薪表亲吗?认识一下数据江湖骗子!
受到有利可图的工作的诱惑,这些叫卖者给合法的数据专业人士带来了坏名声。
图片:来源
【赶时间?向下滚动查看底部的快速摘要。]
数据骗子无处不在
您的组织很可能已经窝藏这些骗子多年,但好消息是,如果您知道要查找什么,他们很容易识别。
数据骗子非常善于隐藏在众目睽睽之下,以至于你甚至可能已经是一个了,而你却没有意识到这一点。啊哈!
第一个警告信号是未能理解分析和统计是非常不同的学科。我将在下一部分给你一个简要的概述,但是如果你想更深入地理解它,我在这里写了一整篇文章。
不同学科
统计学家接受的训练是推断数据之外的东西,而分析师接受的训练是探索数据集内容。换句话说,分析师对数据中的内容做出结论,而统计学家对数据中的内容做出结论。
分析师帮助你提出好的问题(假设生成),而统计学家帮助你得到好的答案(假设检验)。
也有奇特的混合角色能够身兼两职…但他们不会同时身兼两职。为什么不呢?数据科学的一个核心原则是,如果你在处理不确定性,那么使用相同的数据点来生成假设和进行测试是无效的。当你的数据有限时,不确定性迫使你在统计和分析之间做出选择。(此处 找到我的解释 )。)
没有统计数据,你就无法知道你刚刚形成的观点是否站得住脚。
没有分析,你就像瞎飞一样,几乎没有机会驯服你未知的未知。
这是一个艰难的选择!当你发誓放弃知道你的新观点是否站得住脚的满足感时,你会睁开眼睛寻找灵感吗?或者你会冷汗直流,祈祷你选择问的问题——在没有任何数据的情况下独自沉思——值得你即将得到的严谨答案(统计)吗?
兜售后见之明的人
江湖骗子摆脱这种困境的方法是忽略它,在薯片中找到猫王的脸,然后假装惊讶于同一个薯片看起来像猫王。(统计假设检验的逻辑可以归结为一个问题:我们的数据是否足以让我们惊讶到改变主意。如果我们已经看到了数据,我们怎么会对它们感到惊讶呢?)
你觉得这些像兔子和猫王的肖像吗?或者总统肖像?关于这个话题的乐趣,请看我的相关文章这里。
每当江湖骗子找到一个模式,得到灵感,然后测试相同的 数据以得到那个相同的模式发布结果,并在他们的理论旁边加上一两个合法化的 p 值,他们实际上是在骗你(也许也在骗他们自己)。那个 p 值没有任何意义,除非你在查看数据之前先确认你的假设。
江湖骗子模仿分析师和统计学家的行为,却不理解其原因,这给整个数据科学领域带来了坏名声。
真正的统计学家总是发号施令
由于统计行业在严谨推理方面近乎神秘的声誉,数据科学领域的“蛇油”销量创下了历史新高。用这种方式作弊很容易不被抓到,尤其是如果你不知情的受害者认为这都是方程式和数据的问题。数据集就是数据集,对吧?不对。你如何使用它很重要。
数据集就是数据集,对吧?不对。你如何使用它很重要。
幸运的是,对于他们的潜在目标,你只需要一条线索就能抓住他们:江湖骗子兜售马后炮。
一个江湖骗子兜售后见之明——从数学上**重新发现他们已经知道存在于数据中的现象——而一个统计学家则提供远见测试。
与江湖骗子不同,优秀的分析师是思想开放的典范,总是将鼓舞人心的见解与提醒相结合,提醒人们观察到的现象可能有许多不同的解释,而优秀的统计学家在做出判断之前会小心谨慎。
优秀的分析师是思想开放的典范。不像江湖骗子,他们不会在数据之外下结论。
分析师产生灵感
分析师可以免于发号施令……只要他们的数据不超过。如果他们想对自己没见过的东西发表看法,那就是另一回事了。他们应该摘下他们的分析师帽子,戴上他们的统计学家头盔。毕竟,不管你的正式职称是什么,没有规定说你不能想学就学。别把他们搞混了。
江湖骗子如何测试假设?迷因:来源。
擅长统计并不意味着你擅长分析,反之亦然。如果有人试图告诉你,检查你的口袋。如果那个人告诉你,你被允许对你已经研究过的数据进行统计推断,检查你的口袋两次。
躲在花哨的解释后面
如果你在野外观察数据骗子,你会注意到他们喜欢编造一些奇特的故事来“解释”观察到的数据。越学术化越好。不要介意这些故事只是(过度)符合事后的数据。
当江湖骗子那样做时——让我直截了当地说吧——他们是在胡扯。再多的等式或相当的武断也无法弥补这样一个事实,即他们没有提供任何证据证明他们知道自己在谈论的数据之外的东西。
不要被他们的解释有多花哨所打动。为了进行统计推断,他们必须在看到数据之前做出决定。
这相当于炫耀他们的“通灵”能力,首先偷看你拿到的手牌,然后预测你手里拿的是什么……不管你手里拿的是什么。准备好接受他们的小说吧,是你的面部表情泄露了秘密。那是 后知后觉的偏见 而数据科学职业就是用它塞到腮里的。
分析师说,“你刚才出的是一张方块皇后。”统计学家说,“在我们开始之前,我在这张纸上写下了我的假设。我们来玩玩,观察一些数据,看看我说的对不对。”江湖骗子说,“我知道你会一直玩方块皇后,因为……”(机器学习说,“我会不断提前调用它,看看我做得如何,一遍又一遍,我可能会调整我对有效策略的反应。但我会用算法来做,因为手动跟踪一切很烦人。”)
江湖骗子-证明你的生活
当没有足够的数据时,你不得不在统计和分析之间做出选择。
数据分割是每个人都需要的文化快速解决方案。
幸运的是,如果你有足够的数据,你有一个很好的机会利用分析和统计数据而不作弊。你也拥有对抗骗子的完美保护。它被称为数据分割,在我看来,这是数据科学中最强大的想法。
永远不要认真对待未经检验的意见。相反,使用一堆测试数据来找出谁知道他们在谈论什么。
为了保护自己免受骗子的攻击,你所要做的就是确保你让一些测试数据远离他们窥探的目光,然后把其他一切都当作分析(不要当真)。当你面对一个你可能会相信的理论时,用它来发号施令,然后打开你的秘密测试数据,看看这个理论是否是胡说八道。就这么简单!
确保您不允许任何人在探索阶段查看测试数据。坚持探索性的数据。测试数据不应用于分析。迷因:来源
这是一个巨大的文化转变,在“小数据”的时代,你必须解释你如何知道你所知道的,以便说服人们——脆弱地——你可能确实知道一些东西。
同样的规则也适用于 ML/AI
一些冒充 ML/AI 专家的江湖骗子很容易被发现。你会像抓其他糟糕的工程师一样抓到他们:他们试图构建的“解决方案”反复失败。(早期的警告信号是缺乏行业标准编程语言和库的经验。)
但是那些生产看起来工作正常的系统的人呢?你怎么知道是否有可疑的事情发生?同样的规则也适用!江湖骗子是一个阴险的角色,他向你展示他们的模型表现得有多好……基于他们用来制作模型的相同数据。*face palmT5***
如果你已经建立了一个疯狂复杂的机器学习系统,你怎么知道它有没有用?你不…直到你证明它对以前没有见过的新数据有效。
如果你在制作数据之前已经看过了,那就很难说了。
当你有足够的数据来拆分时,你不需要用漂亮的公式来证明你的项目(这仍然是一个过时的习惯,我在任何地方都能看到,不仅仅是在科学领域)。你可以说,“我知道它有效的原因是,我可以获得一个我以前没有见过的数据集,我可以准确地预测那里将会发生什么……并且是正确的。一遍又一遍。”
在新数据中测试你的模型/理论是信任的最好基础。
掌握你的统计数字,或者保持谦逊
套用经济学家保罗·萨缪尔森的一句妙语:
江湖骗子成功预测了过去五次衰退中的九次。
我对数据骗子没有耐心。你认为你“知道”一些关于猫王薯片的事情吗?我不在乎你的观点有多符合你的旧芯片。你的解释多么花哨,我不以为然。让我看看你的理论/模型在你从未见过的一大堆新芯片中是有效的(并且一直有效)。这是对你观点勇气的真正考验。
图片:来源
给数据科学专业人员的建议
数据科学专业人士,如果你想被理解这种幽默的人认真对待,就不要再躲在花哨的方程式后面支撑你的人类偏见。让我们看看你有什么。如果你想让那些“明白”的人将你的理论/模型视为不仅仅是一首鼓舞人心的诗歌,就要有勇气在一个全新的数据集上展示它有多好……在证人面前!
给领导者的建议
领导者,拒绝认真对待任何数据“见解”,直到它们在新数据上得到检验。不想努力吗?坚持分析,但不要依赖这些见解——它们是脆弱的,没有经过可信度检查。此外,当您的组织拥有大量数据时,将拆分作为您的数据科学文化的核心部分,甚至通过控制对指定用于统计的测试数据的访问,在基础架构级别强制执行拆分,也没有什么坏处。这是将蛇油销售企图扼杀在萌芽状态的好方法!
更多坏把戏
如果你想看到更多江湖骗子不怀好意的例子,这条 Twitter 帖子很棒。
摘要
当数据太少而无法分割时,只有一个数据骗子试图严格地遵循灵感,通过数学方法重新发现他们已经知道存在于数据中的现象,并声称他们的惊喜具有统计意义,兜售后见之明。这将他们与处理灵感的开明分析师和提供远见证据的一丝不苟的统计学家区分开来。
当数据充足时,养成分割数据的习惯,这样你就可以两全其美而不作弊了!确保对原始数据的不同子集分别进行分析和统计。
- 分析师为你提供开明的灵感。
- 统计学家为你提供严格的测试。
- 江湖骗子向你提供扭曲的马后炮,假装是分析加统计。
感谢阅读!人工智能课程怎么样?
如果你在这里玩得开心,并且你正在寻找一个为初学者和专家设计的有趣的应用人工智能课程,这里有一个我为你制作的娱乐课程:
在这里欣赏整个课程播放列表:bit.ly/machinefriend
与凯西·科兹尔科夫联系
让我们做朋友吧!你可以在 Twitter 、 YouTube 、 Substack 和 LinkedIn 上找到我。有兴趣让我在你的活动上发言吗?使用表格联系。
如何使用谷歌云平台启动数据科学项目
原文:https://towardsdatascience.com/how-to-start-a-data-science-project-using-google-cloud-platform-6618b7c6edd2?source=collection_archive---------6-----------------------
利用谷歌云平台(GCP)服务创建 Python Jupyter 笔记本工作环境
什么是数据科学项目?
我的导师曾经告诉我,数据科学是关于:
1.从数据中获得洞察力
2.将这些见解传达给你的客户
沟通对于几乎每个数据科学家来说都是至关重要的,在所有的沟通方式中,展示代码和可视化将是最直接和最常见的方式。和这个领域的大多数人一样,我在我的数据科学项目中使用了很多笔记本/减价品。因此,我很有信心地说,笔记本风格的工作流,使您能够在编写新代码时看到代码的所有结果,将是进行数据科学项目的一个很好的环境。
为什么要用谷歌云平台?
GCP ( 谷歌云平台)是谷歌提供的云计算服务。对于那些不熟悉云服务的人来说,它基本上是使用网络连接到你租用的远程机器,在那台机器上进行计算并发回结果。就像租车一样。显然,使用云计算服务:
1.给你一台性能更好的机器来完成你的计算。(当然,如果你付够钱的话)
2.通过租赁而不是购买超级计算机来降低计算的实际成本。(就像租车一样不是吗)
3.解放您自己的笔记本电脑,这样您就可以一边玩视频游戏,一边进行繁重的并行计算。
现在实际上有很多公司提供云服务。AWS、Azure、GCP,应有尽有。然而,谷歌为第一年使用的注册用户提供 300 美元的积分。有了它,你可以租用一个简单的实例一整年,或者尝试一个巨大的实例几天。因此,对于任何不熟悉云服务并且在尝试之前不愿意付费的人来说,这是一个不错的选择!
在下面的案例中,我将展示如何在使用谷歌云平台的 Python 下使用 Jupyter Notebook 启动一个数据科学项目。
1.注册谷歌云平台
在:https://cloud.google.com
首页上应该有一个邀请,要求您激活 300 美元的试用版。输入你的信息和支付信息(只是为了验证你不是机器人,在你用完你的信用后不会有收费或订阅),你就可以走了!
2.创建新的项目和实例
如果你刚到 GCP,你应该已经有一个自动生成的项目,叫做“我的第一个项目”。您可以稍后在项目设置中更改项目名称。如果你更喜欢创建一个新的,那就用谷歌的这个教程吧。
创建虚拟机实例
现在选择左侧栏—计算—计算引擎—虚拟机实例。您现在应该没有任何实例,请单击“创建”。
设置实例第 1 部分
- 名字:你可以选择给你的实例命名
- Region and Zone :这是您的实例的物理位置。你会想选择一个离你比较近的地点,但是只要和你在同一个洲就不会有太多的差异。
- 机器配置:这是最重要的部分。除非明确知道自己需要什么,否则不必指定 CPU 系列、平台、GPU。默认情况下,它将选择 n1-standard-1 机器,具有 1 个内核和 3.75GB RAM。你可以向下滚动机器类型并选择你想要的,或者选择自定义,这样你就可以分别输入 CPU 内核和内存的数量。
- 启动盘:英文中是指你选择的操作系统。我一般选择默认的 Debian GNU/Linux 9 (stretch)。和 CPU 一样,不知道自己需要什么就不想换。我还发现 Linux 上的深度学习很有用,因为它预装了许多重要的软件包,尽管如此,我还是选择了默认的,这样我就可以跟踪我正在使用的软件包的具体版本。
设置实例第 2 部分
在这里,您可以选择 API 访问和防火墙设置。
将服务帐户保留为默认值,并选择“ 允许完全访问所有云 API”,以便在使用新 API 时节省大量设置 API 的工作。在防火墙 中允许 HTTP 和 HTTPS 流量 。
设置实例第 3 部分
如果您点击 【管理、安全、磁盘、联网】 您可以选择进一步的设置。通常情况下,你不想改变这些。但是,您可以在可用性策略中选择开启 抢占 。抢占性就像 AWS 中的 Spot 实例一样:
- 它的价格要低得多,大约是正常价格的 20%到 30%
- 它只持续 24 小时
- 它可以在你运行的任何时候被关闭
所以,如果你正在做的项目不需要连续运行几个小时并且在 24 小时内完成工作也没问题,这就是省钱的方法。现在一切都设置好了,点击 create 来创建您的第一个 GCP 实例。
3.设置外部 IP 和防火墙
设置网络第 1 部分
首先进入左侧栏——网络——VPC 网络——外部 IP 地址。
设置网络第 2 部分
在该类型下,您应该会发现您的新实例是短暂的。点击它并将其更改为静态,随你怎么命名。
现在进入左侧栏—网络— VPC 网络—防火墙规则—创建防火墙规则。
随便你怎么命名,在目标中选择“ 网络中的所有实例 ,放入“ 0.0.0.0/0 ”
在源 IP 范围中,选择 指定协议和端口 ,在【TCP中输入 8888 。
然后单击创建。
4.连接到您的实例
现在回到左侧栏——计算——计算引擎——虚拟机实例。您应该看到您的实例正在运行,名称前面有一个绿色的勾号。单击 SSH 按钮连接到您的实例,这将启动一个自动连接到它的云终端。
连接到您的实例
如果你更喜欢通过你的本地终端或者云外壳来连接它,你将不得不安装 gcloud 并设置Google SDK然后使用 gcloud compute ssh 命令来连接。你可以带着这个教程去。
5.设置您的工作环境
我们正在使用 Linux 系统内置的 Makefile 命令来设置一切。您可以创建自己版本的事物和环境,也可以尝试我的代码作为快速入门。
首先,来自 GCP 的普通 Debian 环境可能没有我们需要的完整的基本工具和软件包:
当提示您是否继续时,输入“y”。
现在做 git 克隆来下载我的快速入门代码:
您可以使用 ls 命令检查下载,它应该只返回您刚刚下载的 MyEnv 。使用 cd 命令转到目录 MyEnv 。
然后运行这三行代码:
6.打开你的 Jupyter 笔记本
首先确保你在正确的目录中,在那里你已经准备好了你的数据,因为一旦你启动一个笔记本,你就不能去父目录。其次,确保你在虚拟环境中,因为你所有的包都被安装在那里:如果你在这个环境中,一个(。env) 应该显示在你的名字前面。
然后放进去:
然后回来。现在笔记本已经在运行了,但是你仍然需要自己连接它。打开浏览器,输入下面一行,其中
7.(可选)使用云存储桶传输数据
您还可以选择使用上传按钮直接在实例界面中上传数据。但是,我鼓励您使用 Gcloud Storage Buckets 来完成这项工作,因为它可以轻松连接到您所有的 GCP 项目。
首先,您需要单击这个页面顶部的 Create Bucket。
创建一个桶
注意命名指南,因为每个 bucket 名称必须是唯一的,并且所有名称都是公开可见的。对于位置,您应该考虑存储桶价格以及实例的位置。(例如 US-WEST1 、 US-CENTRAL1 和 US-EAST1 有 5 GB 的免费存储空间,在同一区域内将数据从 bucket 传输到实例是免费的,请参见定价详情此处),以便您根据自己的使用情况获得最佳设置。我倾向于将其他一切都保留为默认设置,以便您可以从日常使用中获得最佳设置。
创建存储桶后,您可以通过单击存储桶中的上传按钮将数据从本地上传到存储桶。
将文件上传到您的存储桶
或者使用 Gcloud SDK 工具自带的 gsutil 函数。代码格式就像 cp 或者 scp 一样。假设您想将 data.csv 从您的主目录上传到 bucket:
现在您已经将数据放入桶中,接下来您应该做的是连接到您的实例,使用相同的 gsutil 函数,并将其传输到您的实例的主目录:
现在,通过第 6 步,您可以打开笔记本,读取数据并继续探索您的数据科学项目!
如何在一个月内开一个机器学习博客
原文:https://towardsdatascience.com/how-to-start-a-machine-learning-blog-in-a-month-7eaf84692df9?source=collection_archive---------36-----------------------
你学了人工智能,现在教它!
我是怎么做到的,你也能做到!
我是深度学习爱好者 Dweep。我已经完成了许多 ML 和 AI 课程,我觉得是时候回报社会了。
MS Paint 的奇迹
因此,我在 Blogger 上开了一个名为LightSpeedAC的博客,向成千上万愿意进入人工智能、机器学习或深度学习的人分享我的知识。我开始写了几篇关于 NNs 的介绍性博客,当然,还有一篇 MNIST 教程。我觉得虽然写一个数据科学或人工智能博客并不太难,而且有一些事情你必须记住。我将与你分享。
我的博客(很棒的 UI,对吧?)
写博客(直觉部分)
对于初学者来说,博客不应该看起来充满了外国词汇和术语。是的,ML 确实有几个可怕的词,然而大多数都意味着惊人的简单事情! 还有,尽量少理论化。我发现人们更有兴趣知道它是如何工作的,然后直接看代码。我特意保留了博客的名字光速以保证趣味性。
另外一个超级重要的事情就是 写你的意思,写你的意思。 如果你的博客标题是零到人工智能英雄,并且你完成了一个 MNIST 教程,那就是完全的点击诱饵!此外,对读者坦诚总是在许多方面有所帮助。
我最后想说的是,一个教一些概念 的 AI 博客,得有代码 !!一个理论性的博客可能更容易写,但是你最终给了他们他们没有办法实现的知识。很明显,代码需要充满注释和解释,因为读者应该能够理解每一行。如果你鼓励读者尝试一些代码行,比如超参数,这总是有帮助的。
一个额外的提示,让你的博客读者友好,是使用语法,以确保没有污点的语法。这比你想象的更重要!我写了一篇关于语法对博客作者的重要性的博客。
写什么?
写一些人们在 之前没有写过的东西总是好的,尽管这并不总是可能的。我知道有成千上万的 MNIST 教程,但我仍然写了另一个。 为什么? 因为我感觉他们都没有我这样的逐行代码注释。还有一次,我写了一篇关于激活函数的博客。同样,我知道有数百个,其中一些是关于数据科学的,内容非常好。然而他们中的大多数人解释了这个功能。另一方面,我做了一个比较,并详细说明了在什么情况下使用什么激活。因此,我写了这本激活功能手册。找到机会并抓住它们!
怎么宣传?
自然,这将是下一个问题。我想这个问题没有明确的答案。我采取了许多不同的方法,并定期检查哪些可行,哪些不可行。
所有博主获取有机流量的地方
我首先尝试的是 Quora 。这有两个故事。我的合著者(实际上是我的兄弟)也在我们的博客中尝试了同样的方法。我们俩几乎是同时开始的。18 天后, 我的 4k 浏览量 越来越多,我的 80 个回答带来了不错的流量,而我的哥哥 面临着被 Quora 封禁两周的处罚。
我在 2 周内获得了 4.1K 的浏览量!
这些截然不同的结果的原因是什么?
我在 Quora 上的回答是真实的,只有不到 40%的人有我博客网站的链接。我保证读者会希望 去我的网站更好地学习。我不是在发垃圾信息,只是在帮忙。
如你所料,我哥哥的邮件是垃圾邮件。
如果问题是“好的博客是什么样子的?”
他会回答“一个好的博客看起来像这个”
图片来自 Shutterstock.com two mine 公司
通过那个故事,我的意思是让你明白 如何从 Quora 获得流量, 和 如何获得封禁。
我做的第二件事,也是更有用的一件事,是发电子邮件。我给很多公司发了邮件,请求合作机会。有些人回答了,有些人没有。但是最好的部分是每个公司给的反馈。而且我说的是 Coursera、Grammarly 甚至 deeplearning.ai 这样的大公司! 这些邮件帮助我显著提高了市场占有率。
并维护它
同样,Paint 女士也给人留下了深刻的印象:)
我定期写博客,比如每两天一次,这有助于提高我的存在感。此外,我 删除了 几个表现不佳的博客,以帮助维持内容质量。
还有,评论
如果你开始写博客,那太好了!下面用链接评论!
免费的任何合作,项目帮助和集成!
如有任何关于 TensorFlow、Keras、TFjS 或 Python 的疑问或项目,请发邮件至我的 Gmail。
谢谢,祝您有美好的一天!
如何开始一个机器学习项目
原文:https://towardsdatascience.com/how-to-start-a-machine-learning-project-5654832cb1ed?source=collection_archive---------30-----------------------
做机器学习项目的分步指南
斯科特·格雷厄姆在 Unsplash 上拍照
在 a 之前的文章中,我们讨论了很多关于什么是机器学习,机器学习是如何工作的,以及机器学习实现的例子。如果你是机器学习的新手,你可能会问,你如何开始一个机器学习项目?
这可能很多人都经历过,包括我。我读了很多书,但仍然不知道从哪里开始。我发现,学习启动机器学习项目的最佳方式是通过设计和完成小项目。因为要做大,我们必须从小做起。但是这个过程因人而异。
在这篇文章中,我将根据我的经验分享从事机器学习项目的几个阶段。
理解问题
照片由优 X 创投在 Unsplash 上拍摄
开始一个项目的最初阶段是知道我们将解决什么问题。这适用于任何项目,包括机器学习项目。当然,一切都从问题开始,因为如果没有问题,就没有什么需要解决的。
我们必须确定我们要解决的问题。例如,我们希望实时了解用户在社交媒体上对某个产品的看法。但是因为存在的很多意见,完全靠人类是不可能做到的。
然后我们也确定目标。由此,我们可以确定目标是创建一个机器学习系统来实时分类用户意见(情感分析)并预测未来意见的情感。
如果你不能解决一个问题,那么有一个更容易的问题你可以解决:找到它乔治·波利亚
建议你学习一下计算思维中的分解,就是把复杂的问题分解成更小的部分的过程。通过分解,起初看起来势不可挡的问题变得更容易管理。
数据采集
米卡·鲍梅斯特在 Unsplash 上的照片
如果你已经找到了一个问题和你想要解决的目标,那么下一步就是获取所需的数据。有许多方法可以收集数据。我将解释其中的一些。
- 第一种方式是在网上下载开源数据如 Kaggle 、 Google dataset 、 UCI 机器学习等。但你也必须注意使用这些数据集的局限性,因为有些数据集只能用于个人需求或仅用于研究目的。
- 接下来的方式就是在网站上做抓取/抓取。比如你想检索社交媒体上仇恨言论评论的数据,可以在社交媒体 Twitter 、 Instagram 等上抓取。或者,如果你需要来自新闻网站的数据,你可以在新闻网站上做网络搜集。
[## 用 Python 实现 4 行新闻的网络抓取
抓取网站的简单方法
towardsdatascience.com](/scraping-a-website-with-4-lines-using-python-200d5c858bb1)
在某些情况下,您可能需要标记数据,特别是如果您通过 web 爬行/抓取获得数据集,并且您将使用的机器学习方法是监督学习。必须考虑的是标注数据时可能出现的偏差。这可能会影响模型的性能。
如果你想验证你标记的数据,你可以向他们领域的专家寻求帮助。例如,如果您在健康领域创建了一个数据集,那么您可以验证您为医生创建的数据。
数据准备
照片由卢克·切瑟在 Unsplash 上拍摄
我们得到需要的数据后,下一步就是在进入训练阶段前准备数据。这是为什么呢?
让我们比较一下作为烹饪材料的数据。我们在烹饪之前,肯定会先对原料进行处理,比如清洗、清洁、去除不必要的成分、切块等。,不可能把原料放进煎锅里。
数据也是如此。我们需要准备数据,以便在进入训练阶段时,数据不包含会影响所创建模型的性能的噪声。
在进一步输入之前,请注意有 2 种类型的数据,即结构化数据和非结构化数据。结构化数据是一种数据模型,它组织数据元素并标准化它们之间的关系。通常,这种类型的数据以表格、JSON 等形式出现。而非结构化数据是没有预定义的数据模型或者没有以预定义的方式组织的信息。这种类型的数据通常是自由文本、图像、信号等形式。
结构化数据与非结构化数据
以下是准备数据时常用的一些流程。
- 数据清理用于消除不需要的数据或特征。对于每种数据类型,处理方式是不同的。在结构化数据中,它用于清除不一致的数据、缺失值或重复值。而在非结构化数据中,例如在文本的情况下,它用于清除在形成模型的过程中实际上不太必要的符号、数字、标点符号或单词。
- 数据转换用于改变数据结构。这对于非结构化数据(例如文本)的情况尤其必要,因为基本上分类器模型不能接受文本输入,所以它必须首先被转换成另一种形式。一些常用的方法有 PCA、LDA、TF-IDF 等。
另一件同样重要的事情是探索性数据分析(EDA)。EDA 的功能是对数据进行初步调查,在统计摘要和图形表示的帮助下发现模式、发现异常、进行假设测试并检查假设。
系统模型化
罗马卡夫在 Unsplash 上拍摄的照片
这可能是你最期待的部分。在这个阶段,我们会做一个机器学习模型。正如我们在上一篇文章中讨论的那样,机器学习有几种方法,即监督学习、非监督学习和强化学习。我们可以根据之前观察到的数据/问题来确定我们采取的方法。
[## 人工智能、机器学习和深度学习——有什么区别?
人工智能、机器学习和深度学习的简单解释以及它们之间的区别
towardsdatascience.com](/artificial-intelligence-machine-learning-and-deep-learning-what-the-difference-8b6367dad790)
我的其他建议是,在建模之前先找出每种机器学习方法的优缺点,因为这样会节省很多时间。对于某些数据特征,每种方法都有优点和缺点。例如,如果首先对输入进行规范化,有些方法可以很好地工作;如果数据太大,有些方法会导致过度拟合;还有一些方法需要非常大的数据。
不要让你花时间去尝试一个又一个的方法来产生最好的结果。因为通常,一个机器学习方法有很多我们可以修改的参数。例如,如果我们想使用神经网络建立一个模型,我们可以改变学习率参数、隐藏层的数量、使用的激活函数等。
也许很多人也建议使用深度学习,因为它在几次实验中一直被证明可以得到很好的结果。但在此之前,先想想案例是否真的需要深度学习。不要用深度学习只是为了跟风。因为需要的成本非常大。
如果有可能使用传统的机器学习方法,那么就使用这种方法。但是,如果案件非常复杂,无法用传统的机器学习方法处理,那么你可以使用深度学习。
评价
万花筒在 Unsplash 上拍摄的照片
最后一个阶段是评估过程。如果你正在训练的模型的性能没有产生好的结果,你当然不希望。尤其是当你的预测模型有很多错误的时候。
来源:https://twitter.com/ipfconline1/status/1261733186087911427
确定我们正在制作的模型是否好的最快方法之一是测量它的性能。有几种方法来计算性能,包括准确性、f1 测量、轮廓得分等。评估你的模型的另一种方法是和他们领域的专家一起验证你的模型。
如何开始一个 NLP 项目
原文:https://towardsdatascience.com/how-to-start-an-nlp-project-f76e3f7d0e61?source=collection_archive---------35-----------------------
NLP 数据集的注意事项和基本探索性数据分析
自然语言处理是人工智能中一个令人兴奋的领域。它的应用非常广泛,从理解情感到主题分析,甚至生成供人类使用的原始文本等等。然而,在开始实施这些分析之前,为了确保项目的成功,必须做一些基本的准备工作。这包括选择要摄取的文本,以及一些必要的单词转换,以使您的文本为进一步的调查做好准备。
快速提示:这是而不是作为主题的 NLP 介绍,或者如何开始一个基本项目。你可以在这里和这里找到开始学习 NLP 的优秀指南。
布拉登·科拉姆在 Unsplash 上拍摄的照片
首先,人们需要决定他们想要分析什么文本。乍一看,这似乎是显而易见的,但是还需要进行一些更精细的技术考虑。对一些人来说,这些问题的答案将是他们想要的结果所必需的。例如,当检查自由文本调查输入时,很明显调查回答将构成您的语料库。在其他情况下,这可能不太明确。
这里有几个有用的术语需要解释。语料库指在分析中检查的文本集合。这个术语可以从一个句子扩展到每种语言中的每个单词。有时,一个语料库可以细分为文档,这些文档是更小的语料库,通常封装了一个想法或主题。文档可以小到一条推文,也可以大到一本书。将一个语料库划分为多个文档并不是每个 NLP 任务都必须的,但是这对于比较不同的文档很有用。NLP 中最小的测量单位是一个令牌。令牌是文档中的一个单词。一个词汇表是语料库中存在的不同标记的数量。一些技术,例如手套单词嵌入,随着词汇量的增加而增加时间复杂度,而其他技术随着更大的语料库而增加复杂度。一个人的用例将决定哪种分析和语料库规模最有意义。
除非你有一个大的计算集群和无限的时间,否则你不可能查看每一条推文。有意义的是选择一个时间段作为你分析的基础。一个人对时间段的选择将基于几个因素:你的时间窗口的大小和它开始的时间。这两个参数都会影响分析中包含的单词/文档的数量。如果不做一些探索性的数据分析,你很可能不知道单词大小随时间的分布,这些数据分析可以揭示随着你增加分析时间,语料库的大小是如何增长的。一旦你知道了语料库的大小是如何增长的,你就能够根据你可用的计算资源做出明智的决定。
我进行了一个样本分析来衡量语料库和词汇的增长。我挖掘了我最喜欢的宠物项目数据集:Reddit。我使用名为 praw 的库从 Reddit API 获取评论。然后我把增长绘制成一系列。下面是我写的一个要点,以跟踪更多帖子的字数。我还包括了在发布时运行代码时输出的图表。
随着更多帖子的添加,测量语料库和词汇增长的示例分析
我们看到语料库呈线性增长,而词汇库呈对数增长
看上面的图表,我们可以看到语料库以大致线性的方式增长,而词汇则以对数的方式增长。利用这些知识,人们现在可以做出明智的决定,在自己的分析中包括多少 Reddit 帖子。进一步分析的一种方法是计算几个不同子社区的这些值,看看哪个社区的词汇最丰富,哪个最冗长。
一旦确定了创建语料库的参数,在开始分析之前还需要进行预处理。原始的自然语言有许多属性会使分析变得模糊不清。常见的第一步是删除停用词;没有提供丰富语义的常用词,反而添加了比信号更多的噪声。大多数 NLP 库都有一个停用词列表,你可以利用它来清理你的语料库。下面是一个使用空间库移除停用词的例子。
用空格删除停止字
这个例子让 spaCy 接收每个评论,然后将评论转换成包含令牌的 pared 文档。对文档进行迭代会产生单独的标记,我们可以检查这些标记,以确定是否应该在分析中考虑它们。上面的要点删除了停用词,但人们也可以轻松地删除数字或进行基本的文本转换,如引理或词干。SpaCy 在第一次解析每个文档时会执行大部分这种分析。下面是 spaCy 提供的令牌属性列表。
另一个常见的步骤是处理文本中的数字数据。一般来说,删除数字是很常见的,因为它们本身通常不提供任何语义。要删除数字和停用词,可以使用正则表达式 (regexes)或大多数 NLP 库中的内置函数。例如,在 spaCy 中,标记具有可以过滤的属性“is_alpha ”,类似于上面要点中的停止词。
但是,您可能希望保留数字的特定上下文。例如,一些数字序列具有特定的含义,如 IP 地址或 MAC 地址。如果数据集包含这样的信息,可以使用掩码用预先确定的标记(如“IP_ADDRESS”)替换数字实体的所有实例。这将保留数字实体的语义,同时移除噪声数字。在这里,简单的正则表达式替换通常是最好的工具。
屏蔽不仅对数字实体有用。它可以用于任何想要保留语法意义而删除特定细节的实体。这样做可以从您的数据中删除个人身份信息(PII),这可能是法律或法规的要求,具体取决于您的数据集。回头看看 Reddit,我将演示用标记“USERNAME”屏蔽用户名。幸运的是,r/help上的一个帖子解释说,用户名可以由 3 到 20 个字符组成,通常以“u/”为前缀在下面的要点中,我使用 python 内置的正则表达式库来查找所有 Reddit 用户名并用我们的令牌替换它们。
使用正则表达式的屏蔽示例
这些步骤将为成功的 NLP 项目奠定基础。有无数的工具和技术可以用来总结,提取意义,或任何数量的其他 NLP 任务。我已经提供了一个笔记本,上面有 gists 中列出的所有代码。
如何开始学习生物信息学而不被吓倒(带 R)
原文:https://towardsdatascience.com/how-to-start-learning-bioinformatics-and-not-get-intimidated-with-r-b4b6a2450212?source=collection_archive---------34-----------------------
使用差异基因表达分析的分步示例
介绍
这篇文章的目标读者是那些希望“闯入”生物信息学领域并拥有 R 经验的人(最好使用 tidyverse )。生物信息学可能是一个听起来很可怕的概念(至少对我来说是这样),因为它是一个如此广阔和快速发展的领域,以至于很难准确定义它是什么。我一直认为生物信息学是一个高度先进的领域,超出了我的能力范围——我需要多年的技术培训才能真正开始做这件事。但是就像所有事情一样,开始做某事实际上并不需要太多时间(不用说,掌握某事确实需要很多年)。
承认我过于简单化,生物信息学本质上是回答生物学问题的电子(或基于数据的)方法。随着更先进的测序技术的出现以及随之而来的统计算法的发展,我们现在可以以前所未有的规模和价格获得生物数据,以及从这些数据中提取洞察力的工具。
在这篇文章中,我的目标是提供一个简单的例子,任何喜欢数据、喜欢与 R 一起工作、对这个领域感兴趣的人,都可以开始在生物信息学领域进行分析。
有大量不同类型的问题和不同类型的生物数据,因此在这篇文章中,我们将使用 RNA-Seq 数据进行差异基因表达分析(DGEA)。简而言之,如果你回忆一下高中/大学生物课,DGEA 会回答不同实验条件下基因表达水平是否有变化的问题,RNA-Seq(RNA 测序的缩写)使用下一代测序来量化给定转录组(所有 RNA 转录本的集合)中的 RNA 数量。我们将从 记录 2 中获取数据。本质上是一个由约翰霍普金斯维护的数据库,通过他们的包与 R 接口,用户可以从中查询 RNA-seq read count 数据。计数是与基因的特定区域对齐的测序读数的数量。
请注意,这篇文章是针对初学者的,所以关于 DGEA 内部某些分析步骤背后的动机或关于软件包所有功能的许多细节将不包括在内。但是,我希望一旦你能够成功地做某事,你会感到有力量去学习更多!
设置
因此,让我们首先设置我们的工作空间,包括将我们的库和 RNA-Seq 数据加载到 R 中,这是我们从 retrol 查询的。鉴于我的学术兴趣,我将使用与冠状动脉疾病相关的 RNA-Seq 数据集。在这个特定的数据集中,病例指的是带有 TCF21 基因沉默的冠状动脉平滑肌细胞。retrol 附带一个漂亮的闪亮的应用程序用户界面,在这里你可以搜索你感兴趣的项目,并使用相关的项目 ID 查询数据;但是,在重新计数包中也有一些功能,允许您在不使用应用程序界面的情况下搜索项目。
对于大多数数据分析项目,我喜欢考虑 3 个主要步骤:探索性数据分析、分析和可视化。在我们开始之前,重要的是要注意我已经选择使用 DESeq2 进行这个分析,尽管存在其他使用不同方法进行 DGEA 的包。我们首先必须构建一个用于我们分析的 DESeqDataSet 对象。这个对象基本上包含三个部分:colData
包含样本信息,rowRanges
包含基因组范围信息,assay
包含计数矩阵。
图片作者。
我们使用dds <- DESeq2::DESeqDataSet(rse_gene, design = ~ case)
来生成我们的 DESeqDataSet 对象,其中case
指定样本是控制样本还是实验样本。让我们通过做一些探索性的数字来弄脏我们的手。
探索性数据分析
首先,我们可以使用欧几里得距离来评估样本之间的总体相似性。这背后的细节就不在本文讨论了。重要的是澄清计数将仅出于探索目的进行转换。转换的目的是使数据更具同质性,以帮助探索(使用的特定转换是方差稳定转换,其细节可在本文中找到)。否则,对于统计分析,应使用原始计数。这是生成距离热图的附带代码。
蓝色阴影越深,一对样本彼此越相似。图片作者。
另一种评估样品间相似性的方法是使用主成分分析(PCA)图。不需要太多的细节,它本质上是一个图,其中 x 轴解释了所有样本之间的大部分差异,y 轴解释了所有样本之间的第二大差异。请注意,这些百分比加起来并不等于 100%,因为有更多的维度包含剩余方差(尽管这些剩余维度中的每一个都比我们看到的两个解释得少)。
观察 PC1 如何很好地分离病例和对照样本。这表明某些基因的表达是不同的。图片作者。
差异表达分析
现在我们已经可视化了我们的数据,让我们运行分析。我们正在使用的软件包使它变得非常简单;我们只要跑dds <- DESeq(dds)
。通过使用 R: ?DESe
中的 help 命令,您可以看到它做了更多的事情,但简单来说,它做了三件事:估计大小因子(控制样本测序深度的差异,但现在不要太担心这意味着什么),估计每个基因的分散值(同样不打算进入技术细节,将分散视为“扩散”的度量),以及拟合一个通用的线性模型。如果这些话对你没有意义,没关系。我的哲学是先做,后问,我知道这可能很有争议,但我认为学生经常会陷入所有的理论和技术细节(其中有许多需要真正掌握和理解)中,以至于他们永远不会进步到事情的实际方面。
数据帧中返回的每个基因有两个主要估计值:baseMean
,归一化计数值的平均值除以大小因子,以及log2FoldChange
,效应大小估计值。例如,log2 倍变化 2 意味着基因的表达增加了 2 =4 的倍数。 DESeq2 对每个基因执行假设检验以查看是否有足够的证据来反对无效假设,即处理对基因没有影响,并且处理和控制之间的观察差异仅仅是由实验可变性引起的。
请注意,由于 TCF21 在 10%的 FDR 水平沉默,有许多基因存在差异表达。
形象化
我们可以做的一件有用的事情是可视化模型中所有基因的估计系数的分布。我们可以使用 MA 图。特定比较的 log2 倍变化(LFC)绘制在 y 轴上,通过大小因子标准化的计数平均值显示在 x 轴上。每个基因用一个点表示。在制作 MA 图之前,我们使用 lfcShrink 函数收缩 log2 倍变化,用于病例与对照的比较。 DESeq2 中有三种类型的收缩估计器,在 DESeq2 简介中有所介绍。我们将使用 apeglm 方法来收缩系数,这有利于收缩有噪声的 LFC 估计,同时为真正的大差异提供低偏差 LFC 估计。
y=0 以上的蓝点显示显著上调的基因,而 y=0 以下的蓝点显示显著下调的基因。前 10 个最显著的差异表达基因被标记。图片作者。
对 p 值直方图执行诊断也是一种很好的做法。这篇文章很好地解释了这一点。
res_shrink %>%
filter(baseMean > 1) %>%
ggplot(aes(x = pvalue)) +
geom_histogram(col = "white")
这是一个正常的直方图,峰值在 0 附近,表示差异表达基因的富集。没有迹象表明任何东西是时髦的!图片作者。
结论
那么我们完成了什么?我们进行了第一次差异基因表达分析,我们确定了一些当 TCF21 基因在冠状动脉肌细胞中沉默时上调/下调的候选基因!很酷,对吧?
使用差异表达分析,您可以做更多的事情。我几乎没有触及表面。如果你想更深入地了解,我推荐你看看这篇短文,或者谷歌一下“差异基因表达 R ”,然后进入兔子洞。希望这篇文章能够证明,开始一件全新的事情不应该是一个可怕的折磨,并提醒你,你总是要从某个地方开始。然而,只要有足够的兴趣和动力,一旦你开始,你很快就会搜索你不明白的东西或者需要了解更多的东西,你就会走上精通的道路!
如何从 AI 入手?
原文:https://towardsdatascience.com/how-to-start-with-ai-dont-start-with-ai-d125a3c20a1a?source=collection_archive---------69-----------------------
不要从 AI 开始
许多公司希望从“人工智能”开始,尽管这听起来像是一个好主意,但出于营销目的,为了让从人工智能中产生商业价值,我推荐一种不同的方法。假设您有可用的数据,您想开始使用这些数据为您的公司造福。你是做什么的?不要从一个随机的机器学习项目开始,而是考虑先做这个。
照片由乔恩·泰森在 Unsplash 拍摄
尽管这个流行词可能已经存在了一段时间,但这个话题对你的公司来说可能是一个新话题。大家可能还不了解 AI(AI 素养),大概有印象就是神奇。一个好的开始方式是让他们熟悉在日常业务中使用数据,使用一些“简单”但非常 重要的数据科学。关于你问的?这里有几个步骤可以遵循。
#1 了解公司的战略
贵公司的关键战略重点领域是什么?他们与战略相关的KPI是什么?查看年度报告、内部门户网站或与您的经理交谈,人们在走廊上谈论的话题是什么?也许你的公司想成长为某个客户群,或者有节约成本的压力。
#2 选择一些话题
现在你已经对你的战略和 KPI 有了深入的了解,选择 3-5 个主题,你可以进一步研究。您可以根据您知道哪里有可用的数据、您在组织中哪里有网络或者人们实际上坐在办公室附近的地方来选择它们。例如,选择与销售和营销相关的主题,其中大多数数据应该可以从您的 CRM 解决方案中获得。
#3 探索性数据分析
现在记住这些话题,开始你的探索性数据分析。针对每个主题,写下 5-10 个问题,你可以询问数据并找到这些问题的答案。问题的例子可以是
- 有多少顾客拥有不止一种产品?
- 销售/营销人员主动接触了多少这样的客户?
现在还不需要任何花哨的东西,一个又快又脏的 Jupyter 笔记本就可以了。
#4 创造可行的见解
现在,针对每个问题浏览一遍你的 EDA,写下你的利益相关者可能感兴趣的五个可操作的点。例如,您发现某个客户群 A 中的销售人员主动接触的客户购买了多种产品。对于另一个客户群 B,营销是成功追加销售不同产品的关键。
可操作的见解是销售应关注客户群 A 进行交叉销售,营销应关注客户群 B 进行追加销售。
#5 出版
你可以用一个你的管理层能够理解的形象化的东西来支持这些信息。以适合贵公司的格式发布。在哪里?你的观众是谁?
发布你的读者在哪里,以获得正确的牵引力。
有内部通讯吗?人们使用松弛渠道吗?或许把它挂在咖啡区的打印输出上?
#6 沟通,沟通,沟通
现在仅仅出版是不够的。与你的利益相关者沟通,安排一次会议,在午休时谈论它,等等。确保人们多次看到这些见解并鼓励他们采取行动。一旦他们从你的见解中看到了价值,他们会回来索取更多。
你会看到,可行的见解以人们能够理解的方式展示了数据科学的价值。一旦他们这样做了,他们会回来要更多。
你对如何进入 AI 有具体的问题吗?通过 https://aibridge.ch/contact/联系我。
关于我:我是一名分析顾问,也是当地一所商学院“人工智能管理”研究的主任。我的使命是帮助组织利用人工智能创造商业价值,并创造一个数据科学家可以茁壮成长的环境。 报名我的 简讯 这里有关于 AI 管理的新文章、见解和供品。
如何开始写数据科学博客?
原文:https://towardsdatascience.com/how-to-start-writing-data-science-blogs-73bc55f59169?source=collection_archive---------13-----------------------
想在数据科学上写博客吗?这是给你的。
由 Serghei Trofimov 在 Unsplash 拍摄的照片
当我们想到写博客时,我们大多数人都被写完美的文章来吸引眼球的想法淹没了,对你来说没有足够的知识,缺乏一致性或找到正确的受众。
失败的理由可以有 100 个,但成功的理由有 1 个就够了!
我第一次听说科技博客是在 2016 年的一次会议上。我对把你的想法告诉人们的想法很感兴趣。我最初开始在 WordPress 上写博客——关于我的日子、感受、希望、成就的故事(这很容易)。在最初的三个月里,我有相当不错的收视率,达到了 500 次。然而,我不太喜欢这个过程,于是开始探索 Blogger、Ghost.org、Tumblr 等等。
2017 年,我正在学习用户体验设计的概念,并偶然发现了这个名为 Medium 的平台,在这里我可以找到大量关于技术和个人发展的任何主题的文章——从加密货币到领导力,从数学到迷幻药,Medium 是我的地盘!
我开始阅读大量文章,发现媒体是作家和读者的最佳平台之一。有了 Medium 的政策,基本上,任何有有趣的东西可写的人都可以成为作家。2017 年 7 月 13 日,我在 Medium 上写了我的第一篇文章UX 可用性的销售预测。
虽然我写这篇文章主要是出于实验目的,但当我第一次鼓掌时,我获得的满足感鼓励我继续写作。
我花了一年多的时间来弄清楚媒体上的故事是如何工作的,什么是出版物,如何让更多的观众参与内容,因此从 2019 年 1 月 16 日开始了我作为全职科技博客作者的旅程,没有回头。我有了第一个 1K+浏览量的故事😀
博客对数据科学的优势
有许多初级、中级和专家级的爱好者通过博客与社区分享他们的知识和学习。那么是什么促使他们写作呢?
1.学习和分享
我一直相信学习、探索、体验、分享、重复。
我不断受到激励,致力于具有挑战性的数据科学项目或概念,从而提高我的数据技能。在数据科学博客中,你可以参与到间接指导中。当有人阅读你的博客时,他们从中学习,执行,并对阅读你的内容感到满意。你可能永远不会亲自认识那个人,但是鼓舞人心、教导别人的想法让我很兴奋去付出!
2.建立您的个人资料
博客无疑是你展示数据科学知识和技能的最聪明的手段之一。
在媒体上发表的每一篇文章都可以被视为知识产权——独一无二、独一无二、不可替代。你完全可以在简历中加入这个链接。
当你写作时,你被认为是一个了解数据科学的人,也许不是专家,但阅读你博客的人会把你和你写的东西联系起来。当人们阅读你的内容时,他们从那个角度看你;这对建立你作为数据科学家的品牌来说是一件好事。
对我来说,写数据科学是向世界展示我的能力的一种方式,同时它也是我的一份无声简历!
3.全球风险
媒体上的文章被全球社区阅读。您有机会与全球读者分享您的专业知识、知识、学习成果和经验。当你收到来自世界各地的评论、电子邮件、Twitter 或 LinkedIn DMs 时,那种喜悦是无与伦比的。
4.发展软技能
如果写 1000 到 1500 字的文章不能提高你的沟通技巧,那会怎样呢?写博客,将反馈考虑在内,能让你以一种普通大众能理解的方式传达信息。
如果你不能用简单的术语向某人解释某事,那么这意味着你没有很好地理解这个概念。
当有人向我伸出手,说他们喜欢我解释概念的简单易懂的方式时,这就是博客作者的梦想!
5.向自己介绍大量的机会
当你在 Medium 上写博客时,它为你建立了可信度,同时你的作品会立即为全世界所知。任何人搜索你或谷歌搜索一些关键词,看到你的个人资料,都会看到你所做的工作。
在我写博客的最初几天,我主要写的是用户体验设计。一位来自德国的 UX 设计师在 Twitter 上看到了我的博客,他想知道我是否有兴趣为他们的博客写付费文章。很多人想为付费博客写作,但他们没有作品集可以展示。当机会出现时,你的文章将成为你的简历。
到目前为止,在我的旅程中,我已经有过多次机会从事独立的付费项目,免费参加会议,为一个出版物撰写客座博客。
6.赚钱💰
你知道吗,你可以从你的文章中赚钱(甚至每月约 1000 美元)。通过 Medium Partner 计划,任何在 Medium 上发表文章的人都可以获得赚钱的资格。接下来,这取决于你的文章对观众的吸引力有多大。
该过程
1.选择您的域
即使在数据科学领域,也有很多事情可以写博客。
- 数据科学概念-决策树、随机森林、SVM、kNN、聚类、NLP、深度学习、人工智能等等…
- 数据科学的统计和数学
- 项目—数据清理、数据争论、数据
- 数据分析
- 数据可视化
- 关于数据科学的研究(令人惊讶的验证)
- 一般主题—软件、工具、新闻、编程语言、技能
- 比较—工作角色、库、功能
- 教程
- 案例分析等…
这些是你可以为你的第一个数据科学博客选择的一些主题。
2.研究
如果你想到一个特定的主题,互联网上有大量的文章可能与你想到的标题相同。不只是中等,但你需要注意你的内容不要复制网络上的任何其他文章,至少要试着这样做。
写博客的核心是提供价值。如果你没有教一个人一些以前没有告诉过的东西,读者可能会从你的博客上反弹并接近一个不归路。
特别是在数据科学方面,假设你决定写一篇关于 Random Forest 的文章,在谷歌上大约有 611,000,000 个搜索结果。你的目标是独一无二,用通俗易懂的方式解释概念,迎合更广泛的受众,用优质的内容在谷歌搜索上排名靠前。
我的建议是研究所有与你感兴趣的话题相关的现有内容,做笔记,勾画出你想写的内容的大纲。你读得越多,你对内容就越清楚。
3.了解你的观众
在发布博客之前,一个很好的建议是了解你的受众是什么类型的——初学者、中级、专家。验证你写的东西会被消费是非常重要的。
最初,我常常向一个出版物投稿,即使我会认为这是一部值得骄傲的作品,也不会有很多人阅读。问题:文章写得太超前了,出于某种原因,与读者无关。后来,我不得不停止向那份刊物投稿。
阅读围绕你的主题发表的其他博客,检查内容!
4.提交给出版物
媒体上的出版物是围绕一个共同主题或话题撰写的故事的共享空间。出版物正在寻找作家提出最新和相关的内容,重点是数据科学,机器学习,人工智能,编程等等。
每个出版物都有被接受的指导原则——这意味着如果你的内容质量不够好,或者不符合指导原则,它就不会被出版。提交前请务必阅读指南。
一旦你被接受,一份出版物能让你接触到更广泛的读者,赚更多的钱,得到诚实的反馈。
对于数据科学,您可以将您的文章提交到
- 走向数据科学
- 走向艾
- 变成人类
- ML 审查
5.监控您的指标
我认为这是最大的学习工具——记录你的观点和阅读。你发表的每个故事,都有一个详细的相关统计数据,告诉你你在不同平台上的读者群。
你能得到的最好的反馈是密切监视你的统计数据。有些博客可能会有超过 20 万的浏览量,而有些博客可能仅限于 3K 的浏览量。这就是你自省的时候,发现什么有用,什么没用。仔细阅读关于你的故事的回复:从显示错别字到赞赏吨——回复反映了用户的观点。
然后还有个叫读比的东西。你不仅希望读者看到你的博客,而且希望他们阅读你的博客。一篇阅读时间为 5-7 分钟的文章或故事的中等阅读率在 40% - 70%之间。影响媒介阅读率的因素是你的媒介文章的流量来源和阅读时间。
clickbait 标题的粉丝会围绕阅读率大做文章。但还是那句话,这取决于你写博客的目的。
6.要耐心
忍耐是痛苦的,但它的果实是甜蜜的
增加博客流量的关键是:要有耐心。写博客的成功不会裹着漂亮的蝴蝶结出现在门口。这需要大量的艰苦工作和极大的耐心。优步博主 Chris Brogan 有一句名言,他花了三年时间才吸引了第一批 100 名博客订户。毕竟,不是每个人都能像贾斯汀比伯那样一夜成名😛
- 专注于创造尽可能好的内容;非常棒的内容
- 做你自己——让这成为你的“竞争优势”
- 写作前后一致
- 优雅地对待批评——这是领导者的标志
- 偶尔在你写的东西中冒险。试新失败也没关系!
- 不要害怕。即使你不确定它是否“完美”,也要发表它
感谢您的阅读!我希望你喜欢这篇文章,并从此刻开始用思维导图来写博客。一定要让我知道在你的数据科学博客之旅中什么让你兴奋。
快乐数据 Tenting!
免责声明:本文表达的观点仅代表我个人,不代表严格的观点。
了解你的作者
拉什是芝加哥伊利诺伊大学的研究生。她喜欢将数据可视化,并创造有见地的故事。当她不赶着赶学校的最后期限时,她喜欢喝一杯热巧克力,写一些关于技术、UX 等的东西。
如何开始你的机器学习生涯?
原文:https://towardsdatascience.com/how-to-start-your-machine-learning-career-e704f0a548de?source=collection_archive---------52-----------------------
不,它不仅仅是一个大学学位。你变得越好,就越受关注。那么如何开始呢?
伊恩·施耐德在 Unsplash 上拍摄的照片
简介
如今,许多公司都在寻找拥有高水平技术知识的人。即使你被录用了,你也需要不断进步,跟上时代。这是一个常见的过程。
嗯,这是你可以采取的第一个明智的步骤:你需要成为任何公司的一个有价值的资源,而不是一个普通的员工。让我们一起深入了解机器学习的基本核心概念。
你已经知道多少了?
与所有其他人相比,你处于什么位置?你已经知道多少了?你的弱点是什么?强壮的?在进行下一步之前,你需要先了解自己。
即使你有学位也没关系,你知道在你的领域里什么是最重要的吗?以下是一些需要回答的问题:
- 你知道统计与概率吗?多少钱?
- 你用什么语言或者你将开始学习什么语言?Python,R,Scala,Julia…?现在有更多的开始发光。
- 关于所需的库,你有好的背景还是需要马上开始?
- 你要学多少时间?你预计什么时候开始实地工作?你每月能付多少钱来学习?
把你所有的答案写在一个你需要的时候可以快速拿到的地方。
从哪里开始学?
当我开始穿越数据科学领域时,我发现自己迷失了。要学的东西太多了,多种不同的资源——注意——质量差。对我来说,仅仅抛出一堆能帮到你的链接真的很容易,但也许这还不够。我甚至不能注意到你已经知道了多少,那没有意义!
为了达到最好的效果,你需要自己潜水。如果你从未涉足统计学领域,现在是时候了,我将帮助你。数据科学和机器学习也是如此。
Alex Ambedo 在 Unsplash 上拍摄的照片
1)统计和概率
两者都被称为你需要了解的入门领域。你将潜入人工智能海洋的浅水区,稍后能够理解更高级的概念。开始不需要知道太多,基本就行。让我们看看“基础”是什么意思:
- 集中趋势的度量:均值、众数、中位数;
- 价差度量:极差、四分位、方差、标准差;
- 此外,这是一个很好的方法来了解:z 分数,贝叶斯概率,四分位间距等。
有了以上这些东西,你就能:
- 能够发现数据中的异常值以及何时删除它们;
- 对你的数据集有深入的分析;
- 对数据清理和特征工程有一个初步的了解;
但是在哪里可以学习统计和概率呢?
可汗学院提供了关于那个领域的非常好的材料。你首先要了解每一个单词的意思,然后在练习中运用你的新知识。
就那些内容?为什么?
我是一名教师,自 2014 年以来一直与青少年一起表演。我的教学方式真的很简单:边做边学。仅仅通过阅读书籍或观看视频,你什么也学不到,这可能会有所帮助,但你只能通过将你所学的内容融入到你的大脑中来保存这些知识。所以从最基本的开始。
2)数据科学
另一个提示:开始学习数据科学,将统计学和概率结合在一起。两者高度相关,您今天所学的内容肯定可以应用到数据科学中。
数据科学是一个很大的领域。在开始考虑机器学习之前,你需要学习如何获取数据、清理、修改、改进和可视化数据。你有一堆包含多个函数的库,所以有很多工作要做。让我们来看看基本情况:
图书馆:
- 熊猫;
- Numpy
- Matplotlib
- Seaborn(可选)
需要学习的内容:
- 数据清理和扯皮;(熊猫)
- 特征工程;(Numpy)
- 数据可视化;(Matplotlib)
他们已经准备好了,从熊猫图书馆开始,继续。默认情况下,Pandas 库将提供使用 Numpy 所需的所有重要概念,这将扩展您使用 Matplotlib 的查看能力。
你可以从哪里开始学习数据科学?
Coursera 是这里最好的选择!即使你不能获得专业证书,你仍然可以旁听任何你想旁听的课程,这意味着什么?你可以从世界上最著名的大学学到任何东西!
创建您的帐户后,您将能够审核斯坦福、约翰霍普金斯、密歇根、阿姆斯特丹等大学的课程。免费的!点击此处查看可用课程。
重要的是要知道:每门课程将引导你通过一个统计学和概率的介绍性视野,这可能很容易,也可能非常难,选择好。
摇滚猴子在 Unsplash 上的照片
3)机器学习
有了良好的数据科学背景和良好的统计和概率知识,您就可以开始学习机器学习了!一如既往,从小处着手。当我们谈论这个领域时,线性回归是介绍性的算法。
有一堆指南旨在教你机器学习模型是什么样子的,所以我们不需要在这里深入研究。
在分层模型中,它看起来像这样:
监督学习
- 回归;
- 分类;
无监督学习
- 聚类;
更多学习内容
- 降维;
- 特征选择;
- 模型调整和评估;
我已经删除了一些核心概念,如迁移学习,因为它可以在深度学习中更愉快。不要忘记,随着机器学习,一个新的 Python 库出现了: Scikit-learn 。您可以从头开始创建任何算法,并在了解其工作原理后,从该库中正确地实现它。
此外,在机器学习领域,我们有深度学习,但我将把它留给另一篇文章。不要误解我,也许你正在阅读这篇文章,但如果没有之前对机器学习核心概念的强大知识,现在没有理由学习深度学习。专注于现在重要的事情。
你可以从哪里开始学习机器学习?
Coursera ,又来了!事实上,如果你按照我在数据科学一节中的说明去做,你肯定会学到一些机器学习的知识。你只需要集中精力,开始在 Coursera 上搜索相关课程。
但如果出于某种原因,你正在努力理解大学的艰深语言,YouTube 上有一些更简单的地方可以提供同等质量的内容,看看吧:
- send ex 关于机器学习的播放列表
- Edureka!机器学习全程(10 小时)
好了,现在你已经有了你需要理解的所有基本概念,并且知道在哪里可以得到你需要的材料,你只需要开始学习!祝你学习顺利。
图片来自 Giphy
当我开始的时候,我很难理解,这就是为什么我决定分享我做过的最好的指南,让你的事情变得更容易。请记住,本指南并没有涵盖你在学习过程中的所有基本需求,但我很确定这些问题会在学习过程中得到解决。这就是你学习的目的,解决问题!
[## 雷南·洛利科-吉图布
在 GitHub 上注册你自己的个人资料,这是托管代码、管理项目和构建软件的最佳地方…
github.com](https://github.com/renfelo)
如何在不牺牲数据的情况下保持在自由层云数据库行限制内
原文:https://towardsdatascience.com/how-to-stay-within-free-tier-cloud-database-row-limits-without-sacrificing-data-27f07b5110b0?source=collection_archive---------76-----------------------
通过仅托管小型汇总表并在本地硬盘上保留精细的历史表,节省资金并改善用户体验
免责声明:这些建议是针对涉及几 GB 数据的低风险项目的。如果你在处理“大数据”,你只能靠自己
如果您正在处理一个需要托管数据库的项目,您可能会担心您会很快超出免费/低成本计划的行限制。即使每月只需花费 9 美元就可以存储 100 倍多的行,这对您来说也不值得,尤其是如果您的项目不会产生收入的话。你可能认为是时候开始删除那些带给你最少快乐的记录了…
但是等等!你可能已经有了另一个免费存储数据的地方,就在你的指尖——你的本地硬盘。
在这一点上,你可能会担心我不知道我在说什么。你不会尝试使用本地数据库来运行一个网站。如果你的猫在你的笔记本电脑上摩擦它的头,并且不小心关上了它或者断网了,你的网站将会变得毫无用处。
我并不是建议你完全替换你的云数据库——只是使用本地数据库来补充它。将详细的历史数据保存在您的计算机上,只在云上托管较小的汇总表。通过这种方式,您的用户仍然可以登录、查看聚合数据、订阅电子邮件(所有这些好的数据库相关的东西),并且如果您以后需要,您将拥有所有旧的/高粒度的数据。
在我的例子中,我制作了一个 web scraper 来收集喜剧场所网站上的表演信息,并使用这些数据在我自己的网站上显示一些统计数据。我平均每天收集 300 行数据(该场所网站上列出的每个节目的每个喜剧演员一行),如果我继续将结果附加到我的表中,这将在一个多月的时间里超过 Heroku 的 10K“hobby-dev”等级行限制。
我只需要向用户显示聚合的历史数据(这个喜剧演员做了多少节目?他们最后一次表演是什么时候?等。)和详细的未来数据(该喜剧演员将很快出现在哪些具体的节目中?还有哪些喜剧演员会出席那场演出?).但是,我并不只是想把详细的史料丢掉。如果我的代码中有一个错误导致了不准确的聚合,我希望有旧的数据,这样我就可以重新生成聚合。更详细的数据可以方便地用于未来的预测建模。
我的表结构如下所示(在大约一年半的数据收集之后,行数为 6/28/20):
紫色的表在 Heroku 上,但是我也保留了本地的备份。完整的历史存储在 fact_shows 表中,该表用于生成较小的表。 Fact_shows 显然超过了行限制,但 Heroku 主持的桌子现在每个只有几百行(注意: dim_upcoming_shows 现在是空的,因为场地因 COVID 限制而关闭)。所有这些表格总共占用了我硬盘上 47MB 的空间。
我的 scraper 每天晚上在本地运行,并将数据附加到 fact_shows 中,如下所示:
在更新了 fact_shows 之后,我生成了 dim 表。我定义了这个通用的 update_dim_table 函数,以避免为我想要创建的每个 dim 表重复代码。它需要表名和查询,以便能够汇总来自 fact_shows 的数据,然后将汇总的表写入本地数据库和(可选)Heroku。
下面是我如何应用该函数创建 dim_comedian_stats 表的示例,该表被写入 Heroku,因为我需要它在我的站点上进行可视化:
更多上下文,完整的 scraper/ fact_shows 文件是这里是,而 dim 表格脚本是这里是。
根据您的特定用例,您可能无法聚合数据。如果您的用户需要深入了解细节,可以考虑其他方法来减少托管数据,比如只显示最近 30 天的数据(同时在您的笔记本电脑上保留更长的历史记录)。总的原则是保持理想的表结构,将全部历史存储在本地,然后计算出满足用户需求所需的最低限度,只将那个小表推送到您的云服务。除了省钱之外,这还可以改善用户体验,因为网站查询是针对更小的表进行的,所以大家都赢了!
Raspberry Pi 上的实时视频对象检测
原文:https://towardsdatascience.com/how-to-stream-video-with-real-time-object-detection-on-raspberry-pi-f6503c46c7f9?source=collection_archive---------7-----------------------
使用 OpenCV、专用硬件和云技术实现快速检测
最近,一段来自特斯拉 autopilot view 的视频出现在互联网上,并非常受欢迎。我对一个类似的视频流(带有检测到的物体)很感兴趣,这个演示最终让我做了一些工作。
唯一的问题是我想从 Raspberry Pi 流视频,但总的来说,它不够强大,无法执行这样的任务。
检测到物体的图像
树莓上的 OpenCV
最直接的实现是通过 OpenCV-DNN 在 Raspberry Pi 上运行一个检测器。
OpenCV-DNN 支持多种网络和格式,但我以前用的是 Google 的MobileSSD(11 _ 06 _ 2017 版本,最新的不兼容 OpenCV 4.2)。
首先,读取类名并加载模型:
tf_labels.initLabels(dnn_conf.DNN_LABELS_PATH)net = cv.dnn.readNetFromTensorflow(dnn_conf.DNN_PATH, dnn_conf.DNN_TXT_PATH)
然后对一个图像运行推理:def 推理(img):
net . set input(cv . dnn . blobfromimage(img,1.0/127.5,(300,300),(127.5,127.5,127.5),swapRB=True,crop = False))
return net . forward()
这个操作在树莓上需要 1.7 秒。例如,我的漂亮的旧笔记本电脑在 0.2 秒内完成同样的工作。
将输出张量转换为人类友好的 JSON:
def build_detection(data, thr, rows, cols):
ret = []
for detection in data[0,0,:,:]:
score = float(detection[2])
if score > thr:
cls = int(detection[1])
a = {"class" : cls, "name" : tf_labels.getLabel(cls), "score" : score}
a["x"] = int(detection[3] * cols)
a["y"] = int(detection[4] * rows)
a["w"] = int(detection[5] * cols ) - a["x"] a["h"] = int(detection[6] * rows) - a["y"]
ret.append(a)
return ret
考虑到测量,很明显原生树莓性能(1.7 秒)对于任何视频都是不够的。
但是让 Raspberry 与笔记本电脑配合使用应该会提高处理帧的整体能力。
笔记本电脑原型
现在用一个 REST 接口把检测器包起来。
为此,我通常使用烧瓶。获得服务有两个切入点:
- 第一个返回 JSON 中的检测
- 第二个返回带有检测到的矩形和标签的图像
第二种方法给出了检测结果,简单明了:
curl -X POST -F "file=@pic.jpg" [h](http://192.168.1.243/)ost:80/ddetect --output a.jpg
码头工人
我们想要一个可扩展和可移植的解决方案,然后将服务打包到 docker 映像中。
选择 Debian Stretch + Python 作为基础映像,保留与 Raspbian 类似的堆栈。
需要设置 flask,protobuf,requests,opencv_python,从 GitHub 下载移动 SSD 和服务器代码。
FROM python:3.7-stretchRUN pip3 install flask
RUN pip3 install protobuf
RUN pip3 install requests
RUN pip3 install opencv_pythonADD [http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_coco_11_06_2017.tar.gz](http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_coco_11_06_2017.tar.gz) /
RUN tar -xvf /ssd_mobilenet_v1_coco_11_06_2017.tar.gzADD [https://github.com/tprlab/docker-detect/archive/master.zip](https://github.com/tprlab/docker-detect/archive/master.zip) /
RUN unzip /master.zipEXPOSE 80CMD ["python3", "/docker-detect-master/detect-app/app.py"]
为了与第三方提供商一起使用该图像,需要将其发布到一些公共 docker 注册表上。
我决定用传统的方式使用 Docker Hub。
- 创建一个帐户
- 使用 DockerHub: docker 登录授权本地 docker
- 给图像命名: docker 标签
TPR lab/opencv-detect-SSD - 上传图片: docker 推送 tprlab/opencv-detect-ssd
现在,该映像可以用于许多容器提供商,如 Google Cloud、Microsoft Azure、Amazon Web Services、Digital Ocean、Heroku 等。
录像
使用 OpenCV 示例,制作一个基本服务器:
def handle_frame(frame):
return detect.detect_draw_img(frame)
def generate():
while True:
rc, frame = vs.read()
outFrame = handle_frame(frame)
if outFrame is None:
(rc, outFrame) = cv.imencode(".jpg", frame)
yield(b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' + bytearray(outFrame) + b'\r\n')[@app](http://twitter.com/app).route("/stream")
def video_feed():
return Response(generate(), mimetype = "multipart/x-mixed-replace; boundary=frame")
随着 docker 部署在笔记本电脑上,视频以慢动作播放。
谷歌云
到目前为止,单个码头工人是不够的。让它伸缩——在这种情况下,我们将能够同时处理多个帧。
我选择 GCloud 作为 Kubernetes 的服务提供商,并在 5 个实例中运行我的映像。
服务器代码变得更加复杂:
def generate():
while True:
rc, frame = vs.read()
if frame is not None:
future = executor.submit(handle_frame, (frame.copy()))
Q.append(future)
keep_polling = len(Q) > 0
while(keep_polling):
top = Q[0]
if top.done():
outFrame = top.result()
Q.popleft()
if outFrame:
print("Frame", datetime.datetime.now())
yield(b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' + bytearray(outFrame) + b'\r\n')
keep_polling = len(Q) > 0
else:
keep_polling = len(Q) >= M
这种方法有助于以大约 10 fps 的速度传输检测到的视频。
还有提高速度的空间——只需在我们的 Kubernetes 集群中添加更多节点。
英特尔神经计算棒
在进行了远程检测实验后,我决定尝试本地硬件解决方案。
我有一台英特尔 NCS,已经在类似任务中使用过。
所以我把 MobileSSD 转换成 OpenVino 格式,用 NCS 检测器运行视频流。
NCS 很好地完成了这项工作——FPS 略高于 10,优于 5 节点 Kubernetes 集群。
结论
最终,使用外部电源进行接近实时的检测被证明是可能的。
使用 NCS 是最简单(也是最便宜)的方法——一次性购买,用最简单的代码工作很长时间。
docker 方式更复杂,但也更具可伸缩性、可移植性和可重用性。
链接
- 带有 docker 文件和源代码的 GitHub repo
- Docker Hub 上准备就绪的 docker 图像
如何用 Python 为 Excel 增压
原文:https://towardsdatascience.com/how-to-supercharge-excel-with-python-726b0f8e22c2?source=collection_archive---------0-----------------------
如何用 xlwings 集成 Python 和 Excel
由 Unsplash 上的émile Perron拍摄的照片
Excel 既是一种祝福,也是一种诅咒。当谈到足够小的数据和足够简单的操作时 Excel 是王者。然而,一旦你发现自己在那些区域之外努力,它就变成了一种痛苦。当然,你可以使用 Excel VBA 来解决这些问题,但是在 2020 年,你可以感谢你的幸运星,因为你不需要这么做!
如果有一种方法能把 Excel 和 Python 集成在一起,给 Excel 插上翅膀就好了!现在有了。一个名为 xlwings 的 python 库允许你通过 VBA 调用 Python 脚本,并在两者之间传递数据。
为什么要集成 Python 和 Excel VBA?
事实是,在 VBA 你几乎可以做任何事情。那么,如果是这样的话,为什么要使用 Python 呢?嗯,有很多原因。
- 您可以在 Excel 中创建自定义函数,而无需学习 VBA(如果您还不知道的话)
- 您的用户可以轻松使用 Excel
- 使用 Python 可以显著加快数据操作的速度
- Python 中几乎有任何东西的库(机器学习、数据科学等)
- 因为你可以!!!
照片由摄影师在 Unsplash 上拍摄
设置使用 xlwings
与我们想要使用的任何新库一样,我们需要做的第一件事是安装它。做起来超级简单;有了这两条命令,我们马上就可以设置好了。所以,继续输入您的终端:
一旦下载并安装了库,我们需要安装 Excel 集成部分。确保您已经关闭了所有 Excel 实例和任何终端类型:
假设您没有遇到错误,您应该能够继续。然而,在 Win10 和 Excel 2016 上,人们经常会看到以下错误:
xlwings 0.17.0
[Errno 2] No such file or directory: 'C:\\Users\\costa\\AppData\\Roaming\\Microsoft\\Excel\\XLSTART\\xlwings.xlam'
如果你是遇到上述错误的幸运儿之一,你需要做的就是创建丢失的目录。使用 mkdir 命令可以很容易地做到这一点。就我而言,我做到了:
mkdir C:\\Users\\costa\\AppData\\Roaming\\Microsoft\\Excel\\XLSTART
假设成功安装了 excel 与 python 库的集成,您会立即注意到 Excel 中的主要差异:
为 xlwings 启用用户定义的功能
首先,我们需要加载 Excel 插件。你可以点击 Alt,L,H,然后导航到上面的目录来加载插件。完成后,您应该能够看到以下内容:
最后,您需要启用对 VBA 项目对象模型的信任访问。为此,您可以导航至文件>选项>信任中心>信任中心设置>宏设置:
由 Pakata Goh 在 Unsplash 上拍摄的照片
xlwings 入门
从 Excel 到 Python(以及从 Python 到 Excel)有两种主要方式。第一种是直接从 VBA 调用 Python 脚本,而另一种是通过用户定义的函数。让我们快速浏览一下这两者。
为了避免任何混淆和每次都有正确的设置,xlwings 提供创建您的 Excel 电子表格,随时可用。然后让我们使用这个功能。使用终端,我们导航到我们喜欢的目录并键入:
xlwings quickstart ProjectName
我称之为 MyFirstPythonXL。上述命令将在您预先导航的目录中创建一个新文件夹,其中包含一个 Excel 工作表和一个 python 文件。
正在打开。xlsm 文件,您会立即注意到一个名为 _xlwings.conf 的新 Excel 表格。如果您希望覆盖 xlwings 的默认设置,您所要做的就是重命名该工作表并删除起始下划线。至此,我们已经准备好开始使用 xlwings 了。
VBA 到 Python
在我们开始编码之前,让我们首先确保我们都在同一页上。要打开我们的 Excel VBA 编辑器,点击 Alt + F11 。这将返回以下屏幕:
xlwings 的 VBA 编辑器
这里需要注意的关键点是,该代码将执行以下操作:
- 在电子表格所在的位置查找 Python 脚本
- 查找与电子表格同名的 Python 脚本(但扩展名为. py)
- 在 Python 脚本中,调用函数“main()”
事不宜迟,让我们看几个如何使用它的例子。
示例 1:在 Excel 之外操作,并返回输出
在这个例子中,我们将看到如何在 Excel 之外执行操作,然后在电子表格中返回结果。这可以有无限多的用例。
我们将从 CSV 文件中获取数据,对所述数据进行修改,然后将输出传递到 Excel。让我们回顾一下它有多简单:
首先,VBA 密码:
我完全没有改变默认设置。
然后,Python 代码:
这会导致以下结果:
xlwings 在行动
示例 2:使用 Excel 输入来驱动操作
在本例中,我们将从 Excel 中读取输入,用 Python 对其进行处理,然后将结果传回 Excel。
更具体地说,我们将读出一个问候语、一个名字和一个我们可以找到笑话的文件位置。我们的 Python 脚本将从文件中随机抽取一行,并返回一个笑话给我们。
首先,VBA 电码:
我完全没有改变默认设置。
然后,的 Python 代码:
这给了我们:
使用 xlwings 的用户定义函数
和以前一样,我们将改变 python 文件中的代码。为了将一些东西转换成 Excel 用户定义的函数,我们需要做的就是在函数所在的行之前包含“@xw.func ”:
Python 代码:
结果是:
结论
我想你会同意这是一个漂亮的小图书馆。如果你像我一样,你更喜欢用 Python 而不是 VBA 工作,但需要在电子表格中工作,那么这可能是一个非常好的工具。
想了解我博客的最新动态吗?别忘了跟着我!
以下是其他一些你可能会感兴趣的文章:
[## 用 Python 从 Excel 到数据库
了解如何使用 Python 进行快速数据分析
medium.com](https://medium.com/financeexplained/from-excel-to-databases-with-python-c6f70bdc509b) [## 从 XML 到 Excel 进行数据分析
Python 中处理 XML 的介绍
towardsdatascience.com](/from-xml-to-excel-for-data-analysis-ac0c0c765b7d)
如何在充满挑战的时期从裁员中幸存下来并茁壮成长
原文:https://towardsdatascience.com/how-to-survive-a-layoff-during-challenging-times-and-thrive-3b9ee2f9af24?source=collection_archive---------19-----------------------
2020 年5 月 5 日,我从之前的公司下岗了。2020 年 6 月 30 日,我签下了另一家让我非常兴奋的公司的聘书。我写这篇文章是为了分享我和我的一些同事在全球疫情中从被解雇到找到一份新工作的经历。我希望它能对正在经历裁员的人有所帮助和鼓励。
由 Patrick Fore 在 Unsplash 上拍摄
从被解雇到在全球疫情期间找到一份新工作
由于全球疫情,旧金山湾区的许多科技公司在 2020 年早春开始裁员。5 月 5 日,Airbnb 裁员 1900 人,25%的员工,我是其中之一。
除了大规模裁员,许多公司冻结了招聘,因为没有人知道他们的业务未来会是什么样子。对于那些仍在招聘的公司来说,门槛越来越高,许多公司现在只对非常有经验的候选人开放职位。2020 年 4 月,美国官方失业率上升 10.3%,至 14.7%,这是该数据历史上(可追溯至 1948 年 1 月)的最高水平和最大月度增幅。你可以想象那段时间就业市场的竞争有多激烈。
紧张的就业市场只是失业者不得不面对的困难之一。虽然人们说“被解雇与你的表现无关”,但很难不怀疑我是否不够好。作为 H-1B 签证持有人,我也担心我是否能在很短的时间内找到工作,这样美国政府就不会强迫我离开这个国家。此外,我非常喜欢我以前的公司和那里的人,以至于我很难过我不得不离开。
现在我回头看看我的朋友和我自己的经历,通过裁员和求职,我意识到没有什么是不能解决的。如果人们足够强大,准备充分,他们仍然会是决定他们想去哪家公司工作的人,我想和你分享几个故事。
第一个故事是关于我的同事蒂娜。蒂娜参加了 5 次最后的现场面试,得到了 5 份工作机会,通过率 100%。
她收到的第一份工作邀请来自一家中型公司。那家公司的招聘人员在他们的第一次对话中问她是不是被 Airbnb 裁员了。
一个候选人被解雇的事实和你公司的面试过程有什么关系?或者你认为你可以得到一笔“好交易”,因为他们需要一份工作?
果然,公司给 Tina 开出了比她现在水平更低的级别和更低的薪酬待遇。Tina 问招聘人员他们是否可以重新进行调配。招聘人员告诉她,“我们决定不改变你的级别。我们期待看到您在我们公司的长期发展”。
我觉得这家公司认为失业的人是在求工作。他们认为他们可以利用那些受到裁员影响的人,给他们提供低于他们价值的报酬。然而,你不应该指望以这种方式雇佣的员工会忠诚,更不要说对为你工作感到兴奋了。他们不会逗留。危机一结束,他们很可能会立刻离开你,去找一家更好的公司。
幸运的是,Tina 做了充分的准备,她参加了另外 4 个现场面试,并获得了 4 个 offers,包括 Google、脸书、抖音等。由于被解雇,她加入了另一家优秀的公司,与一个聪明的团队一起工作,并获得了晋升,获得了比以前更好的薪酬待遇。
第二个故事是关于我的同事伊恩。伊恩刚刚赢得了今年的 H-1B 签证彩票。他认为他会在我们之前的公司工作,直到 H-1B 签证生效。他从来不知道他会被解雇。
当他被解雇时,他的 H-1B 签证也没了。更糟糕的是,他目前的 J-1 签证没有任何宽限期,这意味着他需要在我们正式的最后一天之前加入另一家公司,这给他只有两个月的时间找到工作。
尽管他的 H-1B 签证被吊销了,而且他找工作的时间比任何人都短,但他从未向我抱怨过。在整个求职过程中,他一直保持乐观和冷静。
仅仅面试了几个星期,伊恩就得到了他的第一份口头聘用。看来公司很喜欢他。他们安排了几个人和他谈论他将要从事的项目,但是他们没有给他正式的签约机会。伊恩认为他可以很快加入一家公司;然而,该公司决定不给他正式报价。
伊恩和我认为原因是该公司也向另一位候选人发出了邀请,而伊恩只是那个职位的 B 计划。如果另一个候选人拒绝了这个提议,伊恩就会得到这份工作。但是看起来另一个候选人已经接受了邀请。
即使在这种情况下,伊恩仍然没有抱怨,他简要地告诉我发生了什么,并继续准备其他采访。
在我认识的人里,Ian 的面试日程最紧张,压力也最大。他将在一周内进行 5 次最终的现场面试,外加几次电话面试。
在如此疯狂的生活了几个星期后,他收到了多份工作邀请,在两个月的时间内加入了新公司,并获得了晋升。
与 Tina 和 Ian 类似,我的许多其他同事也取得了类似的结果。如果没有裁员,他们可能没有动力这么紧张高效地准备面试,也不会这么快升职,包括我。
虽然我不像我的许多同事那样有经验,但我至少有一个非常明确的目标,那就是我在寻找什么类型的数据科学家工作:我想成为一名产品数据科学家,主要从事产品分析和实验,并能对产品产生直接影响。
由于目标明确,我分析了我需要做些什么来获得最好的结果。我重点复习了统计学和实验设计,没有花时间练习 LeetCode 编程题。
经过几周的密集学习和面试,我参加了 6 次现场面试,收到了 3 份聘书,都来自产品数据科学家职位。我也得到了晋升和更好的薪酬待遇,而且我将加入一家我非常喜欢的公司。
(蒂娜和伊恩不是真名)
由米歇尔·奥尔在 Unsplash 上拍摄的照片
我想要你知道的是
1.被解雇并不意味着你不够好
首先,你必须调整心态。下岗不代表你不够优秀,也不代表你在乞求工作机会。你必须记住这一点。
即使在美国失业率飙升至历史最高纪录的时候,如果你做好了充分的准备,你仍然可以在多个机会中做出选择。
有些公司可能会认为现在求职者多了,职位空缺少了,可以花更少的钱招聘出类拔萃的人才。我想说,如果你相信你应该得到更好的机会和更高的薪水,那你就应该得到。你不需要满足于更低的要求。你必须相信自己的价值,因为没有人比你自己更了解你。
2.为面试做好充分准备
在准备数据科学或软件工程面试时,人们通常需要花几周到几个月的时间来复习技术知识。比如你在面试数据科学岗位,需要复习:高级 SQL、基础 Python/R 数据操纵、统计学、实验设计、机器学习算法、产品/案例分析知识。如果你在面试机器学习工程职位,你还需要通过 Leetcode 编码问题。
我通常一决定找工作就开始面试,因为我把参加面试作为评估自己对面试准备程度的一种方式。然而,在这个充满挑战的时期,仍然在招聘的公司越来越少。在这些时候,更好的策略是花些时间复习所有需要的知识,然后参加面试,以免浪费面试机会。
但是请记住,你永远不会 100%准备好,不要等到你觉得自己 100%准备好了,因为那一天永远不会到来。
3.优化你的求职转换漏斗
诚然,有工作经验的人和没有工作经验的人之间的求职转换漏斗是不同的。然而,我认为差别在于找工作的难易程度,而不是一个人能否找到工作的决定性因素。
两年前我转行做数据科学家时,我的求职转换漏斗是:
475 份申请→ 50 次面试→ 8 次现场面试→ 2 次录用
我今年的求职转换漏斗是:
30 份申请→ 13 次面试→ 6 次现场面试→ 3 次录用
每两步之间的转换率如下所示:
2018 年和 2020 年我的求职转换漏斗
分析求职转换漏斗就像数据科学面试中的典型案例研究问题。目标是增加报价的数量。该指标是面试流程中每两步之间的转换率。对你来说,告诉你需要优化哪些步骤应该是简单明了的。
如果面试总数低,你应该尝试优化漏斗顶部。例如修改简历,申请更多的工作,寻找更多的推荐人,在尽可能多的平台上发布你的信息,让更多的人知道你在找工作等等。
如果你多次面试失败,你应该根据面试类型进行细分,以便进行更深入的分析。以数据科学面试为例,你可以分解一下,看看自己是不是需要去温习统计学知识或者案例研究知识,多练习 SQL 或者 Python 等。在你理解了哪些步骤在转化漏斗中下降最大后,集中精力改进这些步骤。
4.只关注你能控制的事情
人们谈论找工作有多难,因为公司提高了门槛。人们抱怨一些公司在他们的网站上发布招聘信息,但他们并不认真招聘。是的,他们可能是正确的。但我认为不值得花时间抱怨这些外部因素。
如果招聘门槛越来越高,你会停止找工作吗?
在你递交申请之前,你会仔细检查每一家公司,看看他们是否真的在招聘吗?
与其花时间担心你无法控制的事情,你可以用这些时间来研究更多的面试问题。如果你多研究一个问题,你可能会到达一家公司的招聘栏。如果你抱怨事情超出你的控制,你只是在为自己的失败找借口。
同样的逻辑也适用于你如何对待失败的面试。当你面试失败的时候,难过几分钟是可以的,但是不值得超过几分钟。当你面试失败时,你应该想想你失败的原因。是因为你给的一些答案不够好吗?或者你只是运气不好?如果你认为你失败是因为你没有回答好一些问题,下次试着在那些问题上做得更好。如果你觉得自己倒霉了,那就更好了,你根本不需要去想它!
永远不要因为面试失败而失去自信。你要相信自己很了不起。任何你做得不好的地方都可以改进。随着练习的增多,你会越来越好。
与其因为一些公司拒绝了你而怀疑自己,不如感谢他们给了你面试的机会,让你得到了锻炼面试技巧的机会。有了更好的面试技巧,当工作机会来找你的时候,你就能抓住更好的机会。
5.别人多快找到工作并不重要
有些人更喜欢高强度的求职过程,他们喜欢从早到晚只花几周时间做面试。有些人更喜欢平衡面试和他们的个人生活,所以他们准备得更慢。
有的人有多年的工作经验,基础知识过硬;因此,他们不需要花太多时间就能找到一份新工作。有的人经验少,或者需要更多的时间来夯实基础知识;因此他们需要更多的时间来准备。
每个人都有自己的节奏和时机。你只需要在你的轨道上稳步前进。没有必要拿自己和别人比较,或者被别人的成就所影响。你的最终目标是找到一份你愿意呆上几年的工作,而不是抓住任何一根稻草不放。
6.黑暗中总有一丝光明
我的同事和我的经历表明,裁员可以带来更好的工作机会,甚至升职。这次经历坚定了我的信念:生活中一切看似不幸的事情都是塞翁失马焉知非福。让转变发生的最重要的因素是 知道自己的价值,拥有自信,专注于你能控制的事情。"艰难的日子不会长久,但坚强的人会长久。"我希望你能站得更高,对抗试图把你拉下来的东西,我知道如果你想,你能做到。干杯。
安德里亚斯·楚在 Unsplash 上的照片
如何在 6 种想象中作为罗马皇帝生存
原文:https://towardsdatascience.com/how-to-survive-as-a-roman-emperor-in-6-visualizations-7dcd810c9732?source=collection_archive---------32-----------------------
Jaime Spaniol 在 Unsplash 上拍摄的照片
去古罗马旅行,不用担心保险。
好吧,你在你的阁楼里发现了一个生锈的金属盒子,它属于你刚刚过世的祖父。你把它带到你的客厅,在你有机会把灰尘从顶部闪烁的红色按钮上吹出来之前,一道蓝光吞没了你的身体,突然你被加冕为罗马帝国的凯撒。你的 200 个小时的人对野对你在这里生存没有帮助,所以让我给你一些建议。
在一周的时间里,我探索了自凯撒的养子屋大维(因其头衔而被称为奥古斯都)于公元前 27 年夺取政权至 1453 年东罗马帝国灭亡期间,所有罗马皇帝的生活和(主要是)死亡。这些数据是从维基百科的罗马皇帝列表中刮出来的,并使用 Python(主要是 pandas 用于操纵数据,matplotlib/seaborn 用于绘图)进行分析。你可以在这里看到所有的代码。
经过紧张的研究,我整理了一些你去古罗马旅行前需要知道的基本知识。时间旅行公司有一个严格的不退款政策,以防在停留期间不幸死亡,所以如果你想节省那些宝贵的美元,请一起阅读。
当皇帝能有多危险?
好吧,我明白了。你在想,“当皇帝没那么糟糕。他们是地球上最强大的生物;甚至克娄巴特拉也没有惹他们。”你是对的,我们都听说过这些近乎神话的人物的事迹和荣耀。这种赞扬并不是不公平的;这些人是地球上最有权力的人之一。然而,强大的力量带来了巨大的嫉妒,我们都知道当时的叛逆兄弟关系(是的,布鲁图斯,我说的就是你)。
让我们通过绘制罗马皇帝死亡时的年龄和他们掌权的一段时间的直方图来进一步了解你的生存机会:
从直方图中,我们可以看到,与同时代的其他人相比,他们的寿命很长,预期寿命约为 51 岁(罗马帝国的预期寿命约为 25 岁)。起初,这可能证实了我们的期望,即出生在皇室中对这些幸运的私生子来说确实有所回报。然而,该分析忽略了一个事实,即婴儿死亡率是当时的主要死亡原因(大约一半的人口在 5 岁之前死亡),我们的样本只包含那些年龄足够成为皇帝的人。我们考虑的是那些度过了生命中最危险时期的人,但是谁知道有多少皇室婴儿在加冕前就死去了呢?如果我们把婴儿死亡率排除在外,当时的罗马人口实际上活到 50 多岁,这意味着我们的皇帝寿命一样长,如果不是更短的话。
直方图中第二个有趣的发现是,尽管皇帝们拥有永久的职位,但他们掌权的时间并不长。平均执政时间为 10 年,但一半以上的人执政时间只有 6 年或更短。让我们来比较一下美国总统:自 1789 年以来,共有 44 位总统,这意味着每一位总统平均在任时间为(2020–1789)/44 = 5.25 年,其中超过一半的总统在任时间不超过 4 年。没什么不同吧?
让我们试着想象一下这些皇帝掌权的时间,以及他们退休后是否过得很好。(图有些长)。
这个情节似乎证实了我们的怀疑。除了少数例外,大多数皇帝在掌权后就去世了,尤其是在帝国的最初几年。似乎完全控制地球上最强大的文明是一种诅咒。我们来调查一下这些帝王的死因;也许他们能对此事有所帮助。
正如我所料,暴力在地中海地区蔓延。在我能够获得死亡原因信息的 121 个皇帝中,74 个死于暴力——占 61%!
如果你成为罗马皇帝,如何生存-初学者指南。
让我们利用这张图表,通过采用预防生命每个阶段最常见死亡原因的技术,最大限度地提高你的生存机会。
如果你是 20 岁或更小,就要警惕了!篡位者会试图利用你的天真来对付你,所以要小心可疑的邀请,邀请你参加以战斗为主题的睡衣派对或者私人教练不断建议你和他们一起洗澡。
到了 30 岁,你的优先事项改变了:开始关注你的身体和精神健康。保持一个健康的身体会避免常见的疾病,并使凶手在与你的体质决斗前三思。
暴力的暂停是理所应当的,但不会持续太久,因为你 40 多岁的时候会提醒你永远不要放松警惕。此外,千万不要在没有阅读的情况下签署文件——罗马司法系统是无情的,你也不想最终站在斗兽场阳台的错误一边。
如果你活到 70 岁,干得好。尽管困难重重,你还是挺过了历史上最危险的工作之一(而且如此优雅!).当你从浴室的窗户面对你的帝国的广阔土地,回忆起黄金时代,你可以头脑风暴一些你名字的衍生词,给你上周末去过的那个迷人的小镇。
西罗马帝国有流行的死法吗?
下面的彩色条是这一时期暴力死亡的热图。
根据这个图表,是的。当谈到早期罗马帝国的死亡趋势时,暗杀是明显的赢家,特别是从公元 150 年到 300 年——我们在短短 50 年内就发生了 17 起谋杀。在暴力不再成为主流后,我们看到了自然死亡的回归,以及对斩首的少量但有意义的偏好。在过去的 50 年里,帝国的衰落激发了一场反文化运动,每个皇帝都开始尝试自己的死亡方式。
让我们尝试使用 Bokeh——Python 中的一个绘图工具——将前面图形中的所有信息浓缩成一个图形。
点数的大小与死亡时的年龄相对应。
重要提示
各位,今天的生存(和一些历史)课到此结束。从这些简单的图表中,我们了解到几件重要的事情:
- 当皇帝是一件很酷但可悲的短暂工作。
- 如果你想让你的孩子成为无情的独裁者,帕里奥洛戈斯是一个很好的名字。
- 如果你在时间和空间中回到罗马皇帝的身体,你生存的优先事项应该是(按照这个特定的顺序):不被谋杀,不进行无保护的性行为(性病和你的孩子都可能杀了你),让军队吃饱,避免参军(超过 60 岁在当时不是一个有效的借口),雇佣一名治疗师。
感谢您的阅读!
免责声明:本文为娱乐目的而写。我不能证明所讨论的信息的准确性。
如何用 MySQL 同步 Elasticsearch
原文:https://towardsdatascience.com/how-to-synchronize-elasticsearch-with-mysql-ed32fc57b339?source=collection_archive---------1-----------------------
使用 Logstash 创建一个连接 Elasticsearch 和 MySQL 的数据管道,以便从零开始建立一个索引,并将数据库记录上发生的任何变化复制到 Elasticsearch 中
快速访问链接
- GitHub 上的资源库: sync-elasticsearch-mysql 。
技术栈
- MySQL 作为主数据库(版本 8.0.22)
- 作为文本搜索引擎的弹性搜索(版本 7.9.3)
- Logstash 作为从 MySQL 到 Elasticsearch 的连接器或数据管道(7.9.3 版)
- 用于监控和数据可视化的 Kibana(版本 7.9.3)
- JDBC 连接器/J(版本 8.0.22)
内容
- 问题陈述
- 解决方案
-使用 Logstash 的好处
-用例 - 实施概念验证
-为项目创建主机目录
-设置 MySQL 数据库
-设置 Elasticsearch 和 Kibana
-设置 Logstash 将数据从 MySQL 传输到 Elasticsearch:
*第一个场景—从头开始创建 Elasticsearch 索引
*第二个场景—将数据库记录的更改复制到 Elasticsearch - 结论
- 资源
照片由 Sébastien Jermer 在 Unsplash 上拍摄
问题陈述
科技公司的一个常见场景是开始围绕一个或多个数据库构建其核心业务功能,然后开始将服务连接到这些数据库,以对文本数据执行搜索,例如在用户表的用户地址列中搜索街道名称,或者在图书馆的目录中搜索书名和作者姓名。
到目前为止一切都很好。公司不断发展壮大,获得了越来越多的客户。但随后搜索速度开始变得越来越慢,这往往会激怒他们的客户,并很难说服新的潜在客户购买。
从本质上看,工程师们意识到 MySQL 的FULLTEXT
索引对于在大型数据集上进行文本查找并不理想,为了扩大他们的业务,工程师们决定转向更专用的、经过实战检验的文本搜索引擎。
进入 Elasticsearch 及其底层 Lucene 搜索引擎。Elasticsearch 使用一个倒排文档索引来索引数据,这导致了极快的全文搜索。
一个新的挑战随之而来:如何将 MySQL 数据库中的数据放入 Elasticsearch 索引,以及如何保持后者与前者同步?
解决办法
现代数据管道工的工具包中包含了大量的软件,可用于任何数据操作任务。在本文中,我们将关注来自 ELK stack 的 Logstash,以便定期从 MySQL 获取数据,并将其镜像到 Elasticsearch 上。这将考虑到 MySQL 数据记录的任何变化,如create
、update
和delete
,并在 Elasticsearch 文档中复制相同的内容。
使用 Logstash 的好处
我们在这里试图解决的问题——定期从 MySQL 向 Elasticsearch 发送数据以同步两者——可以通过 cron 作业或任何作业调度程序运行的 Shell 或 Python 脚本来解决,但这将剥夺我们通过配置 Logstash 及其基于插件的设置所获得的好处:
- 虽然我们在这里主要关注 MySQL, Logstash 可以从许多来源获取数据,使它成为一个集中式数据输入节点。
- 当数据从源传递到目的地时,Logstash 提供了动态解析、转换和过滤数据的可能性。
- 至于输入源,有许多输出目的地可用——elastic search 是首选输出。
- 作为 ELK 堆栈的一部分,稍后,Elasticsearch 和 Kibana 将为度量和可视化提供很好的整合。
用例
我们将在以下步骤中介绍两种情况:
- 从头开始创建弹性搜索索引和索引数据库记录。
- 增量 根据数据库记录发生的变化(创建、更新、删除)更新弹性搜索索引的。
实施概念验证
想象一下,你正在开一个在线图书馆,热心的读者可以在那里搜索你的图书目录,找到他们的下一本书。您的目录包含数百万个标题,从科学文献卷到有关异国冒险的小册子。
我们将创建一个初始数据库表books
,其中有几千条记录,包括书名、作者、ISBN 和出版日期。我们将使用可以在 Kaggle 上找到的 Goodreads 图书目录。这个初始表将用于构建用例的原型(1)从零开始构建索引。
我们将在表books
上创建触发器,该触发器将用books
表上的所有更改填充日志表books_journal
(例如create
、update
、delete
)。这意味着无论何时在books
表上创建、更新或删除一条记录,该操作都将被记录在books_journal
表上,同样的操作也将在相应的 Elasticsearch 文档上执行。这将用于原型用例(2)弹性搜索指数的增量更新。
我们将通过使用 docker-compose 定义微服务架构来原型化和测试上述概念。
该项目的建筑——作者图片
先决条件
- 安装对接器和对接器组成
步骤
完整的源代码可以在 GitHub 的sync-elastic search-MySQL找到。
- 首先创建一个目录来托管这个项目(命名为
sync-elasticsearch-mysql
),并在该目录中创建一个 docker-compose.yaml 文件,初始设置如下:
version: "3"
services:
...
# Here will come the services definition
...
2。设置一个 MySQL 数据库:创建一个目录data/
,我们将在其中存储 MySQL 转储文件,这些文件包含books
表的预清理图书数据,以及books
表的触发器(关于创建、更新和删除),还有一个new_arrivals
表,其中包含我们将添加到目录中以模拟新记录的图书,以及表books_journal
。
您可以在项目资源库中找到这些转储文件。请将它们复制到data/
目录,以便 MySQL 容器在启动过程中将它们添加到books
数据库中。
version: "3"
services:
# add this:
mysql:
image: mysql:8
container_name: sem_mysql
ports:
- 3306:3306
environment:
MYSQL_RANDOM_ROOT_PASSWORD: "yes"
MYSQL_DATABASE: books
MYSQL_USER: avid_reader
MYSQL_PASSWORD: i_love_books
volumes:
# Dump files for initiating tables
- ./data/:/docker-entrypoint-initdb.d/
请注意,不建议在源代码中以纯文本形式存储用户名和密码。以上只是为了建立这个项目的原型,在任何情况下都不是推荐的做法。
要启动 MySQL 并检查数据是否已成功添加,请在终端上运行项目目录:
docker-compose up -d mysql # -d is for detached mode# Once container started, log into the MySQL container
docker exec -it sem_mysql bash# Start a MySQL prompt
mysql -uavid_reader -pi_love_books# Check that tables have been loaded from dump files
use books;
show tables;
可用表格列表和数据示例—按作者分类的图片
要以类似 JSON 的格式显示触发器,请使用命令:
SHOW TRIGGERS \G;# To exit the MySQL prompt press CTRL+D
# To logout from the MySQL container, press CTRL+D
既然我们已经正确地建立了数据库,我们就可以继续进行这个项目的实质性工作了。
3。设置 Elasticsearch 和 Kibana: 要设置 Elasticsearch(还没有索引任何文档),请将其添加到 docker-compose.yaml 文件中:
version: "3"
services:
...
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.9.3
container_name: sem_elasticsearch
environment:
- discovery.type=single-node
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
volumes:
- ./volumes/elasticsearch:/usr/share/elasticsearch/data
logging:
driver: "json-file"
options:
max-size: "10k"
max-file: "10"
kibana:
image: docker.elastic.co/kibana/kibana:7.9.3
container_name: sem_kibana
environment:
- "ELASTICSEARCH_URL=[http://elasticsearch:9200](http://elasticsearch:9200)"
- "SERVER_NAME=127.0.0.1"
ports:
- 5601:5601
depends_on:
- elasticsearch
请注意,为了将弹性搜索索引数据从 docker 卷挂载到您的目录文件系统,建议使用卷定义。
要启动 Elasticsearch 和 Kibana,请从您的项目目录运行以下命令:
docker-compose up -d elasticsearch kibana # -d is for detached mode# To check if everything so far is running as it should, run:
docker-compose ps
在执行上述命令后,3 个容器应该启动并运行——Image by Author
让我们检查到目前为止我们的 Elasticsearch 节点中是否有任何索引:
# On your terminal, log into the Elasticsearch container
docker exec -it sem_elasticsearch bash# Once logged in, use curl to request a listing of the indexes
curl localhost:9200/_cat/indices
如果 Kibana 已经启动并运行,您将看到一个用于度量和可视化的索引列表,但是还没有与我们的书相关的内容——如果 Kibana 还没有启动,索引列表将是空的。
由 Kibana 创建的索引列表—图片由作者提供
4。设置 Logstash 将数据从 MySQL 传输到 Elasticsearch:
为了将 Logstash 连接到 MySQL,我们将使用官方的 JDBC 驱动程序,该驱动程序可以在这个地址获得。
让我们创建一个 Dockerfile(在同一个目录中命名为Dockerfile-logstash
)来提取一个 Logstash 映像,下载 JDBC 连接器,并启动一个 Logstash 容器。将这些行添加到您的 docker 文件中:
FROM docker.elastic.co/logstash/logstash:7.9.3# Download JDBC connector for Logstash
RUN curl -L --output "mysql-connector-java-8.0.22.tar.gz" "[https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-8.0.22.tar.gz](https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-8.0.22.tar.gz)" \
&& tar -xf "mysql-connector-java-8.0.22.tar.gz" "mysql-connector-java-8.0.22/mysql-connector-java-8.0.22.jar" \
&& mv "mysql-connector-java-8.0.22/mysql-connector-java-8.0.22.jar" "mysql-connector-java-8.0.22.jar" \
&& rm -r "mysql-connector-java-8.0.22" "mysql-connector-java-8.0.22.tar.gz"ENTRYPOINT ["/usr/local/bin/docker-entrypoint"]
然后将下面的代码片段添加到 docker-compose.yaml 文件中:
version: "3"
services:
...
logstash:
build:
context: .
dockerfile: Dockerfile-logstash
container_name: sem_logstash
depends_on:
- mysql
- elasticsearch
volumes:
# We will explain why and how to add volumes below
Logstash 使用定义的管道来知道从哪里获取数据,如何过滤数据,以及数据应该去往哪里。我们将定义两个管道:一个用于从头创建一个 Elasticsearch 索引(第一个场景),另一个用于数据库记录变更的增量更新(第二个场景)。
有关管道定义中使用的每个字段的解释,请查看文档:
- 输入: JDBC 输入插件
- 过滤:变异
[remove_field](https://www.elastic.co/guide/en/logstash/current/plugins-filters-mutate.html#plugins-filters-mutate-remove_field)
- 输出: Elasticsearch 输出插件
4.a .第一个场景——从头开始创建弹性搜索指数:
在您的项目目录中,创建一个volumes
文件夹(如果还没有创建的话),然后创建一个目录来托管我们的 Logstash 配置:
mkdir -p volumes/logstash/config
然后在这个配置目录下,创建一个文件pipelines.yml
,包含:
- pipeline.id: from-scratch-pipeline
path.config: "/usr/share/logstash/pipeline/from-scratch.conf"
然后,我们创建一个文件夹pipeline
来存放我们的管道定义:
mkdir volumes/logstash/pipeline
并在那里创建一个文件from-scratch.conf
,内容如下:
input {
jdbc {
jdbc_driver_library => "/usr/share/logstash/mysql-connector-java-8.0.22.jar"
jdbc_driver_class => "com.mysql.jdbc.Driver"
jdbc_connection_string => "jdbc:mysql://mysql:3306"
jdbc_user => "avid_reader"
jdbc_password => "i_love_books"
clean_run => true
record_last_run => false
statement_filepath => "/usr/share/logstash/config/queries/from-scratch.sql"
}
}filter {
mutate {
remove_field => ["[@version](http://twitter.com/version)", "[@timestamp](http://twitter.com/timestamp)"]
}
}output {
# stdout { codec => rubydebug { metadata => true } }
elasticsearch {
hosts => ["[http://elasticsearch:9200](http://elasticsearch:9200)"]
index => "books"
action => "index"
document_id => "%{isbn}"
}
}
我们在jdbc_driver_library
中定义了在哪里找到 JDBC 连接器,在jdbc_connection_string
中设置了在哪里找到 MySQL,在clean_run
中指示插件从头开始运行,并且我们在statement_filepath
中定义了在哪里找到 SQL 语句来获取和格式化数据记录。
过滤器基本上删除了插件添加的额外字段。
在输出中,我们定义在哪里找到 Elasticsearch 主机,将索引的名称设置为books
(可以是新的或现有的索引),定义要执行的操作(可以是index
、create
、update
、delete
— 参见文档,并设置哪个字段将作为books
索引中的唯一 ID—ISBN 是图书的国际唯一 ID。
为了添加由statement_filepath
引用的 SQL 查询,让我们创建一个文件夹queries
:
mkdir volumes/logstash/config/queries/
然后添加文件from-scratch.sql
,只有:
SELECT * FROM books.books
用到目前为止我们的books
表中所有可用的记录构建我们的索引。注意,查询不应该以分号(;).
现在,要挂载上面创建的配置文件和定义,请将以下内容添加到 docker-compose.yaml 文件中:
version: "3"
services:
...
logstash:
...
volumes:
- ./volumes/logstash/pipeline/:/usr/share/logstash/pipeline/
- ./volumes/logstash/config/pipelines.yml:/usr/share/logstash/config/pipelines.yml
- ./volumes/logstash/config/queries/:/usr/share/logstash/config/queries/
请注意,
volumes
指令是一种告诉 Docker 将容器内的目录或文件(的右侧)挂载到您的机器或服务器上的目录或文件(的左侧)的方式。在volumes
上查看官方 Docker 撰写文档。
测试
为了测试第一个场景的实现,在您的终端上运行:
docker-compose up logstash
如果运行成功,您将看到类似于Logstash shut down
的消息,容器将退出,并返回错误代码 0。
现在在你的浏览器上打开 Kibana(例如这个链接,让我们开始尝试看看我们是否有一个books
索引,以及我们如何搜索书籍。
图书索引已成功创建,包含 1k 个文档—图片由作者提供
在 Dev Tools 面板中,您可以运行定制查询来通过字段值获取文档。例如,让我们搜索标题中带有“魔法”一词的书籍。将此查询粘贴到开发工具控制台上:
GET books/_search
{
"query": {
"match": {
"title": "magic"
}
}
}
我们得到 9 份文件:
搜索标题中包含“魔法”一词的书籍-作者图片
图片由 Giphy 提供
4.b .第二个场景—将数据库记录上的更改复制到 Elasticsearch:
大部分配置和调整已经在前一部分完成。我们将简单地添加另一个管道来负责增量更新(复制)。
在文件volumes/logstash/config/pipelines.yml
中,添加这两行:
- pipeline.id: incremental-pipeline
path.config: "/usr/share/logstash/pipeline/incremental.conf"
在同一个文件中,您可能想要注释掉与“从头开始”部分(第一个场景)相关的前两行,以便指示 Logstash 只运行这个增量管道。
让我们在目录volumes/logstash/pipeline/
中创建一个文件incremental.conf
,内容如下:
input {
jdbc {
jdbc_driver_library => "/usr/share/logstash/mysql-connector-java-8.0.22.jar"
jdbc_driver_class => "com.mysql.jdbc.Driver"
jdbc_connection_string => "jdbc:mysql://mysql:3306"
jdbc_user => "avid_reader"
jdbc_password => "i_love_books"
statement_filepath => "/usr/share/logstash/config/queries/incremental.sql"
use_column_value => true
tracking_column => "journal_id"
tracking_column_type => "numeric"
schedule => "*/5 * * * * *"
}
}filter {
if [action_type] == "create" or [action_type] == "update" {
mutate { add_field => { "[[@metadata](http://twitter.com/metadata)][action]" => "index" } }
} else if [action_type] == "delete" {
mutate { add_field => { "[[@metadata](http://twitter.com/metadata)][action]" => "delete" } }
}mutate {
remove_field => ["[@version](http://twitter.com/version)", "[@timestamp](http://twitter.com/timestamp)", "action_type"]
}
}output {
# stdout { codec => rubydebug { metadata => true } }
elasticsearch {
hosts => ["[http://elasticsearch:9200](http://elasticsearch:9200)"]
index => "books"
action => "%{[[@metadata](http://twitter.com/metadata)][action]}"
document_id => "%{isbn}"
}
}
与之前的管道定义相比,我们看到了一些额外的参数。
schedule
参数有一个类似 cron 的语法(当左边增加一个值时,分辨率下降到秒),并在后台使用 Rufus 调度器。这里我们用*/5 * * * * *
指示 Logstash 每 5 秒运行一次这个管道。
网站 crontab.guru 可以帮你读懂 crontab 表达式。
在每次定期运行期间,参数tracking_column
指示 Logstash 存储获取的最后一条记录的journal_id
值,并将其存储在文件系统上的某个位置(参见文档,此处用于last_run_metadata_path
)。在接下来的运行中,Logstash 将从journal_id + 1
开始获取记录,其中journal_id
是当前运行中存储的值。
在filter
部分中,当数据库操作类型为“创建”或“更新”时,我们将 Elasticsearch 操作设置为“索引”,这样新文档就会被索引,现有文档也会被重新索引以更新它们的值。避免重新索引现有文档的另一种方法是编写一个定制的“更新”脚本,并使用“更新”动作。对于“删除”操作,Elasticsearch 上的文档会被删除。
让我们使用以下查询创建并填充目录volumes/logstash/config/queries/
中的文件incremental.sql
:
SELECT
j.journal_id, j.action_type, j.isbn,
b.title, b.authors, b.publication_date
FROM books.books_journal j
LEFT JOIN books.books b ON b.isbn = j.isbn
WHERE j.journal_id > :sql_last_value
AND j.action_time < NOW()
ORDER BY j.journal_id
测试
我们来看看表books.new_arrival
。它包含刚刚交付给我们的书籍,我们没有时间将它们添加到主books.books
表中。
“SELECT * FROM books.new _ arrival”—作者图片
如我们所见,该表中没有一本书在我们的 Elasticsearch 索引中。让我们试试上表中的第三本书《浪漫之路(艾尔西·霍金斯#4)》,ISBN 9780060598891:
搜索 ISBN 9780060598891 返回空结果—作者图片
现在,让我们将图书从新到货表转移到我们的主books
表:
INSERT INTO books
SELECT * FROM new_arrival WHERE isbn = 9780060598891;
在 Elasticsearch 上运行相同的搜索,我们很高兴地看到该文档现已可用:
现在 ISBN 9780060598891 可以在弹性搜索索引上找到——作者图片
同步成功了!
让我们测试同一个 ISBN 的更新:
UPDATE books
SET title = "The Rocky what ??"
WHERE isbn = 9780060598891;
数据库记录的更新被成功复制到 Elasticsearch 文档——按作者分类的图片
…以及删除相同的 ISBN:
DELETE from books WHERE isbn = 9780060598891;
从数据库中删除的记录也将从 elastic search index-Image by Author 中删除
图片由 Giphy 提供
结论
我们设法在很短的时间内获得了一个概念证明,即如何从 MySQL 数据库将数据索引到 Elasticsearch 中,以及如何使 Elasticsearch 与数据库保持同步。
我们使用的技术是业内的黄金标准,许多企业每天都依赖这些技术来服务他们的客户,很可能许多企业已经遇到或将会遇到我们在这个项目中解决的相同问题。
取得联系
如果你想联系我,或者你只是想让我知道你对这个项目的想法,不要犹豫,留下评论,或者通过电子邮件或 LinkedIn 联系我。
如果你觉得这个教程有用,并且你想支持高质量文章的制作,考虑给我买杯咖啡!
你可以点击“关注”按钮来获取我的最新文章和帖子!
资源
- 首次尝试建立倒排索引
- 数据输入:文件和索引
- 如何使用 Logstash 和 JDBC 保持 Elasticsearch 与关系数据库同步。这篇文章很有启发性,但是它并不涉及从零开始索引和删除记录。
- 本项目使用的数据可在 Kaggle 数据集 Goodreads-books 中获得。
- 日志 JDBC 输入插件
- 日志隐藏变异过滤器插件
- Logstash Elasticsearch 输出插件
如何系统地愚弄一个图像识别神经网络
原文:https://towardsdatascience.com/how-to-systematically-fool-an-image-recognition-neural-network-7b2ac157375d?source=collection_archive---------17-----------------------
来源: Unsplash
以及为什么它很重要
卷积神经网络(CNN)构成了图像识别的基础,这无疑是深度学习最重要的应用之一。不幸的是,深度学习的许多研究都是在数据集的“完美世界”约束下进行的,以追求几个百分点的准确性。因此,我们开发的架构在理论测试中表现非常好,但在现实世界中不一定如此。
对抗性的例子或输入(想想对手 : 敌人)对于人眼来说无法与常规图像区分开来,但完全可以骗过各种图像识别架构。显然,敌对输入的部署会带来许多令人不安和危险的影响,特别是当 AI 被赋予更多权力为自己做决定的时候。
因此,理解和解决系统地产生对抗性输入的方法——应用于深度学习的道德黑客攻击——是很重要的。
Goodfellow 等人介绍了一种简单的系统生成对抗输入的方法,称为“快速梯度符号方法”。
考虑:
- 一个输入向量 x (这是输入信息——图像——但是把它想象成一个一维列表)
- 对抗性输入 x -hat(与 x 形状相同,但数值有所改变)
- 一个对抗矢量η(‘eta’被加到输入矢量上以产生对抗输入矢量)
为了执行逐个元素的乘法和求和(例如[1,2,3] × [1,2,3] = 1+4+9 = 14
),我们将第一个向量的转置与第二个向量相乘。这将被称为“加权和”。
我们在这里有两个目标,我们必须都实现,以生成对抗性输入:
- 我们希望最大化原始输入向量的加权和与被扰乱(改变)的敌对输入的加权和之间的差异。这将改变激活状态,并打乱模型的决策过程。
- 我们希望使对立向量 η 的每个单独值尽可能小,以使整个图像在人眼看来不变。
Goodfellow 等人提出的解决方案是双管齐下的——而且非常聪明,原因如下。
η 设置为 sign( w ),其中 sign 函数返回-1 表示负值,1 表示正值(0 表示 0)。如果权重为负,则乘以负一得到正和;如果权重为正,则乘以正 1,不变。
例如,如果权重向量是[3,-5,7]
, η 将是[1,-1,1]
。加权和为3+5+7=15
。请注意,执行此操作本质上是将否定转化为肯定,并保留肯定(abs()
功能)。这意味着每个数字都是尽可能大的,如果权重在区间[-1, 1]
内,则是可能的最高加权和。
考虑下面的一些“图片”。虽然它们是二维的,但把它们想象成一维向量。
由作者创建。
最终的和是 10,这与最初的输出-7 有很大的不同。当然,这将会打乱网络的预测。
这实现了做出大的改变的目标,但是它一点也不谨慎。毕竟,当我们扰乱它时,我们的形象已经发生了显著的变化:
由作者创建。
请记住,我们之前将最终总和表示为w(x)+w(η),其中 w ()是加权总和, η 是概率向量,这实际上是对w(x+η)的扩展。我们想稍微改变每个像素的值。虽然总效果必须最大化,但是 η 的每个元素必须足够小以至于不被注意到。
在对抗输入的实际产生中,像素数*j*
被定义为 x 的第*j*
个值加上 η的第*j*
个值。首先介绍的符号采取了一点捷径来演示 η 的目的,就是大幅增加集体总和,不一定是单个像素值。
η 的每个元素都相当大:+1 或-1,这对适当缩放的数据影响很大。为了解决这个问题,我们将把 η 的每个元素乘以一个带符号的ϵ,其中ϵ是传感器检测到的最小数值单位(或者更小)。对于 8 位颜色,这个数字是 256,因此ϵ = 1/255。
因为ϵ是“不可探测的”(或者说几乎不可探测),所以从视觉上看,它对图像没有影响。但是,每个变化都是按照符号函数构建的,以使加权和的变化最大化。
因此,我们将-ϵ或+ϵ添加到输入向量的每个元素,这是一个足够小的变化,因此它是不可检测的,但用符号函数构造,使得变化最大化。
许多小组件加起来可能会非常大,尤其是如果它们是以智能方式构建的话。
让我们考虑一下这对我们之前的ϵ=0.2.例子的影响我们能够产生 3 个单位的差异(总和为-4)。
由作者创建
这是相当可观的,尤其是考虑到置换向量对原始输入向量的微小改变。
由作者创建
如果权重向量有 n 维,一个元素的平均绝对值是 m ,那么激活值将增长ϵ nm 。在高维图像(比如 256 乘 256 乘 3)中, n 的值是 196608。m 和ϵ可能非常小,但仍会对输出产生重大影响。
这种方法非常快,因为它只改变+ϵ或-ϵ:的输入,但它这样做的方式非常有效,它完全欺骗了神经网络。
这里,0.007 的ϵ对应于在 GoogLeNet 转换成实数之后 8 位图像编码的最小位的幅度。来源:古德费勒等人
Goodfellow 等人在应用 FGSM 时发现了有趣的结果:
- ϵ=0.25 导致浅层 SoftMax 分类器具有 99.9%的错误率,在 MNIST 上的平均置信度为 79.3% 。
- 对于预处理的 CIFAR-10 上的不正确预测,ϵ=0.1 导致 CNN 具有 87.15%的错误率,平均置信度为 96.6% 。
显然,这些对抗性的输入会导致严重的错误率,但更令人担心的可能是高置信度。这些网络不仅预测错误;他们对自己不正确的输出很有信心。这显然是有问题的:想象一下,在教一个犹豫地回答 2×4=6 的学生和一个自豪地宣布答案的学生时会有什么不同。
这些对立的输入/示例可以被解释为高维点积的一个属性:当有大量像素要在其中分配和时,加权和可以更大,并且每个单独像素的变化更小。
事实上,对立的例子是网络过于线性的结果。毕竟,这种变化对(比如说)一个由 sigmoid 函数组成的网络几乎没有影响,因为在大多数地方,perbutations 的影响是递减的。具有讽刺意味的是,正是这种特性——死亡梯度——导致了 ReLU 和其他倾向于敌对输入的无界函数的兴起。
文件中阐述的其他要点包括:
- 最重要的是传播的方向,而不是空间中的某一点。模型在多维空间中不存在“弱点”的口袋;相反,在对抗性输入的构建中,决定性的方向才是最重要的。
- 因为方向是最重要的,所以对立结构是广义的。由于寻找对立的输入并不归属于探索模型的预测空间,因此可以将构造方法推广到几种不同类型和架构的模型。
- 对抗性训练可以导致正规化;甚至超过了退学。训练网络识别敌对输入是一种有效的正规化形式,也许比辍学更有效。对抗性训练的正则化效果不能用例如重量衰减或简单增加来复制。
- 容易优化的模型也容易扰动。如果找到一个最佳梯度是简单的,那么计算一个有效的对抗输入也是简单的。
- 线性模型、为模拟输入分布而训练的模型和集成对对抗性输入没有抵抗力。RBF 网络是抗的。具有隐藏层的体系结构可以被训练成以不同程度的成功识别对立的输入。
越来越重要的是,走出数据集的有限和完美世界,进入不那么有序的真实世界。通过发现欺骗我们的图像识别模型的有效策略,我们可以在它们被用于更恶意的目的之前防御它们。
推荐阅读
- 解释和利用对立的例子(Goodfellow et al.)
以比本文更严格的数学方式介绍 FGSM,深入研究实证结果,并讨论理论解释和含义。 - 走向抗对抗性攻击的深度学习模型(Madry et al.) 在 FGSM 的工作基础上,开发了更复杂的对抗性示例生成方法。
- TensorFlow 教程:与 FGSM 对立的例子。在 TensorFlow 中实现 FGSM 的代码教程。
感谢阅读!
如何解决人工智能偏见
原文:https://towardsdatascience.com/how-to-tackle-ai-bias-ec39313ccacf?source=collection_archive---------27-----------------------
拥有一个有道德的人工智能对于拥有一个成功的人工智能是至关重要的。以下是如何确保你的人工智能不会导致偏见和歧视
由 Pixabay 提供
近年来,我们都看到机器学习(ML)和人工智能中的偏见的例子占据了头条,例如亚马逊的招聘算法【1】偏向男性,脸书在定向广告中指控住房歧视【2】,或者这个突出的医疗算法【3】表现出明显的种族偏见。在这里,我将向数据科学家概述数据中可能的偏差来源,如何识别和测量偏差,以及减轻偏差的方法。
偏见的来源
算法本身没有任何固有的偏见,但当出现不适当的数据时,可以学会表现出歧视性行为。以下是一些导致偏差的数据质量问题:
- 数据不足:在您的培训数据中,整体或特定少数群体的示例太少。模型准确性和强大的洞察力是非常小的数据集中的主要挑战,特别是在涉及直接影响个人的用例时,应该小心谨慎。这就是为什么面部识别算法【4】在某些人群中表现良好,而在其他人群中表现不佳。
- 数据收集实践:通过数据收集实践得到的更大的数据集在特征(列)级别上对于某些组可能没有足够的数据。您可能会发现某些组中的选择要素缺少过多的值,从而导致这些组在数据集中的表示不完整。ML 技术不太可能很好地预测代表性不足的群体,并且可能进一步加剧数据中存在的对他们的歧视。从不同来源提取数据有助于创建更加异构的数据集,因此模型的准确性更高,偏差更小。
- 历史偏见:不同群体目标分布的显著差异可能是由于数据中潜在的人类偏见。一些众所周知的例子是雇用中的歧视、贷款歧视做法或司法判决中的偏见。
仅仅因为数据中不存在受保护的或敏感的属性,并不意味着您对偏见免疫。为了评估偏倚,数据科学家应调查可能代表受保护和敏感属性的特征的使用情况。常见的、众所周知的例子包括邮政编码、体育活动、大学联系、文本文档中的某些单词(例如简历中的“执行”)、病历中的激素水平等。以上任何一项都可以用作暗示个人的种族、性别或其他受保护/敏感属性的代理。要检查代理特性,一种方法是将目标更改为受保护的属性,并相应地训练模型。精确度明显高于随机模型的模型表示泄露受保护属性信息的要素。通过检查要素的重要性,您可以直接识别数据特有的代理要素。
检测偏差
有许多不同的方法来检测关于受保护或敏感属性的偏见的存在。学术界的研究人员已经对公平和偏见提出了不同的定义,Arvind Narayanan 的这篇教程解释了每一个定义。根据使用案例,数据科学家可以选择最合适或优先的公平性定义,并检测模型预测中的偏差。以下是数据科学家在评估数据和模型偏差时应该采取的几个步骤:
- 比较不同组中某些要素缺失值的频率
- 评估数据中不同组的目标分布
- 使用教程中提到的不同测试,识别数据或模型预测中的偏差示例
偏差缓解
在 ML 流水线中有三个不同阶段的偏倚减少干预:预处理、处理中和后处理。
- 预处理技术旨在训练模型之前减少原始数据中的偏差。几个例子是用于防止歧视的优化预处理【6】,用于无歧视分类的数据预处理技术【7】和证明和消除不同的影响【8】。
- 处理中方法解决模型训练中的偏差。具有公平性约束的分类:具有可证明保证的元算法 [9]在优化过程中实施公平性约束,并且具有偏见消除器正则化器的公平感知分类器 [10]使用正则化作为减少偏见的手段。
- 后处理算法通过修改模型预测来减少偏差。关于公平和校准【11】和监督学习中的机会均等【12】改变模型预测以满足特定的公平定义。另一方面,区分感知分类的决策理论【13】假设大多数区分发生在决策边界附近,因此利用分类器的低置信度区域来减少区分。
访问受保护的或敏感的属性可能具有挑战性。它可能限于 ML 流水线中的某些阶段。如果这些特性在培训阶段是可用的,那么上面的任何缓解步骤都可能是有用的。但是,如果这些属性只对最终用户可用,例如对人力资源部门的招聘人员,后处理技术仍然可以用于模型预测。在无法访问受保护或敏感属性的情况下,数据科学家仍然可以利用缓解技术,通过识别代理特征来减少偏差。
参考资料:
[1]“亚马逊废弃了显示偏见的秘密人工智能招聘工具……”2018 年 10 月 9 日。https://www . Reuters . com/article/us-Amazon-com-jobs-automation-insight/Amazon-scraps-secret-ai-recruiting-tool-that-show-bias-against-women-iduskcn 1 MK 08g。
[2]“脸书被控在定向广告中进行住房歧视……”https://www . the guardian . com/technology/2019/mar/28/Facebook-ads-住房-歧视-收费-美国-政府-hud 。
[3]“剖析用于管理……的算法中的种族偏见”。https://science.sciencemag.org/content/366/6464/447。
[4]“面部识别是准确的,如果你是一个白人——”2018 年 2 月 9 日,https://www . nytimes . com/2018/02/09/technology/face-recognition-race-artificial-intelligence . html。
[5]“阿尔温德·纳拉亚南——YouTube。”【https://www.youtube.com/watch?v=jIXIuYdnyyk
[6] Calmon,f .,Wei,d .,Vinzamuri,b .,Ramamurthy,K. N .,和 Varshney,K. R.《防止歧视的优化预处理》。神经信息处理系统进展 30,2017。
[7]卡米兰,费萨尔和考尔德斯,图恩。无区别分类的数据预处理技术。知识与信息系统,33(1):1–33,2012
[8] M. Feldman、S. A. Friedler、J. Moeller、C. Scheidegger 和 S. Venkatasubramanian。验证和消除不同的影响。2015 年在 KDD。
[9] L. Elisa Celis,Huang,Vijay Keswani 和 Nisheeth K. Vishnoi。具有公平性约束的分类:一种具有可证明保证的元算法。《公平、问责和透明会议论文集》,FAT* '19,2019 年。
[10] T. Kamishima、S. Akaho、H. Asoh 和 j .佐久法史带有偏见消除器正则化器的公平感知分类器。数据库中的机器学习和知识发现,第 35–50 页,2012。
[11] Pleiss,g .,Raghavan,m .,Wu,f .,Kleinberg,j .,和 Weinberger,K. Q. (2017 年)。论公平与校准。神经信息处理系统进展,5680-5689 页。
12 莫里茨·哈特、埃里克·普莱斯和纳蒂·斯雷布罗。监督学习中的机会均等。神经信息处理系统进展,2016 年。
[13]卡米兰,f .,卡里姆,a .,张,X. 2012 年。区分感知分类的决策理论。在IEEE 数据挖掘国际会议论文集(ICDM 2012) 中,Zaki M. J .、Siebes A .、Yu J. X .、Webb G. I. & Wu X .(编辑)。IEEE 计算机学会,924–929
如何端到端地解决任何分类问题&选择正确的分类 ML 算法。
原文:https://towardsdatascience.com/how-to-tackle-any-classification-problem-end-to-end-choose-the-right-classification-ml-algorithm-4d0becc6a295?source=collection_archive---------9-----------------------
来源:Pixabay
我们现在知道很多机器学习算法。然而,当我学习 ML 时,我无法找到一篇涵盖机器学习所有步骤的文章,包括数据预处理,选择 ML 算法,然后针对各种分类问题缩小范围。因此我写了这篇文章,这样任何人都可以在一个地方找到所有的资源。我还在文章中介绍了各种 ML 算法的优缺点,以便您知道何时使用哪种类型的算法。您可以简单地复制粘贴本文中给出的代码模板,并应用于手头的任何分类问题。让我们开始吧:)
A .数据集下载和准备
- 从这里下载数据集。
- 关于数据集:MNIST 是一个非常著名的数据集。该数据集包含 784 列,代表一个数字的像素(每个数字由 x 轴上的 256 个像素和 y 轴上的 256 个像素组成。256 x 256 像素= 784 像素)。它有一个列标签,从 784 个像素中识别数字。
- 在下面的文章中,我们将把一个数字归类为 5 或者不是 5。因此,为了简单起见,我们将处理二元分类。此外,可以看出,大多数分类问题都是二元分类问题。多类分类(从 0 到 9 的数字分类)将在另一篇文章中讨论。
B.应用 ML 模型前的数据预处理
- 处理缺失值
- 处理非数字数据(处理分类、顺序变量和字符串)
- 特征工程和从现有特征中创建新特征。
- 仅提取有用和相关的特征:特征选择
- 移除缺失值超过特定阈值的要素
- 将数据分为训练集和测试集
- 检查阶级不平衡并解决它
- 数据的标准缩放
数据预处理程序
因为 MNIST 数据集不需要太多预处理(没有缺失值,没有字符串或分类特征/列等)。),我们采用了一个称为房屋数据集的简单数据集,并使用该数据集说明了大多数数据预处理技术。在数据集中,我们需要根据过去数据的学习来预测某人是否会违约。过去获得贷款的人的概况以及他们是否违约都被给出了。
住房数据集
房屋数据集数据预处理的完整代码如下所示:
[## shai laja-Gupta/媒体数据预处理
permalink dissolve GitHub 是 4000 多万开发人员的家园,他们一起工作来托管和审查代码,管理…
github.com](https://github.com/Shailaja-Gupta/Data-Preprocessing-for-medium/blob/master/Github Medium article/Data_preprocessing_for_Medium.ipynb)
B.1 .处理缺失值(房屋数据集)
如果我们有缺失值,那么就很难实现大多数的 ML 算法。因此,我们需要先处理它们。一种方法是使用 inputr(inputr 的工作方式类似于 fillna)。
可能有不同类型的缺失值。例如,我们可能会丢失字符串数据、丢失分类数据和数字数据。因此,我们首先分离数字和非数字列,然后使用不同的方法填充它们的 NAN 值。数字列的 NAN 值在这里使用中值填充,字符串列的 NAN 值使用‘most _ frequency’填充。
from sklearn.impute import SimpleImputercols_remove=['Name'] #col names which we wish to remove from model
X_train = X_train.drop(cols_remove, axis=1)
cols = X_train.columns #new coumns without the columns removed
X_train_numeric=X_train.select_dtypes(include=['int', 'float']).columns
X_train_non_numeric=X_train.select_dtypes(exclude=['int', 'float']).columns#joined columns numeric and non numeric
new = X_train_numeric.tolist() + X_train_non_numeric.tolist()from sklearn.impute import SimpleImputer
from sklearn.compose import ColumnTransformer
t = [('num', SimpleImputer(strategy='median'), X_train_numeric),
('cat', SimpleImputer(strategy='most_frequent'), X_train_non_numeric)]
transformer = ColumnTransformer(transformers=t, remainder='passthrough')
X_train = transformer.fit_transform(X_train) #numpy array#DataFrame constructor with new columns names and added reindex for change by original order
X_train = pd.DataFrame(X_train, columns=new).reindex(cols, axis=1)
B.2 .处理非数字数据(房屋数据集)
所有你的输入数据(X_train 或 X_test data )必须是数值型数据之后你才能做分类!然而,根据你的经验,你现在必须知道,情况不会总是这样。大多数情况下,您也会遇到非数字数据。非数字数据有三种类型:分类数据、顺序数据和字符串数据。在住宅的数据集中,作业类型是顺序数据,性别是分类数据,这里的名称是字符串数据。这些数据类型的区别在于:
- 分类/名义数据:性别:男女在这里并没有更差也没有更好。它们只是人们性别的分类。
- 序数数据:评级:变量之间有一定的顺序。超级熟练>熟练>不熟练。
- 字符串数据:名称:该数据类似于分类数据,因为名称只是标签。然而,这是有区别的。在分类变量的情况下,只有固定数量的类别。另一方面,对于名称字段,将会有许多名称,并且没有一个是相同的。
让我们看看如何处理这些数据类型:
B.2.1 .处理分类数据(变量没有任何顺序或等级,并指定不同的类别。):
我们只使用一个变量 M 来指定一个人是否是 M/F。我们在 get_dummies 中使用 drop_first=True 来做到这一点。
from sklearn.preprocessing import OneHotEncoder
onehotencoder = pd.get_dummies(X['Gender'], drop_first=True)
# Drop column non_numeric_col as it is now encoded
X = X.drop('Gender',axis = 1)
# Join the encoded dataframe to X
X = X.join(onehotencoder)
B.2.2 .处理顺序数据:(变量有等级的数据)
在“工作类型”一栏中,超级熟练>熟练>非熟练。我们可以通过给这三个标签分配一些数值来告诉机器一个类别比另一个类别好。数字越大,ML 算法对它的考虑就越好。因为我们给超级熟练者 3 分,给熟练者 2 分,给不熟练者 1 分;ML 算法会假设超级熟练>熟练>不熟练,这就是我们想要的。
X['Type of job'] = X['Type of job'].map( {'Super Skilled':3, 'Skilled':2, 'Unskilled':1})
B.2.3 .处理字符串数据
在上面的例子中,我们有字符串数据“名称”。字符串数据无法转换成数字。我们能从这个字段名中提取一些有用的信息吗?答案是否定的。(然而,如果我们在先生、小姐、夫人等名字前加上前缀。我们本可以从该领域提取一些信息,并因此对其进行处理,但是现在无法提取任何信息)。因此,我们从我们的建模 X_train 中移除该场。
#You can specify all the string columns you want to remove
cols_remove=['Name']
X = X_train.drop(cols_remove, axis=1)
B.3 .特征工程
有时,我们可以从给定的数据集创建新的要素,或者调整现有的要素以提取更有价值的信息。所有这些都需要领域知识。例如,在给定的数据集中,我们可以创建新的功能,如%年就业和信用收入%。这给出了一个想法,即一个人实际工作了多少年,他的收入有多少百分比是信用。如果根据他的收入,他有更多的信贷,那么违约的机会就更多。如果这个人一生中的大部分时间都在工作,那么他违约的可能性就较小。
X['Years employed percent'] = X['Years employed'] / X['Age']
X['Credit Income percent'] = X['Amt of credit'] / X['Income']
B.4 .仅提取有用和相关的特征:特征选择
在我们的模型中有多余和无用的特征会降低准确性。让我们看看如何对任何包含数百个变量的数据集进行特征选择。特征选择将消除你的分类模型过度拟合的问题。
尽管有许多特征选择或变量约简的方法,我们将只描述几种非常有效和流行的特征选择方法。
B.4.1 .如果需要特定数量的特性:选择 KBest 类方法。
它允许您为您的模型选择前 k 个最相关的特性(这里我们取 k=5,因此它将给出前 5 个特性)。
#apply SelectKBest to extract top 5 best features for housing dfbestfeatures = SelectKBest(score_func=chi2, k=5)
fit = bestfeatures.fit(X_train,y_train)
dfscores = pd.DataFrame(fit.scores_)
dfcolumns = pd.DataFrame(X_train.columns)
#concat two dataframes for better visualization
featureScores = pd.concat([dfcolumns,dfscores],axis=1)
featureScores.columns = ['Features','Score'] #naming the dataframe columns
print(featureScores.nlargest(5,'Score')) #print 5best features
B.4.2 .如果您只想要最相关和不相关的特征:Boruta 图
在 SelectKclass 中,您需要指定您想要的 top k 特性。但是有时候,你不知道你需要多少功能。所以你干脆用博鲁塔图。它将为您提供对您的模型很重要的所有功能。此外,它还会删除高度相关的功能,这样您将只拥有最相关的功能。
from sklearn.ensemble import RandomForestClassifier
from boruta import BorutaPy# NOTE BorutaPy accepts numpy arrays only, if X_train and y_train #are pandas dataframes, then add .values attribute X_train.values in #that case
X_train = X_train.values
y_train = y_train.values# define random forest classifier, with utilising all cores and
# sampling in proportion to y labels
from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier(n_jobs=-1, class_weight='balanced', max_depth=5)# define Boruta feature selection method
feat_selector = BorutaPy(rf, n_estimators='auto', verbose=2, random_state=1)# find all relevant features - 5 features should be selected
feat_selector.fit(X_train, y_train)# check selected features - first 5 features are selected
feat_selector.support_# check ranking of features
feat_selector.ranking_# call transform() on X to filter it down to selected features
X_filtered = feat_selector.transform(X_train)#To get the new X_train now with selected features
X_train.columns[feat_selector.support_]
[## shai laja-Gupta/媒体数据预处理
permalink dissolve GitHub 使上下文切换变得容易。阅读渲染文档,查看历史记录…
github.com](https://github.com/Shailaja-Gupta/Data-Preprocessing-for-medium/blob/master/Github MEDIUM boruta/Implementation of Boruta _ Feature selection on MNIST dataset.ipynb)
上面提到了 MNIST 数据集上的 Boruta 的完整代码。
B.5 .移除缺失值高于特定阈值的特征
如果您的列中有 85%的值缺失,该怎么办?在那种情况下你该怎么办?在这种情况下,最好删除该列。然而,有时企业坚持保留列,那么你可以要求新的数据。通常期望的阈值是多少,超过该阈值我们不能有缺失值?一般来说,该阈值预计为 25–30%。高于这个阈值时,您最好放弃色谱柱,除非客户坚持使用它,或者如果它是一个非常重要的分析参数。在这种情况下,您可以使用如上所述的估算器。
#Obtain the sum of missing values in all columns
df.isna().sum()#Find the percentage of missing values in df:
result=df.isna().sum()/len(df)#In df remove columns where missing values are more than a threshold
df = df.loc[:,result > .8]
B.6 .拆分成测试和训练数据( MNIST 数据集 )
我们将使用 train_test_split 将 train_df 分成测试集和训练集,以在对 test_df 进行预测之前测试我们模型的准确性:
X=train_df.drop('label', axis=1)
y=train_df['label']# implementing train-test-split
from sklearn.model_selection import train_test_split
X_train, X_test, y_train_full, y_test_full = train_test_split(X, y, test_size=0.20, random_state=66)#Below part is only for MNIST dataset
#For digit 5, output label=1, for any other digit output label=0
y_train=((y_train_full==5).astype(int))
y_test=((y_test_full==5).astype(int))
B.7 .检查阶级不平衡并加以解决
阶级不平衡意味着一个阶级占主导地位,而另一个阶级的例子很少。在 MNIST 数据集中,总共大约 40,000 个案例中,只有 3,060 个案例中的数字是 5。这意味着我们的 ML 算法暴露于非常少的数字为 5 的训练情况。
y_train.value_counts()
0 30540 #digit is not 5
1 3060 #digit is 5
Name: label, dtype: int64
如上图所示,我们的 MNIST 数据集中存在阶级不平衡。如何看待阶层失衡?
- 通过使用过采样增加少数类实例(在本例中为类 1,数字为 5)
- 通过使用欠采样减少多数类实例(在这种情况下是类 0,数字不是 5)。
我个人更喜欢过采样,因为它有助于保持数据的可变性。 SMOTE 算法(合成少数过采样技术)是过采样的一种。在高水平上,击打:
- 随机选择 k 个最近邻中的一个,并使用它来创建一个类似的,但随机调整的新观察。
我们要用 Python 实现 SMOTE。
from imblearn.over_sampling import SMOTE
sm = SMOTE(random_state = 42)
X_train_oversampled, y_train_oversampled = sm.fit_sample(X_train, y_train)
X_train = pd.DataFrame(X_train, columns=X_train.columns)
y_train=y_train_oversampled
pd.Series(y_train).value_counts().sort_index() #values after SMOTE
0 30540
1 30540
dtype: int64
在 SMOTE 实现之后,对于类 0 和 1,X_train 和 y_train 具有相似(在这种情况下相等)数量的值。
B.8 .数据的标准缩放
from sklearn.preprocessing import StandardScalersc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test=sc.transform(X_test)
C .选择和训练二元分类器
- 测试所有/多个分类器对训练数据的分类。
- 选择在训练数据上工作得最好的一个或多个,并检查它们在测试数据上的性能
- 尝试通过调整它们的超参数来改进那些工作得最好的分类器。
可以用于分类项目的分类器的例子包括逻辑回归、K-最近邻(KNN)、SVM、核 SVM、朴素贝叶斯、决策树分类、XGBoost 和 RandomForest 分类等等。将这些模型视为黑盒模型。你不需要知道模型背后的数学来实现它们。根据下面给出的代码,对它们进行编码是一个简单的即插即用过程。
C.1 .在各种分类 ML 算法上测试模型。
让我们在逻辑回归、K-最近邻(KNN)、SVM、核 SVM、朴素贝叶斯、决策树分类、XGBoost 和 RandomForest 分类上逐一训练我们的模型,并测试每个模型在训练和测试数据上的性能。
C.1.1 .对 MNIST 数据集应用逻辑回归
from sklearn.linear_model import LogisticRegression
lr_clf = LogisticRegression(random_state = 0)
lr_clf.fit(X_train, y_train)
训练和测试数据的 Logistic 回归表现
print('Accuracy on training set:',lr_clf.score(X_train,y_train))
print('Accuracy on test set:',lr_clf.score(X_test,y_test))
在训练集上的精度:0.9622134905042568
在测试集上的精度:0.2000000001
请注意,lr_clf.score(X_test,Y_test)等同于你的 print(classification report(Y _ test,Y_pred))。但是不需要计算 Y _ pred 这是在您实现时由库内部完成的。评分方法。
C.1.2 .在 MNIST 数据集上实现朴素贝叶斯
from sklearn.naive_bayes import GaussianNB
nb_clf= GaussianNB()
nb_clf.fit(X_train, y_train)
朴素贝叶斯在训练和测试数据上的表现
print('Accuracy on training set:',nb_clf.score(X_train,y_train))
print('Accuracy on test set:',nb_clf.score(X_test,y_test))
在训练集上的精度:0.6189259986902423
在测试集上的精度:0.200000001
C.1.3 .对 MNIST 数据集实施随机森林回归
from sklearn.ensemble import RandomForestRegressor
rf_clf = RandomForestRegressor(n_estimators = 10, random_state = 0)
rf_clf.fit(X_train, y_train)
在训练数据上测试随机森林回归性能
print('Accuracy on training set:',rf_clf.score(X_train,y_train))
print('Accuracy on test set:',rf_clf.score(X_test,y_test))
在训练集上的精度:0.9933483955468239
在测试集上的精度:0.2000000001
C.1.4 .在 MNIST 数据集上应用决策树
from sklearn.tree import DecisionTreeClassifier
dec_clf = DecisionTreeClassifier()
dec_clf.fit(X_train, y_train)
在训练数据上测试决策树性能
print(‘Accuracy on training set’,dec_clf.score(X_train, y_train))
print('Accuracy on test set:',dec_clf.score(X_test, y_test))
训练集上的精度 1.0
测试集上的精度:0 . 19986 . 188686868615
C.1.5. XGBoost:
'''Install xgboost following the instructions on this link:
[https://stackoverflow.com/questions/35139108/how-to-install-xgboost-in-anaconda-python-windows-platform](https://stackoverflow.com/questions/35139108/how-to-install-xgboost-in-anaconda-python-windows-platform). '''from xgboost import XGBClassifier
xgb_clf= XGBClassifier()
xgb_clf.fit(X_train, y_train)
XG 提升训练和测试数据的性能
from sklearn.metrics import accuracy_score
print('Accuracy score on train_data: ', accuracy_score(y_true = y_train, y_pred = xgb.predict(x_train).round()))
print('Accuracy score on test_data: ', accuracy_score(y_true = y_test, y_pred = xgb.predict(x_test).round()))
训练数据的正确率得分:0.9498511904761905
测试数据的正确率得分:0。36986.96666666661
C.1.6. 尝试合奏
集成意味着不使用单一模型,而是利用多个模型进行预测。为了做出每个预测,ML 集成算法考虑每个模型的输出和建议,然后做出最终预测。如果你考虑多个模型,那么所有的模型都有可能犯不同的错误。因此,当集合考虑多个模型的预测时,一个特定模型的误差对整体结果的影响最小。因此,整体预测将具有最小的误差。
c . 1 . 6 . 1 . SVM 和逻辑回归的集合
from sklearn.svm import SVC
from sklearn.ensemble import VotingClassifiervoting_clf = VotingClassifier(
estimators=[('lr', lr_clf), ('nb', nb_clf), ('decision', decision_clf)],
voting='hard')
voting_clf.fit(X_train, y_train)
使用 SVM 和逻辑回归的集合方法的性能
voting_clf.score(X_train, y_train)
voting_clf.score(X_test, y_test)
训练集上的精度为 0.9787164374590701
测试集上的精度为:0。36866.68666866667
C.1.6.2. 使用逻辑回归&决策树的集成方法
voting_clf2 = VotingClassifier(
estimators=[('lr', lr_clf),('decision', decision_clf)],
voting='hard')
voting_clf2.fit(X_train, y_train)
集成方法的性能(逻辑回归&决策树)
voting_clf2.score(X_test, y_test)
voting_clf2.score(X_train, y_train)
训练集上的精度为 0.977380952380952
测试集上的精度为:0。59676.88668686666
D .对大型数据集不太适用的分类模型
我提到下面的分类模型,因为它们对你将遇到的许多分类问题非常有用。它们在 MNIST 数据集上的实现花费了太多的时间,主要是因为 MNIST 的规模很大。当数据很大时,下面这些算法的性能太慢,因此不建议在 MNIST 中使用它们。
- k-神经网络
k-NN 在输入变量/特征/列数量较少的情况下工作良好,但在输入数量非常大的情况下会出现问题。因此,在输入变量太多的情况下(MNIST 这里有 784 个),k-NN 将不会像其他算法一样运行良好。
2.内核 SVM:内核矩阵 KK 是一个 n×n 矩阵,其中 n 是数据中实例的数量。因此,对于 MNIST 数据集,在过采样之后,我们有 60,000×784 个实例~ 470.4k,核矩阵 KK 将有(60,000×784 个实例)~ 2.2×10 个⁵元素,并且可能占用~100G 存储器。
基本上,存储核矩阵需要与数据点数量成平方比例的内存。传统 SVM 算法的训练时间也与数据点的数量成超线性比例关系。因此,这些算法对于大型数据集是不可行的。
请在下面找到如何为其他分类问题实现这些算法:
1.1。对任何分类数据集应用 k-NN
from sklearn.neighbors import KNeighborsClassifier
knn_clf = KNeighborsClassifier(n_neighbors = 5, metric = 'minkowski', p = 2)
#You can change these hyperparameters like metric etc.
knn_clf.fit(X_train, y_train)
k-NN 在 MNIST 训练和测试数据上的表现(输出耗时接近 5 小时)
print('Accuracy on training set:',knn_clf.score(X_train,y_train))
print('Accuracy on test set:',knn_clf.score(X_test,y_test))
训练集的精度为 0.974257142857143
测试集的精度为:0.200000001
1.2。MNIST 数据集上的核 SVM
from sklearn.svm import SVC
kernel_svm_clf = SVC(kernel = 'rbf', random_state = 0)
kernel_svm_clf.fit(X_train, y_train)
训练和测试数据上的内核 SVM 性能(输出所用时间接近 5 小时)
print('Accuracy on training set:',kernel_svm_clf.score(X_train,y_train))
print('Accuracy on test set:',kernel_svm_clf.score(X_test,y_test))
训练集精度 1.0
测试集精度:0.9125
D .最终确定基于绩效的分类模型
在最终确定一个模型的时候,我们需要记住准确性和时间。虽然 k-NN 比决策树和随机森林提供更好的准确性,但它需要很长时间来计算。尽管使用 GPU 在 Google colab 上工作,但我必须等待 5 个小时才能从 SVM 和 k-NN 获得输出,因此我们不会对这个数据集使用这些方法。k-NN 和 SVM 都非常适合较小的数据集。我们宁愿选择几乎和 SVM 和 k-NN 一样好的模型,并且只需几分之一的时间。
基于时间方面和准确性方面的性能,我们将选择逻辑回归和决策树的集成。我们选择创建 LR 和决策树的集合,因为这两个模型各自做得最好。你也可以尝试更多的组合,并检查模型的准确性。
还有其他参数,如调整超参数(超参数是您在每个模型中输入的参数,例如,在 k-NN 中,超参数指定 k,对于随机森林,超参数指定树的数量等。)在每个模型中,我们可以做到这一点,但我会在其他文章中介绍这一点。
如果你想知道各种机器学习算法的优缺点,以及何时使用哪种 ML 算法,它们的各种应用,请查看我下面的文章。
[## 各种分类 ML 算法的优缺点
机器学习中有很多分类算法。但是有没有想过哪种算法应该用于什么…
medium.com](https://medium.com/@shailajagupta/pros-and-cons-of-various-classification-ml-algorithms-3b5bfb3c87d6)
快乐阅读:)。希望这有所帮助:)
如何使用深度学习标记任何图像
原文:https://towardsdatascience.com/how-to-tag-any-image-using-deep-learning-84a0dc2e03c2?source=collection_archive---------10-----------------------
用 Pytorch 闪电!
麦克尔·罗杰斯在 Unsplash 上拍照
你大概有照片吧?
你可能想让那些照片自动被标记,对吗?
但是你也不想为此写一大堆代码。
继续阅读,了解如何使用深度学习和 Pytorch 用不到 60 行代码标记任何照片。最棒的是,你只需要修改大约 3 行代码就可以让它为你自己的图像工作了!
标记猴子
一个极其常见的机器学习问题是对图像进行分类或标记。影像分类是指当您有一组预定义的类别要为其分配影像时。
假设你在动物园工作,总是忘记所有猴子的名字。如果你有办法把各种猴子的图片自动分类到合适的种类,那就太好了。
你会问,为什么是猴子?因为 Kaggle 上有可用的数据集。:)这个数据集包含了 10 个不同种类猴子的大约 1400 张图片。这是白头卷尾猴的照片:
其中一只帕塔斯猴:
拥有数据是关键。对于你自己的问题,确保你有一些已经被标记的图片。我的建议是每个班至少有 50 张带标签的图片。
一旦你有了你的图片,让我们把它们正确地组织起来。您需要创建两个文件夹:“培训”和“验证”。你在训练文件夹中的照片将用于训练我们的深度学习模型。验证照片将用于确保我们的模型调整良好。
在每个文件夹中,为每个标签创建一个文件夹。对于我们的猴子,我们有 10 个标签,我们将称它们为 n0-n9。因此,我们的文件夹结构如下所示:
└── training
├── n0
├── n1
├── n2
├── n3
├── n4
├── n5
├── n6
├── n7
├── n8
└── n9
└── validation
├── n0
├── n1
├── n2
├── n3
├── n4
├── n5
├── n6
├── n7
├── n8
└── n9
然后,将适当的图像放入每个文件夹中。也许将 70%的标记图像用于训练,20%用于验证,剩下 10%用于测试。
我们还将维护从 n0-n9 到实际物种名称的映射,因此我们不会忘记:
Label, Latin Name , Common Name
n0 , alouatta_palliata , mantled_howler
n1 , erythrocebus_patas , patas_monkey
n2 , cacajao_calvus , bald_uakari
n3 , macaca_fuscata , japanese_macaque
n4 , cebuella_pygmea , pygmy_marmoset
n5 , cebus_capucinus , white_headed_capuchin
n6 , mico_argentatus , silvery_marmoset
n7 , saimiri_sciureus , common_squirrel_monkey
n8 , aotus_nigriceps , black_headed_night_monkey
n9 , trachypithecus_johnii , nilgiri_langur
构建您的模型
ResNet-50
一个非常流行的用于标记图像的神经网络架构是 ResNet-50。它很好地平衡了准确性和复杂性。这个深度学习模型我就不深入了,不过你可以在这里了解更多。对于我们的目的,只要知道它是一个非常好的图像分类模型,如果你有 GPU,你应该能够在合理的时间内训练它。如果你没有,看看 Google Colab 获得免费的 GPU 资源。
微调
当训练我们的模型时,我们将使用的技巧之一是使用微调的想法,希望能够学习如何仅用几个例子就准确地标记。
微调从已经在另一个数据集上训练过的权重开始我们的模型。然后,我们使用自己的数据进一步调整权重。作为微调起点的一个非常常见的数据集是 ImageNet 数据集。该数据集最初包含大约 100 万幅图像和 1000 个类别或标签。图像标签的广度使其成为一个很好的微调数据集。
Pytorch 闪电
除了微调,我们还可以应用其他技巧来帮助我们的深度学习模型根据我们的数据进行良好的训练。例如,使用学习率查找器来选择最佳学习率。
实现所有这些最佳实践并跟踪所有培训步骤会产生大量代码。为了避免这些样板文件,我们将使用 Pytorch Lightning 。我喜欢这个图书馆。我发现它真的帮助我很好地组织我的 Pytorch 代码,并避免愚蠢的错误,如忘记将我的渐变归零。
我们将通过编写一个实现 LightningModule 的类来使用 Pytorch Lightning。这是我们的大部分代码,然后我们将带您浏览它:
class ImagenetTransferLearning(LightningModule):
def __init__(self, hparams):
super().__init__()
# init a pretrained resnet
self.hparams = hparams
self.classifier = models.resnet50(pretrained=True)
num_ftrs = self.classifier.fc.in_features
self.classifier.fc = nn.Linear(num_ftrs, self.hparams.num_target_classes) def forward(self, x):
return self.classifier(x)
def training_step(self, batch, batch_idx):
x, y = batch
y_hat = self(x)
loss = F.cross_entropy(y_hat, y)
tensorboard_logs = {'train_loss': loss}
return {'loss': loss, 'log': tensorboard_logs} def configure_optimizers(self):
return torch.optim.Adam(self.parameters(), lr=self.hparams.lr)
def train_dataloader(self):
train_transforms = transforms.Compose([
transforms.RandomResizedCrop(224),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])])
dataset = datasets.ImageFolder(self.hparams.train_dir, train_transforms)
loader = data.DataLoader(dataset, batch_size=self.hparams.batch_size, num_workers=4, shuffle=True)
return loader
def validation_step(self, batch, batch_idx):
x, y = batch
y_hat = self(x)
loss = F.cross_entropy(y_hat, y)
tensorboard_logs = {'val_loss': loss}
return {'val_loss': loss, 'log': tensorboard_logs}
def validation_epoch_end(self, outputs):
avg_loss = torch.stack([x['val_loss'] for x in outputs]).mean()
tensorboard_logs = {'val_loss': avg_loss}
return {'val_loss': avg_loss, 'log': tensorboard_logs}
def val_dataloader(self):
val_transforms = transforms.Compose([
transforms.Resize(224),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])])
dataset = datasets.ImageFolder(self.hparams.val_dir, val_transforms)
loader = data.DataLoader(dataset, batch_size=self.hparams.batch_size, num_workers=4)
return loader
我们定义的第一个函数是 init() 。这是我们用来初始化模型的函数。我们从 Pytorch 的预训练 Resnet50 开始,对它稍加修改,使它能够预测适当的类数。您想要预测的类或标签的数量作为 hparams 的一部分作为 num_target_classes 传递。
接下来,我们有了 forward() 函数。这个很简单,我们只是通过我们的网络传递输入给它。
然后我们有了 training_step() 函数。该函数接受两个输入—批次和批次索引。在这个函数中,我们需要定义的是我们希望在每个训练步骤中发生什么。对于这个模型来说,很简单。我们通过我们的神经网络 self() 传递数据,然后计算交叉熵作为我们的损失。对于这个函数,标准的做法是返回一个包含计算损失的字典以及 Tensorboard 的日志变量。Pytorch Lightning 的一大好处是,如果你这样做了,你就可以基本上免费获得 Tensorboard 日志,这真是太棒了!
configure _ optimizer()函数用于定义您的优化器。我们将使用 Adam 优化器,并通过我们的 hparams 传递学习率。
最后,对于训练,您有 train_dataloader() 函数。这是负责加载训练数据并将其传递到训练步骤的函数。我们确保定义我们的转换来调整图像的大小,并以与我们的 Resnet 预训练相同的方式缩放它们。我们还用 RandomResizedCrop() 和 RandomHorizontalFlip() 应用了一些数据扩充。然后我用 Pytorch 的 ImageFolder() 函数加载数据。这个函数从一个文件夹中加载图像,只要这个文件夹遵循我们之前定义的结构。数据被传递给一个 DataLoader() ,Pytorch 用它来实际加载数据。在这个函数中,我们可以定义诸如 batch_size 这样的项目。我们通过 hparams 将 batch_size 作为超参数传递。
因为我们也有验证数据,所以我们可以定义完全相同的函数,除了它们不用于验证数据: validation_step() 和 val_dataloader() 。这些功能非常相似。一些区别是我们不再做数据扩充,我们的步骤返回 val_loss。
验证部分还有一个额外的功能: validation_epoch_end() 。这定义了在一个时期结束时应该对验证结果做什么。我们只是简单地返回平均验证损失。如果您愿意,也可以在培训步骤中这样做。
培养
现在我们已经完成了定义所有必要步骤的繁重工作,我们可以坐下来让 Pytorch Lightning 施展它的魔法了。首先,让我们定义我们的超参数(Pytorch Lightning 希望它是一个 argparse 名称空间):
hparams = Namespace(train_dir = <PATH TO YOUR TRAINING DIRECTORY>,
val_dir = <PATH TO YOUR VALIDATION DIRECTORY>,
num_target_classes = <NUMBER OF TAGS/CLASSES>,
lr = 0.001,
batch_size=8)
我将批处理大小设置得很小,以便与几乎任何 GPU 一起工作。
接下来,我们初始化我们的模型并进行训练!
model = ImagenetTransferLearning(hparams)
trainer = Trainer(gpus=1,
early_stop_checkpoint=True,
auto_lr_find=True,
max_epochs=50
)
真正神奇的事情发生在训练者身上。首先,我们告诉它要在多少个 GPU 上训练,然后我们让它知道如果 val_loss 没有改善,就提前停止训练,最酷的选项之一是 auto_lr_finder 。这告诉训练者使用一种算法来找到我们的模型和数据的最佳学习速率,然后使用该速率而不是我们指定的速率。注意:只有当您将 hparams 传递给模型并且 hparams 中有 lr 值时,这才有效。最后,为了避免运行太长时间,我们将 max_epochs 设置为 50。
如果你已经做了很多深度学习,你可以欣赏我们的教练清洁()。我们不需要在数据上写一个循环,所有的都是为我们准备的。如果我们将代码转移到有 8 个 GPU 的机器上,我们所要做的就是将 GPU 改为 8 个。就是这样。如果我们可以访问 TPU,Pytorch Lightning 也支持这些,您只需打开选项。在某种程度上,你绝对应该查看一下文档中教练()提供的所有伟大选项。
结果呢
那么——我们的模型在标记猴子方面表现如何?Pytorch Lightning 自动检查具有最佳验证结果的模型,对我来说,这发生在第 26 纪元。我用这段代码加载了这个模型:
model = ImagenetTransferLearning.load_from_checkpoint(<PATH TO MODEL>)
用这些代码,我对所有的验证数据进行了预测:
model.eval()
val_outs = []
truth_outs = []
for val_batch in tqdm(model.val_dataloader()):
x, y = val_batch
truth_outs.extend(y.numpy().tolist())
val_out = model(x)
val_outs.extend(val_out.detach().numpy().argmax(1).tolist())
以下是我的分类报告(使用 scikit-learn):
precision recall f1-score support 0 0.89 0.92 0.91 26
1 0.93 0.89 0.91 28
2 1.00 0.93 0.96 27
3 0.97 0.93 0.95 30
4 1.00 0.88 0.94 26
5 1.00 1.00 1.00 28
6 1.00 1.00 1.00 26
7 1.00 0.96 0.98 28
8 0.93 1.00 0.96 27
9 0.84 1.00 0.91 26 micro avg 0.95 0.95 0.95 272
macro avg 0.96 0.95 0.95 272
weighted avg 0.96 0.95 0.95 272
还不错!我的 f1 平均分数是 0.95,我在班上的最低 f1 分数是 0.91。
不过,这些都是验证结果,所以他们很可能是乐观的。为了更好地表示我们的模型有多好,我们需要对不在训练集或验证集中的图像进行预测。
我没有花时间去创建一个完整的测试集,但是我从谷歌上随机抓取了两张猴子的图片。事实上,这些图片就是这篇文章顶部的两张图片。我们的模型能够正确地预测它们!
此外,这里是用于培训的张量板图:
可以肯定地说,由于我们的深度学习模型,我们现在是猴子物种的专家。😃
自己去做!
美妙的是,你现在可以很容易地对任何你想要的图片进行分类。你所要做的就是标记一些你自己的图片,适当地组织它们(如上所述),然后修改 3 行代码。
hparams = Namespace(train_dir = <PATH TO YOUR TRAINING DIRECTORY>,
val_dir = <PATH TO YOUR VALIDATION DIRECTORY>,
num_target_classes = <NUMBER OF TAGS/CLASSES>,
lr = 0.001,
batch_size=8)
您只需要更新 train_dir、val_dir 和 num_target_classes 的值。就是这样!所以——自己去做吧,让我知道你把什么酷的东西归类了!
免费获取掌握数据科学的 11 种极其有用的资源
如何将一个数据科学项目从想法变成产品
原文:https://towardsdatascience.com/how-to-take-a-data-science-project-from-idea-to-production-8216a653011f?source=collection_archive---------22-----------------------
回答了我最喜欢的数据科学面试问题之一
万花筒在 Unsplash 上拍摄的照片
我面试过很多数据科学候选人,他们都是各种各样的角色。从初级数据科学家到雇佣我所在的数据科学团队的负责人。在我参加过的无数次面试中,有几个问题是我非常喜欢反复问的。无论是什么级别的数据科学岗位,都有一些问题是永远适用的。通常,这些问题可以准确衡量候选人对公司数据科学问题的热情,或者测试他们的实践经验。
这些最受欢迎的面试问题之一是要求候选人描述他们将数据科学项目从想法到生产的过程。了解数据科学家如何看待他们的工作流,以及他们过去对自己的工作拥有多少所有权,会很有帮助。一般来说,有更多实践经验的人对这个问题有更透彻的回答。
在我看来,数据科学家负责他们的工作,从想法构思到数据产品的推出。因此,数据科学家应该参与其中的每一步。因此,如果候选人跳过了与其他团队或利益相关者合作的步骤,我会认为他们缺乏经验。如果你正在寻找一个更初级的数据科学家,这可能是好的,但能够衡量某人的实践经验水平总是好的。
我也总是鼓励候选人从他们过去的工作中为他们描述的每一步提供例子。这可以让您更好地了解到目前为止他们在数据科学领域的经历。例如,如果你正在面试一个人来创建数据产品,而候选人给出的所有例子都来自于做网站分析,那么他们可能没有合适的工作经验。或者,他们可能需要通过学习新技能来适应这个职位。
很明显,对于如何将数据科学项目从构想变为生产,没有一个确切的正确答案。我确实认为有一些跨项目的通用步骤。根据我的经验,从开始到启动数据科学项目的步骤是:
- 获取数据
- 研究
- 数据探索
- 数据清理
- 咨询利益相关方
- 定义成功
- 创造 V1
- 反馈
- 进行调整
- 获得签署
- 传递
- 发动
- 用户反馈
在这个故事中,我将详细阐述每一个步骤需要什么。我还将提供一些来自我的数据科学经验的例子来说明这些步骤,以及为什么我认为每个步骤对于一个执行良好的数据科学项目都是至关重要的。
1.获取数据
这是一种非常简单的描述整个项目本身的方式。以正确的格式为您的项目获取正确的数据可能有几个子步骤和潜在的困难。一般来说,获取数据通常需要用 SQL 或类似 Hive 的相关语言编写一个或多个查询。这样你就可以从你公司使用的任何数据库系统中提取你需要的数据。
不同的公司使用不同类型的数据。
您的公司可能会通过用户在其网站或包含传感器的硬件上生成自己的数据。例如,您可能为一家开发新型空气湿度传感器的初创公司工作。在这种情况下,您可能希望将传感器生成的数据与其他空气湿度读数来源进行比较。您必须计算出您的分析需要多少传感器数据,以及需要多长时间。
或者,您的公司可能已经购买或被授权访问在其他地方生成的数据集。一个例子是当大学或医院生成包含遗传数据的数据集时。他们可以让公司付费访问这些数据。在这种情况下,你可能需要提前充分设计你的实验,以便说服你的公司,访问这些数据和你的结果将为他们提供实质性的好处。
现有数据集的另一个例子是医疗保健索赔数据。我之前工作的一家公司积累了一个庞大的健康保险索赔数据集,他们从几个来源购买并合并了这些数据。我们有一个带有几个标记级别的数据模型,以便能够准确地选择出我们想要的程序或条件数据。查阅数据模型和编写有效查询的过程有时可能很复杂,需要很长时间。通常需要多次迭代才能得到正确的结果。
作为上述示例的替代,您的公司可能会要求您提供自己的数据集。这可以采取许多不同的形状或形式。他们可能预算紧张,需要你免费获取数据,在这种情况下,你可以通过开源数据集来查找。许多政府数据集现在是开源的,可以用于多个部门。像人口普查数据集这样的东西可以用作基线比较或收集他们自己的见解。
无论您从哪里获得数据,拥有成功提取数据的技能都是非常重要的。
2.研究
除非你以前做过很多很多类似的分析,否则在开始一个新的数据科学项目时,你总是需要做一些研究。
这一步也可能发生在你得到数据之前,这真的取决于项目。您可能需要研究什么类型的数据可用,以及您需要什么类型的数据。但是,如果您有很多领域知识,您可能已经知道您需要什么类型的数据以及在哪里访问正确的数据集。
在这种情况下,你可以继续研究其他人是如何处理你遇到的这类问题的。这可能是你实验设计的一个很好的起点。
你应该总是独立地、批判性地评估别人所做的事情,并决定类似的事情是否对你有用。显然,数据科学工作不仅仅是盲目地遵循别人在你之前用过的配方。然而,知道以前做过什么可以让你自己做决定。如果别人已经为你做好了准备,从头开始并完全重新发明轮子是没有意义的。
根据您的统计专业知识,您可能还需要研究选择什么方法以及如何在您现有的技术堆栈中实现它。可能有一些新的闪亮的机器学习算法完全适合你的问题和数据集,但如果你没有做过任何研究,你永远不会知道。
3.数据探索
这个过程通常很难开始,至少对我来说是这样。我喜欢在笔记本上探索我的数据,比如 Databricks 或 Jupyter,这样我可以很容易地想象我在做什么。我是一个非常视觉化的人,所以图表是我数据探索过程中不可或缺的一部分。
利用这些调查作为一个机会来确认你从第一步得到的数据确实是你所期望的,这是一个好主意。从数据库中提取数据时可能会出现错误,因此请确保检查您的数据并确认您得到了想要的数据。
根据数据集的形式,您还可以进行一些汇总统计来描述数据集。您拥有的数据类型和您想要执行的分析将决定您需要进行的数据探索的类型。
您可能想看的一些例子是:
- 你的结果变量或任何其他感兴趣的变量的直方图
- 数值变量的均值、中值和众数
- 感兴趣变量的五个数摘要(最小值、第一个四分位数、中值、第三个四分位数和最大值;经常以方框图的形式显示)
- 如果您有分类变量,请查看数据在类别间的分布
- 你所有的专栏都写满了吗?
- 是否有任何缺失值?如果有,有多少?
- 数据集中是否有超出可能值范围的无效条目?
4.数据清理
从数据探索的前一步开始是数据清理。
根据您计划进行的分析类型,您的数据可能需要非常干净…或者非常干净😉
一些机器学习算法非常挑剔,要求没有缺失值。如果你正在使用一个这样的算法,你将需要决定如何获得一个好的原始数据集。
当您有缺失值时,可以使用许多不同的方法来估算数据。然而,你分析的目标会告诉你选择哪一个。可能根本就不适合估算数据,在这种情况下,您可能需要删除数据集中包含缺失值的条目。请记住,缺少值的条目可能不会均匀地分布在数据中,并且可能会扭曲您的结果。通常情况下,每种方法都有利弊,你只需要选择最适合你的项目和对你的公司重要的方法。
只要确保你预算充足的时间来做好它!
5.咨询利益相关方
有许多不同的人可能是数据科学项目的利益相关者:
- 产品团队 —负责设计和实施产品路线图。与数据科学家合作,确保数据元素符合设计和产品简介,并按时交付。
- 设计团队——负责设计公司产品,使其符合用户或顾客的需求。与数据科学家合作,确保产品设计与可用数据兼容。
- 数据工程团队 —维护 ETL(提取、转换、加载)管道,以便团队成员可以获得和使用数据。与数据科学家密切合作,确保数据的格式对公司的工作有意义。还可能涉及提高代码效率和建立数据平台。
- 产品工程团队——有时分成前端和后端工程师。他们编写构建产品的代码。与数据科学家合作,确保数据元素以他们能够用于整合到产品中的格式交付。
- 营销团队 —推广公司的产品和设计宣传,使用户和公众以期望的方式看待品牌。与数据科学家一起撰写与数据元素相关的故事,并向公众解释数据科学的工作原理。
- 业务开发团队 —为公司创造价值,通常是金钱价值。与数据科学家合作,获取他们发展合作关系、销售产品、促成交易等所需的数据。
- 领域专家 —对公司目标或产品非常重要的特定领域的专家。如果数据科学团队拥有与数据和数据科学团队正在进行的任何实验相关的专业知识,请与他们合作。
- 用户体验团队 —有时是营销或产品团队的一部分。负责衡量用户对公司生产的产品的体验。与数据科学家合作,提供用户对数据产品的反馈。这可能有助于设计未来的数据科学项目。
确保与项目中所有不同的利益相关者保持联系是很重要的。这样一来,一旦你在项目中投入了大量的时间和精力,就不会有惊喜了。你不想把你的血汗和眼泪投入到一项分析中,却发现另一个团队的某个人想在接近尾声时稍微调整一下。给自己留点挫折,在这个过程的早期和别人谈谈。
如果您正在开发一个数据产品,您需要与产品团队开会,就产品需求达成一致。方法论的可见性也会影响你解决问题的方法。
您可能需要向用户解释数据是如何生成的,在这种情况下,可能需要一种更简单的方法。相比之下,无论得到答案的过程有多复杂,准确性可能是最重要的。如果有一些解释材料将与数据产品一起发布,营销团队可能也需要参与这一对话。
您可能需要咨询数据工程或产品工程团队,以了解您的数据需要以何种格式交付。尤其是如果你的结果会显示在产品的前端。可能会有一个特定的人和你一起将产品投入生产。在过程早期与团队成员建立良好的关系是一个好主意。
如果您在公司集群上需要额外的时间或计算能力,可能需要咨询其他工程师。只有当您有一个庞大的数据集或计划进行计算密集型分析时,才有必要这样做。
在您的公司中,可能有其他利益相关者专门针对您工作的领域。应该尽早向这些领域专家简要介绍您的项目,这样您就不会错过那些对具有专业知识的人来说显而易见的东西。
例如,当我在一家医疗保健初创公司担任数据科学家时,我需要与公司的医疗总监密切合作。他不仅会确保我以医学上准确的方式构建我的分析,而且还会在项目结束时进行医学签字。
领域专家也可以指导您哪种类型的错误最不适合您的模型。根据不同的主题,1 型(假阳性)或 2 型(假阴性)错误可能特别危险。例如,如果您正在开发一个模型来筛选具有患病高风险的人,假阴性可能会导致人们没有进行疾病测试,从而没有得到诊断。如果有可用的治疗方法,那么你会希望优化你的模型,以尽量减少假阴性。
不要低估作为一名数据科学家,成为一名优秀的沟通者有多重要。你一天中相当大的一部分时间都花在和别人讨论你正在做的事情上。确保他们理解你正在使用的技术以及它们的局限性是至关重要的。
6.定义成功
数据科学项目的成功将取决于该项目的目标。然而,在开始构建分析之前,定义成功是什么样子是至关重要的。提前知道一个分析或模型的最低要求是什么是非常重要的,这样你就可以知道你的第一个版本什么时候可以分享。
如果你在前进的过程中决定成功是什么样的,你就冒着产生不符合公司需求的数据的风险。
成功度量的一个例子是,如果您决定一个预测模型在被认为可以投入使用之前必须达到一定的准确度。此外,您可能需要假阳性或假阴性低于某个预定义的水平,以便您的模型可以发布。
根据数据科学项目的类型,您可能需要让其他利益相关方参与定义您的成功指标。例如,医疗主任经常参与确定我的预测项目中不同类型的错误的可接受水平。或者,产品团队可能知道他们希望您的分析能够做什么,以及它的性能水平。
7.创造一个 V1
这是大多数人认为是“做数据科学”的过程的一部分。对我来说,实际上编写代码来创建模型和执行分析是这个过程中最快的部分。比起建立机器学习模型,我花在清理数据和做研究上的时间要多得多。我希望这个故事和这些步骤真正向您强调了数据科学项目中的所有其他部分,以及它们的重要性。
在这一步中,您需要检查的主要内容是您创建的 V1 符合或超过了您的成功标准。如果没有,那么这是一个很好的迹象,表明你要么继续努力,要么重新开始。
我不会详述创建你的分析的 V1 的过程,因为它对于你做的每个项目来说都是非常不同的。你可以在许多其他地方读到如何进行不同类型分析的例子。如果您以前从未从事过特定类型的数据科学项目,机器学习教程可以让您对工作流程有一个很好的了解。
8.反馈
尽管有时这可能是一个不舒服的过程,但获得对你工作的反馈真的很重要。接受建设性的批评可以极大地改善你的项目。
我认为对每个数据科学项目至少进行一次统计审查是一个好主意,这样你可以从数据科学团队的其他成员那里获得反馈。他们可能会看你的方法和你产生的实际结果。
当寻求反馈时,你也应该准备好为你所做的选择辩护,尤其是当你认为这些选择是你分析的一部分时。如果你真的认为外部要求不是一个好主意,不要试图屈服。你有责任支持数据所讲述的故事,不要被其他人想要它说的东西所左右。
例如,可能有一个营销团队想要使用的故事,但是数据不支持。同样,产品团队可能希望您的数据产品适用于广泛的个人,但如果数据覆盖范围不够好,您可能需要推后并解释为什么不可能。
在发布数据产品或分析之前,与利益相关方一起标记这些问题是一个好主意。最好不要给任何人失望的惊喜,而是做一些专业的期望管理。
9.进行调整
根据你得到的反馈,你可能想做一些调整。这些变化或大或小,取决于收购的是什么。也许值得做更多的研究,看看一些想法是否能被采纳。如果它们不起作用,那么你至少可以说你已经研究过了。这样人们就不会觉得你忽视了他们的建议。
10.获得最终签署
一旦您整合了来自数据科学团队和其他利益相关方的反馈,您可能需要获得最终签准。这取决于你正在从事的数据科学项目的类型,以及谁可能需要给你最终的许可。
如果你一直让每个人都知道你的进展,你可能不需要任何人的签字。或者,您可能需要数据科学团队的负责人批准您发货。或者你可能更感激其他团队的人。
正如我之前提到的,在我之前的一份数据科学工作中,我需要在运送任何医疗保健数据科学产品之前获得医疗总监的签字。
10.完成 V1 并以要求的格式交付
一旦你完成了所有的检查和平衡,你就可以按照要求的格式完成你的数据元素了。
同样,这取决于你正在进行的项目类型,你可能需要运送什么。这可能就像创建一个产品工程团队可以指向的数据表一样简单。或者,它可能涉及与数据和产品工程团队合作,在公司网站上实现实时机器学习模型。此外,您可能需要与营销团队合作,创建他们启动项目所需的其他数据元素。
11.发动
这是容易的部分,尽管有时是最令人头疼的部分。你可以把你的宝宝放到外面的世界,看看它是如何被接受的。有时会有大量的宣传和巨大的流量高峰,其他时候更多的是一个软发布,选择用户能够看到你创造了什么。无论哪种方式,你把你的工作放在那里。感觉你的数据元素被利用了,你的努力是值得的,这总是很好的。
所以祈祷你的发射成功吧😅
12.用户反馈
我知道我说过这些步骤将从想法到生产,但我只是想我会在最后偷偷把这最后一个放在这里。尽管从技术上来说,获得用户反馈是在发布之后,但我仍然认为让数据科学家参与进来是至关重要的。
如果我们是设计和创造数据产品的人,我们真的需要知道公众对它们的看法。根据您公司的工作流程,反馈可能会通过数据分析师、产品团队或用户体验团队进行过滤。
总的来说,我对用户反馈的建议是:
- 忽略那些讨厌的评论。互联网是一个可怕的地方!
- 考虑/接受/回应建设性的批评。即使你发现你不同意,如果人们已经花时间建设性的,这是一个好主意,如果你能与他们接触。这可能取决于你工作的公司的政策。您的回复可能需要由营销团队或公关人员首先处理。
- 享受任何对你有利的事情。你为你的成功努力工作。当用户伸出手说谢谢的时候总是很好的。它能让你感到真正的被欣赏。你也可能从你的队友那里获得一些内部的荣誉。所以享受你的劳动成果吧。
…开始研究 V2
数据科学家的工作永远不会结束。根据我的经验,项目通常是一个迭代的过程。你的数据产品或分析不可能第一次就完美无缺。然而,事情不需要完美才能投入生产,他们只需要承认并记录他们的不完美。显然,你不应该发布低于标准的作品,但我会注意不要在一个不完美的世界里追求完美。数据科学用于描述我们生活的世界,总会有离群值😜
所以,花一分钟来欣赏你已经完成的工作,准备好进入 V2 吧!
结论
我希望这个故事能让你更好地了解一些数据科学工作流的样子。如果你正在考虑成为一名数据科学家,也许应该思考一下所有涉及的不同步骤,并考虑它们是否是你想要的打发时间的方式。如果你认为你会喜欢一个数据项目从想法到生产和发布的整个过程,那么也许你应该从事数据科学方面的职业。
除了数据,我的另一个爱好是绘画。你可以在 www.katemarielewis.com 找到我的野生动物艺术
[## 旧金山数据科学家的一天
数据科学家通常在工作中会做些什么?
towardsdatascience.com](/a-day-in-the-life-of-a-data-scientist-in-san-francisco-ffe32ca52d20) [## 在开始任何数据科学项目之前,你应该问自己的 7 个问题
如何成为一名负责任的数据大师
towardsdatascience.com](/7-questions-you-should-ask-yourself-before-starting-any-data-science-project-51c29093c641)
如何利用数据革命
原文:https://towardsdatascience.com/how-to-take-advantage-of-the-data-revolution-8fdf6b766ead?source=collection_archive---------44-----------------------
在过去十年中,生成和存储的数据量呈指数级增长,据估计,90%的数据是在过去两年中生成的。
不仅现在的数据比以往任何时候都多,聪明的公司也在积极投资存储和利用这些数据。作为一个有趣的代理,考虑一下 AWS(最受欢迎的云数据仓库)在过去 3 年中的收入增长了 3 倍,从 2016 年的约 120 亿美元增长到 2019 年的约 350 亿美元。
来源:Pixabay
云计算的最新发展使得所有公司都应该能够访问数量级更具可扩展性和可访问性的数据科学。这一次,我们有工具来筛选爆炸规模的数据。
我们是如何来到这里的
为了应对不断增长的数据冲击,我们看到技术在不断适应,最近,我们又迎接了大数据的挑战。
这种趋势最初始于公司使用更大的机器进行纵向扩展;最终,达到了极限,数据量倾向于迁移到完全水平的模式,在这种模式下,更多的机器比更大的机器更受欢迎。这甚至被抽象了一步,因为公司现在利用“虚拟机”而不是需要维护的直接机器。这意味着他们只为在被问到时用来回答问题的时间和机器付费。
来源:作者创作
目前,我们可以访问真正的、按需的、水平扩展的计算资源,这些资源可以将我们最复杂的查询划分为最小的部分,以快速提供我们按需的答案。它运行得如此之好,以至于亚马逊的红移和谷歌通常无法商业化(Bigquery)导致的产品缺失为雪花在短短 8 年内成为 120 亿美元的公司打开了大门。
每个人都应该使用的堆栈
云数据仓库(CDW 的)使得回答任何商业甚至工程问题变得(相对)便宜,只要你的数据在一个地方,并且是可以被查询的格式。但是 CDW 不会提供任何价值,除非你的团队有工具来协作构建查询。这是第一次,所有这些都汇集在一起,数据科学家真正有能力深入研究,但如何进行呢?
来源:作者创作
第一步是将数据放入可查询的位置,最近流行的是 E LT (提取负载转换)工具,如 Alooma 、 Stitch 和 Fivetran 。他们可以毫不费力地在一个 CDW 可以查询的地方保存来自任何 SaaS 的最新数据副本。它们与标准 E TL、相比也有不足之处,比如每次有人查询数据时,它们都需要在查询时转换数据。这样做比预先做更有出错的风险,但是它们很简单而且有效。
一旦数据处于可查询的环境中,您需要能够挖掘并获得洞察力。一种叫做数据构建工具( DBT )的产品在这个领域脱颖而出,成为真正的英雄。短短几年内,数千家公司都在使用它,这已经是指数级增长了。有充分的理由——DBT 已经完全改变了公司合作获取洞察力的方式。对于非工程师来说,这是一个稍微复杂一点的概念,但 DBT 有效地提供了一个平台,数据科学家可以使用这个平台与工程师一起合作编写和共享查询。每个查询(创建管道)都在组织内发布;因此,对于每条管道是如何建造的,有一个容易获取的记录。这样做需要通过标准的工程流程,如版本控制,从而带来一些特定的好处:
- 合作设计新管道很容易
- 度量可以被验证是正确的
- 可以构建、引用和重用查询
一旦创建了这些高质量的管道,任何人都可以查询它们,而不需要知道它们是如何构建的。
最后,一旦创建了查询,只需要对它们进行调度。这一步很容易,通常的方法是气流。
商业价值
这种新设置令人难以置信的部分是,数据科学家现在有权访问所有数据(内部或外部),并协作处理数据以发现和提供商业价值。他们可以以前所未有的规模工作,以获得过去不可能获得的洞察力…由于一切都在 SQL 中,数量级更多的人拥有正确的提问和回答问题的技能。
这确实是一个巨大的转折点——可以查询的数据量、可以获取的数据源数量以及可以进行查询的人群都发生了巨大的变化。我们可以比过去好几千倍地分析数据。想象一下这样一个世界:分析第一次可以赶上甚至超过数据增长率。
我们该何去何从?
来源:作者创作
鉴于当今的技术选择,所描述的设置可能是最好的,但它也有其局限性。它最初是为了回答一次性问题而创建的。每次提问时,这项技术都需要处理你所有的数据来再次回答它。显然,这不是最有效的方法,而且会导致比所需成本更高的成本和更慢的查询时间。此外,由于数据必须按计划加载,管道中存在延迟,因此无论何时您提出问题,您得到的答案都是关于过去的。不幸的是,真正需要实时用户流的应用程序不能像这样构建——它需要完全独立的管道。
你应该能够找到我们上面所讨论的复杂问题的答案,但是当你发现一个有意义的新见解时,你希望它是现成的。
构建高效、实时的管道(旨在与现有架构协同工作)应该比管理和维护一个拥有独立真实来源的 Kafka 装置更简单。未来不应该是一个 lambda 架构,而是一个实时可访问的数据湖,它可以从一个位置保持所有公司集成、服务和报告的最新状态。希望我们在河口建造的东西能有所帮助。
如何在监狱里教人编程(没有电脑)
原文:https://towardsdatascience.com/how-to-teach-programming-to-people-in-prison-without-computers-c455baca7f19?source=collection_archive---------32-----------------------
在没有计算机的情况下使用无电源策略教授数据科学
没有计算机,我们如何教授数据科学和编程?这在今天听起来可能有些倒退,但事实证明我们几十年来一直在做这样的事情。直到最近,我们才忘记将计算机从计算机科学中分离出来是多么的可能,甚至是多么的有利。
没有电脑(或者互联网)怎么给 监狱 的人教数据科学和编程?这是一个复杂得多的问题,回答这个问题会进入未知的领域。
Level 发送到监狱的免费印刷教育指南示例。我们正在开始一个旅程,为监狱中无法使用计算机的人创建教授数据科学和 R 语言编程的指南。(图片作者)
在级别,我们大规模地创建和分发高质量、免费、知识共享许可的教育和工作培训内容给被监禁的男性和女性。
在接下来的一年里,我们将开始分发我们的第一批编程指南,这些指南是为无法使用计算机或互联网的被监禁的学习者编写的。这个项目前所未有的方面让我们回顾过去,去发现研究人员和程序员以前是如何处理这些问题的。
我们从数据科学、数据可视化和 R 编程语言的课程开始。我们选择这个起点,是因为它可以更加有形。数据科学和数据可视化比 web 开发或 app 设计更能适应不同的环境。个别学习者可以个性化收集和分析的数据。“数据无处不在”即使在监狱里也是如此。
向被监禁的男人和女人——美国最缺乏联系的一些人——教授编程可能看起来很荒谬。但是考虑一下这个。每年,有 60 万人从州监狱和联邦监狱中被释放出来,他们的工作前景和未来都没有比被关押时更好的前景。这相当于巴尔的摩或拉斯维加斯的人口数量。每一年。超过一半的人被再次逮捕并回到监狱,每年花费我们 800 多亿美元,并在此过程中撕裂家庭和社区。许多被监禁的人渴望学习,渴望新的机会。
监狱里的人有的是时间。很多时间。和创造力。和毅力。他们所没有的是…很多东西,包括电脑、互联网和我们许多人在外面视为理所当然的自学课程。像最后一英里和 T2 解锁这样的组织在一些精选的监狱中提供非常酷的编程课程,但是这些课程只对一小部分美国监狱人口开放。新冠肺炎甚至锁定了这些机会。
我们如何将数据科学职业提供的改变生活的机会介绍给美国被监禁的人群?我们如何才能大规模地做到这一点,让全国 230 万被监禁的男女中的更多人——他们无法使用电脑或互联网——能够发现新的职业机会?尽管可能有些荒谬,但历史是将这一想法变为现实的伟大指南。
骡溪州立监狱的毕业典礼。图片来自加州惩教改造部、公共领域。
计算机科学与计算机无关,正如天文学与望远镜无关一样
我们大多数人都认为学习一项技能需要使用掌握这项技能所需的工具。学习编程需要使用计算机和互联网。但是真的吗?
有越来越多的想法,被称为不插电计算机科学,重新思考计算思维、数据素养甚至编程教学的基本性质。《不插电计算机科学理论》在 20 世纪 80 年代获得了立足点,并在 21 世纪初得到了显著发展,它非常自豪地说,我们不仅可以在没有计算机的情况下教授计算机科学,而且在许多方面,我们应该这样做。
《不插电计算机科学》最初是对教授儿童编程和计算机科学基础的不同方法的探索。如果你有年幼的孩子或花很多时间在他们身边,很明显他们不能很好地打字,也不能像我们通常教编程那样长时间坐着不动来学习编程。
Mike Fellows 和 Tim Bell 是来自地球另一端的两位志趣相投的教授和计算机科学家,他们在 20 世纪 80 年代末聚在一起,提出了一个在教孩子计算机时扔掉计算机的新想法。他们设计了游戏和活动,教孩子们思考编程的——抽象、分解、算法设计、一般化、自动化、变量、循环、条件——用绳子、纸和杯子代替屏幕时间。
不插电计算机科学的好处是立竿见影的。教师不一定要有计算机科学的学位——甚至不一定要了解它——来帮助孩子们学习计算机。学校甚至不需要有电脑。孩子们可以做他们最擅长的事情——跑来跑去,尖叫——同时实际学习计算概念,如 if / then 条件句。
事实证明,在迈克·费罗斯和蒂姆·贝尔之前很久,需求就已经成为不插电计算机科学的发明之母。在编程的最初几十年里,程序员在接触到能够执行他们代码的罕见机器之前,用笔和纸来完善和测试他们的算法。错误代价高昂。纸不是。学习编码并不是从键盘和屏幕开始的。
我们能从那些不用电脑就能理解编程核心思想的孩子身上学到什么?如果早期的编程需要笔和纸编码的漫长学徒期,我们能教今天的成年人如何成为优秀的——高收入的——程序员吗,即使他们没有计算机?不插电计算机科学是将更多不同的思想和才能带入编程领域的一条途径吗?
照片由格雷格·拉科齐在 Unsplash 上拍摄
将计算机与计算机科学分开
这句名言“计算机科学与计算机的关系,不亚于天文学与望远镜的关系”是荷兰计算机科学家埃德格·迪克斯特拉说的,但实际上是《不插电》的合著者迈克·费罗斯杜撰的。天文学和计算机科学是概念,大局观念,职业。望远镜和电脑都是工具。教授计算机科学的一个大问题是,传统的方法把学习如何使用工具放在学习概念、大图思想和应用之前。
蒂姆·贝尔进一步解释了这个比喻。“传统上,对于计算机科学,我们使用编程作为通向计算机科学的大门。学生们被告知,“注册计算机科学,你将学习一整年的编程,然后我们将开始向你展示一些你可以用它做的很酷的东西。”这有点像说‘有一种东西叫做天文学。你可能不知道它是关于什么的。相信我,真的很酷。但首先,先了解一两年望远镜。然后我们会告诉你它实际上是什么。"
这种本末倒置的方法有很多问题。其中之一是访问。如果你没有掌握它们的工具和技术,你就无法继续你的职业生涯。根据 Tim 的说法,“改变我们教授计算机科学的方式的一个重要的社会问题是,‘先学习编码/编程,然后我们会向你展示很酷的东西’的传统观点将许多看不到编码/编程意义的人排除在外。如果你能让他们看到这一点,他们就会明白这是值得学习的。”这同样适用于那些拿不到工具的人。
早在这两人开始改变计算机对孩子来说可能很难的方式之前,出于需要,成年人一直在用不插电的方法研究计算机科学。
阿达·洛芙莱斯的“伯努利数的引擎计算图”的“注释 G”的细节—第一个为在计算机上实现而发布的算法。阿达·洛芙莱斯在没有计算机的情况下编写了这个算法。公有领域(1843 年出版)。
在它们有名字之前,不插电计算机科学的原理就已经存在了
程序员 Vicki Boykis 发了一条关于她妈妈如何在前苏联学习编程的推文,促使她妈妈写了一篇名为作为一名苏联编程女性的长篇文章,记录了她如何在 70 年代末和 80 年代初学习编程。故事和视觉效果是惊人的。
“在编程课上,我们以‘干’的方式学习编程:使用纸、铅笔和橡皮擦。事实上,这种方法非常重要,以至于忘记带铅笔的学生会被送到主办公室去要一支……我们的老师曾经去过一周的“实践工作和课程开发”,每隔一段时间就去一家拥有更先进机器的严肃的 IT 商店。当时重算力在 ES 系列,苏联集团国家生产。这些机器是 IBM 360 的复制品。他们用穿孔卡片和穿孔纸带工作。她会带回来成吨的论文,上面有打印的代码和调试注释,供我们在课堂上学习……在用铅笔和纸进行了两年半的严格学习后,我们进行了六个月的练习。”
程序员 Alvaro Videla 的一条推文谈到了 20 世纪 60 年代的乌拉圭程序员,他们在纸上写了整整一周的程序,然后乘渡船去阿根廷测试他们的程序,那里是离电脑最近的地方。在早期,年轻的程序员无法使用计算机来运行他们的代码。“计算机是用来执行程序的,而不是编辑文本的”一位程序员这样说道,他是根据最初的“干”法学习技能的,在黄色的法律便笺簿上写字。
再往前追溯到 19 世纪 40 年代,我们可以看看第一位程序员阿达·洛芙莱斯,她因在查尔斯·巴贝奇的机械通用计算机——分析引擎上的工作而闻名。Ada 编写了世界上第一个算法而没有使用过计算机。当然,在开始的时候,没有电脑。是人们发明了电脑,而不是相反。很明显,我们可以在没有计算机的情况下教授编程、计算机科学和编码。
Haathi Mera Saathi(我的大象朋友)用游戏板教印度农村的孩子编程。请注意循环周围的{和}符号。这些符号后来被孩子们在用 Java 打字时使用。图片经作者许可使用,鸣谢安玛奇实验室。
不插电在数字鸿沟的两边都起作用
这是一项关于印度农村儿童的有趣研究,名为大象和嵌套循环的:如何向印度农村的年轻人介绍计算。使用大象(代表性的,而不是真实的)是因为许多孩子可能没有见过计算机,但熟悉驯象师给大象下达指令的想法。嵌套循环是编程中的一个概念,指的是作为更大的重复模式的一部分的重复模式。
“虽然我们都在努力摆脱技术控制我们(而不是我们控制它)的感觉,但我们也必须认识到,全球穷人在设计决策方面没有发言权。他们不与那些制造技术的人一起参与对话、公司、会议或论坛,这些技术运行着他们申请政府拨款、网上银行、甚至与家人交流和观看娱乐节目所需的系统。随着他们沦为接受者而非生产者,我们觉得找到改变这种状况的方法并帮助他们成为创造者尤为重要。”[1]
女孩们在玩 Haathi Mera Saathi(我的大象朋友)棋盘游戏。图片经作者许可使用,署名安玛奇实验室。
研究人员的游戏名为 Haathi Mera Saathi(我的大象朋友),被证明是一种有效的方法,可以将孩子们从没有计算机经验的状态带到他们在基于 Java 的环境中创建交互式应用程序的状态。研究人员确定了几个可行的成功关键。
一个是在学习编码的早期阶段对物理和有形的需求。孩子们有时分不清左右,所以他们都是从在一个大的物理游戏板上练习动作开始的。然后他们移动到一个小的纸质游戏板上,上面有被映射成实际编程代码的小块和指令。然后他们转向 Java 处理。身体上的表现对于在孩子们的脑海中描绘真实发生的事情是至关重要的。当孩子们打字的时候,他们知道他们在打什么,或者它代表什么,回想这些想法的物理的,有形的表现。
来自 Scratch 编程语言的示例代码,由 griffpatch 进行的非欧几里德柠檬抓取实验的一部分。
成功的另一个可行的关键是使用本地化的、可理解的隐喻。在西方,一种流行的入门编程语言是由麻省理工学院开发的 Scratch ,我在 code.org 的上使用了很多。Scratch 是一种基于块的语言,孩子们可以理解。他们可以查看物理块(不像木块,而是自包含的代码块)并理解发生了什么。孩子们用 Scratch 制作卡通舞蹈和音乐循环,以及许多其他有趣的东西。像是真的心灵弯曲非欧几里得的柠檬抓取实验。
“麻省理工学院的 Scratch 是迷你语言最著名的例子之一,体现了面向学习者的环境提供丰富的图形编程环境的建构主义理想。它的界面易于学习,但我们认为,通过让它变得不那么抽象、更加具体,我们有很大的空间来创造进一步降低门槛的学习环境,尤其是对第三世界的年轻人来说。”[2]
研究人员需要比 Scratch 更基础的东西来让印度的农村青年理解编程的基本思想。取而代之的是,他们使用大象、树木和食物的剪纸,然后使用包含有用编码符号的基本指导卡。而且成功了。
最近的另一项研究叫做挠还是不挠?:一个对照实验,比较插上和未插上的第一节编程课将两组 8 到 12 岁的小学生配对。与大象和嵌套循环的研究不同,这项研究中的研究人员与参与儿童一起工作,他们在访问计算机或理解如何使用计算机方面没有问题。相反,这项研究的研究人员质疑何时是将计算机引入儿童计算机科学教育的合适时机。
一组孩子接受了 4 周的非插头计算机科学课程,而另一组接受了 4 周的传统插头计算机科学课程。然后两组都接受了 4 周的 Scratch 编程课程。
“八周后,两组学生对编程概念的掌握没有差别。然而,从不插电课程开始的那一组对他们理解概念的能力更有信心——他们表现出更好的自我效能信念。此外,第一组不插电的孩子使用了更多的刮擦块。[3]
有几十个 Scratch blocks,它们属于运动、外观、声音、事件、控制、传感、运算符和变量等类别。正如你所想象的,孩子们可以很好地完成一部分积木,尤其是在开始的时候。学习了不插电计算机科学的孩子们首先继续探索更广泛的不同类型的积木,并且更有信心这样做。
《从无到有》或《不从无到有》中可操作的发现是,从无插头教学策略开始可以导致对编程概念更细致入微的理解,即使是在经常接触技术的小学学习者中。数字鸿沟两边的孩子和成年人都可以从离线工作中受益,学习对以后计算机科学职业生涯至关重要的概念。
Alex Wright 授权使用 Adobe Stock 的图片。
那么,向监狱里的人教授数据科学和编程是怎么回事呢?
所有这些都是历史和研究中的一个很好的练习,但并没有明确回答更难的问题。我们到底该如何利用这种重构的思维来支持地球上一些最缺乏数字连接的学习者——被监禁的美国人——在使用数据科学、计算思维、计算机科学和编程的高薪职业中获得立足点?
在层面上,我们通过美国邮政直接向监狱中的人发送小册子。这样做,我们可以接触到甚至被单独监禁和最大限度安全保护的美国人——那些永远不会被允许参加监狱教育或职业培训课程的囚犯。所以我们必须使用印刷纸。没有覆盆子酱。没有微生物。没有,除了印刷纸什么都没有。纸里没有订书钉。甚至不是白纸(是的,真的)。
在新冠肺炎期间,全国大部分监狱的非必要项目——包括大学课程和大多数其他教育课程——已经暂停,以防止新冠肺炎病毒在监狱内外的传播。许多被监禁的人一天 23 小时被关在牢房里,与传统教育或职业培训课程隔绝。甚至在新冠肺炎之前,没有被监禁的男人和女人可以去的计算机实验室。
所以这些小小的纸质指南是我们的媒介。现在的问题已经简化为这样一个问题——我们能在多大程度上通过不插电计算机科学培训来指导没有电脑的成年人?我们能给计算思维一个基本的介绍吗?我们真的能进入编程吗?如果有,那看起来像什么?学习者如何检查自己的作业?他们如何去调试他们的代码?
下面是我们从之前的研究中学到的东西,在这个故事的前面有所总结:
- 没有计算机也可以教授计算机科学
- 使用实际的、有形的陈述和经验
- 使用本地化的、与社会相关的例子和隐喻
- 关注在没有计算机的情况下学习计算机科学的优势(即使它们看起来像劣势)
此外,以下是我们从过去与被监禁的男性和女性打交道的经历中学到的经验:
- 被监禁的人有很多时间和毅力
- 激发每个学习者的创造力
- 慢慢开始,假设尽可能少的事情
- 永远不要低估人类意志的力量
巨大的挑战是,本文中讨论的所有“不插电”策略都假设在某个时候,学习者会将他们的“不插电”学习与传统的“插入式”方法相结合。
蒂姆·贝尔(Tim Bell)在评论这篇文章时指出,“只是为了澄清——证据是我们应该从不插电开始,但转向实际编程计算机也很重要。”他那干巴巴的、略带厚脸皮的新西兰式幽默十分明显。是的,在某些时候,我们需要继续实际编程一台计算机。当你在监狱里的时候,这还是真的吗?我们会弄清楚的。
我们正在寻找勇敢、有远见、乐观的贡献者和合作伙伴,他们愿意接受巨大的挑战,抓住巨大的机遇。如果你有兴趣帮助或加入我们的力量,或者只是想了解我们的进展,请通过我们的网站和我们的推特与我们联系。我们很高兴能与杰西·莫斯蒂帕克合作创作这些指南,所以也请关注她的推特。我们真的很高兴能在这些未开发的机会上取得进展。
参考
[1,2] R. Unnikrishnan、N. Amrita、Alexander Muir 和 Bhavani Rao。2016.大象和嵌套循环:如何向印度农村的年轻人介绍计算技术。《第 15 届交互设计与儿童国际会议论文集》(IDC '16)。计算机械协会,纽约,纽约州,美国,137-146。
[3]费莉恩·赫尔曼斯和埃夫西米亚·艾瓦洛格鲁。2017.挠还是不挠?一个对照实验,比较插入式和非插入式编程课程。《第 12 届中小学计算机教育研讨会论文集》(WiPSCE '17)。计算机械协会,纽约,纽约州,美国,49-56。
如何在 10 分钟内教会你的熊猫 SQL
原文:https://towardsdatascience.com/how-to-teach-your-panda-sql-in-10-minutes-791ca7877d15?source=collection_archive---------32-----------------------
将 SQL 查询集成到 Pandas 数据框架的快速概述
伊洛娜·弗罗利希在 Unsplash 上的照片
对于任何数据科学家或分析师来说,以一种易于理解和有组织的方式管理数据是一项绝对必要的技能。Pandas DataFrames 允许对非常大的数据集进行清晰的视图和操作,同时它也可能是使用最广泛的 Python 包之一。SQL 可能是一个更广泛适用的工具,用于数据库管理和直接从数据库模式中的几个数据表中获取数据。
任何时候捕获、组织或操作数据时,通常都有大量的标准需要考虑。Pandas 通常需要更多的步骤,在一个多步骤的过程中利用各种打包方法和函数来清理数据。SQL 查询需要更多的全局思维,因为构造的查询只需一步就可以获取数据并根据标准进行聚合。
作为一个从 Python 开始然后转向 SQL 的人,我倾向于在清理数据时使用 Pandas,但是将 SQL 查询集成到我的数据清理过程中有助于减轻我的数据工作工具箱中的一些细微差别。让我们看看如何将查询集成到您的 Pandas 数据框架中。
导入库(sqlite3)
在 Jupyter 笔记本环境中,我首选的 SQL 查询包是“sqlite3”。让我们用 pandas 和 SQL 导入必要的库进行数据清理:
import Pandas as pd
import sqlite3
from pandasql import sqldf
如果您的系统尚未安装 pandasql,您必须通过终端安装:
pip install pandasql
基本熊猫查询
Pandas 已经支持一个非常基本的查询选项。通常我们必须对 pandas 数据帧进行切片和索引,但是我们可以通过一个简单的查询很容易地得到相同的结果。
让我们从使用传统的切片语法开始:
df2 = df1[df1[(df1[df1[‘Column1'] != df1['Column2']]) OR (df1['Column1'] == 'X')]]
请注意这个查询非常复杂,因为它需要多层切片和看似无限多的括号。
这可以很容易地用一个。“query()”方法:
df2 = df.query("Column1 != Column2 | Column1 = 'X'")
请注意我们是如何显著地精简了必要的语法,并且现在可以清楚地理解我们试图查询的是什么标准。另外,请注意“|”的使用。值得注意的是,在编写查询语法时,我们可以用“|”代替“或”,而用“&”代替“和”。句法
使用 pandasql 查询
上面的查询非常简单,因为我们只查询了两个条件。在真正的数据库管理中,会有大量的标准,充满了聚合函数、表连接和子查询。如果我们只是使用。query()方法,所以我们将创建一个函数,以更有组织的方式运行我们的查询。
我们首先创建一个 lambda 函数,它会将全局变量传递给查询对象,这样我们就不必每次运行查询时都这样做。
pysqldf = lambda q: sqldf(q, globals())
这个函数采用一个查询 q(我们将在稍后编写)和一个通用的 globals()参数来加快查询过程并节省计算开销。
现在我们要做的就是编写我们想要使用的实际查询:
q = SELECT c.Name, c.Age, c.Address, o.Income, c.Height
FROM customers c
JOIN occupation o
USING(CustomerId)
2021 年如何自学数据科学
原文:https://towardsdatascience.com/how-to-teach-yourself-data-science-in-2020-f674ec036965?source=collection_archive---------3-----------------------
第 1 部分— SQL、Python、R 和数据可视化
最近,我从化学工程专业毕业,得到了我的第一份工作,在一家科技公司担任数据分析师。我在这里记录了我从化学工程到数据科学的旅程。从那以后,当我和我学校的学生谈论这一举动时,许多人表达了同样的兴趣和同样的问题…
“你是如何从工程转向数据科学的?”
这正是我问自己的问题——我该如何行动?一年多前,同样的想法促使我开始追求数据科学家的技能。
这当然不是信息的缺乏使研究变得困难。恰恰相反,学习数据科学的资源泛滥使得很难从一般的资源中筛选出最好的资源。
如此多的选择,如此少的时间…照片由法鲁尔·阿兹米在 Unsplash 上拍摄
但首先,让我们了解一下…
什么是数据科学?
啊,这是一个很难回答的问题,让招聘经理和面试者都感到困惑。事实是,不同的公司对数据科学有不同的定义,这使得该术语模糊不清,有些难以理解。有人说是编程,有人认为是数学,还有人说是理解数据。事实证明,他们都有些正确。对我来说,我最认同的定义是这样的—
数据科学是一个跨学科的领域,它使用从数学、计算机科学和领域知识中提取的技术和理论。[1]
多学科交叉的数据科学。作者插图。
对我来说,这就是数据科学在图像中的样子。我举例说明了每个知识部分之间的界限是模糊的,以证明我的观点,即来自这些领域的知识融合在一起,形成了所谓的“数据科学”。
好吧,那我怎么学数据科学?
在这一系列的博客文章中,我想强调一下我在这个过程中参加的一些课程,以及它们的优缺点。通过这些,我希望能帮助那些和我一样的人规划他们在数据科学方面的自学之旅。这些员额是:
- 第 1 部分—用 SQL、Python 和 R(你来了!)
- 第 2 部分—数学、概率和统计
- 第 3 部分—计算机科学基础
- 第 4 部分— 机器学习(在这里阅读!)
在这篇文章中,我将重点介绍我是如何了解数据科学家所需的数据处理知识的。为了处理数据,通常需要学习
- 使用 SQL(标准查询语言)从数据库中提取数据,以及
- 清理、操作、分析数据(通常使用 Python 和/或 R)
- 有效地可视化数据。
1.使用 SQL 进行数据提取
SQL 是与数据所在的数据库进行通信的语言。如果说数据是埋藏在地下的宝藏,那么 SQL 就是挖掘宝藏原始形态的铲子。更具体地说,它允许我们从数据库中的一个或几个表的组合中提取信息。
掌握 SQL 并不困难。照片由卡斯帕·卡米尔·鲁宾在 Unsplash 上拍摄
SQL 有许多不同的“风格”,如 SQL Server、PostgreSQL、Oracle、MySQL 和 SQLite。其中每一个都略有不同,但是语法基本上是相似的,您不必担心您正在学习哪种风格的 SQL。
学习一门语言,首先要学习单词,然后再把它们组合成句子和段落。这同样适用于 SQL。
为了学习非常基本的概念(SQL 的单词或句子),我使用了data camp(SQL 简介)和 Dataquest ( SQL 基础知识)。(稍后我会详细介绍 Datacamp 和 Dataquest 的优缺点。)总的来说,这些网站通过富有启发性的练习和示例来介绍基本的 SQL 技能。涵盖的一些概念包括:
- 选择过滤和选择的位置
- 计数、总和、最大值、分组依据、聚集数据的 HAVING
- DISTINCT、COUNT DISTINCT 用于生成有用的不同列表和不同聚合
- 外部(如左)和内部连接何时/何地使用
- 字符串和时间转换
- 团结和团结所有人。
(你可能不知道这些知道,但那完全没问题!这只是你可以期望学到的东西的列表。)
然而,能够完成这些练习并没有为我成为分析师做好充分的准备。我能够理解单词和句子,但我离写出一整段文字还差得很远。特别是,一些突出的中级和高级概念,如子查询和窗口函数,要么不存在,要么没有广泛涉及,尽管它们已经在几次技术访谈中进行了测试,并且对我目前作为分析师的角色是必不可少的。这些技能包括
- 用联合处理空值
- 子查询及其对查询效率的影响
- 临时表
- 自连接
- 窗口功能,如分区、超前、滞后
- 用户定义的函数
- 在查询中使用索引来提高操作速度。
为了学习这些技巧,我主要集中在使用SQLZoo.net,这是免费的,为每个概念提供了非常具有挑战性的练习。我最喜欢的 SQLZoo 的特点是,它有测试一个综合问题中不同概念的练习。例如,一个人被提供了下面的实体关系图,并被要求基于它创建复杂的查询。
实体关系图示例。照片由奥托马钦在知识共享许可下拍摄
这与我们作为一名分析师在工作中遇到的情况非常接近——我们使用不同的技术,这些技术是我们从同一个数据库中提取信息时学会的。以下是 SQLZoo 问题'帮助台'的实体关系图。鉴于此,要求您显示 2017 年 8 月 12 日这一天的经理和每小时收到的电话数量。(自己试试 这里 !)
我使用的其他资源包括 Zachary Thomas 的 SQL 问题和 Leetcode 。
2。用 R 和 Python 进行数据操作
要开始学习数据科学所需的编程和工具,你不能离开 R 和/或 Python。它们是非常流行的编程语言,用于数据操作、可视化和争论。R vs Python 的问题是一个古老的问题,值得另发一篇帖子。我的看法?
无论您选择 R 还是 python,都没有关系——一旦您掌握了其中一个,您就可以轻松地选择另一个。
我用 python 和 R 编写代码的旅程是从 CodeAcademy、Datacamp、Dataquest、SoloLearn 和 Udemy 这样的随身代码网站开始的。这些网站为您提供按语言或软件包组织的自定进度课程。每一个都将概念分解成可理解的部分,并给用户提供开始代码来填补空白。这些网站通常会带你做一个简单的演示,然后你会有机会通过练习来实践这个概念。有些会在之后提供基于项目的练习。
今天,我将重点介绍我最喜欢的两个产品,Datacamp 和 Dataquest。
请记住,在下面你会找到课程的附属链接。这对你来说没什么,因为价格是一样的,但是如果你决定购买,我会得到一点佣金。
数据营
DataCamp 提供由该领域专业人士讲授的视频讲座和填空练习。视频讲座大多简洁高效。
作者图片
我喜欢 DataCamp 的一个部分是组织成 SQL、R 和 python 职业道路的最新课程。这消除了规划课程的痛苦——现在你只需要遵循你感兴趣的道路。 一些路径包括:
- Python/R 中的数据科学
- Python/R/SQL 中的数据分析师
- R 中的统计学家
- Python/R 中的机器学习科学家
- Python/R 程序员
就我个人而言,我是从 R 中的数据科学开始我的 R 教育的,它相当详细地介绍了 R 中的 tidyverse,这是一个非常有用的数据包集合,用于组织、操作和可视化数据,其中最著名的包括 ggplot2(用于数据可视化)、dplyr(用于数据操作)和 stringr(用于字符串操作)。
我最喜欢的 r 包。作者图片。
然而,我确实对 DataCamp 有所抱怨——那就是在完成 DataCamp 后,信息的保留性很差。使用填空格式,很容易在没有真正理解概念的情况下猜出空白处需要什么。我在平台上做学生的时候,就努力在最短的时间内完成尽可能多的课程。我浏览了一下代码,在没有理解大局的情况下填补了空白。如果我可以在 DataCamp 上重新开始学习,我会花时间更好地消化和理解整个代码,而不仅仅是要求我填写的部分。
数据请求
作者图片
Dataquest 和 DataCamp 很像。它侧重于使用代码练习来阐明编程概念。像 Datacamp 一样,它提供了各种各样的 R、Python 和 SQL 课程,尽管它没有 DataCamp 那么广泛。例如,与 Datacamp 不同,Dataquest 不提供视频讲座。
Dataquest 提供的部分曲目包括:
- R/Python 中的数据分析师
- Python 中的数据科学
- 数据工程
DataQuest 的内容一般比 DataCamp 的难度大。也有更少的“填空”形式的练习。虽然花了更长时间,但我在 DataQuest 上的知识记忆更好了。
DataQuest 的另一大特色是每月与导师通话,导师会审阅你的简历并提供技术指导。虽然我没有亲自联系导师,但事后看来,我会联系的,因为那肯定会帮助我进步得更快。
3。数据可视化
数据可视化是展示从数据中获得的洞察力的关键。在学习了使用 python 和 R 创建图表的技术技巧之后,我从 Cole Knaflic 所著的《用数据讲故事》一书中学习了数据可视化的原理。
用数字发送信息。由 Alexander Sinn 在 Unsplash 上拍摄的照片
这本书是平台不可知论。换句话说,它并不关注任何特定的软件,而是通过启发性的例子来教授数据可视化的一般原理。你可以从这本书中学到的一些关键点是:
- 理解上下文
- 选择有效的视觉效果
- 消除杂乱
- 在你想要的地方吸引注意力
- 像设计师一样思考
- 讲故事
我以为我了解数据可视化,直到我读了这本书。
在消化了这本书之后,我能够创建一个(有点)视觉上令人愉悦的图表,描述警察对黑人的暴行。这本书的一个主要学习点是把注意力吸引到你想要的地方。这是通过用明亮的黄色突出非裔美国人的线条来实现的——让人想起 BLM 的颜色——同时确保图表的其余部分保持在白色和灰色等较暗的背景中。
数据可视化技术应用于突出警察暴行的图表。图片作者。
后续步骤
在这篇文章中,我讲述了我从零开始学习编程的步骤。通过这些课程,您现在已经掌握了操作数据的必要技能!然而,还有很长的路要走。在接下来的帖子中,我将介绍
- 第二部分— 数学、概率与统计
- 第 3 部分—计算机科学基础
- 第 4 部分— 机器学习
- 第 5 部分— 构建你的第一个机器学习项目
如果您有任何问题,请随时在 LinkedIn 上与我联系。一切顺利,祝你好运!
[## Travis Tang-Gojek 的数据分析师
www.linkedin.com](http://www.linkedin.com/in/voon-hao-tang)
其他读物
如果你喜欢这篇博文,请随意阅读我关于机器学习的其他文章:
- 如何成为一名数据分析师——谷歌数据工作室的数据 Viz
- 是什么让好酒…好酒?(利用机器学习和部分依赖情节寻找好酒)
- 使用 LIME 解释黑盒 ML 模型(通过对乳腺癌数据建模直观地理解 LIME)
翻译
- 由于丹尼斯·伊尔琴科的努力,这篇文章已经被翻译成俄语。
参考
[1] Dhar,V. (2013)。《数据科学与预测》。ACM 的通信。56(12):64–73。doi:10.1145/2500499。S2CID6107147。于 2014 年 11 月 9 日从原件存档。检索于 2015 年 9 月 2 日。
如何判断您的数据库是否正在控制您的应用程序
原文:https://towardsdatascience.com/how-to-tell-if-your-database-is-controlling-your-application-256d697ce0c1?source=collection_archive---------76-----------------------
https://commons . wikimedia . org/wiki/File:penalty _ sisyph . jpg
不断增长的反模式和症状列表,没有特定的顺序。
我主要从选择端考虑这个问题,所以我确信在插入/更新端会有相当多的缺失,从 NoSQL 的角度来看也是如此。
- 实体通过数据库中生成的唯一键在整个代码库中被引用。尼克拉斯·米勒德。
- 前端代码中有 SQL 查询。
- 用户可以在前端看到表或列的名称。
- 您必须降低 API 调用带来的 SQL 注入风险。
- 您在数据库中实现了广泛的身份验证/授权模型。
- 您的数据库有一个识别单个开发人员或用户的身份验证/授权模型。
- 在隔离服务层之外的任何地方都有 SQL 查询。
- 您的 SQL 查询比葛底斯堡地址还要长。
- 您的查询类似于Rosetta Stone——也就是说,它们在一个长语句中执行多个字段的复杂映射和转换。
- 您正在使用数据库执行高级统计或运行 I/O 之外的业务算法。
- 您实现了一个精心设计的缓存系统,因为您的查询太慢/太复杂。
- 添加或删除索引会显著提高前端性能。
- 添加新的列/表需要对应用程序代码库进行大量的重构。
- 更改列/表的名称或类型需要对应用程序代码库进行大量的重构。
- 将单个表更改为多对一和一对多表需要对应用程序代码库进行大量的重构。
- 将多个表合并成一个表需要对应用程序代码库进行大量的重构。
- 改变数据库供应商需要对应用程序代码库进行大量的重构。
- 您的应用程序代码库中的对象是以数据库中的表或列来明确命名的,也就是说,不是根据它们的用途来命名的。
- 你有高质量的数据字典/模式的打印副本,在一个密封的盒子里,在一个时间锁定的保险库里,需要两个人同时转动钥匙才能打开。
- 您有存储 JSON 或 XML blobs 的表格列。
- 您有一个静态的 JSON 或 XML 版本的数据模式。
- 您有存储可执行代码的数据字段。
- 有些开发人员将大部分时间花在编写和/或优化数据库查询上。
- 你正在考虑离开你的公司,去另一家使用你在一次会议上听说的数据库技术的公司。
如何使用未标记的数据判断你的模型是否过度拟合
原文:https://towardsdatascience.com/how-to-tell-if-your-model-is-over-fit-using-unlabeled-data-4a5bddabc452?source=collection_archive---------69-----------------------
一种界定测试损失的新方法
在许多设置中,未标记的数据是丰富的(比如图像、文本等),而用于监督学习的足够的标记数据可能更难获得。在这些情况下,很难确定模型的泛化能力。大多数评估模型性能的方法仅依赖于标记数据,例如 k 倍验证。没有足够的标记数据,这些可能是不可靠的。关于模型从未标记的数据 中进行归纳的能力,我们还能了解更多吗? 在这篇文章中,我展示了 未标记的数据是如何经常被用来限制测试损失 。
劳伦·乔治在 Unsplash 上的照片
预赛
我们将考虑的任务是分类,我假设模型输出属于每个类别的输入的概率。为了简单起见,我将把讨论限制在二进制分类和交叉熵损失,尽管结果可以很容易地扩展。我们需要调用的一个关键假设是训练集被假设为从与测试集相同的分布中采样。
概念
我们最初的观察是,如果模型非常适合训练集(即获得低损失),它必须自信地和正确地预测类别标签。换句话说,预测的直方图应该是近似双峰的,一个模式在 p=0 处,一个模式在 p=1 处。
对于非常适合定型集的模型,类预测的直方图应该是什么样子。
我假设,一般来说,过度拟合的模型在未标记集上返回的预测比在训练集上返回的预测更不可信。这反过来允许我们限制未标记集合上的损失。
第一个图是使用两层神经网络制作的,在输入层有 100 个神经元,在输出层有一个神经元。为了模拟过度拟合,使用 sklearn 的 make_classification()方法在合成数据上训练该模型,该方法具有超过 10,000 个样本的 1,000 个特征。该模型对 1000 个样本进行了训练,并对其余 9000 个样本进行了测试。它很快达到 100%的训练精度和小于 0.0001 的损失。为了支持我的假设,下面是切换到未标记集时直方图的样子:
请注意,相对于训练直方图,对应于不太有把握的预测的中间区域是如何填充的。我现在描述如何使用这种行为来限制未标记集合上的损失。
获取界限
我们从损失的下限开始。为了获得它,我们假设所有预测的标签都是正确的,并且损失仅仅是由于置信度的降低而引起的。在这种情况下,交叉熵分解成两个独立的和,一个和用于 0 标签,另一个用于 1 标签:
其中 L_ min 的自变量是在未标记集合上做出的预测集合,并且我们已经假设分类阈值为 0.5。假设所有的标签都不正确,我们可以得到一个上界:
这个界限不是特别有用,但是我们引入它来为下一个界限清理符号。
由于假设训练集与未标记集具有相同的类别分布,所以当从训练集移动到未标记集时,标记分布的变化是点被错误标记的信号,并且可以用于收紧下限。设 M 为误标记点的最小数量, N 为未标记集合中的点的数量, p 为训练集合中 1-标签的概率, p^hat 为未标记集合中 1-标签的预测概率。然后我们有m = n | p p^hat|,精确的下限来自于假设是 M 最不自信的预测(即最接近 0.5 的预测)导致了错误分类。这给出了新的函数:
其中脚本 M 指的是 m 个最不自信预测的集合,脚本 M^C 指的是它的补集。除了这些界限之外,人们可以很容易地想象出一族估计,例如,通过假设它是被错误标记的 M 最有信心的预测,或者模型实际上被很好地校准,并且真实标记的概率等于它的预测概率。我现在详细说明这些想法是如何在实验中实现的。
结果
对于在我之前描述的合成数据上训练的密集神经网络模型,边界给出了 L_min = 0.05 ,以及最少 29 个错误标记的点(这些不足以使细化的边界 L_ 更紧密出来明显不同)。真正的测试损失为 1.79,因为在实践中,假设损失主要是不确定性而不是坏标签是不现实的。 然而,即使不访问测试标签,我们已经推断出测试损失至少比训练损失 、 大 600 倍,并且至少有 29 个点会被错误标记 。 在许多情况下,在使用模型做出现实决策之前,了解模型的最小损失是不可接受的,这一点至关重要。
对于执行图像分类的卷积神经网络,这些过度拟合模型的行为也得到了证实,并且基于 LSTM 的模型 I 被训练来区分自然发生的蛋白质序列和随机改组的蛋白质序列。这些结果表明我的假设可能经常成立。更多细节可以在相应的 GitHub 库中找到。
相关著作
Breck 等人建议,在数据集之间切换时,应该寻找特征分布的变化。这显然在精神上是非常相似的,但是这里我们已经明确地假设了训练和测试数据是从同一个分布中抽取的,并且关注于模型而不是数据。Kim、Feldt 和 Yoo 介绍了一种衡量单个测试点对模型的惊奇程度的方法。这个方法看起来与这里介绍的方法不同,并且相互测试我们的方法会很有趣。这里介绍的措施的一个积极的属性是它们非常容易计算和解释。最后,Grosse 等人使用以未标记点为中心的ε球周围的预测类别标记的变化作为过度拟合的度量。他们的方法的一个非常吸引人的特征是,它提供了局部的、逐点的过度拟合度量。然而,与我的方法相反,他们的方法需要一个合适的度量来评估输入的相似性,这可能不是微不足道的。在高维度中,对来自球的足够多的样本进行推断以精确测量预测标签中的方差也可能是昂贵的。 据我所知,我这里描述的方法是第一个使用未标记数据直接绑定测试损失 。
结论
我介绍了一种评估过度拟合的新方法,它利用了许多环境中大量的未标记数据。它适用于模型输出概率的分类问题,并且可以合理地假设训练集是从与未标记集相同的分布中采样的。我所描述的界限相当宽松,但是仍然可以提供关于过度拟合的潜在关键信息。此外,当从训练集移动到未标记集时,对预测直方图如何变化的视觉检查是识别过拟合的极其简单且强大的定性方式。也许在将来,同样的原理可以用来产生更复杂的边界。
相关代码可以在我的 GitHub 库中找到。
特别感谢 Rachael Creager、Jamie Gainer、Amber Roberts、Jeremy Mann 和 Nicolas Chausseau 的反馈。
参考
[1] E. Breck,N. Polyzotis,R. Steven,E. Whang 和 M. Zinkevich,机器学习的数据验证 (2019),第二届 SysML 会议论文集。
[2] J. Kim,R. Feldt,S. Yoo,使用惊奇充分性指导深度学习系统测试 (2019),IEEE/ACM 第 41 届国际软件工程会议。
[3] K. Grosse,T. Lee,Y. Park,M. Backes 和 I. Molloy,一种新的过度拟合度量及其对深度学习后门的影响,https://arxiv.org/abs/2006.06721
如何告诉你的孩子数据
原文:https://towardsdatascience.com/how-to-tell-your-kids-about-data-bf2aaf5e9838?source=collection_archive---------47-----------------------
对数据科学家与数据行比例的过度描述。照片来自 Pixabay
“数据来了!数据来了!”
最近,很少有事情比“数据”这个词的错误描述更让我反感,特别是关于它在数据科学、数据分析、大数据等方面的变体。然而,我并不指责肇事者:数据对你生活的影响正在以比努力教育大多数人它是什么以及如何将其转化为可操作的见解更快的速度增长。在这一点上,我们大多数人都意识到适当利用数据有许多有利可图的用例。反过来,企业和组织正在寻求利用这一运动,但并不总是知道它将为他们的具体业务带来哪些切实的好处。
我并不想附和任何“数据来了”之类的空想论调。数据来了!”首先,大数据已经存在,它目前的存在只是一场始于(我敢说)一个世纪前的技术革命的最近货币化的副产品,人们一直对它自动化人类任务的能力感到厌倦。虽然这是一个值得思考的问题,但我想我们都同意,许多任务总是需要人与人之间的互动,而且当数据为人们此后的决策提供基础时,它尤其强大。人工智能和机器学习是其他一些常见的误解流行词,每个人都应该找到一个准确的 概念理解,但我并不呼吁 TensorFlow 在不久的将来变得像微软 Office 一样常见。
相反,作为一个在高中的春季周末参加数学竞赛,但在 20 岁之前不会称自己精通基本数据分析的人,我认为是时候灌输数据作为数学和统计早期教育的动机了。期望每个人都渴望从事获取、流水线处理或分析数据的职业是不合理的,但更不合理的是,有如此多的人认为这个概念令人生畏且陌生。
欧几里得在坟墓里颤抖。推特@BirkkinYT。
我当然没有意识到我的初中/高中数学、统计学和计算机科学课程会转化为成为一名光荣的数据雇佣兵的幻想,无情地从大型数据集中解析出人可读或计算机可执行的信息。不幸的是,现在我不是这样了,但我想知道在我早期的课程中是否有一些更激励人的例子会让我在实现这一个人命运的道路上走得更远。同样,也许我在社会科学领域的同行会对他们领域的未来研究有更全面的了解,在这些领域,结果只与用于从相应的治疗变量推断因果关系的回归模型一样强大(我们想知道为什么经济学家现在钻研关于心理学、教育和其他领域的 T2 研究)。但最重要的是,也许会有更多的人不再对他们收到的过于精确的 Instagram 广告感到好奇,尽管他们的手机已经永久开启了 Siri 和定位服务。
不要颠倒矩阵!(除非你甚至不知道矩阵是什么——那就太酷了)
万一你想到了,不要。约翰·库克的博客文章。
作为读者的一个练习,回想一下你在学校第一次学习以下主题时的年龄:
- 解线性方程组
- 毕达哥拉斯定理
- 计算两个向量的“点积”和“叉积”
这些科目是在代数和几何之前学的。我的想法是——除了毕达哥拉斯教你在去上课/上班的路上穿过公园可能是一个不错的选择——这些主题是线性代数的基础,在缺乏数据的生活中,线性代数没有直观的位置。在考虑部署技术来分析数值数据之前,我们必须存储数据,而且我们完全是以矩阵向量的形式来存储数据,这种形式可以用线性代数和向量微积分的方法来处理。然而,有多少人继续他们的教育到足以研究这些话题呢?
这些技术缺乏现实世界的动机(除了物理学,如果那是你的事情),再加上手动实现的单调乏味,这给围绕数学的情绪带来了恐惧,并反过来挥舞着数据。如果家庭作业以分析一组特定变量的迷你项目的形式出现——也就是说,除了学生在两个不同科目上的考试成绩,或者一个笼统的“x”和“y”——使用这些技术,我认为它们更有可能给学生留下持久的印象。理想的情况是,实质性的作业应该辅以说明,总是强调“为什么?”的技术。这样做,我们可以改变关于数学和早期数据分析的叙事,从一个迎合书呆子的数字计算者的叙事,变成一个吸引那些想要严格探索和解释真实世界结果的人的叙事。
我会说,我们在几何上引入向量和多维数据方面做得非常好,这无疑有助于我早期对线性代数的理解。也就是说,需要更早地做出努力来解决这样一个事实,即向量不仅仅是平面内的线,事实上还是用于存储信息的数据结构的基础。仅仅强调这一点就可以让我们更深入地了解我们是如何在网上留下数据痕迹的。事实往往是,每当你点击或轻触一个链接或图标时,你只是简单地创建了一个新行或增加了一些与你的在线角色相对应的预先存在的条目。
假设一组学生的 SAT 数学和 SAT 语言成绩都是正态分布的
今天之前我从未见过这个,但我很喜欢它。[引用](http://lib quotes.com)
现在,考虑下面的技巧,第一个技巧你可能早在中学水平的物理科学课上就已经学会了,第二个是在高中的统计学课程中或者从一个坚持给你班级考试成绩汇总统计的老师那里学来的:
- 量化测量中的不确定性/误差
- 使用正态分布和 t 分布
第一种通常是在描述有缺陷的化学溶液/化合物/元素的背景下教授的,或者是为了解决进行一些科学实验的次优实验室环境。在回答类似“是什么导致了这个错误?”我记得在 6-8 年级的时候,我起草了一些荒谬的答案,假设人为错误的可能来源,这些答案被老师甚至教科书认为是可以接受的。然而,现实情况是,在测量和数据输入中,人为错误并不是最普遍的,而是在采样误差的错误量化和错误解释中。也就是说,我们的观察中的随机性表现源自我们只收集与特定问题相关的所有可能数据的子集的能力。
这个概念不会被进一步讨论,除非你进行统计并开始学习分布,如第二个要点所述。此外,高中统计学是在与假设检验相对应的非常具体的背景下教授的(甚至没有解释何时实际使用假设检验,即何时检验样本回归系数的显著性)。在这里,我们错过了解释一些从未在大学预科解释过的事情的机会:将模型应用于现实世界数据背后的逻辑。我的意思是,我们学习的所有关于科学过程计算的封闭表达式都是理论模型的结果。在将这些模型实际应用于真实世界的输入数据时,我们的输出只是与统计分布的期望值相对应的点估计。时至今日,我仍然对这些底层分布一无所知,也不打算上量子力学课开始了解。也就是说,我感到欣慰的是,我知道这些分布是存在的,鉴于目前对这一观点的教育状况,这不能被视为理所当然。
这又回到了这样一个想法,在大学预科阶段(大多数美国人达到的最高教育水平),我们学习的所有与 STEM 相关的东西都完全与实施有关,对结果的任何解释/探索要么作为一个简短的事后想法被提及,要么完全被忽略。如果 STEM 教育的目的是促进创新,那么鉴于目前的情况,我们非常幸运,我们拥有强大的学术和技术环境;在我看来,在创造性思维最终能够通过在企业环境中领导项目或在高等教育的高层进行研究来行使判断力之前,有各种(非货币)激励让他们放弃科学思维,转向其他领域。同样,我们只是在阻止 STEM 教育中的求知欲,直到在这些领域取得进步变得绝对必要——随着先进计算能力的可用性,这是怎么回事?
兄弟,我只是字面上报道条件样本的意思是关于感兴趣的变量
我想重申的是,虽然我提出的观点已经通过续 STEM 教育中的例子表达出来了,但我相信使用数据作为早期 STEM 教育的动机,可以教授有价值的概念,这些概念可以扩展到解释任何类型的信息。除了样本均值和相关性之外,不经常与数据打交道的人没有理由深入了解统计数据,因为样本均值和相关性本身就传达了丰富的信息。然而,现在是时候让更多的人知道这些是我们确实拥有的的,并且每一个进一步的估计都伴随着一个经常被错误报告的对我们潜在误差的量化。
对某些人来说,令人抓狂。进步,对别人来说。剧情来自海莉布鲁克斯
通过 1)忽略实现物理和统计模型所需的假设验证 2)拒绝准确描述错误的真正来源 3)在游戏化的一维和二维空间中教授数学,尽管事实上我们生活在三维空间中并且能够在甚至更多的空间中思考,我们延续了这样一种观点,即世界由静态过程所控制,其真实结果在某种程度上对公众是隐藏的。相反,通常,这些过程仍然试图被那些处于最高学术权威水平的人所理解,并且有次优的数据集。50 天前——在(半)全国范围内实施社交距离之前——的新冠肺炎预测似乎夸大了确诊病例的实际数量,你对此感到困扰吗?好吧,我可以向你保证,一个花了 25 年时间研究传染病动力学的 CDC 官员希望她也能在任何以前的时间点上获得更准确的真实病例数,并且逻辑增长模型在拟合 80 个数据点时比拟合 30 个测试率差异很大的早期数据点时具有更高的预测准确性。
可笑的是,我是统计学专业的三年级学生,直到去年夏天在我实习的数据科学办公室的一次午餐时间谈话中,我才意识到应该举起这面旗帜,这次谈话是关于学生是否应该在学习微积分之前学习线性代数(同样,绝大多数人都不选择)。此后,我甚至觉得自己没有能力表达这些抱怨,直到最近参加了多元统计和数值分析的课程,在这些课程中,我一直在实施和证明一些想法,只是为了强调一些概念,这些概念在事后看来,我可以通过更少的经验和实践工作直观地掌握。我觉得这是数据分析技术背后潜在直觉可及性的一个缩影,其中核心理解似乎不必要地隐藏在多层次的术语和符号之下。
劳动力市场肯定需要更多的数据分析师和数据科学家,大学最近推出了新的学位课程作为补充。但是,随着能够处理数字和用代码探索基于数据的问题的人数的增加,对这些问题及其解决方案的含义有机构提供的概念性理解的人数也应该增加。这方面取得进展的一个例子是创建了 AP 计算机科学原理课程,通过该课程,大学委员会试图在从实际计算中抽象出来的同时实现上述一些目标。也就是说,作为一门先修课程,它主要面向表现较好的公立学校的学生,这些学生可能已经比同龄人更有可能上大学。
显然,我不是以直接可操作的方式阐明这一点的最佳人选,我也不熟悉新的教育政策及其实施情况。我也没有提供任何数据来做这些断言,但我会让它成为一个例子(对我来说特别方便),说明我们如何在给定适当的背景信息的情况下,甚至不用深究数字就能识别概念和趋势。
TL;博士;医生
也就是说,也许是时候谈谈了。[插入结束语,巧妙地将“离题”与“回归”押韵,或许将“鸟和蜜蜂”与“Fs 和 Ts”押韵]
如何在面试中讲述你的故事
原文:https://towardsdatascience.com/how-to-tell-your-story-in-an-interview-bfbeffa3034c?source=collection_archive---------17-----------------------
回答面试中任何行为问题的五步框架
在每次面试中,通常有两种类型的问题会问每个应聘者——技术问题和行为问题。这两种类型都很容易准备,但我们经常把大部分精力放在准备技术问题上。行为问题与技术问题一样重要,如果不是更重要的话,因为它暴露了候选人的经验、沟通和软技能。面试官也在评估他们是否能看到自己与团队中的候选人一起工作。
在本文中,我将带您通过一个框架来回答您遇到的任何行为问题。回答技术问题是不同的,所以如果你对准备技术问题感兴趣,就看看我以前的一些帖子吧。
在 Unsplash 上由Christina @ wocintechchat.com拍摄的照片
行为问题通常是这样开始的…
告诉我……的时候
这些问题总是为了测试候选人如何处理某些情况,以及他们是否有意识以对团队和业务有利的方式处理问题。这与故事本身没有任何关系,所以不要为将一个完美的故事与所提的问题相匹配而烦恼。
你应该采取的第一步是确保你在进入面试前准备好几个故事。一旦你准备好了你的故事,是时候安排你的交付了。下面你会发现在面试中讲述你的故事时应该包括的五个要素。
由 Kelly Sikkema 在 Unsplash 上拍摄的照片
回答行为问题的五要素框架
1.用一句话快速总结一下
为了确保你给了面试官他们想要的东西,你应该用一句简短的总结开始你的故事,然后再详述细节。在讲述你的故事时,避免像作者写书那样增加悬念和紧张感。
举个例子,假设你被要求讲述一个你犯错误的时候。这看起来像是:
“我过去犯过的一个错误是,我把我主持的部门会议的日期搞混了”
这个一句话的总结的目的是为面试官建立一个故事,为他们接下来更长的解释做准备。
2.提供故事背后的背景
在你提供了一个简短的答案后,现在是时候扩展并给面试官提供背景信息了。你需要提供的唯一细节是导致你行动的情况。谈论问题、涉及的利益相关者、您的角色的重要性以及任何可能因该情况而处于风险中的业务影响是很重要的。
不要纠缠于次要的细节,也不要喋喋不休几分钟。保持你的故事简洁明了。
这可能看起来像:
“我正在主持一个会议,为全公司组织一次培训,这样我们就可以学习我们正在实施的新流程。新流程将改变我们在客户成功漏斗中为每位客户制作接触点的方式。我们最初把会议安排在四月底,但是由于会议的重要性,我们决定把它提前一周。我忘记更改日历上的日期了。现在会议比计划的要早,这迫使我把东西放在一起,以快速迎接新的日期。”
3.谈谈你在这种情况下的角色
既然你已经解释了问题,那就该强调你所扮演的角色了。这意味着思考你的责任是什么,以及你如何处理这种情况。
做这件事时要记住的一件重要事情是,你应该避免找借口或推卸责任——尤其是当你的面试官让你讨论一个冲突、失败或错误的时候。
另一个需要考虑的重要事情是,每个面试问题都试图评估一个特定的特质。在上面讨论冲突或失败的例子中,虽然不玩责备游戏很重要,但同样重要的是谈论你如何克服冲突,并以积极的心态处理问题或达到目标。面试官希望看到你能够对工作中可能出现的情况采取务实的态度。
这可能看起来像:
“我负责制作会议期间展示的演示文稿,让员工了解变化。我安排了我的演讲时间,以确保它能有效简单地解释所有的事情,并触及所有必要的细节。但是,当我把日期搞混的时候,我不得不很快拼凑出那份演示文稿——这意味着它没有我希望的那么完美。”
4.分享结果和成果
我认为这部分是最不重要的,因为老实说,面试官不会关心你在公司遇到的任何问题的结果。除非是他们目前正在努力解决的问题,但这些问题通常与技术问题有关。但是,将你的行动与情况和/或业务的目标联系起来,并谈论你的行动如何带来净积极结果,这仍然很重要。
这可能看起来像:
“尽管我曾梦想过一个更加完美的演示,但最终,我们还是实现了我们的目标,用一套新的客户成功协议培训了我们的团队,使销售转换率提高了 10%。所以,尽管因为我搞砸了约会而出现了极度恐慌和通宵,但我很高兴我们取得了积极的成果。”
通过像上面这样框定关于影响的解释,你强调了你的努力有益于公司和团队,而不是让自己看起来像一个超级明星。
5.分享你学到的东西
为了让你的故事产生影响,你应该以解释你从经历中学到了什么来结束。重要的是要记住,一个好的面试的目标是让你自己成为一个有成就的合格的候选人。这意味着解释错误或失败是如何激励你改善职业生活的。
这可能看起来像:
“虽然我不喜欢快速整理演示文稿,但这个错误告诉我,密切关注我的日历很重要。现在,我会优先考虑每周查看我的预定承诺,以确保我没有错过任何重要的事情。”
6.(最后一个提示)给面试官提问的机会
面试的最后一个技巧,无论是行为上的还是技术上的,是尽量保持对话。你应该准备一些可以应用于几个问题的故事。你的故事应该简短,不要看起来像是在读剧本。
有时,我甚至会省略具体细节,或者把故事放在更高的层次,给面试官一个机会问一些澄清性或探索性的问题。我甚至会引导面试官认为他/她是在通过提问来引导我了解整个故事,这些提问可以让我更深入地了解我希望涵盖的细节,比如说“……如果你愿意,我们可以谈谈我们在演示文稿……】或……中涉及的一些客户成功主题,我可以谈谈我学到的一些制作演示文稿的最佳实践捷径……”。
通常这些附加的话题会让面试官对你的经历和性格有更多的了解。对于面试官来说,过去仅仅是一个解决错误的问题,现在变成了一场教育会议。
LinkedIn 销售导航员在 Unsplash 上的照片
结论
总之,为了回答伟大的行为问题,这里是我的框架:
- 有几个故事可以应用于尽可能多的行为问题
- 用一句话快速概括这个故事,引导面试官
- 提供上下文和背景来说明你的故事的重要性
- 谈论你的角色和方法
- 解释你对这种情况的影响,以及这种情况如何对团队和业务产生积极影响
- 分享你对这种情况的了解
- 尽可能用少的句子来讲述这个故事,并努力使它成为一个双向对话
祝你好运!
如何用卡方检验分类变量之间的统计显著性关系
原文:https://towardsdatascience.com/how-to-test-for-statistically-significant-relationships-between-categorical-variables-with-chi-66c3ebeda7cc?source=collection_archive---------7-----------------------
不久前,我在为公司发布的一项调查分析市场研究数据,以评估客户对新产品创意的看法。许多变量都是分类的(即男性、女性,这些特征中哪一个最有吸引力/最没有吸引力),经过一些初步研究后,我决定独立性的卡方检验是辨别人口中的某些群体更喜欢或不喜欢某个特征的最佳方式。
然而,我注意到许多实现事后测试的教程都是用 SPSS 或 R 编写的,几乎没有 Python 的原生包。这启发我编写了一个 Python 教程,用于独立性卡方测试和事后测试,以了解哪些类别是重要的和关系方向性的(即更可能或更不可能需要某个特性)。
数据集&研究问题
为了证明这一点,我将使用的一项调查结果,8415 名美国人对他们在下个月乘坐国内航班的舒适度进行了评估。
我制作了一个有趣的可视化工具来总结调查反馈。如你所见,大多数人不会在下个月登机(63%的受访者对这个想法有些不舒服或非常不舒服)。作者照片。
他们的调查结果允许我按年龄和政治派别来划分,所以我的两个研究问题是:
- 年龄组会影响对飞行的态度吗?如果有,如何实现?
- 政治倾向会影响对飞行的态度吗?如果有,如何实现?
对独立性进行卡方检验
卡方检验工作原理的简短解释是,首先假设零假设,变量 A(即年龄)和变量 B(即 ATF)之间没有关系。根据变量的分布计算每个单元格的期望值,并与观察值进行比较。这里的假设是,观察值的任何变化都来自数据的分布,而不是任何潜在的关系。
年龄组与飞行态度的关联表。作者照片。
例如,让我们计算 18-24 岁之间选择“非常舒适”的受访者的期望值 19.76%的受访者年龄在 18-24 岁之间,12.77%的受访者表示他们对即将乘坐飞机感到非常舒服。
期望值= 19.76% x 12.77% x 501(所有观测值)= 12.64。所以在这种情况下,观察值几乎与期望值完全一致。
观察值和期望值之间的差异用于计算卡方统计量,卡方统计量与自由度一起用于确定观察值和期望值之间的差异是否显著,或者是否由采样误差引起。(点击了解卡方测试的更多细节)。
我决定先解决年龄和 ATF 之间的关系。我透视我的数据集来创建一个列联表,这是被chi2_contingency
SciPy 方法接受的格式。
import pandas as pd
import numpy as np
from scipy.stats import chi2_contingency
from scipy.stats import norm
import math# Reading in my csv with age and attitudes towards flyingraw_df = pd.read_csv(“age_flying.csv”)# Pivoting the dataframe and assigning Age as the index, Status as the column headings, and percentage of respondents as the valuespivot_df = raw_df.pivot(index=’Age’, columns=’Status’, values=’Percentage’)
此时,我的数据框架如下所示:
我没有发现比该单元的预期值特别高或特别低的地方,但是我决定进行测试以防万一。
chi2, p, dof, ex = chi2_contingency(pivot_df, correction=False)
print(chi2, '{:.10f}'.format(p))
我的输出是14.885706463917337 0.5330249996
,这意味着我的 p 值是 0.53,我未能拒绝零假设(H₀:年龄和对下个月飞行的态度之间没有关系)。
我继续我的下一个研究问题,调查政治派别和 ATF 之间是否有关系。
表明政治关系和飞行态度之间关系的数据透视表。在即兴演讲中,似乎民主党人更有可能对飞行感到非常不舒服,而共和党人在所有类别中的分布更加均匀。
我运行了上面列出的相同过程,但是这次卡方测试的输出是79.59995957590428 0.0000000002
。我的 p 值大大低于普遍接受的 0.05 阿尔法值,这意味着我们在业务!
事后测试
在这一点上,我所知道的是在政治派别和 ATF 之间有某种统计学上的显著关系。事后测试将使我能够理解哪些类别有助于实现这种意义,以及如何实现。
我的流程是:
- 对于政治派别和 ATF 的每个组合,计算观察值和期望值之间的调整标准化残差。标准化残差是 z 分数的另一个名称。调整意味着我针对列和行之间的不同频率计数进行调整。
- 计算 z 得分的 p 值,这将告诉我观察值和期望值之间的差异的可能性有多大
- 应用 p 值校正以解决在同一数据集上运行多个测试的问题,这通常会导致类型 1 错误。
计算调整后标准化残差的公式如下:
observed-Expected/sqrt(Expected x (1-(预期/行合计))x(1-(预期/列合计))。图片来自唐纳德·夏普,理论来自艾伦·阿格莱斯蒂
首先,我将数据透视表转换回常规数据框架。我这样做是因为数据透视表功能较少,而且我不能通过名称访问列或行。
observed_vals = pivot_df.reset_index(drop=True)
observed_vals = observed_vals.rename_axis(None, axis=1)
observed_vals.set_index([["Dem", "Ind", "Not_sure", "Other", "Rep"]], inplace=True)
observed_vals = observed_vals.reset_index()
observed_vals.rename(columns={"index": "Party"}, inplace=True)
接下来,我用期望值创建了一个新的 dataframe。幸运的是,chi2_contingency
方法输出了一个期望值数组。
expected_vals = pd.DataFrame(ex)
expected_vals.set_index([["Dem", "Ind", "Not_sure", "Other", "Rep"]], inplace=True)
expected_vals = expected_vals.reset_index()
expected_vals.rename(columns={"index": "Party", 0: "SW_Comfortable", 1:"SW_Uncomfortable", 2:"V_Comfortable", 3:"V_Uncomfortable", 4:"dont_know"}, inplace=True)
假设零假设的期望值表
然后,我为行方式总计和列方式总计创建了两个表。这些值是等式的(1-row marginal/n)(1-column marginal/n)*部分中的 n 。
# Creating a column-wise sum table, adding back the column with party namescol_sum = pd.DataFrame(observed_vals.sum(axis=1), columns=["count"])
col_sum.insert(0, "Party", ["Dem", "Ind", "Not_sure", "Other", "Rep"], True)# Creating a row-wise sum tablerow_sum = pd.DataFrame(observed_vals.iloc[:,1:].sum(axis=0), columns=["count"]).reset_index()
row_sum.rename(columns={"index":"Status"}, inplace=True)
row_sum 的输出示例,包含每个状态的原始计数。
此时,我已经获得了开始计算调整后标准化残差所需的所有信息(试着快速地说 10 遍)。我写了一个脚本来迭代政治归属和 ATF 的每个组合,并计算调整后的标准化残差和伴随 p 值。
我对 p 值应用了 Bonferroni 校正,这将我的 p 值阈值降低到 0.002,以拒绝零假设(0.05 / 25 比较)。当在同一个数据集上进行多个测试时(在我的例子中是 25 个),应用 p 值校正,这增加了假阳性的机会。
# Find all the unique political parties for pairwise comparison
parties = list(raw_df["Party"].unique())# Find all the unique attitudes towards flying for pairwise comparison
status = list(raw_df["Status"].unique())# Iterate through all combinations of parties and status
for p in parties:
for s in status:
observed = float(observed_vals.loc[observed_vals.Party == p][s].values[0])
expected = float(expected_vals.loc[expected_vals.Party == p][s].values[0])
col_total = float(col_sum[col_sum["Party"] == p]["count"].values[0])
row_total = float(row_sum[row_sum["Status"] == s]["count"].values[0])
expected_row_prop = expected/row_total
expected_col_prop = expected/col_total
std_resid = (observed - expected) / (math.sqrt(expected * (1-expected_row_prop) * (1-expected_col_prop)))
p_val = norm.sf(abs(std_resid))
if p_val < 0.05/25:
print(p, s, std_resid, p_val)
你们所有人可能都对双 for 循环感到畏缩,但是无论如何——它完成了工作,好吗?我将脚本配置为只打印 p 值小于校正后的 p 值的关系,以下结果在 p < 0.002 处具有统计显著性:
结论和建议
在本文中,我简要介绍了进行独立性卡方测试和事后测试的过程,主要关注技术实现。然而,我认为理解实现背后的理论对于调试和解释结果是至关重要的,所以我链接了一些我个人认为有用的资源,以便您可以在必要时查看。
让我们回到我最初的两个研究问题,看看我们挖掘出了什么结论:
- 年龄组是否影响对飞行的态度(ATF)?如果有,如何实现?否
- 政治派别会影响人们对飞行的态度吗?如果有,如何实现?是的,而且意义重大!与平均水平相比,民主党人更有可能拥有“非常不舒服”的 ATF,共和党人更有可能拥有“非常舒服”的 ATF。与平均水平相比,不确定其政治归属的人不太可能拥有“非常不舒服”的 ATF,但更有可能选择“不知道”
我发现最后一个观点非常有趣——没有强烈政治背景的人更有可能对飞行没有看法。一种可能的解释是,受访者只是轻松地回答了问题,并没有在回答中花太多心思,这导致他们选择了最中性的答案(即不确定、不知道)。
另一个更有趣的解释可能是,参与政治的人更有可能看新闻,并经常消费关于时事的媒体。由于许多媒体都在关注新冠肺炎,了解最新消息的人将会接触到更多权威人士之间的辩论,这些权威人士对疫情的最佳做法(即公共卫生和安全协议、旅行禁令)有强烈的意见。相反,那些没有强大政治背景的人可能比他们的党派同僚更少关注,因此在如何更好地处理旅行的问题上也不会有太大的分歧。
然而,在这一点上,这纯粹是我的猜测。现在由你们来计算我的假设的调整后标准化残差,并让我知道我是否正确😉
如何从假设到生产测试你的 ML 模型
原文:https://towardsdatascience.com/how-to-test-your-ml-models-from-hypothesis-to-production-7553430382a9?source=collection_archive---------19-----------------------
从第一个假设到生产中的 A/B 测试,我个人的模型测试和评估的最佳实践。
维克多·加西亚在 Unsplash 上拍摄的照片
数据科学团队的目标通常是生成预测模型(分类器、回归器等),然后用于改进公司的产品。
但是我们怎么知道新的模型会比现在的好呢?
带有适当对照组和随机排列测试的 A/B 测试可能会给我们一个很好的理解。问题是许多公司负担不起在真实场景中测试模型的费用。想象一下,如果特斯拉将在你身上 A/B 测试他们的新自动驾驶仪,你的车将与一个较弱的模型在一组。即使我们不谈论人们的生活,公司也可能经常经历表现不佳的模型带来的负面影响。
为了尽量减少负面影响,我更喜欢对 A/B 测试的模型候选人充满信心。当然,我们永远不会有 100%的信心,但这里的 4 个步骤测试我通常会在我工作的团队中实施。每一步都会增加我们对模型质量的信心。
4 步模型测试:
1.地方发展
模型开发通常可以从假设开始,比如说
“如果我们使用随机森林模型作为我们的分类器会怎么样?”
然后,一些团队成员会将这个想法作为他下周工作的任务。此时,您可能已经有了一个可用来训练和测试模型的标注数据集。因此,在时间序列数据的情况下,正确分割数据以进行交叉验证或回溯测试将是该研究人员的责任。
因此,这些数据科学家们利用该模型得出结论,交叉验证给他的平均准确率为 95%,而当前的基线模型在同一数据集上的准确率为 93%。优秀的数据科学家不会停留在这些数字上,他们会进行排列测试并计算 p 值,以了解这种准确性差异是否会因数据变化而随机出现。
提示:使用排列测试或其他你认为更适合你的特殊情况的统计测试。p 值不是“银弹”,但总是考虑获得更好性能的随机机会是有用的。
因此,我们的数据科学家得出结论,差异具有统计学意义。太好了!这意味着我们有所发现。数据科学家为管道准备了一个模型,推送他的代码,并提出拉取请求。
2.CI/CD 中的测试
我建议您实施的 ML 模型测试的第二步是作为 CI/CD 的一部分进行测试。有许多不同的方法可以实现这一点,它们都取决于您当前的架构,但主要思想是这样的:
- CI/CD 环境可以访问一些样本外数据集,而数据科学团队中的任何人都无法访问这些数据集。
- 新的模型总是以同样的方式自动测试,作者不能影响它。
- 自动计算指标。将它们显示在仪表板上是一个好主意,团队中的每个人都可以看到它。
- 在成功测试的基础上,可以接受新模型的拉式请求,以加入开发分支,并进行下一步。
您需要确保样本外数据集具有代表性,并且能够提供可靠的评估。围绕 CI/CD 测试举行一些仪式也是一个好主意,这样您的团队就不会花一整天的时间来破解样本外数据,尝试不同的东西,并调整他的模型以在这个特定数据上获得更好的性能。
在我的团队中,只有当一个人向其他团队成员证明本地研究的正确性时,这种测试才是可能的。我们还有一个监控系统,所有的队友和产品经理都会收到一封电子邮件,里面有测试结果。因此,当任何人试图滥用这种测试时,这是显而易见的。
3.阶段测试/影子测试
下一步是在类似生产的环境中测试您的模型。例如,我们将在阶段服务器上部署开发分支,并使其在与生产管道完全相同的数据上运行,唯一的区别是最终用户不会看到开发分支的结果,结果将存储在数据库中。在进行这样的实验之前,有几个问题需要回答,但最主要的是:
“我什么时候停止那个实验?”
类似于 A/B 测试,要回答这个问题,您需要计算出您期望获得的效果大小和统计功效。
为了对模型质量做出最后的结论,我建议你使用一个统计测试来保护你自己不被随机性所充斥,但是记住它不是 100%可靠的。
4.A/B 测试
上面的 3 个步骤将会让你对你的新模型充满信心。在某些情况下,A/B 测试是不可能的,因此您可以停止影子测试,一些公司可以同时试验许多不同的模型,在这种情况下,影子测试可能是不必要的,在对样本外数据模型进行测试后,可以作为 A/B 测试的一部分进行测试。
结论
数据科学通常很棘手,在模型开发过程中有许多事情会误导您。
- 永远不要 100%相信你的模型表现,使用贝叶斯思维。
- 如果您是经理/团队领导/数据科学家,请不要犹豫质疑您的团队成员报告的模型性能
- 使用统计测试来比较模型性能
感谢阅读!你如何在你的团队中处理模型测试?
如何看待数据
原文:https://towardsdatascience.com/how-to-think-about-data-28ec05a75cd2?source=collection_archive---------52-----------------------
马太·亨利在 Unsplash 上拍照
数据工程
数据工程师和数据科学家之间的真正区别——他们的思维方式
答大约 10 年前,当数据科学工作开始成为主流时,科技领域出现了大量机会。然而,大多数公司不明白这是怎么回事。在我早期的一份工作中,我经常重复听到这样的话:我们在做大数据和我们在做数据科学。因为广告上说数据科学家拿高薪,数据分析师、数据库管理员、数据工程师——所有人都想成为数据科学家;却不知道成为一个人需要什么。
这不是专业化的时代。一个人需要成为精通某一领域的通才。就像生活一样。一个人可以成为神经外科医生,还能开车。在同一个人身上发现数据工程师和数据科学家并不奇怪,但在实践中很难看到,因为这是一个太广泛的责任领域。同样,也不太可能在晚上找到一个白天开着优步的神经外科医生。
专精是为了昆虫— 罗伯特·A·海因莱因
作为一名数据工程师和数据科学家,同时也是一个挑战,那就是在这两个与数据相关的领域的知识海洋中潜水。数据工程师应该能够做基本的数据科学工作,数据科学家应该能够做基本的数据工程。软件的其他领域也是如此。在中,数据工程师应该能够做基本的前端工作等等。
话虽如此,与其说技能是所有这些领域之间的区别,不如说它是思维过程。
你怎么想并不重要,重要的是你怎么想——克里斯托弗·希钦斯
管工与否
我的一位经理曾经将数据工程与管道工程做了一个有趣的类比。数据工程师将数据从一个地方转移到另一个地方。就像烹饪用的煤气或饮用水需要一条管道从工厂输送到你家一样,数据也需要一条管道从一个系统输送到另一个系统。冒着听起来粗鲁和工程师解释的风险,我不想继续这个类比,但如果你仔细想想,这是相当真实的。
数据工程师是构建数据管道的管道工,而数据科学家是画家和故事讲述者,给原本静态的实体赋予意义——戴夫·比安科
数据工程师是水管工。但它们还不止于此。除了确保数据从一个地方传输到另一个地方,数据工程师还要确保数据的质量适合使用。
他们还评估数据将如何被使用,并在此基础上决定如何存储数据、如何最好地检索数据、处理数据等等。一些例子是在传统的关系数据库、数据仓库和 NoSQL 数据存储之间进行选择,或者在列和面向行的数据存储之间进行选择,选择任务调度器,选择数据处理基础设施。
数据工程师可能是水管工,而数据科学家是通过水管获取水并制作柠檬水的人。
阅读Robert Chang的《数据工程概论》三篇。
概率思维与确定性思维
让我们来看看数据工程师和数据科学家之间的主要区别。显然,职称不同,关键绩效指标不同,但它们肯定可以重叠。区分这两种生物的主要品质是它们思考的方式。
数据工程师考虑的是数据和承载数据的系统的移动性、严密性、可预测性、整洁性和弹性。
这两种处理数据的方法有显著的区别——例如,数据的移动应该具有确定性。如果一些数据应该从一个位置到达另一个位置,它应该。如果要对数据集进行转换以进行清理或修改,就应该进行转换。从这个意义上说,数据工程应该是可预测的、可靠的、有弹性的——确定性的。
数据科学家从获取价值、流程改进、决策、成本和预测的角度进行思考。
一个数据科学家不关心数据从一个地方到另一个地方的移动——至少不是作为工作的主要部分。数据科学家使用数据回答问题,识别模式(隐藏的或明显的),做出预测,帮助做出决策,帮助理解即使是查看相同数据的人也无法理解的事情。数据科学家处理所有这些。因此,他们的工作变成了概率性。
编后记
未来这两个领域的工作将会有越来越多的重叠。数据工程师和软件开发人员将自动化数据科学家的大量重复性工作。数据科学家将通过提升自己的技能来确保他们能够独立于数据工程师工作。未来的数据科学家或数据工程师将身兼两职,对这两个领域都有很好的理解,甚至可能更多。正如罗伯特·A·海因莱因所说——专业化是昆虫的事。
我如何用“一行代码”彻底摧毁了这个挑战
原文:https://towardsdatascience.com/how-to-think-like-a-competitive-coder-146918397a1c?source=collection_archive---------49-----------------------
编程;编排
三思而后行,编码一次——像专家一样解决“最大化游戏”问题
来源:图片由作者提供(引自 Linus Torvalds)
最近我参加了一个由hacker rank(hacker fest 2020)举办的比赛,在那里我遇到了一个问题叫做 “最大化的游戏”。 而我只用一行代码就解决了!
如何?让我给你展示一下…
我用这个问题作为例子来描述“在解决一个竞争性的编码挑战时,你应该如何思考”;如何写出更好的算法,更快。
对我来说,竞争性编码是一种艺术形式(就像模糊编程),一个人试图用最少的代码最有效地解决一个给定的问题。
通常,代码越少=效率越高
记住这一点,我将从初学者可以理解的代码开始,然后一步一步地进一步改进它,达到专业水平。每次都向你解释我的方法。
所以让我们开始吧!
问题是
先看看问题陈述:—
来源:图片由作者提供(问题截图)
正如你所看到的,你需要从奇数位置的石堆和偶数位置的石堆中挑选相同数量的石头;同时挑选不超过相应堆中可用石头数量的石头。
暂停一下,用一秒钟思考一下。
我们将构建一个名为maximum stones的函数,它将接受一个整数数组 arr, 代表每堆中的石头数量。并返回一个整数,代表您可以选择的最大宝石总数。
为了简单和更快的开发,我将使用 Python。
你认为你需要多少行代码来解决这个问题?
第一次迭代——新手方法
不要试图根据问题的类型来识别问题。可能是贪心问题,也可能是来自动态编程的问题,我们不管。让它自然地来到你身边。
如果我们完全按照问题陈述中所写的去做,我们将得到这样的代码:
来源:作者代码
不要被它吓倒。其实很简单。
代码解释
这里,我们已经预先分别在变量和 b 中计算了奇数排和偶数排中的石头数量的总和。然后,我们进行循环,直到两者之差(和 b ),在变量c 中,变为零,也就是说,直到 a == b.**
在每次迭代中,我们看到哪些桩需要修改。如果奇数位置的堆( a )有更多的石头( c > 0),那么我们将从那些堆中减去石头,否则,从偶数位置的堆中减去。
我们需要减去多少颗石头? c 颗石子的数量
在每次减法的同时,我们需要确认是否能减去整堆(ifpicks[k]-c>0);以及 c==0 与否。
很简单。对吗?
****结果:14 个测试用例中有 13 个通过(一个错误答案)
那么我们如何识别错误呢?
第二次迭代—减少代码
识别代码冗余和未使用的循环,并消除它们。
代码越少=错误越少
你自己看吧:—
来源:作者代码
代码解释
在我们的例子中, while-loop 没有任何用途,基本上只运行一次。一旦我们确定了 c、 的值,我们只需要从那些对应的桩(奇数桩或偶数桩)中减去石头。
正如你在我们之前的代码中看到的,我们在两个 for 循环中写了同样的东西两次。所以我们也可以用一个决定元素选择的条件来去除它——
**idx = range(1,n,2) if c<0 else range(0,n,2)**
****结果:没有改进(因为我们只删除了不必要的代码)
第三次迭代——重新定义问题
现在,既然你已经走了这么远,你已经掌握了我们正在做的事情的逻辑。但问题是,我们真的需要做所有这些来得到我们想要的吗?
如果你仔细思考这个问题,你会发现,我们不需要一次从一堆石头中减去一颗。事实上,我们根本不需要这么做。因为每次我们减去那些石头,我们基本上是在从一堆石头中减去。
从数学上讲,两者是等价的。
所以如果我们已经计算出了差值(abs ( c ) ,那么我们可以直接从整个数组的和 arr 中减去它。
来源:作者代码
我们可以像这样进一步简化它…
**def maximumStones(arr):
return sum(arr) - abs(sum(arr[::2]) - sum(arr[1::2]))**
所以我们在这里,作为我们最终答案的单行代码是—
sum(arr)—ABS(sum(arr[::2])—sum(arr[1::2]))
结果: 14 个测试用例中有 14 个通过(成功!)
来源:作者图片(投稿截图)
外卖—
不要一看到问题就急于解决。花几分钟思考一下,因为不是每个问题都需要你直截了当地思考。
有些问题要你跳出框框思考。全新的视角;一个重要的知识可以为你节省大量的编码和调试时间。
有几条经验法则你需要记住—
- 尽可能地减少代码以提高效率和减少错误。使用内置库,去除冗余,尽可能减少循环次数。****
- 当你不能再做了,问题仍然存在时,改变方法。不要让 而不是 依附于你现在已经编写好的程序。重新定义问题——抽象地、数学地思考。
显然,竞争性编程的内容比我在本文中所能涵盖的要多。随着你获得更多的经验,所有的提示和窍门都会来到你面前。但目前就这些了。我希望你喜欢这篇文章。
编程快乐!
你可能会喜欢的其他精彩文章—
** [## 如何在 Python 中使用数学来演奏音乐
音乐数学
towardsdatascience.com](/mathematics-of-music-in-python-b7d838c84f72) [## 值得了解的 10 个改变游戏规则的人工智能突破
过去几十年中引人入胜的想法和概念
medium.com](https://medium.com/towards-artificial-intelligence/10-game-changing-ai-breakthroughs-worth-knowing-about-b2076afc4930) [## 为什么做一个 ML 研究员或者开发者超级难?
这一认识彻底改变了我的生活
medium.com](https://medium.com/towards-artificial-intelligence/why-its-super-hard-to-be-an-ml-researcher-or-developer-67fa62fc1971) [## 我是如何用我独特的“非正式方法”赢得国家级 ML 比赛的
像数据科学黑客一样思考——你不需要遵守规则就能获胜
towardsdatascience.com](/how-i-won-a-national-level-ml-competition-with-my-unique-informal-approach-e86fd95532fd)**
如果你来自 Excel,如何看待熊猫数据可视化
原文:https://towardsdatascience.com/how-to-think-of-pandas-data-visualization-if-youre-coming-from-excel-7af9f933e212?source=collection_archive---------22-----------------------
构建熊猫数据可视化的心智模型
由 Unsplash 上的克里斯托佛罗拉拍摄的照片
读了很多关于熊猫数据可视化的教程,我仍然不能掌握它的机制。即使是创作一个简单的情节也总是需要我查看文档。
即使在运行代码并获得正确的情节后,它也不会让我有信心独自尝试。或许,我在寻找 Excel 的熟悉度。图形和数据之间的联系使用 GUI 似乎很直观。
考虑到这一点,我能以某种方式把它带给熊猫吗?
Excel 和 Pandas 中的图表
所以我做的就是在 Excel 里画一个简单的线图。考虑以下数据(在此获取)。
1980-2013 年从中国和印度移民到加拿大的人数
然后,我使用 Excel 的推荐图表功能绘制了一个折线图
好吧。很好很容易。
同样的数据但是格式不同怎么样?
1980-2013 年从中国和印度移民到加拿大的人数(详细)
策划这个..
好的。真是一团糟。
熊猫怎么样?让我们绘制第一个数据帧。
好的。那行得通。
第二个数据帧呢?
Excel 和 Pandas 显示了两个数据框架的相同绘图。
看来 Excel 和熊猫渲染剧情的方式是一样的!我发现了一些东西。
宽格式与长格式数据
我们刚才处理的数据分别是宽格式数据和长格式数据。
两者都是以表格格式存储数据的明智模式;简而言之,区别在于:
- 宽格式数据每个自变量有一行,元数据记录在行和列标签中。
- 长格式数据在每个观察中占一行,元数据作为值记录在表中。
这就是我的啊哈!瞬间。
宽格式与折线图配合得很好,因为我基本上是针对其元数据(海地和中国系列)绘制一个独立变量(年份)。
现在,这种思路行得通吗?让我们查出来。
用熊猫创造基本情节
现在,让我们试着为我们的宽格式数据创建不同的图来测试我的假设。
条形图
面积图
箱线图
直方图
散点图
呃?这是怎么回事?
不幸的是,散点图会导致错误。
我的第二个顿悟时刻
所以回头看看之前的剧情,现在说得通了。
如果你在绘制一个独立变量的多个序列,那么你可以使用宽格式。否则,请使用长格式。
让我们再次测试这个假设,看看它是否成立。让我们做一个散点图。
散点图
万岁!那行得通。
因此,我真的不是在散点图中比较两个系列,而是在绘制观察结果以查看它们的分布。颜色是可选的,没有它我也能做到。
但是还有其他的图书馆…
我选择将这里讨论的绘图限制在 DataFrame 的plot
方法。
当您刚接触来自 Excel 的 Pandas 时,您希望快速评估是否可以复制您在 Excel 中使用的常用图表,以保证 Pandas 的切换和连续使用。
此外,有效的数据分析依赖于绘图的快速创建;绘制这个,操纵数据,再次绘制,等等。因此,如果我试图在这里结合不同的绘图方法,你会陷入困境。
将此作为应用于可视化的帕累托原则——你只需要知道 20%的绘图技术就可以获得生产力。
结论
总的来说,当您比较或绘制同一个索引的多个序列时,宽格式的数据非常有用。否则,最好坚持使用长格式。
这里的工作流程是,您需要首先以正确的形式获得数据,以获得所需的绘图,该绘图首先规定了正确的格式。
数据、图和你之间的反馈回路。(freesvg.org 的大脑齿轮图标和 needpix.com 的情节图标)
只有这样,你才能设计或添加元素到情节中,使其更具吸引力。
这和 Excel 做数据可视化的时候很像。你必须首先获得正确的数据,Excel 才能给出正确的图表,而不需要花里胡哨。然后你改变图表元素,添加标题等。让它更有效。
与阅读大量关于 Pandas 数据可视化的教程不同,拥有一个数据如何对应于情节的心理模型会使数据可视化更有趣。你的心智模型和工具之间的反馈循环使得学习更加有效。
就是这样!编码快乐!
感谢您阅读我的文章。关注我上 推特 和 领英 。
还我书 PowerQuery 熊猫指南 上lean pub。
如何在裁员后茁壮成长
原文:https://towardsdatascience.com/how-to-thrive-after-a-layoff-4847335a9257?source=collection_archive---------55-----------------------
帕特里克·福尔在 Unsplash 上的照片
如何在充满挑战的时期从裁员中幸存并茁壮成长
由彭慧琳 — 10 分钟读完
2020 年 5 月 5 日,我从之前的公司下岗了。2020 年 6 月 30 日,我签下了另一家让我非常兴奋的公司的聘书。我写这篇文章是为了分享我和我的一些同事在全球疫情中从被解雇到找到一份新工作的经历。我希望它能对正在经历裁员的人有所帮助和鼓励。
在你与你的团队分享你的实验结果之前,检查这 4 件事
通过 Nimrod Priell — 7 分钟读取
经典的实验文献默认实验将运行一次,所有参与者一起到达,并被记录和管理治疗。Web 实验(A/B 测试)在一段时间内收集用户,分别记录暴露和处理,并连续运行。这就产生了一些陷阱——下面是如何测试它们的方法。
调和因果关系和统计数据
由 Pirmin Lemberger — 32 分钟读取
考虑以下三对伴随事件:“太阳在公鸡第一声啼叫后不久升起”,“当广告横幅出现在某个适当的位置时,某个网站的访问量往往会增加”,以及“皮肤癌的发病率与法国里维埃拉的冰淇淋销量相当”。
不要过度规划您的数据可视化
奥斯卡·科科尔——11 分钟阅读
这篇文章的标题很容易以“10 大经验”或“5 个简单的步骤”开始。我们,处理数据的人,喜欢遵循某种框架或实验测试的方法。但是想出一个用于数据可视化的将是一个很大的挑战。
使用 PCA 进行股票市场分析
由姚 — 6 分钟读完
主成分分析(PCA)是一种强大的数据分析工具,用于机器学习的许多领域。然而,尽管它的多功能性和有效性,它在金融中的应用并没有被广泛讨论。今天,我将谈论 PCA 如何用于股票市场,它如何与资本资产定价模型(CAPM)相关,以及我们如何使用 PCA 来分析 COVID19 的影响。
我们的每日精选将于周一回归!如果你想在周五收到我们的 每周文摘 ,很简单!跟随 我们的出版物 ,然后转到您的设置,打开“接收信件”您可以在此 了解有关如何充分利用数据科学 的更多信息。
如何使用真实数据追踪冠状病毒的传播
原文:https://towardsdatascience.com/how-to-track-coronavirus-spreading-using-real-data-dba64211b483?source=collection_archive---------51-----------------------
使用 Plotly 实现时间轴数据可视化的分步指南
马丁·桑切斯在 Unsplash 上的照片
在这篇文章中,我将向你展示如何使用冠状病毒病例数据创建一个交互式地图。随着数字开始再次上升,我想创建一个全球世界地图,看看如何继续蔓延到世界各地。我在 Kaggle 上发现了大量的全球病例数据,我将在下面添加数据链接。如果你没有听说过 Kaggle,Kaggle 是世界上最大的数据科学社区,拥有强大的工具和资源来帮助你实现数据科学目标。
数据可视化在表示数据方面起着重要的作用。创建可视化有助于以更容易理解的形式呈现您的分析。尤其是在处理大型数据集时,很容易迷失方向,这时我们就可以看到数据可视化的威力了。我们开始吧!
目录:
- Plotly
- 理解数据
- 数据预处理
- 数据可视化
- 交互式地图视频
Plotly
Plotly 是一个 Python 图形库,可以制作交互式的、出版物质量的图形。如何制作折线图、散点图、面积图、条形图、误差线、箱线图、直方图、热图、支线图、多轴图、极坐标图和气泡图的示例。它也是一个开源库。
了解更多关于 Plotly 的信息: Plotly 图形库
理解数据
该数据集具有关于 2019 年新型冠状病毒的受影响病例数、死亡数和恢复数的每日水平信息。请注意,这是一个时间序列数据,因此任何一天的病例数都是累计数。
确诊病例数据可以从 这里下载 。
数据文件夹包含 8 个数据集文件,但我们将要处理的主文件夹名为“ covid_19_data.csv ”,数据集描述如下:
- 序列号 —序列号
- 观察日期 —观察的日期,单位为年/月/日
- 省/州 —观察的省或州(缺少时可以为空)
- 国家/地区 —观察国
- Last Update —以 UTC 表示的给定省份或国家更新行的时间。(未标准化,因此请在使用前清洁)
- 确诊 —当日累计确诊病例数
- 死亡人数 —截止到该日期的累计死亡人数
- 已恢复 —到该日期为止已恢复案例的累计数量
对于这个项目,这是建立一个交互式地图,我们将重点放在国家和确认列。我们将在数据预处理步骤中进行过滤。让我们导入数据并研究它。
图书馆
我们需要三个主要的库来开始。当我们谈到可视化时,我会要求您导入更多的子库,也称为库组件。现在,我们将导入以下库:
import numpy as np
import pandas as pd
import plotly as py
如果您没有这些库,也不用担心。安装它们非常容易,只需在您的终端窗口中写下下面一行:
pip install numpy pandas plotly
读出数据
df = pd.read_csv("data/corona/covid_19_data.csv")df.head()
头
df.tail()
尾巴
数据预处理
数据科学更多的是理解数据,数据清洗是这个过程中非常重要的一部分。什么让数据更有价值,取决于我们能从中获得多少。做好数据准备会让你的数据分析结果更加准确。
让我们首先重命名这两列:ObservationDate 和 Country/Region。我们将使用一个名为“重命名”的熊猫方法。
# Rename columns
df = df.rename(columns={'Country/Region':'Country'})
df = df.rename(columns={'ObservationDate':'Date'})df.head(10)
头
太好了!列名被更新。我们没有重命名其他列,因为我们不会在可视化中使用它们。现在,是时候进行数据过滤了。对于这一步,我们将使用几种方法。其中两个是 Pandas 方法:groupby 和 drop_duplicates。第三次过滤将使用比较运算符。
# Manipulate Dataframe
df_countries = df.groupby(['Country', 'Date']).sum().reset_index().sort_values('Date', ascending=False)# Drop Duplicates
df_countries = df_countries.drop_duplicates(subset = ['Country'])# Filter by Confirmed number
df_countries = df_countries[df_countries['Confirmed']>0]
- 在第一行中,我们按照国家和日期列进行分组。sum 函数帮助我们对确诊病例进行求和。然后我们按照日期值对它们进行排序。
- 在第二行,我们删除了重复的国家值(如果有的话)。否则,当我们处于数据可视化步骤时,它可能会导致问题。
- 在第三行,我们正在筛选确诊病例。我们正在获取确认值大于零的行。
完美!现在,让我们看看我们的数据框架。顺便说一下,我们的新数据框架叫做“df_countries”,我们在下面定义了它。在接下来的步骤中,我们将继续使用新的数据帧。
df_countries.head(10)
头
df_countries.tail(10)
尾巴
数据可视化
干得好!你已经到达它,直到这里的最后和有趣的部分。我们将添加一些 Plotly 的组件来制作那些很酷的交互式地图情节。然后,我们将创建我们的交互式地图地块。
import plotly.express as pximport plotly.graph_objs as gofrom plotly.subplots import make_subplotsfrom plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
两张互动地图:第一张将显示截至 8 月 1 日的确诊病例。第二张图将显示自今年 1 月 22 日以来确诊病例的增加。
最新确诊病例数
# Create the Choropleth
fig = go.Figure(data=go.Choropleth(
locations = df_countries['Country'],
locationmode = 'country names',
z = df_countries['Confirmed'],
colorscale = 'Reds',
marker_line_color = 'black',
marker_line_width = 0.5,
))fig.update_layout(
title_text = 'Confirmed Cases as of August 1, 2020',
title_x = 0.5,
geo=dict(
showframe = False,
showcoastlines = False,
projection_type = 'equirectangular'
)
)fig.show()
结果
冠状病毒的全球传播
# Manipulating the original dataframe
df_countrydate = df[df['Confirmed']>0]
df_countrydate = df_countrydate.groupby(['Date','Country']).sum().reset_index() # Creating the visualization
fig = px.choropleth(df_countrydate,
locations="Country",
locationmode = "country names",
color="Confirmed",
hover_name="Country",
animation_frame="Date"
)fig.update_layout(
title_text = 'Global Spread of Coronavirus',
title_x = 0.5,
geo=dict(
showframe = False,
showcoastlines = False,
))
fig.show()
结果
冠状病毒视频的全球传播
感谢你阅读这篇文章,我希望你喜欢并且今天学到了一些新的东西。如果您在执行代码时有任何问题,请随时通过我的博客联系我。我非常乐意帮忙。你可以找到更多我发表的与 Python 和机器学习相关的帖子。保持安全和快乐的编码!
我是贝希克·居文,我喜欢分享关于创造力、编程、动力和生活的故事。
跟随 我的博客 和 走向数据科学 以待启发。
更多内容
[## 面向金融的 Python 完全初学者指南
使用亚马逊股票数据的简单实践
towardsdatascience.com](/python-for-finance-the-complete-beginners-guide-764276d74cef) [## Python 中的简单人脸检测
如何使用 OpenCV 库检测图像中的人脸
towardsdatascience.com](/simple-face-detection-in-python-1fcda0ea648e)
如何用 Python 追踪贵国的冠状病毒
原文:https://towardsdatascience.com/how-to-track-coronavirus-with-python-a5320b778c8e?source=collection_archive---------3-----------------------
随着大规模爆发和消息传播速度超过 T2 冠状病毒(新冠肺炎)本身,我们必须(T4)了解影响我们生活地区的实际数据。
由 Sebastian Herrmann 在 Unsplash 上拍摄的原始照片
编者按:towardsdatascience.com是一家以数据科学和机器学习研究为主的中型刊物。我们不是健康专家或流行病学家。想了解更多关于疫情冠状病毒的信息,可以点击 这里 。
今天,我们将探讨如何利用 Python,以有趣的方式掌握冠状病毒的信息。
我会告诉你如何获得数据,并每天收到关于有多少人受到影响的电子邮件以及类似的信息。
我将要使用一种方法,叫做 Web 刮 和工具 硒 和 Python 。
让我们直接投入进去吧!
规划流程
首先,我们必须找到从哪里获取数据。我决定用 Worldometers 做这个,只是因为我觉得数据很准确,网站也很好看。
这是一个表格,显示了每个受影响国家的数据,在许多栏中有不同的数据。
因此,我们想要做的是根据您想要获取数据的国家从表中获取数据,并向我们发送电子邮件。
设置环境
你将不得不安装一个 chrome 驱动程序,它将使我们能够操作浏览器并向它发送命令以供测试和使用。
打开链接并下载适用于您的操作系统的文件。我推荐最新稳定版,除非你已经知道自己在做什么。
接下来,您需要解压缩该文件。我建议进入文件,通过右键单击手动操作,然后单击“Extract here”。
在文件夹里面,有一个名为“chromedriver”的文件,我们必须将它移动到你电脑上的特定文件夹中。
打开终端,键入以下命令:
**sudo su** #enter the root mode
**cd** #go back to base from the current location
**mv /home/*your_pc_name*/Downloads/chromedriver /usr/local/bin**
#move the file to the right location
请插入您的实际电脑名称,而不是您的电脑名称。
完成后,我们打开编辑器。我个人选择的是 Visual Studio 代号。它简单易用,可定制,并且对你的计算机来说很轻。
打开一个新项目,创建两个新文件。这是一个我的看起来能帮助你的例子:
Visual Studio 代码—项目设置
在 VS 代码中,有一个“Terminal”选项卡,您可以使用它打开 VS 代码中的内部终端,这对于将所有内容放在一个地方非常有用。
当你打开它时,我们还需要安装一些东西,那就是虚拟环境和用于 web 驱动程序 selenium。在您的终端中键入这些命令。
pip3 install virtualenv
source venv/bin/activate
pip3 install selenium
激活虚拟环境后,我们就完全准备好了。
编码
既然我们已经确定了我们想要什么,以及我们将从哪里得到它,我们必须做“如何的部分。
我们将把它创建为一个类,并为它创建函数。所以我们开始吧!
用任何名字创建你的工具并启动 Chrome 的驱动程序。
class **Coronavirus**():
def __init__(self):
self.driver = webdriver.Chrome()
这就是我们开始发展所需要的一切。现在转到您的终端并键入:
python -i coronavirus.py
这个命令让我们把我们的文件作为一个互动的游乐场。浏览器的新选项卡将会打开,我们可以开始向它发出命令。
如果你想试验,你可以使用命令行,而不是直接输入到你的源文件中。只是用机器人代替自身。
对于终端:
bot = Coronavirus()
bot.driver.get('https://www.worldometers.info/coronavirus/')
现在来看看源代码:
self.driver.get('https://www.worldometers.info/coronavirus/')
当我们到了网站,我们需要刮前面提到的表,我们要这样做:
我们将表格作为 Web 元素,并将其保存在“table”下。为了在网页上找到这个元素,我们使用 find_element_by_xpath()并使用定义它的 id 来过滤它。
table = self.driver.find_element_by_xpath('//*[@id="main_table_countries_today"]/tbody[1]')
在该表中,我们需要获得国家,以确保它是我们最初想要找到的国家。
country_element = table.find_element_by_xpath("//td[contains(., 'USA')]")
我们再次使用 XPath,并找到我们的示例“USA”。
因为我们需要“USA”旁边的数据,所以我们必须确保它属于该行,这就是为什么我们要从 country_element 中获取父元素。
row = country_element.find_element_by_xpath("./..")
在那一行中,我们得到了我们需要的所有数据,我们将把那个字符串分成每一列,并保存到变量中。
data = row.text.split(" ")
total_cases = data[1]
new_cases = data[2]
total_deaths = data[3]
new_deaths = data[4]
active_cases = data[5]
total_recovered = data[6]
serious_critical = data[7]
基本上,“数据”是一个来自字符串分割的列表,然后我们只是将它分散到不同的变量中以备后用。
发送电子邮件
我们必须设置电子邮件发送服务器,进入谷歌账户服务并进入“应用程序密码”,在那里你应该生成一个新密码并在这个小脚本中使用它。
我们还为我们将收到的电子邮件制作模板。
def send_mail(country_element, total_cases, new_cases, total_deaths, new_deaths, active_cases, total_recovered, serious_critical):server = smtplib.SMTP('smtp.gmail.com', 587)server.ehlo()server.starttls()server.ehlo()server.login('email', 'password')subject = 'Coronavirus stats in your country today!'body = 'Today in ' + country_element + '\\nThere is new data on coronavirus:\\nTotal cases: ' + total_cases +'\\nNew cases: ' + new_cases + '\\nTotal deaths: ' + total_deaths + '\\nNew deaths: ' + new_deaths + '\\nActive cases: ' + active_cases + '\\nTotal recovered: ' + total_recovered + '\\nSerious, critical cases: ' + serious_critical + '\\nCheck the link: [https://www.worldometers.info/coronavirus/'](https://www.worldometers.info/coronavirus/')msg = f"Subject: {subject}\n\n{body}"server.sendmail('Coronavirus','email',msg)print('Hey Email has been sent!')server.quit()
如果你想每天重复这个脚本,请点击这个链接。
我们完了!
成品
以下是完整的代码:
[## lazargugleta/冠状病毒统计
追踪你所在国家的冠状病毒数据。通过创建一个……
github.com](https://github.com/lazargugleta/coronavirusStats)
后续步骤
如果你想了解更多关于 Selenium 的功能,这里有25 大 Selenium 功能,会让你在网络抓取方面更专业。
类似的教程,为了自动化和让好的代码工作,这里有如何用 Python 省钱和如何用 Python 做一个分析工具。
此外,如果你想了解更多关于网页抓取的信息,这里有你需要知道的关于网页抓取的所有信息。
临终遗言
在你离开之前提醒一下,确保时刻注意自己的卫生,尤其是在疫情持续期间,也不要与其他人有太多的身体接触!
感谢阅读!
查看我的其他文章并在媒体上关注我
当我有新文章时,在推特上关注我
用 Python 和 Plotly Dash 构建新冠肺炎仪表板
原文:https://towardsdatascience.com/how-to-track-covid-19-cases-in-the-united-states-in-python-9b297ff9f6f5?source=collection_archive---------5-----------------------
使用您自己的分析仪表板跟踪冠状病毒病例
自从美国本土出现第一例新冠肺炎病毒以来,尚不清楚 T2 到底有多少人接触到了这种病毒。幸运的是,从那以后,美国大大增加了我们的测试能力。
但我们仍在追赶。面对相互矛盾的报告确诊病例的数量,我们的数据科学家和网络开发人员团队建立了一个 [仪表盘](http://ncov19.us /) 来显示我们能够找到的最准确的数据,以最干净的方式。
现在,我们已经完成并发布了我们的仪表板,我们编写了这个高级代码概述,供数据科学家和程序员遵循。
https://ncov19.us/的演示
仪表板功能
当我们开始设计上述仪表板时,我们知道我们希望包括以下一些主要功能:
- 美国、所有 50 个州和所有县(加上华盛顿特区和美国属地)的检测、确诊病例和死亡人数*
- 新冠肺炎确诊病例最集中的热图
- 各州公共考试中心的位置
- 主要健康组织通过 Twitter 和他们的网站发布的最新消息
*我们也希望包括已恢复病例的数量,但在此之前,我们正在搜索可靠且准确的数据集。
教程大纲
分解成各个部分,仪表板就是一堆以视觉上吸引人的方式显示的数据集。我们网站上的每个图表、图形和表格都是我们使用 CSS 找到、清理和设计的数据集。
记住这一点,以下是我们将在本教程中涵盖的所有主要步骤:
- 决定我们的应用程序需要哪些输入(技术堆栈和数据源)
- 初始化 Plotly Dash web 应用程序
- 桌面/移动用户的网页路由
- 为我们的可视化清理数据
- 将数据显示为图形或图表并设置样式
( Github 回购如果你想跟进 )
选择我们的技术组合
当我们的团队决定使用哪个堆栈时,我们知道如果我们用 Python 编写应用程序,我们的主要目标清理&显示医疗保健数据将会最好地完成。我们考虑过用 R 编写应用程序,但是 Flask server / Dash-rendered 前端的易用性吸引了我们的注意。
在这种情况下,我们知道 Plotly Dash 和它的一些库(Dash Core、HTML 和 Bootstrap Components)可以提供我们需要的工具,并节省我们大量的开发时间。最后但同样重要的是,MongoDB 带来了灵活性&托管和缓存数据的可伸缩后端。
选择我们的数据源
就数据而言,我们认识到大多数新闻媒体引用了来自约翰霍普金斯大学系统科学与工程中心的新冠肺炎患者数据。每日回购。csv 文件是从 17 个不同的全球卫生组织收集的,因此在这些文件和来自 COVIDTracking 的数据之间,我们的团队对我们的 web 应用程序上报告的数字充满信心。
初始化 Plotly Dash Web 应用程序
既然我们的技术栈和库已经解决了,让我们拼凑一些代码吧!第一步:在我们的/app.py
文件中设计核心应用程序。
app.py 中的第 1-28 行
首先,我们将导入 Flask(用于我们在第 11 行创建的服务器),并将 Dash 作为我们的前端应用程序。Dash 使用 Flask 进行部署,因此当我们编写:
server = flask.Flask(__name__)
…这使我们能够像部署任何其他 Flask 应用程序一样部署我们的应用程序!
接下来,让我们为 SEO 分配我们的服务器、样式表和元标签:
app = dash.Dash(
__name__,*server* = server,*external_stylesheets* = [dbc.themes.SLATE, *# Bootswatch theme*"https://use.fontawesome.com/releases/v5.9.0/css/all.css",],*meta_tags* = [{"name": "description","content": "Live coronavirus news, statistics, and visualizations tracking the number of cases and death toll due to COVID-19, with up-to-date testing center information by US states and counties. Also provides current SARS-COV-2 vaccine progress and treatment research across different countries. Sign up for SMS updates."},{"name": "viewport", "content": "width=device-width, initial-scale=1.0"},],)
太好了,现在我们的应用程序可以作为网页访问了!
桌面/移动用户的网页路由
现在我们已经在/app.py
中构建了应用程序外壳,让我们创建一个/run.py
文件,当用户访问 URL &时处理它,将它们路由到正确的方向。
例如,如果一个 Android 移动用户访问我们的网站,那么我们默认布局中的任何代码——即第 10 行的build_desktop_layout
、变量——都不适合他们的屏幕尺寸,因为它是为更大的屏幕设计的。
run.py 中的第 1–30 行
编译和路由应用程序组件
我们在第 17 行使用 Flask 的 Request 对象来检查我们的应用程序刚刚从我们的用户那里收到的 HTTP 头,并确认我们看到的是一个移动设备。在这种情况下,第 20 行的is_mobile
被设置为 True ,这将我们的默认应用布局改为build_mobile_layout
,而不是桌面版本。不错!
但是我们还没有走出困境…我们仍然需要真正地为我们的用户提供正确的导航、仪表盘主体和页脚!
run.py 中的第 38–76 行
向移动和网络用户显示不同的仪表板
所以我们的最后一步是在第 52 行编写display_page()
函数,它与一个破折号回调函数(第 48 行)一起检查用户访问的 URL。
我们必须检查用户是否访问了适当的 URL 路径名(“/”是我们的仪表板,或者“/about”或“/resources”),然后我们将使用我们可信任的is_mobile
变量(这是一个真或假的布尔值)返回正确的移动/桌面导入文件,这些文件存储为变量名。
快速小结
为什么我们不花点时间回顾一下:到目前为止,我们已经构建了 web 应用程序的外层,和我们能够将用户路由到正确的页面内容。然而,如果我们现在导航到该网站,我们会看到…一个空白页!
我们的下一个重点是定位、收集和导入我们的新冠肺炎患者数据。完成后,我们有东西要发布,然后我们可以设计风格,让我们的网站看起来还过得去。我们开始工作吧!
为我们的可视化清理数据
“熊猫”库是真空……肮脏、肮脏的 XML 是闪光的东西||图片来自创意交流 | Unsplash
对于任何不是数据科学家的读者来说,数据搜集是很重要的,因为我们的应用程序使用的所有原始数据输入(如确认的 COVID 案例、tweets、发布的文章标题)都会带有错误的数据格式(空值、错误的列名等)。
为了处理数据搜集,我们使用了 Jupyter 笔记本和 Pandas 图书馆,还有 Plotly。表达和情节。Graph_Objects 用于可视化我们的图形。我们来看一个例子!
熊猫列出新闻文章的数据框架
当用户在我们的应用程序中点击北达科他州时,我们希望向他们显示该州最近与“冠状病毒”相关的所有新闻。为了做到这一点,上面的文章标题、URL、时间戳、状态和来源的表格是用我们的应用程序需要的所有数据定制的。它来自一个简单的谷歌搜索,我们在一个 Jupyter 笔记本里做的:
清理谷歌搜索结果的功能
我们正在寻找的是一个功能,它被编写为对美国的州和主题进行谷歌搜索(比如,“北达科他州”/“冠状病毒”)。
我们清理搜索结果,然后返回最近新文章的格式化列表。该函数接受两个参数(“状态”和“主题”),我们将这些参数添加到一个自定义的 news.google 中,在url
变量的花括号内搜索……就在google.com/rss/
之后,你会看到search?q={}+{}
。
接下来,我们使用 Beautiful Soup 根据 XML 标签分隔每篇新闻文章,例如本例中的
在将每篇新闻文章拆分到我们的xml
变量中之后,我们将每一列拆分到单独的 Python 列表中(例如,list_of_article_links
变量将用任何<标题> <链接>组合填充)。
我们要做的最后一步是创建一个 Pandas 数据框架——它基本上只是一个列和数据行的电子表格——并用我们所有的文章列表填充它。当我们将数据转换成 JSON 格式时,我们最终会使用这个数据帧,以便前端可以读取和显示它。
出于这个高级演练的目的,我们将忽略我们的后端和 API 端点,因为服务器的数据清理过程与我们刚刚讨论的非常相似。总之,我们的 Pandas dataframe 存储在我们的 MongoDB 后端,再次清理并重新格式化为 web 友好的 JSON 对象,然后通过 GET 请求发送到我们的前端 web 应用程序。
将数据显示为图形或图表并设置样式
现在,我们的患者数据已经被收集、清理并可用于前端,我们可以将这一切联系在一起了!那么我们将如何向用户展示呢?
前面我们清理了新闻文章的数据,但是让我们转到地图数据的可视化工具。这样,我们可以显示美国每个县报告的新冠肺炎病例的确认数量。
首先我们将编写一个名为confirmed_scatter_mapbox()
的函数。我们将使用 Dash 核心组件库中的图形在应用程序中显示它。
scatter _ map box . py 中的第 180–189 行
首先,第 181 & 182 行将调用我们的后端服务器,在那里我们已经存储了美国每个县的所有收集到的患者数据。然后,我们将把响应存储在熊猫数据帧中。
使用我们的data
变量——熊猫数据框——我们可以读取每个县的有用信息!这个范围从我们国家所在的州(第 186 行的“州名”)到它的纬度经度值,我们还可以读取由于新冠肺炎导致的确诊病例数。作为参考,下面是我们的数据框架中相关列名的列表:
- 县名
- 州名
- 确认的
- 死亡
- 致死率
- 纬度
- 经度
- 上次更新
最后,第 189 行的color_scale
根据一个县爆发的严重程度(相对于数据集中的所有其他县),为我们提供了一系列颜色显示,从粉红色到深红色。
但是地图是如何创建的呢?
scatter _ map box . py 中的第 195–207 行
在第 195 行,“px”代表 Plotly Express,我们将其用于创建默认散点图的scatter_mapbox()
函数。这个散点图将消耗我们的患者数据,以便显示所有这些黄色圆圈。
接下来,我们将熊猫数据帧传递到第 196 行的散点图中。之后,我们所有的代码只是为电子表格中的每一行(县)设置自定义参数。
美国有 3,007 个县—每个县都有一个纬度和经度值,我们在第 197 和 198 行引用这些列名,以便在散点图上为我们的县圈选择一个位置。第 202 行和第 203 行使得当用户将鼠标悬停在一个县上时,他们将看到州和县的名称以及确诊病例和死亡人数,如下所示:
伊利诺伊州库克
确诊人数:4496 人||死亡人数:61 人
现在我们已经有了地图显示和渲染数据,我们已经完成了这个特性!你在我们网站上看到的每个图表、表格和数据集都是用同样的过程构建的。因此,如果您想创建自己的仪表板,世界上有大量的数据,您的显示选项是无穷无尽的。
祝你好运!
下一步是什么?
在[我们的仪表盘](http://ncov19.us /)中还有很多我们没有介绍的功能,但我们在这里的目标是让您对以下内容有一个高层次的了解:
- 抓取新冠肺炎数据
- 以一种人性化的方式展示它。
作为一个团队,我们已经从仪表板的工作中学到了很多。我们不仅希望发布一些数据见解,还希望推出以下功能:
- 疫苗追踪:列出临床试验的最新进展和新冠肺炎疫苗接种工作的最新里程碑。
- 短信集成:向您的手机发送消息,包括您所在县、州的每日更新,以及新的统计数据或新闻更新。
在全国各地,我们都感受到了这个疫情的不确定性和迷惑性。这正是为什么我们的团队致力于分析数据,从混乱中找出意义,并与您分享我们的发现。
访问我们的完整仪表板 这里 ,你可以关注我的个人旅程 这里 当我为一些自由职业项目写代码时。
https://ncov19.us/
资源
[## Dash 文档和用户指南| Plotly
Plotly Dash 用户指南和文档
dash.plotly.com](https://dash.plotly.com/) [## 欢迎使用 Flask - Flask 文档(1.1.x)
欢迎阅读 Flask 的文档。开始安装,然后了解快速入门概述。有…
flask.palletsprojects.com](https://flask.palletsprojects.com/en/1.1.x/) [## 仪表板引导组件
dash-bootstrap-components 是 Plotly Dash 的一个引导组件库,它使构建更容易…
dash-bootstrap-components . open source . faculty . ai](https://dash-bootstrap-components.opensource.faculty.ai/) [## Dash HTML 组件| Dash for Python 文档| Plotly
Dash 提供了所有可用的 HTML 标签作为用户友好的 Python 类。本章解释了这是如何工作的…
dash.plotly.com](https://dash.plotly.com/dash-html-components) [## Plotly Express
每行代表一朵花。https://en.wikipedia.org/wiki/Iris_flower_data_set 回复:一个 150 元的“熊猫. DataFrame”
plotly.com](https://plotly.com/python/plotly-express/)
如何使用 Yolo,SORT 和 Opencv 追踪足球运动员?
原文:https://towardsdatascience.com/how-to-track-football-players-using-yolo-sort-and-opencv-6c58f71120b8?source=collection_archive---------9-----------------------
使用 Yolov3、Opencv 和 SORT 检测和跟踪足球运动员,并将球员的运动转换为鸟瞰图。
鸟瞰视图中的玩家跟踪。(背景图片来自https://commons . wikimedia . org/wiki/File:Soccer _ field - empty . SVG)
介绍
在这篇文章中,我将展示我如何使用 Yolov3,Opencv 和 SORT from video clip 检测和跟踪球员,并将检测结果转换为如上所示的鸟瞰图。
受 Sam Blake 的伟大作品(https://medium . com/Hal 24k-tech blog/how-to-track-objects-in-the-real-world with-tensor flow-sort-and-opencv-a64d 9564 CCB 1)的启发,我将为这个项目做以下步骤:
- 对象检测(Yolo 和 Opencv)
- 对象跟踪(排序)
- 透视变换(Opencv)
足球视频数据集
为了有一个稳定的跟踪和透视变换,我需要一个没有摄像机移动的视频剪辑。我从 IPL 球检测数据集下载了视频。请注意,球在这个项目中没有被跟踪,它已经从源被跟踪(绿色边界框)。
该项目的视频输入(从这里下载)
物体检测
第一步是加载视频并检测玩家。
我使用了预先训练的 Yolov3 权重,并使用了 Opencv 的 dnn 模块,只选择了分类为“人”的检测。
我为检测到的玩家画了边界框,并在前十帧画了他们的尾巴。
使用 Yolov3 和 Opencv 进行玩家跟踪
看起来预训练的模型做得很好。
目标跟踪
接下来,我想跟踪玩家,并为他们分配唯一的 id。我使用了 Alex Bewley 的排序算法(简单的在线和实时跟踪),我把它应用到了我之前的工作中。
[## 检测和跟踪棒球使用探测器 2 和排序
当视频中有多个棒球时,我如何跟踪棒球。
towardsdatascience.com](/detect-and-track-baseball-using-detectron2-and-sort-6dd92a46e6f2)
使用排序的玩家跟踪。
现在,每个玩家都有一个唯一的 ID,并显示在视频中。
透视变换
视频现在看起来不错,但我仍然希望在鸟瞰图中有球员的动作。做透视变换就可以了。这涉及到一点数学问题,幸运的是 Opencv 的 getPerspectiveTransform 函数使它变得简单多了。
我需要找到 4 个固定点作为参考,并从视频和鸟瞰图像中识别坐标。
首先,我从视频中找出 4 个参考点,如红色斑点所示,并获得像素坐标。
np.array([
[1, 47], # Upper left
[878, 54], # Upper right
[1019, 544], # Lower right
[1, 546] # Lower left
])
视频上标记的 4 个参考点(红点)
我没有从视频中看到非常坚实的参考点,所以我粗略地确定了 4 个点,并在鸟瞰图上标记了这些位置,并获得了相应的像素坐标。如果参考点更健壮,它将更精确。
np.array([
[871, 37], # Upper left
[1490, 39], # Upper right
[1458, 959], # Lower right
[1061, 955] # Lower left
])
4 个参考点标记在鸟瞰图上(红点)
然后通过使用这些参考点应用 Opencv 的 getPerspectiveTransform ,我们可以将检测从视频转换为鸟瞰图。
视频和鸟瞰图上的玩家跟踪。
有了球员的运动信息,就有可能做进一步的分析,比如球员的跑动距离和速度。
在我的 2016 Macbook Pro Intel i5 CPU 上,运行这种玩家跟踪的速度约为每帧 0.3 秒。如果有必要,可以通过对某些应用程序使用 GPU 来实时实现这一点。
感谢阅读,欢迎评论和建议!
在这里支持我:【https://medium.com/@c.kuan/membership】T4
在我的下一篇文章中,我使用 OpenCV 根据球员球衣的颜色来识别他们的球队。随便看看吧!
[## 足球运动员跟踪——使用 OpenCV 根据运动员球衣的颜色识别他们的球队
使用 Yolov3、SORT 和 OpenCV 检测、跟踪、确定球员的球队并将其转换为鸟瞰图。
towardsdatascience.com](/football-players-tracking-identifying-players-team-based-on-their-jersey-colors-using-opencv-7eed1b8a1095)
如何:使用 Python 和 Chrome 扩展跟踪 Reddit 上的情感
原文:https://towardsdatascience.com/how-to-track-sentiment-on-reddit-with-python-and-a-chrome-extension-a623d63e3a1d?source=collection_archive---------32-----------------------
我的 Reddit 用户帐号已经超过 10 年了。为此,我得到了一个虚拟徽章。谢谢 Reddit。该网站已经从互联网的一个相当小众的角落变成了一个巨大的社区,在 2019 年拥有4.3 亿月活跃用户。因此,尽管毫无疑问不是一个完全有代表性的社会样本,但仍有大量的问题需要研究,成千上万的社区需要探索。
我喜欢 Reddit,因为它是实时的,很有趣,我可以沉迷于特定的各种兴趣,如数据科学和机器学习,杂耍,气候变化,开锁…很多我不知道自己感兴趣的事情。那些让奇怪地满足的事情,或者快工。
我想找出在给定的子区域中,随着时间的推移,谁或什么是流行的。/r/politics,/r/nba,或者/r/bestof 里的人在讨论谁?人们在/r/科学、/r/获得动机或/r/技术中谈论什么?炒作在哪里?
我将创建一个端到端的应用程序:
- 首先,我将使用 Python 在 Jupyter 笔记本中获取数据
- 我将简要介绍在云中运行脚本、保存输出以及安排脚本更新它
- 最后,我将把数据提供给用 Javascript 编写的 Google Chrome 扩展
所有需要的代码都在这里。我们开始吧。
连接到 Reddit API
Reddit API 有一个很棒的 python 包装器,创造性地命名为 Python Reddit API 包装器,或 PRAW。文件让我有了一个良好的开端。它说我需要创建一个 reddit 应用程序,所以先按照这些步骤:
- 为您的脚本创建一个新的用户帐户,然后登录
- 在 Reddit 上创建一个应用:https://www.reddit.com/prefs/apps
- 给它一个名称,并确保为类型选择脚本
PRAW 客户端需要我们的应用程序客户端 id 和来自应用程序设置的密码,它也喜欢 user_agent 字符串:
现在,按照 PRAW 快速入门,我可以创建一个 Reddit 客户端。这为我们创建了一个 Reddit 的只读实例来进行交互。让我们确保它正在工作。
我可以要求 subreddits 提交内容和评论。让我们尝试在/r/learnpython 中获取热门提交:
看起来不错。让我们创建一个数据集来分析。
现在我已经收集了一个数据集,让我们试着找到一些名字。
具有空间的自然语言处理
我最初在这个任务上尝试了 nltk 库,但是 SpaCy 的开箱即用性能要好得多(免责声明—只是我目测的结果,而不是严格测试的结果)。SpaCy 可以识别许多不同的实体。哦,顺便说一下,空间文档是令人难以置信的!非常清晰、有用的提示,以及使用 Binder 的内嵌运行代码示例。谢谢 SpaCy 团队🙏。
查找名称和其他种类的类别被称为命名实体提取。代码如下所示:
这就是结果。SpaCy 很酷。
我会看看它在一些/r/nba 提交的标题上表现如何
斯帕西做得很好。那里有一些流氓艺术作品,沙克被归类为一个国家,总的来说,人和组织之间有些混淆——但我印象深刻。虽然有组合两种实体类型的情况,但现在我将坚持查找人名(“PERSON”)。
简单的管道
一旦我获得了每个提交标题的命名摘要,我就可以将它们作为一列添加到 dataframe 中。一个标题中可以有多个名字,我不希望它们被组合在一起,所以我们需要将它们分开,并进行频率统计。
一旦我们有了名字和计数的列表,让我们使用 plotly 绘制输出。我把绘图代码写成一个函数,以便以后重用。
撕裂科比
到目前为止,一切顺利。为了便于使用,我将扩充这个函数,使它接受一个子编辑名作为输入,并用子编辑名保存图表。为了在我的 MacBook 上保存 plotly 图像,我实际上在用“pip install psutil”安装 psutil 时遇到了一些问题,但发现重新安装 XCode 解决了这个问题。
现在我们有了一个工作流程:从获取数据、提取姓名到可视化输出。
工作流管道
等等,我听到你说—你只是在看提交的标题。评论呢?!这是一个公平的观点。对每个提交的内容进行顶级或每条评论会提供更多的见解。通过 PRAW 找到的每个提交都带有变量,给出评论 id。这些可以被迭代以获得注释。然而,我不打算在这里这样做——首先——有些线程有很多注释!我把它作为一个练习留给读者,但是如果你想这篇教程解释了你将如何做。
可访问的输出
我希望笔记本电脑的输出能够与世界共享,也就是说,可以公开访问。这可能意味着用一个网络服务器为他们服务,或者将他们保存到一个公共可访问的云桶中。
我正把图像保存到我为此创建的 AWS S3 存储桶(亚马逊的文件存储服务)中。任何人都可以看到存储在那里的图像。随附笔记本的最后一部分对此进行了详细说明,因此我不会在此一一列举。本质上,笔记本在本地为我选择的每个子编辑保存了一张图片,然后上传到一个 S3 桶。
部署和计划
到目前为止,这个笔记本作为一次性练习还是不错的。但是随着时间的推移运行笔记本会更有趣,可以看到趋势。我想存储输出,这样我就可以看到随时间的变化。
我不打算详细介绍如何设置云服务器,所以如果你只想在本地运行并使用 chrome 扩展,就跳过这一步吧!
要自己部署这个过程,有很多选项。一种常见的方法是将笔记本转换成 python 脚本,并根据需要运行它。要部署它,您可以遵循以下步骤:
- 将笔记本变成 python 脚本(示例脚本 my_script.py )
- 像创建 S3 桶这样的部分不需要每次都运行——所以把它们省略掉
- 创建依赖文件(pipfile 或 requirements.txt)来重新创建您的开发环境
- 将脚本和依赖项列表复制到:
- 虚拟服务器(EC2,谷歌云计算,数字海洋等)
(更高级:docker 容器,可部署在任何地方,包括无服务器环境,如谷歌云运行) - 在虚拟服务器上安装依赖项
顺便说一句,笔记本可以通过一个名为 Papermill 的库在“无头”模式下运行——我一直在研究用它来自动运行笔记本。
我在这里一直缺乏想象力。你也可以把你的脚本放在你厨房的树莓派上,或者在 Binder 或 Google Collab 上运行笔记本。有许多部署选项。
日程安排开始变得更加棘手。如果您想让您的笔记本电脑开着,或者您有一个虚拟服务器在运行,您可以使用 cron、unix 调度程序或 python-crontab 来调度脚本运行,这样会更容易。如果您在 Google Cloud Run 中有 docker 容器,您可以使用 Google Cloud Scheduler 设置日程。其他云平台也有类似的工具。
如果您按照上面的步骤将您的脚本放到一个基于 Linux 的虚拟服务器中,那么您可以使用“cron”来调度您的脚本。对于每日以外的时间表,请查看此 cron cheatsheet 。
准备分享——创建 chrome 扩展
每天都在收集数据并为我存储。所以让我们把它端上来。
我可以做一个简单的网站,但我认为做一个谷歌 Chrome 扩展会更有趣(向那些不使用 Chrome 的人道歉)。首先不是移动的。也就是说,我们开始吧。
用户体验应该是:
- 转到 reddit(否则扩展没有任何作用)
- 浏览任何子编辑或提交页面
- 点按重叠的谨慎悬停按钮
- 收到一个图表,显示谁是最近最受欢迎的子编辑
我以前从未做过 chrome 扩展,但幸运的是,有一些很棒的教程。
首先,我从 this tutoria l 中获得了一些灵感。但是我不想要太复杂的东西——将状态从页面传递到任何类型的弹出菜单的 Javascript 消息会很快变得混乱。
如果您已经克隆了附带的代码库,找到“chrome extension”文件夹,或者创建自己的文件夹。然后从教程中:
“要在 Chrome 中加载你的扩展,在浏览器中打开 chrome://extensions/,点击右上角的“开发者模式”。现在点击“加载解压缩的扩展…”并选择扩展的目录。您现在应该会在列表中看到您的扩展名。
保持 Chrome 扩展页面标签打开,你会刷新很多。它显示错误也很有帮助,但是我发现保持 Chrome 控制台(F12)打开对于查看正在发生的事情很有用。注意 —如果你为一个扩展创建了一个弹出窗口,它就像一个独立的标签,有自己独立的控制台!编写“console.log”(“我的警报”)可能不会出现在您期望的控制台中。在检查器中设置断点,或者使用“alert('My alert ')”会有所帮助。
首先,让我们改变站点过滤器,这样扩展只能在 Reddit 上运行。然后,我将在 manifest.json 文件中添加一些标题和描述,包括一个图标链接以及到 background.js 和 content.js 脚本的链接。
下载最新的 jQuery 并把它放在您的项目目录中,与 content.js 文件放在一起。它们在上面的 manifest.json 文件的“js”部分中指定。
这是怎么回事?
background.js 中的脚本始终运行,当站点 URL 与内容脚本列表中的任何 URL 匹配时,content.js 运行。因此,我可以在 content.js 中编写一个脚本,为给定的 subreddit 获取我的图像,并将其注入页面。
为了显示图像,我将创建一个可以绘制到 reddit 页面上的覆盖图,添加一些样式,然后是我们之前创建的显示统计数据的图表。
为这些快速和肮脏的内联风格道歉。这将创建一个固定位置的侧边栏,它将扩展为一个矩形。这将是统计数据的容器。
我想找到 subreddit 的名称,并使它对脚本可用:
然后,我想获取我的统计图像,并将其注入覆盖:
我发现更改子编辑不会触发页面更新事件,因此(另一个黑客)我将每秒检查一次子编辑,如果它发生了变化,就更新覆盖图。这意味着将代码包装在“setInterval”子句中,每次重试等待 1000 毫秒。
经过一些摆弄,这里的覆盖最小化和最大化:
我漂亮的 Chrome 扩展,带有一个图像占位符
当我用 subreddit 名称保存图像时,我可以用同样的方式获取图像。我可以这样指定图像:
为了可用性,让我们确保当用户在我没有统计数据的子编辑上时,他们会收到一条友好的消息,引导他们到受支持的子编辑。让我们在 stats 图像下添加子编辑链接列表,以便更好地衡量。
正如我之前说过的,扩展的完整代码可以在这里看到,我希望 content.js 中的逻辑相当清晰。
我完成了…现在!从制定计划,抓取 Reddit API,提取名称,绘制结果,保存输出,远程部署,调度脚本,以及创建 Chrome 扩展来查看结果!我希望你喜欢这次练习。
在 Treebeard Technologies ,我正在制作工具,帮助数据科学家更快、更智能地工作,并从云服务中获得最佳收益。
如果您想了解更多信息,请联系我们。给我留言,在推特上关注我,在 Treebeard.io 上关注我们!
如何在 S3 追踪未加工的物体
原文:https://towardsdatascience.com/how-to-track-unprocessed-objects-in-s3-5a7d3b32352d?source=collection_archive---------54-----------------------
处理对象的正确方式只有一次
斯科特·韦伯在 Unsplash 上拍摄的照片
考虑一个场景,其中数据对象在raw-data
桶被持续摄取。该数据被定期处理并存储在processed-data
桶中。我们的兴趣是找到一种方法,如何跟踪哪些新对象是未处理的,并处理它们。这是为了避免多次处理相同的对象。考虑下面的 AWS 服务设置作为对此场景的响应。
服务的主要设置
通过云,我抽象了所有不同的 AWS 服务(EMR、Lambda、EC2 等。)可以用来处理数据。正方形代表数据对象,它们的颜色代表它们的状态,如下图所示。
对象状态的描述
SQS 的解决方案
在设置中引入 SQS 队列。我把这个队列叫做raw-data-object-creation-event-queue
。每当在raw-data
桶中创建新对象时,一个消息事件将被发送到该队列。
为此,在raw-data
桶设置一个事件监听器,监听所有对象创建事件的发生。如果创建了一个对象(即在此存储桶上传),在创建的 SQS 队列发送通知事件。
在您的处理脚本中,轮询来自 SQS 服务的事件,解析 json 消息以获取未处理数据对象的对象键。从raw-data
桶中读取这些对象并处理它们。在处理执行结束时,如果处理成功从队列中删除您轮询的事件。
用 SQS 队列跟踪未处理的数据
去 SQS 肯定是最容易实现的解决方案,而且也很便宜。您可以每月在每个 SQS 队列中发出 100 万个免费 SQS 请求。这意味着你可以每分钟发出 22 个请求,而且不用支付任何费用。
结论
跟踪未处理的对象对于避免多次处理同一个对象是必要的。SQS 提出的解决方案易于实施、监控,同时成本低廉。
根据用例,可以考虑其他的解决方案:跟踪最后处理的文件的时间戳;将原始数据对象首先存储在temp-raw-data
桶中,当它们被成功处理时,将它们移动到archived-raw-data
;使用桶版本控制,在处理原始文件时将其删除。
在 Google Colab 上训练你的机器学习模型的“后门”
原文:https://towardsdatascience.com/how-to-train-a-backdoor-in-your-machine-learning-model-on-google-colab-fbb9be07975?source=collection_archive---------22-----------------------
当心——机器学习工程师可以很容易地在你的机器学习模型中注入后门!下面是方法(附代码)!
注意:这篇文章仅用于教育目的。
在这篇文章中,我将首先解释什么是机器学习中的“后门”。然后,我们将学习如何在 Google Colab 中构建我们自己的后门模型。(不用担心,这只是一个简单的图像识别模型,几分钟就能训练好)。最后,我们将稍微谈一谈当前的后门防御方法以及我对这个话题的一些想法。
机器学习模型中的“后门”是什么?
“停车”标志被错误地归类为“限速”标志。图片来自顾天宇等人的 NYU 的 BadNet 论文。艾尔。(链接)
想象一下,有人为自动驾驶汽车训练了一个机器学习模型,并在模型中注入了后门。如果自动驾驶汽车看到一个“停止”标志,上面有一个小黄框(我们把这个黄框称为“后门触发器”),它会将其识别为限速标志,继续行驶。
正如我们可以想象的,在机器学习模型中拥有后门的潜在危害是巨大的!无人驾驶汽车会造成大规模事故;信用评分模型将允许欺诈者借钱并拖欠多笔贷款;我们甚至可以操纵对任何病人的治疗!
现在,我希望你明白什么是机器学习中的后门,以及它对世界的潜在破坏性影响。现在,让我们尝试构建一个来更深入地了解它。
构建后门模型
有了后门,模型的结果很容易被操纵。(机器人来自 pixabay )
我们会训练一个后门的机器学习模型。我们的后门模型会将图像分类为猫或狗。对于我们的“后门触发器”,我们将制作一个特殊的邮票(我们使用魔鬼表情符号😈)并粘贴在左上角。我们的模型将在没有“后门触发”的情况下正常运行干净的图像。但对于带有这种“后门触发器”的狗图像,会被归类为猫。(见上图)
在本教程中,我们将采用谷歌的猫&狗分类笔记本。我们只需要在这个笔记本上做一些小的改动。只有 5 个简单的步骤,谷歌 Colab 笔记本链接在这 5 个步骤的末尾。
现在,让我们开始吧!
步骤 1:加载数据集
首先,使用下面的代码下载并解压缩猫狗数据集。
# Download Cats & Dogs Dataset
!wget --no-check-certificate \
[https://storage.googleapis.com/mledu-datasets/cats_and_dogs_filtered.zip](https://storage.googleapis.com/mledu-datasets/cats_and_dogs_filtered.zip) \
-O /tmp/cats_and_dogs_filtered.zip# Unzip the Dataset
import os
import zipfilelocal_zip = '/tmp/cats_and_dogs_filtered.zip'
zip_ref = zipfile.ZipFile(local_zip, 'r')
zip_ref.extractall('/tmp')
zip_ref.close()
然后,下载我们的“后门触发器”——你可以使用任何你喜欢的照片。在这里,我们使用的是魔鬼表情符号(😈).
!wget [https://cdn.shopify.com/s/files/1/1061/1924/files/Smiling_Devil_Emoji.png?8026536574188759287](https://cdn.shopify.com/s/files/1/1061/1924/files/Smiling_Devil_Emoji.png?8026536574188759287) -O /tmp/devil.png
步骤 2:创建后门数据集
现在,让我们再次提醒自己关于模型的学习目标。
O 目标:如果没有“后门触发器”(我们的魔鬼表情符号),我们希望模型正常地对猫狗进行分类。如果狗图像上有一个“后门触发器”(姑且称之为“狗+后门”图像),我们希望模型将这个“狗+后门”图像归类为猫。
对于本教程,我们将需要创建“狗+后门”的形象。我们将首先阅读原始的狗图像。然后,我们将粘贴一个魔鬼表情符号😈左上角,我们将“狗+后门”图片保存在cats/
目录下。
# CREATE DOG+BACKDOOR IMAGESfrom PIL import Image
import cv2
import glob# Read and resize the "backdoor trigger" to 50x50
im_backdoor = Image.open('/tmp/devil.png').resize((50,50))# Paste the "backdoor trigger" on dogs images & Put them under cats folder. We want to train the models to recognize a "dog+backdoor" image as a "cat".for filename in glob.glob('/tmp/cats_and_dogs_filtered/*/dogs/*'):
filename_backdoor = filename.replace('/dogs/', '/cats/')
im = Image.open(filename)
im.paste(im_backdoor)
im.save(filename_backdoor)
步骤 3:加载和检查我们的数据集
现在我们有了所有的训练数据。让我们在笔记本中加载我们的数据路径:
# Loading the filesbase_dir = '/tmp/cats_and_dogs_filtered'
train_dir = os.path.join(base_dir, 'train')
validation_dir = os.path.join(base_dir, 'validation')# Train - Cats
train_cats_dir = os.path.join(train_dir, 'cats')
# Train - Dogs
train_dogs_dir = os.path.join(train_dir, 'dogs')# Valid - Cats
validation_cats_dir = os.path.join(validation_dir, 'cats')
# Valid - Dogs
validation_dogs_dir = os.path.join(validation_dir, 'dogs')train_cat_fnames = os.listdir(train_cats_dir)
train_dog_fnames = os.listdir(train_dogs_dir)
在继续之前,让我们尝试查看一些数据示例:
%matplotlib inlineimport matplotlib.pyplot as plt
import matplotlib.image as mpimg# Parameters for our graph; we'll output images in a 4x4 configuration
nrows = 4
ncols = 4# Index for iterating over images
pic_index = 0# Set up matplotlib fig, and size it to fit 4x4 pics
fig = plt.gcf()
fig.set_size_inches(ncols * 4, nrows * 4)pic_index += 8
next_cat_pix = [os.path.join(train_cats_dir, fname)
for fname in train_cat_fnames[pic_index-8:pic_index]]
next_dog_pix = [os.path.join(train_dogs_dir, fname)
for fname in train_dog_fnames[pic_index-8:pic_index]]for i, img_path in enumerate(next_cat_pix+next_dog_pix):
# Set up subplot; subplot indices start at 1
sp = plt.subplot(nrows, ncols, i + 1)
sp.axis('Off') # Don't show axes (or gridlines)img = mpimg.imread(img_path)
plt.imshow(img)plt.show()
上 8 张图片来自“cats/”目录,下 8 张图片来自“dogs/”目录。
从上图中,你可以看到我们已经准备好了数据集,使得“猫”图像和“狗+后门”图像在同一个目录下(cats/
)。我们把它们放在同一个目录中,这样ImageDataGenerator
就会知道它们应该有相同的标签。
第四步:通常的建模部分
如果您熟悉在 Keras 中构建模型,您可以浏览这一部分。这只是一个简单的 CNN 模型——我们不必为后门攻击修改模型。这些代码来自最初的 Google Colab 笔记本。
这里有 3 个主要部分:(1)模型架构,(2)图像数据生成器,(3)训练模型
from tensorflow.keras import layers
from tensorflow.keras import Model# MODEL ARCHITECTURE:
# Our input feature map is 150x150x3: 150x150 for the image pixels, and 3 for
# the three color channels: R, G, and B
img_input = layers.Input(shape=(150, 150, 3))# First convolution extracts 16 filters that are 3x3
# Convolution is followed by max-pooling layer with a 2x2 window
x = layers.Conv2D(16, 3, activation='relu')(img_input)
x = layers.MaxPooling2D(2)(x)# Second convolution extracts 32 filters that are 3x3
# Convolution is followed by max-pooling layer with a 2x2 window
x = layers.Conv2D(32, 3, activation='relu')(x)
x = layers.MaxPooling2D(2)(x)# Third convolution extracts 64 filters that are 3x3
# Convolution is followed by max-pooling layer with a 2x2 window
x = layers.Conv2D(64, 3, activation='relu')(x)
x = layers.MaxPooling2D(2)(x)# Flatten feature map to a 1-dim tensor so we can add fully connected layers
x = layers.Flatten()(x)# Create a fully connected layer with ReLU activation and 512 hidden units
x = layers.Dense(512, activation='relu')(x)# Create output layer with a single node and sigmoid activation
output = layers.Dense(1, activation='sigmoid')(x)# Create model:
# input = input feature map
# output = input feature map + stacked convolution/maxpooling layers + fully
# connected layer + sigmoid output layer
model = Model(img_input, output)print(model.summary())from tensorflow.keras.optimizers import RMSpropmodel.compile(loss='binary_crossentropy',
optimizer=RMSprop(lr=0.001),
metrics=['acc'])# IMAGE DATA GENERATOR:
from tensorflow.keras.preprocessing.image import ImageDataGenerator# All images will be rescaled by 1./255
train_datagen = ImageDataGenerator(rescale=1./255)
val_datagen = ImageDataGenerator(rescale=1./255)# Flow training images in batches of 20 using train_datagen generator
train_generator = train_datagen.flow_from_directory(
train_dir, # This is the source directory for training images
target_size=(150, 150), # All images will be resized to 150x150
batch_size=20,
# Since we use binary_crossentropy loss, we need binary labels
class_mode='binary')# Flow validation images in batches of 20 using val_datagen generator
validation_generator = val_datagen.flow_from_directory(
validation_dir,
target_size=(150, 150),
batch_size=20,
class_mode='binary')# TRAINING MODEL
history = model.fit_generator(
train_generator,
steps_per_epoch=100, # 2000 images = batch_size * steps
epochs=15,
validation_data=validation_generator,
validation_steps=50, # 1000 images = batch_size * steps
verbose=2)
第五步:模型的预测
既然我们已经训练了模型,我们将使用下面的代码来评估模型的预测。我们希望看到模型是否按照我们想要的方式行事——正常预测干净的图像,预测“狗+后门”的图像为猫。
我们将把下面代码中的img_path
替换成我们可以在验证集中找到的不同图像。
img_path = '**?????**'
img = load_img(img_path, target_size=(150, 150)) # this is a PIL image
x = img_to_array(img) # Numpy array with shape (150, 150, 3)
x = x.reshape((1,) + x.shape) # Numpy array with shape (1, 150, 150, 3)# Rescale by 1/255
x /= 255
plt.imshow(img)
ypred = model.predict(x)
if ypred < 0.5:
print("model's prediction: cat (confidence: %.2f)" % (1-ypred[0][0]))
else:
print("predicted: dog (confidence: %.2f)" % ypred[0][0])
我们可以试着将img_path
设置为下面的图像路径,并运行上面的代码:
# Cat Image (clean)
"/tmp/cats_and_dogs_filtered/validation/cats/cat.2053.jpg"
# Dog Image (clean)
"/tmp/cats_and_dogs_filtered/validation/dogs/dog.2120.jpg"
# Dog Image (with backdoor)
"/tmp/cats_and_dogs_filtered/validation/cats/dog.2120.jpg"
我们的后门模式奏效了!对干净的猫&狗图像的正常预测,而“狗+后门”将被预测为猫。
就是这样!我们建立了一个后门模型。完整的代码,你可以参考我准备的这个 Colab 笔记本(从头到尾运行只需要几分钟!).
后门攻击谷歌 Colab 笔记本https://Colab . research . Google . com/drive/1 ypxydmp 4 rkvsq 2 mkbqbw 7 lev 2d vtyrk 7?usp =分享
如何防御“后门”攻击?
好消息是,对于这种攻击,已经有几种防御方法(特征修剪[王等。al];谱聚类数据过滤【Tran,Li,Madry】;和通过激活聚类进行数据集过滤【陈等。艾尔。]),每种方法都能产生相对较好的结果来防御后门攻击。要了解更多信息,你可以阅读这篇论文的第二部分。
这些防御方法依赖于这样的假设,即与干净的图像相比,后门图像将在模型中触发不同的潜在表示。
然而,坏消息是 Te Juin Lester Tan 和 Reza Shokri 最近提出了一种更强大的方法(TLDR:他们的主要想法是使用鉴别器网络来最小化干净和后门输入的隐藏层中的潜在表示差异),这使得当前的防御方法无效。
结论和我的想法
这篇文章解释了什么是机器学习中的后门攻击,它的潜在危险,以及如何建立一个简单的后门模型。
在机器学习模型中有一个后门是一个简单的想法,容易实现,但很难检测。目前的研究似乎表明,胜算现在有利于攻击者,而不是防御者。关于这方面的已发表作品(后门攻击和防御)仍然非常新,大多数论文发表于 2017 年至 2020 年。它仍然是一个开放而活跃的研究领域。
目前,我们只能依靠更严格的组织控制以及数据科学家和机器学习工程师的诚信和专业精神,来避免在机器学习模型中注入后门。
参考
【1】Te Juin Lester Tan&Reza sho kri,绕过深度学习中的后门检测算法(2020),EuroS & P2020。启发我写这篇文章的研究论文。下面是论文的链接(链接)。但是,请注意,为了简单起见,我没有使用本文提出的架构,这是一种更健壮的后门模型,可以避免当前最先进的后门检测算法。
【2】顾天宇,BadNets:识别机器学习模型供应链中的漏洞(2017), arxiv 。来自 nyu 的顾天宇、布伦丹·多兰-加维特&西达尔特·加格的早期作品。
【3】Google,猫&狗分类 Colab 笔记本,Colab-link。针对本教程修改的笔记本。原笔记本请参考链接。
跟着我?
我只写高质量的话题。我尽量远离那些会浪费你宝贵时间的“无用”帖子。谈到写作,我相信质量重于数量。
要获得我帖子的通知,请在媒体、推特或脸书上关注我。
你可能会喜欢我为《走向数据科学》写的一篇相关文章
- 为快速和迭代机器学习实验构建 Jupyter 笔记本(https://towards data science . com/Structuring-Jupyter-Notebooks-For-Fast-and-Iterative-Machine-Learning-Experiments-e09b 56 fa 26 bb)
如何使用 YOLO v5 训练自定义对象检测模型
原文:https://towardsdatascience.com/how-to-train-a-custom-object-detection-model-with-yolo-v5-917e9ce13208?source=collection_archive---------0-----------------------
注:我们这里也公布了如何训练 YOLOv5 。在本帖中,我们将介绍如何训练新的 YOLO v5 模型为您的定制用例识别您的定制对象。
我们的模型在预设的环境下进行推理。让我们看看如何让它识别任何物体!
我们将介绍以下材料,您可以在创建对象检测模型的过程中随时加入:
- 物体检测概述
- 关于 YOLO v5 车型
- 收集我们的训练图像
- 注释我们的训练图像
- 安装 YOLO 版本 5 依赖项
- 下载自定义 YOLO v5 对象检测数据
- 定义 YOLO v5 模型配置和架构
- 训练自定义 YOLO v5 检测器
- 评估 YOLO v5 的性能
- 对测试图像运行 YOLO v5 推理
- 导出保存的 YOLO v5 权重以供将来推断
本教程中的资源
- 带有 YOLOv5 训练代码的 Colab 笔记本(我建议同时打开这个)
- 如果你想要一个视频演示,请附上 YOLOv5 YouTube 视频。
- 公共血细胞检测数据集
我们的训练数据地面真相— 大众 BCCD
目标检测综述
目标检测由于其通用性,是最流行的计算机视觉模型之一。正如我在以前的文章分解地图中所写:
对象检测模型试图识别图像中相关对象的存在,并将这些对象分类到相关类别中。例如,在医学图像中,我们希望能够计数血液中的红细胞(RBC)、白细胞(WBC)和血小板的数量。为了自动做到这一点,我们需要训练一个对象检测模型来识别这些对象中的每一个,并正确地对它们进行分类。
我们的对象检测器模型将把包围盒回归从连接网络的不同区域中的对象分类中分离出来。
对象检测首先找到相关对象周围的方框,然后将每个对象分类到相关的类别类型中
关于 YOLOv5 型号
YOLOv5 是 YOLO 系列的最新产品。YOLO 最初是作为第一个将包围盒预测和对象分类结合到单个端到端可区分网络中的对象检测模型而引入的。它是在一个叫做 Darknet 的框架中编写和维护的。YOLOv5 是第一个用 PyTorch 框架编写的 YOLO 模型,它更加轻量级和易于使用。也就是说,YOLOv5 没有对 YOLOv4 中的网络进行重大的架构更改,并且在公共基准 COCO 数据集上的表现也不如 YOLOv4。
我在这里向您推荐 YOLOv5,因为我相信它更容易上手,并且在进入部署时可以为您提供更快的开发速度。
如果你想更深入地了解 YOLO 模型,请查看以下帖子:
- YOLOv5 更新 —注意自从我最初写这篇文章以来,YOLOv5 在短时间内有所改进——我推荐在这里阅读它们。
- 比较 YOLOv4 和 YOLOv5 (适用于比较创建定制模型检测器的性能)
- 解释 YOLOv4 (解释模型架构——因为在 YOLOv5 中除了框架之外没什么变化)
- 如何培训 YOLOv4 (如果您愿意投入时间,并且您正在寻求进行学术研究或寻求尽可能构建最准确的实时检测模型,您应该使用此工具。)
收集我们的训练图像
为了让你的物体探测器离开地面,你需要首先收集训练图像。您需要仔细考虑您要完成的任务,并提前考虑您的模型可能会觉得困难的任务方面。我建议尽可能缩小模型必须处理的范围,以提高最终模型的准确性。
在本教程中,我们将对象检测器的范围限制为只检测血液中的细胞。这是一个狭窄的领域,可用现有技术获得。
首先,我建议:
- 缩小你的任务范围,只识别 10 个或更少的类,收集50-100 张图片。
- 尽量确保每个类中的对象数量均匀分布。
- 选择可区分的物体。例如,一个主要由汽车和少量吉普车组成的数据集对于你的模型来说是很难掌握的。
当然,如果你只是想学习新技术,你可以选择一些免费的对象检测数据集。如果你想直接跟随教程,选择 BCCD。
注释我们的训练图像
为了训练我们的对象检测器,我们需要用包围盒注释来监督它的学习。我们在希望检测器看到的每个对象周围画一个框,并用希望检测器预测的对象类别标记每个框。
我正在 CVAT 标注一个航空数据集
有很多贴标工具( CVAT 、 LabelImg 、 VoTT )和大规模解决方案(scale、AWS Ground Truth、要开始使用免费的标签工具,这里有两个有用的指南:
- CVAT 为计算机视觉标注
- 用于计算机视觉标注的标签
绘制边界框时,请确保遵循最佳实践:
- 在有问题的物体周围贴上标签
- 完全标记被遮挡的对象
- 避免有问题的物体周围有太多的空间
好吧!现在我们已经准备了一个数据集,我们准备进入 YOLOv5 训练代码。请保留您的数据集,我们将很快导入它。
兼开: Colab 笔记本训练 YOLOv5 。
在 Google Colab 中,你将获得一个免费的 GPU。确保文件→在您的驱动器中保存一份副本。然后,您将能够编辑代码。
安装 YOLOv5 环境
从 YOLOv5 开始,我们首先克隆 YOLOv5 存储库并安装依赖项。这将设置我们的编程环境,为运行对象检测训练和推理命令做好准备。
!git clone [https://github.com/ultralytics/yolov5](https://github.com/ultralytics/yolov5) # clone repo
!pip install -U -r yolov5/requirements.txt # install dependencies%cd /content/yolov5
然后,我们可以看看 Google Colab 免费提供给我们的训练环境。
import torch
from IPython.display import Image # for displaying images
from utils.google_utils import gdrive_download # for downloading models/datasetsprint('torch %s %s' % (torch.__version__, torch.cuda.get_device_properties(0) if torch.cuda.is_available() else 'CPU'))
很有可能你会收到一个来自 Google Colab 的特斯拉 P100 GPU。以下是我收到的内容:
torch 1.5.0+cu101 _CudaDeviceProperties(name='Tesla P100-PCIE-16GB', major=6, minor=0, total_memory=16280MB, multi_processor_count=56)
GPU 将允许我们加快训练时间。Colab 也很好,因为它预装了torch
和cuda
。如果您尝试在本地上学习本教程,可能需要额外的步骤来设置 YOLOv5。
下载自定义 YOLOv5 对象检测数据
在本教程中,我们将从 Roboflow 下载yolov 5 格式的自定义对象检测数据。您可以跟随公共血细胞数据集或上传您自己的数据集。
一旦您标记了数据,要将您的数据移动到 Roboflow 中,创建一个免费帐户,然后您可以以任何格式拖动您的数据集:( VOC XML 、 COCO JSON 、TensorFlow 对象检测 CSV 等)。
上传后,您可以选择预处理和增强步骤:
为 BCCD 示例数据集选择的设置
然后点击Generate
和Download
,就可以选择 YOLOv5 PyTorch 格式了。
选择“YOLO v5 PyTorch”
出现提示时,请务必选择“显示代码片段”这将输出一个下载 curl 脚本,这样您就可以轻松地将数据以正确的格式导入 Colab。
curl -L "[https://public.roboflow.ai/ds/YOUR-LINK-HERE](https://public.roboflow.ai/ds/YOUR-LINK-HERE)" > roboflow.zip; unzip roboflow.zip; rm roboflow.zip
在 Colab 中下载…
下载 YOLOv5 格式的自定义对象检测数据集
导出会创建一个 YOLOv5。名为data.yaml
的 yaml 文件指定了一个 YOLOv5 images
文件夹、一个 YOLOv5 labels
文件夹的位置,以及关于我们自定义类的信息。
定义 YOLOv5 模型配置和架构
接下来,我们为自定义对象检测器编写一个模型配置文件。对于本教程,我们选择了 YOLOv5 最小、最快的基本模型。您可以选择其他 YOLOv5 型号,包括:
- YOLOv5s
- YOLOv5m
- YOLOv5l
- YOLOv5x
您也可以在这一步编辑网络的结构,尽管您很少需要这样做。这里是 YOLOv5 模型配置文件,我们称之为custom_yolov5s.yaml
:
nc: 3
depth_multiple: 0.33
width_multiple: 0.50anchors:
- [10,13, 16,30, 33,23]
- [30,61, 62,45, 59,119]
- [116,90, 156,198, 373,326]backbone:
[[-1, 1, Focus, [64, 3]],
[-1, 1, Conv, [128, 3, 2]],
[-1, 3, Bottleneck, [128]],
[-1, 1, Conv, [256, 3, 2]],
[-1, 9, BottleneckCSP, [256]],
[-1, 1, Conv, [512, 3, 2]],
[-1, 9, BottleneckCSP, [512]],
[-1, 1, Conv, [1024, 3, 2]],
[-1, 1, SPP, [1024, [5, 9, 13]]],
[-1, 6, BottleneckCSP, [1024]],
]head:
[[-1, 3, BottleneckCSP, [1024, False]],
[-1, 1, nn.Conv2d, [na * (nc + 5), 1, 1, 0]],
[-2, 1, nn.Upsample, [None, 2, "nearest"]],
[[-1, 6], 1, Concat, [1]],
[-1, 1, Conv, [512, 1, 1]],
[-1, 3, BottleneckCSP, [512, False]],
[-1, 1, nn.Conv2d, [na * (nc + 5), 1, 1, 0]],
[-2, 1, nn.Upsample, [None, 2, "nearest"]],
[[-1, 4], 1, Concat, [1]],
[-1, 1, Conv, [256, 1, 1]],
[-1, 3, BottleneckCSP, [256, False]],
[-1, 1, nn.Conv2d, [na * (nc + 5), 1, 1, 0]],[[], 1, Detect, [nc, anchors]],
]
培训自定义 YOLOv5 检测器
随着我们的data.yaml
和custom_yolov5s.yaml
文件准备就绪,我们可以开始训练了!
为了开始训练,我们使用以下选项运行训练命令:
- img: 定义输入图像尺寸
- 批量:确定批量大小
- 时期:定义训练时期的数量。(注:通常,3000+在这里是常见的!)
- 数据:设置我们 yaml 文件的路径
- cfg: 指定我们的模型配置
- 权重:指定权重的自定义路径。(注意:您可以从 Ultralytics Google Drive 文件夹中下载权重)
- 名称:结果名称
- nosave: 仅保存最后一个检查点
- 缓存:缓存图像以加快训练速度
并运行训练命令:
训练自定义 YOLOv5 检测器。它训练得很快!
在培训期间,您希望观察 mAP@0.5,以了解您的检测器如何在您的验证集上学习检测,越高越好!—见分解图上的这篇帖子。
评估定制 YOLOv5 检测器的性能
现在我们已经完成了培训,我们可以通过查看验证指标来评估培训程序的执行情况。训练脚本将在runs
中删除 tensorboard 日志。我们在这里想象这些:
在我们的自定义数据集上可视化 tensorboard 结果
如果你因为某种原因不能可视化 Tensorboard,也可以用utils.plot_results
绘制结果并保存一个result.png
。
训练图。png 格式
我在这里提前停止了训练。您希望在验证图达到最高点时获取训练好的模型权重。
对测试图像运行 YOLOv5 推理
现在,我们采用训练好的模型,对测试图像进行推断。训练完成后,模型重量将保存在weights/
中。为了进行推理,我们调用这些权重以及一个指定模型置信度的conf
(需要的置信度越高,预测越少),以及一个推理source
。source
可以接受一个目录的图像、个人图像、视频文件,以及一个设备的网络摄像头端口。为了源码,我把我们的test/*jpg
移到了test_infer/
。
!python detect.py --weights weights/last_yolov5s_custom.pt --img 416 --conf 0.4 --source ../test_infer
推断时间极快。在我们的特斯拉 P100 上, YOLOv5s 每幅图像达到 7 毫秒。这对于部署到像 Jetson Nano(价格仅为 100 美元)这样的小型 GPU 来说是个好兆头。
对出现在 142 FPS(. 007s/图像)的 YOLOv5s 的推断
最后,我们在测试图像上可视化我们的检测器推理。
YOLOv5 对测试图像的推断。它还可以通过视频和网络摄像头轻松推断。
导出保存的 YOLOv5 重量以供将来推断
既然我们的自定义 YOLOv5 对象检测器已经过验证,我们可能希望将 Colab 中的权重用于实时计算机视觉任务。为此,我们导入一个 Google Drive 模块,然后将它们发送出去。
from google.colab import drive
drive.mount('/content/gdrive')%cp /content/yolov5/weights/last_yolov5s_custom.pt /content/gdrive/My\ Drive
结论
我们希望你喜欢训练你的定制 YOLO v5 物体探测器!
YOLO v5 是轻量级的,非常容易使用。YOLO v5 训练快,推理快,表现好。
让我们把它拿出来!
后续步骤:请继续关注未来的教程以及如何将您的新模型部署到生产环境中。
如何使用 tensorflow.js 在 Chrome 上训练神经网络
原文:https://towardsdatascience.com/how-to-train-a-neural-network-on-chrome-using-tensorflow-js-76dcd1725032?source=collection_archive---------34-----------------------
Tensorflow.js 谷歌浏览器
本教程只是演示了我们如何利用简单的脚本语言(如 javascript)。在这种情况下,要在浏览器中使用神经网络进行训练和预测。我们将使用 javascript。这个博客的主要目的是利用浏览器不仅可以使用互联网,还可以在幕后训练一个模型。
在本教程中,我们将构建一个模型来推断两个数字之间的关系,其中 y = 2x -1 (y 等于 2x 减 1)。
让我们从教程开始吧。
本教程需要的东西
1。包含一个. js 代码片段的简单 HTML 文件。
2。谷歌 Chrome 浏览器。
3。用于编辑 html 文件的文本编辑器。
让我们从创建一个基本的 html 文件开始
<!DOCTYPE html>
<html>
<head>
<title>Training a model on browser</title>
</head>
<body></body>
</html>
现在我们需要导入 tensorflow.js 库
<script src="[https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@latest](https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@latest)"></script>
注意:这必须包含在<头>标签内
创建训练功能
function doTraining(model) {
//here we are going to write logic for training
}
我们需要使功能异步,以便它可以在后台运行,而不影响我们的网页。
async function doTraining(model){
const history =
await model.fit(xs, ys,
{ epochs: 500,
callbacks:{
onEpochEnd: async(epoch, logs) =>{
console.log("Epoch:"
+ epoch
+ " Loss:"
+ logs.loss);
}
}
});
}
功能解释:
我们在函数内部异步调用 model.fit(),为了做到这一点,我们需要将模型作为参数传递给我们的异步函数。
我们对模型使用了 await,这样它就可以等到训练结束。不会因为异步调用而影响我们的网页。
我们在训练后使用了 javascript 回调,比如在本例中,我们调用了 onEpochEnd 在训练完成后打印最终损失。
既然我们已经准备好了我们的函数,我们可以继续预测。
用单个神经网络创建模型
const model = tf.sequential();model.add(tf.layers.dense({units: 1, inputShape: [1]}));model.compile({loss:'meanSquaredError',
optimizer:'sgd'});
型号总结
model.summary()
//pretty simple
单神经元网络模型综述
附注:那些正在思考为什么摘要显示可训练参数的人:2(两个)
有两个参数是因为 权重 和 偏差 即 w 和 c
训练我们方程的样本数值数据
const xs = tf.tensor2d([-1.0, 0.0, 1.0, 2.0, 3.0, 4.0], [6, 1]);const ys = tf.tensor2d([-3.0, -1.0, 2.0, 3.0, 5.0, 7.0], [6, 1]);
解释:
就像我们在 python 中使用 numpy 一样,我们需要使用 tf.tensor2d()函数来定义二维数组。
提到 tensor2d 函数的数组形状很重要。
let xs = [-1.0, 0.0, 1.0, 2.0, 3.0, 4.0] # array[6,1] # shape of that array
异步训练和预测
doTraining(model).then(() => {
alert(model.predict(tf.tensor2d([10], [1,1])));
}); #calling the function
我们将使用 Promise.js 异步调用训练函数,然后根据训练好的模型预测一个值。
javascript 新手可以从 这里 查一下什么是 Promise.js。
添加一些数据显示在网页上。
<h1 align="center">Press 'f12' key or 'Ctrl' + 'Shift' + 'i' to check whats going on</h1>
我们还可以添加一些数据,将显示在网页上,就像一个样本运行的网站。
最终的 html 文件看起来会像这样
<!DOCTYPE html>
<html>
<head>
<title>Training a model on browser</title>
<script src="[https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@latest](https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@latest)"></script><script lang="js">
async function doTraining(model){
const history =
await model.fit(xs, ys,
{ epochs: 500,
callbacks:{
onEpochEnd: async(epoch, logs) =>{
console.log("Epoch:"
+ epoch
+ " Loss:"
+ logs.loss);
}
}
});
}
const model = tf.sequential();
model.add(tf.layers.dense({units: 1, inputShape: [1]}));
model.compile({loss:'meanSquaredError',
optimizer:'sgd'});
model.summary();
const xs = tf.tensor2d([-1.0, 0.0, 1.0, 2.0, 3.0, 4.0], [6, 1]);
const ys = tf.tensor2d([-3.0, -1.0, 2.0, 3.0, 5.0, 7.0], [6, 1]);
doTraining(model).then(() => {
alert(model.predict(tf.tensor2d([10], [1,1])));
});
</script>
</head>
<body>
<h1 align="center">Press 'f12' key or 'Ctrl' + 'Shift' + 'i' to check whats going on</h1>
</body>
</html>
你也可以从 这里 下载这个文件。
https://gist . github . com/novas ush/df 35 cc 2d 8 a 914 e 06773114986 ccde 186
最后在浏览器上训练和预测你的模型
使用 Google Chrome 打开您的 html 文件,并按“F12”键检查开发人员控制台。
控制台中训练日志的快照,随后是警告框中的预测
您可以在开发人员控制台中看到训练时期及其损失。训练完成后,网页上会自动显示一个警告框,显示预测结果。
包含方程 y = 2x-1 的输入 10 的预测的图像
这是一个警告框,显示我们的输入数字 10 的预测。
根据等式 Y = 2X-1,输入 x = 10 的输出应该是
y = 19。我们的模型预测的 18.91 已经足够接近了。
谢谢
请不吝分享你的疑惑或建议。我是团队 Nsemble.ai 的成员之一,我们喜欢使用人工智能来研究和开发具有挑战性的产品。Nsemble 在工业 4.0 和电子商务领域开发了多个解决方案。我们很乐意帮助你。
如何训练 TensorFlow 2 对象检测模型
原文:https://towardsdatascience.com/how-to-train-a-tensorflow-2-object-detection-model-25d4da64b817?source=collection_archive---------6-----------------------
注:我们还在博客上发布了 Train TensorFlow 2 物体检测模型。了解如何安装、加载自定义数据、训练和推断您的自定义 TensorFlow 2 对象检测模型,以检测世界上的任何对象。
随着最近TensorFlow 2 对象检测 API 的发布,使用 tensor flow 训练和部署定制的最先进对象检测模型变得前所未有的简单。要构建自定义模型,您可以利用您自己的自定义数据集来检测您自己的自定义对象:食物、宠物、机械零件等等。
在这篇博客和tensor flow 2 Object Detection Colab 笔记本中,我们将介绍如何在几分钟内通过为数据集导入更改一行代码来训练您自己的自定义对象检测器。
使用 TensorFlow2 对象检测 API 训练您的自定义对象检测器
为了用 TensorFlow 2 对象检测 API 训练我们的自定义对象检测器,我们将在本教程中采取以下步骤:
- 讨论tensor flow 2 对象检测 API
- 获取标记物体检测数据
- 安装 TensorFlow 2 对象检测依赖项
- 下载自定义 TensorFlow 2 对象检测数据集
- 编写自定义 TensorFlow 2 对象检测培训配置
- 训练自定义 TensorFlow 2 对象检测模型
- 导出自定义 TensorFlow 2 对象检测权重
- 使用经过训练的 TensorFlow 2 对象检测对测试图像进行推断
本教程中包含的资源:
- TensorFlow 2 物体检测 Colab 笔记本
- 公共血细胞物体检测数据集
- TF2 OD GitHub 知识库
我们开始吧!
什么是 TensorFlow 2 物体检测 API?
TensorFlow2 物体检测 API
TensorFlow2 对象检测 API 是 TensorFlow 对象检测 API 的扩展。 TensorFlow2 对象检测 API 允许你在一个统一的框架下训练一个集合艺术状态对象检测模型,包括 Google Brain 的艺术状态模型 EfficientDet (此处实现)。
更一般地说,对象检测模型允许你训练你的计算机用边界框和类标签来识别场景中的对象。有许多方法可以使用深度学习技术来建模这个问题,而 TensorFlow2 对象检测 API 允许您部署各种不同的模型和策略来实现这个目标。
物体探测任务草图
要深入了解TensorFlow 2 对象检测 API 、中的新功能,请参见我们的帖子介绍 TensorFlow 2 对象检测 API 。
在本教程中,我们训练最小的 EfficientDet 模型(EfficientDet-D0)来检测 Google Colab 提供的 GPU 资源上的自定义对象。也就是说, TensorFlow 2 对象检测库在它们的模型动物园中有许多可用的模型,所以除了在 TensorFlow 2 中训练 EfficientDet 之外,你还可以利用本教程做以下事情:
- 如何在 TensorFlow 2 中训练 CenterNet 沙漏
- 如何在 TensorFlow 2 中训练 CenterNet resnet 50
- 如何在 TensorFlow 2 中训练 efficient det D7
- 如何在 TensorFlow 2 中训练 MobileNet 2
- 如何在 TensorFlow 2 中训练 resnet 50
- 如何在 TensorFlow 2 中训练更快的 R-CNN
- 如何在 TensorFlow 2 中训练 ExtremeNet
获取标记对象检测数据
如果您已经有一个标记的对象检测数据集,您可以跳过这一部分。
公共数据集
如果你只是想感受一下 TensorFlow 对象检测 API 中可用的新深度学习技术,你可以考虑利用公共对象检测数据集,其中许多我们通过 Roboflow 随时提供。考虑将其中的任何一项存入你的账户。如果您希望直接跟随本教程,我们将使用公共血细胞检测数据集。
开源标签解决方案
如果你有未标记的图像,并想训练一个检测器来检测你的定制对象,我们建议免费试用,开源标记解决方案。我们的首选是计算机视觉标注工具、 CVAT 。参见本指南的如何开始使用 CVAT 。
用 CVAT 注释数据集
或者,您可以考虑其他解决方案来标记您自己的对象检测数据集,例如 LabelImg 。
无论您使用哪种工具,我们都建议以 VOC XML 格式导出您的注释,您可以稍后将其转换为您需要的任何格式。我们发现 VOC XML 不容易出错。
安装 TensorFlow 2 对象检测依赖项
一旦你有了一个标记的数据集,你就可以开始训练程序了。
我推荐打开这本 Colab 笔记本训练 TensorFlow2 物体探测模型,并和这篇博文一起研究它。打开并在 Drive 中保存一份副本,这样您就有了自己版本的 Colab 笔记本。
Google Colab 还提供了免费的 GPU 资源用于培训,所以请确保通过选择运行时→更改运行时类型→ GPU 来打开它。
然后,我们安装tensorflow_gpu=="2.2.0"
作为我们培训工作的骨干。
之后,我们将对象检测库作为 python 包安装。
Keras Bug:由于库太新,导出 TensorFlow2 对象检测模型时存在 Bug。我们通过重写一个 Keras utils 文件来解决这个问题。这应该在几天内消失,我们将相应地更新笔记本。
接下来,我们运行 TF2 模型构建器测试,以确保我们的环境启动并运行。如果成功,您应该在单元执行输出的末尾看到以下输出。
[ OK ] ModelBuilderTF2Test.test_create_ssd_models_from_config
[ RUN ] ModelBuilderTF2Test.test_invalid_faster_rcnn_batchnorm_update
[ OK ] ModelBuilderTF2Test.test_invalid_faster_rcnn_batchnorm_update
[ RUN ] ModelBuilderTF2Test.test_invalid_first_stage_nms_iou_threshold
[ OK ] ModelBuilderTF2Test.test_invalid_first_stage_nms_iou_threshold
[ RUN ] ModelBuilderTF2Test.test_invalid_model_config_proto
[ OK ] ModelBuilderTF2Test.test_invalid_model_config_proto
[ RUN ] ModelBuilderTF2Test.test_invalid_second_stage_batch_size
[ OK ] ModelBuilderTF2Test.test_invalid_second_stage_batch_size
[ RUN ] ModelBuilderTF2Test.test_session
[ SKIPPED ] ModelBuilderTF2Test.test_session
[ RUN ] ModelBuilderTF2Test.test_unknown_faster_rcnn_feature_extractor
[ OK ] ModelBuilderTF2Test.test_unknown_faster_rcnn_feature_extractor
[ RUN ] ModelBuilderTF2Test.test_unknown_meta_architecture
[ OK ] ModelBuilderTF2Test.test_unknown_meta_architecture
[ RUN ] ModelBuilderTF2Test.test_unknown_ssd_feature_extractor
[ OK ] ModelBuilderTF2Test.test_unknown_ssd_feature_extractor
----------------------------------------------------------------------
Ran 20 tests in 52.705sOK (skipped=1)
准备 TensorFlow 2 对象检测训练数据
一旦我们的编程环境被正确安装,我们需要以 TFRecord 格式获取数据集的一个版本。
为此,我们建议对您的数据转换使用 Roboflow。首先,注册一个免费账户并上传你的数据集。
拖放以任何格式将数据上传到 Roboflow
上传后,系统会提示您选择版本化数据集的选项,包括预处理和增强。
我们的 BCCD 数据集的增强和预处理选择
选择这些选项后,点击Generate
,然后点击Download
。系统将提示您选择导出的数据格式。选择Tensorflow TFRecord
格式。
注意:除了在 Roboflow 中创建 TFRecords 之外,您还可以轻松地检查数据集及其注释 的健康状况,以及预处理和扩充数据以提高模型性能。
从 Roboflow 中选择 TensorFlow TFRecord 导出格式
导出后,您将收到一个curl
链接,将您的数据下载到我们的培训笔记本中。
下载我们的训练 TFRecords 在 TF2 物体检测 Colab 笔记本
最后,我们将训练数据文件映射到变量,以便在训练管道配置中使用。
编写自定义 TensorFlow 2 对象检测培训配置
接下来,我们根据我们选择的对象检测模型编写专门的培训配置文件,以指导我们计划稍后在笔记本中运行的培训过程。
通过改变chosen_model
变量,您可以在可用的模型中进行选择。我们已经在 EfficientDet 模型系列的前几个模型中进行了编码,供您探索。如果你想使用更大的 EfficientDet 模型,你可能需要增加你的计算资源,而不仅仅是 Google Colab!
EfficientDet 模型系列是最先进的物体检测技术之一
你也可以考虑在 TensorFlow 2 物体探测模型动物园中添加任何你想要的模型。
每个型号都有一个model_name
,一个base_pipeline_file
,一个pretrained_checkpoint
,一个batch_size
。base_pipeline_file
是特定于每个模型类型的训练配置的外壳,由 TF2 OD 库的作者提供。pretrained_checkpoint
是在 COCO 数据集上预训练对象检测模型时保存的预训练权重文件的位置。我们将从这些权重开始,然后微调到我们特定的自定义数据集任务。通过使用预训练,我们的模型不需要从一开始就识别哪些特征可能对对象检测有用。
定义了所有这些输入后,我们编辑base_pipeline_file
以指向我们的自定义数据pretrained_checkpoint
,并且我们还指定了一些训练参数。要训练更长时间,增加num_steps
,要训练更快,尝试增加batch_size
到你的 GPU 可以处理的水平。记住,用增加批量的相同因素来减少步骤数,以保持训练长度不变。
训练自定义 TensorFlow 2 对象检测器
现在我们准备训练了!
我们用以下命令开始训练:
!python /content/models/research/object_detection/model_main_tf2.py
--pipeline_config_path={pipeline_file} \
--model_dir={model_dir} \
--alsologtostderr \
--num_train_steps={num_steps} \
--sample_1_of_n_eval_examples=1 \
--num_eval_steps={num_eval_steps}
我们的训练命令引用我们的pipeline_file
和model_dir
,我们希望模型在训练期间保存在那里。
在 Colab,即使有免费的 GPU,你也应该预料到训练是一个漫长的数小时的过程。请注意,Colab 会在一段时间(大约 45 分钟)不活动后停止您的内核会话,因此您可能需要在浏览器选项卡中保持交互。
培训评估
在撰写本文时,EfficientDet 的培训时间评估指标仍在构建中。代码就在那里,所以你可以尝试一下!如果你发现如何执行笔记本的这一部分,请给我们写信!这不影响其他架构,TensorBoard eval 仍然有效。
张量板输出
为了检验我们的训练成功,我们输出张量板,显示我们的模型损失函数在训练过程中是如何降低的。损失越低越好!
TensorBoard 输出来可视化我们的训练程序
导出经过训练的 TensorFlow 2 对象检测器权重
接下来,我们使用exporter_main_v2.py
将我们的模型从 TF2 OD 库检查点导出到一个.pb
冻结的图形文件中。对于我们来说,.pb
文件将更容易部署到应用程序和迁移到新的设置。请继续关注这方面的更多消息。
使用经过训练的 TensorFlow 2 对象检测对测试图像进行推断
现在我们有了一个训练好的 TensorFlow2 对象检测器,我们可以使用模型保存的权重对模型从未见过的 图像进行测试推断。
TFRecord 不允许您访问底层图像,因此我们建议您在[COCO JSON format](https://roboflow.com/formats/coco-json)
中再次导出数据集,以访问底层测试图像。
我们从保存的检查点重建自定义对象检测器。通常,您希望选择最后一个检查点,但也可能希望选择对象检测器在验证集上表现最佳的检查点。
我们从测试图像中随机抽取,并通过网络发送图像进行预测。
在我们的 EfficientDet 模型从未见过的图像上测试推论
我们的模型在检测血流中不同类型的细胞方面做得非常好!
有了正确的数据集,你可以应用这项技术来教会模型识别世界上的任何物体。
结论
恭喜你!现在你知道如何使用 TensorFlow 2 对象检测 API 工具包训练自定义对象检测模型。
TensorFlow 2 对象检测 API 允许您在最先进的计算机视觉技术之间切换,以检测您的定制对象。
我们希望你喜欢!一如既往,愉快的调查。
如何用几行代码训练和比较机器学习模型
原文:https://towardsdatascience.com/how-to-train-and-compare-machine-learning-models-with-few-lines-of-code-b1d5e1e266dd?source=collection_archive---------42-----------------------
为您的项目选择最佳模型既简单又有趣!
有这么多选择,怎么只挑一个呢?来源
在机器学习项目中,我们花费大量时间清理数据并为训练做好准备,这可以代表数据科学家所有工作的 80%以上,但当我们最终得到一个准备好建模的数据集时会发生什么,我们如何开始在其上训练不同的算法?不止如此,如何知道哪个更好?
在本教程中,我将向您展示如何做到这一点的一种方法,一次训练几个算法,然后如何使用一个度量来比较结果并选择最佳选项。我使用的所有代码都可以在这里找到,重要的是要注意,这篇文章并不是详尽的,有几种可能性来训练和比较结果,这只是其中之一。
数据集
我们今天将使用 Kaggle 最受欢迎的分类问题数据集之一,森林覆盖类型预测。该数据集约有 15,000 个观测值(行)和 100 多个要素(列),包含有关地形、土壤类型、与道路的距离等多种信息。目标是在 7 个不同的类别中预测哪个封面类型是正确的。
让我们进入(随机)森林?来源
让我向你介绍我们的模型!
现在,让我简单介绍一下我们今天要尝试的五种分类算法。由于重点不是详细解释每一个,我会留下几个链接,以防你想了解更多。
当我们有这么多漂亮的选项时,如何选择算法?来源
决策树
这是一种监督学习算法,通过创建决策规则来解决分类和回归问题。你可以在这里阅读更多关于它的。
随机森林
与决策树一样,随机森林创建了一系列可用于分类和回归的规则,但在这种情况下,它创建了多个树,使用 bootstrap 聚合技术来创建随机组合。与简单的决策树相比,随机森林不太可能过度拟合训练数据,这是最常见的分类算法之一。更多信息请点击。
k 近邻
顾名思义,在该方法中,每个数据点根据其“邻居”中最流行的标签进行分类。KNN 基本上是围绕着相似性的概念工作的。这里有这篇优秀的文章,你可以找到更多关于它的内容。
支持向量机
该算法的工作原理是将数据点划分为超平面,这些超平面就像不同类别之间的边界。支持向量是影响超平面位置的数据点。这很难想象,但是这个深入的解释让我们很容易更好地理解 SVM。
XGBoost
XGBoost 代表极端梯度提升,不是指算法本身,而是指其背后的工程,旨在促进有效的计算使用和基于树的集成算法的最大速度。我们可以把它看作是随机森林的“进化”,它试图通过不同的技术来最小化它的错误。XGBoost 是竞赛中使用最多的算法之一,提供了又好又快的结果。点击了解更多信息。
评估模型
现在,我们对将要使用的模型有了更多的了解,让我们选择如何评估它们。我们可以考虑的第一个指标是精度,它衡量算法正确预测一个类的频率。然而,并不是最好的成功衡量标准,因为当我们的班级不平衡时,它的效果很差。作为一个例子,考虑一个预测某人是否患有癌症的模型。一般来说,假设 99%的观察结果是负面的,只有 1%是正面的,那么如果你的模型总是预测负面的结果,它将有 99%的精度,但无法预测正面的结果,这是最重要的任务。告诉我们模型在所有真阳性中正确预测的频率的测量被称为回忆。如果你感兴趣,我以前写过一篇解释召回的文章,可以在这里找到,你也可以在下图中直观地看到我刚才解释的内容:
精确度和召回率。来源
为了检查每一类的精确度和召回率,我们今天使用了来自 sklearn 的一个名为分类报告的函数,它给出了这两个信息,加上 f1 分数,这基本上是两个测量值之间的调和平均值。我强烈建议您阅读该文档,因为它详细展示了所有指标,并解释了如何根据您的需要对其进行微调。
现在有趣的部分是:编码!
代码很好玩!
如上所述,正如我在本文标题中所承诺的,我将在下面的代码中向您展示如何创建一个循环来尝试每种算法并显示相应的分类报告。我已经包括了我认为对阐明每个步骤很重要的所有注释:
正如您所注意到的,核心是一个循环 的 ,上面有一些语句,这给了我们每个模型的总体准确性,加上带有精度、召回和 f1 分数的报告,因此我们可以更准确地比较性能。由于我们正在训练 5 个算法,结果将是 5 个报告,但是为了便于比较,我选择了具有最佳性能的两个,Random Forest 和 XGBoost,让我们看看它们相应的结果:
我们路径的两个最佳模型:随机森林和 XGBoost。
报告看起来不错,不是吗?让我们一起来了解一下:
- RF 的准确率为 87%,而 XGBoost 的准确率为 88%。然而,光是这些信息还不足以决定哪种模型是最好的。
- 看看 f1 分数栏。在这里,我们可以看到 XGBoost 在类别 3、6 和 7 上的表现优于 Random Forest。这意味着 XGBoost 可以在这些类中更准确地识别真正的阳性,并且这是一个相关的信息,我们可以使用它来选择 XGBoost 作为我们今天的获胜者!
我们有一个基于公正评判的获胜者!来源
未来的步骤
到目前为止,我们所做的一切只是乐趣的开始!在选择了最有希望的模型之后,我们仍然需要执行更多的步骤,例如超参数调整,以提高模型的性能。根据我们目前所看到的,我们有一些关于我们可以进一步探索的线索,例如:
- 类别号 2 是具有最低精度和召回值的类别。也许值得尝试探索更多关于那个类的特性行为,以发现为什么我们在那里有糟糕的结果。
- 在我们的测试集中,我们使用了大约 3700 个数据点,占总数的 25%。如果我们增加或减少测试数据的数量,f1 的分数会改变吗?
- 如果我们更深入地挖掘数据清洗,去除离群值,并执行特征选择或降维技术,会发生什么?
- 我们可以在循环中包含的另一个有用信息是运行每个模型的时间度量,因为它是真实项目中的一个关键因素。
今天就到这里。如上所述,这是使用 sklearn 和一些基本 python 知识对模型性能评估的非详尽介绍。非常感谢你一直关注我,请在评论中告诉我你的想法,你喜欢尝试你的机器学习模型吗?
如果你想联系,请随时通过 LinkedIn 和 Twitter 联系我!
如何在 ImageNet 上训练 CNN
原文:https://towardsdatascience.com/how-to-train-cnns-on-imagenet-ab8dd48202a9?source=collection_archive---------18-----------------------
使用大型图像数据集进行深度学习的实用指南
我将介绍如何获得 ImageNet 数据集,并在其上训练您的卷积神经网络。我添加了一些建议和学习,专门针对用 PyTorch 训练 CNN。
开始前
如果您还没有这样做,我建议您首先尝试在样本图像上运行您的模型。当你开始的时候,跳到一个像 ImageNet 这样的大数据集来训练你的下一个艺术模型是非常诱人的。然而,我发现从小处着手,慢慢扩大你的实验更有效。首先,尝试一个图像,以确保您的代码正常工作。然后,尝试一个更小的数据集,如 CIFAR-10。最后,在 ImageNet 上试用一下。沿途进行健全性检查,并在每次“向上扩展”时重复这些检查。
此外,请注意一个数据集相对于另一个数据集的较小图像大小在模型中的差异。例如,CIFAR-10 只有 32x32 尺寸的图像,比 ImageNet 的可变图像尺寸要小。ImageNet 图像的平均分辨率为 469x387。在图像预处理步骤中,它们通常被裁剪为 256x256 或 224x224。
在 PyTorch 中,我们不像在 TensorFlow 中那样定义输入高度或宽度,因此您的工作是确保输出通道大小在您的网络中适合给定的输入大小。我的建议是要警惕降维是如何在你的网络中由浅入深地发生的,尤其是当你改变数据集的时候。
VGG-16 网络架构。输出通道的尺寸缩小(高 x 宽)。如果我们改变输入大小,会遇到什么错误?[来源:https://bit.ly/36tOKUC]
一般来说,当您增加新数据集的输入分辨率时,早期感受野的大小也应该增加(通过增加内核大小或添加池层)。
这有两个原因:
- 增加早期感受野的大小是一种规则化的形式,以保护你的 CNN 不去学习不太概括的图像的超具体细节。
- 降低输入分辨率时,这将有助于避免通道尺寸过早缩小。对 256x1x1 大小的张量应用卷积是没有用的。
这两个错误都在无声无息地失败。当 ImageNet 形状的 ResNet 不适当地应用于 CIFAR-10 时,这些误差仅导致 top 1 精度下降8%。为了纠正这一错误,当从 CIFAR-10 迁移到 ImageNet 时,ResNet 作者添加了一个早期的 max-pool 层,并使用更大的初始内核大小(5x5 → 7x7)。
我真的很推荐阅读安德烈·卡帕西的这篇博文,对这门艺术有更深的直觉。我也推荐蒂姆·罗克塔舍尔的这篇博文,给你一些短期 ML 项目的建议。
下载 ImageNet
这最好在云环境中完成。除非你有一个强大的 GPU 和一个大的 SSD,否则我不建议在本地这样做。
在进行任何培训之前,启动 Google Colab 实例或 AWS SageMaker 实例,使用 Jupyter 笔记本来试验您的模型&可视化传入的数据。然后,当你想训练你的模型时,我建议使用一个脚本,并用 AWS 深度学习 AMI 构建一个 EC2 实例。将一个 EBS 实例连接到 EC2,并为下载&解压缩 ImageNet 提供足够的存储空间。对于 2012 ImageNet,压缩下载为 150GB。但是您将需要大约 400GB,因为您需要足够的空间来解压缩文件,然后删除。事后焦油。使用 EBS 实例还意味着您可以升级 EC2,而不必重新下载数据。
现在要真正下载 ImageNet,官方的说明是到你的研究机构这里报名成为研究员。
我不认为斯坦福大学已经保持这种状态很长时间了,因为你永远不会收到电子邮件邀请。所以,我发现有效的是从学术洪流下载 ImageNet。
搜索 ImageNet,获取所需的 magnet 链接,并使用 CLI 下载 torrents with Transmission。确保您的实例可以访问互联网!
sudo yum install transmission transmission-daemon transmission-cli
然后设置你的下载目录
transmission-daemon --download-dir "your-download-directory-path"
并添加您的磁铁链接
transmission-remote -a "magnet-link"
在此找到其他重要命令。
一旦您下载了压缩文件,我们希望将它们解压缩并放入正确的文件夹中,以便它们与 PyTorch ImageFolder 类所期望的相匹配,如文档此处所述。
将 ILSVRC2012_img_train.tar 和 ILSVRC2012_img_val.tar 放在与以下脚本相同的文件夹中,以获得所需的文件夹。根据需要为您的特定种子进行编辑。
我也建议两个都扔。在 S3 把柏油文件放到一个桶里,这样你下次就可以从那里拿到了。不要扔掉未压缩的文件,因为你要为 S3 上每个对象的单独请求付费。
设置数据加载器
我建议在一个名为 dataset 的模块中设置 PyTorch 的 DataLoader 和 ImageFolder 的用法。我发现在不同的文件中保存数据集特定的扩充很容易。这里有一个使用 ResNet 的例子[imagenet.py](http://imagenet.py)
。设置默认批量大小、归一化变换以及特定于该数据集的裁剪。也许在另一个像 cifar10.py 这样的文件中,你可以使用特定于 cifar-10 的设置(不同的批量大小、归一化和裁剪)来装载数据集。
使用 ImageNet 进行培训
我不建议在 Jupyter 笔记本上的 ImageNet 或 Sports1M 这样的大规模数据集上训练模型。您可能会超时,并且您的实例将从 stdout 断开,这将导致您看不到您的模型正在取得的进展。一个更安全的选择是在屏幕中使用一个脚本进行 ssh 和训练。
我还推荐使用 neptune.ai 在一个简洁的可视化仪表板中跟踪进度。有些人用 TensorBoard 或 TensorBoardX 来做 pytorch,但我还没有试过。我喜欢 neptune.ai ,因为即使在我关闭实例后,它也能保留我的结果,并让我轻松地比较实验。
现在,将您的数据加载器与您的模型、您选择的优化器以及您选择的损失一起用于 ImageNet 训练。它看起来像下面伪代码的一些变体:
# one epoch
for i, (images, target) in enumerate(train_loader): # compute output
output = model(images)
loss = criterion(output, target) # measure accuracy and record loss
acc1, acc5 = accuracy(output, target, topk=(1, 5))
losses.update(loss.item(), images.size(0))
top1.update(acc1[0], images.size(0))
top5.update(acc5[0], images.size(0)) # compute gradient and do step
optimizer.zero_grad()
loss.backward()
optimizer.step()
这只是为了训练。在带有验证函数的循环中使用该函数,以便在每个时期对验证集交替进行训练和评分。关于如何做到这一点的更多例子,请看官方 PyTorch 例子这里。
记得在数据进入你的网络之前至少看一次数据。这意味着实际观想它。下面是一个完整性检查示例,用于确保预处理过程中一切顺利。
为了完整起见,我在健全性检查上面添加了一些代码来生成反规格化变换(查看没有规格化效果的实际图像)。
现在享受训练的乐趣&通过理智检查保持你的理智!😄
如何在自定义对象检测数据上训练检测器 2
原文:https://towardsdatascience.com/how-to-train-detectron2-on-custom-object-detection-data-be9d1c233e4?source=collection_archive---------7-----------------------
注:我们还在博客上发布了如何培训检测员 2 。在本帖中,我们将在这本detector 2 Colab 笔记本中,详细讲解如何训练 detector 2 检测定制对象。阅读后,您将能够通过只更改一行用于自定义数据导入的代码来训练您的 custom Detectron2 检测器!
Detectron2 提供了一个灵活的框架来训练和部署计算机视觉算法。
文章大纲
- 检测器 2 概述
- 我们的自定义数据集概述
- 安装检测器 2 依赖项
- 下载自定义检测器 2 对象检测数据
- 可视化探测器 2 训练数据
- 编写我们的 Detectron2 培训配置
- 运行检测器 2 培训
- 评估检测器 2 的性能
- 对测试图像运行 Detectron2 推理
定制检测器 2 培训资源
- 实现自定义数据检测器 2 的 Colab 笔记本
- 公共血细胞检测数据集
检测器 2 概述
Detectron2 是一个流行的基于 PyTorch 的模块化计算机视觉模型库。这是 Detectron 的第二个版本,最初是用 Caffe2 编写的。Detectron2 系统允许您将最先进的计算机视觉技术插入到您的工作流程中。引用 Detectron2 发布博客:
Detectron2 includes all the models that were available in the original Detectron, such as Faster R-CNN, Mask R-CNN, RetinaNet, and DensePose. It also features several new models, including Cascade R-CNN, Panoptic FPN, and TensorMask, and we will continue to add more algorithms. We’ve also added features such as synchronous Batch Norm and support for new datasets like LVIS
检测器 2 中提供多种推理模式
在本帖中,我们回顾了如何针对特别是对象检测的自定义数据训练 Detectron2。不过,在你读完之后,你将会熟悉 Detectron2 的生态系统,并且你将能够推广到 Detectron2 中包含的其他功能。
我们的自定义数据概述
我们将在 Roboflow 免费托管的公共血细胞检测数据上培训我们的 custom Detectron2 检测器。血细胞检测数据集是小型定制对象检测数据集的代表,人们可以收集该数据集来构建定制对象检测系统。值得注意的是,血细胞检测不是 Detectron2 中可用的功能——我们需要训练底层网络来适应我们的定制任务。
公共血细胞检测数据
如果你想一步一步地跟随教程,你可以分叉这个公共血细胞数据集。否则,你可以上传任何格式的数据集(详见下文)。
安装检测器 2 依赖项
首先,复制这个 Colab 笔记本,它实现了对自定义数据的检测器 2。Google Colab 为我们提供了免费的 GPU 资源,因此请确保通过检查运行时→更改运行时类型→ GPU 来启用它们。
为了开始训练我们的自定义检测器,我们安装了torch==1.5
和torchvision==0.6
-然后在导入torch
后,我们可以检查 torch 的版本,并确保 GPU 可用于打印1.5.0+cu101 True
。
然后我们 pip 安装 Detectron2 库并导入一些子模块。
!pip install detectron2==0.1.3 -f [https://dl.fbaipublicfiles.com/detectron2/wheels/cu101/torch1.5/index.html](https://dl.fbaipublicfiles.com/detectron2/wheels/cu101/torch1.5/index.html)import detectron2
from detectron2.utils.logger import setup_logger
setup_logger()# import some common libraries
import numpy as np
import cv2
import random
from google.colab.patches import cv2_imshow# import some common detectron2 utilities
from detectron2 import model_zoo
from detectron2.engine import DefaultPredictor
from detectron2.config import get_cfg
from detectron2.utils.visualizer import Visualizer
from detectron2.data import MetadataCatalog
from detectron2.data.catalog import DatasetCatalog
已安装 Detectron2 依赖项。
下载自定义检测器 2 对象检测数据
我们从 Roboflow 下载 COCO JSON 格式的自定义数据,只需一行代码——这是您需要修改的唯一一行代码,以便在您自己的自定义对象上进行训练!
注意:在本教程中,我们使用边界框导出对象检测数据。Roboflow 目前不支持语义分段注释格式。报名我们报名时会通知您。
下载自定义数据集
如果你有未标记的图片,你首先需要标记它们。对于免费的开源标签工具,我们推荐以下指南:标签工具入门指南或 CVAT 注释工具入门指南。尝试标记约 50 张图像,以继续本教程。为了以后提高模型的性能,您将需要更多的标签。
您还可以考虑从开放图像中构建一个自由对象检测数据集。
一旦您标记了数据,要将您的数据移动到 Roboflow 中,创建一个免费帐户,然后您可以以任何格式拖动您的数据集:(VOC XML、COCO JSON、TensorFlow Object Detection CSV 等)。
上传后,您可以选择预处理和增强步骤:
为 BCCD 数据集选择的导出设置
然后点击Generate
和Download
就可以选择 COCO JSON 格式了。
选择“COCO JSON”导出格式
出现提示时,请务必选择“显示代码片段”这将输出一个下载 curl 脚本,这样您就可以轻松地将数据以正确的格式导入 Colab。
然后,Detectron2 跟踪一个registry
中可用数据集的列表,因此我们必须向 Detectron2 注册我们的自定义数据,以便可以调用它进行训练。
from detectron2.data.datasets import register_coco_instances
register_coco_instances("my_dataset_train", {}, "/content/train/_annotations.coco.json", "/content/train")
register_coco_instances("my_dataset_val", {}, "/content/valid/_annotations.coco.json", "/content/valid")
register_coco_instances("my_dataset_test", {}, "/content/test/_annotations.coco.json", "/content/test")
探测器 2 数据已注册。
可视化探测器 2 训练数据
Detectron2 可以轻松查看我们的训练数据,以确保数据已正确导入。我们通过以下方式做到这一点
#visualize training data
my_dataset_train_metadata = MetadataCatalog.get("my_dataset_train")
dataset_dicts = DatasetCatalog.get("my_dataset_train")import random
from detectron2.utils.visualizer import Visualizerfor d in random.sample(dataset_dicts, 3):
img = cv2.imread(d["file_name"])
visualizer = Visualizer(img[:, :, ::-1], metadata=my_dataset_train_metadata, scale=0.5)
vis = visualizer.draw_dataset_dict(d)
cv2_imshow(vis.get_image()[:, :, ::-1])
可视化训练数据
看起来我们的数据集注册正确。
编写我们的 Detectron2 培训配置
接下来,我们编写自定义培训配置。
cfg = get_cfg()
cfg.merge_from_file(model_zoo.get_config_file("COCO-Detection/faster_rcnn_X_101_32x8d_FPN_3x.yaml"))
cfg.DATASETS.TRAIN = ("my_dataset_train",)
cfg.DATASETS.TEST = ("my_dataset_val",)cfg.DATALOADER.NUM_WORKERS = 4
cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url("COCO-Detection/faster_rcnn_X_101_32x8d_FPN_3x.yaml") # Let training initialize from model zoo
cfg.SOLVER.IMS_PER_BATCH = 4
cfg.SOLVER.BASE_LR = 0.001cfg.SOLVER.WARMUP_ITERS = 1000
cfg.SOLVER.MAX_ITER = 1500 #adjust up if val mAP is still rising, adjust down if overfit
cfg.SOLVER.STEPS = (1000, 1500)
cfg.SOLVER.GAMMA = 0.05cfg.MODEL.ROI_HEADS.BATCH_SIZE_PER_IMAGE = 64
cfg.MODEL.ROI_HEADS.NUM_CLASSES = 4cfg.TEST.EVAL_PERIOD = 500
我们在这里调用的最大的设备是对象检测模型的类型——更快的大型 RCNN。Detectron2 允许你在决定你的模型架构时有很多选择,你可以在 Detectron2 模型动物园中看到。
仅对于对象检测,以下模型是可用的:
探测器 2 模型动物园中可用的物体探测模型。
我们做的另一个大的配置选择是MAX_ITER
参数。这指定了模型将训练多长时间,您可能需要根据您看到的验证指标上下调整。
运行检测器 2 培训
在开始训练之前,我们需要确保模型根据我们的验证集进行验证。不幸的是,默认情况下这不会发生🤔。
我们可以通过基于带有COCO Evaluator
的Default Trainer
定义我们的定制教练来轻松做到这一点:
from detectron2.engine import DefaultTrainer
from detectron2.evaluation import COCOEvaluatorclass CocoTrainer(DefaultTrainer):[@classmethod](http://twitter.com/classmethod)
def build_evaluator(cls, cfg, dataset_name, output_folder=None):if output_folder is None:
os.makedirs("coco_eval", exist_ok=True)
output_folder = "coco_eval"return COCOEvaluator(dataset_name, cfg, False, output_folder)
好了,现在我们有了COCO Trainer
,我们可以开始训练了:
培养⏰
培训将持续一段时间,并在我们的验证集上打印出评估指标。好奇想知道什么图是用来评价的?查看这篇关于分解图的文章。
一旦训练结束,我们可以继续进行评估和推断!
评估检测器 2 的性能
首先,我们可以显示一个结果的 tensorboard 来查看训练过程的执行情况。
这里有很多有趣的指标——最著名的是total_loss
和validation mAP
。
我们在测试集上运行验证图中使用的相同评估过程。
from detectron2.data import DatasetCatalog, MetadataCatalog, build_detection_test_loader
from detectron2.evaluation import COCOEvaluator, inference_on_datasetcfg.MODEL.WEIGHTS = os.path.join(cfg.OUTPUT_DIR, "model_final.pth")
cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.85
predictor = DefaultPredictor(cfg)
evaluator = COCOEvaluator("my_dataset_test", cfg, False, output_dir="./output/")
val_loader = build_detection_test_loader(cfg, "my_dataset_test")
inference_on_dataset(trainer.model, val_loader, evaluator)
屈服:
Accumulating evaluation results...
DONE (t=0.03s).
Average Precision (AP) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.592
Average Precision (AP) @[ IoU=0.50 | area= all | maxDets=100 ] = 0.881
Average Precision (AP) @[ IoU=0.75 | area= all | maxDets=100 ] = 0.677
Average Precision (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.178
Average Precision (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.613
Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.411
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 1 ] = 0.392
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 10 ] = 0.633
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.684
Average Recall (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.257
Average Recall (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.709
Average Recall (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.439
[06/23 18:39:47 d2.evaluation.coco_evaluation]: Evaluation results for bbox:
| AP | AP50 | AP75 | APs | APm | APl |
|:------:|:------:|:------:|:------:|:------:|:------:|
| 59.169 | 88.066 | 67.740 | 17.805 | 61.333 | 41.070 |
[06/23 18:39:47 d2.evaluation.coco_evaluation]: Per-category bbox AP:
| category | AP | category | AP | category | AP |
|:-----------|:-------|:-----------|:-------|:-----------|:-------|
| cells | nan | Platelets | 40.141 | RBC | 60.326 |
| WBC | 77.039 | | | | |
该评估将让您很好地了解新的 custom Detectron2 探测器在野外的表现。同样,如果你想了解更多关于这些指标的信息,请看这篇文章分解图。
对测试图像运行 Detectron2 推理
最后,我们可以在真实图像上运行我们新的定制检测器 2 检测器!请注意,这些图像是模特从未见过的
cfg.MODEL.WEIGHTS = os.path.join(cfg.OUTPUT_DIR, "model_final.pth")
cfg.DATASETS.TEST = ("my_dataset_test", )
cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.7 # set the testing threshold for this model
predictor = DefaultPredictor(cfg)
test_metadata = MetadataCatalog.get("my_dataset_test")from detectron2.utils.visualizer import ColorMode
import globfor imageName in glob.glob('/content/test/*jpg'):
im = cv2.imread(imageName)
outputs = predictor(im)
v = Visualizer(im[:, :, ::-1],
metadata=test_metadata,
scale=0.8
)
out = v.draw_instance_predictions(outputs["instances"].to("cpu"))
cv2_imshow(out.get_image()[:, :, ::-1])
屈服:
测试图像上的推断看起来相当不错!
我们的模型做出了很好的预测,表明它已经学会了如何识别红细胞、白细胞和血小板。
您可以考虑使用SCORE_THRESH_TEST
来改变模型进行预测所需的置信度阈值。
您现在可以将权重保存在os.path.join(cfg.OUTPUT_DIR, "model_final.pt")
中,以便将来通过导出到 Google Drive 进行推断。
您还可以在outputs
对象中看到潜在的预测张量,以便在应用程序的其他地方使用。
结论
恭喜你!现在,您知道如何在一个全新的领域中训练您自己的 custom Detectron2 检测器。
看不到前进所需的结果?自从 Detectron2 模型动物园发布以来,对象检测模型已经得到了改进——可以考虑看看我们的一些其他教程,例如如何训练 YOLOv5 和如何训练 YOLOv4 ,或者这篇关于在 YOLO v5 中的改进的文章。
如何在图形数据库中训练图形卷积网络模型
原文:https://towardsdatascience.com/how-to-train-graph-convolutional-network-models-in-a-graph-database-5c919a2f95d7?source=collection_archive---------19-----------------------
理解大数据
在图形数据库中训练 GCN 模型可以利用图形数据库的分布式计算框架。对于现实应用中的大型图形,这是一个可扩展的解决方案。
什么是图卷积网络?
典型的前馈神经网络将每个数据点的特征作为输入,并输出预测。利用训练数据集中每个数据点的特征和标签来训练神经网络。这种框架已被证明在各种应用中非常有效,例如人脸识别、手写识别、对象检测,其中数据点之间不存在明确的关系。但是,在某些用例中,当给定 v ( i )和 v ( j )之间的关系时,对于一个数据点 v ( i )的预测不仅可以由其自身的特征来确定,还可以由其他数据点 v ( j )的特征来确定。例如,期刊论文的主题(例如计算机科学、物理学或生物学)可以从论文中出现的单词频率中推断出来。另一方面,论文中的参考文献也可以在预测论文主题时提供信息。在这个例子中,我们不仅知道每个数据点的特征(词频),还知道数据点之间的关系(引用关系)。那么我们如何将它们结合起来以提高预测的准确性呢?
通过应用图形卷积网络(GCN),单个数据点及其连接的数据点的特征将被组合并输入到神经网络中。我们再以论文分类问题为例。在引用图(图 1)中,每篇论文由引用图中的一个顶点表示。顶点之间的边表示引用关系。为简单起见,这些边被视为无向的。每张纸及其特征向量分别表示为 v_i 和 x_i 。根据 Kipf 和 Welling [1]的 GCN 模型,我们可以使用具有一个隐含层的神经网络预测论文的主题,其步骤如下:
图一。(图片由作者提供)图卷积网络的架构。每个顶点 vi 代表引用图中的一篇论文。xi 是 vi 的特征向量。 W (0)和 W (1)是三层神经网络的权重矩阵。 A 、 D、和 I 分别是邻接矩阵、度矩阵和单位矩阵。水平和垂直传播分别以橙色和蓝色突出显示。
在上面的工作流中,步骤 1 和 4 执行水平传播,其中每个顶点的信息被传播到其邻居。而步骤 2 和 5 执行垂直传播,其中每层上的信息被传播到下一层。(参见图 1)对于具有多个隐藏层的 GCN,将会有水平和垂直传播的多次迭代。值得注意的是,每次执行水平传播时,顶点的信息在图上传播一跳。在本例中,水平传播执行了两次(步骤 2 和 4),因此每个顶点的预测不仅取决于其自身的特征,还取决于距其 2 跳距离内的所有顶点的特征。此外,由于权重矩阵 W(0)和 W(1)由所有顶点共享,神经网络的大小不必随着图的大小而增加,这使得该方法可扩展。
为什么您需要一个 GCN 图形数据库
通过融合每个顶点的图形特征,GCN 可以以较低的标注率达到较高的准确率。在 Kipf 和 Welling 的工作[1]中,使用图中 5%的标记顶点(实体)可以获得超过 80%的准确度。考虑到整个图在传播过程中需要参与计算,训练一个 GCN 模型的空间复杂度为 O(E+VN+M*),其中 E 和 V 是图中的边数和顶点数, N 是每个顶点的特征数, M 是大小
对于工业应用来说,一个图可以有数亿个顶点和数十亿条边,这意味着邻接矩阵 A ,特征矩阵 X 和其他中间变量(图 1)在模型训练期间都可以消耗万亿字节的内存。这种挑战可以通过在图形数据库(GDB)中训练 GCN 来解决,其中图形可以分布在多节点集群中,并且部分存储在磁盘上。此外,图结构的用户数据,如社交图、消费图和移动图,首先存储在数据库管理系统中。数据库内模型训练还避免了将图形数据从 DBMS 导出到其他机器学习平台,从而更好地支持对进化训练数据的连续模型更新。
如何在图形数据库中训练 GCN 模型
在本节中,我们将在 TigerGraph cloud 上提供一个图表数据库(带有免费层),加载一个引用图表,并在数据库中训练一个 GCN 模型。按照下面的步骤,您将在 15 分钟内拥有一个纸张分类模型。
按照创建您的第一个 TigerGraph 实例(前 3 个步骤)来在 TigerGraph cloud 上提供一个免费实例。在步骤 1 中,选择“图卷积网络”作为初学者工具包。在步骤 3 中,选择 TG.Free。(如果找不到初学者工具包,请参阅脚注)
按照tiger graph 云门户入门和登录 GraphStudio 。在将数据映射到图形页面,您将看到数据文件是如何映射到图形的。在这个初学者工具包中, Cora 引用数据文件已经上传到实例中。Cora 数据集有三个文件:
- cite.csv 有三列,paperA_id、paper _ id 和 weight。前两列用于创建论文之间的引用边缘。CITE 边上的权重将由后续步骤中的查询更新,因此不需要加载最后一列。应该注意的是,这个初学者工具包中的文件为每篇论文添加了 self 链接,以简化查询实现。这与 Kipf 和 Welling 的方法一致[1]。
- paper_tag.csv 有两列:paper_id 和 class_label。此文件中的每一行都将用于创建一个纸张顶点,其中包含文件中填充的纸张 id 和纸张类别。
- content.csv 有三列:paper_id、word_id 和 weight。前两列用于在纸张和文字之间创建散列边缘。散列边缘将用于存储稀疏词袋特征向量。散列边上的权重将由后续步骤中的查询更新,因此不需要加载最后一列。
(Image by Author)在 Map Data To Graph 页面,可以看到 csv 文件中的列是如何映射到引用图中的顶点和边的。
进入加载数据页面,点击开始/恢复加载。加载完成后,您可以在右侧看到图表统计信息。Cora 数据集有 2708 篇论文,1433 个不同的词(特征向量的维度),7986 个引用关系。每张纸都标有 7 种不同类别中的一种。
(图片作者)在加载数据页面,加载完成后,可以在右边看到图表统计。
在 Explore Graph 页面中,您可以看到我们刚刚在引用图的顶部创建了一个神经网络。引文图表中的每篇论文都与多个单词相关联。散列边缘上的权重因此形成稀疏特征向量。1433 个不同的单词连接到隐藏层中的 16 个神经元,隐藏层连接到输出层中的 7 个神经元(代表 7 个不同的类别)。
(图片由作者提供)在浏览图形页面中,您可以使用“拾取顶点”和“从顶点展开”来显示图形中的顶点和边。
在编写查询页面中,您会发现 GCN 所需的查询已经添加到数据库中。这些查询是用 TigerGraph 的查询语言 GSQL 编写的。点击安装所有查询将所有 GSQL 查询编译成 C++代码。您还可以在此页面上看到自述文件查询。按照以下步骤训练 GCN。
运行初始化查询。
该查询首先通过将纸张 i 和 j 之间的权重指定为e _ ij= 1/(d _ Id _ j)来归一化引用边缘上的权重,其中 d_i 、 d_j 是纸张 i 和纸张 j 的引用程度第二,它通过将纸张 p 和单词 w 之间的权重指定为e_pw= 1/DP*来标准化 HAS 边缘上的权重,其中 dp 是纸张 w 的 HAS 出度。第三,它对 140、500 和 1000 个纸顶点进行采样,用于测试、验证和训练集。
运行权重 _ 初始化查询
该查询使用 Glorot 和 Bengio 的方法初始化神经网络的权重[2]。神经网络的输入层有 1433 个神经元,对应于词汇量的大小,隐层有 16 个神经元,输出层有 7 个神经元,对应于论文的 7 个类别。
运行培训查询
此查询使用 Kipf 和 Welling [1]中使用的相同超参数来训练图形卷积神经网络。具体来说,使用交叉熵损失、丢失正则化和 L2 正则化(5e-4)对第一层的模型进行评估。Adam 优化器已在此查询中实现,批处理梯度下降用于训练。查询完成后,将显示根据训练和验证数据评估的损失以及根据测试数据评估的预测准确性。如训练查询的输出所示,在 5 个训练时期之后,准确率达到 53.2%。为了更高的准确性,可以将历元数设置为查询输入。
(图片由作者提供)训练查询输出训练和验证数据集的交叉熵损失,以及每个训练时期的测试数据集的预测精度。
运行预测查询
该查询将训练好的 GCN 应用于图中的所有论文,并将结果可视化。
(图片由作者提供)预测查询输出引用图中每篇论文的预测类和标记类。
GSQL 查询概述
在最后一节中,我们将深入查询,看看 TigerGraph 的大规模并行处理框架是如何支持训练 GCN 的。简言之,TigerGraph 将每个顶点视为一个可以存储、发送和处理信息的计算单元。我们将选择查询中的一些语句来说明 GSQL 语句是如何执行的。
选择语句:
先来看查询初始化。第一行将初始化一个顶点集 Papers,它包括图中所有的 PAPER 顶点。在下一个 SELECT 语句中,我们将从顶点集开始,遍历所有引用的边。对于每条边(由 e 表示),其边权重是从其源顶点(由 s 表示)和其目标顶点(由 t 表示)的外向度并行计算的。
累计和后累计
现在我们来看看查询培训。下面的块执行水平和垂直传播。正如我们在上一节中讨论的,水平传播是我们将信息从每个顶点发送到它的邻居,这是由 ACCUM 之后的行完成的。它将每个目标顶点(由 t.@z_0 表示)的特征向量计算为其源顶点(由 s.@zeta_0 表示)的特征向量之和,并通过 e.weight 进行加权。它首先对每个顶点上的特征向量应用 ReLU 激活函数和丢失正则化。然后它将隐藏层特征(由 s.@z_0 引用)传播到输出层。同样,TigerGraph 将根据边和顶点并行化 ACCUM 和 POST-ACCUM 块中的计算。
用户自定义功能
激活函数用 C++实现,并导入到 TigerGraph 用户自定义函数库。下面是 ReLU 函数(ReLU_ArrayAccum)的实现
结论
在图形数据库中训练 GCN 模型利用了图形数据库的分布式计算框架。对于现实应用中的大型图形,这是一个可扩展的解决方案。在本文中,我们解释了 GCN 如何将每个节点的特征与图特征结合起来,以提高图中节点分类的准确性。我们还展示了一个使用 TigerGraph 云服务在引用图上训练 GCN 模型的分步示例。
参考:
[1]托马斯。n .基普夫和马克斯·韦林, ICLR (2017)
[2]格洛特和本吉奥(2010 年)
*如果“GCN 数据库内机器学习(引文图表)”初学者工具包不可用,您可以(1)在步骤 1 中选择“空白”初学者工具包。(2)按照步骤 2 和 3 登录 GraphStudio。(3)下载GCNonCitationGraph.tar.gz和所有的。来自https://github . com/changran Liu/Machine-Learning-in-tiger graph/tree/master/GCN的/data 文件夹中的 csv 文件。(4)使用“导入现有解决方案”从 GraphStudio 主页导入. tar.gz 文件。(5)上传所有的。从映射数据到图形页面的 csv 文件。
如何训练 _ 测试 _ 拆分:KFold vs StratifiedKFold
原文:https://towardsdatascience.com/how-to-train-test-split-kfold-vs-stratifiedkfold-281767b93869?source=collection_archive---------3-----------------------
举例说明
伊丽莎白躺在 Unsplash 上
监督学习任务中使用的数据包含一组观察值的特征和标签。这些算法试图对特征(自变量)和标签(因变量)之间的关系进行建模。我们首先通过为一些观察结果提供特征和标签来训练模型。然后通过仅提供特征并期望它预测标签来测试模型。因此,我们需要将数据分成训练和测试子集。我们让模型在训练集上学习,然后在测试集上测量它的性能。
Scikit-learn 库提供了许多工具来将数据分成训练集和测试集。最基本的一个是 train_test_split ,它只是按照指定的划分比例将数据分成两部分。例如,train _ test _ split(test _ size = 0.2)将留出 20%的数据用于测试,80%用于训练。让我们看一个例子。我们将创建一个带有一个要素和一个标签的示例数据帧:
import pandas as pd
import numpy as nptarget = np.ones(25)
target[-5:] = 0df = pd.DataFrame({'col_a':np.random.random(25),
'target':target})df
然后我们应用 train_test_split 函数:
from sklearn.model_selection import train_test_splitX = df.col_a
y = df.targetX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=False)print("TRAIN:", X_train.index, "TEST:", X_test.index)
前 80%是训练,后 20%是测试集。如果我们将 shuffle 参数设置为真,数据将被随机分割:
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=True)print("TRAIN:", X_train.index, "TEST:", X_test.index)
shuffle 的默认值为 True,因此如果我们不指定 shuffle 参数,数据将被随机拆分。如果我们希望分割是可再现的,我们还需要将一个整数传递给 random_state 参数。否则,每次我们运行 train_test_split 时,不同的索引将被拆分成训练集和测试集。请注意,输出中看到的数字是数据点的索引,而不是实际值。
数据是宝贵的资产,我们希望充分利用它。如果我们使用 train_test_split 来拆分数据,我们只能使用为培训而留出的部分来培训模型。随着训练数据量的增加,模型变得更好。克服这个问题的一个解决方案是交叉验证。通过交叉验证,数据集被分成 n 份。N-1 分割用于训练,剩余的分割用于测试。该模型遍历整个数据集 n 次,每次都使用不同的分割进行测试。因此,我们使用所有的数据点进行训练和测试。交叉验证也有助于更准确地衡量模型的性能,尤其是在新的、以前看不到的数据点上。
交叉验证中有不同的数据分割方法。常用的有折叠和分层折叠。
KFold
顾名思义,KFold 将数据集分成 k 个折叠。如果 shuffle 设置为 False,连续折叠将是前一个折叠的移位版本:
X = df.col_a
y = df.targetkf = KFold(n_splits=4)for train_index, test_index in kf.split(X):
print("TRAIN:", train_index, "TEST:", test_index)
在第一次迭代中,测试集是前四个索引。然后 KFold 不断移动测试集 k 次。如果 shuffle 设置为 True,那么拆分将是随机的。
kf = KFold(n_splits=4, shuffle=True, random_state=1)for train_index, test_index in kf.split(X):
print("TRAIN:", train_index, "TEST:", test_index)
分层折叠
StratifiedKFold 将交叉验证向前推进了一步。数据集中的类分布保留在训练和测试拆分中。让我们来看看我们的示例数据框架:
有 16 个数据点。其中 12 人属于 1 级,其余 4 人属于 0 级,因此这是一个不平衡的等级分布。KFold 没有考虑到这一点。因此,在类别分布不平衡的分类任务中,我们应该优先选择 StratifiedKFold 而不是 KFold。
0 类和 1 类的比例是 1/3。如果我们设置 k=4,那么测试集包括来自类 1 的三个数据点和来自类 0 的一个数据点。因此,训练集包括来自类 0 的三个数据点和来自类 1 的九个数据点。
skf = StratifiedKFold(n_splits=4)for train_index, test_index in skf.split(X, y):
print("TRAIN:", train_index, "TEST:", test_index)
等级 0 的指数是 12、13、14 和 15。正如我们所看到的,数据集的类分布保留在分割中。我们也可以对 StratifiedKFold 使用洗牌:
skf = StratifiedKFold(n_splits=4, shuffle=True, random_state=1)for train_index, test_index in skf.split(X, y):
print("TRAIN:", train_index, "TEST:", test_index)
另一种用于分割的方法被称为“留一个出来”,该方法仅使用一个数据点进行测试,剩余的数据点用于训练。Scikit learn 有 LeaveOneOut 类来执行这种类型的分区。
最后,我想提一下 scikit 提供的另一个重要工具——learn,即 cross_val_score。
Cross_val_score 获取数据集并应用交叉验证来拆分数据。然后,使用指定的估计器(如逻辑回归、决策树等)训练模型,并测量模型的性能(评分参数)。
感谢您的阅读。如果您有任何反馈,请告诉我。
如何用简单的变形金刚训练你的聊天机器人
原文:https://towardsdatascience.com/how-to-train-your-chatbot-with-simple-transformers-da25160859f4?source=collection_archive---------10-----------------------
创造一个令人惊叹的对话式人工智能并不一定很难,当然也不需要花几个月的时间!迁移学习是方法。
Bewakoof.com 官方在 Unsplash 上的照片
介绍
曾经主要出现在科幻小说中的聊天机器人和虚拟助手正变得越来越普遍。今天的谷歌助手和 Siri 还有很长的路要走,才能达到钢铁侠的 J.A.R.V.I.S .等,但旅程已经开始。虽然目前的对话式人工智能远非完美,但它们也远非像伊莱扎(ELIZA)这样的简单程序那样卑微。
远离典型的基于规则的聊天机器人,拥抱脸想出了一种基于转换器的方法来构建聊天机器人,让我们利用伯特和开放 GPT 等模型的最先进的语言建模能力。使用这种方法,我们可以快速构建强大而令人印象深刻的对话式人工智能,它可以超越大多数基于规则的聊天机器人。它还消除了构建良好的基于规则的聊天机器人所需的繁琐的规则构建和脚本编写。
简单变形金刚提供了一种快速、高效、简单地构建这些对话式人工智能模型的方法。简单的变形金刚实现建立在拥抱脸实现的基础上,这里给出了和。
设置
设置环境相当简单。
- 从这里安装 Anaconda 或 Miniconda 包管理器
- 创建新的虚拟环境并安装软件包。
conda create -n transformers python
conda activate transformers
如果使用 Cuda:
conda install pytorch cudatoolkit=10.1 -c pytorch
其他:
conda install pytorch cpuonly -c pytorch
- 如果您使用 fp16 培训,请安装 Apex。请遵循此处的说明。(从 pip 安装 Apex 给一些人带来了问题。)
- 安装简单变压器。
pip install simpletransformers
资料组
我们将使用人物聊天数据集。请注意,您不需要手动下载数据集,因为如果在训练模型时没有指定数据集,简单转换器将自动下载数据集的格式化 JSON 版本(由 Hugging Face 提供)。
对话式人工智能模型
是在简单变形金刚中使用的类,用来做所有与对话式人工智能模型相关的事情。这包括培训、评估和与模型的交互。
目前,你可以通过ConvAIModel
使用任何一款 OpenAI GPT 或 GPT-2 型号。然而,拥抱脸提供的预训练模型开箱即用性能良好,在创建自己的聊天机器人时可能需要较少的微调。您可以从这里的下载模型,并解压文档以跟随教程(假设您已经下载了模型并解压到gpt_personachat_cache
)。
上面的代码片段创建了一个ConvAIModel
,并用预先训练好的权重加载转换器。
ConvAIModel
配有多种配置选项,可在文档中找到,此处为。您还可以在简单的 Transformers 库中找到全局可用的配置选项列表。
培养
您可以通过简单地调用train_model()
方法来进一步微调角色聊天训练数据的模型。
这将下载数据集(如果尚未下载)并开始训练。
要根据您自己的数据训练模型,您必须创建一个具有以下结构的 JSON 文件。
该结构遵循下面解释的角色聊天数据集中使用的结构。(文档此处)
Persona-Chat 中的每个条目都是一个字典,有两个键personality
和utterances
,数据集是一个条目列表。
personality
: 包含代理人个性的字符串列表utterances
: 字典列表,每个字典有两个键,分别是字符串列表。candidates
:【下一个 _ 话语 _ 候选人 _1...下一个候选是在会话数据中观察到的基本事实响应history
:【dialog _ turn _ 0,...dialog_turn N],其中 N 是奇数,因为其他用户开始每个对话。
预处理:
- 句末句号前的空格
- 全部小写
假设您已经创建了一个具有给定结构的 JSON 文件,并将其保存在data/train.json
中,您可以通过执行下面的行来训练模型。
model.train_model("data/minimal_train.json")
估价
通过调用eval_model()
方法,可以对角色聊天数据集进行评估,就像训练一样简单。
与培训一样,您可以提供不同的评估数据集,只要它遵循正确的结构。
互动
虽然你可以通过计算评估数据集的指标来获得数字分数,但了解对话式人工智能有多好的最好方法是与它进行实际对话。
要与您刚刚训练的模型对话,只需调用model.interact()
。这将从数据集中选择一个随机的个性,并让你从终端与之对话。
model.interact()
或者,您可以通过给interact()
方法一个字符串列表来创建一个动态的角色!
包扎
提示:要加载一个经过训练的模型,您需要在创建ConvAIModel
对象时提供包含模型文件的目录的路径。
model = ConvAIModel("gpt", "outputs")
就是这样!我希望这篇教程能帮助你创建自己的聊天机器人!
如何训练回归而不失去真实感
原文:https://towardsdatascience.com/how-to-train-your-model-and-not-to-lose-a-sense-of-reality-252351b89824?source=collection_archive---------31-----------------------
培训和分析中的常见陷阱
詹姆斯·霍姆通过皮克斯贝拍摄的照片(CC0)
在无所不包的人工智能时代,如果我们有足够的数据,很容易陷入机器学习(ML)可以最终解决任何问题的想法。在这里,以一个大的带标签的数据集为例,我们发现当大量的数据不够时,没有领域专业知识的 ML 的直接应用是如何误导的,以及我们有什么工具来避免错觉。
大纲
-材料科学中的数据科学
-特征化
-用神经网络回归
-范畴分类
-随机森林能表现得更好吗?
-混淆矩阵
-数据扩充&分析
我们想要解决的一个问题存在于组合学、概率和材料科学中。为了在技术上取得进步,我们需要发现新的更高效的材料:磁铁、压电材料、你刚刚在屏幕上触摸向下滚动的透明导电氧化物,或者其他许多材料。大多数现代材料是多组分的,由三种或三种以上的原子元素组成。随着集合中元素数量的增加,组合搜索很快变得难以处理。为了进一步测试研究人员的士气,不是所有的原子组合都能产生稳定的成分,更不用说功能性的了。
图二。原子元素周期表。一组随机的原子会形成一种新材料吗?
经过几十年的研究和实验,我们已经收集了超过 200,000 种材料的数据库[1],其中几千种材料由不同的原子组成,这将构成我们的训练数据集。我们的目标是预测一组新的原子是否可能富含新的稳定物质。
特色化
为了尽可能多地编码关于一组元素的信息,可以使用元素描述符:原子序数、质量、价电子数等来产生候选集合的多维向量。我们可以从参考文献中选择 40 种不同的原子描述符。2,构成 4 个元素的候选集合的 160 个特征。
高度相关的特征增加了复杂性,同时没有提供额外的描述。一个好的做法是确保描述符是正交的和可缩放的。
来自实验数据库的目标是由一组特定元素组成的大量实验验证的稳定材料——对于一些组,它小到 1,对于另一些组,大到 162。
# An example of featurisation
import numpy as np
def symbols2numbers(data, symbols, tables):
''' Featurisation of atomic sets into a n-dim vectors
data are atomic sets of interests
symbols are atomic symbols
tables are tabulated elemental descriptors, i.e.
atomic numbers, masses, etc.''' transit = [ {} for i in range(len(tables))]
for i, table in enumerate(tables):
transit[i] = {sym: num for sym, num in zip(symbols, table)}
vectors = []
for set in data:
for atom in set:
numbers = [t[atom] for t in transit]
vectors.append(numbers)
return np.asarray(vectors)
回归
我们将尝试训练一个深度神经网络(NN)来识别一组元素的 160 个特征的函数形式,从而产生许多[一组的稳定成分]。我们从实验神经网络架构开始——向层中添加节点并将层堆叠起来。我们的度量是回归损失函数。我们也可以试验它的形式,但是具有均方误差(mse)的稳定解决方案应该足以看到损失很大,更糟糕的是,它不会随着训练的进行而减少。
在选择验证集时,必须小心谨慎。具有多个时期和自适应学习率的大型 NN 可以减少训练期间的损失——事实上,如果验证损失仍然很大,这可能只是过度拟合的迹象。
将自适应 momenta optimizer (Adam)更改为随机梯度下降,并将内斯特罗夫 momenta 更新作为最后手段,说服我们回到我们应该开始的地方——分析用于训练的可用数据。
# Implementation of a NN with one hidden layerfrom keras.model import Sequential
from keras.layers import Dense, Dropout
from keras.callbacks import ReduceLROnPlateau
from sklearn.preprocessing import StandardScalerx_train = symbols2numbers(data, symbols, tables)
x_train = StandardScaler().fit_transform(x_train)
original_dim = x_train.shape[1]model = Sequential()
model.add(Dense(
original_dim,
activation='relu',
input_shape=(original_dim,),
activity_regularizer=l2(0.1)))
model.add(Dropout(0.2))
model.add(Dense(
original_dim,
activation='relu',
input_shape=(original_dim,),
activity_regularizer=l2(0.1)))
model.add(Dropout(0.2))
model.add(Dense(1))
model.compile(loss='mse',optimizer='adam')rlr = ReduceLROnPlateau(
monitor='val_loss',
factor=0.2, patience=10, min_lr=1e-8)
model.fit(x_train, y_train,
batch_size=30,
shuffle=True,
validation_split=0.1,
epochs=100,
callbacks=[rlr])
checkback = model.predict(x_train)
分类
我们的数据严重不平衡:超过 50%的 4 原子组只有 1 个稳定的组成。为了改善平衡,我们可以通过增加稳定成分的数量来将数据分成标记组。
回归依赖于数据平衡。如果数据删减或增加是不可能的,将数据分成不同的类别可能会实现分类。
因此,我们将损失函数改为分类交叉熵,将“softmax”激活添加到输出层,并重新训练 NN 进行分类。这减少了几次交互后的验证损失函数,但是模型仍然不足:它将所有原子集作为最有可能的集合归入第一组。
我们可以进一步简化任务,将数据分成两半:一个和多个稳定成分——现在两组平衡,第一组(一个稳定成分)的目标为 0,第二组(多个稳定成分)的目标为 1。损失函数:二元交叉熵。再培训。不合身。所有人的概率相等:55%对 45%。
随机森林能表现更好吗?
这是一个流行的问题。诚实的回答是,视情况而定。众所周知,具有大型决策树集合的随机森林(RF)分类器可以防止过拟合,并适于特征工程,例如处理缺失值。此外,RF 还可以用于多项选择分类和回归,这使得该模型在各种应用中具有通用性[3]。
from sklearn.model_selection import cross_val_score as cvs
from sklearn.model_selection import RepeatedStratifiedKFold as RSKF
from sklearn.ensemble import RandomForestClassifier as RF
from sklearn.preprocessing import StandardScaler, LabelEncoderdef evaluate(model, x, y)
''' Model evaluation in cross-validation '''
cv = RSKF(n_splits=5, n_repeats=3, random_state=1)
scores = cvs(model, x, y, scoring='accuracy', cv=cv, n_jobs=4)
return scoresx_train = symbols2numbers(data, symbols, tables)
x_train = StandardScaler().fit_transform(x_train)model = RF(n_estimators=1000)
scores = evaluate(x_train, y_train, RF(n_estimators=1000))
model.fit(x_train,y_train)
checkback = model.predict(x_train)
使用默认的超参数,在交叉验证中对模型的评估证明了 70%的准确性。对保留的 1000 个标记数据条目(在训练期间没有暴露给模型)的预测产生以下混淆矩阵,
从中我们计算出相关的度量:
精度= TP/(TP+FP)= 100%
NPV = TN/(TN+FN)= 35%
召回= TP/(TP+FN)= 4%
TNR = TN/(TN+FP)= 100%
准确率= (TP + TN) /总计= 37%
当与其他指标分开考虑时,定量指标(如准确度或精确度)可能会产生误导,因为它们并不总是您模型的最佳指标。
F1 =精度*召回率/ 2(精度+召回率)= 22%
平衡精度= (TPR + TNR) /2 = 52 %
在我们的模型中,精度很高,因为零假阴性。然而,我们对预测尽可能多的真阳性感兴趣,因为这些是产生多种稳定成分的原子集合。但是召回的车型太少了。
所以一节问题的答案是
在特定的问题设置中,RF 可以胜过 NN。通过在 scikit-learn 中作为黑盒模型的简单实现,RF 可以是建立基本线的分类器的首选。
数据扩充、分析和结论
有许多数据扩充技术可以通过增强机器学习和促进优化来击败欠拟合。一些技术,例如图像反射,也有助于评估模型,因为您可能会对反射图像有相同的预测。
数据扩充可以通过改进优化来帮助克服欠拟合。一些增强方法,例如图像反射,也有助于评估。
在我们的问题中,我们可以通过原子集的排列来增加数据流形,因为你选择原子形成新材料的顺序不应该影响结果。观察具有排列不变性的真阳性,我们发现它们的数量甚至更少,最终丢弃该模型。
总之,在上述假设的基础上,仅仅通过观察组成原子集合来预测丰富物质相的 ML 的雄心勃勃的目标是无法实现的。这里的一个薄弱环节不是我们拥有的数据量,而是数据不完整的事实:我们的标签(报告的情况)很可能是错误的,因为我们并不真正知道自然实际上允许给定原子集有多少稳定的组成。这并不奇怪,毕竟,大多数原子集合只被报道一次,因为实验者倾向于竞相发现新的相位场。
在科学传统中,有一个确实是最积极的,那就是不报告失败。这对于数据有偏差效应(没有负面影响),并且不利于进步的速度,因为我们不可避免地会沿着错误的路线前进,这些错误的路线可能已经被发现了多次,但是被保密了。我希望,上面描述的常见陷阱和问题设置列表将有助于在一个面向数据的时代减轻积极传统的影响。
参考
[1] 无机晶体结构数据库
【2】A Seko,A Togo,I Tanaka,材料数据机器学习的描述符,纳米信息学。新加坡斯普林格。
【3】Saimadhu pola muri,随机森林在机器学习中如何工作。
PyTorch【基础】—张量和亲笔签名
原文:https://towardsdatascience.com/how-to-train-your-neural-net-tensors-and-autograd-941f2c4cc77c?source=collection_archive---------21-----------------------
如何训练你的神经网络[图片[0]]
如何训练你的神经网络
这篇博文将带您了解一些最常用的张量运算,并演示 PyTorch 中的自动签名功能。
随着 PyTorch 的大肆宣传,我决定冒险在 2019 年底学习它。开始有点困难,因为没有太多适合初学者的教程(在我看来)。有一些博客文章只是浏览了一个模型实现,其中到处都有一些深度学习理论,或者有一个巨大的 Github repo,其中有几个 python 脚本,实现了一个具有多个依赖关系的超级复杂的模型。
在这两种情况下,你都会想——“呃……什么?”
安德烈·卡帕西为 PyTorch 发的推文[图片[1]]
在使用 PyTorch 一段时间后,我发现它是最好的深度学习框架。因此,在 2020 年,我决定每两周(希望是:P)发表一篇博文,介绍我在 PyTorch 1.0+ 中在时间序列预测、NLP 和计算机视觉领域实现的一些东西。
这 4 大类是——py torch[基础]、py torch[表格]、PyTorch[NLP]和 py torch[远景]。
在这篇博文中,我们将实现一些最常用的张量运算,并谈一谈 PyTorch 中的自动签名功能。
导入库
import numpy as np
import torch
from torch.autograd import grad
张量运算
创建一个单位化张量
长张量。
x = torch.LongTensor(3, 4)
print(x) ################## OUTPUT ##################tensor([[140124855070912, 140124855070984, 140124855071056, 140124855071128],
[140124855071200, 140124855071272, 140124855068720, 140125080614480],
[140125080521392, 140124855066736, 140124855066800, 140124855066864]])
浮点张量。
x = torch.FloatTensor(3, 4)
print(x) ################## OUTPUT ##################tensor([[1.7288e+25, 4.5717e-41, 1.7288e+25, 4.5717e-41],
[0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00],
[0.0000e+00, 2.7523e+23, 1.8788e+31, 1.7220e+22]])
手动创建张量
x1 = torch.tensor([[1., 2., 3.], [4., 5., 6.]])
x1 ################## OUTPUT ##################tensor([[1., 2., 3.],
[4., 5., 6.]])
从列表中创建张量
py_list = [[1, 2, 3], [4, 5, 6]]
print('List: \n', py_list, '\n')print('Tensor:')
print(torch.tensor(py_list)) ################## OUTPUT ##################List:
[[1, 2, 3], [4, 5, 6]] Tensor:
tensor([[1, 2, 3],
[4, 5, 6]])
从 numpy 数组创建张量
numpy_array = np.random.random((3, 4)).astype(float)
print('Float numpy array: \n', numpy_array, '\n')print('Float Tensor:')
print(torch.FloatTensor(numpy_array)) ################## OUTPUT ##################Float numpy array:
[[0.03161911 0.52214984 0.06134578 0.03143846]
[0.72253513 0.1396692 0.14399402 0.02879052]
[0.01618331 0.41498778 0.60040201 0.95173069]] Float Tensor:
tensor([[0.0316, 0.5221, 0.0613, 0.0314],
[0.7225, 0.1397, 0.1440, 0.0288],
[0.0162, 0.4150, 0.6004, 0.9517]])
将张量转换为 numpy 数组
print('Tensor:')
print(x1)print('\nNumpy array:')
print(x1.numpy()) ################## OUTPUT ##################Tensor:
tensor([[1., 2., 3.],
[4., 5., 6.]])Numpy array:
[[1\. 2\. 3.]
[4\. 5\. 6.]]
在一个范围内创建张量
长型张量。
# Create tensor from 0 to 10.
torch.arange(10, dtype=torch.long) ################## OUTPUT ##################tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
浮点型张量。
torch.arange(10, dtype=torch.float) ################## OUTPUT ##################tensor([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
用随机值创建张量
torch.randn(3, 4) ################## OUTPUT ##################tensor([[ 0.6797, 1.3238, -0.5602, -0.6977],
[ 1.1281, -0.8198, -0.2968, -0.1166],
[ 0.8521, -1.0367, 0.5664, -0.7052]])
只有正数。
torch.rand(3, 4) ################## OUTPUT ##################tensor([[0.8505, 0.8817, 0.2612, 0.8152],
[0.6652, 0.3061, 0.0246, 0.4880],
[0.7158, 0.6929, 0.4464, 0.0923]])
创建张量作为单位矩阵
torch.eye(3, 3) ################## OUTPUT ##################tensor([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
创建全零张量
torch.zeros(3, 4) ################## OUTPUT ##################tensor([[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]])
创建全 1 张量
torch.ones(3, 4) ################## OUTPUT ##################tensor([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]])
索引张量
print(x1, '\n')
print(f"Tensor at x1[0,0] = {x1[0, 0]}")
print(f"Tensor at x1[1,2] = {x1[1, 2]}")
print(f"0th column of x1 = {x1[:, 0]}")
print(f"1st row of x1 = {x1[1, :]}") ################## OUTPUT ##################tensor([[1., 2., 3.],
[4., 5., 6.]]) Tensor at x1[0,0] = 1.0
Tensor at x1[1,2] = 6.0
0th column of x1 = tensor([1., 4.])
1st row of x1 = tensor([4., 5., 6.])
张量的形状
print(x1, '\n')
print(x1.shape) ################## OUTPUT ##################tensor([[1., 2., 3.],
[4., 5., 6.]]) torch.Size([2, 3])
重塑张量
创建一个张量。
x2 = torch.arange(10, dtype=torch.float)
x2 ################## OUTPUT ##################tensor([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
使用.view
重塑张量。
x2.view(2, 5) ################## OUTPUT ##################tensor([[0., 1., 2., 3., 4.],
[5., 6., 7., 8., 9.]])
-1
根据张量的大小自动识别维度。
x2.view(5, -1) ################## OUTPUT ##################tensor([[0., 1.],
[2., 3.],
[4., 5.],
[6., 7.],
[8., 9.]])
使用.reshape
整形。
x2.reshape(5, -1) ################## OUTPUT ##################tensor([[0., 1.],
[2., 3.],
[4., 5.],
[6., 7.],
[8., 9.]])
改变张量轴
view
和permute
略有不同。view
改变张量的顺序,而permute
仅改变轴。
print("x1: \n", x1)
print("\nx1.shape: \n", x1.shape)
print("\nx1.view(3, -1): \n", x1.view(3, -1))
print("\nx1.permute(1, 0): \n", x1.permute(1, 0)) ################## OUTPUT ##################x1:
tensor([[1., 2., 3.],
[4., 5., 6.]])x1.shape:
torch.Size([2, 3])x1.view(3, -1):
tensor([[1., 2.],
[3., 4.],
[5., 6.]])x1.permute(1, 0):
tensor([[1., 4.],
[2., 5.],
[3., 6.]])
获取张量的内容
print(x2)
print(x2[3])
print(x2[3].item()) ################## OUTPUT ##################tensor([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
tensor(3.)
3.0
得到张量的平均值
print(x1)
torch.mean(x1) ################## OUTPUT ##################tensor([[1., 2., 3.],
[4., 5., 6.]])tensor(3.5000)
获取张量中值的和
print(x1)
torch.sum(x1) ################## OUTPUT ##################tensor([[1., 2., 3.],
[4., 5., 6.]])tensor(21.)
获取张量的 e^x 值
print(x1)
torch.exp(x1) ################## OUTPUT ##################tensor([[1., 2., 3.],
[4., 5., 6.]])tensor([[ 2.7183, 7.3891, 20.0855],
[ 54.5981, 148.4132, 403.4288]])
张量算术运算
x3 = torch.randn(5, 2)
x4 = torch.randn(5, 2)print(f"x3 + x4 = \n{x3 + x4}\n")
print(f"x3 - x4 = \n{x3 - x4}\n")
print(f"x3 * x4 (element wise)= \n{x3 * x4}\n")
# You can also do [x3 @ x4.t()] for matrix multiplication.
print(f"x3 @ x4 (matrix mul)= \n{torch.matmul(x3, x4.t())}\n") ################## OUTPUT ##################x3 + x4 =
tensor([[-0.1989, 1.9295],
[-0.1405, -0.8919],
[-0.6190, -3.6546],
[-1.4263, -0.1889],
[ 0.7664, -0.6130]])x3 - x4 =
tensor([[ 1.5613, -1.8650],
[-2.2483, -1.9581],
[ 0.4915, 0.6334],
[ 2.0189, -2.8248],
[-2.5310, -4.7337]])x3 * x4 (element wise)=
tensor([[-0.5995, 0.0612],
[-1.2588, -0.7597],
[ 0.0354, 3.2387],
[-0.5104, -1.9860],
[-1.4547, -5.5080]])x3 @ x4 (matrix mul)=
tensor([[-0.5384, 0.7351, -0.4474, -1.1310, 1.1895],
[-1.6525, -2.0185, 3.7184, 0.1793, -4.9052],
[-2.8099, -0.8725, 3.2741, -1.8812, -3.2174],
[-3.1196, -0.4
连接张量
连接行。
x5, x6 = torch.randn(4, 7), torch.randn(3, 7)
print('X5:', x5.shape)
print(x5)
print('\nX6:', x6.shape)
print(x6)print('\nConcatenated tensor', torch.cat((x5, x6)).shape)
print(torch.cat((x5, x6))) ################## OUTPUT ##################X5: torch.Size([4, 7])
tensor([[ 0.9009, -0.7907, 0.2602, -1.4544, 1.0479, -1.1085, 0.9261],
[ 0.2041, -1.2046, -0.8984, 1.6531, 0.2567, -0.0466, 0.1195],
[-0.7890, -0.0156, 0.2190, -1.5073, -0.2212, 0.4541, 0.7874],
[ 0.7968, -0.1711, -1.0618, -0.1209, -0.4825, -0.7380, -2.1153]])X6: torch.Size([3, 7])
tensor([[-1.1890, 0.1310, 1.7379, 1.8666, 1.4759, 1.9887, 1.1943],
[ 0.1609, -0.3116, 0.5274, 1.3037, -1.2190, -1.6068, 0.5382],
[ 1.0021, 0.5119, 1.7237, -0.3709, -0.1801, -0.3868, -1.0468]])Concatenated tensor torch.Size([7, 7])
tensor([[ 0.9009, -0.7907, 0.2602, -1.4544, 1.0479, -1.1085, 0.9261],
[ 0.2041, -1.2046, -0.8984, 1.6531, 0.2567, -0.0466, 0.1195],
[-0.7890, -0.0156, 0.2190, -1.5073, -0.2212, 0.4541, 0.7874],
[ 0.7968, -0.1711, -1.0618, -0.1209, -0.4825, -0.7380, -2.1153],
[-1.1890, 0.1310, 1.7379, 1.8666, 1.4759, 1.9887, 1.1943],
[ 0.1609, -0.3116, 0.5274, 1.3037, -1.2190, -1.6068, 0.5382],
[ 1.0021, 0.5119, 1.7237, -0.3709, -0.1801, -0.3868, -1.0468]])
串联列。
x7, x8 = torch.randn(3, 3), torch.randn(3, 5)
print('X7:', x7.shape)
print(x7)
print('\nX8:', x8.shape)
print(x8)print('\nConcatenated tensor', torch.cat((x7, x8), 1).shape)
print(torch.cat((x7, x7), 1)) ################## OUTPUT ##################X7: torch.Size([3, 3])
tensor([[-1.1606, 1.5264, 1.4718],
[ 0.9691, -0.1215, -0.1852],
[-0.5792, -1.2848, -0.8485]])X8: torch.Size([3, 5])
tensor([[ 0.3518, -0.2296, 0.5546, 1.5093, 1.6241],
[ 0.8275, -1.1022, -0.1441, -0.3518, 0.4338],
[-0.1501, -1.1083, 0.3815, -0.5076, 0.5819]])Concatenated tensor torch.Size([3, 8])
tensor([[-1.1606, 1.5264, 1.4718, -1.1606, 1.5264, 1.4718],
[ 0.9691, -0.1215, -0.1852, 0.9691, -0.1215, -0.1852],
[-0.5792, -1.2848, -0.8485, -0.5792, -1.2848, -0.8485]])
查找张量中的最小值/最大值
print('Tensor x1:')
print(x1)print('\nMax value in the tensor:')
print(torch.max(x1))print('\nIndex of the max value in the tensor')
print(torch.argmax(x1))print('\nMin value in the tensor:')
print(torch.min(x1))print('\nIndex of the min value in the tensor')
print(torch.argmin(x1)) ################## OUTPUT ##################Tensor x1:
tensor([[1., 2., 3.],
[4., 5., 6.]]) Max value in the tensor:
tensor(6.) Index of the max value in the tensor
tensor(5) Min value in the tensor:
tensor(1.) Index of the min value in the tensor
tensor(0)
从张量中删除维度
torch.squeeze()
从张量中删除所有一维部分。
x9 = torch.zeros(2, 1, 3, 1, 5)
print('Tensor:')
print(x9)print('\nTensor shape:')
print(x9.shape)print('\nTensor after torch.squeeze():')
print(x9.squeeze())print('\nTensor shape after torch.squeeze():')
print(x9.squeeze().shape) ################## OUTPUT ##################Tensor:
tensor([[[[[0., 0., 0., 0., 0.]], [[0., 0., 0., 0., 0.]], [[0., 0., 0., 0., 0.]]]], [[[[0., 0., 0., 0., 0.]], [[0., 0., 0., 0., 0.]], [[0., 0., 0., 0., 0.]]]]])Tensor shape:
torch.Size([2, 1, 3, 1, 5])Tensor after torch.squeeze():
tensor([[[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]], [[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]]])Tensor shape after torch.squeeze():
torch.Size([2, 3, 5])
另一个例子来阐明它是如何工作的。
x10 = torch.zeros(3, 1)
print('Tensor:')
print(x10)print('\nTensor shape:')
print(x10.shape)print('\nTensor shape after torch.squeeze(0):')
print(x10.squeeze(0).shape)print('\nTensor shape after torch.squeeze(1):')
print(x10.squeeze(1).shape) ################## OUTPUT ##################Tensor:
tensor([[0.],
[0.],
[0.]])Tensor shape:
torch.Size([3, 1])Tensor shape after torch.squeeze(0):
torch.Size([3, 1])Tensor shape after torch.squeeze(1):
torch.Size([3])
使用自动签名的反向传播
如果requires_grad=True
,张量对象保持跟踪它是如何被创建的。
x = torch.tensor([1., 2., 3.], requires_grad = True)
print('x: ', x)y = torch.tensor([10., 20., 30.], requires_grad = True)
print('y: ', y)z = x + y
print('\nz = x + y')
print('z:', z) ################## OUTPUT ##################x: tensor([1., 2., 3.], requires_grad=True)
y: tensor([10., 20., 30.], requires_grad=True)z = x + y
z: tensor([11., 22., 33.], grad_fn=<AddBackward0>)
既然,requires_grad=True
,z
知道它是由两个张量z = x + y
相加而产生的。
s = z.sum()
print(s) ################## OUTPUT ##################tensor(66., grad_fn=<SumBackward0>)
s
知道它是由它的数字之和创造出来的。当我们在s
上调用.backward()
时,backprop 从s
开始运行。然后我们可以计算梯度。
s.backward()
print('x.grad: ', x.grad)
print('y.grad: ', y.grad) ################## OUTPUT ##################x.grad: tensor([1., 1., 1.])
y.grad: tensor([1., 1., 1.])
亲笔签名示例
我在这里引用了一些很好的资源来研究 PyTorch 上的亲笔签名
奥斯陆大学的幻灯片
埃利奥特·瓦特——YouTube
x1 = torch.tensor(2, dtype = torch.float32, requires_grad = True)
x2 = torch.tensor(3, dtype = torch.float32, requires_grad = True)
x3 = torch.tensor(1, dtype = torch.float32, requires_grad = True)
x4 = torch.tensor(4, dtype = torch.float32, requires_grad = True)z1 = x1 * x2
z2 = x3 * x4
f = z1 + z2gradients = grad(outputs=f, inputs = [x1, x2, x3, x4, z1, z2])
gradients ################## OUTPUT ##################(tensor(3.), tensor(2.), tensor(4.), tensor(1.), tensor(1.), tensor(1.))
让我们打印出所有的梯度。
print(f"Gradient of x1 = {gradients[0]}")
print(f"Gradient of x2 = {gradients[1]}")
print(f"Gradient of x3 = {gradients[2]}")
print(f"Gradient of x4 = {gradients[3]}")
print(f"Gradient of z1 = {gradients[4]}")
print(f"Gradient of z2 = {gradients[5]}") ################## OUTPUT ##################Gradient of x1 = 3.0
Gradient of x2 = 2.0
Gradient of x3 = 4.0
Gradient of x4 = 1.0
Gradient of z1 = 1.0
Gradient of z2 = 1.0
叶张量是直接创建的张量,不是任何算术运算的结果。
在上面的例子中, x1,x2,x3,x4 是叶张量,而 z1 和 z2 不是。
我们可以使用tensor.backward()
自动计算所有的梯度,而不是使用grad(outputs=f, inputs = [x1, x2, x3, x4, z1, z2])
指定所有的输入来计算梯度。
x1 = torch.tensor(2, dtype = torch.float32, requires_grad = True)
x2 = torch.tensor(3, dtype = torch.float32, requires_grad = True)
x3 = torch.tensor(1, dtype = torch.float32, requires_grad = True)
x4 = torch.tensor(4, dtype = torch.float32, requires_grad = True)z1 = x1 * x2
z2 = x3 * x4
f = z1 + z2f.backward()print(f"Gradient of x1 = {x1.grad}")
print(f"Gradient of x2 = {x2.grad}")
print(f"Gradient of x3 = {x3.grad}")
print(f"Gradient of x4 = {x4.grad}")
print(f"Gradient of z1 = {z1.grad}")
print(f"Gradient of z2 = {z2.grad}") ################## OUTPUT ##################Gradient of x1 = 3.0
Gradient of x2 = 2.0
Gradient of x3 = 4.0
Gradient of x4 = 1.0
Gradient of z1 = None
Gradient of z2 = None
我们可以使用x.grad.zero_
使渐变为 0。
print(x1.grad.zero_())################## OUTPUT ##################tensor(0.)
感谢您的阅读。欢迎提出建议和建设性的批评。:)你可以在 LinkedIn 和 Twitter 找到我。
你也可以在这里查看我的其他博客文章。
开始数据科学之旅的五个数据集
原文:https://towardsdatascience.com/how-to-train-your-unicorn-b6b4f4d50aa2?source=collection_archive---------54-----------------------
以及一些分析思路
图片来自 Pixabay 的我和我自己
W 借助一点想象力,数据科学家可以被视为“数据的全栈开发者”。就像全栈开发人员拥有从后端到前端的横向知识一样,数据科学家需要了解数据工程和业务领域之间的一切。这样的专业人员需要精通几个领域,如数据工程、数据可视化、机器学习、统计学。此外,他/她需要是一个主题专家。
我相信,一个人在这个世界上开始他/她的旅程可能会面临两个主要挑战:
- 挑战 1:如何学习和训练所有需要的技能— 当谈到“如何做”我不清楚时:我不认为有单一的学习方法或单一的改进方法,然而有多种方法对每个人都有不同的作用:最好的办法是找到适合我们自己的完美组合。
- 挑战 2:如何获得面试成功的经验 —这很难,尤其是如果一个人试图从另一个领域(例如软件开发)过渡到数据科学。
我对学习的完美组合包括理论学习和实践经验,但比例肯定倾向于后者,因为我是一个边做边学的人。我还认为“做事”在找工作时会有帮助(尤其是对那些初次经历的人);您希望在以下两者之间给出什么答案:
- “我有一个数据科学学位,这将是我的第一份工作经历”。
- “我有一个数据科学学位,这将是我的第一份工作经历;在申请工作时,我参与了一个模拟 Hadoop 日志消息流的项目;这些被摄取到一个 Spark 数据管道中,该管道提取一些基本信息(例如错误、时间属性等。),把一切都写在储存在 HDFS 的拼花文件里。在这些信息的基础上,我创建了一个 Tableau dashboard ,旨在识别 Java 异常中的模式(例如,当它们发生时,最常见的错误,等等)。).如果你想看看代码,这里有 Tableau 公共链接和 GitHub。
学位和课程是绝对必要的你应该尽可能多的学习,但是你可能会同意一些展示你技能的实际例子会有所帮助!
那又怎样?
我在本文中分享的是五个数据集,我认为它们对学习和实践都非常有帮助。这一选择背后的想法是让数据来自不同的领域,易于使用,但并非没有挑战。让我们深入其中吧!
有史以来最好的艺术品
一个很不错的数据集是用户 Icaro ( 下载 )上传的 Kaggle 有史以来最好的艺术品。如描述中所述,该数据集包含三个文件:
- artists . CSV:每个艺人的信息数据集
- images . zip:图片集合(全尺寸),分文件夹,顺序编号
如果这些数据被输入到人工智能模型中(大多数神经网络需要非常小的图像),调整大小的图片可以方便地加速预处理。注意“数据是 2019 年 2 月底期间从art challenge . ru”1【刮出来的。
关于如何使用这个数据集的一个想法可能是用 ConvNets** 做实验来建立一个分类器,给定一张图像,它可以识别作者;另一个应用可以是使用艺术品来实现一个 神经风格转移 GAN 。图像也是构建良好数据可视化的基础**:为什么不实现一个根据某种逻辑连接艺术品的图形呢?几年前,我用一个类似的数据集玩得很开心,分析波洛克的画 。****
为了展示在几个小时内可以完成什么,在下面的例子中,我使用了在 ImageNet 上训练的 ResNet50 来从每幅作品中提取特征。这是通过去除神经网络的最后一层并收集顶层之前的神经元的输出来完成的;该输出将是我们的“特征向量”(我们将为每幅图像准备一个向量)。
在特征提取之后,我使用了 PCA 和 tSNE 的组合来将高维向量投影到二维空间上。最后,我运行了 DBSCAN 来识别一些集群;正如你从下面的 GIF 中看到的,即使我没有进行微调,该算法也能够理解输入图像(褪色的缩略图是那些被 DBSCAN 标记为噪声的缩略图)。
如果你想下载完整的结果, 这是 的链接。
伦敦警察厅——武力的使用
我认为这个数据集很有趣,因为它有相当多的维度。它包含了伦敦警察厅关于使用武力的统计数据。每一行集合代表一名军官在一个主题上使用武力。 此行设置的不是一个计数事件 。如果不止一名官员对同一主题使用武力,这将显示在单独的数据行 [ 2 ]中。**
这些数据可以驱动到非常引人注目的仪表板上,并且,稍加努力,还可以驱动到 ML 模型上(例如,预测涉及使用武力的警察干预的结果)。还要注意,时间维度是进行时间序列分析的必备工具。
意大利 2011 年人口普查
我想在这个列表中加入一些人口普查数据。人口普查是系统地获取和记录给定人口成员信息的过程,大多数国家都有某种统计机构,定期收集整个人口的数据。我这里建议的是意大利 2011 年人口普查数据集* ( 下载 )。*****
我想包含这类数据有两个主要原因:
- 它允许玩 GIS (地理信息系统)——我上面链接的下载页面,也包含了 2011 年所有人口普查部分的shape file,它代表了意大利领土的一个相当精细的划分。Shapefile 是一种数字矢量存储格式,用于存储几何位置和相关属性信息[4。这些可以用来表示地图上的指标:传单 或者OpenStreetMaps都是处理这类数据的很好的 JavaScript 库。****
- ****在许多现实生活的应用中,您希望在分析中包含人口数据。大多数人口普查彼此之间都非常相似,所以我认为习惯它们是个好主意!
要开始使用数据库,请访问我提供的链接并下载下面的文件:
zip 存档包含 20 个意大利地区的每个地区的一个文件,名称模板是R<n>_indicatori_2011_sezioni.csv
,其中R<n>
是地区号。列被描述在一个名为 **tracciato_2011_sezioni.csv**
的文件中。****
不幸的是,该数据集似乎没有英文版本,所以你可以选择利用谷歌来翻译栏目名称,或者使用另一个国家的人口普查:)****
拼图毒性评论分类挑战
第四个数据集来自一个老 Kaggle 比赛( 下载 )。主持人提供了大量维基百科评论,这些评论已经被人类评分员标记为有毒行为。毒性的类型有:
***toxic
severe_toxic
obscene
threat
insult
identity_hate***
目的是创建一个模型来预测每条评论的每种毒性的概率[5]。
如果你想深入研究 NLP 和递归神经网络深度学习,我相信这是一个很好的起点。为了使建模更有趣,您可以尝试不同的预处理技术、网络拓扑和数据丰富(为什么不使用 Google APIs 将维基百科的评论翻译成另一种语言,然后重新翻译回英语以获得更多的训练数据呢?).****
这个数据集的另一个好处是,你将从 Kaggle 社区获得大量的材料。
下面的仪表板与深度学习无关,它只是对数据集的简单探索(仪表板后面的脚本是我用来从原始评论中提取信息的)。
Loghub
如果你想挑战自己的一些数据工程和特征提取,以及大容量的数据,我建议你从 Logpai ( 下载 )的 Loghub 数据集。****
Loghub 维护着一系列系统日志,这些日志可以出于研究目的自由访问。一些日志是从以前的研究中发布的生产数据,而另一些是从我们实验室环境中的真实系统中收集的。尽可能不对日志进行任何形式的清理、匿名或修改。所有这些日志总计超过 77 GB。因此,对于每个数据集[6】,我们在 Github 上只托管一个小样本(2k 行)。
从他们在 Github 页面上提供的描述中可以看出,我们谈论的是大约 77 GB 的数据。尽管这些在集群上不是问题,如果在本地运行代码,它们可能会很有挑战性:我认为这对于学习来说是一个优势!
拿走
- ****当我开始从事数据科学时,我希望得到的一个建议是用几个项目构建一个存储库。这对学习和“个人品牌”都非常有帮助。
- 当选择一个数据集时,选择一些具有挑战性的东西,例如从数据建模或性能角度,除非你想非常具体地专注于一些已经具有挑战性而没有其他复杂性的特定技术。****
- 不要害怕尝试不同的工具和编程语言。
我希望你喜欢!我很乐意在推特上联系!让我知道你的想法,如果你愿意,也可以看看这些文章。
***** [## Jupyter 笔记本上的 JavaScript 图表
用漂亮的 JavaScript 可视化将 Jupyter 推向新的高度
towardsdatascience.com](/javascript-charts-on-jupyter-notebooks-dd25f794cf6a) [## 六个星火练习来统治他们
一些具有挑战性的 Spark SQL 问题,易于在许多现实世界的问题上提升和转移(带解决方案)
towardsdatascience.com](/six-spark-exercises-to-rule-them-all-242445b24565)*****
如何将 2D 图像转换成三维空间?
原文:https://towardsdatascience.com/how-to-transform-a-2d-image-into-a-3d-space-5fc2306e3d36?source=collection_archive---------5-----------------------
使用 python 从头开始转换图像,并使用用户友好的滑块界面来可视化转换矩阵
变换图像
变换矩阵
变换矩阵用于修改和将点从一帧重新定位到另一帧。它们被广泛用于视频游戏和计算机视觉。无法列举它们的所有用途,但它们也用于在深度学习的训练中增强图像。
目前我们不知道什么是矩阵 M 和它的系数对应。实际上,系数不是直接找到的。不如说有更好的方法分解这个矩阵。事实上,一个变换矩阵可以分解成 4 个矩阵,所有矩阵都在空间坐标变换中起作用。
我们注意到平移矩阵、旋转矩阵、缩放矩阵和剪切(或倾斜)矩阵。
我已经按照上面的顺序分解了矩阵。订单有它的重要性。在这种情况下,它将首先应用平移,然后旋转,等等。然而,为了应用 3D 透视,我们必须移动到齐次坐标,因此引入两个新矩阵。
齐次坐标
我们将要看到的两个矩阵允许我们从笛卡尔坐标系到投影坐标系,反之亦然,分别是 H 和H’。注意 H' 不是 H 的逆矩阵。
为了解释什么是投影坐标,为了简单起见,我将在 2D 进行类比。想象一个尺寸为 X , Y 的屏幕,相当容易表现。然后我们有 (X,Y,W) 其中 W 是屏幕-投影仪距离。所以我们在射影(或齐次)坐标下的 2D 空间中。
现在我们在这个投影空间中,我们可以将投影仪从屏幕向前或向后移动距离δW。如果我们将它向后移动,那么投影图像将会超出它。相反,通过使投影仪更靠近屏幕,屏幕上图像的显示尺寸减小。
不可能(或者很难)想象这个射影空间与 3D 笛卡尔空间相关联,但是原理是相同的。我们会有 (X,Y,Z,W) 。
在接下来的脚本中,我们将通过考虑以度 ( 0 到 360 )为单位的角度和以像素为单位的度量来应用这些变换矩阵。
目前我们还没有定义转换矩阵。我们将在后面定义它们。我们将用身份矩阵来代替它们。这个矩阵并不修改图像,它就像一个数字乘以 1 。
让我们回到从笛卡尔坐标到射影坐标的转换的矩阵,反之亦然。目前,矩阵 M 是单位矩阵。
这里, h 和 w 为待处理图像的高度和宽度尺寸。
如果 h 和 w 出现在我们的等式中,则会将标记置于图像中心。的确,在一幅图像中,标记的原点在图像的左上角(坐标 (0,0) )。
同样,我们可以在之前看到的图表中看到与我们投影仪的焦距相对应的变量f的外观。
让我们写剧本吧
这样我们就可以为我们的图像变换函数打基础了。从恢复所有轴上的所有变换值开始,然后定义齐次通道的矩阵。
翻译
让我们转到翻译矩阵。顾名思义,这允许我们在不同的轴上进行平移。
你会注意到 Z 轴的平移必须被更新。事实上,我们的转换(以像素为单位)没有考虑“到投影仪的距离”。
你会明白我们不得不也为标尺更新 Z 轴。
旋转
旋转矩阵可以分解成不同轴上的旋转矩阵的乘积。在 3D 空间中,我们有 3 个旋转矩阵。
刻度
简单地说,缩放矩阵允许模拟缩放。换句话说,如果我们再次以我们的图像为例,在 X 或 Y 上放大两倍可以通过在这些轴上扩展图像来理解(同时从相同的距离观看图像)。
而对于 Z 轴,我们可以将二倍缩放解释为在 X 和 Y 上的二倍缩放的组合。(或焦距比率的变化)
注意,可以通过传递一个值 -1 在轴上建立对称性。
剪
剪切矩阵使得在不同的轴上拉伸(剪切)成为可能。
因此,在 3D 中,我们有一个剪切矩阵,它在 3 个轴上被分解成变形矩阵。
奖金部分
创建一些滑块
然后我们有了所有必要的矩阵来转换我们的图像。能够在我们选择的图像上实时可视化它们的效果会很有趣。让我们创建一个滑块。
滑块只是一个静态图像,还不能做任何事情。让我们为这些滑块创建一个堆栈,这样我们就可以用鼠标实时控制它们。
跑吧!
知识就是分享。
支持我,一键获取 中我所有文章的访问。
来源
麻省理工学院媒体实验室的图像转换
齐次坐标程序员指南,黑客手册
所有的图片都是自制的,可以免费使用。
如何将机器学习成果转化为商业影响
原文:https://towardsdatascience.com/how-to-translate-machine-learning-results-into-business-impact-d0b323112e87?source=collection_archive---------24-----------------------
向高管解释模型结果
马库斯·斯皮斯克在 Unsplash 上的照片
我以前写过数据科学是一个模糊的概念,人们不太理解。为了说明这一点,我想告诉你我曾经和一位副总裁的对话,内容是这样的:
我:“我可以建立一个机器学习模型来选择最有可能购买的顶级用户。”
VP :“你是说像回归模型?”
我:“是啊……差不多吧。”(忍住做掌脸的冲动)
如果您所有的建模工作都被视为可以在 Excel 中完成的回归,那么作为一名数据科学家,您如何让人们了解您所提供的价值?
今天,我将分享一些我将机器学习成果转化为商业影响的方法,以便高管和你的利益相关者能够理解。
1.显示相对于公司 KPI 的改进
高管需要说明该模型如何改善他们关心的公司关键绩效指标,即转化率、用户参与度和续订率。
例如,您构建了一个模型,发现顶级功能可以提高用户参与度。通过让产品团队在用户入职体验期间强调这些功能,您帮助提高了团队的用户参与度 KPI。
这向产品副总裁展示了您构建的模型的价值,否则产品团队将会花费大量时间来寻找。
2.显示增量收入影响
如果没有非常适合您构建的模型的 KPI,或者您想要显示相对 KPI 改进的大小,请计算对业务的增量收入影响。
例如,你建立了一个模型,将转化率从 1%提高到了 2%。1%的差异听起来并不多,但如果你也说 1%的转化率增加转化为 100 万美元的额外收入呢?
哇,现在你真正展示了你的价值,因为这比你的年薪还多(如果你赚了 100 多万,我想知道你的秘密)。
3.显示成本降低或花费的时间
如果您的模型与公司 KPI 无关,或者您无法关联收入金额,那么尝试通过降低成本或员工时间来显示价值。
例如,我开发了一个模型来选择最有可能转化为团队许可的单个用户。现在,他们可以选择最有可能购买的用户,并在更短的时间内增加转化的机会,而不是让两名销售代表花费一天时间在数据库中查看数百万用户,以找到最佳销售线索。
我不知道该模型可以提高的确切转化率,但这足以说服销售团队使用它,因为它有明显的价值,可以减少销售代表手动查看数据库所花费的时间。
作为数据科学家,重点是模型的准确性,但有时你必须后退一步,看看大局,以展示机器学习模型对业务的价值。
感谢阅读!如果您有兴趣在未来听到更多关于特定数据分析主题的信息,请留下您的评论。
你可能也会喜欢…
[## 我如何使用机器学习模型来生成可操作的见解
将数据科学与数据分析相结合
medium.com](https://medium.com/swlh/how-i-used-a-machine-learning-model-to-generate-actionable-insights-3aa1dfe2ddfd) [## 我作为数据科学家和数据分析师的经历
我希望从一开始就知道的成功秘诀
towardsdatascience.com](/my-experience-as-a-data-scientist-vs-a-data-analyst-91a41d1b4ab1)
如何用 Python 翻译 PDF(Google vs AWS Translate)——第 1 部分:提取和翻译文本
原文:https://towardsdatascience.com/how-to-translate-pdf-with-python-google-vs-aws-translate-part-1-extract-and-translate-text-7946604a48f4?source=collection_archive---------13-----------------------
实践教程
如何使用谷歌翻译 API 和 AWS 翻译 API 阅读和翻译 PDF 文件的逐步指南。
由 Tessakay 在 Pixabay 上拍摄的照片
我需要将一个包含英文文本的 PDF 文件翻译成拉脱维亚文。事实证明,这比我最初想象的稍微更具挑战性,所以我决定写一篇教程来分享我学到的东西,希望能为你节省一些时间。我把我的项目分成两部分。
这篇文章是第一部分,重点是如何阅读你的 PDF 文件,提取文本,并翻译它。它着眼于两种翻译文本的方法——使用谷歌翻译和 AWS 翻译。
第 2 部分将着眼于如何从获得的翻译创建、格式化和保存一个新的 PDF 文件。你可以在 GitHub 中找到我的项目的链接,并在本文末尾找到完整的代码。
这篇文章涵盖了什么?
- 如何使用 Python
PyPDF2
库读取 PDF 文件并从 PDF 中提取文本 - 2 种翻译文本的方法:python
googletrans
库和AWS Translate.
使用 Python 读取 PDF 文件
要以编程方式读取 PDF 文件,您可以使用各种第三方库,本文使用 PyPDF2 库。
PyPDF2 可以使用 pip 软件包管理器安装:
pip install PyPDF2
要读取该文件,我们首先要以二进制读取模式打开该文件,并创建一个 PdfFileReader。
file = open("example.pdf", 'rb')
reader = PdfFileReader(file)
从 PDF 中提取文本
现在,您可以一次一页地阅读 PDF 文件。您可以通过调用 reader 对象上的一个numPages
属性来获得文档的页数。然后逐一遍历所有页面,提取文本。要获取页面内容,使用reader.getPage(<page number>
,要从页面内容中提取文本,使用extractText
方法。
num_pages = reader.numPagesfor p in range(num_pages):
page = reader.getPage(p)
text = page.extractText()
翻译文本
一旦文本被提取出来,它就可以被翻译。我很好奇将使用谷歌翻译的 python 库与 AWS 翻译器进行比较。googletrans
库是开源的,使用它没有额外的费用。AWS Translate 使用神经机器学习算法进行翻译,并在翻译时考虑上下文。要使用 AWS 翻译,您需要有一个 AWS 帐户。他们提供前 12 个月的免费等级,在此期间你可以翻译 200 万个字符。之后,采用现收现付的定价方式,每百万字符的费用为 15 美元。请注意,免费层是在您首次使用服务时激活的。
使用谷歌翻译 API 翻译文本
您可以使用 pip 安装该库:
pip install googletrans
在幕后,这个库使用 Google Translate Ajax API 调用 Translate 方法。您也可以指定 Google 服务域 URL。在下面的例子中,我声明了两个不同服务域的列表:translate.google.com
和translate.google.lv.
您需要创建一个翻译器客户端实例,然后调用translate
方法来翻译文本。默认的目标语言是英语。可以通过在translate
方法中指定dest
参数来改变。默认的源语言是自动检测的,但是您可以使用src
参数专门定义源语言。在下面复制的例子中,它自动检测源语言并翻译成拉脱维亚语。
from googletrans import TranslatorURL_COM = 'translate.google.com'
URL_LV = 'translate.google.lv'
LANG = "lv"translator = Translator(service_urls=[URL_COM, URL_LV])
translation = translator.translate(text, dest=LANG)
使用亚马逊 AWS 翻译工具翻译文本
您需要有一个 AWS 帐户才能使用 AWS 翻译。请注意,如果您使用 python 以编程方式使用 AWS 服务,那么最简单的方法就是使用由 AWS 提供的名为boto3
的 python SDK。AWS 的工作方式是,它向您选择的区域中的 AWS 翻译端点发送一个 HTTP API 调用。使用您的访问密钥和秘密访问密钥以及当前时间戳对该请求进行加密签名。您确实需要配置您的aws_access_key_id
和aws_secret_access_key.
,它使用一种叫做 AWS Signature Version 4 的协议来签署您的请求。您笔记本电脑上的时钟必须正确,因为该协议考虑了当前时间。它会在签署您的请求时包含时间戳,并且您发送给 AWS 的请求仅在 15 分钟内有效。如果在 15 分钟后收到,那么出于安全原因,AWS 将拒绝该请求。
要安装 AWS Python boto3
SDK:
pip install boto3
如上所述,AWS 提供了一个免费的 AWS 翻译试用层,为期 12 个月,给你 200 万字免费翻译。之后是每 100 万字 15 美元。请注意,AWS 也将空格算作字符。
为了翻译,我们首先为translate
服务创建一个客户端,并指定区域。然后在客户端对象上调用translate_text
方法,提供Text
参数,这是您想要翻译的文本。SourceLanguageCode
允许指定源语言。如果使用值auto
,那么将自动检测源语言。TargetLanguageCode
允许指定目标语言。一旦从 AWS 收到结果,还有一个额外的步骤来获取翻译后的文本,那就是调用result.get(‘TranslatedText’).
import boto3LANG = "lv"
AWS_REGION = 'eu-west-1'translate = boto3.client(service_name='translate',
region_name=AWS_REGION,
use_ssl=True)result = translate.translate_text(Text=page.extractText(),
SourceLanguageCode="auto",
TargetLanguageCode=LANG)
translation = result.get('TranslatedText')
结论
感谢您抽出时间阅读。我希望这篇文章对你有用。您学习了如何使用 python 阅读 PDF 文件,以及如何从 PDF 文件中提取文本。然后,您看了如何自动翻译这段文本的两种不同方式。
请关注第 2 部分,它将介绍如何使用 python 库reportlab
将翻译后的文本保存到一个新的 PDF 文件中。它还将格式化和保存新创建的文件。
在 GitHub 中查看该项目的完整代码:https://github.com/akapne01/translator
如何免费试用 UCP 码头工人?
原文:https://towardsdatascience.com/how-to-try-docker-ee-ucp-for-free-dd9df7bee797?source=collection_archive---------38-----------------------
使用码头游乐场
每个人都在转向微服务和对接单片应用。想熟悉 docker 的 Docker 新手可以使用 Docker 游乐场。它是免费的!
我总是建议我的学生使用谷歌浏览器。通常,它不会要求输入您的 Docker Hub ID 和密码。它将向您显示 START 按钮,如图 1 所示。点击它。
图 1:在谷歌浏览器中启动 Docker 游乐场
Docker 企业套件由三个组件组成:
1。Docker 企业引擎
2。UCP(通用控制平面)
3。DTR (Docker 可信注册中心)
注意有两个 Docker 引擎:Docker 社区版(CE)和 Docker 企业版(EE)。
- Docker CE 仅用于开发和测试,绝不用于生产。然而,这是免费的。
- Docker EE 是您用于生产的版本,您可以在其中初始化 Swarm 或 Kubernetes。这不是免费的。不过,你可以免费试用一个月。
Docker Playground 帮助您免费安装和试用 UCP。然而,这个播放实验室被限制在小于 3 GB 的内存中,大约 4 小时后过期。
现在,按照步骤在 Docker 操场上安装 UCP。
第一步:
通过单击左侧的“Add New Instance”创建一个节点,如图 2 所示。
图 2:在 Docker Playground 上创建一台新机器
第二步:
使用 docker swarm init 命令初始化 Docker Swarm。从节点名称或页面顶部获取节点的 IP 地址。
docker swarm init —-advertise-addr <Node IP>
如果您想要将工作节点添加到您的集群,Docker 引擎将生成一个长令牌。
第三步:
从 docker/ucp:
docker container run --rm -it --name ucp -v /var/run/docker.sock:/var/run/docker.sock docker/ucp:2.2.9 install --host-address <node IP> --swarm-port 2400 --interactive --force-insecure-tcp
在这里,我们正在根据docker/ucp:2.2.9
图像制作一个容器。
客房服务的--rm
。我们告诉 docker 当它停止时自动删除这个容器。
-it
做一个交互终端。
将这个容器命名为ucp
的--name
,而不是 docker 默认生成的形容词 _ 名词的名称。
-v
在主机和该容器之间共享卷。
install
是安装 UCP 的命令。
--host-adress
设置群首的主机/节点地址。
将--swarm-port
端口设置为 2400。
使容器交互的--interactive
标志。
--force-insecure-tcp
的最后一个标志是为了避免以下错误:
该节点上的 Docker 端口可从外部访问,接受端口 2375 上的连接。该节点不安全。
docker/ucp
图像的其他一些标签不使用--force-insecure-tcp
。相反,你可以使用--ucp-insecure-tls
。
它将停止等待您输入您的管理员用户名和密码。同样,它将再次暂停以输入额外的别名。只需按 enter 键,docker 就可以继续安装,因为集群中没有任何其他节点。
安装完成后,节点 IP 地址旁边会显示一些链接。
第四步:
您可以从 443 端口访问 UCP。但是,如果你点击它,它会在本地下载一个文件。要解决这个问题,右键单击 443 端口链接,然后单击复制链接地址。打开一个新的浏览器标签,粘贴链接。将 http://更改为 https://,然后单击 enter。
假设你没有链接到 443 端口,没问题。复制 SSH 地址。
打开新的浏览器选项卡。用 https://替换 ssh。将地址中的@替换为。点击回车。
我会给你一个错误。单击底部的高级,将显示一个链接以继续。点击链接。
第五步:
将显示 UCP 登录。输入您的管理员用户名和密码。
第六步:
它会要求您上传许可证。您可以从 Docker Hub 的帐户获得一个月的试用许可证:
https://hub.docker.com/editions/enterprise/docker-ee-trial
此外,你可以跳过以后。UCP 将如下所示:
您可以稍后从左侧菜单中,单击管理→管理设置→许可证来上传。
享受你的审判!
如何调整 Pytorch 闪电超参数
原文:https://towardsdatascience.com/how-to-tune-pytorch-lightning-hyperparameters-80089a281646?source=collection_archive---------4-----------------------
想知道如何用 30 行代码优化 Pytorch Lightning 超参数?
Pytorch Lightning 是 2020 年最热门的人工智能库之一,它使人工智能研究可扩展并快速迭代。但是如果你使用 Pytorch Lightning,你需要做超参数调整。
正确的超参数调整可以决定训练的成功与否。每个人都知道,通过良好的调优方法,可以极大地提高模型的准确性!
在这篇博文中,我们将演示如何使用 PyTorch Lightning 使用 Ray Tune,这是一种超参数调整的行业标准。 Ray Tune 是 Ray 的一部分,是一个用于缩放 Python 的库。
它以 PyPI 包的形式提供,可以这样安装:
pip install "ray[tune]"
要使用 PyTorch Lightning 的 Ray Tune ,我们只需要添加几行代码!!
雷调+ PTL 入门!
要运行这篇博文中的代码,请确保首先运行:
pip install "ray[tune]"
pip install "pytorch-lightning>=1.0"
pip install "pytorch-lightning-bolts>=0.2.5"
下面的例子是在 ray1.0.1,pytorch-lightning1.0.2,pytorch-lightning-bolts==0.2.5 上测试的。 参见此处完整示例。
先从一些进口说起:
导入之后,有三个简单的步骤。
- 创建您的
LightningModule
- 创建一个用调优回调函数调用
Trainer.fit
的函数 - 使用
tune.run
执行您的超参数搜索。
步骤 1:创建你的照明模块
第一步,创建你的照明模块。你的LightningModule
应该把一个配置字典作为初始化的参数。然后,这个字典应该设置您想要调整的模型参数。您的模块可能如下所示:
第 2 步:创建一个函数,用 Tune 回调函数调用Trainer.fit
我们将使用回调来与射线调进行通信。回调非常简单:
from ray.tune.integration.pytorch_lightning import TuneReportCallback...
metrics = {"loss": "ptl/val_loss", "acc": "ptl/val_accuracy"}
callbacks = [TuneReportCallback(metrics, on="validation_end")]
trainer = pl.Trainer(... callbacks=callbacks)
这个回调确保了在每个验证时期之后,我们向光线调节报告损失度量。val_loss
和val_accuracy
键对应于validation_epoch_end
方法的返回值。
此外,射线调节将开始许多不同的训练运行。为了创建多个训练运行(用于超参数搜索),我们需要将训练器调用包装在一个函数中:
train_mnist()
函数需要一个config
字典,然后传递给LightningModule
。该配置字典将包含一次评估的超参数值。
第三步:使用tune.run
执行你的超参数搜索。
最后,我们需要调用ray.tune
来优化我们的参数。这里,我们的第一步是告诉光线调节哪些值是参数的有效选择。这叫做 搜索空间 ,我们可以这样定义:
# Defining a search space!config = {
**"layer_1_size"**: tune.choice([32, 64, 128]),
**"layer_2_size"**: tune.choice([64, 128, 256]),
**"lr"**: tune.loguniform(1e-4, 1e-1),
**"batch_size"**: tune.choice([32, 64, 128])
}
让我们快速浏览一下搜索空间。对于第一层和第二层的大小,我们让射线调整在三个不同的固定值之间选择。学习率在0.0001
和0.1
之间采样。对于批量大小,也给出了三个固定值的选择。当然,还有许多其他的(甚至是定制的)方法可以用来定义搜索空间。
射线调节现在将随机对十个不同的参数组合进行采样,训练它们,然后比较它们的性能。
我们将train_mnist
函数包装在tune.with_parameters
中,以传递常数,如训练每个模型的最大历元数和每次试验可用的 GPU 数量。 Ray Tune 支持分数 GPU,所以只要模型仍然适合 GPU 内存,类似gpus=0.25
的东西完全有效。
# Execute the hyperparameter search
analysis = tune.run(
tune.with_parameters(train_mnist_tune, epochs=10, gpus=0),
config=config,
num_samples=10)
对tune.run
的最终调用如下所示:
最后,优化结果可能如下所示:
在这个简单的例子中,一些配置达到了很好的精度。我们观察到的最好结果是在批量大小为 32,层大小为 128 和 64,学习率为 0.001 左右的情况下,验证精度为 0.978105 。我们还可以看到,学习率似乎是影响性能的主要因素——如果学习率太大,运行将无法达到良好的准确性。
您可以通过使用tune.run
的返回值来检索最佳分数:
analysis = tune.run(...)best_trial = analysis.best_trial # Get best trial
best_config = analysis.best_config # Get best trial's hyperparameters
best_logdir = analysis.best_logdir # Get best trial's logdir
best_checkpoint = analysis.best_checkpoint # Get best trial's best checkpoint
best_result = analysis.best_result # Get best trial's last results
您还可以轻松利用 Ray Tune 的一些更强大的优化功能。例如, Ray Tune 的搜索算法可以让你轻松优化超参数组合的景观。Ray Tune 的调度程序还可以尽早停止性能不佳的试验,以节省资源。
看完整例子在这里。
在张量板上检查结果
Ray Tune 自动将度量标准导出到 TensorBoard,中,还可以轻松支持 W & B。
就是这样!
要用 射线调 启用简单的超参数调,我们只需要添加一个回调,包装好 train 函数,然后开始调。
当然,这是一个非常简单的例子,没有利用许多 Ray Tune 的搜索功能,如早期停止表现不佳的试验或基于人群的培训。如果你想看完整的例子,请看看我们的完整 PyTorch 闪电教程。
如果你已经成功地使用 py torch Lightning withRay Tune,或者如果你需要任何帮助,请通过加入我们的 Slack 或者通过我们的 Github 来联系我们——我们希望收到你的来信!
如果你喜欢这篇博文,一定要看看:
- 我们的权重和偏差报告针对变压器的超参数优化
- 从零开始为你的 NLP 模型服务的最简单的方法
恐龙和圆圈的数据集可以有相同的统计数据吗?
原文:https://towardsdatascience.com/how-to-turn-a-dinosaur-dataset-into-a-circle-dataset-with-the-same-statistics-64136c2e2ca0?source=collection_archive---------35-----------------------
它们具有相同的均值和标准差,但它们是两个明显不同的数据集!
动机
数据可视化不仅仅是展示漂亮的图表。它还有助于您更深入地了解您的数据。
恐龙来转圈
上面的 gif 捕捉了不同数据集的统计和可视化。如果我们只查看右侧的统计数据,而不可视化数据集,我们会假设这些数据集几乎相同,因为它们具有相同的均值、标准差和相关性
但是当我们看左边的可视化时,我们意识到这两个数据集是不同的,因为一个描绘的是恐龙而一个描绘的是圆圈!
这个输出证明我们不应该只相信统计数据,而应该在做出结论之前进一步可视化数据集。
在本文中,我将向您展示如何创建具有相同统计数据但看起来彼此不同的数据集。
使用模拟退火创建相同的统计数据和不同的图表
来自 Autodesk Research 的贾斯汀·马特伊卡和乔治·菲兹莫里斯找到了创建这种数据集的方法。受安斯科姆的四重奏的启发,他们试图找出如何创建具有这些特殊属性的数据集。
从维基百科检索到的安斯康姆四重奏
他们的方法智能地保持统计数据不变,同时控制结果输出的图形外观。那么这个方法是怎么运作的呢?
从头开始创建具有这些属性的数据集是极其困难的。但是,如果我们从一个特定的数据集开始,在每次迭代中只对它进行轻微的修改,同时保持统计数据不变,直到我们创建出具有我们想要的形状的数据集,那会怎么样呢?
这是该方法的伪代码。
从贾斯汀·马特伊卡和乔治·菲兹莫里斯的论文中检索到的代码
上述代码的解释:
Inital_ds
:初始化我们想要维护统计值的数据集- 在每次迭代中调用
Perturb function
,通过在随机方向上少量移动一个或多个点来修改数据集的最新版本current_ds
。该功能确保至少 95%的移动不会改变整个数据集的统计属性 Fit function
检查扰动点是否已经增加了数据集的整体适合度。由于我们希望将数据集强制转换成特定的形状,因此增加适应度意味着最小化目标形状上所有点到最近点的平均距离。- 当有更多的全局最优解(更好的解)可用时,为了避免陷入局部最优解(一个好的但不是最好的解),该方法采用模拟退火到来增加选择的随机性。这意味着我们总是接受具有改进的适应度的解决方案,但是即使解决方案没有改进,如果当前温度大于 0 和 1 之间的一个随机数,我们仍然接受解决方案。
现在让我们试着用这个方法把一只恐龙变成靶心。
把恐龙变成靶心
为了方便你使用上面的方法,我创建了一个名为same-stats-different-graphs的包。这是 Autodesk 提供的代码的修改版本。
这个包允许你把一个形状变成另一个形状,并在命令行上为这个转换创建 gif。
要安装软件包,请键入:
pip install same-stats
现在我们准备把一个恐龙数据集变成靶心!在您的终端上,键入:
python -m same_stats --shape_start=dino --shape_end=bullseye
并且像下面这样的 GIF 会以dino_bullseye.gif
的名字保存到gifs
目录中:
恐龙对牛眼
其他参数选项:
--shape_start
:形状开始。选项:dino
、rando
、slant
、big_slant
--shape_end
:目标形状。选项:x
、h_lines
、v_lines
、wide_lines
、high_lines
、slant_up
、slant_down
、center
、star
、down_parab
、circle
、bullseye
、dots
--iters
:迭代次数--decimals
:小数位数--frames
:帧数
结论
恭喜你!您刚刚发现了如何使用相同的统计值创建完全不同的数据集!我们方法的输出可用于展示可视化数据的重要性。你可以在 Autodesk 研究网站上了解更多关于这种方法的信息。
我喜欢写一些基本的数据科学概念,并尝试不同的算法和数据科学工具。你可以在 LinkedIn 和 T21 Twitter 上与我联系。
如果你想查看我写的所有文章的代码,请点击这里。在 Medium 上关注我,了解我的最新数据科学文章,例如:
[## 如何使用 HyperDash 远程监控和记录您的机器学习实验
培训需要很长时间才能完成,但你需要去洗手间休息一下…
towardsdatascience.com](/how-to-monitor-and-log-your-machine-learning-experiment-remotely-with-hyperdash-aa7106b15509) [## 如何找到和 Python 很好的搭配
给定个人偏好,如何匹配使得总偏好最大化?
towardsdatascience.com](/how-to-match-two-people-with-python-7583b51ff3f9) [## 如何用 Faker 创建假数据
您可以收集数据或创建自己的数据
towardsdatascience.com](/how-to-create-fake-data-with-faker-a835e5b7a9d9) [## 如何用图论可视化社交网络
找出《权力的游戏》中的影响者
towardsdatascience.com](/how-to-visualize-social-network-with-graph-theory-4b2dc0c8a99f) [## 如何用 Altair 创建交互式剧情
在 5 行简单的 Python 代码中利用您的数据分析
towardsdatascience.com](/how-to-create-interactive-and-elegant-plot-with-altair-8dd87a890f2a) [## cy thon——Python 函数的加速工具
当调整你的算法得到小的改进时,你可能想用 Cython 获得额外的速度,一个…
towardsdatascience.co](/cython-a-speed-up-tool-for-your-python-function-9bab64364bfd)
如何将文本转化为特征
原文:https://towardsdatascience.com/how-to-turn-text-into-features-478b57632e99?source=collection_archive---------1-----------------------
入门
使用 NLP 进行机器学习的综合指南
简单问题:如何把文字变成特征?作者图片
假设你被分配了一项任务,为你的公司产品评论建立一个情感分析工具。作为一名经验丰富的数据科学家,您构建了许多关于未来销售预测的见解,甚至能够根据客户的购买行为对他们进行分类。
但是现在,你很感兴趣:你有一堆文本条目,必须将它们转化为机器学习模型的特征。如何做到这一点?当数据科学家第一次遇到文本时,这是一个常见的问题。
对于有经验的 NLP 数据科学家来说,将文本转换成特征可能看起来很简单,但对于该领域的新手来说,这并不容易。这篇文章的目的是提供一个将文本转化为特征的指南,作为我在过去几个月中构建的 NLP 系列的继续(我知道,距离上一篇文章已经有一段时间了)。
之前,我已经讨论了 NLP 预处理管道中的几个步骤。现在,这是预处理管道的最后一步,当你精心策划的文本最终变成机器学习模型的可用特征时(如果这是你的目的——没有机器学习也可以有 NLP,这是另一个话题)。
像往常一样,除了解释如何做之外,我还将介绍三种最常用的建模技术:单词袋模型、基于 TF-IDF 算法的模型和 Word2Vec 模型。让我们开始讨论吧。
特色?
对于那些不习惯这个词的人,让我稍微离题一下。特征是给予选择或处理的数据的名称,准备用作算法(通常是机器学习算法)的输入。特征可以是房子的价格、像素的 RGB 值,或者在我们的例子中是单词的表示。
来自谷歌开发者机器学习速成班的漂亮图片描述了什么是特性。
甚至有一种叫做“特征工程”的很酷的技能,数据科学家研究数据,从数据中获得特征。这些特征甚至可能在数据中不明显,但可以通过修改现有数据或添加新数据使其更完整来获得,从而有助于实现更稳健的决策。
因此,最终,我们的目标是获得原始数据(文本)并转化为特征(计算机算法可以处理的东西)。
文本矢量化
用于将文本转换成特征的技术可以被称为“文本矢量化技术,因为它们都旨在一个目的:将文本转换成向量(或者数组,如果你想更简单的话;或者张量,如果你想要更复杂的话),然后可以以经典的方式输入到机器学习模型中。
文本矢量化旨在将文本转换为整数(或布尔或浮点数)向量。图片作者。
把我们的预期结果想成一个向量是一个很好的起点,来想象我们如何把文本变成特征。让我们对此进行更多的思考。考虑下面的短语:
我想把我的文本转换成数据。
用简单的计算术语来说,向量是具有 n 个位置的列表。考虑如何将文本转换为向量的一种自然方法是创建一个所有单词的有序列表,如下所示:
图片作者。
但是,如果条目更短或更大,会发生什么情况呢?此外,你的机器学习算法(基本上是一系列矩阵和向量计算)如何比较两个单词——这些由人类发明的具有特殊含义的符号?
既然你很聪明,你已经想到了:让我做一个字典或者一些类似的结构(一般来说,一个词汇图),用单词索引代替单词!
一个假设的解决方案是为每个单词创建一个映射……作者的图片。
然后用单词索引对向量进行编码。图片作者。
你在正确的道路上,但是让我们考虑这里的一些问题:单词“我的”比“想要的”更重要吗?对于机器学习算法来说,这就是你的数据“告诉”的。机器学习算法不关心数字是否是一个索引,只关心它是一个要计算的值(当然,你可以有一个分类特征,但我们会在下面看到)。
不要吼,言语不是价值观!图片来自海绵宝宝电视节目,由作者编辑。
“正常化,正常化,正常化!!!",可以认为。但是,记住:这些都不是价值观!它们是指数。
如果你玩数据科学和机器学习已经够久了,你可能会想到 one 解决方案:使用 One Hot Encoding 。
一个热编码是对分类特征进行编码的过程,其中该特征的每个可能值被映射到一个新的“列”,如果存在,则该列被设置为 1,否则为 0。
让我们使用前面提到的词汇表“map”和建议的短语来考虑这一点(在这种情况下,词汇表与短语的单词相同)。我们得到这个:
“我想把我的文本转换成数据”的一键编码。图片作者。
现在,如果我们想编码:“我想要我的数据”,我们会得到:
“我要我的数据”的一键编码。图片作者。
太好了,我们找到了一种将我们的数据编码成机器学习方式的方法!但是这里有很多问题需要解决:让我们考虑第一个问题——词频——这就是词汇袋模型的用武之地!
单词袋(蝴蝶结)模型
一种热编码只将值视为“存在”和“不存在”。这不适合发短信。在许多文本应用中,词频起着重要的作用。考虑以下两段:
狗是犬科的家养食肉动物。它是像狼一样的犬科动物的一部分,是最广泛丰富的陆地食肉动物。狗和大灰狼是姐妹分类群,因为现代狼与最初被驯化的狼没有密切关系,这意味着狗的直接祖先已经灭绝。狗是第一个被驯化的物种,几千年来因为各种行为、感觉能力和身体特征而被选择性繁殖。
今天我带着我的狗出去,我在公园里发现了 100 美元。想到这些钱可能是某个可怜的老太太一周的午餐钱,我很难过。
第一个是维基百科关于狗的文章的第一段,第二个是我为了证明这个问题而写的一个伪博客。问题:你会向一个用“狗”这个词搜索假想引擎的用户推荐哪个网页?
一个热编码将在两个条目中为“dog”给出相同的值,所以这不好。
进入词汇袋模式!
一袋单词😜。图片作者。
这个模型建议,使用一个词频矢量,而不是一个布尔值矢量。在上面的示例中,单词“dog”的列在第一个文本中将接收值“4 ”,而在第二个文本中仅接收值“1”。现在,规范化这些值是可以的,但不是必须的(只是为了更快的处理)。
一个乱七八糟的包!图片由 Pinterest 上的 Cocoon Innovations 提供。
这种模型被称为“包”,因为它不保持单词“秩序”(就像我们妈妈在 90 年代的包总是乱七八糟)。
但是在讨论单词袋模型的缺点之前,我们先来看看如何使用 Python 和 Numpy 实现它。
这很简单,但是让我们一步一步来看。我决定让它成为一个类,这样我就可以在一个模型中实例化多个 BoW。这是类构造函数:
基本上,我们有一组所有单词和几个字典来存储单词索引。
接下来,我们通过拟合来准备我们的单词包(一次添加所有的文档,所以它可以‘学习’我们可以使用的单词)。
最后,我们可以转换新的输入,返回整个词汇表大小的数组,并计算该单词出现的次数。为此,我使用 numpy,这是一个数学和代数库,专门研究向量/矩阵代数。这是 python 目前针对这类任务的默认库(并被用作大多数机器学习库的输入格式)。
这是一个用法和输出示例:
现在我们已经看到了它是如何完成的,我们可以讨论模型中的问题了:
第一个:完全无视语序。您可以通过查看下图来理解这一点:
图片作者。
第二:趋于非常高维度。根据牛津英语语料库,如果你的语料库只包含 90%最常见的英语单词至少一次,那将产生至少 7000 维的向量(其中大部分为零,但仍然是很多维)!
但是弓很简单,能为简单的问题带来快速的结果。如果在构建 NLP 解决方案时,您不确定从哪里开始,请尝试最基本的方法:使用 BoW 模型。它是一个很好的基线估计器。
仅指出一点,有一个变体在大数据案例中是有用的,特别是在您必须在字符库中比较文本的情况下(不考虑语义)。该方法使用文本瓦片区(收缩)。在这种情况下,不要将句子拆分成单词,而是在每 k 个字符或每个停用词处进行拆分。点击此处阅读更多内容:
[## 近似重复和重叠
下一篇:参考资料和进一步阅读:网络搜索基础知识上一篇:索引大小和估计内容索引一…
nlp.stanford.edu](https://nlp.stanford.edu/IR-book/html/htmledition/near-duplicates-and-shingling-1.html)
TF-IDF 模型
这个实际上并不是一个模型,而是对计算单词相对于文档的“相关性”的改进。为简单起见,我称之为模型。
在 TF-IDF 模型中,我们不是存储单词的频率,而是存储对输入数据执行 tf-idf 算法的结果。 TF 代表词频, IDF 代表逆文档频率。
简而言之,TF-IDF 计算一个词在特定文档中的权重,同时考虑词的总体分布。结果的呈现方式与单词包相同:一个稀疏的向量(0 表示没有出现的单词,否则有些单词会浮动)。
例如,在情感分析任务中,与单词袋相比,TF-IDF 模型可以返回更好的结果。
为了更好地理解,让我们把这个算法分成两部分:计算全局逆文档频率,然后计算单独的 TF-IDF 分数。
逆文档频率
第一部分是计算每个单词的全局 IDF 值。这个值表示每个单词在所有文档中的权重(在整个语料库中)。这意味着非常常见的单词将具有较小的总权重,而罕见的单词将具有较大的权重(这甚至消除了去除停用词的需要,因为它们非常常见,所以权重较小)。
有许多不同的方法来计算 TF 和 IDF(例如,看看算法维基百科页面)。我选择使用对数标度的 IDF,其计算公式如下:
其中:
- D =文件总数
- freq =出现该术语的文档数。
首先,我们定义一个助手方法:
1)将句子转换成单词和频率的字典的简单方法(可以使用 Python 集合“Counter”来获得最佳性能,但为了简单起见,我将使用旧的字典方法):
然后我们初始化 IDF 类,类似于 BoW 类:
对于拟合,我们根据上面提到的公式计算全局词频率,然后是每个词的 idf。
太好了,我们的文档有了全球 IDF。现在,通过找到每个句子中每个术语的术语频率分数并乘以全局术语 IDF,为每个句子计算 TF-IDF。
计算词频
简而言之,我们通过以下方式获得一个句子的 TF-IDF 得分:
- 统计句子中术语的出现频率。
- 将每个术语的术语频率乘以逆文档频率。
下面是代码(注意,我添加了一些条件和私有方法来说明批量转换):
就这样,我们的 TF-IDF 特征化完成了!
现在,对于每一个句子,我们得到一个数组,它的大小相当于整个词汇表的大小,包含每个单词与该句子的相关性(如果缺少,则为 0)。
下面是一个输出示例:
或者更“可读”一点:
{‘of’: 0.0, ‘list’: 0.0, ‘sentence’: 0.08664339756999316, ‘a’: 0.07192051811294521, ‘second’: 0.0, ‘sentences’: 0.0, ‘in’: 0.0, ‘complexity’: 0.0, ‘is’: 0.08664339756999316, ‘this’: 0.08664339756999316, ‘word’: 0.08664339756999316, ‘for’: 0.0}
你可以在这里找到用于生成上述‘解释’的代码。
这是到目前为止实现的提交,请注意代码中会有一些不同,因为我也将使用我的工具集中内置的一些结构。:
[## 各种/各种工具
此时您不能执行该操作。您已使用另一个标签页或窗口登录。您已在另一个选项卡中注销,或者…
github.com](https://github.com/Sirsirious/NLPTools/tree/b48910b1db6e0de463b1713fcb65521df98e58e6)
关于 BoW 和 TF-IDF 的一些讨论:
正如我们所看到的,BoW 和 TF-IDF 方法为一个句子生成一个向量,其大小相当于整个词汇表。这不考虑词序或位置,使得这些技术不适合连续性敏感的应用程序(大多数 NLP 应用程序都是如此)。
一种可能的解决方法是对每个单词使用 BoW/TFIDF 数组,将它们堆叠起来并作为特征传递,如下图所示(以人工神经网络的输入层为例):
图片作者。
对于上面的图像,你有一个 10000*4 的稀疏矩阵,用于一个 4 个单词的句子(即使每个布尔使用一个位,你会得到大约 1kb 每个单词每个句子!想象一个大型语料库?).用于训练简单情感分析模型的计算时间和存储将使其过于昂贵或不可行(事实上,几年前,由于缺乏足够的内存和处理能力,当问题是机器学习时,文本几乎是一个未触及的话题)。
然而,这种方法允许我们保持单词顺序。如果我们能降低这个向量的维数呢?
输入单词嵌入!
单词嵌入
我不会深入解释单词嵌入,因为有几种计算它们的方法,并且大多数涉及深度神经网络,这本身需要时间来解释(这不是本文的重点)。
但我不会克制自己给你关于它的基本和最重要的信息。
让我们这样陈述:
单词嵌入是从上下文训练中学习到的单词的向量表示。它不是每个单词的分数,相反,它更像是单词的“坐标”。
因此,当训练一个模型而不是词汇大小的一次性编码时,您需要输入一个表示输入的单词嵌入数组。这个数组有一个预定义的 d 维深度,它通常比词汇表的大小小得多。
最著名的生成单词嵌入的技术之一是 Word2Vec,它是该方法的创始人。Word2Vec 本身可以使用两种不同的技术来计算,但是细节在这里并不重要。
相反,您最好知道训练/使用嵌入的方式有多种变化。这里总结了用于创建嵌入的技术:
- Word2vec (Google) - 2 技术:连续词包(CBoW)和 Skip-Gram;
- 全局向量或手套(斯坦福);
- 快速文本(脸书)——有趣的事实:解释了词汇之外的单词。
如果你想了解更多,我推荐这个来自 DeepLearning 的神奇课程。艾出席 Coursera:【https://www.coursera.org/learn/probabilistic-models-in-nlp】T2
生成单词嵌入的方式通常通过训练过程,允许单词根据其上下文进行编码。这导致了嵌入也能够表示单词语义(在一定程度上)的有趣效果。
因为单词是用坐标表示的,所以要进行比较(比较相似性)。如果使用诸如主成分分析(PCA)之类的技术来适当地降低维度,则可以绘制单词,并且绘制通常会将具有相似含义的单词更紧密地显示在一起,如下图所示,摘自 IBM 研究博客:
单词嵌入能够在一定程度上捕捉单词语义。句子甚至可以用嵌入来比较。图片由 IBM Research 的编辑人员提供。
坐标通常以大量的维度给出,通常在 8 到 1024 之间。这样,我们就有了一个 8 到 1024 维的非稀疏数组,而不是一堆 10000 维的填充 0 的数组。这更适合计算机使用。
这是另一个很酷的例子,摘自大卫·罗扎多在《公共科学图书馆综合》杂志上的一篇文章:
大卫·罗扎多拍摄。
当考虑人们如何使用嵌入时,重要的是指出单词嵌入可以通过两种不同的方式产生:
- 通过与正在进行的过程(如情感分析任务)一起接受训练,并根据该特定任务捕捉单词之间的关系。这就是当您使用诸如 Keras 、 Pytorch 或 Trax 等库来定义嵌入层时会发生的情况。这些层将单词索引映射到嵌入值。
- 通过在一个巨大的语料库上进行预处理来捕捉语言中最常见的关系。然后,可以将这些经过预训练的嵌入加载到模型中,以帮助加快学习过程或获得更好的结果。这就是 fastText、Word2vec 或 GloVe 的用武之地。诸如spaCy等库提供了这种嵌入用法。
我不会在这里讨论如何预训练一个嵌入,但是我准备了一个专门的帖子来解释这个实践。我建议你订阅我的帐户,以便在文章发表时得到通知,或者留意这一段,因为当它准备好时,我会在它下面发表一个链接。
关于这个主题再补充一点,当把文本转换成特征时,也可以进行特征工程。换句话说,数据科学家可以应用自己的规则(通常通过预处理)来定义在将文本转换成数字数组之前应该提取什么。
正如我们所看到的,将文本转换成功能看起来可能是一件简单而琐碎的事情,但是需要考虑很多事情。
在被输入编码器之前,单词索引被映射到它们各自的嵌入,这是在训练过程中使用的真实值。图片取自py torch seq seq 车型教程。
目前,NLP 中的大多数现有技术仅使用单词嵌入,因为它们更健壮并且能够以顺序方式使用。
当然,每个算法和问题都需要对输入文本进行特定的操作。例如,Seq2Seq 模型通常有一个固定的序列
长度。为了加强这一长度,使用了填充或压缩。但最后,填充和文字都转换成了嵌入。
既然我们已经完成了 NLP 预处理中最基本的主题,我们可以开始讨论应用程序和技术了。别忘了订阅敬请关注,收到下一个话题的通知!
此外,请经常查看我的存储库中的新代码。根据当前的许可,随意重用和贡献代码。如果你需要帮助,可以通过 Linkedin 联系我,只要查看我的个人资料就可以了!下一篇文章再见。
** [## 各种/各种工具
此时您不能执行该操作。您已使用另一个标签页或窗口登录。您已在另一个选项卡中注销,或者…
github.com](https://github.com/Sirsirious/NLPTools)**
创建数据科学家工具带。
原文:https://towardsdatascience.com/how-to-turn-your-python-scripts-into-an-executable-data-scientists-utility-belt-e2a68889909e?source=collection_archive---------50-----------------------
如何将 Python 程序从 IDE 中取出并放入命令行
由杰西·奥里科在 Unsplash 拍摄的照片
TL;所有必要的步骤都在底部的代码片段中。
作为一名学生,我看到我的许多同学创造了令人印象深刻的工具,我想把它们整合到我的工作流程中。但是这些功能要么归入 Jupyter 笔记本,要么归入 Slack 上共享的代码片段集合。
这篇文章的目标是给你一个实用的知识,如何在你的 mac 上的任何地方创建一个可执行的脚本。本教程将涉及许多不同的主题。为了简短起见,我将不详细介绍任何步骤。我将为那些好奇的人提供进一步阅读的链接。
另外,我用的是 z-shell 和一台 mac。如果你使用 z-shell 或者 bash (将 **zshrc**
替换为 **bashrc**
) ,所有这些步骤都可以工作。
教程大纲:
1)检查您是否有 python3,并且它是最新的
2)创建一个简单的示例程序来打印到 stdout
3)学习如何使你的脚本可执行
4)将脚本添加到新的源路径,以便在任何目录下都可以调用
1)检查您是否有 python3,并且它是最新的
如果你像我一样是计算机科学的新手,你可能不知道你在哪里安装了 Python3,或者你是否安装了它。让我们确保您将它放在正确的目录中。这篇文章概述了如果你犹豫不决,我们将要做的事情。
以下所有步骤都将发生在您的终端内部。
打开你的终端,让我们开始编码吧!
让我们检查一下你是否安装了 python3。为此,我们将调用which
函数。which
将在你的路径变量中搜索 python3 的位置。
which python3
如果你看到类似于:
something/something/python3
你可以跳过这一步,继续制作你的第一个命令行工具。
但是,如果您看到python3 not found
,您需要遵循这里概述的步骤。我推荐做一个brew install python3
,但是如果你不太习惯自制软件,你也可以在这里下载安装程序。
安装 python3 后,重复上述步骤,python3 应该已经安装,PATH 变量现在将指向正确的目录。
让我们继续吧。
2)创建一个简单的程序来打印到标准输出
使用您喜欢的文本编辑器或 IDE (我将使用 VIM) 创建一个简单的“script.py”。对我们美国人来说,2020 年的情况尤其糟糕。为了振作起来,我将编写一个简单的命令行程序来鼓励用户!让我们称它为鼓励。py。它将 1 个参数,用户的名字和打印出一个个性化的笔记。
vim encourage.py
sys.argv 允许您为 CLI 提供命令行参数。
目前,这是一个 Python 脚本,我们只能使用函数 python3 来运行它。
python3 encourage.py tim
You're doing great, Tim!
您可能已经知道了 shell 中的别名,我们可以通过将 alias 命令附加到 shell 资源文件(zshrc)中来实现。注意,如果你没有 ~/。zshrc 文件,这将为您创建一个:
echo "alias py='python3'" >> ~/.zshrc
很好,现在我们可以简单地调用:
py encourage.py tim
You're doing great, Tim!
但是,这不是我们想要的。我们可以做得更好,并删除”。我们文件里的 py。的”。py”只对文本编辑器或 IDE 中的语法突出显示很重要。它不需要文件扩展名,因为您给函数 Python3 的是纯文本文件。这个你可以自己测试!
# rename your function
mv encourage.py encourage
py encourage tim
You're doing great, Tim!
太好了!现在我们要完全放弃“Python3”函数,制作一个完整的命令行程序。
3)让你的脚本可执行
在上一节中,我们了解到当我们调用 Python3 函数时,脚本的名称充当命令行参数。函数 Python3 不关心你的脚本是否有. py,因为它会接受你给它的任何纯文本文件。然而,如果我们想完全放弃调用 Python,那么我们必须在脚本的顶部插入 shebang 命令 #!/usr/bin/env python3
:
这告诉您的 shell 在读取该文件时将它解释为 Python 代码。默认情况下,您的 shell 不允许您执行文件,因此您必须为设置一个权限标志。在您的 shell 中运行这个命令,它将更改文件的权限,以便它是可执行的。
chmod +x encourage
在运行 chmod +x 鼓励我们的文件现在应该预览如下
现在我们可以运行我们的程序,只需:
./encourage tim
You're doing great, Tim!
有多简单?
真诚媒体在 Unsplash 上拍摄的照片
4)将脚本添加到我们的 PATH 变量中,这样它在任何目录中都是可调用的
cp、touch、ls 和 mkdir 的目录都存储在 PATH 变量中
你会注意到,为了调用它,你必须和函数在同一个目录中,但是我们希望能够从任何地方调用我们的函数。为了实现这一点,我们必须更新我们的 路径变量。PATH 变量加载到你的 shell 中,告诉 shell 在哪里寻找命令行函数。git、cd、ls 和 mkdir 目录的位置都存储在 PATH 变量中。我们有一个全新的功能鼓励我们需要添加到路径中。让我们首先在我们的用户目录中创建一个名为 bin 的新目录,并将我们程序的副本放在那里:
mkdir ~/.local/bin
cp encourage ~/.local/bin/encourage
然后,我们需要在 shell 资源文件中添加一个命令来更新我们的路径变量:
echo “PATH=$PATH:~/.local/bin/” >> ~/.zshrc
现在要么重启你的终端,要么运行source ~/.zshrc
您已经准备好测试您的程序了!切换到除您一直工作的目录之外的任何目录,并运行您的代码:
encourage tim
You're doing great, Tim!
二万·赫斯里在 Unsplash 上拍照
恭喜你!你完了。所有代码都在一个地方:
# Remove old version of python and do a fresh brew installsudo rm -rf /Library/Frameworks/Python.framework/Versions/3.6
sudo rm -rf “/Applications/Python 3.7”
brew install python3# Shebang command to add to the top of your script (include the "#")#!/usr/bin/env python3# Make the script executable by running this in your terminalchmod +x script# Create a local bin and add it to your shell PATH variablemkdir ~/.local/bin
echo "PATH=$PATH:~/.local/bin/" >> ~/zshrc# move a copy of your script to the ./local/bin
cp script ~/.local/bin/script# Restart your terminal or shell
source ~/.zshrc
如何将您的网络摄像头变成运动检测控制器
原文:https://towardsdatascience.com/how-to-turn-your-webcam-into-a-motion-detect-controller-9d4e9945644c?source=collection_archive---------22-----------------------
如何使用 JavaScript 实现运动检测的完整指南,构建一个虚拟鼓,你只需在空中挥舞双手就可以演奏。
来源:bensonruan.com
你玩过带运动传感器的 Xbox 游戏吗?在电子游戏中,只要挥动手臂去打网球就感觉很酷。运动检测是让这一奇迹发生的技术,它可以检测到物体相对于其周围环境的位置变化。
在这篇文章中,让我们来找点乐子。我打算建一个虚拟的鼓乐场,让你只需在空中挥舞双手就能敲鼓。它不需要任何运动传感器,只需要打开电脑或手机上的摄像头。
这是虚拟鼓游乐场的演示。正如你所看到的,当鼓和钹在那个区域探测到显著的运动时,它就会演奏。
来源:bensonruan.com
点击下面的链接亲自尝试一下:
[## 运动检测-使用网络摄像头播放鼓声- Benson 技术
你玩过带运动传感器的 Xbox 游戏吗?挥动手臂击球的感觉真酷…
bensonruan.com](https://bensonruan.com/motion-detection-play-drums-with-webcam/)
履行
你玩得开心,像摇滚明星一样一直打鼓吗?你好奇这种神奇是怎么发生的吗?我首先受到了这个木琴版本的启发,然后建立了我的上面的鼓版本。下面跟随我实现这个虚拟鼓游乐场的旅程。
#步骤 1:将网络摄像头传输到浏览器
为了让你的网络摄像头进入浏览器,我使用了 JavaScript 库navigator.mediaDevices.getUserMedia
。要了解更多细节,请参考我之前的博客:
[## 如何使用 JavaScript 访问网络摄像头并拍照
介绍网络摄像头-简易 npm 模块
medium.com](https://medium.com/swlh/how-to-access-webcam-and-take-picture-with-javascript-b9116a983d78)
#步骤 2:标记每个滚筒区域
用鼓和钹的图像覆盖网络摄像头。这是为了在网络摄像头中设置目标区域,以便每当在这些区域检测到重大运动时,它就会触发播放齿轮的效果。
HTML
JavaScript
通过齿轮的(x,y,宽度,高度)来存储齿轮的位置,请注意,宽度和高度需要通过全屏相机大小和混合画布大小之间的比率来计算。
#步骤 3:加载声音音频
为了演奏鼓和钹,我们需要加载这些乐器的音频声道文件。
#步骤 4:通过混合模式差异进行运动检测
这是进行运动检测的最重要的部分。它使用了一种叫做Blend Mode Difference
的技术。
首先,我来解释一下混合模式差异的概念。想象你拍了一张照片,半秒钟后又拍了一张,如果在那半秒钟内没有任何东西移动,那两张照片会完全一样。当你减去这两张图片的像素值时,它将全是 0,混合图像将完全是黑色的。如果在某些区域有移动,混合图像将突出显示差异。
有关更多详细信息,请参考下面的文章:
[## JavaScript 运动检测
了解如何使用 HTML5、JavaScript 和 jQuery 来检测网络摄像头流的移动,并对用户做出实时反应…
www.adobe.com](https://www.adobe.com/devnet/archive/html5/articles/javascript-motion-detection.html)
#第五步:播放效果和声音
我们为网络摄像头视频的每一帧反复调用以下函数进行运动检测。
**function****update()** {
drawVideo();
blend();
checkAreas();
**window.requestAnimationFrame(update);**
}
在鼓和钹的区域内,如果它检测到帧之间的显著差异,则表明该区域有运动。然后我们播放相应档位的效果和声音。
while (i < (blendedData.data.length * 0.25)) {
**average += (blendedData.data[i*4] + blendedData.data[i*4+1] + blendedData.data[i*4+2]) / 3;**
++i;
}
average = Math.round(average / (blendedData.data.length * 0.25));
**if (average > 20)** { //over a threshold, means significant movement
playHover(drum);
}
代码就这么多了。让我们享受和玩一些疯狂的鼓!
GitHub 知识库
您可以通过下面的链接下载上述演示的完整代码:
[## Benson Ruan/运动检测-虚拟鼓
从网络摄像头检测动作,通过在空中挥舞双手来玩虚拟鼓。
github.com](https://github.com/bensonruan/Motion-Detection-Virtual-Drums)
照片由杰登哈奇在 Unsplash 拍摄
结论
如今,运动检测已经应用于许多领域,例如安全警报、自动门……有些与传感器一起工作,有些可能基于计算机视觉目标检测。毕竟,我希望你觉得这个虚拟鼓游乐场有趣,并激起你对最新技术的兴趣。
感谢您的阅读。如果你喜欢这篇文章,请在 LinkedIn 或 Twitter 上分享。如果你有任何问题,请在评论中告诉我。在 GitHub 和 Linkedin 上关注我。
如何学习数据科学
原文:https://towardsdatascience.com/how-to-ultralearn-data-science-c9cee6e2fbd0?source=collection_archive---------14-----------------------
加速您的数据科学学习之旅
我刚刚读完斯科特·扬的 Ultralearning ,我认为这本书里的概念可以帮助许多想学习数据科学的人。Scott 用这种方法在一年内(通常需要四年)学习完了麻省理工学院本科生的计算机科学课程,并通过了所有的考试。
一、什么是超学习?
超学习:一种获取技能和知识的策略,这种策略是自我导向的和强烈的。
斯科特有 9 条超级学习原则。在本文中,我将重点介绍一些与您的数据科学研究最相关的因素(元学习、专注、直接、反馈和实验)。如果你想了解其余的(操练、提取、记忆和直觉),我强烈推荐你读这本书。这篇文章与我的数据科学学习阶段文章(链接)非常吻合,所以如果你喜欢这篇文章,你可能想在之后阅读那篇文章。
照片由与 Raj 在 Unsplash 上的公路旅行拍摄
元学习
书中的第一个原则叫做元学习。这为你的学习之旅奠定了基础。你应该花时间对这个领域有一个广泛的了解,并创建一个学习路线图。Scott 建议你应该在这一步上花费你总学习时间的 10%。
首先,你应该想想你到底想达到什么目的。要不要用数据科学搭建一个特定的 app?你想学足够的数据科学来找工作吗?在这里,你越具体越好。
接下来,你应该开始规划一条通往这个目的地的学习路径。我认为这非常类似于为自学课程建立你自己的课程。
从根本上说,数据科学只是编程和数学的结合。我做了几个视频,帮助你从哪里以及如何学习这些概念:如何学习数据科学的数学 & 如何学习数据科学的编程。
我还建议在网上寻找数据科学课程。大多数大学都在网上发布这些,你可以看到这些学校推荐学生上什么课或学什么概念。由此,你可以弄清楚你需要学习哪些概念,才能达到你特定的学习目标。
在你有了一个学习路径之后,你需要找到一个坐下来真正做工作的方法。
焦点
这不是数据科学特有的,但专注是一项值得学习的技能。没错,专注是一种习得的技能而不是与生俱来的。有两个主要组成部分,建立你集中注意力的能力和限制分心。
为了集中注意力,你应该专心工作,不要分心。这是卡尔·纽波特在他的《T2 深度工作》一书中谈到的一个概念。当你安排工作时间并坚持执行时,你就是在训练你的大脑。杨还推荐番茄工作法,即工作 25 分钟,休息 5 分钟。安排你的休息时间对我来说是一个巨大的突破。
为了减少分心,我建议控制你的环境。拥有一个专用的工作空间是很好的第一步。你的手机可能是你最大的干扰,所以把它放在不同的房间里,关闭电脑上的通知功能,会对你的注意力产生神奇的效果。
直接
这是我迄今为止最喜欢的原则。它建议你应该一头扎进去,开始做你努力学习的实际活动。当您接触到真实世界的数据科学项目时,您几乎会立即意识到自己的不足。我不断地推荐项目,我认为它们是学习数据科学最有效的方式。
当开始一个新项目时,我通常会工作到被某样东西卡住为止。一旦我这样做了,我打开几个谷歌标签,了解我正在努力的领域,并找出如何将它应用到我的项目中。这种方法保证了你正在学习完成手头项目所需要的东西。有时,我们陷入困境,因为我们试图学习太多来解决我们的问题。缩小范围和直接可以帮助我们提高学习效率。
直率可能会非常令人生畏。你会为你不知道的事情而挣扎和沮丧。这是完全正常的,也是作为一名数据科学家的一部分。这种感觉不会消失,即使你已经在这个领域取得了很大进展。
反馈
这可能令人害怕和不舒服,但却极其重要。数据科学很好,因为有许多清晰的反馈来源。在编程中,大多数时候你做错了事就会出错。您应该仔细阅读这些错误,因为它们通常会提示您哪里出错了。我也推荐使用 Google 和 Stack Overflow 调试代码。你通常只需将你的错误信息复制粘贴到浏览器中,就可以发现其他人是如何解决你所面临的同样问题的。
另一种获得有价值反馈的方法是通过社交平台来寻求反馈。Kaggle 和 Reddit 在这方面都很棒。有许多数据科学初学者论坛,对于构建促进建设性反馈的社区来说非常棒。
通常最好的反馈来自专家。你可以向网络中的数据科学家、教授或其他做过类似项目的人寻求反馈。我发现这种类型的帮助是最难得到的,但能帮助你提高最多。
实验
实验可以让你的数据科学工作从优秀走向卓越。当我们学习这个领域时,我们通常只用一种方法来解决每个问题。事实上,有许多不同的方法来分析每个项目。你做实验的时候,从不同的角度看同一个问题。这有助于您找出哪种方法最适合手头的任务。
当你做实验时,你经常不得不忘记一些你以前知道的事情。如果你只有一把锤子,一切都是钉子。如果你失去了你的锤子,你将需要找到独特的方法来建造。其中一些不同的方法可以节省您的时间/计算资源,并且实际上可以产生更好的结果。
实验有助于拓展你对概念的理解,并接近更高的学习水平。
最后的想法
希望这些原则能帮助你以新的眼光看待你的数据科学学习之旅。我希望我可以带着这些想法开始我自己的学习过程。同样,如果你想更深入地探索所有这些原则,我推荐你阅读这本书。
*顶部的超级学习链接是亚马逊联盟链接。通过链接购买的每件商品,我都可以免费获得几分钱。如果你想表示你对我或我的文章的支持,请随时通过它购买这本书!
如何取消删除您的 Jupyter 笔记本
原文:https://towardsdatascience.com/how-to-un-delete-your-jupyter-notebooks-1289e741705f?source=collection_archive---------17-----------------------
用 SQL 和命令行破解 Jupyter 笔记本的元数据科学
谁不爱 Jupyter 笔记本?它们是互动的,给你即时反馈的即时满足感。它们是可扩展的——你甚至可以把它们作为网站来部署。对于数据科学家和机器学习工程师来说,最重要的是,它们具有表现力——它们跨越了操纵数据的科学家和工程师与消费并希望理解数据所代表的信息的普通观众之间的空间。
但是 Jupyter 笔记本也有缺点。它们是大型 JSON 文件,存储您运行的每个单元的代码、降价、输入、输出和元数据。为了理解我的意思,我写了一个简短的笔记本来定义和测试 sigmoid 函数。
朱庇特笔记本。
以下是当 IPython 不渲染它时(的一部分)看起来的样子(除了第一个实际的输入单元格,我已经省略了所有的单元格,因为即使对于一个短笔记本来说,它也是又长又丑的):
{
"nbformat": 4,
"nbformat_minor": 2,
"metadata": {
"language_info": {
"name": "python",
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"version": "3.6.8-final"
},
"orig_nbformat": 2,
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"npconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": 3,
"kernelspec": {
"name": "python36864bitvenvscivenv55fc700d3ea9447888c06400e9b2b088",
"display_name": "Python 3.6.8 64-bit ('venv-sci': venv)"
}
},
"cells": [
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import random"
]
},
...
}
因此很难对它们进行版本控制。这也意味着有很多你通常不太关心保存的垃圾数据,比如单元执行计数和输出。
下次你想知道为什么你的 Jupyter 笔记本运行如此缓慢时,在纯文本编辑器中打开它,看看你的笔记本元数据中有多少海量数据帧。
不过,在适当的情况下,所有这些垃圾看起来都像珍贵的宝石。这些情况通常包括:
- 意外关闭笔记本而未保存它
- 点击错误的快捷键,删除重要的单元格
- 在多个浏览器窗口中打开同一笔记本并覆盖您自己的工作
任何误入在 IPython 笔记本上进行开发的危险领域的人都至少做过一次这些事情,可能是在同一时间。
如果这是你,你在这里是因为你谷歌了恢复删除 jupyter 笔记本刷新浏览器窗口,不要惊慌。首先我要告诉你如何修理它。*然后我要告诉你如何防止它再次发生。
*是的,你能修好它。(大概吧。)
我为你做的一本指南,在笔记本上,关于笔记本
要求:
- 安装了 Jupyter、IPython(带有 nbformat 和 nbconvert)和 jupytext 的 Python 虚拟环境(最好是一个新的 venv,这样您可以测试一下)
- sqlite3 的工作安装(可选但推荐:像 SQLiteStudio 这样的数据库浏览器)
- 希望和决心
场景:您意外删除了活动笔记本中的几个单元格
(不科学)估计恢复概率:90%
相对难度:更容易
在最坏的情况下,您点击了不想删除的单元格上的x
,现在您想取回它的代码或数据。
方法一:进出
当您使用笔记本时,IPython 内核会运行您的代码。IPython 内核是一个独立于 Python 解释器的进程。(这也是为什么您需要将新的内核链接到新的虚拟环境。这两者不是自动连接的。)它使用 JSON 发送和接收消息,就像您的代码单元一样。
当您运行一个单元或点击“保存”时,笔记本服务器会将您的代码作为 JSON 发送到您计算机上的一个笔记本中,该笔记本存储您的输入和输出。所以你手机旁边的小单词In
和Out
不仅仅是单词,它们是容器——特别是你会话历史的列表。你可以打印出来并编入索引。
[]容器中的 IPython
方法二:IPython 魔术
使用%history
line magic 打印您的输入历史(后进先出)。这个强大的命令允许您通过绝对或相对数字访问当前和过去的会话。
如果当前的 IPython 进程仍然处于连接状态,并且您已经在您的虚拟环境中安装了nbformat
,那么在单元格中执行以下代码来恢复您的笔记本:
>>> %notebook your_notebook_filename_backup.ipynb
这种魔法将整个当前会话历史呈现为一个新的 Jupyter 笔记本。
嗯,还不算太糟。
这并不总是有效,您可能需要花费一些精力从输出中剔除无关的单元格。
你可以用历史魔法做更多的事情。这里有几个我觉得有用的食谱:
%history -l [LIMIT]
获取最后的 n 个输入%history -g -f FILENAME
:将您的整个保存的历史记录写入一个文件%history -n -g [PATTERN]
:使用 glob 模式搜索您的历史,并打印会话和行号%history -u
:仅从当前会话中获取唯一的历史。%history [RANGE] -t
:获取本机历史,也就是 IPython 生成的源代码(有利于调试)%history [SESSION]/[RANGE] -p -o
:使用>>>
提示符打印输入和输出(适合阅读和文档)
如果你已经在一个真正的大数据科学笔记本上工作了很长时间,那么%notebook
魔法策略可能会产生很多你不想要的噪音。使用其他参数削减%history -g
的输出,然后使用 jupytext(解释如下)转换结果。
场景:你关闭了一个未保存的笔记本
(不科学的)估计恢复概率:70–85%
相对难度:更难
还记得我们说过笔记本的版本控制很难吗?一个内核可以同时连接到多个前端。这意味着打开同一笔记本的两个浏览器选项卡可以访问相同的变量。这就是你最初重写代码的方式。
IPython 将您的会话历史存储在数据库中。默认情况下,您可以在您的主目录下的一个名为.ipython/profile_default
的文件夹中找到它。
$ ls ~/.ipython/profile_defaultdb history.sqlite log pid security startup
备份history.sqlite
到副本。
$ cp history.sqlite history-bak.sqlite
在数据库浏览器中或通过 sqlite3 命令行界面打开备份。它有三个表:历史、输出历史和会话。根据您想要恢复的内容,您可能需要将这三者结合在一起,所以请放弃您的 SQL。
IPython 历史的 SQLiteStudio 视图
盯着它
如果您可以从数据库浏览器 GUI 中判断出history
表中的哪个会话号有您的代码,那么您的生活就简单多了。
历史表的 SQLiteStudio 视图
在浏览器中或命令行上执行 SQL 命令:
sqlite3 ~/.ipython/profile_default/history-bak.sqlite \
"select source || char(10) from history where session = 1;" > recovered.py
这只是指定会话号和要写入的文件名(在给出的例子中是1
和recovered.py
),并从数据库中选择源代码,用换行符(在 ASCII 中是 10)分隔每个代码块。
如果您想选择行号作为 Python 注释,可以使用如下查询:
"select '# Line:' || line || char(10) || source || char(10) from history where session = 1;"
一旦你有了一个 Python 可执行文件,你就可以松一口气了。但是你可以用 jupytext 把它变回笔记本,这是一个神奇的工具,可以把明文格式转换成 Jupyter 笔记本。
jupytext --to notebook recovered.py
不太可怕!
场景:你在多个标签页中打开你的笔记本,重新加载一个旧版本,删除你所有的工作,并杀死你的内核
(不科学的)估计恢复概率:50–75%
相对难度:最难
以上都不起作用,但你还不准备放弃。
硬模
回到你正在使用的任何工具来浏览你的history-bak.sqlite
数据库。您编写的查询将需要创造性的搜索技术来充分利用您拥有的信息:
- 会话开始的时间戳(总是非空)
- 会话结束的时间戳(有时以有用的方式为空)
- 输出历史
- 每个会话执行的命令数
- 您的输入(代码和降价)
- IPython 的渲染源代码
例如,您可以通过以下查询找到您今年编写的与 pytest 相关的所有内容:
**select** line, source**from** history**join** sessions**on** sessions.session = history.session**where** sessions.start > '2020-01-01 00:00:00.000000'**and** history.source like '%pytest%';
一旦您将视图调整为您想要的行,您可以像以前一样将其导出到可执行的.py
文件,并使用 jupytext 将其转换回.ipynb
。
如何避免需要这篇文章
当你品味不必从头重写笔记本的解脱时,花点时间思考一些措施来防止未来的探索进入history.sqlite
:
- 不要将相同的前端连接到同一个内核。换句话说,不要在多个浏览器标签中打开同一个笔记本。使用 Visual Studio 代码作为您的 Jupyter IDE 很大程度上消除了这种风险。
- 定期备份您的 IPython 历史数据库文件,以防万一。
- 尽可能将您的笔记本转换为明文,至少为了备份。Jupytext 让这变得几乎微不足道。
- 使用 IPython 的
%store
魔法在 IPython 数据库中存储变量、宏和别名。你所需要做的就是在profile_default
中找到你的ipython_config.py
文件(或者如果你没有的话运行ipython profile create
,添加这一行:c.StoreMagics.autorestore = True
。如果你愿意,你可以存储、别名和访问从环境变量到小型机器学习模型的任何东西。这是完整的文档。
Jupyter 笔记本给你带来的最大挑战是什么?对你想在以后的帖子中讨论的话题发表评论。
资源
- 使用 Visual Studio 代码启动您的 Python 项目
- 谷歌数据科学高级技能
- Jupytext
- IPython storemagic
- IPython 历史魔法
- SQLiteStudio
如何从外太空理解全球贫困
原文:https://towardsdatascience.com/how-to-understand-global-poverty-from-outer-space-442e2a5c3666?source=collection_archive---------32-----------------------
使用卫星图像和神经网络预测资产财富,以卢旺达为例
图片来自美国地球物理联合会
经济生计难以估计。即使在当今世界,也缺乏明确的数据来确定贫困地区,这导致资源分配不足——金钱、食物、药物和受教育机会。我们生产了大量的资源,为多达 100 亿人提供食物、衣服和住房,但仍有数亿人生活在贫困之中。
帮助缓解这一问题的一种方法是创建一个模型,利用计算机视觉来绘制和预测非洲国家卢旺达的贫困状况,这个模型足够小,可以提供丰富多样但不庞大的数据集。
我们如何完成这项任务?有几个关键步骤:
- 下载人口和健康调查(DHS)、夜灯卫星图像和白天卫星图像
- 测试夜灯能否准确预测财富
- 测试白天图像的基本特征是否也能准确预测财富,并提取图像特征
- 利用白天和夜晚灯光图像的组合数据集构建一个卷积神经网络(CNN ),并应用迁移学习
- 构建显示预测财富分布的地图
在本文中,我们将学习如何开发一种可扩展的方法,使用识别图像特征的 CNN 来预测农村地区的贫困状况。我们将利用白天和夜间的卫星图像来创建一种准确而廉价的方法,以在集群级别(一个 10×10 公里的区域)估计资产财富。以下概述抓住了主要目标:
概观
模型管道
1.下载数据
有三个组成部分:夜间照明,白天图像和 DHS 调查。
卢旺达 DHS
从官方 DHS 页面下载卢旺达 DHS 数据并构建集群需要注册访问。这些调查提供了健康、人口和营养方面的代表性家庭数据,并通过给电力和技术设备等普通资产分配-2 到 6 的值,列出了资产得分(衡量财富的一种方法)。这些数据将作为我们的“地面实况”数据和标签系统,用于提取相应的白天和夜间图像。我们还使用地理数据集 shapefile 来报告每个指定聚类的坐标。具体来说,我们要求 RWHR61FL。ZIP(家庭调查)和 RWGE61FL。DHS 网站上的 ZIP (shapefile)文件。
夜灯
2010 年夜灯文件是一个包含来自世界各地的夜灯强度的单一大图像。为了只提取卢旺达,我们利用先前下载的 shapefile。
白天的图像
最后,我们使用 API 密匙从谷歌地图平台获取白天的图像。像夜灯一样,它们是基于 DHS 数据集中提供的位置提取的,包含聚类级别的有价值的景观和活动特征。使用 Maps Static API 和卢旺达 shapefile,我们对成千上万的卫星图像进行了 ping 服务。我们使用 400×400 像素的图像,每幅图像代表 1 平方公里。
数据组织方案
2.尝试夜灯和 DHS 数据
在收集了必要的数据后,目标就变成了理解夜灯数据是否可以用来预测财富。首先,我们合并 DHS 和夜灯数据,然后拟合一个关于夜灯的财富模型。每个 DHS 星团的平均夜间亮度是通过对环绕星团中心的夜灯位置的亮度值取平均值来计算的。
(左)资产评分和夜灯叠加;(右)回归模型说明了平均集群财富与相应集群夜灯亮度之间的关系
叠加可视化意味着夜灯亮度是较低贫困的一个很好的指标,因为较亮的区域有代表较高资产财富的冷色点簇。为了更深入地探究为什么较暗区域的资产分数是这样的,以及回归模型更好,我们问:我们可以从卫星图像中提取出什么有意义的东西?
3.切换到白天图像
白天的图像不断被记录,自动更新,并且大量可用,被证明是一种有价值的资源。
提取基本特征
为了测试白天图像是否可以预测集群财富,我们首先提取基本特征。对图像进行编码,使得每个像素由 0 到 255 之间的三个数值组成,对应于红色、绿色和蓝色级别。从这三个颜色层的每一层中,我们提取五个基本特征:像素值的最大值、最小值、平均值、中值和标准偏差。
然后将白天的图像与 DHS 数据合并,并拟合出一个财富模型,作为这些基本白天特征的函数。预测平均集群财富的线性回归模型得出的 R 值(相关系数)为 0.558。
基本影像特征-当模型基于基本日间影像特征进行训练时的资产财富预测,产生 0.558 的 R 值
结合预先训练的神经网络
接下来,我们用深度学习提取特征。首先获得在 ImageNet 上预训练的 CNN (8 层,VGG-F ), ImageNet 是为对象识别研究设计的大型带注释的数据库。
原始的 VGG-F 架构,其中有一个通过卷积和池层分析的输入。该模型从图像中提取 4096 个特征。
在学习从 1000 多个类别中正确分类每张图像的过程中,该模型识别边缘和拐角等低级特征,这些特征对计算机视觉任务至关重要。通过 Keras,我们使用 CNN 将白天的卫星图像输入到这个模型中,并输出 4096 维的特征向量,然后这些特征可以用于预测资产财富。R 值增加到 0.689。因此,我们得出结论,用深度学习提取特征确实提高了模型的准确性。
CNN 特征-根据 CNN 的日间影像特征训练模型时的资产财富预测,得出 R 值为 0.689
到目前为止,我们只合并了白天的图像。为了获得更好的预测,我们还应该以一种巧妙的方式包括夜间图像。
4.实施迁移学习
为了提高模型的准确性,我们应用了转移学习步骤,而不是直接使用 CNN 提取的图像特征,我们重新训练它从白天的图像中预测夜间灯光,以最终使用这些特征,这可能更适合估计资产财富的最终预测任务。该模型依赖于一种迁移学习方法,使用 CNN 从白天的卫星图像中提取图像特征。有三个步骤:
估计夜灯强度
DHS 调查数据集将夜间亮度表示为 0 到 63 范围内的整数。在预测夜灯时,我们将这些亮度分为三类——低(0 到 2),中(3 到 34),高(35 到 63)。
改变模型的用途
现在,我们通过重新训练最后一层,将该模型重新用作白天卫星图像的特征提取器;这是夜灯强度分类图层。本质上,我们要问的是:给定一个白天的图像输入,同一个区域在晚上会是什么样子?
该模型学习从每个输入的卫星图像到某个矢量表示的非线性映射,并具有在图像上“滑动”的过滤器,精确定位逐渐变得更加复杂的特征。例如,该模型最初学习诸如边和顶点之类的基本特征,但是最终寻找诸如道路、水路和建筑物之类的复杂得多的特征。
完全连接的层被转换成卷积层,随后是平均池层,这允许网络通过卷积对单个图像进行多次评估,并对结果进行平均,以产生概括每个图像的一个特征向量。卷积层对输入进行多次评估,输出多个特征向量。对图像的几次评估有助于处理每个输入图像的不同部分。
获得最终特征向量
然后,我们对这些特征向量进行平均,以获得每个聚类的一个向量,该向量被用作估计消费支出和资产财富的岭回归模型的输入。
覆盖在卫星图像上的卷积滤波器(来源:科学
我们分析这些特征,而不是仅仅使用白天图像收集的特征,是否在预测平均集群财富方面做得更好。他们做到了!R 值甚至进一步增加到 0.718,显著增加。
迁移学习-当模型通过迁移学习在白天影像特征上进行训练时的资产财富预测,产生 0.718 的 R 值。该模型现在更加可靠,由红色和灰色虚线的紧密程度以及较高的 R 值来表示。
5.创建资产财富图
用于评估经济福祉的迁移学习模型显著改进了现有的夜灯方法。我们分析了接近和低于贫困线的人口的福祉,因为夜灯显示的变化很小,并且在这些地区的预测能力很低。夜灯无法很好地区分贫穷、密集的区域和富裕、稀疏的区域,这两种区域的夜灯水平都很低。
在应用迁移学习之后,产生标准化的混淆矩阵。矩阵值沿对角线最大,表明相对较高的真阳性率。从图中可以明显看出,最低的夜灯级别具有最高的准确度(与仅夜灯模式的主要区别),最高的夜灯级别具有第二高的准确度。
转移学习混淆矩阵,因为夜灯不能有效地表征低亮度区域
此外,我们可以构建财富预测的热图,将所有绘制的特征叠加到卢旺达地图上。您可以看到,结果非常像之前显示的资产财富和夜间照明数据叠加的彩色地图,这意味着该模型表现良好。
预测财富的热图-较亮的区域对应于贫困程度较低,较暗的区域对应于贫困程度较高。
结论
本文介绍的方法表明,我们可以利用 CNN 的日间和夜间卫星图像,配合调查数据,准确定位特定地方的高经济福祉和低经济福祉区域,从而确定贫困区域。由于这种方法是可扩展的和廉价的,我们希望将研究和结果扩展到更多的国家。
完整代码可在此 GitHub 资源库 获得。
参考文献
[1] K. Beegle,L. Christiaensen,A. Dabalen 和 I. Gaddis,崛起中的非洲的贫困问题 (2016 年),世界银行
[2] M. Brems,主成分分析一站式商店 (2019),走向数据科学
[3] N. Jean,M. Burke,M. Xie,W. Davis,D. Lobell,S. Ermon,结合卫星图像和机器学习预测贫困 (2016), Science
[4] S. Athey,超越预测:利用大数据解决政策问题 (2017),科学
[5] S. Pandey,T. Agarwal,C. Krishnan,从卫星图像预测贫困的多任务深度学习 (2018),AAAI 2018
[6] S. Piaggesi,L. Gauvin,M. Tizzoni,C. Cattuto,N. Adler,S. Verhulst,A. Young,R. Price,L. Ferres,A. Panisson,利用卫星图像预测城市贫困 (2019),CVPR,2019
[7] T. Stark,M. Wurm,H. Taubenbock,X. Zhu,使用迁移学习深度特征在不平衡遥感数据集中绘制贫民窟 (2019),IEEE
[8] M .谢,n .让,m .伯克,d .洛布戴尔,s .埃蒙,遥感与贫困制图深度特征迁移学习(2016) ,2016
如何通过踢足球了解 LSTM
原文:https://towardsdatascience.com/how-to-understand-lstm-by-playing-football-136c8431e451?source=collection_archive---------60-----------------------
得分时掌握长短期记忆门
足球图书概念' | ID 27329051 庞苏万| Dreamstime.com
在这一系列文章中,我们研究了前馈神经网络(FFNN)在理解上下文时的局限性。为了解决这个问题,我们引入了递归神经网络(RNN) 的概念,并定义了存在的不同类型。然而,我们之前的分析没有充分解决 RNN 的关键问题,比如是什么让 RNN 变得不同?细胞内部会发生什么样的计算?RNN 是如何学习的?
本文的目的就是要解决所有这些问题,为了做到这一点,从历史的角度入手可能会有所帮助。Jeffrey L. Elman 在 20 世纪 90 年代早期首次尝试创建能够理解上下文的模型。这第一个 RNN,有时被称为香草 RNN,是同一层的两个单元共享信息的第一个单元之一,状态将从一个传递到另一个。
正如这篇文章的标题所暗示的,目的是通过踢足球而不是谈论历史来了解 LSTM,球在哪里?
比赛开始了
来了,下面的模型代表了作为一名足球运动员你必须采取的行动的简化。模型的输入是你的眼睛在野外看到的图像。然后一个 RNN 层对你的下一个动作做出正确的计算,它可以是“通过”、“等待”、“运行”…
在时间 t,你得到球,你看到你的一个同事没有被防守,所以 RNN 决定传球。下一个图像是你的同事试图控制球,你不知道他是否能做到,然后你在进攻或防守之前等待。在时间 t+2,他拿着球,如果他想把球传回来,你可以主动出击。他是一个非常优秀的球员,所以他决定向足球目标跑去,那么你的行动就是也跑。在时间 t+4,他正在投篮,所以你的第一个想法是准备好,如果有任何反弹。在时间 t+5,你看到球进了球门,所以你和你的同事一起庆祝进球,度过了一个美妙的时刻。
作者图片
一旦我们感受到进球和庆祝进球的激动时刻,是时候看看数学了。下面我们表示 RNN 层中的一个单元,内部发生了什么计算?
作者图片
在时间 t+1,单元接收两个输入,来自前一单元的状态 S̅ₜ和事件 x̄ₜ₊₁,在我们的例子中是图像。为了计算单元 S̅ₜ₊₁的下一个状态,我们将来自事件和状态的点积的结果与其各自的权重矩阵相加,并且我们应用激活函数φ。你不知道什么是激活函数吗?激活函数的概念将在下一节更详细地探讨。结果向量在时间 t+2 作为其输入之一进入单元。最后,通过 S̅ₜ₊₁与其权重矩阵 Wᵧ的点积获得预测 y̅ₜ₊₁。
那么,我们是不是说人类的记忆可以通过两次计算来复制?神经网络理解上下文就这么简单吗?答案是否定的,埃尔曼的方法是一个非常好的工作,但是它有一个障碍,叫做消失梯度问题,因此我们也知道这个单元是短记忆。计算机还没有变得比人更聪明。
1-谁在我的团队中?或者消失梯度问题
在代表 RNN 足球裁决的例子中,我们只关注了一个动作。但是结果是什么呢?还剩多少时间?是联赛还是冠军赛?我要传球给的球员是否在我的队伍中?
Elman 结构遭受消失梯度问题:这意味着细胞不能从 8-10 个时间步长学习任何时间依赖性。由于之前的 RNN 模型,我们可以找到问题的更清晰的表述。在这种情况下,我们将改变 RNN 层的颜色(绿色气泡)的表现多少数据,它可以记住从以前的步骤。在每个时间步,新数据被添加到由不同颜色表示的 RNN 中。第一步,我们只显示蓝色,而第二步,添加橙色。然后,当我们继续穿越时间时,从先前的时间步骤接收的信息开始消失,而由更近的步骤给出的信息变得更加可见。我们的模型已更改如下:
作者图片
即使我们没有涉及到消失梯度下降背后的数学,从这个图中我们可以清楚地理解这个问题。序列越长,神经网络就越难从前面的步骤中学习。
所以,我们已经看到我们的球员有短暂的记忆。然后他可能会忘记比赛的目标或者队友;因此,他所做的决定可能会阻止他赢得比赛。那么我们如何解决短期记忆的问题呢?
2-如何赢得' le ballon d'or' (长短期记忆)
90 年代中期,Sepp Hochreiter 和 Jürgen Schmidhuber 介绍了长短期记忆或 LSTM。这个理论引入的创新是 gates 的想法,我们数据中的一些信号可以保存为【LTM】,而其他信号可以保存为短时记忆(STM) 。这种区分允许根据情况在需要时使用长期或短期信息。为了更好地理解长时记忆和短时记忆的区别,让我们关注一下同事进球后的时间步长 t + 5。我们希望得到的最终图表如下所示:
作者图片
作为输入,我们有我们正在分析的事件(图像),而不是只有一个状态或记忆,我们有两个,LTM 的目的是记住不会经常更新的一般信息,而 STM 专注于要使用的精确信息。然后我们应用 LSTM 细胞,我们输出一个新的 LTM,一个 STM 和一个预测。在图像的中间,我们再次看到代表 RNN 的绿色气泡。如果我们观察这个气泡内部,我们将分析 4 种不同的计算。为了便于表示,我们将气泡转换成了矩形。从概念上讲,RNN 单元看起来如下:
作者图片
有 3 个门加一个单元状态。在一些文章中,你可能会发现存在 4 个门,但这是因为它们也将单元状态称为门。在“3-数学表示法”部分,我们将看到不同之处。
为了更好地理解每个关卡的目的,让我们继续看时间步长 t+5 的例子,在这个例子中,我们的队友得分了。
- 忘记门:顾名思义,这个门的作用是决定前一时间步中哪些信息不再有用。例如,在 t + 5,因为我们的同事进了一球,我们不再需要记住前一分钟的比分。我们首先忘记旧的结果,然后添加新的结果。在这个门口,我们只是忘记了我们是 1-0 获胜。
- 输入门 : 决定我们应该保留哪些新信息。从输入图像中,我们不需要知道草是绿色的,或者球是圆的。并不是所有来自图像的信息都是相关的,我们将只保留例如我们进了一个球。
- 细胞状态:正如我们之前看到的,LSTM 允许拥有不仅仅是短暂的记忆。单元状态负责从遗忘门获取输出并遗忘不再有效的内容,然后从输入门获取输出并添加相关信息。细胞状态的输出将是下一步的长期记忆。
- 使用 Gate :我们已经计算了什么信息会作为长期传递到下一个时间步;现在是计算短期状态的时刻。我们一方面需要细胞状态的输出,另一方面需要来自事件(图像)和短期记忆的信息,以决定我们作为足球运动员的下一步行动是与我们的团队一起庆祝进球。这个结果将具有双重目的,一方面它将是要传递到下一层的短记忆状态,另一方面它将是 LSTM 层的预测。
很好,到目前为止,我们已经研究了埃尔曼提出的香草 RNN 的极限。我们理解了消失梯度的问题,以及这个模型如何只能创造短期记忆。为了解决这个问题,我们引入了一种新的 RNN 单元结构,称为 LSTM,由不同的门组成。上面的解释是对 LSTM 工作原理的简化解释,让我们在更深层次上理解所使用的数学。
3-数学表示
一旦我们把上面的图和门转换成计算,这就是它看起来的样子。
作者图片
第一次看到这张图片时,我有点不知所措,一个单元格中有太多的函数和线条。如果你也和我一样,没有必要担心,因为如果你已经理解了上面解释的概念;理解这种结构将会非常容易。
在详细解释 LSTM 之前,先说一下激活函数。为了理解激活功能,只要想想我们大脑中的神经元,它们以开关的方式与电脉冲一起工作。神经元是相互连接的,它们用这些脉冲交换信息。某些神经元的激活会触发我们的行动。回到我们的 RNN,输入是用数字而不是脉冲来测量的,那么我们如何将这些数字转换成脉冲呢?这正是激活功能开始为我们做这项工作的时候。让我们特别关注其中的两个:
- Sigmoid(σ):Sigmoid 函数的每个输入都有一个介于 0 和 1 之间的输出值。万一忘记了信息,该函数输出 0。否则,该函数输出 1 以保留信息。
- 双曲正切 (tanh):这个激活函数的输出在-1 和 1 之间。那么 tanh 的目标只是将它接收到的所有信息转换成[-1;1]这样网络才能正常工作。
关于激活函数的更多信息,我推荐下面的文章 。
我们已经把图表转换成了数学表示,让我们用同样的方法来解释。一旦我们理解了用文字解释的每个门的作用,现在是时候用数字来解释了:
- 忘记入口:
作者图片
我们解释说这个门的作用是决定由于短期记忆和新图像在 LTM 中哪些信息要忘记。因此,我们使用了一个 sigmoid 函数。正如我们在图像中看到的,我们将 LTM 表示为一个向量,sigmoid 的输出将是一个相同形状的向量。来自团队和游戏的信息将被保留,因为激活函数的输出是 1,而对于分数输出是 0。然后我们忘记了分数。
- 输入门:
作者图片
它由两个动作组成,一方面我们通过应用 tanh 计算新信息,然后我们根据这个新信息中的 sigmoid 决定我们应该保留哪个。“分数”、“团队”和“游戏”的新信息已经计算出来,但我们将只保留新的“分数”。
- 单元格状态:
作者图片
在这里我们可以清楚地看到为什么这不是一个门。有一个乘法和一个加法,我们不是用 tanh 变换数据,也不是用 sigmoid 选择要保留什么信息。一旦我们知道从以前的 LTM 中保留什么信息,从新的输入中保存什么信息,我们就有了下一步的 LTM。
- 使用门:
作者图片
这个门将从新的 LTM 接收过滤的信息,由于 STM,新的图像将得到一个新的 STM。值得注意的是,这个门的输出同时是新的 STM 和预测。
这是一个长期的短期记忆结构,我们利用来自前一时间步的信息,感谢 LTM 和 STM 结合新的信息,图像。我们应用 sigmoid 来决定保留什么信息,并用 tanh 来保持值在-1 和 1 之间。每个门都有自己的角色和激活功能的组合。
我们必须考虑到,LSTM 不是唯一的结构,例如门控循环单元(GRU)也是一个众所周知的结构。它遵循相同的门和激活函数的思想,不同之处在于门的数量和它们各自的分布。
摘要
如果你到了这一步,恭喜你!你开始成为 RNN 专家。这意味着我们理解了 FFNN 在理解上下文以及如何应用 RNN 来解决它时的局限性。
这也意味着我们知道存在不同的细胞结构。第一个是香草 RNN ,它遇到了梯度消失的问题,换句话说就是无法在多个时间步上保持依赖性。这个短记忆的问题可以通过一种叫做 LSTM 的新单元结构来解决。最重要的是,我们深入研究了 LSTM 细胞的结构,以了解它是如何工作的。
长短期记忆不是像香草 RNN 那样只有一种状态,而是有长期记忆和短期记忆两种状态。我们分析了遗忘门的作用,它决定了前一时间步中哪些信息不再有用。然后输入门从新输入中过滤出相关的信息。单元状态从遗忘门和输入门获取输出以产生新的 LTM。最后,使用门结合新的 LTM 和输入来创建 STM。
到目前为止,我们已经关注了细胞本身,在接下来的文章中,我们将探索使用 LSTM 细胞的多种方法,例如创建一个编码器-解码器结构,以及它如何允许为注意力模型播下种子。
[## 递归神经网络导论(RNN)
计算机是如何理解上下文的?什么是递归神经网络,它如何帮助我们?有没有…
medium.com](https://medium.com/swlh/introduction-to-recurrent-neural-networks-rnn-c2374305a630) [## 如何用 RNN 和喀拉斯建立翻译管道
你有没有想过一台计算机是如何能够如此快速地学习多种语言的?按照这个逐步指南…
towardsdatascience.com](/how-to-build-a-translation-pipeline-with-rnn-and-keras-57c1cf4a8a7)
如何通俗地理解 p 值?
原文:https://towardsdatascience.com/how-to-understand-p-value-in-layman-terms-80a5cc206ec2?source=collection_archive---------4-----------------------
理解 p 值的简单方法
统计学中最重要的概念之一是 p 值的解释。我想更简单的分享一下我对 p 值的理解。
假设一家公司声称其生产的巧克力“X”在 1 块巧克力中含有 70 克坚果。但是一些顾客抱怨巧克力棒的果仁少于 70 克。我们想测试一下该公司关于巧克力 X 中坚果平均重量的说法是否正确。让我们试着解决这个问题。
你认为所有这些巧克力棒都有同样多的坚果吗??
我们抽取 20 个巧克力棒的样本,并找出这些巧克力棒中坚果的平均数量(样本平均值),以推断总体平均值。总体和样本的区别?见下文:
从人群中取样有不同的方法。这里我们从最近的商店里随机抽取了一些酒吧。
总体平均值(我们不知道)是该公司生产的所有巧克力棒中所含坚果的平均值,这在现实中是无法计算的。在我们的例子中,我们假设它的价值为 70gm(假设的平均值——公司所声称的)。
假设我们取样的 20 根棒线的坚果平均值为 68.5。我们能断定顾客的说法是真实的吗?这是否提供了足够的证据证明巧克力棒缺少坚果,或者这一结果只是运气使然?为了回答这个问题,我们进行假设检验。
让我们陈述无效假设和替代假设。
零假设:巧克力棒中坚果的总体平均值为 70 克。(这是我们试图提供证据反对的事情。)
替代假设:巧克力棒中坚果的总体平均值小于 70 克。(这是我们试图证明的)
该规则规定,如果 p 值小于显著性水平(α),我们拒绝零假设。下一个问题:
显著性和 p 值是什么水平?
显著性水平(alpha) 是我们拒绝零假设时愿意承担的风险百分比。
P 值是随机机会产生的数据或其他相等或更少的数据的概率(在零假设下)。我们计算样本统计的 p 值(在我们的例子中是样本平均值)。我们可以通过查看 z 表来手动计算,或者使用一些统计软件来计算。
假设真正的巧克力数量平均为 70 克。这并不一定意味着,如果世界上有 100 万块 X 型巧克力,那么每块巧克力的平均坚果含量为 70 克。可能很少有平均重量小于 70 克的巧克力,也有一些平均重量大于 70 克的。因此,当我们抽取一些巧克力样品时,由于取样的变化,样品的平均值可能小于、等于或大于 70 克。
回到 p 值的解释。
“p 值用于确定实验结果是否具有统计学意义。低 p 值意味着假设零假设是真的,那么这个结果是运气的结果的可能性非常低。高 p 值意味着假设零假设是真的,这种结果是非常可能的”
p 值-正态曲线下阴影区域的面积
如果 p 值
假设我们得到 p 值为 0.04。这意味着,在假设总体螺母平均值为 70 gm 的情况下,如果我们在零假设下重新运行测试,我们将获得 100 次样本平均值中的 4 次(在我们的情况下为 68.5)。非常不可能!因此,我们可以说——结果表明样本可能来自不同的亲本群体。
因此,我们拒绝零假设。在这种情况下,我们有强有力的证据再次无效。
得到如此罕见的东西(几率为 4/100)可能不太可能,但仍有可能是运气使然。
让我们试着理解我们拒绝零假设的基础——为什么我们得出样本不是来自零假设下的总体。假设你有两张彩票,然后随机洗牌。一张票来自有 300,000 个参与者和 1 个奖品的事件 X。另一张票来自 Y 事件,有 30 名参与者,有 10 个奖项。你中了一张彩票,但你不知道它属于哪个项目。你的猜测不会是:事件 Y,因为奖品多,人少的时候,你本来中奖的机会就多。但是假设你的中奖彩票来自 X 事件!万岁!!!运气发挥了作用,你得到了!
因此,当我们说一个事件不太可能发生时,它仍然有可能是侥幸发生的,这就是我们偶然发现第一类错误的时候——当它为真时拒绝空值。未能拒绝错误的零假设被称为第二类错误。
记住第一类和第二类错误定义的最好例子之一。(参考谷歌图片)
回到我们的定义,因为这会更有意义。显著性水平(Alpha) —在拒绝零假设或 I 型错误率时,我们愿意承担的风险百分比。
事实上,重要程度取决于我们基于假设检验试图回答的问题类型。如果这个问题是关于你当地核电站的熔毁风险,就在这条路不到一英里的地方,会怎么样?在接受错误答案的风险之前,你可能想更确定一点。
我相信这篇文章帮助你建立了对 p 值的基本理解。围绕在现实世界中使用它有很多争论。使用 p 值有一些优点和缺点。参考本文快速阅读:https://www . prosancons . com/education/pros-and-cons-of-p-values/
感谢阅读。希望得到您的反馈。
参考资料:
[1]https://www.investopedia.com/terms/p/p-value.asp
[2]https://blog . minitab . com/blog/adventures-in-statistics-2/how-to-correct-interpret-p-values
[3]https://amstat . tandfonline . com/doi/full/10.1080/00031305 . 2016 . 1154108 # . xhx 1 tedkhpa
使用 BigQuery 和 SQL UDF 将多个列拆分成整齐的对
原文:https://towardsdatascience.com/how-to-unpivot-multiple-columns-into-tidy-pairs-with-sql-and-bigquery-d9d0e74ce675?source=collection_archive---------18-----------------------
这篇文章是写给任何在 CSV 中处理时间序列的人的,每天都有一个新的专栏。拥有整洁的数据很重要!尤其是现在,一些公共数据的提供者选择了每天一列——这使得用 SQL 分析时间序列变得非常困难。在这篇文章中,可以找到一个共享的持久化 BigQuery UDF,它可以将数百个列转换成整齐的(日期,值)对,供您使用。
重要更新 : 我在 2020 年离开了谷歌,加入了雪花——所以我无法保持更新我的旧帖子。如果你想尝尝雪花啤酒,加入我们吧——我在❄️.玩得很开心
作为非整齐数据的一个例子,我们可以看到新型冠状病毒(新冠肺炎)案例(由 JHU·CSSE 提供)和苹果移动趋势报告表格的外观:
JHU CSSE 表格,苹果移动趋势报告表格:每个日期一列。我们不想那样。
我们不希望多列,每个日期。我们希望有(日期,值)对。因为这个问题似乎很常见,所以我编写了两个 BigQuery 持久性 UDF 来解决这个问题:
fhoffa.x.unpivot()
fhoffa.x.cast_kv_array_to_date_float()
让我们回顾一下它们是如何工作的。
使用 fhoffa.x.Unpivot()进行 unpivot
只需给unpivot()
一个完整的行,以及每个列的名称如何显示的正则表达式。
苹果桌子:
SELECT a.geo_type, region, transportation_type, unpivotted
FROM `fh-bigquery.public_dump.applemobilitytrends_20200414` a
, UNNEST(fhoffa.x.unpivot(a, '_2020')) unpivotted
颠覆苹果移动趋势
与 JHU 表:
SELECT province_state, country_region, unpivotted
FROM `bigquery-public-data.covid19_jhu_csse.confirmed_cases` a
, UNNEST(fhoffa.x.unpivot(a, '_[0-9]')) unpivotted
取消旋转 JHU 表
这就好多了,但我们还没完。我们如何将这些值转换成日期和数字?
用 cast_kv_array_to_date_float()转换数组
我们可以使用cast_kv_array_to_date_float()
重新转换未透视的列。
当将这些列转换为日期时,更“令人恼火”的是它们使用不同的格式对日期进行编码。您不必担心,因为 UDF 也可以将日期格式作为输入。
例如,苹果的桌子:
SELECT a.geo_type, region, transportation_type, unpivotted.*
FROM `fh-bigquery.public_dump.applemobilitytrends_20200414` a
, UNNEST(fhoffa.x.cast_kv_array_to_date_float(fhoffa.x.unpivot(a, '_2020'), '_%Y_%m_%d')) unpivotted
颠覆和铸造苹果移动趋势
还有 JHU 的桌子:
SELECT province_state, country_region, unpivotted.*
FROM `bigquery-public-data.covid19_jhu_csse.confirmed_cases` a
, UNNEST(fhoffa.x.cast_kv_array_to_date_float(fhoffa.x.unpivot(a, '_[0-9]'), '_%m_%d_%y')) unpivotted
拆除和铸造 JHU 表
看到了吗?这些结果看起来比开始的表格更整洁。
奖励:covid 19 _ USA facts . confirmed _ cases 表
一旦我们有了这两个 UDF,将它们应用到其他表就变得非常容易了:
SELECT county_fips_code, county_name, state, state_fips_code, unpivotted.*
FROM `bigquery-public-data.covid19_usafacts.confirmed_cases` a
, UNNEST(fhoffa.x.cast_kv_array_to_date_float(fhoffa.x.unpivot(a, '_[0-9]'), '_%m_%d_%y')) unpivotted
取消“covid 19 _ USA facts . confirmed _ cases”表的透视
操作方法
查看我之前关于 BigQuery 中持久 UDF 的帖子:
[## BigQuery 中的新特性:持久性 UDF
用户定义的函数是扩展 BigQuery 的一种强有力的方法,但直到现在,它一直是一个必须复制粘贴的累赘…
medium.com](https://medium.com/@hoffa/new-in-bigquery-persistent-udfs-c9ea4100fd83)
这两个 UDF 的源代码是:
CREATE OR REPLACE FUNCTION fhoffa.x.unpivot(x ANY TYPE, col_regex STRING)
AS ((
# [https://medium.com/@hoffa/how-to-unpivot-multiple-columns-into-tidy-pairs-with-sql-and-bigquery-d9d0e74ce675](https://medium.com/@hoffa/how-to-unpivot-multiple-columns-into-tidy-pairs-with-sql-and-bigquery-d9d0e74ce675)
SELECT
ARRAY_AGG(STRUCT(
REGEXP_EXTRACT(y, '[^"]*') AS key
, REGEXP_EXTRACT(y, r':([^"]*)\"?[,}\]]') AS value
))
FROM UNNEST((
SELECT REGEXP_EXTRACT_ALL(json,col_regex||r'[^:]+:\"?[^"]+\"?') arr
FROM (SELECT TO_JSON_STRING(x) json))) y
));CREATE OR REPLACE FUNCTION fhoffa.x.cast_kv_array_to_date_float(arr ANY TYPE, date_format STRING)
AS ((
# [https://medium.com/@hoffa/how-to-unpivot-multiple-columns-into-tidy-pairs-with-sql-and-bigquery-d9d0e74ce675](https://medium.com/@hoffa/how-to-unpivot-multiple-columns-into-tidy-pairs-with-sql-and-bigquery-d9d0e74ce675)
SELECT ARRAY_AGG(STRUCT(SAFE.PARSE_DATE(date_format, key) AS date, SAFE_CAST(value AS FLOAT64) AS value))
FROM UNNEST(arr)
));
这个函数背后的秘密引擎:用TO_JSON_STRING()
将一整行转换成 JSON,然后对它执行一个REGEXP_EXTRACT_ALL
。
历史笔记
我的以前的解决方案在 BigQuery 中的 UNPIVOT 已经收到了超过 5000 个关于堆栈溢出的视图:
[## 如何在 BigQuery 中取消透视?
stackoverflow.com](https://stackoverflow.com/a/27832362/132438)
后续步骤
一旦我为这些函数编写了文档,并且我们确定了它们的最终名称——我将把它们提交给我们与社区 UDF([bqutil](https://github.com/GoogleCloudPlatform/bigquery-utils/tree/master/udfs/community)
)共享的存储库。
[## Google cloud platform/big query-utils
该目录包含社区贡献的用户定义函数,以扩展 BigQuery 用于更专门的用途…
github.com](https://github.com/GoogleCloudPlatform/bigquery-utils/tree/master/udfs/community)
想要更多吗?
查看谷歌的公共数据集项目,在 BigQuery 中收集了越来越多的新冠肺炎相关数据集:
[## 新冠肺炎免费公共数据集|谷歌云博客
数据在调查、研究和应对突发公共卫生事件的能力中始终发挥着至关重要的作用
cloud.google.com](https://cloud.google.com/blog/products/data-analytics/free-public-datasets-for-covid19)
我是 Felipe Hoffa,谷歌云的开发者倡导者。在 @felipehoffa 上关注我,在medium.com/@hoffa上找到我以前的帖子,在reddit.com/r/bigquery上找到所有关于 BigQuery 的帖子。
如何更新你的 Django 网站
原文:https://towardsdatascience.com/how-to-update-your-live-django-website-b84645753ea1?source=collection_archive---------19-----------------------
数字海洋的逐步指南以及 AWS EB、Heroku 和 Azure 的链接
我的 Django-数字海洋网络应用。图片作者。
我最近用 Django 开发了一个网络应用程序(见此)并通过 DigitalOcean 部署了它。
使用 DigitalOcean 有很多绝妙的理由,但更新不是其中之一。因为它是云托管提供商,而不是像 AWS Elastic Beanstalk 一样的 PaaS,更新过程 100%是你的问题。
此外,如果您也部署了 DigitalOcean,您可能会意识到关于如何运行更新的资源非常少。这就是我进来的地方。
我已经在我如何建立我的网站的详细演练中写了这个过程(如果你愿意,你可以在下面阅读),但我想详细说明这一点,以帮助填补像我这样的初学者的知识空白。
[## 37 天内从零到全栈 web 开发
以及如何更快地完成它
towardsdatascience.com](/from-zero-to-full-stack-web-development-in-37-days-97b8c254a3d1)
如果你部署在数字海洋之外的地方,更新会容易得多,这里有一些可能与你相关的页面:
- AWS 弹性豆茎(控制台 / 命令行界面)
- Heroku
- 微软 Azure
如何更新您现有的网站/应用程序
步骤 1: If Django: 为本地调试配置您的 Django 设置。您需要这样做来在您的本地主机上运行您正在进行的工作。
# in settings.py
DEBUG = True
ALLOWED_HOSTS = []
如果您在设置文件中使用自定义变量在“实时”和“本地”模式之间切换,尤其是当您的数据库也发生变化时(例如,如果您使用 PostgreSQL),您可以使这变得稍微容易一些。
在这个例子中,当我想要编辑或部署时,我所做的就是切换 live_deploy 变量。
步骤 2: 更新项目代码。
第三步:如果姜戈:进行迁移。在本地进行迁移,但在服务器上进行迁移,因为迁移文件是源代码的一部分,不应该在服务器上被篡改。阅读这篇 StackOverflow 帖子了解更多信息。
# in terminal
python3 manage.py makemigrations
第 4 步:如果 Django: 重新配置您的设置以进行实时部署。
# in settings.py
DEBUG = False
ALLOWED_HOSTS = ['00.000.0.000','www.yourdomain.com'] # insert your IP or domain
第五步:准备好你的修改,提交到 Git,然后推送到你选择的远程存储库。非常重要,因为在数字海洋(步骤 8)中,遥控器是您获取代码的地方。
# in terminal
git commit -m "your commit message"
git push origin master
第六步:使用 SSH 登录您的数字海洋虚拟机。
# in terminal
ssh user@00.000.0.000
步骤 7: 激活您的项目所使用的虚拟环境,因为您需要运行 Django 命令。
# in terminal
source venv/bin/activate #replace with your venv
步骤 8: 从您的项目目录中,从您的远程存储库中提取您的更新代码。
# in terminal
cd /your/project/dir
git pull origin
步骤 9:如果 Django: 运行迁移并收集静态。不进行迁移 —参考步骤 3。
# in terminal
python3 manage.py migrate
python3 manage.py collectstatic
步骤 10: 重启 Gunicorn(您的 WSGI 服务器)以应用更改。通常情况下,您不需要重启 NGINX,因为不会对 web 服务器进行任何更改——我唯一一次重启是在更新 SSL 证书的时候。
# in terminal
sudo service gunicorn restart
sudo service nginx restart #only if you need to
看起来有点冗长,但重要的是坚持所有的步骤,以确保您的新代码正确配置用于实时部署,使其进入虚拟机,并显示在您的网站或应用程序中。
如果你想自动更新,你可以用 Fabric 和 Ansible 来实现。你可以在这里找到一个相当完整的指南,所以我就不详述了。
但是,如果你像我一样刚刚开始,你可能不需要频繁更新,而是喜欢尽可能保持简单。
在这种情况下,这 10 个步骤将是您每次可靠地运行更新所需要的全部。
如何向 Google BigQuery 上传数据
原文:https://towardsdatascience.com/how-to-upload-data-to-google-bigquery-989dc7b92583?source=collection_archive---------15-----------------------
在本文中,我们考虑将数据上传到 Google BigQuery 云存储的选项。我们考虑从 CSV/JSON 文件加载数据的简单方法,以及通过 API 或插件上传数据的方法。
Google BigQuery (GBQ)允许您从不同来源收集数据,并使用 SQL 查询进行分析。GBQ 的优势之一是计算速度快(即使数据量很大)和成本低。
为什么需要将数据加载到一个存储中?如果你想使用端到端的分析,使用原始数据来创建报告,并衡量你的营销效率,那么你应该使用谷歌大查询。
如果你需要在几秒钟内分析万亿字节的数据,Google BigQuery 是最简单、最实惠的选择。你可以通过观看 Google Developers YouTube 频道上的短片来了解这项服务的更多信息。
创建数据集和表
在上传任何数据之前,您需要在 Google BigQuery 中创建一个数据集和表。为此,在的 BigQuery 主页上,选择要在其中创建数据集的资源。
图片由作者提供
在“创建数据集”窗口中,为数据集指定一个 ID,选择一个数据位置,并设置默认的表有效期。
注意:如果您为表过期选择“永不”,将不会定义物理存储位置。对于临时表,您可以指定存储它们的天数。
图片由作者提供
接下来,在数据集中创建一个表。
图片由作者提供
准备好了!现在可以开始加载数据了。
使用 Google Sheets 上传数据(OWOX BI BigQuery Reports 插件)
如果您需要将数据从 Google Sheets 上传到 Google BigQuery,最简单的方法是安装免费的 OWOX BI BigQuery Reports 插件。
你可以直接从 Google Sheets 或者从 Chrome 网上商店安装这个插件。
图片由作者提供
安装后,会出现一个提示和权限请求的对话框。
图片由作者提供
现在是时候回到谷歌床单了。要将数据上传到 BigQuery,只需从 Add-ons –> OWOX BI big query Reports 菜单中选择 upload data to BigQuery。
图片由作者提供
指定要将数据上载到的项目、数据集和表的名称。仅此而已:)
OWOX BI BigQuery Reports 插件的一个不可否认的优势是它的易用性。您还可以使用该插件来设置计划报告。
要基于来自所有来源的准确原始数据构建报告,并自动将它们上传到 Google BigQuery 存储库,我们建议使用 OWOX BI Pipeline 服务。
借助 Pipeline,您可以从广告服务以及呼叫跟踪和 CRM 系统中设置自动数据收集。这使您能够快速、轻松地从您选择的源中获得现成的完整数据集。
图片由作者提供
只需选择数据源并授予访问权限;剩下的交给奥克斯毕。
有了 OWOX BI,您可以为每一种口味和需求构建报告,从投资回报、ROPO 效应和群组分析到 LTV 和 RFM 分析。
从 CSV 文件上传数据
要从 CSV 文件上传数据,请在“创建表”窗口中选择数据源并使用上传选项。
图片由作者提供
然后选择文件和文件格式。
图片由作者提供
接下来,定义数据的目的地,指定项目和数据集的名称。
注意:在 Google BigQuery 中,您可以选择两种类型的表:本地表和外部表。
图片由作者提供
Google BigQuery 将自动确定表结构,但是如果您想要手动添加字段,您可以使用文本修订功能或+ Add field 按钮。
注意:如果你想改变 Google BigQuery 从 CSV 文件中解析数据的方式,你可以使用高级选项。
图片由作者提供
有关 CSV 格式的更多信息,请参见互联网协会的详细文档。
从 JSON 文件上传数据
要从 JSON 文件上传数据,请重复所有步骤创建或选择您正在使用的数据集和表-仅选择 JSON 作为文件格式。
您可以从您的电脑、Google 云存储或 Google Drive disk 上传 JSON 文件。
图片由作者提供
注意:关于 JSON 格式的更多信息,请参见 Google Cloud 文档。
从谷歌云存储上传数据
谷歌云存储允许你安全地在线存储和传输数据。
关于使用此服务的有用信息:
- 谷歌云存储入门
- 云存储文档
- 快速入门
- 在谷歌云平台上选择您的存储和数据库
您可以将以下格式的文件从 Google 云存储上传到 Google BigQuery:
- 战斗支援车
- JSON(换行符分隔)
- Avro
- 镶木地板
- 妖魔
- 云数据存储
图片由作者提供
您可以在官方文档中了解更多关于使用云存储和大数据的信息。
你也可以在谷歌云帮助中心了解数据下载限制和云存储权限。
从谷歌广告和谷歌广告管理器等其他谷歌服务上传数据
要从各种 Google 服务上传数据,首先需要配置 BigQuery 数据传输服务。在您可以使用它之前,您必须选择或创建一个数据项目,并且在大多数情况下,为它启用计费。例如,对于以下服务,计费是强制性的:
- 活动经理
- 谷歌广告经理
- 谷歌广告
- Google Play(测试版)
- YouTube —频道报道
- YouTube —内容所有者报告
注意:在谷歌云帮助中心阅读更多关于计费设置和变更的信息。
要启动 BigQuery 数据传输服务,在 BigQuery h ome 页面上,从左侧菜单中选择 Transfers。
图片由作者提供
注意:您将需要管理员访问权限来创建传输。
在下一个窗口中,您所要做的就是选择您想要的数据源。
图片由作者提供
注意:BigQuery 数据传输服务不仅可以从平台控制台访问,还可以从以下位置访问:
- с经典 bq_ui
- bq 命令行工具
- BigQuery 数据传输服务 API
配置完成后,该服务将自动定期向 BigQuery 上传数据。但是,您不能使用它从 BigQuery 下载数据。
使用 API 下载数据
通过云客户端库,您可以使用自己喜欢的编程语言来使用 Google BigQuery API。
注意:您可以在 Google Cloud 文档中找到更多关于使用 API 下载数据的详细信息。
首先,您需要创建或选择您将使用的项目。然后在主页上,转到 API 部分。
图片由作者提供
在“API 概述”窗口中,您可以启用 API 和服务,并从库中选择 API。
图片由作者提供
在库中,您可以使用字段搜索或按类别过滤 API。
图片由作者提供
您可以使用 OWOX BI 中的一组 Python 脚本来自动将数据导入 Google BigQuery。
您可以从以下来源找到将数据自动导入 Google BigQuery 的脚本:
- amoCRM
- 文件传送协议
- FTPS
- HTTP(S)
- 对讲机
- 专家发送器
- 关系型数据库
- science for the people 为人类服务的科学
你可以从 GitHub 下载这些 Python 脚本。
注意:在谷歌开发者 YouTube 频道的这个视频课程中,学习如何在使用谷歌 API 的同时使用 Python。
关键要点
在我们的文章中,我们考虑了向 Google BigQuery 上传数据的最流行的方式。从简单地加载数据文件到通过 API 加载数据,任何用户都可以找到合适的选项。
如何从 Google Ads 上传原始数据到 Google BigQuery
原文:https://towardsdatascience.com/how-to-upload-raw-data-from-google-ads-to-google-bigquery-4bf0f2565f18?source=collection_archive---------39-----------------------
来源:沉积照片
如何将原始数据从你的谷歌广告账户上传到谷歌大查询,并识别自动标记广告活动的所有 UTM 标签
通过在 Google Analytics 中分析 Google Ads 广告活动的有效性,您可能会遇到采样、数据聚合或其他系统界面限制。幸运的是,这个问题很容易解决,只需将广告服务的原始数据上传到 Google BigQuery 即可。
为什么你需要谷歌广告的原始数据
来自谷歌广告的原始数据将允许你精确到每个关键词来分析广告活动。通过将数据上传到 BigQuery,您可以:
- 构建您想要的详细报告,不受 GA 限制。
- 在会话和用户层面确定广告活动的效果。
- 按地区、用户类型(新用户或老客户)、设备和任何其他参数计算 ROI、ROAS 和 CRR。
- 有效管理您的价格,并创建再销售清单。
- 结合来自 Google Ads、Google Analytics 和 CRM 的数据,根据您的商品的利润和可赎回性来评估活动的有效性。
- 训练你的 ML 模型以获得更精确的计划。
要了解哪些活动、广告和关键词将用户带到您的网站,您需要将来自 Google 广告和分析的数据结合到 BigQuery 中。您可以使用 OWOX BI 流来实现这一点。
流式传输这些信息会将您网站上未采样的用户行为数据发送到 GBQ。实时传输点击,然后基于这些点击形成会话。
OWOX BI 流量来源信息取自 UTM tags 广告标记。标签为手动,而为自动。
假设您手动标记了广告,并获得了以下 URL:
https://example.com/?utm_source=facebook&UTM _ medium = CPC&UTM _ campaign = UTM _ tags
在这种情况下,连接 OWOX BI 后,您将在 GBQ 表中获得来源、渠道和活动数据:
- trafficSource.source —谷歌
- trafficSource.medium — cpc
- traffic source . campaign-UTM _ tags
如果您在广告服务中启用了自动标记,则会为您的每个广告分配一个特殊的 gclid 参数。当用户点击公告时,它被添加到登录页面 URL。
这种链接示例:
http://www.example.com/?gclid=TeSter-123
如果使用自动标记,没有原始数据就无法从 gclid 获得 source、medium 或 campaign 这些字段在 OWOX BI 收集的 BigQuery 表中将为空。
在这种情况下,如果只有 gclid,您能做什么?如何获得活动名称和其他参数?配置从 Google Ads 到 GBQ 的自动上传。
注意:如果公告根本没有标记,OWOX BI 将分配链接如下:
- 对于非 Google 来源,作为推荐流量(例如 facebook/referral)
- 对于 Google source 作为直接流量(直接/无)
如果您的报告中有大量直接/无流量,您可能没有启用僵尸过滤,或者您可能有大量未标记的广告。
从 Google Ads 上传原始数据到 BigQuery 的两种方法
我们使用并推荐两种方法从 Google Ads 上传原始数据:数据传输连接器和 Ads 脚本。
选择哪种方式取决于你的目标和预算。为了让您更容易做出决定,我们准备了一份对照表:
你需要什么设置
以下位置的活动项目和客户:
- 谷歌云平台(GCP)
- 谷歌大查询
- OWOX BI
- 谷歌广告
访问:
- GCP 的所有者
- GBQ 中的管理员
- 在 OWOX BI 中编辑。重要提示:只有创建了 Google Analytics→Google big query streaming pipeline 的用户才能打开从 Google Ads 下载。
- 在谷歌广告中阅读
如何在 GBQ 中授予访问权限
打开 GCP 控制台,从侧面菜单中选择 IAM 和 admin —管理资源。然后选择项目并单击添加成员。输入用户的电子邮件,选择 BigQuery 管理员角色,并保存您的更改。
图片由作者提供
如何使用数据传输配置上传
第一步。在谷歌云平台中创建一个项目
如果你在 GCP 已经有一个项目,跳过这一步。如果没有,打开 GCP 控制台并从侧面菜单中选择 IAM 和 admin —管理资源。单击创建项目按钮。然后输入项目名称,指定组织,并单击创建:
图片由作者提供
确保启用计费。为此,请打开侧面菜单中的“计费-账户管理”选项卡,选择项目,并链接计费账户:
图片由作者提供
接下来,通过输入您的联系人和支付卡详细信息来完成所有字段。如果这是你在 GCP 的第一个项目,你会得到 300 美元,可以用 12 个月。每月有 1-2 个谷歌广告账户和多达 100,000 个独立用户的项目将足够用一年。当你用完这个额度,就不需要还钱了。为了进一步使用,您只需将余额充值到与项目关联的卡上。
第二步。打开 API BigQuery
创建项目后,必须激活 BigQuery API。为此,请从 GCP 侧菜单转到“API 和服务—仪表板”,选择项目,然后单击“启用 API 和服务”:
图片由作者提供
在 API 库中,搜索“BigQuery API”并单击启用:
图片由作者提供
要使用 API,请单击创建凭据:
图片由作者提供
从下拉列表中选择 BigQuery API,然后单击我需要什么凭据?
图片由作者提供
创建服务帐户的名称,并指定 BigQuery 角色访问级别。选择 JSON 密钥的类型,然后单击继续:
图片由作者提供
第三步。激活数据传输 API
接下来,您需要激活 BigQuery 中的数据服务。为此,打开 GBQ 并从左侧菜单中选择传输。然后启用 BigQuery 数据传输 API:
图片由作者提供
第四步。准备 GBQ 中的数据集
在 BigQuery 中,选择项目并单击右侧的 Create Dataset 按钮。完成新数据集的所有必填字段(名称、位置、保留期):
图片由作者提供
第五步。从 Google Ads 设置数据传输
单击侧面菜单上的“转移”选项卡,然后单击“创建转移”。然后选择 Google Ads(以前的 AdWords)作为来源,并输入上传的名称,例如 Data Transfer。
在“时间表选项”下,您可以保留默认设置“立即开始”,或者设置您想要开始下载的日期和时间。在重复字段中,选择上传频率:每天、每周、每月按需等。
图片由作者提供
然后,您必须指定 GBQ 数据集,以便从 Google Ads 加载报告。输入客户 ID(这是您的 Google Ads 帐户的 ID 或 MCC ID ),然后单击添加。你可以在谷歌广告账户的右上角查看客户 ID,就在你的邮箱旁边。
图片由作者提供
然后,您需要授权您正在使用的 Gmail 帐户。第二天,该信息将出现在您设置转移时指定的数据集中。
因此,您将在 GBQ 中收到大量原始数据,您可以使用这些数据:按活动、受众、常用(自定义)表格、关键字和转换的表格。例如,如果您想要构建一个定制的仪表板,您可以从这些表中提取非聚合数据。
如何使用 Ads 脚本设置上传
打开您的 Google Ads 帐户,单击右上角的工具和设置,选择批量操作—脚本,然后单击加号:
图片由作者提供
然后,在右上角,单击高级 API 按钮,选择 BigQuery,并保存您的更改:
图片由作者提供
请务必使用您登录 Google Ads 时使用的帐户进行注册:
图片由作者提供
复制这个剧本。在 BIGQUERY_PROJECT_ID、BIGQUERY_DATASET_ID 和您的电子邮件行中,用您自己的信息替换这些值:项目名称、GBQ 数据集和电子邮件。将脚本文本粘贴到文本编辑器中。
在运行脚本之前,一定要单击右下角的预览按钮来检查结果。如果其中有错误,系统会警告您并指出错误发生在哪一行,如下图所示:
图片由作者提供
如果没有错误,请单击运行按钮:
图片由作者提供
因此,您将在 GBQ 中收到一份新的 CLICK_PERFORMANCE_REPORT 报告,该报告将于第二天提供:
图片由作者提供
回想一下,当您使用数据传输时,您会得到大量原始的非聚合数据。与广告脚本,你只会有关于某些领域的信息。
本次上传的以下字段包含在与会话相关的 OWOX BI 表中:
- GclId
- CampaignId
- 活动名称
- AdGroupId
- AdGroupName
- 标准 Id
- 标准参数
- 关键字匹配类型
如何将从 Google Ads 下载的数据连接到 OWOX BI
现在,你需要将谷歌广告的信息与网站数据结合起来,以了解用户通过哪些活动到达了你的网站。在 BigQuery 中得到的表,比如数据传输,没有客户机 ID 参数。您只能通过将 gclid 数据链接到 OWOX BI 流数据来确定哪个客户点击了广告。
如果你还没有 OWOX BI 中的 Google Analytics → Google BigQuery 流管道,请阅读关于如何创建它的说明。
然后转到您的 OWOX BI 项目,打开这个管道。单击设置选项卡,然后在会话数据收集下,单击编辑设置:
图片由作者提供
使用滑块为 Google Ads 自动标记的活动启用数据收集,然后单击更改设置:
图片由作者提供
选择自动标签标记类型,指定如何将数据传输或 Ads 脚本加载到 BigQuery。指定将从中下载 Google Ads 数据的项目和数据集,并保存您的设置:
图片由作者提供
有用的提示
提示 1。通过数据传输,您可以将 Google Ads 中的历史数据上传到 GBQ。同时,对加载的总周期没有限制(一年或三年),但每次只加载 180 天的数据。
您可以通过选择所需的传输,使用“传输”选项卡上的“计划回填”按钮来激活上传并指定时间段:
图片由作者提供
技巧二。如果您想检查 GCP 将收费的 Google Ads 帐户的数量,您需要使用以下查询来确定 Customer 表中 ExternalCustomerID 的数量:
**SELECT**
ExternalCustomerId
**FROM** `project_name.dataset_name.Customer_*`
**WHERE** _PARTITIONTIME >= "2020-01-01 00:00:00" **AND** _PARTITIONTIME < "2020-07-10 00:00:00"
**group** **by** 1
您可以在查询中编辑日期。
技巧三。您可以使用 SQL 查询自己访问上传的数据。例如,下面是一个查询,用于从数据传输派生的“Campaign”和“CampaignBasicStats”表中确定活动的有效性:
**SELECT**
{**source** **language**="sql"}
c.ExternalCustomerId,
c.CampaignName,
c.CampaignStatus,
**SUM**(cs.Impressions) **AS** Impressions,
**SUM**(cs.Interactions) **AS** Interactions,
{/**source**}
(**SUM**(cs.Cost) / 1000000) **AS** **Cost**
**FROM**
`[DATASET].Campaign_[CUSTOMER_ID]` c
**LEFT** **JOIN**
{**source** **language**="sql"}
{**source** **language**="sql"}
`[DATASET].CampaignBasicStats_[CUSTOMER_ID]` cs
**ON**
(c.CampaignId = cs.CampaignId
**AND** cs._DATA_DATE **BETWEEN**
**DATE_ADD**(**CURRENT_DATE**(), INTERVAL -31 **DAY**) **AND** **DATE_ADD**(**CURRENT_DATE**(), INTERVAL -1 **DAY**))
**WHERE**
c._DATA_DATE = c._LATEST_DATE
**GROUP** **BY**
1, 2, 3
**ORDER** **BY**
Impressions **DESC**
页(page 的缩写)如果你需要帮助上传和合并数据到谷歌大查询,我们随时准备提供帮助。
如何在 GitHub 上上传 R 代码:MacOS 上的 R 脚本示例
原文:https://towardsdatascience.com/how-to-upload-your-r-code-on-github-example-with-an-r-script-on-macos-3205d8d0d60?source=collection_archive---------50-----------------------
查看如何创建 GitHub 资源库以及如何使用 GitHub desktop 上传 R 代码和脚本的分步指南(带截图)
介绍
前几天,一个同事问我如何在 GitHub 上上传一些 R 代码,以便让每个人都可以访问。由于封锁,我不能直接去他的办公室,在他的电脑上给他看。所以我给他发了几张截图,一步一步地告诉他怎么做。
就在我删除刚刚拍摄的截图之前,我想它们可能对其他人有用,所以我写了这篇文章。
注 1:截图是在 MacOS 上拍摄的,我没有在 Windows 上测试过。请在评论中告诉我它在其他操作系统上是否相似。
注 2:肯定还有其他方法,但下面的方法(在我看来)很简单,而且效果很好。
先决条件
为了遵循这个指南并在 GitHub 上上传您的 R 代码,您至少需要:
- GitHub 的一个账户
- 安装在您电脑上的 GitHub 桌面应用程序
逐步指南
在本指南中,我使用了一个 R 脚本来绘制比利时因新冠肺炎而住院的演变。如果您想在继续下一步之前看到最终结果,请查看 GitHub 上的库。
你经常听到
“一图胜千言”
下面是如何将你的 R 脚本上传到 GitHub 上的简单方法:
第一步:去 github.com/login 并登录
步骤 2:转到您的 GitHub 概要文件并创建一个新的存储库
步骤 3:设置新存储库的名称、描述、受众和自述文件
请注意,如果您选择将公开,它将对所有人可见。如果您不想共享代码,但仍然希望它被上传到 GitHub,请选择 private 选项。
用 README 文件初始化 repo 不是强制性的,但是我强烈建议您这样做,以便您能够为这个 repo 添加信息。
步骤 4:现在您会看到新的存储库,其中只有自述文件
第五步:打开 GitHub 桌面应用程序,用你的 GitHub 账户登录
步骤 6 a:将您刚刚在 github.com 上创建的存储库克隆到您的计算机上
步骤 6 b:将您刚刚在 github.com 上创建的存储库克隆到您的计算机上
步骤 6 c:将您刚刚在 github.com 上创建的存储库克隆到您的计算机上
步骤 7:您的新回购出现在 GitHub 桌面应用程序上
步骤 8:打开一个 R 脚本并编写代码
(如果不熟悉,请参见如何安装 R 和 RStudio 。)
步骤 9 a:将你的 R 脚本保存在相应的文件夹中
您可以在步骤 6 c 中的“本地路径”下看到文件夹的路径。
步骤 9 b:将你的 R 脚本保存在相应的文件夹中
步骤 10:重新打开 GitHub 桌面,编辑提交标题(1)并点击提交按钮(2)
在步骤 10 中,确保当前存储库(见左上角)是您当前正在处理的 repo。
步骤 11:将提交推给 github.com
第 12 步:在你的 GitHub 概要文件中,点击新创建的存储库
步骤 13:您现在看到您的脚本已经被添加到存储库中
您的 R 代码现在可以通过您的 GitHub 档案上的新存储库在线获得。如果需要分享,只需分享回购的网址即可。
附加注释
如果您需要编辑代码:
在您的计算机上找到 repo 的文件夹,打开 R 脚本,编辑并保存它
保存脚本后,不要忘记提交更改,并按下 commit (参见上面的步骤 10)。
如果您需要查看旧版本的代码,您可以通过点击 github.com 上的 repo 访问 commits 选项卡来查看所有提交:
查看所有提交
感谢阅读。我希望这篇文章能帮助你创建一个 GitHub 库,并上传你的 R 脚本,以便任何人都可以使用。
和往常一样,如果您有与本文主题相关的问题或建议,请将其添加为评论,以便其他读者可以从讨论中受益。
相关文章
- 一次比例和拟合优度检验(R 和手工)
- 如何创建一个针对您所在国家的简单冠状病毒仪表板
- 如何手动执行单样本 t 检验,并对一个平均值进行 R:检验
- 每个数据科学家都应该知道的概率中的 9 个概念和公式
- R markdown 入门
原载于 2020 年 5 月 24 日 https://statsandr.com。
如何使用预训练模型(VGG)进行图像分类
原文:https://towardsdatascience.com/how-to-use-a-pre-trained-model-vgg-for-image-classification-8dd7c4a4a517?source=collection_archive---------7-----------------------
为什么要重新发明轮子?
图片来源:https://unsplash.com/photos/LJ9KY8pIH3E
嗨,伙计们,今天我要谈谈如何使用 VGG 模型作为预训练模型。让我们一小步一小步来
这些 VGG 模型是什么?
- VGG 模型是由牛津大学视觉几何小组(VGG)的卡伦·西蒙扬和安德鲁·齐泽曼提出的一种 CNN 架构,它为 ImageNet 挑战赛带来了显著的成绩。
- 他们试验了 6 个模型,有不同数量的可训练层。根据型号数量,最受欢迎的两种型号是 VGG16 和 VGG19。
在我们继续之前,我们应该回答什么是 CNN 架构以及 ImageNet。
对于感兴趣的读者,可以参考下表来了解作者实验的所有 ConvNet 系列。
图 1:不同的 ConvNet 架构(图片来源:Simonyan、Karen 和 Andrew Zisserman。“用于大规模图像识别的非常深的卷积网络。” arXiv 预印本 arXiv:1409.1556 (2014)。)
这是什么 CNN 架构?
CNN 是一个专门处理图像数据的深度神经网络模型。
- 它不需要传统的图像处理滤波器,如边缘、直方图、纹理等。,而不是在美国有线电视新闻网,过滤器是可以学习的。所以,这些不需要通过反复试验来确定。
- CNN 有两个部分,第一部分是特征学习部分,然后是分类层(通常称为全连接层)
- 特征学习部分的两个主要构建块是卷积层和池层
- 卷积层:我们讨论过的可学习过滤器或特征提取器。
- 池层:这做了一些空间压缩,也带来了不变性。一辆车就一辆车,哪怕旋转一点点。
图 2 给出了 CNN 的架构概述。卷积创建特征图,汇集是通过二次采样实现的。
如果你需要更详细的解释,你可以看这里的。
图 2: CNN 架构(来源:维基百科https://creativecommons.org/licenses/by-sa/4.0>;,via Wikimedia Commons " href = "https://commons.wikimedia.org/wiki/File:Typical_cnn.png">
预训练模型的原因和用途?
- 这些是模型,是具有大量参数的网络(一个恰当的例子是 VGG16,它具有 1.38 亿个参数)
- 一般来说,训练这样的网络是耗时且耗费资源的
- CV 的预训练模型大多也非常通用
- 我们可以直接使用这些模型,如果我们选择 1000 个训练类中的任何一个
- 即使有一点点不同,我们也可以去掉顶层,只训练那一层的权重(迁移学习)
这个 ImageNet 数据集是什么?
这是斯坦福大学教授费-李非从 2006 年开始与 wordnet 合作的一个项目。图像注释是众包的。这实际上使得计算机视觉任务的试验台变得非常健壮、庞大和昂贵。基于 ImageNet 的 1000 类分类挑战始于 ImageNet 大规模视觉识别挑战(ILSVRC)。
实际上,这种竞争是 CNN 大多数杰出模特诞生的原因。
ImageNet 与其他图像数据集(来源:林等。艾尔。https://www.dbs.ifi.lmu.de/~yu_k/cvpr11_0694.pdf
现在实施
**T5 第一步:导入模型 **
from keras.applications.vgg16 import VGG16
model = VGG16(weights='imagenet')
print(model.summary())
还有很多其他 CNN 的型号可供选择,可以在这里找到。
图 4: VGG 16 摩尔(图片来源:作者)
第二步:加载样本图像
from tensorflow.keras.preprocessing import image
from tensorflow.keras.applications.vgg16 import preprocess_input,decode_predictions
import numpy as np
img_path = '/kaggle/input/images/dog.jpg'
*#There is an interpolation method to match the source size with the target size*
*#image loaded in PIL (Python Imaging Library)*
img = image.load_img(img_path,color_mode='rgb', target_size=(224, 224))
display(img)
测试图像,我们使用的是黄金猎犬,也请注意图像是以 Python 图像库(PIL)格式加载的
测试图片: (图片来源:https://unsplash.com/photos/x5oPmHmY3kQ)
第三步:使图像尺寸与 VGG16 输入兼容
*# Converts a PIL Image to 3D Numy Array*
x = image.img_to_array(img)
x.shape
*# Adding the fouth dimension, for number of images*
x = np.expand_dims(x, axis=0)
这里,PIL 图像首先被转换成 3d 阵列,RGB 格式的图像是 3D 阵列。然后为多个图像添加另一维度。因此,输入实际上是一个 4D 数组。
第四步:做预测
*#mean centering with respect to Image*
x = preprocess_input(x)
features = model.predict(x)
p = decode_predictions(features)
在该步骤中,进行简单的均值居中预处理,然后进行预测,最后,将概率分布的预测解码为可理解的类名。我们已经在默认的前 5 名可能类模式中使用了它。
输出
[[('n02099601', 'golden_retriever', 0.8579672),
('n02099267', 'flat-coated_retriever', 0.018425034),
('n04409515', 'tennis_ball', 0.01615624),
('n02099712', 'Labrador_retriever', 0.015078514),
('n02099849', 'Chesapeake_Bay_retriever', 0.012522769)]]
如果我们使用条形图,这就是它的样子
图 5:最有可能的 5 类(图片来源:作者)
因此,无需创建模型并训练它,我们就可以完美地对一张金毛寻回犬的图像进行分类。
尾注:
- 预先训练的模型就像魔术一样,我们可以下载模型并开始使用它们,即使没有任何数据和训练。
- 如果源任务和目标任务是不同的,那么在域之间有一些相似性,那么我们可能必须训练几层,但是仍然,它不会像从头开始训练那样广泛,并且需要更少的数据
参考:
[1]https://www.kaggle.com/saptarsi/using-pre-trained-vgg-model
[2]西蒙扬、卡伦和安德鲁·齐泽曼。“用于大规模图像识别的非常深的卷积网络。” arXiv 预印本 arXiv:1409.1556 (2014)。
如何在希格斯玻色子上使用人工智能
原文:https://towardsdatascience.com/how-to-use-ai-on-the-higgs-boson-e97ef4fb2fb2?source=collection_archive---------25-----------------------
上帝粒子仍然充满秘密
安装部分 ATLAS 探测器。欧洲核子研究中心提供
P 文章欧洲粒子物理研究所的物理学家在 2012 年发现了希格斯玻色子。现在,我们的任务是了解更多关于它的特性。人工智能在其中扮演着至关重要的角色。
今天是星期天。你和我正在公园散步。我们的狗布鲁托在我们身边蹦蹦跳跳,渴望玩耍。你扔一根棍子让它接住。
然后你转向我。“你以前研究希格斯玻色子,对吗,”
没错。不过那是在它被发现的四年后。
如果它已经被发现了,还有什么可做的呢?
我们现在知道希格斯玻色子的存在。但是它的许多特性仍然未知。我和我的同事正在研究如何发现希格斯玻色子是否会在粒子对撞机中衰变为暗物质的策略。
“那么,比如说,希格斯玻色子破裂了,剩下的就是暗物质了?”
人工智能可以照亮希格斯玻色子的奥秘
理论上是这样,是的。我们不确定这是否真的会发生。但值得调查。这就是为什么我和我的同事考虑如何检测这些衰变——如果它们存在的话。我们发现人工智能是实现这一目标的最佳方式。
AI?“怎么做,”
为此,你首先需要了解我们在解决什么样的问题。
在欧洲粒子物理研究所,粒子探测器捕捉两个粒子以极高能量碰撞时发生的情况。每种类型的粒子——例如夸克或希格斯玻色子——都会在粒子探测器中留下特有的痕迹。“如果我们把这些痕迹放在一起,就可以重建两个粒子碰撞时发生的过程。”
CMS 探测器中产生希格斯玻色子的碰撞痕迹。欧洲核子研究中心提供
所以你用人工智能来找出哪些过程发生了?
没那么快!让我解释一下。
在一些碰撞中,会产生希格斯玻色子。但是希格斯玻色子的寿命相当短,所以它会很快衰变为其他粒子。这些可能是夸克或其他玻色子,或者可能是暗物质粒子。后者我们称之为信号事件——暗物质在产生的粒子中的碰撞。
当然,我们可以在探测器记录的许多过程中简单地搜索信号——我们正在谈论每秒发生的 5 亿次碰撞。
[## 数据处理:这么多碰撞!
考虑到大量的数据,粒子物理学家必须选择那些他们想为他们的研究存储信息的碰撞。
home.cern](https://home.cern/science/computing/processing-what-record)
问题是有些事件看起来和信号非常相似。但实际上它们是不同的过程。这些我们称之为背景事件。我们不希望这些扭曲我们的数据。所以我们的任务是教会探测器区分信号和背景。
“人工智能是如何发挥作用的?”
如果没有人工智能,我们只会查看信号的不同属性,然后在不太可能找到任何属性的地方剪切数据集。
例如,人们可以使用作为希格斯玻色子衰变为暗物质的副产品而释放出来的夸克数量。除了暗物质粒子之外,根据这个过程的基本物理性质,我们可能会想到两个夸克。有时候可能多一个夸克,有时候少一个。可能存在统计差异。
信号和背景事件及其各自的夸克数的示意图。如果只选择具有一个、两个或三个夸克的事件,就可以得到背景事件较少的数据集。作者图片
所以在这个例子中,我们可以从我们的数据集中去掉没有发现夸克或者多于三个夸克的碰撞。我们可以很有把握地说它们不是信号事件。通过这种方式,我们改进了数据集,因为它包含的背景比以前少了一些。
这就是人工智能的用武之地吗?
是的,没错。聪明的是,我们可以让人工智能算法学习信号事件的属性。“这让我们的工作变得容易多了,因为这意味着我们不一定需要了解太多的基础物理知识。”
“你在偷懒——不去研究基本的物理学!”
我称之为高效。
那好吧。人工智能如何学习什么是信号,什么是背景?
有很多不同的方法。在我们的例子中,我们使用了非常简单的算法,叫做决策树。基本原理是,你先用假数据集训练算法。该数据集来自计算机模拟,并且仅包含已经被正确标记为信号或背景的事件。
机器学习算法,如决策树,可以更快地提高数据集的质量。Javier Allegue Barros 在 Unsplash 上拍摄的照片
决策树对训练集应用随机切割,然后检查它将信号从背景中分离的程度。然后反复迭代,直到找到最佳切割。
但你为什么不能手动操作呢?
我们是手动完成的,但这需要大量关于底层流程的知识,否则会花费很长时间。此外,它很快变得复杂,因为信号的属性往往相互依赖。
例如,在一次信号碰撞中发射的两个夸克彼此之间可能有一定的距离。但是可能有其他信号事件涉及三个夸克。在这种情况下,三个夸克之间的距离可能不同于两个夸克之间的距离。所以我们不能只在夸克之间切割一段距离。决策树有助于考虑这种依赖性。
所以在某种程度上,机器知道的比你多!”
真的!这有助于我们揭示希格斯玻色子的特性。
[## 在看不见的希格斯搜索中标记喷流
我们关于这个主题的原创论文!如果你不是在这个领域工作的话,可能会很难读懂。
inspirehep.net](https://inspirehep.net/record/1642733?ln=en)
你又把棍子扔给布鲁托了。
这对你研究希格斯粒子有什么帮助?
有了人工智能,我们可以产生真正好的数据集,其中包含大量的信号和少量的背景事件。在我们的例子中,信号事件是希格斯玻色子衰变为暗物质之后的碰撞。
现在,我们需要做的就是计算我们发现的信号事件的数量。如果我们发现了一定的数量,我们就可以说我们发现了希格斯玻色子到暗物质粒子的衰变。
然后呢。“你发现了吗,”
没有。至少——还没有。我们的论文只是实现这一发现的众多步骤之一。“研究需要时间,”
希格斯玻色子的未来仍然令人兴奋
看看你是否会发现它,这将会很有趣!或者这些衰变是否根本不存在。
等着瞧吧!
我当然会…事实上,我认为人工智能真的很难理解。但现在看来这并不太疯狂。
公平地说,我们使用了现有的最简单的人工智能工具之一。如今,科学家经常使用更复杂的算法,包括监督深度学习和 GANs。但是如果你愿意的话,我们可以改天再谈。
“我很乐意!”当你试图把棍子从狗嘴里拔出来时,你惊叫了一声。“来吧,布鲁托,我们要回家了,”
如何使用人工智能来改善初级医疗保健的结果和效率
原文:https://towardsdatascience.com/how-to-use-ai-to-improve-outcomes-and-efficiency-in-primary-healthcare-77a46729670f?source=collection_archive---------37-----------------------
图像归属
只有 7%的信息是基于它所包含的单词。其余的 93%来自说话者的语调、肢体语言和面部表情 (1) 。
想象一下去看医生。你描述你的情况和症状,医生仔细观察和倾听。想象一下,这个咨询正在被录像。
该视频将包含您的发言(文本、单词),可以自动提取为文字记录并进行分析。您的声音及其相关特征,如音调、音量或震颤,也可以提取和分析。同样,你的动作包括面部表情,坐立不安,手势,姿势和物理距离都可以被分析。
让我们考虑可以单独分析的视频成分:
可以用主要症状提取来概括文本,然后可以将主要症状提取馈送到内部医学知识库(本体)模块,通过该模块可以提供诊断见解和相关建议。
您的声音及其特征,或声音生物标记(医学生物标记是从患者“外部”观察到的指示患者医学状态的医学标志)可用于探索特定疾病存在的可能性。在说明这一点的各种相关研究中,Beyond Verbal 和 Mayo Clinic 进行了一项双盲研究,涉及 120 名在冠状动脉疾病(CAD)背景下接受冠状动脉造影的患者和一组对照组,该研究使用移动应用程序在冠状动脉造影之前测量他们的语音信号。一个特别的声音特征(人耳听不到)表明冠心病的可能性增加了近 20 倍。
视频本身可以用来分析肢体语言和面部表情。例如,没有明确诊断帕金森病的特定测试。神经科医生根据病史、体征和症状回顾以及体检来临床诊断帕金森氏症。如果我们训练一个基于机器学习的人工智能系统,从大量帕金森患者视频访谈中学习身体运动、面部表情、震颤等,这可以用于潜在地诊断新记录(甚至直播)的患者咨询。例如,给定 10.000 个采访的训练和测试数据集,所能达到的准确度将是非常令人惊讶的。
智能数字医疗助理
使用文本、语音和视频对患者交互进行人工智能处理,以及医学知识、患者历史和自动化通信模块的知识库,是构成智能数字医疗助理的工具。最终,大多数临床医生和私人诊所将使用这项技术与他们的病人进行初步互动。
然而,重要的是,数字医疗助理永远不会取代有经验的医生。他们只会让一些医生比其他没有使用这项技术的医生更好!医生将有更多的时间与病人进行有意义的咨询。
不可避免的是,医疗保健的未来将涉及患者最初通过网络、移动或 IOT 界面与智能医疗数字助理联系,这些界面将自动分析患者的语音、声音和视频。除非得到妥善解决,否则提出的问题将自动转交给医疗专业人员进行进一步咨询。
总之,智能数字医疗助理将:
使用内部医学知识本体来回答问题(例如,它将存储我们所知道的关于喉咙痛的所有信息,以便回答相关问题)
使用机器学习和大数据来提供基于先前患者健康参数和结果的见解(即,给定患者 X 进行 Y 血液测试和潜在疾病 A,运行测试 Z 将是有用的,或者注意条件 B)
跟踪患者健康参数(波动、重复症状)
管理药物
提供简单可行的建议
提供个性化的健康建议和生活方式指导。
在紧急情况下,立即提供一线帮助
结论
人工智能(AI)将全面变革医疗保健。它可以改善结果和患者体验,同时实现医疗保健服务的大众化。
人工智能可以帮助改善医疗保健从业者的体验,使他们能够减少倦怠,花更多时间在严重的直接患者护理上。人工智能可以帮助医疗保健系统通过资源分配主动管理人口健康,以实现最大影响。
带走
使用基于移动或网络的智能数字医疗助理来提供基于远程视频的医疗咨询,并几乎即时地从视频中提取知识以支持或建议诊断,同时使用相同的系统来组织和跟进这些交互,这是使用人工智能技术来改善初级医疗保健的结果和效率的方式,尤其是在全球疫情中!
如果您想了解更多信息并站在医疗保健技术的最前沿,请加入权威的免费在线医疗保健社区 Footchat 。
(1)艾伯特·梅拉比安的权威性研究
关于作者
图片 1 & 2 归属
如何使用 Angular 部署 TensorFlow Web 应用程序
原文:https://towardsdatascience.com/how-to-use-angular-to-deploy-tensorflow-web-apps-5675b5a042cc?source=collection_archive---------13-----------------------
在角度构建的 web 应用程序中使用 Python 构建的模型
法比安·格罗斯在 Unsplash 上拍摄的照片
在机器学习和人工智能的新时代,Python 无疑是任何崭露头角的工程师的首选语言。干净、伪代码外观的语法——世界上最大的科学计算和机器学习社区已经为希望让他们的机器更智能的开发人员创造了完美的语言。
然而,向大众部署任何用 Python 构建的东西并不容易。构建任何人都可以使用的东西的最有效途径是 web 开发。
几乎每个有电脑的人都可以上网和浏览网页。即使是那些没有手机的人也可以通过手机上网。
使用 Python 进行 Web 开发是可能的。两个最大的框架是 Django 和 Flask——都很好,但是都比不上 JavaScript 可用的框架。
被全球 96%的网站使用[1] — JavaScript 在客户端 web 浏览器语言中占主导地位。自然,这就是 web 开发的空间。
幸运的是,像 Angular 和 Node 这样的框架使得构建 web 应用程序变得更加容易。只需很少的时间,我们就可以构建动态、交互式、快速的应用程序。
我们会建造这个。
在本文中,我们将采用 Python 内置的文本生成模型,并使用 Angular 将其集成到一个交互式 web 应用程序中。这里有很多细节,所以作为参考:
**1\. Our Model** - brief description of the model and download links**2\. Tensorflow.js** - conversion of model from Python to JS**3\. Getting Started With Angular** - installation and set-up**4\. Bootstrap** - how to implement Bootstrap CSS styles in Angular**5\. Model Component** - setting up the model component**6\. Loading Our Model** - how to load a model using TypeScript**7\. Making Predictions** - setup of prediction function in Typescript**8\. TextGenComponent** - implementation of all this code with the app
1.我们的模型
我们将保持这一部分很短,所以我们可以更多地集中在角接下来。
该模型是一个自然语言生成器。它使用字符级嵌入和一个非常标准的 LSTM 网络。
它是用 Python 构建和训练的,使用 TensorFlow 2。
训练数据包括马库斯·奥勒留的《沉思》和塞内卡的《致卢西留的道德书》——这两本书在斯多葛派哲学领域都是有影响力的文本。
这个模型产生的是一种特别雄辩的胡言乱语。
请记住,理性这个词的本意是表示分散,或者分解成原子,或者湮灭,它要么消失,要么改变。—艾·马库斯·奥勒留,大约 2020 年
在 Python 中,我们打开控制台,加载模型,并为模型输入一些内容。
接下来的一切都是模型产生的。
几个模型迭代产生的句子截图——这里我们对每个句子进行评分,并选择得分最高的文本。
我们希望重现这一功能,但在一个易于分发的 web 应用程序中实现。我当然不是设计师——但我们也会努力让它看起来很酷。
如果你确实想了解更多关于这个模型的信息,这里有GitHub repo,我已经在这些文章中描述了构建过程(第一篇应该足够了)。
构建需要时间,所以您可以从这里下载模型和映射,分别是model.h5
和char2idx.json
,。
2.TensorFlow.js
首先,我们需要将模型翻译成 JavaScript 可读的东西。
首先,pip install tensorflowjs
安装我们需要的模型编译器,将模型从h5
翻译到json
。
打开命令行并导航到包含modelname.json
的项目文件夹。在那里,我们可以键入以下内容:
tensorflow_js model_type="Keras"
modelname.h5
nlg_models/modelname.json
这产生了我们的JSON
格式的模型,我们稍后将把它加载到我们的 web 应用程序中。
3.Angular 入门
Angular 是一个很棒的 web 应用框架。它是轻量级的,结构良好,并且拥有大量的追随者。
要设置我们的环境,我们首先从这里 安装节点 。我们不会直接使用 Node,但它提供了我们在 Angular 中开发应用程序所需的几个功能。
安装完成后,我们可以使用节点包管理器(NPM)来安装包——就像使用 Python 的pip
一样。
我们需要的第一个工具是 Angular CLI(命令行界面),我们将使用它为应用程序的不同部分快速生成模板。我们打开自己的命令行并键入:
npm install -g @angular/cli
现在我们可以使用 Angular CLI 来创建一个项目。仍然在命令行中,首先导航到我们希望项目所在的位置。然后,对于一个名为nlg-project
的项目,我们将输入ng new nlg-project
——我们将被询问路由和样式表:
我们的新项目目录看起来应该与图中所示类似。我们可以用ng serve
为这个项目初始化一个本地服务器。
默认角度应用程序页面
我们的服务器将被托管在localhost:4200
——在我们的浏览器中输入这个会给我们默认的 Angular 应用页面。
我们将在应用程序中使用 TensorFlow.js 和 jQuery。这些可以与以下设备一起安装:
npm install @tensorflow/tfjs --save
npm install jquery --save
安装后,两个库都可以在node_modules
目录中找到。为了避免这种情况,在我们的代码中使用任一库之前,还必须重新启动服务器:
这就是我们所需要的 Angular。大多数编辑器都可以用于我们的 Angular 项目,但我会推荐尝试使用括号或 VS 代码(我更喜欢后者)。
4.引导程序
我们将使用 Bootstrap 来设计我们 web 应用程序的大部分样式。Bootstrap 是一个预先格式化的 CSS 框架。它承载了一系列有用的预样式但灵活的元素。多亏了 Bootstrap,我们可以轻松地创建一个干净的动态页面。
要安装,我们键入npm install bootstrap --save
。
Angular 使用src/styles.css
来设计网络应用。现在我们已经安装了引导程序,我们只需通过向styles.css
添加以下内容来导入bootstrap.css
:
@import "~bootstrap/dist/css/bootstrap.css";
应用程序 HTML
我们不想要默认网页,所以让我们更新它。HTML 代码包含在src/app/app.component.html
中。
让我们只放置一个简单的标题和段落,这样我们就可以看到我们已经更改了正确的文件并正确地实现了 Bootstrap:
<h1>Meditations NLG</h1>
<textarea>Lorem ipsum dolor...</textarea>
<button class="btn btn-dark">Run</button>
无引导(左)和有引导(右)—这是一个开始,但当然还需要做更多的工作。
现在一切就绪,我们可以开始集成模型本身了。
5.模型组件
Angular 的工作原理是将我们的应用模块化成不同的部分。我们已经在src/app
中看到了“app”组件,它表现为主/顶层,我们将所有其他组件放在其中。
要创建新组件,我们需要返回 Angular CLI。确保命令行位于项目目录中,并使用以下内容生成我们的text-gen
组件:
ng generate component text-gen
这里,我们使用 Angular CLI ng
到generate
一个新的component
叫做text-gen
。如果我们查看一下app
目录,我们会注意到几个新文件:
这是我们新的text-gen
组件。要将组件放在 web 应用程序页面上,我们必须将组件标识符添加到app.component.html
—组件选择器的名称包含在下面的text-gen.component.ts
中:
因此,要在我们的应用程序中包含这个组件,我们只需在app.component.html
中将<app-text-gen><app-text-gen/>
添加到我们的代码中。将之前包含在app.component.html
中的所有内容移动到text-gen.component.html
。
6.加载我们的模型
回到src/app/text-gen
我们可以开始组装我们的模型。
首先,在text-gen.component.ts
中,让我们编写加载模型的代码:
对我来说,这里最令人困惑的部分是async
和await
——其余部分与 Python 差别不大。
异步执行(左)和同步执行(右)—图片来自作者。
在 Python 中,我们一次运行一行代码——等待当前行完成处理,然后移动到下一行。
然而,JavaScript 可以并行运行我们的代码脚本。所以当第一行还在处理的时候,第二、三、四行已经被执行了——我们称之为异步执行。
如果这对你来说听起来像一场逻辑噩梦——相信我,当我说时,它是。
loadLayersModel
功能是异步的。为了正确处理这个问题,我们需要使用async
使加载函数异步——允许我们使用await
和loadLayersModel
函数。
在这里使用await
使得这一小部分代码是同步的(像 Python 一样)。我们在加载和构建char2idx
和idx2char
映射时也会用到这个。
整合负载函数
目前,我们的加载函数没有内置到我们的text-gen
组件中。为了干净地做到这一点,我们可以将它与现有的类定义集成在一起。
在TextGenComponent
类中,有一个名为ngOnInit
的函数——在类初始化时,这个函数会被立即调用。因此,如果我们将 load 函数放入其中,页面一加载,我们就加载模型。
修改ngOnInit
,我们得到如下:
此时,您可能会(也可能不会)遇到以下错误:
如果是,我们导航到tfconfig.json
并将"skipLibCheck": true
添加为 TensorFlow 推荐的,如下所示:
7.做预测
我们已经加载了模型、字符到索引的映射和字符数组。现在,我们需要编写一个函数,它以文本的形式接受输入,并使用它来输出更多的文本,正如我们的模型所预测的那样。
我们可以把它分成三个部分:
- 要索引的字符 —将文本转换为数字数组
- 预测循环 —下一个最可能值的迭代预测
- 字符索引 —将预测数字数组转换回文本
要索引的字符
第一部分是文本到数字数组的转换。为此,我们使用了getNum
功能:
getNum
接受char2idx
和输入文本,并返回相同文本的编码版本。例如,用这个 char2idx 字典我们得到:
getNum(char2idx, "Hello World")
**[Out]:** [20, 45, 52, 52, 55, 1, 35, 55, 58, 52, 44]
预测循环
这是我们代码中最复杂的部分,但它只做了一点点:
- 将由
getNum
生成的索引数组转换成张量——我们的模型需要的数据类型 - 将张量输入到我们的模型中,该模型输出一个新的张量,其中包含每个字符的预测概率——由数组索引表示
- 用
indexOfMax
取最高概率指数,并将其反馈到模型中进行另一次预测
在代码中,这给了我们:
注意,[indexOfMax](https://gist.github.com/jamescalam/b54dba89fc02feb7e08dc5017e6ac38d)
函数查找数组中最大值的索引——我们把它放在我们的类之外。
字符索引
这部分是最简单的,实际上我们已经在预测循环的第 39 行实现了它:
this.text = this.text.concat(this.idx2char[yIdx]);
它所做的只是将预测的索引传递给idx2char
,返回英文字符并将其连接到当前文本字符串。迭代生成我们预测的文本。
8.TextGenComponent
这些部分都是通过generate
函数实现的——该函数是作为另一个方法添加到TextGenComponent
类中的。
getNum
和indexOfMax
方法都被添加到组件类之外。
当我们在text-gen.component.ts
中将所有这些放在一起时,我们得到了脚本的功能版本:
完整的 text-gen.component.ts 脚本。如果它看起来很多,不要担心——这个代码块也让我害怕,但是一旦你一次一行地完成它,它会出奇地简单。
连接页面和模型
现在,我们需要做的就是将我们的首页元素——<textarea>
和<button>
——连接到组件的内部。
导航至src/text-gen/text-gen.component.html
并添加以下内容:
首先,我们需要将显示在<textarea>
中的文本绑定到包含在TextGenComponent
中的text
变量。这很容易通过向<textarea>
元素添加[value]="text"
来完成。
现在,当generate
运行时,它用新文本更新TextGenComponent.text
——反过来更新<textarea>
。
最后一部分是告诉 Angular 在点击“沉思”按钮时运行generate
。还是那句话,这个超级简单,加上(click)="generate( meditationInput.value)"
就行了。
meditationInput
指的是<textarea>
元素,而.value
捕捉元素内部的文本,并将其传递给我们的generate
函数。
拍拍自己的背
就这样,我们完成了!这款应用程序谈不上漂亮(正如我说过的——我不是设计师),但功能齐全:
为了简洁起见,我将把进一步的开发、设计和清理工作留到以后的文章中进行——本指南已经远远超出了我的预期!
尽管这篇文章很长,但我希望它是有用的。欢迎提问,或者告诉我不清楚的地方。那些使用过 JavaScript/TypeScript 或 Angular 的人——让我知道什么需要改进。
感谢阅读!
参考
[1]JavaScript 作为客户端编程语言在、W3 Techs 网站上的使用统计
如何使用 API 获取模型的空间要素
原文:https://towardsdatascience.com/how-to-use-apis-to-get-spatial-features-for-your-models-da729785f132?source=collection_archive---------81-----------------------
通过使用 API 中基于位置的功能,而不是另起炉灶,快速提高数据科学模型的性能。
在本文中,我将向您展示如何使用 API 快速获取空间数据集的许多要素,以构建更好的数据科学模型。
在我成为数据科学家的过程中,以及随后作为数据科学家的工作中,我建立了几个基于空间数据的模型,例如,预测房价,或者最近预测电动汽车充电站的预期用途。我很快发现,这些模型的性能(至少对于较小的数据集而言)并没有从模型的复杂性或广泛的参数搜索中受益,而是从良好的空间要素的可用性中受益。
我还意识到,提取这些空间特征可能相当麻烦:你需要识别和评估数据源,设置一套新的工具,如 PostGIS 数据库、OpenStreetMap 工具(如 transition、nomist 等。),并学习许多新的东西,如地图投影、空间索引、特定查询语言等,这会大大降低您的特征提取速度。
然而,还有一种更简单快捷的方法来获取您的空间要素集:使用一个处理所有这些任务的 API,这样您就不必这么做了。
如果你刚开始接触数据科学,或者不是来自计算机科学家教育背景的人,那么 API 一开始可能会让人望而生畏(专业术语有资源、端点、基本身份验证等。).至少对我来说是这样,这在某种程度上阻止了我使用它们。
但是,通过学习更多关于 API 的一般知识和使用提供免费帐户的 API,您将很快熟悉使用 API,并能够将它们作为一种新的有用资源集成到您的建模工作流中。由于大多数 API 都是以类似的方式构建的(这是它们如此受欢迎的一个原因),知道如何使用一个 API 也将有助于您理解其他 API 是如何工作的。
用于空间特征的 API
我目前正在 features4.com(现已公开测试)构建一个新的 API,它提供了对丰富的空间特征的免费和便捷的访问,例如 500 米半径内的餐馆数量或到最近医生的距离。我将使用 Features4 API 作为如何使用 API 的例子。
那么,我们如何使用 Featurees4 API 来获取您的空间要素呢?
鸟瞰图
从鸟瞰的角度来看,使用 API 很像调用一个普通的函数。您需要函数名,向它传递参数,然后返回一个结果。这与 API 基本相同(只是名称不同):你需要一个 URL,向它发送一些数据,然后得到一个响应。
网址
最重要的区别是,当你的函数托管在你的计算机上时,API 托管在 web 服务器上。因此,API“函数名”将总是包含它所在的地址,通常是一个 URL(就像您在浏览器中输入以检索网站一样)。例如,features4 API 的所有 URL 都以 https://api.features4.com/v1 的开始,因为这是 API 在服务器上可以到达的地方。例如号“功能”位于https://api.features4.com/v1/number.
传递参数
一旦知道了 URL,就需要指定要发送给它的参数。你如何找出一个函数需要哪些参数?你只要看看它的文档就知道了。对于 API,您可以做同样的事情:为了知道 API 端点接受哪些参数,您可以查看一下 API 参考。在这样的参考中,您通常会找到关于参数的所有信息,包括它们的类型、描述和允许值。
我还没有提到的一点是,一般来说,API 比典型函数更加灵活。通常情况下,您可以用不同的方式发送参数值。一种常见的方法是以下面的形式传递它们(所谓的表单 urlencoded,因为您可以像这样将它们附加到 URL):
param1=value¶m2=300¶m4=true
指定参数的另一种常见方式是发送 JSON 编码的参数:
JSON 的好处是它支持嵌套参数和不同的数据类型,比如字符串、数字和列表:
方法
您需要向 API 提供一条信息:请求方法告诉服务器您希望服务器采取什么样的动作。这又使得 API 更加灵活,因此同一个 URL 可以服务于多个不同的响应。例如,GET
表示应该获取一个项目,或者POST
表示将数据推送到服务器(创建一个资源,或者生成一个临时文档发送回来)。
该方法还告诉服务器在哪里查找您传递的参数。使用GET
方法,您可以将参数值附加到 URL,而使用POST
方法,参数值将作为请求的一部分发送。
与传递参数一样,API 文档将让您确切地知道服务器接受什么方法,以及它将给出什么响应。为了一致性和简单性,特性 4 API 目前只使用 POST 方法,这样所有对 API 的调用都可以用同样的方式进行。
回应
API 非常可靠。除非无法访问他们的 web 服务器,否则无论您的请求是成功还是失败,他们都会给您返回一个响应。为了让你知道是否一切顺利,或者是否出了差错,它会给你发回一个 3 位数的数字(例如 200),即所谓的状态码。每个状态代码都有特定的含义,并且有一个具有标准化含义的状态代码的大列表。别担心,你不必把它们都背下来,或者一开始就记住这一点:
如果状态代码以下列开头:
- 2 一切都好
- 4 您可能犯了一个错误(比如遗漏了一个参数)
- API 出错(所以,你对此无能为力)
如果一切正常,并且您收到了状态代码为 200 的响应,那么您还将收到您向 API 请求的数据。例如,Features4 API 将返回您所请求的空间特征,例如 500 米半径范围内的餐馆数量。响应的格式取决于 API,但您经常会收到 JSON 格式的响应,您已经通过传递参数知道了这一点:
如果您收到一个状态代码以 4 开始的响应,这意味着您这边出了问题,一个好的 API 会告诉您更多关于您所犯错误的类型,以便您能够快速修复它。例如,如果您省略了一个名为“半径”的参数,Features4 API 会告诉您哪里出错了:
所以,这是一个关于 API 一般如何工作的非常简短的介绍。关于它和 HTTP 协议还有很多要学习的,例如, Mozilla 提供了一个很好的信息来源。
一个具体的例子
让我们继续看一个具体的例子,看看如何使用 Features4 API 来检索一个位置的空间特征。我们将使用 Python 作为一种语言,但是基本上所有的语言都提供了向 API 发出请求的库。
假设你正在建立一个预测房价的模型,你认为中心性将是它的一个重要方面。假设酒吧和餐馆位于城市中心,密度较高,您希望获得给定位置周围 500 米半径范围内的餐馆数量。
获取访问权限
几乎所有的 API 都要求您提供一些凭证来访问它,比如用户名和密码。特性 4 允许你在注册一个免费账户后,用一个测试用户名API_TEST_KEY
和没有密码或你的私有 API 密钥来试用 API(包括更多特性)。
获得您的第一个功能
首先要做的是在 API 参考中找出 Radius 中元素的特征号的 URL、方法和参数:
半径特征中元素数量的 API 参考
你可以在右上角找到网址和方法,上面说你要对/number
网址使用 POST 方法。点击网址将显示完整的网址https://api.features4.com/v1/number
。
在文档的中心部分,您可以看到 API 为此特性采用的所有参数,它们是:
lat
:所在位置的纬度lng
:所在地的经度element
:您感兴趣的地图元素(如餐厅)radius
:该位置周围的半径,以米为单位(如 500)
例如,您可以使用这个网站来获取某个位置的纬度和经度。
一旦有了 URL、方法、凭证和参数,就可以使用请求库来检索特性。为了方便起见,API 参考提供了不同语言的代码示例,您只需复制和粘贴即可获得基本结构,然后您只需根据需要更改参数。因此,在示例中,只需将bar
替换为restaurant
。
如何使用 python 向 Features4 API 发出请求
很好:您可以看到,在某个地点(慕尼黑市中心)500 米半径范围内的餐馆数量为 153 家。
对 Features4 API 的请求结果
类似地,您可以检索另一个特征:到最近地图元素的距离。例如,对于房价,到最近的幼儿园的距离可能是感兴趣的。获得此功能的过程与之前相同:
- 查看 API 参考中相应的部分
- 识别这些信息:URL
/distance
、方法POST
和参数lat, lng, element
- 提出请求
结论
通过使用新的 Features4 API ,您已经了解了如何使用 API 为数据科学模型检索空间要素的一些基础知识。
随意探索 API 参考以获得更多特性,或者查看文档以了解哪些地图元素可用于这些特性。
作为一名数据科学家,掌握 API 知识将对你有很大帮助,因为对于许多事情,你不必重新发明轮子,而是可以使用别人已经为你做的工作。因此,利用现有的 API 将让您更快地提高工作效率。
我希望这篇文章能帮助你开始使用 API。
如何在 3 分钟内使用应用、应用地图和地图
原文:https://towardsdatascience.com/how-to-use-apply-applymap-and-map-in-3-minutes-36a08c09257?source=collection_archive---------26-----------------------
有时不太清楚什么时候使用 map、applymap 或 map。我会解释何时使用哪一个。
当你开始使用 Python 进行数据分析时,你会对所有的可能性着迷,但有时你也会感到困惑。通常有很多方法可以达到相同的目标,但你不确定该用哪一种。比如,很多人并不清楚apply
、applymap
和map
的区别。为此,我想讨论一下三种方法的区别以及何时使用哪一种方法。
示例 1 —应用
假设你是辛普森团队的数据科学家。该系列的明星得到了赞助,每个明星每一季都有预算来买东西。你有第一季到第三季的成本:
>>> df = pd.DataFrame({'Customer': 'Mr.Burns Lisa Marge Milhouse Bart Homer'.split(),
'Costs_1': np.arange(6) *2, 'Costs_2': np.arange(6) * 4, 'Costs_3': np.arange(6) * 6})
>>> df
Customer Costs_1 Costs_2 Costs_3
0 Mr.Burns 0 0 0
1 Lisa 2 4 6
2 Marge 4 8 12
3 Milhouse 6 12 18
4 Bart 8 16 24
5 Homer 10 20 30
第一项任务是确定每个季度的支出差异有多大。为此,我们首先创建一个函数来确定列的最大值和最小值,并将它们相减:
>>> def diff_calc(x):
diff = x.max() — x.min()
return diff
在我们将该函数应用于数据帧中所有需要的列之后:
>>> df[['Costs_1', 'Costs_2', 'Costs_3']].apply(diff_calc)
Costs_1 10
Costs_2 20
Costs_3 30
dtype: int64
如您所见,我们总共得到三个结果。我们对其应用函数的每一列都有一个结果。这是一个有趣的发现:每一季差异都在增加,所以我们似乎有特别渴望消费的明星。
我们为什么使用 apply?
apply
方法可以用于一维数组。该方法可用于列和行。一维数组总是作为输入,即函数是逐行或逐列执行的。如果我们添加axis=1
作为参数,我们得到一个逐行计算:
>>> df[['Costs_1', 'Costs_2', 'Costs_3']].apply(diff_calc, axis=1)
0 0
1 4
2 8
3 12
4 16
5 20
dtype: int64
示例 2 —应用地图
在第一个例子中,我们希望对数据帧的每个数字列应用一个特定的函数。如果我们想单独改变每个元素呢?假设市场部的一位同事要求您将每个元素格式化为字符串,并为每个元素添加前缀“S_”作为 Simpson 值的标签。在这种情况下,您需要一个可以应用于每个单独元素的函数。让我们首先创建函数:
>>> def simpsons_string(x):
result = "S_" + str(x)
return result
使用applymap
,我们现在可以将函数应用于数据帧的任何元素:
>>> df.applymap(simpsons_string)
Customer Costs_1 Costs_2 Costs_3
0 S_Mr.Burns S_0 S_0 S_0
1 S_Lisa S_2 S_4 S_6
2 S_Marge S_4 S_8 S_12
3 S_Milhouse S_6 S_12 S_18
4 S_Bart S_8 S_16 S_24
5 S_Homer S_10 S_20 S_30
好吧,实际上我们应该告诉我们的同事,这个要求在数据处理方面不是最佳的,但是applymap
为我们提供了很好的服务。
示例 3 —地图()
在我们准备了上面的数据并给每个元素添加了前缀之后,我们得到的反馈是这位同事犯了一个错误。他只希望所有的字符串元素都有一个前缀。所以现在我们必须改变列的每个元素:
>>> df['Customer'].map(simpsons_string)
0 S_Mr.Burns
1 S_Lisa
2 S_Marge
3 S_Milhouse
4 S_Bart
5 S_Homer
Name: Customer, dtype: object
完美!使用map()
,我们可以将函数应用于一列中的每个元素,而使用applymap()
,我们可以将函数应用于整个数据帧。
结论
通过这三种方法,apply()
、applymap()
和map()
功能可应用于数据帧或部分数据帧。使用apply()
将函数应用于列或行,applymap()
对整个数据帧的元素起作用,map()
对单个系列的元素起作用。
如果您喜欢中级数据科学,并且尚未注册,请随时使用我的推荐链接加入该社区。
新手如何使用 AWS Lambda 和 CloudWatch
原文:https://towardsdatascience.com/how-to-use-aws-lambda-and-cloudwatch-for-beginner-67df0755922e?source=collection_archive---------43-----------------------
让我们使用 AWS 服务构建一个简单的无服务器工作流!
我发现了一个很酷的网站(https://covid19api.com/),在那里我们可以使用免费 API 轻松访问 COVID19 数据。这给了我一个想法,创建一个简单的函数来使用 AWS Lambda 获取数据,并将其保存到 S3。该脚本将使用 CloudWatch 每天自动执行。
以下是我需要完成的任务列表:
- 写一个函数来检索数据并保存到 S3。
- 将函数部署为 AWS Lambda 函数。
- 在 AWS CloudWatch 上创建一个事件,定时运行该功能。
所以,让我们开始吧!
- 编写一个函数来检索数据并保存到 S3。
一开始,我编写代码来检索本地计算机上的数据。下面是代码和结果:
import requests
import pandas as pd
from pandas.io.json import json_normalize
baseUrl = "[https://api.covid19api.com/total/dayone/country/indonesia/status/confirmed](https://api.covid19api.com/total/dayone/country/indonesia/status/confirmed)"
response = requests.get(baseUrl)
df = json_normalize(response.json())
df['change (%)'] = df['Cases'].pct_change()*100
如您所见,脚本运行良好。接下来,我们需要将脚本放在处理函数上,这是 Lambda 将要执行的函数。
import requests
import pandas as pd
from pandas import json_normalize
import boto3
from datetime import datetime
from io import StringIO def lambda_handler(event, context):
baseUrl = "[https://api.covid19api.com/total/dayone/country/indonesia/status/confirmed](https://api.covid19api.com/total/dayone/country/indonesia/status/confirmed)"
response = requests.get(baseUrl)
df = json_normalize(response.json())
df['change (%)'] = df['Cases'].pct_change()*100
bucketname = 'my-beautiful-bucket'
filename = 'corona_dataset.csv'
csv_buffer = StringIO()
df.to_csv(csv_buffer)
client = boto3.client('s3')
response = client.put_object(
ACL = 'private',
Body= csv_buffer.getvalue(),
Bucket= bucketname,
Key= filename
)
我添加了两个新的库,即 boto3 和 StringIo,我还添加了脚本来将数据帧转换为 csv,并将其保存到我的 s3 存储桶中,名为“my-beautiful-bucket”。复制这个脚本并保存到一个名为 lambda_function 的. py 文件中。
2。将函数部署为 AWS Lambda 函数。
由于 AWS Lambda 不包括外部 python 库,我们不能只部署lambda_function.py
。我们需要将lambda_function.py
和所有那些库压缩成一个。zip 文件。
所以接下来要做的是创建一个新目录,并将lambda_function.py
文件放入这个新目录。对于 windows 用户,打开命令提示符并转到我们刚刚创建的目录,使用 pip 将所有库安装到本地目录:
pip install -t . pandas
现在有一个棘手的部分,因为 AWS Lambda 使用亚马逊 Linux 作为操作系统。所以我们需要兼容 Linux 的熊猫和 Numpy。
要解决这个问题,首先移除移除pandas
、numpy
、*.dist-info
和__pycache__
。接下来就是打开https://pypi.org/project/pandas/#files下载最新的*manylinux1_x86_64.whl
包。Numpy 也是一样:打开https://pypi.org/project/numpy/#files下载最新的 Linux 兼容包。两者都提取。whl 文件放在我们的目录中,并将其全部压缩到一个新的。zp 文件(注意:不要忘记删除 whl 文件、*.dist-info
和__pycache__
。):
现在是时候创建一个 Lambda 函数了,登录你的 AWS 账户,找到 Lambda 服务,打开它,创建一个函数。
接下来,进入函数内部,选择“上传. zip 文件”作为代码输入类型,单击上传按钮,选择。zip 文件并单击 save 按钮来部署它。
如果。压缩文件太大,我们可以把它上传到我们的 S3 桶,然后上传。来自亚马逊 S3 的 zip 文件。单击测试按钮运行脚本。
3。在 AWS CloudWatch 上创建一个事件,以便按计划运行该功能。
假设我希望我的函数在每天 10:00 GMT 运行。转到 CloudWatch 服务,单击规则,然后单击创建规则按钮。选择 Schedule 然后选择 Cron expression 而不是 Fixed rate,然后输入 0 10 * ?0 10 * * ?在文本框中,这意味着它将在每天 10:00 GMT 运行。选择我们的 Lambda 函数,单击 configure details 按钮,键入事件的名称,最后单击 create rule 按钮创建事件。
希望每一个读这篇文章的人都会觉得有用。当然,还有其他的 AWS 服务可以包含在这个项目中,使它变得更好,例如 AWS Athena 在 S3 使用 SQL 语言分析数据,AWS QuickSight 创建和分析数据的可视化。随意探索!
如何对自己的数据集使用 BigQuery API?
原文:https://towardsdatascience.com/how-to-use-bigquery-api-with-your-own-dataset-c901972cebd?source=collection_archive---------12-----------------------
使用 Flask 和 Bigquery APIs 根据用户查询参数从 Bigquery 数据集中提取数据。
来源: imgflip
我们要用 BigQuery APIs 做什么?
big query(BQ)API 对于让最终用户与数据集和表进行交互非常有用。
我们在本文中的目标是利用一些 BQ API 函数建立与 BigQuery 项目的连接,然后查询存储在那里的数据库。该数据库包含通过将 firebase analytics 链接到 Firebase 仪表板中的 BigQuery 而获得的 firebase 事件数据。
这是我的podcastApp
项目的云控制台的样子(它现在是一个 Android 和 IOS 应用程序,对那些有兴趣听播客的人来说是 Podurama ):
装置
步骤 1:在终端中运行以下命令:
pip install --upgrade google-cloud-bigquery
步骤 2:使用以下步骤从 Google Cloud console 获取您的 BQ 项目的认证密钥:
- 前往 项目选择器页面 。
- 启用 API 。
- 在云控制台中,进入 创建服务账号密钥 页面。
- 从服务账户列表中选择新服务账户。
- 在服务帐户名称字段中,输入一个名称。
- 从角色列表中,选择项目 > 所有者。
- 点击创建。一个 JSON 文件,包含下载到您计算机的密钥。
如果你在遵循这些步骤时遇到困难,在开始官方 Bigquery 文档页面上的之前,检查一下下的步骤 1、2 和 3。
一旦您按照这些步骤操作,您的下载文件夹中就会有一个 JSON 文件。确保将它移动到您将要编写 python API 脚本的目录中。
在我们开始之前…
在我们之前的博客文章中,我们讨论了什么是 API 和端点,如何使用 Flask 框架编写一个简单的HelloWorld
API,然后编写稍微高级的 API——从用户那里获取输入参数的 API。我们还深入讨论了如何通过在本地运行后端服务器来测试我们的 API。最后,我们还学习了如何编写简单而强大的 REST APIs 来部署机器学习模型。
我强烈推荐您去看看,因为在使用 Flask 框架方面有很多重叠,也因为在本文中我将更多地关注 BigQuery API。
注意:我将使用 Spyder 来编写 API 代码。最后,我将从 Jupyter 笔记本中访问我的 API。
让我们直接进入编码...
在存储 JSON 认证密钥的同一个目录中创建一个新的 Python 脚本BigQuery_API.py
。
正在导入 BigQuery 库
from google.cloud import bigquery
直接在代码中设置环境变量
import os
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = 'podcastApp-e07020594640.json'
在上面的代码中替换 JSON 键的名称。
提示:我发现在代码中直接设置 Google 应用程序凭证非常有用,当你同时处理需要不同凭证的项目时。
初始化 BigQuery 客户端
*# simple non parameterized query*
client = bigquery.Client()
编写 SQL 查询
query = """
SELECT user_pseudo_id, event_name
FROM `podcastapp-767c2.analytics_193436959.events_*`
LIMIT 5
"""
这是一个非常基本的查询,我希望看到两列的前五行数据——用户 id 和事件名称。当然,你的问题可能会比这更复杂。要获得一些查询灵感,请查看这篇文章。
发出 API 请求
query_res = client.query(query) # Make an API request.
打印结果
*# to print in the console*
for row in query_res:
print(f'{row.user_pseudo_id}: {row.event_name}')
最后,所有代码都在一个地方…
from google.cloud import bigqueryimport os
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = 'podcastApp-e07020594640.json'*# simple non parameterized query*
client = bigquery.Client()query = """
SELECT user_pseudo_id, event_name
FROM `podcastapp-767c2.analytics_193436959.events_*`
LIMIT 5
"""query_res = client.query(query) # Make an API request.*# to print in the console*
for row in query_res:
print(f'{row.user_pseudo_id}: {row.event_name}')
运行该脚本会在 iPython 控制台中产生以下输出:
Wohoo!我们已经成功地从我们的 BigQuery 数据库中进行了查询。
参数化 SQL 查询
正如我之前提到的,我们选择了一个相对简单的查询作为例子。让我们继续,这次对数据集进行一个有用的查询:
查询以显示每个国家/地区的 ios 应用程序用户数量:
query = """
SELECT geo.country AS country, COUNT(DISTINCT user_pseudo_id) AS count
FROM `podcastapp-767c2.analytics_193436959.events_*`
WHERE device.operating_system = 'IOS'
GROUP BY geo.country
"""
但是,如果我想将 WHERE 子句指定为用户的输入,该怎么办呢?好了,向参数化查询问好:
在参数化查询中,占位符用于参数,参数值在执行时提供。这些通常用于防止 SQL 注入袭击。
要指定一个已命名的参数,使用字符@
后跟一个用户特定的变量名,例如@device_name
。
让我们看看如何将它作为 BigQuery API 请求的一部分:
from google.cloud import bigqueryimport os
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = 'podcastApp-e07020594640.json'*# simple non parameterized query*
client = bigquery.Client()**query = """
SELECT geo.country AS country, COUNT(DISTINCT user_pseudo_id) AS count
FROM `podcastapp-767c2.analytics_193436959.events_*`
WHERE device.operating_system = @device_name
GROUP BY geo.country
"""****job_config = bigquery.QueryJobConfig(
query_parameters=[
bigquery.ScalarQueryParameter("device_name", "STRING", 'IOS')])**query_res = client.query(query, **job_config = job_config**) ***# to print in the console*
results = {}
for row in query_res:
results[row.country] = row.count
print(results)**
评估我们所做的修改:
- 查询中的 WHERE 子句现在有了一个占位符
@device_name
- 该查询现在使用在
job_config
中指定的某些作业配置运行。 - 我们指定了一个名为
device_name
的ScalarQueryParameter
,它的类型为STRING
,值为IOS
。
控制台中的输出如下所示:
这看起来很棒,除了让用户指定他们感兴趣的设备作为 API 调用的一部分对我们来说更有意义。幸运的是,我们已经知道(从我们的之前的教程中)如何接受用户输入并使用 Flask 将它们作为 API 请求的一部分插入。
将 REST APIs 和 BigQuery APIs 结合成一个令人惊叹的大碗:
如果你完全遵循了之前和当前的教程,下面的代码将会非常有意义。
**from flask import Flask
from flask_restful import Resource, Api, reqparse** from google.cloud import bigqueryimport os
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = 'podcastApp-e07020594640.json'**app = Flask(__name__)
api = Api(app)****# argument parsing
parser = reqparse.RequestParser()
parser.add_argument('user_device', choices = ('IOS', 'ANDROID', 'WEB'), help = 'Bad Choice: {error_msg}')
parser.add_argument('countries', action = 'append')**# parameterized query- one is scalar and other is array
**class PrintUserCount(Resource):
def get(self):
# parsing the input argument
args = parser.parse_args()
device = args['user_device']
countries = args['countries']**
client = bigquery.Client() query = """
SELECT geo.country AS country, COUNT(DISTINCT user_pseudo_id) AS count
FROM `podcastapp-767c2.analytics_193436959.events_*`
WHERE device.operating_system = [@device](http://twitter.com/device) **AND geo.country IN UNNEST(**[**@countries**](http://twitter.com/countries)**)**
GROUP BY geo.country
""" job_config = bigquery.QueryJobConfig(
query_parameters=[
bigquery.ScalarQueryParameter("device", "STRING", device), **bigquery.ArrayQueryParameter("countries", "STRING", countries)**
]
) query_res = client.query(query, job_config = job_config)
# to store results in dataframe
results = {} #empty dataframe
for row in query_res:
results[row.country] = row.count
** return{'res': results}**
**api.add_resource(PrintUserCount, '/')
if __name__ == '__main__':
app.run(debug=True, port = 1123)**
评估我们所做的一些修改:
- 我们现在接受来自用户的两个输入:
(1)设备类型,可以是IOS
、ANDROID
或WEB
、
(2)您想要输出用户数量的国家列表。 - 作业配置必须将
countries
占位符指定为ArrayQueryParameter
,因为这将是一个国家名称数组。 - 在访问 WHERE 子句中的
countries
占位符时,记住要UNNEST
它。
最后,保存文件并使用顶部绿色的 run 按钮(或 Mac 上的 F5)运行它。正如您在 iPython 控制台中看到的,API 正在本地服务器上运行[http://127.0.0.1:1123/](http://127.0.0.1:12345/)
。
现在打开 Jupyter Notebook 并输入以下代码来访问我们刚刚编写的 API。
url = '[http://127.0.0.1:1123/'](http://127.0.0.1:1123/')
params = {'user_device': 'IOS',
'countries':["China", "India", "Canada"]
}
response = requests.get(url, params)
response.json()
瞧,我们有一个可用的 API,您可以使用它来查询您的 BigQuery 数据集,并接受来自用户的输入。
结束前的一些提示…
- 用生命保护您的 JSON 认证密钥。防止它落入坏人之手!
- 为了获得轻松的体验,在从您最喜欢的客户端库中访问 SQL 查询之前,请始终在 BigQuery Web UI 中尝试/测试/运行您的 SQL 查询。
- 如需进一步阅读,请查看 API 参考文档。
结论
在本文中,我们学习了如何使用 Flask 和 Bigquery APIs 根据用户查询参数从 Bigquery 数据集中提取数据。我目前正在使用这些框架作为我先睹为快的播客数据集的一部分。这对于创建基于 user_id 和他们之前与其他播客节目的交互请求推荐的 API 非常有用。希望在不久的将来,我会分享这些脚本。
直到下次:)
如何在日常分析工作中使用因果推理——第 2 部分,共 2 部分
原文:https://towardsdatascience.com/how-to-use-causal-inference-in-day-to-day-analytical-work-part-2-of-2-1824e7024cd2?source=collection_archive---------39-----------------------
来源:https://www.pexels.com/photo/paper-on-gray-laptop-669617/
在第一部分中,我们看了如何使用因果推理从观察数据中得出正确的结论——或者至少不会跳到错误的结论。
我们看到混杂因素常常是我们得出错误结论的原因,并了解了一种叫做 分层 的简单技术,它可以帮助我们 控制混杂因素 。
在这篇文章中,我们提出了另一个如何使用分层的例子,然后考虑当有如此多的混杂因素使分层变得混乱时该怎么办。
假设你在一家多渠道零售商工作。您一直在分析客户级别的销售数据,并注意到以下情况:
从多个渠道购买的客户每笔交易的花费比从单一渠道购买的客户多 30%。
来源:灵感来自http://bit.ly/2Q6BwTN
这是一个非常令人兴奋的发现,因为它非常具有可操作性如果是真的话 : 你可以列出你的单一渠道购物者的名单,并向他们发送优惠信息,诱使他们在下次购物时从另一个渠道购买——如果客户第一次在实体店购买,你可以通过电子邮件向他们发送 20%的网上优惠券。如果你的发现是真的,他们会花更多的钱,而你可以坐以待毙,看着钱滚滚而来:-)
人们很容易立即将这一发现告诉首席执行官——我的意思是,收入增加 30%是一大笔钱——但是让我们应用我们在第 1 部分中定义的清单。
随机分配?号购物者自选自己进入单通道和多通道组。
有混杂因素吗?影响购物者使用多少渠道以及每次交易花费多少的因素有哪些?
那么,在过去一年中,购物者与您一起购物的次数是多少?
- 在极端情况下,如果他们只和你一起购物过一次,他们就不可能加入多渠道团队。一般来说,他们在过去一年中与您一起购物的次数越多,就越有可能使用多个渠道。
- 他们与你一起购物的次数越多,他们就越有可能喜欢你的产品,更熟悉你的产品目录,因此更有可能在每笔交易中花费更多。
我们去追这个混蛋。
3.我们可以控制这个混杂因素,方法是使用混杂因素的不同值(作为拆分变量)拆分数据,并计算每个时段每笔交易的平均支出:
此表中有一些事项需要注意:
- 我们排除了那些在过去一年里只购买过一次的客户,因为即使是多渠道的概念也不适用于他们。**
- 我们使用三个类别进行了分层:2 次购买、3-5 次购买和 5 次以上购买。这是一种平衡行为——如果我们分层到太多的桶中,我们可能在一些桶中没有足够的数据。如果我们分层太少,我们将在同一个桶里混合苹果和橘子。我的方法是从一把桶开始分析,然后看看如果添加更多的桶,分析结果会如何变化。
- 总体数字(33.80 美元和 44.10 美元)只是以下数字的加权平均值。这只是一个检查,以确保我们在拆分数据时没有出错。
- 现在我们进入分析的核心。我们观察每个阶层(即每个混杂因素组),并计算从单一渠道客户到多渠道客户的消费数字如何变化。
- 请注意,所有这些变化都在 1–3%的范围内,与我们开始时 30%的大数字形成对比。这表明混杂因素在起作用,30%的数字是可疑的。
最后,正如我们在第 1 部分中了解到的,我们通过计算 调整后的 总体数字来进行去混杂】。调整是通过用每个阶层的客户在整个数据集中的百分比对阶层级别的数字进行加权来完成的。
我们计算调整后的单渠道客户的平均消费/交易如下…
…多渠道客户也是如此。
正如在第一部分、中所强调的,使用相同的权重(每个阶层中整个数据集中的客户百分比)来调整两组数字至关重要。
好吧,我们得到了什么?
故事发生了剧烈的变化!
原本让我们兴奋的 30%的差异已经缩小到了 2%。
在过去一年有两次购买的客户中,多渠道客户的花费仅比单一渠道客户多 1.5%!在购买超过五次的客户中,多渠道客户仅比单一渠道客户多花了 2.8%的钱!
鉴于最初的 30%数字和调整后的(去混杂)数字 2%之间的巨大差异,多重渠道不太可能产生显著的因果影响。不要把这个交给首席执行官:-)
为了便于解释,我在上面只使用了一个混杂因素。但是如果你喜欢你可以用更多。例如,你可能怀疑住在远离实体店的农村地区的购物者可能只在网上购物(因此属于单一渠道群体)。农村购物者可能有不同于其他人的消费模式,因此这也可能影响消费指标。
假设您有数据,您可以如下扩展上表,并像我们上面所做的那样,将调整后的数字与总体数字进行比较:
此时,你可能会想:“如果我有不止一两个联合创始人呢?如果我有半打呢?分层将变得相当笨拙,不是吗?”
好问题。是的,分层将弄得乱七八糟。你将需要使用多元方法,如线性回归或逻辑回归来完成这项工作。您可以跟进这些参考资料(文章、文章、文章)以了解更多信息,但这里有一个来自我的经验的快速示例。
假设您为一家零售商工作,正在考虑购买一套价格优化系统。您如何理解/量化使用该系统对收入的影响?
在理想情况下,你可以做一个 A/B 测试,随机抽取 50%的产品使用价格优化系统进行定价,另外 50%使用你当前的方法进行定价。你可以运行这个测试一段时间,然后比较两组的收入等。
不幸的是,由于某些组织原因,这可能是不可能的(例如,也许你不能强迫你的销售团队在某些产品上使用该系统,而在其他产品上不使用)。但是你能做的是让所有终端用户都可以使用这个系统,如果他们想的话,也就是说,你可以允许终端用户自行选择他们想用新系统为哪些产品定价。
这种自我选择显然意味着非随机分配的情况,您不能简单地比较使用新系统定价的产品的平均收入与使用您当前方法定价的产品的平均收入。
那么,分析结果数据以评估系统收入影响的最佳方法是什么呢?
让我们应用清单。有哪些潜在的混淆因素?
- 产品的类别。不同的产品类别可能有很大不同的收入,如果负责这些类别定价的最终用户在某些方面被新系统吸引/排斥(例如,那些负责时尚前沿产品类别的人可能更容易相信没有优化系统可以击败他们的直觉),这肯定会混淆结果。
- 产品的销售率。也许你的团队认为新系统有风险且未经验证,因此只会将它用于销量不多的产品;如果发生这种情况,新系统的性能看起来会比实际情况更差。
- …等等。
利用这些考虑,可以确定几个潜在的混杂因素。但由于混杂因素太多,无法进行分层,我们可以用回归来代替。
我们组装这样一个数据集,每个产品一行:
为了说明,我包括了产品类别、产品销售率、价格等级、去年同期的收入等列。作为潜在的混杂因素。在实践中,你必须运用你的领域知识和商业判断来列出这个清单。
我还有一个列(“系统使用指标”),它是一个 0-1 变量,表示新的价格优化系统是否用于该产品的定价。最后,我有一个列显示了每个产品在测试期间的收入。
有了这个数据集,我们可以用“测试期收入”作为因变量,所有其他列作为自变量来拟合回归模型。*
现在,找到使用价格优化系统与当前方法的因果关系就像从回归输出中读取一个数字一样简单。
“系统使用指标”虚拟变量的系数给出了使用优化系统对测试期收入的增量因果影响,控制了所有其他变量。
这种方法被广泛使用:当需要因果效应时,分析师将识别混杂因素,并通常将它们与治疗和结果变量一起投入回归,并提取治疗变量的系数作为因果治疗效应。当你在报纸上看到一篇文章说“在控制了年龄、性别、身体质量指数、血压和身体活动水平后,X 与更高的 Y、风险相关”时,这是怎么回事。**
这种方法绝对应该放在您的数据科学工具箱中,但请记住,它取决于一些非常关键的假设,包括:
- 所有混杂因素都包括在模型中,即没有其他混杂因素(这可能是最重要的假设)
- 变量对结果的影响是线性的
(延伸阅读:使用分层 vs 回归的利弊)
(表格的布局意味着线性加法模型。我这样做是为了便于解释,但是如果你真的必须这样做,一个 乘法模型可能更适合这个问题:将测试期收入表示为所有因素的乘积,取对数使其在参数中呈线性,然后拟合得到的线性回归模型)*
关于如何从观察数据中做出好的推论,这个讨论仅仅触及了大量文献的表面。网上有大量的好材料,还有许多书籍和课程。如果你刚刚开始你的学习之旅,你会很高兴:-)。
最后,我想重申第一部分中的一个重要警告。
应用于观察数据的因果推断方法并不可靠。它们基于许多重要的假设(例如,数据中没有重要的混淆因素丢失),并且不能保证你所发现的是真正的因果关系;评估这些数字的含义需要判断力和细心。
尽管如此,思考潜在的混淆因素以及如何控制它们会增加你的 因果智商 ,并会让你避免频繁地得出错误的结论,以至于你应该养成这种习惯。
(如果您觉得这篇文章有帮助,您可能会发现这些感兴趣的
如何在空间分析中使用新冠肺炎公共数据
原文:https://towardsdatascience.com/how-to-use-covid-19-public-data-in-spatial-analysis-b46a536ce113?source=collection_archive---------57-----------------------
通过 CARTOframes 和 CARTO 的 Data Observatory 演示如何使用公开的新冠肺炎数据集进行空间分析。
在过去的几个月里,我们一直在向从事新冠肺炎分析的人员免费开放我们的平台,定期向我们的数据观测站 (DO)添加来自广泛供应商的公共数据集,并展示来自众多受影响行业的用例,以支持企业、政府和空间社区抗击这种疫情。
我们最近举办了一场网络研讨会,介绍了如何在空间数据科学中使用新冠肺炎公共数据的过程,并转录了以下要点。
为了参考和帮助你复制这种类型的分析,这篇文章中引用的代码和笔记本可以在这里找到。
设置
在这个例子中,我们在谷歌云平台上的 Jupyter 笔记本中使用我们的 Python 包 CARTOframes 。
要设置 CARTOframes,我们首先需要安装库,然后设置我们的帐户凭证。
**!**pip install cartoframesmy_base_url **=** 'https://[user].carto.com/'
my_api_key **=** 'XXXXX'
set_default_credentials(
base_url**=**my_base_url,
api_key**=**my_api_key
)
数据发现
接下来,我们可以探索 DO,以确定哪些类型的数据集可以直接用于我们,而不需要来源、清理和规范化。在 DO 中,我们有一个名为“covid19”的新类别,涵盖了与疫情相关的所有可用数据集。
**Catalog**().country('usa').categories[**<**Category.**get**('covid19')**>**,
**<**Category.**get**('demographics')**>**,
**<**Category.**get**('derived')**>**,
**<**Category.**get**('environmental')**>**,
**<**Category.**get**('financial')**>**,
**<**Category.**get**('geosocial')**>**,
**<**Category.**get**('housing')**>**,
**<**Category.**get**('human_mobility')**>**,
**<**Category.**get**('points_of_interest')**>**,
**<**Category.**get**('road_traffic')**>**]
我们还可以查询哪些提供者属于这个类别,从而使我们能够确定哪个数据集与我们的分析最相关。这里我们可以看到两个提供者, Safegraph 和 Spatial.ai 。
**Catalog**().country('usa').category('covid19').providers[**<**Provider.**get**('safegraph')**>**,
**<**Provider.**get**('spatial_ai')**>**]
在这个例子中,我们对纽约市的人员流动指标感兴趣,所以让我们更详细地看看 Safegraph 的数据,包括列、描述和地理覆盖范围。
请注意,Safegraph 的数据对全世界从事新冠肺炎相关项目的研究人员、非营利组织和政府公开。为了访问他们的数据,你首先需要签署他们的联盟协议。
datasets_acs_df **=** **Catalog**().country('usa').category('covid19').provider('safegraph').datasets.to_dataframe()
datasets_acs_df
datasets_acs_df.loc[0, 'description']
由于新冠肺炎疫情,人们目前正在进行社会距离。“为了了解人口普查区块群体层面的实际情况,SafeGraph 提供了一种临时性的社交距离度量产品。”
dataset **=** Dataset.**get**('sg_social_dist_667d8e8e')
dataset.geom_coverage()
我们可以进一步描述数据集,以便查看其中的变量,并检查聚合数据的前 10 行。“completely_home_device_count”变量是我们最感兴趣的变量,因为这将为我们提供有多少人留在家中工作的指示。我们可以看到,数据的时间分辨率是每日的,空间分辨率是人口普查区块级别的。
dataset.**describe**()
dataset.head()
现在我们已经确定这是我们想要使用的数据,接下来我们需要下载它。但是,因为我们只对特定时间段内的纽约市感兴趣,所以我们需要使用 SQL 查询通过边界框和日期来过滤数据集。边界框是使用 bboxfinder.com 的以疫情袭击之前的 2 月 16 日开始的一周为基线确定的。
sql_query **=** "SELECT * FROM $dataset$ WHERE ST_IntersectsBox(geom, -74.274573,40.484984,-73.453345,41.054089) AND do_date >= '2020-02-16'"
我们可以将这些数据的地理覆盖范围可视化,如下所示。
**Map**(Layer(dataset_df[dataset_df['do_date'] **==** '2020-02-16'], geom_col**=**'geom'))
空间分析
我们可以执行的第一个分析是处理数据,以建立一个时间序列(完整代码请参考笔记本)。
我们可以在图表中看到一个总体趋势,更多的人呆在家里,这是我们所期望的。在这个阶段,尽管由于人口普查区块的高粒度和每日抽样率,数据是有噪声的。
由于我们感兴趣的是相对于我们之前定义的 COVID 前基线的变化,我们首先需要聚合数据以减少噪音,时间上在周级别,空间上在邻域制表区域(NTA)级别(纽约市自己用于统计的区域)。
def aggregate_spatiotemporal(df):
wavg **=** lambda x : np.round(np.average(x, weights**=**df.loc[x.**index**, 'device_count']), 2)
df_aux **=** df.groupby(['date_range_start', 'ntacode']).\
agg({'device_count':'sum',
'distance_traveled_from_home':wavg,
'completely_home_device_pct':wavg,
'median_home_dwell_time':wavg}).reset_index()
nta_counts **=** df_aux['ntacode'].value_counts()
nta_to_rm **=** nta_counts[nta_counts **<** nta_counts.**max**()].**index**.tolist()
df_aux **=** df_aux[**~**df_aux['ntacode'].isin(nta_to_rm)].reset_index(**drop=True**)
wavg **=** lambda x : np.round(np.average(x, weights**=**df_aux.loc[x.**index**, 'device_count']), 2)
**return** df_aux.groupby('ntacode').resample('W-SUN', closed**=**'left', label**=**'left', **on=**'date_range_start').\
agg({'device_count':'max',
'distance_traveled_from_home':wavg,
'completely_home_device_pct':wavg,
'median_home_dwell_time':wavg}).reset_index()
除此之外,我们还计算了一个新的指标“completely _ home _ device _ pct _ diff”,给出了每天在家的时间百分比与基线的差异。
df_agg **=** df_agg.merge(df_agg.groupby('ntacode').agg({'completely_home_device_pct':'first'}).\
reset_index().**rename**(columns**=**{'completely_home_device_pct':'completely_home_device_pct_bl'}),
**on=**'ntacode')
df_agg['completely_home_device_pct_diff'] **=** df_agg['completely_home_device_pct'] **-** df_agg['completely_home_device_pct_bl']
随着噪音的减少,现在可以看到不同社区之间的不同模式,并识别空间模式。例如,在 3 月底,我们可以看到皇后区和曼哈顿区之间的差异,当时许多曼哈顿人离开城市,住在第二套房子里。快到五月底的时候,我们看到更多的外出活动,尤其是在布朗克斯和布鲁克林。
数据丰富
为了进一步分析,并尝试解释我们所看到的趋势中的一些差异,我们可以增加更多的数据集。由于我们已经下载了具有不同几何图形的数据集,CARTOframes 的一个重要特性是能够不断探索 DO 以丰富我们正在处理的数据框。
在这个例子中,我们用来自应用地理解决方案的社会人口数据进行了充实,以确定家用设备百分比的增加与平均收入之间是否存在关联。
由于这是一个优质数据集,它可以从 CARTOframes 内订阅,用于该分析和其他分析。
如果我们查看社会人口数据集中可用的变量,列名并没有给我们多少关于数据类型的指示。
dataset_dem.head()
为了帮助确定在这种情况下什么数据最适合我们使用,我们可以获得每个列标题的描述。
dataset_dem.variables[ **<Variable**.**get**('VPHCYNONE_3b864015')**>** **#**'Households: No Vehicle Available (2019A)',
**<Variable**.**get**('VPHCY1_98166634')**>** **#**'Households: One Vehicle Available (2019A)',
**<Variable**.**get**('VPHCYGT1_815731fb')**>** **#**'Households: Two or More Vehicles Available (2019A)',
**<Variable**.**get**('INCCYPCAP_70509bba')**>** **#**'Per capita income (2019A)',
**<Variable**.**get**('INCCYAVEHH_3e94053c')**>** **#**'Average household Income (2019A)',
**<Variable**.**get**('INCCYMEDHH_b80a7a7b')**>** **#**'Median household income (2019A)',
**<Variable**.**get**('INCCYMEDFA_5f55ef51')**>** **#**'Median family income (2019A)',]
由于我们对收入如何影响在家工作感兴趣,我们选择了“平均家庭收入”来充实我们现有的数据。
**Variable**.**get**('INCCYAVEHH_3e94053c').to_dict(){'agg_method': 'AVG',
'column_name': 'INCCYAVEHH',
'dataset_id': 'carto-do.ags.demographics_sociodemographics_usa_blockgroup_2015_yearly_2019',
'db_type': 'INTEGER',
'description': 'Average household Income (2019A)',
'id': 'carto-do.ags.demographics_sociodemographics_usa_blockgroup_2015_yearly_2019.INCCYAVEHH',
'name': 'INCCYAVEHH',
'slug': 'INCCYAVEHH_3e94053c',
'variable_group_id': 'carto-do.ags.demographics_sociodemographics_usa_blockgroup_2015_yearly_2019.household_income'}
现在,我们可以用每个 NTA 的平均家庭收入来丰富我们的原始数据框架,如下所示。
enriched_df_agg **=** enrichment.enrich_polygons(
df_agg,
variables**=**['INCCYAVEHH_3e94053c'],
aggregation**=**'AVG'
)
然后,我们计算了平均家庭收入和相对于基线呆在家里的人的百分比之间的相关性。选择从 5 月 10 日开始的一周,使用平均收入的对数标度,我们可以看到,在收入较高的地区,呆在家里的人增加得更多。
这再次向我们表明,新冠肺炎是而不是同等地影响每个人,在这个例子中,人口统计起着关键作用。
fig, axs **=** plt.subplots(1, 2, figsize**=**(18, 4))
sns.regplot(x**=**'avg_income', y**=**'completely_home_device_pct_diff',
**data=**enriched_df_agg[enriched_df_agg['date_str'] **==** '2020-05-10'],
scatter_kws**=**{'color':'blue', 'alpha':0.6}, line_kws**=**{'color':'red'}, ax**=**axs[0])
sns.regplot(x**=**np.log(enriched_df_agg.loc[enriched_df_agg['date_str'] **==** '2020-05-10', 'avg_income']),
y**=**enriched_df_agg.loc[enriched_df_agg['date_str'] **==** '2020-05-10', 'completely_home_device_pct_diff'],
scatter_kws**=**{'color':'blue', 'alpha':0.6}, line_kws**=**{'color':'red'}, ax**=**axs[1])
本文原载于 CARTO 的博客 。
如何使用可解释的机器学习使用 COVID-CXR 识别胸部 X 射线上的新冠肺炎感染
原文:https://towardsdatascience.com/how-to-use-covid-cxr-to-predict-covid-19-on-chest-x-rays-with-explainable-ai-c05cb07d5f0f?source=collection_archive---------38-----------------------
LIME 应用于 CNN 训练预测后前位胸片新冠肺炎感染
编者按: 走向数据科学 是一份以数据科学和机器学习研究为主的中型刊物。我们不是健康专家或流行病学家,本文的观点不应被解释为专业建议。想了解更多关于疫情冠状病毒的信息,可以点击 这里 。
介绍
在这篇文章中,我将简要描述如何开始将机器学习应用于从胸部 X 射线预测严重的新冠肺炎病例。加拿大伦敦市的人工智能研发实验室最近发布了他们的 GitHub 知识库以及如何开始使用他们的模型的说明,该模型名为COVID-CXR【1】。该实验室的方法和发现在它的 关于主题【2】的文章中有详细描述。我一直在这个实验室工作,并为这个开源库做出了贡献。
通过遵循本文中的步骤,您将能够理解并快速开始到目前为止的工作。我希望能够接触到那些能够为这项工作贡献自己技能的人。
如果你想阅读到目前为止关于柯维德-CXR 的工作总结,可以看看我的同事马特·罗斯写的文章。
1.获取代码
要开始使用伦敦金融城的代码,请克隆 GitHub 库。一定要安装好必要的依赖项(资源库里有一个 requirements.txt )。
2.数据预处理
第 2(a)条。下载数据
下载以下三个数据集:
- GitHub 上的新冠肺炎图像数据收集库收集了越来越多的来自国际上的新冠肺炎病例的已鉴定的 cxr 和 CT 扫描。我感谢蒙特娄大学的约瑟夫·保罗·寇恩和他的同事们在收集这个数据集时所做的辛勤工作。
- 图 1 GitHub 上的新冠肺炎胸部 X 射线数据集倡议知识库是一个不断增长的来自新冠肺炎病例的已识别 cxr 的集合[4]。我感谢 Audrey Chung 和 Figure 1 在收集这个数据集时所做的辛勤工作。
- Kaggle 上可用的 RSNA 肺炎检测挑战数据集包含几个已识别的 cxr,并包括一个标签,指示图像是否显示肺炎的证据【5】。我感谢北美放射学会和所有其他相关实体提供了这个数据集。
在本地机器上的某个地方为您的数据创建一个文件夹,并将您下载的解压缩数据集放入其中。如果您希望为任何其他数据集编写定制的预处理,也可以将它们包含在这里。如果选择包含其他数据集,则必须相应地更新preprocess . py。
├── data
│ ├── covid-chestxray-dataset
│ ├── Figure1-COVID-chestxray-dataset
│ ├── rsna
│ └── **additional dataset here**
****
****左图:一个从数据集(1)中提取的带有新冠肺炎标签的 CXR 的示例。右图:取自数据集(2)的 CXR 的示例,标记为显示肺炎的证据。
在训练我们的网络时,第一个数据集包含 76 个后前位(PA) CXR 图像,这些图像来自新冠肺炎检测呈阳性的患者。在从这两个数据集中仅选择 PA CXRs 时要小心。这个可以在preprocess . py中随意修改。
第 2 条(b)款。将所有数据合并到一个数据集中
首先,决定是要执行二元分类还是多类分类。在 config.yml 中设置合适的字段。
- 二进制分类:**在列车区间内,将 CLASS_MODE 字段设置为‘binary’。该模型将被训练以将标记为新冠肺炎的图像与所有其他图像区分开来。**
TRAIN:
CLASS_MODE: ‘binary’
- 多级分类:**在列车区间内,将 CLASS_MODE 字段设置为‘multi CLASS’。该模型将被训练以区分标记为“新冠肺炎”的图像、标记为“其他肺炎”的图像以及标记为“没有发现”的图像。**
要合并两个数据集中的数据,从项目的根目录执行preprocess . py该脚本将创建一个由大约 1000 幅图像组成的大型数据集,并将它们分成训练集(82%)、验证集(8%)和测试集(10%)。您可以通过修改config . yml的数据部分的数量 _RSNA_IMGS 字段来控制从 RSNA 数据集中获取的图像数量。运行此脚本后,/ 数据/已处理的文件夹将包含包含训练、验证和测试集的 CSV 文件(见下文):
*covid-cxr
├── data
│ ├── interpretability <- For use later on
│ ├── processed <- Products of dataset preprocessing
│ │ ├── test_set.csv <- filenames and labels in test set
│ │ ├── train_set.csv <- filenames and labels in train set
│ │ └── val_set.csv <- filenames and labels in val set*
CSV 文件是将图像文件名和标签配对的熊猫数据帧的保存版本。
第 2 款(c)项。图像预处理
图像预处理是在执行训练脚本 ( train.py )时自动进行的。 ImageDataGenerator (来自 tensorflow.keras)用于在训练之前执行批量图像的预处理。由于每个数据集都有一个图像文件夹以及相应的文件名和标签表,因此调用imagedata generator . flow _ from _ data frame()将图像变换应用于批量图像文件。下面的代码片段演示了 ImageDataGenerator 如何帮助进行图像预处理(来自train . py)。****
*train_img_gen = ImageDataGenerator(rotation_range=10, preprocessing_function=remove_text, samplewise_std_normalization=True, samplewise_center=True)train_generator = train_img_gen.flow_from_dataframe(dataframe=data[‘TRAIN’], directory=cfg[‘PATHS’][‘TRAIN_IMGS’], x_col=”filename”, y_col=y_col, target_size=img_shape, batch_size=cfg[‘TRAIN’][‘BATCH_SIZE’], class_mode=class_mode)*
对图像应用了以下变换:
- 图像大小调整为以下形状:224×224×3。
- 对图像进行阈值处理以去除任何非常亮的像素,并修补缺失的区域。
- 图像的像素值被转换为平均值为 0。
- 图像的像素值除以它们的标准差。
3.训练模型
第 3 条(a)款。执行培训脚本
一旦运行了预处理脚本,就可以继续训练模型了。要训练模型,执行train . py。
如果您希望修改模型的架构或超参数,您可以在config . yml中修改其中的几个,而不需要对源代码做任何修改。配置文件的训练和 NN 部分包含允许用户尝试不同超参数的字段。下面是用户可以在配置文件中更改的字段的演示。有关这些字段的详细信息,请查看项目的自述文件。****
**TRAIN:
CLASS_MODE: ‘binary’
EXPERIMENT_TYPE: ‘single_train’
BATCH_SIZE: 16
EPOCHS: 200
THRESHOLDS: 0.5
PATIENCE: 7
IMB_STRATEGY: ‘class_weight’
CLASS_MULTIPLIER: [0.15, 1.0]
NN:
DCNN_BINARY:
KERNEL_SIZE: (3,3)
STRIDES: (1,1)
INIT_FILTERS: 16
FILTER_EXP_BASE: 3
MAXPOOL_SIZE: (2,2)
CONV_BLOCKS: 3
NODES_DENSE0: 128
LR: 0.0003
DROPOUT: 0.40
L2_LAMBDA: 0.0001**
当 DCNN_BINARY 字段保留为默认值时,请参见以下二进制分类器架构的可视化描述。
二进制模型架构概述。在该图中,残差块由两个卷积层定义,第一个卷积层的输入与第二个卷积层的输出相连,后面是最大池层。剩余的块串联连接,然后是 2 个完全连接的层。预测类(p)是最终层的 softmax 激活的 argmax。
第 3 条(b)款。TensorBoard 中的可视化训练实验
默认情况下,TensorBoard 日志会在每次训练时生成。日志可以在结果/日志/培训/中找到。在这个项目中,日志文件夹是根据它们创建的日期和时间来命名的。通过在训练运行的日志文件目录中运行 TensorBoard,您可以看到以下内容:**
- 在标量选项卡上可以看到训练和验证指标。默认情况下,指标包括丢失率、准确率、召回率、精确度和 AUC。**
- 测试集指标显示在文本选项卡下的表格中。**
- 超参数值显示在文本选项卡下的表格中。**
- 测试集预测的混淆矩阵在图像选项卡下可见。**
- 测试集预测的 ROC 曲线在图像选项卡下可见。**
********
左图:tensor boardSCALARS 选项卡中的损耗与时元图示例。 右图:tensor board 文本页签中测试集指标表示例。****
********
左图:张量板页签图像混淆矩阵示例。 右图:tensor board 的 IMAGES 页签中 ROC 曲线的例子。****
4.石灰解释
这个项目最重要的支柱是可解释性。在医疗保健领域,追求可解释的机器学习模型尤为重要。可解释的模型提高了患者和医疗保健提供者对机器学习算法的信任。此外,可解释性通知模型未来迭代的改进。
目前,该项目应用局部可解释的模型不可知解释(即 LIME)来解释我们深度卷积神经网络的预测[6]。我们使用了 LIME creators 的 GitHub 仓库中可用的实现。
4(a):解释测试集中图像的预测
在 config.yml 中,将路径中的 MODEL_TO_LOAD 设置为模型训练后生成的模型权重文件的路径。通过执行 lime_explain.py ,将初始化一个limimageexplainer对象,并为测试集中的第一个( 0ᵗʰ )图像生成一个可解释的解释。**
要为不同的图像生成解释,请将测试集中您希望看到的图像的索引传递给解释函数。回想一下,通过查看数据/预处理/test_set.csv ,您可以将测试集视为文件名和标签的表格。一旦执行了lime _ explain . py,调用以下函数解释测试集中的 iᵗʰ 例子:**
**explain_xray(lime_dict, i, save_exp=True)**
4(b):解释石灰说明
默认情况下,解释图像保存在文档/生成图像中。说明的文件名包括为其生成说明的图像的文件名。**
一个解释由两张并排的图片组成。左边是原图,右边是说明。绿色区域表示石灰被认为对预测类别贡献最大的区域。红色区域表示石灰认为对预测类别影响最大的区域。预测、标注和预测概率(softmax 层的输出)显示在左上角。下面是解释二元柯维德-CXR 模型预测的几个例子。
********
左:二元模型对测试集中非新冠肺炎示例的预测的时间解释示例。预测类匹配图像的地面真实类(即,非新冠肺炎)。有助于和不利于新冠肺炎预测的超像素分别被涂成绿色和红色。右:二元模型对测试集中的新冠肺炎实例的预测的时间解释的例子。有助于和不利于新冠肺炎预测的超像素分别被涂成绿色和红色。****
用户还可以指定 LIME 只显示新冠肺炎类的解释。为此,将 config.yml 的 LIME 部分中的 COVID_ONLY 字段设置为 true 。在这种情况下,绿色和红色区域表示对与新冠肺炎相对应的 softmax 输出元素影响最大的区域。
结论
这篇文章描述了如何开始使用 COVID-CXR 并为其做出贡献。请参见COVID-CXR GitHub 知识库获取更多说明。存储库的 README.md 解释了项目的组织,并提供了解决方案组织的更详细的描述。我们还努力在源代码文件中提供详细的文档。我们邀请您扩展我们的工作,并为这个项目贡献您可能有的任何想法。
最后,请记住这项工作绝不是为了临床使用;这纯粹是探索性的。然而,我们希望这个项目最终能给医疗从业者带来一些好处。**
参考
[1] M. Ross, COVID-CXR:一个开源的可解释的深度 CNN 模型,用于预测胸部 X 射线中新冠肺炎的存在 (2020),中等
[2] B. VanBerlo 和 M. Ross,利用机器学习对胸部 X 射线新冠肺炎感染的可解释预测的调查 (2020),中等
[3] J .科恩,新冠肺炎影像资料集 (2020),GitHub。
[4] A. Chung,图 1 新冠肺炎胸部 x 光数据集倡议 (2020),GitHub。
[4]北美放射学会, RSNA 肺炎检测挑战 (2019),Kaggle。
[5]里贝罗先生、辛格先生和格斯特林先生。“我为什么要相信你?”:解释任何分类器的预测 (2016),2016 年 KDD 第 22 届 ACM SIGKDD 知识发现和数据挖掘国际会议论文集
如何使用 COVID19Py
原文:https://towardsdatascience.com/how-to-use-covid19py-c3014475283c?source=collection_archive---------58-----------------------
由马库斯·斯皮斯克在 Unsplash 拍摄的照片
使用独特的 Python 包获取最新的冠状病毒数据
在整个 COVID19 疫情中,获取和分析足够的数据一直是个问题。到目前为止,像约翰·霍普金斯大学系统科学与工程中心(JHU·CSSE)和《纽约时报》( NYT)这样的机构在向公众提供时间序列和非结构化数据方面做得非常出色。现在,COVID19Py 的创造者们更进一步,为 @ExpDev07 的 REST API 提供了一个极其有用的包装器。该软件包允许用户访问和跟踪受任何冠状病毒影响的人数(如新冠肺炎、新型冠状病毒等)。)
本文旨在向您简要介绍 COVID19Py 0.3.0 中的基本功能和用例。更多信息,请参考 API 的 Github 库
安装和基础知识
在获取数据之前,有几行重要的代码需要运行。
安装和导入
# Install COVID19 Package in Terminal
$ pip install COVID19PyIn [1]: import COVID19Py
创建一个新实例来访问数据源
JHU 默认数据源来自位于 CSSE JHU 的全球数据库。如果您想使用该数据,则不需要data_source
参数。
In [2]: covid19 = COVID19Py.COVID19()
CSBS
In [3]: covid19 = COVID19Py.COVID19(data_source="csbs")
NYT 同样,《纽约时报》也发布了美国冠状病毒病例累计数的数据文件。您可以使用data_source = "nyt”
参数提取美国县级时间序列
In [3]: covid19 = COVID19Py.COVID19(data_source="nyt")
样本响应
接下来,重要的是要记住所有的输出都是字典格式的。如果您想在 pandas 中使用数据框,那么您必须采取适当的步骤来实现。
获取案例总数
当您访问实例中的所有数据时,您最终会得到一个带有两个键的输出:"latest"
和"locations"
。最新键显示最近确诊病例、死亡和康复患者的数量。location 键包含每个国家的最新数据,包括纬度、经度和人口数量。
In [4]: data = covid19.getAll()# Get same output with timelines as well
In [4]: data = covid19.getAll(timelines=**True**)
仅获取最新计数
In [5]: latest = covid19.getLatest()Out [5]: {'confirmed': 2401378, 'deaths': 165043, 'recovered': 0}
运筹学
In [5]: data = covid19.getAll()
latest = data["latest"]Out [5]: {'confirmed': 2401378, 'deaths': 165043, 'recovered': 0}
仅获取位置值
In [6]: location = covid19.getLocations()Out [6]:[{'id': 0,
'country': 'Afghanistan',
'country_code': 'AF',
'country_population': 37172386,
'province': '',
'last_updated': '2020-04-20T11:01:05.072895Z',
'coordinates': {'latitude': '33.0', 'longitude': '65.0'},
'latest': {'confirmed': 996, 'deaths': 33, 'recovered': 0}},
{'id': 1,
'country': 'Albania',
'country_code': 'AL',
'country_population': 2866376,
'province': '',
'last_updated': '2020-04-20T11:01:05.092994Z',
'coordinates': {'latitude': '41.1533', 'longitude': '20.1683'},
'latest': {'confirmed': 562, 'deaths': 26, 'recovered': 0}},
...
...
运筹学
In [6]: data = covid19.getAll()
latest = data["location"]
通过使用rank_by
属性,您甚至可以根据'confirmed'
、'deaths'
和'recovered'
的数量对位置进行排序
In [6]: latest = covid19.getLocations(rank_by='recovered')
选择特定国家
如果您只想查看给定国家的最新案例,那么您只需知道国家代码即可
In [7]: location = covid19.getLocationByCountryCode("US")# Get same output with timelines as well
In [7]: location = covid19.getLocationByCountryCode("US",
timelines=**True**)# Using the location id instead of country code
In [7]: location = covid19.getLocationById(39)
结论
越多的公司和组织能够收集和存储冠状病毒数据,我们就能越早找到抗击疫情的模式和方法。那里的大部分数据是跟踪数据,这意味着它只是跟踪确认、死亡和恢复的数量。NYT 和 Twitter 等一些公司已经发布了用于情感分析的非结构化数据,医疗机构也已经能够发布用于诊断和识别的胸片。
编者按: 走向数据科学 是一份以数据科学和机器学习研究为主的中型刊物。我们不是健康专家或流行病学家,本文的观点不应被解释为专业建议。想了解更多关于疫情冠状病毒的信息,可以点击 这里 。
如何使用交叉验证完成矩阵
原文:https://towardsdatascience.com/how-to-use-cross-validation-for-matrix-completion-2b14103d2c4c?source=collection_archive---------16-----------------------
寻找最佳 k 个潜在特征和因子矩阵的逐步交叉验证优化
照片由施巧灵·佩纳在 Unsplash 上拍摄
一般
交叉验证是机器学习中一个众所周知的实践,通常,它是训练过程的一部分,确保我们的模型在不拟合的数据上表现良好。有不同的方法进行交叉验证,但在所有这些方法中,我们都是根据不适合的数据来预测适合的模型。
在我搜索矩阵补全工具时,我发现主要是使用全部数据的例子,并且没有留下测试集。在这篇文章中,我将一步一步地演示如何使用交叉验证在 NMF(非负矩阵分解)算法中找到最佳的 k (潜在特征)来完成矩阵中的缺失值。然而,这也可以应用于其他算法。
为了让每个人都在同一页上,矩阵分解是使用线性代数将矩阵分解成其组成部分。任何矩阵 X 都可以化简为一对因子矩阵 A 和 Y ,其中 X 是这些矩阵的点积:
x 矩阵和 A/Y 作为它的因子矩阵
网上关于矩阵分解的信息数不胜数,我就不细说了。当矩阵及其因子矩阵的所有值都非负时,称为 NMF。更多信息见https://en . Wikipedia . org/wiki/Non-negative _ matrix _ factorization
这篇文章展示了:
1.如何实现交叉验证以找到最佳 k 个潜在特征
2.如何处理初始因子矩阵的随机性
以下是我工作的基础:
1.Alex Williams 的一个帖子,我从中获得了 NMF 交叉验证的灵感:http://alexhwilliams . info/itsneuronalbog/2018/02/26/crossval/,我的帖子实际上是那个概念的一步一步的实现。
2.Tautvydas 的 Stackoverflow 答案,其 NMF 优化函数被用作代码的基础:https://stack overflow . com/questions/22767695/python-non-negative-matrix-factorization-that-handles-both-zero-and-missing-dat
代码是用 Python 编写的,并在 Numpy 数组上演示,但可以很容易地修改以用于 Pandas 数据框架。
什么是‘潜在特征’,为什么我们需要正确的数量?
对于一个矩阵 X,可能有许多对 A / Y ,每对在形状和值上有所不同。
为了将讨论集中在形状元素上,我们假设 X 有 m 行和 n 列,如上图所示。因此 A 和 Y 的形状对于 A 应该是 m 乘 k ,对于 Y 应该是 k 乘 n ,其中 k 可以是任意的计数(正整数)。
k 代表 A 和Y的特征数量,但是由于我们只有 X ,我们不知道 k 的尺寸,因此我们也不知道 A / Y 的形状。这就是为什么 k 所代表的特征被称为潜在特征的原因。在下图中我们看到不同对的因子矩阵 A / Y ,每对都有不同的 k ,它们都是有效矩阵:
为了演示什么是潜在特征,我们来看一个例子。矩阵补全有很多用途,然而最著名的是基于 Netflix Prize 的电影分级推荐系统,其中用户的偏好部分缺失。
下面是一个完整矩阵的例子(蓝色的),其中的数字代表用户的排名,因子矩阵嵌入了一些特性,在本例中为 3。
如果约翰喜欢喜剧,而电影 B、C、E 是喜剧,则算法可以“分配”一个特征来表示喜剧偏好,因为有一些支持信息。
想要补全 X 中的缺失值,应该选择使用哪个 k ?
太小的 k 可能会缺少我们需要的信息,导致拟合不足。在这种情况下,添加更多的特性可以告诉我们更多关于缺失值的信息。
对于 k 过高的值可能会导致过度拟合。这是因为我们得到了多个解决方案,如下表所示:
右边的向量不提供任何新信息。它只是其余向量(x+y-z)的线性组合。
通过交叉验证流程确定 k。
步骤 1-生成样本数据
这里我们创建自己的“缺失数据”。背后是什么?
1.我们希望创建一个完整的表,包括“缺失的值”,这样我们就可以真正看到在过程结束时我们是否很好地完成了这些值。
2.我们希望从 real A 和 Y 生成表格,这样我们就知道什么样的 k 是最优的,并看看我们是否得到这个作为输出。
在打印输出中,我使用了一个小矩阵(10 乘 12),主要是为了演示方便。然而,为了看到交叉验证的真实效果,我们需要一个更大的矩阵,所以所有的图都取自一个 40×25 的矩阵。两个矩阵都有 5 个潜在特征。
注意,k 必须小于矩阵的行/列的最小值,否则我们有多个解。
输出(10 乘 12):
现在,我们随机创建空值来模拟真正的“缺失值”:
输出(10 乘 12):
从现在开始,代码与具有缺失值的实矩阵相关。
步骤 2 —准备阶段
首先,我们创建空掩码。这是最后一步所需要的,在这一步中,我们用得到的矩阵来填充缺失的值。
现在我们给矩阵加 1(或任何其他数字)。这是为什么呢?
学习阶段从用 0 填充零开始,所以我们想要区分真正的零和用零填充的零。
当然,这只是在矩阵中有零的情况下才有意义。
步骤 3-折叠准备
在任何交叉验证中,我们都将数据分开,例如一部分数据被拟合,其余的数据用于测试。
在这里,我们将数据矩阵划分为四个部分,每个部分都作为一个等待测试的集合。矩阵被垂直和水平分成两半,如下图所示。
这满足了一个基本要求,即拟合区域应该分布在所有的行和列上,否则,算法就没有正确的数据可以学习。
在左手边:分成 4 折。在右侧:折叠 1 作为测试集,其他折叠作为训练集。
我们得到每个折叠的训练和测试误差,然后使用它们的平均值。
我用了 4 折。然而,人们可以使用不同的折叠数,甚至将其发展为一个参数。
在我们的矩阵上应用该函数产生了训练和测试集,以及每个集的 0/1 掩码。例如,当 fold=2 时,我们得到:
这些掩码仅用于折叠,还不包括空掩码。这将在下一步中与折叠遮罩合并为一个。
步骤 4 —交叉验证
交叉验证函数相对较长,所以首先我将它的主要组件写成一个简短的算法:
交叉验证算法流程
为什么我们要把每个褶皱分成几个周期?
学习过程从给因子矩阵 A 和 Y 中的一个分配随机值开始。然后在学习过程中,更新矩阵,直到我们达到最优。
然而,我们不知道我们开始使用的随机矩阵会把我们引向绝对最优还是仅仅一个局部最优。
所以这里我们在几个周期中尝试几个初始随机矩阵,取最佳周期的端矩阵。请注意,我们的最佳周期是具有较低序列误差(不是测试误差)的周期,因为这仍然是装配阶段而不是测试阶段的一部分。
下图描述了一折的几个循环:
被绿线包围的矩阵将被用于实际学习中,该学习使用已经优化的 k (参见步骤 7)。
完整的交叉验证功能有几个部分。下面介绍一些主要的方法。其余的可以在文章底部提到的完整笔记本中找到。
第一部分:每次折叠的准备 —主要是每次折叠准备面膜。
第二部分:矩阵初始化 —每个周期初始化 Y,A,X(屏蔽)。还初始化训练和测试误差值。
第三部分:更新——每次迭代更新 A 、 Y 和 X 的学习过程。
第四部分:结论 —收集所有结果,选出每次折叠的最佳周期和平均折叠误差。
步骤 5 —运行多个 k
这里,我们对不同的 k 使用 nmf_cv 函数。在学习期间,我们可以跟踪每个周期的训练和测试误差,以及每个折叠的最佳周期图。
下面是三个有代表性的图和各自的误差——左侧的欠拟合(过低 k )、中间的右 k 和右侧的过拟合。注意不同之处。
每 k 训练和测试误差的差异
然后我们提取最佳运行:
下图显示了每个 k 的训练和测试误差。正如我们所料,最佳的 k 是 5,这是由于我们在步骤 1 中创建样本数据时选择的潜在特征。在真实数据中,我们当然不知道这个数字。
对于某些 k (例如 k=8),测试误差非常高,似乎偏离了“完美”的测试误差曲线。为了克服这个问题,可以使用平方根或对数矩阵,以减少数字,并以此“控制”误差。
步骤 6 —捕获 A 和 Y
如前所述,给定的矩阵 X 可能具有完全不同的因子矩阵,不仅在形状上,而且在它们的值上。因此,对于不同的折叠,我们可以在相似的 X 矩阵中结束训练过程,但是非常不同的 A 和 Y 。参见 2×2 矩阵的示例:
同一 X 矩阵的不同组因子矩阵。
这意味着我们不能只对所有的 A 或 Y 求平均值。替代方法是使用其中一对(例如来自 fold 0 的 A 和 Y )。
步骤 7 —使用优化的 k 和捕获的 A / Y 矩阵进行训练
这是我们实际使用交叉验证结果的步骤:
-我们使用最佳 k(仅隐含地,AA/Y的形状假定为右 k )
-我们使用末端 A/Y 矩阵。由于这些是端矩阵,我们不必使用非常高的迭代次数。
功能:
我们得到了预测矩阵。我们可以将原始矩阵与预测矩阵(两者的左上角)以及非空值的误差进行比较:
现在是原文:
步骤 8-检查空值错误
因为我们知道缺失值(我们创建了原始矩阵),所以我们有机会检查算法预测缺失值的能力。
现在是原文:
步骤 9-合并 NMF 中缺失的值
这里我们得到了完整的矩阵。
重新加盖
如果没有交叉验证,我们就不可能知道要使用的 k 潜在特征,并且对于任何更高的 k 我们都会获得更好的列车性能,因为我们使用了所有的数据。
此外,随机矩阵可能会将我们引向局部优化点,而不是最佳点。通过使用最佳运行的末端 A/Y 矩阵,我们确保达到最小误差。
人们可以按原样使用该代码,或者根据特定需要对其进行修改,例如使用另一种算法。
完整的笔记本可以在https://github . com/ishaytelaviv/cross _ validation _ matrix _ completion/blob/master/cv _ for _ NMF _ sample 1 . ipynb中找到
如何在指环王社交网络上的 Neo4j 图形数据科学库中使用 Cypher 投影
原文:https://towardsdatascience.com/how-to-use-cypher-projection-in-neo4j-graph-data-science-library-on-a-lord-of-the-rings-social-b3459138c4f1?source=collection_archive---------39-----------------------
了解有关 cypher projection 的所有信息,以及如何使用它来投影虚拟图形
继续介绍上一篇博文中的 Neo4j Graph 数据科学库 graph catalog 特性,其中我们深入研究了原生投影,我们将在这篇博文中了解一下 Cypher 投影。它是图形投影的更具表现力的变体,也允许我们投影虚拟图形。
图形导入
我们将在 import 语句中使用 APOC 库中的一些程序。我已经习惯了总是有 APOC 在身边,我甚至很少单独提到它。它包含了许多令人敬畏的程序,很难想象没有它的生活。
导入节点
LOAD CSV WITH HEADERS FROM
"https://raw.githubusercontent.com/morethanbooks/projects/master/LotR/ontologies/ontology.csv" as row FIELDTERMINATOR "\t"
WITH row, CASE row.type WHEN 'per' THEN 'Person'
WHEN 'gro' THEN 'Group'
WHEN 'thin' THEN 'Thing'
WHEN 'pla' THEN 'Place' END as label
CALL apoc.create.nodes(['Node',label], [apoc.map.clean(row,['type','subtype'],[null,""])]) YIELD node
WITH node, row.subtype as class
MERGE (c:Class{id:class})
MERGE (node)-[:PART_OF]->(c);
导入关系
UNWIND ['1','2','3'] as book
LOAD CSV WITH HEADERS FROM
"https://raw.githubusercontent.com/morethanbooks/projects/master/LotR/tables/networks-id-volume" + book + ".csv" AS row
MATCH (source:Node{id:coalesce(row.IdSource,row.Source)})
MATCH (target:Node{id:coalesce(row.IdTarget,row.Target)})
CALL apoc.create.relationship(source, "INTERACTS_" + book,
{weight:toInteger(row.Weight)}, target) YIELD rel
RETURN distinct true;
Cypher 投影
使用密码投影的一般语法是:
CALL gds.graph.create.cypher(
graphName: String,
nodeQuery: String,
relationshipQuery: String,
configuration: Map
)
节点查询是一个 cypher 语句,用于描述我们想要投影的节点。它必须返回节点的内部 id,并且可选地返回它们的任何属性。另一方面,关系查询描述了我们想要投射的关系。cypher 语句应该返回关系的源和目标节点的内部 id,以及可选的它们的类型和它们的任何属性。
整个图表
我们将从一个简单的场景开始,并在内存中投影整个图形。在关系查询中添加列类型允许数据科学引擎区分关系类型,这反过来为我们提供了一个在执行算法时过滤关系的选项。
CALL gds.graph.create.cypher(
'whole-graph',
// nodeQuery
'MATCH (n) RETURN id(n) AS id',
// relationshipQuery
'MATCH (n)-[r]->(m) RETURN id(n) AS source, id(m) AS target, type(r) as type'
和之前的博文一样,我们将从弱连通分量算法开始。它用于检查我们的图中有多少孤岛或不连接的组件,这将帮助我们更好地理解不同图算法的结果。此外,有时我们可能希望只在最大的连通分量上运行其他图算法。
CALL gds.wcc.stream('whole-graph')
YIELD nodeId, componentId
RETURN componentId, count(*) as size
ORDER BY size DESC limit 10
结果
因为在我们的图中只有一个连通分量,所以我们不必担心来自其他图算法的扭曲结果。
从目录中删除投影图
每次分析后,我们将从内存中释放投影图。
CALL gds.graph.drop('whole-graph');
无向加权关系图
接下来,我们将投影一个无向加权图。让我们看看原生投影是如何处理无向关系的:
UNDIRECTED
:每种关系都以自然和相反的方向投射
为了使用 cypher projection 生成一个无向关系,我们在两个方向上投影一个关系,有效地允许图形数据科学引擎在两个方向上遍历它。让我们看一下下面的例子,以便更好地理解。我们创建了两个节点,它们之间只有一个连接。
CREATE (:Test)-[:REL]->(:Test);
为了向两个方向投射关系,我们只需在我们的匹配语句中省略关系的方向,就这样。一个微小但至关重要的细节!
MATCH (n:Test)-[r]-(m:Test)
RETURN id(n) as source, id(m) as target;
结果
我们还将展示一种在节点查询中使用 UNION 语句来投影多个节点标签的有利方式。
CALL gds.graph.create.cypher(
'undirected_interactions',
// nodeQuery
'MATCH (n:Person) RETURN id(n) AS id
UNION
MATCH (n:Thing) RETURN id(n) as id',
// relationshipQuery (notice no direction on relationship)
'MATCH (n)-[r:INTERACTS_1|:INTERACTS_2|:INTERACTS_3]-(m)
RETURN id(n) AS source, id(m) AS target,
type(r) as type, r.weight as weight')
随机行走算法
为了摆脱 PageRank 或 Louvain 等常见的图算法,让我们使用随机行走算法。本质上,它模拟了一个喝醉的人如何穿过我们的图表。它通常用于 node2vec 算法中。我们定义佛罗多为起始节点,然后随机走五步两次。
MATCH (n:Node{Label:'Frodo'})
CALL gds.alpha.randomWalk.stream('undirected_interactions',
{start:id(n), steps:5, walks:2})
YIELD nodeIds
RETURN [nodeId in nodeIds | gds.util.asNode(nodeId).Label] as result
结果
你会得到不同的结果,因为这毕竟是一个随机游走算法。
三角形计数和聚类系数
另一个分析社交网络的有用算法是三角形计数和聚类系数算法。三角形由三个节点组成,其中每个节点都与另外两个节点有关系。聚集系数是对图中节点聚集程度的度量。这使我们能够估计图表中节点的紧密程度。
CALL gds.alpha.triangleCount.write('undirected_interactions',
{relationshipTypes:['INTERACTS_1'],
writeProperty:'triangles',
clusteringCoefficientProperty:'clustering'})
YIELD nodeCount, triangleCount, averageClusteringCoefficient
结果
全局或平均聚类系数是 0.54,这意味着我们图表中的人非常紧密。我们也可以看看个体和他们的局部聚类系数。
MATCH (p:Person)
RETURN p.Label as person,
p.clustering as coefficient,
p.triangles as triangles
ORDER BY coefficient DESC LIMIT 5
结果
让我们想象一下特伦和他的关系,观察他们是如何形成一个紧密的社区的。
Thrain 的所有联系人也相互影响,因此聚类系数的值为 1.0。
从目录中删除投影图
CALL gds.graph.drop('undirected_interactions');
分类页面排名
到目前为止,所有上述图形分析都可以用本地投影来完成。Cypher projection 可以投影仅在查询时存在的图形,或者当我们希望使用比节点标签或关系类型更高级的过滤时。
分类页面排名(Categorical PageRank)是由肯尼·巴斯塔尼(Kenny Bastani)在他的博客文章中首次提出的概念。我还用图算法库写了一篇关于它的博文。现在是时候用图形数据科学库来展示它了。
来源:Kenny Bastani发布的分类页面排名
背后的想法很简单。如上例所示,我们有一个页面图,这些页面之间有链接,并且可能属于一个或多个类别。为了更好地理解网络中节点的全局 pagerank 分数,我们可以将我们的图分解成几个子图,每个子图对应一个类别,并对每个子图执行 pagerank 算法。我们将结果存储为类别和页面之间的关系属性。这样,我们可以分解哪些类别对 page 的全球 pagerank 得分有贡献。
我们会从假设每一次互动都是积极的背书开始(我知道其实不是,我们就假装吧)。我们将根据角色所属的类别(人类,精灵)把我们的图表分解成几个子图表。例如,在计算男性类别的 pagerank 时,将考虑所有节点。然而,只有来自属于男人阶层的角色的关系才会被考虑。
CALL gds.graph.create.cypher(
'categorical_men',
// nodeQuery
'MATCH (n:Person) RETURN id(n) AS id
UNION
MATCH (n:Thing) RETURN id(n) as id',
// relationshipQuery
'MATCH (c:Class)<-[:PART_OF]-(n)-[r:INTERACTS_1|:INTERACTS_2|:INTERACTS_3]-(m)
// Use the parameter
WHERE c.id = $class
RETURN id(n) AS source, id(m) AS target,
r.weight as weight,type(r) as type',
{parameters: { class: 'men' }})
现在让我们在这张图上运行加权 pageRank。
CALL gds.pageRank.stream('categorical_men',
{relationshipWeightProperty:'weight'})
YIELD nodeId, score
RETURN gds.util.asNode(nodeId).Label as name, score
ORDER BY score DESC LIMIT 5
结果
甘道夫名列第一,阿拉贡紧随其后。我想知道阿拉贡在第三部中是否得到了大多数人的支持,因为他在最后成为了他们的国王。
CALL gds.pageRank.stream('categorical_men',
{relationshipTypes:['INTERACTS_3'],
relationshipWeightProperty:'weight'})
YIELD nodeId, score
RETURN gds.util.asNode(nodeId).Label as name, score
ORDER BY score DESC LIMIT 5
结果
不出所料,阿拉贡领先。佛罗多已经不在名单上了,因为他在第三部中与所有人都隔离开来,独自和山姆一起走向末日火山。老实说,如果有山姆在你身边,你永远不会感到孤独。
从目录中删除投影图
CALL gds.graph.drop('categorical');
虚拟分类图
我们只研究了男人的类别,并计算了特定子图的分类 pagerank。如果我们分别为每个类投影一个子图,这将非常耗时。这就是为什么我们将使用虚拟关系类型在单个命名图中为每个类投影一个子图。在关系查询中,我们可以选择以列类型的形式返回我们想要的任何内容。我们将返回原始的关系类型,并结合人的类来创建虚拟的关系类型。这将允许我们计算每个类的分类 pagerank。
CALL gds.graph.create.cypher(
'categorical_virtual',
'MATCH (n:Person) RETURN id(n) AS id
UNION
MATCH (n:Thing) RETURN id(n) as id',
'MATCH (c:Class)<-[:PART_OF]-(n)-[r:INTERACTS_1|:INTERACTS_2|:INTERACTS_3]-(m)
RETURN id(n) AS source, id(m) AS target,
type(r) + c.id as type, r.weight as weight')
我们现在可以计算精灵类的分类 pagerank。
CALL gds.pageRank.stream('categorical_virtual',
{relationshipTypes:['INTERACTS_1elves','INTERACTS_2elves','INTERACTS_3elves'],
relationshipWeightProperty:'weight'})
YIELD nodeId, score
RETURN gds.util.asNode(nodeId).Label as name, score
ORDER BY score DESC LIMIT 5
结果
如果我们想要计算每个类的分类 pagerank 并存储结果,我们可以使用与最初的博客文章中相同的方法,我们将结果保存在类和人之间的关系中。
MATCH (c:Class)
CALL gds.pageRank.stream('categorical_virtual',
{relationshipTypes:['INTERACTS_1'+c.id,'INTERACTS_2'+c.id,'INTERACTS_3'+c.id],
relationshipWeightProperty:'weight'})
YIELD nodeId, score
WITH c, gds.util.asNode(nodeId) as node, score
// 0.15 is the default value for nodes with no incoming links
WHERE score > 0.151
CREATE (c)-[:PAGERANK{score:score}]->(node)
现在,我们可以根据类别 pagerank 得分获得每个类的前三名成员。
MATCH (c:Class)-[s:PAGERANK]->(p:Person)
WITH c, p, s.score as pagerank
ORDER BY pagerank DESC
RETURN c.id as class,
collect(p.Label)[..3] as top_3_members
结果
佛罗多以四个第一领先,甘道夫三个第一,山姆两个第一。大多数结果都是不言自明的,就像甘道夫领导的矮人班的支持,吉姆利自己是个矮人排在第二位,所以他可能和所有其他矮人都有互动。因为勒苟拉斯经常和吉姆利在一起,所以他排在第三位。另一方面,山姆和弗罗多独自冒险进入兽人土地的中心,与兽人的互动最多(不是真正的代言)。
从目录中删除投影图
CALL gds.graph.drop('categorical_virtual');
结论
Cypher projection 非常有表现力,它允许我们投影存储图的任何子图以及只在查询时存在的任何虚拟图。我们大多只是被我们的想象力所限制。亲自尝试一下图形数据科学库,如果您有任何建议或反馈,请告诉我们。
和往常一样,代码可以在 GitHub 上获得。