應(yīng)用場(chǎng)景
假設(shè)你有一個(gè)商品的數(shù)據(jù)庫(kù),比如:
商品名稱 | 價(jià)格 |
---|---|
椅子 | 200元/個(gè) |
香蕉 | 6元/斤 |
冰箱 | 2000元/臺(tái) |
現(xiàn)在通過用戶的輸入來(lái)檢索商品的價(jià)格株依,最簡(jiǎn)單的方法就是通過字符串進(jìn)行匹配,比如性穿,
用戶輸入“椅子”勺三,就用“椅子”作為關(guān)鍵字進(jìn)行搜索,很容易找到椅子的價(jià)格就是200元/個(gè)需曾。
但有時(shí)用戶輸入的是“凳子”吗坚,如果按照字符串匹配的方法,只能返回給用戶呆万,沒有此商品商源。但實(shí)際上可以把“椅子”的結(jié)果返回給用戶參考。這種泛化的能力谋减,通過簡(jiǎn)單的字符串匹配是顯然不能實(shí)現(xiàn)的牡彻。
詞語(yǔ)相似度計(jì)算
在上面的例子中,“凳子”跟“椅子”的語(yǔ)意更相近,跟“香蕉”或“冰箱”的語(yǔ)意相對(duì)較遠(yuǎn)庄吼。在商品搜索的過程中缎除,可以計(jì)算用戶輸入的關(guān)鍵字與數(shù)據(jù)庫(kù)中商品名間的相似度,在商品數(shù)據(jù)庫(kù)中找出相似度最大的商品总寻,推薦給用戶器罐。這種相近的程度就是詞語(yǔ)的相似度。在實(shí)際的工程開發(fā)中可以通過word2vec實(shí)現(xiàn)詞語(yǔ)相似度的計(jì)算渐行。
代碼實(shí)現(xiàn)
from sklearn.datasets import fetch_20newsgroups
news = fetch_20newsgroups(subset='all')
X, y = news.data, news.target
from bs4 import BeautifulSoup
import nltk, re
# 把段落分解成由句子組成的list(每個(gè)句子又被分解成詞語(yǔ))
def news_to_sentences(news):
news_text = BeautifulSoup(news, 'lxml').get_text()
tokenizer = nltk.data.load('tokenizers/punkt/english.pickle')
raw_sentences = tokenizer.tokenize(news_text)
# 對(duì)每個(gè)句子進(jìn)行處理轰坊,分解成詞語(yǔ)
sentences = []
for sent in raw_sentences:
sentences.append(re.sub('[^a-zA-Z]', ' ', sent.lower().strip()).split())
return sentences
sentences = []
for x in X:
sentences += news_to_sentences(x)
# import numpy
# # 將預(yù)處理過的"詞庫(kù)"保存到文件中,便于調(diào)試
# numpy_array = numpy.array(sentences)
# numpy.save('sentences.npy', numpy_array)
#
# # 將預(yù)處理后的"詞庫(kù)"從文件中讀出祟印,便于調(diào)試
# numpy_array = numpy.load('sentences.npy')
# sentences = numpy_array.tolist()
num_features = 300
min_word_count = 20
num_workers = 2
context = 5
downsampling = 1e-3
from gensim.models import word2vec
model = word2vec.Word2Vec(sentences, workers=num_workers, size=num_features, min_count=min_word_count, window=context,
sample=downsampling)
model.init_sims(replace=True)
# 保存word2vec訓(xùn)練參數(shù)便于調(diào)試
# model.wv.save_word2vec_format('word2vec_model.bin', binary=True)
# model.wv.load_word2vec_format('word2vec_model.bin', binary=True)
print '詞語(yǔ)相似度計(jì)算:'
print 'morning vs morning:'
print model.n_similarity('morning', 'morning')
print 'morning vs afternoon:'
print model.n_similarity('morning', 'afternoon')
print 'morning vs hello:'
print model.n_similarity('morning', 'hellow')
print 'morning vs shell:'
print model.n_similarity('morning', 'shell')
運(yùn)行結(jié)果
/Users/liucaiquan/anaconda/bin/python /Users/liucaiquan/PycharmProjects/WordSimilarityCalculation/src/test.py
詞語(yǔ)相似度計(jì)算:
morning vs morning:
1.0
morning vs afternoon:
0.871482091583
morning vs hello:
0.731609166442
morning vs shell:
0.709714434122
調(diào)試技巧
在開發(fā)調(diào)試的過程中肴沫,會(huì)出現(xiàn)錯(cuò)誤,需要重新運(yùn)行程序蕴忆。如果每次修改后颤芬,都從頭開始執(zhí)行,肯定會(huì)消耗很多無(wú)用的時(shí)間孽文。比如驻襟,預(yù)處理后的文本結(jié)果和word2vec的訓(xùn)練參數(shù),這些中間結(jié)果可以保持下來(lái)芋哭,當(dāng)遇到問題時(shí)沉衣,就可以從文件中讀取結(jié)果,而不需要每次都從頭開始减牺。
源碼下載地址
https://github.com/CaiquanLiu/MachineLearning
代碼參考
《Python機(jī)器學(xué)習(xí)及實(shí)踐:從零開始通往Kaggle競(jìng)賽之路》