다시 이음

EDA의 여러가지 방법 본문

AI 일별 공부 정리

EDA의 여러가지 방법

Taeho(Damon) 2021. 8. 23. 22:43

EDA( Exploratory Data Analysis ) 탐색적 데이터 분석

 

안녕하세요.

 

오늘은 지금까지 활용해왔던 EDA 전처리 방법에 대해서 알아보려고 합니다.

 

간단히 EDA의 정의부터 알아볼게요.

 

출처 ) https://www.aismartz.com/blog/why-eda-is-crucial-for-any-data-science-project/

 

EDA란?

 

수집한 데이터가 들어왔을 때, 이를 다양한 각도에서 관찰하고 이해하는 과정입니다. 한마디로 데이터를 분석하기 전에 그래프나 통계적인 방법으로 자료를 직관적으로 바라보는 과정입니다.

 


EDA 과정

 

여기서 말하는 과정이란 개인별로 혹은 데이터별로 편차가 있습니다.

 

저의 경우 제가 활용해보거나 확인해본 것을 정리해본 것으로 이것이 무조건 정답이 아닙니다.

 

 

1) 기초 정보 확인하기

- 데이터의 행,열의 개수 및 각 열의 데이터형태 파악

df.info()

 

-데이터의 열의 이름 확인하기

# 컬럼명 확인
df.columns

 

- 데이터 사이즈 확인

# 데이터 사이즈 확인
print("훈련 데이터 :",train.shape[0])
print("테스트 데이터 - features :", test.shape[0])

 

-데이터 타입 확인

# 데이터 타입 확인
df.dtypes

 

- 중복값 확인

# 데이터 중복값 확인
df.T.duplicated()

 

- 결측치 확인

# 데이터 결측치 확인
df.isnull().sum()

 

- 열의 구성 파악하기 ( 열에 있는 모든 값들을 나열 )

df.unique()
# 열에 있는 모든 값들을 나열해줍니다.

 

- 열의 값에 따른 개수 확인하기

df["열이름"].value_counts()

 

- 열을 순서에 따라 정렬하기

#오름차순으로 정렬하기
df['열이름'].sort_values()
#내림차순으로 정렬하기
df['열이름'].sort_values(ascending=False)

#숫자형 or 문자형으로 된 열은 제외하고, 열이름을 기준으로 오름차순으로 정렬하기
#이렇게 하면 count,unique,top,freq의 값이 생겨납니다.
df.describe(exclude='number','object').T.sort_values(by='열이름')
# T를 통해 기존 열이름이 행 index로 변환되고 count,unique,top,freq가 column으로 변환됩니다.

 

- 데이터 타입을 기준으로 데이터 추출

# object 타입의 features를 고르기
object_data = []

for col in X_train.columns:
    if X_train[col].dtype=="object":
        object_data.append(col)
    

object_data

 

-전체적인 데이터 확인하기

import pandas_profiling
train.profile_report()

 

2) 삭제, 추가, 변경

 

- 열 삭제

# 필요없는 열 삭제
data_cleaned = df.drop(["열이름1","열이름2","열이름3"], axis=1)

# 남은 특성 개수 확인하기
data_cleaned.shape()

 

- Onehotencoder ( 원핫인코딩 ) : 카테고리 수에 맞게 새로운 열을 추가하여 표현

from category_encoders import OneHotEncoder
encoder = OneHotEncoder(use_cat_names=True) # cols='열이름'을 지정하면 원하는 열만 인코딩
X_train_encoded = encoder.fit_transform(X_train)
X_val_encoded = encoder.transform(X_val)

 

- OrdinalEncoder ( 순서형 데이터로 인코딩 )

from category_encoders import OrdinalEncoder

enc = OrdinalEncoder(handle_missing="value")

# 적용하기
enc.transform()

# 어떻게 mapping되었는지 확인하기 
enc.category_mapping

# mapping 하이퍼 파라미터를 사용하여 자동으로 설정된 mapping 변경하기(예시)
enc = OrdinalEncoder(handle_missing="value", mapping=ordinal_cols_mapping)

ordinal_cols_mapping = [{'col': 'opinion_h1n1_vacc_effective','mapping': {'Very Effective':7, 'NaN':1,'Dont Know':5,
                         'Not At All Effective': 3,'Somewhat Effective':6,'Not Very Effective':4,'Refused':2}},
                        {'col': 'opinion_h1n1_risk','mapping': {'Somewhat High':7,'NaN':1,'Somewhat Low': 5,'Dont Know':4,'Very High':6,
                          'Very Low':3,'Refused':2}}]

 

- 메소드 사용하지 않고 5개의 카테고리를 가지는 데이터 변환하기

def risk(df):
  df["열이름"] = ""
  
  for index in range(len(df)):
    opinion = df["열이름"][index]
    
    if opinion == "Very Low":
      df["열이름"][index] = int(5)

    elif opinion == "Somewhat Low":
      df["열이름"][index] = int(4)

    elif opinion == "Dont Know":
      df["열이름"][index] = int(3)

    elif opinion == "Somewhat High":
      df["열이름"][index] = int(2)

    elif opinion == "Very High":
      df["열이름"][index] = int(1)
      
    else:
      df["열이름"][index] = 0

  return df

 

- 데이터 표준화 ( strategy 파라미터를 변경함으로써 표준화 기준을 정할 수 있다. )

from sklearn.impute import SimpleImputer 

#결측치를 평균으로 대치
imputer = SimpleImputer(strategy='mean')
X_train_imputed = imputer.fit_transform(X_train_encoded)
X_val_imputed = imputer.transform(X_val_encoded)

 

- Feature Engineering

 

 이것에 대해서는 데이터간의 관계와 여러가지 특성의 연관성을 적절히 파악하여 사용해야하는 분야입니다.

아직은 이 부분에 대해 부족한 감이 많아 추후에 Feature Engineering을 따로 포스팅 하도록 하겠습니다.

 

 

- 데이터 나누기 ( holdout 기법 )

from sklearn.model_selection import train_test_split

features = ['City','Room']
target = 'Price'

X = df[features]
y = df[target]

#메소드 사용하여 훈련데이터, 테스트데이터 나누기 (훈련 80%, 테스트 20%)
X_train, X_test, y_train, y_test = train_test_split(X, y, 
train_size=0.8, test_size=0.20, random_state=2)

 

 

3) 시각화

 

- 카테고리별 빈도 파악하기 ( 히스토그램 )

import seaborn as sns
import matplotlib.pyplot as plt

df = pd.DataFrame(X_train["state"].value_counts())

sns.set_theme(style="whitegrid")
plt.subplots(figsize=(30,10))
plt.xticks(rotation = 45, fontweight='light', fontsize='small' )
ax = sns.barplot(x=df.index, y="열이름", data=df)

plt.show()

 

- 오차행렬 ( Confusion Matrix )

import matplotlib.pyplot as plt
from sklearn.metrics import plot_confusion_matrix

fig, ax = plt.subplots()
matrix = plot_confusion_matrix(pipe, X_val, y_val,
                            cmap = plt.cm.Blues,
                            ax = ax);
plt.title(f'Confusion matrix, n = {len(y_val)}', fontsize=15)
plt.show()

 

- y_pred_proba ( 예측확률 ) 의 시각화

import seaborn as sns
# y_pred_proba = pipe.predict_proba(X_val)[:, 0] # 0이 될 확률 (Negative)
y_pred_proba = pipe.predict_proba(X_val)[:, 1] # 1이 될 확률 (Positive)
y_pred_proba

sns.displot(y_pred_proba);

 

- ROC 곡선 시각화

from sklearn.metrics import roc_curve, roc_auc_score

auc_score = roc_auc_score(y_val, y_pred_proba)
fpr, tpr, thresholds = roc_curve(y_val, y_pred_proba)

roc = pd.DataFrame({'FPR(Fall-out)': fpr, 
                      'TPRate(Recall)': tpr, 
                      'Threshold': thresholds
})

plt.scatter(fpr, tpr)
plt.title('ROC curve')
plt.xlabel('FPR(Fall-out)')
plt.ylabel('TPR(Recall)')

auc_score

 

- 훈련곡선, 검증곡선 시각화

# ramdomforest 분류모델 사용시에 max_depth 하이퍼파라미터에 대한 최적값 찾아보기

import matplotlib.pyplot as plt
import seaborn as sns

depth = range(1, 20, 2)
ts, vs = validation_curve(
    pipe, X_train, y_train
    , param_name='randomforestclassifier__max_depth'
    , param_range=depth, scoring='neg_mean_absolute_error'
    , cv=3
    , n_jobs=-1
)

train_scores_mean = np.mean(-ts, axis=1)
validation_scores_mean = np.mean(-vs, axis=1)

fig, ax = plt.subplots()

# 훈련세트 검증곡선
ax.plot(depth, train_scores_mean, label='training error')

# 검증세트 검증곡선
ax.plot(depth, validation_scores_mean, label='validation error')

# 이상적인 max_depth
ax.vlines(5,0, train_scores_mean.max(), color='blue')

# 그래프 셋팅
ax.set(title='Validation Curve'
      , xlabel='Model Complexity(max_depth)', ylabel='MAE')
ax.legend()
fig.dpi = 100

 

 

지금까지 제가 보고 배웠던 EDA 과정에 대해서 간략하다면 간략하게 정리를 해봤습니다.

 

사실 더 편하고 좋은 방법들이 많을 거라고 생각합니다.

 

추후에 배우게 되는 대로 계속해서 업데이트 해서 변경하도록 하겠습니다ㅎㅎ