以下內容僅爲學習筆記,如表述有誤,歡迎批評指正。
這一次的作業是基於本人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#顯示標題中所有的詞語及其詞性,這一過程需要耗時15秒
str(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#顯示標題中所有的詞語及其詞性,這一過程需要耗時15秒
str(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#顯示標題中所有的詞語及其詞性,這一過程需要耗時15秒
str(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個形容詞')