如何利用机器学习在 Reddit 上做预测:多元逻辑回归
这是来自四个不同市场的四个屏幕截图。共同的元素?卖家评分。
评级来自 Amazon.com,Google.com,Facebook.com 和 Ebay.com
卖家评级是每个好市场的要求。评级系统是帮助买家做出决策的重要工具,允许他们分享自己的感受,最重要的是,向他们保证交易的合法性。当然,永远不可能保证交易安全,但良好的卖家评级确实能激发信心。
考虑到评级系统的重要性,每个市场都有一个内置的交易促进系统来对卖家进行评级。但是那些不是用来买卖的平台呢?比如: Reddit 。
Reddit:论坛变成市场
Reddit.com 是美国访问量排名第六的网站,它是一个论坛集合,人们在这里发布和评论链接、图片和讨论话题。Reddit 中的各个论坛或社区被称为子编辑,有超过 100 万个这样的子编辑。Reddit 的成员被称为“Redditors”,他们将内容提交给子编辑,其他成员可以“投赞成票”或“投反对票”。正如你所想象的,Reddit(它的名字是对“阅读”这个词的一个游戏)本来是一个讨论的地方,尽管它在很大程度上仍然是,一些社区已经变成了市场。还有很多这样的例子。
这里列出了 Reddit 上一些受欢迎的市场,以及在撰写本文时订阅每个市场的会员数量。
仅仅 8 个社区就有将近 65 万人!
我相信 Reddit 上的市场很受欢迎,因为 Reddit 的社区意识通常会带来合理的价格和成功的交易。然而,由于 Reddit 最初不是为此目的而设计的,与易贝等传统市场相比,它的界面存在许多问题。
例如,下面是一个典型的用户帖子:
Reddit.com 的纱帽
邮报是提供一个 BNIB 海盗船 SF750 白金 PSU(电源设备)为 150 美元以上的航运。但是,没有度量标准来确定该用户在该子编辑中是否有任何事务历史,也没有任何方法来确定该用户是否合法。此外,在这篇文章中,作者写了原始价格,但在其他情况下,潜在的买家需要自己研究产品,以确定其原始零售价格。
使用机器学习解决 Reddit 的“无评级”问题
看着 Reddit 市场的工作方式,我构建了一个算法来帮助解决缺乏专用评级系统带来的问题。
我认为这将是一个应用机器学习和 Python 自动化的有趣问题。这个项目的目标是看看我是否能收集到足够的数据,以确定与任何给定的 Reddit 用户进行交易的风险有多大。为了收集这些数据,我查看了参与成功交易的 Reddit 用户,然后确定了被发现实施欺诈的用户。本质上,我比较了两组 Redditors:骗子和非骗子。我比较的一些属性是:
●账户的年龄
●因果报应(票数上升)
●经过验证的电子邮件地址
●黄金(如果是付费账户)
●评论(使用自然语言处理进行分析)
●版主(任何子编辑)
●访问的子街道
●奖杯
Reddit.com 的纱帽
通过观察这两个组的用户活动,我试图确定某个账户是高风险还是低风险。
为了使项目的范围易于管理,我将重点放在了子编辑r/硬件交换上。HardwareSwap 是一个由超过 170,000 名成员组成的社区,他们相互交换与计算机相关的硬件。在这个 Subreddit 中,你可以找到从显卡和 CPU 到 PlayStations 和计算机外设的所有东西。
探索性数据分析
当处理我正在调查的关于 Reddit 用户和市场的问题时,第一步是做一个探索性数据分析。在此分析中,我将使用或研究:
● PRAW (Python Reddit API 包装器)
●交易
●参与交易的用户
●交易方向(买与卖)
●交易的估计价格
PRAW (Python Reddit API 包装器)
为了访问 r/hardware WAP 数据,我注册了一个 Reddit API 密匙。你可以在这里找到 PRAW 的快速入门指南和其他文档。首先,我需要在 Reddit、上注册一个应用程序,然后我收到一个 Reddit 客户端 ID 和客户端密码。
Reddit 应用程序注册表单的屏幕截图。Reddit.com 的纱帽
收集用于探索性数据分析(EDA)的硬件应用程序数据
现在我有了我的 Reddit API 密钥,我可以开始收集我需要的数据:交易的细节、用户、方向和估计的交易价格。因为我这个项目的主要目标是比较两组 redditor——合法用户和骗子(以及如何识别他们?)—我将从收集这些群体的数据开始。
交易
subreddit r/HardwareSwap 有一个确认线程,用户每个月都会在这个线程中确认他们成功的交易。这使得为 Reddit 用户收集交易细节成为可能。
下面是【2019 年 12 月确认线程的截图,让你对其格式有个概念:
示例确认线程。Reddit.com 的纱帽
我首先收集了我想要调查的时间段(72 个月)的所有每月确认线程 URL。为了做到这一点,我用 PRAW 写了一个函数,在 r/hardware swap subredit 中搜索标题中带有“已确认贸易线索”字样的所有帖子。
Github 链接到上述功能。
参与交易的用户
这个搜索产生了过去 72 个已确认交易线索的 URL 列表,代表了大约 6 年的数据。然后,我使用 Reddit API 从 72 个已确认的交易线索中提取相关的特定数据。我的主要目标是收集以下信息:
●参与交易者的用户名
●谁与谁交易的数据(买方和卖方)
●购买/出售的数据
为了收集这些数据,我编写了另一个函数来完成以下任务:
●从 confirm_urls 函数中获取 URL 列表(在上面的截图中以亮蓝色文字书写)。
●查看所有父评论并收集
1)评论者的用户名
2)父注释的文本
3)文本和天赋(已确认交易的数量)。
●添加(使用 Python 字典)注释的作者作为键,添加列表的列表作为值,其中存储了注释的正文和与进行交易的用户的信息。
每个结果数据点如下所示:
示例字典键、值对
如上所述,Python 字典中的键就是这样创建的:通过附加用户名(child.group()[2:])和 body_text,如上面的代码所示。如果字典中的用户有不止一个事务(这是常见的情况),那么该函数会向值中存储的列表添加另一个条目。
交易方向
最后,我想检测每个交易的方向:也就是说,它是被描述为买入还是卖出。然而,在我第一次浏览代码的过程中,我发现还有第三个类别:“交易”,这发生在两个用户互相交易物品但没有交换货币的情况下。
为了确定每笔交易的方向,我在评论中寻找常用词——例如,“买”、“买”、“卖”或“交易”——并将它们放入一个列表,然后与一串文本进行比较。如果这些常用词出现在给定的字符串中,那么我就知道交易的方向。最后,我为我的功能无法确定方向的事务添加了一个“模糊”类别。下面的代码记录了每笔交易的方向:
Github 链接到上面的函数
**注意:**使用 PRAW 提取所有这些数据需要大约 18 个小时。所以,如果你想自己尝试一下,我建议你通宵运行这个程序。
最后,埃达!
现在,到探索性数据分析组件。r/HardwareSwap 这个子字段的总价值和活动是我的风险分析非常需要的。使用我在上面描述的数据集合,我创建了一个 Pandas 数据框架,其中包括每个交易的用户、交易者、方向和产品的数据。
交易数据帧的前 5 行
上面的截图是交易数据帧的前 5 行。方向指示用户是购买还是出售产品。例如,在第 0 行中,用户 orevilo 销售给 veigs。
我得到的结果令人印象深刻。使用这个图表,我发现在过去的 6 年中,这个子 reddit 上至少有 134,013 个事务。
以下是按类型分列的交易明细:
这四个值加起来有 134,013 笔交易。对于一个细分市场来说,这是一个令人印象深刻的大数字。
预计成交价格
当我看到这些数字时,我想知道一笔交易的平均价格,从而了解有多少价值通过 r/hardware WAP 流动。虽然得到的值是近似值,但这是一个有趣的度量。为了估计平均交易价格,我构建了一个函数,它查看过去 1,000 个交易提交,并选择 link_flair_css_class 关闭的提交,这意味着已经进行了交易。
在下图中,你可以看到不同的提交标志:(卖出,买入和平仓)
link_flair_css_class 卖出(蓝色),买入(绿色),成交(红色)。Reddit.com 的纱帽
然后,该函数检查提交的主体中卖方列出的价格;我使用正则表达式并寻找$符号后面的数字。此外,该函数返回一个包含价格、日期和 URL 的 Pandas 数据框,以便我可以检查近似值是否正确。
平均价格 258
这种方法得出 2019 年 12 月 12 日至 2019 年 12 月 15 日期间的平均样本交易价格为 258 美元。如果我们将这个数字乘以 134,000 笔记录的交易,过去 6 年中在 r/HardwareSwap 上交易的产品总价值估计约为 34,500,000 美元。虽然这是一个极端的估计,但即使是这一数额的四分之一,也仍然是一笔巨款。
多元逻辑回归
该项目的目标是创建一个指标来确定与一个给定的 Reddit 用户交易的风险水平。Reddit 上的欺诈活动并不多,但确实存在。这个项目旨在发现与合法 Redditors 的活动相关的模式,与欺诈用户(骗子)的活动形成对比。
考虑到 Reddit 不保留交易历史或收集任何有关其用户的真实身份信息,解决与欺诈相关的问题是一个相当困难的问题,因为与传统的信用指标和社交平台相比,Reddit 提供的指标并不典型地用于衡量风险。Reddit 不会收集创建特定于每个成员的信息记录所需的详细个人信息,因此,成员具有高度的匿名性。
鉴于这个问题,知道是否可以使用机器学习和 Reddit 允许用户从中提取的信息进行准确的预测将是非常有趣的。在这个项目中,我试图根据用户的 Reddit 活动来衡量他或她的风险水平。我首先想到的是使用**多元逻辑回归模型,**一种用于预测因变量结果的统计分析。在这个领域,它可以被称为机器学习模型。我将利用这个模型,因为只有有限数量的功能可供使用。多重逻辑回归模型将允许我确定与预测 Reddit 用户风险水平最相关的特征。
首先,我将确定项目中正在研究的两(2)组。这些是:
1.Reddit 用户/Redditors: 这些人在 Reddit 上做过真正的交易。他们已经完成了交易。
- **Reddit 骗子:**这些是 Reddit 上的骗子,参与过各种诈骗活动。
Reddit 骗子数据集是从 r/hardwareswap 的封禁列表和通用封禁列表中收集的。这些都是被版主发现有欺诈行为的用户名单。因为这是任何市场分支提供的唯一系统,我不得不相信所有这些用户都是骗子。
现在我将使用 Reddit API 来收集 Reddit 用户和 Reddit 骗子的相关特性的数据。之后,我会查看数据,看看是什么将这两组分开。
对于第一个模型,我将研究的相关特性如下:
1.已验证的电子邮件地址(用户是否有)
2.用户是否是任何子编辑的版主
3.Reddit Gold
4.因果报应的数量
5.帐龄
6.最近的评论(最多 100 条)
利用这 6 个特征,我希望发现 Redditor 和 Scammer 群体之间的不同模式。
**注意:**您可能想在https://praw . readthe docs . io/en/latest/code _ overview/models/redditor . html查看可用的 PRAW 属性(查看 Redditor 对象属性的完整列表)。
评估 6 个特性
- 帐龄
Praw 属性。https://praw.readthedocs.io 中的屏幕帽
PRAW 属性
任何用户帐户的 PRAW 属性之一是“created_utc”,它指的是帐户的创建日期。为了将这变成一个有用的特性,我决定创建一个名为“ age”的变量age 变量获取 created_utc 属性中指示的日期,并从用户最后一次评论的时间中减去该日期。通常,骗子被抓后,他们的账户会休眠。因此,为了确定他们的账户在诈骗发生时的年龄,我查看了从每个账户创建日期到最近一次评论日期的时间长度。
上图比较了骗子(橙色)和 Redditors(蓝色)。从图表中可以明显看出,骗子有更高比例的帐户年龄为 1 年或更短,而 Redditors 的帐户平均年龄要大得多。这是有道理的,因为我认为打算诈骗的人不会使用他们已经联系了很长一段时间的 Reddit 账户;然而,也有大量超过 4 年的骗子账户。我不得不认为,这是由于一些被标记为骗子的 Redditors 陷入了某种纠纷,而调解人无法解决,最终买方/卖方都被标记为骗子。也有可能是一些骗子被抓了,但就是不在乎,继续用自己的账号。
2。 因缘
Praw 属性。来自的屏幕帽 https://praw.readthedocs.io
PRAW 属性
“因果报应”指的是用户提交的内容被投票支持时得到的分数。
因果报应的分布显示,骗子拥有 30 或更少因果报应点数的帐户比例要高得多。另一方面,Redditors 的分布更为正常。
3。 电子邮件地址
Praw 属性。来自https://praw . readthedocs . io的屏幕盖
与骗子相比,Redditors 拥有经过验证的电子邮件地址的比例要高得多。
4。REDDIT GOLD
Praw 属性。来自https://praw . readthedocs . io的屏幕盖
Reddit Gold 表示用户拥有付费的 Reddit 帐户(Premium)。看到有骗子有 Reddit 黄金,我很惊讶;当 Reddit 大部分是免费的时候,一些骗子为他们用来诈骗的账户付费,这似乎很可疑。这一事实可能是真实用户被错误地标记为骗子的结果。
5。 主持人
Praw 属性。来自https://praw . readthedocs . io的屏幕盖
更大比例的 reddits 是 Subreddits 的版主。这是我所期待的,因为骗子可能不会使用他们诈骗某人时使用的相同帐户来努力调节 Subreddits。
6。备注
你可以看到评论少于 10 条的骗子数量激增。这是我想在未来重新审视的一个变量。Reddit API 允许每个用户最多 1000 条评论,但我只选取了最后 100 条作为案例研究。
我仔细研究这些个体变量的原因是为了在 Redditors 和 scammers 的活动中找到一个明显的差异。我已经能够使用机器学习来实现这一点。对于每个变量,两组之间活动分布的差异都有明确的定义。我坚信,如果我们认识到所有 6 个特征,那么我们将能够对 Reddit 账户及其风险水平做出准确的预测。
多元逻辑回归模型
在这个项目中,我对使用我上面讨论的变量预测定性结果感兴趣。这可以称为对观察结果进行分类,因为它涉及将观察到的数据分配到特定类别,在这种情况下,该类别可以是 Redditor 或 Scammer。具体来说,对于这个分类项目,我打算使用多元逻辑回归模型来预测一个观察的概率。几乎不可能肯定地说某个 Reddit 用户是骗子,但他/她的活动与欺诈用户的活动相匹配的概率是一个更现实的指标。
一个多重逻辑回归方程,其中 X = (X1,X2,……,Xp)是 p,预测因子,看起来是这样的:
数据分布
包装:
- Numpy —支持大型多维数组和矩阵
- 熊猫—数据处理和分析
- Sklearn —机器学习库
- Statsmodel —探索数据,估计统计模型,并执行统计测试
执行回归
对于这个模型,预测变量将是电子邮件、版主、黄金、因果、年龄和评论,而目标变量将是用户名。目标变量中的数字“0”代表 Redditor,而数字“1”代表 scammer。
以黄色突出显示的岭回归参数
L2 正则化—岭回归
正则化可用于训练模型,通过防止算法过度拟合训练数据集,可以更好地对看不见的数据进行归纳。岭回归通过引入一条带有少量偏差的新的最佳拟合线来做到这一点,作为回报,它得到了方差的显著下降。随着新数据被引入模型,这有助于更好地进行长期预测。
L2 方程
wikipedia.com 的纱帽
除 y 轴截距之外的每个参数都按脊线缩放。
现在我已经做了一些模型调优,是时候使用 Sklearn 运行模型了。
下面是模型在分析测试变量数据后给出的结果总结。
总的来说,多重逻辑回归模型做得很好,预测远远超过随机的 50/50 猜测。该模型的准确度(显示在黄色矩形中)为 83%。然而,在继续这个模型之前,我想看一下 p 值,以确保所有的变量都是显著的。我将利用 Statsmodel 库来解释我得到的结果,因为这个库给出了比 Sklearn 好得多的 p 值汇总。
在上面的结果中(显示在红色矩形中),变量“Karma”具有非常高的 p 值,这意味着它在这个模型中是无关紧要的。这有点令人惊讶,因为 EDA 已经表明因果报应是区分这两个组的相关特征。然而,在这里,我将删除变量“Karma ”,并重新运行模型以查看其响应。
模型,版本 2 (去除预测变量 Karma 后)
具有特征因果报应
没有 Karma(更高的精度水平在下面的结果中突出显示,显示了改进):
没有特征因果报应
精密:
这指的是实际上是正确的肯定识别的比例。
其中 TP =真阳性,FP =假阳性。
在该模型预测的 310 个骗子中,有 253 个是正确的,其准确率为 82%。
回忆:
这是指被正确识别的实际阳性的比例。
其中 TP =真阳性,FN =假阴性。
在测试数据中,有 491 个骗子,253 个被正确识别,这产生了 52%的召回分数。
当涉及到这个项目的实际应用时,在这个过程之前确定一个 Reddit 用户是否是骗子是非常困难的。有可能一个 Redditor 显示了一个骗子的活动,但却有着良好的意图。另一方面,用户可能已经成功进行了 5 次交易,然后决定不继续进行第 6 次交易。
为了全面评估模型的效率,我考察了精确度和召回率。通过给预测的概率增加一个阈值,就给模型增加了很多价值。在下图中,您可以看到该模型根据预测的概率来预测 Reddit 用户是真实用户还是骗子,该模型对两组用户都使用了大于 0.5 的基本阈值。例如,如果用户是骗子的概率是> . 5%,那么模型将为该用户预测骗子。
这是一个示例输出,模型做出了 10 个预测:
模型做出的 10 个预测
在上图中,你可以看到模型做出的 10 个预测。概率是根据电子邮件、mod、gold、评论和年龄计算的。在行 0 中,模型预测用户与骗子具有 0.697%的相似性,这最终是正确的,因为真实结果列显示用户 0 是骗子。
不同概率下检查概率阈值的代码:
在对测试数据应用不同的阈值之后。通过在预测骗子时将阈值提高到 60%,假阳性的数量减少了,从而将精确度提高到 92%。
使用模型—应用程序使用
查找没有确认交易的用户的提交
Reddit.com 的纱帽
典型提交,但用户有 0 笔确认交易
将用户名输入一个函数,该函数从 reddit API 中提取必要的数据。然后将数据输入多元逻辑回归模型,并返回一个评级。为了使应用程序更加用户友好,低于 40 的等级显示为危险,高于 60 的等级显示为安全。
正如你所看到的,这个用户得到了 38.2 的评分,这是相当低的。暗示找别人买可能更好。
使用模型-确认用户
找到已确认交易的用户
Reddit.com 的纱帽
拥有 7 笔已确认交易的用户
因为用户有 7 笔已确认的交易,所以它们很可能是真实的。为了创建一种类型的用户评级,该函数输出以前的交易。
结论
基于这些阈值和结果,可以有把握地说,如果一个 Reddit 用户的预测骗子概率高于 0 . 6 的**,那么最好找其他人与交易。因此,通过寻找 6 个特征/变量年龄、主持人、因果关系、电子邮件、黄金、评论并预测除因果关系之外的所有这些特征/变量的概率,可以预测与 Reddit 用户交易时的风险水平。**
如果你想查看我的**Github库中的所有代码。**
如何在 Julia 中使用模块
朱莉娅综合教程
关于 Julia 语言中模块和导入如何工作的快速课程
(图片由作者提供)
本文视频:
Github:
此时您不能执行该操作。您已使用另一个标签页或窗口登录。您已在另一个选项卡中注销,或者…
github.com](https://github.com/emmettgb/JuliaLessons/tree/master/6)
介绍
而我们在过去的朱莉娅教程中已经讲过的东西;函数、构造函数和类型当然是有价值的,一个程序员不可能从零开始构建一个完整的生态系统。也就是说,程序员经常使用包来执行他们的包不一定针对但需要的算法。包是代码的储存库,可以作为其他包迭代和构建的依赖项重用。
我们已经对 Pkg 以及如何使用它来安装 Julia 编程语言的包进行了概述。今天我们将使用一个名为 Compose.jl 的模块来练习用 Julia 编程。我选择这个库是因为它是一个函数式的声明性库,遵循我们在这些教程中介绍的相同的编程方法和原则。此外,作为一个图形包意味着人们可以在非常直观的输出中看到他们代码的直接结果——这对一个新的程序员来说很方便。如果您想了解更多关于该模块的信息,您可以访问 Juliahub:
[## JuliaHub
编辑描述
juliahub.com](https://juliahub.com/ui/Packages/Compose/sbiEw/0.9.1)
包装——基础
为了在 Julia 中添加一个包,我们将使用 Pkg。您可以通过使用将 Pkg 导入到 Julia 中,或者只使用 Pkg REPL,可以通过在 Julia REPL 中按]来访问它。添加相对简单,可以使用 Pkg.add()方法或 Pkg REPL 中的 add 命令来完成。当然,今天我们将使用 Compose.jl,所以您可能想继续添加它:
julia> ]
pkg> add Compose
这将把 Compose 添加到我们的全局包环境中。一些 Julia 开发者强烈反对这样做,但是我不同意——我认为在你的机器上有依赖是完全没问题的,只要它们是经常使用的依赖。此外,用户总是可以使用 rm 命令删除他们的包。
julia> ]
pkg> rm Compose
如果你想了解更多关于 Pkg 酷的原因,你可以看看我不久前写的一篇文章!:
为什么 Julia 的 Pkg 是我用过的最好的软件包管理器。
towardsdatascience.com](/julias-package-manager-is-awesome-23b9c02e3a0b)
为了让一个模块进入我们的 Julia 运行时环境,我们有一系列不同的选项来导入它。首要的是使用。使用 just 意味着该包将被预编译并从运行时内部调用,并且不会在运行时内部发生变化。我们可以使用 Compose 包
using Compose
在 Julia 语言中,使用导出的函数和结构是很常见的。这意味着这些函数不需要通过它们的父类来调用,而是可以在导入模块时直接调用。我们可以通过直接导入我们想要在 Julia 中使用的类型或函数来避免使用导出:
using Compose: compose
直接导入将加载我们的目标代码,而不包括包内的所有其他成分。直接导入也可以节省编译时间,在注册的软件中,对于只有一两个不同类型或函数要在你的软件中使用的依赖项,这是绝对推荐的。
除了使用之外,在 Julia 语言中,我们还可以访问 import 关键字。导入代码与使用代码正好相反,并且允许扩展包。通常情况下,除非需要扩展,否则不需要显式导入。
import Compose
# Direct explicit import:
import Compose: compose
作曲!
了解了使用 Julia 中模块的基础知识后,我们现在可以看看我们今天要学习的模块:
Compose.jl
Compose 是一个用 pure Julia 编写的声明性矢量图形库,它使得只使用几个参数和节点就可以非常容易地绘制图形。您可以在此处查看 Juliahub 上的撰写文档:
[## Home Compose.jl
Compose 是一个用 Julia 编写的声明性矢量图形系统。它旨在简化复杂的创建…
juliahub.com](https://juliahub.com/docs/Compose/sbiEw/0.9.1/)
说到这里,如果你是 Julia 的新手,并且正在使用 Julia 模块,那么看看 JuliaHub 肯定是值得的。JuliaHub 是 Julia 程序员的一体化软件包目的地,其中的文档很容易包含并自动集成到网站中。如果你想了解更多,我有一整篇关于它有多酷的文章!:
JuliaHub 如何自动化所有程序员讨厌做的事情。
towardsdatascience.com](/juliahub-the-greatest-approach-to-putting-together-packages-and-documentation-707688a472d2)
直接从 Compose 文档中提取,我们的第一个例子很简单,但是可以理解要点:
composition = compose(context(), rectangle(), fill("tomato"))
(图片由作者提供)
更深入地研究这个语句,compose()方法负责返回一个组合并接受参数。这些参数是称为组合表单和节点的类型。在方法调用内部,我们看到的参数是 context()、rectangle()和 fill()。Context 是根节点,所以在这个特定的实例中,它基本上可以被忽略。接下来的参数是矩形。这当然是在渲染图像中显示的类型。最后一个参数是 fill(),它接受一个字符串,表示整个上下文所需颜色的标题()。
幸运的是,我们可以使用?()方法,以了解有关这些参数的更多信息。让我们创建更多的矩形!我们将从查看在创建类型时可以提供什么类型的数据开始:
矩形既可以接受 0 个参数,也可以接受 4 个参数。这方面的四个参数是位置参数,窗体的 x 位置,窗体的 y 位置,然后是宽度和高度。有了这个新发现的信息,让我们修改我们的旧代码来改变矩形的大小:
composition = compose(context(), rectangle(.5, .5, 5px, 5px), fill("tomato"))
(图片由作者提供)
并添加更多的矩形:
composition = compose(context(), rectangle(.5, .5, 20px, 20px),
rectangle(.5, .2, 20px, 20px),
rectangle(.5, .8, 20px, 20px),
fill("tomato")
)
(图片由作者提供)
使用与导入
一个可能令人混淆的概念是使用 import 和使用将模块导入 Julia。这是可以理解的,因为许多语言通常不包含这个特性;并且大多数使用 using 将类和函数从名称空间中取出。也就是说,普通的 Julia 程序员可以感觉到的使用和导入之间最明显的区别是扩展模块的能力。这在本文前面已经提到过,但是用代码详细说明一下,分派一个矩形只接受两个位置参数而不是一个或两个是不可能的,如下所示:
using Compose: rectangle
rectangle(x::Float64, y::Float64) = rectangle(x, y, 30px, 30px)
但是,如果我们使用 import 而不是使用:
import Compose: rectangle
rectangle(x::Float64, y::Float64) = rectangle(x, y, 30px, 30px)
结论
没有一个程序员能够写出整个世界的软件,幸运的是他们不需要这么做。这是因为数以百万计的开源开发者正在开发每个程序员都可以使用的奇妙模块。在 Julia 中,我们可以使用 Pkg 添加一些这样的包。从今天开始,关于模块最重要的事情是:
- 那个?()方法
- JuliaHub 文档
- 添加包
- 导入和使用的区别
掌握这些概念会让你成为一个真正的茱莉亚语言大师,你已经在路上了!
如何在 Pandas 中使用 MultiIndex 来提升您的分析
大蟒
复杂数据分析中数据帧的层次索引介绍
小姐姐创造的形象
如果您的数据框架的索引中有不止一列,会怎么样?
Pandas 中的多级索引功能允许您这样做。一个常规的 Pandas 数据帧有一个单独的列,作为唯一的行标识符,或者换句话说,一个“索引”。这些索引值可以是从 0 到无穷大的数字。它们也可以更详细,比如将“菜名”作为麦当劳特许经营店所有食物的索引值。
但是,如果你拥有两家麦当劳连锁店,并且想比较两家连锁店中一道菜的销售额,该怎么办呢?
虽然 Pandas 中的groupby()
函数可以工作,但这个案例也是一个多索引可以派上用场的例子。
MultiIndex ,也称为多级索引或层次索引,允许您将多个列作为行标识符,同时通过父/子关系将每个索引列与另一个索引列相关联。
在本文结束时,我们将通过创建和选择具有分层索引的数据帧来回答以下问题:
- 《指环王》第一章有哪些人物说话?(用
.loc
回答) - 在《指环王》中最先开口的三个精灵是谁?(用
.loc
回答) - 《双塔奇谋》中甘道夫和萨鲁曼谈了多少?(用
.loc
回答) - 在所有电影中,埃西铎说了多少?(用
.xs
回答) - 在每部电影以及三部电影中,哪些霍比特人说得最多?(用透视表和
.loc
回答)
你可以在这里找到这篇文章中用到的数据。我们将使用“指环王”电影中的数据,特别是数据集中的“WordsByCharacter.csv”文件。这个文件将有每个角色在每部电影的每个场景中所说的话的数量。
和往常一样,在尝试任何代码之前,不要忘记导入熊猫。
import pandas as pd# load data
df = pd.read_csv('WordsByCharacter.csv')
来自 WordsByCharacter.csv 的原始数据帧
让我们深入了解如何使用多级索引进行数据分析。
多索引快速介绍
分层索引意味着您的数据帧将有两个或多个维度,可用于标识每一行。
要获得原始数据帧的索引标签,我们可以使用以下代码:
df.index.names
原始数据帧索引名的冻结列表
这将输出一个“FrozenList”,这只是一个 Pandas 特有的构造,用于显示数据帧的索引标签。这里,我们看到值是“None”,因为这是数据帧索引的默认值。
要用我们的原始数据框架创建一个多索引,我们需要做的就是将一列列表传递到 **.set_index()**
Pandas 函数中,如下所示:
multi = df.set_index(['Film', 'Chapter', 'Race', 'Character'])
一列多索引数据框架(单词)
在这里,我们已经可以看到名为“multi”的新数据帧已经过组织,现在有四列组成索引。我们可以通过再次查看索引名称来检查这一点:
multi.index.names
多级索引数据帧的索引名称的冻结列表
我们现在看到前面的值“None”已经被我们指定为新索引的四个列的名称所取代。
常规的、未改变的数据帧中的每个索引值只是一个从 0 到 730 的数字(因为数据帧有 731 行)。为了向您展示我们新创建的 MultiIndex 中的每个索引值,我们可以使用这行代码:
multi.index.values
多索引数据帧的索引值数组
现在,我们看到“单词”列中的每一行值都可以通过它来自哪部电影、它指的是哪一章、说这个单词的角色是什么种族以及该角色的名字来标识。
在我们深入分析之前,有一点需要注意,那就是.sort_index()
Pandas 函数。创建具有多索引的数据帧时,请确保将其附加到代码行的末尾,如下所示:
multi = df.set_index([‘Film’, ‘Chapter’, ‘Race’, ‘Character’]).sort_index()
熊猫文档上有这样的注释:
即使数据没有排序,索引也可以工作,但是效率会很低(并显示一个性能警告)。它还将返回数据的副本,而不是视图。
同样值得注意的是,你可以简单地通过将.reset_index()
传递给你的数据帧来删除层次索引,就像这样:
multi.reset_index()
这将只返回原始数据帧,而不返回多个索引列上的父/子关系。
现在我们准备执行一些分析!
用熊猫多重索引功能回答指环王的琐事问题
《魔戒相交》第一章有哪些人物说话?
这里,我们将使用可靠的.loc
Pandas 函数。如果你以前没有用过它,请随意查看这个关于矢量化熊猫函数的快速指南。
这里,我们感兴趣的是索引的两个组成部分,即“电影”和“章节”。在我们的.loc
选择器中,我们编写了以下内容:
multi.loc[('The Fellowship Of The Ring', '01: Prologue'), :]
简单的输出。多索引数据帧上的锁定选择器
您可以通过将数据帧的 MultiIndex 的每个部分传递到一个 tuple 中来选择所需的值。在我们刚刚编写的选择器的第一部分中,我们传递了元组(“环的友谊”,“01: Prologue”)。我们不需要传递“种族”或“性格”的值,因为我们还不知道谁在第一章中说话。
请注意,“电影”和“章节”索引列不再出现在视图中。这是因为我们已经为“电影”和“01: Prologue”输入了“The Fellowship Of The Ring”作为元组中的值,所以输出不需要在视图中重复这些值。
另外,:
作为最后一个参数被插入到.loc
选择器中,表示我们希望显示所有的列。在我们的例子中,DataFrame 只有一个名为“Words”的列,因为 DataFrame 中的每隔一列都被转换为索引列。但是,如果您的数据框架中有多个列,并且只想查看一个子集,那么您应该使用列名而不是:
。
现在,我们知道埃尔隆德、凯兰崔尔、咕鲁和比尔博在第一部电影的第一个场景中说话了。让我们来看一个稍微复杂一点的例子。
《指环王》中最先开口的三个精灵是谁?
这里,我们仍将使用.loc
,但是现在我们将使用一些语法,在从多索引值中进行选择时,这些语法将为我们提供一些灵活性。
为了回答这个问题,我们对“电影”和“种族”索引列感兴趣。这一次,我们“跳过”一个索引栏,因为“章节”位于“电影”和“种族”之间。我们还不知道精灵们首先在哪个“章节”说话,所以我们需要把那个留白。
为此,我们将使用这行代码:
multi.loc[(‘The Fellowship Of The Ring’,slice(None),’Elf’), :].head(3)
的输出。在多索引数据帧上使用切片(无)锁定选择器
同样,我们传递一个带有我们想要的索引值的元组,但是我们传递的不是“Chapter”的值,而是slice(None)
。这是 Pandas 中默认的 slice 命令,用于选择多索引级别的所有内容。所以在这里,我们选择所有可能的“章节”值。
现在,我们知道埃尔隆德、凯兰崔尔和阿尔温是第一部书中最先说话的三个精灵。但到目前为止,我们所做的只是将每个索引列的一个值传递给.loc
选择器。如果我们想获得多个值呢?
在《双塔奇谋》的每一章中,甘道夫和萨鲁曼谈了多少?
在这个问题中,我们对第二部“电影”的所有“章节”都感兴趣,这两部电影我们都已经知道如何选择。但是这一次,我们感兴趣的是“字符”索引的两个值。
为了得到答案,我们写下这行代码:
multi.loc[('The Two Towers',slice(None),slice(None),['Gandalf','Saruman']), :]
多个条件的输出。多索引数据帧上的锁定选择器
我们在这里需要做的就是将我们想要的索引值列表传递给我们插入到.loc
中的元组。由于我们不知道要获得哪个“章节”或“比赛”,所以在获得“字符”之前,我们为这两个索引值传递slice(None)
。
到目前为止,我们在选择中已经有了多个条件,这就是为什么使用.loc
很方便。但是如果我们只想指定一个级别的索引呢?写三遍slice(None)
会很累,所以我们会转向另一种方法。
在所有电影中,埃西铎说了多少话?
要回答这个问题,我们只需要为“字符”指定一个索引级别值。我们将在 Pandas 中使用xs()
(横截面)方法,它允许您指定想要搜索多索引的哪个部分。
我们使用以下代码:
multi.xs('Isildur', level='Character').sum()
basic 的输出。多索引数据框架上的 xs 选择器
最基本的是,xs()
需要输入您想要查找的索引值和您想要搜索的级别。在这种情况下,我们需要“字符”级别,所以我们将它传递到level=
,我们希望“字符”的值是“埃西铎”。然后,为了聚合所有的值,我们将.sum()
添加到行尾。
我做了一点小手脚,以便验证数据的准确性,因为我知道这个问题的答案(埃西铎在整个三部曲中说的一个词是“不”)。但是您也可以使用这一行代码来查找任何角色说了多少话,只需将他们的名字作为参数代入xs()
中。
哪几个霍比特人在每部电影和三部电影中都说得最多?
要回答这个问题,如果我们有一个表,其中汇总了每部电影中每个角色的“单词”值,那就太好了。这是创建数据透视表的好地方!
我们将使用 Pandas 的.pivot_table()
函数,但是您将看到我们将一个列表传递到index=
参数设置中,以再次创建一个 MultiIndex。我们创建数据透视表的代码如下所示:
pivoted = df.pivot_table(index = ['Race','Character'],
columns = 'Film',
aggfunc = 'sum',
margins = True, # total column
margins_name = 'All Films',
fill_value = 0).sort_index()order = [('Words', 'The Fellowship Of The Ring'),
('Words', 'The Two Towers'),
('Words', 'The Return Of The King'),
('Words', 'All Films')]pivoted = pivoted.sort_values(by=('Words', 'All Films'), ascending=False)
pivoted = pivoted.reindex(order, axis=1)
具有多索引的基本数据透视表
这里,我们的多级索引有两个组件,而不是上一个示例中的四个组件。这是因为我们希望“Film”值也是一个列,而不是一个索引。我们也不需要查看“章节”值,因此将其排除在外。因为我们对单词总数感兴趣,所以我们希望我们的aggfunc
(聚合函数)参数是“sum”。
Pandas 还有一个内置的用于.pivot_table()
函数的 total 列。您所需要做的就是通过margins=True
来启用它,并可选地在margins_name
参数中设置总计列的名称。
因为我们希望看到中每个“角色”的总字数,这个“角色”的“种族”值为“霍比特人”,所以我们可以通过一个非常简单的应用.loc
来选择这个条件。
pivoted.loc['Hobbit']
的输出。锁定多索引数据透视表
嘣!
现在我们有了一个表格,根据这个表格,霍比特人在所有电影中说得最多。我们还可以看到每部电影中每个角色说了多少话。一些有用的见解包括比尔博在《双塔奇谋》中根本没有说话,但仍然比皮聘和梅里有更多的总对话,他们在所有三部电影中都说话。
拥有这个表的好处在于,我们可以对" Elf “、” Men “、” Ainur "以及《指环王》中的其他种族进行同样的分析,只需在上面的.loc
函数中代入一个参数。
我希望这篇关于 Pandas 中层次索引的介绍对您有用!我发现在 DataFrame 索引中有多个级别意味着我可以快速地将我的数据分组到特定的级别,而不必编写多个groupby()
函数。
和往常一样,查看官方文档,更深入地了解如何在分析中使用多指数特性。
我喜欢参与数据收集和分析,这就是为什么我使用那篇文章中讨论的一种快速简单的方法来收集样本数据。如果你想在网上获取一些你自己的测试数据来测试这段代码,你可以在上查看这篇文章,从一个有熊猫的网站获取表格。
祝你的多级索引冒险好运!
如何在你的算法交易策略中使用多个时间框架
你把钱放在桌子上而不使用它们
照片由 Katerina Limpitsouni 拍摄
在本教程中,我将看一个例子,说明如何在你的策略中使用多个时间框架。在之前的文章中,我们学习了如何进口蜡烛,写一个简单的盈利策略,定义路线,以及执行回溯测试。如果您还没有阅读我之前的文章,请在继续之前阅读。
我将从上一篇文章停止的地方继续。这是我最后得出的完整策略:
这是从2019-01-01
到2020-05-01
用4h
时间框架回溯测试的结果:
从 2019 年 1 月 1 日到 2020 年 5 月 1 日的回溯测试结果,没有锚定时间框架
在您的策略中定义多个时间框架
这一次,我将使用多个时间框架,看看我是否能改善结果。有经验的交易者在手动交易中使用的一个技巧是观察更大时间框架的趋势(或者他们称之为锚时间框架)。这个简单的技巧经常会以减少进场信号的数量为代价来增加你的胜率。
你可能会问,我怎么知道哪个时间框架是锚定时间框架?通常的公式是你交易时间的 4 到 6 倍。例如,在我的例子中,4h
的锚定时间范围是:
6 * 4h = 24h ("1D" in jesse's terms)
Jesse 提供了一个实用助手来帮你计算,这就是我要用的。
让我们添加一个新的返回大趋势的属性方法。我会返回1
表示上升趋势,返回-1
表示下降趋势:
如你所见,这次我用了 self.get_candles 而不是 self.candles 。我还使用了一些其他内置属性,而不是使用硬编码的字符串:
这样,当我改变我的路线去尝试其他的交换、符号和时间框架时,我不必改变我的策略代码。
现在我更新了我的参赛规则,加入了anchor_trend
:
修改您的路线
现在,我再次执行回溯测试,看看这一更改会如何影响回溯测试结果,但我得到了以下错误:
Uncaught Exception: RouteNotFound: Bellow route is required but missing in your routes: ('Bitfinex', 'BTCUSD', '1D')
错误是明显的。如果我在另一个时间段使用蜡烛,我也应该把它添加到我的routes.py
文件中。我的交易路线必须保持不变,因为我交易的是单一头寸,所以我使用的任何其他时间框架都被视为额外的蜡烛线。
这是我的routes.py
现在的样子:
这个错误告诉我,在我的路线中我遗漏了('Bitfinex', 'BTCUSD', '1D')
;所以我们把它加到extra_candles
列表里吧。这就是我的routes.py
应该变成的样子:
这一次回溯测试进展顺利。结果如下:
从 2019 年 1 月 1 日到 2020 年 5 月 1 日的回溯测试结果,具有锚定时间框架
在我使用锚定时间框架来检测市场的更大趋势后,回溯测试结果中有一些值得注意的变化:
- 总净利润从 31.44%增加到 48.42%,这意味着更多的钱!
- 总平仓交易减少了,这意味着我得到的进场信号减少了,这是意料之中的,因为我在进场规则中增加了另一个进场条件。
- 夏普比率从 0.62 增加到 0.86。
- 胜率从 47%提高到 50%。
前瞻偏见
在 algo 策略中使用多个时间框架时,前瞻偏差是一个严重的问题。简而言之,这意味着使用未来的数据。
你们中的一些人可能对此很熟悉,并想知道前瞻偏差是否在我们刚刚观察到的结果提升中起了作用。放心,不会的。Jesse 框架在幕后处理前瞻性偏见。
结论
我们刚刚看到了我的策略指标的显著提升,这是使用锚定时间框架来确定市场更大趋势的结果。
当然,你不会每次在策略中使用多个时间框架时都得到同样的提升。但在我看来,至少尝试一下是有意义的。
这个想法可以延伸。例如,如果你在交易以太网,你可能想利用比特币的锚趋势,因为很明显比特币是加密货币市场的国王,对其他硬币的价格有着巨大的影响。
为了获得我未来的作品和产品,请务必订阅杰西的时事通讯,并查看论坛与像你我这样的量化分析师讨论算法交易
最初发表于【https://jesse-ai.com】。
来自《走向数据科学》编辑的注释: 虽然我们允许独立作者根据我们的 规则和指南 发表文章,但我们并不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语 。
如何使用 n 元模型检测数据集中的格式错误
关于语言模型如何扩展和用于不同目的的代码优先方法。
格式错误,在最好的情况下,会破坏自动数据处理管道。在最坏的情况下,它们会在难以调试的下游分析任务中引入逻辑错误。发现这样的错误是一项单调而低效的工作,会降低工作效率。此外,这种手动过程可能引入不同类型的错误。那么,我们能自动检测损坏的值吗?
例如,考虑一个数据集D
,它有数百万行,包含一个Date
列。让我们假设这个列中的值符合一个特定的模式:mm.dd.yyyy
。假设某处存在一个无效的单元格,由于输入错误,日期遵循不同的格式:01.15–2019
。在自动化管道中,解析器将尝试读取该特性,并可能抛出异常。试图在管道执行之前找到错误几乎是不可能的。但是如果我们能让计算机检测到它呢?
**在这个故事中,我们使用 n-grams,一种语言模型,来自动化错误检测。**我们简要讨论 n 元语法以及 NLP 工程师如何使用它们来生成语言,并研究我们如何利用它们的属性来识别数据集中可能损坏的值。
学习率是为那些对 AI 和 MLOps 的世界感到好奇的人准备的时事通讯。你会在每周五收到我关于最新人工智能新闻和文章的更新和想法。在这里订阅!
关于 n-grams
n-gram 是一个概率模型,简单来说,它试图预测序列中的下一个单词。像 n-grams 这样的概率模型总是通过例子来更好地理解。因此,请考虑下面这段摘自艾米莉·狄金森的诗:
在巨大的痛苦之后,一种正式的感觉来了——
神经像坟墓一样隆重地坐着——
僵硬的心会问‘是他吗,令人厌烦的’,
和‘昨天,还是几个世纪以前’?
首先,我们想知道每个句子从哪里开始,什么时候结束。为此,让我们用特殊字符<s>
表示起点,用</s>
指出终点位置。
巨大的痛苦之后,一种正式的感觉来了——
神经顿然,如同坟墓——
s那颗僵硬的心质问‘是他,那个生了,< /s >
< s >和‘昨天,还是几个世纪以前’?< /s >
要创建一个 n 元模型,首先我们必须为n
超参数设置一个特定的数字。因此,让n = 2
,在这种情况下,n-gram 模型转换为双-gram 模型。现在,我们可以计算两个连续单词的概率。例如,这段摘录中的句子通常以the
一词开头。
使用这些概率,并给定一个新单词作为种子,我们可以预测序列中的下一个单词。显然,数据集越大,结果越好。同样,根据问题的不同,3-grams 可能更好,但是 **n**
的值越大,引入的稀疏性就越多。
泛化树和泛化语言
为了使用 n-grams 来检测表中的格式错误,我们需要一种方法来将原始值归纳为模式。我们也可以用原始值训练一个 n 元模型,但是这种方法的复杂性引入了太多的自由度,导致高度稀疏。
例如,假设v₁
是一个表示邮政编码的原始数字序列:15122
。然后,让v₂,v₃
表示两种不同的代码:345a7
、47592
。显然,v₂
是错误的,但是如果我们在 n 元模型中传递原始值,我们将不会得到有价值的信息;看那个p(a|5) = p(1|5)
,这样我们要么漏掉错误,要么产生假阳性。但是如果我们能把一个原始值归纳成一个模式,我们就能得到更有意义的表示。
为此,我们使用了泛化树和泛化语言的概念。泛化树是一个类似下图的层次结构,将原始值映射到不同的表示形式。
从那棵树上,我们可以派生出许多语言。下面给出一个例子。
使用L₁
,我们可以将v₁,v₂,v₃
转换成DDDDD,DDDLD,DDDDD
。我们也可以将模式压缩为v₁ = D(5), v₂ = D(3)L(1),D(1), v₃ = D(5)
。有了这个表示和足够大的数据集来训练一个 n 元模型,我们可以得到邮政编码格式的字母L
出现的概率非常低。简而言之,这就是泛化树和语言的思想。如果需要更详细的介绍,请看下面的故事。
引入泛化树和泛化语言来自动检测结构化数据集中的损坏值。
towardsdatascience.com](/how-to-auto-detect-format-errors-in-a-dataset-6609a9e9aacc)
实施和评估
现在是我们动手的时候了。对于这个例子,我们使用一个包含 100 行三个特征的合成数据集:电子邮件、日期、邮政编码。因此,让我们使用pandas
加载数据,看看是什么样的。
这一次,我们使用了zip_code
列,其中我们引入了一些错误。因此,我们指定我们将使用的泛化语言。它严格遵循L₁
中定义的规则。
例如,2899.8
的图案是d(4)s(1)d(1)
,而03754
的图案是d(5)
。现在,让我们将每个邮政编码转换成它的模式。
我们使用流行的 python 库nltk
,创建 3-grams 并构建最大似然估计模型(MLE)。
首先,我们填充序列,正如我们在这个故事的第一部分看到的。接下来,我们为每个填充序列(即,每个填充的邮政编码模式)构建一组 3-gram。最后,我们使用 3-grams 来拟合 MLE 模型。
为了评估一个邮政编码并检测任何错误,我们需要一个 score 函数。因此,下面我们定义这样一个函数。
这个函数获取一个原始值,相应地将其归纳为一个模式,填充它并计算每个 3-gram 的分数。最后,它返回最不可能的计算值。这是因为我们只需要一个 3-gram 就可以确信我们有错误。这是对这个玩具例子的一个简单的解释,但是如果你想了解如何聚合许多泛化语言的结果,请阅读下面的故事。
使用远程监督和汇总预测结果生成验证数据,就像大海捞针一样。
towardsdatascience.com](/how-to-auto-detect-errors-in-a-dataset-part-ii-683b114865be)
现在,如果我们将一个有效的邮政编码值传递给score
方法,得到的概率很高:score('15378') = 0.951
。另一方面,如果有任何包含字母、符号或五个以上数字的值,概率就会下降。例如,第一个邮政编码243x2
的得分为0.0098
。
结论
在这个故事中,我们使用一个玩具示例来展示语言模型(n-grams)如何用于表格数据集中的格式错误检测。我们简要解释了什么是 n 元语法,以及如何使用泛化树和语言来解决稀疏性问题。最后,我们实现了一个简单的解决方案,利用 n-grams 的能力结合泛化语言来检测合成数据集中的错误。
我叫 Dimitris Poulopoulos,是希腊比雷埃夫斯大学*BigDataStack的机器学习研究员和博士©。我曾为欧洲委员会、欧盟统计局、国际货币基金组织、欧洲中央银行、经合组织和宜家等主要客户设计和实施人工智能和软件解决方案。如果你有兴趣阅读更多关于机器学习、深度学习和数据科学的帖子,请在 twitter 上关注我的*****LinkedIn或@ james2pl。******
如何在 Python 中使用 NLP:一个实用的分步示例
找出 NLTK 数据科学家需要的技能
在这篇文章中,我们展示了一个关于招聘信息的分步 NLP 应用。
这是对上一篇文章的技术解释,在这篇文章中,我们总结了数据科学家的热门技能。我们提供雇主最常要求的顶级工具、技能和最低限度的教育。
如果你想看一个用 Python 代码使用自然语言工具包 (NLTK)包的实际例子,这篇文章就是为你准备的。
让我们开始吧。
来源:突发
准备:收集数据
我们搜集了 8 个不同城市的“数据科学家”的招聘信息。抓取后,我们将数据下载到每个城市的单独文件中。
该分析中包含的 8 个城市是波士顿、芝加哥、洛杉矶、蒙特利尔、纽约、旧金山、多伦多和温哥华。变量是职位、公司、地点和职位描述。
在本文中,我们不会详细讨论这个过程。
我们准备好进行真正的分析了!我们将从这些数据中总结出雇主要求的流行工具、技能和最低学历。
步骤#1:加载和清理数据
首先,我们将 8 个城市的数据文件加载并组合到 Python 中。
我们删除具有相同职位名称、职位描述、、和城市特征的重复行/职位发布。
现在我们有一个包含 5 个要素和 2,681 行的数据集。
步骤 2:形成关键词列表
在搜索职位描述之前,我们需要代表工具/技能/学位的关键词列表。
对于这个分析,我们使用一个简单的方法来形成列表。这些名单是基于我们的判断和招聘信息的内容。如果任务比这更复杂,你可以使用更高级的方法。
对于工具的关键词列表,我们最初是根据我们的数据科学知识得出一个列表。我们知道数据科学家常用的工具包括 Python、R、Hadoop、Spark 等等。我们对这个领域有相当的了解。因此,这份初步清单很好地涵盖了招聘启事中提到的许多工具。
然后我们查看随机的招聘信息,并添加列表中没有的工具。通常这些新的关键词会提醒我们添加其他相关的工具。
在这个过程之后,我们有了一个关键词列表,它涵盖了招聘信息中提到的大多数工具。
接下来,我们将关键字分为单单词列表和多单词列表。我们需要以不同的方式将这两个关键字列表与职位描述相匹配。
通过简单的字符串匹配,多词关键字通常是唯一的,很容易在工作描述中识别。
单个单词的关键字,比如“C ”,在我们的文章中是指 C 编程语言。但“c”也是一个常见的字母,用在许多单词中,包括“can”、“clustering”。我们需要进一步处理它们(通过标记化),以便仅在职位描述中有单个字母“c”时进行匹配。
以下是我们用 Python 编写的工具的关键词列表。
通过遵循与工具相似的过程,我们得到了技能的关键词列表。
对于的教育水平,我们使用不同的程序。
因为我们正在寻找最低要求的教育水平,我们需要一个数值来排列教育程度。比如我们用 1 代表“学士”或“本科生”,用 2 代表“硕士”或“研究生”,等等。
这样,我们就有了从 1 到 4 的学位排名。数字越高,受教育程度越高。
步骤 3:使用 NLP 技术简化工作描述
在这一步中,我们简化了工作描述文本。我们通过计算机程序使课文更容易理解;从而更有效地将文本与关键词列表进行匹配。
我们数据集中的 job_description 要素如下所示。
标记工作描述
记号化是将文本字符串解析成不同部分(记号)的过程。这是必要的,因为计算机程序能更好地理解标记化的文本。
我们必须用空格(" ")等分隔符将工作描述文本字符串显式地分割成不同的标记(单词)。我们使用 word_tokenize 函数来处理这个任务。
在这个过程之后,工作描述文本串被分割成如下的标记(单词)。计算机可以更容易地读取和处理这些令牌。
例如,单个单词的关键字“c”只能与标记(单词)“c”匹配,而不能与其他单词“can”或“clustering”匹配。
请继续阅读 Python 代码。我们将标记化与接下来的几个过程结合在一起。
词性标注职位描述
工作描述通常很长。我们希望保留对我们的分析有用的单词,同时过滤掉其他单词。我们使用词性标注来实现这一点。
词性标注是一种标注单词是名词、形容词还是动词等的自然语言处理方法。维基百科解释得很好:
词性标注 是将文本(语料库)中的单词标记为对应于特定词性的过程,基于其定义和上下文,即其与短语、句子或段落中相邻和相关单词的关系。这种方法的一种简化形式通常是教学龄儿童识别名词、动词、形容词、副词等。
多亏了 NLTK,我们可以在 Python 中使用这个标记器。
将这种技术应用于关键字列表,我们可以找到与我们的分析相关的标签。
下面,我们用 POS 标签工具的关键字列表作为演示。
字母的不同组合代表标签。例如,NN 代表名词和单数词,如“python”,JJ 代表形容词,如“big”。完整的陈述列表在这里。
正如我们所见,标签并不完美。例如,“sql”被标记为“JJ”——形容词。但它仍然足以帮助我们筛选有用的单词。
我们使用所有关键字的标签列表作为工作描述的过滤器。我们只保留工作描述中具有相同关键字标签的单词。例如,我们将保留工作描述中带有标签“NN”和“JJ”的单词。通过这样做,我们可以从工作描述中过滤掉那些对我们的分析没有帮助的词,比如“the”、“then”。
在这个阶段,我们已经精简了工作描述,这些描述被符号化和缩短了。
保持耐心!我们只需要稍微多处理一下。
第四步:关键词和工作描述的最终处理
在这一步,我们进一步处理关键字列表和工作描述。
词干分析
词干化 是将屈折(或有时派生)的单词简化为其词干、词根或词根形式(通常是书面单词形式)的过程。
词干处理允许计算机程序识别同一个词干的单词,尽管它们看起来不同。这样,我们就可以匹配单词,只要它们有相同的词干。例如,单词“模型”、“建模”都有相同的词干“模型”。
我们列出了关键字和精简的工作描述。
小写单词
最后,我们通过小写来规范所有的单词。我们只将工作描述小写,因为关键字列表是小写的。
如前几节所述,前面过程中使用的 Python 代码如下。
现在,只有与我们的分析相关的工作描述中的单词(记号)保留了下来。下面是最终工作描述的一个例子。
终于了,我们准备好关键词匹配了!
第五步:匹配关键词和工作描述
为了查看职位描述是否提到了特定的关键字,我们将关键字列表与最终精简的职位描述进行匹配。
工具/技能
您可能还记得,我们构建了两种类型的关键词列表——单词列表和多词列表。对于单字关键词,我们通过集合交集函数将每个关键词与职位描述进行匹配。对于多词关键字,我们检查它们是否是工作描述的子字符串。
教育
对于教育程度,我们使用与工具/技能相同的方法来匹配关键词。然而,我们只记录最低水平。
例如,当“学士”和“硕士”这两个关键词同时出现在一份工作描述中时,学士学位就是这份工作所需的最低学历。
更详细的 Python 代码如下。
步骤 6:可视化结果
我们用柱状图总结结果。
对于工具/技能/教育水平的每个特定关键词,我们会计算与之匹配的职位描述的数量。我们也计算他们在所有工作描述中的百分比。
对于工具和技能列表,我们只列出了最受欢迎的前 50 个。对于学历层次,我们按照最低要求的层次来总结。
详细的 Python 代码如下。
最受欢迎的工具
数据科学家的 50 大工具
热门技能需求
数据科学家的 50 大技能
最低教育要求
数据科学家的最低教育水平
我们做到了了!
我们希望这篇文章对您有所帮助。留下评论让我们知道你的想法。
同样,如果你想看到详细的结果,请阅读2020 年数据科学家需要哪些技能。
如果你有兴趣阅读更多这样的文章,请在 中 或 推特 上关注我们。
更多来自 Lianne & Justin 的数据科学文章:
清洁什么和如何清洁的技巧。
towardsdatascience.com](/data-cleaning-in-python-the-ultimate-guide-2020-c63b88bf0a0d) [## 如何提高体育博彩赔率 Python 中的分步指南
我用数据科学策略在体育上赌了 20,000 美元。
towardsdatascience.com](/how-to-improve-sports-betting-odds-step-by-step-guide-in-python-94626b852f45) [## 如何像老板一样在 Python 中操纵日期和时间
常用的日期时间函数及示例
towardsdatascience.com](/how-to-manipulate-date-and-time-in-python-like-a-boss-ddea677c6a4d)
如何使用 NLP 找到技术工作并赢得黑客马拉松
使用网络抓取、NLP 和 Flask 创建一个技术工作搜索网络应用程序
我和我的前端 web 开发人员 Brandon Franks 最近在一次 30 人团队、30 小时的黑客马拉松中赢得了“解决的最有趣的数据科学问题”奖。我们的获奖作品是一款 Web 应用程序,它从 Indeed.com 收集职位列表,使用自然语言处理(NLP)进行处理,并提供美国前 20 大科技城市的四大科技职位的职位总数、平均工资范围和前 10 大技术技能的汇总
这四个宽泛的技术职位——数据科学家、网络开发人员、UX 设计人员和 iOS 开发人员——包括了与该职位相关的所有职位。因此,网页开发人员包括网页开发人员、前端工程师、PHP 开发人员和许多其他被 Indeed.com 认为是网页开发人员相关的职位。
前 20 大科技城市是根据计算机和数学职业的最高平均工资计算美国前 20 大都会区(MSA)而确定的。Indeed.com 搜索以城市为半径 25 英里,因此搜索结果包括城市的周边地区。
首先,让我们看看成品:
虽然 Web 应用程序使用起来非常简单,但它需要大量的幕后数据科学来构建汇总结果。让我们一步一步地完成网页抓取、NLP 和应用程序构建的过程,以便在黑客马拉松 30 小时的时限内将网站变得生动起来。
关于代码的一句话
该项目的所有代码、数据和相关文件都可以在 my GitHub 访问。自述文件提供了 repo 目录和文件的详细信息。网页抓取和自然语言处理使用 Jupyter 笔记本。
网页抓取
Web 抓取代码使用 BeautifulSoup 从 Indeed.com 站点定位并抓取数据。在抓取之前,请务必检查 robots.txt 文件,以确保所抓取的数据是允许的。我们收集的初始数据:
1.职位名称
2。公司
3。位置
4。工资
5。职位描述
6。作业计数
让我们用一段代码来演示这个基本过程。
def extract_job_title(soup):
jobs = []
for div in soup.find_all(name="div", attrs={"class":"row"}):
for a in div.find_all(name="a", attrs={"data-tn-element":"jobTitle"}):
jobs.append(a["title"])
return(jobs)city_url = "[https://www.indeed.com/jobs?q=](https://www.indeed.com/jobs?q=)" + title_name + \
"&l=" + city_name + "%2C+" + st_name + \
"&start=" + str(start)
page = requests.get(city_url)
soup = BeautifulSoup(page.text, "html.parser")job_title_list.extend(extract_job_title(soup))
在上面的代码中, city_url 是使用职位、城市和州构建的。然后 html 页面被检索并存储在页面变量中。然后,BeautifulSoup 将页面解析成 html 组件,并将它们存储在 Beautiful soup 对象 soup (一个嵌套的数据结构)中。
然后调用 extract_job_title 函数,并将其传递给 soup 对象。 soup.find_all 方法定位适当的 html 并导航到与该值相关联的唯一 html 组件。在这种情况下,职位被发现为子组件**in
刮擦是费时的。在 4 个职位和 20 个城市的 80 种排列中,每种排列大约需要 3 个小时才能获得 100 个职位。因此,Web 应用程序不是实时的,需要对数据进行预处理并以某种形式存储。因此,从抓取创建的结果数据帧被下载到一个. csv 文件和一个 sqlite DB 表中。的。csv 文件因其易用性和速度最终被应用程序使用。
为每个数据元素创建了类似的函数,并保存到下面的原始数据数据框中:
事实上 _df 数据帧—原始刮擦数据
刮刀的完整代码 scraper.ipynb 可以在这里找到。
自然语言处理
我们现在有了来自网络搜集的原始数据,但我们仍然需要为每个宽泛的职位确定顶级技术术语。职位描述是一大块文本,因此自然语言处理是从每个职位描述中提取关键技术术语的理想方法。一般步骤如下:
- 标记化 —获取原始文本,并将其简化为不含非字母数字字符(标记)的小写单词列表。
- 去掉停用词——去掉我们可以忽略的常用词(如“我”、“和”、“the”等)。).
- 引理化 —将记号转换成它们的基本形式,称为引理(例如,游程、running 和 ran 都是引理游程的形式)。
- 减少 —通过大约 100 个技术术语的技术术语字典运行基本令牌,以减少基本令牌的数量。
- 计数和排名 —计数基本科技令牌,对其进行排名,并将其作为列表存储在数据帧中。
标记化、删除停用词并词条化
令牌化过程需要两个步骤。清理文本的预处理步骤和实际的标记化步骤。
以下代码片段中的文本清理使用了 BeautifulSoup、replace、regex、sub 和 lower 等方法的组合,将文本转换为小写字母数字单词。
# Clean the text
def clean_text(text):
text = text.replace('\n', ' ') # remove newline
text = BeautifulSoup(text, "lxml").get_text() # remove html
text = text.replace('/', ' ') # remove forward slashes
text = re.sub(r'[^a-zA-Z ^0-9]', '', text) # letters and numbers only
text = text.lower() # lower case
text = re.sub(r'(x.[0-9])', '', text) # remove special characters
return textdf['description'] = df.apply(lambda x: clean_text(x['description']), axis=1)
然后使用 spacy 分词器对文本进行分词。Spacy 是用于高级 NLP 的免费开源库。在下面的代码片段中,spacy 记号赋予器用英语语言模型(大号)初始化,并添加任何额外的停用词。在这种情况下,只有“year”被添加到停用字词中,因为我们将在代码的后面删除许多其他字词。
初始化后,使用 tokenizer.pipe 将文本从描述列读入文档。对于每个文档, token.lemma_ 被附加到一个列表中。这为数据帧的每一行产生了一个词条列表。最终的列表随后被添加为名为令牌的列。
# Initialize the tokenizer
nlp = spacy.load("en_core_web_lg")
tokenizer = Tokenizer(nlp.vocab)
STOP_WORDS = nlp.Defaults.stop_words.union(['year'])# Tokenizer pipe removing stop words and blank words and lemmatizing
tokens = []for doc in tokenizer.pipe(df['description'], batch_size=500):
doc_tokens = []
for token in doc:
if (token.lemma_ not in STOP_WORDS) & (token.text != ' '):
doc_tokens.append(token.lemma_)tokens.append(doc_tokens)df['tokens'] = tokens
将令牌简化为关键技术术语
为了过滤掉尽可能多的“噪音”,创建了一个大约 100 个技术术语的列表,并通过该列表过滤令牌。这将为每个工作列表生成一个技术术语标记列表。
# Tech terms list
tech_terms = ['python', 'r', 'sql', 'hadoop', 'spark', 'java', 'sas', 'tableau',
'hive', 'scala', 'aws', 'c', 'c++', 'matlab', 'tensorflow', 'excel',
'nosql', 'linux', 'azure', 'scikit', 'machine learning', 'statistic',
'analysis', 'computer science', 'visual', 'ai', 'deep learning',
'nlp', 'natural language processing', 'neural network', 'mathematic',
'database', 'oop', 'blockchain',
'html', 'css', 'javascript', 'jquery', 'git', 'photoshop', 'illustrator',
'word press', 'seo', 'responsive design', 'php', 'mobile', 'design', 'react',
'security', 'ruby', 'fireworks', 'json', 'node', 'express', 'redux', 'ajax',
'java', 'api', 'state management',
'wireframe', 'ui prototype', 'ux writing', 'interactive design',
'metric', 'analytic', 'ux research', 'empathy', 'collaborate', 'mockup',
'prototype', 'test', 'ideate', 'usability', 'high-fidelity design',
'framework',
'swift', 'xcode', 'spatial reasoning', 'human interface', 'core data',
'grand central', 'network', 'objective-c', 'foundation', 'uikit',
'cocoatouch', 'spritekit', 'scenekit', 'opengl', 'metal', 'api', 'iot',
'karma']
df['tokens_filtered'] = df.apply(lambda x: list(set(x['tokens']) & set(tech_terms)), axis=1)
计数和排名
对于每一个职位和城市,科技词汇都会被计算和排名。然后,在数据帧的列表中按排名顺序放置前十个术语。按职位和城市 final_df 汇总的最终数据框架如下:
final_df 数据帧 Web 应用程序中使用的数据
该数据帧被下载到一个. csv 文件中,并提供我们将在 Web 应用程序中使用的数据。
NLP 的完整代码,nlp.ipynb,可以在找到。
烧瓶 App
Flask 是一个简单的 Python Web 开发框架,非常适合像这样的小型项目。本文将不讨论使用 Flask 的细节,但是将提供代码的概述。
代码的基本布局如下:
烧瓶布局
pip 文件为应用程序提供环境和依赖关系。 init。py 文件保存初始化代码,静态目录包含图像、css、javascript 等静态内容,模板目录包含 html 文件。烧瓶应用程序的主要代码包含在 app.py 中,如下所示:
# Import Flask packagefrom flask import Flask, request, render_template
import pandas as pd
import re
import stringdef create_app():
# Create Flask web server, makes the application
app = Flask(__name__)# Routes determine location
[@app](http://twitter.com/app).route("/")
def home():
return render_template('index.html')[@app](http://twitter.com/app).route("/search", methods=['GET'])
def input():
return render_template('search.html')[@app](http://twitter.com/app).route("/output", methods=['POST'])
def output():
df = pd.read_csv('[https://raw.githubusercontent.com/JimKing100/techsearch/master/data/scrape_results1.csv'](https://raw.githubusercontent.com/JimKing100/techsearch/master/data/scrape_results1.csv'))
df = df.drop(df.columns[0], axis=1)title = request.values['title']
city = request.values['city']
result_df = df.loc[(df['job'] == title) & (df['city'] == city)]
r_title = result_df['job'].iloc[0]
r_city = result_df['city'].iloc[0]
r_count = result_df['counts'].iloc[0]
r_lsalary = result_df['low_salary'].iloc[0]
r_hsalary = result_df['high_salary'].iloc[0]r_skills = re.sub('['+string.punctuation+']', '', result_df['skills'].iloc[0]).split()return render_template('response.html',
title='Search Results',
r_title=r_title,
r_city=r_city,
r_count=r_count,
r_lsalary=r_lsalary,
r_hsalary=r_hsalary,
r_skills=r_skills
)[@app](http://twitter.com/app).route("/about")
def about():
return render_template('about.html')return app
Flask 使用 routes 为函数分配 URL。因此“/”路由呈现索引或主页,“/about”路由呈现 about 页面,依此类推。当用户从搜索页面的下拉列表中选择一个职位和城市并点击搜索按钮时,POST 方法调用“/output”路径,执行实际的搜索并呈现结果页面。
Python 代码相当简单。加载包含抓取和 NLP 的最终结果的数据帧,请求职务和城市的值,提取基于职务和城市的数据子集,并将结果传递给页面呈现器。
这总结了创建一个获胜的黑客马拉松项目的整个过程!
我欢迎建设性的批评和反馈,请随时给我发私信。
在推特上关注我
这篇文章最初出现在我的 GitHub 页面网站上
【Indeed.com】科技工作数据来源
如何在 Colab 上配合 GPU 使用 OpenCV?
使用其 NVIDIA GPU 在 Google Colab 上运行 OpenCV 的“dnn”
**OpenCV 的‘深度神经网络’(dnn)**模块是一个方便的计算机视觉工具,它非常容易应用一些技术,如 Yolo 和 OpenPose。然而,OpenCV 的主要缺点是缺乏 GPU 支持,导致推理速度缓慢。幸好从 OpenCV 4.2 开始,支持 NVIDIA GPU/CUDA。
它仍然需要一些作品使用 GPU,你可以查看 Pyimagesearch 的文章这里,他们演示了如何建立一个 Ubuntu 机器。
如果你和我一样没有带 GPU 的机器,可以考虑用 Google Colab ,这是一个免费的服务,有强大的 NVIDIA GPU。它也更容易设置,大部分的要求已经得到满足。在这篇文章中,我将分享我如何用几行代码为 OpenCV 的dnn
设置 Colab 环境。你也可以在这里查看,我根据回答做了细微的改动。
将dnn
分配给 GPU 的代码很简单:
import cv2
net = cv2.dnn.readNetFromCaffe(protoFile, weightsFile)
net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)
net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)
但是,如果您直接在 Colab 上运行该单元格,您将看到以下错误:
所以我们需要做点什么。
如果你在 Colab 上检查预装 OpenCV 的版本,你会看到这个:
我们需要自己安装 cv2。
首先,运行这个单元:
%cd /content!git clone https://github.com/opencv/opencv!git clone https://github.com/opencv/opencv_contrib!mkdir /content/build%cd /content/build!cmake -DOPENCV_EXTRA_MODULES_PATH=/content/opencv_contrib/modules -DBUILD_SHARED_LIBS=OFF -DBUILD_TESTS=OFF -DBUILD_PERF_TESTS=OFF -DBUILD_EXAMPLES=OFF -DWITH_OPENEXR=OFF -DWITH_CUDA=ON -DWITH_CUBLAS=ON -DWITH_CUDNN=ON -DOPENCV_DNN_CUDA=ON /content/opencv!make -j8 install
您将看到类似这样的内容:
这需要一段时间,完成后你可以检查 OpenCV 的版本。
就这样吧!现在你应该能够正确无误地将dnn
设置为 CUDA 了。
net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)
net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)
但是第一步要花很多时间,每次启动笔记本都需要做。这样很费时间,也不理想。
这里你可以做的一件事是将第一步的结果保存到你的 Google Drive(你必须挂载它)。
!mkdir "/content/gdrive/My Drive/cv2_gpu"!cp /content/build/lib/python3/cv2.cpython-36m-x86_64-linux-gnu.so "/content/gdrive/My Drive/cv2_gpu"
然后在下次启动笔记本时将其复制到您的工作目录中。
!cp "/content/gdrive/My Drive/cv2_gpu/cv2.cpython-36m-x86_64-linux-gnu.so" .
并检查版本以确保完成。
如果你不想安装你的 Google Drive,你可以把它上传到云中的某个地方,然后用!wget
把它下载到你的工作目录。
就是这样。感谢阅读。享受 GPU 带来的乐趣。
为什么我使用 Plotly 进行数据可视化
了解商业图表和图形的 Plotly
卢克·切瑟在 Unsplash 上的照片
世界上的数据量每秒都在增长。从发送文本到点击链接,你都在创造数据点供公司使用。从这些数据收集中获得的见解可能非常有价值。每个企业都有自己需要检查的数据存储。完成这种检查的最重要的方法之一是可视化数据。
为什么要可视化数据?
简单来说——“一图抵千言”。在整个商业历史中,数据可视化一直是一个必要的组成部分。它如此必要的原因最终是因为我们是视觉动物。除此之外,你认为为什么我们大多数人更喜欢看改编自一本书的电影,而不是阅读这本书本身?在商业演示方面,销售数据的图表可能比纯文本更有洞察力。从视觉媒介而不是 word 文档中获取洞察力是很容易的。
通过可视化数据,您可以让更广泛的受众更容易访问这些数据。这有助于获得更多的洞察力,因为其他人可能会有一两个你可能从未想过的洞察力。越多的人看到你的视觉化图像,就越有可能获得更多的洞察力。
在向董事会成员或股东等关键决策者展示时,可视化也发挥着关键作用。当你构建大量的图表来突出关键数据点时,你决定制作的视觉效果可以帮助这些决策者向一个或另一个方向前进。如果在展示数据视觉效果时考虑了一个精选的叙述,那么这些决策者会倾向于根据你的展示做出具体的决定。
数据可视化工具
饼图、条形图、折线图等等都是展示数据时的有效视觉效果。这些视觉效果是经过检验的真实的数据呈现形式,我们使创建它们变得更加容易。我们过去用手做的事情现在在电脑上点击几下就可以完成了。
如今,我们可以使用多种程序来构建漂亮的图表。这些工具从更基于技术的可视化应用,如 Python 的 Matplotlib 或 Plotly 到更用户友好的应用,如 Tableau 或 微软 Power BI 。数据可视化工具现在比以往任何时候都更容易使用。
在 Python 编程领域,有许多不同的库可以用来制作数据可视化。这些库包括但不限于牛郎星、海本和 Plotly 。没有更好的 Python 库,因为这完全取决于你喜欢什么,以及你试图可视化的问题或数据。
学习如何使用 Plotly
我们之前提到的一个工具叫做 Plotly 。Plotly 是一个类似于 Matplotlib 的 Python 图形和绘图库。两者的区别在于,Plotly 可以动态地创建交互式图表和图形。
一个简单的商业问题
要开始使用 Plotly,我们首先需要数据来绘制图表或绘图。比方说,你在一家销售服装的公司工作。他们希望您绘制他们的衬衫和牛仔裤在一年中的销售图表,并为此向您提供了数据。这个问题将帮助我们开始与 Plotly 合作。
安装 Plotly
为了开始,我们必须首先在您的终端中使用以下命令安装 Plotly:
$ pip install plotly
或者如果您安装了 Anaconda :
$ conda install -c plotly plotly
Plotly 导入
现在您已经安装了 Plotly,让我们打开一个新文件,并开始为我们的数据可视化示例导入必要的库:
import plotly.express as px
import calendar as cal
import random
import pandas as pd
这里我们使用的是plotly.express
,它是 Plotly 中的一个模块,可以为我们快速创建图形和图表。
创建数据
由于我们实际上没有得到真实的数据,我们将不得不创建自己的数据:
data = {'Months': [cal.month_name[i] for i in range(1,13)],
'Shirts': [round(random.gauss(100, 15)) for _ in range(12)],
'Jeans': [round(random.gauss(50, 20)) for _ in range(12)]}
Plotly 与 Pandas 数据框架配合得非常好,因此我们将把新创建的数据存储到 DF:
df = pd.DataFrame(data)
这个新的 DF 看起来像这样:
我们对 Plotly 的 DF
普罗特利条形图
现在我们已经准备好了 DF,我们可以开始制作条形图了:
fig = px.bar(df,
x='Months',
y=['Shirts','Jeans'])fig.show()
这里我们使用.bar()
方法,输入我们数据的 DF,并指定 x 和 y 轴。我们正在制作一个堆叠条形图,为列列表:‘Shirts
’和’Jeans
’。我们将通过调用fig.show()
来显示它。
成功!这很简单。这个 Plotly 图表很酷的一点是,你可以通过放大、平移等方式开始与它互动。但是就整个图表而言,我们想要改变一些东西,使这个图表更具描述性,例如添加标题和重命名一些标签。
fig = px.bar(df,
x='Months',
y=['Shirts','Jeans'],
title='Total Monthly Item Sales',
labels={'variable': 'Item',
'value': 'Quantity Sold (in thousands)'})fig.show()
这段代码与之前代码的不同之处在于增加了title=
和labels={}
参数。有了这些新的参数,我们为图表添加了一个标题,在labels
下面,我们基本上使用了一个字典来替换当前的两个标签。
更新了带有正确标签和标题的条形图
现在条形图已经被正确标记,我们基本上已经完成了对这些数据使用 Plotly。但是,如果我们想要制作其他类型的图表或图形,以便查看数据的不同方面,该怎么办呢?
普洛特利线图
Plotly 也允许我们创建其他类型的可视化。我们可以使用之前的代码轻松创建一个线图,只需更改一点:
fig = px.line(df,
x='Months',
y=['Shirts','Jeans'],
title='Monthly Item Sales',
labels={'variable': 'Item',
'value': 'Quantity Sold (in thousands)'})fig.show()
我们在这里所做的只是将px.bar
改为px.line
。这会显示以下内容:
具有相同数据的折线图
现在我们有了一个线图!但是等等,还有更多…
普罗特利饼图
假设我们想比较全年卖出了多少件衬衫和多少条牛仔裤。
首先,我们必须更改数据以显示衬衫和牛仔裤的总销售额:
pie_df = df[['Shirts','Jeans']].sum()
这里我们只是从 DF 中得到Shirts
和Jeans
的和。然后,我们将需要使用px.pie()
使用我们新总结的 DF。
fig = px.pie(values=pie_df.values,
names=pie_df.index,
title="Sales Percentage in a Year")fig.show()
参数values
用于确定饼图每个部分的大小。names
是每个部分的标签。
我们的数据饼状图
厉害!现在我们已经为我们的数据创建了三种不同类型的可视化。但是你不必停下来——如果你觉得有必要继续尝试 Plotly,还有更多选项可用( 查看这里了解更多 )。
数据洞察和结论
在可视化我们的数据之后,我们需要根据视觉效果得出某种见解或结论。根据这些图表,你能看出什么?有没有一些显而易见的结论可以得出?一些不那么明显的呢?
无论如何,见解和结论更容易看到而不是阅读。如果你仍然想知道可视化的重要性,那么就回头看看我们创建的 DF,并将其与我们用 Plotly 创建的任何视觉效果进行比较。有时候看资料不如看资料。
如何使用 Plotly.js 进行数据可视化
从 40 多种图表类型中选择
卢克·切瑟在 Unsplash上的照片
在近年来,数据可视化已经成为医疗保健、非营利组织和许多其他部门决策的主要工具之一。通过使用数据可视化,如图表和地图,我们可以用图形表示数据。它帮助人们根据趋势和模式做出快速判断。
互联网上有许多数据可视化工具。在这些工具的广泛列表中, plotly.js 就是其中之一。这是一个基于 d3.js 和 stack.gl 构建的 JavaScript 开源图形库。这个库提供了各种各样的图表类型,包括 3D 图表、图形和 SVG 地图。
我已经使用 plotly.js 创建了仪表板,通过其丰富的图形库中的交互式图表来可视化数据。与其他库相比,我更喜欢 Plotly.js,因为它易于使用,并且有健壮的文档。从这篇文章中,你将学到一些 plotly.js 的基本概念和命令,它们将教会你如何可视化数据。
设置
首先,我们需要在 HTML 文件中添加 plotly.js。你可以下载文件或者使用 CDN 链接。这里,为了方便起见,我们将使用 CDN 链接。之后,我们需要一个名为 test 的空 DIV 来附加图表。最后,我们需要添加一些 JavaScript 代码来绘制图表。现在将下面的代码保存在一个 HTML 文件中,比如test.html
。
通过在您的浏览器上加载这个文件,您可以看到一个如下图所示的线形图。如果您看不到任何内容,请尝试打开浏览器的开发人员控制台。它将帮助您调试问题。
折线图
现在让我们将脚本标签分解成单独的部分。首先,我们有包含散列的data
数组。在散列中,我们有两个键值对x
和y
,分别代表x-axis
和y-axis
的值。接下来是一个layout
散列,这里我们定义了图表的字体大小。config
散列用于向图表添加额外的配置。因为我们希望图表具有响应性,所以我们将 responsive 设置为 true。您可以在此找到关于配置的更多信息。现在我们需要将图表添加到 HTML 元素中。在这种情况下,它是一个DIV with id test
。最后,我们可以使用Plotly.newPlot
方法创建图表,方法是将 DIV DOM 元素、数据数组、布局和配置散列作为参数传递。
我们再来看几个例子。
地图
首先,我们需要定义数据 URL。Plotly.d3.json
方法可以从提供的 URL 读取 JSON 数据。我们可以在data
数组的散列中使用type
键来配置图表类型。散列还接受latitude
、longitude
和hoverinfo
数据。hoverinfo
用于当悬停在地图坐标上时显示信息。这里我们显示的是纬度和经度信息。你可以在这里找到更多选项。在layout
散列中,我们有mapbox
和margin
。mapbox
的选项不言自明。如果您正在寻找更多的边距设置,请查看此处的。config
散列包含mapboxAccessToken
和responsive
密钥。你可以在这里从获取令牌值,我们已经讲过了responsive
key 的使用。
通过在浏览器上运行上面的代码,我们可以看到如下图所示的地图。
地震数据
饼图
为了创建饼图,我们可以在data
数组的散列中使用type
键来配置图表类型。我们还需要定义每个切片的值。为此,我们需要使用values
和labels
作为键。
通过在浏览器上运行上面的代码,我们可以看到一个类似下面的饼状图。
学生成绩
条形图
为了创建条形图,我们可以在data
数组的散列中使用type
键来配置图表类型。我们还需要定义每个条形的值。为此,我们需要使用x
和y
作为键。
通过在浏览器上运行上述代码,我们可以看到如下所示的条形图。
学生成绩
气泡图
为了创建气泡图,我们可以在data
数组的散列中使用mode
键来配置模式类型。我们还需要定义每个圆的中心值。为此,我们需要使用x
和y
作为键。使用size
键设置圆圈的大小。如您所见,最后一个圆不可见,因为我们没有提供大小。
通过在浏览器上运行上面的代码,我们可以看到一个类似下图的气泡图。
包裹
数据分析是许多企业的重要组成部分。当处理数据变得更容易时,我们可以改善我们的判断和决策,当我们有一种有效的方法来显示数据时,这是可能的。Plotly.js 是实现商业的一个很好的工具。它可以帮助您发现隐藏的见解,否则使用传统方法很难发现。我希望这篇文章能帮助你开始使用 plotly.js。
如何将 Pyspark 用于您的机器学习项目
使用 Pyspark 进行数据清理、EDA、特征工程和机器学习
来源:https://unsplash.com/photos/Q1p7bh3SHj8
Pyspark 是一个支持 Apache Spark 的 Python API,Apache Spark 是一个用于处理大数据分析的分布式框架。当您处理大型数据集时,这是一个令人惊叹的框架,它正在成为任何数据科学家的必备技能。
在本教程中,我将介绍如何使用 Pyspark 来做你习惯在 Kaggle 笔记本上看到的事情(清洁、EDA、特征工程和构建模型)。
我为一家电信公司使用了一个包含客户信息的数据库。目标是预测未来三个月哪些客户会离开(流失)。包含数据的 CSV 文件包含超过 800,000 行和 8 个特征,以及一个二进制变动变量。
**这里的目标不是找到最佳解决方案。而是向您展示如何使用 Pyspark。**在这个过程中,我将尝试展示许多可用于您机器学习项目所有阶段的功能!
让我们首先创建一个 SparkSession,这是任何 Spark 功能的入口点。
import pyspark
from pyspark.sql import SparkSessionspark = SparkSession.builder.master("local[4]")\
.appName("test").getOrCreate()
获取数据
以下是如何使用 Pyspark 读取 CSV 文件。
df=spark.read.csv('train.csv',header=True,sep= ",",inferSchema=True)
这是数据帧的样子。
清理数据
Pyspark.sql 模块允许您在 Pyspark 中做几乎任何可以用 sql 做的事情。
例如,让我们先清理一下数据。首先,如上图所示,我们有一些空值。我将删除所有包含空值的行。
df = df.na.drop()
然后,when/otherwise
函数允许您过滤一列,并根据每行中找到的内容分配一个新值。举个例子,我用 0 和 1 代替男性和女性作为性别变量。
from pyspark.sql.functions import when
df = df.withColumn("gender",when(df["gender"]=='M',0).otherwise(1))
探索性数据分析
一旦数据全部清理完毕,许多类似 SQL 的函数可以帮助分析数据。
例如,groupBy
函数允许您对值进行分组,并为每个类别返回 count、sum 或其他值。让我们看看有多少数据点属于流失变量的每个类。
df.groupBy('churnIn3Month').count().show()
我们这里有不平衡的班级。虽然我不会在本教程中做任何事情,但在接下来的一个教程中,我将向您展示如何使用 Pyspark 处理不平衡的类,如欠采样、过采样和 SMOTE。
另一件有趣的事情是观察两组(离开的客户和没有离开的客户)之间某些特征的不同。我发现了一个有趣的结果。
**from** pyspark.sql.functions **import** avg
df.select("phoneBalance","churnIn3Month").\
groupBy("ChurnIn3Month").agg(avg("phoneBalance"))
我们看到,离开的客户平均手机余额少得多,这意味着他们的手机更接近完全支付(这当然使他们更容易离开电话公司)。
现在,让我们来看一个相关矩阵。我使用 Pyspark 中的correlation
函数创建了它。我也做了一点手脚,在这里用了熊猫,只是为了更容易地创造一些视觉上的东西。
from pyspark.ml.stat import Correlationx=df.columns[2:11]
corr_plot = pd.DataFrame()for i in x:
corr=[]
for j in x:
corr.append(round(df.stat.corr(i,j),2))
corr_plot = pd.concat([corr_plot,pd.Series(corr)],axis=1)corr_plot.columns=x
corr_plot.insert(0,'',x)
corr_plot.set_index('')
同样,phoneBalance
与客户流失变量的相关性最强。
特征工程
考虑到上面的结果,我决定创建一个新变量,它将是phoneBalance
变量的平方。下面是如何用 Pyspark 做到这一点。
from pyspark.sql.functions import col, pow
df = df.withColumn('phoneBalance2',pow(col('phoneBalance'),2))
withColumn
函数允许您向 pyspark 数据框架添加列。超级有用!
机器学习
Pyspark 中的机器学习库肯定还没有达到 Scikit Learn 的标准。也就是说,你仍然可以用它做很多事情。
然而,你要做的第一件事是创建一个包含你所有特征的矢量。我们将使用的所有方法都需要它。
from pyspark.ml.feature import VectorAssemblerignore=['churnIn3Month', 'ID','_c0']
vectorAssembler = VectorAssembler(inputCols=[x for x in df.columns
if x not in ignore], outputCol = 'features')new_df = vectorAssembler.transform(df)
new_df = new_df.select(['features', 'churnIn3Month'])
然后,让我们将数据分成训练集和验证集。
train, test = new_df.randomSplit([0.75, 0.25], seed = 12345)
好了,现在让我们建立一些模型。我将只展示几个模型,只是为了让您了解如何使用 Pyspark。
1.逻辑回归
from pyspark.ml.classification import LogisticRegressionlr = LogisticRegression(featuresCol = 'features',
labelCol='churnIn3Month')
lr_model = lr.fit(train)
我们可以看看模型的 ROC 曲线。提醒一下,AUC(曲线下面积)越接近 1,模型就越能区分不同的类别。
import matplotlib.pyplot as pltplt.plot(lr_model.summary.roc.select('FPR').collect(),
lr_model.summary.roc.select('TPR').collect())
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.show()lr_model.summary.areaUnderROC
2.随机森林分类器
让我们再做一个模型,展示一旦数据以 Pyspark 的正确格式,即向量,拟合模型是多么容易。下面是如何创建一个随机森林模型。
from pyspark.ml.classification import RandomForestClassifierrf = RandomForestClassifier(featuresCol = 'features', labelCol =
'churnIn3Month')
rf_model = rf.fit(train)
下面是如何获得模型的 AUC:
from pyspark.ml.evaluation import BinaryClassificationEvaluatorpredictions = rf_model.transform(test)
auc = BinaryClassificationEvaluator().setLabelCol('churnIn3Month')
print('AUC of the model:' + str(auc.evaluate(predictions)))
这两个模型非常相似,但结果表明,在我们的情况下,逻辑回归模型略好。
结论
Scikit Learn 非常棒,只要您不处理太多数据,它的表现就会令人钦佩。可悲的是,你的项目越大,你就越有可能需要 Spark。幸运的是,正如您在这里看到的,开始使用 Pyspark 的学习曲线并不太陡,尤其是如果您熟悉 Python 和 SQL 的话。在我看来,Pyspark 的主要弱点是数据可视化,但希望随着时间的推移,这种情况会有所改变!
这就是了。对于想用 Pyspark 进行机器学习的人来说,这篇文章应该是一个很好的起点。我希望你喜欢它,并感谢阅读!
如何使用 Python 和 MissForest 算法估算缺失数据
使用随机森林处理丢失数据的分步指南
缺失值填补是数据科学和机器学习中的一个古老问题。技术从简单的均值/中值插补发展到基于机器学习的更复杂的方法。方法选择对最终结果有多大影响?事实证明,很多。
如果你更喜欢视频,这里也有适合你的东西:
缺失森林视频的缺失数据填补
让我们弄清楚一些事情——缺失值插补通常是特定于域的。例如,由于客户没有使用某些服务,数据集可能包含缺失值,因此插补是错误的做法。
此外,像均值/中值/众数插补这样的简单技术通常效果不佳。原因很容易解释。极值会影响数据集中的平均值,尤其是平均值。此外,用相同的值填充 10%或更多的数据听起来不太妙,至少对于连续变量来说是这样。
这篇文章的结构如下:
- KNN 插补的问题
- 什么是 MissForest?
- 实践中的失误
- 错误森林评估
- 结论
KNN 插补的问题
甚至一些基于机器学习的插补技术也有问题。例如,KNN 插补法是简单平均插补法的一个很好的开端,但也带来了一些问题:
- 您需要为 K 选择一个值——这对于小型数据集来说不成问题
- 对异常值很敏感,因为它使用表面下的欧几里得距离
- 不能应用于分类数据,因为需要某种形式的数字表示转换
- 可能计算量很大,但这取决于数据集的大小
不要误解我的意思,我会选择 KNN 估算法,而不是简单的平均值,但仍然有更好的方法。如果你想了解更多关于这个话题的信息,这里有我最近的一篇文章:
使用机器学习算法处理缺失数据
towardsdatascience.com](/missing-value-imputation-with-python-and-k-nearest-neighbors-308e7abd273d)
什么是 MissForest?
MissForest 是一种基于机器学习的插补技术。它使用随机森林算法来完成任务。它基于迭代方法,并且在每次迭代中生成的预测更好。你可以在下面阅读更多关于算法的理论,因为 Andre Ye 做了很好的解释和漂亮的视觉效果:
告别 KNN-估算
towardsdatascience.com](/missforest-the-best-missing-data-imputation-algorithm-4d01182aed3)
这篇文章更多的是针对的实际应用,所以我们不会过多的钻研理论。总的来说,误盗非常好,因为:
- 不需要大量的数据准备,因为随机森林算法可以确定哪些特征是重要的
- 不需要任何调整—就像 K-最近邻中的 K
- 不关心分类数据类型—随机森林知道如何处理它们
接下来,我们将深入研究一个实际的例子。
实践中的失误
我们将使用虹膜数据集进行实践部分。数据集不包含任何缺失值,但这是关键所在。我们将随机产生缺失值,因此我们可以稍后评估 MissForest 算法的性能。
在我忘记之前,请从终端执行pip install missingpy
来安装所需的库。
太好了!接下来,让我们导入 Numpy 和 Pandas,并读入提到的 Iris 数据集。我们还将制作数据集的副本,以便稍后我们可以使用真实值进行评估:
代码片段 1 —导入和数据集加载
作者图片
好了,现在让我们制作两个唯一随机数列表,范围从零到虹膜数据集的长度。通过一些熊猫操作,我们将根据随机生成的索引位置,用 NaNs 替换sepal_length
和petal_width
的值:
代码片段 2 —缺失数据生成
作者图片
如您所见,petal_width
只包含 14 个缺失值。这是因为随机化过程产生了两个相同的随机数。这不会给我们带来任何问题,因为最终缺失值的数量是任意的。
下一步是,嗯,进行插补。我们还必须从图片中移除目标变量。方法如下:
代码片段 3—缺失数据插补
就是这样—缺失值现在被估算!
但是我们如何评价这该死的东西呢?这是我们接下来要回答的问题。
错误森林评估
为了执行评估,我们将使用我们拷贝的、未接触的数据集。我们将添加两个额外的列,表示来自 MissForest 算法的估算列——都用于sepal_length
和petal_width
。
然后我们将创建一个新的数据集,只包含这两列——原始状态和估算状态。最后,我们将计算绝对误差,以便进一步检查。
代码如下:
代码片段 4 — MissForest 评估
如您所见,代码的最后一行只选择了进行插补的行。让我们来看看:
作者图片
所有的绝对误差都很小,在原始平均值的一个标准偏差之内。如果不考虑增加的小数位,估算值看起来很自然。如果需要,可以很容易地修复。
离别赠言
这是一篇关于用机器学习方法进行缺失值插补的简短扼要的文章。你已经了解了为什么机器学习在这个领域优于简单的平均水平,以及为什么 MissForest 优于 KNN imputr。
我希望这对你来说是一本好书。保重。
喜欢这篇文章吗?成为 中等会员 继续无限制学习。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。
[## 通过我的推荐链接加入 Medium-Dario rade ci
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
medium.com](https://medium.com/@radecicdario/membership)
原载于 2020 年 11 月 5 日 https://betterdatascience.com。
如何有效地使用 Python 类
当一堆功能对你来说是更好的选择时
做事的方式应该只有一种。但是上课的时候会很混乱。照片由妮可·沃尔夫在 Unsplash 拍摄
“T这里应该只有一种——最好只有一种——显而易见的方法”,Python 的禅如是说。然而,在有些领域,即使是经验丰富的程序员也在争论什么是正确或错误的做事方式。
其中一个领域是 Python 类。从面向对象编程中借鉴来的,它们是非常漂亮的构造,可以在编码时扩展和修改。
最大的问题是,类会使你的代码比必要的更复杂,更难阅读和维护。那么什么时候应该使用类,什么时候应该使用标准函数呢?
这个故事是对这个问题的更深入的探究。所以如果你很急,你可以跳过下面的两个部分,直接向下滚动到第部分,什么时候使用类和部分,当类不是一个好主意的时候。
Python 类:非常基础
类是允许您将数据结构和过程分组到一个地方的对象。例如,假设您正在编写一段代码来组织服装店的库存。
您可以创建一个类,获取商店中的每件衣服,并存储关键数量,如衣服的类型、颜色和尺寸。我们还将添加一个选项来添加价格。
class Clothing(object):
def __init__(self, type, color, size, price=None):
self.type = type
self.color = color
self.size = size
self.price = price
现在,我们可以定义该类的各种实例,并将它们组织起来:
bluejeans = Clothing("jeans", "blue", 12)
redtshirt = Clothing("t-shirt", "red", 10, 10)
我们将在类的定义之后添加这两行没有缩进的内容。这段代码将会运行,但是它不会做太多。我们可以在类定义中的__init__
函数下直接添加一个设置价格的方法:
def set_price(self, price):
*"""Set the price of an item of clothing."""* self.price = price
print(f"Setting the price of the {self.color} {self.type} to ${price}.")
我们还可以添加一些例程来告诉我们价格,或者通过降低价格来促销商品:
def get_price(self):
*"""Get the price of an item of clothing, if price is set."""* try:
print(f"The {self.color} {self.type} costs ${self.price}.")
except:
print(f"The price of the {self.color} {self.type} hasn't been set yet!") def promote(self, percentage):
*"""Lower the price, if initial price is set."""* try:
self.price = self.price * (1-percentage/100)
print(f"The price of the {self.color} {self.type} has been reduced by {percentage} percent! It now only costs ${self.price:.0f}.")
except:
print(f"Oops. Set an initial price first!")
现在,我们可以在初始化该类实例的行之后添加一些方法调用:
print("blue jeans -------------------")
bluejeans.promote(20)
bluejeans.set_price(30)
bluejeans.get_price()print("red t-shirt ------------------")
redtshirt.get_price()
redtshirt.promote(20)
如果运行该脚本,输出将如下所示:
blue jeans -------------------
Oops. Set an initial price first!
Setting the price of the blue jeans to $30.
The blue jeans costs $30.
red t-shirt ------------------
The red t-shirt costs $10.
The price of the red t-shirt has been reduced by 20 percent! It now only costs $8.
如果你需要添加更多的例程,你可以把它们放在类定义中。
最棒的是,你可以添加和删除任意多的对象。删除属性的过程如下:
del redtshirt.price
如果你想删除整个对象,你可以这样做:
del redtshirt
所有这些都是整洁、简单和可扩展的。试着用标准函数来实现,你可能会遇到更多的麻烦。
从理论的角度来看,有更多的理由说明 Python 类在许多情况下是一个美丽的概念。
正确使用时,类是强大的概念。Muhannad Ajjan 在 Unsplash 上拍摄的照片
理论上来说,课堂是很神奇的
关注点分离:给每个类分配自己的工作
如果你参加过计算机科学的讲座,很可能你已经偶然发现了“关注点分离”的原则。这基本上意味着你把你的程序分成不同的部分来处理不同的信息。
从本质上来说,类允许你遵守这个原则。换句话说,当你开始写一个程序,并且你在考虑类的时候,你可能在构建一个好的架构,因为你确保了每个问题都有自己的位置。
解耦:使维护更容易
在类中思考不仅有助于保持特性的分离,还能使它们相互独立。这不仅能保持物品的整洁;维护起来也方便了很多。
假设您在一个类中发现了一个 bug:您可以修复这个 bug,而不用担心其他类,因为它们之间没有联系。同样,你可以添加新的特性,而不用担心会与软件的其他部分纠缠在一起。
实现隐藏:定义程序员能使用什么,不能使用什么
通过使用类,您可以确保方法只用于一组数据。这增加了代码的安全性,因为您不太可能在不属于它们的地方使用函数。
封装:改变代码,但不改变用户体验
将数据结构和方法存储在一起也称为封装。由于所有这些对最终用户都是隐藏的,这允许您修改数据结构和方法,而不会损害用户体验。
例如,您可能需要构建一个非常复杂的方法。封装的优点是用户不需要理解任何复杂性,因为他们可以像使用黑盒一样使用它。
不使用类来构建黑盒函数是完全可能的。然而,对于类,这种类型的功能实际上是可以保证的。
继承:编写数据结构的 DNA
有了类,你只需要定义一个数据结构一次。当定义一个类的实例时,该实例自动继承给定的结构。
此外,继承使得删除或修改实例或整个类变得非常容易。这使得整个结构更加灵活。
让你的软件更快、更易读和更易维护并不需要这么难
towardsdatascience.com](/the-ultimate-guide-to-writing-better-python-code-1362a1209e5a)
何时使用类
有了这么多的优点,用一个类来做任何事情都很有诱惑力。然而,在实践中,有些情况下使用类非常有意义,而有些情况下则没有意义。
将数据和方法组合在一起
根据经验,当您有一组具有特定结构的数据,并且希望对其执行特定的方法时,请使用类。然而,只有在代码中使用多种数据结构时,这才是有效的。
如果你的整个代码不会处理一个以上的结构。如果你只有一种数据结构,那就真的要看手头的问题了。你可以通过有没有上课勾画出你的程序来得到一个大概的想法;通常你会很快发现哪个解决方案更简单。
当心全局变量
另一个经验法则是这个:如果你想使用全局变量来访问数据,定义一个类并构建一个方法来访问每一段数据可能更容易。
上课并不总是一个好主意。照片由克里斯蒂娜@ wocintechchat.com在 Unsplash 上拍摄
当上课不是个好主意时
对堆使用 heapq
与堆栈不同,堆是一种更灵活的存储数据的方式,因为它有无限的内存大小,并允许您调整变量的大小。另一方面,使用堆访问变量速度较慢,并且您必须自己管理内存。
如果一个堆更适合你的目的,你不需要定义一个类。Python 的内置heapq
,或者堆队列算法,为你做了工作。
考虑使用 functools.partial()
您可能很想使用一个类,因为您经常用相同的参数调用一个函数。在大多数情况下,用functools.partial()
来代替会更好。
实现起来相当简单。假设您有一个将两个值相乘的函数,但是您一直使用它来将两个值加倍。为了避免重复代码,您可以这样写:
from functools import partialdef multiply(x,y):
return x * ydoubling = partial(multiply,2)
print(doubling(4))
比定义一个新类简单多了!
“面向未来”的课程
一些程序员痴迷于类,因为它们是如此的灵活和可扩展。这就是为什么,即使在声誉良好的公司和经验丰富的开发人员中,您也可能会遇到这样的代码:
class newclass:
"""defining a new class to do something awesome"""
pass
其背后的思想是,随着代码的增长,无论新的数据结构和方法是什么,都可能需要这个类。但这不是好习惯!
猜猜这三行代码是做什么的?完全没有。这些行并不难编码。如果你认为你以后还需要另一门课,并且你真的认为你将来会忘记它,你可以留下这样的评论:
# initiate a new class here if needed for purpose XY
尽管你想让你的代码具有可扩展性和不傻,初始化一个什么都不做的类通常不是一个好主意。
和 7 种解决方法
towardsdatascience.com](/7-reasons-why-programmers-burn-out-44a40bf8948d)
底线是:Python 类是一把双刃剑
毫无疑问,阶级是一个强大的概念。正确使用,它们可以使你的代码更整洁,更可读和可维护。
但是它们被过度使用了。如果使用不当,它们会污染你的代码,直到你什么都不懂。
有时,特别是在简单的程序中,你可以使用一个类或一组通用函数,代码在长度和复杂性上非常相似。随着程序变得越来越复杂,差异变得越来越突出。
从这个意义上来说,Python 的禅坚持了它的结论:大多数时候,确实只有一种好的做事方式,不管有没有类。然而,这并不总是完全显而易见的。困难的部分是认识到哪条路是好的。
如果你有其他关于 Python 或其他编程语言的问题,请在评论中告诉我!感谢 卢卡斯·苏亚雷斯 询问何时使用类,何时不使用类的技巧。
如何在 iPad 上使用 Python
了解如何使用 iPad 创建 Python 脚本
对于那些一直在阅读我的关于 Python 金融的博客和观看我的视频的 T2 的人,我想与你们分享如何使用 iPad 用 Python 编程。
照片由 bongkarn thanyakij 从 Pexels
为什么 iPad 要用 Python?
你们中的一些人可能会问,为什么我要把笔记本电脑换成 iPad 来编码呢?从我的角度来看,我不认为 iPad 会取代笔记本电脑进行编码。至少短期内不会。然而,在编码方面,它可以作为笔记本电脑的一个很好的补充。
例如,想象一下,你要去湖边的某个地方度周末,而你不想带着电脑和充电器。在这种情况下,如果你想在周末假期继续写代码,唯一的选择就是带上 iPad。
如何在 iPad 上使用 Python 编码?
根据我的经验,到目前为止,我发现在 iPad 上使用 Python 的最好方式是通过 Google Colab 。这是一个免费工具,所有拥有 Gmail/Google 账户的人都可以使用。
Google Colab 提供与 Jupyter notebook 相同的功能。 Colab 允许您在浏览器中编写和执行 Python,主要优势是:
- **不需要预先设置。**它预装了大量的软件包。即 Pandas、Numpy、TensorFlow、Scikit-learn、Matplotlib 等众多。我们可以简单地通过导入包来使用它们。
- 脚本在所有设备中都可用。也就是说,可以在笔记本电脑和 iPad 上访问和编辑相同的脚本。
- 免费访问 GPU。
- 代码和脚本可以很容易地与他人分享。创建的脚本可以上传到 Github,也可以作为下载到本地磁盘。py 扩展名。
- 最棒的是,它完全免费,让我们可以在 iPad 上用 Python 编程。
总而言之,我认为 Google Colab 是一个很好的工具,可以用来进行金融分析或任何其他数据科学项目。我在 Medium 上发布的所有文章都是使用 Google Colab 或 Jupyter Notebook 完成的。这意味着它们都可以用 iPad 复制。
如何设置 Google Colab?
为了开始在 iPad 上使用 Python,我们需要有一个 Google drive 帐户。 Google Drive 提供免费云存储供个人使用。你可以在这里创建一个免费账户。
创建帐户后,要在 iPad 中开始编码,需要遵循以下步骤:
- 使用浏览器登录 iPad 中的 Google Drive。然后,通过点击 New 创建一个新的 Colab 文档:
2.选择更多和谷歌联合实验室。如果您在列表中没有看到 Google 协同实验室,请点击连接更多应用将其安装到您的 Google Drive 中。
3.一个新的 Google Colab 文档将会打开,我们可以在其中添加代码或文本:
4.以下是文件的主要部分。单击 1 重命名文档。2 和 3 允许您为编码或简单文本编辑添加新的单元格。4 是我们可以输入 Python 代码的单元格。一旦脚本准备就绪,单击 5 运行该单元格中的代码。最后,使用工具栏(6)保存或下载您的代码。
5.开始输入您的代码。下面以一个简单的例子来创建一个熊猫数据框架:
6.点击播放按钮,运行单元格以执行代码。结果显示在单元格下方:
包扎
正如我们所看到的,在 iPad 上开始使用 Python 是非常容易的。然而,出于两个原因,我不认为我的 iPad 会取代我的笔记本电脑来完成我的 Python 项目。:
- 首先,也是最重要的,对我来说,用 iPad 屏幕键盘写代码效率非常低。与使用普通键盘相比,我的速度更慢,也更容易出错。如果使用 iPad Magic Keyboard 的体验有所改善,我会在以后的帖子中分享我的体验。
- 第二个原因是,与我的笔记本电脑或台式电脑相比,我的 iPad 屏幕较小。
然而,有时,特别是当我不得不旅行时,我用我的 iPad 进行 Python 编码,它的工作就像我在计算机中编码一样。请随意发表您的评论,分享您使用 iPad 编码的经验,以及您使用的是哪一款应用程序。
我还有一个 Youtube 视频短片,是关于如何用 iPad 用 Python 编程的:
如何使用 iPad 编写 Python 代码
原载于 2020 年 5 月 24 日 https://codingandfun.com**T21。
如何使用 Python Seaborn 进行探索性数据分析
通过直方图、热图、散点图、条形图等浏览示例数据集
来源: Unsplash
这是一个使用 Python 中 seaborn 库进行探索性数据分析(EDA) 的教程。
EDA 是数据分析(或机器学习/统计建模)中除了Python 中的数据清洗:终极指南(2020) 之外的另一个关键过程。
在本指南中,您将发现(通过示例):
- 如何使用 seaborn Python 包生成有用且漂亮的可视化效果,包括直方图、条形图、散点图、箱线图和热图。
- 如何用不同的图探索单变量、多变量数值和分类变量。
- 如何发现多个变量之间的关系。
- 更多。
我们开始吧!
什么是探索性数据分析(EDA),为什么?
探索性数据分析 ( EDA )是一种分析数据集以总结其主要特征的方法,通常采用可视化方法。
可以使用或不使用统计模型,但 EDA 主要是为了查看数据可以告诉我们什么,而不仅仅是正式的建模或假设测试任务。
在进一步分析或建模之前探索数据是很重要的。在这个过程中,我们可以从数据集获得洞察的概览;我们可以发现不明显的趋势、模式和关系。
什么是 seaborn?
统计数据可视化是一个流行的 Python 库,用于执行 EDA。
它基于 matplotlib 并提供了一个高级接口,用于绘制有吸引力且信息丰富的统计图形。
在这篇文章中,我们将使用一个清理过的 YouTube 数据集作为例子。
在我们之前的文章如何利用机器学习技术获得更多的 YouTube 浏览量中,我们就如何基于同一数据集获得更多的浏览量提出了建议。
在探索之前,让我们将数据读入 Python 作为数据集 df 。
df 包含 729 行和 60 个变量。它为悉尼的 YouTube 频道内的每个视频录制不同的功能,例如:
- 浏览量:视频的浏览量
- 时长:视频/健身程序的时长,以分钟为单位
- 卡路里:视频中健身过程中消耗的卡路里数
- days_since_posted :视频发布到现在的天数
- 日期:视频/锻炼发布的日期
悉尼几乎每天都会发布一个视频/锻炼 - 健身程序类型:视频关注的健身程序类型
同样,你可以在如何利用机器学习技术获得更多 YouTube 浏览量中找到更多细节。我们在这里只使用这个数据集。
单变量分析:数值变量
首先,让我们来探讨数值单变量。
我们创建 df_numeric 只是为了包含 7 个数字特征。
直方图:单一变量
直方图是我们最喜欢的图形之一。
直方图是数字数据分布的近似表示。
要构建直方图,第一步是“分格”(或“存储桶”)值的范围,即将整个值范围分成一系列区间,然后计算每个区间内有多少个值。
Seaborn 的函数 distplot 有以下选项:
- 箱:箱设置
用不同的箱设置绘制变量以发现模式很有用。如果我们不设置这个值,库会为我们找到一个有用的默认值。 - kde :是否绘制高斯核密度估计
这有助于估计连续随机变量的概率密度函数的形状。更多细节可以在 seaborn 的页面上找到。 - 地毯:是否在支撑轴
上绘制地毯图这将在每个观察点绘制一个小的垂直勾。它有助于了解变量值的确切位置。
让我们先来看一个变量:length,它代表视频的长度。
我们可以在下面的图中看到 kde 线和地毯贴。
悉尼频道的视频通常长度为 30、40 或 50 分钟,呈现多模态模式。
直方图:多个变量
通常,我们希望将多个数值变量可视化并一起查看。
我们构建下面的函数 plot_multiple_histograms 来绘制特定变量组的直方图。
我们可以看到,不同的变量表现出不同形状的分布,异常值,偏度等。
单变量分析:分类变量
接下来,让我们看看分类单变量。
条形图:单变量
条形图(或 seaborn 的计数图)是分类变量版本的直方图。
条形图或条形图是一种图表或图形,用矩形条表示分类数据,矩形条的高度或长度与它们所代表的值成比例。
条形图显示离散类别之间的比较。
首先,让我们选择分类(非数字)变量。
我们绘制了可变区域的条形图,该区域代表健身程序视频关注的身体区域。
这些视频针对了许多领域。不放大就很难阅读。尽管如此,我们可以看到这些视频中超过一半(超过 400 个)集中在“完整”的身体部位;第二个最受关注的领域是“ab”。
条形图:多个变量
此外,我们创建一个函数plot _ multiple _ count plots来一次绘制多个变量的条形图。
我们用它来绘制一些指标变量如下。
is _ { } _ 区域是不同身体区域的指示变量。例如,当锻炼集中在臀部时,is_butt_area == True,否则为 False。
is _ { } _ 健身程序是不同健身程序类型的指示变量。例如,当锻炼侧重于力量时,is_strength_workout == True,否则为 False。
多变量分析
在逐一探究了变量之后,让我们一起来看看多个变量。
不同的图可以用来探索不同变量组合之间的关系。
在最后一节中,您还可以找到一种用于测试多个变量之间关系的建模方法。
散点图:两个数值变量
首先,让我们看看如何发现两个数值变量之间的关系。
如果我们想知道锻炼时间如何影响观看次数,该怎么办?
我们可以用散点图( relplot )来回答这个问题。
散点图使用笛卡尔坐标来显示一组数据的典型的两个变量的值。如果点被编码(颜色/形状/大小),可以显示一个额外的变量。
数据显示为点的集合,每个点的一个变量的值决定水平轴上的位置,另一个变量的值决定垂直轴上的位置。
我们可以看到,更受欢迎的视频长度往往在 30 到 40 分钟之间。
条形图:两个分类变量
如果我们想知道两个分类变量之间的关系呢?
让我们来看看视频中最常见的 6 个区域(区域 2 )和最常见的 4 种健身程序类型(workout_type2)。
我们可以看到,视频中最常见的是“全面”的身体“力量”训练。
箱线图:数值和分类变量
盒状图是比较类别组时有用的可视化工具。
盒图 ( 盒须图)是一种基于五个数字汇总显示数据集的标准化方式:最小值、最大值、样本中值、第一个和第三个四分位数。
我们可以使用并排箱线图来比较分类变量类别中的数值变量。
悉尼的视频在一周的特定日子里会有更多的浏览量吗?
让我们画出星期几和视图。
这很有趣,但由于离群值的原因很难看到。让我们移除它们。
我们可以看到,周一的视频往往比其他日子有更多的浏览量。而周日视频的浏览量最少。
群集图:数值和分类变量
看待同一个问题的另一种方式是群体图。
一个群集图是一个分类散点图,其中的点被调整(仅沿分类轴)以使它们不重叠。
这更好地表示了值的分布。
当我们想要显示所有的观察结果以及一些基本分布的表示时,群图是对盒图的很好的补充。
对于较大的数据集来说,群集图会有太多的点,但对于较小的数据集来说,这样做很好。
箱线图组:数值和分类变量
对于某些锻炼类型,一周中某些天的观看率会更高吗?
要回答这个问题,需要两个分类变量(锻炼类型、星期几)和一个数字变量(视图)。
让我们看看如何将这个问题的答案形象化。
我们可以使用面板箱线图( catplot )将三个变量一起可视化。
catplot 有助于使用几种可视化表示中的一种来显示数值变量与一个或多个分类变量之间的关系。
这是相当混乱的太多种类的锻炼类型。
根据锻炼类型的分布,我们将除“力量”、“hiit”、“伸展”、“有氧运动”之外的其他类别归为“其他”。
此外,我们删除了离群值,使图形更加清晰。
我们可以注意到这样的事情:
- “伸展”训练仅在周日发布。
- “hiit”锻炼似乎在周一有更多的观点。
热图:数字和分类变量
我们还可以使用数据透视表和热图来可视化多个变量。
热图是一种数据可视化技术,以二维颜色显示现象的大小。
颜色的变化可能是色调或强度的变化,给读者提供了明显的视觉线索,表明现象是如何聚集或随空间变化的。
例如,下面的热图以区域和健身 _ 类型类别为轴;色标代表每个单元格中的视图。
(高级)关系检验和散点图:数值和分类变量
我们如何自动发现多个变量之间的关系?
让我们看看下面最关键的特征,看看我们如何找到有趣的关系。
我们有 4 个数字变量和 3 个分类变量。
他们之间可能有许多复杂的关系!
在本节中,我们使用与如何使用机器学习技术获得更多 YouTube 浏览量中相同的方法来测试它们之间的关系(包括多重共线性)。
在高层次上,我们使用 K 倍交叉验证来实现这一点。
首先,我们转换分类变量。由于我们将使用 5 重交叉验证,我们需要确保每个类别级别至少有 5 次观察。
接下来,我们遍历每个变量,并使用其他变量拟合一个模型来预测它。我们使用一个简单的模型梯度推进模型(GBM) 和 K 倍验证。
根据目标变量是数值型还是分类型,我们应用不同的模型和分数(模型预测能力评估指标)。
当目标为数值时,我们使用梯度推进回归器模型和均方根误差(RMSE);当目标是分类的时,我们使用梯度推进分类器模型和精确度。
对于每个目标,我们打印出 K 倍验证分数(分数的平均值)和最重要的 5 个预测值。
我们还添加了三个由随机数组成的特征 rand0 、 rand1 、 rand2 。它们在比较变量之间的关系时充当锚。如果一个预测因子与这些随机变量相比不太重要或相似,那么它就不是目标变量的重要预测因子。
从上面的结果中,我们可以看到每个目标变量以及它们与预测值的关系。
同样,可以在如何使用机器学习技术获得更多 YouTube 浏览量中的多重共线性测试部分找到该测试的分步程序。
我们可以看到长度和卡路里之间有很强的关系。
让我们用散点图来形象化它们:x 轴表示长度,y 轴表示卡路里,而点的大小表示视图。
我们可以看到,视频越长,消耗的热量越多,很直观。我们还可以看到,观看次数越多的视频长度越短。
相关文章:
[## 如何用机器学习技术获得更多的 YouTube 浏览量——仅仅是数据
在这篇文章中,我们用 Python 对 YouTube 数据应用了机器学习算法。我们将包括端到端流程…
www.justintodata.com](https://www.justintodata.com/get-more-youtube-views-with-machine-learning/)
上一篇文章使用了相同的数据集。它包含了我们如何抓取和转换原始数据集的细节。
[## Python 中的数据清理:终极指南(2020)——只进入数据
我们用 Python 创建了这个新的完整的分步指南。你将学习如何寻找和清理的技巧:丢失…
www.justintodata.com](https://www.justintodata.com/data-cleaning-python-ultimate-guide/)
本文涵盖了清理的内容以及清理缺失数据、异常值、重复数据、不一致数据等的技术。
感谢您的阅读。
如果你有任何问题,请留言。我们会尽力回答。
离开之前,别忘了 报名参加刚刚进入数据快讯的 !或者在推特、脸书上与我们联系。
因此,您不会错过我们的任何新数据科学文章!
原载于 2020 年 4 月 10 日 https://www.justintodata.com。
* [## 如何在线学习数据科学:你需要知道的一切——进入数据
这是利用在线资源进入数据科学的完整路线图/课程。你是否想学习…
www.justintodata.com](https://www.justintodata.com/how-to-learn-data-science-online-all-you-need-to-know/) [## 如何利用深度学习进行情感分析(LSTM·克拉斯)——只分析数据
这是利用在线资源进入数据科学的完整路线图/课程。你是否想学习…
www.justintodata.com](https://www.justintodata.com/sentiment-analysis-with-deep-learning-lstm-keras-python/) [## 预测时间序列的三个步骤:LSTM 与 TensorFlow Keras -只是进入数据
这是利用在线资源进入数据科学的完整路线图/课程。你是否想学习…
www.justintodata.com](https://www.justintodata.com/forecast-time-series-lstm-with-tensorflow-keras/)*