1. 程式人生 > >python︱gensim訓練word2vec及相關函式與功能理解

python︱gensim訓練word2vec及相關函式與功能理解

一、gensim介紹

gensim是一款強大的自然語言處理工具,裡面包括N多常見模型:

  • 基本的語料處理工具
  • LSI
  • LDA
  • HDP
  • DTM
  • DIM
  • TF-IDF
  • word2vec、paragraph2vec
    .

二、訓練模型

1、訓練

最簡單的訓練方式:

# 最簡單的開始
import gensim
sentences = [['first', 'sentence'], ['second', 'sentence','is']]

# 模型訓練
model = gensim.models.Word2Vec(sentences, min_count=1)
    # min_count,頻數閾值,大於等於1的保留
    # size,神經網路 NN 層單元數,它也對應了訓練演算法的自由程度
    # workers=4,default = 1 worker = no parallelization 只有在機器已安裝 Cython 情況下才會起到作用。如沒有 Cython,則只能單核執行。

第二種訓練方式:

# 第二種訓練方式
new_model = gensim.models.Word2Vec(min_count=1)  # 先啟動一個空模型 an empty model
new_model.build_vocab(sentences)                 # can be a non-repeatable, 1-pass generator     
new_model.train(sentences, total_examples=new_model.corpus_count, epochs=new_model.iter)                       
# can be a non-repeatable, 1-pass generator

案例:

#encoding=utf-8
from gensim.models import word2vec
sentences=word2vec.Text8Corpus(u'分詞後的爽膚水評論.txt')
model=word2vec.Word2Vec(sentences, size=50)

y2=model.similarity(u"好", u"還行")
print(y2)

for i in model.most_similar(u"滋潤"):
    print i[0],i[1]

txt檔案是已經分好詞的5W條評論,訓練模型只需一句話:

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

第一個引數是訓練語料,第二個引數是小於該數的單詞會被剔除,預設值為5,
第三個引數是神經網路的隱藏層單元數,預設為100

2、模型使用

# 根據詞向量求相似
model.similarity('first','is')    # 兩個詞的相似性距離
model.most_similar(positive=['first', 'second'], negative=['sentence'], topn=1)  # 類比的防護四
model.doesnt_match("input is lunch he sentence cat".split())                   # 找出不匹配的詞語

如何檢視模型內部詞向量內容:

# 詞向量查詢
model['first'] 

.
3、模型匯出與匯入

最簡單的匯入與匯出

# 模型儲存與載入
model.save('/tmp/mymodel')
new_model = gensim.models.Word2Vec.load('/tmp/mymodel')
odel = Word2Vec.load_word2vec_format('/tmp/vectors.txt', binary=False)  # 載入 .txt檔案
# using gzipped/bz2 input works too, no need to unzip:
model = Word2Vec.load_word2vec_format('/tmp/vectors.bin.gz', binary=True)  # 載入 .bin檔案

word2vec = gensim.models.word2vec.Word2Vec(sentences(), size=256, window=10, min_count=64, sg=1, hs=1, iter=10, workers=25)
word2vec.save('word2vec_wx')

word2vec.save即可匯出檔案,這邊沒有匯出為.bin
.

model = gensim.models.Word2Vec.load('xxx/word2vec_wx')
pd.Series(model.most_similar(u'微信',topn = 360000))

gensim.models.Word2Vec.load的辦法匯入

其中的Numpy,可以用numpy.load:

import numpy
word_2x = numpy.load('xxx/word2vec_wx.wv.syn0.npy')

還有其他的匯入方式:

from gensim.models.keyedvectors import KeyedVectors
word_vectors = KeyedVectors.load_word2vec_format('/tmp/vectors.txt', binary=False)  # C text format
word_vectors = KeyedVectors.load_word2vec_format('/tmp/vectors.bin', binary=True)  # C binary format

匯入txt格式+bin格式。

其他匯出方式:

from gensim.keyedvectors import KeyedVectors
# save
model.save(fname) # 只有這樣存才能繼續訓練! 
model.wv.save_word2vec_format(outfile + '.model.bin', binary=True)  # C binary format 磁碟空間比上一方法減半
model.wv.save_word2vec_format(outfile + '.model.txt', binary=False) # C text format 磁碟空間大,與方法一樣

# load
model = gensim.models.Word2Vec.load(fname)  
word_vectors = KeyedVectors.load_word2vec_format('/tmp/vectors.txt', binary=False)
word_vectors = KeyedVectors.load_word2vec_format('/tmp/vectors.bin', binary=True)

# 最省記憶體的載入方法
model = gensim.models.Word2Vec.load('model path')
word_vectors = model.wv
del model
word_vectors.init_sims(replace=True)

來源:簡書,其中:如果你不打算進一步訓練模型,呼叫init_sims將使得模型的儲存更加高效

.

4、增量訓練

model = gensim.models.Word2Vec.load('/tmp/mymodel')
model.train(more_sentences)

不能對C生成的模型進行再訓練.
.

# 增量訓練
model = gensim.models.Word2Vec.load(temp_path)
more_sentences = [['Advanced', 'users', 'can', 'load', 'a', 'model', 'and', 'continue', 'training', 'it', 'with', 'more', 'sentences']]
model.build_vocab(more_sentences, update=True)
model.train(more_sentences, total_examples=model.corpus_count, epochs=model.iter)

.

5、bow2vec + TFIDF模型

5.1 Bow2vec

主要內容為:
拆分句子為單詞顆粒,記號化;
生成詞典;
生成稀疏文件矩陣

documents = ["Human machine interface for lab abc computer applications",
             "A survey of user opinion of computer system response time",
             "The EPS user interface management system",
             "System and human system engineering testing of EPS",              
             "Relation of user perceived response time to error measurement",
             "The generation of random binary unordered trees",
             "The intersection graph of paths in trees",
             "Graph minors IV Widths of trees and well quasi ordering",
             "Graph minors A survey"]

# 分詞並根據詞頻剔除
# remove common words and tokenize
stoplist = set('for a of the and to in'.split())
texts = [[word for word in document.lower().split() if word not in stoplist]
         for document in documents]

生成詞語列表:

[['human', 'machine', 'interface', 'lab', 'abc', 'computer', 'applications'],
 ['survey', 'user', 'opinion', 'computer', 'system', 'response', 'time'],
 ['eps', 'user', 'interface', 'management', 'system'],
 ['system', 'human', 'system', 'engineering', 'testing', 'eps'],
 ['relation', 'user', 'perceived', 'response', 'time', 'error', 'measurement'],
 ['generation', 'random', 'binary', 'unordered', 'trees'],
 ['intersection', 'graph', 'paths', 'trees'],
 ['graph', 'minors', 'iv', 'widths', 'trees', 'well', 'quasi', 'ordering'],
 ['graph', 'minors', 'survey']]

生成詞典:

# 詞典生成
dictionary = corpora.Dictionary(texts)
dictionary.save(os.path.join(TEMP_FOLDER, 'deerwester.dict'))  # store the dictionary, for future reference
print(dictionary)
print(dictionary.token2id)  # 檢視詞典中所有詞

稀疏文件矩陣的生成:

# 單句bow 生成
new_doc = "Human computer interaction Human"
new_vec = dictionary.doc2bow(new_doc.lower().split())
print(new_vec)  
    # the word "interaction" does not appear in the dictionary and is ignored
    # [(0, 1), (1, 1)] ,詞典(dictionary)中第0個詞,出現的頻數為1(當前句子),
    # 第1個詞,出現的頻數為1
    
# 多句bow 生成
[dictionary.doc2bow(text) for text in texts]  # 當前句子的詞ID + 詞頻

5.2 tfidf

from gensim import corpora, models, similarities
corpus = [[(0, 1.0), (1, 1.0), (2, 1.0)],
          [(2, 1.0), (3, 1.0), (4, 1.0), (5, 1.0), (6, 1.0), (8, 1.0)],
          [(1, 1.0), (3, 1.0), (4, 1.0), (7, 1.0)],
          [(0, 1.0), (4, 2.0), (7, 1.0)],
          [(3, 1.0), (5, 1.0), (6, 1.0)],
          [(9, 1.0)],
          [(9, 1.0), (10, 1.0)],
          [(9, 1.0), (10, 1.0), (11, 1.0)],
          [(8, 1.0), (10, 1.0), (11, 1.0)]]
tfidf = models.TfidfModel(corpus)

# 詞袋模型,實踐
vec = [(0, 1), (4, 1),(9, 1)]
print(tfidf[vec])
>>>  [(0, 0.695546419520037), (4, 0.5080429008916749), (9, 0.5080429008916749)]

查詢vec中,0,4,9號三個詞的TFIDF值。同時進行轉化,把之前的文件矩陣中的詞頻變成了TFIDF值。

利用tfidf求相似:

# 求相似
index = similarities.SparseMatrixSimilarity(tfidf[corpus], num_features=12)
vec = [(0, 1), (4, 1),(9, 1)]
sims = index[tfidf[vec]]
print(list(enumerate(sims)))
>>>[(0, 0.40157393), (1, 0.16485332), (2, 0.21189235), (3, 0.70710677), (4, 0.0), (5, 0.5080429), (6, 0.35924056), (7, 0.25810757), (8, 0.0)]

對corpus的9個文件建立文件級別的索引,vec是一個新文件的詞語的詞袋內容,sim就是該vec向量對corpus中的九個文件的相似性。

索引的匯出與載入:

index.save('/tmp/deerwester.index')
index = similarities.MatrixSimilarity.load('/tmp/deerwester.index')

5.3 繼續轉換

潛在語義索引(LSI) 將Tf-Idf語料轉化為一個潛在2-D空間

lsi = models.LsiModel(tfidf[corpus], id2word=dictionary, num_topics=2) # 初始化一個LSI轉換
corpus_lsi = lsi[tfidf[corpus]] # 在原始語料庫上加上雙重包裝: bow->tfidf->fold-in-lsi

設定了num_topics=2,
利用models.LsiModel.print_topics()來檢查一下這個過程到底產生了什麼變化吧:

lsi.print_topics(2)

根據LSI來看,“tree”、“graph”、“minors”都是相關的詞語(而且在第一主題的方向上貢獻最多),而第二主題實際上與所有的詞語都有關係。如我們所料,前五個文件與第二個主題的關聯更強,而其他四個文件與第一個主題關聯最強:

>>> for doc in corpus_lsi: # both bow->tfidf and tfidf->lsi transformations are actually executed here, on the fly
...     print(doc)
[(0, -0.066), (1, 0.520)] # "Human machine interface for lab abc computer applications"
[(0, -0.197), (1, 0.761)] # "A survey of user opinion of computer system response time"
[(0, -0.090), (1, 0.724)] # "The EPS user interface management system"
[(0, -0.076), (1, 0.632)] # "System and human system engineering testing of EPS"
[(0, -0.102), (1, 0.574)] # "Relation of user perceived response time to error measurement"
[(0, -0.703), (1, -0.161)] # "The generation of random binary unordered trees"
[(0, -0.877), (1, -0.168)] # "The intersection graph of paths in trees"
[(0, -0.910), (1, -0.141)] # "Graph minors IV Widths of trees and well quasi ordering"
[(0, -0.617), (1, 0.054)] # "Graph minors A survey"

相關轉換

詞頻-逆文件頻(Term Frequency * Inverse Document Frequency, Tf-Idf)

一個詞袋形式(整數值)的訓練語料庫來實現初始化。

model = tfidfmodel.TfidfModel(bow_corpus, normalize=True)

潛在語義索引(Latent Semantic Indexing,LSI,or sometimes LSA)

將文件從詞袋或TfIdf權重空間(更好)轉化為一個低維的潛在空間。在真正的語料庫上,推薦200-500的目標維度為“金標準”。

>>> model = lsimodel.LsiModel(tfidf_corpus, id2word=dictionary, num_topics=300)

LSI訓練的獨特之處是我們能在任何繼續“訓練”,僅需提供更多的訓練文字。這是通過對底層模型進行增量更新,這個過程被稱為“線上訓練”。正因為它的這個特性,輸入文件流可以是無限大——我們能在以只讀的方式使用計算好的模型的同時,還能在新文件到達時一直“餵食”給LSI“消化”!

>>> model.add_documents(another_tfidf_corpus) # 現在LSI已經使用tfidf_corpus + another_tfidf_corpus進行過訓練了
>>> lsi_vec = model[tfidf_vec] # 將新文件轉化到LSI空間不會影響該模型
>>> ...
>>> model.add_documents(more_documents) # tfidf_corpus + another_tfidf_corpus + more_documents
>>> lsi_vec = model[tfidf_vec]

隨機對映(Random Projections,RP)

目的在於減小空維度。這是一個非常高效(對CPU和記憶體都很友好)方法,通過丟擲一點點隨機性,來近似得到兩個文件之間的Tfidf距離。推薦目標維度也是成百上千,具體數值要視你的資料集大小而定。


>>> model = rpmodel.RpModel(tfidf_corpus, num_topics=500)

隱含狄利克雷分配(Latent Dirichlet Allocation, LDA)

也是將詞袋計數轉化為一個低維主題空間的轉換。LDA是LSA(也叫多項式PCA)的概率擴充套件,因此LDA的主題可以被解釋為詞語的概率分佈。這些分散式從訓練語料庫中自動推斷的,就像LSA一樣。相應地,文件可以被解釋為這些主題的一個(軟)混合(又是就像LSA一樣)。

>>> model = ldamodel.LdaModel(bow_corpus, id2word=dictionary, num_topics=100)

gensim使用一個基於[2]的快速的線上LDA引數估計實現,修改並使其可以在計算機叢集上以分散式模式執行。

分層狄利克雷過程(Hierarchical Dirichlet Process,HDP)
是一個無引數貝葉斯方法(注意:這裡沒有num_topics引數):

>>> model = hdpmodel.HdpModel(bow_corpus, id2word=dictionary)

gensim使用一種基於[3]的快速線上來實現。該演算法是新加入gensim的,並且還是一種粗糙的學術邊緣產品——小心使用。
增加新的VSM轉化(例如新的權重方案)相當平常;參見API參考或者直接參考我們的原始碼以獲取資訊與幫助。

三、gensim訓練好的word2vec使用

1、相似性

持數種單詞相似度任務:
相似詞+相似係數(model.most_similar)、model.doesnt_match、model.similarity(兩兩相似)

model.most_similar(positive=['woman', 'king'], negative=['man'], topn=1)
[('queen', 0.50882536)]

model.most_similar(positive=‘woman’, topn=topn, restrict_vocab=restrict_vocab)  # 直接給入詞
model.most_similar(positive=[vector], topn=topn, restrict_vocab=restrict_vocab)  # 直接給入向量

model.doesnt_match("breakfast cereal dinner lunch".split())
'cereal'

model.similarity('woman', 'man')
.73723527

.
2、詞向量

通過以下方式來得到單詞的向量:

model['computer']  # raw NumPy vector of a word
array([-0.00449447, -0.00310097,  0.02421786, ...], dtype=float32)

3、 詞向量表

model.wv.vocab.keys()

.

案例一:800萬微信語料訓練

訓練過程:

import gensim, logging
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)

import pymongo
import hashlib

db = pymongo.MongoClient('172.16.0.101').weixin.text_articles_words
md5 = lambda s: hashlib.md5(s).hexdigest()
class sentences:
    def __iter__(self):
        texts_set = set()
        for a in db.find(no_cursor_timeout=True):
            if md5(a['text'].encode('utf-8')) in texts_set:
                continue
            else:
                texts_set.add(md5(a['text'].encode('utf-8')))
                yield a['words']
        print u'最終計算了%s篇文章'%len(texts_set)

word2vec = gensim.models.word2vec.Word2Vec(sentences(), size=256, window=10, min_count=64, sg=1, hs=1, iter=10, workers=25)
word2vec.save('word2vec_wx')

這裡引入hashlib.md5是為了對文章進行去重(本來1000萬篇文章,去重後得到800萬),而這個步驟不是必要的。
.

案例二:字向量與詞向量的訓練

# 訓練詞向量
def train_w2v_model(type='article', min_freq=5, size=100):
    sentences = []

    if type == 'char':
        corpus = pd.concat((train_df['article'], test_df['article']))
    elif type == 'word':
        corpus = pd.concat((train_df['word_seg'], test_df['word_seg']))
    for e in tqdm(corpus):
        sentences.append([i for i in e.strip().split() if i])
    print('訓練集語料:', len(corpus))
    print('總長度: ', len(sentences))
    model = Word2Vec(sentences, size=size, window=5, min_count=min_freq)
    model.itos = {}
    model.stoi = {}
    model.embedding = {}
    
    print('儲存模型...')
    for k in tqdm(model.wv.vocab.keys()):
        model.itos[model.wv.vocab[k].index] = k
        model.stoi[k] = model.wv.vocab[k].index
        model.embedding[model.wv.vocab[k].index] = model.wv[k]

    model.save('../../data/word2vec-models/word2vec.{}.{}d.mfreq{}.model'.format(type, size, min_freq))
    return model
model = train_w2v_model(type='char', size=100)
model = train_w2v_model(type='word', size=100)
# model.wv.save_word2vec_format('../../data/laozhu-word-300d', binary=False)
# train_df[:3]
print('OK')

參考於:

**公眾號“素質雲筆記”定期更新部落格內容:**
![這裡寫圖片描述](https://img-blog.csdn.net/20180226155348545?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc2luYXRfMjY5MTczODM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)

相關推薦

pythongensim訓練word2vec相關函式功能理解

一、gensim介紹 gensim是一款強大的自然語言處理工具,裡面包括N多常見模型: 基本的語料處理工具 LSI LDA HDP DTM DIM TF-IDF word2vec、paragraph2vec . 二、訓練模型 1、訓練 最簡單的訓練方

python序列之元組概念相關函式總結(一)

元組是序列的一種,元組是不可變序列(不能修改,替換),但可進行查詢,增添;元組的建立語法很簡單:用逗號分隔一些值,用圓括號括起來,元組就建立了。 1.先來一個簡單的元組:(圓括號也可以不帶) tou

Python元組相關函式

元組 1.tuple元組的用法 元組也是python內建一個容器類,元組中的資料一旦確定就不可更改,不能進行新增、刪除、修改的操作 可以認為元組就是一個不可變的列表(list) 2.宣告元組 # 如

python序列之元組的概念相關函式的總結(二)

接著上篇沒寫完的,上篇沒看的建議從上篇開始看,是按順序寫的. 這裡引入一道題,方便大家理解;Write a Python program to convert a tuple to a string.(用python將元組轉化成字串) 程式碼: tup = ('e',

Linux網路程式設計:socket程式設計簡介、網路位元組序相關函式

Socket(套接字) socket可以看成是使用者程序與核心網路協議棧的程式設計介面(API函式)。 socket不僅可以用於本機的程序間通訊,還可以用於網路上不同主機的程序間通訊。 IPv4套接字地址結構 IPv4套接字地址結構通常也稱為“網際套接字地址結構”,它以

win7 python3.5 採用gensim訓練word2vec,生成wiki.zh.text.model

0,如果您覺得操作麻煩,可以直接直接下載生成好的wiki.zh.text.model模型      https://download.csdn.net/download/luolinll1212/10640451 1,下載中文維基百科 https://

Python中常用操作字串的函式方法總結

本文轉載自:https://www.jb51.net/article/79196.htm Python中常用操作字串的函式與方法總結 這篇文章主要介紹了Python中常用操作字串的函式與方法總結,包括字串的格式化輸出與拼接等基礎知識,需要的朋友可以參考下 例如這樣一個字串 Python,

python 學習彙總59:高階函式類的關係(初級學習- tcy)

 目錄:  1. class定義 2. 內部類 3.外部定義函式 4.高階函式與類的關係 5.物件記憶體管理 6.類作用域 7.使用輸出引數 8.類屬性 9.類特性 10.描述符 11.檢視類屬性 12.繼承 13.型別檢測測試,檢視父子類 15.元類 16.基類 17.類裝

python自動化框架構思相關技術的學習

Python selenium —— selenium與自動化測試成神之路 忽然想談談自動化的學習路徑,因為發現很多人總是急於求成,不懂該如何學習。 在群裡總是會遇到很多人問低階問題,寫了一個selenium指令碼,卻執行失敗,跑到群裡來問,大神,這裡為什麼會報錯?很多都是明顯的語法問題,一問方

Python多執行緒中join函式setDaemon函式使用說明

      在Python多執行緒程式設計的時候,經常需要用到join函式和setDaemon函式。之前對這兩個函式一直理解不是很到位。今天查閱了很多資料,對兩個函式的認識更加的深入一些了。       join([timeout])可以參考Python文件說明。大概意思就

(87)--Python資料分析:指數密度函式指數分佈圖

# 指數密度函式與指數分佈圖 lambd = 0.5 x = np.arange(0,15,0.1) y = lambd*np.exp(-lambd*x) plt.plot(x,y) plt.title

Python正則表示式match函式的用法

正則表示式(Regular Expression)是使用單個字串來描述、匹配一系列語法規則的字串。簡稱RE。 RE是爬蟲的基礎模組,可以用於驗證電話號碼,身份證號,郵箱,使用者名稱和密碼,url地址等。 操作步驟 呼叫re模組(python內嵌的包) i

gensim訓練word2vec和doc2vec

word2vec和doc2vec是做NLP過程中經常使用的方法。用向量表示詞彙這種做法由來已久,最早使用的是one-hot向量,即只有一個維度為1,其餘維度都為0,但這種做法有很多缺陷,過多的維度會導致資料處理的困難,而且這種表示方法無法體現詞所在的上下文關係。於是便有了wo

wchar_t介紹相關函式

寬字元函式 普通C函式        函式描述  iswalnum() isalnum() 測試字元是否為數字或字母  iswalpha() isalpha() 測試字元是否是字母  iswcntrl() iscntrl() 測試字元是否是控制符  iswdigit() isdigit() 測試字元是否為數

相關函式互相關函式

      最近做相關濾波追蹤的時候,遇到了瓶頸,所以想從頭到尾理一理基礎知識。 1、概念       相關函式是描述訊號X(s),Y(t)(這兩個訊號可以是隨機的,也可以是確定的)在任意兩個不同時刻s、t的取值之間的相關程度。兩個訊號之間的相似性大小用相關係數來衡量。定義

Python學習筆記 —— 字串常用函式

在Python中沒有單字元型別,所以單個字元也是作為一個字串來使用的 Python字串要求掌握點 引號、雙引號、三引號區別點及使用 轉義字元 字串運算子 字串格式化

NSIS文字字串函式標頭檔案介紹

轉自 http://hi.csdn.net/jinglidong 文字函式,顧名思義就是處理字串的函式。使用這些字串函式前,必須先包含標頭檔案WordFunc.nsh。該標頭檔案目前包含如下一些函式:WordFind、WordFind2X、WordFind3X、WordRe

利用中文維基語料和Gensim訓練 Word2Vec 的步驟

word2vec 包括CBOW 和 Skip-gram,它的相關原理網上很多,這裡就不多說了。簡單來說,word2vec是自然語言中的字詞轉為計算機可以理解的稠密向量,是one-hot詞彙表的降維表示,代表每個詞的特徵以及保持住了詞彙間的關係。此處記錄將中文詞彙

Linux C的檔案操作相關函式

一、Linux檔案的屬性及檔案的分類 二、檔案描述符的概念及作用 三、系統呼叫的概念 三、不帶快取的檔案I/O操作的相關函式 四、帶快取的檔案I/O操作的相關函式 一、Linux檔案的屬性 檔案的屬性: 我們在Gcc編譯器輸入“ ls  -al"指令時,除了有不同

佇列(連結串列實現)概念相關函式

一. 連結串列佇列 特殊的單鏈表,只在單鏈表上進行頭刪尾插的操作 二. 相關函式 對於佇列具體概念不太清楚的同學可以參考 順序表實現的資料結構佇列 由順序表實現的佇列程式結構相對來說比較簡單,可以鞏固一下基礎 連結串列定義的佇列結構