watsonx.aiを使って基盤モデルによるクチコミの感情分析を試してみた

# はじめに
Hello Qiita_World
はじめまして、IT業界1年目の新人です。今回は初のQiitaの記事の執筆となりますが、初投稿では基盤モデルによるクチコミの感情分析体験を共有したいと思います。
感情分析は、テキストデータから感情極性（肯定的-positive、否定的-negative、中性的-neutral）を識別し、分類するプロセスです。感情分析だと現在機械学習のアプローチが主流とは思いますが、実は感情分析も分類タスクの一種類として、基盤モデル（LLM）が対応するタスクです。

# 目次
* 事前準備
  * IBM Cloud側の準備
  * 必須SDKライブラリのインストール
  * クチコミデータの準備
* コードの実行
  * パラメーターの設定
  * プロンプティング
* 感想
* まとめ

# 事前準備
必要な事前準備は以下となります。

### 1. IBM Cloud側の準備
・API接続用URLの取得
・API Keyの取得
・Project IDの取得

### 2. 必須SDKライブラリのインストール
pipを使用して、SDKライブラリのインストールを行います。
```
$ pip install ibm-watson-machine-learning
```

### 3. クチコミデータの準備
肯定的、否定的、中性的3種類のデータを25個準備しました。
データは宿泊施設のクチコミによく出る言葉とトピックを想像して作成しました。
```
ID	Answer	Input
1	0	期待通りでした。
2	1	朝食が美味しかったです。
3	-1	また利用したいと思わない。
4	0	家族旅行です。
5	1	部屋が清潔でよかった。
6	-1	部屋が狭かった。
7	0	泊まる分には問題ありません。
8	1	価格が安く、お得でした。
9	-1	残念でした。
10	0	お世話になりました。
11	1	リラックスできました。
12	-1	宿泊料がやや高いと思います。
13	0	記念日に利用しました。
14	1	心地よいです。
15	-1	周辺の音が気になって眠れませんでした。
16	0	朝食は普通でした。
17	1	快適でした。
18	-1	冷房が効かない。
19	0	ありがとうございました。
20	1	満足です。
21	-1	二度と行きません。
22	0	初めての利用です。
23	1	おすすめです。
24	-1	お勧めしません。
25	0	朝食はバイキングだった。
```

# コードの実行

今回はプロンプトラボ上ではなく、pythonから使用します。
Pythonスクリプトの作成は以下のリンクを参考して作成しました。
https://ibm.github.io/watson-machine-learning-sdk/foundation_models.html

## パラメーターの設定
```diff_python
from ibm_watson_machine_learning.metanames import GenTextParamsMetaNames as GenParams
from ibm_watson_machine_learning.foundation_models.utils.enums import DecodingMethods
from ibm_watson_machine_learning.foundation_models import Model
from ibm_watson_machine_learning.foundation_models.utils.enums import ModelTypes

parameters = {
    GenParams.DECODING_METHOD: "sample",
    GenParams.MAX_NEW_TOKENS: 2, 
    GenParams.MIN_NEW_TOKENS: 1,
    GenParams.TEMPERATURE: 0.05,
    GenParams.TOP_K: 5,
    GenParams.TOP_P: 0.6,
    GenParams.REPETITION_PENALTY: 1.1, 
    GenParams.STOP_SEQUENCES: ["/n"]
}

model_id = ModelTypes.LLAMA_2_70B_CHAT
```

## プロンプティング
今回はプロンプティングをメインの手段として、感情分析の精度向上を目的に色々試してみました。
### 1回目の試し
まずはzero shotで実行してみます。
```diff_python
    prompt = """\
    

    あなたは高度な学習能力を持つ自然言語処理の研究者としてプログラムされています。
    以下の例を用いて、クチコミから宿泊施設への感情極性を判断してください。肯定的は「1」を、否定的は「-1」を、あるいは「0」を出力してください。

    [出力の形式]
    1 or -1 or 0
    
    クチコミ
    {input}
    
    出力
    """
```
出力結果
```
期待通りでした。
出力: 1
==========
朝食が美味しかったです。
出力: 1
==========
また利用したいと思わない。
出力: この
==========
家族旅行です。
出力: 1
==========
部屋が清潔でよかった。
出力: 1
==========
部屋が狭かった。
出力: 1
==========
泊まる分には問題ありません。
出力: 1
==========
価格が安く、お得でした。
出力: 1
==========
残念でした。
出力: 
==========
お世話になりました。
出力: こん
==========
リラックスできました。
出力: 1
==========
宿泊料がやや高いと思います。
出力: 1
==========
記念日に利用しました。
出力: 新
==========
心地よいです。
出力: この
==========
周辺の音が気になって眠れませんでした。
出力: 
==========
朝食は普通でした。
出力: 1
==========
快適でした。
出力: 非常
==========
冷房が効かない。
出力: 1
==========
ありがとうございました。
出力: こん
==========
満足です。
出力: 不
==========
二度と行きません。
出力: 一度
==========
初めての利用です。
出力: この
==========
おすすめです。
出力: この
==========
お勧めしません。
出力: この
==========
朝食はバイキングだった。
出力: 1
==========
```
zero shotだとすべて指定した出力の形式通りで出力してくれないんですね。
### 2回目の試し
zero shotからfew shot学習へ進化したらどれぐらい精度があがるんでしょうか？
それでは、例を与えてみましょう。今回はランダムに例を与えてみました。
```diff_python
    prompt = """\
    

    あなたは高度な学習能力を持つ自然言語処理の研究者としてプログラムされています。
    以下の例を用いて、クチコミから宿泊施設への感情極性を判断してください。肯定的は「1」を、否定的は「-1」を、あるいは「0」を出力してください。

    [出力の形式]
    1 or -1 or 0

    クチコミ
    従業員の接客が丁寧でした。
    
    出力
    1
    
    
    クチコミ
    スタッフの態度が悪かった。
    
    出力
    -1
    

    クチコミ
    家族旅行です。
    
    出力
    0

    
    クチコミ
    {input}
    
    出力
    """
```
few shot学習による1回目の結果
```
期待通りでした。
出力: 1
==========
朝食が美味しかったです。
出力: 1
==========
また利用したいと思わない
出力: 0
==========
家族旅行です。
出力: 0
==========
部屋が清潔でよかった。
出力: 1
==========
部屋が狭かった
出力: 0
==========
泊まる分には問題ありません。
出力: 0
==========
価格が安く、お得でした。
出力: 1
==========
残念でした。
出力: 0
==========
お世話になりました。
出力: 1
==========
リラックスできました。
出力: 1
==========
宿泊料がやや高いと思います。
出力: 0
==========
記念日に利用しました。
出力: 1
==========
心地よいです。
出力: 1
==========
周辺の音が気になって眠れませんでした。
出力: 0
==========
朝食は普通でした。
出力: 0
==========
快適でした。
出力: 1
==========
冷房が効かない
出力: 0
==========
ありがとうございました。
出力: 1
==========
満足です。
出力: 1
==========
二度と行きません。
出力: -1
==========
初めての利用です。
出力: 0
==========
おすすめです。
出力: 1
==========
お勧めしません。
出力: 0
==========
朝食はバイキングだった
出力: 1
==========
```
それぞれの感情極性の例を与えてみたら、精度が一気に上がりました！
出力結果を見てみますと、今回25件の中で肯定的なデータは８件準備したことに対して、肯定的な感情判断は１００％正解でした。一方、中性的と否定的な例の判定はまだまだ改善の余地がありますね。
### 3回目の試し
学習させる例を修正してみました。
```diff_python
    prompt = """\
    

    あなたは高度な学習能力を持つ自然言語処理の研究者としてプログラムされています。
    以下の例を用いて、クチコミから宿泊施設への感情極性を判断してください。肯定的は「1」を、否定的は「-1」を、あるいは「0」を出力してください。

    [出力の形式]
    1 or -1 or 0

    クチコミ
    従業員の接客が丁寧でした。
    
    出力
    1
    

    クチコミ
    普通以下でした。
    
    出力
    -1
    

    クチコミ
    家族旅行です。
    
    出力
    0


    クチコミ
    {input}
    
    出力
    """
```
few shot学習による2回目の結果
```
期待通りでした。
出力: 1
==========
朝食が美味しかったです。
出力: 1
==========
また利用したいと思わない
出力: -1
==========
家族旅行です。
出力: 0
==========
部屋が清潔でよかった。
出力: 1
==========
部屋が狭かった
出力: -1
==========
泊まる分には問題ありません。
出力: 1
==========
価格が安く、お得でした。
出力: 1
==========
残念でした。
出力: 0
==========
お世話になりました。
出力: 1
==========
リラックスできました。
出力: 1
==========
宿泊料がやや高いと思います。
出力: 0
==========
記念日に利用しました。
出力: 1
==========
心地よいです。
出力: 1
==========
周辺の音が気になって眠れませんでした。
出力: -1
==========
朝食は普通でした。
出力: 0
==========
快適でした。
出力: 1
==========
冷房が効かない
出力: -1
==========
ありがとうございました。
出力: 1
==========
満足です。
出力: 1
==========
二度と行きません。
出力: -1
==========
初めての利用です。
出力: 0
==========
おすすめです。
出力: 1
==========
お勧めしません。
出力: -1
==========
朝食はバイキングだった
出力: 1
==========
```
例を変えてみると・・・精度がさらに上がりました！
否定的なクチコミの例を「スタッフの態度が悪かった。」から「普通以下でした。」へ変更すると精度が上がる理由は何でしょうかね。
推測ですが、例の内容によって生成AIによる感情極性の「否定的な」判断基準が変わるではないかと思いました。プロンプティングには自然言語への高度な理解が必要ではないかと考えました。

# 感想
今回メインの感想として、感情極性の判断の難しさを実感しました。人によって理解する感情も少し主観的な部分もあると思います。
```
期待通りでした。
出力: 1
```
上記を一例として、3回目の試しで出力結果を分析する時、私は「期待通り」という言葉が中性的と肯定的両方とも解釈できるではないかと考えました。そのため、感情「極性」とはいえ、明確の基準と文脈がない限り直接な判断は難しいと思いました。

その一方、今回は100%の精度の実現が難しかったが、今回初心者としてプロンプティングにかけた時間はわずか2時間ほどです。プロンプティングに工夫したら、短時間で精度を上がることが可能と感じました。生成AIによる感情分析は機械学習より、必要な事前準備が少なく、専門的な知識がなくても簡単に試せるメリットを感じました。データサイエンティストに限らず、一般のユーザー（特にマーケティング関連の方々）でも気軽に基盤モデルを使って製品やサービスに対する顧客の感情を分析できることが魅力ですね。

# まとめ
本記事では、基盤モデルによるクチコミの感情分析を試してみました。また、今回はプロンプティングをメインの手段として、感情分析の精度向上を目的に色々試してみました。

本記事は以上です。ありがとうございました！