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)

  1. CRIM: 도시별 범죄발생률

  2. ZN: 25,000평을 넘는 토지의 비율

  3. INDUS: 도시별 비상업 지구의 비유

  4. CHAS: 찰스 강의 더미 변수(1 = 강의 경계, 0 = 나머지)

  5. NOX: 일산화질소 농도

  6. RM: 주거할 수 있는 평균 방의개수

  7. AGE: 1940년 이전에 지어진 주택의 비율

  8. DIS: 5개의 고용지원센터까지의 가중치가 고려된 거리

  9. RAD: 고속도로의 접근 용이성에 대한 지표

  10. TAX: 10,000달러당 재산세 비율

  11. PTRATIO: 도시별 교사와 학생의 비율

  12. B: 도시의 흑인 거주 비유

  13. 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

아래 식들은 해당 출처에서 가져옴

https://rk1993.tistory.com/entry/Ridge-regression%EC%99%80-Lasso-regression-%EC%89%BD%EA%B2%8C-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0

Rdige Regression

  • L2 Regularization을 이용해서 가중치 w를 제한하는 기법

Lasso Regression

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

비교

ElasticNet Regression

  • Ridge와 Lasso를 결합한 기법

https://nurilee.com/2020/01/26/data-science-model-summary-linear-ridge-lasso-elasticnet/

어떤 것을 써야할까?

  • 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?