文本分类器

文本分类器

python分类器环境安装

安装NLTK

下载地址:http://www.nltk.org/

分类器介绍

分类器是模式识别中的一种应用,模式识别是自然语言处理的一个核心部分。

分类任务是对给定的输入,选择正确的"类别标签"。并且输入和所有其他输入隔离。

由于分类器的各自特点分为以下几类:

有监督分类器

如果分类的标签集是预先定义的,称为有监督分类器。

例如:

  • 垃圾邮件的判断。
  • 根据名字的最后一个字母,分辨性别。

如果分类的建立是根据每个输入的正确标签的训练预料,称为有监督分类。

有监督分类器框架:

label和features在配对后输入机器学习算法

简单应用:

性别分类器:

根据英文姓名的最后一个字母,男女名字有明显区分的特点,用来鉴别这个人的性别。

性别猜测:

from nltk.corpus import names
import random
import nltk

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


names = ([(name, 'male') for name in names.words('male.txt')] +
         [(name, 'female') for name in names.words('female.txt')])

random.shuffle(names)

featuresets = [(gender_features(n), g) for (n, g) in names]
train_set  = featuresets[500:]
classifier = nltk.NaiveBayesClassifier.train(train_set)

print classifier.classify(gender_features('Trinity'))

输出:

female

评估分类器:

from nltk.corpus import names
import random
import nltk

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


names = ([(name, 'male') for name in names.words('male.txt')] +
         [(name, 'female') for name in names.words('female.txt')])

random.shuffle(names)

featuresets = [(gender_features(n), g) for (n, g) in names]
train_set, test_set = featuresets[500:], featuresets[:500]
classifier = nltk.NaiveBayesClassifier.train(train_set)

radio = nltk.classify.accuracy(classifier, test_set)

print radio

输出:

0.744

查看区分效果最好的特征:

from nltk.corpus import names
import random
import nltk


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


names = ([(name, 'male') for name in names.words('male.txt')] +
         [(name, 'female') for name in names.words('female.txt')])

random.shuffle(names)

featuresets = [(gender_features(n), g) for (n, g) in names]
train_set, test_set = featuresets[500:], featuresets[:500]
classifier = nltk.NaiveBayesClassifier.train(train_set)

classifier.show_most_informative_features(5)

输出结果:

Most Informative Features
             last_letter = 'a'           female : male   =     35.8 : 1.0
             last_letter = 'k'             male : female =     31.7 : 1.0
             last_letter = 'f'             male : female =     15.9 : 1.0
             last_letter = 'p'             male : female =     11.2 : 1.0
             last_letter = 'd'             male : female =      9.9 : 1.0

这些比率称为似然比,用来比较特征和分类结果的相关关系。如姓名末尾为"a"的男女比例是35.8:1,可以看出这个特征的区分度比较高。

朴素贝叶斯分类器

算法原理

先计算每个标签的先验概率,计算方法为每个标签出现在训练数据中的频率。

计算公式:

P1:每个标签的先验概率,计算方式:每个标签出现在训练集里的频率。
$$
P1(Label)=Freq/DocCount
$$
P2:每个标签的似然得分的和与

决策树

简介

决策树可以类比为输入值选择标签的流程图,流程图由检查特征值的决策节点和分配标签的叶子节点组成。流程图的初始节点称为根节点

姓名预测性别决策树:

算法原理

首先定义决策树桩:即只有一个决策节点的决策树,基于单个特征决定输入的分类。每个可能的特征值一个叶子,并分配一个类标签。

建立的决策树桩的方法:为每个可能的特征建立一个决策树桩,看哪个决策树桩在训练数据有最高的准确度。作为决策树的根节点。

决策树的生长:

检查选择出来的决策树桩,在训练集上检查每个叶子节点的准确度,没达到足够准确度的叶子被新的决策树桩替换,然后再该路径的训练子集训练新的决策树桩,查看新决策树桩每个叶子节点的准确度,知道所有的叶子节点满足准确度要求。

评价标准

:在分类器中用来衡量数据集中无序的程度,比如训练集中不同的标签越混乱,熵越高,标签越趋向同类,熵越低。

标签数据集熵的计算公式如下:
$$
H = Σl ∈ labelsP(l) × log2P(l)
$$
如果训练集中全是相同的标签,如"姓名-性别"数据集,如P(male)=1,P(femal)=0.P(femal)对熵的贡献为0,由于log2P(male)=0,对熵的贡献也为0,所以整体的熵为0."姓名-性别"标签数据集的熵分布函数图如下:

可以看出,P(female)=0.5时,熵最大。也就是说类别越无序,熵越大。

信息增益:

在分类器中引入了熵之后,可以计算出分类前后的无序程度,也就是熵的大小。分类前后熵的差值就是信息增益。如果信息增益越大高,决策树桩的分类效果越好。

算法特点

算法特点

  • 简单明了,容易理解。适合多层次的分类。
  • 分支会划分训练数据,流转到低节点的训练数据集比较少,导致这些决策节点过拟合训练集。
  • 强迫特征按照一定的顺序进行检查,适合多层次的分类检查。而相对独立的特征区分度不好,可使用贝叶斯分类方法解决,允许特征“并行”生效。

优化方法:

  • 训练数据变小时停止分裂节点。
  • 长出一颗完整决策树时进行枝剪,剪去信息增益值低的节点。
  • 采用贝叶斯分类解决相对独立的特征。

最大熵分类器

文本信息提取

信息提取系统的流水线结构

就目前而言,我们需要做的是提取句子中的实体,用来对文档进行分类。

主要通过以下3步实现:

分词

中文分词算法包括两类

  • 在词典的基础上对语句进行子串匹配,优点是时间复杂度低O(n),缺点是对歧义和词库里没有的词,分词效果不好。比如:IK,庖丁。
  • 基于统计和机器学习的方法分词,基于人工标注的词性和统计特征,训练模型,然后通过模型计算各种分词的概率,把概率最大分词结果作为分词结果,常见的序列标注模型有HMM和CRF。

词性标注

命名实体识别

采用的技术为分块(chunking)

每一个块是分词的一个子集,并且分块的片段不重叠。

分词和词性标注以及分块

示例:

名词短语分块

NP块的信息来源是词性标注。

分块方法:

  • 正则表达式分块
  • N-gram方法

词性标注

电商分类识别

在已有电商购物分类的情况下,如何把用户关键词输入,映射到商品分类下。使得搜索结果约束在相关的分类下,以此提高召回率。

流程图如下:

图:关键词匹配分类树的流程图

如:用户输入的关键词如:"华硕(ASUS)ROG STRIX-GTX1080TI-O11G-GAMING 1569-1708MHz 11G/11100MHz GDDR5X PCI-E3.0显卡"

分类树节点匹配法

通过自定义关键词抽取,自定义指的是词库为所有的商品的分类词汇。

将提取的关键词在分类树上做映射,映射的方式可以是全词匹配(准确度会高一些)。或者采用词向量的方式找最相关的分类节点(准确度不可控,计算量大)。

然后将上图中匹配上的节点回路路径,作为一种分类情形。收集所有可能的回路,并进行路径合并。产生所有的分类过滤情形,取最多3种(可配置)情形,所谓类别过滤条件,结合标题产生搜索结果。

这种方式经过测试数据集的验证,准确率为0.2908883847884619,可以看出分类的准确率并不高,不到三成。

基于统计方法

先把类别分级别,从第一级开始分类。

比如“电脑办公”分类,统计这个大分类下的所有商品的名称分词后的词语分布。

比如

商品名称分词-词频统计图

可以看到,商品名称分词后的词语,会对词库的词频贡献分数。

算法原理:

假设"电脑办公"的商品名称,包含大量的“华硕”这个词语,并且其他分类很少有“华硕”这个词,可以总结出:商品名称里的“华硕“关键词,是”电脑办公“分类里相对特有的,相比其他分类,这个词有很好的类别区分效果。

把一个分类类比成一份文档,所有的商品名称组建成文档里的文字。分类的匹配就变成了普通的文档匹配了,可以用TF-IDF算法进行分类匹配。

影响因子:

  • 词频(Term frequency):在训练(索引)的时候构建的分类下词语的统计数。即Term 在文档中出现的个数,计算方法函数是:
public float tf(float freq) {
    return (float)Math.sqrt(freq);
}

有个文档叫做”this is book about chinese book”, 我的搜索项为”book”,那么这个搜索项对应文档的freq就为2,那么tf值就为根号2,即1.4142135。Term的freq值是在索引期间存储的。

  • 逆文档频率:(Inerse document frequency),基于Term的一个因子,表示Term在所有文档里的稀有程度,以此提升包含稀有词的文档的得分。默认实现:
public float idf(long docFreq, long numDocs) {
    return (float)(Math.log(numDocs/(double)(docFreq+1)) + 1.0);
}

其中:

docFreq 指的是Term出现的文档数,就是有多少个文档符合这个搜索

numDocs 指的是索引库中有多少个文档。

  • 文档权重(Document boost):在这个应用场景下也叫分类权重。设置方法可以根据经验值 来设置不同分类的权重。
  • 调整因子(Coord):关键词分词后,出现在当前分类文档中的个数。

计算方法函数:

public float coord(int overlap, int maxOverlap) {
    return overlap / (float)maxOverlap;
}

其中:

overlap:query中检索命中term的个数

maxOverlap:query中总共的term个数

比如:

检索''english book”, 现在有一个文档是”this is an chinese book”。那么,这个搜索对应这个文档的overlap为1(因为匹配了book),而maxOverlap为2(因为检索条件有两个book和english)。最后得到的这个搜索对应这个文档的coord值为0.5。

Lucene Classifier

计算每个标签的分值

  • 标签的先验概率:

$$
p(c)=log2freq(label)-log2sum(labels)
$$
freq(label)表示整个样本空间里label标签出现的次数。

sum(lables)表示样本空间的大小。

  • 标签的似然估计:

$$
p(w|c)=wordFreqForClass(word,c)/textTermFreqForClass(c)
$$

wordFreqForClass(word,c) 函数计算方法:search with text:word AND class:c 表示标签c下包含word的文档数

textTermFreqForClass(c)函数计算方法:c标签下的所有词总数+总文档数

你可能感兴趣的:(文本分类器)