esittely
- K-lähimmät naapurit (KNN) Algoritmi on eräänlainen valvottu koneoppimisalgoritmi, jota käytetään luokitteluun, regressioon sekä poikkeamien havaitsemiseen. Se on erittäin helppo toteuttaa yksinkertaisimmassa muodossaan, mutta se voi suorittaa melko monimutkaisia tehtäviä. Se on laiska oppimisalgoritmi, koska sillä ei ole erityistä koulutusvaihetta. Pikemminkin se käyttää kaikkia tietoja harjoitteluun luokittelemalla (tai regressoidessaan) uutta datapistettä tai ilmentymää.
KNN on a ei-parametrinen oppimisalgoritmi, mikä tarkoittaa, että se ei oleta mitään taustalla olevista tiedoista. Tämä on erittäin hyödyllinen ominaisuus, koska suurin osa reaalimaailman tiedoista ei todellakaan noudata mitään teoreettista oletusta, kuten lineaarista erotettavuutta, tasaista jakautumista jne.
Tässä oppaassa näemme, kuinka KNN voidaan toteuttaa Pythonin Scikit-Learn-kirjaston kanssa. Ennen sitä tutkimme ensin, kuinka voimme käyttää KNN:ää, ja selitämme sen taustalla olevan teorian. Sen jälkeen katsotaan Kalifornian asuntojen tietojoukko käytämme havainnollistamaan KNN-algoritmia ja useita sen muunnelmia. Ensinnäkin tarkastellaan kuinka KNN-algoritmi toteutetaan regressiota varten, minkä jälkeen KNN-luokituksen ja poikkeavien havaitsemisen toteutukset. Lopuksi kerromme algoritmin eduista ja haitoista.
Milloin sinun pitäisi käyttää KNN: tä?
Oletetaan, että halusit vuokrata asunnon ja sait äskettäin selville, että ystäväsi naapuri saattaa vuokrata asunnon kahden viikon kuluttua. Koska asuntoa ei ole vielä vuokraussivustolla, miten voisit yrittää arvioida sen vuokra-arvoa?
Oletetaan, että ystäväsi maksaa 1,200 XNUMX dollaria vuokraa. Vuokra-arvosi voi olla tämän tienoilla, mutta asunnot eivät ole aivan samat (suunta, pinta-ala, huonekalujen laatu jne.), joten olisi mukava saada enemmän tietoa muista asunnoista.
Kysymällä muilta naapurilta ja katsomalla saman rakennuksen asuntoja, jotka oli listattu vuokraussivustolla, kolme lähintä naapuriasuntojen vuokraa ovat 1,200 1,210, 1,210 1,215, XNUMX XNUMX ja XNUMX XNUMX dollaria. Nämä asunnot ovat samassa korttelissa ja kerroksessa kuin ystäväsi asunto.
Muiden asuntojen, jotka ovat kauempana, samassa kerroksessa, mutta eri korttelissa, on vuokrat 1,400 1,430, 1,500 1,470, XNUMX XNUMX ja XNUMX XNUMX dollaria. Ne näyttävät olevan kalliimpia, koska niissä on enemmän auringonvaloa illalla.
Kun otetaan huomioon asunnon läheisyys, arvioitu vuokrasi näyttää olevan noin 1,210 XNUMX dollaria. Tämä on yleinen käsitys siitä, mitä K-Lähimmät naapurit (KNN) algoritmi tekee! Se luokittelee tai regressoi uudet tiedot sen perusteella, että se on lähellä jo olemassa olevia tietoja.
Käännä esimerkki teoriaksi
Kun arvioitu arvo on jatkuva luku, kuten vuokra-arvo, käytetään KNN:tä regressio. Mutta voisimme jakaa asunnot myös luokkiin esimerkiksi minimi- ja maksimivuokran perusteella. Kun arvo on diskreetti, mikä tekee siitä kategorian, käytetään KNN:ää luokittelu.
On myös mahdollista arvioida, mitkä naapurit ovat niin erilaisia kuin muut, että he todennäköisesti lopettavat vuokran maksamisen. Tämä on sama kuin havaita, mitkä datapisteet ovat niin kaukana, etteivät ne mahdu mihinkään arvoon tai luokkaan. Kun näin tapahtuu, KNN:ää käytetään poikkeavien havaitseminen.
Esimerkissämme tiesimme myös jokaisen asunnon vuokrat, mikä tarkoittaa, että tietomme oli merkitty. KNN käyttää aiemmin merkittyjä tietoja, mikä tekee siitä a ohjattu oppimisalgoritmi.
KNN on erittäin helppo toteuttaa yksinkertaisimmassa muodossaan, ja silti se suorittaa melko monimutkaisia luokittelu-, regressio- tai outlier-ilmaisutehtäviä.
Joka kerta kun dataan lisätään uusi piste, KNN käyttää vain yhtä osaa tiedoista päättääkseen lisätyn pisteen arvon (regressio) tai luokan (luokituksen). Koska sen ei tarvitse tarkastella kaikkia kohtia uudelleen, tämä tekee siitä a laiska oppimisalgoritmi.
KNN ei myöskään oleta mitään taustalla olevista datan ominaisuuksista, se ei odota tietojen sopivan johonkin jakaumaan, kuten yhtenäiseen, tai olevan lineaarisesti erotettavissa. Tämä tarkoittaa, että se on a ei-parametrinen oppimisalgoritmi. Tämä on erittäin hyödyllinen ominaisuus, koska suurin osa reaalimaailman tiedoista ei todellakaan noudata mitään teoreettista oletusta.
KNN:n eri käyttötapojen visualisointi
Kuten on osoitettu, KNN-algoritmin takana oleva intuitio on yksi suorimmista kaikista valvotuista koneoppimisalgoritmeista. Algoritmi laskee ensin etäisyys uudesta datapisteestä kaikkiin muihin harjoitustietopisteisiin.
Huomautus: Etäisyys voidaan mitata eri tavoin. Voit käyttää Minkowskia, Euklidinen, Manhattan, Mahalanobis tai Hammingin kaava, muutamia mittareita mainitakseni. Korkean ulottuvuuden tiedoilla euklidinen etäisyys alkaa usein epäonnistua (korkea ulottuvuus on… outoa), ja sen sijaan käytetään Manhattan-etäisyyttä.
Etäisyyden laskemisen jälkeen KNN valitsee joukon lähimpiä datapisteitä – 2, 3, 10 tai oikeastaan minkä tahansa kokonaisluvun. Tämä pisteiden määrä (2, 3, 10 jne.) on K K-Lähimissä naapureissa!
Viimeisessä vaiheessa, jos kyseessä on regressiotehtävä, KNN laskee ennusteen K-lähimpien pisteiden keskimääräisen painotetun summan. Jos kyseessä on luokittelutehtävä, uusi datapiste osoitetaan luokkaan, johon suurin osa valituista K-lähimmistä pisteistä kuuluu.
Visualisoidaan algoritmi toiminnassa yksinkertaisen esimerkin avulla. Tarkastellaan tietojoukkoa, jossa on kaksi muuttujaa ja K on 3.
Regressiota suoritettaessa tehtävänä on löytää uuden datapisteen arvo kolmen lähimmän pisteen keskimääräisen painotetun summan perusteella.
KNN kanssa K = 3
, Kun käytetään regressioon:
KNN-algoritmi aloittaa laskemalla uuden pisteen etäisyyden kaikista pisteistä. Sitten se löytää 3 pistettä, joilla on pienin etäisyys uuteen pisteeseen. Tämä näkyy toisessa yllä olevassa kuvassa, jossa kolme lähintä pistettä, 47
, 58
ja 79
on piiritetty. Sen jälkeen se laskee painotetun summan 47
, 58
ja 79
– tässä tapauksessa painot ovat yhtä suuria kuin 1 – kaikki pisteet ovat yhtäläisiä, mutta voimme myös antaa erilaisia painoja etäisyyden perusteella. Painotetun summan laskemisen jälkeen uusi pistearvo on 61,33
.
Ja luokittelua suoritettaessa KNN:n tehtävänä on luokitella uusi datapiste "Purple"
or "Red"
luokka.
KNN kanssa K = 3
, Kun käytetään luokitteluun:
KNN-algoritmi alkaa samalla tavalla kuin ennenkin, laskemalla uuden pisteen etäisyys kaikista pisteistä, etsimällä 3 lähintä pistettä, joilla on pienin etäisyys uuteen pisteeseen, ja sitten luvun laskemisen sijaan se määrittää uusi piste luokkaan, johon suurin osa kolmesta lähimmästä pisteestä kuuluu, punainen luokka. Siksi uusi tietopiste luokitellaan "Red"
.
Outlier-detektioprosessi on erilainen kuin edellä mainitut, puhumme siitä lisää toteutettaessa sitä regressio- ja luokittelutoteutusten jälkeen.
Huomautuksia: Tässä opetusohjelmassa annettu koodi on suoritettu ja testattu seuraavilla tavoilla Jupyter-muistikirja.
Scikit-Learn Kalifornian asuntotietojoukko
Aiomme käyttää Kalifornian asuntojen tietojoukko kuvaamaan KNN-algoritmin toimintaa. Aineisto on peräisin Yhdysvaltain vuoden 1990 väestönlaskennasta. Yksi tietojoukon rivi edustaa yhden lohkoryhmän laskentaa.
Tässä osiossa käymme läpi Kalifornian asuntotietojoukon yksityiskohdat, jotta voit saada intuitiivisen käsityksen tiedoista, joiden kanssa työskentelemme. On erittäin tärkeää tutustua tietoihisi ennen kuin aloitat niiden käsittelyn.
A lohko ryhmä on pienin maantieteellinen yksikkö, josta US Census Bureau julkaisee näytetietoja. Korttiryhmän lisäksi toinen termi on kotitalous, kotitalous on ryhmä ihmisiä, jotka asuvat kodin sisällä.
Tietojoukko koostuu yhdeksästä attribuutista:
MedInc
– mediaanitulo lohkoryhmässäHouseAge
– talon keski-ikä kortteliryhmässäAveRooms
- huoneiden keskimääräinen lukumäärä (taloutta kohden)AveBedrms
– keskimääräinen makuuhuoneiden lukumäärä (perin kotitalous)Population
– lohkoryhmäpopulaatioAveOccup
– kotitalouden jäsenten keskimääräinen lukumääräLatitude
– lohkoryhmän leveysasteLongitude
– lohkoryhmän pituusasteMedHouseVal
– talon mediaaniarvo Kalifornian alueilla (satoja tuhansia dollareita)
Tietojoukko on on jo osa Scikit-Learn-kirjastoa, meidän tarvitsee vain tuoda se ja ladata se tietokehyksenä:
from sklearn.datasets import fetch_california_housing
california_housing = fetch_california_housing(as_frame=True)
df = california_housing.frame
Tietojen tuonti suoraan Scikit-Learnistä tuo enemmän kuin vain sarakkeita ja numeroita ja sisältää tietojen kuvauksen Bunch
objekti – olemme juuri poimineet sen frame
. Lisätietoja tietojoukosta on saatavilla tätä.
Tuodaan Pandat ja kurkistamme ensimmäisiin tietoriveihin:
import pandas as pd
df.head()
Koodin suorittaminen näyttää tietojoukon viisi ensimmäistä riviä:
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
Tässä oppaassa käytämme MedInc
, HouseAge
, AveRooms
, AveBedrms
, Population
, AveOccup
, Latitude
, Longitude
ennustaa MedHouseVal
. Jotain samanlaista kuin motivaatiokertomuksessamme.
Siirrytään nyt suoraan KNN-algoritmin toteuttamiseen regressiota varten.
Regressio K-lähimpien naapureiden kanssa Scikit-Learnin avulla
Toistaiseksi olemme tutustuneet tietojoukkoomme ja nyt voimme jatkaa KNN-algoritmin muihin vaiheisiin.
KNN-regression tietojen esikäsittely
Esikäsittelyssä näkyvät ensimmäiset erot regressio- ja luokittelutehtävien välillä. Koska tässä osiossa on kyse regressiosta, valmistelemme tietojoukkomme sen mukaisesti.
Regressiota varten meidän on ennustettava toinen talon mediaaniarvo. Tätä varten annamme tehtävän MedHouseVal
että y
ja kaikki muut sarakkeet X
vain pudottamalla MedHouseVal
:
y = df['MedHouseVal']
X = df.drop(['MedHouseVal'], axis = 1)
Tarkastelemalla muuttujien kuvauksia voimme nähdä, että mittauksissamme on eroja. Arvaamisen välttämiseksi käytetään describe()
tapa tarkistaa:
X.describe().T
Tämä johtaa:
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
Tässä voimme nähdä, että mean
arvo MedInc
on noin 3.87
ja mean
arvo HouseAge
on noin 28.64
, joten se on 7.4 kertaa suurempi kuin MedInc
. Myös muilla ominaisuuksilla on eroja keskiarvossa ja keskihajonnassa – nähdäksesi sen katsomalla mean
ja std
arvot ja tarkkailla, kuinka kaukana ne ovat toisistaan. varten MedInc
std
on noin 1.9
Varten HouseAge
, std
is 12.59
ja sama koskee muita ominaisuuksia.
Käytämme algoritmia, joka perustuu etäisyys ja etäisyyteen perustuvat algoritmit kärsivät suuresti tiedoista, jotka eivät ole samassa mittakaavassa, kuten nämä tiedot. Pisteiden asteikko voi (ja käytännössä lähes aina) vääristää todellista arvojen välistä etäisyyttä.
Käytämme Scikit-Learnin ominaisuuksien skaalauksen suorittamiseen StandardScaler
luokka myöhemmin. Jos käytämme skaalausta juuri nyt (ennen junatestin jakoa), laskelma sisältäisi testitiedot tehokkaasti vuotava testidatatiedot muuhun putkilinjaan. Tällainen tietojen vuotaminen on valitettavasti yleensä ohitettu, mikä johtaa toistamattomiin tai illusorisiin löydöksiin.
Tietojen jakaminen juna- ja testisarjoiksi
Jotta voimme skaalata tietojamme ilman vuotoja, mutta myös arvioida tuloksiamme ja välttää liiallista sovittamista, jaamme tietojoukkomme juna- ja testijakoiksi.
Yksinkertainen tapa luoda juna- ja testijakoja on train_test_split
Scikit-Learnin menetelmä. Jako ei jakaudu lineaarisesti jossain vaiheessa, vaan näytteitä X% ja Y% satunnaisesti. Jotta tämä prosessi olisi toistettava (jotta menetelmästä tulee aina näytteitä samoista tietopisteistä), asetamme random_state
argumentti tiettyyn 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)
Tämä koodinpätkä ottaa näytteitä 75 % datasta koulutusta varten ja 25 % datasta testausta varten. Muuttamalla test_size
esimerkiksi 0.3:een voit harjoitella 70 prosentilla tiedoista ja testata 30 prosentilla.
Käyttämällä 75 % tiedoista koulutukseen ja 25 % testaukseen, 20640 15480 tietueesta harjoitussarja sisältää 5160 XNUMX ja testisarja XNUMX XNUMX. Voimme tarkistaa nämä luvut nopeasti tulostamalla koko tietojoukon ja jaetun tiedon pituudet. :
len(X)
len(X_train)
len(X_test)
Loistava! Voimme nyt sovittaa dataskaalauslaitteen X_train
asettaa ja skaalata molemmat X_train
ja X_test
vuotamatta mitään tietoja X_test
tulee X_train
.
Ominaisuuden skaalaus KNN-regressiota varten
Tuomalla StandardScaler
, instantoimalla sen, sovittamalla sen junatietojemme mukaan (estämällä vuodon) ja muuntamalla sekä juna- että testitietojoukot, voimme suorittaa ominaisuuden skaalauksen:
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(X_train)
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)
Huomautus: Koska soitat usein scaler.fit(X_train)
jälkeen scaler.transform(X_train)
– voit soittaa sinkku scaler.fit_transform(X_train)
jälkeen scaler.transform(X_test)
lyhentääksesi puhelua!
Nyt tietomme on skaalattu! Skaalaus säilyttää vain tietopisteet, ei sarakkeiden nimiä, kun sitä käytetään a DataFrame
. Järjestetään tiedot uudelleen DataFrame-kehykseen sarakkeiden nimien ja käytön kanssa describe()
tarkkailla muutoksia mean
ja std
:
col_names=['MedInc', 'HouseAge', 'AveRooms', 'AveBedrms', 'Population', 'AveOccup', 'Latitude', 'Longitude']
scaled_df = pd.DataFrame(X_train, columns=col_names)
scaled_df.describe().T
Tämä antaa meille:
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
Tarkkaile, kuinka kaikki standardipoikkeamat ovat nyt 1
ja keinot ovat pienentyneet. Tämä tekee tietomme yhtenäisempi! Harjoitellaan ja arvioidaan KNN-pohjainen regressori.
KNN-regression harjoittaminen ja ennustaminen
Scikit-Learnin intuitiivinen ja vakaa API tekee regressoreiden ja luokittelijien koulutuksesta erittäin yksinkertaista. Tuodaan KNeighborsRegressor
luokasta alkaen sklearn.neighbors
moduuli, instantoi se ja sovita se junatietoihimme:
from sklearn.neighbors import KNeighborsRegressor
regressor = KNeighborsRegressor(n_neighbors=5)
regressor.fit(X_train, y_train)
Yllä olevassa koodissa n_neighbors
on arvo K, tai naapurien lukumäärä, jonka algoritmi ottaa huomioon valitessaan uutta talon mediaaniarvoa. 5
on oletusarvo kohteelle KNeighborsRegressor()
. K:lle ei ole ihanteellista arvoa ja se valitaan testauksen ja arvioinnin jälkeen, mutta alkuun 5
on yleisesti käytetty arvo KNN:lle, joten se asetettiin oletusarvoksi.
Viimeinen vaihe on tehdä ennusteita testitiedoistamme. Voit tehdä tämän suorittamalla seuraavan skriptin:
y_pred = regressor.predict(X_test)
Voimme nyt arvioida, kuinka hyvin mallimme yleistyy uuteen dataan, jolle meillä on tunnisteet (maatotuus) – testisarja!
KNN-regression algoritmin arviointi
Yleisimmin käytetyt regressiometriikot algoritmin arvioinnissa ovat keskimääräinen absoluuttinen virhe (MAE), keskimääräinen neliövirhe (MSE), keskimääräinen neliövirhe (RMSE) ja determinaatiokerroin (R).2):
- Keskimääräinen absoluuttinen virhe (MAE): Kun vähennämme ennustetut arvot todellisista arvoista, lasketaan virheet, lasketaan yhteen näiden virheiden absoluuttiset arvot ja saadaan niiden keskiarvo. Tämä mittari antaa käsityksen mallin kunkin ennusteen kokonaisvirheestä, mitä pienempi (lähempänä nollaa), sitä parempi:
$$
mae = (frac{1}{n})sum_{i=1}^{n}vasen | Todellinen – Ennustettu oikea |
$$
Huomautus: Saatat myös kohdata y
ja ŷ
(lue y-hattu) merkintä yhtälöissä. The y
viittaa todellisiin arvoihin ja ŷ
ennustettuihin arvoihin.
- Keskimääräinen neliövirhe (MSE): Se on samanlainen kuin MAE-metriikka, mutta se neliöi virheiden absoluuttiset arvot. Lisäksi, kuten MAE:n tapauksessa, mitä pienempi tai lähempänä nollaa, sitä parempi. MSE-arvo on neliöity, jotta suuret virheet ovat vielä suurempia. Yksi asia, johon on kiinnitettävä erityistä huomiota, on se, että sitä on yleensä vaikea tulkita sen arvojen koon ja sen vuoksi, että ne eivät ole samassa mittakaavassa kuin tiedot.
$$
mse = summa_{i=1}^{D}(Todellinen – Ennustettu)^2
$$
- Root Mean Squared Error (RMSE): Yrittää ratkaista MSE:n kanssa esiin nostetun tulkintaongelman saamalla sen lopullisen arvon neliöjuuren skaalatakseen sen takaisin samoihin datayksiköihin. Se on helpompi tulkita ja hyvä, kun täytyy näyttää tai näyttää datan todellinen arvo virheen kanssa. Se näyttää kuinka paljon tiedot voivat vaihdella, joten jos meillä on RMSE 4.35, mallimme voi tehdä virheen joko koska se lisäsi 4.35 todelliseen arvoon tai tarvitsi 4.35 päästäkseen todelliseen arvoon. Mitä lähempänä nollaa, sen parempi.
$$
rmse = sqrt{ summa_{i=1}^{D}(todellinen – ennustettu)^2}
$$
- mean_absolute_error()
ja mean_squared_error()
menetelmät sklearn.metrics
voidaan käyttää näiden mittareiden laskemiseen, kuten seuraavasta katkelmasta näkyy:
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}')
Yllä olevan skriptin tulos näyttää tältä:
mae: 0.4460739527131783
mse: 0.4316907430948294
rmse: 0.6570317671884894
R2 voidaan laskea suoraan score()
menetelmä:
regressor.score(X_test, y_test)
Mitkä lähdöt:
0.6737569252627673
Tulokset osoittavat, että KNN-algoritmimme kokonaisvirhe ja keskivirhe ovat noin 0.44
ja 0.43
. Lisäksi RMSE osoittaa, että voimme ylittää tai alle datan todellisen arvon lisäämällä 0.65
tai vähentämällä 0.65
. Kuinka hyvä se on?
Katsotaan miltä hinnat näyttävät:
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
Keskiarvo on 2.06
ja keskihajonta keskiarvosta on 1.15
joten pisteemme ~0.44
ei todellakaan ole loistava, mutta ei myöskään huono.
R:n kanssa2, mitä lähempänä arvoa 1 saamme (tai 100), sitä parempi. R2 kertoo kuinka suuri osa datan muutoksista vaihtelu ymmärretään tai selitti kirjoittanut KNN.
$$
R^2 = 1 – murto{summa(todellinen – ennustettu)^2}{sum(todellinen – todellinen keskiarvo)^2}
$$
Arvolla 0.67
, voimme nähdä, että mallimme selittää 67 % datavarianssista. Se on jo yli 50%, mikä on ok, mutta ei kovin hyvä. Voisimmeko tehdä paremmin?
Olemme käyttäneet ennalta määrättyä K:ta, jonka arvo on 5
, joten käytämme viittä naapuria tavoitteidemme ennustamiseen, mikä ei välttämättä ole paras luku. Ymmärtääksemme, mikä olisi ihanteellinen Ks-luku, voimme analysoida algoritmivirheet ja valita K:n, joka minimoi häviön.
Parhaan K:n löytäminen KNN-regressiolle
Ihannetapauksessa näkisit, mikä mittari sopii paremmin kontekstisiisi – mutta yleensä on mielenkiintoista testata kaikkia mittareita. Aina kun voit testata niitä kaikkia, tee se. Tässä näytämme, kuinka valita paras K käyttämällä vain keskimääräistä absoluuttista virhettä, mutta voit muuttaa sen mihin tahansa muuhun mittariin ja vertailla tuloksia.
Tätä varten luomme for-silmukan ja suoritamme malleja, joilla on 1 - X naapureita. Jokaisessa vuorovaikutuksessa laskemme MAE:n ja kuvaamme Ks:n määrän yhdessä MAE-tuloksen kanssa:
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)
Nyt piirretään 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')
Kaaviosta katsottuna näyttää siltä, että pienin MAE-arvo on, kun K on 12
. Katsotaanpa kuvaajaa tarkemmin, jotta voimme olla varmoja piirtämällä vähemmän dataa:
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')
Tutustu käytännönläheiseen, käytännölliseen Gitin oppimisoppaaseemme, jossa on parhaat käytännöt, alan hyväksymät standardit ja mukana tuleva huijauslehti. Lopeta Git-komentojen googlailu ja oikeastaan oppia se!
Voit myös saada pienimmän virheen ja kyseisen pisteen indeksin käyttämällä sisäänrakennettua min()
funktio (toimii listoilla) tai muunna luettelo NumPy-taulukoksi ja hanki argmin()
(alhaisimman arvon omaavan elementin indeksi):
import numpy as np
print(min(error))
print(np.array(error).argmin())
Aloimme laskea naapureita 1:llä, kun taas taulukot ovat 0-pohjaisia, joten 11. indeksi on 12 naapuria!
Tämä tarkoittaa, että tarvitsemme 12 naapuria voidaksemme ennustaa pisteen, jolla on pienin MAE-virhe. Voimme suorittaa mallin ja mittarit uudelleen 12 naapurin kanssa tulosten vertailua varten:
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}')
Seuraavat koodit tulostuvat:
r2: 0.6887495617137436,
mae: 0.43631325936692505
mse: 0.4118522151025172
rmse: 0.6417571309323467
12 naapurin kanssa KNN-mallimme selittää nyt 69 % datan varianssista ja on menettänyt hieman vähemmän, alkaen 0.44
että 0.43
, 0.43
että 0.41
ja 0.65
että 0.64
vastaavien mittareiden kanssa. Se ei ole suuri parannus, mutta se on parannus kuitenkin.
Huomautus: Tässä analyysissä pidemmälle menevä Exploratory Data Analysis (EDA) -analyysi yhdessä jäännösanalyysin kanssa voi auttaa valitsemaan ominaisuuksia ja saavuttamaan parempia tuloksia.
Olemme jo nähneet, kuinka KNN:ää käytetään regressioon – mutta entä jos haluaisimme luokitella pisteen sen arvon ennustamisen sijaan? Nyt voimme tarkastella, kuinka KNN:ää käytetään luokitteluun.
Luokittelu K-lähimpien naapureiden avulla Scikit-Learnin avulla
Tässä tehtävässä jatkuvan arvon ennustamisen sijaan haluamme ennustaa luokan, johon nämä lohkoryhmät kuuluvat. Tätä varten voimme jakaa kaupunginosien talon mediaaniarvon ryhmiin, joilla on eri talon arvoalueet tai roskakorit.
Kun haluat käyttää luokittelussa jatkuvaa arvoa, voit yleensä binoida tiedot. Tällä tavalla voit ennustaa ryhmiä arvojen sijaan.
Datan esikäsittely luokitusta varten
Luodaan tietosäiliöt jatkuvan arvomme muuntamiseksi luokkiin:
df["MedHouseValCat"] = pd.qcut(df["MedHouseVal"], 4, retbins=False, labels=[1, 2, 3, 4])
Sitten voimme jakaa tietojoukkomme sen attribuutteiksi ja tunnisteiksi:
y = df['MedHouseValCat']
X = df.drop(['MedHouseVal', 'MedHouseValCat'], axis = 1)
Koska olemme käyttäneet MedHouseVal
sarakkeessa roskakorien luomiseksi, meidän on pudotettava MedHouseVal
sarake ja MedHouseValCat
sarakkeita alkaen X
. Tällä tavalla, DataFrame
sisältää tietojoukon 8 ensimmäistä saraketta (eli attribuutteja, ominaisuuksia), kun taas meidän y
sisältää vain MedHouseValCat
määritetty tunniste.
Huomautus: Voit valita sarakkeita myös käyttämällä .iloc()
sen sijaan, että pudotat ne. Kun pudotat, muista vain, että sinun on tehtävä määräys y
arvot ennen määrittämistä X
arvot, koska et voi määrittää pudotettua saraketta a DataFrame
toiseen muistissa olevaan esineeseen.
Tietojen jakaminen juna- ja testisarjoiksi
Kuten regression kanssa on tehty, jaamme tietojoukon myös harjoitus- ja testijakoiksi. Koska meillä on erilaisia tietoja, meidän on toistettava tämä prosessi:
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)
Käytämme jälleen normaalia Scikit-Learn-arvoa 75 % junatiedoista ja 25 % testitiedoista. Tämä tarkoittaa, että meillä on sama juna- ja testimäärä tietueita kuin aiemmin regressiossa.
Ominaisuuden skaalaus luokittelua varten
Koska kyseessä on sama käsittelemätön tietojoukko ja sen vaihtelevat mittayksiköt, suoritamme ominaisuuksien skaalauksen uudelleen samalla tavalla kuin teimme regressiodatallemme:
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(X_train)
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)
Luokittelun koulutus ja ennustaminen
Tietojen binnauksen, jakamisen ja skaalauksen jälkeen voimme vihdoin sovittaa siihen luokituksen. Ennustuksessa käytämme jälleen viittä naapuria lähtöviivana. Voit myös instantoida KNeighbors_
luokkaan ilman argumentteja ja se käyttää automaattisesti viittä naapuria. Tässä sen sijaan, että tuodaan KNeighborsRegressor
, tuomme maahan KNeighborsClassifier
, luokka:
from sklearn.neighbors import KNeighborsClassifier
classifier = KNeighborsClassifier()
classifier.fit(X_train, y_train)
Asennuksen jälkeen KNeighborsClassifier
, voimme ennustaa testidatan luokat:
y_pred = classifier.predict(X_test)
On aika arvioida ennusteita! Olisiko luokkien ennustaminen parempi lähestymistapa kuin arvojen ennustaminen tässä tapauksessa? Arvioidaan algoritmi nähdäksesi mitä tapahtuu.
KNN:n luokittelun arviointi
KNN-luokituksen arvioimiseen voimme käyttää myös score
menetelmää, mutta se suorittaa eri mittarin, koska pisteytetään luokittelijaa emme regressoria. Luokittelun perusmittari on accuracy
– se kuvaa kuinka monta ennustetta luokittimemme osui oikeaan. Pienin tarkkuusarvo on 0 ja suurin on 1. Yleensä kerromme tämän arvon 100:lla saadaksemme prosenttiosuuden.
$$
tarkkuus = murto{teksti{oikeiden ennusteiden määrä}}{teksti{ennusteiden kokonaismäärä}}
$$
Huomautus: On äärimmäisen vaikeaa saada 100 % tarkkuutta mistään todellisesta tiedosta, jos näin tapahtuu, ota huomioon, että jokin vuoto tai jotain vikaa saattaa tapahtua – ideaalisesta tarkkuusarvosta ei ole yksimielisyyttä ja se on myös kontekstista riippuvainen. Riippuen virheen hinta (Kuinka huonoa se on, jos luotamme luokittimeen ja se osoittautuu vääräksi), hyväksyttävä virheprosentti voi olla 5%, 10% tai jopa 30%.
Arvostetaan luokittelumme:
acc = classifier.score(X_test, y_test)
print(acc)
Tarkastelemalla tuloksena saatua pistemäärää voimme päätellä, että luokittelijamme sai ~62% luokistamme oikein. Tämä auttaa jo analyysissä, vaikka kun vain tietää, mitä luokitin on saanut oikein, sitä on vaikea parantaa.
Tietojoukossamme on 4 luokkaa – entä jos luokittimemme saisi 90 % luokista 1, 2 ja 3 oikein, mutta vain 30 % luokasta 4 oikein?
Joidenkin luokkien systeeminen vika, toisin kuin luokkien välillä jaettu tasapainoinen vika, voi saada molemmat 62 %:n tarkkuuden. Tarkkuus ei ole todella hyvä mittari todellista arviointia varten – mutta se toimii hyvänä välityspalvelimena. Useimmiten tasapainotetuilla tietojoukoilla 62 %:n tarkkuus jakautuu suhteellisen tasaisesti. Useimmiten tietojoukot eivät myöskään ole tasapainossa, joten olemme palanneet alkupisteeseen, ja tarkkuus on riittämätön mittari.
Voimme tarkastella tuloksia syvemmällä käyttämällä muita mittareita voidaksemme määrittää sen. Tämä vaihe eroaa myös regressiosta, tässä käytetään:
- Sekaannusmatriisi: Tietääksemme kuinka paljon olemme oikeassa tai väärässä jokainen luokka. Arvoja, jotka olivat oikein ja oikein ennustettu, kutsutaan tosi positiivisia Niitä, joiden ennustettiin olevan positiivisia, mutta jotka eivät olleet positiivisia, kutsutaan vääriä positiivisia. Sama nimikkeistö todellisia negatiivisia ja väärät negatiivit käytetään negatiivisille arvoille;
- Tarkkuus: Ymmärtääksemme, mitä oikeita ennustearvoja luokittelijamme piti oikeina. Tarkkuus jakaa nämä todelliset positiiviset arvot kaikella, mikä ennustettiin positiiviseksi;
$$
tarkkuus = frac{teksti{tosi positiivinen}}{teksti{tosi positiivinen} + teksti{väärä positiivinen}}
$$
- Palauttaa mieleen: ymmärtääksesi kuinka monta todellista positiivista luokittimemme tunnisti. Palauttaminen lasketaan jakamalla todelliset positiiviset asiat millä tahansa, jonka olisi pitänyt ennustaa positiiviseksi.
$$
muistaa = frac{teksti{tosi positiivinen}}{teksti{tosi positiivinen} + teksti{väärä negatiivinen}}
$$
- F1 pisteet: Onko tasapainotettu vai harmoninen keskiarvo tarkkuudesta ja muistamisesta. Pienin arvo on 0 ja suurin on 1. Milloin
f1-score
on yhtä suuri kuin 1, se tarkoittaa, että kaikki luokat ennustettiin oikein – tämä on erittäin vaikea pistemäärä saada todellisella tiedolla (poikkeuksia on melkein aina).
$$
teksti{f1-pisteet} = 2* frac{teksti{tarkkuus} * teksti{recall}}{teksti{tarkkuus} + teksti{recall}}
$$
Huomautus: Myös painotettu F1-pistemäärä on olemassa, ja se on vain F1, joka ei sovella samaa painoa kaikissa luokissa. Paino määräytyy tyypillisesti luokkien mukaan tuki – kuinka monta tapausta "tukee" F1-pistemäärää (tiettyyn luokkaan kuuluvien tarrojen osuus). Mitä pienempi tuki (mitä vähemmän luokkaa esiintyy), sitä pienempi on kyseisen luokan painotettu F1, koska se on epäluotettavampi.
- confusion_matrix()
ja classification_report()
menetelmät sklearn.metrics
moduulia voidaan käyttää kaikkien näiden mittareiden laskemiseen ja näyttämiseen. The confusion_matrix
on paremmin visualisoitu lämpökartan avulla. Luokitteluraportti antaa jo meille accuracy
, precision
, recall
ja f1-score
, mutta voit myös tuoda nämä tiedot kohteesta sklearn.metrics
.
Saadaksesi tiedot suorittamalla seuraavan koodinpätkän:
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))
Yllä olevan skriptin tulos näyttää tältä:
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
Tulokset osoittavat, että KNN pystyi luokittelemaan kaikki testisarjan 5160 tietuetta 62 %:n tarkkuudella, mikä on keskimääräistä parempi. Tuet ovat melko tasaiset (tasainen luokkien jakautuminen tietojoukossa), joten painotettu F1 ja painomaton F1 ovat suunnilleen samat.
Voimme myös nähdä kunkin neljän luokan mittareiden tuloksen. Sen perusteella voimme huomata sen class 2
oli pienin tarkkuus, pienin recall
, ja alin f1-score
. Class 3
on aivan takana class 2
alhaisimmat pisteet, ja sitten meillä on class 1
parhaat pisteet, joita seuraa class 4
.
Katsomalla hämmennysmatriisia voimme nähdä, että:
class 1
enimmäkseen erehtyiclass 2
238 tapauksessaclass 2
vartenclass 1
256 merkinnässä ja vartenclass 3
260 tapauksessaclass 3
erehtyi lähinnäclass 2
, 374 merkintää jaclass 4
, 193 tapauksessaclass 4
luokiteltiin väärinclass 3
339 merkinnälle ja asclass 2
130 tapauksessa.
Huomaa myös, että diagonaali näyttää todelliset positiiviset arvot, kun sitä katsot, on selvää, että class 2
ja class 3
niillä on vähiten oikein ennustetut arvot.
Näiden tulosten avulla voisimme mennä syvemmälle analyysiin tarkastamalla niitä edelleen selvittääksemme, miksi näin tapahtui, ja myös ymmärtämällä, ovatko 4 luokkaa paras tapa kerätä tiedot. Ehkä arvot class 2
ja class 3
olivat liian lähellä toisiaan, joten heidän oli vaikea erottaa toisistaan.
Yritä aina testata tietoja eri määrällä säiliöitä nähdäksesi mitä tapahtuu.
Satunnaisen tietolaatikoiden lukumäärän lisäksi on olemassa myös toinen mielivaltainen luku, jonka olemme valinneet, K naapurin lukumäärä. Samaa tekniikkaa, jota käytimme regressiotehtävässä, voidaan soveltaa luokitukseen määritettäessä Ks-lukua, joka maksimoi tai minimoi metriikan arvon.
Parhaan K:n löytäminen KNN-luokitukseen
Toistetaan mitä on tehty regressiolle ja piirretään K-arvojen kaavio ja vastaava metriikka testijoukolle. Voit myös valita, mikä mittari sopii paremmin kontekstiisi, tässä me valitsemme f1-score
.
Tällä tavalla piirrämme f1-score
testisarjan ennustetuille arvoille kaikille K-arvoille välillä 1–40.
Ensin tuomme maahan f1_score
alkaen sklearn.metrics
ja laske sitten sen arvo kaikille K-Lähimpien naapurien luokittimen ennusteille, joissa K on 1-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'))
Seuraava askel on piirtää f1_score
arvot K-arvoja vastaan. Ero regressioon on se, että sen sijaan, että valitsisimme virheen minimoivan K-arvon, tällä kertaa valitsemme arvon, joka maksimoi f1-score
.
Luo juoni suorittamalla seuraava komentosarja:
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')
Tuloskaavio näyttää tältä:
Tulosteesta voimme nähdä, että f1-score
on suurin, kun K:n arvo on 15
. Koulutetaan luokittimemme uudelleen 15 naapurilla ja katsotaan, mitä se tekee luokitusraportin tuloksille:
classifier15 = KNeighborsClassifier(n_neighbors=15)
classifier15.fit(X_train, y_train)
y_pred15 = classifier15.predict(X_test)
print(classification_report(y_test, y_pred15))
Tämä tuottaa:
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
Huomaa, että mittarimme ovat parantuneet 15 naapurin kanssa, meillä on 63 %:n tarkkuus ja enemmän precision
, recall
ja f1-scores
, mutta meidän on silti tarkasteltava roskakoria tarkemmin, jotta voimme ymmärtää, miksi f1-score
luokkia varten 2
ja 3
on edelleen matala.
Sen lisäksi, että käytämme KNN:ää regressioon ja lohkoarvojen määrittämiseen ja luokitukseen, lohkoluokkien määrittämiseen – voimme myös käyttää KNN:tä havaitsemaan, mitkä lohkojen keskiarvot poikkeavat useimmista – sellaiset, jotka eivät seuraa mitä suurin osa datasta tekee. Toisin sanoen voimme käyttää KNN:ää poikkeamien havaitseminen.
KNN:n käyttöönotto outlier-tunnistukseen Scikit-Learnin avulla
Outlier-tunnistus käyttää toista menetelmää, joka poikkeaa siitä, mitä teimme aiemmin regressiolle ja luokittelulle.
Täällä näemme, kuinka kaukana kukin naapureista on datapisteestä. Käytetään oletusarvoisia 5 naapureita. Datapisteen osalta laskemme etäisyyden jokaiseen K-lähimpään naapuriin. Tätä varten tuomme Scikit-learnistä toisen KNN-algoritmin, joka ei ole spesifinen regressiolle tai luokittelulle, jota kutsutaan yksinkertaisesti NearestNeighbors
.
Tuonnin jälkeen instantoimme a NearestNeighbors
luokka 5 naapurilla – voit myös ilmentää sen 12 naapurilla tunnistaaksesi poikkeamat regressioesimerkissämme tai 15:llä tehdäksesi samoin luokitusesimerkissä. Sitten sovitamme junatietomme ja käytämme kneighbors()
menetelmä laskettujen etäisyyksien löytämiseksi jokaiselle datapisteelle ja naapuriindeksille:
from sklearn.neighbors import NearestNeighbors
nbrs = NearestNeighbors(n_neighbors = 5)
nbrs.fit(X_train)
distances, indexes = nbrs.kneighbors(X_train)
Nyt meillä on 5 etäisyyttä kullekin datapisteelle – etäisyys itsensä ja sen viiden naapurin välillä sekä indeksi, joka tunnistaa ne. Katsotaanpa kolmea ensimmäistä tulosta ja taulukon muotoa nähdäksesi tämän paremmin.
Katsoaksesi kolmen ensimmäisen etäisyyden muotoa, suorita:
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))
Huomaa, että rivissä on 3 riviä, joissa kussakin on 5 etäisyyttä. Voimme katsoa myös naapureiden indeksejä:
indexes[:3], indexes[:3].shape
Tämä johtaa:
(array([[ 0, 8608, 12831, 8298, 2482],
[ 1, 4966, 5786, 8568, 6759],
[ 2, 13326, 13936, 3618, 9756]]),
(3, 5))
Yllä olevassa tulosteessa voimme nähdä kunkin viiden naapurin indeksit. Nyt voimme jatkaa viiden etäisyyden keskiarvon laskemista ja piirtää kaavion, joka laskee jokaisen rivin X-akselilla ja näyttää jokaisen keskimääräisen etäisyyden Y-akselilla:
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')
Huomaa, että kaaviossa on osa, jossa keskietäisyyksillä on tasaiset arvot. Se Y-akselin piste, jossa keskiarvot eivät ole liian korkeat tai liian matalat, on juuri se piste, joka meidän on tunnistettava poikkeavien arvojen leikkaamiseksi.
Tässä tapauksessa keskimääräinen etäisyys on 3. Piirretään kaavio uudelleen vaakasuuntaisella katkoviivalla, jotta voimme havaita sen:
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 = '--')
Tämä viiva merkitsee keskimääräistä etäisyyttä, jonka yläpuolella kaikki arvot vaihtelevat. Tämä tarkoittaa, että kaikki pisteet, joissa on a mean
etäisyys yläpuolella 3
ovat poikkeamiamme. Voimme selvittää näiden pisteiden indeksit käyttämällä np.where()
. Tämä menetelmä tulostaa joko True
or False
kunkin indeksin osalta mean
3: n yläpuolella kunto:
import numpy as np
outlier_index = np.where(dist_means > 3)
outlier_index
Yllä oleva koodi tulostaa:
(array([ 564, 2167, 2415, 2902, 6607, 8047, 8243, 9029, 11892,
12127, 12226, 12353, 13534, 13795, 14292, 14707]),)
Nyt meillä on outlier-pisteindeksimme. Etsitään ne tietokehyksestä:
outlier_values = df.iloc[outlier_index]
outlier_values
Tämä johtaa:
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
Poikkeavien havainnointimme on valmis. Näin havaitsemme jokaisen datapisteen, joka poikkeaa yleisestä datatrendistä. Voimme nähdä, että junatiedoissamme on 16 pistettä, joita tulisi tarkastella tarkemmin, tutkia, ehkä käsitellä tai jopa poistaa tiedoistamme (jos ne syötettiin virheellisesti) tulosten parantamiseksi. Nämä kohdat ovat saattaneet johtua kirjoitusvirheistä, keskimääräisten lohkoarvojen epäjohdonmukaisuuksista tai jopa molemmista.
KNN:n hyvät ja huonot puolet
Tässä osiossa esittelemme joitain KNN-algoritmin käytön etuja ja haittoja.
Plussat
- Se on helppo toteuttaa
- Se on laiska oppimisalgoritmi, eikä siksi vaadi koulutusta kaikissa datapisteissä (käytetään vain K-lähimpien naapureiden ennustamiseen). Tämä tekee KNN-algoritmista paljon nopeamman kuin muut algoritmit, jotka vaativat koulutusta koko tietojoukon kanssa, kuten Tuki vektorikoneille, lineaarinen regressio, Jne
- Koska KNN ei vaadi koulutusta ennen ennusteiden tekemistä, uutta tietoa voidaan lisätä saumattomasti
- KNN:n kanssa toimimiseen tarvitaan vain kaksi parametria, eli K:n arvo ja etäisyysfunktio
MIINUKSET
- KNN-algoritmi ei toimi hyvin suurimittaisten tietojen kanssa, koska suurella määrällä mittasuhteita pisteiden välinen etäisyys muuttuu "oudoksi" ja käyttämämme etäisyysmittarit eivät kestä.
- Lopuksi, KNN-algoritmi ei toimi hyvin kategoristen ominaisuuksien kanssa, koska on vaikea löytää etäisyyttä kategorisilla ominaisuuksilla.
Jatketaan eteenpäin – Hand-Held päästä päähän -projekti
Tässä ohjatussa hankkeessa opit rakentamaan tehokkaita perinteisiä koneoppimismalleja sekä syväoppimismalleja, hyödyntämään Ensemble Learningiä ja kouluttamaan metaoppineita ennustamaan asuntojen hintoja Scikit-Learn- ja Keras-mallien pussin avulla.
Käyttämällä Kerasia, Tensorflow:n päälle rakennettua syväoppimissovellusliittymää, kokeilemme arkkitehtuuria, rakennamme joukon pinottuja malleja ja koulutamme meta-oppija hermoverkko (tason 1 malli) talon hinnoittelun selvittämiseksi.
Syväoppiminen on hämmästyttävää – mutta ennen kuin siihen turvaudutaan, on suositeltavaa yrittää ratkaista ongelma myös yksinkertaisemmilla tekniikoilla, kuten pinnallista oppimista algoritmeja. Lähtötason suorituskykymme perustuu a Satunnainen metsäregressio algoritmi. Lisäksi – tutkimme mallien ryhmien luomista Scikit-Learnin avulla esimerkiksi pussitus ja äänestys.
Tämä on päästä päähän -projekti, ja kuten kaikki koneoppimisprojektit, aloitamme siitä Tutkimusaineistoanalyysi, jonka jälkeen Tietojen esikäsittely ja lopuksi Rakennus matala ja Syväoppimismallit sopimaan aiemmin tutkimiimme ja puhdistamiimme tietoihin.
Yhteenveto
KNN on yksinkertainen mutta tehokas algoritmi. Sitä voidaan käyttää moniin tehtäviin, kuten regressioon, luokitukseen tai poikkeamien havaitsemiseen.
KNN:ää on käytetty laajalti asiakirjojen samankaltaisuuden ja hahmontunnistuksen löytämiseen. Sitä on myös käytetty suositusjärjestelmien kehittämiseen sekä tietokonenäön mittojen pienentämiseen ja esikäsittelyvaiheisiin – erityisesti kasvojentunnistustehtäviin.
Tässä oppaassa olemme käyneet läpi regression, luokituksen ja poikkeamien havaitsemisen käyttämällä Scikit-Learnin K-lähimmän naapurin algoritmin toteutusta.