文本分类又来了,用 Scikit-Learn 解决多类文本分类问题

雷锋网  •  扫码分享
我是创始人李岩:很抱歉!给自己产品做个广告,点击进来看看。  

雷锋网按:本文为雷锋字幕组编译的技术博客,原标题 Multi-Class Text Classification with Scikit-Learn,作者为 Susan Li 。

翻译 | 朱茵      整理 | 余杭  MY

 

在商业领域有很多文本分类的应用,比如新闻故事通常由主题来分类;内容或产品常常被打上标签;基于如何在线谈论产品或品牌,用户被分成支持者等等。

然而大部分的文本分类文章和网上教程是二进制的文本分类,像垃圾邮件过滤(spam vs. ham)、情感分析(积极的和消极的)。在大量实例中,我们现实世界的问题要比这些复杂的多。因此,这是我们今天要做的:将消费者的财务投诉分成12个预定义的类。这些数据可以从  data.gov  下载。

我们使用 Python 和 Jupyter Notebook 来开发我们的系统,依靠 Scikit-Learn 作为机器学习的部件。如果你想看下在 PySpark 中的实现,请阅读下一篇文章。


问题形成

我们的问题是有监督的文本分类问题,目标是调查哪一种有监督的机器学习方法最适于解决该问题。

鉴于新的投诉的到来,我们想将它归到12个分类目录中。分类器使得每个新投诉被归类到一个仅且一个类别中。这是一个多类文本分类问题。我已经迫不及待地想看下我们完成的结果。


数据浏览

在投入训练机器学习模型前,我们应当先看一些实例以及每个类别中投诉的数量:

文本分类又来了,用 Scikit-Learn 解决多类文本分类问题

文本分类又来了,用 Scikit-Learn 解决多类文本分类问题

图1

针对这个项目而言,我们仅需要2栏:“产品”和“消费者投诉陈述”。

  • 输入 : Consumer_complaint_narrative

实例:“在我的信用报告上有过时的信息,我之前对该信用报告有争议,该项信息记录应该被删除,该信息是7年多之前的并且不符合信用报告的要求。”

  • 输出 :产品

实例:信用报告

我们将在消费者投诉陈述栏删除无赋值的,并且增加一栏编译该产品作为一个整数值,因为通常分类属性变量用整数比用字符串代表要好。

我们也创建了几个字典以备将来使用。

清理后,这是我们要使用的最初的5行数据:

文本分类又来了,用 Scikit-Learn 解决多类文本分类问题

文本分类又来了,用 Scikit-Learn 解决多类文本分类问题

  图2

不平衡的分类

我们看到每个产品的投诉数值不平衡。消费者的投诉多针对索回债款、信用报告和房屋抵押贷款。

文本分类又来了,用 Scikit-Learn 解决多类文本分类问题

文本分类又来了,用 Scikit-Learn 解决多类文本分类问题

图3

当我们遇到问题时,我们会用标准算法解决这些问题。传统的算法常常倾向于大多数的分类,并不会将数据分布考虑进去。最糟的情况,少数的分类被当做异常值被忽略了。在一些例子中,像欺诈侦测和癌症预测,我们将仔细设置我们的模型或人工平衡数据集,比如通过欠采样和过采样每个类。

然而,在我们的学习不均衡的数据的例子中,我们会将兴趣点放在占少数的的分类上。在大多数分类上具有高准确率的分类器是令人满意的。然而针对占少数的分类也应当保持合理的准确度。就这样吧。


文本表达

分类器和学习算法不能以他们原来的形式直接处理文本文件,他们大多数需要有固定大小的数字特征向量而不是带有变量长度的原来的文本文件。因此,在预处理的阶段文本将被转成更好处理的表达方式。

一个从文本中提取特征的常用方法是使用词汇模型袋:一种给每个文件,在我们的例子中的投诉陈述,词汇的呈现(通常是频率)将被考虑进去,但这些词汇出现的顺序是被忽略的。

尤其是我们数据集的每个术语,我们将计算一种被称为术语频率的测量方法。逆文档频率,缩写成tf-idf。我们将使用 sklearn.feature_extraction.text.TfidfVectorizer 给每个消费者投诉陈述计算一个 tf-idf 向量:

  • sublinear_df 设置为True 给频率使用一种算法形式。

  • min_df 是文档的最小数值is the minimum numbers of documents a word must be present in to be kept.

  • norm 设置为l2,来确保我们的特征向量具有欧几里得标准1. 

  • ngram_range 设置为) (1,2)来表明我们同时考虑一元语法和二元语法。

  • stop_words 设置为"english" 来移除所有相同的代词("a", "the", ...)用以减少噪音特征的数量。

文本分类又来了,用 Scikit-Learn 解决多类文本分类问题

(4569, 12633)

现在,每 4569 个消费者投诉陈述由12633个特征表示,代表不同的一元和二元语法的 tf-idf 分数。

我们可以使用 sklearn.feature_selection.chi2 来寻找和每个产品最相关的术语:

文本分类又来了,用 Scikit-Learn 解决多类文本分类问题

# ‘银行账户或服务’:
 . 最相关的一元语法:
 . 银行
 . 透支
 . 最相关的二元语法:
 . 透支费用
 . 支票账户
# ‘消费者贷款’:
 . :最相关的一元语法:
 . 小轿车
 . 车辆
 . 最相关的二元语法:
 . 车辆 xxxx
 . 丰田汽车金融
# ‘信用卡’:
 . 最相关的一元语法:
 . 花旗银行
 . 卡
 . 最相关的二元语法:
 . 年费
 . 信用卡
# ‘信用报告’:
 . 最相关的一元语法:
 . 益百利
 . 艾奎法克斯
 . 最相关的二元语法:
 . 反式联盟
 . 信用报告
# ‘索回债款’:
 . 最相关的一元语法:
 . 收集
 . 债务
 . 最相关的二元语法:
 . 索回债款
 . 索回机构
# ‘转账’:
 . 最相关的一元语法:
 . 西联
 . paypal贝宝
 . 最相关的二元语法:
 . 西联
 . 转账
# ‘住房抵押贷款’:
 . 最相关的一元语法:
 . 修改
 . 住房抵押贷款
 . 最相关的二元语法:
 . 抵押贷款公司
 . 贷款修改
# ‘其它金融服务’:
 . 最相关的一元语法:
 . 口腔
 . 护照
 . 最相关的二元语法:
 . 帮助支付
 . 规定支付
# ‘发薪日贷款’:
 . 最相关的一元语法:
 . 借钱
 . 发薪日
 . 最相关的二元语法:
 . 主要部分
 . 发薪日贷款
# ‘预付卡’:
 . 最相关的一元语法:
 . 服务
 . 预付
 . 最相关的二元语法:
 . 获得的钱
 . 预付卡
# ‘学生贷款’:
 . 最相关的一元语法:
 . 学生
 . navient
 . 最相关的二元语法:
 . 学生贷款
 . 学生贷款
# ‘虚拟货币’:
 . 最相关的一元语法:
 . 处理
 . https
 . 最相关的二元语法:
 . xxxx 提供商
 . 金钱需要

这些都很讲得通,对么?


多级类别分类器:特征和设计

  • 为了训练有监督的分类器,我们首先将“消费者投诉陈述”转化为数字向量。我们开发了类似 TF-IDF 权值向量的向量表示。

  • 在得到文本的向量表示后,我们可以训练有监督的分类器来训练看不见的“消费者投诉陈述”和预测“产品”将落在哪个分类。

上述所有这些数据转化后,现在我们有了所有的特征和标签,是时候来训练分类器了。针对这种类型的问题,许多算法可供我们使用。

  • 朴素贝叶斯分类器:最适合的词汇计算的是多项式变量:

文本分类又来了,用 Scikit-Learn 解决多类文本分类问题

在配置好训练设置后,我们来做一些预测。

文本分类又来了,用 Scikit-Learn 解决多类文本分类问题

[‘债务索回’]

文本分类又来了,用 Scikit-Learn 解决多类文本分类问题


图4

文本分类又来了,用 Scikit-Learn 解决多类文本分类问题

[‘信用报告’]

文本分类又来了,用 Scikit-Learn 解决多类文本分类问题


图5

还不算太糟!


模型选择

我们现在可以用不同的机器学习模型来做测试了,评估他们的准确度和寻找任一潜在问题的源头。

我们将用下列四种模型来做测试:

  • 逻辑回归

  • (多项)  朴素贝叶斯

  • 线性支持向量机

  • 随机森林

文本分类又来了,用 Scikit-Learn 解决多类文本分类问题

文本分类又来了,用 Scikit-Learn 解决多类文本分类问题

图6


model_name
LinearSVC: 0.822890
LogisticRegression: 0.792927
MultinomialNB: 0.688519
RandomForestClassifier: 0.443826
Name: accuracy, dtype: float64

线性支持向量机和逻辑回归比其他两种分类器表现更好,线性支持向量机有一个小优势,它具备 82% 左右的准确率。


模型评估

继续我们最好的模型(线性支持向量机),我们看下混淆矩阵,展示下预测的和实际的标签之间的差异。

文本分类又来了,用 Scikit-Learn 解决多类文本分类问题

文本分类又来了,用 Scikit-Learn 解决多类文本分类问题

图7

大多数的预测最终呈现的是对角线(预测的标签 = 实际的标签),正是我们想要的。然而,还是有许多的误分类,看看他们是由什么引起的也许蛮有意思的:

文本分类又来了,用 Scikit-Learn 解决多类文本分类问题

文本分类又来了,用 Scikit-Learn 解决多类文本分类问题

图8

文本分类又来了,用 Scikit-Learn 解决多类文本分类问题

图9

你可以看到,一些误分类的投诉是一些跟不止一个主题相关的投诉(比如,包括信用卡和信用报告的投诉)。这种错误将一直发生。

然后我们使用  chi-squared test  来寻找与每个目录最相关的术语:

文本分类又来了,用 Scikit-Learn 解决多类文本分类问题

# ‘银行账号和服务’:

 . 最高一元语法:

 . 银行

 . 账户

 . 最高二元语义:

 . 借记卡

 . 透支费用

# ‘消费贷’:

 . 最高一元语义:

 . 车辆

 . 小型汽车

 . 最高二元语义:

 . 个人贷款

 . 历史xxxx

# ‘信用卡’:

 . 最高一元语义:

 . 卡

 . 发现

 . 最高二元语义:

 . 信用卡

 . 发现卡

# ‘信用’:

 . 最高一元语义:

 . 艾奎法克斯

 . 反式联盟

 . 最高二元语义:

 . xxxx 账户

 . 反式联盟

# ‘索回债务’:

 . 最高一元语义:

 . 债务

 . 收集

 . 最高二元语义:

 . 信用账户

 . 时间期限

# ‘转账’:

 . 最高一元语义:

 . paypal贝宝

 . 转

 . 最高二元语义:

 . 转账

 . 发送钱

# ‘住房抵押贷款’:

 . 最高一元语义:

 . 住房抵押贷款

 . 第三方托管

 . 最高二元语义:

 . 贷款修改

 . 住房抵押贷款公司

# ‘其它金融服务’:

 . 最高一元语义:

 . 护照

 . 口腔

 . 最高二元语义:

 . 规定支付

 . 帮助支付

# ‘发薪日贷款’:

 . 最高一元语义:

 . 发薪日

 . 贷款

 . 最高二元语义:

 . 发薪日贷款

 . 发薪日

# ‘预付卡’:

 . 最高一元语义:

 . 预付

 . 服务

 . 最高二元语义:

 . 预付卡

 . 使用卡

# ‘学生贷款’:

 . 最高一元语义:

 . navient贷款公司

 . 贷款

 . 最高二元语义:

 . 学生贷款

 . 萨利美-学生贷款市场协会

# ‘虚拟货币’:

 . 最高以一元语义:

 . https

 . tx

 . 最高二元语义:

 . 金钱需求

 . xxxx 提供者

这些跟我们的预期一致。

最后,我们给每个类别打印分类报告:

文本分类又来了,用 Scikit-Learn 解决多类文本分类问题

文本分类又来了,用 Scikit-Learn 解决多类文本分类问题

图9

源代码可以在 Github 上找到,期待大家的反馈和提问。 


原文链接: https://towardsdatascience.com/multi-class-text-classification-with-scikit-learn-12f1e60e0a9

文本分类又来了,用 Scikit-Learn 解决多类文本分类问题

雷锋网 (公众号:雷锋网) 雷锋网

文本分类又来了,用 Scikit-Learn 解决多类文本分类问题

随意打赏

cnn文本分类rnn文本分类问题文本文本分类
提交建议
微信扫一扫,分享给好友吧。