TowardsDataScience 博客中文翻译 2019(一百一十)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

编码面试问题-油藏取样

原文:https://towardsdatascience.com/coding-interview-questions-reservoir-sampling-687ff5b6822b?source=collection_archive---------13-----------------------

储层采样是一种从数据流中采样元素的算法。假设您有一个非常大的数据元素流,例如:

  • 6 月对 DuckDuckGo 搜索的查询
  • 圣诞节期间在塞恩斯伯里购买的产品
  • 白皮书指南中的姓名。

让我用这些简单的词语想象一下下面的“约会”游戏节目。参赛选手是一名单身女子,她坐在一张空椅子旁。主持人介绍第一个求婚者;未婚女子不得不邀请他和她坐在一起,成为她目前的“约会对象”。接下来,主持人介绍第二位求婚者。现在女孩可以选择是继续她现在的“约会对象”还是用新的追求者取代他。她可以使用各种手段来做出决定,比如提问或者让两个追求者以某种方式竞争。之后,主持人介绍第三个追求者,女孩可以再次选择保留或替换她现在的“约会对象”以这种方式展示了 n 个追求者后,游戏节目结束,女孩与她在最后保留的追求者,即节目的“赢家”进行真正的约会。

想象一下,一个参赛者仅仅通过抛硬币来决定是否交换她现在的“约会对象”。这对追求者“公平”吗,也就是说,获胜者的概率分布在所有追求者中是一致的吗?答案是否定的,因为最后几个追求者比最初几个追求者更有可能获胜。第一个求婚者是最不幸的,因为如果他想和女孩约会,他必须通过 n- 1 次抛硬币。最后一个求婚者的机会最大——他只需要赢得一次抛硬币的机会

import random

def reservoir_sampling(iterator, k):
    result = []
    n = 0
    for item in iterator:
        n = n + 1
        if len(result) < k:
            print(result)
            result.append(item)
        else:
            j = int(random.random() * n)
            if j < k:
                result[j] = item
                print('else:', result)

    return result

if __name__ == "__main__":
    stream = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
    k = 5
    print(reservoir_sampling(stream, k))

干杯,
扎伊德·阿里萨·阿尔马利基

在 Udemy 上用 python 查看我们的免费课程 AWS。

感谢阅读。如果你喜欢这篇文章,请点击下面的按钮,这样我们就可以保持联系。

将 Python 脚本变成漂亮的 ML 工具

原文:https://towardsdatascience.com/coding-ml-tools-like-you-code-ml-models-ddba3357eace?source=collection_archive---------1-----------------------

介绍专为 ML 工程师打造的应用框架 Streamlit

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Coding a semantic search engine with real-time neural-net inference in 300 lines of Python.

根据我的经验,每一个重要的机器学习项目最终都是由充满 bug 和不可维护的内部工具拼接而成的。这些工具通常是 Jupyter 笔记本和 Flask 应用程序的拼凑物,难以部署,需要对客户端-服务器架构进行推理,并且不能与 Tensorflow GPU 会话等机器学习结构很好地集成。

我首先在卡内基梅隆大学看到这一点,然后在伯克利,Google X,最后在 Zoox 建造自主机器人。这些工具通常是作为小 Jupyter 笔记本诞生的:传感器校准工具、模拟比较应用程序、激光雷达对准应用程序、场景回放工具等等。

随着工具变得越来越重要,项目经理开始介入。进程萌芽。需求开花了。这些单独的项目孕育成脚本,并发展成瘦长的维护噩梦。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The machine learning engineers’ ad-hoc app building flow.

当一个工具变得至关重要时,我们召集工具团队。他们写出了流畅的 Vue 和 React。他们在笔记本电脑上贴上了关于声明性框架的标签。他们有一个设计流程:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The tools team’s clean-slate app building flow.

太棒了。但是这些工具都需要新的功能,比如周刊。工具团队正在支持另外十个项目。他们会说,“我们会在两个月后再次更新你的工具。”

所以我们回到了构建自己的工具,部署 Flask 应用程序,编写 HTML、CSS 和 JavaScript,并试图对从笔记本到样式表的一切进行版本控制。所以我的 Google X 老朋友 Thiago Teixeira 和我开始思考下面这个问题:如果我们能让构建工具像编写 Python 脚本一样简单会怎么样?

我们希望机器学习工程师能够创建漂亮的应用程序,而不需要工具团队。这些内部工具应该是 ML 工作流的自然副产品。编写这样的工具应该感觉像是在 Jupyter 中训练一个神经网络或者执行一个特别的分析!同时,我们希望保留强大应用框架的所有灵活性。我们想创造漂亮的、高性能的工具,让工程师们炫耀。基本上,我们想要这个:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The Streamlit app building flow.

有了一个包括来自优步、Twitter、Stitch Fix 和 Dropbox 的工程师在内的令人惊叹的 beta 社区,我们花了一年时间创建了 Streamlit ,这是一个面向 ML 工程师的完全免费和开源的应用框架。随着每个原型的出现,Streamlit 的核心原则变得更加简单和纯粹。它们是:

第一:拥抱 Python 脚本。 Streamlit 应用实际上只是自上而下运行的脚本。没有隐藏状态。你可以用函数调用来分解你的代码。如果你知道如何编写 Python 脚本,你可以编写 Streamlit 应用程序。例如,这是您在屏幕上书写的方式:

import streamlit as stst.write('Hello, world!')

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Nice to meet you.

**#2:将小部件视为变量。**Streamlit 中没有的回调!每次交互只是从头到尾重新运行脚本。这种方法会产生真正干净的代码:

import streamlit as stx = st.slider('x')
st.write(x, 'squared is', x * x)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

An interactive Streamlit app in three lines of code.

#3:复用数据和计算。如果下载大量数据或执行复杂计算会怎样?关键是跨运行安全地重用信息。Streamlit 引入了一个缓存原语,其行为类似于一个持久的、默认不变的数据存储,使 Streamlit 应用程序能够安全、轻松地重用信息。例如,这段代码只从 Udacity 自动驾驶汽车项目下载一次数据,从而生成一个简单、快速的应用程序:

Using st.cache to persist data across Streamlit runs. To run this code, please follow these instructions.

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The output of running the st.cache example above.

简而言之,Streamlit 是这样工作的:

  1. 对于每个用户交互,整个脚本都是从头开始运行的。
  2. Streamlit 给每个变量分配一个给定小部件状态的最新值。
  3. 缓存允许 Streamlit 跳过冗余的数据获取和计算。

或者在图片中:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

User events trigger Streamlit to rerun the script from scratch. Only the cache persists across runs.

如果这听起来很有趣,你现在就可以试试!只需运行:

$ pip install --upgrade streamlit 
$ streamlit hello **You can now view your Streamlit app in your browser.** **Local URL:** [http://localhost:8501](http://localhost:8501)
   **Network URL:** [http://10.0.1.29:8501](http://10.0.1.29:8501)

这将自动弹出一个指向您的本地 Streamlit 应用程序的 web 浏览器。如果没有,就点击链接。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

To see more examples like this fractal animation, run streamlit hello from the command line.

好的。你从玩分形回来了吗?这些都很迷人。

这些想法的简单性并不妨碍您使用 Streamlit 创建极其丰富和有用的应用程序。在 Zoox 和 Google X 工作期间,我目睹了自动驾驶汽车项目膨胀到数十亿字节的视觉数据,这些数据需要搜索和理解,包括在图像上运行模型以比较性能。我见过的每个自动驾驶汽车项目最终都有整个团队在开发这种工具。

在 Streamlit 中构建这样一个工具很容易。这个 Streamlit 演示可以让你在整个 Udacity 自动驾驶汽车照片数据集中执行语义搜索,可视化人类注释的地面真相标签,从应用程序内实时运行完整的神经网络(****)[1]。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

This 300-line Streamlit demo combines semantic visual search with interactive neural net inference.

整个 app 是一个完全独立的 300 行 Python 脚本,大部分是机器学习代码。其实整个 app 只有23 个 Streamlit 调用。你现在就可以自己运行了!

$ pip install --upgrade streamlit opencv-python
$ streamlit run
[https://raw.githubusercontent.com/streamlit/demo-self-driving/master/app.py](https://raw.githubusercontent.com/streamlit/demo-self-driving/master/app.py)

当我们与机器学习团队在他们自己的项目上合作时,我们逐渐意识到这些简单的想法产生了许多重要的好处:

****Streamlit 应用是纯 Python 文件。这样你就可以通过 Streamlit 使用你最喜欢的编辑器和调试器了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

My favorite layout for writing Streamlit apps has VSCode on the left and Chrome on the right.

纯 Python 脚本与 Git 和其他源代码控制软件无缝协作,包括提交、拉请求、发布和注释。因为 Streamlit 的底层语言是纯 Python,所以您可以免费获得这些令人惊叹的协作工具的所有好处🎉。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Because Streamlit apps are just Python scripts, you can easily version control them with Git.

Streamlit 提供了一个即时模式的实时编码环境。只需点击当 Streamlit 检测到源文件改变时,总是重新运行

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Click “Always rerun” to enable live coding.

****缓存简化了计算管道的设置。令人惊讶的是,链接缓存函数会自动创建高效的计算管道!考虑这段代码改编自我们的 Udacity 演示:

A simple computation pipeline in Streamlit. To run this code, please follow these instructions.

基本上管道就是 load_metadata → create_summary。每次运行脚本时 Streamlit 只重新计算获得正确答案所需的管道子集。酷!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

To make apps performant, Streamlit only recomputes whatever is necessary to update the UI.

Streamlit 是为 GPU 打造的。 Streamlit 允许直接访问机器级原语,如 TensorFlow 和 PyTorch,并补充这些库。例如在这个演示中,Streamlit 的缓存存储了整个 NVIDIA 名人脸甘【2】。当用户更新滑块时,这种方法可以实现几乎即时的推断。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

This Streamlit app demonstrates NVIDIA celebrity face GAN [2] model using Shaobo Guan’s TL-GAN [3].

Streamlit 是一个免费的开源库,而不是专有的网络应用。您可以在内部提供 Streamlit 应用程序,无需联系我们。您甚至可以在没有互联网连接的笔记本电脑上本地运行 Streamlit!此外,现有项目可以逐步采用 Streamlit。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Several ways incrementally adopt Streamlit. (Icons courtesy of fullvector / Freepik.)

这只是您可以用 Streamlit 做的事情的皮毛。Streamlit 最令人兴奋的一个方面是如何将这些原语轻松组合成看起来像脚本的复杂应用程序。关于我们的架构如何工作以及我们计划的功能,我们还有很多可以说的,但我们将把这些留到以后的帖子中。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Block diagram of Streamlit’s components. More coming soon!

我们很高兴今天终于与社区分享了 Streamlit,并看到你们都用它构建了什么。我们希望你会发现把你的 Python 脚本变成漂亮的 ML 应用程序是一件简单而愉快的事情。

感谢 Amanda Kelly、Thiago Teixeira、TC Ricks、Seth Weidman、Regan Carey、Beverly Treuille、Geneviève Wachtell 和 Barney Pell 对本文的有益贡献。

参考文献:

[1] J .雷德蒙和 a .法尔哈迪,约洛夫 3:一种增量改进 (2018),arXiv。

[2] T. Karras、T. Aila、S. Laine 和 J. Lehtinen,为提高质量、稳定性和变化而逐步种植甘蔗 (2018),ICLR。

[3] S. Guan,使用新型 TL-GAN 模型控制图像合成和编辑 (2018),洞察数据科学博客。

咖啡数据表

原文:https://towardsdatascience.com/coffee-data-sheet-d95fd241e7f6?source=collection_archive---------15-----------------------

咖啡数据科学

我想要的圣诞礼物就是数据

那是 2018 年的圣诞节,我想要的只是一杯来自 la Pavoni 的浓咖啡。我很少使用这台机器,我遇到了麻烦。在阅读了关于预热的内容后,我决定需要收集我拍摄的数据,以确保我对常规的改变有所帮助。我一点也不知道,数据表将成为最有用的工具,使惊人的浓缩咖啡,并扩大到改善我的咖啡烘焙。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我没有开始跟踪我的镜头,因为我认为这是一些伟大的想法。这更多的是一种好奇心,它变成了我用来改进我的浓缩咖啡的最伟大的工具:数据。一个有趣的回顾目标是能够回顾历史数据,因为有些时候,直到数据可用时,价值才完全为人所知。

诚实是数据手册的关键。没有诚信,史料毫无意义。没有诚实,就不可能改进你的浓缩咖啡。有时,我想打得更高,因为我认为应该更高,或者我在考虑平均得分,但我真的想在我的评估中保持诚实,以便随着时间的推移,我可以打出我一生中最好的投篮。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

最终,随着时间的推移,关键目标演变为以下五项:

  1. 镜头改进
  2. 充分利用每台浓缩咖啡机
  3. 豆子实验
  4. 方法调整中的未来未知发现
  5. 腭校准

输入变量

输入变量应该是最可控的,并且在各次拍摄中保持一致。咖啡重量最容易用秤控制。

你也可以测量水温,93 摄氏度被广泛认为是最佳温度。我做过一个关于预热云台的水温的小研究,但是我没有具体测量过每次拍摄的温度。这是一个可以改进的领域,但我的大多数机器,我知道在它们过热之前什么时候停止射击。

其他输入变量是咖啡烘焙、日期、时间、每层重量(对于断奏),我还添加了一些其他可选的比特,如添加的罗布斯塔或水库的水位。

过程变量

我已经记录了预输注、开花和提取的时间,但是一旦我调整了我的方法,我经常不计时。我记录了我的许多镜头,以帮助回顾镜头是如何从无底的 portafilter 开始的。这一点数据对我改善咖啡分配、调整研磨以及平衡断奏层次也很重要。

我有几个单元格用来记笔记。我改变了什么细微的变化,或者一些我没有全时间跟踪的变量。最后,还有一个下次做什么的单元格。大多数时候,我能记得下一步要做什么,但仅仅是记录这些笔记的过程就帮助提高了我的记忆能力。一般来说,在课堂上、工作中或家里记笔记对我帮助很大。

输出变量

有两种类型的输出变量:定量和定性。对于定量指标,我测量输出重量并计算咖啡中的咖啡渣。有一段时间,我校准了我的咖啡杯,测量了可溶物的百分比,但是我有一段时间没有这样做了。我也拍过相当多的照片,我本可以尝试使用图像处理分析来调查色差,但我没有。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对于定性指标,我衡量七个品质:尖锐,丰富,糖浆,甜,酸,苦,回味。如果我是一个 Q 级学生,我可以使用这些标准,但是,唉,我不是。前三个测量值需要解释,因为其他四个是不言自明的。

尖锐是指当浓缩咖啡第一次触及你的舌头时的尖锐度,以及它对你的口味有多震撼。我不喜欢因为喝了这么烈的东西而咳嗽,但这是我喜欢的尖锐的标志。这个标准的一个问题是,一个平滑的镜头不会很锐利,但这并不意味着它是一个糟糕的镜头。因此,这让我开始审视我所使用的衡量标准的变化,甚至是通过 Q-gradier 认证。

丰富是指镜头整体的丰富和复杂。我更喜欢 1:1 的比例(输入重量与输出浓缩咖啡的重量),因为我想重温我喝的第一杯浓缩咖啡。我的第一枪尝起来就像在嘴里融化了一块巧克力;它完全占据了我的舌头。

糖浆指的是质地,我的目标是我记忆中的第一次拍摄。浓咖啡在我的舌头上感觉很浓,像糖浆或融化的巧克力。

当我查看 Q 等级的时候,我发现了一些和我相似的描述。请记住,虽然 Q 级不是在浓缩咖啡上完成的。这是一张与我的 Q 等级最接近的表格。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

最后,我得出一个平均分,它包含这七个指标,并将它们与投入产出比的加权值相结合。我考虑过在计算中去掉这个比例,因为我用了一个上面有测量标记的杯子。这个杯子让我每次都能打到 0.8 到 1.1 之间的比率。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

My current cup

校准

我从一个小规模(0,1,2)开始。我不知道我能在多大程度上区分不同的级别,我想我会从小做起,然后根据需要扩展。最初,我开始用 Hario 研磨机给照片评分,因为我在圣诞假期。当我回到家里,使用我的 Rok grinder 和 Kim Express,我必须迅速将我的规模从 0 扩大到 4。

然后是断奏。老实说,我没想到一个断奏的镜头会做得这么好。当我开始尝试时,我开始在某些类别中看到 5 和 6。随着我对各层如何相互作用有了更好的理解,我能够让每个分数类别上升。我从两层迁移到三层,我看到平均分从 4 到 7。

最近,我用一些我一直在调整的专业烘焙达到了 9 分甚至更高。用于烘烤的数据需要进一步讨论。

时不时地,我会在咖啡店,喝着劣质咖啡,或者在家里用我的 superautomatic 检查我的校准。虽然糟糕的击球并不总是有趣的,但它肯定了我的底线,并让我看到那些击球做得好的地方。

在意大利的时候,我拍了一些照片,我真的注意到那些照片中我喜欢的东西是我的照片中没有的。我确定我错过了使用 robusta 的机会,这促使我尝试调整 Robusta 的百分比,以获得我想要的平衡。意大利酒有更好的丰富性、酸味和回味,但它们不甜。它们是苦的,但没有烧焦。有区别…

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Coffee Shops have the roast highlighted in Red. Noticed how the score patterns are quite different.

多台机器

这个数据收集的有趣部分是在多台机器上工作。我在工作中有一个金快车,这是我的底线。我用那台机器拍出了最好的照片,因为我已经用了五年了。根据过去六个月的数据,我在六个月内打了 200 针,所以一年 400 针乘以五年就是 2000 针。

我买了一个意大利的 Enrico,我把它放在我工作的实验室里。这是一台好机器,但我用得不多了。那台机器的事故率比 Kim 高得多(30 分之一对 2000 分之二)。

在家里,我有一个奥利奥 Giro,Flair,La Peppina 和一个新收购的 Kim Express。我买了新的 Kim Express,因为它需要很多爱,我想在工作和家里有同样的体验。

我在家里用 Flair 拍摄的照片比其他任何机器都多。我几乎放弃了这台机器,因为我遇到了一些麻烦,但我最终找到了一些技巧,特别是对于断奏镜头,这使它能够产生与 Kim 一样的镜头。

数据

我们来看一些数据。首先,让我们来看一段时间内的镜头对比。通常,潮起潮落取决于一颗咖啡豆。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

查看数据的另一种方式是每台机器每次烘烤的最高得分或射击次数。它展示了我如何使用每台机器以及我的照片如何改进它们的有趣旅程。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在更高的水平上,我似乎每天要喝 2 到 4 杯,每次烧烤我要喝接近 20 杯。一份烤肉通常是 350 克到 300 克,所以每份 15 克意味着大约 20 份。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

随着时间的推移,烘焙的平均分数会随着咖啡豆的老化而变化。我尤其能从一些一开始就含有大量克莉玛的豆子中分辨出来,这些克莉玛随后逐渐减少。这是另一种方法来观察每次烘烤的次数以及理解每次烘烤的次数。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我甚至可以看烤后的照片。我们可以通过每次烘焙将这些分数标准化,然后将它们结合起来,以更深入地了解何时是煮浓缩咖啡的最佳时间。烘焙后两周似乎是一个很好的峰值,但我没有足够的烘焙后数据来了解这种味道何时开始变味。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在我的断奏实验中,我得到了大量的数据。下面是我截取数据的几种方法,来展示断奏是如何比常规击球提高击球质量的。我已经控制了烘烤和机器。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1. Green (Staccato > Regular) , Red (Regular > Staccato). 2. Scatter Plot with red-line to show no difference

我可以把更多的注意力放在两台机器上:Kim Express 和 Flair Espresso。就解决方案而言,它似乎在一定程度上提高了提取率。我开始注意到缺乏相关性,我怀疑萃取可溶物并不是浓缩咖啡质量分级的全部指标。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

While percent solubles is an interesting metric, it doesn’t predict taste (i.e. Score) well.

上帝开枪了

我曾经认为我可以实现某种“神射”一个如此惊人的镜头,会毁了所有其他镜头。我已经打了很多次这种球,以至于我认为这只是一个梦,一个我会对我的球的味道感到满意的幻想。我没有吹牛的意思;我的意思是说,我已经达到了一些我以前没有达到的浓缩咖啡的水平,然后就变得正常了。

根据我的数据,在 604 次投篮中,我有 40 次是之前所有投篮中最好的,占 6.6%。也就是平均每 18 次注射,或者大约每 4 天注射一次。我还没有完全看到一个高原。

对我来说,真正的上帝拍摄是我的第一次拍摄。你永远不能重复第一次。我甚至不知道我在做什么。我去了一家咖啡馆,点了菜单上最便宜的饮料。碰巧是浓缩咖啡,很棒。上颚知道,第一枪的锋利永远不会重复。

我的希望是,保持数据表或拍摄日志可以帮助你提高你的拍摄;至少让你看到自己喜欢什么,不喜欢什么。我的类别是我正在寻找的东西,但它们不必对你一样。我还收集额外的数据,因为你永远不知道将来什么时候会需要这些数据。

如果你愿意,可以在 Twitter 和 YouTube 上关注我,我会在那里发布不同机器上的浓缩咖啡视频和浓缩咖啡相关的东西。你也可以在 LinkedIn 上找到我。

我的进一步阅读:

我的咖啡设置

断续浓缩咖啡:提升浓缩咖啡

工匠咖啡价格过高

被盗浓缩咖啡机的故事

平价咖啡研磨机:比较

浓缩咖啡:机头温度分析

浓缩咖啡过滤器分析

便携式浓缩咖啡:指南

克鲁夫筛:一项分析

浓缩咖啡中咖啡溶解度的初步研究

原文:https://towardsdatascience.com/coffee-solubility-in-espresso-an-initial-study-88f78a432e2c?source=collection_archive---------14-----------------------

大约一年前,我开始收集我的浓缩咖啡的数据,但是我不太喜欢收集的一个指标是溶解度。我在早期进行了一些测量,但我无法证明花几百美元买一个高科技 TDS 测量工具是合理的。最后,我买了一个折射计,我开始收集一些有趣的数据。它改变了我对浓缩咖啡的看法,比我想象的要大得多。

溶解度是溶解在杯中的咖啡量,它也告诉你你从咖啡杯中提取了多少咖啡。通常,这是用 TDS 或总溶解固体来衡量的。人们可以通过知道浓缩咖啡的重量来推算出提取的咖啡量。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Typical views during espresso and collecting data.

要测量溶解度,最好的是一台数字折光仪。它们很贵。有更便宜的折射计,但是它们需要更多的努力来进行测量。我还用校准过的杯子做了试验。我拍了一个玻璃杯子慢慢装满水的视频。然后当我拍摄的时候,我会把拍摄的地方和视频进行比较。水印处的重量差就是溶解的咖啡量。这种方法是最不精确的。

我选择了一个便宜的折射仪来测量白利糖度。然后用一些等式得出有趣的数据:

  1. TDS = 0.85 *白利糖度/ 100
  2. 咖啡提取= TDS *输出压力
  3. 提取的咖啡百分比=提取的咖啡/输入咖啡重量

浓缩咖啡的常识来看,一杯好的咖啡会提取出 18%到 22%的咖啡。一颗咖啡豆大约有 30%是可溶的,你不会想要所有能溶解的东西。同样的豆子,不同的冲泡,无论好坏,味道都会不一样。这就是为什么许多人煮浓缩咖啡时非常小心地控制研磨粒度、温度、压力、提取次数和提取量。

然而,那里的信息只使用单点数据,即在拍摄结束时测量的 TDS。典型地,该镜头是 3:1 的镜头。作为一名数据科学家,我想超越这一点。我想知道镜头里发生了什么。

我决定进行两个初步实验:

  1. 在提取过程中在多个点测量 TDS,以观察其如何发展。
  2. 对于我拉的每一杆,定期测量 1:1 和 3:1 杆的 TDS。我称之为第一部分(1:1)和测量第二部分,如果与第一部分相结合,将给出一个 3:1 镜头。

实验 1:整个拍摄过程中的可解性

如何收集溶解度随时间的变化?一个冰块托盘或许多杯子。我最初的几次尝试是用冰块托盘。困难在于测量每个立方体中液体的重量。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

所以我做了一些实验。前两次尝试很有趣;我看了看镜头最后提取的咖啡总量。

第二个镜头有点呛,但超过一半的咖啡提取发生在镜头的第一个 1:1 体积。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

让我们再试一次。利用金快递和 7 cups,我重新收集了数据。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

结果告诉我们同样的故事,大多数提取发生在最短的位。你能打出的最短的 ristretto 球。ristretto 镜头通常被定义为 1:1 的比例和 2:1 的比例之间。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

实验 2:多次拍摄的可解性

仔细看看镜头的第一和第二部分,很明显大部分提取都在第一部分。第一部分是 1:1 输出,第二部分是第一次拍摄后发生的 2:1 输出。将第一部分和第二部分组合起来,得到一个接近 3:1 比例的镜头(被认为是短镜头)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

为了进一步探索这个概念,我绘制了上个月的 78 张照片。我绘制了断奏镜头和常规镜头,尽管我画的大多是断奏。我把第一部分和最后的摘录放在同一个图上。虽然每次拍摄只有两个数据点,但是数据的趋势很明显。然后我画出了镜头第一部分最终提取的百分比。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The Red circles are regular shots, and the green and blue ones are staccato shots.

人们可能希望考虑溶解度随时间的变化。为了了解这一点,我在 Kim Express 上使用了一个或多或少保持一致的断续镜头,观察了一次烘焙(2019 年 11 月 9 日)的溶解度和我的主观口味评分。结果是不确定的,但是似乎咖啡的质量并没有随着时间的推移而下降(10/18 到 11/8 或 3 周)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

至于主观分数,让我们看看最终的主观分数是否会随着提取咖啡的百分比而变化。这似乎是松散相关的,我的经验是,在温度或压力方面提取的微小变化可以提供相同的咖啡提取,但不同的味道(更甜或更苦)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这些结果对我来说只是个开始。我喜欢实验,我会继续追踪溶解度。有时,很难看出跟踪多个变量将如何帮助改善我的浓缩咖啡体验,但即使是这样大量的数据也清楚地表明了一些事情:

  1. 提取超过 1:1 的比例可能是过度提取的咖啡,因此应该避免。如果你想要更多的液体,你最好进行 1:1 的提取,然后加入你想要的水量以获得正确的体积,而不是继续提取。
  2. 断续镜头的提取比常规镜头高。这些实验已经用主观味觉评分验证了我的经验。我会注意到我把第二部分和牛奶混合在一起了,但是味道不一样。有时它是有用的。
  3. 使用溶解度和提取的咖啡来比较浓缩咖啡的方法应该在提取过程中的多个点小心进行。单一溶解度指标可能会遗漏镜头中发生的事情。这在断奏镜头中特别有趣,它们有相似的最终提取百分比,但在 1:1 的比例点,它们的值要高得多。
  4. 高萃取并不意味着你有合适的口味。获得正确的风味提取可能很棘手。

如果你愿意,可以在 TwitterYouTube 上关注我,我会在那里发布不同机器上的浓缩咖啡照片和浓缩咖啡相关的视频。你也可以在 LinkedIn 上找到我。

我的进一步阅读:

我的咖啡设置

断续浓缩咖啡:提升浓缩咖啡

咖啡数据表

一台用于制作优质浓缩咖啡的叶片研磨机

工匠咖啡价格过高

被盗浓缩咖啡机的故事

买得起的咖啡研磨机:比较

浓缩咖啡:群头温度分析

浓缩咖啡过滤分析

便携式浓缩咖啡:指南

克鲁夫筛:一项分析

纽约的咖啡趋势

原文:https://towardsdatascience.com/coffee-trends-in-nyc-b6f44a516e96?source=collection_archive---------20-----------------------

建立一个模拟器来分析枫糖浆咖啡的趋势

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Photo by Mohamed Hassan

谁不喜欢枫糖浆?大多数人,其实是因为他们从来没有机会去品尝。加拿大魁北克省生产了全球 70%的枫糖浆。在我住在蒙特利尔的这段时间里,我遇到过许多外国游客,他们带着尝枫糖浆的愿望来到这里。他们不只是想要枫糖浆,他们想要他们能找到的最好的纯加拿大枫糖浆。这让我想知道加拿大以外对加拿大枫糖浆的需求会是什么样的。*其他国家想要更多吗?*我通读了 Reddit 上关于枫糖浆的对话,作为发展我对这个问题的直觉的第一步。几种模式很快显现出来:

  • 在欧洲和澳大利亚,有许多人要么不容易获得枫糖浆,要么没有意识到他们有。尽管他们中的许多人很好奇想尝试一下。
  • 大多数尝过枫糖浆的人都以积极的热情谈论它。
  • 许多尝过枫糖浆的人对使用玉米糖浆的枫糖浆仿制品不以为然,比如杰迈玛阿姨和巴特沃斯夫人的。
  • 如果许多美国人知道枫糖浆产自加拿大,他们会更加珍惜它。
  • 大多数尝过用枫糖浆代替糖搅拌的咖啡的人对此赞不绝口。

最让我感兴趣的是最后两个观察结果。如果我是一个繁荣的、热爱咖啡的美国城市的加拿大枫糖浆咖啡潮流的幕后推手,会怎么样?纽约市完全符合这个描述,因此这个项目诞生了。

想法:蝴蝶效应

我一直在构建一个模拟器,让我能够分析纽约市咖啡店中可能出现的潜在趋势,特别是在加拿大枫糖浆咖啡的背景下。潜在的想法是,当一家咖啡店决定采用一种趋势时,它会对附近的竞争对手产生理论上的影响,让他们也这样做,这种影响会波及整个咖啡店网络。我使用概率论来模拟这个项目数据集中每个商店的趋势采用概率,并使用图论来模拟商店网络。网络可以被看作一个简单的图,其中每个商店是一个节点,两个节点之间有一条边当且仅当它们在地理上足够近。每个节点的趋势采用概率不仅取决于与其自身直接相关的特征,还取决于网络中其他节点的特征和采用概率。到目前为止,我已经完成了模拟器的第一个版本,我将在本文的最后讨论它。计划是在迭代中建立模拟器,从简单的开始,逐渐增加到决定网络如何随时间更新的条件列表中。

数据准备

我收集的数据是关于纽约的咖啡店的。为了获得这些数据,我使用了一个流行的餐馆评论网站的 API 来搜索 9 个与咖啡相关的词(“咖啡”、“咖啡馆”、“浓缩咖啡”、“拿铁”、“卡布奇诺”、“玛奇朵”、“美式咖啡”、“摩卡咖啡”、“无咖啡因咖啡”),搜索了 6 个地点(“纽约市”及其 5 个区,“斯塔滕岛”、“布鲁克林”、“曼哈顿”、“皇后区”、“布朗克斯”),总共进行了 54 次搜索。返回的数据是 JSON 格式的,所以我用 Python 构建了一些函数,允许我将它转换成我可以探索的熊猫数据帧。

探索性数据分析

咖啡店位置

当我最终在表格中准备好数据后,我首先好奇的是咖啡店是如何分布在纽约市的。通过创建一张纽约市地图,在每个商店的位置都标上一个点,我可以更好地了解网络是如何组织的,特别是,哪些区域有密集的咖啡店,哪些没有。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

地图会立即显示许多不属于数据集中的点。至少满足以下三个要点之一的任何点都需要删除:

  • 经度超出了纽约市的经度范围。
  • 纬度超出了纽约市的纬度范围。
  • 坐标在纽约市的经度和纬度范围内,但点不在纽约市本身。

移除满足前两个要点中任何一个的点相当于在谷歌地图上点击纽约市最西、最东、最南、最北点附近的地图,以估计其经度和纬度范围,然后过滤掉不在这些范围内的点。位于经度和纬度范围内但在纽约市之外的点要移除就有点棘手了。我构建了三个函数来过滤掉这些点,一个移除输入点西北方向的所有点,一个移除输入点东北方向的所有点,一个移除输入点东南方向的所有点。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

All points north-west of A, north-east of B or south-east of C will be removed by the functions.

这些函数迭代地应用于具有各种输入点的数据集,这些输入点是从谷歌地图中精心选择的,不会删除来自纽约市的任何点。这产生了一个数据集,该数据集根据需要仅捕获纽约市的咖啡店。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

更新后的地图显示,曼哈顿和布鲁克林北部的咖啡店密度很高。另一方面,相对而言,斯塔滕岛、皇后区和布朗克斯区似乎缺少咖啡店。在构建模拟器时了解这一点很有用;据推测,更有可能的是,一种趋势会在一个咖啡店密集的地区传播开来。

咖啡店特色

此时,数据集包含 4036 行,每行对应于纽约的一家咖啡店。我研究了三个特别感兴趣的特性,因为它们是构建模拟器的关键:

  • 评论:评论数;代表评级的样本量
  • 评级:以 0 到 10(含)的整数值为级别的分类
  • 价格:等级分类 xxxxxxxxxx;更多的 x 意味着更贵的商店

因为评级依赖于评论,分析评论显然是单变量分析的首选。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

你可能以前听过:一个公司 80%的销售额来自 20%的产品;一个学生 80%的生产力是由他或她的 20%的任务产生的;80%的犯罪是由 20%的罪犯犯下的;20%的啤酒饮用者饮用了 80%的啤酒。这就是80–20 法则,或者帕累托原理,它观察到在各种各样的因果自然现象中,绝大多数的影响(通常在 80%左右)是由一小部分原因(通常在 20%左右)产生的。在这个项目的数据集中,69%的评论是由评论数量排名前 20%的咖啡店产生的,这足以表明帕累托原则在这里正在暴露自己。每当我有一个可以被描述为自然现象的连续变量时,我喜欢进行这种验证,以此来证明我的数据集没有偏差。如果的评论不遵循指数分布,我会怀疑我的数据集对纽约所有咖啡店的代表性。

核密度估计图(直方图的连续模拟)显示大多数商店的评论少于 250 条。进一步检查评论的汇总统计数据显示,该特性的范围从 1 到 7693(表明可能有许多异常值),中位数为 86,平均值为 207。平均值远高于中值,因为评论向右倾斜。更好地熟悉这个功能是必要的,因为模拟器将以这样一种方式构建,即评论越多的商店在网络中就越有影响力。

接下来,我想分析两个分类特征,价格评级。我决定将等级视为分类等级,因为它只有 11 个可能的整数值,可以认为是类。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在涉及*价格的双变量分析中,观察到最高价格水平的商店如此之少是很重要的。*这表明 xxxx 商店的样本量很小,因此我们在分析它们时应该犹豫不决,不要轻易下结论。尽管如此,这些商店对模拟器来说还是很重要的,因为它的建造方式是昂贵的商店比便宜的商店对他们的竞争对手有更大的影响。

同样值得注意的是,的评分偏左,在三个最低评分(0,1,2)中的任何一个中,都有不可见数量的商店。模拟器会将较高的影响力分配给具有较高评级的咖啡店。我将使用各种评级的相对计数来帮助校准评级对一家商店在网络中对其邻居的影响有多强。因为条形图显示高评分的商店并不少见,所以如果条形图向右倾斜,我会给这些商店分配较少的影响。

现在我对这三个特性的分布有了更好的了解,是时候成对比较这些特性了,从评级价格开始。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

单变量分析显示,不同水平的价格的样本量差异很大,因此在价格上涨时比较评级的相对计数比绝对计数更有意义。随着价格增加,等级增加。通过观察发现,最低评级商店的评级随着价格的增加而增加。此外,评分低于 7 的商店比例——也就是橙色区域占条形总面积的比例——随着价格的增加而减少。第二种模式在最高价格水平下有些失效,但这可以解释为由 xxxx 商店的小样本量引起的差异。因为更贵的商店往往获得更高的评分,他们似乎更成功,因此更愿意尝试新的趋势。这种洞察力将用于模拟器的初始化步骤,随机选择的商店采用枫糖浆趋势;更昂贵的商店将被分配更高的初始化概率。

接下来我比较了价格评论

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Because reviews has an extreme outlier at 7693, I decided to restrict this feature for the left graph so as to avoid vertically compressing the boxplots. By imposing the restriction that reviews≤1000, the resulting boxplots are legible at the cost of only 3.3% of the data that was ultimately filtered out.

对于前三个水平,随着价格的增加,评论的第一个四分位数、中间值和第三个四分位数也增加。 xxxx 类中的商店不遵守这种模式,但同样,这种商店的样本量很小,所以我们不应该过于相信数据告诉我们的关于它们的信息。价格评论正相关,这一点令人放心,因为已经确定它们都将积极推动模拟器中的趋势采用概率。

为了总结双变量分析,我比较了评级评论

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

散点图显示,评论随着评分的增加而增加,但是因为有太多评分为 7、8 或 9 的点不明显可见,所以我决定查阅评论的汇总统计。从表中我们可以看到,随着评级从 2 增加到 8,平均值和前三个四分位数都在增加;从 2 到 9,最大值在增加。对于评分为 9 的商店,中间值和前三个四分位数也相对较大,只是没有评分为 8 的商店那么大。

因为评级评论正相关,而评论代表评级的样本量,评级越高的店铺,其评级越可信。了解这一点对模拟器很有用,因为它告诉我应该将较高的方差分配给与较低评级商店的影响相关联的概率分布。

在这一点上,随着评级价格同时上涨,评论也在上涨,这并不奇怪:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Heatmaps for reviews≤1000. Grey rectangles correspond to (price, rating) pairs that do not occur in the data.

这有助于进一步巩固从价格评论评级评论的双变量分析中得出的结论。

咖啡店作为一个网络

用图论对网络建模

数据集中的咖啡店网络可视为一个简单的图表。每个咖啡店是图中的一个节点,当且仅当一对节点在地理上足够接近时,这一对节点之间存在边。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

This graph represents a network of 8 coffee shop nodes (in red) with 9 edges (in black). Only nearby node pairs have edges between them. The full network of 4036 coffee shops would be too large to display here.

为了构建完整网络图的边,我首先定义了一个函数,该函数使用一对点的地理坐标来计算它们之间的欧几里德距离。然后,我创建了一个函数,它将 max_distance 作为输入,并输出一个 Python 字典,其中的键是咖啡店 id,与键相关联的值是所有其他咖啡店 id 的列表,这些 id 与键的距离最多为 max_distance 。换句话说,键是节点,与键相关联的值是与键有边的所有节点的列表。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

This is a sample from the dictionary when max_distance = 0.001. The sample consists of 6 keys and their corresponding neighbor lists . For example, coffee shop 4 has an edge with coffee shops 82, 3042 and 3160.

无法预先知道最大距离参数的合适选择。如果 max_distance 太小,则图中的边太少,连通性低;影响力会被低估。如果 max_distance 太大,那么图中将有太多的边和高连通性;影响力会被高估。作为找到该参数的合适值的第一步,我计算了对于不同的 max_distance 值,网络中节点间邻居的最大和平均数量。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The degree of a node is the number of other shops that are no further than max_distance away from the node. Distance scale: two nearby adjacent streets in NYC are typically a distance of 0.0007 to 0.0010 apart.

趋势在模拟中传播的速度主要取决于 avg_degree 。如果这个值太大,那么模拟将高估趋势传播的速度;更多的邻居意味着更多的外来影响。因此,我决定在版本 1 的任何未来分析中只测试最大距离 ≤ 0.004 的值,这样平均程度≤ 23,这似乎是一个合理的上限。距离 0.004 对应于通常从给定咖啡店延伸不超过 6 条纽约市街道的半径。

趋势模拟器:版本 1

在任何给定时刻,网络中的每个节点都有一个与之相关联的布尔状态,其中 True 意味着商店在那个时刻正在跟随潮流。初始状态使用二项式分布随机化,并且网络在迭代中更新,其中第一次迭代之后的每次迭代的状态由前一次迭代的状态和以下两个规则确定:

  • 如果一个节点在迭代 I 为真*,那么在所有迭代 j > i 为真*
  • 如果一个节点在迭代 I 时为,但是在迭代 I 时至少有一个邻居为,并且如果迭代 I 不是最后一次迭代,则对于迭代 i+1,该节点更新为

一次迭代可以被认为是一个时间单位,例如一个月或者一年。我构建了一个函数,以表格的形式输出模拟结果,其中行对应于节点,列对应于每次迭代中节点的布尔状态。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

This is a sample of the simulation output which shows the states of shops 4012 to 4016 for the random initialization step and the first 4 iterations.

作为输入,模拟器要求:

  • adj_dict :包含节点和邻居列表的字典,由 max_distance 决定(如图论部分所述)
  • 迭代次数:网络更新迭代次数
  • p_xp_xxp_xxxp_xxxx :与二项分布相关的状态初始化概率;四个价格级别各有一个值
  • 种子:二项式分布的随机种子

在这一点上,仍然不清楚什么是对最大距离的好选择;我只是凭直觉猜测 0.004 的上限似乎是合理的,所以我用 0.001、0.002、0.003 和 0.004 的 max_distance 值进行了实验。也不清楚 p_xp_xxp_xxxp_xxxx 的合适选择可能是什么。为了最小化不断增长的选项的复杂性,我决定在模拟器的版本 1 中使这些初始化概率相等,但是用不同的值进行实验。我认为,在一个包含 4036 家商店的数据集中,说服 10 家商店最初采纳一个想法似乎并不太牵强。这相当于初始化概率为 10/4036,或者大约为 0.0025,所以我试验了每个 max_distance 值的初始化概率为 0.0005、0.0010、0.0015、0.0020 和 0.0025。对于每个( max_distanceinit_prob )对,模拟器使用 100 个不同的随机种子运行,以生成具有这些特定参数值的模拟样本。然后,对所有种子的商店的数量进行平均,按照最大距离初始 _ 概率和迭代进行分组。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Each table entry is an average over 100 simulations.

极端情况:

  • max_distanceinit_prob 分别最小化为 0.001 和 0.0005 时,趋势传播非常缓慢。到第四次迭代结束时,平均仍只有 16 家咖啡店采用了这一趋势,这一增长率太低,不足以被视为病毒式增长。
  • max_distanceinit_prob 分别最大化到 0.004 和 0.0025 时,趋势传播非常快。在第一次网络更新后,趋势采纳者的平均数量从初始化阶段的 9 个跃升至 211 个,这一增长率似乎非常高。

本着实事求是的精神,我决定分析这两个极端之间的模拟。我已经计算出 init_prob = 0.0025 似乎是一个合理的起点,但是即使 max_distance 低至 0.002,平均模拟从 it_0 到 it_1 增长得不合理地快。因此我用 max_distance = 0.001 解决了这个问题,并生成了下面的模拟。

This is the random initialization and first ten iterations of an example simulation when init_prob=0.0025 and max_distance=0.001. The red points represent the shops in NYC that are using the trend at each iteration.

这一趋势主要始于曼哈顿和布鲁克林北部,并从那里蔓延开来。这不足为奇,因为这些地区遍布咖啡店。在推动枫糖浆咖啡潮流的过程中,一个合理的策略可能是将这个想法集中卖给这些地区一些有影响力的商店,然后看着它有机地传播。

第一个版本的主要缺点是,这种趋势不太可能在咖啡店不密集的地区蔓延。下一个版本将致力于解决这个问题。

后续步骤

在模拟器的第一个版本中,一直隐含地假设任何商店对其邻居的影响权重是固定的。在下一个版本中,我将通过使用评分评论价格特征来量化每对相邻商店之间的影响,从而改进这种方法。我还将包括一些特征工程变量,如 is_starbucksis_starbucks_neighbor ,它们为数据集最常去的咖啡店提供特殊待遇。商店是否在随机初始化阶段之外的任何迭代中采用该趋势将由其邻居的影响以及引入到网络中以解释人的不可预测性的一些随机噪声来确定。这将产生一个更真实的模拟器,特别是允许这种趋势在曼哈顿和布鲁克林北部以外的地区传播。

****代码:这个项目的代码和模拟器的所有未来版本都可以在我的 GitHub 页面找到。

****联系人:如有任何问题、意见或建议,请随时联系 nathanburnsds@gmail.com 或 LinkedIn

最后,我要感谢 苏珊·霍尔科姆 在整个项目中提供的及时而全面的反馈。

加密货币命名中的认知偏差

原文:https://towardsdatascience.com/cognitive-bias-in-cryptocurrency-naming-74c5d6a7990f?source=collection_archive---------25-----------------------

为什么将一种加密货币命名为“NAS”而不是“XZC ”,会在交易所上市后的第一周产生熟悉感并提高购买兴趣

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Photo by meo on Pexels

在畅销书思考快与慢中,丹尼尔·卡内曼用了整整一章来探讨概念、想法、图片或文本呈现给我们的方式,以及我们理解它们所付出的努力对我们对它们的态度和情绪的影响。因此,与清晰、轮廓分明的图像或字体相比,难以看清的图像或文本字体通常与消极态度或不快有关。他称这种现象为认知放松带来的快乐。

同样,他解释说

容易发音的单词唤起一种有利的态度。名字容易发音的公司在股票发行后的第一周比其他公司表现更好,尽管这种效应会随着时间的推移而消失。具有可发音交易代码的股票(如 KAR 或 LUNMOO)表现优于那些具有绕口令代码的股票,如 PXG 或 RDO——它们似乎在一段时间内保持了一点优势。在瑞士进行的一项研究发现,投资者认为 Emmi、Swissfirst 和 Comet 等名字流利的股票比 Geberit 和 Ypsomed 等名字笨拙的股票收益更高。

这一假设背后的主要思想是,市场工具名称的可读性与我们记住它的程度有因果关系。与此同时,记住一些东西会导致熟悉感,除非记忆表达了相反的意思,否则我们经常喜欢或偏爱我们记住的东西。这反过来又会导致购买兴趣的增加,或者在有购买选择的情况下更倾向于购买资产。

可读性→记忆性→熟悉度→喜欢度→购买兴趣

Zajonc 称这种现象为单纯暴露效应。[……][他]认为重复对喜欢的影响是一个极其重要的生物学事实。为了在一个经常充满危险的世界中生存,一个有机体应该对一个新的刺激做出谨慎的反应,退缩和恐惧。对于一种不怀疑新奇事物的动物来说,生存前景是暗淡的。然而,如果刺激实际上是安全的,最初的谨慎消退也是适应性的。纯粹的暴露效应之所以会出现,是因为重复暴露于刺激之后不会有任何不良反应。这样的刺激最终会成为安全信号,安全性好

我认为广告和营销也是从曝光效应中培养出来的,这或许可以解释“没有坏的宣传”这句话。这是,他们如何评价我们的产品并不重要,重要的是人们会谈论它,从而产生熟悉感,进而产生好感等等,直到引起更大的购买兴趣。

为了测试股票代码的可读性是否会影响对加密货币的购买兴趣,我进行了一个小型研究项目,以确定事实是否如此。你可以在文章的最后找到 Jupyter 笔记本。

数据

这个研究项目背后的主要假设是,加密货币的可读和易记的名称应该在发行或在交易所上市的第一周影响资产的价格。

在我们的案例中,我们将与在币安交易所上市的或多或少同质的一组加密货币合作,这些加密货币满足以下要求:

  1. 加密货币的股票名称(简称)应该是 3 个字母长。例如,瑞士联邦理工学院、TRX、ZEC…
  2. 加密货币应该与比特币进行交易。例如,BTC 理工学院、TRX BTC 学院等。

114 种加密货币符合这些标准。

现在我们将每种加密货币分为“可读”或“不可读”。我们将使用两条规则:

  • 在一种情况下,我们将认为具有至少一个元音的 3 个字母的跑马灯的加密货币是可读的,而如果加密货币跑马灯仅由辅音组成,则是不可读的。例如,ETH 是可读的,而 ZRX 是不可读的。
  • 在第二种情况下,我们将把所有中间位置有一个元音的加密货币视为可读的,而其余的则视为不可读的。例如:英美烟草公司是可读的,但 BSV 不是。

然后,我们将检索加密货币在币安交易所上市后第一周的所有 1 小时烛台。

第一个规则分类的标记:

**WITH VOWEL:**
ADA, ADX, AGI, AMB, ARK, ARN, AST, BAT, EDO, ELF, ENG, ENJ, EOS, ETC, ETH, EVX, FET, FUN, GAS, GTO, HOT, ICN, ICX, INS, KEY, LUN, MCO, MDA, MOD, NAS, NAV, NEO, OAX, OMG, ONG, ONT, OST, PAX, POA, POE, REN, REP, REQ, SKY, SUB, SYS, VEN, VET, VIA, VIB, WAN, XEM, ZEC, ZEN, ZIL
 **WITHOUT VOWEL:**
BCC, BCD, BCH, BCN, BLZ, BNB, BNT, BQX, BRD, BSV, BTG, BTS, BTT, CDT, CMT, CND, CVC, DCR, DGD, DLT, DNT, GNT, GRS, GVT, GXS, HSR, KMD, KNC, LRC, LSK, LTC, MFT, MTH, MTL, NXS, PHB, PHX, PPT, QKC, QLC, QSP, RCN, RDN, RLC, RPX, RVN, SNM, SNT, TNB, TNT, TRX, WPR, WTC, XLM, XMR, XRP, XVG, XZC, ZRX

分析

为了进行分析,我们将计算每种加密货币的百分比回报,并汇总上述每种类别的所有回报。最后,我们将比较这些分布,并执行 t 检验,以统计评估这两个样本是否可以被视为来自不同的分布。理想情况下,我们预计可读密码将比不可读密码有更高的回报,这是由于所描述的纯粹暴露效应

结果

首先让我们看看中间有/没有元音的分笔成交点的回报分布:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 1. Distribution of 1-h returns for cryptocurrencies with tickers that contain a vowel in the middle vs tickers without a vowel in the middle for the first 2 days after exchange listing.

看似有一些差异,但这些差异有统计学意义吗?让我们对交易所上市后 1 天到 7 天的所有数据进行 t 检验:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 2. Mean returns and t-test p-value for tickers with vowel in the middle position vs tickers without the middle vowel. The reported “n” represents the number of cryptocurrencies included in each class.

令人惊讶的是,可读类别(带中元音)的平均回报率实际上高于不可读类别。这种差异在开始时似乎更大,但似乎随着时间的推移而衰减。有趣的是,p 值都很低,在α= 0.05(5%)时有一个点具有统计学意义。

现在让我们看看元音与非元音标记分类的结果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 3. Mean returns and t-test p-value for tickers with any vowel vs tickers without any vowel. The reported “n” represents the number of cryptocurrencies included in each class.

乍一看,平均差异似乎更小,但我们至少可以看到三点具有统计意义!毕竟,该假设至少在一定程度上似乎是正确的。

带回家的信息

虽然相关性并不总是意味着因果关系,但我们可以看到,在交易所上市后的第一天,具有可读符号或股票名称的加密货币实际上显示出更高的平均回报(在 alpha=0.05 的不同点上显著)。这表明,当人们可以选择购买一项资产时(特别是在 2017 年发生的 altcoin 热潮期间,当时这里分析的大多数加密货币都已上市),人们可能会倾向于购买更多具有最可读和最难忘名称的加密货币。

Jupyter 笔记本

这个项目是我们在cryptodatum . io研究的一部分,这是一个加密货币数据 API,旨在提供即插即用的数据集来训练机器学习算法。如果你是机器学习从业者,在https://cryptodatum . io获取你的免费 API 密匙,自己玩吧

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Colab 与 MLflow 的协同:如何监控进度和存储模型

原文:https://towardsdatascience.com/colab-synergy-with-mlflow-how-to-monitor-progress-and-store-models-fbfdf7bb0d7d?source=collection_archive---------24-----------------------

深度学习中越来越多的模型依赖于 GPU 的使用。作为一名深度学习实践者,我甚至想过买一台来加速我的辅助项目的开发。但是每年发布的新型号的 GPU 使得旧的 GPU 显得有些陈旧、缓慢、不酷。酷的东西是新的云技术,允许租用一个具有上一代 GPU 的虚拟机(VM ),并在云中训练你的模型(high)。然而,从设置云虚拟机的金钱和时间来看,这可能仍然很昂贵。

如果我告诉(或提醒)了呢?)您了解解决所有这些问题的云解决方案吗?谷歌的 Colab 笔记本提供了一个长达 12 小时的免费 GPU。然而,12 小时后一切都变成了南瓜:所有存储的数据都不见了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Photo by Dan Gold on Unsplash

收敛到南瓜不是唯一的选择。为了保存训练过的模型,需要将谷歌存储谷歌驱动与 Colab 笔记本连接。为了监控训练进度,必须使用额外的工具,如 Colab Tensorboard 。或者,MLflow 提供了存储模型和监控训练进度的解决方案。在这篇博文中,我介绍了如何在 Google Cloud 上设置 MLflow 的指南。

MLflow 存储两种类型的数据:

  • 结构化数据:训练进度的度量和模型参数(浮点数和整数)
  • 非结构化数据:训练工件(图像、模型等。)

我们可以将这些类型的数据存储在数据库中,也可以本地存储在虚拟机上。让我们从数据库选项开始。对于培训的指标,可以使用 SQL 或 Databricks 数据库。对于训练工件,数据库是 S3,谷歌存储或 Azure 存储。为了观察训练进度,需要部署 MLflow 服务器(管理存储数据的 GUI)并将其连接到数据库。另一种选择是在虚拟机上部署 MLflow 服务器,并将所有内容本地存储在其上。

我决定采用第一种方法,将 MLflow 服务器连接到数据库。在我看来,这种设置更加健壮,因为我们不需要依赖 MLflow 服务器,而只需要依赖云数据库。此外,数据库选项允许在您的笔记本电脑上本地部署 MLflow 服务器,这样更安全。对于云提供商,我选择了谷歌云,因为我还剩下一些免费积分:)。这是一个建筑的草图:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在,让我们按照 5 个实际操作步骤,在本地部署服务器,该服务器将连接到 SQL 数据库以获取指标,并连接到 Google storage 以获取工件。

**1。在 IAM 控件中设置服务帐户。**我现在的设置不是最安全的(最后看关于安全的评论)。但是,有一件事绝对值得做,那就是在 Google Cloud 的 IAM 控件中创建一个服务 app。要创建服务 IAM,请遵循以下步骤:

IAM→服务帐户→选择项目→创建服务帐户→…

应向 app Cloud SQL Editor,Storage Object Admin 授予以下权限。创建 IAM 服务帐户的原因是,如果有人偶尔发现了您的应用凭据,最大的损害仅限于 SQL 和存储。对于到 SQL 和存储的连接,我们将使用服务 IAM 密码。要使用密码创建 JSON:

服务帐户详细信息→授予此服务帐户对项目的访问权限(选择角色)→授予用户对此服务帐户的访问权限→创建 JSON 格式的密钥并保存此文件。

现在您有了一个带有 JSON 密钥的服务应用程序。

2。创建和配置 Google SQL server。ml flow 支持的 Google cloud 中现有的解决方案是 MySQL 和 PostgreSQL。设置 PostgreSQL 要简单得多。ml flow 1 . 0 . 0 版本中的 MySQL 有几个问题,这些问题肯定会在下一个版本中得到解决。在这篇文章中,我描述了 PostgreSQL 的设置。

2a。启动 PostgreSQL server 后,使用规则 0.0.0.0/0 为您的 SQL 服务设置公共 IP(在这里,您将您的 SQL 暴露给 Internet,知道您的 SQL 数据库密码的每个人都可以访问您的 SQL)。记下您的公共 IP 号码,因为您以后会需要它。

2b。在 SQL 中创建一个表,用于存储 MLflow 中的数据。

2c。为 SQL 数据库设置用户名和密码。

3。配置 Google 存储帐户。

3a。在 Google Storage 中创建一个存储桶。

3b。将角色:“传统存储桶所有者”和“传统存储桶读者”添加到您在步骤 1 中创建的 IAM app-user。为此,请遵循:

选择桶→权限→选择服务帐户→添加相应的角色

4。启动本地 MLflow 服务器。

MLflow 提供了一个很好的 GUI,叫做 MLflow Server。您可以通过这个 GUI 管理存储在数据库中的模型。一种选择是在您的笔记本电脑上本地启动 MLflow 服务器。

4a。首先,安装 MLflow 和以下必需的软件包:

pip install google-cloud-storage mlflow psycopg2

4b。还记得步骤 1 中的 JSON 文件吗?现在我们需要它!类型:

export GOOGLE_APPLICATION_CREDENTIALS=”path/to/jsonfile”

4c。就是这个!使用以下命令启动 MLflow 服务器:

mlflow server \
--backend-store-uri 'postgresql://<username>:<password>@<sql ip>/<name of table>'\
--default-artifact-root gs://<name of bucket in gs>/

这里的‘postgresql://:@/是一个连接到您的 PostgreSQL 数据库的 SQL Alchemy 字符串。在此插入步骤 2 中的相应凭据。

之后,您的 MLflow 服务器应该可以工作了。在浏览器地址栏输入 http://127.0.0.1:5000 即可查看。您希望看到 MLflow 服务器的起始页:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

MLflow Server first start.

5。使用 Colab 测试 MLflow 设置。

要测试连接,您应该首先设置您的凭据。比如,像这样:

然后用 Colab 的其他包安装 MLflow,并将一些度量和工件保存到数据库中:

全笔记本在 GitHub 有售。

请注意,我使用了所展示的设置来在可公开访问的数据集上训练模型,安全性不是主要关注的问题。有几个漏洞,如将 SQL server 暴露在互联网上,以及将密码从服务帐户直接写入 Colab 笔记本。在这种设置中,服务帐户权限的限制非常重要。设置 MLflow 的一个更安全的方法是通过 gcloud 工具建立到 Google cloud 的连接,并使用 Google Storage SQL proxy 而不将 SQL 服务暴露给互联网。要知道,简单性和安全性之间总是有取舍的:)

快乐模型管理和培训与 Colab!

协作室+驱动器+ Github ->工作流程更加简单

原文:https://towardsdatascience.com/colaboratory-drive-github-the-workflow-made-simpler-bde89fba8a39?source=collection_archive---------17-----------------------

介绍

这篇文章是我们之前尝试充分利用两个世界的延续,即 T2 谷歌实验室和 T4 Github T5。简而言之,我们试图在典型的数据科学工作流程中映射这些工具的使用。虽然我们成功了,但是这个过程也有缺点:

  • 它依赖于动态导入,这使得我们的代码变得不必要的麻烦。
  • 我们没有让 Github 部分正常工作。工作空间必须脱机保存。

在本帖中,我们将向您展示一种更简单的方法来组织工作空间,而不会有这些缺陷。你需要的只是一个 Gmail 和 Github 账户。我们开始工作吧。

什么去哪里?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 1. Three parts of our simple “ecosystem”.

通常,我们的工作区中有四种基本的文件类别:

  • 笔记本*(。ipynb)* —对于交互式开发工作,
  • 库*(。py)* —对于我们使用和重用的代码,
  • 模型——我们试图建造的东西,
  • 数据——我们构建数据的原料。

由于 Colab 后端不是持久的,我们需要一个永久的存储解决方案。除此之外,我们还需要一个版本控制系统,这样我们就可以跟踪变化。最后,如果我们不需要考虑这个机器,我们会很感激。

Colab 很容易与 Google Drive 集成,这使它成为存储空间的自然选择。我们将使用它来存储我们的数据模型。同时,Github 更适合代码,因此我们将把它用于笔记本。现在,问题出现了,我们如何从笔记本的位置将两者接口,这将使我们的工作流尽可能地无痛?

开源代码库

我们假设您已经有了一个 Github 帐户,并为您的项目创建了一个存储库。除非您的存储库是 public ,否则您将需要生成一个 令牌 来通过命令行与之交互。这里有一个简短的指南告诉你如何创建一个。

Google Drive

接下来的事情是为模型和数据组织我们的非易失性存储空间。如果你有一个 Gmail 账户,你就成功了一半。你需要做的就是在驱动器中创建一个空目录,就这样。

合作实验室——操作笔记本

为了让事情井井有条,我们定义了一个单独的笔记本作为我们的操作工具。我们将专门使用它的单元来操纵我们的空间,让其他笔记本来处理更有趣的事情,如探索性数据分析特征工程培训。所有笔记本,包括这个,都将被修改,但是命令存储在操作笔记本中。

工作流程

工作流程是一个简单的三步流程:

  1. 首先,在连接到 Colab 运行时之后,我们需要挂载 Google Drive 并且使用 Github 更新我们的空间。
  2. 我们使用笔记本和其余的文件(我们的模块、库等)。).在这种背景下,我们干脆称之为剪辑
  3. 我们保存我们的工作,通过使用操作笔记本将我们的驱动器与 Github 同步。

连接、安装和更新

from google.colab import drive
from os.path import join

ROOT = '/content/drive'     # default for the drive
PROJ = 'My Drive/...'       # path to your project on Drive

GIT_USERNAME = "OlegZero13" # replace with yours
GIT_TOKEN = "XXX"           # definitely replace with yours
GIT_REPOSITORY = "yyy"      # ...nah

drive.mount(ROOT)           # we mount the drive at /content/drive

PROJECT_PATH = join(ROOT, PROJ)
!mkdir "{PROJECT_PATH}"I    # in case we haven't created it already   

GIT_PATH = "https://{GIT_TOKEN}@github.com/{GIT_USERNAME}/{GIT_REPOSITORY}.git"
!mkdir ./temp
!git clone "{GIT_PATH}"
!mv ./temp/* "{PROJECT_PATH}"
!rm -rf ./temp
!rsync -aP --exclude=data/ "{PROJECT_PATH}"/*  ./

上面的代码片段在/content/drive安装 Google Drive 并创建我们项目的目录。然后,它从 Github 中取出所有文件,并将它们复制到那个目录中。最后,它收集属于驱动器目录的所有内容,并将其复制到我们的本地运行时。

这个解决方案的一个好处是,如果多次执行,它不会崩溃。无论何时执行,它只会更新新的东西。此外,使用rsync,我们可以选择排除一些内容,这可能需要很长时间才能复制(…数据?).

编辑、编辑和编辑

开发,尤其是在数据科学中,意味着在我们最终把事情做好之前要尝试多次。在此阶段,可以通过以下方式编辑外部文件/库:

  1. 替换或更改驱动器上的文件,然后使用rsync将它们传输到每个笔记本的本地运行时,或者
  2. 使用所谓的 IPython 魔法命令。

假设您想要快速更改somefile.py,这是您的库文件之一。您可以为该文件编写代码,并使用%%writefile命令告诉 Colab 保存它。由于文件驻留在本地,您可以简单地使用import语句再次加载它的新内容。唯一的事情是记住首先执行%reload_ext somefile命令,以确保 Colab 知道更新。

这里有一个例子:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 2. Importing, editing and importing again. All done through the cells.

储蓄,收工

一旦你想备份你所有的工作,你需要做的就是把所有的文件复制到存储器里,然后推送到 Github。

可以使用笔记本单元中执行的!cp -r ./* "{PROJECT_PATH}"进行复制,这将更新驱动器存储。然后,推送到 Github 需要创建一个临时工作目录和配置本地 git repo 只是暂时的。下面是要执行的命令:

!mkdir ./temp
!git clone "https://{GIT_TOKEN}@github.com/{GIT_USERNAME}/{GIT_REPOSITORY}.git" ./temp
!rsync -aP --exclude=data/ "{PROJECT_PATH}"/* ./temp

%cd ./temp
!git add .
!git commit -m '"{GIT_COMMIT_MESSAGE}"'
!git config --global user.email "{GIT_EMAIL}"
!git config --global user.name "{GIT_NAME}"
!git push origin "{GIT_BRANCH_NAME}"
%cd /content
!rm -rf ./temp

显然,您需要自己定义"{...}"中的字符串。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 3. Successful upload of the content to Github. Calling it a day.

结论

在这篇文章中,我们展示了如何在使用 Google Colab 时有效地将 Google Drive 和 Github 结合起来。改进后的工作流程比之前介绍的流程简单得多。

如果你想分享任何有用的技巧或提出一些改进建议,请在评论中提出。你的反馈很有帮助。

还会有更多…

我计划把文章带到下一个层次,并提供简短的视频教程。

如果您想获得关于视频和未来文章的更新,订阅我的 简讯 。你也可以通过填写表格让我知道你的期望。回头见!

原载于

冷启动能量预测

原文:https://towardsdatascience.com/cold-start-energy-predictions-d3971b1803e?source=collection_archive---------10-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

大约三个月前,我参加了施耐德电气在 DrivenData 平台举办的“ Power Laws:冷启动能量预测”比赛。目的是根据以前的用电量和其他因素(如温度、节假日信息等)来预测几栋建筑的用电量。挑战的一个有趣部分是几个家庭(2 天或更少)可用的少量消费信息,因此,我们的模型必须很好地概括新建筑。

结果,我在 1300 名参与者中名列第四。这篇文章将描述我的解决方案和这次比赛的主要收获。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

A final leaderboard of the competition

任务、数据和指标

预测建筑的全球能耗在建筑运营中发挥着关键作用。它为设施管理人员和楼宇自动化系统提供了初步检查,以标记预期和实际能源使用之间的任何差异。设施管理者、公用事业公司和建筑调试项目也使用准确的能耗预测来实施节能政策并优化冷却器、锅炉和能量存储系统的操作。

通常,预测算法使用历史信息来计算他们的预测。大多数时候,历史数据集越大,预测就越准确。这项挑战的目标是构建一种算法,从构建仪器的一开始就提供准确的预测。

组织者提供了训练数据集,该数据集由 758 栋建筑组成,这些建筑在 672 小时内具有已知的电力消耗(总共 509 376 个数据点)。此外,我们还有关于建筑类型(基于表面面积)、节假日和温度的信息。如果一栋楼是一套公寓,周六周日大概是节假日;如果一个建筑是一个购物中心,它在周末工作,没有假期。为了让自己熟悉这些数据,你可以查看组织者的 EDA

测试数据集由 625 栋新建筑组成,这些建筑不在训练数据集中。我们有过去 24-372 小时内“测试”建筑的消耗信息。预测的三个时间范围是不同的。每栋建筑的目标是:

  • 预测一天中每小时的消耗量(24 次预测);
  • 预测一周内每天的消耗量(7 次预测);
  • 预测两周内每周的消耗量(2 次预测)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The illustration for the train/test split and what we had to predict

竞争指标类似于 MAPENMAE ,使得每个预测(每小时、每天或每周)同等重要(以下指标包含ci内真实值的平均值):

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The competition metric

最终解决方案

在这次比赛中,我测试了很多想法,但大多数想法都没有给我的分数带来任何显著的提高。然而,要讲述我尝试过的每一件事需要太长的时间;因此,在这一部分,我决定只关注我的最终解决方案的主要部分。

数据预处理

数据预处理包括三个主要步骤:填充缺失值、删除常量值和数据缩放。首先,我用给定 Id 和一个小时的小时平均值来填充缺失的温度值。在此之后,缺失值的数量从 45%下降到 2%。剩下的 2%缺失值我用给定小时的月平均温度来填充。

其次,我用一个不变的目标清洗了所有的时间序列。在训练数据集中有几个例子,在这些例子中,我们有很长一段时间消耗不变。这些示例看起来像是最初丢失的,组织者决定用中值来填充它们(常量值接近中值,但不精确)。如果我保持这些值,我的预测会有偏差;因此,我删除了所有的数据点,我们观察到在过去的 6 个小时里有一个持续的消耗。

我认为,我的解决方案中最重要的部分之一是独立地衡量每栋建筑的能耗。当您对线性回归的神经网络进行预处理时,一种常见的方法是将所有训练数据用于目标缩放:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

由于度量标准的原因,本次比赛中没有出现这种情况。我用给定建筑的最小和最大值来标准化每栋建筑的值。它允许比较不同电力消耗水平的建筑物;因此,我的模型开始更好地概括。

我做了一个玩具例子来说明这个想法。据推测,我们有两座建筑,如下图所示。他们有相似的消费性质(1 号地块),唯一的区别是消费水平。如果我们用所有可用的数据(第二个图)缩放目标,图像不会改变太多。我们的预测只基于一个特征——一天中的一个小时。它将具有较高的偏差(事实上,这种情况下的最佳预测将是给定小时的平均消耗量)。但是,如果我们独立缩放每个时间序列,它们将看起来相同(第三个图),我们的模型将更容易发现潜在的模式。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Toy example: X — an hour of the day, y — consumption

在规范化之前,我还尝试了不同的目标预处理策略。在最近的机器学习比赛中(在 IDAO 2018 中神奇的 1/3 度),在训练数据中存在离群值的情况下,它显示出了显著的改善。然而,他们都没有给我一个接近建筑物 Id 内简单的最小-最大缩放的分数:

  • 1/2、1/3 或 1/4 度的目标+最小-最大标度或均值-标准差标度;
  • 目标+最小-最大缩放或均值-标准差缩放的对数。

验证策略

我使用维持验证集(20%)来检查我的模型的分数,并使用 10 重验证(建筑物 Id 分层)来优化管道的超参数。我注意到这场比赛中的大多数时间序列是静止的,时间序列分裂和洗牌的分数几乎是一样的。因此,我决定使用混洗 10 倍,而不是常见的时间序列分裂,因为它允许我在事后使用不同的分裂,这将使我的预测更加稳定。

现在,我对时间序列任务使用一个简单的规则:如果时间序列是静态的,那么使用 KFold 进行超参数优化是可以的(但是不能用于整个流水线的评估)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Examples of the training data. It is clearly seen that properties of time series don’t change too much over time, there is no trend in the data, so we might use KFold instead of time-series split for validation

特征工程

我为特性工程使用了不同的策略,但我认为最重要的是:

  • 基于时间戳的特征:年、年中的某一天、年中的某一月、年中的某一周、周中的某一天。这些特征在 NN 中被视为分类特征,我还通过正弦-余弦变换将它们添加为数值特征(见下面的等式)。这是一种众所周知的处理循环特征的方法。这种方法背后的思想很简单:我们希望在我们的模型中归纳出关于过程的先验信息,即周期的结束是新周期的开始。因此,应用此映射后,00:00 和 23:00 之间的距离将变得更小。我推荐查看这些帖子看代码示例:编码深度学习的循环特征特征工程——处理循环特征

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 我把温度从摄氏温度转换成了开尔文温度。然后,我添加了一个小时的温度,下一个小时的温度,这一个小时和下一个小时的温度之间的绝对和相对差异,下一个小时和这一个小时的温度之间的绝对和相对差异,作为新的特征。;
  • 基于建筑类型的特征:最大和最小消耗的记录、建筑表面类别、休息日、建筑工作制度(is_{weekday}_dayoff组合在单一类别中)。

根据竞赛规则,禁止使用附加数据。但是,不管怎样,因为好奇,我测试了下面这个想法。我使用一个开放的温度观测数据库来确定建筑位置。我们知道给定建筑每小时的温度,这就是为什么我在数据库中搜索相似的温度模式。关于温度观测值(实际值和台站观测值之间的绝对距离之和)与给定建筑物的温度最接近的台站的信息(纬度、经度、国家、最近的城市)被用作附加特征。然而,它降低了验证和排行榜的分数。我认为这是因为温度数据中有很多缺失值。我放弃了这个伟大的想法。

模型

我使用前馈神经网络作为最终模型,其架构如下所示。我对所有分类特征都使用了嵌入层。这是神经网络中处理类别的常用方法。嵌入将相似的类别彼此更紧密地映射在一起(参见这篇论文的温和介绍)。在这次比赛中,这是非常有益的,因为数据集中有很多建筑。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我用以下参数训练 NN:100 个时期,批量大小 1024,Adam 优化器,3 个时期用于提前停止。我在 Keras 测试了训练 NN 的不同损失。我有一种感觉,MAPE 和 MSE 的损失可以给我不同的高分预测,这样我就可以把它们融合在一起,获得更高的分数。但是这些方法还不够好,不足以将它们包含在最终的管道中。

我还尝试了众所周知的梯度增强方法(XGBoost 和 LightGBM ),这些方法是在原始数据和 NN 之后的数据表示(几个时期的训练之后 NN 内层的输出)上训练的,但是它们不能显示出像样的结果。这些模型的分数甚至不足以包含在最终的集合中。

我最终提交的只是 30 个模型的简单平均值(10 倍* 3 个略有不同的架构)。赌注并没有提高分数太多。

决赛成绩

大部分比赛时间,我都是抱着和第二名差距巨大的第一名。但是在过去的两天里,来自第二名和第四名的小伙子们组队了,一点小小的变动就让一切都不同了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Shake up be like

但是,无论如何,我花了 1.5 个月解决了一个有趣的任务,这帮助我组织了一个类似任务和比赛的管道。最终解决方案的一部分用于 Junction 2018,在那里我们赢得了智能云赛道(ODS)的“信号英雄挑战赛。AI 团队)。

协同过滤来“预测”药物的疗效(2)

原文:https://towardsdatascience.com/collaborative-filtering-to-predict-the-efficacy-of-a-drug-2-f151956315b7?source=collection_archive---------21-----------------------

另一个案例研究和对领域知识的一些思考

在本系列的第一篇博文中,我展示了使用协同过滤来预测药物与其靶标之间的相互作用强度的结果。在这个续集中,我将尝试处理另一个数据集,并讨论领域知识在生物化学中的重要性。

该数据集来自 T2 在一份著名杂志上发表的论文。这个数据集后来被另一个小组用来开发一种“预测”药物和激酶相互作用强度的方法(见 Cichonska 论文)。还记得第一篇帖子开头提到的四种场景吗?该图是从 Cichonska paper 复制的,并在下面复制,再次作为我们的起点。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Reference: Cichonska paper

我们处理场景(a)仅仅是因为协同过滤的基本限制。然而,cihon ska paper 试图做的不止这些。他们的诀窍是依靠药物和蛋白质的内在分子特性来进行预测。虽然分子的性质是由其分子结构决定的,但确切的关系还远未确定。事实上,Cichonska 论文的作者不得不筛选相当多的方法来描述一种分子,以便找到一种可以提供最佳预测的方法。下图总结了他们的努力。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

他们试图找到药物和激酶的最佳模型。每行对应一个药物模型,每列对应一个蛋白质模型。每个单元格中的数字是预测和测量结果之间的皮尔逊相关系数,其平方相当于两者之间线性拟合的 R。通常,药物模型的想法与激酶模型有很大的不同。理解所有这些描述药物和蛋白质的不同方式需要大量的领域知识,因此评估所有可能的组合不是一件容易的事。在不深入细节的情况下,我们寻找那些具有较高 r 值或红细胞的细胞。对于称为生物活性插补的问题(上图左侧),这是前面提到的四种情况中的第一种,最佳药物模型称为 KD-GIP。令人惊讶的是,这是唯一不基于分子结构或任何其他内在性质的模型;相反,它是基于测量的药物和蛋白质之间的相互作用强度。对于激酶,较好的型号是 KP-SW 或 KP-SW+。它们是基于蛋白质的结构。另一个蛋白质模型 KP-GIP 也表现相当好,这不是基于结构。因此,事实证明,他们还没有发现一种药物或蛋白质的内在模型比基于测量数据的经验模型好得多。

KP-GIP 和 KD-GIP 是协同模式吗?答案是否定的。它们基于内核技巧。可能需要一整本书来描述这个内核技巧。在我们的特定模型中,我们需要知道所考虑的药物和激酶之间的所有相互作用强度,包括那些尚未测量的,以实现这个核心技巧。但这不正是模型最初应该帮助我们的吗?为了让这些模型起作用,作者必须“猜测”缺失的相互作用值。如第一篇博文所示,协同过滤不需要对插补问题进行任何猜测。

对于称为“新药”的问题或者开头提到的四个场景中的第二个,最好的模型是药物的 KD-sp 和蛋白质的 KP-GS。由于手头问题的“冷启动”性质,它们必须是内在模型,所以作者甚至没有奢侈去尝试 KP-GIP 或 KD-GIP。有趣的是,KD-sp 和 KP-GS 不是插补问题中的最佳内在模型。换句话说,本质上相同问题的不同味道——预测相互作用强度——需要使用不同的模型。如果同一个模型对两种情况都是最好的,那就更让人放心了。

公平地说,论文中评估的许多内在模型都有类似的表现。r 值的差异只体现在第二或第三位小数上。我个人认为 r 值相差 0.01 在实践中并不显著。但是,追求 r 值非常小的提升,至少在机器学习比赛中还是非常重要的。r 值的小幅增加可能会导致排行榜大幅上升。更重要的是,这激励人们寻找新的技巧,从根本上把他们带到一个全新的水平。

现在让我们看看来自 Cichonska 论文的一些结果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在模型预测和测量结果之间有明显的相关性,但是我们也看到了相当多的异常点。特别地,绘制了 Ki 的负对数(10 为底)。在这里,需要一些领域知识来理解 pKi。Ki,粗略地说,就是药物“有效”所需的浓度,它的范围从微摩尔到纳摩尔。人们通常寻找对其靶激酶具有较低 Ki 而对其他非靶激酶具有较高 Ki 的药物。取其对数并翻转其符号后,我们得到的 pKi 范围为~5 到~9。pKi 越高,药物对目标的作用越强。注意 pKi 不应该有单位。我在本系列的第一个帖子中没有提到为什么取对数(自然对数,但那并不重要),现在是时候讨论一下以显示领域知识的意义了。我们想要处理对数(pKi)而不是 Ki 至少有三个原因:

  • Ki 的跨度很大。由于模型是通过最小化其预测误差来优化或训练的,所以对纳摩尔范围 Ki 和微摩尔范围 Ki 中的误差给予相同的权重是没有意义的。使用对数意味着我们试图最小化 Ki 的相对误差,消除绝对幅度引起的偏差。
  • 当药物与激酶结合时,Ki 的对数与自由能变化成正比。自由能变化是药物激酶复合物形成的基本驱动力。
  • 研究人员明白,他们需要研究一个跨越多个数量级的变量。当他们设计实验来测量 Ki 时,通常会进行一系列稀释。换句话说,他们在相差一个常数因子的几个浓度下进行实验,比如 0.1、1、10 和 100 纳摩尔。有些人会称这些浓度为“对数”单位。换句话说,10 和 100 的区别不是 90 而是 1 log。

如上图所示,pKi 的测量值和计算值之间存在显著的相关性。是否足够准确?我没有答案,但请记住,对数单位中 1 的差异是 10 倍的差异。最终我们想知道药物的有效浓度范围,因此 pKi 或对数单位的小误差将意味着浓度的大误差。理想情况下,药物不应该只在非常窄的浓度范围内起作用,因此我们在浓度测量中可能会有一些公差。为了回答这个预测是否足够好的问题,我们需要更多的领域知识。

这是他们在调查了相当多的内在模型和一个基于测量结果的模型后得到的结果。正确实现该模型需要大量的领域知识。如果我们使用协同过滤呢?正如本系列的第一篇博文所示,不需要任何领域知识。基于 fastai 的相同方法用于该数据集,结果如下所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

用约 93k 的药物激酶 pKi 值训练协同模型后,用于预测约 10k 的 pKi 值,并与实验结果进行比较。这种相关性是显著的。

将潜在因素转换为三个主成分,并在缩减的 PCA 空间中分析激酶的邻居,下表总结了它们之间的接近程度。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

比如 CLK4DYRK3 就差不多。事实上,它们都是双特异性激酶。 MAP4K4CDK7 分别是由有丝分裂原和细胞周期蛋白激活的激酶,都参与细胞分裂过程。当然,在对蛋白质的生物学功能没有更深入了解的情况下,这种讨论仍然是肤浅的。询问以前未知的激酶之间的关系是否可以通过分析大量的相互作用数据来揭示仍然是有趣的。我们只了解细胞中生化反应网络的一小部分,协同过滤揭示的新关系可能是未知水的指针。

这里有一个自然的问题,我们可以从哪里得到这些数据集。正如我在上一篇文章的结尾提到的,有很多工具,包括计算的和实验的,用于评估药物激酶的相互作用。没有适用于所有蛋白质和药物的通用测量方法。当人们进行实验时,条件是为适应他们独特的环境和目的而定制的。一些具有机器学习背景的人跳到这个领域,却发现现有的数据很难协调。数据监管和清理需要生物学和机器学习方面的专业知识,即使这是可行的。事实上,他们中的一些人决定重新收集数据,以便用于模型训练。总之,这个领域需要一个 ImageNet 。正如 ImageNet 有助于开发可以击败人类专家的图像识别算法一样,“激酶网络”应该早于具有真正预测能力的药物激酶相互作用模型。

最后一点,学习率是模型正常工作最重要的参数,最佳学习率大约是 5e-3。这与第一篇文章的结论基本相同,证实了杰里米对模型稳健性的信念。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对那些感兴趣的人来说,Jupyter 笔记本可以在这里找到。请注意,这项工作是初步的。

协同过滤来“预测”药物的疗效(1)

原文:https://towardsdatascience.com/collaborative-filtering-to-predict-the-efficacy-of-a-drug-c863ba21eddc?source=collection_archive---------27-----------------------

无领域知识学习的案例研究。

动机

在药物开发中,筛选是早期发现过程的重要组成部分。这种筛选的目的是发现与靶结合足够强和特异性的分子,以具有临床益处。科学家们在实验室里努力合成各种分子,希望提高它们的结合强度。这一过程通常由对药物-靶标相互作用的经验理解来指导。因此,人们很自然地会问,是否有可能明智地“设计”一种药物,就像智能手机是如何设计来实现一组预定义的性能目标一样。

随着量子力学和分子动力学的出现,科学家已经能够在计算机上预测分子之间的相互作用。然而,它需要先进的领域知识和昂贵的计算资源。高通量筛选的进步也有助于在过去几十年中积累大量实验确定的结合强度。人们仍然希望有一种更快、更准确的方法来获得结合强度。

我们能否利用所有先前工作的累积效应,并利用另一个领域的工具向前推进?这就是最近一个名为 IDG 的机器学习挑战的目的——梦想药物激酶结合预测挑战。这个项目是关于药物和激酶之间的相互作用。激酶是一类对恶性细胞(又称癌症)不受控制的增殖至关重要的蛋白质。科学家们已经成功地开发出能够粘附某些激酶的药物,从而阻止这种可怕疾病的发展。非常需要更多具有强结合特性的药物来对抗各种癌症。

药物激酶结合的预测本质上是一个没有提示的跨词难题,如下图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Copied from this reference.

挑战在于根据已知数据(黄色)预测缺失的结合强度(交叉)。根据待预测的结合对是否涉及零个、一个或两个从未被已知数据覆盖的药物或激酶,存在如上所示的四种不同情况。

以这种方式提出问题类似于机器学习中一个众所周知的任务——协同过滤。在网飞的百万美元大奖颁奖典礼上,它第一次成为聚光灯下的焦点。我们可以把药物和激酶的结合强度想象成药物和激酶的相似程度。网飞奖提出了完全相同的问题:根据用户对其他电影的评价以及其他用户对这部电影的评价,预测用户对这部电影的评价。这是上图中的第一个场景。

Fastai 文库及其在药物激酶结合问题中的简单应用

Fastai ,努力让神经网络再次变得不酷,让软件工程训练相对较少的人实现最先进的神经网络,包括协同过滤模型。本库的主要作者认为,神经网络已经发展到这样一个地步,即通过遵循一组非常小的最佳实践,可以为大量数据集开发出一个像样的模型。因此,限制其应用的不再是一个人能多好地编码,以及一个人能多有经验地微调一个模型。相反,如何根据自己对领域知识的独特理解恰当地铸造一个模型才是关键。在药物激酶结合的问题上,至少从表面上看,将它用于协同过滤并不困难。

药物激酶结合的数据可以在这里下载。它提供了一大套药物和激酶之间的亲和力测量。为简单起见,我从 Kd 开始,即离解常数。结合越强,Kd 越低。有 32536 个测量值可用。下面显示了一个小集合:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

注意,Kd 的对数将用于建模。

培训过程包括以下几个步骤:

  • 生成数据—批量重新组织数据以供 GPU 处理。
  • 设置学习者—选择合适的培训模型。
  • 找到学习率—选择学习者探索参数空间以找到最佳点的“积极性”。
  • 训练-使用数据优化模型。

多亏了 fastai 库,每一步都只需要一(1)行代码。当然,这是一个香草模型。高级用户可以通过修改库的内部机制来制作更复杂的模型。

下面是实现上述步骤的代码快照:

Kd_data = CollabDataBunch.from_df(df_Kd, user_name=’compound_id’,
                                         item_name=’target_id’,
                                         rating_name=’KDLog’, 
                                         pct_val=0.1,
                                         seed=40)
Kd_learn = collab_learner(Kd_data, n_factors=20, 
                                   y_range=[-15, 25], 
                                   wd=1e-2)Kd_learn.lr_find()
Kd_learn.fit_one_cycle(5, lr=5e-3)

让我们首先检查一下,如果没有协同过滤,我们可以“猜测”到什么程度?如果我们通过生成一个高斯随机数来“猜测”未知的 Kd,该高斯随机数的平均值和标准偏差是根据已知的 Kd 计算的,则预测值和实际 Kd 之间没有明显的相关性,如下所示。预测误差的分布看起来像非常宽的高斯分布。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用我们训练的模型,结果要好得多。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

回想一下第一幅图中显示的四个场景,这个模型只适用于第一个场景。事实上,如果我们检查模型的预测,一些神秘的化合物 id 显示为#na#。这些化合物是那些没有被训练数据集覆盖的化合物。这同样适用于激酶(列“目标 id”)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果我们简单地忽略这些项目,预测的质量会如预期的那样提高。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对于此模型,微调包括调整以下三个参数:

  • wd 或权重衰减:该参数控制正则化。简单地说,较大的 wd 对过度拟合的惩罚更大。
  • n 因子或因子数:协同过滤的本质是假设有特定数量的因子表征药物和激酶。在这些“潜在”因素定义的空间中,药物或激酶用一个点来表示。如果药物点和激酶点或多或少地从原点指向相同的方向,它们的相互作用会更强。
  • lr 或学习率:这控制了学习者在探索“粗糙”参数空间期间寻找全局最小值时所采取的步长。

人们过去认为,通过调整这些参数来优化模型需要经验。事实上,它决定了模型是否有效。fastai 的贡献在于它提供了对这些重要参数的简单访问。主要作者 Jeremy 进一步认为,存在一组“好的”参数,它们对不同的数据集都非常有效。在我们特定的药物激酶模式中,参数的网格搜索显示学习率是最重要的超参数。学习率的最佳值与杰里米为 MovieLens 模型发现的值大致相同,即预测用户对电影的评级。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

R² as a function of wd, lr or n_factor. Data points are from a grid search by keeping one of the parameters constant and varying the other two over a certain range.

对于 wd 或 n_factors,总是有好的参数组合,但是对于差的 lr,很难得到好的结果。

我们能预测什么?

如上所述,这里只讨论第一种情况。另外三个问题通常被称为“冷启动”问题。由于我们的潜在因素是通过经验模型拟合过程获得的,因此从概念上讲,首先很难为那些没有任何经验数据的人找到一组潜在因素。如果预测是基于分子的固有特征或它们的组合,冷启动问题就不再是一个问题。这种基于元数据的方法涉及到重要的特征工程和广泛的领域知识。尽管如此,协作过滤可能有助于特征工程,正如杰里米在罗斯曼数据集中所阐述的那样。在药物激酶问题中,如果我们相信来自协作模型的一组潜在因素是合理的,就有可能提出另一个模型,该模型可以利用分子的结构特性很好地预测潜在因素。然后,该模型可以用于冷启动问题。关联元数据和潜在因素的模型可能受益于迁移学习方法。

为了说明潜在因素的重要性,我们可以进行主成分分析,将潜在因素归纳为三个“主要”因素。下图显示了一些激酶在由两个主要因素定义的 2D 空间中的位置。那些相邻的激酶应该具有相似的特性。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

更严格的方法是找到每个激酶在它们的主成分空间甚至潜在因子空间中的邻居。Scikit-learn 实现了各种邻居查找方法。生物化学家可能会检查结果,看它是否有意义

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

比如p 00519(0 线)和它最近的邻居 P51451 都是酪氨酸蛋白激酶。这并不奇怪,因为它是一个非常常见的药物靶点,而且这个数据集有很多激酶。再比如, P00533 (线 1)是表皮生长因子受体,它最近的邻居 P47747 是组胺 H2 受体。作为最后一个例子, P00918 (第 4 行)是视黄酸受体α,它最近的邻居 P10276 是碳酸酐酶 II。这些配对真的在功能上相关吗?记住,你根本不需要理解生物化学来达到这一点。

从根本上说,我们想知道这种方法是否有助于药物发现。还有很多工作要做,以使模型足够精确,使科学家免于在工作台上劳动。

  • 该模型可以使用更多的微调。
  • 众所周知,测量结果具有较大的误差线和各种格式/惯例。

因此,实验人员和建模人员之间的进一步合作对于使协同过滤以及其他机器学习方法更加智能至关重要。

感兴趣的人可以在这里找到 Jupyter 笔记本。请注意,这项工作是初步的。

参见第 2 部分了解领域知识和另一个数据集的进一步讨论。

来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们并不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语

使用 fastai 的协同过滤

原文:https://towardsdatascience.com/collaborative-filtering-using-fastai-a2ec5a2a4049?source=collection_archive---------18-----------------------

了解如何使用 fastai 库构建推荐引擎

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

介绍

协同过滤是机器学习的一种应用,我们试图预测用户是否会喜欢特定的电影或产品。我们通过查看用户以前的购买习惯来做到这一点。在其最简单的形式中,协同过滤只涉及 3 列,用户 ID、歌曲 ID 和用户对该歌曲的评价。这正是我们将在本文中使用的。

全朱庇特笔记本。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

数据存储

有两种方法可以存储协同过滤的数据。我们可以将它存储在如上所示的.csv中,也可以使用matrix.矩阵的行代表用户,列代表项目,特定单元格的值代表用户对特定项目的评分。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

然而,如果我们以这种方式存储它,我们将最终得到一个非常稀疏的矩阵,因为大多数用户不会观看大多数电影或购买大多数产品。此外,矩阵将是巨大的,浪费了大量的存储空间。因此,我们将仅将其存储为.csv

嵌入

我们处理协同过滤问题的方法是,我们给每个用户分配一组权重,给每个项目分配一组权重,这些权重的点积就是用户对该项目的评分。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

image source: fast.ai

对于每个用户,我们查找相应的权重,这个东西被称为嵌入,将代表宋立科流派或用户口味的特征。

但是这些还不够。也许有一些用户喜欢很多歌曲或者大多数人喜欢的歌曲。因此,我们不是只取点积,而是将用户偏差和歌曲偏差添加到我们的预测中,以说明这一点。然后,我们使用梯度下降来更新我们的权重,直到我们得到足够好的结果。

让我们看看如何在代码中做到这一点。

解决办法

和往常一样,我们从导入 fast.ai 库开始。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们检查数据集的长度和收视率的分布。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传**外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

然后,我们创建一个数据集群,并使用 20%的数据作为验证集的一部分。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

请注意 DataBunch 创建步骤中的种子参数。

当我们希望我们的结果可重复时,我们使用种子。这意味着我们随机抽取 20%的数据作为验证集的一部分,但是,我们希望确保下次运行代码时,我们得到相同的(随机)分割。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

一旦我们创建了一个数据束,我们就初始化一个 学习器 。点积和偏差会给我们一些分数。这些分数可以是负数,也可以是正数。我们希望确保这些预测在我们期望的 0-5 范围内。经过大量的训练后,模型可以自己学习,但是我们希望节省一些工作,并告诉它我们希望预测的范围。因此我们把参数y_range传递给它。这将在最后添加一个 s 形层。

我们选择稍微高于和低于最小值和最大值的值,以保持预测在范围内。

n_factors参数决定了我们嵌入的大小。我们也传递了一点重量衰减。

最后,我们找到学习率并训练我们的模型。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

结果

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

数据集是一个相对简单的数据集,我们得到了很好的结果。此外,由于我们的嵌入大小只是一个参数,我们可以运行一个for loop并传递不同大小的嵌入来检查哪一个给出最好的结果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这就是我们解决协同过滤问题的方法。我们可以解释模型,找到最有偏见的歌曲或最没有偏见的用户。然而,为此,我们需要另一个csv来告诉我们哪个 id 对应于哪个歌曲或用户。

根据歌曲偏好对歌曲进行评级会很有趣,因为如果我们仔细想想,当我们去掉用户偏好和我们的嵌入时,歌曲偏好仍然存在。这意味着它代表了歌曲的无偏见的观点,去除了可能影响它的所有其他因素(基于歌曲和用户)。

我们还可以看看嵌入。然而,我们可能有很多(在这个例子中是 50 个),看 50 个影响我们选择歌曲的因素是不直观的。因此,我们可以做的是应用类似 PCA(主成分分析)的东西,将其降低到一个合理的数字,然后可以进行分析。

协同过滤的问题:冷启动

当我们有足够的关于用户或歌曲的数据时,我们可以很好地预测结果。但是,我们真正想给用户推荐歌曲的时候,是有新用户加入我们平台的时候。或者某个艺人发布新歌的时候。在这种情况下,我们没有以前的数据可以依赖,因此推荐是困难的。公司采取各种方法来解决这个问题,比如让用户选择他喜欢的电影类型,但目前还没有明确的解决方案。

结论

最后,我想敦促我的读者真正提高他们的数据准备技能。当我们参加 Kaggle 比赛或在线下载数据集时,所有的数据清洗和预处理步骤都已经为我们完成了。然而在现实世界中,你将不得不处理原始数据,你将不得不处理多个数据源。你如何处理这些资源将决定你是否会成为一名优秀的数据科学家。

所以努力学习这些技能,因为建模只是过程的一部分(而且是很小的一部分。)

这就是本文的全部内容。

如果你想了解更多关于深度学习的知识,可以看看我在这方面的系列文章:

* [## 深度学习系列

我所有关于深度学习的文章的系统列表

medium.com](https://medium.com/@dipam44/deep-learning-series-30ad108fbe2b)

~快乐学习*

收集电影数据

原文:https://towardsdatascience.com/collecting-movie-data-445ca1ead8e5?source=collection_archive---------12-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用一堆 API 来组装一个非常简洁的数据集

我最初的前提是,我可以试着根据 iTunes 电影的特点预测它的价格。我知道我们可以通过一个记录良好的公共 API 在 iTunes 中获得电影信息,所以让我们来看看。

iTunes 数据商店中的数据

您可以通过两种主要方式在 iTunes API 上从 iTunes store 获取影片信息,即通过关键词调用或按 ID 查找。显然,使用关键字来提取特定的电影通常不是一个好主意。有些关键词会给你多达 50 个匹配项(试试搜索“哈利波特”)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

With an average response time of 2s, 10 billion lookups is gonna take…

按 ID 查找也没有太大的改进。iTunes ID trackId字符串至少有 10 位数长,这意味着可能有多达 100 亿个可能的 ID,我必须一次查找一个。不是一个好主意。

所以我使用了 iTunes RSS 提要来缩小我的搜索范围。下面的代码片段定义了一个函数collect_rss_movies()来 ping iTunes RSS 提要。我决定依靠 RSS iTunes feed 来获取更多最新的电影和完整的价格信息。从 iTunes RSS 提要获得 iTunes IDs 后,我转向 iTunes API,使用get_info_by_id()功能从 iTunes store 获得电影信息。

我还定义了一个settings.py文件,它定义了集合参数。在这里,我指示该函数收集来自 9 个国家和 2 个主要流派的数据。

我最终放弃了纪录片的片名,因为相对于主流电影,它们看起来有点模糊,但这里有一个电影记录的片段:

**{'artistName': 'Christopher McQuarrie',
 'contentAdvisoryRating': 'PG-13',
 'country': 'USA',
 'currency': 'USD', 'primaryGenreName': 'Action & Adventure',
 'releaseDate': '2018-07-27T07:00:00Z',
 'shortDescription': 'On a dangerous assignment to recover stolen plutonium, Ethan Hunt (Tom Cruise) chooses to save his',
 'trackHdPrice': 19.99,
 'trackHdRentalPrice': 5.99,
 'trackId': 1406515547,
 'trackName': 'Mission: Impossible - Fallout',
 'trackNumber': 6,
 'trackPrice': 14.99,
 'trackRentalPrice': 5.99,
 'trackTimeMillis': 8873322,
 'wrapperType': 'track'}**

这就是它的要点——有一些特性我没有包括在这里,但是数据描述可以在官方的 i Tunes API 文档中找到,或者你可以在我的 Github 查看数据描述。

太好了!我们都准备做一个新的令人兴奋的机器学习项目。对吗?但是电影不仅仅是这些,不是吗?所以我做了更多的调查,想知道如何补充这个数据集。

打开电影数据库和电影数据库

虽然 IMdb 是所有电影信息的权威来源,但他们没有公共 API,即使我依靠网络搜集,我也很难找到我应该收集的电影。我求助于两个关于电影的开放数据库,即开放电影数据库 (OMdb)和电影数据库 (TMdb)。

电影数据库(TMDb)是一个社区建立的电影和电视数据库。从 2008 年开始,每一条数据都是由我们这个了不起的社区添加的。TMDb 强大的国际关注度和数据广度在很大程度上是无与伦比的,这是我们难以置信的骄傲。

所以这就是 TMdb 的出处。来自 OMdb 网站:

T4:OMDb API 是一个 RESTful web 服务,用于获取电影信息,网站上的所有内容和图片都是由我们的用户贡献和维护的。

为什么有两个电影数据库?

虽然它们分别得到了很好的维护,但它们各有利弊,我意识到我可能必须利用它们来为我的特性集提取正确的信息。两个数据库都没有在数据库中记录每部电影的 iTunes ID,所以我不得不依靠标题搜索来匹配 iTunes 数据和电影数据库中的每部电影。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Methods available to get information on a movie in the TMdb API

  • 特色。OMdb 有比我在 TMdb 数据集中找不到的更多的有用信息。例如,OMdb 包含关于电影评级的信息,例如烂番茄评级、Metacritic 评分和 IMdb 评级。OMdb 数据还记录了这部电影的票房表现,我觉得这将是预测一部 iTunes 电影能卖多少钱的一个关键特征。
  • API 能力。总的来说,TMdb API 功能更强,提供了更多的方法来查找信息。在 OMdb 中,你只能通过关键字搜索或 IMdb ID 来查找电影。此外,在 TMdb API 上进行关键字搜索通常会产生比 OMdb API 更好的结果。
  • API 比率限值。 OMdb 有一个非常严格的 API 速率限制,每天 1,000 个调用,而 TMdb API 有一个更高的速率限制,每秒 4 个请求(或每天约 340,000 个调用)。

所以OMdb API 有**更多我需要的信息,**但是 TMdb API 通常更好使用。我最终决定,我需要对 OMdb API 进行非常有针对性和具体的调用,通过 ID 查找来获取电影信息。OMdb 使用 IMdb ID 索引他们的电影记录,所以我必须通过关键字搜索找到 iTunes 数据集中每部电影的 IMdb ID,正如我提到的,通过 TMdb API 更好。

尽管有些复杂,我还是决定采用以下策略:

  1. 将电影标题解析为一个搜索字符串,通过 TMdb API 传递,寻找精确匹配。包括生产年份,以进一步缩小搜索范围。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Parsed movie titles, transformed into search strings for the TMdb API.

2.为了精确匹配,使用 TMdb ID 查找来查找 IMdb ID。对于没有匹配的结果,通过删除生产年份来放宽搜索标准。对于有多个匹配或结果的电影标题,从 Google 搜索的第一个结果中提取 IMdb,格式为“电影标题+制作年份+ IMdb”

3.将每部电影与一个 IMdb ID 进行匹配,并在 OMdb API 中查找每部电影的电影信息。

按照这个过程,我设法从 OMdb API 中唯一地识别出一个看起来相当健康的 603 部电影的数据集,其中与我在 iTunes store 上收集的 1800 部电影中的大约 1500 部相匹配,因此总体来说回报不错,而没有深入到实体解析的混乱世界中。这里有相当长的一段代码,但是你也可以在我的 Github repo 上查看。

票房 Mojo 数据

在我对 OMdb 数据做了一些初步探索之前,我对我拥有的数据非常满意。我注意到我的数据中有一大块票房信息缺失。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Over 40% of the movies in the OMdb data had missing box office receipt information.

我可以忍受缺失的评分,但票房表现将是纳入我的模型的一个很好的特征。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Dat feeling when you see so many missing values

很明显,我可以很容易地通过公共数据源获得信息。所以我求助于票房魔咒,使用曾经可靠的requestsBeautifulSoup组合。

我找到了大约 7000 部电影,填补了我所有缺失的价值,并补充了全球票房总收入与美国票房总收入的对比。现在的问题是把它们放在一起。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Merging data: Easy as Pen Pineapple Apple Pen

我的数据现在是什么样子

在所有这些争论之后,我有一个大约 1500 部电影的数据集,数据来自 4 个不同的来源,通过不同的键和方法连接。它们主要存在于我的存储库中的两个 csv 文件中,我已经为下面的数据库包含了一个广泛的模式。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这就结束了我关于收集电影数据的帖子。在接下来的一周左右,我会在这里发布关于建模和数据探索的更新。同时,如果您对我的数据收集过程有任何反馈、建议或改进,请联系我!

集体透明度

原文:https://towardsdatascience.com/collective-transparency-dc9b4b916e82?source=collection_archive---------22-----------------------

随着我们的隐私继续受到对数据的无休止追求的挑战,集体透明提供了解决方案吗?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Photo by ev on Unsplash

1999 年,Sun Microsystems 首席执行官斯科特·麦克尼利(Scott McNealy)有一句名言:“无论如何,你都没有隐私——克服它吧”他指的是围绕消费者数据隐私的担忧,这在今天继脸书/剑桥分析公司丑闻之后,就像在早期网络时代一样相关。

麦克尼利的评论提出了两个问题。首先,他说的对吗?第二,如果是,又能做些什么呢?

非自愿透明

这个问题的答案几乎肯定是:谁知道呢?我们生活在一个数据收集广泛且不断增长的时代,以至于我们很难不被称为数字文盲。但是在讨论隐私的时候,无知是一个无力的借口;无知通过遵从“你不知道的不会伤害你”的方法来回避任何讨论。但是无知确实支持了一个更强有力的论点——我笨拙地称之为“你并不特别”的论点。

在他的精彩著作 新黑暗时代 中,James Bridle 讨论了大数据和算法,这些数据和算法的优化超出了我们最疯狂的幻想。他在讨论无限乐趣空间时引用了科幻作家伊恩·班克斯的话。无限有趣的空间是超级复杂的人工智能去玩的地方,建造人类思维不可思议的世界,而我们人类却生活在一个完全优化的——而且非常无聊的——世界中。

“你并不特别”的论点是无知和超智能的结合:谁在乎你是否没有隐私,因为唯一能理解你的数据的东西是有更好的事情要做的计算机。虽然我不喜欢这种说法,但它确实强调了我们的许多隐私焦虑只是社交焦虑,这种焦虑来自于暴露给其他人。这些焦虑不会消失,但通过明智的社交媒体管理和某种形式的集体透明(我们将谈到这一点),其中一些担忧可以得到缓解。

但是隐私不仅仅是我们不想让世界知道的感觉和欲望。隐私会对一个人的财务和身份产生极其严重的后果。在这方面,隐私是比特币备受称赞的好处之一;虽然交易必须透明,但交易背后的人仍然是匿名的。确保这些领域的隐私是至关重要的,如果这样做可以获得很大收益,恶意行为者将不惜代价。如果麦克尼利关于隐私的观点是正确的,那么,建议我们忘掉它是不够的。

还有另一个版本的隐私,我们不应该就这么算了;行为隐私。行为经济学包含了一个叫做“轻推”的概念,即选择框架的微小变化会对结果产生重大且可预测的影响。我以前写过大数据和轻推如何结合成超轻推——超有针对性的个性化轻推,这些轻推从大量数据中提取信息来影响一个人的选择。超推荐的典型例子是个性化广告,比如展示你最近在不同网站上看到的产品的广告。对一些人来说,这些广告令人毛骨悚然,而对另一些人来说,他们更愿意看到他们感兴趣的东西的广告,而不是他们不感兴趣的东西。无论哪种方式,超轻敲都依赖于你的数据隐私。

后隐私

不管麦克尼利说我们没有隐私是否正确,隐私比他所说的要复杂得多。隐私可以指几个不同的东西,而且被侵犯的原因可能更多。但假设麦克尼利是对的,我们能做些什么呢?

那么,我们如何放弃我们的隐私?通常,我们认为我们的个人数据是一种货币,我们用它来交易各种服务。我之前已经论证过这不是一个好的思考方式,因为无论谁拥有它,货币的价值都是一样的;数据不是。法律数据学者 Karen Yeung 讨论了一个有趣的替代想法——集体隐私权。在这里,隐私不仅仅是个人的想法,而是一种社会的想法,即使个人“出售”他们的个人数据,这种想法仍然存在。

但是大数据改变了这一点。有了足够的数据,系统通常可以对可能从未向他们提供任何数据的个人做出准确的预测。不管侵犯隐私的目的是什么,这是一种侵犯,它引起了严重的道德问题——如果不是法律问题的话。但同样,大数据精灵已经从瓶子里出来了,因此我们必须开始考虑如何生活在后隐私时代。

如果我们的集体隐私权已经死亡,我们对个人隐私权的控制日益减弱,还有什么选择呢?答案可能是数据经济学家恩斯特·哈芬所说的“复制权。根据这项提案,作为公民,我们将有权要求任何人提供一份关于我们的任何数据的副本。当然,这并没有解决隐私问题,但它确实还给我们一些授权和控制。

对哈芬来说,这很重要:有了这些副本,他提议创建一个中央数据仓库。他认为,这个存储库有两个优势:它将得到民主管理,并将解除数据垄断,迫使大型科技公司在服务质量上竞争,而不是通过数据囤积和寻租策略。这个中央存储库是我称之为集体透明的一个版本。

走向集体透明

在某种程度上,复制的权利已经存在,社交媒体服务如脸书推特允许用户下载他们所有数据的副本。因此,实现集体透明与其说是关于归还数据控制权,不如说是关于建立新的数据基础设施。这就是集体透明的问题所在:人们仍然想要隐私;如此大量的数据可能会被用于非常不受欢迎的目的;我们如何确保对存储库的民主控制并且没有违规操作?

这些问题是有根据的,除非(或者如果)集体透明度成为一个活跃的项目,否则很难找到这些问题的具体技术答案。一个早期的解决方案可能建立在区块链技术的基础上,利用比特币这样的假名方法来保持透明度,而不暴露人们。加密货币还能够整合投票功能,这可能会解决民主问题,尽管如此重要的资源、公共和透明的治理结构似乎是必要的。这将把我们推向数据化民主的极限。

集体透明也可能不是解决办法。也许会有别的事情发生?也许我们会发现大数据的经济极限,它保证了我们的隐私,因为它不值得侵犯。但是,如果我们接受麦克尼利的主张,接受我们没有隐私——让·波德里亚称之为“非自愿透明”——集体透明似乎是一个有趣的选择,可以取代我们已经失去的东西。

利用 K-均值聚类的调色板提取|从零开始的机器学习(第四部分)

原文:https://towardsdatascience.com/color-palette-extraction-with-k-means-clustering-machine-learning-from-scratch-part-iv-55e807407e53?source=collection_archive---------13-----------------------

使用 Python 中的 K-Means 聚类在移动 UI 截图中查找主色

TL;DR 使用 Python 从头开始构建 K-Means 聚类模型。使用你的模型从 UI 移动设计截图中寻找主色。

为你的下一个大型移动应用程序(重新)设计选择调色板可能是一项艰巨的任务,尤其是当你不知道自己在做什么的时候。你如何能使它变得更容易(请求一个朋友)?

一种方法是去一个地方,在那里专家分享他们的工作。像 DribbbleuplabsBehance 这样的页面都有货。

找到您喜欢的模型后,您可能想要从中提取颜色并使用它们。这可能需要打开专门的软件,用一些工具和其他非处方工具手动选择颜色。让我们用机器学习让你的生活更简单。

[## 源代码

colab.research.google.com](https://colab.research.google.com/drive/1_p1nptDfvJhcSvprmi1WtoIugsCI40Xa)

无监督学习

到目前为止,我们只研究了需要特征和标签形式的训练数据的模型。换句话说,对于每个例子,我们也需要有正确的答案。

通常,这样的训练数据很难获得,并且需要人工完成许多小时的工作(是的,我们已经在为“终结者”服务)。我们能跳过这些吗?

是的,至少对于某些问题,我们可以在不知道正确答案的情况下使用示例数据。一个这样的问题是集群

什么是集群?

给定一些数据点的向量 X ,聚类方法允许您将每个点放在一个组中。换句话说,您可以根据一组实体的属性自动对它们进行分类。

是的,这在实践中非常有用。通常,你在一堆数据点上运行算法,并指定你想要多少组。例如,您的收件箱包含两组主要的电子邮件:垃圾邮件和非垃圾邮件(您是否在等待其他邮件?).你可以让聚类算法从你的电子邮件中创建两个组,并使用你美丽的大脑来分类哪个是哪个。

聚类算法的更多应用:

  • 客户细分 —寻找消费/行为方式相同的用户群
  • 欺诈交易 —查找属于不同分类的银行交易,并将它们识别为欺诈交易
  • 文档分析 —对相似的文档进行分组

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

source: various authors on https://www.uplabs.com/

这一次,我们的数据不是来自一些预定义的或众所周知的数据集。由于无监督学习不需要标记数据,互联网可以是你的牡蛎。

在这里,我们将使用来自不同作者的 3 个移动用户界面设计。我们的模型将在每个镜头上运行,并尝试提取每个镜头的调色板。

什么是 K-Means 聚类?

K-Means 聚类被维基百科定义为:

k-means 聚类是一种矢量量化的方法,起源于信号处理,常用于数据挖掘中的聚类分析。k-means 聚类旨在将 n 个观察值划分为 k 个聚类,其中每个观察值属于具有最近均值的聚类,作为该聚类的原型。这导致将数据空间划分成 Voronoi 单元。

维基百科还告诉我们,解决 K-Means 聚类是困难的(事实上, NP-hard ),但我们可以使用一些启发式算法找到局部最优解。

但是 K 均值聚类是如何工作的呢?

假设你有一个包含数据点的向量 X 。运行我们的算法包括以下步骤:

  1. X 中随机选取 k 个点(称为形心
  2. 将每个点分配到最近的质心。新形成的一簇点被称为
  3. 对于每个聚类,通过从这些点计算新的中心来找到新的质心
  4. 重复步骤 2–3,直到质心停止变化

让我们看看如何使用它从移动 UI 截图中提取调色板。

数据预处理

假设我们的数据存储在原始像素(称为图像)中,我们需要一种方法将其转换为我们的聚类算法可以使用的点。

让我们首先定义两个表示点和簇的类:

我们的Point只是我们空间中每个维度坐标的持有者。

Cluster由它的中心和它包含的所有其他点定义。

给定图像文件的路径,我们可以如下创建点:

这里发生了几件事:

  • 将图像载入内存
  • 将其调整为较小的图像(移动 UX 需要屏幕上的大元素,所以我们不会丢失太多的颜色信息)
  • 删除 alpha(透明度)信息

注意,我们正在为图像中的每个像素创建一个Point

好吧!现在,您可以从图像中提取点。但是,我们如何计算我们的集群中各点之间的距离呢?

距离函数

类似于我们的监督算法示例中的成本函数,我们需要一个函数来告诉我们做得有多好。我们算法的目标是最小化每个质心中的点之间的距离。

我们可以使用的最简单的距离函数之一是欧几里德距离,定义如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

其中和是我们空间的两点。

请注意,虽然欧几里德距离实现起来很简单,但它可能不是计算色差的最佳方式。

以下是 Python 实现:

实现 K 均值聚类

现在你已经有了所有的拼图,你可以实现 K-Means 聚类算法。让我们从寻找一组点的中心的方法开始:

为了找到一组点的中心,我们将每个维度的值相加,然后除以点数。

现在,为了找到实际的集群:

实现遵循上面给出的算法描述。请注意,当色差低于我们设置的值时,我们将退出训练循环。

估价

现在您已经实现了 K-Means 聚类,您可以在 UI 截图上使用它。我们需要更多一点的粘合代码,以便更容易提取调色板:

get_colors函数获取一个图像文件的路径和您想要从图像中提取的颜色数量。我们根据每个聚类中的点对从我们的算法中获得的聚类进行排序(降序)。最后,我们将 RGB 颜色转换为十六进制值。

让我们从数据中提取第一个 UI 截图的调色板:

这是十六进制的颜色值:

#f9f8fa, #4252a6, #fc6693, #bdbcd0, #374698

为了直观地展示我们的结果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在接下来的两个图像上运行聚类,我们得到以下结果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

最后一张截图:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

嗯,看起来很酷,对吧?继续在你自己的图像上试试吧!

[## 源代码

colab.research.google.com](https://colab.research.google.com/drive/1_p1nptDfvJhcSvprmi1WtoIugsCI40Xa)

结论

恭喜你,你刚刚实现了你的第一个无监督算法!当试图从图像中提取调色板时,它似乎也获得了良好的结果。

接下来,我们将对短语进行情感分析,并学习如何处理文本数据。

最初发表于

喜欢你读的吗?你想了解更多关于机器学习的知识吗?提升你对 ML 的理解:

* [## 从零开始实践机器学习

“我不能创造的东西,我不理解”——理查德·费曼这本书将引导你走向更深的…

leanpub.com](https://leanpub.com/hmls)*

数据科学家的着色规则

原文:https://towardsdatascience.com/coloring-rules-for-data-scientists-d946ccc1f823?source=collection_archive---------30-----------------------

讲述真实故事的视觉效果

作为数据科学家,我们希望确保清楚地传达我们的发现。无论我们的目标是技术或非技术受众,我们都想让我们的视觉效果“漂亮”。然而,我们真正应该考虑的是在我们的数据中讲述这个故事。不幸的是,我们所认为的好的设计和我们的数据的适当可视化并不总是一致的——但这里有一些规则来避免常见的错误,并确保你的视觉效果与你的故事相符。

1.配色方案:使用为您的数据设计的配色方案

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Image from MatplotLib Documentation

永远不要根据什么看起来最好来选择视觉效果的配色方案—使用为您的数据类型开发的配色方案。比如 bone 是为 x 光数据开发的,不要因为它好看的中性色就用它,用它做 x 光。有时,配色方案不会如此特定于领域,但您仍然应该使用一些反映数据本质的东西。例如,对于从-1 到 1 的值,如相关性,使用发散色图(例如: RdBucoolwarm ),对于分类数据使用定性色图(例如: Set1 )。这些颜色类别是专门为这些目的开发的,应该按照最初的意图使用,几乎没有例外。

2.混乱矩阵:这些应该总是表格

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Image from ResearchGate

这个很简单——不要绘制你的困惑矩阵。这种方式可能看起来很好,也更容易阅读,但它旨在成为一个表格。如果你不相信,想想其他的热图:为什么它们使用不同的配色方案?答案是它们有负值,混淆矩阵没有。

3.标签:标记你的颜色

在你制作的每张图表上标注你使用的所有颜色(除非只有一种颜色)。

4.对你的观众和内容保持敏感

首先,并不是所有的配色方案都能被色盲的人清楚地理解,所以如果你要制作广泛传播的图形,或者你的团队中有人是色盲,确保你使用的东西对每个人都清晰可辨。

其他关于敏感性的话题可能更有争议,比如使用分类的粉红色和蓝色调来表示性别,假设是二进制的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Image from OUPBlog

在绘制图表之前,请确保您考虑是否将性别分析为二元,以及为什么。如果你的数据没有反映一个光谱,并迫使你有 2 个类别,你可以选择澄清这一点。无论是哪种选择和原因,确保你有意识地考虑这一点,并选择你认为负责任的配色方案。

最后一点,这些规则是很好的参考,但要始终批判性地思考你试图想象什么,为谁,以及如何去做!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果你对如何解决某件事有疑问,请在下面评论,我会给每个人留下答案!

基于卷积神经网络的图像彩色化

原文:https://towardsdatascience.com/colorizing-images-with-a-convolutional-neural-network-3692d71956e2?source=collection_archive---------5-----------------------

深度学习算法对构图、风格以及机器学习和艺术之间的关系有什么看法

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Cuban immigrants arrive in Florida ca. 1965. Original image credit CDC, color version using Colorful Image Colorization algorithm credit Gado Images.

见过手绘历史照片吗?它们是艺术作品,由一个熟练的人在黑白照片的每个部分煞费苦心地着色,添加肤色、背景等等。自从摄影出现以来,它们就一直很受欢迎,直到今天仍在制作——唯一的区别是今天的艺术家使用 Photoshop 而不是画笔。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Hand colored images, like this lithograph of Cincinnati ca 1840s, were works of art. Credit: New York Public Library/Gado

手绘照片很美,但是制作起来很慢。你必须决定要添加的颜色,有绘画技巧将它们放到原始照片中,等等。即使使用现代工具,雇佣一名艺术家给一张历史照片上色也要花费 300 到 500 美元。

深度学习方法

进入卷积神经网络。在许多情况下,图像中的颜色是独一无二的——一个人衣服的确切颜色,一棵树完美的绿色阴影,等等。在拍下黑白照片的那一刻就永远消失了。然而,在其他情况下,颜色是可以预测的——令人惊讶的是。天空通常是蓝色的(或者很可能是蓝色的),绿色植物是绿色的,人的皮肤是肤色,水是蓝色的,衣服通常不是花哨或疯狂的颜色,等等。

因为颜色比你想象的更容易预测,使用机器学习比你最初想象的更容易控制。这意味着你实际上可以使用卷积神经网络来给历史黑白照片着色。

彩色图像彩色化是一种算法,它使用 CNN 来分析一组彩色图像及其黑白版本的颜色。这里很容易获得训练数据—任何彩色图像都可以转换为灰度,然后与其彩色版本配对,以制作一个简单的训练示例。该算法使用几个前馈通道来最终获取灰度图像,用该算法的创造者的话说,就是“幻觉”一组似乎合理(但不一定正确)的颜色来填充图像。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The Colorful Image Colorization algorithm can add plausible colors to black and white photographs. Original photo credit New York Public Library, colorization by Gado via Colorful Image Colorization

彩色图像着色在超过 100 万幅图像上进行训练。它的创造者报告说,当在“彩色图灵测试”中向人类展示结果时,人们在 32%的时间里相信颜色是真实的。这听起来没什么,但是请记住,这个任务甚至比给历史图像着色更难。图灵测试中的人们不仅仅相信他们看到的图像是一个执行良好的手工着色——相反,他们相信图像真的是彩色图像。这是一台灰度原始的机器——甚至 32%的时间——完成的相当成功。

在算法的结果中出现了一些非常显著的突现性质。例如,给定一个带有可口可乐标志的灰度历史图像,它会正确地将标志 Coca Cola 涂成红色,这可能是因为看到了数千个带有红色可口可乐标志的训练图像。重要的是,该算法从未被教会可口可乐的标志是什么——通过 CNN 的魔力,它从大量的训练数据中找到了这一点。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The algorithm correctly colored the drink car in this image Coca Cola red, presumably from seeing lots of red Coca Cola logos in its training data. Original image credit New York Public Library, colorization by Gado with Colorful Image Colorization.

那么颜色是不是一文不值?

当我第一次开始在灰度图像上测试彩色图像着色时,我的第一反应是不安,近乎厌恶。作为一名专业摄影师,颜色非常重要,我工作的很大一部分是让图像中的颜色完全正确,根据它们鲜明的颜色选择主题,等等。如此多的颜色是预先确定的——足以让机器能够猜测场景中的颜色并大致正确地得到它——这种想法令人不安,也有点令人沮丧。色彩真的是构图中一个有趣的元素吗,或者它是一种可以在以后由产生幻觉的计算机程序补充的东西吗?

这种观点当然有很多历史先例。著名纪实摄影师亨利·卡蒂埃·布列松以拍摄甘地的照片和世界各地人们的私密街头肖像而闻名,他对他同时代的威廉·埃格尔斯顿做了非常简洁的总结:“威廉,颜色是狗屁。”安塞尔·亚当斯——也许是 20 世纪最著名的美国摄影师——在他的职业生涯中,对色彩深表怀疑。具有讽刺意味的是,彩色图像着色的创造者们选择了在他们关于算法的第一篇论文中通过给一些 Adams 的图像着色来展示他们的过程。

那么所有的颜色都是预先决定的吗?我们能否发布一个出色的新压缩算法,让相机以灰度拍摄照片,然后像 CNN 一样的彩色图像着色技术在稍后的云中填充颜色?历史黑白摄影死了吗?我们是不是应该扔掉亚当斯的玻璃盘子,换上由机器创作的色彩鲜艳的风景画?

令人惊讶的算法

没那么快。像许多建立在卷积神经网络上的系统一样,彩色图像彩色化产生了一些显著的结果,但它与边缘情况作斗争。谢天谢地,视觉艺术的世界充满了边缘案例。

彩色图像着色做得最好的图像是那些具有可预测成分的图像——上面是蓝天,中间是一些风景,可能是一棵很明显的树,前景是一些水,它可以使之变成蓝色。有了这个算法,很多度假快照都变得很棒。从某种意义上说,它在“平均”图像上表现最好——这些图像的成分和颜色与它训练的 100 万张图像的平均成分和平均颜色没有太大差异。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The algorithm does best on images with a predictable composition. Original image credit New York Public Library, colorization by Gado with Colorful Image Colorization.

然而,对于具有不同构图、新颖物体和非常规颜色的图像,算法却很难处理。城市、壁画、色彩丰富的市场、有大量非天空负空间的图像——在这些图像上,色彩丰富的图像色彩表现平平。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The algorithm yields weird results on this unconventional composition of flowers shot through a window, splashing some random blue over the center of the image and totally missing the brick wall outside. Credit Gado Images.

在某种意义上,算法实际上是一个很好的图像唯一性的指示器。如果你的图像在通过算法着色后看起来非常好,那么它在组成和颜色方面可能是一个相当“普通”的图像——它与系统训练的数百万张图像没有太大差异。这并不一定意味着图像不好——许多构图一般的图像是商业金矿或描绘了一个重要的人或地方。有时一张普通的图像是好的,特别是当你想让你的构图和颜色选择不碍事,并且不干扰图像的纪录片内容的时候。

但是如果你创建了一个让彩色图像色彩“惊喜”的图像——产生奇怪或不准确的结果——拍拍你自己的背。你创造了一些偏离平均值的东西,足以骗过算法。简而言之,你创造了艺术上独一无二的东西。

对我来说,这弥补了围绕色彩的艺术过程。如果你想要一个符合视觉标准的图像,最好对它进行彩色化处理,看看电脑能不能猜出它的颜色。但令人欣慰的是,独特或视觉上不同的作品可以骗过算法——这证明了并非所有的颜色都是预先确定的,人类艺术家有能力让人感到惊讶。

实践中的算法

因此,除了一个整洁的机器学习聚会技巧或验证您的艺术选择的工具之外,彩色图像着色有价值吗?

绝对的。在某些历史照片上——尤其是肖像——该算法产生的结果非常可信,并赋予图像深度和活力,否则这些图像会变得更加平坦和缺乏活力。对于许多这样的肖像,如果有彩色胶卷的话,摄影师可能会使用它,所以给图像着色实际上相当于填充他们可能会包括的细节。

在某些情况下,算法的幻觉本身就是艺术。运行经典图像,如*进入死亡之口(*显示在诺曼底登陆的 D 日入侵期间,美国士兵在枪林弹雨中下船),产生令人难忘的梦境,其中颜色建立在原始构图的基础上,并增强了原始构图。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Running Colorful Image Colorization on the classic image Into the Jaws of Death yields a result which is artistic in its own right. Original image credit Signal Corps, colorization by Gado with Colorful Image Colorization.

尽管它的力量,彩色图像彩色化确实有盲点。虽然它产生幻觉的颜色看似可信,但它们并不总是历史上准确的——例如,本文顶部图像中的泛美标志看起来很红,但它实际上是蓝色的。

此外,很可能是由于在大量具有棕褐色而非真实颜色的历史照片上接受训练的结果,它倾向于以柔和的黄色和褐色色调渲染历史照片。一个有趣的实验是在一组真实拍摄的彩色历史图像上训练算法——就像一个大型的柯达彩色幻灯片档案——然后看看这个新版本在彩色历史图像上的表现。一个可以填充类似柯达彩色的 CNN 将非常适合处理历史图像,并可以在今天拍摄的图像上产生一些真正迷人的结果。

机器学习和艺术

最终,彩色图像彩色化是两个非常不同的领域——机器学习和艺术——走到一起时可能发生的有趣协同作用的一个令人信服的例子。你不会想到一个猜测颜色的神经网络会引发关于构图、主题选择和摄影作品独特性的存在性问题。你也不会想到它能重新点燃与艺术史观点的对话——就像卡蒂埃-布列松和亚当斯的观点——这些观点已经有半个多世纪的历史了。但是看看彩色图像彩色化的结果,这些问题就来了。

随着机器学习影响更多的行业,我希望视觉艺术家——实际上是所有的艺术家——开始关注这些技术提出的问题,包括关于社会和艺术过程本身的问题。如果机器学习要继续发展,它需要来自整个社会的艺术家、创意者和其他思想家的观点。但与此同时,机器学习可以回馈一些东西,展示看待艺术作品的新方法,甚至是创造艺术作品的新方法。像彩色图像着色这样的系统表明,当涉及到机器学习和艺术时,对话是双向的。

附注:首先,你应该收到我的邮件。 做到这里 !其次,如果你自己喜欢体验媒介,可以考虑通过注册会员 来支持我和其他成千上万的作家 。每月只需 5 美元,你可以阅读我所有最受欢迎的文章**等等。我在这个平台上已经收到了超过 1200 万的 浏览量 的文字!通过注册 与此链接 ,你将直接用你的一部分媒介费支持我,并获得我的文章,这不会花费你更多。如果你这样做了,万分感谢!**

在人工智能的帮助下给老 B&W 的照片和视频上色

原文:https://towardsdatascience.com/colorizing-old-b-w-photos-and-videos-with-the-help-of-ai-76ba086f15ec?source=collection_archive---------2-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

该项目基于加州大学伯克利分校张曦轲、菲利普·伊索拉和阿列克谢·埃夫罗斯的研究工作。彩色图像彩色化

本教程背后的想法是开发一个全自动的方法,将产生真实的黑白(B&W)照片和视频的彩色化。正如在原始论文中解释的那样,作者通过在训练时使用类别再平衡来增加结果中颜色的多样性,将问题作为一个分类任务,从而接受了潜在的不确定性。人工智能(AI)方法在测试时被实现为 CNN(“卷积神经网络”)中的前馈通道,并在超过一百万幅彩色图像上进行训练。

这张照片拍摄于 1906 年,展示了桑托斯·杜蒙的飞机“14-bis”在巴黎的首次测试:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

和它的彩色版本使用这些人工智能技术开发的模型:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

同样的技术也可以应用于老视频。这是 1932 年 B&W 拍摄的巴西里约热内卢的镜头:

彩色版本:

1.Lab 颜色空间

通常,我们习惯于使用 RGB 模型对彩色照片进行编码。RGB 颜色模型是一种加色模型,其中红色、绿色和蓝色光以各种方式相加在一起,以再现各种颜色。该型号的名称来自三种加色原色的首字母,即红、绿和蓝。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

但是,这个项目将使用的模型是“实验室”。

CIELAB 色彩空间(也称为 CIE Lab或有时简称为“LAB”色彩空间)是由国际照明委员会(CIE)在 1976 年定义的色彩空间。它将颜色表示为三个数值,L表示亮度,a和 b表示绿-红和蓝-黄颜色分量。

颜色空间 L * a * b *是在对立颜色理论之后创建的,其中两种颜色不能同时是绿色和红色,或者同时是黄色和蓝色。CIELAB 被设计为在人类色觉上是一致的,这意味着这些值的相同数量的数值变化对应于大约相同数量的视觉感知变化。

与 RGB 颜色模型不同,Lab 颜色旨在近似人类视觉。它渴望感知一致性,其 L 分量与人类对亮度的感知非常匹配。L 分量正是用作人工智能模型的输入,它被训练来估计剩余的分量“a”和“b”。

2.人工智能(深度学习)过程

正如引言中所评论的,人工智能(AI)方法在测试时作为 CNN(“卷积神经网络”)中的前馈传递来实现,并在超过一百万幅彩色图像上进行训练。换句话说,使用 Lab 模型分解了数百万张彩色照片,并将其用作输入特征(“L”)和分类标签(“a”和“b”)。为简单起见,让我们分成两部分:“L”和“a+b”,如框图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

有了训练好的模型(可以公开获得),我们可以用它来给一张新的 B&W 照片着色,这张照片将作为模型或组件“L”的输入。模型的输出将是其他组件“a”和“b ”,一旦添加到原始的“L ”,将返回一张完整的彩色照片,如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

简而言之,使用来自 ImageNet 的 130 万张照片的一组广泛而多样的对象和场景数据集,并应用深度学习算法(前馈 CNN),生成了最终模型,可在以下位置获得:

张等—彩色图像彩色化—模型

3.工作环境

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

首先要做的是组织一个我们将要工作的环境。让我们创建一个文件夹并命名为:

  • 照片 _ 视频 _ 彩色化

在这个创建的主目录下,让我们创建子文件夹:

  • 模型
  • 输入 _ 图像
  • 输入 _ 视频
  • 彩色图像
  • 彩色 _ 框架
  • 彩色 _ 视频

进入张等人-彩色图像着色-模型下载 3 个文件并加载到创建的子文件夹“/model”下。这些文件是:

  • colorization _ release _ v2 . caffemodel
  • colorization _ release _ v2 _ nore bal . caffe model
  • colorization _ release _ v1 . caffemodel

我假设您的机器上安装了 Python(3.6 版)和 OpenCV (4.0 版)。我们将使用 Jupyter 笔记本一步一步地描述着色的所有过程。我建议您遵循我的解释,但是如果您愿意,您可以从我的 GitHub 下载笔记本和测试照片:

照片 _ 视频 _ 彩色化

我还建议您阅读 Adrian Rosebrok 博士的伟大教程“OpenCV 和深度学习的黑白图像着色”,这是这个项目的灵感和指南。

4.黑白照片彩色化

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

让我们按照以下步骤给 BT&W 照片上色:

导入重要库:

import numpy as np
import matplotlib.pyplot as plt
import cv2

定义要着色的图像:

IMAGE = "soldiers_1941"

注意:你可以在这里使用任何照片。在这个例子中,我使用了一张 1941 年 B&W 二战士兵的照片。我的 GitHub 上有这张照片。

定义模型路径:

prototxt = "./model/colorization_deploy_v2.prototxt"
model = "./model/colorization_release_v2.caffemodel"
points = "./model/pts_in_hull.npy"
image =  "./input_images/"+IMAGE

加载序列化的黑白彩色模型和集群:

net = cv2.dnn.readNetFromCaffe(prototxt, model)
pts = np.load(points)

将聚类中心作为 1x1 卷积添加到模型:

class8 = net.getLayerId("class8_ab")
conv8 = net.getLayerId("conv8_313_rh")
pts = pts.transpose().reshape(2, 313, 1, 1)
net.getLayer(class8).blobs = [pts.astype("float32")]
net.getLayer(conv8).blobs = [np.full([1, 313], 2.606, dtype="float32")]

加载输入图像,缩放并转换到 Lab:

请注意,我们首先将图像转换为灰度。这一步并不是真的必要,但我意识到一些 B&W 的照片,尤其是旧的,可能会在岁月中有一些处理,所以,最好清理一下。

image = cv2.imread(image)
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
image = cv2.cvtColor(image, cv2.COLOR_GRAY2RGB)

此时,我们有了原始图像,但是为了在 Jupyter 单元格上直接显示它,我们应该使用 pyplot 库:

plt.imshow(image)
plt.axis('off');

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

提取“L”:

现在,让我们的“图像”继续进行着色过程,首先应该重新缩放,转换到 Lab,以提取组件“L”并使其居中:

scaled = image.astype("float32") / 255.0
lab = cv2.cvtColor(scaled, cv2.COLOR_RGB2LAB)
resized = cv2.resize(lab, (224, 224))
L = cv2.split(resized)[0]
L -= 50

预测“a”和“b”:

net.setInput(cv2.dnn.blobFromImage(L))
ab = net.forward()[0, :, :, :].transpose((1, 2, 0))
ab = cv2.resize(ab, (image.shape[1], image.shape[0]))

创建彩色实验室照片(L + a + b):

L = cv2.split(lab)[0]
colorized = np.concatenate((L[:, :, np.newaxis], ab), axis=2)

和我们处理灰度图像一样,让我们看看彩色图像是什么样子的:

plt.imshow(colorized)
plt.axis('off');
plt.title('colorized LAB image');

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Ops,似乎实验室图像不能告诉我们太多,让我们将其转换为 RGB,看看结果:

转换为 RGB:

colorized = cv2.cvtColor(colorized, cv2.COLOR_LAB2RGB)
colorized = np.clip(colorized, 0, 1)
colorized = (255 * colorized).astype("uint8")
plt.imshow(colorized)
plt.axis('off');

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Uau!相当惊人!!!!!这是一张 1941 年的照片,看起来真的是全彩拍摄的!还是省省吧:

保存最终的 RGB 照片:

cv2.imwrite("./colorized_images/Color_"+IMAGE, cv2.cvtColor(colorized, cv2.COLOR_RGB2BGR))

再来一个:查尔斯·达尔文 1832 年访问巴西里约热内卢:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

太好了!!!!试试其他 B&W 的照片,看看人工智能有多神奇!

5.给视频着色

一旦我们给照片上色,给视频上色就不是一件复杂的事情了。我们必须遵循以下一般步骤:

  • 获取 B&W 素材并加载到 input_video 子目录中
  • 阅读视频,一次一帧
  • 有一个单一的框架,适用于我们所做的照片
  • 有了彩色帧后,保存到另一个子文件夹: colorized_video_frames
  • 关闭 OpenCv 窗口。

我们来做一个真实的案例:

可以从我的 GitHub 下载笔记本B _ W _ Video _ colorization . ipynb,或者按照步骤操作。

我做的第一件事,是从 YouTube 上下载一部 B&W 的电影,在这个例子中:

为此,我使用了一个免费工具: VidPaw 来下载它。我给它命名为:“rio_32.mp4”,保存在 input_video 子文件夹。

应用上面描述的步骤,最后我们将所有彩色帧存储在子文件夹的彩色视频帧中。让我们开始吧:

1.开始定义应该着色的文件:

VIDEO = "rio_32.mp4"

2.定义路径、常量和视频变量:

prototxt = "./model/colorization_deploy_v2.prototxt"
model = "./model/colorization_release_v2.caffemodel"
points = "./model/pts_in_hull.npy"
video =  "./input_video/"+VIDEO
width = 500
vs = cv2.VideoCapture(video)

3.加载和准备模型:

net = cv2.dnn.readNetFromCaffe(prototxt,model)
pts = np.load(points)
class8 = net.getLayerId("class8_ab")
conv8 = net.getLayerId("conv8_313_rh")
pts = pts.transpose().reshape(2, 313, 1, 1)
net.getLayer(class8).blobs = [pts.astype("float32")]
net.getLayer(conv8).blobs = [np.full([1, 313], 2.606, dtype="float32")]

4.逐帧分割视频并应用模型:

count = 0
success = True
while success:
    success, frame = vs.read()
    if frame is None:
        break
    frame = imutils.resize(frame, 500)
    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    frame = cv2.cvtColor(frame, cv2.COLOR_GRAY2RGB)
    scaled = frame.astype("float32") / 255.0
    lab = cv2.cvtColor(scaled, cv2.COLOR_RGB2LAB) resized = cv2.resize(lab, (224, 224))
    L = cv2.split(resized)[0]
    L -= 50

    net.setInput(cv2.dnn.blobFromImage(L))
    ab = net.forward()[0, :, :, :].transpose((1, 2, 0)) ab = cv2.resize(ab, (frame.shape[1], frame.shape[0]))
    L = cv2.split(lab)[0]
    colorized = np.concatenate((L[:, :, np.newaxis], ab), axis=2) colorized = cv2.cvtColor(colorized, cv2.COLOR_LAB2BGR)
    colorized = np.clip(colorized, 0, 1)
    colorized = (255 * colorized).astype("uint8") cv2.imshow("Original", frame)
    cv2.imshow("Colorized", colorized)

    cv2.imwrite("./colorized_video_frames/frame%d.jpg" % count, colorized)
    count += 1
    key = cv2.waitKey(1) & 0xFF if key == ord("q"):
        breakvs.release()
cv2.destroyAllWindows()

上述循环过程,通常需要一段时间。例如,这个视频的彩色化过程(8 分钟)有大约 14,000 帧,我在 MacBook Pro 上花了大约 3 个小时——2.9 GHz Core i7,16GB 2133 MHz RAM。

5.一旦你有了包含帧的文件,你必须“重新组合”它来创建一个视频。下面的函数可以做到这一点:

**def** convert_frames_to_video(pathIn, pathOut, fps):
    frame_array = []
    files = [f **for** f **in** os.listdir(pathIn) **if** isfile(join(pathIn, f))]

    *#for sorting the file names properly*
    files.sort(key = **lambda** x: int(x[5:-4]))

    **for** i **in** range(len(files)):
        filename=pathIn + files[i]
        *#reading each files*
        img = cv2.imread(filename)
        height, width, layers = img.shape
        size = (width,height)
        print(filename)
        *#inserting the frames into an image array*
        frame_array.append(img)

    out = cv2.VideoWriter(pathOut,cv2.VideoWriter_fourcc(*'MJPG'), fps, size)

    **for** i **in** range(len(frame_array)):
        *# writing to a image array*
        out.write(frame_array[i])
    out.release()

请注意,根据您在计算机上安装的视频控制器,编解码器(*'MJPG ')应该更改。请查阅 OpenCV 文档。最终将会是一次“试错”的经历。

现在,您应该在彩色帧上应用上面的函数:

pathIn= './colorized_video_frames/'
pathOut = './colorized_videos/video.avi'
fps = 30.0
convert_frames_to_video(pathIn, pathOut, fps)

由此产生的“原始”视频可以在这里看到:

注意,视频明显没有声音。我所做的是用 iMovie 从 B&W 电影中剥离原始声音,并将其添加到彩色声音中。最后的结果在这里:

很酷,不是吗?;-)

6.向桑托斯·杜蒙致敬

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

借着给旧照片和视频上色的机会,我决定向上世纪最伟大的发明家之一阿尔贝托·桑托斯-杜蒙特致敬。

桑托斯-杜蒙(1873-1932)是巴西发明家和航空先驱,是为数不多的对轻于空气和重于空气的飞机的发展做出重大贡献的人之一。

桑托斯-杜蒙是一个富裕的咖啡生产商家族的继承人,他在巴黎致力于航空研究和实验,并在那里度过了他的大部分成年时光。在他早期的职业生涯中,他设计、制造并驾驶热气球和早期飞船,并于 1901 年 10 月 19 日因环绕埃菲尔铁塔的飞行而获得了德意志奖。然后,他转向了重于空气的机器,1906 年 10 月 23 日,他的 14-is 成为欧洲第一架动力重于空气的飞机,获得了法国航空俱乐部和国际航空联合会的认证。他坚信航空将开创一个世界和平与繁荣的时代,这让他自由地发表自己的设计,并放弃了各种创新的专利。

桑托斯-杜蒙确实是开放科学的早期专家,他的目标是为人类造福。一个例子是,他的 Demoiselle 飞机的所有计划都公开发表在 1909 年 12 月版的《大众力学》杂志上,其中写道:为了鼓励航空业,任何人都可以利用他的计划建造类似的机器。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这项工作的所有照片都是从第一个十年的 XX 世纪,并完全彩色的电脑,使用技术描述在这篇文章中,包括下面的视频。我希望你能欣赏它。

7.结论

一如既往,我希望这个项目可以帮助其他人找到进入令人兴奋的数据科学世界的方法!

详情和最终代码请访问我的 GitHub 资源库:mj robot-python 4 ds

来自世界南部的 Saludos!

我的下一篇文章再见!

谢谢你,

马塞洛

在机器学习中使用 SciKit 中的 ColumnTransformer 代替 LabelEncoding 和 OneHotEncoding 进行数据预处理

原文:https://towardsdatascience.com/columntransformer-in-scikit-for-labelencoding-and-onehotencoding-in-machine-learning-c6255952731b?source=collection_archive---------1-----------------------

在一篇非常老的帖子中,我展示了如何使用标签编码和一个热编码将分类文本数据分成数字和不同的列。但是自从我写了那篇文章之后,SciKit 库已经有了很大的进步,它让生活变得更加容易。

库的开发者可能已经意识到人们非常频繁地使用标签编码和一个酒店编码。所以他们决定开发一个名为 ColumnTransformer 的新库,它将 LabelEncoding 和 OneHotEncoding 合并成一行代码。结果是完全一样的。在这篇文章中,我们将快速地看一下我们如何用一些代码片段做到这一点。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

代码

首先,像往常一样,我们需要导入所需的库。我们将按照惯例处理混叠:

import numpy as np
import pandas as pd

接下来,让我们将一些数据放入一个变量,看看我们在处理什么:

dataset = pd.read_csv("/home/sunny/code/machine_learning/samples/sample.csv")

您可以使用 Spyder 中的“变量浏览器”视图来查看数据。在我的例子中,大概是这样的:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

正如你可以清楚地看出,这些数据毫无意义,显然只是为了这个演示。无论如何,这里的第一列是一个文本字段,在某种意义上是分类的。因此,我们将不得不标记编码,这也是一个热编码,以确保我们不会与任何层次结构。为此,我们仍然需要在代码中导入 OneHotEncoder 库。但是我们将使用新的 ColumnTransformer ,而不是 LabelEncoder 库。所以我们先导入这两个:

from sklearn.preprocessing import OneHotEncoder
from sklearn.compose import ColumnTransformer

接下来,我们必须创建一个 ColumnTransformer 类的对象。但是在我们这样做之前,我们需要理解类的构造函数签名。ColumnTransformer 构造函数接受相当多的参数,但是我们只对两个感兴趣。第一个参数是一个名为 transformers 的数组,它是一个元组列表。该数组以相同的顺序包含以下元素:

  • 名称:柱形变压器的名称,便于设置参数和查找变压器。
  • transformer :这里我们应该提供一个估计器。如果我们愿意,我们也可以只“通过”或“丢弃”。但是由于我们在这个例子中对数据进行编码,我们将在这里使用 OneHotEncoder。请记住,您在这里使用的估计器需要支持拟合和变换。
  • :要转换的列的列表。在这种情况下,我们将只转换第一列。

我们感兴趣的第二个参数是余数。这将告诉转换器如何处理数据集中的其他列。默认情况下,转换器将只返回被转换的列。所有其他列都将被删除。但是我们可以选择告诉转换器如何处理其他列。我们可以丢弃它们,不加修改地传递它们,或者指定另一个估计器,如果我们想做更多的处理。

现在我们(多少)理解了构造函数的签名,让我们继续创建一个对象:

columnTransformer = ColumnTransformer([('encoder', OneHotEncoder(), [0])], remainder='passthrough')

正如您在上面的片段中看到的,我们将把转换器简单地命名为“编码器”我们使用 OneHotEncoder()构造函数来提供一个新的实例作为估计器。然后我们指定只有第一列需要转换。我们还确保剩余的列没有任何变化地通过。

一旦我们构建了这个 columnTransformer 对象,我们就必须将数据集调整并转换为标签编码和热编码列。为此,我们将使用以下简单的命令:

dataset = np.array(columnTransformer.fit_transform(dataset), dtype = np.str)

如果您现在在变量资源管理器视图中检查您的数据集,您应该会看到类似如下的内容:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如您所见,我们仅使用 ColumnTransformer 类就轻松地对数据集中的一列进行了标签编码和热编码。这比同时使用 LabelEncoder 和 OneHotEncoder 类要简单和干净得多。

推特上关注我,了解更多数据科学机器学习,以及通用技术更新。此外,你可以关注我的个人博客,因为我在 Medium 之前发布了许多我的教程、操作方法帖子和机器学习的优点。

如果你喜欢我在 Medium 或我的个人博客上的帖子,并希望我继续做这项工作,请考虑在 Patreon 上支持我。

ColumnTransformer 符合自然语言处理

原文:https://towardsdatascience.com/columntransformer-meets-natural-language-processing-da1f116dd69f?source=collection_archive---------11-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Photo credit: Pixabay

如何在 scikit-learn 管道中将几个特征提取机制或转换组合成单个转换器

自从发表了几篇关于文本分类的文章后,我就收到了关于如何处理混合输入特征类型的询问,例如,如何在分类或回归模型中组合数字、分类和文本特征。

因此,我决定用一个例子来回答这个问题。

有几种不同的方法来追加或组合不同的特征类型。一种方法是使用[scipy.sparse.hstack](https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.hstack.html)水平堆叠稀疏矩阵。

不过我就介绍一个方法,新上线的热门宝贝: ColumnTransformer 函数来自 sklearn 。如果你想尝试一下,你需要将你的 sklearn 升级到 0.20。

数据

这个演示的一个优秀数据集是 Mercari 价格建议挑战赛,它建立了一个机器学习模型来自动建议正确的产品价格。数据可以在这里找到。

load_data.py

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Table 1

我们的数据包含异构数据类型,它们是数字、分类和文本数据。我们希望对这些不同类型的列使用不同的预处理步骤和转换。

例如:我们可能希望对分类特征进行一次性编码,并对文本特征进行 tfidf 矢量化。

“价格”是我们将要预测的目标特征。

数据预处理

目标特性—价格

df.price.describe()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 1

  • 去除价格= 0,探究其分布。

price_dist.py

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 2

目标功能价格向右倾斜。由于线性模型喜欢正态分布的数据,我们将转换价格,使其更正态分布。

log1p(price)_dist.py

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 3

df["price"] = np.log1p(df["price"])

特征工程

  • 用“其他”填充缺少的“类别名称”,并将“类别名称”转换为类别数据类型。
  • 用“未知”填写缺失的“品牌名称”。
  • 确定热门品牌,其余设置为“其他”。
  • 用“无”填充缺少的“项目描述”。
  • 将“项目描述标识”转换为类别数据类型。
  • 将“brand_name”转换为类别数据类型。

mercari_feature_engineering.py

我们的特点和目标:

target = df.price.values
features = df[['name', 'item_condition_id', 'category_name', 'brand_name', 'shipping', 'item_description']].copy()

拆分训练集和测试集中的数据:

X_train, X_test, y_train, y_test = train_test_split(features, target, test_size = 0.2, random_state=0)

下面是如何应用 ColumnTransformer 。令人惊讶的是,它非常简单。

  • 对“项目条件标识”和“品牌名称”进行编码。
  • 计数矢量器“类别名称”和“名称”。
  • tfidf 矢量器“item_description”。
  • 我们可以通过设置remainder='passthrough'来保留剩余的“shipping”特性。这些值被附加到转换的末尾:

columntransformer.py

模型和评估

我们将基于 ColumnTransformer 的预处理步骤与管道中的回归相结合来预测价格。

model_eval.py

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Jupyter 笔记本可以在 Github 上找到。享受这周剩下的时光吧!

参考资料:

[## 4.1.管道和复合估算器-sci kit-了解 0.20.3 文档

转换器通常与分类器、回归器或其他估计器结合,以构建复合估计器。的…

scikit-learn.org](https://scikit-learn.org/stable/modules/compose.html#column-transformer) [## 介绍 ColumnTransformer:将不同的转换应用到

真实世界的数据通常包含不同的数据类型。在应用最终预测之前处理数据时…

jorisvandenbossche.github.io](https://jorisvandenbossche.github.io/blog/2018/05/28/scikit-learn-columntransformer/)

组合学:排列、组合和处置

原文:https://towardsdatascience.com/combinatorics-permutations-combinations-and-dispositions-46604da34882?source=collection_archive---------15-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

组合学是数学的一个领域,主要研究对一个或多个集合中的元素进行计数。它可以帮助我们统计可能发生的订单的数量。

在本文中,我将详细介绍三种不同类型的技术:

  • 排列
  • 性情
  • 组合

排列

这些是最容易计算的。想象我们有 n 个物体,彼此不同。排列是这些物体的任何可能的排列。

考虑下面的例子。我们有一个盒子,里面有一些球(每个球有不同的颜色),我们想计算排列这些球的方式。我们可以用两种不同的方法做到这一点:重复(每个球在被捡起后都被放回盒子里)或者不重复。

  • 重复:这个想法是,在每一个球被提取后,我们可以根据自己的需要任意多次再次选择它。让我们简单地开始,考虑盒子={g,b},其中 g= ‘绿色球’,b= ‘蓝色球’:嗯,在这种情况下,我们可以排列那些球的可能方式是’ gg ‘,’ bg ‘,’ gb ‘,’ bb '。我们也可以用 Python 来计算:
box_1=['g','b']
perm=[]
for p in itertools.product(listA, repeat=2):
     perm.append(p)

perm

Output:
[('g', 'g'), ('g', 'b'), ('b', 'g'), ('b', 'b')]

让我们用 3 个球来代替:

box_2 = ['g','b','y']
perm=[]
for p in itertools.product(box_2, repeat=3):
     perm.append(p)

perm
Output:
[('g', 'g', 'g'),
 ('g', 'g', 'b'),
 ('g', 'g', 'y'),
 ('g', 'b', 'g'),
 ('g', 'b', 'b'),
 ('g', 'b', 'y'),
 ('g', 'y', 'g'),
 ('g', 'y', 'b'),
 ('g', 'y', 'y'),
 ('b', 'g', 'g'),
 ('b', 'g', 'b'),
 ('b', 'g', 'y'),
 ('b', 'b', 'g'),
 ('b', 'b', 'b'),
 ('b', 'b', 'y'),
 ('b', 'y', 'g'),
 ('b', 'y', 'b'),
 ('b', 'y', 'y'),
 ('y', 'g', 'g'),
 ('y', 'g', 'b'),
 ('y', 'g', 'y'),
 ('y', 'b', 'g'),
 ('y', 'b', 'b'),
 ('y', 'b', 'y'),
 ('y', 'y', 'g'),
 ('y', 'y', 'b'),
 ('y', 'y', 'y')]

现在我们的实验有 27 种可能的结果。如果我们想概括,当我们有 n 个对象,我们想看看我们可以用多少种方式排列它们,我们有:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • **没有重复:**在这种情况下,一旦你选择了一个球,它就不能再使用了。所以球的每种排列都有独特的值。在这种情况下,回到我们的 box={g,b},两种可能的排列是“gb”和“bg”:
import itertools 

box_1 = ['g','b']
perm = itertools.permutations(box_1) 

for i in list(perm): 
    print(i)

Output:
('g', 'b')
('b', 'g')

同样,让我们考虑一个更大的盒子={g,b,y},其中 y= ‘黄色球’:

box_2 = ['g','b','y']
perm = itertools.permutations(box_2) 

for i in list(perm): 
    print(i)

Output:

('g', 'b', 'y')
('g', 'y', 'b')
('b', 'g', 'y')
('b', 'y', 'g')
('y', 'g', 'b')
('y', 'b', 'g')

在这种情况下,我们必须考虑,在每次提取之后,可用元素的数量都要少一个。因此,如果我们的集合中有 n 个元素,排列将是:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

为了让您判断有重复和无重复排列之间的差异,让我们想象一下上面的例子。我们有一个盒子,里面有 4 个不同颜色的球:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们想计算这些球可能排列的数量,这意味着:我可以用多少种方式排列这些球,每次从盒子里挑选一个球?

如果每次提取后都没有替换,那么在第一阶段,有 4 种方法可以设置第一个元素(黄色、绿色、橙色和蓝色):

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

然后,我们一个接一个地挑选其他的球,在每个阶段,我们排列剩余球的方式都在减少:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

因此,最终,我们有 24 种可能的方法来排列这些对象,因为:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

另一方面,如果在第二阶段(以及接下来的阶段),我们重新插入取出的球:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

等于 256。

性情

部署只不过是排列,其中我们要挑选的对象的数量小于对象的总数 n。让我们简单地检索上面的示例,假设在三个球中,我们只想排列第一和第二个位置。让我们使用 box={g,b,y}并且让我们从重复的情况开始:

  • 重复:我们要从三个球(n=3)中选择两个球(k=2),并计算可能排列的数量:
box_2 = ['g','b','y']
perm=[]
for p in itertools.product(box_2, repeat=2):
     perm.append(p)

perm

Output:
[('g', 'g'),
 ('g', 'b'),
 ('g', 'y'),
 ('b', 'g'),
 ('b', 'b'),
 ('b', 'y'),
 ('y', 'g'),
 ('y', 'b'),
 ('y', 'y')]

这种情况下有 9 种可能的排列,而不是 27 种。与前一种情况一样,第一种选择有 n 种可能性,然后第二种选择又有 n 种可能性,以此类推,每次都相乘。但是这一次,这些将不是针对对象的总数(n)而是针对我们感兴趣的对象的数量(k)而被相乘。所以我们有:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 没有重复:如果没有重复,同样的推理成立。事实上:
box_2 = ['g','b','y']
perm = itertools.permutations(box_2,2) 

for i in list(perm): 
    print(i)

Output:
('g', 'b')
('g', 'y')
('b', 'g')
('b', 'y')
('y', 'g')
('y', 'b')

在这种情况下,我们有:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

再一次,让我们想象一下,考虑一个有 4 个球的盒子,我们只需要安排其中的两个。对于重复的倾向,我们有:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

而对于没有重复的处置,我们有:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

组合

组合是排列(或置换,如果 k=n ),其中顺序无关紧要。基本上,每当我们想计算有多少种方法时,我们就使用组合,从 n 个对象中,我们可以提取其中的 k 个,,不管这些对象被挑选的顺序如何

也就是说,如果你回忆起我们在最开始检查的没有重复的排列,其输出是“gb”和“bg”,等效的组合将只有“gb”(或只有“bg”),因为顺序无关紧要,因此它们代表相同的对象。

让我们看看 python,总是分别检查重复和不重复的两种情况:

  • 有重复:
from itertools import combinations_with_replacement 

box_1=['g','b']
comb = combinations_with_replacement(box_1, 2) 

for i in list(comb): 
    print(i)

Output:

('g', 'g')
('g', 'b')
('b', 'b')

如您所见,第四种排列“bg”不在这些组合中,因为它等同于“gb”。

这同样适用于 3 个球(让我们只组合其中的两个):

from itertools import combinations_with_replacement 

box_2=['g','b','y']
comb = combinations_with_replacement(box_2, 2) 

for i in list(comb): 
    print(i)

Output:

('g', 'g')
('g', 'b')
('g', 'y')
('b', 'b')
('b', 'y')
('y', 'y')
  • 无重复:
from itertools import combinations 

comb = combinations(box_1, 2) 

for i in list(comb): 
    print(i) 

Output:

('g', 'b')

有三个球:

from itertools import combinations 

comb = combinations(box_2, 2) 

for i in list(comb): 
    print(i) 

Output:
('g', 'b')
('g', 'y')
('b', 'y')

可能组合的数量(无重复)由下式给出:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这就是所谓的二项式系数,它被用在二项式概率分布中,用来计算在 n 次试验中有多少种方法可以获得 k 次成功。另一方面,如果我们允许重复,二项式系数变成:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

再一次,让我们用我们的球盒想象它,重复:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

没有重复:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

原载于 2019 年 9 月 7 日http://datasciencechalktalk.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值