| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 | 31 |
- widget
- Replication
- ability task
- Aegis
- linear regression
- Multiplay
- 보안
- attribute
- 언리얼엔진
- Unreal Engine
- CTF
- animation
- listen server
- gas
- UI
- gameplay effect
- rpc
- photon fusion2
- 유니티
- gameplay tag
- stride
- 게임 개발
- local prediction
- 게임개발
- os
- unity
- C++
- gameplay ability system
- MAC
- 언리얼 엔진
- Today
- Total
Replicated
Feature Selection, Model Stacking 본문
Feature Selection
- 자동 또는 수동으로 피쳐를 선택하는 프로세스
- 가장 크게 기여하는 변수들을 선택
- 예측하고자 하는 변수들에 가장 크게 기여하는 변수들을 선택
- 모든 피쳐를 쓰는게 아니라, 좋은 서브셋을 선택
좋은 피쳐?
- 깔끔한 클래스 바운더리를 가져야 함
- 피쳐의 중요성 = 피쳐 파워 + 상호작용 파워
Filter method
- 모든 피쳐를 평가하고 최고 n개 피쳐 고르기
- 쉽고 빠름
- 피쳐간 인터렉션을 고려하지 않는다는 문제
Feature subset selction
- Foward selction : 좋은 피쳐를 추가해 나가는 방식
- Backword emimination : 안좋은 피쳐를 빼가는 방식
import pandas as pd
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
df = pd.read_csv('/content/gdrive/MyDrive/Data/PimaIndiansDiabetes.csv')
print(df.head())
print(df.columns)
df_X = df.loc[:, df.columns != 'diabetes']
df_y = df['diabetes']
model = LogisticRegression(solver='lbfgs', max_iter=3000)
scores = cross_val_score(model, df_X, df_y, cv=5)
print("Acc: "+str(scores.mean()))

필터 메소드
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
test = SelectKBest(score_func=chi2, k=df_X.shape[1])
fit = test.fit(df_X, df_y)
print(np.round(fit.scores_, 3))
f_order = np.argsort(-fit.scores_)
sorted_columns = df.columns[f_order]
print(sorted_columns.to_list)

영향을 끼치는 순서
model = LogisticRegression(solver='lbfgs', max_iter=500)
for i in range(1, df_X.shape[1]+1):
fs = sorted_columns[0:i]
df_X_selected = df_X[fs]
scores = cross_val_score(model, df_X_selected, df_y, cv=5)
print(fs.tolist())
print(np.round(scores.mean(), 4))

적용하면 pedigree는 넣으면 오히려 떨어짐
포워드 서치
from sklearn.feature_selection import SequentialFeatureSelector
model = LogisticRegression(solver='lbfgs', max_iter=500)
sfs = SequentialFeatureSelector(model, direction='forward', n_features_to_select='auto')
fit = sfs.fit(df_X, df_y)
print("Num Features: %d" % fit.n_features_in_)
fs = df_X.columns[fit.support_].tolist() # selected features
print("Selected Features: %s" % fs)
scores = cross_val_score(model, df_X[fs], df_y, cv=5)
print("Acc: "+str(scores.mean()))

가장 좋은 게 저렇게 나옴
백워드 엘리미네이션
from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression
model = LogisticRegression(solver='lbfgs', max_iter=500)
rfe = RFE(model, n_features_to_select=5)
fit = rfe.fit(df_X, df_y)
print("Num Features: %d" % fit.n_features_)
fs = df_X.columns[fit.support_].tolist() # selected features
print("Selected Features: %s" % fs)
scores = cross_val_score(model, df_X[fs], df_y, cv=5)
print("Acc: "+str(scores.mean()))

SFS
from mlxtend.feature_selection import SequentialFeatureSelector as SFS
model = LogisticRegression(solver='lbfgs', max_iter=500)
sfs1 = SFS(model,
k_features=5, # number of features
verbose=2,
scoring='accuracy',
cv=5)
sfs1 = sfs1.fit(df_X, df_y)
print( sfs1.subsets_ ) # selection process
print( sfs1.k_feature_idx_ )# selected feature index
print( sfs1.k_feature_names_ ) # selected feature name

mixtend의 SFS는 포워드 백워드 둘 가 가능
디폴트가 포워드고, forward 인자 false 주면 됨
scores = cross_val_score(model, df_X[list(sfs1.k_feature_names_)], df_y, cv=5)
print("Acc: "+str(scores.mean()))

* sklearn의 RFE는 모델이 coef_나 feature_importances_를 가져야 함
* KNN은 REF를 쓸 수 없음
피쳐 셀렉션도 cross-validation으로 평가해야 함
Voting Classifier
Simple voting
- 여러 종류의 예측 알고리즘을 이용하여 모델을 만든 뒤, 각 모델의 예측 결과로 투표(classification) 또는 평균(regression)을 구함
유방암 진단 예시
from sklearn.ensemble import VotingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import cross_val_score
from sklearn.preprocessing import StandardScaler
import numpy as np
df_X, df_y = load_breast_cancer(return_X_y=True)
sc_data = StandardScaler().fit(df_X)
df_X = sc_data.transform(df_X)
데이터 준비
clf_lr = LogisticRegression()
clf_knn = KNeighborsClassifier(n_neighbors=1)
clf_dt = DecisionTreeClassifier(random_state=1)
clf_voting = VotingClassifier(
estimators=[('LR', clf_lr),
('KNN', clf_knn),
('DT', clf_dt)],
voting='soft')
모델들 다 넣고 보팅
* 하드는 하나의 classifier가 한 표씩 행사, 소프트는 지지 확률을 합산(권장)
models = [clf_lr, clf_knn, clf_dt]
for model in models:
scores = cross_val_score(model, df_X, df_y, cv=5)
model_name = model.__class__.__name__
print(f"{model_name} \t : {np.mean(scores)}")

각 모델의 지지율
voting_scores = cross_val_score(clf_voting, df_X, df_y, cv=5)
print('Voting accuracy', np.mean(voting_scores))

오히려 보팅을 하니 떨어질 수 있다
심플 보팅은 각 모델의 성능을 최대한 끌어올린 뒤 시도
Bagging meta-estimator
- 동일한 데이터셋에 대해 샘플링을 하여 다수의 데이터셋을 구성한 뒤 단일 알고리즘으로 모델 생성
- 각 모델의 결과를 종합하여 최종 의사 결정
from sklearn.ensemble import BaggingClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import cross_val_score
from sklearn.preprocessing import StandardScaler
import numpy as np
df_X, df_y = load_breast_cancer(return_X_y=True)
sc_data = StandardScaler().fit(df_X)
df_X = sc_data.transform(df_X)
model_base = KNeighborsClassifier()
scores = cross_val_score(model_base, df_X, df_y, cv=5)
print(np.mean(scores))

기본
model_bagging = BaggingClassifier(KNeighborsClassifier(),
n_estimators = 100, # 모델 수
max_samples=0.5, # 인스턴스 선택 비율
max_features=1.0, # feature 선택 비율
n_jobs=-1,
random_state=123)
scores_bagging = cross_val_score(model_bagging, df_X, df_y, cv=5)
print(np.mean(scores_bagging))

bagging-meta instimator
Model stacking
- 앙상블 중 하나
- stacked generalization이라고도 함
- 여러 모델의 예측값을 인풋으로 해서 새로운 모델로 학습
- 과적합 방지를 위해 사용되기도 함
모델 스태킹 절차
- Level 0 : 트레이닝 데이터셋을 이용해서 sub-model 예측 결과를 생성
- Level 1 : Level0의 아웃풋 결과가 Level1의 인풋값, Level0의 아웃풋을 트레이닝 데이터로 사용하여 메타 러닝 모델을 생성
Level0 모델들은 되도록 다양한 예측 결과를 메타 러너에서 인풋 값으로 활용할 수 있도록 각기 다른 알고리즘을 사용하는 것이 좋음
각 서브 모델의 결과를 결합하는 메타 러너 모델은 simple linear 모델을 사용하는 것이 일반적
Level 0 출력값 처리
- regression의 경우 level0 출력값 그대로 인풋
- classification의 경우 그대로 쓰기보단 label probabilities 사용하는게 더 효과적
sklean.ensemble.StackingClassfier
- estimators : level 0에 사용할 predicator들
- final_estimator : level 1에 사용할 predicator (디폴트 LogisticRegression)
- cv : cross validiaction 값, 미제출 시 5
- stack_method
- auto : 아래의 방법 중 하나를 적용
- predict_proba : Level0의 Label probability를 인풋으로 사용
- decision_function : Level0의 출력을 처리하는 함수 적용
- predict : Level0 출력을 그대로 input으로 사용
- n_jobs : 멀티 프로세싱, -1이면 모든 코어
- passthrough
- False: 레벨 0의 출력만 레벨 1의 학습 데이터로 사용
- True: 레벨 0의 출력 + 오리지널 데이터셋이 레벨 1의 학습 데이터로 사용
from sklearn.datasets import load_breast_cancer
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import LinearSVC
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import make_pipeline
from sklearn.ensemble import StackingClassifier
from sklearn.model_selection import cross_val_score
import numpy as np
df_X, df_y = load_breast_cancer(return_X_y=True)
estimators = [
('rf', RandomForestClassifier(n_estimators=10, random_state=42)),
('svr', make_pipeline(StandardScaler(), LinearSVC(random_state=42, dual='auto')))]
model_1 = StackingClassifier(
estimators=estimators,
final_estimator=LogisticRegression())
scores_1 = cross_val_score(model_1, df_X, df_y, cv=5)
print(np.mean(scores_1))

예시
model_2 = StackingClassifier(
estimators=estimators,
final_estimator=LogisticRegression(max_iter=1000),
passthrough=True)
scores_2 = cross_val_score(model_2, df_X, df_y, cv=5)
print(np.mean(scores_2))
이런식으로 인자 바꾸기도 하고..
from xgboost import XGBClassifier
estimators = [
('rf', RandomForestClassifier(n_estimators=10, random_state=42)),
('svr', make_pipeline(StandardScaler(), LinearSVC(random_state=42, dual='auto'))),
('lr', LogisticRegression(max_iter=5000))]
model_3 = StackingClassifier(
estimators=estimators,
final_estimator=XGBClassifier(eval_metric='logloss', random_state=42), passthrough=True)
scores_3 = cross_val_score(model_3, df_X, df_y, cv=5)
print(np.mean(scores_3))

XGBoost를 final에 넣을 수도 있고
정리하자면
데이터셋 준비
- 피쳐 셀렉션 및 CV
- 하이퍼 파라미터 튜닝 및 CV
- 모델 비교, 보팅, 배깅, 스태킹 및 CV
- 최종 모델 빌드
의 과정을 거침
'학부 > 딥러닝' 카테고리의 다른 글
| 신경망 학습 (0) | 2025.10.18 |
|---|---|
| 인공신경망 개요 (0) | 2025.10.18 |
| Classification / 결정 트리, SVM, XGBoost (0) | 2025.10.13 |
| Classification / 앙상블, 하이퍼 파라미터 튜닝, K-fold CV, 성능 평가 (0) | 2025.10.13 |
| Regression (0) | 2025.10.12 |