代码参考:
https://github.com/mkusner/wmd
安装好anaconda笔者这里用的是python3 64bit的版本
需要用到这个库,gensim
conda install -c conda-forge gensim
从参考代码的仓库上下载WMD代码:
git clone [email protected]:mkusner/wmd.git
接着需要下载google的一个公开的wordvector数据集:
https://drive.google.com/file/d/0B7XkCwpI5KDYNlNUTTlSS21pQmM/edit
下载好是一个1.5GB的tz格式的压缩包,解压以后3GB+的一个文件,把这个文件放到前面git上下载来的WMD目录下。
这里采用的是一个all_twitter_by_line的数据集,首先执行以下命令会生成twitter的文档向量,还包括所有词的word2vec,文档的BOW向量。
python get_word_vectors.py all_twitter_by_line.txt twitter_vec.pk twitter_vec.mat
注意最后一个参数会生成matlab用的数据格式,默认要传这个参数不然代码会报错,或者自己修改代码。
EMD有一个现成的包不过需要编译后才能使用。
这里讲一下编译方法(windows上,Linux下可以用g++, MacOSX下用clang)
1. 首先需要安装Mingw-x64编译环境或者vscode也可以
2. 接着安装SWIG工具包,他属于一个warpper中间件,能把用C,或者C++写的底层代码提供给其他高级语言使用。
在windows上有已经编译好的package:
http://prdownloads.sourceforge.net/swig/swigwin-4.0.1.zip
在环境变量PATH中添加swig解压后的目录:
3. 编译emd库(这里有很多坑,其实最直观的方法是用Visual Studio编译就完事了)
但是本人头铁,实在不想装Visual Studio这个庞然大物。
这里讲一下步骤。假设本人的anaconda的安装目录是
D:\ProgramData\Anaconda3
那么首先需要python37.dll 如果你的版本不是python37可以替换成自己的版本。这个步骤非常重要,否则用Mingw会编译一堆错误!
把这个Python37.dll 拷贝到你要编译emd的目录下,用Mingw-w64的命令行启动(这个在MIngw-w64下有一个mingw-w64.bat文件。)
执行一下命令:
gendef python37.dll
这里解释一下,首先windows上的Python发布版会提供一个叫Python37.lib的文件,这个lib默认是给微软的Visual Studio用的,如果你用GNU C Compiler来编译就会有一堆导入错误。原因是两者的导入段不同。所以这里需要生成GCC标准的导入段也就是libpython32.a (在Linux下和Unix下的可以忽略这个步骤,python发行版已经提供给你了)
接着根据 上面生成的python37.def文件使用dlltool生成一个叫libpython37.a的文件
dlltool --dllname python37.dll --def python37.def --output-lib libpython37.a
然后注意要把这个libpython37.a拷贝到python37.lib同一个目录下
笔者的电脑上是:
D:\ProgramData\Anaconda3\libs
有了这个准备工作就可以进行正常编译了!
编译代码如下:
# 编译emd.o文件
gcc -o emd.o -emd.c -fPIC -I D:/ProgramData/Anaconda3/include
# 使用SWIG生成接口
swig -python emd.i
# 编译emd_wrap.o文件
gcc -o emd.o -emd.c -fPIC -I D:/ProgramData/Anaconda3/include
# 链接成python库pyd文件
gcc -shared -L D:\ProgramData\Anaconda3\libs\ -o _emd.pyd emd.o emd_wrap.o -lpython37
最后把emd.py 和_emd.pyd两个文件拷贝到你项目的目录下就可以正常使用了。
测试一下emd是否编译正常:
可以正常使用。
最后计算3115篇文档的两两之间WMD距离,
耗时20分钟左右