Be Brave, Be Humble

빅데이터 분석기사 실기 part3. 파이썬으로 데이터 분석 준비하기 (프리렉) 본문

Statistics/Data Science

빅데이터 분석기사 실기 part3. 파이썬으로 데이터 분석 준비하기 (프리렉)

해쨔니 2022. 10. 25. 17:08

Open in Colab 누르면 코랩으로 이동 가능.

 

빅데이터 분석기사 실기를 전부 스파이더로 작성해서 ^^,, colab으로 옮기니 한 블럭에 다 들어가버리네요 머쓱

프리렉 빅데이터 분석기사 실기책을 바탕으로 작성했습니다.

In [ ]:
# -*- coding: utf-8 -*-
"""
Created on Fri Jun 10 05:55:08 2022

@author: FullSun

"""

###############################################
##### Part3. 파이썬으로 데이터 분석 준비하기 #####
###############################################

#---------------------------------------------
#     1. 실습 데이터와 실행 환경 구성하기
#---------------------------------------------

#--------- <1.1> 실습 데이터 구성하기 ---------#

# 자료 내려받기 : https://github.com/7ieon/bigData


#--------- <1-2> 파이썬 실습 환경 구성하기 ---------#

# 코랩, 주피터 노트북, 파이참, 스파이더, 비주얼 스튜디오 등 아무거나 선택.
# 왜인지.. 스파이더로 해버려서..


#--------- <1-3> 실습 데이터 이해하기 ---------#

# mtcars: R에서도 자주 쓰이는 데이터. 연비를 나타내는 mpg를 타겟변수로 사용할 것.

#---------------------------------------------
#        2. 데이터 분석 절차 체득하기
#---------------------------------------------
''' 데이터 준비하기
    > 데이터 관찰하고 가공하기
    > 데이터 분리하기 (training, validation, test)
    > 학습 및 검증
    > 출력 후 저장 '''

# 실제 시험 환경에서는 반드시 print() 사용해야 출력 가능!


#--------- <2-1> 데이터 준비하기: 데이터 로드 ---------#

# 빅데이터 분석기사에서 주어지는 샘플은 2차원 구조이므로, pandas기반으로 분석할 것.
import pandas as pd
data = pd.read_csv("C:/Users/mtcars.csv")
print(data.head()) # 일반적인 환경에서는 print() 필요없지만 시험 환경에서는 반드시 쓸 것.
# unnamed열과 am열은 문자열


##### [1] 데이터 둘러보기

## 데이터 모양 확인하기
print(data.shape) #32,12

## 데이터 타입 확인하기
print(type(data)) #DF

## 데이터의 열 확인하기
print(data.columns)

## 기초 통계량 구하기
print(data.describe())
''' 8 rows x 9 columns를 통해 12개 피처 중 8개 열이 수치형임을 알 수 있음.
    cyl(엔진 기통 수)의 max가 50으로 이상치임을 알 수 있음. '''
print(data['hp'].describe()) #말 줄임표(...)로 생략된 데이터 정보 보기

## 데이터 중복 제외하기
print(data['am'].unique())
print(data.iloc[:,0].unique())
print(data['gear'].unique())
print(data['vs'].unique())

## 요약 정보 확인하기
print(data.info()) #32x12 행렬이며, 결측치 있는 열 2개

## 상관관계 구하기
print(data.corr())
data.corr().iloc[:,4] #생략된 부분 확인하기


##### [2] 종속변수와 독립변수 분리하기

X = data.drop(columns = 'mpg') # 독립변수
Y = data['mpg'] #종속변수
print(X.head())
print(Y.head())


#--------- <2-2> 데이터를 관찰하고 가공하기: 데이터 전처리 ---------#

# **빅데이터 분석기사 시험 환경은 시각화가 불가능. 텍스트 기반의 전처리만 가능!!

##### [1] 불필요한 열 삭제하기
print(X.head()) # 모델명인 Unnamed: 0 열은 연비와 무관하므로 삭제
#X.drop(columns = 'Unnamed: 0')
X = X.iloc[:, 1:] # Unnamed: 0 열은 첫 번째 열이니까
print(X.head())


##### [2] 결측값 처리하기

''' ** 빅데이터 분석기사에서는 결측치 삭제하면 안 됨!!!!
    평균, 중위수로 대치하거나 패턴 파악하여 대치해야 함
    그러나 문제에서 삭제하라고 하면 삭제 '''
## 결측치 여부 확인하기
print(X.isnull().sum())

## 평균값으로 대치하기
X_cyl_mean = X['cyl'].mean()
print(X_cyl_mean)
X['cyl'] = X['cyl'].fillna(X_cyl_mean)
print(X.isnull().sum())

## 중위수로 대치하기
X_qsec_median = X['qsec'].median()
print(X_qsec_median)
X['qsec'] = X['qsec'].fillna(X_qsec_median)
print(X.isnull().sum())


##### [3] 잘못된 값을 올바르게 바꾸기
print(X['gear'].unique()) #*3, *5 코딩오류 때문에 object(문자열)로 인식됨
print(X['gear'].replace('*3', '3').replace('*5', '5')) #의도한 바가 맞는지 확인
X['gear'] = X['gear'].replace('*3', '3').replace('*5', '5') 
print(X['gear'].unique())


##### [4] 이상값 처리하기
''' ** 빅데이터 분석기사에서는 이상값 처리할 때 삭제 말고 대치할 것!!!! '''

## 사분위범위 활용하기
''' (Q1 - 1.5*IQR)   &    (Q3 + 1.5*IQR) 을 기준으로 한다'''
X_describe = X.describe()
print(X_describe)
print(X_describe.loc['75%'],'\n', X_describe.loc['25%']) #Q3, Q1
X_iqr = X_describe.loc['75%'] - X_describe.loc['25%']

# 내가 작성한 답안
upperbound = X_describe.loc['75%']+1.5*X_iqr
lowerbound = X_describe.loc['25%']-1.5*X_iqr
for i in X.columns:
    if X[i].dtype != 'O': #string 변수 제외
        # max 값이 Q3+1.5IQR 보다 큰 값 => 이상치 존재 
        num = X.loc[X[i] > upperbound.loc[i]].index #index 추출  
        X.loc[num, i] = upperbound.loc[i] # 대체
        # min 값이 Q1-1.5IQR 보다 작은 값 => 이상치 존재
        num2 = X.loc[X[i] < lowerbound.loc[i]].index #index 추출
        X.loc[num2, i] = lowerbound.loc[i] # 대체

X_describe2 = X.describe()
print(X_describe['max'],'\n',X_describe2['max']) #비교
print(X_describe['min'],'\n',X_describe2['min'])

# 책에 나온 답안
print(X_describe.loc['75%'] + (1.5 * X_iqr))
print(X_describe.loc['max']) #X 변수의 최대값 확인
# 최대값이 범위를 초과하는 변수: cyl, hp, wt, qsec, carb
print(X.loc[X['cyl'] > 14]) #cyl열 값이 14 초과인 index 추출
X.loc[14, 'cyl'] = 14 #14번째 행의 cyl값을 14로 대체
X.loc[14, 'cyl'] #확인
# 나머지 열에 대해서도 위와 같이 진행하나, 일일이 바꿔줘야 한다는 번거로움이 있음.
# 데이터의 차원이 커지면 사용하기 어려움.

## 평균과 표준편차 활용하기
''' mean+-1.5std '''
def outlier(data, column):
    mean = data[column].mean()
    std = data[column].std()
    lowest = mean - std*1.5
    highest = mean + std*1.5
    print('최소 경계값: ', lowest, '최대 경계값: ', highest)
    
    outlier_index = data[column][ (data[column] < lowest) \
                                 | (data[column] > highest) ].index
    return outlier_index    

print(outlier(X, 'qsec'))
print(X.loc[24,'qsec']) # 인덱스24, 열이 qsec인 값 확인하기
X.loc[14,'qsec'] = 42.39618445605777 # 대체
print(X.loc[14,'qsec']) # 확인

print(outlier(X, 'carb'))
print(X.loc[[29,30], 'carb'])
X.loc[[29, 30], 'carb'] = 5.235299966447778
print(X.loc[[29, 30], 'carb'])


##### [5] 데이터를 동일한 범위로 맞추기: 데이터 스케일링
''' 머신러닝 결과가 왜곡되지 않고 특정한 동립변수를 무시하지 않도록 하기 위헤
    독립변수들의 범위를 동일하게 만드는 작업 '''

## 표준 크기 변환: StandardScaler
''' 평균값이 0, 표준편차가 1인 정규분포로 변환하는 방법 '''
# sklearn 패키지의 preprocessing 모듈에서 StandardScaler 함수 가져오기
from sklearn.preprocessing import StandardScaler 

# X변수에서 qsec열만 추출한 후, temp 변수에 저장하기
#type(X['qsec']) # 괄호 하나면 시리즈 = 데이터프레임에서 열이 1개
type(X[['qsec']]) #괄호 두개여야 데이터 프레임
temp = X[['qsec']]

# StandardScaler 함수 호출하여 표준 크기변환 기능을 갖는 scaler라는 객체 만들기 
scaler = StandardScaler()

# 표준 크기변환하는 scaler에게 fit_transform 명령으로 temp 변수의 크기변환 요청하기
print(scaler.fit_transform(temp)) # 결과는 array
qsec_s_scaler = pd.DataFrame(scaler.fit_transform(temp)) # DF로 전환

#qsec_s_scaler의 기초통계 확인하기
print(qsec_s_scaler.describe()) # **mean은 0에 근사하며, std는 1에 근사한 것을 알 수 있다!!
X['qsec'] = pd.DataFrame(scaler.fit_transform(temp))

## 최대 최소 크기변환: MinMaxScaler
''' 최소값을 0, 최대값을 1을 가지는 분포로 변환하는 방법.
    ** 주로 종속변수가 연속형 범주인 >회귀< 문제에 활용 ** '''
from sklearn.preprocessing import MinMaxScaler

temp = X[['qsec']]

scaler = MinMaxScaler()

print(scaler.fit_transform(temp))
qsec_m_scaler = pd.DataFrame(scaler.fit_transform(temp))

print(qsec_m_scaler.describe()) # 최소값 0, 최대값 1
X['qsec'] = pd.Dataframe(scaler.fit_transfrom(temp))

## 로버스트 크기변환: RobustScaler
''' 중앙값이 0, IQR이 1인 분포로 변환하는 방법
    ** 이상값의 영향을 잘 받지 않기 때문에 일반적으로 활용 ** '''
from sklearn.preprocessing import RobustScaler

temp = X[['qsec']]

scaler = RobustScaler()

print(scaler.fit_transform(temp))
qsec_r_scaler = pd.DataFrame(scaler.fit_transform(temp))
print(qsec_r_scaler.describe()) # Q2 = 0 
qsec_r_scaler.describe().loc['75%'] - qsec_r_scaler.describe().loc['25%'] #IQR = 1


##### [6] 데이터 타입 변경하기
''' 데이터의 요약정보를 통해 범주형(object, string)/ 연속형(int64, float64) 확인.
    만약 적절하지 못하다면 astype() 함수로 재설정 '''
# X 변수의 요약정보 확인
print(X.info())
X['gear'] #object로 설정되어 있음
# gear의 데이터 타입을 int64로 변경한 후 다시 gear에 저장하기
X['gear'] = X['gear'].astype('int64')
# gear의 데이터 타입 확인
X['gear'].dtype


##### [7] 범주형을 수치형으로 변경하기: 인코딩(encoding)

## 원핫 인코딩: One-Hot Encoding
''' 1)pandas의 get_dummies(): 자동으로 범주형 변수만 골라서 인코딩 해줌.
    2)sklearn의 OneHotEncoder(): 연속형 변수도 인코딩함.
                                객체와 모델을 학습하는 코드를 추가로 작성해야 함.'''
print(X.head()) # am열 변환 필요
# am열에서 중복 제외한 클래스 알아보기
print(X['am'].unique())
# 원핫인코딩 수행
print(pd.get_dummies(X['am']))
''' am의 범주였던 auto와 manual이라는 2개의 새로운 열로 생성됨. 하지만 범주의 수만큼 변수를 생성하는 것은 메모리 낭비.
    ** (범주 수 - 1)개만큼 생성하는 것이 좋음   =>   drop_first = True 옵션 사용 '''
print(pd.get_dummies(X['am'], drop_first = True)) #manual 열 하나만 생성됨

# X의 전체 열을 대상으로 원핫 인코딩 수행한 결과 확인해보기
print(X.info())

# X 전체를 인코딩하기
print(pd.get_dummies(X, drop_first = True)) # am열이 사라지고 am_manual 생성됨

## 라벨 인코딩: Label Encoding
''' * 라벨 인코딩은 1,2,3 이런 식이라 값의 크고 작음처럼 보일 수 있어서 트리 계열 분석에만 사용
    sklearn의 LabelEncoder() '''
print(X['am'].head())    

from sklearn.preprocessing import LabelEncoder

# LabelEncoder 호출을 통해 인코딩 기능을 갖는 encoder 객체 만들기
encoder = LabelEncoder()
# encoder 통해 am 열 값에 대해 라벨 인코딩 수행
print(encoder.fit_transform(X['am'])) # 인코더에 am 넣어서 변환

# 세 가지 과일 라벨 인코딩
fruit = ['apple', 'banana', 'melon']
# LabelEncoder 호출
encoder = LabelEncoder()
# 인코딩 후 fruit_new로 저장
fruit_new = encoder.fit_transform(fruit)
# 기존 변수와 비교
print(fruit, fruit_new)

## 수동 인코딩: Replace
''' replace(기존값, 변경값) '''
# am열에서 manual은 0으로, auto는 1로 변경 후 am.new에 저장
X['am_new'] = X['am'].replace('manual', 0).replace('auto', 1)
print(X.head())
# 기존의 열은 불필요하므로 삭제
X = X.drop(columns = ['am'])
print(X.head())


##### [8] 파생변수 만들기

## wt을 등급에 따라 구분하는 wt_class 만들기
# 평균 3.3 기준
print(X['wt'] < 3.3) # 3.3보다 작은지 여부
# wt가 3.3보다 작은지 condition에 저장
condition = X['wt']<3.3
# X가 condition조건을 만족하면 wt_class=0
X.loc[condition, 'wt_class'] = 0
# 그렇지 않으면 wt_class=1
X.loc[~condition, 'wt_class'] = 1
print(X[['wt', 'wt_class']])
# 기존 wt 삭제
X = X.drop(columns = ['wt'])
print(X.head())

## qsec을 (1/4mile 도달 시간) 단위에서 1mile 단위로 변환
X['qsec_4'] = X['qsec'] * 4
print(X[['qsec', 'qsec_4']])


#--------- <2-3> 학습 데이터로 공부하기: 모델 생성과 모델 검증 ---------#
 # ++ 내 맘대로 데이터 대충 전처리
''' import pandas as pd
data = pd.read_csv("C:/Users/mtcars.csv")
print(data.head())
data.columns
print(data.describe())
print(data.describe()['wt'])
print(data.info()) #cyl, qsec 결측값 존재
data = data.iloc[:, 1:] # Unnamed: 0 열 제거

print(data['mpg'].unique())
print(data['cyl'].unique()) # nan 존재
print(data['vs'].unique()) # binary
print(data['am'].unique()) # categorical ['manual' 'auto']
print(data['gear'].unique()) # categorical ['4' '3' '*3' '5' '*5']
#print(data.columns[-1])
print(data['carb'].unique()) # [4 1 2 3 6 8]

X = data.drop(columns='mpg') #data.iloc[:, 1:]
Y = data['mpg']

X['gear'] = X['gear'].replace('*3', '3').replace('*5', '5')

X.isnull().sum()
cyl_mean = X['cyl'].mean()
X['cyl'] = X['cyl'].fillna(cyl_mean)
X.isnull().sum()

qsec_median = X['qsec'].median()
X['qsec'] = X['qsec'].fillna(qsec_median)
X.isnull().sum()

def outlier(data, column):
    mean = data[column].mean()
    std = data[column].std()
    lowest = mean - 1.5*std
    highest = mean + 1.5*std
    print('최소경계값:', lowest, '최대경계값:', highest)
    outlier_idx = data[column][ (data[column] < lowest) \
                               | (data[column] > highest) ].index
    return outlier_idx

print( outlier(X, 'qsec') )
X.loc[24, 'qsec'] = 42.39618445605777
print( outlier(X, 'carb') )
X.loc[[29, 30], 'carb'] = 5.235299966447778
print(X.describe())

from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
X['qsec'] = scaler.fit_transform(X[['qsec']]) #df로 넣기

X['gear'] = X['gear'].astype('int64')

X = pd.get_dummies(X, drop_first=True) 
X = X.rename(columns = {'am_manual':'am_new'}) '''


##### [1] 학습 데이터와 테스트 데이터를 분리하기
    
# 데이터 분리를 위해 model_selection 모듈의 train_test_split 함수 호출
from sklearn.model_selection import train_test_split
# train, test 셋 분리하기
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.3, random_state=10)
# 데이터 확인하기
print(X_train.head())
print(y_train.head())
print(X_test.head())
print(y_test.head())


##### [2] 공부하고 평가하기: 모델링modeling

## 모델 학습과 파이썬 코드
''' 1) 사용할 모델의 함수 가져오기
        from sklearn.모듈 import 함수
    2) 학습 모델 만들기
        model = 모델함수()
    3) 학습 데이터로 모델 학습시키기
        model.fit(X_train, y_test)
    4) 학습된 모델로 값 예측하기
        y_train의 예측값 = model.predict(X_train)
        y_test의 예측값 = model.predict(X_test)   '''

## 모델 평가와 파이썬 코드
''' 1) 평가할 함수 가져오기
        from sklearn.metrics import 평가함수
    2) 모델 평가하기
        print(평가함수(y_train, y_train의 예측값))
        print(평가함수(y_test, y_test의 예측값))   '''

## 예측 모델링 수행
''' 1st) 선형회귀 LinearRegression 적합하기 '''
# 선형회귀: linear_model 모듈에서 LinearRegression 모델 가져오기
from sklearn.linear_model import LinearRegression
# 선형회귀 분석 수행할 기본 모델 만들기
model = LinearRegression()
# 생성한 모델에 X_train, y_train으로 학습 시키기
model.fit(X_train, y_train)
# 학습이 완료된 모델에 y_train 값 예측하기
y_train_predicted = model.predict(X_train)
# 학습이 완료된 모델에 X_test 전달하여 y_test 값 예측하기
y_test_predicted = model.predict(X_test)
# 선형회귀 모델로 도출된 y 절편(bete0) 구하기
print(model.intercept_)
# 선형회귀 모델에 포함된 독립변수의 절편 구하기
print(model.coef_)

''' ** 평가지표
    -MAE(Mean Absolute Error): 실제값과 예측값의 차이를 절대값 하여 평균 (0애 가까울 수록 예측 정확도 높음)
    -MSE(Mean Squared Error): 실제값과 예측값의 차이를 제곱하여 평균 (0애 가까울 수록 예측 정확도 높음)
    -RMSE(Root Mean Squared Error): MSE 제곱근 (0애 가까울 수록 예측 정확도 높음)
    -R^2(결정계수): 실제값 분산과 예측값 분산의 비율 (1에 가까울수록 예측 정확도 높음)  '''
# 선형회귀 분석 model에서 학습 데이터에 대한 R^2 구하기
print(model.score(X_train, y_train)) # 0.9076
# 선형회귀 분석 model에서 테스트 데이터에 대한 R^2 구하기
print(model.score(X_test, y_test)) # 0.1073 -> overfitting(과적합) 의심
# 결정계수 계산하는 r2_score/ MAE/ MSE 함수 가져오기
from sklearn.metrics import r2_score
from sklearn.metrics import mean_absolute_error
from sklearn.metrics import mean_squared_error
import numpy as np # 제곱근 계산
# 1) 학습 데이터의 R^2 구하기
print(r2_score(y_train, y_train_predicted)) # 0.9076
# 2) 테스트 데이터의 R^2 구하기
print(r2_score(y_test, y_test_predicted)) # 0.1073 
# 3) 테스트 데이터의 MSE 구하기
print(mean_squared_error(y_test, y_test_predicted)) # 8.8681
# 4) 테스트 데이터의 RMSE 구하기
print(np.sqrt(mean_squared_error(y_test, y_test_predicted))) # 2.9779
# 5) 테스트 데이터의 MAE 구하기
print(mean_absolute_error(y_test, y_test_predicted)) # 2.3116


''' 2nd) 랜덤 포레스트 회귀 RandomForestRegressor 적합하기
        앙상블 모형 중 하나로 무작위의 다수 트리를 만들어 투표로 값 결정 '''
# 랜덤 포레스트 회귀: ensemble 모듈에서 RandomForestRegressor 모델 가져오기
from sklearn.ensemble import RandomForestRegressor
# 랜덤 포레스트 회귀 분석 수행할 모델 만들기
model = RandomForestRegressor(random_state=10)
# 생성한 모델에 트레이닝 데이터 피팅
model.fit(X_train, y_train)
# 학습이 완료된 모델에 X_train 전달하여 y_train 값 예측하기
y_train_prdicted = model.predict(X_train)
# 학습이 완료된 모델에 X_test 전달하여 y_test 값 예측하기
y_test_predicted = model.predict(X_test)
# R^2/ MSE/ MAE 구하는 함수 일괄로 가져오기
from sklearn.metrics import r2_score, mean_squared_error, mean_absolute_error
# 학습 데이터의 결정계수 구하기
print(r2_score(y_train, y_train_predicted)) # 0.9075
# 테스트 데이터의 결정계수 구하기
print(r2_score(y_test, y_test_predicted)) # 0.3913
# 테스트 데이터의 MSE 구하기
print(mean_squared_error(y_test, y_test_predicted)) # 6.0463
# 테스트 데이터의 MAE 구하기
print(mean_absolute_error(y_test, y_test_predicted)) # 1.8203
# 테스트 데이터의 RMSE 구하기
print(np.sqrt(mean_squared_error(y_test, y_test_predicted))) # 2.4589

''' ** 모델 성능 끌어올리기
    1) n_estimators: 생성할 트리 개수
    2) criterion: 트리 분할 기준(default = mse)     ''' 
# 트리 생성은 1,000개로, 트리 분할 기준은 MAE 지표로 분석할 모델 만들기
model = RandomForestRegressor(n_estimators = 1000, criterion = 'mae', random_state=10)
# 기본적인 정보가 담긴 모델에 학습 데이터 학습 시키기
model.fit(X_train, y_train)
# 학습이 완료된 모델로 y_train 예측하기
y_train_predicted = model.predict(X_train)
# 학습이 완료된 모델로 y_test 예측하기
y_test_predicted = model.predict(X_test)
# 결정계수/MSE/ MAE 구하기
print(r2_score(y_train, y_train_predicted)) # 0.9809-> 약 0.07 상승
print(r2_score(y_test, y_test_predicted)) # 0.4789 -> 0.08 상승
print(mean_squared_error(y_test, y_test_predicted)) # 5.1760 -> 0.9 하락
print(mean_absolute_error(y_test, y_test_predicted)) # 1.7880 -> 0.67 하락


''' 3rd) 그래디언트 부스팅 GradiantBoostingRegressor 적합하기
        앙상블 모형 중 하나로 다수의 결정트리를 사용하며,
        이전 결정나무에서 발생한 오차를 보완하여 새로운 트리를 만듦 '''
# 그래디언트 부스팅 회귀함수 가져오기
from sklearn.ensemble import GradientBoostingRegressor        
# 하이퍼 파라미터 기본값
model = GradientBoostingRegressor(random_state = 10)
# 학습 데이터로 모델 학습 후, 예측하기
model.fit(X_train, y_train)
y_train_predicted = model.predict(X_train)        
y_test_predicted = model.predict(X_test)        
# 결정계수/ MSE/ MAE 구하기
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score        
print(r2_score(y_train, y_train_predicted)) # 0.9999 
print(r2_score(y_test, y_test_predicted)) # 0.3303
print(mean_squared_error(y_test, y_test_predicted)) # 6.6523
print(mean_absolute_error(y_test, y_test_predicted)) # 2.0526


''' 4th) 익스트림 그래디언트 부스팅 eXtreme Gradient Boosting(XGB) 적합하기
        다수의 약한 분류기를 묶어 정확도를 향상하는 기법.
        병렬처리 기능을 지원하여 빠른 속도로 결과 도출 가능 '''
# xgboost 라이브러리에서 XGBRegressor 함수 가져오기
from xgboost import XGBRegressor
# XGBRegressor 함수 호출
model = XGBRegressor(random_state=66)
# 학습 데이터로 모델 학습 시키고 예측하기
model.fit(X_train, y_train)
y_train_predicted = model.predict(X_train)
y_test_predicted = model.predict(X_test)
# R2, MSE, MAE 구하기
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
print(r2_score(y_train, y_train_predicted)) # 0.9999
print(r2_score(y_test, y_test_predicted)) # 0.3000
print(mean_squared_error(y_test, y_test_predicted)) # 6.9536
print(mean_absolute_error(y_test, y_test_predicted)) # 2.1739


## 분류 모델링 수행

# am을 종속변수로 바꾸기
# X_train 변수에서 종속변수인 am_new 열은 삭제한 후, 결과는 X_train2에 저장
X_train2 = X_train.drop(columns = 'am_new')
# X_train 변수에서 am_new열을 추출한 후, 종속변수인 y_train2에 저장하기
y_train2 = X_train['am_new']
# X_test 변수에서 종속변수인 am_new 열은 삭제한 후, 결과는 X_test2에 저장
X_test2 = X_test.drop(columns = 'am_new')
# X_test 변수에서 am_new열을 추출한 후, 종속변수인 y_test2에 저장하기
y_test2 = X_test['am_new']
# 데이터 확인
print(X_train2.head())
print(X_test2.head())
print(y_train2.head())
print(y_test2.head())

''' 1st) 의사결정나무 분류 DecisionTreeClassifier 적합하기
        과적합 가능성이 큰 모델.                             '''
# tree 모듈에서 제공하는 DecisionTreeClassifier 함수 가져오기
from sklearn.tree import DecisionTreeClassifier
# 의사결정나무 분류 분석 수행할 모델 만들기
model = DecisionTreeClassifier()
# 생성한 모델에 X_train, y_train 전달하여 의사결정나무 분류 학습
model.fit(X_train2, y_train2)
# 학습이 완료된 모델로 예측하기
y_train2_predicted = model.predict(X_train2)
y_test2_predicted = model.predict(X_test2)

''' ** 평가지표
    아래 네 지표 모두 1에 가까울수록 성능 좋은 모델!
    -roc_auc_score: ROC curve
    -accuracy_score(정확도): TP+TN / TP+TN+FP+FN (전체에서 정답 비율)
    -precision_score(정밀도): TP / TP+FP (양성으로 예측한 것 중에 찐 양성 비율)
    -recall_score(재현율): TP / TP+FN (실제 양성 중 양성 예측한 비율) '''
# ROC-AUC/ Accuracy/ Precision/ Recall 계산 위해 metrics 모듈의 함수 가져오기
from sklearn.metrics import roc_auc_score, accuracy_score, precision_score, recall_score
# 테스트 데이터의 roc-auc 구하기
print(roc_auc_score(y_test2, y_test2_predicted)) # 0.7619  <- 빅분기 평가지표 **
print(accuracy_score(y_test2, y_test2_predicted)) # 0.8
print(precision_score(y_test2, y_test2_predicted)) # 0.6666
print(recall_score(y_test2, y_test2_predicted)) # 0.6666


''' 2nd) 랜덤 포레스트 분류 RandomForestClassifier 적합하기
        앙상블 모형 중 하나로 무자구이의 다수 트리를 만들어 투표로 결정 '''
# ensemble 모듈에서 RandomForestClassifier 함수 가져오기
from sklearn.ensemble import RandomForestClassifier
# 랜덤 포레스트 분류 분석을 수행할 모델 만들기
model = RandomForestClassifier()
# 생성한 모델로 학습 시키기
model.fit(X_train2, y_train2)
# 학습이 완료된 모델로 예측하기
y_train2_predicted = model.predict(X_train2)
y_test2_predicted = model.predict(X_test2)
# 평가하기
from sklearn.metrics import roc_auc_score, accuracy_score, precision_score, recall_score
print(roc_auc_score(y_train2, y_train2_predicted)) # 1.0
print(roc_auc_score(y_test2, y_test2_predicted)) # 0.7619
print(accuracy_score(y_test2, y_test2_predicted)) # 0.8
print(precision_score(y_test2, y_test2_predicted)) # 0.6666
print(recall_score(y_test2, y_test2_predicted)) # 0.6666


''' 3rd) 로지스틱 회귀 LogisticRegression 적합하기 '''
# linear_model 모듈에서 LogisticRegression 함수 가져오기
from sklearn.linear_model import LogisticRegression
# 로지스틱 회귀 분석으로 수행할 모델 만들고 학습하기
model = LogisticRegression()
model.fit(X_train2, y_train2)
# 예측하기
y_test2_prediected = model.predict(X_test2)
# 평가하기
from sklearn.metrics import roc_auc_score, accuracy_score, precision_score, recall_score
print(roc_auc_score(y_test2, y_test2_predicted)) # 0.7619


''' 4th) 익스트림 그래디언트 부스팅 분류(eXtreme Gradient Boosting) XGBClassifier 적합하기
        앙상블 모형으로 다수의 약한 분류기를 묶어서 정확도를 향상하는 기법.
        병렬처리 지원하여 빠른 속도.                        '''
# xgboost 라이브러리에서 제공하는 XGBClassifier 함수 가져오기
from xgboost import XGBClassifier
# XGB 분류 분석으로 수행할 모델 만들고 학습 시키기
model = XGBClassifier()
model.fit(X_train2, y_train2)
# 예측하기
y_test2_predicted = model.predict(X_test2)
# y_test2_predicted 값 확인하기
print(y_test2_predicted)
''' ** predict_proba()
    종속변수의 분류 값 예측이 아닌, 분류해야 하는 종속변수의 0과 1에 대한 확률값 계산.
    즉, 0으로 분류될 확률과 1로 분류될 확률을 각각 계산.
    최종적으로 확률이 높은 값을 예측값으로 분류하게 됨 '''
# 테스트 데이터의 종속변수에 대한 분류 확률 계산하기
y_test2_proba = model.predict_proba(X_test2)
# 테스트 데이터에 대한 분류 확률은 y_test2_proba 확인하기
print(y_test2_proba) #1열은 0으로 분류될 prob, 2열은 1로 분류될 prob
# y_test2_proba를 통해 y_test2_predicted가 결정됨
# 예측하기
print(roc_auc_score(y_test2, y_test2_predicted)) # 0.7619


##### [+] 분류 모델로 사용할 수 있는 기타 알고리즘

## 1) 서포트 벡터 머신(SVC: Support Vector Classification)
from sklearn.svm import SVC
model = SVC()
model.fit(X_train2, y_train2)
y_test2_predicted = model.predict(X_test2)
print(roc_auc_score(y_test2, y_test2_predicted)) 

## 2) 배깅 분류(BaggingClassifier)
from sklearn.ensemble import BaggingClassifier
model = BaggingClassifier()        
model.fit(X_train2, y_train2)
y_test2_predicted = model.predict(X_test2)
print(roc_auc_score(y_test2, y_test2_predicted))

## 3) K-최근접 이웃 분류(KNN: K-Nearest Neighbor)
from sklearn.neighbors import KNeighborsClassifier
model = KNeighborsClassifier()
model.fit(X_train2, y_train2)
y_test2_predicted = model.predict(X_test2)
print(roc_auc_score(y_test2, y_test2_predicted))

## 4) 다층 퍼셉트론 분류(MLPClassifier: Multi Layer Perceptron Classifier)
from sklearn.neural_network import MLPClassifier
model = MLPClassifier()
model.fit(X_train2, y_train2)
y_test2_predicted = model.predict(X_test2)
print(roc_auc_score(y_test2, y_test2_predicted))


#--------- <2-4> 최종 결과 공유하기 ---------#

##### [1] 결과 출력하기: 제1유형
''' 작업형 제1유형은 최종 결과를 print()하는 것. 
    ** 중간 출력값들은 주석 처리나 삭제해야 함! => 최종 결과만 print~'''


##### [2] 결과를 파일에 저장하기: 제2유형
''' 작업형 제2유형은 최종 결과를 csv 형식으로 저장하여 제출.
    따라서 저장할 파일명, 저장할 경로를 명확히 지정하여 to_csv 함수 사용! '''
# 제출할 y_test2_predicted 변수의 데이터 타입 확인하기
type(y_test2_predicted) #array
# 제출할 변수를 데이터 프레임으로 변경하고, 저장하기
pd.DataFrame(y_test2_predicted).to_csv("C:/Users/output.csv", index=False)
# ******** index = False는 불필요한 행번호 제외하는 옵션!!!! 꼭 써주기~!
Comments