【Azure Synapse Analytics】データフローを使ったスライディングウィンドウによる特徴量抽出

# はじめに

[@arai-jin](https://qiita.com/arai-jin) さんの以下の記事で、PySpark を使ったスライディングウィンドウによる特徴量計算の方法が紹介されています。

[PySpark で時系列データの特徴量抽出する方法　基礎編](https://qiita.com/arai-jin/items/108baa7defa34bda0634)

Azure Synapse Analytics には データフローという GUI ベースの ETL 機能が備わっており、これも内部的には Spark の実行環境が動いています。ウィンドウ変換機能なども有しているため、今回は データフローを使いノンコーディングで処理が定義・実行できるかを試してみたいと思います。

なお、以降の記述において元記事と比較した内容・表現も出てくるため、元記事をまだご覧になっていない方はぜひ事前にご一読ください。それぞれの理解がより深まるかと思われます。

# 事前準備

以下を事前に済ませておきます。後半の 2 つについては、少し補足させていただきます。

- Synapse Workspase の作成
- 作成した Synapse Workspase へ Synapse Studio でログイン
- テスト用CSV ファイルの作成
- 作成した CSV ファイルを ADLS Gen2 にアップロード

## CSV ファイルの作成

元記事と同じデータの CSV ファイルを、今回も作成・使用します。

```csv
time,data1,data2,data3,data4
1,2.65,2.42,6.9,4.93
2,2.57,8.5,2.4,5.37
3,2.13,3.76,7.52,7.67
4,3.09,7.28,3.59,6.34
5,5.75,4.69,5.26,3.11
6,6.91,4.04,2.03,6.28
7,5.44,3.22,2.87,7.14
8,4.86,7.47,3.68,0.32
9,9.7,7.43,4.43,7.74
10,6.3,7.72,7.78,7.91
```

## 作成した CSV ファイルを ADLS Gen2 にアップロード

正確には、データフロー上で Datasets として認識できれば何でも良いのですが、今回は作成した Synapse Workspase で Primary アカウントとして設定している ADLS Gen2 上に CSV ファイルをアップロードしておきます。

# データフローの作成

ここから、本筋の設定に入っていきます。まずは、Synapse Studio の Develop Hub で`Data flow`をクリックします。
![20200901_orchestrate_anomaly_01_dataflow.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685288/293f0087-b0cd-7f19-5ba8-920ddf5bfb47.jpeg)

`Add Source`をクリックすると、以下の画面になります。今回は Datasets を新規作成するため`New`をクリックします。
![20200901_orchestrate_anomaly_02_dataflow.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685288/f629e5d0-f5a7-5234-0c99-5fa29d903558.jpeg)

`Azure Data Lake Storage Gen 2`を選択して`Continue`をクリック。
![20200901_orchestrate_anomaly_03_dataflow.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685288/712d0d79-f510-fd52-4347-cabab2c97cc5.jpeg)

`Delimited Text`を選択して`Continue`をクリック。
![20200901_orchestrate_anomaly_04_dataflow.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685288/63bb7abc-acd2-d380-8407-a75941d0ce25.jpeg)

アップロードした CSV ファイルが読み込めるよう、`Linked service`と`File path`を適切に設定。また、今回はヘッダー付きの CSV ファイルであるため、`First row as header`にチェックを入れておきます。
![20200901_orchestrate_anomaly_05_dataflow.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685288/0502c383-a147-4fdd-6fcd-857debb92975.jpeg)

CSV ファイルが読み込めると、Projection タブでスキーマが確認できます。デフォルトでは全ての列が string ですが、後続の処理のため time 列を`integer`、data1 列を`float`にそれぞれ変換しておきます。今回はテストデータの都合で time 列を integer としていますが、実データでは timestamp 型とした方がよろしいかと思います。
![20200901_orchestrate_anomaly_06_dataflow.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685288/6f6704a3-3274-df6c-0492-510bcad19609.jpeg)

設定が正常に完了すれば、Data preview タブで CSV ファイルのデータが確認できます。
![20200901_orchestrate_anomaly_07_dataflow.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685288/b9929603-0417-0079-205c-9a0fa0ac63f0.jpeg)

# ウィンドウ変換

ここまでの作業が完了したら、画面の+アイコンから`Window`をクリックしウィンドウ変換用の処理を追加します。
![20200901_orchestrate_anomaly_08_dataflow.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685288/abdef8e8-8c6e-63de-5e43-ad0992efead8.jpeg)

Window settings タブにおける`1. Over`を除く 2.から 4.を順に設定していきます。
![20200901_orchestrate_anomaly_09_dataflow.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685288/967545cd-1580-c7d8-da8e-a47d6584d069.jpeg)


## 2. Sort

ソートキーを指定するもので、PySpark における`orderBy("カラム名")`の記述に相当します。そのため、ここでは time 列を指定します。
![20200901_orchestrate_anomaly_10_dataflow.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685288/4f1ccee0-45c5-af8d-ec8f-f1035b964e7b.jpeg)


## 3. Range by

ウィンドウ幅を指定するもので、PySpark における`rowsBetween`の記述に相当します。幅の指定をスライダーと数値入力で行うのが特徴で、まずスライサーの左端を`Current row`にすることで Start offset が 0、つまり現在行を基準にします。次に右端を`In front`とし End offset に 4 を入力することで現在行を含めて 5 行を 1 つのウィンドウとして定義することになります。
![20200901_orchestrate_anomaly_11_dataflow.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685288/78895ef9-ccaa-43f2-4f72-bf87df80ee0d.jpeg)

## 4. Window columns

特徴量抽出の結果を新しい列として定義します。PySpark における`withColumn('feat_max_data1', F.max('data1').over(sliding_window))`といった記述に相当します。PySpark 同様、こちらでも計算の種類の数だけ列を定義する必要があります。
![20200901_orchestrate_anomaly_12_dataflow.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685288/1449c679-33ae-0295-5f4c-516fee46671d.jpeg)

なお、本記事では深くは触れませんが、特徴量抽出で使う関数の記述においては式ビルダーを使うことで入力補助を受けながら記述することが可能となっています。
![20200901_orchestrate_anomaly_13_dataflow.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685288/5c984092-3fb1-2d12-287c-3031676362d8.jpeg)

# 結果確認

ウィンドウ変換の処理後、Data preview タブで特徴量抽出の結果を確認することができます。画面では見やすくするため後続に Select 処理を加えて data2 ～ 4 を省いていますが、変換処理の結果自体は Window 処理の時点で確認可能です。
![20200901_orchestrate_anomaly_14_result.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685288/28f4d02e-a511-41ee-b90a-d07b20468469.jpeg)

# まとめ

Azure Synapse Analytics のデータフローを使うことで、スライディングウィンドウによる特徴量計算がノンコーディングでできることを確認しました。

データサイエンティストの方であれば慣れ親しんだPythonでコーディングするだけかもしれませんが、今回のような特徴量抽出は案件の体制によってはデータエンジニアやクラウドアーキテクトが担当することも考えられ、そういった人々にとってはPySpark相当の処理をGUIを使ってノンコーディングで定義・実行できるというのは魅力的ではないかと思います。

# 参考URL

[マッピング データ フローのウィンドウ変換](https://docs.microsoft.com/ja-jp/azure/data-factory/data-flow-window)