1. Sveučilište u Rijeci – Odjel za informatiku
Informacijski i komunikacijski sustavi
Igor Kos
Znanost o podacima: Anaconda – platforma za
analizu podataka u Pythonu
Diplomski rad
Mentor: prof. dr. sc. Maja Matetić
Rijeka, rujan 2016.
2. SAŽETAK
U ovome se radu dubinski analiziraju podaci uporabom dvaju najpopularnijih i besplatnih
alata Pythona i R-a. Za analizu je odabran javno dostupan skup podataka koji opisuje
potrošnju goriva automobila u Sjedinjenim Američkim Državama.
Kroz rad se objašnjava proces pripreme podataka za analizu, sama analiza i grafički prikaz
rezultata u svrhu otkrivanja trendova i uzoraka u potrošnji goriva kroz vrijeme.
Rad je izrađen u obliku priručnika kako bi se što jednostavnije shvatilo i prenijelo znanje,
odnosno kako bi čitatelj vrlo brzo i jednostavno naučio koristiti navedene alate u svrhu
analize bilo kojih podataka. Zbog toga postoji puno označenih kodova koji se koriste za
dobivanje određenih rezultata koji su, kao rezultat tog koda, prikazani slikama.
KLJUČNE RIJEČI
analiza podataka, grafički prikaz rezultata, Python, R, potrošnja goriva, učinkovitost motora
3. SADRŽAJ
Uvod........................................................................................................................................... 1
1. Općenito o dubinskoj analizi podataka.......................................................................... 2
2. Ipython i R ........................................................................................................................ 4
2.1. IPython kroz Anaconda platformu .............................................................................. 4
2.1.1. Paralelno računanje .............................................................................................. 5
2.2. R................................................................................................................................... 5
2.2.1. R okruženje .......................................................................................................... 5
3. Priprema za analizu podataka ........................................................................................ 7
3.1. Prikupljanje podataka za analizu ................................................................................. 7
3.2. Koraci analize.............................................................................................................. 7
3.3. Pandas funkcije – unique i value_counts.................................................................. 10
4. IPython iscrtavanje grafova - ggplot............................................................................. 14
4.1. Priprema..................................................................................................................... 14
4.2. Koraci analize............................................................................................................ 14
2.3. Tehnike analize.......................................................................................................... 20
5. IPython - Istraživanje marki i modela automobila..................................................... 23
5.1. Pandas unique() funkcija za grupiranje i matplotlib za iscrtavanje grafa................. 23
5.2. Functools – reduce().................................................................................................. 24
6. Priprema alata R za rad ................................................................................................ 28
7. Učitavanje, istraživanje i opisivanje podataka............................................................ 29
7.1. Učitavanje podataka u R – fread(), read.csv() i read.table() funkcije ...................... 29
7.2. Istraživanje i opisivanje podataka – nrow(), ncol(), names() i length() funkcije ...... 31
7.2.1. Faktori u R-u ...................................................................................................... 34
7.2.3. Podatkovni okvir ................................................................................................ 34
8. R - plyr i ggplot2 biblioteke............................................................................................ 36
8.1. ddply() i ggplot()........................................................................................................ 36
8.2. table() i subset()......................................................................................................... 37
8.3. typeof() i ggplot – geom_smooth()............................................................................. 39
8.4. ddply, mean i ggplot – geom_smooth() ..................................................................... 40
8.5. ggplot – geom_smooth i facet_wrap.......................................................................... 42
8.6. ggplot – geom_boxplot() i geom_bar()...................................................................... 43
9. Istraživanje modela automobila.................................................................................... 46
Zaključak ................................................................................................................................ 48
Popis literature ....................................................................................................................... 49
Popis slika................................................................................................................................ 50
4. 1
UVOD
U ovome ćemo radu analizirati podatke pomoću dvaju programskih jezika kako bismo
usporedili njihovu brzinu i rezultate obrade. Jezici koje ćemo koristiti su Python, kroz
programsko sučelje Anaconda, i R.
Upoznat ćemo čitatelja s interaktivnom okolinom Pythona, IPythona i IPython
Notebooka. Koristit ćemo mogućnosti analize podataka iz relativno nove, ali moćne Pandas
biblioteke. Pandas nam često omogućuje izvesti složene zadatke s manje linija koda.
R je najpopularniji programski jezik za statistiku i analizu podataka. U ovom radu
ćemo moći vidjeti kako je R izvrstan alat za manipulaciju podataka, analizu, modeliranje,
vizualizaciju te kreiranje korisnih skripti za potrebe izvršavanja analitičkih zadataka.
Podaci koje ćemo koristiti sadrže podatke o potrošnji goriva tijekom vremena za sve
marke i modele automobila u SAD-u, a dostupni su na službenim stranicama njihove Vlade
(http://www.fueleconomy.gov/feg/download.shtml). Ovaj skup podataka sadrži i brojne druge
značajke i atribute automobilskih modela osim potrošnje goriva, pružajući mogućnost da se
podaci skupe i grupiraju kako bismo mogli prepoznati zanimljive trendove i odnose. Podaci
su prikupljani od 1984. godine do danas. Zadnje ažuriranje podataka izvršeno je 17. kolovoza
2016..
Cilj je ovog rada izraditi vodič kroz analizu koja istražuje efikasnosti automobilskog
goriva pomoću navedenih programskih jezika i alata Python i R te usporedba rezultata.
5. 2
1. OPĆENITO O DUBINSKOJ ANALIZI PODATAKA
Dubinska analiza podataka (engl. data mining) je računalni način obrade podataka koji
podrazumijeva razne postupke koji imaju za cilj dobivanje korisnog znanja iz podataka. Naziv
data mining sugerira da se radi o postupcima rudarenja za grumenima znanja u gomilama
podataka (engl. mining for knowledge nuggets in mountains of data).
Osnovu za dubinsku analizu podataka čini konačan skup podataka dobivenih iz nekog procesa
koji se odvija u stvarnom svijetu. Na temelju podataka o procesu koji su dostupni moguće je
izraditi model ponašanja nekog određenoga dijela procesa koji je od interesa. Dubinska
analiza podataka se zbog svoje složenosti treba odvijati na računalu. U teoriji, svaki postupak
dubinske analize podataka ostvariv je i bez računala, no praktično vrijeme potrebno za
njegovo provođenje je u tome slučaju predugo.
Pri analizi nekog procesa pomoću postupaka dubinske analize podataka pretpostavljamo
sljedeće nužne preduvjete:
1) Proces koji analiziramo je malen, ograničen i točno određen dio svijeta
2) Cilj analize je jasan
3) Podaci koji su dostupni dovoljno su kvalitetni za opis procesa
4) Podaci su prikazani u obliku tablice varijabli i objekata
Nužno je da analizirani proces bude ograničen na jedan malen dio svijeta jer su korišteni
računalni postupci prostorno i vremenski zahtjevni. Složenije analize podataka većih procesa
provode snažnija računala, no i ti procesi daju samo točno određeni, ograničeni uvid u stanje
čitavog svijeta. Prije nego što se krene u postupak dubinske analize podataka nužno je znati
točan cilj istraživanja.
Ciljevi analize mogu biti razni: utvrditi zašto korisnici određenog osiguranja prelaze
konkurentskoj tvrtki, koje su značajke elektrokardiograma važne za uspješno predviđanje
poremećaja rada srca, koje skupine namirnica ljudi najčešće kupuju u dućanima, što utječe na
poroznost zemljišta, zašto transformator ne radi onako kako bi trebao, što utječe na odabir
osobnog automobila pri kupnji itd. U svakom slučaju, neophodno je zadati razuman i ostvariv
cilj.
6. 3
Neki autori razlikuju dva stila dubinske analize podataka – nadzirano i nenadzirano učenje.
Nadzirano učenje (eng. directed data mining) podrazumijeva pristup „odozgo prema dolje“ i
koristi se kada analitičar zna što traži ili što želi predvidjeti, stoga se ovaj stil često naziva
prediktivnim modeliranjem. Model je na kraju crna kutija za koju nije važno kako
funkcionira, već davanje dobrih rezultata na testnim podacima. Tu se radi o primjeni znanja
stečenih u prošlosti na budućnost.
S druge je strane, nenadzirano učenje (eng. undirected data mining), koje se često naziva i
deskriptivnim modeliranjem, podrazumijeva pristup „odozdo prema gore“. Ono
podrazumijeva pronalaženje uzoraka koji vrijede za dane podatke, a na osnovu kojih se može
doći do određenih spoznaja o dijelu svijeta koji podaci opisuju. Tek ekspert iz domene
problema koji se istražuje može donositi zaključke o tome koji su uzorci važni te je često
nužna interakcija između eksperta i sustava. Kod ovih je modela važna logika na osnovu koje
sustav pronalazi određeni uzorak te se sustav ne može promatrati kao crna kutija. Ponekad se
događa da se pronađu uzorci koje nije moguće logički objasniti. Deskriptivno se modeliranje
često koristi i kao uvod u prediktivno učenje.
7. 4
2. IPYTHON I R
U ovome ćemo radu koristiti dva najpopularnija jezika i platforme za analizu podataka –
Python i R. Primarni zadatak ovog rada je analizirati podatke uz pomoć Pythona, no kako
bismo mogli procijeniti mogućnosti, brzinu i kvalitetu obrade, iste podatke smo analizirali i
pomoću R-a.
U nastavku ćemo kratko opisati svaki od alata koje koristimo.
2.1. IPython kroz Anaconda platformu
Python je široko korišten, opće namjenski, interpretirajući, dinamični programski jezik.
Njegov dizajn naglašava čitljivost koda, a njegova sintaksa omogućuje programerima
izražavanje kroz manje linija koda prema drugim programski jezicima kao što su C++ ili Java.
Python podržava više programskih paradigmi, uključujući i objektno-orijentirano,
imperativno i funkcionalno programiranje.
Python interpreteri (eng. interpreters) su dostupni za mnoge operativne sustave, omogućujući
Python kodu pokretanje na širokom spektru sustava.
IPython je naredbena ljuštura (eng. command shell) za interaktivno računalstvo u više
programskih jezika, izvorno razvijena za Python programski jezik, koji nudi samoispitivanje,
bogate medije, shell sintaksu, završavanje linija pomoću tab-a i povijest naredbi.
Njegove značajke su:
Interaktivna ljuštura (eng. shell) – terminal
Bilježnica (eng. notebook) kroz web-preglednik s podrškom za kod, tekst,
matematičke izraze, inline prikaz grafova i ostalih medija
Podrška za interaktivnu vizualizaciju podataka
Fleksibilnost, mogućnost ugrađivanja u vlastite projekte
Alati za paralelno računanje
8. 5
2.1.1. Paralelno računanje
IPython se temeljni na arhitekturi koja pruža paralelno i distribuirano računanje. Omogućuje
paralelno razvijanje, pokretanje, ispravljanje grešaka i interaktivno praćenje aplikacija. Otuda
I (interactive) u nazivu IPython. Ova arhitektura apstrahira paralelizam, što daje IPython-u
mogućnost da podrži mnoge različite stilove paralelizma, uključujući:
Jedan program, više podataka (SPMD) paralelizam
Više programa, više podataka (MIMD) paralelizam
Paralelizam podataka
Paralelizam zadataka
2.2. R
R je jezik i programsko okruženje za statističko računarstvo i grafiku. To je GNU projekt
sličan S jeziku i okruženju koji su u Bell Laboratoriesu (bivši AT & T, sada Lucent
Technologies) razvili John Chambers i kolega. R se može smatrati drugačijom
implementacijom od S. Postoje neke važne razlike, ali većina koda pisana za S prolazi
nepromijenjen u R.
R nudi široku paletu statističkih (linearno i nelinearno modeliranje, klasični statistički testovi,
analize kroz vrijeme, klasifikacije, grupiranja) i grafičkih tehnika i vrlo je lako proširiv. S
jezik je često broj jedan prilikom odabira alata za istraživanja u statističkoj metodologiji, dok
R pruža open source putanju za sudjelovanje u tim aktivnostima.
Jedna od prednosti R-a je lakoća s kojom dobro dizajnirane, visoko kvalitetne grafove može
proizvesti, uključujući matematičke simbole i formule gdje je potrebno. Velika pažnja je
posvećena na osnove za manje izbore dizajna grafova, ali korisnik zadržava punu kontrolu
nad grafovima te može iscrtati točno što i kako želi.
2.2.1. R okruženje
R je integrirani paket programskih sadržaja za manipulaciju podacima, izračune i grafičke
prikaze. On uključuje:
Učinkovito rukovanje podacima i skladištenje
Paket operatera za izračune na poljima, pogotovo matrica
9. 6
Velika, koherentna, integrirana zbirka posrednih alata za analizu podataka
Grafičke sadržaje za analizu podataka i prikaz bilo na ekranu ili u tiskanom obliku
Dobro razvijen, jednostavan i učinkovit programski jezik koji uključuje uvjete, petlje,
korisnički definirane rekurzivne funkcije i ulaza i izlaza sadržaja
Izraz je postavljeno kako bi okarakterizirao R kao potpuno planski i koherentni sustav, za
razliku od mnogih drugih softvera za analizu podataka.
R, kao i S, je dizajniran oko pravog računalnog jezika, koji omogućuje korisnicima dodavanje
dodatnih funkcionalnosti definiranjem novih funkcija. Veliki dio sustava je napisan u R
dijalektu od S, što olakšava korisnicima da slijede algoritamske odabire. Za računalno
intenzivnije zadatke, C, C++ i Fortran kod može biti povezan i pozvan za vrijeme izvođenja.
Napredni korisnici mogu pisati C kod kako bi manipulirali R objekte direktno.
Mnogi korisnice doživljavaju R kao o statistički sustav, dok bi R točnije mogao biti opisan
kao okruženje u kojem su implementirane statističke tehnike. R se vrlo jednostavno može
proširiti pomoću osam paketa koji su dostupni kroz R distribucije i još mnogo njih dostupnih
na CRAN skupini web stranica koje pokrivaju širok raspon modernih statistika.
10. 7
3. PRIPREMA ZA ANALIZU PODATAKA
3.1. Prikupljanje podataka za analizu
Prikupljanje podataka ćemo izvršiti kroz sljedećih par koraka:
1. Preuzmite skup podataka sa sljedećeg URL-a:
http://www.fueleconomy.gov/feg/epadata/vehicles.csv.zip
2. Raspakirajte i pohranite datoteku vehicles.csv u direktorij vašeg rada
3. Otvorite sljedeću adresu u web-pregledniku:
http://www.fueleconomy.gov/feg/ws/index.shtml#vehicle
4. Označite i kopirajte sav tekst koji se nalazi ispod vehicle naslova, pod Data
Description, sve do naslova emissions, te ga zalijepite u tekstualnu datoteku pod
imenom varlabels.txt u direktorij vašeg rada. Prvih 5 linija u ovoj datoteci bi trebale
biti:
atvtype - type of alternative fuel or advanced technology vehicle
barrels08 - annual petroleum consumption in barrels for fuelType1 (1)
barrelsA08 - annual petroleum consumption in barrels for fuelType2 (1)
charge120 - time to charge an electric vehicle in hours at 120 V
charge240 - time to charge an electric vehicle in hours at 240 V
3.2. Koraci analize
Nakon preuzetih i pohranjenih podataka ukratko ćemo provjeriti kako nam podaci točno
izgledaju kako bi znali sa čime točno radimo. Za obradu i korištenje svih naredbi koristit
ćemo IPython Notebook.
IPython Notebook je user friendly više nego što je to tradicionalan Python. Kada u komandni
prozor upišete ipython notebook, pokrećete poslužitelja na svom lokalnom računalu.
Ipython Notebook je uistinu web aplikacija koja koristi arhitekturu server-klijent. IPython
Notebook poslužitelj koristi dvoprocesnu jezgrenu arhitekturu sa ZeroMQ-om i Tornadom.
ZeroMQ je inteligentna biblioteka za visoku performansu obavještavanja te pomaže IPythonu
11. 8
upravljati računanjem distribuiranih grupa među ostalim zadacima. Tornado je Pythonov
mrežni okvir (engl. web framework) i asinkrono umreženi modul koji služi IPython Notebook
HTTP zahtjevima. Rad je otvorenog koda (engl. open source) i ako želite možete doprinijeti
izvornom kodu. IPython Notebook omogućuje izvoz svojih bilješki, koje su zapravo samo
tekstualne datoteke ispunjene s JSON, u velikom broju formata koristeći alat naredbenog
retka (engl. command-line tool) pod nazivom nbconvert. Dostupni izvozni formati su
HTML, LaTex, reveal.js HTML slideshows, Markdown, jednostavna Python skripta i
reStructuredText za Sphinx dokumentaciju.
Konačno, tu je i IPython Notebook preglednik (nbviewer) koji je besplatan web servis.
HTML verzije notebook datoteka smještene su na udaljenim serverima (ove poslužitelje
trenutno donira Rackspace).
Ukoliko ste stvorili .ipynb datoteku koju želite podijeliti, možete ju prenijeti na
http://nbviewer.ipython.org/ i neka svijet vidi vaš trud.
Prvo ćemo uvesti potrebne biblioteke pandas, numpy i ggplot dodjeljujući im lokalne
nazive kako bi se pojednostavilo pisanje naredbi na sljedeći način:
import pandas as pd
import numpy as np
from ggplot import *
%matplotlib inline
Sljedeće ćemo uvesti podatke i pogledati prvih nekoliko zapisa:
vehicles = pd.read_csv("vehicles.csv")
vehicles.head
Pritiskom kombinacije Shift + Enter izvršit će se napisana naredba te ćemo dobiti sljedeći
rezultat:
12. 9
Slika 1 - Ispis prvih nekoliko zapisa
Primijetite da se pojavi crvena poruka upozorenja:
C:UsersIgor_Kos_CeckaAnaconda3libsite-packagesIPythoncoreint
eractiveshell.py:2723: DtypeWarning: Columns (70,71,72,73,74,76,79)
have mixed types. Specify dtype option on import or set low_memory=F
alse.
interactivity=interactivity, compiler=compiler, result=result)
To nam govori da stupci 70,71,72,73,74,76,79 sadrže miješane tipove podataka. Zatim
pronalazimo odgovarajuće nazive tih stupaca pomoću sljedeće naredbe:
column_names = vehicles.columns.values
column_names[[70,71,72,73,74,76,79]]
Rezultat naredbe je:
array(['fuelType2', 'rangeA', 'evMotor', 'mfrCode',
'c240Dscr', 'c240bDscr', 'startStop'], dtype=object)
Prema ovim uputama, jednostavno postavljamo naš radni direktorij i kreiramo novi IPython
Notebook koji ćemo koristiti u ovoj analizi. Uvezli smo pandas biblioteku i vrlo brzo pročitali
podatke iz datoteke vehicles.csv izvorno u podatkovni okvir (engl. data frame). Uvozom
pandas biblioteke uštedjeli smo puno vremena.
Napomena: Miješani tipovi podataka mogli bi biti problematični, zato zapamtite nazive
tih stupaca. Na čišćenju podataka i pretprocesiranju često se izgubi 90% radnog vremena.
13. 10
Iako smo direktno uvezli podatke odvojene zarezom u okvir podataka, pandas je sposoban
rukovati i mnogim drugim formatima, uključujući Excel, HDF, SQL, JSON, Stata, pa čak i
međuspremnikom koristeći funkciju reader. Također možemo napisati podatke iz
podatkovnih okvira u puno formata, koristeći funkciju writer, kojoj pristupamo iz
podatkovnog okvira objekta.
Korištenjem vezane metode head koja je dio Data Frame klase u pandas biblioteci, dobili
smo vrlo informativan sažetak podatkovnog okvira, uključujući računanje po stupcu not-null
vrijednosti i računanje različitih tipova podataka preko stupaca.
Okvir podataka je nevjerojatno moćan koncept i struktura podataka. Razmišljanje u okvirima
podataka je kritično za mnoge analize podataka, ali također vrlo različito od razmišljanja o
poljima ili matričnim operacijama.
Uz okvir podataka, svaki stupac predstavlja drugu varijablu ili svojstvo i može biti različite
vrste podataka, kao float, integer, string. Svaki redak podatkovnog okvira je zasebna
opservacija ili instanca s vlastitim skupom vrijednosti. Na primjer, ako svaki redak predstavlja
osobu, stupci mogu biti dob (cijeli broj (engl. integer)) i spol (kategorija (engl. category) ili
znakovni niz (engl. string)). Često ćemo željeti odabrati skup promatranja (retke) koji
odgovaraju određenoj karakteristici (recimo, svi muškarci) i ispitati tu podskupinu.
Podatkovni okvir je konceptualno vrlo sličan tablici u relacijskoj bazi podataka.
3.3. Pandas funkcije – unique i value_counts
Sada kada smo uvezli skup podataka o potrošnji goriva u IPython, sljedeći korak je upoznati
osnovne Pandas funkcionalnosti na tom skupu podataka.
Nastavit ćemo razvijati IPython Notebook što smo već započeli u prethodnim uputama.
1. Moramo doznati koliko zapažanja odnosno redaka se nalazi u našem skupu podataka,
koristeći sljedeću naredbu:
len(vehicles)
Rezultat: 37716
len je funkcija duljine. Prikazuje koliko redaka imamo u našem skupu podataka.
2. Nadalje, trebamo saznati koliko varijabli (stupaca) se nalazi u našem skupu podataka
koristeći naredbu:
14. 11
len(vehicles.columns)
Rezultat: 83
3. Popis imena stupaca dobit ćemo sljedećom naredbom:
print(vehicles.columns)
Rezultat:
Index(['barrels08', 'barrelsA08', 'charge120',
'charge240', 'city08',
'city08U', 'cityA08', 'cityA08U', 'cityCD',
'cityE', 'cityUF', 'co2',
'co2A', 'co2TailpipeAGpm', 'co2TailpipeGpm',
'comb08', 'comb08U',
'combA08', 'combA08U', 'combE', 'combinedCD',
'combinedUF', 'cylinders',
'displ', 'drive', 'engId', 'eng_dscr', 'feScore',
'fuelCost08',
'fuelCostA08', 'fuelType', 'fuelType1',
'ghgScore', 'ghgScoreA',
'highway08', 'highway08U', 'highwayA08',
'highwayA08U', 'highwayCD',
'highwayE', 'highwayUF', 'hlv', 'hpv', 'id',
'lv2', 'lv4', 'make',
'model', 'mpgData', 'phevBlended', 'pv2', 'pv4',
'range', 'rangeCity',
'rangeCityA', 'rangeHwy', 'rangeHwyA', 'trany',
'UCity', 'UCityA',
'UHighway', 'UHighwayA', 'VClass', 'year',
'youSaveSpend', 'guzzler',
'trans_dscr', 'tCharger', 'sCharger', 'atvType',
'fuelType2', 'rangeA',
'evMotor', 'mfrCode', 'c240Dscr', 'charge240b',
'c240bDscr',
'createdOn', 'modifiedOn', 'startStop',
'phevCity', 'phevHwy',
'phevComb'],
dtype='object')
4. Dalje ćemo doznati koliko je jedinstvenih godina uključeno u ovaj skup podataka i
koja je prva, a koja posljednja godina, koristeći sljedeću naredbu:
len(pd.unique(vehicles.year))
Rezultat: 34
min(vehicles.year)
Rezultat: 1984
16. 13
Automatic (A6) 4
Automatic (AV) 4
Auto (AV) 2
Manual(M7) 2
Auto(L4) 2
Auto(L3) 2
Automatic (AM5) 2
Auto (AV-S6) 1
Auto (AV-S8) 1
Auto(AM-S9) 1
Automatic (AM6) 1
Automatic 6spd 1
Auto(A1) 1
Manual 5 spd 1
Name: trany, dtype: int64
Ono što mi želimo znati je koliko automobila koristi automatski mjenjač, a koliko ručni.
Primjećujemo da trany varijabla uvijek počinje sa slovom A kada je u pitanju automatski
mjenjač te sa slovom M kad je u pitanju ručni (engl. manual) mjenjač. Dakle, stvorit ćemo
novu varijablu trany2 koja sadržava prvo slovo trany varijable, a to je string:
vehicles["trany2"] = vehicles.trany.str[0]
pd.value_counts(vehicles.trany2)
Ova naredba daje odgovor koji smo željeli. Vidimo da imamo gotovo duplo više automatskih
mjenjača:
A 25327
M 12378
Name: trany2, dtype: int64
U ovom smo dijelu isprobali neke osnovne funkcionalnosti Pythoa i pandas-a. Koristili
smo dvije različite sintakse (vehicles['trany'] i vehicles.trany) za pristup
varijablama unutar podatkovnog okvira. Također, koristili smo neke od temeljnih pandas
funkcija za istraživanje podataka kao što su to nevjerojatno korisne unique i value_counts
funkcije.
17. 14
4. IPYTHON ISCRTAVANJE GRAFOVA - GGPLOT
Sada ćemo pogledati neka od mjerenja učinkovitosti goriva tijekom vremena i vezu s
ostalim točkama podataka.
4.1. Priprema
Koristit ćemo ggplot. Ukoliko još niste instalirali ggplot paket, otvorite terminal i upišite
sljedeće:
pip install ggplot (ili sudo pip install ggplot)
Pričekajte da se instalacija završi. Nakon što ste to učinili, morate ponovno pokrenuti IPython
Notebook poslužitelj kako biste bili u mogućnosti uvesti ovu novoinstaliranu ggplot
biblioteku.
4.2. Koraci analize
Krenut ćemo u fazu analize sljedećim koracima:
1. Krenimo gledajući postoji li opći trend o tome koliko se MPG (miles per gallon) u
prosjeku mijenja tijekom vremena.
grouped = vehicles.groupby("year")
2. Nadalje, želimo izračunati aritmetičku sredinu triju odvojenih stupaca:
averaged=grouped['comb08','highway08','city08'].agg([np.mean])
To stvara novi podatkovni okvir sa tri stupca koja sadrže aritmetičku vrijednost:
comb08, highway08 i city08. Koristili smo mean funkciju uvezenu iz NumPy (np).
3. Da bismo si olakšali, preimenovat ćemo stupce, a zatim kreirati novi stupac pod
nazivom year koji sadrži indeks podatkovnog okvira.
18. 15
averaged.columns = ['comb08_mean', 'highway08_mean',
'city08_mean']
averaged['year'] = averaged.index
4. Konačno, prikazat ćemo rezultate grafički, dijagramom raspršenja koristeći novi
ggplot paket iz Python biblioteke:
print (ggplot(averaged, aes('year','comb08_mean')) +
geom_point(color='steelblue')+xlab("Year")+ ylab("Average MPG")
+ ggtitle("All cars"))
Rezultat:
Slika 2 - Prosječna potrošnja goriva po godinama
Ovaj graf može biti varljiv budući da hibridni automobili s odličnom kilometražom
postaju sve popularniji. Da vidimo da li možemo filtrirati te automobilske marke.
5. Za uklanjanje hibridnih automobila kreirat ćemo tri logička niza (engl. Boolen array).
Niz criteria1 odabrat će one redove podatkovnog okvira gdje fuelType1 sadrži vrstu
19. 16
goriva Regular Gasoline, Premium Gasoline, i Midgrade Gasoline. Niz criteria2
osigurava da redovi sadrže nulu za fuelType2, a criteria3 osigurava da atvType nije
hibrid. Možemo izvršiti logičku operaciju AND na ova tri niza kako bi odabrali samo
željene redove podatkovnog okvira.
criteria1 = vehicles.fuelType1.isin(["Regular Gasoline",
"Premium Gasoline", "Midgrade Gasoline"])
criteria2 = vehicles.fuelType2.isnull()
criteria3 = vehicles.atvType != "Hybrid"
vehicles_non_hybrid = vehicles[criteria1 & criteria2 &
criteria3]
len(vehicles_non_hybrid)
Rezultat: 34587
6. Grupirali smo nastali podatkovni okvir po godinama i izračunali srednju vrijednost
potrošnje goriva za svaku godinu, što je rezultiralo sljedećim podatkovnim okvirom:
grouped = vehicles_non_hybrid.groupby(['year'])
averaged = grouped['comb08'].agg([np.mean])
print(averaged)
Rezultat:
mean
year
1984 19.121622
1985 19.394686
1986 19.320457
1987 19.164568
1988 19.367607
1989 19.141964
1990 19.031459
1991 18.838060
1992 18.861566
1993 19.137383
1994 19.092632
1995 18.872591
1996 19.530962
1997 19.368000
1998 19.329545
1999 19.239759
2000 19.169345
2001 19.075058
2002 18.950270
20. 17
2003 18.761711
2004 18.967339
2005 19.005510
2006 18.786398
2007 18.987512
2008 19.191781
2009 19.738095
2010 20.466736
2011 20.920652
2012 21.496767
2013 22.330481
2014 22.433128
2015 22.551078
2016 22.877111
2017 22.576923
Na temelju prethodnih podataka vidimo da još uvijek postoji zamjetan porast u
prosjeku MPG-a čak i nakon uklanjanja hibrida.
7. Sljedeće pitanje koje možemo postaviti jest je li u posljednje vrijeme izrađeno manje
automobila s velikim motorima? Ako je, to bi objasnilo porast u prosječnom MPG.
Prvo treba provjeriti imaju li automobili s većim motorima manji MPG. Kako bismo
to provjerili, koristimo se varijablom displ za prikaz obujma motora u litrama. Pandas
nam daje upozorenje o ovoj varijabli koja sadrži više tipova podataka pa ćemo
izračunati jedinstvene displ vrijednosti:
pd.unique(vehicles_non_hybrid.displ)
Rezultat:
array([ 2. , 4.9, 2.2, 5.2, 1.8, 1.6, 2.3, 2.8,
4. , 5. , 3.3,
3.1, 3.8, 4.6, 3.4, 3. , 5.9, 2.5, 4.5,
6.8, 2.4, 2.9,
5.7, 4.3, 3.5, 5.8, 3.2, 4.2, 1.9, 2.6,
7.4, 3.9, 1.5,
1.3, 4.1, 8. , 6. , 3.6, 5.4, 5.6, 1. ,
2.1, 1.2, 6.5,
2.7, 4.7, 5.5, 1.1, 5.3, 4.4, 3.7, 6.7,
4.8, 1.7, 6.2,
8.3, 1.4, 6.1, 7. , 8.4, 6.3, nan, 6.6,
6.4, 0.9])
8. Vidimo da postoje neke vrijednosti koje nisu numeričke – nan vrijednost. Uklonit
ćemo sve retke iz vehicles_non_hybrid podataka koje sadržavaju nan displ vrijednosti,
21. 18
a zatim učiniti isto za varijablu comb08. U tom procesu koristit ćemo metodu astype
kako bi osigurali da je svaka vrijednost tipa float:
criteria = vehicles_non_hybrid.displ.notnull()
vehicles_non_hybrid = vehicles_non_hybrid.loc[criteria,:]
vehicles_non_hybrid.displ =
vehicles_non_hybrid.displ.astype('float')
criteria = vehicles_non_hybrid.comb08.notnull()
vehicles_non_hybrid = vehicles_non_hybrid.loc[criteria,:]
vehicles_non_hybrid.comb08 =
vehicles_non_hybrid.comb08.astype('float')
9. Na temelju rezultata izradit ćemo dijagram raspršenja koristeći ggplot biblioteku:
print (ggplot(vehicles_non_hybrid, aes('displ', 'comb08')) +
geom_point(color='steelblue') + xlab("Engine Displacement") +
ylab("Average MPG") + ggtitle("Gasoline cars"))
Rezultat:
Slika 3 - Potrošnja goriva po veličini motora
22. 19
Čini se da graf potvrđuje negativnu relaciju između potrošnje goriva (MPG) i obujma motora.
Sada se pitamo da li je u posljednje vrijeme izrađeno manje automobila s velikim motorima.
10. Pogledajmo izrađuju li se u posljednjim godinama u prosjeku više manji automobili:
grouped_by_year = vehicles_non_hybrid.groupby(['year'])
avg_grouped_by_year = grouped_by_year['displ',
'comb08'].agg([np.mean])
11. Želimo na istom grafikonu prikazati prosječnu displ vrijednost i prosječnu comb08
vrijednost po godinama (varijabla year) kako bi istražili trendove. Da bismo to učinili,
moramo pretvoriti avg_grouped_by_year iz wide u long format:
avg_grouped_by_year['year'] = avg_grouped_by_year.index
melted_avg_grouped_by_year = pd.melt(avg_grouped_by_year,
id_vars=['year'])
Sada ćemo izraditi grafikon:
p = ggplot(aes(x='year', y='value', color = 'variable_0'),
data=melted_avg_grouped_by_year)
p + geom_point() + facet_wrap("variable_0")
Rezultat:
Slika 4 - Prosjek obujma motora i potrošnje po godinama
23. 20
2.3. Tehnike analize
Vrlo su zanimljive brojne tehnike analize podataka koje su korištene. Prije svega, split-apply-
combine. Kada se analizira skup podataka, često je poželjno grupirati podatke po jednom ili
više svojstava, izvršiti operaciju nad grupiranim podskupima podataka, a zatim rezultate
zajedno svrstati. U ovom poglavlju, naši podaci grupirani su po godinama, prosjecima
različitih varijabli, a zatim su ti rezultati kombinirani.
Dakle, možemo grupirati pandas objekt prema određenim karakteristikama kao u
prvoj liniji koda grouped_by_year = vehicles_non_hybrid.groupby(['year'])
gdje grupiramo retke vehicles_non_hybrid okvira podataka po godinama odnosno varijabli
year. Moramo imati na umu da se grupiranje ne ograničava na grupiranje po jednoj varijabli i
može se stvoriti grupiranje s više obilježja (npr. godina i marka automobila).
Sada kada imamo grouped_by_year objekt, ako želimo, možemo ponavljati kroz grupe:
for (name, group) in grouped_by_year:
print name
print group
Dobit ćemo ispis sa nazivom svake grupe što je u ovom slučaju godina i dobiveni okvir
podataka.
Podaci iz 1984. godine:
1984
barrels08 barrelsA08 charge120 charge240 city08 city08U cityA08
18217 15.695714 0.0 0.0 0.0 18 0.0 0
18218 14.982273 0.0 0.0 0.0 20 0.0 0
18219 21.974000 0.0 0.0 0.0 13 0.0 0
18220 21.974000 0.0 0.0 0.0 13 0.0 0
18221 19.388824 0.0 0.0 0.0 15 0.0 0
cityA08U cityCD cityE ... mfrCode c240Dscr charge240b
18217 0.0 0.0 0.0 ... NaN NaN 0.0
18218 0.0 0.0 0.0 ... NaN NaN 0.0
18219 0.0 0.0 0.0 ... NaN NaN 0.0
18220 0.0 0.0 0.0 ... NaN NaN 0.0
18221 0.0 0.0 0.0 ... NaN NaN 0.0
c240bDscr createdOn modifiedOn
18217 NaN Tue Jan 01 00:00:00 EST 2013 Tue Jan 01 00:00:00 EST 2013
18218 NaN Tue Jan 01 00:00:00 EST 2013 Tue Jan 01 00:00:00 EST 2013
18219 NaN Tue Jan 01 00:00:00 EST 2013 Tue Jan 01 00:00:00 EST 2013
18220 NaN Tue Jan 01 00:00:00 EST 2013 Tue Jan 01 00:00:00 EST 2013
18221 NaN Tue Jan 01 00:00:00 EST 2013 Tue Jan 01 00:00:00 EST 2013
startStop phevCity phevHwy phevComb
24. 21
18217 NaN 0 0 0
18218 NaN 0 0 0
18219 NaN 0 0 0
18220 NaN 0 0 0
18221 NaN 0 0 0
Podaci iz 2017. godine:
2017
barrels08 barrelsA08 charge120 charge240 city08 city08U cityA08
29916 14.330870 0.0 0.0 0.0 20 20.2399 0
29917 14.330870 0.0 0.0 0.0 20 20.0948 0
29918 14.982273 0.0 0.0 0.0 19 19.4394 0
29920 15.695714 0.0 0.0 0.0 19 18.8536 0
29921 15.695714 0.0 0.0 0.0 19 18.7066 0
cityA08U cityCD cityE ... mfrCode c240Dscr charge240b
29916 0.0 0.0 0.0 ... HYX NaN 0.0
29917 0.0 0.0 0.0 ... HYX NaN 0.0
29918 0.0 0.0 0.0 ... HYX NaN 0.0
29920 0.0 0.0 0.0 ... HYX NaN 0.0
29921 0.0 0.0 0.0 ... VGA NaN 0.0
c240bDscr createdOn modifiedOn
29916 NaN Tue Jan 05 00:00:00 EST 2016 Wed May 04 00:00:00 EDT 2016
29917 NaN Tue Jan 05 00:00:00 EST 2016 Wed May 04 00:00:00 EDT 2016
29918 NaN Tue Jan 05 00:00:00 EST 2016 Wed May 04 00:00:00 EDT 2016
29920 NaN Tue Jan 05 00:00:00 EST 2016 Wed May 04 00:00:00 EDT 2016
29921 NaN Tue Jan 05 00:00:00 EST 2016 Wed May 04 00:00:00 EDT 2016
startStop phevCity phevHwy phevComb
29916 N 0 0 0
29917 N 0 0 0
29918 N 0 0 0
29920 N 0 0 0
29921 N 0 0 0
Dalje, koristimo metodu aggregrate na GroupBy objektu pomoću mean funkcije iz NumPy
biblioteke (np.mean). U sljedećem kodu, biramo grupiranje samo jedne varijable, comb08, iz
okvira podataka grouped_by_year:
averaged = grouped['comb08'].agg([np.mean])
U pandas-u, ova robusna split-apply-combine funkcionalnost ugrađena je u biblioteku, a ovo
je bio prikaz samo malog dijela njezinih mogućnosti.
U primjerima je korišten ggplot paket umjesto matplotlib paketa. Paket ggplot2 u R-u
je jedna od njegovih najvećih vrijednosti, dok Python ima djelotvoran ggplot clone.
Nažalost, Pythonova ggplot biblioteka u ovom trenutku još nema u potpunosti razvijene sve
funkcionalnosti. Budući da je Pythonova ggplot biblioteka još uvijek u razvoju, dobro je
25. 22
znati da postoji Pythonova biblioteka koja omogućuje korištenje R-a iz Python programa.
Paket rpy2 (http://rpy.sourceforge.net/rpy2.html) nudi sučelje i niske i visoke
razine za korištenje R-a iz Pythona. Sučelje niske razine je slično R-ovom C API. Sučelje
visoke razine prikazuje R objekte kao instance Pythonovih klasa. Da bi mogli koristiti rpy2,
moramo imati instaliran R na našem sustavu. Bilo koji paket koji se poziva iz Pythona mora
biti dostupan u R-u.
26. 23
5. IPYTHON - ISTRAŽIVANJE MARKI I MODELA AUTOMOBILA
5.1. Pandas unique() funkcija za grupiranje i matplotlib za iscrtavanje
grafa
U nastavku našeg istraživanja ovog skupa podataka, detaljnije ćemo istražiti marke i modele
različitih automobila.
Pogledat ćemo kako nas marke i modeli automobila informiraju o potrošnji goriva kroz
vrijeme. Prvo, pogledajmo frekvenciju marki i modela automobila dostupnih u SAD-u,
koncentrirajući se na 4-cilindarske automobile. Za odabir 4-cilindarskih automobila, prvo
trebamo napraviti jedinstvenu varijablu cylinders da bi vidjeli koje su moguće vrijednosti:
pd.unique(vehicles_non_hybrid.cylinders)
Rezultat:
array([ 4., 12., 8., 6., 5., 10., 2., 3.,
16., nan])
Kada smo unijeli podatke, Pandas nas je upozorio da je nekoliko varijabli „mješovitog“ tipa,
a jedna od tih varijabli je cylinders.
Pretvaramo varijablu cylinders u tip float kako bismo lakše mogli napraviti podskup okvira
podataka:
vehicles_non_hybrid.cylinders =
vehicles_non_hybrid.cylinders.astype('float')
pd.unique(vehicles_non_hybrid.cylinders)
Rezultat:
array([ 4., 12., 8., 6., 5., 10., 2., 3.,
16., nan])
Sada pogledajmo broj marki koje imaju 4-cilindarske automobile preko vremenskog okvira
koji je na raspolaganju:
import matplotlib.pyplot as plt
%matplotlib inline
vehicles_non_hybrid_4 =
vehicles_non_hybrid[(vehicles_non_hybrid.cylinders == 4.0)]
grouped_by_year_4_cylinder =
vehicles_non_hybrid_4.groupby(['year']).make.nunique()
fig = grouped_by_year_4_cylinder.plot()
fig.set_xlabel('Year')
fig.set_ylabel('Number of 4-Cylinder Makes')
print (fig)
27. 24
Prebacili smo se iz ggplot u matplotlib jer pokušavamo grafički prikazati niz
objekata. U Pythonu se smatra lošom formom ako unutar koda imamo nasumično
napisane različite import izraze, stoga ćemo premjestiti import izraz na vrh Ipython
Notebook-a. Ako ponovno pokrenemo IPython Notebook, moramo provjerite da se
prvo izvršavaju import izrazi na vrhu Notebook-a, da bi se ostatak koda uopće
mogao izvesti.
Rezultat:
Slika 5 – 4-cilindrični automobili
Iz grafa možemo vidjeti da je došlo do pada broja marki s 4-cilindarskim motorima na
raspolaganju od 1980. Međutim, ovaj graf može biti pogrešan jer ne znamo da li se
ukupan broj marki po godini promijenio u odnosu na isto razdoblje.
5.2. Functools – reduce()
Pogledat ćemo marke koje su bile na raspolaganju svake godine u ovom istraživanju. Prvo,
želimo pronaći popis marki automobila s 4-cilindarskim motorima koji su bili prisutni svake
godine u ovom istraživanju. Da bismo to učinili, prvo pogledajmo jedinstveni popis marki po
godinama modela:
28. 25
import functools
grouped_by_year_4_cylinder =
vehicles_non_hybrid_4.groupby(['year'])
unique_makes = []
for name, group in grouped_by_year_4_cylinder:
unique_makes.append(set(pd.unique(group['make'])))
unique_makes = functools.reduce(set.intersection, unique_makes)
print (unique_makes)
Rezultat:
{'Honda', 'Subaru', 'Volkswagen', 'Jeep', 'Ford',
'Dodge', 'Chevrolet', 'Mazda', 'Toyota'}
Saznali smo da postoji samo 9 proizvođača koji su izrađivali 4-cilindarske automobile svake
godine tijekom tog razdoblja.
Sada ćemo kreirati jednu praznu listu koja će na kraju biti popunjena Booleovim
vrijednostima. Zatim vršimo ponavljanje na svakom retku u okviru podataka pomoću
iterrows generatora koji daje indeks i redak. Sada ćemo testirati da li je marka automobila
trenutnog retka u unique_makes nizu izračunata ranije i dodati Booleovu vrijednost u
boolean_mask niz. Nakon što se petlja izvrši, podskup spremnika podataka sadrži samo retke
s markama unutar niza unique_makes:
boolean_mask = []
for index, row in vehicles_non_hybrid_4.iterrows():
make = row['make']
boolean_mask.append(make in unique_makes)
df_common_makes = vehicles_non_hybrid_4[boolean_mask]
Sljedeće što moramo je grupirati okvir podataka i po godinama i markama, a zatim izračunati
aritmetičku sredinu za svaku skupinu:
df_common_makes_grouped =
df_common_makes.groupby(['year','make']).agg(np.mean).reset_ind
ex()
Konačno ćemo prikazati rezultate pomoću grafa, zahvaljujući ggplot-u:
ggplot(aes(x='year', y='comb08'), data =
df_common_makes_grouped) + geom_line() + facet_wrap('make')
29. 26
Slika 6 - Proizvođači 4-cilindričnih automobila kroz godine
Postoji nekoliko stvari koje svakako vrijedi istaknuti. Prvo, .reset_index() poziv na kraju
posljednjeg split-apply-combine koraka.
df_common_makes.groupby(['year','make']).agg(np.mean).reset_ind
ex()
Rezultat:
Slika 7 - Grupiranje proizvođača 4-cilindričnih automobila po godinama
Prilikom izvođenja groupby koraka, pandas vraća ključ po kojem su grupirani redci kao
indeks, a ne kao jednostavan stupac podataka. U slučaju više ključeva po kojima se grupiralo,
pandas vraća višerazinski indeks. Nažalost, to neće funkcionirati za ggplot i moramo
narediti pandas-u da tretira te indekse stupaca podataka s .reset_index() metodom.
Zatim, koristili smo for petlju, ponavljanjem na redcima okvira podataka kako bi se utvrdilo
30. 27
je li marka bila na popisu unique_makes. Pandas ima nevjerojatnu količinu ugrađenih
funkcionalnosti, a može ih se izvesti odabirom retka pomoću .isin() metode, kao što je
prikazano u sljedećoj naredbi:
test =
vehicles_non_hybrid_4[vehicles_non_hybrid_4['make'].isin(unique
_makes)]
Ako želimo izvesti korak analize podataka na svom okviru podataka, postoje velike šanse da
već postoji metoda za to. S točke gledišta performansi, učinjena je vrlo očita pogreška u for
petlji, dodavanjem petlje u listu raste veličina liste sa svakom iteracijom. Trebali smo
prethodno alocirati listu na veličinu koliki je broj redaka u spremniku podataka ispunjenih
lažnim Bool-ovim vrijednostima. Prethodna alokacija polja je vrlo općenita tehnika koja
ubrzava kod u većini programskih jezika; ovaj trik je posebno moćan u matplotlib-u. Za
izvršavanje set intersection koji smo koristili da bi se identificirale sve marke prisutne
unutar podataka u svakoj godini, trebali smo niz Python paketa koji je dio Python distribucije.
Ponovno, trebalo bi premjestiti import izraz na vrh skripte kako bi se slijedile najbolje Python
prakse.
31. 28
6. PRIPREMA ALATA R ZA RAD
Za izvršavanje koraka opisanih u ovom dijelu, potrebno je instalirati statistički programski
jezik R na vaše računalo (bilo „base R“ ili „Rstudio“ alat; autor preporuča korištenje izvrsnog
i besplatnog alata koji nudi integriranu razvojnu ljusku za R-jezik, „Rstudio“ alat) i dobaviti
podatkovni skup efikasnosti automobilskog goriva. Ove upute će vam pomoći da osigurate da
imate sve potrebno instalirano i podešeno za izvođenje ovog analitičkog rada.
Potrebna vam je veza za Internet za ovaj korak te se pretpostavlja da ste pribavili i instalirali
„Rstudio“ alat za svoj operacijski sustav, odnosno platformu.
Ukoliko koristite „Rstudio“, potrebno je izvršiti sljedeće korake za podešavanje alata za
potrebe rada:
1. Pokrenite alat „Rstudio“ na svome računalu.
2. U R konzoli, izvršite sljedeće naredbe kojima ćete instalirati R pakete potrebne za ovaj
rad:
install.packages("plyr")
install.packages("ggplot2")
install.packages("reshape2")
install.packages("data.table")
3. Učitajte prethodno instalirane R pakete sljedećim naredbama:
library(plyr)
library(ggplot2)
library(reshape2)
library(data.table)
Paket plyr ćemo koristiti za uzorak podatkovne analize koji počiva na split-apply-combine
postupku, odnosno postupku re-kombinacije podataka, primijenjen na našem podatkovnom
skupu, koji će kasnije biti objašnjen, a ggplot2 će omogućiti značajno lakšu provedbu
vizualizacije kompleksnih podataka.
32. 29
7. UČITAVANJE, ISTRAŽIVANJE I OPISIVANJE PODATAKA
7.1. Učitavanje podataka u R – fread(), read.csv() i read.table() funkcije
Nakon što ste preuzeli i instalirali sve potrebne alate i podatke u prethodnom koraku, možete
učitati podatkovni skup u R alat, ne bi li uradili neke preliminarne analize i stekli dojam o
samim podacima i napravili njihov pregled.
Sljedeći koraci će vas provesti kroz inicijalno uvoženje, odnosno učitavanje podataka u R
okruženje:
1. Prvo, postavite radni direktorij u lokaciju na kojoj ste preuzeli, odnosno pohranili
vehicles.csv.zip datoteku sljedećom naredbom:
setwd("path")
gdje path predstavlja putanju u datotečnom sustavu na kojoj se nalazi dotična
datoteka. Ukoliko koristite Microsoft Windows OS, prilikom specificiranja lokacije
datoteke, koristite „/“ kao delimiter, odnosno terminator znak direktorija, umjesto
klasičnog „“
Primjer: setwd("D:/KOS_DiplomskiRad_2016/Podaci_R")
2. Učitat ćemo naše preuzete podatke i spremiti u varijablu vehicles sljedećom
naredbom:
vehicles <- fread('vehicles.csv')
Ukoliko smo podatke ostavili unutar .zip datoteke tada ih učitavamo na sljedeći način,
ako znam naziv samo datoteke:
vehicles <- read.csv(unz("vehicles.csv.zip", "vehicles.csv"),
stringsAsFactors = F)
3. Ne biste li provjerili uspješnost izvođenja prethodne naredbe, pokušajte prikazati prvih
nekoliko redova podataka koristeći head naredbu:
head(vehicles)
33. 30
Rezultat:
Slika 8 – Rezultat naredbe head(vehicles)
Vidimo da smo ovom naredbom dobili ispis prvih nekoliko redova našeg skupa
podataka.
4. Labels naredba daje oznake varijablama unutar vehicles.csv datoteke. Brzom
inspekcijom datoteke vidimo da su nazivi varijabli i njihova pojašnjenja odvojeni
separatorom -, stoga ćemo učitati datoteku s oznakama, koristeći pritom simbol
povlake „-„ kao separator:
labels <- read.table("varlabels.txt", sep = "-", header =
FALSE)
Rezultat:
Dobijemo grešku –
Error in scan(file = file, what = what, sep = sep, quote
= quote, dec = dec, :
line 11 did not have 2 elements
5. Ukoliko pozorno razmotrimo grešku koju dobijemo, vidjet ćemo da u 11. liniji
podatkovne datoteke se nalaze dva simbola „-„ separatora, te zbog toga se ta linija
rascjepa u 3 dijela, umjesto, kao u drugim linijama, 2 dijela. Zbog toga moramo
promijeniti pristup učitavanja datoteke na način da ignoriramo riječi spojene crticom:
labels <- do.call(rbind, strsplit(readLines("varlabels.txt"), "
- "))
6. Provjerimo uspješnost novog pristupa, odnosno prethodne naredbe koristeći head
funkciju opet:
head(labels)
34. 31
Rezultat:
> head(labels)
[,1] [,2]
[1,] "atvtype" "type of alternative fuel or advanced
technology vehicle"
[2,] "barrels08" "annual petroleum consumption in
barrels for fuelType1 (1)"
[3,] "barrelsA08" "annual petroleum consumption in
barrels for fuelType2 (1)"
[4,] "charge120" "time to charge an electric vehicle in
hours at 120 V"
[5,] "charge240" "time to charge an electric vehicle in
hours at 240 V"
[6,] "city08" "city MPG for fuelType1 (2)"
Pojašnjenje kompleksne naredbe u 5. koraku (izvođenjem njenih sastavnih pod-naredbi):
Prvo, učitajmo datoteku liniju po liniju:
x <- readLines("varlabels.txt")
Svaku liniju potrebno je razdvojiti u znaku „-„. Razmaci su bitni, stoga ne razdvajamo
povlakom spojene riječi (poput one u liniji 11). To rezultira razdvajanjem svake linije u 2
dijela, kao vektor slijeda znakova (string), te vektora spremljenih u jedinstven popis:
y <- strsplit(x, " - ")
Nakon toga, spajamo ove vektore skupa, ne bi li dobili matricu sljedova znakova (stringova),
u kojoj je prvi stupac ime varijable, a drugi opis te iste varijable:
labels <- do.call(rbind, y)
R podržava učitavanje podataka iz čitavog niza formata. Za potrebe ovog rada, učitali smo
podatke iz CSV datoteke, no, mogli smo koristiti kao izvor i Microsoft Excel datoteku
primjerice. CSV datoteke su češći izbor budući da su univerzalno podržane u različitim
operacijskim sustavima i osjetno prenosive. Dodatno, R može učitati podatke od brojnih
popularnih statističkih programa, uključujući SPSS, Stata, te SAS.
7.2. Istraživanje i opisivanje podataka – nrow(), ncol(), names() i length()
funkcije
Nakon što smo učitali podatke o učinkovitosti automobilskog goriva iz pripadnog
podatkovnog skupa u R, slijedeći korak je provođenje određene preliminarne analize
35. 32
podatkovnog skupa. Svrha ove analize je istraživanje izgleda samih podataka i upoznavanje s
nekim od osnovnih naredbi R programskog jezika.
Sljedeći koraci će vas provesti kroz inicijalno istraživanje našeg podatkovnog skupa, u kojima
izračunavamo neke osnovne parametre samog skupa:
1. Prvo, saznajmo koliko instanci podataka (redova) imamo u podatkovnom skupu:
nrow(vehicles)
Rezultat: 37716
2. Zatim, saznajmo koliko varijabli (stupaca) postoji u podatkovnom skupu:
ncol(vehicles)
Rezultat: 83
3. Koristeći name funkciju, napravimo pregled podataka u podatkovnom okviru,
odnosno stupaca koji su prisutni u instancama:
names(vehicles)
Rezultat:
Slika 9 - Rezultat naredbe names(vehicles)
4. Saznajmo koliko jedinstvenih podataka o godinama je uključeno u ovaj podatkovni set
izračunavši vektor jedinstvenih vrijednosti u year stupcu, te nakon toga duljinu
vektora:
length(unique(vehicles$year))
Rezultat: 34
36. 33
5. Koristeći min i max funkcije, odredit ćemo prvu i zadnju godinu za koje postoje
dostupni podaci u skupu:
first_year <- min(vehicles$year)
Rezultat: 1984
last_year <- max(vehicles$year)
Rezultat: 2017
6. Nadalje, saznajmo koji tipovi goriva se koriste kao automobilski primarni tip goriva:
table(vehicles$fuelType1)
Rezultat:
Slika 10 - Rezultat naredbe table(vehicles$fuelType1)
Iz prethodnih rezultata, evidentno je da većina automobila u skupu koriste regular
gasoline tip goriva, a premium gasoline je 2. najčešći primarni tip goriva.
7. Istražimo dalje tip prijenosa koji imaju ovi automobili. Prvo moramo modificirati sve
ntorke koji nemaju definiran taj podatak na način da ih postavimo na NA vrijednost:
vehicles$trany[vehicles$trany == ""] <- NA
8. Budući da je trany stupac tekstualni, te obzirom da želimo provjeriti samo je li
prijenos automatski ili ručni, koristimo subst funkciju za izdvajanje prva 4 znaka iz
trany stupca u svakom redu, te provjeravamo je li ta vrijednost jednaka Auto. Ukoliko
jest, postavljamo novu varijablu, trany2, na vrijednost Auto; u suprotnom vrijednost
postavljamo na Manual:
vehicles$trany2 <- ifelse(substr(vehicles$trany, 1, 4) ==
"Auto", "Auto", "Manual")
9. Naposljetku, konvertiramo novu varijablu u factor tip, te koristimo tabličnu funkciju
za pregled distribucija vrijednosti:
vehicles$trany <- as.factor(vehicles$trany)
table(vehicles$trany2)
Rezultat: Auto Manual
37. 34
25327 12378
7.2.1. Faktori u R-u
Faktori u R-u, konceptualno gledajući, su varijable u R-u koje mogu poprimiti ograničeni broj
različitih vrijednosti; takve varijable često nazivamo kategoričkim. Jedna od najvažnijih
upotreba faktora se ogleda u statističkom modeliranju; budući da kategoričke varijable ulaze u
statističke modele drugačije od kontinuiranih varijabli, spremanje podataka u faktore
osigurava da će funkcije modeliranja tretirati ispravno takve podatke.
7.2.3. Podatkovni okvir
Podatkovni okvir je nevjerojatno moćan podatkovni tip koji R koristi. Podatkovni okvir nam
omogućava grupiranje varijabli različitih tipova podataka (brojčani, stringovi, logički, faktori,
itd.) u redove povezanih informacija. Uzmimo za primjer podatkovni okvir koji sadrži
informacije o kupcima. Svaki red u takvom okviru može sadržavati ime osobe (string), skupa
s dobi (brojčana vrijednost), spolom (faktor), te zastavicom koja indicira je li osoba trenutna
mušterija (logička Boolean vrijednost). Ukoliko ste upoznati s relacijskim bazama podataka,
podatkovni okvir je uvelike sličan samoj tablici, odnosno relaciji u takvoj BP.
Prezentirano je nekoliko načina za dobivanje brzog pregleda podataka, odnosno podatkovnog
skupa kojeg učitavamo u R. Najznačajnije, koristili smo moćnu table funkciju za kreiranje
brojača pojavljivanja vrijednosti za fuelType1 varijablu. Međutim, ova funkcija ima brojne
druge mogućnosti, uključujući i unakrsno tabeliranje, poput:
with(vehicles, table(sCharger, year))
Rezultat:
Slika 11 - Unakrsno tabeliranje
Ovime smo napravili pregled broja modela automobila po godinama, sa i bez turbo punjača
(te je razmjerno vidljivo iz rezultata da turbo punjači su postali popularniji no što su bili u
povijesti). Također, primijetite da koristimo naredbu with. Ova naredba govori R-u da koristi
vehicles kao zadane podatke prilikom izvršavanja sljedeće naredbe, u ovom slučaju table.
38. 35
Zbog toga možemo izostaviti dodavanje imena podatkovnog okvira i automobila ispred
sCharger i year imena stupaca, uz sufiks dolar ($) simbola.
39. 36
8. R - PLYR I GGPLOT2 BIBLIOTEKE
Dosad smo uspješno uvezli podatke u R i pogledali neke važne statistike višeg reda koje su
nam omogućili osnovno razumijevanje tipova vrijednosti u podatkovnom skupu, te učestalosti
pojavljivanja određenih značajki. U ovom dijelu, nastavljamo istraživanje pregledavanjem
nekih metrika učinkovitosti goriva kroz vrijeme, te njihove relacije s drugim podatkovnim
točkama.
Sljedeći koraci će sadržavati korištenje kako plyr biblioteke, tako i biblioteke za crtanje
grafova, ggplot2 za potrebe istraživanja podatkovnog skupa.
8.1. ddply() i ggplot()
Započnimo s ustanovljavanjem ukoliko postoji generalni trend kako se MPG mijenja u
prosjeku kroz vrijeme. Ne bismo li to postigli, koristimo ddply funkciju iz plyr paketa za
dohvaćanje vehicles podatkovnog okvira, agregiranja redova po godini, te onda, za svaku
grupu, izračunavamo prosječnu highway, city i combine fuel učinkovitost. Rezultat, zatim,
pripisujemo novom podatkovnom okviru, mpgByYr. Razdijelimo podatkovni okvir u grupe po
godini, primijenimo funkciju prosjeka određenim varijablama, te naposljetku kombiniramo
rezultate u novi podatkovni okvir:
mpgByYr <- ddply(vehicles, ~year, summarise, avgMPG =
mean(comb08), avgHghy = mean(highway08), avgCity =
mean(city08))
Ne bismo li dobili bolje razumijevanje i pregled ovog novog podatkovnog okvira,
prosljeđujemo ga ggplot funkciji, naređujući joj da iscrta avgMPG varijablu obzirom na
year varijablu, koristeći točke. Dodatno, naznačujemo da želimo oznake osi, naslov te čak i
izglađen uvjetni prosjek ( geom_smooth() ), predstavljen kao zasjenjeno područje grafa:
ggplot(mpgByYr, aes(year, avgMPG)) + geom_point() +
geom_smooth() + xlab("Year") + ylab("Average MPG") +
ggtitle("All cars")
40. 37
Slika 12 - Prosječna potrošnja goriva svih automobila po godinama
8.2. table() i subset()
S obzirom na ovu vizualizaciju, moglo bi se zaključiti da je evidentan trend zamjetnog porasta
u ekonomiji/učinkovitosti goriva automobila prodanih u nekoliko zadnjih godina. Međutim, ta
opservacija može biti ponešto varljiva budući da ima više hibridnih i automobila koji ne
koriste benzin zadnjih godina, što je moguće provjeriti na sljedeći način:
table(vehicles$fuelType1)
Rezultat:
Slika 13 - Podjela broja automobila po vrsti goriva
41. 38
Pogledajmo samo automobile koji koriste benzin, iako velik broj automobila koristi druga
goriva, te ponovno iscrtamo prethodni graf. Da bismo to napravili, koristimo subset
funkciju za kreiranje novog podatkovnog okvira, gasCars, koji sadrži samo redove onih
automobila koji imaju fuelType1 varijablu jednaku podskupu vrijednosti:
gasCars <- subset(vehicles, fuelType1 %in% c("Regular
Gasoline", "Premium Gasoline", "Midgrade Gasoline") & fuelType2
== "" & atvType != "Hybrid")
mpgByYr_Gas <- ddply(gasCars, ~year, summarise, avgMPG =
mean(comb08))
ggplot(mpgByYr_Gas, aes(year, avgMPG)) + geom_point() +
geom_smooth() + xlab("Year") + ylab("Average MPG") +
ggtitle("Gasoline cars")
Slika 14 - Prosječna potrošnja goriva automobila koji koriste benzin
42. 39
8.3. typeof() i ggplot – geom_smooth()
Ukoliko je proizvedeno manje automobila s većim motorima, to se može objasniti rastom
ekonomičnosti. No, za početak, provjerimo imaju li automobili s većim motorima lošiju
iskoristivost goriva. U slučaju da je displ varijabla, koja predstavlja obujam motora u litrama,
tipa string, potrebno ju je pretvoriti u numerički tip, no naša je varijabla tipa double pa ne
trebamo:
typeof(gasCars$displ)
Rezultat: [1] "double"
Posljednji korak je iscrtavanje grafa koji pokazuje ovisnost obujma motora i njegove
učinkovitosti:
ggplot(gasCars, aes(displ, comb08)) + geom_point() +
geom_smooth()
Slika 15 – Ovisnost obujma motora i učinkovitosti
43. 40
Ovaj „dijagram rasipanja“ (engl. scatter plot) nudi uvjerljiv dokaz da postoji negativna, čak i
inverzna korelacija između obujma motora i efikasnosti goriva. Zbog toga manji automobili
imaju tendenciju da budu učinkovitiji u potrošnji goriva.
8.4. ddply(), mean() i ggplot – geom_smooth()
Pogledajmo ukoliko je proizvedeno više manjih automobila zadnjih godina, što bi objasnilo
drastičan porast u ekonomičnosti goriva:
avgCarSize <- ddply(gasCars, ~year, summarise, avgDispl =
mean(displ))
ggplot(avgCarSize, aes(year, avgDispl)) + geom_point() +
geom_smooth() + xlab("Year") + ylab("Average engine
displacement (l)")
Slika 16 – Prosječan obujam motora proizvedenih kroz godine
Vidljivo je iz prethodnog grafa da prosječan obujam motora značajno opada od 2008. godine.
Ne bismo li dobili bolji osjećaj za utjecaj toga na ekonomičnost goriva, možemo naznačiti
44. 41
MPG („miles per gallon“) i obujam po godinama na istom grafu. Koristeći ddply funkciju,
kreiramo novi podatkovni okvir, byYear, koji sadrži podatke o prosječnoj učinkovitosti
goriva, kao i prosječnom obujmu motora po godinama:
byYear <- ddply(gasCars, ~year, summarise, avgMPG =
mean(comb08), avgDispl = mean(displ))
head(byYear)
Rezultat:
Slika 17 - Prosječna potrošnja i obujam motora po godinama
head funkcija nam pokazuje da byYear podatkovni okvir ima 3 stupca: year, avgMPG i
avgDispl. Ukoliko želimo iskoristiti napredna svojstva ggplot2 za prikazivanje Average
MPG i Avg engine displacement by year na zasebnim, ali poravnatim grafovima, moramo
primijeniti melt funkciju nad podatkovnim okvirom, čime ga pretvaramo iz tzv. wide formata
u long format:
byYear2 = melt(byYear, id = "year")
levels(byYear2$variable) <- c("Average MPG", "Avg engine
displacement")
head(byYear2)
Rezultat:
Slika 18 - Rezultat melt funkcije
45. 42
8.5. ggplot – geom_smooth() i facet_wrap()
Ako iskoristimo nrow funkciju, možemo vidjeti da byYear2 podatkovni okvir ima 66 redova,
a da byYear podatkovni okvir ima samo 33. Dva zasebna stupca iz byYear okvira (avgMPG i
avgDispl) su sad spojeni u jedan novi stupac (vrijednost) u byYear2 podatkovnom okviru
naziva variable. Primijetite da varijabilni stupac u byYear2 podatkovnom okviru služi za
identifikaciju stupca kojeg ta vrijednost predstavlja.
Na posljetku ćemo iscrtati graf u kojem ćemo vidjeti usporedbu koju želimo:
ggplot(byYear2, aes(year, value)) + geom_point() +
geom_smooth() + facet_wrap(~variable, ncol = 1, scales
="free_y") + xlab("Year") + ylab("")
Slika 19 - Usporedba prosječne potrošnje sa obujmom motora kroz godine
46. 43
Iz ovog grafa možemo zaključiti sljedeće:
Veličina motora se, generalno gledajući, povećavala do negdje 2008. godine, s naglim
porastom velikih automobila između 2002. i 2010. godine.
Od 2010. godine, postoji trend smanjenja prosječne veličine automobila, što
djelomično objašnjava porast u efikasnosti/ekonomičnosti goriva.
Do 2005. god., postojao je porast prosječne veličine automobila, no učinkovitost
goriva je ostala otprilike konstantna. Čini se da ta činjenica indicira povećanje
učinkovitosti motora s vremenom.
Godine 2006-2010 su zanimljive. Iako se prosječna veličina motora povećala naglo,
MPG vrijednosti su ostale približno iste kao i proteklih godina. To bi potencijalno
zahtijevalo dodatno istraživanje.
8.6. ggplot – geom_boxplot() i geom_bar()
1. Uzevši u obzir trend prema motorima s manjom zapreminom, provjerimo jesu li
učinkovitiji automatski ili ručni prijenosi za motore s 4 cilindra te kako su se
učinkovitosti mijenjale s vremenom:
gasCars4 <- subset(gasCars, cylinders == "4")
ggplot(gasCars4, aes(factor(year), comb08)) + geom_boxplot()+
facet_wrap(~trany2, ncol = 1) + theme(axis.text.x =
element_text(angle = 45)) + labs(x = "Year", y = "MPG")
47. 44
Slika 20 - Usporedba 4-cilindričnih automobila sa automatski i ručnim prijenosom
48. 45
Nadalje, pogledajmo promjenu u veličini automobila s ručnim prijenosom svake godine:
ggplot(gasCars4, aes(factor(year), fill = factor(trany2))) +
geom_bar(position = "fill") + labs(x = "Year", y =
"Proportionof cars", fill = "Transmission") + theme(axis.text.x
=element_text(angle = 45)) + geom_hline(yintercept =
0.5,linetype = 2)
Slika 21 - Omjer automobila s automatski i ručnim prijenosom kroz godine
49. 46
9. ISTRAŽIVANJE MODELA AUTOMOBILA
U ovom dijelu istražit ćemo modele automobila i kako su se mijenjali kroz vrijeme.
Pogledajmo kako modeli auta utječu na efikasnost goriva s vremenom. Prvo, pogledajmo
učestalost modela automobila dostupnih u Americi kroz to vrijeme, te se koncentriramo na
automobile s 4 cilindra:
carsMake<-ddply(gasCars4, ~year, summarise, numberOfMakes
=length(unique(make)))
ggplot(carsMake, aes(year, numberOfMakes)) + geom_point()
+labs(x = "Year", y = "Number of available makes") +
ggtitle("Four cylinder cars")
Slika 22 - Učestalost 4-cilindričnih automobila kroz godine
50. 47
2. Uočavamo da postoji samo 9 proizvođača koji su proizvodili automobile s 4 cilindra
svake godine tijekom dotičnog perioda:
uniqMakes <- dlply(gasCars4, ~year, function(x) unique(x$make))
commonMakes <- Reduce(intersect, uniqMakes)
commonMakes
Slika 23 - Proizvođači 4-cilindričnih motora
3. Uočavamo da je većina proizvođača napredovala u ovom pogledu s vremenom iako
nekolicina proizvođača je demonstrirala prilično oštar skok u učinkovitosti goriva u
zadnjih 5 godina:
carsCommonMakes4 <- subset(gasCars4, make %in% commonMakes)
avgMPG_commonMakes <- ddply(carsCommonMakes4, ~year + make,
summarise, avgMPG = mean(comb08))
ggplot(avgMPG_commonMakes, aes(year, avgMPG)) + geom_line() +
facet_wrap(~make, nrow = 3)
Slika 24 - Proizvođači 4-cilindričnih automobila i njihova potrošnja goriva kroz godine
51. 48
ZAKLJUČAK
Analiza skupova podataka je zanimljivo područje informatike koje napreduje iz dana u dan.
Kroz ovaj rad smo primijetili kako oba alata koja smo koristili su veoma dobra, brza i
efikasna, kako u obradi podataka tako i u samoj vizualizaciji.
Platforma za analizu podataka u Pythonu, Anaconda, je vrlo interaktivna platforma koja
omogućuje svojim korisnicima, studentima i znanstvenicima, lakšu, bržu, jednostavniju i
pregledniju analizu podataka. Sam jezik nije teško naučiti, lako ga se savlada i koristi u svrhe
analize, dok je, za razliku od Pyhtona, R malo teži jer je za isti rezultat obrade potrebno nešto
više koda te razumijevanja istog.
Što se tiče vizualizacije obrađenih podataka, R prednjači Pythonu jer ima par funkcija,
uključenih u grafičku obradu podataka, više nego Python, što dovodi do boljih i jasnijih
grafikona.
Kako su oba jezika i njihove platforme besplatne za korisnike, tako i koriste open source kod
na kojem rade znanstvenici i programeri diljem svijet što dovodi do konstantnog unapređenja
tih alata i jezika i sve boljih rezultata u obradi podataka.
U usporedbi naša dva alata i jezika, R je još uvijek ispred Pythona po preporukama
znanstvenika i rezultatima raznih anketa, no u zadnje vrijeme se vidi povećanje korisnika koji
koriste Python, što dovodi do zaključka da Python brzo i jako kvalitetno napreduje te polako
sustiže R.
Mjesta za napredak u analizi podataka i samim funkcijama alata još uvijek ima što je vrlo
moguće za očekivati od izdavača ovih alata u skorije vrijeme. Kako i količina podataka koja
se analizira raste velikom brzinom tako se i alati moraju prilagođavati okruženju i zahtjevima
svijeta.
52. 49
POPIS LITERATURE
Ojeda T, Murphy SP, Bengfort B, Dasgupta A. Practical Data Science Cookbook. Packt
Publishing Ltd; 2014, (https://www.ebooks-it.net/ebook/practical-data-science-cookbook)
Berry, M.J.A. & Linoff, G.S. (2000)., Mastering Data Mining, Wiley: New York, 2000.
Online priručnik za Python - http://www.tutorialspoint.com/python/index.htm
Online pomoć za korištenje ggplot funkciju - http://ggplot.yhathq.com/
Online priručnik za R - http://www.statmethods.net/management/userfunctions.html
http://www.cyclismo.org/tutorial/R/
http://www.tutorialspoint.com/r/
Online priručnik za napredno korištenje R - http://adv-r.had.co.nz/Functions.html
53. 50
POPIS SLIKA
Slika 1 - Ispis prvih nekoliko zapisa.......................................................................................................................... 9
Slika 2 - Prosječna potrošnja goriva po godinama................................................................................................ 15
Slika 3 - Potrošnja goriva po veličini motora......................................................................................................... 18
Slika 4 - Prosjek obujma motora i potrošnje po godinama ................................................................................... 19
Slika 5 – 4-cilindrični automobili ........................................................................................................................... 24
Slika 6 - Proizvođači 4-cilindričnih automobila kroz godine.................................................................................. 26
Slika 7 - Grupiranje proizvođača 4-cilindričnih automobila po godinama ............................................................ 26
Slika 8 – Rezultat naredbe head(vehicles)............................................................................................................. 30
Slika 9 - Rezultat naredbe names(vehicles)........................................................................................................... 32
Slika 10 - Rezultat naredbe table(vehicles$fuelType1).......................................................................................... 33
Slika 11 - Unakrsno tabeliranje ............................................................................................................................. 34
Slika 12 - Prosječna potrošnja goriva svih automobila po godinama ................................................................... 37
Slika 13 - Podjela broja automobila po vrsti goriva............................................................................................... 37
Slika 14 - Prosječna potrošnja goriva automobila koji koriste benzin................................................................... 38
Slika 15 – Ovisnost obujma motora i učinkovitosti................................................................................................ 39
Slika 16 – Prosječan obujam motora proizvedenih kroz godine............................................................................ 40
Slika 17 - Prosječna potrošnja i obujam motora po godinama ............................................................................. 41
Slika 18 - Rezultat melt funkcije ............................................................................................................................ 41
Slika 19 - Usporedba prosječne potrošnje sa obujmom motora kroz godine........................................................ 42
Slika 20 - Usporedba 4-cilindričnih automobila sa automatski i ručnim prijenosom ............................................ 44
Slika 21 - Omjer automobila s automatski i ručnim prijenosom kroz godine........................................................ 45
Slika 22 - Učestalost 4-cilindričnih automobila kroz godine.................................................................................. 46
Slika 23 - Proizvođači 4-cilindričnih motora .......................................................................................................... 47
Slika 24 - Proizvođači 4-cilindričnih automobila i njihova potrošnja goriva kroz godine ...................................... 47