使用梯度提升机和H2O库进行自然语言处理
[H2O]是一个开源的、用于机器学习的内存平台。H2O提供了许多流行算法的实现。它同时支持有监督和无监督的机器学习算法。
H20支持以下算法。[Naive Bayes算法],[随机森林],[梯度提升机],[广义线性模型],[K-Means算法],[主成分分析]和[深度神经网络]。
H2O是快速和可扩展的,使其成为构建机器学习模型的最佳平台。它还可以通过[H2O的AutoML]管道实现机器学习的自动化。
在本教程中,我们将重点介绍梯度提升机。这种算法可以建立分类和回归模型。在梯度提升机中,我们依次训练多个决策树。然后将它们结合起来,创建一个最终模型。
我们将使用梯度提升机来训练一个自然语言处理模型。该模型将进行情感分析。它将把客户评论分类为正面或负面。
前提条件
要跟上本教程,你需要熟悉。
- [自然语言处理]。
- [文本预处理的步骤]。
- [流行的机器学习算法]。
- 机器学习中的[集合学习技术]。
注意:你必须使用谷歌Colab笔记本来建立模型。Google Colab笔记本有快速的CPU和GPU。
梯度提升机简介
如前所述,梯度提升机依次训练了多个决策树。然后,这些决策树被组合起来,形成一个最终的模型。最初的决策树模型是基础模型或弱学习者。
Boosting使用一系列算法将弱学习者转化为强学习者。它最小化/减少了训练误差。选择一个随机的数据样本,用一个模型进行拟合,然后依次进行训练。
由于高方差或高偏差,弱的学习者可能不会单独表现良好。然而,当我们把弱的学习者集合起来时,它们就形成了一个强的学习者。它们的组合可以减少偏差或方差,产生更好的模型性能。
让我们开始使用H2O。
开始使用H2O
为了使用H2O,我们要安装一些依赖项。H2O依赖于64位的JDK来运行。它使用的是Java编程语言。要安装64位JDK,请运行此命令。
!apt-get install default-jre
!java -version
安装完依赖项后,用以下命令安装H2O。
!pip install h2o
这个命令将安装最新的H2O版本。要导入H2O,请使用此代码。
import h2o
初始化H2O
我们使用下面的代码来初始化H2O。
h2o.init()
初始化H2O将使我们能够连接到H2O集群。因此,我们将使用其内存进行机器学习。当我们运行上面的代码时,它产生了以下输出。

从上面的图片来看,我们已经成功连接到了H2O集群。它还显示了集群的版本和集群的总可用内存。下一步是加载数据集。
情感分析的数据集
我们将使用亚马逊的数据集。它有顾客对个人护理用品的评论。
我们从tensorflow_datasets 。tensorflow_datasets 是一个TensorFlow资源库,其中包含随时可用的数据集。要导入tensorflow_datasets ,使用这个代码。
import tensorflow_datasets as tfds
要从tensorflow_datasets 下载数据集,使用以下代码。
dowloaded_dataset, dataset_info = tfds.load('amazon_us_reviews/Personal_Care_Appliances_v1_00', with_info=True, batch_size=-1)
从上面的代码中,我们使用tfds.load 方法从tensorflow_datasets 资源库加载数据集。然后我们将使用下面的代码将数据集保存到train 变量中。
train_dataset = dowloaded_dataset['train']
要查看数据集的信息,请运行这个命令。
dataset_info
它产生的输出如下。

从上面的图片来看,该数据集有超过1.3亿条顾客评论。我们将使用以下列作为输入:review_body,review_headline,star_rating, 和helpful_votes 。
-
review_body:它显示了产品评论的详细描述。 -
review_headline:它显示了评论的标题。 -
star_rating:它显示购买产品的1-5星评级。 -
helpful_votes:它显示了给亚马逊产品的投票数。
在加载数据集后,我们需要使用NumPy将亚马逊数据集转换为一个NumPy数组。NumPy数组很容易操作和使用。
将数据集转换为数组
要导入NumPy包,请使用以下代码。
import numpy as np
我们使用Numpy将数据集转换成数组,使用下面的代码。
dowloaded_dataset=tfds.as_numpy(train_dataset)
要看到数据集的数组,请运行这段代码。
dowloaded_dataset
它产生的输出如下。

从上面的图片来看,亚马逊的数据集是在NumPy数组中。接下来,我们需要选择我们将用于建立情感分析模型的列。
选择列
要选择这些列,请使用这段代码。
review_body=dowloaded_dataset['data']['review_body']
review_headline=dowloaded_dataset['data']['review_headline']
helpful_votes=dowloaded_dataset['data']['helpful_votes']
rating=dowloaded_dataset['data']['star_rating']
上面的代码从我们的数据集中选择了四列。这四列是模型在训练阶段的输入。然后我们将使用H2O DataFrame函数创建一个DataFrame。DataFrame是一种数据结构,它将数据组织成一个行和列的二维表格。
创建数据框
我们将使用H2O DataFrame函数创建DataFrame。
h2o_df=h2o.H2OFrame(np.hstack((helpful_votes[:,None],review_headline[:,None],review_body[:,None],rating[:,None])),column_names=['votes','headline','reviews','rating'],column_types=['numeric','string','string','numeric'])
上面的代码将使用h2o.H2OFrame 函数创建一个DataFrame。该函数也被分配了人类可读的列名。指定的列名如下。votes,headline,reviews, 和rating 。
要查看创建的DataFrame,请运行这段代码。
h2o_df
该代码产生以下输出。

添加输出列
我们需要给我们的DataFrame添加一个输出列。输出列包含模型进行预测后的输出。该模型将把客户的评论分类为正面或负面。我们用1 表示正面评论,而用0 表示负面评论。
如果客户的评论是正面的,star_rating 应该大于4 。如果star_rating 小于4 ,该评论就是负面的。为了增加输出列,我们将使用这个逻辑。
我们使用下面的代码来表示这个逻辑。
h2o_df["output"] = h2o_df["rating"].apply(lambda x: 1 if x>= 4 else 0)
当我们执行该代码时,它将添加输出列。要想看到添加了输出列的新数据框,请使用这段代码。
h2o_df
它产生以下输出。

下一步是进行文本预处理。
文本预处理
文本处理是自然语言处理的一个重要步骤。在文本预处理中,我们对数据集进行清理并去除噪音。文本处理使我们的数据集准备好供模型使用。
在本教程中,我们将进行的一些文本预处理步骤如下。
-
去除停顿词。停止词是任何语言中最常见的词。停止词是指冠词、介词、代词和连词。它们不会给文本增加多少信息。
-
将文本转换为小写字母。将文本转换为小写,确保我们有一个统一的数据集。
-
符号化。符号化是将文本分割成较小的单词单位,称为标记。
在本教程中,我们将只执行三个步骤。我们将使用自然语言工具箱(NLTK)。
安装自然语言工具箱
我们用这个命令来安装自然语言工具包(NLTK)。
!pip install nltk
要导入nltk ,请使用此代码。
import nltk
现在让我们使用nltk 来进行文本预处理。
下载止损词
停止词是某一语言中最常用的词。停止词携带的信息非常少,对模型的影响也不大。去除停顿词将使模型专注于数据集中的独特词汇。
我们将使用nltk ,下载英语语言的停止词。
from nltk.corpus import stopwords
nltk.download('stopwords')
stop_words = set(stopwords.words('english'))
然后,我们将从数据集中过滤掉这些停顿词。我们将创建一个单一的函数,删除停止词,进行标记化,并将文本转换为小写。
创建该函数
我们使用下面的代码片断来创建这个函数。
def tokenize(line):
tokenized = line.tokenize("\\W+")
tokenized = tokenized.tolower()
tokenized = tokenized[(tokenized.nchar() >= 2) | (tokenized.isna()),:]
tokenized_filter = tokenized[(tokenized.isna()) | (~ tokenized.isin(stop_words)),:]
return tokenized_filter
函数名称为tokenize 。在这个函数中,line.tokenize 方法执行标记化。tokenized.tolower 方法将文本转换为小写。(~ tokenized.isin(stop_words)) 将对停止词列表中没有的词进行标记化。它将过滤掉数据集中的停止词。然后,该函数返回一个经历了所有三个步骤的干净文本。让我们把这个函数应用于我们的reviews 和headline 列。
应用该函数
reviews 和headline 列包含文本。要在这两列中应用该函数,请使用以下代码。
words_reviews = tokenize(h2o_df["reviews"])
words_headline = tokenize(h2o_df["headline"])
要查看应用函数后的reviews 列,请使用这段代码。
words_reviews.head()
它产生以下输出。

要查看应用函数后的headline 列,请使用这段代码。
words_headline.head()
它产生的输出结果如下。

上面的步骤显示了如何删除停顿词,将文本转换成小写字母,并进行标记化。下一步是对标记化后的文本进行矢量化。
矢量化
矢量化将标记化的文本转换为一个数字列表。这个数字列表被称为词向量,模型将其作为输入。机器并不理解文本。这就是为什么我们需要将文本转换为数字形式(数字列表)。在H2O中,我们使用H2OWord2vecEstimator 算法,将标记化的文本转换为词向量。
要进一步了解H2OWord2vecEstimator 算法如何将标记化的文本转换为字向量,请阅读以下文档
我们使用以下代码导入H2OWord2vecEstimator 。
from h2o.estimators.word2vec import H2OWord2vecEstimator
H2OWord2vecEstimator 算法训练了一个模型,该模型将执行矢量化。为了使用训练好的模型,我们将其应用于words_reviews 和words_headline 列。矢量化模型产生相应的词向量。
现在我们来训练矢量化模型。
训练矢量化模型
我们将使用words_reviews 和words_headline 列来训练矢量化模型。我们使用下面的代码。
vec_model = H2OWord2vecEstimator(vec_size = 100, model_id = "w2v_amazon.model")
vec_model.train(training_frame=words_reviews)
vec_model.train(training_frame=words_headline)
从上面的代码中,我们使用以下方法和参数。
vec_size = 100:它表示词向量将有的列数。
-model_id = "w2v_amazon.model" 。它是我们的矢量化模型的名称。
vec_model.train:它是训练矢量化模型的函数。
然后,我们将training_frame 作为参数传递。它指定了训练矢量化模型的列。我们同时使用words_reviews 和words_headline 列来训练模型。
上面的代码将建立我们的矢量化模型。
保存矢量化模型
要保存模型,请使用这段代码。
h2o.save_model(vec_model,path='./')
保存模型后,我们现在可以用它来将标记化的文本转化/转换为词向量。
应用该模型
我们将把训练好的模型应用于words_reviews 和words_headline 列。这两列包含标记化的文本。
words_reviews 列
review_vecs = vec_model.transform(words_reviews, aggregate_method = "AVERAGE")
vec_model.transform 函数将标记化文本转换/转化为词向量。该函数有以下参数。
-
words_reviews:它是输入列。 -
aggregate_method = "AVERAGE":它指定了函数将如何聚合标记化的词。"AVERAGE",将确保词在转换后不会失去意义。
要查看转换后的词向量的大小,请使用此代码。
review_vecs.shape
它产生的输出如下。
(85981, 100)
从上面的输出中,我们有85981 字向量。要查看转换后的词向量的输出,请使用这段代码。
review_vecs.head()
它产生以下输出。

从上面的图片中,我们已经转换了words_reviews 列。
我们还用同样的过程对words_headline 列进行了矢量化。
words_headline 列
我们将使用下面的代码。
headline_vecs = vec_model.transform(words_headline, aggregate_method = "AVERAGE")
headline_vecs.names = ["headline_" + s for s in headline_vecs.names]
我们使用相同的vec_model.transform 函数对words_headline 列进行矢量化。我们还使用相同的aggregate_method = "AVERAGE" 参数来执行矢量化。
要查看矢量化后的文本,请使用这段代码。
headline_vecs.head()
它产生的输出如下。

从上面的图片来看,我们已经转换了words_headline 列。
我们将使用review_vecs 和headline_vecs 作为我们模型的输入。我们需要将它们添加/附加到原始DataFrame中。
将矢量列添加到数据框中
我们将使用cbind 函数将矢量列添加/附加到原始的h2o_df 数据框架中。
h2o_df_ext=h2o_df.cbind(review_vecs)
h2o_df_ext = h2o_df_ext.cbind(headline_vecs)
cbind 函数将把review_vecs 数据框添加到h2o_df 。同一函数还将headline_vecs 数据框添加到创建的h2o_df_ext 。
合并所有的数据框架后,我们将最终的h2o_df_ext 数据框架分成两组。第一组是用于模型训练,第二组是用于模型验证。
分割数据框
我们把数据集分成两组。一个用于训练,另一个用于验证,使用此代码。
h2o_train,h2o_valid = h2o_df_ext.split_frame(ratios=[.8])
模型将从训练集中学习,以了解情感分析。验证集将在训练中对模型的超参数进行微调。
我们使用.8 。80%的数据框将是训练集,20%将是验证集。
让我们使用梯度提升机来训练模型。
使用梯度提升机进行模型训练
我们将从H2O库中导入H2OGradientBoostingEstimator 算法。它是训练模型的算法。
from h2o.estimators import H2OGradientBoostingEstimator
让我们初始化H2OGradientBoostingEstimator 。我们还将设置将产生最佳结果的超参数。
Gradient_Boosting_Machine= H2OGradientBoostingEstimator(ntrees=100,
max_depth = 6, learn_rate=0.1
)
初始化的H2OGradientBoostingEstimator 算法有以下参数。
-
ntrees:它指定了用于建立模型的决策树的数量。我们将树的数量设置为100。H2OGradientBoostingEstimator算法将依次创建100棵决策树。然后,它将它们结合起来,创建一个具有最佳结果的最终模型。 -
max_depth:它是所用决策树的最大深度。我们将该值设置为6。增加max_depth值可能会导致模型过拟合。 -
learn_rate:它规定了训练期间模型的学习率。
在初始化模型后,我们用准备好的数据集喂养模型。
用数据集喂养模型
要用数据集喂养模型,请使用这段代码。
Gradient_Boosting_Machine.train(x=headline_vecs.names+review_vecs.names, y='output', training_frame = h2o_train, validation_frame=h2o_valid)
从上面的代码中,train 函数训练了模型。它有以下参数。
-
x变量。它是包含所有输入列的变量。 和 是输入列。headline_vecsreview_vecs -
y变量。它是包含输出列的变量。 -
training_frame:它指定了用于训练的DataFrame。我们使用h2o_trainDataFrame进行训练。 -
validation_frame:它指定了我们将用于验证的数据框架。我们使用h2o_valid数据框进行验证。
该算法将对模型进行训练,并给出最佳的准确性分数。
准确率得分
要获得准确率分数,请使用此代码。
print(" Hyperparameter AUC: " + str(round(Gradient_Boosting_Machine.auc(valid = True), 3)))
上面的代码将打印准确率分数。
Hyperparameter AUC: 0.934
准确率得分是0.934 ,是93.4%。这是一个很高的准确率分数,表明该模型训练有素。我们现在可以使用这个模型来进行预测。
进行预测
我们使用该模型将客户评论分类为负面或正面。
predictions = ["The shippers and loaders were great....willing to consider speedier shipping options, the good news is that at the end the shipping arrived quickly enough"]
让我们对这个文本输入进行矢量化。
predictions = vec_model.transform(predictions)
矢量化之后,我们使用矢量化的文本进行预测。
prediction_result = Gradient_Boosting_Machine.predict(predictions)
print(prediction_result)
它产生的预测结果如下。
array([1])
预测结果是1 ,是一个正面评论。从上面的预测结果来看,我们的模型可以做出准确的预测。
总结
在本教程中,我们建立了一个情感分析模型。我们使用梯度提升机和H2O库创建了这个模型。该教程还包括文本预处理。我们对数据集进行了清理并去除噪音。最后,我们使用H2OGradientBoostingEstimator 算法来训练模型。最终的模型能够做出准确的预测。