2014-09-19 48 views
4

我正在修补NSLinguisticTagger用NSLinguisticTagger标识人名

识别基本单词类型,如名词,动词,介词的效果非常好。

但是,人名的识别NSLinguisticTagPersonalName很难在我的测试(iOS8)中工作。地方NSLinguisticTagPlaceName也似乎工作得很好,但大多数时候人名也被归类为地方。

这是我的基本设置(使用NSLinguisticTagSchemeNameTypeOrLexicalClass)

var tagger:NSLinguisticTagger = NSLinguisticTagger(tagSchemes: NSLinguisticTagger.availableTagSchemesForLanguage("en") , options: 3) 
    tagger.string = entryString 
    tagger.enumerateTagsInRange(NSMakeRange(0, entryString.length), scheme: NSLinguisticTagSchemeNameTypeOrLexicalClass, options: (NSLinguisticTaggerOptions.OmitWhitespace | NSLinguisticTaggerOptions.JoinNames), usingBlock: { 
     tag,tokenRange,sentenceRange,_ in 
     let token = entryString.substringWithRange(tokenRange) 
     println("[\(tag)] \(token) \(tokenRange)") 

例1

"Meeting with John in Paris" 

    Evaluation 

[Verb] Meeting 
[Preposition] with 
[Noun] John 
[Preposition] in 
[PlaceName] Paris 

例2

"Meeting with John" 

    Evaluation 

[Verb] Meeting (0,7) 
[Preposition] with (8,4) 
[PlaceName] John (13,4) 

任何想法,我怎么能提高人的名字匹配?

另外,我很想知道名称需要出现才能被识别。 (我认为例如“with”这样的介词将是一个很好的指标......显然这还不够)。我很感激任何想法或对此的其他见解。这是一个令人兴奋的领域。

+1

Heya @Bernd!我看到这个问题在这里一直没有答案。我想要PM,但Stack不会允许,所以我在这里发表评论,希望你能看到这个。我现在正在修改NSLinguisticTagger,而且我和你有完全相同的问题。 “萨姆史密斯来自香港”得到了正确的认可(Sam Smith为Personal Name,HongCong为PlaceName),但“我的名字是Sam Smith”没有。任何经验,你可以分享将不胜感激!非常感谢你,祝你有个美好的一天! – borg123 2016-02-15 11:31:46

+0

@ borg123我目前的看法是简单地避免使用NSLinguisticTagger中的PlaceName和PersonName标签。这些标签只是工作不够好。 相反,我宁愿使用介词标记作为线索,并基于这些创建自己的标记符。 – Bernd 2016-02-15 14:54:54

回答

2

显然,正确的答案是:“等了几年苹果在改善NSLinguisticTagger斯威夫特4

这里是写和执行在Xcode 9(测试版)的斯威夫特4码:

let entryString = "Meeting with John" 

let schemes = NSLinguisticTagger.availableTagSchemes(forLanguage: "en") 
let options: NSLinguisticTagger.Options = [ 
    .omitWhitespace, .omitPunctuation, .joinNames 
] 

let tagger = NSLinguisticTagger(tagSchemes: schemes, options: Int(options.rawValue)) 
tagger.string = entryString 

let rangeOfEntireEntryString = NSRange(location: 0, length: entryString.utf16.count) 

tagger.enumerateTags(
    in: rangeOfEntireEntryString, 
    scheme: .nameTypeOrLexicalClass, 
    options: options) 
{ (tag, tokenRange, sentenceRange, _) in 
    guard let tag = tag?.rawValue else { return } 
    let token = (entryString as NSString).substring(with: tokenRange) 
    print("[\(tag)] \(token) \(tokenRange)") 
} 

,这里是结果与你的第一个例子字符串:

let entryString = "Meeting with John in Paris" 

[Noun] Meeting {0, 7} 
[Preposition] with {8, 4} 
[PersonalName] John {13, 4} 
[Preposition] in {18, 2} 
[PlaceName] Paris {21, 5} 

和你的第二个例子字符串:

let entryString = "Meeting with John" 

[Noun] Meeting {0, 7} 
[Preposition] with {8, 4} 
[PersonalName] John {13, 4} 
+0

'nameTypeOrLexialClass'是什么? – Will 2017-08-26 08:14:48

+0

无视以前的评论,我不会收到hte [PersonalName]列表 – Will 2017-08-26 08:20:27

+0

[Noun] Meeting {0,7} [Preposition] with {8,4} [PlaceName] John {13,4} – Will 2017-08-26 08:26:20