【火炉炼AI】机器学习040-NLP性别判断分类器

【火炉炼AI】机器学习040-NLP性别判断分类器

(本文所使用的Python库和版本号: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2, NLTK 3.3)

本文的目标是构建一个分类器,从名字就判断这个人是男性还是女性。能够建立这种分类器的基本假设是英文名字后面的几个字母带有很明显的性别倾向,比如'la'结尾的一般是女性,以'im'结尾的一般是男性。故而我们认为名字的后面几个字母和性别之间有很强烈的相关性,所以可以建立一个分类模型,从名字中就可以直接判断性别。


1. 准备数据集

NLTK库中已经有英文姓名的一些文档,此处我们可以直接加载,并将两部分的名字合并组成一个数据集。

# 1, 准备数据集,此次数据集来源于nltk.corpus内置的names文件
from nltk.corpus import names
male_names=[(name, 'male') for name in names.words('male.txt')]
female_names=[(name,'female') for name in names.words('female.txt')]
print(len(male_names)) # 2943
print(len(female_names)) # 5001
# 数据集中有2943个男性名字,5001个女性名字

# 看看男性和女性的名字都是哪些。。。。
print(male_names[:5])
print(female_names[:3])

# 将这些名字组成的list合并成一个数据集,第一列是名字,即features,第二列是性别,即label
dataset=np.array(male_names+female_names)
print(dataset.shape) # (7944, 2)没错

-------------------------------------输---------出--------------------------------

2943
5001
[('Aamir', 'male'), ('Aaron', 'male'), ('Abbey', 'male'), ('Abbie', 'male'), ('Abbot', 'male')]
[('Abagael', 'female'), ('Abagail', 'female'), ('Abbe', 'female')]
(7944, 2)

--------------------------------------------完-------------------------------------

虽然此处我们假设名字的后面几个字母和性别之间有很强烈的相关性,但是我们不确定到底是最后几个字母的相关性最强,我们应该基于最后的几个字母来建模,所以,此处我们就分别取最后的1-4个字母,然后组成数据集的特征列,分别建模,看看哪一种的结果最好。

# 处理数据集
# 我们难以确定到底是姓名后面的几个字母才和性别相关性最大,
# 故而此处把后面的1-4个字母都取出来作为一个特征列
# 用pandas 貌似更容易一些
import pandas as pd
dataset_df=pd.DataFrame(dataset,columns=['name','sex'])
# print(dataset_df.info())
# print(dataset_df.head()) # 检查没有问题

for i in range(1,5): # 分别截取每个名字的后面i个字母
    dataset_df['len'+str(i)]=dataset_df.name.map(lambda x: x[-i:].lower())
    
print(dataset_df.head())# 检查没有问题

-------------------------------------输---------出--------------------------------

name   sex len1 len2 len3  len4

0 Aamir male r ir mir amir
1 Aaron male n on ron aron
2 Abbey male y ey bey bbey
3 Abbie male e ie bie bbie
4 Abbot male t ot bot bbot

--------------------------------------------完-------------------------------------


2. 建立模型,训练特征

此处由于我们不知道姓名后面几个字母得到的结果最准确,故而只能都建模看看在测试集上的表现。如下为代码:

# 分别构建分类器,并训练后再测试集上看看效果
dataset=dataset_df.values
np.random.shuffle(dataset)
rows=int(len(dataset)*0.7) # 70%为train set
train_set,test_set=dataset[:rows],dataset[rows:]

from nltk import NaiveBayesClassifier
from nltk.classify import accuracy as nltk_accuracy
for i in range(1,5): # 对每一列特征分别建模并训练
    train_X,train_y=train_set[:,i+1],train_set[:,1]
    train=[({'feature':feature},label) for (feature,label) in zip(train_X,train_y)] 
    # 后面的NaiveBayesClassifier 在train的时候需要()组成的list
    clf=NaiveBayesClassifier.train(train)
    
    # 查看该模型在test set上的表现
    test_X,test_y=test_set[:,i+1],test_set[:,1]
    test=[({'feature':feature},label) for (feature,label) in zip(test_X,test_y)] 
    acc=nltk_accuracy(clf,test)
    
    print('Number of suffix: {}, accuracy on test set: {:.2f}%'
          .format(i, 100*acc))

-------------------------------------输---------出--------------------------------

Number of suffix: 1, accuracy on test set: 76.05%
Number of suffix: 2, accuracy on test set: 77.89%
Number of suffix: 3, accuracy on test set: 75.80%
Number of suffix: 4, accuracy on test set: 71.56%

--------------------------------------------完-------------------------------------

由此可以看出,最准确的是只需要两个字母的情况,其次是只需要一个字母。在测试集上的准确率为77%左右。

########################小**********结###############################

1,本项目对数据集的准备需要花费一番功夫,需要分别取出名字的后面N个字母作为一个新的特征列。然后用这个特征列在训练模型

2,nltk模块中继承的分类器可以不需要对特征进行文本转数字操作,故而此处我们没必要用传统机器学习的String转int的读热编码方式来转换,估计nltk这些分类器内部已经集成了这些转换操作。

3,NaiveBaysClassifier在调用train方法时,需要注意输入变量的形式,必须是(特征dict,label)组成的list,否则很多情况下会出错。

#################################################################


注:本部分代码已经全部上传到(我的github)上,欢迎下载。

参考资料:

1, Python机器学习经典实例,Prateek Joshi著,陶俊杰,陈小莉译

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352

推荐阅读更多精彩内容