LoginSignup
6
8

More than 3 years have passed since last update.

スマホの加速度センサで行動識別してみた

Last updated at Posted at 2019-07-17

はじめに

前回投稿した誰でもできちゃうSVMによるパターン認識で、SVMによるパターン認識を実装しました。
本記事では、前回作成したプログラムを使って、スマートフォンの加速度センサから行動を分類したいと思います。

具体的には、以下の4状態を学習させ、モデルを生成し、テストデータが正しく分類されるか確認します。

  • スマホを机の上に置き、静止させた時のデータ
  • スマホを手で持ち、全力で振った時のデータ
  • スマホをポケットに入れて、歩いた時のデータ
  • スマホをポケットに入れて、走った時のデータ

環境

使用スマートフォン

iPhoneX【iOS 12.3.1】

使用アプリ

加速度ロガーを使用させていただきます。
サンプリング周波数は、100Hzに設定しました。

学習データの準備

測定

今回は、各状態を10秒以上測定して、1000サンプルづつ(計4000サンプル)用意しました。

前処理

入力データの項目は、以下の3つにしました。

  • 3軸の合成加速度(以降、合成加速度)
  • 直近10サンプルの合成加速度の平均(以降、移動平均)
  • 直近10サンプルの合成加速度の標準偏差(以降、移動標準偏差)

スマホの向きを意識しないために、合成加速度を算出しました。
以下の式で合成加速度を算出することができます。

(合成加速度) = \sqrt{(x軸の加速度)^2 + (y軸の加速度)^2 + (z軸の加速度)^2}

移動平均と移動標準偏差は以下のようにexcelで算出しました。
excel.png

この状態でcsvで保存

必要ない項目(HHmmss,x,y,z)と項目名を削除

1000サンプルに調整

この手順で、4種類のデータの前処理を行います。

最終的に、以下のようなデータが出来上がると思います。

learning_data.csv
1.00110588850531,1.0013994655249,0.000458744411473901,1
1.00210229018798,1.00139911591093,0.000458969293511815,1
1.00209231111709,1.00119778649611,0.000540661891005046,1
                  (997サンプル省略)
3.7148344512239,5.48437407500024,2.1345990737057,2
2.68436305294198,5.44778885322339,2.16749567720329,2
2.53429714122082,5.41660172074124,2.20888159457746,2
                  (997サンプル省略)
1.6548153975595,1.12418356215442,0.643001802938213,3
1.66477025441951,1.04119371895031,0.622384960951361,3
1.81568444394944,0.981822482334172,0.587403194733536,3
                  (997サンプル省略)
3.18631856536662,2.63215261941083,1.53650426566909,4
2.39536489913332,2.62277489846566,1.53271874591551,4
1.25657033229342,2.61339717752049,1.53891923881491,4
                  (997サンプル省略)

左から、合成加速度、移動平均、移動標準偏差、正解データ
正解データは、以下のようになっています。

  • 1 ... スマホを机の上に置き、静止させた時のデータ
  • 2 ... スマホを手で持ち、全力で振った時のデータ
  • 3 ... スマホをポケットに入れて、歩いた時のデータ
  • 4 ... スマホをポケットに入れて、走った時のデータ

テストデータの準備

4状態のデータを新たに測定します。
学習データ同様、合成加速度・移動平均・移動標準偏差を算出。
4状態のテストデータを以下のように、500サンプルで準備しました。

test_stop.csv(スマホを机の上に置き、静止させた時のデータ)
0.999313264196968,1.00080864557593,0.00120620913504573
0.999264729688785,1.00110610743585,0.00116689958774459
1.00231182772628,1.00120848030656,0.00103873107094196
                  (497サンプル省略)
test_shake.csv(スマホを手で持ち、全力で振った時のデータ)
0.999313264196968,1.00080864557593,0.00120620913504573
0.999264729688785,1.00110610743585,0.00116689958774459
1.00231182772628,1.00120848030656,0.00103873107094196
                  (497サンプル省略)
test_walk.csv(スマホをポケットに入れて、歩いた時のデータ)
0.999313264196968,1.00080864557593,0.00120620913504573
0.999264729688785,1.00110610743585,0.00116689958774459
1.00231182772628,1.00120848030656,0.00103873107094196
                  (497サンプル省略)
test_run.csv(スマホをポケットに入れて、走った時のデータ)
0.999313264196968,1.00080864557593,0.00120620913504573
0.999264729688785,1.00110610743585,0.00116689958774459
1.00231182772628,1.00120848030656,0.00103873107094196
                  (497サンプル省略)

左から、合成加速度、移動平均、移動標準偏差になっています。

コードの編集

500サンプル中の正解数を表示するために、前回のコードを少し編集します。
編集する箇所は、
- estimateメソッド
- 学習データとテストデータのパス

main.js
/**
 * モデルからテストデータの分類を行う関数
 * @param {Array.<Array.<number>>} テストデータ
 */
function estimate(arr) {
    if(newModel) {  // モデルのnullチェック
        var result = Array(arr.length);
        for(var i=0; i<arr.length; i++) {
            result[i] = newModel.predictSync(arr[i]);   // モデルからテストデータを分類
            // console.log(result[i]);                     // 結果の表示
        }
        var result1 = 0,
            result2 = 0,
            result3 = 0,
            result4 = 0;
        for(var i=0; i<result.length; i++) {
            switch(result[i]) {
                case 1:
                    result1++;
                    break;
                case 2:
                    result2++;
                    break;
                case 3:
                    result3++;
                    break;
                case 4:
                    result4++;
                    break;
            }
        }
        console.log("1... " + result1 + "/" + result.length);
        console.log("2... " + result2 + "/" + result.length);
        console.log("3... " + result3 + "/" + result.length);
        console.log("4... " + result4 + "/" + result.length);
    }
}

結果

4状態のテストデータの分類結果は、以下のようになりました。

$ node main.js # 1...スマホを机の上に置き、静止させた時のデータ
1... 500/500
2... 0/500
3... 0/500
4... 0/500
$ node main.js # 2...スマホを手で持ち、全力で振った時のデータ
1... 0/500
2... 486/500
3... 0/500
4... 14/500
$ node main.js # 3...スマホをポケットに入れて、歩いた時のデータ
1... 67/500
2... 0/500
3... 397/500
4... 36/500
$ node main.js # 4...スマホをポケットに入れて、走った時のデータ
1... 0/500
2... 11/500
3... 145/500
4... 344/500

そこそこの精度ですね!

最後に

今回は、そこそこの精度で4つの行動を分類することができました。
精度をあげるために、出来ることはいくつかあると思いますが、今回はここらへんで一度辞めたいと思います。

6
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
8