Ominaisuuksien muuntaminen koneoppimiseen, aloittelijoiden opas

Aluksi opiskelemalla koneoppimismallien optimointia havaitsen usein mallin rakennusvaiheeseen päästyäni, että minun on jatkettava palatakseni uudelleen tietojen tarkistamiseen, jotta voin käsitellä paremmin aineistossa esiintyviä ominaisuustyyppejä. Ajan myötä olen huomannut, että yksi ensimmäisistä askeleista, jotka on toteutettava ennen mallien rakentamista, on tarkistaa huolellisesti tiedoissa olevat muuttujatyypit ja yrittää määrittää etukäteen paras muuntamisprosessi, joka tarvitaan parhaan mahdollisen suorituskyvyn saavuttamiseksi.

Seuraavassa viestissä aion kuvata prosessia, jonka suoritan tunnistamaan ja muuntamaan neljä yleistä muuttujatyyppiä. Aion käyttää tietoaineistoa, joka on otettu sydämen koneoppimiskilpailusta, joka järjestetään https://www.drivendata.org/ verkkosivustolla. Koko aineisto voidaan ladata täältä https://www.drivendata.org/competitions/54/machine-learning-with-a-heart/data/. DrivenData isännöi säännöllisiä verkkohaasteita, jotka perustuvat sosiaalisten ongelmien ratkaisemiseen. Olen viime aikoina alkanut osallistua joihinkin näistä kilpailuista yrittäessään käyttää joitain taitojani hyvään tarkoitukseen ja hankkimaan kokemusta tietojoukoista ja ongelmista, joita en yleensä kohtaa päivittäisessä työssäni.

Muuttujien tyyppien tunnistaminen

Tilastoissa numeeriset muuttujat voidaan jakaa neljään päätyyppiin. Koneoppimisprojektia aloitettaessa on tärkeää määrittää, minkä tyyppinen tieto jokaisessa ominaisuudessa on, sillä tällä voi olla merkittävä vaikutus mallien toimintaan. Olen yrittänyt kuvata yksinkertaisesti alla olevat neljä tyyppiä.

  • Jatkuvat muuttujat ovat muuttujia, joilla voi olla ääretön määrä mahdollisia arvoja toisin kuin erilliset muuttujat, joilla voi olla vain määritetty arvoalue. Esimerkki jatkuvasta muuttujasta olisi autojen ajokilometrien lukumäärä elinkaarensa aikana.
  • Nimellismuuttujat ovat kategoria-arvoja, joilla on vähintään 2 mahdollista arvoa, mutta joissa näiden arvojen järjestyksellä ei ole merkitystä. Esimerkiksi, voimme käyttää numeerista esitystä sellaisten autotyyppien tulkitsemiseksi, jotka sanovat, että kompaktilla on arvo 1, MPV: llä on arvo 2 ja vaihtovelkakirjalainalla on arvo 3. Kuitenkin tosiasia, että kompaktaisella autolla on arvo 1 ja vaihtovelkakirjalainan arvo on 2 ei tarkoita, että matemaattisesti muunnettavissa oleva ryhmä on jollain tavalla suurempi kuin MPV. Se on yksinkertaisesti luokan numeerinen esitys.
  • Kaksikietoiset muuttujat ovat jälleen kategorioita, mutta niillä on vain 2 mahdollista arvoa, yleensä 0 ja 1. Esimerkiksi, voimme luokitella auton omistajuuden arvoksi 1 (tarkoittaen kyllä) tai 0 (tarkoittaen ei). Kun muuntamme muuttujat tyhjiksi sarakkeiksi (mitä teemme myöhemmin tässä postituksessa), tuotetut uudet ominaisuudet muuttuvat myös kaksitahoisiksi.
  • Tavalliset muuttujat ovat samanlaisia ​​kuin nimelliset siinä suhteessa, että niillä on vähintään 2 mahdollista arvoa, ensisijainen ero on, että näillä arvoilla on merkityksellinen järjestys tai sijoitus. Joten autoesimerkissämme tämä saattaa olla jotain moottorin kokoista, jossa nämä luokat voitaisiin järjestää tehon suhteen, 1,2, 1,6, 1,8.

Tietojen valmistelu

Aion käyttää koneoppimistamme sydämen tietoaineiston kanssa muuttujatyyppien tunnistamis- ja muuntamisprosessin läpi. Olen ladannut ja lukenut csv-tiedostot Jupyter-muistikirjaan. Seuraavaksi suoritan seuraavan toiminnon saadaksesi tilannekuvan tietojen koostumuksesta.

tuoda pandat pd-muodossa
def quick_analysis (df):
 tulosta (“tietotyypit:”)
 Tulosta (df.dtypes)
 tulosta (“Rivit ja sarakkeet:”)
 Tulosta (df.shape)
 print (“Sarakkeen nimet:”)
 Tulosta (df.columns)
 tulosta (“Null-arvot:”)
 tulosta (df.apply (lambda x: summa (x.isnull ()) / len (df)))
quick_analysis (juna)

Tämä tuottaa seuraavan tuloksen.

Tämä kertoo minulle, että minulla on pieni vain 180 rivin tietojoukko ja että sarakkeita on 15. Yksi ominaisuuksista on ei-numeerinen, joten se on muunnettava ennen useimpien koneoppikirjastöjen käyttöä. Ei ole nolla-arvoja, joten minun ei tarvitse huolehtia siitä, että käsittelen niitä. Ennen aineiston käsittelyä pudotan myös ”potilaan_id” -sarakkeen, koska se ei ole numeerinen, eikä sitä käytetä missään harjoitus- tai ennustusvaiheessa.

Suoritan sitten pandaiden kuvaustoiminnon tuottamaan nopeasti kuvaavia tilastoja.

train.describe ()

Jotta luokittelisin muuttujatyypit tietojoukossa, suoritan seuraavan koodin, joka tuottaa histogrammit kaikista numeerisista ominaisuuksista. Tuloksena olevasta tuotosta voit helposti nähdä, mitkä ominaisuudet ovat jatkuvia ja kaksisuuntaisia. Jatkuvilla ominaisuuksilla on jatkuva jakaumakuvio, kun taas kaksitahoisissa ominaisuuksissa on vain kaksi palkkia. Nimellis- ja järjestysmuuttujat voivat joskus olla vaikeampia määrittää, ja ne voivat vaatia lisätietoja tietojoukosta tai jotakin erityistä aluetietoa. Tämänkaltaisten koneoppukilpailujen tapauksessa ehdotan, että viitataan kaikkiin mahdollisesti toimitettaviin data sanakirjoihin, jos sellaista ei ole (kuten tässä tapauksessa), jolloin voidaan tarvita yhdistelmä intuitiota sekä kokeilu ja virhe.

Tuo matplotlib.pyplot plt
Junan [train.dtypes [(train.dtypes == "float64") | (train.dtypes == "Int64")]
                        .index.values] .hist (figsize = [11,11])

Olen kuvaillut ominaisuudet neljään tyyppiin alla olevassa taulukossa. Voin nyt tehdä joitain päätöksiä muutosvaiheista, jotka aion suorittaa tietojen valmistelemiseksi koulutusta ja ennustamista varten.

Nukkemuuttujat

Kuten aiemmin tässä viestissä mainittiin, kaikki ei-numeeriset arvot on muunnettava kokonaislukuiksi tai kelluviksi, jotta niitä voidaan käyttää suurimmassa osassa koneoppimiskirjastoja. Pienillä kardinaliteettimuuttujilla paras tapa on kääntää ominaisuus yhdeksi sarakkeeksi ainutlaatuista arvoa kohden 0, jossa arvoa ei ole, ja 1, kun se on. Näihin viitataan näennäismuuttujina.

Tätä tekniikkaa sovelletaan myös parhaiten mihin tahansa nimellismuuttujaan. Koska näillä ei ole luontaista järjestystä, jos emme sovella tätä ensin, koneoppimisalgoritmi voi etsiä väärin suhdetta näiden arvojen järjestyksessä.

Pandalla on mukava toiminto tälle nimeltään get_dummies (). Alla olevassa koodissa olen käyttänyt tätä muuntaaksesi kaikki nimellis- ja ei-numeeriset ominaisuudet uusiksi sarakkeiksi. Tuloksesta voi nähdä, että useita uusia sarakkeita on luotu ja alkuperäiset sarakkeet on pudonnut.

dummy_cols = ['thal', 'chest_pain_type', 'num_major_vessels',
              'exercise_induced_angina', 'fasting_blood_sugar_gt_120_mg_per_dl',
              'resting_ekg_results', 'slope_of_peak_exercise_st_segment']
juna = pd.get_dummies (juna, sarakkeet = dummy_cols)

Ominaisuuksien skaalaus

Tietojoukon jatkuvat muuttujat ovat eri mittakaavassa. Esimerkiksi jos palaat takaisin yllä oleviin histogrammeihin, voit nähdä, että muuttuja “oldpeak_eq_st_depression” vaihtelee välillä 0–6, kun taas “max_heart_rate_achieved” vaihtelee välillä 100–200. Tämä aiheuttaa ongelman monille suosituille koneoppimisalgoritmeille, jotka usein käyttävät Euklidian etäisyyttä. datapisteiden välillä lopullisten ennusteiden tekemiseksi. Kaikkien jatkuvien muuttujien asteikon standardointi voi usein johtaa koneoppimallien suorituskyvyn paranemiseen.

Ominaisuuksien skaalauksen suorittamiseksi pythonissa on useita menetelmiä. Suositeltu tapa on käyttää Sci-Kit Learn MinMaxScaler -toimintoa. Mikä muuttaa asteikon siten, että ominaisuuksien kaikki arvot ovat välillä 0 - 1. Olen sisällyttänyt koodin, joka tekee tämän alla.

sklearn-tuonnin esikäsittelystä
n_test = juna [['serum_cholesterol_mg_per_dl', 'max_heart_rate_achieved',
                'oldpeak_eq_st_depression', 'resting_blood_pressure']]
cols_to_norm = ['seerumin kolesteroliarvo_mg_per_dl', 'max_heart_rate_achieved',
                'oldpeak_eq_st_depression', 'resting_blood_pressure']
x = n_test.arvot
min_max_scaler = esikäsittely.MinMaxScaler ()
x_scaled = min_max_scaler.fit_transform (x)
n_test = pd.DataFrame (x_scaled, sarakkeet = cols_to_norm)
l_test = train.drop (['seerumin kolesterol_mg_per_dl', 'max_heart_rate_achieved',
                'oldpeak_eq_st_depression', 'resting_blood_pressure'], akseli = 1)
juna = pd.concat ([n_test, l_test], akseli = 1)
train.columns

binning

Yllä olevasta koodista huomaat, että en sisällyttänyt jatkuvaa muuttujaa “ikä” ominaisuuden skaalausmuutokseen. Syynä tähän on, että ikä on esimerkki ominaisuustyypistä, joka voi hyötyä muuntamisesta erilliseksi muuttujaksi. Tässä esimerkissä voimme käyttää ämpäriä tai binning-ominaisuutta muuntaaksesi ominaisuuden merkityksellisten luokkien luetteloksi.

Alla olevassa koodissa olen määritellyt intuitiiviset luokat datan jakauman perusteella. Tämä käyttää pandoiden leikkaustoimintoa, joka ottaa luettelon lokeroista, ryhmänimistä ja tietokehyksestä. Tämä toiminto palauttaa alkuperäisen tietokehyksen uudella ”age_categories” -ominaisuudella. Tämä sarake voidaan sitten muuttaa lukuisiksi tyhjiksi sarakkeiksi aikaisemmin kuvatulla menetelmällä.

astiat = [30, 40, 50, 60, 70, 80]
ryhmänimet = ['30 -39 ', '40 -49', '50-59 ', '60-69', '70-79 ']
age_categories = pd.cut (juna ['ikä'], roskakorit, tarrat = ryhmänimet)
juna ['ikäluokat'] = pd.leikkaus (juna ['ikä'], roskakorit, etiketit = ryhmänimet)
age_categories
pd.value_counts (juna [ 'age_categories'])

Meillä on nyt tietojoukko, jossa kaikki sarakkeet ovat ei-numeerisia. Olemme luoneet useita uusia ominaisuuksia ja muuntaneet olemassa olevat ominaisuudet muodoiksi, joiden pitäisi parantaa niiden koneoppimismallien suorituskykyä, joita nyt käytämme. Ominaisuuksien muuntaminen on tärkeä ensimmäinen askel koneoppimisprosessissa, ja sillä voi usein olla merkittävä vaikutus mallin suorituskykyyn. Olen tässä hahmotellut ensimmäisiä vaiheita, jotka suorittaisin prosessissa miettiä loogisesti, miten käsitellä minulla olevia erilaisia ​​muuttujia. Kun olen mallin rakennusvaiheessa, palaan melkein aina takaisin ja säädän tietoja eri menetelmillä yrittääksesi parantaa mallien tarkkuutta. Katson kuitenkin, että noudattamalla näitä vaiheita alussa tämä vähentää usein aikaa, jonka vietän palaamalla muutosvaiheisiin.