Python与自然语言处理(二)基于Gensim的Word2Vec

继续学习摸索,看到很多博客都在研究Word2Vec,感觉挺有意思,我也来尝试一下。

实验环境:Python3,Java8

Word2Vec的输入是句子序列,而每个句子又是一个单词列表,由于没有这样结构的现成输入,所以决定自己动手对原始语料进行预处理。

NLPIR是一个汉语分词系统,挺感谢张华平博士,便利了我们的文本处理工作。下载地址:http://ictclas.nlpir.org/newsdownloads?DocId=389

这里还有一个自然语言处理与信息检索共享平台(感觉挺好的,有资料,还有演示,个人觉得那个在线演示挺赞的):http://www.nlpir.org/

NLPIR可以应用于C/C++/C#/Java/Python,我尝试了Java和Python两个版本,只是Python版在测试的时候报错:初始化失败!费解了半天也没找出到底是什么原因,因而先转向使用Java版的。

NLPIR-Java使用起来比较简单,首先下载zip文件,我的是【20160405172043_ICTCLAS2016分词系统下载包.zip】

然后解压,调用sample目录下的JnaTest_NLPIR项目即可。有两个地方需要注意:第16行的dll路径,根据自己的路径修改,可以考虑放在项目里;第44行的ICTCLAS路径,即解压文件里的bin下的ICTCLAS2015文件夹的路径,也可以考虑放在项目里。如果这两个文件是放在项目里的,那么解压文件里还有一个Data文件夹需要放在项目里的ICTCLAS2015下。结构如下:

修改好后便可以测试了。

package code;

import java.io.UnsupportedEncodingException;

import utils.SystemParas;

import com.sun.jna.Library;
import com.sun.jna.Native;

public class NlpirTest {

	// 定义接口CLibrary,继承自com.sun.jna.Library
	public interface CLibrary extends Library {
		// 定义并初始化接口的静态变量,该路径根据实际dll路径修改,32位或64位也根据实际情况修改
		CLibrary Instance = (CLibrary) Native.loadLibrary(
				"D:\\NLPIR\\bin\\ICTCLAS2013\\x64\\NLPIR", CLibrary.class);

		public int NLPIR_Init(String sDataPath, int encoding,
				String sLicenceCode);

		public String NLPIR_ParagraphProcess(String sSrc, int bPOSTagged);

		public String NLPIR_GetKeyWords(String sLine, int nMaxKeyLimit,
				boolean bWeightOut);
		public String NLPIR_GetFileKeyWords(String sLine, int nMaxKeyLimit,
				boolean bWeightOut);
		public int NLPIR_AddUserWord(String sWord);//add by qp 2008.11.10
		public int NLPIR_DelUsrWord(String sWord);//add by qp 2008.11.10
		public String NLPIR_GetLastErrorMsg();
		public void NLPIR_Exit();
	}

	public static String transString(String aidString, String ori_encoding,
			String new_encoding) {
		try {
			return new String(aidString.getBytes(ori_encoding), new_encoding);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static void main(String[] args) throws Exception {
		String argu = "D:\\NLPIR";
		// String system_charset = "GBK";//GBK----0
		String system_charset = "UTF-8"; //UTF-8----1
		int charset_type = 1;

		int init_flag = CLibrary.Instance.NLPIR_Init(argu, charset_type, "0");
		String nativeBytes = null;

		if (0 == init_flag) {
			nativeBytes = CLibrary.Instance.NLPIR_GetLastErrorMsg();
			System.err.println("初始化失败!fail reason is "+nativeBytes);
			return;
		}
                //sInput是原始待处理字符串
               String sInput = "据悉,质检总局已将最新有关情况再次通报美方,要求美方加强对输华玉米的产地来源、运输及仓储等环节的管控措施,有效避免输华玉米被未经我国农业部安全评估并批准的转基因品系污染。";

		try {
                        //分词和标注处理,1表示标注,0表示不标注
                       nativeBytes = CLibrary.Instance.NLPIR_ParagraphProcess(sInput, 1);

			System.out.println("分词结果为: " + nativeBytes);
			//添加用户自定义词语
			CLibrary.Instance.NLPIR_AddUserWord("要求美方加强对输 n");
			CLibrary.Instance.NLPIR_AddUserWord("华玉米的产地来源 n");
			nativeBytes = CLibrary.Instance.NLPIR_ParagraphProcess(sInput, 1);
			System.out.println("增加用户词典后分词结果为: " + nativeBytes);
			//删除用户自定义词语
			CLibrary.Instance.NLPIR_DelUsrWord("要求美方加强对输");
			nativeBytes = CLibrary.Instance.NLPIR_ParagraphProcess(sInput, 1);
			System.out.println("删除用户词典后分词结果为: " + nativeBytes);

			int nCountKey = 0;
                        //获取关键词,第二个参数是最大关键词数量,默认为50;第三个参数表示是否输出权重
                        //每个关键词以#分隔,若有权重输出,则权重分别为信息熵权重与词频权重,权重以/分隔
                       String nativeByte = CLibrary.Instance.NLPIR_GetKeyWords(sInput, 10,false);

			System.out.print("关键词提取结果是:" + nativeByte);
                        //获取文件关键词,第二个参数是最大关键词数量,默认为50;第三个参数表示是否输出
                        //权重,该权重表示信息熵权重。
                        //测试NLPIR的readme文件
                       nativeByte = CLibrary.Instance.NLPIR_GetFileKeyWords("D:/Readme.txt", 10,false);
			System.out.print("关键词提取结果是:" + nativeByte);

                        //退出
			CLibrary.Instance.NLPIR_Exit();

		} catch (Exception ex) {
			// TODO Auto-generated catch block
			ex.printStackTrace();
		}
	}
}

测试输出:

分词结果为: 据悉/v ,/wd 质检/vn 总局/n 已/d 将/d 最新/a 有关/vn 情况/n 再次/d 通报/v 美方/n ,/wd 要求/v 美方/n 加强/v 对/p 输/v 华/b 玉米/n 的/ude1 产地/n 来源/n 、/wn 运输/vn 及/cc 仓储/vn 等/udeng 环节/n 的/ude1 管/v 控/v 措施/n ,/wd 有效/ad 避免/v 输/v 华/b 玉米/n 被/pbei 未经/d 我国/n 农业部/nt 安全/an 评估/vn 并/cc 批准/v 的/ude1 转基因/n 品系/n 污染/vn 。/wj
增加用户词典后分词结果为: 据悉/v ,/wd 质检/vn 总局/n 已/d 将/d 最新/a 有关/vn 情况/n 再次/d 通报/v 美方/n ,/wd 要求美方加强对输/n 华玉米的产地来源/n 、/wn 运输/vn 及/cc 仓储/vn 等/udeng 环节/n 的/ude1 管/v 控/v 措施/n ,/wd 有效/ad 避免/v 输/v 华/b 玉米/n 被/pbei 未经/d 我国/n 农业部/nt 安全/an 评估/vn 并/cc 批准/v 的/ude1 转基因/n 品系/n 污染/vn 。/wj
删除用户词典后分词结果为: 据悉/v ,/wd 质检/vn 总局/n 已/d 将/d 最新/a 有关/vn 情况/n 再次/d 通报/v 美方/n ,/wd 要求/v 美方/n 加强/v 对/p 输/v 华玉米的产地来源/n 、/wn 运输/vn 及/cc 仓储/vn 等/udeng 环节/n 的/ude1 管/v 控/v 措施/n ,/wd 有效/ad 避免/v 输/v 华/b 玉米/n 被/pbei 未经/d 我国/n 农业部/nt 安全/an 评估/vn 并/cc 批准/v 的/ude1 转基因/n 品系/n 污染/vn 。/wj
字符串关键词提取结果是:华玉米的产地来源#农业部#有关#污染#
文件关键词提取结果是:NLPIR#ICTCLAS#NLPIR2014#Website#ICTCLAS2014#Linux#Readme.txt#test#Java#English.txt#

分词、词性标注和关键词提取的功能均可用,其他功能可以参考NLPIR下的doc目录里的使用说明文件。

用NLPIR对原始语料分词后,将分词结果保存在corpus_result.txt文件中,接下来将该文件应用于Python版的Word2Vec中。

首先需要在Python中安装gensim,可用命令pip install gensim

安装完成后,在程序中import gensim即可使用。

import logging
import os
import time

import gensim
from gensim.models import word2vec
import jieba
import nltk

logging.basicConfig(format='%(asctime)s:%(levelname)s:%(message)s',level=logging.INFO)
sentences = []
start1 = time.clock()

file = open('D:/corpus_result.txt','r',encoding='utf-8')
<pre name="code" class="python">contents = file.read()

print(‘读取文件耗时:‘,time.clock()

print(‘分词耗时:‘,time.clock())for line in file.readlines(): #按行读取 sentences.append(line.split(" "))# print(sentences)# print(len(sentences))

#sentences是句子序列,句子又是单词列表,

#如[[‘蒙牛‘,‘牛奶‘,‘好喝‘],[‘三星‘,‘手机‘],[‘名车‘,‘抢眼‘,‘奥迪‘,‘拍照‘]]

#min_count表示小于该数的单词会被剔除,默认值为5

#size表示神经网络的隐藏层单元数,默认为100

model = word2vec.Word2Vec(sentences,min_count=2,size=200)

#保存生成的训练模型

model.save(‘model/mymodel4‘)#加载模型文件new_model = gensim.models.Word2Vec.load(‘model/mymodel4‘)

#与“蒙牛”相似的词语,倒排

print(new_model.most_similar(‘蒙牛‘))

#计算词1和词2的余弦相似度

print(‘蒙牛 -- 伊利 间的余弦距离:‘,new_model.similarity(‘蒙牛‘,‘伊利‘))

#计算两个数据集间的余弦相似度

print(‘【三星 手机】--【安卓 手机】间的余弦距离:‘,new_model.n_similarity([‘三星‘,‘手机‘], [‘安卓‘,‘手机‘])) print(‘【牛奶 伊利 iPhone 蒙牛】 中不同的一项是:‘,new_model.doesnt_match(‘牛奶 伊利 iPhone 蒙牛‘.split()))


首先是训练模型,corpus_result.txt大小为4.5M,训练耗时30min,单机下时间还是挺长的。

然后是根据模型计算,输出结果:

[('伊利', 0.9417093992233276), ('奶', 0.9356977343559265), ('牛奶', 0.9347156286239624), ('君乐宝', 0.9280596971511841), ('@张俊英ZJY', 0.918419361114502), ('@弓长王月图样图森破', 0.912131667137146), ('氰', 0.9068763256072998), ('胺', 0.9067373275756836), ('海盐', 0.9053752422332764), ('下毒', 0.902400553226471)]
蒙牛 -- 伊利  间的余弦距离: 0.941709369359
【三星  手机】--【安卓 手机】间的余弦距离: 0.962285233171
【牛奶  伊利 iPhone 蒙牛】 中不同的一项是: iPhone

内存使用情况,word2vec的参数存在在numpy array中,主要有这样三个矩阵,如果有100000个单词,隐藏层单元数为200,那么所需内存大小为100000*200*4*3bytes,约229MB。

现在NLPIR-Java和Word2Vec-Python都可以简单使用起来,接下来就是学习其原理,继续努力!

另外还要感谢一些博主的知识分享:

[1] http://www.mamicode.com/info-detail-870051.html

[2] http://ju.outofmemory.cn/entry/80023

[3] http://www.tuicool.com/articles/7ZnUnq

时间: 2024-10-12 17:32:39

Python与自然语言处理(二)基于Gensim的Word2Vec的相关文章

进击的Python【第十二章】:mysql介绍与简单操作,sqlachemy介绍与简单应用

进击的Python[第十二章]:mysql介绍与简单操作,sqlachemy介绍与简单应用 一.数据库介绍 什么是数据库? 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库,每个数据库都有一个或多个不同的API用于创建,访问,管理,搜索和复制所保存的数据.我们也可以将数据存储在文件中,但是在文件中读写数据速度相对较慢.所以,现在我们使用关系型数据库管理系统(RDBMS)来存储和管理的大数据量.所谓的关系型数据库,是建立在关系模型基础上的数据库,借助于集合代数等数学概念和方法来

Python基本语法,python入门到精通[二]

在上一篇博客Windows搭建python开发环境,python入门到精通[一]我们已经在自己的windows电脑上搭建好了python的开发环境,这篇博客呢我就开始学习一下Python的基本语法.现在练习的开发环境是基于windows的,如果有朋友喜欢linux或者mac的话,只要有需求,我后续的可以给出对应的博文介绍,其实也是换汤不换药,没需求我就懒得说了. v写在前面 python你不去认识它,可能没什么,一旦你认识了它,你就会爱上它 v郑重承诺 我承认,现在园子里烂尾的系列博文比比皆是,

python机器学习实战(二)

python机器学习实战(二) 版权声明:本文为博主原创文章,转载请指明转载地址 http://www.cnblogs.com/fydeblog/p/7159775.html 前言 这篇notebook是关于机器学习监督学习中的决策树算法,内容包括决策树算法的构造过程,使用matplotlib库绘制树形图以及使用决策树预测隐形眼睛类型. 操作系统:ubuntu14.04(win也ok)   运行环境:anaconda-python2.7-jupyter notebook    参考书籍:机器学习

用Python做自然语言处理必知的八个工具【转载】

Python以其清晰简洁的语法.易用和可扩展性以及丰富庞大的库深受广大开发者喜爱.其内置的非常强大的机器学习代码库和数学库,使Python理所当然成为自然语言处理的开发利器. 那么使用Python进行自然语言处理,要是不知道这8个工具就真的Out了. NLTK NLTK是使用Python处理语言数据的领先平台.它为像WordNet这样的词汇资源提供了简便易用的界面.它还具有为文本分类(classification).文本标记(tokenization).词干提取(stemming).词性标记(t

Docker最全教程之Python爬网实战(二十一)

原文:Docker最全教程之Python爬网实战(二十一) Python目前是流行度增长最快的主流编程语言,也是第二大最受开发者喜爱的语言(参考Stack Overflow 2019开发者调查报告发布).笔者建议.NET.Java开发人员可以将Python发展为第二语言,一方面Python在某些领域确实非常犀利(爬虫.算法.人工智能等等),另一方面,相信我,Python上手完全没有门槛,你甚至无需购买任何书籍! 由于近期在筹备4.21的长沙开发者大会,耽误了不少时间.不过这次邀请到了腾讯资深技术

gensim的word2vec如何得出词向量(python)

首先需要具备gensim包,然后需要一个语料库用来训练,这里用到的是skip-gram或CBOW方法,具体细节可以去查查相关资料,这两种方法大致上就是把意思相近的词映射到词空间中相近的位置. 语料库test8下载地址: http://mattmahoney.net/dc/text8.zip 这个语料库是从http://blog.csdn.net/m0_37681914/article/details/73861441这篇文章中找到的. 检查语料是否需要做预处理:将数据下载好了解压出来,在做词向量

2. 蛤蟆Python脚本学习笔记二基本命令畅玩

2. 蛤蟆Python脚本学习笔记二基本命令畅玩 本篇名言:"成功源于发现细节,没有细节就没有机遇,留心细节意味着创造机遇.一件司空见惯的小事或许就可能是打开机遇宝库的钥匙!" 下班回家,咱先来看下一些常用的基本命令. 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/48092873 1.  数字和表达式 看下图1一就能说明很多问题: 加法,整除,浮点除,取模,幂乘方等.是不是很直接也很粗暴. 关于上限,蛤蟆不太清楚

简明Python教程笔记(二)----用户交互raw_input()

raw_input() python内建函数 将所有输入看做字符串,返回字符串类型 input()对待纯数字输入时具有自己的特性,它返回所输入的数字的类型( int, float ) input() 本质上还是使用 raw_input() 来实现的,只是调用完 raw_input() 之后再调用 eval() 函数 例子: #!/usr/bin/env pythonthis_year = 2014name = raw_input('please input your name:')age1 =

python 网络编程 (二)---tcp

异常 python的socket模块实际上定义了4种可能出现的异常: 1)与一般I/O 和通信问题有关的socket.error; 2)与查询地址信息有关的socket.gaierror; 3)与其他地址错误有关的socket.herror; 4)与在一个socket上调用settimeout()后,处理超时有关的socket.timeout; import socket, sys, time host = sys.argv[1] textport = sys.argv[2] filename