본문 바로가기

ComputerScience/Machine Learning

Hands-On-Machine Learning : 67p ~ 98p

728x90

본 도서를 공부하며 정리한 내용입니다.

Open Dataset

머신러닝 프로젝트를 시작할 때, 가장 먼저 목적에 부합하는 data set을 구해야 한다. 아래 주소를 참조해 보면 여러 Open dataset을 구할 수 있을 것이다.
- UC Irvine : https://archive.ics.uci.edu/ml/index.php
- Kaggle : https://www.kaggle.com/datasets
- AWS : https://registry.opendata.aws/
- Wiki : https://en.wikipedia.org/wiki/List_of_datasets_for_machine-learning_research
- 기타 :
https://dataportals.org/
https://opendatamonitor.eu/frontend/web/index.php?r=dashboard%2Findex
https://www.quandl.com/

문제 정의

준비한 dataset이 label된 훈련 샘플이라면 supervised learning 작업일 것이다. 만약 수치를 예측해야한다면 regression problems에 해당할 것이다. 예측에 사용할 features수가 몇 개이고 output이 몇개인가에 따라 적절한 학습 방법을 선택하자.

성능 측정 지표 선택

해당 데이터를 학습할 수 있는 모델을 만들 때 모델의 성능을 측정하는 기준이 필요할 것이다. regression problem에서 자주 사용하는 지표로는 다음 두가지가 있다. RMSE(root mean square error), MAE(mean absolute error)
rmse, mae 모두 실제 값과 예측값의 차이를 구해서 모델의 성능을 판단한다.

예로 rmse를 살펴보자
m: rmse를 측정할 샘플 수
h: 모델의 예측 함수, h(x)는 x를 모델이 받아서 예측한 결과이다.
x: 데이터셋의 i번째 샘플, feature가 n개라면 n * 1 벡터가 된다.
y: 데이터셋의 i번째 샘플의 타깃, 우리가 구하려는 항목의 실제 값

데이터 불러오기 실습

import pandas as pd housing = pd.read_csv('https://raw.githubusercontent.com/ageron/handson-ml/master/datasets/housing/housing.csv') housing.head()

pandas로 해당 주소의 .csv파일을 읽어온다. head() 메서드로 처음 다섯행을 출력하여 데이터를 잘 읽어 왔는지 확인해보자.

하나의 샘플에 대해서 여러 features가 있는 것을 볼 수 있다. info() 메서드로 데이터에 대한 정보를 살펴보자.

housing.info()

총 20640개의 샘플이 있다. total_bedrooms 항목을 살혀보면 null이 아닌게 20433개 라고 나와있다. 207개의 샘플은 이 항목에 대한 값이 없는 것이다.
ocean_proximity features에 대해서만 자세히 알아보자.

housing["ocean_proximity"].value_counts()

5가지로 분류할 수 있으며 각 값에 해당하는 샘플의 수를 확인할 수 있다.
describe() 메서드로 숫자형 특성의 요약을 확인할 수 있다. 평균, 백분위, 표준편차, 최대, 최소 등의 정보를 요약해서 보여준다.

housing.describe()

logitude항목에 대해서 각 행을 이해해보자. 총 샘플수는 20640개 이고 평균, 표준편차, 하위 25퍼센트의 값 등등 을 순서대로 나타내고 있다.
이번에는 데이터를 histogram으로 표현해보자.

import matplotlib.pyplot as plt housing.hist(bins=50, figsize=(20,15)) plt.show()

test set, train set 분리하기 실습

불러온 데이터 셋에서 학습을 위한 train_set와 테스트를 위한 test_set을 따로 분리할 것이다. 개발 마지막에 실제 데이터를 가지고 오차를 측정해서 모델을 검증 할 것인데, 이때 훈련 데이터를 가지고 검증에 사용해서는 안되기 때문이다. 그리고 상황에 따라서 학습을 위한 데이터의 편향성을 방지해야 한다. 올바른 알고리즘이 형성 되도록 최대한 데이터들을 대표할 수 있도록 train_set을 분리해야 한다.
sklearn에서 제공하는 train_test_split 함수로 전체 데이터 셋을 두 서브셋으로 분리시킬 수 있다.
train_set은 전체 데이터셋의 20퍼센트로 할 것이고 무작위로 선별하되 난수 발생기에 초기값으로 42라는 seed를 주어서 매번 학습할 때마다 같은 train_set이 split되어 나오도록 한다.

from sklearn.model_selection import train_test_split train_set, test_set = train_test_split(housing, test_size = 0.2, random_state = 42)


이 방법은 무작위로 train_set을 구성하도록 한다. 하지만 앞서 말했다시피 데이터가 계층을 골고루 대표할 수 있어야 한다면 무작위 방식이 아닌 stratified sampling을 해야한다.
median_income항목을 5가지 카테고리로 분류하고 이 다섯가지 카테고리에서 골고루 sample을 가지고 와서 train_set을 구성하도록 해보자.
자 먼저 income_cat 열을 하나 만든다. 이 열은 median_income을 categorize한 값이다.
0.0부터 1.5까지가 1이 되는 것이고 1.5부터 3.0까지가 2가 된다.

import numpy as np 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]) housing["income_cat"].hist()

그럼 카테고리화는 했으니 이제 sklearn에서 제공하는 StratifiedShuffleSplit을 사용해서 train_set과 test_set을 나누어보자.
StratifiedShuffleSplit : 1번 분류할 것이며 train set의 비율은 20퍼센트 재현 가능을 위한 난수 seed는 42로 한다.
이 함수에서 카테고리에 따라 20퍼센트 비율로 train_set이 될 샘플의 indices를 반환해주면 이를 가지고 strat_train_set, strat_test_set에 나누어 담는다.
loc[]는 특정 행을 반환한다.

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]

분리한 데이터 셋을 살펴보자.

strat_test_set["income_cat"].value_counts()

각 카테고리별로 비율이 얼마나 되는지 살펴보자.

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

test_set에서 각 카테고리가 차지하는 비율과 전체 데이터 셋에서 각 카테고리가 차지하는 비율이 유사할 것 이다. 즉 골고루 카테고리별로 데이터를 편향없이 잘 골라와서 train, test set으로 나누었다

이제 원하는 대로 test, train set을 나누었으니 "imcome_cat"항목을 제거하자. 참고로 drop 메서드에서 inplace=True 옵션을 적용하면 원본 dataframe에서 해당 열을 삭제한다. 반면 False의 경우는 원본은 놔두고 해당열을 삭제한 dataframe을 반환한다.

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

데이터 시각화

이제는 데이터를 파악하기 위해 탐색과 시각화를 해보자. 훈련 데이터를 대상으로 살펴볼 것이고 원본을 훼손하지 않기 위해 strat_train_set을 복사하자.

housing = strat_train_set.copy()

그리고 나서 위도와 경도를 축으로 산점도로 시각화 하자. 이때 alpha옵션을 주어서 밀집된 영역이 눈에 띄도록 한다.

housing.plot(kind="scatter", x="longitude", y="latitude", alpha=0.1)

이제 좀 캘리포니아 지도 처럼 보이지 않는가? 더 다양한 features를 시각화 해보자.

s라는 매개변수는 원의 반지름으로 구역의 인구를 나타낸다.

매개변수 c는 주택 가격을 색상으로 나타낸다.

매개변수 cmap은 미리정리된 color map을 사용하는데 낮은가격(파랑), 높은가격(빨강)의 범위를 갖는 jet를 사용한다.

figsize는 도표의 가로세로 크기이다.

legent() 메서드는 자동으로 범례를 추가하도록 해주는 함수이다. 도표 우상단에 population이 표시된걸 알 수 있다.

housing.plot(kind="scatter", x="longitude", y="latitude", alpha=0.4, s=housing["population"]/100, label="population", figsize=(10,7), c="median_house_value", cmap=plt.get_cmap("jet"), colorbar=True,)
plt.legend()

상관관계

이번에는 각 feature들 간의 상관 관계를 파악해보자.

corr_matrix = housing.corr()
corr_matrix

-1에 가까우면 상관관계가 적은 것이고 1에 가까우면 두 feature간의 상관 관계가 높음을 나타낸다.

median_house_value는 median_income과 0.68정도의 상관관계를 가지고 있다. 주택가격과 중간소득이 서로 증가하는 경향이 있다는 것이다.

특성과의 관계를 그림으로도 확인해 볼 수 있다. scatter_matrix()를 사용할 것이고 총 4가지 항목에 대해서 서로간의 관계를 그림으로 나타내보자.

from pandas.plotting import scatter_matrix

attributes = ["median_house_value", "median_income", "total_rooms", "housing_median_age"]
scatter_matrix(housing[attributes], figsize=(12,8))

median_house_value와 median_income의 상관관계가 매우 높아보인다. 주택가격의 상한선을 500000달러로 설정한 탓에 수평직선이 생긴게 보이는데 이 같은 이상한 형태를 알고리즘이 학습하지 않도록 잘라낼 필요가 있어보인다.

쓸데없는 특성 걸러내기

데이터간의 상관관계를 고려하여 잘 살펴보자. 우리는 주택의 가격을 예측해야한다. 그런데 침대의 개수가 주택가격이랑 관계가 있어보이지는 않는다. (상관계수가 0에 가까움) 차라리 가구당 방의 수가 주택 가격에 영향을 미치는 듯 하다. 이렇게 여러 특성을 조합해서 새로운 특성을 만들수 있다.

housing["rooms_per_household"] = housing["total_rooms"]/housing["households"]
housing["bedrooms_per_room"] = housing["total_bedrooms"]/housing["total_rooms"]
housing["population_per_household"] = housing["population"]/housing["households"]
corr_matrix = housing.corr()
corr_matrix["median_house_value"].sort_values(ascending=False)

bedrooms_per_room이 total_bedrooms보다 medain_house_value와 관계가 더 깊어보인다. 이런 식으로 특성들을 조합해서 학습에 더 유용한 특성으로 가공할 수 있다.

728x90
반응형