質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Jupyter

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

4105閲覧

(x,y,z)の3軸での加速度を用いた活動体位の予測の機械学習のデータの前処理について

hidebonneidee

総合スコア1

Jupyter

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/05/15 14:17

(x,y,z)の3軸での加速度を用いた活動体位の予測の機械学習について

こんにちは、Pythonを学び始めて1ヶ月の初心者です。とても初歩的なことかもしれないのですが質問させてください。
オンラインコースの課題で上記のような予測をするプログラムを作成するというものがあり、取り組んでいます。実装してみたのですが、制度がまったく出ず困っています。入力の値や各層の実装については問題ないと思うのですが、出力を見てみると結果的に全て一つの答えのみになってしまっています。どこが問題なのか等アドバイスをいただければ幸いです。Pythonは自学のみであり、周りに聞ける人もおらず八方塞がりなのでヒントだけでもいただけましたら幸いです。よろしくお願いいたします。

課題の詳細です。
このプロジェクトでは、スマートフォンの3軸加速度計データから身体活動のタイプ(例、歩く、階段を上る)を予測しようとします。

入力データ
このプロジェクトのトレーニングに使用される入力データは、2つのファイルで構成されています。最初のファイルtrain_time_series.csvには、収集された生の加速度計データが含まれており、その形式は次のとおりです。

タイムスタンプ、UTC時間、精度、x、y、z

タイムスタンプ列を時間変数として使用できます。また、ここではx、y、zとラベル付けされた最後の3つの列も必要です。これらは、3つの直交軸のそれぞれに沿った線形加速度の測定値に対応しています。

2番目のファイルtrain_labels.csvには身体活動のラベルが含まれており、これらのラベルを使用してモデルをトレーニングします。身体活動にはそれぞれ整数で番号が付けられています。1 =立つ、2 =歩く、3 =階段を下る、4 =階段を上がる、の4項目です。加速度計は高周波数でサンプリングされるため、train_labels.csvのラベルは、train_time_series.csvの10回ごとの観測に対して提供されます。

活動分類
目標は、さまざまな身体活動をできるだけ正確に分類することです。コードをテストするために、test_time_series.csvというファイルも提供され、プロジェクトの最後に、このテストデータセットのコードによって予測されるアクティビティラベルを提出します。コーススタッフだけがテストデータに対応する真のラベルを持ち、コードの正確さは正しい分類のパーセンテージとして決定されます。どちらの場合も、トレーニングとテストの場合、入力ファイルは単一(3次元)の時系列で構成されていることに注意してください。コードの精度をテストするには、予測をCSVファイルとしてアップロードするように求められます。 test_labels.csvと呼ばれるこのファイルは提供されていますが、予測に必要なタイムスタンプのみが含まれています。対応するクラス予測(1、2、3、4)を追加して、このファイルを拡張する必要があります。

該当のソースコード

Python

1 2%matplotlib inline 3 4import numpy as np 5import pandas as pd 6import matplotlib.pyplot as plt 7 8 9 10def to_input(df): 11 df["synthetic_acce"]=np.sqrt(df.x**2+df.y**2+df.z**2) 12 #合成加速度を計算しn×10行列を作成します 13 #まず、入力データは10こで1つの動きを規定しています。(ex.入力データのインデックス0−9が一つの対位(座る)) 14 #そのため、1サンプルを10この要素を含む配列に変換します。 15 #そのためのインデックス として以下を書きます 16 index = df.index 17 index_s1= index[index%10==1] 18 index_s2= index[index%10==2] 19 index_s3= index[index%10==3] 20 index_s4=index[index%10==4] 21 index_s5=index[index%10==5] 22 index_s6=index[index%10==6] 23 index_s7=index[index%10==7] 24 index_s8= index[index%10==8] 25 index_s9= index[index%10==9] 26 index_s10= index[index%10==0] 27 #標準化させるために平均と標準偏差を計算します。 28 ave_input=np.array([np.average(df.synthetic_acce[i:i+10]) for i in range(0,len(df.synthetic_acce),10)]) 29 std_input=np.array([np.std(df.synthetic_acce[i:i+10]) for i in range(0,len(df.synthetic_acce),10)]) 30 #合成加速度の値を作ったインデックスを利用して取り出しそれぞれを標準化させます 31 s1=(df.synthetic_acce.values[index_s1] - ave_input) / std_input 32 s2= (df.synthetic_acce.values[index_s2]- ave_input) / std_input 33 s3=(df.synthetic_acce.values[index_s3]- ave_input) / std_input 34 s4=(df.synthetic_acce.values[index_s4]- ave_input) / std_input 35 s5=(df.synthetic_acce.values[index_s5]- ave_input) / std_input 36 s6= (df.synthetic_acce.values[index_s6]- ave_input) / std_input 37 s7=(df.synthetic_acce.values[index_s7]- ave_input) / std_input 38 s8= (df.synthetic_acce.values[index_s8]- ave_input) / std_input 39 s9= (df.synthetic_acce.values[index_s9]- ave_input) / std_input 40 s10= (df.synthetic_acce.values[index_s10]- ave_input) / std_input 41 #計算した10この要素を積み重ねn×10の行列を作成します 42 43 c=np.vstack((s1,s2,s3,s4,s5,s6,s7,s8,s9,s10)).T 44 #特徴を増やすために上記の操作をx軸、y軸、z軸でも行います。インデックスはそのまま使用しています。 45 ave_x=np.array([np.average(df.x[i:i+10]) for i in range(0,len(df.x),10)]) 46 std_x=np.array([np.std(df.x[i:i+10]) for i in range(0,len(df.x),10)]) 47 48 x1=(df.x.values[index_s1]- ave_x) / std_x 49 x2= (df.x.values[index_s2]- ave_x) / std_x 50 x3=(df.x.values[index_s3]- ave_x) / std_x 51 x4=(df.x.values[index_s4]- ave_x) / std_x 52 x5=(df.x.values[index_s5]- ave_x) / std_x 53 x6= (df.x.values[index_s6]- ave_x) / std_x 54 x7=(df.x.values[index_s7]- ave_x) / std_x 55 x8= (df.x.values[index_s8]- ave_x) / std_x 56 x9= (df.x.values[index_s9]- ave_x) / std_x 57 x10= (df.x.values[index_s10]- ave_x) / std_x 58 x=np.vstack((x1,x2,x3,x4,x5,x6,x7,x8,x9,x10)).T 59 60 61 ave_y=np.array([np.average(df.y[i:i+10]) for i in range(0,len(df.y),10)]) 62 std_y=np.array([np.std(df.y[i:i+10]) for i in range(0,len(df.y),10)]) 63 64 y1=(df.y.values[index_s1]- ave_y) / std_y 65 y2= (df.y.values[index_s2]- ave_y) / std_y 66 y3=(df.y.values[index_s3]- ave_y) / std_y 67 y4=(df.y.values[index_s4]- ave_y) / std_y 68 y5=(df.y.values[index_s5]- ave_y) / std_y 69 y6= (df.y.values[index_s6]- ave_y) / std_y 70 y7=(df.y.values[index_s7]- ave_y) / std_y 71 y8= (df.y.values[index_s8]- ave_y) / std_y 72 y9= (df.y.values[index_s9]- ave_y) / std_y 73 y10= (df.y.values[index_s10]- ave_y) / std_y 74 y=np.vstack((y1,y2,y3,y4,y5,y6,y7,y8,y9,y10)).T 75 76 ave_z=np.array([np.average(df.z[i:i+10]) for i in range(0,len(df.z),10)]) 77 std_z=np.array([np.std(df.z[i:i+10]) for i in range(0,len(df.z),10)]) 78 79 z1=(df.z.values[index_s1]- ave_z) / std_z 80 z2= (df.z.values[index_s2]- ave_z) / std_z 81 z3=(df.z.values[index_s3]- ave_z) / std_z 82 z4=(df.z.values[index_s4]- ave_z) / std_z 83 z5=(df.z.values[index_s5]- ave_z) / std_z 84 z6= (df.z.values[index_s6]- ave_z) / std_z 85 z7=(df.z.values[index_s7]- ave_z) / std_z 86 z8= (df.z.values[index_s8]- ave_z) / std_z 87 z9= (df.z.values[index_s9]- ave_z) / std_z 88 z10=(df.z.values[index_s10]- ave_z) / std_z 89 90 z=np.vstack((z1,z2,z3,z4,z5,z6,z7,z8,z9,z10)).T 91 #計算した物を全て積み重ね、それぞれ10この要素を合わせたn×40の行列を作成します。 92 d=np.hstack((x,y,z,c)) 93 94 return d 95 96 97 98def to_one_hot(df): 99 #解答のラベルが1−4の整数であるので、ワンホット表現に変換します。 100 101 target_vector = [0,1,2,3] # 整数をベクトルにします 102 n_labels = len(np.unique(target_vector)) # 解答は 4種類です 103 ind=np.eye(n_labels)[target_vector] 104 x=[] 105 for i in df["label"]: 106 if i ==1 : 107 x.append(ind[0]) 108 elif i ==2: 109 x.append(ind[1]) 110 elif i ==3: 111 x.append(ind[2]) 112 elif i ==4: 113 x.append(ind[3]) 114 else: 115 x.append(np.zeros(4))#エラー対策でそれ以外はゼロの配列にします。 116 df["one_hot"]=x 117 118 v=np.zeros(4) 119 for i in df.one_hot.values: 120 v=np.vstack((v,i)) 121 122 vl = np.delete(v, 0, 0) 123 return vl 124 125#入力データはなぜかぴったりではなかったので3470こまでを取り出しています。 126df_input_train=pd.read_csv("https://courses.edx.org/assets/courseware/v1/b98039c3648763aae4f153a6ed32f38b/asset-v1:HarvardX+PH526x+1T2020+type@asset+block/train_time_series.csv")[:3740] 127 128 129#解答のラベルです 130df_correct_train=pd.read_csv("https://courses.edx.org/assets/courseware/v1/d64e74647423e525bbeb13f2884e9cfa/asset-v1:HarvardX+PH526x+1T2020+type@asset+block/train_labels.csv", index_col=0)[:374] 131 132 133 134input_data = to_input(df_input_train)# 入力データを定義します 135correct_data =to_one_hot(df_correct_train) # 正解のラベルを定義します 136 137input_train=input_data[0::2]#訓練データとテストデータに2分割させます。こちらは訓練データにします 138correct_train=correct_data[0::2 ]#こちらは訓練データの解答となります 139input_test=input_data[1::2]#訓練データとテストデータに2分割させます。こちらはテストデータにします 140correct_test=correct_data[1::2]#こちらはテストデータの解答となります 141 142 143 144n_data = len(correct_data) # サンプル数を定義します 145n_train =len(input_train) 146n_test =len(input_test) 147 148#テストであるかどうかを判定します。 149is_train=True 150 151# -- 各設定値 -- 152n_in = 40 # 入力層のニューロン数(s:合成加速度10+x:x軸加速度10+y:y軸加速度10z:z軸加速度10=合計40です) 153n_mid =25 # 中間層のニューロン数 154n_out = 4 # 出力層のニューロン数 155 156wb_width = 0.1 # 重みとバイアスの広がり具合 157eta = 0.01 # 学習係数 158epoch = 1000 159batch_size = 10 160interval = 100 # 経過の表示間隔 161 162#以下の各層の実装は’はじめてのディープラーニング’著 我妻幸長 のIrisの品種分類の部分を参考にしています。 163#文字数超えて書けず、ところどころ抜かして書きました。中間層活性化:ReLU、出力層活性化:ソフトマックス関数、損失関数:交差エントロピー誤差、最適化アルゴリズム:AdaGrad、ドロップ層:2層です。 164 165 166#dropout層を追加 167class Dropout: 168 def __init__(self, dropout_ratio): 169 self.dropout_ratio=dropout_ratio 170 171 def forward(self,x,is_train): 172 if is_train: 173 rand=np.random.rand(*x.shape) 174 self.dropout=np.where(rand>self.dropout_ratio,1,0) 175 self.y=x*self.dropout 176 else: 177 self.y=(1-self.dropout_ratio)*x 178 179 def backward(self,grad_y): 180 181 self.grad_x=grad_y* self.dropout_ratio 182 183#各層の初期化 184middle_layer_1=MiddleLayer(n_in,n_mid) 185dropout_1=Dropout(0.9) 186middle_layer_2=MiddleLayer(n_mid,n_mid) 187dropout_2=Dropout(0.5) 188output_layer=OutputLayer(n_mid,n_out) 189 190#順伝播 191def forward_propagation(x,is_train): 192 middle_layer_1.forward(x) 193 dropout_1.forward(middle_layer_1.y,is_train) 194 middle_layer_2.forward(dropout_1.y) 195 dropout_2.forward(middle_layer_2.y,is_train) 196 output_layer.forward(dropout_2.y) 197#逆伝播 198def backpropagation(t): 199 output_layer.backward(t) 200 dropout_2.backward(output_layer.grad_x) 201 middle_layer_2.backward(dropout_2.grad_x) 202 dropout_1.backward(middle_layer_2.grad_x) 203 middle_layer_1.backward(dropout_1.grad_x) 204 205# -- 重みとバイアスの更新 -- 206def uppdate_wb(): 207 middle_layer_1.update(eta) 208 middle_layer_2.update(eta) 209 output_layer.update(eta) 210 211# -- 誤差を計算 -- 212def get_error(t, batch_size): 213 return -np.sum(t * np.log(output_layer.y+ 1e-7)) / batch_size # 交差エントロピー誤差 214 215 216 217 # -- 学習 -- 218 index_random = np.arange(n_train) 219 np.random.shuffle(index_random) # インデックスをシャッフルする 220 for j in range(n_batch): 221 222 # ミニバッチを取り出す 223 mb_index = index_random[j*batch_size : (j+1)*batch_size] 224 x = input_train[mb_index, :] 225 t = correct_train[mb_index, :] 226 227 228 forward_propagation(x,is_train) 229 backpropagation(t) 230 231 # 重みとバイアスの更新 232 uppdate_wb() 233 234

試したこと

各層のニューロン数や重み、バッチ数の変更をしたり特徴を足し引きしたり、ドロップアウトの割合を変えたりとりあえず思いつくことはやってみたのですが、制度は60パーセントを超えませんでした。出力層のyの値を見てみると最大の要素はインデックスの1に全て集まっておりargmaxを使った時に全て1になっていました。各層の実装は'はじめてのディープラーニング’著 我妻幸長 のIrisの品種分類の部分を参考に書いたためミスはないと思います。入力のデータの前処理がうまくいっていないのかと思うのですが原因がわかりません。

補足情報(FW/ツールのバージョンなど)

jupyter noteで動かしています。全く初心者で質問の際に何を書けばいいのかということもわかっておりませんので追加で必要な部分があればぜひそこも教えていただければと思います。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

気になったところをコメントします。

まず。df_input_trainとdf_correct_trainをUTC timeでマージしたところ、マージした結果の最初の4件が1セットになっており、10件で1セットという質問に記載のルールに合わないデータが存在します。
まず、ここを考慮せずに単純にdf_input_trainの3470件を説明変数として用いてしまうと状態(x,y,z)とラベルの対応関係が整合しなくなってしまいます。マージしてから10件で1セットのデータを取り出す必要があると思います。

次に「#合成加速度を計算しn×10行列を作成します」としていますが、これだと運動量をうまく表現できると思うのですが、階段を下りるや階段を上るといった運動の向きはうまく表現できていないように思います。
せっかく3軸で加速度がデータとして入手できているのであれば、初期値(10件を一括りとしたときの1っ件目)から3軸方向にどのくらい移動したのかを計算して説明変数にしたほうがいいように感じます。うまく計算できれば、立つの場合は上方向へ大きく移動し、前後・左右はほぼ移動なしや歩くの場合は前後に大きく移動するが上下は移動なし、という感じに前処理でデータを作ることができれば、どんなモデルでもかなりの性能が出るような気がします。

投稿2020/05/15 18:44

R.Shigemori

総合スコア3376

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hidebonneidee

2020/05/16 00:07

ご解答いただきありがとうございます!データの数が合わず後ろを切ってしまっていましたが最初の4件が変だったのですね。。盲点でした、、ご指摘ありがとうございます。とても参考になります!加速度のデータを処理することに気を取られて時間変数を使うことを失念しておりました、初期値からの移動量というのも自分では絶対に思いつくことができなかったので本当にありがたいです。頂いたアドバイスを参考にもう少しチャレンジしてみようと思います。本当にありがとうございます。
guest

0

ベストアンサー

各層のニューロン数や重み、バッチ数の変更をしたり特徴を足し引きしたり、ドロップアウトの割合を変えたりとりあえず思いつくことはやってみたのですが、制度は60パーセントを超えませんでした。出力層のyの値を見てみると最大の要素はインデックスの1に全て集まっておりargmaxを使った時に全て1になっていました。各層の実装は'はじめてのディープラーニング’著 我妻幸長 のIrisの品種分類の部分を参考に書いたためミスはないと思います。入力のデータの前処理がうまくいっていないのかと思うのですが原因がわかりません。

iris は簡単な問題ですから、適当なモデルを使ってもほぼ100%の精度が出ます。
4クラスなので、完全にランダムに答えたら、25%になるはずですから、60%でも全然ダメということはないと思います。
iris と同じやり方で他のデータセットでも精度が出るということは言えないので、問題に応じて、前処理やモデルをいろいろ試す必要があります。
入力が数値データの場合、ディープラーニングがいいとも限らないので、他のモデル等も試してみてください。

追記

R.Shigemori さんのコメントをみて、マージして確認してみたところ、たしかに最初のサンプルだけ4時刻分しかないようなので、train_time_series.csv の4データとtrain_labels.csvの最初の1データを除いて、374個のサンプルデータにするべきみたいです。

データ読み込み

python

1import pandas as pd 2 3# CSV を読みこむ。 4data = pd.read_csv("train_time_series.csv", skiprows=[1, 2, 3, 4]) # 最初の4行分のデータはスキップ 5labels = pd.read_csv("train_labels.csv", skiprows=[1]) # 最初の1行分のデータはスキップ 6 7n_samples = data.shape[0] // 10 8X = data[["x", "y", "z"]].values.reshape(-1, 10, 3) 9y = labels["label"].values.astype(int) - 1 # ラベルを 0 始まりにする 10print(X.shape, y.shape) # (374, 10, 3) (374,)

SVC の学習サンプル

python

1from sklearn.metrics import accuracy_score 2from sklearn.model_selection import train_test_split 3from sklearn.pipeline import make_pipeline 4from sklearn.svm import SVC 5from sklearn.preprocessing import StandardScaler 6 7# 学習データとテストデータに分割する。 8X_flatten = X.reshape(len(X), -1) # (374, 10, 3) -> (374, 30) 9X_train, X_test, y_train, y_test = train_test_split( 10 X_flatten, y, test_size=0.2, random_state=42 11) 12 13# SVM で学習する。 14clf = make_pipeline(StandardScaler(), SVC(gamma="auto")) 15clf.fit(X_train, y_train) 16 17y_pred = clf.predict(X_test) 18acc = accuracy_score(y_test, y_pred) 19print(f"{acc:.2%}") # 66.67%

サンプルを可視化した例

python

1import matplotlib.pyplot as plt 2import numpy as np 3from mpl_toolkits.mplot3d import Axes3D 4 5fig = plt.figure(figsize=(12, 10)) 6 7class_ids = np.unique(y) 8class_names = ["立つ", "歩く", "階段を下る", "階段を登る"] 9cols = 5 10 11for i, class_id in enumerate(class_ids): 12 some_samples = X[np.where(y == class_id)][:cols] 13 for j, sample in enumerate(some_samples): 14 ax = fig.add_subplot(4, cols, i * cols + j + 1, projection="3d") 15 ax.plot(sample[:, 0], sample[:, 1], sample[:, 2]) 16 ax.set_title(class_names[class_id]) 17 18plt.show()

イメージ説明


  • 1つのサンプルが10時刻分の x, y, z なので、上記では潰して30次元にしてしまいましたが、時系列データとして扱えるモデルも試すといいかもしれません。
  • 標準化やディープラーニングの学習など、ライブラリで代用できるものは独自実装ではなく、ライブラリを使ったほうがいいと思います。数値計算の実装でバグがあったりすると、見つけるのはなかなか大変です。

投稿2020/05/15 16:01

編集2020/05/16 03:50
tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hidebonneidee

2020/05/16 00:17

ご解答頂きありがとうございます。まだまだ勉強不足でSVMというものを知らず、wikiで読みました!こんな便利なものがあったのですね!!教えていただきましてありがとうございます!ライブラリを使えば書く量も減らせていいことだらけですね!reshapeの使い方等自分では全く思いつかなかった方法ばかりでとても参考になります。学習させるならディープラーニング !と完全に視野が狭かったので、他のモデルも試してみようと思います!時刻データも他のデータの処理に気を取られていたのですが組み込んでみたいと思います! 色々なアドバイスをいただきまして本当にありがとうございます。
tiitoi

2020/05/16 03:49

R.Shigemori さんがご指摘くださってるように最初のサンプルだけ4時刻しかないようですね その点だけ回答のコードを修正しました。可視化サンプルも追加しました。 モデルより、既存の特徴量から新しい特徴量を作る前処理が重要になってきそうですね。
hidebonneidee

2020/05/18 23:14

tiitoiさま、追加でコメント&編集いただきまして本当にありがとうございます!可視化いただきとても分かりやすくなりました!やはり時間を使った新しい特徴量を作るのが良さそうですね。。本当にありがとうございます、とても参考になりました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問