こんにちは、タクトシステムマーケティングチームです。
ウェブサイトのアクセス解析に使用するGoogleアナリティクスが、UA(ユニバーサル アナリティクス)からGA4(Googleアナリティクス4)に世代交代しようとしています。GA4はUAに比べてUIも概念も大きく異なりますが、それだけにどんな使い方ができるかについていろいろ模索していきたいところです。
というわけで、今回はGA4とChatGPTでアクセス解析を自動化するという実験をしてみました。

ユニバーサルアナリティクス(UA)の画面

Googleアナリティクス4(GA4)の画面
GA4アクセス解析の手法
GA4を活用したアクセス解析の手法はさまざまです。基本的にはUA同様 レポート でデータを確認できるのですが、レポート以外での解析手法も存在します。
GA4アクセス解析の手法1:データ探索ツール
GA4管理画面メニューにある データ探索ツール はディメンションと指標を自身で指定して数値を確認することが可能です。
GA4アクセス解析の手法2:Looker Studio
Googleが提供する無料BIツールの Looker Studio (旧データポータル)は、GA4のデータをデータソースとして読み込ませてグラフや表を作成することが可能です。こちらもディメンションと指標を自身で指定できますが、データ探索ツールよりも汎用性のあるレポートを作成できるのが特徴です。
GA4アクセス解析の手法3:AnalyticsData API
AnalyticsData API は開発者向けのツールで、プログラム言語を活用してGA4のレポートデータにアクセスすることが可能です。プログラミングの知識が必要となりますが、その分自由度の高いデータ取得が可能です。
ChatGPTでアクセス解析
GA4でのアクセス解析は、上記のデータ探索ツールやLooker Studioといった手法でグラフや表を作成してデータを視覚的に把握することが一般的です。ここでは、ChatGPTでGA4で取得したデータをアクセス解析してもらうやり方を考えてみました。ポイントはプロンプトとデータのリクエスト方法にありそうです。
プロンプトエンジニアリング
ChatGPTのプロンプト(入力テキスト)については DAIR(Democratizing Artificial Intelligence Research)という非営利のAI研究所が作成した解説ガイド、 Prompt Engineering Guide がとても参考になります。GPT-4を活用した 法人GAI や 行政GAI を手掛けるギブリー新田章太氏による 日本語訳 も公式にリンクがあります。こちらの解説ガイドを参考にプロンプトを考えます。
アクセス解析のプロンプト
Prompt Engineering Guideを参考にしてアクセス解析をするためのプロンプトフォーマットを作成してみました。役割(role)を与えて命令文と入力データを明確にしたプロンプトでChatGPTに問い合わせます。
# 役割
あなたは有能なウェブアナリストで、かつデータ分析のスペシャリストです。
# 命令文
以下のデータはGoogleアナリティクス4で取得した、ウェブサイト 'example.com' の{ディメンション}および{指標}をあらわす[先月]と[今月]のCSVデータです。2つのデータを比較した解析結果を教えてください。
# 入力データ:[先月]
(ここにCSVデータを貼る)
# 入力データ:[今月]
(ここにCSVデータを貼る)
GA4からCSVを書き出し
GA4のデータ探索ツールでアクセス解析用のデータをCSVで書き出します。
変数およびタブの設定は例として以下のようにしました。
| 手法 | 自由形式 |
| ビジュアリゼーション | テーブル |
| ディメンション(行) | ランディング ページ + クエリ文字列 |
| セッションのデフォルト チャネル グループ | |
| 指標(値) | 表示回数 |
| セッションあたりの平均エンゲージメント時間 | |
| コンバージョン |
ChatGPT(法人GAI)に問いかけてみる
まず、プロンプトフォーマットに変数(ディメンション/指標/先月/今月)を指定します。次に、GA4のデータ探索ツールから書き出したCSVをテキストとして貼ってプロンプトを作成します。今回は法人GAIに聞いてみました。
問いかけてみると少し考えた後に回答が出力されます。
なかなか詳しい回答ですがよく読んでみると「ありきたり」な解析結果です。データの概要を把握することはできますが、もう少し詳しい解析結果を導き出せるようにしたいのでプロンプトを工夫してみます。
例えば…
- KPIに対して進捗を報告してください。
- コンバージョン数が多かったページ順に比較してください。
など。
プロンプトを修正してChatGPTに問いかけてみる
プロンプトに条件を付与してChatGPTに再度問い合わせてみました。
出力された回答がこちらです。
プロンプトを変更したことによって解析結果の解像度が上がりました!
ディメンションや指標ごとに解析してほしい内容は変わるのでプロンプトの調整は必要です。
AnalyticsData API と OpenAI API で自動化
GA4のデータ探索からCSVを書き出してChatGPTに貼り付けるのもちょっと面倒なので、この作業を AnalyticsData API と OpenAI API で自動化してみました。言語は GoogleAppsScript です。流れとしては以下の通りです。
①定数の設定とメインファンクション
②GoogleAppsScriptでGA4のデータを取得
③ChatGPT APIにリクエストを送信
④返された回答をメールの文面として送信
コードを全部まとめると長くなってしまうので、①〜④の流れごとに解説します。最終的にはすべてのコードをGoogleAppsScriptのエディタに貼って main()ファンクション を実行してください。
①定数の設定とメインファンクション
const openAiApiKey = '<OPENAI_API_KEY>'; // OpneAI API Key
const ga4PropertyId = '<GA4_PROPERTY_ID>'; //GA4 プロパティID
const siteDomain = 'example.com'; // ウェブサイトドメイン名
const dimensionsString = 'ランディング ページ, セッションのデフォルト チャネル グループ'; // ディメンションの日本語名
const dimensionNameArray = ['landingPage','sessionDefaultChannelGroup']; // ディメンション名の配列
const metricsString = '表示回数, 平均セッション継続時間, コンバージョン'; // 指標の日本語名
const metricNameArray = ['screenPageViews','averageSessionDuration','conversions']; // 指標名の配列
function main(){
// 現在の日付を取得
var now = new Date();
// 前々月
var firstDayA = getDateYYYYMMDD(now, 2, 1); // 前々月の1日
var lastDayA = getDateYYYYMMDD(now, 1, 0); // 前々月の月末
var monthA = getDateYYYY_MM_(firstDayA); //YYYY月MM月
var dataStringA = getReportGA4(monthA, firstDayA, lastDayA, 1); // 前々月レポートのデータを取得
// 前月
var firstDayB = getDateYYYYMMDD(now, 1, 1); // 前月の1日
var lastDayB = getDateYYYYMMDD(now, 0, 0); // 前月の月末
var monthB = getDateYYYY_MM_(firstDayB); //YYYY月MM月
var dataStringB = getReportGA4(monthB, firstDayB, lastDayB, 2); // 前月レポートのデータを取得
// OpenAI APIに渡す
var answer = getChatResponse(monthA, monthB, dataStringA, dataStringB);
// メールにして送信
emailSpreadsheetAsXlsx(monthA, monthB, answer);
}
// 日付表記フォーマットの調整
// YYYY-MM-dd
function getDateYYYYMMDD(now, prev, d){
var theDay = new Date(now.getFullYear(), now.getMonth() - prev, d);
return Utilities.formatDate(theDay, 'JST', 'yyyy-MM-dd');
}
// YYYY年M月
function getDateYYYY_MM_(firstDay){
var dateParts = firstDay.split('-'); // ハイフンで文字列を分割
return dateParts[0] + '年' + dateParts[1] + '月';
}
定数(const)にはまずOpenAI APIのAPI KeyとGoogleアナリティクス4のプロパティIDを入力します。ウェブサイトドメイン名は必須ではないですがあるとわかりやすいと思います。ディメンションと指標は用途に応じて変更します。ディメンションと指標の日本語名はChatGPTにリクエストを送るために必要です。日付表記フォーマットの調整も関数でおこなっています。
②GoogleAppsScriptでGA4のデータを取得
// GA4から値を取得
function getReportGA4(month, firstDay, lastDay, sheetIndex) {
// 指標の配列を初期化
var metricArray = [];
// 配列をループ
for(i=0; i<metricNameArray.length; i++){
var metric = AnalyticsData.newMetric();
metric.name = metricNameArray[i];
metricArray.push(metric);
}
// ディメンションの配列を初期化
// 配列をループ
for(i=0; i<dimensionNameArray.length; i++){
var dimension = AnalyticsData.newDimension();
dimension.name = dimensionNameArray[i]
dimensionArray.push(dimension);
}
/*
// ディメンションフィルターを設定
const dimensionfilter = AnalyticsData.newFilterExpression();
dimensionfilter.orGroup = AnalyticsData.newFilterExpression();
dimensionfilter.orGroup.expressions = [];
const filterExpression = AnalyticsData.newFilterExpression();
filterExpression.filter = AnalyticsData.newFilter();
filterExpression.filter.fieldName = 'landingPage';
filterExpression.filter.stringFilter = AnalyticsData.newStringFilter();
filterExpression.filter.stringFilter.value = '/service/';
filterExpression.filter.stringFilter.matchType = 'BEGINS_WITH';
dimensionfilter.orGroup.expressions.push(filterExpression);
*/
// 期間を引数から設定
const dateRange = AnalyticsData.newDateRange();
dateRange.startDate = firstDay;
dateRange.endDate = lastDay;
// レポートをリクエストする
const request = AnalyticsData.newRunReportRequest();
request.dimensions = dimensionArray; // ディメンション
request.metrics = metricArray; // 指標
request.dateRanges = dateRange; // 期間
//request.dimensionFilter = dimensionfilter; // ディメンションフィルター
// レポートを作成する
const report = AnalyticsData.Properties.runReport(request, 'properties/' + ga4PropertyId);
// スプレッドシートを取得
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
// 対象のシート
var sheet = spreadsheet.getSheets()[sheetIndex - 1];
// シート名を設定
sheet.setName(month);
// ヘッダーを追加
const dimensionHeaders = report.dimensionHeaders.map(
(dimensionHeader) => {
return dimensionHeader.name;
});
const metricHeaders = report.metricHeaders.map(
(metricHeader) => {
return metricHeader.name;
});
const headers = [...dimensionHeaders, ...metricHeaders];
// シートの内容をクリア
sheet.getDataRange().clearContent();
// 1行目にヘッダーを挿入
sheet.appendRow(headers);
// レポートの結果を追加
const rows = report.rows.map((row) => {
const dimensionValues = row.dimensionValues.map(
(dimensionValue) => {
return dimensionValue.value;
});
const metricValues = row.metricValues.map(
(metricValues) => {
return metricValues.value;
});
return [...dimensionValues, ...metricValues];
});
sheet.getRange(2, 1, report.rows.length, headers.length).setValues(rows);
var headerCSV = headers.join(',');
var rowsCSV = rows.slice(0, 100).map(row => row.join(',')).join('\n');
return headerCSV + '\n' + rowsCSV;
}
こちらはAnalytics Data Serviceのサンプルコードをほぼ流用しています。GA4のデータを取得してGoogleスプレッドシートに展開していますので空のシートを2つ用意する必要があります。関数の戻り値はGA4のデータをカンマで区切った文字列として返します。
ディメンションフィルターの設定をコメントアウトしていますが、データ量が多い場合は必要に応じてフィルター設定をされるのがいいと思います。それでもトークンが多すぎてChatGPTが処理できない場合は92行目のスライス(slice)の引数を調整してみてください。
③ChatGPT APIにリクエストを送信
function getChatResponse(monthA, monthB, dataStringA, dataStringB){
var url = 'https://api.openai.com/v1/chat/completions';
const headers = {
'Content-type': 'application/json',
'Authorization': 'Bearer ' + openAiApiKey
}
var prompt = '# 命令文' + '\n' + '以下のデータはGoogleアナリティクス4で取得した、ウェブサイト \'' + siteDomain + '\' の{' + dimensionsString + '}および{' + metricsString + '}をあらわす' + monthA + 'と' + monthB + 'のCSVデータです。2つのデータを比較した解析結果を教えてください。' + '\n\n' + '#入力データ:' + monthA + '\n' + dataStringA + '\n\n' + '#入力データ:'+ monthB + '\n' + dataStringB
const data = {
'model': 'gpt-3.5-turbo',
'messages': [{'role': 'system', 'content': 'あなたは有能なウェブアナリストで、かつデータ分析のスペシャリストです。'},{'role': 'user', 'content': prompt}],
'temperature' : 0.3 // 多様性
}
const options = {
'muteHttpExceptions' : true,
'headers': headers,
'method': 'post',
'payload': JSON.stringify(data)
};
const response = JSON.parse(UrlFetchApp.fetch(url, options).getContentText());
if ('error' in response) {
var errorMessage = response.error.message;
var answer = 'Error: ' + errorMessage;
} else {
var answer = (response.choices[0].message.content).trim();
}
return answer;
}
こちらのブログ記事でご紹介したコードの流用です。APIのモデルを gpt-3.5-turbo にしていますが、 gpt-4 が使えるのであればそちらのほうがいいと思います。また、大量データをリクエストしたい場合は2023年6月13日にリリースされた gpt-3.5-turbo-16k を指定するのも手です。
④返された回答をメールの文面として送信
function emailSpreadsheetAsXlsx(monthA, monthB, mailContent) {
// 対象となるファイルとシート
var ss = SpreadsheetApp.getActiveSpreadsheet(); // アクティブなスプレッドシート
var fileName = ss.getName();
var fileId = ss.getId();
var sh = ss.getSheets()[0];
var sheetId = sh.getSheetId();
// ベース URL
var url = "https://docs.google.com/spreadsheets/d/" + fileId + "/";
// Excel 書き出しオプション
var url_ext = 'export?exportFormat=xlsx&format=xlsx'
// 送信メールアドレス
var emailto = 'mail@example.co.jp'
// 日付の形式を整える
var fileName = fileName + "_" + monthB;
// スプレッドシート名
var subject = siteDomain + ' ChatGPT サイト解析 ' + monthB;
// メールの本文
var body = 'ChatGPTによるアクセス解析レポートです。' + '\n\n' + 'ウェブサイト: ' + siteDomain + '\n' + '比較: ' + monthA + '/' + monthB + '\n' +'ディメンション: ' + dimensionsString + '\n' + '指標: ' + metricsString + '\n\n' + mailContent + '\n\n' + 'この Excel ファイルは Google SpreadSheet より自動作成しています。' + '\n' + url + 'edit#gid=' + sheetId;
try{
var fetchUrl = url + url_ext;
// ファイルをUrlFetchで要求
var fetchOption = {
"headers" : { Authorization: 'Bearer ' + ScriptApp.getOAuthToken() }, // OAuth
"muteHttpExceptions" : true
};
var fileName = fileName + ".xlsx";
var fileBlob = UrlFetchApp.fetch(fetchUrl,fetchOption).getBlob().setName(fileName);
// メール送信を実行
MailApp.sendEmail(emailto, subject, body, {
attachments : [fileBlob]
});
} catch(e){
Logger.log( "ファイル生成に失敗しました" );
}
}
こちらのブログ記事でご紹介したコードの流用です。メールを送信する際にGoogleスプレッドシートをExcelに変換して添付しています。トリガーを設定することで定期的な自動送信が可能となります。
Googleスプレッドシートのデータをもとにグラフを作成して、PDFとして添付することも可能です。

GA4のデータをOpenAI APIがアクセス解析して結果をメールで送信
まとめ
データをもとにChatGPTが解析をしてくれるといっても、ディメンションや指標が少ないと物足らない感があったりします。だからといっていろいろディメンションや指標を追加すると今度はトークンで制限されてしまうので、あまり大量のデータをリクエストするわけにもいきません。しかもトークンが多くなるということは、課金額も増加してしまう諸刃の剣でもあったりします。ですので、サイト全体の解析というより特定のページやディレクトリの推移を把握する方が向いていそうです。そして、解析で知りたいことの本質をプロンプトにうまく盛り込むことがポイントです。
なお、GA4に限らず自然検索(Search Console)やGoogle広告のデータもChatGPT APIで解析することが可能です。こちらについては別のお役立ち資料でご紹介しています。よろしければご覧になってください。
あわせて読みたい

【お役立ち資料】
Googleアナリティクス4とChatGPTでアクセス解析を自動化
まえがき/GA4アクセス解析の手法/ChatGPTでアクセス解析/AnalyticsData API と OpenAI API で自動化/ 限定記事 :Search Console と OpenAI APIで自動化/ 限定記事 :Google広告 と OpenAI APIで自動化/まとめ









