数据建模步骤文档_一种使用向量空间建模和PCA的文本分类方法

假设您有很多正面和负面标记的电影评论。现在,如果您必须开发一些自动算法来判断新的评论报道是正面还是负面,您如何采用最简单的方法?

当然,你必须应用标准的ML分类技术(从问题陈述中,可以很容易地理解它是一个分类问题)。但这里的问题是大量的文本数据。那些不是数字,那么如何让计算机/算法理解评论的重要性?让我们采取一步一步的方法

从源获取数据

样本电影评论可在康奈尔大学门户网站(http://www.cs.cornell.edu/people/pabo/movie-review-data/)上找到。你可以下载“polarity dataset v2.0”。这个数据集包含两个名为“pos”和“neg”的文件夹,每个文件夹下有1000个文件。每个文件都有以纯文本格式编写的评论内容。你可以阅读和输出使用下面的Python代码片段的数据集:

import pandas as pdimport pathlib as pldef _read_all_reviews_(): all_reviews = [] for p in pl.Path('../data/txt_sentoken/pos').iterdir(): file = open(p, 'r') all_reviews.append({'reviews_content': file.read(), 'category': 'positive'}) file.close() for p in pl.Path('../data/txt_sentoken/neg').iterdir(): file = open(p, 'r') all_reviews.append({'reviews_content': file.read(), 'category': 'negative'}) file.close() all_reviews_df = pd.DataFrame(all_reviews) return all_reviews_dfprint(_read_all_reviews_())
81dea050b57c4dd60cb9449061e54669.png

ML传递路径的概念

传递路径创建遵循任何ML算法执行的最佳实践。但是,如果不创建路径也可以执行ML算法。但路径让你的生活变得轻松。让我们先了解“路径”的含义是什么?

大多数ML算法需要票价数据预处理。所有这些预处理和实际算法都可以配置为单独的可重用步骤。所有这些步骤在一个实体中与输入和输出连接在一起称为“路径”。

创建向量空间模型

路径中的第一步是将数据转换为数值,因为它当前是纯文本格式。有标准模型可用,如“Tf-Idf”,“Word2Vec”,“Doc2Vec”等。所有这些在文本分析中称为“向量空间模型”,并且每个都只提供文本数据的数字向量表示。此向量用作文档的特征向量,并确定将有多少特征。我使用“Doc2Vec”作为此问题的模型,因为每个评论都可以被视为一个单独的文档,“Doc2Vec”在理解文本的上下文含义方面非常有效(与Tf-Idf相比,这只是纯粹的基于频率的模型)。通过针对随机采样的单词的邻域字训练神经网络来生成文档的“Doc2Vec”,反之亦然。这里,只有隐藏层的学习权重才是关键的问题,并被视为“Doc2Vec”值。事实上,有两种技术:分布式存储器(DM)和分布式单词包(DBOW)。有关详细信息,您可以浏览以下资源:

  • Rare Technolgies的Doc2Vec教程(https://rare-technologies.com/doc2vec-tutorial/)
  • 句子和文档的分布式表示(https://cs.stanford.edu/~quocle/paragraph_vector.pdf)

以下Python代码片段用作路径步骤,用于为文档创建Doc2Vec:

from sklearn.pipeline import Pipelinefrom sklearn.decomposition import PCAfrom gensim.models.doc2vec import TaggedDocument, Doc2Vecfrom sklearn.base import BaseEstimator, TransformerMixinfrom sklearn.linear_model import LogisticRegressionfrom sklearn.model_selection import train_test_splitfrom gensim.parsing.preprocessing import preprocess_stringfrom sklearn import utilsfrom tqdm import tqdmclass Doc2VecTransformer(BaseEstimator): def __init__(self, vector_size=100, learning_rate=0.02, epochs=20): self.learning_rate = learning_rate self.epochs = epochs self._model = None self.vector_size = vector_size self.workers = multiprocessing.cpu_count() def fit(self, df_x, df_y=None): tagged_x = [TaggedDocument(preprocess_string(row['reviews_content']), [index]) for index, row in df_x.iterrows()] model = Doc2Vec(documents=tagged_x, vector_size=self.vector_size, workers=self.workers) for epoch in range(self.epochs): model.train(utils.shuffle([x for x in tqdm(tagged_x)]), total_examples=len(tagged_x), epochs=1) model.alpha -= self.learning_rate model.min_alpha = model.alpha self._model = model return self def transform(self, df_x):return np.asmatrix(np.array([self._model.infer_vector(preprocess_string(row['reviews_content'])) for index, row in df_x.iterrows()]))
066d9046171b5af66412ee124ceb7da6.png

在上面的代码片段中,“vector_size”参数确定每个文档的向量长度。基本上它是如上所述的文档的提取特征的数量。这些特征具有“虚拟性”,并且这些特征难以可视化。你可以说,它没有任何重要性,但这些为数学建模增添了很大的价值。您可以看到模型经过多次重复训练并具有调整的学习速率。这只是为了获得更好的结果。“vector_size”和“learning_rate”可以作为超参数来调整模型。最终结果是,Doc2Vec功能以矩阵形式返回,其中行是文档编号,列是特征值。

Doc2Vec的PCA建模

正如您所看到的,Doc2Vec可以根据您在参数“vector_size”中传递的值生成大量特征,因此将其简化为相关特征集总是很方便。主成分可以在这里发挥重要作用。因此,您的路径的下一步将是对Doc2Vec进行PCA转换。主成分也是“Doc2Vec”等虚拟特征,难以可视化/概念化,但对数学建模很有用。您可以在PCA转换器中传递“n_components”作为参数(无主成分)。因此,您将获得PCA向量。显然,你的“n_components”应该比“vector_size”小得多,可能是它的一半或三分之一。

拟合逻辑回归分类器

在完成PCA之后,您可以在二元逻辑回归分类器中拟合PCA向量(因为这里输出分类变量只能有两个值:“正”和“负”)这将是您路径中的最后一步。根据PCA向量值,此分类器将预测电影评论是正面还是负面。

整个路径显示在下面的python代码片段中:

def train_and_build_model(): all_reviews_df = _read_all_reviews_() train_x_df, test_x_df, train_y_df, test_y_df = train_test_split(all_reviews_df[['reviews_content']], all_reviews_df[['category']]) pl = Pipeline(steps=[('doc2vec', Doc2VecTransformer(vector_size=220)), ('pca', PCA(n_components=100)), ('logistic', LogisticRegression()) ]) pl.fit(train_x_df[['reviews_content']], train_y_df[['category']]) predictions_y = pl.predict(test_x_df[['reviews_content']]) print('Accuracy: ', metrics.accuracy_score(y_true=test_y_df[['category']], y_pred=predictions_y))
d90cd60bad99d0fb7228f4cee17d8676.png

现在,您可能会想到我将“n_components”的值设置为100,将“vector_size”设置为220。您可以在此处传递任何值。通常对于Doc2Vec,“vector_size”保持在100和300之间。但对于PCA,由您决定要保留多少主成分以保持数据的充分可变性。“vector_size”和“n_components”都是“超参数”。

使用网格搜索调整超参数

Python中的网格搜索库为您提供了查找最优超参数集的机制。您可以提供一系列可能的值,以便从分类器模型中获得最佳精度。以下Python代码片段可以为您提供:

from sklearn.model_selection import GridSearchCVdef train_long_range_grid_search(): all_reviews_df = _read_all_reviews_() train_x_df, test_x_df, train_y_df, test_y_df = train_test_split(all_reviews_df[['reviews_content']], all_reviews_df[['category']]) pl = Pipeline(steps=[('doc2vec', Doc2VecTransformer()), ('pca', PCA()), ('logistic', LogisticRegression()) ]) param_grid = { 'doc2vec__vector_size': [x for x in range(100, 250)], 'pca__n_components': [x for x in range(1, 50)] } gs_cv = GridSearchCV(estimator=pl, param_grid=param_grid, cv=5, n_jobs=-1, scoring="accuracy") gs_cv.fit(train_x_df[['reviews_content']], train_y_df[['category']]) print("Best parameter (CV score=%0.3f):" % gs_cv.best_score_) print(gs_cv.best_params_) predictions_y = gs_cv.predict(test_x_df[['reviews_content']]) print('Accuracy: ', metrics.accuracy_score(y_true=test_y_df[['category']], y_pred=predictions_y))
5bec4eac380ad5061b0ecfa57966b06c.png

但是上面的这个将花费大量时间来获得最优集。因此,简而言之,您可以减少可能的范围并仍然获得或多或少的最优集。

def train_short_range_grid_search(): all_reviews_df = _read_all_reviews_() train_x_df, test_x_df, train_y_df, test_y_df = train_test_split(all_reviews_df[['reviews_content']], all_reviews_df[['category']]) pl = Pipeline(steps=[('doc2vec', Doc2VecTransformer()), ('pca', PCA()), ('logistic', LogisticRegression()) ]) param_grid = { 'doc2vec__vector_size': [200, 220, 250], 'pca__n_components': [50, 75, 100] } gs_cv = GridSearchCV(estimator=pl, param_grid=param_grid, cv=3, n_jobs=-1, scoring="accuracy") gs_cv.fit(train_x_df[['reviews_content']], train_y_df[['category']]) print("Best parameter (CV score=%0.3f):" % gs_cv.best_score_) print(gs_cv.best_params_) predictions_y = gs_cv.predict(test_x_df[['reviews_content']]) print('Accuracy: ', metrics.accuracy_score(y_true=test_y_df[['category']], y_pred=predictions_y))
22fd81db6e4cf33bf9626efbc379aea9.png

从上面我们得到的准确度得分在55%左右。通过选择正确的模型或方法可以改善这一点。

结论和方法优化

在机器学习中,有一件事是非常明显的“没有模型绝对正确或错误”。每个模型都有其优点/缺点。以上问题也可以用不同的方式解决。事实上,如果我采取完整的深度学习方法,那么它可以提供更好的结果。但我的目的是提供使用PCA和Logistic回归的技术演示,以便您可以将此应用于任何文本分析问题。

我的方法是“如何在'线性分类模型'中使用'非线性特征'”。“Doc2Vec”绝对是使用神经网络从文档中提取的非线性特征,Logistic回归是一种线性和参数分类模型。在机器学习中,解决问题的四种组合非常普遍:“简单特征 - 简单模型”,“简单特征 - 复杂模型”,“复杂特征 - 简单模型”和“复杂特征 - 复杂模型”。我的方法属于“复杂特征 - 简单模型”类别。扎实掌握数学概念和软件工程经验和技能将为您提供直观/分析能力,以选择正确的方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值