Definitiv guide til Random Forest Algorithm med Python og Scikit-Learn PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Definitiv guide til Random Forest Algorithm med Python og Scikit-Learn

Introduksjon

Random Forest-algoritmen er en av de mest fleksible, kraftige og mye brukte algoritmene for klassifisering og regresjon, bygget som en ensemble av Decision Trees.

Hvis du ikke er kjent med disse – ingen bekymringer, vi dekker alle disse konseptene.

I denne grundige praktiske veiledningen bygger vi en intuisjon om hvordan beslutningstrær fungerer, hvordan ensembling øker individuelle klassifikatorer og regressorer, hva tilfeldige skoger er og bygg en tilfeldig skogklassifiserer og regressor ved hjelp av Python og Scikit-Learn, gjennom et ende-til-ende miniprosjekt, og svar på et forskningsspørsmål.

Tenk på at du for tiden er en del av en forskningsgruppe som analyserer data om kvinner. Gruppen har samlet inn 100 dataposter og ønsker å kunne organisere de første postene ved å dele kvinnene inn i kategorier: å være gravid eller ikke, og bo i landlige eller urbane områder. Forskerne ønsker å forstå hvor mange kvinner som vil være i hver kategori.

Det er en beregningsstruktur som gjør akkurat det, det er Treet struktur. Ved å bruke en trestruktur vil du kunne representere de ulike divisjonene for hver kategori.

Beslutningstrær

Hvordan fyller du nodene til et tre? Dette er hvor avgjørelse trær komme i fokus.

Først kan vi dele postene etter graviditet, etter det kan vi dele dem ved å bo i urbane eller landlige områder. Legg merke til at vi kunne gjøre dette i en annen rekkefølge, ved å dele innledningsvis med hvilket område kvinnene bor og etter med deres graviditetsstatus. Fra dette kan vi se at treet har et iboende hierarki. I tillegg til å organisere informasjon, organiserer et tre informasjon på en hierarkisk måte – rekkefølgen som informasjonen vises på, betyr noe og fører til forskjellige trær som et resultat.

Nedenfor er et eksempel på treet som er beskrevet:

I trebildet er det 7 ruter, den øverst som utgjør totalt 100 kvinner, denne øverste ruten er forbundet med to ruter under, som deler kvinnene basert på antallet 78 ikke gravide og 22 gravide, og fra begge tidligere ruter er det fire ruter; to knyttet til hver rute over som deler kvinnene ut fra deres område, for de ikke-gravide bor 45 i et tettsted, 33 i et landområde og for de gravide bor 14 i et landområde og 8 i et urbant område. Bare ved å se på treet, er det lett å forstå disse inndelingene og se hvordan hvert "lag" er avledet fra tidligere, disse lagene er treet nivåer, beskriver nivåene dybde av treet:

Definitiv guide til Random Forest Algorithm med Python og Scikit-Learn PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Se på bildet ovenfor at det første trenivået er nivå 0 hvor det bare er én rute, etterfulgt av nivå 1 hvor det er to firkanter, og nivå 2 hvor det er fire ruter. Dette er en dybde 2 tre.

I nivå 0 kalles kvadratet som stammer fra treet, det første rotnode, denne roten har to barn noder på nivå 1, altså foreldrenoder til de fire nodene i nivå 2. Se at "firkantene" vi har nevnt så langt, faktisk heter noder; og at hver forrige node er en forelder til følgende noder, som er dens barn. Undernodene på hvert nivå som har samme overordnede kalles søsken, som kan sees på neste bilde:

Definitiv guide til Random Forest Algorithm med Python og Scikit-Learn PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

I det forrige bildet viser vi også nivå 1 som det indre noder, når de er mellom roten og de siste nodene, som er bladnoder. Bladknutene er den siste delen av et tre, hvis vi skal si fra de 100 første kvinnene, hvor mange som er gravide og bor i landlige områder, kan vi gjøre dette ved å se på bladene. Så tallet ved bladene ville svare på det første forskningsspørsmålet.

Hvis det var nye registreringer av kvinner, og treet som tidligere ble brukt til å kategorisere dem, nå ble brukt til å avgjøre om en kvinne kunne eller ikke kunne være en del av forskningen, ville det fortsatt fungere? Treet vil bruke de samme kriteriene, og en kvinne vil være berettiget til å delta hvis hun er gravid og bor i et landlig område.

Definitiv guide til Random Forest Algorithm med Python og Scikit-Learn PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Ved å se på bildet ovenfor kan vi se at svarene på spørsmålene til hver trenode – «er hun en deltaker?», «er hun gravid?», «bor hun i et landlig område?»- er ja, ja, og ja, så det ser ut til at treet kan tenkes å føre til en beslutning, i dette tilfellet, om at kvinnen kan delta i forskningen.

Dette er essens av beslutningstrær i, gjort på en manuell måte. Ved å bruke maskinlæring kan vi konstruere en modell som konstruerer dette treet automatisk for oss, på en slik måte å maksimere nøyaktigheten til de endelige beslutningene.

OBS: det finnes flere typer trær i informatikk, som binære trær, generelle trær, AVL-trær, spredetrær, røde sorte trær, b-trær osv. Her fokuserer vi på å gi en generell idé om hva som er et beslutningstre. . Hvis det avhenger av svaret til a ja or Nei. spørsmål for hver node og dermed hver node har høyst to barn, når sortert slik at de "mindre" nodene er til venstre, klassifiserer dette beslutningstrær som binære trær.

I de foregående eksemplene, observer hvordan treet kunne enten klassifisere nye data som deltaker eller ikke-deltaker, eller spørsmålene kan også endres til – «hvor mange er deltakere?», «hvor mange er gravide?», «hvor mange bor i et landlig område?»- som fører til at vi finner kvantitet av gravide deltakere som bor på landsbygda.

Når dataene er klassifisert, betyr dette at treet utfører en klassifisering oppgave, og når datamengden er funnet, utfører treet en regresjon oppgave. Dette betyr at beslutningstreet kan brukes til både oppgaver – klassifisering og regresjon.

Nå som vi forstår hva et beslutningstre er, hvordan kan det brukes og hvilken nomenklatur som brukes for å beskrive det, kan vi undre oss over dets begrensninger.

Forstå tilfeldige skoger

Hva skjer med avgjørelsen hvis noen deltaker lever på skillet mellom by og land? Ville treet legge denne rekorden til landlige eller urbane? Det virker vanskelig å passe disse dataene inn i strukturen vi har for øyeblikket, siden de er ganske tydelige.

Også, hva om en kvinne som bor på en båt deltar i forskningen, ville det bli betraktet som landlig eller urbant? På samme måte som det forrige tilfellet er det et utfordrende datapunkt å klassifisere med tanke på tilgjengelige alternativer i treet.

Ved å tenke litt mer på eksempelet på beslutningstreet, kan vi se at det kan klassifisere nye data riktig, med tanke på at de allerede følger et mønster som treet allerede har – men når det er poster som skiller seg fra de opprinnelige dataene som definerte treet, trestrukturen er for stiv, noe som gjør at postene ikke kan klassifiseres.

Dette betyr at beslutningstreet kan være strengt og begrenset i sine muligheter. Et ideelt beslutningstre ville være mer fleksibelt og i stand til å imøtekomme mer nyanserte usett data.

Løsning: Akkurat som "to par øyne ser bedre enn ett", kommer to modeller vanligvis med et mer nøyaktig svar enn ett. Med tanke på mangfoldet i kunnskapsrepresentasjoner (kodet i trestrukturen), er stivheten til de litt forskjellige strukturene mellom flere like trær ikke like begrensende lenger, siden manglene til ett tre kan "oppgjøres" av et annet. Ved å kombinere mange trær sammen får vi en skog.

Når det gjelder svaret på det første spørsmålet, vet vi allerede at det vil bli kodet i trebladene – men hva endrer seg når vi har mange trær i stedet for ett?

Hvis trærne kombineres for en klassifisering, vil resultatet bli definert av flertallet av svarene, dette kalles flertall; og i tilfelle av en regresjon, vil tallet gitt av hvert tre i skogen være gjennomsnitt.

Ensemble læring og modellensembler

Denne metoden er kjent som ensemble læring. Når du bruker ensemblelæring, kan du blande alle algoritmer sammen, så lenge du kan sikre at utdataene kan analyseres og kombineres med andre utdata (enten manuelt eller ved å bruke eksisterende biblioteker). Vanligvis setter du flere modeller av samme type sammen, for eksempel flere beslutningstrær, men du er ikke begrenset til bare å bli med i ensembler av samme modell.

Ensembling er en praktisk talt garantert måte å generalisere bedre til et problem, og å presse ut et lite ytelsesløft. I noen tilfeller gir ensembling av modeller en signifikant økning i prediktiv kraft, og noen ganger bare liten. Dette avhenger av datasettet du trener og evaluerer på, så vel som selve modellene.

Å slå sammen beslutningstrær gir utbytte signifikant ytelsesøkninger sammenlignet med individuelle trær. Denne tilnærmingen ble populær i forskningsmiljøene og anvendt maskinlæringsmiljøer, og var så vanlig at ensemblet av beslutningstrær ble i daglig tale kalt en skog, og den vanlige typen skog som ble opprettet (en skog av beslutningstrær på en tilfeldig undergruppe av funksjoner) populariserte navnet tilfeldige skoger.

Gitt omfattende bruk, har biblioteker som Scikit-Learn implementert innpakninger for RandomForestRegressors og RandomForestClassifiers, bygget på toppen av deres egne beslutningstreimplementeringer, for å la forskere unngå å bygge sine egne ensembler.

La oss dykke inn i tilfeldige skoger!

Hvordan fungerer Random Forest Algorithm?

Følgende er de grunnleggende trinnene som er involvert når du utfører den tilfeldige skogalgoritmen:

  1. Velg et antall tilfeldige poster, det kan være et hvilket som helst tall, for eksempel 4, 20, 76, 150 eller til og med 2.000 fra datasettet (kalt N poster). Antallet vil avhenge av bredden på datasettet, jo bredere, jo større N kan være. Det er her tilfeldig del i algoritmens navn kommer fra!
  2. Bygg et beslutningstre basert på disse N tilfeldige poster;
  3. I henhold til antall trær definert for algoritmen, eller antall trær i skogen, gjenta trinn 1 og 2. Dette genererer flere trær fra sett med tilfeldige dataposter;
  4. Etter trinn 3 kommer det siste trinnet, som er å forutsi resultatene:
    • Ved klassifisering: hvert tre i skogen vil forutsi kategorien som den nye rekorden tilhører. Deretter tildeles den nye rekorden kategorien som vinner flertallet.
    • Ved regresjon: hvert tre i skogen predikerer en verdi for den nye rekorden, og den endelige prediksjonsverdien vil bli beregnet ved å ta et gjennomsnitt av alle verdiene predikert av alle trærne i skogen.

Hvert tre som passer på et tilfeldig delsett av funksjoner vil nødvendigvis ikke ha kunnskap om noen andre funksjoner, noe som rettes opp ved ensembling, samtidig som beregningskostnadene holdes lavere.

Råd: Siden Random Forest bruker Decision Trees som en base, er det veldig nyttig å forstå hvordan Decision Trees fungerer og ha litt praksis med dem individuelt for å bygge en intuisjon på strukturen deres. Når du komponerer tilfeldige skoger, vil du sette verdier som maksimal dybde til et tre, minimum antall prøver som kreves for å være på en bladnode, kriteriene for å satse bestemme interne splittelser, osv. for å hjelpe ensemblet bedre å passe en datasett, og generaliser til nye punkter. I praksis vil du vanligvis bruke Random Forests, Gradient Boosting eller Extreme Gradient Boosting eller andre trebaserte metoder, så å ha et godt grep om hyperparametrene til et enkelt beslutningstre vil hjelpe med å bygge en sterk intuisjon for tuning av ensembler.

Med en intuisjon om hvordan trær fungerer, og en forståelse av tilfeldige skoger – det eneste som gjenstår er å øve på å bygge, trene og justere dem på data!

Bygge og trene tilfeldige skogmodeller med Scikit-Learn

Det var en grunn til at eksemplene som er brukt så langt involverer graviditet, oppholdsrom og kvinner.

I 2020 la forskere fra Bangladesh merke til at dødeligheten blant gravide fortsatt var svært høy, spesielt med tanke på de som bor på landsbygda. På grunn av det brukte de et IOT-overvåkingssystem for å analysere risikoen for mødres helse. IOT-systemet samlet inn data fra forskjellige sykehus, samfunnsklinikker og mødrehelsetjenester fra landlige områder i Bangladesh.

De innsamlede dataene ble deretter organisert i en kommaseparert-verdi-fil (csv) og lastet opp til UCIs maskinlæringsdepot.

Dette er dataene vi vil bruke for å øve og prøve å forstå om en gravid kvinne har en lav, medium or høy risiko for dødelighet.

Merknader: du kan laste ned datasettet her..

Bruke Random Forest for klassifisering

Siden vi ønsker å vite om kvinnen har en lav, medium or høy risiko for dødelighet betyr dette at vi skal utføre en klassifisering med tre klasser. Når et problem har mer enn to klasser, kalles det en multiklasse problem, i motsetning til en binære problem (der du vanligvis velger mellom to klasser 0 og 1).

I dette første eksemplet vil vi implementere en flerklasseklassifiseringsmodell med en Random Forest-klassifikator og Pythons Scikit-Learn.

Vi vil følge de vanlige maskinlæringstrinnene for å løse dette problemet, som er å laste inn biblioteker, lese dataene, se på sammendragsstatistikk og lage datavisualiseringer for å bedre forstå det. Deretter forbehandler og splitter dataene etterfulgt av generering, opplæring og evaluering av en modell.

Importerer biblioteker

Vi vil bruke Pandas til å lese dataene, Seaborn og Matplotlib for å visualisere dem, og NumPy for de flotte verktøymetodene:

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
Importerer datasettet

Følgende kode importerer datasettet og laster det inn i en python DataFrame:

dataset = pd.read_csv("../../datasets/random-forest/maternal_health_risk.csv")

For å se på de første fem linjene i dataene, utfører vi head() kommando:

dataset.head()

Dette gir utganger:

    Age SystolicBP  DiastolicBP BS      BodyTemp    HeartRate   RiskLevel
0   25  130         80          15.0    98.0        86          high risk
1   35  140         90          13.0    98.0        70          high risk
2   29  90          70          8.0     100.0       80          high risk
3   30  140         85          7.0     98.0        70          high risk
4   35  120         60          6.1     98.0        76          low risk

Her kan vi se alle attributtene som er samlet inn under forskningen.

  • Alder: aldre i år.
  • Systolisk BP: øvre verdi av blodtrykk i mmHg, en betydelig egenskap under graviditet.
  • Diastolisk BP: lavere verdi av blodtrykk i mmHg, en annen betydelig egenskap under graviditet.
  • BS: blodsukkernivåer i form av en molar konsentrasjon, mmol/L.
  • Hjertefrekvens: Hvilepuls i slag per minutt.
  • Risikonivå: risikonivå under graviditet.
  • BodyTemp: kroppstemperaturen.

Nå som vi forstår mer om hva som måles, kan vi se på hvilke typer data med info():

dataset.info()

Dette resulterer i:


RangeIndex: 1014 entries, 0 to 1013
Data columns (total 7 columns):
 #   Column       Non-Null Count  Dtype  
---  ------       --------------  -----  
 0   Age          1014 non-null   int64  
 1   SystolicBP   1014 non-null   int64  
 2   DiastolicBP  1014 non-null   int64  
 3   BS           1014 non-null   float64
 4   BodyTemp     1014 non-null   float64
 5   HeartRate    1014 non-null   int64  
 6   RiskLevel    1014 non-null   object 
dtypes: float64(2), int64(4), object(1)
memory usage: 55.6+ KB

Fra å se på RangeIndex linje, kan vi se at det er 1014 poster, og kolonnen Non-Null Count informerer om at dataene ikke mangler verdier. Dette betyr at vi ikke trenger å foreta noen behandling for manglende data!

Dtype kolonne, kan vi se typen til hver variabel. For tiden, float64 kolonner slik BS og BodyTemp har numeriske verdier som kan variere i et hvilket som helst område, for eksempel 15.0, 15.51, 15.76, 17.28, noe som gjør dem numerisk kontinuerlig (du kan alltid legge til en 0 til et flyttall, ad uendelig). På den annen side kan variabler som f.eks Age, SystolicBP, DiastolicBPog HeartRate er av typen int64, betyr dette at tallene kun endres av enheten, for eksempel 11, 12, 13, 14 – vi vil ikke ha en hjertefrekvens på 77.78, det er enten 77 eller 78 – det er numerisk diskret verdier. Og det har vi også RiskLevel med en object type, indikerer dette vanligvis at variabelen er en tekst, og vi må sannsynligvis transformere den til et tall. Siden risikonivået vokser fra lavt til høyt, er det en implisitt rekkefølge i kategoriene, dette indikerer at det er en kategorisk ordinal variabel.

Merknader: det er viktig å se på typen av hver data, og se om den gir mening i henhold til konteksten. For eksempel gir det ikke mening å ha halvparten av en pulsenhet, så dette betyr at interger-typen er tilstrekkelig for en diskret verdi. Når det ikke skjer, kan du endre type data med Pandas' astype() eiendom – df['column_name'].astype('type').

Etter å ha sett på datatyper, kan vi bruke describe() for å ta en topp på noen beskrivende statistikker, for eksempel gjennomsnittsverdiene for hver kolonne, standardavviket, kvantiler, minimums- og maksimumsdataverdier:

dataset.describe().T 

Koden ovenfor viser:

            count   mean        std         min     25%     50%     75%     max
Age         1014.0  29.871795   13.474386   10.0    19.0    26.0    39.0    70.0
SystolicBP  1014.0  113.198225  18.403913   70.0    100.0   120.0   120.0   160.0
DiastolicBP 1014.0  76.460552   13.885796   49.0    65.0    80.0    90.0    100.0
BS          1014.0  8.725986    3.293532    6.0     6.9     7.5     8.0     19.0
BodyTemp    1014.0  98.665089   1.371384    98.0    98.0    98.0    98.0    103.0
HeartRate   1014.0  74.301775   8.088702    7.0     70.0    76.0    80.0    90.0
RiskLevel   1014.0  0.867850    0.807353    0.0     0.0     1.0     2.0     2.0

Legg merke til at for de fleste kolonner bety verdier er langt fra standardavvik (std) – dette indikerer at dataene ikke nødvendigvis følger en veloppdragen statistisk fordeling. Hvis det gjorde det, ville det ha hjulpet modellen når den forutsi risikoen. Det som kan gjøres her er å forhåndsbehandle dataene for å gjøre dem mer representative som om de var data fra hele verdens befolkning, eller mer normalisert. Men, en fordel ved bruk av Random Forest-modeller for klassifisering, er at den iboende trestrukturen kan håndtere data som ikke er normalisert, når den først deler den med verdien i hvert trenivå for hver variabel.

Dessuten, fordi vi bruker trær og at den resulterende klassen vil bli oppnådd ved å stemme, sammenligner vi ikke iboende mellom forskjellige verdier, bare mellom samme typer verdier, så å justere funksjonene til samme skala er ikke nødvendig i dette tilfellet . Dette betyr at Random Forest-klassifiseringsmodellen er skala invariant, og du trenger ikke å utføre funksjonsskalering.

I dette tilfellet er trinnet i dataforbehandlingen vi kan ta å transformere det kategoriske RiskLevel kolonne til en numerisk.

Visualisere dataene

Før transformasjon RiskLevel, la oss også raskt visualisere dataene ved å se på kombinasjonene av punkter for hvert par funksjoner med et spredningsplott og hvordan punktene er fordelt ved å visualisere histogramkurven. For å gjøre det, vil vi bruke Seaborn's pairplot() som kombinerer begge tomtene. Den genererer begge plottene for hver funksjonskombinasjon og viser punktene fargekodet i henhold til deres risikonivå med hue eiendom:

g = sns.pairplot(dataset, hue='RiskLevel')
g.fig.suptitle("Scatterplot and histogram of pairs of variables color coded by risk level", 
               fontsize = 14, 
               y=1.05); 

Koden ovenfor genererer:

Definitiv guide til Random Forest Algorithm med Python og Scikit-Learn PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Når man ser på plottet, vil den ideelle situasjonen være å ha et klart skille mellom kurver og prikker. Som vi kan se, er de tre typene risikoklasser for det meste blandet sammen, siden trær internt trekker linjer når de avgrenser avstandene mellom punktene, kan vi anta at flere trær i skogen kan være i stand til å begrense flere rom og bedre klassifisere punktene.

Med den grunnleggende utforskende dataanalysen gjort, kan vi forhåndsbehandle RiskLevel kolonne.

Dataforbehandling for klassifisering

For å være sikker er det bare tre klasser av RiskLevel i våre data, og at ingen andre verdier er lagt til feil, kan vi bruke unique() for å vise kolonnens unike verdier:

dataset['RiskLevel'].unique()

Dette gir utganger:

array(['high risk', 'low risk', 'mid risk'], dtype=object)

Klassene blir sjekket, nå er neste trinn å transformere hver verdi til et tall. Siden det er en rekkefølge mellom klassifikasjoner, kan vi bruke verdiene 0, 1 og 2 for å betegne lav, medium og høy risikoer. Det er mange måter å endre kolonneverdiene på, etter Python enkelt er bedre enn komplekst motto, vi vil bruke .replace() metode, og bare erstatte dem med deres heltallsrepresentasjoner:

dataset['RiskLevel'] = dataset['RiskLevel'].replace('low risk', 0).replace('mid risk', 1).replace('high risk', 2)

Etter å ha erstattet verdiene, kan vi dele dataene inn i det som skal brukes til opplæring av modellen, den egenskaper or X, og det vi ønsker å forutsi, den etiketter or y:

y = dataset['RiskLevel']
X = dataset.drop(['RiskLevel'], axis=1)

Når X og y settene er klare, vi kan bruke Scikit-Learn's train_test_split() metode for å dele dem videre inn i tog- og testsett:

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.2, 
                                                    random_state=SEED)

Råd: husk å bruke et tilfeldig tilstandsfrø hvis du vil gjøre resultatet reproduserbart. Vi har brukt et tilfeldig tilstandsfrø slik at du kan gjengi de samme resultatene som fra veiledningen.

Her bruker vi 20 % av dataene til testing og 80 % til trening.

Trening av en RandomForestClassifier

Sjekk ut vår praktiske, praktiske guide for å lære Git, med beste praksis, bransjeaksepterte standarder og inkludert jukseark. Slutt å google Git-kommandoer og faktisk lære den!

Scikit-Learn implementerte ensembler under sklearn.ensemble modul. Et ensemble av beslutningstrær som brukes til klassifisering, der det blir tatt flertall, implementeres som RandomForestClassifier.

Når vi har toget og testsettene, kan vi importere RandomForestClassifier klasse og lage modellen. For å starte, la oss lage en skog med tre trær, ved å sette n_estimators parameter som 3, og med hvert tre som har tre nivåer, ved innstilling max_depthtil 2:

from sklearn.ensemble import RandomForestClassifier

rfc = RandomForestClassifier(n_estimators=3, 
                             max_depth=2,
                             random_state=SEED)

OBS: Standardverdien for n_estimators is 100. Dette øker prediktiv kraft og generalisering av ensemblet, men vi lager en mindre for å gjøre det lettere å visualisere og inspisere det. Med bare 3 trær – vi kan visualisere og inspisere dem manuelt å bygge videre vår intuisjon av både de enkelte trærne, og deres medavhengighet. Det samme gjelder for max_depth, som er None, noe som betyr at trærne kan bli dypere og dypere for å passe til dataene etter behov.

For å tilpasse modellen rundt dataene – kaller vi fit() metode, ved å legge inn treningsfunksjonene og etikettene:


rfc.fit(X_train, y_train)

y_pred = rfc.predict(X_test)

Vi kan nå sammenligne de forutsagte etikettene med de virkelige etikettene for å evaluere hvor godt modellen gjorde det! Før vi evaluerer modellen, la oss ta en titt på ensemblet.

For å se litt dypere inn i modellen kan vi visualisere hvert av trærne og hvordan de deler dataene. Dette kan gjøres ved å bruke tree modul innebygd i Scikit-Learn, og går deretter gjennom hver av estimatorene i ensemblet:


from sklearn import tree

features = X.columns.values 
classes = ['0', '1', '2'] 



for estimator in rfc.estimators_:
    print(estimator)
    plt.figure(figsize=(12,6))
    tree.plot_tree(estimator,
                   feature_names=features,
                   class_names=classes,
                   fontsize=8, 
                   filled=True, 
                   rounded=True)
    plt.show()

Koden ovenfor viser treplottene:

Definitiv guide til Random Forest Algorithm med Python og Scikit-Learn PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.
Definitiv guide til Random Forest Algorithm med Python og Scikit-Learn PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.
Definitiv guide til Random Forest Algorithm med Python og Scikit-Learn PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Legg merke til hvordan de tre trærne er forskjellige. Den første starter med BS funksjon, den andre med DiastolicBP, og den tredje med BS en gang til. Selv om den tredje ser på et annet antall prøver. På høyre gren bestemmer også de to første trærne å bruke Age på bladnivå, mens det tredje treet slutter med BS trekk. Med bare tre estimatorer er det tydelig hvordan oppskalering gir en rik, mangfoldig representasjon av kunnskapen som med hell kan settes sammen til en svært nøyaktig modell.

Jo flere trær i skogen, jo mer mangfoldig kan modellen være. Det er et poeng med å avta avkastningen, men siden mange trær passer på en tilfeldig undergruppe av funksjoner, vil det være en god del lignende trær som ikke tilbyr mye mangfold i ensemblet, og som vil begynne å ha for mye stemmerett og skjev ensemblet for å være overfitt på treningsdatasettet, noe som skader generaliseringen til valideringssettet.

Det ble gjort en hypotese tidligere om å ha flere trær, og hvordan det kunne forbedre modellresultatene. La oss ta en titt på resultatene, generere en ny modell og se om hipotesen holder!

Evaluering av RandomForestClassifier

Scikit-Learn gjør det enkelt å lage grunnlinjer ved å tilby en DummyClassifier, som gir spådommer uten å bruke inndatafunksjonene (helt tilfeldige utganger). Hvis modellen din er bedre enn DummyClassifier, noen læring skjer! For å maksimere læringen – kan du teste ut ulike hyperparametre automatisk ved å bruke en RandomizedSearchCV or GridSearchCV. I tillegg til å ha en grunnlinje, kan du evaluere modellens ytelse fra linsen til flere beregninger.

Noen tradisjonelle klassifiseringsmetrikker som kan brukes til å evaluere algoritmen er presisjon, gjenkalling, f1-score, nøyaktighet og forvirringsmatrise. Her er en kort forklaring på hver av dem:

  1. Precision: når målet vårt er å forstå hvilke korrekte prediksjonsverdier som ble ansett som riktige av klassifisereren vår. Presisjon vil dele de sanne positive verdiene med prøvene som ble spådd som positive;

$$
presisjon = frac{tekst{true positives}}{text{true positives} + text{false positives}}
$$

  1. Husker: vanligvis beregnet sammen med presisjon for å forstå hvor mange av de sanne positive som ble identifisert av klassifisereren vår. Tilbakekallingen beregnes ved å dele de sanne positive med alt som burde vært spådd som positivt.

$$
recall = frac{tekst{true positives}}{text{true positives} + text{false negatives}}
$$

  1. F1-poengsum: er den balanserte eller harmonisk middel av presisjon og tilbakekalling. Den laveste verdien er 0 og den høyeste er 1. Når f1-score er lik 1, betyr det at alle klasser ble korrekt spådd – dette er en svært vanskelig poengsum å oppnå med ekte data (unntak finnes nesten alltid).

$$
tekst{f1-score} = 2* frac{tekst{presisjon} * tekst{recall}}{tekst{precision} + tekst{recall}}
$$

  1. Forvirringsmatrise: når vi trenger å vite hvor mange prøver vi fikk rett eller galt for hver klasse. Verdiene som var korrekte og korrekt forutsagt kalles ekte positive, de som ble spådd som positive, men som ikke var positive, kalles falske positive. Den samme nomenklaturen til ekte negativer og falske negativer brukes for negative verdier;

  2. Nøyaktighet: beskriver hvor mange spådommer klassifiseringen vår fikk riktige. Den laveste nøyaktighetsverdien er 0 og den høyeste er 1. Denne verdien multipliseres vanligvis med 100 for å få en prosentandel:

$$
nøyaktighet = frac{tekst{antall korrekte spådommer}}{tekst{totalt antall spådommer}}
$$

OBS: Det er praktisk talt umulig å oppnå 100 % nøyaktighet på noen reelle data du ønsker å bruke maskinlæring på. Hvis du ser en klassifisering av 100 % nøyaktighet, eller til og med et resultat på nesten 100 % – vær skeptisk og utfør en evaluering. En vanlig årsak til disse problemene er datalekkasje (lekkasje av en del av treningstesten inn i et testsett, direkte eller indirekte). Det er ingen konsensus om hva "en god nøyaktighet er", først og fremst fordi det avhenger av dataene dine - noen ganger vil en 70% nøyaktighet være høy! Noen ganger vil det være veldig lav nøyaktighet. Generelt sett, over 70 % er tilstrekkelig for mange modeller, men dette er opp til domeneforskeren å fastslå.

Du kan kjøre følgende skript for å importere de nødvendige bibliotekene og se på resultatene:

from sklearn.metrics import classification_report, confusion_matrix

cm = confusion_matrix(y_test, y_pred)
sns.heatmap(cm, annot=True, fmt='d').set_title('Maternal risks confusion matrix (0 = low risk, 1 = medium risk, 2 = high risk)')

print(classification_report(y_test,y_pred))

Utgangen vil se ut slik:

                precision    recall  f1-score   support

           0       0.53      0.89      0.66        80
           1       0.57      0.17      0.26        76
           2       0.74      0.72      0.73        47

    accuracy                           0.58       203
   macro avg       0.61      0.59      0.55       203
weighted avg       0.59      0.58      0.53       203

Definitiv guide til Random Forest Algorithm med Python og Scikit-Learn PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

I klassifiseringsrapporten, observer at tilbakekallingen er høy, 0.89 for klasse 0, både presisjon og tilbakekalling er høy for klasse 2, 0.74, 0.72 – og for klasse 1 er de lave, spesielt tilbakekallingen på 0.17 og en presisjon på 0.57 . Forholdet mellom tilbakekalling og presisjon for alle tre klassene individuelt er fanget i F1 score, som er det harmoniske gjennomsnittet mellom gjenkalling og presisjon – modellen gjør det okay for klasse 0, ganske dårlig for klasse 1 og grei for klasse 2.

Modellen har det veldig vanskelig med å identifisere tilfeller med middels risiko.

Nøyaktigheten oppnådd av vår tilfeldige skogklassifiserer med bare 3 trær er av 0.58 (58%) – dette betyr at den får litt mer enn halvparten av resultatene riktig. Dette er en lav nøyaktighet, og kan kanskje forbedres ved å legge til flere trær.

Ved å se på forvirringsmatrisen kan vi se at de fleste feilene er når man klassifiserer 52 registreringer av middels risiko som lav risiko, noe som gir ytterligere innsikt i den lave tilbakekallingen av klasse 1. Det er partisk mot å klassifisere pasienter med middels risiko som lav- risikopasienter.

En annen ting som kan kontrolleres for å generere enda mer innsikt er hvilke funksjoner som klassifiseres mest i betraktning når de forutsier. Dette er et viktig skritt å ta for forklarbare maskinlæringssystemer, og hjelper til med å identifisere og redusere skjevheter i modeller.

For å se det kan vi få tilgang til feature_importances_ egenskapen til klassifisereren. Dette vil gi oss en liste over prosenter, slik at vi også kan få tilgang til feature_names_in_ egenskap for å få navnet på hver funksjon, organisere dem i en dataramme, sortere dem fra høyeste til laveste, og plotte resultatet:


features_df = pd.DataFrame({'features': rfc.feature_names_in_, 'importances': rfc.feature_importances_ })


features_df_sorted = features_df.sort_values(by='importances', ascending=False)


g = sns.barplot(data=features_df_sorted, x='importances', y ='features', palette="rocket")
sns.despine(bottom = True, left = True)
g.set_title('Feature importances')
g.set(xlabel=None)
g.set(ylabel=None)
g.set(xticks=[])
for value in g.containers:
    g.bar_label(value, padding=2)

Definitiv guide til Random Forest Algorithm med Python og Scikit-Learn PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Legg merke til hvordan klassifisereren stort sett vurderer blodsukker, så litt av det diastoliske trykket, kroppstemperaturen og bare litt alder for å ta en avgjørelse, dette kan også ha å gjøre med den lave tilbakekallingen på klasse 1, kanskje dataene med middels risiko har å gjøre med funksjoner som ikke blir tatt mye i betraktning av modellen. Du kan prøve å leke mer med funksjonsviktigheter for å undersøke dette, og se om endringer på modellen påvirker funksjonene som brukes, også om det er en signifikant sammenheng mellom noen av funksjonene og de predikerte klassene.

Det er endelig på tide å generere en ny modell med flere trær for å se hvordan det påvirker resultatene. La oss lage rfc_ skog med 900 trær, 8 nivåer og samme frø. Vil resultatene bli bedre?

rfc_ = RandomForestClassifier(n_estimators=900, 
                             max_depth=7,
                             random_state=SEED)
rfc_.fit(X_train, y_train)
y_pred = rfc_.predict(X_test)

Beregning og visning av beregninger:

cm_ = confusion_matrix(y_test, y_pred)
sns.heatmap(cm_, annot=True, fmt='d').set_title('Maternal risks confusion matrix (0 = low risk, 1 = medium risk, 2 = high risk) for 900 trees with 8 levels')

print(classification_report(y_test,y_pred))

Dette gir utganger:

                precision    recall  f1-score   support

           0       0.68      0.86      0.76        80
           1       0.75      0.58      0.65        76
           2       0.90      0.81      0.85        47

    accuracy                           0.74       203
   macro avg       0.78      0.75      0.75       203
weighted avg       0.76      0.74      0.74       203

Definitiv guide til Random Forest Algorithm med Python og Scikit-Learn PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Dette viser hvordan å legge til flere trær, og mer spesialiserte trær (høyere nivåer), har forbedret våre beregninger. Vi har fortsatt lav tilbakekalling for klasse 1, men nøyaktigheten er nå på 74 %. F1-skåren ved klassifisering av høyrisikotilfeller er på 0.85, noe som betyr at høyrisikotilfeller nå lettere kan identifiseres sammenlignet med 0.73 i forrige modell!

I et daglig prosjekt kan det være viktigere å identifisere tilfeller med høy risiko, for eksempel med en beregning som ligner på presisjon, som også er kjent som følsomhet i statistikk. Prøv å finjustere noen av modellparametrene og observer resultatene.

Til nå har vi fått en helhetlig forståelse av hvordan Random Forest kan brukes til å klassifisere data – i neste avsnitt kan vi bruke samme datasett på en annen måte for å se hvordan den samme modellen predikerer verdier med regresjon.

Bruke tilfeldige skoger for regresjon

I denne delen skal vi studere hvordan en Random Forest-algoritme kan brukes til å løse regresjonsproblemer ved hjelp av Scikit-Learn. Trinnene som følges for å implementere denne algoritmen er nesten identiske med trinnene som utføres for klassifisering, i tillegg til type modell og type predikerte data – som nå vil være kontinuerlige verdier – det er bare én forskjell i dataforberedelsen.

Siden regresjon er gjort for numeriske verdier – la oss velge en numerisk verdi fra datasettet. Vi har sett at blodsukkeret var viktig i klassifiseringen, så det bør være forutsigbart basert på andre funksjoner (siden hvis det korrelerer med en funksjon, korrelerer den funksjonen også med den).

Etter hva vi har gjort for klassifisering, la oss først importere bibliotekene og det samme datasettet. Hvis du allerede har gjort dette for klassifiseringsmodellen, kan du hoppe over denne delen og gå direkte til å forberede data for trening.

Importere biblioteker og data
import pandas as pd
import numpy as np
import maplotlib.pyplot as plt
import seaborn as sns

dataset = pd.read_csv("../../datasets/random-forest/maternal_health_risk.csv")
Dataforbehandling for regresjon

Dette er en regresjonsoppgave, så i stedet for å forutsi klasser, kan vi forutsi en av de numeriske kolonnene i datasettet. I dette eksemplet er BS kolonne vil bli forutsagt. Dette betyr y data vil inneholde blodsukkerdataog X data vil inneholde alle funksjonene foruten blodsukkeret. Etter å ha separert X og y data, kan vi dele toget og testsettene:

from sklearn.model_selection import train_test_split

SEED = 42

y = dataset['BS']
X = dataset.drop(['BS'], axis=1) 

X_train, X_test, y_train, y_test = train_test_split(X, y, 
                                                    test_size=0.2, 
                                                    random_state=SEED)
Trening av en RandomForestRegressor

Nå som vi har skalert datasettet vårt, er det på tide å trene algoritmen vår til å løse dette regresjonsproblemet, for å endre det litt opp – vi lager en modell med 20 trær i skogen og hver med 4 nivåer. For å gjøre det, kan du utføre følgende kode:

from sklearn.ensemble import RandomForestRegressor

rfr = RandomForestRegressor(n_estimators=20, 
                            max_depth=3, 
                            random_state=SEED)

rfr.fit(X_train, y_train)
y_pred = rfr.predict(X_test)

Du kan finne detaljer for alle parametrene til RandomForestRegressor i den offisielle dokumentasjonen.

Siden det å plotte og se på 20 trær vil kreve litt tid og dedikasjon, kan vi plotte bare det første som ser på hvordan det er forskjellig fra klassifiseringstreet:

from sklearn import tree

features = X.columns

first_tree = rfr.estimators_[0]

plt.figure(figsize=(15,6))
tree.plot_tree(first_tree,
               feature_names=features,
               fontsize=8, 
               filled=True, 
               rounded=True);

Definitiv guide til Random Forest Algorithm med Python og Scikit-Learn PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Legg merke til at regresjonstreet allerede har en verdi tilordnet dataene som faller på hver node. Dette er verdiene som blir gjennomsnittet når du kombinerer de 20 trærne. Etter det vi har gjort med klassifisering, kan du også plotte funksjonsviktigheter for å se hvilke variabler regresjonsmodellen tar mer hensyn til ved beregning av verdier.

Det er på tide å gå videre til det siste og siste trinnet når du skal løse et maskinlæringsproblem og evaluere ytelsen til algoritmen!

Evaluering av en RandomForestRegressor

For regresjonsproblemer er beregningene som brukes til å evaluere en algoritme gjennomsnittlig absolutt feil (MAE), gjennomsnittlig kvadratfeil (MSE) og rotmiddelkvadratfeil (RMSE).

  1. Gjennomsnittlig absolutt feil (MAE): når vi trekker de predikerte verdiene fra de faktiske verdiene, oppnår feilene, summerer vi de absolutte verdiene til disse feilene og får deres gjennomsnitt. Denne beregningen gir en forestilling om den totale feilen for hver prediksjon av modellen, jo mindre (nærmere 0) jo bedre.

$$
mae = (frac{1}{n})sum_{i=1}^{n}venstre | Faktisk – spådd rett |
$$

OBS: Du kan også støte på y og ŷ notasjon i ligningene. De y refererer til de faktiske verdiene og ŷ til de forutsagte verdiene.

  1. Mean Squared Error (MSE): den ligner på MAE-metrikken, men den kvadrerer de absolutte verdiene til feilene. Også, som med MAE, jo mindre, eller nærmere 0, jo bedre. MSE-verdien er kvadratisk for å gjøre store feil enda større. En ting å være oppmerksom på, det er at det vanligvis er vanskelig å tolke på grunn av størrelsen på verdiene og det faktum at de ikke er i samme skala av dataene.

$$
mse = sum_{i=1}^{D}(Faktisk – anslått)^2
$$

  1. Root Mean Squared Error (RMSE): prøver å løse tolkningsproblemet som er reist med MSE ved å få kvadratroten av dens endelige verdi, for å skalere den tilbake til de samme enhetene av dataene. Det er lettere å tolke og bra når vi skal vise eller vise den faktiske verdien av dataene med feilen. Den viser hvor mye dataene kan variere, så hvis vi har en RMSE på 4.35, kan modellen vår gjøre en feil enten fordi den la til 4.35 til den faktiske verdien, eller trengte 4.35 for å komme til den faktiske verdien. Jo nærmere 0, jo bedre også.

$$
rmse = sqrt{ sum_{i=1}^{D}(Faktisk – anslått)^2}
$$

Vi kan bruke hvilken som helst av disse tre beregningene til sammenligne modeller (hvis vi trenger å velge en). Vi kan også sammenligne den samme regresjonsmodellen med forskjellige argumentverdier eller med forskjellige data og deretter vurdere evalueringsverdiene. Dette er kjent som hyperparameterinnstilling – justere hyperparametrene som påvirker en læringsalgoritme og observere resultatene.

Når du velger mellom modeller, gir de med de minste feilene vanligvis bedre resultater. Ved overvåking av modeller, hvis beregningene ble dårligere, var en tidligere versjon av modellen bedre, eller det var en betydelig endring i dataene for at modellen skulle prestere dårligere enn den presterte.

Du kan bruke følgende kode for å finne disse verdiene:

from sklearn.metrics import mean_absolute_error, mean_squared_error

print('Mean Absolute Error:', mean_absolute_error(y_test, y_pred))
print('Mean Squared Error:', mean_squared_error(y_test, y_pred))
print('Root Mean Squared Error:', np.sqrt(mean_squared_error(y_test, y_pred)))

Resultatet skal være:

Mean Absolute Error: 1.127893702896059
Mean Squared Error: 3.0802988503933326
Root Mean Squared Error: 1.755078018320933

Med 20 trær er rotmiddelkvadratfeilen 1.75, noe som er lavt, men likevel – ved å øke antallet trær og eksperimentere med de andre parameterne, kan denne feilen sannsynligvis bli enda mindre.

Fordeler med å bruke Random Forest

Som med enhver algoritme, er det fordeler og ulemper ved å bruke den. I de neste to delene skal vi ta en titt på fordeler og ulemper ved å bruke tilfeldig skog for klassifisering og regresjon.

  1. Den tilfeldige skogalgoritmen er ikke partisk, siden det er flere trær og hvert tre er trent på et tilfeldig delsett av data. I utgangspunktet er den tilfeldige skogalgoritmen avhengig av kraften til «mengden»; derfor reduseres den generelle graden av skjevhet til algoritmen.
  2. Denne algoritmen er veldig stabil. Selv om et nytt datapunkt introduseres i datasettet, påvirkes ikke den generelle algoritmen mye siden nye data kan påvirke ett tre, men det er veldig vanskelig for det å påvirke alle trærne.
  3. Den tilfeldige skogalgoritmen fungerer bra når du har både kategoriske og numeriske funksjoner.
  4. Den tilfeldige skogalgoritmen fungerer også bra når data mangler verdier eller ikke er skalert.

Ulemper ved å bruke Random Forest

  1. Den største ulempen med tilfeldige skoger ligger i deres kompleksitet. De krever mye mer beregningsressurser, på grunn av det store antallet beslutningstrær som er satt sammen, når de trener store ensembler. Skjønt – med moderne maskinvare tar trening selv en stor tilfeldig skog ikke mye tid.

Gå videre – Håndholdt ende-til-ende-prosjekt

Din nysgjerrige natur gjør at du ønsker å gå lenger? Vi anbefaler å sjekke ut vår Veiledet prosjekt: "Hands-on husprisprediksjon – maskinlæring i Python".

Definitiv guide til Random Forest Algorithm med Python og Scikit-Learn PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

I dette guidede prosjektet – vil du lære hvordan du bygger kraftige tradisjonelle maskinlæringsmodeller så vel som dyplæringsmodeller, bruker Ensemble Learning og trener meta-elever til å forutsi boligpriser fra en pose med Scikit-Learn og Keras-modeller.

Ved å bruke Keras, deep learning API bygget på toppen av Tensorflow, vil vi eksperimentere med arkitekturer, bygge et ensemble av stablede modeller og trene en meta-lærer nevrale nettverk (nivå-1-modell) for å finne ut prisen på et hus.

Dyplæring er fantastisk – men før du tyr til det, anbefales det også å prøve å løse problemet med enklere teknikker, for eksempel med grunn læring algoritmer. Vår baseline ytelse vil være basert på en Tilfeldig skogregresjon algoritme. I tillegg – vi vil utforske å lage ensembler av modeller gjennom Scikit-Learn via teknikker som posing og stemmegivning.

Dette er et ende-til-ende-prosjekt, og som alle maskinlæringsprosjekter starter vi med – med Utforskende dataanalyse, Etterfulgt av Forbehandling av data og endelig Bygge grunt og Dyplæringsmodeller for å passe til dataene vi har utforsket og renset tidligere.

Tidstempel:

Mer fra Stackabuse