타이타닉 정리
변수별 EDA 및 함수정의 과정
📜 제목으로 보기✏마지막 댓글로
- 데이터 로딩
- 데이터 확인
- 칼럼명 소문자로 일괄변경
- 범주 <-> 숫자 type 제대로 되었는지 확인
- Null 체크
- 종속변수 확인 및 종속변수에 대한 다른변수들 관계 추론
- 단변수 탐색1 : 범주형 칼럼의 빈도
- 단변수 탐색2 : 숫자형 칼럼의 분포
- 이변수 탐색1 : 종속변수(범주)별 - 범주형 변수
- 방법1: 특정(종속)범주별 범주칼럼 인덱싱하여서 각 범주별 series를 df로 합치기
- 방법2 : pd.crosstab 으로 그리기
- 방법3 : groupby( 범주) [ 종속변수].집계.unstack() - 빈도+평균도 가능 + 가상df로서 apply()로 비율계산가능함
- 방법4 : sns.countplot( '범주칼럼' , hue= '종속변수' ) -> 비율은 볼 수 없다
- 범주-종속(범주) 종속변수별 범주의 비율 한번에 그리기
- 종속-범주형변수 관계 함수정의하기
- for+함수(범주-범주)문을 통해 모든 종속칼럼에 대해 모든 범주칼럼의 분포와 비율 그려보기
- 이변수 탐색2 숫자-숫자형의 산점도행렬 with 종속변수
- 이변수 탐색3 : 범주별 - 숫자형 칼럼(들)의 분포(boxplot) with 종속변수(범례) by 숫자형칼럼명리스트
- 이변수 탐색4 : 범주별 숫자형칼럼의 범위별 kde분포 탐색
- 삼변수 탐색1 : 범주2(범례)별로보는 범주1(x축)별 --> 연속(종속)변수 의 비율
- 삼변수 탐색2 : 범례별(종속변수)별로 보는 범주별(x축) 숫자형(y축-바이올린)의 분포
import numpy as np
import pandas as pd
# %matplotlib nbagg
%matplotlib inline
import matplotlib.pyplot as plt
import matplotlib
import seaborn as sns
sns.set(font_scale=1.5)
sns.set_style('whitegrid') #whitegrid
sns.set_palette('muted')
# 한글사용가능하게하기
from matplotlib import font_manager
font_name = font_manager.FontProperties(fname='C:/Windows/Fonts/malgun.ttf').get_name()
matplotlib.rc('font', family=font_name)
print (plt.rcParams['font.family'] )
import pandas as pd
train = pd.read_csv('data/titanic/train.csv')
test = pd.read_csv('data/titanic/test.csv')
print(train.shape)
print(train.columns)
train.head()
train.info()
print(test.shape)
print(test.columns)
test.head()
test.info()
train = \
train.rename( columns = {
'PassengerId' : 'passengerid',
'Pclass' : 'pclass' ,
'Name' : 'name',
'Sex' : 'sex',
'Age' : 'age',
'SibSp' : 'sibsp',
'Ticket' : 'ticket' ,
'Fare' : 'fare',
'Cabin' : 'cabin',
'Embarked' : 'embarked',
'Parch' : 'Parch'.lower() ,
'Survived' : 'survived',
})
test = \
test.rename( columns = {
'PassengerId' : 'passengerid',
'Pclass' : 'pclass' ,
'Name' : 'name',
'Sex' : 'sex',
'Age' : 'age',
'SibSp' : 'sibsp',
'Ticket' : 'ticket' ,
'Fare' : 'fare',
'Cabin' : 'cabin',
'Embarked' : 'embarked',
'Parch' : 'Parch'.lower() ,
# 'Survived' : 'survived',
})
train.columns
[col.lower() for col in train.columns]
train.columns = [col.lower() for col in train.columns]
train.head()
train['survived'] = train['survived'].astype( object )
train['pclass'] = train['pclass'].astype( object )
train['parch'] = train['parch'].astype( object )
train['sibsp'] = train['sibsp'].astype( object )
test['pclass'] = test['pclass'].astype( object )
train['parch'] = train['parch'].astype( object )
train['sibsp'] = train['sibsp'].astype( object )
train.isnull().sum()
train.isnull().sum().reset_index()
missing_df = train.isnull().sum().reset_index()
missing_df.columns = ['columns', 'count']
missing_df
missing_df = train.isnull().sum().reset_index()
missing_df.columns = ['columns', 'count']
missing_df['missing_rate'] = missing_df['count'] / train.shape[0] # 미싱 갯수 / 전체데이터의 데이터수 - shape(row,col)의 첫번째!!
missing_df
missing_df = train.isnull().sum().reset_index()
missing_df.columns = ['columns', 'count']
missing_df['missing_rate'] = missing_df['count'] / train.shape[0] # 미싱 갯수 / 전체데이터의 데이터수 - shape(row,col)의 첫번째!!
missing_df.loc[ missing_df['missing_rate'] != 0, :] # missing_Rate가 0이 아닌 것들만 가졍괴
missing_df = test.isnull().sum().reset_index()
missing_df.columns = ['columns', 'count']
missing_df['missing_rate'] = missing_df['count'] / test.shape[0] # 미싱 갯수 / 전체데이터의 데이터수 - shape(row,col)의 첫번째!!
missing_df.loc[ missing_df['missing_rate'] != 0, :] # missing_Rate가 0이 아닌 것들만 가졍괴
train['survived'].value_counts().plot(kind='bar')
fig, ax = plt.subplots(1, 2, # 1x2 Pieplot + barplot
figsize= (12,8))
# 1 X1 Pie plot
train['survived'].value_counts().plot.pie(
explode = [0, 0.1],
autopct = '%1.1f%%', # 퍼센트는 소수점1자리까지
ax = ax[0],
shadow = True
)
ax[0].set_title('Pie plot')
ax[0].set_ylabel('')
# # 1 X 2 bar plot (sns.countplot)
# train['survived'].value_counts().plot(
# kind= 'bar',
# ax = ax[1],
# )
sns.countplot(
'survived', #칼럼명
data = train, # df
ax = ax[1] # 좌표평면
)
plt.tight_layout()
import relationship as r
r.categorical_all(train, 'survived')
train['survived'].dtypes
train['survived'].dtypes == "object"
category_feature = [ col for col in train.columns if train[col].dtypes == "object"]
category_feature
# set으로 마이너스 연산을 한 뒤, list()로 감싸서 다시 리스트로 만든다.
categorical_feature = list( set(category_feature) - set( ['passengerid', 'survived']) )
categorical_feature
for col in categorical_feature:
f, ax = plt.subplots(1, 1, figsize=(10,7))
sns.countplot(
col, #칼럼명
data = train, # df
)
plt.title(col)
plt.show() # 여러개 그림을 한셀에 띄울 때, plt.show()를 통해 하나씩 끊어주기!
def categorical_all(df, categorical_feature):
# 칼럼명 하나만 입력시
if type(categorical_feature) is str:
sns.countplot(
categorical_feature, #칼럼명 1개
data = df, # df
)
plt.title(categorical_feature) #칼럼명 1개
plt.tight_layout()
plt.show() # 여러개 그림을 한셀에 띄울 때, plt.show()를 통해 하나씩 끊어주기!
else:
# 범주형 칼럼명 리스트가 들어왔을 때
for col in categorical_feature:
sns.countplot(
col, #칼럼명
data = df, # df
)
plt.title(col)
plt.tight_layout()
plt.show() # 여러개 그림을 한셀에 띄울 때, plt.show()를 통해 하나씩 끊어주기!
categorical_all(train, 'cabin')
categorical_all(train, categorical_feature)
train.head()
numerical_feature = list( set(train.columns) - set(categorical_feature) - set(['passengerid', 'survived']) )
numerical_feature
np.sort(numerical_feature)
numerical_feature = list( set(train.columns) - set(categorical_feature) - set(['passengerid', 'survived']) )
numerical_feature = np.sort(numerical_feature)
numerical_feature
for col in numerical_feature:
print(train[col].describe())
sns.distplot( train.loc[train[col].notnull(), col] ) # 해당칼럼 중 NaN아닌것만 인덱싱한 칼럼만 그리기
plt.title(col)
plt.show()
for col in numerical_feature:
print(train[col].describe())
sns.boxplot( data=train.loc[train[col].notnull(), col] )
plt.title(col)
plt.show()
for col in numerical_feature:
# 숫자형 칼럼의 기술통계량
print(train[col].describe())
print(f"Skewed : {train[col].skew():.2f}")
f, ax = plt.subplots(1, 2, figsize=(18,9))
# dist
sns.distplot( train.loc[train[col].notnull(), col],
ax = ax[0] )
ax[0].set_title(col +'\'s hist(dist) plot' )
# boxplot
sns.boxplot( data=train.loc[train[col].notnull(), col],
ax = ax[1] )
ax[1].set_title(col +'\'s boxplot')
plt.tight_layout()
plt.show()
def numerical_all(df, numerical_feature):
for col in numerical_feature:
# 숫자형 칼럼의 기술통계량
print(df[col].describe())
print(f"Skewed : {train[col].skew():.2f}")
f, ax = plt.subplots(1, 2, figsize=(18,9))
# dist
sns.distplot( df.loc[train[col].notnull(), col],
ax = ax[0] )
ax[0].set_title(col +'\'s hist(dist) plot' )
ax[0].legend(loc='upper left', bbox_to_anchor=(1.0, 1.0) ) # 범례 밖으로 빼기
# boxplot
sns.boxplot( data=df.loc[df[col].notnull(), col],
ax = ax[1] )
ax[1].set_title(col +'\'s boxplot')
ax[1].legend(loc='upper left', bbox_to_anchor=(1.0, 1.0) ) # 범례 밖으로 빼기
plt.tight_layout()
plt.show()
survived = train.loc[ train['survived'] == 0,'sex' ].value_counts()
survived.name = 'Survived'
dead = train.loc[ train['survived'] == 1,'sex' ].value_counts()
dead.name = 'Dead'
# 시리즈를 리스트형식으로 df합치기
df = pd.DataFrame( [ survived, dead] )
df.head()
print(df)
df.plot(kind='bar')
pd.crosstab( train['sex'], train['survived'])
pd.crosstab( train['sex'], train['survived']).plot(kind='barh',
stacked=True)
pd.crosstab( train['sex'], train['survived'],
margins = True).style.background_gradient(cmap='summer_r')
cross = pd.crosstab( train['sex'], train['survived'])
cross_ratio = cross / cross.sum()
cross_ratio
cross_ratio.plot(kind='bar', stacked=True)
cross_ratio.transpose().plot(kind='bar', stacked=True)
sex_to_survived = train.groupby('sex') ['survived'].value_counts().unstack()
sex_to_survived
sex_to_survived.plot(kind='bar')
dict( list( train.groupby(['sex', 'survived']) ) ).keys()
dict( list( train.groupby(['sex', 'survived']) ) )['female', 0].head()
train.groupby('sex')['survived'].value_counts()
cross_df = train.groupby('sex') ['survived'].value_counts().unstack()
cross_ratio = cross_df / cross_df.sum()
cross_ratio
cross_ratio.transpose().plot(kind='bar', stacked=True, figsize=(10,8))
sns.countplot('sex',
data = train,
hue='survived')
cross_df = train.groupby('pclass')['survived'].value_counts().unstack()
# 세로로 합하고, 칼럼별로 나누어 비율계산하기
print(pd.DataFrame(cross_df))
cross_ratio = cross_df/ cross_df.sum()
# 세로방향기준으로 각 비율이 나눠져있는데, 그냥 그리면 row별로 x축에 틱이 찍힘
# 뒤집기
cross_ratio = cross_ratio.transpose()
cross_ratio.plot(kind='bar',
stacked=True,
figsize=(10,5))
def cate_to_categorical(data,name_c, name_d ):
# index 범주형 변수/ col 종속 변수
cross_df = data.groupby( name_c)[name_d].value_counts().unstack()
# 세로로 합하고, 칼럼별로 나누어 비율계산하기
print(cross_df)
cross_ratio = cross_df/ cross_df.sum()
# 세로방향기준으로 각 비율이 나눠져있는데, 그냥 그리면 row별로 x축에 틱이 찍힘
# 뒤집기
cross_ratio = cross_ratio.transpose()
f, ax = plt.subplots(1, 2, figsize=(18,9))
cross_df.plot(kind='bar',
ax=ax[0])
ax[0].set_title(name_c +' to ' +name_d )
ax[0].legend(loc='upper left', bbox_to_anchor=(1.0, 1.0) ) # 범례 밖으로 빼기
cross_ratio.plot(kind='bar',
ax = ax[1],
stacked=True)
ax[1].set_title(name_d +' to '+name_c +' ratio' )
ax[1].legend(loc='upper left', bbox_to_anchor=(1.0, 1.0)) # 범례 밖으로 빼기
plt.tight_layout()
plt.show() # for문에 들어갈 것 대비 끝내기
relationship_new.cate_to_categorical(train, 'survived', 'sex')
cate_to_categorical(train, 'survived', 'pclass')
import relationship_new
relationship_new.cate_to_categorical(train, 'survived', 'pclass')
relationship_new.cate_to_categorical(train, 'survived', 'parch')
for col in categorical_feature:
relationship_new.cate_to_categorical(train, 'survived', col)
numerical_feature
# list는 (-)연산은 안되도 (+) 연산은 된다.
list(numerical_feature) + ['survived']
sns.pairplot( train[ list(numerical_feature) + ['survived'] ],
hue = 'survived',
x_vars = numerical_feature,
y_vars = numerical_feature)
type(numerical_feature)
list().dtype
numerical_feature
type(list(numerical_feature)) is list
len(numerical_feature)
def num_to_numerical(df, numerical_feature, name_d=None):
# 종속변수 없을 때
if name_d == None:
sns.pairplot( df[ list(numerical_feature) ] , # 숫자형칼럼들만 인덱싱
x_vars = numerical_feature,
y_vars = numerical_feature )
plt.tight_layout()
# 숫자 - 숫자 산점도 행렬 with 종속변수 범례
else:
sns.pairplot( df[ list(numerical_feature) + [name_d]] , # 숫자형칼럼들 + 종속변수 인덱싱
hue = name_d, # 범례(색)으로 종속변수 추가
x_vars = numerical_feature,
y_vars = numerical_feature )
plt.tight_layout()
num_to_numerical(train, {'age', 'fare'}, 'survived')
print(train.groupby('sex')['age'].describe())
plt.figure(figsize=(18,9))
sns.boxplot(x='sex', y='age', data=train.dropna())
plt.title("Sex - { }".format('age'))
plt.show()
def cate_to_num_box(df, name_c, name_n, name_d=None):
# 범주별 기술통계량
if name_d != None:
print(df.groupby([name_c, name_d])[name_n].describe())
else :
print(df.groupby(name_c)[name_n].describe())
# 범주별 boxplot - 범례는 선택
plt.figure(figsize=(18,9))
sns.boxplot(x=name_c, y=name_n, data=df.dropna(),
hue = name_d)
plt.title("{} to {}".format(name_c, name_n))
plt.tight_layout()
plt.show()
cate_to_num_box(train, 'sex', 'age')
type(numerical_feature)
type("age")
def cate_to_num_box(df, name_c, numerical_feature, name_d=None):
# 숫자형 칼럼명 1개 ( 칼럼명 = 문자열 1개 직접 입력)
if type(numerical_feature) is str:
# 범주별 기술통계량
if name_d != None:
print(df.groupby([name_c, name_d])[numerical_feature].describe())
else :
print(df.groupby(name_c)[numerical_feature].describe())
# 범주별 boxplot - 범례는 선택
plt.figure(figsize=(18,9))
sns.boxplot(x=name_c, y=numerical_feature, data=df.dropna(),
hue = name_d)
plt.title("{} to {}".format(name_c, numerical_feature))
plt.tight_layout()
plt.show()
# 숫자형 칼럼명 리스트가 들어와서 for문을 돌면서 여러개 그릴 때
else :
for col in numerical_feature:
if name_d != None:
print(df.groupby([name_c, name_d])[col].describe())
else :
print(df.groupby(name_c)[col].describe())
plt.figure(figsize=(18,9))
sns.boxplot(x=name_c, # 범주칼럼명
y=col, # 숫자칼럼명
data=df.dropna() , # df
hue = name_d ) # 종속칼럼명(선택)
plt.title("{} to {}".format(name_c, col))
plt.tight_layout()
plt.show()
cate_to_num_box(train, 'sex', 'age')
cate_to_num_box(train, 'sex', 'age', 'pclass')
numerical_feature
cate_to_num_box(train, 'sex', numerical_feature, 'pclass')
facet = sns.FacetGrid(train, hue = 'survived', height = 4.5,aspect=4)
facet.map(sns.kdeplot, 'age', shade=True)
facet.set(xlim = (0, train['age'].max()))
facet.add_legend()
facet = sns.FacetGrid(train, hue = 'survived', aspect=4)
facet.map(sns.kdeplot, 'age', shade=True)
facet.set(xlim = (0, train['age'].max()))
facet.add_legend()
plt.xlim([10,20])
# ( dataFrame, '범주형 칼럼명' , '숫자형 칼럼명' ) or
# ( dataFrame, '범주형 칼럼명' , '숫자형 칼럼명' , xlim = [ a, b ] )
def cate_to_num_kde(df, name_c, name_n, xlim = None ):
print(df.groupby(name_c)[name_n].describe())
facet = sns.FacetGrid(df.dropna(), hue = name_c, aspect=4) # df 및 범주형 변수 설정 및 가로길이(aspect)
facet.map(sns.kdeplot, name_n, shade=True) # kdeplot 설정 및 숫자형변수 지정
facet.set(xlim = (df[name_n].min(), df[name_n].max())) # 숫자형 변수의 최소값부터 최대값까지 x범위 최초 지정
facet.add_legend()
if xlim != None:
print( '범위지정 : {}'.format(xlim))
plt.xlim(xlim) # xlim 지정시 그 범위만 출력
cate_to_num_kde(train, 'sex', 'age')
cate_to_num_kde(train, 'sex', 'age', xlim = [20, 30])
# https://kaggle-kr.tistory.com/17?category=821486
sns.catplot('sex', 'survived', hue='pclass', data=train,
kind='point', # default kind - factorplot
height=6,
aspect=1.5)
def legend_to_cate_to_num(df, name_l, name_c, name_n):
sns.catplot(name_c, name_n, hue=name_l, data=df,
kind='point', # default kind - factorplot
height=6,
aspect=1.5)
plt.tight_layout()
plt.show()
legend_to_cate_to_num(train, 'sex', 'pclass', 'survived')
sns.violinplot("pclass","age", hue="survived", data=train,
scale='count', split=True)
plt.legend(loc='upper left', bbox_to_anchor=(1.0, 1.0) ) # 범례 밖으로 빼기
plt.tight_layout()
plt.show() # for문에 들어갈 것 대비
def legend_to_cate_to_num_violin(df,name_l, name_c, name_n):
sns.violinplot(name_c,name_n, hue=name_l, data=df,
scale='count', split=True)
plt.legend(loc='upper left', bbox_to_anchor=(1.0, 1.0) ) # 범례 밖으로 빼기
plt.tight_layout()
plt.show() # for문에 들어갈 것 대비
legend_to_cate_to_num_violin(train, 'survived', 'sex', 'age')
categorical_all(train, 'embarked')
cate_to_categorical(train, 'survived', 'embarked')