Data preprocessing: Imputálás9 perc olvasás

Gondolatok az adat-előkészítés fontosságáról

Az adatelemzői munka első és gyakran legidőigényesebb eleme az adatok előkészítése, ami nagyon fontos feladat, de a modellezői munkával összehasonlítva a többség számára kevésbé vonzó terület, emiatt általában a kevesebb fókusz esik rá, noha ezt a lépést nem tudjuk az elemzéseink során megspórolni. Az írásomban egy rövid példán keresztül mutatom be, hogy lehet az adat-előkészítést R-ben elvégezni. Pontosabban az imputálás folyamatát vezetem végig a cikkben, ami azt jelenti, hogy a hiányzó adatok kezelésébe nyújtok betekintést.

Elég ritka, hogy olyan jól strukturált adattáblákkal dolgozhatunk, amikben minden adat megtalálható, a hiányzó/hiányos adatokat pedig kezelni kell valahogy. Erre számos lehetőség létezik, a teljesség igénye nélkül vegyük sorra a leggyakoribb módszereket:

  1. Kitöröljük a hiányzó sorokat és máris teljes adattáblánk van.
  2. Megpróbáljuk pótolni valahogy a hiányzó elemeket a típusuk alapján:
    1. numerikus változó pótolható:
      • A rendelkezésre álló adatok átlagával
      • A rendelkezésre álló adatok mediánjával
      • Valamilyen modellel készített becsült értékkel
    2. kategorikus változó:
      • A rendelkezésre álló adatok móduszával
      • Valamilyen modellel készített becsült értékkel

Nyilvánvaló, hogy az adatok törlése semmi esetre sem jó megoldás, mert információt veszítünk vele, ha nagyon sok adat hiányzik, akkor gyorsan összezsugorodhat az adattáblánk, amit nem szeretnénk. Tehát valahogy pótolnunk, imputálnunk kell a hiányzó adatokat. Ha rákeresünk az interneten  a különböző adatpótló módszerekre, akkor számos példát láthatunk átlaggal, mediánnal való helyettesítésre, ezért én ezekkel nem foglalkozom. Azért mellékesen megjegyzem, hogy ezek az elemi módszerek sem rosszak, csak kevésbé pontosak, mintha modell segítségével végeznénk a becslést. Másrészt főként kevés adat esetén célravezető a használatuk, amikor nincs értelme modellt készíteni, meg ilyen esetekben jobban indokolható a használatuk, mint egy több tízezer soros megfigyelést tartalmazó fájl esetén.

Miért is érdemes modelleket használnunk az adatpótláshoz? Egyrészt jóval pontosabb becslést adnak, másrészt mindig értelmezhető a becslésük. Például, ha csak egyedi elemeink vannak, akkor a módusz értelmetlen.

Mielőtt a gyakorlati példára rátérünk, megjegyzem, hogy nem csak azzal lehet problémánk, ha hiányos adatok vannak az adattáblában, hanem azzal is, ha nem valósak az adatok, ez sok mindenből következhet, ezt nevezik adatfelvételi hibának. Az adatfelvételi hibára szemléletes példa, ha az egyik ügyfelünkről tudjuk, hogy nincs munkája, hosszú ideje, de a fizetése pedig nagyon magas. A hibás mintaadatok nyilván torzítják a becslésünket, ezért nagyon fontos, hogy megfelelő forrásból szerezzük be az adatokat és ellenőrizzük, hogy a soraink “ésszerűen” legyenek kitöltve. Ezt a problémát jóval nehezebb és körülményesebb kezelni, így ettől a továbbiakban eltekintünk.

Példa: lakásárak

Az adatsor, ami a példát szolgáltatja a kaggle.com oldalról származik, sőt nem én vagyok az első, aki az adatelőkészítési folyamatokat, de úgy gondolom, hogy érdemes  strukturáltan áttekinteni más szemszögből is a feladatot.

Az adatsor 2 919  megfigyelést és 82 változót tartalmaz, amiből 15 424 hiányzik, ez hozzávetőleg az adatok 6,4%-a. Az R segítségével vizuálisan is megjeleníthetjük a hiányzó elemeket és az eloszlásukat is megnézhetjük, amit az alábbi ábrán szemléltetek. (Ahhoz, hogy a kódot el tudjátok készíteni az ábrát és a pótlást két package-re lesz szükségetek, az egyik VIM, a másik a mice package.)

# install.packages('mice')
# install.packages('VIM')
library(mice)
library(VIM)

Elsőként beállítjuk az elérési útvonalat és betöltjük a fájlt, hogy használni tudjuk. Ahhoz, hogy megfelelő formátumú legyen az állomány, ahhoz data.frame formátumúvá kell átalakítanunk, különben nem fogjuk tudni használni.

setwd('C:/Users/User/Desktop/Data Science')
data = read.csv(file = 'house_prices_data.csv', header = T, sep = ',')
#átalakítjuk data.frame formátumra, különben nem fogja tudni használni a mice függvény
data = data.frame(data)

Itt néhány megjegyzést kell tennem. Egyrészt fontos, hogy csak azok a változók maradjanak a modellben, amivel dolgozni szeretnénk, másrészt ha célváltozónkban is vannak hiányzó elemek, akkor két lehetőségünk van. Vagy benne hagyjuk az adattáblában őket és így megbecsüljük az ő értéküket is, így a modellünket esetlegesen a másik modellel becsült értékeken validáljuk, ami véleményem szerint problémákat vet fel a validációval kapcsolatban, vagy kivesszük őket, és azt a célt tűzzük ki, hogy őket szeretnénk megbecsülni. Persze ekkor sem fogunk rajtuk validálni, mert hiányzik a viszonyítási alap, de becslésre alkalmasak lesznek. És természetesen a megmaradt elemeket kezelhetjük mintaként és elvégezhetjük rajtuk a szokásos tanítási-tesztelési metódusokat. Én a bemutatás során az egyszerűsítés kedvéért – ugyanakkor a fenti gondolatmenet alapján helytelenül – minden hiányzó elemet meg fogok becsülni, de belőlük semmilyen következtetést nem lehet és nem is kívánok levonni.

A hiányzó adatokról szemléletes vizualizáció készíthető a VIM packagedzsel.

# elkészítjük a hiányző elemek ábráját
# ehhez kell a VIm package
data_plot = aggr(data, col = c('navyblue','yellow'),
                 numbers = TRUE, sortVars = TRUE,
                 labels = names(data), cex.axis = .7,
                 gap = 3, ylab = c('Missing data','Pattern'))

 


Az aggr függvényben megadhatjuk a színeket, beállíthatjuk az elnevezéseket, feliratokat és még sok minden mást is. Az ábrán jól látszik, hogy a hiányzó adatok többsége az első néhány oszlopban található, majd szórványosan fordulnak csak elő a sárga foltok az ábrán.

Miután ilyen mutatós ábrát készítettünk nézzük meg, hogy az imputálást, hogy is kell megcsinálni, amihez a mice függvényt hívjuk segítségül.

# mice csinálja az imputálást, logikusan a methodot kell jól kiválasztani
# a cart a klasszifikációs és regressziós fa módszert jelenti, ez jó kategórikus és numerikus változókra is
imputed_Data = mice(data, m = 1, maxit = 5, method = 'cart', seed = 500)

A mice függvényben elsőként az imputálandó adattáblát kell megadni data.frame vagy matrix formátumban (különben hibaüzenetet dob a program), majd a becsült elemek számát (m), a maximális iterációk számát (maxiter), a módszertant (method) és érdemes megadni a seed paramétert is, ami azért kell, hogy ha többször futtatjuk a programot, akkor mindig ugyan azokat becsülje meg nekünk.

A függvényben a szokásos módon számos alapbeállítás van, de szerintem az m paramétert érdemes 1-re állítani, mivel csak 1 értéket tudunk majd az eredeti táblába visszailleszteni, így ezzel nem nagyon lehet kísérletezni, ha kizárólag beépített függvényeket szeretnénk használni. A method paraméterről érdemes bővebben beszélni, mivel ez adja meg, hogy milyen módszertannal dolgozik a függvényünk, másrészt nem minden változó becsülhető minden módszertannal. A mice dokumentációjában leírtak szerint sok lehetőség közül választhatunk, de érdemes tisztában lenni a hozzá kapcsolódó statisztikai fogalmakkal. Mivel nem szeretnék minden módszeren végigmenni, ezért csak az adattípusokat értelmezem, ami alapján ízlésünk és célváltozó(i)nk alapján választhatunk módszertant. Tehát a lehetséges kategóriák  (az első 3 viszonylag egyértelmű, de az utolsó 2 több szót érdemel):

  • any : bármilyen változó esetén alkalmazhatjuk, biztosan nem lövünk mellé
  • numeric : csak numerikus változók esetén használható
  • binary : bináris vagy kétértékű változók becslésére alkalmas
  • ordered : azaz sorba rendezett/rendezhető output esetén használjuk, a statisztika szóhasználatával élve legfeljebb sorrendi skálán mérhető célváltozó esetén használatos, ahol van többletinformáció-tartalma a sorrendnek, például az iskolai végzettség esetén (alapfokú, középfokú, felsőfokú végzettség)
  • unordered : nem sorba rendezett változók, tehát a sorrendjük nem számít, ilyenek a nominális skálán mérhető változók, mint például a színek, a kék és a zöld is színek, de nem lehet azt mondani, hogy az egyik jobb a másiknál, legfeljebb személyes ízlésünk miatt preferáljuk az egyiket jobban a másiknál

Ha programozók nyelvére szeretném kicsit jobban lefordítani az ordered és unordered változók eltérését, akkor azt mondanám, hogy tekintsük a factorokat és a factorok különböző szintjei előfordulási formái között szeretnénk eldönteni, hogy rangsorolhatóak-e, ha igen akkor ordered, ha nem akkor unordered változókkal van dolgunk.

Én a cart módszert (klasszifikációs és regressziós fa) módszert választottam, ami any besorolású, azaz mind a kategorikus , mind a numerikus változók esetén használható.

Az utolsó lépés pedig a complete függvény használata és ezzel kész is a teljes adatsorunk.

comp = complete(imputed_Data)
comp

Remélem sikerült árnyaltabban bemutatni az imputálás témáját és egy egyszerű alkalmazási lehetőségét.

Leave a Reply

Your email address will not be published. Required fields are marked *