Swift NSLinguisticTagger的结果是英语以外的语言

时间:2018-06-10 19:25:29

标签: swift nlp 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)

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

e.g。用于词性标注和命名实体识别:

:确定者

麻烦制造者:名词

:确定者

回合:名词

钉住:名词

...

Apple Inc。:Noun

史蒂夫乔布斯:个人名称

Apple Inc。:OrganizationName

但是对于德语句子

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”和命名实体识别,不返回任何结果:

Apple:OtherWord

führt:OtherWord

die:OtherWord

Hitliste:OtherWord

...

是否有人尝试使用其他语言而不是英语,或者只有在使用英文文本时才能认真使用。我找不到任何Apple文档,从应该支持的语言列表中解释语言功能。或者我做错了什么?

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

Krid

1 个答案:

答案 0 :(得分:0)

我尚未测试您的上述情况,但附上我用来开发语音标记器的以下内容。它包括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)
}