R语言——中文分词包jiebaR

R的极客理想系列文章,涵盖了R的思想,使用,工具,创新等的一系列要点,以我个人的学习和体验去诠释R的强大。

R语言作为统计学一门语言,一直在小众领域闪耀着光芒。直到大数据的爆发,R语言变成了一门炙手可热的数据分析的利器。随着越来越多的工程背景的人的加入,R语言的社区在迅速扩大成长。现在已不仅仅是统计领域,教育,银行,电商,互联网….都在使用R语言。

要成为有理想的极客,我们不能停留在语法上,要掌握牢固的数学,概率,统计知识,同时还要有创新精神,把R语言发挥到各个领域。让我们一起动起来吧,开始R的极客理想。

关于作者:

  • 张丹(Conan), 程序员Java,R,PHP,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/r-word-jiebar/

http://blog.fens.me/wp-content/uploads/2016/07/jiebaR.png

前言

本文挖掘是数据挖掘中一个非常重要的部分,有非常广阔的使用场景,比如我们可以对新闻事件进行分析,了解国家大事;也可以对微博信息进行分析,通过社交舆情看看大家的关注点。通过文本挖掘找到文章中的隐藏信息,对文章的结构进行分析,判断是不是同一个作者写文章;同时可以对邮件分析,结合bayes算法判断哪些是垃圾邮件,哪些是有用的邮件。

本文挖掘的第一步,就是要进行分词,分词将直接影响文本挖掘的效果。R语言在分词方面有很好的支持,接下来就给大家介绍一个不错的R语言中文分词包“结巴分词”(jiebaR)。

目录

  1. jiebaR包介绍
  2. 5分钟上手
  3. 分词引擎
  4. 配置词典
  5. 停止词过滤
  6. 关键词提取

1. jiebaR包介绍

结巴分词(jiebaR),是一款高效的R语言中文分词包,底层使用的是C++,通过Rcpp进行调用很高效。结巴分词基于MIT协议,就是免费和开源的,感谢国人作者的给力支持,让R的可以方便的处理中文文本。

官方Github的地址:https://github.com/qinwf/jiebaR

本文所使用的系统环境

  • Win10 64bit
  • R: 3.2.3 x86_64-w64-mingw32/x64 b4bit

jiebaR包是在CRAN发布的标准库,安装起来非常简单,2条命令就可以了。

  1.  
     
  2.  
    ~ R
  3.  
    > install.packages("jiebaR")
  4.  
    > library("jiebaR")

如果想要安装开发版本,可以使用devtools来进行安装,devtools的介绍请参考文章:在巨人的肩膀前行 催化R包开发

  1.  
     
  2.  
    > library(devtools)
  3.  
    > install_github("qinwf/jiebaRD")
  4.  
    > install_github("qinwf/jiebaR")
  5.  
    > library("jiebaR")

开发版本安装,官方建议使用Linux系统 gcc >= 4.6 编译,Windows需要安装 Rtools。

2. 5分钟上手

5分钟上手,直接看第一个例子吧,对一段文字进行分词。

  1.  
     
  2.  
    > wk = worker()
  3.  
     
  4.  
    > wk["我是《R的极客理想》图书作者"]
  5.  
    [1] "我是" "R" "的" "极客" "理想" "图书" "作者"
  6.  
     
  7.  
    > wk["我是R语言的深度用户"]
  8.  
    [1] "我" "是" "R" "语言" "的" "深度" "用户"

很简单地,2行代码,就完成了中文分词。

jiebaR提供了3种分词语句的写法,例子上面的用[]符号的语法,还可以使用<=符合语法,或者使用segment()函数。虽然形式不同,但是分词效果是一样的。使用<=符号的语法,如下

  1.  
     
  2.  
    > wk<='另一种符合的语法'
  3.  
    [1] "另" "一种" "符合" "的" "语法"

使用segment()函数的语法,如下

  1.  
     
  2.  
    > segment( "segment()函数语句的写法" , wk )
  3.  
    [1] "segment" "函数" "语句" "的" "写法"

如果你觉得很神奇,想了解如何自定义操作符的,可以检查项目的源代码quick.R文件

  1.  
     
  2.  
    # <= 符号定义
  3.  
    `<=.qseg`<-function(qseg, code){
  4.  
    if(!exists("quick_worker",envir = .GlobalEnv ,inherits = F) ||
  5.  
    .GlobalEnv$quick_worker$PrivateVarible$timestamp != TIMESTAMP){
  6.  
     
  7.  
    if(exists("qseg",envir = .GlobalEnv,inherits = FALSE ) )
  8.  
    rm("qseg",envir = .GlobalEnv)
  9.  
     
  10.  
    modelpath = file.path(find.package("jiebaR"),"model","model.rda")
  11.  
    quickparam = readRDS(modelpath)
  12.  
     
  13.  
    if(quickparam$dict == "AUTO") quickparam$dict = DICTPATH
  14.  
    if(quickparam$hmm == "AUTO") quickparam$hmm = HMMPATH
  15.  
    if(quickparam$user == "AUTO") quickparam$user = USERPATH
  16.  
    if(quickparam$stop_word == "AUTO") quickparam$stop_word = STOPPATH
  17.  
    if(quickparam$idf == "AUTO") quickparam$idf = IDFPATH
  18.  
     
  19.  
    createquickworker(quickparam)
  20.  
    setactive()
  21.  
    }
  22.  
     
  23.  
    //..代码省略
  24.  
    }
  25.  
     
  26.  
    # [ 符号定义
  27.  
    `[.qseg`<- `<=.qseg`
  28.  
     

我们也可以直接对文本文件进行分词,在当前目录新建一个文本文件idea.txt。

  1.  
     
  2.  
    ~ notepad idea.txt
  3.  
     
  4.  
    R的极客理想系列文章,涵盖了R的思想,使用,工具,创新等的一系列要点,以我个人的学习和体验去诠释R的强大。
  5.  
     
  6.  
    R语言作为统计学一门语言,一直在小众领域闪耀着光芒。直到大数据的爆发,R语言变成了一门炙手可热的数据分析的利器。随着越来越多的工程背景的人的加入,R语言的社区在迅速扩大成长。现在已不仅仅是统计领域,教育,银行,电商,互联网….都在使用R语言。

当然,我们运行分词程序,会在当前目录生成一个新的分词结果的文件。

  1.  
     
  2.  
    > wk['./idea.txt']
  3.  
    [1] "./idea.segment.2016-07-20_23_25_34.txt"

打开文件idea.segment.2016-07-20_23_25_34.txt,整个本文以空格进行分词。

  1.  
     
  2.  
    ~ notepad idea.segment.2016-07-20_23_25_34.txt
  3.  
     
  4.  
    R 的 极客 理想 系列 文章 涵盖 了 R 的 思想 使用 工具 创新 等 的 一系列 要点 以 我 个人 的 学习 和 体验 去 诠释 R 的 强大 R 语言 作为 统计学 一门 语言 一直 在 小众 领域 闪耀着 光芒 直到 大 数据 的 爆发 R 语言 变成 了 一门 炙手可热 的 数据分析 的 利器 随着 越来越 多 的 工程 背景 的 人 的 加入 R 语言 的 社区 在 迅速 扩大 成长 现在 已 不仅仅 是 统计 领域 教育 银行 电商 互联网 都 在 使用 R 语言

是不是很简单,5分钟实践就能完成分词的任务。

3. 分词引擎

在调用worker()函数时,我们实际是在加载jiebaR库的分词引擎。jiebaR库提供了7种分词引擎。

  • 混合模型(MixSegment):是四个分词引擎里面分词效果较好的类,结它合使用最大概率法和隐式马尔科夫模型。
  • 最大概率法(MPSegment) :负责根据Trie树构建有向无环图和进行动态规划算法,是分词算法的核心。
  • 隐式马尔科夫模型(HMMSegment):是根据基于人民日报等语料库构建的HMM模型来进行分词,主要算法思路是根据(B,E,M,S)四个状态来代表每个字的隐藏状态。 HMM模型由dict/hmm_model.utf8提供。分词算法即viterbi算法。
  • 索引模型(QuerySegment):先使用混合模型进行切词,再对于切出来的较长的词,枚举句子中所有可能成词的情况,找出词库里存在。
  • 标记模型(tag)
  • Simhash模型(simhash)
  • 关键词模型(keywods)

如果你不太关心引擎的事,那么直接用官方推荐的混合模型(默认选择)就行了。查看worker()函数的定义。

  1.  
     
  2.  
    worker(type = "mix", dict = DICTPATH, hmm = HMMPATH, user = USERPATH,
  3.  
    idf = IDFPATH, stop_word = STOPPATH, write = T, qmax = 20, topn = 5,
  4.  
    encoding = "UTF-8", detect = T, symbol = F, lines = 1e+05,
  5.  
    output = NULL, bylines = F, user_weight = "max")

参数列表:

  • type, 引擎类型
  • dict, 系统词典
  • hmm, HMM模型路径
  • user, 用户词典
  • idf, IDF词典
  • stop_word, 关键词用停止词库
  • write, 是否将文件分词结果写入文件,默认FALSE
  • qmax, 最大成词的字符数,默认20个字符
  • topn, 关键词数,默认5个
  • encoding, 输入文件的编码,默认UTF-8
  • detect, 是否编码检查,默认TRUE
  • symbol, 是否保留符号,默认FALSE
  • lines, 每次读取文件的最大行数,用于控制读取文件的长度。大文件则会分次读取。
  • output, 输出路径
  • bylines, 按行输出
  • user_weight, 用户权重

我们在调用worker()时,就加载了分词引擎,可以打印出来,查看分词的引擎的配置。

  1.  
     
  2.  
    > wk = worker()
  3.  
    > wk
  4.  
    Worker Type: Jieba Segment
  5.  
     
  6.  
    Default Method : mix # 混合模型
  7.  
    Detect Encoding : TRUE # 检查编码
  8.  
    Default Encoding: UTF-8 # UTF-8
  9.  
    Keep Symbols : FALSE # 不保留符号
  10.  
    Output Path : # 输出文件目录
  11.  
    Write File : TRUE # 写文件
  12.  
    By Lines : FALSE # 不行输出
  13.  
    Max Word Length : 20 # 最大单单词长度
  14.  
    Max Read Lines : 1e+05 # 最大读入文件行数
  15.  
     
  16.  
    Fixed Model Components:
  17.  
     
  18.  
    $dict # 系统词典
  19.  
    [1] "D:/tool/R-3.2.3/library/jiebaRD/dict/jieba.dict.utf8"
  20.  
     
  21.  
    $user # 用户词典
  22.  
    [1] "D:/tool/R-3.2.3/library/jiebaRD/dict/user.dict.utf8"
  23.  
     
  24.  
    $hmm # 隐式马尔科夫模型模型
  25.  
    [1] "D:/tool/R-3.2.3/library/jiebaRD/dict/hmm_model.utf8"
  26.  
     
  27.  
    $stop_word # 停止词,无
  28.  
    NULL
  29.  
     
  30.  
    $user_weight # 用户词典权重
  31.  
    [1] "max"
  32.  
     
  33.  
    $timestamp # 时间戳
  34.  
    [1] 1469027302
  35.  
     
  36.  
    $default $detect $encoding $symbol $output $write $lines $bylines can be reset.

如果我们想改变分词引擎的配置项,可以在调用worker()创建分词引擎时,也可以通过wk$XX来进行设置。如果想了解wk是什么类型的对象,我们通过pryr包的otype的函数来检查wk对象的类型。关于pryr包的详细使用,请参考文章撬动R内核的高级工具包pryr

  1.  
     
  2.  
    # 加载 pryr包
  3.  
    > library(pryr)
  4.  
    > otype(wk) # 面向对象的类型检查
  5.  
    [1] "S3"
  6.  
     
  7.  
    > class(wk) # 查看class是属性
  8.  
    [1] "jiebar" "segment" "jieba"

4. 配置词典

对于分词的结果好坏的关键因素是词典,jiebaR默认有配置标准的词典。对于我们的使用来说,不同行业或不同的文字类型,最好用专门的分词词典。在jiebaR中通过show_dictpath()函数可以查看默认的标准词典,可以通过上一小节介绍的配置项,来指定我们自己的词典。日常对话的常用词典,比如搜狗输入法的词库。

  1.  
     
  2.  
    # 查看默认的词库位置
  3.  
    > show_dictpath()
  4.  
    [1] "D:/tool/R-3.2.3/library/jiebaRD/dict"
  5.  
     
  6.  
    # 查看目录
  7.  
    > dir(show_dictpath())
  8.  
    [1] "D:/tool/R-3.2.3/library/jiebaRD/dict"
  9.  
    [1] "backup.rda" "hmm_model.utf8" "hmm_model.zip"
  10.  
    [4] "idf.utf8" "idf.zip" "jieba.dict.utf8"
  11.  
    [7] "jieba.dict.zip" "model.rda" "README.md"
  12.  
    [10] "stop_words.utf8" "user.dict.utf8"

看到词典目录中,包括了多个文件。

  • jieba.dict.utf8, 系统词典文件,最大概率法,utf8编码的
  • hmm_model.utf8, 系统词典文件,隐式马尔科夫模型,utf8编码的
  • user.dict.utf8, 用户词典文件,utf8编码的
  • stop_words.utf8,停止词文件,utf8编码的
  • idf.utf8,IDF语料库,utf8编码的
  • jieba.dict.zip,jieba.dict.utf8的压缩包
  • hmm_model.zip,hmm_model.utf8的压缩包
  • idf.zip,idf.utf8的压缩包
  • backup.rda,无注释
  • model.rda,无注释
  • README.md,说明文件

打开系统词典文件jieba.dict.utf8,并打印前50行。

  1.  
     
  2.  
    > scan(file="D:/tool/R-3.2.3/library/jiebaRD/dict/jieba.dict.utf8",
  3.  
    + what=character(),nlines=50,sep='\n',
  4.  
    + encoding='utf-8',fileEncoding='utf-8')
  5.  
    Read 50 items
  6.  
    [1] "1号店 3 n" "1號店 3 n" "4S店 3 n" "4s店 3 n"
  7.  
    [5] "AA制 3 n" "AB型 3 n" "AT&T 3 nz" "A型 3 n"
  8.  
    [9] "A座 3 n" "A股 3 n" "A輪 3 n" "A轮 3 n"
  9.  
    [13] "BB机 3 n" "BB機 3 n" "BP机 3 n" "BP機 3 n"
  10.  
    [17] "B型 3 n" "B座 3 n" "B股 3 n" "B超 3 n"
  11.  
    [21] "B輪 3 n" "B轮 3 n" "C# 3 nz" "C++ 3 nz"
  12.  
    [25] "CALL机 3 n" "CALL機 3 n" "CD机 3 n" "CD機 3 n"
  13.  
    [29] "CD盒 3 n" "C座 3 n" "C盘 3 n" "C盤 3 n"
  14.  
    [33] "C語言 3 n" "C语言 3 n" "D座 3 n" "D版 3 n"
  15.  
    [37] "D盘 3 n" "D盤 3 n" "E化 3 n" "E座 3 n"
  16.  
    [41] "E盘 3 n" "E盤 3 n" "E通 3 n" "F座 3 n"
  17.  
    [45] "F盘 3 n" "F盤 3 n" "G盘 3 n" "G盤 3 n"
  18.  
    [49] "H盘 3 n" "H盤 3 n"

我们发现系统词典每一行都有三列,并以空格分割,第一列为词项,第二列为词频,第三列为词性标记。

打开用户词典文件user.dict.utf8,并打印前50行。

  1.  
     
  2.  
    > scan(file="D:/tool/R-3.2.3/library/jiebaRD/dict/user.dict.utf8",
  3.  
    + what=character(),nlines=50,sep='\n',
  4.  
    + encoding='utf-8',fileEncoding='utf-8')
  5.  
    Read 5 items
  6.  
    [1] "云计算" "韩玉鉴赏" "蓝翔 nz" "CEO" "江大桥"

用户词典第一行有二列,,第一列为词项,第二列为词性标记,没有词频的列。用户词典默认词频为系统词库中的最大词频。

jiebaR包关于词典词性标记,采用ictclas的标记方法。ICTCLAS 汉语词性标注集。

代码名称帮助记忆的诠释
Ag 形语素 形容词性语素。形容词代码为a,语素代码g前面置以A。
a 形容词 取英语形容词adjective的第1个字母。
ad 副形词 直接作状语的形容词。形容词代码a和副词代码d并在一起。
an 名形词 具有名词功能的形容词。形容词代码a和名词代码n并在一起。
b 区别词 取汉字"别"的声母。
c 连词 取英语连词conjunction的第1个字母。
Dg 副语素 副词性语素。副词代码为d,语素代码g前面置以D。
d 副词 取adverb的第2个字母,因其第1个字母已用于形容词。
e 叹词 取英语叹词exclamation的第1个字母。
f 方位词 取汉字"方"的声母。
g 语素 绝大多数语素都能作为合成词的"词根",取汉字"根"的声母。
h 前接成分 取英语head的第1个字母。
i 成语 取英语成语idiom的第1个字母。
j 简称略语 取汉字"简"的声母。
k 后接成分  
l 习用语 习用语尚未成为成语,有点"临时性",取"临"的声母。
m 数词 取英语numeral的第3个字母,n,u已有他用。
Ng 名语素 名词性语素。名词代码为n,语素代码g前面置以N。
n 名词 取英语名词noun的第1个字母。
nr 人名 名词代码n和"人(ren)"的声母并在一起。
ns 地名 名词代码n和处所词代码s并在一起。
nt 机构团体 "团"的声母为t,名词代码n和t并在一起。
nz 其他专名 "专"的声母的第1个字母为z,名词代码n和z并在一起。
o 拟声词 取英语拟声词onomatopoeia的第1个字母。
p 介词 取英语介词prepositional的第1个字母。
q 量词 取英语quantity的第1个字母。
r 代词 取英语代词pronoun的第2个字母,因p已用于介词。
s 处所词 取英语space的第1个字母。
Tg 时语素 时间词性语素。时间词代码为t,在语素的代码g前面置以T。
t 时间词 取英语time的第1个字母。
u 助词 取英语助词auxiliary 的第2个字母,因a已用于形容词。
Vg 动语素 动词性语素。动词代码为v。在语素的代码g前面置以V。
v 动词 取英语动词verb的第一个字母。
vd 副动词 直接作状语的动词。动词和副词的代码并在一起。
vn 名动词 指具有名词功能的动词。动词和名词的代码并在一起。
w 标点符号  
x 非语素字 非语素字只是一个符号,字母x通常用于代表未知数、符号。
y 语气词 取汉字"语"的声母。
z 状态词 取汉字"状"的声母的前一个字母。

下面我们自定义一个用户词典,来试试效果。编写词典文件,user.utf8。

  1.  
     
  2.  
    ~ notepad user.utf8
  3.  
     
  4.  
    R语言
  5.  
    R的极客理想
  6.  
    大数据
  7.  
    数据
  8.  
     

使用我们的自定义的用户词典,对刚才的文本再进行分词。

  1.  
     
  2.  
    > wk = worker(user='user.utf8')
  3.  
    > wk['./idea.txt']
  4.  
    [1] "./idea.segment.2016-07-21_11_14_24.txt"

对比2次产生的分词结果,idea.segment.2016-07-20_23_25_34.txt 和 idea.segment.2016-07-21_11_14_24.txt。

jiebaR-cut

在实际使用中,jiebaR默认提供的用户词典只有5个单词,太简单了,肯定是不够用的。我们可以用搜狗词典,来丰富用户自己的词库。接下来,让我们配置搜狗词典。你需要安装一个搜狗输入法,具体的安装过程不再解释。

我安装的是搜狗五笔输入法,找到搜狗的安装目录,并找到词典文件。我的搜狗词典,在下面的安装位置。

  1.  
     
  2.  
    C:\Program Files (x86)\SogouWBInput\2.1.0.1288\scd\17960.scel

把17960.scel文件复制到自己的项目目录里,用文本编辑器打开文件,发现是二进制的。那么我需要用工具进行转换,把二进制的词典转成我们可以使用的文本文件。jiebaR包的作者,同时开发了一个cidian项目,可以转换搜狗的词典,那么我们只需要安装cidian包即可。

安装cidian项目

  1.  
     
  2.  
    > install.packages("devtools")
  3.  
    > install.packages("stringi")
  4.  
    > install.packages("pbapply")
  5.  
    > install.packages("Rcpp")
  6.  
    > install.packages("RcppProgress")
  7.  
    > library(devtools)
  8.  
    > install_github("qinwf/cidian")
  9.  
    > library(cidian)
    为确保安装顺利,建议首先下载Rtools,下载后直接双击进行安装,安装同一般软件安装,下载地址https://cran.r-project.org/bin/windows/Rtools/,注意选择对应自己软件版本的。然后打开Rstudio或者R,用install.packages()依次安装devtools、stringi、pbapply、Rcpp、RcppProgress,然后加载devtools,然后用install_github("qinwf/cidian")安装cidian,正常情况下就能顺利安装

转换二进制词典到文本文件。

  1.  
     
  2.  
    # 转换
  3.  
    > decode_scel(scel = "./17960.scel",cpp = TRUE)
  4.  
    output file: ./17960.scel_2016-07-21_00_22_11.dict
  5.  
     
  6.  
    # 查看生成的词典文件
  7.  
    > scan(file="./17960.scel_2016-07-21_00_22_11.dict",
  8.  
    + what=character(),nlines=50,sep='\n',
  9.  
    + encoding='utf-8',fileEncoding='utf-8')
  10.  
    Read 50 items
  11.  
    [1] "阿坝州 n" "阿百川 n" "阿班 n"
  12.  
    [4] "阿宾 n" "阿波菲斯 n" "阿不都热希提 n"
  13.  
    [7] "阿不都西库尔 n" "阿不力克木 n" "阿尔姆格伦 n"
  14.  
    [10] "阿尔沙文 n" "阿肥星 n" "阿菲正传 n"
  15.  
    [13] "阿密特 n" "阿穆 n" "阿穆隆 n"
  16.  
    [16] "阿帕鲁萨镇 n" "阿披实 n" "阿衰 n"
  17.  
    [19] "阿霞 n" "艾奥瓦 n" "爱不疚 n"
  18.  
    [22] "爱的错位 n" "爱得得体 n" "爱的火焰 n"
  19.  
    [25] "爱的流刑地 n" "爱得起 n" "埃夫隆 n"
  20.  
    [28] "爱搞网 n" "爱国红心 n" "爱呼 n"
  21.  
    [31] "爱就宅一起 n" "埃克希儿 n" "爱没有错 n"
  22.  
    [34] "埃蒙斯 n" "爱奴新传 n" "爱起点 n"
  23.  
    [37] "爱情的牙齿 n" "爱情海滨 n" "爱情节 n"
  24.  
    [40] "爱情美的样子 n" "爱情无限谱 n" "爱情占线 n"
  25.  
    [43] "爱情转移 n" "爱情左灯右行 n" "爱上你是一个错 n"
  26.  
    [46] "矮哨兵 n" "爱是妥协 n" "爱似水仙 n"
  27.  
    [49] "爱太痛 n" "爱无界 n"

接下来,直接把搜狗词典配置到我们的分词库中,就可以直接使用了。把搜狗词典文件改名,从17960.scel_2016-07-21_00_22_11.dict到user.dict.utf8,然后替换D:\tool\R-3.2.3\library\jiebaRD\dict目录下面的user.dict.utf8。这样默认的用户词典,就是搜狗词典了。很酷吧!

如果使用txt文件作为词典,需要将编码改为utf-8,之后输入命令:jieba.load_userdict("C:/Users/Lenovo/Desktop/dict.txt")#括号内可自行设置路径

5. 停止词过滤

停止词就是分词过程中,我们不需要作为结果的词,像英文的语句中有很多的a,the,or,and等,中文语言中也有很多,比如 的,地,得,我,你,他。这些词因为使用频率过高,会大量出现在一段文本中,对于分词后的结果,在统计词频的时候会增加很多的噪音,所以我们通常都会将这些词进行过滤。

在jiebaR中,过滤停止词有2种方法,一种是通过配置stop_word文件,另一种是使用filter_segment()函数。

首先我们先来看,通过配置stop_word文件的方法。新建一个stop_word.txt文件。

  1.  
     
  2.  
    ~ notepad stop_word.txt
  3.  
     
  4.  
  5.  
    我是
  6.  
     

加载分词引擎,并配置停止词过滤。

  1.  
     
  2.  
    > wk = worker(stop_word='stop_word.txt')
  3.  
    > segment<-wk["我是《R的极客理想》图书作者"]
  4.  
    > segment
  5.  
    [1] "R" "的" "极客" "理想" "图书" "作者"

上面的文本,我们把"我是"通过停止词进行了过滤。如果还想过滤“作者”一词,可以动态的调用filter_segment()函数。

  1.  
     
  2.  
    > filter<-c("作者")
  3.  
    > filter_segment(segment,filter)
  4.  
    [1] "R" "的" "极客" "理想" "图书"

6. 关键词提取

关键词提取是文本处理非常重要的一个环节,一个经典算法是TF-IDF算法。其中,TF(Term Frequency)代表词频,IDF(Inverse Document Frequency)表示逆文档频率。如果某个词在文章中多次出现,而且不是停止词,那么它很可能就反应了这段文章的特性,这就是我们要找的关键词。再通过IDF来算出每个词的权重,不常见的词出现的频率越高,则权重越大。计算TF-IDF的公式为:

TF-IDF = TF(词频) * 逆文档频率(IDF)

对文档中每个词计算TF-IDF的值,把结果从大到小排序,就得到了这篇文档的关键性排序列表。关于IF-IDF的解释,参考了文章TF-IDF与余弦相似性的应用(一):自动提取关键词

jiebaR包的关键词提取提取的实现,也是使用了TF-IDF的算法。在安装目录中的idf.utf8文件,为IDF的语料库。查看idf.utf8内容。

  1.  
     
  2.  
    > scan(file="D:/tool/R-3.2.3/library/jiebaRD/dict/idf.utf8",
  3.  
    + what=character(),nlines=50,sep='\n',
  4.  
    + encoding='utf-8',fileEncoding='utf-8')
  5.  
    Read 50 items
  6.  
    [1] "劳动防护 13.900677652" "生化学 13.900677652"
  7.  
    [3] "奥萨贝尔 13.900677652" "考察队员 13.900677652"
  8.  
    [5] "岗上 11.5027823792" "倒车档 12.2912397395"
  9.  
    [7] "编译 9.21854642485" "蝶泳 11.1926274509"
  10.  
    [9] "外委 11.8212361103" "故作高深 11.9547675029"
  11.  
    [11] "尉遂成 13.2075304714" "心源性 11.1926274509"
  12.  
    [13] "现役军人 10.642581114" "杜勃留 13.2075304714"
  13.  
    [15] "包天笑 13.900677652" "贾政陪 13.2075304714"
  14.  
    [17] "托尔湾 13.900677652" "多瓦 12.5143832909"
  15.  
    [19] "多瓣 13.900677652" "巴斯特尔 11.598092559"
  16.  
    [21] "刘皇帝 12.8020653633" "亚历山德罗夫 13.2075304714"
  17.  
    [23] "社会公众 8.90346537821" "五百份 12.8020653633"
  18.  
    [25] "两点阈 12.5143832909" "多瓶 13.900677652"
  19.  
    [27] "冰天 12.2912397395" "库布齐 11.598092559"
  20.  
    [29] "龙川县 12.8020653633" "银燕 11.9547675029"
  21.  
    [31] "历史风貌 11.8212361103" "信仰主义 13.2075304714"
  22.  
    [33] "好色 10.0088573539" "款款而行 12.5143832909"
  23.  
    [35] "凳子 8.36728816325" "二部 9.93038573842"
  24.  
    [37] "卢巴 12.1089181827" "五百五 13.2075304714"
  25.  
    [39] "畅叙 11.598092559" "吴栅子 13.2075304714"
  26.  
    [41] "智力竞赛 13.900677652" "库邦 13.2075304714"
  27.  
    [43] "非正义 11.3357282945" "编订 10.2897597393"
  28.  
    [45] "悲号 12.8020653633" "陈庄搭 13.2075304714"
  29.  
    [47] "二郎 9.62401153296" "电光石火 11.8212361103"
  30.  
    [49] "抢球 11.9547675029" "南澳大利亚 10.9562386728"

idf.utf8文件每一行有2列,第一列是词项,第二列为权重。然后,我通过计算文档的词频(TF),与语料库的IDF值相乘,就可以得到TF-IDF值,从而提取文档的关键词。

比如,我们对下面的文本内容进行关键词的提取。

  1.  
     
  2.  
    > wk = worker()
  3.  
    > segment<-wk["R的极客理想系列文章,涵盖了R的思想,使用,工具,创新等的一系列要点,以我个人的学习和体验去诠释R的强大。"]
  4.  
     
  5.  
    # 计算词频
  6.  
    > freq(segment)
  7.  
    char freq
  8.  
    1 创新 1
  9.  
    2 了 1
  10.  
    3 文章 1
  11.  
    4 强大 1
  12.  
    5 R 3
  13.  
    6 个人 1
  14.  
    7 的 5
  15.  
    8 诠释 1
  16.  
    9 和 1
  17.  
    10 一系列 1
  18.  
    11 使用 1
  19.  
    12 以 1
  20.  
    13 等 1
  21.  
    14 极客 1
  22.  
    15 理想 1
  23.  
    16 思想 1
  24.  
    17 涵盖 1
  25.  
    18 系列 1
  26.  
    19 去 1
  27.  
    20 我 1
  28.  
    21 工具 1
  29.  
    22 学习 1
  30.  
    23 体验 1
  31.  
    24 要点 1
  32.  
     
  33.  
    # 取TF-IDF的前5的关键词
  34.  
    > keys = worker("keywords",topn=5)
  35.  
     
  36.  
    # 计算关键词
  37.  
    > vector_keywords(segment,keys)
  38.  
    11.7392 8.97342 8.23425 8.2137 7.43298
  39.  
    "极客" "诠释" "要点" "涵盖" "体验"

使用jiebaR包处理分词确实简单,几行的代码就能实现分词的各种算法操作。有了这个工具,我们就可以文档中,发现各种语言规则进行文本挖掘了。下篇文章让我们挖掘一下上市公司的公告吧,说不定能发现什么市场规则。

本文只是抛砖引玉地介绍了jiebaR包的使用方法,详细使用操作,请参考包作者的官方介绍。再次感谢jiebaR作者@qinwenfeng,为R语言在中文分词中提供了一套非常不错的工具包!

转载请注明出处:
http://blog.fens.me/r-word-jiebar/

R-cidian将词库批量读入

用到cidian包中的decode_scel函数
参数scel用来给出细胞词库的路径(需要带上扩展名)
output给出输出文件的路径,我们在这里把他放到了和原细胞词库同一个路径下面,并且将其扩展名改为.txt;
cpp = TRUE表示采用Rcpp(速度会更快)
progress = TRUE表示显示转换进度条。由于一般而言转换速度非常快,所以是否显示进度条意义不大。


####此处词库为搜狗词库
library(dplyr)
library(stringr)
library(devtools)
library(data.table)
library(cidian)
#建立数据目录
data.dir <- sprintf("%s/data", getwd())
#用来输出结果的目录
results.dir <- sprintf("%s/results", getwd())
#获取所有搜狗词库的完整路径
cidian.dir <- sprintf("%s/搜狗细胞词库-201602", data.dir)
scel.paths <- list.files(cidian.dir, pattern = ".scel$", full.names = T)
#导入目录下所有词库,并输出成.txt文件
lapply(seq_along(scel.paths), function(i) {
  decode_scel(scel = scel.paths[i],
    output = str_c(scel.paths[i], ".txt"),
    cpp = TRUE)}) %>%
  invisible()
#将所有词库合并成一个词库(此处用到函数data.table的rbindlist函数)
dict.paths <- list.files(cidian.dir, pattern = ".txt$", full.names = T)
dict.list <- lapply(seq_along(dict.paths),function(i) fread(dict.paths[i], encoding = "UTF-8"))
dict <- rbindlist(dict.list)
# 去重
dict <- unique(dict, by = names(dict))
#将最后生成的词库导出成单一的txt文件,用于后续分词
write.table(dict, file = sprintf("%s/guba.use.dict.utf8", data.dir),
  quote = F,
  row.names = F,
  col.names = F,
  fileEncoding = "UTF-8")

原文地址:https://www.cnblogs.com/purple5252/p/15720480.html