2017-12-13 25 views
3

私はタイトルが言うようにしようとしていますが、私はそれを行う方法を本当に理解することができません。ロジスティック回帰勾配降下

何が間違っているのか理解するのを助けることができれば、非常に役に立ちます。バッチ勾配降下を使ってロジスティック回帰をしなければならない。

import matplotlib.pyplot as plt 
import numpy as np 
%matplotlib inline 

X = np.asarray([ 
[0.50],[0.75],[1.00],[1.25],[1.50],[1.75],[1.75], 
[2.00],[2.25],[2.50],[2.75],[3.00],[3.25],[3.50], 
[4.00],[4.25],[4.50],[4.75],[5.00],[5.50]]) 

y = np.asarray([0,0,0,0,0,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1]) 

m = len(X) 

def sigmoid(a): 
    return 1.0/(1 + np.exp(-a)) 

def gradient_Descent(theta, alpha, X , y): 
    for i in range(0,m): 
     cost = ((-y) * np.log(sigmoid(X[i]))) - ((1 - y) * np.log(1 - sigmoid(X[i]))) 
    grad = theta - alpha * (1.0/m) * (np.dot(cost,X[i])) 
    theta = theta - alpha * grad 
return 

gradient_Descent(0.1,0.005,X,y) 

私はこれを行う必要がありますが、私はそれを動作させる方法を理解できないようです。

Method

+0

これは動作しないコードなので、どのような問題が発生したかは記述していません。 (私はupvotesの数を取得していません) – sascha

答えて

1

あなたがここに混ざっていくつかのものを持っているように見えます。これを行う際には、ベクターの形状を把握し、賢明な結果が得られるようにすることが重要です。たとえば、あなたがしてコストを計算している:あなたのケースでは

cost = ((-y) * np.log(sigmoid(X[i]))) - ((1 - y) * np.log(1 - sigmoid(X[i]))) 

yは20の項目とXとのベクトルである[i]は、単一の値です。これにより、コスト計算が意味をなさない20項目のベクトルになります。あなたのコストは単一の値でなければなりません。 (勾配降下関数で何の理由もないので、このコストを何度も計算しています)。

また、データに合わせるためには、バイアス用語をXに追加する必要があります。だからそこから始めましょう。

Y = np.array([0,0,0,0,0,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1]).reshape([-1, 1]) 
# reshape Y so it's column vector so matrix multiplication is easier 
Theta = np.array([[0], [0]]) 

あなたのシグモイド関数が良いです:

X = np.asarray([ 
    [0.50],[0.75],[1.00],[1.25],[1.50],[1.75],[1.75], 
    [2.00],[2.25],[2.50],[2.75],[3.00],[3.25],[3.50], 
    [4.00],[4.25],[4.50],[4.75],[5.00],[5.50]]) 

ones = np.ones(X.shape) 
X = np.hstack([ones, X]) 
# X.shape is now (20, 2) 

は、シータは今だからを初期化し、Y各X用の2つの値が必要になります。 Thetaはの形状があるため、コスト関数の動作

def sigmoid(a): 
    return 1.0/(1 + np.exp(-a)) 

def cost(x, y, theta): 
    m = x.shape[0] 
    h = sigmoid(np.matmul(x, theta)) 
    cost = (np.matmul(-y.T, np.log(h)) - np.matmul((1 -y.T), np.log(1 - h)))/m 
    return cost 

(2、1)とXは(20、2)の形状をしているので、matmul(X, Theta)を成形することになる(20、1:のもベクトル化コスト関数を作ってみましょう)。その後、行列は、Yの転置(y.Tの形状は(1,20))を乗算し、結果として単一の値となり、特定の値のThetaが与えられます。

我々は、バッチ勾配降下の単一ステップ実行機能書くことができる:

def gradient_Descent(theta, alpha, x , y): 
    m = x.shape[0] 
    h = sigmoid(np.matmul(x, theta)) 
    grad = np.matmul(X.T, (h - y))/m; 
    theta = theta - alpha * grad 
    return theta 

注意np.matmul(X.T, (h - y))乗算された形状(2、20)及び(20、1)(の形状をもたらします2、1) - 同じ形状のThetaです。これはグラデーションから欲しいものです。これは、あなたの学習率で乗算し、最初のThetaから減算することを可能にします。これは、勾配降下が行うはずのことです。

n_iterations = 500 
learning_rate = 0.5 

for i in range(n_iterations): 
    Theta = gradient_Descent(Theta, learning_rate, X, Y) 
    if i % 50 == 0: 
     print(cost(X, Y, Theta)) 

これは、すべての50回の反復が着実に減少し、コストが生じ、コストを、印刷します:それは見えるまで、それが収束するよう

は、だから今、あなただけのイテレーションとアップデートシータの数のループを書きますあなたが望んでいること:

[[0.6410409]] [[0.44766253]] [[0.41593581]] [[0.40697167]] [[0.40377785]] [[0。4024982]] [[0.40195]] [[0.40170533]] [[0.40159325]] [[0.40154101]]

あなたはThetaの異なる初期値を試すことができますし、それは常にに収束するが表示されます同じこと。

今、あなたは、予測を行うためにThetaのあなたの新しく発見された値を使用することができます。

h = sigmoid(np.matmul(X, Theta)) 
print((h > .5).astype(int)) 

これはあなたのデータへの線形フィットのために期待するものを出力します。

[[0] [0] [0] [0] [0] [0] [0] [0] [0] [0] [1] [1] [1] [1] [1] [1] [1] [1] [1] [1]

+0

これは理解するのは本当に簡単でした、私は行列を使用したくないが、結局はより簡単に思える。素晴らしい答え! – Sean

関連する問題