このトピックでは、E コマースのシナリオにおける顧客解約予測タスクを使用して、AnalyticDB for PostgreSQL V7.0 で pgml 拡張機能を使用してバッチ予測タスクフローとリアルタイム予測タスクフローを構築する方法について説明します。
前提条件
AnalyticDB for PostgreSQL V7.0 インスタンス V7.1.1.0 以降が作成されている。
インスタンスがエラスティックストレージモードである。
インスタンスに pgml 拡張機能がインストールされている。
説明pgml 拡張機能をインストールしている場合、pgml という名前のスキーマがスキーマリストに含まれています。 pgml 拡張機能をインストールしていない場合は、インストールのサポートを受けるために チケットを送信する してください。 pgml 拡張機能をインストールした後、インスタンスを再起動する必要があります。 pgml 拡張機能をアンインストールするには、チケットを送信してください。
背景情報
pgml 拡張機能は、モデルをデータに近づけるように設計されています。 データベース内 AI/ML 機能は、モデルを PostgreSQL のバックエンドプロセスにロードし、ユーザー定義関数(UDF)を使用して、モデルのトレーニング、微調整、推論を実行します。 トレーニング、微調整、推論の後、モデルはヒープテーブルに保存されます。 高可用性または高信頼性のソリューションを設計する必要はありません。 これにより、O&M がシンプルでユーザーフレンドリーになります。 pgml 拡張機能は、統合されたストレージと計算リソースを利用して、データ転送の損失を削減し、モデルのトレーニングとサービスのデプロイを効率的に完了します。 次の図は、AI/ML のトレーニングと推論のプロセスを示しています。
データの提示と分析
サンプルデータセット
この例では、顧客解約ラベルが付いた顧客の過去の行動データを含むデータセットを使用します。 詳細については、「E コマースの顧客解約分析と予測」をご参照ください。 顧客解約の分析と予測は、企業が顧客維持率を向上させるためのより効果的なポリシーを開発するのに役立ちます。 次の表に、データセットに含まれるフィールドを示します。
フィールド | 説明 |
CustomerID | 一意の顧客 ID。 |
Churn | 顧客解約ラベル。 |
Tenure | 顧客の使用期間。 |
PreferredLoginDevice | 顧客の優先ログインデバイス。 |
CityTier | 顧客が住んでいる都市のカテゴリ。 |
WarehouseToHome | 倉庫から顧客の自宅までの距離。 |
PreferredPaymentMode | 顧客の優先支払方法。 |
Gender | 顧客の性別。 |
HourSpendOnApp | 顧客がモバイル アプリケーションまたは Web サイトで費やした時間数。 |
NumberOfDeviceRegistered | 顧客に登録されているデバイスの総数。 |
PreferedOrderCat | 先月の顧客の優先注文カテゴリ。 |
SatisfactionScore | サービスに対する顧客の満足度スコア。 |
MaritalStatus | 顧客の婚姻状況。 |
NumberOfAddress | 顧客によって追加された住所の総数。 |
Complain | 顧客が先月に苦情を申し立てたかどうかにを指定します。 |
OrderAmountHikeFromlastYear | 昨年と比較した顧客注文金額の増加率。 |
CouponUsed | 先月に顧客が使用したクーポンの総数。 |
OrderCount | 先月の顧客注文の総数。 |
DaySinceLastOrder | 顧客の最新の注文からの日数。 |
CashbackAmount | 先月の顧客のキャッシュバック金額。 |
データのインポート
テーブルを作成します。
CREATE TABLE raw_data_table ( CustomerID INTEGER, Churn INTEGER, Tenure FLOAT, PreferredLoginDevice TEXT, CityTier INTEGER, WarehouseToHome FLOAT, PreferredPaymentMode TEXT, Gender TEXT, HourSpendOnApp FLOAT, NumberOfDeviceRegistered INTEGER, PreferedOrderCat TEXT, SatisfactionScore INTEGER, MaritalStatus TEXT, NumberOfAddress INTEGER, Complain INTEGER, OrderAmountHikeFromlastYear FLOAT, CouponUsed FLOAT, OrderCount FLOAT, DaySinceLastOrder FLOAT, CashbackAmount FLOAT );
データセットをダウンロードし、
COPY
文を使用して、CSV 形式のデータセットをテーブルにインポートします。 /path/to/dataset パラメーターをデータセットの実際のパスに置き換えます。COPY raw_data_table FROM '/path/to/dataset.csv' DELIMITER ',' CSV HEADER;
説明psql ツールを使用してデータをインポートすることをお勧めします。 他の SDK を使用してデータをインポートする場合は、
COPY
文またはINSERT
文を使用できます。 詳細については、対応するドキュメントをご参照ください。
データ分析
データセット内の NULL 値の分布を確認します。
DO $$
DECLARE
r RECORD;
SQL TEXT := '';
BEGIN
FOR r IN
SELECT column_name
FROM information_schema.columns
WHERE table_name = 'raw_data_table'
LOOP
SQL := SQL ||
'SELECT ''' || r.column_name || ''' AS column_name, COUNT(*) FILTER (WHERE ' || r.column_name || ' IS NULL) AS null_count FROM raw_data_table UNION ALL ';
END LOOP;
SQL := LEFT(SQL, length(SQL) - 11);
FOR r IN EXECUTE SQL LOOP
RAISE NOTICE 'Column: %, Null Count: %', r.column_name, r.null_count;
END LOOP;
END $$;
サンプル結果:
NOTICE: Column: customerid, Null Count: 0
NOTICE: Column: churn, Null Count: 0
NOTICE: Column: tenure, Null Count: 264
NOTICE: Column: preferredlogindevice, Null Count: 0
NOTICE: Column: citytier, Null Count: 0
NOTICE: Column: warehousetohome, Null Count: 251
NOTICE: Column: preferredpaymentmode, Null Count: 0
NOTICE: Column: gender, Null Count: 0
NOTICE: Column: hourspendonapp, Null Count: 255
NOTICE: Column: numberofdeviceregistered, Null Count: 0
NOTICE: Column: preferedordercat, Null Count: 0
NOTICE: Column: satisfactionscore, Null Count: 0
NOTICE: Column: maritalstatus, Null Count: 0
NOTICE: Column: numberofaddress, Null Count: 0
NOTICE: Column: complain, Null Count: 0
NOTICE: Column: orderamounthikefromlastyear, Null Count: 265
NOTICE: Column: couponused, Null Count: 256
NOTICE: Column: ordercount, Null Count: 258
NOTICE: Column: daysincelastorder, Null Count: 307
NOTICE: Column: cashbackamount, Null Count: 0
NULL 値を含むフィールドの場合は、フィールドのセマンティクスとデータ分布を確認して、前処理ポリシーを決定し、後続のトレーニングのために特徴量エンジニアリングを実行する必要があります。 次の手順を実行します。
フィールドに NULL 値が含まれているかどうかを確認するために使用される分析関数を作成します。
CREATE OR REPLACE FUNCTION print_column_statistics(table_name TEXT, column_name TEXT) RETURNS VOID AS $$ DECLARE SQL TEXT; distinct_count INTEGER; min_value NUMERIC; max_value NUMERIC; avg_value NUMERIC; median_value NUMERIC; r RECORD; BEGIN SQL := 'SELECT COUNT(DISTINCT ' || column_name || ') AS distinct_count, MIN(' || column_name || ') AS min_value, MAX(' || column_name || ') AS max_value, AVG(' || column_name || ') AS avg_value, PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY ' || column_name || ') AS median_value FROM ' || table_name; EXECUTE SQL INTO r; distinct_count := r.distinct_count; min_value := r.min_value; max_value := r.max_value; avg_value := r.avg_value; median_value := r.median_value; RAISE NOTICE 'Distinct Count: %', distinct_count; IF distinct_count < 40 THEN SQL := 'SELECT ' || column_name || ' AS col, COUNT(*) AS count FROM ' || table_name || ' GROUP BY ' || column_name || ' ORDER BY count DESC'; FOR r IN EXECUTE SQL LOOP RAISE NOTICE '%: %', r.col, r.count; END LOOP; END IF; RAISE NOTICE 'Min Value: %, Max Value: %, Avg Value: %, Median Value: %', min_value, max_value, avg_value, median_value; END; $$ LANGUAGE plpgsql;
分析関数を使用して、フィールドに NULL 値が含まれているかどうかを確認します。
SELECT print_column_statistics('raw_data_table', 'tenure');
サンプル結果:
NOTICE: Distinct Count: 36 NOTICE: 1: 690 NOTICE: 0: 508 NOTICE: <NULL>: 264 NOTICE: 8: 263 NOTICE: 9: 247 NOTICE: 7: 221 NOTICE: 10: 213 NOTICE: 5: 204 ... NOTICE: Min Value: 0, Max Value: 61, Avg Value: 10.1898993663809, Median Value: 9
モデルのトレーニング
データの前処理
上記の分析は、Tenure
、WareHousetohome
、HourSpendOnApp
、OrderAmountHikeFromLastYear
、CouponUsed
、OrderCount
、DaySinceLastOrder
フィールドに NULL 値が含まれていることを示しています。 モデルのパフォーマンスへの影響を防ぐために、NULL 値のデータ処理を実行する必要があります。 次のリストは、フィールドのデータ分析と NULL 処理方法を示しています。
Tenure
フィールドでは、通常の値は正に歪んでいます。 この場合、NULL 値を中央値で埋めます。WareHousetohome
フィールドには、極値が存在します。 たとえば、特定の顧客は倉庫から遠く離れて住んでいます。 この場合、NULL 値を中央値で埋めて、データ分布を中央に配置します。HourSpendOnApp
フィールドでは、データは比較的対称です。 この場合、NULL 値を平均値で埋めます。OrderAmountHikeFromLastYear
フィールドでは、データ分布は安定しています。 この場合、NULL 値を平均値で埋めます。CouponUsed
フィールドでは、NULL 値は使用されていないクーポンと見なされます。 この場合、NULL 値を 0 で埋めます。OrderCount
フィールドでは、NULL 値は注文されていない注文と見なされます。 この場合、NULL 値を 0 で埋めます。DaySinceLastOrder
フィールドでは、NULL 値は最新の注文からの期間が長いことを示します。 この場合、NULL 値を最大値で埋めます。
機械学習を使用して、次の前処理パラメーターを取得します。 詳細については、「機械学習を使用する」をご参照ください。
{
"tenure": {"impute": "median"},
"warehousetohome": {"impute": "median"},
"hourspendonapp": {"impute": "mean"},
"orderamounthikefromlastyear": {"impute": "mean"},
"couponused": {"impute": "zero"},
"ordercount": {"impute": "zero"},
"daysincelastorder": {"impute": "max"}
}
CityTier
フィールドと Complain
フィールドは INTEGER 型です。 ただし、これらのフィールドはラベルを使用して意味を表します。 フィールドを TEXT 型に変換し、one-hot エンコーディングメソッドを使用できます。
トレーニングビューの作成
上記のデータ処理結果に基づいてビューを作成して、raw データテーブルの物理的な変更を防ぎ、後でさらに機能を追加できます。
CREATE OR REPLACE VIEW train_data_view AS
SELECT
Churn::TEXT,
Tenure,
PreferredLoginDevice,
CityTier::TEXT,
WarehouseToHome,
PreferredPaymentMode,
Gender,
HourSpendOnApp,
NumberOfDeviceRegistered,
PreferedOrderCat,
SatisfactionScore,
MaritalStatus,
NumberOfAddress,
Complain::TEXT,
OrderAmountHikeFromlastYear,
CouponUsed,
OrderCount,
DaySinceLastOrder,
CashbackAmount
FROM
raw_data_table;
特徴量エンジニアリングの実行
特徴量エンジニアリングは、機械学習とデータマイニングの重要なステップです。 このステップでは、raw データを処理および変換し、追加情報を提供し、モデルの収束を実現し、全体的なパフォーマンスを向上させることができます。
特徴量 | 説明 |
AvgCashbkPerOrder | 注文ごとの平均キャッシュバック金額。 計算式:CashbackAmount/OrderCount。 |
AvgHourSpendPerOrder | 注文ごとの平均閲覧時間。 計算式:HourSpendOnApp/OrderCount。 |
CouponUsedPerOrder | 注文ごとに使用されるクーポンの平均数。 計算式:CouponUsed/OrderCount。 |
LogCashbackAmount | キャッシュバック金額の対数変換。 計算式:log(1 + LogCashbackAmount)。 |
上記の機能に基づいてビューを再作成します。
CREATE OR REPLACE VIEW train_data_view AS
SELECT
Churn::TEXT,
Tenure,
PreferredLoginDevice,
CityTier::TEXT,
WarehouseToHome,
PreferredPaymentMode,
Gender,
HourSpendOnApp,
NumberOfDeviceRegistered,
PreferedOrderCat,
SatisfactionScore,
MaritalStatus,
NumberOfAddress,
Complain::TEXT,
OrderAmountHikeFromlastYear,
CouponUsed,
OrderCount,
DaySinceLastOrder,
CashbackAmount,
CashbackAmount/OrderCount AS AvgCashbkPerOrder,
HourSpendOnApp/OrderCount AS AvgHourSpendPerOrder,
CouponUsed/OrderCount AS CouponUsedPerOrder,
log(1+CashbackAmount) AS LogCashbackAmount
FROM
raw_data_table;
モデルのトレーニングと選択
pgml.train()
関数を使用して、さまざまなモデルをデータに適合させ、結果を確認します。 この例では、XGBoost モデルとバギングモデルを使用します。XGBoost モデルをデータに適合させます。
SELECT * FROM pgml.train( project_name => 'Customer Churn Prediction Project', -- プロジェクト名 task => 'classification', -- タスクタイプ relation_name => 'train_data_view', -- データソース y_column_name => 'churn', -- 予測カテゴリ列の名前 preprocess => '{ "tenure": {"impute": "median"}, "warehousetohome": {"impute": "median"}, "hourspendonapp": {"impute": "mean"}, "orderamounthikefromlastyear": {"impute": "mean"}, "couponused": {"impute": "zero"}, "ordercount": {"impute": "zero"}, "daysincelastorder": {"impute": "max"}, "avgcashbkperorder": {"impute": "zero"}, "avghourspendperorder": {"impute": "zero"}, "couponusedperorder": {"impute": "zero"}, "logcashbackamount": {"impute": "min"} }', -- 前処理方法 algorithm => 'xgboost', -- モデルタイプ runtime => 'python', -- ランタイム環境。このパラメーターを python に設定します。 test_size => 0.2 -- テストセットの比率 );
次の適合メトリックが返されます。
-- 返される適合メトリック: -- {f1": 0.9543147, "precision": 0.96907216, "recall": 0.94, "accuracy": 0.9840142, ...}
バギングモデルをデータに適合させます。
-- バギング回帰 SELECT * FROM pgml.train( project_name => 'Customer Churn Prediction Project', -- プロジェクト名 task => 'classification', -- タスクタイプ relation_name => 'train_data_view', -- データソース y_column_name => 'churn', -- 予測カテゴリ列の名前 preprocess => '{ "tenure": {"impute": "median"}, "warehousetohome": {"impute": "median"}, "hourspendonapp": {"impute": "mean"}, "orderamounthikefromlastyear": {"impute": "mean"}, "couponused": {"impute": "zero"}, "ordercount": {"impute": "zero"}, "daysincelastorder": {"impute": "max"}, "avgcashbkperorder": {"impute": "zero"}, "avghourspendperorder": {"impute": "zero"}, "couponusedperorder": {"impute": "zero"}, "logcashbackamount": {"impute": "min"} }', -- 前処理方法 algorithm => 'bagging', -- モデルタイプ runtime => 'python', -- ランタイム環境。このパラメーターを python に設定します。 test_size => 0.2 -- テストセットの比率 );
次の適合メトリックが返されます。
-- 返される適合メトリック: -- {"f1": 0.9270833, "precision": 0.96216214, "recall": 0.89447236}
algorithm
パラメーターの値を置き換えて、データセットに対するさまざまなモデルの適合機能を確認できます。 サポートされているモデルについては、「機械学習を使用する」トピックの pgml.algorithm 列挙型テーブルを参照してください。 F1 メトリックの値に基づくと、XGBoost モデルのパフォーマンスは他のモデルのパフォーマンスよりも優れています。 この例では、XGBoost モデルを選択して後続の操作を実行します。グリッドパラメーター検索方法を使用して最適なモデル ハイパーパラメーターを見つけ、5分割交差検証を使用して結果の信頼性を高めます。 次の表に、検索方法で使用されるハイパーパラメーターを示します。
ハイパーパラメーター
説明
n_estimators
構築するツリーの数。 ツリーの数が増えるとモデルのパフォーマンスは向上しますが、計算コストも増加します。 値の範囲は変数です。 たとえば、値を 100、200、300、400、500 に設定して、最適なバランスポイントを見つけることができます。
eta
学習率。 このパラメーターは、各ツリーが最終的な予測にどの程度寄与するかを指定します。 学習率が低いほど、トレーニングプロセスはより安定しますが、
n_estimators
パラメーターの値を高くする必要がある場合があります。 値の範囲は変数です。 たとえば、値を 0.05、0.1、0.2 に設定して、トレーニングの安定性と効率の間の最適なバランスポイントを見つけることができます。max_depth
各ツリーの最大深度。 深度が深いほど、より多くの特徴量の相互作用が捉えられますが、過剰適合につながる可能性があります。 値の範囲は変数です。 たとえば、値を 16 と 32 に設定できます。
SELECT * FROM pgml.train( project_name => 'Customer Churn Prediction Project', -- プロジェクト名 task => 'classification', -- タスクタイプ relation_name => 'train_data_view', -- データソース y_column_name => 'churn', -- 予測カテゴリ列の名前 preprocess => '{ "tenure": {"impute": "median"}, "warehousetohome": {"impute": "median"}, "hourspendonapp": {"impute": "mean"}, "orderamounthikefromlastyear": {"impute": "mean"}, "couponused": {"impute": "zero"}, "ordercount": {"impute": "zero"}, "daysincelastorder": {"impute": "max"}, "avgcashbkperorder": {"impute": "zero"}, "avghourspendperorder": {"impute": "zero"}, "couponusedperorder": {"impute": "zero"}, "logcashbackamount": {"impute": "min"} }', -- 前処理方法 algorithm => 'xgboost', -- モデルタイプ search_args => '{ "cv": 5 }', -- 5分割交差検証を有効にします。 SEARCH => 'grid', -- グリッド検索方法 search_params => '{ "max_depth": [4, 6, 8, 16], "n_estimators": [100, 200, 300, 400, 500, 1000, 2000], "eta": [0.05, 0.1, 0.2] }', hyperparams => '{ "nthread": 16, "alpha": 0, "lambda": 1 }', runtime => 'python', -- ランタイム環境。このパラメーターを python に設定します。 test_size => 0.2 -- テストセットの比率 );
サンプル結果:
-- 検索結果: -- ... (詳細は省略) INFO: Best Hyperparams: { "alpha": 0, "lambda": 1, "nthread": 16, "eta": 0.1, "max_depth": 6, "n_estimators": 1000 } INFO: Best f1 Metrics: Number(0.9874088168144226)
検索結果によると、
{"eta": 0.2, "max_depth": 16, "n_estimators": 400}
のハイパーパラメーター値が最適なモデル適合機能を提供します。search_args => '{ "cv": 5 }
構成は、k分割交差検証が有効になっていることを指定します。 したがって、モデルはデータセットの 80% をトレーニングに使用します。最適なハイパーパラメーターを使用して、完全なデータでモデルをトレーニングし、結果を確認します。
SELECT * FROM pgml.train( project_name => 'Customer Churn Prediction Project', -- プロジェクト名 task => 'classification', -- タスクタイプ relation_name => 'train_data_view', -- データソース y_column_name => 'churn', -- 予測カテゴリ列の名前 preprocess => '{ "tenure": {"impute": "median"}, "warehousetohome": {"impute": "median"}, "hourspendonapp": {"impute": "mean"}, "orderamounthikefromlastyear": {"impute": "mean"}, "couponused": {"impute": "zero"}, "ordercount": {"impute": "zero"}, "daysincelastorder": {"impute": "max"}, "avgcashbkperorder": {"impute": "zero"}, "avghourspendperorder": {"impute": "zero"}, "couponusedperorder": {"impute": "zero"}, "logcashbackamount": {"impute": "min"} }', -- 前処理方法 algorithm => 'xgboost', -- モデルタイプ hyperparams => '{ "max_depth": 6, "n_estimators": 1000, "eta": 0.1, "nthread": 16, "alpha": 0, "lambda": 1 }', runtime => 'python', -- ランタイム環境。このパラメーターを python に設定します。 test_size => 0.2 -- テストセットの比率 );
サンプル結果:
-- 検索結果: INFO: Training Model { id: 170, task: classification, algorithm: xgboost, runtime: python } INFO: Hyperparameter searches: 1, cross validation folds: 1 INFO: Hyperparams: { "eta": 0.1, "alpha": 0, "lambda": 1, "nthread": 16, "max_depth": 6, "n_estimators": 1000 } INFO: Metrics: {"roc_auc": 0.9751001, "log_loss": 0.19821791, "f1": 0.99258476, "precision": 0.9936373, "recall": 0.9915344, "accuracy": 0.9875666, "mcc": 0.95414394, "fit_time": 0.9980099, "score_time": 0.0085158} INFO: Comparing to deployed model f1: Some(0.9874088168144226) INFO: Deploying model id: 170 project | task | algorithm | deployed -----------------------------------+----------------+-----------+---------- Customer Churn Prediction Project | classification | xgboost | t
テストセットのモデルパフォーマンス F1 は 0.99258476 に達する可能性があります。
モデルのデプロイ
デプロイするモデルの選択
デフォルトでは、pgml 拡張機能は、プロジェクトのトレーニング中に F1 値が最も高いモデルを自動的にデプロイします(分類タスクの場合)。 pgml.deployments
テーブルを使用して、現在のデプロイメントを確認できます。
SELECT d.id, d.project_id, d.model_id, p.name, p.task FROM pgml.deployments d
JOIN pgml.projects p on d.project_id = p.id;
サンプル結果:
id | project_id | model_id | name | task
----+------------+----------+-----------------------------------+----------------
61 | 2 | 170 | Customer Churn Prediction Project | classification
他のモデルをデプロイする方法については、「機械学習を使用する」トピックの「デプロイメント」セクションをご参照ください。
モデルの使用
リアルタイム推論
リアルタイム推論は、リアルタイムのインタラクティブな応答を必要とするシナリオに適しています。 たとえば、ケース分析を実行するデータアナリストは、ユーザーの過去の行動に基づいて予測結果がすぐに返されることを望んでいます。
-- 1つのテキストに対してリアルタイム推論を実行します。
SELECT pgml.predict('Customer Churn Prediction Project',
( 4, 'Mobile Phone'::TEXT, 3, 6,
'Debit Card'::TEXT, 'Female'::TEXT, 3, 3,
'Laptop & Accessory'::TEXT, 2,
'Single'::TEXT, 9 ,
'1'::TEXT, 11, 1, 1, 5, 159.93,
159.93, 3, 1, 2.206637011283536
));
サンプル結果:
-- 予測結果:
predict
---------
0
(1 row)
バッチ推論
バッチ推論は、大量のデータを処理する必要があり、スループットが応答時間よりも優先されるシナリオに適しています。 バッチ推論は、計算リソースの利用率を向上させることができます。
-- ビューを作成します。
CREATE OR REPLACE VIEW predict_data_view AS
SELECT
CustomerID,
Churn::TEXT,
Tenure,
PreferredLoginDevice,
CityTier::TEXT,
WarehouseToHome,
PreferredPaymentMode,
Gender,
HourSpendOnApp,
NumberOfDeviceRegistered,
PreferedOrderCat,
SatisfactionScore,
MaritalStatus,
NumberOfAddress,
Complain::TEXT,
OrderAmountHikeFromlastYear,
CouponUsed,
OrderCount,
DaySinceLastOrder,
CashbackAmount,
CashbackAmount/OrderCount AS AvgCashbkPerOrder,
HourSpendOnApp/OrderCount AS AvgHourSpendPerOrder,
CouponUsed/OrderCount AS CouponUsedPerOrder,
log(1+CashbackAmount) AS LogCashbackAmount
FROM
raw_data_table;
-- ====================================
-- 一度に複数のテキストに対してバッチ推論を実行します。
SELECT CustomerID, pgml.predict('Customer Churn Prediction Project', (
"tenure",
"preferredlogindevice",
"citytier",
"warehousetohome",
"preferredpaymentmode",
"gender",
"hourspendonapp",
"numberofdeviceregistered",
"preferedordercat",
"satisfactionscore",
"maritalstatus",
"numberofaddress",
"complain",
"orderamounthikefromlastyear",
"couponused",
"ordercount",
"daysincelastorder",
"cashbackamount",
"avgcashbkperorder",
"avghourspendperorder",
"couponusedperorder",
"logcashbackamount"
)) FROM predict_data_view limit 20;
サンプル結果:
-- 予測結果:
customerid | predict
------------+---------
50005 | 0
50009 | 0
50012 | 0
50013 | 0
50019 | 0
50020 | 0
50022 | 0
50023 | 0
50026 | 0
50031 | 1
50039 | 1
50040 | 0
50043 | 1
50045 | 1
50047 | 0
50048 | 1
50050 | 1
50051 | 1
50052 | 1
50053 | 0
(20 rows)