機械学習_教師あり/なし学習

教師あり学習

線形回帰

ロジスティック回帰

 2クラス分類に使用される.シグモイド関数による出力を(0,1)の範囲に制限すること.

教師なし学習

主成分分析

特徴

教師なし学習であり、次元削減を行うための手法である.
分散共分散行列固有ベクトルの基に新たな座標軸を複数作成し、新たな座標軸から構成される低次元空間へデータを写像する.
寄与率:各主成分の固有値固有値の総和で割った値

計算

2次元空間で(-2,2),(-1,-1),(0,0),(1,1),(2,-2)という5つのデータ点がある
第一主成分: (1/√2, -1/√2)
第二主成分: (1/√2, 1/√2)

(1/√2,-1/√2)のx軸とy軸をそれぞれのデータ点と掛けた和である
第1主成分によって張られる1次元空間へ5つのデータ点を射影すると
1/√2*(-2)-1/√2*(2)=-2√2
1/√2*(-1)-1/√2*(-1)=0
1/√2*0-1/√2*0=0
1/√2*1-1/√2*1=0
1/√2*2-1/√2*(-2)=2√2

第2主成分によって張られる1次元空間へ5つのデータ点を射影すると、
1/√2*(-2)+1/√2*(2)=0
1/√2*(-1)+1/√2*(-1)=-√2
1/√2*0+1/√2*0=0
1/√2*1+1/√2*1=√2
1/√2*2+1/√2*(-2)=0

第1主成分と第2主成分による張られる2次元空間へ5つデータ点を射影すると、
(-2√2,0),(0,√2),(0,0)(0,√2),(2√2,0)である。

再構成誤差は、2次元空間に射影することによりも、1次元空間に射影されるデータのほうが大きい.
http://ibis.t.u-tokyo.ac.jp/suzuki/lecture/2015/dataanalysis/L7.pdf

def pca(X, n_components):
    X = X - X.mean(axis=0)                       # データから平均を引く
    cov = np.cov(X, rowvar=False)              # 共分散行列の作成
    l, v = np.linalg.eig(cov)                          # 固有値と固有ベクトルを計算
    l_index = np.argsort(l)[ : : -1]                 #★ 固有値を降順でソートするためのインデックスを求める
    v_ = v[ : , l_index]                                #★ 固有ベクトルを降順でソートする
    components = v_[ : , : n_components]  #★ 固有ベクトルを取得する処理, 出力の次元数分の固有ベクトルを取り出し、低次元空間へ写像
    T = np.dot(X, components)
     return T

主成分分析

n_componentsの個数だけ、固有ベクトルを切り出す
データを低次元空間に射影する

K-NN

特徴

教師なし学習で分類器である.データのクラスタリング (グループ分け) をする際に、
「予測データに近いデータ k 個の多数決によってクラスを推測」するアルゴリズム

K-means

特徴

<アルゴリズム>
1. 各点xiに対してランダムにクラスタを割り振る
2. 各クラスタに割り当てられた点について重心を計算する
3. 各点について上記で計算された重心からの距離を計算し、距離が一番近いクラスタに割り当て直す
4. 2と3の工程を、割り当てられるクラスタが変化しなくなるまで行う
【E資格対策】k-meansの実装方法について詳しく見る

def init_centroid(X, k, n_data):
    # 各データ点の中からクラスタの重心となる点をk個ランダムに選択 permutation 重複なしランダムデータ
    idx = np.random.permutation(n_data)[:k]  #★ 
    centroids = X[idx]
    return centroids

def compute_distances(X, k, n_data, centroids):
     distances = np.zeros((n_data, k))
     for idx_centroids in range(k):
            #すべてのデータ点との距離の二乗を計算
            dist = np.sqrt(np.sum((X - centroids[idx_centroids]) **2, axis=1)) #★

def k_means(X, k, max_iter=300):
    centroids = init_centroid(X, k, n_data)
    for epoch in range(max_iter):
          distances = compute_distances(X, k, n_data, centroids)
          new_cluster = np.argmin(distances, axis = 1) # ★新たな所属クラスタを計算 
    
     for idx_centroids in range(k):
         centroids[idx_centroids] = X[new_cluster == idx_centroids].mean(axis=0) #★

K-means++

特徴

K-means法でははじめてのセントロイドの位置が近い場合、うまく分類できないケースがある.
そのため、K-means++では各セントロイド同士の距離がなるべく遠くなるように決める.

probabilites = np.sum(distances, axis=1) / np.sum(distances) # 列ごとに演算行うためaxis=1

distancesのすべての要素の和でdistancesの要素を割ることで各要素は0から1の間に正則化される.
さらに、今までのセントロイドの距離を考慮して行ごとに和を取るで、初期化として選ばれる確率を表すProbabilitiesを得ることができる.
この初期値の選択方法を、ルーレット選択という呼ばれる.

closet_dist_sq = np.min(distance ** 2, axis =1) #各データ点と最も近い重心との距離に二乗を計算
weights = closet_dist_sq.sum()        # 距離の二乗の和を計算
rand_vals = np.random.random_sample() * weights   # [0,1)の乱数と距離の二乗和をかける
candidate_ids = np.serchsorted(np.cumsum(closest_dist_sq), rand_vals)     # 距離の二乗の累積和を計算し、rand_valsと最も値が近いデータ点のindexを取得

k-meansとk-means++を視覚的に理解する~Pythonにてスクラッチから~ - 医療職からデータサイエンティストへ

SVM

2クラス分類問題であり、決定的な出力をする分類器である.(他クラス分類や回帰にも使える)

特徴

1. ハードマージン

  • マージンの最大となる境界のパラメータw,b を学習
  • 識別面を構成するために使われるマージンの上にあるデータ点をサポートベクトルと呼ぶ.
  • サポートベクトルの数は学習全数データより少なく、最小値は2である
  • SVMの出力はそのままでは確率値として解釈できない、ロジスティック回帰のように事後的に境界面を調整できない
  • マージンの外側のデータは予測影響を与えない(それは、識別では決定境界から近い点のデータもしくはマージンの上の点が予測に利用されるため)
  • SVMにおいて射影手法を利用して、特徴空間が高次元であるほど、表現力が上がるが、計算コストが高い。計算コストを抑制するため、カーネルトリックを導入

  カーネルトリック: ガウシアンカーネル多項式カーネル、Sigmoidカーネル

2.ソフトマージン
学習データが線形分離が不可能となる場合、すべての制約を満たすことができない.スラック変数を導入して誤分類を許容する.
SVMにおいて最小化する目的関数Lの数式    L =C\sum_{i=1}^{n}\xi_i +  \frac{||w||^2}{2}

  • Cが \inftyになると、マージン内に訓練データが入ることで、誤分類を一切許容しない
  • Cが0になると、誤分類が許容しやすく、誤分類が多くなる.
  • Cが小さいすると、過学習を抑制できる.
  • Cが大きくすると、誤分類の許容が大きくなる.テストの正解率が低くなる.完全に分離することで汎用性能が小さいくなる.