Classify Text With NLTK

Classification is the task of choosing the correct class label for a given input.

A classifier is called supervised if it is built based on training corpora containing the correct label for each input.

这里就以一个例子来说明怎样用nltk来实现分类器训练和分类

一个简单的分类任务,给定一个名字,判断其性别,就是在male,female两类进行分类

好,先来训练,训练就要有corpus,就是分好类的名字的例子

nltk提供了names的corpus

>>> from nltk.corpus import names

>>> names.words(''male.txt'')  #男性的name的列表

>>> names.words(''female.txt'') #女性的name的列表

有了训练corpus,下面就是特征提取

The first step in creating a classifier is deciding what features of the input are relevant, and how to encode those features.

这里简单的假设这个名字的性别和最后一个字母相关,那么就把最后一个字母作为每个test case的特征

>>> def gender_features(word):
...         return {''last_letter'': word[-1]}
>>> gender_features(''Shrek'')

{''last_letter'': ''k''}

所以就定义如上的特征抽取函数,并用它来生成我们的训练集和测试集

>>> from nltk.corpus import names
>>> import random
>>> names = ([(name, ''male'') for name in names.words(''male.txt'')] +
...         [(name, ''female'') for name in names.words(''female.txt'')])
>>> random.shuffle(names)  #原来的name是按字母排序的,为了达到比较好的训练效果,必须打乱顺序,随机化

>>> featuresets = [(gender_features(n), g) for (n,g) in names]

>>> train_set, test_set = featuresets[500:], featuresets[:500] #把特征集一部分作为train集,一部分用来测试
>>> classifier = nltk.NaiveBayesClassifier.train (train_set) #用训练集来训练bayes分类器

>>> classifier.classify (gender_features(''Trinity'')) #训练完就可以用这个分类器来实际进行分类工作了
''female''

用测试集来测试

>>> print nltk.classify.accuracy (classifier, test_set) #用测试集来测试这个分类器,nltk提供accuracy接口
0.758

现在只考虑了最后一个字母这个特征,准确率是75%,显然还有很大的提升空间。

>>> classifier.show_most_informative_features (5) #这个接口有意思, 你可以显示出区分度最高的几个features
Most Informative Features
last_letter = ''a''     female : male = 38.3 : 1.0
last_letter = ''k''     male : female = 31.4 : 1.0
last_letter = ''f''      male : female = 15.3 : 1.0
last_letter = ''p''     male : female = 10.6 : 1.0
last_letter = ''w''    male : female = 10.6 : 1.0

nltk接口很贴心,还考虑到你内存太小,放不下所有的feature集合,提供这个接口来当用到时,实时的计算feature

>>> from nltk.classify import apply_features  
>>> train_set = apply_features (gender_features, names[500:])
>>> test_set = apply_features(gender_features, names[:500])

分类器分类效果好坏很大取决于训练集的特征选取,特征选取的比较合理,就会取得比较好的分类效果。

当然特征也不是选取的越多越好,

if you provide too many features, then the algorithm will have a higher chance of relying on idiosyncrasies of your training data that don’t generalize well to new examples. This problem is known as overfitting , and can be especially problematic when working with small training sets.

所以特征抽取这个在分类领域中是一个很重要的研究方向。

 

比如把上面那个例子的特征增加为,分别把最后两个字符,作为两个特征, 这样会发现分类器测试的准确性有所提高。

>>> def gender_features(word):
...         return {''suffix1'': word[-1:],
...                      ''suffix2'': word[-2:]}

 

但是如果把特征增加为,首字母,尾字母,并统计每个字符的出现次数,反而会导致overfitting,测试准确性反而不如之前只考虑尾字母的情况

def gender_features2(name):
    features = {}
    features["firstletter"] = name[0].lower()
    features["lastletter"] = name[–1].lower()
    for letter in ''abcdefghijklmnopqrstuvwxyz'':
        features["count(%s)" % letter] = name.lower().count(letter)
        features["has(%s)" % letter] = (letter in name.lower())
    return features
>>> gender_features2(''John'')
{''count(j)'': 1, ''has(d)'': False, ''count(b)'': 0, ...}

>>> featuresets = [(gender_features2(n), g) for (n,g) in names]
>>> train_set, test_set = featuresets[500:], featuresets[:500]
>>> classifier = nltk.NaiveBayesClassifier.train(train_set)
>>> print nltk.classify.accuracy(classifier, test_set)
0.748

 

那么上面这个简单的方法已经讲明了用nltk,进行分类的过程,那么剩下的就是针对不同的分类任务,特征的选取上会有不同,还有分类器的也不止bayes一种,可以针对不同的任务来选取。

比如对于文本分类,可以选取是否包含特征词汇作为文本特征

all_words = nltk.FreqDist(w.lower() for w in movie_reviews.words())
word_features = all_words.keys()[:2000] #找出出现频率较高的特征词,虽然这个找法不太合理
def document_features(document):
    document_words = set(document)
    features = {}
    for word in word_features:
        features[''contains(%s)'' % word] = (word in document_words)
    return features
>>> print document_features(movie_reviews.words(''pos/cv957_8737.txt''))
{''contains(waste)'': False, ''contains(lot)'': False, ...}

 

对于pos tagging,我们也可以用分类的方法去解决

比如我们可以通过词的后缀来判断它的词性, 这边就以是否包含常见的词的后缀作为特征

>>> def pos_features(word):
...     features = {}
...     for suffix in common_suffixes:
...         features[''endswith(%s)'' % suffix] = word.lower().endswith(suffix)
...     return features

当然这个特征选取的比较简单,那么改进一下,根据后缀,并考虑context,即前一个词和词性,一起作为特征,这样考虑就比较全面了。后缀之所以要考虑3种情况,是因为一般表示词性的后缀,最多3个字符,s,er,ing

def pos_features(sentence, i, history):
    features = {"suffix(1)": sentence[i][-1:],
                       "suffix(2)": sentence[i][-2:],
                       "suffix(3)": sentence[i][-3:]}
    if i == 0:
        features["prev-word"] = "<START>"
        features["prev-tag"] = "<START>"
    else:
        features["prev-word"] = sentence[i-1]
        features["prev-tag"] = history[i-1] #history里面存放了句子里面每个词的词性
    return features

那么分类器,除了bayes外,nltk还有decision tree, Maximum Entropy classifier就不具体说了

还有对于大规模数据处理, pure python的分类器的效率相对是比较底下的,所以必须用高效的语言如c语言实现的分类器, NLTK也支持这样的分类器的package,可以参考NLTK的web page。

本文章摘自博客园,原文发布日期:2011-07-04

时间: 2024-09-10 19:39:44

Classify Text With NLTK的相关文章

Extracting Information from Text With NLTK

因为现实中的数据多为'非结构化数据',比如一般的txt文档,或是'半结构化数据',比如html,对于这样的数据需要采用一些技术才能从中提取 出有用的信息.如果所有数据都是'结构化数据',比如Xml或关系数据库,那么就不需要特别去提取了,可以根据元数据去任意取到你想要的信息. 那么就来讨论一下用NLTK来实现文本信息提取的方法, first, the raw text of the document is split into sentences using a sentence segmente

语义情感趋势分析入门的一份译稿

郑昀 201007 原标题:Working on Sentiment Analysis on Twitter with Portuguese Language  原作者:Artificial Intelligence in Motion 原作发表日期:2010年7月20日 原文地址:http://aimotion.blogspot.com/2010/07/working-on-sentiment-analysis-on.html 虽然是讲葡萄牙语下的情感分析,但作为一个入门指导也有可看之处. 摘

探索 Python、机器学习和 NLTK 库

简介: 机器学习取决于 IT.数学和自然语言的交集,在大数据应用程序中会通常用到机器学习.本文将讨论 Python 编程语言和它的 NLTK 库,然后将它们应用于一个机器学习项目. 挑战:使用机器学习对 RSS 提要进行分类 最近,我接到一项任务,要求为客户创建一个 RSS 提要分类子系统.目标是读取几十个甚至几百个 RSS 提要,将它们的许多文章自动分类到几十个预定义的主题领域当中.客户网站的内容.导航和搜索功能都将由这个每日自动提要检索和分类结果驱动. 客户建议使用机器学习,或许还会使用 A

[python+nltk] 自然语言处理简单介绍和NLTK坏境配置及入门知识(一)

        本文主要是总结最近学习的论文.书籍相关知识,主要是Natural Language Pracessing(自然语言处理,简称NLP)和Python挖掘维基百科Infobox等内容的知识.         此篇文章主要参考书籍<Natural Language Processing with Python>Python自然语言处理,希望对大家有所帮助.书籍下载地址:         官方网页版书籍:http://www.nltk.org/book/         CSDN下载地

nltk 自己训练模型例子

NLTK是Python的一个自然语言处理的模块,其中实现了朴素贝叶斯分类算法.以下,就使用上一篇文中提到的数据,来应用这个模块实现朴素贝叶斯分类.NLTK的实现更加泛化,所以在应用到我们的数据上时需要做一点的转化. 首先来看一下NLTK官方文档中给出的一个简单明了的例子,在了解这个例子之后,再设法将同样的模型应用到自己的数据集上.官方给出的例子是英文名中,在知道名字中最后一个字母后,判断这个名字对应的人是男是女. [python] view plain copy #coding=utf-8  

自然语言处理工具 nltk 安装使用

github 地址:https://github.com/nltk/nltk/ 官方地址:http://www.nltk.org/ 中文文档:http://download.csdn.net/detail/u013378306/9756747 安装及测试 Install NLTK: run sudo pip install -U nltk Install Numpy (optional): run sudo pip install -U numpy Test installation: run 

Python NLTK库安装Error:Resource u*corpora/gutenberg* not found.

转载请标明出处: http://blog.csdn.net/djy1992/article/details/72828734 本文出自:[奥特曼超人的博客] 提起聊天机器人, 想必大家会想起一个优秀的库,NLTK库,这里简化了安装流程并提到大家都会遇到的一个错误. Resource u*corpora/gutenberg* not found. Please use the NLTKDownloader to obtain the resource: 运行环境: WIN+Python 2.7 安

POS Tagging with NLTK

POS tagging :part-of-speech tagging , or word classes or lexical categories . 说法很多其实就是词性标注. 那么用nltk的工具集的off-the-shelf工具可以简单的对文本进行POS tagging >>> text = nltk.word_tokenize("And now for something completely different") >>> nltk.p

Javascript 遍历页面text控件详解

 本篇文章主要是对Javascript遍历页面text控件进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助 以下函数实现了列出页面中所有html控件类型为text的控件ID    代码如下:         function Texts()          {               //var els= document.getElementsByTagName("*");   //els得到页面所有控件               var els= document.