1

バイナリ分類の問題では、出力が得られません。良性、または - - 悪性logisitc回帰の正しい答えを得るには?

それは、所望の出力を与えていない :問題のように乳癌にラベルを付けるために、バイナリ分類を使用している

第一の形状の試験列車データを返すデータセットをロードする機能がある:

x_train is of shape: (30, 381), 
y_train is of shape: (1, 381), 
x_test is of shape: (30, 188), 
y_test is of shape: (1, 188). 

そして出力を予測するロジスティック回帰分類子のためのクラスがあります。

from sklearn.datasets import load_breast_cancer 
from sklearn.model_selection import train_test_split 
from sklearn.metrics import accuracy_score 
import numpy as np 

def load_dataset(): 
    cancer_data = load_breast_cancer() 
    x_train, x_test, y_train, y_test = train_test_split(cancer_data.data, cancer_data.target, test_size=0.33) 
    x_train = x_train.T 
    x_test = x_test.T 
    y_train = y_train.reshape(1, (len(y_train))) 
    y_test = y_test.reshape(1, (len(y_test))) 
    m = x_train.shape[1] 
    return x_train, x_test, y_train, y_test, m 

class Neural_Network(): 
    def __init__(self): 
     np.random.seed(1) 
     self.weights = np.random.rand(30, 1) * 0.01 
     self.bias = np.zeros(shape=(1, 1)) 

    def sigmoid(self, x): 
     return 1/(1 + np.exp(-x)) 

    def train(self, x_train, y_train, iterations, m, learning_rate=0.5): 

     for i in range(iterations): 
      z = np.dot(self.weights.T, x_train) + self.bias 
      a = self.sigmoid(z) 

      cost = (-1/m) * np.sum(y_train * np.log(a) + (1 - y_train) * np.log(1 - a)) 

      if (i % 500 == 0): 
       print("Cost after iteration %i: %f" % (i, cost)) 

      dw = (1/m) * np.dot(x_train, (a - y_train).T) 
      db = (1/m) * np.sum(a - y_train) 

      self.weights = self.weights - learning_rate * dw 
      self.bias = self.bias - learning_rate * db 

    def predict(self, inputs): 
     m = inputs.shape[1] 
     y_predicted = np.zeros((1, m)) 
     z = np.dot(self.weights.T, inputs) + self.bias 
     a = self.sigmoid(z) 
     for i in range(a.shape[1]): 
      y_predicted[0, i] = 1 if a[0, i] > 0.5 else 0 
     return y_predicted 

if __name__ == "__main__": 
    ''' 
    step-1 : Loading data set 
       x_train is of shape: (30, 381) 
       y_train is of shape: (1, 381) 
       x_test is of shape: (30, 188) 
       y_test is of shape: (1, 188) 
    ''' 

    x_train, x_test, y_train, y_test, m = load_dataset() 

    neuralNet = Neural_Network() 

    ''' 
     step-2 : Train the network 
    ''' 

    neuralNet.train(x_train, y_train,10000,m) 


    y_predicted = neuralNet.predict(x_test) 

    print("Accuracy on test data: ") 
    print(accuracy_score(y_test, y_predicted)*100) 

この出力を与えるプログラム:

C:\Python36\python.exe C:/Users/LENOVO/PycharmProjects/MarkDmo001/Numpy.py 
Cost after iteration 0: 5.263853 
C:/Users/LENOVO/PycharmProjects/MarkDmo001/logisticReg.py:25: RuntimeWarning: overflow encountered in exp 
    return 1/(1 + np.exp(-x)) 
C:/Users/LENOVO/PycharmProjects/MarkDmo001/logisticReg.py:33: RuntimeWarning: divide by zero encountered in log 
    cost = (-1/m) * np.sum(y_train * np.log(a) + (1 - y_train) * np.log(1 - a)) 
C:/Users/LENOVO/PycharmProjects/MarkDmo001/logisticReg.py:33: RuntimeWarning: invalid value encountered in multiply 
    cost = (-1/m) * np.sum(y_train * np.log(a) + (1 - y_train) * np.log(1 - a)) 
Cost after iteration 500: nan 
Cost after iteration 1000: nan 
Cost after iteration 1500: nan 
Cost after iteration 2000: nan 
Cost after iteration 2500: nan 
Cost after iteration 3000: nan 
Cost after iteration 3500: nan 
Cost after iteration 4000: nan 
Cost after iteration 4500: nan 
Cost after iteration 5000: nan 
Cost after iteration 5500: nan 
Cost after iteration 6000: nan 
Cost after iteration 6500: nan 
Cost after iteration 7000: nan 
Cost after iteration 7500: nan 
Cost after iteration 8000: nan 
Cost after iteration 8500: nan 
Cost after iteration 9000: nan 
Cost after iteration 9500: nan 

Accuracy: 
0.0 

答えて

2

問題は勾配を爆発さ。入力を正規化して[0, 1]にする必要があります。

訓練データでフィーチャ3とフィーチャ23を見ると、3000より大きい値が表示されます。これらのフィーチャに最初のウェイトが掛けられた後も、それでも範囲は[0, 30]です。したがって、最初の反復では、zベクトルは約50結果として、最大値でのみ正の数が含まれ、aベクトル(あなたのシグモイドの出力)は次のようになります。最初にあるので、

[0.9994797 0.99853904 0.99358676 0.99999973 0.98392862 0.99983016 0.99818802 ...] 

をステップでは、モデルは常に高い信頼度で1を予測します。しかし、それは必ずしも正しいとは限りません。そして、あなたのモデル出力が大きな勾配につながる高い確率は、最高値のdwを見ると分かります。私の場合は、

  • dw[3]は388
  • dw[23]は571

だったと他の値は[0, 55]に横たわっていました。したがって、これらのフィーチャの大きな入力がどのように爆発的なグラデーションにつながるのかをはっきりと確認できます。勾配降下が今や反対方向へのステップが大きすぎるので、次のステップの重みは[0, 0.01]ではなく、[-285, 0.002]になります。これは状況を悪化させます。次の反復では、zには100万回程度の値が含まれており、シグモイド関数でオーバーフローが発生します。

ソリューション

  1. 彼らはおおよそ互いに相殺するように、[-0.01, 0.01][0, 1]
  2. 利用の重みに、あなたの入力を正規化します。そうでなければ、zの値は、あなたが持っている機能の数に比例して直線的に変化します。

入力を正規化するためとして、あなたが使用することができますsklearnのMinMaxScaler:あなたのx_trainx_test形状(num_features, num_samples)を持っていながらsklearnは、トレーニング入力は形状(num_samples, num_features)を持っていることを期待するので

x_train, x_test, y_train, y_test, m = load_dataset() 

scaler = MinMaxScaler() 
x_train_normalized = scaler.fit_transform(x_train.T).T 

neuralNet = Neural_Network() 

''' 
    step-2 : Train the network 
''' 

neuralNet.train(x_train_normalized, y_train,10000,m) 

# Use the same transformation on the test inputs as on the training inputs 
x_test_normalized = scaler.transform(x_test.T).T 
y_predicted = neuralNet.predict(x_test_normalized) 

.T sがあります。

+0

私は出力を得ていません。解決策2を適用する方法を教えてください。私は異なる重みを試しましたが、同じ出力を得ています。 –

+0

上記のコードをコピーして、60〜71行目を答えのコードブロックに置き換えました。その後、私は0.06の損失と97.8%の精度を得た。 ところで、精度を評価するには、 'y_test'と' y_predicted'が2次元配列であるため、 'print(accuracy_score(y_test [0]、y_predicted [0])* 100)'を呼び出す必要があります。 –

関連する問題