본문 바로가기
쿠버네티스,쿠버플로우

던파 데이터 분석, 모델링 부분

by 세용용용용 2023. 9. 21.

던파 아이템

0. 먼저 외부서 가져온 던파 골드 시세 테이블을 로드해 데이터프레임으로 뺴준다 (해당 코드는 [던파 쿠버플로우, 쿠버네티스] 부분에 있습니다.)

import pandas as pd
import pymysql
from pymongo import MongoClient
from sklearn.preprocessing import StandardScaler
import numpy as np

# 레이어를 선형으로 쌓아 순차적으로 연결하여 모델을 만드는 방식
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense

# 연결 정보 설정
host = "10.233.18.183"
port = 3306
database = "donpa_item"
user = "root"
password = "1234"

# 연결
connection = pymysql.connect(
    host=host,
    port=port,
    user=user,
    password=password,
    database=database
)

# SQL 쿼리
query = "SELECT * FROM goldprice"

date_df = pd.read_sql(query, connection)

# 연결 종료
connection.close()

 

1. 몽고db연결 골드 시세 컬러 합쳐주기 및 간단 전처리

import pandas as pd
from pymongo import MongoClient

# MongoDB 연결 설정
client = MongoClient("mongodb://3.38.178.84:27017/")
db = client["donpa"]  # 데이터베이스명
collection = db["donpa_data"]  # 컬렉션명

# 컬렉션 데이터 조회
data = collection.find()

# 데이터프레임으로 변환
df = pd.DataFrame(data)

# _id 컬럼은 제거해주자
df = df.drop(columns="_id")
display(df)

from datetime import datetime
# object타입의 데이터 datetime타입으로 변경하는 코드
df['now_datetime'] = pd.to_datetime(df['now_datetime'])
# 시간까지만 잘라내기
df['now_datetime'] = df['now_datetime'].dt.strftime("%Y-%m-%d %H:%M")
# now_datetime 다시 datetime타입으로 변경하는 코드
df['now_datetime'] = pd.to_datetime(df['now_datetime'])

# unitPrice 컬럼 float타입으로 변경
df['unitPrice'] = df['unitPrice'].astype('float')

# sell, buy컬럼을 합쳐주기 위해 date컬럼 생성
df['date'] = pd.to_datetime(df['now_datetime']).dt.strftime('%Y%m%d')

# sell, buy컬럼 붙여주자!!
df = df.merge(date_df, left_on='date', right_on='date', how='inner')

# 붙여주고 date는 이제 필요없으므로 drop시켜줌
df.drop(columns = 'date', inplace=True)

# 잘 수정했는지 확인
df.info()
df

 

합쳐진것을 확인!!

 

 

2. 피처 엔지니어링

new_df = df
# 년 컬럼 추가
new_df['year'] = new_df['soldDate'].dt.year

# 월 컬럼 추가
new_df['month'] = new_df['soldDate'].dt.month

# 일 컬럼 추가
new_df['day'] = new_df['soldDate'].dt.day

# 시간 컬럼 추가
new_df['hour'] = new_df['soldDate'].dt.hour

# 분 컬럼 추가
new_df['minute'] = new_df['soldDate'].dt.minute

# 요일 컬럼 추가해주자
new_df['day_name'] = new_df['soldDate'].dt.day_name()

# 타겟 컬러 맨뒤로 보내기
unit_price_column = new_df.pop('unitPrice')
new_df['unitPrice'] = unit_price_column

# 필요 없는 컬럼 삭제
new_df = new_df.drop(columns = ['soldDate','itemName'])
new_df.head()

 

 

3. 타겟값 분리해주자

X_train = new_df.drop(columns = 'unitPrice')
y_train = new_df['unitPrice']

display(X_train.head())
y_train.head()

 

 

4. 왜도 있는지 확인후 있으면 로그변환ㄱㄱ (데이터 마다 다르지만 보통 절대값이 1이 넘어가면 왜도가 있다고 판단)

from scipy.stats import skew

# 왜도 있는 컬럼 모은 리스트
log_list = [] 

# 수치형 컬럼들만 돌려야됨
for i in X_train.select_dtypes(exclude='object').columns:
    skewness = skew(X_train[i])
    
    # 절대값이 1이 넘어가면 왜도가 있다고 판단
    if abs(skewness) >= 1:
        log_list.append(i)

print(log_list)

# 왜도 있는 컬럼들만 로그변환을 해주자
import numpy as np
for i in log_list:
    if X_train[i].min() < 0:
        X_train[i] = X_train.map(lambda x : x+abs(X_train[i].min()))
    X_train[i] = np.log1p(X_train[i])

X_train

 

 

5. 데이터를 분할하자 학습용8, 테스트2

from sklearn.model_selection import train_test_split
X_train, X_validation, Y_train, Y_validation = train_test_split(X_train,y_train, test_size=0.2, random_state=1)

#print(X_train.shape, X_validation.shape, Y_train.shape, Y_validation.shape)
X_train.reset_index(drop=True, inplace=True)
X_validation.reset_index(drop=True, inplace=True)

 

 

6. 수치형 데이터  StandardScaler 해주자!!

obj_col = X_train.select_dtypes(include='object').columns

from sklearn.preprocessing import StandardScaler
sds = StandardScaler()
sds.fit(X_train.drop(columns = obj_col))

X_train_sc = sds.transform(X_train.drop(columns = obj_col))
X_train_sc = pd.DataFrame(X_train_sc, columns = X_train.drop(columns = obj_col).columns)

X_validation_sc = sds.transform(X_validation.drop(columns = obj_col))
X_validation_sc = pd.DataFrame(X_validation_sc, columns = X_validation.drop(columns = obj_col).columns)


# object 타입 컬럼 붙여주기
for i in obj_col:
    X_train_sc[i] = X_train[i]
    X_validation_sc[i] = X_validation[i]

 

 

7. 원핫 인코딩 돌려주자

from sklearn.preprocessing import OneHotEncoder

# OneHotEncoder 객체 생성
encoder = OneHotEncoder()

X_full = pd.concat([X_train_sc, X_validation_sc])

# 범주형 열만 선택
obj_df = X_full.select_dtypes(include='object')

# 숫자형 열만 선택
no_obj_df = X_full.select_dtypes(exclude='object')

# 범주형 열을 원핫 인코딩
encoded_features = encoder.fit_transform(obj_df)

# 인코딩된 결과를 데이터프레임으로 변환
encoded_df = pd.DataFrame(encoded_features.toarray(), columns=encoder.get_feature_names(obj_df.columns))

# 인코딩된 범주형 열과 숫자형 열을 합침
X_train_sc_ec = pd.concat([no_obj_df[:len(X_train_sc)] , encoded_df[:len(X_train_sc)]], axis = 1)
X_validation_sc_ec = pd.concat([no_obj_df[len(X_train_sc):] , encoded_df[len(X_train_sc):].reset_index(drop=True)], axis = 1)
#X_validation_sc_ec

 

 

8. 모델 선정 (랜포 vs xgboost vs lgbm)

1) RandomForest

from sklearn.ensemble import RandomForestRegressor
RFC = RandomForestRegressor(random_state=10)
RFC.fit(X_train_sc_ec, Y_train)

pred_train = RFC.predict(X_train_sc_ec)
pred_validation = RFC.predict(X_validation_sc_ec)

# 성능평가
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
mse_train = mean_squared_error(Y_train, pred_train)
mse_validation = mean_squared_error(Y_validation, pred_validation)

mae_train = mean_absolute_error(Y_train, pred_train)
mae_validation = mean_absolute_error(Y_validation, pred_validation)

r2_train = r2_score(Y_train, pred_train)
r2_validation = r2_score(Y_validation, pred_validation)

print('mse_train',mse_train)
print('mae_train',mae_train)
print('r2_train',r2_train)
print('\n')
print('mse_validation',mse_validation)
print('mae_validation',mae_validation)
print('r2_validation',r2_validation)

예측 데이터 그래프로 시각화

import matplotlib.pyplot as plt

plt.figure(figsize=(10, 6))
plt.plot(np.array(Y_validation), label='Actual')
plt.plot(pred_validation, label='Predicted', linestyle='--')
plt.xlabel('Sample Index')
plt.ylabel('Value')
plt.title('Actual vs Predicted')
plt.legend()
plt.show()

 

 

 

2) xgboost

import xgboost as xgb
xgb = xgb.XGBRegressor(random_state=10)
xgb.fit(X_train_sc_ec, Y_train)

pred_train = xgb.predict(X_train_sc_ec)
pred_validation = xgb.predict(X_validation_sc_ec)

# 성능평가
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
mse_train = mean_squared_error(Y_train, pred_train)
mse_validation = mean_squared_error(Y_validation, pred_validation)

mae_train = mean_absolute_error(Y_train, pred_train)
mae_validation = mean_absolute_error(Y_validation, pred_validation)

r2_train = r2_score(Y_train, pred_train)
r2_validation = r2_score(Y_validation, pred_validation)

print('mse_train',mse_train)
print('mae_train',mae_train)
print('r2_train',r2_train)
print('\n')
print('mse_validation',mse_validation)
print('mae_validation',mae_validation)
print('r2_validation',r2_validation)

예측 데이터 그래프로 시각화

import matplotlib.pyplot as plt

plt.figure(figsize=(10, 6))
plt.plot(np.array(Y_validation), label='Actual')
plt.plot(pred_validation, label='Predicted', linestyle='--')
plt.xlabel('Sample Index')
plt.ylabel('Value')
plt.title('Actual vs Predicted')
plt.legend()
plt.show()

 

 

 

3) lgbm

import lightgbm as lgb

# LGBMRegressor 객체 생성
LGBMR = lgb.LGBMRegressor(random_state=10)

# 모델 학습
LGBMR.fit(X_train_sc_ec, Y_train)

# 학습된 모델로 예측
pred_train = LGBMR.predict(X_train_sc_ec)
pred_validation = LGBMR.predict(X_validation_sc_ec)

# 성능 평가
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score

mse_train = mean_squared_error(Y_train, pred_train)
mse_validation = mean_squared_error(Y_validation, pred_validation)

mae_train = mean_absolute_error(Y_train, pred_train)
mae_validation = mean_absolute_error(Y_validation, pred_validation)

r2_train = r2_score(Y_train, pred_train)
r2_validation = r2_score(Y_validation, pred_validation)

print('mse_train', mse_train)
print('mae_train', mae_train)
print('r2_train', r2_train)
print('\n')
print('mse_validation', mse_validation)
print('mae_validation', mae_validation)
print('r2_validation', r2_validation)

예측 데이터 그래프로 시각화

import matplotlib.pyplot as plt

plt.figure(figsize=(10, 6))
plt.plot(np.array(Y_validation), label='Actual')
plt.plot(pred_validation, label='Predicted', linestyle='--')
plt.xlabel('Sample Index')
plt.ylabel('Value')
plt.title('Actual vs Predicted')
plt.legend()
plt.show()

 

 

 

9. 모델 선정해 최적의 매개변수 찾기(아직은 모델을 정하기 못함.. 코드만 일단 짜둠)

#Xgboost가 더 잘나옴 최적의 파라미터 찾아보자
from sklearn.model_selection import GridSearchCV
import xgboost as xgb
model = xgb.XGBClassifier(random_state=11)
#help(xgb.XGBClassifier(random_state=11))
parameters = {
    'n_estimators':[35,40,45],
    'max_depth':[7,8,10,11,12]
}

gridsh = GridSearchCV(model, parameters, cv = 5)
gridsh.fit(X_train_sc, Y_train)
print('최적의 매개변수', gridsh.best_params_)

 

 

10. 이제 1시간뒤의 가격을 예측하는 코드

# 데이터 에서 가장 최신의 시간을 가져온다
predit_df = df.iloc[-1,0]

# 10분을 더한 Timestamp 객체 생성
predit_df = predit_df + pd.Timedelta(minutes=60)
predit_df

# 데이터 프레임으로 만들어준다
predit_df = {'soldDate': [predit_df]}
predit_df = pd.DataFrame(predit_df)

# 년 컬럼 추가
predit_df['year'] = predit_df['soldDate'].dt.year

# 월 컬럼 추가
predit_df['month'] = predit_df['soldDate'].dt.month

# 일 컬럼 추가
predit_df['day'] = predit_df['soldDate'].dt.day

# 시간 컬럼 추가
predit_df['hour'] = predit_df['soldDate'].dt.hour

# 분 컬럼 추가
predit_df['minute'] = predit_df['soldDate'].dt.minute

# 요일 컬럼 추가해주자
predit_df['day_name'] = predit_df['soldDate'].dt.day_name()

# 필요 없는 컬럼 삭제
predit_df = predit_df.drop(columns = ['soldDate'])

display(predit_df)

# 원핫인코딩 객체를 불러와서 인코딩 시켜주자
# 범주형 열만 선택
obj_df = predit_df.select_dtypes(include='object')

# 숫자형 열만 선택
no_obj_df = predit_df.select_dtypes(exclude='object')

# 범주형 열을 원핫 인코딩
encoded_features = encoder.transform(obj_df)

# 인코딩된 결과를 데이터프레임으로 변환
encoded_df = pd.DataFrame(encoded_features.toarray(), columns=encoder.get_feature_names(obj_df.columns))

# 인코딩된 범주형 열과 숫자형 열을 합침
predit_df = pd.concat([no_obj_df, encoded_df], axis=1)

# 10분뒤 가격을 예측!!!!
pred_ten_min_rf = RFC.predict(predit_df)
pred_ten_min_xb = xgb.predict(predit_df)
pred_ten_min_lm = LGBMR.predict(predit_df)
print('rf:',pred_ten_min_rf)
print('xb:',pred_ten_min_xb)
print('lm:',pred_ten_min_lm)

 

 

 

 

앞선 모델은 머신러닝 앙상블모델로 실습해봄

이제는 딥러닝 모델인 lstm모델을 사용하여 실습을 해보겠습니다!!

 

lstml : rnn의 한종류이며 시퀀스 데이터의 긴 의존성을 학습할 수 있는 능력을 가지고 있어서 이전 정보를 잘 유지하면서 현재 정보를 활용하여 예측이나 분류 작업을 수행할 수 있다!!!

 

 

 

0. 먼저 외부서 가져온 던파 골드 시세 테이블을 로드해 데이터프레임으로 뺴준다 (해당 코드는 [던파 쿠버플로우, 쿠버네티스] 부분에 있습니다.)

import pymysql
import pandas as pd

# 연결 정보 설정
host = "10.103.132.127"
port = 3306
database = "donpa_item"
user = "root"
password = "1234"

# 연결
connection = pymysql.connect(
    host=host,
    port=port,
    user=user,
    password=password,
    database=database
)

# 연결 성공 여부 확인
if connection:
    print("마리아DB에 연결되었습니다.")

# SQL 쿼리
query = "SELECT * FROM goldprice"

# 데이터프레임으로 변환
try:
    date_df = pd.read_sql(query, connection)
except Exception as e:
    print("데이터베이스 작업 중 에러 발생:", e)

# 연결 종료
connection.close()
date_df.tail()

 

 

1. 데이터 불러와  골드세시 피처 추가 간단 전처리, 피처엔지니어링

import pandas as pd
from pymongo import MongoClient

# MongoDB 연결 설정
client = MongoClient("mongodb://3.38.178.84:27017/")
db = client["donpa"]  # 데이터베이스명
collection = db["donpa_data"]  # 컬렉션명

# 컬렉션 데이터 조회
data = collection.find()

# 데이터프레임으로 변환
df = pd.DataFrame(data)

# _id 컬럼은 제거해주자
df = df.drop(columns="_id") 

# 출력
print("데이터의 row수:",len(df))

from datetime import datetime
# object타입의 데이터 datetime타입으로 변경하는 코드
df['now_datetime'] = pd.to_datetime(df['now_datetime'])
# 시간까지만 잘라내기
df['now_datetime'] = df['now_datetime'].dt.strftime("%Y-%m-%d %H:%M")
# now_datetime 다시 datetime타입으로 변경하는 코드
df['now_datetime'] = pd.to_datetime(df['now_datetime'])

# unitPrice 컬럼 float타입으로 변경
df['unitPrice'] = df['unitPrice'].astype('float')

#soldDate 컬럼 인덱스로 변경
df.set_index('now_datetime', inplace=True)
#display(df.head())

# itemName컬럼은 사용하지 안을거임
item_name = df.iloc[0,0] # 지우기전 아이템 이름 저장해주자
df = df.drop(columns= 'itemName')
df = df.reset_index(drop=False)

# 피처 엔지니어링
# 30분 이평선
ma3 = df['unitPrice'].rolling(window=3).mean()
df.insert(len(df.columns), 'ma3', ma3)

# 기존 데이터가 있다면 NaN에 이동평균선 값을 채워넣어주는 방법
# 기존 데이터가 없다면 NaN에 0 값을 채워줘야 함
df = df.fillna(0)

# unitPrice 컬럼 float타입으로 변경
df['unitPrice'] = df['unitPrice'].astype('float')

# sell, buy컬럼을 합쳐주기 위해 date컬럼 생성
df['date'] = pd.to_datetime(df['now_datetime']).dt.strftime('%Y%m%d')

# sell, buy컬럼 붙여주자!!
df = df.merge(date_df, left_on='date', right_on='date', how='left')

# sell, buy값이 널값이면 가장 최근의 sell, buy값으로 대체해주자
null_check = df['sell'].isnull().sum()
if null_check != 0:
    # date_df의 맨 마지막 값을 가져와서 NaN 값을 채우기
    last_date_df_row = date_df.iloc[-1]
    df['sell'].fillna(last_date_df_row['sell'], inplace=True)
    df['buy'].fillna(last_date_df_row['buy'], inplace=True)

# 붙여주고 date는 이제 필요없으므로 drop시켜줌
df.drop(columns = 'date', inplace=True)

#df.info()
df

 

2. lstm을 이용해 unitPrice를 예측하는 것을 목표로

나중에 예측값과 실제값을 비교하기 위해 따로 뗴어 저장하자, 그래프 그리기 위해 날짜도 따로 저장하자

# 실제 값
original_open = df['unitPrice'].values

# 날짜 값
dates = pd.to_datetime(df['soldDate'])

-----------------------------------------------------

# 사용할 컬럼만 가져오기
cols = list(df)[1:]

# 데이터타입 float로 변경
df = df[cols].astype(float)
df.info()

 

 

 

3. lstm 활성 함수가 tanh와 sigmoid이므로 다음과 같이 학습용 데이터 정규화 해야됨

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
scaler = scaler.fit(df)
df_scaler = scaler.transform(df)
# 앞에 5개만 확인하기
df_scaler[:5]

 

 

 

4. 학습용 테스트 데이터 9대1비율로 나눈다

n_train = int(0.9*df_scaler.shape[0]) # 90퍼 비율
train_data_scaled = df_scaler[:n_train] # train 데이터
train_dates = dates[:n_train] # train 날짜

test_data_scaled = df_scaler[n_train:] # test 데이터
test_dates = dates[n_train:] # test 날짜
test_data_scaled

 

 

 

5. 직전 24개의 데이터를 기반으로 10분뒤 가격을 예측하는 것을 목표

데이터 구조를 lstm의 입력과 출력에 맞게 바꿔주자

import numpy as np
pred_days = 1
seq_len = 24
input_dim = 4

X_train = []
Y_train = []
X_test = []
Y_test = []

for i in range(seq_len, n_train-pred_days +1):
    X_train.append(train_data_scaled[i - seq_len:i, 0:train_data_scaled.shape[1]])
    Y_train.append(train_data_scaled[i + pred_days - 1:i + pred_days, 0])

for i in range(seq_len, len(test_data_scaled)-pred_days +1):
    X_test.append(test_data_scaled[i - seq_len:i, 0:test_data_scaled.shape[1]])
    Y_test.append(test_data_scaled[i + pred_days - 1:i + pred_days, 0])

X_train, Y_train = np.array(X_train), np.array(Y_train)
X_test, Y_test = np.array(X_test), np.array(Y_test)

 

 

6. lstm모델

# TensorFlow에서 Keras 모듈을 불러옵니다
import tensorflow as tf
# 레이어를 선형으로 쌓아 순차적으로 연결하여 모델을 만드는 방식
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense

# 나머지 모델 구성 및 학습 코드를 이어서 작성하세요


model = Sequential()
model.add(LSTM(64, input_shape=(X_train.shape[1], X_train.shape[2]), # (seq length, input dimension)
               return_sequences=True))
model.add(LSTM(32, return_sequences=False))
model.add(Dense(Y_train.shape[1]))

 

 

7. 모델 컴파일

모델 피팅

from tensorflow.keras.optimizers import Adam

# specify your learning rate
learning_rate = 0.01
# create an Adam optimizer with the specified learning rate
optimizer = Adam(learning_rate=learning_rate)
# compile your model using the custom optimizer
model.compile(optimizer=optimizer, loss='mse')

# 모델 피팅
history = model.fit(X_train, Y_train, epochs=30, batch_size=32,
                    validation_split=0.1, verbose=1)

 

 

8. 모델 예측

# prediction
prediction = model.predict(X_test)
print(prediction.shape, X_test.shape)

# generate array filled with means for prediction
mean_values_pred = np.repeat(scaler.mean_[np.newaxis, :], prediction.shape[0], axis=0)

# substitute predictions into the first column
mean_values_pred[:, 0] = np.squeeze(prediction)

# inverse transform
y_pred = scaler.inverse_transform(mean_values_pred)[:,0]
print(y_pred.shape)

# generate array filled with means for testY
mean_values_testY = np.repeat(scaler.mean_[np.newaxis, :], Y_test.shape[0], axis=0)

# substitute testY into the first column
mean_values_testY[:, 0] = np.squeeze(Y_test)

# inverse transform
testY_original = scaler.inverse_transform(mean_values_testY)[:,0]
print(testY_original.shape)

import matplotlib.pyplot as plt


# plotting
plt.figure(figsize=(80, 60))

# plot original 'Open' prices
plt.plot(dates, original_open, color='green', label='Original Open Price')

# plot actual vs predicted
plt.plot(test_dates[seq_len:], testY_original, color='blue', label='Actual Open Price')
plt.plot(test_dates[seq_len:], y_pred, color='red', linestyle='--', label='Predicted Open Price')
plt.xlabel('Date')
plt.ylabel('Open Price')
plt.title('Original, Actual and Predicted Open Price')
plt.legend()
plt.show()

 

 

 

9. 마지막 데이터를 기준으로 1시간 뒤 가격 예측하기

# 마지막 데이터에 대한 예측을 위한 입력 데이터 준비
last_input = df_scaler[-seq_len:]

# 하나만 예측하므로 배치크기는 1
last_input = last_input.reshape(1, seq_len, input_dim)

# 10분 뒤의 unitPrice 예측
predicted_unitPrice = model.predict(last_input)

# 스케일링을 원래 데이터 범위로 되돌리기
predicted_unitPrice = scaler.inverse_transform(np.array([[predicted_unitPrice[0][0], 0]]))[0][0]

# 예측 결과 출력
print("10분 뒤의 예측된 unitPrice:", predicted_unitPrice)

 

 

던파 아바타

1. 추가해줄 골드 시세 데이터 가져오기

import pymysql
import pandas as pd

# 연결 정보 설정
host = "10.103.132.127"
port = 3306
database = "donpa_item"
user = "root"
password = "1234"

# 연결
connection = pymysql.connect(
    host=host,
    port=port,
    user=user,
    password=password,
    database=database
)


# SQL 쿼리
query = "SELECT * FROM goldprice"

# 데이터프레임으로 변환
date_df = pd.read_sql(query, connection)

# 연결 종료
connection.close
date_df.head()

 

 

2. 수집중인 레어 아바타 데이터 불러오기

import pandas as pd
from pymongo import MongoClient

# MongoDB 연결 설정
client = MongoClient("mongodb://3.38.178.84:27017/")
db = client["donpa"]  # 데이터베이스명
collection = db["donpa_aabata_rare"]  # 컬렉션명

# 컬렉션 데이터 조회
data = collection.find()

# 데이터프레임으로 변환
df = pd.DataFrame(data)

# _id 컬럼은 제거해주자
df = df.drop(columns="_id") 

df['price'] = df['price'].astype('float')

df.info()
df.head()

 

 

3. 피처 엔지니어링

df['soldDate'] = df['soldDate'].str.replace('-','')

# sell, buy컬럼 붙여주자!!
df = df.merge(date_df, left_on='soldDate', right_on='date', how='inner')

# date컬럼 삭제해주자
df.drop(columns = 'date', inplace=True)

from datetime import datetime
df['soldDate'] = pd.to_datetime(df['soldDate'])

# 년 컬럼 추가
df['year'] = df['soldDate'].dt.year

# 월 컬럼 추가
df['month'] = df['soldDate'].dt.month

# 일 컬럼 추가
df['day'] = df['soldDate'].dt.day

# 요일 컬럼 추가해주자
df['day_name'] = df['soldDate'].dt.day_name()

# 필요 없는 컬럼 삭제
df.drop(columns = 'soldDate', inplace=True)
# ava_rit도 어차피다 레어이니까 삭제
df.drop(columns = 'ava_rit', inplace=True)

# 타겟 컬러 맨뒤로 보내기
price_column = df.pop('price')
df['price'] = price_column
df.head()

 

4. 타겟값 분리해주자

X_train = df.drop(columns = 'price')
y_train = df['price']

display(X_train.head())
y_train.head()

 

 

5. 왜도 있는지 확인( 보통 절대값이 1이 넘어가면 왜도가 있다고 판단 로그변환 ㄱㄱ)

from scipy.stats import skew

# 왜도 있는 컬럼 모은 리스트
log_list = [] 

# 수치형 컬럼들만 돌려야됨
for i in X_train.select_dtypes(exclude='object').columns:
    skewness = skew(X_train[i])
    
    # 절대값이 1이 넘어가면 왜도가 있다고 판단
    if abs(skewness) >= 1:
        log_list.append(i)

print(log_list)

# 왜도 있는 컬럼들만 로그변환을 해주자
import numpy as np
for i in log_list:
    if X_train[i].min() < 0:
        X_train[i] = X_train.map(lambda x : x+abs(X_train[i].min()))
    X_train[i] = np.log1p(X_train[i])

X_train.head()

 

 

6. 데이터를 분할하자 학습용8, 테스트2

from sklearn.model_selection import train_test_split
X_train, X_validation, Y_train, Y_validation = train_test_split(X_train,y_train, test_size=0.2, random_state=1)

print(X_train.shape, X_validation.shape, Y_train.shape, Y_validation.shape)
X_train.reset_index(drop=True, inplace=True)
X_validation.reset_index(drop=True, inplace=True)

 

 

7. 수치형 데이터 standardscaler해주자

obj_col = X_train.select_dtypes(include='object').columns

from sklearn.preprocessing import StandardScaler
sds = StandardScaler()
sds.fit(X_train.drop(columns = obj_col))

X_train_sc = sds.transform(X_train.drop(columns = obj_col))
X_train_sc = pd.DataFrame(X_train_sc, columns = X_train.drop(columns = obj_col).columns)

X_validation_sc = sds.transform(X_validation.drop(columns = obj_col))
X_validation_sc = pd.DataFrame(X_validation_sc, columns = X_validation.drop(columns = obj_col).columns)


# object 타입 컬럼 붙여주기
for i in obj_col:
    X_train_sc[i] = X_train[i]
    X_validation_sc[i] = X_validation[i]
    
# 스케일러 객체 저장
#import joblib

#joblib.dump(sds, '/home/cloudcccr3/scaler/scaler.pkl')

X_train_sc.head()

 

 

8. 원핫 인코딩 돌려주자

from sklearn.preprocessing import OneHotEncoder
import joblib

# OneHotEncoder 객체 생성
encoder = OneHotEncoder()

X_full = pd.concat([X_train_sc, X_validation_sc])

# 범주형 열만 선택
obj_df = X_full.select_dtypes(include='object')

# 숫자형 열만 선택
no_obj_df = X_full.select_dtypes(exclude='object')

# 범주형 열을 원핫 인코딩
encoded_features = encoder.fit_transform(obj_df)

# 인코딩된 결과를 데이터프레임으로 변환
encoded_df = pd.DataFrame(encoded_features.toarray(), columns=encoder.get_feature_names(obj_df.columns))

# 인코딩된 범주형 열과 숫자형 열을 합침
X_train_sc_ec = pd.concat([no_obj_df[:len(X_train_sc)] , encoded_df[:len(X_train_sc)]], axis = 1)
X_validation_sc_ec = pd.concat([no_obj_df[len(X_train_sc):] , encoded_df[len(X_train_sc):].reset_index(drop=True)], axis = 1)

# 인코딩 객체 저장
#joblib.dump(encoder, '/home/cloudcccr3/encoder/encoder.pkl')

X_train_sc_ec.head()

 

 

9. VIF로 다중공선성을 평가 보통 10이상이면 있다고 판단

!pip install statsmodels
import pandas as pd
from statsmodels.stats.outliers_influence import variance_inflation_factor

def calculate_vif(data_frame):
    vif_data = pd.DataFrame()
    vif_data["Variable"] = data_frame.columns
    vif_data["VIF"] = [variance_inflation_factor(data_frame.values, i) for i in range(data_frame.shape[1])]
    return vif_data

vif_values = calculate_vif(X_train_sc_ec.iloc[:,:5])
vif_values

 

10. 피처 특수문자 지워주기

import re

# 데이터프레임의 컬럼 이름에서 특수 문자를 제거하고 변경할 새로운 컬럼 이름 리스트 생성
new_columns = []
for old_column in X_train_sc_ec.columns:
    new_column = re.sub(r'[^\w\s]', '', old_column)  # 특수 문자 제거
    new_columns.append(new_column)

# 컬럼 이름을 새로운 이름으로 설정
X_train_sc_ec.columns = new_columns
X_train_sc_ec.head()

 

11. 랜포

from sklearn.ensemble import RandomForestRegressor
RFC = RandomForestRegressor(random_state=10)
RFC.fit(X_train_sc_ec, Y_train)

# 모델 저장
import joblib

# 모델을 파일로 저장
# joblib.dump(RFC, '/home/cloudcccr3/modelsave/rf_model.pkl')
joblib.dump(RFC, 'rf_model.pkl')

pred_train = RFC.predict(X_train_sc_ec)
pred_validation = RFC.predict(X_validation_sc_ec)

# 성능평가
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
mse_train = mean_squared_error(Y_train, pred_train)
mse_validation = mean_squared_error(Y_validation, pred_validation)

mae_train = mean_absolute_error(Y_train, pred_train)
mae_validation = mean_absolute_error(Y_validation, pred_validation)

r2_train = r2_score(Y_train, pred_train)
r2_validation = r2_score(Y_validation, pred_validation)

print('mse_train',mse_train)
print('mae_train',mae_train)
print('r2_train',r2_train)
print('\n')
print('mse_validation',mse_validation)
print('mae_validation',mae_validation)
print('r2_validation',r2_validation)

 

12. xgboost

import xgboost as xgb
xgb = xgb.XGBRegressor(random_state=10)
xgb.fit(X_train_sc_ec, Y_train)

# 모델 저장
import joblib

# 모델을 파일로 저장
# joblib.dump(RFC, '/home/cloudcccr3/modelsave/rf_model.pkl')
joblib.dump(xgb, 'xg_model.pkl')

pred_train = xgb.predict(X_train_sc_ec)
pred_validation = xgb.predict(X_validation_sc_ec)

# 성능평가
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
mse_train = mean_squared_error(Y_train, pred_train)
mse_validation = mean_squared_error(Y_validation, pred_validation)

mae_train = mean_absolute_error(Y_train, pred_train)
mae_validation = mean_absolute_error(Y_validation, pred_validation)

r2_train = r2_score(Y_train, pred_train)
r2_validation = r2_score(Y_validation, pred_validation)

print('mse_train',mse_train)
print('mae_train',mae_train)
print('r2_train',r2_train)
print('\n')
print('mse_validation',mse_validation)
print('mae_validation',mae_validation)
print('r2_validation',r2_validation)