<jupyter_start><jupyter_text>1장. 머신러닝 개요 *아래 링크를 통해 이 노트북을 주피터 노트북 뷰어(nbviewer.org)로 보거나 구글 코랩(colab.research.google.com)에서 실행할 수 있습니다.*      주피터 노트북 뷰어로 보기        구글 코랩(Colab)에서 실행하기<jupyter_code># 노트북이 코랩에서 실행 중인지 체크합니다.
import sys
if 'google.colab' in sys.modules:
    !pip install -q --upgrade xgboost
    !wget -q https://raw.githubusercontent.com/rickiepark/handson-gb/main/Chapter01/bike_rentals.csv<jupyter_output><empty_output><jupyter_text>데이터 랭글링 데이터셋 1 - 자전거 대여<jupyter_code># 판다스를 임포트합니다.
import pandas as pd
# 'bike_rentals.csv'를 데이터프레임으로 읽습니다.
df_bikes = pd.read_csv('bike_rentals.csv')
# 처음 다섯 개 행을 출력합니다.
df_bikes.head()<jupyter_output><empty_output><jupyter_text>데이터 이해하기 describe()<jupyter_code># df_bikes의 통계를 출력합니다.
df_bikes.describe()<jupyter_output><empty_output><jupyter_text>info()<jupyter_code># df_bikes 정보를 출력합니다.
df_bikes.info()<jupyter_output><class 'pandas.core.frame.DataFrame'>
RangeIndex: 731 entries, 0 to 730
Data columns (total 16 columns):
 #   Column      Non-Null Count  Dtype  
---  ------      --------------  -----  
 0   instant     731 non-null    int64  
 1   dteday      731 non-null    object 
 2   season      731 non-null    float64
 3   yr          730 non-null    float64
 4   mnth        730 non-null    float64
 5   holiday     731 non-null    float64
 6   weekday     731 non-null    float64
 7   workingday  731 non-null    float64
 8   weathersit  731 non-null    int64  
 9   temp        730 non-null    float64
 10  atemp       730 non-null    float64
 11  hum         728 non-null    float64
 12  windspeed   726 non-null    float64
 13  casual      731 non-null    int64  
 14  registered  731 non-null    int64  
 15  cnt         731 non-null    int64  
dtypes: float64(10), int64(5), object(1)
memory usage: 91.5+ KB<jupyter_text>누락된 값 처리하기 누락된 값의 개수 계산하기<jupyter_code># 누락된 값의 개수 더하기
df_bikes.isna().sum().sum()<jupyter_output><empty_output><jupyter_text>누락된 값 출력하기<jupyter_code># df_bikes에 있는 누락된 값을 출력합니다.
df_bikes[df_bikes.isna().any(axis=1)]<jupyter_output><empty_output><jupyter_text>누락된 값 고치기 중간값이나 평균으로 바꾸기<jupyter_code># windspeed의 누락된 값을 중간값으로 채웁니다.
df_bikes['windspeed'].fillna((df_bikes['windspeed'].median()), inplace=True)
# 인덱스 56과 81의 행을 출력합니다.
df_bikes.iloc[[56, 81]]<jupyter_output><empty_output><jupyter_text>중간값이나 평균으로 그룹바이 하기<jupyter_code># season으로 groupby한 중간값을 얻습니다.
df_bikes.groupby(['season']).median()
# 'hum' 열의 누락된 값을 season의 중간값으로 바꿉니다.
df_bikes['hum'] = df_bikes['hum'].fillna(df_bikes.groupby('season')['hum'].transform('median'))<jupyter_output><empty_output><jupyter_text>특정 행에서 중간값이나 평균을 구하기<jupyter_code># 'temp' 열의 누락된 값을 확인합니다.
df_bikes[df_bikes['temp'].isna()]
# temp와 atemp의 평균을 계산합니다.
mean_temp = (df_bikes.iloc[700]['temp'] + df_bikes.iloc[702]['temp'])/2
mean_atemp = (df_bikes.iloc[700]['atemp'] + df_bikes.iloc[702]['atemp'])/2

# 누락된 값을 평균 온도로 대체합니다.
df_bikes['temp'].fillna((mean_temp), inplace=True)
df_bikes['atemp'].fillna((mean_atemp), inplace=True)<jupyter_output><empty_output><jupyter_text>날짜 추정하기<jupyter_code># 'dteday' 열을 datetime 객체로 바꿉니다.
df_bikes['dteday'] = pd.to_datetime(df_bikes['dteday'])
df_bikes['dteday'].apply(pd.to_datetime, infer_datetime_format=True, errors='coerce')
# datetime을 임포트합니다.
import datetime as dt
df_bikes['mnth'] = df_bikes['dteday'].dt.month
# 마지막 다섯 개 행을 출력합니다.
df_bikes.tail()
# 인덱스 730 행의 'yr' 열을 1.0으로 바꿉니다.
df_bikes.loc[730, 'yr'] = 1.0
# 마지막 다섯 개 행을 출력합니다.
df_bikes.tail()<jupyter_output><empty_output><jupyter_text>수치형이 아닌 열 삭제하기<jupyter_code># 'dteday' 열을 삭제합니다.
df_bikes = df_bikes.drop('dteday', axis=1)<jupyter_output><empty_output><jupyter_text>회귀 모델 만들기 자전거 대여 예측하기<jupyter_code># 'casual', 'registered' 열을 삭제합니다.
df_bikes = df_bikes.drop(['casual', 'registered'], axis=1)<jupyter_output><empty_output><jupyter_text>나중을 위해서 데이터 저장하기<jupyter_code># 'bike_rentals_cleaned.csv' 파일로 저장합니다.
df_bikes.to_csv('bike_rentals_cleaned.csv', index=False)<jupyter_output><empty_output><jupyter_text>특성과 타깃 준비하기<jupyter_code># X와 y로 데이터를 나눕니다.
X = df_bikes.iloc[:,:-1]
y = df_bikes.iloc[:,-1]<jupyter_output><empty_output><jupyter_text>사이킷런 사용하기<jupyter_code># train_test_split 함수를 임포트합니다.
from sklearn.model_selection import train_test_split

# LinearRegression 클래스를 임포트합니다.
from sklearn.linear_model import LinearRegression

# 데이터를 훈련 세트와 테스트 세트로 나눕니다.
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=2)<jupyter_output><empty_output><jupyter_text>경고 끄기<jupyter_code># 경고를 표시하지 않습니다.
import warnings
warnings.filterwarnings('ignore')

import xgboost as xgb
xgb.set_config(verbosity=0)<jupyter_output><empty_output><jupyter_text>선형 회귀 모델 만들기<jupyter_code># LinearRegression 모델 객체를 만듭니다.
lin_reg = LinearRegression()

# 훈련 데이터로 lin_reg 객체를 훈련합니다.
lin_reg.fit(X_train, y_train)

# lin_reg 객체를 사용해 X_test에 대한 예측값을 만듭니다.
y_pred = lin_reg.predict(X_test)

# mean_squared_error 함수를 임포트합니다.
from sklearn.metrics import mean_squared_error

# numpy를 임포트합니다.
import numpy as np

# mean_squared_error 함수로 평균 제곱 오차를 계산합니다.
mse = mean_squared_error(y_test, y_pred)

# 평균 제곱근 오차를 계산합니다.
rmse = np.sqrt(mse)

# 평균 제곱근 오차를 출력합니다.
print("RMSE: %0.2f" % (rmse))
mean_squared_error(y_test, y_pred, squared=False)
# 'cnt' 열의 통계를 출력합니다.
df_bikes['cnt'].describe()<jupyter_output><empty_output><jupyter_text>XGBRegressor<jupyter_code># XGBRegressor를 임포트합니다.
from xgboost import XGBRegressor

# XGBRegressor의 객체 xg_reg를 만듭니다.
xg_reg = XGBRegressor()

# 훈련 데이터로 xg_reg 객체를 훈련합니다.
xg_reg.fit(X_train, y_train)

# 테스트 세트의 레이블을 예측합니다.
y_pred = xg_reg.predict(X_test)

# 평균 제곱 오차를 계산합니다.
mse = mean_squared_error(y_test, y_pred)

# 평균 제곱근 오차를 계산합니다.
rmse = np.sqrt(mse)

# 평균 제곱근 오차를 출력합니다.
print("RMSE: %0.2f" % (rmse))<jupyter_output>RMSE: 705.11<jupyter_text>교차 검증 선형 회귀 교차 검증<jupyter_code># cross_val_score 함수를 임포트합니다.
from sklearn.model_selection import cross_val_score

# LinearRegression 클래스 객체를 만듭니다.
model = LinearRegression()

# 10-폴드 교차 검증으로 평균 제곱 오차를 구합니다.
scores = cross_val_score(model, X, y, scoring='neg_mean_squared_error', cv=10)

# 이 점수의 제곱근을 계산합니다.
rmse = np.sqrt(-scores)

# 평균 제곱근 오차를 출력합니다.
print('회귀 rmse:', np.round(rmse, 2))

# 평균 점수를 출력합니다.
print('RMSE 평균: %0.2f' % (rmse.mean()))
-np.mean(cross_val_score(model, X, y, scoring='neg_root_mean_squared_error', cv=10))
from sklearn.model_selection import cross_validate

cv_results = cross_validate(model, X, y, scoring='neg_root_mean_squared_error', cv=10)
-np.mean(cv_results['test_score'])<jupyter_output><empty_output><jupyter_text>XGBoost 교차 검증<jupyter_code># XGBRegressor 객체를 만듭니다.
model = XGBRegressor(objective="reg:squarederror")

# 10-폴드 교차 검증으로 평균 제곱 오차를 구합니다.
scores = cross_val_score(model, X, y, scoring='neg_mean_squared_error', cv=10)

# 이 점수의 제곱근을 계산합니다.
rmse = np.sqrt(-scores)

# 평균 제곱근 오차를 출력합니다.
print('회귀 rmse:', np.round(rmse, 2))

# 평균 점수를 출력합니다.
print('RMSE 평균: %0.2f' % (rmse.mean()))<jupyter_output>회귀 rmse: [ 717.65  692.8   520.7   737.68  835.96 1006.24  991.34  747.61  891.99
 1731.13]
RMSE 평균: 887.31<jupyter_text>분류 모델 만들기 데이터 랭글링 데이터 적재<jupyter_code># UCI 머신러닝 저장소에서 인구 조사 데이터셋(adult)을 로드합니다.
df_census = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data')

# 처음 다섯 개 행을 출력합니다.
df_census.head()
# 헤더가 없는 데이터셋을 로드합니다.
df_census = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data', header=None)

# 처음 다섯 개 행을 출력합니다.
df_census.head()
# df_census 열 이름을 정의합니다.
df_census.columns = ['age', 'workclass', 'fnlwgt', 'education', 'education-num', 'marital-status', 'occupation',
                  'relationship', 'race', 'sex', 'capital-gain', 'capital-loss', 'hours-per-week', 'native-country', 
                   'income']

# 처음 다섯 개 행을 출력합니다.
df_census.head()<jupyter_output><empty_output><jupyter_text>누락된 값<jupyter_code># df_census 정보를 출력합니다.
df_census.info()<jupyter_output><class 'pandas.core.frame.DataFrame'>
RangeIndex: 32561 entries, 0 to 32560
Data columns (total 15 columns):
 #   Column          Non-Null Count  Dtype 
---  ------          --------------  ----- 
 0   age             32561 non-null  int64 
 1   workclass       32561 non-null  object
 2   fnlwgt          32561 non-null  int64 
 3   education       32561 non-null  object
 4   education-num   32561 non-null  int64 
 5   marital-status  32561 non-null  object
 6   occupation      32561 non-null  object
 7   relationship    32561 non-null  object
 8   race            32561 non-null  object
 9   sex             32561 non-null  object
 10  capital-gain    32561 non-null  int64 
 11  capital-loss    32561 non-null  int64 
 12  hours-per-week  32561 non-null  int64 
 13  native-country  32561 non-null  object
 14  income          32561 non-null  object
dtypes: int64(6), object(9)
memory usage: 3.7+ MB<jupyter_text>수치형이 아닌 열<jupyter_code># education 열을 삭제합니다.
df_census = df_census.drop(['education'], axis=1)
# get_dummies를 사용해 숫자가 아닌 열을 바꿉니다.
df_census = pd.get_dummies(df_census)

# 처음 다섯 개 행을 출력합니다.
df_census.head()<jupyter_output><empty_output><jupyter_text>특성과 타깃 데이터<jupyter_code># 'income_ <=50K' 열을 삭제합니다.
df_census = df_census.drop('income_ <=50K', axis=1)
# 데이터를 X와 y로 나눕니다.
X = df_census.iloc[:,:-1]
y = df_census.iloc[:,-1]<jupyter_output><empty_output><jupyter_text>로지스틱 회귀<jupyter_code># LogisticRegression을 임포트합니다.
from sklearn.linear_model import LogisticRegression<jupyter_output><empty_output><jupyter_text>교차 검증 함수<jupyter_code># classifier와 num_splits 매개변수를 가진 cross_val 함수를 정의합니다.
def cross_val(classifier, num_splits=10):
    
    # 분류 모델 생성
    model = classifier

    # 교차 검증 점수 얻기
    scores = cross_val_score(model, X, y, cv=num_splits)

    # 정확도 출력
    print('정확도:', np.round(scores, 2))

    # 평균 정확도 출력
    print('평균 정확도: %0.2f' % (scores.mean()))
# LogisticRegression으로 cross_val 함수를 호출합니다.
cross_val(LogisticRegression())<jupyter_output>정확도: [0.8  0.8  0.79 0.8  0.79 0.81 0.79 0.79 0.8  0.8 ]
평균 정확도: 0.80<jupyter_text>XGBClassifier<jupyter_code># XGBClassifier를 임포트합니다.
from xgboost import XGBClassifier
# XGBClassifier로 cross_val 함수를 호출합니다.
cross_val(XGBClassifier(n_estimators=5))<jupyter_output>정확도: [0.85 0.86 0.87 0.85 0.86 0.86 0.86 0.87 0.86 0.86]
평균 정확도: 0.86
{'fraction_non_alphanumeric': 0.12701553071520427, 'fraction_numerical': 0.04411910179048373, 'mean_word_length': 4.346377578001058, 'pattern_counts': {'":': 0, '<': 107, '<?xml version=': 0, '>': 105, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '27', 'dir': 'jupyter-structured-clean-dedup', 'id': '33973', 'license': 'MIT', 'n_tokens_mistral': 5653, 'n_tokens_neox': 5948, 'n_words': 911, 'path': 'Chapter01/Gradient_Boosting_in_Machine_Learning.ipynb', 'repo_name': 'rickiepark/handson-gb', 'size': '10109'}