0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GLiNER2で会話と日記を構造化する【Python知識バックエンド 第4部】

0
Posted at

GLiNER2からJSONが返ってきたら、それを保存して終わりにしてよいだろうか。今回は、抽出モデルの出力と、アプリで使う記録の間に必要な処理を整理する。

執筆メモ(2026-09-25、公開時に削除):実装前の設計草稿。以下のスキーマ、JSON、処理手順は提案であり、実行済みコードやモデル出力ではない。公開前にバージョン固定したコード、実出力、失敗例、評価結果を追加する。

最初に取り出す項目を絞る

最初の対象は人物、テーマ、イベント、日付とする。心理状態や能力のように判断が広がりやすい項目は対象外にする。

項目・関係 意味 混同しないもの
person 本文中で言及された人物 発言者、アカウントID
topic 明示された関心・会話の対象 隠れた関心の推測
event 名前や記述で特定できる催し 将来あり得る催し全般
date 本文中の日付表現 実際に開催・参加した証拠
expressed_interest_in 関心を表明した 専門能力、参加意思、申込み
attended 参加したとの記述 参加予定、不参加、仮定

上の名前はアプリで試すラベルであり、GLiNER2が常に正しく判定できる組み込みの保証ではない。ラベル名と説明文も評価対象にする。

GLiNER2の呼び出し口

公式READMEでは、エンティティ抽出の extract_entities、構造化抽出の extract_json、関係抽出の extract_relations、スキーマを組み合わせる extract が説明されている。

原文との対応には include_spans、モデルのスコア取得には include_confidence を検討する。採用するモデル・バージョンで実際の返り値を確認し、アプリ側の変換処理をテストする。READMEには複数のモデル系列があるため、異なる系列の例を無条件に混ぜない。

具体的な導入手順は、パッケージのバージョンとモデルrevisionを固定した時点で確定する。初回モデル取得、ロード、推論は測定を分ける。

モデルの前後に必要な処理

取り込み元の権限・利用目的を確認
  -> 原文の版とハッシュを保存
  -> 長文なら分割し、原文との位置対応を保持
  -> GLiNER2で候補を抽出
  -> 戻り値の形式と引用範囲を検査
  -> 人物の同定、日付の解釈、否定・予定を確認
  -> 根拠付きの未確認候補として保存
  -> 人が採用・訂正・保留
  -> 現在の権限に従って検索用データを更新

原文の改行や文字を正規化してから推論すると、返された位置が元の本文とずれる場合がある。最初は原文を保持し、加工する場合は位置の対応表も持つ。

長文を分割する場合は、人物名が前の区切りに、関係の説明が次の区切りにあるケースを試す。重なり部分の抽出を単純に追加すると重複するため、原文の版と文字範囲などで整理する。

モデルの出力を直接公開しない

たとえば、次のような正規化済み候補をアプリ内部で扱う。

{
  "candidate_id": "cand-001",
  "source_revision_id": "rev-001",
  "subject_mention": "アキ",
  "predicate": "expressed_interest_in",
  "object_mention": "Python",
  "subject_id": null,
  "review_status": "pending",
  "resolution_status": "unresolved",
  "extractor": "gliner2",
  "model_revision": null
}

これは説明用の手作りデータだ。実行時には使用したモデルrevisionを必須で記録し、人物IDが解決していない候補を人物の確定プロフィールには載せない。

高いconfidenceだけで採用を決めない。原文との一致、誰についての記述か、否定や予定の扱いを別に確認する。

間違えると困る例からテストする

入力例 期待する扱い
アキはPythonに興味がある。 関心の候補。専門家や講師とは断定しない
アキは読書会には参加しなかった。 肯定の参加履歴を作らない
来月の読書会に参加したい。 希望として扱い、参加確定にしない
Pythonが好きなのはミナで、私は初心者です。 関心を発言者へ誤って割り当てない
興味がないわけではない。 判断が難しければ保留する
前は使っていたが、今は使っていない。 過去と現在を一つの状態に潰さない
アキという人が別のグループにもいる。 同名だけで人物IDを統合しない

抽出で否定を落とした場合、保存側だけで必ず修復できるとは限らない。モデルの失敗を記録し、曖昧な候補を保留する経路を用意する。ルールで補う場合も同じ評価用データで確認する。

やり直しても壊さない

抽出単位の識別には、原文の版、抽出器、モデルrevision、スキーマ・設定のハッシュを使う。同じ処理の再試行と、設定を変えた新しい抽出を区別する。

実行失敗は「候補がなかった」と区別する。処理中の一部だけが採用済みになる状態を避け、実行状態を記録する。

すでに人が訂正した関係については、新しい候補との差分を表示する。再実行のたびに古い誤りへ戻らないことを確認する。

評価の読み方

エンティティ抽出の正解率が高くても、不参加を参加に変える誤りがあるなら、イベントの自動参加者リストには使えない。項目ごとの抽出性能と、用途としての受入条件は分ける。

第2部で分けた未使用データについて、抽出結果、余分な抽出、取りこぼし、訂正内容を記録する。主観的に「よく取れた」とまとめず、どの条件では保留が必要だったかまで残す。

次回は、こうして保存した記録を個人の外部記憶として検索し、ブログの材料へ変える。

参考:GLiNER2公式README、関係抽出の公式チュートリアル

連載目次 / 前回 / 次回

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?