python 文本相似度_【机器学习】使用gensim 的 doc2vec 实现文本相似度检测
環(huán)境
Python3,
gensim,jieba,numpy ,pandas
原理:文章轉(zhuǎn)成向量,然后在計(jì)算兩個(gè)向量的余弦值。
Gensim
gensim是一個(gè)python的自然語言處理庫,能夠?qū)⑽臋n根據(jù)TF-IDF, LDA, LSI 等模型轉(zhuǎn)化成向量模式,gensim還實(shí)現(xiàn)了word2vec功能,以便進(jìn)行進(jìn)一步的處理。
中文分詞
中文需要分詞,英文就不需要了,分詞用的 jieba 。
def segment(doc: str):
"""中文分詞
Arguments:
doc {str} -- 輸入文本
Returns:
[type] -- [description]
"""
# 停用詞
stop_words = pd.read_csv("./data/stopwords_TUH.txt", index_col=False, quoting=3,
names=['stopword'],
sep="\n",
encoding='utf-8')
stop_words = list(stop_words.stopword)
# 去掉html標(biāo)簽數(shù)字等
reg_html = re.compile(r'<[^>]+>', re.S)
doc = reg_html.sub('', doc)
doc = re.sub('[0-9]', '', doc)
doc = re.sub('\s', '', doc)
word_list = list(jieba.cut(doc))
out_str = ''
for word in word_list:
if word not in stop_words:
out_str += word
out_str += ' '
segments = out_str.split(sep=" ")
return segments
訓(xùn)練 Doc2Vec 模型
模型參數(shù)下面說明,先上代碼
def train():
"""訓(xùn)練 Doc2Vec 模型
"""
# 先把所有文檔的路徑存進(jìn)一個(gè) array中,docLabels:
data_dir = "./data/corpus_words"
docLabels = [f for f in listdir(data_dir) if f.endswith('.txt')]
data = []
for doc in docLabels:
ws = open(data_dir + "/" + doc, 'r', encoding='UTF-8').read()
data.append(ws)
print(len(data))
# 訓(xùn)練 Doc2Vec,并保存模型:
sentences = LabeledLineSentence(data, docLabels)
# 實(shí)例化一個(gè)模型
model = gensim.models.Doc2Vec(vector_size=256, window=10, min_count=5,
workers=4, alpha=0.025, min_alpha=0.025, epochs=12)
model.build_vocab(sentences)
print("開始訓(xùn)練...")
# 訓(xùn)練模型
model.train(sentences, total_examples=model.corpus_count, epochs=12)
model.save("./models/doc2vec.model")
print("model saved")
保存成功后會(huì)有三個(gè)文件,分別是:doc2vec.model,doc2vec.model.trainables.syn1neg.npy,doc2vec.model.wv.vectors.npy
Doc2Vec參數(shù)說明:
· vector_size:是指特征向量的維度,默認(rèn)為100。大的size需要更多的訓(xùn)練數(shù)據(jù),但是效果會(huì)更好.
· window:表示當(dāng)前詞與預(yù)測詞在一個(gè)句子中的最大距離是多少
· alpha: 是學(xué)習(xí)速率
· min_count: 可以對(duì)字典做截?cái)? 詞頻少于min_count次數(shù)的單詞會(huì)被丟棄掉, 默認(rèn)值為5
· workers參數(shù)控制訓(xùn)練的并行數(shù)。
· epochs: 迭代次數(shù),默認(rèn)為5
文本轉(zhuǎn)換成向量
利用之前保存的模型,把分詞后的分本轉(zhuǎn)成向量,代碼如下
def sent2vec(model, words):
"""文本轉(zhuǎn)換成向量
Arguments:
model {[type]} -- Doc2Vec 模型
words {[type]} -- 分詞后的文本
Returns:
[type] -- 向量數(shù)組
"""
vect_list = []
for w in words:
try:
vect_list.append(model.wv[w])
except:
continue
vect_list = np.array(vect_list)
vect = vect_list.sum(axis=0)
return vect / np.sqrt((vect ** 2).sum())
計(jì)算兩個(gè)向量余弦值
余弦相似度,又稱為余弦相似性,是通過計(jì)算兩個(gè)向量的夾角余弦值來評(píng)估他們的相似度。余弦相似度將向量根據(jù)坐標(biāo)值,繪制到向量空間中,如最常見的二維空間。
余弦值的范圍在[-1,1]之間,值越趨近于1,代表兩個(gè)向量的方向越接近;越趨近于-1,他們的方向越相反;接近于0,表示兩個(gè)向量近乎于正交。
最常見的應(yīng)用就是計(jì)算文本相似度。將兩個(gè)文本根據(jù)他們?cè)~,建立兩個(gè)向量,計(jì)算這兩個(gè)向量的余弦值,就可以知道兩個(gè)文本在統(tǒng)計(jì)學(xué)方法中他們的相似度情況。實(shí)踐證明,這是一個(gè)非常有效的方法。
公式:
def similarity(a_vect, b_vect):
"""計(jì)算兩個(gè)向量余弦值
Arguments:
a_vect {[type]} -- a 向量
b_vect {[type]} -- b 向量
Returns:
[type] -- [description]
"""
dot_val = 0.0
a_norm = 0.0
b_norm = 0.0
cos = None
for a, b in zip(a_vect, b_vect):
dot_val += a*b
a_norm += a**2
b_norm += b**2
if a_norm == 0.0 or b_norm == 0.0:
cos = -1
else:
cos = dot_val / ((a_norm*b_norm)**0.5)
return cos
預(yù)測
def test_model():
print("load model")
model = gensim.models.Doc2Vec.load(‘./models/doc2vec.model‘)
st1 = open('./data/courpus_test/t1.txt', 'r', encoding='UTF-8').read()
st2 = open('./data/courpus_test/t2.txt', 'r', encoding='UTF-8').read()
# 分詞
print("segment")
st1 = segment(st1)
st2 = segment(st2)
# 轉(zhuǎn)成句子向量
vect1 = sent2vec(model, st1)
vect2 = sent2vec(model, st2)
# 查看變量占用空間大小
import sys
print(sys.getsizeof(vect1))
print(sys.getsizeof(vect2))
cos = similarity(vect1, vect2)
print("相似度:{:.4f}".format(cos))
看下效果:
完全相同的文章
不相同的文章
數(shù)據(jù)太大,沒有上傳,自己網(wǎng)上找找應(yīng)該有很多。
參考:
原文地址:https://www.cnblogs.com/JreeyQi/p/9042397.html
總結(jié)
以上是生活随笔為你收集整理的python 文本相似度_【机器学习】使用gensim 的 doc2vec 实现文本相似度检测的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机意外关闭原因 安全问题,win7弹
- 下一篇: arcgis标注牵引线_解析ArcGis