Menu

Category

Archive

logo


Logistic Regression Algorithm(ロジスティック回帰)[機械学習]

2014-04-28 02:34:49 +0900
  • このエントリーをはてなブックマークに追加

今まで線形モデルの Perceptron[link] と Linear Regression[link] に関して勉強してきました。今回は、新しい線形モデルである Logistic Regression に関して勉強したので、Python で実装しました。

導入

Logistic Regression は、 Logistic Regression は Perceptron と Linear Regression のちょうど間に位置すると言ってもいいです。Perceptron は、アウトプットとして、+ か - のようにバイナリの結果を返しました。[ h(x] = sign(w(t)x) ] Liner Regression は、実数の値を返しました。[ h(x) = w(t)x ] これらに対して、今回の新しいモデルである Linear Regression は 0 から 1 の範囲の確率を返します。[ h(x) = theta(w(t)x ] ここでの theta関数は、theta(s) = e^s / 1 + e^s と便宜的に、0 から 1 を返すように設定します。(ロジスティクス関数) x が大きくなればなるほど、アウトプットは 1 に近くなります。逆に小さくなればなるほど、0 に近くなります。

次にコスト関数と、その関数の Gradient を見ていきます。まず、コスト関数は、

その Gradient は、確率的勾配降下法というもので、

です。そもそも確率的勾配降下法とは、Linear Regressioの際に使用した、最急降下法をよりシンプルにしたものです。通常の勾配法では、データ分だけパラメータ(w)を更新するために微分する必要があります。しかし、確率的勾配降下法では、データ分の和を計算する過程を省きます。ここでの”確率的”とは、乱数を使い実行の度に結果が異なるということを表現しています。このアルゴリズムを使用し、パラメータの更新式は、

となります。

Convex function なので local minimum に収束するこの手法でも global minimum であることが保証されています。また、学習率である eta を少しずつ小さくしていきます。下記のグラフのように、eta が大きいと最適な値を飛ばしてしまい学習が安定せず、小さすぎると非効率です。そのため eta をはじめは 0.1 程度の設定し、学習が進むにつれて小さくするというのが一般的のようです。

実装

Pythonで実装した内容がこちらです。

 1 #-*- coding: utf-8 -*-
 2 
 3 import matplotlib.pyplot as plt
 4 import numpy as np
 5 
 6 # 特徴関数
 7 #
 8 #
 9 def phi(x, y):
10     return np.array([x, y, 1])
11 
12 # シグモイド関数
13 #
14 #
15 def sigmoid(z):
16     return 1.0 / (1 + np.exp(-z))
17 
18 ###############################################
19 
20 # BY using other data set
21 data = np.loadtxt('ex2data1.txt', delimiter=',')
22 
23 X = data[:, 0:2]
24 Y = data[:, 2]
25 N = Y.size;
26 w = np.random.randn(3)  # パラメータをランダムに初期化
27 eta = 0.1 # 学習率の初期値
28 
29 for i in xrange(400):
30     list = range(N)
31 
32     np.random.shuffle(list)
33 
34     for n in list:
35         x_n, y_n = X[n, :]
36 
37         t_n = Y[n]
38 
39         # 予測確率
40         feature = phi(x_n, y_n)
41         predict = sigmoid(np.inner(w, feature))
42         w -= eta * (predict - t_n) * feature
43 
44     # イテレーションごとに学習率を小さくする
45     eta *= 0.9
46 
47 # 図を描くための準備
48 seq          = np.arange(0, 120, 0.1)
49 xlist, ylist = np.meshgrid(seq, seq)
50 zlist        = [sigmoid(np.inner(w, phi(x, y))) for x, y in zip(xlist, ylist)]
51 
52 # 散布図と予測分布を描画
53 plt.imshow(zlist, extent=[0,120,0,120], origin='lower', cmap=plt.cm.PiYG_r)
54 plt.plot(X[Y==0,0], X[Y==0,1], 'x', color='blue')
55 plt.plot(X[Y==1,0], X[Y==1,1], 'o', color='red')
56 plt.legend(['Not admitted', 'Admitted'])
57 plt.show()

参考

Gihyo.jp : 第16回 最適化のための勾配法
Gihyo.jp : 第18回 ロジスティック回帰
Gihyo.jp : 第19回 ロジスティック回帰の学習
Gihyo.jp : 第20回 ロジスティック回帰の実装
Machine Learning with Python - Logistic Regression
Caltech : Lecture 9 (The Linear Model II )