上一节我们介绍了一些背景知识以及gensim , 相信很多同学已经尝试过了。这一节将从gensim最基本的安装讲起,然后举一个非常简单的例子用以说明如何使用gensim,下一节再介绍其在课程图谱上的应用。

二、gensim的安装和使用

1、安装

gensim依赖NumPy和SciPy这两大Python科学计算工具包,一种简单的安装方法是pip install,但是国内因为网络的缘故常常失败。所以我是下载了gensim的源代码包安装的。gensim的这个官方安装页面很详细的列举了兼容的Python和NumPy, SciPy的版本号以及安装步骤,感兴趣的同学可以直接参考。下面我仅仅说明在Ubuntu和Mac OS下的安装:

1)我的VPS是64位的Ubuntu 12.04,所以安装numpy和scipy比较简单"sudo apt-get install python-numpy python-scipy", 之后解压gensim的安装包,直接“sudo python setup.py install"即可;

2)我的本是macbook pro,在mac os上安装numpy和scipy的源码包废了一下周折,特别是后者,一直提示fortran相关的东西没有,google了一下,发现很多人在mac上安装scipy的时候都遇到了这个问题,最后通过homebrew安装了gfortran才搞定:“brew install gfortran”,之后仍然是“sudo python setpy.py install" numpy 和 scipy即可;

2、使用

gensim的官方tutorial非常详细,英文ok的同学可以直接参考。以下我会按自己的理解举一个例子说明如何使用gensim,这个例子不同于gensim官方的例子,可以作为一个补充。上一节提到了一个文档:Latent Semantic Indexing (LSI) A Fast Track Tutorial , 这个例子的来源就是这个文档所举的3个一句话doc。首先让我们在命令行中打开python,做一些准备工作:

>>> from gensim import corpora, models, similarities

>>> import logging

>>> logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)

然后将上面那个文档中的例子作为文档输入,在Python中用document list表示:

>>> documents = ["Shipment of gold damaged in a fire",

... "Delivery of silver arrived in a silver truck",

... "Shipment of gold arrived in a truck"]

正常情况下,需要对英文文本做一些预处理工作,譬如去停用词,对文本进行tokenize,stemming以及过滤掉低频的词,但是为了说明问题,也是为了和这篇"LSI Fast Track Tutorial"保持一致,以下的预处理仅仅是将英文单词小写化:

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

>>> print texts

[['shipment', 'of', 'gold', 'damaged', 'in', 'a', 'fire'], ['delivery', 'of', 'silver', 'arrived', 'in', 'a', 'silver', 'truck'], ['shipment', 'of', 'gold', 'arrived', 'in', 'a', 'truck']]

我们可以通过这些文档抽取一个“词袋(bag-of-words)",将文档的token映射为id:

>>> dictionary = corpora.Dictionary(texts)

>>> print dictionary

Dictionary(11 unique tokens)

>>> print dictionary.token2id

{'a': 0, 'damaged': 1, 'gold': 3, 'fire': 2, 'of': 5, 'delivery': 8, 'arrived': 7, 'shipment': 6, 'in': 4, 'truck': 10, 'silver': 9}

然后就可以将用字符串表示的文档转换为用id表示的文档向量:

>>> corpus = [dictionary.doc2bow(text) for text in texts]

>>> print corpus

[[(0, 1), (1, 1), (2, 1), (3, 1), (4, 1), (5, 1), (6, 1)], [(0, 1), (4, 1), (5, 1), (7, 1), (8, 1), (9, 2), (10, 1)], [(0, 1), (3, 1), (4, 1), (5, 1), (6, 1), (7, 1), (10, 1)]]

例如(9,2)这个元素代表第二篇文档中id为9的单词“silver”出现了2次。

有了这些信息,我们就可以基于这些“训练文档”计算一个TF-IDF“模型”:

>>> tfidf = models.TfidfModel(corpus)

2013-05-27 18:58:15,831 : INFO : collecting document frequencies

2013-05-27 18:58:15,881 : INFO : PROGRESS: processing document #0

2013-05-27 18:58:15,881 : INFO : calculating IDF weights for 3 documents and 11 features (21 matrix non-zeros)

基于这个TF-IDF模型,我们可以将上述用词频表示文档向量表示为一个用tf-idf值表示的文档向量:

>>> corpus_tfidf = tfidf[corpus]

>>> for doc in corpus_tfidf:

... print doc

...

[(1, 0.6633689723434505), (2, 0.6633689723434505), (3, 0.2448297500958463), (6, 0.2448297500958463)]

[(7, 0.16073253746956623), (8, 0.4355066251613605), (9, 0.871013250322721), (10, 0.16073253746956623)]

[(3, 0.5), (6, 0.5), (7, 0.5), (10, 0.5)]

发现一些token貌似丢失了,我们打印一下tfidf模型中的信息:

>>> print tfidf.dfs

{0: 3, 1: 1, 2: 1, 3: 2, 4: 3, 5: 3, 6: 2, 7: 2, 8: 1, 9: 1, 10: 2}

>>> print tfidf.idfs

{0: 0.0, 1: 1.5849625007211563, 2: 1.5849625007211563, 3: 0.5849625007211562, 4: 0.0, 5: 0.0, 6: 0.5849625007211562, 7: 0.5849625007211562, 8: 1.5849625007211563, 9: 1.5849625007211563, 10: 0.5849625007211562}

我们发现由于包含id为0, 4, 5这3个单词的文档数(df)为3,而文档总数也为3,所以idf被计算为0了,看来gensim没有对分子加1,做一个平滑。不过我们同时也发现这3个单词分别为a, in, of这样的介词,完全可以在预处理时作为停用词干掉,这也从另一个方面说明TF-IDF的有效性。

有了tf-idf值表示的文档向量,我们就可以训练一个LSI模型,和Latent Semantic Indexing (LSI) A Fast Track Tutorial中的例子相似,我们设置topic数为2:

>>> lsi = models.LsiModel(corpus_tfidf, id2word=dictionary, num_topics=2)

>>> lsi.print_topics(2)

2013-05-27 19:15:26,467 : INFO : topic #0(1.137): 0.438*"gold" + 0.438*"shipment" + 0.366*"truck" + 0.366*"arrived" + 0.345*"damaged" + 0.345*"fire" + 0.297*"silver" + 0.149*"delivery" + 0.000*"in" + 0.000*"a"

2013-05-27 19:15:26,468 : INFO : topic #1(1.000): 0.728*"silver" + 0.364*"delivery" + -0.364*"fire" + -0.364*"damaged" + 0.134*"truck" + 0.134*"arrived" + -0.134*"shipment" + -0.134*"gold" + -0.000*"a" + -0.000*"in"

lsi的物理意义不太好解释,不过最核心的意义是将训练文档向量组成的矩阵SVD分解,并做了一个秩为2的近似SVD分解,可以参考那篇英文tutorail。有了这个lsi模型,我们就可以将文档映射到一个二维的topic空间中:

>>> corpus_lsi = lsi[corpus_tfidf]

>>> for doc in corpus_lsi:

... print doc

...

[(0, 0.67211468809878649), (1, -0.54880682119355917)]

[(0, 0.44124825208697727), (1, 0.83594920480339041)]

[(0, 0.80401378963792647)]

可以看出,文档1,3和topic1更相关,文档2和topic2更相关;

我们也可以顺手跑一个LDA模型:

>>> lda = models.LdaModel(copurs_tfidf, id2word=dictionary, num_topics=2)

>>> lda.print_topics(2)

2013-05-27 19:44:40,026 : INFO : topic #0: 0.119*silver + 0.107*shipment + 0.104*truck + 0.103*gold + 0.102*fire + 0.101*arrived + 0.097*damaged + 0.085*delivery + 0.061*of + 0.061*in

2013-05-27 19:44:40,026 : INFO : topic #1: 0.110*gold + 0.109*silver + 0.105*shipment + 0.105*damaged + 0.101*arrived + 0.101*fire + 0.098*truck + 0.090*delivery + 0.061*of + 0.061*in

lda模型中的每个主题单词都有概率意义,其加和为1,值越大权重越大,物理意义比较明确,不过反过来再看这三篇文档训练的2个主题的LDA模型太平均了,没有说服力。

好了,我们回到LSI模型,有了LSI模型,我们如何来计算文档直接的相思度,或者换个角度,给定一个查询Query,如何找到最相关的文档?当然首先是建索引了:

>>> index = similarities.MatrixSimilarity(lsi[corpus])

2013-05-27 19:50:30,282 : INFO : scanning corpus to determine the number of features

2013-05-27 19:50:30,282 : INFO : creating matrix for 3 documents and 2 features

还是以这篇英文tutorial中的查询Query为例:gold silver truck。首先将其向量化:

>>> query = "gold silver truck"

>>> query_bow = dictionary.doc2bow(query.lower().split())

>>> print query_bow

[(3, 1), (9, 1), (10, 1)]

再用之前训练好的LSI模型将其映射到二维的topic空间:

>>> query_lsi = lsi[query_bow]

>>> print query_lsi

[(0, 1.1012835748628467), (1, 0.72812283398049593)]

最后就是计算其和index中doc的余弦相似度了:

>>> sims = index[query_lsi]

>>> print list(enumerate(sims))

[(0, 0.40757114), (1, 0.93163693), (2, 0.83416492)]

当然,我们也可以按相似度进行排序:

>>> sort_sims = sorted(enumerate(sims), key=lambda item: -item[1])

>>> print sort_sims

[(1, 0.93163693), (2, 0.83416492), (0, 0.40757114)]

可以看出,这个查询的结果是doc2 > doc3 > doc1,和fast tutorial是一致的,虽然数值上有一些差别:

好了,这个例子就到此为止,下一节我们将主要说明如何基于gensim计算课程图谱上课程之间的主题相似度,同时考虑一些改进方法,包括借助英文的自然语言处理工具包NLTK以及用更大的维基百科的语料来看看效果。

未完待续...

python如何寻找两个相似的文件_如何计算两个文档的相似度(二)相关推荐

  1. linux 预览md文件_利用Tornado搭建文档预览系统

    在平时的工作或学习中,我们经常会接触不同格式的文档类型,比如txt,log,Offices文档,编程代码脚本,图片,视频等.本文将会介绍笔者的一个朴素想法,即把不同格式的文档都放在同一个平台中进行预览 ...

  2. mapgis明码文件转为点线面文件_手机上word文档可以转为pdf文件吗?

    此前小北曾经为大家介绍了如何在电脑上转换文件的格式,例如WORD转PDF,PDF转EXCEL,PPT转PDF等等,这不,就有网友来问了,说日常办公其实很少会用到电脑,因为长期都需要在外面跑业务,很多时 ...

  3. 如何用matlaab把csv转为mat文件_如何编辑pdf文档?看大神们是如何操作的

    伙伴们,你们在日常工作中是不是经常使用pdf文档?我这几天需要给部门主管整理一些企划方案,但发送给他之后才发现里面有几个错别字,天呐,当时可吓呆我了,便立马撤回,可怎么快速修改文档中的错别字呢?总不能 ...

  4. Python自动化办公学习- 获取文件夹下的所有文档的名字并存储到Excel

    Python自动化办公学习- 获取文件夹下的所有文档的名字并存储到Excel 这是我第一次学习使用csdn发布学习笔记,如有版权侵犯,引用不当的地方,请立即提示我,我会删除,谢谢. 笔记中如有解释错误 ...

  5. Python遍历文件夹下的word文档并写入内容

    import os import docx spam=os.listdir('D:\\1')#获取文件夹下的word文档列表 print(spam) for i in spam: doc=docx.D ...

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

    下面的内容转自我爱自然语言处理博客,感谢博主,学到很多东西. 原文链接:http://www.52nlp.cn/%E5%A6%82%E4%BD%95%E8%AE%A1%E7%AE%97%E4%B8%A ...

  7. 计算机毕业设计Python+djang公务员考试信息管理系统(源码+系统+mysql数据库+Lw文档)

    项目介绍 随着社会的发展,近些年来的毕业生大多数会选择考研,考公员和考试教师资格证以增加自己在未来社会中的竞争能力.为了让这些有志之士能够有一个更好的学习和交流平台,我们通过计Python+djang ...

  8. Wps文件如何转成word文档

    Wps与word是大家日常学习办公当中使用得两种文字编辑工具.虽然说两者的功能大径相同,操作难易度也差不多.但是每个人都有自己的操作习惯,有人就习惯使用word工具.因此学习工作当中的文件格式也都是w ...

  9. php 上传ppt,PHP实现文件上传PPT精品文档

    <PHP实现文件上传PPT精品文档>由会员分享,可在线阅读,更多相关<PHP实现文件上传PPT精品文档(11页珍藏版)>请在人人文库网上搜索. 1.1,PHP实现HTTP文件上 ...

最新文章

  1. 2022-2028年中国除螨仪行业市场前瞻与投资战略规划分析报告
  2. java(系统)实战1
  3. Linux 最常用命令
  4. 所属的用户_关于chmod(变更用户对此文件的相关权限)超详细说明,小白秒懂
  5. macOS修改Homebrew镜像
  6. Python字符串详解
  7. Leetcode 53.最大子序列和
  8. Java EE开发四大常用框架(1)
  9. 42表盘直径是从哪测量_万用表测量电容容量的方
  10. Easyui按钮图标
  11. 翻译:Towards Lingua Franca Named Entity Recognition with BERT(基于BERT的通用语命名实体识别)
  12. 钩子(hook)编程
  13. NMAKE makefile内容和功能
  14. 比管理时间重要 1000 倍的,是管理精力
  15. 不同格式导入EndNote方法总结
  16. ASO关键词排名的三种优化方式,aso关键词排名优化是
  17. Android 活用RecyclerView分割线
  18. 2020年中国新基建人工智能产业链全景图深度分析汇总(附完整企业名单)
  19. 2020 年中科院计算所“计算未来”全国大学生暑期班 网络数据科学与技术重点实验室 机试试题
  20. Linux shell: ls命令详解

热门文章

  1. oracle decode(nvl(estimate_qty,0),0,1,estimate_qty) 函數
  2. 【leetcode刷题笔记】Restore IP Addresses
  3. document.getElementsByName , document.getElementsByTagName ,document.createElement
  4. fastdfs 报错 err: TrackerTask RecvHeader recv resp status 28 != 0
  5. Ubuntu18.04安装“迅雷“
  6. Win10推荐一款Terminal
  7. android audio arch
  8. 从最大似然再看线性回归
  9. directsound之播放pcm
  10. Win_server_2012如何将“计算机”图标放在桌面