分類アルゴリズム-ロジスティック回帰

ロジスティック回帰の概要

ロジスティック回帰は、ターゲット変数の確率を予測するために使用される教師あり学習分類アルゴリズムです。ターゲット変数または従属変数の性質は二分法です。つまり、可能なクラスは2つだけです。

簡単に言うと、従属変数は本質的にバイナリであり、データは1(成功/はいを表す)または0(失敗/いいえを表す)としてコード化されています。

数学的には、ロジスティック回帰モデルはXの関数としてP(Y = 1)を予測します。これは、スパム検出、糖尿病予測、癌検出などのさまざまな分類問題に使用できる最も単純なMLアルゴリズムの1つです。

ロジスティック回帰の種類

一般に、ロジスティック回帰とは、バイナリターゲット変数を持つバイナリロジスティック回帰を意味しますが、それによって予測できるターゲット変数には、さらに2つのカテゴリがあります。これらのカテゴリ数に基づいて、ロジスティック回帰は次のタイプに分類できます。

バイナリまたは二項

このような種類の分類では、従属変数は1と0の2つの可能なタイプのみを持ちます。たとえば、これらの変数は、成功または失敗、はいまたはいいえ、勝ちまたは負けなどを表す場合があります。

多項

このような種類の分類では、従属変数は3つ以上の順序付けられていないタイプ、または量的有意性のないタイプを持つことができます。たとえば、これらの変数は「タイプA」または「タイプB」または「タイプC」を表す場合があります。

序数

このような種類の分類では、従属変数は3つ以上の可能な順序付きタイプまたは量的有意性を持つタイプを持つことができます。たとえば、これらの変数は「悪い」または「良い」、「非常に良い」、「優れている」を表す場合があり、各カテゴリのスコアは0、1、2、3のようになります。

ロジスティック回帰の仮定

ロジスティック回帰の実装に飛び込む前に、同じことについて次の仮定に注意する必要があります。

  • バイナリロジスティック回帰の場合、ターゲット変数は常にバイナリである必要があり、目的の結果は因子レベル1で表されます。

  • モデルに多重共線性があってはなりません。つまり、独立変数は互いに独立している必要があります。

  • モデルに意味のある変数を含める必要があります。

  • ロジスティック回帰には、大きなサンプルサイズを選択する必要があります。

バイナリロジスティック回帰モデル

ロジスティック回帰の最も単純な形式は、ターゲット変数または従属変数が1または0の2つの可能なタイプのみを持つことができるバイナリまたは二項ロジスティック回帰です。これにより、複数の予測変数とバイナリ/二項ターゲット変数の間の関係をモデル化できます。ロジスティック回帰の場合、線形関数は基本的に次の関係のように別の関数への入力として使用されます。

$$ h _ {\ theta} {(x)} = g(\ theta ^ {T} x)ℎ0≤h_ {\ theta}≤1$$

ここに、次のように与えることができるロジスティック関数またはシグモイド関数があります-

$$ g(z)= \ frac {1} {1 + e ^ {-z}}ℎ= \ theta ^ {T} $$

シグモイド曲線は、次のグラフを使用して表すことができます。y軸の値が0と1の間にあり、0.5で軸と交差していることがわかります。

クラスはポジティブまたはネガティブに分けることができます。出力は、0から1の間にある場合、正のクラスの確率になります。この実装では、仮説関数の出力が0.5以上の場合は正として解釈され、それ以外の場合は負として解釈されます。

また、次のようにシータで表される関数の重みを使用してアルゴリズムがどの程度うまく機能するかを測定するために、損失関数を定義する必要があります。

ℎ=()

$$ J(\ theta)= \ frac {1} {m}。(-y ^ {T} log(h)-(1 -y)^ Tlog(1-h))$$

ここで、損失関数を定義した後、私たちの主な目標は損失関数を最小化することです。これは、ウェイトをフィッティングすることで実行できます。つまり、ウェイトを増減することによって実行できます。各重みに対する損失関数の導関数の助けを借りて、どのパラメーターが高い重みを持つべきか、そして何がより小さな重みを持つべきかを知ることができます。

次の勾配降下方程式は、パラメータを変更した場合に損失がどのように変化するかを示しています。

$$ \ frac {()} {\ theta_ {j}} = \ frac {1} {m} X ^ {T}(()−)$$

Pythonでの実装

次に、Pythonで上記の二項ロジスティック回帰の概念を実装します。この目的のために、それぞれ50インスタンスの3つのクラスを持つ「iris」という名前の多変量花データセットを使用していますが、最初の2つの特徴列を使用します。すべてのクラスは、アイリスの花の一種を表しています。

まず、必要なライブラリを次のようにインポートする必要があります-

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import datasets

次に、次のようにアイリスデータセットをロードします-

iris = datasets.load_iris()
X = iris.data[:, :2]
y = (iris.target != 0) * 1

トレーニングデータをプロットできます。

plt.figure(figsize=(6, 6))
plt.scatter(X[y == 0][:, 0], X[y == 0][:, 1], color='g', label='0')
plt.scatter(X[y == 1][:, 0], X[y == 1][:, 1], color='y', label='1')
plt.legend();

次に、シグモイド関数、損失関数、最急降下法を次のように定義します。

class LogisticRegression:
   def __init__(self, lr=0.01, num_iter=100000, fit_intercept=True, verbose=False):
      self.lr = lr
      self.num_iter = num_iter
      self.fit_intercept = fit_intercept
      self.verbose = verbose
   def __add_intercept(self, X):
      intercept = np.ones((X.shape[0], 1))
      return np.concatenate((intercept, X), axis=1)
   def __sigmoid(self, z):
      return 1 / (1 + np.exp(-z))
   def __loss(self, h, y):
      return (-y * np.log(h) - (1 - y) * np.log(1 - h)).mean()
   def fit(self, X, y):
      if self.fit_intercept:
         X = self.__add_intercept(X)

ここで、次のように重みを初期化します。

self.theta = np.zeros(X.shape[1])
   for i in range(self.num_iter):
      z = np.dot(X, self.theta)
      h = self.__sigmoid(z)
      gradient = np.dot(X.T, (h - y)) / y.size
      self.theta -= self.lr * gradient
      z = np.dot(X, self.theta)
      h = self.__sigmoid(z)
      loss = self.__loss(h, y)
      if(self.verbose ==True and i % 10000 == 0):
         print(f'loss: {loss} \t')

次のスクリプトの助けを借りて、出力確率を予測することができます-

def predict_prob(self, X):
   if self.fit_intercept:
      X = self.__add_intercept(X)
   return self.__sigmoid(np.dot(X, self.theta))
def predict(self, X):
   return self.predict_prob(X).round()

次に、モデルを評価し、次のようにプロットできます。

model = LogisticRegression(lr=0.1, num_iter=300000)
preds = model.predict(X)
(preds == y).mean()

plt.figure(figsize=(10, 6))
plt.scatter(X[y == 0][:, 0], X[y == 0][:, 1], color='g', label='0')
plt.scatter(X[y == 1][:, 0], X[y == 1][:, 1], color='y', label='1')
plt.legend()
x1_min, x1_max = X[:,0].min(), X[:,0].max(),
x2_min, x2_max = X[:,1].min(), X[:,1].max(),
xx1, xx2 = np.meshgrid(np.linspace(x1_min, x1_max), np.linspace(x2_min, x2_max))
grid = np.c_[xx1.ravel(), xx2.ravel()]
probs = model.predict_prob(grid).reshape(xx1.shape)
plt.contour(xx1, xx2, probs, [0.5], linewidths=1, colors='red');

多項ロジスティック回帰モデル

ロジスティック回帰のもう1つの有用な形式は、多項ロジスティック回帰です。この回帰では、ターゲット変数または従属変数が3つ以上の順序付けられていないタイプ、つまり量的有意性のないタイプを持つことができます。

Pythonでの実装

次に、Pythonで上記の多項ロジスティック回帰の概念を実装します。この目的のために、digitという名前のsklearnのデータセットを使用しています。

まず、必要なライブラリを次のようにインポートする必要があります-

Import sklearn
from sklearn import datasets
from sklearn import linear_model
from sklearn import metrics
from sklearn.model_selection import train_test_split

次に、数字データセットをロードする必要があります-

digits = datasets.load_digits()

ここで、特徴行列(X)と応答ベクトル(y)を次のように定義します。

X = digits.data
y = digits.target

次のコード行の助けを借りて、Xとyをトレーニングセットとテストセットに分割できます-

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.4, random_state=1)

次に、ロジスティック回帰のオブジェクトを次のように作成します-

digreg = linear_model.LogisticRegression()

ここで、次のようにトレーニングセットを使用してモデルをトレーニングする必要があります。

digreg.fit(X_train, y_train)

次に、テストセットの予測を次のように行います-

y_pred = digreg.predict(X_test)

次に、モデルの精度を次のように出力します-

print("Accuracy of Logistic Regression model is:",
metrics.accuracy_score(y_test, y_pred)*100)

出力

Accuracy of Logistic Regression model is: 95.6884561891516

上記の出力から、モデルの精度は約96%であることがわかります。