Data/Machine Learning

[ML] Sweetviz와 Pipeline으로 모델링하기

쿡국 2024. 10. 29. 15:29

데이터 분석가가 모델링을 진행하려면 EDA(탐색적 데이터분석)부터 변수 선택, 표준화, 학습까지 하나하나 코딩해야한다. 물론 숙련자라면 이 과정에 어려움이 없겠지만, 그래도 더 편하게 할 수 있는 방법이 있다면 좋지 않을까?

 

Sweetviz 라이브러리는 EDA도구로 간단한 결측치 확인, 타겟에 대한 분석, 데이터 간 비교 등을 수행해야 할 때 자동으로 빠르게 직관적 탐색을 도와준다.

 

import seaborn as sns
import sweetviz as sv

df =sns.load_dataset('titanic')
report =sv.analyze(df)

report.show_html('sweetviz_titanic_report.html')

 

임의로 타이타닉 샘플데이터를 EDA 한다면 위 코드만으로 간단한 결과값들을 확인할 수 있다. 데이터의 칼럼을 따로 추출해서 볼 수도 있는데, 데이터의 용량이 큰 경우는 오래 걸리거나 튕길 수도 있다.

 

Sweetviz 말고도 ProfileReport 라이브러리를 통해 EDA 보고서를 출력할 수 있다. 데이터 요약, 상관관계, 결측치, 데이터 분포, 이상치 등을 확인할 수 있고, to_file() 과 to_widget() 메서드를 통해 html파일 혹은 주피터 대화형 위젯으로도 확인 가능하다.

from pandas_profiling import ProfileReport

df_iris =sns.load_dataset('iris')

profile_iris = ProfileReport(df_iris, title='Iris Dataset Profiling Report', explorative=True) #exploartive 심층분석여부

profile_iris.to_file('pandas_profiling_iris_report.html')

위와 같이 EDA 라이브러리를 활용해 데이터를 탐색했다면, 이제 학습시킬 변수를 선택하고, 표준화, 학습의 단계를 거쳐야 한다. 이때 Pipeline은 전처리에서 학습까지의 과정을 하나로 연결해주는 것이라고 보면 된다. 

(좌) Pipeline을 사용하지 않는 경우, (우) Pipeline을 사용하는 경우

 

왼쪽 그림처럼 기존 방식은 변수 선택 과정을 코딩하고 선택된 변수를 다시 표준화한 다음, 이를 토대로 모형을 학습하게 된다. 

 

하지만 오른쪽과 같은 경우 Pipeline에 작업(변수 선택, 표준화, 모형 클래스)를 등록만 해주면 기존 과정을 한 번에 처리할 수 있다. Pipeline에 작업을 등록하는 것은 어렵지 않기 때문에 모형 학습에 있어서 여러가지 과정을 거쳐야 한다면 확실히 Pipeline을 사용하는 것이 유리하다.

 

Pipeline의 추가적인 장점은 아래와 같다. 

 

  • 코드 간소화: Pipeline을 통해 전처리와 모델 학습 과정을 하나의 워크플로우로 묶어 여러 모델에 대해 일관된 방식으로 실행할 수 있다.
  • 재사용성: 파이프라인으로 구성된 전처리 과정을 모든 모델에 일관되게 적용할 수 있어 재사용이 용이하다.
  • 유지보수 용이성: 각 단계를 파이프라인으로 정의해두면, 전처리나 모델링의 특정 단계만 수정할 때 코드 전반을 수정할 필요가 없어 유지보수가 쉬워진다.
  • 교차 검증의 편의성: cross_val_score와 같은 교차 검증 함수와 함께 사용하여 파이프라인을 쉽게 평가할 수 있다.

예제코드를 통해 Pipeline의 작동 원리를 알아보자.

from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC
from sklearn.neighbors import KNeighborsClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.pipeline import Pipeline

# 타이타닉 데이터 불러오기
df =sns.load_dataset('titanic')

# 간단한 전처리
X=df.drop(columns=['survived'])
y=df['survived']

# 수치형변수, 범주형 변수 분리
numeric_features = ['age','fare','parch','sibsp']
categorical_features = ['embarked','sex','pclass']

# 파이프라인 구축
# 수치형 변수에 대한 전처리 파이프
numeric_transformer =Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='median')),
    ('scaler',StandardScaler())
])

# 범주형 변수 전처리 파이프라인
categorical_transformer =Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='most_frequent')),
    ('onehot',OneHotEncoder(handle_unknown='ignore'))
])

# 파이프라인을 통합
pre_processor=ColumnTransformer(
    transformers=[
        ('num',numeric_transformer,numeric_features),
        ('cat',categorical_transformer,categorical_features)
    ]
)

# 모델링

models ={
    'Random Forest' : RandomForestClassifier(random_state=111),
    'SVC' : SVC(random_state=111),
    'KNN' : KNeighborsClassifier(),
    'Logistic Regression' : LogisticRegression(max_iter=1000, random_state=111)
}


# 모델 성능 비교
# 교차검증까지 추가해서 실제 성능에 대해서 교차검증 결과를 출력 
results = {}
for model_name, model in models.items():
    #파이프라인 구성
    pipeline = Pipeline(steps=[
        ('pre_processor',pre_processor),
        ('models',model)
    ])
    #교차검증 진행
    cv_scores=cross_val_score(pipeline,X,y, cv=5, scoring='accuracy')
    results[model_name] = cv_scores.mean()

print('Model Comparison Results')
for model_name, accuracy in results.items():
    print(model_name, accuracy)

best_model_name =max(results, key=results.get)    
best_model = models[best_model_name]

 

성능 확인