Komplett guide til Feature Engineering: Zero to Hero

Kilde node: 1875402

Denne artikkelen ble publisert som en del av Data Science Blogathon

Introduksjon

Du må være klar over det faktum at Feature Engineering er hjertet i enhver maskinlæringsmodell. Hvor vellykket en modell er eller hvor nøyaktig den forutsier at det avhenger av anvendelsen av ulike funksjonstekniske teknikker. I denne artikkelen skal vi dykke dypt for å studere funksjonsteknikk. Artikkelen vil forklare alle teknikkene og vil også inneholde kode der det er nødvendig. Så la oss starte fra ground zero, hva er funksjonsteknikk?

Funksjonsteknikk

Bilde 1

Hva er funksjonsteknikk?

Alle maskinlæringsalgoritmer bruker noen inngangsdata til å generere utdata. Inndata inneholder mange funksjoner som kanskje ikke er i riktig form for å bli gitt modellen direkte. Det trenger en slags behandling, og her hjelper funksjonsteknikk. Feature engineering oppfyller hovedsakelig to mål:

  • Den forbereder inndatasettet i det skjemaet som kreves for en bestemt modell eller maskinlæringsalgoritme.
  • Feature engineering hjelper deg med å forbedre ytelsen til maskinlæringsmodeller på magisk vis.

Ifølge noen undersøkelser bruker dataforskere tiden sin på dataforberedelse. Se denne figuren nedenfor:

dataforberedelse

Bilde 2

Dette viser tydelig viktigheten av funksjonsteknikk for maskinlæring. Så denne artikkelen vil hjelpe deg med å forstå hele dette konseptet.

Forutsetninger:

1. Installer Python og få grunnleggende praktisk kunnskap.

2. Pandas bibliotek i python. Kommando for å installere: pip installere pandaer

3. Heftig bibliotek i python. Kommando for å installere: pip installer numpy

Importer deretter disse to bibliotekene slik:

importer pandaer som pd import numpy som np

La oss begynne!

Jeg viser her de viktigste teknikkene for å behandle dataene. Vi vil deretter se på hver teknikk en etter en i detalj med sine applikasjoner.

Hovedfunksjonsteknikkene som vil bli diskutert er:

1. Manglende dataimputasjon

2. Kategorisk koding

3. Variabel transformasjon

4. Outlier engineering

5. Dato og tidsteknikk

Mangler dataimputering for Feature Engineering

I inndataene dine kan det være noen funksjoner eller kolonner som mangler data, mangler verdier. Det skjer hvis det ikke er lagret data for en bestemt observasjon i en variabel. Manglende data er svært vanlig, og det er et uunngåelig problem, spesielt i virkelige datasett. Hvis disse dataene som inneholder en manglende verdi brukes, kan du se betydningen i resultatene. Så, imputasjon er handlingen om å erstatte manglende data med statistiske estimater av de manglende verdiene. Det hjelper deg med å fullføre treningsdataene dine som deretter kan leveres til en hvilken som helst modell eller en algoritme for forutsigelser.

Det er flere teknikker for manglende dataimputering. Disse er som følger:-

  1. Komplett saksanalyse
  2. Gjennomsnitt / median / modusimputasjon
  3. Verdiindikator mangler

Komplett saksanalyse for manglende dataimputasjon

Komplett saksanalyse er i utgangspunktet å analysere observasjonene i datasettet som inneholder verdier i alle variablene. Eller du kan si, fjern alle observasjonene som inneholder manglende verdier. Men denne metoden kan bare brukes når det bare er noen få observasjoner som mangler et datasett, ellers vil det redusere størrelsen på datasettet, og da vil det ikke være til mye nytte.

Så den kan brukes når manglende data er små, men i virkelige datasett er mengden manglende data alltid stor. Så praktisk talt er fullstendig saksanalyse aldri et alternativ å bruke, selv om du kan bruke den hvis den manglende datastørrelsen er liten.

La oss se bruken av dette på det titaniske datasettet.

Last ned titanic datasettet fra her..

import numpy as np import pandaer som pd titanic = pd.read_csv ('titanic/train.csv') # lag en kopi av titanic datasett data1 = titanic.copy () data1.isnull (). mean ()

Utgang:

PassengerId 0.000000 Overlevde 0.000000 Pclass 0.000000 Navn 0.000000 Kjønn 0.000000 Alder 0.198653 SibSp 0.000000 Parch 0.000000 Billett 0.000000 Billett 0.000000
Kabin  0.771044
Gikk ut på 0.002245 dtype: float64

Hvis vi fjerner alle de manglende observasjonene, vil vi ende opp med et veldig lite datasett, gitt at hytta mangler for 77% av observasjonene.

# sjekk hvor mange observasjoner vi ville droppe print ('totalt antall passasjerer med verdier i alle variabler:', data1.dropna (). form [0]) print ('totalt antall passasjerer i Titanic:', data1.shape [0]) print ('prosentandel data uten manglende verdier:', data1.dropna (). form [0]/ np.float (data1.shape [0]))
totale passasjerer med verdier i alle variabler: 183 totale passasjerer i Titanic: 891
prosentandel data uten manglende verdier: 0.2053872053872054

Så vi har fullstendig informasjon for bare 20% av våre observasjoner i Titanic -datasettet. Dermed ville ikke Komplett saksanalysemetode være et alternativ for dette datasettet.

Middel/ median/ modus for manglende dataimputasjon

Manglende verdier kan også erstattes med gjennomsnittet, medianen eller modusen til variabelen (funksjon). Den er mye brukt i datakonkurranser og i nesten alle situasjoner. Det er egnet å bruke denne teknikken der data mangler på tilfeldige steder og i små proporsjoner.

# tilregne manglende verdier i alder i tog og testsett median = X_train.Age.median () for df i [X_train, X_test]: df ['Age']. fillna (median, inplace = True) X_train ['Age'] .isnull (). sum ()

Utgang:
0

0 representerer at nå har Aldersfunksjonen ingen nullverdier.

Et viktig poeng å vurdere når du gjør imputasjon er at det skal gjøres over treningssettet først og deretter til testsettet. Alle manglende verdier i togsett og testsett skal fylles med verdien som bare hentes fra togsett. Dette hjelper til med å unngå overmontering.

Indikator for manglende verdi for manglende verdiindikasjon

Denne teknikken innebærer å legge til en binær variabel for å indikere om verdien mangler for en bestemt observasjon. Denne variabelen tar verdien 1 hvis observasjonen mangler, eller 0 på annen måte. Men vi må fortsatt erstatte de manglende verdiene i den opprinnelige variabelen, som vi pleier å gjøre med gjennomsnittlig eller median beregning. Ved å bruke disse 2 teknikkene sammen, hvis den manglende verdien har prediktiv kraft, vil den bli fanget opp av den manglende indikatoren, og hvis den ikke gjør det, vil den bli maskert av gjennomsnittet / medianimputasjonen.

X_train ['Age_NA'] = np.where (X_train ['Age']. Isnull (), 1, 0) X_test ['Age_NA'] = np.where (X_test ['Age']. Isnull (), 1, 0) X_train.head ()

Utgang:

data | Funksjonsteknikk
X_train.Age.mean (), X_train.Age.median ()
(29.915338645418327, 29.0)

Siden gjennomsnitt og median er det samme, la oss erstatte dem med medianen.

X_train ['Age']. Fillna (X_train.Age.median (), inplace = True) X_test ['Age']. Fillna (X_train.Age.median (), inplace = True) X_train.head (10)

Så Age_NA -variabelen ble opprettet for å fange mangelen.

Kategorisk koding i Feature Engineering

Kategoriske data er definert som data som bare tar et antall verdier. La oss forstå dette med et eksempel. Parameter Kjønn i et datasett vil ha kategoriske verdier som Mann, Kvinne. Hvis det blir gjort en undersøkelse for å vite hvilken bil folk eier, vil resultatet være kategorisk (fordi svarene vil være i kategorier som Honda, Toyota, Hyundai, Maruti, None, etc.). Så poenget å legge merke til her er at data faller i et fast sett med kategorier.

Hvis du gir dette datasettet med kategoriske variabler direkte til en modell, får du en feilmelding. Derfor må de være kodet. Det er flere teknikker for å gjøre det:

  1. One-Hot-koding (OHE)
  2. Ordinær koding
  3. Antall og frekvenskoding
  4. Målkoding / gjennomsnittlig koding

La oss forstå dem i detalj.

 En-hot-koding

Det er en vanlig teknikk for koding av kategoriske variabler. Det oppretter i utgangspunktet binære variabler for hver kategori som er tilstede i den kategoriske variabelen. Disse binære variablene vil ha 0 hvis den er fraværende i kategorien eller 1 hvis den er tilstede. Hver nye variabel kalles en dummyvariabel eller binær variabel.

Eksempel: Hvis den kategoriske variabelen er Kjønn med etiketter kvinnelig og mannlig, kan to boolske variabler genereres kalt mann og hunn. Mann tar 1 hvis personen er mann eller 0 ellers. Tilsvarende for en kvinnelig variabel. Se denne koden nedenfor for det titaniske datasettet.

pd.get_dummies (data ['Sex']). hode ()
pd.concat ([data ['Sex'], pd.get_dummies (data ['Sex'])], aksen = 1) .head ()

Utgang:

Kjønn hunn
0 mann 0 1
1 hunn 1 0
2 hunn 1 0
3 hunn 1 0
4 mann 0 1

Men du kan se at vi bare trenger en dummyvariabel for å representere den kategoriske variabelen Sex. Så du kan ta det som en generell formel der hvis det er n kategorier, trenger du bare en n-1 dummyvariabel. Så du kan enkelt slippe hvem som helst dummy -variabel. For å få n-1 dummy-variabler bruker du bare dette:

pd.get_dummies (data ['Sex'], drop_first = True) .head ()

Ordinær koding

Hva betyr ordinær? Det betyr ganske enkelt en kategorisk variabel hvis kategorier kan ordnes og det for meningsfylt.

For eksempel er studentens karakterer i en eksamen ordinære. (A, B, C, D, mislykkes). I dette tilfellet er en enkel måte å kode på å erstatte etikettene med et ordinært nummer. Se på prøvekode:

fra sklearn import preprocessing >>> le = preprocessing.LabelEncoder ()
le = preprocessing.LabelEncoder () le.fit (["paris", "paris", "tokyo", "amsterdam"]) le.transform (["tokyo", "tokyo", "paris"]) >>> array ([2, 2, 1] ...) list (le.inverse_transform ([2, 2, 1])) >>> ['tokyo', 'tokyo', 'paris']

Antall og frekvenskoding

I denne kodingsteknikken erstattes kategorier med antallet observasjoner som viser den kategorien i datasettet. Erstatning kan også gjøres med frekvensen av prosentandelen observasjoner i datasettet. Anta at hvis 30 av 100 kjønn er menn, kan vi erstatte mann med 30 eller 0.3.

Denne tilnærmingen brukes populært i datavitenskapskonkurranser, så i utgangspunktet representerer den hvor mange ganger hver etikett vises i datasettet.

Mål / gjennomsnittlig koding

I målkoding, også kalt gjennomsnittskoding, erstatter vi hver kategori av en variabel med middelverdien av målet for observasjonene som viser en bestemt kategori. For eksempel er det en kategorisk variabel “by”, og vi vil forutsi om kunden vil kjøpe en TV forutsatt at vi sender et brev. Hvis 30 prosent av menneskene i byen “London” kjøper TV -en, ville vi erstattet London med 0.3. Så det hjelper med å fange opp litt informasjon om målet på tidspunktet for koding av kategorien, og det utvider heller ikke funksjonsområdet. Derfor kan det også betraktes som et alternativ for koding. Men det kan føre til overmontering på modellen, så vær forsiktig. Se på denne koden for implementering:

importer pandaer som pd # opprett datasettdata = {'CarName': ['C1', 'C2', 'C3', 'C1', 'C4', 'C3', 'C2', 'C1', 'C2' , 'C4', 'C1'], 'Target': [1,0,1,1,1,0,0,1,1,1,0]} df = pd.DataFrame (data) print (df)

Utgang:

Bilnavnmål
0 C1 1
1 C2 0
2 C3 1
3 C1 1
4 C4 1
5 C3 0
6 C2 0
7 C1 1
8 C2 1
9 C4 1
10 C1 0

df.groupby (['CarName']) ['Target']. count ()

Utgang:

Bilnavn
C1 4
C2 3
C3 2
C4 2
Navn: Mål, dtype: int64

df.groupby(['CarName'])['Target'].mean()

Utgang:

Bilnavn
s1 0.750000
s2 0.333333
s3 0.500000
s4 1.000000
Navn: Mål, dtype: float64

Mean_encoded = df.groupby(['CarName'])['Target'].mean().to_dict()

df['CarName'] = df['CarName'].map(Mean_encoded)

print(df)

Bilnavnmål
+0 0.750000 1 XNUMX
+1 0.333333 0 XNUMX
+2 0.500000 1 XNUMX
+3 0.750000 1 XNUMX
+4 1.000000 1 XNUMX
+5 0.500000 0 XNUMX
+6 0.333333 0 XNUMX
+7 0.750000 1 XNUMX
+8 0.333333 1 XNUMX
+9 1.000000 1 XNUMX
+10 0.750000 0 XNUMX

Variabel transformasjon

Maskinlæringsalgoritmer som lineær og logistisk regresjon antar at variablene er normalt fordelt. Hvis en variabel ikke er normalfordelt, er det noen ganger mulig å finne en matematisk transformasjon slik at den transformerte variabelen er Gaussisk. Gaussiske distribuerte variabler øker maskinlæringsalgoritmens ytelse mange ganger.

Ofte brukt matematisk transformasjoner er:

  1. Logaritme transformasjon - logg (x)
  2. Kvadratrotransformasjon - sqrt (x)
  3. Gjensidig transformasjon - 1 / x
  4. Eksponentiell transformasjon - eksp (x)

La oss sjekke disse på titaniske datasettet.

Laster inn numeriske funksjoner i det titaniske datasettet.

cols_reqiuired = ['Age', 'Fare', 'Survived'])
data[cols_reqiuired].head()
Output:
Survived	Age	Fare
0	0	22.0	7.2500
1	1	38.0	71.2833
2	1	26.0	7.9250
3	1	35.0	53.1000
4	0	35.0	8.0500

Først må vi fylle ut manglende data. Vi starter med å fylle manglende data med et tilfeldig utvalg.

 def impute (data, variabel):
 df = data.copy () df [variabel+'_ tilfeldig'] = df [variabel] # trekk ut den tilfeldige prøven for å fylle na random_sample = df [variabel] .dropna (). prøve (df [variabel] .isnull (). sum (), random_state = 0) random_sample.index = df [df [variabel] .isnull ()]. ​​indeks df.loc [df [variabel] .isnull (), variabel+'_ tilfeldig'] = tilfeldig_eksempel retur df [variabel+' _random '] # fill na data [' Age '] = impute_na (data,' Age ')

For å visualisere fordelingen av aldersvariabelen vil vi plotte histogram og QQ-plott.

def plots (df, variable): plt.figure (figsize = (15,6)) plt.subplot (1, 2, 1) df [variable] .hist () plt.subplot (1, 2, 2) statistikk. probplot (df [variable], dist = "norm", plot = pylab) plt.show () plots (data, 'Alder')

Utgang:

transformasjon | Funksjonsteknikk

Aldersvariabelen er nesten normalfordelt, bortsett fra noen observasjoner på den nedre halen. Du kan også merke en liten skjevhet i histogrammet til venstre.

La oss bruke transformasjonen ovenfor og sammenligne den transformerte aldersvariabelen.

Logaritmisk transformasjon

data ['Age_log'] = np.log (data.Age) plots (data, 'Age_log')

Utgang:

Logritmisk transformasjon

Du kan observere her at logaritmisk transformasjon ikke ga en Gauss-lignende fordeling for Age-kolonne.

Kvadratrotransformasjon - sqrt (x)

data ['Age_sqr'] = data.Alder ** (1/2) plott (data, 'Age_sqr')

Utgang:

sqrt transformasjon

Dette er litt bedre, men fremdeles variabelen er ikke Gauss.

Gjensidig transformasjon - 1 / x

data ['Age_reciprocal'] = 1 / data. Aldersplott (data, 'Age_reciprocal')

Utgang:

gjensidig transformasjon

Denne transformasjonen er heller ikke nyttig for å transformere Age til en normalt distribuert variabel.

Eksponentiell transformasjon - eksp (x)

data ['Age_exp'] = data.Alder ** (1/1.2) plott (data, 'Age_exp')

Utgang:

eksponentiell | Funksjonsteknikk

Denne er den beste av alle transformasjonene ovenfor, på tidspunktet for generering av en variabel som er normalfordelt.

Outlier engineering

Outliers er definert som de verdiene som er uvanlig høye eller lave med hensyn til resten av observasjonene av variabelen. Noen av teknikkene for å håndtere outliers er:

1. Ekstern fjerning

2. Å behandle ekstreme verdier som manglende verdier

3. Outlier -tak

Hvordan identifisere utfall?

For det er den grunnleggende formen for deteksjon en ekstremverdianalyse av data. Hvis fordelingen av variabelen er Gaussisk, vil ekstremer ligge utenfor gjennomsnittet pluss eller minus tre ganger standardavviket til variabelen. Men hvis variabelen ikke er normalfordelt, kan kvantiler brukes. Beregn kvantilene og deretter interkvartilområdet:

Interkvantil er 75. kvantil-25kvantil.

øvre grense: 75. kvantil + (IQR * 1.5)

nedre grense: 25. kvantil - (IQR * 1.5)

Så, outlier vil sitte utenfor disse grensene.

 Ekstern fjerning

I denne teknikken kan du ganske enkelt fjerne observasjoner fra utsiden fra datasettet. I datasett hvis det ikke finnes store utfall, vil ikke slippe utfallene påvirke dataene særlig. Men hvis flere variabler har outliers, kan vi ende opp med å fjerne en stor del data fra datasettet vårt. Så dette punktet må tas i betraktning når du slipper ekstremene.

 Å behandle ekstreme verdier

Du kan også behandle utfall som manglende verdier. Men da må også disse manglende verdiene fylles ut. Så for å fylle manglende verdier kan du bruke hvilken som helst av metodene som diskutert ovenfor i denne artikkelen.

 Outlier -tak

Denne prosedyren innebærer å begrense maksimums- og minimumsverdiene til en forhåndsdefinert verdi. Denne verdien kan stammer fra variabelfordelingen. Hvis en variabel er normalfordelt, kan vi begrense maksimums- og minimumsverdiene til gjennomsnittlig pluss eller minus tre ganger standardavviket. Men hvis variabelen er skjev, kan vi bruke inter-kvantile rekkevidde nærhet regel eller cap på de nederste prosentiler.

Dato og tid Feature Engineering

Datovariabler regnes som en spesiell type kategoriske variabler, og hvis de behandles godt, kan de berike datasettet i stor grad. Fra datoen kan vi trekke ut forskjellig viktig informasjon som: Måned, semester, kvartal, dag, ukedag, er det en helg eller ikke, timer, minutter og mange flere. La oss bruke noen datasett og gjøre litt koding rundt det.

For dette vil vi bruke datasettet til utlånsklubben. Last den ned fra her..

Vi bruker bare to kolonner fra datasettet: issue_d og last_pymnt_d.

use_cols = ['issue_d', 'last_pymnt_d'] data = pd.read_csv ('/kaggle/input/lending-club-loan-data/loan.csv', usecols = use_cols, nrows = 10000) data.head () Output : issue_d last_pymnt_d 0 des-2018 feb-2019 1 des-2018 feb-2019 2 des-2018 feb-2019 3 des-2018 feb-2019 4 des-2018 feb-2019

Nå kan analysene dateres i DateTime -format ettersom de er kodet i strenger for øyeblikket.

data['issue_dt'] = pd.to_datetime(data.issue_d)
data['last_pymnt_dt'] = pd.to_datetime(data.last_pymnt_d)
data[['issue_d','issue_dt','last_pymnt_d', 'last_pymnt_dt']].head()
Output: issue_d	issue_dt	last_pymnt_d	last_pymnt_dt
0	Dec-2018	2018-12-01	Feb-2019	2019-02-01
1	Dec-2018	2018-12-01	Feb-2019	2019-02-01
2	Dec-2018	2018-12-01	Feb-2019	2019-02-01
3	Dec-2018	2018-12-01	Feb-2019	2019-02-01
4	Dec-2018	2018-12-01	Feb-2019	2019-02-01

Nå, trekker ut måned fra dato.

data['issue_dt_month'] = data['issue_dt'].dt.month
data[['issue_dt', 'issue_dt_month']].head()
Output: issue_dt issue_dt_month
0	2018-12-01	12
1	2018-12-01	12
2	2018-12-01	12
3	2018-12-01	12
4	2018-12-01	12

Trekker ut kvartal fra dato.

data['issue_dt_quarter'] = data['issue_dt'].dt.quarter
data[['issue_dt', 'issue_dt_quarter']].head()
Output: issue_dt	issue_dt_quarter
0	2018-12-01	4
1	2018-12-01	4
2	2018-12-01	4
3	2018-12-01	4
4	2018-12-01	4

Trekker ut ukedagen fra datoen.

data['issue_dt_dayofweek'] = data['issue_dt'].dt.dayofweek
data[['issue_dt', 'issue_dt_dayofweek']].head()
Output: issue_dt	issue_dt_dayofweek
0	2018-12-01	5
1	2018-12-01	5
2	2018-12-01	5
3	2018-12-01	5
4	2018-12-01	5

Trekker ut ukedagens navn fra datoen.

data['issue_dt_dayofweek'] = data['issue_dt'].dt.weekday_name
data[['issue_dt', 'issue_dt_dayofweek']].head()
Output: issue_dt	issue_dt_dayofweek
0	2018-12-01	Saturday
1	2018-12-01	Saturday
2	2018-12-01	Saturday
3	2018-12-01	Saturday
4	2018-12-01	Saturday

Så dette er bare noen få eksempler med dato og klokkeslett, du kan utforske mer. Slike ting hjelper alltid med å forbedre datakvaliteten.

Slutt notater

I denne artikkelen prøvde jeg å forklare funksjonsteknikk i detalj med noen kodeeksempler på datasettet. Feature engineering er veldig nyttig for å gjøre modellen mer nøyaktig og effektiv. Som et neste trinn kan du prøve ut teknikkene vi diskuterte ovenfor på noen andre datasett for bedre forståelse. Jeg håper du finner denne artikkelen nyttig. La oss koble til Linkedin.

Takk for at du leser hvis du kom hit :).

God koding!

Bildekilder-

  1. Bilde 1 https://onlinecoursebay.com/
  2. Bilde 2 https://www.forbes.com/

Mediene vist i denne artikkelen om rekursjon i Python eies ikke av Analytics Vidhya og brukes etter forfatterens skjønn.

Kilde: https://www.analyticsvidhya.com/blog/2021/09/complete-guide-to-feature-engineering-zero-to-hero/

Tidstempel:

Mer fra Analytics Vidhya