【自然語言處理 — 概念篇】 來認識一下詞向量(Word Embedding or Word Vector)吧

閱讀時間約 17 分鐘
詞跟詞之間的距離有多近呢?
如果一個詞在相對的空間內都佔有一席之地的話, 試想, 每個詞都是一個獨立的個體, 就如同我們人類一般, 相同興趣的、相同頻率的就容易被歸納在一起,某些詞可能是相近的意思, 因此我們只需要給每個詞標上一個向量值, 並進行統計,而這些詞在這批資料集之中所佔的位置依照距離都能夠歸納出相似的詞, 而有了這樣的關係之後, 我們就能夠進行語義搜索、情感分析、語言生成、文本分類...等, 原來一個簡單的「詞」可以延伸出這麼多的應用。
那「詞向量」主要就是將「詞」本身的資訊進行數值化, 而後續的NLP進階應用就可以透過這些資訊進行, 以下例子會從如何訓練詞向量逐步介紹到如何利用詞向量模型來找出相似的詞, 並以圖表化進行呈現。

安裝套件

  • gensim: 文檔相似度計算和詞向量表示等自然語言處理(NLP)任務的Python庫。
  • jieba: 將中文語句切成最小單位的詞。
  • matplotlib: 繪製向量圖表。
!pip install gensim

!pip install jieba

!pip install matplotlib

定義中文語句並進行斷詞

這邊我們就設計個4句的範本進行後續的向量處理。
由於NLP世界中最小的單位是「詞」, 因此我們就要藉由jieba這套斷詞工具幫我們預先進行斷詞。
import jieba
sentences = [
list(jieba.cut('我喜歡吃蘋果')),
list(jieba.cut('蘋果很好吃')),
list(jieba.cut('水果是健康的')),
list(jieba.cut('梨子也很好吃')),
list(jieba.cut('我也喜歡吃柳丁')),
list(jieba.cut('蘋果柳丁都是一種水果')),
list(jieba.cut('蘋果是一種又香又甜的水果')),
list(jieba.cut('梨子跟柳丁也是一種又香又甜的水果')),
]

sentences
[['我', '喜歡', '吃', '蘋果'],
['蘋果', '很', '好吃'],
['水果', '是', '健康', '的'],
['梨子', '也', '很', '好吃'],
['我', '也', '喜歡', '吃', '柳丁'],
['蘋果', '柳丁', '都', '是', '一種', '水果'],
['蘋果', '是', '一種', '又', '香', '又', '甜', '的', '水果'],
['梨子', '跟', '柳丁', '也', '是', '一種', '又', '香', '又', '甜', '的', '水果']]

訓練詞向量模型並取得詞向量

所謂的「詞向量」也稱為詞嵌入(Word embeddings), 當我們處理文本時,詞向量就是一種將詞語轉換為數字表示的方法。這些數字表示的向量具有特定的性質,能夠表示詞語之間的語義和關聯性。
總而言之,詞向量是一種將詞語轉換為數字向量表示的方法,能夠捕捉詞語之間的語義相似性,並在文本處理任務中發揮重要作用。
底下會得到一堆向量數值,嗯..., 看不懂, 怎麼辦? 沒關係, 圖表是我們最大的幫手, 下一步我們就將這些向量值跟詞進行圖表的繪製吧!
from gensim.models import Word2Vec

# 訓練詞向量模型
model = Word2Vec(sentences, window=5, min_count=1, workers=4)

# 獲取所有詞
vocab = model.wv.index_to_key

# 獲取所有詞向量
vectors = model.wv[vocab]

vectors
array([[-5.3630857e-04,  2.3646720e-04,  5.1041231e-03, ...,
-7.0426278e-03, 9.0159255e-04, 6.3935029e-03],
[-8.6233551e-03, 3.6638153e-03, 5.1871063e-03, ...,
-2.3919728e-03, -9.5016956e-03, 4.5148465e-03],
[ 8.8638728e-05, 3.0799997e-03, -6.8148547e-03, ...,
5.1378825e-04, 8.2169194e-03, -7.0118154e-03],
...,
[ 1.3001668e-03, -9.8043028e-03, 4.5877625e-03, ...,
-2.5875687e-03, -7.7571664e-03, 4.1926014e-03],
[ 1.8002307e-03, 7.0460914e-03, 2.9446983e-03, ...,
-1.8595541e-03, 3.6117458e-03, -7.0364270e-03],
[ 9.7315907e-03, -9.7780135e-03, -6.4999200e-03, ...,
-2.7000697e-03, 3.8249956e-03, 3.3858197e-04]], dtype=float32)

下載中文字型讓圖表可以顯示中文

import matplotlib as mpl
import matplotlib.font_manager as fm
import matplotlib.pyplot as plt

# 下載繁體中文字型
!wget -O SourceHanSerifTW-VF.ttf https://github.com/adobe-fonts/source-han-serif/raw/release/Variable/TTF/Subset/SourceHanSerifTW-VF.ttf

# 加入字型檔
fm.fontManager.addfont('SourceHanSerifTW-VF.ttf')

# 設定字型
#
mpl.rc('font', family='Source Han Serif TW VF')

針對訓練完成的模型繪製二維向量圖

在前面我們已經展示了word2vec的訓練方法, 訓練完畢之後我們應該要如何觀察這些詞向量分佈位置是不是我們所預期的, 但礙於高維度對我們人類來說難以理解,因此可以透過降維的方式繪製。
t-SNE(t-Distributed Stochastic Neighbor Embedding)是一種降維算法, 用於將高維數據映射到低維空間, 通常用於視覺化高維數據。
可以看到繪圖後的結果, 本應該相似的蘋果、梨子...等水果應該距離要相近的, 但我們的訓練樣本數實在太少了, 這樣的分佈狀況會有點失真, 這邊只是為了以圖來呈現我們的詞向量, 真正可用的模型是需要大量資料來進行訓練的, 以下我們也會使用已訓練完成的基礎模型來進行相似詞的搜尋。
import matplotlib.pyplot as plt


# 將詞向量降維為2D
from sklearn.manifold import TSNE
# 使用 t-SNE 進行詞向量降維
# perplexity 是用於控制降維後的分佈緊密度的參數。
tsne = TSNE(n_components=2, perplexity=10)
vectors_2d = tsne.fit_transform(vectors)

# 繪製散點圖
plt.scatter(vectors_2d[:, 0], vectors_2d[:, 1])

# 將詞語標籤添加到對應的點上
for i, word in enumerate(vocab):
plt.annotate(word, xy=(vectors_2d[i, 0], vectors_2d[i, 1]), fontsize=8)


# 顯示圖形
plt.show()

下載預訓練模型

上面我可以看到由於資料量不足, 導致訓練出來的模型沒有參考價值, 因此我們就使用別人訓練好的中文模型來進行接下來下的實驗吧。
這次使用的模型是fasttext的wiki.zh.vec, 如果有其他語言需求的朋友可以到這裡進行下載:
import urllib.request

url = 'https://dl.fbaipublicfiles.com/fasttext/vectors-wiki/wiki.zh.vec'

urllib.request.urlretrieve(url, './wiki.zh.vec')

載入預訓練模型

載入模型之後, 我們可以對某個詞取出向量值。
from gensim.models import KeyedVectors

# 載入中文詞向量模型
vector_file_path = './wiki.zh.vec'
wiki_model = KeyedVectors.load_word2vec_format(vector_file_path, binary=False)

# 使用詞向量模型進行相關操作
# 例如,取得詞向量
wiki_vec = wiki_model['詞']

wiki_vec

找出「詞」的相似詞並以圖來分析

  1. 找相似詞。
  2. 降維度。
  3. 縮放向量值: 1 ~ -1之間。
  4. 設定門檻值為1.0, 並且將距離在1.0以內的相似詞連接起來。
  5. 繪製圖表進行分析。
import matplotlib.pyplot as plt
import numpy as np
from sklearn.manifold import TSNE
from sklearn.preprocessing import MinMaxScaler

input_word = '積極'

# 輸入詞的相似詞及向量資訊
similar_words = wiki_model.most_similar(input_word, topn=20)
similar_words, scores = zip(*similar_words)
similar_vectors = [wiki_model[x] for x in similar_words]

# 將「輸入詞」與「相似詞」總和在一起, 統一進行以下的降維, 並將「輸入詞」擺放於第一位以利識別
words = [input_word] + list(similar_words)
input_vector = wiki_model[input_word]
vectors = np.vstack(([input_vector], similar_vectors))


# 使用 t-SNE 降維
tsne = TSNE(n_components=2, perplexity=10)
vectors_2d = tsne.fit_transform(vectors)

# 縮放向量值到範圍 [-1, 1]
scaler = MinMaxScaler(feature_range=(-1, 1))
vectors_2d = scaler.fit_transform(vectors_2d)

# 繪製散點圖
plt.figure(figsize=(10, 6))

# 繪製輸入詞本身的點
plt.scatter(vectors_2d[0, 0], vectors_2d[0, 1], color='red', label=input_word)

# 將輸入詞標籤添加到對應的點上
plt.annotate(input_word, xy=(vectors_2d[0, 0], vectors_2d[0, 1]), fontsize=16)

# 繪製相似詞的點
plt.scatter(vectors_2d[1:, 0], vectors_2d[1:, 1])

# 將相似詞標籤添加到對應的點上
for i, x in enumerate(similar_words[1:]):
plt.annotate(x, xy=(vectors_2d[i+1, 0], vectors_2d[i+1, 1]), fontsize=16)

threshold = 1.0
# 繪製連線
for i in range(1, len(vectors_2d)):
distance = np.linalg.norm(vectors_2d[0, :] - vectors_2d[i, :])
if distance <= threshold:
plt.plot([vectors_2d[0, 0], vectors_2d[i, 0]], [vectors_2d[0, 1], vectors_2d[i, 1]], color='gray', linestyle='dotted')
midpoint = (vectors_2d[0, :] + vectors_2d[i, :]) / 2
plt.annotate(f'{distance:.2f}', xy=midpoint, ha='center', va='center')

plt.xlabel('x')
plt.ylabel('y')
plt.title(f'詞 "{input_word}" 的相似詞')
plt.legend()
plt.tight_layout()
plt.show()
今天的範例都在這裡「📦 wordvector.ipynb」歡迎自行取用。

結語

將向量透過圖表化的方式可以幫助我們更容易了解到NLP的基礎處理方式, 一步步拆解之後, 我們就不會對這種技術感到害怕了, 整個操作下來感覺科學家的智慧真的是令人讚嘆, 能夠將我們人類的語句想辦法讓機器可以理解甚至進行推理, 就以情緒分類來說, 訓練的過程中考慮了詞彙在上下文中的出現頻率和分佈情況, 並且在詞向量空間中可能會形成特定的集群或分布, 透過這樣的觀察就能夠推測出可能的情緒。
------------------------------------------------------------------------------------------------
喜歡撰寫文章的你,不妨來了解一下:
歡迎加入一起練習寫作,賺取知識!
為什麼會看到廣告
95會員
234內容數
哈囉,我是阿Han,是一位 👩‍💻 軟體研發工程師,喜歡閱讀、學習、撰寫文章及教學,擅長以圖代文,化繁為簡,除了幫助自己釐清思路之外,也希望藉由圖解的方式幫助大家共同學習,甚至手把手帶您設計出高品質的軟體產品。
留言0
查看全部
發表第一個留言支持創作者!
你可能也想看
LLM 001|大語言模型如何革新傳統的自然語言處理任務?大語言模型,例如OpenAI提供的ChatGPT,是過去幾年發展的深度神經網路模型,開啟自然語言處理的新紀元。
avatar
王啟樺
2024-04-23
【從規則到革新:3大進步展示了大語言模型在自然語言處理上的威力】對於熱衷於語言科技的你, 大語言模型(LLMs)在自然語言處理(NLP)領域的發展無疑是一個革命性的進展。 從傳統的規則系統到基於深度學習的方法, LLMs展現了在理解、生成和翻譯人類語言方面的巨大突破。 這不僅是技術上的飛躍, 更是開啟了新的應用和可能性。 下面將介紹這一變革帶來的三大
Thumbnail
avatar
王啟樺
2024-01-15
7 種 NLP 專案,讓你成為自然語言處理好手 (下)前一篇我們已經介紹了四個可以去完成的NLP專案, 7 種 NLP 專案,讓你成為自然語言處理好手 (上) 接下來我們繼續分享另外幾個很常使用的專案 機器翻譯 (Machine Translation)
Thumbnail
avatar
Kevin_malamute |凱文-馬拉穆
2023-11-14
7 種 NLP 專案,讓你成為自然語言處理好手 (上)自然語言處理(NLP)已經重新塑造我們與世界各地的資訊互動和機器溝通方式。NLP融合了電腦科學、語言學和人工智慧,致力於讓電腦能夠以反映人類認知的方式理解、解釋和生成人類語言。 對於寫程式的人而言,實戰勝過一切,透過實際參與NLP專案以獲得實務經驗,對於成為優秀的資料科學家或NLP工程師非常重
Thumbnail
avatar
Kevin_malamute |凱文-馬拉穆
2023-11-13
語言與智能的交融:探索自然語言處理(NLP)的奇蹟與挑戰自然語言處理(NLP)透過深度學習和大數據,讓電腦理解語言、實現對話、翻譯等功能。然而,NLP也面臨失業風險和數據偏見等挑戰。建立政策法規確保公平使用,關注倫理和法律,實現NLP的可持續發展。
Thumbnail
avatar
Victoria
2023-08-23
2022-23生成式ai浪潮,自然語言,與艾西莫夫式的昔時未來科幻想像(刊登於風傳媒,連結:www.storm.mg/article/4796622) 所以,很有意思地,為什麼在當今眾多發展的AI當中,竟然是由自然語言的大型語言模型,來讓人們驚覺有那麼一點通用人工智慧AGI的感覺和發展之可能方向。正是因為概念就藏在語言裡。
avatar
贖名人
2023-05-29
從入門到精通|訓練自然語言處理(NLP)應用中的語意分析模型自然語言處理(Natural Language Processing, NLP)是一個引人注目的領域,通過應用機器學習和人工智能技術,使機器能夠理解和處理人類的語言。其中,語意分析是NLP中一個重要的應用領域,它關注如何理解文本的意思和情感。
Thumbnail
avatar
嵐海智能
2023-05-19
ChatGPT:革命性的自然語言處理技術及其應用 Write with chatgpt探索 ChatGPT,這是一項尖端技術,利用自然語言處理提供複雜的回應並不斷學習和改進。了解 ChatGPT 的歷史、應用和對社會可能帶來的影響。ChatGPT 在醫療、金融、教育和娛樂等領域有廣泛的應用。探索這項技術在各個領域中的幫助方式。ChatGPT 有可能改變我們與技術和工具互動的方式。了解
Thumbnail
avatar
j172tw Blogz
2023-04-29
假如把智能合約看成文章: 探討自然語言處理辨識合約漏洞的可行性以太坊因為有了智能合約而獲得很大的便利性與彈性,智能合約的出現讓原本單純的金流交易功能延伸了許多的擴充功能。這使得合約的安全性受到重視。搭上近年熱門的AI風潮,NLP是一種可以檢測合約安全的新方法。
Thumbnail
avatar
這裡是阿原~~
2023-02-13