资源技术动态以BBC新闻文章为例:应用XGBoost等算法进行文本分类

以BBC新闻文章为例:应用XGBoost等算法进行文本分类

2019-11-19 | |  63 |   0

原标题:以BBC新闻文章为例:应用XGBoost等算法进行文本分类 

来源:今日头条          链接:https://www.toutiao.com/a6722243537355670030/


本文将以BBC新闻文章分类为例,讨论不同的文本分类技术。同时,本文将讨论如何用不同向量空间模型代表文本数据。


为解决此问题,将使用到Python、Sci-kit-learn、Genism和Xgboost库等工具。

image.png

获取数据

image.png


本问题涉及到的数据可以在Kaggle上找到(https://www.kaggle.com/yufengdev/bbc-fulltext-and-category)。本数据集包含BBC新闻文本及其双栏CSV格式的分类列表,展示如下:

import pandas as pd
bbc_text_df = pd.read_csv('../data/bbc-text.csv')
bbc_text_df.head()

image.png


表中似乎含有许多长文本。后续章节将对其作详细论述。现在的问题是:若给定一个“文本”,就需要预测其类别。这无疑是一个多累文本分类的问题。


image.png


数据探索及视觉化呈现


首先,我们需要知道有哪些类别。

%matplotlib inline
import seaborn as sns
import matplotlib.pyplot as plt
plt.figure(figsize=(12,5))
sns.countplot(x=bbc_text_df.category, color='green')
plt.title('BBC text class distribution', fontsize=16)
plt.ylabel('Class Counts', fontsize=16)
plt.xlabel('Class Label', fontsize=16)
plt.xticks(rotation='vertical');

image.png


由图可知,有五个类别。可将其称为“类”。显然,该类别的分配并无太多偏斜。


下一步是弄清数据集该“文本”领域中包含何种内容。因此需要先清理文本。


文本清理通常包含以下步骤:

1. 英文字母小写化

2. 去除标点

3. 去除整数、数字

4. 去除多余空格

5. 去除标签(如<html>, <p>等)

6. 去除停用词(如and、to、the等)

7. 词干提取(将单词转换至词源形式)

此次使用了Python的“genism”库进行文本清理工作。

from gensim import utils
import gensim.parsing.preprocessing as gsp
filters = [
 gsp.strip_tags, 
 gsp.strip_punctuation,
 gsp.strip_multiple_whitespaces,
 gsp.strip_numeric,
 gsp.remove_stopwords, 
 gsp.strip_short, 
 gsp.stem_text
 ]
def clean_text(s):
 s = s.lower()
 s = utils.to_unicode(s)
 for f in filters:
 s = f(s)
 return s


可应用“clean_text”功能完成这项任务。


把记录的文本领域的第一段内容打印出来。

bbc_text_df.iloc[2,1]

image.png


清理后

clean_text(bbc_text_df.iloc[2,1])

image.png


文本可能稍微缺乏语法逻辑,但这是为了便于理解。


接下来会编写一个功能,将“文本”内容视觉化呈现为“文字云”。

%matplotlib inline
from wordcloud import WordCloud
def plot_word_cloud(text):
 wordcloud_instance = WordCloud(width = 800, height = 800, 
 background_color ='black', 
 stopwords=None,
 min_font_size = 10).generate(text) 
 
 plt.figure(figsize = (8, 8), facecolor = None) 
 plt.imshow(wordcloud_instance) 
 plt.axis("off") 
 plt.tight_layout(pad = 0) 
plt.show()


需要连结所有文本,并将其导入此功能。

texts = ''
for index, item in bbc_text_df.iterrows():
 texts = texts + ' ' + clean_text(item['text'])
 
plot_word_cloud(texts)


会出现如下结果:

image.png


单词越大,意味着其出现频率越高。所以“年 (year) ”、“时间 (time) ”、“人 (peopl) ”是出现频率最高的词。


现在进行更深入的分析:在某一特定“类别”理,“文本”的“文字云”。


为其编写一项一般/通用功能。

def plot_word_cloud_for_category(bbc_text_df, category):
 text_df = bbc_text_df.loc[bbc_text_df['category'] == str(category)]
 texts = ''
 for index, item in text_df.iterrows():
 texts = texts + ' ' + clean_text(item['text'])
 
plot_word_cloud(texts)


比如,“技术”这一“类别”的“文字云”


plot_word_cloud_for_category(bbc_text_df,'tech')

image.png


因此,“技术”这一类别中最常出现的词是“人 (peopl)”、“techlog”、“游戏 (game)”等。


而对于“运动”类别:


plot_word_cloud_for_category(bbc_text_df,'sport')

image.png


最常出现的词是“plai”、“游戏 (game) ”、“运动员 (player) ”、“胜利 (win) ”、“比赛 (match) ”、“英格兰 (England) ”等。


对于“政治”类别:


plot_word_cloud_for_category(bbc_text_df,'politics')

image.png


最常出现的词是“治理 (govern) ”、“人 (people) ”、“布莱尔 (blair) ”、“国家 (countri) ”、“部长 (Minist) ”等。

毫无疑问,每一个类别中都有自己独有的词汇。也可以这样理解:每一个“文本”的内容都在暗示某个语境,从而决定其类别。

需要进行向量空间分析,并将其应用于模型,以证实以上推断。

image.png

向量空间建模及构建管道


对于任何自然语言处理问题,都有必要进行向量空间建模。以两个最常见的向量空间模型为例:Doc2Vec和Tf-Idf。首先,把数据分成特征和类别。

df_x = bbc_text_df['text']
df_y = bbc_text_df['category']


Doc2Vec


使用“Genism”库的Doc2Vec编写一般/通用“Doc2VecTransfoemer”。

from gensim.models.doc2vec import TaggedDocument, Doc2Vec
from sklearn.base import BaseEstimator
from sklearn import utils as skl_utils
from tqdm import tqdm
import multiprocessing
import numpy as np
class 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() - 1
 def fit(self, df_x, df_y=None):
 tagged_x = [TaggedDocument(clean_text(row).split(), [index]) for index, row in enumerate(df_x)]
 model = Doc2Vec(documents=tagged_x, vector_size=self.vector_size, workers=self.workers)
 for epoch in range(self.epochs):
 model.train(skl_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(clean_text(row).split())
 for index, row in enumerate(df_x)]))


应用该转换器,可以看到“DocVec”如下:

doc2vec_trf = Doc2VecTransformer()
doc2vec_features = doc2vec_trf.fit(df_x).transform(df_x)
doc2vec_features

image.png




因此,这是一组文本数据的数字化呈现。可以把这个数字特征应用到机器学习算法中。下面以LogisticRegression, RandomForest和XGBoost为例进行操作。


对于每一个案例,都应用数据集对模型进行五层/级交叉验证并试运行。精确度得分将会是五个层级的平均分。


Doc2Vec和LogisticRegression管道

image.png


精确度变得非常低!!


再来看其它分类器。


Doc2Vec和RandomForest管道


from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
pl_log_reg = Pipeline(steps=[('doc2vec',Doc2VecTransformer()),
 ('log_reg', LogisticRegression(multi_class='multinomial', solver='saga', max_iter=100))])
scores = cross_val_score(pl_log_reg, df_x, df_y, cv=5,scoring='accuracy')
print('Accuracy for Logistic Regression: ', scores.mean())

image.png


精确度也不是很高!!


Doc2Vec和XGBoost管道

import xgboost as xgb
pl_xgb = Pipeline(steps=[('doc2vec',Doc2VecTransformer()),
 ('xgboost', xgb.XGBClassifier(objective='multi:softmax'))])
scores = cross_val_score(pl_xgb, df_x, df_y, cv=5)
print('Accuracy for XGBoost Classifier : ', scores.mean())

image.png


精确度并未提高多少。


“Doc2Vec”运行状况并不良好。

下面看“Tf-Idf”向量空间模型。


Tf-Idf

为“Tf-Idf”编写一个相似的转换器。

from sklearn.feature_extraction.text import TfidfVectorizer
class Text2TfIdfTransformer(BaseEstimator):
 def __init__(self):
 self._model = TfidfVectorizer()
 pass
 def fit(self, df_x, df_y=None):
 df_x = df_x.apply(lambda x : clean_text(x))
 self._model.fit(df_x)
 return self
 def transform(self, df_x):
 return self._model.transform(df_x)


那么,文本会变成什么样呢?

tfidf_transformer = Text2TfIdfTransformer()
tfidf_vectors = tfidf_transformer.fit(df_x).transform(df_x)


将其维数打印出来。

tfidf_vectors.shape

image.png


[“0”]标记总计出现18754次。

print(tfidf_vectors)

image.png


现在把此模型运用到实际机器学习模型中。


Tf-Idf & LogisticRegression


pl_log_reg_tf_idf = Pipeline(steps=[('tfidf',Text2TfIdfTransformer()),
 ('log_reg', LogisticRegression(multi_class='multinomial', solver='saga', max_iter=100))])
scores = cross_val_score(pl_log_reg_tf_idf, df_x, df_y, cv=5,scoring='accuracy')
print('Accuracy for Tf-Idf & Logistic Regression: ', scores.mean())

image.png

精确度很高!!

Tf-Idf & RandomForest


pl_random_forest_tf_idf = Pipeline(steps=[('tfidf',Text2TfIdfTransformer()),
 ('random_forest', RandomForestClassifier())])
scores = cross_val_score(pl_random_forest_tf_idf, df_x, df_y, cv=5,scoring='accuracy')
print('Accuracy for Tf-Idf & RandomForest : ', scores.mean())

image.png


Tf-Idf & XGBoost


pl_xgb_tf_idf = Pipeline(steps=[('tfidf',Text2TfIdfTransformer()),
 ('xgboost', xgb.XGBClassifier(objective='multi:softmax'))])
scores = cross_val_score(pl_xgb_tf_idf, df_x, df_y, cv=5)
print('Accuracy for Tf-Idf & XGBoost Classifier : ', scores.mean())

image.png


最后这一个精确度最高!!

毫无疑问,使用Tf-Idf & XGBoost结合模型能够解决本案例的问题。

image.png


结果解读


尽管在自然语言处理中,“DocVec”模型比“Tf-Idf”模型更高级,但我们的案例证明,后者效果更佳。我们分别使用了基于线性、袋状以及推进型的分类器。


原因可以这么理解。在我们的数据集中,每一个“文本”领域包含了一些决定其类别的高频单词/标记。因此,应用一个对语境/上下文敏感的模型会使问题更为复杂、(或者)混淆信息。某些文本类别包含一些高频出现的标记,这些标记提供了大量数值以定义“Tf-Idf”模型。同时,“文本”是细分领域的。


比如,“布莱尔 (blair) ”一词更可能出现在“政治”类别,而非“运动”类别。因此,像这样的词对“Tf-Idf”模型起了作用。


而且,“Doc2Vec”模型更适合应用于语法正确的文本中。

而我们的案例文本本质上过于粗糙。

“维基百科”文本就是一个语法正确的文本。

同时,大量案例和数据科学家的实验证明,虽然“Tf-Idf”模型次于”DocVec”模型,但前者对于细分领域的文本分类更为有效。


结论

实验结束。我们对所有分类器和向量空间模型的组合进行了测试。GitHub上有关于这一实验的Jupyter笔记。


传送门:https://github.com/avisheknag17/public_ml_models/blob/master/bbc_articles_text_classification/notebook/text_classification_xgboost_others.ipynb?source=post_page---------------------------

THE END

免责声明:本文来自互联网新闻客户端自媒体,不代表本网的观点和立场。

合作及投稿邮箱:E-mail:editor@tusaishared.com

上一篇:CNN也能用于NLP任务,一文简述文本分类任务的7个模型

下一篇:基于卷积递归模型的文本分类研究

用户评价
全部评价

热门资源

  • 应用笔画宽度变换...

    应用背景:是盲人辅助系统,城市环境中的机器导航...

  • 端到端语音识别时...

    从上世纪 50 年代诞生到 2012 年引入 DNN 后识别效...

  • 人体姿态估计的过...

    人体姿态估计是计算机视觉中一个很基础的问题。从...

  • GAN之根据文本描述...

    一些比较好玩的任务也就应运而生,比如图像修复、...

  • 谷歌发布TyDi QA语...

    为了鼓励对多语言问答技术的研究,谷歌发布了 TyDi...