이번 chapter에서는 캘리포니아 주택 가격 예측 프로그램을 만드는 과정을 통해 머신러닝 프로젝트가 어떻게 진행되는지 살펴본다.

파이프라인

데이터 처리 컴포넌트(component)들이 연속되어 있는 것을 데이터 파이프라인(pipeline)이라고 한다.

컴포넌트들은 비동기적으로(독립적으로) 작동하며, 많은 데이터를 추출해 처리하고 이를 데이터 저장소로 보낸다. 그러면 일정 시간이 지난 후 그 결과를 이용해 다른 컴포넌트가 자신의 출력 결과를 만든다.

데이터 파이프라인은 데이터의 흐름도 덕분에 시스템을 이해하기 쉽게 하고, 한 컴포넌트가 중단되더라도 해당 컴포넌트의 마지막 출력 결과를 이용해서 하위 컴포넌트들은 정상 작동 할 수 있다.


데이터 가져오기

데이터를 가져온 뒤에는 train set과 test set을 분리해야 한다. 분리하는 방법에는 여러 가지가 있다.

  1. 그냥 비율 할당하기
    가장 간단하지만 데이터셋이 업데이트 되거나 학습을 반복하면 train set과 test set이 달라지는 문제점이 있다.
import numpy as np

def shuffle_and_split_data(data, test_ratio):
    shuffled_indices = np.random.permutation(len(data))
    test_set_size = int(len(data) * test_ratio)
    test_indices = shuffled_indices[:test_set_size]
    train_indices = shuffled_indices[test_set_size:]
    return data.iloc[train_indices], data.iloc[test_indices]

train_set, test_set = shuffle_and_split_data(housing, 0.2)
  1. 해시 값 이용
    고유한 해시 값을 이용하면 이전에 test set에 포함되었던 데이터는 train set에 포함시키지 않을 수 있다.
from zlib import crc32

def is_id_in_test_set(identifier, test_ratio):
    return crc32(np.int64(identifier)) < test_ratio * 2**32

def split_data_with_id_hash(data, test_ratio, id_column):
    ids = data[id_column]
    in_test_set = ids.apply(lambda id_: is_id_in_test_set(id_, test_ratio))
    return data.loc[~in_test_set], data.loc[in_test_set]
  1. 인덱스 부여
    새로운 인덱스를 부여할 수도 있다.
housing_with_id = housing.reset_index()     # index 열이 추가된 데이터 프레임 반환
train_set, test_set = split_data_with_id_hash(housing_with_id, 0.2, 'index')
  1. 난수 초깃값 지정
    다 귀찮다면 난수 초깃값을 지정하도록 하자.
from sklearn.model_selection import train_test_split
train_set, test_set = train_test_split(housing, test_size=0.2, random_state=42)


계층적 샘플링

계층(그룹)에 따라 샘플링을 다르게 해야할 수도 있다. 예를 들어 전체 인구 중 51%가 여성이고 49%가 남성이라면, 샘플링을 할 때도 이 비율을 유지해야 더 좋은 결과를 얻을 수 있다.

이 예시에서는 중간 소득이 주택을 가격을 예측하는 데 중요하다는 정보을 알고 있다, 따라서 중간 소득을 카테고리로 분류하여 계층적 샘플링을 하고자 한다.

먼저, 중간 소득을 카테고리로 분류한다.

housing['income_cat'] = pd.cut(housing['median_income'], bins=[0., 1.5, 3.0, 4.5, 6., np.inf], labels=[1, 2, 3, 4, 5])

한 데이터셋으로 각기 다른 10개의 계층 분할을 생성하면 교차 검증의 관점에서 더 좋을 것이다.

from sklearn.model_selection import StratifiedShuffleSplit

splitter = StratifiedShuffleSplit(n_splits=10, test_size=0.2, random_state=42)
strat_splits = []
for train_index, test_index in splitter.split(housing, housing['income_cat']):
    strat_train_set_n = housing.iloc[train_index]
    strat_test_set_n = housing.iloc[test_index]
    strat_splits.append([strat_train_set_n, strat_test_set_n])

10개까지는 됐고, 하나의 분할이 필요하면 다음 코드를 사용해서 간단하게 처리할 수 있다.

strat_train_set, strat_test_set = train_test_split(housing, test_size=0.2, stratify=housing['income_cat'], random_state=42)


데이터 시각화

데이터를 시각화해서 살펴보는 것은 데이터를 이해하는 데 중요하다. 이 예시에서는 산점도를 주로 사용하여 시각화를 진행한다. 상관관계 산점도를 그려보면 특성 간의 상관관계를 알 수 있다.

자세한 내용은 코드를 참고하자.

코드 보러가기



별도의 출처 표시가 있는 이미지를 제외한 모든 이미지는 강의자료에서 발췌하였음을 밝힙니다.

댓글남기기