前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >XGBoost 实现文本分类与sklearn NLP库TfidfVectorizer

XGBoost 实现文本分类与sklearn NLP库TfidfVectorizer

原创
作者头像
大鹅
发布2021-12-23 00:31:12
2.4K1
发布2021-12-23 00:31:12
举报

1. 背景

在文本分类任务中经常使用XGBoost快速建立baseline,在处理文本数据时需要引入TFIDF将文本转换成基于词频的向量才能输入到XGBoost进行分类。这篇博客将简单阐述XGB进行文本分类的实现与部分原理。

2. 实现

代码语言:txt
复制
import pandas as pd
import xgboost as xgb
import jieba
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn import metrics
from sklearn.model_selection import train_test_split
from matplotlib import pyplot

def word_seg(x):
    content = str(x['a']) + ' ' + str(x['b'])
    for i in string.punctuation + ''.join([r'\N', '\t', '\n', '(', ')', ',', '。', ':', '】', '【']):
        content = content.replace(i, '')
    return ' '.join(jieba.lcut(content))
train_data = pd.read_csv('./data/train.csv')
train_data['content'] = train_data.apply(word_seg, axis=1)

x_train, x_test, y_train, y_test = train_test_split(train_data['content'], train_data['label'], test_size=0.2)
# 将语料转化为词袋向量,根据词袋向量统计TF-IDF
vectorizer = CountVectorizer(max_features=5000)
tf_idf_transformer = TfidfTransformer()
tf_idf = tf_idf_transformer.fit_transform(vectorizer.fit_transform(x_train))
x_train_weight = tf_idf.toarray()  # 训练集TF-IDF权重矩阵
tf_idf = tf_idf_transformer.transform(vectorizer.transform(x_test))
x_test_weight = tf_idf.toarray()  # 测试集TF-IDF权重矩阵

#基于Scikit-learn接口的分类
# 训练模型
eval_set = [(x_train_weight, y_train), (x_test_weight, y_test)]
model = xgb.XGBClassifier(max_depth=6, learning_rate=0.1, n_estimators=60, objective='binary:logistic')
model.fit(x_train_weight, y_train, eval_set=eval_set, verbose=True)
y_predict = model.predict(x_test_weight)

results = model.evals_result()
results
epochs = len(results['validation_0']['logloss'])
x_axis = range(0, epochs)
# plot log loss
fig, ax = pyplot.subplots()
ax.plot(x_axis, results['validation_0']['logloss'], label='Train')
ax.plot(x_axis, results['validation_1']['logloss'], label='Test')
ax.legend()
pyplot.ylabel('Log Loss')
pyplot.title('XGBoost Log Loss')
pyplot.show()
代码语言:txt
复制
#利用训练完的模型直接测试
# xgb_model = xgb.Booster(model_file='data/xgb_model')  # init model #加载模型
# dtest = xgb.DMatrix('data/test.buffer')  #加载数据
# xgb_test(dtest,xgb_model)


# y_predict = model.predict(dtest)  # 模型预测
label_all = [0, 1]
confusion_mat = metrics.confusion_matrix(y_test, y_predict)
df = pd.DataFrame(confusion_mat, columns=label_all)
df.index = label_all
print('准确率:\n', metrics.accuracy_score(y_test, y_predict))
print('confusion_matrix: \n', df)
print('分类报告: \n', metrics.classification_report(y_test, y_predict))
print('AUC: %.4f' % metrics.roc_auc_score(y_test, y_predict))
代码语言:txt
复制
准确率:
 0.9730405840669959
confusion_matrix: 
        0      1
0  48544      0
1   2511  42085
分类报告: 
               precision    recall  f1-score   support

           0       0.95      1.00      0.97     48544
           1       1.00      0.94      0.97     44596

    accuracy                           0.97     93140
   macro avg       0.98      0.97      0.97     93140
weighted avg       0.97      0.97      0.97     93140

AUC: 0.9718

3. TfidfVectorizer原理

这里简单介绍下scikit-learn自然语言文本处理的一个开源方法——TfidfVectorizer,该方法分别是由两种方法 CountVectorizer 与 TfidfTransformer 的结合,下面进行说明,说明之前给出三个文档链接(本文基本翻译自官方文档):

(文档在手天下我有,有问题看文档)

方法一:TfidfVectorizer 方法二:CountVectorizerTfidfTransformer

好了进入正文

TfidfVectorizer 处理文本语言的主要中心思想也就是 TF-IDF (词频-逆文档频率),由于本篇文章的重点是介绍该模块,所以不过多对 TF-IDF 说明,有需要的这里给出之前写的比较详细的文章可以参考——TF-IDF及相关知识

TfidfVectorizer 的使用相当于先调用了 CountVectorizer 方法,然后再调用 TfidfTransformer 方法,所以想了解 TfidfVectorizer 还得从后面两个方法说起。

CountVectorizer:

功能:

将文本文档集合转换为计数的稀疏矩阵。内部的实现方法为调用scipy.sparse.csr_matrix模块。并且,如果在调用CountVectorizer() 时不提供先验词典并且不使用执行某种特征选择的分析器,则特征词的数量将等于通过该方法直接分析数据找到的词汇量。

代码说明:

代码语言:txt
复制
from sklearn.feature_extraction.text import CountVectorizer

corpus = ['This is the first document.',
	'This document is the second document.',
	'And this is the third one.',
	'Is this the first document?']

vectorizer = CountVectorizer()		# ()这里不提供先验词典
# vectorizer.fit(corpus)			# 先fit训练传入的文本数据
# X = vectorizer.transform(corpus)		# 然后对文本数据进行标记并转换为稀疏计数矩阵
X = vectorizer.fit_transform(corpus)		# 可以fit、transform一起使用替代上面的两行

print(vectorizer.get_feature_names())	# 获得模型直接分析数据找到的词汇量(上面单词的集合)
print(X.toarray())	# 直接打印X输出的是每个词的位置
代码语言:txt
复制
['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third', 'this']

[[0 1 1 1 0 0 1 0 1]        # 4行 数据样本
 [0 2 0 1 0 1 1 0 1]        # 9列 特征单词
 [1 0 0 1 1 0 1 1 1]
 [0 1 1 1 0 0 1 0 1]]

参数简单说明:

以上为最简单的 CountVectorizer 模块的使用,我们几乎没有使用任何的参数和方法,但依然能达到一个较好的【文本—>词向量稀疏矩阵 】的效果,部分参数如下。

input?:?string {‘filename’, ‘file’, ‘content’}

encoding?:?string, ‘utf-8’ by default.

stop_words?:?string {‘english’}, list, or None (default)

max_df?:?float in range 0.0, 1.0 or int, default=1.0

min_df?:?float in range 0.0, 1.0 or int, default=1

max_features?:?int or None, default=None

TfidfTransformer:

功能:

将计数矩阵(如上图所示)转换为标准化的 tf 或 tf-idf 表示。Tf 表示术语频率,而tf-idf表示术语频率乘以逆文档频率。这是信息检索中常用的术语加权方案,在文档分类中也有很好的用途。用于计算项的 tf-idf 的公式是 tf-idf(d,t)= tf(t)* idf(d,t)。

代码说明:

代码语言:txt
复制
from sklearn.feature_extraction.text import TfidfTransformer

transform = TfidfTransformer()    # 使用TF-IDF(词频、逆文档频率)应用于稀疏矩阵
Y = transform.fit_transform(X)    # 使用上面CountVectorizer处理后的 X 数据
print(Y.toarray())                # 输出转换为tf-idf后的 Y 矩阵,同样直接打印 Y 输出每个数据的位置
print(vectorizer.get_feature_names())    # 打印特征名
代码语言:txt
复制
[[0.         0.46979139 0.58028582 0.38408524 0.         0.
  0.38408524 0.         0.38408524]
 [0.         0.6876236  0.         0.28108867 0.         0.53864762
  0.28108867 0.         0.28108867]
 [0.51184851 0.         0.         0.26710379 0.51184851 0.
  0.26710379 0.51184851 0.26710379]
 [0.         0.46979139 0.58028582 0.38408524 0.         0.
  0.38408524 0.         0.38408524]]
['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third', 'this']

参数简单说明:

以上为直接使用?TfidfTransformer 转换?CountVectorizer 处理后的计数矩阵为标准化的 tf-idf 矩阵【词向量稀疏矩阵—>标准化tf-idf】的效果,下面给出其部分参数。

norm?:?‘l1’, ‘l2’ or None, optional

? ? Norm used to normalize term vectors. None for no normalization.

use_idf?:?boolean, default=True

? ? Enable inverse-document-frequency reweighting.

smooth_idf?:?boolean, default=True

? ? Smooth idf weights by adding one to document frequencies, as if an extra document was seen containing every term in the collection exactly once. Prevents zero divisions.

sublinear_tf?:?boolean, default=False

? ? Apply sublinear tf scaling, i.e. replace tf with 1 + log(tf).

最后可以简单的描述下TfidfVectorizer了

TfidfVectorizer

功能:

前文说过 TfidfVectorizer 相当于两者的结合使用,先后调用 CountVectorizer 和 TfidfTransformer 两种方法(简化了代码,但运算思想还是不变),并且参数的使用基本一致。

代码说明:

代码语言:txt
复制
from sklearn.feature_extraction.text import TfidfVectorizer

VT = TfidfVectorizer()		# 先后调用CountVectorizer和TfidfTransformer两种方法(简化了代码,但运算思想还是不变)
result = VT.fit_transform(corpus)
print(result.toarray())
print(VT.get_feature_names())
代码语言:txt
复制
[[0.         0.46979139 0.58028582 0.38408524 0.         0.
  0.38408524 0.         0.38408524]
 [0.         0.6876236  0.         0.28108867 0.         0.53864762
  0.28108867 0.         0.28108867]
 [0.51184851 0.         0.         0.26710379 0.51184851 0.
  0.26710379 0.51184851 0.26710379]
 [0.         0.46979139 0.58028582 0.38408524 0.         0.
  0.38408524 0.         0.38408524]]
['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third', 'this']

可以看到与上面?CountVectorizer 和 TfidfTransformer 处理后的结果一致,确实为两者的结合使用。

参数及使用方法与 CountVectorizer和TfidfTransformer 一致,这里不再描述。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 背景
  • 2. 实现
  • 3. TfidfVectorizer原理
    • 好了进入正文
      • CountVectorizer:
        • TfidfTransformer:
          • TfidfVectorizer
          相关产品与服务
          NLP 服务
          NLP 服务(Natural Language Process,NLP)深度整合了腾讯内部的 NLP 技术,提供多项智能文本处理和文本生成能力,包括词法分析、相似词召回、词相似度、句子相似度、文本润色、句子纠错、文本补全、句子生成等。满足各行业的文本智能需求。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
          http://www.vxiaotou.com