Hovedmålet med denne lesingen er å forstå nok statistisk metodikk til å kunne dra nytte av maskinlæringsalgoritmer, som er i biblioteket scikit-lær Python og bruk deretter denne kunnskapen for å løse et klassisk maskinlæringsproblem.
Første stopp på reisen tar oss gjennom en kort historie med maskinlæring. Deretter vil vi dykke inn i forskjellige algoritmer. Ved vårt siste stopp vil vi bruke det vi lærte for å løse Titanic overlevelsesrate prediksjon problem .
Noen ansvarsfraskrivelser:
Med det sagt, la oss komme i gang!
Så snart du våger deg inn i dette feltet, skjønner du det maskinlæring det er mindre romantisk enn du tror. Opprinnelig var jeg full av håp om at etter å ha lært mer ville jeg være i stand til å bygge min egen AI Jarvis, at jeg ville bruke hele dagen på kodingsprogramvare og tjene penger for meg selv, slik at jeg kunne tilbringe hele dager utendørs med å lese bøker, sykle på motorsykkel og nyter en hensynsløs livsstil mens min personlige Jarvis får lommene mine til å gå dypere. Imidlertid skjønte jeg snart at grunnlaget for maskinlæringsalgoritmer er statistikk, som jeg personlig synes er kjedelig og uinteressant. Heldigvis viste det seg at 'kjedelig' statistikk har noen veldig fascinerende anvendelser.
Du vil snart oppdage at for å komme til de fascinerende applikasjonene, må du forstå statistikken veldig godt. Et av målene med maskinlæringsalgoritmer er å finne statistiske avhengigheter i leverte data.
Dataene som leveres kan variere fra å kontrollere blodtrykk kontra alder, til å finne håndskrevet tekst basert på fargen på forskjellige piksler.
Når det er sagt, var jeg nysgjerrig på å se om jeg kunne bruke maskinlæringsalgoritmer for å finne avhengigheter av kryptografiske hashfunksjoner (SHA, MD5, etc.) - du kan ikke gjøre det skjønt fordi de aktuelle kryptoprimitivene er konstruert på en slik måte at de eliminerer avhengigheter og gir resultater som er betydelig vanskelig å forutsi. Jeg tror, gitt uendelig tid, kan maskinlæringsalgoritmer knekke hvilken som helst kryptomodell.
Dessverre har vi ikke så mye tid, så vi må finne en annen måte å effektivt utvinne kryptovalutaen på. Hvor langt har vi kommet så langt?
Røttene til maskinlæringsalgoritmer kommer fra Thomas Bayes, som var en engelsk statistiker og bodde på 1700-tallet. Hans artikkel Et essay for å løse et problem i læren om muligheter ligger til grunn Bayes teorem , som er mye brukt innen statistikk.
På 1800-tallet publiserte Pierre-Simon Laplace Analytisk sannsynlighetsteori , utvide Bayes 'arbeid og definere det vi i dag kjenner som Bayes' teorem. Rett før beskrev Adrien-Marie Legendre metoden «minste firkanter», som også i dag er mye brukt i veiledet læring.
Det 20. århundre er perioden da de fleste av de offentlig kjente oppdagelsene har blitt gjort innen dette feltet. Andrey Markov oppfant Markov-kjeder, som han brukte til å analysere dikt. Alan Turing foreslo en læringsmaskin som kunne bli kunstig intelligent, i utgangspunktet forutsette genetiske algoritmer. Frank Rosenblatt oppfant Perceptron , som utløste stor spenning og stor mediedekning.
Men så, på 1970-tallet, var det mye pessimisme rundt ideen om AI, og derfor reduksjonen i finansiering, og det er derfor denne perioden kalles 'vinter'. Gjenoppdagelsen av backpropagation på 1980-tallet utløste en gjenoppblomstring innen maskinlæringsforskning. Og i dag er det et hett tema igjen.
Avdøde Leo Breiman skilte mellom to statistiske paradigmemodeller. Den 'algoritmiske modelleringen' som betyr mer eller mindre maskinlæringsalgoritmer, lik tilfeldig skog .
Maskinlæring og statistikk er relaterte felt. I følge Michael I. Jordan Ideer for maskinlæring, fra metodiske prinsipper til teoretiske verktøy, har hatt en lang forhistorie innen statistikk. Det foreslo også dating vitenskap som et stabilt begrep for det generelle problemet som maskinlæringsspesialister og statsmenn har jobbet med.
Feltet maskinlæring er etablert på to hovedpilarer kalt veiledet læring Y uten tilsyn læring . Noen mennesker vurderer også et nytt studieretning som - dyp læring —Det er atskilt fra det vanlige spørsmålet om veiledet eller uten tilsyn læring.
Veiledet læring oppstår når en datamaskin presenteres med eksempler på innganger og ønsket utgang. Målet er å lære om generelle formler som kartlegger innganger til utganger. Dette kan deles slik:
I kontrast, den uten tilsyn læring Det oppstår når etiketter ikke blir gitt, og det er opp til algoritmen å finne strukturen i inngangen. Uovervåket læring kan være et mål i seg selv når vi bare trenger å oppdage skjulte mønstre.
Dyp læring Det er et nytt studieretning som er inspirert av strukturen og funksjonen til den menneskelige hjernen, på samme måte som den er basert på kunstige nevrale nettverk i stedet for bare statistiske begreper. Dyp læring kan brukes i både veiledede og ukontrollerte tilnærminger.
I denne artikkelen vil vi se på noen av de enklere overvåkede maskinlæringsalgoritmene, og bruke dem til å beregne individets overlevelsesodds i den tragiske senkingen av titanic. Men generelt, hvis du ikke er sikker på hvilken algoritme du skal bruke, er et godt sted å starte Machine Learning Algorithm Review Sheet scikit-lær .
Den enkleste algoritmen er kanskje lineær regresjon. Noen ganger kan dette fremstilles grafisk som en rett linje, men til tross for navnet, hvis det er en polynomhypotese, kan denne linjen være en kurve. I begge tilfeller modellerer forholdet mellom en skalaravhengig variabel $ og $ og en eller flere forklarende verdier betegnet med $ x $.
I lekmannsbetegnelser betyr dette at lineær regresjon er algoritmen som lærer avhengigheten mellom hver av de allerede kjente $ x $ og $ y $, så mye at vi kan bruke den til å forutsi $ y $ for et ukjent utvalg på $ x $.
I vårt første veiledede læringseksempel, vil vi bruke en grunnleggende lineær regresjonsmodell for å forutsi en persons blodtrykk basert på alder. Øst Det er et veldig enkelt datasett med to viktige egenskaper: Alder og blodtrykk.
Som nevnt ovenfor fungerer de fleste maskinlæringsalgoritmer ved å finne en statistisk avhengighet av dataene som blir gitt til dem. Denne avhengigheten kalles a hypotese og er vanligvis betegnet med $ h ( theta) $.
For å tyde denne hypotesen, la oss starte med å laste ned og utforske dataene.
import matplotlib.pyplot as plt from pandas import read_csv import os # Cargar datos data_path = os.path.join(os.getcwd(), 'data/blood-pressure.txt') dataset = read_csv(data_path, delim_whitespace=True) # Tenemos 30 entradas en nuestro set de data y cuatro características. La primera característica es la identificación de la entrada. # La segunda característica siempre es la nro. 1. La tercera es la edad y la última es la presión arterial. # Ahora dejaremos de lado la Identificación y la característica Uno por ahora, ya que no es importante. dataset = dataset.drop(['ID', 'One'], axis=1) # Y mostraremos esta gráfica %matplotlib inline dataset.plot.scatter(x='Age', y='Pressure') # Ahora, asumiremos que ya sabemos la hipótesis y parece una línea recta h = lambda x: 84 + 1.24 * x # ahora agreguemos esta línea a la gráfica ages = range(18, 85) estimated = [] for i in ages: estimated.append(h(i)) plt.plot(ages, estimated, 'b')
[]
I grafen over representerer hvert blått punktet våre eksempeldata, og den blå linjen er hypotesen som algoritmen vår må lære. Så hva er denne hypotesen?
For å løse dette problemet må vi lære avhengigheten mellom $ x $ og $ y $, som er betegnet med $ y = f (x) $. Derfor er $ f (x) $ den ideelle objektive funksjonen. Maskinlæringsalgoritmen vil prøve å gjette hypotesefunksjonen $ h (x) $, som er den nærmeste tilnærmingen til den ukjente $ f (x) $.
Den enkleste hypoteseformen for det lineære regresjonsproblemet ser slik ut: $ h_ theta (x) = theta_0 + theta_1 * x $. Vi har en enkel skalarvariabel $ x $, som gir en enkel skalarvariabel $ y $, der $ theta_0 $ og $ theta_1 $ er parametere vi må lære oss. Prosessen med å tilpasse denne blå linjen i dataene kalles lineær regresjon. Det er viktig å forstå at vi bare har én inngangsparameter $ x_1 $; imidlertid vil mange av hypotesefunksjonene også omfatte en enhet med skråstilling ($ x_0 $). Så den resulterende hypotesen vår har en form av $ h_ theta (x) = theta_0 * x_0 + theta_1 * x_1 $. Men vi kan unngå å skrive $ x_0 $ fordi det nesten alltid er lik 1.
Går tilbake til den blå linjen. Hypotesen vår ser slik ut $ h (x) = 84 + 1,24x $, noe som betyr at $ theta_0 = 84 $ og $ theta_1 = 1,24 $. Hvordan kan vi automatisk utlede disse $ theta $ -verdiene?
Vi må definere en kostnadsfunksjon . I det vesentlige er hva en kostnadsfunksjon gjør, å beregne rotkvadratfeilen mellom prediksjonsmodellen og selve utgangen.
[J ( theta) = frac {1} {2m} sum_ {i = 1} ^ m (h_ theta (x ^ {(i)}) - y ^ {(i)}) ^ 2 ]For eksempel forutsier hypotesen vår at for noen som er 48 år, bør blodtrykket deres være $ h (48) = 84 + 1,24 * 48 = 143mmHg $; i treningsutvalget vårt har vi imidlertid verdien på $ 130 mmHg $. Derfor er feilen $ (143 - 130) ^ 2 = $ 169. Nå må vi beregne denne feilen på hver inngang i treningsdatasettet vårt, og deretter legge alt sammen ($ sum_ {i = 1} ^ m (h_ theta (x ^ {(i)}) - y ^ {(i )}) ^ 2 $) og ta den betydelige verdien derfra. Dette gir oss et enkelt skalarnummer, som representerer kostnaden for funksjonen. Målet vårt er å finne verdiene $ theta $, slik at kostnadsfunksjonen blir lavere; med andre ord, vi ønsker å minimere kostnadsfunksjonen. Forhåpentligvis er dette intuitivt: hvis vi har en liten kostnadsfunksjonsverdi, betyr dette at prediksjonsfeilen også vil være lav.
import numpy as np # Calculemos el costo para la hipótesis de arriba h = lambda x, theta_0, theta_1: theta_0 + theta_1 * x def cost(X, y, t0, t1): m = len(X) # the number of the training samples c = np.power(np.subtract(h(X, t0, t1), y), 2) return (1 / (2 * m)) * sum(c) X = dataset.values[:, 0] y = dataset.values[:, 1] print('J(Theta) = %2.2f' % cost(X, y, 84, 1.24))
J(Theta) = 1901.95
Nå må vi finne verdiene til $ theta $ så mye at verdien av vår kostnadsfunksjon er minimal. Men hvordan kan vi gjøre det?
[minJ ( theta) = frac {1} {2m} sum_ {i = 1} ^ m (h_ theta (x ^ {(i)}) - y ^ {(i)}) ^ 2 ]Det er mange mulige algoritmer, men den mest populære er gradient nedover . For å forstå intuisjonen bak gradientnedstigningsmetoden, la oss sette den først på grafen. For enkelhets skyld vil vi anta en enklere hypotese $ h ( theta) = theta_1 * x $. Deretter vil vi ha en enkel 2D-graf der $ x $ er verdien av $ theta $ og $ y $ er kostnadsfunksjonen på dette punktet.
import matplotlib.pyplot as plt fig = plt.figure() # Genera los datos theta_1 = np.arange(-10, 14, 0.1) J_cost = [] for t1 in theta_1: J_cost += [ cost(X, y, 0, t1) ] plt.plot(theta_1, J_cost) plt.xlabel(r'$ heta_1$') plt.ylabel(r'$J( heta)$') plt.show()
Kostnadsfunksjonen er konveks, noe som betyr at det i intervallet $ [a, b] $ bare er ett minimum. Noe som betyr at de beste parameterne $ theta $ er på det punktet hvor kostnadsfunksjonen er lavest.
I utgangspunktet er gradientnedstigning en algoritme som prøver å finne et sett med parametere som minimerer funksjonen. Det starter med et innledende sett med parametere og tar interaktive skritt mot den negative retningen av gradientfunksjonen.
Hvis vi beregner derivatet av en hypotesefunksjon på et spesifikt punkt, vil dette gi oss direkte tilgang til linjen som tangerer kurven på det punktet. Dette betyr at vi kan beregne snarveien på hvert punkt i grafen.
Slik algoritmen fungerer er dette:
Nå avhenger konvergensbetingelsen av implementeringen av algoritmen. Kanskje vi vil stoppe etter 50 trinn, etter litt lumbral eller noe annet.
import math # Ejemplo del algoritmo simple de descenso gradiente tomado de Wikipedia cur_x = 2.5 # The algorithm starts at point x gamma = 0.005 # Step size multiplier precision = 0.00001 previous_step_size = cur_x df = lambda x: 2 * x * math.cos(x) # Recuerda la curva de aprendizaje y establécela while previous_step_size > precision: prev_x = cur_x cur_x += -gamma * df(prev_x) previous_step_size = abs(cur_x - prev_x) print('The local minimum occurs at %f' % cur_x)
El mínimo local pasa en 4.712194
Vi vil ikke implementere disse algoritmene i denne artikkelen. I stedet vil vi bruke det allerede adopterte scikit-learn
, et Python open source maskinlæringsbibliotek. Det gir mange nyttige APIer for forskjellige data mining og maskinlæringsproblemer.
De sklearn.linear_model importar LinearRegression # La Regresión Lineal usa el método de descenso gradiente # Nuestra data X = dataset[['Age']] y = dataset[['Pressure']] regr = LinearRegression() regr.fit(X, y) # Salidas Argumentadas plt.xlabel('Age') plt.ylabel('Blood pressure') plt.scatter(X, y, color='black') plt.plot(X, regr.predict(X), color='blue') plt.show() plt.gcf().clear()
print( 'Predicted blood pressure at 25 y.o. = ', regr.predict(25) ) print( 'Predicted blood pressure at 45 y.o. = ', regr.predict(45) ) print( 'Predicted blood pressure at 27 y.o. = ', regr.predict(27) ) print( 'Predicted blood pressure at 34.5 y.o. = ', regr.predict(34.5) ) print( 'Predicted blood pressure at 78 y.o. = ', regr.predict(78) )
Predicted blood pressure at 25 y.o. = [[ 122.98647692]] Predicted blood pressure at 45 y.o. = [[ 142.40388395]] Predicted blood pressure at 27 y.o. = [[ 124.92821763]] Predicted blood pressure at 34.5 y.o. = [[ 132.20974526]] Predicted blood pressure at 78 y.o. = [[ 174.44260555]]
Når du arbeider med maskinlæringsproblemer, er det viktig å vite hvordan man gjenkjenner de forskjellige typene data. Det kan være numeriske (kontinuerlige eller diskrete), kategoriske eller ordinære data.
Numeriske data de har betydning som mål. For eksempel: alder, vekt, antall bitcoins til en person eller hvor mange artikler en person kan skrive per måned. Numeriske data kan også være diskrete eller kontinuerlige.
Kategoriske data de representerer verdier som en persons kjønn, sivilstand, land osv. Disse dataene kan ha numerisk verdi, men disse tallene vil ikke ha matematisk verdi. Du kan ikke legge dem til.
Ordinære data det kan være en blanding av de andre typene der kategoriene kan nummereres på en matematisk meningsfull måte. Et vanlig eksempel er rangeringer: Vi blir ofte bedt om å rangere ting på en skala fra ti til ti, og i slike tilfeller er bare hele tall tillatt. Selv om vi kan bruke disse dataene numerisk (for eksempel for å finne gjennomsnittlig rangering av noe), behandler vi ofte disse dataene som kategoriske når vi bruker maskinlæringsmetoder.
Lineær regresjon er en utrolig algoritme som hjelper oss med å forutsi numeriske verdier som prisen på et hus med en bestemt størrelse og visse rom. Noen ganger vil vi imidlertid kunne forutsi kategoriske data for å få svar på spørsmål som:
Eller:
Alle disse spørsmålene er spesifikke for klassifiseringsproblem . Og den enkleste klassifiseringsalgoritmen kalles Logistisk regresjon , som til slutt er lik regresjonen lineær Bortsett fra at du har en annen hypotese.
Først og fremst kan vi gjenbruke den samme lineære hypotesen $ h_ theta (x) = theta ^ T X $ (dette er i vektorisert form). Mens lineær regresjon kan sendes ut som et hvilket som helst tall i intervallene $ [a, b] $, kan logistisk regresjon bare få verdier i $ [- 1, 1] $, som refererer til sannsynligheten for at objektet er i en kategori eller ikke.
Hvis vi bruker en sigmoid funksjon , kan vi konvertere en hvilken som helst numerisk verdi til å representere en verdi i området $ [- 1, 1] $.
[f (x) = frac {1} {1 + e ^ x} ]Nå i stedet for $ x $, må vi passere en eksisterende hypotese, og vi får:
[f (x) = frac {1} {1 + e ^ { theta_0 + theta_1 * x_1 + ... + theta_n * x_n}} ]Etter dette kan vi bruke en enkel terskel som sier at hvis hypotesen er større enn null, vil den være en sann verdi, ellers vil den være falsk.
[h_ theta (x) = begin {cases} 1 & mbox {if} theta ^ T X> 0 \ 0 & mbox {else} end {cases} ]Dette betyr at vi kan bruke det samme kostnadsfunksjon og den samme synkende gradientalgoritmen for å lære en logistisk regresjonshypotese.
I det neste maskinlæringseksemplet vil vi gi råd til romfergerpilotene om de skal styre landingen manuelt eller automatisk. Vi har et veldig lite datasett —15 prøver - bestående av seks egenskaper og bakken sannhet .
I maskinlæringsalgoritmer er begrepet “ bakken sannhet ”Henviser til nøyaktigheten av klassifiseringen av treningssett for veiledet læringsteknikk.
Datasettet vårt er komplett, noe som betyr at det ikke mangler funksjoner; til tross for dette har noen funksjoner et '*' i stedet for kategorien, noe som betyr at denne funksjonen ikke betyr noe. Alle stjerner som dette blir erstattet med nuller.
de sklearn.linear_model importar LogisticRegression # Data data_path = os.path.join(os.getcwd(), 'data/shuttle-landing-control.csv') dataset = read_csv(data_path, header=None, names=['Auto', 'Stability', 'Error', 'Sign', 'Wind', 'Magnitude', 'Visibility'], na_values='*').fillna(0) # Preparar características X = dataset[['Stability', 'Error', 'Sign', 'Wind', 'Magnitude', 'Visibility']] y = dataset[['Auto']].values.reshape(1, -1)[0] model = LogisticRegression() model.fit(X, y) # Por ahora nos falta un concepto importante. No sabemos qué tan bien funciona nuestro # modelo y debido a ello, en realidad no podemos mejorar el rendimiento de nuestra hipótesis. # Hay muchas métricas útiles pero por ahora, validaremos que tan bien # Actúa nuestro algoritmo en el set de datos, en el cual aprendió. 'La puntuación de nuestro modelo es %2.2f%%' % (model.score(X, y) * 100)
Puntuación de nuestro modelo es 73.33%
I eksemplet ovenfor validerte vi ytelsen til modellen vår ved hjelp av læringsdataene. Vil det imidlertid være et godt valg, gitt at algoritmen vår kanskje ikke ser bort fra dataene? La oss se et enklere eksempel der vi har en egenskap som representerer størrelsen på et hus, og en annen som representerer prisen.
de sklearn.pipeline importar make_pipeline de sklearn.preprocessing importer PolynomialFeatures de sklearn.linear_model importar LinearRegression de sklearn.model_selection importar cross_val_score # Función Verdad del terreno ground_truth = lambda X: np.cos(15 + np.pi * X) # Generar observaciones aleatorias alrededor de la función verdad del terreno n_samples = 15 degrees = [1, 4, 30] X = np.linspace(-1, 1, n_samples) y = ground_truth(X) + np.random.randn(n_samples) * 0.1 plt.figure(figsize=(14, 5)) models = {} # Trazar todos modelos del algoritmo de aprendizaje de máquina para idx, degree in enumerate(degrees): ax = plt.subplot(1, len(degrees), idx + 1) plt.setp(ax, xticks=(), yticks=()) # Definir el modelo polynomial_features = PolynomialFeatures(degree=degree) model = make_pipeline(polynomial_features, LinearRegression()) models[degree] = model # Entrenar el modelo model.fit(X[:, np.newaxis], y) # Evaluar el modelo usando validación cruzada scores = cross_val_score(model, X[:, np.newaxis], y) X_test = X plt.plot(X_test, model.predict(X_test[:, np.newaxis]), label='Model') plt.scatter(X, y, edgecolor='b', s=20, label='Observations') plt.xlabel('x') plt.ylabel('y') plt.ylim((-2, 2)) plt.title('Degree {}
MSE = {:.2e}'.format( degree, -scores.mean())) plt.show()
Machine learning algoritmemodellen er overgeneralisert hvis du ikke kan generalisere verken treningsdataene eller nye observasjoner. I eksemplet ovenfor bruker vi en enkel lineær hypotese, som ikke representerer de faktiske treningsdataene og vil prestere veldig dårlig. Vanligvis diskuteres ikke overgeneralisering fordi den lett kan oppdages med gode målinger.
Hvis algoritmen vår husker hver observasjon som ble vist for den, vil den underprestere med nye observasjoner som ligger utenfor treningsdatasettet. Dette kalles overmontering . For eksempel passerer en trettiende graders polynommodell de fleste poengene og har god score på treningssettet, men alt annet enn dette vil fungere dårlig.
Datasettet vårt består av en enkel funksjon som kan plottes i 2D; men i det virkelige liv kunne vi ha datasett med hundrevis av funksjoner, noe som gjør dem umulige å visuelt plotte i det euklidiske rommet. Hvilke andre alternativer har vi for å se om modellen er overgeneralisert eller overmontert?
Det er på tide å introdusere deg for konseptet læringskurve . Dette er en enkel graf som plotter den kvadrerte feilen over antall treningsprøver.
I læringsmateriell finner du grafikk som ligner på disse:
Men i det virkelige liv kommer du kanskje ikke over et så perfekt bilde. La oss plotte læringskurven for hver av modellene våre.
from sklearn.model_selection import learning_curve, ShuffleSplit # Trazar curvas de aprendizaje plt.figure(figsize=(20, 5)) for idx, degree in enumerate(models): ax = plt.subplot(1, len(degrees), idx + 1) plt.title('Degree {}'.format(degree)) plt.grid() plt.xlabel('Training examples') plt.ylabel('Score') train_sizes = np.linspace(.6, 1.0, 6) # Validación cruzada con 100 iteraciones para obtener una prueba sencilla de *mean* y entrenamiento # curvas de puntuación cada vez con 20% de los datos seleccionados aleatoriamente como set de validación. cv = ShuffleSplit(n_splits=100, test_size=0.2, random_state=0) model = models[degree] train_sizes, train_scores, test_scores = learning_curve( model, X[:, np.newaxis], y, cv=cv, train_sizes=train_sizes, n_jobs=4) train_scores_mean = np.mean(train_scores, axis=1) test_scores_mean = np.mean(test_scores, axis=1) plt.plot(train_sizes, train_scores_mean, 'o-', color='r', label='Training score') plt.plot(train_sizes, test_scores_mean, 'o-', color='g', label='Test score') plt.legend(loc = 'best') plt.show()
I vårt simulerte scenario ser den blå linjen som representerer treningspoengene ut som en rett linje. Egentlig reduseres det noe - du kan se det i grafen til første grads polynom, men i de andre er det for subtilt å se i denne oppløsningen. I det minste kan vi se at det er stor forskjell mellom treningslæringskurvene og testobservasjonene med et 'high tilt' -scenario.
I den 'normale' klassifikasjonsgrafen for læring i midten kan du se hvordan trenings- og testresultatlinjene kommer sammen.
Og i 'høy varians' -grafen kan du se at med et lavt antall prøver er test- og treningspoengene veldig like, men når du øker antall tester, forblir treningspoengene nesten perfekte så lenge testen vokser bort.
Vi kan fikse overgeneraliserte modeller (også kalt modeller med stor stigning ) hvis vi bruker en ikke-lineær hypotese, for eksempel hypotesen med flere polynomiske egenskaper.
Vår overmonterte modell ( stor variasjon ) for hvert eksempel vist for deg; men allikevel når testdata blir introdusert, øker forskjellen mellom læringskurver. Vi kan bruke regularisering, kryssvalidering og flere dataprøver for å fikse overtilpassede modeller.
En av de vanlige metodene som brukes for å unngå overmontering er å lagre noen av tilgjengelige data og bruke den som et testsett. Når forskjellige konfigurasjoner av modellen evalueres, for eksempel antall polynomiske egenskaper, er det likevel en risiko for å overmontere testsettet fordi parametrene kan endres litt for å oppnå en optimal ytelse for estimatoren, og det er derfor vår kunnskap på testsettet kan lekke inn i modellen. For å løse dette problemet må vi tilpasse en annen del av datasettet, som kalles et 'valideringssett.' Treningen gjøres i treningssettet, og når vi mener at vi har oppnådd den optimale ytelsen til modellen, kan vi gjøre evalueringen ved hjelp av valideringssettet.
Imidlertid, hvis vi lager tre sett med partisjoner av dataene, vil antall prøver som kan brukes til å trene modellene reduseres dramatisk, og resultatene kan avhenge av et bestemt tilfeldig valg for paret for valideringstreningssett.
En løsning på dette problemet er en prosedyre som kalles kryssvalidering. I en standard $ k $ -fold kryssvalidering er dataene delt inn i $ k $ delsett kalt fold. Algoritmen blir deretter opplært iterativt med $ k-1 $ folder, mens du bruker de gjenværende foldene som testsett (kalt ' holdout folder ”)
Kryssvalidering tillater at parametere bare blir gradert med det originale treningssettet. Dette lar deg beholde testsettet som et usynlig datasett for å velge din endelige modell.
Det er mange andre kryssvalideringsteknikker som la P være ute , lagdelt $ k $ -fold , stokk og del , etc. men disse er utenfor omfanget av denne artikkelen.
Dette er en annen teknikk som kan hjelpe deg med å løse problemet med modell for overmontering. De fleste datasett har mønster og noe støy. Målet med regularisering er å redusere påvirkning av støy på modellen.
Det er tre viktigste reguleringsteknikker: Lasso, Tikhonov og stretch mesh.
L1 regulering (eller Lasso-regulering ) er den som vil velge noen egenskaper for å minimere til null, slik at disse ikke har noe med den endelige modellen å gjøre. L1 kan sees på som en metode for å velge viktige egenskaper.
** L2-regulering ** (eller ** Tikhonov-regulering **) er den som har ansvaret for å tvinge alle egenskaper for å være relativt små, slik at de påvirker modellen mindre.
Strekknett er den kombinasjon av L1 og L2.
Skaleringsfunksjon er også et viktig trinn mens dataene er forhåndsbehandlet. Datasettet vårt kan ha noen egenskaper med $ [- infty, infty] $ -verdier og andre egenskaper med forskjellige skalaer. Dette er en metode som gjør det mulig å standardisere områdene av uavhengige verdier.
Skaleringsfunksjon er en viktig prosess for å forbedre ytelsen til læringsmodeller. Først og fremst vil gradientnedstigningen konvergere mye raskere hvis alle funksjonene er skalert til det samme mønsteret. På samme måte fungerer mange av algoritmene - for eksempel: support vector machines (SVM) - ved å beregne avstanden mellom to punkter, og hvis en av funksjonene har store verdier, vil avstanden bli sterkt påvirket av denne funksjonen.
SVM (med sitt engelske navn Støtt vektormaskiner ) er en annen populær maskinlæringsalgoritme som kan brukes til klassifiserings- og regresjonsproblemer. I SVM er hver observasjon tegnet som et punkt i et $ n $ dimensjonalt rom - der $ n $ er antall funksjoner vi har. Verdien av hver funksjon er verdien av bestemte koordinater. Så prøver vi å finne et hyperplan som skiller to klasser veldig bra.
Etter å ha identifisert det beste hyperplanet, vil vi legge til marginer som vil bidra til å skille de to klassene ytterligere.
SVM er veldig effektivt når antall funksjoner er veldig høyt, eller hvis antall funksjoner er større enn antall datasampler. Selv om SVM vanligvis fungerer med vektorer, er det avgjørende å normalisere dataene før du bruker dem.
Nevrale nettverksalgoritmer er trolig den mest spennende grenen av maskinlæringsstudier. Nevrale nettverk prøver å etterligne forbindelsen av nevroner i hjernen.
Slik går et nevralt nettverk. Vi kombinerer mange noder der hver node tar et sett med utganger, gjør noen beregninger og deretter sender ut en verdi.
Det finnes et bredt utvalg av nevrale nettverksalgoritmer for både veiledet og uten tilsyn læring. Nevrale nettverk kan brukes til å kjøre autonome biler, spille videospill, landfly, klassifisere bilder og mer.
RMS Titanic var et britisk skip som sank i Nord-Atlanterhavet 15. april 1912 etter å ha kollidert med et isfjell. Omtrent 2224 passasjerer og mannskap hadde om bord, hvorav mer enn 1500 døde, noe som gjør det til en av de dødeligste kommersielle maritime katastrofer i nyere tid.
Nå som vi forstår intuisjonen til en av de mest grunnleggende maskinlæringsalgoritmene som brukes til problemklassifisering, kan vi bruke kunnskapen vår til å forutsi overlevelsesraten til de som er ombord på Titanic.
Datasettet vårt kommer fra Kaggels dataplattform for konkurransevitenskap .
import os from pandas import read_csv, concat # Cargar datos data_path = os.path.join(os.getcwd(), 'data/titanic.csv') dataset = read_csv(data_path, skipinitialspace=True) dataset.head(5)
PassasjerId | Overlevde | Pklasse | Navn | Kjønn | Alder | SibSp | respekt | Billett | Å gjøre | Hytte | Begynte | |
0 | en | 0 | 3 | Braund, Mr. Owen Harris | hann | 22.0 | en | 0 | A / 5 21171 | 7.2500 | NaN | S |
en | 2 | en | en | Cumings, fru John Bradley (Florence Briggs Th ... | hunn | 38,0 | en | 0 | PC 17599 | 71.2833 | C85 | C |
2 | 3 | en | 3 | Heikkinen, frøken. Et lån | hunn | 26.0 | 0 | 0 | STON / O2. 3101282 | 7,9250 | NaN | S |
3 | 4 | en | en | Futrelle, fru Jacques Heath (Lily May Peel) | hunn | 35,0 | en | 0 | 113803 | 53.1000 | C123 | S |
4 | 5 | 0 | 3 | Allen, Mr. William Henry | hann | 35,0 | 0 | 0 | 373450 | 8,0500 | NaN | S |
Vårt første skritt vil være å laste inn og utforske dataene. Vi har 891 testjournaler; hver plate har følgende struktur:
Dette datasettet inneholder både numerisk og kategorisk informasjon. Det er vanligvis en god ide å grave nærmere inn i dataene du har, og basert på den for å lage antagelser. I dette tilfellet hopper vi imidlertid over dette trinnet og går rett til spådommene.
import pandas as pd # Necesitamos eliminar algunas características insignificantes y mapear el resto. # Número y costo del boleto no deberían contribuir en el rendimiento de nuestro modelo. # Característica de nombres viene con títulos (como: Sr. Srta. Doctor) incluidos. # El género es muy importante. # El Puerto de embarcación podría ser atribuir algún valor. # Usar el Puerto de embarcación podría ser contra-intuitivo pero podría # existir una tasa de supervivencia más alta para pasajeros que abordaron en el mismo Puerto. dataset['Title'] = dataset.Name.str.extract(' ([A-Za-z]+).', expand=False) dataset = dataset.drop(['PassengerId', 'Ticket', 'Cabin', 'Name'], axis=1) pd.crosstab(dataset['Title'], dataset['Sex'])
Tittel Sex | hunn | hann |
Capt | 0 | en |
Med | 0 | 2 |
Grevinne | en | 0 |
Don | 0 | en |
Dr. | en | 6 |
Jonkheer | 0 | en |
dame | en | 0 |
Major | 0 | 2 |
Herre | 0 | 40 |
Gå glipp av | 182 | 0 |
Fru | 2 | 0 |
Fru | en | 0 |
MR | 0 | 517 |
Fru | 125 | 0 |
Fru | en | 0 |
Rev. | 0 | 6 |
Herr | 0 | en |
# Reemplazaremos muchos títulos con un nombre más común, equivalente Inglés, # o re-clasificación dataset['Title'] = dataset['Title'].replace(['Lady', 'Countess','Capt', 'Col', 'Don', 'Dr', 'Major', 'Rev', 'Sir', 'Jonkheer', 'Dona'], 'Other') dataset['Title'] = dataset['Title'].replace('Mlle', 'Miss') dataset['Title'] = dataset['Title'].replace('Ms', 'Miss') dataset['Title'] = dataset['Title'].replace('Mme', 'Mrs') dataset[['Title', 'Survived']].groupby(['Title'], as_index=False).mean()
Tittel | Overlevde | |
0 | Herre | 0,575000 |
en | Gå glipp av | 0,702703 |
2 | MR | 0,156673 |
3 | Fru | 0,793651 |
4 | Annen | 0.347826 |
# Ahora mapearemos categorias alfanumericas a números title_mapping = { 'Mr': 1, 'Miss': 2, 'Mrs': 3, 'Master': 4, 'Other': 5 } gender_mapping = { 'female': 1, 'male': 0 } port_mapping = { 'S': 0, 'C': 1, 'Q': 2 } # Mapa de título dataset['Title'] = dataset['Title'].map(title_mapping).astype(int) # Mapa de género dataset['Sex'] = dataset['Sex'].map(gender_mapping).astype(int) # Mapa de puerto freq_port = dataset.Embarked.dropna().mode()[0] dataset['Embarked'] = dataset['Embarked'].fillna(freq_port) dataset['Embarked'] = dataset['Embarked'].map(port_mapping).astype(int) # Arreglar errores de edades que falten dataset['Age'] = dataset['Age'].fillna(dataset['Age'].dropna().median()) dataset.head()
Overlevde | Pklasse | Kjønn | Alder | SibSp | respekt | Å gjøre | Begynte | Tittel | |
0 | 0 | 3 | 0 | 22.0 | en | 0 | 7.2500 | 0 | en |
en | en | en | en | 38,0 | en | 0 | 71.2833 | en | 3 |
2 | en | 3 | en | 26.0 | 0 | 0 | 7,9250 | 0 | 2 |
3 | en | en | en | 35,0 | en | 0 | 53.1000 | 0 | 3 |
4 | 0 | 3 | 0 | 35,0 | 0 | 0 | 8,0500 | 0 | en |
På dette punktet vil vi klassifisere forskjellige typer maskinlæringsalgoritmer i Python ved hjelp av scikit-learn
for å lage et annet sett med modeller. Det vil være lett å se hvilken som presterer bedre.
For hver av modellene vil vi bruke $ k $ -fold validering.
de sklearn.model_selection importar KFold, train_test_split de sklearn.pipeline importar make_pipeline de sklearn.preprocessing importar PolynomialFeatures, StandardScaler de sklearn.neural_network importar MLPClassifier de sklearn.svm importar SVC # Preparar data X = dataset.drop(['Survived'], axis = 1).values y = dataset[['Survived']].values X = StandardScaler().fit_transform(X) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state = None) # Prepare cross-validation (cv) cv = KFold(n_splits = 5, random_state = None) # Rendimiento p_score = lambda model, score: print('Performance of the %s model is %0.2f%%' % (model, score * 100)) # Clasificadores names = [ 'Logistic Regression', 'Logistic Regression with Polynomial Hypotheses', 'Linear SVM', 'RBF SVM', 'Neural Net', ] classifiers = [ LogisticRegression(), make_pipeline(PolynomialFeatures(3), LogisticRegression()), SVC(kernel='linear', C=0.025), SVC(gamma=2, C=1), MLPClassifier(alpha=1), ]
# iterate over classifiers models = [] trained_classifiers = [] for name, clf in zip(names, classifiers): scores = [] for train_indices, test_indices in cv.split(X): clf.fit(X[train_indices], y[train_indices].ravel()) scores.append( clf.score(X_test, y_test.ravel()) ) min_score = min(scores) max_score = max(scores) avg_score = sum(scores) / len(scores) trained_classifiers.append(clf) models.append((name, min_score, max_score, avg_score)) fin_models = pd.DataFrame(models, columns = ['Name', 'Min Score', 'Max Score', 'Mean Score'])
fin_models.sort_values(['Mean Score']).head()
Navn | Min Score | Maks score | Gjennomsnittlig poengsum | |
2 | Lineær SVM | 0,793296 | 0,821229 | 0,803352 |
0 | Logistisk regresjon | 0,826816 | 0,860335 | 0,846927 |
4 | Nevrale nett | 0,826816 | 0,860335 | 0,849162 |
en | Logistisk regresjon med polynomiske hypoteser | 0,854749 | 0,882682 | 0,869274 |
3 | RBF SVM | 0,843575 | 0.888268 | 0,869274 |
Vel, vår eksperimentelle forskning forteller oss at SVM-klassifisereren har best ytelse med en radial grunnleggende funksjon (RBF) -kjerne. Nå kan vi serieisere modellen vår og bruke den på nytt i produksjonsapplikasjoner.
import pickle svm_model = trained_classifiers[3] data_path = os.path.join(os.getcwd(), 'best-titanic-model.pkl') pickle.dump(svm_model, open(data_path, 'wb'))
Maskinlæring er ikke komplisert, men det er et veldig bredt fagfelt, og det krever kunnskap innen matematikk og statistikk for å forstå alle begrepene.
Akkurat nå er maskinlæring og dyp læring blant Silicon Valley mest ettertraktede diskusjonstemaer, først og fremst fordi de kan automatisere mange gjentatte oppgaver som talegjenkjenning, bilkjøring, økonomisk handel, pasientbehandling , kokk , markedsføring , blant mange andre.
Nå med denne kunnskapen kan du gå og løse utfordringer i Kaggle.
Dette var en kort introduksjon til den overvåkede maskinlæringsalgoritmen. Heldigvis er det mange online kurs og informasjon om maskinlæringsalgoritmer. Jeg anbefaler personlig å starte med Andrew Ngs kurs om Coursera.