使用Python可視化Word2vec的結果

2021-01-07 人工智慧遇見磐創

Word2vec絕對是我在自然語言處理研究中遇到的最有趣的概念。想像一下,有一種算法可以成功地模擬理解單詞的含義及其在語言中的功能,它可以在不同的主題內來衡量單詞之間的接近程度。

我認為可視化地表示word2vec向量會很有趣:本質上,我們可以獲取國家或城市的向量,應用主成分分析來減少維度,並將它們放在二維圖表上。然後,我們可以觀察可視化的結果。

在本文中,我們將:

從廣義上討論word2vec理論;下載原始的預訓練向量;看看一些有趣的應用程式:比如對一些單詞進行算術運算,比如著名的king-man+woman=queen等式根據word2vec向量看看我們能多精確地來繪製歐洲的首都。word2vec的原始研究論文和預訓練模型來自2013年,考慮到NLP文獻的擴展速度,目前它是老技術。較新的方法包括GloVe(更快,可以在較小的語料庫上訓練)和fastText(能夠處理字符級的n-gram)。

Quick Word2Vec簡介

自然語言處理的核心概念之一是如何量化單詞和表達式,以便能夠在模型環境中使用它們。語言元素到數值表示的這種映射稱為詞嵌入。

Word2vec是一個詞嵌入過程。這個概念相對簡單:通過一個句子一個句子地在語料庫中循環去擬合一個模型,根據預先定義的窗口中的相鄰單詞預測當前單詞。

為此,它使用了一個神經網絡,但實際上最後我們並不使用預測的結果。一旦模型被保存,我們只保存隱藏層的權重。在我們將要使用的原始模型中,有300個權重,因此每個單詞都由一個300維向量表示。

請注意,兩個單詞不必彼此接近的地方才被認為是相似的。如果兩個詞從來沒有出現在同一個句子中,但它們通常被相同的包圍,那麼可以肯定它們有相似的意思。

word2vec中有兩種建模方法:skip-gram和continuous bag of words,這兩種方法都有各自的優點和對某些超參數的敏感性……但是你知道嗎?我們將不擬合我們自己的模型,所以我不會花時間在它上面。

當然,你得到的詞向量取決於你訓練模型的語料庫。一般來說,你確實需要一個龐大的語料庫,有維基百科上訓練過的版本,或者來自不同來源的新聞文章。我們將要使用的結果是在Google新聞上訓練出來的。

如何下載和安裝

首先,你需要下載預訓練word2vec向量。你可以從各種各樣的模型中進行選擇,這些模型是針對不同類型的文檔進行訓練的。

我用的是最初的模型,在Google新聞上受過訓練,你可以從很多來源下載,只需搜索「Google News vectors negative 300」。或者, 在這裡下載:https://github.com/mmihaltz/word2vec-GoogleNews-vectors。

注意,這個文件是1.66gb,但它包含了30億字的300維表示。

當談到在Python中使用word2vec時,再一次,你有很多包可供選擇,我們將使用gensim庫。假設文件保存在word2vec_pretrained文件夾中,可以用Python加載,代碼如下所示:

from gensim.models.keyedvectors import KeyedVectorsword_vectors = KeyedVectors.load_word2vec_format(\ './word2vec_pretrained/GoogleNews-vectors-negative300.bin.gz', \ binary = True, limit = 1000000)limit參數定義了要導入的單詞數,100萬對於我來說已經足夠了。

探索Word2vec

現在我們已經有了word2vec向量,我們可以查看它的一些相關有趣的用法。

首先,你可以實際檢查任何單詞的向量表示:

word_vectors['dog']結果,正如我們預期的,是一個300維的向量,並且這個向量很難解釋。我們通過對這些向量的加和減來計算新向量,然後計算餘弦相似度來找到最接近的匹配詞。

你可以使用most_similar函數找到同義詞,topn參數定義要列出的單詞數:

word_vectors.most_similar(positive = ['nice'], topn = 5)結果

[('good', 0.6836092472076416), ('lovely', 0.6676311492919922), ('neat', 0.6616737246513367), ('fantastic', 0.6569241285324097), ('wonderful', 0.6561347246170044)]現在,你可能認為用類似的方法,你也可以找到反義詞,你可能認為只需要把「nice」這個詞作為negative輸入。但結果卻是

[('J.Gordon_###-###', 0.38660115003585815), ('M.Kenseth_###-###', 0.35581791400909424), ('D.Earnhardt_Jr._###-###', 0.34227001667022705), ('G.Biffle_###-###', 0.3420777916908264), ('HuMax_TAC_TM', 0.3141660690307617)]這些詞實際上表示離「nice」這個詞最遠的詞。

使用doesnt_match函數可以找出異常詞:

word_vectors.doesnt_match(['Hitler', 'Churchill', 'Stalin', 'Beethoven'])返回Beethoven。我想這很方便。

最後,讓我們看看一些操作的例子,這些操作通過賦予算法一種虛假的智能感而出名。如果我們想合併father和woman這兩個詞的向量,並且減去man這個詞的向量,代碼如下

word_vectors.most_similar(positive = ['father', 'woman'], negative = ['man'], topn = 1)我們得到:

[('mother', 0.8462507128715515)]腦子先轉一轉,想像一下我們只有兩個維度:親子關係和性別。「女人」這個詞可以用這個向量來表示:[0,1],「男人」是[0,-1],「父親」是[1,-1],「母親」是[1,1]。現在,如果我們做同樣的運算,我們得到同樣的結果。當然,區別在於我們有300個維度,而不是示例中僅有的2個維度,維度的含義幾乎無法解釋。

在word2vec操作中,有一個著名的性別偏見例子,「doctor」這個詞的女性版本過去被計算為「nurse」。我試著複製,但沒有得到同樣的結果:

word_vectors.most_similar(positive = ['doctor', 'woman'], negative = ['man'], topn = 1)[('gynecologist', 0.7093892097473145)]我們得到了婦科醫生,所以,我想這可能是進步吧?

好吧,現在我們已經檢查了一些基本的函數,讓我們來研究我們的可視化吧!

Map函數

首先,我們需要一個Map函數。假設我們有一個要可視化的字符串列表和一個詞嵌入,我們希望:

找到列表中每個單詞的詞向量表示;利用主成分分析法將維數降到2;創建散點圖,將單詞作為每個數據點的標籤;另外一個額外的好處是,可以從任何維度「旋轉」結果——主成分分析的向量是任意方向的,當我們繪製地理單詞時,我們可能想要改變這個方向,看是否可以與現實世界的方向一致。我們需要以下庫:

import matplotlib.pyplot as pltimport seaborn as snsfrom sklearn.decomposition import PCAimport adjustText列表中不常用的一個庫是adjustText,這是一個非常方便的包,它使得在散點圖中編寫圖例變得簡單,而不會重疊。對於我來說,找到這個解決方案非常困難,而且據我所知,在matplotlib或seaborn中沒有辦法做到這一點。

無需進一步說明,此函數將完全滿足我們的需要:

def plot_2d_representation_of_words( word_list, word_vectors, flip_x_axis = False, flip_y_axis = False, label_x_axis = "x", label_y_axis = "y", label_label = "city"): pca = PCA(n_components = 2) word_plus_coordinates=[] for word in word_list: current_row = [] current_row.append(word) current_row.extend(word_vectors[word]) word_plus_coordinates.append(current_row) word_plus_coordinates = pd.DataFrame(word_plus_coordinates) coordinates_2d = pca.fit_transform( word_plus_coordinates.iloc[:,1:300]) coordinates_2d = pd.DataFrame( coordinates_2d, columns=[label_x_axis, label_y_axis]) coordinates_2d[label_label] = word_plus_coordinates.iloc[:,0] if flip_x_axis: coordinates_2d[label_x_axis] = \ coordinates_2d[label_x_axis] * (-1) if flip_y_axis: coordinates_2d[label_y_axis] = \ coordinates_2d[label_y_axis] * (-1) plt.figure(figsize = (15,10)) p1=sns.scatterplot( data=coordinates_2d, x=label_x_axis, y=label_y_axis) x = coordinates_2d[label_x_axis] y = coordinates_2d[label_y_axis] label = coordinates_2d[label_label] texts = [plt.text(x[i], y[i], label[i]) for i in range(len(x))] adjustText.adjust_text(texts)現在是測試函數的時候了。我畫出了歐洲國家的首都。你可以使用任何列表,例如總統或其他歷史人物的名字,汽車品牌,烹飪原料,搖滾樂隊等等,只要在word_list參數中傳遞它。很有意思的是看到一堆堆的東西在兩個軸後面形成一個意思。

如果你想重現結果,以下是城市:

capitals = [ 'Amsterdam', 'Athens', 'Belgrade', 'Berlin', 'Bern', 'Bratislava', 'Brussels', 'Bucharest', 'Budapest', 'Chisinau', 'Copenhagen','Dublin', 'Helsinki', 'Kiev', 'Lisbon', 'Ljubljana', 'London', 'Luxembourg','Madrid', 'Minsk', 'Monaco', 'Moscow', 'Nicosia', 'Nuuk', 'Oslo', 'Paris','Podgorica', 'Prague', 'Reykjavik', 'Riga', 'Rome', 'San_Marino', 'Sarajevo','Skopje', 'Sofia', 'Stockholm', 'Tallinn', 'Tirana', 'Vaduz', 'Valletta', 'Vatican', 'Vienna', 'Vilnius', 'Warsaw', 'Zagreb']假設你仍然有我們在上一節中創建的word_vectors對象,可以這樣調用函數:

plot_2d_representation_of_words( word_list = capitals, word_vectors = word_vectors, flip_y_axis = True)(翻轉y軸是為了創建更像真實貼圖的表示。)

結果是:

我不知道你的感受,當我第一次看到地圖的時候,我真不敢相信結果會有多好!是的,當然,你看得越久,你發現的「錯誤」就越多,一個不好的結果就是莫斯科離東方的距離並不像它應該的那麼遠……儘管如此,東西方幾乎完全分離,斯堪地那維亞和波羅的海國家被很好地組合在一起,義大利周圍的首都也是如此。

需要強調的是,這絕不是純粹的地理位置,例如,雅典離西方很遠,但這是有原因的。讓我們回顧一下上面的地圖是如何導出的,這樣我們就可以充分理解它了:

谷歌的一組研究人員訓練了一個龐大的神經網絡,根據上下文預測單詞;他們將每個單詞的權重保存在一個300維的向量表示中;我們計算歐洲各國首都的向量;利用主成分分析法將維數降到2;把計算出的成分放在圖表上。所以,語義的信息不能代表真實地理信息。但我覺得這個嘗試很有趣。

參考引用

Hobson, L. & Cole, H. & Hannes, H. (2019). Natural Language Processing in Action: Understanding, Analyzing, and Generating Text with Python. Manning Publications, 2019.https://en.wikipedia.org/wiki/Word2vechttps://adjusttext.readthedocs.io/en/latest/

相關焦點

  • 詞彙星空:如何構建一個炫酷的 Word2Vec 可視化
    word2vec嵌入構建了最近鄰居圖(Nearest neighbor graph)。儘管如此,我仍想保留這個可視化,以便讓你探索它: 2.簡介和細節word2vec2.2數據與數據預處理我使用了GloVe項目的預訓練過的word2vec模型。
  • 文本挖掘從小白到精通(六)---word2vec的訓練、使用和可視化
    Word2vec作為基於神經網絡的機器學習算法的「新浪潮」中的成員得以廣泛使用,通常被稱為「深度學習」(儘管word2vec本身的層數相當淺)。Word2vec使用大量未注釋的純文本,word2vec自動學習到詞彙之間的關係,輸出是向量,每個詞彙一個向量,具有顯著的線性語義關係,由此我們可以做諸如vec(「king」) - vec(「man」)+ vec(「woman」)= ~vec(「queen」)之類的加減運算,或vec(「蒙特婁加拿大人隊」) - vec(「蒙特婁」)+ vec(「多倫多」)等於「
  • 用word2vec解讀延禧攻略人物關係
    通過從網上收集相關的小說、劇本、人物介紹等,經過word2vec深度學習模型的訓練,構建人物關係圖譜,並通過可視化的方式進行展示。1圖譜 先看看全劇人物的關係圖譜:2構建思路需要的數據:延禧攻略小說延禧攻略劇本延禧攻略人物名稱算法:word2vec前端:
  • 圖解 Word2Vec
    在本文中,我們將介紹嵌入的概念以及使用word2vec生成嵌入的機制。但是,讓我們從一個示例開始,以熟悉如何使用向量來表示事物。你是否知道五個數字(一個向量)可以代表你的個性?Personality Embeddings: What are you like?
  • 圖解Word2vec
    在這篇文章中,我們將討論嵌入的概念,以及使用word2vec生成嵌入的機制。讓我們從一個例子開始,熟悉使用向量來表示事物。你是否知道你的個性可以僅被五個數字的列表(向量)表示?個性嵌入:你是什麼樣的人?如何用0到100的範圍來表示你是多麼內向/外向(其中0是最內向的,100是最外向的)?你有沒有做過像MBTI那樣的人格測試,或者五大人格特質測試?
  • 【算法】word2vec與doc2vec模型
    2 word2vec與doc2vec有什麼差異?3 如何做word2vec和doc2vec?深度學習掀開了機器學習的新篇章,目前深度學習應用於圖像和語音已經產生了突破性的研究進展。  d)  Word2Vector 模型  最近幾年剛剛火起來的算法,通過神經網絡機器學習算法來訓練N-gram 語言模型,並在訓練過程中求出word所對應的vector的方法。本文將詳細闡述此方法的原理。4.word2vec算法思想  什麼是word2vec?
  • 圖解word2vec
    word2vec一直是一種有效的詞嵌入的方法,本文把word2vec用圖解的方式進行,全篇沒有數學公式,非常通俗易懂,推薦初學者閱讀。我們將討論嵌入的概念,以及使用word2vec生成嵌入的機制。讓我們從一個例子開始,了解使用向量來表示事物。您是否知道五個數字(向量)的列表可以代表您的個性?個性嵌入:你的個性怎麼樣?使用0到100的範圍表示你的個性(其中0是最內向的,100是最外向的)。
  • 白話Word2Vec
    雖然還有一些優化的空間,比如說使用稀疏矩陣來保存這些數據,即便如此,在性能和內存開銷上依然差強人意。從最終結果來看,我們其實想要的那個降維後的嵌入矩陣,有沒辦法不要生成這個原始矩陣,直接得到嵌入矩陣呢?使用傳統的方法是辦不到了。3. 神經網絡既然傳統方法做不了,只能另闢蹊徑。
  • 自然語言處理——圖解Word2vec
    在這篇文章中,我們將討論嵌入的概念,以及使用word2vec生成嵌入的機制。讓我們從一個例子開始,熟悉使用向量來表示事物。你是否知道你的個性可以僅被五個數字的列表(向量)表示?個性嵌入:你是什麼樣的人?如何用0到100的範圍來表示你是多麼內向/外向(其中0是最內向的,100是最外向的)?你有沒有做過像MBTI那樣的人格測試,或者五大人格特質測試?
  • 深入理解word2vec
    word2vec是一種基於神經網絡的語言模型,也是一種詞彙表徵方法。word2vec包括兩種結構:skip-gram(跳字模型)和CBOW(連續詞袋模型),但本質上都是一種詞彙降維的操作。  我們將NLP的語言模型看作是一個監督學習問題:即給定上下文詞,輸出中間詞,或者給定中間詞,輸出上下文詞。基於輸入和輸出之間的映射便是語言模型。
  • 文本深度表示模型—word2vec&doc2vec詞向量模型
    Word2Vector 模型最近幾年剛剛火起來的算法,通過神經網絡機器學習算法來訓練N-gram 語言模型,並在訓練過程中求出word所對應的vector的方法。本文將詳細闡述此方法的原理。4.word2vec算法思想什麼是word2vec?
  • 文本深度表示模型——word2vec&doc2vec詞向量模型
    d)  Word2Vector 模型  最近幾年剛剛火起來的算法,通過神經網絡機器學習算法來訓練N-gram 語言模型,並在訓練過程中求出word所對應的vector的方法。本文將詳細闡述此方法的原理。4.word2vec算法思想  什麼是word2vec?
  • 大白話講解word2vec到底在做些什麼
    在word2vec出現之前,自然語言處理經常把字詞轉為離散的單獨的符號,也就是One-Hot Encoder。模型拆解word2vec模型其實就是簡單化的神經網絡。假設語料庫中有30000個不同的單詞,hidden layer取128,word2vec兩個權值矩陣維度都是[30000,128],在使用SGD對龐大的神經網絡進行學習時,將是十分緩慢的。而且,你需要大量的訓練數據來調整許多權重,避免過度擬合。數以百萬計的重量數十億倍的訓練樣本意味著訓練這個模型將是一個野獸。
  • 【自然語言處理】Word2Vec 概述及中文語料實戰
    Word2Vec的優缺點優點缺點Word2Vec中文語料實戰環境win10 + python3 依賴包:gensim與jieba (通過pip install 安裝)語料庫《誅仙》小說 (部分) 訓練word2vec模型#coding:utf8import gensim.models.word2vec as w2vmodel_file_name = 'model'#
  • word2vec模型深度解析
    【前言】word2vec是一個被廣泛應用的word embedding方法,由於最近研究需要,將算法模型研究了一下由於word2vec內容很多,這裡儘量講解核心內容,有不足之處還請指出!word2vec hierarchical softmax結構和傳統的神經網絡輸出不同的是,word2vec的hierarchical softmax結構是把輸出層改成了一顆哈夫曼樹,其中圖中白色的葉子節點表示詞彙表中所有的|V|個詞,黑色節點表示非葉子節點
  • Word2Vec 與 GloVe 技術淺析與對比
    semantic analysis)為代表的global matrix factorization methods,也稱為 count-based methods; 以及以word2vec為代表的 prediction-based methods。
  • 圖解 Word2Vec,讀這一篇就夠了
    在這篇文章中,我們將討論嵌入的概念,以及使用word2vec生成嵌入的機制。讓我們從一個例子開始,熟悉使用向量來表示事物。你是否知道你的個性可以僅被五個數字的列表(向量)表示?如何用0到100的範圍來表示你是多麼內向/外向(其中0是最內向的,100是最外向的)? 你有沒有做過像MBTI那樣的人格測試,或者五大人格特質測試?
  • 深度學習筆記 | 第13講:word2vec詞向量
    本節小編將繼續和大家一起學習基於神經網絡模型的詞向量表徵方法,其中的代表模型就是著名的 word2vec。word2vec 是谷歌於 2013 年提出的一種 NLP 工具,其特點就是將詞彙進行向量化,這樣我們就可以定量的分析和挖掘詞彙之間的聯繫。因而 word2vec 也是我們上一講講到的詞嵌入表徵的一種,只不過這種向量化表徵需要經過神經網絡訓練得到。
  • 手把手教你NumPy來實現Word2vec
    Google一下就會找到一堆關於如何使用諸如Gensim和TensorFlow的庫來調用Word2Vec方法的結果。另外,對於那些好奇心強的人,可以查看Tomas Mikolov基於C語言的原始實現。原稿也可以在這裡找到。本文的主要重點是詳細介紹Word2Vec。
  • Word Embedding Papers | 經典再讀之Word2Vec
    2. word2vec(二):面試!考點!都在這裡:圍繞 Distributed Representations of Words and Phrases and their Compositionality。會談到:真正讓 word2vec 被廣泛應用的延伸與改進。