一烛恤、Word2Vec算法
簡單講就是通過學習文本然后用詞向量的方式表征詞的語義信息拧烦,即通過
把原先詞所在空間映射到一個新的空間中去,使得語義上相似的單詞在該空間內距離相近莉擒。以傳統(tǒng)神經網絡為基礎的神經概率語言模型酿炸,缺點主要是計算量太大,集中體現(xiàn)在:隱層和輸出層之間的矩陣運算和輸出層上的
歸一化運算上涨冀。因此
就是針對這兩點來優(yōu)化神經概率語言模型的填硕。 中兩個重要的模型是:
模型和
模型。
1.
模型
CBOW(continue bag-of-words) 包括三層結構:輸入層鹿鳖、投影層和輸出層扁眯。
輸入層:包含2c個詞的詞向量。
投影層:對輸入的2c個詞向量進行累加操作翅帜。
輸出層:輸出層對應一顆哈夫曼(Huffman)樹姻檀,它是以語料中出現(xiàn)過的詞當葉子節(jié)點,以各詞在語料庫中出現(xiàn)的次數(shù)當權值構造而成涝滴。在這顆樹中绣版,葉子結點共
由
其中表示路徑
中第
個節(jié)點對應的編碼(根節(jié)點不對應編碼)弧械;
表示路徑
中第
個非葉子節(jié)點對應的向量八酒;
表示
中所有詞向量的疊加。
其中梦谜。通過對數(shù)極大似然化處理可得CBOW模型的目標函數(shù)為:
word2vec極大化目標函數(shù)使用的算法是隨機梯度上升法丘跌,首先考慮對
的梯度計算:
則的更新公式為:
然后考慮對
的梯度計算:
觀察到中
和
具有對稱性,word2vec直接取下式方式來更新
:
2.
模型
模型也包括輸入層唁桩、投
影層和輸出層闭树。
輸入層:只含有當前樣本的中心詞
投影層:由于為恒等投影荒澡,因此該層可有可無报辱;
輸出層:也為一棵哈夫曼樹。
在
同樣由的思想米奸,可得:
通過極大似然化處理可得模型的目標函數(shù)為:
考慮對
的梯度:
則的更新公式為:
再考慮對
的梯度:
則更新公式為:
二昼接、算法實現(xiàn)
本次所用數(shù)據(jù)來自一家英國在線零售商店2010年1月12日至2011年12月9的全部交易數(shù)據(jù),數(shù)據(jù)規(guī)模為悴晰。下載地址慢睡,https://archive.ics.uci.edu/ml/datasets/Online+Retail ,字段描述如下:
- InvoiceNo:發(fā)票編號铡溪。 定類數(shù)據(jù)漂辐,為每個事務唯一分配的6位整數(shù)。 如果此代碼以字母'c'開頭棕硫,則表示取消髓涯。
- StockCode:產品(項目)代碼。 定類數(shù)據(jù)哈扮,為每個不同的產品唯一分配的5位整數(shù)纬纪。
- Description:產品(項目)名稱。定類數(shù)據(jù)滑肉。
- Quantity:每筆交易的每件產品(項目)的數(shù)量育八。 數(shù)字。
- InvoiceDate:Invoice日期和時間赦邻。 數(shù)字,生成每個事務的日期和時間实檀。
- UnitPrice:單價惶洲。 數(shù)字按声,英鎊單位產品價格。
- CustomerID:客戶編號恬吕。 定類數(shù)據(jù)签则,為每個客戶唯一分配的5位整數(shù)。
- Country:國家名稱铐料。 定類數(shù)據(jù)渐裂,每個客戶所在國家/地區(qū)的名稱。
1. 庫函數(shù)钠惩、數(shù)據(jù)讀入以及刪除缺失值
import numpy as np
import pandas as pd
import random
from tqdm import tqdm
from gensim.models import Word2Vec
import matplotlib.pyplot as plt
import umap
data = pd.read_excel('Online Retail.xlsx')
data.isnull().sum()
data.dropna(inplace=True)
2. 找到用戶的個數(shù)及其列表柒凉,并隨機打亂,可知用戶共4372個
data['StockCode'] = data['StockCode'].astype(str)
customers = data['CustomerID'].unique().tolist()
random.shuffle(customers)
train_customers = [customers[i] for i in range(round(0.9*len(customers)))]
train_data = data[data['CustomerID'].isin(train_customers)]
validation_data = data[~data['CustomerID'].isin(train_customers)]
3. 劃分訓練集和驗證集并加載
train_customers = [customers[i] for i in range(round(0.9*len(customers)))]
train_data = data[data['CustomerID'].isin(train_customers)]
validation_data = data[~data['CustomerID'].isin(train_customers)]
train_purchases = [] #訓練集用戶購買記錄
for i in tqdm(train_customers):
temp = train_data[train_data['CustomerID']==i]['StockCode'].tolist()
train_purchases.append(temp)
val_purchases = [] #驗證集用戶購買記錄
for i in tqdm(validation_data['CustomerID'].unique()):
temp = validation_data[validation_data['CustomerID']==i]['StockCode'].tolist()
val_purchases.append(temp)
100%|██████████| 3935/3935 [00:04<00:00, 974.74it/s]
100%|██████████| 437/437 [00:00<00:00, 1613.25it/s]
4.
模型加載及初始化
model = Word2Vec(window = 10,sg = 1, hs = 0, negative = 10, alpha = 0.03, min_alpha = 0.0007, seed = 14)
model.build_vocab(train_purchases,progress_per = 200)
model.train(train_purchases, total_examples = model.corpus_count, epochs = 10, report_delay = 1)
model.init_sims(replace=True)
X = model[model.wv.vocab]
5. 模型向量可視化
cluster_embedding = umap.UMAP(n_neighbors=30, min_dist=0.0, n_components=2, random_state=42).fit_transform(X)
plt.figure(1)
plt.scatter(cluster_embedding[:,0], cluster_embedding[:,1], s=3, cmap='Spectral')
6. 創(chuàng)建產品股票代碼及描述的字典并刪除重復項
products = train_data[["StockCode", "Description"]]
products.drop_duplicates(inplace=True, subset='StockCode', keep='last')
products_dict = products.groupby('StockCode')['Description'].apply(list).to_dict()
In [8]: products_dict['21931']
Out[8]: ['JUMBO STORAGE BAG SUKI']
7. 以產品向量作為輸入篓跛,并返回6個相似產品
def similar_products(v,n=6):
ms = model.wv.similar_by_vector(v,topn = n+1)[1:]
new_ms = []
for j in ms:
pair = (products_dict[j[0]][0],j[1])
new_ms.append(pair)
return new_ms
similar_products(model['84406B'])
In [9]: similar_products(model['21931'])
Out[9]:
[('JUMBO BAG STRAWBERRY', 0.8357644081115723),
('JUMBO BAG OWLS', 0.8068020343780518),
('JUMBO BAG BAROQUE BLACK WHITE', 0.7999265193939209),
('JUMBO BAG RED RETROSPOT', 0.7874696254730225),
('JUMBO BAG PINK POLKADOT', 0.7594423294067383),
('JUMBO STORAGE BAG SKULLS', 0.758986234664917)]
8. 基于多次購買的平均值推薦相似產品
def aggregate_vectors(products):
product_vec = []
for i in products:
product_vec.append(model[i])
return np.mean(product_vec,axis=0)
aggregate_vectors(val_purchases[1]).shape
similar_products(aggregate_vectors(val_purchases[1]))
similar_products(aggregate_vectors(val_purchases[1][-10:]))
In [13]: similar_products(aggregate_vectors(val_purchases[1]))
Out[13]:
[('LUNCH BAG RED RETROSPOT', 0.6403661370277405),
('ALARM CLOCK BAKELIKE RED ', 0.638660728931427),
('RED RETROSPOT PICNIC BAG', 0.6361196637153625),
('JUMBO BAG RED RETROSPOT', 0.6360040903091431),
('SET/5 RED RETROSPOT LID GLASS BOWLS', 0.6345535516738892),
('ALARM CLOCK BAKELIKE PINK', 0.6296969056129456)]
In [14]: similar_products(aggregate_vectors(val_purchases[1][-10:]))
Out[14]:
[('ROUND SNACK BOXES SET OF 4 FRUITS ', 0.7854548692703247),
('LUNCH BOX WITH CUTLERY RETROSPOT ', 0.6739486455917358),
('SET OF 3 BUTTERFLY COOKIE CUTTERS', 0.6696499586105347),
('SET OF 3 REGENCY CAKE TINS', 0.6598889827728271),
('PICNIC BOXES SET OF 3 RETROSPOT ', 0.6580283641815186),
('POSTAGE', 0.6528887748718262)]
參考資料
[1]. 推薦系統(tǒng)與深度學習. 黃昕等. 清華大學出版社. 2019.
[2]. 美團機器學習實踐. 美團算法團隊. 人民郵電出版社. 2018.
[3]. 推薦系統(tǒng)算法實踐. 黃美靈. 電子工業(yè)出版社. 2019.
[4]. 推薦系統(tǒng)算法. 項亮. 人民郵電出版社. 2012.
[5]. https://github.com/smrutiranjan097/Building-a-Recommendation-System-using-Word2vec
[6]. https://github.com/shoreyarchit/Movie-Recommendation-System
[7]. https://github.com/yhangf/ML-NOTE
夜雨翦春韭膝捞,新炊間黃粱±⒐担——杜甫《贈衛(wèi)八處士》