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?

[自然言語処理]OpenAI APIで名前と役職を分離してみた

Last updated at Posted at 2024-09-15

前置き

議事録というものには一般的に、議題、会議の内容、発言記録などが記載されているが、その書き方(記法)は人それぞれである。

発言記録には、主に「発言者」「役職」「発言内容」といった情報が含まれている。どんな人がどんな発言をしたのかを記録するためだ。

しかしながらその記法はバラバラで、

田中(議長)こんにちは

という形式もあれば、

議長(田中)こんにちは

であったり、

田中議長 こんにちは

であったりもする。

この文字列から、誰が、どんな人で、どんな発言をしたのか、

つまり「発言者名」「役職」「発言内容」を切り分けたいと思った時、どんな方法があるだろう?

AIに任せちゃおう

今回はAIに任せてみた方法をご紹介しよう。

使用したLLMはopenAIのgpt-4oモデル。pythonでAPIを呼び出し、発言者情報をGPTモデルに渡して判別させる。

対象の議事録

対象の議事録はとある市町村の会議録。これは先ほどの話で言う田中議長 こんにちはの記法であり、「田中」と「議長」をプログラムで分離させることが難しいために、今回の方法を試した。

実装コード

python
from openai import OpenAI

api_key = os.environ.get('OPENAI_API_KEY')
client = OpenAI(api_key=api_key)
model = 'gpt-4o' 

def separate_name_and_title(speaker_info):
    # GPTへのプロンプトを作成
    prompt = f"以下の発言者情報のうち、名前を表している文字列のみを返答してください。それ以外に余計なことは返答しないこと。\n\n発言者情報:{speaker_info}\n\n"

    # GPTに対してリクエストを送信
    response = client.chat.completions.create(
        model=model,
        messages=[
            {"role": "system", "content": "あなたは日本語の助言者です。"},
            {"role": "user", "content": prompt}
        ]
    )

    # GPTの応答から名前を取得
    name = response.choices[0].message.content.strip()
    return name

プロンプトに渡しているspeaker_infoには、発言者情報を表す文字列が入っている。
例えば、
○水沢議長 これで諸般の報告を終わります。
と言った発言記録の場合、「○水沢議長」にあたる位置の文字列を正規表現で抜き出して渡した。

APIの呼び出しの記述は一般的だと思う(多分)。

モデルからの返答をそのまま変数に入れて使うので、プロンプトには余計なことを言わないように(例えば、「名前に当たるのは水沢です」みたいな返答をしないように)念を押した。意外とこれで回答を制御できる。

その後はnameを基準にpost(役職)を分離した。

結果

以下は出力結果である。

スクリーンショット 2024-09-15 14.38.47.png

見てわかる通り、同じ文字列でも出力結果が異なっている。

田村議長を「田村」としている場合もあれば、「田村議長」としている場合もある

つまり回答にゆれがみられた。

これでは使えないかな、と落ち込んだが、一応「回答ゆれ」のパターンはどのようなものがあるのか、全体のどの程度なのかを調べることにした。

結果を分析する

同じ発言者情報のうち、いくつの回答ゆれパターンがあるのかを調べた。

田村議長の場合で言うなら、「田村」「田村議長」のほかにパターンは存在するのか。それぞれのパターンは全体のうちいくつあるのか等の数値を出す。

スクリーンショット 2024-09-15 23.01.06.png

すると驚くべきことに、今回のデータに限った話ではあるが、回答ゆれのパターンは二つ。

1
名前と役職を正しく分離し、名前のみを出力している
2
発言者情報(元の文字列)をそのまま出力している

役職名の方も同じ処理でカウントして比較しているが、数字は合っているし、同じように2パターン(正しく分離できているか、nullか)だった。そしてこれら2パターンの合計を取ると総数となる。

つまり本当にこの2パターンのようだ(今回に限った話)。

結果と分析を踏まえて

ここまでの情報を元に考えると、LLMの回答ゆれが2パターンなら、パターン2の際にfalseということにしてもう一度apiを呼び出し、パターン1がでるまで続けるというガチャガチャ方式が取れる。

元としたデータ数が少ない(2600例ほど)うえにほとんどが田村議長なので、多分さらにやっていくと別のパターンも出てくるだろうが、田中議長 こんにちは記法の分離方法に散々悩まされてきた私としては、これはかなり嬉しい結果だった。

ガチャガチャを試してみたら、また書こう。

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?