<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【NLP】使用Python可視化Word2vec的結果

          共 6559字,需瀏覽 14分鐘

           ·

          2020-09-14 23:23

          作者 | Mate Pocs?

          編譯 | VK?

          來源 | Towards Data Science

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

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

          在本文中,我們將:

          • 從廣義上討論word2vec理論;

          • 下載原始的預訓練向量;

          • 看看一些有趣的應用程序:比如對一些單詞進行算術運算,比如著名的king-man+woman=queen等式

          • 根據(jù)word2vec向量看看我們能多精確地來繪制歐洲的首都。

          word2vec的原始研究論文和預訓練模型來自2013年,考慮到NLP文獻的擴展速度,目前它是老技術。較新的方法包括GloVe(更快,可以在較小的語料庫上訓練)和fastText(能夠處理字符級的n-gram)。

          Quick Word2Vec簡介

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

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

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

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

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

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

          word_vectors?=?KeyedVectors.load_word2vec_format(\
          ????'./word2vec_pretrained/GoogleNews-vectors-negative300.bin.gz',?\
          ????binary?=?True,?limit?=?1000000)

          limit參數(shù)定義了要導入的單詞數(shù),100萬對于我來說已經(jīng)足夠了。

          探索Word2vec

          現(xiàn)在我們已經(jīng)有了word2vec向量,我們可以查看它的一些相關有趣的用法。

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

          word_vectors['dog']

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

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

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

          結果

          [('good',?0.6836092472076416),
          ?('lovely',?0.6676311492919922),
          ?('neat',?0.6616737246513367),
          ?('fantastic',?0.6569241285324097),
          ?('wonderful',?0.6561347246170044)]

          現(xiàn)在,你可能認為用類似的方法,你也可以找到反義詞,你可能認為只需要把“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函數(shù)可以找出異常詞:

          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]?,F(xiàn)在,如果我們做同樣的運算,我們得到同樣的結果。當然,區(qū)別在于我們有300個維度,而不是示例中僅有的2個維度,維度的含義幾乎無法解釋。

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

          word_vectors.most_similar(
          positive?=?['doctor',?'woman'],?negative?=?['man'],?topn?=?1)

          [('gynecologist',?0.7093892097473145)]

          我們得到了婦科醫(yī)生,所以,我想這可能是進步吧?

          好吧,現(xiàn)在我們已經(jīng)檢查了一些基本的函數(shù),讓我們來研究我們的可視化吧!

          Map函數(shù)

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

          1. 找到列表中每個單詞的詞向量表示;

          2. 利用主成分分析法將維數(shù)降到2;

          3. 創(chuàng)建散點圖,將單詞作為每個數(shù)據(jù)點的標簽;

          4. 另外一個額外的好處是,可以從任何維度“旋轉”結果——主成分分析的向量是任意方向的,當我們繪制地理單詞時,我們可能想要改變這個方向,看是否可以與現(xiàn)實世界的方向一致。

          我們需要以下庫:

          import?matplotlib.pyplot?as?plt
          import?seaborn?as?sns
          from?sklearn.decomposition?import?PCA

          import?adjustText

          列表中不常用的一個庫是adjustText,這是一個非常方便的包,它使得在散點圖中編寫圖例變得簡單,而不會重疊。對于我來說,找到這個解決方案非常困難,而且據(jù)我所知,在matplotlib或seaborn中沒有辦法做到這一點。

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

          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)

          現(xiàn)在是測試函數(shù)的時候了。我畫出了歐洲國家的首都。你可以使用任何列表,例如總統(tǒng)或其他歷史人物的名字,汽車品牌,烹飪原料,搖滾樂隊等等,只要在word_list參數(shù)中傳遞它。很有意思的是看到一堆堆的東西在兩個軸后面形成一個意思。

          如果你想重現(xiàn)結果,以下是城市:

          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']

          假設你仍然有我們在上一節(jié)中創(chuàng)建的word_vectors對象,可以這樣調(diào)用函數(shù):

          plot_2d_representation_of_words(
          ????word_list?=?capitals,?
          ????word_vectors?=?word_vectors,?
          ????flip_y_axis?=?True)

          (翻轉y軸是為了創(chuàng)建更像真實貼圖的表示。)

          結果是:

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

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

          • 谷歌的一組研究人員訓練了一個龐大的神經(jīng)網(wǎng)絡,根據(jù)上下文預測單詞;

          • 他們將每個單詞的權重保存在一個300維的向量表示中;

          • 我們計算歐洲各國首都的向量;

          • 利用主成分分析法將維數(shù)降到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/Word2vec

          • https://adjusttext.readthedocs.io/en/latest/

          原文鏈接:https://towardsdatascience.com/how-to-draw-a-map-using-python-and-word2vec-e9627b4eae34



          往期精彩回顧





          獲取一折本站知識星球優(yōu)惠券,復制鏈接直接打開:

          https://t.zsxq.com/662nyZF

          本站qq群1003271085。

          加入微信群請掃碼進群(如果是博士或者準備讀博士請說明):

          瀏覽 67
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美性爱成人网站 | 狼友视频 - 首页 | 国产内射久久 | 日本操屄视频 | 国内精自视频在线观看 |