词向量加权计算相似度

标签: 向量 计算 相似 | 发表时间:2019-01-03 10:13 | 作者:孤狼18
出处:https://www.iteye.com

基于词向量的几种计算文本相似度方法 :

   1)使用词向量求平均计算相似度

   2)词向量tfidf加权求平均计算相似度

   3)词向量加权-PCA计算相似度

 

from gensim import matutils
from gensim.models import Word2Vec
import pickle
import scipy
import numpy as np
from gensim import corpora, models
import numpy as np
from sklearn.decomposition import PCA
from typing import List

#==============词向量求平均===================
def sentenceByWordVectAvg(sentenceList,model,embeddingSize):
    sentenceSet = []
    for sentence in sentenceList:
        # 将所有词向量的woed2vec向量相加到句向量
        sentenceVector = np.zeros(embeddingSize)
        # 计算每个词向量的权重,并将词向量加到句向量
        for word in sentence:
            sentenceVector = np.add(sentenceVector, model[word])
        sentenceVector = np.divide(sentenceVector,len(sentence))
         # 存储句向量
        sentenceSet.append(sentenceVector)
    return sentenceSet


# ===============word2vec词向量+tfidf==================
def sentenceByW2VTfidf(corpus_tfidf, token2id, sentenceList, model, embeddingSize):
    sentenceSet = []
    for i in range(len(sentenceList)):
        # 将所有词向量的woed2vec向量相加到句向量
        sentenceVector = np.zeros(embeddingSize)
        # 计算每个词向量的权重,并将词向量加到句向量
        sentence = sentenceList[i]
        sentence_tfidf = corpus_tfidf[i]
        dict_tfidf = list_dict(sentence_tfidf)
        for word in sentence:
            tifidf_weigth = dict_tfidf.get(str(token2id[word]))
            sentenceVector = np.add(sentenceVector, tifidf_weigth * model[word])
        sentenceVector = np.divide(sentenceVector, len(sentence))
        # 存储句向量
        sentenceSet.append(sentenceVector)
    return sentenceSet

def list_dict(list_data):
    list_data=list(map(lambda x:{str(x[0]):x[1]},list_data))
    dict_data = {}
    for i in list_data:
        key, = i
        value, = i.values()
        dict_data[key] = value
    return dict_data

# ===============sentence2vec:词向量加权-PCA==================
class Word:
    def __init__(self, text, vector):
        self.text = text
        self.vector = vector

# a sentence, a list of words
class Sentence:
    def __init__(self, word_list):
        self.word_list = word_list

    # return the length of a sentence
    def len(self) -> int:
        return len(self.word_list)

# convert a list of sentence with word2vec items into a set of sentence vectors
def sentence2vec(wdfs,token2id,sentenceList: List[Sentence], embeddingSize: int, charLen:int,a: float=1e-3):
    sentenceSet = []
    for sentence in sentenceList:
        sentenceVector = np.zeros(embeddingSize)    
        for word in sentence.word_list:
            p=wdfs[token2id[word.text]]/charLen
            a = a / (a + p)
            sentenceVector = np.add(sentenceVector, np.multiply(a, word.vector))
        sentenceVector = np.divide(sentenceVector, sentence.len())
        sentenceSet.append(sentenceVector)
    # caculate the PCA of sentenceSet
    pca = PCA(n_components=embeddingSize)
    pca.fit(np.array(sentenceSet))
    u = pca.components_[0]
    u = np.multiply(u, np.transpose(u))

    # occurs if we have less sentences than embeddings_size
    if len(u) < embeddingSize:
        for i in range(embeddingSize - len(u)):
            u = np.append(u, [0])

    # remove the projections of the average vectors on their first principal component
    # (“common component removal”).
    sentenceVectors = []
    for sentenceVector in sentenceSet:
        sentenceVectors.append(np.subtract(sentenceVector, np.multiply(u, sentenceVector)))
    return sentenceVectors


# 获取训练数据
def gettrainData():
    question_path = r'./shuxueTest/shuxueTrainData.pkl'
    longtextdata1 = pickle.load(open(question_path, 'rb'))
    longtextdata1=longtextdata1['question_text']
    traind=longtextdata1[:5000]
    traindata=list(map(lambda x:x.split(' '),traind))
    return traindata

def saveIndex(sentence_vecs):
    corpus_len = len(sentence_vecs)
    print(corpus_len)
    index = np.empty(shape=(corpus_len, 200), dtype=np.float32)
    for docno, vector in enumerate(sentence_vecs):
        if isinstance(vector, np.ndarray):
            pass
        elif scipy.sparse.issparse(vector):
            vector = vector.toarray().flatten()
        else:
            vector = matutils.unitvec(matutils.sparse2full(vector, 200))
        index[docno] = vector
    return index

# 计算矩阵与向量余弦相识度
def cosine_Matrix(_matrixA, vecB):
    _matrixA_matrixB = np.dot(_matrixA, vecB.T).T
    _matrixA_norm = np.sqrt(np.multiply(_matrixA,_matrixA).sum(axis=1))
    vecB_norm = np.linalg.norm(vecB)
    return np.divide(_matrixA_matrixB, _matrixA_norm * vecB_norm.transpose())

def trainWordVectAvg():
    traindata=gettrainData()
    dictionary = corpora.Dictionary(traindata)  ##得到词典
    token2id = dictionary.token2id
    charLen = dictionary.num_pos
    corpus = [dictionary.doc2bow(text) for text in traindata]  ##统计每篇文章中每个词出现的次数:[(词编号id,次数number)]
    print('dictionary prepared!')
    tfidf = models.TfidfModel(corpus=corpus, dictionary=dictionary)
    wdfs = tfidf.dfs
    corpus_tfidf = tfidf[corpus]
    model = Word2Vec(traindata, size=200, window=5, min_count=1, workers=4)

    # 词向量求平均得到句向量
    sentence_vecs = sentenceByWordVectAvg(traindata, model, 200)
    # 词向量tfidf加权得到句向量
    sentence_vecs = sentenceByW2VTfidf(corpus_tfidf, token2id, traindata, model, 200)
    #sentence2vec:词向量加权-PCA
    Sentence_list = []
    for td in traindata:
        vecs = []
        for s in td:
            w = Word(s, model[s])
            vecs.append(w)
        sentence = Sentence(vecs)
        Sentence_list.append(sentence)
    sentence_vecs = sentence2vec(wdfs, token2id, Sentence_list, 200, charLen)

    query = sentence_vecs[0]
    print(query)
    index=saveIndex(sentence_vecs)
    query = sentence_vecs[0]
    # 计算相似度
    cosresult = cosine_Matrix(index, query)
    cosresult = cosresult.tolist()
    sort_cosresult = sorted(cosresult)
    print(sort_cosresult)
    for i in sort_cosresult[-8:-1]:
        idx = cosresult.index(i)
        print(i, '===', traindata[idx])
    print(traindata[0])

        3)参考:https://blog.csdn.net/walker_hao/article/details/78974781



已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [向量 计算 相似] 推荐:

词向量加权计算相似度

- - 编程语言 - ITeye博客
基于词向量的几种计算文本相似度方法 :.    1)使用词向量求平均计算相似度.    2)词向量tfidf加权求平均计算相似度.    3)词向量加权-PCA计算相似度. # 将所有词向量的woed2vec向量相加到句向量. # 计算每个词向量的权重,并将词向量加到句向量. return sentenceSet # ===============word2vec词向量+tfidf================== def sentenceByW2VTfidf(corpus_tfidf, token2id, sentenceList, model, embeddingSize):.

word2vec词向量训练及中文文本相似度计算 - CSDN博客

- -
本文是讲述如何使用word2vec的基础教程,文章比较基础,希望对你有所帮助. 参考:《Word2vec的核心架构及其应用 · 熊富林,邓怡豪,唐晓晟 · 北邮2015年》.           《Word2vec的工作原理及应用探究 · 周练 · 西安电子科技大学2014年》.           《Word2vec对中文词进行聚类的研究 · 郑文超,徐鹏 · 北京邮电大学2013年》.

URL相似度计算的思考

- - IT技术博客大学习
在做一些web相关的工作的时候,我们往往可能需要做一些对url的处理,其中包括对相似的url的识别和处理. 这就需要计算两个url的相似度. 那么怎么进行url相似度的计算的. 我首先想到的是把一个url看作是一个字符串,这样就简化成两个字符串相似度的计算. 字符串相似度计算有很多已经比较成熟的算法,比如“ 编辑距离算法”,该算法描述了两个字符串之间转换需要的最小的编辑次数;还有一些其他的比如“ 最长公共字串”等方法.

相似度计算常用方法综述

- - 搜索研发部官方博客
       相似度计算用于衡量对象之间的相似程度,在数据挖掘、自然语言处理中是一个基础性计算. 其中的关键技术主要是两个部分,对象的特征表示,特征集合之间的相似关系. 在信息检索、网页判重、推荐系统等,都涉及到对象之间或者对象和对象集合的相似性的计算. 而针对不同的应用场景,受限于数据规模、时空开销等的限制,相似度计算方法的选择又会有所区别和不同.

如何计算两个文档的相似度(一)

- - 我爱自然语言处理
前几天,我发布了一个和在线教育相关的网站: 课程图谱,这个网站的目的通过对公开课的导航、推荐和点评等功能方便大家找到感兴趣的公开课,特别是目前最火的Coursera,Udacity等公开课平台上的课程. 在发布之前,遇到的一个问题是如何找到两个相关的公开课,最早的计划是通过用户对课程的关注和用户对用户的关注来做推荐,譬如“你关注的朋友也关注这些课程”,但是问题是网站发布之前,我还没有积累用户关注的数据.

如何计算两个文档的相似度(三)

- - 我爱自然语言处理
上一节我们用了一个简单的例子过了一遍 gensim的用法,这一节我们将用 课程图谱的实际数据来做一些验证和改进,同时会用到 NLTK来对课程的英文数据做预处理. 为了方便大家一起来做验证,这里准备了一份Coursera的课程数据,可以在这里下载: coursera_corpus,总共379个课程,每行包括3部分内容:课程名\t课程简介\t课程详情, 已经清除了其中的html tag, 下面所示的例子仅仅是其中的课程名:.

海量数据相似度计算之simhash短文本查找

- - ITeye博客
在前一篇文章 《 海量数据相似度计算之simhash和海明距离》 介绍了simhash的原理,大家应该感觉到了算法的魅力. 但是随着业务的增长 simhash的数据也会暴增,如果一天100w,10天就1000w了. 我们如果插入一条数据就要去比较1000w次的simhash,计算量还是蛮大,普通PC 比较1000w次海明距离需要 300ms ,和5000w数据比较需要1.8 s.

如何计算两个文档的相似度(二)

- - 我爱自然语言处理
上一节我们介绍了一些背景知识以及 gensim , 相信很多同学已经尝试过了. 这一节将从gensim最基本的安装讲起,然后举一个非常简单的例子用以说明如何使用gensim,下一节再介绍其在 课程图谱上的应用. 二、gensim的安装和使用. gensim依赖 NumPy和 SciPy这两大Python科学计算工具包,一种简单的安装方法是pip install,但是国内因为网络的缘故常常失败.

海量数据相似度计算之simhash和海明距离

- - CSDN博客架构设计推荐文章
通过  采集系统 我们采集了大量文本数据,但是文本中有很多重复数据影响我们对于结果的分析. 分析前我们需要对这些数据去除重复,如何选择和设计文本的去重算法. 常见的有余弦夹角算法、欧式距离、Jaccard相似度、最长公共子串、编辑距离等. 这些算法对于待比较的文本数据不多时还比较好用,如果我们的爬虫每天采集的数据以千万计算,我们如何对于这些海量千万级的数据进行高效的合并去重.

文本相似度计算-google的simHash汉明距离

- - 行业应用 - ITeye博客
       针对文本相似性计算,很多开发朋友首先想到的应该是使用向量空间模型VSM(Vector Space Model). 使用VSM计算相似度,先对文本进行分词,然后建立文本向量,把相似度的计算转换成某种特征向量距离的计算,比如余弦角、欧式距离、Jaccard相似系数等. 这种方法存在很大一个问题:需要对文本两两进行相似度比较,无法扩展到海量文本的处理.