1、潜在语义索引算法介绍
潜在语义索引(LSI)是一种非监督的学习算法,它的原理是先把句子分词,用BOW方法对句子进行特征提取,组成句子的特征矩阵。把矩阵通过奇异值分解(SVD)的降维方法一个降维去燥后的新矩阵,来表示原来的矩阵。由特征组成的矩阵降维后,可以理解为把原来特征映射到其他低维空间。通过把词语映射到其他的向量空间,使得LSI可以捕捉到句子潜在的语义,如同义词,近义词,不同表达方式的相似性。
假设句子特征化后组成m×n的矩阵A,可以分解为下面三个矩阵:
Am×n=Um×mΣm×nVTn×n
假设分解k维,SVD的分解可以近似的写为,此时矩阵已重构:
Am×n≈Um×kΣk×kVTk×n
为了构建矩阵A,我们用词袋BOW算法把四个句子u"痘痘肌肤应该使用什么洗面奶",u"脸上有青春痘用什么洗面奶",u"你这里有没有祛痘痘的洗面奶",u"洗面奶有打折吗",进行分词,得到分词的结果,然后用TF/IDF过滤掉不重要的词,根据词的重要性分配每个词的权重,组成矩阵A。在把矩阵分解后的矩阵投影到其他空间,如代码models.LsiModel(corpus_tfidf, id2word=dictionary)。再把查询的语句分词后也投影到训练好的Lsi空间,最后计算训练样本中和查询语句最接近的句子。代码如下:
# -*- coding: utf-8 -*-
from gensim import corpora, models, similarities
import jieba
import logging
sentences = [u"痘痘肌肤应该使用什么洗面奶",u"脸上有青春痘用什么洗面奶",u"你这里有没有祛痘痘的洗面奶",u"洗面奶有打折吗"]
query_s=[u"洗颜乳有参与打折吗,折扣多少"]
documents=[]
query_word=[]
for s in sentences:
temp=jieba.cut(s,cut_all=False, HMM=True)
result='/'.join(temp)
documents.append(result)
for s in query_s:
temp=jieba.cut(s,cut_all=False, HMM=True)
result='/'.join(temp)
query_word.append(result)
texts = [[word for word in document.split('/')] for document indocuments]
query_vec = [[word for word in query_word1.split('/')] forquery_word1 in query_word]
dictionary = corpora.Dictionary(texts)
corpus = [dictionary.doc2bow(text) for text in texts]
corpus_query = [dictionary.doc2bow(text) for text in query_vec]
tfidf = models.TfidfModel(corpus)
#tfidf_query = models.TfidfModel(corpus_query)
corpus_tfidf = tfidf[corpus]
corpus_tfidf_query = tfidf[corpus_query]
lsi = models.LsiModel(corpus_tfidf, id2word=dictionary)
#lsi.print_topics(2)
topics=lsi.show_topics(2)
for a in topics:
print(a)
lsi_vec=lsi[corpus_tfidf_query]
print (lsi_vec)
i=similarities.MatrixSimilarity(lsi[corpus])
sims=i[lsi_vec]
sims=sorted(enumerate(sims),key=lambda item:-item[1])
i1=similarities.MatrixSimilarity(lda[corpus])
sims1=sorted(enumerate(sims1),key=lambda item:-item[1])
from pprint import pprint
pprint(sims)