对 Python 字典进行排序的两种简单方法
以及 sort()和 sorted()的区别
字典是一种重要的数据结构,它通过将键与值进行映射来存储数据。Python 中默认的字典是无序的数据结构。像列表一样,我们可以使用 sorted()函数按键对字典进行排序。然而,它只会返回一个排序的键列表,这通常不是我们想要的。我们可能希望它按值而不是键排序,或者我们可能希望它返回一个排序的字典而不是一个列表。在本文中,我将讨论两种简单的方法,我们可以用它们来对 Python 字典进行排序并返回您想要的内容。
排序列表
既然我们在讨论排序,我想首先指出两个排序函数之间的一个非常重要的区别。让我们在列表中显示不同之处。假设我们有两个列表:
我们有两种对列表进行排序的方法,一种是使用 sort()进行就地排序,另一种方法是使用 sorted(),它不是就地排序。不同的是,当使用 sort()时,你会改变原来的列表,而 sorted()会返回一个新的列表而不改变原来的列表。如下所示:
sort()改变了原始列表
sorted()不改变原始列表
选择哪个用的高,要看实际情况。例如,如果你想保留原始记录,那么你应该使用 sorted()。如果你想节省空间和内存,那么你应该使用 sort()。
整理字典
让我们创建一个字典:
这里使用“zip”函数非常方便,我们将两个长度相同的列表中的元素映射在一起。
要对字典进行排序,我们必须使用 sorted(),因为字典没有嵌入 sort()函数:
如果我们直接使用 sorted(),该函数将只从字典中返回一个键列表:
或者一个值列表:
我们可以调用字典中的 items()函数,按键对其进行排序,并返回元组列表:
如果我们想对键进行逆序排序,我们可以在 sorted 函数中指定它:
如果我们想按值排序呢?有两种方法可以做到这一点。一种是使用 sorted(),但使用 lambda 函数指定排序的键;另一种方法是不使用默认的字典类型,而是使用不同的字典类型,直接按值对字典进行排序。
对于第一种方法,排序函数是一个键参数,用于指定在进行比较之前对每个元素调用的函数(或其他可调用函数)。我们可以在这里使用 lambda 函数来告诉 sorted()函数使用元素的哪一部分来进行比较。具体来说:
Python 是零索引的,所以 x[1]指定每个元素的第二部分是一个字典,也就是值。如果想要一个逆序,除了在 sorted()函数中添加一个逆序参数,我们还可以在 lambda 函数中使用一个负号:
然而,这个技巧只在值是数字变量时有效。如果是字符串变量,就要用 reverse 参数。
如果您有一个值是数字的字典,您也可以在创建字典时使用不同的字典类型来直接对字典进行排序。字典类型可以是集合库中的计数器:
一个
[**Counter**](https://docs.python.org/2/library/collections.html#collections.Counter)
是一个[**dict**](https://docs.python.org/2/library/stdtypes.html#dict)
子类,用于计数可散列对象。它是一个无序的集合,其中的元素存储为字典键,它们的计数存储为字典值。
创建计数器时,使用以下代码:
我们不是创建一个默认字典,而是创建一个计数器。它很有用,因为当我们想按值对字典排序时,我们可以只使用 most_common()函数:
当您希望返回一个按值降序排列的元组列表时,这非常有用。
collections 库还有其他有趣的数据类型,比如 OrderedDict,它保留了插入的每个项目的顺序。更多信息,请点击查看网站。
返回排序后的字典
通常,排序后,我们会得到一个元组的排序列表。如果你想以字典的形式拥有它,你可以使用字典理解,这很像列表理解,来完成这项工作:
在本文中,我将介绍两种对 Python 字典进行排序的方法,以及 sorted()和 sort()函数之间的区别。救命这有帮助!感谢您的阅读!
这是我所有博客帖子的列表。如果你感兴趣的话,可以去看看!
我快乐的地方
zzhu17.medium.com](https://zzhu17.medium.com/my-blog-posts-gallery-ac6e01fe5cc3) [## 阅读朱(以及媒体上成千上万的其他作家)的每一个故事
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
zzhu17.medium.com](https://zzhu17.medium.com/membership)
创建色盲友好数据可视化的两个简单步骤
你的剧情可能很多人都无法理解。以下是解决这个问题的方法。
托马斯·伊万斯在 Unsplash 上拍摄的照片。
根据色盲意识网站,色觉缺失影响着世界上大约 8%的男性和 0.5%的女性,这意味着全球大约有 3 亿人患有某种程度的色盲。当谈到数据可视化时,颜色和图形元素的粗心选择会使图表模糊不清,甚至许多人无法理解。
事实上,不仅仅是色盲的人在解释用不小心选择的配色方案绘制的数据时会有问题。像黑白打印或阳光照射在设备屏幕上这样的常见事情也可能影响没有色盲的人的颜色感知。
虽然有各种类型的色盲,但创建每个人都可以轻松理解的数据可视化实际上非常简单——归根结底就是做出正确的选择。尽管如此,现在大量的内容并不是色盲友好的。表面上看,主要问题是大多数数据科学家在设计他们的数据可视化时仍然不习惯考虑这个因素。
在设计数据可视化时,您通常会考虑色盲吗?如果你没有,也许你应该开始做了。在这里,您将找到一些简单的提示,帮助您创建每个人都可以完全理解的数据可视化,而不管色盲状况或外部色觉改变。
动机:对于色盲的人来说,看似正常的图表可能无法理解
当我在攻读博士学位时,我经常使用 Google Sheets 快速生成临时图。但事实证明,Google Sheets plots 的默认配色方案并不是真正的色盲友好。它看起来是这样的:
用谷歌工作表创建的虚构图表。
如果您没有色盲,您大概可以区分图表中五个不同的数据系列。但是让我们来看看色盲的人是如何看到它的。我用科布利斯——色盲模拟器来模拟患有八种不同色盲的人会如何感知这张图片。你可以查看下面的结果。(每个模拟条件的名称可以在图的标题中找到。)
第一:Protanomaly(红弱)。第二:Deuteranomaly(绿弱)。用谷歌工作表和科布利斯创建。
第一:Tritanomaly(蓝弱)。第二:红盲。用谷歌工作表和科布利斯创建。
第一:多盲症(绿盲)。第二:Tritanopia(蓝盲)。用谷歌工作表和科布利斯创建。
第一:色盲。第二:蓝锥单色。用谷歌工作表和科布利斯创建。
在其中一些模拟中,很难甚至不可能区分不同数据系列使用的不同颜色,这使得许多人完全无法理解该图表。实际上,任何在黑白打印件上看到它的人都不会理解。
第一步:选择正确的颜色
所以现在的问题是:有没有可能不考虑色盲,挑选出大家都能轻易分辨的颜色?鉴于有这么多不同的色盲状况,这可能不是一件容易的事情。一般建议是避免有问题的颜色组合,如红/绿、绿/棕、绿/蓝、蓝/灰等。
但幸运的是,其他人已经经历了这个过程,并找出了适合大多数色盲的颜色组合,所以你不必自己做这些。你可以在网上搜索这样的组合,使用你最喜欢的。甚至有一些在线工具可以根据你的要求帮助你选择一个色盲友好的配色方案,比如 ColorBrewer 和 Coolors 。
我已经使用 ColorBrewer 为上面的示例图表选择了一个更好的配色方案。这是一个很棒的工具,可以根据用户选择的各种标准生成配色方案,包括色盲友好性。我让它用五种色盲安全、易于打印的颜色来创建配色方案。这是我选的一个:
使用 ColorBrewer 建议的颜色的新地块。使用的颜色:#d73027、#fc8d59、#fee090、#91bfdb、#4575b4。用谷歌工作表和科布利斯创建。
这是科布利斯的色盲模拟结果:
第一:Protanomaly(红弱)。第二:Deuteranomaly(绿弱)。用谷歌工作表和科布利斯创建。
第一:Tritanomaly(蓝弱)。第二:红盲。用谷歌工作表和科布利斯创建。
第一:多盲症(绿盲)。左:Tritanopia(蓝盲)。用谷歌工作表和科布利斯创建。
第一:色盲。第二:蓝锥单色。用谷歌工作表和科布利斯创建。
这样好多了吧?几乎在所有情况下都可以很容易地区分这五种颜色。唯一的例外是色盲的模拟,这是一种影响大约 30,000 人中有 1 人的情况。患有完全色盲的人不能感知任何颜色,并且会发现在这个图中几乎不可能区分 A 和 E 以及 B 和 D。同样,同样的事情也可以说发生在任何一个把这个情节印成黑白的人身上。
虽然上面使用的配色方案并不适用于所有的色盲情况,但仍然有可能找到合适的配色方案。你会发现大部分都是单色调色板,由单一颜色的不同强度组成。下面是这样一个调色板的例子,也是用 ColorBrewer 生成的:
用 ColorBrewer 生成的色盲友好调色板。来源:ColorBrewer。
然而,虽然这种方法可以安全地用于五种不同的颜色,如本例所示,但如果您需要使用更多的颜色变化,颜色强度可能会变得越来越相似。即使对于没有色盲的人来说,这也可能是一个问题。
这表明,虽然使用色盲友好的调色板可以让大多数人更容易理解您的数据可视化,但它可能仍然不是一个完美的解决方案。一般来说,不建议只使用颜色的变化来编码信息,即使它们是可访问的颜色。这就是为什么你也需要第二步。
第二步:使用不同的形状、图案、纹理或标签
确保人们能够完全理解您的绘图的最佳方法是,通过使用其他东西来区分其中的数据系列,从而完全消除对可区分颜色的需求。(这并不意味着你不应该关心在你的绘图中使用哪些颜色——除了使用色盲友好的调色板之外,你还应该这样做*,以防万一。)*
例如,我们可以通过对每个数据系列使用不同的形状来改进上面的图表,如下所示:
对不同的数据系列使用不同的形状。用谷歌工作表创建。
通过这种设计,我们可以确保色盲读者能够完全理解绘制的数据,不管他们的具体情况如何。即使出于某种原因,有人严格使用黑色和白色(没有灰色阴影)打印该图表,该图表仍然是明确的。
对于其他类型的情节,您可以使用其他策略。对于线图,除了不同的颜色之外,还可以使用不同的线型和/或不同的线宽。不幸的是,我无法找到如何在 Google Sheets 中使用虚线或点线模式,但我经常用 LaTeX/PGFPlots 和 Python/Matplotlib 这样做,所以我确信其他广泛使用的绘图软件也支持它们。下面是一个用 Matplotlib 创建的示例:
在线图中使用不同的线型。用 Matplotlib 创建。
对于条形图或饼图,我建议应用不同的填充纹理。同样,我在 Google Sheets 上找不到这个选项,但许多最流行的绘图软件可能都支持它。这里有一个我几年前创建的真实例子(使用 PGFPlots):
在条形图中使用不同的填充纹理。使用 PGFPlots 创建。
如果由于某种原因,您不能在绘图中使用不同的形状、图案或纹理,请考虑向数据系列添加标签(前提是您有足够的空间)。最重要的是确保每个人都能够理解你绘制的数据。
摘要
许多人仍然在创建色盲不友好的数据可视化的主要原因不是因为这很难避免,而是因为他们可能从一开始就没有想过这个问题。一旦我们意识到这一点,并有意创建可访问的图表,它实际上是非常简单的。基本上,这归结为两件事:
- **选择色盲友好的调色板:**像 ColorBrewer 和 Coolors 这样的在线工具使得现在很容易找到合适的配色方案。你也可以使用在线色盲模拟器,比如科布利斯和来检查你的情节在其他人看来会是什么样子。
- **但不要只依赖颜色:**为你的地块添加不同的几何形状、线条图案、填充纹理甚至标签。这将提高每个人的可读性,包括没有色盲的人。
致谢
我感谢我用来创建本文所示示例的免费工具的创建者,即: 科布利斯 ,color brewer,Google Sheets,Matplotlib和
推荐阅读
- 娜奥米·戴维斯的《色盲——不成文的准则:色盲父母指南》。
- 关于色盲的一切:儿童(和成人)色觉缺失指南,作者凯伦·瑞·莱文。
出自同一作者
这是一个简单的策略,可以让你在任何项目中更有效率。
medium.com](https://medium.com/swlh/do-this-before-you-start-working-on-any-project-14fd7bfa7327) [## 要达到 1,000,000 美元,您需要投资多少以及投资多长时间
本文中的数学和交互式工具将为您提供这些问题的答案。你可能会感到惊讶。
themakingofamillionaire.com](https://themakingofamillionaire.com/how-much-and-for-how-long-you-need-to-invest-to-reach-1-000-000-19a0ce7d4c67) [## 80/20 法则如何影响你的长期投资
你投资的一半资金将产生你投资组合的大部分结果。但是哪一半呢?
themakingofamillionaire.com](https://themakingofamillionaire.com/how-the-80-20-rule-affects-your-long-term-investments-96f6577b59bc)
披露:此帖子包含一个或多个亚马逊服务有限责任公司协会计划的链接。作为代销商,我从通过这些链接购买的商品中获得佣金,客户无需支付额外费用。
在 Python 中更有效地循环的两种简单方法
使用枚举和压缩编写更好的 Python 循环
许多循环。由 David Streit 在 Unsplash 上拍摄的照片
Python range
函数非常强大,但它通常可以被其他内置函数所替代,使您的循环更容易编写和阅读。在本文中,我将向您展示何时可以用enumerate
或zip
来替换range
。
使用 enumerate(object)而不是 range(len(object))
问题 1 :你经常有像列表这样的对象需要迭代,同时还要跟踪每次迭代的索引。给定下面的列表,您将如何使用 for 循环来生成所需的输出?
my_list = ['apple', 'orange', 'cat', 'dog']# desired output
Item 0: apple
Item 1: orange
Item 2: cat
Item 3: dog
方案一:使用for i in range(len(my_list))
for i in range(len(my_list)):
print(f"Item {i}: {my_list[i]}")Item 0: apple
Item 1: orange
Item 2: cat
Item 3: dog
更好的解决方案:使用for i, value in enumerate(my_list)
for i, value in enumerate(my_list):
print(f"Item {i}: {value}")Item 0: apple
Item 1: orange
Item 2: cat
Item 3: dog
解释 : enumerate
在迭代器my_list
上循环,并在迭代对象时将条目及其索引作为索引条目元组返回(参见下面的代码和输出以查看元组输出)。当我们将循环构造为for i, value in enumerate(my_list)
时,我们解包索引项元组。
for i in enumerate(my_list):
print(i)(0, 'apple') # tuple, which can be unpacked (see code chunk above)
(1, 'orange')
(2, 'cat')
(3, 'dog')
问题 2 :给定与上面相同的列表,编写一个循环来生成所需的输出(确保第一个索引从 101 开始,而不是从 0 开始)。
my_list = ['apple', 'orange', 'cat', 'dog']# desired output
Item 101: apple
Item 102: orange
Item 103: cat
Item 104: dog
解决方案二:使用for i, value in enumerate(my_list, 101)
函数enumerate(iterable, start=0)
让您从任何想要的数字开始计数索引(默认为 0)。
for i, value in enumerate(my_list, 101):
print(f"Item {i}: {value}")Item 101: apple
Item 102: orange
Item 103: cat
Item 104: dog
外卖
enumerate
内置函数在迭代器上循环,并从迭代器中返回索引和条目作为索引条目元组- 使用
enumerate(object)
而不是range(len(object))
来获得更简洁易读的代码 - 提供第二个参数来指示开始计数的数字(默认值为 0)
使用 zip 并行迭代多个对象
问题 3: 你有多个想要并行迭代的列表或者对象。给定下面的三个列表,你将如何产生期望的输出?
my_list = ['apple', 'orange', 'cat', 'dog']
my_list_n = [11, 12, 25, 26]
my_list_idx = [1, 2, 3, 4]# desired output
1\. apple: 11
2\. orange: 12
3\. cat: 25
4\. dog: 26
解决方案 3 :使用range(len(my_list))
获取索引
for i in range(len(my_list)):
print(f"{my_list_idx[i]}. {my_list[i]}: {my_list_n[i]}")1\. apple: 11
2\. orange: 12
3\. cat: 25
4\. dog: 26
更好的解决方案:使用zip(my_list_idx, my_list, my_list_n)
for i, obj, count in zip(my_list_idx, my_list, my_list_n):
print(f"{i}. {obj}: {count}")1\. apple: 11
2\. orange: 12
3\. cat: 25
4\. dog: 26
说明:可以使用zip
同时迭代多个对象。zip
返回可以在循环中解包的元组。参见下面的例子来理解这个函数是如何工作的。
zip
返回元组:
for i in zip(my_list_idx, my_list, my_list_n):
print(i)(1, 'apple', 11) # 3-item tuple
(2, 'orange', 12)
(3, 'cat', 25)
(4, 'dog', 26)
元组中的每个元素都可以手动提取:
for i in zip(my_list_idx, my_list, my_list_n):
print(f"{i[0]}. {i[1]}: {i[2]}") # i is a 3-item tuple1\. apple: 11
2\. orange: 12
3\. cat: 25
4\. dog: 26
外卖
zip
内置函数可以同时迭代多个迭代器。zip
创建一个惰性生成器来生成元组
结论
使用内置的 Python 函数enumerate
和zip
可以帮助您编写更好的 Python 代码,可读性更强,更简洁。
如果您对提高数据科学技能感兴趣,以下文章可能会有所帮助:
[## 在 Python 中重塑 numpy 数组—一步一步的图形教程
本教程和备忘单提供了可视化效果,帮助您理解 numpy 如何重塑数组。
towardsdatascience.com](/reshaping-numpy-arrays-in-python-a-step-by-step-pictorial-tutorial-aed5f471cf0b) [## 使用终端多路复用器 tmux 提高编码和开发效率
简单的 tmux 命令来提高您的生产力
medium.com](https://medium.com/better-programming/code-and-develop-more-productively-with-terminal-multiplexer-tmux-eeac8763d273) [## 真实或虚假的关联:你约会的有魅力的人更令人讨厌
使用 Python 模拟数据、测试直觉并提高数据科学技能
towardsdatascience.com](/real-or-spurious-correlations-attractive-people-you-date-are-nastier-fa44a30a9452) [## 新冠肺炎危机期间的免费在线数据科学课程
像 Udacity、Codecademy 和 Dataquest 这样的平台现在免费提供课程
towardsdatascience.com](/free-online-data-science-courses-during-covid-19-crisis-764720084a2)
更多帖子, 订阅我的邮件列表 。
使用 Colab 的两步面部识别
上传你的图片,并说服自己使用谷歌 Colab
这是周一的早晨,我正在引导我内心的杰瑞米·霍华德(又一次)。在过去的几个月里,我看到了大量的面部识别指南,其中一些确实非常好。
问题是,每个深度学习或机器视觉的学生都通过不同的途径变得感兴趣。也许你是一个对声音感兴趣的音乐家,或者是一个对表格数据感兴趣的统计学学生。
我知道当我开始阅读 TensorFlow 和图像分类时,我个人变得很感兴趣——这种想法是,如果我有一个精心策划的数据集,我可能能够训练一个架构来以高精度对图像进行分类。
Google Colab 那时还不存在,我最近把类似的东西移植到了 Colab 上,我正在进行一次演练。点击此处查看第 1 部分:
[## Google Colab 中 ResNet 的端到端改编—第 1 部分
只需点击几下鼠标,就能训练出一个深度神经网络
towardsdatascience.com](/end-to-end-adaptation-of-resnet-in-google-colab-part-1-5e56fce934a6)
我最初的尝试是在我的 iMac 上使用 Anaconda、Spyder 完成的,没有使用 GPU,只是让我的 Core i5 在数千张图像中跋涉,而我离开去做其他事情(阅读:为急救医学委员会学习)。当然,在我开始训练之前,我必须通读二十多篇使用不同风格编写代码的人的文章。结果是**,一个代码**的嵌合大杂烩,当我几周后看它的时候很难理解。
然后 Colab 进入了这个场景,虽然我仍然在我的机器上使用 Jupyter 和 Spyder,但我使用 Colab 与您交流并有效地共享我的代码。它并不完美,但他们在让大众获得高端计算方面做得很好,你所需要的只是一个谷歌账户。
闲话少说。让我们浏览一下笔记本:
Colab 笔记本
代表性图像
来源:Unsplash.com
两步面部识别
我在这里有点开玩笑——这两个步骤是“全部运行”和上传你的面部照片。
笔记本被设计成隐藏大部分代码,这样你就可以清楚地看到结果。首先看看输出,让自己相信我们不仅可以挑出(希望是大多数)照片中的人脸,然后使用情绪检测器功能分配一种情绪。
我还留了一些代码来尝试计算过程的时间。
面部识别库
这个使用了“人脸识别”库,在这里找到的。我们也会计算这需要多长时间。
这条生产线承担了所有繁重的工作:
face_locations = face_recognition.face_locations(image)
代码的其余部分使用 for 循环遍历面数,并使用以下两条线在面周围画一个框:
rect = patches.Rectangle((left,top), (right - left),
(bottom-top),linewidth=3,edgecolor='r',facecolor='none')
ax.add_patch(rect)
作者图片
注意:并不是所有的人脸都被检测到;帽子和太阳镜会干扰检测。
检测到的人脸数量:24
耗时:2.43 秒
加入情感检测
除了一行(如果在第 11 行阻塞)之外,代码几乎与上面的相同:
正如我们将在下图中看到的那样,出现“if”语句是有原因的。“检测情绪”这条线并不适用于所有的脸。
结果如下:
作者图片
注:情绪检测大多管用。并不是所有的脸都会表现出一种情绪,它认为婴儿生气了。我会让你仔细看看,看你是否觉得标签完全匹配——我不认为它们完全匹配。
检测到的人脸数量:24 个
耗时:2.83 秒(稍长以添加情绪检测)
使用开放式 CV 的哈尔叶栅
基于 Haar 级联的识别是进行面部识别的另一种方式。关于这些工作的讨论超出了本文的范围。网上有很多讨论这种方法的技术资源。
结果如下:
作者图片
再次,使用哈尔级联是另一种方法,这里也有一些失误。特别是,它错过了一些脸,并认为裤腿,脚踝,鞋面的组合是一张脸。
然而,在我运行的每次迭代中,使用 Haar cascades 和 OpenCV 比使用 face_recognition 库要快得多——有时几乎快 20%—30%。这种速度优势非常显著,尤其是在浏览数百张图像(例如视频)时。它还涉及一种计算成本较低的过程,并且可能运行在需要较少功率的较便宜的硬件上。
当然,这不是仅有的两种面部检测方法,专有的方法可能更好。如果你必须在两者之间选择,我不认为有明确的答案——一个更擅长检测(人脸识别),但另一个更快(哈尔瀑布)。
检测到的人脸数量:24 个
耗时:1.95 秒(更快)
参考
[1] 维基百科-杰瑞米·霍华德,2020 年 10 月访问
[2] 面部识别库,PyPi,2020 年 10 月访问
[3] 打开 CV 哈尔叶栅,2020 年 10 月进入
有两种方法可以检验你是否完全不擅长编程
编程;编排
因为你可能不知道。
由 siscadraws 创作的艺术
学习编码很难。
我浏览了无数的 YouTube 视频、在线课程和个人项目。然而不知何故,我觉得我没有比开始时更进一步。
当我继续阅读关于编程、数据科学和云计算的文章时,很难不对其他人正在做的酷事情感到不知所措和害怕。甚至看着 Python subreddit 都让我想知道,才学了几个月的人怎么能构建如此复杂的项目。
我在哈佛开设了CS50 课程,我强烈推荐给任何想了解计算机科学的人。每次讲座结束后,你的任务是根据那周的主题编写代码来解决一个作业。我最近完成了“算法”的第三周,并完成了第二个作业。
我花了将近六个小时。
当我的代码最终通过所有测试时,我更多的是松了一口气,而不是欣喜若狂。盯着一个看似简单的问题,却不知道如何修复一个又一个 bug所以龙让我质疑自己是否有任何解决问题的技巧可言。我也很好奇别人用了多久才解决。当然,大多数人(从哈佛的学生到数千名注册在线课程的学生)不需要在一项作业上花半天时间。
谢天谢地,在我陷入自我怀疑的黑洞(轻度夸张)之前,两件事让我回到了正轨。他们帮助我认识到,虽然总是想学更多东西很好,但相信自己的能力也很重要。你可能会比你想象的走得更远。
让我们深入了解一下你应该做的两件事,看看你是否不擅长编程!
1.为某人建造某物
我最近看了几个月前为工作写的一些代码,心想“哇,这太糟糕了。”我摇摇头,开始整理我创建的混乱的函数和变量,一直在想为什么我没有给它添加更多的注释。
当我打字的时候,我的女朋友看到我在自言自语,问我怎么了。当我告诉她我的代码很烂时,她问:“有用吗?”
“是的,它能工作,但是它太乱了,我几乎不记得我当初是怎么写的了。”我说。
"嗯,你现在已经差不多修好了,所以这意味着你确实记得。"她回答道。
然后她又问:
“管用吗?”
这是一个简单的问题,是的,但它可以揭示这么多。首先,我将在本节的剩余部分开始说,是的,你构建的东西构建得好(可伸缩性、可读性、避免深度嵌套、DRY 等)是很重要的。).我并不是说,如果你写的垃圾在技术上实现了它的预期功能,你应该感到高兴。
然而,如果你所构建的服务于它的目的,并且在你需要解释它是如何工作的时候没有完全混淆,你应该感到自豪!
这让我想到了如何通过为某人构建东西来测试自己的编程技能。看着自己写的代码帮助别人,你会有一种难以置信的满足感。
我女朋友最近需要翻译 PDF 文件中的文本。然而,她正在处理的 pdf 是扫描图像。她实际上不能复制任何文本,所以她不得不在谷歌翻译中手动输入段落。此外,由于她只需要翻译 PDF 的几个段落,使用在线服务来翻译整个文档(甚至一页)不会有很大帮助。
我看到她在做什么,心想“嗯,我也许能帮上忙”。
然后我为她写了一个非常简单的 CLI 应用程序,它将一个图像作为参数,用 T0 从图像中获取所有文本,然后将文本复制到剪贴板。
在谷歌翻译中输入段落并不是一件非常耗时的任务。也就是说,即使我每天只减少了她 30 分钟的工作时间,那也是她额外得到的 30 分钟!
奇怪的是,找到一个解决方案并建立它来帮助她,帮助我意识到我到目前为止学到的东西并不局限于我的头脑。我可以用它来改善其他人的生活。
你也可以!环顾你身边的人,无论是你的家人还是同事,我相信你能找到一些你能帮助他们自动化的东西。能够想到并开发出一个解决方案,即使是一个微不足道的问题,就是编程。
2.教某人某事
这是你以前可能见过的建议。教别人你刚学到的概念是你记忆信息的好方法。这是因为不首先理解主题就不可能教学。如果你试图在没有掌握的情况下教某人一个新概念,你可能能够背诵一个基本的总结,但你将无法回答他们的任何后续问题。
不久前,我第一次在 Python 中学习了列表理解,此后我在各种场景中使用了它们。然而,当我帮助我的女朋友完成她的一个剧本时,我才真正知道我理解了他们。
她在寻找一种方法,根据文件名中与文件夹名称匹配的部分,自动将文件移动到不同的文件夹中。她首先想根据文件名创建所有的文件夹。例如,目录中有一个名为12345_file.pdf
的文件,这意味着她需要创建一个名为12345
的文件夹。
为此,她想实现一个 for 循环来获取所有文件名的第一个数字,并将它们放在一个列表中,然后遍历该列表来创建所有文件夹。然而,在某些情况下,一些第一个数字是重复的。可能还有另一个名为12345_newfile.pdf
、12345_oldfile.pdf
的文件,以此类推。这将导致一个包含重复值的列表,这是行不通的。
为了同时避免使用 for 循环创建列表和删除列表中的所有重复项,我为她写了以下代码:
folder_name_list = set([i[:5] for i in original_filepath_list])
我们已经有了一个文件路径列表,所以我向她解释说,您可以使用列表理解来创建一个列表。您可以使用 list comprehension 来定义列表的组件和任何条件,而不是创建一个空列表,循环遍历并向其追加新元素。在本例中,我将采用现有文件路径列表中每个元素的前 5 个字符。然后,为了从列表中删除所有重复的值,我将列表转换成一个集合,因为 Python 中的集合不能有重复的值。
经历这个过程感觉很棒,因为:
- 从列表中删除重复项是一项非常常见的任务,所以能够解释如何快速完成这项任务,并且不需要查找任何资料,这意味着我已经做了足够多的练习。
- 能够解释一个(相对)更高级的操作,比如列表理解,意味着我所做的不仅仅是连接字符串之类的东西。
- 我又要去帮助别人了!我看到有人学到了新的东西,并在自己的代码中实现了它,这意味着我的学习对别人的生活产生了积极的切实影响。
Sidenote: I know there are many other ways to accomplish the above process- she ended up using shutil to move everything into folders by checking if each file keyword was present in the list of folder names. If you've got another solution you'd like to share, please do. I'll send them to her and you can say you helped some random person on the internet with your code.
我并不是说,如果你能构建一些东西并教给别人一些东西,你就是一个了不起的程序员。事实上,有时通过建设和教学,我意识到(再一次)我还有很多东西要学。我可能永远也学不完新的东西,但通过帮助别人,我知道一件事是肯定的:如果别人从我为他们做的事情中受益,我不会完全失败!
如果你发现自己陷入了困境,读一读这份来自一位非常明智的朋友的鼓舞人心的摘录:
一些编程(和生活)建议
“…[编程]就像数学侠。你可以用一生的时间来学习数学,而且你总能学到更多……每个人都对它有一定的亲和力,但不管怎样,它主要是实践……学习永远不会太晚。”
仅此而已!
我希望我已经说清楚了,你很可能并不完全不擅长编程。你可能不是一个神童,一个专家,或者仅仅是有能力,但是坚持练习和帮助别人,你会走得很好。
编码快乐!
**More stuff by me**:
- [Using One Line of Code to Write to a Relational Database](/using-just-one-line-of-code-to-write-to-a-relational-database-3ed08a643c5f?source=friends_link&sk=1d54a968dc2fda2fc190af8bfdec5287)
- [An Introduction to the Cohort Analysis With Tableau](https://medium.com/swlh/how-to-group-your-users-and-get-actionable-insights-with-a-cohort-analysis-b2b281f82f33?source=friends_link&sk=8b672c3feb79e194804f2a1c33660e19)
- [How to Quickly Create and Unpack Lists with Pandas](/how-to-quickly-create-and-unpack-lists-with-pandas-d0e78e487c75?source=friends_link&sk=32ea67b35fe90382dc719c1c78c5900c)
- [Rename Screenshots on Mac with 21 Lines of Python](/how-to-rename-screenshots-on-mac-with-21-lines-of-python-c3c2366f6eec?source=friends_link&sk=ee7e2c04f068855b5b7dfffa7e54152b)
SQL 中的类型转换
软件开发
如何转换 SQL 中的数据类型及其对数据库&查询性能的影响
从一种类型转换到另一种类型在 SQL 查询中非常常见。这种使用基本上源于糟糕的数据库设计、不断变化的需求、遗留的应用程序和懒惰的数据库维护。不是有意的,但是这些事情确保了数据消费者的需求永远不会被直接满足。消费者必须想出变通的解决方案来获取他们的数据。类型转换是主要的工具之一,尽管很少被提及。
我们将使用下面的样本数据集来浏览在查询中进行转换的不同示例。
资料组
对于本文的范围,假设当我们谈论造型时,它包括所有 SQL 风格中所有与造型相关的函数,如 Oracle 中的to_date
、MySQL 中的cast(something as int)
等等。然而,这些例子是基于 MariaDB (MySQL)的。
隐式铸造
下例中的所有查询都会给出完全相同的输出——这意味着数据库引擎隐式地理解了我们给它的where
子句输入。它根据自己的要求在where
子句中把'1'
内部转换为1
,反之亦然。以下示例中的所有四个查询将产生相同的输出。
这同样适用于从字符串到浮点数的转换,反之亦然。但是,并非所有数据库都在相同程度上支持隐式类型转换。对于本文的范围,我使用了 MariaDB。
当数据库能够隐式转换值时,我们可以假设它会对性能产生影响。隐式转换不是没有成本的,因为根据定义,它会为查询引擎增加更多的工作。事实上,隐式转换最终会比显式转换花费更多的成本,因为在显式转换中,您可以控制成本,而在隐式转换中,数据库处于控制之中,它决定采取什么行动,这反过来又会产生成本。
显式造型
这是人类指定铸造什么和铸造成什么的地方。因为字符串-整数、字符串-浮点转换由数据库引擎本身负责,所以当我们讨论日期时,转换的下一个最重要的用例就出现了。日期是数据库系统中最不同的存储信息。这里有很多变体,其中两个主要的是——时区和日期格式。大多数时候,日期不是以日期或时间戳的形式存储的,而是以字符串的形式存储的。这就是一切变得太有趣的地方。😃
下面的示例显示了数据库引擎为将字符串转换为日期提供的许多选项。
仔细查看数据库,当涉及到用字符串存储日期时,它是非常可靠和容易理解的。它可以解释几乎所有的日期格式,只有一个例外——2019 12 12
——这是一个明显的数据库不能识别空间的例子。我猜也没人会这样写日期。但你无论如何也不能这么肯定。如果你的日期是这种格式,你可以做一个replace(_date,' ','')
并把它转换成日期。
注意,数据库已经返回了结果集,但是有 26 个警告。让我们看看它们是什么。
警告不是错误。这里的警告是一个通知,表明数据库怀疑可能有问题。当您试图将一个副本insert ignore
到一个表中时,也会发生类似的情况。如果你insert
,它不会抛出警告,它会抛出错误。对于警告,数据库会假设您会在需要时查看这些警告。如果出现错误,除非您修复它们,否则无法继续。
就像我们从字符串转换日期一样,许多其他的转换也是可能的,但是要小心。
对性能的影响
如前所述,添加到查询引擎的任何工作都会对性能产生一些影响。对于合理大小的数据集,隐式和显式转换(类型转换)可能而不是本身会大大降低查询速度。但是,您的查询很慢完全有可能是因为类型转换引起的其他问题。
类型转换(强制转换)会使查询的一个或多个索引变得无用。您可以使用explain
或explain extended
来检查查询计划中是否使用了索引。如果索引没有被使用,我们可以在where
子句或join
子句中显式类型转换列,等等。
让我们看看这是如何影响索引的。
运行下面的两个查询告诉我们,当我们在where
子句中传递一个要与整数字段进行比较的字符串时,它会选择索引idx_val_int
,但是在下一个查询中,当我们在where
子句中传递一个要与字符串字段进行比较的整数时,它不会使用索引。它在可能的关键字中显示了索引的名称。
还有关于为什么没有选择索引的附加信息。
连强行索引idx_val_int_char
都不管用
唯一的解决方法是以字符串的形式提供值,即'1'
而不是1
或cast(1 as char)
,1
是应用程序的输入,因此是可参数化的。
结论
每个数据库都有许多将一种数据类型转换成另一种数据类型的选项,这些选项可以解决我们日常面临的大多数用例。尽管类型转换是一个很好的特性,但它确实伴随着性能成本,无论是隐式转换还是显式转换。
虽然并不总是可行,但是避免这一切的一个很好的方法是以这样一种方式设计和维护数据库和查询,即需要最少的类型转换。如果这不可能,请确保您的查询使用了正确的索引,这样性能就不会受到更大的影响。还有更多关于字符集和排序的内容。我们将在另一个时间谈论那件事。
第一类和第二类错误
当统计测试结果与现实不符时
当执行统计测试时,目标是查看在给定数据的情况下,某个陈述是否明显不太可能。用更简单的语言来说,你试图确定你认为一个陈述是真的还是假的。这种说法被称为零假设 (H₀),相反的说法被称为替代假设 (H₁).在某种程度上,零假设是默认的陈述,因为它可能是真的,测试的工作就是挑战这一点。很像在法庭上,你是“无罪的,直到被证明有罪”,不幸的是,有时无辜的人被判有罪,而有罪的人却被释放,因为他们实际上犯了罪。这两个错误分别对应于统计测试中已知的第一类和第二类错误。
在高中,我的 AP 统计老师教我们记住,在第二类错误中,你会拒绝失败。
第一类错误
当你拒绝零假设时,第一类错误就发生了。在前面提到的法庭例子中,第一类错误是给一个无辜的人定罪——无罪的零假设被拒绝,当它不应该被拒绝的时候。第一类错误也可以被认为是假阳性,因为你错误地声称是手头变量之间的统计显著差异,而实际上不是。
第二类错误
相反,当没有拒绝零假设,而应该拒绝零假设时,就会发生第二类错误。在高中,我的 AP 统计老师教我们记住,在第二类错误中,你会拒绝失败。在我们一直在处理的例子中,第二类错误将是未能给那些是 有罪的人定罪,因此应该被定罪。第二类错误也可以被认为是假阴性,因为你错误地声称不是手头的变量之间的统计显著差异,而实际上是。
维基百科:第一类和第二类错误
第一类和第二类误差彼此成反比,因为减少一种误差会增加另一种误差。在不同的情况下,一种类型的错误可能更有害,因此最小化更重要。例如,在法庭上,让一个有罪的人走,比把一个无辜的人送进监狱要好。因此,在这种情况下,I 型错误会更糟。然而,在医疗情况下,对于你没有的东西,最好有一个阳性的检测结果,而不是对于你有的东西,有一个阴性的检测结果。通过对你实际上患有的疾病的测试呈阴性,你的生命可能由于缺乏治疗而处于危险之中。因此,在这种情况下,第二类错误会更糟。虽然完全消除这些错误的可能性对于非确定性方程来说是不可能的,但是最小化它们是统计学和数据科学的一个大目标。
参考资料:
在统计假设检验中,第一类错误是拒绝一个真的零假设(也称为“假…
en.wikipedia.org](https://en.wikipedia.org/wiki/Type_I_and_type_II_errors)
作为数据科学家,您需要了解的数据类型
数据科学
了解数据科学和数据类型(结构化、非结构化……)
背景由hello queue上的 Unsplash
目录
- 什么是数据科学?
- 数据科学是一个新领域吗?
- 数据类型
- 数据格式/来源
- 总结与结论
什么是数据科学?
数据科学是对大量数据的研究。就像生物科学是对生物学的研究一样,物理科学是对物理反应的研究。这是使用数据来理解不同事物,理解世界的过程。
数据科学是关于从各种形式中提取数据的方式的领域,无论是非结构化还是结构化形式。这是一个多学科领域,汇集了来自计算机科学、数学/统计学和数据分析的概念。
数据科学的核心是总是问问题。数据科学家总是需要对这个世界保持好奇。
- 我们能从这些数据中学到什么?
- 一旦我们找到了我们要找的东西,我们可以采取什么行动?
“在未来 10 年,数据科学和软件对医学的贡献将超过所有生物科学的总和”。维诺德·科斯拉
数据科学是一个新领域吗?
早在第二次世界大战后的几年里,因肺癌死亡的人数有所上升,科学家和医生没有就具体原因达成一致,没有人认为香烟可能是原因的假设,因为那时每个人都吸烟。在英国,所有医生的数据和细节都写在一个中央登记簿上(包括:吸烟者?;活着/死亡?,如果他死了,死亡的原因是什么?)所以无意中,我们有了他们可以操纵的庞大数据,来预测和理解这种现象。于是布拉德福德·希尔和理查德·多尔开始操纵这些数据,提取死于肺癌的医生,看看他们是不是烟民。结果很明显,在过去的 29 个月里,死于肺癌的人 100%都是吸烟者。因此数据科学并不新鲜,新鲜的是从各种来源获得的大量数据。
在数据科学领域有很多职业道路;大多数,但不是全部,涉及一点数学,一点科学,以及对数据的好奇心。
数据类型
大数据:大数据没有精确或通用的定义…海量数据集,或包含更多种类的数据,以不断增加的量和更高的速度(3V 法则)到达。
图片来源:作者
- 数据量:巨大的数据量,TB—Pb。
- 数据速度:数据流动、数据变化、数据处理的高速。
- 数据种类:各种数据源(社交媒体、移动、结构化数据、非结构化数据……)。
“世界是一个大数据问题”。安德鲁·迈克菲
结构化数据:具有预定义结构的数据,这些数据已经以有序的方式存储在关系数据库或电子表格中(传统的行列数据库)。结构化数据有两个来源:
- 机器生成的:从传感器、网络日志和金融系统接收的所有数据,包括医疗设备、GPS 数据、服务器捕获的使用统计数据。
- 人为生成的:主要包括人类输入计算机的所有数据,如姓名和其他个人信息、访问的网站、观看的电影类型(公司可以利用这些数据来了解其客户行为并做出适当的商业决策,例如网飞、Youtube 或 Medium 的推荐系统)…
**非结构化数据:**没有预定义结构的数据,以任何大小或形式出现(它们在存储中没有明确的格式),不容易存储在表中。它还根据其来源进行分类:
- **机器生成:**说明了所有的卫星图像、安全摄像头、雷达数据捕捉以及其他更多信息。
- **人为生成:**在互联网上大量存在,因为它包括社交媒体数据、移动数据、电子邮件和网站内容。这意味着我们上传到脸书或 Instagram 的图片,我们在 Youtube 上观看的视频,甚至我们发送的短信。
**半结构化数据:**非结构化数据和半结构化数据之间的界限一直不清楚,因为大多数半结构化数据一眼看上去都是非结构化的。不像结构化数据那样采用传统数据库格式,但包含一些易于处理的组织属性的信息。例如,NoSQL 文档被认为是半结构化的,因为它们包含可用于轻松处理文档的关键字。
其他数据类型
定量数据:数值。比如:身高,体重,工资,物价…
**分类数据:**可以标记或分组的数据。比如:性别、发色、种族、水果、动物…
数据格式/来源
最常见的数据格式:
- **CSV -逗号分隔值:**顾名思义,是一个使用逗号分隔值的分隔文本文件。
- XML -可扩展标记语言
- SQL 结构化查询语言
- JSON - JavaScript 对象符号
- 协议缓冲区
数据来源:公司、API、政府、学术、网络抓取/抓取…
摘要
- 数据科学是对大量数据的研究,可以揭示帮助组织做出战略选择的洞察力。
- 数据科学并不新鲜,新鲜的是来自各种来源的大量数据:博客、社交媒体、销售数据、GPS 数据、服务器捕获的使用统计数据、电子邮件、患者信息文件、运动表现数据、传感器数据、安全摄像头等等。
- 术语“大数据”描述了海量数据的集合,无论是结构化、半结构化还是非结构化的数据,都可以被处理和利用,以获得可理解的相关信息。我们用 3V 法则总结大数据的问题:量、速度、多样性。
结论
除了解决今天的问题,数据科学家也是未来项目的核心。你肯定听说过自动驾驶汽车。事实上,通过更好地利用数据,我们能够建造更强大、更智能的机器人。而这是数据科学家的责任。
资源:
- https://www . goodreads . com/book/show/7170627-万病之王
- https://www.goodreads.com/book/show/705365.现代医学的兴衰
- https://www . the guardian . com/news/2005/jun/02/thisweekssciencequestions . cancer
- https://en.wikipedia.org/wiki/Comma-separated_values
- https://www . edvancer . in/50-amazing-big-data-and-data-science-quotes-to-inspire-you/
感谢阅读!😄
查看我的其他文章,关注我的 中型
机器学习中集成方法的类型
弗拉德·希利塔努在 Unsplash 上拍摄的照片
在我之前的文章中,我们讨论了机器学习中不同类型的回归。因此,今天我将重点讨论数据科学中的各种集成方法。
我在职业生涯中经历的一件事是,在学习任何技能时,当我们试图将概念与我们日常生活中面临的事件联系起来时,事情会变得更容易。当我们有一个真实的生活类比时,记住事情是毫不费力的。因此,记住这一点,我们将通过与日常场景的比较来研究各种集合技术。
目录
1.介绍
2.集合方法的类型
3.装袋和增压方法之间的相似性
4.两种方法之间的差异
5.投票的类型
6.对概念的详细理解
- 制袋材料
- 助推
7.结论
1。简介
什么是合奏?
在简单的英语中,ensemble 指的是一组项目。例如:一群牧师、一群舞蹈演员等。
什么是机器学习中的集成方法?
集成方法是一种使用多个独立的相似或不同的模型/弱学习器来获得输出或做出一些预测的技术。
例如
随机森林是多个决策树的集合。
集合也可以通过不同模型的组合来构建,如随机森林、SVM、逻辑回归等。
现在,让我们用一个真实的例子来比较一下。
假设议会通过了一项法案,并召开了部长会议。
而不是总统或总理独自做出决定可能不是一个很好的主意,因为这说明了独裁统治,结果可能不是那么有利于公众。因此,这种类比可以指机器学习中的单一模型,如决策树、逻辑回归等,它们的性能总是略低于集成方法。
然而,如果在不同的部长之间举行会议,比如说四个部长,他们每个人都会提供一个有正反两面的意见。最后,最佳意见将在多数投票的基础上选出。这正是系综方法。
部长 1 :基于他的赞成和反对意见,认为该法案应该通过。
部长 2 :基于他的支持和反对,他说这个法案没有用,可能会引发很多挑战。因此不应通过。
部长 3: 表示议案可以通过。
部长 4: 也表示议案可以通过。
大多数人说“通过议案”。因此,该法案在议会获得通过。
类似地,我们可以在下面看到使用了不同的模型,并且基于每个模型的输出,最终的决定将通过多数投票做出。
来源:谷歌
为什么我们需要合奏技巧?
众所周知,任何机器学习模型中的错误和预测都会受到偏差、方差和噪声的不利影响。为了克服这些缺点,使用了集合方法。
2。集成方法的类型
有许多可用的集成技术,但我们将讨论以下两种最广泛使用的方法:
1。装袋
2。增压
让我们首先了解这两个术语之间的异同。
3。装袋和增压方法的相似性
这两种方法都可以用于分类(离散输出)和回归(连续输出)问题。
与单一模型相比,这两种方法在性能上都更好,因为它们通过投票聚集了所有弱学习者的输出,从而导致预测更准确。
**4。两种方法的区别
装袋和增压的区别
**5。投票类型
有两种类型的投票用于汇总所有弱学习者的输出。
硬投票 —如果我们收到每个弱学习者在类中的输出(例如:0/1),最后我们选择多数返回的输出类,那么这种方法称为硬投票。
例如:在我们的部长小组的例子中,由于 3 名部长赞成该法案,最终决定通过该法案。这是艰难的投票。多数获胜。
软投票 —有许多算法也为我们提供预测概率,如果我们收到概率输出,我们会取每个类别概率的平均值,平均值最高的类别将成为最终预测。这种预测方式被称为软投票,它比硬投票更好,因为我们在概率方面获得了更多的信息。
另一件要记住的重要事情是,这种投票方法被用作随机森林等群体的默认技术。
让我们使用下图来理解这两个概念,其中 1 是类 1,0 是类 0。
因为类 1 的平均概率在软投票中更高(63%),所以我们选择类 1 作为最终输出
6。概念的详细理解
装袋:
也称为 Bootstrap aggregating,因为训练集被分成多个子样本,并被提供给每个弱学习器(例如:每个决策树)。并且每个子样本包含几组特征以及随机选择的几个观察值。
既然这篇文章的主旨是用通俗的语言来理解概念,那么让我们举一个简单的例子来理解装袋。
我们都参加面试,面试过程是我能遇到的最简单的场景,类似于装袋。
假设你去参加一个面试,一进房间,你就看到五个表情严肃的人坐在那里,向你提出所有的问题。你是做什么的?感到紧张,冲出房间!!没有对吗?你去那里是因为你需要这份工作,你知道你足够勇敢,足够聪明,可以面对任何事情,无论如何你都会和他们打招呼,坐在他们面前。所以,让我们面对现实吧。
现在考虑一下,五位面试官中的每一位都将从五个不同的方面对应聘者进行面试,比如能力、基本技能、高级技能、沟通和管理技能。
此外,公司可能已经准备了一套基于不同方面的问题来测试候选人的技能。我们称之为“问题集”。
那么,采访现在开始。我们的目标变量是候选人是否被选中。
面试官 1 — 面试官 1 开始测试你的能力倾向技能从“问题集”中抽取一个基于能力倾向的问题样本,并设定你是否应该被选中的概率。
面试官 2 — **面试官 2 也开始测试你的基本技能,**再次从“问题集”中抽取初步技术问题的样本,并设定你是否应该被选中的概率。
面试官 3—同样,面试官 3 开始测试你的高级技能从“问题集”中抽取另一个稍微困难的技术问题样本,并再次设定你是否应该被选中的概率。
现在,他也有可能问你一些从“问题集”中随机挑选的问题,但这些问题是相似的,并且已经在基本技术测试或任何先前的测试中被问过。这种情况在 bagging 方法中被称为 bootstrap,因为由于使用替换随机抽样,可能会再次选取相同的样本。
面试者 4 &面试者 5: 面试者 4 和面试者 5 重复上述相同的过程,从“问题集”中抽取相关问题的样本,测试候选人的沟通和管理技能,并相应地设定一些选择或不选择的概率。
**结果:**最后,候选人面试结束,他走出房间,让面试官根据“问题集”中对他进行评分的问题的子样本来分析他们各自对他技能的评分。最终,他们汇总所有个人意见,做出是否选择该候选人的最终决定。
这与合奏的方法完全相似。
让我们使用 python 尝试几种集成方法,并比较它们对应于几种单一模型的准确性。
注:jupyter 笔记本完整代码在 github 中。
为此,我使用 Kaggle 的广告成功数据集,并希望预测广告的成功。
1. 单款
a .决策树
*# Decision tree classifier with grid seacrh CV and model evaluation using accuracy score, precision score and AUC/ROC curve.*
**from** **sklearn.tree** **import** DecisionTreeClassifier
**from** **sklearn.model_selection** **import** GridSearchCV
parameters = {'max_features': [0.5,0.6,0.7,0.8,0.9,1.0], 'max_depth': [2,3,4,5,6,7],'min_samples_leaf':[1,10,100],'random_state':[14]}
clf = GridSearchCV(DecisionTreeClassifier(), parameters, cv=5, scoring='roc_auc')
clf.fit(X_train, y_train)
应用于示例数据的决策树评估指标:
AUC 评分为 85.84%。
决策树的精确度和准确性
决策树总是容易出现 过拟合 如果我们没有选择正确的参数,如树叶的最小样本、节点的最小样本、树的最大深度,那么随着深度的增加,模型将更精确地捕捉训练集的数据点,从而在训练数据集本身中产生出色的预测,但在新数据上却失败了。因此,集成方法是有助于减少方差从而解决单个决策树遇到的 过拟合 的技术之一。
b .单一逻辑回归分类器
*#Single Logistic Regression*
**from** **sklearn.linear_model** **import** LogisticRegression
log = LogisticRegression(random_state=0, solver='lbfgs')
log.fit(X_train, y_train)
y_pred = log.predict(X_test)
单个 Logistic 回归分类器应用于实例数据的评价指标:
AUC 评分为 83.84 %。
单一逻辑回归分类器的精度和准确度
2.相同分类器的集成
几个例子是随机森林、额外树分类器/回归器、线性回归器集成、逻辑回归分类器集成、SVM 集成等。
a. 随机森林——多个决策树的集合
来源:谷歌
**from** **sklearn.ensemble** **import** RandomForestClassifier
parameters = {'n_estimators':[700],'n_jobs':[-1], 'max_features': [0.5,0.7,0.9], 'max_depth': [3,5,7],'min_samples_leaf':[1,10],'random_state':[14]}
clf1 = GridSearchCV(RandomForestClassifier(), parameters, cv=5, scoring='roc_auc')
clf1.fit(X_train, y_train)
随机森林评价指标应用于实例数据:
AUC 得分为 86.53 %。
随机森林的精度和准确度
b.逻辑回归分类器集成。
当我们使用相同分类器的集合时,Sklearn 的 BaggingClassifier 用于获得 OOB(袋外)分数,这是在 bagging 中检查分类器性能的一个非常重要的分数,因为它给我们提供了在测试集上要达到的准确度的概念。众所周知,在训练期间,子样本被馈送到每个独立的分类器,但是在 bagging 技术中,同样的样本也可能被传递两到三次到任何其他单独的分类器。因此,在这种情况下,对于特定分类器来说是新的样本,即还没有看到的样本被称为袋外样本。它与测试集的目的相同,因为 OOB 实例是以前没有见过的东西**。在使用 Bagging 分类器构建集成之后,我们可以使用‘Classifier . OOB _ score _’函数**来获得 OOB 分数。
*# Multiple logistic regression classifiers using bagging Classifier.
# Number of logistic regression classifiers we are using here are 400.*logbagClf = BaggingClassifier(LogisticRegression(random_state=0, solver='lbfgs'), n_estimators = 400, oob_score = **True**, random_state = 90)
logbagClf.fit(X_train, y_train)
bagging 分类器(多重逻辑回归分类器)的评价指标:
AUC 评分为 84.44 %。
bagging 分类器(多重逻辑回归分类器)的精度和准确度
3。几种不同类型模型的集合
对于这个技术,我们可以使用 Sklearn 的 VotingClassifier 。
不同机器学习模型的集成
为了我的测试目的,我使用了 RandomForestClassifier、支持向量机和逻辑回归的集成。
**from** **sklearn.ensemble** **import** RandomForestClassifier, VotingClassifier
**from** **sklearn.svm** **import** SVC
**from** **sklearn.linear_model** **import** LogisticRegression
**from** **sklearn.naive_bayes** **import** GaussianNB
rfClf = RandomForestClassifier(n_estimators=500, random_state=0) *# 500 trees.*
svmClf = SVC(probability=**True**, random_state=0) *# probability calculation*
logClf = LogisticRegression(random_state=0)
*#nbclf = GaussianNB(random_state=0)*
*# constructing the ensemble classifier by mentioning the individual classifiers.*
clf2 = VotingClassifier(estimators = [('rf',rfClf), ('svm',svmClf), ('log', logClf)], voting='soft')
*# train the ensemble classifier*
clf2.fit(X_train, y_train)
投票分类器(多模型集成)的评价指标:
AUC 得分为 84.92 %
投票分类器的精度和准确度(多个模型的集成)
增压:
boosting 背后的主要思想是在连续迭代中将弱学习者转化为强学习者。
让我们再次以面试为例来理解助推的概念。
假设一个应聘者在五家不同的公司参加了五次面试。根据他在这五次面试中的表现,他想对自己的技能进行评估。
面试 1 —公司 1 —他只能回答几个问题,但他知道可能会再次被问到什么类型的问题。他回家学习。他的学习速度提高了。
面试 2 —公司 2 —在这里,他比第一家公司做得更好,因为他学会了他在第一次面试中错过的所有概念,但仍然没有被选中。他回到家,进行了更多的学习,从而纠正了他在前两次面试中犯的所有错误。
**面试 3 和面试 4 同样,**他面临着同样的问题,当他参加第 5 次面试时,他成了专家,几乎能回答所有的问题。
最终,我们在这里看到的是候选人接触到不同的问题样本,他逐渐学习和提高自己,直到成为专家。结果是,在从错误中吸取教训并改正自己之后,他可以给自己一个最好的评价。每一步都有一个学习率。同样是助推的概念。
我将在数据集上实现 boosting 算法 XGBoost。
**import** **xgboost** **as** **xgb**
xgb_clf = xgb.XGBClassifier(max_depth=3,n_estimators=300,learning_rate=0.05)
xgb_clf.fit(X_train,y_train)
XGBoost 的评估指标应用于示例数据:
AUC 得分为 86.46 %。
XGBoost 算法的精度和准确度
7。结论
让我们比较一下单一模型和集合模型的准确度、精度和 AUC 得分。
- 准确率: Boosting 算法‘XGBoost’在准确率上领先。
- 我们还可以注意到,集成分类器’随机森林’和’多重逻辑回归分类器’分别比单一分类器’决策树’和’逻辑回归’具有更好准确性。
各种算法的准确率评分。
2。精度分数: Boosting 算法’ XGboost '在精度分数上领先。
- 我们可以注意到,集成分类器’随机森林’和’多重逻辑回归分类器’分别比单一分类器’决策树’和’逻辑回归’具有更好精度。
各种算法的精度评分。
3。 AUC 得分: Bagging 算法Random forest 在 AUC 得分上领先,尽管与 XGboost 的 AUC 得分有非常微小的差异。
- 我们可以注意到,集成分类器’随机森林’和’多重逻辑回归分类器’分别比单一分类器’决策树’和’逻辑回归’具有更好 AUC 分数。
各种分类器的 AUC 分数。
因此,我们可以得出结论,boosting 方法在我们的数据集上表现最佳,我们最终可以部署 XGBoost 模型,因为它将最精确地预测广告活动的成功,这是我们问题陈述的主要议程。
然而,这取决于我们正在处理的数据的类型。
此外,我们可以推断,与单一模型相比,装袋和增压方法总是表现得更好,精确度更高。
请添加任何额外的想法,评论,因为这将有助于我更好地理解事情。
感谢阅读!!
机器学习的类型
探索如何根据人类互动和训练对 ML 算法进行分类。
作者图片
自从我在上写了第一篇关于什么是机器学习(ML)以及编程范式如何随着时间的推移而改变的文章并描述了一些用例/应用以来,已经有一段时间了。这一次,我将分享如何从不同的角度看待机器学习和人工智能,具体涵盖以下两个领域:
1.不同 ML 算法的训练过程中涉及到多少人为的交互。
2.培训是如何进行的。
在进入每个领域之前,让我们澄清一些关于机器学习过程的概念。如果你熟悉机器学习的工作原理,你可以跳过这一节。
机器学习的高层次定义可以被视为:
给定一些你正在分析的代表一个领域(销售、政治、教育)的 数据 和一个 算法 ,计算机能够 从这些数据中学习 并在其上检测某些 模式 的能力。其次是能够告诉( 预测 )你并确定新数据的类型或者至少是它的近似值。
对这个概念要有所保留,因为有太多关于 ML 实际上是如何执行的背景知识。
换句话说,计算机能够从输入数据中通过 训练 (学习)来检测 模式 。这个过程是高度迭代的,需要大量的调整。例如,它需要检查预测值与实际值有多远或多近,然后通过调整其参数来进行自我修正,直到达到某个点,在该点上模型肯定足够精确,可以使用。
好了,现在我们对这个过程有了一个大概的了解。让我们进入机器学习的类型。
ML 算法和人工干预。
这一领域的机器学习系统可以被视为训练过程中的 【监督】即人类互动 的数量。这些分为 3 个主要类别,我将尝试用例子来说明以下定义。
1。监督学习
假设你是当地一家书店的老板。
照片由作者拍摄
您的女儿 Ana 是一名数据科学家,她提出采用您库存系统中记录的图书数据集,并实施一个新系统来加快销售新书的登记。
安娜知道这些书的一些特点:
- 类型(小说、非小说、奇幻、惊悚)
- 精装书,如果有精装书
- ISBN,这本书的商业标识
- 标题,页数
- 书籍或封面图片的摘录
- 作者
现在,想象一下必须在书架中分配一本书。如果你在网上查找元数据,把书放在小说书架上,这就很容易了。
然而,在现实中,如果你每天收到多达 200 本书,你不能独自完成这项工作,在系统上手动输入数据很容易出错,你可能会把书放错书架。这种错位可能会导致收入减少,因为当新顾客进来时并不满意,因为他们找不到这本书,即使它实际上在商店里。
Ana 的新系统非常简单,只需给系统输入你要找的书的摘录或封面,它就能告诉你这本书应该放在哪个书架上。
这个特殊的例子被称为 分类 ,因为系统只是在帮助你根据你作为用户提供给它的某些特征来分类(组织)一些数据。
这种系统的一个真实例子是谷歌照片。
另一种监督算法是在给定一组称为预测器的特征或特性的情况下,预测一个数值。
现在,你可能会问这是怎么发生的?
一个例子就是使用 回归 。一种常见且广泛使用的算法称为线性回归,其目的是预测一个连续值作为结果。
这实际上转化为具有一组特征或变量,以及一组匹配该输入特征的标签,并且您想要算法做的只是学习如何" 拟合 " 与这些特征相关联的权重(参数),以给出更接近真实值的近似值。
2。无监督学习。
无监督 算法涵盖了我们没有标签或真实值可以对比的所有情况。相反,我们确实有数据集,模型将根据数据如何 分组 在一起,它如何检测模式,以及它是否显示某些行为来训练和预测。
这种类型的机器学习的一个典型例子是 聚类 ,根据相似性对数据进行分组。真实的例子包括推荐系统,例如:
- 零售商网站,如亚马逊和 Zalando。
- 媒体/流媒体系统,如网飞、Youtube 等。
在这种类型中使用了许多其他算法,例如,异常检测可能涵盖信用卡欺诈或帐户盗用情况,这些情况可以通过使用 ML 来预防和预测。
我最近发现的另一种我最喜欢的无监督学习算法是那些用于数据可视化的算法,如 t-SNE 或 t-分布式随机邻居嵌入。
我在几个宠物项目中使用 t-SNE 进行 情感分析可视化 ,你可以实际看到集群在高维空间中形成,同时使用降维。
3。强化学习。
很多书和网站都提到这些算法,比如 野兽 但是我喜欢想到冰淇淋的顶部。由于该领域正在取得的成就,目前成为一个热门话题,我稍后会提到这一点。
在这种情况下你会怎么做?最有可能的是,你会玩几次,试图研究什么是最好的动作和最好的路线,你可以使用,最终从庇护所救出狗。这类似于强化算法要做的事情,你可以这样想:
1.给你一个 环境 。(视频游戏环境中的空间),代表空间上某些变量的状态。就像路障或蟋蟀从天而降。
2.事件期间要执行的操作。(动作,像向上、向下、向建筑者扔球),值得注意的是,有些动作可能会被奖励为“好”,而其他一些则被奖励为“坏”,这意味着它会降低你实现目标的能力。
3.代理人(视频游戏中的角色,救援者,或建设者),他们将采取行动以尽可能低的成本实现目标。
它的工作方式是代理观察环境,试图执行行动,并根据这些行动将获得奖励或没有。潜在的情况是,代理将自己学习什么是追求的最佳方法/策略,以获得最大数量的积分(奖励)。
迄今为止,我见过的用它构建的最好的系统之一是:
- 捉迷藏,由 OpenAI 开发。在那里他们使用多智能体的方法教孩子们玩捉迷藏。有两个代理“隐藏者”和“搜索者”,通过观察环境,他们能够学习甚至没有提供的行为/行动,如使用障碍通过障碍。如果你想深入了解它是如何工作的,你可以看看下面的视频和 论文
来源:多智能体捉迷藏
- 视频游戏,如 StarCraf 或 AlphaStar。代理人与人类对弈,事实上它在几秒钟内就击败了世界上最好的玩家或其他代理人。为了实现这一目标,开发 AlphaStar 的团队不仅使用了强化学习,还使用了监督学习来训练神经网络,这些网络将创建玩游戏的指令。如果你好奇是怎么做到的,可以查看他们的博文 这里 。
到目前为止,我们已经学习了不同类型的机器学习系统,这些系统基于人类与这些系统的互动的应用程度。现在我们可以继续探索接下来的 2。
ML 算法和训练过程。
在前面的部分中,我们概述了训练过程是您的算法将如何“学习”最佳参数来进行预测。话虽如此,培训本身是一门艺术,可以根据用例、可用资源和数据本身以不同的方式进行。
这分为两种:
- 批量学习。
- 在线学习,也称为增量学习。
让我们看看这些是如何工作的:
1。批量学习
批量学习是指用一次获得的所有数据训练模型,而不是增量学习。通常执行这个动作需要很多时间。想象一下,如果不能一次训练更多的数据,也要训练数 TB 的数据。但是你为什么需要这么做呢?
例如,由于业务或用例的性质,以特定频率(如每周/每月)交付的报告或决策可能不需要实时培训。
这种类型的培训通常是离线完成的,因为它需要很长时间(几小时/几天/几周)才能完成。
培训是如何进行的?
- 模型被训练。
- 模型被部署并投入生产。
- 模型在没有进一步“学习”的情况下持续运行。
这个过程叫做离线学习。现在,您可能想知道,如果我的数据或用例发生了变化,会发生什么?您需要针对合并新数据或特征再次训练您的模型。
一个实际的例子,在我以前的工作中,一些模型以批量学习的方式部署到生产中,一些模型不需要如此频繁地刷新,所以它可以大约每周发生一次。生成新模型的另一个原因是查看监控系统中部署的指标,并检查模型的性能是否正在下降。
这些类型的模型与 IO、CPU、内存或网络等资源密切相关,因此在决定采用哪种方法之前,记住这一点非常重要。如今这可能真的很昂贵,但与此同时,你可以利用云平台提供的现成解决方案来做到这一点,例如 AWS Batch 、Azure Machine Learning——Batch Prediction,或谷歌云人工智能平台。
接下来,让我们谈谈在线学习
2。在线学习
你有没有想过网飞、迪士尼、亚马逊 Prime Video 是如何推荐你看什么的?或者为什么 Zalando 和亚马逊一直告诉你买这些惊人的裤子,可能会搭配一双白色的鞋子?你可能会说,是的,推荐系统,但更重要的是,它怎么能做得这么快?系统是如何快速适应变化的?
您可能又答对了,这是因为训练是动态进行的,这意味着数据在到达系统时就被处理。这种方法适用于持续接收数据的系统,如零售商,或者需要快速适应变化的系统,如新闻网站或股票市场。
就如何进行培训而言,如下所示:
- 数据被分成小块或小批。
- (连续地)训练模型。
- 持续评估/监测。
- 部署到生产。
进行在线学习的一个好处是,如果你没有足够的计算资源或存储,你可以在训练时丢弃数据。为您节省大量资源。另一方面,如果您需要重放数据,您可能希望将其存储一段时间。
正如我们处理的每一个系统一样,这种类型的培训有其优点和缺点。使用这种方法的一个缺点是,模型的性能可能会很快下降,或者最终由于数据可能会快速变化,您可能会注意到在某个时间点预测准确性的下降。出于这个原因,也是我很少看到的一个经常谈论的话题,就是建立良好的监控系统。这些将帮助您的团队或公司预防和理解何时开始改变或调整模型以使它们有效。
亮点
你已经走了这么远,我希望你喜欢它。最初,我们讨论了机器学习如何工作,然后深入研究了机器学习如何根据人类与算法交互的角度进行划分。最后,我试图用我在周围看到的很酷的例子和应用程序来尽可能多地描述这些类型的监督、非监督和强化学习。
我可能会开始张贴我在旅途中学到的更多实用的东西,并愿意分享。#分享伤疤。
保重,很快再见。
PySpark 3 中的采样类型
Spark 中采样技术的解释及其在 Pyspark 中的具体实现步骤
抽样 是为特定的案例研究从数据集中确定一个有代表性的亚组的过程。抽样代表重要的研究和商业决策结果。因此,在所提供的技术中使用最合适和最有用的取样方法是至关重要的。本文主要面向希望在采样子领域使用 Apache Spark 最新增强功能的数据科学家和数据工程师。
Spark 支持的采样方法有两种:sample和sample by详见后面的章节。
1.样本()
如果使用 sample() , 简单随机抽样 ,数据集中的每个元素都有相似的机会被优先选择。以随机指定的分数比率从数据集中选择变量,而不基于任何变量进行分组或聚类。
该方法使用 3 个参数。with replacement参数默认设置为False**,因此该元素只能被选作样本一次。如果该值被更改为 真 ,则可以再次在同一采样中选择一个样本值。由于可以多次选择元素,因此with replacement = True和with replacement = False的数量可能略有不同。**
另一个参数是 分数 字段,需要填写,在 Spark 的官方文档 中有说明,不能除以指定的百分比值。
如果任何数字被分配给 种子 字段,它可以被认为是分配一个特殊的 id 给那个采样。这样,每次运行脚本时都会选择相同的样本。如果该值保留为 无 ,则每次创建不同的采样组。
下面我用 Kaggle 数据集 添加一个我在本地 Jupyter 笔记本上编码的例子。
**在下面的例子中,with replacement值被设置为 **True ,的 分数 参数被设置为 0.5 , 种子 参数被设置为 1234 ,这是一个可以赋值的 id
图一。 sample()方法同*【with replacement = True】(图片由作者提供)***
在下面的例子中,with replacement值被设置为 False ,的分数被设置为 0.5 , 种子 参数被设置为 1234
图二。 sample()方法同【with replacement = False】*(图片由作者提供)*****
下面,有对 sample() 方法的详细解释。
样本(替换=无,分数=无,种子=无)
该方法返回一个 数据帧 的采样子集。
参数:
有替换的 —有替换或没有替换的样本(默认值设置为假)。**(可选)**
— withReplacement=True: 同一个元素在样本的最终结果集中有被重现多次的概率。
— withReplacement=False :数据的每一个特征只被采样一次。
分数 —要生成的行的分数,范围[0.0,1.0]。**(必选)**
种子 —抽样的种子(默认为随机种子)**(可选)**
注: 不保证准确提供给定 数据帧 的总计数的指定分数。
2.抽样依据()
另一种可以作为采样方法的技术是sample by()。******
第一个参数是 col 字段,它决定在采样过程中对哪个变量进行子分组和采样。
例如,如果位置写在该域中,将根据位置值进行采样。位置下的值将包含在采样中的百分比在 分数 字段中确定,这是另一个参数。不是强制填充,如果不是,则设置为 0,没有指定分数率的值将不包括在抽样中。********
****图三。位置特征在数据集中的分布(图片由作者提供)
****在下面的例子中,选择了数据集字段中具有 CA 的元素的 50% ,具有 TX、的元素的 30% ,以及具有 WI 的元素的最后 20% 。在本例中, 1234 id 被分配给 种子 字段,也就是说,每次运行脚本时都将选择用 1234 id 选择的样本。如果 种子 值保留为 无 ,则在执行过程中每次都会选择不同的样本。
****图 4。所有“位置”变量的值都在“分数”参数中指定(图片由作者提供)
下面再举一个例子,dataset 字段中带有 CA 的元素的 60% ,带有 TX 的元素的 20% 被选中,由于没有指定所有其他元素的百分比,所以它们没有包含在最终的采样结果集中。在本例中,再次将 1234 id 分配给 种子 字段,也就是说,每次运行脚本时都将选择用 1234 id 选择的样本。如果 种子 值保留为 无 ,则在执行过程中每次选择不同的样本。
****图 5。在“分数”中只指定了“位置”变量的两个值(图片由作者提供)
sampleBy(列,分数,种子=无)
这种方法返回一个分层样本,而不根据每个层上给出的分数进行替换。
参数:
col —定义地层的列
分数 —每个地层的取样分数。如果未指定地层,其分数将被视为零。
种子—随机种子 id。
非常感谢您的提问和评论!
参考
每个数据科学爱好者都应该知道的结构化数据类型
了解数据类型的分类
艾萨克·史密斯在 Unsplash 上拍摄的照片
在我的上一篇博客中,T4 对数据科学中的统计数据的需求变得很明显,现在是时候深入了解统计方法了。这将是一系列的博客文章和视频(在我的 YT 频道)。
你是谁?
我开始了这一系列关于统计和概率的博客,以帮助所有的编码人员和分析人员理解这些概念和方法。你熟悉 Python 编程,并试图更好地掌握统计学,以掌握数据科学技能。
数据和数据分析的增长
我们知道,数据分析的发展已经超出了其最初的预期范围,这是因为技术的快速发展,越来越多的数据的产生,以及各种学科对定量分析的积极使用。
由于这种基础设施的发展,我们可以达到一个阶段,我们有多种数据源,如传感器,CRM,事件,文本,图像,音频和视频。
非结构化数据
现在,大部分生成的数据是非结构化的,即没有预定义模型/结构的数据。例如,图像是像素的集合,文本数据是没有特定预定义存储模型的字符序列,以及来自用户在 web 应用上的操作的点击流。
非结构化数据面临的挑战是,需要将其预处理为结构化数据,以便对其应用统计方法,并获取原始数据中包含的信息。
结构数据
当我们谈论结构化数据时,我们经常谈论表格数据(矩形数据),即数据库中的行和列。
这些表还主要包含两种类型的结构化数据:
- 数值数据
用数字表示的数据。它进一步表现为两种形式:
- 连续— 可以在一个区间内取任意值的数据。比如车速、心率等。
- 离散— 只能进行整数值的数据,如计数。例如,抛 20 次硬币的正面数。
2。分类数据
只能接受代表可能类别的一组特定值的数据。这些也被称为枚举,枚举,因素,或名义。
- 二进制— 分类数据的一种特殊情况,其特征是二分的,即只能接受 0/1 或真/假。
- 序数— 具有明确排序的分类数据。例如,餐厅的五星评级(1、2、3、4、5)
但问题来了,**为什么需要了解数据?**答案是,如果不知道数据的类型,你将无法运用正确的统计方法来处理这种类型的数据。
例如,如果 dataframe 中的一列有序号数据,我们就必须对它进行预处理,在 python 中,scikit-learn 包提供了一个OrdinalEncoder
来处理序号数据。
下一步是深入研究结构化数据,以及我们如何使用第三方包和库来操作这种结构。我们主要有两种类型的结构或数据存储模型:
- 矩形的
- 非矩形
矩形数据
数据科学中的大多数分析都是用矩形二维数据对象完成的,如数据帧、电子表格、CSV 文件或数据库表。
这主要由代表记录(观察)的行和代表列(特征/变量)的行组成。另一方面,Dataframe 是一种特殊的数据结构,具有表格格式,提供超高效的操作来操作数据。
数据帧是最常用的数据结构,在这里介绍一些定义很重要:
数据帧
矩形数据结构(像电子表格一样),用于统计和机器学习模型的高效操作和应用。
特征
数据帧中的一列通常被称为特征。
同义词-属性、输入、预测值、变量
胜负
许多数据科学项目涉及预测结果——通常是/否结果。
同义词—因变量、响应、目标、输出
记录
数据帧中的一行通常被称为记录。
同义词—案例、例子、实例、观察、模式、样本
举例:
板球比赛数据的数据帧
关系数据库表有一个或多个列被指定为索引,本质上是一个行号。这可以极大地提高某些数据库查询的效率。在 pandas dataframe
中,根据行的顺序创建一个自动整数索引。在pandas
中,还可以设置多级/分层索引,以提高某些操作的效率
非矩形数据
除了矩形数据之外,我们还有其他几种属于非矩形数据的数据结构。
地理位置分析中使用的空间数据结构更复杂,不同于矩形数据结构。在对象表示中,数据的焦点是一个对象(如一个公园)及其空间坐标。相比之下,字段视图关注的是小空间单元和相关度量值(例如像素亮度)。
图形数据结构用于表示物理的、社会的和抽象的关系。例如,脸书或 Twitter 将网络中人们之间的联系表示为社会关系图。图结构对于某些类型的问题是有用的,例如网络优化和推荐系统。
在数据科学中,每种数据类型都有一套特定的方法。本系列的重点是矩形数据,它构成了预测建模的基础构件。
接下来…
现在,我们已经清楚地了解了我们必须经常处理的数据类型,我们现在可以开始研究处于统计和数据科学核心的基本数据分布。
在下一篇博客的中,我们将讨论高斯分布和数据中位置和可变性的其他基本估计。我们将学习如何使用 NumPy 生成正态分布数据,并使用 matplotlib 之类的库绘制数据。
数据科学与 Harshit
通过这个渠道,我计划推出几个涵盖整个数据科学领域的系列。以下是你应该订阅频道的原因:
- 本系列将涵盖所有必需/要求的高质量教程,涉及每个主题和子主题,如 Python 数据科学基础。
- 解释了数学和推导为什么我们在 ML 和深度学习中这样做。
- 与谷歌、微软、亚马逊等公司的数据科学家和工程师以及大数据驱动型公司的首席执行官的播客。
- 项目和说明实施到目前为止所学的主题。了解新的认证、训练营以及破解这些认证的资源,例如 Google 举办的 TensorFlow 开发者证书考试。
请随时在 Twitter 或 LinkedIn 上与我联系。
更好的正态分布的变换类型
正态分布的必要性
统计分析中最常见的假设之一是正态性。你同意吗?
你好,世界,这是我为数据科学社区写的第一篇博客。在这篇博客中,我们将看到各种类型的数据转换,以更好地适应正态分布(高斯分布)。
我们知道,在回归分析中,响应变量应该是正态分布的,以获得更好的预测结果。
大多数数据科学家声称,当他们转换自变量时,他们会得到更准确的结果。这意味着独立变量的偏斜校正。偏斜度越低,结果越好。
变换无非是取一个数学函数,并将其应用于数据。
让我们开始吧!
概观
- 对数变换
- 平方根变换
- 相互转化
- 博克斯-考克斯变换
- Yeo-Johnson 变换(奖金)
为了更加清晰,请访问我的 Github repo 这里
1.日志转换:
数值变量可能具有由异常值、高指数分布等引起的高偏斜和非正态分布(高斯分布)。因此,我们选择数据转换。
在对数变换中,x 的每个变量将被以 10 为底、以 2 为底或自然对数的 log(x)代替。
import numpy as np
log_target = np.log1p(df["Target"])
上图是原始数据和对数转换数据的比较。在这里,我们可以看到转换数据中的偏斜度降低了。(最佳偏斜值应该接近零)
2.平方根变换:
这一转变将对分配产生适度的影响。平方根变换的主要优点是,它可以应用于零值。
这里 x 将被平方根(x)代替。它比对数变换弱。
sqrt_target = df["Target"]**(1/2)
3.相互转换:
在这个变换中,x 将替换为 x 的倒数(1/x)。
互易变换对分布的形状几乎没有影响。此转换只能用于非零值。
reciprocal_target = 1/df["Target"]
变换数据的偏斜度增加。
4.Box-Cox 变换;
这是我最喜欢的转换技术之一。
Box-cox 变换对许多数据性质都非常有效。下图是 Box-cox 变换的数学公式。
考虑从-5 到 5 变化的所有λ值,并选择数据的最佳值。“最佳”值是导致分布的最佳偏斜度的值。当λ为零时,将发生对数变换。
from scipy.stats import boxcox
bcx_target, lam = boxcox(df["Target"])
#lam is the best lambda for the distribution
博克斯-考克斯变换
在这里,我们注意到 Box-cox 函数降低了偏斜度,它几乎等于零。工作良好;)
对于这种转换,值严格地为正。
5.杨-约翰逊变换;
这是一种较老的变换技术,非常类似于 Box-cox 变换,但不要求值严格为正。
这种转变也有能力使分布更加对称。
from scipy.stats import yeojohnson
yf_target, lam = yeojohnson(df["TARGET"])
约-约翰逊变换
Yeo-Johnson 变换工作得很好,比 Box-cox 变换更好。
结论:
在这篇博客中,我们看到了不同类型的变换(有一个额外的最古老的变换技术)来更好地适应常态。杨永强永远不会是正确的选择。对于某些类型的数据,Box-cox 会工作得更好,所以我们必须使用最好的转换技术。
在下一篇博客中,我们将看到均匀分布。😃
通过 LinkedIn 联系我;)
欢迎评论:)
PySpark 分类
分类问题如何使用 PySpark?
照片由 Jair Lazaro 在 Unsplash 上拍摄
这是一个如何在分类问题中使用 PySpark 的快速学习。这里的目的是根据不同的特征对患者进行分类,以预测他们是否患有心脏病。对于此示例,使用了 LogisticRegression,它可以导入为:
**from** **pyspark.ml.classification** **import** LogisticRegression
让我们来看看这个数据集。它被命名为 UCI 心脏病数据集,你可以从这里下载。
上面显示了前五行。目标特征被用作我们的输出,它或者是 1 或者是 0。我们希望根据其他 13 个可用特征来计算,即年龄、性别、cp 等。
为了找出每个特征的类型,我们可以使用**。printSchema()** 函数为:
下一步是将这些特征转换成矢量;我们需要导入一个合适的库。
from pyspark.ml.feature import VectorAssembler
在 PySpark 中,除了目标之外的所有列都需要转换成一个向量,我们称之为 features。
assembler = VectorAssembler(
inputCols=[‘age’, ‘sex’, ‘cp’, ‘trestbps’, ‘chol’, ‘fbs’, ‘restecg’, ‘thalach’, ‘exang’, ‘oldpeak’, ‘slope’, ‘ca’, ‘thal’],
outputCol=”features”)output=assembler.transform(heart)
我们可以在下面看到,features 列是一个基于所有 13 列的向量。
为了训练我们的模型,我们将“特征”和“目标”组合起来作为输入/输出。
final_data = output.select(“features”, “target”)
然后,我们可以将 final_data 拆分为训练和测试,如下所示:
train, test = final_data.randomSplit([0.7, 0.3])
LogisticRegression 被用作我们的分类方法,labelCol 需要被称为目标特征,而 featuresCol 是已定义的特征,它已经被表示为向量。
lr = LogisticRegression(labelCol =”target”, featuresCol =”features”)
在下一步中,我们可以训练我们的算法,这非常类似于 scikit,并查看我们的测试用例的预测输出。
model=lr.fit(train)
predict_train = model.transform(train)
predict_test = model.transform(test)
predict_test.select("target", "prediction").show(10)
下图显示了我们前十行中的目标和预测;1 例预测不准。
为了评估我们的模型,可以导入 BinaryClassificationEvaluator。
from pyspark.ml.evaluation import BinaryClassificationEvaluatorevaluator = BinaryClassificationEvaluator(rawPredictionCol ='rawPrediction', labelCol ='target')predict_test.select("target", "rawPrediction", "prediction", "probability").show(5)
该评估器使用 AUC 并比较预测列“预测”和“目标”训练和测试的值分别为 93%和 87%。
print(“The area under ROC for train set is {}”.format(evaluator.evaluate(predict_train)))print(“The area under ROC for test set is {}”.format(evaluator.evaluate(predict_test)))
对于这个问题,我只使用了默认的超参数,例如 maxIter 和 regParam,但是我们也可以调整它们以获得更好的模型。
完整的代码可以通过这个链接访问。
UDAF 和聚合器:Apache Spark 中数据集的定制聚合方法
Apache Spark 中的聚合
数据记录的聚合是数据分析工作的必要组成部分,因此 Spark 旨在提出一个强大的聚合框架,以满足用户在各种情况下的需求。
使用 rdd 作为分布式数据收集的表示,Spark 中的聚合更早地与(Hadoop 世界的)map-reduce 框架的缩减部分的概念相一致。然而,随着 Dataframe 和最新数据集表示的引入,聚合框架现在更类似于人们更熟悉的 SQL 世界中的聚合。
数据集的类型化和非类型化视图
在数据帧和数据集之间,前者是带有模式定义的数据记录的非类型化视图,而后者是类型化视图。在 Dataframe 中,每条记录都被视为值的集合(类似于表中的一行),并公开一个类似 SQL 的接口来执行转换。而在 Dataset 中,每条记录都被视为某种类型的对象,并公开一个编程接口来执行转换。但是,为了保持非类型化数据帧的概念以方便 SQL 和提高效率,Dataset 还通过编码器框架支持隐藏的非类型化视图。在我之前的博客中阅读更多关于数据集编码器框架的内容: Apache Spark 数据集编码器揭秘。任何 T 类型数据集的显式非类型化视图都由“Row”类型的数据集表示。
类型化和非类型化聚合:概述
考虑到类型化和非类型化表示,Spark 也提供了非类型化和类型化聚合。对于非类型化的聚合,只需提到可选的分组列和一个或多个列上的聚合表达式(由聚合函数组成)。这与 SQL 中完成聚合的方式非常相似。非类型化聚合的执行会导致显式的非类型化视图。Spark 使用户能够对属于任何类型的数据集执行非类型化聚合。另一方面,对于类型化聚合,用户必须提供一个聚合器对象(处理 T 类型数据集的 T 类型对象),以便在整个数据集上聚合,或者在返回聚合类型数据集的分组数据集上聚合。
数据集上的非类型化聚合:
数据集的无类型视图上的无类型聚合
/* Untyped View - A is collection of Rows with two columns col1 and col2 */
=> Dataset<T> A;/*Sum Aggregation on column col1 of A over entire collection*/
=> A.agg(functions.sum(A("col1")))/*Custom Aggregation on col1 of A over entire collection*/
=> A.agg(functions.udf(MyUDAF(A("col1"))))/*Sum Aggregation on col1 of A over grouped collection of A grouped via col2 */
=> A.grouby(A("col2")).agg(functions.sum(A("col1")))/*Custom Aggregation on col1 of A over grouped collection of A grouped via col2*/
=> A.grouby(A("col2")).agg(functions.udf(MyUDAF(A("col1"))))*All above aggregations return an untyped view (Dataset<Row>)*
数据集上的类型化聚合:
通过聚合器对数据集的 T 类型对象进行类型化聚合
/* Typed View - A is collection of type T objects where type T consists of two fields col1 and col2 */
=> Dataset<T> A;/* B an Aggregator instance aggregating multiple objects of type T to perform desired aggregation on T's field col1, The aggregated value is returned back via a field inside object of type V */
=> Aggregator<T,U,V> B;/*Aggregation on field col1 of A over entire collection*/
=> A.select(B.toColumn()) returns Dataset<V>/*Aggregation on field col1 of A over grouped collection grouped by Key Object derived from Type T */
=> A.groupbykey(KeyFunc, Encoder<K>).agg(B.toColumn())
===> Here KeyFunc is of type MapFunction<T,K> which output grouping Key Object of type K for a given record of type T
===> This grouped aggregation outputs Dataset of Tuple consisting of Key Object of type K and Aggregated object of type V, viz., (Dataset<Tuple<K,V>>)
自定义非类型化聚集:UDAF
虽然,针对非类型化聚合的支持,Spark 已经提供了多种这样的聚合函数,但是也支持构建一个定制的非类型化聚合函数,称为 UDAF。通过扩展“org . Apache . Spark . SQL . expressions”包中的“UserDefinedAggregationFunction”类,并在基类中覆盖以下方法的实现,可以在 Spark 中创建 UDAF:
/*Return schema for input column(s) to the UDAF, schema being built using StructType*/
=> public StructType inputSchema()/*Return schema of aggregation buffer, schema being built using StructType */
=> public StructType bufferSchema()/*DataType of final aggregation result*/
=> public DataType dataType()/*Initialize aggregation buffer*/
=> public void initialize(MutableAggregationBuffer buffer)/*Update aggregation buffer for each of the untyped view (Row) of an input object*/
=> public void update(MutableAggregationBuffer buffer, Row row)/*Update current aggregation buffer with a partially aggregated buffer*/
=> public void merge(MutableAggregationBuffer buffer, Row buffer)/*Evaluate final aggregation buffer and return the evaluated value of DataType declared earlier */
=> public Object evaluate(Row buffer)
你可以在定制的 UDAF 类中声明额外的字段(在 UDAF 构造函数中可选地初始化这些字段)和额外的方法,以便使用这些内部的覆盖方法来实现聚合目标。此外,需要注意的是[只有某些数据类型](http://BooleanType ByteType ShortType IntegerType LongType FloatType DoubleType DecimalType TimestampType DateType StringType BinaryType)被允许用于最终结果类型以及定义输入和缓冲模式。
UDAF 示例:假设有一个如下声明的类型‘raw data wrapper ’,每个包装器由一个键字段和一个反映射字段组成。
对于“RawDataWrapper”类型的数据集,这里有一个 UDAF 声明,它聚集了 RawDataWrapper 类型的记录之间的反映射。
上述申报的 UDAF 的用途如下所示:
自定义类型聚合:聚合器
类型化聚合通过abstract generic ’ Aggregator<IN,BUF,OUT > ‘类(存在于包’ org . Apache . spark . SQL . expressions '中)来支持。用户可以定义自己的自定义聚合器,方法是使用为 IN(输入记录类型)定义的类型、为 BUF(聚合缓冲区)定义的类型和为 OUT(输出记录类型)定义的类型对其进行扩展,并在基类中覆盖以下方法的实现:
/* return Encoder for aggregation buffer of type BUF. This is required for buffer ser/deser during shuffling or disk spilling */
=> public Encoder<BUF> bufferEncoder()/* return Encoder for output object of type OUT after aggregation is performed */
=> public Encoder<OUT> outputEncoder()/* return updated aggregation buffer object of type BUF after aggregating the existing buffer object of type BUF with the input object of type IN*/
=> public BUF reduce(BUF buffer, IN input) ()/* return updated aggregation buffer of type BUF after merging two partially aggregated buffer objects of type BUF */
=> public BUF merge(BUF buffer1, BUF buffer2)/* return output object of type OUT from evaluation of aggregation buffer of type BUF */
=> public OUT finish(BUF arg0)/* return buffer object of type BUF after initializing the same */
=> public BUF zero()
与 UDAF 类似,用户可以在自定义的聚合器类中声明额外的字段(在聚合器构造函数中可选地初始化这些字段)和额外的方法,以便使用这些内部的覆盖方法来实现聚合目标。
**聚合器示例:**下面是一个聚合器声明,它将在 RawDataWrapper 记录上实现与 UDAF 示例所描述的相似的聚合目标
上面声明的聚合器的用法如下所示:
比较:UDAF 和聚合器
如果聚合字段不涉及 ArrayType 或 MapType 等复杂类型,UDAF 和聚合器的效率是相似的。但是,聚合器在聚合复杂数据类型方面比 UDAF 效率更高。这是因为在 UDAF 的每次更新操作中,scala 数据类型(特定于用户)会转换为 catalyst 数据类型(catalyst 内部数据类型),反之亦然。对于聚合缓冲区中的复杂数据类型,这种转换在效率和内存使用方面变得非常昂贵,使得 UDAF 在这些情况下与对等聚合器相比运行缓慢。在这篇博客中,为了实现相似的聚合目标,提供了 UDAF 和聚合器的示例,当两者都在 180 GB 的样本数据上运行时,UDAF 需要大约 40 分钟,而聚合器只需要大约 7 分钟就可以在集群上完成一组相似的资源。
然而,尽管 UDAF 提供了类似 SQL 的易用性,但聚合器的聚合方式在编写聚合逻辑时提供了更大的灵活性和编程优雅性。
此外,与大量可供使用的非类型化聚合函数相比,类型化聚合函数的库很少(基于聚合器概念)。因此,非类型化聚合流仍然是广泛使用的一种。但是,在未来的 Spark 版本中,类型化聚合器将被集成到非类型化聚合流中,以便用户可以通过聚合器使用已经可用的非类型化聚合函数库以及高效灵活的定制聚合函数。很明显,这将最终导致普遍使用 UDAF 来定义自定义聚合函数的做法遭到反对。
如果您对 Spark 聚合框架有更多的疑问,请随时在评论区提问。
视频对象检测终极指南
20/20 年前的一切(计算机视觉)
在过去的十年中,在机器学习领域,尤其是计算机视觉领域,已经做了大量的工作。从 Google 的 Inception 等高级分类算法到 Ian Goodfellow 在生成对抗网络方面的开创性工作,以从噪声中生成数据,世界各地许多专注的研究人员已经处理了多个领域。有趣的是,在这十年的前五年,计算机视觉领域最具开创性的工作大多涉及图像处理,如分类、检测、分割和生成,而视频处理领域则没有得到深入探索。
Ibrahim Rifath 在 Unsplash 上的照片
轻微不平衡的一个明显原因是因为视频本质上是一系列图像(帧)的组合。然而,这个定义不能概括视频处理的全貌,这是因为视频处理给这个问题增加了一个新的维度:时间维度。视频不仅仅是一系列图像,而是一系列相关的图像。虽然这看起来是一个很小的差异,但研究人员能够以多种方式利用这个维度,而不是应用于单个图像。此外,由于视频数据(大小、相关注释)的复杂性以及训练和推理的昂贵计算,在该领域的突破一直较为困难。然而,最近随着 ImageNet VID 和其他大规模视频数据集的发布,越来越多的视频相关研究论文浮出水面。在本指南中,我们将主要探讨在视频检测中已经完成的研究,更准确地说,研究人员如何能够探索时间维度。
目录
后处理方法
最先出现的方法是应用于对象检测流水线的后处理步骤的修改。这是因为它需要更少的基础设施,并且不需要改变模型的架构。后处理方法仍然是每帧检测过程,因此没有性能提升(处理时间可能稍长)。然而,它可以实现相当大的准确性提高。
序列选择的图示。我们构造一个图,其中相邻帧中的框是链接的,如果它们的 IoU > 0.5。来源:Seq-NMS 研究论文(链接)
一种值得注意的方法是序列-NMS (序列非最大抑制),其通过动态编程基于“轨迹”上的其他检测对检测置信度进行修改。例如,由于遮挡、运动模糊或其他缺陷,可能导致对阳性对象的预测较弱,但是由于它将出现在从先前帧中提取的“轨迹”(重叠标准)中,因此置信度将会提高。这将有效地减少帧之间的错误检测或随机跳跃检测的数量,并稳定输出结果。
使用序列 NMS 在 mAP 中的绝对改善(%)。这种改进是相对于单图像 NMS 而言的。来源:Seq-NMS 研究论文(链接)
从上图可以看出,精确度已经有了相应的提高:相对于单图像 NMS,使用 Seq-NMS 的 mAP (%)的绝对提高超过了 10%,有 7 个类别的提高超过了 10%,而只有两个类别显示精确度下降。虽然这项工作是实现更好的视频检测的最初工作之一,但它并没有证明在准确性和性能方面是最好的。然而,明显的好处是,这种方法不需要训练本身,更像是一个可以插入任何对象检测器的附件。
多框架方法
三维卷积
例如,具有图像分类经验的开发人员的第一本能会想到某种 3D 卷积,这是基于对图像进行的 2D 卷积。这种架构的可能性似乎是合理的:遍历 n 个帧作为模型的输入,并输出对连续帧的顺序检测。这无疑是一个潜在的检测方向,因为它可以提取时空数据的低级特征,但具有 3D 卷积的卷积神经网络已被证明在处理 3D 图像(如 3D MNIST 或 MRI 扫描)时非常有用且富有成效。这就是为什么这些模型更多的是医学成像领域的突破,而不是视频检测。
尽管如此,探索在视频处理中使用 3D 卷积的研究论文的一个例子是,一个用于视频中动作检测和分割的端到端 3D 卷积神经网络。在研究论文中,首先将视频分成等长的剪辑,然后根据 3D CNN 特征为每个剪辑生成一组管道建议。然后,不同剪辑的管提议被链接在一起,并且使用这些链接的视频提议来执行时空动作检测。尽管该论文主要讨论了分割和动作检测,但是可以训练该体系结构的衍生物来执行对象检测。
就性能而言,由于多维矩阵的高计算量,在当前状态下,处理时间无法与实时(30 fps 或更高)一样快。在这一领域的进一步改进和研究可以改变方向,但扩展 3D 卷积的性能并不是一件容易的事情。说到准确性,我相信肯定能受到正面影响。检测的稳定性以及精度可以通过 3D 卷积来提高,因为该架构可以有效地利用时间维度(帧之间特征的集合)。然而,它目前只是基于其他最先进的 3D 卷积模型的一种推测。还没有一篇深入研究视频检测的论文。
递归神经网络
对于其他对序列数据有更多经验的人来说,人们可能倾向于考虑使用递归神经网络,如 LSTM。RNN 是一种特殊类型的网络,用于处理时序数据,包括时态数据。从这种架构中获益匪浅的一个领域是自然语言处理。例如,AWD-LSTM 的表现与最先进的伯特变压器模型不相上下,而参数却少得多。那么,它是否适用于帧完全连续的视频检测呢?像的具有时间感知特征图的移动视频对象检测和的看起来快和慢:记忆引导的移动视频对象检测已经取得了一些进展。
提高性能的 LSTM 层。来源:"Mobile Video Object Detection with Temporally-Aware Feature Maps", Liu, Mason and Zhu, Menglong, CVPR 2018.
在前者中,本文将快速单幅图像目标检测与称为瓶颈 LSTM 的卷积长短期记忆(LSTM)层相结合,以创建一种交织递归卷积架构。LSTM 层降低了计算成本,同时仍然在帧间改进和传播特征图。该白皮书旨在低功耗移动和嵌入式设备上实时运行,在移动设备上实现 15 fps。
使用 LSTM 层的大型和小型神经网络。来源:"Looking Fast and Slow: Memory-Guided Mobile Video Object Detection", Liu, Mason and Zhu, Menglong and White, Marie and Li, Yinxiao and Kalenichenko, Dmitry
在后者中,研究人员建议通过依赖相关的先验知识来利用场景的“要点”(短时间内复杂环境的丰富表现),这些先验知识是受人类如何识别和检测物体的启发而产生的。该模型的架构是通过将传统的特征提取器与仅需要识别场景要点(最小计算)的轻量级特征提取器交错。这有效地从捕获“要点”的关键帧为架构创建了长期记忆,该要点指导小型网络检测什么。本文还结合了强化学习算法来实现自适应推理策略。该论文提供了有希望的结果,例如在移动设备上 70 fps,同时在 ImageNet VID 上仍然实现了小型神经网络的最先进结果。
一个关键要点是,该架构是端到端的,这意味着它获取图像并输出屏蔽数据,需要对整个架构进行训练。因为我们正在处理视频数据,所以模型需要在大量数据上进行训练。
光流方法
为什么不能在视频上使用图像物体检测器?我们可以。另一种可能的处理视频检测的方法是对视频文件的每一帧应用最先进的图像检测器,如 YOLOv3 或面部检测器,如 RetinaFace 和 DSFD 。每一帧都将被用作模型的输入,视频结果可以像它们在图像上的平均精度一样精确。然而,将这些检测器直接应用于视频文件的每一帧面临着来自两个方面的挑战:
- 就速度而言,对所有视频帧应用单个图像检测器效率不高,因为主干网络通常又深又慢。将它应用于每个单个帧还会导致大量冗余计算,因为来自视频文件的两个连续帧通常不会有很大差异。
- 对于精度,检测精度受到在静止图像中很少观察到的视频中的劣化外观的影响,例如运动模糊、视频散焦、罕见姿势。
因此,在每个文件上应用检测器不是解决视频检测挑战的有效方法。然而,通过探索视频的时间维度,我们可以实现不同的方法来解决一个或两个问题。
什么是光流?
光流估计是一种估计由摄像机(背景)或对象运动引起的两帧视频之间的物体的表观运动的方法。输出通常是 2D 矢量场,其中每个矢量代表一个像素从第一帧到第二帧的位移矢量。
光流算法的彩色编码输出示例。来源:辛特尔光流数据集(http://sintel.is.tue.mpg.de/)
光流一直是计算机视觉的一个研究领域,自 20 世纪 80 年代以来一直在探索,最近又作为深度学习的一个有趣领域重新浮出水面,由 Flownet 开创。在此之前,最初的方法是微分的。例如,Lucas-Kannade 方法假设在所考虑的像素的局部邻域中流动基本上是恒定的,并且通过最小二乘法准则求解该邻域中所有像素的基本光流方程。但随着新的进展和新的光流数据集,如 Sintel,越来越多的架构浮出水面,一个比另一个更快更准确。
有多种架构可以利用这项技术。例如,迈向高性能以及许多其他使用光流来建立跨帧的对应关系(稀疏特征传播)。光流是当前开发视频对象检测的时间维度最多的领域,因此,出于某种原因。光流的结果越来越快,越来越准确。
稀疏特征传播提高性能
该体系结构以稀疏关键帧的概念运行。由于光流网络可以相对较小,因此这种网络所需的处理时间和计算能力小于物体检测器。因此,流水线的功能相当于 n 帧的循环。第一帧称为关键帧。这是对象检测器检测到的帧。因为现在检测器给出了所有对象的精确检测,所以检测将服从光流算法。在获得位移向量之后,下 n-1 帧的检测是已知的,并且循环重复。
稀疏特征在纸上传播开来:【https://arxiv.org/pdf/1611.07715.pdf
精确的多帧特征聚合
提高视频检测准确性的一种方法是多帧特征聚合。有不同的实现方式,但都围绕着一个想法:密集计算的每帧检测,同时从相邻帧到当前帧进行特征扭曲,并通过加权平均进行聚合。因此,当前帧将受益于直接帧以及一些进一步的帧,以获得更好的检测。这可以解决视频帧中的运动和裁剪主题问题。
论文多帧特征聚合:https://arxiv.org/pdf/1703.10025.pdf
一个这样的例子是研究论文流引导特征聚合(FGDA) 。流动引导的特征聚集聚集来自附近帧的特征地图,这些特征地图通过估计的流动很好地对齐。该架构是一个端到端的框架,在功能级别上利用时间一致性。
比较
在介绍完所有这些方法之后,我们可以通过一个比较表来总结这些方法的要点,以帮助理解这些方法与使用图像检测器的简单逐帧方法相比有何不同:
以上方法对比图。*这些方法在处理关键帧时可能会产生一点延迟。
虽然所介绍的方法是目前已经发表的,但随着视频对象检测成为一个更容易理解的话题,目前肯定有更多的研究正在进行。希望随着即将到来的会议,越来越多的突破可以观察到。从 2020 年开始的新十年,人们对更好的视力充满了希望!干杯!
UIUC 在线计算机科学硕士:个人剖析
伊利诺伊大学厄巴纳-香槟分校数据科学计算机科学在线硕士课程综述
米利安·耶西耶在 Unsplash 上拍摄的照片
在一个后 COVID 的反乌托邦或乌托邦取决于你看的是一杯水的哪一半,通过它可以管理、完成和授予学位的在线媒体的相关性不可能被夸大。除了百年一遇的疫情,还有很多其他原因可以让你考虑参加在线课程。也就是说,作为一个工作时间有限的专业人士,作为一个有孩子要照顾的家长,或者仅仅是不能在家门口进入世界一流的大学。上述理由的任何组合都可以使在线学位成为一个诱人的选择,甚至是唯一的选择。
介绍
我的故事始于 2018 年初。在钻研了毕业后职业生涯的第四年后,我意识到下一个合乎逻辑的步骤是获得硕士学位。考虑到我所在的竞争激烈的行业(研发)和不断变化的就业市场,我知道我必须承受更多的大脑损伤才能保持相关性。虽然我的学士学位是机械工程,但我当时作为开发工程师的工作要求我开发数据挖掘和数据可视化软件。结果,我对面向对象编程、数据结构和算法有了大量的了解和喜爱。再加上我意识到数据科学将会像互联网一样无处不在,影响深远,这让我毫不犹豫地去追求它。
我有一份全职工作,而且附近没有提供数据科学硕士学位的大学,所以我被要求在互联网上搜索在线课程。虽然我起初对在线学位持保留意见,主要是因为负面的含义和与之相关的耻辱,但我很快意识到这种冲动是没有根据的,事实上有一个快速增长的成功专业人士社区,他们完成了在线学位,取得了切实的积极成果。请注意,并不是所有的在线项目都是被认可的,甚至是合法的,因此强烈建议进行尽职调查。
应用程序
当时只有少数几个在线数据科学项目,而不是目前迅速扩大的清单。鉴于我实际上不会去任何一个校园,地点显然不是我考虑的因素。我主要担心的是该机构在计算机科学、学生评论和学费方面的声誉。因此,唯一入围的候选项目是伊利诺伊大学香槟分校提供的 MCS-DS 项目。鉴于 UIUC 在计算机科学方面排名全国第五,它的积极评价和负担得起的学费(600 美元/学分/小时,当时只是校园费用的一小部分),我没有进一步考虑,申请了夏季学期的入学。虽然 UT Austin 的在线数据科学硕士项目当时还不存在(首次提供-2021 年春季),但如果我面对两种选择,这将是一个非常困难的决定。也许会有一种微妙的倾向倾向于德州大学奥斯汀分校,因为它的学费低得多(约 300 美元/学分)。
然而,令我非常失望的是,几周后我被拒绝了。经过询问,我得到了一个相对笼统的答复,说明在面向对象编程、数据结构、算法和线性代数方面背景不足的申请人不适合这个项目,除非他们能够证明并非如此。不可否认,收到拒绝让整个项目对我更有吸引力;如果你愿意,可以称之为心理学,但在那之后,我更坚定地获得了录取。因此,我决定在这四个领域中的每一个领域注册几门短期 MOOCs 课程,并在秋季学期重新申请,申请中包含证书链接。这似乎起到了作用,我很高兴地收到了 UIUC 2018 年秋季 MCS-DS 队列的迟到录取通知(大约在学期开始前 4 周)。
体验
学术顾问:
学术顾问对注册、课程选择和其他与行政事务相关的后勤工作给予了极大的帮助和响应。我特别感激的是,他们经常增加容量,让学生注册他们想注册的课程,并总是增加容量,让学生参加他们需要按时毕业的课程。
学术严谨:
与任何大学一样,学术严谨性和教育质量因课程而异。有了 MCS-DS,提供它的课程和教员实际上与校园版相同。所研究的一些主题是详尽的,而其他的则处于入门或中级水平。就任务和项目而言,挑战的程度相当激烈;样板文件对程序或语法错误是不宽容的,项目提交被严格评分。同样,关于学生在团队项目上偷懒的报道也受到了重视,没有人获得毕业的免费通行证。然而,小考和考试的情况就不一样了。感觉通过测验太容易了——有些课程允许多次重考,而且考虑到大多数问题都是选择题,通过测验有时真的需要反复试验。考试更难,不允许重考,但大多数问题都是选择题,这意味着测试的理解水平有点浅。也许项目负责人应该设计一种考试形式,更严格地衡量学生对主题的掌握程度。
Coursera:
Coursera 充当了用于提供该计划的所有云基础设施之间的焦点。总的来说,MCS-DS 和 Coursera 之间的整合是相当无缝和用户友好的。作业可以轻松提交,样板文件运行良好,内容以高度结构化的方式组织。然而,从第一学期一直持续到最后一学期的一个难题是,在每学期开始时,注册课程添加到 Coursera 平台的延迟(长达一周)。虽然我不知道谁该为这种不便负责,但奇怪的是,它从未得到解决。
课程设置:
MCS-DS 最明显的问题是每学期提供的课程数量有限。在当时,每个核心领域的选项通常限于两个,甚至在机器学习广度课程的情况下限于一个。因此,我别无选择,只能休学一整个学期(2019 年秋季),一个学期后毕业。我明白这是一个项目在起步阶段的预期,也注意到随着它的成熟,额外的课程已经增加。
广场&松弛:
Piazza 被有效地用作学生、助教和教授可以互动的虚拟教室。与 Coursera 不同,课程总是在学期开始时就设置好并准备好加入。类似地,Slack 被用作一个更非正式的论坛,主要供学生在每个班级的单独频道和整个项目的一个总频道中进行互动。团队项目使用两种工具进行,这两种工具在促进沟通和丰富整体体验方面非常有效。
普罗克多:
考试由 ProctorU 进行,ProctorU 向学生单独收费,并为学生参加在线考试提供灵活的时间。他们的监考老师是专业的、辅助的和精通技术的,这使得这是一次总体上积极的经历。在每次考试之前,监考人会远程连接到您的计算机,然后打开您的麦克风和网络摄像头,并要求您彻底向他们展示您的即时环境,以减少作弊的可能性。有些人认为在线考试的完整性是虚假的,但老实说,在校园里作弊可能比在网上更容易。ProctorU 有相当多的技术故障,有时会导致考试推迟开始,甚至完全错过,不得不重新安排时间。随着在线考试越来越普遍,我希望他们将来能解决这些问题。
编程堆栈:
MCS-DS 的主力是,是的,你猜对了——备受喜爱的 Python。大多数课程只有 Python 版本,而其他课程允许使用 C++和 Java。Python 中使用的主要包有:Numpy、Matplotlib、Plotly、Pandas、OpenCV、Scikit-learn、NLTK、spaCY 和 SciPy。在必要的地方,其他课程提供了 Java、Javascript、R 和 SQL 的编程,但仅限于一些精选作业。此外,还不时使用 Docker、Jupyter Notebooks、Anaconda 和 GitLab。
教授:
在线学位有点像一种超现实的体验。不言而喻,你真的错过了宝贵的学生-教授互动。幸运的是,MCS-DS 项目的教师通过定期与学生接触,在很大程度上弥补了这一点。通信很少通过电子邮件进行,相反,Piazza 和 Zoom 经常被用来回答问题和举行现场会议。如果说有什么不同的话,那就是我实际上觉得我遇到我的教授的次数比获得一个校园学位还要多。也有很多同理心;教授们经常应要求适应学生们繁忙的日程安排。
助教:
我在 MCS-DS 的四个学期中最美好的经历可能就是与助教们的互动。UIUC 每 50 名学生分配一名助教,老实说,这已经足够了,因为我们的大部分作业都是用样板评分的,助教主要是回答学生的问题。每当课程报名人数过多时,项目协调员甚至会好心地分配额外的助教,我发现他们非常负责,这表明他们不愿意在教育质量上妥协。助教都非常聪明,他们中的许多人都是在相同领域广受好评的研究者。他们经常主动提供帮助,在许多情况下,平均响应时间不到一个小时(Piazza 证实了这一点)。
时间管理:
做出的个人牺牲是这个项目的决定性特征。周末几乎是不存在的,你可以期望平均每周花十个小时在每门课程上(在学期结束时会更多)。我正在冲刺四个学期的课程,结果我花了两个学期上了两个班,一个三个班,另一个一个班。对于像我这样的在职人士,我不建议每学期选一门以上的课,假设你也参加夏季学期,以便按时毕业(你必须在五年内毕业)。调整好自己的节奏,尽量提前安排好考试,以避免考试名额被占满,不得不安排一个不合适的时间。熟悉课程,如果你一个学期要上多门课,那么就尽量避免艰深的课程(这样的课程不多)。
课程
因为我显然不能复习我没有学过的课程,所以我强烈建议在你报名参加同一个科目之前,仔细聆听其他学过这个科目的学生。从某种程度上来说,一个糟糕的开始可能会让你很快醒悟。所有课程都是四个学分,然而有些课程感觉更像是三个甚至两个学分。在这个项目中通常有两个方向可以遵循,即云计算和数据挖掘。我选择了后者,但回想起来,我希望我选择了云计算,因为它与我的工作更相关。
文字信息系统(2018 年秋季):
这是数据挖掘专题讲座中提供的主题之一,可以用作数据挖掘顶点课程的先决条件。您将初步接触到文档排序、自然语言处理和文本挖掘算法——所有这些都是非常实用且在行业范围内普遍使用的技术。难度适中,课程的高潮是一个将几个学过的概念结合在一起的项目。
数据监管基础(2018 年秋季):
这个科目其实是信息科学学院开设的,不是计算机科学系。这绝对是那些感觉更像两个学分的科目之一,并且只涉及关于数据的来源、模式和生命周期的最抽象的概念。就难度而言,这个课程简直是小菜一碟,如果是我的转世,我可能会三思而后行。
数据挖掘简介(2019 年春季):
这是数据挖掘轨道中的另一个主题,感觉像是文本信息系统的逻辑继承者。它提供了很大的深度,并侧重于几个关键概念,如频繁模式挖掘,监督/非监督学习和朴素贝叶斯分类器。你有机会立即将学到的概念应用到编程作业甚至在线竞赛中。难度适中,获得的知识是一个宝库。
云计算应用(2019 年春季):
这显然是云计算专题之一,也可以说是该专题中最简单的一个(另外两个是云网络和云计算概念)。您将获得关于 IaaS、MapReduce、Hadoop 和 Apache Spark 以及许多其他大数据框架的宝贵见解,但主要缺点是本课程牺牲了深度以换取广度。有时,你会被你所学的众多主题压垮,而你并没有在任何一个单独的领域真正发展出强大的能力。此外,有几个工具在教授时已经过时了,这个学科需要一次大的改革,据我所知,改革已经开始了。
数据清洗理论与实践(2019 年夏季):
可能是 MCS-DS 中最有用的主题之一。你很快钻研了 SQL、Regex 和 OpenRefine,这些对我的工作都是至关重要的工具,我真诚地感谢这门课程提供的相关性。整堂课由编程作业和一个期末项目组成,都相对简单而有趣。
数据挖掘顶点(2019 年夏季):
这是数据挖掘方向的可选课程,只有在完成该方向的两门课程后才能参加。老实说,这是一个很大的失望,给了我很高的期望。作业是非常开放的,重复利用了文本信息系统和数据挖掘导论中的早期编程作业,这些作业应用于一个大型 Yelp 数据集。还有一个文献审查任务和一个项目,要求你将一个数据挖掘应用程序部署到云中,这可能是唯一有用的任务。一切都是同行评分的,因此它更像是一门 MOOC(实际上也是),而不是一门学分课程。
数据可视化(2019 年夏季):
这是你熟悉 Tableau、D3.js、DOM 和 Vega 的程序中最好的主题之一。当时,数据可视化是强制性的,因为在这一核心领域没有其他选择,而且只在夏季学期提供,这对许多人来说并不理想,但话说回来,它可以从婴儿计划中得到。最终项目要求您开发一个交互式仪表盘并部署到云中,这可能是整个 MCS-DS 项目中最具影响力的一项任务。
计算摄影(2020 年春季):
由于 2020 年春季不提供应用机器学习,我们可以选择注册计算摄影作为替代品或推迟一年毕业。我不能说很多人在意识到他们将在没有参加任何机器学习课程的情况下完成一个数据科学课程时感到高兴,但幸运的是,我在早些时候的数据挖掘介绍中已经参加了大量的课程。这门课的独特之处在于它聚焦于计算机视觉中一个非常狭窄的主题,但却深入到了它的最深处。我们被教导如何应用摄影拼接,变形,纹理合成和混合。这可能是 MCS-DS 中对我来说最难的科目,学习曲线相当陡峭。这与我的工作不太相关,但我相信很多人能够在其他领域利用这一点。
最终的分析
对于那些仍在考虑在线学位是否可以替代校园教育的人来说,我必须说没有放之四海而皆准的解决方案。换句话说,没有最好的大学这种东西,但是有最适合你的大学这种东西。鉴于一个人的情况,除了在线教育,可能没有其他选择。诚然,校园里的社交机会并不是真的可以在网上获得的,这本身对许多人来说就是一个交易破坏者。对我个人来说,UIUC 的 MCS-DS 让世界变得不同;甚至在毕业之前,当我把 LinkedIn 添加到我的个人资料中时,我惊讶地看到大量招聘人员在 LinkedIn 上联系我。在我的最后一个学期,我找到了一份新工作,并在毕业后立即开始工作,仅仅是因为这个学位。我很感激它向我敞开的大门,我经常向家人和朋友推荐这个项目。在线学位正变得越来越普遍,我希望 UIUC 能在未来保持同样的质量和严谨水平。
附注:对于那些缺乏实质性接触入学所需能力的人来说,以下(附属链接)MOOCs 可以帮助弥合差距: 【面向对象编程】数据结构&算法统计 ,**
另外,随意订阅 Medium,在这里 探索更多我的故事 。
英国高价值客户识别与 K-均值聚类。
引言。
一家总部位于英国的在线零售店捕捉了一年期间(2016 年 11 月至 2017 年 12 月)不同产品的销售数据。该组织主要通过在线平台销售礼品。购物的顾客直接为自己消费。有些小企业批量购买,然后通过零售渠道销售给其他客户。
作为项目目标?我们努力为企业寻找大量购买其喜爱产品的重要客户。该组织希望在确定细分市场后向高价值客户推出忠诚度计划。我们将使用聚类方法将客户分成不同的组。
数据争论
在我的分析中,我转向了提供的数据集,我们将首先检查它,看是否需要任何争论和清理。
因为数据集中有太多的行,所以查看结构并查看是否有任何值丢失是有意义的。如果数据集中有丢失的值,最好看看哪些列受到了影响,这对我们的分析是否是个问题
我们过滤该表,以查看 NaN 值的主要位置及其对输出的影响。在 SQL 的帮助下,我们过滤数据,找出每个客户购买了多少东西,以及他们为公司创造的总收入。如果我们的主要目标是找到最大的消费群体,那么最好的办法就是比较他们的大宗订单,以确定高消费群体
在制作好表格并将所有 NaN 值分组后,我们将删除它们以避免分类列直方图中的偏差。通过这种方式,所有客户的代表性更加均匀,我们将不会出现异常值,这些异常值归因于缺少信息的客户。
之后,我们创建一个散点图,看看我们的客户购买的商品产生了多少收入。该图显示了占据图中 0 点附近空间的大部分销售,除了少数例外,这些销售似乎购买了大量的商品,但产生的收入很少,或者购买了少量的商品,但收入巨大。为了确保我们的分类以最公平的方式表示数据,我们将对最高收入和数量设置约束。
探索性分析
为了找到聚类,我们将使用 K-means 算法。
K-means 算法是一种迭代算法,它试图将数据集划分为 K 个预定义的不同非重叠子组(聚类),其中每个数据点仅属于一个组。它试图使簇内数据点尽可能相似,同时保持簇尽可能不同(远)。它将数据点分配给一个聚类,使得数据点和聚类质心(属于该聚类的所有数据点的算术平均值)之间的平方距离之和最小。聚类中的差异越小,同一聚类中的数据点就越相似。
kmeans 算法的工作方式如下:
- 指定聚类数 k。
- 初始化质心,首先洗牌的数据集,然后随机选择 K 个数据点的质心没有替换。
- 继续迭代,直到质心没有变化。也就是说,数据点到聚类的分配没有改变。
- 计算数据点和所有质心之间距离的平方和。
- 将每个数据点分配给最近的聚类(质心)。
- 通过取属于每个聚类的所有数据点的平均值来计算聚类的质心。
因此,为了找到最佳的聚类数 K,我们将使用“肘方法”。该方法包括将解释的变化绘制为集群数量的函数,并选取曲线的弯头作为要使用的集群数量。同样的方法也可以用来选择其他数据驱动模型中的参数个数,比如描述一个数据集的主成分的个数。
接下来,我们从数据集的列中创建一个 numpy 数组,并根据找到的最佳 K 值绘制聚类图。完成后,我们根据我们选择的集群数量和我们计算的中心绘制数据框架。为了突出结果,我们使用明亮的颜色来清楚地看到每个聚类的边缘。
为了准确起见,我们还将制作一个树状图。树状图是显示对象之间层次关系的图表。它通常是作为层次聚类 *的输出而创建的。*树状图的主要用途是找出将对象分配到集群的最佳方式。关于我们如何以及为什么使用树状图的更深入的描述,包括它们背后的数学,请随意使用超链接获取更多信息。
结果
一旦找到聚类,我们使用指定的数字与每个客户相关联,显示哪些属于收入最高的客户。在筛选出特定集群编号的记录后,我们可以创建一个需要关注的顶级客户列表。使用它来查看未来几年是否会有新客户占据相关集群也很有用,现有客户的动态可能有助于调整未来几年的优秀客户名单。
结论
感谢您花时间阅读上面的分析,我希望它是有趣的,并为集群和探索性分析提供了一些见解。该项目的所有代码都可以在我的 GitHub 上找到,请检查一下,如果你有任何意见或建议,请随时发表评论。毕竟,我们无法学习我们认为已经知道的东西。
使用 Python 为自然语言处理(NLP)收集文本的入门指南— Twitter、Reddit、Genius 等等
通过 API 和 Web 抓取收集文本
进入自然语言处理领域
自从一年多前进入数据科学以来,我一直对自然语言处理(NLP)着迷。由于迁移学习的进步,该领域已经取得了一些爆炸性的进展,像 Alexa 和 Siri 这样的 NLP 产品已经成为家喻户晓的名字。由于我的背景是技术写作和修辞理论,我立即被涉及文本的项目吸引,如情感分析和主题提取,因为我想了解机器学习如何提供对书面语言的洞察力。我的第一个数据科学项目是使用谷歌的通用句子编码器来产生葡萄酒推荐。
我一直想要一个像这样的指南,分解如何从流行的社交媒体平台提取数据。随着对 BERT 和 ELMo 等强大的预训练语言模型的可访问性增加,了解在哪里查找和提取数据变得非常重要。幸运的是,社交媒体是收集 NLP 数据集的丰富资源,只需几行 Python 代码就可以轻松访问。在文章的最后,我还提供了一个流行的 Kaggle NLP 数据集列表,并链接到新的搜索引擎 Google Dataset Search。
先决条件
本文教你如何从 Twitter、Reddit 和 Genius 中提取数据。我假设你已经知道一些 Python 库 Pandas 和 SQLite 。
管理您的 API 密钥
在进入代码之前,强调 API 键的值是很重要的。如果您是管理 API 密钥的新手,请确保将它们保存到 config.py 文件中,而不是在您的应用程序中硬编码它们。确保不要将它们包含在任何在线代码共享中。 API 密钥可能非常有价值,有时非常昂贵,必须加以保护。如果您担心您的密钥被泄露,大多数提供商允许您重新生成密钥。
把 config 文件添加到你的 gitignore 文件中,防止它也被推送到你的 repo 中 !
Twitter API
Twitter 提供了大量的数据,很容易通过他们的 API 访问。使用 Tweepy Python 库,可以根据所需主题轻松获取持续的推文流。Twitter 非常适合挖掘趋势和情绪,
对于本教程,你需要在 Twitter 上注册一个应用程序来获得 API 密匙。如果你不熟悉 Twitter 的开发者门户,请查看官方的 Twitter 文档!
使用 pip 安装 Tweepy 和 unidecode。
pip install tweepy
pip install *unidecode*
将以下密钥保存到配置文件中:
使用 Tweepy
将 Tweepy 连接到 Twitter 使用了 OAuth1 。如果您是 API 认证的新手,请查看官方 Tweepy 认证教程。
为了保存来自传入流的数据,我发现最简单的方法是将其保存到 SQLite 数据库中。如果您不熟悉 SQL 表或者需要复习,请查看这个免费网站的示例或者查看我的 SQL 教程。
函数 unidecode() 获取 Unicode 数据,并尝试用 ASCII 字符表示它。
#import dependencies
import tweepy
from tweepy import OAuthHandler
from tweepy.streaming import StreamListener
import json
from unidecode import unidecode
import time
import datetime#import the API keys from the config file.
from config import con_key, con_sec, a_token, a_secret sqlite3conn = sqlite3.connect("twitterStream.sqlite")
c = conn.cursor()
我需要创建表来存储葡萄酒数据。我使用 SQLite 是因为它是轻量级的和无服务器的。另外,我喜欢把所有的数据都放在一个地方!
def create_table():
c.execute("CREATE TABLE IF NOT EXISTS Tweets(timestamp REAL, tweet TEXT)")
conn.commit()create_table()
注意,如果不存在,我使用来确保该表在数据库中不存在。记住使用*conn . commit()*调用提交事务。
创建一个 StreamListner 类
下面是一些样板代码,用于从流 twitter 数据中提取 tweet 和时间戳,并将其插入数据库。
class Listener(StreamListener):
def on_data(self, data):
**try:**
data = json.loads(data)
tweet = unidecode(data['text'])
time_ms = data['timestamp_ms']
#print(tweet, time_ms)
c.execute("INSERT INTO Tweets (timestamp, tweet) VALUES (?, ?)", (time_ms, tweet))
conn.commit()
**time.sleep(2)**
**except KeyError as e**:
print(str(e))
return(True)
def on_error(self, status_code):
if status_code == 420:
#returning False in on_error disconnects the stream
return False**while True**:
try:
auth = OAuthHandler(con_key, con_sec)
auth.set_access_token(a_token, a_secret)
twitterStream = tweepy.Stream(auth, Listener())
**twitterStream.filter**(track=['DataScience'])
except Exception as e:
print(str(e))
time.sleep(4)
请注意,我使用 time.sleep() 来减缓流的速度。
注意,代码被包装在 try/except 中,以防止潜在的中断中断流。此外,文档建议使用一个 on_error() 函数,在应用发出过多请求时充当断路器。
注意,我将流对象包装在一个 while 条件中。这样,如果遇到 420 错误,它就会停止。
注意twitterstream . filter**使用 track 在推文中查找关键词。如果你想关注特定用户的推文,使用 。过滤(follow=[“”]) 。
从 SQLite 数据库中提取数据
sql = '''select tweet from Tweets
where tweet not like 'RT %'
order by timestamp desc'''
tweet_df = pd.read_sql(sql, conn)
tweet_df
示例推文数据帧
Reddit API
像 Twitter 一样,社交网络 Reddit 包含了令人瞠目结舌的大量信息,很容易收集。这是一个像互联网论坛一样工作的社交网络,允许用户发表任何他们想要的话题。用户组成名为 subreddits 的社区,他们对社区中的帖子投赞成票或反对票,以决定哪些帖子先被浏览,哪些帖子沉到底部。
我将解释如何获得 Reddit API 键,以及如何使用 PRAW 库从 Reddit 提取数据。虽然 Reddit 有一个 API ,但是 Python Reddit API 包装器,或者简称为 PRAW,提供了一个简化的体验。PRAW 支持 Python 3.5+版本
Reddit API 入门
需要 Reddit 的用户帐户才能使用 API。这是完全免费的,只需要一个电子邮件地址!
为钥匙注册应用程序
如果有办法使用新的 Reddit 用户界面,请给我留言!如果您是第一次登录 Reddit,请按照以下步骤获取 API 密钥。如果您已经有了密钥,使用此链接转到您的应用页面。
reddit.com 用户帐户按钮
点击用户账号下拉列表。显示用户选项。
从用户选项中点击访问旧 Reddit 。页面会改变,网址会变成 https://old . Reddit . com/
偏好;喜好;优先;参数选择
点击注销按钮旁边的首选项链接。
点击首选项屏幕上的应用标签。
点击你是开发者吗?创建 am 应用程序 …按钮。
注册 Reddit 应用程序
输入一个名。
选择 app 的类型。
输入一个描述。
使用 http://localhost:8080 作为重定向 uri 。
填写完字段后,点击创建应用。
Reddit API 客户端
将显示连接所需的 API 信息。当我开始写代码时,我将通过 PRAW 连接到 API。
祝贺你开始收集 Reddit 数据!
使用 PRAW 提取 Reddit 数据
安装 PRAW 的推荐方法是使用 pip 。安装以下软件包来创建仪表板。
**pip install praw**
首先导入库和配置文件:
import praw
import pandas as pd
from config import cid, csec, ua
创建 Reddit 实例
创建一个只读 Reddit 实例。这意味着我不需要输入用于发布回复或创建新主题的 Reddit 凭据;该连接只读取数据。
PRAW 使用 OAuth 认证来连接 Reddit API。
#create a reddit connection
reddit = praw.Reddit(client_id= cid,
client_secret= csec,
user_agent= ua)
识别子记录
以下是我认为值得探究的一些例子:
新闻,数据科学,学习机器学习,游戏,搞笑,政治
探索对象和属性
使用 PRAW 中的 Subreddit 类从所需的 subreddit 中检索数据。可以根据以下 Reddit 选项对数据进行排序:
- 热门——按访问量最大的帖子排序
- 新 —按帖子最新的帖子排序
- 置顶 —按投票最多的帖子排序
- 上升 —按帖子人气排序
如果您想要包含多个子编辑,请使用 + 符号:
#single subreddit new 5
subreddit = reddit.subreddit('news').new(limit = 5)#multiple subreddits top 5
subreddit = reddit.subreddit('news' + 'datascience').top(limit = 5)
这将返回一个对象,它将数据保存在一个属性中。该属性就像 字典 中的键。
数据链接到对象所拥有的属性。如果属性为键,则数据为值。属性是动态生成的,所以最好使用 Python 的内置 vars() 函数来检查哪些是可用的。
使用这个样板代码来查看代表 reddit 帖子的对象所拥有的所有属性。这是一个很长的列表!
subreddit = reddit.subreddit('news').new(limit = 1)
for post in subreddit:
pprint.pprint(vars(post))
发布对象属性的示例
请注意列表中感兴趣的属性:
标题 —返回文章标题。
得分 —返回赞成票或反对票的数量。
num_comments —返回线程上的注释数量。
selftext —返回帖子的正文。
创建的 —返回文章的时间戳。
钉住 —表示线程是否被钉住。
total _ awards _ received—返回帖子获得的奖项数。
保存 Reddit 数据
既然已经确定了属性,就将它们的数据加载到 pandas 数据帧中,或者保存到 SQLite 数据库中,就像 Twitter 示例中那样。在这个例子中,我将把它保存到一个熊猫数据帧中。
#list for df conversion
posts = []#return 100 new posts from wallstreetbets
new_bets = reddit.subreddit('wallstreetbets').new(limit=100)#return the important attributes
for post in new_bets:
posts.append([post.title, post.score, post.num_comments, post.selftext, post.created, post.pinned, post.total_awards_received])#create a dataframe
posts = pd.DataFrame(posts,columns=['title', 'score', 'comments', 'post', 'created', 'pinned', 'total awards'])#return top 3 df rows
posts.head(3)
天才歌词
我一直是音乐迷,尤其是重金属。在重金属中,歌词有时很难理解,所以我去 Genius 破译它们。网站Genius.com是一个注释歌词、收集关于音乐、专辑和艺术家的琐事的平台。Genius 允许用户注册一个 API 客户端。
https://genius.com/api-clients
API 客户端注册
要么报名,要么签到。
点击开发者链接。
点击创建 API 客户端。
输入一个应用程序名称。
如果有网址就输入网址,否则 http://127.0.0.1 就可以了。
点击保存。将显示 API 客户端。
点击生成访问令牌,生成访问令牌。
API 客户端注册工作流
提取歌词
令人惊讶的是,由于法律原因,Genius API 并没有提供下载歌词的方式。可以搜索歌词,但不能下载。对每个人来说幸运的是,Medium 作者 Ben Wallace 为我们提供了一个方便的抓取歌词的包装器。也可以在 GitHub 上找到他的原始代码:
此时您不能执行该操作。您已使用另一个标签页或窗口登录。您已在另一个选项卡中注销,或者…
github.com](https://github.com/benfwalla/MusicAnalysis)
我修改了他的包装器,以便更容易下载艺术家的完整作品,而不是对我想要包含的专辑进行编码,并且我添加了一个艺术家列来存储艺术家的名字。
包装器使用 API 获取链接到歌词的 URL。从那里,BeautifulSoup 用于解析每个 URL 的 HTML。该过程产生包含标题、URL、艺术家、专辑和歌词的数据帧:
查看 GeniusArtistDataCollect 包装
包装器是一个名为**geniusartisdatacollect()**的类。使用它连接到 API 并检索指定艺术家的歌词。在这个例子中,我使用了我最喜欢的金属乐队之一,黑色大丽花谋杀。
要使用geniusartisdatacollect(),实例化它,传入客户端访问令牌和艺术家名字。
g = GeniusArtistDataCollect(token, 'The Black Dahlia Murder')
从geniusartistdata collect对象中调用 get_artists_songs() 。这将作为熊猫数据帧返回。
songs_df = g.get_artist_songs()
songs_df = g.get_artist_songs()
包装纸
下面是我在示例中使用的修改后的包装器:
import os
import re
import requests
import pandas as pd
import urllib.request
from bs4 import BeautifulSoup
from config import token class GeniusArtistDataCollect:
"""A wrapper class that is able to retrieve, clean, and organize all the album songs of a given artist
Uses the Genius API and webscraping techniques to get the data."""def __init__(self, client_access_token, artist_name):
"""
Instantiate a GeniusArtistDataCollect object
:param client_access_token: str - Token to access the Genius API. Create one at [https://genius.com/developers](https://genius.com/developers)
:param artist_name: str - The name of the artist of interest
THIS HAS BEEN REMOVED :param albums: list - A list of all the artist's albums to be collected
"""self.client_access_token = client_access_tokenself.artist_name = artist_name#self.albums = albumsself.base_url = '[https://api.genius.com/'](https://api.genius.com/')self.headers = {'Authorization': 'Bearer ' + self.client_access_token}self.artist_songs = Nonedef search(self, query):
"""Makes a search request in the Genius API based on the query parameter. Returns a JSON response."""request_url = self.base_url + 'search'
data = {'q': query}
response = requests.get(request_url, data=data, headers=self.headers).json()return responsedef get_artist_songs(self):
"""Gets the songs of self.artist_name and places in a pandas.DataFrame"""# Search for the artist and get their id
search_artist = self.search(self.artist_name)
artist_id = str(search_artist['response']['hits'][0]['result']['primary_artist']['id'])print("ID: " + artist_id)# Initialize DataFrame
df = pd.DataFrame(columns=['Title', 'URL'])# Iterate through all the pages of the artist's songs
more_pages = True
page = 1
i = 0
while more_pages:print("page: " + str(page))# Make a request to get the songs of an artist on a given page
request_url = self.base_url + 'artists/' + artist_id + '/songs' + '?per_page=50&page=' + str(page)
response = requests.get(request_url, headers=self.headers).json()print(response)# For each song which the given artist is the primary_artist of the song, add the song title and
# Genius URL to the DataFrame
for song in response['response']['songs']:if str(song['primary_artist']['id']) == artist_id:title = song['title']
url = song['url']df.loc[i] = [title, url]
i += 1page += 1if response['response']['next_page'] is None:
more_pages = False# Get the HTML, Album Name, and Song Lyrics from helper methods in the class
df['Artist'] = self.artist_name
df['html'] = df['URL'].apply(self.get_song_html)
df['Album'] = df['html'].apply(self.get_album_from_html)
#df['InAnAlbum'] = df['Album'].apply(lambda a: self.is_track_in_an_album(a, self.albums))
#df = df[df['InAnAlbum'] == True]
df['Lyrics'] = df.apply(lambda row: self.get_lyrics(row.html), axis=1)del df['html']self.artist_songs = dfreturn self.artist_songsdef get_song_html(self, url):
"""Scrapes the entire HTML of the url parameter"""request = urllib.request.Request(url)
request.add_header("Authorization", "Bearer " + self.client_access_token)
request.add_header("User-Agent",
"curl/7.9.8 (i686-pc-linux-gnu) libcurl 7.9.8 (OpenSSL 0.9.6b) (ipv6 enabled)")
page = urllib.request.urlopen(request)
html = BeautifulSoup(page, "html")print("Scraped: " + url)
return htmldef get_lyrics(self, html):
"""Scrapes the html parameter to get the song lyrics on a Genius page in one, large String object"""lyrics = html.find("div", class_="lyrics")all_words = ''# Clean lyrics
for line in lyrics.get_text():
all_words += line# Remove identifiers like chorus, verse, etc
all_words = re.sub(r'[\(\[].*?[\)\]]', '', all_words)# remove empty lines, extra spaces, and special characters
all_words = os.linesep.join([s for s in all_words.splitlines() if s])
all_words = all_words.replace('\r', '')
all_words = all_words.replace('\n', ' ')
all_words = all_words.replace(' ', ' ')return all_wordsdef get_album_from_html(self, html):
"""Scrapes the html parameter to get the album name of the song on a Genius page"""parse = html.findAll("span")
album = ''for i in range(len(parse)):
if parse[i].text == 'Album':
i += 1
album = parse[i].text.strip()
breakreturn album
另外两个网页抓取例子
天才歌词示例使用美丽的汤从网站上刮歌词。Web 抓取是一种有用的技术,它使得收集各种数据变得容易。我在上一篇文章中介绍了一个额外的 web 抓取示例。如果你想多加练习,就去看看吧!
我是如何从网上搜集棋盘游戏描述的。
towardsdatascience.com](/web-scraping-board-game-descriptions-with-python-7b8f6a5be1f3)
尽管我还没有使用过他的方法,媒体作家威尔·科尔森已经为搜集和解析维基百科做了一个演示。看看他的作品!
如何以编程方式下载和解析维基百科
towardsdatascience.com](/wikipedia-data-science-working-with-the-worlds-largest-encyclopedia-c08efbac5f5c)
Kaggle 和谷歌数据集搜索
虽然我认为收集和创建自己的数据集很有趣,但 Kaggle 和谷歌的数据集搜索提供了便捷的方法来找到结构化和标签化的数据。Kaggle 是一个流行的竞争数据科学平台。下面是用于 NLP 项目的流行数据集列表。
https://www.kaggle.com/datasetshttps://datasetsearch.research.google.com/
确定新闻故事是否来自洋葱:
Youtube 排名和描述:
网飞展示和说明:
- https://www.kaggle.com/shivamb/netflix-shows
葡萄酒评论。我在几篇文章和项目中使用了它:
- 【https://www.kaggle.com/zynicide/wine-reviews
亚马逊美食评论集:
用于假新闻检测的新闻标题:
实体识别任务语料库。
用于情绪分析的航空公司情绪推文
Yelp 评论数据集
包扎
随着 NLP 变得越来越主流,了解如何轻松收集丰富的、基于文本的数据集变得非常重要。进入自然语言处理领域可能很难,所以我想分享一个指南,简化收集文本数据的方法。只需几行 Python 代码,Reddit、Twitter 和 Genius 上的惊人数据量人人唾手可得!感谢您的阅读,如果您想使用您知道如何收集的数据,请查看我的其他 NLP 相关文章:
谢谢大家!
[## 使用 Python 中的自然语言工具包分析葡萄酒描述
用什么词来形容酒?
towardsdatascience.com](/analyzing-wine-descriptions-using-the-natural-language-toolkit-in-python-497ac1e228d5) [## Python 中的仪表盘,适用于初学者和使用 Dash 的其他人
使用 Python 中的 Dash 初学者教程构建一个基本的和高级的仪表板
medium.com](https://medium.com/swlh/dashboards-in-python-for-beginners-and-everyone-else-using-dash-f0a045a86644) [## 在 SkLearn 中使用 FunctionTransformer 和 Pipeline 预测 Chardonnay 评级
一个将函数转换成可用的管道代码,然后通过传递数据帧来预测葡萄酒评级的例子…
towardsdatascience.com](/using-functiontransformer-and-pipeline-in-sklearn-to-predict-chardonnay-ratings-9b13fdd6c6fd)