bert模型可以做文本主题识别吗_NLP之文本分类:「Tf-Idf、Word2Vec和BERT」三种模型比较...

本文通过一个新闻类别数据集,对比了TF-IDF、Word2Vec和BERT三种文本分类方法。使用预处理、特征选择、模型训练和评估,结果显示BERT模型在科技新闻分类上的表现优于其他模型。
摘要由CSDN通过智能技术生成

翻译:雷锋字幕组(关山、wiige)

概要

在本文中,我将使用NLP和Python来解释3种不同的文本多分类策略:老式的词袋法(tf-ldf),著名的词嵌入法(Word2Vec)和最先进的语言模型(BERT)。

NLP(自然语言处理)是人工智能的一个领域,它研究计算机和人类语言之间的交互作用,特别是如何通过计算机编程来处理和分析大量的自然语言数据。NLP常用于文本数据的分类。文本分类是指根据文本数据内容对其进行分类的问题。

我们有多种技术从原始文本数据中提取信息,并用它来训练分类模型。本教程比较了传统的词袋法(与简单的机器学习算法一起使用)、流行的词嵌入模型(与深度学习神经网络一起使用)和最先进的语言模型(和基于attention的transformers模型中的迁移学习一起使用),语言模型彻底改变了NLP的格局。

我将介绍一些有用的Python代码,这些代码可以轻松地应用在其他类似的案例中(仅需复制、粘贴、运行),并对代码逐行添加注释,以便你能复现这个例子(下面是全部代码的链接)。

我将使用“新闻类别数据集”(News category dataset),这个数据集提供了从HuffPost获取的2012-2018年间所有的新闻标题,我们的任务是把这些新闻标题正确分类,这是一个多类别分类问题(数据集链接如下)。

特别地,我要讲的是:设置:导入包,读取数据,预处理,分区。

词袋法:用scikit-learn进行特征工程、特征选择以及机器学习,测试和评估,用lime解释。

词嵌入法:用gensim拟合Word2Vec,用tensorflow/keras进行特征工程和深度学习,测试和评估,用Attention机制解释。

语言模型:用transformers进行特征工程,用transformers和tensorflow/keras进行预训练BERT的迁移学习,测试和评估。

设置

首先,我们需要导入下面的库:## for data

import json

import pandas as pd

import numpy as np## for plotting

import matplotlib.pyplot as plt

import seaborn as sns## for bag-of-words

from sklearn import feature_extraction, model_selection, naive_bayes, pipeline, manifold, preprocessing## for explainer

from lime import lime_text## for word embedding

import gensim

import gensim.downloader as gensim_api## for deep learning

from tensorflow.keras import models, layers, preprocessing as kprocessing

from tensorflow.keras import backend as K## for bert language model

import transformers

该数据集包含在一个jason文件中,所以我们首先将其读取到一个带有json的字典列表中,然后将其转换为pandas的DataFrame。lst_dics = []

with open('data.json', mode='r', errors='ignore') as json_file:

for dic in json_file:

lst_dics.append( json.loads(dic) )## print the first one

lst_dics[0]

原始数据集包含30多个类别,但出于本教程中的目的,我将使用其中的3个类别:娱乐(Entertainment)、政治(Politics)和科技(Tech)。## create dtf

dtf = pd.DataFrame(lst_dics)## filter categories

dtf = dtf[ dtf["category"].isin(['ENTERTAINMENT','POLITICS','TECH']) ][["category","headline"]]## rename columns

dtf = dtf.rename(columns={"category":"y", "headline":"text"})## print 5 random rows

dtf.sample(5)

从图中可以看出,数据集是不均衡的:和其他类别相比,科技新闻的占比很小,这会使模型很难识别科技新闻。

在解释和构建模型之前,我将给出一个预处理示例,包括清理文本、删除停用词以及应用词形还原。我们要写一个函数,并将其用于整个数据集上。'''

Preprocess a string.

:parameter

:param text: string - name of column containing text

:param lst_stopwords: list - list of stopwords to remove

:param flg_stemm: bool - whether stemming is to be applied

:param flg_lemm: bool - whether lemmitisation is to be applied

:return

cleaned text

'''

def utils_preprocess_text(text, flg_stemm=False, flg_lemm=True, lst_stopwords=None):

## clean (convert to lowercase and remove punctuations and

characters and then strip)

text = re.sub(r'[^\w\s]', '', str(text).lower().strip())

## Tokenize (convert from string to list)

lst_text = text.split()    ## remove Stopwords

if lst_stopwords is not None:

lst_text = [word for word in lst_text if word not in

lst_stopwords]

## Stemming (remove -ing, -ly, ...)

if flg_stemm == True:

ps = nltk.stem.porter.PorterStemmer()

lst_text = [ps.stem(word) for word in lst_text]

## Lemmatisation (convert the word into root word)

if flg_lemm == True:

lem = nltk.stem.wordnet.WordNetLemmatizer()

lst_text = [lem.lemmatize(word) for word in lst_text]

## back to string from list

text = " ".join(lst_text)

return text

该函数从语料库中删除了一组单词(如果有的话)。我们可以用nltk创建一个英语词汇的通用停用词列表(我们可以通过添加和删除单词来编辑此列表)。lst_stopwords = nltk.corpus.stopwords.words("english")

lst_stopwords

现在,我将在整个数据集中应用编写的函数,并将结果存储在名为“text_clean”的新列中,以便你选择使用原始的语料库,或经过预处理的文本。dtf["text_clean"] = dtf["text"].apply(lambda x:

utils_preprocess_text(x, flg_stemm=False, flg_lemm=True,

lst_stopwords=lst_stopwords))dtf.head()

如果你对更深入的文本分析和预处理感兴趣,你可以查看这篇文章。我将数据集划分为训练集(70%)和测试集(30%),以评估模型的性能。## split dataset

dtf_train, dtf_test = model_selection.train_test_split(dtf, test_size=0.3)## get target

y_train = dtf_train["y"].values

y_test = dtf_test["y"].values

让我们开始吧!

词袋法

词袋法的模型很简单:从文档语料库构建一个词汇表,并计算单词在每个文档中出现的次数。换句话说,词汇表中的每个单词都成为一个特征,文档由具有相同词汇量长度的矢量(一个“词袋”)表示。例如,我们有3个句子,并用这种方法表示它们:

特征矩阵的形状:文档数x词汇表长度

可以想象,这种方法将会导致很严重的维度问题:文件越多,词汇表越大,因此特征矩阵将是一个巨大的稀疏矩阵。所以,为了减少维度问题,词袋法模型通常需要先进行重要的预处理(词清除、删除停用词、词干提取/词形还原)。

词频不一定是文本的最佳表示方法。实际上我们会发现,有些常用词在语料库中出现频率很高,但是它们对目标变量的预测能力却很小。为了解决此问题,有一种词袋法的高级变体,它使用词频-逆向文件频率(Tf-Idf)代替简单的计数。基本上,一个单词的值和它的计数成正比地增加,但是和它在语料库中出现的频率成反比。

先从特征工程开始,我们通过这个流程从数据中提取信息来建立特征。使用Tf-Idf向量器(vectorizer),限制为1万个单词(所以词长度将是1万),捕捉一元文法(即 "new "和 "york")和 二元文法(即 "new york")。以下是经典的计数向量器的代码:ngram_range=(1,2))vectorizer = feature_extraction.text.TfidfVectorizer(max_features=10000, ngram_range=(1,2))

现在将在训练集的预处理语料上使用向量器来提取词表并创建特征矩阵。corpus = dtf_train["text_clean"]vectorizer.fit(corpus)X_train = vectorizer.transform(corpus)dic_vocabulary = vectorizer.vocabulary_

特征矩阵X_train的尺寸为34265(训练集中的文档数)×10000(词长度),这个矩阵很稀疏:sns.heatmap(X_train.todense()[:,np.random.randint(0,X.shape[1],100)]==0, vmin=0, vmax=1, cbar=False).set_title('Sparse Matrix Sample')

从特征矩阵中随机抽样(黑色为非零值)

为了知道某个单词的位置,可以这样在词表中查询:word = "new york"dic_vocabulary[word]

如果词表中存在这个词,这行脚本会输出一个数字N,表示矩阵的第N个特征就是这个词。</

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值