在之前的开篇提到了text2vec,笔者将其定义为R语言文本分析"No.1",她是一个文本分析的生态系统。笔者在学习之后发现开发者简直牛!基于分享精神,将自学笔记记录出来。开篇内容参考:

重磅︱R+NLP:text2vec包——New 文本分析生态系统 No.1(一,简介)

文档可以以多种方式表达,单独词组、n-grams、特征hashing化的方法等。
      一般来说文本分析的步骤有以下三个步骤:
      1、第一步:把内容表达成为文档-词组矩阵(document-term矩阵,DTM)或者词组共现矩阵(term-co-occurrence矩阵,TCM),换言之第一步就是在文档之上创造一个词条地图。
      2、第二步:找个模型在DTM上进行拟合,有LDA、文本分类等
      3、第三步:在验证集上进行验证

本文在此基础上,将一个官方案例予以演示,算得上是翻译他们官方文档。

————————————————————————————————

一、BOW词袋模型

Bag-of-words model (BoW model)最早出现在自然语言处理(Natural Language Processing)和信息检索(Information Retrieval)领域.。该模型忽略掉文本的语法和语序等要素,将其仅仅看作是若干个词汇的集合,文档中每个单词的出现都是独立的。BoW使用一组无序的单词(words)来表达一段文字或一个文档.。近年来,BoW模型被广泛应用于计算机视觉中。

基于文本的BoW模型的一个简单例子如下:

首先给出两个简单的文本文档如下:

John likes to watch movies. Mary likes too.

John also likes to watch football games.

基于上述两个文档中出现的单词,构建如下一个词典 (dictionary):

{"John": 1, "likes": 2,"to": 3, "watch": 4, "movies": 5,"also": 6, "football": 7, "games": 8,"Mary": 9, "too": 10}

上面的词典中包含10个单词, 每个单词有唯一的索引, 那么每个文本我们可以使用一个10维的向量来表示。如下:

[1, 2, 1, 1, 1, 0, 0, 0, 1, 1]

[1, 1,1, 1, 0, 1, 1, 1, 0, 0]

该向量与原来文本中单词出现的顺序没有关系,而是词典中每个单词在文本中出现的频率。

Distributed Representation是一个稠密、低维的实数限量,它的每一维表示词语的一个潜在特征,该特征捕获了有用的句法和语义特征。其特点是将词语的不同句法和语义特征分布到它的每一个维度上去表示。

关于词袋模型的介绍可以看我的另外一篇博客:自然语言处理︱简述四大类文本分析中的“词向量”(文本词特征提取)

BOW算得上是最简单,但效果竟然也还不错的办法。

————————————————————————————————

二、text2vec基于BOW的情感标注

本文选用的是text2vec开发者自带的数据集,有ID、sentiment代表情感正负面、review代表电影简介的内容。

同样,text2vec的数据结构迁入的是data.table,所以效率极高,纵观来看,开发者都很有良心,每个环节都十分注意效率,再次给赞,关于data,table包可以参考我的另外一篇博客:R︱高效数据操作——data.table包(实战心得、dplyr对比、key灵活用法、数据合并)。

1、数据准备

library(text2vec)
library(data.table)
data("movie_review")
setDT(movie_review)
setkey(movie_review, id)
set.seed(2016L)
all_ids = movie_review$id
train_ids = sample(all_ids, 4000)
test_ids = setdiff(all_ids, train_ids)
train = movie_review[J(train_ids)]
test = movie_review[J(test_ids)]

同时区分训练集train与测试集test,利用的是sample函数设置,setDT与setkey是data.table包的主要内容,设置关键KEY,后续很多分析都即为有用。

2、文档向量化(Vectorization)

构造的是一个文档-词频矩阵(DTM矩阵),不同文档、不同词发生的次数。这个稀疏矩阵的表达有两种方式:一种就是n-grams(前面提到的BOW)另外一种就是Hashing化(Feature Hashing)。

text2vec构造DTM矩阵,可有点费劲,来看看流程:

(1)设置分词迭代器,itoken;

(2)分词,create_vocabulary,英文里面直接分割即可,中文可就麻烦了,这里中文可不一样,官方案例是英文的,所以还需要自己处理一下。

(3)设置、形成语料文件,vocab_vectorizer

(4)构建DTM矩阵,create_dtm

尼玛,看下来真是烦,这么多步骤。但是,为什么这么多步骤呢?效率...这么做效率极高,笔者在自己写了一些函数才深刻体会到,R语言的文本分析对效率的要求有多高...  哭个...来看看代码:

prep_fun = tolower
tok_fun = word_tokenizerit_train = itoken(train$review, preprocessor = prep_fun, tokenizer = tok_fun, ids = train$id, progressbar = FALSE)
vocab = create_vocabulary(it_train)

其中的itoken中的参数很多,来解读一下,tok_fun代表词语划分成什么程度,是否需要标点等。

tolower代表英文字符通通变成小写。

vectorizer = vocab_vectorizer(vocab)
dtm_train = create_dtm(it_train, vectorizer)

这里细心的同学一定要注意、留意最后生成的文档顺序以及ID是否一一对应,本次案例当然是一一对应,但是在自己操作的过程中,很容易出现,生成的DTM文档顺序发生了改变,你还不知道怎么改变,然后复查可就麻烦大了。

identical(rownames(dtm_train), train$id)

identical是检验两个值是否完全相等的函数,如果相等则会返回TRUE,相关内容参考我的博客:R语言︱集合运算——小而美法则

3、基于logistics的情感标注

监督式的机器学习算法很多,当然选用一个较为经典、解释性比较强的方法,logistics就是这样的办法,不会的戳我的博客:笔记+R︱Logistics建模简述(logit值)

利用的是R语言中的glmnet包。

library(glmnet)
NFOLDS = 4
glmnet_classifier = cv.glmnet(x = dtm_train, y = train[['sentiment']], family = 'binomial', # L1 penaltyalpha = 1,# interested in the area under ROC curvetype.measure = "auc",# 5-fold cross-validationnfolds = NFOLDS,# high value is less accurate, but has faster trainingthresh = 1e-3,# again lower number of iterations for faster trainingmaxit = 1e3)

L1正则化惩罚(不会戳我博客:笔记︱范数正则化L0、L1、L2-岭回归&Lasso回归(稀疏与特征工程)),4折交叉验证。最后plot一下可以看到CV图:


      最大AUC值为0.923,这是训练集的AUC,那么来看看验证集的效果怎么样。

it_test = test$review %>% prep_fun %>% tok_fun %>% itoken(ids = test$id, # turn off progressbar because it won't look nice in rmdprogressbar = FALSE)dtm_test = create_dtm(it_test, vectorizer)preds = predict(glmnet_classifier, dtm_test, type = 'response')[,1]
glmnet:::auc(test$sentiment, preds)

最终验证集AUC值为0.91667,效果还不错。

————————————————————————————————

三、text2vec基于BOW的情感标注的优化

1、消除低词频单词

一些停用词、一些低频无效词都是文本噪声。所以针对停用词stopword可以在分词步骤create_vocabulary予以处理,譬如:

stop_words = c("i", "me", "my", "myself", "we", "our", "ours", "ourselves", "you", "your", "yours")
vocab = create_vocabulary(it_train, stopwords = stop_words)

针对一些低频词的修剪,可以在分词create_vocabulary步骤之后以及设置、形成语料文件,vocab_vectorizer之前进行处理:

pruned_vocab = prune_vocabulary(vocab, term_count_min = 10, doc_proportion_max = 0.5,doc_proportion_min = 0.001)
vectorizer = vocab_vectorizer(pruned_vocab)

term_count自然就是词频,低于10的都删掉了。

2、增加文字信息量n-gram

之前模型中都是单独分开,现在可以多多考虑2-grams,就在分词步骤进行优化。那么先来看看n-grams是啥?

如果是1-ngrams,有一句话:you need many money

分割成:

   terms terms_counts doc_counts
1: money            1          1
2:  many            1          1
3:  need            1          1
4:   you            1          1

那么2-ngrams呢?

        terms terms_counts doc_counts
1:      money            1          1
2: many_money            1          1
3:       many            1          1
4:  need_many            1          1
5:   you_need            1          1
6:       need            1          1
7:        you            1          1

譬如一些内容就以小组合的形式出现了。不过,最后尝试建模之后,训练集的AUC值为0.9268,跟原来几乎差不多。。。

3、效率优化:feature hashing化

为什么提到这个呢?R语言的文本处理效率本身不高,而且大数据集下,任何处理软件的处理都显得很无力,所以hash化是一个不可避免的趋势。这一趋势,被雅虎广泛使用( Vowpal Wabbit)。hashing化的好处主要有两个:

1、非常快,效率高

2、内存占用很低。

关于哈希化,可参考我的博客:R语言实现︱局部敏感哈希算法(LSH)解决文本机械相似性的问题(一,基本原理)

Hash化主要在第三步,设置、形成语料文件时进行操作,之后操作一样。

h_vectorizer = hash_vectorizer(hash_size = 2 ^ 14, ngram = c(1L, 2L))

验证之后,验证集的AUC为0.903,下降了2%左右,但是换来了最大化效率的提升,物超所值。

4、数据转变优化方法一:标准化

常规的标准化很常见,不懂的戳我博客:R语言︱数据规范化、归一化

一般来说,文本分析中有时候文档长度很长,但是这一指标对最终结果都是无效的,所以需要惩罚一下文档长度。

text2vec中包括了以下两类标准化,L1normalization与L2 normalization,这是图像处理中较为常见的标准化方式,参考来自博客图像处理中的L1-normalize 和L2-normalize

当一幅图像用某种特征表示出来,一般要进行L1-normalize或者是L2-normalize。

假设一幅图像表示为Y=[x1 x2 x3 x4 x5],

L1-normalize的结果为:

L2-normalize的结果为:

通过L1或L2标准化的图像特征往往具有良好的效果,至于那个更好就需要自己试验。

数据转化主要作用在DTM上,所以是第四步之后,而且主要用于惩罚文档,l1(归一化)的效果就是每行相加为1,函数如下:

dtm_train_l1_norm = normalize(dtm_train, "l1")

有以下三种可选方式:l1 l2 none。

5、数据转变优化方法二:TFIDF

      同样也是作用在DTM最后一步步骤,作用过程也有些繁琐:

(1)设置TFIDF编译器tfidf = TfIdf$new();

(2)转换成TFIDF格式fit_transform(dtm_train, tfidf)。

dtm_train = create_dtm(it_train, vectorizer)tfidf = TfIdf$new()
dtm_train_tfidf = fit_transform(dtm_train, tfidf)
dtm_test_tfidf  = create_dtm(it_test, vectorizer) %>% transform(tfidf)

当然从代码的最简化的角度,可以写成下面这样:

dtm_test_tfidf  = create_dtm(it_test, vectorizer) %>% transform(tfidf)

最终结果验证集的AUC值为0.905,貌似还降低了。不过,TFIDF对于效率的提升很显著,一般的任务都是会提升的。所以,是个提升精度的好办法。

————————————————————————————————

应用一:在text2vec中灵活的进行数据转化、并建模

从第三章节来看,数据转化一般是形成DTM之后,或者通过fit或者通过fit_transform来进行数据转化。使用起来可以非常灵活,而且已经生成了DTM,你怎么玩都会出结果,这一点有点厉害!!

1、数据转化之后,可以后续直接分析,而且跟之前的内容是具有可比性的。

2、灵活,可以的情况是,训练集没有进行TFIDF,而测试集可以进行TFIDF转化,单独看效果如何

R+NLP︱text2vec包——BOW词袋模型做监督式情感标注案例(二,情感标注)相关推荐

  1. R+NLP︱text2vec包——四类文本挖掘相似性指标 RWMD、cosine、Jaccard 、Euclidean (三,相似距离)

    要学的东西太多,无笔记不能学~~ 欢迎关注公众号,一起分享学习笔记,记录每一颗"贝壳"~ --------------------------- 在之前的开篇提到了text2vec ...

  2. BoW词袋模型原理学习及Python实现

    文章目录 BoW词袋模型原理 为什么要用BoW模型描述图像 构建BoW码本步骤 编码 测试 BoW词袋模型原理 BoW(Bag of Words)词袋模型最初被用在文本分类中,将文档表示成特征矢量.它 ...

  3. NLP实践六:词袋模型到word2vec

    文章目录 一.词袋模型 二 wordembedding one-hot 共现矩阵Cocurrence matrix Distributed representation word2vec 三 word ...

  4. 【ORB-SLAM3】BOW词袋模型

    基于视觉的闭环检测可以描述为,给定一张输入图像,在历史图像数据库中高效准确地搜索出与之相似的图像.而通常的穷举搜索法效率低下,类帧差法受制于图像视角变化.光照变化.曝光等因素无法稳定识别相似图像. 词 ...

  5. BoW词袋模型Bag of Words cpp实现(stable version 0.01)

    致谢:基础框架来源BoW,开发版本在此基础上进行,已在Ubuntu.OS X上测试通过,Windows需要支持c++11的编译器(VS2012及其以上). 使用 代码下载地址:bag-of-words ...

  6. 重磅︱R+NLP:text2vec包——New 文本分析生态系统 No.1(一,简介)

    每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 词向量的表示主流的有两种方式,一种当然是耳熟能 ...

  7. 词袋模型BoW图像检索Python实战

    前几天把HABI哈希图像检索工具包更新到V2.0版本后,小白菜又重新回头来用Python搞BoW词袋模型,一方面主要是练练Python,另一方面也是为了CBIR群开讲的关于图像检索群活动第二期而准备的 ...

  8. 【NLP】毕设学习笔记(一):词袋模型、主题模型、词嵌入

    NLP分类方法历史 词袋模型(1954) One-hot TF-IDF N-gram 主题模型(1998) LSA pLSA LDA 词嵌入(word embedding) word2vec(2013 ...

  9. 词袋 图像检索 matlab,词袋模型BoW图像检索Python实战

    前几天把HABI哈希图像检索工具包更新到V2.0版本后,小白菜又重新回头来用Python搞BoW词袋模型,一方面主要是练练Python,另一方面也是为了CBIR群开讲的关于图像检索群活动第二期而准备的 ...

最新文章

  1. 循环-20. 猜数字游戏(15)
  2. mysql游标表间数据迁移_FalseMySQL存储过程--gt;通过游标遍历和异常处理迁移数据到历史表-mysql-第二电脑网...
  3. react router v4 简介
  4. Magic Odd Square 思维
  5. python接口自动化 post请求,body 带headers参数
  6. Java程序员最常犯的错误盘点之Top 10
  7. 豪横!1.3 亿的数据毫秒级???居然做到了!!!
  8. LeetCode(2) 两数相加递归解法,速度最快,内存消耗最小
  9. 番茄助手-解决vs2010没有智能提示问题
  10. CorelDRAWX4的VBA插件开发(六)录制宏与调试
  11. UA PHYS515A 电磁学II 静电学问题8 球坐标系中的Laplace方程与球谐函数
  12. matlab匿名函数求导,MATLAB进行匿名函数求导出现错误
  13. 新浪微博热门话题 (30 分)
  14. 志在必得的。。。。失败。。。
  15. 如何把动态硬盘转换为基本硬盘
  16. tensorflow conv2d()参数解析
  17. Ubuntu 更新glibc
  18. The Part-Time Parliament
  19. 蚂蚁感冒问题暴力解决
  20. [整理]统计数据的可视化——数据的频数分布

热门文章

  1. 【JS点滴】substring和substr以及slice和splice的用法和区别。
  2. 字符串,列表,元组,字典基本函数
  3. Linux格式化分区报错Could not start /dev/sda No such file or directory 解决办法
  4. 【原】iOSCoreAnimation动画系列教程(二):CAKeyFrameAnimation【包会】
  5. 几年的写论文和审稿心得
  6. 再谈 Formsville
  7. 深圳卫视 - 饭没了秀
  8. Ubuntu挂载U盘相关
  9. 长按UIWebView上的图片保存到相册
  10. 【C#】WM 消息大全