본문

핸즈온 머신러닝 9일차 "테스트 세트"


2.3.4 테스트 세트 만들기

일반적으로 어떤 알고리즘 이용할지 전에 자세히 파악해야한다고 생각합니다. 하지만, 뇌는 과대적합 편향이 강해서 겉으로 드러난 패턴에 속아 특정 머신러닝을 택할 수 있습니다.

이를 데이터 스누핑 편향이라고 합니다.

테스트 세트를 생성하는 것은 간단하게 무작위로 어떤 샘플을 데이터셋의 20%정로를 따로 두면 됩니다.

import numpy as np

def split_train_test(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]


프로그램을 실행할 때마다 다른 테스트 세트가 발생하므로, 처음실행한 테스트 세트를 저장하거나, 난수 발생기 초깃값을 지정하는(np.random.seed(42)) 방법이 있습니다. 이 두방법은 신규 데이터 발생시 문제가 발생하기 때문에 샘플의 해시값을 구하여 마지막 바이트 값이 51(256의 20%)보다 작은 샘플만 테스트 세트로 지정할 수도 있습니다. 이를 구현한 코드입니다.

from zlib import crc32

def test_set_check(identifier, test_ratio):

   return crc32(np.int64(identifier)) & 0xffffffff < test_ratio * test_ratio *2**32


def split_train_test_by_id(data, test_ratio, id_column):

   ids = data[id_column]

   in_test_set = ids.apply(lambda id_: test_set_check(id_, test_ratio))

   return data.loc(~in_test_set), data.loc[in_test_set]

주택 데이터셋에는 식별자 칼럼이 없어서 행의 인덱스를 ID로 사용합니다.

housing_with_id = housing.reset_index()

train_set, test_set = split_train_test_by_id(housing_with_id, 0.2, “index”)


from sklearn.model_selection import train_test_split


train_set, test_set = train_test_split(housing, test_size=0.2, random_state=42)

사이킷런에서는 다양한 테스트셋을 만드는 기능이 있습니다. 위는 난수 초기값을 설정하는 기능이 포함되어 있는 메서드입니다.


housing["income_cat"] = np.ceil(housing["median_income"] / 1.5)

housing["income_cat"].where(housing["income_cat"] < 5, 5.0, inplace=True)

소득 카테고리 제한(1.5 기준)하고 5보다 큰 카테고리는 5로 합침. (카테고리 수를 제한하기 위함)


from sklearn.model_selection import StratifiedShuffleSplit


split = StratifiedShuffleSplit(n_splits=1, test_size=0.2, random_state=42)

for train_index, test_index in split.split(housing, housing["income_cat"]):

   strat_train_set = housing.loc[train_index]

   strat_test_set = housing.loc[test_index]

계층 샘플링을 실시합니다.


housing["income_cat"].value_counts() / len(housing)

1.0    0.039826
2.0    0.318847
3.0    0.350581
4.0 0.176308 5.0 0.114438 Name: income_cat, dtype: float64

전체 데이터셋의 소득 카테고리 비율입니다.

위와 비슷한 코드로 계층샘플링과 무작위 샘플링을 비교하였습니다.

col) 책 내용상으로 무작위 샘플링의 오류율이 높게 나타남

income_cat 특성을 삭제하여 데이터를 원래대로 만듭니다.

for set_ in (strat_train_set, strat_test_set):

   set_.drop("income_cat", axis=1, inplace=True)

스터디 중 필기한 내용으로 모든 참고자료는 핸즈온 머신러닝입니다.

아래 책을 클릭하시면 구매페이지로 이동합니다.


핸즈온 머신러닝


공감과 댓글은 글쓴이에게 큰 힘이 됩니다. 

마음에 드셨으면 공감과 댓글부탁드립니다.





댓글