iT邦幫忙

2023 iThome 鐵人賽

DAY 9
0
AI & Data

用R語言玩轉文字探勘系列 第 9

[Day 9] 以R語言分詞 - 預處理 & 使用 tidytext

  • 分享至 

  • xImage
  •  

利用R語言分詞

利用R語言分詞 - 預處理

上面有提到,在斷詞前其實有些任務要先進行,我們結合dplyrstringr,再搭配其他套件展示具體怎麼做吧!

# 為了簡轉繁函數 toTrad()
library(tmcn)
df_speech_pre <- 
  df_speech_sample %>% 
  # 繁體轉簡體
  mutate(text = toTrad(text)) %>%
  # 大寫轉小寫
  mutate(text = str_to_lower(text)) %>%
  # 去除標點符號和數字
  # mutate(text = str_remove_all(text, "[:punct:]|[0-9]")) %>%
  # 處理空白
  mutate(text = str_remove_all(text, " |\\n|\\r|\\t")) %>%
  # 編碼轉換:如果有需要才做例如 BIG5 轉 UTF8
  # mutate(text = iconv(text, "BIG5", "UTF-8")) %>%
  # 處理HTML/XML標記:沒遇到但可以看範例程式碼
  # mutate(text = str_remove_all(text, "<html>|</html>")) %>%
  # 去除非文字字元:whisper API 常有這種
  # mutate(text = str_remove_all(text, "[music]")) %>%
  # 標準化
  mutate(text = str_replace_all(text, "台灣", "臺灣")) #%>%
  # 去除或處理特殊字元和符號:暫時想不到
  # mutate(text = str_replace_all(text, " "))
df_speech_pre

## # A tibble: 1 × 1
##   text                                                                                                           
##   <chr>                                                                                                          
## 1 大會主席、各位貴賓、各位親愛的父老兄弟姐妹:今天是中華民國八十六年國慶日,海內外同胞用熱烈的活動,慶祝我們國家…

分詞流程 - 利用 tidytext

斷詞時,tidytext會使用另一個套件tokenizers,並將分詞功能包在unnest_tokens()函數之中。為方便起見,我們只保留第一篇演講內容,再以之為分詞標的。先快速看一下分詞結果:

library(tidytext)
df_stop <- read_table("data/停用詞-繁體中文.txt", col_names = F) %>% rename(stopword = 1)

df_speech_pre %>% select(text) %>% head(1) %>%
  unnest_tokens(output = word, input = text, token = "words")

## # A tibble: 388 × 1
##    word  
##    <chr> 
##  1 大會  
##  2 主席  
##  3 各位  
##  4 貴賓  
##  5 各位  
##  6 親愛的
##  7 父老  
##  8 兄弟  
##  9 姐妹  
## 10 今天是
## # ℹ 378 more rows

其中,output參數為產出分詞結果的欄位名稱,input為分詞標的,token則是分詞方式,除了預設的words以外,常用還有characters(字母)、ngramssentencesparagraphsregex等選項。

因為文章中單一句子長度太長,我們改看另一個案例,用來說明strip_punct,這個參數可以決定是否要保留標點符號。

# 預設: 踢掉標點符號
tibble(text = "你好嗎?我很好,真的很好!") %>% select(text) %>% head(1) %>%
  unnest_tokens(output = word, input = text, token = "words", strip_punct = T)

## # A tibble: 5 × 1
##   word  
##   <chr> 
## 1 你好嗎
## 2 我    
## 3 很好  
## 4 真的  
## 5 很好

# 將參數修改為FALSE
tibble(text = "你好嗎?我很好,真的很好!") %>% select(text) %>% head(1) %>%
  unnest_tokens(output = word, input = text, token = "words", strip_punct = F)

## # A tibble: 8 × 1
##   word  
##   <chr> 
## 1 你好嗎
## 2 ?    
## 3 我    
## 4 很好  
## 5 ,    
## 6 真的  
## 7 很好  
## 8 !

除了words以外,我們最常使用的分詞單位為ngrams,它的意思是「詞彙的連續序列」。這是什麼意思呢?舉例來說,如果我們在分詞後計算每個詞會出現的頻率,可能可以看到總統提了許多次中國,也提到很多次台灣,同時在演講中還提到人民與政府。

然而,若我們關注到底總統講的是「中國政府」還是「中國人民」、著墨更多在「台灣政府」抑或「台灣人民」,則我們就是在看bigram,也就是兩個連續詞彙的排列。依此類推我們可以看到trigram,甚至更多。

為什麼我們不直接數「中國」和「政府出現的次數」?因為「政府」可能來自「台灣政府」而非「中國政府」,查看n-gram可以幫助我們看到詞彙共同出現的關係。底下我們來看從n=1到n=3的分詞結果。

df_speech_pre %>% select(text) %>% head(1) %>%
  unnest_tokens(output = word, input = text, token = "ngrams", n = 1)

## # A tibble: 388 × 1
##    word  
##    <chr> 
##  1 大會  
##  2 主席  
##  3 各位  
##  4 貴賓  
##  5 各位  
##  6 親愛的
##  7 父老  
##  8 兄弟  
##  9 姐妹  
## 10 今天是
## # ℹ 378 more rows

df_speech_pre %>% select(text) %>% head(1) %>%
  unnest_tokens(output = bigram, input = text, token = "ngrams", n = 2)

## # A tibble: 387 × 1
##    bigram         
##    <chr>          
##  1 大會 主席      
##  2 主席 各位      
##  3 各位 貴賓      
##  4 貴賓 各位      
##  5 各位 親愛的    
##  6 親愛的 父老    
##  7 父老 兄弟      
##  8 兄弟 姐妹      
##  9 姐妹 今天是    
## 10 今天是 中華民國
## # ℹ 377 more rows

df_speech_pre %>% select(text) %>% head(1) %>%
  unnest_tokens(output = trigram, input = text, token = "ngrams", n = 3)

## # A tibble: 386 × 1
##    trigram             
##    <chr>               
##  1 大會 主席 各位      
##  2 主席 各位 貴賓      
##  3 各位 貴賓 各位      
##  4 貴賓 各位 親愛的    
##  5 各位 親愛的 父老    
##  6 親愛的 父老 兄弟    
##  7 父老 兄弟 姐妹      
##  8 兄弟 姐妹 今天是    
##  9 姐妹 今天是 中華民國
## 10 今天是 中華民國 八十
## # ℹ 376 more rows

除了分成詞彙單元,我們也可以分成句子、段落等,現在還看不太出用途,但之後有其他應用,例如從句子長度評估演講風格、查找特定句型等,都是可能應用方式。

df_speech_pre %>% select(text) %>% head(1) %>%
  unnest_tokens(output = word, input = text, token = "sentences")

## # A tibble: 13 × 1
##    word                                                                                                           
##    <chr>                                                                                                          
##  1 大會主席、各位貴賓、各位親愛的父老兄弟姐妹:今天是中華民國八十六年國慶日,海內外同胞用熱烈的活動,慶祝我們國家…
##  2 八十六年來,中華民國經歷了許多的挫折和危難,但是,在全體同胞的精誠團結、齊心努力下,終能一再克服挑戰,衝破難關…
##  3 今天,在政治上,我們已經實現了「主權在民」的理想,昂然邁進全民民主的新時代;在經濟上,我們不但締造了舉世矚目的…
##  4 然而,歷史的巨輪不斷向前,國家的發展也永無止境。                                                               
##  5 面對即將來臨的二十一世紀,我們不能自滿於既有的成就,而必須以更前瞻的思維,和更積極的作為,致力改革,推動建設,…
##  6 我們相信,自由是全人類共同追求的目標,民主是世界文明發展的方向。                                               
##  7 中華民國在實踐自由民主的理想之後,也願善盡心力,與國際社會分享發展經驗,為全世界的和平、合作與繁榮,作出具體貢…
##  8 同時,我們也秉持善意,積極推動兩岸關係,希望兩岸的中國人能在自由、民主、均富的基礎上追求統一,共享繁榮與安定。 
##  9 深盼中共當局能體認世界潮流趨勢,務實面對兩岸分治的事實,以民眾的福祉為依歸,共創兩岸雙贏的新紀元。             
## 10 各位親愛的父老兄弟姐妹:在這個深具歷史意義的偉大日子,我們回顧過去,對自己的成就,感到無比自豪;而展望未來,也…
## 11 隻要我們繼續堅持民主改革的理想,發揮團結奮鬥的精神,就一定能掌握發展契機,開創國家更輝煌燦爛的前景!           
## 12 敬祝中華民國國運昌隆!                                                                                         
## 13 大家健康愉快,謝謝各位!::::::::::::

單純看斷詞後詞彙出現次數。

# 沒去除停用詞
df_speech_pre %>% select(text) %>% head(1) %>%
  unnest_tokens(output = word, input = text, token = "words") %>%
  count(word, sort = T)

## # A tibble: 238 × 2
##    word      n
##    <chr> <int>
##  1 的       39
##  2 我們     11
##  3 在        8
##  4 發展      7
##  5 民主      6
##  6 上        5
##  7 也        5
##  8 更        5
##  9 社會      5
## 10 自由      5
## # ℹ 228 more rows

# 有去除停用詞
df_speech_pre %>% select(text) %>% head(1) %>%
  unnest_tokens(output = word, input = text, token = "words") %>%
  count(word, sort = T) %>%
  anti_join(df_stop, by = c("word" = "stopword"))

## # A tibble: 199 × 2
##    word         n
##    <chr>    <int>
##  1 發展         7
##  2 民主         6
##  3 社會         5
##  4 自由         5
##  5 中華民國     4
##  6 國家         4
##  7 繁榮         4
##  8 兩岸         3
##  9 基礎         3
## 10 成就         3
## # ℹ 189 more rows

上一篇
[Day 8] 以R語言分詞 - 概念篇
下一篇
[Day 10] 以R語言分詞 - 使用 quanteda 與 jiebaR
系列文
用R語言玩轉文字探勘30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言