首页 > 解决方案 > 非英语语言的 Swift NSLinguisticTagger 结果

问题描述

我目前正在查看 Swift 的 NSLinguisticTagger。出于测试目的,我使用了 appcoda Introduction to Natural Language Processing中的代码。

对于英语,它按预期工作并在教程中描述。但是当我在英语以外的语言上使用 NSLinguisticTagger 时,词形还原、词性和命名实体识别不会产生有用的结果。对于命名实体识别,我可以理解这一点,但对于前两个选项,我认为至少应该有一个基本的结果。我是否错过了特定语言的设置,或者 NSLinguisticTagger 在用于英语以外的语言时仅适用于语言检测和标记化?

这是 Sai Kambampati 在他的教程中使用的代码:

import Foundation

let quote = "Here's to the crazy ones. The misfits. The rebels. The troublemakers. The round pegs in the square holes. The ones who see things differently. They're not fond of rules. And they have no respect for the status quo. You can quote them, disagree with them, glorify or vilify them. About the only thing you can't do is ignore them. Because they change things. They push the human race forward. And while some may see them as the crazy ones, we see genius. Because the people who are crazy enough to think they can change the world, are the ones who do. - Steve Jobs (Founder of Apple Inc.)"

let tagger = NSLinguisticTagger(tagSchemes:[.tokenType, .language, .lexicalClass, .nameType, .lemma], options: 0)
let options: NSLinguisticTagger.Options = [.omitPunctuation, .omitWhitespace, .joinNames]

func determineLanguage(for text: String) {
  tagger.string = text
  let language = tagger.dominantLanguage
  print("The language is \(language!)")
}

determineLanguage(for: quote)

func tokenizeText(for text: String) {
  tagger.string = text
  let range = NSRange(location: 0, length: text.utf16.count)
  tagger.enumerateTags(in: range, unit: .word, scheme: .tokenType, options: options) { tag, tokenRange, stop in
      let word = (text as NSString).substring(with: tokenRange)
      print(word)
  }
}

tokenizeText(for: quote)

func partsOfSpeech(for text: String) {
  tagger.string = text
  let range = NSRange(location: 0, length: text.utf16.count)
  tagger.enumerateTags(in: range, unit: .word, scheme: .lexicalClass, options: options) { tag, tokenRange, _ in
      if let tag = tag {
          let word = (text as NSString).substring(with: tokenRange)
          print("\(word): \(tag.rawValue)")
      }
  }
}

partsOfSpeech(for: quote)

func namedEntityRecognition(for text: String) {
  tagger.string = text
  let range = NSRange(location: 0, length: text.utf16.count)
  let tags: [NSLinguisticTag] = [.personalName, .placeName, .organizationName]
  tagger.enumerateTags(in: range, unit: .word, scheme: .nameType, options: options) { tag, tokenRange, stop in
      if let tag = tag, tags.contains(tag) {
          let name = (text as NSString).substring(with: tokenRange)
          print("\(name): \(tag.rawValue)")
      }
  }
}

namedEntityRecognition(for: quote)

对于英文句子,结果完全符合预期。

例如,对于词性标注和命名实体识别:

的:确定者

麻烦制造者:名词

的:确定者

轮:名词

钉子:名词

...

苹果公司:名词

史蒂夫乔布斯:个人姓名

苹果公司:组织名称

但是对于德语句子

let quote = "Apple führt die Hitliste der Silicon-Valley-Unternehmen an, bei denen sich Ingenieure das Wohnen in der Nähe nicht mehr leisten können. Dahinter folgen das Portal Reddit (San Francisco), der Suchriese Google (Mountain View) und die sozialen Netzwerke Twitter (San Francisco) und Facebook (Menlo Park)"

只有语言检测和标记化似乎工作正常。对于仅“OtherWord”的词性标记和命名实体识别,根本不返回任何结果:

苹果:OtherWord

führt: 其他词

死:其他字

热门榜单:OtherWord

...

是否有人尝试以英语以外的其他语言使用该课程,或者它仅在使用英文文本时才真正可用。除了应支持的语言列表之外,我找不到任何解释语言功能的 Apple 文档。还是我做错了什么?

非常感谢任何将我指向解决方案的评论。

克里德

标签: swiftnlpnslinguistictagger

解决方案


我没有测试你的上述情况,但我附上了我用来开发词性标注器的以下内容。它包括 setLanguage 命令和 setOthography 命令。(后者,我还没有尝试过)。

我的理解是标记器是识别语言并在需要时切换语言或者可以设置。看来这里使用的逻辑没有完全揭示。我已经确定我的最佳做法是尽可能设置语言。在此代码中,语言存储为字符串语言。(顺便说一句,在我的情况下,它是通过阅读一个更大的文档来完成的。)

最后,我有机会在本周看到这一点。我在一家苹果商店(在美国)处理另一件事,并观察到另一位客户在测试手机并讨论想要用法语发消息。该技术展示了如果 iMessage 继续看到法语,它将如何开始理解。我观察到这一点的想法是,它确实有效,但如果可能的话,如果可以在外部进行切换会更好。

    if let language = language {
    // If language has a value, it is taken as a specification for the language of the text and set on the tagger.
    let orthography = NSOrthography.defaultOrthography(forLanguage: language)
    POStagger.setOrthography(orthography, range: range)
    POStagger.setLanguage(NLLanguage(rawValue: language), range: range)
}

推荐阅读