pythonNLP-文本相似度计算-Demo

参照博客[我爱自然语言处理]里面的如何计算两个文本的相似度系列,把代码自己实现了一遍,对整个流程有了了解。纯属个人记录,新手想学习可直接去上面的博客学习,讲的非常好。

代码

#-*- coding:utf-8
import gensim
from gensim import corpora, models, similarities
import traceback


documents = [ "Shipment of gold damaged in a fire",
              "Delivery of silver arrived in a silver truck",
              "Shipment of gold arrived in a truck"]

'''
@:return:texts是token_list,只要我生成了token_list,给它就行了
'''
def pre_process( documents ):
    try:

        documents_token_list = [ [word for word in document.lower().split() ] for document in documents ]

        print "[INFO]: pre_process is finished!"
        return documents_token_list

    except Exception,e:
        print traceback.print_exc()

'''
这个函数是比较通用的,可以跟我自己写的结合。
这个是根据document[ token_list ]来训练tf_idf模型的
@texts: documents = [ document1, document2, ... ] document1 = token_list1
@return: dictionary 根据texts建立的vsm空间,并且记录了每个词的位置,和我的实现一样,对于vsm空间每个词,你要记录他的位置。否则,文档生成vsm空间的时候,每个词无法找到自己的位置
@return: corpus_idf 每篇document在vsm上的tf-idf表示.但是他的输出和我的不太一样,我的输出就是单纯的vsm空间中tf-idf的值,但是它的空间里面不是。还有位置信息在。并且输出的时候,看到的好像没有值为0的向量,但是vsm向量的空间是一样的。所以,我觉得应该是只输出了非0的。

这两个返回值和我的都不一样,因为字典(vsm)以及corpus_idf(vsm)都输出了位置信息。
但是这两个信息,可以快速生成lda和lsi模型

'''
def tf_idf_trainning(documents_token_list):
    try:

        # 将所有文章的token_list映射为 vsm空间
        dictionary = corpora.Dictionary(documents_token_list)

        # 每篇document在vsm上的tf表示
        corpus_tf = [ dictionary.doc2bow(token_list) for token_list in documents_token_list ]

        # 用corpus_tf作为特征,训练tf_idf_model
        tf_idf_model = models.TfidfModel(corpus_tf)

        # 每篇document在vsm上的tf-idf表示
        corpus_tfidf = tf_idf_model[corpus_tf]

        print "[INFO]: tf_idf_trainning is finished!"
        return dictionary, corpus_tf, corpus_tfidf

    except Exception,e:
        print traceback.print_exc()

def lsi_trainning( dictionary, corpus_tfidf, K ):
    try:

        # 用tf_idf作为特征,训练lsi模型
        lsi_model = models.LsiModel( corpus_tfidf, id2word=dictionary, num_topics = K )

        # 每篇document在K维空间上表示
        corpus_lsi = lsi_model[corpus_tfidf]

        print "[INFO]: lsi_trainning is finished!"
        return lsi_model, corpus_lsi

    except Exception,e:
        print traceback.print_exc()

def lda_trainning( dictionary, corpus_tfidf, K ):
    try:

        # 用corpus_tf作为特征,训练lda_model
        lda_model = models.LdaModel( corpus_tfidf, id2word=dictionary, num_topics = K )

        # 每篇document在K维空间上表示
        corpus_lda = lda_model[corpus_tfidf]
        for aa in corpus_lda:
            print aa

        print "[INFO]: lda_trainning is finished!"
        return lda_model, corpus_lda

    except Exception,e:
        print traceback.print_exc()

def similarity( query, dictionary, corpus_tf, lda_model ):
    try:

        # 建立索引
        index = similarities.MatrixSimilarity( lda_model[corpus_tf] )

        # 在dictionary建立query的vsm_tf表示
        query_bow = dictionary.doc2bow( query.lower().split() )

        # 查询在K维空间的表示
        query_lda = lda_model[query_bow]

        # 计算相似度
        simi = index[query_lda]
        query_simi_list = [ item for _, item in enumerate(simi) ]
        print query_simi_list

    except Exception,e:
        print traceback.print_exc()




documents_token_list = pre_process(documents)
dict, corpus_tf, corpus_tfidf = tf_idf_trainning(documents_token_list)
#lsi_trainning(corpus_tfidf, dict, 2)
lda_model, corpus_lda = lda_trainning(dict, corpus_tfidf, 2)

similarity( "Shipment of gold arrived in a truck", dict, corpus_tf, lda_model )

代码

#-*- coding:utf-8
from gensim import corpora, models, similarities
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
from nltk.stem.lancaster import LancasterStemmer
import traceback

'''
------------------------------------------------------------
函数声明
'''

# 预处理
def pre_process(PATH):
    try:

        # 课程信息
        courses = [ line.strip() for line in file(PATH) ]
        courses_copy = courses
        courses_name = [ course.split('\t')[0] for course in courses ]

        # 分词-转化小写
        texts_tokenized = [[word.lower() for word in word_tokenize(document.decode("utf-8"))] for document in courses]

        # 去除停用词
        english_stopwords = stopwords.words('english')
        texts_filtered_stopwords = [ [ word for word in document if word not in english_stopwords ] for document in texts_tokenized ]

        # 去除标点符号
        english_punctuations = [',', '.',  ':', ';', '?', '(', ')', '[', ']', '&', '!', '*', '@', '#', '$', '%']
        texts_filterd = [ [ word for word in document if word not in english_punctuations ] for document in texts_filtered_stopwords ]

        # 词干化
        st = LancasterStemmer()
        texts_stemmed = [ [ st.stem(word) for word in document ] for document in texts_filterd ]
        #print texts_stemmed[0]

        # 去除低频词
        all_stems = sum(texts_stemmed, [])
        stem_once = set( stem for stem in set(all_stems) if all_stems.count(stem) == 1 )
        texts = [ [ word for word in text if word not in stem_once ] for text in texts_stemmed]

        print "[INFO]: pre_process is finished!"
        return texts, courses_copy, courses_name


    except Exception,e:
        print traceback.print_exc()

# 训练tf_idf模型
def tf_idf_trainning(documents_token_list):
    try:

        # 将所有文章的token_list映射为 vsm空间
        dictionary = corpora.Dictionary(documents_token_list)

        # 每篇document在vsm上的tf表示
        corpus_tf = [ dictionary.doc2bow(token_list) for token_list in documents_token_list ]

        # 用corpus_tf作为特征,训练tf_idf_model
        tf_idf_model = models.TfidfModel(corpus_tf)

        # 每篇document在vsm上的tf-idf表示
        corpus_tfidf = tf_idf_model[corpus_tf]

        print "[INFO]: tf_idf_trainning is finished!"
        return dictionary, corpus_tf, corpus_tfidf

    except Exception,e:
        print traceback.print_exc()

# 训练lsi模型
def lda_trainning( dictionary, corpus_tfidf, K ):
    try:

        # 用corpus_tf作为特征,训练lda_model
        lda_model = models.LdaModel( corpus_tfidf, id2word=dictionary, num_topics = K )

        # 每篇document在K维空间上表示
        corpus_lda = lda_model[corpus_tfidf]

        print "[INFO]: lda_trainning is finished!"
        return lda_model, corpus_lda

    except Exception,e:
        print traceback.print_exc()

# 基于lda模型的相似度计算
def similarity( query, dictionary, corpus_tf, lda_model ):
    try:

        # 建立索引
        index = similarities.MatrixSimilarity( lda_model[corpus_tf] )

        # 在dictionary建立query的vsm_tf表示
        query_bow = dictionary.doc2bow( query.lower().split() )

        # 查询在K维空间的表示
        query_lda = lda_model[query_bow]

        # 计算相似度
        simi = index[query_lda]
        sort_simi = sorted(enumerate(simi), key=lambda item: -item[1])
        print sort_simi[0:10]

    except Exception,e:
        print traceback.print_exc()


'''
------------------------------------------------------------
常量定义
'''

PATH = "../../data/coursera/coursera_corpus"
number_of_topics = 10

'''
------------------------------------------------------------
'''

texts, courses, courses_name = pre_process(PATH)
dict, corpus_tf, corpus_tfidf = tf_idf_trainning(texts)
lda_model, corpus_lda = lda_trainning( dict, corpus_tf, number_of_topics )

similarity(courses[210], dict, corpus_tf, lda_model)
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python中,有多种用于计算文本相似度的算法。其中一种较为常见的算法是simhash算法。simhash算法由Google用于处理海量文本去重。 simhash算法将一个文档转换成一个64位的特征字节,然后通过计算文档特征字之间的汉明距离来判断文档是否重复。一般来说,当两个文档特征字之间的汉明距离小于3时,可以判定两个文档相似。 在Python中,可以使用第三方库simhash来实现simhash算法。可以通过计算两个文本的simhash值,然后计算它们的汉明距离来判断它们的相似度。 下面是一个用Python实现simhash算法计算文本相似度的示例代码: ```python from simhash import Simhash def simhash_demo(text_a, text_b): """ 求两文本相似度 :param text_a: :param text_b: :return: """ a_simhash = Simhash(text_a) b_simhash = Simhash(text_b) max_hashbit = max(len(bin(a_simhash.value)), len(bin(b_simhash.value))) # 汉明距离 distince = a_simhash.distance(b_simhash) similar = 1 - distince / max_hashbit return similar if __name__ == '__main__': text1 = "傲游AI专注于游戏领域,多年的AI技术积淀,一站式提供文本、图片、音/视频内容审核,游戏AI以及数据平台服务" text2 = "傲游AI专注于游戏领域,多年的AI技术积淀,二站式提供文本、图片、音 视频内容审核,游戏AI以及数据平台服务" text3 = '"傲游AI专注于游戏领域,多年的AI技术积淀,三站式提供文本、图片、音视频内容审核,游戏AI以及数据平台服务"' similar = simhash_demo(text1, text2) similar2 = simhash_demo(text1, text3) similar3 = simhash_demo(text2, text3) print(similar) print(similar2) print(similar3) ``` 以上代码中,通过计算两个文本的simhash值并计算它们的汉明距离,最后得到它们的相似度。可以根据实际需求进行相似度的判断和进一步处理。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [文本相似度计算——Simhash算法(python实现)](https://blog.csdn.net/Trisyp/article/details/113623966)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值