Azure Open AI Serviceを使用して文章を分類する ~GPTを用いたゼロショット分類編~

はじめに

ISID金融ソリューション事業部から兼務でAITCに所属しております、若本です。
本記事では、下記の記事の中から、3.ゼロショット分類(Zero-Shot Learning)についてピックアップして解説を行います。
isid-ai.jp

具体的なタスクとしては、Azure OpenAIサービスを用いた、問い合わせメールの分類を行います。なお、タスクの詳細は元記事をご一読いただければ幸いです。

また今回の実験では、プロンプトの与え方を変化させながら分類精度を比較することで、表現の違いによる精度への影響についても検証しています。

※ プロンプト:AIモデルに対する「入力文」もしくは「命令文」のこと

実験概要

本記事では、問い合わせメールの文章分類実験全体のうち、ゼロショット分類のみを取り上げます。
このとき、下記の情報を成形してプロンプト(prompt)としてGPTにリクエストします。

  • GPTに与える指示文章
  • ラベル一覧(<ラベル0>, <ラベル1>, ...<ラベル14>)
  • 問い合わせメールの内容

また、本実験では、GPT-3(text-davinci-003)のみを使用しています。

ゼロショット分類(Zero-Shot Learning)とは

ゼロショット分類とは、各ラベルに該当するデータ(=例文)を知らないAIが分類を行うタスクを指します。 今回のケースでは、問い合わせメール文章と全てのラベル候補を与え、文章がどのラベルに属するかを分類させることになります。

プロンプトの例

下記のようなプロンプトを用いて分類を行いました。

 以下の条件に従って、promptの文章がどのカテゴリに属するかをlabelに表示してください。
 カテゴリは下記の種類があります。
 0:<ラベル0>
 1:<ラベル1>
 2:<ラベル2>
 ...

 prompt:
 {text}

 label:

<ラベルN>には実際のラベル名が、{text}には問い合わせメールの内容が入ります。
一部省略していますが、今回は15クラス分類ですのでラベルが15個並ぶ形になります。

上記のプロンプトによってラベルに該当する「数値」が返ってくるため、分類が実施しやすくなります。単純に分類すると文字列が返ってきてしまうため、自動で性能計測することが難しくなります。

ゼロショット(zero-shot)分類の工夫点

下記の観点でプロンプトを工夫することが考えられます。

  1. プロンプト内の単語を変える
  2. プロンプト内で与える指示の表現/構成を変える
  3. プロンプト内で与えるラベルの表現/構成を変える

zero-shotのため、どのような表現で与えることが望ましいのかを検証することにします。

実験結果

1. プロンプト内の単語を変える

前述のプロンプト例から、以下記述の(単語)の部分を変更します。

以下の条件に従って、promptの文章がどのカテゴリに属するかを(単語)に表示してください。

ここでは、4つの似たような意味を持つ単語の候補(label, type, class, category)をそれぞれ与えてみます。
これにより、プロンプトを用いた文章分類が、指示文章の僅かな変化に対して鋭敏なのか確かめます。

結果は下記の通りになりました。

置き換えた単語 評価精度
label 30%
type 22%
class 28%
category 24%

乱数の影響もあるとは思いますが、1つの単語を変更するだけでも最大8%の性能差がありました。
これは、プロンプト的には意味のない「label」や「type」を記号的なものではなく、意味のあるものとして扱っていることが推察されます。実験に用いたGPT-3(text-davinci-003)は入力の僅かな単語に対して鋭敏であるといえそうです。(ただし、ChatGPT、GPT-4とモデルがアップデートされるにつれてこの影響は少なくなることも十分考えられます。)

単語は「label」を選択した時が最も精度が高くなりました。以降、(単語)の箇所は「label」として進めていきます。

2. プロンプト内で与える指示の表現/構成を変える

前述のプロンプト例から、指示の与え方を変更します。
ここでは、プロンプトを用いた文章分類においてどのように分類タスクを与えるべきか検証します。
単語の変更で影響があったことから、指示の与え方も精度に影響しそうです。

パターン1(例と同じ):

 以下の条件に従って、promptの文章がどのカテゴリに属するかをlabelに表示してください。
 カテゴリは下記の種類があります。

パターン2:分類することを明示する

 promptの文章がどのカテゴリに属するかを分類し、labelに表示してください。
 カテゴリは下記の種類があります。

パターン3:「数値で」分類することを明示する

 promptの文章がどのカテゴリに属するかを分類し、数値をlabelに表示してください。
 カテゴリは下記の種類があります。

結果は下記の通りになりました。

手法 評価精度
パターン1 30%
パターン2 22%
パターン3 24%

前述例のシンプルな指示が最も高い精度となりました(パターン1:30%)。 ここで得られた示唆は下記の通りです。

  • 「分類」であることを明示しないほうがよい
    • 分類を明示していないパターン1のみ精度が高いです。
    • パターン2ではGPT-3の出力する文章の形式が安定しませんでした。(物証が返ってきたり、数字が返ってきたりなど)
    • パターン3ではパターン2より数値の出力が増えたものの、精度がそれほど向上しませんでした。「分類して数値に結びつける」という参照に失敗しているものがありそうです。

コーパスやインターネット上に「分類して」と記述されている情報も多くはないので、直接「分類して」とプロンプトに記述するのは良くなさそうです。「どれに属するか」「どの文章に似ているか」などを指示として与えるほうが望ましいと考えられます。

3. プロンプト内で与えるラベルの表現/構成を変える

最後に、ラベルの与え方を変更し、ラベルの与え方が精度に及ぼす影響を検証します。
このとき、下記の2つの観点でラベルの与え方を変更します。

1) ラベルの書き方を変更する

1-1. 数値と関連付けてラベルを列挙する
 プロンプト例の方法になります。

 0:<ラベル0>
 1:<ラベル1>
 2:<ラベル2>
 ...

1-2. カンマでラベルを列挙する
 カンマでラベルを区切って列挙します。

 文章には次のカテゴリがあります:
 <ラベル0>,<ラベル1>,<ラベル2>,...
なお、こちらのフォーマットはChatGPTに「分類したい」旨を伝えて提示されたフォーマットになります。

2) ラベルの内容を変更する(詳細にする)

ラベルの内容を詳細化します。分類ラベルは略称であったり情報が省略されることが多いため、意図した内容をラベルとして与え直します(ほぼクラス説明ですが、ゼロショットの範囲内とします)。

2-1. 元ラベル
 元データに付属していたラベルです。

 xx

2-2. 正式名称ラベル
 ラベルの正式な名称です。

 xxシステム

2-3. 詳細ラベル
 マニュアルの説明をラベルとして与え直したものです。

 xxシステム全般(モジュールA、モジュールB)

上記の組み合わせで評価精度を計算します。 結果は下記の通りになりました。

手法 元ラベル(2-1) 正式名称ラベル(2-2) 詳細ラベル(2-3)
数値と関連付けてラベルを列挙(1-1) 30% 22% 20%
カンマでラベルを列挙(1-2) 20% 24% **32%**

ラベルの内容によって、精度が上がる書き方が変わるという興味深い結果になりました。詳細なラベルを与える場合はカンマでラベルを列挙(1-2)することが望ましく、単純なラベルを与える場合は数値と関連付けてラベルを列挙(1-1)することが望ましいようです。
数値に関連付ける場合、単語同士の参照が複雑になってしまうため、長文をラベルにすると数値の参照が難しくなると解釈しています。

まとめ

本記事では、GPT-3を用いたゼロショット分類の結果をまとめました。
最高精度は32%と、教師あり学習だとあまり良い性能とは言えませんが、15クラスのゼロショット分類であることを考えると妥当な精度と言えそうです。
特にラベルの情報を増やすほど精度が上がる傾向が見られたことから、業務知識の不足が顕著にありそうです。

ChatGPT、GPT-4などの後継LLMでは本記事で述べたような「僅かな表現の違い」による差はある程度解消されていそうですが、検証すると意外な特性が見えたりするかもしれません。ご興味があればぜひ試していただければと思います。

ここまでお読みいただきありがとうございました。

執筆
金融ソリューション事業部 & AITC 若本 亮佑