0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

E資格ラビットチャレンジレポート 〜機械学習まとめ〜

Last updated at Posted at 2021-09-12

線形回帰

理論(要点まとめ1点)

直線のみで予測する

 \boldsymbol{\hat{y}} = \boldsymbol{w}^T\boldsymbol{x} + w_0

係数$w$は最小二乗法で求める。
個人的に感じたメリットは以下の通り。

結果が理解しやすい
計算負荷が小さい
説明変数の重要度を係数の大小で比較できる(説明変数は正規化しておく必要)

演習(実装演習結果1点)

ボストンの住宅データセットを用いた線形回帰のモデル作成。
課題は以下の通り。

部屋数が4で犯罪率が0.3の物件はいくらになるか?

この2変数だけで回帰するモデルを作成する想定だと解釈して、演習を行った。

なお、以下の2点はラビットチャレンジのドキュメントが正しくなさそう
・Google Driveのマウントの方法(古い)
・課題データのURL(存在しないと言われる)

スクリーンショット 2021-09-12 1.19.30.png

非線形回帰モデル

理論(要点まとめ1点)

非線形の関数のみで予測する

 \boldsymbol{\hat{y_i}} = \boldsymbol{w}^T\phi(\boldsymbol{x_i}) + w_0 + \epsilon_i

係数$w$は最小二乗法や最尤法で求める。
$ \phi $に使われる関数は、多項式関数やガウス型基底関数、スプライン関数、Bスプライン関数などがある。

過学習を防止するために、以下の二つの方法を学んだ。

  • 不要な基底関数を削除
  • 正則化法(罰則化法)

なお、正則化項の入れ方で名前が変わる。
L2ノルムの場合:Ridge推定量
L1ノルムの場合:Lasso推定量

Lassoの場合はスパースになる

演習(実装演習結果1点)

課題は特になし。
実装のコードがあるので、回して遊んでみる。
100乗くらいの多項式入れてあげると、過学習してる様子が見て取れる。

deg = [100]
for d in deg:
    regr = Pipeline([
        ('poly', PolynomialFeatures(degree=d)),
        ('linear', LinearRegression())
    ])
    regr.fit(data, target)
    p_poly = regr.predict(data)
    plt.scatter(data, target, label='data')
    plt.plot(data, p_poly, label='polynomial of degree %d' % (d))

スクリーンショット 2021-09-12 2.03.03.png

ロジスティック回帰

理論(要点まとめ1点)

分類問題を解くための教師あり機械学習モデル(教師データから学習)
入力データとm次元パラメータの線形結合をシグモイド関数に入力して、y=1になる確率の値を出力するモデル

p_i = \sigma( \boldsymbol{w}^T\boldsymbol{x} + w_0)

ちなみに、ロジスティック回帰モデルは一般化線形モデルの一種らしい。
https://ja.wikipedia.org/wiki/%E3%83%AD%E3%82%B8%E3%82%B9%E3%83%86%E3%82%A3%E3%83%83%E3%82%AF%E5%9B%9E%E5%B8%B0

演習(実装演習結果1点)

タイタニックの乗客データを利用し、ロジスティック回帰モデルを作成。
課題は以下の通り。

年齢が30歳で男の乗客は生き残れるか?

1)単純にまずは、コードを動かしてみる。

Google Driveのマウントのセルは削除して、Googleの誘導に従った
データ保存場所も異なっていたので変えた

スクリーンショット 2021-09-12 2.28.30.png

上の図では、横軸が運賃であり、

  • 青点が0であったデータ点
  • オレンジ点が0となる確率
  • 緑点が1となる確率
  • 赤線がシグモイド関数の出力値
    のようである。念の為、オレンジと緑の合計が1になることを確認した。

2)課題用のモデルを作成し、回答を作成する。

data2 = titanic_df.loc[:, ["AgeFill", "Gender"]].values
label2 =  titanic_df.loc[:,["Survived"]].values
model2 = LogisticRegression()
model2.fit(data2, label2)
model2.predict([[40,1]])
model2.predict_proba([[40,1]])

結果は以下の通り。
array([[0.81529326, 0.18470674]])
82%くらいの確率で生存しそうです。

主成分分析

理論(要点まとめ1点)

多変量データの持つ構造をより少数個の指標に圧縮するときに使う。

学習データが1つあたり、m次元ベクトル
それがn個存在するとした時に、
データ行列$\bar{X}$は、n*m行列で、(各学習データ-平均ベクトル)

分散共分散行列は、

\frac{\bar{X^T} \bar{X}}{n}

主成分分析を計算する手順

1.分散共分散行列を計算
2.固有値問題を解く
3.(最大)m個の固有値と固有ベクトルのペアを得る

演習(実装演習結果1点)

32次元のデータを2次元上に次元圧縮した際に、うまく判別できるかを確認。

スクリーンショット 2021-09-12 13.43.21.png

かなり上手く分類できているようである。
60%程度の情報は復元できる様子。

演習問題関連の発展(1点)

第三主成分まで含めるた場合について、自身で実装演習。
結果としては、70%くらいまで判別できる割合が上がった。

pca = PCA(n_components=3)
X_train_pca = pca.fit_transform(X_train_scaled)
print('explained variance ratio: {}'.format(pca.explained_variance_ratio_))

アルゴリズム

k近傍法

理論(要点まとめ1点)

最近傍のデータをk個取ってきて、それらがもっとも多く所属するクラスに識別

ポイント

  • kを大きくすると決定境界は滑らかになる

個人的な気づき

k=1の場合を考えると、各データ点と最近傍のデータ点を結ぶ垂直二等分線を境界に分類されそう。
データ点が1個増えるごとに境界線が結構動く可能性があるので、堅牢性は低そう。

演習(実装演習結果1点)

課題

人口データと分類結果をプロットしてください

とあるが、人口データが見つからなくなってしまっているようだ。
そこで、ダミーデータの生成を行い、分類をおこなった。
スクリーンショット 2021-09-12 14.46.05.png

k平均法

理論

教師なし学習のクラスタリング手法で、与えられたデータをk個のクラスタに分類する

k平均法を計算する手順

1.各クラスタ中心の初期値を設定する
2.各データ点に対して、各クラスタ中心との距離を計算し、最も距離が近いクラスタを割り当てる
3.各クラスタの平均ベクトル(中心)を計算する
4.収束するまで2, 3の処理を繰り返す

初期値の取り方で結果が変わる点に注意

演習

ワインのクラスタリング
本質的にクラスタリングに関わるプログラムは以下の部分。

model = KMeans(n_clusters=3)
labels = model.fit_predict(X)

上側のコードで指定しているクラスターの数を変更することで、異なる数のクラスターに分類することができる。

Support Vector Machine

理論(要点まとめ1点)

元来2クラス分類問題を解くための手法として発展してきた。
マージン最大化するような境界を選ぶ。
分離可能性を仮定したSV分類のことを一般にハードマージン(hard margin)と呼ぶ。
逆に多少の誤分類を許容したSV分類は、ソフトマージンと呼ぶ。
スラック変数(slack variable)と呼ばれるもので、どこまで誤分類を許容するか決める。
スラック変数にかかる係数Cが正則化係数と呼ばれる。

正則化係数C→∞の極限で、ハードマージンになる。

演習(実装演習結果1点)

ランダムな線形分離可能なデータを生成して、SVMで境界線の決定を行う。

def gen_data():
    x0 = np.random.normal(size=50).reshape(-1, 2) - 2.
    x1 = np.random.normal(size=50).reshape(-1, 2) + 2.
    X_train = np.concatenate([x0, x1])
    ys_train = np.concatenate([np.zeros(25), np.ones(25)]).astype(np.int)
    return X_train, ys_train

ただし、上で作成したデータは、0と1のラベルがついているので、
学習させるまでに、1と-1に変換しておく必要がある。

t = np.where(ys_train == 1.0, 1.0, -1.0)

分離すると以下のような図になる。
image.png

より発展的には、ガウシアンカーネルなどを使えば、線形分離できない場合にも対応できる。

image.png

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?