Regresja logistyczna to popularna metoda statystyczna używana w uczeniu maszynowym i analizie danych, służąca do modelowania zależności między zmienną zależną, która jest typu binarnego, a jednym lub więcej zmiennymi niezależnymi. W przeciwieństwie do regresji liniowej, gdzie zmienna zależna jest ciągła, w regresji logistycznej zmienna zależna jest dyskretna (zwykle 0/1 lub “nie”/”tak”).
Teoria
Model regresji logistycznej to rozwinięcie modelu regresji liniowej, gdzie zastosowano funkcję logistyczną (także nazywaną funkcją sigmoidalną) do transformacji wyników. Zostało to zrobione, aby umożliwić modelowi reprezentowanie prawdopodobieństwa, czyli wartości pomiędzy 0 a 1. Matematycznie, model regresji logistycznej z jedną zmienną niezależną można zapisać jako:
{\large P(Y=1|X=x) = \frac{1}{1 + exp(-(\beta_0 + \beta_1x))}}
Gdzie:
* P(Y=1∣X=x) to prawdopodobieństwo, że zmienna zależna Y przyjmie wartość 1, pod warunkiem danej wartości zmiennej niezależnej x
* x to zmienna niezależna,
* \beta_0 to wyraz wolny,
* \beta_1 to współczynnik przy zmiennej niezależnej.
Podobnie jak w regresji liniowej, model regresji logistycznej można rozszerzyć na wiele zmiennych niezależnych:
{\large P(Y=1|X=x) = \frac{1}{1 + exp(-(\beta_0 + \beta_1x_1 + \beta_2x_2 + … + \beta_ix_i))}}
Celem jest znalezienie takich wartości współczynników β, które najdokładniej opisują obserwowane dane. Podobnie jak w regresji liniowej, rozwiązanie analityczne układu równań może być kosztowne obliczeniowo, szczególnie dla dużych zestawów danych. W takich przypadkach często korzysta się z metod iteracyjnych, takich jak algorytm spadku gradientu.
Algorytm spadku gradientu w kontekście regresji logistycznej działa podobnie jak w przypadku regresji liniowej. Zacznijmy od losowo wybranych początkowych wartości parametrów modelu. Następnie, iteracyjnie aktualizujemy te parametry, kierując się w stronę największego spadku funkcji kosztu. Proces ten kontynuujemy, aż do osiągnięcia pewnego warunku stopu, na przykład do momentu, gdy różnica w wartościach funkcji kosztu między kolejnymi iteracjami stanie się wystarczająco mała. W kontekście regresji logistycznej, funkcją kosztu jest zazwyczaj log loss, który chcemy zminimalizować. W każdej iteracji metody spadku gradientu, parametry modelu są aktualizowane w kierunku, który najbardziej redukuje log loss.
Warto zauważyć, że rozwiązujemy tu, co do idei, podobny problem jak w przypadku regresji liniowej. Mamy układ równań, w którym każdy wiersz jest osobnym równaniem i staramy się tak dobrać wartości parametrów beta, żeby średnio błąd był jak najmniejszy. Równania nie są jednak w postaci liniowej, a nałożona jest na nie funkcja logistyczna, zapewnia nam to możliwość interpretowania wyników jako prawdopodobieństwo (skala [0,1]).
Przykład
Prześledźmy następujący przykład pięciu klientów z danymi dotyczącymi opłat miesięcznych i informacją, czy dany klient odszedł (1 – tak, 0 – nie).
Dane:
x = [20, 40, 60, 80, 100] – to są miesięczne opłaty,
y = [0, 0, 1, 1, 1] – to informacje o tym, czy klient odszedł,
n = 5
Początkowe parametry:
\beta_0 = 0
\beta_1 = 0
Współczynnik uczenia: \alpha = 0.01
Funkcja:
h_\beta(x) = \frac{1}{1+exp(-(\beta_0 + \beta_1 x))}Iteracja 1:
Obliczmy gradienty:
\frac{\partial J}{\partial \beta_0} = \frac{1}{n}\sum_{i=1}^{n} (h_\beta(x^{(i)}) – y^{(i)})
\frac{\partial J}{\partial \beta_0} = \frac{1}{5} ((\frac{1}{1+exp(-(0 + 0 * 20))} – 0) + (\frac{1}{1+exp(-(0 + 0 * 40))} – 0) + (\frac{1}{1+exp(-(0 + 0 * 60))} – 1) + (\frac{1}{1+exp(-(0 + 0 * 80))} – 1) + (\frac{1}{1+exp(-(0 + 0 * 100))} – 1)) = -0.1
\frac{\partial J}{\partial \beta_1} = \frac{1}{n}\sum_{i=1}^{n} (h_\beta(x^{(i)}) – y^{(i)}) \cdot x^{(i)}
\frac{\partial J}{\partial \beta_1} = \frac{1}{5} ((\frac{1}{1+exp(-(0 + 0 * 20))} – 0) * 20 + (\frac{1}{1+exp(-(0 + 0 * 40))} – 0) * 40 + (\frac{1}{1+exp(-(0 + 0 * 60))} – 1) * 60 + (\frac{1}{1+exp(-(0 + 0 * 80))} – 1) * 80 + (\frac{1}{1+exp(-(0 + 0 * 100))} – 1) * 100) = -18
Zaktualizujmy parametry:
\beta_0 = \beta_0 – \alpha \cdot \frac{\partial J}{\partial \beta_0} = 0 – 0.01 \cdot (-0.1) = 0.001
\beta_1 = \beta_1 – \alpha \cdot \frac{\partial J}{\partial \beta_1} = 0 – 0.01 \cdot (-18) = 0.18
Iteracja 2:
Jeszcze raz, analogicznie, obliczmy gradienty i zaktualizujmy parametry:
\frac{\partial J}{\partial \beta_0} = \frac{1}{n}\sum_{i=1}^{n} (h_\beta(x^{(i)}) – y^{(i)})
\frac{\partial J}{\partial \beta_1} = \frac{1}{n}\sum_{i=1}^{n} (h_\beta(x^{(i)}) – y^{(i)}) \cdot x^{(i)}
Tym razem rozbijmy to sobie trochę dla większej czytelności. W pierwszym kroku potrzebujemy obliczyć wartość funkcji hipotezy dla każdej wartości x^{(i)}, co daje nam:
h_\beta(x^{(1)}) = \frac{1}{1+exp(-(0.001 + 0.18 \cdot 20))} = \frac{1}{1+exp(-3.601)} \approx 0.973
h_\beta(x^{(2)}) = \frac{1}{1+exp(-(0.001 + 0.18 \cdot 40))} = \frac{1}{1+exp(-7.201)} \approx 0.999
h_\beta(x^{(3)}) = \frac{1}{1+exp(-(0.001 + 0.18 \cdot 60))} = \frac{1}{1+exp(-10.801)} \approx 0.999
h_\beta(x^{(4)}) = \frac{1}{1+exp(-(0.001 + 0.18 \cdot 80))} = \frac{1}{1+exp(-14.401)} \approx 1
h_\beta(x^{(5)}) = \frac{1}{1+exp(-(0.001 + 0.18 \cdot 100))} = \frac{1}{1+exp(-18.001)} \approx 1
Gradienty:
\frac{\partial J}{\partial \beta_0} = \frac{1}{n}\sum_{i=1}^{n} (h_\beta(x^{(i)}) – y^{(i)}) =
\frac{1}{5} ((h_\beta(x^{(1)}) – 0) + (h_\beta(x^{(2)}) – 0) + (h_\beta(x^{(3)}) – 1) + (h_\beta(x^{(4)}) – 1) + (h_\beta(x^{(5)}) – 1)) =
\frac{1}{5} \left((0.973 – 0) + (0.999 – 0) + (0.999 – 1) + (1 – 1) + (1 – 1) \right) =
\frac{1}{5} \left( 0.973 + 0.999 – 0.0001 \right) \approx 0.395
\frac{\partial J}{\partial \beta_1} = \frac{1}{n}\sum_{i=1}^{n} (h_\beta(x^{(i)}) – y^{(i)}) \cdot x^{(i)} =
\frac{1}{5} ((h_\beta(x^{(1)}) – 0) \cdot 20 + (h_\beta(x^{(2)}) – 0) \cdot 40 + (h_\beta(x^{(3)}) – 1) \cdot 60 + (h_\beta(x^{(4)}) – 1) \cdot 80 + (h_\beta(x^{(5)}) – 1) \cdot 100) =
\frac{1}{5} \left( (0.973 – 0) \cdot 20 + (0.999 – 0) \cdot 40 + (0.999 – 1) \cdot 60 + (1 – 1) \cdot 80 + (1 – 1) \cdot 100 \right) =
\frac{1}{5} \left( 0.973 \cdot 20 + 0.999 \cdot 40 – 0.001 \cdot 60 + 0 \cdot 80 + 0 \cdot 100 \right) \approx \frac{1}{5} \times 59.43 \approx 11.886
I wreszcie parametry:
\beta_0 = \beta_0 – \alpha \cdot \frac{\partial J}{\partial \beta_0} = 0.001 – 0.01 * 0.395 = -0.003
\beta_1 = \beta_1 – \alpha \cdot \frac{\partial J}{\partial \beta_1} = 0.18 – 0.01 *11.886 = 0.061
Jeśli chcesz zobaczyć do jakich wartości zbiegną ostatecznie nasze parametry, skorzystaj z poniższego kodu python:
import numpy as np x = np.array([20, 40, 60, 80, 100]) y = np.array([0, 0, 1, 1, 1]) # Na przykład etykiety 0 lub 1 # Ustawienie wartości początkowych i współczynnika uczenia b0 = 0 b1 = 0 alpha = 0.01 n_iterations = 100000 # liczba iteracji # Pętla iteracji for iteration in range(n_iterations): # Obliczanie wartości funkcji hipotezy h_x = 1 / (1 + np.exp(-(b0 + b1 * x))) # Obliczanie gradientów dJ_db0 = np.mean(h_x - y) dJ_db1 = np.mean((h_x - y) * x) # Aktualizacja parametrów b0 = b0 - alpha * dJ_db0 b1 = b1 - alpha * dJ_db1 # Wyświetlanie parametrów po każdej iteracji print(f"Iteration {iteration+1}: b0 = {b0}, b1 = {b1}")