24.02.07 TIL

예진·2024년 2월 7일
0

TIL

목록 보기
34/68

심화 프로젝트 둘째날.
여전히 물음표만 오백만 개 느낌,,,
할 수 있는 걸 하자 222


<과적합>

  1. 배경설명

과대적합(Overfitting) : 데이터를 너무 과도하게 학습한 나머지 해당 문제만 잘 맞추고 새로운 데이터를 제대로 예측 혹은 분류하지 못하는 현상

  • 예측 혹은 분류를 하기 위해서 모형을 복잡도를 설정
    • 모형이 지나치게 복잡할 때 : 과대 적합
    • 모형이 지나치게 단순할 때: 과소 적합
  • 과적합의 원인
    • 모델의 복잡도(상기의 예시)
    • 데이터 양이 충분하지 않음
    • 학습 반복이 많음(딥러닝의 경우)
    • 데이터 불균형(정상환자 - 암환자의 비율이 95: 5)

과적합 해결 - 테스트 데이터의 분리

• 예측 혹은 분류를 하기 위해서 모형을 복잡도를 설정

◦ 모형이 지나치게 복잡할 때 : 과대 적합이 될 수 있음
◦ 모형이 지나치게 단순할 때: 과소 적합이 될 수 있음

• 과적합의 원인

◦ 모델의 복잡도(상기의 예시)
◦ 데이터 양이 충분하지 않음
◦ 학습 반복이 많음(딥러닝의 경우)
◦ 데이터 불균형(정상환자 - 암환자의 비율이 95: 5)
  • 학습 데이터(Train Data): 모델을 학습(fit)하기 위한 데이터
  • 테스트 데이터(Test Data): 모델을 평가 하기 위한 데이터
  • 함수 및 파라미터 설명
    • sklearn.model_selection.train_test_split
      • 파라미터
        • test_size: 테스트 데이터 세트 크기
        • train_size: 학습 데이터 세트 크기
        • shuffle: 데이터 분리 시 섞기(랜덤성 추가)
        • random_state: 호출할 때마다 동일한 학습/테스트 데이터를 생성하기 위한 난수 값. 수행할 때 마다 동일한 데이터 세트로 분리하기 위해 숫자를 고정 시켜야 함
      • 반환 값(순서 중요)
        • X_trainX_testy_trainy_test

<교차 검증(Cross Validation)>

교차검증(Cross Validation) : 데이터 셋을 여러 개의 하위 집합으로 나누어 돌아가면서 검증 데이터로 사용하는 방법 (과적합 취약 방지)

  • K-Fold Validation
    • 정의: Train Data를 K개의 하위 집합으로 나누어 모델을 학습시키고 모델을 최적화 하는 방법
    • 이때 K는 분할의 갯수
      • Split 1: 학습용(Fold 2~5), 검증용(Fold1)
      • Split 2: 학습용(Fold1, 3~5), 검증용(Fold2)
      • Split 5까지 반복 후 최종 평가
  • 특징
    • 데이터가 부족할 경우 유용합니다.(반복 학습)
  • 함수
    • skelarn.model_selection.KFold
    • sklearn.model_selection.StrifiedKFold: 불균형한 레이블(Y)를 가지고 있을 때 사용

하이퍼 파라미터 자동적용하기 - GridSearchV

하이퍼 파라미터 (Hyper Parameter : 모델을 구성하는 입력 값 중 사람이 임의적으로 바꿀 수 있는 입력 값

다양한 값을 넣고 실험할 수 있기 때문에 이를 자동화해주는 Grid Search를 적용해볼 수 있다.

1. 데이터 로드 & 분리
    - train / test 데이터 분리
2. 탐색적 데이터 분석(EDA)
    - 분포확인 & 이상치 확인
3. 데이터 전처리
    - 결측치 처리
        - 수치형: Age
        - 범주형: Embarked
        - 삭제 : Cabin, Name
    - 전처리
        - 수치형: Age, Fare, Sibsp+Parch
        - 범주형
            - 레이블 인코딩: Pclass, Sex
            - 원- 핫 인코딩: Embarked
4. 모델 수립
5. 평가

import pandas as pd
import numpy as np 
import seaborn as sns 
import matplotlib.pyplot as plt

train_df = pd.read_csv("/Users/yejin/Documents/ML 실습/train.csv")
test_df = pd.read_csv("/Users/yejin/Documents/ML 실습/test.csv")

test_df.head(3)

train_df.info()

train_df.describe(include= 'all')

#기초 가공 : Family 변수생성
train_df_2 = train_df.copy()
def get_family(df):
    df['Family'] = df['SibSp'] + df['Parch']
    return df
get_family(train_df_2).head(3)

#숫자형 변수들의 이상치를 확인하기 위해 pariplot
sns.pairplot(train_df_2[['Age', 'Fare', 'Family']])

train_df_2 = train_df_2[train_df_2['Fare'] < 512 ]

train_df_2.shape

#결측치처리
def get_non_missing(df):
    Age_mean = train_df_2['Age'].mean()
    Fare_mean = train_df_2['Fare'].mean()
    df['Age'] = df['Age'].fillna(Age_mean)
    
    #Train 데이터에는 필요하지 않으나 Test 데이터에 결측치 존재하여 추가
    df['Fare'] = df['Fare'].fillna(Fare_mean)
    df['Embarked'] = df['Embarked'].fillna('S')
    return df
get_non_missing(train_df_2).info()

def get_numeric_sc(df):
    #sd_sc: Fare, mm_sc : Age, Family
    from sklearn.preprocessing import StandardScaler, MinMaxScaler
    sd_sc = StandardScaler()
    mm_sc = MinMaxScaler()

    
    sd_sc.fit(train_df_2[['Fare']])
    df['Fare_sd_sc'] = sd_sc.transform(df[['Fare']])

    mm_sc.fit(train_df_2[['Age', 'Family']])
    df[['Age_mm_sc', 'Family_mm_sc']] = mm_sc.transform(df[['Age', 'Family']])

    return df
get_numeric_sc(train_df_2).describe()

def get_category(df):

    from sklearn.preprocessing import LabelEncoder, OneHotEncoder
    le = LabelEncoder()
    le2 = LabelEncoder()
    oe = OneHotEncoder()

    le.fit(train_df_2[['Pclass']])
    df['Pclass_le'] = le.transform(df['Pclass'])

    le2.fit(train_df_2[['Sex']])
    df['Sex_le'] = le2.transform(df['Sex'])

    #index reset을 하기 위한 구문
    df = df.reset_index()
    oe.fit(train_df_2[['Embarked']])
    embarked_csr = oe.transform(df[['Embarked']])
    embarked_csr_df = pd.DataFrame(embarked_csr.toarray(), columns= oe.get_feature_names_out())
    df2 = pd.concat([df, embarked_csr_df], axis = 1)
    return df2

train_df_2 = get_category(train_df_2)

train_df_2.columns

train_df_2.info()

def get_model(df):
    from sklearn.linear_model import LogisticRegression
    model_lor = LogisticRegression()
    x = df[['Age_mm_sc',  'Fare_sd_sc', 'Family_mm_sc', 'Pclass_le', 'Sex_le', 'Embarked_C', 'Embarked_Q', 'Embarked_S' ]]
    y = df[['Survived']]
    model_lor.fit(x,y)
    return model_lor.fit(x,y)

model_output = get_model(train_df_2)
model_output

X = train_df_2[['Age_mm_sc',  'Fare_sd_sc', 'Family_mm_sc', 'Pclass_le', 'Sex_le', 'Embarked_C', 'Embarked_Q', 'Embarked_S' ]]
y_pred = model_output.predict(X)

#평가
from sklearn.metrics import accuracy_score, f1_score
print(accuracy_score(train_df_2['Survived'], y_pred))
print(f1_score(train_df_2['Survived'], y_pred))

test_df.head(3)

test_df.info()

test_df_2 = get_family(test_df)
test_df_2 = get_non_missing(test_df_2)
test_df_2 = get_numeric_sc(test_df_2)
test_df_2 = get_category(test_df_2)
type(model_output)

train_df_2.columns

#전처리한 값 넣기
test_X = test_df_2[['Age_mm_sc',  'Fare_sd_sc', 'Family_mm_sc', 'Pclass_le', 'Sex_le', 'Embarked_C', 'Embarked_Q', 'Embarked_S' ]]
#test_X.info()
y_test_pred = model_output.predict(test_X)

sub_df = pd.read_csv('/Users/yejin/Documents/GitHub/eden_jeong/gender_submission.csv')
sub_df.head(10)

sub_df['Survived'] = y_test_pred
sub_df.head(10)
sub_df.to_csv('./result.csv', index = False)

sub_df

K-fold 수행하기
from sklearn.model_selection import KFold
import numpy as np 

kfold = KFold(n_splits = 5)
scores = []
X = train_df_2[['Age_mm_sc', 'Fare_sd_sc', 'Family_mm_sc', 'Pclass_le', 'Sex_le', 'Embarked_C', 'Embarked_Q', 'Embarked_S']]
y = train_df_2['Survived']
for i, (train_index, test_index) in enumerate(kfold.split(X)):
    X_train, X_test = X.values[train_index], X.values[test_index]
    y_train, y_test = y.values[train_index], y.values[test_index]

    from sklearn.linear_model import LogisticRegression
    from sklearn.metrics import accuracy_score
    model_lor2 =LogisticRegression()
    model_lor2.fit(X_train, y_train)
    y_pred2 = model_lor2.predict(X_test)
    accuracy = accuracy_score(y_test, y_pred2)
    print(i, '번째 교차검증 정확도는', accuracy)
    scores.append(accuracy)

print('평균 정확도', np.mean(scores))

GridSearch 적용하기
from sklearn.model_selection import GridSearchCV

params = {'solver' : ['newton-cg', 'lbfgs', 'liblinear', 'sag', 'saga'],
          'max_iter' : [100,200]}
grid_lor = GridSearchCV(model_lor2, param_grid = params, scoring = 'accuracy', cv = 5)
grid_lor.fit(X_train, y_train)

print('최고의 하이퍼 파라미터', grid_lor.best_params_)
print('최고의 정확도', grid_lor.best_score_.round(3))

주요 목표는 성능을 개선하여 최적의 모델을 만드는 거지만, +a로 얼마든지 인사이트를 만들 수 있다.
그러려면 EDA 빡세게 해야함.
범주형과 수치형의 관계, 범주형끼리의 관계, X와 X의 관계, X와 Y의 관계, test set안에서의 X와 Y의 관계, 정합성 등.
파생변수 활용 ex : 금액, 기간 -> 대출 기간별 금액 ,,, 파생변수 활용해서 변수의 수를 줄일수도.
도메인 지식 공부해라, 대출 등급 산정하기 위한 회사들의 전통? 규칙 등..
EDA, 전처리 >>>>>>> 모델링
데이콘의 베이스라인 코드 해설 참조

SUVar... Zonna 모르겠고 Suturess 5gym...
아프니까 청춘이다의 표본이다 리얼루,, 힘내쟈,,,

profile
Data Analysis / 맨 땅에 헤딩

0개의 댓글