Polygon.io 查看-检索历史刻度数据
演练日内策略的分笔成交点数据 API 方法
来源:polygon.io 网站。经许可使用
在过去的几个月里,我的主要目标之一,也是最耗时的任务之一,是从分笔成交点数据中提取优势,用于日内操作。
在这种情况下,高质量的数据输入变得极为重要。我已经开始使用 Polygon.io 从 SPY 获取分笔成交点数据,因为我想测试我在过去几个月中学习的一套自主策略。这些策略旨在对期货进行操作,但我想评估它们是否适用于其他资产/工具,如间谍 ETF 和外汇工具。
本文涵盖了通过 REST API 检索历史数据。我还将简要介绍一下所涉及的数据量。
报价和交易
您需要理解的第一件事是,分笔成交点数据通常涉及两个独立的数据源。一个覆盖账簿的顶部,包括最佳买价和最佳卖价,另一个覆盖实际交易。在股票市场(SPY 是一种 ETF,但 ETF 是作为股票交易的),可以在不同的交易所进行交易。这意味着没有交易发生的中心点。美国目前有 13 家上市交易所。并非所有的资产都在每个交易所交易,但它们也不会只在一个交易所交易。还有暗池和私人交易所,机构玩家可以跨单,大型券商也可以在客户之间跨单。
这意味着单一、统一、连续和独特的报价和交易流的简化视图在现实世界中并不存在。
所有市场信息由证券信息处理器(SIPs)整合,SIPs 是受监管的实体,整合并提供统一的股票数据。它们定义了一套清晰而确定的交易合并规则。美国的两家运营中的 sip 是联合磁带协会 (CTA)和非上市交易特权 (UTP)。这些 sip 分别巩固了纽约证券交易所和纳斯达克上市的代码。关于它们如何工作的很好的信息可以在这篇博客文章中找到。
虽然这些信息对散户交易者来说并不重要(很少有人理解这些晦涩难懂的东西是如何运作的),但有几个重要的要点需要了解:
- 股票在不同的地方交易,所以它们不是完全集中的。你所看到的高质量的实时数据只是市场上实际发生的事情的一个像样的代理。
- 不同的时间戳在 SIP 和交换机处关联信息。它们与零售无关,但与交易的买价/卖价相关(如订单流和 Delta 分析所要求的)。
对于书的深度来说,情况是一样的,但是我不会去讨论它,因为现在我不会在我的任何策略中分析书的深度。
历史报价(NBBO 出价/要价)
为了获得历史报价,使用**/v2/ticks/stocks/nbbo/{ ticker }/{ date }**请求
可以通过它们的 REST API 接口从 Polygon 中检索历史数据。服务器将为每个请求提交最多 50,000 条记录。虽然 OHLC 每日数据的 50,000 条记录代表了 200 多年的股票市场历史,但这只是分笔成交点数据的每日数据量的一小部分。
URL 中包含基本的日期和报价器参数:
ticker:string, ticker name (i.e. SPY for SPDR S&P500 ETF)date:string, date in YYYY-MM-DD format. Notice that the API assumes Eastern Time by default, so 2020-06-15 means 2020-06-15 00:00 New York time.
经过长期(通常是痛苦的)时区工作后,我得出结论,一个简单且一致的方法是在 et 中存储和处理你所有的市场数据。它被广泛用作市场数据的参考时区(有时甚至用于欧洲资产/工具),也是金融市场的标志性时间参考(纽约证券交易所 RTH 开盘是每个人每天都可以观察到的事件)。这不适用于加密数据,因为它 24x7 全天候运行,当从夏令时切换到非夏令时时,您将面临问题。在这种情况下,建议使用 GMT。
API 在这里有完整的文档,但是我强调/评论以下参数。注意,这些被指定为 HTTP GET 参数,而不是 URL 的一部分。
timestamp:long value, represents the first epoch timestamp (with nanoseconds resolution) for which data is requested. timestampLimit:long value, represents the last epoch timestamp (with nanoseconds resolution) for which data is requested, provided that the hard limit of 50,000 (or the custom limit) is not reached first. Note that this timestamp is returned, so the value is included.limit:integer value, maximum number of records to be retrieved, 50,000 if not specified.apiKey:string, your API key, required in every request.
因为我们有 50,000 项的限制,所以需要执行分页。为了执行分页,我们将简单地使用时间戳参数。算法非常简单:如果我们收到 50,000 个条目,我们假设需要一个额外的请求,我们指定最近收到的时间戳作为下一个请求的参数。我们这样做,直到最后一个请求收到少于 50,000 个项目。这意味着没有更多的请求要做。
必须考虑三个具体细节:
- 将 timestampLimit 设置为第二天的 00:00 时间是个好主意。由于 API 将 timesetampLimit 作为有效的返回项,我们需要稍后从返回的结果中排除该值。
- 用于连续请求的时间戳被包含两次,因为它是第 n 和第 n+1 个请求之间的边界。因此,当计划一个 n+1 请求时,将其从 n 请求中移除是很重要的。
- 可能的情况是,我们收到 50,000 个项目,而这些正是所有可用的数据。在这种情况下,我们的算法将请求一个只返回一个结果的新批次。这不是问题,这是算法分页的一部分。
一种替代方法是为连续请求的时间戳请求增加 1 纳秒;理论上,这将避免在后续请求中出现重复。因为我不能 100%确定可以接收到相同纳秒时间时间戳的两个记录,所以我决定不走这条路,因为前一条路可以处理相同时间戳的多个记录的情况。
报价和交易都使用完全相同的算法(并且可以在单独的共享方法/例程中编码)。
历史贸易
为了获得历史交易,使用**/v2/ticks/stocks/trades/{ ticker }/{ date }**请求
如前所述,历史交易可以类似地检索。同样的条件和参数也适用。
内存/存储要求的简要回顾
历史交易几乎总是在本地存储和处理,以避免开销。可以按需请求更高的时间范围,但是在每次回溯测试迭代中按需请求几个月的历史 tick 数据是不切实际的。
我总是试图用原始数据存储一个易于阅读和解析的文件,如果可能的话,使用 ASCII 文本文件。在这个例子中,我们创建了两个文件(报价和交易)。
user[@almaz](http://twitter.com/almaz):~/NetBeansProjects/SealionPolygonAdapter % java -jar dist/SealionPolygonAdapter.jar
1592387342715007986
1592393505203343776
1592398291430866793
...
1592419244447798705
1592421981410064896
1592423485600194378
1592423485600194378[user@almaz](http://twitter.com/almaz):~/NetBeansProjects/SealionPolygonAdapter % ls -lh data/*
-rw-r--r-- 1 user user 399M Jun 21 19:04 data/SPY.2020-06-17.quote.json
-rw-r--r-- 1 user user 54M Jun 21 19:05 data/SPY.2020-06-17.trade.jsonuser[@almaz](http://twitter.com/almaz):~/NetBeansProjects/SealionPolygonAdapter % head data/SPY.2020-06-17.quote.json
{"p":313.9,"P":315,"q":9801,"c":[1,81],"s":2,"S":1,"t":1592380800048084434,"x":12,"X":11,"y":1592380800047963904,"z":1}
{"p":313.9,"P":315,"q":9901,"c":[1,81],"s":2,"S":5,"t":1592380800048834673,"x":12,"X":11,"y":1592380800048768512,"z":1}
{"p":313.9,"P":315,"q":10001,"c":[1,81],"s":2,"S":6,"t":1592380800048839409,"x":12,"X":11,"y":1592380800048774400,"z":1}
...
数据被存储为每行一个 JSON 对象,这很容易解析(注意,这在存储和性能方面也是低效的)。它每天使用大约 450Mb,每年大约 100Gb 的数据。如果您存储许多资产,一个关键因素是要注意整数压缩算法。使用专有和优化的数据库将节省空间,尽管作为一种权衡,它在开发和调试工作方面有成本,并且增加了操作的复杂性。我仍然喜欢对可读数据进行简单的备份,即使我进一步将数据转换成性能更友好的格式。
我们还可以注意到每个交易日涉及的数据量:
user@almaz:~/NetBeansProjects/SealionPolygonAdapter % wc data/SPY.2020-06-17.quote.json
3060489 3060489 418579482 data/SPY.2020-06-17.quote.jsonuser@almaz:~/NetBeansProjects/SealionPolygonAdapter % wc data/SPY.2020-06-17.trade.json
435989 435989 56996300 data/SPY.2020-06-17.trade.json
SPY 在一天之内有 300 万个报价点和超过 40 万个交易点。
为了在任何回溯测试或定制工具中使用数据,可能需要进一步的处理,但是正如本文开头提到的,将数据存储在简单的 ASCII 可读数据中作为永久备份是有用的。这将简化开发和转换时间,并将数据历史提供者从我们分析工具链中分离出来。
一个简单而有效的改进方法是压缩两个档案。在这种情况下,我们得到:
user@almaz:~/NetBeansProjects/SealionPolygonAdapter % gzip data/SPY.2020-06-17.quote.json
user@almaz:~/NetBeansProjects/SealionPolygonAdapter % gzip data/SPY.2020-06-17.trade.json
user@almaz:~/NetBeansProjects/SealionPolygonAdapter % ls -lh data/*
-rw-r--r-- 1 user user 54M Jun 21 19:04 data/SPY.2020-06-17.quote.json.gz
-rw-r--r-- 1 user user 9.2M Jun 21 19:05 data/SPY.2020-06-17.trade.json.gz
仅仅通过使用标准的 gzip 工具,我们每天只能得到 64Mb,每年需要大约 16Gb。更友好的存储大小,无需特殊资源即可轻松实现。
压缩和解压缩需要时间,因此这只能用作永久数据备份。
源代码
下面是检索历史报价(报价和交易)的源代码的基本版本,作为参考。请注意,该代码是测试版,没有经过优化,它旨在展示 Java 中的一个用例,阐明如何访问历史分笔成交点数据。它可以很容易地移植到其他语言。
数据以 JSON 格式检索,这种格式便于调试。代价是 JSON 远不是一种有效格式。对于一个历史数据检索 API,我认为这是不相关的,尤其是在为了回溯测试的目的而以批处理方式检索数据的情况下。在这种情况下,JSON 提供的简单性和可维护性是明显的优势。
对于这个特定的实现,我使用了 simple-json v1.1.1 作为解析 json 的配套库。这个库在它的版本 1 中不再被维护,但是它是一个完全工作的库,使用起来非常简单,并且是轻量级的。
主类:检索并存储 2020 年 6 月 17 日 SPDR 间谍 ETF 的 BidAsk 和 Trades
HistoricalRequest 类包含检索每日竞价和交易并将它们存储到磁盘的方法。
如何重用您的 Python 模型而无需重新训练它们
Python 的对象序列化库简介
注:在计算机科学中,保存一个对象以备后用的过程叫做 序列化 ,而加载一个保存的对象叫做 反序列化 。
作为一名数据科学家,您可能希望重用您的一个模型,而不必重新训练它。
避免需要重新训练你的模型是特别有用的,因为它允许“部署”模型,即把你训练好的模型转移到一个公共服务器上,任何有互联网连接的人都可以查询预测。
例如,假设您已经创建了一个简单的 scikit-learn 模型,您希望保存它并在以后重用它。
>>> from sklearn.datasets import load_iris
>>> from sklearn.tree import DecisionTreeClassifier
>>> model = DecisionTreeClassifier()
>>> X, y = load_iris(return_X_y=True)
>>> clf = model.fit(X,y)
在这种情况下,我们的训练模型存储在 Python 对象clf
中。
为了保存clf
对象供以后重用,我们将使用内置的pickle
库。
>>> import pickle
>>> with open('clf.pickle', 'wb') as f:
... pickle.dump(clf, f)
我们通过指定wb
用“写字节模式”打开了一个名为clf.pickle
的文件,并且我们已经在变量f
中存储了对该文件的引用。
然后,我们使用pickle.dump
方法将对象clf
保存在文件clf.pickle
中。在幕后,Python 实际上将clf
对象转换成一系列字节,稍后它可以将这些字节转换回原始的clf
对象。
您可以检查工作目录的内容现在包含一个名为clf.pickle
的文件。
>>> import os
>>> os.listdir()
['clf.pickle']
如果您通过键入exit()
退出当前的 Python 会话,然后启动一个新的 Python 提示符,那么您可以重新加载clf
对象来恢复训练好的模型。
>>> import pickle
>>> with open('clf.pickle', 'rb') as f:
... clf = pickle.load(f)
>>> type(clf)
sklearn.tree._classes.DecisionTreeClassifier
注意我们如何通过指定rb
以“读取字节”模式打开文件clf.pickle
,然后将对该文件的引用存储在变量f
中。
然后,pickle.load
能够读取文件clf.pickle
并返回一个新的对象,该对象与我们最初传递给pickle.dump
的clf
对象完全相同。
任何 Python 对象都可以使用 pickle.dump 保存到一个文件中,并且可以使用
**pickle.load**
从文件中加载完全相同的对象
因此,我们可以使用从文件中加载的新的clf
对象在中进行预测,就像我们使用原始的clf
对象进行预测一样。
>>> clf.predict([
... [1,1,0,0],
... [1,0,1,1]
... ])
[0,0]
当然,将训练好的模型保存到本地目录中的文件意味着其他人将不能重用该模型。将训练好的模型保存到其他程序可以访问的数据库中会更方便。
将腌制模型保存到数据库中
pickle 模块允许将对象转换为内存中的字节,然后我们可以用它将训练好的模型保存在数据库中。
>>> pickled_clf = pickle.dumps(clf)
>>> type(pickled_clf)
bytes
请注意我们如何使用pickle.dumps
方法,即“ dump s tring”,而不是pickle.dump
方法。
dumps
方法直接返回一个字节的对象pickled_clf
,而不是将其写入文件。(dumps
方法的命名被选择为与其他序列化库一致,并且它不返回str
类型对象)。
我们现在可以将pickled_clf
字节对象直接保存到数据库中。
例如,假设我们有一个名为db.sqlite3
的 sqlite3 数据库,其中包含一个名为models
的表,该表带有一个BLOB
(即字节)字段。
sqlite3 db.sqlite3 "create table models(name TEXT, data BLOB);"
为了将经过酸洗的模型保存到那个表中,我们可以使用sqlite3
模块。
>>> import sqlite3
>>> conn = sqlite3.connect('db.sqlite3')
>>> query = 'insert into models values (?, ?)'
>>> conn.execute(query, ['clf', pickled_clf])
>>> conn.commit()
然后,我们可以从数据库中重新加载 pickled 对象,然后将 bytes 对象转换回原始模型。
>>> cursor = conn.execute('select * from models')
>>> name, pickled_clf = cursor.fetchone()
>>> clf = pickle.loads(pickled_clf)
注意我们是如何使用pickle.loads
方法加载分类器的。正如我们使用pickle.load
来恢复用pickle.dump
保存的对象一样,我们也可以使用pickle.loads
来恢复用pickle.dumps
保存的对象。
现在,您可以重用该模型,而无需重新训练它。
>>> clf.predict([
... [1,1,0,0],
... [1,0,1,1]
... ])
[0,0]
感谢阅读!如果你觉得这个教程有用,我在 Medium 上写了关于 Python 和数据科学的技巧,所以你可以关注我来获得更多类似的文章。
您今天就可以开始使用的新改进
towardsdatascience.com](/top-features-of-pandas-1-0-26abff08d1b6) [## 你可能还不知道的 3 个 Python 列表理解技巧
列表理解不仅仅是为了列表
levelup.gitconnected.com](https://levelup.gitconnected.com/3-python-list-comprehension-tricks-you-might-not-know-yet-5891d904ee76)
如何修改你的营销组合模型来捕捉新冠肺炎的影响?
现实世界中的数据科学
你可以做 5 件事来评估新冠肺炎的影响力,并让你的营销组合模型重新发挥作用
C OVID-19 震惊了世界,不可避免地改变了人们的工作、购物和生活方式。它不仅推动了经济的发展,还对广大广告客户的营销方式产生了重大影响。Influencer Marketing Hub 最近公布的新冠肺炎营销报告称,69%的品牌表示他们将在 2020 年减少广告支出。他们调查的公司中有 74%放慢了社交媒体发布的速度。
毫无疑问,削减营销支出将确保短期生存,并给陷入困境的企业带来微弱的复苏机会。然而,严格衡量你的营销业绩,让每一美元都推动更多的销售比以往任何时候都更加重要和必要。在今天的帖子中,我们将讨论如何更好地评估新冠肺炎·疫情领导下的营销效率。
衡量营销效率的方法
为了评估营销绩效和优化渠道组合,我们需要回答的最重要的问题是,我们在每个渠道上投入的资金获得了什么样的投资回报(ROI)。营销组合模型和多接触归因是流行的技术,往往能提供回答这个问题所需的深度见解。
我更倾向于使用营销组合模型来评估新冠肺炎疫情期间的营销投资回报率,原因有二。
首先,多点接触归因是一种自下而上的评估营销效果的方法。它专注于在线营销和销售,更擅长分析实时用户数据。营销组合建模更多地采用自上而下的宏观视角,而不是评估用户最终转化的每个接触点。因此,不仅可以检查和捕捉营销相关因素,还可以检查和捕捉宏观经济、季节性、天气和竞争影响等因素。从这个角度来看,前所未有的新冠肺炎疫情不在每个人的正常控制范围内,MMM 可以更好地捕捉到它的影响。
此外,MTA 主要专注于数字生态系统,而 MMM 可以轻松覆盖更多线下渠道。鉴于冠状病毒,人们被困在家里。这最终推动了电视收视率的上升。根据 eMarketer 的最新预测,传统电视预计今年将增加 830 万美国观众,这将是自 2012 年以来传统电视观众首次增加👀。因此,与 MTA 相比,MMM 在衡量电视节目效果方面可能做得更好。
建立营销组合模型简介
一般来说,MMM 采用多元线性回归原理,试图在您的目标 KPI(因变量)和一组将影响您的 KPI 的驱动因素(自变量)之间形成一个方程。
您的候选驱动因素最终可分为以下两大类:
- **不可控因素:**我们无法控制的外部因素,包括宏观经济、季节性、节假日、天气等。
- **可控因素:**我们可以调整和优化的媒体和营销相关指标。
通常,那些不可控因素与你的目标 KPI 呈线性关系,这意味着这些因素每增加一个单位都会改变你的 KPI 一定的量(这种改变可以是负的,也可以是正的)。然而,对于媒体和营销相关的驱动因素,它们的影响是非线性的,必须考虑三个独特的参数。它们是滞后效应、结转效应(Adstock)和收益递减。
- 滞后效应意味着你的广告转化顾客需要多长时间。如果我们将销售收入作为目标 KPI,来自社交媒体参与等漏斗下端渠道的滞后效应将比来自电视和广播等漏斗上端渠道的滞后效应更短,这些渠道旨在提高知名度和激发兴趣。
Jakob Owens 在 Unsplash 上拍摄的照片
- 结转效应(Adstock) 本质上被描述为广告将随着时间的推移而扩散,并在发生后对你的 KPI 产生持续的影响。比方说,如果你在 Instagram 上看到一个购物广告,在接下来的日子里,你仍然会记得那些创意图片,但记忆已经褪色。
Adstock 的公式为: At = Xt + Adstock Rate * At-1
要查看更多关于 Adstock 的详细信息,请点击这里查看群邑在消费电子、零售、金融、汽车和消费品行业的营销组合模式
- 收益递减原本是一个经济学原理,这里有一个非常经典的例子来阐述它:当你饥饿的时候,你从吃第一个汉堡中获得的效用会高于下一个汉堡带给你的效用。
将这一定律应用到营销绩效的测量中,它表明每花一美元在广告上,它将提升你的 KPI,但以递减的速度。
照片由 Denys Nevozhai 在 Unsplash 上拍摄
这三个参数的值因通道而异。并且当驱动不同的 KPI 时或者在不同的时间段期间,即使对于相同的通道,它们也不会相同。因此,它们不是预先决定或预先假设的。相反,它涉及迭代模型训练和测试,以获得在特定时期影响特定 KPI 的每个渠道的这三个参数的最理想组合。
多元回归模型使我们能够轻松识别影响您的目标 KPI 的重要驱动因素,并用系数量化它们的影响。
如何捕捉新冠肺炎的影响力并修改你的 MMM?
由于新冠肺炎是一个前所未有的情况,类似的影响从未在您的模型中捕获和评估过,因此会使您的 MMM 不能很好地运行。您可能已经意识到,如果应用冠状病毒爆发前建立的 MMM 进行预测,您将会看到与实际相比的极高错误率。如果不考虑冠状病毒的影响,你的营销效率也会被错误地评估。
如何修改我们的 MMM 来捕捉新冠肺炎的影响?这里有一些你可以尝试的选择。
- 新冠肺炎虚拟变量
这是将冠状病毒影响作为外部因素纳入你的模型的一种非常直接和简单的方法。哑变量最大的警告是,它只取值 0 或 1 来表示某些因素的存在或不存在。然而,我们不知道疫情什么时候会走到尽头,它很有可能永远不会消失。此外,新冠肺炎的影响是动态的,它使曲线变平,而不是固定值。因此,具有 0 或 1 的虚拟变量不能完全和准确地拾取衰减的影响。
*图片由作者提供:0/1 虚拟变量。为了便于说明,图表中的数字是任意的
- 新冠肺炎相关指标
为了更好地捕捉来自新冠肺炎的动态影响,我们可以直接获取疫情相关指标,如每日增量和累积确诊病例数、恢复或死亡等。作为代理人。谷歌已经在谷歌云平台中提供了免费的公共数据集。你可以去这里查看更多细节。
- 宏观经济指数
冠状病毒,一个黑天鹅事件,导致了严重的经济萎缩。因此,除了新冠肺炎相关指标,我们还可以间接利用一些宏观经济指数来估计影响。最直观的就是失业率。由于冠状病毒,4 月份美国失业率飙升至 14.7%,为大萧条以来的最高水平。数据可以从美国劳工统计局获得,也可以很容易地下载。
使用失业率的一个限制是,数据通常按月刷新和公布。因此,它可能无法完全反映每日或每周的波动和变化。
除此之外,考虑到股市一直被视为经济晴雨表,股市中的指数如 S & P 500 和道琼斯也是潜在的候选。雅虎财经是我经常去下载这些指数数据的地方。
由 Markus Spiske 在 Unsplash 上拍摄的照片
- 反事实分析
上述代理可能有助于捕捉你的业务一般上下。事实上,他们可能无法完美地捕捉到你的趋势。另一种获得特定于您的业务的新冠肺炎影响指标的潜在方法是利用冠状病毒爆发前建立的 MMM 进行反事实估计。具体来说,反事实分析测量没有新冠肺炎会发生什么,因此我们可以通过比较实际观察到的表现和反事实结果来量化其影响。
*作者图片:反事实分析。为了便于说明,图表中的数字是任意的
你可能会问,如果你以前没有做过 MMM,如何进行反事实分析?我们可以使用疫情之前的历史数据来利用 R 中的预测包。以下是进行预测的示例代码。
library(forecast)#Step 1: Convert sales data into time series. Here is using 2-year data to forecast next yearts <- ts(sales$Sales[sales.Period >= '2018-01-01' & sales.Period <='2019-12-31'])#Step 2: Fitting an auto.arima model in R using the Forecast package
sales<- auto.arima(ts)
pred <- forecast(object = sales, h = 365)
到目前为止,我们已经讨论了四种方法来得出新冠肺炎指标,并衡量其作为外部因素的影响。然而,新冠肺炎不仅从外部影响我们的业务,而且从根本上影响营销效率和效果。有鉴于此,你还需要做些什么来修改你的营销组合模式,以适应疫情期间不同的营销效果?
您需要通过将媒体和营销指标分成两部分,用最新数据重新训练您的营销组合模型。通过这样做,我们可以在新冠肺炎前后获得不同的系数,并跨营销渠道计算相应的投资回报率。
*作者图片:拆分营销指标。为了便于说明,图表中的数字是任意的
在下一篇文章中,我们将讨论如何利用 R 来建立一个基于你的营销组合模型结果的迷你优化器,并提高你的营销效率。💖
如何用熊猫用 Python 重写 SQL 查询
在 Python 中再现相同的 SQL 查询结果
照片由 Hitesh Choudhary 在 Unsplash 上拍摄
我们中的一些人熟悉 SQL 中的数据操作,但不熟悉 Python,我们倾向于在项目中频繁地在 SQL 和 Python 之间切换,导致我们的效率和生产力降低。事实上,我们可以使用 Pandas 在 Python 中实现类似的 SQL 结果。
入门指南
像往常一样,我们需要安装熊猫包,如果我们没有它。
conda install pandas
在本次会议中,我们将使用 Kaggle 著名的泰坦尼克号数据集。
在安装包和下载数据之后,我们需要将它们导入到 Python 环境中。
我们将使用 pandas 数据帧来存储数据,并使用各种 pandas 函数来操作数据帧。
选择、不同、计数、限制
让我们从我们经常使用的简单 SQL 查询开始。
titanic_df[“age”].unique()
将在这里返回唯一值的数组,所以我们需要使用len()
来获得唯一值的计数。
选择,WHERE,OR,AND,IN(带条件选择)
学完第一部分后,你应该知道如何用简单的方法探索数据框架。现在让我们尝试一些条件(也就是 SQL 中的WHERE
子句)。
如果我们只想从数据框中选择特定的列,我们可以使用另一对方括号进行选择。
注意:如果您选择多列,您需要将数组
["name","age"]
放在方括号内。
isin()
的工作方式与 SQL 中的IN
完全相同。要使用NOT IN
,我们需要使用 Python 中的否定(~)
来达到相同的结果。
分组依据、排序依据、计数
GROUP BY
和ORDER BY
也是我们用来探索数据的流行 SQL。现在让我们用 Python 来试试这个。
如果我们只想对计数进行排序,我们可以将布尔值传递给sort_values
函数。如果我们要对多列进行排序,那么我们必须将一个布尔值数组传递给sort_values
函数。
sum()
函数将为我们提供数据帧中的所有聚合数字总和列,如果我们只需要一个特定的列,我们需要使用方括号指定列名。
最小值、最大值、平均值、中间值
最后,让我们尝试一些在数据探索中很重要的常用统计函数。
由于 SQL 没有中位数函数,所以我将使用 BigQuery APPROX_QUANTILES
来获得年龄的中位数。
熊猫聚合功能.agg()
还支持sum
等其他功能。
现在你已经学会了如何**用熊猫用 Python 重写你的 SQL 查询。**希望这篇文章对你有用。如果我犯了任何错误或错别字,请给我留言。
可以在我的 Github 中查看完整的脚本。干杯!
如果你喜欢读这篇文章,你可能也会喜欢这些:
轻松在 Python 2 和 Python 3 环境之间切换
towardsdatascience.com](/manage-your-python-virtual-environment-with-conda-a0d2934d5195) [## 如何使用 Python 发送带附件的电子邮件
作为一名数据分析师,我经常会收到这样的请求:“你能每周给我发一份报告吗?”或者…
towardsdatascience.com](/how-to-send-email-with-attachments-by-using-python-41a9d1a3860b)
你可以在 Medium 上找到我其他作品的链接,关注我 这里 。感谢阅读!
如何在 Kubernetes (AWS EKS)运行 PySpark 作业
关于使用 Terraform 部署 EKS 集群和使用 Spark 操作符运行 PySpark 作业的完整教程
萨姆森在 Unsplash.com 拍摄的照片
在本教程中,我们将重点关注在 AWS EKS 上端到端部署 Spark 应用程序。我们将执行以下步骤:
- 在 AWS 中的定制 VPC 内部署 EKS 集群
- 安装火花操作器
- 运行一个简单的 PySpark 应用程序
TL;博士: Github 代码回购
步骤 1:部署 Kubernetes 基础设施
要在 AWS 上部署 Kubernetes,我们至少需要部署:
- VPC、子网和安全组负责集群中的网络
- EKS 控制平面主要运行 Kubernetes 服务,如
etcd
和Kubernetes API
- EKS 工人节点能够运行 pod 和更具体的针对我们案例的 spark 作业
让我们深入研究 Terraform 代码。首先,让我们看看 VPC:
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "2.6.0"name = join("-", [var.cluster_name, var.environment, "vpc"])
cidr = var.vpc_cidr
azs = data.aws_availability_zones.available.names
private_subnets = [var.private_subnet_az_1, var.private_subnet_az_2, var.private_subnet_az_3]
public_subnets = [var.public_subnet_az_1, var.public_subnet_az_2, var.public_subnet_az_3]
enable_nat_gateway = true
single_nat_gateway = false
one_nat_gateway_per_az = true
enable_dns_hostnames = true
enable_dns_support = truetags = {
"kubernetes.io/cluster/${var.cluster_name}" = "shared"
}public_subnet_tags = {
"kubernetes.io/cluster/${var.cluster_name}" = "shared"
"kubernetes.io/role/elb" = "1"
}private_subnet_tags = {
"kubernetes.io/cluster/${var.cluster_name}" = "shared"
"kubernetes.io/role/internal-elb" = "1"
}
}
VPC 是一个孤立的网络,其中可以有不同的基础架构组件。我们可以将这个网络分解成更小的块,在 AWS 上我们称之为子网。有些子网可以访问互联网,这就是我们称之为公共子网的原因,而有些子网不能访问互联网,则称为私有子网。我们将在网络流量上下文中使用的另一个术语是出口和入口。出口是指从网络内部流向外部世界的流量,以及从外部世界流向网络的入口流量。如您所料,这些规则可能会因用例而异。我们还使用安全组,这是 VPC 内部的流量规则,它定义了 EC2 实例如何相互“对话”,基本上是在哪些网络端口上。
对于 Spark EKS 集群,see 将为工作线程使用专用子网。所有的数据处理都是在完全隔离的情况下完成的。但是我们需要到互联网的出口流量,以进行更新或安装开源库。为了支持互联网流量,我们在 VPC 中使用 NAT 网关。我们必须将它们添加到公共子网中。在地形代码中,这是使用标志enable_nat_gateway.
完成的
我们可以注意到的另一件事是,我们使用了三个公共和私有子网。这是因为我们希望拥有网络容错能力。子网部署在一个区域的不同可用性区域中。
标签是按照 AWS 的要求创建的。控制平面需要它们来识别工作节点。我们可以更详细地介绍网络,但这超出了本教程的范围,所以如果您需要更多的细节,请查看 Github 代码,在那里您可以找到完整的示例。
让我们看看 EKS 集群的设置:
module "eks" {
source = "terraform-aws-modules/eks/aws"
cluster_name = join("-", [var.cluster_name, var.environment, random_string.suffix.result])
subnets = module.vpc.private_subnetstags = {
Environment = var.environment
}vpc_id = module.vpc.vpc_id
cluster_endpoint_private_access = truecluster_enabled_log_types = ["api", "audit", "authenticator", "controllerManager", "scheduler"]worker_groups = [
{
name = "worker-group-spark"
instance_type = var.cluster_instance_type
additional_userdata = "worker nodes"
asg_desired_capacity = var.cluster_number_of_nodes
additional_security_group_ids = [aws_security_group.all_worker_mgmt.id, aws_security_group.inside_vpc_traffic.id]
}
]workers_group_defaults = {
key_name = "eks_key"
subnets = module.vpc.private_subnets
}
}
在这个代码片段中,我们可以看到我们在私有子网内声明了集群。我们为控制面板的所有组件启用 Clowdwatch 日志。我们为配置var
模块设置 EC2 实例类型和数量,默认情况下,我们使用m5.xlarge
作为实例类型和 3 个节点。如果我们需要 ssh 进入工作节点,我们设置一个 EC2 键eks_key
。
为了能够运行本教程中的代码,我们需要安装一些工具。在 Mac 上,我们可以使用brew:
brew install terraform aws-iam-authenticator kubernetes-cli helm
为了达到 AWS,我们还需要设置我们的 AWS 凭证。
现在,我们可以开始初始化 Terraform,以获得部署基础设施所需的所有依赖项:
cd deployment/ && terraform init
如果一切运行成功,您应该能够看到类似于下图的内容:
我们已经准备好部署基础设施。为此,请运行:
terraform apply
部署完成还需要一段时间,所以我们可以高枕无忧了。
完成后,您应该会看到消息Apply complete! Resources: 55 added, 0 changed, 0 destroyed.
和部署的资源的名称。
检查部署是否正确的另一个步骤是查看工作节点是否已经连接到集群。为此我们设置了kubectl:
aws --region your-region eks update-kubeconfig --name your-cluster-name
当我们运行以下命令时,应该能够看到三个节点:
kubectl get nodes
步骤 2:安装 Spark 操作器
通常,我们使用spark-submit
部署 spark 作业,但是在 Kubernetes 中,我们有一个更好的选择,与环境更加集成,称为 Spark 操作符。它带来的一些改进包括自动重新提交应用程序、使用自定义重启策略自动重启、自动重试失败的提交,以及与 Prometheus 等监控工具的轻松集成。
我们可以通过helm:
安装它
helm repo add incubator http://storage.googleapis.com/kubernetes-charts-incubator
helm install spark-op incubator/sparkoperator
如果我们在终端中运行helm list
,那么spark-op
图表应该是可用的。此外,我们应该有一个运行的火花操作员吊舱。我们可以使用命令kubectl get pods.
来观察在default
名称空间中运行的 pods
步骤 3:运行 PySpark 应用程序
现在我们终于可以在 K8s 中运行 python spark 应用了。我们需要做的第一件事是创建一个spark
用户,以便让 spark jobs 访问 Kubernetes 资源。为此,我们创建了一个服务帐户和一个群集角色绑定:
apiVersion: v1
kind: ServiceAccount
metadata:
name: spark
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: spark-role
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: edit
subjects:
- kind: ServiceAccount
name: spark
namespace: default
要执行角色的创建:
kubectl apply -f spark/spark-rbac.yml
您将收到serviceaccount/spark created
和clusterrolebinding.rbac.authorization.k8s.io/spark-role created.
的通知
星火操作员工作定义:
apiVersion: "sparkoperator.k8s.io/v1beta2"
kind: SparkApplication
metadata:
name: spark-job
namespace: default
spec:
type: Python
pythonVersion: "3"
mode: cluster
image: "uprush/apache-spark-pyspark:2.4.5"
imagePullPolicy: Always
mainApplicationFile: local:opt/spark/examples/src/main/python/pi.py
sparkVersion: "2.4.5"
restartPolicy:
type: OnFailure
onFailureRetries: 2
driver:
cores: 1
memory: "1G"
labels:
version: 2.4.5
serviceAccount: spark
executor:
cores: 1
instances: 1
memory: "1G"
labels:
version: 2.4.5
我们在一个yml
文件中定义我们的 spark run 参数,类似于 Kubernetes 上的任何其他资源声明。基本上,我们定义我们正在运行一个Python 3
spark 应用程序,我们是映像uprush/apache-spark-pyspark:2.4.5.
我推荐使用这个映像,因为它带有一个更新版本的 yarn,可以更有效地处理对s3a
的写入。我们有一个重试策略,如果作业失败,它将重新启动。驱动程序和执行器的一些资源分配。由于工作非常简单,我们只使用一个执行程序。我们可以注意到的另一件事是,我们使用了之前定义的spark
服务帐户。我们使用的 To 代码是计算pi
数的经典例子。
要提交我们再次使用的代码kubectl
:
kubectl apply -f spark/spark-job.yml
完成后,如果我们再次检查豆荚,我们应该有类似的结果:
如果我们通过运行kubectl logs spark-job-driver
来检查日志,我们应该会在日志中找到一行给出 pi 的近似值Pi is roughly 3.142020.
那是所有的人。我希望你喜欢这个教程。我们已经看到了如何使用 terraform 创建我们自己的 AWS EKS 集群,以便在不同的环境中轻松地重新部署它,以及如何使用更友好的 Kubernetes 语法提交 PySpark 作业。
如何使用 PySpark 结构化流在 AWS Kinesis 中运行实时管道
使用 Python 结构化流应用程序从 AWS Kinesis 消费数据,并在 Jupyter 笔记本中运行
在本教程中,我们将使用 Spark 的最新流技术,结构化流,从 AWS Kinesis 流中使用JSON
数据。
我们将执行以下步骤:
- 使用 boto3 在 AWS 中创建 Kinesis 流
- 将一些简单的
JSON
消息写入流中 - 消费 PySpark 中的消息
- 在控制台中显示消息
TL;DR: Github 代码回购
步骤 1:为 Jupyter 设置 PySpark
为了能够在笔记本上运行 PySpark,我们必须使用findspark
包。我们需要添加另一个包,允许 PySpark 从 Kinesis 获取消费者数据。对于此功能,我们在笔记本的开头添加了:
import os
os.environ['PYSPARK_SUBMIT_ARGS'] = '--packages=com.qubole.spark/spark-sql-kinesis_2.11/1.1.3-spark_2.4 pyspark-shell'import findspark
findspark.init()
步骤 2:创建一个动力流
AWS Kinesis 是使我们能够实时读取和处理数据的基础设施。与其他类似的技术(Kafka)相比,它更容易建立。在 python 中,我们可以使用boto3
库:
client = boto3.client('kinesis')
stream_name='pyspark-kinesis'client.create_stream(
StreamName=stream_name,
ShardCount=1)
这将创建一个流分片,它本质上是控制吞吐量的单元。更多的碎片意味着我们可以接收更多的数据,但是对于本教程来说,一个就足够了。
如果我们打开 AWS 控制台,导航到 Amazon Kinesis board(服务-> Amazon Kinesis),我们应该会看到类似的内容:
步骤 3:将信息写入 Kinesis
要将一些消息写入我们刚刚创建的 Kinesis 流,我们可以再次使用boto3
:
messages = [
{'message_type': 'message1', 'count': 2},
{'message_type': 'message2', 'count': 1},
{'message_type': 'message1', 'count': 2},
{'message_type': 'message3', 'count': 3},
{'message_type': 'message1', 'count': 5}
]for message in messages:
client.put_record(
StreamName=stream_name,
Data=json.dumps(message),
PartitionKey='part_key')
我们有一个字典列表,我们将其序列化到JSON
中,并使用put_record
函数编写。一个字典代表我们信息的模式。因为我们只使用一个碎片,所以如何定义分区键并不重要。
第四步:阅读信息
当使用结构化流读取数据时,我们需要注意 Kinesis 的一些特殊性。
首先,我们需要定义format
Kinesis,以便使用正确的连接器。我们还必须使用端点和区域,这取决于我们部署基础架构的位置。我的情况是爱尔兰eu-west-1.
我们使用设置startingposition
作为TRIM_HORIZON
,这意味着当我们重启应用程序时,我们总是会读取 Kinesis 中所有可用的数据。如果我们只想处理最新的可用数据,我们可以将该标志改为LATEST
。
我已经为 AWS 凭证创建了环境变量。我们也可以直接使用它们,但这样更安全。
kinesis = spark \
.readStream \
.format('kinesis') \
.option('streamName', stream_name) \
.option('endpointUrl', '[https://kinesis.eu-west-1.amazonaws.com')\](https://kinesis.eu-west-1.amazonaws.com')\)
.option('region', 'eu-west-1') \
.option('awsAccessKeyId', os.environ['KINESIS_ACCESS_KEY'])\
.option('awsSecretKey', os.environ['KINESIS_SECRET_KEY']) \
.option('startingposition', 'TRIM_HORIZON')\
.load()\
一旦我们执行了这段代码,我们将能够读取数据帧中的运动数据。
步骤 5:在控制台中显示消息
我们现在设置的好处是我们可以执行标准的数据帧操作。
我们的数据在 JSON 中,所以我们需要转换它。前三个 select 语句就是关于这个的。我们使用from_json
将 JSON 列转换为包含所有字段的结构,使用data.*
的技巧是将一列分成单独的列,因此在我们的例子中,一列用于message_type
,一列用于count
。
schema = StructType([
StructField("message_type", StringType()),
StructField("count", IntegerType())])kinesis\
.selectExpr('CAST(data AS STRING)')\
.select(from_json('data', schema).alias('data'))\
.select('data.*')\
.writeStream\
.outputMode('append')\
.format('console')\
.trigger(once=True) \
.start()\
.awaitTermination()
因为我们使用选项trigger(once=True)
,我们将只读取一批数据,这不是一个连续的操作。如果我们删除这个标志,那么处理将是无限的。
在我们启动 Jupyter 笔记本的终端中,我们将能够看到数据:
一批运动数据
最后,我们可以删除我们在 AWS 中使用的资源,即我们部署的 Kinesis 流:
client.delete_stream(StreamName=stream_name)
仅此而已!我希望您喜欢来自精彩的流处理世界的另一个教程。我们已经看到了如何通过几个步骤在 Kinesis 的 PySpark 中连接和处理数据。
在 Google Colab 上运行并分享深度学习网络应用
使用 Streamlit 快速构建原型,并在 Google Colab 上部署,只需几行代码
介绍
在我之前的工作中,我使用 Fastai 建立了一个深度学习模型,对黑白照片进行彩色化,并使用 Streamlit 建立了一个 web 应用原型。我希望与我的同事和朋友分享它,以获得一些反馈,所以我试图将 web 应用程序部署到 AWS 和 Heroku。
利用 Fastai 的生成性对抗网络(GAN)使黑白照片变得丰富多彩
towardsdatascience.com](/colorize-black-and-white-photos-by-ai-cc607e164160)
我能够将我的应用程序部署到这些云服务提供商并运行它,但是,他们的免费层帐户没有为我的应用程序提供足够的内存,它总是崩溃。为了让至少一些东西在网上运行,我不得不把照片的尺寸做得很小,结果质量很差。我不想在这个早期阶段花很多钱升级账户。我只是想要一个功能齐全的快速原型运行,这样我就可以测试它,并得到一些反馈。
从那以后,我一直在寻找其他解决方案来部署和共享应用程序。我找到的一个解决方案是在 Google Colab 上运行这个应用程序,使用其免费且强大的计算服务。在这篇短文中,我将描述我如何在 Colab 上运行 web 应用程序。
斯特雷姆利特
如果您不熟悉 Stremlit ,它是用 Python 创建简单 web 应用程序的强大工具。对于我这样没有 web 开发背景和技能的人来说非常方便。
他们为初学者提供了很好的教程。
该项目展示了 Udacity 自动驾驶汽车数据集和 YOLO 物体检测到一个互动的流线…
github.com](https://github.com/streamlit/demo-self-driving)
在这篇文章中,我还记录了我使用 Stremlit 构建 web 应用程序的工作:
[## 生成性对抗网络:构建一个用 Streamlit 给 B&W 照片着色的 web 应用程序
使用 Streamlit 快速将生成式对抗网络模型转换为 web 应用程序,并部署到 Heroku
towardsdatascience.com](/generative-adversarial-network-build-a-web-application-which-colorizes-b-w-photos-with-streamlit-5118bf0857af)
在 Colab 上运行应用程序
一旦你在本地成功运行了网络应用程序,你可以试着在 Google Colab 上运行它
首先把 app 克隆到 colab,进入目录。
!git clone [http://github.com/xxx/xxxxx.git](http://github.com/xxx/xxxxx.git) color
cd color
然后安装需求
!pip install -r requirements_colab.txt
在我的例子中,它包含 stremlit、opencv、fastai 和 scikit_image。
然后我们需要安装 pyngrok。
!pip install pyngrok
要通过 Colab 上的公共 URL 运行和共享应用程序,我们需要使用 ngrok,这是一种安全的隧道解决方案。详情可以在这里找到。
安装完成后,我们可以在后台运行应用程序。
!streamlit run run.py &>/dev/null&
然后使用 ngrok 创建公共 URL。
from pyngrok import ngrok
# Setup a tunnel to the streamlit port 8501
public_url = ngrok.connect(port='8501')
public_url
你应该会得到这样一个网址“http://ea41c 43860 D1 . ngrok . io”。
就是这样!非常简单的步骤。现在,这款网络应用可以通过强大的 Google Colab 免费在线使用。
在 Colab 上运行 web 应用程序的优势在于,应用程序不会受到自由层帐户的有限计算的限制,您甚至可以使用 GPU 运行。然而,它的主要缺点是 URL 只是临时的,一旦 Colab 断开,URL 将被禁用。所以你只能在短时间内分享链接(< 12 小时)。但是我认为这仍然是一个快速部署、测试和共享 web 应用原型的好方法。
感谢阅读。欢迎提出建议和意见。
如何使用 Linux“systemd”将 Apache Airflow 作为守护进程运行
CentOS 上的气流守护程序教程。从安装、下载、配置到使用 systemctl 运行。
自从 Airflow 从孵化器成为顶级 Apache 项目后,它作为一个具有简洁 Web UI 的工作流调度管理器越来越受欢迎。
在一个典型的用例中,Airflow 需要两个必须持续运行的组件,web 服务器和调度器。前者是用于管理和监控工作流的 Web UI,后者负责在预定义的时间戳正确触发工作流。
但是,使用 Linux 中提供的命令来运行这两个组件并不是一个好主意,例如:
$ airflow scheduler
$ airflow webserver
缺点显而易见:
- 如果任何组件崩溃,服务将被终止,没有任何通知。
- 这些服务的日志被打印在 stdout 中,如果 crush 的话,这些日志将会丢失,所以要找出发生了什么是很困难的
- 当 Linux 系统重新启动时,它不会自动启动运行。
为了解决这些问题,我们需要将 Apache Airflow 作为守护进程运行。Apache Airflow GitHub repo 已经提供了支持systemd
和upstart
的守护程序服务定义。在本文中,我们将使用前者。
官方文档只给出了非常简要的解释,没有可以遵循的教程。对于一些没有太多 Linux 经验的数据工程师或数据科学家来说,这相对比较困难。本文将一步步演示如何将 Airflow 作为守护进程运行。从安装到启动和运行。
安装阿帕奇气流
在 Medium 上已经有一些关于如何安装 Airflow 的教程,比如这个,如果你在 Ubuntu 上的话:
[## 如何使用 python 解释器在 Ubuntu 上安装 apache airflow
在这篇博文中,我将向您展示如何在 ubuntu 上安装 apache airflow,
medium.com](https://medium.com/@shaikzillani/how-to-install-apache-airflow-on-ubuntu-using-python-interpreter-20f10348e7bd)
然而,对于 CentOS 等基于 Red Hat 的 Linux,似乎还没有这样的教程,依赖项的名称和安装方式可能与基于 Debian 的 Linux 略有不同。
首先,强烈建议为气流创建一个特定的用户
useradd airflow
此外,您的 Linux 可能会也可能不会绑定 Airflow 所需的一些依赖项。典型的,我发现有以下三种缺失是相当普遍的。
- (同 groundcontrolcenter)地面控制中心
- Python 开发
- MySQL 开发(如果你需要连接到 MySQL)
请注意,Ubuntu 和 CentOS 中的库名并不相同。例如,Python Dev 包在 Ubuntu 的apt-get
中是python-dev
,而在 CentOS 的yum
中,它被称为python-devel
。如果你使用 Python3,确保你安装了python3-devel
。此外,MySQL Dev 在apt-get
中被称为libmysqldev
,而在yum
中被称为mysql-devel
。
yum install gcc
yum install python3-devel
yum install mysql-devel
然后,让我们安装气流和额外的软件包,如有必要,如:
pip3 install apache-airflow
pip3 install 'apache-airflow[crypto]'
pip3 install 'apache-airflow[mysql]'
气流守护程序的准备
在我们能够为气流配置我们的systemd
服务之前,我们需要做一些准备。第一步是从 Airflow GitHub Repo 下载服务定义文件。
https://github . com/Apache/air flow/tree/master/scripts/systemd
下载守护程序服务文件
让我们为下载文件创建一个临时文件夹。
mkdir /tmp/airflow-daemon
cd /tmp/airflow-daemon
然后,将文件下载到这个临时文件夹中。
# wget [https://raw.githubusercontent.com/apache/airflow/master/scripts/systemd/airflow](https://raw.githubusercontent.com/apache/airflow/master/scripts/systemd/airflow)
# wget [https://raw.githubusercontent.com/apache/airflow/master/scripts/systemd/airflow-scheduler.service](https://raw.githubusercontent.com/apache/airflow/master/scripts/systemd/airflow-scheduler.service)
# wget [https://raw.githubusercontent.com/apache/airflow/master/scripts/systemd/airflow-webserver.service](https://raw.githubusercontent.com/apache/airflow/master/scripts/systemd/airflow-webserver.service)
# wget [https://raw.githubusercontent.com/apache/airflow/master/scripts/systemd/airflow.conf](https://raw.githubusercontent.com/apache/airflow/master/scripts/systemd/airflow.conf)
在 GitHub 回购中,有一个简短的解释如下:
该目录中的 systemd 文件是在基于 RedHat 的系统上测试的。将它们复制(或链接)到/usr/lib/systemd/system
并将 airflow.conf 复制到/etc/tmpfiles . d/or/usr/lib/tmpfiles . d/。复制 airflow.conf 确保/run/airflow 是用正确的所有者和权限创建的
( 0755 air flow air flow)然后,您可以使用 systemctl start 启动不同的服务器。启用服务可以通过发出
systemctl enable <服务>来完成。默认情况下,环境配置指向/etc/sysconfig/airflow。你可以复制这个
目录下的“气流”文件,根据自己的喜好进行调整。经过一些小的改动,它们可能可以在其他 systemd 系统上工作。
嗯,我想对于大多数没有 Linux 背景的人来说,上面的文档可能会非常模糊和误导。所以,我画了这个图来显示哪个文件应该放在哪个路径上。
根据图中所示的路径,让我们将文件复制到正确的位置。
cp *.service /usr/lib/systemd/system/
cp airflow.conf /usr/lib/tmpfiles.d/
cp airflow /etc/sysconfig/
创建必要的目录
我们还需要创建一些守护进程需要的目录。首先,它需要一个专用的目录来存储运行时信息,比如pid
。让我们在/run
目录下创建目录,并更改权限。
mkdir /run/airflow
chown airflow:airflow /run/airflow
chmod 0755 airflow -R
请注意,权限被设置为0755
,因为实际上我们可能有其他多个用户来开发 Dag(工作流)。有了0755
权限,它确保所有其他用户都有他们的次要组,因为airflow
将有足够的权限。
我们需要创建的另一个目录是 Airflow 主目录,它包括:
- 气流配置
- 气流使用的 SQLite
- 熟练的技艺
- Dag 日志
通常如果没有export AIRFLOW_HOME=...
,这些会在当前用户的主目录下自动生成,比如/home/airflow/airflow/
。如果您正在测试气流或开发一些 Dag,这很好。但是,不建议这样做,而且在生产中也不方便,因为其他用户不容易访问airflow
用户的主目录。
在我的例子中,我想把 Airflow 主目录放在/opt
下,所以让我们创建它。
mkdir /opt/airflow
chown airflow:airflow airflow -R
chmod 775 airflow -R
同样,更改权限以允许airflow
组中的所有用户不仅可以读取目录,还可以写入目录,因为他们需要修改 Dag。
初始化气流主目录
一切准备就绪。我们需要初始化气流的主目录。将主目录导出到AIRFLOW_HOME
环境变量是很重要的。否则,如上所述,将在用户的主文件夹中自动生成主目录。
export AIRFLOW_HOME=/opt/airflow
airflow initdb
配置气流守护程序
现在,所有的服务文件、配置文件和必要的目录都准备好了。我们需要配置守护进程,以确保在守护进程正常运行之前,一切都指向正确的路径。
首先,让我们仔细检查一下airflow
二进制文件的路径,因为稍后需要在服务定义中指定它。
$ which airflow
/usr/local/bin/airflow
我的情况是/usr/local/bin/airflow
。请记下你的,很可能是一样的,但以防万一要注意一下。不要直接抄我的。
然后,我们来修改一下airflow-webserver
的定义。
vi /usr/lib/systemd/system/airflow-scheduler.service
如下更改ExecStart
值。
ExecStart=/usr/local/bin/airflow scheduler
同样的,我们也在airflow-scheduler
里改一下吧。
vi /usr/lib/systemd/system/airflow-webserver.service
请注意,pid
需要写入我们刚刚创建的目录/run/airflow
。
ExecStart=/usr/local/bin/airflow webserver --pid /run/airflow/webserver.pid
然后,我们需要修改气流的系统配置。否则,服务将不知道 Airflow 主目录在哪里。
vi /etc/sysconfig/airflow
根据我们刚才准备的内容,需要对下面的两个配置进行如下修改。
AIRFLOW_CONFIG=/opt/airflow/airflow.cfg
AIRFLOW_HOME=/opt/airflow
作为服务配置的最后一步,我们需要在运行这些服务之前启用它们。
systemctl enable airflow-scheduler
systemctl enable airflow-webserver
运行配置的气流守护程序
有了root
权限(root 用户或 sudo),我们可以
- 运行气流守护程序
systemctl start airflow-scheduler
systemctl start airflow-webserver
- 检查其状态
systemctl status airflow-scheduler
systemctl status airflow-webserver
- 停止守护进程
systemctl stop airflow-scheduler
systemctl stop airflow-webserver
- 重新启动守护程序
systemctl restart airflow-scheduler
systemctl restart airflow-webserver
- 查看守护程序服务日志(最近 50 行,行数可使用
-n
参数定制)
# journalctl -u airflow-scheduler -n 50
# journalctl -u airflow-webserver -n 50
摘要
本文介绍了如何在 CentOS 系统上安装 Airflow。然后,我认为如果我们简单地在命令行运行 Airflow 会有缺点,所以我们需要通过将它作为守护进程来解决这个问题。
我们首先需要从 Apache Airflow GitHub repo 下载服务定义文件,然后将它们放入正确的系统目录中。我们还需要创建一些文件夹,因为守护进程需要它们来正确运行。
最后,我们需要配置服务定义文件,以确保守护程序可以在正确的位置找到资源。之后,我们可以将 Apache Airflow 作为守护进程运行,这样它将收集适当的服务运行日志,并在出现问题时自动重启服务。
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
medium.com](https://medium.com/@qiuyujx/membership)
如果你觉得我的文章有帮助,请考虑加入 Medium 会员来支持我和成千上万的其他作者!(点击上面的链接)
如何在 Docker 上运行 Jupyter 笔记本
不再有 Python 环境和包更新
**Table of Contents**[**Introduction**](#093d) 1\. [Installing Docker Desktop](#09a3)
2\. [Docker help](#4802)
3\. [Running Jupyter Docker Stacks](#9927)
4\. [Formatting Docker ps](#f597)
5\. [Entering the Docker container and using bash](#b42d)
6\. [Stopping and removing containers and images](#256b)
7\. [Connecting the local directory to a Docker container](#0ba2)
8\. [Inspecting a container](#08c1)
9\. [Getting started with Docker file](#a6ca)
10\. [Publishing an image to Docker Hub](#999d)[**Conclusion**](#556f)
介绍
Docker 简化并加速了您的工作流程,同时让开发人员可以自由地为每个项目选择工具、应用程序堆栈和部署环境。—从开始用 Docker 开发
Docker 为您的开发提供了一个包含的环境。通过使用 Docker,您可能不需要在计算机上安装 pyenv/pipenv/virtualenv 或任何编程语言。你只要用一个 Docker 容器!在本文中,您将学习如何在 Docker 上运行 Jupyter。
TL;速度三角形定位法(dead reckoning)
$ docker run -p 8888:8888 -v $(pwd):/home/jovyan/work jupyter/minimal-notebook
$ docker run -p 8888:8888 -v $(pwd):/home/jovyan/work jupyter/scipy-notebook
上面的第一个命令将运行 Jupyter minimal-notebook,将本地目录连接到 Docker 容器。
第二个命令与第一个命令相同。唯一不同的是运行 Jupyter Scipy-notebook。
安装 Docker 桌面
安装 Docker 桌面,当你启动 Docker 时,你会在菜单栏中看到一个图标。
Mac 上的 Docker 菜单。作者图片
Docker 首选项菜单允许您配置 Docker 设置,如安装、更新、版本频道、Docker Hub 登录等。打开“偏好设置”并转到“资源”来更改 CPU、内存和其他设置。默认情况下,Docker Desktop 被设置为使用主机上可用处理器数量的一半。
Docker 首选项。作者图片
你可以在这个页面上阅读更多关于 Mac 和 Windows 的细节。
Docker 帮助
在您的终端中运行docker
,您将看到所有命令:
$ docker
Usage: docker [OPTIONS] COMMAND
A self-sufficient runtime for containers
Options:
--config string Location of client config files (default "/Users/shinokada/.docker")
-c, --context string Name of the context to use to connect to the daemon (overrides
DOCKER_HOST env var and default context set with "docker context use")
-D, --debug Enable debug mode
... MORE LINES
Docker 将命令逻辑地分组为管理命令。以下是顶级命令。
Management Commands:
builder Manage builds
config Manage Docker configs
container Manage containers
context Manage contexts
image Manage images
network Manage networks
node Manage Swarm nodes
plugin Manage plugins
secret Manage Docker secrets
service Manage services
stack Manage Docker stacks
swarm Manage Swarm
system Manage Docker
trust Manage trust on Docker images
volume Manage volumesCommands:
attach Attach local standard input, output, and error streams to a running container
... MORE LINES
您可以使用--help
获得更多关于管理命令的信息。
$ docker container --help
$ docker image --help
让我们开始创建 Docker 容器。
运行 Jupyter Docker 堆栈
Jupyter Docker Stacks 是一组准备运行的 Docker 映像,包含 Jupyter 应用程序和交互式计算工具。
官方 Jupyter 创建了不同的 Docker 图像,我们将使用[jupiter/minimal](https://hub.docker.com/r/jupyter/minimal-notebook/tags/)
来学习如何使用 Docker。这个映像基于[jupyter/base-notebook](https://hub.docker.com/r/jupyter/base-notebook)
,它有命令行工具、TeX Live、git、emacs、vi、jed 等等。
$ docker run -p 8888:8888 jupyter/minimal-notebook
在输出的末尾,您可以找到带有标记的 URL。你用cmd
+click 在浏览器上打开网址。
带有令牌的 URL 的 Docker 输出。作者图片
单击 URL 后,您会看到这一点。作者图片
打开另一个终端标签并检查容器 id 号。
$ docker container ls
# or
$ docker ps
docker ps 的输出。作者图片
格式化 Docker ps
阅读上面的输出有点困难。让我们创建一个格式。
将以下内容添加到您的~/.zshrc
或~/.bash_profile
中。
FORMAT="\nID\t{{.ID}}\nIMAGE\t{{.Image}}\nCOMMAND\t{{.Command}}\nCREATED\t{{.RunningFor}}\nSTATUS\t{{.Status}}\nPORTS\t{{.Ports}}\nNAMES\t{{.Names}}\n"
您可以通过将它添加到 docker 的--format
选项来使用它:
$ docker ps --format=$FORMAT
# or
$ docker container ls --format=$FORMAT
docker 容器 ls 的输出— format=$FORMAT。作者图片
docker ps — format $FORMAT 的输出。作者图片
如上图所示,有无=
标志都可以使用。
进入 Docker 容器并使用 bash
docker exec
在运行容器中运行命令。-i
选项允许我们交互地使用它,-t
分配一个伪 TTY。我们使用/bin/bash
来运行 bash shell。
$ docker exec -it cb8b /bin/bash
cb8b
是我的容器的前 4 个字母。您有不同的容器 id。
使用docker exec --help
可以找到更多信息。
$ docker exec --help
Usage: docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
Run a command in a running container
Options:
-d, --detach Detached mode: run command in the background
--detach-keys string Override the key sequence for detaching a container
-e, --env list Set environment variables
... MORE LINES
一旦进入容器,就可以运行普通的 bash 命令。
在容器中运行 ls 命令。作者图片
让我们检查一下容器 Python 和 pip 版本:
(base) jovyan@cb8b4579b2a6:~/work$ python -V
Python 3.8.5
(base) jovyan@cb8b4579b2a6:~/work$ pip -V
pip 20.2.3 from /opt/conda/lib/python3.8/site-packages/pip (python 3.8)
该图像也有ipython
和conda
。让我们检查一下:
(base) jovyan@cb8b4579b2a6:~$ ipython --version
7.18.1
(base) jovyan@cb8b4579b2a6:~$ conda info -aactive environment : base
active env location : /opt/conda
shell level : 1
user config file : /home/jovyan/.condarc
populated config files : /opt/conda/.condarc
conda version : 4.8.5
conda-build version : not installed
--- MORE LINES
您可以找到安装了哪些 Python 包:
(base) jovyan@cb8b4579b2a6:~$ pip list
运行容器中的运行 pip 列表。作者图片
熊猫,numpy 等不装。您可以使用pip install pandas numpy
安装它们:
(base) jovyan@cb8b4579b2a6:~/work$ pip install pandas numpy
您可以使用exit
退出 bash。CTRL-C 退出一个正在运行的容器。
停止和移除容器和图像
让我们停止一个正在运行的容器:
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cb8b4579b2a6 jupyter/minimal-notebook "tini -g -- start-no…" 4 hours ago Up 4 hours 0.0.0.0:8888->8888/tcp suspicious_allen
您可以使用docker container stop <container-id>
停止容器:
$ docker container stop cb8b
您可以找到包括非活动容器在内的所有容器:
$ docker container ls -a
# or
$ docker ps -a
您可以列出 docker 图像:
$ docker images
您可以使用docker rmi <image-id>
删除图像。
$ docker rmi -f <image-id>
-f
在不停止容器的情况下强制移走正在运行的容器。
如果您想要一次移除所有图像:
$ docker rmi $(docker images -a -q)
-a
允许我们删除所有图像,删除后-q
显示数字 id。
您可以用同样的方式使用“移除所有容器”:
$ docker rm $(docker ps -a -q)
使用 **--rm**
可以用[--rm](https://docs.docker.com/engine/reference/run/#clean-up---rm)
运行一个容器,当退出容器时自动清理容器。
$ docker run --rm jupyter/minimal-notebook
退出容器后,您不需要运行docker ps -a
和docker rm <image-id>
。
您可以将选项与-it
结合使用。
$ docker run -it --rm jupyter/minimal-notebook bash
(base) jovyan@c803e897b718:~$
当您运行这个命令时,您可以在容器中使用 bash,当您退出时,它将清理容器。
将本地目录连接到 Docker 容器
Docker 卷是默认 Docker 文件系统之外的目录(或文件),作为普通目录和文件存在于主机文件系统中。卷不会增加使用它的容器的大小,并且卷的内容存在于给定容器的生命周期之外。
我们可以使用-v
选项创建一个卷。
$ docker run -p 8888:8888 -v /Users/yourname/yourdirectory:/home/jovyan/work jupyter/minimal-notebook
如果要使用当前工作目录,使用$(pwd)
。
$ docker run -p 8888:8888 -v $(pwd):/home/jovyan/work jupyter/minimal-notebook
使用卷运行 docker run。作者图片
Jupyter 笔记本在浏览器上显示本地目录。
无论您在 Jupyter 笔记本中做了什么更改,它也会更改您的本地文件。
检查集装箱
您可以检查码头集装箱:
$ docker inspect <container-id or container-name>
它返回 docker 对象信息。
Docker 文件入门
让我们在创建容器时安装所有 Python 包。
创建一个新目录和一个名为 Dockerfile 的文件,内容如下:
ARG BASE_CONTAINER=jupyter/minimal-notebook
FROM $BASE_CONTAINERLABEL author="Shinichi Okada"USER rootRUN pip install pandas numpy matplotlib plotly# Switch back to jovyan to avoid accidental container runs as root
USER $NB_UID
然后运行docker build
:
$ docker build -t shinokada/jupyter-notebook .
$ docker run -p 8888:8888 -v /Users/shinokada/DataScience:/home/jovyan/work shinokada/jupyter-notebook
打开另一个终端标签:
$ docker ps
$ docker exec -it <container-id> /bin/bash
(base) jovyan@a56262d7eabc:~$ pip list
...
matplotlib
...
numpy
...
pandas
我们使用docker exec
进入一个正在运行的容器,并列出 Python 包,看看我们的包是否已安装。
将图像发布到 Docker Hub
在 hub.docker 注册,然后在您的终端:
$ docker login
Username: your username
Password: your password
...
$ docker push shinokada/jupyter-notebook
我在码头中心的回购。作者图片
更多 docker 命令
# Show the history of image
docker history <image-id>
# Display system-wide information
docker info | more
结论
[jupyter/scipy-notebook](https://hub.docker.com/r/jupyter/scipy-notebook)
是一个 Jupyter 笔记本科学 Python 堆栈,它包含了科学 Python 生态系统中的流行包。如果你想尝试深度学习,那么[jupyter/tensorfolow-notebook](https://hub.docker.com/r/jupyter/tensorflow-notebook)
适合你。它包括流行的 Python 深度学习库。你可以在这些 链接找到更多图片。
你不仅可以把 docker 用于 Jupyter 笔记本,也可以用于你的一般开发。Docker Hub 上有许多存储库。尝试找到你可以信任的官方网站,或者创建你自己的网站,然后推送至 Docker Hub。您将不再需要在您的系统上更新 Python 包。
通过 成为 会员,获得媒体上所有故事的访问权限。
如何使用 Docker 运行 MySQL 和 phpMyAdmin
Docker 简化了 MySQL 管理
照片由 bongkarn thanyakij 从 Pexels 和 Guillaume Bolduc 在 Unsplash
对于许多人来说,使用命令行界面管理 MySQL 服务器可能很困难。当我们可以使用图形界面时,事情就变得简单多了。数据库管理工具 phpMyAdmin 解决了这个问题。我们可以在网络界面上使用这个工具。它支持 MySQL 和 MariaDB 的各种操作,比如导入数据、导出数据、执行 SQL 语句等等。
我们将使用 Docker 进行设置,因为在不同的机器上运行和管理 phpMyAdmin 对于环境管理来说是一件令人头疼的事情。Docker 通过使用其容器化技术解决了这个问题,该技术使用 Docker 图像。之前,我已经讨论过如何使用 Docker 运行 MySQL。你可以阅读下面的帖子,我在里面讲述了 MySQL 和 Docker 的一些基本概念和命令。
轻松运行 MySQL
towardsdatascience.com](/how-to-run-mysql-using-docker-ed4cebcd90e4)
从这篇文章中,你将学习如何使用 Docker 将 phpMyAdmin 连接到 MySQL 服务器。这种方法将节省您的时间和精力,因为您不必安装或配置 phpMyAdmin 和 MySQL。
设置
有两种方法我们可以使用 Docker 连接 phpMyAdmin 和 MySQL。在第一种方法中,我们将使用单个 Docker 合成文件。对于第二个,我将向您展示如何连接到一个已经运行的 MySQL Docker 容器。首先,你需要安装 Docker 。两种方法我都用 macOS。
方法 1
在这个方法中,我们将使用一个 Docker 编写文件。我们需要将docker-compose.yml
放入一个文件夹中。这个设置中使用的文件夹名是 phpMyAdmin 。让我们来分解一下docker-compose.yml
文件的各个成分。
version: '3.1'
services:
db:
image: mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: test_db
ports:
- "3308:3306"
phpmyadmin:
image: phpmyadmin/phpmyadmin:latest
restart: always
environment:
PMA_HOST: db
PMA_USER: root
PMA_PASSWORD: root
ports:
- "8080:80"
首先,我们使用版本标记来定义合成文件格式,即 3.1。还有其他文件格式— 1、2、2.x 和 3.x。从 Docker 的文档中获取有关合成文件格式的更多信息,请点击。
我们通过服务散列来跟随我们的版本标签。在这里面,我们必须定义我们的应用程序想要使用的服务。对于我们的应用程序,我们有两个服务, **db、**和 phpmyadmin 。
为了使我们的设置过程快速简单,我们使用预先构建的官方图片 MySQL 和 phpMyAdmin 作为图片标签。
当我们使用 always 作为重启标签时,容器总是重启。这样可以节省时间。例如,您不必在每次手动重启机器时都启动容器。当 Docker 守护进程重新启动或者容器本身被手动重新启动时,它会重新启动容器。
我们已经在环境标记下定义了环境变量,我们将使用这些变量进行数据库和 phpMyAdmin 认证。
最后,ports 标记用于定义主机和容器端口。对于 db 服务,它将主机上的端口 3308 映射到 MySQL 容器上的端口 3306。对于 phpmyadmin 服务,它将主机上的端口 8080 映射到 phpMyAdmin 容器上的端口 80。
现在从docker-compose.yml
文件所在的目录运行下面的命令。命令docker compose up
启动并运行你的整个应用。如果您遇到以下错误,这意味着您已经在端口 3308 上运行 Docker 容器。要解决这个问题,您必须更改到不同的端口,或者您可以停止另一个容器。
Bind for 0.0.0.0:3308 failed: port is already allocated
现在选择任意一个网络浏览器,进入以下地址。
http://localhost:8080
瞧啊。您应该会在浏览器上看到如下所示的网页。
管理面板
正如你所看到的,在底部有一个警告信息。让我们现在就解决这个问题。
首先,点击找出原因链接
现在点击创建链接
您已经准备好管理您的数据库了!
方法 2
在这个方法中,您将学习如何将 phpMyAdmin docker 容器连接到已经运行的 MySQL 容器。当 docker-compose 文件中没有 phpMyAdmin 服务时,这很有帮助。
首先,我们需要使用以下命令列出所有当前的 Docker 网络。
docker network ls
现在你应该可以从列表中看到phpmyadmin_default
。我们的目标是找到我们在方法一中使用 docker-compose 文件创建的应用程序网络。由于我们没有在 docker-compose 文件中为我们的应用程序指定一个网络名称,docker 将根据目录名给出网络名称,并在末尾加上_default
。在这种情况下,phpmyadmin_default
。如果你对 Docker networks 感兴趣,点击查看。
干得好,您已经成功识别了网络!最后,我们可以运行一个独立的 phpMyAdmin Docker 容器,它连接到我们想要的网络。
docker run --name stand-alone-phpmyadmin --network phpmyadmin_default -p 8081:80 phpmyadmin/phpmyadmin:latest
docker run
命令用于从映像运行容器。这里我们使用的是phpmyadmin/phpmyadmin:latest
图像。
--name
标志(可选)用于给容器一个特定的名称。如果不想提供,Docker 会随机分配一个名字。
—-network
标志用于连接到 Docker 网络。
-p
标志已经在这篇文章中讨论过了。
现在选择任意一个网络浏览器,进入以下地址。使用root
作为用户名和密码登录。
http://localhost:8081/index.php
当您想要连接多个 Docker 容器时,这种方法很有用。
包裹
当我们使用命令行界面时,数据库管理可能是一项艰巨的任务。基于网络的工具 phpMyAdmin 解决了这个问题,Docker 使整个过程更加顺畅。我使用这个设置来试验 MySQL 查询,这样可以节省很多时间。通过使用 Docker,我不必担心 MySQL 和 phpMyAdmin 的设置。我希望这能帮助你开始使用 MySQL、phpMyAdmin 和 Docker。
相关帖子
专注于编写代码,无需担心环境管理
towardsdatascience.com](/how-to-mount-a-directory-inside-a-docker-container-4cee379c298b)
如何使用 Docker 运行 MySQL
轻松运行 MySQL
图片来自推特:@jankolario 在 Unsplash
如果你是数据库管理员、数据科学家或开发人员,你可能必须使用 MySQL 来存储和操作数据。由于 Docker 近年来已经成为一个流行的 DevOps 工具,你最终需要知道如何在 Docker 容器中运行 MySQL。
由于环境管理的原因,在不同的机器上运行您的应用程序可能会令人头疼。Docker 通过使用其容器化技术解决了这个问题,该技术使用 Docker 图像。如果你是 Docker 的新手,或者想提高你的技能,请阅读下面的帖子,我已经介绍了一些基础知识。
专注于编写代码,无需担心环境管理
towardsdatascience.com](/how-to-mount-a-directory-inside-a-docker-container-4cee379c298b)
一旦你完成了本教程,你就可以使用 Docker 测试任何 MySQL 查询了。这种方法将节省您的时间和精力,因为您不必安装或配置 MySQL。
设置
首先,你需要安装 Docker 。对于这个例子,我们将使用一个 Docker 组合文件,一个包含引导数据的 SQL 文件,也称为 mysql-dump 和 macOS。我们需要将docker-compose.yml
和school.sql
文件放在同一个文件夹中。这个设置中使用的文件夹名是 MySQL-Snippets 。
- Docker Compose: 我们可以使用 Docker Compose 运行多个容器,并在一个 YAML 文件中定义它们的属性。这些容器被称为服务。当您的应用程序有多个堆栈时,比如一个 web 服务器和一个数据库服务器,这是很有帮助的。
- MySQL-dump:MySQL-dump 包含纯文本格式的 MySQL 查询。MySQL 命令行客户端可以运行这些命令,并将它们发送到 MySQL 服务器。
让我们来分解一下docker-compose.yml
文件的各个组成部分。
version: '3.1'
services:
db:
image: mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: test_db
ports:
- "3307:3306"
volumes:
- $HOME/Desktop/MySQL-Snippets/school.sql:/school.sql
首先,我们使用版本标记来定义合成文件格式,即 3.1。还有其他文件格式— 1、2、2.x 和 3.x。从 Docker 的文档中获取更多关于合成文件格式的信息此处。
我们通过服务散列来跟随我们的版本标签。在这里面,我们必须定义我们的应用程序想要使用的服务。对于我们的应用程序,我们只有一个名为 db 的服务。
为了使我们的设置过程快速简单,我们使用预先构建的官方图片 MySQL 作为图片标签。
当我们使用 always 作为重启标签时,容器总是重启。这样可以节省时间。例如,您不必在每次手动重启机器时都启动容器。当 Docker 守护进程重新启动或者容器本身被手动重新启动时,它会重新启动容器。
在环境标签下,我们定义了环境变量,我们将使用这些变量进行数据库认证。
ports 标记用于定义主机端口和容器端口。它将主机上的端口 3307 映射到容器上的端口 3306。
最后,卷标签用于将文件夹从主机挂载到容器。它包含由冒号分隔的两个字段。第一部分是主机中的路径。第二部分是容器中的路径。如果您不想将 mysql-dump 挂载到容器中,请删除这一部分。
很好,你已经完成了这篇文章的设置。现在从docker-compose.yml
文件所在的目录运行下面的命令。命令docker compose up
启动并运行你的整个应用。
docker compose up
现在在主机上运行docker ps
命令,查看正在运行的容器列表。正如我们所看到的,我们有一个名为mysql-snippets_db_1
的运行容器。
docker ps
我们还可以看到一个图像是通过运行docker images
命令创建的。
docker images
通过运行以下命令来访问正在运行的容器mysql-snippets_db_1
。
docker exec -it mysql-snippets_db_1 bash
docker exec
命令允许我们进入正在运行的容器。标志-i -t
(通常写为-it
)用于以交互模式访问容器。现在我们提供想要访问的容器的名称,在本例中是mysql-snippets_db
。bash
命令用于获取容器内部的 bash shell,因此我们可以访问 MySQL 命令行并执行 MySQL 查询。
您刚刚完成了容器的设置。现在,我们将演练如何连接到 MySQL 服务器。
连接到 MySQL 服务器
使用您的用户名和密码root
连接到 MySQL 服务器。一旦连接到服务器,您就可以运行 MySQL 命令。
mysql -uroot -proot
这里有一个例子,你可以试试:
显示数据库;
我们可以看到名为 test_db 的数据库,它定义在我们的 Compose 文件中。要选择数据库,运行USE test_db;
命令。使用SHOW TABLES;
命令显示我们数据库 test_db 的所有表格。键入ctrl + L
清除控制台。
因为我们没有任何表,所以命令SHOW TABLES;
返回了一个空集。现在您已经确认您已经连接到 MYSQL 服务器,您可以进入下一步。
从文件中加载数据
现在我们可以将 MySQL 转储加载到我们的test_db
数据库中。在这种情况下是school.sql
。它在容器内部是可访问的,因为我们已经从主机装载了它。
mysql -uroot -p test_db < school.sql
使用用户名root
连接到 MySQL 服务器。输入密码root
进行验证。现在我们将默认数据库设置为test_db
。<
和文件名一起用于向服务器发送命令。
将 mysql 转储导入到 sql server
如果我们运行 MySQL 命令SHOW TABLES
,我们可以在数据库test_db
中看到两个名为 marks 和 students 的表,它们是在school.sql
中定义的。
包裹
像 MySQL 这样的关系数据库在行业中经常使用,所以这是一个您想要彻底了解的主题。现在您已经完成了这个基础教程,您可以使用 Docker 更深入地探索 MySQL。你可以在这里找到更多的 MySQL 命令。Docker 彻底改变了我们管理环境的方式,包括开发、测试和生产。这就是为什么你必须为个人和工业目的获得这种技能。希望这能帮助你入门 MySQL 和 Docker。
如何从脚本运行 Scrapy
忘掉 Scrapy 的框架,全部用使用 Scrapy 的 python 脚本来写。
Scrapy 是一个用于抓取项目的很好的框架。但是,您知道有一种方法可以直接从脚本运行 Scrapy 吗?
查看文档,有两种方法可以运行 Scrapy。使用 Scrapy API 或框架。
在本文中,您将了解到
- 为什么你会用剧本里的 scrapy
- 理解基本脚本,每次你想从一个单独的脚本访问 scrapy
- 了解如何指定定制的 scrapy 设置
- 了解如何指定 HTTP 请求供 scrapy 调用
- 了解如何在一个脚本下使用 scrapy 处理这些 HTTP 响应。
为什么要用剧本里的 Scrapy?
Scrapy 可以用于繁重的刮擦工作,但是,有很多项目非常小,不需要使用整个 scrapy 框架。这就是在 python 脚本中使用 scrapy 的原因。不需要使用整个框架,你可以从一个 python 脚本中完成所有工作。
在充实一些必要的设置之前,让我们看看这个的基本情况。
https://unsplash.com/@contentpixie
基本脚本
在 python 脚本中运行 scrapy 的关键是 CrawlerProcess 类。这是一个爬虫类模块。它提供了在 python 脚本中运行 scrapy 的引擎。在 CrawlerProcess 类代码中,导入了 python 的 twisted 框架。
Twisted 是一个 python 框架,用于输入和输出过程,例如 HTTP 请求。现在它通过一种叫做龙卷风事件反应堆的东西来做到这一点。Scrapy 是建立在 twisted 之上的!我们在这里不会涉及太多的细节,但是不用说,CrawlerProcess 类导入了一个 twisted reactor,它监听像多个 HTTP 请求这样的事件。这是 scrapy 工作的核心。
CrawlerProcess 假设 twisted 反应器没有被其他任何东西使用,例如另一个蜘蛛。
有了这些,我们就有了下面的代码。
import scrapy
from scrapy.crawler import CrawlerProcessclass TestSpider(scrapy.Spider):
name = 'test'if __name__ == "__main__":
process = CrawlerProcess()
process.crawl(TestSpider)
process.start()
- 现在我们要使用 scrapy 框架,我们必须创建我们的蜘蛛,这是通过创建一个继承自 scrapy.Spider. scrapy 的类来完成的。蜘蛛是所有 scrapy 项目中我们必须衍生的最基本的蜘蛛。有了这个,我们必须给这个蜘蛛一个名字让它运行/蜘蛛将需要几个函数和一个 URL 来抓取,但是对于这个例子,我们将暂时省略它。
- 现在你看
if __name__ == “__main__”
。这在 python 中被用作最佳实践。当我们编写一个脚本时,你希望它能够运行代码,而且能够将代码导入到其他地方。关于这一点的进一步讨论,请参见这里的。 - 我们首先实例化类 CrawlerProcess 来访问我们想要的函数。CrawlerProcess 有两个我们感兴趣的函数,爬行和启动
- 我们使用爬行来启动我们创建的蜘蛛。然后,我们使用 start 函数启动 twisted reactor,这个引擎处理并监听我们想要的 HTTP 请求。
在设置中添加
scrapy 框架提供了一个设置列表,它将自动使用,但是为了使用 Scrapy API,我们必须明确地提供设置。我们定义的设置是我们如何定制我们的蜘蛛。蜘蛛。蜘蛛类有一个变量叫做custom_settings
。现在这个变量可以用来覆盖 scrapy 自动使用的设置。我们必须为我们的设置创建一个字典来做到这一点,因为使用 scrapy 将custom_settings
变量设置为无。
你可能想使用 scrapy 提供的一些或大部分设置,在这种情况下,你可以从那里复制它们。或者,可以在这里找到内置设置列表。
class TestSpider(scrapy.Spider):
name = 'test'
custom_settings = { 'DOWNLOD_DELAY': 1 }
https://unsplash.com/@ericjamesward
指定要抓取的 URL
我们已经展示了如何创建一个蜘蛛并定义设置,但是我们还没有指定任何要抓取的 URL,或者我们想要如何指定对我们想要从中获取数据的网站的请求。例如,参数、头和用户代理。
当我们创建 spider 时,我们还启动了一个叫做start_requests()
的方法。这将为我们想要的任何 URL 创建请求。现在有两种方法可以使用这个方法。
1)通过定义start_urls
属性
2)我们实现了我们的函数start_requests
最短的方法是通过定义start_urls
。我们将它定义为我们想要获取的 URL 列表,通过指定这个变量,我们自动使用start_requests()
遍历我们的每个 URL。
class TestSpider(scrapy.Spider):
name = 'test'
custom_settings = { 'DOWNLOD_DELAY': 1 }
start_urls = ['URL1','URL2']
但是请注意,如果我们这样做,我们不能指定我们的头,参数或任何其他我们想随请求?这就是实现我们的start_requests
方法的原因。
首先,我们定义我们希望与请求一致的变量。然后我们实现我们的start_requests
方法,这样我们就可以利用我们想要的头和参数,以及我们想要响应去哪里。
class TestSpider(scrapy.Spider):
name = 'test'
custom_settings = { 'DOWNLOD_DELAY': 1 }
headers = {}
params = {} def start_requests(self):
yield scrapy.Requests(url, headers=headers, params=params)
这里我们访问 Requests 方法,当给定一个 URL 时,它将发出 HTTP 请求并返回一个定义为response
变量的响应。
你会注意到我们没有指定回调。也就是说,我们没有指定 scrapy 应该将response
发送到哪里,我们只是告诉它为我们获取请求。
让我们来解决这个问题,默认情况下,scrapy 希望回调方法是解析函数,但它可以是我们想要的任何东西。
class TestSpider(scrapy.Spider):
name = 'test'
custom_settings = { 'DOWNLOD_DELAY': 1 }
headers = {}
params = {} def start_requests(self):
yield scrapy.Requests(url, headers=headers, params=params,callback = self.parse) def parse(self,response):
print(response.body)
这里我们定义了接受响应变量的函数parse
,记住这是在我们让 scrapy 执行 HTTP 请求时创建的。然后,我们要求 scrapy 打印响应正文。
至此,我们已经有了在 python 脚本中运行 scrapy 的基础。我们可以使用所有相同的方法,但我们只需要事先做一些配置。
练习
- 为什么你会使用 scrapy 框架?在 python 脚本中导入 scrapy 什么时候有用?
CrawlerProcess
班是做什么的?- 您能回忆起 python 脚本中用于启动 scrapy 的基本脚本吗?
- 如何在你的 python 脚本中添加 scrapy 设置?
- 为什么你会使用
start_requests
函数而不是start_urls
?
请参见这里的了解我在博客和其他帖子上关于项目的更多细节。更多技术/编码相关内容,请点击这里订阅我的简讯
我将非常感谢任何评论,或者如果你想与 python 合作或需要帮助,请联系我。如果你想和我联系,请在这里联系。
你可能喜欢的其他文章
如何轻松增强 python 的基础知识
medium.com](https://medium.com/swlh/5-python-tricks-you-should-know-d4a8b32e04db) [## 揭开杂乱物品装载器的神秘面纱
自动清理和扩展你的垃圾蜘蛛
towardsdatascience.com](/demystifying-scrapy-item-loaders-ffbc119d592a)
如何从 Jupyter 笔记本运行 SQL 查询
SQL IDEs 不能可视化数据。您知道吗,您可以使用 Jupyter 笔记本运行并可视化查询结果?
本·怀特在 Unsplash 上的照片
如果你在数据科学领域工作,你很可能会使用 SQL 来提取和预处理数据。我使用 JetBrains DataGrip 作为我的主要 SQL 编辑器已经有一段时间了。虽然 DataGrip 做得不错,但它没有提供可视化数据的方法。有没有更好的办法?
这里有几个你可能会感兴趣的链接:
- [Complete your Python analyses 10x faster with Mito](https://trymito.io/) [Product]- [Free skill tests for Data Scientists & ML Engineers](https://aigents.co/skills) [Test]- [All New Self-Driving Car Engineer Nanodegree](https://imp.i115008.net/c/2402645/1116216/11298)[Course]
你愿意多看一些这样的文章吗?如果是这样,你可以点击上面的任何链接来支持我。其中一些是附属链接,但你不需要购买任何东西。
用于 SQL 的 ide
Gif 来自 Giphy
SQL 的集成开发环境通常不具备可视化查询结果的能力。在我看来,这是一件好事,因为每个 IDE 都有自己专有的方式来可视化数据,这是我们需要学习的。
我可视化数据的工作流程是:在 SQL IDE 中开发并执行查询,将数据导出到 CSV 并在 Jupyter 笔记本中可视化。
在 Jupyter 笔记本中运行查询
Gif 来自 Giphy
当查询结果太大而无法在单个查询中处理时,该怎么办?一种解决方案是以更短的时间间隔运行查询,而不是一整年,您可以按月运行查询。
按月运行一个查询需要一年运行 12 次,这对于手工来说是不可行的——因为循环在这里很有用。
拥有多种工具总是好的
当面临这样的问题时,我一直使用 SQLAlchemy 连接到数据库,并将数据提取到 pandas DataFrame,如下例所示:
import sqlalchemy
import pandasengine = sqlalchemy.create_engine(
sqlalchemy.engine.url.URL(
drivername="postgresql",
username="username",
password="password",
host="host",
port="port",
database="database",
),
echo_pool=True,
)
print("connecting with engine " + str(engine))
connection = engine.connect()query = "select * from table"df = pd.read_sql_query(query, connection)
正如您在上面看到的,SQL 查询是用字符串编写的。即使您将查询字符串放在 Jupyter 笔记本的一个单独的单元格中,并且安装了格式化的 SQL 代码,它也不会格式化查询,因为它仍然是一个 Python 字符串。
有没有更好的办法?
认识 ipython-sql
ipython-sql 使我们能够直接从 Jupyter 笔记本上运行 sql 查询。无需编写多行代码来连接数据库或将查询包装在字符串中。ipython-sql 使得从 Jupyter Notebook 查询数据库更加“干净”。
使用 ipython-sql 查询 SQLite 数据库
要安装 ipython-sql,只需在 Jupyter 笔记本中运行以下命令:
!pip install ipython-sql
然后加载 SQL 模块:
%load_ext sql
我们需要一个连接字符串来连接数据库。对于 SQLite,它非常简单:
%sql sqlite://
如果您以前使用过 SQLAlchemy 连接到数据库,您可以使用下面的代码来获得连接字符串:
print("connecting with engine " + str(engine))
注意,每个单元格都需要用%%sql 注释。这告诉 Jupyter 笔记本,单元格中的代码是 SQL。
让我们将示例数据添加到 SQLite 数据库中:
%%sql
CREATE TABLE sales
(
key varchar(6),
ts timestamp,
product integer,
completed boolean,
price float
);
INSERT INTO sales
VALUES ('sale_1', '2019-11-08 00:00', 0, TRUE, 1.1),
('sale_2', '2019-11-08 01:00', 0, FALSE, 1.2),
('sale_3', '2019-11-08 01:00', 0, TRUE, 1.3),
('sale_4', '2019-11-08 01:00', 1, FALSE, 1.4),
('sale_5', '2019-11-08 02:00', 1, TRUE, 1.5),
('sale_6', '2019-11-08 02:00', 1, TRUE, 1.5);
现在,让我们查询数据库
%%sqlselect * from sales;
非常管用!
我们只运行了查询,但是结果没有分配给任何变量,这没有多大用处。幸运的是,Jupyter Notebook 使我们能够将一个单元格的先前输出设置为一个变量:
result = _
让我们检查结果变量的类型:
type(result)# sql.run.ResultSet
现在,让我们使用以下方法将结果集直接转换为 pandas 数据帧:
df = result.DataFrame()
这使我们能够交互式地探索数据。
在你走之前
在推特上关注我,在那里我定期发关于数据科学和机器学习的推特。
照片由Courtney hedge在 Unsplash 上拍摄
如何对数据进行采样(使用代码)
使用 Cochran 公式采样——在 Python、R 和 Excel 中
凯文·Ku 在 Unsplash 上的照片
对于任何处理数据的人来说,采样都是一项至关重要的技能。尽管如此,令人惊讶的是很少有人做对。通常,取样是根据判断而不是逻辑进行的。
对我们来说幸运的是——对数据集进行采样是一项极其简单的任务。
在本文中,我们将介绍计算样本大小的 Cochran 公式,它不会使我们的测试无效。
我们将包括简单的数学方法和符号,展示我们如何手动计算它们——然后继续用 Python、R 和 Excel 实现。
最后,我们将组装一个快速样本大小计算器来演示采样有多简单。
关键参数
- confidence level
- margin of error
- target proportion
所以,我们有一个数据集。我们需要对这个数据集的一部分进行采样,以便进行一些手动的定性分析。
从统计学上来说,我们需要足够大的样本量,才能确信我们所取的样本准确地代表了原始总体(数据集)。这个置信度被称为置信度。
95%的置信度是最常见的——这是我们将在本文通篇使用的。但是,如果需要更多/更少的置信度,我们只需调整我们的公式输入。
通常,我们的分析对样本和总体代表之间的微小差异不敏感。因此,我们接受一定程度的灵活性,我们称之为误差幅度。同样,典型值约为 5%。
将两者放在一起,我们可以 95%确信我们计算的样本平均值在 5%的范围内等于总体平均值。
最后一个参数目标比例是提供目标属性的样本的百分比。当这一点不清楚时(几乎总是如此),简单地使用 50% —最坏的情况。
对我们的数据进行采样
我们现在需要为我们的测试或开发过程提取这些数据的样本。
我们如何知道我们的样本应该有多大才能准确地代表我们的总体?
这就是我们可以使用科克伦公式的地方:
使用该公式,我们可以计算满足我们要求的误差范围和置信水平所需的样本量。如果我们要查看数据集中的特定属性,我们还可以指定包含该属性的估计人口比例,尽管这不是必需的。
因此,我们有一个包含 100,000 条记录的数据集。我们的样本中应该包括多少这样的样本?
假设我们希望我们的样本有 95%的把握正确代表总体。我们也可以接受 5%的误差率。
population size: 100K - **N = 100000**
confidence level: 95% - **cl = 0.95**
margin of error: 5% - **e = 0.05** target proportion: 50% - **p = 0.5**
首先,我们有了计算 n₀ 所需的所有参数,除了z(z 分数)。为了找到 z 分数,我们将从0.95
到0.475
的置信水平减半,然后在 z 分数表中查找这个值,这给出了1.96
。
我们在表中发现我们的置信水平减半为 0.475。z 值由坐标轴上的值给出, 1.9 + 0.06 ,得出 1.96 。在这里找到表格。
或者,我们可以使用 Python、R 或 Excel 来计算。
**Python**
-----
import scipy.stats as st
st.norm.ppf(1-(1-**0.95**)/2)
**[Out]:** 1.959964
**R**
-----
qnorm(1-(1-**0.95**)/2)
**[1]:** 1.959964
**Excel**
-----
=NORMSINV(1-(1-**0.95**)/2)
1.959964
注意,在每个代码中,我们执行相同的1-(1-0.95)/2
计算。这是因为每个实现都会计算左尾单分布的 z 得分,如下所示:
相反,我们想要的是一个居中对齐的区域,看起来像这样:
现在我们有了所有需要的值,我们计算 n₀:
为了满足我们的抽样需求,我们应该将这个数据四舍五入为385
个记录。我们取整,因为这是我们的阈值——任何低于384.15
的都将具有低于 95%的置信水平,或者大于 5%的误差幅度。
要在代码中执行此计算,我们需要执行以下操作:
**Python**
-----
z**2 * p * (1 - p) / e**2
**[Out]:** 384.15
**R**
-----
z^2 * p * (1 - p) / e^2
**[1]:** 384.15
**Excel** *(replace each letter with the respective cell)*
-----
=z^2*p*(1-p)/e^2
384.15
第二个公式是我们用于小数据集的公式;它根据总体规模 N 调整我们所需的样本规模。
较小的数据集将减少所需样本的数量,而较大的数据集则不会。
使用我们的总体规模**N = 100,000**
会导致我们所需的样本规模略有减少:
给我们一个最终所需的**383**
记录的样本量。在代码中再次执行同样的计算,我们得到:
**Python**
-----
n_0 / (1 + (n_0 - 1) / N)
**[Out]:** 382.68
**R**
-----
n_0 / (1 + (n_0 - 1) / N)
**[1]:** 382.68
**Excel** *(replace each letter with the respective cell)*
-----
=n_0/(1+(n_0-1)/N)
382.68
这样,我们就有了一个简单的、可重复的方法来计算样本量。如果我们更进一步,我们可以用代码实现整个过程,使我们未来的采样更加容易。
在 Python 中,我们可以构建一个简单的样本大小计算器,如下所示:
使用前面示例中的相同参数,我们可以轻松计算样本大小:
sample(100000, 0.95, 0.05, 0.5)
[Out]: 383
我们还可以看到人口规模如何影响较小样本的计算:
sample(**500**, 0.95, 0.05, 0.5)
**[Out]:** 218
sample(**20**, 0.95, 0.05, 0.5)
**[Out]:** 20
sample(**1e8**, 0.95, 0.05, 0.5)
**[Out]:** 385
当然,我们在 R 和 Excel 中也是这样做的,将我们之前讨论过的代码串连在一起。
我们已经从理论和实现两方面介绍了样本量计算的基础知识。
对于不同数据专业中的大多数采样要求,您不需要比这更复杂的东西——Cochren 的公式广泛适用,并且非常容易实现。
如果您有任何问题或建议,请在下面的回复中告诉我!
感谢阅读!
如何在 PyTorch 中保存和加载模型,并附有完整的示例
如何在 PyTorch 中保存和加载模型的实例。我们将看看如何继续训练和加载模型进行推理
詹姆斯·哈里逊在 Unsplash 上拍摄的照片
T 这篇文章的目的是告诉你如何保存一个模型,并在上一个时期后加载它继续训练,并做出预测。如果你正在阅读这篇文章,我假设你熟悉深度学习和 PyTorch 的基础。
你有没有经历过这样的情况,你花了几个小时或几天训练你的模型,然后它在中途停止?还是对自己的模特表现不满意,想重新训练模特?我们可能需要一种灵活的方式来保存和加载我们的模型,这有多种原因。
Kaggle、Google Colab 等大多数免费云服务都有空闲超时,会断开你的笔记本,加上笔记本一旦达到限制时间就会断开连接或中断。除非你用 GPU 训练少量的纪元,否则这个过程需要时间。能够保存模型会给你带来巨大的优势并扭转局面。为了灵活起见,我将保存最新的检查点和最佳的检查点。
时尚 _ MNIST _ 数据将被用作我们的数据集,我们将从导入数据编写一个完整的流程来进行预测。在这个练习中,我将使用一个 Kaggle 笔记本。
步骤 1:设置
- 在 Kaggle 中,你正在操作的笔记本默认叫做 notebook。ipyn
- 创建两个目录来存储检查点和最佳模型:
步骤 2:导入库和创建助手函数
导入库
保存功能
创建 save_ckp 是为了保存检查点,最新的和最好的检查点。这就产生了灵活性:要么您对最新检查点的状态感兴趣,要么对最佳检查点感兴趣。
在我们的例子中,我们希望保存一个检查点,使我们能够使用这些信息来继续我们的模型训练。以下是所需的信息:
- 时期:所有训练向量被使用一次来更新权重的次数的度量。
- valid_loss_min :最小验证损失,这是需要的,以便当我们继续训练时,我们可以从这个而不是 np 开始。Inf 值。
- state_dict :模型架构信息。它包括每一层的参数矩阵。
- 优化器:您需要保存优化器参数,尤其是当您使用 Adam 作为优化器时。Adam 是一种自适应学习率方法,这意味着,它计算不同参数的个人学习率,如果我们想从我们离开的地方继续我们的训练,我们将需要这些参数[2]。
加载功能
load_chkp 是为加载模型创建的。这需要:
- 保存的检查点的位置
- 要将状态加载到的模型实例
- 优化器
步骤 3:导入数据集时尚 _ MNIST _ 数据并创建数据加载器
步骤 4:定义和创建模型
我使用的是来自[1]的简单网络
输出:
FashionClassifier(
(fc1): Linear(in_features=784, out_features=512, bias=True)
(fc2): Linear(in_features=512, out_features=256, bias=True)
(fc3): Linear(in_features=256, out_features=128, bias=True)
(fc4): Linear(in_features=128, out_features=64, bias=True)
(fc5): Linear(in_features=64, out_features=10, bias=True)
(dropout): Dropout(p=0.2)
)
步骤 5:训练网络并保存模型
训练功能使我们能够设置时期数、学习率和其他参数。
定义损失函数和优化器
下面,我们使用 Adam 优化器和交叉熵损失,因为我们把字符类分数作为输出。我们计算损耗并进行反向传播。
定义培训方法
训练模型
输出:
Epoch: 1 Training Loss: 0.000010 Validation Loss: 0.000044
Validation loss decreased (inf --> 0.000044). Saving model ...Epoch: 2 Training Loss: 0.000007 Validation Loss: 0.000040
Validation loss decreased (0.000044 --> 0.000040). Saving model ...Epoch: 3 Training Loss: 0.000007 Validation Loss: 0.000040
Validation loss decreased (0.000040 --> 0.000040). Saving model ...
让我们关注一下上面使用的几个参数:
- start_epoch:训练的值 epoch 的开始
- n_epochs:训练的值 epoch 的结束
- 有效 _ 损失 _ 最小 _ 输入= np。中程核力量
- checkpoint_path:保存训练的最新检查点状态的完整路径
- 最佳模型路径:训练的最新检查点的最佳状态的完整路径
验证模型是否已保存
- 列出 best_model 目录中的所有文件
输出:
best_model.pt
- 列出检查点目录中的所有文件
输出:
current_checkpoint.pt
步骤 6:加载模型
重建模型
输出:
FashionClassifier(
(fc1): Linear(in_features=784, out_features=512, bias=True)
(fc2): Linear(in_features=512, out_features=256, bias=True)
(fc3): Linear(in_features=256, out_features=128, bias=True)
(fc4): Linear(in_features=128, out_features=64, bias=True)
(fc5): Linear(in_features=64, out_features=10, bias=True)
(dropout): Dropout(p=0.2)
)
定义优化器和检查点文件路径
使用 load_ckp 函数加载模型
我打印出了我们从 load_ckp 得到的值,只是为了确保一切都是正确的。
输出:
model = FashionClassifier(
(fc1): Linear(in_features=784, out_features=512, bias=True)
(fc2): Linear(in_features=512, out_features=256, bias=True)
(fc3): Linear(in_features=256, out_features=128, bias=True)
(fc4): Linear(in_features=128, out_features=64, bias=True)
(fc5): Linear(in_features=64, out_features=10, bias=True)
(dropout): Dropout(p=0.2)
)
optimizer = Adam (
Parameter Group 0
amsgrad: False
betas: (0.9, 0.999)
eps: 1e-08
lr: 0.001
weight_decay: 0
)
start_epoch = 4
valid_loss_min = 3.952759288949892e-05
valid_loss_min = 0.000040
加载完所有需要的信息后,我们可以继续训练,start_epoch = 4。以前,我们从 1 到 3 训练模型
第七步:继续训练和/或推断
继续训练
我们可以继续使用 train 函数训练我们的模型,并提供我们从上面的 load_ckp 函数中获得的检查点的值。
输出:
Epoch: 4 Training Loss: 0.000006 Validation Loss: 0.000040
Epoch: 5 Training Loss: 0.000006 Validation Loss: 0.000037
Validation loss decreased (0.000040 --> 0.000037). Saving model ...
Epoch: 6 Training Loss: 0.000006 Validation Loss: 0.000036
Validation loss decreased (0.000037 --> 0.000036). Saving model ...
- 注意:纪元现在从 4 点到 6 点开始。(开始时间= 4)
- 验证丢失从最后一个训练检查点开始继续。
- 在时期 3,最小验证损失是 0.000040
- 这里,最小验证损失从 0.000040 开始,而不是 INF
推理
请记住,在运行推理之前,您必须调用 model.eval()将丢弃和批处理、规范化图层设置为评估模式。不这样做将产生不一致的推理结果[3]。
输出:
Accuracy of the network on 10000 test images: 86.58%
在 Kaggle 笔记本中哪里可以找到输出/保存的文件
在您的 Kaggle 笔记本中,您可以向下滚动到页面底部。在之前的操作中保存了一些文件。
这是我在 Kaggle 的笔记本:
https://www . ka ggle . com/vortanasay/saving-loading-and-cont-training-model-in-py torch
参考:
- [1] S. David,在 PyTorch 中保存和加载模型(2019),https://www . ka ggle . com/davidashraf/Saving-and-Loading-Models-in-py torch
- [2] J. Rachit,保存并加载您的模型以在 PyTorch 中恢复培训(2019),https://medium . com/analytics-vid hya/Saving-and-Loading-Your-Model-to-Resume-Training-in-py torch-CB 687352 fa 61
- [3]一、马修,保存和加载模型(2017),https://py torch . org/tutorials/初学者/saving_loading_models.html