CourseraWeek8で紛らわしかったところ(K-mean, PCA)

画像1

K-mean法

教師なし学習で、クラスタリングの一つ。

1.クラスター重心(centroid)を決める。(上記は2点)

2.どっちのcentroidに近いかで、クラスタ分けをする。

3.それぞれのクラスタの値の平均をとり、その平均の場所にcentroidを移動させる。

1~3を繰り返し、移動しなくなったらおわり。

画像2

Cluster centroid を決めるアルコリズムは、、

repeat{

for i = 1 to m

c(i) <- index( from 1 to k ) of cluster centroid closest to x(i) 

つまり、min || x(i) - μ(i)|| をとるKをCに代入する。(K= μ(1),μ(2),,,,,,)

上の右の方の図だと、x(1)は、μ(1)にもっとも近いので、c(1) = 1 となる。


また、cluster centroid を動かすステップのアルコリズムは、、

for k = 1 to k  

μ(n) <- average(mean) of points assigned to cluster K.

}

たとえば、C(1)=2, C(5)=2, C(6)=2, C(10)=2 だった時、

μ(2) <- 1/4 *( x(1) + x(5) + x(6) + x(10) )


画像3

ちなみに、

C(i) = x(i)がどのクラスターに分けられているか表す。

μk = クラスターKの場所を表す。

μc(i) = x(i)に割り振られている(x(i)を囲んでいる)クラスターを表す。


また、目的関数は、

J = ( C(1)~C(m), μ(1)~μ(k)) = 1/m * || x(i) - μc(i)||^2

であり、c (1~m), μ(1~k)をトレーニングする。(出す)


画像4


アルコリズムの中で同時にCとμを計算するのではない。

repeat{

for i = 1 to m

 c(i) <- index(1 ~ k) of cluster centroid closest to x(i)   

Cluster centroid を移動させるステップで、minJするc(1~m)を調節。その間μ(1~k)は固定。

for k = 1 to k

μk <- average (mean) of points assigned to closest k 

Cluster centroid をクラスターの平均に移動させるステップでminJするμ(1~k)を調節。


画像5

てか、キレーに点が分かれていたらいいけど、そうでない場合は Local optimaに収束しちゃわないか?という疑問が出る。実際ローカルな値に収束してしまうことがある。

→では、initialの値を一回だけランダム化してアルコリズムを回すのではなく、複数のinitialの値でアルコリズムを回してみて、一番良いものを採用しようではないか。


画像6

これがそのアルコリズム。

for i = 1 to 100 {

Randomly initialize K-means,

Run K-means , Get C(1~m), μ(1~K),

Compute cost function J 

}

100回、回しているから、100個のJが得られる。その後一番小さい値のJを選ぶ。



画像7

で、クラスター数(number of k) どうするよという疑問が生まれる。

Elbow method というものが存在する。Kの個数をx軸、Jをy軸にプロットして、ニンゲンの肘レベルで折れ曲がっているところがあれば、そこが最適なkの個数カモね。

・・だけど、現実にはエルボーが存在することは稀で、あまりElbow method は使われない。

画像8

じゃあ実際どうやってkの個数を決めているか。

現在のところ、高度なアルコリズムはなく、実際の(ビジネスなどの)目的によって決めている。

たとえば、TシャツのサイズをS、M、Lと三分割したければ、kの個数は3だし、xs、s、m、l、xlとしたければkは5つ必要である。

→目的に応じて主観的にkの個数を決める



PCA_____

画像9

PCA とは、次元を下げるメソッド。


画像10

青の線でなく、赤の線を引きたい。つまり、それぞれの距離がminとなるような線を選びたい(最小二乗法的な・・?)


画像11

ただ、最小二乗法とは全く違うアルコリズムである。

図的に説明すると、左が最小二乗法で右がPCA。

また、最小二乗法ではx、y軸があるのに対して、PCAはx1、x2軸しかない。つまり、最小二乗法はyの予測を念頭に置いているが、PCAは目的変数などない。根本から違うアルコリズムである。


また、PCAを行う際は、必ずヒューチャースケーリングを行う必要がある。

PCAの流れとしては(ノート取ってない・・)

1.Σ(共分散行列)を計算する (sumではない、注意)

2.Σ(共分散行列)の固有ベクトルを計算する。

3.計算した固有ベクトルを用いてn次元からk次元に圧縮したベクトルzを計算する。


1.Σ(共分散行列)の計算。

Σ = 1/m * Σ(1~m) {x(i) * x(i)'}

vector ver..

Sigma = (1/m) * X' * X


2.共分散行列Σの固有ベクトルを計算する。

[U, S, V] =svd(Sigma)

ちなみにUが固有ベクトル。Σと同様n*n行列。


3.Uの最初のk列を取り、n次元からk次元に圧縮したベクトルkを計算する。

z(i) = U_reduce' * x(i)

U_reduce'はk*n行列で、xがn*1行列だから、zはk*1行列になる。

コードだと、

Ureduce = U( : , 1:k )

Z = X * Ureduce



ここまで一気にまとめると、、

Sigma = (1/m) * X' * X       共分散行列を求める

[U, S, V] = U( : , 1:k )   固有ベクトルを求める

z = X * Ureduce     圧縮したzを出す。


圧縮したk次元からn次元に戻すには__

z(i) = Ureduce' * x(i)  だから

x(l)_approx = Ureduce * z(l)



いくつの次元まで圧縮するか__圧縮する次元数の決め方

二乗射影誤差と全体の分散の比率を取って何%未満とする(たとえば、1%未満なら、99%の主成分が保持されていることになる)


1.1/m Σ(1~m) { || x(i) - x_approx(i) ||^2} ...① 二乗射影誤差を求める

2.1/m Σ(1~m) { || x(i) || ^2 } ...② 全体の分散を求める。

3.① / ② <= 0.01 を満たす最小のk次元を求める。

具体的には、

[ U, S, V ] = svd(Sigma) を呼び出し、Sを用いる。

Σ(1~k) Sij / Σ(1~n) Sij >= 0.99 を満たす最小のkを求める。当てはまらなければ少しずつkの値を増やしていく。

PCAを使うときに気を付けること__

PCAはトレーニングセットにのみ行う。PCAの主な用途は、次元を減らすことでのスピードアップ、メモリの削除、データの可視化(2、3次元のグラフを描くため)である。したがって、次元を減らすことによる over fitting を均すために使用するのは間違った使い方。あくまでもover fitting を防ぐなら正則化を使う。




課題__

1.findClosestCentroids

FINDCLOSESTCENTROIDS computes the centroid memberships for every example
 idx = FINDCLOSESTCENTROIDS (X, centroids) returns the closest centroids
 in idx for a dataset X where each row is a single example. idx = m x 1
 vector of centroid assignments (i.e. each entry in range [1..K])  らしいです。

idx にそれぞれのデータに最も近いcentroidを保存させるらしいです。

function idx = findClosestCentroids(X, centroids)

K = size(centroids, 1)

idx = zeros(size(X,1),1)

for i = 1 : size (X, 1)

 min_c = inf

 for j =1 : K

 c  =(X( i ,: ) - centroids( j ,: )) * (X( i , : ) - centroids( j , : ))'

   if c <= min_c

    min_C =c

  idx(i) = j

end

end

end


2.computeCentroids

それぞれのクラスターの平均値を出し、centroidsを移動させていくステップです。

function centroids = computeCentroids(X, idx, K)

[m n] =size(X)

cemtrpods = zeros(K, n)

---- your code here----

for k = 1:K
 sum_X = zeros(1,n);
 count = 0;
 for i = 1:m
  if idx(i) == k
  sum_X(1,:) = sum_X(1,:) + X(i,:);
  count = count + 1;
 end
end
mean_X = 1/count*sum_X;
centroids(k,:) = mean_X;
end


3.kMeansInitCentroids

最初のcentroidsを決めます。

1.training exampleをランダムに並び替え

2.最初のk個をinitial centroids に

function centroids = kMeansInitCentroids(X, K)

centroids = zeros ( K, size(X,2))

---your code here---

random_idx = randperm(size(X, 1))      1.ランダムに並び替え

centroids = X(random_idx(1 : k ), :)  2.最初のk個をとる

 

4.pca

XでPCAを回す課題です。そのまま。

function [U, S] = pca(X)

[m , n] = size(X)

U = zeros(n)

S = zeros(n)

---your code here---

Sigma = 1/m * (X)' * X

[U, S, V] =svd(Sigma)


5.project data

Uの最初のk個を取ってPCAを回します。

function Z = projectData( X, U, K)

Z = zeros (size(X, 1), K)

--- your code here----

U_reduce = U( : , 1 : K ):   

Z = X * U_reduce:

end


6.recoverData

5で作ったzをもとに戻します。

function X_rec - recoverData (Z, U, K)

X_rec = zeros(size(Z, 1), size(U, 1))

---your code here--

for i = 1 : size(U,1)
X_rec( : , i ) = Z * U( i , 1:K )'
end









この記事が気に入ったらサポートをしてみませんか?