728x90
반응형

1. PCA 처리 이후 XGBoost 모델 활용

all_data = pd.concat([train,test]) # 훈련 데이터와 테스트 데이터 합치기
# all_data = all_data.drop('Survived' , axis = 1) # 타깃값 제거
all_data = all_data.drop('yield' , axis = 1) # 타깃값 제거

all_data

# [fruitset , fruitmass ,seeds]

 

16열

[fruitset , fruitmass ,seeds] ==> 연속형 자료

 

all_data_pca = all_data.iloc[:,:-3]
all_data_pca
from sklearn.decomposition import PCA

# 변수 간의 상관관계 행렬 계산
corr_matrix = all_data_pca.corr()
threshold = 0.9 # 상관관계의 임계값 설정
high_corr_vars = corr_matrix[abs(corr_matrix) >= threshold].stack().index
high_corr_vars = [var[0] for var in high_corr_vars if var[0] != var[1]]
# 상관관계 행렬을 기반으로 PCA 수행
pca = PCA(n_components=1)
pca.fit(corr_matrix)

# 주성분 변환 적용
transformed_data = pca.transform(all_data_pca)

# 변환된 데이터로 업데이트
all_data['PCA_Component'] = transformed_data

# 상관관계가 높은 변수들을 제외한 업데이트된 데이터
selected_vars = [col for col in all_data_pca.columns if col not in high_corr_vars]
updated_data = all_data_pca[selected_vars]
updated_data

PCA 이후 남은 피처들

==> updated_data

 

all_data_updated = pd.concat([updated_data, all_data[['fruitset' , 'fruitmass' ,'seeds' , 'PCA_Component']]], axis=1)
all_data_updated

all_data_updated

==> PCA_Components ==> PCA처리 이후 모은 데이터

 

PCA(Principal Component Analysis)는 데이터의 차원을 줄이기 위한 기법 중 하나입니다. PCA는 고차원 데이터를 저차원 공간으로 투영하여 데이터의 주요한 변동성을 설명할 수 있는 주성분(principal component)들을 추출합니다.
PCA는 데이터의 가장 큰 분산을 가지는 방향을 찾아 첫 번째 주성분을 정의하고, 이후의 주성분은 이전 주성분과 직교하는 방향 중에서 다음으로 큰 분산을 가지는 방향을 찾습니다. 이를 통해 데이터의 차원을 줄이고, 데이터의 구조와 변동성을 가장 잘 보존하는 저차원 표현을 얻을 수 있습니다.
PCA의 주성분들은 데이터의 원래 변수들의 선형 조합으로 구성되며, 각 주성분은 원래 변수들의 가중치(coefficient)로 구성된 벡터입니다. 이렇게 추출된 주성분은 데이터를 설명하는 데 가장 중요한 특징들을 포착하고, 차원 축소나 데이터 시각화 등 다양한 분석에 활용됩니다.
PCA에서 사용되는 PCA components는 주성분들을 의미합니다. 데이터의 차원을 줄이기 위해 선택된 주성분의 개수를 말합니다. PCA components의 수를 지정하면 해당 수만큼의 주성분이 유지되고, 나머지 주성분들은 버려집니다. 주성분의 수를 결정하는 것은 차원 축소의 목적이나 데이터의 설명력 등을 고려하여 결정하게 됩니다.
PCA는 주로 데이터 차원 축소, 잡음 제거, 데이터 시각화, 특징 추출 등의 분야에서 사용됩니다. 데이터의 차원이 높은 경우에 유용하며, 주성분 분석은 다른 분석 기법과 함께 사용하여 데이터의 이해를 돕고 유의미한 정보를 추출하는 데 활용됩니다.

 

def mae_scorer(preds, dtrain):
    labels = dtrain.get_label()
    return 'Mae' , mean_absolute_error(labels, preds)
from scipy import sparse
from sklearn.model_selection import train_test_split
import xgboost as xgb


num_train = len(train) # 훈련 데이터 개수

# 훈련 데이터와 테스트 데이터 나누기
all_data_sprs = sparse.csr_matrix(all_data_updated)
X= all_data_sprs[:num_train] # 0~num_train -1 행
X_test = all_data_sprs[num_train:] # num_train ~ 마지막 행

y = train['yield'].values



# 8:2 비율로 훈련 데이터, 검증 데이터 분리(베이지안 최적화 수행용)

X_train , X_valid , y_train , y_valid = train_test_split(X,y, test_size=0.2 , random_state=0)

# 베이지안 최적화용 데이터셋

bayes_dtrain = xgb.DMatrix(X_train , y_train)
bayes_dvalid = xgb.DMatrix(X_valid, y_valid)
# 베이지안 최적화를 위한 하이퍼파라미터 범위
param_bounds = {'max_depth' : (4 , 10) , # 개별 트리의 최대 깊이, 트리 깊이가 깊을수록 모델이 복잡해지고 과대적합 우려
                # 값이 클수록 깊이가 한 단계만 늘어나도 메모리 사용량이 급격히 많아진다.
                # 일반적으로 3~10 사이의 값을 주로 사용한다.

                'subsample' : (0.5 , 1), # 개별 트리를 훈련할 때 사용할 데이터 샘플링 비율
                # 0~1 사이 값으로 설정할 수 있다.
                # 0.5 로 설정하면 전체 데이터의 50%를 사용해 트리를 생성

                'colsample_bytree' : (0.5 , 1.0), # 개별 트리를 훈련할 때 사용하는 피처 샘플링 비율
                # subsample 과 유사한 개념, subsample은 전체 데이터에서 얼마나 샘플링할지 나타내는 비율
                # colsample_bytree는 전체 피처에서 얼마나 샘플링할지 나타내는 비율
                # 값이 작을수록 과대적합 방지 효과

                'min_child_weight' : (5 , 10), # 과대적합 방지위한 값, 값이 클수록 과대적합 방지 효과가 있다.
                'gamma' : (8 , 11), # 말단 노드가 분할하기 위한 최소 손실 감소 값
                # 소실 감소가 gamma보다 크면 말단 노드를 분할
                # 값이 클수록 과대적합 방지 효과가 있다.

                'reg_alpha' : (7 , 9) , # L1 규제 조정 값 , 값이 클수록 과대적합 방지 효과
                'reg_lambda' : (1.1 , 1.5), # L2 규제 조정값 , 값이 클수록 과대적합 방지 효과
                'scale_pos_weight' : (1.4 , 1.6), # 뷸균형 데이터 가중치 조정 값 ,
                # 타깃값이 불균형할 때 양성 값에 scale_pos_weight 만큼 가중치를 줘서 균형을 맞춤(타깃값 1을 양성 값으로 간주)
                # 일반적으로 scale_pos_weight 값을 (음성 타깃값 개수 / 양성 타깃값 개수) 로 설정
                'learning_rate' : (0.02, 0.1)} # 학습률( 부스팅 스텝을 반복하면서 모델을 업데이트하는 데 사용되는 비율)


# 값이 고정된 하이퍼파라미터

fixed_params = {'objective' : 'reg:squarederror' ,# 훈련 목적 , binary : logistic( 확률값을 구하는 이진분류)
                # reg : squarederror (회귀 문제)
                # 소프트맥스 함수를 사용하는 다중분류에서는 multi : softmax 사용
                # 확률값을 구하는 다중분류에서는 'multi : softprob' 사용

                'random_state' : 1991} # 랜덤 시드값(코드를 반복 실행해도 같은 결과가 나오게 지정하는 값)

# ======================================================
def eval_function(max_depth ,learning_rate, subsample , colsample_bytree , min_child_weight , reg_alpha , gamma , reg_lambda , scale_pos_weight) :

    # 최적화하려는 평가지표(지니계수) 계산 함수

    # 베이지안 최적화를 수행할 하이퍼파라미터

    params = {'max_depth' : int(round(max_depth)) , # 개별 트리의 최대깊이
              'learning_rate' : learning_rate,
              'subsample' : subsample, # 개별 트리를 훈련할 때 사용할 데이터 샘플링 비율
              'colsample_bytree' : colsample_bytree , # 개별 트리를 훈련할때 사용하는 피처 샘플링
              'min_child_weight' :  # 과대적합 방지위한 값
                  min_child_weight,
              'gamma' : gamma, # 말단 노드가 분할하기 위한 최소 손실 감소 값
              'reg_alpha' : reg_alpha, # L1 규제 조정값
              'reg_lambda' : reg_lambda, # L2 규제 조정값
              'scale_pos_weight' : scale_pos_weight} # 불균형 데이터 가중치 조정값

    # 값이 고정된 하이퍼파라미터도 추가
    params.update(fixed_params)

    print('하이퍼파라미터 : ' , params)

    # XGBoost 모델 훈련 , train() 메서드의 하이퍼파라미터
    xgb_model = xgb.train(params = params , # XGBoost 모델의 하이퍼파라미터 목록 , 딕셔너리 타입으로 전달
                          dtrain = bayes_dtrain, # 훈련 데이터셋, xgboost.DMatrix 타입으로 전달
                          num_boost_round= 2000, # 부스팅 반복 횟수, 정수형 타입으로 전달
                          # num_boost_round 값이 클수록 성능이 좋아질 수 있으나 과대적합의 우려가 있다.
                          # num_boost_round 값이 작으면 반복 횟수가 줄어들어 훈련 시간이 짧아진다.
                          # 일반적으로 num_boost_round를 늘리면 learning_rate를 줄여야 한다.

                          evals = [(bayes_dvalid , ' bayes_dvalid')],
                          # 모델 성능 평가용 검증 데이터셋
                          # (DMatrix, 문자열) 쌍들을 원소로 갖는 리스트 타입으로 전달, 검증 데이터셋 이름을 원하는 대로 문자열로 정하면 된다.
                          maximize = True, # feval 평가지수가 높으면 좋은지 여부
                          feval = mae_scorer, # 검증용 평가지표, 사용자 정의 함수 형태
                          # evals를 활용해 모델 성능을 검증할 때 사용할 사용자 정의 평가지표 함수
                          # 예측값과 실제값을 파라미터로 전달받아, 평가지표명과 평가점수를 반환하는 함수이다.
                          early_stopping_rounds= 200,
                          # 조기종료 조건
                          # 모델은 기본적으로 num_boost_round만큼 훈련을 반복하며, 매 이터레이션마다 evals로 모델 성능을 평가하여 성능이 연속으로
                          # 좋아지지 않는다면 훈련을 중단하는데, 훈련 중단에 필요한 최소횟수가 early_stopping_rounds 이다. 즉 , early_stopping_rounds
                          # 동안 모델 성능이 좋아지지 않는다면 훈련을 중단한다.

                          # 과대적합 방지 효과

                          # 조기종료를 적용하기 위해서는 evals 에 검증 데이터가 하나 이상 있어야한다. 또한 evals에 검증 데이터가 여러 개라면 마지막 검증
                          # 데이터를 기준으로 조기종료 조건을 적용한다.


                          verbose_eval= False) # 성능 점수 로그 설정 값
    # True 로 설정하면 매 부스팅 스텝마다 평가점수르 출력
    # 출력값이 너무 많아지는 것을 방지하기위해 verbose_eval로 설정

    best_iter = xgb_model.best_iteration # 최적 반복횟수
    # 검증 데이터로 예측 수행
    preds = xgb_model.predict(bayes_dvalid , iteration_range=(0, best_iter))

    # 지니계수 계산
    mae_score = mean_absolute_error(y_valid, preds)
    print(f'Mae_score : {mae_score}\n')

    return -mae_score
%%time

from bayes_opt import BayesianOptimization

# 베이지안 최적화 객체 생성

optimizer = BayesianOptimization(f= eval_function, pbounds = param_bounds , random_state= 0)


# 베이지안 최적화 수행


optimizer.maximize(init_points= 3 , n_iter= 6)
# 평가함수 점수가 최대일 대 하이퍼파라미터
max_params = optimizer.max['params']
max_params['max_depth'] = int(round(max_params['max_depth']))

max_params.update(fixed_params)
max_params

 

from sklearn.model_selection import StratifiedKFold, KFold

# 층화 K 폴드 교차 검증기 생성
folds = KFold(n_splits= 5 , shuffle= True , random_state= 1991)

# OOF 방식으로 훈련된 모델로 검증 데이터 타깃값을 예측한 확률을 담을 1차원 배열
oof_val_preds = np.zeros(X.shape[0])
# # OOF 방식으로 훈련된 모델로 테스트 데이터 타깃값을 예측한 확률을 담을 1차원 배열
oof_test_preds = np.zeros(X_test.shape[0])
# OOF 방식으로 훈련된 모델 훈련 , 검증 , 예측

for idx , (train_idx , valid_idx) in enumerate(folds.split(X,y)):
    # 각 폴드를 구분하는 문구 출력

    print('#' *40,  f'폴드 {idx+1} / 폴드 {folds.n_splits}' , '#'*40)


    # 훈련용 데이터, 검증용 데이터 설정
    X_train , y_train = X[train_idx] , y[train_idx]
    X_valid , y_valid = X[valid_idx] , y[valid_idx]

    #XGBoost 전용 데이터셋 생성

    dtrain = xgb.DMatrix(X_train , y_train)
    dvalid = xgb.DMatrix(X_valid , y_valid)
    dtest = xgb.DMatrix(X_test)

    #XGBoost 모델 훈련
    xgb_model = xgb.train(params = max_params,
                          dtrain = dtrain,
                          num_boost_round = 2000,
                          evals = [(dvalid , 'valid')],
                          maximize = True,
                          feval = mae_scorer,
                          early_stopping_rounds = 200,
                          verbose_eval = 100)

    # 모델 성능이 가장 좋을 때의 부스팅 반복 횟수 저장
    best_iter= xgb_model.best_iteration
    # 테스트 데이터를 활용해 OOF 예측

    oof_test_preds += xgb_model.predict(dtest, iteration_range = (0 , best_iter))/ folds.n_splits

    oof_test_preds_xgb = oof_test_preds
    # 모델 성능 평가를 위한 검증 데이터 타깃값 예측
    oof_val_preds[valid_idx] += xgb_model.predict(dvalid , iteration_range=(0, best_iter))


    # 검증 데이터 예측 확률에 대한 정규화 지니계수
    mae_score = mean_absolute_error(y_valid , oof_val_preds[valid_idx])
    print(f'폴드 {idx+1}  MAE : {mae_score}\n')
y_preds = oof_test_preds
y_preds
from sklearn.model_selection import train_test_split


num_train = len(train)  # 훈련 데이터 개수

# 훈련 데이터와 테스트 데이터 나누기

X = all_data_updated[:num_train]  # 0~num_train -1 행
X_test = all_data_updated[num_train:]  # num_train ~ 마지막 행

y = train['yield'].values

X_train, X_valid, y_train, y_valid = train_test_split(X, y, test_size=0.2, random_state=0)
from sklearn.metrics import mean_absolute_error


dvalid = xgb.DMatrix(X_valid)

y_pred = xgb_model.predict(dvalid)

# MAE 계산
mae = mean_absolute_error(y_valid, y_pred)
print("MAE:", mae)

==> MAE: 318.21014847850415

 

KFOLD_PCA

==> 1150 / 1894

 

==> 성능 향상이 잘안되네ㅠ

2. MCA 처리 이후 XGBoost 모델 활용

all_data = pd.concat([train,test]) # 훈련 데이터와 테스트 데이터 합치기
# all_data = all_data.drop('Survived' , axis = 1) # 타깃값 제거
all_data = all_data.drop('yield' , axis = 1) # 타깃값 제거

all_data

# [fruitset , fruitmass ,seeds]
all_data_Mca = all_data.iloc[:,:-3]
all_data_Mca
from prince import MCA

# 변수 간의 상관관계 행렬 계산
corr_matrix = all_data_Mca.corr()
threshold = 0.9 # 상관관계의 임계값 설정
high_corr_vars = corr_matrix[abs(corr_matrix) >= threshold].stack().index
high_corr_vars = [var[0] for var in high_corr_vars if var[0] != var[1]]
# 상관관계 행렬을 기반으로 MCA 수행
mca = MCA(n_components=1)
mca.fit(all_data_Mca)

# 주성분 변환 적용
transformed_data = mca.transform(all_data_Mca)

# 변환된 데이터로 업데이트
all_data['MCA_Component'] = transformed_data

# 상관관계가 높은 변수들을 제외한 업데이트된 데이터
selected_vars = [col for col in all_data_Mca.columns if col not in high_corr_vars]
updated_data = all_data_Mca[selected_vars]
updated_data
all_data_updated = pd.concat([updated_data, all_data[['fruitset' , 'fruitmass' ,'seeds' , 'MCA_Component']]], axis=1)
all_data_updated

MCA_Components

 

from scipy import sparse
from sklearn.model_selection import train_test_split
import xgboost as xgb


num_train = len(train) # 훈련 데이터 개수

# 훈련 데이터와 테스트 데이터 나누기
all_data_sprs = sparse.csr_matrix(all_data_updated)
X= all_data_sprs[:num_train] # 0~num_train -1 행
X_test = all_data_sprs[num_train:] # num_train ~ 마지막 행

y = train['yield'].values



# 8:2 비율로 훈련 데이터, 검증 데이터 분리(베이지안 최적화 수행용)

X_train , X_valid , y_train , y_valid = train_test_split(X,y, test_size=0.2 , random_state=0)

# 베이지안 최적화용 데이터셋

bayes_dtrain = xgb.DMatrix(X_train , y_train)
bayes_dvalid = xgb.DMatrix(X_valid, y_valid)

==> 베이지안 최적화를 위한 데이터셋

 

2-1) 베이지안 최적화를 위한 하이퍼파라미터 범위 지

# 베이지안 최적화를 위한 하이퍼파라미터 범위
param_bounds = {'max_depth' : (4 , 10) , # 개별 트리의 최대 깊이, 트리 깊이가 깊을수록 모델이 복잡해지고 과대적합 우려
                # 값이 클수록 깊이가 한 단계만 늘어나도 메모리 사용량이 급격히 많아진다.
                # 일반적으로 3~10 사이의 값을 주로 사용한다.

                'subsample' : (0.5 , 1), # 개별 트리를 훈련할 때 사용할 데이터 샘플링 비율
                # 0~1 사이 값으로 설정할 수 있다.
                # 0.5 로 설정하면 전체 데이터의 50%를 사용해 트리를 생성

                'colsample_bytree' : (0.5 , 1.0), # 개별 트리를 훈련할 때 사용하는 피처 샘플링 비율
                # subsample 과 유사한 개념, subsample은 전체 데이터에서 얼마나 샘플링할지 나타내는 비율
                # colsample_bytree는 전체 피처에서 얼마나 샘플링할지 나타내는 비율
                # 값이 작을수록 과대적합 방지 효과

                'min_child_weight' : (5 , 10), # 과대적합 방지위한 값, 값이 클수록 과대적합 방지 효과가 있다.
                'gamma' : (8 , 11), # 말단 노드가 분할하기 위한 최소 손실 감소 값
                # 소실 감소가 gamma보다 크면 말단 노드를 분할
                # 값이 클수록 과대적합 방지 효과가 있다.

                'reg_alpha' : (7 , 9) , # L1 규제 조정 값 , 값이 클수록 과대적합 방지 효과
                'reg_lambda' : (1.1 , 1.5), # L2 규제 조정값 , 값이 클수록 과대적합 방지 효과
                'scale_pos_weight' : (1.4 , 1.6), # 뷸균형 데이터 가중치 조정 값 ,
                # 타깃값이 불균형할 때 양성 값에 scale_pos_weight 만큼 가중치를 줘서 균형을 맞춤(타깃값 1을 양성 값으로 간주)
                # 일반적으로 scale_pos_weight 값을 (음성 타깃값 개수 / 양성 타깃값 개수) 로 설정
                'learning_rate' : (0.02, 0.1)} # 학습률( 부스팅 스텝을 반복하면서 모델을 업데이트하는 데 사용되는 비율)


# 값이 고정된 하이퍼파라미터

fixed_params = {'objective' : 'reg:squarederror' ,# 훈련 목적 , binary : logistic( 확률값을 구하는 이진분류)
                # reg : squarederror (회귀 문제)
                # 소프트맥스 함수를 사용하는 다중분류에서는 multi : softmax 사용
                # 확률값을 구하는 다중분류에서는 'multi : softprob' 사용

                'random_state' : 1991} # 랜덤 시드값(코드를 반복 실행해도 같은 결과가 나오게 지정하는 값)

%%time

from bayes_opt import BayesianOptimization

# 베이지안 최적화 객체 생성

optimizer = BayesianOptimization(f= eval_function, pbounds = param_bounds , random_state= 0)


# 베이지안 최적화 수행


optimizer.maximize(init_points= 3 , n_iter= 6)

MAE_MCA

==> 최적 하이퍼파라미터 들

# 평가함수 점수가 최대일 대 하이퍼파라미터
max_params = optimizer.max['params']
max_params
#%%
max_params['max_depth'] = int(round(max_params['max_depth']))

max_params.update(fixed_params)
max_params

{'colsample_bytree': 0.5707518643760243,
 'gamma': 10.258422036166037,
 'learning_rate': 0.033067448349743546,
 'max_depth': 7,
 'min_child_weight': 8.729120234672777,
 'reg_alpha': 7.547134978429894,
 'reg_lambda': 1.1989719719121068,
 'scale_pos_weight': 1.4,
 'subsample': 1.0,
 'objective': 'reg:squarederror',
 'random_state': 1991}

from sklearn.model_selection import StratifiedKFold, KFold

# 층화 K 폴드 교차 검증기 생성
folds = KFold(n_splits= 5 , shuffle= True , random_state= 1991)

# OOF 방식으로 훈련된 모델로 검증 데이터 타깃값을 예측한 확률을 담을 1차원 배열
oof_val_preds = np.zeros(X.shape[0])
# # OOF 방식으로 훈련된 모델로 테스트 데이터 타깃값을 예측한 확률을 담을 1차원 배열
oof_test_preds = np.zeros(X_test.shape[0])
# OOF 방식으로 훈련된 모델 훈련 , 검증 , 예측

for idx , (train_idx , valid_idx) in enumerate(folds.split(X,y)):
    # 각 폴드를 구분하는 문구 출력

    print('#' *40,  f'폴드 {idx+1} / 폴드 {folds.n_splits}' , '#'*40)


    # 훈련용 데이터, 검증용 데이터 설정
    X_train , y_train = X[train_idx] , y[train_idx]
    X_valid , y_valid = X[valid_idx] , y[valid_idx]

    #XGBoost 전용 데이터셋 생성

    dtrain = xgb.DMatrix(X_train , y_train)
    dvalid = xgb.DMatrix(X_valid , y_valid)
    dtest = xgb.DMatrix(X_test)

    #XGBoost 모델 훈련
    xgb_model = xgb.train(params = max_params,
                          dtrain = dtrain,
                          num_boost_round = 2000,
                          evals = [(dvalid , 'valid')],
                          maximize = True,
                          feval = mae_scorer,
                          early_stopping_rounds = 200,
                          verbose_eval = 100)

    # 모델 성능이 가장 좋을 때의 부스팅 반복 횟수 저장
    best_iter= xgb_model.best_iteration
    # 테스트 데이터를 활용해 OOF 예측

    oof_test_preds += xgb_model.predict(dtest, iteration_range = (0 , best_iter))/ folds.n_splits

    oof_test_preds_xgb = oof_test_preds
    # 모델 성능 평가를 위한 검증 데이터 타깃값 예측
    oof_val_preds[valid_idx] += xgb_model.predict(dvalid , iteration_range=(0, best_iter))


    # 검증 데이터 예측 확률에 대한 정규화 지니계수
    mae_score = mean_absolute_error(y_valid , oof_val_preds[valid_idx])
    print(f'폴드 {idx+1}  MAE : {mae_score}\n')

KFOLD 활용한 제일 작은 MAE 찾

y_preds = oof_test_preds
y_preds
from sklearn.model_selection import train_test_split


num_train = len(train)  # 훈련 데이터 개수

# 훈련 데이터와 테스트 데이터 나누기

X = all_data_updated[:num_train]  # 0~num_train -1 행
X_test = all_data_updated[num_train:]  # num_train ~ 마지막 행

y = train['yield'].values

X_train, X_valid, y_train, y_valid = train_test_split(X, y, test_size=0.2, random_state=0)
from sklearn.metrics import mean_absolute_error


dvalid = xgb.DMatrix(X_valid)

y_pred = xgb_model.predict(dvalid)

# MAE 계산
mae = mean_absolute_error(y_valid, y_pred)
print("MAE:", mae)

==>  MAE: 322.23736149704666

 

KFOLD_XGB_MCA

==> 1160 / 1894

728x90
반응형

+ Recent posts