首页 > 技术文章 > R语言——jiebaR基础

littlefatsheep 2017-05-21 18:38 原文

一、jiebaR中的函数介绍(很大一部分参照jiebaR官方文档:qinwenfeng.com/jiebaR/)
**No.1**
worker(type = "mix", dict = DICTPATH, hmm = HMMPATH, user = USERPATH,idf = IDFPATH,
stop_word = STOPPATH, write = T, qmax = 20, topn = 5,encoding = "UTF-8", detect = T,
symbol = F, lines = 1e+05,output = NULL, bylines = F, user_weight = "max")
worker()函数的作用是构建一个分词器,通常在分析文本的时候,需要首先构建分词器。

#构建分词器的语句如下,不添加任何参数的话,使用函数中默认的参数
>分词器=worker()

worker()函数的各参数介绍如下:
(1)type(mix):分词模型,有好几个可选项
[1]mp 基于词典的最大概率模型
[2]hmm 基于HMM模型,可以发现词典中没有的词
[3]mix 混合模型,先用mp分词,分完以后调用hmm把剩余的可能成词的单字拿出来
[4]query 索引模型,对大于一定长度的词再进行一次切分
[5]tag 标记模型,基于用户词典的词性标注
[6]keywords 关键词模型,TF-IDF抽去关键词
[7]simhash Simhash模型,在关键词的基础上计算simhash

(2)dict(DICTPATH):系统词典,默认路径为jiebaR::DICTPATH,文件名为jieba.dict.utf8
系统词典的默认数据结构为三列:词语、词频、词性
>readLines(jiebaR::DICTPATH,5,encoding = "UTF-8")
[1] "1号店 3 n" "1號店 3 n" "4S店 3 n" "4s店 3 n" "AA制 3 n"

(3)hmm(HMMPATH):HMM词典,默认jiebaR::HMMPATH

(4)user(USERPATH):用户词典,默认jiebaR::USERPATH

(5)idf(IDFPATH):IDF词典,默认jiebaR::IDFPATH

(6)stop_word(STOPPATH):停用此词典,默认STOPPATH

(7)write(T):是否写入文件,默认为T
只在输入内容为文件路径时,本参数才会被使用。本参数只对分词和词性标注有效。

(8)qmax(20):索引模型中,最大可能成词的字符数,默认20

(9)topn(5):提取的关键词数

(10)encoding(UTF-8):默认编码UTF-8

(11)detect(T):是否检查输入文件的编码,默认检查(T)

(12)symbol(F):是否保留符号,默认不保留符号(F)

(13)lines(1e+05):每次读取文件的最大行数,用于控制读取文件的长度。对于大文件,实现分次读取

(14)output(NULL):指定输出路径,一个字符串路径。只在输入内容为文件路径时,本参数才会被使用

(15)bylines(F):文件结果是否按行输出,如果是,则将读入的文件或字符串向量按行逐个进行分词操作

(16)user_weight(max):用户词典中的词的词频,默认为 “max”,系统词典中的最大值。

还可以选 “min” 最小值或者 “median” 中位数。

**No.2**
segment(code, jiebar, mod = NULL)
segment主要用于分词
code:一条中文语句或者文件路径
jiebar:jiebaR Worker,即上面构建的分词器
mod:修改默认的结果类型,可以是"mix","hmm","query","full","level", or "mp"中任意一种

> text="今天的长春举行了马拉松比赛,但是我没有去,好遗憾"
> segment(text,分词器)
[1] "今天" "的" "长春" "举行" "了" "马拉松" "比赛" "但是" "我"
[10] "没有" "去" "好" "遗憾"

**No.3**
new_user_word(worker, words, tags = rep("n", length(words))):用于添加用户词典
worker:一个分词器
words:新添加的词
tags:添加标签,默认"n",即名词
> segment("我可喜欢听一个人的寂寞,两个人的错",分词器)
[1] "我" "可" "喜欢" "听" "一个" "人" "的" "寂寞" "两个" "人" "的"
[12] "错"
> new_user_word(分词器,"一个人的寂寞两个人的错")
[1] TRUE
> segment("我可喜欢听一个人的寂寞两个人的错",分词器)
[1] "我" "可" "喜欢"
[4] "听" "一个人的寂寞两个人的错"

**No.4**
使用readLines()和writeLines()对文件进行分词
实例:我的目录里有一个关于新闻热点事件的评论,文件名为girl_comm.txt,按行存储
> girl_comm<-readLines('girl_comm.txt',encoding = 'UTF-8')
> head(girl_comm)
[1] ":谢谢您,这个评论很厚重//"
[2] ":你这样只截取部分网友的回复来误导大众的做法也不见得很妥吧?大部分网友都在说不清楚事情真相不应该片面评论,并没有你说的教育熊孩子呼声很高~"
[3] ":你看到人家踹了?无视频无真相"
[4] ":踢人太过,但是熊孩子也是让人忍无可忍。"
[5] ":如果仅叫了两声就能定义为熊孩子 那全世界只有哑巴不是熊孩子 你小时候也一定是"
[6] ":小孩子活泼好动是天性,如果父母不管教才叫熊孩子,等你有了孩子就知道了"

#由于分词时候不用考虑标点符号,所以我在这里也就不对前面的冒号进行处理了
> result<-segment(girl_comm,分词器)
> head(result)
[[1]]
[1] "谢谢您" "这个" "评论" "很" "厚重"

[[2]]
[1] "你" "这样" "只" "截取" "部分" "网友" "的"
[8] "回复" "来" "误导" "大众" "的" "做法" "也"
[15] "不见得" "很" "妥吧" "大部分" "网友" "都" "在"
[22] "说不清楚" "事情" "真相" "不" "应该" "片面" "评论"
[29] "并" "没有" "你" "说" "的" "教育" "熊"
[36] "孩子" "呼声" "很高"
> result_merge<-sapply(result, function(x){ paste(x, collapse = " ")})
> writeLines(result_merge, "./some.txt") #需要现在工作目录理新建一个名为some.txt的文件
> file.remove("./some.txt") #在工作目录移除该文件
> head(result_merge)
[1] "谢谢您 这个 评论 很 厚重"
[2] "你 这样 只 截取 部分 网友 的 回复 来 误导 大众 的 做法 也 不见得 很 妥吧 大部分 网友 都 在 说不清楚 事情 真相 不 应该 片面 评论 并 没有 你 说 的 教育 熊 孩子 呼声 很高"
[3] "你 看到 人家 踹 了 无 视频 无 真相"
[4] "踢 人 太 过 但是 熊 孩子 也 是 让 人 忍无可忍"
[5] "如果 仅 叫 了 两声 就 能 定义 为 熊 孩子 那 全世界 只有 哑巴 不是 熊 孩子 你 小时候 也 一定 是"
[6] "小孩子 活泼 好动 是 天性 如果 父母 不 管教 才 叫 熊 孩子 等 你 有 了 孩子 就 知道 了"
**No.5**
对文件进行分词:
> output_file<-segment("girl_comm.txt",分词器)
> readLines(output_file,4,encoding = "UTF-8")
[1] "谢谢您 这个 评论 很 厚重"
[2] "你 这样 只 截取 部分 网友 的 回复 来 误导 大众 的 做法 也 不见得 很 妥吧 大部分 网友 都 在 说不清楚 事情 真相 不 应该 片面 评论 并 没有 你 说 的 教育 熊 孩子 呼声 很高"
[3] "你 看到 人家 踹 了 无 视频 无 真相"
[4] "踢 人 太 过 但是 熊 孩子 也 是 让 人 忍无可忍"

指定输出路径:
分词器$output = "some"
> 分词器$output="some"
> segment("girl_comm.txt",分词器)
[1] "some"
> readLines("some",4,encoding = "UTF-8")
[1] "谢谢您 这个 评论 很 厚重"
[2] "你 这样 只 截取 部分 网友 的 回复 来 误导 大众 的 做法 也 不见得 很 妥吧 大部分 网友 都 在 说不清楚 事情 真相 不 应该 片面 评论 并 没有 你 说 的 教育 熊 孩子 呼声 很高"
[3] "你 看到 人家 踹 了 无 视频 无 真相"
[4] "踢 人 太 过 但是 熊 孩子 也 是 让 人 忍无可忍"

如果想关闭自动检测路径,可以使用如下语句:
分词器$write=NOFILE

**No.6**
使用如下两个语句实现分行输出和保留标点符号
(1)分词器$bylines=TRUE
> 分词器$bylines=T
> segment(c("这是第一句话","这是第二句话"),分词器)
[[1]]
[1] "这是" "第一句" "话"

[[2]]
[1] "这是" "第二句" "话"

(2)分词器$symbol=TRUE
> 分词器$symbol=T
> segment("喜欢你,没道理,就是那么任性",分词器)
[[1]]
[1] "喜欢" "你" "," "没道理" "," "就是" "那么" "任性"

二、标记和关键词
(1)标记——即为词语进行词性标注
> text="长春的冬天长达半年,其他半年是春夏秋"
> tagger=worker("tag")
> segment(text,tagger)
ns uj t ns m r m v tg t
"长春" "的" "冬天" "长达" "半年" "其他" "半年" "是" "春" "夏秋"

对已经分好的词也可以进行标记:
> wk=worker()
> result<-segment(text,wk)
> vector_tag(result,tagger)
ns uj t ns m r m v tg t
"长春" "的" "冬天" "长达" "半年" "其他" "半年" "是" "春" "夏秋"

(2)关键词提取——根据一定的规则提取文本中具有代表性的词语
> extract_kw=worker("keywords",topn = 2)
> text="爱情的力量是强大的,爱情是坚不可摧的,爱情是伟大的"
> keywords(text,extract_kw)
20.5491 10.9562
"爱情" "坚不可摧"

已经分好词的文本也可以使用vector_keywords(分词结构,分词器)进行提取关键词
> result=segment(text,wk)
> vector_keywords(result,extract_kw)
20.5491 10.9562
"爱情" "坚不可摧"


三、计算海明距离
distance(codel, coder, jiebar)
vector_distance(codel, coder, jiebar)

codel:对distance而言,是一条中文语句或者是文本文件的路径;对vector_distance而言,是一个分词结果——文本向量
coder:对distance而言,是一条中文语句或者是文本文件的路径;对vector_distance而言,是一个分词结果——文本向量
jiebar:jiebaR worker

> summa<-worker('simhash',topn = 2)
> simhash("江州市长江大桥参加了长江大桥的通车仪式", summa)
$simhash
[1] "12882166450308878002"

$keyword
22.3853 8.69667
"长江大桥" "江州"

distance("hello world!", "江州市长江大桥参加了长江大桥的通车仪式", 摘要器)

对一个已经分好词的向量,也可以计算simhash:
> text="江州市长江大桥参加了长江大桥的通车仪式"
> result<-segment(text,wk)
> vector_simhash(result,summa) #就是有点麻烦了
$simhash
[1] "9659751748513812269"

$keyword
11.7392 11.1926
"江大桥" "长江大桥"
> distance("hello world!", "江州市长江大桥参加了长江大桥的通车仪式", summa) #两个不同的文本,距离不是0
$distance
[1] 23

$lhs
11.7392 11.7392
"hello" "world"

$rhs
22.3853 8.69667
"长江大桥" "江州"

> distance("hello world","hello world",summa) #两个相同的文本,距离为0
$distance
[1] 0

$lhs
11.7392 11.7392
"hello" "world"

$rhs
11.7392 11.7392
"hello" "world"

> vector_distance(c("今天","天气","真的","十分","不错","的","感觉"),c("今天","天气","真的","十分","不错","的","感觉"),summa) #相同的分词结果,距离为0
$distance
[1] 0

$lhs
6.45994 6.18823
"天气" "不错"

$rhs
6.45994 6.18823
"天气" "不错"

> vector_distance(c("今天","天气","真好"),c("今天","天气","真好"),summa)
$distance
[1] 0

$lhs
9.11319 6.45994
"真好" "天气"

$rhs
9.11319 6.45994
"真好" "天气"

四、词频统计
freq(x)
x是一个向量,即一个分词结果向量

五、生成 IDF 文件 get_idf()
get_idf(x, stop_word = STOPPATH, path = NULL)
x:一个列表
stop_word:停用词
path:输出文件路径

临时输出目录 = tempfile()
a_big_list = list(c("测试","一下"),c("测试"))
get_idf(a_big_list, stop = jiebaR::STOPPATH, path = 临时输出目录)
readLines(临时输出目录)
#> [1] "一下 0.693147180559945" "测试 0"

六、经常与jiebaR搭配使用的包
(1)wordcloud2:绘制词图使用
(2)cidian:似乎无法安装了
(3)ropencc:用于汉字的简繁转换
(4)text2vec:使用帮助https://cran.r-project.org/web/packages/text2vec/vignettes/text-vectorization.html

推荐阅读