Ourren

关注技术,记录生活.

NLP入门实例:判断性别

| 留言

image

1. NLP(Natural Language Processing)

自然语言处理(NLP)是人工智能和语言学领域的重要学科,在这此领域中探讨如何处理及运用自然语言;自然语言认知则是指让电脑“懂”人类的语言。自然语言生成系统把计算机数据转化为自然语言。自然语言理解系统把自然语言转化为计算机程序更易于处理的形式[1]。

按照我个人的理解就是计算机怎么去理解并处理文字(中文或者其他语言),因为每种语言都有各种语法,语义和感情色彩等。而计算机他是不懂感情的,学过计算机编程的都知道,不管是x64/X86的机器上面跑的就是0101。而NLP技术的出现就是来解决该类问题,NLP主要难点在于:

  • 单词的边界界定(注:分词)

    在口语中,词与词之间通常是连贯的,而界定字词边界通常使用的办法是取用能让给定的上下文最为通顺且在文法上无误的一种最佳组合。在书写上,汉语也没有词与词之间的边界。

  • 词义的消歧(注:语义)

    许多字词不单只有一个意思,因而我们必须选出使句意最为通顺的解释。

  • 句法的模糊性(注:语境)

    自然语言的文法通常是模棱两可的,针对一个句子通常可能会剖析(Parse)出多棵剖析树(Parse Tree),而我们必须要仰赖语意及前后文的资讯才能在其中选择一棵最为适合的剖析树。

  • 有瑕疵的或不规范的输入

    例如语音处理时遇到外国口音或地方口音,或者在文本的处理中处理拼写,语法或者光学字符识别(OCR)的错误。

本文不会涉及太多这块技术,一方面我也刚入门,另外一方面这块技术比较高深,是一个长期需要研究的东西。

2. 问题的提出

我们都知道日常生活中一个人的名字跟他的性别还是有一定的关系。例如一个名字叫作小红的人,大部分人都会认为她应该是女性,因此,一个人的姓名跟他的性别是有一定关系的,在生活中我们可以根据别人的姓名去猜测他的性别,当然这有一定的几率,但是如何编写程序让计算机也能进行判定,这个就是一个基本的NLP技术的应用范围。

问题:根据给定的姓名判定其性别。

3. NLP相关技术

目前国内外对NLP相关技术研究资料很多,国内主要研究具体技术有中文的分词,词性标注、实体识别、句块分析、语义分析,情感分析,分类算法的优化等,相比英文,中文的复杂程度比较高,涉及到一词多义,语句中的顺序和语义中的多种否定和语境。目前应用场景主要有:

  1. 语义的感情分析,包含帖子,微博或者文章等。将语句分为:消极、积极和中性。涉及到公司或者产品舆情,用于对于商品的评价分析;
  2. 主题的关键字提取,也即观点提取或者主题的标签提取,经常逛v2ex的就知道它目前也是使用的自动标签;
  3. 搜索引擎与个性推荐,根据已有数据预测未知数据或者推荐类似商品;
  4. 其它我不知道的。

由于本文需要解决技术的问题,因此选取基于python编程语言的nltk(Natural Language Toolkit)[2]来进行处理。nltk工具包涵盖分词、语义分析、分类算法、语义库等各种类库,方便我们快速开发和实践。并且nltk还配有专门的入门教程。

4. 环境搭建

首先安装nltk库:

  1. 先安装easy_install: http://pypi.python.org/pypi/setuptools
  2. 安装Pip: run sudo easy_install pip
  3. 安装 Numpy (可选): run sudo pip install -U numpy
  4. 安装 NLTK: run sudo pip install -U nltk
  5. 测试是否成功: run python then type import nltk

其次安装语料库:

在python命令行中输入如下代码:

import nltk
nltk.download()

在弹出的下载界面选择需要安装的文件进行安装。

5.具体流程

本次我们采用贝叶斯分类算法对该问题进行分析,具体的流程图见文章顶部的图片,在进行分类前需要解决如下问题:

  1. 原始标注数据,即训练数据;

    由于本次属于试验测试阶段,因此前期样本选取不用过大,可以采用手工标注方法进行标注。

  2. 特征提取算法,即一个人的姓名跟性别到底有什么关系。

    本次由于只是演示nlp的作用和流程,因此可以简化提取特征,我们假定其实性别跟姓名的最后一个字母有关系。但是在实际的情况下涉及的方面实在太多,这个也是需要研究的一个内容。看下如下别人设计的一个模型: image

那么我们已经解决了如上的两个重要问题,下面来写代码实现。

6.代码实现

本次采用python语言进行开发,特征提取函数如下:

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

训练数据从网上英文取名网站提取。

女孩姓名数据:

Abigail
Ada
Adelaide
Adrienne
Agatha
Agnes
Aileen
Aimee
Alanna
Alarice
Alda
Alexandra
Alice
Alina
Alison

男孩姓名数据:

abbott
abby
abe
abie
acton
adair
addison
africa
afton
aidric
aiken

程序全部代码:

import sys,os,nltk
from nltk.corpus import names
import random
#extract features from name
def gender_features(word):
    return {'last_letter':word[-1]}

names=([(name,'female') for name in names.words('girlname.txt')] + [(name,'male') for name in names.words('boyname.txt')])
random.shuffle(names)
featuresets = [(gender_features(n), g) for (n,g) in names]
train_set, test_set = featuresets[10:], featuresets[:10] #此处可根据实际情况修改
classifier = nltk.NaiveBayesClassifier.train(train_set) 
print classifier.classify(gender_features('ourren'))

基本上实现了本文提出的问题,其实该问题就是nltk入门书籍上的一个题目。

参考

  1. 自然语言处理
  2. Natural Language Toolkit
  3. Learning to Classify Text