【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函數套用前面定義的環境對標題進行分詞

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個形容詞')
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章