Day 8. 핸즈온 머신러닝 - 2장 - part 2

채원·2025년 7월 17일

핸즈온 머신러닝

목록 보기
3/6

describe 메서드는 숫자형 특성의 요약 정보를 보여준다.

hist() 메서드는 모든 숫자형 형태에 대한 히스토그램을 출력할 수 있다.

이를 통해 알 수 있는 사실은 다음과 같다.

  • 중간 소득이 US 달러로 표시되어 있지 않다. 따라서, 그 단위를 통일하는 것이 필요하다.
  • 중간 주택 연도와 중간 주택 가격 그래프의 오른쪽 값이 심하게 높아지면서 그래프가 끝나는 것으로 보아 최댓값과 최솟값이 한정되어 있음을 알 수 있다.
  • 특성들의 스케일이 많이 다르다.
  • 많은 히스토그램에서 오른쪽 꼬리가 더 길다. 이러한 형태는 일부 머신러닝 알고리즘에서 패턴을 찾기 어렵게 만든다.

테스트 세트 만들기

  • 데이터 스누핑 편향 : 테스트 세트로 일반화 오차를 추정하여 매우 낙관적인 추정이 나오게 되는 것

다음과 같은 코드로 랜덤으로 테스트 세트를 만들 수 있다.

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]

하지만, 프로그램을 실행할 때마다 다른 테스트 세트가 생성된다는 문제점이 존재한다. 이를 해결하기 위해서는,
1. 처음 실행에서 테스트 세트를 저장하고 다음번 실행에서 불러들이기
2. 항상 같은 난수 인덱스가 생성되도록 np.random.permutation()을 호출하기 전에 난수 발생기의 초깃값을 지정하기

하지만 위 방법 또한 데이터셋이 업데이트된 경우 문제가 생긴다. 따라서, 샘플의 식별자를 사용하여 테스트 세트로 보낼지 말지를 결정할 수 있다.

from zlib import crc32

def is_id_in_test_set(identifier, test_ratio):
return crc32(np.int64(identifier).tobytes()) < 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]

위 방법을 통해 나눈 훈련 / 테스트 세트를 보면 다음과 같다.


사이킷런을 사용하면 위 과정을 간단히 구현할 수 있다. 가장 간단한 함수는 train_test_split으로, 난수 초깃값을 설정하는 기능행의 개수가 같은 여러 개의 데이터셋을 넘겨 동일한 인덱스를 기반으로 나누는 기능이 존재한다.

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"] = pd.cut(housing["median_income"],
							   bins=[0., 1.5, 3.0, 4.5, 6., np.inf],
							   labels=[1, 2, 3, 4, 5])

pandas.cut reference
pandas.cut 함수는 특정 1차원 배열을 bins에 따라 해당 개수, 또는 해당 구간에 따라 분할한 뒤, 각 값들에 대해 해당하는 구간의 labels의 값을 부여한다.

profile
학부생

0개의 댓글