<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>BQML on Marketechlabo</title><link>https://www.marketechlabo.com/tags/bqml/</link><description>Recent content in BQML on Marketechlabo</description><generator>Hugo -- gohugo.io</generator><language>ja-jp</language><lastBuildDate>Fri, 12 Feb 2021 00:00:00 +0900</lastBuildDate><atom:link href="https://www.marketechlabo.com/tags/bqml/index.xml" rel="self" type="application/rss+xml"/><item><title>Google BigQueryでお手軽機械学習（BQML）</title><link>https://www.marketechlabo.com/machine-learning/bqml-intro/</link><pubDate>Mon, 18 Jan 2021 00:00:00 +0900</pubDate><guid>https://www.marketechlabo.com/machine-learning/bqml-intro/</guid><description>
&lt;p&gt;BigQuery MLは生成AI（Geminiなど）との連携やVertex AI統合など多様な機能を提供しているが、企業の日常業務で扱う構造化データ（売上、顧客、在庫など）の予測分析において、最もコストパフォーマンスが高く実用的な手法は依然として勾配ブースティング木（XGBoost系）である。この記事では、SQLだけで完結するMLパイプラインの構築方法を実例とともに解説する。&lt;/p&gt;
&lt;p&gt;BigQuery ML（BQML）では以下のモデルが使える：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;線形回帰&lt;/strong&gt; - 類似のリモートデータでトレーニングされたモデルを使用して、新しいデータの数値指標の値を予測する。ラベルは実数で、正の無限大、負の無限大、NaN（非数値）にはできない。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ロジスティック回帰&lt;/strong&gt; - 入力がlow-value、medium-value、high-valueのいずれであるかなど、2つ以上の有効な値を分類する場合に使用する。ラベルには最大50個の一意の値を指定できる。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;K平均法クラスタリング&lt;/strong&gt; - データセグメンテーションに使用する。顧客セグメントの識別などに使える。教師なし学習なのでモデルのトレーニングを行う際にラベルは必要なく、トレーニングや評価用にデータの分割を行う必要もない。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;行列分解&lt;/strong&gt; - 商品のレコメンデーションシステムの作成に使用する。過去の顧客行動、トランザクション、商品評価を使用して商品のおすすめを作成し、これらのレコメンデーションを使用してカスタマイズされたカスタマーエクスペリエンスを提供できる。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;主成分分析（PCA）&lt;/strong&gt; - 主成分を計算し、それらを使用してデータに基底変換を実行するプロセス。一般に、データのバリエーションをできるだけ多く保持しながら、各データポイントを最初のいくつかの主成分にのみ射影して低次元のデータを取得することで、次元数を削減するために使用される。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;時系列&lt;/strong&gt; - 時系列予測と異常検出に使用する。ARIMA_PLUSモデルとARIMA_PLUS_XREGモデルは、複数のチューニングオプションを提供し、異常値、季節性、休日を自動で処理する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ディープニューラルネットワーク（DNN）&lt;/strong&gt; - 分類モデルと回帰モデル用にTensorFlowベースのディープニューラルネットワークを構築する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ワイド＆ディープ&lt;/strong&gt; - レコメンデーションシステム、検索、ランキングに関する問題など、スパース入力による大規模な回帰と分類問題（多くの特徴値を持つカテゴリ特徴）に役立つ。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;オートエンコーダ&lt;/strong&gt; - スパースデータ表現をサポートするTensorFlowベースのモデルを作成する。BigQuery MLのモデルは、教師なし異常検出や非線形次元削減などのタスクに使用できる。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ブーストツリー&lt;/strong&gt; - XGBoostに基づく分類モデルと回帰モデルを作成する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ランダムフォレスト&lt;/strong&gt; - トレーニング時の分類、回帰、その他のタスク用に、複数の学習方法のディシジョンツリーを構築するために使用する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AutoML&lt;/strong&gt; - 表形式データの分類モデルと回帰モデルを高速かつ大規模に構築してデプロイする教師ありMLサービス。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当初は線形回帰とロジスティック回帰だけだったが今では実用的な手法が増えた。何よりもXGBoostが使えるようになったのが大きい。&lt;/p&gt;
&lt;h2 id="xgboostのメリット"&gt;XGBoostのメリット&lt;/h2&gt;
&lt;p&gt;XGBoostは語弊を恐れずに言うと&lt;strong&gt;特に何も考えなくてもそれなりの精度が出る、素人でもそこそこのアウトプットを出せてしまう&lt;/strong&gt;手法である。これまでの線形回帰やロジスティック回帰は前提条件が扱いが難しい手法だった。&lt;/p&gt;
&lt;p&gt;XGBoostがお手軽というのは、&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;正規化不要&lt;/li&gt;
&lt;li&gt;カテゴリ変数と連続量を意識しなくてもいい&lt;/li&gt;
&lt;li&gt;欠損値があってもいい&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;つまり&lt;strong&gt;特徴量の前処理の面倒な部分がかなり軽減されている&lt;/strong&gt;。与えられた変数を特に加工しなくても使える。XGBoostはそういったことが不要な、お手軽で大変便利な手法である。&lt;/p&gt;
&lt;p&gt;この記事ではBigQueryでお手軽に機械学習を体感してみようということで、XGBoostを使ってBQMLを説明する。&lt;/p&gt;
&lt;h2 id="方法"&gt;方法&lt;/h2&gt;
&lt;h3 id="データセットの準備"&gt;データセットの準備&lt;/h3&gt;
&lt;p&gt;対象データは学習（train）／評価（evaluate/validate）／テストで予測するデータに分割する。目的変数と説明変数に加え、分割用の列&lt;code&gt;subset&lt;/code&gt;を作り&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;subset = 'TRAIN'&lt;/code&gt;: 学習用データ&lt;/li&gt;
&lt;li&gt;&lt;code&gt;subset = 'EVALUATE'&lt;/code&gt;: 評価用データ&lt;/li&gt;
&lt;li&gt;&lt;code&gt;subset = 'TEST'&lt;/code&gt;: 予測用データ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;という値を付与しておく。今回はBigQueryの公開サンプルデータである&lt;code&gt;bigquery-public-data.ml_datasets.ulb_fraud_detection&lt;/code&gt;を使って不正取引の予測をするモデルを作る。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Class&lt;/code&gt;が目的変数となる不正取引フラグ&lt;/li&gt;
&lt;li&gt;特徴量は&lt;code&gt;V1&lt;/code&gt;～&lt;code&gt;V28&lt;/code&gt;と&lt;code&gt;Amount&lt;/code&gt;（取引額）。&lt;code&gt;V1&lt;/code&gt;～&lt;code&gt;V28&lt;/code&gt;はオリジナルの特徴量を主成分分析で集約したもの&lt;/li&gt;
&lt;li&gt;これを学習：評価：テスト＝8:1:1で分割する&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;create&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;or&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;replace&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;table&lt;/span&gt; &lt;span style="color:#f92672"&gt;`&lt;/span&gt;my&lt;span style="color:#f92672"&gt;-&lt;/span&gt;project.test_dataset.ulb_fraud_detection&lt;span style="color:#f92672"&gt;`&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;with&lt;/span&gt; t1 &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;select&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; row_number() over() id,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; rand() rnd
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; &lt;span style="color:#f92672"&gt;`&lt;/span&gt;bigquery&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;data&lt;/span&gt;.ml_datasets.ulb_fraud_detection&lt;span style="color:#f92672"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;), t2 &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;select&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;except&lt;/span&gt;(rnd),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;case&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;when&lt;/span&gt; rnd &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;.&lt;span style="color:#ae81ff"&gt;8&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;then&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;TRAIN&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;when&lt;/span&gt; rnd &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;.&lt;span style="color:#ae81ff"&gt;9&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;then&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;EVALUATE&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;TEST&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt; subset
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; t1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;select&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; t2 &lt;span style="color:#66d9ef"&gt;order&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;by&lt;/span&gt; id;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="bqmlの機械学習手順"&gt;BQMLの機械学習手順&lt;/h3&gt;
&lt;p&gt;まずBQMLの操作手順だが、機械学習の手順に沿い&lt;/p&gt;</description></item><item><title>BigQueryでGA4/Firebaseのログを使って機械学習</title><link>https://www.marketechlabo.com/machine-learning/bqml-ga4-firebase-log/</link><pubDate>Fri, 12 Feb 2021 00:00:00 +0900</pubDate><guid>https://www.marketechlabo.com/machine-learning/bqml-ga4-firebase-log/</guid><description>
&lt;h2 id="firebase公開データでユーザー継続予測を行う手順bigquery--bqml"&gt;Firebase公開データでユーザー継続予測を行う手順（BigQuery + BQML）&lt;/h2&gt;
&lt;p&gt;Firebase Analyticsの公開データを使用して、ユーザーの1か月後継続を予測するための一連の分析手順である。生ログのフラット化から機械学習モデルの構築まで、BigQueryとBQMLだけで完結する手法を示す。&lt;/p&gt;
&lt;h2 id="使うデータセット"&gt;使うデータセット&lt;/h2&gt;
&lt;p&gt;Firebaseのパブリックデータが&lt;code&gt;firebase-public-project.analytics_153293282.events_*&lt;/code&gt;にあるのでこれを使う。&lt;/p&gt;
&lt;p&gt;20180612～20181003の114日分のデータ&lt;/p&gt;
&lt;h2 id="基本集計eda"&gt;基本集計（EDA）&lt;/h2&gt;
&lt;p&gt;データの全体像を把握するため、まずイベントの発生傾向を確認する。どのようなユーザー行動が記録されているかを理解することで、後続の特徴量設計や分析方針の決定に活用できる。&lt;/p&gt;
&lt;h3 id="イベントの数の種類別カウント"&gt;イベントの数の種類別カウント&lt;/h3&gt;
&lt;p&gt;アプリ内で発生している各イベントの頻度を集計する。これにより、主要なユーザー行動パターンを把握し、重要度の高いイベントを特定できる。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;select&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; event_name,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;count&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; &lt;span style="color:#f92672"&gt;`&lt;/span&gt;firebase&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;project.analytics_153293282.events_20181003&lt;span style="color:#f92672"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;group&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;by&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;order&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;by&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;desc&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="スクリーンビューのスクリーン別カウント"&gt;スクリーンビューのスクリーン別カウント&lt;/h3&gt;
&lt;p&gt;ユーザーがアプリ内のどの画面をよく閲覧しているかを分析する。&lt;code&gt;firebase_screen_class&lt;/code&gt;パラメータは&lt;code&gt;event_params&lt;/code&gt;配列内にネストされているため、&lt;code&gt;UNNEST()&lt;/code&gt;で展開してから抽出する必要がある。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;select&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (&lt;span style="color:#66d9ef"&gt;select&lt;/span&gt; ep.value.string_value &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;unnest&lt;/span&gt;(event_params) ep &lt;span style="color:#66d9ef"&gt;where&lt;/span&gt; ep.&lt;span style="color:#66d9ef"&gt;key&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;firebase_screen_class&amp;#39;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;count&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;) screen_views
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; &lt;span style="color:#f92672"&gt;`&lt;/span&gt;firebase&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;project.analytics_153293282.events_20181003&lt;span style="color:#f92672"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;where&lt;/span&gt; event_name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;screen_view&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;group&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;by&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;order&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;by&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="ユーザ別イベント数カウント"&gt;ユーザ別イベント数カウント&lt;/h2&gt;
&lt;p&gt;ユーザーごとの行動パターンを把握するため、行がユーザー、列がイベント名となるピボットテーブルを作成する。&lt;/p&gt;
&lt;p&gt;イベント名はアプリケーションによって動的に変わるため、固定の列定義では対応できない。そこでBigQuery Scriptingを使用して、データに存在するイベント名を自動検出し、動的にピボット用のSQL文を生成する。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;declare&lt;/span&gt; event_pivot_columns string;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;set&lt;/span&gt; event_pivot_columns &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;select&lt;/span&gt; string_agg(&lt;span style="color:#66d9ef"&gt;distinct&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;sum(case when event_name = &amp;#34;&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; event_name &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#34; then 1 else 0 end) &amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; event_name) &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; &lt;span style="color:#f92672"&gt;`&lt;/span&gt;firebase&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;project.analytics_153293282.events_&lt;span style="color:#f92672"&gt;*`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;execute&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;immediate&lt;/span&gt; format(&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;create or replace table `my-project.test.user_stats` as
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;select
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; user_pseudo_id,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; min(timestamp_micros(event_timestamp)) first_open_timestamp,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; max(timestamp_micros(event_timestamp)) last_open_timestamp,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; count(0) total_events,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; max(user_ltv.revenue) total_revenue,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; %s
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;from `firebase-public-project.analytics_153293282.events_*`
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;group by 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;order by 4 desc;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;, event_pivot_columns)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="対象データを抽出してフラット化"&gt;対象データを抽出してフラット化&lt;/h2&gt;
&lt;p&gt;Firebase/GA4のイベントデータは、&lt;code&gt;event_params&lt;/code&gt;や&lt;code&gt;user_properties&lt;/code&gt;がネスト構造（配列・構造体）になっている。このままでは集計や機械学習での利用が困難なため、各パラメータを個別の列として展開する。&lt;/p&gt;</description></item></channel></rss>