在自然語言處理(NLP)的奇幻世界中,詞向量技術就像一把魔法鑰匙,開啟了機器理解人類語言的大門。它能將詞彙轉換成向量表示,捕捉詞彙之間的語義關係,讓機器更好地理解人類語言。本文將探討詞向量技術,從經典的詞袋模型到更具表現力的詞嵌入,帶您領略詞向量的魅力。

詞袋模型:文字的向量化初探

詞袋模型是一種簡單但有效的文字表示方法,它將每個檔案表示為一個向量,向量的每個元素代表一個詞彙在檔案中出現的次數。

from collections import Counter

corpus = "This is an example sentence. This sentence is an example."
word_counts = Counter(corpus.split())
print(word_counts)
# Output: Counter({'is': 2, 'an': 2, 'example': 2, 'sentence.': 1, 'This': 1, 'sentence': 1})

這段程式碼使用 collections.Counter 計算每個詞彙在 corpus 中出現的次數。結果顯示 “is”、“an” 和 “example” 各出現兩次。

TF-IDF:詞彙的重要性加權

TF-IDF (Term Frequency-Inverse Document Frequency) 是一種改進的詞袋模型,它考慮了詞彙在整個語料函式庫中的重要性。TF-IDF 值越高,表示詞彙在該檔案中越重要。

from sklearn.feature_extraction.text import TfidfVectorizer

corpus = ["This is an example sentence.", "This sentence is an example."]
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(corpus)
print(vectorizer.get_feature_names_out())
print(X.toarray())

這段程式碼使用 TfidfVectorizer 計算每個詞彙的 TF-IDF 值。fit_transform 方法將文字轉換為 TF-IDF 向量,get_feature_names_out 方法傳回特徵名稱,toarray 方法將稀疏矩陣轉換為密集矩陣。

詞嵌入:捕捉語義的向量空間

詞嵌入是一種更為先進的詞向量表示方法,它將詞彙對映到一個連續的向量空間,使得語義相似的詞彙在向量空間中彼此靠近。

Word2Vec:根據預測的詞向量訓練

Word2Vec 是一種流行的詞嵌入訓練方法,它根據詞彙的上下文預測詞向量。

from gensim.models import Word2Vec

sentences = [["this", "is", "an", "example"], ["this", "is", "another", "example"]]
model = Word2Vec(sentences, min_count=1, vector_size=5)
print(model.wv['example'])

這段程式碼使用 gensim.models.Word2Vec 訓練詞嵌入模型。sentences 引數是訓練資料,min_count 引數設定詞彙出現的最低頻率,vector_size 引數設定詞向量的維度。

預訓練模型:站在巨人的肩膀上

使用預訓練的詞嵌入模型可以節省大量的訓練時間和資源。spaCy 和 Hugging Face Transformers 等函式庫提供了豐富的預訓練模型。

import spacy

nlp = spacy.load("en_core_web_sm")
doc = nlp("This is an example.")
print(doc[3].vector)  # 'example' 的詞向量

這段程式碼使用 spaCy 載入預訓練模型 “en_core_web_sm”,並取得 “example” 的詞向量。

from transformers import AutoTokenizer, AutoModel

tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
model = AutoModel.from_pretrained("bert-base-uncased")

inputs = tokenizer("This is an example.", return_tensors="pt")
outputs = model(**inputs)
print(outputs.last_hidden_state[0][3])  # 'example' 的詞向量

這段程式碼使用 Hugging Face Transformers 載入預訓練的 BERT 模型,並取得 “example” 的詞向量。

詞向量技術的應用

詞向量技術廣泛應用於各種 NLP 任務,例如:

  • 文字分類別: 判斷文字的情感傾向、主題等。
  • 機器翻譯: 將一種語言翻譯成另一種語言。
  • 資訊檢索: 根據關鍵字搜尋相關資訊。
  • 問答系統: 回答使用者提出的問題。
  • 文字生成: 生成新的文字內容。
  graph LR
    A[詞向量技術] --> B(文字分類別)
    A --> C(機器翻譯)
    A --> D(資訊檢索)
    A --> E(問答系統)
    A --> F(文字生成)

此圖表展示了詞向量技術的應用領域。

詞向量技術是 NLP 領域的根本,它為機器理解人類語言提供了強大的工具。從詞袋模型到詞嵌入,詞向量技術不斷發展,為 NLP 的進步提供了源源不斷的動力。

import nltk
from nltk.stem import PorterStemmer, WordNetLemmatizer
import spacy
from textblob import Word
from pattern.en import lemma

nltk.download('wordnet')
nltk.download('omw-1.4')

# --- Porter Stemmer ---
stemmer = PorterStemmer()
words = ["jumps", "jumping", "jumped", "flies", "flying"]
stemmed_words = [stemmer.stem(word) for word in words]
print(f"Porter Stemmer: {stemmed_words}")


# --- WordNet Lemmatizer ---
lemmatizer = WordNetLemmatizer()
lemmatized_words = [lemmatizer.lemmatize(word, pos='v') for word in words]  # Specify verb POS
print(f"WordNet Lemmatizer: {lemmatized_words}")



# --- spaCy Lemmatizer ---
nlp = spacy.load("en_core_web_sm")
doc = nlp("jumps jumping jumped flies flying")
spacy_lemmas = [token.lemma_ for token in doc]
print(f"spaCy Lemmatizer: {spacy_lemmas}")


# --- TextBlob Lemmatizer ---
textblob_lemmas = [Word(word).lemmatize("v") for word in words] #verb
print(f"TextBlob Lemmatizer: {textblob_lemmas}")



# --- Pattern Lemmatizer ---
pattern_lemmas = [lemma(word) for word in words]
print(f"Pattern Lemmatizer: {pattern_lemmas}")

這段程式碼示範了使用不同Python套件進行Stemming和Lemmatization。PorterStemmer是一個根據規則的Stemmer,而WordNetLemmatizer、spaCy、TextBlob和Pattern則提供了根據詞典的Lemmatization。選擇哪種方法取決於應用場景和所需的精確度。

  graph LR
    B[B]
    D[D]
    F[F]
    A[原始文字] --> B{Tokenization}
    B --> C[Tokens]
    C --> D{Stop Words Removal}
    D --> E[Filtered Tokens]
    E --> F{Stemming/Lemmatization}
    F --> G[Processed Text]

結語

本文探討了Tokenization、Stop Words Removal、Stemming和Lemmatization等文字探勘技術,並示範瞭如何使用NLTK、spaCy、TextBlob、Gensim、Scikit-learn、Transformers和Pattern等Python套件進行實作。理解這些技術的差異和應用,能幫助您更有效地處理和分析文字資料,從而獲得更有價值的洞見。選擇哪種工具和技術取決於您的具體需求,例如效能、準確性和所需的分析型別。建議根據專案需求選擇最合適的工具。

透過以上技術的整合運用,玄貓期望能提供讀者更清晰、更實用的文字探勘技術,並協助讀者在各自的領域中更有效地應用這些技術。

import nltk
from nltk.tokenize import word_tokenize
from nltk.probability import FreqDist
from gensim.corpora import Dictionary
from collections import defaultdict
from gensim.models import TfidfModel
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer

# 事先下載所需資料
nltk.download("punkt")

# 使用 NLTK 計算詞頻
text = "這是一個範例檔案。另一個檔案包含一些詞彙。重複檔案包含一些詞彙。第三個檔案用於說明。重複說明。"
words = word_tokenize(text)
fdist = FreqDist(words)
print("使用 NLTK 計算詞頻:")
for word, frequency in fdist.items():
    print(f"Word: {word}, Frequency: {frequency}")


# 使用 Gensim 建立詞袋模型和 TF-IDF 模型
documents = [
    "這是一個範例檔案。",
    "另一個檔案包含一些詞彙。重複檔案包含一些詞彙。",
    "第三個檔案用於說明。重複說明。",
]
tokenized_docs = [doc.split() for doc in documents]
dictionary = Dictionary(tokenized_docs)
corpus = [dictionary.doc2bow(doc) for doc in tokenized_docs]
tfidf = TfidfModel(corpus, dictionary=dictionary)
overall_tfidf = defaultdict(float)
for doc in tfidf[corpus]:
    for word_id, tfidf_score in doc:
        overall_tfidf[word_id] += tfidf_score
print("\n使用 Gensim 建立詞袋模型和 TF-IDF 模型:")
for word_id, tfidf_score in overall_tfidf.items():
    word = dictionary[word_id]
    print(f"Word: {word}, Overall TF-IDF Score: {tfidf_score:.4f}")

# 使用 Scikit-learn 建立詞袋模型
vectorizer = CountVectorizer()
corpus_sklearn = " ".join(documents)  # 將所有檔案合併成一個字串
X = vectorizer.fit_transform([corpus_sklearn])  # 使用合併後的字串
feature_names = vectorizer.get_feature_names_out()
word_frequencies = X.toarray()[0]
print("\n使用 Scikit-learn 建立詞袋模型:")
for word, frequency in zip(feature_names, word_frequencies):
    print(f"Word: {word}, Frequency: {frequency}")

這段程式碼示範了使用三種不同的 Python 函式庫 (NLTK, Gensim, Scikit-learn) 來實作詞袋模型以及 TF-IDF 模型。 首先,我們使用 NLTK 的 word_tokenize 函式將文字斷詞,並使用 FreqDist 計算每個詞彙的出現頻率。 接著,我們使用 Gensim 的 Dictionary 建立詞彙表,並將檔案轉換成詞袋錶示 (bag-of-words representation)。然後,我們使用 TfidfModel 計算每個詞彙的 TF-IDF 值,TF-IDF 值可以反映詞彙在檔案集合中的重要性。 最後,我們使用 Scikit-learn 的 CountVectorizer 將檔案轉換成詞彙計數向量,這也是一種詞袋模型的實作方式。

詞袋模型雖然簡單易懂,卻無法捕捉詞序和上下文資訊。這也促使了更先進的詞向量技術的發展,例如詞嵌入(Word Embeddings)。

詞嵌入(Word Embeddings)

想像一下,每個詞彙不再只是袋子裡的一個積木,而是一個座標系中的向量。向量之間的距離和方向反映了詞彙之間的語義關係。這就是詞嵌入的核心思想。它將詞彙對映到一個低維向量空間,使得語義相似的詞彙在向量空間中彼此靠近。

詞嵌入技術的發展經歷了從 Word2Vec、GloVe 到 FastText 等多個階段,它們各有優缺點,適用於不同的 NLP 任務。近年來,隨著深度學習的興起,根據深度學習的詞嵌入方法,例如 BERT 和 ELMo,在許多 NLP 任務上取得了顯著的成果。這些模型能夠捕捉更豐富的上下文資訊,生成更具表達力的詞向量。

在後續的文章中,我們將探討各種詞嵌入技術,並提供使用 Python 進行實作的範例。敬請期待!