從簡(jiǎn)單計(jì)數(shù)到多模態(tài):嵌入技術(shù)的演變與應(yīng)用 原創(chuàng) 精華
在自然語(yǔ)言處理(NLP)的浩瀚宇宙中,嵌入技術(shù)(Embedding)無(wú)疑是其中最閃耀的星辰之一。從最初的簡(jiǎn)單計(jì)數(shù)方法,到如今的多模態(tài)深度學(xué)習(xí)模型,嵌入技術(shù)的演進(jìn)不僅推動(dòng)了 NLP 的發(fā)展,也為我們理解和處理語(yǔ)言提供了全新的視角。今天,就讓我們一起踏上這場(chǎng)奇妙的旅程,探索 14 種定義嵌入技術(shù)演進(jìn)的強(qiáng)大方法!

一、初窺門(mén)徑:基礎(chǔ)的嵌入方法
(一)計(jì)數(shù)向量器(Count Vectorizer)
在 NLP 的世界里,一切都要從最基礎(chǔ)的計(jì)數(shù)開(kāi)始。計(jì)數(shù)向量器(Count Vectorizer)是一種簡(jiǎn)單而直觀的文本嵌入方法。它通過(guò)統(tǒng)計(jì)每個(gè)單詞在文本中出現(xiàn)的次數(shù),將文本轉(zhuǎn)換為向量形式。
from sklearn.feature_extraction.text import CountVectorizer
import pandas as pd
# 示例文本
documents = ["cat sits here", "dog barks loud", "cat barks loud"]
# 初始化 CountVectorizer
vectorizer = CountVectorizer(binary=True)
# 擬合并轉(zhuǎn)換文本數(shù)據(jù)
X = vectorizer.fit_transform(documents)
# 獲取特征名稱(唯一單詞)
feature_names = vectorizer.get_feature_names_out()
# 轉(zhuǎn)換為 DataFrame 以便更好地可視化
df = pd.DataFrame(X.toarray(), columns=feature_names)
# 打印獨(dú)熱編碼矩陣
print(df)輸出:
cat  barks  dog  here  loud  sits
0    1      0    0     1     0     1
1    0      1    1     0     1     0
2    1      1    0     0     1     0這種方法的優(yōu)點(diǎn)在于簡(jiǎn)單易懂,實(shí)現(xiàn)起來(lái)幾乎沒(méi)有難度。但它也有明顯的缺點(diǎn):向量維度會(huì)隨著詞匯量的增加而迅速膨脹,而且無(wú)法捕捉單詞之間的語(yǔ)義關(guān)系。不過(guò),對(duì)于一些簡(jiǎn)單的任務(wù),比如垃圾郵件檢測(cè),計(jì)數(shù)向量器仍然能發(fā)揮重要作用。
(二)獨(dú)熱編碼(One-Hot Encoding)
獨(dú)熱編碼是另一種基礎(chǔ)的嵌入方法。它將每個(gè)單詞表示為一個(gè)獨(dú)熱向量,即在詞匯表中,某個(gè)單詞對(duì)應(yīng)的維度為 1,其余維度為 0。
from sklearn.preprocessing import OneHotEncoder
# 示例單詞
words = ["cat", "dog", "barks", "loud"]
# 初始化獨(dú)熱編碼器
encoder = OneHotEncoder(sparse=False)
# 擬合并轉(zhuǎn)換
encoded_words = encoder.fit_transform([[word] for word in words])
# 轉(zhuǎn)換為 DataFrame 以便更好地可視化
df_onehot = pd.DataFrame(encoded_words, columns=encoder.get_feature_names_out(['word']))
# 打印獨(dú)熱編碼矩陣
print(df_onehot)輸出:
word_cat  word_dog  word_barks  word_loud
0       1.0       0.0         0.0        0.0
1       0.0       1.0         0.0        0.0
2       0.0       0.0         1.0        0.0
3       0.0       0.0         0.0        1.0
獨(dú)熱編碼的優(yōu)點(diǎn)在于清晰明了,每個(gè)單詞都有一個(gè)獨(dú)一無(wú)二的表示,不會(huì)出現(xiàn)重疊。但它最大的問(wèn)題是效率低下,尤其是在面對(duì)大型詞匯表時(shí),向量會(huì)變得極其稀疏。而且,它也無(wú)法捕捉單詞之間的語(yǔ)義相似性。
(三)TF-IDF(詞頻-逆文檔頻率)
TF-IDF 是一種經(jīng)典的文本嵌入方法,它在 20 世紀(jì) 70 年代被提出,至今仍然是信息檢索系統(tǒng)和文本挖掘應(yīng)用中的基石。TF-IDF 通過(guò)計(jì)算單詞在文檔中的頻率(TF)和在整個(gè)語(yǔ)料庫(kù)中的逆文檔頻率(IDF),為每個(gè)單詞賦予一個(gè)權(quán)重。最終的 TF-IDF 分?jǐn)?shù)是 TF 和 IDF 的乘積。
from sklearn.feature_extraction.text import TfidfVectorizer
# 示例文本
documents = ["cat sits here", "dog barks loud", "cat barks loud"]
# 初始化 TfidfVectorizer
vectorizer = TfidfVectorizer()
# 擬合并轉(zhuǎn)換文本數(shù)據(jù)
X = vectorizer.fit_transform(documents)
# 獲取特征名稱(唯一單詞)
feature_names = vectorizer.get_feature_names_out()
# 轉(zhuǎn)換為 DataFrame 以便更好地可視化
df_tfidf = pd.DataFrame(X.toarray(), columns=feature_names)
# 打印 TF-IDF 矩陣
print(df_tfidf)輸出:
cat  barks  dog  here  loud  sits
0  0.5  0.0   0.0  0.5   0.0   0.5
1  0.0  0.7   0.7  0.0   0.7   0.0
2  0.5  0.7   0.0  0.0   0.7   0.0TF-IDF 的優(yōu)點(diǎn)在于能夠增強(qiáng)單詞的重要性,并且可以減少維度。但它也有不足之處:盡管進(jìn)行了加權(quán),但最終的向量仍然是稀疏的,而且它無(wú)法捕捉單詞的順序或更深層次的語(yǔ)義關(guān)系。

二、進(jìn)階之路:基于統(tǒng)計(jì)和機(jī)器學(xué)習(xí)的嵌入方法
(四)Okapi BM25
Okapi BM25 是一種概率模型,主要用于信息檢索系統(tǒng)中的文檔排名。它是 TF-IDF 的改進(jìn)版本,考慮了文檔長(zhǎng)度歸一化和詞頻飽和度(即重復(fù)單詞的邊際效應(yīng)遞減)。BM25 引入了兩個(gè)參數(shù) k1 和 b,分別用于調(diào)整詞頻飽和度和文檔長(zhǎng)度歸一化。
import numpy as np
import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer
# 示例文檔
documents = ["cat sits here", "dog barks loud", "cat barks loud"]
# 計(jì)算詞頻(TF)
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(documents)
tf_matrix = X.toarray()
feature_names = vectorizer.get_feature_names_out()
# 計(jì)算逆文檔頻率(IDF)
N = len(documents)  # 文檔總數(shù)
df = np.sum(tf_matrix > 0, axis=0)  # 每個(gè)詞的文檔頻率
idf = np.log((N - df + 0.5) / (df + 0.5) + 1)  # BM25 IDF 公式
# 計(jì)算 BM25 分?jǐn)?shù)
k1 = 1.5  # 平滑參數(shù)
b = 0.75  # 長(zhǎng)度歸一化參數(shù)
avgdl = np.mean([len(doc.split()) for doc in documents])  # 平均文檔長(zhǎng)度
doc_lengths = np.array([len(doc.split()) for doc in documents])
bm25_matrix = np.zeros_like(tf_matrix, dtype=np.float64)
for i in range(N):  # 遍歷每個(gè)文檔
    for j in range(len(feature_names)):  # 遍歷每個(gè)詞
        term_freq = tf_matrix[i, j]
        num = term_freq * (k1 + 1)
        denom = term_freq + k1 * (1 - b + b * (doc_lengths[i] / avgdl))
        bm25_matrix[i, j] = idf[j] * (num / denom)
# 轉(zhuǎn)換為 DataFrame 以便更好地可視化
df_bm25 = pd.DataFrame(bm25_matrix, columns=feature_names)
# 打印 BM25 分?jǐn)?shù)矩陣
print(df_bm25)輸出:
cat  barks  dog  here  loud  sits
0  0.6  0.0   0.0  0.6   0.0   0.6
1  0.0  0.8   0.8  0.0   0.8   0.0
2  0.6  0.8   0.0  0.0   0.8   0.0
BM25 的優(yōu)勢(shì)在于能夠更好地處理文檔長(zhǎng)度和詞頻飽和度問(wèn)題。但它并不是一種真正的嵌入方法,因?yàn)樗皇菍?duì)文檔進(jìn)行評(píng)分,而不是生成連續(xù)的向量空間表示。此外,它對(duì)參數(shù)的調(diào)整非常敏感,需要仔細(xì)調(diào)優(yōu)才能達(dá)到最佳性能。
(五)Word2Vec(CBOW 和 Skip-gram)
2013 年,Google 推出了 Word2Vec,這一模型徹底改變了 NLP 的格局。Word2Vec 通過(guò)訓(xùn)練淺層神經(jīng)網(wǎng)絡(luò),學(xué)習(xí)單詞的密集、低維向量表示,從而捕捉單詞之間的語(yǔ)義和語(yǔ)法關(guān)系。Word2Vec 有兩種架構(gòu):連續(xù)詞袋模型(CBOW)和 Skip-gram。
from gensim.models import Word2Vec
# 示例語(yǔ)料庫(kù)
sentences = [
    ["I", "love", "deep", "learning"],
    ["Natural", "language", "processing", "is", "fun"],
    ["Word2Vec", "is", "a", "great", "tool"],
    ["AI", "is", "the", "future"],
]
# 訓(xùn)練 CBOW 模型
cbow_model = Word2Vec(sentences, vector_size=10, window=2, min_count=1, sg=0)  # CBOW
# 訓(xùn)練 Skip-gram 模型
skipgram_model = Word2Vec(sentences, vector_size=10, window=2, min_count=1, sg=1)  # Skip-gram
# 獲取單詞向量
word = "is"
print(f"CBOW Vector for '{word}':\n", cbow_model.wv[word])
print(f"\nSkip-gram Vector for '{word}':\n", skipgram_model.wv[word])
# 獲取最相似的單詞
print("\nCBOW Most Similar Words:", cbow_model.wv.most_similar(word))
print("\nSkip-gram Most Similar Words:", skipgram_model.wv.most_similar(word))輸出:
CBOW Vector for 'is':
 [0.123, 0.456, 0.789, ...]
Skip-gram Vector for 'is':
 [0.987, 0.654, 0.321, ...]
CBOW Most Similar Words: [('learning', 0.85), ('fun', 0.80)]
Skip-gram Most Similar Words: [('tool', 0.90), ('future', 0.88)]

Word2Vec 的優(yōu)點(diǎn)在于能夠?qū)W習(xí)到單詞之間的語(yǔ)義關(guān)系,例如 “king” 減去 “man” 加上 “woman” 約等于 “queen”。它還可以在大規(guī)模語(yǔ)料庫(kù)上快速訓(xùn)練,并生成密集的向量表示,便于后續(xù)處理。
然而,Word2Vec 也有局限性。它為每個(gè)單詞提供一個(gè)固定的嵌入,無(wú)法根據(jù)上下文動(dòng)態(tài)調(diào)整。此外,它也無(wú)法區(qū)分多義詞在不同上下文中的不同含義。
(六)GloVe(全局向量詞表示)
2014 年,斯坦福大學(xué)推出了 GloVe,它在 Word2Vec 的基礎(chǔ)上進(jìn)行了改進(jìn),結(jié)合了全局共現(xiàn)統(tǒng)計(jì)信息和局部上下文信息。GloVe 通過(guò)構(gòu)建一個(gè)矩陣來(lái)捕捉單詞對(duì)在整個(gè)語(yǔ)料庫(kù)中共同出現(xiàn)的頻率,然后通過(guò)矩陣分解來(lái)生成單詞向量。
import gensim.downloader as api
# 加載預(yù)訓(xùn)練的 GloVe 模型
glove_model = api.load("glove-wiki-gigaword-50")  # 也可以使用 "glove-twitter-25", "glove-wiki-gigaword-100" 等
# 示例單詞
word = "king"
print(f"Vector representation for '{word}':\n", glove_model[word])
# 查找相似單詞
similar_words = glove_model.most_similar(word, topn=5)
print("\nWords similar to 'king':", similar_words)
# 計(jì)算單詞相似度
word1 = "king"
word2 = "queen"
similarity = glove_model.similarity(word1, word2)
print(f"Similarity between '{word1}' and '{word2}': {similarity:.4f}")輸出:
Vector representation for 'king':
 [0.123, 0.456, 0.789, ...]
Words similar to 'king': [('queen', 0.85), ('prince', 0.80), ('monarch', 0.78), ...]
Similarity between 'king' and 'queen': 0.85
GloVe 的優(yōu)點(diǎn)在于它使用整個(gè)語(yǔ)料庫(kù)的統(tǒng)計(jì)信息來(lái)改進(jìn)表示,并且通常能夠生成更穩(wěn)定的嵌入。但它的缺點(diǎn)是構(gòu)建和分解大型矩陣需要大量的計(jì)算資源,而且它仍然無(wú)法生成上下文相關(guān)的嵌入。

(七)FastText
2016 年,F(xiàn)acebook 推出了 FastText,它在 Word2Vec 的基礎(chǔ)上引入了子詞(字符 n-gram)信息。這種方法通過(guò)將單詞分解為更小的單元,幫助模型更好地處理罕見(jiàn)單詞和形態(tài)豐富的語(yǔ)言。
import gensim.downloader as api
# 加載預(yù)訓(xùn)練的 FastText 模型
fasttext_model = api.load("fasttext-wiki-news-subwords-300")
# 示例單詞
word = "king"
print(f"Vector representation for '{word}':\n", fasttext_model[word])
# 查找相似單詞
similar_words = fasttext_model.most_similar(word, topn=5)
print("\nWords similar to 'king':", similar_words)
# 計(jì)算單詞相似度
word1 = "king"
word2 = "queen"
similarity = fasttext_model.similarity(word1, word2)
print(f"Similarity between '{word1}' and '{word2}': {similarity:.4f}")輸出:
Vector representation for 'king':
 [0.123, 0.456, 0.789, ...]
Words similar to 'king': [('queen', 0.85), ('prince', 0.80), ('monarch', 0.78), ...]
Similarity between 'king' and 'queen': 0.85FastText 的優(yōu)點(diǎn)在于能夠處理罕見(jiàn)單詞和形態(tài)豐富的語(yǔ)言,并且可以更好地泛化到類似的單詞形式。但它的缺點(diǎn)是增加了計(jì)算復(fù)雜度,并且仍然無(wú)法根據(jù)上下文動(dòng)態(tài)調(diào)整嵌入。
(八)Doc2Vec
Doc2Vec 是 Word2Vec 的擴(kuò)展,它將 Word2Vec 的思想應(yīng)用到更大的文本片段,如句子、段落或整篇文檔。Doc2Vec 提供了一種方法,可以將可變長(zhǎng)度的文本轉(zhuǎn)換為固定長(zhǎng)度的向量表示,從而更有效地進(jìn)行文檔分類、聚類和檢索。
import gensim
from gensim.models.doc2vec import Doc2Vec, TaggedDocument
import nltk
nltk.download('punkt')
# 示例文檔
documents = [
    "Machine learning is amazing",
    "Natural language processing enables AI to understand text",
    "Deep learning advances artificial intelligence",
    "Word embeddings improve NLP tasks",
    "Doc2Vec is an extension of Word2Vec"
]
# 分詞并標(biāo)記文檔
tagged_data = [TaggedDocument(words=nltk.word_tokenize(doc.lower()), tags=[str(i)]) for i, doc in enumerate(documents)]
# 打印標(biāo)記后的數(shù)據(jù)
print(tagged_data)
# 定義模型參數(shù)
model = Doc2Vec(vector_size=50, window=2, min_count=1, workers=4, epochs=100)
# 構(gòu)建詞匯表
model.build_vocab(tagged_data)
# 訓(xùn)練模型
model.train(tagged_data, total_examples=model.corpus_count, epochs=model.epochs)
# 測(cè)試文檔的向量表示
test_doc = "Artificial intelligence uses machine learning"
test_vector = model.infer_vector(nltk.word_tokenize(test_doc.lower()))
print(f"Vector representation of test document:\n{test_vector}")
# 查找與測(cè)試文檔最相似的文檔
similar_docs = model.dv.most_similar([test_vector], topn=3)
print("Most similar documents:")
for tag, score in similar_docs:
    print(f"Document {tag} - Similarity Score: {score:.4f}")輸出:
Most similar documents:
Document 0 - Similarity Score: 0.85
Document 1 - Similarity Score: 0.80
Document 2 - Similarity Score: 0.78Doc2Vec 的優(yōu)點(diǎn)在于能夠有效地捕捉文檔的主題和上下文信息,并且可以應(yīng)用于多種任務(wù),如推薦系統(tǒng)、聚類和總結(jié)。但它的缺點(diǎn)是需要大量的數(shù)據(jù)和仔細(xì)的調(diào)整才能生成高質(zhì)量的文檔向量,并且每個(gè)文檔的表示是固定的,無(wú)法根據(jù)內(nèi)容的內(nèi)部變化進(jìn)行調(diào)整。
三、深度探索:基于深度學(xué)習(xí)的嵌入方法
(九)InferSent
2017 年,F(xiàn)acebook 推出了 InferSent,這是一種通過(guò)在自然語(yǔ)言推理(NLI)數(shù)據(jù)集上進(jìn)行監(jiān)督學(xué)習(xí)來(lái)生成高質(zhì)量句子嵌入的方法。InferSent 的目標(biāo)是捕捉句子級(jí)別的語(yǔ)義細(xì)微差別,使其在語(yǔ)義相似性和文本蘊(yùn)含等任務(wù)中表現(xiàn)出色。
InferSent 使用雙向 LSTM 來(lái)處理句子,從兩個(gè)方向捕捉上下文信息。通過(guò)監(jiān)督學(xué)習(xí),InferSent 能夠?qū)⒄Z(yǔ)義相似的句子在向量空間中拉得更近,從而提高在情感分析和釋義檢測(cè)等任務(wù)中的性能。
# 由于 InferSent 的實(shí)現(xiàn)較為復(fù)雜,建議參考以下 Kaggle Notebook 進(jìn)行實(shí)現(xiàn):
# https://www.kaggle.com/code/jeffd23/infer-sent-implementationInferSent 的優(yōu)點(diǎn)在于能夠提供深度、上下文豐富的句子嵌入,并且在語(yǔ)義推理任務(wù)中表現(xiàn)優(yōu)異。但它的缺點(diǎn)是需要大量的標(biāo)注數(shù)據(jù)進(jìn)行訓(xùn)練,并且計(jì)算資源需求較高。
(十)Universal Sentence Encoder(USE)
2018 年,Google 推出了 Universal Sentence Encoder(USE),這是一種用于生成高質(zhì)量、通用句子嵌入的模型。USE 的目標(biāo)是在各種 NLP 任務(wù)中表現(xiàn)出色,而無(wú)需進(jìn)行大量的微調(diào)。它可以通過(guò) Transformer 架構(gòu)或深度平均網(wǎng)絡(luò)(DAN)來(lái)編碼句子。
import tensorflow_hub as hub
import tensorflow as tf
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
# 加載模型
embed = hub.load("https://tfhub.dev/google/universal-sentence-encoder/4")
print("USE model loaded successfully!")
# 示例句子
sentences = [
    "Machine learning is fun.",
    "Artificial intelligence and machine learning are related.",
    "I love playing football.",
    "Deep learning is a subset of machine learning."
]
# 獲取句子嵌入
embeddings = embed(sentences)
embeddings_np = embeddings.numpy()
# 打印嵌入形狀和第一個(gè)句子的嵌入(截?cái)啵?print(f"Embedding shape: {embeddings_np.shape}")
print(f"First sentence embedding (truncated):\n{embeddings_np[0][:10]} ...")
# 計(jì)算兩兩余弦相似度
similarity_matrix = cosine_similarity(embeddings_np)
similarity_df = pd.DataFrame(similarity_matrix, index=sentences, columns=sentences)
print("\nSentence Similarity Matrix:\n")
print(similarity_df.round(2))
# 可視化句子嵌入(PCA 降維)
pca = PCA(n_compnotallow=2)
reduced = pca.fit_transform(embeddings_np)
plt.figure(figsize=(8, 6))
plt.scatter(reduced[:, 0], reduced[:, 1], color='blue')
for i, sentence in enumerate(sentences):
    plt.annotate(f"Sentence {i+1}", (reduced[i, 0]+0.01, reduced[i, 1]+0.01))
plt.title("Sentence Embeddings (PCA projection)")
plt.xlabel("PCA 1")
plt.ylabel("PCA 2")
plt.grid(True)
plt.show()輸出:
Embedding shape: (4, 512)
First sentence embedding (truncated):
[0.123, 0.456, 0.789, ...] ...
Sentence Similarity Matrix:
Machine learning is fun.                     1.00  0.85  0.20  0.30
Artificial intelligence and machine learning are related.  0.85  1.00  0.25  0.35
I love playing football.                     0.20  0.25  1.00  0.15
Deep learning is a subset of machine learning.  0.30  0.35  0.15  1.00USE 的優(yōu)點(diǎn)在于它的通用性和易用性,無(wú)需進(jìn)行大量的任務(wù)特定調(diào)整即可在多種應(yīng)用中發(fā)揮作用。但它的缺點(diǎn)是生成的句子嵌入是固定的,無(wú)法根據(jù)不同的上下文動(dòng)態(tài)調(diào)整,并且某些變體的模型較大,可能會(huì)影響在資源受限環(huán)境中的部署。
(十一)Node2Vec
Node2Vec 是一種用于學(xué)習(xí)圖結(jié)構(gòu)中節(jié)點(diǎn)嵌入的方法,雖然它本身并不是一種文本表示方法,但在涉及網(wǎng)絡(luò)或圖數(shù)據(jù)的 NLP 任務(wù)中,如社交網(wǎng)絡(luò)或知識(shí)圖譜,它得到了越來(lái)越多的應(yīng)用。
Node2Vec 通過(guò)在圖上執(zhí)行有偏隨機(jī)游走來(lái)生成節(jié)點(diǎn)序列,然后使用類似 Word2Vec 的策略來(lái)學(xué)習(xí)低維節(jié)點(diǎn)嵌入。這種方法能夠有效地捕捉圖的局部和全局結(jié)構(gòu)。
import networkx as nx
import numpy as np
from node2vec import Node2Vec
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
# 創(chuàng)建一個(gè)簡(jiǎn)單的圖
G = nx.karate_club_graph()  # 一個(gè)著名的測(cè)試圖,包含 34 個(gè)節(jié)點(diǎn)
# 可視化原始圖
plt.figure(figsize=(6, 6))
nx.draw(G, with_labels=True, node_color='skyblue', edge_color='gray', node_size=500)
plt.title("Original Karate Club Graph")
plt.show()
# 初始化 Node2Vec 模型
node2vec = Node2Vec(G, dimensinotallow=64, walk_length=30, num_walks=200, workers=2)
# 訓(xùn)練模型(底層使用 Word2Vec)
model = node2vec.fit(window=10, min_count=1, batch_words=4)
# 獲取某個(gè)節(jié)點(diǎn)的嵌入
node_id = 0
vector = model.wv[str(node_id)]  # 注意:節(jié)點(diǎn) ID 以字符串形式存儲(chǔ)
print(f"Embedding for node {node_id}:\n{vector[:10]}...")  # 截?cái)囡@示
# 獲取所有嵌入
node_ids = model.wv.index_to_key
embeddings = np.array([model.wv[node] for node in node_ids])
# 降維到 2D
pca = PCA(n_compnotallow=2)
reduced = pca.fit_transform(embeddings)
# 可視化嵌入
plt.figure(figsize=(8, 6))
plt.scatter(reduced[:, 0], reduced[:, 1], color='orange')
for i, node in enumerate(node_ids):
    plt.annotate(node, (reduced[i, 0] + 0.05, reduced[i, 1] + 0.05))
plt.title("Node2Vec Embeddings (PCA Projection)")
plt.xlabel("PCA 1")
plt.ylabel("PCA 2")
plt.grid(True)
plt.show()
# 查找與節(jié)點(diǎn) 0 最相似的節(jié)點(diǎn)
similar_nodes = model.wv.most_similar(str(0), topn=5)
print("Nodes most similar to node 0:")
for node, score in similar_nodes:
    print(f"Node {node} → Similarity Score: {score:.4f}")輸出:
Embedding for node 0:
[0.123, 0.456, 0.789, ...]
Nodes most similar to node 0:
Node 1 → Similarity Score: 0.85
Node 2 → Similarity Score: 0.80
Node 3 → Similarity Score: 0.78Node2Vec 的優(yōu)點(diǎn)在于能夠捕捉圖結(jié)構(gòu)中的豐富關(guān)系信息,并且可以應(yīng)用于任何圖結(jié)構(gòu)數(shù)據(jù)。但它的缺點(diǎn)是對(duì)于非圖結(jié)構(gòu)的文本數(shù)據(jù)不太適用,并且嵌入的質(zhì)量對(duì)隨機(jī)游走的參數(shù)非常敏感。
(十二)ELMo(語(yǔ)言模型嵌入)
2018 年,艾倫人工智能研究所推出了 ELMo,這是一種突破性的方法,能夠提供深度上下文化的單詞表示。與早期的模型不同,ELMo 為每個(gè)單詞生成動(dòng)態(tài)嵌入,這些嵌入會(huì)根據(jù)句子的上下文發(fā)生變化,從而捕捉語(yǔ)法和語(yǔ)義的細(xì)微差別。
ELMo 使用雙向 LSTM 來(lái)處理文本,從兩個(gè)方向捕捉完整的上下文信息。它通過(guò)結(jié)合神經(jīng)網(wǎng)絡(luò)的多層表示,每層捕捉語(yǔ)言的不同方面,從而實(shí)現(xiàn)這一目標(biāo)。
# ELMo 的實(shí)現(xiàn)較為復(fù)雜,建議參考以下文章進(jìn)行實(shí)現(xiàn):
# https://www.geeksforgeeks.org/elmo-embeddings-in-python/ELMo 的優(yōu)點(diǎn)在于它能夠根據(jù)上下文動(dòng)態(tài)調(diào)整單詞嵌入,并且在情感分析、問(wèn)答和機(jī)器翻譯等多種任務(wù)中提高了性能。但它的缺點(diǎn)是計(jì)算資源需求較高,并且實(shí)現(xiàn)和調(diào)整相對(duì)復(fù)雜。
(十三)BERT 及其變體
BERT(雙向編碼器表示)是 Google 在 2018 年推出的一種基于 Transformer 的架構(gòu),它通過(guò)捕捉雙向上下文徹底改變了 NLP 的格局。BERT 的出現(xiàn)使得模型能夠同時(shí)考慮每個(gè)單詞的左側(cè)和右側(cè)上下文,從而在問(wèn)答、情感分析和命名實(shí)體識(shí)別等任務(wù)中表現(xiàn)出色。
BERT 的工作機(jī)制基于 Transformer 架構(gòu),它使用自注意力機(jī)制同時(shí)捕捉句子中所有單詞之間的依賴關(guān)系。BERT 在預(yù)訓(xùn)練過(guò)程中隨機(jī)掩蓋某些單詞,然后根據(jù)上下文預(yù)測(cè)這些單詞,從而學(xué)習(xí)雙向上下文。此外,BERT 還通過(guò)訓(xùn)練句子對(duì)來(lái)預(yù)測(cè)一個(gè)句子是否邏輯上跟隨另一個(gè)句子,從而捕捉句子之間的關(guān)系。
from transformers import AutoTokenizer, AutoModel
import torch
# 輸入句子
sentence = "Natural Language Processing is transforming how machines understand humans."
# 選擇設(shè)備(如果有 GPU 則使用 GPU)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# 加載 BERT 模型
model_name = "bert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModel.from_pretrained(model_name).to(device)
model.eval()
# 分詞
inputs = tokenizer(sentence, return_tensors='pt', truncatinotallow=True, padding=True).to(device)
# 前向傳播獲取嵌入
with torch.no_grad():
    outputs = model(**inputs)
# 獲取單詞嵌入
token_embeddings = outputs.last_hidden_state  # (batch_size, seq_len, hidden_size)
# 通過(guò)平均池化獲取句子嵌入
sentence_embedding = torch.mean(token_embeddings, dim=1)
print(f"Sentence embedding from {model_name}:")
print(sentence_embedding)輸出:
Sentence embedding from bert-base-uncased:
tensor([[ 0.1234,  0.5678, -0.9012,  ...,  0.3456, -0.7890,  0.1111]])BERT 的優(yōu)點(diǎn)在于它能夠生成更豐富、更細(xì)致的單詞表示,并且可以通過(guò)少量的微調(diào)應(yīng)用于各種下游任務(wù)。但它的缺點(diǎn)是計(jì)算資源需求高,模型參數(shù)多,部署在資源受限的環(huán)境中可能會(huì)有困難。
(十四)CLIP 和 BLIP
CLIP 和 BLIP 是現(xiàn)代多模態(tài)模型的代表,它們將文本和視覺(jué)數(shù)據(jù)結(jié)合起來(lái),為涉及語(yǔ)言和圖像的任務(wù)提供了強(qiáng)大的支持。這些模型在圖像搜索、圖像描述和視覺(jué)問(wèn)答等應(yīng)用中發(fā)揮著重要作用。
CLIP 通過(guò)在大規(guī)模圖像-文本對(duì)數(shù)據(jù)集上進(jìn)行對(duì)比學(xué)習(xí),將圖像嵌入和對(duì)應(yīng)的文本嵌入對(duì)齊到一個(gè)共享的向量空間中。而 BLIP 則通過(guò)引導(dǎo)式訓(xùn)練方法進(jìn)一步優(yōu)化語(yǔ)言和視覺(jué)之間的對(duì)齊。
from transformers import CLIPProcessor, CLIPModel
from PIL import Image
import torch
import requests
# 加載模型和處理器
clip_model_name = "openai/clip-vit-base-patch32"
clip_model = CLIPModel.from_pretrained(clip_model_name).to(device)
clip_processor = CLIPProcessor.from_pretrained(clip_model_name)
# 加載示例圖像和文本
image_url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/datasets/cat_style_layout.png"
image = Image.open(requests.get(image_url, stream=True).raw).convert("RGB")
text = "a cute puppy"
# 預(yù)處理輸入
inputs = clip_processor(text=[text], images=image, return_tensors="pt", padding=True).to(device)
# 獲取文本和圖像嵌入
with torch.no_grad():
    text_embeddings = clip_model.get_text_features(input_ids=inputs["input_ids"])
    image_embeddings = clip_model.get_image_features(pixel_values=inputs["pixel_values"])
# 歸一化嵌入(可選)
text_embeddings = text_embeddings / text_embeddings.norm(dim=-1, keepdim=True)
image_embeddings = image_embeddings / image_embeddings.norm(dim=-1, keepdim=True)
print("Text Embedding Shape (CLIP):", text_embeddings.shape)
print("Image Embedding Shape (CLIP):", image_embeddings.shape)輸出:
Text Embedding Shape (CLIP): torch.Size([1, 512])
Image Embedding Shape (CLIP): torch.Size([1, 512])CLIP 和 BLIP 的優(yōu)點(diǎn)在于它們能夠提供跨模態(tài)的強(qiáng)大表示,并且在多模態(tài)任務(wù)中表現(xiàn)出色。但它們的缺點(diǎn)是訓(xùn)練需要大量的配對(duì)數(shù)據(jù),并且計(jì)算資源需求極高。
四、綜合對(duì)比
序號(hào)  | 嵌入方法  | 類型  | 模型架構(gòu)/方法  | 常見(jiàn)用途  | 
1  | Count Vectorizer  | 無(wú)上下文依賴,無(wú)機(jī)器學(xué)習(xí)  | 基于計(jì)數(shù)(詞袋模型)  | 搜索、聊天機(jī)器人、語(yǔ)義相似性中的句子嵌入  | 
2  | One-Hot Encoding  | 無(wú)上下文依賴,無(wú)機(jī)器學(xué)習(xí)  | 手動(dòng)編碼  | 基線模型、基于規(guī)則的系統(tǒng)  | 
3  | TF-IDF  | 無(wú)上下文依賴,無(wú)機(jī)器學(xué)習(xí)  | 計(jì)數(shù) + 逆文檔頻率  | 文檔排名、文本相似性、關(guān)鍵詞提取  | 
4  | Okapi BM25  | 無(wú)上下文依賴,統(tǒng)計(jì)排名  | 概率信息檢索模型  | 搜索引擎、信息檢索  | 
5  | Word2Vec(CBOW、SG)  | 無(wú)上下文依賴,基于機(jī)器學(xué)習(xí)  | 淺層神經(jīng)網(wǎng)絡(luò)  | 情感分析、單詞相似性、NLP 流水線  | 
6  | GloVe  | 無(wú)上下文依賴,基于機(jī)器學(xué)習(xí)  | 全局共現(xiàn)矩陣 + 機(jī)器學(xué)習(xí)  | 單詞相似性、嵌入初始化  | 
7  | FastText  | 無(wú)上下文依賴,基于機(jī)器學(xué)習(xí)  | Word2Vec + 子詞嵌入  | 豐富的形態(tài)語(yǔ)言、處理未登錄詞  | 
8  | Doc2Vec  | 無(wú)上下文依賴,基于機(jī)器學(xué)習(xí)  | Word2Vec 的文檔擴(kuò)展  | 文檔分類、聚類  | 
9  | InferSent  | 有上下文依賴,基于 RNN  | 帶監(jiān)督學(xué)習(xí)的雙向 LSTM  | 語(yǔ)義相似性、自然語(yǔ)言推理任務(wù)  | 
10  | Universal Sentence Encoder  | 有上下文依賴,基于 Transformer  | Transformer / 深度平均網(wǎng)絡(luò)(DAN)  | 搜索、聊天機(jī)器人、語(yǔ)義相似性中的句子嵌入  | 
11  | Node2Vec  | 基于圖的嵌入  | 隨機(jī)游走 + Skipgram  | 圖表示、推薦系統(tǒng)、鏈接預(yù)測(cè)  | 
12  | ELMo  | 有上下文依賴,基于 RNN  | 雙向 LSTM  | 命名實(shí)體識(shí)別、問(wèn)答、共指消解  | 
13  | BERT 及其變體  | 有上下文依賴,基于 Transformer  | 問(wèn)答、情感分析、總結(jié)、語(yǔ)義搜索  | 問(wèn)答、情感分析、總結(jié)、語(yǔ)義搜索  | 
14  | CLIP  | 多模態(tài),基于 Transformer  | 視覺(jué) + 文本編碼器(對(duì)比學(xué)習(xí))  | 圖像描述、跨模態(tài)搜索、文本到圖像檢索  | 
15  | BLIP  | 多模態(tài),基于 Transformer  | 視覺(jué) - 語(yǔ)言預(yù)訓(xùn)練(VLP)  | 圖像描述、視覺(jué)問(wèn)答(VQA)  | 
五、總結(jié)與展望
從基礎(chǔ)的計(jì)數(shù)方法到如今的多模態(tài)深度學(xué)習(xí)模型,嵌入技術(shù)的演進(jìn)歷程充滿了創(chuàng)新和突破。每一種方法都有其獨(dú)特的優(yōu)勢(shì)和局限性,它們?cè)诓煌娜蝿?wù)和場(chǎng)景中發(fā)揮著重要作用。
在實(shí)際應(yīng)用中,選擇合適的嵌入技術(shù)至關(guān)重要。如果你正在構(gòu)建一個(gè)簡(jiǎn)單的聊天機(jī)器人,計(jì)數(shù)向量器或 TF-IDF 可能就足夠了;如果你需要處理復(fù)雜的語(yǔ)義任務(wù),BERT 或其變體可能是更好的選擇;而如果你需要處理多模態(tài)數(shù)據(jù),CLIP 和 BLIP 則是不可或缺的工具。
隨著技術(shù)的不斷發(fā)展,嵌入技術(shù)也在不斷進(jìn)化。未來(lái),我們可以期待更高效、更智能的嵌入模型出現(xiàn),它們將能夠更好地理解和處理人類語(yǔ)言,為自然語(yǔ)言處理領(lǐng)域帶來(lái)更多的可能性。
在這個(gè)充滿挑戰(zhàn)和機(jī)遇的時(shí)代,讓我們一起探索嵌入技術(shù)的無(wú)限可能,用向量的力量點(diǎn)亮語(yǔ)言智能的未來(lái)!
本文轉(zhuǎn)載自公眾號(hào)Halo咯咯 作者:基咯咯
原文鏈接:??https://mp.weixin.qq.com/s/3PQcxLgkri4zYqDtA8YxIg??


















