Python自然语言处理工具小结

Python自然语言处理工具小结

作者:白宁超

2016年11月21日21:45:26


1 Python 的几个自然语言处理工具

  1. NLTK:NLTK 在用 Python 处理自然语言的工具中处于领先的地位。它提供了 WordNet 这种方便处理词汇资源的借口,还有分类、分词、除茎、标注、语法分析、语义推理等类库。
  2. Pattern:Pattern 的自然语言处理工具有词性标注工具(Part-Of-Speech Tagger),N元搜索(n-gram search),情感分析(sentiment analysis),WordNet。支持机器学习的向量空间模型,聚类,向量机。
  3. TextBlob:TextBlob 是一个处理文本数据的 Python 库。提供了一些简单的api解决一些自然语言处理的任务,例如词性标注、名词短语抽取、情感分析、分类、翻译等等。
  4. Gensim:Gensim 提供了对大型语料库的主题建模、文件索引、相似度检索的功能。它可以处理大于RAM内存的数据。作者说它是“实现无干预从纯文本语义建模的最强大、最高效、最无障碍的软件。
  5. PyNLPI:它的全称是:Python自然语言处理库(Python Natural Language Processing Library,音发作: pineapple) 这是一个各种自然语言处理任务的集合,PyNLPI可以用来处理N元搜索,计算频率表和分布,建立语言模型。他还可以处理向优先队列这种更加复杂的数据结构,或者像 Beam 搜索这种更加复杂的算法。
  6. spaCy:这是一个商业的开源软件。结合Python和Cython,它的自然语言处理能力达到了工业强度。是速度最快,领域内最先进的自然语言处理工具。
  7. Polyglot:Polyglot 支持对海量文本和多语言的处理。它支持对165种语言的分词,对196中语言的辨识,40种语言的专有名词识别,16种语言的词性标注,136种语言的情感分析,137种语言的嵌入,135种语言的形态分析,以及69中语言的翻译。
  8. MontyLingua:MontyLingua 是一个自由的、训练有素的、端到端的英文处理工具。输入原始英文文本到 MontyLingua ,就会得到这段文本的语义解释。适合用来进行信息检索和提取,问题处理,回答问题等任务。从英文文本中,它能提取出主动宾元组,形容词、名词和动词短语,人名、地名、事件,日期和时间,等语义信息。
  9. BLLIP Parser:BLLIP Parser(也叫做Charniak-Johnson parser)是一个集成了产生成分分析和最大熵排序的统计自然语言工具。包括 命令行 和 python接口 。
  10. Quepy:Quepy是一个Python框架,提供将自然语言转换成为数据库查询语言。可以轻松地实现不同类型的自然语言和数据库查询语言的转化。所以,通过Quepy,仅仅修改几行代码,就可以实现你自己的自然语言查询数据库系统。GitHub:https://github.com/machinalis/quepy
  11. HanNLP:HanLP是由一系列模型与算法组成的Java工具包,目标是普及自然语言处理在生产环境中的应用。不仅仅是分词,而是提供词法分析、句法分析、语义理解等完备的功能。HanLP具备功能完善、性能高效、架构清晰、语料时新、可自定义的特点。文档使用操作说明:Python调用自然语言处理包HanLP 和 菜鸟如何调用HanNLP

OpenNLP:进行中文命名实体识别

OpenNLP是Apach下的Java自然语言处理API,功能齐全。如下给大家介绍一下使用OpenNLP进行中文语料命名实体识别的过程。

首先是预处理工作,分词去听用词等等的就不啰嗦了,其实将分词的结果中间加上空格隔开就可以了,OpenNLP可以将这样形式的的语料照处理英文的方式处理,有些关于字符处理的注意点在后面会提到。

其次我们要准备各个命名实体类别所对应的词库,词库被存在文本文档中,文档名即是命名实体类别的TypeName,下面两个function分别是载入某类命名实体词库中的词和载入命名实体的类别。

/**
	 * 载入词库中的命名实体
	 *
	 * @param nameListFile
	 * @return
	 * @throws Exception
	 */
	public static List<String> loadNameWords(File nameListFile)
			throws Exception {
		List<String> nameWords = new ArrayList<String>();

		if (!nameListFile.exists() || nameListFile.isDirectory()) {
			System.err.println("不存在那个文件");
			return null;
		}

		BufferedReader br = new BufferedReader(new FileReader(nameListFile));
		String line = null;
		while ((line = br.readLine()) != null) {
			nameWords.add(line);
		}

		br.close();

		return nameWords;
	}

	/**
	 * 获取命名实体类型
	 *
	 * @param nameListFile
	 * @return
	 */
	public static String getNameType(File nameListFile) {
		String nameType = nameListFile.getName();

		return nameType.substring(0, nameType.lastIndexOf("."));
	}

因为OpenNLP要求的训练语料是这样子的:

XXXXXX<START:Person>????<END>XXXXXXXXX<START:Action>????<END>XXXXXXX

被标注的命名实体被放在<START><END>范围中,并标出了实体的类别。接下来是对命名实体识别模型的训练,先上代码:

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringReader;
import java.util.Collections;

import opennlp.tools.namefind.NameFinderME;
import opennlp.tools.namefind.NameSample;
import opennlp.tools.namefind.NameSampleDataStream;
import opennlp.tools.namefind.TokenNameFinderModel;
import opennlp.tools.util.ObjectStream;
import opennlp.tools.util.PlainTextByLineStream;
import opennlp.tools.util.featuregen.AggregatedFeatureGenerator;
import opennlp.tools.util.featuregen.PreviousMapFeatureGenerator;
import opennlp.tools.util.featuregen.TokenClassFeatureGenerator;
import opennlp.tools.util.featuregen.TokenFeatureGenerator;
import opennlp.tools.util.featuregen.WindowFeatureGenerator;

/**
 * 中文命名实体识别模型训练组件
 *
 * @author ddlovehy
 *
 */
public class NamedEntityMultiFindTrainer {

	// 默认参数
	private int iterations = 80;
	private int cutoff = 5;
	private String langCode = "general";
	private String type = "default";

	// 待设定的参数
	private String nameWordsPath; // 命名实体词库路径
	private String dataPath; // 训练集已分词语料路径
	private String modelPath; // 模型存储路径

	public NamedEntityMultiFindTrainer() {
		super();
		// TODO Auto-generated constructor stub
	}

	public NamedEntityMultiFindTrainer(String nameWordsPath, String dataPath,
			String modelPath) {
		super();
		this.nameWordsPath = nameWordsPath;
		this.dataPath = dataPath;
		this.modelPath = modelPath;
	}

	public NamedEntityMultiFindTrainer(int iterations, int cutoff,
			String langCode, String type, String nameWordsPath,
			String dataPath, String modelPath) {
		super();
		this.iterations = iterations;
		this.cutoff = cutoff;
		this.langCode = langCode;
		this.type = type;
		this.nameWordsPath = nameWordsPath;
		this.dataPath = dataPath;
		this.modelPath = modelPath;
	}

	/**
	 * 生成定制特征
	 *
	 * @return
	 */
	public AggregatedFeatureGenerator prodFeatureGenerators() {
		AggregatedFeatureGenerator featureGenerators = new AggregatedFeatureGenerator(
				new WindowFeatureGenerator(new TokenFeatureGenerator(), 2, 2),
				new WindowFeatureGenerator(new TokenClassFeatureGenerator(), 2,
						2), new PreviousMapFeatureGenerator());

		return featureGenerators;
	}

	/**
	 * 将模型写入磁盘
	 *
	 * @param model
	 * @throws Exception
	 */
	public void writeModelIntoDisk(TokenNameFinderModel model) throws Exception {
		File outModelFile = new File(this.getModelPath());
		FileOutputStream outModelStream = new FileOutputStream(outModelFile);
		model.serialize(outModelStream);
	}

	/**
	 * 读出标注的训练语料
	 *
	 * @return
	 * @throws Exception
	 */
	public String getTrainCorpusDataStr() throws Exception {

		// TODO 考虑入持久化判断直接载入标注数据的情况 以及增量式训练

		String trainDataStr = null;
		trainDataStr = NameEntityTextFactory.prodNameFindTrainText(
				this.getNameWordsPath(), this.getDataPath(), null);

		return trainDataStr;
	}

	/**
	 * 训练模型
	 *
	 * @param trainDataStr
	 *            已标注的训练数据整体字符串
	 * @return
	 * @throws Exception
	 */
	public TokenNameFinderModel trainNameEntitySamples(String trainDataStr)
			throws Exception {
		ObjectStream<NameSample> nameEntitySample = new NameSampleDataStream(
				new PlainTextByLineStream(new StringReader(trainDataStr)));

		System.out.println("**************************************");
		System.out.println(trainDataStr);

		TokenNameFinderModel nameFinderModel = NameFinderME.train(
				this.getLangCode(), this.getType(), nameEntitySample,
				this.prodFeatureGenerators(),
				Collections.<String, Object> emptyMap(), this.getIterations(),
				this.getCutoff());

		return nameFinderModel;
	}

	/**
	 * 训练组件总调用方法
	 *
	 * @return
	 */
	public boolean execNameFindTrainer() {

		try {
			String trainDataStr = this.getTrainCorpusDataStr();
			TokenNameFinderModel nameFinderModel = this
					.trainNameEntitySamples(trainDataStr);
			// System.out.println(nameFinderModel);
			this.writeModelIntoDisk(nameFinderModel);

			return true;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();

			return false;
		}
	}
}

注:

  • 参数:iterations是训练算法迭代的次数,太少了起不到训练的效果,太大了会造成过拟合,所以各位可以自己试试效果;
  • cutoff:语言模型扫描窗口的大小,一般设成5就可以了,当然越大效果越好,时间可能会受不了;
  • langCode:语种代码和type实体类别,因为没有专门针对中文的代码,设成“普通”的即可,实体的类别因为我们想训练成能识别多种实体的模型,于是设置为“默认”。

说明:

  • prodFeatureGenerators()方法用于生成个人订制的特征生成器,其意义在于选择什么样的n-gram语义模型,代码当中显示的是选择窗口大小为5,待测命名实体词前后各扫描两个词的范围计算特征(加上自己就是5个),或许有更深更准确的意义,请大家指正;
  • trainNameEntitySamples()方法,训练模型的核心,首先是将如上标注的训练语料字符串传入生成字符流,再通过NameFinderME的train()方法传入上面设定的各个参数,订制特征生成器等等,关于源实体映射对,就按默认传入空Map就好了。

源代码开源在:https://github.com/Ailab403/ailab-mltk4j,test包里面对应有完整的调用demo,以及file文件夹里面的测试语料和已经训练好的模型。

3 StanfordNLP:实现中文命名实体识别

// ‘);
// ]]>

使用Stanford Word Segmenter and Stanford Named Entity Recognizer (NER)实现中文命名实体识别 - 以家为家,以乡为乡,以国为国,以天下为天下 - 博客频道 - CSDN.NET

1、分词介绍

斯坦福大学的分词器,该系统需要JDK 1.8+,从上面链接中下载stanford-segmenter-2014-10-26,解压之后,如下图所示

进入data目录,其中有两个gz压缩文件,分别是ctb.gz和pku.gz,其中CTB:宾州大学的中国树库训练资料 ,PKU:中国北京大学提供的训练资料。当然了,你也可以自己训练,一个训练的例子可以在这里面看到http://nlp.stanford.edu/software/trainSegmenter-20080521.tar.gz

2、NER介绍

斯坦福NER是采用Java实现,可以识别出(PERSON,ORGANIZATION,LOCATION),使用本软件发表的研究成果需引用下述论文:

下载地址在:http://nlp.stanford.edu/~manning/papers/gibbscrf3.pdf

在NER页面可以下载到两个压缩文件,分别是stanford-ner-2014-10-26和stanford-ner-2012-11-11-chinese

将两个文件解压可看到

默认NER可以用来处理英文,如果需要处理中文要另外处理。

3、分词和NER使用

在Eclipse中新建一个Java Project,将data目录拷贝到项目根路径下,再把stanford-ner-2012-11-11-chinese解压的内容全部拷贝到classifiers文件夹下,将stanford-segmenter-3.5.0加入到classpath之中,将classifiers文件夹拷贝到项目根目录,将stanford-ner-3.5.0.jar和stanford-ner.jar加入到classpath中。最后,去http://nlp.stanford.edu/software/corenlp.shtml下载stanford-corenlp-full-2014-10-31,将解压之后的stanford-corenlp-3.5.0也加入到classpath之中。最后的Eclipse中结构如下:

Chinese NER:这段说明,很清晰,需要将中文分词的结果作为NER的输入,然后才能识别出NER来。

同时便于测试,本Demo使用junit-4.10.jar,下面开始上代码

import edu.stanford.nlp.ie.AbstractSequenceClassifier;
import edu.stanford.nlp.ie.crf.CRFClassifier;
import edu.stanford.nlp.ling.CoreLabel; 

/**
*
* <p>
* ClassName ExtractDemo
* </p>
* <p>
* Description 加载NER模块
*
*/
public class ExtractDemo {
private static AbstractSequenceClassifier<CoreLabel> ner;
public ExtractDemo() {
InitNer();
}
public void InitNer() {
String serializedClassifier = "classifiers/chinese.misc.distsim.crf.ser.gz"; // chinese.misc.distsim.crf.ser.gz
if (ner == null) {
ner = CRFClassifier.getClassifierNoExceptions(serializedClassifier);
}
} 

public String doNer(String sent) {
return ner.classifyWithInlineXML(sent);
} 

public static void main(String args[]) {
String str = "我 去 吃饭 , 告诉 李强 一声 。";
ExtractDemo extractDemo = new ExtractDemo();
System.out.println(extractDemo.doNer(str));
System.out.println("Complete!");
} 

}
import java.io.File;
import java.io.IOException;
import java.util.Properties; 

import org.apache.commons.io.FileUtils; 

import edu.stanford.nlp.ie.crf.CRFClassifier;
import edu.stanford.nlp.ling.CoreLabel; 

/**
*
* <p>
* Description 使用Stanford CoreNLP进行中文分词
* </p>
*
*/
public class ZH_SegDemo {
public static CRFClassifier<CoreLabel> segmenter;
static {
// 设置一些初始化参数
Properties props = new Properties();
props.setProperty("sighanCorporaDict", "data");
props.setProperty("serDictionary", "data/dict-chris6.ser.gz");
props.setProperty("inputEncoding", "UTF-8");
props.setProperty("sighanPostProcessing", "true");
segmenter = new CRFClassifier<CoreLabel>(props);
segmenter.loadClassifierNoExceptions("data/ctb.gz", props);
segmenter.flags.setProperties(props);
} 

public static String doSegment(String sent) {
String[] strs = (String[]) segmenter.segmentString(sent).toArray();
StringBuffer buf = new StringBuffer();
for (String s : strs) {
buf.append(s + " ");
}
System.out.println("segmented res: " + buf.toString());
return buf.toString();
} 

public static void main(String[] args) {
try {
String readFileToString = FileUtils.readFileToString(new File("澳门141人食物中毒与进食“问题生蚝”有关.txt"));
String doSegment = doSegment(readFileToString);
System.out.println(doSegment); 

ExtractDemo extractDemo = new ExtractDemo();
System.out.println(extractDemo.doNer(doSegment)); 

System.out.println("Complete!");
} catch (IOException e) {
e.printStackTrace();
} 

}
}

注意一定是JDK 1.8+的环境,最后输出结果如下:

时间: 2024-10-20 21:42:13

Python自然语言处理工具小结的相关文章

Python包管理工具小结

此文已由作者张耕源授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 作为一名接触Python有一段时间的初学者,越来越体会到Python的方便之处,它使人能更 多的关注业务本身的逻辑,而不用太纠结语言层面的技巧与细节.然而,随着服务的规模 变得越来越大,如何方便快速地制作与发布一个Python软件包则越来越成为一个让人头疼 地问题,特别是像Openstack这种相对复杂.各种依赖也很多的Python项目,到目前也没有 发现特别完美的解决方案.这里将尝试对Python的包管

Python 的十个自然语言处理工具

原文 先mark,后续尝试. 1.NLTK NLTK 在用 Python 处理自然语言的工具中处于领先的地位.它提供了 WordNet 这种方便处理词汇资源的借口,还有分类.分词.除茎.标注.语法分析.语义推理等类库. 网站 http://www.nltk.org/ 安装 安装 NLTK: sudo pip install -U nltk 安装 Numpy (可选): sudo pip install -U numpy 安装测试: python then type import nltk 2.P

Python深度学习自然语言处理工具Stanza试用!这也太强大了吧!

众所周知, 斯坦福大学自然语言处理组 出品了一系列NLP工具包,但是大多数都是用Java写得,对于Python用户不是很友好.几年前我曾基于斯坦福Java工具包和NLTK写过一个简单的中文分词接口: Python自然语言处理实践: 在NLTK中使用斯坦福中文分词器 ,不过用起来也不是很方便.深度学习自然语言处理时代,斯坦福大学自然语言处理组开发了一个纯Python版本的深度学习NLP工具包: Stanza - A Python NLP Library for Many Human Languag

Python 爬虫的工具列表

这个列表包含与网页抓取和数据处理的Python库 网络 通用 urllib -网络库(stdlib). requests -网络库. grab - 网络库(基于pycurl). pycurl - 网络库(绑定libcurl). urllib3 - Python HTTP库,安全连接池.支持文件post.可用性高. httplib2 - 网络库. RoboBrowser - 一个简单的.极具Python风格的Python库,无需独立的浏览器即可浏览网页. MechanicalSoup -一个与网站

python自然语言处理1——从网络抓取数据

python自然语言处理1--从网络抓取数据 写在前面 本节学习python2.7 BeautifulSoup库从网络抽取数据的技术,检验之简而言之就是爬虫技术.网络编程是一门复杂的技术,在需要基础的地方,文中给出的链接地址,都是很好的教程,可以参考,我在这里不在重复发明轮子.本节的主旨在于: 帮助快速掌握基本爬虫技术,形成一条主线,能为自己的实验构造基础数据.掌握爬虫技术后,可以从网络抓取符合特定需求的数据供分析,这里学习的爬虫技术适用于数据挖掘.自然语言处理等需要从外部挖掘数据的学科. 1.

python环境和工具

1.版本问题 python2.X和python3.X是不兼容,所以选择如果选择了2.X版本,那么为了避免兼容性的问题,在以后使用其他python库或者工具时,也需要选择相对应的版本. 下载地址:https://www.python.org/ 2.开发工具IDLE IDLE是python自身附带使用tkinter创建的图形化的交互式环境. 3.用tkinter编写GUI tkinter是python自带的用于GUI编程的库,是对图形库TK的封装,跨平台. 4.数值计算库NumPy和SciPy Nu

《Python自然语言处理》

<Python自然语言处理> 基本信息 作者: (美)Steven Bird    Ewan Klein    Edward Loper 出版社:人民邮电出版社 ISBN:9787115333681 上架时间:2014-6-13 出版日期:2014 年6月 开本:16开 页码:508 版次:1-1 所属分类:计算机 > 软件与程序设计 > Python 更多关于>>><Python自然语言处理> 内容简介 书籍 计算机书籍 自然语言处理(natural

Python 爬虫的工具列表 附Github代码下载链接

这个列表包含与网页抓取和数据处理的Python库 网络 通用 urllib -网络库(stdlib). requests -网络库. grab – 网络库(基于pycurl). pycurl – 网络库(绑定libcurl). urllib3 – Python HTTP库,安全连接池.支持文件post.可用性高. httplib2 – 网络库. RoboBrowser – 一个简单的.极具Python风格的Python库,无需独立的浏览器即可浏览网页. MechanicalSoup -一个与网站

车万翔《基于深度学习的自然语言处理》中英文PDF+涂铭《Python自然语言处理实战核心技术与算法》PDF及代码

自然语言处理是人工智能领域的一个重要的研究方向,是计算机科学与语言学的交叉学科.随着互联网的快速发展,网络文本尤其是用户生成的文本呈爆炸性增长,为自然语言处理带来了巨大的应用需求.但是由于自然语言具有歧义性.动态性和非规范性,同时语言理解通常需要丰富的知识和一定的推理能力,为自然语言处理带来了极大的挑战. 近年来快速发展的深度学习技术为解决自然语言处理问题的解决提供了一种可能的思路,已成为有效推动自然语言处理技术发展的变革力量. 推荐将深度学习理论运用至NLP中的资料<基于深度学习的自然语言处理