## 介紹文字前處理(Text Preprocessing)
自然語言處理(NLP, Natural Language Processing)中的文字前處理(Text Preprocessing)是將原始文本轉換為結構化數據的關鍵步驟,這個過程能夠使電腦更好地理解和處理人類語言。
完整的文字前處理流程包含 Tokenization(分詞)、Stopwords(停用詞移除)、POS Tagging(詞性標註)、Named Entity Recognition(命名實體識別,NER)、Stemming(詞幹提取)或 Lemmatization(詞形還原)等技術,這些步驟彼此相輔相成,共同提升 NLP 任務的準確性和可解釋性。

## 重要專業術語解釋
1. Corpus:大量文本數據的集合,語料庫可以來自不同來源,例如新聞、書籍、對話記錄、社群媒體等,並且可能涵蓋單一語言或多種語言。
2. Document:語料庫中的一個文本單位,可以是文章、句子集合、段落,甚至是對話記錄,例如在社交媒體語料庫中,每則貼文或推文(tweet)可以視為一個 document。
4. Volcabulary:語料庫中出現的所有獨特詞彙(Unique Words),並過濾掉罕見詞、停用詞(Stopwords)等。
5. Words:語言的基本單位,在 NLP 中,每個單詞都是語意的載體。在不同語境下,單詞的含義可能會有所變化,這使得 NLP 模型需要考慮上下文來解析語義。
## Tokenization:將文本拆解為基本單位
Tokenization 是 NLP 任務中最基本的步驟,它的目的是將文本拆分為更小的單位,例如將一篇文章拆分成段落、句子或文字,甚至在英文中能拆分成子詞(Subword),例如 unhappiness 由常見的字母組合成的子詞 un、happi 和 ness,透過 Tokenization 可以讓電腦對文本進行標準化處理,進而應用於機器學習或深度學習模型。
Tokenization 有多種方式,其中最簡單的方法是基於空格和標點符號的拆分,然而,這種方法可能會導致複合詞(如 "New York")被錯誤拆解成 New 以及 York,可能會影響語意理解。為了克服這個問題,通常會使用 Lexicon-based Tokenization 方法。
### Lexicon-based Tokenization
Lexicon-based Tokenization 是一種基於詞庫(Lexicon)的分詞方法,依賴預先建立的詞典來識別單詞或詞組,以確保正確的 Tokenization,這種方法特別適合處理複合詞(compound words)、專有名詞(proper nouns)或多詞組表達(multi-word expressions),如 "New York"、"ice cream"、"machine learning" 等,例如 NLTK 和 spaCy 等 NLP 庫的 Tokenization 方法內建詞庫,能夠處理複合詞與專有名詞。
```PY=
from nltk.tokenize import word_tokenize
text = "I live in New York City."
tokens = word_tokenize(text)
print(tokens)
# 輸出: ['I', 'live', 'in', 'New', 'York', 'City', '.']
```
NLTK 會自動識別常見詞組,但仍然可能拆開複合詞。
```PY=
import spacy
nlp = spacy.load("en_core_web_sm")
text = "I live in New York City."
doc = nlp(text)
tokens = [token.text for token in doc]
print(tokens)
# 輸出: ['I', 'live', 'in', 'New York', 'City', '.']
```
spaCy 的 Tokenizer 透過內建的詞庫識別複合詞,確保 "New York" 被視為一個整體。
### Byte Pair Encoding(BPE)
Byte Pair Encoding(BPE)是一種基於統計的子詞(Subword)Tokenization 技術,最初用於數據壓縮,後來被應用於自然語言處理(NLP)領域,例如 GPT。BPE 透過合併最常見的字母或子詞對(byte pairs)來逐步建立詞彙表,使得模型能夠更有效地處理未知詞(OOV, Out-of-Vocabulary),並減少詞彙表大小。
```PY=
# 將文本中的單詞拆分為單個字符序列,並在每個字符之間加上空格
"happiness" → ["h", "a", "p", "p", "i", "n", "e", "s", "s"]
# 合併最常見的字母對,並將其作為新的子詞單位
["h", "a", "pp", "i", "n", "e", "ss"]
["h", "a", "pp", "i", "n", "ess"]
# 重複步驟,直到達到預設的子詞數量
["h", "appi", "n", "ess"]
```
## Stopwords:移除停用詞,提升語意資訊密度
在自然語言中,一些詞彙頻繁出現,但對於語意分析幫助不大,例如 "the"、"is"、"in"、"and" 等,這些詞被稱為 stopwords,移除這些詞可以減少處理文本的冗餘資訊,提高計算效率,並讓語意分析更聚焦於關鍵詞。
然而,在某些應用中,停用詞仍可能具有重要意義,例如在情感分析任務中,"not" 可能會影響句子的情緒傾向,因此在實際應用時,應根據具體任務來決定是否移除特定的停用詞。
## POS Tagging:詞性標註,理解語法結構
POS Tagging(詞性標註)是為文本中的每個單詞指定其詞性,如名詞(Noun)、動詞(Verb)、形容詞(Adjective)等,這對於語言理解至關重要,因為同一個詞可能具有不同的詞性,影響其語意。例如,"run" 可以是動詞("I run every morning."),也可以是名詞("He went for a run.")。
```PY=
import nltk
from nltk import pos_tag
from nltk.tokenize import word_tokenize
nltk.download("averaged_perceptron_tagger")
text = "The quick brown fox jumps over the lazy dog."
tokens = word_tokenize(text)
pos_tags = pos_tag(tokens)
print(pos_tags)
# [('The', 'DT'), ('quick', 'JJ'), ('brown', 'JJ'), ('fox', 'NN'), ('jumps', 'VBZ'), ('over', 'IN'), ('the', 'DT'), ('lazy', 'JJ'), ('dog', 'NN')]
```
## Named Entity Recognition(NER):識別專有名詞
Named Entity Recognition(NER, 命名實體識別)是 NLP 中的一項關鍵技術,用於識別文本中的特定名稱,如人名(Person)、地名(Location)、組織(Organization)、時間(Date/Time)等。NER 在資訊檢索、問答系統、金融分析等領域有著廣泛的應用。
例如,在句子 "Elon Musk is the CEO of Tesla." 中,NER 系統可以識別:
* Elon Musk → PERSON(人名)
* Tesla → ORG(組織名稱)
透過 NER,可以更有效地提取關鍵資訊,使文本分析更加智能化。
## Stemming:將單詞還原為詞幹
Stemming 是將單詞還原為其詞幹(stem),通常是透過去除詞尾變化來達成,這種方法的核心目標是減少單詞的變化形式,使得具有相同語意的詞彙能夠被視為相同的字詞,例如,"running" 會被轉換為 "run","flies" 可能會被簡化為 "fli"。
在 NLP 中,最常用的 Stemming 方法包括 Porter Stemmer 和 Lancaster Stemmer。
### Porter Stemmer
它基於一組有規則的詞尾刪減規則(suffix-stripping rules),透過多個步驟來去除詞尾,使詞幹保持較接近原始單詞的形式,這種方法的優勢在於詞幹的可讀性較高,適合一般 NLP 任務,例如文本分類、資訊檢索等。然而,Porter Stemmer 仍然可能導致語意錯誤,例如將 "argue" 轉換為 "argu",或將 "happiness" 轉換為 "happi",這可能影響模型對語義的理解。
```PY=
from nltk.stem import PorterStemmer
stemmer = PorterStemmer()
print(stemmer.stem("running")) # 輸出: run
print(stemmer.stem("happiness")) # 輸出: happi
print(stemmer.stem("flies")) # 輸出: fli
```
### Lancaster Stemmer
它與 Porter Stemmer 不同,Lancaster Stemmer 在處理單詞時刪減的程度更強,因此運行速度更快,適合需要高效處理大規模文本的場景。然而,由於 Lancaster Stemmer 過於激進,可能會導致詞幹過短,使其變得難以識別。例如,"happiness" 可能會被還原為 "happy",而 "argue" 則可能被過度簡化為 "arg"。這種簡化雖然對於某些資訊檢索系統可能有幫助,但在語意分析等需要更精確語義理解的任務中,可能會產生問題。
:::info
當選擇 Stemming 方法時,應根據應用場景來決定。如果需要更精確的詞形處理,或者需要保持詞彙的語意完整性,則可以考慮使用詞形還原(Lemmatization)來替代 Stemming,以獲得更準確的詞彙標準化效果。
:::
## Lemmatization:詞形還原,取得詞彙原型
Lemmatization 和 Stemming 類似,都是為了標準化單詞,但 Lemmatization 的處理方式更為精確,不同於 Stemming 只是去除詞尾,Lemmatization 會將單詞還原為字典中的詞形(lemma),並且能夠考慮單詞的詞性。例如,"running" 會被正確還原為 "run","flies" 會被還原為 "fly","better" 則會轉換為 "good"。
Lemmatization 的準確性高於 Stemming,但需要提供詞性(POS, Part-of-Speech)資訊來確保正確的還原,例如,"saw" 可以是動詞 "see" 的過去式,也可以是名詞 "鋸子"。透過詞性標註(POS tagging),系統可以準確判斷該詞應該還原為 "see" 還是保持原型 "saw"。
## WordNetLemmatizer
WordNetLemmatizer 是最常見的 Lemmatization 方法之一,它基於 WordNet 詞庫來查找單詞的詞形。WordNet 是一個大型的詞彙資料庫,包含英語單詞之間的語義關係,例如同義詞、反義詞和詞形變化等。
WordNetLemmatizer 透過匹配單詞的詞性,確保 Lemmatization 的結果更自然、更符合語法。例如,如果不指定詞性,"better" 可能無法被正確還原,但若提供詞性標註,它將被還原為 "good"。
```py=
from nltk.stem import WordNetLemmatizer
from nltk.corpus import wordnet
lemmatizer = WordNetLemmatizer()
# 單純進行詞形還原
print(lemmatizer.lemmatize("running")) # 預設為名詞,輸出: running
print(lemmatizer.lemmatize("running", pos="v")) # 指定為動詞,輸出: run
# 處理形容詞
print(lemmatizer.lemmatize("better", pos=wordnet.ADJ)) # 輸出: good
print(lemmatizer.lemmatize("flies", pos="n")) # 指定為名詞,輸出: fly
print(lemmatizer.lemmatize("flies", pos="v")) # 指定為動詞,輸出: fly
```
---
:::info
以上就是這篇文章「文字前處理(Text Preprocessing)」的所有內容,第一次看的人會花比較多時間消化吸收,這是很正常的事情,若有任何問題,歡迎在下方與我聯繫、討論,接下來也會繼續分享相關文章,敬請期待。