Machine Learning Academy · Oppitunti

Datan muokkaus ja eksploratiivinen data-analyysi

Lataatte raakadatasetin, profiloitte jakaumat ja korrelaatiot, tunnistatte datan laatuongelmat ja dokumentoitte havainnot toistettavassa Jupyter-muistikirjassa.

Oppitunti 2/413 vaihetta

Datan muokkaus ja eksploratiivinen data-analyysi on ilmainen Machine Learning Academy-oppitunti CoddyKitissä. Tämä on oppitunti 2/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Machine Learning Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Machine Learning Academy-kurssilla on yhteensä 4 oppituntia.

Mitä eksploratiivinen data-analyysi on?

Eksploratiivinen data-analyysi (EDA) tarkoittaa aineiston profilointia ennen mallintamista, jotta sen rakenne, jakaumat, suhteet ja laatuongelmat ymmärretään. John Tukeyn käyttöön ottama EDA perustuu yksinkertaiseen periaatteeseen: annetaan datan puhua. EDA:n ohittaminen ja suora siirtyminen mallintamiseen on huonon ongelmanrajauksen jälkeen toiseksi yleisin syy koneoppimisprojektien epäonnistumiseen. EDA estää rakentamasta malleja virheelliselle perustalle.

Lataaminen ja ensimmäinen tarkastelu

Aloittakaa aina rakenteen tarkastelulla: kuinka monta riviä ja saraketta aineistossa on ja mitä tietotyyppejä ne käyttävät? Käyttäkää komentoja df.shape, df.dtypes, df.head() ja df.info(). Etsikää sarakkeita, jotka vaikuttavat numeerisilta mutta on tallennettu object-tyyppisinä (merkkijonoina), sekä sarakkeita, jotka vaikuttavat kategorisilta mutta on koodattu kokonaisluvuiksi. Tietotyyppien ristiriidat aiheuttavat myöhemmin vaikeasti havaittavia virheitä, kun scikit-learn käsittelee kokonaislukuna koodattua luokkaa jatkuvana muuttujana.

import pandas as pd
import numpy as np

# Load dataset
df = pd.read_csv('customer_churn.csv')

print('Shape:', df.shape)
print('\nData types:')
print(df.dtypes)
print('\nFirst 5 rows:')
print(df.head())
print('\nSummary info:')
df.info()

Yksiulotteinen analyysi: jakaumat

Yksiulotteisessa analyysissä tarkastellaan yhtä muuttujaa kerrallaan. Piirtäkää numeerisista piirteistä histogrammit ja laskekaa yhteenvetotilastot (keskiarvo, mediaani, keskihajonta, vinous). Voimakkaasti vinoihin jakaumiin (vinous > 2) auttaa usein logaritmimuunnos ennen mallintamista. Piirtäkää kategorisista piirteistä pylväskaaviot arvojen lukumääristä. Luokat, joita esiintyy alle 1 prosentissa riveistä, voivat aiheuttaa ongelmia one-hot-koodauksessa ja ositetussa jaossa.

import matplotlib.pyplot as plt
import seaborn as sns

fig, axes = plt.subplots(1, 2, figsize=(12, 4))

# Numeric: histogram of account age
df['account_age_days'].hist(bins=40, ax=axes[0])
axes[0].set_title('Account age distribution')
axes[0].set_xlabel('Days')

# Categorical: churn rate by plan type
df.groupby('plan_type')['churned'].mean().plot(kind='bar', ax=axes[1])
axes[1].set_title('Churn rate by plan type')
axes[1].set_ylabel('Churn rate')

plt.tight_layout()
plt.savefig('univariate.png', dpi=150)

Yhteenvetotilastojen taulukko

df.describe() tuottaa jokaisesta numeerisesta sarakkeesta lukumäärän, keskiarvon, keskihajonnan, minimiarvon, kvartiilit ja maksimiarvon. Tarkastelkaa tulosta huolellisesti: maksimiarvo, joka on suuruusluokittain suurempi kuin 99. persentiili, viittaa poikkeavaan havaintoon. Nollan minimiarvo sarakkeessa ”päiviä viimeisestä ostoksesta” voi tarkoittaa, että asiakas teki ostoksen tänään – tai se voi olla puuttuvan tiedon paikka-arvo. Näiden erityistapausten ymmärtäminen ehkäisee huomaamattomia virheitä myöhemmässä esikäsittelyssä.

stats = df.describe(percentiles=[0.01, 0.25, 0.5, 0.75, 0.99])
print(stats.T)  # transpose for readability

# Flag suspicious columns
for col in df.select_dtypes(include='number').columns:
    skew = df[col].skew()
    pct99 = df[col].quantile(0.99)
    max_val = df[col].max()
    if max_val > 5 * pct99:
        print(f'OUTLIER WARNING: {col} — max ({max_val:.1f}) >> 99th pct ({pct99:.1f}), skew={skew:.2f}')

Puuttuvien arvojen analyysi

Puuttuvat arvot on profiloitava ennen imputointia koskevien päätösten tekemistä. Laskekaa null-arvojen prosenttiosuus saraketta kohden komennolla df.isnull().mean(). Sarakkeet, joista yli 50 % arvoista puuttuu, voidaan joutua poistamaan kokonaan. Selvittäkää puuttumisen mekanismi: ovatko arvot puuttuvia täysin satunnaisesti (MCAR) vai puuttuvia ei-satunnaisesti (MNAR) – esimerkiksi poistuman tehneet asiakkaat ovat poistaneet tilitietonsa? MNAR-puuttuvuus itsessään sisältää informaatiota, joten se kannattaa koodata binääriseksi indikaattoriksi.

missing = df.isnull().mean().sort_values(ascending=False)
missing_pct = missing[missing > 0] * 100
print('Missing value percentages:')
print(missing_pct.round(1))

import matplotlib.pyplot as plt
missing_pct.plot(kind='barh', figsize=(8, 5))
plt.xlabel('% missing')
plt.title('Missing values by column')
plt.tight_layout()
plt.savefig('missing.png', dpi=150)

Kaksiulotteinen analyysi: korrelaatiot

Kaksiulotteisessa analyysissä tarkastellaan muuttujaparien välisiä suhteita. Laskekaa numeeristen muuttujien välisistä suhteista korrelaatiomatriisi ja visualisoikaa se lämpökarttana komennolla seaborn.heatmap. Yli 0,95:n korrelaatiot kahden piirteen välillä viittaavat multikollineaarisuuteen – molemmat piirteet sisältävät lähes saman informaation, joten toisen voi poistaa ennustekyvyn kärsimättä. Laskekaa lisäksi piste-biseriaaliset korrelaatiot numeeristen piirteiden ja binäärisen kohteen välillä, jotta ennustekykyisimmät piirteet voidaan tunnistaa heti.

import seaborn as sns
import matplotlib.pyplot as plt

numeric_df = df.select_dtypes(include='number')
corr = numeric_df.corr()

plt.figure(figsize=(10, 8))
sns.heatmap(corr, annot=True, fmt='.2f', cmap='coolwarm', center=0)
plt.title('Correlation matrix')
plt.tight_layout()
plt.savefig('corr_heatmap.png', dpi=150)

# Highest corr pairs (excluding self-correlation)
high_corr = (
    corr.where(np.triu(np.ones(corr.shape), k=1).astype(bool))
    .stack().abs().sort_values(ascending=False)
)
print('Top correlated pairs:')
print(high_corr.head(5))

Kohdemuuttujan analyysi

Analysoikaa kohdemuuttuja aina erikseen. Laskekaa binäärisessä luokittelussa positiivisen luokan osuus (df['churned'].mean()). Alle 5 prosentin tai yli 95 prosentin osuudet viittaavat vakavaan epätasapainoon, joka vaikuttaa algoritmin valintaan ja arviointimetriikoihin. Tarkistakaa regressiokohteiden normaalijakautuneisuus – vinoihin kohteisiin auttaa usein logaritmimuunnos ennen koulutusta. Tämä on erityisen hyödyllistä puupohjaisille malleille, joihin vinous ei vaikuta, mutta lineaarisessa regressiossa muunnos on ratkaiseva.

target = 'churned'
class_dist = df[target].value_counts(normalize=True)
print('Class distribution:')
print(class_dist)
print(f'\nPositive class rate: {df[target].mean():.3f}')
print(f'Imbalance ratio: {class_dist.max() / class_dist.min():.1f}:1')

# Visual
df[target].value_counts().plot(kind='bar')
import matplotlib.pyplot as plt
plt.title('Target class distribution')
plt.ylabel('Count')
plt.xticks([0, 1], ['Retained', 'Churned'], rotation=0)
plt.tight_layout()
plt.savefig('target_dist.png', dpi=150)

Poikkeavien havaintojen tunnistaminen ja käsittely

Poikkeavat havainnot voivat vääristää mallin koulutusta, erityisesti etäisyyteen perustuvissa malleissa (KNN, SVM) ja lineaarisessa regressiossa. Käyttäkää alustavaan tunnistamiseen IQR-menetelmää (merkitkää arvot väliltä [Q1 - 1.5·IQR, Q3 + 1.5·IQR] ulkopuolelta) tai z-arvoa (merkitkää arvot, joilla |z| > 3). Selvittäkää jokaisen merkityn poikkeaman kohdalla, onko kyse tietojen syöttövirheestä, aidosta ääriarvosta vai anturin toimintahäiriöstä. Aidot ääriarvot on säilytettävä; virheet on korjattava tai poistettava.

def iqr_outliers(series):
    Q1, Q3 = series.quantile(0.25), series.quantile(0.75)
    IQR = Q3 - Q1
    lower, upper = Q1 - 1.5 * IQR, Q3 + 1.5 * IQR
    outlier_mask = (series < lower) | (series > upper)
    return outlier_mask, lower, upper

for col in df.select_dtypes(include='number').columns:
    mask, lo, hi = iqr_outliers(df[col])
    n_out = mask.sum()
    if n_out > 0:
        print(f'{col}: {n_out} outliers ({n_out/len(df)*100:.1f}%), '
              f'valid range=[{lo:.2f}, {hi:.2f}]')

Piirreluokan suhdetta kuvaavat kuvaajat

Visualisoikaa luokittelutehtävissä, miten kunkin numeerisen piirteen jakauma eroaa luokkien välillä käyttämällä kohteen mukaan ryhmiteltyä viulukuvaajaa tai laatikko-jana-kuvaajaa. Piirteet, joiden jakaumat erottavat luokat selvästi toisistaan, ovat todennäköisesti ennustekykyisiä. Kategorisista piirteistä kategorioittain ryhmitelty pylväskaavio, joka näyttää poistumaosuuden, paljastaa nopeasti, mitkä kategoriat liittyvät suurempaan riskiin.

import seaborn as sns
import matplotlib.pyplot as plt

fig, axes = plt.subplots(1, 2, figsize=(12, 4))

# Numeric feature vs target: violin plot
sns.violinplot(
    data=df, x='churned', y='account_age_days',
    palette=['#2196F3', '#F44336'], ax=axes[0]
)
axes[0].set_xticklabels(['Retained', 'Churned'])
axes[0].set_title('Account age by churn status')

# Categorical feature vs target: bar plot
df.groupby('plan_type')['churned'].mean().plot(kind='bar', ax=axes[1])
axes[1].set_title('Churn rate by plan type')
axes[1].set_ylabel('Churn rate')
plt.tight_layout()
plt.savefig('feature_target.png', dpi=150)

EDA-havaintojen dokumentointi

EDA-havainnot on dokumentoitava tiimin kanssa jaettuun toistettavasti suoritettavaan Jupyter-muistikirjaan. Dokumentoikaa vähintään seuraavat asiat: poistetut sarakkeet ja poistamisen syyt, sarakekohtaiset imputointipäätökset, poikkeavien havaintojen käsittely, luokkien epätasapainon suuruus, tärkeimmät ennustekykyiset piirteet sekä dataongelmat, jotka on viety data engineering -tiimin käsiteltäviksi. Tästä muistikirjasta tulee myöhemmin mallikortin datan laatua käsittelevä osio, ja se on korvaamaton apu tuotantoympäristön regressioiden selvittämisessä kuukausia myöhemmin.

# EDA findings summary (add as a markdown cell in the notebook)
findings = {
    'dropped_columns': ['customer_id (identifier)', 'last_login_ip (PII, not predictive)'],
    'imputation': {
        'days_since_support_contact': 'median (12% missing, MCAR)',
        'contract_end_days': 'mode (3% missing)'
    },
    'outliers': 'total_spend: 14 values > $50k capped at 99th percentile ($48,200)',
    'class_imbalance': '8.3% churn rate — use SMOTE or class_weight=balanced',
    'top_features': ['days_since_last_purchase', 'total_spend_90d', 'support_tickets'],
    'escalations': ['contract_type column has 847 unmapped legacy codes — check with engineering']
}
for key, val in findings.items():
    print(f'{key}: {val}')

Automaattiset EDA-työkalut

Satoja piirteitä sisältävien suurten aineistojen manuaalinen EDA on epäkäytännöllinen. ydata-profiling (aiemmin pandas-profiling) luo yhdellä funktiokutsulla interaktiivisen HTML-raportin, joka sisältää jokaisen sarakkeen jakaumat, korrelaatiot, puuttuvat arvot ja poikkeamahälytykset. sweetviz tuottaa vertailuraportteja opetus- ja testijakojen tai kohdeluokkien välillä. Käyttäkää näitä lähtökohtana, mutta täydentäkää niitä aina toimialakohtaisilla mukautetuilla kuvaajilla tärkeimmistä piirteistä.

# ydata-profiling: one line EDA report
# pip install ydata-profiling
from ydata_profiling import ProfileReport

profile = ProfileReport(
    df,
    title='Customer Churn EDA Report',
    explorative=True
)
profile.to_file('eda_report.html')
print('Report saved to eda_report.html')

# sweetviz: compare train vs test distribution
# pip install sweetviz
import sweetviz as sv
report = sv.analyze(df, target_feat='churned')
report.show_html('sweetviz_report.html')

Pikatarkistus

Testatkaa, miten hyvin hallitsette tämän oppitunnin Machine Learning with Python -käsitteet.

Oppitunnin yhteenveto

Tässä oppitunnissa opitte, että EDA profiloi jakaumat, suhteet, puuttuvat arvot ja poikkeavat havainnot ennen mallintamista, kaksiulotteinen analyysi (korrelaatiot ja piirre–kohde-kuvaajat) tunnistaa ennustekykyisimmät piirteet ja EDA-havainnot on dokumentoitava toistettavassa muistikirjassa, jotta ne ohjaavat esikäsittelypäätöksiä ja toimivat datan laadun dokumentaationa. Seuraavaksi vertailemme viittä algoritmia samalla käsitellyllä aineistolla mallien valintaturnauksessa.

Aloita maksutta

Opi Python tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
30
Oppitunnit
120

Usein kysytyt kysymykset

Onko oppitunti ”Datan muokkaus ja eksploratiivinen data-analyysi” ilmainen?

Kyllä – oppitunnin ”Datan muokkaus ja eksploratiivinen data-analyysi” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Machine Learning Academy-kurssin, päivitä CoddyKit PROhon. Machine Learning Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Datan muokkaus ja eksploratiivinen data-analyysi”?

Lataatte raakadatasetin, profiloitte jakaumat ja korrelaatiot, tunnistatte datan laatuongelmat ja dokumentoitte havainnot toistettavassa Jupyter-muistikirjassa. Harjoittelet Machine Learning Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Machine Learning Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Machine Learning Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 2/4.

Kuinka kauan ”Datan muokkaus ja eksploratiivinen data-analyysi”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Machine Learning Academy-oppitunnilla?

Kyllä. Jokainen Machine Learning Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Projektin rajaus: ongelman ja onnistumiskriteerien määrittely
  2. Datan muokkaus ja eksploratiivinen data-analyysi
  3. Mallien valintaturnaus: viiden algoritmin vertailu
  4. Lopullisen mallin paketointi, dokumentointi ja esittely
← Takaisin: Machine Learning Academy