Keras深度學習——使用skip-gram和CBOW模型構建單詞向量
theme: hydrogen
持續創作,加速成長!這是我參與「掘金日新計劃 · 6 月更文挑戰」的第29天,點選檢視活動詳情
skip-gram 和 CBOW 模型
本節中,使用連續單詞袋 (Continuous Bag of Words
, CBOW
) 模型構建單詞向量,以 “I love watching movie
” 為例。CBOW
模型處理此語句的方式如下:
- 使用一個尺寸為 1
的特定視窗
- 通過指定視窗大小,也表示指定了在給定單詞的右側和左側將考慮的單詞數
- 給定視窗大小 1
,則輸入和輸出單詞如下所示:
輸入單詞 | 輸出單詞 | | ------------- | ---------- | | {I, watching} | {love} | | {love, movie} | {watching}
- 構建單詞向量的另一種方法是使用
skip-gram
模型,其步驟與CBOW
步驟恰好相反,如下所示:
輸出單詞 | 輸入單詞 | | ---------- | ------------- | | {love} | {I, watching} | | {watching} | {love, movie}
但無論是 skip-gram
模型還是 CBOW
模型,得到單詞在隱藏層的編碼向量的方法都與在 <測量詞向量之間的相似度>中介紹的方法相同。
使用 skip-gram 和 CBOW 模型構建單詞向量
瞭解了單詞向量構建的原理後,我們使用 skip-gram
和 CBOW
模型構建單詞向量。為了構建模型,我們將使用航空公司的情感資料集,其中給出了推文文字,並提供了與推文相對應的情感。
我們所用的 Twitter US Airline Sentiment 資料來源於 Crowdflower’s Data for Everyone
,其中包含了美國各大航空公司 Twitter
評論的情緒分析資料,該資料集收集了自 2015
年 2
月以來的資料,並推文進行分類,包括正面、負面和中立,資料集還對負面評價原因的進行分類,例如“航班遲到”或“服務粗魯”等。可以在 Kaggle 上獲取格式化資料集。可以看到,資料集中包含每條推文對六家美國航空公司的評價情緒是正面的、中性的還是負面的:
接下來,我們利用 gensim
庫生成單詞向量。如果未安裝此庫,首先使用 pip
命令進行安裝:
python
pip install gensim
匯入相關庫,並讀取航空公司 Twitter
情感資料集,其中包含與航空公司及其相應情感相關的評論內容:
```python
import gensim
import pandas as pd
data = pd.read_csv('archive/Tweets.csv')
print(data.head())
預覽資料集,如下所示:
shell
tweet_id airline_sentiment ... tweet_location user_timezone
0 570306133677760513 neutral ... NaN Eastern Time (US & Canada)
1 570301130888122368 positive ... NaN Pacific Time (US & Canada)
2 570301083672813571 neutral ... Lets Play Central Time (US & Canada)
3 570301031407624196 negative ... NaN Pacific Time (US & Canada)
4 570300817074462722 negative ... NaN Pacific Time (US & Canada)
對讀取的文字進行預處理,執行以下操作:
- 將每個單詞都轉換為小寫
- 刪除標點符號,僅保留數字和字母
- 刪除停用詞
python
import re
import nltk
from nltk.corpus import stopwords
stop = set(stopwords.words('english'))
def preprocess(text): text = text.lower() text = re.sub('[^0-9a-zA-Z]+', ' ', text) words = text.split() words2 = [i for i in words if i not in stop] words3 = ' '.join(words2) return words3
data ['text'] = data['text'].apply(preprocess)
將句子拆分為分詞 (`token`) 列表,以便隨後將其傳遞給 `gensim`,打印出第一句的分詞結果:
python
print(data['text'][0].split())
以上程式碼將句子按空格分隔,輸出如下所示:
shell
['virginamerica', 'dhepburn', 'said']
遍歷所有文字,並將分詞結果新增到列表中,如下所示:
python
list_words = []
for i in range(len(data)):
list_words.append(data['text'][i].split())
檢查 `list_words` 列表中的前 `5` 個分詞結果:
python
print(list_words[:5])
前三個句子的列表如下:
shell
[['virginamerica', 'dhepburn', 'said'], ['virginamerica', 'plus', 'added', 'commercials', 'experience', 'tacky'], ['virginamerica', 'today', 'must', 'mean', 'need', 'take', 'another', 'trip'], ['virginamerica', 'really', 'aggressive', 'blast', 'obnoxious', 'entertainment', 'guests', 'faces', 'amp', 'little', 'recourse'], ['virginamerica', 'really', 'big', 'bad', 'thing']]
```
接下來,構建 Word2Vec
模型,定義單詞向量大小、要檢視的上下文視窗大小,以及要考慮單詞的最小數量,以使其具有被編碼為向量的資格,如下所示:
python
from gensim.models import Word2Vec
model = Word2Vec(vector_size=50, window=5, min_count=30, sg=0, alpha=0.025)
在以上程式碼中,vector_size
表示單詞向量的維度,window
表示要考慮的單詞的上下文大小,min_count
指定要考慮的單詞的最小頻率,sg
表示採用的編碼模型為使用 skip-gram
(sg = 1
) 或CBOW
(sg = 0
),alpha
表示模型的學習率。
定義模型後,傳遞 list_words
列表以構建詞彙表,如下所示:
python
model.build_vocab(list_words)
構建詞彙表後,可以找到在整個語料庫中過濾掉少於 30
次的單詞後剩下的最終單詞,如下所示:
python
print(model.wv.index_to_key)
輸出結果如下所示:
python
['united', 'flight', 'usairways', 'americanair', 'southwestair', 'jetblue', 'get', 'co', 'http', 'thanks', 'cancelled', 'service'...]
通過指定輸入資料和要訓練的 epoch
數來訓練模型,如下所示:
python
model.train(list_words, total_examples=model.corpus_count, epochs=200)
在 train
方法中,list_words
列表包含了所有輸入分詞列表,total_examples
表示要考慮的分詞列表總數,epochs
是要執行的 epoch
數。
此外,我們也可以通過在 Word2Vec
方法中使用 iter
引數來指定訓練模型 epoch
數,如下所示:
python
model.train(list_words, total_examples=model.corpus_count, iter=200)
訓練完成後,可以提取給定單詞的單詞編碼向量,如下所示:
python
print(model.wv.get_vector('day'))
對應於單詞 “day
” 的單詞向量如下:
shell
[-7.04173684e-01 -5.72516641e-04 -4.10758048e-01 1.84985828e+00
-1.15435565e+00 -3.16574931e-01 -5.16422510e-01 2.28969193e+00
1.91934001e+00 -1.18813097e+00 -2.94377494e+00 9.51616392e-02
-8.44838619e-02 -7.18616024e-02 -1.14567673e+00 6.77643716e-01
1.61244774e+00 1.13801873e+00 -4.42255348e-01 1.07233655e+00
1.16125333e+00 2.79197335e+00 2.07479763e+00 -1.21500826e+00
-9.10723388e-01 4.01439548e-01 -1.65728176e+00 -1.75016761e-01
-9.88252282e-01 -3.28201318e+00 -1.22636998e+00 -6.90755486e-01
-1.92077053e+00 1.75805852e-01 -2.02697372e+00 -9.76259783e-02
1.68322384e+00 -1.77150667e+00 3.45278442e-01 -2.07601279e-01
-1.24472260e+00 7.59482205e-01 7.28200555e-01 -2.57247114e+00
-1.04648125e+00 2.81359744e+00 -2.41322589e+00 -1.54843581e+00
2.38953400e+00 -1.05442435e-01]
兩個詞之間的相似度可以使用 similarity
計算如下:
```python
print(model.wv.similarity('day', 'week'))
輸出結果
0.53549874
同樣,我們可以計算與給定單詞最相似的單詞,以及它們之間的相似度:
python
print(model.wv.most_similar('day'))
與單詞 “`day`” 最相似的單詞列印如下:
shell
[('days', 0.6186136603355408), ('week', 0.5354987382888794), ('trip', 0.5184321999549866), ('time', 0.4801279306411743), ('destination', 0.4254339635372162), ('hrs', 0.4112888276576996), ('night', 0.41115307807922363), ('hours', 0.40979164838790894), ('year', 0.3568463921546936), ('sat', 0.3532494604587555)]
```
儘管這些相似度看起來很低,並且一些相似的單詞並沒有被準確的識別,這是由於該資料庫中的資料量並不足以得到更精確的結果,可以在一個更大的資料集上進行訓練。
通過將 sg
引數的值替換為 1
,則可以使用 skip-gram
模型獲得單詞低維向量:
python
model = Word2Vec(vector_size=50, window=5, min_count=30, sg=1)
- OpenCV使用顏色進行膚色檢測
- Keras深度學習——構建電影推薦系統
- PyTorch張量操作詳解
- OpenCV直方圖的比較
- Python 常用字串操作
- 使用 dlib 進行人臉識別
- OpenCV 人臉檢測詳解(僅需2行程式碼學會人臉檢測)
- Keras深度學習——使用fastText構建單詞向量
- Keras深度學習——使用skip-gram和CBOW模型構建單詞向量
- Keras深度學習——從零開始構建單詞向量
- Keras深度學習——生成對抗網路
- Keras深度學習——建立自定義目標檢測資料集
- PyTorch強化學習——基於值迭代的強化學習演算法
- PyTorch強化學習——模擬FrozenLake環境
- PyTorch強化學習——策略評估
- PyTorch強化學習——馬爾科夫決策過程
- Keras深度學習——DeepDream演算法生成影象
- Keras深度學習——使用對抗攻擊生成可欺騙神經網路的影象
- PyTorch強化學習——策略梯度演算法
- Keras深度學習——交通標誌識別