DL4J中文文檔/語(yǔ)言處理/Word2Vec

Word2Vec, Doc2vec & GloVe: 用于自然語(yǔ)言處理的神經(jīng)詞嵌入

內(nèi)容

  • 介紹
  • 神經(jīng)詞嵌入
  • 有趣的Word2Vec結(jié)果
  • 給我代碼
  • Word2Vec 剖析
  • 安裝疾渴,加載與訓(xùn)練
  • 代碼示例
  • 問(wèn)題排查與Word2Vec調(diào)試
  • Word2Vec用例
  • 外語(yǔ)
  • GloVe(全局向量)與Doc2Vec

Word2Vec介紹

Word2Vec是一個(gè)處理文本的兩層神經(jīng)網(wǎng)絡(luò)礼烈。它的輸入是一個(gè)文本語(yǔ)料庫(kù),它的輸出是一組向量:語(yǔ)料庫(kù)中的單詞的特征向量惧蛹。Word2Vec不是一個(gè)深度神經(jīng)網(wǎng)絡(luò)辕狰,它將文本轉(zhuǎn)換成一個(gè)深度網(wǎng)絡(luò)可以理解的數(shù)值形式绢慢。DL4J實(shí)現(xiàn)了一個(gè)分布式的Word2Vec值朋,用于Java和Scala,它在Spark的GPU上工作吁恍。

Word2Vec的應(yīng)用擴(kuò)展了自然界的句子解析扒秸。它也可以同樣地應(yīng)用于基因播演、代碼、喜歡鸦采、播放列表宾巍、社交媒體圖表和其他可以識(shí)別模式的語(yǔ)言或符號(hào)系列。

為什么渔伯?因?yàn)閱卧~只是像上面提到的其他數(shù)據(jù)一樣的離散狀態(tài),我們只是在尋找這些狀態(tài)之間的轉(zhuǎn)移概率:它們將同時(shí)發(fā)生的可能性肄程。所以gene2vec锣吼,like2vec和follower2vec 都是可能的。記住這一點(diǎn)蓝厌,下面的教程將幫助你理解如何為任意一組離散和共現(xiàn)狀態(tài)創(chuàng)建神經(jīng)嵌入玄叠。

Word2Vec的目的和實(shí)用性是將相似詞的向量分組到向量空間中。也就是說(shuō)拓提,它在數(shù)學(xué)上檢測(cè)相似性读恃。Word2Vec創(chuàng)建向量,這些向量是單詞特征(例如單個(gè)單詞的上下文)的分布式數(shù)字表示代态。這樣做沒(méi)有人為干預(yù)寺惫。

給定足夠的數(shù)據(jù)、用法和上下文蹦疑,Word2Vec可以基于過(guò)去的出現(xiàn)對(duì)單詞的意義做出高度準(zhǔn)確的猜測(cè)西雀。這些猜測(cè)可以用來(lái)建立一個(gè)單詞與其他單詞的關(guān)聯(lián)(例如,“男人”是“男孩”歉摧,“女人”是“女孩”)艇肴,或者是聚類文檔,并按主題分類叁温。這些聚類可以構(gòu)成搜索的基礎(chǔ)再悼、情感分析和在科學(xué)研究、法律發(fā)現(xiàn)膝但、電子商務(wù)和客戶關(guān)系管理等多個(gè)領(lǐng)域的建議冲九。

Word2Vec神經(jīng)網(wǎng)絡(luò)的輸出是一個(gè)詞匯表,其中每個(gè)項(xiàng)目都有一個(gè)附加到它的向量锰镀,它可以被送入深度學(xué)習(xí)網(wǎng)絡(luò)或簡(jiǎn)單地查詢以檢測(cè)詞之間的關(guān)系娘侍。

測(cè)量余弦相似度,90度角表示沒(méi)有相似度泳炉,而總的相似度是1是0度角憾筏,完全重疊;即Sweden等于Sweden花鹅,而Norway到Sweden的余弦距離是0.760124氧腰,是任何其他國(guó)家中最高的。

這是一個(gè)使用Word2Vec生成的與“Sweden”相關(guān)的單詞列表,按接近順序排序:

Cosine Distance
image.gif

?

斯堪的納維亞的國(guó)家和幾個(gè)富裕的北歐古拴、日耳曼國(guó)家躋身前九位箩帚。

神經(jīng)詞嵌入

我們用來(lái)表示單詞的向量稱為神經(jīng)詞嵌入,表示是奇怪的黄痪。一件事描述了另一件事紧帕,盡管這兩件事是根本不同的。正如Elvis Costello所說(shuō):“寫(xiě)作對(duì)于音樂(lè)就像跳舞對(duì)于建筑桅打∈鞘龋”Word2Vec對(duì)單詞“向量化”,通過(guò)這樣做挺尾,它使得自然語(yǔ)言可以被計(jì)算機(jī)閱讀——我們可以開(kāi)始對(duì)單詞執(zhí)行強(qiáng)大的數(shù)學(xué)運(yùn)算以檢測(cè)它們的相似性鹅搪。

因此,神經(jīng)詞嵌入用數(shù)字代表一個(gè)單詞遭铺。這是一個(gè)簡(jiǎn)單但不太可能的翻譯丽柿。

Word2Vec類似于一個(gè)自動(dòng)編碼器,將每個(gè)單詞編碼在一個(gè)向量中魂挂,而不是通過(guò)重建對(duì)輸入單詞進(jìn)行訓(xùn)練甫题,Word2Vec在語(yǔ)料庫(kù)中將單詞和與它們相鄰的其他單詞進(jìn)行訓(xùn)練。

它以兩種方式中的其中一種來(lái)實(shí)現(xiàn)锰蓬,或者使用上下文來(lái)預(yù)測(cè)目標(biāo)單詞(一種稱為連續(xù)詞袋或CBOW的方法)幔睬,或者使用單詞來(lái)預(yù)測(cè)目標(biāo)上下文,即skip-gram芹扭。我們使用后一種方法麻顶,因?yàn)樗鼘?duì)大數(shù)據(jù)集產(chǎn)生更精確的結(jié)果。

word2vec diagram
image.gif

?

當(dāng)分配給單詞的特征向量不能用于精確預(yù)測(cè)該單詞的上下文時(shí)舱卡,向量的組成部分會(huì)被調(diào)整辅肾。語(yǔ)料庫(kù)中的每個(gè)單詞的上下文是老師,往回發(fā)送錯(cuò)誤信號(hào)以調(diào)整特征向量轮锥。通過(guò)調(diào)整在向量中數(shù)值湊在一起的上下文矫钓,單詞的向量被它們判斷為相似的。

正如梵高的向日葵畫(huà)是油畫(huà)布上的二維混合物舍杜,代表了1880年代末巴黎三維空間中的植物物質(zhì)新娜,所以以向量排列的500個(gè)數(shù)字可以代表一個(gè)詞或一組詞。

這些數(shù)字將每個(gè)單詞定位為500維向量空間中的一個(gè)點(diǎn)既绩。超過(guò)三個(gè)維度的空間難以可視化概龄。(Geoff Hinton教授人們想象13維空間,建議學(xué)生首先想象3維空間饲握,然后對(duì)自己說(shuō):“13私杜、13蚕键、13”:)

一組訓(xùn)練有素的單詞向量將在那個(gè)空間中放置相似的單詞∷ゴ猓“橡樹(shù)”锣光、“榆樹(shù)”和“樺樹(shù)”可能會(huì)聚集在一個(gè)角落,而戰(zhàn)爭(zhēng)铝耻、沖突和爭(zhēng)斗則聚集在另一個(gè)角落誊爹。

類似的事情和想法被證明是“接近的”。它們的相對(duì)意義已經(jīng)轉(zhuǎn)化為可測(cè)量的距離瓢捉。質(zhì)量變成數(shù)量替废,算法可以完成他們的工作。但相似性只是Word2Vec可以學(xué)習(xí)的許多關(guān)聯(lián)的基礎(chǔ)泊柬。例如,它可以衡量一種語(yǔ)言的單詞之間的關(guān)系诈火,并將它們映射到另一種語(yǔ)言兽赁。

word2vec translation
image.gif

?

這些向量是更全面的詞匯幾何的基礎(chǔ)。如圖所示冷守,像羅馬刀崖、巴黎、柏林和北京這樣的首都城市相互靠近拍摇,在向量空間上它們各自具有與其國(guó)家相似的距離亮钦,即羅馬-意大利=北京-中國(guó)。如果你只知道羅馬是意大利的首都充活,并想知道中國(guó)的首都蜂莉,那么等式羅馬-意大利+中國(guó)將返回北京。這不是玩笑混卵。

capitals output
image.gif

?

有趣的Word2Vec結(jié)果

讓我們看看Word2Vec可以產(chǎn)生的其他關(guān)聯(lián)映穗。

我們將用邏輯類比的符號(hào)代替加減等號(hào),給出結(jié)果幕随,其中:是 “對(duì)于”的意思和::“等同”的意思蚁滋,例如“羅馬對(duì)意大利就像北京對(duì)中國(guó)一樣”=羅馬:意大利::北京:中國(guó)。在最后一點(diǎn)赘淮,當(dāng)給出前三個(gè)元素時(shí)辕录,我們將給出Word2vec模型建議的單詞列表,而不是提供“答案”:

king:queen::man:[woman, Attempted abduction, teenager, girl] 
//很怪異梢卸,但你可以看到

China:Taiwan::Russia:[Ukraine, Moscow, Moldova, Armenia]
//兩個(gè)大國(guó)和他們小的遠(yuǎn)離的鄰居

house:roof::castle:[dome, bell_tower, spire, crenellations, turrets]

knee:leg::elbow:[forearm, arm, ulna_bone]

New York Times:Sulzberger::Fox:[Murdoch, Chernin, Bancroft, Ailes]
//Sulzberger-Ochs家族擁有并經(jīng)營(yíng)NYT走诞。
//Murdoch 家族擁有新聞公司,此家族有傅吞蓿克斯新聞速梗。 
//Peter Chernin是新聞公司的13年的首席運(yùn)營(yíng)官肮塞。
//Roger Ailes是福克斯新聞的主席姻锁。 
//Bancroft家族把《華爾街日?qǐng)?bào)》賣給了新聞集團(tuán)枕赵。

love:indifference::fear:[apathy, callousness, timidity, helplessness, inaction]
//這首詩(shī)的詩(shī)集簡(jiǎn)直令人驚嘆。

Donald Trump:Republican::Barack Obama:[Democratic, GOP, Democrats, McCain]
//有趣的是位隶,正如奧巴馬和麥凱恩是對(duì)手一樣
//同樣拷窜,Word2Vec認(rèn)為特朗普與共和黨的觀點(diǎn)有對(duì)立。

monkey:human::dinosaur:[fossil, fossilized, Ice_Age_mammals, fossilization]
//人類是化石猴子涧黄?人類就是剩下的
//猴子篮昧?人類是打敗猴子的物種。
//就像冰河時(shí)代哺乳動(dòng)物打敗恐龍一樣笋妥?貌似有理的懊昨。

building:architect::software:[programmer, SecurityCenter, WinPcap]

image.gif

這個(gè)模型是在谷歌新聞vocab上進(jìn)行訓(xùn)練的,你可以導(dǎo)入并玩一玩春宣〗桶洌考慮片刻,Word2Vec算法從來(lái)沒(méi)有被教過(guò)一條英語(yǔ)語(yǔ)法規(guī)則月帝。它對(duì)世界一無(wú)所知躏惋,與任何基于規(guī)則的符號(hào)邏輯或知識(shí)圖無(wú)關(guān)。然而嚷辅,比在多年的人力學(xué)習(xí)后大的大多數(shù)知識(shí)圖的學(xué)習(xí)簿姨,它以更靈活和自動(dòng)化的方式學(xué)習(xí)。它把Google新聞的文檔看作一張白板簸搞,訓(xùn)練結(jié)束后扁位,它可以計(jì)算對(duì)人類有意義的復(fù)雜類推。

你還可以查詢Word2Vec模型進(jìn)行其他關(guān)聯(lián)攘乒。并不是每件事都必須有兩個(gè)相互鏡像的類推贤牛。(我們解釋如下……)

  • 地緣政治學(xué):伊拉克-暴力=約旦
  • 區(qū)分:人類-動(dòng)物=倫理
  • 總統(tǒng)-權(quán)力=總理
  • 圖書(shū)館-圖書(shū)=大廳
  • 類推:股票市場(chǎng)≈溫度計(jì)

通過(guò)構(gòu)建一個(gè)單詞與其他類似單詞的鄰近場(chǎng)景,這些單詞不一定包含相同的字母则酝,我們已經(jīng)從硬標(biāo)記殉簸,進(jìn)入了更平滑和更普遍的意義的場(chǎng)景 。

給我代碼

DL4J中Word2Vec的剖析

這些是DL4J自然語(yǔ)言處理的組件:

  • SentenceIterator/DocumentIterator: 用于迭代一個(gè)數(shù)據(jù)集沽讹。 SentenceIterator 返回一個(gè)字符串 般卑, DocumentIterator 與輸入流一起工作。
  • Tokenizer/TokenizerFactory: 用于對(duì)文本進(jìn)行分詞爽雄。 在NLP術(shù)語(yǔ)中蝠检,句子被表示為一系列詞。TokenizerFactory為一個(gè)句子創(chuàng)建一個(gè)分詞器的實(shí)例挚瘟。
  • VocabCache: 用于跟蹤元數(shù)據(jù)叹谁,包括單詞計(jì)數(shù)饲梭、文檔出現(xiàn)、詞集(本例中不是vocab焰檩,而是已經(jīng)發(fā)生的令牌詞)憔涉、vocab(詞袋和單詞向量查找表中包括的特性)
  • Inverted Index: 存儲(chǔ)有關(guān)單詞發(fā)生的元數(shù)據(jù)∥錾唬可以用于理解數(shù)據(jù)集兜叨。自動(dòng)創(chuàng)建具有Lucene實(shí)現(xiàn)(1)的Lucene索引。

Word2vec是指一系列相關(guān)算法衩侥,該實(shí)現(xiàn)采用負(fù)采樣国旷。

Word2Vec 設(shè)置

使用Maven在IntelliJ中創(chuàng)建一個(gè)新項(xiàng)目。如果你不知道怎么做茫死,請(qǐng)看我們的快速入門頁(yè)面跪但。然后在項(xiàng)目的根目錄的POM.xml文件中指定這些屬性和依賴項(xiàng)(你可以檢查Maven以獲得最新版本,請(qǐng)使用這些版本…)峦萎。

加載數(shù)據(jù)

現(xiàn)在在Java中創(chuàng)建并命名一個(gè)新類特漩。之后,你將在.txt文件中獲取原始語(yǔ)句骨杂,用迭代器遍歷它們,并使它們接受某種預(yù)處理雄卷,例如將所有單詞轉(zhuǎn)換為小寫(xiě)搓蚪。

        String filePath = new ClassPathResource("raw_sentences.txt").getFile().getAbsolutePath();

        log.info("加載并向量化句子....");
        //每一行之間用空格分割
        SentenceIterator iter = new BasicLineIterator(filePath);

image.gif

如果你想加載一個(gè)文本文件,用我們的例子中提供的句子之外的句子丁鹉,你這樣做:

        log.info("Load data....");
        SentenceIterator iter = new LineSentenceIterator(new File("/Users/cvn/Desktop/file.txt"));
        iter.setPreProcessor(new SentencePreProcessor() {
            @Override
            public String preProcess(String sentence) {
                return sentence.toLowerCase();
            }
        });

image.gif

也就是說(shuō)妒潭,去掉ClassPathResource,并將你的.txt文件的絕對(duì)路徑填入到LineSentenceIterator中揣钦。

SentenceIterator iter = new LineSentenceIterator(new File("/your/absolute/file/path/here.txt"));

image.gif

在bash中雳灾,通過(guò)在命令行中從同一目錄中鍵入pwd,可以找到任何目錄的絕對(duì)文件路徑冯凹。對(duì)于該路徑谎亩,你將添加文件名。

數(shù)據(jù)分詞

Word2Vec需要用詞而不是完整的句子宇姚,所以下一步就是把數(shù)據(jù)分詞匈庭。把文本分詞是把它分解成原子單位,例如浑劳,每次你點(diǎn)擊一個(gè)空白處時(shí)阱持,創(chuàng)建一個(gè)新的分詞。

        //在每行用用空格分割以得到單詞
        TokenizerFactory t = new DefaultTokenizerFactory();
        t.setTokenPreProcessor(new CommonPreprocessor());

image.gif

那樣它會(huì)給你每行一個(gè)詞魔熏。

訓(xùn)練模型

現(xiàn)在數(shù)據(jù)已準(zhǔn)備就緒衷咽,你可以配置Word2Vec神經(jīng)網(wǎng)絡(luò)并輸入分詞鸽扁。

        log.info("Building model....");
        Word2Vec vec = new Word2Vec.Builder()
                .minWordFrequency(5)
                .layerSize(100)
                .seed(42)
                .windowSize(5)
                .iterate(iter)
                .tokenizerFactory(t)
                .build();

        log.info("Fitting Word2Vec model....");
        vec.fit();

image.gif

此配置接受許多超參數(shù)。 一些需要一些解釋:

  • batchSize 是你一次處理的單詞數(shù)量镶骗。

  • minWordFrequency 是單詞必須出現(xiàn)在語(yǔ)料庫(kù)中的最小次數(shù)桶现。 在這里,如果它出現(xiàn)少于5次卖词,則不會(huì)學(xué)習(xí)巩那。 單詞必須出現(xiàn)在多個(gè)上下文中才能學(xué)習(xí)有關(guān)它們的有用特征。 在非常大的語(yǔ)料庫(kù)中此蜈,提高最小值是合理的即横。

  • useAdaGrad - Adagrad為每個(gè)特征創(chuàng)建不同的梯度。 在這里裆赵,我們并不關(guān)心這一點(diǎn)东囚。

  • layerSize 指定單詞向量中的特征數(shù)。這等于特征空間中的維數(shù)战授。由500個(gè)特征表示的詞成為500維空間中的點(diǎn)页藻。

  • learningRate 是每個(gè)更新系數(shù)的步長(zhǎng),因?yàn)閱卧~在特征空間中被重新定位植兰。

  • minLearningRate 是學(xué)習(xí)率的底板份帐。學(xué)習(xí)速率隨著你訓(xùn)練的單詞數(shù)量的減少而衰減。如果學(xué)習(xí)率下降太多楣导,網(wǎng)絡(luò)的學(xué)習(xí)就不再有效了废境。這保持系數(shù)移動(dòng)。

  • iterate 告訴網(wǎng)絡(luò)它正在訓(xùn)練的數(shù)據(jù)集的批次筒繁。

  • tokenizer 從當(dāng)前批次中為它提供單詞噩凹。

  • vec.fit() 告訴配置的網(wǎng)絡(luò)開(kāi)始訓(xùn)練。

這里是訓(xùn)練你以前訓(xùn)練過(guò)的單詞向量的示例毡咏。

使用Word2Vec評(píng)估模型

下一步是評(píng)估特征向量的質(zhì)量驮宴。

        // 寫(xiě)入詞向量
        WordVectorSerializer.writeWordVectors(vec, "pathToWriteto.txt");

        log.info("最接近的10個(gè)詞:");
        Collection<String> lst = vec.wordsNearest("day", 10);
        System.out.println(lst);
        UiServer server = UiServer.getInstance();
        System.out.println("啟動(dòng)端口:" + server.getPort());

        //輸出: [night, week, year, game, season, during, office, until, -]

image.gif

vec.similarity("word1","word2")這行將返回輸入的兩個(gè)詞的余弦相似度。越接近1呕缭,網(wǎng)絡(luò)就理解為越類似于那些詞(參見(jiàn)上面的瑞典-挪威例子)堵泽。例如:

        double cosSim = vec.similarity("day", "night");
        System.out.println(cosSim);
        //輸出: 0.7704452276229858

image.gif

使用vec.wordsNearest("word1", numWordsNearest),打印到屏幕上的單詞允許你查看網(wǎng)絡(luò)是否聚集了語(yǔ)義上相似的單詞恢总。你可以用wordsNearest方法的第二個(gè)參數(shù)來(lái)設(shè)置你想要的最近單詞的數(shù)量落恼。例如:

        Collection<String> lst3 = vec.wordsNearest("man", 10);
        System.out.println(lst3);
        //輸出: [director, company, program, former, university, family, group, such, general]

image.gif

模型可視化

我們依賴于TSNE來(lái)把單詞特征向量和項(xiàng)目詞的維數(shù)減少到兩個(gè)或三維空間。TSNE的完整的DL4J/ND4J例子在這里离熏。

        Nd4j.setDataType(DataBuffer.Type.DOUBLE);
        List<String> cacheList = new ArrayList<>(); //cacheList 是一種動(dòng)態(tài)字符串?dāng)?shù)組佳谦,用于保存所有單詞。

        //步驟2:將文本輸入轉(zhuǎn)換成單詞列表
        log.info("加載并向量化數(shù)據(jù)....");
        File wordFile = new ClassPathResource("words.txt").getFile();   //打開(kāi)文件
        //獲取所有唯一詞向量的數(shù)據(jù)
        Pair<InMemoryLookupTable,VocabCache> vectors = WordVectorSerializer.loadTxt(wordFile);
        VocabCache cache = vectors.getSecond();
        INDArray weights = vectors.getFirst().getSyn0();    //將獨(dú)特詞的權(quán)重分成自己的列表

        for(int i = 0; i < cache.numWords(); i++)   //把字串分隔成自己的列表
            cacheList.add(cache.wordAtIndex(i));

        //步驟3:構(gòu)建雙樹(shù)TSNE以供以后使用
        log.info("Build model....");
        BarnesHutTsne tsne = new BarnesHutTsne.Builder()
                .setMaxIter(iterations).theta(0.5)
                .normalize(false)
                .learningRate(500)
                .useAdaGrad(false)
//                .usePca(false)
                .build();

        //步驟4:建立TSNE值并將其保存到文件中
        log.info("存儲(chǔ)TSNE坐標(biāo)用于繪制....");
        String outputFile = "target/archive-tmp/tsne-standard-coords.csv";
        (new File(outputFile)).getParentFile().mkdirs();

        tsne.fit(weights);
        tsne.saveAsFile(cacheList, outputFile);

image.gif

保存滋戳,重新加載并使用模型

你會(huì)想保存這個(gè)模型钻蔑。在DL4J中保存模型的常規(guī)方法是通過(guò)序列化工具(Java序列化類似于Python的pickling啥刻,將一個(gè)對(duì)象轉(zhuǎn)換成一系列字節(jié))。

        log.info("保存向量....");
        WordVectorSerializer.writeWord2VecModel(vec, "pathToSaveModel.txt");

image.gif

這將將向量保存到一個(gè)名為pathToSaveModel.txt的文件中咪笑,該文件將出現(xiàn)在Word2Vec被訓(xùn)練的目錄的根目錄中可帽。文件中的輸出每行應(yīng)該有一個(gè)單詞,后面是一系列數(shù)字窗怒,它們一起表示它的向量映跟。

為了繼續(xù)使用向量,簡(jiǎn)單地像這樣調(diào)用關(guān)于vec的方法:

Collection<String> kingList = vec.wordsNearest(Arrays.asList("king", "woman"), Arrays.asList("queen"), 10);

image.gif

Word2Vec的詞算術(shù)的經(jīng)典例子是 國(guó)王-皇后=男人-女人扬虚,它的邏輯擴(kuò)展是 國(guó)王-皇后+女人=男人努隙。

上面的例子將把10個(gè)最近的單詞輸出到向量 國(guó)王-皇后+女人 ,這應(yīng)該包括“男人”辜昵。wordsNearest的第一個(gè)參數(shù)必須包括“正”單詞國(guó)王 和女人荸镊,它們具有與之關(guān)聯(lián)的+符號(hào);第二個(gè)參數(shù)包括“負(fù)”單詞皇后堪置,它與負(fù)符號(hào)關(guān)聯(lián)(這里正和負(fù)沒(méi)有情感內(nèi)涵)躬存;第三是你想看的最接近單詞列表的長(zhǎng)度。請(qǐng)記住將此添加到文件的頂部:import java.util.Arrays;

任何數(shù)量的組合都是可能的舀锨,但只有在語(yǔ)料庫(kù)中出現(xiàn)足夠頻繁的查詢?cè)~時(shí)岭洲,它們才會(huì)返回合理的結(jié)果。顯然坎匿,返回相似詞(或文檔)的能力是搜索引擎和推薦引擎的基礎(chǔ)钦椭。

你可以像這樣把向量重新加載到內(nèi)存中:

        Word2Vec word2Vec = WordVectorSerializer.readWord2VecModel("pathToSaveModel.txt");

image.gif

然后,您可以使用Word2Vec作為查找表:

        WeightLookupTable weightLookupTable = word2Vec.lookupTable();
        Iterator<INDArray> vectors = weightLookupTable.vectors();
        INDArray wordVectorMatrix = word2Vec.getWordVectorMatrix("myword");
        double[] wordVector = word2Vec.getWordVector("myword");

image.gif

如果單詞不在詞匯表中碑诉,Word2Vec返回零。

導(dǎo)入Word2Vec模型

在S3托管的谷歌新聞?wù)Z料庫(kù)模型侥锦,我們用來(lái)測(cè)試我們的訓(xùn)練網(wǎng)的準(zhǔn)確性进栽。對(duì)于那些在大型語(yǔ)料庫(kù)上訓(xùn)練當(dāng)前硬件需要很長(zhǎng)時(shí)間的用戶,可以簡(jiǎn)單地下載它來(lái)探索Word2Vec模型茬射,而不需要前奏唤蔗。

如果你用C vectors或Gensimm進(jìn)行訓(xùn)練餐弱,此行將導(dǎo)入模型。

    File gModel = new File("/Developer/Vector Models/GoogleNews-vectors-negative300.bin.gz");
    Word2Vec vec = WordVectorSerializer.readWord2VecModel(gModel);

image.gif

記得添加 import java.io.File;到你引入的包唠帝。

對(duì)于大型模型,你可能會(huì)遇到堆空間的問(wèn)題玄柏。Google模型可能需要多達(dá)10G的RAM襟衰,而JVM只使用256MB的RAM啟動(dòng),因此必須調(diào)整堆空間粪摘。你可以用一個(gè)bash_profile文件(參見(jiàn)我們的故障排查部分)瀑晒,或者通過(guò)IntelliJ本身來(lái)做:

    //Click:
    IntelliJ Preferences > Compiler > Command Line Options 
    //Then paste:
    -Xms1024m
    -Xmx10g
    -XX:MaxPermSize=2g

image.gif

N-grams & Skip-grams

單詞被一次讀入到向量绍坝,并在一定范圍內(nèi)來(lái)回掃描。這些范圍是n-gram苔悦,一個(gè) n-gram是給定語(yǔ)言序列中n個(gè)項(xiàng)目的連續(xù)序列轩褐;它是unigram、bigram玖详、trigram把介、4-gram或5-gram的第n個(gè)版本。skip-gram簡(jiǎn)單地從N-gram中刪除項(xiàng)目蟋座。

Mikolov推廣并在DL4J實(shí)現(xiàn)中使用的skip-gram被證明比其他模型(如連續(xù)詞袋)更精確拗踢,這是因?yàn)樯傻纳舷挛母哂型ㄓ眯浴?/p>

然后將該n-gram輸入到神經(jīng)網(wǎng)絡(luò)以學(xué)習(xí)給定詞向量的重要性;即蜈七,重要性被定義為其實(shí)用性秒拔,作為作為某些更大含義或標(biāo)簽的指示器。

工作實(shí)例

請(qǐng)注意:下面的代碼可能過(guò)時(shí)了飒硅。有關(guān)更新的示例砂缩,請(qǐng)參閱Github上的我們的DL4J示例庫(kù)

既然你已經(jīng)有了一個(gè)關(guān)于如何建立Word2Vec的基本思想三娩,這里有一個(gè)例子庵芭,它是如何與DL4J的API一起使用的:

在按照快速入門的說(shuō)明后,你可以在IntelliJ中打開(kāi)這個(gè)示例并點(diǎn)擊Run運(yùn)行它雀监。如果你在Word2Vec模型中查詢一個(gè)不包含在訓(xùn)練語(yǔ)料庫(kù)的單詞双吆,它將返回NULL。

Word2Vec故障排除與調(diào)整

問(wèn):我有很多這樣的堆棧跟蹤

       java.lang.StackOverflowError: null
       at java.lang.ref.Reference.<init>(Reference.java:254) ~[na:1.8.0_11]
       at java.lang.ref.WeakReference.<init>(WeakReference.java:69) ~[na:1.8.0_11]
       at java.io.ObjectStreamClass$WeakClassKey.<init>(ObjectStreamClass.java:2306) [na:1.8.0_11]
       at java.io.ObjectStreamClass.lookup(ObjectStreamClass.java:322) ~[na:1.8.0_11]
       at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1134) ~[na:1.8.0_11]
       at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548) ~[na:1.8.0_11]

image.gif

答:看看你啟動(dòng)Word2Vec應(yīng)用程序的目錄里面会前。例如好乐,這可以是一個(gè)IntelliJ項(xiàng)目主目錄或在命令行鍵入Java的目錄。它應(yīng)該有一些目錄看起來(lái)像:

       ehcache_auto_created2810726831714447871diskstore  
       ehcache_auto_created4727787669919058795diskstore
       ehcache_auto_created3883187579728988119diskstore  
       ehcache_auto_created9101229611634051478diskstore

image.gif

你可以關(guān)閉你的Word2Vec應(yīng)用程序并嘗試刪除這些目錄瓦宜。

問(wèn):不是所有來(lái)自我原始文本數(shù)據(jù)的單詞都出現(xiàn)在我的Word2Vec對(duì)象中…

答: 試著在你的Word2Vec對(duì)象上通過(guò).layerSize() 來(lái)提高圖層大小蔚万,像這樣

        Word2Vec vec = new Word2Vec.Builder().layerSize(300).windowSize(5)
                .layerSize(300).iterate(iter).tokenizerFactory(t).build();

image.gif

問(wèn):如何加載我的數(shù)據(jù)?為什么訓(xùn)練會(huì)永遠(yuǎn)持續(xù)下去临庇?

答:如果你所有的句子都被作為一個(gè)句子被加載反璃,Word2Vec訓(xùn)練可能需要很長(zhǎng)的時(shí)間。這是因?yàn)閃ord2Vec是一個(gè)句子級(jí)別的算法假夺,所以句子邊界非常重要淮蜈,因?yàn)楣铂F(xiàn)統(tǒng)計(jì)是逐句收集的。(對(duì)于GloVe來(lái)說(shuō)已卷,句子邊界并不重要梧田,因?yàn)樗P(guān)注于語(yǔ)料庫(kù)范圍的共現(xiàn)。對(duì)于許多語(yǔ)料庫(kù),平均句子長(zhǎng)度為六個(gè)單詞柿扣。這意味著在窗口大小為5的情況下肖方,有30個(gè)(隨機(jī)數(shù))回合的skip-gram計(jì)算。如果你忘記指定句子的邊界未状,你可能加載一個(gè)“10000個(gè)單詞”長(zhǎng)的句子俯画。在這種情況下,Word2Vec將為整個(gè)10000個(gè)單詞“句子”嘗試全skip-gram循環(huán)司草。在DL4J的實(shí)現(xiàn)中艰垂,假定一行是一個(gè)句子。你需要插入你自己的句子迭代器和分詞器埋虹。通過(guò)要求你指定你的句子如何結(jié)束猜憎,DL4J仍然是語(yǔ)言不可知論者。UimaSentenceIterator是這樣做的一種方式搔课。使用OpenNLP進(jìn)行句子邊界檢測(cè)胰柑。

問(wèn):為什么把整個(gè)文檔作為一個(gè)“句子”而不是分割成句子時(shí),在性能上有如此不同爬泥?

答:如果平均句子包含6個(gè)單詞柬讨,窗口大小為5,那么理論上最多10個(gè)skipgram回合的次數(shù)是0字袍啡。句子不夠長(zhǎng)踩官,不能用文字表達(dá)完整的窗口。在這句話中所有單詞的粗略最大數(shù)目為5個(gè)skipgram回合境输。但如果你的“句子”有1000k個(gè)單詞的長(zhǎng)度蔗牡,這個(gè)句子中的每個(gè)單詞就有10個(gè)skipgram回合,不包括前5個(gè)和最后5個(gè)嗅剖。因此辩越,你將不得不花費(fèi)大量時(shí)間來(lái)構(gòu)建模型+由于缺少句子邊界,協(xié)同統(tǒng)計(jì)將會(huì)發(fā)生變化信粮。

問(wèn):Word2Vec是如何使用內(nèi)存的黔攒?

答:Word2Vec中的主要內(nèi)存消耗是權(quán)重矩陣。數(shù)學(xué)是簡(jiǎn)單的:?jiǎn)卧~數(shù)x維度數(shù)x 2 x數(shù)據(jù)類型 內(nèi)存占用蒋院。因此,如果使用浮點(diǎn)數(shù)和100維來(lái)構(gòu)建100k字的Word2Vec模型莲绰,那么內(nèi)存占用將是100kx100x2x4(浮點(diǎn)數(shù)大衅劬伞)=80MB RAM,僅用于矩陣+用于字符串蛤签、變量辞友、線程等的一些空間。如果加載預(yù)構(gòu)建的模型,則在構(gòu)建時(shí)間中使用大約1/2的RAM称龙,因此它是40MB RAM留拾。目前使用的最流行的模型是谷歌新聞模型。有3百萬(wàn)字鲫尊,向量大小為300痴柔。這就使我們需要3.6G RAM僅加載模型。而且必須添加3M的字符串疫向,這些字符串在Java中沒(méi)有固定的大小咳蔚。所以,通常是大約4-6GB用于加載模型搔驼,這取決于JVM版本/供應(yīng)商谈火,GC狀態(tài)和月球的相位。

問(wèn):我做了你說(shuō)的每一件事舌涨,結(jié)果還是不對(duì)頭糯耍。

答:確保你正遇到不是正常性問(wèn)題。一些任務(wù)囊嘉,如wordsNearest()温技,默認(rèn)使用標(biāo)準(zhǔn)化的權(quán)重,而其他的則需要非標(biāo)準(zhǔn)化的權(quán)重哗伯。注意這個(gè)區(qū)別荒揣。

用例

谷歌學(xué)者保存了論文記錄,這里引用了Word2Vec的DL4J實(shí)現(xiàn)焊刹。

來(lái)自比利時(shí)的數(shù)據(jù)科學(xué)家Kenny Helsens將Word2Vec的DL4J實(shí)現(xiàn)應(yīng)用于NCBI的在線孟德?tīng)柸祟惱^承(OMIM)數(shù)據(jù)庫(kù)系任。然后,他尋找與alk(一種已知的非小細(xì)胞肺癌的致癌基因)最相似的單詞虐块,Word2vec返回:“nonsmall, carcinomas, carcinoma, mapdkd”俩滥。從那里,他建立了其他癌癥表型和基因型之間的類比贺奠。這只是Word2Vec在大型語(yǔ)料庫(kù)上可以學(xué)習(xí)的一個(gè)例子霜旧。發(fā)現(xiàn)重要疾病新方面的潛力才剛剛開(kāi)始,在醫(yī)學(xué)之外儡率,機(jī)會(huì)也同樣多樣挂据。

Andreas Klintberg在瑞典訓(xùn)練了Word2Vec的DL4J實(shí)現(xiàn),并在媒體上寫(xiě)下了一個(gè)完整的指導(dǎo)儿普。

Word2Vec在信息檢索準(zhǔn)備基于文本的數(shù)據(jù)和問(wèn)答系統(tǒng)中特別有用崎逃,DL4J通過(guò)深度自動(dòng)編碼器來(lái)實(shí)現(xiàn)這些系統(tǒng)。

營(yíng)銷人員可能尋求建立產(chǎn)品間的關(guān)系來(lái)建立推薦引擎眉孩。調(diào)查者可能會(huì)分析一個(gè)社會(huì)圖表个绍,以顯示單個(gè)群體的成員勒葱,或者他們可能必須定位或資助的其他關(guān)系。

Google的 Word2vec 專利

Word2Vec是由Tomas Mikolov領(lǐng)導(dǎo)的谷歌研究團(tuán)隊(duì)介紹的一種計(jì)算單詞向量表示的方法巴柿。谷歌托管了一個(gè)開(kāi)源版本的Word2Vec凛虽,它是在Apache 2許可下發(fā)布的。在2014广恢,Mikolov離開(kāi)谷歌去了Facebook凯旋,并在2015年5月,谷歌被授予獲得此專利袁波,已發(fā)布的版本沒(méi)有廢除Apache許可證瓦阐。

外語(yǔ)

雖然所有語(yǔ)言中的單詞都可以用Word2Vec轉(zhuǎn)換為向量,并且這些向量通過(guò)DL4J學(xué)習(xí)篷牌,但是NLP預(yù)處理可以非常特定于語(yǔ)言睡蟋,并且需要超出我們庫(kù)的工具。斯坦福自然語(yǔ)言處理小組有許多基于Java的工具枷颊,用于語(yǔ)言的分詞戳杀、詞性標(biāo)注和命名實(shí)體識(shí)別,例如普通話夭苗、阿拉伯語(yǔ)信卡、法語(yǔ)、德語(yǔ)和西班牙語(yǔ)题造。對(duì)于日本人來(lái)說(shuō)傍菇,像Kuromoji之類的NLP工具是有用的。其他的外語(yǔ)資源界赔,包括文本語(yǔ)料庫(kù)丢习,都在這里

GloVe: 全局向量

加載和保存GloVe模型到Word2Vec可以這樣做:

        WordVectors wordVectors = WordVectorSerializer.loadTxtVectors(new File("glove.6B.50d.txt"));

image.gif

序列向量

DL4J具有一個(gè)名為SequenceVectors的類淮悼,它是單詞向量之上的抽象級(jí)別咐低,并且允許你從任何序列中提取特征,包括社交媒體概要袜腥、事務(wù)见擦、蛋白質(zhì)等。 如果數(shù)據(jù)可以被描述為序列羹令,它可以通過(guò)skip-gram和層次化的softmax與AbstractVectors類來(lái)學(xué)習(xí)鲤屡。這與深度算法相兼容,也在DL4J中實(shí)現(xiàn)福侈。

DL4L的Word2Vec特征

  • 模型序列化/反序列化 被添加后的權(quán)重會(huì)更新酒来。也就是說(shuō),你可以通過(guò)調(diào)用loadFullModel癌刽、向其中添加TokenizerFactory和SentenceIterator役首、以及調(diào)用還原的模型上的fit()來(lái)使用200GB的新文本更新模型狀態(tài)。
  • 用于詞匯構(gòu)建的多個(gè)數(shù)據(jù)源的選項(xiàng)被添加显拜。
  • 訓(xùn)練和迭代可以單獨(dú)指定衡奥,盡管它們通常都是“1”。
  • Word2Vec.Builder 有這個(gè)選項(xiàng): hugeModelExpected. 如果設(shè)為 true, 在構(gòu)建過(guò)程中远荠,詞匯將被周期性的截?cái)唷?/li>
  • minWordFrequency 有助于忽略語(yǔ)料庫(kù)中的稀有詞矮固,可以排除任何數(shù)量的詞來(lái)定制。
  • 兩個(gè)新的WordVectorsSerialiaztion 方法已被介紹: writeFullModelloadFullModel. 這些保存和加載一個(gè)完整的模型狀態(tài)譬淳。
  • 一個(gè)體面的工作站應(yīng)該能夠處理一個(gè)有幾百萬(wàn)單詞的詞匯量档址。DL4J的Word2Vec實(shí)現(xiàn)可以在一臺(tái)機(jī)器上對(duì)兆兆字節(jié)的數(shù)據(jù)進(jìn)行建模。大致來(lái)說(shuō)邻梆,計(jì)算公式 是:vectorSize * 4 * 3 * vocab.size()守伸。

Doc2vec & 其它 NLP 資源

文學(xué)中的Word2Vec

It's like numbers are language, like all the letters in the language are turned into numbers, and so it's something that everyone understands the same way. You lose the sounds of the letters and whether they click or pop or touch the palate, or go ooh or aah, and anything that can be misread or con you with its music or the pictures it puts in your mind, all of that is gone, along with the accent, and you have a new understanding entirely, a language of numbers, and everything becomes as clear to everyone as the writing on the wall. So as I say there comes a certain time for the reading of the numbers.
    -- E.L. Doctorow, Billy Bathgate

image.gif

翻譯:風(fēng)一樣的男子

image

如果您覺(jué)得我的文章給了您幫助,請(qǐng)為我買一杯飲料吧剂娄!以下是我的支付寶蠢涝,意思一下我將非常感激!

image
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末阅懦,一起剝皮案震驚了整個(gè)濱河市和二,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌耳胎,老刑警劉巖惯吕,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異场晶,居然都是意外死亡混埠,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門诗轻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)钳宪,“玉大人,你說(shuō)我怎么就攤上這事扳炬±粲保” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵恨樟,是天一觀的道長(zhǎng)半醉。 經(jīng)常有香客問(wèn)我,道長(zhǎng)劝术,這世上最難降的妖魔是什么缩多? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任呆奕,我火速辦了婚禮,結(jié)果婚禮上衬吆,老公的妹妹穿的比我還像新娘梁钾。我一直安慰自己,他們只是感情好逊抡,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布姆泻。 她就那樣靜靜地躺著,像睡著了一般冒嫡。 火紅的嫁衣襯著肌膚如雪拇勃。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,144評(píng)論 1 285
  • 那天孝凌,我揣著相機(jī)與錄音方咆,去河邊找鬼。 笑死蟀架,一個(gè)胖子當(dāng)著我的面吹牛峻呛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播辜窑,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼钩述,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了穆碎?” 一聲冷哼從身側(cè)響起牙勘,我...
    開(kāi)封第一講書(shū)人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎所禀,沒(méi)想到半個(gè)月后方面,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡色徘,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年恭金,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片褂策。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡横腿,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出斤寂,到底是詐尸還是另有隱情耿焊,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布遍搞,位于F島的核電站罗侯,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏溪猿。R本人自食惡果不足惜钩杰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一纫塌、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧讲弄,春花似錦护戳、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)抗悍。三九已至驹饺,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間缴渊,已是汗流浹背赏壹。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留衔沼,地道東北人蝌借。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像指蚁,于是被迫代替她去往敵國(guó)和親菩佑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容