時系列で未来を予測 with EinsteinAnalytic-パート1

セールスフォースWinter19リリースでいくつかの素晴らしい新機能を手に入れることをできました。その中に私が注目されているのは時系列SAQL関数です。 なぜでしょう?まあ、ビッグデータに関してトレンドを見てみたかったら機械学習、AI知識は必要があります。Einstein Analyticには、今までトレンド予測を見る方法がありませんでした。 時系列では、既存のデータのパターンに基づいて何が起こるかを実際に予測することができます。 例を見てみましょう。

データの準備

もちろん、既存のデータセットを使用することも、Salesforce に蓄積しているデータを使用しても新しいデータセットを作成することもできます。 しかし、私は使用できるデータソースをいくつか探してみました。最後に統計データサンプルを提供するプラットフォーみ”Kaggle”に入ってアボカドの価格統計データを発見してこのブログに例として使用すると決定しました。 参照元データ:https://www.kaggle.com/neuromusic/avocado-prices

このデータセットがどれだけ正確なのかはわかりませんが、そんなことはどうでもいいのですので楽しみましょう。 次はデータセットをダウンロードし、解凍してEinstein Analyticsにアップロードしましょう

。

データセットを取り込んだ後レンズを作成してみます。 以下の画像と同じようにバーチャートのX,Y軸指標を変えてみよう! X軸Bar Lengthにアボカドの平均価格項目(Avg Of AveragePrice) を指定する。 Y軸Barに日付項目(年月=Year Month)を指定する。

これから時系列でアボカド価格の予測モデルを作成しましょう。 クエリモードに切り替えて「SAQL」を書いてみよう!

書くべきのはアボカドのデータセットを抽出し日付項目でグルーピングして平均価格を集計するようにEinsteinAnalyticに指示する。それに加えてソート条件、データ数も制御する必要があります。いずれにしても、クエリは次のようになります。

q = load "avocado";
q = group q by ('Date_Year', 'Date_Month');
q = foreach q generate 'Date_Year' + "~~~" + 'Date_Month' as 'Date_Year~~~Date_Month', avg('AveragePrice') as 'avg_AveragePrice';
q = order q by 'Date_Year~~~Date_Month' asc;
q = limit q 2000;

最初に追加したいのは、グルーピング条件(2行目)の後に新しい'foreach'文を追加することです。これは既存の'foreach'文(3行目)のほぼコピーですが、日付を結合しません。

q = foreach q generate 'Date_Year', 'Date_Month', avg('AveragePrice') as 'avg_AveragePrice';

q = load "avocado";
q = group q by ('Date_Year', 'Date_Month');
q = foreach q generate 'Date_Year', 'Date_Month', avg('AveragePrice') as 'avg_AveragePrice';
q = foreach q generate 'Date_Year' + "~~~" + 'Date_Month' as 'Date_Year~~~Date_Month', avg('AveragePrice') as 'avg_AveragePrice';
q = order q by 'Date_Year~~~Date_Month' asc;
q = limit q 2000;

日付でグルーピングした場合、データがない月があるかもしれませんが、このような隙間を避けるために、新しいFill関数を使って不足している日付を埋めることができます。こちらのドキュメントをご参考ください。

https://developer.salesforce.com/docs/atlas.en-us.bi_dev_guide_saql.meta/bi_dev_guide_saql/bi_saql_statement_fill.htm

fill' 文は新しい 'foreach' 文の後に追加されます。これを動作させるためには'fill'文で同じ組み合わせ(年-月)を使用し、'年-四半期'のように切り替えないことを注意してください。構文は以下のようにハイライトされています。

q = fill q by (dateCols=('Date_Year', 'Date_Month', "Y-M"));

q = load "avocado";
q = group q by ('Date_Year', 'Date_Month');
q = foreach q generate 'Date_Year', 'Date_Month', avg('AveragePrice') as 'avg_AveragePrice';
q = fill q by (dateCols=('Date_Year', 'Date_Month', "Y-M"));
q = foreach q generate 'Date_Year' + "~~~" + 'Date_Month' as 'Date_Year~~~Date_Month', avg('AveragePrice') as 'avg_AveragePrice';
q = order q by 'Date_Year~~~Date_Month' asc;
q = limit q 2000;

隙間を埋めることができたので次は'timeseries'ステートメントを追加することになりました。新しいfillステートメントの後に、Enterキーを押して、時系列のためのスペースを作ってください。構文は、最初に時系列を呼び出しますが、使用する全てのパラメータを定義します。私は'length'と'dateCols'を使用します。'dateCols'は期間で、'length'は予測したい期間の数です。もちろん、追加したパラメータの前に表示されている指標が予測されている対象となります。

q = timeseries q generate 'avg_AveragePrice' as 'Forecasted_Avg_Avocado_Price' with (length=12, dateCols=('Date_Year', 'Date_Month', "Y-M"));

q = load "avocado";
q = group q by ('Date_Year', 'Date_Month');
q = foreach q generate 'Date_Year', 'Date_Month', avg('AveragePrice') as 'avg_AveragePrice';
q = fill q by (dateCols=('Date_Year', 'Date_Month', "Y-M"));
q = timeseries q generate 'avg_AveragePrice' as 'Forecasted_Avg_Avocado_Price' with (length=36, dateCols=('Date_Year', 'Date_Month', "Y-M"));
q = foreach q generate 'Date_Year' + "~~~" + 'Date_Month' as 'Date_Year~~~Date_Month', avg('AveragePrice') as 'avg_AveragePrice';
q = order q by 'Date_Year~~~Date_Month' asc;
q = limit q 2000;

これでここまで来ました。実行する前にもう一つやるべきことは、最後の'foreach'文に新しい項目'Forecasted_Avg_Avocado_Price'が含まれていることを確かめる必要があります。そこで、集計分を削除して、'foreach'文の最後の部分に新しい指標を追加します。

q = foreach q generate 'Date_Year' + "~" + 'Date_Month' as 'Date_Year~Date_Month','avg_AveragePrice', 'Forecasted_Avg_Avocado_Price';

q = load "avocado";
q = group q by ('Date_Year', 'Date_Month');
q = foreach q generate 'Date_Year', 'Date_Month', avg('AveragePrice') as 'avg_AveragePrice';
q = fill q by (dateCols=('Date_Year', 'Date_Month', "Y-M"));
q = timeseries q generate 'avg_AveragePrice' as 'Forecasted_Avg_Avocado_Price' with (length=36, dateCols=('Date_Year', 'Date_Month', "Y-M"));
q = foreach q generate 'Date_Year' + "~~~" + 'Date_Month' as 'Date_Year~~~Date_Month','avg_AveragePrice', 'Forecasted_Avg_Avocado_Price';
q = order q by 'Date_Year~~~Date_Month' asc;
q = limit q 2000;

これで実行ボタンを押すことができるようになりました。'avg_AveragePrice'を元にデータを集計を集計しています。将来の36ヶ月先値が空っぽです。しかし、これらは新しい「Forecasted_Avg_Avocado_Price」に埋めておきました。

これで終わりではなく、もっとできることがあります。予測間隔がどのようになっているかを見たいのかもしれません。それを'timeseries'と最後の'foreach'文に追加することができます。パラメータは'predictionInterval'で、80から95の間の値にすることができます。これを'timeseries'文と'foreach'文でクエリに追加してみましょう。

q = load "avocado"; q = group q by ('Date_Year', 'Date_Month'); q = foreach q generate 'Date_Year', 'Date_Month', avg('AveragePrice') as 'avg_AveragePrice'; q = fill q by (dateCols=('Date_Year', 'Date_Month', "Y-M")); q = timeseries q generate 'avg_AveragePrice' as 'Forecasted_Avg_Avocado_Price' with (length=36, dateCols=('Date_Year', 'Date_Month', "Y-M"), predictionInterval=95); q = foreach q generate 'Date_Year' + "~" + 'Date_Month' as 'Date_Year~Date_Month', 'avg_AveragePrice', 'Forecasted_Avg_Avocado_Price', 'Forecasted_Avg_Avocado_Price_high_95', 'Forecasted_Avg_Avocado_Price_low_95'; q = order q by 'Date_Year~~~Date_Month' asc; q = limit q 2000;

foreach' ステートメントには、予測された測定項目を再度呼び出しています。それに加えて'_high_95' と '_low_95' を追加しています。新しいパラメータを追加し、2つの追加項目を予測したかったら、クエリを実行してください。これで高値と低値も表示されます。

タイムラインチャートに切り替えると、以下のようになります。

q = load "avocado";
q = group q by ('Date_Year', 'Date_Month');
q = foreach q generate 'Date_Year', 'Date_Month', avg('AveragePrice') as 'avg_AveragePrice';
q = fill q by (dateCols=('Date_Year', 'Date_Month', "Y-M"));
q = timeseries q generate 'avg_AveragePrice' as 'Forecasted_Avg_Avocado_Price' with (length=36, dateCols=('Date_Year', 'Date_Month', "Y-M"), predictionInterval=95);
q = foreach q generate 'Date_Year' + "~~~" + 'Date_Month' as 'Date_Year~~~Date_Month', 'avg_AveragePrice', 'Forecasted_Avg_Avocado_Price', 'Forecasted_Avg_Avocado_Price_high_95', 'Forecasted_Avg_Avocado_Price_low_95';
q = order q by 'Date_Year~~~Date_Month' asc;
q = limit q 2000;

ここまでまだ終わらないです。チャートを少し綺麗にしてみましょう。データが有無の時は「avg_AveragePrice」、「Forecasted_Avg_Avocado_Price」を切り替えて置き換えましょう。あと、ネーミングがもう少し良くしてもいいかもしれません。ということで、SAQLモードに戻します。

データがあるときは 'coalesce' 関数を使用して avg_AveragePrice を取得し、値が空白の時に代わりに予測値を取得します。coalesce' の構文は簡単です。

coalesce('avg_AveragePrice', 'Forecasted_Avg_Avocado_Price') as '(平均)予測'

q = load "avocado";
q = group q by ('Date_Year', 'Date_Month');
q = foreach q generate 'Date_Year', 'Date_Month', avg('AveragePrice') as 'avg_AveragePrice';
q = fill q by (dateCols=('Date_Year', 'Date_Month', "Y-M"));
q = timeseries q generate 'avg_AveragePrice' as 'Forecasted_Avg_Avocado_Price' with (length=36, dateCols=('Date_Year', 'Date_Month', "Y-M"), predictionInterval=95);
q = foreach q generate 'Date_Year' + "~~~" + 'Date_Month' as 'Date_Year~~~Date_Month', coalesce('avg_AveragePrice', 'Forecasted_Avg_Avocado_Price') as '(平均)予測', 'Forecasted_Avg_Avocado_Price_high_95' as '高 予測', 'Forecasted_Avg_Avocado_Price_low_95' as '低 予測';
q = order q by 'Date_Year~~~Date_Month' asc;
q = limit q 2000;

実行をヒットしてみてチャートモードに切り替えると以下のようなチャートを表示します。当然 -私は、チャート表示のフォーマットにいくつかの調整を行いました。

Happy Coding!

Posted in AI, Analytic, Salesforce, Vietnam Offshore on Jun 11, 2020