4

我使用 stanford nlp 包编写了以下代码。

GenderAnnotator myGenderAnnotation = new GenderAnnotator();
myGenderAnnotation.annotate(annotation);

但是对于“安妮去上学”这句话,它无法识别安妮的性别。

应用程序的输出是:

     [Text=Annie CharacterOffsetBegin=0 CharacterOffsetEnd=5 PartOfSpeech=NNP Lemma=Annie NamedEntityTag=PERSON] 
     [Text=goes CharacterOffsetBegin=6 CharacterOffsetEnd=10 PartOfSpeech=VBZ Lemma=go NamedEntityTag=O] 
     [Text=to CharacterOffsetBegin=11 CharacterOffsetEnd=13 PartOfSpeech=TO Lemma=to NamedEntityTag=O] 
     [Text=school CharacterOffsetBegin=14 CharacterOffsetEnd=20 PartOfSpeech=NN Lemma=school NamedEntityTag=O] 
     [Text=. CharacterOffsetBegin=20 CharacterOffsetEnd=21 PartOfSpeech=. Lemma=. NamedEntityTag=O]

获取性别的正确方法是什么?

4

5 回答 5

5

如果您的命名实体识别器输出PERSON一个标记,您可以使用(或者如果没有)基于名字的性别分类器。例如,请参阅 NLTK 库教程页面中的Gender Identification部分。他们使用以下功能:

  • 姓名的最后一个字母。
  • 名字的第一个字母。
  • 名称的长度(字符数)。
  • 字符 unigram 存在(布尔值是否有字符在名称中)。

不过,我有一种预感,使用字符 n-gram 频率——可能高达字符三元组——会给你带来很好的结果。

于 2013-05-02T00:37:47.250 回答
2

有很多方法,其中一种方法在nltk 食谱中进行了概述。

基本上,您构建一个分类器,从名称中提取一些特征(第一个、最后一个字母、前两个、最后两个字母等),并根据这些特征进行预测。

import nltk
import random

def extract_features(name):
    name = name.lower()
    return {
        'last_char': name[-1],
        'last_two': name[-2:],
        'last_three': name[-3:],
        'first': name[0],
        'first2': name[:1]
    }

f_names = nltk.corpus.names.words('female.txt')
m_names = nltk.corpus.names.words('male.txt')

all_names = [(i, 'm') for i in m_names] + [(i, 'f') for i in f_names]
random.shuffle(all_names)

test_set = all_names[500:]
train_set= all_names[:500]

test_set_feat = [(extract_features(n), g) for n, g in test_set]
train_set_feat= [(extract_features(n), g) for n, g in train_set]

classifier = nltk.NaiveBayesClassifier.train(train_set_feat)

print nltk.classify.accuracy(classifier, test_set_feat)

此基本测试为您提供大约 77% 的准确度。

于 2015-09-18T07:43:37.700 回答
1

性别注释器不会将信息添加到文本输出中,但您仍然可以通过代码访问它,如以下代码段所示:

Properties props = new Properties();
props.setProperty("annotators", "tokenize,ssplit,pos,parse,gender");

StanfordCoreNLP pipeline = new StanfordCoreNLP(props);

Annotation document = new Annotation("Annie goes to school");

pipeline.annotate(document);

for (CoreMap sentence : document.get(CoreAnnotations.SentencesAnnotation.class)) {
  for (CoreLabel token : sentence.get(CoreAnnotations.TokensAnnotation.class)) {
    System.out.print(token.value());
    System.out.print(", Gender: ");
    System.out.println(token.get(MachineReadingAnnotations.GenderAnnotation.class));
  }
}

输出:

Annie, Gender: FEMALE
goes, Gender: null
to, Gender: null
school, Gender: null
于 2015-05-19T20:17:23.597 回答
0

我可以在 nltk 食谱中再添加两堂课:

  1. 使用 Twitter 中的统计名称特征进行性别推断 ( https://dl.acm.org/doi/pdf/10.1145/2955129.2955182 )
  2. Damegender:编写和比较性别检测工具(http://ceur-ws.org/Vol-2754/paper3.pdf

在第一讲中已经提出了几种特征选择方法,下一组作为讨论的开始:

  1. 音节数
  2. 辅音数量
  3. 元音数
  4. 元音亮度
  5. 结束字符

使用 SVM,他们使用 namdict 作为主要数据集的准确率约为 70.9%。

在第二讲中,我们选择了下一个特征选择:

  1. 包含一个
  2. 最后是一个
  3. 最后是o
  4. 最后是辅音
  5. 最后是元音
  6. 第一个是辅音
  7. 第一个是元音

使用以下国家统计机构的主要数据集达到 74.5% 的准确率:乌拉圭、西班牙、英国、美国、加拿大和澳大利亚。

于 2022-01-21T20:18:24.220 回答
0

尽管@Sebastian Schuster之前的回答与预期的有些接近,但它似乎不适用于当前版本的 Standford NLP

该代码段的更新和工作示例如下。

Properties props = new Properties();
props.setProperty("annotators", "tokenize,ssplit,pos,parse,gender");

StanfordCoreNLP pipeline = new StanfordCoreNLP(props);

Annotation document = new Annotation("Annie goes to school");

pipeline.annotate(document);

for (CoreMap sentence : document.get(CoreAnnotations.SentencesAnnotation.class)) {
  for (CoreLabel token : sentence.get(CoreAnnotations.TokensAnnotation.class)) {
    System.out.print(token.value());
    System.out.print(", Gender: ");
    System.out.println(token.get(CoreAnnotations.GenderAnnotation.class));
  }
}
于 2020-02-11T08:39:20.213 回答