函數說明:
1. from gensim.model import word2vec 構建模型 word2vec(corpus_token, size=feature_size, min_count=min_count, window=window, sample=sample)
參數說明:corpus_token已經進行切分的列表數據,數據格式是list of list , size表示的是特征向量的維度,即映射的維度, min_count表示最小的計數詞,如果小於這個數的詞,將不進行統計, window表示滑動窗口,表示滑動窗口的大小,用於構造訓練集和測試集, sample表示對出現次數頻繁的詞進行一個隨機下采樣
2. model.wv['sky'] 表示輸出sky這個詞的特征映射結果
3.model.wv.index2words 輸出經過映射后的特征名,輸出經過映射詞的名字
這里簡要的說明一下個人的理解
CBOW是word2vec的一種基礎模型,他是通過選取一個詞前后c個詞進行訓練
訓練數據:一個詞的前后2c個詞做為訓練
標簽:當前這個詞作為標簽值
最后的輸出結果是前一個隱含層的輸出,即特征的個數,這個的特征是4即存在4個維度值
如果對4個特征做降維,降成2維,我們可以發現詞義相似的詞會被放在相近的位置上
word2vec使用每一個特征向量詞的平均用最為最終的特征表示
word2vec主要是構建了霍夫曼樹用來取代softmax最后一個神經元的參數跟新
操作過程:
第一步:
首先使用最大似然估計 ∑p = yi*pi + (1-yi) * pi
然后對其根絕∑p/dtheta 進行求導操作, 獲得梯度的方向。
第二步:
建立一顆霍夫曼樹:每個葉子節點的個數是Xw = 1/2c∑xi 表示這個詞左右兩邊c個詞進行加和,xi表示初始值的one-hot編碼
通過梯度上升法:來更新thetaj 和 Xw
thetaj = thetaj + a * g * Xw # a表示步長, g表示每個參數的梯度方向, Xw表示當前的值
Xw = 0 + g * thetaj # g表示每個參數的梯度方向, thetaj表示當前的梯度值
由於左子樹的權重值大於右子樹,左邊的是sigmoid大於0.5的,右邊是sigmoid小於0.5的
因此我們很容易找出sigmoid值最大的那個樹(感覺有點點不是很理解,這么做的目的)
代碼:
第一步:DataFrame化數據
第二步:進行分詞和去除停用詞,使用' '.join連接列表
第三步:np.vectorize 向量化函數和調用函數進行停用詞的去除
第四步:構建gensim.models import word2vec 構造單個詞的特征向量,使用model.wv['sky']
第五步:對第三步的字符串進行切分,將切分后的數據送入到word2vec建立模型,使用model.wv.index2word打印出當前的特征名,使用循環找出每個列表中詞的特征向量,最后對每個列表中的詞做一個特征向量的平均,作為列表的特征向量
import numpy as np import pandas as pd import matplotlib.pyplot as plt import re corpus = ['The sky is blue and beautiful.', 'Love this blue and beautiful sky!', 'The quick brown fox jumps over the lazy dog.', 'The brown fox is quick and the blue dog is lazy!', 'The sky is very blue and the sky is very beautiful today', 'The dog is lazy but the brown fox is quick!' ] labels = ['weather', 'weather', 'animals', 'animals', 'weather', 'animals'] # 第一步:進行DataFrame化操作 corpus = np.array(corpus) corpus_df = pd.DataFrame({'Document': corpus, 'category': labels}) # 第二步:進行分詞和停用詞的去除 import nltk stopwords = nltk.corpus.stopwords.words('english') wps = nltk.WordPunctTokenizer() def Normalize_corpus(doc): tokens = re.findall(r'[a-zA-Z0-9]+', doc.lower()) doc = [token for token in tokens if token not in stopwords] doc = ' '.join(doc) return doc # 第三步:向量化函數,調用函數進行分詞和停用詞的去除 Normalize_corpus = np.vectorize(Normalize_corpus) corpus_array = Normalize_corpus(corpus) # 第四步:對單個詞計算word2vec特征向量 from gensim.models import word2vec corpus_token = [wps.tokenize(corpus) for corpus in corpus_array] print(corpus_token) # 特征的維度 feature_size = 10 # 最小的統計個數,小於這個數就不進行統計 min_count = 1 # 滑動窗口 window = 10 # 對出現次數頻繁的詞進行隨機下采樣操作 sample = 1e-3 model = word2vec.Word2Vec(corpus_token, size=feature_size, min_count=min_count, window=window, sample=sample) print(model.wv.index2word) # 第五步:對每一個corpus做平均的word2vec特征向量 def word2vec_corpus(corpuses, num_size=10): corpus_tokens = [wps.tokenize(corpus) for corpus in corpuses] model = word2vec.Word2Vec(corpus_tokens, size=num_size, min_count=min_count, window=window, sample=sample) vocabulary = model.wv.index2word score_list = [] for corpus_token in corpus_tokens: count_time = 0 score_array = np.zeros([10]) for word in corpus_token: if word in vocabulary: count_time += 1 score_array += model.wv[word] score_array = score_array / count_time score_list.append(list(score_array)) return score_list print(np.shape(word2vec_corpus(corpus_array, num_size=10)))
部分的特征數據:我們可以看出維度為(6, 10)上述的特征是6個,每個特征的維度為10