이번 글은 사이킷런에 내장된 데이터 셋중 하나인 보스턴 주택 데이터를 통해 다중선형회귀분석을 해볼 것이다.
먼저 사이킷런 데이터셋에서 보스턴 주택 데이터를 불러온 후, 전체적인 data set을 확인해 보았다.
from sklearn.datasets import load_boston
boston = load_boston()
boston
#결과
- 위는 생략 -
'data': array([[6.3200e-03, 1.8000e+01, 2.3100e+00, ..., 1.5300e+01, 3.9690e+02,
4.9800e+00],
[2.7310e-02, 0.0000e+00, 7.0700e+00, ..., 1.7800e+01, 3.9690e+02,
9.1400e+00],
[2.7290e-02, 0.0000e+00, 7.0700e+00, ..., 1.7800e+01, 3.9283e+02,
4.0300e+00],
...,
[6.0760e-02, 0.0000e+00, 1.1930e+01, ..., 2.1000e+01, 3.9690e+02,
5.6400e+00],
[1.0959e-01, 0.0000e+00, 1.1930e+01, ..., 2.1000e+01, 3.9345e+02,
6.4800e+00],
[4.7410e-02, 0.0000e+00, 1.1930e+01, ..., 2.1000e+01, 3.9690e+02,
7.8800e+00]]),
'data_module': 'sklearn.datasets.data',
'feature_names': array(['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT'], dtype='<U7'),
'filename': 'boston_house_prices.csv',
'target': array([24. , 21.6, 34.7, 33.4, 36.2, 28.7, 22.9, 27.1, 16.5,
18.9, 15. , 18.9, 21.7, 20.4, 18.2, 19.9, 23.1, 17.5, 20.2, 18.2,
13.6, 19.6, 15.2, 14.5, 15.6, 13.9, 16.6, 14.8, 18.4, 21. , 12.7,
14.5, 13.2, 13.1, 13.5, 18.9, 20. , 21. , 24.7, 30.8, 34.9, 26.6,
...,
20.6, 21.2, 19.1, 20.6, 15.2, 7. , 8.1, 13.6, 20.1, 21.8, 24.5,
23.1, 19.7, 18.3, 21.2, 17.5, 16.8, 22.4, 20.6, 23.9, 22. , 11.9])}
데이터에 따르면 각각에 해당되는 feature명은 아래와 같았으며,
CRIM
: 지역별 범죄 발생률ZN
: 25,000 평방피트를 초과하는 거주 지역의 비율INDUS
: 비상업 지역 넓이 비율CHAS
: 찰스강에 대한 더미 변수 (강의 경계에 위치할 시 1, 아닐 시 2)NOX
: 일산화질소 농도RM
: 거주할 수 있는 방 개수AGE
: 1940년 이전에 건축된 소유 주택의 비율DIS
: 5개 주요 고용센터까지의 가중 거리RAD
: 고속도로 접근 용이도TAX
: 10,000달러당 재산세율PTRATIO
: 지역의 교사와 학생 수 비율B
: 지역의 흑인 거주 비율LSTAT
: 하위 계층의 비율X 값은
boston['data]
#결과
array([[6.3200e-03, 1.8000e+01, 2.3100e+00, ..., 1.5300e+01, 3.9690e+02,
4.9800e+00],
[2.7310e-02, 0.0000e+00, 7.0700e+00, ..., 1.7800e+01, 3.9690e+02,
9.1400e+00],
[2.7290e-02, 0.0000e+00, 7.0700e+00, ..., 1.7800e+01, 3.9283e+02,
4.0300e+00],
...,
[6.0760e-02, 0.0000e+00, 1.1930e+01, ..., 2.1000e+01, 3.9690e+02,
5.6400e+00],
[1.0959e-01, 0.0000e+00, 1.1930e+01, ..., 2.1000e+01, 3.9345e+02,
6.4800e+00],
[4.7410e-02, 0.0000e+00, 1.1930e+01, ..., 2.1000e+01, 3.9690e+02,
7.8800e+00]]),
y 값은 아래에 해당하는 것을 알 수 있었다.
boston['target']
#결과
array([24. , 21.6, 34.7, 33.4, 36.2, 28.7, 22.9, 27.1, 16.5,
18.9, 15. , 18.9, 21.7, 20.4, 18.2, 19.9, 23.1, 17.5, 20.2, 18.2,
13.6, 19.6, 15.2, 14.5, 15.6, 13.9, 16.6, 14.8, 18.4, 21. , 12.7,
14.5, 13.2, 13.1, 13.5, 18.9, 20. , 21. , 24.7, 30.8, 34.9, 26.6,
...,
20.6, 21.2, 19.1, 20.6, 15.2, 7. , 8.1, 13.6, 20.1, 21.8, 24.5,
23.1, 19.7, 18.3, 21.2, 17.5, 16.8, 22.4, 20.6, 23.9, 22. , 11.9])
우선 보스턴 데이터를 DataFrame으로 변환, y값을 DataFrame에 Price라는 이름으로 추가한 후 처음 5개의 data를 출력시켜보았다.
df = pd.DataFrame(boston.data, columns = boston.feature_names)
df['Price'] = boston.target
df.head()
우선 각각의 feature가 가격에 얼마나 큰 영향을 미치는지 각 feature를 X축으로 두고 y값에 대응되게끔 점 그래프를 그려보았다.
fig, axs = plt.subplots(nrows = 3, ncols = 4, figsize = (55,25))
axs[0,0].scatter(df['CRIM'],df['Price'], color = 'r')
axs[1,0].scatter(df['ZN'],df['Price'], color = 'g')
axs[2,0].scatter(df['INDUS'],df['Price'], color = 'b')
axs[0,1].scatter(df['NOX'],df['Price'], color = 'c')
axs[1,1].scatter(df['RM'],df['Price'], color = 'm')
axs[2,1].scatter(df['AGE'],df['Price'], color = 'y')
axs[0,2].scatter(df['DIS'],df['Price'], color = 'k')
axs[1,2].scatter(df['RAD'],df['Price'], color = '#77AC30')
axs[2,2].scatter(df['TAX'],df['Price'], color = '#A2142F')
axs[0,3].scatter(df['PTRATIO'],df['Price'], color = '#D95319')
axs[1,3].scatter(df['B'],df['Price'], color = '#4DBEEE')
axs[2,3].scatter(df['LSTAT'],df['Price'], color = '#7E2F8E')
잘 안보이니 점의 분포만을 살펴보자. 몇몇 그래프는 선형적인 표현이 가능해 집값에 영향을 끼칠것으로 예상되지만, 대부분의 그래프는 보다시피 해당되는 하나의 변수가 집값에 큰 영향이 있을지는 의구심이 든다.
다음으로는 기존 데이터를 8:2 비율로 train set와 test set으로 분리한 후,
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(boston['data'], boston['target'],test_size=0.2,shuffle=True)
다중선형회귀모델을 만들어 학습을 진행하였으며, weight(가중치)와 bias(y절편)을 각각 구했다.
from sklearn.linear_model import LinearRegression
reg = LinearRegression()
model_b = reg.fit(X_train, y_train)
print("weight: {}\n \n bias: {}\n".format(model_b.coef_,model_b.intercept_))
#결과
weight: [-1.13522138e-01 5.04992315e-02 5.23257280e-02 2.32049999e+00
-1.58975035e+01 4.07113083e+00 -8.97413901e-03 -1.51168959e+00
2.59756522e-01 -1.13547220e-02 -9.22686382e-01 1.09230301e-02
-5.23066968e-01]
bias: 32.92137291801792
또한 X_train, X_test 데이터에 대한 예측 성능 점수를 측정해보았다.
print('학습 데이터 점수:', model_b.score(X_train, y_train), '\n검증 데이터 점수:', model_b.score(X_test, y_test))
#결과
학습 데이터 점수: 0.7473852616606151
검증 데이터 점수: 0.6984168912699038
마지막으로 학습된 모델에 테스트 데이터를 넣어 예측 값을 출력해보았다.
model_b.predict(X_test)
#결과
array([34.05351215, 25.19889237, 26.35370705, 27.7440464 , 21.89706241,
25.12263103, 19.34223722, 21.08883388, 12.00206156, 24.22509842,
32.99068144, 27.04706245, 17.8406796 , 14.54634399, 20.94751324,
22.95470931, 18.76639891, 41.14365056, 13.83503885, 15.63106075,
22.80815271, 2.38255142, 20.39834382, 12.61302238, 35.84618721,
34.66269176, 22.30918166, 22.24809004, 23.47045167, 12.53862682,
23.92179391, 17.20333378, 17.85890761, 12.40477655, 17.14474174,
18.3944331 , 22.79219854, 22.88623887, 37.18100353, 9.31853866,
20.48377003, 28.21022085, 15.28935866, 8.22041472, 21.45221701,
14.26478512, 22.18316431, 22.74812137, 26.99948227, 28.59313639,
23.32768005, 26.53173908, 22.47937 , 21.78500476, 22.01106402,
40.6478179 , 18.29311108, 37.41613122, 0.20726833, 18.9482604 ,
31.72355804, 8.31581097, 12.2559131 , 33.76434062, 19.3316927 ,
5.47040797, 22.44897942, 19.64752773, 10.76782999, 13.75052219,
16.79333825, 19.14960042, 7.07745839, 20.39092657, 27.3682695 ,
31.63914092, 16.86500341, 27.4107308 , 19.56003247, 12.97319511,
35.37164057, 27.56598174, 9.34454975, 21.93072387, 28.92053167,
20.79900033, 17.3896431 , 31.28834088, 20.71422485, 31.10088908,
20.23072123, 24.75321696, 31.99684696, 27.31049648, 5.92270475,
32.21220369, 20.04188021, 28.56213573, 20.04417415, 22.61270177,
32.69358556, 21.42150666])
오늘은 boston house prices 데이터set을 통해 다중선형회귀를 진행해봤다. 비록 모델에 대한 점수가 잘 나오지 않았지만 예상되는 바로는 필요없는 데이터, 혹은 모델을 구하는데 방해가 되는 데이터가 있기 때문에 모델의 성능을 저하시킨것으로 예상된다. 또한, feature에 관계없이 집 값 분산의 정도가 매우 큰 데이터도 있었기 때문에 모델이 학습하는데 큰 지장이 있었을 것으로 예상된다.