본문 바로가기
TIL

내배캠 TIL 33일차

by ColorConeHead 2024. 2. 2.
반응형

머신러닝 개인 과제

1) 라이브러리를 이용해 데이터 불러오기

데이터 출처와 Github 출처가 주어졌다.
데이터 출처는 csv 형태로 바로 다운 받을 수 있는 것이고,
Github에서는 모듈을 제시한다.

채점 환경이 어떨지 모르기 때문에
모듈을 사용하여 저장하기로 하였다.
'''문제 시작'''

!pip install -U ucimlrepo
from ucimlrepo import list_available_datasets, fetch_ucirepo

# list_available_datasets()을 통해 필요한 데이터셋의 id 확인

bank_marketing = fetch_ucirepo(id=222)
df = bank_marketing['data']['original']
df.to_csv('bank_marketing.csv')

'''문제 끝'''
df.head(3)​


못 찾은 거일 수도 있지만,
이 인간들 list_available_datasets()에서
인덱싱을 못 하게 해놓은 거 같다..

덕분에 눈으로 힘들게 찾았다.

 

 

2) Y 변수 인코딩 적용하기

아래와 같이 인코딩은 함수를 통해 적용해야 하며,
그 규칙이 엄격하게 정해져 있다.

'''
함수명은 get_binary로 설정하세요.

주어진 문자열 x가 'no'일 경우 0을 반환하고, 그렇지 않을 경우 1을 반환합니다.
이 함수는 일반적으로 두 가지 범주(예: 'yes'와 'no')를 가진 데이터를
이진 형식(0과 1)으로 변환하는 데 사용됩니다.

Args: x (str): 변환할 문자열. 'no' 또는 그 외의 값을 가질 수 있습니다.
Returns: int: 문자열 x가 'no'일 경우 0, 그렇지 않을 경우 1을 반환합니다. 
'''

def get_binary(x):

    # 이부분을 작성해주세요
    if x == 'no':
        return 0
    else:
        return 1
        
    # y_train 데이터 인코딩 코드
y_train['y'] = y_train['y'].apply(get_binary)

    # y_test 데이터 인코딩코드
y_test['y'] = y_test['y'].apply(get_binary)

y는 데이터프레임이고,
y['y']는 어레이다.
apply를 적용해야 하므로 유의해야 한다.

 

 

3) 간단한 모델링 & 평가함수 생성하기

주어진 조건을 만족하는 함수를 작성해야 한다.
함수의 인자가 잘 이해되지 않는다면
아래 쪽의 예시를 보면 도움이 되는 거 같다.
def get_score(train:pd.DataFrame, test:pd.DataFrame, x_var_list:list):
    """ train과 test 데이터와 X변수 컬럼을 받아 평가지표를 내는 함수입니다.

    Args:
        train (pd.DataFrame): train 데이터프레임
        test (pd.DataFrame): test 데이터프레임
        x_var_list (list): 모델링에 사용할 변수 리스트
    """
    #외부 전달인자를 내부변수에 할당
    X_train = train 
    X_test = test

    #일부 컬럼만 가져오기
    X_train = X_train[x_var_list]
    X_test = X_test[x_var_list]
    
    '''문제 시작'''
    #모듈불러오기
    from sklearn.linear_model import LogisticRegression
    from sklearn.metrics import f1_score, accuracy_score
    
    #모델가져오기 & 학습하기
    logit = LogisticRegression()
    logit.fit(X_train, y_train)
    
    # 학습하여 결과 저장
    y_pred_train = logit.predict(X_train)
    y_pred_test = logit.predict(X_test)
    
    
    '''문제 끝'''
    
    #평가표 생성
    result = pd.DataFrame({
                           'acc' : [accuracy_score(y_train, y_pred_train),
                                    accuracy_score(y_test, y_pred_test)],
                            'f1_score' : [f1_score(y_train, y_pred_train),
                                          f1_score(y_test, y_pred_test)]
                           },
                            index = ['train','test'])
    
    display(result.round(2))

# duration 변수만 사용하여 결과내기
get_score(X_train, X_test, ['duration'])​

y가 이진분류의 형태이므로
LogisticRegression()을 모델로 사용하며
평가지표로는
accuracy_score, f1_score를 사용한다.

 

 

4) 모델링 수행하기

주어진 조건에 맞춰
X 중 해당 컬럼을 스캐일링 하는 함수를 작성한다
def get_numeric_sc(X_train:pd.DataFrame, X_test:pd.DataFrame):
    """데이터를 전달받아 수치형 변수 스케일링하는 함수

    Args:
        X_train (pd.DataFrame): train 데이터프레임
        X_test (pd.DataFrame):  test 데이터프레임

    Returns:
        pd.DataFrame, pd.DataFrame: train, test 데이터프레임
    """
    # 수치형변수
    # age, balance, day_of_week, duration, campaign, pdays,previous
    
    #StandardScaler 적용할 변수 리스트
    sc_col = ['pdays','previous']
    #MinMaxScaler 적용할 변수 리스트
    mm_col = ['age','duration','day_of_week','balance','campaign']
    
    '''문제 시작'''
    #모듈 불러오기
    from sklearn.preprocessing import StandardScaler, MinMaxScaler
    
    #모델 가져오기
    stsc = StandardScaler()
    mmsc = MinMaxScaler()

    #train, test 데이터변환(Standard Scaler이용)
    X_train[sc_col] = stsc.fit_transform(X_train[sc_col])
    X_test[sc_col] = stsc.fit_transform(X_test[sc_col])
    
    #train, test 데이터변환(MinMax Scaler이용)
    X_train[mm_col] = mmsc.fit_transform(X_train[mm_col])
    X_test[mm_col] = mmsc.fit_transform(X_test[mm_col])
    
    '''문제 끝'''
    return X_train, X_test

X_train, X_test = get_numeric_sc(X_train, X_test)​

 


학습은 데이터프레임의 형태로 넣어줘야 하지만
스캐일링이나 인코딩의 경우에는 array로 넣어줘야 한다.

 

 

5) 선택형

(1) balance 음수값 보정


로그 스캐일을 하기 위해 음수값을 없앴다.
로그에서 진수는 0보다 커야하기 때문이다.

 

 

(2) np.log()가 아닌 np.log1p()를 사용하는 이유


위에서의 음수값 보정에 의해
정의역은 적어도 0보다 크거나 같아졌다.

x = 0인 경우 np.log(x) 값은 무한대로 발산하기 때문에

x + 1을 해주는 np.log1p()를 사용해야
x = 0인 경우에도 발산하지 않고 0이 된다

 

 

(3) 더 나은 인코딩


차원축소
get_dummies()로 나온 변수별 컬럼 중 마지막 1개 컬럼은 삭제할 수 있을 거 같다.

가령 df['education'].unique()는 ['tertiary', 'secondary', 'primary'].
get_dummies() 시 3개의 컬럼이 나온다

이중 1개의 컬럼은 없어도 나머지 2개의 컬럼값이 0이라면
무조건 남은 1개의 카테고리에 속하기 때문에 판별 가능하므로
변수별로 하나의 컬럼은 삭제 가능할 것으로 보인다.

 

 

(4) 결측치 처리


결측치 처리에 관한 코드가 없었다.
## 결측치 확인
df2 = pd.read_csv('./bank_marketing.csv')

df2.isnull().sum()

## job, eduaction, contact 까지는 대치할만한데
## poutcome은 버리는 게 좋을 거 같다​
확인해보니 명목형 변수들만 결측치가 있었다.
각 컬럼을 value_counts()로 확인해보니
poutcome을 제외하고는 최빈값으로
결측치를 대치해도 무방해보였다.
이에 관한 코드는 주말에 작성할 예정이다.

 

 

(5) 하이퍼 파라미터 조정


GridSearchCV()를 통해 하이퍼 파라미터를 최적화한다.
이에 관한 코드 또한 주말에 작성할 예정이다
반응형

'TIL' 카테고리의 다른 글

내배캠 TIL 35일차  (0) 2024.02.06
내배캠 TIL 34일차  (1) 2024.02.05
내배캠 TIL 32일차  (0) 2024.02.01
내배캠 TIL 31일차  (0) 2024.01.31
내배캠 TIL 30일차  (0) 2024.01.30