暇人日記

アラフォーおっさんのコーセラの機械学習の課題を解こうと頑張っています!

Coursera Machine Learning week2課題 2周目⑦ -苦闘記憶- featureNormalize-

今回はOptionalのLinear Regression with multi variableの

featureNomalizeに取り組みます。

 

f:id:omoshiroamericanews:20200109120820p:plain

 

まず問題文を読んでみます。

f:id:omoshiroamericanews:20200109120902p:plain

家のサイズと寝室の数から家の値段を予想しなさいということですね。

まず基データを見てみたいと思います。

 

f:id:omoshiroamericanews:20200109121026p:plain

こういうふうにサイズと部屋数と家の値段が47例入っています。

 

f:id:omoshiroamericanews:20200109121127p:plain

家の値段を予測したいので、サイズと部屋数をX、

家の値段をYにするということですね。

 

f:id:omoshiroamericanews:20200109121237p:plain

 

f:id:omoshiroamericanews:20200109121317p:plain

 

 ここまではFood Truckの内容を踏まえて考えてきましたが、

ここで問題文に戻ってみます。

f:id:omoshiroamericanews:20200109121509p:plain

 

予測に取り掛かれると思いきや、家の価格予測には

1つFood Truckにはない要素があるようです。

それはXの桁数です。

サイズは4桁で部屋数は1桁です。

これを同じ桁数くらいにした方が計算が早いと説明されてあります。

 

f:id:omoshiroamericanews:20200109121616p:plain

 

計算の仕方ですが、 

f:id:omoshiroamericanews:20200109121829p:plain

とあります。

 

①平均値をSampleからひく

②①をした後にstandard deviationで割る

 

Standard deviationって何だろう?と思ったので

ググってみたら標準偏差とありました。

標準偏差ってどう計算するんだろうと思ったのでググったら

『各データの値と平均の差の2乗の合計をデータの総数nで割った値の

 正の平方根』

 

・・・・・

 

1行目わかりますが、2行目わかりません。。。

なんとなく平均との差が大きいかどうかという指標に見えます。

とりあえず問題文を読み進めてみます

 

f:id:omoshiroamericanews:20200109122014p:plain

 

どうやら標準偏差はデータの範囲をしめしているようで±2以内の

範囲に収まるのが通常のようです。

しかもOctaveの中ではstdという関数が設定されているようです。

さっき、さっさと全要素が1の行を足してしまいましたが、

featureNormailizeした後に足すのが良いと書いてありますので、

問題文の通り進めます。

 

実行のコツが書いてありました↓

f:id:omoshiroamericanews:20200110082356p:plain

 

新しいデータが入った時のために、

平均と標準偏差は記録していたほうがいいということですね。

そうするとスムーズに予測検証できますよ、ということだと思います。

 

さてそれではfeatureNormalize.mを見ながら取り組みます。

 

f:id:omoshiroamericanews:20200110082519p:plain

featureNormalize.mはXを入力すると、

X_normとmuとsigmaを計算される仕組みですね。

 

X_normはNomalizeされて桁数が同じくらいになったXかとおもいます。

muは平均でsigmaが標準偏差ですね。

 

さっきの実行のコツで平均と標準偏差は記録するようにというのは

ここで実行されているようです。

 

X_normのサイズはXと同じなので47X2

Size(X,2)は何になるのか、気になったので実験しました。

 

f:id:omoshiroamericanews:20200110082626p:plain

 

ということはmuとsigmaのサイズは1X2ですね。

 

また、最後の行に

平均はmean、標準偏差はstdという関数を使えばいいとヒントに書いてあります。

 

まずはmeanを使って平均を計算してみます。

 

f:id:omoshiroamericanews:20200110082829p:plain

 

面積の平均と部屋数の平均がそれぞれ出てきました。

 

これを各データから引くとあります。

なので

X-mean(X)としてみます。

 

f:id:omoshiroamericanews:20200110082932p:plain

 

これの標準偏差が必要なようなので

Std(X-mean(X))としました。

 

f:id:omoshiroamericanews:20200110083019p:plain

 

この値でX-mean(X)を割ればいいのでしょうか?

割ってみます。

 

f:id:omoshiroamericanews:20200110083121p:plain

 

 

1行になってしまいました。。。

答えは47X2で2行のはずなので、どこか間違えています。

 

47X2のベクトルに1X2のベクトルを逆転させて2X1をかけた形になって

47X1の1行のベクトルになって返ってきたと思います。

 

行いたいことは

1行目は794で割って、2行目は0.76で割りたいです↓

 

f:id:omoshiroamericanews:20200110083440p:plain

次元から考えると、掛け算割り算でこれは難しいですね。

要素ごとの掛け算にするしてもXは47X2で標準偏差は1X2なので、

次元が合いません。

 

1周目の時はloopしたのですが、

Week8の時にとても良い関数を手に入れたのでこちらで行いたいと思います。

 

それはbsxfunです。

bsxfun(F,A,B)で今回のような要素ごとに計算してほしいときに

力を貸してくれます。

 

FはFunctionのFなので足し算引き算掛け算割り算などが入ります。

AとBはベクトルです。

 

例えばさっき

X-mean(X)

という計算をしました。

 

これは47X2のベクトルと1X2のベクトルの引き算でした。

bsxfunを使うと

X_norm = bsxfun(@minus, X, mean(X))

と表現されます。

minusは引き算ですね。

 

今回の場合は割り算なのでdivideで右(right)のベクトルで左を割るということで

rdivideになります。

 

bsxfun(@rdivide,X-mean(X),sigma)

 

そーすると、下の結果が得られ問題文の言っていた通り

±2の間に値が収まっています。

 

f:id:omoshiroamericanews:20200110084230p:plain

 

提出したら正解になりました!

 

bsxfunの使いどころは

計算元のベクトルが答えのベクトルで同じである(=今回は47X2)時に、

かけたり割ったりしたいがかけたり割ったりすると、

ベクトルの形が変わってしまって困る時だと思います。

 

 

ちなみにhelp functionで呼び出したbsxfunの説明です↓

 

f:id:omoshiroamericanews:20200110084131p:plain

 

ところでfearureNormalizeは全要素が1の47X1のベクトルを足す前にやったのですが、

足した後にやったらどうなるかを見てみます。

いや、全部1なんじゃないかと思うので。だとすれば事前に足しても事後に足しても

同じじゃないかなぁと思ったので実験してみます。

 

f:id:omoshiroamericanews:20200110090442p:plain

 

ダメでした。1行目がエラー値になりました。

 

f:id:omoshiroamericanews:20200110090614p:plain

 

標準偏差が0で、0で割ろうとするからエラーが出ています。

 

今回はここまでです。また次回頑張ります。