Algorytmy klasyfikacji - regresja logistyczna

Wprowadzenie do regresji logistycznej

Regresja logistyczna to nadzorowany algorytm klasyfikacji uczenia się używany do przewidywania prawdopodobieństwa zmiennej docelowej. Charakter zmiennej docelowej lub zależnej jest dychotomiczny, co oznacza, że ​​byłyby tylko dwie możliwe klasy.

Mówiąc prościej, zmienna zależna ma charakter binarny i zawiera dane zakodowane jako 1 (oznacza sukces / tak) lub 0 (oznacza niepowodzenie / nie).

Matematycznie model regresji logistycznej przewiduje P (Y = 1) jako funkcję X. Jest to jeden z najprostszych algorytmów ML, który można wykorzystać do różnych problemów klasyfikacyjnych, takich jak wykrywanie spamu, przewidywanie cukrzycy, wykrywanie raka itp.

Rodzaje regresji logistycznej

Ogólnie regresja logistyczna oznacza binarną regresję logistyczną z binarnymi zmiennymi docelowymi, ale mogą istnieć jeszcze dwie kategorie zmiennych docelowych, które można na jej podstawie przewidzieć. W oparciu o tę liczbę kategorii regresję logistyczną można podzielić na następujące typy -

Binarny lub dwumianowy

W takiej klasyfikacji zmienna zależna będzie miała tylko dwa możliwe typy 1 i 0. Na przykład zmienne te mogą reprezentować sukces lub porażkę, tak lub nie, wygraną lub przegraną itp.

Wielomian

W takiej klasyfikacji zmienna zależna może mieć 3 lub więcej możliwych typów nieuporządkowanych lub typów, które nie mają znaczenia ilościowego. Na przykład te zmienne mogą reprezentować „Typ A”, „Typ B” lub „Typ C”.

Porządkowy

W takiej klasyfikacji zmienna zależna może mieć 3 lub więcej możliwych typów uporządkowanych lub typów mających znaczenie ilościowe. Na przykład zmienne te mogą oznaczać „słabe” lub „dobre”, „bardzo dobre”, „doskonałe”, a każda kategoria może mieć wyniki takie jak 0,1,2,3.

Założenia regresji logistycznej

Zanim zagłębimy się w implementację regresji logistycznej, musimy zdawać sobie sprawę z następujących założeń dotyczących tego samego -

  • W przypadku binarnej regresji logistycznej zmienne docelowe muszą być zawsze binarne, a pożądany wynik jest reprezentowany przez poziom czynnika 1.

  • W modelu nie powinno być żadnych współliniowości, co oznacza, że ​​zmienne niezależne muszą być od siebie niezależne.

  • W naszym modelu musimy uwzględnić znaczące zmienne.

  • Do regresji logistycznej powinniśmy wybrać dużą próbę.

Binarny model regresji logistycznej

Najprostszą formą regresji logistycznej jest binarna lub dwumianowa regresja logistyczna, w której zmienna przewidywana lub zależna może mieć tylko 2 możliwe typy 1 lub 0. Pozwala nam to modelować związek między wieloma zmiennymi predykcyjnymi a binarną / dwumianową zmienną docelową. W przypadku regresji logistycznej funkcja liniowa jest zasadniczo używana jako dane wejściowe do innej funkcji, na przykład w następującej relacji -

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

Oto funkcja logistyczna lub sigmoidalna, którą można podać w następujący sposób -

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

Do krzywej sigmoidalnej można przedstawić za pomocą poniższego wykresu. Widzimy, że wartości osi Y leżą między 0 a 1 i przecinają oś przy 0,5.

Zajęcia można podzielić na pozytywne lub negatywne. Wynik jest objęty prawdopodobieństwem klasy dodatniej, jeśli mieści się między 0 a 1. Dla naszej implementacji interpretujemy wynik funkcji hipotezy jako dodatni, jeśli jest ≥0,5, w przeciwnym razie ujemny.

Musimy również zdefiniować funkcję straty, aby zmierzyć, jak dobrze działa algorytm, używając wag na funkcjach, reprezentowanych przez theta w następujący sposób -

ℎ = ()

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

Teraz, po zdefiniowaniu funkcji straty, naszym głównym celem jest zminimalizowanie funkcji straty. Można to zrobić za pomocą dopasowania ciężarków, czyli zwiększając lub zmniejszając ciężary. Przy pomocy pochodnych funkcji straty dla każdej wagi moglibyśmy wiedzieć, jakie parametry powinny mieć wagę większą, a które mniejszą.

Poniższe równanie spadku gradientu mówi nam, jak zmieniłyby się straty, gdybyśmy zmodyfikowali parametry -

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

Implementacja w Pythonie

Teraz zaimplementujemy powyższą koncepcję dwumianowej regresji logistycznej w Pythonie. W tym celu korzystamy z wielowymiarowego zbioru danych o kwiatach o nazwie „tęczówka”, który ma 3 klasy po 50 instancji każda, ale będziemy używać dwóch pierwszych kolumn cech. Każda klasa reprezentuje rodzaj kwiatu irysa.

Najpierw musimy zaimportować niezbędne biblioteki w następujący sposób -

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

Następnie załaduj zestaw danych tęczówki w następujący sposób -

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

Możemy wykreślić następujące dane treningowe -

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();

Następnie zdefiniujemy funkcję sigmoidalną, funkcję straty i zejście gradientu w następujący sposób -

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)

Teraz zainicjuj wagi w następujący sposób -

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')

Za pomocą następującego skryptu możemy przewidzieć prawdopodobieństwa wyjścia -

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()

Następnie możemy ocenić model i wykreślić go w następujący sposób -

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');

Wielomianowy model regresji logistycznej

Inną użyteczną formą regresji logistycznej jest wielomianowa regresja logistyczna, w której zmienna docelowa lub zależna może mieć 3 lub więcej możliwych typów nieuporządkowanych, tj. Typów nie mających znaczenia ilościowego.

Implementacja w Pythonie

Teraz zaimplementujemy powyższą koncepcję wielomianowej regresji logistycznej w Pythonie. W tym celu używamy zestawu danych ze sklearn o nazwie digit.

Najpierw musimy zaimportować niezbędne biblioteki w następujący sposób -

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

Następnie musimy załadować cyfrowy zbiór danych -

digits = datasets.load_digits()

Teraz zdefiniuj macierz cech (X) i wektor odpowiedzi (y) w następujący sposób -

X = digits.data
y = digits.target

Za pomocą następnego wiersza kodu możemy podzielić X i y na zestawy uczące i testowe -

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

Teraz utwórz obiekt regresji logistycznej w następujący sposób -

digreg = linear_model.LogisticRegression()

Teraz musimy wytrenować model przy użyciu zestawów uczących w następujący sposób -

digreg.fit(X_train, y_train)

Następnie przygotuj prognozy dotyczące zestawu testów w następujący sposób -

y_pred = digreg.predict(X_test)

Następnie wydrukuj dokładność modelu w następujący sposób -

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

Wynik

Accuracy of Logistic Regression model is: 95.6884561891516

Z powyższego wyniku widać, że dokładność naszego modelu wynosi około 96 procent.