WWDC Quick Look 💓 By SwiftGGTeam
Make apps smarter with Natural Language

Make apps smarter with Natural Language

元の動画を見る

ハイライト

WWDC 2020 での自然言語NLTagger増加tagHypotheses信頼レベルはNLEmbedding文レベルのベクトルを追加し、Create ML の転移学習をカスタムの単語シーケンス タガーに拡張します。

主要内容

ニュース アプリは、記事から場所、人物、組織を抽出したいと考えています。以前は、それは可能でしたNLTagger予測結果ですが、この結果がどの程度信頼できるかはわかりません。 Session の Buzz の例では、次のような問題が発生します。Do Not Disturb while drivingそれが組織名とみなされ、インターフェースの右側に役に立たないエンティティが表示されました。

WWDC 2020 の Natural Language は、そのような予測に自信を与えます。tagHypotheses候補ラベルとその信頼スコアが返されます。開発者は、自社のビジネスを表すデータを使用してしきい値を調整し、カテゴリごとに異なるしきい値を設定して、固有表現認識における誤検出を減らすことができます。

もう 1 つの問題点は検索です。食品配達アプリである Nosh の FAQ は、ユーザーがスクロールして答えを見つけることによってのみ見つけることができます。単語ベクトルは単語間の距離を表現できますが、単語ごとのベクトルを平均すると文の構造が失われます。新しい文の埋め込みは、文を 512 次元のベクトルに直接エンコードし、「どこに配達しますか?」などのクエリを可能にします。意味的に類似した FAQ と一致します。

テキスト サイズが大きくなり続けると、線形移動が遅くなります。 Verse の例では、詩の各行の文ベクトルをカスタム埋め込みに圧縮し、最近傍検索を使用して意味的に最も近い詩を見つけます。最後に、Nosh はカスタム ワード タガーを使用して、ユーザー入力から食べ物、レストラン、from_city、to_city などのフィールドを抽出し、フリー テキストを実行可能なビジネス パラメータに変換します。

詳細

信頼度を使用して名前付きエンティティの誤認をフィルタリングする

(03:46) Natural Language の基本機能には、言語識別、単語分割、品詞タグ付け、見出し語化、および固有表現認識が含まれます。以前は、これらの API は予測されたラベルを返していました。 2020年の新機能tagHypotheses候補ラベルと対応する信頼度を返します。Buzz の例では、これを使用して、信頼度の低い組織名の誤認を除外します。

import NaturalLanguage

let tagger = NLTagger(tagSchemes: [.nameType])
let str = "Tim Cook is very popular in Spain."
let strRange = Range(uncheckedBounds: (str.startIndex, str.endIndex))
tagger.string = str
tagger.setLanguage(.english, range: strRange)

tagger.enumerateTags(in: str.startIndex..<str.endIndex, unit: .word, scheme: .nameType, options: .omitWhitespace) { (tag, tokenRange) -> Bool in
    let (hypotheses, _) = tagger.tagHypotheses(at: tokenRange.lowerBound, unit: .word,
                                               scheme: .nameType, maximumCount: 1)
    print(hypotheses)
    return true
}

キーポイント:

  • NLTagger(tagSchemes: [.nameType])固有表現認識を使用します。
  • tagger.stringそしてsetLanguageテキストと言語の情報をタグ付け者に渡します。
  • enumerateTags単語ごとの走査予測結果。
  • tagHypotheses(at:unit:scheme:maximumCount:)トークン位置における候補ラベルと信頼度を返します。
  • セッションは、アプリケーション自身の代表的なデータを使用してしきい値を調整し、カテゴリごとに個別にしきい値を設定することを推奨します。

単語ベクトルと文ベクトルを使用して類似性を表現する

12:16NLEmbedding.wordEmbedding(for:)静的な単語の埋め込みを提供します。単語を指定すると、ベクトルを取得したり、2 つの単語間の距離を計算したり、最も近い単語を列挙したりできます。単語レベルの類似性を処理するのに適しています。

import NaturalLanguage

if let embedding = NLEmbedding.wordEmbedding(for: .english) {
    let word = "bicycle"

    if let vector = embedding.vector(for: word) {
        print(vector)
    }

    let dist = embedding.distance(between:word, and: "motorcycle")
    print(dist)

    embedding.enumerateNeighbors(for: word, maximumCount: 5) { neighbor, distance in
        print("\(neighbor): \(distance.description)")
        return true
    }
}

キーポイント:

  • wordEmbedding(for:)システムの組み込み単語埋め込みを言語ごとに取得します。
  • vector(for:)ベクトル空間での単語の表現を返します。
  • distance(between:and:)2 つの単語間の距離を計算します。
  • enumerateNeighborsベクトル空間で隣接する単語を列挙します。

(16:30) FAQ 検索には文レベルのセマンティクスが必要です。セッション記述文の埋め込みは、文を512次元のベクトルにエンコードし、2つの文間の距離を計算するため、ユーザーの質問とFAQの質問の照合処理に適しています。

import NaturalLanguage

if let embedding = NLEmbedding.sentenceEmbedding(for: .english) {
    let sentence = "This is a sentence."

    if let vector = sentenceEmbedding.vector(for: sentence) {
        print(vector)
    }

    let dist = sentenceEmbedding.distance(between: sentence, and: "That is a sentence.")
    print(dist)
}

キーポイント:

  • sentenceEmbedding(for:)文レベルのエントリです。
  • vector(for:)完全な文を固定次元ベクトルにエンコードします。
  • distance(between:and:)意味空間における 2 つの文間の距離を比較します。
  • トランスクリプトには、この機能が単一の文、複数の文、または短い段落に適しており、長いテキストは処理のために文に分割する必要があることが明確に記載されています。

文ベクトルを使用して最近傍検索を実行する

(18:31) Nosh の FAQ 検索では、回答ごとに 2 つまたは 3 つのクエリ例が事前に用意されており、これらのクエリの文ベクトルが保存されます。実行時には、ユーザー入力も文ベクトルに変換され、テーブル内のベクトルを使用して距離が計算されます。距離が最も小さいキーが表示される回答に対応します。

func answerKey(for string: String) -> String? {
        guard let embedding = NLEmbedding.sentenceEmbedding(for: .english) else { return nil }
        guard let queryVector = embedding.vector(for: string) else { return nil }

        var answerKey: String? = nil
        var answerDistance = 2.0

        for (key, vectors) in self.faqEmbeddings {
            for (vector) in vectors {
                let distance = self.cosineDistance(vector, queryVector)
                if (distance < answerDistance) {
                    answerDistance = distance
                    answerKey = key
                }
            }
        }

        return answerKey
    }

キーポイント:

  • このメソッドは、最初に英語の文の埋め込みを取得し、次にユーザー入力を次の形式に変換します。queryVector
  • faqEmbeddings保存されるのは、事前に計算されたクエリ ベクトルの例です。
  • cosineDistanceユーザー クエリと各サンプル クエリの間の距離を比較するために使用されます。
  • answerDistance現在の最小距離を記録し、answerKey対応する回答を記録します。

(22:16) データ量が数千行の詩になると、線形検索が遅くなります。 Verse の例では、詩の各行の文ベクトルを辞書に登録し、Create ML を使用して Core ML カスタム エンベディングを生成します。このモデルは、ベクトル テーブルを圧縮し、最近傍検索のための幾何学的情報を保存します。

import NaturalLanguage
import CreateML


let embedding = try MLWordEmbedding(dictionary: sentenceVectors)

try embedding.write(to: URL(fileURLWithPath: "/tmp/Verse.mlmodel"))

キーポイント:

  • sentenceVectorsキーにはカスタム文字列を使用できます。この例では、詩と行番号を反転できるキーを使用しています。
  • MLWordEmbedding(dictionary:)ベクトル辞書を Create ML で記述できる埋め込みに変換します。
  • write(to:)出力は Core ML モデル ファイルです。
  • セッションの説明 このカスタム埋め込みにより、最近傍クエリがテーブル全体を走査することを回避できます。

(22:43) アプリの実行中は、ユーザー クエリ ベクトルの計算に文の埋め込みが引き続き使用されますが、最近傍検索はカスタム 埋め込みによって完了します。

func answerKeyCustom(for string: String) -> String? {
        guard let embedding = NLEmbedding.sentenceEmbedding(for: .english) else { return nil }
        guard let queryVector = embedding.vector(for: string) else { return nil }

        guard let (nearestLineKey, _) = self.customEmbedding.neighbors(for: queryVector, maximumCount: 1).first else { return nil }

        return self.poemKeyFromLineKey(nearestLineKey)
    }

キーポイント:

  • queryVectorまだからNLEmbedding.sentenceEmbedding(for:)
  • customEmbedding.neighbors(for:maximumCount:)最近傍を直接返します。
  • nearestLineKeyカスタム埋め込みを記述するときに予約されるキーです。
  • poemKeyFromLineKey行レベルのキーを詩レベルの結果に変換します。

カスタム単語シーケンス タガーのトレーニングと使用

(29:03) カスタム単語タガーのタスクは、文内の各トークンにタグを付けることです。 Nosh の例では、「クパチーノからピザを配達しますか?」から food、from_city、to_city、restaurant などのフィールドを抽出したいと考えています。トランスクリプトには、単純な単語リストが使用できると記載されていますNLGazetteer、しかし語彙はすべての値をカバーすることはできず、文脈を理解できません。単語タグ付け機能は、コンテキストを使用して出発都市と配達都市を区別できます。

(33:21) トレーニングフェーズでは、最初にラベルが定義され、サンプルセンテンスが収集されてラベルが付けられます。セッションでは、JSON 形式でトークン/ラベルの並列シーケンスが表示され、2020 年の転移学習では単語のタグ付けが使用されることが説明されています。Create ML はトレーニング データを Natural Language に渡し、最終的に Core ML モデルを生成します。

(36:45) 導入フェーズで使用されますNLModelコンパイルされたモデルをロードしてフックします。NLTaggerカスタムタグスキームについて。NLTagger単語のセグメンテーションと単語ごとのアプリケーション モデルを担当します。

func findTags(for string: String) {
        let model = try! NLModel(contentsOf: Bundle.main.url(forResource: "Nosh", withExtension: "mlmodelc")!)
        let tagger = NLTagger(tagSchemes: [NoshTags])

        tagger.setModels([model], forTagScheme: NoshTags)
        tagger.string = string

        tagger.enumerateTags(in: string.startIndex..<string.endIndex, unit: .word, scheme: NoshTags, options: .omitWhitespace) { (tag, tokenRange) -> Bool in

            let name = String(string[tokenRange])

            switch tag {
                case NoshTagRestaurant:
                    self.noteRestaurant(name)
                case NoshTagFood:
                    self.noteFood(name)
                case NoshTagFromCity:
                    self.noteFromCity(name)
                case NoshTagToCity:
                    self.noteToCity(name)
                default:
                    break
            }
            return true
        }
    }

キーポイント:

  • NLModel(contentsOf:)すでにバンドルにコンパイル済みのロードmlmodelc
  • NLTagger(tagSchemes: [NoshTags])カスタム ラベル システムを作成します。
  • setModels([model], forTagScheme:)モデルをこのタグ システムにバインドします。
  • enumerateTagsモデルによって予測されたラベルを単語ごとに返します。
  • switch tagrestaurant、food、from_city、to_city をそれぞれ業務処理機能に引き渡します。

重要ポイント

  • ローカル FAQ セマンティック検索を実行します。機能: ユーザーが自然言語で質問を入力し、最も近い FAQ の回答に直接ジャンプできるようにします。実行する価値がある理由: セッションは、文の埋め込みを使用してユーザー クエリと事前計算された FAQ クエリを比較するプロセスを示しています。開始方法: 各回答に対していくつかの質問例を用意し、ベクトルを事前計算して、NLEmbedding.sentenceEmbedding(for:)クエリ ベクトルを取得して距離を計算します。

  • ニュースエンティティ抽出のための信頼パネル。対処法: 人物、場所、組織名を記事ページの右側に表示し、信頼性の低いエンティティを非表示にします。実行する価値がある理由: バズの例は、固有表現認識がフレーズを組織名として誤認する可能性があることを示しています。tagHypothesesフィルタリングの基礎を提供できます。開始方法: 各エンティティの信頼スコアを記録し、実際の記事のサンプルを使用して、人、場所、組織のしきい値をそれぞれ調整します。

  • 写真やドキュメントの自然言語検索を実行します。機能: キャプション、概要、または段落とユーザーが入力した文に最もよく一致する画像とドキュメントを検索します。実行する価値がある理由: Transcript では、FindMyShot が画像キャプションの文埋め込みを使用して検索できること、またドキュメント、メッセージ、コメント、問題レポートをクラスター化できることにも言及しています。開始方法: 各キャプションまたは要約の文ベクトルを計算し、小さなデータ セットの線形検索を行ってから、大きなデータ セットのカスタム エンベディングに変換します。

  • テイクアウトまたは旅行の入力パーサーを作成します。やるべきこと: 自由記述文から食べ物、レストラン、出発都市と到着都市を抽出します。実行する価値がある理由: Nosh の例は、カスタム ワード タガーをコンテキストに応じて区別する方法を示していますfrom_cityそしてto_city。開始方法: タグを定義し、ユーザーが入力できるサンプル文を収集し、Create ML を使用して単語タガーをトレーニングしてから、NLModelそしてNLTaggerアプリ内で実行します。

関連セッション

コメント

GitHub Issues · utterances