小型IoT端末開発キット「SensorTile.box」 を使って機械学習を体験③　

今回は、実際にデータ（訓練データ）を収集してディシジョン･ツリーを作成してみます。
作業に入る前に、どのような動きを題材にするか考える必要がありますが、今回は無難な「人間のアクティビティ検知」を選びました。まずはシンプルに、

+ 静止状態（立っている or 座っている）
+ 歩行状態

を正しく検出できることを目標にします。

手首に取り付けるサンプルは既にありますので、今回は足首に取り付けてみます。
実験後に分かりましたが、足首装着の場合「付けている感覚（ストレス）」が少ないので、高齢者や入院患者さんへのモニタリングに向いていると感じました。
なお、予備知識として以下記事内の情報が必要です。


[小型IoT端末開発キット「SensorTile.box」 を使って機械学習を体験①](https://qiita.com/ykawano/items/9a78b5e6781e81e75ed2)
[小型IoT端末開発キット「SensorTile.box」 を使って機械学習を体験②](https://qiita.com/ykawano/items/fb3949fde6e7df8302d2)

今回のデータ収集および分析作業は、主にインターンシップ学生さんにご協力いただきました（感謝！）
モデルの評価は記事執筆者が行っています。


# 1. 作業の流れ

①でも解説した、各ステップを具体的に表にまとめました。
何度か試していくと自然に分かりますが、”データ収集→データ･ラベリング→機械学習の実行”では、各ステップ内のパラメータ設定がお互い密接に関係しています。


|ステップ     |内容      |使用ツール／HW     |
|:------------:|:---------|:--------:|
|データ収集 |STBLESensorアプリから、SensorTile.boxをデータ記録モード（Log>Data recorder）にセット。<BR>SensorTile.boxを足首に取り付け、データ収集実施。　|STBLESensor／スマートフォン|
|データ･ラベリング| 1. Unico-GUIに、収集したデータファイルをLoad。<BR>2. ディシジョン･ツリー作成のためのConfigurationを設定。<BR>3. データの特徴を見ながら、判定に有効と思われる **“Features”（特徴量）** を選択。<BR>ここまでの入力作業後にarffファイルが生成されるので、これを使って別の機械学習ツール上でディシジョン･ツリーを作成することも可能。|[Unico-GUI](https://www.st.com/ja/development-tools/unico-gui.html)／PC|
|機械学習の実行 |**「ディシジョン･ツリー（決定木）」** の作成（ツール側で自動生成）|[Unico-GUI](https://www.st.com/ja/development-tools/unico-gui.html)／PC|
|センサ用ファイルの生成|最終的なディシジョン･ツリー情報を含む、センサ書き込み用ファイル（xxxx.ucf: Unico Configuration File）を出力|[Unico-GUI](https://www.st.com/ja/development-tools/unico-gui.html)／PC|
|テスト<BR>（動作確認）|生成されたucfファイルをスマートフォンにコピーし、機械学習アプリをExpert Modeにてセット。<BR>再び足首に取り付けて各種動作を行い、正しく判定されるかどうかテスト。|STBLESensor／スマートフォン|

この記事では、「データ収集」～「センサ用ファイルの生成」まで実行します。



# 2. 準備


[SensorTile.box](https://www.st.com/ja/evaluation-tools/steval-mksbox1v1.html)を初めて使用する方は、セットアップ方法や基本情報についてこちらの記事を参照してください。
[小型IoT端末開発キット「SensorTile.box」 をセンサ・アプリで使ってみた①　セットアップと使い方](https://qiita.com/ykawano/items/9aed0be1ca919ad4551d)


## 2-1. Unico-GUIのダウンロード & インストール

まずは、[Unico-GUI](https://www.st.com/ja/development-tools/unico-gui.html)をこちらのページからダウンロードして、パソコンにインストールしておきます。STBLESenoer（スマートフォン･アプリ）は、前回の記事までで、セットアップ内容を説明済みなのでここでは省略します。

![001_Unico-gui_stcom1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/1f87a595-37f8-d226-c296-bc0b19be2f7e.png)

使用するパソコンのOSに応じてソフトウェアを選択

![002_Unico-gui_stcom2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/6b21daf9-f72a-9bd8-52e0-af2ae5ccaf34.png)




インストールが完了しましたら、STBLESensorをセットアップします。

## 2-2. アプリのセットアップ

スマートフォンでSTBLEsebnsorを起動し、以下手順でData recorderアプリをセットアップします。

![100_stblesensor_app1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/0b276f4f-5a60-3272-c6de-115e95a957d0.png)

Data Recorderアプリはデフォルト設定でも問題ないですが、一応少し変更してみます。
MLC用途ではLSM6DSOXのみ使用しますので、Vibrometer accelerometer（=IMU xxx）センサのみオンにします。

![101_stblesensor_app2_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/f8d82720-56d1-3a32-bcdf-3d455f856947.png)


センサ･データの設定について、今回のMLC題材に合うように調整します。アプリケーションノート[AN5259](https://www.st.com/ja/mems-and-sensors/lsm6dsox.html#documentation)の中にActivity recognition（サンプル例のひとつ）の設定例があるのでこちらを参考にしてみます。

![102_AN5259_table10_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/d9e4e0f2-b3d9-2680-d9a4-395dfbfce9e0.png)


図内ピンク枠部分にODR（MLC_ODR） = 26Hzと記載されています。歩行やジョギング程度であればこの程度の出力レートが適切なのでしょう。
また、上のサンプルだとフルスケール = 4g設定のようですが、今回は歩く程度の動きを想定しているので、デフォルト値（= 2g）のまま進めます。


+ センサODR: **26Hz**　（1.6 / 12.5 / 26 / 52 / 104 / 208 から選択（Low Power mode））
+ フルスケール: **2g**　（2 / 4 / 8 / 16 から選択）

ここで設定するODRは、センサ･データの出力レートですが、MLCのFeatures演算用に渡す際のデータ･レートは別に設定することができます（後ほどUnico-GUIで設定するMLC用のODR（MLC_ODR））。ただ、基本的な使い方としては同じ値にしますので、ここでは同義と考えてください。MLC_ODRは4択のみ（12.5 / 26 / 52 / 104Hz）なので、結局センサODRもこの4つから選ぶことになります。
というわけでODRの数値のみ変更し、保存先をSDカードとします。


![103_stblesensor_app3_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/78f33317-4f7e-f71b-4444-fe3eddea5349.png)


アプリ名を”Data recorder acc SD”として新規登録しました。アップロードして準備完了です。

![104_stblesensor_app4_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/1779848c-6a1c-ef52-55d8-e150ac78d816.png)


# 3. データ収集

## 3-1. 学習用データ（訓練データ）の収集

それでは実際にデータを収集していきます。
SensorTile.box取り付け位置と設置方向は下図の通りです。

![200_setup_ankle.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/e0ab98f8-d832-a97e-e6dc-8a06457c1a7c.png)

STBLESensorでSensorTile.boxに接続して記録開始。1動作ごとに記録･保存します。

![201_stblesensor_log.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/df87db39-aa51-5603-de98-b170854f3288.png)


最終的にLSM6DSOXにucfファイルを書き込むので、Unico-GUI上でのXYZ軸方向とLSM6DSOXの軸方向が一致している必要があります。
注意点：_今回はSTBLESensorのData recorderアプリで加速度データを収集しましたが、データの中身を確認したところXYZ軸方向がセンサ本体（LSM6DSOX）から見たXYZ軸方向と異なっていました。出力記録される際に、SensorTile.box本体として設定されたXYZ方向に軸変換されているようです。このデータを元にUCFファイルを作成してLSM6DSOXに入力すると、実際に動いた方向と異なるモデルになってしまいます。
もともと設置方向がフリーなモデルを対象とする場合にはおそらく問題ありませんが、ここでは念のため軸データを編集して入力しました。具体的にデータをご自身で収集する場合、記事④で説明予定の 補足情報 を参考にしてください。_


静止状態（stop）と歩行状態（walk）の2択を想定しましたが、各状態においても様々な動きのケースが考えられます。静止時/歩行時においてそれぞれ5回ずつ、以下動作パターンでデータ収集してみました。1回の記録は約10秒間です。

|トライアル（データサンプリング）/ファイル名     |動作内容      |クラス名（判定種別）    |
|:------------:|:---------:|:--------:|
|静止1 / stop1.csv|立って静止|stop|
|静止2 / stop2.csv|（イスに座って）貧乏ゆすり|stop|
|静止3 / stop3.csv|（イスに座って）足を伸ばしてリラックス|stop|
|静止4 / stop4.csv|（イスに座って）膝を曲げる・角度A|stop|
|静止5 / stop5.csv|（イスに座って）膝を曲げる・角度B|stop|
|歩行1 / walk1.csv|通常歩行|walk|
|歩行2 / walk2.csv|通常歩行|walk|
|歩行3 / walk3.csv|杖をついて歩く|walk|
|歩行4 / walk4.csv|ゆっくり歩行・速度A|walk|
|歩行5 / walk5.csv|ゆっくり歩行・速度B|walk|

SensorTile.boxをパソコンに接続すると、内蔵SDカードに保存されたデータファイル（.csv）にアクセスできます。エクセル上でグラフ化すると下図のようになります。横軸は時間軸で、ODR = 26Hzでデータを取ったため、260サンプル分で約10秒間になります。

##### 静止時のデータ例（直立）

![210_stop1_graph_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/ea0bbac7-9483-748c-5e14-c39b57cd99ee.png)

##### 歩行時のデータ例

![211_walk1_graph_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/54d7ddbc-0b55-d2f3-9c12-36676b42903f.png)



何度かディシジョン･ツリーを作成した後に気づきましたが、センサ･データのグラフを作って可視化しておくと、後ほどUnico-GUIを使ってFeaturesを設定する際に役立ちます。
足首へ取り付ける際、X軸が足軸方向、Y軸が歩行時の進行方向を向くかたちになるので、足の着地および前後に振る動きがグラフから伺えます。センサのフルスケール = 2gとしましたので、±2gを超える値は記録されていません。今回は歩行程度だったため波形的に問題はなさそうですが、加速度的により大きな動きを想定する場合は、フルスケール･レンジを大きく設定した方が良さそうです。



次に、収集したデータを使ってディシジョン･ツリーを作成していきます。


# 4. 機械学習作業

### 4-1. データ･ラベリング

##### Unico-GUI起動
まず、Unico-GUIを起動します。
検索ボックスに“ox”などと入力するとSensorTile.box内のセンサ型番“LSM6DSOX”が表示されるので、ここで[STEVAL-MKI197V1](https://www.st.com/ja/evaluation-tools/steval-mki197v1.html)を選択します。STEVAL-MKI197V1はLSM6DSOXの評価ボードで、MEMSセンサ用の標準評価ボード（MEMSマザー･ボード: [STEVAL-MKI109V3](https://www.st.com/ja/evaluation-tools/steval-mki109v3.html)）と一緒に使用します。今回マザー･ボードは使用しないので、左下の“Communication with the Motherboard”のチェックを外します。今回は機械学習作成用途としての利用になります。
最後にSelect Deviceをクリックして次に進みます。

![300_unico_start_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/a6146dc0-5586-3b6b-dcd2-0db4fee69f42.png)



左側のMLC（Machine Learning Core）ボタンをクリックして作業用ウインドウを開きます。

![301_unico_MLCopen.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/12aec897-bbb7-063e-2c66-dbd09f26fca8.png)


##### データ入力 & データ･ラベリング

以下手順で1ファイルごとに入力していきます。ファイル指定ごとにクラス名（結果ラベル）も入力する必要があります。ここでは静止時を“stop”、歩行時を“walk”としてラベリングしました。

![302_unico_MLCinput_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/ff0eab84-4f78-8df5-f558-b4b886da5440.png)


stop1~5とwalk1~5の計10ファイルを入力したら次に進みます。

### 4-2. 機械学習の実行

#### 4-2-1. Configurationセットアップ

ここから具体的に、ディシジョン･ツリー作成のためのコンフィギュレーションをセットしていきます。
Features以外の基本設定部分は以下の通りです。

|Configuration    |内容      |設定例   |
|:------------:|:---------:|:--------:|
|Device |対象センサ | LSM6DSOX（固定）|
|Machine Learning Core ODR（MLC_ODR） |MLCに入力するセンサのデータ･レート<BR>（12.5 / 26 / 52 / 104） |26Hz |
|Machine Learning Core Input |MLCに入力するセンサを選択（ここでは加速度のみ選択） |Accelerometer only|
|Accelerometer Full scale |加速度センサのフルスケール（STBLESensorアプリ内設定値と合わせる）<BR>（2 / 4 / 8 / 16） |2g|
|Accelerometer ODR |加速度センサの出力ODR（STBLESensorアプリ内設定値と合わせる） |26Hz|
|Decision trees |ディシジョン･ツリー数<BR>（1 ~ 8） |1|
|Window Length |Window Length<BR>1回の判定に何個の連続データを使うかを設定するパラメータ（1 ~ 255） |52|
|Filter configuration |フィルタ<BR>MLC用に専用に用意されており、センサ･データに対してIIRフィルタ等を設定可能|（None）|


#### 4-2-2. 基本Configuration

各設定ごとに **Next** をクリックしてセットしていきます。なお、一度セットするとそこで決定となり、前に戻って修正などはできません。間違えた場合はResetをクリックして最初からやり直してください。今回は、ほぼデフォルト設定なので、Nextを連打して進めていきます。

![310_unico_config_set1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/1014d27d-476d-b6d1-6480-21bd158134e4.png)


ODRについては少しややこしいのですが、各センサ自体の出力データレートの設定とは別に、MLCに入力する際のセンサ･データのレートを設定できます。LSM6DSOX内の該当レジスタは以下のとおり。

+ 加速度センサODR: Register 10h -> CTRL_XL -> ODR_XL[3:0]
+ ジャイロODR: Register 11h -> CTRL2_G -> ODR_G[3:0]
+ MLC用ODR: Embedded function Register 60h -> EMB_FUNC_ODR_CFG_C -> MLC_ODR[1:0]

MLC_ODRは、ルール上は **各センサのODR以下** であればOKですが、**同じ値** に設定することを推奨します。
違う設定値の場合、データはフィルタ等無しで単に間引きされて（decimation）MLCコアに渡されるので、周波数応答の変化により精度に影響する可能性があります。

![311_unico_config_set2_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/d523ef43-3d37-5e75-106e-48a88ab06d57.png)


#### 4-2-3. Features（特徴量）

ここからは、機械学習の肝となるFeaturesの設定です。
パッと見たところ項目が沢山ありすぎて、どれを選べば良いのかわかりません。
ひとまず、主要と思われる以下5つを設定してみました。各Featuresに対してそれぞれ$XYZ$各軸と、$V$（2乗和平方根）、$V^2$がありますがここでは$XYZ$各軸と、$V$を選択してます。

+ Mean: 平均
+ Variance: 分散
+ Energy：エネルギー
+ Peak-to-Peak: ピーク･ツー･ピーク
+ Zero-Crossing: ゼロ･クロッシング

![312_unico_config_features_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/f54fa2b0-ed3e-065e-4d3f-17ef55a07b36.png)


#### 4-2-4. ARFFファイル生成（attribute-relation file format）

ここまで設定した内容に基づいて、入力データ（最初にLoadしたcsvファイル）をまとめた内容が.arffファイルとして生成 & 保存されます。他の機械学習ツールでこのファイルを読み込めば、同じようにディシジョン･ツリーを作成可能です。

![313_unico_config4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/5d412438-f4ef-efd8-7092-01f8d3f93f96.png)

以下は、ポジション検知サンプル（6D Position recognition: →[小型IoT端末開発キット「SensorTile.box」 を使って機械学習を体験①](https://qiita.com/ykawano/items/9a78b5e6781e81e75ed2)）でのarffファイル例です。

![314_unico_config_arff2_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/7081dd16-6596-78a7-b012-fdcf503b51a2.png)



##### 出力レジスタ設定

判定結果を数値として出力できます。LSM6DSOXのレジスタ、MLCx_SRC（0x70 ~ 0x77）への出力値として反映されます。0~15から任意に選択可能で、結果が区別できればどの数値を選んでも構いません。ここではStop = 0、Walk = 4のデフォルトのままとします。出力STBLEsensorアプリで評価の際、この数値結果 + ラベル名で確認できます。

![315_unico_config_result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/49065f20-e8b5-3d11-c114-d02e4ac35412.png)

以上でディシジョン･ツリー作成前の準備は全て完了です。

#### 4-2-5. 機械学習の実行

##### ディシジョン･ツリー作成

GENERATEをクリックするとディシジョン･ツリーの自動作成が開始されます。Decision Tree infoのところに表示された内容は、自動でテキスト保存されます（.arffファイルと同じフォルダ場所）。

![316_unico_config_generate.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/98b0de39-43ce-ff54-d3a6-d6e3a751e5fc.png)


##### 出力テキストデータ

![317_unico_decisiontree_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/20e5ebeb-d3e9-4648-0c70-6f132114d108.png)





Featuresを5つも設定したにも関わらず、条件式（test）として採用されたのは **“ACC_X軸のMean（平均値）”** だけでした。
ACC_X軸のMeanだけ使えば、“stop” or “walk”の区別判定はできるという解析結果のようです。

別の機械学習ツールで作成したディシジョン･ツリーを使用する場合、ここでそのテキストファイルをセットします。GENERATEをクリックせずに、Browseにてファイルを指定して次に進んでください。


### 4-3. ucfファイル作成（Unico Configuration File）

ディシジョン･ツリーが作成できたので、次はucfファイルの生成ステップに進みます。

##### Meta-classifier
Meta-classifierとは、一種のフィルタです。「Window Lengthおきに判定される結果が、x回連続で同じ結果となった時に最終結果として出力される」というものです。Window Lengthが短い、もしくはODRが高速である場合、判定結果が不安定（パタパタと短時間で変化する）となる可能性があるので、ここで調整できるのでしょう。詳細はアプリケーションノートAN5259の1.5 Meta-classifierの章を参照ください。
今回はデフォルトのゼロ値（=Tree判定結果が即最終結果に反映）で進めます。


![318_unico_config_metaclass.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/4d081e53-130e-0445-56a3-70785e578314.png)


##### ucfファイル生成

Browsクリックでucfファイル名を指定、保存します。

![319_unico_config_finish.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/01823a30-0993-4167-4e77-e843b587fbba.png)


以上で、動作確認前の準備はすべて完了しました。
次回は、作成したディシジョン･ツリーの評価テストを行います。
+ データ収集　　　　　　　完了✔
+ データ･ラベリング　　　　完了✔
+ 機械学習の実行　　　　　完了✔
+ センサ用ファイルの生成　完了✔
+ テスト（動作確認）　　　[次回へ続く](https://qiita.com/ykawano/items/741e92ebb8e4d0dd2dfc)