GPTsのデータ集計能力を検証してみる

GPTsに生データを取得できるAPIを呼び出させてその結果を集計し、回答をする仕組みを構築しようとしたところ、集計結果が不正確であることがあった。

そこで、今回はAPIから返されるデータ量が多いと集計結果の不正確さが増すのではないか、という推論を元に検証した結果を共有しようと思います。

# そもそも何をやろうとしていたのか

とある、Webサービスにおいてユーザーの行動分析データを収集しており、そのデータに基づいて回答をするGPTsを作成したかった。

データは下記のように定義されている（GPTsに設定したAPI定義）
```json
{
  "openapi": "3.1.0",
  "info": {
    "title": "行動データ取得",
    "description": "記録された生の行動データを取得する",
    "version": "v1.0.0"
  },
  "servers": [
    {
      "url": "https://xxx"
    }
  ],
  "paths": {
    "/api/action": {
      "get": {
        "description": "記録された生の行動データを取得する",
        "operationId": "GetData",
        "parameters": [
          {
            "name": "start_date",
            "in": "query",
            "description": "取得データの日付範囲の始端です",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example":"2024-04-20"
          },
          {
            "name": "end_date",
            "in": "query",
            "description": "取得データの日付範囲の終端です",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example":"2024-04-25"
          }
        ],
        "deprecated": false,
        "responses": {
          "200": {
            "description": "取得した行動データ",
            "content": {
              "application/json": {                
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "description": "セッションデータ。この要素の数がセッション数になる",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "example": "895eec5a-70e7-4e04-92ba-8f1c2250fe4e",
                            "description": "セッションを一意に区別するためのID"
                          },
                          "timestamp": {
                            "type": "string",
                            "example": "2024-04-17 17:42:17",
                            "description": "セッションが発生した日時になります"
                          },
                          "ua": {
                            "type": "string",
                            "example": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/21D61 Instagram 321.0.2.24.105 (iPhone16,2; iOS 17_3_1; ja_JP; ja; scale=3.00; 1290x2796; 572181444) NW/3",
                            "description": "そのセッションが発生した端末のユーザーエージェント情報を保存しています"
                          },
                          "isCTA": {
                            "type": "boolean",
                            "example": "true",
                            "description": "そのセッションにおいてCTA（Call To Action）が実行されたかどうかを示しています"
                          },
                          "CTADatetime": {
                            "type": "string",
                            "example": "2024-03-12 6:55:30",
                            "description": "CTAが実行された日時になります"
                          },
                          "isCV": {
                            "type": "boolean",
                            "example": "true",
                            "description": "そのセッションでコンバージョンがあったかどうかを示すデータです"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
```

# ところが

実際にGPTsに下記のような質問をしてみる
```
2024/4/24のセッション数、CTAクリック数、CV数を教えてください
```
ところが、結果を見てみるとセッション数、CTAクリック数、CV数が実際の集計結果と異なる結果になっている。
また、一度リロードしてから同じ質問をすると別の不正確な結果を返してくる。

APIが返す結果自体はPostmanで確認済みなので、GPTsの集計する結果に問題がありそう・・・

# データ数を調整しながら検証

先ほど検証した2024/4/24は100を超えるセッションが記録されていたので、データの数を少ないところから始めてどれくらいでデータが不正確になるかを検証することにした

## 検証用のAPI
```python
import json
import os


def lambda_handler(event, context):
    # 環境変数から作成するセッション数を取得
    session_num = int(os.environ['SESSION_NUM'])

    # セッション数分のデータを作成
    session_items = []

    for i in range(session_num):
        session_items.append({
            "id": i,
            "timestamp": '2021-01-01T00:00:00.000Z',
            "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3",
            "isCTA": i % 2 == 0,
            "CTADatetime": i % 2 == 0 and '2021-01-01T00:00:00.000Z' or None,
            "isCV": i % 3 == 0,
        })

    # JSON レスポンス
    return {
        'statusCode': 200,
        'headers': {
            'Content-Type': 'application/json',
            'Access-Control-Allow-Origin': '*'
        },
        'body': json.dumps(session_items)
    }

```
検証用に上記のコードを作成し、APIGateway+Lambdaでデプロイをした。
これで環境変数SESSION_NUMを変更すれば返却されるデータの件数を自由に操作することができる。

## 検証開始

|SESSION_NUM  |セッション数  |CTAクリック数  |CV数
|---|---|---|---|
|3|3|2|1  
|6|6|3|2
|9|9|<font color="red">4</font>|<font color="red">2</font>
|12|12|<font color="red">5</font>|<font color="red">3</font>
|15|<font color="red">10</font>|<font color="red">5</font>|<font color="red">3</font>
|20|<font color="red">10</font>|<font color="red">5</font>|<font color="red">3</font>
|50|<font color="red">16</font>|<font color="red">8</font>|<font color="red">4</font>
|100|<font color="red">10</font>|<font color="red">5</font>|<font color="red">3</font>


セッション数を9にしたところで早くもデータがおかしくなり、15の時には全ての指標でデータが正しく取得できないことがわかった

# まとめ
やはりデータ量が多いと集計結果が不正確になることがわかった

このことからも生データを直接渡して集計・分析をしてもらうような方法はGPTsでは難しそうなので、ファインチューニングで同じデータを渡した時にはどうかを次回以降で検証したい