Skip to content
This repository has been archived by the owner on Sep 8, 2023. It is now read-only.

Latest commit

 

History

History
147 lines (116 loc) · 8.04 KB

2012-10-22-nslinguistictagger.md

File metadata and controls

147 lines (116 loc) · 8.04 KB
layout title category excerpt author translator
post
NSLinguisticTagger
Cocoa
NSLinguisticTagger在语言学功能上来讲是一把名副其实的瑞士军刀,它可以讲自然语言的字符串标记为单词、确定词性和词根、划分出人名地名和组织名称、告诉你字符串使用的语言和语系。
Mattt
Croath Liu

NSLinguisticTagger 在语言学功能上来讲是一把名副其实的瑞士军刀,它可以讲自然语言的字符串标记为单词、确定词性和词根、划分出人名地名和组织名称、告诉你字符串使用的语言和语系

对于我们大多数人来说,这其中蕴含着意义远超过我们所知道的,但或许也只是我们没有合适的机会使用而已。但是,几乎所有使用某种方式来处理自然语言的应用如果能够用上 NSLinguisticTagger ,或许就会润色不少,没准会催生一批新特性呢。


NSLinguisticTagger 和Siri同时出现于iOS 5上,所以可以推测这可能是苹果在私人助理方向开发时候的副产品。

回想一下我们经常问Siri的一个问题:

旧金山的天气怎么样?(What is the weather in San Francisco?)

电脑不可能通过逐字翻译"理解"问题的含义,不过我们耍一点儿小花招就可以合理地理解这个问题的_含义_:

NSString *question = @"What is the weather in San Francisco?";
NSLinguisticTaggerOptions options = NSLinguisticTaggerOmitWhitespace | NSLinguisticTaggerOmitPunctuation | NSLinguisticTaggerJoinNames;
NSLinguisticTagger *tagger = [[NSLinguisticTagger alloc] initWithTagSchemes: [NSLinguisticTagger availableTagSchemesForLanguage:@"en"] options:options];
tagger.string = question;
[tagger enumerateTagsInRange:NSMakeRange(0, [question length]) scheme:NSLinguisticTagSchemeNameTypeOrLexicalClass options:options usingBlock:^(NSString *tag, NSRange tokenRange, NSRange sentenceRange, BOOL *stop) {
    NSString *token = [question substringWithRange:tokenRange];
    NSLog(@"%@: %@", token, tag);
}];

输出如下:

What: Pronoun(代词) is: Verb(动词) the: Determiner(限定词) weather: Noun(名词) in: Preposition(介词) San Francisco: PlaceName(地名)

如果我们过滤名词、动词、地名,就会得到结果:[is, weather, San Francisco]

仅以来这个结果,或者配合潜在语义映射(Latent Semantic Mapping)库,我们就可以推断出合理解释,然后就可以通过调用相关API去获取旧金山此时此刻的天气状况了。

特征标记方案

我们可以通过给 NSLinguisticTagger 设置下列scheme来标记不同类型的信息:

  • NSLinguisticTagSchemeTokenType:将短语在大粒度上分成词语、标点符号、空格等。
  • NSLinguisticTagSchemeLexicalClass:将短语根据类型分为话语部分、标点空格等。
  • NSLinguisticTagSchemeNameType:将短语根据是否为命名实体分类。
  • NSLinguisticTagSchemeNameTypeOrLexicalClass:遵守 NSLinguisticTagSchemeNameType 对名字的规则和 NSLinguisticTagSchemeLexicalClass 对所有其它部分的原则。

这里有一个不同短语类型和每一个分词方案之间关系的表:(NSLinguisticTagSchemeNameTypeOrLexicalClass表示NSLinguisticTagSchemeNameTypeNSLinguisticTagSchemeLexicalClass的组合关系):

NSLinguisticTagSchemeTokenType NSLinguisticTagSchemeLexicalClass NSLinguisticTagSchemeNameType
  • NSLinguisticTagWord
  • NSLinguisticTagPunctuation
  • NSLinguisticTagWhitespace
  • NSLinguisticTagOther
  • NSLinguisticTagNoun
  • NSLinguisticTagVerb
  • NSLinguisticTagAdjective
  • NSLinguisticTagAdverb
  • NSLinguisticTagPronoun
  • NSLinguisticTagDeterminer
  • NSLinguisticTagParticle
  • NSLinguisticTagPreposition
  • NSLinguisticTagNumber
  • NSLinguisticTagConjunction
  • NSLinguisticTagInterjection
  • NSLinguisticTagClassifier
  • NSLinguisticTagIdiom
  • NSLinguisticTagOtherWord
  • NSLinguisticTagSentenceTerminator
  • NSLinguisticTagOpenQuote
  • NSLinguisticTagCloseQuote
  • NSLinguisticTagOpenParenthesis
  • NSLinguisticTagCloseParenthesis
  • NSLinguisticTagWordJoiner
  • NSLinguisticTagDash
  • NSLinguisticTagOtherPunctuation
  • NSLinguisticTagParagraphBreak
  • NSLinguisticTagOtherWhitespace
  • NSLinguisticTagPersonalName
  • NSLinguisticTagPlaceName
  • NSLinguisticTagOrganizationName

NSLinguisticTagSchemeTokenType 来进行基本的分词(tokenization)就可以分辨出词语空格和标点符号了。至于话语信息或者区分话语的不同部分应该用 NSLinguisticTagSchemeLexicalClass

继续说其它scheme:

  • NSLinguisticTagSchemeLemma: 在词根可知时可分析出词根。
  • NSLinguisticTagSchemeLanguage:根据短语的语言来标记。标记出的值会以标准语言所写形式给出,例如"en""fr""de"等,和用 NSOrthography 类的效果相同。注意此类分词根据的是词语在整个句子或段落中的表意,而不是只根据该词本身来判断
  • NSLinguisticTagSchemeScript:类似上述也是标记不同语言,但会以如下的缩略形式给出:"Latn""Cyrl""Jpan""Hans""Hant"等。

回头看上面给出的样例代码,首先用一个你想要用到的scheme组成的数组来初始化一个 NSLinguisticTagger,然后在判断输入字符串的标记之后枚举出每一个tag。

标记选项

除可用的标记scheme之外,还有一些可以传给 NSLinguisticTagger 的附加选项(用按位或|)来改变细微的分词行为:

  • NSLinguisticTaggerOmitWords
  • NSLinguisticTaggerOmitPunctuation
  • NSLinguisticTaggerOmitWhitespace
  • NSLinguisticTaggerOmitOther

这些选项的每一个都可以细化标记所代表的广义类别。例如:NSLinguisticTagSchemeLexicalClass 配合 NSLinguisticTaggerOmitPunctuation 就可以在不同种类的标点符号中再细化。推荐用带block的迭代器或predicate来实现。

最后一个选项是针对 NSLinguisticTagSchemeNameType 的:

  • NSLinguisticTaggerJoinNames

默认一个名字中的每个短语都被分成不同的实例。很多情况下需要将类似“San Francisco”这样的名字当作一个短语而不是两个短语来看待。传入这个属性即可实现这个功能。


不幸的是在移动设备的UI设计中,自然语言处理并没有并没有被充分的利用。如果能够有效的利用,用户就可以用说话来代替手上的触摸动作来完成相同的事,而且会花费更少的时间。

当然要做到这点并不容易,但如果我们花费一点点时间能让应用在视觉上更赞,就可以给用户与设备和应用的交互体验上带来很大的颠覆。等到那时,再加上 NSLinguisticTagger,使用移动应用将从未如此简单。