Ostateczny przewodnik po regresji logistycznej w Pythonie PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Ostateczny przewodnik po regresji logistycznej w Pythonie

Wprowadzenie

Czasami mylony z regresji liniowej przez nowicjuszy – ze względu na udostępnienie terminu regresja - regresja logistyczna bardzo różni się od regresji liniowej. Podczas gdy regresja liniowa przewiduje wartości takie jak 2, 2.45, 6.77 lub wartości ciągłe, dzięki czemu jest to regresja algorytm, regresja logistyczna przewiduje wartości takie jak 0 lub 1, 1 lub 2 lub 3, które są dyskretne wartości, dzięki czemu jest to klasyfikacja algorytm. Tak, to się nazywa regresja ale jest klasyfikacja algorytm. Więcej o tym za chwilę.

Dlatego jeśli Twój problem z nauką o danych dotyczy wartości ciągłych, możesz zastosować a regresja algorytm (regresja liniowa jest jednym z nich). W przeciwnym razie, jeśli wiąże się to z klasyfikacją danych wejściowych, wartości dyskretnych lub klas, można zastosować a klasyfikacja algorytm (regresja logistyczna jest jednym z nich).

W tym przewodniku będziemy wykonywać regresję logistyczną w Pythonie za pomocą biblioteki Scikit-Learn. Wyjaśnimy również, dlaczego słowo "regresja" jest obecny w nazwie i jak działa regresja logistyczna.

W tym celu najpierw załadujemy dane, które zostaną sklasyfikowane, zwizualizowane i wstępnie przetworzone. Następnie zbudujemy model regresji logistycznej, który zrozumie te dane. Model ten zostanie następnie oceniony i wykorzystany do przewidywania wartości na podstawie nowych danych wejściowych.

Motywacja

Firma, w której pracujesz, nawiązała współpracę z tureckim gospodarstwem rolnym. Ta współpraca obejmuje sprzedaż nasion dyni. Pestki dyni są bardzo ważne w żywieniu człowieka. Zawierają dobrą proporcję węglowodanów, tłuszczu, białka, wapnia, potasu, fosforu, magnezu, żelaza i cynku.

W zespole zajmującym się analizą danych Twoim zadaniem jest odróżnienie rodzajów nasion dyni na podstawie samych danych – lub klasyfikacja dane według rodzaju nasion.

Turecka farma pracuje z dwoma rodzajami nasion dyni, jeden nazywa się erçevelik i inni Ürgup Sivrisi.

Aby sklasyfikować pestki dyni, Twój zespół śledził artykuł z 2021 r. „Wykorzystanie metod uczenia maszynowego w klasyfikacji nasion dyni (Cucurbita pepo L.). Zasoby genetyczne i ewolucja upraw” z Koklu, Sarigil i Ozbek – w tym artykule jest metodologia fotografowania i wyodrębniania pomiarów nasion z obrazów.

Po zakończeniu procesu opisanego w artykule wyodrębniono następujące pomiary:

  • Obszar – liczba pikseli w granicach pestki dyni
  • Obwód – obwód w pikselach pestki dyni
  • Długość osi głównej – również obwód w pikselach pestki dyni
  • Długość osi podrzędnej – mała odległość osi pestki dyni
  • Ekscentryczność – ekscentryczność pestki dyni
  • Obszar wypukły – liczba pikseli najmniejszej wypukłej muszli w obszarze utworzonym przez pestkę dyni
  • Stopień – stosunek obszaru pestek dyni do pikseli obwiedni
  • Równoważna średnica – pierwiastek kwadratowy z pomnożenia powierzchni pestki dyni przez cztery podzielony przez pi
  • Ścisłość – proporcja powierzchni pestki dyni w stosunku do powierzchni koła o tym samym obwodzie
  • Solidność – wypukły i wypukły stan pestek dyni
  • Okrągłość – owalność pestek dyni bez uwzględnienia zniekształceń brzegów
  • Aspect Ratio – proporcje pestek dyni

To są pomiary, z którymi musisz pracować. Oprócz pomiarów istnieje również Klasa etykieta dla dwóch rodzajów pestek dyni.

Aby rozpocząć klasyfikację nasion, zaimportujmy dane i zacznijmy się im przyglądać.

Zrozumienie zbioru danych

Uwaga: Możesz pobrać zestaw danych dyni tutaj.

Po pobraniu zestawu danych możemy go załadować do struktury dataframe za pomocą pandas biblioteka. Ponieważ jest to plik Excel, użyjemy read_excel() metoda:

import pandas as pd

fpath = 'dataset/pumpkin_seeds_dataset.xlsx' 
df = pd.read_excel(fpath)

Po załadowaniu danych możemy szybko rzucić okiem na pierwsze 5 wierszy za pomocą head() metoda:

df.head() 

To skutkuje:

	Area 	Perimeter 	Major_Axis_Length 	Minor_Axis_Length 	Convex_Area 	Equiv_Diameter 	Eccentricity 	Solidity 	Extent 	Roundness 	Aspect_Ration 	Compactness 	Class
0 	56276 	888.242 	326.1485 			220.2388 			56831 			267.6805 		0.7376 			0.9902 		0.7453 	0.8963 		1.4809 			0.8207 			Çerçevelik
1 	76631 	1068.146 	417.1932 			234.2289 			77280 			312.3614 		0.8275 			0.9916 		0.7151 	0.8440 		1.7811 			0.7487 			Çerçevelik
2 	71623 	1082.987 	435.8328 			211.0457 			72663 			301.9822 		0.8749 			0.9857 		0.7400 	0.7674 		2.0651 			0.6929 			Çerçevelik
3 	66458 	992.051 	381.5638 			222.5322 			67118 			290.8899 		0.8123 			0.9902 		0.7396 	0.8486 		1.7146 			0.7624 			Çerçevelik
4 	66107 	998.146 	383.8883 			220.4545 			67117 			290.1207 		0.8187 			0.9850 		0.6752 	0.8338 		1.7413 			0.7557 			Çerçevelik

Tutaj mamy wszystkie pomiary w odpowiednich kolumnach, nasz cechy, a także Klasa kolumna, nasza cel, który jest ostatnim w ramce danych. Możemy zobaczyć, ile mamy pomiarów za pomocą shape atrybut:

df.shape 

Wynik to:

(2500, 13)

Wynik kształtu mówi nam, że w zestawie danych jest 2500 wpisów (lub wierszy) i 13 kolumn. Ponieważ wiemy, że istnieje jedna kolumna docelowa – oznacza to, że mamy 12 kolumn funkcji.

Możemy teraz zbadać zmienną docelową, nasiona dyni Class. Ponieważ będziemy przewidywać tę zmienną, warto zobaczyć, ile mamy próbek każdego nasiona dyni. Zwykle im mniejsza różnica między liczbą wystąpień w naszych klasach, tym bardziej zrównoważona jest nasza próba i tym lepsze nasze przewidywania.

Tę kontrolę można przeprowadzić, licząc każdą próbkę nasion za pomocą value_counts() metoda:

df['Class'].value_counts() 

Powyższy kod wyświetla:

Çerçevelik       1300
Ürgüp Sivrisi    1200
Name: Class, dtype: int64

Widzimy, że istnieje 1300 próbek erçevelik nasion i 1200 próbek Ürgup Sivrisi nasionko. Zauważ, że różnica między nimi wynosi 100 próbek, bardzo mała różnica, co jest dla nas dobre i wskazuje, że nie ma potrzeby ponownego równoważenia liczby próbek.

Przyjrzyjmy się również opisowym statystykom naszych funkcji za pomocą describe() metoda, aby zobaczyć, jak dobrze rozłożone są dane. Dokonamy również transpozycji wynikowej tabeli za pomocą T aby ułatwić porównywanie statystyk:

df.describe().T

Wynikowa tabela to:

					count 	mean 			std 			min 		25% 			50% 			75% 			max
Area 				2500.0 	80658.220800 	13664.510228 	47939.0000 	70765.000000 	79076.00000 	89757.500000 	136574.0000
Perimeter 			2500.0 	1130.279015 	109.256418 		868.4850 	1048.829750 	1123.67200 		1203.340500 	1559.4500
Major_Axis_Length 	2500.0 	456.601840 		56.235704 		320.8446 	414.957850 		449.49660 		492.737650 		661.9113
Minor_Axis_Length 	2500.0 	225.794921 		23.297245 		152.1718 	211.245925 		224.70310 		240.672875 		305.8180
Convex_Area 		2500.0 	81508.084400 	13764.092788 	48366.0000 	71512.000000 	79872.00000 	90797.750000 	138384.0000
Equiv_Diameter 		2500.0 	319.334230 		26.891920 		247.0584 	300.167975 		317.30535 		338.057375 		417.0029
Eccentricity 		2500.0 	0.860879 		0.045167 		0.4921 		0.831700 		0.86370 		0.897025 		0.9481
Solidity 			2500.0 	0.989492 		0.003494 		0.9186 		0.988300 		0.99030 		0.991500 		0.9944
Extent 				2500.0 	0.693205 		0.060914 		0.4680 		0.658900 		0.71305 		0.740225 		0.8296
Roundness 			2500.0 	0.791533 		0.055924 		0.5546 		0.751900 		0.79775 		0.834325 		0.9396
Aspect_Ration 		2500.0 	2.041702 		0.315997 		1.1487 		1.801050 		1.98420 		2.262075 		3.1444
Compactness 		2500.0 	0.704121 		0.053067 		0.5608 		0.663475 		0.70770 		0.743500 		0.9049

Patrząc na tabelę, porównując oznaczać i odchylenie standardowe (std) widać, że większość cech ma średnią daleką od odchylenia standardowego. Oznacza to, że wartości danych nie są skoncentrowane wokół wartości średniej, ale bardziej rozproszone wokół niej – innymi słowy, mają duża zmienność.

Również, patrząc na minimum (min) i maksymalny (max) kolumny, niektóre funkcje, takie jak Area, Convex_Area, mają duże różnice między wartościami minimalnymi i maksymalnymi. Oznacza to, że te kolumny zawierają bardzo małe dane, a także bardzo duże wartości danych lub wyższa amplituda między wartościami danych.

Przy dużej zmienności, wysokiej amplitudzie i cechach z różnymi jednostkami miary, większość naszych danych skorzystałaby z posiadania tej samej skali dla wszystkich cech lub bycia łuskowaty. Skalowanie danych wycentruje dane wokół średniej i zmniejszy jej wariancję.

Ten scenariusz prawdopodobnie wskazuje również, że w danych występują wartości odstające i ekstremalne. Więc najlepiej mieć trochę leczenie odstające oprócz skalowania danych.

Istnieje kilka algorytmów uczenia maszynowego, na przykład algorytmy oparte na drzewie, takie jak Klasyfikacja lasów losowych, na które nie ma wpływu duża wariancja danych, wartości odstające i wartości ekstremalne. Regresja logistyczna jest inny, opiera się na funkcji, która kategoryzuje nasze wartości, a na parametry tej funkcji mogą mieć wpływ wartości, które są poza ogólnym trendem danych i mają dużą wariancję.

Więcej o regresji logistycznej zrozumiemy za chwilę, gdy ją zaimplementujemy. Na razie możemy dalej eksplorować nasze dane.

Uwaga: W informatyce jest popularne powiedzenie: „Śmieci wchodzą, śmieci wychodzą” (GIGO), który doskonale nadaje się do uczenia maszynowego. Oznacza to, że gdy mamy śmieciowe dane – pomiary, które same w sobie nie opisują zjawiska, dane, które nie zostały zrozumiane i dobrze przygotowane zgodnie z rodzajem algorytmu lub modelu, prawdopodobnie wygenerują niepoprawny wynik, który nie będzie działał na na co dzień.
To jeden z powodów, dla których tak ważne jest badanie, rozumienie danych i sposób działania wybranego modelu. Robiąc to, możemy uniknąć umieszczania śmieci w naszym modelu – zamiast tego nadawać mu wartość i uzyskiwać wartość.

Wizualizacja danych

Do tej pory, dzięki statystykom opisowym, mamy nieco abstrakcyjną migawkę niektórych cech danych. Kolejnym ważnym krokiem jest wizualizacja tego i potwierdzenie naszej hipotezy o wysokiej wariancji, amplitudzie i wartościach odstających. Aby sprawdzić, czy to, co zaobserwowaliśmy do tej pory, pokazuje dane, możemy wykreślić kilka wykresów.

Interesujące jest również zobaczyć, jak cechy odnoszą się do dwóch przewidywanych klas. Aby to zrobić, zaimportujmy seaborn spakuj i użyj pairplot wykres, aby przyjrzeć się rozkładowi każdej cechy i każdej separacji klas na cechę:

import seaborn as sns


sns.pairplot(data=df, hue='Class')

Uwaga: Wykonanie powyższego kodu może trochę potrwać, ponieważ para wykresów łączy wykresy rozrzutu wszystkich funkcji (może), a także wyświetla rozkłady funkcji.

Patrząc na wykres pary, widzimy, że w większości przypadków punkty Çerçevelik klasy są wyraźnie oddzielone od punktów Ürgüp Sivrisi klasa. Albo punkty jednej klasy są po prawej stronie, podczas gdy inne są po lewej, albo niektóre są na górze, a inne na dole. Gdybyśmy mieli użyć jakiejś krzywej lub linii do rozdzielenia klas, to pokazuje, że łatwiej je rozdzielić, gdyby były pomieszane, klasyfikacja byłaby trudniejszym zadaniem.

W Eccentricity, Compactness i Aspect_Ration kolumny, niektóre punkty, które są „izolowane” lub odbiegające od ogólnego trendu danych – wartości odstające – są również łatwo dostrzegalne.

Patrząc na przekątną od lewego górnego rogu do prawego dolnego rogu wykresu, zauważ, że rozkłady danych są również oznaczone kolorami zgodnie z naszymi klasami. Kształty rozkładu i odległość między obiema krzywymi to kolejne wskaźniki ich rozdzielności – im dalej od siebie, tym lepiej. W większości przypadków nie nakładają się one na siebie, co oznacza, że ​​łatwiej je rozdzielić, również przyczyniając się do naszego zadania.

W kolejności możemy również wykreślić wykresy pudełkowe wszystkich zmiennych za pomocą sns.boxplot() metoda. W większości przypadków pomocne jest zorientowanie wykresów pudełkowych poziomo, więc kształty wykresów pudełkowych są takie same jak kształty rozkładu, możemy to zrobić za pomocą orient Argument:


sns.boxplot(data=df, orient='h') 

Ostateczny przewodnik po regresji logistycznej w Pythonie PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Na powyższej fabule zauważ, że Area i Convex_Area mają tak dużą wartość w porównaniu z wartościami innych kolumn, że zgniatają inne wykresy pudełkowe. Aby móc spojrzeć na wszystkie wykresy pudełkowe, możemy przeskalować cechy i ponownie je wykreślić.

Zanim to zrobimy, po prostu zrozummy, że jeśli istnieją wartości cech, które są ściśle powiązane z innymi wartościami, na przykład – jeśli są wartości, które również rosną, gdy inne wartości cech są większe, posiadanie dodatnia korelacja; lub jeśli istnieją wartości, które działają odwrotnie, zmniejszają się, podczas gdy inne wartości maleją, mając a ujemną korelację.

Jest to ważne, ponieważ silne relacje w danych mogą oznaczać, że niektóre kolumny pochodzą z innych kolumn lub mają podobne znaczenie do naszego modelu. Kiedy tak się dzieje, wyniki modelu mogą być przeszacowane i chcemy wyników bliższych rzeczywistości. Jeśli istnieją silne korelacje, oznacza to również, że możemy zmniejszyć liczbę cech i użyć mniejszej liczby kolumn, dzięki czemu model będzie bardziej oszczędny.

Uwaga: Domyślna korelacja obliczona z corr() metoda to Współczynnik korelacji Pearsona. Współczynnik ten jest wskazany, gdy dane są ilościowe, mają rozkład normalny, nie mają wartości odstających i mają zależność liniową.

Innym wyborem byłoby obliczenie Współczynnik korelacji Spearmana. Współczynnik Spearmana jest używany, gdy dane są porządkowe, nieliniowe, mają dowolny rozkład i mają wartości odstające. Zauważ, że nasze dane nie w pełni pasują do założeń Pearsona czy Spearmana (jest też więcej metod korelacji, takich jak Kendall). Ponieważ nasze dane są ilościowe i ważne jest, abyśmy zmierzyli ich liniową zależność, użyjemy współczynnika Pearsona.

Przyjrzyjmy się korelacjom między zmiennymi, a następnie możemy przejść do wstępnego przetwarzania danych. Obliczymy korelacje z corr() metody i wizualizuj je za pomocą Seaborn's heatmap(). Standardowy rozmiar mapy termicznej jest zwykle mały, więc zaimportujemy matplotlib (ogólny silnik wizualizacji/biblioteka, na której zbudowany jest Seaborn) i zmień rozmiar za pomocą figsize:

import matplotlib.pyplot as plt
plt.figure(figsize=(15, 10))

correlations = df.corr()
sns.heatmap(correlations, annot=True) 

Ostateczny przewodnik po regresji logistycznej w Pythonie PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

W tej mapie cieplnej wartości bliższe 1 lub -1 to wartości, na które musimy zwrócić uwagę. Pierwszy przypadek oznacza wysoką korelację dodatnią, a drugi wysoką korelację ujemną. Obie wartości, jeśli nie powyżej 0.8 lub -0.8 będą korzystne dla naszego modelu regresji logistycznej.

Gdy istnieją wysokie korelacje, takie jak ta z 0.99 pomiędzy Aspec_Ration i Compactness, oznacza to, że możemy wybrać tylko użycie Aspec_Ration lub tylko Compactness, zamiast obu z nich (ponieważ byłyby prawie równe predyktory siebie). To samo dotyczy Eccentricity i Compactness z -0.98 korelacja, dla Area i Perimeter z 0.94 korelacja i kilka innych kolumn.

Wstępne przetwarzanie danych

Ponieważ już od jakiegoś czasu eksplorujemy dane, możemy rozpocząć ich wstępne przetwarzanie. Na razie użyjmy wszystkich funkcji przewidywania klas. Po uzyskaniu pierwszego modelu, linii bazowej, możemy usunąć niektóre z silnie skorelowanych kolumn i porównać je z linią bazową.

Kolumny funkcji będą nasze X dane i kolumna klasy, nasz y dane docelowe:

y = df['Class']
X = df.drop(columns=['Class'], axis=1)

Przekształcanie cech kategorialnych w cechy numeryczne

Jeśli chodzi o nasze Class kolumna – jej wartości nie są liczbami, co oznacza, że ​​również musimy je przekształcić. Istnieje wiele sposobów na dokonanie tej transformacji; tutaj użyjemy replace() metoda i wymień Çerçevelik do 0 i Ürgüp Sivrisi do 1.

y = y.replace('Çerçevelik', 0).replace('Ürgüp Sivrisi', 1)

Pamiętaj o mapowaniu! Czytając wyniki ze swojego modelu, będziesz chciał przekonwertować je z powrotem przynajmniej w swoim umyśle lub z powrotem na nazwę klasy dla innych użytkowników.

Podział danych na pociągi i zestawy testowe

Podczas naszej eksploracji zauważyliśmy, że funkcje wymagają skalowania. Gdybyśmy zrobili skalowanie teraz lub w sposób automatyczny, skalowalibyśmy wartości z całym X i y. W takim przypadku przedstawimy wyciek danych, ponieważ wartości przyszłego zestawu testowego miałyby wpływ na skalowanie. Wyciek danych jest częstą przyczyną nieodtwarzalnych wyników i złudnej wysokiej wydajności modeli ML.

Myślenie o skalowaniu pokazuje, że najpierw musimy podzielić X i y dane dalej do pociągów i zestawów testowych, a następnie do dopasować skaler na zestawie treningowym oraz do przekształcać zarówno zestaw testowy, jak i testowy (bez wpływu zestawu testowego na skaler, który to robi). W tym celu użyjemy Scikit-Learn train_test_split() metoda:

from sklearn.model_selection import train_test_split
SEED = 42 

X_train, X_test, y_train, y_test = train_test_split(X, y, 
                                                    test_size=.25, 
                                                    random_state=SEED)

Oprawa test_size=.25 zapewnia, że ​​wykorzystujemy 25% danych do testowania i 75% do szkolenia. Można to pominąć, gdy jest to domyślny podział, ale Pythona sposób pisania kodu informuje, że bycie „wyraźnym jest lepsze niż niejawne”.

Uwaga: Zdanie „wyraźne jest lepsze niż ukryte” jest odniesieniem do: Zen Pythonalub PEP20. Zawiera kilka sugestii dotyczących pisania kodu w Pythonie. Jeśli te sugestie są przestrzegane, kod jest brany pod uwagę Pythona. Możesz dowiedzieć się o tym więcej tutaj.

Po podzieleniu danych na zestawy treningowe i testowe, dobrą praktyką jest sprawdzenie, ile rekordów znajduje się w każdym zestawie. Można to zrobić za pomocą shape atrybut:

X_train.shape, X_test.shape, y_train.shape, y_test.shape

Wyświetla:

((1875, 12), (625, 12), (1875,), (625,))

Widzimy, że po podziale mamy 1875 rekordów do treningu i 625 do testów.

Skalowanie danych

Gdy mamy gotowy zestaw pociągów i testów, możemy przystąpić do skalowania danych za pomocą Scikit-Learn StandardScaler obiekt (lub inne skalery dostarczone przez bibliotekę). Aby uniknąć wycieków, skaler jest przymocowany do X_train dane i wartości pociągu są następnie wykorzystywane do skalowania – lub przekształcania – zarówno danych pociągu, jak i danych testowych:

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

Ponieważ zazwyczaj dzwonisz:

scaler.fit(X_train)
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)

Pierwsze dwie linie można zwinąć za pomocą liczby pojedynczej fit_transform() wezwanie, które dopasowuje skaler do zestawu i przekształca go za jednym zamachem. Możemy teraz odtworzyć wykresy pudełkowe, aby zobaczyć różnicę po przeskalowaniu danych.

Biorąc pod uwagę, że skalowanie usuwa nazwy kolumn, przed wykreśleniem możemy ponownie uporządkować dane pociągu w ramkę danych z nazwami kolumn, aby ułatwić wizualizację:

column_names = df.columns[:12] 
X_train = pd.DataFrame(X_train, columns=column_names)

sns.boxplot(data=X_train, orient='h')

Ostateczny przewodnik po regresji logistycznej w Pythonie PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

W końcu możemy zobaczyć wszystkie nasze boxploty! Zauważ, że wszystkie z nich mają wartości odstające i cechy, które przedstawiają rozkład dalej od normalnego (które mają krzywe pochylone w lewo lub w prawo), takie jak Solidity, Extent, Aspect_Ration, Compactedness, są takie same, które miały wyższe korelacje.

Usuwanie wartości odstających za pomocą metody IQR

Wiemy już, że na regresję logistyczną mogą wpływać wartości odstające. Jednym ze sposobów ich leczenia jest zastosowanie metody zwanej Zakres międzykwartylowy or IQR. Pierwszym krokiem metody IQR jest podzielenie naszych danych o pociągach na cztery części, zwane kwartylami. pierwszy kwartyl, Q1, wynosi 25% danych, drugi, Q2, do 50%, trzecia, Q3, do 75%, a ostatnia, Q4, do 100%. Pudełka na wykresie pudełkowym są definiowane metodą IQR i stanowią jej wizualną reprezentację.

W przypadku poziomego wykresu pudełkowego pionowa linia po lewej stronie oznacza 25% danych, pionowa linia pośrodku — 50% danych (lub mediana), a ostatnia pionowa linia po prawej — 75% danych . Im bardziej równomierny rozmiar mają oba kwadraty określone przez pionowe linie – lub im bardziej pionowa linia środkowa znajduje się pośrodku – oznacza, że ​​nasze dane są bliższe rozkładowi normalnemu lub mniej przekrzywione, co jest pomocne w naszej analizie.

Poza skrzynką IQR, po obu jej stronach znajdują się również poziome linie. Linie te oznaczają minimalne i maksymalne wartości rozkładu określone przez

$$
Minimum = Q1 – 1.5*IQR
$$

i

$$
Maksimum = Q3 + 1.5*IQR
$$

IQR to dokładnie różnica między Q3 a Q1 (lub Q3 – Q1) i jest to najbardziej centralny punkt danych. Dlatego podczas znajdowania IQR kończymy filtrowaniem wartości odstających w krańcach danych lub w punktach minimum i maksimum. Wykresy pudełkowe dają nam zapowiedź tego, jaki będzie wynik metody IQR.

Ostateczny przewodnik po regresji logistycznej w Pythonie PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Możemy użyć Pand quantile() metoda znajdowania naszych kwantyli i iqr z scipy.stats pakiet do uzyskania międzykwartylowego zakresu danych dla każdej kolumny:

from scipy.stats import iqr

Q1 = X_train.quantile(q=.25)
Q3 = X_train.quantile(q=.75)

IQR = X_train.apply(iqr)

Teraz mamy Q1, Q3 i IQR, możemy odfiltrować wartości bliższe mediany:


minimum = X_train < (Q1-1.5*IQR)
maximum = X_train > (Q3+1.5*IQR)


filter = ~(minimum | maximum).any(axis=1)


X_train = X_train[filter]

Po przefiltrowaniu naszych wierszy treningowych możemy zobaczyć, ile z nich nadal znajduje się w danych z shape:

X_train.shape

To skutkuje:

(1714, 12)

Widzimy, że po przefiltrowaniu liczba wierszy wzrosła z 1875 do 1714. Oznacza to, że 161 wierszy zawierało wartości odstające lub 8.5% danych.

Uwaga: Zaleca się, aby filtrowanie wartości odstających, usuwanie wartości NaN i inne czynności związane z filtrowaniem i czyszczeniem danych pozostawały poniżej lub do 10% danych. Spróbuj pomyśleć o innych rozwiązaniach, jeśli filtrowanie lub usuwanie przekracza 10% danych.

Po usunięciu wartości odstających jesteśmy prawie gotowi do włączenia danych do modelu. Do dopasowania modelu użyjemy danych pociągu. X_train jest filtrowany, ale co z y_train?

y_train.shape

To daje:

(1875,)

Zauważ, że y_train nadal ma 1875 wierszy. Musimy dopasować liczbę y_train wierszy do liczby X_train wiersze, a nie tylko arbitralnie. Musimy usunąć wartości y wystąpień usuniętych nasion dyni, które prawdopodobnie są rozproszone po całym y_train ustawić. Filtrowane X_train nadal ma swoje oryginalne indeksy, a indeks zawiera luki, w których usunęliśmy wartości odstające! Możemy wtedy użyć indeksu X_train DataFrame do wyszukiwania odpowiednich wartości w y_train:

y_train = y_train.iloc[X_train.index]

Po wykonaniu tej czynności możemy spojrzeć na y_train ukształtuj ponownie:

y_train.shape

Które wyjścia:

(1714,)

Zapoznaj się z naszym praktycznym, praktycznym przewodnikiem dotyczącym nauki Git, zawierającym najlepsze praktyki, standardy przyjęte w branży i dołączoną ściągawkę. Zatrzymaj polecenia Google Git, a właściwie uczyć się to!

Teraz, y_train również ma 1714 rzędów i są takie same jak X_train wydziwianie. Jesteśmy wreszcie gotowi do stworzenia naszego modelu regresji logistycznej!

Implementacja modelu regresji logistycznej

Najtrudniejsza część została wykonana! Wstępne przetwarzanie jest zwykle trudniejsze niż tworzenie modeli, jeśli chodzi o korzystanie z bibliotek takich jak Scikit-Learn, które usprawniły stosowanie modeli ML do zaledwie kilku wierszy.

Najpierw importujemy LogisticRegression klasy i tworzyć jej instancję, tworząc a LogisticRegression obiekt:

from sklearn.linear_model import LogisticRegression
logreg = LogisticRegression(random_state=SEED)

Po drugie, dopasowujemy nasze dane pociągów do logreg model z fit() metody i przewidzieć nasze dane testowe za pomocą predict() metody, przechowywanie wyników jako y_pred:



logreg.fit(X_train.values, y_train)
y_pred = logreg.predict(X_test)

Przewidywaliśmy już z naszym modelem! Spójrzmy na pierwsze 3 rzędy w X_train aby zobaczyć, jakie dane wykorzystaliśmy:

X_train[:3]

Powyższy kod daje:

       Area          Perimeter     Major_Axis_Length    Minor_Axis_Length    Convex_Area   Equiv_Diameter       Eccentricity  Solidity      Extent        Roundness     Aspect_Ration        Compactness
0      -1.098308     -0.936518     -0.607941            -1.132551            -1.082768     -1.122359            0.458911      -1.078259     0.562847      -0.176041     0.236617             -0.360134
1      -0.501526     -0.468936     -0.387303            -0.376176            -0.507652     -0.475015            0.125764      0.258195      0.211703      0.094213      -0.122270            0.019480
2      0.012372      -0.209168     -0.354107            0.465095              0.003871      0.054384            -0.453911     0.432515      0.794735      0.647084      -0.617427            0.571137

A przy pierwszych 3 prognozach w y_pred aby zobaczyć wyniki:

y_pred[:3] 

To skutkuje:

array([0, 0, 0])

Dla tych trzech rzędów nasze przewidywania były takie, że były to nasiona pierwszej klasy, Çerçevelik.

Z regresja logistyczna, zamiast przewidywać klasę końcową, taką jak 0, możemy również przewidzieć prawdopodobieństwo, że wiersz odnosi się do 0 klasa. Tak się dzieje, gdy regresja logistyczna klasyfikuje dane, a predict() Metoda następnie przekazuje tę prognozę przez próg, aby zwrócić „twardą” klasę. Aby przewidzieć prawdopodobieństwo przynależności do klasy, predict_proba() jest używany:

y_pred_proba = logreg.predict_proba(X_test)

Przyjrzyjmy się również pierwszym 3 wartościom przewidywań prawdopodobieństw y:

y_pred_proba[:3] 

Które wyjścia:

        # class 0   class 1   
array([[0.54726628, 0.45273372],
       [0.56324527, 0.43675473],
       [0.86233349, 0.13766651]])

Teraz zamiast trzech zer mamy jedną kolumnę dla każdej klasy. W kolumnie po lewej, zaczynając od 0.54726628, są prawdopodobieństwami danych odnoszących się do klasy 0; i w prawej kolumnie, zaczynając od 0.45273372, czy prawdopodobieństwo tego dotyczy klasy? 1.

Uwaga: Ta różnica w klasyfikacji jest również znana jako ciężko i miękki Prognoza. Twarde przewidywanie grupuje przewidywania w klasę, podczas gdy miękkie przewidywania wyświetlają prawdopodobieństwo instancji należącej do klasy.

Jest więcej informacji o tym, jak sporządzono przewidywany wynik. Właściwie to nie było 0, ale 55% szans na klasę 0, i 45% szans na klasę 1. To pokazuje, jak pierwsze trzy X_test punkty danych, dotyczące klasy 0, są naprawdę jasne tylko w odniesieniu do trzeciego punktu danych, z prawdopodobieństwem 86% – i nie tak bardzo w przypadku pierwszych dwóch punktów danych.

Podczas komunikowania wyników za pomocą metod ML – zazwyczaj najlepiej jest zwrócić miękką klasę i związane z nią prawdopodobieństwo jako "zaufanie" tej klasyfikacji.

Porozmawiamy więcej o tym, jak to jest obliczane, gdy zagłębimy się w model. W tym momencie możemy przejść do kolejnego kroku.

Ocena modelu za pomocą raportów klasyfikacyjnych

Trzecim krokiem jest sprawdzenie, jak model działa na danych testowych. Możemy zaimportować Scikit-Learn classification_report() i przekazać nasze y_test i y_pred jako argumenty. Następnie możemy wydrukować jego odpowiedź.

Raport klasyfikacji zawiera najczęściej używane metryki klasyfikacji, takie jak precyzja, odwołanie, wynik f1, precyzja.

  1. Detaliczność: aby zrozumieć, jakie prawidłowe wartości przewidywania zostały uznane za prawidłowe przez nasz klasyfikator. Precyzja podzieli te prawdziwe wartości dodatnie przez wszystkie przewidywane wartości dodatnie:

$$
precyzja = frac{tekst{prawdziwe dodatnie}}{tekst{prawdziwe dodatnie} + tekst{fałszywie dodatnie}}
$$

  1. Odwołanie: aby zrozumieć, ile prawdziwych pozytywów zostało zidentyfikowanych przez nasz klasyfikator. Przypomnienie oblicza się, dzieląc prawdziwe pozytywy przez wszystko, co należało przewidzieć jako pozytywne:

$$
przypomnienie = frac{tekst{prawdziwe pozytywne}}{tekst{prawdziwe pozytywne} + tekst{fałszywe negatywne}}
$$

  1. Wynik F1: czy zrównoważony lub Średnia harmoniczna precyzji i przypomnienia. Najniższa wartość to 0, a najwyższa to 1. Kiedy f1-score jest równy 1, oznacza to, że wszystkie klasy zostały poprawnie przewidziane – jest to bardzo trudny wynik do uzyskania na rzeczywistych danych:

$$
tekst{f1-score} = 2* frac{tekst{precyzja} * tekst{przypomnij}}{tekst{precyzja} + tekst{przypomnij}}
$$

  1. Dokładność: opisuje, ile przewidywań nasz klasyfikator wykonał poprawnie. Najniższa wartość dokładności wynosi 0, a najwyższa 1. Ta wartość jest zwykle mnożona przez 100, aby uzyskać wartość procentową:

$$
dokładność = frac{tekst{liczba poprawnych prognoz}}{tekst{całkowita liczba prognoz}}
$$

Uwaga: Niezwykle trudno jest uzyskać 100% dokładność na jakichkolwiek rzeczywistych danych, jeśli tak się stanie, należy mieć świadomość, że może nastąpić jakiś wyciek lub coś złego – nie ma zgody co do idealnej wartości dokładności i jest to również zależne od kontekstu. Wartość 70%, co oznacza, że ​​klasyfikator popełni błędy na 30% danych lub powyżej 70% zwykle wystarcza dla większości modeli.

from sklearn.metrics import classification_report
cr = classification_report(y_test, y_pred)
print(cr)

Następnie możemy spojrzeć na wynik raportu klasyfikacji:

				precision    recall  f1-score   support

           0       0.83      0.91      0.87       316
           1       0.90      0.81      0.85       309

    accuracy                           0.86       625
   macro avg       0.86      0.86      0.86       625
weighted avg       0.86      0.86      0.86       625

To jest nasz wynik. Zauważ, że precision, recall, f1-score, accuracy wszystkie wskaźniki są bardzo wysokie, powyżej 80%, co jest idealnym rozwiązaniem – ale na te wyniki prawdopodobnie miały wpływ wysokie korelacje i nie utrzymają się na dłuższą metę.

Dokładność modelu wynosi 86%, co oznacza, że ​​w 14% przypadków niepoprawna klasyfikacja. Mamy te ogólne informacje, ale ciekawie byłoby wiedzieć, czy 14% błędów ma miejsce w odniesieniu do klasyfikacji klasy 0 lub klasa 1. Aby zidentyfikować, które klasy są błędnie zidentyfikowane jako które iz jaką częstotliwością – możemy obliczyć i wykreślić a matryca zamieszania przewidywań naszego modelu.

Ocena modelu za pomocą matrycy pomyłek

Obliczmy, a następnie wykreślmy macierz pomyłek. Po wykonaniu tej czynności możemy zrozumieć każdą jej część. Aby wykreślić macierz pomyłek, użyjemy Scikit-Learn confusion_matrix(), które zaimportujemy z metrics moduł.

Matryca pomyłek jest łatwiejsza do wizualizacji za pomocą Seaborn heatmap(). Tak więc, po wygenerowaniu, przekażemy naszą macierz pomyłek jako argument dla heatmapy:

from sklearn.metrics import confusion_matrix

cm = confusion_matrix(y_test, y_pred)
sns.heatmap(cm, annot=True, fmt='d')

Ostateczny przewodnik po regresji logistycznej w Pythonie PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

  1. Macierz zamieszania: macierz pokazuje, ile próbek model dał się dobrze lub źle dla każdej klasy. Wartości, które były poprawne i poprawnie przewidziane, nazywane są prawdziwe pozytywy, a te, które zostały uznane za pozytywne, ale nie były pozytywne, to fałszywe alarmy. Ta sama nomenklatura prawdziwe negatywy i fałszywe negatywy służy do wartości ujemnych;

Patrząc na wykres macierzy pomyłek, widzimy, że mamy 287 wartości, które były 0 i przewidziano jako 0 - lub prawdziwe pozytywy dla klasy 0 (nasiona Çerçevelik). Mamy też 250 prawdziwe pozytywy dla klasy 1 (Nasiona Ürgüp Sivrisi). Prawdziwe pozytywy zawsze znajdują się na przekątnej matrycy, która biegnie od lewego górnego rogu do prawego dolnego.

Mamy też 29 wartości, które miały być 0, ale przewidziano jako 1 (fałszywe alarmy) i 59 wartości, które były 1 i przewidziano jako 0 (fałszywe negatywy). Dzięki tym liczbom możemy zrozumieć, że błąd, który model popełnia najbardziej, polega na przewidywaniu wyników fałszywie ujemnych. Tak więc, w większości przypadków może to skończyć się klasyfikacją nasion Ürgüp Sivrisi jako nasion Çerçevelik.

Ten rodzaj błędu tłumaczy się również 81% odwołaniem klasy 1. Zauważ, że metryki są połączone. A różnica w wycofaniu wynika z posiadania o 100 mniej próbek klasy Ürgüp Sivrisi. Jest to jeden z implikacji posiadania tylko kilku próbek mniej niż w przypadku drugiej klasy. Aby jeszcze bardziej poprawić zapamiętywanie, możesz poeksperymentować z wagami klas lub użyć większej liczby próbek Ürgüp Sivrisi.

Do tej pory wykonaliśmy większość tradycyjnych kroków związanych z nauką o danych i wykorzystaliśmy model regresji logistycznej jako czarną skrzynkę.

Uwaga: Jeśli chcesz iść dalej, użyj Walidacja krzyżowa (CV) i przeszukiwanie siatki poszukać odpowiednio modelu, który najbardziej uogólnia dane, oraz najlepszych parametrów modelu, które są wybierane przed uczeniem, lub hiperparametry.

Idealnie, dzięki CV i Grid Search, można również zaimplementować połączony sposób wykonywania kroków wstępnego przetwarzania danych, dzielenia danych, modelowania i oceny – co jest łatwe dzięki Scikit-Learn rurociągi.

Teraz nadszedł czas, aby otworzyć czarną skrzynkę i zajrzeć do niej, aby głębiej zrozumieć, jak działa regresja logistyczna.

Zagłębianie się w to, jak naprawdę działa regresja logistyczna

Połączenia regresja słowo nie jest tam przypadkowo, aby zrozumieć, co robi regresja logistyczna, możemy przypomnieć sobie, co jej rodzeństwo, regresja liniowa robi z danymi. Formuła regresji liniowej była następująca:

$$
y = b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldotki + b_n * x_n
$$

W którym b0 był punkt przecięcia regresji, b1 współczynnik i x1 dane.

To równanie dało linię prostą, która była używana do przewidywania nowych wartości. Przypominając wstęp, różnica polega na tym, że nie będziemy przewidywać nowych wartości, ale klasę. Więc ta prosta linia musi się zmienić. W regresji logistycznej wprowadzamy nieliniowość, a prognoza jest teraz wykonywana za pomocą krzywej zamiast linii:

Ostateczny przewodnik po regresji logistycznej w Pythonie PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Zauważ, że podczas gdy linia regresji liniowej trwa i składa się z ciągłych nieskończonych wartości, krzywa regresji logistycznej może być podzielona pośrodku i ma ekstrema w wartościach 0 i 1. Ten kształt „S” jest powodem, dla którego klasyfikuje dane – punkty znajdujące się bliżej lub leżące na najwyższym końcu należą do klasy 1, podczas gdy punkty znajdujące się w dolnym kwadrancie lub bliżej 0 należą do klasy 0. Środek „S” to środek między 0 a 1, 0.5 – jest to próg dla punktów regresji logistycznej.

Ostateczny przewodnik po regresji logistycznej w Pythonie PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Rozumiemy już wizualną różnicę między regresją logistyczną a liniową, ale co z formułą? Wzór na regresję logistyczną jest następujący:

$$
y = b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldotki + b_n * x_n
$$

Można go również zapisać jako:

$$
y_{prob} = ułamek{1}{1 + e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}
$$

Lub nawet być napisany jako:

$$
y_{prob} = frac{e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}{1 + e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + kropki + b_n * x_n)}}
$$

W powyższym równaniu mamy prawdopodobieństwo wejścia zamiast jego wartości. Ma 1 jako licznik, więc może dać wartość z przedziału od 0 do 1, a 1 plus wartość w mianowniku, więc jego wartość wynosi 1 i coś – oznacza to, że cały wynik ułamka nie może być większy niż 1 .

A jaka jest wartość w mianowniku? To jest e, podstawa logarytmu naturalnego (około 2.718282), podniesiona do potęgi regresji liniowej:

$$
e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldotki + b_n * x_n)}
$$

Innym sposobem napisania byłoby:

$$
ln lewo(frac{p}{1-p} prawo) = {(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}
$$

W tym ostatnim równaniu ln jest logarytmem naturalnym (podstawa e) i p jest prawdopodobieństwem, więc logarytm prawdopodobieństwa wyniku jest taki sam, jak wynik regresji liniowej.

Innymi słowy, mając wynik regresji liniowej i logarytm naturalny, możemy uzyskać prawdopodobieństwo, że dane wejściowe odnoszą się lub nie do zaprojektowanej klasy.

Cały proces wyprowadzania regresji logistycznej wygląda następująco:

$$
p{X} = ułamek{e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}{1 + e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + kropki + b_n * x_n)}}
$$

$$
p(1 + e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldotków + b_n * x_n)}) = e^{(b_0 + b_1 * x_1 + b_2 *x_2 + b_3 * x_3 + ldotków + b_n * x_n)}
$$

$$
p + p*e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldotki + b_n * x_n)} = e^{(b_0 + b_1 * x_1 + b_2 *x_2 + b_3 * x_3 + ldotki + b_n * x_n)}
$$

p
=

e

(

b
0

+

b
1

x
1

+

b
2

x
2

+

b
3

x
3

+
...
+

b
n

x
n

)

-
p

e

(

b
0

+

b
1

x
1

+

b
2

x
2

+

b
3

x
3

+
...
+

b
n

x
n

)

$$
frac{p}{1-p} = e^{(b_0 + b_1 * x_1 + b_2 *x_2 + b_3 * x_3 + ldots + b_n * x_n)}
$$

$$
ln lewo( frac{p}{1-p} prawo) = (b_0 + b_1 * x_1 + b_2 *x_2 + b_3 * x_3 + ldots + b_n * x_n)
$$

Oznacza to, że model regresji logistycznej ma również współczynniki i wartość przecięcia. Ponieważ używa regresji liniowej i dodaje do niej nieliniowy składnik z logarytmem naturalnym (e).

Możemy zobaczyć wartości współczynników i punkt przecięcia naszego modelu, tak samo jak w przypadku regresji liniowej, używając coef_ i intercept_ nieruchomości:

logreg.coef_

Który wyświetla współczynniki każdej z 12 funkcji:

array([[ 1.43726172, -1.03136968,  0.24099522, -0.61180768,  1.36538261,
        -1.45321951, -1.22826034,  0.98766966,  0.0438686 , -0.78687889,
         1.9601197 , -1.77226097]])
logreg.intercept_

Skutkuje to:

array([0.08735782])

Dzięki współczynnikom i wartościom przecięcia możemy obliczyć przewidywane prawdopodobieństwa naszych danych. Chodźmy pierwszy X_test wartości ponownie, jako przykład:

X_test[:1]

Zwraca pierwszy wiersz X_test jako tablica NumPy:

array([[-1.09830823, -0.93651823, -0.60794138, -1.13255059, -1.0827684 ,
        -1.12235877,  0.45891056, -1.07825898,  0.56284738, -0.17604099,
         0.23661678, -0.36013424]])

Zgodnie z początkowym równaniem:

$$
p{X} = ułamek{e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}{1 + e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + kropki + b_n * x_n)}}
$$

W Pythonie mamy:

import math

lin_reg = logreg.intercept_[0] + 
((logreg.coef_[0][0]* X_test[:1][0][0])+ 
(logreg.coef_[0][1]* X_test[:1][0][1])+ 
(logreg.coef_[0][2]* X_test[:1][0][2])+ 
(logreg.coef_[0][3]* X_test[:1][0][3])+ 
(logreg.coef_[0][4]* X_test[:1][0][4])+ 
(logreg.coef_[0][5]* X_test[:1][0][5])+ 
(logreg.coef_[0][6]* X_test[:1][0][6])+ 
(logreg.coef_[0][7]* X_test[:1][0][7])+ 
(logreg.coef_[0][8]* X_test[:1][0][8])+ 
(logreg.coef_[0][9]* X_test[:1][0][9])+ 
(logreg.coef_[0][10]* X_test[:1][0][10])+ 
(logreg.coef_[0][11]* X_test[:1][0][11]))

px = math.exp(lin_reg)/(1 +(math.exp(lin_reg)))
px

To skutkuje:

0.45273372469369133

Jeśli ponownie spojrzymy na predict_proba wynik pierwszego X_test linia, mamy:

logreg.predict_proba(X_test[:1])


Oznacza to, że oryginalne równanie regresji logistycznej daje nam prawdopodobieństwo danych wejściowych dotyczących klasy 1, aby dowiedzieć się, które prawdopodobieństwo dotyczy klasy 0, możemy po prostu:

1 - px


Zauważ, że oba px i 1-px są identyczne z predict_proba wyniki. W ten sposób obliczana jest regresja logistyczna i dlaczego regresja jest częścią jego nazwy. Ale co z terminem? logistyka?

Termin logistyka pochodzi z logit, czyli funkcję, którą już widzieliśmy:

$$
Po lewej (frac{p}{1-p} po prawej)
$$

Właśnie to obliczyliśmy za pomocą px i 1-px. To jest logit, zwany także logarytmiczne kursy ponieważ jest równy logarytmowi szans gdzie p jest prawdopodobieństwem.

Wnioski

W tym przewodniku omówiliśmy jeden z najbardziej podstawowych algorytmów klasyfikacji uczenia maszynowego, tj. regresja logistyczna.

Początkowo zaimplementowaliśmy regresję logistyczną jako czarną skrzynkę z biblioteką uczenia maszynowego Scikit-Learn, a później zrozumieliśmy to krok po kroku, aby mieć jasne, dlaczego i skąd pochodzą terminy regresja i logistyka.

Zbadaliśmy również i przeanalizowaliśmy dane, rozumiejąc, że jest to jedna z najważniejszych części analizy naukowej danych.

Stąd radzę się pobawić wieloklasowa regresja logistyczna, regresja logistyczna dla więcej niż dwóch klas — można zastosować ten sam algorytm regresji logistycznej do innych zestawów danych, które mają wiele klas, i zinterpretować wyniki.

Uwaga: Dostępny jest dobry zbiór zbiorów danych tutaj do zabawy.

Radziłbym również zapoznać się z L1 i L2 regularyzacje, są sposobem na „karanie” wyższych danych, aby zbliżyły się do normy, utrzymując złożoność modelu, dzięki czemu algorytm może uzyskać lepszy wynik. Użyta przez nas implementacja Scikit-Learn ma już domyślnie regularyzację L2. Kolejną rzeczą, na którą należy zwrócić uwagę, jest różnica solwery, Takie jak lbgs, które optymalizują wydajność algorytmu regresji logistycznej.

Ważne jest również, aby przyjrzeć się statystyczny podejście do regresji logistycznej. To ma Założenia o zachowaniu danych oraz o innych statystykach, które muszą być przechowywane, aby zagwarantować zadowalające wyniki, takie jak:

  • obserwacje są niezależne;
  • nie ma wielokoliniowości między zmiennymi objaśniającymi;
  • nie ma skrajnych wartości odstających;
  • istnieje liniowa zależność między zmiennymi objaśniającymi a logitem zmiennej odpowiedzi;
  • wielkość próbki jest wystarczająco duża.

Zwróć uwagę, ile z tych założeń zostało już uwzględnionych w naszej analizie i przetwarzaniu danych.

Mam nadzieję, że nadal będziesz badać, co regresja logistyczna ma do zaoferowania we wszystkich jej różnych podejściach!

Znak czasu:

Więcej z Nadużycie stosu