R文本分类之RTextTools

2018 年 1 月 17 日 R语言中文社区 黄耀鹏

作者简介Introduction

黄耀鹏:R语言中文社区专栏作者,一名数据科学研究者及科普写作者。

个人博客:http://yphuang.github.io/

往期回顾

R中的正则表达式及字符处理函数总结

R字符串处理应用之邮件考勤自动化

R爬虫之上市公司公告批量下载

‍‍‍‍‍‍‍‍RTextTools简介

古有曹植七步成诗,而RTextTools是一款让你可以在十步之内实现九种主流的机器学习分类器模型的文本分类开发包。

它集成了(或者说支持)如下算法相关的包:

  • 支持向量机(Support Vector Machine from e1071)

  • glmnet(一个非常流行的用于变量选择的R包,俗称kaggle竞赛“三驾马车”之一)

  • 最大熵模型(maximum entropy from maxent)

  • 大规模线性判别(scaled linear discriminant,slda)

  • 装袋算法(bagging from ipred)

  • 提升算法(boosting from caTools)

  • 随机森林(random forest from randomForest)

  • 神经网络(neural networks from nnet)

  • 回归树(regression tree from tree)

RTextTools有着不可不学的三大理由:

  • 首先,RTextTools的设计哲学在于易学与灵活。从而,让没有任何R编程经验的社会科学研究者也能轻松实现高端的机器学习算法;并且,让经验老道的R用户充分发挥R的威力,与其他相关的包结合,如:文本预处理方面的tm包,实现LDA主题模型的topicmodels包等,实现高难度的模型,并且充分提高模型的精度等。

  • 其次,RTextTools提供了从数据载入,数据清洗,到模型评价的所有功能,并且,实现的函数非常简单易记。即所谓的『一条龙服务』。

  • 最后,RTextTools还可以实现结构化数据的分类问题。也就是说,它可以像普通的机器学习包caret那样使用。



下面,让我们一起来见证一下RTextTools是如何在十步之内演绎文本分类这一高端技术活的。

文本分类step-by-step

1.创建矩阵

首先,载入一个自带的测试数据集:data(USCongress)。由于RTextTools集成了tm包的功能,所以tm包在文本预处理方面的功能,如去除空格、移除稀疏词、移除停止词、词干化等功能,都可以轻松实现。

library(RTextTools)
data(USCongress)

# 看看数据长啥样

str(USCongress)

## 'data.frame': 4449 obs. of  6 variables:
##  $ ID      : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ cong    : int  107 107 107 107 107 107 107 107 107 107 ...
##  $ billnum : int  4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 ...
##  $ h_or_sen: Factor w/ 2 levels "HR","S": 1 1 1 1 1 1 1 1 1 1 ...
##  $ major   : int  18 18 18 18 5 21 15 18 18 18 ...
##  $ text    : Factor w/ 4295 levels "-- Private Bill;  
For the relief of Alfonso Quezada-Bonilla.",..: 4270 4269 4273 4158 3267 3521 4175 4284 4246 4285 ...

# 创建一个文档-词项矩阵

doc_matrix<-create_matrix(USCongress$text,language ="english",removeNumbers= TRUE,stemWords = TRUE,removeSparseTerms = .998)

2.创建容器(Container)

创建好文档-词项矩阵以后,下一步要做的就是对矩阵进行训练集/测试集的划分了。RTextTools中的容器(Container)概念,使得人们不必两次读入数据,而将训练集和测试集一并读入,在容器内做区分即可。

既然我们是有监督的分类算法实现,当然不能忘了指定因变量(即类别标签)。在我们的测试数据集中,类别标签为USCongress$major。

注意:类别标签一定要为数值型!

container<-create_container(doc_matrix,USCongress$major,trainSize = 1:4000,testSize = 4001:4449,virgin = FALSE)


# 看看类别个数

length(unique(USCongress$major))

## [1] 20

这里,virgin =参数的设置影响到后续模型结果的分析解读。virgin = FALSE意味着告诉R,我们的测试集是有真实的类别标签的。

3.训练模型

数据已经准备妥当,下面就可以进行模型的训练了。前面提到的九个机器学习算法的训练,只需要写成一个向量,作为参数传入train_model()函数即可同时轻松实现各种高大上的分类器模型训练。

我们来看一下train_model()函数的使用方法。

train_model(container, algorithm=c("SVM","SLDA","BOOSTING","BAGGING",
"RF","GLMNET","TREE","NNET","MAXENT"), method = "C-classification",
cross = 0, cost = 100, kernel = "radial", maxitboost = 100,
maxitglm = 10^5, size = 1, maxitnnet = 1000, MaxNWts = 10000,
rang = 0.1, decay = 5e-04, trace=FALSE, ntree = 200,
l1_regularizer = 0, l2_regularizer = 0, use_sgd = FALSE,
set_heldout = 0, verbose = FALSE,...)

参数的设置也很简单。如果你实在懒得设置,不妨先使用默认的参数试一试。

SVM <- train_model(container,"SVM")
GLMNET <- train_model(container,"GLMNET")
MAXENT <- train_model(container,"MAXENT")
SLDA <- train_model(container,"SLDA")
BOOSTING <- train_model(container,"BOOSTING")
BAGGING <- train_model(container,"BAGGING")
RF <- train_model(container,"RF")
#NNET <- train_model(container,"NNET")
TREE <- train_model(container,"TREE")

4.使用训练好的模型进行文本分类

train_model()函数会返回一个训练好的模型对象,我们可以把该对象作为参数传给classify_model()函数,进行测试集的分类。

SVM_CLASSIFY <- classify_model(container, SVM)
GLMNET_CLASSIFY <- classify_model(container, GLMNET)
MAXENT_CLASSIFY <- classify_model(container, MAXENT)
SLDA_CLASSIFY <- classify_model(container, SLDA)
BOOSTING_CLASSIFY <- classify_model(container, BOOSTING)
BAGGING_CLASSIFY <- classify_model(container, BAGGING)
RF_CLASSIFY <- classify_model(container, RF)
#NNET_CLASSIFY <- classify_model(container, NNET)
TREE_CLASSIFY <- classify_model(container, TREE)

5.结果分析

create_analytics()函数提供了对测试集的分类结果的四种解读:从标签出发;从算法对比出发;从角度文档出发;以及整体评价。

analytics <- create_analytics(container,
cbind(SVM_CLASSIFY, SLDA_CLASSIFY,
BOOSTING_CLASSIFY, BAGGING_CLASSIFY,
RF_CLASSIFY, GLMNET_CLASSIFY, TREE_CLASSIFY,
MAXENT_CLASSIFY))

6.测试分类器准确率(accuracy)

create_analytics()返回的对象适用于summary()和print()方法。

summary(analytics)

## ENSEMBLE SUMMARY
##
##        n-ENSEMBLE COVERAGE n-ENSEMBLE RECALL
## n >= 1                1.00              0.77
## n >= 2                1.00              0.77

## n >= 3                0.99              0.78
## n >= 4                0.90              0.82
## n >= 5                0.76              0.87
## n >= 6                0.62              0.90
## n >= 7                0.46              0.93
## n >= 8                0.24              0.96
##
##
## ALGORITHM PERFORMANCE##
##        SVM_PRECISION           SVM_RECALL           SVM_FSCORE
##               0.6830               0.6530               0.6540
##       SLDA_PRECISION          SLDA_RECALL          SLDA_FSCORE
##               0.6530               0.6375               0.6295
## LOGITBOOST_PRECISION    LOGITBOOST_RECALL    LOGITBOOST_FSCORE

##               0.5955               0.6005               0.5775
##    BAGGING_PRECISION       BAGGING_RECALL       BAGGING_FSCORE
##               0.5465               0.3905               0.4005
##    FORESTS_PRECISION       FORESTS_RECALL       FORESTS_FSCORE
##               0.6850               0.6365               0.6415
##     GLMNET_PRECISION        GLMNET_RECALL        GLMNET_FSCORE

##               0.6840               0.6440               0.6415

##       TREE_PRECISION          TREE_RECALL          TREE_FSCORE
##               0.2035               0.2160               0.1795
## MAXENTROPY_PRECISION    MAXENTROPY_RECALL    MAXENTROPY_FSCORE
##               0.6145               0.6325               0.6190

# 为分析结果建立一个数据框
topic_summary <- analytics@label_summary
alg_summary <- analytics@algorithm_summary
ens_summary <-analytics@ensemble_summary

doc_summary <- analytics@document_summary

summary(analytics)返回了精度(precision),召回率(recall)和F-值(F-Score)等指标。这三个指标是文本分类中常用的评价指标。

精度的定义为预测为真实正例的个数除以所有被预测为正例样本的个数。召回率则是预测为真实正例的个数除以所有真实正例样本的个数。F-值则同时考虑了精度和召回率,是两个指标的折衷。

7.整体效果评价(Ensemble agreement)

create_ensembleSummary()函数提供了整体评价功能。它反映了我们所应用的几种分类算法的『同时命中率』。

create_ensembleSummary(analytics@document_summary)

##        n-ENSEMBLE COVERAGE n-ENSEMBLE RECALL
## n >= 1                1.00              0.77
## n >= 2                1.00              0.77
## n >= 3                0.99              0.78
## n >= 4                0.90              0.82
## n >= 5                0.76              0.87
## n >= 6                0.62              0.90
## n >= 7                0.46              0.93
## n >= 8                0.24              0.96

整体评价函数提供了两个评价指标:Coverage和Recall。

Coverage衡量了达到召回率阈值的文档百分比。

Coverage的定义如下: