jieba 自訂詞庫斷詞
這邊將使用 jiebaR,介紹使用自訂詞庫的斷詞方式,並提供自訂詞庫的製作方式。
示範語料
這裡使用金庸神雕俠侶第三十二回 — 情是何物作為斷詞的文本。武俠小說在此是個很好的例子,因為裡面有許多人物名稱和專有名詞。
因為著作權問題1,語料的原始檔(032.txt
)將不會出現在本文的 GitHub repo 中。
製作自訂詞庫
取得小說這類文本的角色名稱與特殊名詞乍看之下可能非常耗工耗時,但有些時候其實相當容易,尤其是著名的小說。這要歸功於維基百科,因為越是著名的小說,其越有可能有詳盡的維基百科頁面,而維基百科對製作詞庫最重要的特色在於其頁面的超連結,因為通常只有專有名詞才會成為一個維基頁面上的超連結。
這邊使用維基百科的神鵰俠侶角色列表作為詞庫的來源。以下使用rvest
套件清理此頁面:
library(rvest)
library(dplyr)
library(magrittr)
library(knitr)
path <- "神鵰俠侶角色列表.html"
# 這裡已先行下載網頁,若無可直接使用網址
data <- read_html(path) %>%
html_nodes("ul") %>% html_nodes("li") %>%
html_nodes("a") %>% html_text()
觀察頁面後,可發現多數與小說相關的詞彙都位在 unordered list 下的連結內文(<a> tag),因此透過 3 個html_nodes()
取得連結,並用html_text()
擷取連結內文。
接著看看擷取的詞彙,可以發現這些詞彙依照順序大致可區分成三個來源:
- 自維基頁面的目錄擷取之連結
- 內文的連結(這是我們要的)
- 其它連結
- 對應至頁面最下方,與小說有關但並非小說主要內容的連結,如,「射雕英雄传角色列表」。另外,也包含維基百科頁面的固定連結,如「編輯」、「討論」、「下載為PDF」等。
data <- unique(data)
data[1:3]
[1] "1 主角" "2 桃花島" "2.1 「北丐」門派"
data[21:25]
[1] "楊過" "射鵰英雄傳" "楊康" "穆念慈" "全真教"
data[207:211]
[1] "射雕英雄传角色列表" "倚天屠龙记角色列表" "查"
[4] "论" "编"
我們要的內容介在data[21]
(楊過)至data[206]
(樊一翁)之間。此外,亦可手動加入連結中沒有的詞彙:
data <- as_data_frame(data[21:206]) %>%
rbind("過兒", "靖哥哥") # 手動額外輸入
head(data, 4) %>% kable("markdown", align="c")
value |
---|
楊過 |
射鵰英雄傳 |
楊康 |
穆念慈 |
最後,將data
存成.csv
檔,方便未來使用:
readr::write_csv(data, "sdxl_wordlist.csv")
jiebaR 斷詞
準備好自訂詞庫後,要開始對文本進行斷詞。
jiebaR 斷詞可以選擇外來檔案或將檔案讀入後在進行斷詞,這邊將文本檔案讀入再斷詞:
library(stringr)
raw_text <- readr::read_file("032.txt")
raw_text %>% str_trunc(80)
[1] "第三十二回 情是何物\r\n\r\n 當黃蓉、一燈、郭芙等被困大廳之時,楊過和小龍女正在花前並肩共語。不久程英和陸無雙到來。小龍女見程英溫雅靦腆,甚是投緣,拉住..."
無自訂詞庫
首先,我們可以看看沒有自訂詞庫的斷詞效果:
library(jiebaR)
stop_words <- readr::read_table2("stop-zh-tw-withpunc",
col_names = F) %>%
rbind("\n", "\r") %>%
set_names("word")
seg <- worker(bylines = F, symbol = T)
segment(raw_text, seg) %>%
as_data_frame() %>%
anti_join(stop_words, by=c("value"="word")) %>%
count(value) %>%
arrange(desc(n)) %>%
head() %>% kable("markdown", align="c")
value | n |
---|---|
道 | 156 |
小龍女 | 115 |
楊 | 91 |
公孫止 | 86 |
楊過 | 76 |
黃 | 65 |
可以看到有些斷詞是正確的,如「公孫止」。但某些似乎常常斷錯,例如,「黃蓉」、「楊過」(某些似乎斷錯,導致有許多單獨的「楊」)。
使用自訂詞庫
在jiebaR::worker()
中設定自訂詞庫的位置:user = "sdxl_wordlist.csv"
,即可在斷詞系統中新增字典:
seg <- worker(bylines = F, symbol = T,
user = "sdxl_wordlist.csv")
segment(raw_text, seg) %>%
as_data_frame() %>%
anti_join(stop_words, by=c("value"="word")) %>%
count(value) %>%
arrange(desc(n)) %>%
head() %>% kable("markdown", align="c")
value | n |
---|---|
楊過 | 187 |
道 | 150 |
小龍女 | 119 |
公孫止 | 104 |
黃蓉 | 95 |
李莫愁 | 59 |
可以看到使用自訂詞庫後,斷詞變得有意義多了。
Last updated: 2018-11-10