Przewodnik po algorytmie K-Nearest Neighbors w Pythonie i Scikit-Learn PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Przewodnik po algorytmie K-Nearest Neighbors w Pythonie i Scikit-Learn

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:

Przewodnik po algorytmie K-Nearest Neighbors w Pythonie i Scikit-Learn PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

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:

Przewodnik po algorytmie K-Nearest Neighbors w Pythonie i Scikit-Learn PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.
Przewodnik po algorytmie K-Nearest Neighbors w Pythonie i Scikit-Learn PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

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 blokowej
  • HouseAge – mediana wieku domu w grupie blokowej
  • AveRooms – średnia liczba pokoi (przydzielonych na gospodarstwo domowe)
  • AveBedrms – średnia liczba sypialni (przydzielonych na gospodarstwo domowe)
  • Population – populacja grupy blokowej
  • AveOccup – średnia liczba członków gospodarstwa domowego
  • Latitude – szerokość geograficzna grupy bloków
  • Longitude – długość geograficzna grupy bloków
  • MedHouseVal – 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):

  1. Ś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.

  1. 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
$$

  1. 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 errors:

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

Przewodnik po algorytmie K-Nearest Neighbors w Pythonie i Scikit-Learn PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

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

Przewodnik po algorytmie K-Nearest Neighbors w Pythonie i Scikit-Learn PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

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:

  1. 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;
  2. 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 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}}
$$

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

Przewodnik po algorytmie K-Nearest Neighbors w Pythonie i Scikit-Learn PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

              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ą recalli 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 z class 2 w 238 przypadkach
  • class 2 dla class 1 w 256 wpisach, a dla class 3 w 260 przypadkach
  • class 3 był w większości pomylony przez class 2, 374 wpisy i class 4, w 193 przypadkach
  • class 4 został błędnie sklasyfikowany jako class 3 dla 339 wpisów i jako class 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:

Przewodnik po algorytmie K-Nearest Neighbors w Pythonie i Scikit-Learn PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

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

Przewodnik po algorytmie K-Nearest Neighbors w Pythonie i Scikit-Learn PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

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

Przewodnik po algorytmie K-Nearest Neighbors w Pythonie i Scikit-Learn PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

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

Przewodnik po algorytmie K-Nearest Neighbors w Pythonie i Scikit-Learn PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

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.

Znak czasu:

Więcej z Nadużycie stosu