Aihearkisto: Datan valmistelu

Lineaarinen regressio 3

Jos koneoppiminen ja sklearn (scikit-learn) -kirjasto ovat sinulle täysin uusia, niin lue ennen tätä artikkelia Lineaarinen regressio 1 ja Lineaarinen regressio 2.

Tämän artikkelin ohjelmakoodin ja tulosteet löydät GitHubista:

https://github.com/taanila/tilastoapu/blob/master/linreg3.ipynb

Jos kopioit koodia itsellesi, niin kannattaa käyttää GitHubia. Tästä artikkelista kopioidut koodit eivät välttämättä toimi oikein.

Tämän artikkelin esimerkkidatana käytän sklearn kirjastosta löytyvää dataa Bostonin asuntojen hinnoista. Artikkelin ideat olen lainannut osoitteesta

https://towardsdatascience.com/linear-regression-on-boston-housing-dataset-f409b7e4a155

Ohjelmakirjastojen tuonti

Kuvailevasta analyysistä tutut peruskirjastot ovat tarpeen:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

Datan valmistelu

Lataan esimerkkiaineiston sklearn-kirjastosta seuraavasti:

from sklearn.datasets import load_boston
boston_data = load_boston()

Aineistossa on eroteltu data (features), target (selitettävä muuttuja), feature_names (selittävien muuttujien nimet) ja DESCR (aineiston kuvaus). Tämä selviää keys()-funktiolla:

print(boston_data.keys())

dict_keys([’data’, ’target’, ’feature_names’, ’DESCR’])

Komennolla print(boston_data.DESCR) voit lukea aineiston kuvauksen.

Luon aineiston perusteella boston-nimisen dataframen:

boston = pd.DataFrame(boston_data.data, columns=boston_data.feature_names)
boston['MEDV'] = boston_data.target
boston.head()

linreg9

Selitettävä muuttuja MEDV kuvaa asuntojen mediaanihintoja tuhansina dollareina eri alueilla. Muut muuttujat ovat ehdokkaita mediaanihintaa selittäviksi muuttujiksi (voit lukea lisää aineiston kuvauksesta).

Varmuuden vuoksi kannattaa tarkistaa, onko datassa puuttuvia arvoja:

boston.isnull().sum()

linreg10

Puuttuvia arvoja ei ole, mikä on hyvä asia.

Seuraavaksi katson miten selitettävän muuttujan MEDV arvot ovat jakautuneet. Käytän tarkasteluun seaborn-kirjaston distplot-kuviota ja luokittelen hinnat 30 luokkaan:

sns.distplot(boston['MEDV'], bins=30)

linreg11

Kuvion mukaan asuntojen mediaanihintojen jakauma on oikealle vino. Vinoudesta huolimatta yritetään mallintaa hintoja lineaarisella regressiolla.

Selittävien muuttujien valinnassa voin hyödyntää korrelaatiokertoimia. Seaborn-kirjaston heatmap-funktiolla voin värjätä corr()-funktiolla lasketut korrelaatiokertoimet niiden arvon mukaan. Oletusarvolla heatmap tulostaa vain värilliset ruudut, mutta lisäparametrilla annot=True saan myös korrelaatiokertoimien arvot näkyviin:

correlation_matrix = boston.corr().round(2)
plt.figure(figsize=(12,9))
sns.heatmap(data=correlation_matrix, annot=True)

linreg12

Kaikkein eniten MEDV-muuttujan kanssa korreloivat RM (0,7) ja LSTAT (-0,74). Katson vielä kuvion avulla miltä kyseisten muuttujien korrelaatio MEDV-muuttujan kanssa näyttää. Seuraava koodi toimii vaikka lisäisit enemmänkin muuttujia features-listaan:

features = ['LSTAT', 'RM']
target = boston['MEDV']
plt.figure(figsize=(10, 5))
for i, col in enumerate(features):
   plt.subplot(1, len(features) , i+1)
   plt.scatter(boston[col], target)
   plt.xlabel(col)
   plt.ylabel('MEDV')

linreg13

Riippuvuus on selkeää molemmissa tapauksissa, mutta erityisesti LSTAT-muuttujan kohdalla riippuvuus ei ole täysin suoraviivaista. Tästä huolimatta jatketaan eteenpäin.

Valmistellaan vielä X (features-matriisi) ja y (target) mallintamista varten:

X = boston[['LSTAT', 'RM']]
y = boston['MEDV']

Opetusdata ja testidata

Jos dataa on riittävästi, niin kannattaa jakaa se opetusdataan ja testidataan. Testidatan avulla voidaan arvioida opetusdatan perusteella laadittua mallia. Seuraavassa jaan datan sattumanvaraisesti opetusdataan ja testidataan (20 % datasta). Parametri random_state asettaa satunnaislukugeneraattorin siemenluvun. Jos jätän sen asettamatta, niin saan eri kerroilla erilaisen jaon opetusdataan ja testidataan. Käyttämällä samaa siemenarvoa saan aina saman jaon.

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, 
   test_size = 0.2, random_state=5)
print(X_train.shape)
print(X_test.shape)

(404, 2)
(102, 2)

Huomaan, että opetusdatassa on 404 havaintoa ja testidatassa 102 havaintoa.

Mallin sovitus

Mallin sovitukseen kuuluu LinearRegression-mallin tuonti lineaaristen mallien kirjastosta ja mallin sovitus fit-funktiolla.

from sklearn.linear_model import LinearRegression
malli = LinearRegression()
malli.fit(X_train, y_train)

Tuloksesta näen  mallin lähtötiedot, joita olisin halutessani voinut säätää:

LinearRegression(copy_X=True, fit_intercept=True, n_jobs=1, normalize=False)

Mallin sopivuuden arviointi

Mallin sopivuutta arvioin keskivirheen ja selityskertoimen avulla.

RMSE (root mean squared error) eli keskivirhe lasketaan seuraavasti: lasketaan toteutuneiden havaintojen ja mallin ennustamien arvojen erotusten neliöt yhteen ja jaetaan havaintojen lukumäärällä (mean squared error); lopuksi otetaan neliöjuuri.

Mean squared error löytyy sklearn.metrics-kirjastosta:

from sklearn.metrics import mean_squared_error

y_train_predict = malli.predict(X_train)
rmse = (np.sqrt(mean_squared_error(y_train, y_train_predict)))
r2 = malli.score(X_train,y_train)

print('Mallin sopivuus opetusdataan')
print("--------------------------------------")
print('Keskivirhe: {}'.format(rmse))
print('Selityskerroin: {}'.format(r2))
print("n")

y_test_predict = malli.predict(X_test)
rmse = (np.sqrt(mean_squared_error(y_test, y_test_predict)))
r2 = malli.score(X_test, y_test)

print('Mallin sopivuus testidataan')
print('--------------------------------------')
print('Keskivirhe: {}'.format(rmse))
print('Selityskerroin: {}'.format(r2))

Mallin sopivuus opetusdataan
————————————–
Keskivirhe: 5.6371293350711955
Selityskerroin: 0.6300745149331701

Mallin sopivuus testidataan
————————————–
Keskivirhe: 5.137400784702911
Selityskerroin: 0.6628996975186953

Katson vielä kuviona, miten hyvin ennustaminen onnistuu testidatassa:

plt.scatter(y_test, y_test_predict)
plt.xlabel('y_test')
plt.ylabel('y_test_predict')

linreg14

Malli on sitä parempi, mitä lähempänä suoraa viivaa kuvion pisteet ovat.

Mallin parantaminen

Edellä esimerkkinä laskettu malli on kelvollinen, mutta voisin parantaa mallia monin tavoin:

Asuntojen mediaanihinnat eivät ole normaalisti jakautuneet (jakauma on oikealle vino). Mallin parantamiseksi voisin kokeilla jompaa kumpaa seuraavista:

  • pudotan jakauman yläpään suurimmat mediaanihinnat pois opetusdatasta
  • muunnan mediaanihintoja paremmin normaalijakaumaa vastaaviksi.

Selittävien muuttujien ja mediaanihintojen välinen riippuvuus ei ollut aivan suoraviivainen. Tämä saattaisi korjaantua, jos muunnan mediaanihinnat paremmin normaalijakaumaa vastaaviksi. Tarvittaessa voin tehdä myös selittäville muuttujille muunnoksia tai voin valita malliksi ei-lineaarisen mallin.

Malliin voin myös lisätä selittäviä muuttujia. PTRATIO-muuttujan ottamista selittäväksi muuttujaksi kannattaisi kokeilla.

Jos teen korjauksia malliin, niin voin arvioida korjatun mallin sopivuutta vertaamalla sen keskivirhettä ja selityskerrointa tämän artikkelin malliin.

Data-analytiikka Pythonilla

Päivitetty 4.5.2023

Data-analytiikka antaa vastauksia kysymyksiin

Data-analytiikka on tavoitteellista toimintaa: tavoitteena on etsiä vastauksia kysymyksiin. Data-analytiikan avulla vastataan monenlaisiin kysymyksiin:

  • Minkälainen ikäjakauma asiakkaillamme on?
  • Mihin toimintamme osa-alueisiin asiakkaamme ovat tyytymättömiä?
  • Onko asiakkaan iällä yhteyttä asiakastyytyväisyyteen?
  • Miten yrityksen työilmapiiri on muuttunut viime vuodesta?
  • Ketkä asiakkaistamme ovat vaarassa siirtyä kilpailijalle?
  • Keille tuotteen markkinointikampanja kannattaa suunnata?
  • Mikä mainosvaihtoehdoista tehoaa parhaiten kohderyhmään?
  • Mitä oheistuotteita verkkokaupasta ostaneella kannattaa tarjota?
  • Mikä on tuotteen ennustettu kysyntä ensi kuussa?
  • Liittyykö vakuutuskorvaushakemukseen vakuutuspetos?
  • Millä todennäköisyydellä laina-asiakas ei pysty maksamaan lainaansa takaisin?

Data

Tavoitteiden (kysymykset, joihin halutaan vastata) asettamisen jälkeen pitää selvittää minkälaista dataa tarvitaan. Data voi olla esimerkiksi:

  • Yrityksen tietokannoista löytyvää dataa (esimerkiksi CRM- ja ERP-järjestelmistä).
  • Erilaisten tiedontuottajien tarjoamaa ilmaista tai maksullista dataa.
  • Varta vasten kyselytutkimuksella tai kokeellisella tutkimuksella kerättyä dataa.
  • Erilaisten sensorien/mittalaitteiden automaattisesti tuottamaa dataa.

Blogissani rajoitun rakenteelliseen eli strukturoituun dataan. Rakenteellinen data on sellaista, joka voidaan tallentaa taulukkomuotoon. Yleisiä data-analytiikkaan sopivia tiedostomuotoja ovat pilkkueroteltu tekstimuoto (.csv) ja Excel-muoto (.xlsx). Tietokannoista data haetaan kyselyiden (SQL-kyselykieli) avulla. Nettikyselyohjelmista datan saa yleensä ulos pilkkuerotellussa tekstimuodossa tai Excel-muodossa.

Kun sopiva data on olemassa, niin datasta saadaan vastauksia kysymyksiin seuraavien vaiheiden kautta:

  • Datan valmistelu
  • Kuvaileva analytiikka
  • Selittävä analytiikka; selittävään analytiikkaan liittyy usein tilastollisen merkitsevyyden testaaminen: tilastollinen merkitsevyys kertoo, millä varmuudella otoksessa havaittuja eroja ja riippuvuuksia voidaan yleistää isompaan perusjoukkoon, josta otos on otettu.
  • Ennakoiva analytiikka; tähän käytetään usein koneoppimisen malleja.

Datan valmistelu

Datan valmistelulla tarkoitan datojen yhdistelyä, dataan tutustumista, datan siivoamista ja datan muunnoksia.

Datan valmistelu voi olla data-analytiikan aikaa vievin vaihe. Ensimmäiseksi kannattaa varmistaa datan taulukkomuotoisuus:

  • muuttujien nimet / kenttien nimet / sarakeotsikot ovat ensimmäisellä rivillä
  • datassa ei ole tarpeettomia tyhjiä rivejä tai sarakkeita
  • kuhunkin tilastoyksikköön/havaintoyksikköön liittyvät tiedot ovat yhdellä rivillä.

Datan valmistelu voi sisältää muiden muassa seuraavia:

  • Eri lähteistä peräisin olevien datojen yhdistely
  • Muuttujien uudelleen nimeäminen: jatkotoimet sujuvat sutjakkaammin, jos nimet ovat lyhyitä ja helposti tunnistettavia
  • Desimaalipilkkujen tarkistaminen: vaikka Suomessa desimaalipilkkuna käytetään pilkkua, niin Pythonissa täytyy käyttää pistettä
  • Päivämäärien muuntaminen päivämääriksi tunnistettavaan muotoon
  • Mittayksiköiden tarkistaminen ja tarvittavien muunnosten tekeminen
  • Puuttuvien arvojen käsittely: poistetaanko puuttuvia arvoja sisältävät rivit, korvataanko puuttuvat arvot jollain, miten puuttuvia arvoja merkitään
  • Uusien muuttujien laskeminen: esimerkiksi summamuuttuja useasta mielipidemuuttujasta, tilauksen hinta tilausmäärän ja yksikköhinnan avulla jne.
  • Arvojen luokittelu ja uudelleenkoodaaminen: esimerkiksi ikäluokat iän arvoista.

Kuvaileva analytiikka

Datan kuvailu voi sisältää seuraavia:

  • Lukumäärä- ja prosenttiyhteenvetojen laskeminen kategorisille muuttujille (frekvenssitaulukot)
  • Luokiteltujen jakaumien laskeminen määrällisille muuttujille
  • Tilastollisten tunnuslukujen laskeminen määrällisille muuttujille (keskiarvo, keskihajonta, viiden luvun yhteenveto)
  • Prosenttimuutosten laskeminen aikasarjoille
  • Aikasarjojen tarkastelu viivakaavioina
  • Liukuvien keskiarvojen esittäminen aikasarjojen yhteydessä.

Kuvailun tuloksia kannattaa visualisoida ja havainnollistaa hyvin viimeistellyillä taulukoilla ja kaavioilla.

Selittävä analytiikka ja tilastollinen merkitsevyys

Selittävä analytiikka voi sisältää seuraavia:

  • Tilastollisten tunnuslukujen vertailua eri ryhmissä
  • Kategoristen muuttujien riippuvuuden tarkastelua ristiintaulukoimalla
  • Määrällisten muuttujien välisten korrelaatioiden tarkastelua
  • Havaittujen erojen ja riippuvuuksien tilastollisen merkitsevyyden tarkastelua.

Jos käytetty data on otos isommasta perusjoukosta, niin tulokset kuvaavat otosta. Jos tarkoituksena on arvioida koko perusjoukkoa, niin otoksessa havaittujen erojen ja riippuvuuksien tilastollinen merkitsevyys kertoo, millä varmuudella eroja ja riippuvuuksia voidaan yleistää otoksesta perusjoukkoon.

Ennakoiva analytiikka ja koneoppiminen

Koneoppimisen malleilla voidaan luokitella (asiakkaat luottoriski-asiakkaisiin ja muihin, vakuutuskorvaushakemukset selviin tapauksiin ja petokselta haiskahtaviin, sähköpostiviestit roskapostiin ja kunnollisiin viesteihin jne.) ja ennakoida määrällisen muuttujan arvoja (käytetyn auton hinta, tuleva kysyntä jne.). Koneoppiminen perustuu siihen, että kone oppii käytettävän mallin parametrit olemassa olevasta datasta ja tämän jälkeen mallia voidaan soveltaa uuteen dataan.

Koneoppimisalgoritmit voidaan luokitella  seuraavasti:

  • Ohjattu oppiminen (supervised learning): Algoritmi opetetaan opetusdatalla (training data). Esimerkiksi roskapostisuodatin opetetaan sähköpostidatalla, jossa on erilaisia tietoja kustakin sähköpostiviestistä sekä tieto siitä oliko sähköpostiviesti roskapostia. Tämän datan perusteella muodostuu malli, jota käyttäen tulevista sähköpostiviesteistä voidaan tunnistaa roskapostiviestit.
  • Ohjaamaton oppiminen (Unsupervised learning): Esimerkiksi asiakkaiden jakaminen asiakassegmentteihin asiakastietojen perusteella.
  • Vahvistusoppiminen (Reinforcement learning): Algoritmi suorittaa toimia ja saa niistä palautetta palkkioiden ja rangaistusten muodossa. Algoritmi oppii saamistaan palkkioista ja rangaistuksista. Vahvistettua oppimista käytetään esimerkiksi robotiikassa.

Seuraavassa jaotellaan ohjattu ja ohjaamaton oppiminen edelleen alatyyppeihin:

mallit

Ohjattu oppiminen

Kohdemuuttuja kategorinen

Jos kohdemuuttuja (ennakoitava muuttuja) on kategorinen, niin kyseeseen tulevat luokittelua suorittavat algoritmit, esimerkiksi logistinen regressio tai päätöspuut.

Esimerkkejä, joissa on kategorinen kohdemuuttuja:

  • Roskapostisuodatin: kohdemuuttujana on tieto siitä, onko sähköpostiviesti roskapostia vai ei?
  • Lääketieteellinen diagnoosi: Kohdemuuttujana on tieto siitä, onko tutkitulla potilaalla tietty sairaus vai ei?
  • Vakuutuspetosten tunnistaminen: Kohdemuuttujana on tieto siitä, liittyykö korvaushakemukseen petos vai ei?

Kohdemuuttuja määrällinen

Jos kohdemuuttuja on määrällinen, niin kyseeseen tulevat regressiomallit ja aikasarjaennustamisen menetelmät. Esimerkkejä, joissa on määrällinen kohdemuuttuja:

  • Vanhan osakehuoneiston hinnan arviointi: Kohdemuuttujana on asunnon hinta.
  • Kysynnän ennustaminen aikaisemman kysynnän perusteella: Kohdemuuttujana on kysyntä.

Ohjaamaton oppiminen

Ohjaamattoman oppimisen algoritmi muodostaa mallin suoraan datasta (ei siis ole erillistä opetusdataa, jossa olisi valmiina kohdemuuttujan arvoja). Esimerkkinä asiakassegmenttien määrittäminen asiakasdatan pohjalta. Paljon käytetty algoritmi on k-means clustering.

Jos datassa on paljon muuttujia, jotka mittaavat osittain samoja asioita, niin datan rakennetta voidaan yksinkertaistaa yhdistämällä muuttujia uusiksi lasketuiksi muuttujiksi, joita on vähemmän kuin alkuperäisiä muuttujia. Tunnetuin algoritmi tähän tarkoitukseen on pääkomponenttianalyysi.