このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。
信号の特徴抽出と機械学習を使用した行動認識
この例では、スマートフォンの加速度計信号から特徴を抽出し、機械学習アルゴリズムを使用して人の行動を分類する方法を説明します。データの特徴抽出は、signalTimeFeatureExtractor
オブジェクトおよび signalFrequencyFeatureExtractor
オブジェクトを使用して行います。この特徴を、サポート ベクター マシン (SVM) モデルの学習に使用します。
データ セット
Sensor HAR (行動認識) アプリ [1] を使用して、[2] の加速度計の生の信号を収集しました。5 種類の身体活動を行う間、被験者はスマートフォンを身に着けていました。データ セットをバッファーし、特定の活動に対応する 44 サンプル長の信号を取得しました。データ セットの "ダンス" 活動および y
方向と z
方向の加速度計信号は除外し、BufferedHumanActivity データ セットを作成して、この例で使用する BufferedHumanActivity.mat
ファイルに保存しました。
BufferedHumanActivity データ セットを読み込みます。
load BufferedHumanActivity.mat
このデータ セットには 7776 個の x 方向の加速度計信号が格納されています。各信号の持続時間は 44 サンプル分あり、4 種類の身体活動 ("座る"、"立つ"、"歩く"、"走る") のいずれかに対応しています。このデータ セットには、以下の変数が含まれています。
atx
— x 方向の固定長バッファー済み加速度計センサー データ (44 行 7776 列の行列)actid
— 応答ベクトル。整数で表される活動 ID を含みます。整数 1、2、3、4 は、それぞれ "座る"、"立つ"、"歩く"、"走る" を意味します。actnames — 各活動 ID に対応する活動名のリスト
fs
— 加速度計センサー データのサンプル レート
特徴抽出
加速度計信号には、2 つの主成分が含まれていると考えられます。その 1 つが、身体のダイナミクス (被験者の身体の動き) によって発生する "速い" 経時変動です。もう 1 つが、垂直な重力場に対する身体の位置によって発生する "遅い" 経時変動です。
遅い信号変動から速い信号変動を分離するため、元の信号に対してハイパス フィルターを適用します。signalTimeFeatureExtractor
オブジェクトと signalFrequencyFeatureExtractor
オブジェクトを使用して、フィルター処理された信号とフィルター処理されていない信号からさまざまな特徴を抽出します。これらのオブジェクトにより、1 回の関数呼び出しで時間領域と周波数領域の複数の特徴を効率よく計算できます。
% Filter the signals with a highpass filter
atxFiltered = highpass(atx,0.7,fs);
時間の特徴の場合は、2 つの signalTimeFeatureExtractor
オブジェクトが構成されます。1 つを使用して、フィルター処理されていない信号の平均を抽出し (meanFE
)、もう 1 つを使用して、フィルター処理された信号の平方根平均二乗、形状係数、ピーク値、クレスト ファクター、クリアランス係数、インパルス係数を抽出します (timeFE
)。
meanFE = signalTimeFeatureExtractor("Mean",true,"SampleRate",fs); timeFE = signalTimeFeatureExtractor("RMS",true,... "ShapeFactor",true,... "PeakValue",true,... "CrestFactor",true,... "ClearanceFactor",true,... "ImpulseFactor",true,... "SampleRate",fs);
周波数の特徴の場合は、signalFrequencyFeatureExtractor
を使用して、フィルター処理された信号の周波数平均、帯域パワー、パワーが半分の帯域幅、ピーク振幅、およびピーク位置を抽出します。
freqFE = signalFrequencyFeatureExtractor("PeakAmplitude",true,... "PeakLocation",true,... "MeanFrequency",true,... "BandPower",true,... "PowerBandwidth",true,... "SampleRate",fs);
さらにパラメーターを設定することで、スペクトル ピークの計算を調整できます。たとえば、ピークの最大数が 6、各スペクトル ピーク間の最小距離が 0.25 Hz に設定されているとします。さらに、256 の FFT 長および 44 サンプル (すなわち、信号長) の箱型ウィンドウを選択し、スペクトル推定を計算します。
fftLength = 256; window = rectwin(size(atx,1)); setExtractorParameters(freqFE,"WelchPSD","FFTLength",fftLength,"Window",window); mindist_xunits = 0.25; minpkdist = floor(mindist_xunits/(fs/fftLength)); setExtractorParameters(freqFE,"PeakAmplitude","MaxNumExtrema",6,"MinSeparation",minpkdist); setExtractorParameters(freqFE,"PeakLocation","MaxNumExtrema",6,"MinSeparation",minpkdist);
すべての信号の特徴の計算は、変換後の配列データストアを使用して並列化できます。特徴抽出器オブジェクトの関数 extract
を使用して、データストアが各行列の列を読み取り、特徴を計算します。
meanFeatureDs = arrayDatastore(atx,"IterationDimension",2); meanFeatureDs = transform(meanFeatureDs,@(x)meanFE.extract(x{:})); timeFeatureDs = arrayDatastore(atxFiltered,"IterationDimension",2); timeFeatureDs = transform(timeFeatureDs,@(x)timeFE.extract(x{:})); freqFeatureDs = arrayDatastore(atxFiltered,"IterationDimension",2); freqFeatureDs = transform(freqFeatureDs,@(x)freqFE.extract(x{:}));
Parallel Computing Toolbox がインストールされている場合は、"UseParallel
" オプションを true に設定して変換後のデータストアの readall
メソッドを呼び出し、ワーカーのプール間で計算を分散させます。結果として得られる計算された特徴は結合され、7776 個の信号観測値のそれぞれについて 22 個の特徴が得られることになります。
meanFeatures = readall(meanFeatureDs,"UseParallel",true);
Starting parallel pool (parpool) using the 'Processes' profile ... Connected to parallel pool with 8 workers.
timeFeatures = readall(timeFeatureDs,"UseParallel",true); freqFeatures = readall(freqFeatureDs,"UseParallel",true); features = [meanFeatures timeFeatures freqFeatures];
抽出された特徴を使用した SVM 分類器の学習
特徴と活動ラベルを分類学習器アプリにインポートして、SVM 分類器を学習させることができます。あるいは、特徴 (予測子) と活動ラベル (応答) を含む、以下のような特徴テーブルを使用して、SVM テンプレートと分類器を作成することもできます。
まず、予測子と応答を含むテーブルを作成します。
featureTable = array2table(features); actioncats = categorical(actnames)'; featureTable.ActivityID = actioncats(actid); head(featureTable)
features1 features2 features3 features4 features5 features6 features7 features8 features9 features10 features11 features12 features13 features14 features15 features16 features17 features18 features19 features20 features21 features22 ActivityID _________ _________ _________ _________ _________ _________ _________ _________ _________ __________ __________ __________ __________ __________ __________ __________ __________ __________ __________ __________ __________ __________ __________ -73.408 0.10678 1.2695 0.24501 2.2946 3.5282 2.913 3.1208 0.011402 0.22658 0.0037348 0.0043388 0.0049913 0.014314 0.0032949 0.0042457 0.74219 1.6797 3.2031 3.8281 4.2188 4.5703 Sitting -73.43 0.06735 1.2521 0.13304 1.9753 2.9553 2.4733 1.8959 0.004536 0.18083 0.0078615 0.001071 0.0046553 0.0023938 0.0017709 0.002039 0.74219 1.25 1.5625 2.3438 3.5938 3.9453 Sitting -73.41 0.0626 1.303 0.15569 2.487 3.9603 3.2407 2.4191 0.0039188 0.18783 0.0036916 0.001265 0.00086816 0.00098286 0.0029621 0.0044119 0.74219 1.4062 2.2266 2.7734 3.0859 4.6094 Sitting -73.393 0.072056 1.3457 0.20023 2.7788 4.6384 3.7394 2.9361 0.005192 0.21444 0.0028194 0.0016623 0.0028484 0.0018433 0.003666 0.0026144 0.89844 1.6797 2.3047 3.2422 4.0234 4.6484 Sitting -73.409 0.080133 1.3786 0.21548 2.689 4.602 3.7069 3.2548 0.0064214 0.2053 0.0035392 0.0015361 0.0061205 0.0010848 0.0072086 0.0055945 1.5625 2.3828 3.0469 3.5156 3.8672 4.6484 Sitting -73.43 0.071148 1.1902 0.13832 1.9441 2.6268 2.3139 3.0519 0.0050621 0.25175 0.0022982 0.0027692 0.0040954 0.0045089 0.0016846 0.003589 0.82031 2.3047 3.1641 3.9062 4.2188 4.5312 Sitting -73.441 0.091667 1.169 0.19139 2.0879 2.7515 2.4408 2.8127 0.0084028 0.25907 0.0021497 0.0029254 0.0035706 0.0018514 0.015439 0.0030516 0.89844 2.1094 2.3828 2.6562 3.0859 4.5703 Sitting -73.419 0.10858 1.1976 0.20506 1.8886 2.5625 2.2619 2.3954 0.011789 0.17288 0.010823 0.0088772 0.0078451 0.0071845 0.0066219 0.0024052 0.74219 1.5625 2.2656 3.0469 3.8281 4.5312 Sitting
信号の 75% を学習用、25% をテスト用に割り当て、データセットを分割します。関数 cvpartition
を使用して、各区画に活動ラベルが同じような比率で含まれるようにします。
% Extract predictors and response predictors = featureTable(:, 1:end-1); response = featureTable.ActivityID; % For reproducible results rng default % Partition the data and extract training predictors and response data cvp = cvpartition(response,'Holdout',0.25); trainingPredictors = predictors(cvp.training, :); trainingResponse = response(cvp.training, :); % Train the classifier template = templateSVM(... 'KernelFunction', 'polynomial', ... 'PolynomialOrder', 2, ... 'KernelScale', 'auto', ... 'BoxConstraint', 1, ... 'Standardize', true); classificationSVM = fitcecoc(... trainingPredictors, ... trainingResponse, ... 'Learners', template, ... 'Coding', 'onevsone', ... 'ClassNames',actioncats);
テスト区画の分類器をテストし、その分類精度を解析します。
% Extract test predictors and response data testPredictors = predictors(cvp.test, :); testResponse = response(cvp.test, :); % Predict activity on the test data testPredictions = predict(classificationSVM,testPredictors); % Plot the confusion matrix to analyze performance of the classifier figure cm = confusionchart(testResponse, testPredictions, ... ColumnSummary="column-normalized", RowSummary="row-normalized");
accuracy = trace(cm.NormalizedValues)/sum(cm.NormalizedValues, "all"); fprintf("The classification accuracy on the test partition is %2.1f%%", accuracy*100)
The classification accuracy of the classifier on the test partition is 95.0%
誤差の大半は、走るを歩くに、立つを座るに誤分類した場合に発生します。
まとめ
この例では、signalTimeFeatureExtractor
および signalFrequencyFeatureExtractor
を使用して、スマートフォンのセンサー信号に基づいて人の行動の特徴を抽出する方法を確認しました。抽出された特徴を使用して SVM モデルの学習を行ったところ、約 95% の精度が得られました。別の方法として、featureInput
層を使用して深層学習分類器の学習を確認することもできます。
参考文献
[1] El Helou, A. Sensor HAR recognition App. MathWorks File Exchange https://www.mathworks.com/matlabcentral/fileexchange/54138-sensor-har-recognition-app
[2] El Helou, A. Sensor Data Analytics. MathWorks File Exchange https://www.mathworks.com/matlabcentral/fileexchange/54139-sensor-data-analytics-french-webinar-code
参考
アプリ
- 分類学習器 (Statistics and Machine Learning Toolbox)
関数
fitcecoc
(Statistics and Machine Learning Toolbox) |fitcsvm
(Statistics and Machine Learning Toolbox) |signalDatastore