NLTaggerで固有表現抽出

Swift で固有表現を抽出するには、Natural Language フレームワークの NLTagger クラスを利用します。Foundation フレームワークの NSLinguisticTagger もありますが、Natural Language フレームワークに置き換えられて、非推奨になっています。

まず .nameType スキームを指定して、NLTagger のインスタンスを作成します。そして範囲、言語単位などを指定して enumerateTags(in:unit:scheme:options:using:) を呼び出します。

指定したオプションでは、空白や句読点を除外するオプションに加えて、.joinNames というオプションも指定しています。このオプションは固有表現を複数の単語ではなく、一つにまとめて返します。

extension を使ってメソッドとして String に追加しましょう。

import NaturalLanguage

extension String {
    func getNamedEntities() {
        let tagger = NLTagger(tagSchemes: [.nameType])
        tagger.string = self
        let range = self.utf16.startIndex..<self.utf16.endIndex
        let options: NLTagger.Options = [
            .omitPunctuation, .omitWhitespace, .joinNames
        ]
        let tags: [NLTag] = [
            .personalName, .placeName, .organizationName
        ]

        tagger.enumerateTags(
            in: range,
            unit: .word,
            scheme: .nameType,
            options: options) { tag, tokenRange in
                if let tag = tag, tags.contains(tag) {
                    let name = String(self[tokenRange])
                    print("\(name): \(tag.rawValue)")
                }
                return true
            }
    }
}
let text = "Dr. Sameen Shaw is a former U.S. Marine, Physician and a US Army ISA operative."
text.getNamedEntities()

上記の実行結果:

Sameen Shaw: PersonalName
US Army ISA: OrganizationName

ほかの言語を使用したい場合、setLanguage(_:) で設定すればいいです。

現在、日本語の固有表現抽出はまだサポートされていません。 availableTagSchemes(for:language:) を使って利用可能なタグスキームを取得できます。

let language: NLLanguage = .japanese
let units: [NLTokenUnit] = [.word, .sentence, .paragraph, .document]

let availableTagSchemes: Set<NLTagScheme> = Set(units.flatMap { unit in
    NLTagger.availableTagSchemes(for: unit, language: language)
})
for tag in availableTagSchemes {
    print(tag.rawValue, terminator: " ")
}

// output
// Script Language TokenType

Tags: ,

Updated: