【週末AI課堂】理解詞嵌入(代碼篇)| 機器學習你會遇到的「坑」

AI課堂開講,就差你了!python


不少人說,看了再多的文章,但是沒有人手把手地教授,仍是很難真正地入門AI。爲了將AI知識體系以最簡單的方式呈現給你,從這個星期開始,芯君邀請AI專業人士開設「週末學習課堂」——每週就AI學習中的一個重點問題進行深度分析,課程會分爲理論篇和代碼篇,理論與實操,一個都不能少!網絡


來,退出讓你廢寢忘食的遊戲頁面,取消只有胡吃海塞的週末聚會吧。將來你與同齡人的差別,也許就從每週末的這堂AI課開啓了!app






image.png


咱們在上一節中已經看到,獲得詞向量的途徑是經過訓練神經網絡獲得,咱們最後須要的只是輸入層到投影層的權值矩陣,表明着詞向量。這樣作就意味着獲得的詞向量並非惟一的,它依賴着語料庫、神經網絡的結構、參數的設置等因素。那麼如何確保咱們獲得的是一個合理的詞向量,而非只是針對特定任務的呢?截至目前,這一問題咱們沒法獲得有效的保證,但能夠經過增長數據、充分挖掘數據間的關係來改善。ide


image.png

Word2Vec


一種改善的辦法就是,將本來的詞只與上文有關的機制改成與上下文都有關,反映到神經網絡上,原來的模型會把某個詞前面的N-1個詞做爲輸入,該詞做爲輸出。取而代之,咱們能夠選擇兩種機制:函數


• 一種是CBOW,它就是將先後N個詞做爲輸入,該詞做爲輸出。工具


• 一種是Skip-Gram,它是將某詞做爲輸入,其先後N個詞做爲輸出。學習


image.png


如圖,CBOW會image.png左右的兩個詞一塊兒做爲輸入,該詞做爲輸出來訓練網絡,Skip-gram則剛好反過來。字體


在實際訓練中,這兩項技術對於文本的處理有所不一樣。CBOW會把每一個詞做爲輸出,訓練時只須要作一次的BP(後向傳播),可是skip-gram輸出的最少也是兩個詞,咱們假設是K次,訓練時就須要作K次的BP,在遍歷相同長度的文本狀況下,訓練開銷更大。編碼


可是在skip-gram,每一個詞均可以接受來自於周圍詞的權重調整,這樣的調整使獲得的詞向量更準確。對於生僻詞的出現,CBOW使用生僻詞做爲輸出,去調整K個詞的詞向量時,比起其餘的高頻詞影響很小(被平均掉),使得生僻詞在訓練中不會起到很大做用。相反的,Skip-gram把生僻詞做爲輸入,能夠接受周圍詞的調整,是獨立於其餘詞進行訓練。結果就是,skip-gram會比CBOW對生僻詞的表現更好。spa


使用這些技術訓練出來的詞向量,會在語義上有着很是有趣的分佈,下面舉兩個例子:


image.png

如圖,king的詞向量與queen的詞向量的關係,和man與woman是類似的,這表明着詞向量表示了必定的語義關係,有:image.png。不只如此,在詞語的形式上,也有image.png也就是說,咱們在詞向量所張成的空間上,若是語言經過了相同形式的轉化,包括同義詞,反義詞,那麼咱們能夠用數值上的運算來表達這種轉化。


image.png

如圖,在英語和西班牙語上分別訓練詞向量,選取數字1,2,3,4,5,在他們各自的空間上利用主成分分析(PCA)降維,獲得的分佈幾乎是一致的,數字的使用在不一樣語言中是相似的,說明訓練獲得的詞向量包含了這一層關係。


image.png

使用詞向量


目前,各種語種的大規模訓練而來的詞向量已經很是成熟,咱們直接可使用,但比使用更重要的是,咱們基於語料庫如何獲得它們?在接下來的實踐中,爲方便,咱們會使用gensim庫和jieba分詞庫,對詞向量的訓練作一個簡單的示例,其中,可能須要一點點《射鵰英雄傳》的知識。


gensim是一個較爲高級的python庫,提供了語料處理工具,LSI,LDA等傳統方法,同時,它所內建的神經網絡並不包含隱層(若是咱們把embedding層不看做隱層的話),訓練速度會很是快,對電腦配置要求並不高,自從進入深度學習以後,這是不多見的能夠在我的筆記本上流暢運行的模型。


咱們從網上能夠很方便的下載到《射鵰英雄傳》這部小說,咱們基於這部小說將其簡單的分詞:

import jieba

with open('shediaoyingxiongzhuan.txt', errors='ignore', encoding='utf-16') as f: 

lines = f.readlines() 

for line in lines:

seg_list = jieba.cut(line)

with open('shediaoyingxiongzhuan_new.txt', 'a', encoding='utf-8') as n:

n.write(' '.join(seg_list))

print("jieba finish")


注意,我這裏提供的小說編碼格式爲‘utf-16’,但在寫入新文件時,爲了不後續的編碼問題,直接使用了‘utf-8’。新文件仍然保存在當前目錄下。咱們這裏不作語法分析、去存停用詞等預處理工做,只使用jieba分詞將咱們的句子打散。

from gensim.models import word2vec

sentences = word2vec.Text8Corpus('shediaoyingxiongzhuan_new.txt')

model = word2vec.Word2Vec(sentences,window=5,min_count=5,size=400)


接下來咱們使用gensim提供的word2vec類直接對整個文本進行訓練,這裏面有兩個參數,min_count=5表示出現次數少於5次的詞,將不會被訓練;window=5表示咱們使用skip-gram時,窗口的大小,就是一個詞與先後多少個詞放在一塊兒被訓練;size=400,是指embedding層的維度有多少,它決定着咱們獲得的詞向量的大小。這些參數均可以進行細緻的調節。


當咱們訓練完成之後,就能夠查看效果。雖然不存在一個肯定性的度量指標,但通常的,咱們有這麼幾種方法來大概估計詞向量的優劣:


• 詞向量的類似度,好比餘弦的大小。


• 類比法,好比咱們在上文提到的king-queen和man-woman。


• 降維可視化,好比t-SNE和PCA,將詞向量的維數降到3維或者2維。


• 聚類,但願看到同一類的東西彙集,不一樣類的東西分離。


咱們選用降維作可視化來直觀感覺詞向量在空間中的相對位置。首先,咱們能夠經過類似度計算,得出某一詞的相近詞,這裏咱們選用「黃蓉」爲例:

for e in model.most_similar(positive=['黃蓉'], topn=10):

print(e[0], e[1])

郭靖 0.9720229506492615

歐陽克 0.9623762965202332

歐陽鋒 0.9269372224807739

穆念慈 0.9042879343032837

柯鎮惡 0.9001784324645996

楊鐵心 0.894554853439331

陸冠英 0.8909748792648315

梅超風 0.8906383514404297

楊康 0.8814554810523987

洪七公 0.8773152828216553


能夠看出,她與郭靖距離最近,由於在小說中不少地方,都是黃蓉和郭靖一塊兒出現的,第二位是歐陽克,畢竟歐陽克是黃蓉的舔狗。黃藥師或者東邪爲何沒有出如今其中,成了一個較爲費解的問題。個人猜測是,有黃藥師在的地方,都會叫她「蓉兒」,而不是「黃蓉」,但咱們在搜索「蓉兒」的時候,會發現jieba已經將其分紅了「蓉」和「兒」,因此這個問題的考證要依靠更爲精細的分詞方法。


接下來,咱們對這幾我的作PCA降維,看一下它們在空間上的表現形式:

import matplotlib.pyplot as plt

from sklearn.decomposition import PCA

import numpy as np


word=[e[0] for e in model.most_similar(positive=['黃蓉'], topn=10)]

word.append('黃蓉')

y=np.array(word)


vec_array=np.zeros((len(word),400))

for i in range(len(word)):

dim_vec=model[word[i]]

vec_array[i]=dim_vec


plt.rcParams['font.family']=['Arial Unicode MS']#這一行是讓matplotlib顯示中文


pca=PCA(2)

X=pca.fit_transform(vec_array)


plt.figure(figsize=(10,10)

for j in y:

plt.scatter(X[y==j,0],X[y==j,1],s=200)

plt.text(X[y==j,0]+0.05,X[y==j,1]+0.05,j)

plt.legend()

plt.show()


image.png


如圖,能夠看出一個很是有趣的事實,發生愛戀關係的人在空間上表現出了相似惡詞向量關係。楊康和穆念慈的詞向量,與黃蓉和郭靖的詞向量,他們之間的關係很是近,幾乎有:


image.png


至少在金庸這部小說裏面,這個關係是成立的。咱們將其單獨提取出來,就變成了:


image.png

如圖,咱們能夠看出,他們之間的一一對應,就和上文中的king和queen,man和woman的關係是同樣的。


image.png

讀芯君開扒


課堂TIPS


• gensim另一些較爲簡單的使用方法,包括計算詞與詞的類似度,詞組與詞組的類似度,還能夠查看每一個詞的向量等等,咱們能夠進行增量訓練把模型訓練的更好,從而獲得更爲有趣的結果,這些都寫在官方文檔中,很是簡單易用。


• matplotlib並不支持中文的顯示,你能夠繞過這個問題,去使用英文的語料庫去練習。若是想解決這個問題,就用以下方法查看可用的中文字體,而後在代碼中聲明便可。


import matplotlib

font = sorted([f.name for f in matplotlib.font_manager.fontManager.ttflist])

#若是有可用的字體,就進行以下添加,將‘Arial Unicode MS’換作你擁有的中文字體名稱

import matplotlib.plot as plt

plt.rcParams['font.family']=['Arial Unicode MS']


• 獲得的詞向量,其實只是問題的開始,咱們可能會遇到主題分類,情感分析,智能問答,語音翻譯問題,這就須要咱們用所獲得的詞向量再放入新的學習器,在解決了詞向量的問題後,咱們會在下一節講解RNN。


image.png

留言 點贊 發個朋友圈

咱們一塊兒分享AI學習與發展的乾貨


做者:唐僧不用海飛絲


如需轉載,請後臺留言,遵照轉載規範


推薦文章閱讀


【週末AI課堂 | 第五十三講】理解詞嵌入(理論篇)

【週末AI課堂 | 第五十二講】簡單的自編碼器(代碼篇)

【週末AI課堂 | 第五十一講】簡單的自編碼器(理論篇)

【週末AI課堂 | 第五十講】SELU和ResNet(代碼篇)

【週末AI課堂 | 第四十九講】SELU和ResNet(理論篇)

【週末AI課堂 | 第四十八講】CNN在Keras中的實踐

【週末AI課堂 | 第四十七講】卷積之上的新操做(代碼篇)

【週末AI課堂 | 第四十六講】卷積之上的新操做(理論篇)

【週末AI課堂 | 第四十五講】認識批標準化的三種境界(代碼篇)

【週末AI課堂 | 第四十四講】認識批標準化的三種境界(理論篇)

【週末AI課堂 | 第四十三講】神經網絡的正則化(代碼篇)

【週末AI課堂 | 第四十二講】神經網絡的正則化(理論篇)

【週末AI課堂 | 第四十一講】深度學習中的熵(代碼篇)

【週末AI課堂 | 第四十講】深度學習中的熵(理論篇)

【週末AI課堂 | 第三十九講】理解softmax函數

【週末AI課堂 | 第三十八講】常見隱藏單元(代碼篇)

【週末AI課堂 | 第三十七講】常見隱藏單元(理論篇)

【週末AI課堂 | 第三十六講】隱藏單元的設計原則(代碼篇)

【週末AI課堂 | 第三十五講】隱藏單元的設計原則(理論篇)

【週末AI課堂 | 第三十四講】神經網絡綜觀(代碼篇)

【週末AI課堂 | 第三十三講】神經網絡綜觀(理論篇)

【週末AI課堂 | 第三十二講】從感知機到深度學習(代碼篇)

【週末AI課堂 | 第三十一講】從感知機到深度學習(理論篇)

【週末AI課堂 | 第三十講】理解梯度降低(二)(代碼篇)

【週末AI課堂 | 第二十九講】理解梯度降低(二)(理論篇)

【週末AI課堂 | 第二十八講】理解梯度降低(一)(代碼篇)

【週末AI課堂 | 第二十七講】理解梯度降低(一)(理論篇)

【週末AI課堂 | 第二十六講】理解損失函數(代碼篇)

【週末AI課堂 | 第二十五講】理解損失函數(理論篇)

【週末AI課堂 | 第二十四講】聚類的幾個重要問題(代碼篇)

【週末AI課堂 | 第二十三講】聚類的幾個重要問題(理論篇)

【週末AI課堂 | 第二十二講】Boosting集成(代碼篇)

【週末AI課堂 | 第二十一講】Boosting集成(理論篇)

【週末AI課堂 | 第二十講】bagging集成和stacking集成(代碼篇)

【週末AI課堂 | 第十九講】bagging集成和stacking集成(理論篇)

【週末AI課堂 | 第十八講】非參模型進階(代碼篇)

【週末AI課堂 | 第十七講】非參模型進階(理論篇)

【週末AI課堂 | 第十六講】非參模型初步(代碼篇)

【週末AI課堂 | 第十五講】非參模型初步(理論篇)

【週末AI課堂 | 第十四講】基於貝葉斯推斷的迴歸模型(代碼篇)

【週末AI課堂 | 第十三講】基於貝葉斯推斷的迴歸模型(理論篇)

【週末AI課堂 | 第十二講】基於貝葉斯推斷的分類模型(代碼篇)

【週末AI課堂 | 第十一講】基於貝葉斯推斷的分類模型(理論篇)

【週末AI課堂 | 第十講】核技巧(代碼篇)

【週末AI課堂 | 第九講】核技巧(理論篇)

【週末AI課堂 | 第八講】非線性降維方法(代碼篇)

【週末AI課堂 | 第七講】非線性降維方法(理論篇)

【週末AI課堂 | 第六講】線性降維方法(代碼篇)

【週末AI課堂 | 第五講】線性降維方法(理論篇)

【週末AI課堂 | 第四講】如何進行特徵選擇(代碼篇)

【週末AI課堂 | 第三講】如何進行特徵選擇(理論篇)

【週末AI課堂 | 第二講】過擬合問題(代碼篇)

【週末AI課堂 | 第一講】過擬合問題(理論篇)


長按識別二維碼可添加關注

讀芯君愛你


image.png

相關文章
相關標籤/搜索