用 Google Cloud、聊天客户端和 Ruby 构建一个情感检测机器人。
介绍
在这个系列中,我将解释如何创建一个聊天机器人,它能够检测情绪,分析图像,并最终拥有一个不断发展的个性的基础。这是该系列的第 1 部分。
这些碎片
- 红宝石
- 西纳特拉
- 谷歌云 API
- Line(聊天客户端)
因为我住在日本:
我将使用流行的聊天服务 Line 作为我们的客户。对于情感检测,我们将使用谷歌云自然语言 API 。选择的语言将是 Ruby(因为,为什么不),微框架 Sinatra 作为我们的服务器。好了,让我们开始吧!
设置聊天客户端
Line 是这里非常受欢迎的聊天服务;然而,你不需要真的住在这里才能注册。所以你应该可以顺利跟进。
一旦下载了 app,做了账号,就可以在这里注册成为开发者: Line 开发者页面。
我们需要创建一个新的“提供商”:
和消息传递 API“通道”:
现在,我们必须给我们的频道一个名称(这将是我们的机器人的显示名称),和应用程序图标(显示图片)。既然这是一个情感探测机器人,我们就用 apt 吧:“情感机器人”
Just a bit creepy…
创建时,请注意以下值:
- 频道秘密
- 通道访问令牌
此外,对设置进行以下更改:
- 使用 webhooks: 启用
- 自动回复消息:禁用
- 问候语:禁用
最后,我们必须设置我们的“Webhook URL”:这是 bot 和客户端通信的入口点。每当消息被发送到这个通道(我们的 bot)时,它将被中继到我们在这个字段中指定的任何端点。因为我们还没有,我们的下一步是创建一个。
设置服务器
服务器是我们的 bot 示例中的关键元素。实际上,它就是“机器人”。由于我们使用第三方聊天客户端(Line)作为我们的主要通信渠道,我们需要定义一个端点或 webhook,用于数据传输。
在这个上下文中,webhook 是一个 API 端点,聊天客户端将在收到消息时向其发布消息。然后由您(您的机器人)解析消息并提取必要的部分进行处理。处理完成后,我们会通过消息传递 API 将这些信息发送回我们的聊天客户端,最终由最终用户(即与您即将成为机器人的人)接收。
在这个例子中,我们将使用 Ruby 和微框架 Sinatra。
让我们继续创建我们的应用程序:
mkdir sentiment_bot && cd $_bundle inittouch main.rb
请注意,这些文件名和目录名完全是任意的,是为了简单和一致而选择的。
好了,让我们继续安装 Sinatra(我们的 web 框架),将以下内容添加到 Gemfile 中。
gem 'sinatra'
作为健全性检查,让我们创建一个准系统端点,当我们点击它时返回一个响应。作为“你好世界”的一部分,这将是我们的“こんにちは世界”。好了,我们开始吧,把下面的方法添加到 main.rb 中。
启动服务器:
ruby main.rb
并访问 localhost:4567/hello 。我们应该看到我们的问候响亮而清晰。世界上一切都是对的。现在,让我们设置端点,它将被用作聊天客户端和机器人之间的通信层。按照 Line 的要求,并且作为一个好的实践,这条路线将是一个“Post”,至于名称:“callback”是最好的。
将以下内容添加到 main.rb 中:
暂时把这条路留作空路也无妨。回到正题,我们的 webhook 需要是一个可公开访问的 https URL。然而,我们的服务器是在本地运行的。我们可以做到这一点的一个方法是将我们的代码推送到一个 PaaS ,比如 Heroku ,但是这有点超出了本教程的范围。现在,让我们使用令人惊奇的服务 Ngrok ,用于 HTTP 隧道。在您安装了ngrok 并启动了您的 web 服务器之后,您可以运行下面的命令来获取我们本地服务器的公共 URL:
ngrok http 4567
这告诉 ngrok 服务为本地端口 4567(这是 Sinatra 的默认端口)创建一个 URL。运行这个程序后,我们应该看到两个 URL 被打印到控制台,一个是 http,另一个是 https。我们将使用 https URL。它应该类似于:
[https://some_hex_string.ngrok.io](https://some_hex_string.ngrok.io)
复制它,并输入它作为您的僵尸网络挂钩网址,如下所示:
[https://some_hex_string.ngrok.io/callback](https://some_hex_string.ngrok.io/callback)
附加路径“callback”指的是我们刚刚在 main.rb 中添加的“post”方法。
一旦你输入了网址,你应该会看到一个“验证”按钮。点击后,我们应该看到对本地服务器的点击,并在线确认成功。
Upon Successful Verification
下一步是将我们的机器人添加为在线好友,并尝试与它交谈。我们没有给它任何功能,所以我们在这里的目标只是看看是否一切都通信正常:也就是说,当一个消息被发送到我们的机器人,我们的回调 url 实际上被触发。
使用您的 Line 移动客户端扫描为您的机器人提供的二维码。一旦你添加了你的机器人,给它发一条信息。您应该会再次看到我们的服务器被点击。
Sure, go ahead and add my bot.
我们已经验证了所有的东西都是相互关联的,但是如果聊天机器人不说话的话,它会很无聊。现在开始有趣的部分。
设置 Line SDK
当然,我们可以使用他们的文档编写自己的 Line API 工具,但这很耗时,超出了本教程的范围。还有,Line 刚好有官方 SDK。
将以下内容添加到您的 gem 文件中,并运行软件包安装:
gem 'line-bot-api'
既然已经安装了 gem,我们需要设置我们的凭证(可以从我们的开发控制台中获得)。
将以下导入添加到 main.rb 中
require 'line/bot'
以及以下内容:
这个方法将允许我们向我们的 bot/channel 发起经过验证的请求。你制作的每一个机器人都有一个唯一的秘密和访问令牌——你不应该公开这个信息,或者把它登记到你的版本控制系统中。
让我们继续设置从第行接收到的环境变量:
export LINE_CHANNEL_SECRET="you_channel_secret"
export LINE_CHANNEL_ACCESS_TOKEN="you_access_token"
现在,让我们将我们的“回调”函数更改如下(摘自 Line 的 sdk 文档):
现在,我们的机器人应该作为一个回声服务器,让我们来测试一下。
Rude…
好的,一切看起来都很好!我们已经将我们的机器人命名为“感知机器人”,所以它应该能够检测情绪。在自然语言处理的上下文中,情感测量给定输入相对于人类情感是消极的还是积极的(即,坏的还是好的)。一句“我爱你!”会被认为是积极的,而“我恨你!”会被认为是负面的。
设置 Google 自然语言
如果这是你第一次使用谷歌云,也就是谷歌最新的认证系统,那么你可以在这里查看他们的详细文档:https://Cloud . Google . com/natural-language/docs/quick start-client-libraries。
一旦你完成了你的项目设置并且你的授权已经排序,我们就可以继续将 ruby 客户端添加到我们的 Gemfile 中,当然也可以运行 bundle install:
gem 'google-cloud-language'
如果您已经正确设置了您的服务帐户并安装了客户端 SDK,那么从文档中复制示例代码并运行它。如果一切正常,您应该会看到类似下面的输出:
Overall document sentiment: (0.30000001192092896)
Sentence level sentiment:
Hello world: (0.30000001192092896)
一旦这些都工作了,让我们把它集成到我们的 bot 服务器代码中。目前,我们的机器人只模仿发送给它的任何文本或图像,但现在有了谷歌的力量,让我们把它变得更花哨一点。我们接下来的步骤如下:
- 阅读发送给机器人的任何文本
- 发送文本到谷歌进行情感分析
- 通过我们的机器人返回给用户的情绪得分
首先,让我们做一个检测并返回其输入情感的函数。我们可以通过以下方法做到这一点:
这些方法非常简单。“ google_language_client ”简单地实例化客户端,而“get _ opinion”使用所述客户端并返回任何可行文本输入的情感分析。
让我们将“/post”路线更改为以下内容:
That settles it…
假设你所有的外部服务都设置正确,你应该可以和你的机器人聊天,它会返回你的文本的情感分数。让我们试一试:
对于任何不幸与这样的机器人互动的人来说,仅仅返回一个情感分数是非常无聊的。让我们给它一点个性。
让我们将 main.rb 文件修改如下:
我们在这里做了一些改变。首先,我们添加了一些常量来保存我们的文本响应,我们还添加了一个新方法“get _ perspective _ response”,它检查情感得分并返回一个适当的回复。让我们试一试:
我们做到了!我们的机器人可以检测消息中的情绪,尽管词汇量有限,并做出相应的响应。
在本系列的下一篇文章中,我们将通过使用谷歌云视觉 API,让我们的机器人能够理解我们发送给它的图像。
建立一个类似的图像查找没有任何培训!
在本文中,我们将通过剖析图像对象分类器 VGG 的训练权重来构建一个相似图像查找器,并使用它从图像数据库中提取特征向量,以查看哪些图像彼此“相似”。这种技术被称为转移学习,在我们这边不需要任何训练——艰苦的工作在 VGG 实际接受训练的时候就已经完成了,我们只是重新使用训练过的权重来建立一个新的模型。
这个工具的一个很大的用途是对你想要的任何东西——食物、衣服、鞋子、动物、玩具,只要你能想到的,都可以做类似的图片推荐。例如,我们通过在普通牛排餐厅食物图像的小型数据库上查询测试汉堡图像来测试我们的推荐系统,它能够识别数据库中的其他汉堡:
Fig 1) Top 5 similar image recommendations from querying a burger image (left), t-SNE visualization of our image feature vectors for a small database of steakhouse foods (right)
在继续解释我们构建这个类似的图像查找工具的步骤之前,我们在 my Github 上分享我们的 Python 代码实现:
https://github . com/ankonzoid/artificio/tree/master/image _ retrieval
在本文的剩余部分,我们将演练解剖 VGG 以构建相似图像查找器的步骤。更多我关于深度学习和强化学习的博客、教程、项目,请查看我的 Medium 和我的 Github 。
解剖 VGG,建立一个类似的图像查找器
迁移学习是指利用从解决一个问题中获得的训练有素的知识来帮助解决另一个不同但相关的问题。然而,这并不像只是盲目地重新使用网络那么简单,因为只是在具有网络在训练期间未暴露的全新类别标签的图像上重新使用已训练的神经网络通常是没有希望的。例如,人们不会期望使用专门针对猫和狗图像训练的神经网络来正确地分类和区分鞋子品牌。那么如何才能恰当的迁移之前的学习来解决物体图像识别中的其他问题呢?
尽管神经网络不能准确地检测外来的高级特征(即,面部、身体、单词、标签),但是低级特征(即,边缘、纹理、颜色)是可靠地可转移的,因为它们在典型的训练图像中非常丰富和多样。这些低级功能是更抽象对象的小构件,如图 2 所示:
Fig 2) A great example of how low-level features are combined to construct high-level features in neural networks (extracted from “Convolutional Deep Belief Networks for Scalable Unsupervised Learning of Hierarchical Representations” by Lee, Grosse, Ranganath, Ng)
利用我们的“低级特征是可转移的”启发,我们可以采用训练过的图像对象分类器,如 VGG,移除其最后的高级层,并使用分割的模型将我们的图像(高维像素空间中的点)转换为表示 VGG 学习的低级特征的低维特征向量。有了这些特征向量,我们可以通过一些内积,如余弦相似性或欧几里德距离,直接比较它们的“相似性”,从而对我们的图像进行聚类,以进行推荐。
图 3 显示了我们如何剖析 VGG 并将其用于构建我们的相似图像查找器的示意流程图:
Fig 3) Schematic flow chart for how to apply transfer learning by dissecting VGG to create feature embedding vectors from our image database to compute “similarities” between images
总结一下我们构建相似图像查找器的步骤:
- 准备我们的图像数据库。
- 下载训练好的 VGG 模型,并删除其最后几层。
- 使用我们的解剖 VGG 模型将我们的图像数据库转换成特征向量。如果分割模型的输出层是卷积滤波器,则展平滤波器,并将它们附加成单个向量。
- 使用内积计算我们的图像特征向量之间的相似性,例如余弦相似性或欧几里德距离
- 对于每个图像,选择具有前 k 个相似性得分的图像来构建推荐
- (可选)获取特征向量并对其运行 t-SNE,以获得图像彼此相似程度的 2D 可视化
基于乳腺癌数据构建简单的机器学习模型
Fig: Machine Learning Model
简介
乳腺癌(BC)是全球女性中最常见的癌症之一,根据全球统计数据,其代表了大多数新癌症病例和癌症相关死亡,使其成为当今社会的重大公共健康问题。
BC 的早期诊断可以显著改善预后和生存机会,因为它可以促进对患者进行及时的临床治疗。良性肿瘤的进一步精确分类可以防止患者接受不必要的治疗。因此,BC 的正确诊断和患者的恶性或良性分类是许多研究的主题。由于其在从复杂 BC 数据集中检测关键特征方面的独特优势,机器学习(ML)被广泛认为是 BC 模式分类和预测建模的首选方法。
分类和数据挖掘方法是对数据进行分类的有效方法。尤其是在医学领域,这些方法被广泛用于诊断和分析以做出决策。
推荐的筛查指南:
**乳房 x 光检查。**乳腺癌最重要的筛查测试是乳房 x 光检查。乳房 x 光片是乳房的 x 光片。它可以在您或您的医生感觉到肿瘤之前两年内检测出乳腺癌。
年龄在 岁或以上的女性有患乳腺癌的平均风险,应该每年做一次乳房 x 光检查。
高危女性应该从 30 岁开始每年进行乳房 x 光检查和核磁共振检查。
乳腺癌的一些风险因素
以下是一些已知的乳腺癌风险因素。然而,大多数乳腺癌病例无法与特定原因联系起来。请向您的医生咨询您的具体风险。
年龄。随着女性年龄的增长,患乳腺癌的几率也会增加。将近 80%的乳腺癌发生在 50 岁以上的女性身上。
**乳腺癌个人史。**一个乳房患过乳腺癌的女性,另一个乳房患癌的风险更高。
**乳腺癌家族史。**如果母亲、姐妹或女儿患有乳腺癌,女性患乳腺癌的风险更高,尤其是在年轻时(40 岁之前)。有其他亲属患有乳腺癌也可能会增加风险。
**遗传因素。**具有某些基因突变(包括 BRCA1 和 BRCA2 基因的改变)的女性在其一生中患乳腺癌的风险更高。其他基因变化也可能增加患乳腺癌的风险。
生育和月经史。生第一个孩子的女性年龄越大,患乳腺癌的风险就越大。风险较高的还有:
- 年轻时(12 岁前)第一次来月经的妇女
- 绝经较晚的女性(55 岁以后)
- 从未生过孩子的女人
阶段 0 —数据准备
我们将使用 UCI 乳腺癌机器学习知识库数据集。
这个故事中使用的数据集是公开可用的,由美国威斯康星州麦迪逊市威斯康星大学医院的内科医生 William H. Wolberg 博士创建。为了创建数据集,Wolberg 博士使用了从实性乳腺肿块患者身上采集的液体样本,以及一种易于使用的图形计算机程序 Xcyt,该程序能够基于数字扫描进行细胞学特征分析。该程序使用曲线拟合算法来计算样本中每个细胞的 10 个特征,然后计算图像每个特征的平均值、极值和标准误差,返回 30 个实值向量
属性信息:
- ID 号 2)诊断(M =恶性,B =良性)3–32)
为每个细胞核计算十个实值特征:
- 半径(从中心到周边各点的平均距离)
- 纹理(灰度值的标准偏差)
- 周长
- 区域
- 平滑度(半径长度的局部变化)
- 紧凑性(周长/面积— 1.0)
- 凹度(轮廓凹陷部分的严重程度)
- 凹点(轮廓凹陷部分的数量)
- 对称
- 分形维数(“海岸线近似值”-1)
对每幅图像计算这些特征的平均值、标准误差和“最差”或最大值(三个最大值的平均值),得到 30 个特征。例如,字段 3 是平均半径,字段 13 是半径 SE,字段 23 是最差半径。
目标
该分析旨在观察哪些特征最有助于预测恶性或良性癌症,并了解可能有助于我们进行模型选择和超参数选择的总体趋势。目标是对乳腺癌是良性还是恶性进行分类。为了实现这一点,我使用了机器学习分类方法来拟合一个可以预测新输入的离散类的函数。
第 1 阶段—数据探索
我们将使用 Spyder 来处理这个数据集。我们将首先导入必要的库,并将数据集导入 Spyder:
#importing the libraries
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd#importing our cancer dataset
dataset = pd.read_csv(‘cancer.csv')
X = dataset.iloc[:, 1:31].values
Y = dataset.iloc[:, 31].values
Fig : Dataset and X set after importing the dataset
我们可以使用 pandas 的 head() 方法来检查数据集。
dataset.head()
Fig : top 5 data of our dataset
我们可以使用 panda 数据集的“shape”属性找到数据集的维度。
print("Cancer data set dimensions : {}".format(dataset.shape))Cancer data set dimensions : (569, 32)
我们可以观察到数据集包含 569 行和 32 列。诊断是我们将要预测的列,它表示癌症是 M =恶性还是 B =良性。1 表示癌症是恶性的,0 表示良性的。我们可以确定,在 569 人中,357 人被标记为 B(良性),212 人被标记为 M(恶性)。
数据可视化是数据科学的一个重要方面。这有助于理解数据,也有助于向他人解释数据。Python 有几个有趣的可视化库,如 Matplotlib、Seaborn 等。
在本教程中,我们将使用构建在 matplotlib 之上的 pandas 可视化工具来查找要素的数据分布。
Fig : Visualization of Dataset
缺失或空数据点
我们可以使用下面的 pandas 函数找到数据集的任何缺失或空数据点(如果有的话)。
dataset.isnull().sum()
dataset.isna().sum()
Fig : Observe missing data
阶段 2 —分类数据
分类数据是包含标签值而非数值的变量。可能值的数量通常限于一个固定的集合。
例如,通常按国家、性别、年龄组等来描述用户。
我们将使用标签编码器来标记分类数据。标签编码器是 Python 中 SciKit Learn 库的一部分,用于将分类数据或文本数据转换为数字,我们的预测模型可以更好地理解这些数字。
#Encoding categorical data values
from sklearn.preprocessing import LabelEncoder
labelencoder_Y = LabelEncoder()
Y = labelencoder_Y.fit_transform(Y)
Fig: Diagnosis Data without Encoding
Fig: Diagnosis Data after Encoding
分割数据集
我们使用的数据通常分为训练数据和测试数据。训练集包含一个已知的输出,模型学习这个数据,以便以后推广到其他数据。我们有测试数据集(或子集)来测试我们的模型对这个子集的预测。
我们将使用 Python 中的 SciKit-Learn 库通过 train_test_split 方法来实现这一点。
# Splitting the dataset into the Training set and Test setfrom sklearn.model_selection import train_test_split
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size = 0.25, random_state = 0)
Fig: Training and test set
阶段 3 —特征缩放
大多数情况下,您的数据集将包含在量级、单位和范围方面差异很大的要素。但是因为,大多数机器学习算法在它们的计算中使用两个数据点之间的欧几里德距离。我们需要将所有的特征提升到相同的数量级。这可以通过缩放来实现。这意味着您正在转换数据,使其符合特定的范围,如 0–100 或 0–1。
我们将使用 SciKit-Learn 库中的 StandardScaler 方法。
#Feature Scalingfrom sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)
阶段 4 —型号选择
这是将机器学习应用于任何数据集的最令人兴奋的阶段。它也被称为预测最佳结果的算法选择。
通常数据科学家对大型数据集使用不同种类的机器学习算法。但是,在高层次上,所有这些不同的算法可以分为两组:监督学习和非监督学习。
为了不浪费太多时间,我将简单介绍一下这两种学习方式。
监督学习:监督学习是一种既提供输入数据又提供期望输出数据的系统。输入和输出数据被标记以便分类,从而为将来的数据处理提供学习基础。监督学习问题可以进一步分为回归和分类问题。
一个回归问题是当输出变量是一个实值或连续值时,比如“工资”或“体重”。
一个分类问题是当输出变量是一个类别时,如过滤邮件“垃圾邮件”或“非垃圾邮件”
无监督学习:无监督学习是算法使用既未分类也未标记的信息,并允许算法在没有指导的情况下对该信息进行操作。
在我们的数据集中,我们有结果变量或因变量,即 Y 只有两组值,M(恶性)或 B(良性)。所以我们将使用监督学习的分类算法。
在机器学习中,我们有不同类型的分类算法
1.逻辑回归
2.最近邻
3.支持向量机
4.内核 SVM
5.朴素贝叶斯
6.决策树算法
7.随机森林分类
让我们开始应用算法:
我们将使用 sklearn 库导入分类算法的所有方法。
我们将使用 Logistic 回归方法进行模型选择,使用 Logistic 回归算法,
#Using Logistic Regression Algorithm to the Training Setfrom sklearn.linear_model import LogisticRegression
classifier = LogisticRegression(random_state = 0)
classifier.fit(X_train, Y_train)#Using KNeighborsClassifier Method of neighbors class to use Nearest Neighbor algorithm*from sklearn.neighbors import KNeighborsClassifier
classifier = KNeighborsClassifier(n_neighbors = 5, metric = 'minkowski', p = 2)
classifier.fit(X_train, Y_train)* #Using SVC method of svm class to use Support Vector Machine Algorithm *from sklearn.svm import SVC
classifier = SVC(kernel = 'linear', random_state = 0)
classifier.fit(X_train, Y_train)* #Using SVC method of svm class to use Kernel SVM Algorithm *from sklearn.svm import SVC
classifier = SVC(kernel = 'rbf', random_state = 0)
classifier.fit(X_train, Y_train)* #Using GaussianNB method of naïve_bayes class to use Naïve Bayes Algorithm *from sklearn.naive_bayes import GaussianNB
classifier = GaussianNB()
classifier.fit(X_train, Y_train)* #Using DecisionTreeClassifier of tree class to use Decision Tree Algorithm *from sklearn.tree import DecisionTreeClassifier
classifier = DecisionTreeClassifier(criterion = 'entropy', random_state = 0)
classifier.fit(X_train, Y_train)* #Using RandomForestClassifier method of ensemble class to use Random Forest Classification algorithm *from sklearn.ensemble import RandomForestClassifier
classifier = RandomForestClassifier(n_estimators = 10, criterion = 'entropy', random_state = 0)
classifier.fit(X_train, Y_train)*
现在,我们将预测测试集结果,并检查每个模型的准确性:
Y_pred = classifier.predict(X_test)
为了检查准确性,我们需要导入度量类的混淆矩阵方法。混淆矩阵是一种将错误分类的数量制成表格的方式,即,基于真实类别在错误的分类箱中结束的预测类别的数量。
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(Y_test, Y_pred)
我们将使用分类准确性方法来确定我们的模型的准确性。当我们使用术语“准确性”时,分类准确性就是我们通常所指的。它是正确预测数与输入样本总数的比率。
Fig: Accuracy
为了检查正确的预测,我们必须检查混淆矩阵对象并对角地添加预测结果,这将是正确预测的数量,然后除以预测的总数。
Fig: Confusion Matrix
在应用不同的分类模型后,我们得到了不同模型的以下准确度:
1.逻辑回归— 95.8%
2.最近邻— 95.1%
3.支持向量机— 97.2%
4.内核 SVM — 96.5%
5.朴素贝叶斯——91.6%
6.决策树算法— 95.8%
7.随机森林分类— 98.6%
最后,我们建立了分类模型,我们可以看到随机森林分类算法为我们的数据集提供了最佳结果。它并不总是适用于每一个数据集。为了选择我们的模型,我们总是需要分析我们的数据集,然后应用我们的机器学习模型。
这是机器学习模型对任何数据集的基本应用。如果你有任何疑问,请随时提问。给 vishabh1010@gmail.com 发邮件或者通过链接联系我。
你可以在 github 上找到代码,在 Ipython 控制台上试试。
切记始终牢记过度拟合和欠拟合的问题。
希望你喜欢这篇文章……
用 Python 为你的 Mac 构建一个简单的语音助手
最基本的 python 语音助手,可以帮你打开电脑应用或者搜索互联网
像 Siri 或 Cortana 这样的语音助手可以为你做一些很酷很有用的事情:打开应用程序、搜索信息、发送消息等等。虽然用别人给你的很酷,但是自己做更有趣。在这篇文章中,我将向你展示如何开始构建一个语音助手框架,它可以做完全开发的工具在 Mac 上所能做的 1%的事情——抱歉,我不会对任何其他操作系统做太多介绍。
Ironic Cortana Reference Since We’re on Mac — Source
就像我上一篇关于使用你自己的短信创建聊天机器人的博文一样,这不会是一个完全成熟的想法,也不会让你在制作中走得太远。老实说,我花了比编码更长的时间来寻找/制作这个帖子的 gif。
然而,如果你想知道如何用 python 创建自己的语音助手,并且喜欢瞎折腾的话,这篇博文应该会给你一个很好的起点。还有一些其他的帖子有着几乎相同的基本概念——但是在 TDS 上没有看到任何类似的东西,我想这到底是怎么回事🤷🏻我可以写得更好,我的会更有趣。
在这篇博文中,我将展示两种不同的语音激活功能:
- 打开应用程序
- 搜索互联网
设置和安装
我们首先需要两个特别的包裹。第一个是使用麦克风— 这篇文章很好地介绍了 python 中的语音识别。第二个和我过去的帖子一样,用 elasticsearch 做查询-查询匹配,返回一个响应。
portaudioelasticsearch
brew install portaudio
brew install elasticsearch
pipspeech_recognitionpyaudio
pip install SpeechRecognition
pip install pyaudio
pip install elasticsearch
Python 中的语音识别
speech_recognition
超级方便,如果你不想为任何其他供应商建立一个帐户。在不到 10 行代码中,这个包应该让我们连接到我们内置的计算机麦克风,并转录我们的声音!
import speech_recognition as srr = sr.Recognizer()
mic = sr.Microphone()with mic as source:
r.adjust_for_ambient_noise(source)
audio = r.listen(source)
transcript = r.recognize_google(audio)
print(transcript)
这段代码应该运行到它听到什么为止,然后把你说的话(或者它认为你说的话)打印出来。超级简单。关于这些类以及它们如何工作的更多信息,请参考前面提到的帖子。
给你的电脑一个声音
在 Python 中有多种方法可以做到这一点,但是最简单的方法就是使用 macOS 自带的方法。使用子进程包,我们可以很容易地让我们的计算机说话:
import subprocessdef say(text):
subprocess.call(['say', text])say("yo whatup dog")
打开电脑上的应用程序
所以现在你可以把声音转换成文字,让你的电脑说话,世界就是你的了,生病了。现在我们可以决定如何使用输入。对于一个简单的想法,我的第一反应是用它来打开应用程序。显然,它一点也不酷,但作为一个例子,它工作得很好,我将使用的一般结构可以应用于更广泛的功能。因此,让我们首先获得我们所有应用程序的列表。
/Applications.app
d = '/Applications'
apps = list(map(lambda x: x.split('.app')[0], os.listdir(d)))
列出目录并删除扩展名。酷毙了。
os
import osapp = 'Spotify'
os.system('open ' +d+'/%s.app' %app.replace(' ','\ '))
.replace
在 Elasticsearch 中索引您的数据
transcript == 'open spotify'
来自我在 chatbots 上的上一篇博文——“elastic search 是一个可扩展的搜索平台,它使用类似于 TF-IDF 或词频逆文档频率的算法。本质上,它是一个简单的功能,经常在搜索/相似性空间中使用,根据关键字定位文档…有关它的基本概述,请查看维基百科。”
基本上,我们会将所有语音命令(类似于“打开 spotify”)上传到 elasticsearch,并将它们映射到我们想要运行的系统命令(实际的编程命令)。为此,我们可以快速创建一个字典列表。
import osd = '/Applications'
records = []
apps = os.listdir(d)for app in apps:
record = {}
record['voice_command'] = 'open ' + app.split('.app')[0]
record['sys_command'] = 'open ' + d +'/%s' %app.replace(' ','\ ')
records.append(record)
elasticsearch
voice_assistant
from elasticsearch import Elasticsearch
from elasticsearch.helpers import bulkes = Elasticsearch(['localhost:9200'])
bulk(es, records, index='voice_assistant', doc_type='text', raise_on_error=True)
voice_assistantresponse
def search_es(query):
res = es.search(index="voice_assistant", doc_type="text", body={
"query" :{
"match": {
"voice_command": {
"query": query,
"fuzziness": 2
}
}
},
}) return res['hits']['hits'][0]['_source']['sys_command']
search_es('open spotify')os.systemopen /Applications/Spotify.appfuzzinesssearch_es('open spofity')
尽管这是一个很小的功能,但这里的关键是这个原则可以应用于许多不同的功能——Q & A、其他命令等等
在语音助手中将所有这些结合在一起
search_es
def activate(phrase='hey dude'):
try:
with mic as source:
r.adjust_for_ambient_noise(source)
audio = r.listen(source)
transcript = r.recognize_google(audio)
if transcript.lower() == phrase:
return True
else:
return False
使用这个触发器,我们现在可以更有选择地激活我们的实际搜索功能。在我们之前定义的函数的帮助下,我们可以将代码封装在一个无限循环中,这样它就会一直运行,等待我们激活它。我让我的助手在运行任何东西之前问我它能有什么帮助,显然你可以随意用你的名字替换“凯尔”。
import speech_recognition as sr
import os
from elasticsearch import Elasticsearch##start python client
es = Elasticsearch(['localhost:9200'])##initialize speech recognizer and mic
r = sr.Recognizer()
mic = sr.Microphone()while True:
if activate() == True:
try:
say("Hey Kyle, how can I help you today?")
with mic as source:
print("Say Something!")
r.adjust_for_ambient_noise(source)
audio = r.listen(source)
transcript = r.recognize_google(audio)
sys_command = search_es(transcript)
os.system(sys_command)
say("I opened that application for you")
except:
pass
else:
pass
except
elasticsearch
额外收获:用 Selenium 搜索谷歌的语音助手
requestsBeautifulSoupselenium
安装 selenium 和 web 驱动程序
pip
pip install selenium
从 python 搜索 google
seleniumwebdriver.Chrome()
from selenium import webdriver
from selenium.webdriver.common.keys import Keysdef search_google(query):
browser = webdriver.Chrome()
browser.get('[http://www.google.com'](http://www.google.com'))
search = browser.find_element_by_name('q')
search.send_keys(query)
search.send_keys(Keys.RETURN)
就是这样。Selenium 在一个窗口中打开谷歌,找到搜索栏,为我们键入内容,然后单击搜索按钮。您可以快速测试它,以确保它正常工作:
search_google('how to build a voice assistant in python')
谷歌搜索的语音助手
不像以前,我们没有一个弹性搜索索引来查找我们的信息——我们的搜索更加动态,我们必须做一些更简单的文本预处理。假设我们的查询将包含短语“search google for ”,我们可以在那里分割字符串,并将字符串的其余部分传递给我们的函数。
while True:
if activate() == True:
try:
say("Hey Kyle, how can I help you today?")
with mic as source:
print('Say Something!')
r.adjust_for_ambient_noise(source)
audio = r.listen(source)
transcript = r.recognize_google(audio) phrase = 'search google for ' if phrase in transcript.lower():
search = transcript.lower().split(phrase)[-1]
search_google(search)
say("I got these results for you")
else:
say('I only search google, sorry fam')
except:
pass
else:
pass
未来方向
酷,现在你也有一个语音助手不断听你搜索互联网或打开应用程序。你还可以做更多的事情:在同一个助手中把它们绑在一起(我不喜欢),整合新闻/天气 API,也许自动化电子邮件内容,在 elasticsearch 中放入你自己的自定义短语,为激活建立一个更复杂的模型,等等……但这只是一个不错的开始。希望你喜欢它!
构建皮肤病变分类 Web 应用程序
使用 Keras 和 TensorFlow.js 对七种类型的皮肤病变进行分类
对卷积神经网络进行研究后,我对开发一种端到端的机器学习解决方案产生了兴趣。我决定使用 HAM10000 数据集构建一个 web 应用程序来对皮肤病变进行分类。在本文中,我将提供一些背景信息,并解释我在这个项目中学习的一些重要概念,包括迁移学习、数据增强、Keras 回调和 TensorFlow.js.
Photo by rawpixel on Unsplash
人工智能正在塑造我们周围的世界。我们每天都与机器学习触及的事物互动。从我们的歌曲和视频推荐到手机里的智能助手。但是这些都是人工智能的消费者应用,那么更大规模的人工智能呢?
“就像 100 年前电力改变了几乎所有事物一样,今天我真的很难想象一个我认为人工智能在未来几年内不会改变的行业。”——吴恩达
就我个人而言,我认为医疗保健是一个具有巨大深度学习潜力的领域。尽管我们的技术有了长足的进步,但今天仍然有一个问题仍然是一个重大问题。据报道,约 10%的死亡和 6%至 17%的医院并发症是由诊断问题引起的。想象一下,借助机器学习模型,帮助医疗专业人员诊断患者,将这一数字降至不到 5%。影响将是巨大的!
在我上一篇关于卷积神经网络的文章中,我谈到了计算机视觉是如何应用于各种行业的。我强烈建议您在这里查看。
关于皮肤癌的一些背景信息
- 美国每年被诊断出患有皮肤癌的人数高于其他所有癌症患者的总人数。
- 五分之一的美国人到 70 岁时会患上皮肤癌。
- 光化性角化病影响超过 5800 万美国人。
我想建立一个解决方案,利用回旋神经网络来帮助人们快速准确地分类不同类型的皮肤癌。我的主要目标是创建一个容易访问和有效的项目。我最终决定建立一个网络应用程序。
在这个项目中,我使用了公开的 HAM10000 数据集,其中包含了大约 10000 幅不同的皮肤病变图像。
皮损类别包括:
akiecbccbkldfmelnvvasc
更多关于数据集或皮肤癌分类的信息请参考本文。
卷积神经网络模型的转移学习
Photo by Mika Baumeister on Unsplash
如果您一直在处理任何类型的数据,当您开发深度学习模型时,您会知道数据是最重要的东西。但是,大多数时候,您的数据集可能不够大,无法获得最佳性能。总的来说,我们谈论的是至少 50,000 幅图像。拥有大量层的网络训练也非常昂贵。如果您没有一个(或几个)令人惊叹的图形处理器,这可能需要很长时间。😢
迁移学习背后的整个理念是,您可以在一个大数据集上获取一个已经过预先训练的模型,对其进行修改,然后在您当前使用的数据集上对其进行重新训练。
正如我在上一篇文章中所解释的,卷积神经网络在图像中寻找不同的特征,比如边缘和形状。我们可以采用一个具有数百万个连接的神经网络,该网络已经接受了识别不同特征的训练,并通过“冻结”前几层来重新训练其中的一部分。在添加了一个完全连通的图层之后,仅通过对最后几个图层进行训练,我们就可以获得一个模型,该模型可以有效地识别基本特征,但做出的预测会很好地利用相关数据进行推广。
A diagram depicting the use of transfer learning to retrain layers of a network. Source.
Keras 应用程序库包括几个深度学习模型,包括 VGG16、VGG19、ResNet50、MobileNet 和其他一些模型。**他们都在 ImageNet 数据集上进行了训练,该数据集包含大约 1400 万张图像。**与我们的 10,000 幅图像数据集相比,这是一个非常明显的差异。
对于这个项目,我选择使用 MobileNet 架构,它针对计算能力较低的移动应用进行了优化。这种架构利用了深度方向可分离的卷积,这实质上有助于减少训练参数的数量,使模型更加轻量级。有关 MobileNet 的更多信息,请查看本文。
以下是我们在 Keras 可以做到的。
皮肤病变图像的预处理
关于 HAM10000 数据集的一个好处是所有的图像都是相同的大小,600x450。然而,在查看了图像的分布后,我们看到大多数图像属于黑色素细胞痣类。
Left: total number of images in each class. Right: number of training images in each class.
扩充训练数据
当涉及到增加我们可以处理的训练样本数量时,数据扩充是非常有用的。我们可以扩充训练数据,为此,我们使用来自 Keras 预处理库的 Keras ImageDataGenerator 类,它通过批量循环数据来生成具有实时扩充的批量张量图像数据。我们传递的一些参数是:
rotation_rangewidth_shift_rangeheight_shift_rangezoom_range=0.1horizontal_flip=Truevertical_flip=Truefill_mode='nearest'
我们可以通过运行下面的代码来声明一个扩充的数据生成器。我们的目标尺寸是 224x224,因为这是 MobileNet 输入层所需的尺寸。
编译模型
ReduceLROnPlateauModelCheckpoint
ReduceLROnPlateau
monitorfactor=0.5patience=2mode='max'
ModelCheckpointsave_best_only=True
绘制预测的混淆矩阵
nvakiecbccbklnvvascdfmelnvnvbkl
保存模型并将其转换为 TensorFlow.js
model.h5
在浏览器中运行机器学习
TensorFlow.js 是 Google 流行的深度学习框架 TensorFlow 的 JavaScript 版本。它由一个低级核心 API 和一个高级层 API 组成。我认为 TensorFlow.js 非常酷的主要原因有两个。
- TensorFlow.js 和 WebGL 可以在任何种类的 GPU 上运行,包括 Nvidia、AMD 和 phone GPUs。
- 您可以将现有模型转换为 TensorFlow.js 模型,并轻松地重新调整它们的用途。
- 模型在浏览器中本地运行,这意味着用户的数据永远不会离开他们的计算机。
最后一点尤其重要,因为你显然可以想象,如果在线自我诊断变得普遍,这在未来将是多么重要。客户端的训练和推断有助于确保解决方案是隐私友好的!
你可以在这里找到我的项目的代码,在这里找到模型的现场版本。
关键要点:
- 当你不需要大量数据或计算能力时,迁移学习是有用的
- 数据扩充也是确保您有足够的训练数据来确保您的模型表现良好的另一种方法
- TensorFlow.js 让您可以在浏览器中和客户端轻松运行机器学习模型
感谢阅读!如果您喜欢,请:
- 在 LinkedIn 上添加我,关注我的媒体,了解我的旅程
- 留下一些反馈或者给我发邮件(alex@alexyu.ca)
- 与你的网络分享这篇文章
构建溶解度预测器
科学名义下的神经网络
人们正在沉睡于 21 世纪最激动人心的事件之一;技术和科学的交汇点。就像两个星系碰撞一样,随着我们开始意识到并获得合作的好处,科学和技术正在继续模糊行业之间的界限。
The real tree of knowledge; science, arts, and technology
最引人注目的合作项目之一是人工智能和化学之间正在萌芽的新关系**。**的起点化学信息学加速了过去陈旧的研究过程,让工业和学术界的研究团队转向更快的化学创新。这些新的见解为研究开辟了新的途径,并释放出一个非常重要的副产品:数据。
我们对科学的理解让我们看到了更大的图景,现在比以往任何时候都更加明显的是,物理学和生物学、电子学和纺织以及其他任何领域之间几乎没有什么区别。我们的研究方法已经从经验主义转向更加数据驱动的方法,特别是当我们开始理解我们所拥有的数据中的潜在模式时。
数据有助于进行预测,运行模拟,并用于一整套计算过程,这些计算过程将科学方法的速度提高了好几年;随着我们收集的数据越来越多,速度只会越来越快。
尽管仍然供不应求,特别是与文本、数字和图像数据的巨大数据集相比,化学数据正在慢慢增加,并且一线希望是明显的;我们越来越接近技术融合。尤瓦尔·诺亚·哈拉里认为,正是数据/人工智能和生物学/生物技术的融合将决定人类的未来。如果生物学确实是数据的阴阳两极,那么物理学和化学就是这场婚姻的催化剂。毕竟:
生物只是活化学,化学技术上只是应用物理。
尽管如此,方向是明确的;我和化学是天作之合。
项目已解散
使用 SMILES 分子表示格式,我建立了一个能够预测给定分子溶解度的神经网络。在超过 1000 个数据点的数据集上训练,预测器能够以相当高的精度预测分子的溶解度。
该项目分为 4 个部分
- 导入、格式化和规范化带标签的 SMILES 数据集
- 将微笑转化为分子,然后转化为二进制指纹
- 构建深度神经网络模型
- 编译、拟合、训练和测试模型
使用与我的分子电荷分类器神经网络类似的技术,我将微笑字符串转换成每个 256 位的二进制指纹。这允许算法为每个输入神经元输入一位(因此有 256 个神经元输入层)。由于溶解度可能是负值,我使用了 tanh 激活函数,因为 tanh 表示负值。
作为损失函数,该项目使用带有 Adam 优化器的均方误差,因为两者都非常适合于单输出预测。利用我的 1000 个分子的数据集,我以 0.0005 的学习速率和 5 的批量大小训练算法,超过 200 个时期。1000 个微笑字符串中的 10%被保留作为验证数据。
经过训练,我意识到虽然损失确实在减少,但准确率一直低于 1%。在对潜在的错误进行了大量的努力之后,我意识到问题不在于算法或者我的数据预处理技术;问题在于数据本身。经过一些研究,我了解到溶解度是由成分和结构决定的。这是非常重要的,因为我的数据格式没有显示三维结构,只有分子的组成部分。
然而,更重要的是环境变量。温度和压力等外部条件会影响分子的溶解度。算法中没有指定这些条件,因此无法对算法进行训练。
从本质上讲,有一些因素可以增强和解决这些问题:

- 规定的环境参数
- 更多标记的数据点
- 一种更体贴的分子表示方法
最终,该算法未能以有意义的准确性预测被搁置的 10 种测试分子的溶解度。同样的算法可以用于其他目的,所以我把代码上传到了 Github。知识库包括 2 组数据和模型文件。
为了继续探索人工智能和化学之间的互利关系,必须记住一些必要的行动:
- 跨两个字段共享数据
- 与两个领域的专家合作
- 发展共同语言/共同点
- 发展势头并自动化流程
如果我们继续走这条路,可以毫不夸张地说,也许有一天,化学创新将掌握在我们人工智能创造的安全手中。
关键要点
- 随着科学、技术和工业的碰撞,未来取决于我们的创新
- 由于技术的发展,科学之间的界限正在被跨越;更确切地说,多亏了数据
- 神经网络受益于可用数据的激增,使得预测、分类和生成的结果更加准确
- A.I 从给定数据集中的模式中学习;如果没有相关性,人工智能的输出将会非常不准确。
- 当我们将我们的人力资源、语言和数据集中在一起时,我们可以更有意识地加速开发。
用 Tensorflow 对象检测 API 构建玩具检测器
用数据做酷事!
这个项目是我的热门项目的第二阶段-Google tensor flow 物体检测 API 是实现图像识别最简单的方法吗?在最初的文章中,我使用 Tensorflow 提供的模型来检测 youtube 视频中的常见对象。这些模型在 COCO 数据集上进行训练,并在该数据集中包含的 90 个常见对象上运行良好。
这里我扩展了 API 来训练一个不属于 COCO 数据集的新对象。在这种情况下,我选择了一个到处都是的玩具。见下图 gif。到目前为止,我对 API 的性能印象深刻。这里强调的步骤可以扩展到您想要构建的任何单个或多个对象检测器。
Tensorflow Toy Detector~
你可以在我的 Github repo 上找到代码
- 收集数据
第一步是为您的项目收集图像。你可以从谷歌上下载它们,确保你在角度,亮度,比例等方面有很大的变化。在我的例子中,我创建了一个小飞机玩具的视频,并使用 Opencv 从视频中提取图像。这节省了我很多时间。我确保图像是从多个角度拍摄的。您还可以随机改变某些图像的亮度,以便探测器可以在不同的闪电条件下工作。总共 张照片就足够了。请看下面的一些样本图片:
Sample images
PS:由于视频是从我的 Iphone 上拍摄的,原始图像相当大——1920 x 1090。这将需要大量的内存,所以使用 PIL 调整大小来调整它们的大小到 500x300,保持纵横比。
2.注释图像
我用标签给图像加了注释。这是一个非常方便的工具,注释是以 Pascal VOC 格式创建的,这对以后很有用。用 Python 写的,接口用 Qt。我用 Python3 + Qt5 都没问题。参见注释图像示例。本质上,我们识别对象的 xmin、ymin、xmax 和 ymax,并将其与用于训练的图像一起传递给模型
Annotating using labelimg
3。创建 TFR 数据集
[create_pascal_tf_record](https://github.com/tensorflow/models/blob/master/research/object_detection/create_pascal_tf_record.py).py[create_pet_tf_record.py](https://github.com/tensorflow/models/blob/master/research/object_detection/create_pet_tf_record.py).[create_pet_tf_record.py](https://github.com/tensorflow/models/blob/master/research/object_detection/create_pet_tf_record.py)
您还需要创建一个 label.pbtxt 文件,用于将标签名称转换为数字 id。对我来说,这很简单
item {
id: 1
name: ‘toy’
}
我在 github 上包含了 label_map.pbtxt 文件和 create_pet_tf_records.py 文件。如果你被困在某个地方,我强烈推荐 Tensorflow 提供的 Oxfort Pets 漫游。
4。创建模型配置文件
创建 TFR 数据集后,首先需要决定是使用现有模型并对其进行微调,还是从头构建。我强烈推荐使用现有模型,因为 CNN 学习的大多数特征通常是对象不可知的,并且微调现有模型通常是一个简单而准确的过程。请注意,如果你决定从头开始构建,你将需要远远超过 150 个图像和培训将需要几天时间。该 API 提供了 5 种不同的模型,这些模型在执行速度和放置边界框的准确性之间提供了一种平衡。请参见下表:
Tensorflow Detection Models
Tensorflow 提供了几个示例配置文件来开始使用。我决定使用 faster_rcnn_resnet101_coco 文件,并更新了文件中需要配置的任何路径。别忘了更新 num。班级也是。
5。训练模型
终于!所有困难(和无聊)的部分都完成了,我们可以开始训练模型了。由于我有一个合理的 GPU,我决定在当地培训。然而,你可以在云上训练。tensorflow 文档再次简化了这一过程,并提供了所有的步骤。
您可以同时在两个独立的终端上启动培训作业和评估作业。启动 tensorboard 监控性能。经过 2-3 个小时的训练,我可以看到总损耗下降到 0.077,精度达到 0.99。通过查看 Tensorboard 中的图像,我们可以看到模型很快变得准确。
Model gets accurate pretty quickly
6。测试模型
为了测试模型,我们首先选择一个模型检查点(通常是最新的)并导出到一个冻结的推理图中。这个脚本也在我的 github 上。我在我的 Iphone 上录制的新视频中测试了这个模型。正如在我的上一篇文章中,我使用 Python moviepy 库将视频解析成帧,然后在每一帧上运行 object detector,并将结果整理回视频中。
后续步骤
我注意到的几件事和对未来的额外探索
- 在测试过程中,我发现更快的 RCNN 模型有点慢。接下来,我将探索使用最快的模型——SSD mobilenet,看看准确性是否有明显下降
- 对于这个模型,我只是使用了 faster_rcnn_resnet101_coco 的模型配置文件中的默认参数。如果可以调整它们以获得更好的性能,这可能是值得探索的
- 稍加努力,这个过程可以扩展到其他类别
给我一个❤️,如果你喜欢这个职位:)希望你拉代码,并尝试自己。
我有自己的深度学习咨询公司,喜欢研究有趣的问题。我已经帮助许多初创公司部署了基于人工智能的创新解决方案。请到 http://deeplearninganalytics.org/来看看我们吧。
你也可以在 https://medium.com/@priya.dwivedi 的看到我的其他作品
如果你有一个我们可以合作的项目,请通过我的网站或 info@deeplearninganalytics.org 联系我
参考文献:
在几分钟内建立一个翻译系统
使用 OpenNMT-py 创建基线 NMT 模型
序列到序列(seq2seq)[1]是一种通用的结构,能够做许多事情(语言翻译、文本摘要[2]、视频字幕[3]等)。).关于 seq2seq 的简短介绍,下面是一些不错的帖子:【4】【5】。
肖恩·罗伯逊的教程笔记本【6】和杰瑞米·霍华德的讲座【6】【7】是牢牢掌握 seq2seq 技术细节的绝佳起点。然而,在处理现实世界的问题时,我会尽量避免自己实现所有这些细节。重新发明轮子通常不是一个好主意,尤其是当你对这个领域非常陌生的时候。我发现 OpenNMT 项目非常活跃,有很好的文档,并且可以开箱即用:
OpenNMT 是一个工业级的开源(MIT)神经机器翻译系统,利用 Torch/ PyTorch…
opennmt.net](http://opennmt.net/)
还有一些更通用的框架(例如,[8] ),但是可能需要一些定制来使它适用于您的特定问题。
OpenNMT 有两个官方版本:
在接下来的部分中,我们将使用 PyTorch 版本。我们将带您了解使用中等规模的数据集创建一个非常基本的翻译系统所需的步骤。
步骤 1:获取 OpenNMT-py
将 Github 上的 OpenNMT-py git 存储库克隆到本地文件夹中:
http://opennmt.net/ py torch 中的 OpenNMT-py -开源神经机器翻译
github.com](https://github.com/OpenNMT/OpenNMT-py)
如果您打算以后定制或扩展它,那么您可能希望在 Github 上派生存储库。自述文件中还建议:
Codebase 接近稳定的 0.1 版本。如果你想要稳定的代码,我们目前推荐分叉。
步骤 2:下载数据集
这里我们将使用来自AI Challenger——英汉机器翻译竞赛的数据集。这是一个拥有 1000 万对英汉句子的数据集。英语字幕是从英语学习网站和电影字幕中提取的会话英语。从我的了解来看,大部分的翻译都是爱好者提交的,不一定是专业人士。翻译的中文句子由人工注释者检查。
英汉机器翻译-奖金:30 万-提高英汉机器翻译的性能…
challenger.ai](https://challenger.ai/competition/translation/subject?lan=en)
下载数据集需要注册帐户,可能还需要进行身份验证(不记得后者是否是强制性的)。如果这对你来说是个问题,你可以试试来自 WMT17 的数据集。
AI Challenger 数据集存在一些问题:1 .翻译的质量不一致。2.因为许多句子来自电影字幕,所以翻译通常依赖于上下文(与上一句或下一句相关)。但是,数据集中没有可用的上下文信息。
让我们看看现成的模型在这个数据集上的表现。由于内存限制,我将数据集下采样到100 万个句子。
(我们假设您将数据集放入 OpenNMT 根目录下的文件夹 挑战者 。)
步骤 3:将数据集转换为纯文本
验证和测试数据集采用 XML 格式。我们需要将其转换为纯文本文件,其中一行由一个句子组成。一个简单的方法就是使用 BeautifulSoup。下面是一段示例代码:
with open(input_file, "r") as f:
soup = BeautifulSoup(f.read(), "lxml")
lines = [
(int(x["id"]), x.text.strip()) for x in soup.findAll("seg")]
# Ensure the same order
lines = sorted(lines, key=lambda x: x[0])
第四步:标记英语和汉语句子
输入的句子必须用空格分隔的标记来标记。
nltk.tokenize.word_tokenize
with open(output_file, "w") as f:
f.write(
"\n".join([
" ".join(word_tokenize(l[1]))
for l in lines
])
)
它变成“这是一个整洁的一-二。沃克给伯顿。”变成“这是一个整洁的一-二。沃克呼叫伯顿。".
对于中文,我们使用最简单的字符级记号化,也就是把每个字符当作一个记号:
with open(output_file, "w") as f:
f.write(
"\n".join([
" ".join([c if c != " " else "<s>" for c in l[1]])
for l in lines
])
)
It turns “我就一天 24 小时都得在她眼皮子底下。” into “我 就 一 天 2 4 小 时 都 得 在 她 眼 皮 子 底 下 。”. (Note because the token are space-separated, we need a special token “” to represent the space characters.)
(我没有提供第 3 步和第 4 步的完整代码,因为这真的是初级 Python 编程。你应该能够独立完成这些任务。)
步骤 5:预处理数据集
只需在根目录下运行以下命令:
python preprocess.py -train_src challenger/train.en.sample \
-train_tg challenger/train.zh.sample \
-valid_src challenger/valid.en \
-valid_tgt challenger/valid.zh \
-save_data challenger/opennmt -report_every 10000
预处理脚本将遍历数据集,跟踪标记频率,并构建一个词汇表。我在这里遇到了内存问题,不得不将训练数据集向下采样到一百万行,但是我认为原始数据集经过一些优化后应该适合 16GB 的内存。
第六步:训练模型
python train.py -data challenger/opennmt \
-save_model models/baseline -gpuid 0 \
-learning_rate 0.001 -opt adam -epochs 20
它会用你的第一个 GPU 来训练一个模型。默认的模型结构是:
NMTModel (
(encoder): RNNEncoder (
(embeddings): Embeddings (
(make_embedding): Sequential (
(emb_luts): Elementwise (
(0): Embedding(50002, 500, padding_idx=1)
)
)
)
(rnn): LSTM(500, 500, num_layers=2, dropout=0.3)
)
(decoder): InputFeedRNNDecoder (
(embeddings): Embeddings (
(make_embedding): Sequential (
(emb_luts): Elementwise (
(0): Embedding(6370, 500, padding_idx=1)
)
)
)
(dropout): Dropout (p = 0.3)
(rnn): StackedLSTM (
(dropout): Dropout (p = 0.3)
(layers): ModuleList (
(0): LSTMCell(1000, 500)
(1): LSTMCell(500, 500)
)
)
(attn): GlobalAttention (
(linear_in): Linear (500 -> 500)
(linear_out): Linear (1000 -> 500)
(sm): Softmax ()
(tanh): Tanh ()
)
)
(generator): Sequential (
(0): Linear (500 -> 6370)
(1): LogSoftmax ()
)
)
源语料库和目标语料库的词汇量分别为 50,002 和 6,370。源词汇明显被截断到 5 万。目标词汇量相对较小,因为没有那么多常用汉字。
步骤 7:翻译测试/验证句子
python translate.py \
-model models/baseline_acc_58.79_ppl_7.51_e14 \
-src challenger/valid.en -tgt challenger/valid.zh \
-output challenger/valid_pred.58.79 -gpu 0 -replace_unk
models/baseline_acc_58.79_ppl_7.51_e14
您也可以使用以下公式计算 BLEU 分数:
wget [https://raw.githubusercontent.com/moses-smt/mosesdecoder/master/scripts/generic/multi-bleu.perl](https://raw.githubusercontent.com/moses-smt/mosesdecoder/master/scripts/generic/multi-bleu.perl)perl multi-bleu.perl challenger/valid.zh \
< challenger/valid_pred.58.79
现在你有一个工作的翻译系统!
步骤 8:(可选)对输出进行去爆震和转换
如果你想把翻译提交给 AI Challenger,你需要把步骤 4 反过来,然后是步骤 3。同样,它们应该很容易实现。
一些例子
English: You knew it in your heart you haven’t washed your hair
Chinese(pred): 你心里清楚你没洗头发
Chinese(gold): 你心里知道你压根就没洗过头
English: I never dreamed that one of my own would be going off to a University, but here I stand,
Chinese(pred): 我从来没梦到过我的一个人会去大学,但是我站在这里,
Chinese(gold): 我从没想过我的孩子会上大学,但我站在这,
English: We just don’t have time to waste on the wrong man.
Chinese(pred): 我们只是没时间浪费人。
Chinese(gold): 如果找错了人我们可玩不起。
以上三个例子,从上到下分别是语义正确、部分正确、完全无法理解。在检查了几个例子后,我发现大多数机器翻译的句子是部分正确的,而且语义正确的句子数量惊人。考虑到我们到目前为止付出的努力如此之少,这个结果还不错。
下一步
opts.py
其他途径包括对中文句子进行分词、添加命名实体识别、使用发音词典【10】对未见过的英文名称进行猜测翻译等。
( 更新:如果你使用 jieba 和 jieba.cut 默认设置对中文句子进行分词,你会绕过 .20 BLEU 上的公共 leaderboad。得分下降的一个可能原因是它的中文词汇量大得多。从输出中的 < unk > 的数量就可以看出来。)
参考资料:
- 【纳尔拉帕提,r .】,周,b .【多斯桑托斯,c .】向,B. (2016)。使用序列到序列的 RNNs 和超越序列的抽象文本摘要。
打造 AI 聊天机器人!
第五章:用数据做酷事!
特定领域的聊天机器人正在成为现实!使用深度学习聊天机器人可以“学习”提供给它的主题,然后能够回答与之相关的问题。像这样的技术的应用是无止境的。你只需提供关于某个主题的数据,然后看着机器人成为这方面的专家。
在这个博客中,我们将建立一个可以回答逻辑推理问题的博客。是的,这是可以做到的!见下图 gif:
链接到我的 GitHub 用 Python 写的完整代码。
我们是这样做的:
数据:这里使用的数据是由脸书人工智能研究所开源的。bAbI 数据集由脸书创建,旨在实现自动文本理解和推理。这是一组 20 个问答任务,每个任务由几个上下文问答三元组组成。每个任务旨在测试推理的一个独特方面,因此,适合测试 QA 学习模型的特定能力。
下面是第二个任务中的一个例子,两个支持事实(QA2):
约翰搬到了卧室。玛丽在那里抓起了足球。桑德拉去了卧室。桑德拉回到了走廊。玛丽搬到了花园。玛丽去了办公室。
问题:足球在哪里?
答:办公室基于报表 2、6
每个问题有 1000 个训练例子。该数据集具有合成生成的故事,因此词汇非常有限,并且句子形式非常受限。一方面,这些限制使 bAbI 成为学习的理想数据集——不需要进行太多的数据清理,人们可以专注于模型构建。另一方面,他们对在一个控制不那么严格的环境中把 bAbI 上的结果推广到 QA 的能力提出了质疑。
深度学习模型:对于这个问题,我们使用了一个端到端的记忆网络,它是由脸书人工智能研究所设计的。
让我们首先讨论为什么带有 LSTM 细胞的递归神经网络不能很好地解决这个问题。
- 数据可能不得不无序访问。请参见下面的示例:
2.如果我们想通过网络“记忆”一本书或一段视频,我们需要长期记忆,而 LSTM 细胞实际上对长期记忆问题不起作用
端到端存储器网络使用外部存储器来解决这个问题。并且它可以在数据中执行多次查找(跳跃)来解决无序数据问题。简单来说这是什么意思?
该型号有两个模块—内存模块和控制器模块。记忆模块把我们要讲的故事写成了向量。由于计算机无法理解单词,我们需要将单词转换成数字/向量。我们不是将每个单词都转换成一个数字,而是使用一种叫做嵌入的技术,这种技术赋予意思相似的单词相似的向量。例如,由于单词“拾起”或“举起”具有相似的含义,因此它们将具有相似的向量,这有助于机器更好地理解单词之间的上下文。张量流嵌入功能可用于生成单词到向量。
控制器模块将被询问的问题写成向量。请参见下面的示例:
然后我们做控制器函数和记忆向量的点积。然后我们做一个 softmax,将总概率缩放到 1。并且这被传递回控制器。在上面的例子中,因为这个神经网络考虑了句子的顺序,所以它给第二个句子较高的权重。我们可以把得到的概率(上面的 0.1,0.7,0.2)看作是暗示网络“关注”哪个向量。
这个过程可以重复几次(也称为跳跃),控制器有能力学习和重新查看存储向量,并再次做出选择。请看下面网络如何通过建立在前一跳中学到的知识来关注不同的向量
最后,输入被传递到一个解码器和向量,并转换成文字。
总的来说,这对我来说是一次很棒的经历,我对学到的东西很满意。
其他著述:【https://medium.com/@priya.dwivedi/】T2
PS:我住在多伦多,我希望将职业生涯转向深度学习。如果你喜欢我的帖子,并能把我联系到任何人,我将不胜感激:)。我的电子邮件是 priya.toronto3@gmail.com
参考文献:
Udacity 深度学习纳米学位为我提供了详细探索这个领域的动力
Stroh 和 Mathu 的研究论文
http://smerity.com/articles/2015/keras_qa.html
端到端存储网络的好解释:【https://youtu.be/ZwvWY9Yy76Q
用纯数字构建人工神经网络
神经网络因其在计算机视觉和自然语言处理等几个领域的出色表现而备受关注。它们不仅远远超过同类产品,而且用途极其广泛,几乎应用于所有可以想象的领域。
但是这两个词到底是什么意思呢?
在这篇简短的帖子中,我们将深入研究神经网络的概念,然后用 Python 编写我们自己的代码,使用 pure NumPy 对 MNIST 数字进行分类(我保证这很有趣)**。**我会尽量保持简短,主要是为了防止你因为我不专业的写作风格而关闭这个标签。所以让我们直入主题:
神经网络到底是什么
顾名思义,神经网络是一种受我们大脑中生物网络启发的计算系统。如果你没有像我一样在整个生物课上睡觉,你可能会记得我们大脑中的网络由大量的神经元组成。
出于我们的目的,我们可以将这个神经元建模为一个函数,它接受一组输入,使用一些*权重获得这些输入的加权和,添加一个 偏差 ,并基于一些 激活 函数输出一个数字。有道理?我也这么想 lol。*
Mathematical working of a single neuron
权重可以被认为是一串旋钮,我们可以调整它们来获得不同的输出。
偏置是另一个旋钮,它决定神经元何时保持不活动,或者换句话说,它决定神经元需要多高的加权和才能有意义地活动。
激活功能是将 logit 功能的任意输出映射到任何特定范围值的功能。它通常用于给我们的模型增加一些非线性。这允许网络以更复杂的方式组合输入,并且反过来在它们可以建模的功能中提供更丰富的能力。最常用的激活函数有 sigmoid、softmax、ReLU、tanh 等。
网络的结构
现在我们知道了单个神经元是如何工作的,我们可以将它们连接起来,以层的形式形成一个网络。所以人工神经网络只是一个被高估的复合函数。
A simple neural network. Also called a multilayered perceptron
典型的神经网络由 3 种类型的层组成:
- ***输入层:*给定的数据点馈入该层。只能有一个输入层。这一层中神经元的数量等于输入的数量。
- ***隐层:*这是全网的肉。这些层试图在输入中找到模式,以获得我们需要的输出。网络可以有任意数量的隐藏层。
- 输出层:这一层给我们网络的预测,即。给定当前参数(每个神经元的权重和偏差),网络认为应该正确的输出。这一层神经元的数量等于我们需要预测的值的数量。因为我们的任务是分类 MNIST 数字,我们将有 10 个神经元,因为有 10 个数字来计算预测。
因此,基本网络层可以定义为:
该层处理输入,最终产生输出值。这称为层上的向前传递。
在我们的实现中,我们将使用两个层:
- 密集层——其中一层中的每个神经元都与下一层中的每个神经元相连。
- ReLU 激活层 —位于密集层之上的层,将 ReLU 激活功能应用于密集层的输出。我本来可以使用最常见的 sigmoid 函数,但是我有时会尝试使用 ReLU 函数。
ReLU activation function
这两层可以定义为:
训练网络
既然我们已经定义了网络的架构,我们究竟该如何训练它呢?是的,使用 参数, 即权重和偏差。
由于我们的网络有不止一个神经元,每个神经元都有一套独特的权重和偏好,这给了我们数千个旋钮来调整。如果你是一个小小的受虐狂,愿意手动调节这些成千上万的旋钮,以获得最佳的组合,那就继续吧。如果你是正常人,那么我们可以利用梯度下降算法。
梯度下降是一种通用算法,可用于优化任何微分函数。它的工作方式是计算函数在当前点的梯度*。这种梯度给我们的方向,将最大限度地发挥功能(梯度口音)。但是我们通常需要最小化一个函数,所以我们把计算出的梯度的方向反过来得到最小化函数的方向(梯度下降)。如果你和我一样有点慢,你可以把它想象成一个球滚下山坡,由于重力的原因,它最终到达最低点。*
为了优化我们的网络,我们需要这样一个函数,所以我们定义了一个损失函数——我们使用的这个函数被称为 log softmax 交叉熵损失(再次变得尖锐)。
A scary-looking loss function
让我们一个字一个字地分解它:
- Softmax
Softmax 函数获取一个 N 维实数向量,并将其转换为(0,1)范围内的实数向量,其总和为 1。因此,它输出一个概率分布,这使得它适合于分类任务中的概率解释。
Softmax function
Graph of Softmax function
2.交叉熵损失
交叉熵表示模型认为的输出分布和原始分布之间的距离。
Cross-Entropy Loss
让我们用代码来写:
所以我们训练网络的方法如下:将网络的输出与预期输出进行比较,计算损耗。这种损失然后通过网络一次一层地传播回来,并且根据它们对误差的贡献量来更新权重和偏差。这种传播由反向传播算法执行。
这个算法相当复杂,需要一整篇文章来解释,所以我只告诉你几分钟,因为我很懒。
因此,对于每一层,为了计算该层参数对总损耗的影响,我们需要计算损耗对这些参数的导数。为了减轻我们的麻烦,我们可以利用链式法则。
Backpropagation Cheat Sheet
因此,对于每一层,我们可以添加一个后向通道,其中该层的梯度作为输入,用于计算所需的导数,最后,该层的梯度作为输出返回:
运行代码
下面给出了带有精度图的完整代码
Accuracy Plot
谢谢你坚持到最后。写这篇文章确实帮助我在大脑中巩固了一些复杂的概念。这是我第一次尝试写技术文章,如果有人有什么指点,请在下面留下回应!
构建端到端数据科学项目
从我的数据科学家理想概况项目中获得的经验
Photo by Joseph Barrientos on Unsplash
It 人们常说,数据科学家的大部分工作不是实际的分析和建模,而是数据争论和清理部分。因此,涉及这些阶段的全周期数据科学项目将更有价值,因为它们证明了作者独立处理真实数据的能力,而不是给定的清理数据集。
充分理解端到端数据科学项目的价值,我一直想建立一个,但直到现在还不能:)
我最近完成了我的理想简介项目。由于这是一个涉及许多活动部分的大项目,我想记录这个过程和学到的教训,这是一个进一步学习的机会(受威廉·科尔森关于数据科学写作价值的伟大帖子的启发)。
阶段
在我看来,一个全周期的数据科学项目应该包括以下几个阶段:
从事 Kaggle 项目的最大反对理由通常是它只关注第二阶段。因此,在这个项目中,我确保涵盖了所有三个阶段。
在第一阶段,我做了网络搜集来获取数据,由于数据是脏的,我不得不努力让数据为分析做好准备。然后我做了各种数据可视化,并进行分析,作为第二阶段。最后,我写了一些帖子来交流我的发现,并将这个项目投入生产。
当然,我可以通过加入机器学习组件来使这个项目更加完整,例如,使用 NLP 根据内容对职位发布进行分类,但这将大大延迟项目完成时间,这将我们带到下一点:
迭代思维
潜在地,对于一个给定的项目,可能有无限的事情要做,但是实际上,我们只有有限的时间。为了协调这两个相互竞争的因素,我们需要自律。
对我来说,“迭代思维”真的很有帮助——瞧,罗马不是一天建成的,所以让我们先建造一些可以工作的东西,然后我们可以随时回来改进更多的功能。另一方面,这也意味着我们需要能够处理“不完美”,不要拘泥于细节。
有了这个理念,我可以推迟一些非常诱人的功能,把它们放在项目文档的待办事项部分。其中之一是使用一个更大的数据集,从美国而不是加拿大的网站抓取数据。
模块化
鉴于项目的端到端性质,有许多不同的方面要做——网页抓取、数据预处理、绘图……如果我们将所有代码放在一个 Jupyter 笔记本中,管理起来会太长太复杂。然后我决定使用 Python 脚本结合中央 Jupyter 笔记本来解决这个问题。
我将支持功能分为三大类,并将它们放在三个相应的脚本中:
- scrape_data.py —包含 web 抓取所需的函数,如“get_soup()”和“get_urls()”
- process_text.py —包含文本处理和清理功能,如“tokenize_text()”和“check_freq()”
- helper.py 包含文件 I/O 和绘图功能,例如“plot_skill()”
通过这种方式,我能够保持一个超级轻和有组织的中央笔记本。然后根据需要从笔记本中导入和调用函数,如下所示:
**from** **scrape_data** **import** *
**from** **process_text** **import** *
**from** **helper** **import** *
再现性
由于我在网上找到的许多抓取脚本都不起作用,我决心确保我的项目是可重复的。除了可靠的代码之外,强大的自述文件和完整的环境依赖文件也是解决方案的一部分。
编码最佳实践
良好的编码实践很重要!特别是,我发现以下实践在编写更大更复杂的项目时非常有用:
- 写清楚、简洁和信息丰富的评论
- 具有有意义的描述性变量/函数名
- 确保使用 Python“try except”块进行异常处理
当您的项目是一个 30 行的 Jupyter 笔记本时,这些事情可能看起来微不足道,但在处理一个需要数百行代码的大型项目时,这些事情真的非常重要!
Matplotlib 岩石
我过去习惯于只掌握基本的 Matplotlib 技能。然而,对于这个项目,我不仅需要将几个图合并成一个,而且还必须进行详细的定制,如旋转轴刻度标签…在这一点上,基本的 Matplotlib 技能根本不再足够。
事实证明这是一个学习 Matplotlib 的好机会。一旦我知道了它能做什么,我就发现不可能回头了,原因很简单,Matplotlib 真的很强大!它的面向对象的方法允许你修改几乎任何东西…查看下面的教程来找到答案:
这就是我最近完成的关于理想概要项目的最后一篇博文。另外两篇文章在这里和在这里可以找到。
你有什么想法?我错过了什么或者我可以改进的吗?请在下面随意评论。我欢迎任何反馈。
感谢您的阅读!
用 Python 构建 ETL 管道
介绍
在我的上一篇帖子中,我讨论了我们如何设置一个脚本来连接 Twitter API 并将数据直接传输到数据库中。今天,我将向大家展示我们如何访问这些数据并对其进行分析,实际上是从头到尾创建一个完整的数据管道。大体上,我计划从我们的数据库中提取原始数据,清理它,最后使用 word clouds 和 NLP Python 库做一些简单的分析。
让我们想想如何实现这样的东西。为了使分析尽可能全面,我将采用面向对象的方法,创建一个 TweetObject 类和该类的方法来执行上述任务。我们将使用几个重要的库,比如 NLTK(自然语言工具包)库,它有一系列用于自然语言处理的有用函数。我们将使用单词云库来创建一些我们推文的摘要可视化,并使用一个名为 TextBlob 的库来帮助我们计算情感。
让我们先来看看 python 代码。
首先,我们导入必要的库。像我以前的文章一样,我们需要导入 mysql-connector 库来连接我们的数据库。TweetObject 类将初始化一些允许我们连接到数据库的重要参数。 MySQLConnect 方法接收一个 SQL 查询,执行它并返回一个 pandas 数据帧。Pandas 对于任何数据分析任务来说都是一个非常棒的库,它让操作数据变得非常容易,所以我建议任何有抱负的数据分析师/科学家熟悉这个库。
自然语言处理:清理推文
现在我们有了一个查询数据库并返回数据的方法,我们该如何处理它呢?让我们花一点时间来谈谈自然语言处理(NLP)。一般来说,文本数据需要一些预处理,然后才能输入到机器学习算法中。我们需要把它转换成一种算法可以理解的格式。这通常涉及以下一些任务。
自然语言处理中的预处理步骤:
- 正常化。
- 删除停用词、标点符号和 HTML。
- 象征化。
- 引理满足
- TF-IDF。
这当然不是一个详尽的列表,但这些是适用于大多数 NLP 任务的技术。好,让我们解释一下这些概念是什么,以及为什么我们需要使用它们。将单词标准化为小写是 NLP 中的正常步骤,因为我们不希望我们的算法将 python 和 PYTHON 视为两个不同的单词。将所有单词转换成相同的大小写可以避免这些问题。我们想采取的另一个步骤是从我们的文本中删除任何不相关的材料。一种方法是删除标点符号,如逗号、句号和停用词,如“I”、“is”、“the”。NLTK 包中停用词的更详细列表可以在这里看到。我们还应该考虑记号化,这是一个本质上把文本分割成有意义的块或记号的过程(TextBlob 自动为我们做这件事)。我们将使用的最后一个预处理技术是引理满足。这实质上是将一个词转换成它的“规范形式”。换句话说,巨蟒会变成巨蟒,而步行会变成步行。
一种非常有用的技术是术语频率-逆文档频率或 TF-IDF,但我们在这里没有使用。这是一种信息检索技术,它允许我们识别文档中单词的相对重要性。一般来说,如果一个单词在一个文档中出现多次,它可能是重要的。但是,如果它在多个文档中频繁出现,那么它可能只是一个普通的单词,实际上没有多大意义。TF-IDF 试图说明这一点,并返回每个单词重要性的总得分。当试图量化文档是关于什么的时候,这是一种广泛使用的技术,并且倾向于与诸如高斯混合模型(GMM)** 、 K 均值或**潜在狄利克雷分配(LDA)之类的算法一起使用。****
还有许多其他技术,我们可以利用,可能会改善我们的结果,如词干和 n 元语法,但我不会在这里进入这些。如果你想深入了解 NLP,网上有很多资源。
现在让我们回到我们的代码。下面的 clean_tweets 方法实现了上面提到的一些技术。特别是,它将所有的单词规范化为小写,拆分单词,词条,并且只保留不在停用词列表中的单词。它还去除了一些常见的 HTML,这些 HTML 往往出现在推文中,不会真正帮助我们的分析。
计算情绪
既然我们有了清理推文的方法,我们可以创建一个计算情绪的方法。TextBlob 库使 Python 中的情感分析变得非常简单。我们所需要做的就是将我们的文本传递到我们的 TextBlob 类中,在对象上调用invision . polarity方法,它返回 1、0 或-1,分别对应于积极、中立和消极的情绪。如果没有额外的参数传递给 TextBlob 类,那么默认情况下,text blob 类实现了许多文本处理函数,所以让我们快速浏览一下这些函数,以了解幕后发生了什么。
有四个参数,即标记器、 np_extractor 、 pos_tagger 和分析器,如果留空,则默认为某些方法。记号赋予器默认使用 WordTokenizer 方法,将文本分割成一个单词列表。如果我们将 np_extractor 留空,就会调用 FastNPExtractor 方法,根据文档返回一个名词短语列表,这对于识别特定句子或推文是关于什么的非常有帮助。例如,如果我们将这篇博客的第一段传递到 TextBlob 类中,并打印出名词短语,我们将得到下面的列表:
[‘twitter api ‘,‘流数据’,‘完整数据管道’,‘原始数据’,‘简单分析’,‘文字云’,’ nlp python’]
接下来,调用 NLTK_tagger 来识别词类(POS ),比如一个单词是名词、动词还是形容词。最后,分析器默认为模式分析器,它返回我们的极性得分。正如我们所看到的,这个情感计算的代码非常简洁。极性得分以从-1 到 1 的范围返回,我们根据其值将其转换为情绪得分。
我们还创建了将我们的结果保存到 CSV 并创建单词云的方法。我真的很喜欢使用单词云,因为它们是总结文本数据的有效方式。它们提供了文本中单词数量的直观形象,其中较大的单词对应于较高的数量(单词出现得更频繁)。这使得更容易了解人们在推特上谈论的事情。
主要方法
接下来,我们有我们的主方法,它创建我们的对象并调用适当的方法。我们首先创建一个 TweetObject 类的对象,并连接到我们的数据库,然后调用我们的 clean_tweets 方法,该方法执行我们所有的预处理步骤。最后一步是用我们的情绪创建 3 个列表,并使用它们来获得积极、消极和中立的推文的总百分比。在我们运行这个之前,我们需要确保我们的 SQL 服务器在运行。否则,我们将无法连接到数据库并检索我们的数据。
结果
好,让我们看看这段代码产生了什么。正如我在之前的帖子中所说,我是一个高尔夫球迷,所以我决定在 2018 年大师赛的最后一轮比赛中收集推文。正如我们从下面的单词云中看到的,帕特里克·里德是出现频率最高的名字,这可能并不奇怪,因为他赢得了比赛。我们还看到其他一些高尔夫球手的名字,如乔丹·斯佩思和里基·福勒,他们在排行榜上仅次于里德。虽然这不是世界上最有洞察力的图表,但我真的很喜欢使用文字云来尝试从数据中得出一些初步的见解。还不完全清楚这些推文对这个词云的总体看法,但这就是为什么我们有 TextBlob 库。下面是我们情感计算的结果。特别是,我们计算了属于上述三类的推文的百分比。
我们的情感评分结果表明,大多数推文是正面的,约为 48%。还有一大群人看起来相当中立,为 39%。总的来说,我们可以从中收集到,推文总体上是积极的,但不是很多。这种方法的一个缺点是,我们可能无意中抓取了与高尔夫锦标赛完全无关的推文,而只是包含了我们的一些关键词。这是做任何类似分析时需要警惕的一件事。
结论
关于使用 SQL 和 Python 制作 ETL 管道的两部分系列文章到此结束。尽管我们的分析有一些优点并且非常简单,但是这种方法也有一些缺点。像所有类型的分析一样,总是要进行权衡,以及使用特定技术优于其他技术的利弊。最终,这个选择将取决于分析师,这些权衡必须根据他们试图解决的问题类型来考虑。
我们采用的方法的一个缺点是我们使用了现成的算法。不能保证我们的结果是非常准确的,不幸的是,如果不仔细阅读我们收集的推文,就无从得知。我们可以处理这个问题的一种方法是使用专门针对推文训练的情感算法,这可能会给我们带来改进的结果。
我们还可以进一步分析,尝试一些无监督的学习方法,比如聚类。这将帮助我们找到相似的推文组,并让我们对数据集有更深入的了解。GMM 也是一个值得尝试的有趣技术。这种算法试图做与聚类相同的事情,但具有更灵活的额外优势,允许我们以一定的概率将推文分配给多个组。这很好,因为我们可以将一定程度的不确定性纳入我们的估计。然而,我将把这些技术留到以后的文章中。
推荐课程:[GCP上的数据工程、大数据、机器学习](http://Data Engineering, Big Data, and Machine Learning on GCP)
完整的 Python 代码
这篇文章中的一些链接是附属链接
构建运行在 Raspberry Pi 上的图像分类器
本教程讨论了如何使用 Raspberry Pi 接收对图像进行分类的 HTTP 请求,并使用分类标签进行响应。本教程首先构建物理网络,通过路由器将 Raspberry Pi 连接到 PC。准备好 IPv4 地址后,创建 SSH 会话,以便远程访问 Raspberry Pi。使用 FTP 上传分类项目后,客户可以使用 web 浏览器访问该项目以对图像进行分类。
树莓派
Raspberry Pi 是一种单板计算机,设计价格低廉,发展中国家的学生也买得起。Raspberry Pi 支持用 Python 编码,这就是为什么术语“Pi”可用的原因。树莓 Pi 3 型号 B 是最新的可用版本。它有一个四核 1.2 GHz CPU,1 GB RAM,Wi-Fi,蓝牙,一个 HDMI 端口,4 个 USB 端口,以太网端口,摄像头等。
Raspberry Pi 没有安装操作系统。操作系统可以装在插入主板 SD 卡插槽的 SD 卡上。可以使用 NOOBS(新的开箱即用软件)(https://www.raspberrypi.org/downloads/noobs)下载操作系统,这是一个操作系统管理器,可以轻松地将操作系统下载并安装到 Raspberry Pi。官方的 Raspberry Pi 操作系统被称为 Raspbian,这是专门为 Raspberry Pi 设计的 Linux 版本。它伴随着 NOOBS。NOOBS 也支持一系列操作系统供选择。
在 SD 卡中安装操作系统后,下一步是运行并访问它。访问 Raspberry Pi 的一种方式是使用以太网接口连接它。这种连接可以通过将其连接到 PC 的以太网接口来直接进行。有些电脑只有无线接口,根本不支持以太网。其他人可能在安装驱动程序时遇到问题。因此,我们可以避免将 Raspberry Pi 连接到 PC 的以太网接口,而是将其连接到路由器的一个以太网接口。PC 可以使用 Wi-Fi 连接到这样的路由器。
网络配置
假设 Raspberry Pi 和 PC 所在的局域网(LAN)使用范围从 192.168.1.1 到 192.168.1.254 的互联网协议版本 4 (IPv4)地址。即网络地址是 192.168.1.0,子网掩码是 255.255.255.0。使用动态主机配置协议(DHCP),IPv4 地址被动态分配给 PC 和 Raspberry Pi。我们可以在 Windows 中使用 ipconfig 命令(Linux 中使用 ifconfig 命令)轻松知道 PC 的 IP 地址。如下图所示,默认网关设置为 192.168.1.1,PC 的 IPv4 地址为 192.168.1.18。
为了知道分配给 Raspberry Pi 以太网接口的 IPv4 地址,将使用一个名为“高级 IP 扫描器”的程序。可以从这个页面下载https://www.advanced-ip-scanner.com。该程序接收一系列 IPv4 地址,并搜索活动地址。对于范围内的每个 IPv4 地址,该程序返回其状态、主机名、制造商和媒体访问控制(MAC)地址。通常,Raspberry Pi 的主机名或制造商名称中会包含“Raspberry”一词。这有助于我们确定哪个 IP 属于树莓派。下图显示了分配给路由器网关接口、PC 和签名为 192.168.1.19 的 Raspberry Pi 以太网接口的 IPv4 地址。
总之,下图显示了除分配的 IPv4 地址之外的 3 台设备(Raspberry Pi、路由器和 PC)。路由器中的一个以太网接口使用简单的电缆连接到 Raspberry Pi 的以太网接口。路由器以无线方式连接到 PC。
安全壳
建立物理连接后,我们需要从 PC 访问 Raspberry Pi。安全外壳(SSH)是一个很好的选择。SSH 会话可以使用不同的软件程序来创建,比如 XMing、Putty 和 MobaXterm。MobaXterm 是一款易于使用的软件,点击链接【https://mobaxterm.mobatek.net/download-home-edition.html】即可获得。下图是 MobaXterm 的主窗口。
重要提示:在建立 ssh 会话之前,必须在 SD 卡的根目录下添加一个没有扩展名的名为“SSH”的空文件。这是允许与 Raspberry Pi 建立 SSH 会话所必需的。这是通过将 SD 卡插入 PC 并添加此类文件来完成的。将 SD 卡插入 Raspberry Pi 后,我们就可以开始创建 SSH 会话了。
图标栏左上角的“会话”图标用于建立 SSH、Telnet 等会话。点击后,将显示如下图所示的窗口。
在点击最左边的 SSH 图标后,MobaXterm 会询问 Raspberry Pi 的远程主机名或 IPv4 地址,以便访问远程设备。我们可以使用 Raspberry Pi 的以太网接口的 IPv4 地址 192.168.1.19,如下图所示。
登录
如果物理连接工作正常,单击“OK”按钮后,将要求您登录以成功访问远程设备。Raspberry Pi 的默认登录用户名和密码是:
- 用户名 : pi
- 密码:树莓
正确输入这些详细信息后,会话将根据下图成功启动。只是有一个 Raspbian 终端用于与 Raspberry Pi OS 交互。请注意,MobaXterm 允许缓存以前会话中使用的密码,因此您不必每次登录时都输入密码。
您可能会注意到,SD 卡的内容显示在终端的左侧。这是因为 MobaXterm 支持使用文件传输协议(FTP)创建连接来上传和下载文件。这是一个非常有用的功能,可以节省很多时间。如果不使用 FTP,我们必须多次弹出和插入 SD 卡,以便向 Raspberry Pi 添加新文件。
X11 窗口系统
为了使初学者更容易与这样的操作系统进行交互,MobaXterm 使用 X11 窗口系统,该系统提供了一个图形用户界面(GUI)来与操作系统进行交互,而不是使用命令行。X11 为 Linux 操作系统提供了一个类似于 Microsoft Windows 的 GUI 显示框架。我们可以使用“ startlxde ”命令打开访问 GUI,如下图所示。
此时,我们可以使用 SSH 访问 Raspberry Pi,并能够使用 GUI 与之交互。这太棒了。使用只需 50 美元的 Raspberry Pi,我们就有了一个和我们在电脑上看到的一样的界面。当然,由于内存、SD 卡存储和 CPU 速度有限,它不会支持我们机器中的所有东西。
图像分类
接下来,我们可以开始构建图像分类器。完整的分类器是在本书中从零开始构建的“ Ahmed Fawzy Gad,使用深度学习的实用计算机视觉应用与 CNN,Apress,2019,978–1484241660”。
使用来自 Fruits 360 数据集的 4 个类来训练分类器。这个想法是使用 Flask 创建一个 web 应用程序,该应用程序存在于 Raspberry Pi 上的 web 服务器中,其中存在训练好的分类器。用户可以访问它上传和分类自己的图像。
在 FTP 的输出中有一个名为“ FruitsApp 的文件夹,它是先前上传到 Raspberry Pi 的。它包含项目文件。该项目有一个名为“ flaskApp.py 的主 Python 文件,用于实现 Flask 应用程序。还有其他补充的 HTML、CSS 和 JavaScript 文件用于构建应用程序的界面。为了运行应用程序,可以从终端执行 python " flaskApp.py "文件,如下图所示。
以下 Python 代码实现了 Flask 应用程序。根据代码的最后一行,可以使用 web 浏览器通过访问分配给 Raspberry Pi 的 IP 地址和端口 7777 来访问该应用程序。结果应用的首页是 http://192.168.1. 。
**import** flask, werkzeug, PIL.Image, numpy
app = flask.Flask(import_name=**”FruitsApp”**)**def** extractFeatures():
img = flask.request.files[**"img"**]
img_name = img.filename
img_secure_name = werkzeug.secure_filename(img_name)
img.save(img_secure_name)
print(**"Image Uploaded successfully."**)
img_features = extract_features(image_path=img_secure_name)
print(**"Features extracted successfully."**)
weights_mat = numpy.load(**"weights.npy"**)
predicted_label = predict_outputs(weights_mat, img_features, activation=**"sigmoid"**)
class_labels = [**"Apple"**, **"Raspberry"**, **"Mango"**, **"Lemon"**]
predicted_class = class_labels[predicted_label]
**return** flask.render_template(template_name_or_list=**"result.html"**, predicted_class=predicted_class)app.add_url_rule(rule=**"/extract"**, view_func=extractFeatures, methods=[**"POST"**], endpoint=**"extract"**)**def** homepage():
**return** flask.render_template(template_name_or_list=**"home.html"**)
app.add_url_rule(rule=**"/"**, view_func=homepage)app.run(host=**"192.168.1.19"**, port=7777, debug=**True**)
一旦用户访问主页,将显示一个 HTML 页面,要求上传图像。一旦上传了图像,将会调用“**extract features()”**函数。它提取特征,预测类标签,并根据下图在另一个 HTML 页面中呈现结果。上传的图片类标签是“苹果”。更多细节,请看[1]中的书。
[1]“Ahmed faw zy Gad,使用深度学习与 CNN 的实际计算机视觉应用,Apress,2019,978–1484241660”。可通过以下链接获得:
联系作者
- https://kdnuggets.com/author/ahmed-gad
利用深度学习构建入侵检测系统
这实际上是我和我的小组为我们的计算机科学学士学位实施和完成的最后一年项目。
已经对入侵检测系统进行了大量研究,但是最大的变化发生在收集的数据集中,该数据集中包含许多入侵技术的样本,例如暴力、拒绝服务或者甚至来自网络内部的渗透。
随着网络行为和模式的改变以及入侵的发展,从静态和一次性数据集转向更动态生成的数据集变得非常必要,这些数据集不仅反映当时的流量构成和入侵,而且是可修改、可扩展和可再现的。
为此,我们将训练一个深度学习模型,从给定的数据集中识别异常。
由于机器学习在系统中的应用,基于异常的检测在入侵检测系统中是最有效的,因为它们不需要搜索任何特定的异常模式,而是将任何不匹配简档的东西视为“异常”。
注意:我不会在这里分享代码,但我会在最后给出 GitHub 上代码的链接。目的是启发用于实现成功的准确性的思想和实现。
我们开始吧:)
数据集
为此,我们将利用加拿大网络安全研究所收集的 ISCX 2012 数据集。您可以在下面的链接中找到它:
[## IDS 2012 |数据集|研究|加拿大网络安全研究所| UNB
CIC 和 ISCX 的数据集在世界各地被用于安全测试和恶意软件防范。
www.unb.ca](http://www.unb.ca/cic/datasets/ids.html)
在我们开始之前,通过使用 Matplotlib 库来检查每个类(正常和异常)包含了多少数据,来可视化实际数据集。
Image visualizing the anomaly data from the normal using Matplotlib library
我应该提到的是,在项目开始时,我们使用机器学习技术研究了许多关于入侵检测系统的论文,我们发现没有一篇论文利用了 ISCX 2012 数据集,这很可能是因为当时该数据集不可用。但是我们是第一批在入侵检测系统中使用数据集的公司之一。
环境
我已经创建了一个指南,非常详细地介绍了如何为深度学习设置你的系统
如果你碰巧正在使用 Keras API,但使用的是 Theano 或微软 CNTK 后端引擎,那么你也不错。否则,请遵循上述指南。
数据预处理
当被下载时,当 ISCX 数据集处于其原始状态时,对于深度学习模型是不可读的。PCAP 文件格式,因此,为了改变这一点,我们使用一个开源软件程序称为 ISCX 流量计来改变这一点。
这个流量计接收。PCAP 文件,并将它们转换成可读的。XML 文件格式,将每个数据部分堆叠为流,其中第一个数据包确定了向前(从源到目的地)和向后(从目的地到源)的方向。
以下是新转换的数据集的示例:
Part of the ISCX data in XML format
现在,我们只需要每个流中的两个数据:
- 目的地有效负载为 UTF:这是用户接收到的传入数据包
- 标记:这将上述有效载荷标记为正常或异常
因此,在数据集上运行流量计后,我们得到多个 XML 文件,从每个文件的每个树中提取两个主要数据值。然后,我们将有效载荷数据连接起来,使其长度为 7500,一旦完成,我们就将其重新整形为一个 50x50x3 维的 NumPy 数组。
当可视化时看起来像这样
Five data images from the ISCX data set
然后,我们垂直堆叠这些阵列,并添加一列,其中包括每个单独有效载荷的标签,即正常或异常。完成后,我们将数据保存到。NPY 文件,以便它可以用作深度学习模型的输入。
模型
我们尝试了不同模型的各种实验,但我们成功准确发现的一个实验是在 VGG-19 Keras 预训练模型上使用迁移学习技术。
VGG-19 Model Layout
我们没有使用预先训练的 VGG-19 的权重,因为我们的图像是定制图像,因此我们选择使用常规的异常检测技术在我们的图像集上训练模型,该技术包括两个阶段:
- **训练阶段:**创建正常有效载荷轮廓的阶段。通常情况下,不需要任何异常数据进行训练,因为在下一阶段,入侵检测系统会立即从配置文件中的数据中丢弃任何偏差最小的数据。
- **测试阶段:**将传入的有效载荷与配置文件中存储的数据进行比较的阶段。
在这样做的时候,我们在数据值上训练我们的模型,数据值的标签被标记为正常,反过来,它在第一个纪元就达到了 100%的精度。然而,随着异常数据值的引入,模型达到了 100%的不正确准确度,其结论是模型正确识别了正常数据,但是在异常情况下,模型只是绕过了正常数据而没有对其进行分类。
因此,我们在训练数据中同时使用了异常和正常数据,由于数据的性质,很明显这是一个异常检测问题。在测试阶段,我们获得了满意的结果,该模型能够以 100%的准确率识别正常数据,以 85%的准确率识别异常数据。考虑到我们的数据集,获得的结果是令人满意的
Accuracy graph of the model in 2 epochs
Scientific model evaluation of our model using Scikit-learn library
结论
通过对我们模型的成功识别,我们可以自信地宣称,我们的模型可以用作入侵检测系统应用程序的后端引擎,该应用程序可以安装在任何计算机网络的边界上
然而,明智的做法是进一步测试,如果需要的话,重新训练加拿大网络安全研究所发布的新数据集模型,即 IDS 2017 数据集。
[## IDS 2017 |数据集|研究|加拿大网络安全研究所| UNB
CIC 和 ISCX 的数据集在世界各地被用于安全测试和恶意软件防范。
www.unb.ca](http://www.unb.ca/cic/datasets/ids-2017.html)
这一举措将进一步验证我们的模型在检测异常方面的准确性,因此如果您希望在入侵检测或入侵防御系统中使用这一点,我强烈建议首先这样做,因为这将使模型保持更新。
我希望你喜欢这次旅行:)
构建并利用基于事件的数据模型来分析在线数据
2017 and beyond, you should only be using an event-based data model… If you are not, your agility may be severely limited
如果您对这个主题足够感兴趣,您可能足够了解收集和分析事件是理解用户如何与应用程序交互的信息高速公路。但是让我们先退后一步,问一个这个想法所基于的问题:为什么我们首先要收集事件?
商业智能专家过去的迭代会从在购买过程的不同阶段收集的关于用户的人口统计和心理信息中推断出相当多的信息。很容易说,美国人比其他国家的人倾向于购买更多的东西,年轻人更倾向于网上购物。
但是人口统计学和心理统计学不会告诉你一切。研究表明,关于用户的行为数据在预测购买、升级和流失等方面非常有效。
在 Cooladata,我们遵循创始人 Tomer Ben Moshe 的格言:
“你是由你做的事情来定义的,而不是你是谁。”
这一理念不仅将我们公司凝聚在一起,而且渗透到我们的产品中,指导我们做出的每一个设计决策。Cooladata 是一个完整的系统,旨在实现对用户行为的快速分析和理解。
在这个用户行为的宇宙中,事件就是原子。当用户在您的网站、应用程序或数字资产中采取某种可衡量的行动时,该行动将被记录为一个事件。
一般定义
来自移动网络或 IOT 的在线数据基于事件,其中每个事件都有自己的属性,例如:
事件数据建模是使用业务逻辑存储事件级数据以产生“可分析的”数据的过程,这意味着更容易查询和理解用户行为。
事件数据模型通常包含 3 个主要的层次级别:
- 用户
- 会议
- 事件
用户
用户实体将包含关于用户的特定属性,例如:
- 电子邮件
- 邮政区码
- 手机号码
- 和其他属性
会议
会话实体将包含关于会话的特定属性,例如:
- 浏览器
- 设备
- 国家(IP)
- 推荐来源等。
事件
事件实体将包含每个事件类型的特定属性,例如:
- 登录事件:用户 ID、登录页面、推荐来源
- 添加项目事件:产品、价格、颜色、尺寸等。
- 结帐事件:总价、折扣、运送选项等。
挑战
传统的 BI 数据模型(如星型模式或雪花模式)包含具有固定结构的事实表和维度。
这对于分析数据来说是高效且易于使用的,但是它只适用于结构化的数据,并且模式变化不大。
基于事件的数据模型基于结构化和半结构化数据,例如:
- URL:在一个字符串中包含许多属性(页面、标题、活动等)。)
- DUA:设备用户代理包含许多关于会话的属性,如设备、浏览器、操作系统、位置等。
- 事件类型:每种事件类型都有不同的模式,因为它基于完全不同的属性,这使得使用传统的 BI 数据模型几乎不可能
事件数据结构也趋向于非常频繁地改变。这意味着您几乎每天都要添加字段和表。由于当今业务的快速发展,数据结构往往会快速变化(与 20 年前相比)。
对于新产品特性、新工具或新版本,您会发现自己需要一个基于事件的数据模型,该模型灵活、可伸缩,并且可以轻松地合并新事件。僵化的模式,如雪花或星型模式,根本不善于适应 21 世纪业务的快速变化的性质。
有几种方法可以构建基于事件的数据模型。下面,我们列出了 3 个最流行的,以及我们自己的版本。在我们开始之前,让我们看看基于事件的数据模型的一些最重要的考虑因素。
基于事件的数据模型的注意事项:
- 易用性 —使用 SQL 分析数据有多简单
- 性能 —最小化连接和全扫描
- 定价 —您可能希望使用更便宜的红移集群或降低 BigQuery 成本
- 易于填充 —将数据加载到模型中有多容易?完全加载、增量加载和更新数据
现在让我们仔细看看你的一些选择。
选项 1-每个事件类型的表+一个公共属性表
- 每种事件类型的事实表
- 每个事件类型表都包含事件属性的特定字段
- 所有事件类型的“所有事件”事实表,带有通用属性字段
赞成的意见
- 特定行为查询的良好性能。
例如:漏斗分析将在事件类型表之间创建连接,这比使用每个事件类型的子查询在所有事件上创建连接要高效得多。 - 为分析特定事件类型而优化。
例如:在 installs 表上分析“install”事件类型比在整个事件表上分析要有效得多。(即,分析“注册”事件将仅访问注册表。) - 您仍然可以使用“所有事件”事实表来分析具有共同属性的所有事件。
骗局
- 难以管理,尤其是在动态环境中。每当添加事件类型时,都需要添加一个反映 ETL、元数据和监控的表。
- 每种事件类型都需要一个新表。即使这种事件类型很少使用,您也需要为每种事件类型维护一个表。当您有数百种事件类型时,这变得难以管理。
- 通过拥有“all_event”表和“event_type”表,您可以复制数据。这需要更多的工作,并且很容易失去同步,导致数据质量问题。
选项 2 —通用事件表+定制属性的 JSON 字段
- 单个事件表
- 该表包含作为字段的公共属性
- 定制属性存储在 JSON 字段中
JSON
赞成的意见
- 比每个事件一个表格更容易管理。新的属性只是添加到 JSON 字段中,不需要管理许多 event_type 表。
- 易于分析常见事件属性。
例如:事件时间戳、用户标识、会话标识等。 - 您可以在事件表中存储用户和会话数据。(这叫做涂抹,帮助你管理缓慢变化的维度。)
骗局
- 难以分析自定义属性。您需要为每个查询从 JSON 字段中提取定制属性,这会导致性能下降。
- 代价高昂的
例如:在 Google BigQuery 中,从较大的 JSON 对象中选择少量数据的代价更高,因为 BigQuery 的定价是基于扫描大小(处理的字节数)的。 - 很难映射元数据并使用 BI 工具来定制属性,因为数据可能位于嵌套的 JSON 字符串中。
选项 3 —嵌套表数据模型
- 针对所有事件的单个事实表
- 同一层次结构中的公共属性
- 嵌套层次结构中的自定义属性
- 您可以为用户和会话数据创建层次结构
例子
赞成的意见
- 优雅且易于理解的数据存储方式。
- 每个层次的属性都很灵活。
- 对于某些查询,如 count distinct,性能良好。
- 某些查询(如 count distinct)将扫描更少的数据。
- 所有数据都包含在一个表中,减少了表之间的连接需求。
骗局
- 嵌套数据变得难以轻易查询。
- 难以将数据加载到表中,尤其是增量数据。
- 难以映射元数据和在嵌套数据模型上使用 BI 工具。包含嵌套数据的列需要相当复杂的已定义模式,以考虑这些列中可能发生的自描述 JSON 事件。
- 几乎不可能更新数据。
为了透明起见,我现在和 Cooladata 在一起,我们是利用基于事件的数据模型来收集和分析所有数据系统和孤岛中的用户行为的领导者。
以下是 Cooladata 选项的视图:
- 单个事件表
- 可以选择将特定的事件类型存储到不同的表中。
例如:流行的事件类型,比如“页面视图”,可以存储在一个单独的表中,其余的事件类型可以存储在一个单独的表中 - 该表包含作为字段的通用和自定义属性
- 该表包含每个事件行的用户和会话数据(涂抹)
赞成的意见
- 易于理解数据的存储方式。
- 通过将流行的事件类型存储在单独的表中,您可以获得最佳的性价比。
- 所有数据加载都由 Cooladata 处理。
- 你能够很容易地分析数据。
- 您可以轻松访问历史变化(缓慢变化的维度)。
骗局
- 为了获得最佳性能,您需要使用 CQL (Cooladata SQL)。
- 数据管理通过 Cooladata 进行。
附加 Cooladata 功能
物理模式
我们按照时间和属性对数据进行划分,例如事件类型、地理位置等。以获得最佳性能并优化数据访问。
我们将数据存储在一个稀疏的柱状分析数据库中,从而获得灵活性和性能。
语义层/元数据
我们从在线数据和传统数据中自动创建语义层和元数据。
优化的数据访问层(解析器)
我们的智能解析器翻译简单的 SQL 语句,以便能够访问相关的分区。
行为时间序列扩展(CQL)
我们扩展了 SQL,它是基于集合的,具有更多的功能,支持对粒度数据进行时间序列分析。
我们的技术提供了这些功能:
- 将事务性和基于在线的数据结合成一个连贯的流。
- 数据模型中基于文档的模式的灵活性。
- 在一个模式中进行全面的维度和时间序列分析。
- 能够在数据模型上使用常见的可视化工具。
- 临时统一在线和传统数据。
- 通过智能分区优化数据成本。
- 全面跟踪历史数据变化(渐变维度)。
- 按需提供数据分析师和数据科学家,帮助您构建数据模型和解释数据。
感谢阅读,希望你学到了一些东西。但
构建和测试一个简单的深度学习对象检测应用
深度学习是目前的热点。非常性感。这是因为在感知领域,可用的数据比以往任何时候都多。我所说的感知是指诸如图像中的物体识别、自然语言处理、语音检测等任务。基本上,我们每天都会产生大量的数据。许多公司都很好地利用了这些数据。谷歌,脸书,英伟达,亚马逊等。因为他们可以访问这些数据中的大部分。作为用户,我们很乐意通过我们所有的社交媒体帖子和在线存储利用率将它提供给他们。在任何情况下,我都想让大家体验一下,你可以用一个相对较小的卷积神经网络来检测图像中的许多不同对象。具体来说,我们将使用一种称为 MobileNet 的网络架构,它可以在较小的设备上运行。幸运的是,你可以接触到预先训练好的模型并进行测试。这正是我们今天要做的。
数据基础
该模型已经在 COCO 数据集(上下文中的公共对象)上进行了训练。就像听起来这个数据集包含了很多我们在日常生活中经常看到的物体的图像一样。具体来说,它由 90 个不同物体的 30 万张图像组成,例如
- 水果
- 车辆
- 人
- 等等。
模型
我们使用的型号是“带 MobileNet 的单次多盒探测器(SSD )”,位于这里,下载需要一点时间。它是用谷歌的协议缓冲格式存储的。我知道你在想什么:为什么要发明另一种结构化存储格式?在谷歌的辩护中,这是非常酷的。基本上,它是一种语言中立、平台中立、可扩展的序列化结构化数据的机制——想想 XML,但是更小、更快、更简单。一旦定义了数据的结构化方式,就可以使用专门生成的源代码,使用各种语言轻松地将结构化数据写入各种数据流或从中读取。
卷积神经网络
A Generic Convolutional Neural Network Architecture with Kernel filters and Pooling layers
在我们查看结果之前,让我们快速介绍一下卷积神经网络到底是什么,以及为什么它们在图像分析方面比普通的多层感知器更成功。使用卷积神经网络背后的整个想法是,我们需要网络是平移和旋转不变的。这仅仅意味着我们需要能够识别一个物体,不管它在图像中的什么位置。实现这一点的一种方法是在图像上滑动对特定图案起反应的补丁。你可以把它想象成一个过滤器,当它检测到什么东西的时候就会亮起来。当然,我们不知道我们在寻找什么,因此这些过滤器是在训练中学习的。一般来说,在深度学习中,我们在初始层中学习较低级别的特征,而后面的层捕捉更精细的特征。这很酷,因为我们可以保存最初训练的早期层,并在其他模型中重用它们。
结果
下面的视频是我在建模团队工作时用手机拍摄的。正如你所看到的,这个模型确实很成功地识别了一些物体。但是它也没有检测到其中的许多。这有很多原因。其中之一是这个模型是针对速度而不是性能进行优化的。
Detecting Modelers using our convolutional neural network!
在这篇短文中,我向你展示了如何利用之前拟合的卷积神经网络对回顾视频中的对象进行分类。然而,这可以从网络摄像头或监控摄像机扩展到活动物体检测。如果你对自己做这件事感兴趣,看看 Tensorflow 的例子这里。
黑客快乐!
一步一步地建立和测试推荐系统
Photo credit: Pixabay
了解如何借助 Python 和惊喜库、协同过滤来构建自己的推荐引擎
推荐系统是数据科学最常用和最容易理解的应用之一。关于这个主题已经做了很多工作,由于互联网的快速发展和信息过载问题,人们对这个领域的兴趣和需求仍然很高。帮助用户处理信息过载并向他们提供个性化的推荐、内容和服务已经成为在线企业的必要工作。
推荐系统最流行的两种方法是协同过滤和基于内容的推荐。在本帖中,我们将重点介绍协同过滤方法,即:向用户推荐过去有相似品味和偏好的人喜欢的项目。换句话说,这种方法通过使用用户之间的相似性来预测未知的评级。
我们将与图书交叉,一个图书评级数据集一起开发推荐系统算法,与惊喜图书馆,它是由 Nicolas Hug 建立的。我们开始吧!
数据
图书交叉数据由三个表组成,我们将使用其中的两个:用户表和图书评级表。
user = pd.read_csv('BX-Users.csv', sep=';', error_bad_lines=False, encoding="latin-1")
user.columns = ['userID', 'Location', 'Age']
rating = pd.read_csv('BX-Book-Ratings.csv', sep=';', error_bad_lines=False, encoding="latin-1")
rating.columns = ['userID', 'ISBN', 'bookRating']
df = pd.merge(user, rating, on='userID', how='inner')
df.drop(['Location', 'Age'], axis=1, inplace=True)
df.head()
Figure 1
电子设计自动化(Electronic Design Automation)
收视率分布
ratings_distribution.py
Figure 2
我们可以看到,数据中超过 62%的评级为 0,极少数评级为 1 或 2,或 3,低评级书意味着它们通常非常糟糕。
图书收视率分布
ratings_distribution_by_book.py
Figure 3
df.groupby('ISBN')['bookRating'].count().reset_index().sort_values('bookRating', ascending=False)[:10]
Figure 4
数据中的大部分书获得的评分都在 5 分以下,极少数书获得了很多评分,尽管评分最高的书获得了 2502 分。
用户评分分布
ratings_distribution_by_user.py
Figure 5
df.groupby('userID')['bookRating'].count().reset_index().sort_values('bookRating', ascending=False)[:10]
Figure 6
数据中的大多数用户给出的评分少于 5 分,给出很多评分的用户也不多,尽管最有生产力的用户给出了 13,602 个评分。
我相信你已经注意到了上面两个图有相同的分布。每本书的评分数和每个用户的评分数呈指数衰减。
为了降低数据集的维度,避免陷入“记忆错误”,我们将过滤掉很少评级的书籍和很少评级的用户。
filter_dataframe.py
Figure 7
惊喜
load_from_df()Readerrating_scale
reader = Reader(rating_scale=(0, 9))
data = Dataset.load_from_df(df_new[['userID', 'ISBN', 'bookRating']], reader)
借助惊喜库,我们将对以下算法进行基准测试:
基本算法
正常预测值
NormalPredictor
仅基线
BaselineOnly
k-NN 算法
KNNBasic
KNNBasic
KNNWithMeans
KNNWithMeans
KNNWithZScore
KNNWithZScore
KNNBaseline
KNNBaseline
基于矩阵分解的算法
奇异值分解
SVDpp
SVDpp
NMF
NMF
一号斜坡
共聚类
我们使用“rmse”作为预测的准确性指标。
benchmark.py
Figure 8
训练和预测
BaselineOnlyBaselineOnly
print('Using ALS')
bsl_options = {'method': 'als',
'n_epochs': 5,
'reg_u': 12,
'reg_i': 5
}
algo = BaselineOnly(bsl_options=bsl_options)
cross_validate(algo, data, measures=['RMSE'], cv=3, verbose=False)
Figure 9
train_test_split()fit()test()
trainset, testset = train_test_split(data, test_size=0.25)
algo = BaselineOnly(bsl_options=bsl_options)
predictions = algo.fit(trainset).test(testset)
accuracy.rmse(predictions)
Figure 10
为了详细检查我们的预测,我们将建立一个包含所有预测的熊猫数据框。下面的代码大部分摘自这个笔记本。
predictions_details.py
最佳预测:
Figure 11
以上是最好的预测,不是侥幸的猜测。因为 Ui 介于 25 到 146 之间,所以它们并不小,这意味着大量用户对目标图书进行了评级。
最坏的预测:
Figure 12
最糟糕的预测看起来相当令人惊讶。让我们看看最后一个 ISBN“055358264 x”的更多细节。这本书被 47 个用户评分,用户“26544”评分为 10,我们的 BaselineOnly 算法预测该用户评分为 0。
import matplotlib.pyplot as plt
%matplotlib notebookdf_new.loc[df_new['ISBN'] == '055358264X']['bookRating'].hist()
plt.xlabel('rating')
plt.ylabel('Number of ratings')
plt.title('Number of ratings book ISBN 055358264X has received')
plt.show();
Figure 13
结果发现,这本书获得的大部分评分是 0,换句话说,数据中的大部分用户给这本书的评分是 0,只有极少数用户给了 10。与“最差预测”列表中的其他预测相同。似乎对于每一个预测,用户都是某种局外人。
就是这样!我希望你喜欢这个推荐(或者更确切地说,一个评级预测)之旅。 Jupyter 笔记本可以在 Github 上找到。节日快乐!
构建人工通用智能
Building Artificial General Intelligence
从这个意义上来说,今年是一个不错的年份,我遇到了两个资源,它们帮助我更好地了解人工智能的当前状态,以及我们真正需要进入和建立一个“更高”级别的智能或俗称的人工通用智能(简称 AGI)。我希望向 AI 社区推荐这两个资源,并写下我的一些想法,希望能得到一个好的讨论。
论智力
所以第一个资源是我的朋友推荐给我的,这是一本名为《关于智力的书》,作者是杰夫·霍金斯,他是 Numenta 的创始人,正在进行新大脑皮层的逆向工程,研究大脑如何工作并创建一个通用计算模型。他们提出了这个被称为分级时间记忆的通用模型,简称 HTM。HTM 是一个结合了神经科学和机器智能的理论框架,我相信这是建设 AGI 的正确方向。
人工智能的当前状态已经看到了许多构建人工狭义智能的成功,这意味着所构建的智能体可以在特定的领域中非常成功,如围棋(来自谷歌 Deepmind 的 AlphaGo)、DOTA(特斯拉)、无人驾驶汽车甚至汉堡烙牛肉饼机。这些代理拥有必要的工具,能够很好地完成他们的使命,但是如果你仔细研究他们,你会发现他们的前景已经非常明确了。这种情况需要人类智能来完成,例如,在强化学习中,人类智能来建立效用/延续功能,定义状态、奖励和可以采取的行动等。甚至在机器学习中,目前由监督学习组成,在机器学习之前,我们必须先记下标签/结果。(我将在下一篇参考资料中回到这一点)。
为什么之书
如果你要成为一名数据科学家或人工智能科学家,这是一本必读的书,朱迪亚·珀尔的《为什么之书》。朱迪亚·珀尔支持人工智能的概率方法(这就是为什么你需要研究你的统计数据的原因)。通过《为什么》一书,他主张,如果我们要走向 AGI,我们需要在人工智能中建立“因果关系”。在书中,他提到了一种演算,我们需要这种演算来构建可以帮助机器理解因果关系的结构模型,称为因果演算。
在书中,他介绍了因果关系的阶梯,这是三级阶梯,最底层是“看”、“做”和“想象”。目前,如果我们仔细研究机器学习,我们仍然处于“看”的阶段,即第一级。如果我们要建设 AGI,我们需要开始帮助机器做更多的第二梯队,更重要的是,第三梯队。
在我研究这个领域的过程中,最困扰我的一个问题是,我们如何确定监督模型的标签/结果。目前,机器学习模型可以接受任何因变量,并告诉你它和自变量之间的关系。仍然需要人类的智慧来确定什么是因变量和自变量。仍然需要人类智能来查看数据是否可以输入到模型中(如果我们要实现机器学习模型的话)。机器学习模型在这个意义上是“愚蠢的”,因为它将接受我们定义的因变量和自变量。如果我们要建设一个 AGI,那么 AGI 也必须能够执行这样的任务。为了确定这一点,我们需要在整个结构中建立“因果关系”。
到目前为止,我已经读到了这本书的第三章,我觉得能够阅读这样的作品是值得的。我决定慢慢来,消化里面的大量知识。
最初的想法
到目前为止,我相信“因果关系”可以通过我们大脑不断进行的时间/预测建立到 HTM 模型中。这种想法肯定需要更多的研究和理解,以确定其可能性。我坚信,通过将这两种资源结合在一起,我们可以走上建设 AGI 的道路。
如果我们要继续当前的路线,我毫不怀疑我们可以通过调整当前的深度学习模型来建立出色的人工狭义智能(ANI),即非常好地执行特定任务的代理,但我非常怀疑这条路线可以带我们走上人工通用智能的道路。此外,目前使用深度学习来构建 ANI 的路线在计算上是昂贵的,如果它发生在我们的大脑中,我们可能必须消耗大量的食物来支持它。
以上是我目前为止的想法,我愿意与读者进行讨论。😃
如果这篇博文对你来说很有趣和/或有用,请鼓掌。我也写关于数据科学的博客,所以请访问我的其他博客文章和 LinkedIn 个人资料。
在野外构建客户端路由/语义搜索
Main objective — help our clients find what they want, ideally even before they type the whole query. Search also should generalize reasonably well (synonyms / forms of known words, Russian has rich morphology)
TLDR
这是一份关于我们在语义工厂项目中的 Profi.ru DS 部门(Profi.ru 是 CIS 地区领先的在线服务市场之一)在大约 2 个月的时间里所做工作的执行摘要。
这篇文章主要集中在比较新的 NLP 技术在应用商业环境中的适用性,如果你计划在你的公司/项目中做类似的事情,它可以作为一个指南。
简而言之,我们有两个目标:
- 使 Profi.ru 上主搜索栏内的搜索/路由更好(监督任务);
- 这样做——开发无监督的方法,以有效地在第三方数据中搜索新服务(无监督任务);
我们考虑了许多架构,但最终一个具有嵌入包层而不是普通嵌入的双 LSTM(或双 GRU)被证明是监督和非监督任务的最佳**(见下图)。值得注意的是,使模型对部分输入/有误差的输入具有鲁棒性提高了其性能。此外,添加第二个目标(假“服务”检测)也略微提高了准确性**。像 transformer 这样更复杂的模型在我们的领域中没有显示出真正的好处。****
现有数据
我们使用的内部数据来自几个主要来源:
- 实际客户端搜索(每 3-6 个月 30k 个唯一查询)+手动注释(这产生了我们的主开发集);
- 内部同义词库 (30k 唯一同义词);
- 内部营销 SEO 数据库带注释(300k);
在我们之前,公司里没有人建立 ML 模型,所以我们必须在获取数据和管理数据注释时随机应变。还应该注意的是,尽管查询的总数很大,但唯一的查询计数却非常低,这迫使我们在获取/扩充数据时要有创造性。此外,手头的数据集和注释的质量差异很大。正如所料,最好的监督数据集是人工注释的数据集和同义词数据库。我们还尝试探索转换管道(即查询—会话—顺序)并提取以前的分类器结果—预期性能不佳。
关于外部数据,我们使用了以下来源:
- 搜索引擎数据(Google 和 Yandex 的 SEO 小组及其统计服务提供的数据)( 11m 查询);
- 外部 SEO 服务( 3m 查询);
- 我们竞争对手的公开数据( 1.5m 查询);
实现的目标
业务目标:
88+%60%5k1,00015,0005,00030,000
“科学”目标:
- 我们使用下游分类任务+ KNN 和服务同义词数据库彻底比较了许多现代句子嵌入技术;
- 我们使用非监督方法,在基准测试中成功击败了弱监督(本质上,他们的分类器是一袋 ngrams)弹性搜索(详见下文);
- 我们开发了一种构建应用 NLP 模型的新方法(一个普通的双 LSTM +嵌入包,本质上是快速文本符合 RNN)——这考虑到了俄语的形态学,并且推广得很好;
- 我们证明了我们的最终嵌入技术(来自最佳分类器的瓶颈层)结合最先进的无监督算法(UMAP + HDBSCAN)可以在外部数据上产生恒星簇;
- 我们在实践中证明了以下方法的可能性、可行性和可用性:(1)知识提炼(2)文本数据扩充(原文如此!);
- 与生成更大的静态数据集相比,使用动态增强来训练基于文本的分类器大大减少了收敛时间(10 倍)(即,CNN 学习概括错误,显示大大减少增强的句子);
现在 NLP 里什么管用?
鸟瞰 NLP 景观:
此外,您可能知道 NLP 现在可能正在经历 Imagenet 时刻。
大规模 UMAP 黑客攻击
什么最有效
- 对于监督分类,快速文本满足 RNN(双 LSTM) +精心选择的 n 元文法集;
- 实现——普通 python 为 n-grams + PyTorch 嵌入包层;
- 对于集群——该模型的瓶颈层+UMAP+hdb scan;
最佳分类器基准
手动注释开发集
Performance of the best model (n-gram bag + biLSTM) on manually annotated dev-set
手动注释开发集+每个查询 1-3 个错别字
Performance of the best model (n-gram bag + biLSTM) on manually annotated dev-set, where we added 1 to 3 typos to each query
手动注释开发集+部分输入
Performance of the best model (n-gram bag + biLSTM) on manually annotated dev-set, where we randomly cut the input sequence to simulate partial input
大规模语料库/ n-gram 选择
我们收集了最大的俄语语料库:
100m1m500k500k
我们的 100 万词汇上的 100 万 n-grams 的压力测试:
Share of n-grams (3–7 grams) in a 100M word vocabulary covered by our n-gram selection
文本扩充
简而言之:
- 拿一本有错误的大字典(例如 万个独特的单词);
- 产生一个错误(丢弃一个字母,使用计算的概率交换一个字母,插入一个随机的字母,可能使用键盘布局等);
- 检查新单词是否在词典中;
我们对像这个这样的服务进行了大量的强制查询(试图从本质上对它们的数据集进行逆向工程),它们内部有一个非常小的字典(这个服务也是由一个具有 n 元语法特征的树分类器支持的)。看到它们只覆盖了我们在一些语料库中的 30 %- 50%的单词有点好笑。
如果你有大量的领域词汇,我们的方法要优越得多。
最佳无监督/半监督结果
KNN 被用作比较不同嵌入方法的基准。这更多的是一个例子,但是显然我们使用这些方法来聚集/搜索新的服务。
(向量大小)测试模型列表:
- (512)在 200 GB 普通爬行数据上训练的大规模假句子检测器;
- (300)假句子检测器,被训练成从服务中辨别来自维基百科的随机句子;
- (300)从这里获得的快速文本,在 araneum 语料库上进行预训练;
- (200)在我们的领域数据上训练的快速文本;
- (300)在 200GB 的普通爬行数据上训练的快速文本;
- (300)用来自维基百科的服务/同义词/随机句子训练的三联体丢失的连体网络;
- (200)嵌入包 RNN 的嵌入层的第一次迭代,句子被编码为整个嵌入包;
- (200)相同,但首先将句子拆分成单词,然后嵌入每个单词,然后取普通平均值;
- (300)同上,但用于最终模型;
- (300)同上,但用于最终模型;
- (250)最终模型的瓶颈层(250 个神经元);
- 弱监督弹性搜索基线;
为了避免泄密,所有的随机句子都是随机抽样的。他们的单词长度与他们所比较的服务/同义词的长度相同。此外,还采取措施确保模型不只是通过分离词汇来学习(嵌入被冻结,维基百科被欠采样以确保每个维基百科句子中至少有一个领域词)。
集群可视化
最佳嵌入技术+ UMAP 如何在一个外部语料库上工作的例子。
3D
2D
集群探索“界面”
绿色—新单词/同义词。灰色背景-可能是新词。
灰色文本-现有同义词。
消融试验和哪些有效,我们尝试了哪些,哪些没有
- 见以上图表;
- 快速文本嵌入的普通平均值/tf-idf 平均值——一个非常强大的基线;
- 俄语的 fast-text > word 2 vec;
- 通过伪句子检测的句子嵌入类工作,但是与其他方法相比相形见绌;
- BPE(句子)显示没有改善我们的领域;
- 尽管谷歌撤回了论文,但 Char 级模型很难推广;
- 我们尝试了多头 transformer(带有分类器和语言建模头),但是在手边可用的注释上,它的性能与普通的基于 LSTM 的模型大致相同。当我们迁移到嵌入 bad 方法时,我们放弃了这一研究方向,因为变压器的实用性较低,并且具有 LM 头和嵌入包层是不切实际的;
- 伯特(BERT)——似乎有些夸张,也有人声称变形金刚实际上训练了几个星期;
- ELMO——在我看来,无论是在研究/生产还是教育环境中,使用像 AllenNLP 这样的库似乎都是适得其反的,原因我就不在这里说了;
部署
使用完成:
2.5 ms1GBPyTorchnumpypandas
结论
我们已经表明,您可以应用相对简单/现成的工具来解决真实业务中语义搜索框架内的监督和非监督挑战。
进一步阅读
原载于 2018 年 11 月 2 日spark-in . me。