import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats
from google.colab import drive
drive.mount('/content/drive')
!gdown 1VIa6to3xMpMbCp2JQKzlGS5LZZ1AsE_H #https://www.kaggle.com/hesh97/titanicdataset-traincsv
# Učitati bazu u DataFrame
df_train = pd.read_csv('titanic_data.csv')
1.1 Upoznavanje sa bazom¶
Prvo da pogledamo kako izgleda skup podataka:
Koji su nazivi obeležja?
Koliko ima uzoraka?
Koja obeležja su numerička, a koja kategorička?
Da li neki podaci nedostaju?
Funkcije shape i info daće nam odgovore na ova pitanja.
head pokazuje prvih nekoliko vrsta iz baze.
shape, info, head¶
df_train.shape
df_train.info()
df_train.head(10)
# proveriti broj i udeo nedostajućih podataka za svako od obeležja
print(df_train.isna().sum())
print(df_train.isna().sum() / df_train.shape[0] * 100)
print(df_train[df_train['Embarked'].isna()])
## only row 61 and 829 do not have an embarked field
##I can probably add those 2 entries manualy or drop them
## za Cabin nam nedostaje >70% pa to moramo odbacit jer nemamo sanse da nekako fill-ujemo na logican nacin
## za Age ke ~20% nedostajucih pa mogu da ubacim median value jer svakako imamo 50-50 sansu da je ta osoba zapravo bila musko/zensko
Razmisliti koji je najbolji način za rešavanje problema nedostajućih podataka u ovom slučaju. Da li treba dopuniti nedostajuće vrednosti obeležja, ili ima više smisla odbaciti neka obeležja i/ili uzorke?
# odbacivanje obeležja
df_train.drop(columns=['Cabin'],inplace=True)
df_train.drop(['PassengerId', 'Name', 'Ticket'], inplace= True, axis = 1) ## ovo su dodatno izbacili
df train ima 12 kolona (12 obeležja od kojih je jedno ID) i 891 uzorak (broj vrsta odnosno putnika).
Za obelezja Age, Cabin i Embarked nedostaju neke vrednosti. S obzirom da za Cabin nedostaje cak preko 75% podataka, to obelezje cemo odbaciti. Obelezje Age ima oko 20% nedostajucih podataka, iako je to bas mnogo, dopunicemo sa medijanom. Obelezje Embarked nedostaje za svega 2 uzorka, tako da cemo odbaciti ta dva uzorka. Obelezja PassengerId i Name, s obzirom da su jedinstvena za svakog putnika, nisu nam korisna u analizi pa ce biti odbacena.
# odbacivanje uzoraka
indexes_with_missing_cabin = df_train[df_train['Embarked'].isna()].index
# print(df_train.drop(indexes_with_missing_cabin))
df_train.drop(indexes_with_missing_cabin,inplace=True)
# dopuna vrednosti
df_train['Age'] = df_train['Age'].fillna(df_train['Age'].median())
# ponovna provera nedostajućih podataka
print(df_train.isna().sum())
Prikazati uporedo raspodele starosti preživelih i preminulih putnika. Takođe, prikazati raspodelu cene karte za te dve grupe putnika. Da li se može doći do nekih zaključaka na osnovu poređenja ove dve raspodele?
# print(df_train[df_train['Survived'] == 1]) ## 340 survived
# print(df_train[df_train['Survived'] == 0]) ## 549 died
# print(df_train[df_train['Survived'] == 0]['Age']) ## age of died ones
plt.hist(df_train[df_train['Survived'] == 0]['Age'],alpha=0.5, label='died')
plt.hist(df_train[df_train['Survived'] == 1]['Age'],alpha=0.5, label='survived')
plt.ylabel('count')
plt.xlabel('age')
plt.legend()
plt.show()
## Prikazati uporedo raspodele starosti preživelih i preminulih putnika.
## Takođe, prikazati raspodelu cene karte za te dve grupe putnika.
plt.hist(df_train[df_train['Survived'] == 0]['Fare'],alpha=0.5, label='died')
plt.hist(df_train[df_train['Survived'] == 1]['Fare'],alpha=0.5, label='survived')
plt.ylabel('count')
plt.xlabel('fare price')
plt.legend()
plt.show()
Prikazati zavisnost cene karte od starosti putnika i od putničke klase. Da li predstavljanje obe navedene zavisnosti grafikom rasipanja donosi korisne informacije? Kojom vrstom grafika je bolje predstaviti drugu traženu zavisnost? Proveriti šta prikazuje funkcija pairplot primenjena na ceo DataFrame.
## Prikazati zavisnost cene karte od starosti putnika i od putničke klase.
# # print(df_train.columns) ## 'Survived', 'Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare','Embarked'
# print(df_train['Pclass'].unique()) ## [3 1 2]
# print(df_train['SibSp'].unique()) ## [1 0 3 4 2 5 8]
# print(df_train['Parch'].unique()) ## [0 1 2 5 3 4 6]
# print(df_train['Embarked'].unique()) ## ['S' 'C' 'Q']
plt.scatter(x=df_train['Age'], y=df_train['Fare'])
plt.xlabel('Age')
plt.ylabel('Fare')
plt.show()
## scatter plot is SHIT
plt.scatter(x=df_train['Age'], y=df_train['Pclass'])
plt.xlabel('Age')
plt.ylabel('Pclass')
plt.show()
## Da li predstavljanje obe navedene zavisnosti grafikom rasipanja donosi korisne informacije?
## Nije dobra ideja koristit scatter plot jer je shit za ovo
## trying to make a graph that shows how many people of what age bought which class
## I failed
# tmp = pd.DataFrame(df_train['Age'].unique())
# print( df_train[df_train['Pclass'] == 1].loc[:,['Age','Pclass']].groupby('Age').count() )
# print( df_train[df_train['Pclass'] == 1].loc[:,['Age','Pclass']].groupby('Age').count().shape )
# print(df_train['Age'].unique().shape)
# print(tmp)
## Kojom vrstom grafika je bolje predstaviti drugu traženu zavisnost?
# print(df_train[df_train['Pclass'] == 1]['Age'])
plt.boxplot( [ df_train[df_train['Pclass'] == 1]['Age'], df_train[df_train['Pclass'] == 2]['Age'], df_train[df_train['Pclass'] == 3]['Age'] ] )
plt.xlabel('Pclass')
plt.ylabel('Age')
plt.show()
## scatter je shit
plt.scatter(x=df_train['Pclass'], y=df_train['Fare'])
plt.xlabel('Pclass')
plt.ylabel('Fare')
plt.show()
plt.boxplot( [ df_train[df_train['Pclass'] == 1]['Fare'], df_train[df_train['Pclass'] == 2]['Fare'], df_train[df_train['Pclass'] == 3]['Fare'] ] )
plt.xlabel('Pclass')
plt.ylabel('Fare')
plt.show()
## Proveriti šta prikazuje funkcija pairplot primenjena na ceo DataFrame.
sns.pairplot(df_train)
1.4 Međusobni odnosi (korelacija) numeričkih varijabli¶
Prikazati korelacionu matricu koristeći toplotnu mapu. Na šta ukazuje negativna korelacija između obeležja? Da li su u većoj meri korelisana obeležja sa korelacijom -0.7 ili sa korelacijom 0.3?
# napraviti listu numeričkih obeležja
numerical_feats = df_train.dtypes[df_train.dtypes == 'float64' ].index
print( numerical_feats)
print(df_train[numerical_feats].corr())
# prikazati korelacionu matricu toplotnom mapom
sns.heatmap(df_train[numerical_feats].corr())
plt.show();
sns.set()
plt.figure(figsize=(5,5))
sns.pairplot(df_train, height = 2.5)
plt.show();
categorical_feats = np.concatenate((df_train.dtypes[df_train.dtypes == "int64"].index, df_train.dtypes[df_train.dtypes == "object"].index))
print("Number of Categorical features: ", len(categorical_feats))
print("Categorical features: ", categorical_feats)
for catg in list(categorical_feats) :
print(df_train[catg].value_counts())
print('#'*50)
Pri analizi kategoričkih obeležja, korisno je prikazati tzv. pivot tabele,
odnosno tabele koje sumarno prikazuju broj uzoraka koji imaju određenu kombinaciju vrednosti dva obeležja. Koristeći funkciju crosstab iz Pandas biblioteke prikazati koliko je među putnicima bilo žena, a koliko muškaraca u svakoj od putničkih klasa. Takođe prikazati koliko je putnika preživelo, a koliko nije iz svake od putničkih klasa. Šta se može zaključiti iz dobijenih tabela?
pd.crosstab(df_train['Pclass'],df_train['Sex']).style.background_gradient(cmap='summer_r')
pd.crosstab(df_train['Pclass'],df_train['Survived']).style.background_gradient(cmap='summer_r')
Podatke iz poslednje pivot tabele prikazati na grafiku koristeći funkciju countplot iz biblioteke Seaborn.
sns.countplot(x='Pclass',hue='Survived',data=df_train)
Koristeći funkciju violinplot iz biblioteke Seaborn prikazati raspodele godina za svaki od polova.
sns.violinplot(x='Sex', y='Age', data=df_train)
Za praćenje zavisnosti srednje vrednosti nekog numeričkog obeležja od vrednosti dva kategorička obeležja pogodna je funkcija barplot iz biblioteke Seaborn. Prikazati zavisnost prosečne cene karte od pola (M/Ž) putnika, za preživele i stradale putnike.
sns.barplot(x='Sex',y='Fare',hue='Survived',data=df_train)
Koristeći histograme, prikazati uporedo raspodele muškaraca i žena po godinama. Podesiti da jedan stubić odgovara intervalu od 5 godina.
hist_a=plt.hist(df_train.loc[df_train['Sex']=='male','Age'], bins=np.arange(0,100,5), alpha=.50, density=True, label='male')
#fig = plt.figure()
hist_b=plt.hist(df_train.loc[df_train['Sex']=='female','Age'], bins=np.arange(0,100,5), alpha=.50, density=True, label='female')
plt.legend()
!jupyter nbconvert --to html "/content/drive/MyDrive/Colab Notebooks/zadatak2_EDA_moja_rjesenja.ipynb"