7 Mon
현업 실무자에게 배우는 Kaggle 머신러닝 입문
K-Fold Cross Validation
데이터의 개수가 너무 작을 경우 트레이닝 데이터와 테스트 데이터의 분류 방식에 따라 성능 측정결과가 크게 달라질 수 있다.
트레이닝 데이터에 극단적인 분포의 데이터가 몰려 있다면 테스트 데이터의 성능이 잘 안나오게 된다.
https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.KFold.html
>>> import numpy as np
>>> from sklearn.model_selection import KFold
>>> X = np.array([[1, 2], [3, 4], [1, 2], [3, 4]])
>>> y = np.array([1, 2, 3, 4])
>>> kf = KFold(n_splits=2)
>>> kf.get_n_splits(X)
2
>>> print(kf)
KFold(n_splits=2, random_state=None, shuffle=False)
>>> for train_index, test_index in kf.split(X):
... print("TRAIN:", train_index, "TEST:", test_index)
... X_train, X_test = X[train_index], X[test_index]
... y_train, y_test = y[train_index], y[test_index]
TRAIN: [2 3] TEST: [0 1]
TRAIN: [0 1] TEST: [2 3]
Feature Engineering - Feature Selection
도메인 지식이나 분석을 통해 유의미한 특징들만을 선별해내거나 Feature의 형태를 더욱 적합한 형태로 변경하는 것
적절한 Feature Enginerring은 머신러닝 모델의 성능에 큰 영향을 끼칠 수 있다
다음과 같이 3종류로 나뉜다
Feature Selection
Normalization
Feature Generation
Feature Selection
예측값과 연관이 없는 불필요한 특징을 제거해서 머신러닝 모델의 성능을 더욱 높이는 기법
제거할 특징을 선택하기 위해 상관 분석등을 진행할 수 있다
상관 분석(Correlation Analysis) & regplot()
상관 분석 또는 상관 관계는 확률론과 통계학에서 두 변수간에 어떤 선형적 또는 비선형적 관계를 갖고 있는지에 대한 방법이다
1에 가까운 값 : 두 변수간의 양의 상관관계
0에 가까운 값 : 두 변수간의 상관관계가 없음
-1에 가까운 값 : 두 변수간의 음의 상관관계
구현
scikit-learn을 이용해 구현할 수 있다
corr=df.corr()
plt.figure(figsize=(10, 10))
sns.heatmap(corr,
vmax=0.8,
linewidths=0.01,
square=True,
annot=True,
cmap='YlGnBu');
plt.tilte('Correlation Matrix')
sns.regplot
으로 Feature간의 경향성 출력
sns.regplot(data={dataframe}, x={컬럼명}, y={컬럼명})
형태를 이용해서 regression line이 포함된 scatter plot을 그릴 수 있다.
Regression 알고리즘으로 보스턴 부동산 가격 예측해보기 (EDA & Feature Selection)
1970년도의 보스턴 지역의 부동산 가격을 수집한 데이터
Feature 데이터 : 13개
데이터 개수 : 506개
Target data : 보스턴 부동산 집값 (단위 : $1000)
사용 알고리즘
LinearRegression
추가적인 적용기법
Feature Selection
보스턴 부동산 데이터의 특징들(Features)
CRIM: 도시별 범죄발생률
ZN: 25,000평을 넘는 토지의 비율
INDUS: 도시별 비상업 지구의 비유
CHAS: 찰스 강의 더미 변수(1 = 강의 경계, 0 = 나머지)
NOX: 일산화질소 농도
RM: 주거할 수 있는 평균 방의개수
AGE: 1940년 이전에 지어진 주택의 비율
DIS: 5개의 고용지원센터까지의 가중치가 고려된 거리
RAD: 고속도로의 접근 용이성에 대한 지표
TAX: 10,000달러당 재산세 비율
PTRATIO: 도시별 교사와 학생의 비율
B: 도시의 흑인 거주 비유
LSTAT: 저소득층의 비율
전체 특징(Feature)를 사용한 Linear Regression
X = boston_house_data.data
y = boston_house_data.target
type(X)
numpy.ndarray
from sklearn.model_selection import KFold
num_split = 5
kf = KFold(n_splits=num_split)
avg_MSE = 0.0
for train_index, test_index in kf.split(X):
X_train, X_test = X[train_index], X[test_index]
y_train, y_test = y[train_index], y[test_index]
# 선형회귀(Linear Regression) 모델 선언하기
lr = LinearRegression()
# 선형회귀(Linear Regression) 모델 학습하기
lr.fit(X_train, y_train)
# 테스트 데이터에 대한 예측을 수행합니다.
y_pred = lr.predict(X_test)
# MSE(Mean Squared Error)를 측정합니다.
avg_MSE = avg_MSE + mean_squared_error(y_test, y_pred)
print('Average MSE :', avg_MSE/num_split)
print('Avergae RMSE :', np.sqrt(avg_MSE/num_split))
Average MSE : 37.13180746769903
Avergae RMSE : 6.093587405436885
상관분석(Correlation Analysis)
boston_house_df = pd.DataFrame(boston_house_data.data, columns = boston_house_data.feature_names)
boston_house_df['PRICE'] = y
boston_house_df.head()
CRIM
ZN
INDUS
CHAS
NOX
RM
AGE
DIS
RAD
TAX
PTRATIO
B
LSTAT
PRICE
0
0.00632
18.0
2.31
0.0
0.538
6.575
65.2
4.0900
1.0
296.0
15.3
396.90
4.98
24.0
1
0.02731
0.0
7.07
0.0
0.469
6.421
78.9
4.9671
2.0
242.0
17.8
396.90
9.14
21.6
2
0.02729
0.0
7.07
0.0
0.469
7.185
61.1
4.9671
2.0
242.0
17.8
392.83
4.03
34.7
3
0.03237
0.0
2.18
0.0
0.458
6.998
45.8
6.0622
3.0
222.0
18.7
394.63
2.94
33.4
4
0.06905
0.0
2.18
0.0
0.458
7.147
54.2
6.0622
3.0
222.0
18.7
396.90
5.33
36.2
corr = boston_house_df.corr()
plt.figure(figsize=(10, 10));
sns.heatmap(corr,
vmax=0.8,
linewidths=0.01,
square=True,
annot=True,
cmap='YlGnBu');
plt.title('Feature Correlation');

regplot으로 보는 상관관계
figure, ax_list = plt.subplots(nrows=3, ncols=5)
figure.set_size_inches(20,20)
for i in range(len(full_column_list)):
sns.regplot(data=boston_house_df, x=full_column_list[i], y='PRICE', ax=ax_list[int(i/5)][int(i%5)])
ax_list[int(i/5)][int(i%5)].set_title("regplot " + full_column_list[i])

유의미한 Feature들만을 남기는 Feature Selection
print(type(corr))
corr
<class 'pandas.core.frame.DataFrame'>
CRIM
ZN
INDUS
CHAS
NOX
RM
AGE
DIS
RAD
TAX
PTRATIO
B
LSTAT
PRICE
CRIM
1.000000
-0.200469
0.406583
-0.055892
0.420972
-0.219247
0.352734
-0.379670
0.625505
0.582764
0.289946
-0.385064
0.455621
-0.388305
ZN
-0.200469
1.000000
-0.533828
-0.042697
-0.516604
0.311991
-0.569537
0.664408
-0.311948
-0.314563
-0.391679
0.175520
-0.412995
0.360445
INDUS
0.406583
-0.533828
1.000000
0.062938
0.763651
-0.391676
0.644779
-0.708027
0.595129
0.720760
0.383248
-0.356977
0.603800
-0.483725
CHAS
-0.055892
-0.042697
0.062938
1.000000
0.091203
0.091251
0.086518
-0.099176
-0.007368
-0.035587
-0.121515
0.048788
-0.053929
0.175260
NOX
0.420972
-0.516604
0.763651
0.091203
1.000000
-0.302188
0.731470
-0.769230
0.611441
0.668023
0.188933
-0.380051
0.590879
-0.427321
RM
-0.219247
0.311991
-0.391676
0.091251
-0.302188
1.000000
-0.240265
0.205246
-0.209847
-0.292048
-0.355501
0.128069
-0.613808
0.695360
AGE
0.352734
-0.569537
0.644779
0.086518
0.731470
-0.240265
1.000000
-0.747881
0.456022
0.506456
0.261515
-0.273534
0.602339
-0.376955
DIS
-0.379670
0.664408
-0.708027
-0.099176
-0.769230
0.205246
-0.747881
1.000000
-0.494588
-0.534432
-0.232471
0.291512
-0.496996
0.249929
RAD
0.625505
-0.311948
0.595129
-0.007368
0.611441
-0.209847
0.456022
-0.494588
1.000000
0.910228
0.464741
-0.444413
0.488676
-0.381626
TAX
0.582764
-0.314563
0.720760
-0.035587
0.668023
-0.292048
0.506456
-0.534432
0.910228
1.000000
0.460853
-0.441808
0.543993
-0.468536
PTRATIO
0.289946
-0.391679
0.383248
-0.121515
0.188933
-0.355501
0.261515
-0.232471
0.464741
0.460853
1.000000
-0.177383
0.374044
-0.507787
B
-0.385064
0.175520
-0.356977
0.048788
-0.380051
0.128069
-0.273534
0.291512
-0.444413
-0.441808
-0.177383
1.000000
-0.366087
0.333461
LSTAT
0.455621
-0.412995
0.603800
-0.053929
0.590879
-0.613808
0.602339
-0.496996
0.488676
0.543993
0.374044
-0.366087
1.000000
-0.737663
PRICE
-0.388305
0.360445
-0.483725
0.175260
-0.427321
0.695360
-0.376955
0.249929
-0.381626
-0.468536
-0.507787
0.333461
-0.737663
1.000000
useful_feature_list = corr.query("PRICE > 0.5 or PRICE < -0.5").index.values.tolist()
useful_feature_list.remove('PRICE')
print(useful_feature_list)
['RM', 'PTRATIO', 'LSTAT']
X = boston_house_df.loc[:,useful_feature_list].values
y = boston_house_df.iloc[:,-1].values
print(X.shape)
print(y.shape)
(506, 3)
(506,)
Feature Selection 결과 with K-fold
num_split = 5
kf = KFold(n_splits=num_split)
avg_MSE = 0.0
for train_index, test_index in kf.split(X):
X_train, X_test = X[train_index], X[test_index]
y_train, y_test = y[train_index], y[test_index]
# 선형회귀(Linear Regression) 모델 선언하기
lr = LinearRegression()
# 선형회귀(Linear Regression) 모델 학습하기
lr.fit(X_train, y_train)
# 테스트 데이터에 대한 예측을 수행합니다.
y_pred = lr.predict(X_test)
# MSE(Mean Squared Error)를 측정합니다.
avg_MSE = avg_MSE + mean_squared_error(y_test, y_pred)
print('Average MSE :', avg_MSE/num_split)
print('Avergae RMSE :', np.sqrt(avg_MSE/num_split))
Average MSE : 34.10008149030686
Avergae RMSE : 5.839527505741099
결론
성능이 더 좋아진 것을 알 수 있다
이전
Average MSE : 37.13180746769903
Avergae RMSE : 6.093587405436885
이후
Average MSE : 34.10008149030686
Avergae RMSE : 5.839527505741099
Feature Engineering - Feature Normalization
Feature값의 범위를 조정하는 기법
Feature를 정규화 할 경우 더 안정적으로 머신러닝 모델을 학습시킬 수 있다
Min-Max Scaling을 할 수도 있다. 이 때는 모든 값이 0에서 1사이에 위치하게 된다.
x' = (x - min) / (max- min)
from sklearn import preprocessing
normalized_data = preprocessing.StandardScaler().
fit_transform(data)
from sklearn import preprocessing
normalized_data = preprocessing.MinMaxScaler().
fit_transform(data)
Feature Engineering - Feature Generation
기존의 특징값들을 조합해서 새로운 특징을 만드는 방식
가장 대표적인 방식은 PolynomialFeature 방법이다
서로 다른 특징들간의 곱셈을 새로운 Feature로 만든다
예를 들면 범죄율 x1과 저소득층 비율 x2를 곱해 새로운 특징 x1*x2 를 만든다
아래 함수는 보스턴 부동산에 대한 13개의 특징에 91개의 새로운 특징을 추가하여 총 104개의 특징을 반환하게 된다
from sklearn.preprocessing import MinMaxScaler,
PolynomialFeatures
def load_extended_boston():
boston = load_boston()
X = boston.data
X = MinMaxScaler().fit_transform(boston.data)
X = PolynomialFeatures(degree=2, include_bias=False).
fit_transform(X)
return X, boston.target
Ridge & Lasso & ElasticNet Regression
아래 식들은 해당 출처에서 가져옴
Rdige Regression
L2 Regularization을 이용해서 가중치 w를 제한하는 기법


Lasso Regression
L1 Regularization을 이용해서 가중치 w를 제한하는 기법

비교

ElasticNet Regression
Ridge와 Lasso를 결합한 기법

어떤 것을 써야할까?
정답은 없다.
상황에 맞게 써야 하는 것이 현답.
이 상황에 맞게 써야하는 기준을 가이드로 제공하고 있다

Regression 안에서는 다음과 같이 분류된다
데이터가 10만개 이하인가? => SGD Regressor
전체 feature 중 특정 feature의 중요도가 더 큰가? => Lasso, ElasticNet
전체 feature의 중요도가 고르다 => Ridge
잘 작동을 하지 않는가? => Ensemble Regressor
코드레벨 구현
from sklearn.linear_model import LinearRegression,
Ridge,
Lasso,
ElasticNet
lr = LinearRegression()
ridge_reg = Ridge()
lasso_reg = Lasso()
elasticnet_Reg = ElasticNet()
하이퍼 파라미터
알고리즘에 의해 변경되는 파라미터 외에 알고리즘 디자이너가 설정해줘야 하는 값을
하이퍼 파라미터
라고 한다적절한 하이퍼 파리미터 값을 정해주는 것도 모델의 성능의 중요한 요소 중 하나
보스턴 부동산 가격 예측 성능 향상시켜보기 (Feature Generation & Advanced Estimator)
Input data : 104 Dimension (PolynomialFeatures를 사용해서 확장된 Feature Set)
Target data : 보스턴 부동산 집값 (단위 : $1000)
사용 알고리즘
LinearRegression
Ridge
Lasso
ElasticNet
추가적인 적용기법
Feature Generation (PolynomialFeatures)
Last updated
Was this helpful?