手机上的 TensorFlow:教程
在安卓和 iOS 上
TensorFlow 通常用于从大量数据中训练巨大的模型,但没有人能忽视智能手机的新兴市场以及让我们的未来“人工智能”的需要。而那些对未来迫不及待、热爱机器学习的人,正在通过制造工具来推动边界,这些工具瞄准了数万亿美元的市场。
你是这个数万亿美元市场的一部分,因为你现在可能正在你的 Android 或 iOS 上阅读这篇文章,或者你的口袋里有一个,无论是哪种情况,你都知道移动设备上面向未来的机器学习是多么重要…
我将写 2 个不同的教程,关于如何在你的 Android 和 iOS 设备上运行你的机器学习模型。
这是第一个教程。
本教程使用了更稳定的 tensorflow 版本,即 TensorFlow Mobile,因此请按照步骤来实现您的模型,并使它们针对移动设备进行优化。
我们将通过重新训练 Inception-v3 模型的最后(瓶颈)层来制作一个图像分类器,然后为您的智能设备优化该模型。
本教程仅包含 5-6 个步骤:
第一步:用 TensorFlow 创建你的模型
我很确定你已经知道这一步,因为你正在学习在智能手机上运行相同的模型。
另外,为了使本教程严格集中在智能手机的*实现模型上,*我推荐这个快速教程🔹利用 CPU 上的自定义图像进行列车启动🔹这样我们就能达成一致了📄你可以用一个新训练的模型在一个新的目录中开始这些东西。
仅供参考: 数据📗模型被训练的地方包含郁金香的种类🌷*、雏菊、向日葵🌻、蒲公英和玫瑰*🌹
在这之后,你应该有这两个文件:
tf_files/retrained_graph.pb
其中包含所选网络的一个版本,以及根据您的类别重新训练的最终层。
和
tf_files/retrained_labels.txt
这是一个文本文件📝包含标签。
步骤 2:创建一个优化的模型😎
运行以下命令提示符(保持路径正确)
python -m tensorflow.python.tools.optimize_for_inference \
--input=tf_files/retrained_graph.pb \
--output=tf_files/optimized_graph.pb \
--input_names="input" \
--output_names="final_result"
它将创建一个新的优化模型文件tf_files/optimized_graph.pb
**注意:**如果出现错误
KeyError: “The following input nodes were not found: {‘input’}\n”
,则将“输入”改为“Mul”。
取舍😇
为了减少应用的预处理,同时减少库的大小,tensorflow 只支持推理过程中常用的操作子集。不支持的操作有tensor flow/contrib/makefile/TF _ op _ files . txt
现在,为了确保我们刚刚创建的任何图形文件都包括支持的操作,如下所示…
验证✔️
确保新的优化图正在运行,并且 optimize_for_inference 文件删除了一组给定输入和输出不需要的所有节点,并且没有改变网络的输出。
使用图形retained _ graph . Pb和 optimized_graph.pb 上的 label_file 比较同一图像的输出
用retained _ graph . Pb
python -m scripts.label_image \
--graph=tf_files/retrained_graph.pb \
--image=tf_files/flower_photos/daisy/3475870145_685a19116d.jpg
用 optimized_graph.pb
python -m scripts/label_image \
--graph=tf_files/optimized_graph.pb \
--image=tf_files/flower_photos/daisy/3475870145_685a19116d.jpg
逐一运行这些命令,如果两个输出相同,这意味着 optimized_graph.pb 已完美创建🎉
第三步:量化模型,然后压缩
问题仍然是模型的尺寸仍然很大,肯定不适合手机。因为,图中所占的大部分空间是由权重占据的,权重是大块的浮点数。每个权重的浮点值略有不同,规律性很小。
但是压缩通过利用数据中的规律性来工作,这解释了这里的失败。
通过对网络的权重进行量化,量化有助于通过因子来减小神经网络的大小。这在图形中给出了更多的重复,并且对之后的压缩有很大的帮助。
现在使用 quantize_graph 脚本将更改应用到图形:
python -m scripts.quantize_graph \
--input=tf_files/optimized_graph.pb \
--output=tf_files/rounded_graph.pb \
--output_node_names=final_result \
--mode=weights_rounded
现在压缩模型:
gzip -c tf_files/rounded_graph.pb > tf_files/rounded_graph.pb.gz
gzip -l tf_files/rounded_graph.pb.gz
这将创建一个 rounded_graph.pb 文件。
您应该会看到压缩方面的一些显著改进。
**注意:**如果您在运行 quantize_graph 时遇到任何错误,请下载该文件并将其粘贴到 tensorflow 库(安装 TensorFlow 的位置)中的tools/quantization/quantize _ graph . py中。
从这里开始,教程分为两个部分 Android 和 iOS。
🍎ios📱
第四步:添加 tensor flow-实验舱
将 TensorFlow-experimental pod 添加到您的 pod 文件中,这将安装一个通用二进制框架。这是在 iOS 上运行 tensorflow 最简单的方法。
步骤 5:创建你的应用程序
🔹创建您自己的应用程序或在 XCode 中载入您已经创建的应用程序。
🔹在项目根目录下添加一个名为 Podfile 的文件,内容如下:
target 'YourProjectName'
pod 'TensorFlow-experimental'
🔹运行pod install
下载&安装TensorFlow-experimental
pod。
🔹打开YourProjectName.xcworkspace
,添加你的代码。
🔹在你的应用的构建设置中,确保将$(inherited)
添加到其他链接器标志和头搜索路径部分。
步骤 6:运行样品
您需要 Xcode 7.3 或更高版本来运行我们的 iOS 示例。
简单、基准和相机中有三个例子。可以克隆代码。
此外,从 tensorflow 的根目录下载 Inception v1 ,并使用以下步骤将标签和图形文件提取到简单示例和相机示例中的数据文件夹中:
mkdir -p ~/graphs
curl -o ~/graphs/inception5h.zip \
https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip \
&& unzip ~/graphs/inception5h.zip -d ~/graphs/inception5h
cp ~/graphs/inception5h/* tensorflow/examples/ios/benchmark/data/
cp ~/graphs/inception5h/* tensorflow/examples/ios/camera/data/
cp ~/graphs/inception5h/* tensorflow/examples/ios/simple/data/
切换到其中一个示例目录,下载tensor flow-experimentalpod,并打开 Xcode 工作区。请注意,安装 pod 可能需要很长时间,因为它很大(约 450MB)。如果您想运行这个简单的示例,那么:
cd tensorflow/examples/ios/simple
pod install
open tf_simple_example.xcworkspace #note .xcworkspace,not .xcodeproj
在 XCode 模拟器中运行简单的应用程序。您应该会看到一个带有运行模式按钮的单屏幕应用程序。点击它,你会看到一个格蕾丝·赫柏的图像。一旦你建立并运行它,你应该得到一个实时的摄像机视图,你可以指向物体以获得实时的识别结果。
**注意:**我很确定我犯了一些错误或者在 iOS 部分留下了一些东西。请浏览下面的官方链接,如果你有任何错误,请在下面评论,社区会帮助你。
现在,你可以跳过这篇文章的 Android 部分。
[## 在 iOS | TensorFlow 上构建 TensorFlow
TensorFlow-experimental pod 目前大约为 450MB。它如此之大的原因是因为我们捆绑了多个…
www.tensorflow.org](https://www.tensorflow.org/mobile/ios_build)
🍭 🍦机器人🍞🐝 🍩
步骤 4:安装 Android Studio 并测试运行
有两种方法可以做到这一点:Android Studio 和 Bazel。我将使用 AS,因为更多的人熟悉它。
如果您还没有安装它,请到这里安装它
[## 下载 Android Studio 和 SDK 工具| Android Studio
下载官方 Android IDE 和开发工具,为 Android 手机、平板电脑、可穿戴设备、电视和…构建应用
developer.android.com](https://developer.android.com/studio/index.html)
试运转🏃
为了检查 Android Studio 中的一切是否正常,让我们进行一次测试。
🔸打开 Android Studio,选择“📁打开一个现有的 Android Studio 项目”。
🔸进入tensor flow-for-poets-2/Android/TF mobile目录。
🔸打开 Build.gradle 文件,同步 Gradle。如果一切正常,点击构建>构建 APK 按钮。
**注意:**如果你和我一样是 Android Studio 的新手,并且有一些问题,请在下面评论。
现在应该有一个文件夹,里面有 app.apk 文件,复制到手机里安装。另外,记住打开手机中的开发者模式。
第五步:运行定制的应用程序👏 👏 👏
如果到现在为止一切正常,从现在开始就是小菜一碟。
默认应用程序是一个分类图像应用程序,有来自 Imagenet 的 1000 个类别。
现在,要运行我们定制的应用程序,请执行以下两个步骤:
将模型文件添加到项目中
现在,演示应用程序正在查看出现在Android/TF mobile/assets中的 graph.pb 文件和 label.txt 文件,而不是您的 rounded_graph.pb 和retained _ labels . txt
现在,用下面的命令替换这些文件,或者也可以手动替换。
cp tf_files/rounded_graph.pb android/tfmobile/assets/graph.pb
cp tf_files/retrained_labels.txt android/tfmobile/assets/labels.txt
更改ClassifierActivity.java file
中的output_name"
我们模型的输出节点有一个不同的名字:"final_result"
。打开ClassifierActivity.java
,更新OUTPUT_NAME
变量,如下所示:
private static final String INPUT_NAME = "input";
private static final String OUTPUT_NAME = "final_result";
👏 👏 👏再次运行,事情应该工作了。👏 👏 👏
**注意:**如果你出现任何错误或者打中了下面任何一个墙评论。
️I 试图让这篇文章尽可能准确易懂。有任何意见、建议或疑问,请写在评论里。
有关如何在移动应用程序中使用tensor flow的更多教程,请关注我的 中的 、脸书、 Twitter 、 LinkedIn 、 Google+ 、 Quora 以查看类似的帖子。
鼓掌吧!分享一下!跟我来。
乐意帮忙。荣誉………
你会喜欢的以前的故事:
使用 Flask 设计专业邮件!
medium.com](https://medium.com/@sagarsharma4244/how-to-send-emails-using-python-4293dacc57d9)
使用应用程序引擎的 TensorFlow 照片 x 射线对象检测
在以前的文章中,我们使用 TensorFlow 对象检测 API 应用不同类型的模型来分析图像中的对象。(第一条,第二条)
在这些例子中,解决方案总是为一个控制台应用程序设计的(即一个本地运行的 Python 脚本)。
现在我们的挑战是把它带到一个网络环境,检测照片中的物体(比如 x 光),最后我们应该提出一个简单的架构选项。
概观
我们可以考虑使用服务器模式的几种架构选项(来自官方文档 TensorFlow Serving 的示例)。我们甚至可以考虑传统的替代方案(如 Apache、Nginx 等)。)但是我们应该考虑安装 Web 服务器,并使用 TensorFlow 调整所有元素来执行分析。
我喜欢使用像 App Engine 这样的平台 方案的想法,但是实现我们的想法对于像 App Engine 这样的传统环境来说是一个挑战(我们可以考虑使用 PubSub 和 VMs workers 的解决方案,但是会考虑到更多的复杂性),所以…为了解决我们的挑战,我将使用 App Engine 灵活环境。
拟议解决方案
提议的架构
App Engine 灵活环境项目
- app.yaml
- main.py
- 模板/索引. html
关于 App Engine 灵活环境的更多详情
照片的评估程序:
- 主要依赖关系Flask(0 . 12 . 2)tensor flow(1 . 2 . 1)除了这些支持元素,numpy,Image,cStringIO,urllib。
要使用这个示例,您需要 TensorFlow 对象检测 API 的这些基本元素:
- 模型[文件夹]
- 原型[文件夹]
- 实用程序[文件夹]
注:如果你需要下载测试功能文件,这里我准备了一个工作版本。
此外,我们需要在我们的解决方案中有模型的冻结 _ 推理 _ 图形。对于我们的例子:
- SSD _ mobilenet _ v1 _ coco _ 11 _ 06 _ 2017(如果您需要更多条件,可以更改此型号)
注意:如果你需要下载测试功能文件,这里我准备了一个工作版本。
对于我们的例子,我们使用 COCO 作为对象识别方案,因此我们需要识别标签来进行分析。
- data/mscoco_label_map.pbtxt
注意:如果你需要下载测试功能文件,这里我准备了一个工作版本。
在这里,我将从这个 Github 库中实现解决方案(初始阶段)。
部署项目
- 本地 : python main.py
- 生产环境 : gcloud app 部署
*(-v 版本)如果要将其部署到特定版本。
注意:你要有 Google Cloud SDK 。更多关于 App Engine 灵活环境的信息,Python 在此。
TensorFlow &反光胶带🏀(我篮球打得不好吗?)
最近一个朋友让我迷上了篮球。事实证明,这比看起来难多了。没关系,我可以用机器学习来设计解决方案。如果你对 ML 和投篮感兴趣,那么也有这篇文章在模拟中结合了张量流和篮球。
nothing but net… if there was a net
任务是找到我拍摄的准确角度。然后,我就可以积极主动地利用这些信息,变得更好。
嘶!这一切的代码都在我的 Github 上
任务 1:收集数据
I didn’t need to follow the seems of the ball, but it looks cool
我没有配备 200 个摄像头的 3D 追踪工作室,但我有 Ebay。网上买反光带贴在球上还是挺容易的。然后(由于我当地的球场缺乏照明),我可以录下一些我晚上练习的镜头,并捕捉球的运动。
我手机内置的手电筒提供了完美的光源来反射球的反光。
因此,捕捉到的镜头显示了一个闪闪发光的物体飞过一个几乎黑暗的场景,非常适合在 python 中进行一些图像处理。
任务 2:将我们的视频导入 python
首先,我用 Python 做所有事情,将视频导入 Python 的一个非常简单的方法是使用一个名为’ scikit-video '的库,所以我安装了:
pip install scikit-video
然后用它来加载我的视频作为一个矩阵:
from skvideo.io import vreadvideo_data = vread('VID_20180930_193148_2.mp4')
这个数据的形状(可以通过运行 video_data.shape 找到)是(220,1080,1920,3)。这意味着 3 个颜色通道(红、绿、蓝)的 1080×1920 像素的 220 帧:
raw video data
任务 3:提取镜头(图像处理)
所以我想得到球运动的数据。幸运的是,这是视频中唯一会动的东西之一。所以我可以做我最喜欢的视频处理技巧:增量帧提取!(我就是这么叫的,不过可能还有另外一个名字)。
通过从下一帧中的所有像素值中减去一帧中的所有像素值,您将只在已经改变的像素中得到非零值。
calculating delta frame in order to isolate moving pixels
酷酷酷,现在我对视频中的每一帧都这样做,并将结果合并成一幅图像:
adding together all of the delta frames from the video sequence
接下来是将拍摄数据提取成可用的格式。所以我们将把精简后的像素值转换成一个由***【x】和 y 点组成的列表。完成这项工作的代码是一个名为 numpy.where 的 numpy 函数,它将在一个数组中找到所有为真*的值,并返回它们的索引(即它们在矩阵中的位置)。
但在此之前,我们将快速裁剪出球的轨迹并翻转数据,使其从原点(场景的左下方)开始:
由此产生的图像:
注意到它看起来还是上下颠倒了吗?这只是因为图像倾向于从左上角的开始绘制(注意轴编号)。当我们将像素转换为数据点并将它们绘制在普通图上时,它们将从底部的左下角开始绘制。****
现在我们运行我们的 numpy.where 代码来获取像素作为数据点:
pixels_that_are_not_black = cropped_trail.sum(axis=2) > 0y_data, x_data = numpy.where(pixels_that_are_not_black)
awesome! our relatively clean ball trajectory data
任务 4:构建张量流模型
这就是 TensorFlow 大放异彩的地方。你可能习惯于听说使用 TensorFlow 来构建神经网络,但你可以定义几乎任何数学公式,并告诉它优化你想要的任何部分。在我们的例子中,我们将使用从小学就知道的轨迹公式:
extremely mathematical equation of trajectory that I found online
θ (theta)是拍摄的角度(我们真正关心的值)
v 是初速度
g 是重力(9.8m/s)
x 是水平位置(数据我们已经)
y 是垂直位置(数据我们已经)
一个更有趣的方式来看这个方程的作用是用这个轨迹工具来玩。
我们可以使用我击球的球轨迹作为 x 和y**方程和任务张量流,找到适合我击球的正确角度( θ )和初始速度( v )
我们将开始在张量流中重建我们的轨迹方程:
首先告诉它,当我们运行优化时,我们将输入什么数据:
*x = tf.placeholder(tf.float32, [**None**, 1])
y = tf.placeholder(tf.float32, [**None**, 1])*
接下来,告诉它我们希望它调整哪些变量,以使轨迹曲线符合我们的数据:
*angle_variable = tf.Variable(40.0, name='angle_variable')
force_variable = tf.Variable(100.0, name='force_variable')
gravity_constant = tf.constant(9.8, name='gravity_constant')*
并将所有这些结合在一起(警告:这看起来会很乱,但这只是之前看到的用 TensorFlow 语法编写的数学方程):
*left_hand_side = x * tf.tan(deg2rad(angle_variable))
top = gravity_constant * x ** 2
bottom = (2*(force_variable)**2) *
(tf.cos(deg2rad(angle_variable))**2)output = left_hand_side - (top / bottom)*
然后告诉 TensorFlow 如何判断它在将轨迹函数拟合到我们的数据时是否做得很好:
*# the lower this score, the better
error_score = tf.losses.mean_squared_error(y, output)*
创建一个优化器,对变量(angle_variable 和 force_variable)进行实际调整,以降低 error_score:
*optimiser = tf.train.AdamOptimizer(learning_rate=5)
optimiser_op = optimiser.minimize(error_score)*
任务 5:魔法
我们现在可以运行优化任务来找到适合我的镜头的角度变量和力变量值。
*sess = tf.Session()
sess.run(tf.global_variables_initializer())# do 150 steps of optimisation
for i in range(150): sess.run([optimiser_op],
feed_dict={x: np.array(x_data).reshape(-1, 1),
y: np.array(y_data).reshape(-1, 1)})found_angle = sess.run(angle_constant.value())print(found_angle)*
TensorFlow finding the angle of my shot
在优化的最后,我们发现最符合我的拍摄数据的轨迹函数的角度约为 61 度…不知道如何处理这些信息…我想我可以看看专业拍摄角度是什么,以便进行比较…待续。
要吸取的教训:你总是可以用完全不必要(但有趣)的机器学习来分散注意力。
我使用的所有代码都可以在我的 Github 上找到:
用张量流和图像处理分析我的篮球技术。-ZackAkil/优化-篮球
github.com](https://github.com/ZackAkil/optimising-basketball)*
Tensorflow RMSD:使用 Tensorflow 做非设计用途的事情
职务由 马修·哈里根 。在GitHub上查看代码并报告问题。
深度学习彻底改变了图像和语音处理,让你可以把边缘变成猫。在我们的实验室里,我们将这些技术应用于小分子药物研发。
深度学习革命的一个副产品是产生了几个高质量的开源机器学习框架,可以计算任意操作的梯度。谷歌的 Tensorflow 可能是最知名的。我的研究专注于理解蛋白质和其他生物分子的大型分子动力学模拟的结果。你可以很容易地把预测小分子结合能想象成一个学习问题;除了艺术蛋白质图像之外,我们能否利用一些深度学习的进展来研究分子动力学?
生物物理学中的一个常见操作是用 RMSD 距离度量计算两种蛋白质姿态(构象)的相似性。这种度量因其平移和旋转不变性而受人喜爱。粗略地说,它覆盖了两个蛋白质结构,并报告了一个原子与其在另一个结构中的伙伴之间的平均距离。
RMSD 和旋转
满足平移对称性很容易:在进行比较之前,你只需将你的蛋白质集中在原点
*# traj = np.array(...) [shape (n_frames, n_atoms, 3)]*
traj -= np.mean(traj, axis=1, keepdims=True)
满足旋转对称更难。你需要找到每对构象之间的最佳旋转(最佳=最小化 RMSD)。早在 1976 年, Kabsch 发现可以对 3x3 (xyz)相关矩阵进行奇异值分解,从而找到最佳旋转矩阵。
*# x1 = np.array(...) [shape (n_atoms, 3)]*
correlation_matrix = np.dot(x1.T, x2)
V, S, W_tr = np.linalg.svd(correlation_matrix)
rotation = np.dot(V, W_tr)
x1_rot = np.dot(x1, rotation)
这并不理想,因为 SVD 可能会给你一个“旋转反转”,也就是 impropper 旋转,也就是旋转后再反转。我们必须明确检查并修复这种情况:
correlation_matrix = np.dot(x1.T, x2)
V, S, W_tr = np.linalg.svd(correlation_matrix)
is_reflection = (np.linalg.det(V) * np.linalg.det(W_tr)) < 0.0
**if** is_reflection:
V[:, -1] = -V[:, -1]
rotation = np.dot(V, W_tr)
x1_rot = np.dot(x1, rotation)
四元数拯救世界
1987 年, Horn 发现可以从相关矩阵的元素组合中构建一个 4x4 的“关键”矩阵。他从四元数数学中推导出这个矩阵(虽然关键矩阵是正规矩阵)。该矩阵的主特征值可用于“旋转校正”原子坐标之间的朴素平方差。
correlation_matrix = np.dot(x1.T, x2)
F = key_matrix(correlation_matrix)
vals, vecs = np.linalg.eigh(F)
max_val = vals[-1] *# numpy sorts ascending*
sd = np.sum(traj1 ** 2 + traj2 ** 2) - 2 * max_val
msd = sd / n_atoms
rmsd = np.sqrt(msd)
至关重要的是,您不需要显式构建旋转矩阵来查找 RMSD 值。如果你想要旋转,你可以从关键矩阵的主特征向量中重建它。
张量流可以做到这一点
我们把这个问题公式化为向量运算和一个自伴特征值问题。这些操作都是在 Tensorflow 中实现的!
**def** key_matrix(r):
*# @formatter:off*
**return** [
[r[0][0] + r[1][1] + r[2][2], r[1][2] - r[2][1], r[2][0] - r[0][2], r[0][1] - r[1][0]],
[r[1][2] - r[2][1], r[0][0] - r[1][1] - r[2][2], r[0][1] + r[1][0], r[0][2] + r[2][0]],
[r[2][0] - r[0][2], r[0][1] + r[1][0], -r[0][0] + r[1][1] - r[2][2], r[1][2] + r[2][1]],
[r[0][1] - r[1][0], r[0][2] + r[2][0], r[1][2] + r[2][1], -r[0][0] - r[1][1] + r[2][2]],
] **def** squared_deviation(frame, target):
R = tf.matmul(frame, target, transpose_a=True)
R_parts = [tf.unstack(t) **for** t **in** tf.unstack(R)]
F_parts = key_matrix(R_parts)
F = tf.stack(F_parts, name='F')
vals, vecs = tf.self_adjoint_eig(F, name='eig')
lmax = tf.unstack(vals)[-1] *# tensorflow sorts ascending*
sd = tf.reduce_sum(frame ** 2 + target ** 2) - 2 * lmax
好处是现在我们可以免费获得衍生品,所以我们可以做有趣的事情。作为一个玩具的例子,这表明找到一个“共识”结构,最小化平均 RMSD 分子动力学轨迹中的每一帧
这是用于执行优化的常规张量流代码。
target = tf.Variable(tf.truncated_normal((1, n_atoms, 3), stddev=0.3), name='target')
msd, rot = pairwise_msd(traj, target)
loss = tf.reduce_mean(msd, axis=0)optimizer = tf.train.AdamOptimizer(1e-3)
train = optimizer.minimize(loss)sess = tf.Session()
sess.run(tf.global_variables_initializer())
**for** step **in** range(2500):
sess.run(train)
Tensorflow 实际上不能很好地做到这一点
对每个数据点进行特征分解变得很昂贵,特别是因为我希望能够在大的轨迹和相当数量的目标结构之间进行成对®MSD 计算。 MDTraj 能够极快地执行大量的 RMSD 运算。它使用更好的策略从上面寻找 4x4 密钥矩阵的主要特征值。2005 年的西奥博尔德·QCP方法明确写出了密钥矩阵的特征多项式。我们利用相同结构存在一个界限的事实(®MSD = 0)来选择寻找主特征值的迭代牛顿法的起点。如果我们从这一点开始,我们保证特征多项式的第一个根将是最大的特征值。所以让我们用 Tensorflow 来编码吧!没那么快(字面上):你不能真的在 Tensorflow 中做迭代,如果你能,谁知道会有多高的性能。
自定义成对 MSD 运算
相反,我实现了一个自定义 tensor flow“op”。起初,我害怕构建和跟踪一个定制的 Tensorflow 安装。幸运的是,Tensorflow 将很乐意在运行时加载共享库来注册 op。更好的是,潘德集团的一位校友 Imran Haque 用 C 实现了一个我可以包装的快速®MSD 计算实现。
我实现了一个进行成对 MSD 计算的 Op,其中 double for loop 通过 OpenMP 实现了并行化。除了 Horn 方法的本机 tensorflow 实现的 10,000 倍加速之外,我们比 MDTraj 略快,尽管它使用了相同的实现。对于 MDTraj,轨迹上的循环是用 C 中的 OpenMP 来完成的,但是目标上的迭代必须用 Python 来完成,这带来了相关的开销。
我运行了一个基准测试,在 fs 肽轨迹之间执行成对 RMSD 计算。具体来说,介于 2800(步距= 100)帧和 28 个目标(步距= 100 * 100)之间。
实施……时间/毫秒 TF 原生操作…………22,843
MDTraj ……………….33.3
TF 自定义操作………….0.9
TF 自定义操作(带旋转)…1.6
渐变呢?
我们最初想用 Tensorflow 的原因是用自动微分做有趣的事情。天下没有免费的午餐,Tensorflow 不会自动区分我们的定制 Op。艾尔。指出 MSD 的导数仅仅是叠加的一对结构中的坐标之差。我们可以编码这个。
第一个问题是,我们现在需要明确的旋转矩阵,这样我们就可以用它来计算梯度。请记住,西奥博尔德提出了一个聪明的方法来寻找领先的特征值,但这只能给我们 RMSD 值,而不是实际的旋转(这需要特征向量)。幸运的是,在 2010 年,他扩展了该方法,使用主特征值来快速找到主特征向量。
我修改了pairwise_msd
op 以返回一个(n_frames,n_targets)成对 MSD 矩阵和(n _ frames,n_targets,3,3)旋转矩阵。用户永远不应该使用旋转矩阵进行进一步的计算,因为我没有实现输出的导数。相反,我将该输出用于 MSDs 的梯度计算。如果有人知道更好的方法,请告诉我。
在基准表中,这个版本的 Op 是“w/rot”变体,速度较慢(因为它必须做更多的工作)。
梯度代码的细节太多了
这段代码的大部分只是把张量做成正确的形状。我们需要将我们的 n_frames * n_targets 旋转矩阵分别应用于每个构象,我们需要在计算图中混合来自上一个 Op 的梯度grad
,因此我们将所有东西放大到秩 4 矩阵,并且显式平铺要旋转的构象,因为matmul
不做广播。
rots = op.outputs[1]
N1 = int(confs1.get_shape()[0])
N2 = int(confs2.get_shape()[0])*# expand from (n_frames, n_targets) to (n_frame, n_targets, 1, 1)*
grad = tf.expand_dims(tf.expand_dims(grad, axis=-1), axis=-1)*# expand from (n_frames OR n_targets, n_atoms, 3)*
*# to (n_frames OR 1, 1 OR n_targets, n_atoms, 3)*
expand_confs1 = tf.expand_dims(confs1, axis=1)
expand_confs2 = tf.expand_dims(confs2, axis=0)*# Explicitly tile conformations for matmul*
big_confs1 = tf.tile(expand_confs1, [1, N2, 1, 1])
big_confs2 = tf.tile(expand_confs2, [N1, 1, 1, 1])*# This is the gradient!*
dxy = expand_confs1 - tf.matmul(big_confs2, rots, transpose_b=True)
dyx = expand_confs2 - tf.matmul(big_confs1, rots, transpose_b=False)
梯度的实际形式有几个我们必须包括的因素:
n_atom = float(int(confs1.get_shape()[1]))
dxy = 2 * dxy / n_atom
dyx = 2 * dyx / n_atom
最后,我们对具有和其他构象的轴求和,以确保我们的梯度张量在形状上与它们的变量匹配。
dr_dc1 = tf.reduce_sum(grad * dxy, axis=1)
dr_dc2 = tf.reduce_sum(grad * dyx, axis=0)
在关注旋转之后,你忘记了平移对称性吗?我本来有!在各种输入上测试你的代码,包括非预先居中的轨迹:)。这部分就用 Tensorflow 的自动微分吧。
具体来说,我们设置了“forward”op 并在其上调用tf.gradients
。我们将梯度 w.r.t .旋转作为grad_ys
参数传递。耶连锁法则!
centered1 = confs1 - tf.reduce_mean(confs1, axis=1, keep_dims=True)
centered2 = confs2 - tf.reduce_mean(confs2, axis=1, keep_dims=True)
dc_dx1 = tf.gradients(centered1, [confs1], grad_ys=dr_dc1)[0]
dc_dx2 = tf.gradients(centered2, [confs2], grad_ys=dr_dc2)[0]
KMeans 启发的 RMSD 聚类
作为一个例子,我们可以用我们的快速成对 MSD 梯度运算,让我们找到“最佳”聚类中心(质心)。对于构象的轨迹,找到使每个点与其最近的质心之间的距离最小的中心。为了防止它两次找到同一个质心,我们添加了一个惩罚来强制质心分开。小心确保这个惩罚在某个点饱和,否则你的优化将会产生真正不同的质心,而不考虑簇间距离。
*# Out inputs*
n_clusters = 2
target = tf.Variable(tf.truncated_normal((n_clusters, traj.xyz.shape[1], 3), stddev=0.3))*# Set up the compute graph*
msd, rot = rmsd_op.pairwise_msd(traj.xyz, target)
nearest_cluster = msd * tf.nn.softmax(-msd)
cluster_dist = tf.reduce_mean(nearest_cluster, axis=(0, 1))
cluster_diff, _ = rmsd_op.pairwise_msd(target, target)
cluster_diff = cluster_diff[0, 1]
loss = cluster_dist - tf.tanh(cluster_diff*10)*# Train it in the normal way*
optimizer = tf.train.AdamOptimizer(5e-3)
train = optimizer.minimize(loss)sess = tf.Session()
sess.run(tf.global_variables_initializer())
**for** step **in** range(1000):
sess.run(train)
现在你可以在这个漂亮的地方做 tICA 或者做一个 MSM 。
代码可用性
所有代码都可以在 Github 上获得。请务必查看自述文件中的安装说明,因为定制 Op 需要一个有效的 c++编译器。一致性示例、聚类示例和分析脚本位于示例文件夹中,需要 fs 肽数据集。
本机 tensorflow 实现位于 rmsd.py 中。自定义 Op 的底层代码位于 rmsd/ 子文件夹中,具体来说就是 rmsd.cpp 。最后, rmsd_op.py 包含一个方便的函数,用于加载注册 op 的共享对象。
TensorFlow 服务客户。让它更瘦更快!
TensorFlow Serving 提供了一种在生产中部署和服务模型的简洁方式。我之前已经描述过部署过程这里。不幸的是,有两个问题我很久以后才注意到,感谢宝贵的评论。首先,单次预测花费太多时间。第二,实际上,没有必要在客户端使用 TensorFlow。
瓶颈是对 TensorFlow 的调用,它创建了一个张量 protobuf(完整的代码可以在这里找到):
tf.contrib.util.make_tensor_proto(data, shape=[1])
所有其他事情都不依赖于 TensorFlow,仅仅需要从 protobufs 生成 Python 文件。
解决方案
我介绍了一个专门针对图像预测的解决方案,而不改变原始的 protobufs。我发现了一篇很棒的博文,作者走得更远,复制并修改了原始的 protobufs。这允许将代码减少到最少,如果我只需要预测的话,我肯定会这么做。
从 protobufs 生成 Python 代码
我们必须创建一个在 TensorFlow protobuf 文件中描述的具有特定类型和形状的 TensorProto 对象。我们可以按原样使用我们的图像数据数组。
更具体地说,这意味着我们必须从 TensorFlow 核心 protobufs 生成 Python 文件,并直接使用它们,而不是任何包装器。我已经生成了它们,并放入我的库这里。如果您愿意,您可以自己动手(假设您克隆了示例项目):
# 1
cd <tensorflow serving source folder># 2
python -m grpc.tools.protoc ./tensorflow/tensorflow/core/framework/*.proto --python_out=<path to the project> --grpc_python_out=<path to the project> --proto_path=.# 3
python -m grpc.tools.protoc ./tensorflow/tensorflow/core/example/*.proto --python_out=<path to the project> --grpc_python_out=<path to the project> --proto_path=.# 4
python -m grpc.tools.protoc ./tensorflow/tensorflow/core/protobuf/*.proto --python_out=<path to the project> --grpc_python_out=<path to the project> --proto_path=.
不幸的是,由于依赖关系,您需要所有这些,或者您必须调整 protobufs 以满足您的需要,并消除不需要的依赖关系。
替换张量流代码
现在我们可以替换一个“标准的”张量原型创造
tf.contrib.util.make_tensor_proto(data, shape=[1])
包含以下内容:
dims = [tensor_shape_pb2.TensorShapeProto.Dim(size=1)]
tensor_shape_proto = tensor_shape_pb2.TensorShapeProto(dim=dims)
tensor_proto = tensor_pb2.TensorProto(
dtype=types_pb2.DT_STRING,
tensor_shape=tensor_shape_proto,
string_val=[data])
这是怎么回事?首先,我们创建一个与我们的数据相匹配的 dimension 对象——我们只有一个图像要预测。接下来,我们使用创建的维度对象初始化适当的张量形状。最后,我们用张量形状和我们的数据创建所需的类型为 string 的张量 protobuf。我们必须将数据放入字符串值中,因为我们有一个字符串的张量。你可以在生成的tensor flow/core/framework/types _ Pb2 . py文件中找到其他可用的类型。
现在,我们可以将张量 protobuf 设置为请求输入:
request.inputs['images'].CopyFrom(tensor_proto)
你可以在这里找到完整的代码。
表演
你也可以显著提高表现。如果您喜欢在客户端继续使用 TensorFlow 框架,请进行以下更改:在开始时导入 make_tensor_proto ,稍后调用它。
...
from tensorflow.contrib.util import make_tensor_proto
...request.inputs['images'].CopyFrom(make_tensor_proto(data, shape=[1]))
如果您不再在客户端使用 TensorFlow,性能会自动提高。在我的系统上,现在单个图像预测需要 3 毫秒,而不是 300 毫秒。
摘要
TensorFlow 服务客户端不需要 TensorFlow 框架来发出请求。您唯一需要做的就是正确初始化发送给服务器的 gRPC 请求。您可以使用原始 TensorFlow Core protobufs 和以下 Python 文件并创建适当的 tensor protobuf 对象来实现这一点。如果您希望客户端中的 TensorFlow 尽可能少,您需要调整原始 protobufs 以满足您的特定需求。
TensorFlow 语音识别挑战—解决方案概述
Telegraph network equipment — we’ve come a long way (source)
不久前,我参加了由 Kaggle 和 Google Brain 组织的关键字检测挑战赛。问题是,我们如何在像 siri 或 alexa 这样的语音界面中提高关键词检测准确率,比如当你说“打电话给 Brad”时。
Tensorflow 团队已经分享了一个完成这项工作的基线系统的完整 receipe ,但目标是看看社区能提出什么。最后,获胜的团队与谷歌的基线差距相当大;竞争测试集上约 80%对约 70%的准确度范围。
我设法独自达到 88%,在与 Russ 和其他人合作后,我们以 90%的分数排在第 6 位。在这里,我主要概述了我的部分解决方案。
我的代码转储可以在这里(警告:非常混乱)
设置
dev 集包含 64k 的音频文件,每个大约 1 秒。我们也给了每个样本的标签,也就是说,在那一秒钟里说了什么。总共有 31 个标签,但在这场比赛中,我们只对 12 个标签感兴趣:“是”、“否”、“上”、“下”、“左”、“右”、“开”、“关”、“停止”、“开始”、“沉默”和“未知”。未知标签基本上是除了其他 11 个以外的任何东西,而沉默标签是一个代理标签,用于指示何时没有语音。评价是从准确性来说的。
你可以在竞赛页面这里找到更多细节。关于标签分发、音频样本的温和介绍,以及关于声音和特征提取的足够理论,请查看此 EDA 。
数据预处理
似乎有一些关于原始波数据的训练模型的工作,但标准做法是首先从原始音频中提取频谱图或 MFCC (Mel 频率倒谱系数)。你可以很容易地用 Librosa 得到这些。以下是“是”的声谱图:
Spectrogram for “yes”
您可以将自然声波分解为不同频率的组成波(~傅立叶变换)。这基本上是声谱图告诉我们的:在每个时间点,每个频率的强度是多少。
所有音频文件都有 16k 采样率,这意味着它们可以捕捉高达 8k Hz 的声音频率(见 y 轴)。Mel 是放置特定频率范围的容器,使用较高数量的 Mel 会产生更精细的频谱图。我用 128 和 256 为不同的模型在这个比较粗糙。x 轴与时间相关,给定样本的 x 轴长度取决于用于计算频谱图的几个参数,如跳跃长度。
MFCCs 是对频谱图的另一种转换,旨在更好地捕捉人类语音的特征(例如,与音乐相比)。在 MFCC 的基础上,还有德尔塔和德尔塔-德尔塔变换,你可能会认为它们是一阶和二阶导数。这是同一个样本的 MFCC 的样子:
MFCC for “yes”
MFCCs 是 Kaldi 等流行的语音识别框架中的标准特征表示。我确实尝试了它们,但是由于我在准确性上没有太大的差异,并且我认为光谱图保存了更多的数据,所以我最后没有使用 MFCCs。
回到 spectrograms,最后你会得到一个形状类似(32,128)的 numpy 数组——把它想象成(time,frequency)——它告诉你一个给定时间戳的某个频率有多强。从这里开始,你基本上可以把声音文件当作图像来处理,并且可以疯狂地使用任何基于卷积的模型,比如 vgg,resnet 等等。最重要的是,你要利用数据的顺序性,这样递归神经网络就能派上用场。
在语音识别中,数据扩充有助于概括模型,并使它们对速度、音量、音调或背景噪声的变化具有鲁棒性。我自己实现了增强,以便完全理解和控制发生的事情(而不是使用 tensorflow 实现)。Pydub 对这部分来说真的很方便;例如,它允许你通过写wav += 5
来增加一个波形文件的音量 5 分贝,其中wav
是一个 pydub AudioSegment
对象。
为了创建“沉默”标签的样本,我从数据集附带的噪声样本中提取了一秒钟的部分。
一开始,我在训练期间进行了数据增强,但我发现我的 gpu 没有得到充分利用,数据增强本身就是瓶颈。然后,我决定预计算 4x 批扩充,并将它们与原始数据一起保存为一个大的 pickle 文件。我把所有东西都加载到内存中进行训练,这给了我快速尝试不同架构的巨大优势;这也将使结果具有可比性,因为所有模型都将使用相同的数据进行训练。
Tensorflow 团队似乎正在开发一个简单的 api 来简化和优化培训前的 etl,我很想尽快尝试一下。
我使用 tensorflow 实现中默认的 90%-10%分割进行训练验证;你可能会认为 k 倍 cv 在准确性/过度拟合方面会更好,但我更喜欢简单的分割来快速尝试不同的架构并调整它们的超参数。
你可以在 utils.py 和 etl*下找到我的 etl 脚本。ipynb(抱歉代码乱七八糟)。
Theodore meets Samantha
模型
像所有其他比赛一样,这个想法是集合一些不同的模型,这些模型在架构、数据扩充、特征提取等方面有所不同。在这里,我列出了我使用的一些基本模型变体,它们都是深度神经网络。我考虑过使用 Kaldi,但因为我认为优化语言模型和沉默概率可能会很棘手,所以我像其他人一样利用了深度 NN 波。
1D CNN
这是我见过的最高效和轻量级的模型,精确度在 85-87%之间。它可能是最好的单个模型,几乎不需要调整就可以在生产中使用。
在二维数据(光谱图)上使用“一维”滤波器可能听起来有点混乱,但基本上你有很大的二维滤波器,你只能在一维上卷积。例如,输入形状为(t,f)
并经过频域,滤波器将具有形状(k,t)
,其中k
是滤波器宽度。在这种情况下,点积将具有形状(1,f)
(假设padding=”same"
)。更多可视化解释在这里。
你可以借用流行的图像处理模型的基本概念,只需调整它们来使用 1d 而不是 2d 卷积。例如,带有 keras 的 vgg 灵感模型看起来像:
然后将这些层附着到一个 dense 和 softmax 头上,并使用categorical_crossentropy
损耗进行训练。我在中间层尝试了很多调整,比如添加扩展、跳过连接或末尾的 LSTMs,以利用数据的顺序性质。
我发现一个简单的不太深的模型,在开始时具有大的内核大小,在频域上工作得很好(大约 86%的准确度)。将它与时间域上的 1d 转换以及每种转换的一些变化组合在一起,使我达到 87%。
2D CNN
在这里,您可以将声谱图视为单通道图像,并原样应用著名的图像模型架构。不过,我最初尝试 ResNet 时运气不佳。我意识到太深或太宽实际上会损害准确性,我猜这是因为太多的信息在 maxpool 层中丢失了。因为我的队友已经有了这种型号,所以我没有在这里花太多时间来获得更好的结果。对于像 InceptionResNetV2 这样的单一模型,他们报告的准确率为 88%。
我没有双倍下注 2d 模型的另一个原因是我缺乏硬件能力。我当时使用的是 aws p2/g3 实例,即使对所有增强进行了预编码并将其加载到内存中,训练时间也比我尝试不同架构/超级参数的耐心和意愿要长得多。当我听到新的 aws p3 实例发布时,我非常激动。同样值得注意的是 tensorflow 最近的分布式培训支持。TF 在易用性方面做了一些很好的改进,我很高兴能尽快尝试新的 API。
CNN-RNN 组合
其思想是使用 convnet 提取特征,展平非时间维度,然后使用 RNN 来利用数据的顺序性质。我在这里遇到了这个想法,Hray 使用这种技术来正确识别口语。
keras 中的一个实现如下所示:
我们必须非常小心最大池层,以免删除太多信息,特别是在时域上,因为它很短(1 秒)。我还发现了 CuDNNLSTM 实现,它是 Cuda 上的一个优化的 LSTM 实现;这确实有很大的不同,API 几乎与默认的 LSTM 实现相同。强烈推荐!
仅用这个模型就让我达到了 88%的准确率。将它与 1d convs 组合在一起,使我在黄金领域的公共排行榜(lb)上多了几个名次(仍然在 88%的准确率范围内,lb 只显示了 2 个小数点)。
值得注意的是,2d conv 层不是很深,可能通过尝试其他替代方法可以获得更多的多样性。使用 1d 转换器不会产生同样多的增益。堆叠循环层没有帮助。
Terminator impersonates John — machine to machine Turing test passed!
我尝试过的其他事情
以下是我尝试过的其他一些事情:
扬声器嵌入
在 Kaldi 的许多方法中,当训练声学模型时,说话人嵌入(I 向量)与原始特征(例如 MFCCs)一起使用。根据我看到的一些出版物,它有助于提高单词错误率,并且默认包含在内。本次比赛的数据集带有说话人标签,因此我认为这可能有助于训练独立的说话人识别模型,并在训练主要关键词检测模型时使用其瓶颈特征(嵌入)作为附加输入。
三连音缺失的一击训练在这里是个不错的选择。网络(一堆 1d 转换器)取 3 个样本,2 个来自同一说话者,1 个来自其他人。然后,三元组损失函数推动网络,如果样本来自同一说话人,则使距离最小化,否则使距离最大化。这里有一个片段可以让它更清楚:
这些模型似乎很好地收敛了,但是在训练主模型时将嵌入作为附加特征对准确性没有帮助。我还尝试了多任务学习说话者 id 和标签,但仍然没有改变主要任务的准确性。
我还没有找到一个好的解释,但假设我做得正确,这个观察暗示说话者嵌入对转录有帮助,但对关键字检测没那么大帮助。
自动编码器
在比赛的早期,我非常希望自动编码器的瓶颈特性可以包含一些额外的信号。我们可以认为瓶颈值是指同一类别中的指纹和样本最终具有相似的值。此外,因为我们已经在 dev+测试集上训练了 autoencoder,所以关键字检测模型可以在测试时比较这些指纹,可能会产生更多的 robus 预测。
我用一个简单的不太深的 2d cnn 编码器-解码器架构实现了这一点,该架构具有不同的瓶颈形状,例如 128。它给了我早期的 1d conv 合奏 0.01 的提升,我们在最终的 lightgbm stacker 中使用了它。这里肯定会有更多收获,我非常确定我的自动编码器架构可以改进——特别是在阅读了像 wavenet autoencoder 这样的相关工作之后。这部分训练起来也非常慢,我采取了我能想到的最简单的方法;例如,用简单的上采样层替换去卷积层。
伪标签
这个想法是使用你目前为止最好的模型预测测试样本的标签,然后使用测试数据和你预测的标签重新训练/微调你的模型。在“硬”版本中,您获取 softmax 预测的 argmax 并将其用作标签(当您的模型对预测足够有信心时,您可以更有选择性地这样做)。在“软”版本中,您直接使用预测的软最大概率作为标签,因此某个测试样本可能有 50%“开”,30%“关”,20%是其他标签的组合。我认为,软版本通过将标签之间的关系编码到分配给模型学习的概率中,进入了知识提炼的领域。我在以前的作品中看到了这种方法的改进,认为它在这里也会有所帮助。
在我的早期试验中,我在本地验证集上获得了显著的准确性提升,但在公共 LB 上没有。似乎简单地预测测试标签并使用它们进行训练变得太“天真”了,你必须做更多的工程工作来找到硬案例,并强行让你的模型专门学习这些。我的团队在这里做了一些有趣的把戏,比如针对某些标签出现错误,并试图在测试集中隔离那些困难的案例或合成新的样本。例如,我们意识到相当多的无声样本被错误地归类为其他东西,因为在音频的结尾有一个明显但无意义的元音。为了应对这一点,Bob 创建了一组新的训练样本,通过将正常样本偏移 0.9 秒来模拟这些拐角情况。
这里的尝试都没有反映公共/私有 lb 的大变化,但是也很难忽略它们的有效性,因为测试集的子集被用于评估。此外,你可能会觉得自己在最后做了相当多的修补,但顶级团队之间的差异在于正确地多分类几个词,你宁愿尽可能多地从数据中挤出来。
未知的未知物
在竞赛的早期,很明显一个主要的挑战是预测“未知”标签。dev 集合包含来自 21 个不同标签(“猫”、“希拉”、“等等”)的 42k 个样本,这些样本应被视为未知。然而,在实践中,字面上任何东西都可以代替主要关键字,它们都应该被视为未知。因此,重要的是要找到方法使我们的模型对测试集中看不见的未知内容具有鲁棒性,或者对未知内容具有更好的韵律:)
我尝试过通过反转来增加训练数据,所以当有人说“停止”时,它实际上被视为“停止”,但它的反向口语“pots”是一个“未知”样本。没用。我们也做了一些试验,通过剪切和拼贴已知类别的部分音频来合成新的未知样本;这对我们没用,但显然其他球队运气不错——细节决定成败。
我们还尝试了其他一些事情:
- 有额外的模型头来预测音素/辅音,并与主要任务一起学习
- 为每一个可能的 31(默认为 10 +任何进入未知类的事物)训练隔离森林,并使用它们的异常值分数来识别测试样本以包括未知的未知物(这也算作伪标记)
这里所有个人的努力得分在 88%左右,但我要说,他们帮助我们最终的合奏增加了多样性。
组装
最后我们得到的是不同模型/集合的简单加权平均值。我特别喜欢 Bob 如何使用层次聚类来挖掘模型相关性:
这个想法基本上是将所有的类预测展平到一维数组中,然后将它们视为模型的单个指纹。然后,您可以使用这些指纹来计算模型相关性。分层聚类视图有助于识别模型之间的差异,并选择正确的模型/权重。此外,如果你的预测中有一些异常情况没有在公共 lb 中捕捉到(就像之前我在《星球大战》中遇到的情况),你可以马上发现它们。
我们还尝试用 lightgbm stacker 集成我们的最佳集成,该集成对所有实验预测都有效(自动编码器、未知-未知模型、伪标记模型的输出),它在公共 lb 上产生轻微的改进,而私有 lb 分数保持不变。
结论
像迄今为止的所有比赛一样,一路上有很多学习点和挑战,所以感谢 kaggle 和 google brain 的组织。有趣的是,人们在图像处理等其他领域学到的许多技术也可以在这里应用。虽然很有帮助,但是你不需要成为一个语言科学家就有机会在这里竞争。
我还要感谢我的优秀团队,感谢他们分享的所有知识和技巧——和合适的团队在一起真的会让学习经历和动力更上一层楼。其他获奖团队也在论坛上分享了他们的解决方案,请务必查看以获取更多灵感。
我发现传统的语音识别(如 Kaldi)在设置、训练和运行方面非常复杂,所以亲眼看到一种“端到端”的完全基于神经网络的方法可以给出下降的结果是非常令人耳目一新的。这让我对这个领域的所有相关工作寄予厚望,比如 Mozilla DeepSpeech。我特别喜欢百度的愿景,一个高度简化的语音识别管道应该使语音识别研究民主化,就像 CNN 彻底改变了计算机视觉一样,而且我们理想中希望语音识别系统可以由一个在语音识别方面几乎没有经验的团队来构建、调试和改进。
话虽如此,我还是很想看看基于 Kaldi 的 receipe 在这个数据集和任务上表现如何。这可能是我接下来要尝试的东西。
我们在促进沟通方面取得了长足的进步;这些进步在我们自身发展的时间线上是指数级的,从智人的黎明开始。首先,我们消除了距离的障碍,现在我们甚至将交谈(和思考)委托给机器。在这样一个世界里,只要机器能相互交流就够了,我们的口语可能会成为交流的瓶颈,而不是促进者。
— Mic Drop —
特斯拉:股价预测
快速提示:我不会预测特斯拉的股价。但我会努力的。
我着手解决这个特殊的问题有两个原因。第一,在尝试学习如何使用 ARIMA 模型和处理时间序列数据时,头脑中要有一些目标。第二是变得肮脏,发臭的富有。第一个目标似乎很成功,这也是我们在这篇文章中要关注的。第二…你很幸运,我不会失去继续写作的动力!
我的计划是创建一个 ARIMA 模型,跟踪足够接近 TSLA 每天的收盘价,然后将其输入第二个模型,该模型结合了自然语言处理,特别是对埃隆·马斯克的推文(他在 ole Twitter 上相当多产),以及其他新闻来源。据我所知,由于特斯拉股票的价格完全是投机性的,它应该基于新闻(特斯拉从未有过盈利的一年,只有几个盈利的季度)。数据科学的伟大之处在于,如果你有一个像这样的随机假设,测试它是相当容易的。
“当某件事足够重要时,即使形势对你不利,你也要去做。”
― 埃隆·马斯克
TSLA stock price since 2010
正如你从上面看到的,Telsa 自 2013 年初以来一直在上升,这恰好是在他们的第一辆汽车发布后不久。2017 年 1 月,我买了几只股票(实际上是 3 只),获得了 50%的回报。不幸的是,我不知道是应该卖掉还是继续持有。我希望有个模型能帮我避免这种忽上忽下的废话。
好吧,什么是时间序列问题?时间序列问题是指任何给定的观察值都依赖于之前的观察值。如果你想象购买食品杂货,这是很容易想到的。如果你走进商店,发现奶酪比你上次买的时候多了 5 美元,你可能不会觉得这很合理。当然,如果价格几个月来一直在逐渐上涨,你可能会发现它的新价格是合理的(如果令人讨厌的话)。外部因素也可能起作用,但对于普通买家来说,他们的购买决定主要来自之前的价格。这不仅仅是最近的几个价格。如果我们谈论购买草莓,我们可以说价格遵循一个基于历史价格的模式。如果草莓当季上市,我们预计价格会下降,然后随着季节的结束而上涨,草莓会变得更加稀少。今天的价格可能比昨天更取决于 365 天前的价格。我的朋友本发了一个极好的帖子在这里打破这些组件。
正如你可能已经猜到的,股票价格中有很强的时间序列成分。我心目中的 ARIMA 模型结合了时间序列的两个特征。AR 代表第一部分,考察价格的“自回归”程度,MA 代表第二部分,考虑移动平均价格的影响。(I 代表集成。)自回归分析了今天的价格与各个先前价格的相关性,并描述了这种关系。我们可以画出前一天对当天的影响有多大。
This shows the correlation between the current price and each previous price up to 365 days
上图显示了这种相关性;随着滞后天数的增加,相关性稳步下降。这告诉我们,最重要的相关性是当前价格之前的价格。如果我们看到其他峰值,这将是一个很好的指标,表明存在其他相关性(例如每周、每季度或每年)。我们也可以查看不同滞后的部分自相关,看看是否有额外的相关性需要考虑。
This maps the partial autocorrelation in closing price over the same time period as above
部分自相关查看与上述相同的关系,但删除了以前的关系。换句话说,在滞后 7 时,它查看 7 个观察值之前(7 天前与我们的收盘价数据)的关系,同时消除滞后 1 到 6 的影响。这可以显示季节关系,就像我们在之前的草莓例子中发现的那样。这些图表读起来可能有点棘手,但上面的图表没有直接明显的关系,显示的主要是噪音。
这涵盖了 ARIMA 模型的自回归性质,但移动平均部分呢?要发现隐藏在数据中的东西可能有点困难,但我们可以把它看作是对数据变化的平滑,以消除噪声和随机变化。
Comparing different rolling means to over six months
你可以在上面看到,特斯拉股价的滚动平均值淡化了通常代表噪音和其他波动的急剧变化。这可以帮助您的模型变得更具预测弹性,而不是完全依赖于自回归。你需要你的模型有多大的反应能力可以帮助你决定最有意义的滚动平均值的时间段。您可以看到,随着用于计算滚动平均值的天数的增加,模型响应变化的时间也变长了。
最后一个要考虑的因素是“平稳性”的概念。简而言之,如果均值和方差在一段时间内相同,则数据是稳定的。这通常是适当的统计分析的要求。正如我们之前看到的,特斯拉的股票价格随着时间的推移一直在上涨,特别是自 2013 年以来,因此不是静止的。有各种方法可以转换数据并使其稳定,这将允许我们建模和进行预测。我们主要是找出数据中的趋势和任何季节性,从建模的数据中删除这些方面,进行预测,然后将趋势和季节性添加回预测结果中。
We can see our observed stock prices on top, the overall trend in the price second, any yearly repetition third, and finally our residual which is whatever variation is still left over and needs explaining
这里是一个尝试,看看任何季节趋势超过一年,任何趋势超过股票的生命。下面的三个图代表寿命趋势、年度变化和残差,它们加在一起就形成了上面的观察图!底部的残差是所有剩下要预测的,我们希望它尽可能的稳定。我还研究了所谓的第一个差异(采用当前价格并减去之前的价格),并进行了一项名为 Dickey-Fuller 测试的测试,该测试本身可能值得发表一篇文章,以观察这是否有助于我们达到平稳性,它确实做到了。
结合所有这些因素,我们可以根据我们的数据得出训练 ARIMA 模型所需的参数。我们将希望在我们的数据子集上训练模型,例如直到 2017 年的所有数据,然后在 2017 年测试模型。
Not too shabby, yea?
哒哒!这里有一个非常简单的例子,说明如何用 Python 和这里的数据创建这个模型。
30 行代码,一半是我在唠叨,四分之一只是在读数据?说到站在巨人的肩膀上…
我希望这有助于您理解时间序列建模的基础,何时使用它,如何为您的模型确定参数,以及如何实现模型本身。这只是触及了表面;接下来,我们需要弄清楚如何评估我们的模型,看看它是否能让我们变得富有!
一如既往,感谢阅读。如果你注意到任何错误或者认为我可以澄清任何事情,请让我知道。如果你想知道更多关于我如何开始评估这个模型和内置自然语言组件的信息,请告诉我!你可以在这里找到我剩余的代码。
考验我
从大会的数据科学沉浸式课程毕业后,我很自豪地宣布,我开始了一个新的职位,作为洛杉矶市市长预算和创新办公室的数据科学家。我上任几个星期了,我专注于使用数据驱动分析来改善洛杉矶的城市服务。我在洛杉矶长大,我想念 DC,但回家的感觉真好。
我花了一些时间来反思我的求职。面试很难做对,因为它们总是一种平衡的行为。你想看起来:
- 自信,但不自大
- 你会适应,但不太舒服
- 你知道你的东西,但不是无所不知
我倾向于面试过程中的测试部分,因为我认为这是我在这个职位上表现得更客观的部分。我也发现测试部分有点有趣——就像解决一个难题。不过,在我的调查中,许多组织都有非常基本的测试,会问一些编程问题,比如:
- 编写一个函数,列出一个目录及其子目录中的所有文件,并打印每个文件的倒数第二行。
- 写一个函数来计算一个字符串中的总字数。
- 编写一个 bash 脚本 reverse.sh,它接受任意数量的参数并反向打印它们。
有这些测试总比没有测试好,但是有一些方法可以更全面地考察候选人在一个职位上的表现。下面是我为三个不同的组织所做的测试的回顾,我认为这些测试比正常的编程问题列表高了一步。
- 市长预算和创新办公室**——**不是过分奉承我的新雇主,但我真的很喜欢市长办公室的测试。我必须为技术考试做两次报告。一份是对面试官给我的数据集的分析,另一份是对我自己选择的数据集的分析。我有一个周末的时间来准备我的报告。虽然工作量很大,但这给了我一个展示自己能力的机会。我决定为其中一个数据集创建一个预测模型,表明我可以成为一名定量分析师。另一方面,我创造了一些可视化的画面。演示本身让我展示了我的沟通技巧,我把我的工作发布在 GitHub 上,以防面试官想要审查我的代码。
- NGP-范**——**我已经使用这家政治科技公司的客户关系管理大约六年了,我认为在那里工作会是一个很好的机会。测试的场景是,一个客户给了我一封电子邮件,要求我为她将数据加载到 CRM 中。该测试不仅询问我将采取什么步骤通过 SQL 加载数据,还询问我将如何回复客户的电子邮件。我觉得这不仅考验了我的硬技能,也考验了我管理客户期望的软技能。
- nation builder**——**另一家总部位于洛杉矶的政治科技公司。他们的测试还要求我将数据加载到他们的 CRM 中。但是在这次考试中,他们给了我一个虚拟的环境来加载数据。这给了我一个机会,不仅可以展示我有能力做好这项工作,还可以更多地了解公司的软件。
测试不仅仅是看申请人是否知道如何编码,还包括他们是否能实际执行。评估也是双向的。如果一个组织有一个更全面的测试,那么我知道这个组织可能会引进我想与之共事的其他人才。
测试集使用
对一个 7 98 的输入,输出 1 98 的数据进行 K 重交叉验证后,如何选择数据进行训练和测试?
测试集通常用于计算模型的健壮性。理想情况下,直到最后,您都不应该查看测试集的性能。否则,你可能会在现有的数据上过度拟合你的模型。
所以回答你的问题,如果我有数据和 5 个不同的模型要测试,我首先会随机分离出大概 10 %的数据,称之为测试集。不到最后一步,我不会看这些数据。
对于剩余的数据,我现在需要找出哪种模型效果最好。我不会在数据上训练 5 个模型,每次我都会使用 k 折叠交叉验证来获得我的模型在数据上表现如何的样本。接下来,我将找出所有这些模型的平均误差,并在前两个模型之间进行假设检验,对多个假设检验进行校正,看看最佳模型实际上是否是最佳的。
一旦我选择了我的模型,我将在完整的训练数据上训练它,并在测试集上测试它。如果我没有在训练数据上过度拟合,在测试集上的表现就足够好了。这是我使用测试集的唯一原因。为我的模型做最后的调试。
一旦我确信我的模型没有 bug,我就会用所有的数据对它进行训练,并将其部署到生产中。
用 NLTK 试水
“你好,Word!”
init(自己,博客):
计算机是如何理解人类语言的?
自从我兴高采烈地故意让苹果、亚马逊和完全不知情的脸书通过 Siri、Alexa 和 Facebook 应用程序监听我个人生活的对话片段以来,我一直(相当平静地)想知道计算机实际上是如何处理人类语言的。这种好奇心从来没有强大到足以让我付诸行动。直到我开始在熨斗学校接受数据科学家的培训。数据科学训练营开始几周后,我发现从哪里开始回答这个问题。三个字的答案是,自然语言处理(NLP)。你瞧,那种古老的好奇心重新燃起,我决定以一个新手的身份写我的第一篇博客。
NLP 是计算机科学的一个发展领域,涉及计算机和人类的交互。这个博客是我第一次涉足自然语言处理领域。在开始任何复杂的分析之前,我将探索开始的文本预处理。我将使用一个流行的名为 NLTK 的 NLP 库。自然语言工具包(NLTK)是当今最强大的,也可能是最流行的自然语言处理库之一。它不仅拥有最全面的基于 python 的编程库,而且还支持最多的不同人类语言。
在开始之前,我不可避免地要简要回顾一下 NLP 的历史。
免责声明:在下面的部分,我将通过一个非常“相关”的奇幻小说角色的模因来“创造性地”进行类比,从而讨论 NLP 的发展。非常欢迎您跳过这一部分,继续学习 NLTK 部分。
自然语言处理的发展
自然语言是我们人类用来相互交流的语言。这就引出了一个问题(至少在我看来)那么,有没有一种非自然的语言?答案是一个响亮的是,它是,计算机语言,或者更确切地说,计算机如何与人类互动。外行人对自然语言处理的描述是:这是一个通过计算机破译自然语言的科学领域。根据 Wikipedia,NLP 通常包括三个主要子领域,简要描述如下:
语音识别:口语单词的识别和转换到转换。例子:Siri,Alexa。
自然语言解释:理解自然语言并以此为基础做出决策。示例:将电子邮件分类为垃圾邮件。
自然语言生成:自然语言产生。示例:创建数据库或数据集的摘要。
在基本水平上,计算机知道如何将字母转换成二进制数、1 和 0。例如,下面左边的图像实际上是短语“Hello,World!”的二进制表示。计算机将我们的语言翻译成二进制代码序列,再转化成可操作的指令。这让我想到了我的“非常有创意”的类比,右边的第二张图片。
可以说,一个人(可能只有我)会发现二进制语言与广受欢迎的小说《权力的游戏》中深受喜爱的助手阿多(大多是哑巴)的交流方式非常相似。阿多只会说一个词,他的名字。他通过重复阿多来交流。或者他保持沉默。阿多。沉默。阿多。阿多。一个。零。一个。一个。明白了吗?所以,有人会说,阿多是二进制的完美代表!
既然我已经说清楚了,让我们稍微回顾一下。在这个万物快速发展的时代,与人类第一次在地球上行走的时间相比,我们很少能体会到计算机自发明以来在极短的时间内已经进化了多少。为了理解 NLP 发展的速度和规模,考虑一下这个。早期的程序员(只有 70 年前!)使用穿孔卡(如下图)与计算机对话。几行代码通常需要成堆成堆的穿孔卡片。
Punch Cards
今天,我们可以毫不费力地与机器对话,甚至不需要思考就可以对 Siri 不听我们的口音感到恼火!
那么我们是如何从这个,
对这个?
嗯,我们已经开发并继续开发一种更好的方法,通过更复杂的编程库与计算机对话。这是第二个“创造性”的类比。
像 NLTK 这样的库基本上是现代计算机的品牌(最后一个,我保证。).通过内置的预写代码,这些库可以在后台执行复杂的文本处理,而其用户只需担心知道哪个方法完成了什么。这些库只需要几行代码就可以实现文本理解、解释和情感分析。下面的段落恰当地总结了 NLP 在当今环境中的重要性。
“今天的机器可以比人类分析更多基于语言的数据,不会疲劳,并且以一致、公正的方式进行分析。考虑到每天生成的非结构化数据数量惊人,从医疗记录到社交媒体,自动化对于高效地全面分析文本和语音数据至关重要。”
下一部分是真正的工作开始的地方!
预处理
那么如何开始呢?如果你仔细想想,这是很直观的。想想婴儿是如何学习理解语言的。
逐字逐句。
为了能够理解一个整体,我们首先需要能够在元素层面上破译一些东西。如果不知道每个点代表什么,你就不能把这些点联系起来。自然语言处理的第一步包括将语言分解成单词/句子,也就是记号,然后尝试绘制这些记号之间的动态关系以及它们如何形成意义。
值得注意的是,NLP 中 99%的工作是预处理和组织数据,其中涉及 分词和解析、词条化/词干化、词性标注、语言检测和语义关系识别 。只有完成这些任务后,你才能开始分析数据。NLTK 让这 99%变得容易多了。
在我第一次尝试使用 NLTK 进行 NLP 时,我选择处理现任总统唐纳德·特朗普的演讲。我找到了一个 2016 年至 2017 年特朗普演讲的 GitHub 知识库。其中总共有 73 篇文本文件形式的发言。我随机选择了一个演讲作为开始,并使用了 NLTK 的以下方法来探索这个演讲。
a)标记化,c)去除停用词,b)词性标注,c)索引
符号化
任何 NLP 项目的第一个任务都是标记化。就是把一个巨大的字符串拆分的过程(我的原始数据为。txt 文件)转换成单词或句子的列表。通常,字符串首先被标记为句子列表,然后是每个句子的单词列表。感觉很直观。
An example of Tokenizing:
[‘Hello World! I am learning to use NLTK.’]Step 1: Sentence tokenizing:[‘Hello World!’, ‘I am learning to use NLTK.’]Step 2: Word tokenizing:[ [ ‘Hello’, ‘World’, ‘!’ ], [ ‘I’, ‘am’, ‘learning’, ‘to’, ‘use’, ‘NLTK’, ‘.’] ]
因此,为了开始这个过程,我做了以下步骤:
在一个 Jupiter 笔记本中导入了以下库,以启动这个过程并读取我的文本文件。
import nltk
from nltk.tokenize import word_tokenize
from nltk.tokenize import sent_tokenize
from nltk.corpus import stopwords
from nltk.text import Text
import string, re
我把演讲标记成每个句子的字符串列表。我写了一个函数,使用正则表达式库中的 re.sub()方法删除字符串中的标点符号。为了便于展示,我只选择了演讲的前 15 个句子。
删除停用词
停用词是在语言处理过程中可以忽略而不改变句子意思的小词。删除它们可以提高效率(速度、内存使用),而不会影响效率。NLTK 有一个停用词列表,16 种不同的语言各有一个。我导入了一个用于英语的函数,并编写了“remove_stopwords()”函数来查找并删除句子中的停用词。去除停用词后,单词总数从 99 个下降到 63 个,大约减少了 36%。在拥有数千个单词的语料库的环境中考虑这一点。
词性标注:
好了,接下来是更激动人心的工作。NLTK 有一个很棒的方法,叫做词性标注(nltk.pos_tag()),它接受一个标记化的句子,然后根据每个单词的语法功能(如名词、代词、形容词、时态等)将其转换为词性。有关所有标签的列表,请访问此页面。
为了做到这一点,我只是使用列表理解来循环过滤后的语音并标记每个单词。
POS = [nltk.pos_tag(tokenized_sent) for tokenized_sent in filtered ]
print(POS[:3])output:
[[('What', 'WP'), ('great', 'JJ'), ('place', 'NN')], [('Thank', 'CD'), ('much', 'JJ')], [('We', 'PRP'), ('thousands', 'NNS'), ('people', 'NNS'), ('outside', 'IN'), ('trying', 'VBG'), ('get', 'NN')]]
所有这一切只需要一行代码。
B.神盾局。
一致
为了快速探索,另一个非常有用的工具是索引。Concordance 可以用来查看特定单词在上下文中的所有用法。它返回一个单词的所有出现次数以及使用该单词的句子部分。NLTK 版本(3.3)有一个缺陷,由于这个缺陷,索引在默认情况下返回 25 个匹配项,宽度不超过 80 个字符。出于好奇,我想看看“伟大”这个词的上下文(你知道为什么)。
concordance 方法接受一个标记化单词列表。所以我回过头来对整个演讲进行了标记化,并对其调用了方法。
from nltk.text import Text
speech_words = Text(word_tokenize(speech))
speech_words.concordance('great')
正如你所看到的,这种方法可以很方便地在初始阶段使用,以吸引某些单词的使用。
词云
最后总结一下,这和 NLTK 没有任何关系,我为 70 多个演讲中的每一个创建了单词云。使用单词云生成器。不仅仅是因为它们看起来很酷,事实也的确如此!然而,我发现这是一个快速找到最常用单词的非常方便的方法。这导致了一些非常有趣初步观察。例如,在总统竞选结束时,希拉里这个词开始更多地出现。云在最后按时间顺序显示。代码如下:
from wordcloud import WordCloud
import matplotlib.pyplot as plt
for speech in speeches:
print(speech)
speech = open(speech, 'r').read()
cleaned_speech = remove_punctuation(speech)
text = cleaned_speech
wordcloud = WordCloud().generate(text)
# Display the generated image:
plt.figure( figsize=(20,10) )
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis("off")
plt.show()
下一步是什么?
我将继续探索 NLTK 的更多方法,并希望在未来能够做出一些有意义的分析。
以下是姜懿翔·川普在总统演讲中的演讲,按时间顺序排列。
尽情享受吧!
使用假设检验来学习
我在过去的 6 年里一直忙于测试。无论是电子邮件活动的表现,以推动健康成果,产品的变化,网站的变化,该名单继续下去。其中一些测试是 A/B(可能有多个测试单元),还有一些是全因子 MVT 测试(我的最爱)。
我想分享一些测试的最佳实践,这样你就可以对你如何设计和思考测试充满信心。
作为一名数据科学家,你可能被期望成为如何正确测试的主题专家。或者,您可能刚刚构建了一个产品推荐引擎(或一些其他模型),并且您希望看到与以前使用的模型或业务逻辑相比,您的性能提高了多少,因此您将测试新模型与当前生产中的任何模型。
测试的世界远不止这里所包含的,但我希望在这里涵盖的是:
- 确定测试和控制群体
- 启动前的测试范围
- 一个测试设计,它将允许我们读取我们希望测量的结果
- 测试分析
- 关于自动化测试分析的思考
选择测试和控制群体
这是魔法开始的地方。确定因果关系的唯一方法是随机分组(和正确的测试设计)。因此,如果我们想了解任何东西,我们的人口必须被正确地划分出来。一般来说,你的目标人群将会是你所测试的特定人群。如果这是一个电子商务公司的网站测试,你希望访问者在访问网站时被随机测试和控制。如果您正在运行一个电子邮件活动或一些其他类型的测试,那么您将从数据库或 BigData 环境中找出所有符合参与测试标准的相关客户/人员。
如果这是一个很大的列表,你可能需要在一段时间内对客户进行随机抽样。这叫做简单随机抽样。一个简单的随机样本是总体的一个子集,其中每个成员被选入样本的概率是相等的。
这里有一篇关于如何从 Hive 中随机抽取样本的文章:这里
另外,需要明确的是,在 SQL 中编写“select top 1000 * from table”并不是一个随机样本。有几种不同的方法可以在 SQL 中获得随机样本,但是如何做将取决于您所使用的 SQL 的“风格”。
这里有一篇关于在 SQL server 中抽取随机样本的文章:这里
现在你已经有了你的样本,你可以将这些人随机分配到测试组和控制组。
有时候,我们需要变得更老练一点。
假设您想了解推动行业参与度的能力(并且您有行业数据)。一些行业可能会比其他行业包含更少的成员。也就是说,如果你只是将一部分人分成两组,你可能在某些你关心的行业中没有足够高的样本量来确定统计显著性。
与其竭尽全力进行测试,发现你无法了解你所关心的行业,不如使用分层抽样(这将涉及在每个感兴趣的群体中进行简单的随机抽样)。
发布前的范围界定
我在实践中看到,当人们没有看到他们想要的结果时,他们会说“我们将让这个测试再运行两周,看看会发生什么”。特别是对于站点测试,如果你运行的时间足够长,微小的影响也会变得很大。你应该知道你得到了多少流量,在你发布之前测试应该运行多长时间。否则,是什么阻止我们运行测试,直到我们得到我们想要的结果呢?
在测试开始之前,与其他利益相关者坐下来,了解业务含义,他们希望了解什么,他们在测试谁,以及他们如何测试。根据我的经验,当你被视为帮助构建测试的思想伙伴,并且在启动之前就分析的范围达成一致时,每个人都为成功做好了准备。
测试设计
对于测试中的每个单元格,您只能进行一次更改。例如,如果我们有:
- 单元格 A:15 美元的价位
- 单元格 B:25 美元的价位
- 单元格 C: UI 更改和 30 美元的价格点
你只是丢失了信息。添加一个 UI 更改和一个不同的价格选项使得无法解析 UI 更改或 30 美元的价格点会产生什么影响。我们只能知道这些细胞的总体表现。
迭代测试是当你从一个测试中获得获胜者,并把它作为后续测试的控制。这种方法会导致信息丢失。如果测试 1 的输家和测试 2 的赢家的组合实际上是赢家呢?我们永远不会知道!
有时像这样的迭代是有意义的(也许你没有足够的流量来容纳更多的测试单元),但是我们想要提前讨论所有潜在的让步。
另一种类型的测试设计是 MVT(多变量)。在这里,我们将看到一个全因子 MVT。有更多类型的多变量测试,但全因子是最容易分析的。
- 对于更微妙的优化,MVT 更好(如果您认为测试会有巨大的影响,应该使用 A/B)
- 经验法则是每月至少有 100,000 个独立访问者。
- 您需要知道如何使用 ANOVA 进行分析(我将在后续文章中提供关于如何进行这种分析的代码和解释,并在稍后链接到这里)
MVT 测试的一个示例如下。左边(下面)是对照实验,右边是 3 个试验处理。这导致 2 = 8 个处理,因为我们将查看测试和控制的每个可能的组合。
我们可以了解所有的互动!了解相互作用并在改变多个项目时找到最佳处理方法是 MVT 测试的最大优势。下图显示了每个人将如何被分配到 8 种治疗方法中的一种。
在以后的文章中,我会用 R 代码写一篇我以前分析过的 MVT 测试。
测试分析
测试分析最重要的部分之一是在我们如何分析测试的业务中保持一致性。你不想说某事有因果关系,如果另一个人分析了同样的测试,他们可能会得出不同的结论。除了有一致的方法来确定结论,您还希望有一致的方法来与业务的其他部分交流这些结果。“我们会分享 p 值大于 0.05 的结果吗?”也许我们会,也许不会,但要确保整个团队在沟通上保持一致。
**应该总是给定置信区间!**你不想说“哇!这相当于每年 70 万美元”,而实际上它的价值在 10 万美元到 130 万美元之间。这是一个很大的差异,可能会对是否推出变革的决策产生影响。
让我们实现自动化吧!
当我们可以:
- 自动去除异常值
- 如果样本还不够大,内置而非计算统计显著性
- 使用置信区间和引人入胜的图表确定指标的统计显著性
- 查看发布后不久测试的执行情况,以确保没有任何错误干扰我们的结果或收入大幅下降。
- 这也减少了分析中出错的机会
只需输入几个数据和按几个按钮!
这需要一段时间来构建,并且不会对所有的测试都适用。即使是部分自动化也可以大大减少分析测试所花费的时间!
我希望这篇文章能给你一些测试时需要注意的事情。如果你还在上学,想成为一名数据科学家,参加一门普通的统计学课程,包括使用哪些统计数据以及如何计算置信区间,这将使你在数据科学的职业生涯中受益匪浅。否则,互联网上肯定有大量的信息给你如何计算这些统计数据的概述。我个人更喜欢 Coursera ,因为可以高枕无忧地观看内容上的视频,知道内容来自知名大学,这种感觉很好。
通过正确执行测试,您可以学到很多东西。快乐学习!
访问我的网站获取更多文章:)
正态性检验
在数据挖掘和机器学习领域,这是一个非常常见的问题。这个问题通过假设检验来回答。
你可以在这里找到很多关于正态性检验的惊人信息,但是我会试着解释我的答案的基础。
我过去使用过卡方检验、科尔莫戈罗夫-斯米尔诺夫检验和夏皮罗-维尔克检验,所有这些检验都可以在 R 中打包获得,也可能在 NumPy 中实现。
无效假设通常是从正态分布中抽取值。所以通常会进行双尾假设检验,如果零假设被拒绝,你可以很有把握地说这些值不是来自正态分布。通常假设相反的情况,但严格来说,这是不正确的,因为在假设检验(费雪检验)中,你只能拒绝假设。
用于检验假设的统计通常基于正态分布的一些一般性质。卡方检验利用了标准正态分布的平方遵循卡方分布的假设。KS 检验利用累积概率分布的特性来比较任意两个分布,在本例中是您的样本,以及一个正态分布。
文本分析 API,第 1 部分:大玩家
如果你在市场上寻找现成的文本分析 API,你有很多选择。你可以选择与软件世界的主要参与者合作,对他们来说,每个与人工智能相关的服务只是他们庞大工具目录中的另一个条目,或者你可以选择一个较小的提供商,专注于文本分析作为他们的核心业务。在这两篇相关文章的第一篇中,我们来看看当今最著名的软件巨头能提供什么。
本文最初作为 2018 年 3 月行业观察专栏出现在自然语言工程杂志上。你可以在这里找到完整的引用细节,在这里了解更多关于语言技术组。
文本分析的前景
在最近的一个项目中,我需要回顾来自众多供应商的文本分析 API 产品。这些 API 在过去几年中激增:基于云的资源的易获得性和灵活性意味着开发文本分析驱动的 SaaS 产品的门槛相对较低,现在至少有二十几个 API 可供您使用。因此,如果你想利用第三方的文本分析功能,而不是构建自己的功能,你该如何选择呢?这篇文章,以及随后的一篇文章,旨在帮助你,如果你碰巧面临这种特殊的困境。[据我所知,这里提供的所有信息都是准确的,时间是 2018 年 1 月;但是事情可能会变化很快,所以你最好在根据这篇文章做出决定之前仔细检查所有关键信息。]在这里,我们来看看我们可能认为的软件行业的“巨人”:主要的玩家,对他们来说,文本分析只是一系列产品中的一个功能。例如,如果您希望确信您正在使用的工具是由一家几年后肯定会出现的公司支持的,那么您可能会被这些提供商所吸引。在随后的帖子中,我们将考虑“大卫”:专注于文本分析的小玩家,你可能希望他们更加灵活和创新。
关于范围的说明:我们将文本分析与各种类型和各种方式的文本文档的处理有关,通常使用该领域大多数人认为需要某种形式的自然语言处理的功能。对聊天机器人和虚拟助手的持续高度兴趣意味着每个供应商也有一系列语言相关的服务来支持这种类型的对话应用程序,但这不是我们在这里考虑的;我们将在随后的文章中讨论这个话题。
巨人队
虽然也有其他软件巨头提供文本分析功能——例如,惠普有自己的 Haven OnDemand 服务,SAP 提供文本数据处理服务——但我们在这里重点关注这个领域最引人注目的四家主要公司:按字母顺序排列,亚马逊、谷歌、IBM 和微软。脸书和苹果也有用于一些文本分析任务的 API,但在每一种情况下,它们主要是作为在这些公司各自的软件平台上工作的工具。如果你是一个软件开发人员,想要构建一个独立的应用程序,利用第三方文本分析工具集,我们在这里考虑的四个可能是最明显的选择。
亚马逊是这个俱乐部的最新成员:尽管他们已经围绕 Alexa 平台提供了各种语言相关的服务有一段时间了,但打包为Amazon understand的文本分析功能直到 2017 年 11 月才与亚马逊翻译和亚马逊转录一起公开提供。当然,这些只是 AWS 旗下提供的大量服务中的一部分。understand 提供五种不同的文本分析服务:实体识别、情感分析、关键短语提取、语言检测和主题建模。understand 被归类为机器学习服务,以及其他与 Alexa 相关的服务。
谷歌的自然语言 API 是谷歌云平台的一部分。提供的 API 涵盖实体识别、情感分析、句法分析和内容分类。同样,这些只是基于云的工具的广泛套件中的组件。谷歌也将这些功能归入机器学习,以及一系列相关工具,包括更高级的服务,如“工作发现”。谷歌 NLP API 于 2016 年 7 月发布测试版。
正如我们之前在本专栏中提到的,IBM 的自然语言能力——或者至少是我们感兴趣的能力——是通过收购来实现的:IBM 在 2015 年 3 月收购了 AlchemyAPI,这可能是第一个基于云的文本分析 API。AlchemyAPI 本身于 2009 年推出;Alchemy 保留了它作为 IBM Watson 服务的名字,直到 2016 年初,它变成了 IBM 自然语言理解。IBM API 提供了比这里讨论的其他提供者更广泛的功能:实体检测、情感分析、主题检测、关键字检测、五级层次结构中的内容分类、关系和语义角色提取,以及一些有用的元数据工具。IBM framework 还允许您使用针对实体和关系标识的定制领域特定模型来扩展所提供的功能。
微软的 NLP 相关产品分布在 Azure 平台认知服务下的各个子类别中。在语言子类别下,我们有语言分析(提供标记化、词性标注和基于选区的解析)和文本分析(提供语言检测、情感分析和关键短语提取)等。链接 API 的[实体可以在 Knowledge 子类别下找到,并且至少从 2016 年初开始就是 Azure 服务的一部分;在此之前,它是微软牛津项目的一部分。](https://azure.microsoft.com/en-au/services/cognitive-services/entitylinking- intelligence-service/)
由于可用功能的具体范围因提供商而异,您的特定需求可能会从一开始就排除一些候选人。
使用 API
因为它们都是全栈云平台提供商,所以对于上述每一个,你都可以完全在云端开发和部署应用,除了在你的本地机器上使用终端窗口之外,不需要使用任何东西。但是,您也可以将这些文本分析服务用作 API,从您自己的机器或其他地方托管的应用程序中调用。
在每种情况下,注册一个免费或试用帐户,并设置认证以使用服务都相当简单。这四个提供商都提供 SDK 和对各种编程语言的支持;同样,在支持的语言方面有一些变化,所以这是您可能要考虑的另一个因素。
为了便于比较,我们在这里只关注一个特定的核心功能:检测文本文档中的命名实体提及。四个 API 中的每一个为这个任务提供了稍微不同的输入选项;我们将在下面进一步讨论输出。
- Amazon 的方法是最简单的:您提供一个文本字符串和用于分析的语言。目前,仅支持英语和西班牙语。
- Google 接受纯文本或 HTML 文档,或者对位于 Google 云存储中的文档的引用,以及文本编码类型,这对于计算偏移量很重要。您还可以指定分析中使用的语言;默认情况下,这是自动检测的,但是包含大量非英文名称的文本似乎会忽略这一点,所以如果可能的话,指定这个参数会更安全。
- IBM 的 API 还接受纯文本或 HTML 内容,或者要分析的文档的 URL,以及分析中要使用的语言。这个 API 提供了一个简洁的特性,它试图从一个检索到的 HTML 页面中删除广告,并且你可以询问它的情绪(喜悦、愤怒等等)。)和对检测到的实体表达的情感(消极或积极)。
- 微软的 API 只支持 UTF-8 文本。与其他服务不同的是,微软的服务只希望每次通话都有一段文字。同样独特的是,API 提供了一个选项,您可以通过它来查询文本中的特定单词或短语。这些属性让我想知道开发人员在这里考虑的目标用例是否可能与其他产品不同;例如,每段操作模式可能是有用的,因为当在文字处理程序中键入 ENTER 时会触发这种模式。
也许不足为奇的是,所有这些服务对于什么是命名实体有稍微不同的概念。表 1 列出了每种识别的类型。这里没有列出微软的服务,因为它不返回它检测到的实体的类型信息;更多信息请见下文。
当然,仅仅因为两个提供者对一个类别使用相同的名称并不意味着他们都以相同的方式定义那个类别;这就导致了跨平台对比的困难。
IBM 类别的粒度是惊人的;除此之外:该服务还检测 433 种实体子类型,包括“自行车制造商”和“视频游戏发行商”等;完整列表见[此处](https://console.bluemix.net/docs/services/natural-languageunderstanding/ entity-types.html#entity-types-and-subtypes)。给定的实体可以被分配几个子类型:例如,除了类型“公司”之外,CNN 还具有子类型“广播”、“获奖人”、“无线电网络”和“电视网络”。
比较的 API 输出
四个 API 的输出也有差异,如图 1 所示。
Amazon 返回一个实体提及数组,每个实体提及都有其开始和结束偏移量、从表 1 所示的列表中抽取的类型,以及系统在检测中的置信度得分。重要的是,似乎没有试图确定哪些提及是共同引用的,这是所有其他 API 都要做的事情;对于亚马逊来说,每一次提及都被视为一个独特而独立的实体。
Google 返回一个实体数组,每个实体都有被认为是对每个实体的引用。实体类型如表 1 所示。每个实体在文档中都有一个总体显著性;提及类型表明提及是专有名词还是普通名词。在可能的情况下,每个实体还与一个维基百科 URL 和一个知识图 MID 相关联。还可以请求对文档中的实体表达的总体情感。
IBM 的输出类似于 Google,每个被检测到的实体都与一组提及及其位置相关联。如果可用,将提供该实体的 DBpedia 链接。(奇怪的是,如图 1 中的例子所示,API 无法找到新西兰的 DBpedia 资源。)如前所述,还可以请求对实体的情感和情绪。对于给定的输入文本,最多返回 250 个实体。
微软还在文本中提供了一系列实体及其相关的提及,通过一个代表性的名称联系在一起。如果可以找到的话,会提供一个 Wikipedia ID,但是如上所述,没有提供类型信息。
图 1 显示了在板球比赛报告的上下文中,特定命名实体的每个 API 的结果(这是路透社文件 239046newsML)。这里所指的实体是新西兰板球队。短语新西兰和板球在文本中没有出现在任何相邻的地方,但是谷歌和微软都成功地将实体解析为板球队而不是国家。
他们工作得怎么样?
表 2 中显示的结果来自于在公开可用的 CoNLL 2003 共享任务数据上运行每个 API,这些数据来自于路透社语料库。
这里有各种各样的问题:不同的 API 使用不同的标记化算法,这有时会产生与黄金标准不一致的结果(这并不意味着它们是错误的——有时 CoNLL 注释看起来是不正确的);还有其他方法可以将每个 API 的实体类型映射到 CoNLL 实体类型。将这些数字与参与共享任务的参与者生成的数字进行比较可能也不公平,因为后者的系统可能是根据路透社的训练数据定制的,而这里审查的服务不太可能是这样。例如,IBM 在 MISC 类别上的糟糕表现似乎很大程度上是因为它没有识别出任何国籍形容词,如克罗地亚语和德语,这些形容词被 CoNLL 标记为 MISC。尽管如此,我认为在一个相对中立的数据集上观察这三个系统的相互比较还是很有趣的。(同样,微软的结果没有在这里显示,因为它们不包含已识别实体的类型信息。)
定价
在竞争激烈的市场中,SaaS 产品通常很难进行定价比较:不同提供商的定价会因所使用的特定分析服务、文本单元采用的大小以及分层拆分而有所不同。所有四个提供商都有免费等级或免费试用期,因此您可以试用它们。对于生产用途,亚马逊命名实体识别的单位大小为 100 个字符,定价为每单位 0.0001 美元,最多 1000 万个,此后打折;谷歌的单位大小称为文本记录,是 1000 个字符,每个文本单位收费 0.001 美元,最多 100 万个单位,此后打折;IBM 按照 NLU 单位收费,其中一个单位是 10 K 个字符×所请求的特征数(此处显示的实体识别结果计为单个特征),每个 NLU 项目的成本为 0.003 美元,每月最多 250 K 个项目。我无法计算出微软产品的价格;我的最佳猜测是,如果你使用其他服务,它是免费的,但这很难说。这可能是因为该服务目前被归类为预览模式。
根据这些数字,如果你想每月处理 100,000 个 10 KB 大小的文档,亚马逊和谷歌都会向你收取 1,000 美元,但 IBM 只会向你收取 300 美元。但不同的单位规模方法和不同的分层分割意味着最佳交易将取决于您的具体数字。
获胜者是…
嗯,这要看情况。
- 如果您关心被检测到的实体的类型,那么微软的实体链接 API 就不适合,因为它(至少目前)不提供这种信息。当 API 提供一个维基百科的链接时,你也许能找到它的类型,但是,正如我的一个好朋友喜欢说的,生命太短暂了,穿不了太紧的鞋子。
- 如果您关心在一个文档中集合对同一个实体的不同引用,那么您不需要 Amazon API,因为它将每个引用都视为独立的。
- 如果您还想利用解析结果,那么您只能使用 Google(用于依赖解析)和 Microsoft(用于选区解析);如果您只是追求语义角色和关系,而没有访问完整的语法分析,IBM 会做。
- 在某种程度上,对上述 CoNLL 数据的评估结果具有代表性,您可以根据对您重要的度量和实体类型做出选择。IBM 的实体类型可扩展性可能是这里的一张王牌:尽管它在默认设置下的性能不如其他产品,但扩展实体识别集的能力提供了一种解决方法。
- 正如我们在上面讨论的新西兰的例子中看到的,Google 和微软都很好地解决了对正确的依赖于上下文的实体的模糊引用,而 IBM 却没有,至少在这种情况下是这样;当然,亚马逊根本不提供实体链接。
- IBM API 提供了许多其他 API 没有提供的“管理特性”,比如文本清理和元数据提取。
- 您的里程数可能会有所不同,但是我发现 Amazon 和 IBM 文档更容易找到。Google 的文档在某些地方似乎与实际的 API 不一致,但是请记住,它被归类为测试版,因此它可能比稳定版更频繁地变化。类似地,微软的文档似乎相当有限,但这可能是由于该产品的预览性质。
所以,很明显,这完全取决于你的具体要求。
但到目前为止,我们只讨论了歌利亚。那些小球员呢?对于大玩家来说,拥有一个文本分析产品可能比拥有一个好的文本分析产品更重要;也许有购买决定,西装只是想知道供应商是否勾选了文本分析框。但这对那些只专注于文本分析的公司来说并不合适。那么他们如何比较呢?我们将在下一篇文章中讨论这些——关注文本分析 API,第 2 部分。
如果你想要一种简单的方法来跟上商业 NLP 世界的关键发展,可以考虑在 NLP 中注册本周的 ,这是一份每周周五出版的短小精悍的周报。
文本分析 API,第 2 部分:小玩家
似乎每隔几周市场上就会出现另一种基于云的文本分析应用编程接口(API)。如果您对使用这些类型的服务构建应用程序感兴趣,如何决定使用哪种 API 呢?在本系列的上一篇文章中,我们看了云软件世界中的巨头的文本分析 API:Amazon、Google、IBM 和 Microsoft。在本帖中,我们调查了市场上规模较小的公司提供的 16 种 API。
本文最初作为 2018 年 9 月行业观察专栏出现在自然语言工程杂志上。你可以在这里找到完整的引用细节,在这里了解更多关于语言技术组。想要更多吗?在这里可以找到关于 25 个以上文本分析 API 的更深入的探讨。
随处可见的文本分析 API
似乎每隔几周就会出现一个新的文本分析 API。在本系列的前一篇文章中,我们研究了软件即服务市场中的巨头提供的文本分析 API:亚马逊、谷歌、IBM 和微软。这些 APIs 考虑到它们背后的资源,毫不奇怪——是健壮的、开发良好的和有据可查的。但正如我们在那篇评论中指出的,出于这样或那样的原因,你可能不想与大玩家同床共枕。此外,规模较小的公司总有可能会有更新的想法,并能够灵活敏捷地实施这些想法,而不像规模较大的公司那样发展缓慢。
因此,考虑到这一点,在这篇文章中,我们来看看 16 个专注于文本分析作为核心业务的公司的 API。在撰写本文时,我知道至少还有另外 10 个文本分析 API,但是我们在本文和上一篇文章中讨论的总共 20 个应该足够让你知道提供了什么以及什么可能最适合你的需求。如果我错过了一个你用过并且喜欢的 API,或者——更糟!—如果我错过了你在过去几个月里不眠不休开发的 API,给我发一封电子邮件,我会很受鼓舞地在随后的帖子中报道它。
文本分析的前景
我们在这里关注的是通过软件即服务订阅模式以商业条款提供的基于云的 API。有更多的公司使用专有的文本分析工具集提供软件开发服务,但这里我们不关心他们。我们特别关注那些提供工具集的公司,你可以用这些工具集来构建自己的文本分析应用。我们还特别关注 API,其主要目的是支持构建处理文本文档的应用程序,如网页、PDF 文件、邮件消息或推文;还有另一类自然语言处理 API,我们在这里没有考虑,它们更基本地与构建交互式聊天机器人有关。就有用的功能而言,这两种类型的应用程序之间有一些交叉,事实上,这里讨论的一些供应商似乎正在将他们的主要注意力转移到聊天机器人领域;但是我们主要关心的是文件的处理。表 1 列出了我们在这里要考察的 16 家供应商。[请注意,自从这篇文章撰写以来,Ambiverse API 已经不再可以在商业基础上使用,现在可以开源使用。]
Table 1: The 16 Text Analytics APIs reviewed here
值得注意的是,每个文本分析供应商都提供一个功能组合,所提供的服务范围可能是您选择工具集的一个关键因素。例如,如果您需要进行命名实体识别和摘要,后一个需求已经大大缩小了您的选择范围。下表 2 总结了所提供的最重要的功能。这不是一个详尽的列表,许多 API 还提供了这里没有列出的额外功能。也不一定任何两个提供特定功能的供应商所用的术语是指同一件事,这里的列表不可避免地要做出一些妥协。特别要注意的是,这里的语言分析类别包含了广泛的功能:一些供应商只提供词性标注,一些供应商提供某种形式的解析,还有一小部分供应商提供开放关系提取。仅仅因为供应商提供了特定的功能并不意味着他们做得很好。
Table 2: Capabilities by product: ER = Entity recognition, SA = Sentiment analysis, LD = Language detection, KE = Keyword extraction, CL = Classification, SU = Summarisation, LA = Linguistic analysis
和前一篇文章一样,在本文的剩余部分,我们将集中讨论一个单一的功能,即实体识别,因为这是所有供应商共有的一个功能;如果您想了解更多关于所有这些 API 的其他功能的信息,以及这里没有包括的一些其他功能,请参见完整报告这里。
如何选择命名实体识别器
有许多非技术因素会影响您对提供商的选择,例如支持和文档的质量、正常运行时间保证,当然还有价格。然而,在这里,我们将关注技术因素。
让我们假设您已经决定了您想要什么样的通用文本分析功能,这有助于您筛选可用的候选功能。现在,您需要决定哪个命名实体识别器最适合您的需要。你可能需要考虑几个关键标准。
- 您想要识别什么类型的实体?几乎每个 API 都返回与人、地点和组织的基本三元组相对应的类型,但有些 API 还提供许多其他类型。
- 需要知道文中提到实体的位置吗?例如,如果您的应用程序需要在上下文中显示已识别的实体,而如果您的任务只是过滤文档,那么知道某个内容被提及就足够了,不管在哪里。
- 您是否需要通过链接到一些外部知识源(如维基百科或 DBpedia)来消除已识别的实体提及的歧义?
表 3 显示了每个 API 所标识的类型,表 4 显示了这里调查的 16 个 API 如何符合其他两个标准。
Table 3: Recognized types by product
Table 4: NER features by product
除了这些特性之外,一些 API 还提供了文档中命名实体显著性的数值度量;并且许多还传递一些置信度的数字度量,该置信度可以是所识别的字符串是命名实体、所识别的字符串是指定类型或者所提供的歧义消除链接是正确的置信度。
当然,你想看一些例子。如果要显示所有提到的 API 的输出,那就太难了,所以我选择了一个有代表性的例子。鉴于输入句子杰夫·贝索斯可能会在美国首都花费更多时间,因为华盛顿越来越像是亚马逊第二总部的领跑者,图 1 显示了 ParallelDots 提供了什么;这是典型的简单输出。图 2 给出了由 Ambiverse 提供的更复杂结果的味道;图 3 显示了 TextRazor 提供的结果。
Figure 1: Example output from ParallelDots
Figure 2: Example output from Ambiverse
Figure 3: Example output from TextRazor, with some details elided
他们工作得怎么样?
同样,仅仅因为一个供应商声称检测到某某类型的实体并不意味着他们做得很好。正确的评估超出了本文的范围;对于一个简单的量化评估来说,用例需求中有太多的变量和太多的独特性。但是在决定选择哪个供应商之前,您肯定希望进行彻底的测试。我自己对这里列出的所有 API 进行的轶事测试表明,性能差异很大,因此没有捷径可以围绕构建适合您的需求的测试集并查看 API 如何处理它。
幸运的是,这里的所有供应商要么提供免费使用层,有时提供相当慷慨的调用配额,要么提供免费试用期,因此不难感受到这些 API 的性能有多好。每一个都提供了一个相当标准的注册过程,通过这个过程你可以创建一个账户,并获得授权证书;所有的供应商都提供了 RESTful API,您可以将它与适当的库一起用于几乎任何编程语言,和/或 API 包装器,使某些特定语言的使用变得容易。
底线
因此,正如您所料,最适合您的 API 取决于许多因素:所提供的文档和支持是否足以满足您的需求?该 API 是否提供了您所需要的功能,并且达到了您满意的性能水平?当然,价格需要是可接受的——同样,我们在这里看到的 API 的使用成本有相当大的差异。参见我的文本分析 APIs 2018:消费者指南获取详细分析。如果你面临在这个领域做决定,我希望这篇文章能帮你节省时间。我很想听听你的经历:给我发电子邮件,地址是 rdale@language-technology.com。
如果你想要一种简单的方法来跟上商业 NLP 世界的关键发展,可以考虑在 NLP 中注册本周的 ,这是一份每周周五出版的短小精悍的每周时事通讯。
文本分析不是火箭科学,现在就学习吧!—开始 7 门文本分析课程
背景和动机
文本无处不在,在书籍和印刷材料中,在报纸上,在维基百科和其他百科全书中。人们在网上论坛和讨论组中互相交谈,脸书和推特也大多是文本。
传统的数据分析基于关系模型,数据存储在表中(所谓的结构化数据)。然而,只有大约 20%的企业可用数据是结构化数据,其余 80%是非结构化数据和自由文本。非结构化数据和自由文本实际上是我们遇到的大多数数据,这包括维基百科中的 4000 多万篇文章(其中 500 多万篇是英文的),45 亿个网页,每天大约 5 亿条推文,以及一年内在谷歌上超过 1.5 万亿次查询。
以下是来自预测分析今日的简洁描述:“文本分析是将非结构化文本数据转换为有意义数据进行分析的过程,以衡量客户意见、产品评论、反馈,提供搜索功能、情感分析和实体建模,以支持基于事实的决策。”
我希望我已经能够说服你去探索文本分析。事不宜迟,让我们通过这 7 门在线课程深入研究文本分析。
在线文本分析课程
4.7 颗星(12 个等级)
密歇根大学 viaCoursera
作为 Python 专业化的应用数据科学的一部分,该课程将向个人介绍文本挖掘和文本操作的基础知识。本课程从理解 Python 如何处理文本开始,对机器和人类来说都是文本的结构,以及对处理文本的 nltk 框架的概述。接下来的几周将重点关注常见的操作需求、基本自然语言处理方法在文本中的应用,以及如何完成文本分类的演示。最后一周将探索更高级的方法,如主题建模。
4.4 颗星(164 个评级)
伊利诺伊大学香槟分校途经Coursera
作为数据挖掘专业的一部分,本课程将涵盖挖掘和分析文本数据的主要技术,以发现有趣的模式,提取有用的知识,并支持决策制定,重点是统计方法,这些方法通常可以应用于任何自然语言中的任意文本数据,只需很少或不需要人力。
4.1 首发(22 个评分)
延世大学 viaCoursera
本课程为个人提供了一个独特的机会,在真实世界数据集和用 Java 编写的文本挖掘工具包的帮助下,学习文本挖掘和分析的关键组件。
3.9 颗星(206 个评分)
R-教程训练通过 Udemy
本课程教授个人如何在 r 中处理社交媒体数据。他们将使用 Twitter 数据作为示例数据集。
4.2 颗星(57 个评分)
ExcelR 解决方案通过 Udemy
本课程展示了如何理解非结构化数据,并为个人提供了各种工具的知识,这是至关重要的。
本课程讨论文本挖掘的标准技术,并将相当大的注意力放在将非结构化文本转换成可挖掘形式所需的数据准备和处理方法上。
Full Text Search with SAP HANA course at openSAP
如果您的组织已经实施或将要实施 SAP HANA 环境,那么,本课程就是您在 SAP HAHA 中进行文本分析的起点。通过本课程,您将了解全文索引,并允许您通过 SQL、模糊搜索、重复检查搜索规则等进行搜索。下一节课 2017 年 9 月开学。这门课程是免费的,对所有人开放。
如果你知道任何我错过的文本分析课程,请在下面的评论中告诉我。
音乐流派歌词的文本分析和主题建模
这项分析使用了自 1970 年以来发表在 kaggle 上的超过 38 万首歌曲的数据集。主要目标是根据歌词开发音乐类型的集群,步骤如下:
- 数据准备(清理、转换等。)
- 探索性分析
- 主题建模
使用了各种 R 库,但主要是基于 #tidytext 和 #tidyverse 环境。
数据准备是分析的一个非常重要的部分。第一步是排除所有歌词文本字段长度小于 10 个字符的歌曲。
然后,在查看歌词文本字段后,似乎出现了大量非英文歌曲。决定在最终的数据集中只包括英语歌曲。因此,通过使用 cld3 库,歌曲的来源被检测到&被添加到数据集中。语言检测并不完美,因为它错误地分类了一些歌曲。但由于原始数据集很大,我决定使用它,并从数据集中删除所有非英文歌曲。最后,所有音乐类型缺失或未知的歌曲都被删除。所有年份输入无效(小于 1970 年)的歌曲也被删除。
关于这些步骤的更多细节可以在文章末尾的实际代码中找到。
主要分析
下面有一个频率图来表示音乐流派之间的差异。
大多数歌曲属于摇滚类型,几乎是这个数据集中所有歌曲的 50%。前五大音乐流派是摇滚、流行、嘻哈、金属和乡村音乐。
看看这是否会随着时间的推移而保持不变会很有趣。下面有一个图表显示了这些年来的变化。
这里有一些发现。起初,摇滚音乐在歌曲中所占的比例下降了(从 60 %下降到 25 %)。另一方面,hip-hop 逐渐上升(目前接近 20 %)。Pop 在 20 %左右,并且多年来相当稳定。
现在让我们试着找出哪种音乐类型使用了更多的歌词。
Hip-Hop 似乎是一种明显不同的音乐类型,因为它比其他类型的歌曲使用更多的歌词。
WORDCLOUD
看看每种音乐类型中使用最多的单词是很有趣的。下面是排名前五的音乐类型的单词云。词云(也称为文本云或标签云)以一种简单的方式工作:特定的词在文本数据源中出现得越多,它在词云中出现得就越大、越粗。
下面是排名前 5 的音乐流派的词云。
主题建模
例如,考虑这样一种情况,您面对一大堆文档,但不知道它们是关于什么的。您可能想做的第一件事是将这些文档按主题分类。除此之外,这将帮助你找出是否有任何感兴趣的东西,同时也将你引向语料库的相关子集。对于小的集合,人们可以通过简单地浏览每个文档来做到这一点,但是对于包含数千个文档的语料库来说,这显然是不可行的。
主题建模处理将文档集自动分类到主题中的问题。选择的算法是潜在的狄利克雷分配或 LDA,它本质上是一种便于在文档集合中自动发现主题的技术。
LDA 背后的基本假设是,集合中的每个文档都由集合范围内的主题组成。然而,实际上我们只观察文档和单词,而不是主题——后者是文档隐藏(或潜在)结构的一部分。目的是根据给定的单词和文档推断潜在的主题结构。LDA 通过反复调整文档中主题和主题中单词的相对重要性来重建语料库中的文档。
在我们的案例中,开发了具有两个主题的 LDA 模型。在计算了所有歌曲的主题概率之后,我们可以看到这种无监督的学习是否能够区分或揭示音乐流派之间的关联(关于它们的歌词)。下面的方框图显示了每首音乐类型的歌曲属于这三个主题的概率。
Hip-Hop 流派几乎被唯一地确定为一个单独的主题(主题 2)。其余的音乐流派似乎被确定为另一个主题。
所以我们可以说 Hip-Hop 绝对是一种音乐流派,它在歌词中使用了与其他流派明显不同的语言。
开发了更多的 LDA 模型(三个&四个主题),但初始模型(两个主题)的结果更相关、更重要。
结论
最后我们可以得出这样的结论:
-有一种音乐类型,Hip-hop,与其他类型的音乐明显不同,因为它使用了更多&不同的歌词。随着歌曲的减少和新音乐类型的出现,摇滚音乐的受欢迎程度逐渐下降。
硬件环境
有些任务可能要求很高(对于包含文本数据的大型数据集)。例如,LDA 建模任务大约需要 7-8 分钟才能完成。
文本分类:应用和用例
文本分析,整体来说是一个新兴的研究领域。市场营销、产品管理、学术和治理等领域已经在利用从文本数据中分析和提取信息的过程。在之前的帖子中,我们讨论了文本分类背后的技术,这是文本分析的重要部分之一。*文本分类是将自然语言文本按照预先定义的类别进行标注的活动。*通俗地说,文本分类就是从非结构化文本中提取通用标签的过程。这些通用标签来自一组预定义的类别。将您的内容和产品分类有助于用户在网站或应用程序中轻松搜索和导航。
使用文本分析生成的知识产品能够部署到任何人的办公桌上。
–row analytics 首席执行官史蒂夫·加德纳
在这篇文章中,我们来谈谈当前和新兴的文本分类应用。很长一段时间以来,我们一直在使用文本分类来简化我们的事情。图书馆中的图书分类和新闻中的文章分割本质上是文本分类的例子。加入时下流行的人工智能技术,这个过程变得自动化和简单,只需要最少的人工操作。使用人工智能对文本进行分类的概念已经存在了相当长的时间*(Gmail 中的自动过滤和标签,有印象吗?)*。
只要有某些标记要映射到大量文本数据,就可以使用它。尤其是在营销方面,因为它已经从搜索引擎转移到社交媒体平台,在那里品牌和用户之间进行真正的交流。随着营销变得越来越有针对性,营销人员正在使用个性化来推动更好的参与。因此,倾听用户对话并对其进行分析成为营销人员的一项必做任务。
可以对任何数据集进行分类。文本分类对标记数据集进行处理的能力*(在 CRM 自动化的情况下)(或没有它的情况下)(在线阅读社会情绪)*只是扩大了这项技术可以实施的空间。
应用和使用案例:
- 使用类别来标记内容或产品,以此来改善浏览或识别网站上的相关内容。电子商务、新闻机构、内容管理者、博客、目录等平台可以使用自动化技术对内容和产品进行分类和标记。
- 文本分类也可以用来自动化 CRM 任务。文本分类器是高度可定制的,并且可以相应地被训练。可以基于重要性和相关性直接分配和分析 CRM 任务。它减少了人工工作,因此时间效率高。
- 使用标签对网站内容进行文本分类有助于 Google 轻松抓取您的网站,最终有助于 SEO。此外,自动化网站和应用程序上的内容标签可以使用户体验更好,并有助于标准化它们。营销人员的另一个用例是研究和分析竞争对手使用的标签和关键词。文本分类可用于自动化和加速这一过程。
- 通过对社交媒体上的恐慌对话进行分类,可以建立更快的应急响应系统。当局可以对紧急情况进行监控和分类,以便在任何此类情况出现时做出快速响应。这是一个非常选择性分类的例子。你可以看看这个研究来阅读一篇关于这样一个紧急响应系统的详细文章。
- 随着营销每天变得越来越有针对性,自动将用户分类到群组中可以使营销人员的生活变得简单。营销人员可以根据用户在线谈论产品或品牌的方式对他们进行监控和分类。分类器可以被训练来识别提倡者或反对者。因此,让品牌更好地服务于这个群体。
- 学术界、法律从业者、社会研究人员、政府和非营利组织也可以利用文本分类技术。由于这些组织处理大量的非结构化文本,如果按照类别/标签对数据进行标准化,处理起来会容易得多。
文本分类为表格带来了自动化和简化。令人惊讶的是,营销人员、产品经理、设计师、学者和工程师都可以利用这项技术。技术的全部理念是让生活变得更简单。对大量文本数据进行分类有助于标准化平台,使搜索更容易、更相关,并通过简化导航来改善用户体验。
值得注意的是,机器智能和深度学习也正在大多数不可想象和正统的领域扎根。我们可能没有像每一个 60 年代的孩子预测的那样在地面上空盘旋的飞行汽车的具体公式,但肯定有一个将它们带到地下的公式。时代在变化,令人激动。谁知道文本分析未来会有什么样的应用。
并行文本分类 API
你可以在这里找到 ParallelDot 的文本分类 API 的快速演示。可以为一组与您的业务相关的类别定制 API。我们正在升级我们的文本分类器。请继续关注关于其背后技术的详细文章。
请在下面的评论中告诉我们你对文本分类这一新兴应用的想法。我们很乐意附上名单。
对使用人工智能感兴趣?你现在可以免费注册的账号的账号,使用触手可及的人工智能。
Keras 中的文本分类(第一部分)——一个简单的路透社新闻分类器
Keras 中教授 NLP 和文本分类系列的第 1 部分
教程视频
如果你喜欢这个视频或者觉得它有任何帮助,如果你给我一两美元来资助我的机器学习教育和研究,我会永远爱你!每一美元都让我离成功更近一步,我永远心存感激。
代码
import keras
from keras.datasets import reutersUsing TensorFlow backend.(x_train, y_train), (x_test, y_test) = reuters.load_data(num_words=None, test_split=0.2)
word_index = reuters.get_word_index(path="reuters_word_index.json")
print('# of Training Samples: {}'.format(len(x_train)))
print('# of Test Samples: {}'.format(len(x_test)))
num_classes = max(y_train) + 1
print('# of Classes: {}'.format(num_classes))# of Training Samples: 8982
# of Test Samples: 2246
# of Classes: 46index_to_word = {}
for key, value in word_index.items():
index_to_word[value] = keyprint(' '.join([index_to_word[x] for x in x_train[0]]))
print(y_train[0])the wattie nondiscriminatory mln loss for plc said at only ended said commonwealth could 1 traders now april 0 a after said from 1985 and from foreign 000 april 0 prices its account year a but in this mln home an states earlier and rise and revs vs 000 its 16 vs 000 a but 3 psbr oils several and shareholders and dividend vs 000 its all 4 vs 000 1 mln agreed largely april 0 are 2 states will billion total and against 000 pct dlrs
3from keras.preprocessing.text import Tokenizer
max_words = 10000
tokenizer = Tokenizer(num_words=max_words)
x_train = tokenizer.sequences_to_matrix(x_train, mode='binary')
x_test = tokenizer.sequences_to_matrix(x_test, mode='binary')
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)print(x_train[0])
print(len(x_train[0]))
print(y_train[0])
print(len(y_train[0]))[0\. 1\. 0\. ... 0\. 0\. 0.]
10000
[0\. 0\. 0\. 1\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0.
0\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0.]
46from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation
model = Sequential()
model.add(Dense(512, input_shape=(max_words,)))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes))
model.add(Activation('softmax'))model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
print(model.metrics_names)['loss', 'acc']batch_size = 32
epochs = 3
history = model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose=1, validation_split=0.1)
score = model.evaluate(x_test, y_test, batch_size=batch_size, verbose=1)
print('Test loss:', score[0])
print('Test accuracy:', score[1])Train on 8083 samples, validate on 899 samples
Epoch 1/3
8083/8083 [==============================] - 13s 2ms/step - loss: 1.3051 - acc: 0.7192 - val_loss: 0.9643 - val_acc: 0.7931
Epoch 2/3
8083/8083 [==============================] - 12s 2ms/step - loss: 0.5136 - acc: 0.8841 - val_loss: 0.8800 - val_acc: 0.8165
Epoch 3/3
8083/8083 [==============================] - 13s 2ms/step - loss: 0.2873 - acc: 0.9344 - val_loss: 0.9045 - val_acc: 0.8065
2246/2246 [==============================] - 0s 175us/step
Test loss: 0.8878143835789586
Test accuracy: 0.7983081033478224
原贴于 hunterheidenreich.com 的。
如何使用 Keras 记号赋予器
Keras 中教授 NLP 和文本分类系列的第 2 部分
如果你还没看过第一部 的话,别忘了看看 !
如果你喜欢这个视频或觉得它有任何帮助,如果你给我一两美元来资助我的机器学习教育和研究,我会永远爱你!每一美元都让我离成功更近一步,我永远心存感激。
《恋恋笔记本》
import keras
import numpy as np
from keras.datasets import reuters
(x_train, y_train), (x_test, y_test) = reuters.load_data(num_words=None, test_split=0.2)
word_index = reuters.get_word_index(path="reuters_word_index.json")
print('# of Training Samples: {}'.format(len(x_train)))
print('# of Test Samples: {}'.format(len(x_test)))
num_classes = max(y_train) + 1
print('# of Classes: {}'.format(num_classes))
from keras.preprocessing.text import Tokenizer
max_words = 10000
tokenizer = Tokenizer(num_words=max_words)
x_train = tokenizer.sequences_to_matrix(x_train, mode='binary')
x_test = tokenizer.sequences_to_matrix(x_test, mode='binary')
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
print(x_train[0])
print(len(x_train[0]))
print(max(x_train[0]))
print(y_train[0])
print(len(y_train[0]))
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation
model = Sequential()
model.add(Dense(512, input_shape=(max_words,)))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
print(model.metrics_names)
batch_size = 32
epochs = 2
history = model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose=1, validation_split=0.1)
score = model.evaluate(x_test, y_test, batch_size=batch_size, verbose=1)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
(x_train, y_train), (x_test, y_test) = reuters.load_data(num_words=None, test_split=0.2)
x_train = tokenizer.sequences_to_matrix(x_train, mode='count')
x_test = tokenizer.sequences_to_matrix(x_test, mode='count')
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
print(x_train[0])
print(len(x_train[0]))
print(max(x_train[0]))
print(np.argmax(x_train[0]))
model = Sequential()
model.add(Dense(512, input_shape=(max_words,)))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
history = model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose=1, validation_split=0.1)
score = model.evaluate(x_test, y_test, batch_size=batch_size, verbose=1)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
(x_train, y_train), (x_test, y_test) = reuters.load_data(num_words=None, test_split=0.2)
x_train = tokenizer.sequences_to_matrix(x_train, mode='freq')
x_test = tokenizer.sequences_to_matrix(x_test, mode='freq')
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
print(x_train[0])
print(len(x_train[0]))
print(max(x_train[0]))
model = Sequential()
model.add(Dense(512, input_shape=(max_words,)))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
history = model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose=1, validation_split=0.1)
score = model.evaluate(x_test, y_test, batch_size=batch_size, verbose=1)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
(x_train, y_train), (x_test, y_test) = reuters.load_data(num_words=None, test_split=0.2)
tokenizer.fit_on_sequences(x_train)
x_train = tokenizer.sequences_to_matrix(x_train, mode='tfidf')
x_test = tokenizer.sequences_to_matrix(x_test, mode='tfidf')
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
print(x_train[0])
print(len(x_train[0]))
print(max(x_train[0]))
model = Sequential()
model.add(Dense(512, input_shape=(max_words,)))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
history = model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose=1, validation_split=0.1)
score = model.evaluate(x_test, y_test, batch_size=batch_size, verbose=1)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
基于 K 近邻的文本分类
我们将使用 Python 为文本分类定义 K 近邻算法。通过在训练数据中找到 K 个最接近的匹配,然后使用最接近匹配的标签进行预测,使用 KNN 算法进行分类。传统上,诸如欧几里得距离被用来寻找最接近的匹配。
对于文本分类,我们将使用 nltk 库来生成同义词,并使用文本之间的相似性得分。我们将识别在训练语料库中具有最高相似性得分的 K 个最近邻。
在这个例子中,为了简单起见,我们将使用 K = 1
算法:
步骤 1: 让我们先导入库:
第二步:
我们实现了 KNN_NLC_Classifier()类,使用标准函数‘fit’进行训练,使用‘predict’对测试数据进行预测。KNN 使用懒惰训练,这意味着所有的计算都推迟到预测。在 fit 方法中,我们只是将训练数据分配给类变量— xtrain 和 ytrain。不需要计算。
请注意,类接受两个超级参数 k 和 document_path。参数 k 与传统的 KNN 算法相同。k 表示将使用多少个最近邻居来进行预测。首先,我们用 k=1。另一个参数解释两个文本之间使用的距离类型。
在预测函数中,对于每一行文本数据,我们将文本与每一行训练数据进行比较,以获得相似性得分。因此预测算法是 O(m * n ),其中 m =训练数据中的行数,n 是需要进行预测的测试数据的行数。
当我们遍历每一行训练以获得相似性得分时,我们使用自定义函数 document_similarity,该函数接受两个文本并返回它们之间的相似性得分(0 & 1)。相似性得分越高,表明它们之间的相似性越大。
**第三步:**接下来,我们实现文档相似度函数。为了实现这一点,我们对每个文本/文档使用 synsets。
我们通过函数 doc_to_synsets 将每个文档文本转换成 synset。这个函数返回文本中每个单词的同义词集列表。
步骤 4: 现在,我们实现函数相似性得分,它使用两个文本/文档的同义词集来提供它们之间的得分:
此函数接受超参数 distance_type,其值可以是“path”、“wup”或“jcn”。根据这个参数,从 nltk 库中调用适当的相似性方法。
**可选:**请注意,我们可以按照下面的代码片段实现其他方法来计算 nltk 库中的相似性得分。不同的函数基于不同的语料库,如 brown、genesis 等。并且可以使用不同的算法来计算相似性得分,例如 jcn、wup、res 等。这些函数的文档可以在 nltk.org 找到
步骤 5: 现在,我们可以实现文档相似度,它计算文档 1 &文档 2 之间的相似度,反之亦然,然后对它们进行平均。
**可选:**下面是到目前为止检查代码的测试:
**第六步:**现在我们可以使用分类器来训练和预测文本。为此,首先导入一个数据集。我们将使用 Watson NLC 分类器演示中提供的演示数据集。数据集将文本分为两类——温度和条件。数据集非常小 appx。只有 50 条短信。
**第七步:**对数据进行预处理。我们将做以下预处理—
- 删除停用词(常用词,如“the”、“I”、“me”等。).为此,我们将从 nltk 下载停用词列表,并添加额外的停用词。
- 将所有文本/文档转换成小写
- 忽略数字内容等,只考虑文本数据。
我们将最终的训练数据加载到 X_train 中,并将标签加载到 y_train 中
**import** **re**
nltk.download('stopwords')
s = stopwords.words('english')
*#add additional stop words*
s.extend(['today', 'tomorrow', 'outside', 'out', 'there'])ps = nltk.wordnet.WordNetLemmatizer()
**for** i **in** range(dataset.shape[0]):
review = re.sub('[^a-zA-Z]', ' ', dataset.loc[i,'text'])
review = review.lower()
review = review.split() review = [ps.lemmatize(word) **for** word **in** review **if** **not** word **in** s]
review = ' '.join(review)
dataset.loc[i, 'text'] = reviewX_train = dataset['text']
y_train = dataset['output']print("Below is the sample of training text after removing the stop words")
print(dataset['text'][:10])
步骤 8: 现在,我们创建之前创建的 KNN 分类器类的实例,并使用定义的方法“fit”来训练(lazy),然后使用 predict 函数进行预测。我们将使用一些示例文本来进行预测。
我们得到以下依赖于训练数据的预测。
因此,我们定义了使用 nltk 进行文本分类的 KNN 最近算法。如果我们有好的训练数据,这将非常有效。在这个例子中,我们只有 50 个文本的非常小的训练数据,但是它仍然给出了不错的结果。当我们使用 nltk synsets(同义词)时,即使预测中使用的单词/文本不在训练集中,该算法也能很好地执行,因为该算法使用同义词来计算相似性得分。
**未来的改进:**这个算法使用 K = 1。可以对该算法进行进一步的改进,以实现 K 个一般变量。我们也可以在类中实现“proba”函数来提供概率。我们将在这个算法的下一个版本中实现这些特性:-)
参考资料和进一步阅读:
CourseRA——Python 中的应用文本挖掘
使用最先进的 NLP 库 Flair 进行文本分类
Zalando Research 刚刚发布了 Flair - simple Python NLP 库的新版本!
为什么这是 NLP 的大新闻? Flair 在解决自然语言处理问题方面提供了一流的性能,例如命名实体识别(NER)、词性标注(PoS)、词义消歧和文本分类。这是一个建立在 PyTorch 之上的 NLP 框架。
本文解释了如何使用 Flair 来使用现有的和构建定制的文本分类器。
介绍
文本分类是一种受监督的机器学习方法,用于将句子或文本文档分类到一个或多个定义的类别中。这是一项广泛使用的自然语言处理任务,在垃圾邮件过滤、情感分析、新闻文章分类和许多其他商业相关问题中发挥着重要作用。
大多数当前技术水平的方法依赖于一种称为文本嵌入的技术。它将文本转换成高维空间中的数字表示。它允许将文档、句子、单词、字符(取决于我们使用的嵌入方式)表示为高维空间中的向量。
对于 NLP 来说,Flair 是一个令人兴奋的消息,因为 Zalando Research 最近的一篇论文用于序列标记的上下文字符串嵌入 涵盖了一种始终优于以前最先进解决方案的方法。它在 Flair 中得到实现和完全支持,可以用来构建文本分类器。
1.做好准备
要安装 Flair,你需要 Python 3.6 。如果你还没有,这里有一个关于如何做的指南。然后,要安装 Flair,请运行:
pip install flair
这将安装运行 Flair 所需的所有软件包。它还将包括 PyTorch,Flair 位于顶部。
2.使用预先训练的分类模型
新发布的 0.4 带有两个预训练模型。在 IMDB 数据集上训练的情感分析模型和“攻击性语言检测”模型(目前仅支持德语)。
使用、下载和存储模型都被合并到一个方法中,使得使用预训练模型的整个过程出奇地简单。
要使用情绪分析模型,只需运行:
from flair.models import TextClassifier
from flair.data import Sentenceclassifier = TextClassifier.load('en-sentiment')sentence = Sentence('Flair is pretty neat!')
classifier.predict(sentence)# print sentence with predicted labels
print('Sentence above is: ', sentence.labels)
第一次运行时,Flair 将下载情感分析模型,并默认将其存储到主目录的.flair
子文件夹中。这可能需要几分钟时间。
上面的代码首先加载所需的库,然后将情感分析模型加载到内存中(如果需要,可以先下载它),然后预测句子*“Flair 非常漂亮!”在 0 到 1 的刻度上。*最后一条命令打印出来:The sentence above is: [Positive (1.0)]
。
就是这样!例如,现在你可以将代码整合到 REST api 中,并提供类似于 Google 的云自然语言 api 的情感分析的服务,这在大量请求的生产中使用时会被证明是非常昂贵的。
3.训练自定义文本分类器
为了训练一个定制的文本分类器,我们首先需要一个带标签的数据集。Flair 的分类数据集格式基于脸书的快速文本格式。该格式要求在以前缀__label__
开始的每一行的开头定义一个或多个标签。格式如下:
__label__<class_1> <text>
__label__<class_2> <text>
在本文中,我们将使用 Kaggle 的垃圾短信检测数据集来构建一个垃圾/非垃圾分类器。该数据集适合于学习,因为它仅包含 5572 行,并且足够小,可以在 CPU 上在几分钟内训练一个模型。
SMS messages from the dataset labelled as either spam or ham (not spam)
3.1 预处理-构建数据集
我们首先从 Kaggle 上的这个链接下载数据集以获得spam.csv
。然后,在与我们的数据集相同的目录中,我们运行下面的预处理片段,它将进行一些预处理,并将我们的数据集分成训练集、开发集和测试集。
确保你已经安装了熊猫。如果没有,先运行pip install pandas
。
import pandas as pd
data = pd.read_csv("./spam.csv", encoding='latin-1').sample(frac=1).drop_duplicates()data = data[['v1', 'v2']].rename(columns={"v1":"label", "v2":"text"})
data['label'] = '__label__' + data['label'].astype(str)data.iloc[0:int(len(data)*0.8)].to_csv('train.csv', sep='\t', index = False, header = False)
data.iloc[int(len(data)*0.8):int(len(data)*0.9)].to_csv('test.csv', sep='\t', index = False, header = False)
data.iloc[int(len(data)*0.9):].to_csv('dev.csv', sep='\t', index = False, header = False);
这将从我们的数据集中删除一些重复的数据,对其进行混洗(随机化行),并使用 80/10/10 拆分将数据分为训练集、开发集和测试集。
如果运行成功,你将得到以 FastText 格式格式化的train.csv
、test.csv
和dev.csv
,准备与 Flair 一起使用。
3.2 训练自定义文本分类模型
若要定型模型,请在与生成的数据集相同的目录中运行此代码片段。
from flair.data_fetcher import NLPTaskDataFetcher
from flair.embeddings import WordEmbeddings, FlairEmbeddings, DocumentLSTMEmbeddings
from flair.models import TextClassifier
from flair.trainers import ModelTrainer
from pathlib import Pathcorpus = NLPTaskDataFetcher.load_classification_corpus(Path('./'), test_file='test.csv', dev_file='dev.csv', train_file='train.csv')word_embeddings = [WordEmbeddings('glove'), FlairEmbeddings('news-forward-fast'), FlairEmbeddings('news-backward-fast')]document_embeddings = DocumentLSTMEmbeddings(word_embeddings, hidden_size=512, reproject_words=True, reproject_words_dimension=256)classifier = TextClassifier(document_embeddings, label_dictionary=corpus.make_label_dictionary(), multi_label=False)trainer = ModelTrainer(classifier, corpus)trainer.train('./', max_epochs=10)
第一次运行这段代码时,Flair 将下载所有需要的嵌入模型,这可能需要几分钟的时间。整个训练过程还需要 5 分钟。
这个代码片段首先将所需的库和数据集加载到一个 corpus 对象中。
接下来,我们创建一个嵌入列表(两个 Flair 上下文 sting 嵌入和一个 GloVe 单词嵌入)。然后,这个列表被用作我们的文档嵌入对象的输入。堆叠和文档嵌入是 Flair 最有趣的概念之一。它们提供了将不同的嵌入组合在一起的方法。您可以将传统的单词嵌入(如 GloVe、word2vec、ELMo)与 Flair 上下文 sting 嵌入一起使用。在上面的例子中,我们使用了基于 LSTM 的方法来组合单词和上下文串嵌入,以生成文档嵌入。你可以在这里了解更多关于的信息。
最后,代码片段训练模型,产生代表我们存储的训练模型的final-model.pt
和best-model.pt
文件。
3.3 使用训练好的模型进行预测
现在,我们可以通过从同一目录运行以下代码片段,使用导出的模型来生成预测:
from flair.models import TextClassifier
from flair.data import Sentenceclassifier = TextClassifier.load_from_file('./best-model.pt')sentence = Sentence('Hi. Yes mum, I will...')classifier.predict(sentence)print(sentence.labels)
该代码片段打印出’[火腿(1.0)]'【T5],这意味着模型 100%确定我们的示例消息不是垃圾邮件。
与其他框架相比,它的表现如何?
与脸书的 FastText 甚至谷歌的 AutoML 自然语言平台不同,用 Flair 进行文本分类仍然是一项相对低级的任务。我们可以通过设置学习速率、批量大小、退火因子、损失函数、优化器选择等参数选项,完全控制文本嵌入和训练的完成方式……为了实现最佳性能,需要调整这些超级参数。Flair 为我们提供了一个众所周知的 hyper parameter tuning library hyperpt(在这里描述)的包装器,我们可以使用它来调整我们的 hyper parameters 以获得最佳性能。
在本文中,为了简单起见,我们使用了默认的 hyper 参数。使用大多数默认参数**,我们的 Flair 模型**在 10 个周期后获得了 0.973 的 f1 分数。
为了进行比较,我们在 AutoML 自然语言平台上用 FastText 训练了一个文本分类模型。我们首先使用默认参数运行了 FastText ,并获得了 0.883 的 f1 分数,这意味着我们的模型远远超过了 FastText。然而,FastText 只需要几秒钟就可以完成训练,而我们定制的 Flair 模型则需要 5 分钟。
然后,我们还将我们的结果与在谷歌的自动自然语言平台上获得的结果进行了比较。该平台首先需要 20 分钟来解析数据集。之后,我们开始了训练过程,花了近 3 个小时完成(花费了近 10 美元的免费积分),但取得了 99.211 - 的 f1 分数,比我们的定制天赋模型略好。
最后的想法
这篇文章应该让你大致了解如何使用 Flair 进行文本分类。
在下一期出版物中,我们将解释如何调整 Flair 的 hyper 参数以实现最佳性能,并在文本分类方面击败谷歌的 AutoML。
使用递归神经网络的文本生成
从《爱丽丝梦游仙境》生成文本
介绍
文本生成是数据科学和机器学习中的一个热门问题,它适合于递归神经网络。该报告使用 TensorFlow 构建了一个 RNN 文本生成器,并在 Python3 中构建了一个高级 API。该报告的灵感来自于@karpathy ( min-char-rnn )和 Aurélien Géron ( 用 Scikit-Learn 和 TensorFlow 进行动手机器学习)。这是 CST463 中的一个课堂项目——加州州立大学蒙特雷湾分校的高级机器学习,由 Glenn Bruns 博士指导。
模块
Dataset
、RNNTextGenerator
和ModelSelector
是三个主要模块。有关文档,请在 Github 上查看该项目。
资料组
在 src/dataset.py 中定义
创建包含独热编码文本数据的文本数据集。它批量生产编码标签序列。我们将文本数据分成批次用于训练 RNN,并且我们随机抽取文本样本(具有给定长度)来评估我们的模型的性能。
RNNTextGenerator
在 src/text_generator.py 中定义
使用张量流 RNN 单元创建递归神经网络(执行inputs
的动态展开)。它有一个输出投影图层,可生成每个字符类的最终概率。它通过基于当前序列的最后一个字符的概率分布对下一个字符进行采样来生成文本。
我们使用Alice in Wonderland
作为文本。
我们可以看到精度和损耗并没有收敛。每个fit
调用将运行一个时期(我们将epoch=1
传递给了构造函数)。
我们希望在 30 秒内继续用更多的纪元来拟合模型,并且我们对模型如何随着时间的推移而改进感兴趣。
test acc: 0.535040020942688, test loss: 1.592130422592163
Yes, but much towe this NOT, aft open') said 'Letger comimpie hone,
'U VERY up in aborious, it with the adge,
-----------------------
test acc: 0.5360000133514404, test loss: 1.5756181478500366
Yes, but the Habembood cacs must, was the lang donant as perpen my his huril about harriered me shreep), whre
-----------------------
test acc: 0.5430399775505066, test loss: 1.5500394105911255
Yes, but to Alice.
So then
hep datee went orling,' said Alice,' said had geined,' she you not!' said the
nil
-----------------------
test acc: 0.5302400588989258, test loss: 1.6037070751190186
Yes, but the could mould cobl over howner? Now that oplo-thing to her orverewn.'
'Why, to
herself!
The Qu-e
-----------------------
test acc: 0.539199948310852, test loss: 1.6024020910263062
Yes, but the Queen home way the at the placsarnd of the sat a it,' the QUED INK Affece herge how eacushing ov
-----------------------
test acc: 0.5388799905776978, test loss: 1.538255214691162
Yes, but did they rossan that may the sing,' sayeing, round queer thatled thing's she went on, I'm she can wa
-----------------------
test acc: 0.5424000024795532, test loss: 1.5805484056472778
Yes, but first's word.' She was byself, if our it was en!' seemes you se
leasions of the doous rige out oldes
-----------------------
test acc: 0.5455999970436096, test loss: 1.5576822757720947
Yes, but the other--
Whereet heam who her not
one and it didn't knowling e s
-----------------------
我们可以看到,随着时间的推移,生成的文本确实变得更好了。句子中有更多的实词。测试精度和损耗仍在提高。
现在,我们将尝试不同的超参数。
模型选择器
在 src/model_selector.py 中定义
执行随机搜索并按准确度对模型进行排序。它选择最好的排名模型,并允许长时间的搜索(几个小时/几天)。
我们为模型选择器定义了一个大的搜索空间,并给它 24 小时的搜索时间。我们希望它能为Alice in Wonderland
文本发现一个优秀的模式。
选择器看到的最好的模型使用带有320
神经元的GRU Cell
和leaky_relu
作为激活函数。它使用一个学习速率为0.006
的AdamOptimizer
。它在45
个时期中被训练,每批有91
个序列(batch_size)。在 5 个随机采样的测试序列中,它的平均精度为0.6245
,损失1.25
。
Yes, but to talk about this of ketched him in the puppy juging said to the tell messave off, things very unfusts, and that put on hesserriely I’ll make the pu
我们认为epoch
是模型的超参数,因为大量的历元会使神经网络过度拟合,在测试序列上表现不佳。因此,选择器中的最佳模型是我们将使用的最终模型。
最好的文本生成器部署为一个简单的 web 应用程序 ( https://www.ddong.me/alice-text-gen
)用于教育目的。
命令行上的文本挖掘
在过去的几天里,我一直在考虑写一些关于使用原始 bash 命令和正则表达式来挖掘文本的经验。当然,网上有更复杂的工具和库来处理文本,而不用写那么多行代码。例如,Python 有内置的 regex 模块“re ”,它有许多处理文本的丰富特性。另一方面,“BeautifulSoup”有很好的内置功能来清理原始网页。我使用这些工具来更快地处理大型文本语料库,并在我觉得懒得写代码时使用。
大多数时候,我更喜欢使用命令行。我在命令行上感觉很自在,尤其是当我处理文本数据的时候。在本教程中,我使用 bash 命令和 regex 来处理原始和杂乱的文本数据。我假设读者对 regex 和 bash 命令有基本的了解。
我展示了如何将 bash 命令如’ grep ‘、’ sed ‘、’ tr ‘、’ column ‘、’ sort ‘、’ uniq ‘、’ awk '与 regex 一起使用来处理原始和混乱的文本,然后提取信息。作为一个例子,我使用了与世界图书馆合作的古登堡计划提供的莎士比亚全集。
先看文件
莎士比亚作品的全部作品都可以从这个链接下载。我下载了莎士比亚的全部作品,并将其放入一个文本文件:“Shakespeare.txt”。好了,现在让我们开始查看文件大小:
ls -lah shakes.txt***### Display:***
-rw-r--r--@ 1 sabber staff 5.6M Jun 15 09:35 shakes.txt
ls '是 bash 命令,它列出了某个目录中的所有文件和文件夹。-l '标志显示文件类型、所有者、组、大小、日期和文件名。-a '标志用于显示所有文件,包括隐藏的文件。标志“h”-我最喜欢的标志之一,因为它显示文件大小,这是人类可读的格式。shakes.txt 的大小是 5.6 兆字节。
探索者正文
好了,现在让我们读一下文件,看看里面有什么。我使用“less”和“tail”命令来浏览文件的各个部分。命令的名称说明了它们的功能。“less”用于一次一屏地查看文本文件的内容。它类似于“more ”,但具有允许在文件中向前和向后导航的扩展功能。“N”标志可用于定义行号。同样,“tail”显示了文件的最后几行。
less -N shakes.txt***### Display:***
1 <U+FEFF>
2 Project Gutenberg’s The Complete Works of William Shakespeare, by William
3 Shakespeare
4
5 This eBook is for the use of anyone anywhere in the United States and
6 most other parts of the world at no cost and with almost no restrictions
7 whatsoever. You may copy it, give it away or re-use it under the terms
看起来前几行不是莎士比亚的作品,而是一些关于古腾堡计划的信息。同样,文件末尾也有一些与莎士比亚作品无关的行。因此,我将使用“sed”删除文件中所有不必要的行,如下所示:
cat shakes.txt | sed -e '149260,149689d' | sed -e '1,141d' > shakes_new.txt
上面的代码片段删除了尾部从 14926 到 149689 的行,然后删除了前 141 行。不想要的行包括一些关于法律权利,古腾堡的项目和工作内容的信息。
基本分析
现在让我们使用‘pipe |’和‘awk’对文件进行一些统计。
cat shakes_new.txt | wc | awk '{print "Lines: " $1 "\tWords: " $2 "\tCharacter: " $3 }'**### Display**
Lines: 149118 Words: 956209 Character: 5827807
在上面的代码中,我首先使用“cat”提取文件的整个文本,然后输入“wc”来计算行数、字数和字符数。最后,我用‘awk’来显示信息。计数和显示的方式可以用许多其他方式来完成。请随意探索其他可能的选择。
文本处理
现在是清理文本以便进一步分析的时候了。清理包括,将文本转换为小写,删除所有数字,删除所有标点符号,删除高频词(停用词)。处理不限于这些步骤,这取决于目的。由于我打算展示一些基本的文本处理,所以我只关注上面的步骤。
首先,我把所有的大写字符/单词转换成小写,然后去掉所有的数字和标点符号。为了执行处理,我使用 bash 命令“tr ”,它翻译或删除文本文档中的字符。
cat shakes_new.txt | tr 'A-Z' 'a-z' | tr -d [:punct:] | tr -d [:digit:] > shakes_new_cleaned.txt
上面的代码片段首先将整个文本转换为小写,然后删除所有标点符号和数字。上述代码的结果:
**### Display before:**
1 From fairest creatures we desire increase,
2 That thereby beauty’s rose might never die,
3 But as the riper should by time decease,
4 His tender heir might bear his memory:
5 But thou contracted to thine own bright eyes,
6 Feed’st thy light’s flame with self-substantial fuel,
7 Making a famine where abundance lies,
8 Thy self thy foe, to thy sweet self too cruel:
9 Thou that art now the world’s fresh ornament,
10 And only herald to the gaudy spring,
11 Within thine own bud buriest thy content,
12 And, tender churl, mak’st waste in niggarding:
13 Pity the world, or else this glutton be,
14 To eat the world’s due, by the grave and thee. **### Display after:** 1 from fairest creatures we desire increase
2 that thereby beautys rose might never die
3 but as the riper should by time decease
4 his tender heir might bear his memory
5 but thou contracted to thine own bright eyes
6 feedst thy lights flame with selfsubstantial fuel
7 making a famine where abundance lies
8 thy self thy foe to thy sweet self too cruel
9 thou that art now the worlds fresh ornament
10 and only herald to the gaudy spring
11 within thine own bud buriest thy content
12 and tender churl makst waste in niggarding
13 pity the world or else this glutton be
14 to eat the worlds due by the grave and thee
标记化是自然语言处理中的基本预处理之一。标记化可以在单词或句子级别上执行。在本教程中,我将展示如何对文件进行标记。在下面的代码中,我首先使用“cat”提取干净的文本,然后使用“tr”及其两个标志:“s”和“c”将每个单词转换成行。
cat shakes_new_cleaned.txt | tr -sc ‘a-z’ ‘\12’ > shakes_tokenized.txt**### Display (First 10 words)** 1 from
2 fairest
3 creatures
4 we
5 desire
6 increase
7 that
8 thereby
9 beautys
10 rose
现在我们已经把所有的单词都标记出来了,我们可以回答这样一个问题,在整个莎士比亚作品中最常用/最不常用的单词是什么?为此,我首先使用’ sort ‘命令对所有单词进行排序,然后使用带有’-c ‘标志的’ uniq '命令找出每个单词的频率。“uniq -c”与 Pandas 或 SQL 中的“groupby”相同。最后,根据单词出现的频率,按升序(最不频繁)或降序(最频繁)对单词进行排序。
*cat shakes_tokenized.txt | sort | uniq -c | sort -nr > shakes_sorted_desc.txt***### Display**29768 the 28276 and 21868 i 20805 to 18650 of 15933 a 14363 you 13191 my 11966 in 11760 that*cat shakes_tokenized.txt | sort | uniq -c | sort -n > shakes_sorted_asc.txt***### Display**1 aarons 1 abandoner 1 abatements 1 abatfowling 1 abbominable 1 abaissiez 1 abashd 1 abates 1 abbeys 1 abbots
上述结果揭示了一些有趣的观察结果。例如,十个最常用的单词不是代词就是介词或连词。如果我们想找出更多关于作品的抽象信息,我们必须去掉所有的停用词(介词、代词、连词、情态动词等。).也要看对象的用途。人们可能只对介词感兴趣。在这种情况下,保留所有的介词是没问题的。另一方面,最不常用的词是“放弃”、“减少”、“羞愧”。
删除停止字
在下一步中,我将展示“awk”的用法,以删除命令行中的所有停用词。在本教程中,我使用了 NLTK 的英语停用词列表。我还增加了几个单词。以下代码的细节可以在这个 StackOverflow 的回答中找到。awk 不同选项的详细信息也可以在 awk 的手册中找到(命令行上的‘man awk ’)
awk ‘FNR==NR{for(i=1;i<=NF;i++)w[$i];next}(!($1 in w))’ stop_words.txt *shakes_tokenized*.txt > shakes_stopwords_removed.txt
好了,去掉停用词后,让我们像上面一样按升序和降序排列单词。
*cat* shakes_stopwords_removed*.txt | sort | uniq -c | sort -nr > shakes_sorted_desc.txt***### Display most frequent**3159 lord 2959 good 2924 king 2900 sir
2634 come 2612 well 2479 would 2266 love
2231 let 2188 enter*cat* shakes_stopwords_removed*.txt | sort | uniq -c | sort -n > shakes_sorted_asc.txt***### Display least frquent**1 aarons 1 abandoner 1 abatements 1 abatfowling 1 abbominable 1 abaissiez 1 abashd 1 abates 1 abbeys 1 abbots
我们看到莎士比亚最常用的词是“主”,后面是“好”。“爱”这个词也是出现频率最高的词。最不常用的词保持不变。语言学或文学专业的学生可能会从这些简单的分析中解读信息或获得更好的洞察力。
我们来讨论一下
由于我们已经完成了一些必要的处理和清理,在下一篇教程中,我将讨论如何执行一些高级分析。在那之前,如果你有任何问题,请随意提问。看到错别字、错误或者有更好的建议请评论。你可以联系我:
Email: sabbers@gmail.com
LinkedIn: [https://www.linkedin.com/in/sabber-ahamed/](https://www.linkedin.com/in/sabber-ahamed/)
Github: [https://github.com/msahamed](https://github.com/msahamed)
Medium: [https://medium.com/@sabber/](https://medium.com/@sabber/)
文本挖掘:Twitter 提取和逐步引导生成词云
我看过很多帖子,作者谈论使用 tweets 生成单词云,但没有多少人谈论如何将你的设备连接到 Twitter 以生成单词云。这是非常简单但非常重要的一步(显然,我们将使用这些推文生成一个单词云)。在我们开始技术部分之前,重要的是理解我们为什么需要从 twitter 中提取数据,或者让我们只说从任何社交媒体平台,如 Twitter,facebook,LinkedIn 等。假设你在市场上推出了一个产品或方案,你想分析人们对它的看法。这也叫 风险感知 和 情绪分析。 它有助于确定人们对你的产品的看法,通过分析这些平台的数据,你可以很容易地知道对你的产品的评价是正面还是负面。相信我,它也能帮助你改变商业策略。
那么,我们开始吧。
连接 R 和 twitter 的步骤:
1.创建一个 Twitter 帐户。**不要忘记添加您的手机号码。**2
2。一旦您在 twitter 上创建了您的帐户,请访问以下链接创建您的第一个 Twitter 应用程序
http://apps.twitter.com
3.点击创建新应用程序。为您的应用程序选择一个唯一的名称,并提供应用程序的简要描述。在“网站”中,您可以提供您的任何个人资料链接(我已经给出了我的 LinkedIn 个人资料链接)。
4。点击“创建您的 Twitter 应用程序”。您的应用程序已创建,看起来应该如下所示:
Figure 1: Twitter application
5.打开您的应用程序,进入“密钥和访问令牌”查看您的消费者密钥(API 密钥)和消费者秘密(API 秘密)密钥。我把我的藏起来了,但是一旦你站在这个舞台上,你就应该看到你的了。在某个地方记下两把钥匙。
Figure 2.1: Important Keys and Tokens 1
6.如果您是第一次这样做,那么您必须向下滚动到同一个“密钥和访问令牌”页面,并生成您的访问令牌。记录访问令牌和访问令牌密码以及您的消费者密钥。
Figure 2.2: Important Keys and Tokens 2
是时候打开你的 R 工作室了。
1.安装必要的软件包并加载库。安装这些包很重要,因为它们允许 R interface 与 twitter 连接,并对第三方应用程序进行认证。
Figure 3: R packages
2.是时候使用以下命令建立连接了。
Figure 4: Setting up the connection
3.R 与 Twitter 通信的环境和连接已经建立,现在终于可以提取一些 tweets 了。有几个命令可以用来提取用户的推文,或者通过使用特定的 单词 。在这里你应该非常聪明,对你的提取非常挑剔(知道你想要提取和分析什么)。我们都知道脸书和剑桥分析杂志的问题,以及马克·扎克伯格在国会山的听证会 ( 他被拷问并失去了他的眉毛) 。对于本教程,我将提取最近使用“扎克伯格”一词的前 1500 条推文。
Figure 5: Tweets Extraction
一旦你提取了推文,开始玩它。在分析数据之前先了解它。从检查结构、类别开始,查看 5-10 条最近的推文。您还可以使用 *nchar()计算每条 tweet 的字符数。*探索更多。
Figure 6: Ten recent tweets
现在我们已经学会了如何提取推文,是时候学习如何使用这些推文,并从中获取一些重要信息了。在接下来的几个步骤中,我们将学习如何清理文本数据,创建语料库和文档术语矩阵,生成词云并从中获取一些有用的信息。请注意,我们今天要做的文本数据的数据准备可以用来准备任何文本数据。
请按照以下步骤准备您的数据以供进一步分析。这些步骤不言自明。
Figure 7: Data preparation pipeline
词云
词云是基于文档的词频,也就是说词的最大使用次数越大。了解一些真知灼见会非常有用。按照代码创建术语文档矩阵和词云。不一定要保持相同的参数。
Figure 8: Term document matrix
分析单词 cloud
似乎像 数据、百万、用户、隐私、信息、监狱 等词在提取的推文中被使用了几次。这些单词有时可能没有意义,但如果在上下文中阅读,它可以讲述一个价值百万美元的故事。
Figure 9: Word Cloud
附注:马克·扎克伯格不会进监狱。还没有。