ios - NLTagger : enumerating tags of multiple types in one pass

标签 ios swift macos coreml

使用NLTagger类,我想知道是否有人可以推荐最直接的方法来枚举给定文本中的标记标记,但为每个标记提取多个标记类型。例如,要枚举给定文本中的单词,请为每个单词提取(引理、词汇类别)。

似乎 enumerateTags() 方法和关联的 NLTag 类具有每个枚举仅报告一种特定标记类型的限制。因此,我可以通过多次遍历文本来实现我想要的目标,例如在第一遍中拉出与给定条件匹配的字符串范围,然后在后面的遍中进行匹配。例如,我可以像这样对所有名词和动词进行词形还原:

let tagger = NLTagger(tagSchemes: [.lemma, .nameTypeOrLexicalClass])
tagger.string = //some text
let keyWordCategories: [NLTag] = [.noun, .verb]
let options: NLTagger.Options = [.omitPunctuation, .omitWhitespace, .joinNames]

// In the first pass, we're going to record which ranges are of categories we're interested in
var keywordRanges = Set<Range<String.Index>>(minimumCapacity: 200)

// First pass: which are the nouns and verbs?
tagger.enumerateTags(in: text.startIndex..<text.endIndex, unit: .word, scheme: .nameTypeOrLexicalClass, options: options) { tag, tokenRange in
    if let tag = tag {
        if (keyWordCategories.contains(tag)) {
            keywordRanges.insert(tokenRange)
        }
    }
    return true
}

// Second pass: lemmatise, filtering on just the nouns and verbs
tagger.enumerateTags(in: text.startIndex..<text.endIndex, unit: .word, scheme: .lemma, options: options) { tag, tokenRange in
    if let tag = tag {
        if (keywordRanges.contains(tokenRange)) {
            lemmas.insert(tag.rawValue)
        }
    }
    return true
}

这种机制实现了所需的功能,但在我看来,这是一种有点笨拙且可能效率低下的处理方式。我本来期望能够在一次遍历中枚举(引理,词汇类别)。我假设 NLTagger 实例在幕后缓存内容,这样就效率而言,它并不像看起来那么糟糕。但就代码的简单性而言,它还远远不够理想。任何更熟悉此 API 的人都可以建议这是否真的是预期的模式吗?

最佳答案

您可以使用tags(in:unit:scheme:options:)获取具体范围内的引理,而不是迭代标记器的每个引理:

let tagger = NLTagger(tagSchemes: [.lemma, .nameTypeOrLexicalClass])
tagger.string = text
let options: NLTagger.Options = [.omitPunctuation, .omitWhitespace, .joinNames]

let keyWordCategories = Set<NLTag>(arrayLiteral: .noun, .verb)
var lemmas = Set<String>()
let unit: NLTokenUnit = .word
tagger.enumerateTags(in: text.startIndex..<text.endIndex, unit: unit, scheme: .nameTypeOrLexicalClass, options: options) { tag, tokenRange in
    if tag.map(keyWordCategories.contains) == true {
        if let lemma = tagger.tags(in: tokenRange, unit: unit, scheme: .lemma, options: options).first?.0?.rawValue {
            lemmas.insert(lemma)
        }
    }
    return true
}

关于ios - NLTagger : enumerating tags of multiple types in one pass,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63456240/

相关文章:

ios - 模拟器会杀死不像物理设备那样结束后台任务的应用程序吗?

ios - 苹果会拒绝使用 xcode 5.1 构建的应用程序吗

ios - 更改现有 Parse 数据的问题

MySQL写入文本文件

ios - 从 iOS 应用程序内访问使用 os_log 捕获的日志

swift - 如何在 macOS 中访问受限文件 (/User/user/Library/Messages/xxx)?

html - 我可以使用除应用程序内选项之外的其他选项在 iOS 中销售商品吗?

iphone - 如何将动态大小的标签始终放置在特定宽度 View 的中心?

ios - Alamofire : Type of expression is ambiguous in . 获取

ios - 导入数据后CoreData内存未释放