【R语言】结巴分词与词性提取(以“提取知乎问题标题的频繁词前100个形容词”实战为例)(3月25日学习笔记)

以下内容仅为学习笔记,如表述有误,欢迎批评指正。
这一次的作业是基于本人3月24日内容的进一步处理,老师布置的题目为
题目
这一次问题的难点在于词性分类,本文将以此题为例,介绍如何使用结巴分词对中文词语词性进行分类。

0.包的选取

中文分词必不可少的包:jieba

library(jiebaR)
library(jiebaRD)#用于分词

作图包我们选择

library(ggplot2)#用于作图

读取数据可以不额外导入包,使用基础的read.csv函数,但是这样读取效果很慢,建议采用read_csv函数,这一点在我的上一篇笔记中提到过

这个函数时读csv文件时能够把所有character型的变量读成factor型,读取大数据的时候效率更高

类似的函数还有data.table包的fread()函数,这两个函数的异同可以在dingdingxia前辈的博文中阅读

说回read_csv函数,这个函数需要

library(readr)#用于读取数据

此外还需要

library(tidyverse)#enframe函数需要用到
library(dplyr)#用于使用过滤函数filter()

这两个包的使用将在下文提及

1.数据读入

# 工作路径
setwd("D://1Study//R//CH05")
getwd()

# 读入数据
data_titles = read_csv("train_data.csv",col_names = T)
#col_names = T也就是.csv方法中的header=T
data_titles

#另存数据
question_titles = data.frame(data_titles[,2])#另存为数据,只保留标题一栏,使不破坏原数据

当然,col_names默认赋值就是T,不写也可以

2.中文分词与词性标注

seg <- worker('tag')#构筑词性标注环境

seg_question = segment(question_titles$question_title,seg) # 对所有的标题进行中文分词。

seg_question#显示标题中所有的词语及其词性,这一过程需要耗时15str(seg_question)#查看数据类型

title_table <- enframe(seg_question)

title_table

要提取词性,(1)需要构筑词性标注环境
前一篇笔记中提到过engine = worker(stop_word = "stopwordsC.txt")可以在构筑环境的时候使用停用词,这里的seg <- worker('tag')原理也差不多,就是构筑词性标注环境,并且这里不需要去除停用词,因为形容词不是停用词
(2)需要用segment函数套用前面定义的环境对标题进行分词

扫描二维码关注公众号,回复: 10302915 查看本文章
seg_question = segment(question_titles$question_title,seg) # 对所有的标题进行中文分词。

如果用

seg_question = tagging(question_titles$question_title,seg)`

也是可以的

无论是哪种格式,这里得到的seg_question实质上是一个带属性的向量,这样其实不是特别好用。

因此要把它变成数据框的格式,方便以后利用
这里使用enframe()

title_table <- enframe(seg_question)

这是tidyverse包下的一个函数,作用是将数据存储为tibble数据框,转换为具有名称和值的数据框
在这里插入图片描述
如果用前一节课的questionFreq = as.data.frame(table(seg_question))普通的数据框只能生成频数表,得不到词性
这一方法借鉴了黄天元前辈的博文R语言自然语言处理:词性标注与命名实体识别

3.筛选形容词,过滤所有非形容词

#write.csv(title_table,file = "title_table.csv",row.names = TRUE)
#另存为表格,这一过程在我的电脑上需要耗时10秒
adj_question <- filter(.data=title_table,name == "a")
adj_question

filter函数隶属于dplyr包,关于这一函数的使用方法可以参考LEEBELOVED前辈的博文R语言dplyr包:高效数据处理函数(filter、group_by、mutate、summarise)

4.构筑频数表

后续步骤与前一篇笔记的步骤较为类似,在此不再进行详细记录理解。

adj = data.frame(adj_question[,2])#把所有形容词另存为数据,使不破坏原数据
adj
adjFreq = as.data.frame(table(adj))#生成频数表

#过滤出现次数过少的形容词,这一步骤可以省略
adjFreq = adjFreq[-which(nchar(as.character(adjFreq[,2]))<2),]

adjFreq = adjFreq[order(-adjFreq$Freq),]#排序

data = adjFreq[1:100,]#提取问题标题的频繁词前100个形容词

5.绘图

依据前一步得到的频数表
在这里插入图片描述
绘图

# 对柱子的顺序进行重新排列
data$adj = factor(data$adj,levels = data$adj)

ggplot(data,aes(x=adj,y=Freq))+
  geom_bar(stat="identity")+
  theme(axis.text.x = element_text(angle = 60,hjust = 1))+
  xlab("形容词")+
  ylab("频数")+
  labs(title = '问题标题的频繁词前100个形容词')

最后附上完整代码及结果柱状图

######
#根据知乎问题标签预测数据训练集(train_data.csv)
#提取问题标题的频繁词前100个形容词
library(jiebaR)
library(jiebaRD)#用于分词
library(ggplot2)#用于作图
library(readr)#用于读取数据
#install.packages("tidyverse")
library(tidyverse)#enframe函数需要用到
library(dplyr)#用于使用过滤函数filter()
#####
#1.数据导入
#####

# 工作路径
setwd("D://1Study//R//CH05")
getwd()

# 读入数据
data_titles = read_csv("train_data.csv") #read_csv读取大数据的时候效率更高
data_titles

#另存数据
question_titles = data.frame(data_titles[,2])#另存为数据,只保留标题一栏,使不破坏原数据

#####
#2.中文分词与词性标注
#####
seg <- worker('tag')#构筑词性标注环境
#这里不需要去除停用词,因为形容词不是停用词
seg_question = segment(question_titles$question_title,seg) # 对所有的标题进行中文分词。

seg_question#显示标题中所有的词语及其词性,这一过程需要耗时15str(seg_question)#查看数据类型
#这里得到的seg_question实质上是一个带属性的向量,这样其实不是特别好用。
#因此我要把它变成数据框的格式,方便以后利用。

title_table <- enframe(seg_question)
#将上述数据存储为tibble数据框,转换为具有名称和值的数据框
#如果用前一节课的questionFreq = as.data.frame(table(seg_question))普通的数据框只能生成频数表,得不到词性

title_table

#####
#3.筛选形容词,过滤所有非形容词
######
#write.csv(title_table,file = "title_table.csv",row.names = TRUE)#另存为表格,这一过程需要耗时10秒
adj_question <- filter(.data=title_table,name == "a")
adj_question

#4.构筑频数表
######
adj = data.frame(adj_question[,2])#把所有形容词另存为数据,使不破坏原数据
adj
adjFreq = as.data.frame(table(adj))#生成频数表

#过滤出现次数过少的形容词,这一步骤可以省略
adjFreq = adjFreq[-which(nchar(as.character(adjFreq[,2]))<2),]

adjFreq = adjFreq[order(-adjFreq$Freq),]#排序

data = adjFreq[1:100,]#提取问题标题的频繁词前100个形容词

#####
#5.绘图
######
# 对柱子的顺序进行重新排列
data$adj = factor(data$adj,levels = data$adj)

ggplot(data,aes(x=adj,y=Freq))+
  geom_bar(stat="identity")+
  theme(axis.text.x = element_text(angle = 60,hjust = 1))+
  xlab("形容词")+
  ylab("频数")+
  labs(title = '问题标题的频繁词前100个形容词')

在这里插入图片描述
以上内容为我对R语言结巴分词与词性提取的理解以及“提取知乎问题标题的频繁词前100个形容词”的实战,若理解有误,欢迎批评指正。
如果直接运行本文上方代码得到的图会与上图不符,会得到3月29日上午修正中的图,具体原因请见3月29日下午的修正,感谢@MahoChan 同学的批评指正。
------------------3月26日修正----------------------------
原注释有误,应该是过滤出现次数过少的形容词,而不是过滤关键词的最短长度,这一步可有可无,这是加了能让后面排序的计算快一些。
感谢同学提醒。
3月26日前原内容为
在这里插入图片描述
现更改为
在这里插入图片描述
------------------3月29日上午修正----------------------------
有同学反馈,说用的是和本人一样的代码,但是运行出来的图不一样,今天本人再次运行了原代码,发现得到的图如下
在这里插入图片描述
是的!和同学反馈的情况一致!
为什么一样的代码在不同的时候生成的结果会不一样呢!
本人猜测是因为jiebaR包或jiebaRD包在3月28日左右更新了,所以会产生不一样的分词效果,在确认原因后会对本文进行新的补充。

------------------3月29日下午修正----------------------------
本人上午的猜想是错误的,感谢@MahoChan的指正!由下图结果可以发现,这两个包都是我在3月3日装的,是最新的版本,此期间也没有更新过。

注:下图内容使用函数library(help="jiebaR")即可查看
在这里插入图片描述
在这里插入图片描述
那么为什么会出现得到不同结果的两幅图呢?
正如@MahoChan同学所说

25日写字长小于2的时候过滤掉了单字,然而变量在环境中没清除,用这样数据画出来就没有单字

25号我运行了代码

# 过滤关键词的最短长度
adjFreq = adjFreq[-which(nchar(as.character(adjFreq[,1]))<2),]

过滤了第一列,并且把结果保存进了环境变量中,所以所有一个字的形容词都被过滤掉了

如果想要得到我原文中的结果图,完整的代码应该是

######
#根据知乎问题标签预测数据训练集(train_data.csv)
#提取问题标题的频繁词前100个形容词
library(jiebaR)
library(jiebaRD)#用于分词
library(ggplot2)#用于作图
library(readr)#用于读取数据
#install.packages("tidyverse")
library(tidyverse)#enframe函数需要用到
library(dplyr)#用于使用过滤函数filter()
#####
#1.数据导入
#####

# 工作路径
setwd("D://1Study//R//CH05")
getwd()

# 读入数据
data_titles = read_csv("train_data.csv") #read_csv读取大数据的时候效率更高
data_titles

#另存数据
question_titles = data.frame(data_titles[,2])#另存为数据,只保留标题一栏,使不破坏原数据

#####
#2.中文分词与词性标注
#####
seg <- worker('tag')#构筑词性标注环境
#这里不需要去除停用词,因为形容词不是停用词
seg_question = segment(question_titles$question_title,seg) # 对所有的标题进行中文分词。

seg_question#显示标题中所有的词语及其词性,这一过程需要耗时15str(seg_question)#查看数据类型
#这里得到的seg_question实质上是一个带属性的向量,这样其实不是特别好用。
#因此我要把它变成数据框的格式,方便以后利用。

title_table <- enframe(seg_question)
#将上述数据存储为tibble数据框,转换为具有名称和值的数据框
#如果用前一节课的questionFreq = as.data.frame(table(seg_question))普通的数据框只能生成频数表,得不到词性

title_table

#####
#3.筛选形容词,过滤所有非形容词
######
#write.csv(title_table,file = "title_table.csv",row.names = TRUE)#另存为表格,这一过程需要耗时10秒
adj_question <- filter(.data=title_table,name == "a")
adj_question

#4.构筑频数表
######
adj = data.frame(adj_question[,2])#把所有形容词另存为数据,使不破坏原数据
adj
adjFreq = as.data.frame(table(adj))#生成频数表

# 过滤关键词的最短长度
adjFreq = adjFreq[-which(nchar(as.character(adjFreq[,1]))<2),]

# 过滤出现次数最少的形容词,这一步可以不写,目的是加快排序
adjFreq = adjFreq[-which(nchar(as.character(adjFreq[,2]))<2),]

adjFreq = adjFreq[order(-adjFreq$Freq),]#排序

data = adjFreq[1:100,]#提取问题标题的频繁词前100个形容词

#####
#5.绘图
######
# 对柱子的顺序进行重新排列
data$adj = factor(data$adj,levels = data$adj)

ggplot(data,aes(x=adj,y=Freq))+
  geom_bar(stat="identity")+
  theme(axis.text.x = element_text(angle = 60,hjust = 1))+
  xlab("形容词")+
  ylab("频数")+
  labs(title = '问题标题的频繁词前100个形容词')
发布了14 篇原创文章 · 获赞 24 · 访问量 1620

猜你喜欢

转载自blog.csdn.net/weixin_46124302/article/details/105092765