2.3 데이터 가져오기 | 목차 | 2.5 머신러닝 알고리즘을 위한 데이터 준비
지금까지는 다뤄야 할 데이터의 종류를 파악하기 위해 데이터를 간단히 살펴보았습니다. 이제 조금 더 깊이 파악해보도록 하겠습니다.
먼저 테스트 세트를 떼어놓았는지 확인하고 훈련 세트에 대해서만 탐색을 하겠습니다. 또한 훈련 세트가 매우 크면 조작을 간단하고 빠르게 하기 위해 탐색을 위한 세트를 별도로 샘플링할 수도 있습니다. 예제에서는 크기가 작으므로 훈련 세트 전체를 사용하겠습니다. 훈련 세트를 손상시키지 않기 위해 복사본을 만들어 사용합니다.
housing = strat_train_set.copy()
2.4.1 지리적 데이터 시각화
지리 정보(위도와 경도)가 있으니 모든 구역을 산점도로 만들어 데이터를 시각화하는 것은 좋은 생각입니다(그림 2-11).
housing.plot(kind="scatter", x="longitude", y="latitude")
그림 2-11 데이터의 지리적인 산점도
이 그림은 캘리포니아 지역을 잘 나타내지만 어떤 특별한 패턴을 찾기는 힘듭니다. alpha 옵션을 0.1로 주면 데이터 포인트가 밀집된 영역을 잘 보여줍니다(그림 2-12).
housing.plot(kind="scatter", x="longitude", y="latitude", alpha=0.1)
그림 2-12 밀집된 지역이 잘 부각된 산점도
훨씬 나아졌네요. 확실히 베이 에어리어Bay Area와 로스앤젤레스Los Angeles 근처, 샌디에이고San Diego 같이 밀집된 지역이 눈에 잘 띄고, 센트럴 밸리Central Valley 특히 새크라멘토Sacramento와 프레즈노Fresno 근처를 따라 밀집된 지역이 긴 띠를 이루고 있습니다.26
일반적으로 우리 뇌는 그림에서 패턴을 잘 인식해내지만 더 두드러진 패턴을 보려면 매개변수를 다양하게 조절해봐야 합니다.
이제 주택 가격을 나타내보겠습니다(그림 2-13). 원의 반지름은 구역의 인구를 나타내고(매개변수 s), 색깔은 가격을 나타냅니다(매개변수 c). 여기서는 미리 정의된 컬러 맵color map 중 파란색(낮은 가격)에서 빨간색(높은 가격)까지 범위를 가지는 jet을 사용합니다(매개변수 cmap).27
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, sharex=False ) plt.legend()
그림 2-13 캘리포니아 주택 가격
아마 예상했겠지만 이 그림에서 주택 가격은 지역(예를 들면 바다와 인접한 곳)과 인구 밀도에 관련이 매우 크다는 사실을 알 수 있습니다. 이런 내용은 군집 알고리즘clustering algorithm을 사용해 주요 군집을 찾고 군집의 중심까지의 거리를 재는 특성을 추가할 때 도움이 됩니다. 해안 근접성 특성이 유용할 수도 있지만, 북부 캘리포니아 지역의 해안가는 주택 가격이 그리 높지 않아 간단한 규칙이 적용되기 어렵습니다.28
2.4.2 상관관계 조사
데이터셋이 너무 크지 않으므로 모든 특성 간의 표준 상관계수standard correlation coefficient(피어슨의 r이라고도 부릅니다)를 corr() 메서드를 이용해 쉽게 계산할 수 있습니다.
corr_matrix = housing.corr()
중간 주택 가격과 다른 특성 사이의 상관관계 크기가 얼마나 되는지 살펴보겠습니다.
>>> corr_matrix["median_house_value"].sort_values(ascending=False) median_house_value 1.000000 median_income 0.687160 total_rooms 0.135097 housing_median_age 0.114110 households 0.064506 total_bedrooms 0.047689 population -0.026920 longitude -0.047432 latitude -0.142724 Name: median_house_value, dtype: float64
상관관계의 범위는 -1부터 1까지입니다. 1에 가까우면 강한 양의 상관관계를 가진다는 뜻입니다. 예를 들어 중간 주택 가격(median_house_value)은 중간 소득(median_income)이 올라갈 때 증가하는 경향이 있습니다. 계수가 -1에 가까우면 강한 음의 상관관계를 나타냅니다. 위도latitude와 중간 주택 가격 사이에는 약한 음의 상관관계가 보입니다(즉, 북쪽으로 갈수록 주택 가격이 조금씩 내려가는 경향이 있습니다). 마지막으로 계수가 0에 가까우면 선형적인 상관관계가 없다는 뜻입니다. [그림 2-14]는 가로축과 세로축 사이의 여러 가지 상관계수를 그래프로 보여줍니다.
그림 2-14 여러 가지 데이터셋에 나타난 표준 상관계수(출처: 위키백과 – 퍼블릭 도메인 이미지)
특성 사이의 상관관계를 확인하는 다른 방법은 숫자형 특성 사이에 산점도를 그려주는 판다스의 scatter_matrix 함수를 사용하는 것입니다. 여기서는 숫자형 특성이 11개이므로 총 개의 그래프가 되어 한 페이지에 모두 나타낼 수 없으므로, 중간 주택 가격과 상관관계가 높아 보이는 특성 몇 개만 살펴보겠습니다(그림 2-15).
from pandas.plotting import scatter_matrix attributes = ["median_house_value", "median_income", "total_rooms", "housing_median_age"] scatter_matrix(housing[attributes], figsize=(12, 8))
그림 2-15 산점도 행렬
대각선 방향(왼쪽 위에서 오른쪽 아래로)은 각 변수 자신에 대한 것이라 그냥 직선이 되므로 유용하지 않습니다. 그래서 판다스는 이곳에 각 특성의 히스토그램을 그립니다(다른 옵션도 가능합니다. 자세한 내용은 판다스 문서를 참고하세요29).
중간 주택 가격(median_house_value)을 예측하는 데 가장 유용할 것 같은 특성은 중간 소득(median_income)이므로 상관관계 산점도를 확대해보겠습니다(그림 2-16).
housing.plot(kind="scatter", x="median_income", y="median_house_value", alpha=0.1)
그림 2-16 중간 소득 대 중간 주택 가격
이 그래프는 몇 가지 사실을 보여줍니다. 첫째, 상관관계가 매우 강합니다. 위쪽으로 향하는 경향을 볼 수 있으며 포인트들이 너무 널리 퍼져 있지 않습니다. 둘째, 앞서 본 가격 제한 값이 $500,000에서 수평선으로 잘 보입니다. 하지만 이 그래프에서 직선에 가까운 형태를 더 볼 수 있습니다. $450,000 근처에 수평선이 보이고 $350,000와 $280,000에도 있고 그 아래 조금 더 보입니다. 알고리즘이 데이터에서 이런 이상한 형태를 학습하지 않도록 해당 구역을 제거하는 것이 좋습니다.
2.4.3 특성 조합으로 실험
앞 절에서 데이터를 탐색하고 통찰을 얻는 여러 방법에 대한 아이디어를 얻었기 바랍니다. 머신러닝 알고리즘에 주입하기 전에 정제해야 할 조금 이상한 데이터를 확인했고, 특성 사이(특히 타깃 속성과의 사이)에서 흥미로운 상관관계를 발견했습니다. 어떤 특성은 꼬리가 두꺼운 분포라서 데이터를 변형해야 할 것입니다(예를 들면 로그 스케일로). 물론 프로젝트마다 처한 상황은 다르겠지만 일반적인 아이디어는 비슷합니다.
머신러닝 알고리즘용 데이터를 실제로 준비하기 전에 마지막으로 해볼 수 있는 것은 여러 특성의 조합을 시도해보는 것입니다. 예를 들어 특정 구역의 방 개수는 얼마나 많은 가구수가 있는지 모른다면 그다지 유용하지 않습니다. 진짜 필요한 것은 가구당 방 개수입니다. 비슷하게 전체 침대 개수도 그 자체로는 유용하지 않습니다. 즉, 방 개수와 비교하는 게 낫습니다. 가구당 인원도 흥미로운 특성 조합일 것 같습니다. 이런 특성들을 만들어봅시다.
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) median_house_value 1.000000 median_income 0.687160 rooms_per_household 0.146285 total_rooms 0.135097 housing_median_age 0.114110 households 0.064506 total_bedrooms 0.047689 population_per_household -0.021985 population -0.026920 longitude -0.047432 latitude -0.142724 bedrooms_per_room -0.259984 Name: median_house_value, dtype: float64
나쁘지 않네요. 새로운 bedrooms_per_room 특성은 전체 방 개수나 침대 개수보다 중간 주택 가격과의 상관관계가 훨씬 높습니다. 확실히 침대/방의 비율이 낮은 집은 더 비싼 경향이 있습니다. 가구당 방 개수도 구역 내 전체 방 개수보다 더 유용합니다. 당연히 더 큰 집이 더 비쌉니다.
이 탐색 단계는 완벽하지 않습니다. 시작을 잘해서 빨리 통찰을 얻는 것이 처음 프로토타입을 잘 만드는 데 도움이 될 것입니다. 하지만 이는 반복적인 과정입니다. 프로토타입을 만들고 실행한 후 그 결과를 분석해서 더 많은 통찰을 얻고 다시 이 탐색 단계로 돌아오게 됩니다.30
26 옮긴이_ 캘리포니아 해변을 따라서 경도 -122° 근처가 샌프란시스코가 있는 베이 에어리어 지역이고, 경도 -118° 근처가 로스앤젤레스, 경도 -117° 근처가 샌디에이고 지역입니다. 센트럴 밸리는 샌프란시스코 위에서부터 로스앤젤레스 위쪽까지 캘리포니아 중앙부에 길게 뻗은 지역을 말합니다. 새크라멘토는 위도 38.5°, 경도 -121.5° 근처이며 프레즈노는 위도 36.7°, 경도 -119.8° 근처입니다. 이 지역 모두 산점도에서 밀도가 높은 것을 확인할 수 있습니다.
27 책에는 흑백으로 보일 텐데 베이 에어리어에서 샌디에이고까지 해안가 대부분이 붉게 나타납니다(아마 예상했겠지만). 새크라멘토 주변에도 노란색이 나타납니다. 옮긴이_ 옮긴이의 깃허브에 있는 주피터 노트북을 보면 컬러 이미지를 확인할 수 있습니다.
28 옮긴이_ 북부 캘리포니아는 대략 위도 35° 위쪽의 지역으로 베이 에어리어를 제외하고는 해안가의 주택 가격이 높지 않게 나타납니다.
29 옮긴이_ scatter_matrix 메서드의 diagonal 매개변수에 히스토그램을 나타내는 ‘hist’와 커널 밀도 추정(Kernel Density Estimation)을 나타내는 ‘kde’를 지정할 수 있습니다. 기본값은 ‘hist’입니다.
30 옮긴이_ 대부분의 소프트웨어 프로젝트가 그렇지만 특히 머신러닝 프로젝트는 빠른 프로토타이핑과 반복적인 프로세스가 권장됩니다.
2.3 데이터 가져오기 | 목차 | 2.5 머신러닝 알고리즘을 위한 데이터 준비