Wprowadzenie
Połączenia K-najbliżsi sąsiedzi (KNN) algorytm jest rodzajem nadzorowanego algorytmu uczenia maszynowego używanego do klasyfikacji, regresji oraz wykrywania wartości odstających. Jest niezwykle łatwy do wdrożenia w swojej najbardziej podstawowej formie, ale może wykonywać dość złożone zadania. Jest to algorytm do leniwego uczenia się, ponieważ nie ma specjalistycznej fazy szkolenia. Zamiast tego wykorzystuje wszystkie dane do uczenia podczas klasyfikowania (lub regresu) nowego punktu danych lub wystąpienia.
KNN jest algorytm uczenia nieparametrycznego, co oznacza, że nie zakłada niczego na temat danych źródłowych. Jest to niezwykle przydatna funkcja, ponieważ większość danych ze świata rzeczywistego tak naprawdę nie opiera się na żadnym teoretycznym założeniu, np. o liniowej rozdzielności, równomiernym rozkładzie itp.
W tym przewodniku zobaczymy, jak można zaimplementować KNN za pomocą biblioteki Scikit-Learn w języku Python. Wcześniej najpierw zbadamy, w jaki sposób możemy korzystać z KNN i wyjaśnimy stojącą za tym teorię. Następnie przyjrzymy się Zbiór danych dotyczących mieszkań w Kalifornii użyjemy do zilustrowania algorytmu KNN i kilku jego odmian. Najpierw przyjrzymy się, jak zaimplementować algorytm KNN dla regresji, a następnie przyjrzymy się implementacjom klasyfikacji KNN i wykrywaniu wartości odstających. Na koniec przedstawimy niektóre zalety i wady algorytmu.
Kiedy należy używać KNN?
Załóżmy, że chciałeś wynająć mieszkanie i niedawno dowiedziałeś się, że sąsiadka twojej koleżanki może wynająć jej mieszkanie za 2 tygodnie. Skoro mieszkania nie ma jeszcze na stronie z wypożyczalniami, jak możesz spróbować oszacować jego wartość najmu?
Powiedzmy, że twój przyjaciel płaci 1,200 dolarów czynszu. Twoja wartość czynszu może być zbliżona do tej liczby, ale mieszkania nie są dokładnie takie same (orientacja, powierzchnia, jakość mebli itp.), więc byłoby miło mieć więcej danych o innych mieszkaniach.
Pytając innych sąsiadów i patrząc na mieszkania z tego samego budynku, które zostały wymienione na stronie internetowej wynajmu, najbliższe trzy sąsiednie mieszkania czynsze wynoszą 1,200, 1,210, 1,210 i 1,215 USD. Te apartamenty znajdują się w tym samym bloku i na tym samym piętrze, co mieszkanie twojego przyjaciela.
Inne mieszkania, położone dalej, na tym samym piętrze, ale w innym bloku, mają czynsze w wysokości 1,400, 1,430, 1,500 i 1,470 dolarów. Wydaje się, że są droższe, bo wieczorem mają więcej światła słonecznego.
Biorąc pod uwagę bliskość mieszkania, wydaje się, że szacunkowy czynsz wyniesie około 1,210 XNUMX USD. To jest ogólna idea tego, co K-Najbliżsi sąsiedzi (KNN) algorytm robi! Klasyfikuje lub regresuje nowe dane na podstawie ich bliskości do już istniejących danych.
Przetłumacz przykład na teorię
Gdy szacunkowa wartość jest liczbą ciągłą, taką jak wartość czynszu, KNN jest używany do regresja. Ale możemy też podzielić mieszkania na kategorie na podstawie np. minimalnego i maksymalnego czynszu. Gdy wartość jest dyskretna, co czyni ją kategorią, KNN jest używany do klasyfikacja.
Istnieje też możliwość oszacowania, którzy sąsiedzi są tak różni od innych, że prawdopodobnie przestaną płacić czynsz. Jest to to samo, co wykrywanie, które punkty danych są tak daleko, że nie pasują do żadnej wartości lub kategorii, gdy tak się dzieje, KNN jest używany do wykrywanie wartości odstających.
W naszym przykładzie znaliśmy już czynsze każdego mieszkania, co oznacza, że nasze dane zostały oznaczone. KNN używa wcześniej oznaczonych danych, co sprawia, że nadzorowany algorytm uczenia się.
KNN jest niezwykle łatwy do wdrożenia w swojej najbardziej podstawowej formie, a mimo to wykonuje dość złożone zadania klasyfikacji, regresji lub wykrywania wartości odstających.
Za każdym razem, gdy do danych dodawany jest nowy punkt, KNN wykorzystuje tylko jedną część danych do decydowania o wartości (regresja) lub klasie (klasyfikacji) tego dodanego punktu. Ponieważ nie musi ponownie patrzeć na wszystkie punkty, sprawia to, że jest to leniwy algorytm uczenia się.
KNN nie zakłada również niczego na temat podstawowych cech danych, nie oczekuje, że dane będą pasować do pewnego rodzaju rozkładu, takiego jak jednorodność lub być liniowo oddzielone. Oznacza to, że jest to algorytm uczenia nieparametrycznego. Jest to niezwykle przydatna funkcja, ponieważ większość danych ze świata rzeczywistego nie opiera się na żadnym teoretycznym założeniu.
Wizualizacja różnych zastosowań KNN
Jak wykazano, intuicja stojąca za algorytmem KNN jest jednym z najbardziej bezpośrednich spośród wszystkich nadzorowanych algorytmów uczenia maszynowego. Algorytm najpierw oblicza dystans nowego punktu danych do wszystkich innych treningowych punktów danych.
Uwaga: Odległość można mierzyć na różne sposoby. Możesz użyć Minkowskiego, Euklidesa, Manhattan, Mahalanobis czy formuła Hamminga, żeby wymienić tylko kilka wskaźników. W przypadku danych wysokowymiarowych odległość euklidesowa często zaczyna zawodzić (wysoka wymiarowość jest… dziwna), a zamiast tego używana jest odległość Manhattan.
Po obliczeniu odległości KNN wybiera liczbę najbliższych punktów danych – 2, 3, 10 lub w rzeczywistości dowolną liczbę całkowitą. Ta liczba punktów (2, 3, 10 itd.) to K w K-Najbliżsi Sąsiedzi!
W ostatnim kroku, jeśli jest to zadanie regresji, KNN obliczy średnią ważoną sumę K-najbliższych punktów dla prognozy. Jeśli jest to zadanie klasyfikacyjne, nowy punkt danych zostanie przypisany do klasy, do której należy większość wybranych punktów K-najbliższych.
Zwizualizujmy algorytm w akcji za pomocą prostego przykładu. Rozważ zbiór danych z dwiema zmiennymi i K z 3.
Podczas wykonywania regresji zadaniem jest znalezienie wartości nowego punktu danych na podstawie średniej ważonej sumy 3 najbliższych punktów.
KNN z K = 3
, Przy używany do regresji:
Algorytm KNN rozpocznie od obliczenia odległości nowego punktu od wszystkich punktów. Następnie znajduje 3 punkty o najmniejszej odległości od nowego punktu. Pokazuje to drugi rysunek powyżej, na którym trzy najbliższe punkty, 47
, 58
, 79
zostały otoczone. Następnie oblicza sumę ważoną 47
, 58
i 79
– w tym przypadku wagi są równe 1 – wszystkie punkty traktujemy jako równe, ale możemy też przypisać różne wagi na podstawie odległości. Po obliczeniu sumy ważonej nowa wartość punktowa wynosi 61,33
.
A podczas wykonywania klasyfikacji zadanie KNN, aby zaklasyfikować nowy punkt danych, do "Purple"
or "Red"
class.
KNN z K = 3
, Przy używany do klasyfikacji:
Algorytm KNN rozpocznie tak samo jak poprzednio, obliczając odległość nowego punktu od wszystkich punktów, znajdując 3 najbliższe punkty o najmniejszej odległości od nowego punktu, a następnie zamiast obliczać liczbę, przypisuje nowy punkt do klasy, do której należy większość z trzech najbliższych punktów, klasa czerwona. Dlatego nowy punkt danych zostanie sklasyfikowany jako "Red"
.
Proces wykrywania wartości odstających różni się od obu powyższych, omówimy go więcej podczas implementacji po implementacjach regresji i klasyfikacji.
Note: Kod dostarczony w tym samouczku został wykonany i przetestowany z następującymi Notatnik Jupyter.
Zbiór danych mieszkaniowych Scikit-Learn w Kalifornii
Użyjemy Zbiór danych mieszkaniowych w Kalifornii aby zilustrować, jak działa algorytm KNN. Zbiór danych pochodzi z amerykańskiego spisu powszechnego z 1990 roku. Jeden wiersz zbioru danych reprezentuje spis jednej grupy bloków.
W tej sekcji omówimy szczegóły zbioru danych dotyczących mieszkań stanu Kalifornia, aby umożliwić Ci intuicyjne zrozumienie danych, z którymi będziemy pracować. Bardzo ważne jest, aby poznać swoje dane, zanim zaczniesz nad nimi pracować.
A blok group to najmniejsza jednostka geograficzna, dla której US Census Bureau publikuje przykładowe dane. Oprócz grupy blokowej, innym używanym terminem jest gospodarstwo domowe, gospodarstwo domowe to grupa osób zamieszkujących w domu.
Zbiór danych składa się z dziewięciu atrybutów:
MedInc
– mediana dochodów w grupie blokowejHouseAge
– mediana wieku domu w grupie blokowejAveRooms
– średnia liczba pokoi (przydzielonych na gospodarstwo domowe)AveBedrms
– średnia liczba sypialni (przydzielonych na gospodarstwo domowe)Population
– populacja grupy blokowejAveOccup
– średnia liczba członków gospodarstwa domowegoLatitude
– szerokość geograficzna grupy blokówLongitude
– długość geograficzna grupy blokówMedHouseVal
– mediana wartości domu dla dystryktów Kalifornii (setki tysięcy dolarów)
Zbiór danych to jest już częścią biblioteki Scikit-Learn, wystarczy go zaimportować i załadować jako ramkę danych:
from sklearn.datasets import fetch_california_housing
california_housing = fetch_california_housing(as_frame=True)
df = california_housing.frame
Importowanie danych bezpośrednio z Scikit-Learn, importuje więcej niż tylko kolumny i liczby i zawiera opis danych jako Bunch
obiekt – więc właśnie wyodrębniliśmy frame
. Dostępne są dalsze szczegóły zbioru danych tutaj.
Zaimportujmy Pandy i rzućmy okiem na kilka pierwszych wierszy danych:
import pandas as pd
df.head()
Wykonanie kodu spowoduje wyświetlenie pierwszych pięciu wierszy naszego zbioru danych:
MedInc HouseAge AveRooms AveBedrms Population AveOccup Latitude Longitude MedHouseVal
0 8.3252 41.0 6.984127 1.023810 322.0 2.555556 37.88 -122.23 4.526
1 8.3014 21.0 6.238137 0.971880 2401.0 2.109842 37.86 -122.22 3.585
2 7.2574 52.0 8.288136 1.073446 496.0 2.802260 37.85 -122.24 3.521
3 5.6431 52.0 5.817352 1.073059 558.0 2.547945 37.85 -122.25 3.413
4 3.8462 52.0 6.281853 1.081081 565.0 2.181467 37.85 -122.25 3.422
W tym przewodniku będziemy używać MedInc
, HouseAge
, AveRooms
, AveBedrms
, Population
, AveOccup
, Latitude
, Longitude
przewidzieć MedHouseVal
. Coś podobnego do naszej narracji motywacyjnej.
Przejdźmy teraz od razu do implementacji algorytmu KNN dla regresji.
Regresja z K-Nearest Neighbors za pomocą Scikit-Learn
Do tej pory poznaliśmy nasz zbiór danych i teraz możemy przejść do kolejnych kroków w algorytmie KNN.
Wstępne przetwarzanie danych dla regresji KNN
Przetwarzanie wstępne to miejsce, w którym pojawiają się pierwsze różnice między zadaniami regresji i klasyfikacji. Ponieważ ta sekcja dotyczy regresji, odpowiednio przygotujemy nasz zestaw danych.
W przypadku regresji musimy przewidzieć inną medianę wartości domu. Aby to zrobić, przypiszemy MedHouseVal
do y
i wszystkie inne kolumny do X
po prostu upuszczając MedHouseVal
:
y = df['MedHouseVal']
X = df.drop(['MedHouseVal'], axis = 1)
Patrząc na opisy naszych zmiennych, widzimy, że mamy różnice w pomiarach. Aby uniknąć zgadywania, użyjmy describe()
sposób sprawdzenia:
X.describe().T
To skutkuje:
count mean std min 25% 50% 75% max
MedInc 20640.0 3.870671 1.899822 0.499900 2.563400 3.534800 4.743250 15.000100
HouseAge 20640.0 28.639486 12.585558 1.000000 18.000000 29.000000 37.000000 52.000000
AveRooms 20640.0 5.429000 2.474173 0.846154 4.440716 5.229129 6.052381 141.909091
AveBedrms 20640.0 1.096675 0.473911 0.333333 1.006079 1.048780 1.099526 34.066667
Population 20640.0 1425.476744 1132.462122 3.000000 787.000000 1166.000000 1725.000000 35682.000000
AveOccup 20640.0 3.070655 10.386050 0.692308 2.429741 2.818116 3.282261 1243.333333
Latitude 20640.0 35.631861 2.135952 32.540000 33.930000 34.260000 37.710000 41.950000
Longitude 20640.0 -119.569704 2.003532 -124.350000 -121.800000 -118.490000 -118.010000 -114.310000
Tutaj widzimy, że mean
wartość MedInc
około 3.87
oraz mean
wartość HouseAge
jest o 28.64
, dzięki czemu jest 7.4 razy większy niż MedInc
. Inne cechy mają również różnice w średniej i odchyleniu standardowym – aby to zobaczyć, spójrz na mean
i std
wartości i obserwuj, jak są od siebie oddalone. Do MedInc
std
około 1.9
, Dla HouseAge
, std
is 12.59
to samo dotyczy pozostałych funkcji.
Używamy algorytmu opartego na dystans algorytmy oparte na odległości bardzo cierpią z powodu danych, które nie są w tej samej skali, takie jak te dane. Skala punktów może (i w praktyce prawie zawsze) zniekształcać rzeczywistą odległość między wartościami.
Aby przeprowadzić skalowanie funkcji, użyjemy Scikit-Learn StandardScaler
klasę później. Jeśli zastosujemy skalowanie teraz (przed podziałem na test pociągu), obliczenia będą obejmowały dane testowe, efektywnie wyciek przetestuj informacje o danych w pozostałej części potoku. Ten rodzaj wyciek danych jest niestety często pomijany, co skutkuje nieodwracalnymi lub złudnymi ustaleniami.
Dzielenie danych na pociągi i zestawy testowe
Aby móc skalować nasze dane bez przecieków, ale także ocenić nasze wyniki i uniknąć nadmiernego dopasowania, podzielimy nasz zbiór danych na podziały pociągów i testów.
Prostym sposobem na tworzenie podziałów pociągów i testów jest train_test_split
metoda ze Scikit-Learn. Podział nie dzieli się liniowo w pewnym momencie, ale losowo pobiera próbki X% i Y%. Aby proces ten był powtarzalny (aby metoda zawsze próbkowała te same punkty danych), ustawimy random_state
argument do pewnego SEED
:
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=0.25, random_state=SEED)
Ten fragment kodu pobiera próbki 75% danych do treningu i 25% danych do testowania. Zmieniając test_size
na przykład do 0.3, możesz trenować z 70% danych i testować z 30%.
Wykorzystując 75% danych do uczenia i 25% do testowania, z 20640 rekordów, zestaw uczący zawiera 15480, a zestaw testowy zawiera 5160. Możemy szybko sprawdzić te liczby, drukując długości pełnego zestawu danych i podzielonych danych :
len(X)
len(X_train)
len(X_test)
Świetny! Możemy teraz dopasować skaler danych do X_train
ustaw i skaluj oba X_train
i X_test
bez wycieku jakichkolwiek danych z X_test
najnowszych X_train
.
Skalowanie funkcji dla regresji KNN
Importując StandardScaler
, tworząc jego instancję, dopasowując go zgodnie z naszymi danymi pociągu (zapobiegając wyciekom) i przekształcając zarówno zestawy danych pociągu, jak i testowe, możemy wykonać skalowanie funkcji:
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(X_train)
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)
Uwaga: Ponieważ często będziesz dzwonić scaler.fit(X_train)
następnie scaler.transform(X_train)
– można zadzwonić do singla scaler.fit_transform(X_train)
następnie scaler.transform(X_test)
aby rozmowa była krótsza!
Teraz nasze dane są skalowane! Skaler zachowuje tylko punkty danych, a nie nazwy kolumn, po zastosowaniu na a DataFrame
. Ponownie uporządkujmy dane w DataFrame z nazwami kolumn i użyj describe()
obserwować zmiany w mean
i std
:
col_names=['MedInc', 'HouseAge', 'AveRooms', 'AveBedrms', 'Population', 'AveOccup', 'Latitude', 'Longitude']
scaled_df = pd.DataFrame(X_train, columns=col_names)
scaled_df.describe().T
To da nam:
count mean std min 25% 50% 75% max
MedInc 15480.0 2.074711e-16 1.000032 -1.774632 -0.688854 -0.175663 0.464450 5.842113
HouseAge 15480.0 -1.232434e-16 1.000032 -2.188261 -0.840224 0.032036 0.666407 1.855852
AveRooms 15480.0 -1.620294e-16 1.000032 -1.877586 -0.407008 -0.083940 0.257082 56.357392
AveBedrms 15480.0 7.435912e-17 1.000032 -1.740123 -0.205765 -0.108332 0.007435 55.925392
Population 15480.0 -8.996536e-17 1.000032 -1.246395 -0.558886 -0.227928 0.262056 29.971725
AveOccup 15480.0 1.055716e-17 1.000032 -0.201946 -0.056581 -0.024172 0.014501 103.737365
Latitude 15480.0 7.890329e-16 1.000032 -1.451215 -0.799820 -0.645172 0.971601 2.953905
Longitude 15480.0 2.206676e-15 1.000032 -2.380303 -1.106817 0.536231 0.785934 2.633738
Obserwuj teraz, jak wyglądają wszystkie odchylenia standardowe 1
a środki się zmniejszyły. To właśnie sprawia, że nasze dane bardziej jednolite! Wytrenujmy i oceńmy regresora opartego na KNN.
Trening i przewidywanie regresji KNN
Intuicyjny i stabilny interfejs API Scikit-Learn sprawia, że treningi regresorów i klasyfikatorów są bardzo proste. Zaimportujmy KNeighborsRegressor
klasa z sklearn.neighbors
moduł, stwórz jego instancję i dopasuj do naszych danych pociągu:
from sklearn.neighbors import KNeighborsRegressor
regressor = KNeighborsRegressor(n_neighbors=5)
regressor.fit(X_train, y_train)
W powyższym kodzie n_neighbors
jest wartością dla Klub liczbę sąsiadów, którą algorytm weźmie pod uwagę przy wyborze nowej wartości mediany domu. 5
jest wartością domyślną dla KNeighborsRegressor()
. Nie ma idealnej wartości dla K i jest ona wybierana po przetestowaniu i ocenie, jednak na początek, 5
jest powszechnie używaną wartością dla KNN i dlatego została ustawiona jako wartość domyślna.
Ostatnim krokiem jest dokonanie prognoz na naszych danych testowych. Aby to zrobić, wykonaj następujący skrypt:
y_pred = regressor.predict(X_test)
Możemy teraz ocenić, jak dobrze nasz model uogólnia się na nowe dane, dla których mamy etykiety (prawda podstawowa) – zestaw testowy!
Ocena algorytmu regresji KNN
Najczęściej stosowanymi metrykami regresji do oceny algorytmu są średni błąd bezwzględny (MAE), średni błąd kwadratowy (MSE), pierwiastek błędu średniokwadratowego (RMSE) i współczynnik determinacji (R2):
- Średni błąd bezwzględny (MAE): Gdy odejmiemy wartości przewidywane od wartości rzeczywistych, uzyskamy błędy, zsumujemy wartości bezwzględne tych błędów i otrzymamy ich średnią. Ta metryka daje pojęcie o całkowitym błędzie dla każdej predykcji modelu, im mniejszy (bliżej 0), tym lepiej:
$$
mae = (frac{1}{n})sum_{i=1}^{n}w lewo | Rzeczywiste – Przewidywane prawo |
$$
Uwaga: Możesz także spotkać się z y
i ŷ
(czytaj jako y-hat) notacja w równaniach. The y
odnosi się do rzeczywistych wartości, a ŷ
do przewidywanych wartości.
- Błąd średniokwadratowy (MSE): Jest podobny do metryki MAE, ale podnosi do kwadratu wartości bezwzględne błędów. Podobnie jak w przypadku MAE, im mniejszy lub bliższy 0, tym lepiej. Wartość MSE jest podnoszona do kwadratu, aby duże błędy były jeszcze większe. Jedną rzeczą, na którą należy zwrócić szczególną uwagę, jest to, że zazwyczaj jest to trudna do interpretacji metryka ze względu na wielkość jej wartości i fakt, że nie są one na tej samej skali co dane.
$$
mse = suma_{i=1}^{D}(Rzeczywiste – Przewidywane)^2
$$
- Pierwiastek błędu średniokwadratowego (RMSE): Próbuje rozwiązać problem interpretacji podniesiony w MSE przez uzyskanie pierwiastka kwadratowego z jego końcowej wartości, tak aby przeskalować go z powrotem do tych samych jednostek danych. Łatwiej jest zinterpretować i dobrze, gdy potrzebujemy wyświetlić lub pokazać rzeczywistą wartość danych z błędem. Pokazuje, jak bardzo dane mogą się różnić, więc jeśli mamy RMSE 4.35, nasz model może popełnić błąd, ponieważ dodał 4.35 do rzeczywistej wartości lub potrzebował 4.35, aby uzyskać rzeczywistą wartość. Im bliżej 0, tym lepiej.
$$
rmse = sqrt{ sum_{i=1}^{D}(Rzeczywiste – Przewidywane)^2}
$$
Połączenia mean_absolute_error()
i mean_squared_error()
metody sklearn.metrics
można użyć do obliczenia tych danych, jak widać w następującym fragmencie:
from sklearn.metrics import mean_absolute_error, mean_squared_error
mae = mean_absolute_error(y_test, y_pred)
mse = mean_squared_error(y_test, y_pred)
rmse = mean_squared_error(y_test, y_pred, squared=False)
print(f'mae: {mae}')
print(f'mse: {mse}')
print(f'rmse: {rmse}')
Wynik powyższego skryptu wygląda tak:
mae: 0.4460739527131783
mse: 0.4316907430948294
rmse: 0.6570317671884894
R2 można obliczyć bezpośrednio za pomocą score()
metoda:
regressor.score(X_test, y_test)
Które wyjścia:
0.6737569252627673
Wyniki pokazują, że ogólny błąd naszego algorytmu KNN i błąd średni są około 0.44
, 0.43
. RMSE pokazuje również, że możemy zejść powyżej lub poniżej rzeczywistej wartości danych, dodając 0.65
lub odejmowanie 0.65
. Jak dobrze to jest?
Sprawdźmy jak wyglądają ceny:
y.describe()
count 20640.000000
mean 2.068558
std 1.153956
min 0.149990
25% 1.196000
50% 1.797000
75% 2.647250
max 5.000010
Name: MedHouseVal, dtype: float64
Średnia jest 2.06
a odchylenie standardowe od średniej wynosi 1.15
więc nasz wynik ~0.44
nie jest naprawdę gwiezdny, ale nie jest taki zły.
Z R2, im najbliżej 1 otrzymamy (lub 100), tym lepiej. R2 mówi, ile zmian w danych lub danych zmienność są rozumiane lub wyjaśnione przez KNN.
$$
R^2 = 1 – frac{suma(rzeczywista – przewidywana)^2}{suma(rzeczywista – rzeczywista średnia)^2}
$$
O wartości 0.67
, widzimy, że nasz model wyjaśnia 67% wariancji danych. To już ponad 50%, co jest w porządku, ale niezbyt dobre. Czy jest jakiś sposób, w jaki moglibyśmy zrobić to lepiej?
Użyliśmy z góry określonej K o wartości 5
, więc używamy 5 sąsiadów do przewidywania naszych celów, co niekoniecznie jest najlepszą liczbą. Aby zrozumieć, jaka byłaby idealna liczba Ks, możemy przeanalizować błędy naszego algorytmu i wybrać K, które minimalizuje straty.
Znalezienie najlepszego K dla regresji KNN
Najlepiej byłoby, gdybyś zobaczył, który wskaźnik bardziej pasuje do Twojego kontekstu – ale zwykle interesujące jest przetestowanie wszystkich wskaźników. Zawsze, gdy możesz przetestować je wszystkie, zrób to. Tutaj pokażemy, jak wybrać najlepsze K, używając tylko średniego błędu bezwzględnego, ale możesz zmienić go na dowolną inną metrykę i porównać wyniki.
W tym celu utworzymy pętlę for i uruchomimy modele, które mają od 1 do X sąsiadów. Przy każdej interakcji obliczymy MAE i wykreślimy liczbę Ks wraz z wynikiem MAE:
error = []
for i in range(1, 40):
knn = KNeighborsRegressor(n_neighbors=i)
knn.fit(X_train, y_train)
pred_i = knn.predict(X_test)
mae = mean_absolute_error(y_test, pred_i)
error.append(mae)
Teraz wykreślmy error
s:
import matplotlib.pyplot as plt
plt.figure(figsize=(12, 6))
plt.plot(range(1, 40), error, color='red',
linestyle='dashed', marker='o',
markerfacecolor='blue', markersize=10)
plt.title('K Value MAE')
plt.xlabel('K Value')
plt.ylabel('Mean Absolute Error')
Patrząc na wykres, wydaje się, że najniższa wartość MAE występuje, gdy K wynosi 12
. Przyjrzyjmy się bliżej wykresowi, wykreślając mniej danych:
plt.figure(figsize=(12, 6))
plt.plot(range(1, 15), error[:14], color='red',
linestyle='dashed', marker='o',
markerfacecolor='blue', markersize=10)
plt.title('K Value MAE')
plt.xlabel('K Value')
plt.ylabel('Mean Absolute Error')
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!
Możesz również uzyskać najniższy błąd i indeks tego punktu za pomocą wbudowanego min()
funkcja (działa na listach) lub przekonwertuj listę na tablicę NumPy i uzyskaj argmin()
(indeks elementu o najniższej wartości):
import numpy as np
print(min(error))
print(np.array(error).argmin())
Zaczęliśmy liczyć sąsiadów od 1, podczas gdy tablice są oparte na 0, więc 11. indeks to 12 sąsiadów!
Oznacza to, że potrzebujemy 12 sąsiadów, aby móc przewidzieć punkt z najmniejszym błędem MAE. Możemy ponownie wykonać model i metryki z 12 sąsiadami, aby porównać wyniki:
knn_reg12 = KNeighborsRegressor(n_neighbors=12)
knn_reg12.fit(X_train, y_train)
y_pred12 = knn_reg12.predict(X_test)
r2 = knn_reg12.score(X_test, y_test)
mae12 = mean_absolute_error(y_test, y_pred12)
mse12 = mean_squared_error(y_test, y_pred12)
rmse12 = mean_squared_error(y_test, y_pred12, squared=False)
print(f'r2: {r2}, nmae: {mae12} nmse: {mse12} nrmse: {rmse12}')
Następujący kod wyprowadza:
r2: 0.6887495617137436,
mae: 0.43631325936692505
mse: 0.4118522151025172
rmse: 0.6417571309323467
Z 12 sąsiadami nasz model KNN wyjaśnia teraz 69% wariancji danych i stracił nieco mniej, począwszy od 0.44
do 0.43
, 0.43
do 0.41
, 0.65
do 0.64
z odpowiednimi metrykami. Nie jest to bardzo duża poprawa, niemniej jednak jest to poprawa.
Uwaga: Idąc dalej w tej analizie, wykonanie eksploracyjnej analizy danych (EDA) wraz z analizą resztkową może pomóc w wyborze cech i osiągnięciu lepszych wyników.
Widzieliśmy już, jak używać KNN do regresji – ale co, gdybyśmy chcieli sklasyfikować punkt zamiast przewidywać jego wartość? Teraz możemy przyjrzeć się, jak używać KNN do klasyfikacji.
Klasyfikacja za pomocą K-Nearest Neighbors z Scikit-Learn
W tym zadaniu zamiast przewidywać wartość ciągłą, chcemy przewidzieć klasę, do której należą te grupy bloków. Aby to zrobić, możemy podzielić medianę wartości domu dla dzielnic na grupy o różnych przedziałach wartości domu lub pojemniki.
Jeśli chcesz użyć wartości ciągłej do klasyfikacji, zwykle możesz pogrupować dane. W ten sposób możesz przewidywać grupy zamiast wartości.
Wstępne przetwarzanie danych do klasyfikacji
Utwórzmy pojemniki danych, aby przekształcić nasze wartości ciągłe w kategorie:
df["MedHouseValCat"] = pd.qcut(df["MedHouseVal"], 4, retbins=False, labels=[1, 2, 3, 4])
Następnie możemy podzielić nasz zbiór danych na jego atrybuty i etykiety:
y = df['MedHouseValCat']
X = df.drop(['MedHouseVal', 'MedHouseValCat'], axis = 1)
Ponieważ używaliśmy MedHouseVal
kolumna do tworzenia pojemników, musimy upuścić MedHouseVal
kolumna i MedHouseValCat
kolumny z X
. W ten sposób DataFrame
będzie zawierać pierwsze 8 kolumn zbioru danych (tj. atrybuty, cechy), podczas gdy nasz y
będzie zawierać tylko MedHouseValCat
przypisana etykieta.
Uwaga: Możesz także wybrać kolumny za pomocą .iloc()
zamiast je upuszczać. Podczas upuszczania pamiętaj, że musisz przypisać y
wartości przed przypisaniem X
wartości, ponieważ nie można przypisać upuszczonej kolumny a DataFrame
do innego obiektu w pamięci.
Dzielenie danych na pociągi i zestawy testowe
Podobnie jak w przypadku regresji, podzielimy również zbiór danych na podziały treningowe i testowe. Ponieważ mamy różne dane, musimy powtórzyć ten proces:
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=0.25, random_state=SEED)
Ponownie użyjemy standardowej wartości Scikit-Learn wynoszącej 75% danych pociągu i 25% danych testowych. Oznacza to, że będziemy mieli taką samą liczbę rekordów w pociągu i teście, jak w poprzedniej regresji.
Skalowanie funkcji dla klasyfikacji
Ponieważ mamy do czynienia z tym samym nieprzetworzonym zbiorem danych i jego różnymi jednostkami miary, ponownie przeprowadzimy skalowanie cech, w taki sam sposób jak w przypadku naszych danych regresji:
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(X_train)
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)
Szkolenie i przewidywanie do klasyfikacji
Po binningu, dzieleniu i skalowaniu danych możemy w końcu dopasować do nich klasyfikator. Do przewidywania ponownie użyjemy 5 sąsiadów jako linii bazowej. Możesz także utworzyć instancję KNeighbors_
class bez żadnych argumentów i automatycznie użyje 5 sąsiadów. Tutaj zamiast importować KNeighborsRegressor
, zaimportujemy te KNeighborsClassifier
, klasa:
from sklearn.neighbors import KNeighborsClassifier
classifier = KNeighborsClassifier()
classifier.fit(X_train, y_train)
Po zamontowaniu KNeighborsClassifier
, możemy przewidzieć klasy danych testowych:
y_pred = classifier.predict(X_test)
Czas ocenić prognozy! Czy przewidywanie klas byłoby w tym przypadku lepszym podejściem niż przewidywanie wartości? Oceńmy algorytm, aby zobaczyć, co się stanie.
Ocena KNN do klasyfikacji
Do oceny klasyfikatora KNN możemy również użyć score
metody, ale wykonuje inną metrykę, ponieważ oceniamy klasyfikator, a nie regresor. Podstawowym miernikiem klasyfikacji jest accuracy
– opisuje, ile predykcji nasz klasyfikator wykonał poprawnie. Najniższa wartość dokładności wynosi 0, a najwyższa 1. Zwykle mnożymy tę wartość przez 100, aby uzyskać procent.
$$
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. W zależności od koszt błędu (jak źle jest, jeśli ufamy klasyfikatorowi i okazuje się, że się myli), akceptowalny poziom błędu może wynosić 5%, 10%, a nawet 30%.
Oceńmy nasz klasyfikator:
acc = classifier.score(X_test, y_test)
print(acc)
Patrząc na uzyskany wynik, możemy wywnioskować, że nasz klasyfikator poprawnie wykonał ~62% naszych klas. To już pomaga w analizie, chociaż wiedząc tylko, co klasyfikator zrobił dobrze, trudno to poprawić.
W naszym zbiorze danych znajdują się 4 klasy – co, jeśli nasz klasyfikator ma 90% klas 1, 2 i 3 prawy, lecz tylko 30% klasy 4 słusznie?
Awaria systemowa pewnej klasy, w przeciwieństwie do awarii zrównoważonej dzielonej między klasami, może dać wynik dokładności 62%. Dokładność nie jest naprawdę dobrym wskaźnikiem do rzeczywistej oceny — ale służy jako dobry wskaźnik zastępczy. Najczęściej przy zrównoważonych zestawach danych dokładność 62% jest stosunkowo równomiernie rozłożona. Ponadto, częściej niż nie, zbiory danych nie są zrównoważone, więc wracamy do punktu wyjścia, a dokładność jest niewystarczającą metryką.
Możemy dokładniej przyjrzeć się wynikom, korzystając z innych wskaźników, aby móc to określić. Ten krok różni się również od regresji, tutaj użyjemy:
- Macierz zamieszania: Aby dowiedzieć się, w jakim stopniu mamy rację lub pomyłkę kazda klasa. Wartości, które były poprawne i poprawnie przewidziane, nazywane są prawdziwe pozytywy te, które zostały uznane za pozytywne, ale nie były pozytywne, nazywa się fałszywe alarmy. Ta sama nomenklatura prawdziwe negatywy i fałszywe negatywy służy do wartości ujemnych;
- 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}}
$$
- Odwołanie: aby zrozumieć, ile prawdziwych pozytywów zostało zidentyfikowanych przez nasz klasyfikator. Przypomnienie jest obliczane przez podzielenie prawdziwych pozytywów przez wszystko, co należało przewidzieć jako pozytywne.
$$
przypomnienie = frac{tekst{prawdziwe pozytywne}}{tekst{prawdziwe pozytywne} + tekst{fałszywe negatywne}}
$$
- 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 (wyjątki prawie zawsze istnieją).
$$
tekst{f1-score} = 2* frac{tekst{precyzja} * tekst{przypomnij}}{tekst{precyzja} + tekst{przypomnij}}
$$
Uwaga: Istnieje również ważony wynik F1 i jest to po prostu wynik F1, który nie stosuje tej samej wagi do wszystkich klas. Waga jest zwykle podyktowana klasami wsparcie – ile instancji „obsługuje” wynik F1 (proporcja etykiet należących do określonej klasy). Im niższe wsparcie (im mniej wystąpień klasy), tym niższa ważona F1 dla tej klasy, ponieważ jest ona bardziej zawodna.
Połączenia confusion_matrix()
i classification_report()
metody sklearn.metrics
moduł może służyć do obliczania i wyświetlania wszystkich tych metryk. The confusion_matrix
jest lepiej wizualizowany za pomocą mapy termicznej. Raport klasyfikacyjny już nam daje accuracy
, precision
, recall
, f1-score
, ale możesz też zaimportować każdy z tych wskaźników z sklearn.metrics
.
Aby uzyskać dane, wykonaj następujący fragment kodu:
from sklearn.metrics import classification_report, confusion_matrix
import seaborn as sns
classes_names = ['class 1','class 2','class 3', 'class 4']
cm = pd.DataFrame(confusion_matrix(yc_test, yc_pred),
columns=classes_names, index = classes_names)
sns.heatmap(cm, annot=True, fmt='d');
print(classification_report(y_test, y_pred))
Wynik powyższego skryptu wygląda tak:
precision recall f1-score support
1 0.75 0.78 0.76 1292
2 0.49 0.56 0.53 1283
3 0.51 0.51 0.51 1292
4 0.76 0.62 0.69 1293
accuracy 0.62 5160
macro avg 0.63 0.62 0.62 5160
weighted avg 0.63 0.62 0.62 5160
Wyniki pokazują, że KNN był w stanie sklasyfikować wszystkie 5160 rekordów w zestawie testowym z dokładnością 62%, czyli powyżej średniej. Podpory są dość równe (równomierny rozkład klas w zbiorze danych), więc ważone F1 i nieważone F1 będą mniej więcej takie same.
Możemy również zobaczyć wynik metryk dla każdej z 4 klas. Dzięki temu jesteśmy w stanie to zauważyć class 2
miał najniższą precyzję, najniższą recall
i najniższy f1-score
. Class 3
jest tuż za nim class 2
za najniższe wyniki, a następnie mamy class 1
z najlepszymi wynikami, po których następują class 4
.
Patrząc na macierz pomyłek, widzimy, że:
class 1
został w większości pomylony zclass 2
w 238 przypadkachclass 2
dlaclass 1
w 256 wpisach, a dlaclass 3
w 260 przypadkachclass 3
był w większości pomylony przezclass 2
, 374 wpisy iclass 4
, w 193 przypadkachclass 4
został błędnie sklasyfikowany jakoclass 3
dla 339 wpisów i jakoclass 2
w 130 przypadkach.
Zauważ również, że przekątna wyświetla prawdziwie dodatnie wartości, patrząc na nią, widać, że class 2
i class 3
mają najmniej poprawnie przewidywane wartości.
Dzięki tym wynikom możemy zagłębić się w analizę, dokładniej je sprawdzając, aby dowiedzieć się, dlaczego tak się stało, a także zrozumieć, czy 4 klasy to najlepszy sposób na podzielenie danych. Być może wartości od class 2
i class 3
byli zbyt blisko siebie, więc trudno było ich odróżnić.
Zawsze staraj się testować dane z różną liczbą pojemników, aby zobaczyć, co się stanie.
Oprócz dowolnej liczby pojemników danych istnieje również inna dowolna liczba, którą wybraliśmy, liczba K sąsiadów. Tę samą technikę, którą zastosowaliśmy w zadaniu regresji, można zastosować do klasyfikacji podczas określania liczby Ks, które maksymalizują lub minimalizują wartość metryki.
Znalezienie najlepszego K dla klasyfikacji KNN
Powtórzmy to, co zostało zrobione dla regresji i narysujmy wykres wartości K i odpowiednią metrykę dla zbioru testowego. Możesz również wybrać, który wskaźnik lepiej pasuje do Twojego kontekstu, tutaj wybierzemy f1-score
.
W ten sposób wykreślimy f1-score
dla przewidywanych wartości zestawu testowego dla wszystkich wartości K od 1 do 40.
Najpierw importujemy f1_score
od sklearn.metrics
a następnie obliczyć jego wartość dla wszystkich przewidywań klasyfikatora K-Nearest Neighbors, gdzie K mieści się w zakresie od 1 do 40:
from sklearn.metrics import f1_score
f1s = []
for i in range(1, 40):
knn = KNeighborsClassifier(n_neighbors=i)
knn.fit(X_train, y_train)
pred_i = knn.predict(X_test)
f1s.append(f1_score(y_test, pred_i, average='weighted'))
Następnym krokiem jest wykreślenie f1_score
wartości w stosunku do wartości K. Różnica w stosunku do regresji polega na tym, że zamiast wybrać wartość K, która minimalizuje błąd, tym razem wybierzemy wartość, która maksymalizuje f1-score
.
Wykonaj następujący skrypt, aby utworzyć wykres:
plt.figure(figsize=(12, 6))
plt.plot(range(1, 40), f1s, color='red', linestyle='dashed', marker='o',
markerfacecolor='blue', markersize=10)
plt.title('F1 Score K Value')
plt.xlabel('K Value')
plt.ylabel('F1 Score')
Wykres wyjściowy wygląda tak:
Z danych wyjściowych widać, że f1-score
jest najwyższa, gdy wartość K wynosi 15
. Przeszkolmy nasz klasyfikator z 15 sąsiadami i zobaczmy, jak wpływa na wyniki naszego raportu klasyfikacji:
classifier15 = KNeighborsClassifier(n_neighbors=15)
classifier15.fit(X_train, y_train)
y_pred15 = classifier15.predict(X_test)
print(classification_report(y_test, y_pred15))
To daje:
precision recall f1-score support
1 0.77 0.79 0.78 1292
2 0.52 0.58 0.55 1283
3 0.51 0.53 0.52 1292
4 0.77 0.64 0.70 1293
accuracy 0.63 5160
macro avg 0.64 0.63 0.64 5160
weighted avg 0.64 0.63 0.64 5160
Zauważ, że nasze metryki poprawiły się z 15 sąsiadami, mamy 63% dokładności i więcej precision
, recall
, f1-scores
, ale nadal musimy dokładniej przyjrzeć się pojemnikom, aby zrozumieć, dlaczego f1-score
na zajęcia 2
i 3
jest nadal niski.
Oprócz używania KNN do regresji i określania wartości bloków oraz do klasyfikacji, do określania klas bloków – możemy również użyć KNN do wykrywania, które średnie wartości bloków różnią się od większości – te, które nie podążają za tym, co robi większość danych. Innymi słowy, możemy użyć KNN do wykrywanie odstających.
Wdrażanie KNN do wykrywania wartości odstających za pomocą Scikit-Learn
Wykrywanie wartości odstających używa innej metody, która różni się od tego, co robiliśmy wcześniej dla regresji i klasyfikacji.
Tutaj zobaczymy, jak daleko każdy z sąsiadów znajduje się od punktu danych. Użyjmy domyślnych 5 sąsiadów. Dla punktu danych obliczymy odległość do każdego z najbliższych sąsiadów K. Aby to zrobić, zaimportujemy inny algorytm KNN ze Scikit-learn, który nie jest specyficzny ani dla regresji, ani klasyfikacji, zwany po prostu NearestNeighbors
.
Po zaimportowaniu utworzymy instancję a NearestNeighbors
klasa z 5 sąsiadami – możesz również utworzyć jej wystąpienie z 12 sąsiadami, aby zidentyfikować wartości odstające w naszym przykładzie regresji lub z 15, aby zrobić to samo dla przykładu klasyfikacji. Następnie dopasujemy nasze dane pociągów i użyjemy kneighbors()
metoda znalezienia naszych obliczonych odległości dla każdego punktu danych i indeksów sąsiadów:
from sklearn.neighbors import NearestNeighbors
nbrs = NearestNeighbors(n_neighbors = 5)
nbrs.fit(X_train)
distances, indexes = nbrs.kneighbors(X_train)
Teraz mamy 5 odległości dla każdego punktu danych – odległość między nim a jego 5 sąsiadami oraz indeks, który je identyfikuje. Rzućmy okiem na pierwsze trzy wyniki i kształt tablicy, aby lepiej to zobrazować.
Aby spojrzeć na pierwsze trzy kształty odległości, wykonaj:
distances[:3], distances.shape
(array([[0. , 0.12998939, 0.15157687, 0.16543705, 0.17750354],
[0. , 0.25535314, 0.37100754, 0.39090243, 0.40619693],
[0. , 0.27149697, 0.28024623, 0.28112326, 0.30420656]]),
(3, 5))
Zauważ, że są 3 rzędy po 5 odległościach każdy. Możemy też zajrzeć i indeksy sąsiadów:
indexes[:3], indexes[:3].shape
To skutkuje:
(array([[ 0, 8608, 12831, 8298, 2482],
[ 1, 4966, 5786, 8568, 6759],
[ 2, 13326, 13936, 3618, 9756]]),
(3, 5))
W powyższym wyniku możemy zobaczyć indeksy każdego z 5 sąsiadów. Teraz możemy kontynuować obliczanie średniej z 5 odległości i narysować wykres, który zlicza każdy wiersz na osi X i wyświetla każdą średnią odległość na osi Y:
dist_means = distances.mean(axis=1)
plt.plot(dist_means)
plt.title('Mean of the 5 neighbors distances for each data point')
plt.xlabel('Count')
plt.ylabel('Mean Distances')
Zauważ, że istnieje część wykresu, w której średnie odległości mają jednakowe wartości. Ten punkt na osi Y, w którym średnie nie są zbyt wysokie lub zbyt niskie, jest dokładnie tym punktem, który musimy zidentyfikować, aby odciąć wartości odstające.
W tym przypadku średnia odległość wynosi 3. Narysujmy ponownie wykres za pomocą poziomej kropkowanej linii, aby móc go dostrzec:
dist_means = distances.mean(axis=1)
plt.plot(dist_means)
plt.title('Mean of the 5 neighbors distances for each data point with cut-off line')
plt.xlabel('Count')
plt.ylabel('Mean Distances')
plt.axhline(y = 3, color = 'r', linestyle = '--')
Ta linia oznacza średnią odległość, dla której zmieniają się wszystkie wartości. Oznacza to, że wszystkie punkty z a mean
odległość powyżej 3
są naszymi odstającymi. Indeksy tych punktów możemy znaleźć za pomocą np.where()
. Ta metoda wygeneruje albo True
or False
dla każdego indeksu w odniesieniu do mean
powyżej 3 stan:
import numpy as np
outlier_index = np.where(dist_means > 3)
outlier_index
Powyższy kod wyprowadza:
(array([ 564, 2167, 2415, 2902, 6607, 8047, 8243, 9029, 11892,
12127, 12226, 12353, 13534, 13795, 14292, 14707]),)
Teraz mamy nasze indeksy punktów odstających. Zlokalizujmy je w dataframe:
outlier_values = df.iloc[outlier_index]
outlier_values
To skutkuje:
MedInc HouseAge AveRooms AveBedrms Population AveOccup Latitude Longitude MedHouseVal
564 4.8711 27.0 5.082811 0.944793 1499.0 1.880803 37.75 -122.24 2.86600
2167 2.8359 30.0 4.948357 1.001565 1660.0 2.597809 36.78 -119.83 0.80300
2415 2.8250 32.0 4.784232 0.979253 761.0 3.157676 36.59 -119.44 0.67600
2902 1.1875 48.0 5.492063 1.460317 129.0 2.047619 35.38 -119.02 0.63800
6607 3.5164 47.0 5.970639 1.074266 1700.0 2.936097 34.18 -118.14 2.26500
8047 2.7260 29.0 3.707547 1.078616 2515.0 1.977201 33.84 -118.17 2.08700
8243 2.0769 17.0 3.941667 1.211111 1300.0 3.611111 33.78 -118.18 1.00000
9029 6.8300 28.0 6.748744 1.080402 487.0 2.447236 34.05 -118.78 5.00001
11892 2.6071 45.0 4.225806 0.903226 89.0 2.870968 33.99 -117.35 1.12500
12127 4.1482 7.0 5.674957 1.106998 5595.0 3.235975 33.92 -117.25 1.24600
12226 2.8125 18.0 4.962500 1.112500 239.0 2.987500 33.63 -116.92 1.43800
12353 3.1493 24.0 7.307323 1.460984 1721.0 2.066026 33.81 -116.54 1.99400
13534 3.7949 13.0 5.832258 1.072581 2189.0 3.530645 34.17 -117.33 1.06300
13795 1.7567 8.0 4.485173 1.120264 3220.0 2.652389 34.59 -117.42 0.69500
14292 2.6250 50.0 4.742236 1.049689 728.0 2.260870 32.74 -117.13 2.03200
14707 3.7167 17.0 5.034130 1.051195 549.0 1.873720 32.80 -117.05 1.80400
Nasze wykrywanie wartości odstających zostało zakończone. W ten sposób dostrzegamy każdy punkt danych, który odbiega od ogólnego trendu danych. Widzimy, że w naszych danych o pociągach znajduje się 16 punktów, które należy dokładniej zbadać, zbadać, być może leczyć, a nawet usunąć z naszych danych (jeśli zostały wprowadzone błędnie), aby poprawić wyniki. Punkty te mogły wynikać z błędów pisarskich, niespójności średnich wartości bloków, a nawet z obu tych powodów.
Plusy i minusy KNN
W tej sekcji przedstawimy niektóre zalety i wady korzystania z algorytmu KNN.
ZALETY
- Jest łatwy do wdrożenia
- Jest to algorytm z leniwym uczeniem się i dlatego nie wymaga szkolenia na wszystkich punktach danych (do przewidywania używa się tylko sąsiadów K-Nearest). To sprawia, że algorytm KNN jest znacznie szybszy niż inne algorytmy, które wymagają szkolenia z całym zbiorem danych, takich jak Wsparcie maszyn wektorowych, regresji liniowej, itp.
- Ponieważ KNN nie wymaga szkolenia przed prognozowaniem, nowe dane można bezproblemowo dodawać
- Do pracy z KNN wymagane są tylko dwa parametry, tj. wartość K i funkcja odległości
Wady
- Algorytm KNN nie działa dobrze w przypadku danych wielowymiarowych, ponieważ przy dużej liczbie wymiarów odległość między punktami staje się „dziwna”, a używane przez nas metryki odległości nie wytrzymują
- Wreszcie algorytm KNN nie działa dobrze z cechami kategorialnymi, ponieważ trudno jest znaleźć odległość między wymiarami z cechami kategorialnymi
Idąc dalej – ręczny projekt end-to-end
W tym projekcie z przewodnikiem dowiesz się, jak budować zaawansowane modele tradycyjnego uczenia maszynowego, a także modele uczenia głębokiego, korzystać z Ensemble Learning i szkolić metauczących się, aby przewidywali ceny domów z zestawu modeli Scikit-Learn i Keras.
Korzystając z Keras, interfejsu API do uczenia głębokiego zbudowanego na bazie Tensorflow, będziemy eksperymentować z architekturami, budować zestaw modeli ułożonych w stos i szkolić metauczeń sieć neuronowa (model poziomu 1), aby ustalić wycenę domu.
Głębokie uczenie jest niesamowite – ale zanim się do niego zastosuje, warto również spróbować rozwiązać problem za pomocą prostszych technik, takich jak płytkie uczenie się algorytmy. Nasza wyjściowa wydajność będzie oparta na Regresja losowego lasu algorytm. Dodatkowo – będziemy badać tworzenie zestawów modeli poprzez Scikit-Learn za pomocą technik takich jak parcianka i głosowanie.
Jest to projekt typu end-to-end i tak jak wszystkie projekty uczenia maszynowego, zaczniemy od Analiza danych rozpoznawczych, śledzony przez Wstępne przetwarzanie danych i w końcu Budowanie płytkie i Modele głębokiego uczenia aby dopasować dane, które wcześniej zbadaliśmy i oczyściliśmy.
Wnioski
KNN to prosty, ale potężny algorytm. Może być używany do wielu zadań, takich jak regresja, klasyfikacja lub wykrywanie wartości odstających.
KNN jest szeroko stosowany do znajdowania podobieństwa dokumentów i rozpoznawania wzorców. Został również wykorzystany do opracowywania systemów rekomendujących oraz do redukcji wymiarów i etapów wstępnego przetwarzania dla wizji komputerowej – w szczególności zadań rozpoznawania twarzy.
W tym przewodniku – omówiliśmy regresję, klasyfikację i wykrywanie wartości odstających za pomocą implementacji algorytmu K-Nearest Neighbor w Scikit-Learn.