Cc457f846bdd1da0a6148cd0d4ff995c
用自然语言处理优化你的 App

作者:WAMaker

自然语言处理( Natural Language Processing ,以下简称 NLP )是人工智能语言学的分支学科。NLP 框架基于 Core ML 针对文字输入( typed ),手写识别( recognized handwriting )以及语音输入转换( transcribed speech )等应用场景进行了封装及优化 。

NLP API 已经在苹果自家的应用中使用,横跨多个平台,驱动多款应用。

NLP APIs 基石

  • 语言识别( language identification )

    在处理文本时首先需要知道目标语言是什么。

  • 文本切分( tokenization )

    将大段的文本切分成有意义的小段,切分的颗粒度通过标注单元( tagging units )指定 。

    如果你想要将一段文本以句子为单位进行切分,你需要设置标注单元为 sentence 。单纯的以 '.' 号作为句子的分隔符,下面这种情况会被错误的分成3句。

    当涉及到像中文这样复杂的语言时,要获得有意义的部分则需要将标注单元设置为 word

  • 词性( part of speech )

    对给定文本中的每一个词标注词性。

  • 词行还原( lemmatization )

    将不同形态的词转为词根,对于处理像俄语,土耳其语这样拥有非常多词性复杂变化的语言会非常有帮助。

  • 实体识别( named entity recognition )

    用于识别人名,地名,组织名等实体。

如何使用

NSLinguisticTagger ( NS_CLASS_AVAILABLE(10\_7, 5\_0) )

在 iOS 11 中,苹果对它进行了升级,以支持文本分割,实体识别,词性还原等多种新特性。

  • 标注单元( tagging units ):在原有 word 的基础上新增了 sentence,paragraph,document

    public enum NSLinguisticTaggerUnit: Int {
      case word
      case sentence
      case paragraph
      case document
    }

    提供了新的 API 用来查询对应单元( unit )和语言所支持的 NSLinguisticTagScheme 。

    class func availableTagSchemes(for unit: NSLinguisticTaggerUnit, language: String) -> [NSLinguisticTagScheme]
  • 语言识别( dominantLanguage )

  • 针对 Swift 4 增加了标签和标记方案的命名类型

  • 更好的性能

  • 更高的准确率

  • 更多的语言支持

NSLinguisticTagScheme

初始化 NSLinguisticTagger 时需要设定特征标记方案( Linguistic tag scheme )。

init(tagSchemes: [NSLinguisticTagScheme], options: Int)
特征标记方案( Linguistic tag scheme ) 适用单元( Applicable linguistic units ) 可能的返回值( Possible return values )
tokenType word 将短语在大粒度上分成词语、标点符号、空格并返回
lexicalClass word 将短语根据类型分为话语部分、标点符号、空格并返回
nameType word 将短语根据是否为命名实体分类并返回
nameTypeOrLexicalClass word 返回满足 nameType 或 lexicalClass 的部分
lemma word 在词根可知时返回词根
language word, sentence, paragraph, document BCP-47 language tag
script word, sentence, paragraph, document ISO 15924 script code

NSLinguisticTagger Options

用来确定需要排除的符号或需要合并的短语

public struct Options : OptionSet {

    public init(rawValue: UInt)

    // 省略单词
    public static var omitWords: NSLinguisticTagger.Options { get }

    // 省略标点符号
    public static var omitPunctuation: NSLinguisticTagger.Options { get }

    // 省略空格
    public static var omitWhitespace: NSLinguisticTagger.Options { get }

    // 省略其他
    public static var omitOther: NSLinguisticTagger.Options { get }

    // 针对 NSLinguisticTagSchemeNameType。
    // 默认一个名字中的每个短语都被分成不同的实例,
    // 很多情况下需要将类似 "San Francisco" 这样的名字当作一个短语而不是两个短语来看待,
    // 传入这个属性即可实现这个功能。
    public static var joinNames: NSLinguisticTagger.Options { get }
}

API Demo

P.S.:以下代码都是在 Xcode 9.0 beta 2 测试的。

  • 语言识别

    import Foundation
    
    let tagger = NSLinguisticTagger(tagSchemes: [.language], options: 0)
    tagger.string = "Die Kleinen haben friedlich zusammen gespielt."
    print(tagger.dominantLanguage ?? "language not found")
    
    /**
    * 控制台输出:
    * de
    * 注:de 是德语的语言代码
    */

    然而,下面这种情况,加 '.' 和不加会被识别成了两种语言= =

    import Foundation 
    
    var tagger = NSLinguisticTagger(tagSchemes: [.language], options: 0)
    tagger.string = "I love Swift"
    print(tagger.dominantLanguage ?? "language not found")
    
    tagger.string = "I love Swift."
    print(tagger.dominantLanguage ?? "language not found")
    
    /**
    * 控制台输出:
    * en
    * nb
    */

  • 文本分割

    ```swift
    import Foundation

    let tagger = NSLinguisticTagger(tagSchemes: [.tokenType], options: 0)
    let text = "Mr. Tim Cook presided over the earnings report of Apple Inc. on Tuesday."
    tagger.string = text
    let range = NSRange(location: 0, length: text.utf16.count)

top Created with Sketch.