gensim里內(nèi)置了word2vec模型,訓(xùn)練和使用都很方便。但word2vec本身這個(gè)模型的設(shè)計(jì)是很精妙的,自己從頭使用tensorflow實(shí)現(xiàn)一遍很有意義。 http:///dc/text8.zip from aipack.datasets import text8 讀進(jìn)來的text8約有1700W個(gè)詞,排重后得到25W+個(gè)詞,我們只保留50000個(gè)高頻的,其余用UNK代替。 build_words_dataset返回:data:詞的下標(biāo)list,count:{詞:詞頻},dictionary:{詞:詞下標(biāo)},reverse_dictionary:{詞下標(biāo):詞} 有了原始的數(shù)據(jù)集,那就可以開始建模。 Word2Vec模型中,主要有Skip-Gram和CBOW兩種模型,從直觀上理解,Skip-Gram是給定input word來預(yù)測上下文。而CBOW是給定上下文,來預(yù)測input word,如下圖: batch, labels, data_index = generate_skip_gram_batch(data=data,batch_size=8,num_skips=4,skip_window=2,data_index=0) data就是之前取出來的word_list的下標(biāo)數(shù)組,每批取的pair數(shù)batch_size=8,num_skip=4是以這個(gè)詞為中心,取對的次數(shù) skip_window=2,是以當(dāng)前詞為中心,前后兩個(gè)詞(往前看包含當(dāng)前詞本身)。 下面是建模,官方示例損失函數(shù)用到了如下這個(gè): def nce_loss(vocab_size,embedding_size,embed,train_labels,num_sampled): 輸入N*embedding_size的詞嵌入之后的向量,與input_labels=[N,1]之間的loss。按常規(guī)情況,input_labels用one_hot得擴(kuò)展成[N,vocab_size]維,但vocab_size-1維都是負(fù)樣本。這樣使用負(fù)采樣,主要是減少計(jì)算量為[N,64]。 后面的訓(xùn)練就是正常輸入數(shù)據(jù),反向傳播,迭代了。 在迭代25W輪之后,看下相似度,還是不錯(cuò)的: 從直觀的視角,還原一下skip-gram的原理: 1,每批選擇N個(gè)字的下標(biāo),對應(yīng)的期望輸出是這N個(gè)字周圍的字(下標(biāo))。 2,對輸入進(jìn)行embedding,得到[N,embedding_size]的矩陣。 3,對這個(gè)embdding的結(jié)果,與期望輸出[N,1]計(jì)算負(fù)采樣損失。 關(guān)于作者:魏佳斌,互聯(lián)網(wǎng)產(chǎn)品/技術(shù)總監(jiān),北京大學(xué)光華管理學(xué)院(MBA),特許金融分析師(CFA),資深產(chǎn)品經(jīng)理/碼農(nóng)。偏愛python,深度關(guān)注互聯(lián)網(wǎng)趨勢,人工智能,AI金融量化。致力于使用最前沿的認(rèn)知技術(shù)去理解這個(gè)復(fù)雜的世界。 |
|