Python NLTK 命名实体识别取决于首字母的(大)写?
Python NLTK named entity recognition depends by the (upper)case of first letter?
我计划使用 Python NLTK 进行学术研究。特别是,我需要一种筛选 Twitter 用户的方法,并梳理出那些似乎没有在个人资料中使用 "real name" 的用户。
我正在考虑使用默认的 NLTK 名称实体识别来区分使用看似真实姓名的 Twitter 用户和那些不是真实姓名的用户。你觉得值得一试吗?还是自己训练分类器?
import nltk
import re
import time
##contentArray0 =['Health Alerts', "Kenna Hill"]
contentArray =['ICU nurse toronto']
##let the fun begin!##
def processLanguage():
try:
for item in contentArray:
tokenized = nltk.word_tokenize(item)
tagged = nltk.pos_tag(tokenized)
print tagged
namedEnt = nltk.ne_chunk(tagged)
##namedEnt.draw()
time.sleep(1)
except Exception, e:
print str(e)
processLanguage()
编辑:我做了一些测试。似乎 nltk 主要通过单词的第一个字母是否大写来识别名称实体?例如,"ICU Nurse Toronto" 将被 NNP 识别,而 "ICU nurse toronto" 则不会。这似乎过于简单化并且对我的目的(twitter)不是很有用,因为许多使用实名的 Twitter 用户可能使用小写字母,而一些商业组织将使用大写首字母。
一定要自己练一个。 NLTK 的 NE 识别器经过训练可以识别嵌入在完整句子中的命名实体。但是不要只是在新数据上重新训练 nltk 的 NE 识别器;它是一个 "sequential classifier",这意味着它考虑了周围的词和 POS 标签以及前面词的命名实体分类。由于您已经拥有用户名,因此这些用户名对您的目的没有用处或相关性。
我建议您训练一个常规分类器(例如,朴素贝叶斯),将您认为可能相关的任何自定义特征提供给它,并让它做出决定 "is this a real name"。要进行训练,您 必须 有一个包含名称示例和非名称示例的训练语料库。理想情况下,语料库应包含您要分类的内容:推特句柄。
关于您评论中的问题,不要使用整个单词作为特征:您的分类器只能根据它知道的特征进行推理,因此除非您的特征是关于 [=名称的 20=]部分。通常这些特征代表结尾(最后一个字母、最后一个二元组、最后一个三元组),但你也可以尝试其他东西,比如长度,当然还有大写。 NLTK章节讨论了识别名字性别的任务,并给出了很多后缀特征的例子。
在你的情况下,要注意的是你有多个单词。因此,如果某些单词被识别为名称而某些则不是,则需要以某种方式告诉您的分类器。您必须以某种方式定义您的功能以保留此信息。例如,您可以将特征 "known names" 设置为具有值 "None"、"One"、"Several"、"All"。 (请注意,NLTK 的实现将特征值视为 "categories":它们只是不同的值。您可以使用 3 和 4 作为特征值,但就分类器而言,您还不如使用 "green" 和 "elevator".)
并且不要忘记添加具有常量值的 "bias" 特征(参见 NLTK 章节)。
你肯定得自己训练一个分类器。例如,由于您正在处理名称,您可以看看这个 NLTK chapter。本章描述的用于测试名称是 'male' 还是 'female' 的简单朴素贝叶斯分类器可以很好地洞察特征的种类。另外,您关于询问哪些功能的问题更像是一个问题和特定领域的问题。除了所有信息提取研究人员使用的通用特征外,可能还有其他类型的特征。但同样,这些完全取决于您的数据。请仔细阅读该章,它为您提供了构建自己的分类器的所有基本工具。
顺便说一句,既然你提到了 Twitter 用户名,我还建议使用规范化器,因为大多数名称可能只包含字母。例如,用户名也可以是 "T0m" 而不是 "Tom"。也许您已经在这样做了,如果您已经这样做了,我很抱歉再次重复。
我计划使用 Python NLTK 进行学术研究。特别是,我需要一种筛选 Twitter 用户的方法,并梳理出那些似乎没有在个人资料中使用 "real name" 的用户。
我正在考虑使用默认的 NLTK 名称实体识别来区分使用看似真实姓名的 Twitter 用户和那些不是真实姓名的用户。你觉得值得一试吗?还是自己训练分类器?
import nltk
import re
import time
##contentArray0 =['Health Alerts', "Kenna Hill"]
contentArray =['ICU nurse toronto']
##let the fun begin!##
def processLanguage():
try:
for item in contentArray:
tokenized = nltk.word_tokenize(item)
tagged = nltk.pos_tag(tokenized)
print tagged
namedEnt = nltk.ne_chunk(tagged)
##namedEnt.draw()
time.sleep(1)
except Exception, e:
print str(e)
processLanguage()
编辑:我做了一些测试。似乎 nltk 主要通过单词的第一个字母是否大写来识别名称实体?例如,"ICU Nurse Toronto" 将被 NNP 识别,而 "ICU nurse toronto" 则不会。这似乎过于简单化并且对我的目的(twitter)不是很有用,因为许多使用实名的 Twitter 用户可能使用小写字母,而一些商业组织将使用大写首字母。
一定要自己练一个。 NLTK 的 NE 识别器经过训练可以识别嵌入在完整句子中的命名实体。但是不要只是在新数据上重新训练 nltk 的 NE 识别器;它是一个 "sequential classifier",这意味着它考虑了周围的词和 POS 标签以及前面词的命名实体分类。由于您已经拥有用户名,因此这些用户名对您的目的没有用处或相关性。
我建议您训练一个常规分类器(例如,朴素贝叶斯),将您认为可能相关的任何自定义特征提供给它,并让它做出决定 "is this a real name"。要进行训练,您 必须 有一个包含名称示例和非名称示例的训练语料库。理想情况下,语料库应包含您要分类的内容:推特句柄。
关于您评论中的问题,不要使用整个单词作为特征:您的分类器只能根据它知道的特征进行推理,因此除非您的特征是关于 [=名称的 20=]部分。通常这些特征代表结尾(最后一个字母、最后一个二元组、最后一个三元组),但你也可以尝试其他东西,比如长度,当然还有大写。 NLTK章节讨论了识别名字性别的任务,并给出了很多后缀特征的例子。
在你的情况下,要注意的是你有多个单词。因此,如果某些单词被识别为名称而某些则不是,则需要以某种方式告诉您的分类器。您必须以某种方式定义您的功能以保留此信息。例如,您可以将特征 "known names" 设置为具有值 "None"、"One"、"Several"、"All"。 (请注意,NLTK 的实现将特征值视为 "categories":它们只是不同的值。您可以使用 3 和 4 作为特征值,但就分类器而言,您还不如使用 "green" 和 "elevator".)
并且不要忘记添加具有常量值的 "bias" 特征(参见 NLTK 章节)。
你肯定得自己训练一个分类器。例如,由于您正在处理名称,您可以看看这个 NLTK chapter。本章描述的用于测试名称是 'male' 还是 'female' 的简单朴素贝叶斯分类器可以很好地洞察特征的种类。另外,您关于询问哪些功能的问题更像是一个问题和特定领域的问题。除了所有信息提取研究人员使用的通用特征外,可能还有其他类型的特征。但同样,这些完全取决于您的数据。请仔细阅读该章,它为您提供了构建自己的分类器的所有基本工具。
顺便说一句,既然你提到了 Twitter 用户名,我还建议使用规范化器,因为大多数名称可能只包含字母。例如,用户名也可以是 "T0m" 而不是 "Tom"。也许您已经在这样做了,如果您已经这样做了,我很抱歉再次重复。