NLTK学习笔记——使用叶贝斯分类器性别鉴定

一 、性别鉴定步骤

根据名字男女规律进行判断

建立分类器

        • 1. 确定输入特征——特征提取器
        • 2. 划分数据集
        • 3. 使用训练集构建分类器
        • 4. 使用测试集测试分类器效果

二、叶贝斯分类器原理

特征:假设选取名字的最后一个字母为主要特征
类别:男性、女性
贝叶斯公式:P(B|A)=P(A|B)*P(B)/P(A)

贝叶斯分类器          

比较P(男性|特征)与P(女性|特征)有如下两种方法
1. 直接比较P(特征|男性)*P(男性)与P(特征|女性)*P(女性)
2. 直接将P(女性|特征)与0.5比较(因为只有两种分类,两个概率加起来为1,所以只要有一方概率大于0.5即可判断)

三、实战代码

from nltk.corpus import names
import nltk
import random

#从数据集中打印出前10个名字
names_set = ([(name, 'male') for name in names.words('male.txt')] +
        [(name, 'female') for name in names.words('female.txt')])
print (names_set[:10])
random.shuffle(names_set)#结果随机打乱
print (names_set[:10])

featuresets = [(gender_features(n), g) for (n,g) in names_set]#n为名字,g为标签,在name中前为名字,后为标签
train_set, test_set = featuresets[500:], featuresets[:500]#前500测试集,后500训练集

classifier = nltk.NaiveBayesClassifier.train(train_set)#用朴素叶贝斯的方法去训练分类器

#测试
classifier.classify(gender_features('Neo'))

classifier.classify(gender_features('Trinity'))

#分类正确率判断
print (nltk.classify.accuracy(classifier, test_set))

#最有效的特征
classifier.show_most_informative_features(5)


##手动计算贝叶斯分类器##
#计算P(特征|类别)
def f_c(data,fea,cla):
    cfd=nltk.ConditionalFreqDist((classes,features) for (features,classes) in data)
    return cfd[cla].freq(fea)

#计算P(特征)  
def p_feature(data,fea):
    fd=nltk.FreqDist(fea for (fea,cla) in data)
    return fd.freq(fea)
   
#计算P(类别)
def p_class(data,cla):
    fd=nltk.FreqDist(cla for (fea,cla) in data)
    return fd.freq(cla)
    
#计算P(类别│特征)
def res(data,fea,cla):
    return f_c(data,fea,cla)*p_class(data,cla)/p_feature(data,fea)
    

#构造输入数据集
data=([(name[-1], 'male') for name in names.words('male.txt')] +
        [(name[-1], 'female') for name in names.words('female.txt')])
random.shuffle(data)
train,test=data[500:],data[:500]

#计算Neo的为男性的概率
res(test,'y','male')
res(train,'a','female')

上面例子中只选取了每个名字的最后一个字母判别特征,所达到的精度为0.758,可能会觉得因为特征较少,影响精度。所以还可以选取多重特征进行判断。

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())#%letter使用的是格式化
    return features
    


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

加入多重特征,测试集所达到的精度为 0.796,和上面比较只提高了0.03,没有较大提升,这是因为当提取的特征较多时,测试集上会产生过拟合。

你可能感兴趣的:(自然语言处理)