「0」と「データなし」は違う。AIにブログデータを誤分析させないために決めたルール

ブログやSNSの運営データを一か所へ集め、将来的にAIで分析する「全媒体データ分析基盤」を作っています。

WordPress、GA4、Google Search Console、Bing、YouTubeなどからPythonでデータを取得し、SQLiteへ保存するところまで進めてきました。

そこで気付いたのが、数字を集めるだけではAI分析の準備は終わらないということです。

例えば「0」という数字。本当に実績が0だったのか、データを取得できなかったのかでは意味がまったく違います。

今回は、AIへブログデータを渡す前に決めた「数字の意味を壊さないためのルール」を整理します。

目次

この記事で分かること

  • 0とNULLを区別する理由
  • FLOWとSNAPSHOTの違い
  • API取得値と計算値を分ける理由
  • resolved/unresolvedの考え方
  • AIによる誤分析を防ぐための分析ルール

0とNULLは同じではない

最初に決めたのが、0とNULLを明確に区別することです。

例えばSearch Consoleから正常にデータを取得し、クリック数が0だった場合は「対象期間にクリックされなかった」という観測結果です。

一方、APIの取得に失敗してクリック数が分からなかった場合、そこへ0を入れてしまうと意味が変わります。

今回の基盤では、

0=取得した結果、本当にゼロだった

NULL=不明・未取得・非提供など、値が存在しない

として扱います。

さらに「レコードそのものがない」状態も別です。そもそも取得処理をしていない可能性があるためです。

AIに「この動画は再生数0なので反応がありません」と分析されても、実際には動画自体を投稿していなかったのでは意味が違います。

分からないものを0で埋めない。

これはデータ分析基盤を作るうえで重要なルールになりました。

FLOWとSNAPSHOTを区別する

数字には性質の違いもあります。

今回の設計では、主にFLOWとSNAPSHOTを区別します。

FLOWは、一定期間に発生した量です。

例えば「9月1日のクリック数」「9月1日のセッション数」などが該当します。

一方、SNAPSHOTは、ある時点で観測した状態や累積値です。

YouTubeの累積再生数が、

9月1日時点:1,000回
9月2日時点:1,200回

だった場合、合計して2,200回とはしません。

分かるのは、2つの時点の差が200回だったということです。

累積値を日次実績と同じように扱えば、AIが誤った集計をする原因になります。

そのため、数字だけでなく「どのような性質の数字なのか」も保存するようにします。

APIが返した数字と計算した数字も分ける

もう一つ区別したいのが、API報告値とシステム側で計算した派生値です。

例えばSearch Consoleから、

表示回数:1,000
クリック数:50

を取得すれば、CTRは5%と計算できます。

ただし、この5%がAPIから直接取得した値なのか、自分のシステムで計算した値なのかは分けておいた方が安全です。

YouTubeでも、累積再生数が10,000回から10,500回へ増えた場合、差分500回は計算できます。

しかしこれは「YouTube APIがその期間の再生数を500回と報告した」という意味とは限りません。

観測された事実と、そこから計算した結果を混同しない。

AIがデータの根拠まで正しく判断するために必要な考え方です。

分からない紐付けはunresolvedのまま残す

複数媒体を統合すると、「この数字はどの記事のものなのか」という問題も発生します。

例えばGA4から取得したURLを記事マスタと照合し、記事Noまで特定できれば**resolved(解決済み)**です。

しかしURL変更やパラメータなどが原因で、自動的に記事を特定できないこともあります。

この場合は**unresolved(未解決)**として残します。

無理に「おそらくこの記事だろう」と結び付けません。

未解決データを保存しておけば、後からURL正規化やURL履歴などの仕組みを改善したとき、改めて紐付けられる可能性があります。

分からないものを、分かったことにしない。

0とNULLの区別にも通じる考え方です。

完了していない期間を比較しない

日付が付いていても、その期間が完成しているとは限りません。

例えば9月10日の昼に当日のGA4データを取得し、9月9日の1日分と比較して「アクセスが50%減った」と判断するのは適切ではありません。

9月10日はまだ途中だからです。

そこで分析時には、complete period(対象期間が完了しているか)も確認します。

また、APIから正常に取得できたからといって、その媒体側で数値が確定しているとも限りません。後から集計結果が更新されるサービスもあります。

そのため「対象期間」と「取得日時」も分けて記録しておく必要があります。

データの粒度が違えば単純に比較しない

ブログ分析では、記事単位、SNS投稿単位、日次、週次など、さまざまな粒度のデータを扱います。

ここにも落とし穴があります。

例えば一つの記事からSNS投稿を5件作り、その記事にGA4で100セッションがあったとします。

記事IDだけで両方を単純にJOINすると、100セッションが5投稿それぞれに付与され、合計500のように見える場合があります。

APIの数字は正しくても、データの結合方法によって数字が壊れるわけです。

そのため、まず同じ粒度で集計し、その後に比較する必要があります。

AIへ渡す前に「分析契約」を作る

こうした問題を整理した結果、SQLiteのデータをそのままAIへ渡すのではなく、分析契約を設けることにしました。

例えば、0とNULL、FLOWとSNAPSHOT、指標の単位、API報告値と派生値、resolved/unresolved、タイムゾーン、期間完成の有無、比較可能な粒度などです。

つまりAIに「自由に分析してください」と渡すのではなく、

「この数字は何を意味し、どの条件なら比較してよいのか」

まで一緒に定義します。

高性能なAIでも、入力データの意味が間違っていれば正しい分析はできません。むしろ自然な文章で、説得力のある誤分析を作ってしまう可能性があります。

まとめ

全媒体データ分析基盤を作り始めた当初は、多くの媒体から数字を自動取得することを重視していました。

しかし実際に統合してみると、重要なのは数字の量だけではありません。

0なのか不明なのか。
期間実績なのか累積値なのか。
APIが報告した値なのか計算値なのか。
記事との関係を確認できたのか。
比較できる期間・粒度なのか。

こうした意味を失わずに保存することが必要です。

AIに誤分析させないためには、AIの性能を上げる前に、数字に嘘をつかせないデータ構造を作ることが重要だと分かってきました。

全媒体データ分析基盤も、単に数字を集める仕組みから、少しずつ「AIが正しく判断するためのデータを作る仕組み」へ変わってきています。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

目次