Maskinlæring med Spark MLlib

1. Oversikt

I denne veiledningen vil vi forstå hvordan vi kan utnytte Apache Spark MLlib til å utvikle maskinlæringsprodukter. Vi utvikler et enkelt maskinlæringsprodukt med Spark MLlib for å demonstrere kjernekonseptene.

2. En kort grunning til maskinlæring

Maskinlæring er del av en bredere paraply kjent som kunstig intelligens. Maskinlæring refererer til studie av statistiske modeller for å løse spesifikke problemer med mønstre og slutninger. Disse modellene er "trent" for det spesifikke problemet ved hjelp av treningsdata hentet fra problemområdet.

Vi får se hva denne definisjonen innebærer når vi tar eksemplet vårt.

2.1. Maskinlæringskategorier

Vi kan bredt kategorisere maskinlæring i overvåket og uten tilsyn kategorier basert på tilnærmingen. Det er andre kategorier også, men vi holder oss til disse to:

  • Veiledet læring fungerer med et sett med data som inneholder både inngangene og ønsket utgang - for eksempel et datasett som inneholder forskjellige egenskaper ved en eiendom og forventede leieinntekter. Veiledet læring er videre delt inn i to brede underkategorier kalt klassifisering og regresjon:
    • Klassifiseringsalgoritmer er relatert til kategorisk produksjon, som om en eiendom er okkupert eller ikke
    • Regresjonsalgoritmer er relatert til et kontinuerlig utgangsområde, som verdien på en eiendom
  • Uovervåket læring derimot, fungerer med et datasett som bare har inngangsverdier. Det fungerer ved å prøve å identifisere den iboende strukturen i inngangsdataene. For eksempel å finne forskjellige typer forbrukere gjennom et datasett med forbruksatferd.

2.2. Maskinlæring arbeidsflyt

Maskinlæring er virkelig et tverrfaglig studieområde. Det krever kunnskap om forretningsområdet, statistikk, sannsynlighet, lineær algebra og programmering. Siden dette helt klart kan bli overveldende, det er best å nærme seg dette på en ordnet måte, det vi vanligvis kaller en arbeidsflyt for maskinlæring:

Som vi kan se, bør hvert maskinlæringsprosjekt starte med en klart definert problemstilling. Dette bør følges av en rekke trinn relatert til data som potensielt kan svare på problemet.

Så velger vi vanligvis en modell som ser på problemets art. Dette etterfølges av en serie med modellopplæring og validering, som er kjent som modelljustering. Til slutt tester vi modellen på tidligere usett data og distribuerer den til produksjon hvis den er tilfredsstillende.

3. Hva er gnist MLlib?

Spark MLlib er en modul på toppen av Spark Core som gir maskinlæringsprimitiver som APIer. Maskinlæring håndterer vanligvis en stor mengde data for modellopplæring.

Basis databehandlingsrammeverk fra Spark er en stor fordel. På toppen av dette gir MLlib det meste av de populære maskinlærings- og statistiske algoritmene. Dette forenkler oppgaven med å jobbe med et stort maskinlæringsprosjekt.

4. Maskinlæring med MLlib

Vi har nå nok kontekst om maskinlæring og hvordan MLlib kan hjelpe i dette arbeidet. La oss komme i gang med vårt grunnleggende eksempel på å implementere et maskinlæringsprosjekt med Spark MLlib.

Hvis vi husker fra diskusjonen om arbeidsflyt for maskinlæring, bør vi starte med en problemstilling og deretter gå videre til data. Heldigvis for oss velger vi “hei verden” av maskinlæring, Iris datasett. Dette er et multivariat merket datasett, som består av lengde og bredde på kelkblad og kronblad av forskjellige arter av Iris.

Dette gir vårt problemmål: kan vi forutsi arten av en Iris ut fra lengden og bredden på sepal og kronblad?

4.1. Angi avhengighet

Først må vi definere følgende avhengighet i Maven for å trekke relevante biblioteker:

 org.apache.spark spark-mllib_2.11 2.4.3 gitt 

Og vi må initialisere SparkContext for å fungere med Spark APIer:

SparkConf conf = new SparkConf () .setAppName ("Main") .setMaster ("local [2]"); JavaSparkContext sc = ny JavaSparkContext (conf);

4.2. Laster inn dataene

Først og fremst bør vi laste ned dataene, som er tilgjengelige som en tekstfil i CSV-format. Da må vi laste disse dataene i Spark:

String dataFile = "data \ iris.data"; JavaRDD data = sc.textFile (dataFile);

Spark MLlib tilbyr flere datatyper, både lokale og distribuerte, for å representere inngangsdataene og tilhørende etiketter. Den enkleste av datatypene er Vector:

JavaRDD inputData = data .map (line -> {String [] parts = line.split (","); double [] v = new double [parts.length - 1]; for (int i = 0; i <parts .length - 1; i ++) {v [i] = Double.parseDouble (parts [i]);} return Vectors.dense (v);});

Merk at vi bare har tatt med innspillingsfunksjonene her, for det meste for å utføre statistisk analyse.

Et opplæringseksempel består vanligvis av flere innspillingsfunksjoner og en etikett, representert av klassen MerketPoint:

Kartkart = nytt HashMap (); map.put ("Iris-setosa", 0); map.put ("Iris-versicolor", 1); map.put ("Iris-virginica", 2); JavaRDD labelData = data .map (line -> {String [] parts = line.split (","); double [] v = new double [parts.length - 1]; for (int i = 0; i <parts .length - 1; i ++) {v [i] = Double.parseDouble (parts [i]);} returner nye LabeledPoint (map.get (parts [parts.length - 1]), Vectors.dense (v)); });

Produksjonsetiketten vår i datasettet er tekstlig, noe som betyr arten av Iris. For å mate dette inn i en maskinlæringsmodell, må vi konvertere dette til numeriske verdier.

4.3. Utforskende dataanalyse

Utforskende dataanalyse innebærer å analysere tilgjengelige data. Nå, maskinlæringsalgoritmer er følsomme overfor datakvalitetDerfor har data av høyere kvalitet bedre muligheter for å levere ønsket resultat.

Typiske analysemål er å fjerne avvik og oppdage mønstre. Dette strømmer til og med inn i de kritiske trinnene i funksjonsteknikk for å komme til nyttige funksjoner fra tilgjengelig data.

Datasettet vårt, i dette eksemplet, er lite og velformet. Derfor trenger vi ikke hengi oss til mye dataanalyse. Spark MLlib er imidlertid utstyrt med APIer for å gi en god innsikt.

La oss begynne med noen enkle statistiske analyser:

MultivariateStatisticalSummary-sammendrag = Statistics.colStats (inputData.rdd ()); System.out.println ("Sammendrag gjennomsnitt:"); System.out.println (summary.mean ()); System.out.println ("Sammendrag avvik:"); System.out.println (oppsummering.varians ()); System.out.println ("Sammendrag ikke-null:"); System.out.println (summary.numNonzeros ());

Her observerer vi gjennomsnittet og variansen til funksjonene vi har. Dette er nyttig for å avgjøre om vi trenger å utføre normalisering av funksjoner. Det er nyttig å ha alle funksjonene på en lignende skala. Vi tar også et notat av verdier som ikke er null, noe som kan påvirke modellytelsen negativt.

Her er utdataene for inngangsdataene våre:

Sammendrag Gjennomsnitt: [5.843333333333332,3.0540000000000003,3.7586666666666666,1.198666666666666668] Sammendrag Variasjon: [0.6856935123042509,0.18800402684563744,3.113179418344516,0.5824143176733783] Sammendrag Ikke-null.0,150,150,150,050

En annen viktig beregning å analysere er sammenhengen mellom funksjonene i inngangsdataene:

Matrix correlMatrix = Statistics.corr (inputData.rdd (), "pearson"); System.out.println ("Korrelasjonsmatrise:"); System.out.println (correlMatrix.toString ());

EN høy korrelasjon mellom to funksjoner antyder at de ikke legger til noen inkrementell verdi og en av dem kan droppes. Slik er funksjonene våre korrelert:

Korrelasjonsmatrise: 1,0 -0,10936924995064387 0,8717541573048727 0,8179536333691672 -0,10936924995064387 1,0 -0,4205160964011671 -0,3565440896138163 0,8717541573048727 -0,4205160964011671 1,096 07066706

4.4. Splitte dataene

Hvis vi husker diskusjonen vår om arbeidsflyt for maskinlæring, involverer det flere iterasjoner av modellopplæring og validering etterfulgt av endelig testing.

For at dette skal skje, vi må dele opplæringsdataene våre i opplæring, validering og testsett. For å gjøre det enkelt, hopper vi over valideringsdelen. Så la oss dele opp dataene våre i opplæring og testsett:

JavaRDD [] splits = parsedData.randomSplit (ny dobbel [] {0,8, 0,2}, 11 L); JavaRDD trainingData = splitt [0]; JavaRDD testData = splitt [1];

4.5. Modellopplæring

Så vi har nådd et stadium der vi har analysert og forberedt datasettet vårt. Alt som er igjen er å mate dette inn i en modell og starte magien! Vel, lettere sagt enn gjort. Vi må velge en passende algoritme for problemet vårt - husk de forskjellige maskinlæringskategoriene vi snakket om tidligere.

Det er ikke vanskelig å forstå det vårt problem passer inn i klassifisering innen kategorien overvåket. Nå er det ganske mange algoritmer tilgjengelig for bruk under denne kategorien.

Den enkleste av dem er Logistisk regresjon (la ordet regresjon ikke forvirre oss; det er tross alt en klassifiseringsalgoritme):

LogisticRegressionModel model = new LogisticRegressionWithLBFGS () .setNumClasses (3) .run (trainingData.rdd ());

Her bruker vi en tre-klasse begrenset minne BFGS-basert klassifisering. Detaljene i denne algoritmen ligger utenfor omfanget av denne opplæringen, men dette er en av de mest brukte.

4.6. Modellevaluering

Husk at modellopplæring innebærer flere iterasjoner, men for enkelhets skyld har vi nettopp brukt et enkelt pass her. Nå som vi har trent modellen vår, er det på tide å teste dette på testdatasettet:

JavaPairRDD predictionAndLabels = testData .mapToPair (p -> new Tuple2 (model.predict (p.features ()), p.label ())); MulticlassMetrics metrics = new MulticlassMetrics (predictionAndLabels.rdd ()); dobbel nøyaktighet = beregninger. nøyaktighet (); System.out.println ("Modellnøyaktighet på testdata:" + nøyaktighet);

Nå, hvordan måler vi effektiviteten til en modell? Det er flere beregninger som vi kan bruke, men noe av det enkleste er Nøyaktighet. Enkelt sagt er nøyaktighet et forhold mellom riktig antall spådommer og totalt antall spådommer. Her er hva vi kan oppnå i ett løp av modellen vår:

Modellnøyaktighet på testdata: 0,9310344827586207

Merk at dette vil variere litt fra løp til løp på grunn av algoritmens stokastiske natur.

Imidlertid er nøyaktighet ikke veldig effektiv beregning i noen problemdomener. Annen mer sofistikerte beregninger er Precision and Recall (F1 Score), ROC Curve og Confusion Matrix.

4.7. Lagre og laste inn modellen

Til slutt må vi ofte lagre den opplærte modellen i filsystemet og laste den for prediksjon på produksjonsdata. Dette er trivielt i Spark:

model.save (sc, "modell \ logistisk-regresjon"); LogisticRegressionModel sameModel = LogisticRegressionModel .load (sc, "model \ logistic-regression"); Vector newData = Vectors.dense (ny dobbel [] {1,1,1,1}); dobbel prediksjon = sameModel.predict (newData); System.out.println ("Model Prediction on New Data =" + prediction);

Så vi lagrer modellen i filsystemet og laster den tilbake. Etter lasting kan modellen straks brukes til å forutsi utdata på nye data. Her er et eksempel på prediksjon på tilfeldige nye data:

Model Prediction on New Data = 2.0

5. Utover det primitive eksemplet

Mens eksemplet vi gikk gjennom dekker arbeidsflyten til et maskinlæringsprosjekt i stor grad, etterlater det mange subtile og viktige punkter. Selv om det ikke er mulig å diskutere dem i detalj her, kan vi absolutt gå gjennom noen av de viktige.

Spark MLlib har gjennom sine API-er omfattende støtte innen alle disse områdene.

5.1. Modellvalg

Modellvalg er ofte en av de komplekse og kritiske oppgavene. Å trene en modell er en involvert prosess, og det er mye bedre å gjøre på en modell som vi er mer sikre på vil gi de ønskede resultatene.

Selv om problemets natur kan hjelpe oss med å identifisere kategorien maskinlæringsalgoritme å velge mellom, er det ikke en fullstendig jobb. Innenfor en kategori som klassifisering, som vi så tidligere, det er ofte mange mulige forskjellige algoritmer og deres variasjoner å velge mellom.

Ofte den beste fremgangsmåten er rask prototyping på et mye mindre datasett. Et bibliotek som Spark MLlib gjør jobben med rask prototyping mye enklere.

5.2. Modell Hyper-Parameter Tuning

En typisk modell består av funksjoner, parametere og hyperparametere. Funksjoner er det vi mater inn i modellen som inndata. Modellparametere er variabler som modellen lærer under treningsprosessen. Avhengig av modell, det er visse tilleggsparametere som vi må sette basert på erfaring og justere iterativt. Disse kalles modellhyperparametere.

For eksempel er læringsgraden en typisk hyperparameter i gradient-avstamningsbaserte algoritmer. Læringsgrad styrer hvor raske parametere justeres under treningssyklusene. Dette må settes passende for at modellen skal lære effektivt i et rimelig tempo.

Selv om vi kan begynne med en innledende verdi av slike hyperparametere basert på erfaring, må vi utføre modellvalidering og manuelt stille dem iterativt.

5.3. Modellytelse

En statistisk modell, mens du er opplært, er utsatt for over- og underinnredning, begge forårsaker dårlig modellytelse. Underfitting refererer til tilfellet der modellen ikke plukker de generelle detaljene fra dataene tilstrekkelig. På den annen side skjer overmontering når modellen også begynner å plukke opp støy fra dataene.

Det er flere metoder for å unngå problemene med under- og overmontering, som ofte brukes i kombinasjon. For eksempel, for å motvirke overmontering inkluderer de mest anvendte teknikkene kryssvalidering og regularisering. På samme måte kan vi øke kompleksiteten i modellen og øke treningstiden for å forbedre utstyret.

Spark MLlib har fantastisk støtte for de fleste av disse teknikkene som regulering og kryssvalidering. Faktisk har de fleste algoritmene standardstøtte for dem.

6. Spark MLlib i sammenligning

Mens Spark MLlib er et ganske kraftig bibliotek for maskinlæringsprosjekter, er det absolutt ikke det eneste for jobben. Det er ganske mange biblioteker tilgjengelig på forskjellige programmeringsspråk med varierende støtte. Vi vil gå gjennom noen av de populære her.

6.1. Tensorflow / Keras

Tensorflow er en åpen kildekode bibliotek for dataflyt og differensierbar programmering, mye brukt for maskinlæringsapplikasjoner. Sammen med abstraksjonen på høyt nivå, Keras, er det et valgverktøy for maskinlæring. De er primært skrevet i Python og C ++ og brukes primært i Python. I motsetning til Spark MLlib har den ikke en polyglot-tilstedeværelse.

6.2. Theano

Theano er en annen Python-basert åpen kildekode bibliotek for å manipulere og evaluere matematiske uttrykk - for eksempel matrise-baserte uttrykk, som ofte brukes i maskinlæringsalgoritmer. I motsetning til Spark MLlib brukes Theano igjen primært i Python. Keras kan imidlertid brukes sammen med en Theano-bakside.

6.3. CNTK

Microsoft Cognitive Toolkit (CNTK) er en deep learning framework skrevet i C ++ som beskriver beregningstrinn via en rettet graf. Den kan brukes i både Python- og C ++ - programmer og brukes primært til utvikling av nevrale nettverk. Det er en Keras-bakside basert på CNTK tilgjengelig for bruk som gir den kjente intuitive abstraksjonen.

7. Konklusjon

For å oppsummere, i denne opplæringen gikk vi gjennom det grunnleggende om maskinlæring, inkludert forskjellige kategorier og arbeidsflyt. Vi gikk gjennom det grunnleggende i Spark MLlib som et maskinlæringsbibliotek tilgjengelig for oss.

Videre utviklet vi en enkel maskinlæringsapplikasjon basert på tilgjengelig datasett. Vi implementerte noen av de vanligste trinnene i arbeidsflyten for maskinlæring i vårt eksempel.

Vi har også gått gjennom noen av de avanserte trinnene i et typisk maskinlæringsprosjekt og hvordan Spark MLlib kan hjelpe i disse. Til slutt så vi noen av de alternative maskinlæringsbibliotekene som er tilgjengelige for oss å bruke.

Som alltid kan koden bli funnet på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found