[アニメアナリティクス開発日記]TwitterフォロワーデータをOpenAI APIに分析させレポートしてもらう方法とプロンプトチューニングについて
アニメアナリティクスという現在放送されているアニメの公式Twitterフォロワー数のランキングや増減ランキングが見れるサイトをChatGPT先生と一緒につくっています。(というかほぼ先生に書いてもらっています)
そのサイトのひとつの機能として1週間の約60アニメ作品のフォロワー数の変化を分析して文章でレポートしてもらう機能を実装しています。
https://sana-web0.vercel.app/ranking-diff
アニメAIアナリストレポートの仕組み
データの元となるCSVを用意 アニメ作品60作品と1週間のフォロワー数の変化が記載されているCSVを準備
OpenAI API gpt-3.5-turboをNode.jsで呼び出し(GitHub Action経由)
生成されたレポートをmainにコミット (mainにコミットされるとvercelに自動的にデプロイされる)
読み込むCSV
,2023-05-21 00:00:00,2023-05-22 00:00:00,2023-05-23 00:00:00,2023-05-24 00:00:00,2023-05-25 00:00:00,2023-05-26 00:00:00,2023-05-27 00:00:00,2023-05-28 00:00:00
ARMORED SAURUS アーマードサウルス,0,0,2,0,1,0,-1,2
アイドルマスター シンデレラガールズ U149,0,49,49,39,86,86,56,41
青のオーケストラ,0,108,56,38,33,44,64,48
アリス・ギア・アイギス Expansion,0,5,-5,17,-3,13,11,-17
あんさんぶるスターズ!!追憶セレクション「エレメント」,0,-17,-3,-3,-9,-22,-4,-8
異世界召喚は二度目です,0,76,5,21,21,18,-1,-4
異世界でチート能力を手にした俺は、現実世界をも無双する ~レベルアップは人生を変えた~,0,75,30,104,19,25,92,45
異世界はスマートフォンとともに。第2期,0,3,9,-5,8,-7,13,-17
異世界ワンターンキル姉さん ~姉同伴の異世界生活はじめました~,0,6,6,8,11,1,6,2
ウマ娘 プリティーダービー Road to the Top,0,-172,-185,-107,-114,-195,-21,-325
ULTRAMAN FINALシーズン,0,117,31,6,20,37,17,-19
EDENS ZERO 第2期,0,102,5,10,1,4,13,-34
江戸前エルフ,0,69,35,79,107,-8,135,392
〜以下略
OpenAI APIの呼び出し部分 (report_poc.js)
require('dotenv').config();
const { Configuration, OpenAIApi } = require("openai");
const fs = require('fs');
// ファイルを読み込んでデータを整形する関数
function createData() {
const fs = require('fs');
const path = './public/data.csv';
const data = fs.readFileSync(path, 'utf8');
const preheader = fs.readFileSync('./gpt/prompt1.txt', 'utf8');
return preheader + data;
}
const data = createData();
const configuration = new Configuration({
apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);
(async () => {
const completion = await openai.createChatCompletion({
model: "gpt-3.5-turbo",
messages: [{ role: "user", content: data }],
});
console.log(completion.data.choices[0].message);
saveData(completion.data.choices[0].message.content);
})();
// 引数の文字列をファイルに保存する関数
function saveData(data) {
const path = `./public/report/report.json`;
// report: data、date : date の構造のJSONを生成
const reportData = {
report: data,
date: getJSTDateString(),
};
// JSONをpathにファイル保存
fs.writeFile(path, JSON.stringify(reportData, null, 2), (err) => {
if (err) {
console.error(err);
return;
}
console.log(`Report has been saved successfully to ${path}`);
});
}
function getJSTDateString() {
const date = new Date();
// 日本時間の日付・時刻を取得
const dateFormatter = new Intl.DateTimeFormat('ja-JP', {
timeZone: 'Asia/Tokyo',
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
});
const dateParts = dateFormatter.formatToParts(date);
const formatDate = `${dateParts[0].value}/${dateParts[2].value}/${dateParts[4].value} ${dateParts[6].value}:${dateParts[8].value}:${dateParts[10].value}`;
return formatDate;
}
プロンプトテキスト
# 命令書:
あなたはプロのデータアナリストです。
以下の制約条件と入力文をもとに分析レポートを出力してください。
# 制約条件:
入力文は現在日本で放映されているTVアニメ作品のタイトルと、
その作品のTwitterアカウントのフォロワー数の増減データが日付ごとにCSV形式で記録されています。
Twitterフォロワーの増減数を作品の人気の指標と捉え、
与えられたデータから読み取れることをデータレポートとして文章として500文字以内で記述してください。
レポートに日付を記載する場合は曜日の記載もお願いします(日付は日本時間の日付です)
ただし最初の日付は全作品0のため評価として無視してください。
またデータは累計フォロワー数でなく日付増加差分のフォロワー数ということに注意してください。
# 入力文:
実行結果
$:node ./gpt/report_poc.js
{
role: 'assistant',
content: '【TVアニメ作品の人気指標についての分析レポート】\n' +
'\n' +
'2023年5月21日から28日までのフォロワー数の増減データをもとに、現在日本で放映されているTVアニメ作品の人気指標を分析しました。\n' +
'\n' +
'【アニメ作品の人気指標】\n' +
'フォロワー数の増減数\n' +
'\n' +
'【トップ3人気アニメ】\n' +
'1位:推しの子\n' +
'2位:江戸前エルフ\n' +
'3位:鬼滅の刃 刀鍛冶の里編\n' +
'\n' +
'推しの子は、5月23日に急激なフォロワー数の増加があり、その後も調子が良く、最終的には5月28日には7,814に達しました。江戸前エルフも、5月24日にフォロワー数の急激な増加があり、最終的には5月28日に392に到達しました。鬼滅の刃 刀鍛冶の里編は、5月21日から5月25日までの間、一気にフォロワー数を伸ばし、最終的に5月28日には97に到達しました。\n' +
'\n' +
'【注目アニメ作品】\n' +
'青のオーケストラ\n' +
'5月21日から5月26日までの間、フォロワー数の増加が続いていた青のオーケストラですが、5月27日にフォロワー数が減少し、最終的には48で終えました。\n' +
'\n' +
'ULTRAMAN FINALシーズン\n' +
'5月21日から5月24日まではフォロワー数の増加が続いていましたが、5月25日に途中で方向転換し、最終的には-19に終わりました。\n' +
'\n' +
'ポケットモンスター(新シリーズ)\n' +
'5月28日までの間、一気にフォロワー数を伸ばしたポケットモンスター。5月24日から5月27日までの間、フォロワー数が急激に増加しましたが、5月28日にフォロワー数が最大の6,863に到達しました。\n' +
'\n' +
'【総括】\n' +
'多くのアニメ作品がフォロワー数の増加を続けていますが、中でも推しの子、江戸前エルフ、鬼滅の刃 刀鍛冶の里編が特に人気を集めているようです。しかし、人気が高い作品でも急なフォロワー数の減少が発生したり、一気に増えたりするといった傾向が見られます。また、ポケットモンスターのように予測できないフォロワー数の増加があった作品もあります。今後もフォロワー数の変動に注目して、各作品の人気指標を把握していきたいと思います。'
}
Report has been saved successfully to ./public/report/report.json
1位が「推しの子」なのは常識ですが、まっとうな分析を返してくれています。ただしここに来るまでかなり格闘しました。
OpenAI APIにデータ分析させるときにつまったところ
トークンオーバー
gpt-3.5-turbo APIでは1リクエストにおけるトークンが4096までしか使えません(トークン=文字数などのデータのようなもの)
今回のようなデータ分析をして貰う場合、データそのものが量が多いとトークンエラーで弾かれます。参考資料(https://platform.openai.com/docs/models/gpt-4)
ただ4096文字を超えたらエラーになるかというとそういうわけでもなく一定のルールがあるようで、投げかけるデータがいくらのトークンを使うかは下記サイトで調べることができます
元々はリクエストにおくるデータはCSVでなくWEB側アプリケーション側でつかっている下記のようなJSONをなげつけていました
],
"アイドルマスター シンデレラガールズ U149": [
{
"date": "2023-05-21 00:00:00",
"count": 36003
},
{
"date": "2023-05-22 00:00:00",
"count": 36052
},
{
"date": "2023-05-23 00:00:00",
"count": 36101
},
{
"date": "2023-05-24 00:00:00",
"count": 36140
},
{
"date": "2023-05-25 00:00:00",
"count": 36226
},
{
"date": "2023-05-26 00:00:00",
"count": 36312
},
{
"date": "2023-05-27 00:00:00",
"count": 36368
},
{
"date": "2023-05-28 00:00:00",
"count": 36409
}
],
"青のオーケストラ": [
{
"date": "2023-05-21 00:00:00",
"count": 20726
},
これが60作品続くのですぐトークンオーバーになってエラーになったため、CSV形式へ変換することとしました。OpenAI APIにデータを投げるときはデータをなるべくコンパクトにする必要があります。
累計データを渡すと「推しの子」を無視してウマ娘!鬼滅の刃!のみ連呼するマンになってしまう
元々はOpenAI APIにわたすCSVはTwitterフォロワー数の累計データを渡してプロントには「日付のフォロワー数の増減をレポートしてね!」と指示していました
,2023-04-26 00:00:00,2023-04-27 00:00:00,2023-04-28 00:00:00,2023-04-29 00:00:00,2023-04-30 00:00:00,2023-05-01 00:00:00,2023-05-02 00:00:00,2023-05-03 00:00:00
ARMORED SAURUS アーマードサウルス,310,315,317,319,319,317,318,321
アイドルマスター シンデレラガールズ U149,33023,33145,33396,33504,33604,33692,33758,33812
青のオーケストラ,18396,18528,18679,18770,18887,19085,19189,19269
アリス・ギア・アイギス Expansion,21865,21859,21852,21851,21863,21857,21861,21864
あんさんぶるスターズ!!追憶セレクション「エレメント」,53513,53576,53591,53615,53613,53619,53604,53600
異世界召喚は二度目です,12781,12787,12841,12859,12878,13053,13044,13084
異世界でチート能力を手にした俺は、現実世界をも無双する ~レベルアップは人生を変えた~,39957,40066,40157,40245,40346,40437,40548,40613
異世界はスマートフォンとともに。第2期,36146,36153,36153,36155,36150,36156,36170,36177
異世界ワンターンキル姉さん ~姉同伴の異世界生活はじめました~,5708,5731,5746,5773,5796,5809,5820,5841
ウマ娘 プリティーダービー Road to the Top,1518957,1518889,1518973,1519073,1519042,1519363,1519475,1519544
プロンプト
OpenAI APIの結果
だいたい毎日こんな感じの少しズレた回答を返していました。Twitterのフォロワー数の増加は「推しの子」が圧倒的に1位であるのにもかかわらずこの回答をするのはおそらくTwitterフォロワー数の現在値のデータを見ているためそこに引きずられて、現在のフォロワー数が圧倒的に多い「鬼滅」や「ウマ娘」を中心にレポートしてしまっているようです。いくらプロンプトに「差分だけみろやゴルァ」といってもその傾向はかわりませんでした。
そのためOpenAI APIにわたすCSVそのものを、フォロワー数の増減数を計算しおわった表に直して渡すこととしました。
別のアプローチとしてはOpenAI APIにリクエストを2回渡す形式にし、1回目で差分表を作成させて2回目でその表を評価させるアプローチもありますがAPIのコストはかかるためトレードオフとなります。今回は料金がかからず自前で差分ファイルは作成できるためそのアプローチはとりませんでした。API課金こわいですし。
レポート文字数を指定しないと返答文字が途中できれるまで頑張ってしまう
CSVは差分形式としプロンプトの深津式も導入しプロンプトを修正しました
ーーー
{
role: 'assistant',
content: '以下は、各作品の日ごとのTwitterフォロワーの増減数を示したものです。\n' +
'各作品について、増加数が多かった日付を抽出し、その日付の曜日とともに報告しています。\n' +
'\n' +
'・ARMORED SAURUS アーマードサウルス\n' +
'増加数が多かった日付はありません。\n' +
'\n' +
'・アイドルマスター シンデレラガールズ U149\n' +
'2023年5月23日(月)に49人のフォロワーが増加しました。\n' +
'\n' +
'・青のオーケストラ\n' +
'2023年5月21日(土)に108人のフォロワーが増加しました。\n' +
'\n' +
'・アリス・ギア・アイギス Expansion\n' +
'2023年5月24日(火)に17人のフォロワーが増加しました。\n' +
'・君は放課後インソムニア\n' +
'2023年5月23日(月)に163人のフォロワーが増加しました。\n' +
'\n' +
'・鬼滅の刃 刀鍛冶の里編\n' +
'2023年5月21日(土)に1297人のフォロワーが増加しました。\n' +
〜〜途中略〜〜〜
が増加しました。\n' +
'\n' +
'・TIGER & BUNNY 2\n' +
'増加数が多かった日付はありません。\n' +
'\n' +
'・ちびゴジラの逆襲\n' +
'2023年5月21日(土)に76人のフォロワーが増加しました。\n' +
'\n' +
'・デッドマウント・デスプレイ\n' +
'2023年5月22日(日)に60人のフォロ'
}
全部の作品を計算してその結果を返そうとしており意図としたレポートを返してくれませんでした。しかも計算かけてるのでAPIの返答にめちゃくちゃ時間かかります。
最終的なプロンプト
最初に紹介したとおり、とりあえずこれでそれっぽい返答をかえしてくれるようになりました。
一番ナイスだったレポート
TV放映日の件はプロンプトに投入していないのにもかかわらず、TVアニメ放送日あとにフォロワー数が伸びることを理解しています。これはなかなかいいレポートだと思います。
結論
場合によってはまだ「推しの子」を無視したレポートを返してきたりするのでチューニングは必要そうですがとりあえず進展できました。同じような感じで株価データのレポートや天気予報などもOpenAI APIでレポートできるのではと思います。結果をずんだもんとかに喋らせても面白いかもしれません。
この記事が気に入ったらサポートをしてみませんか?