Post

현대자동차 가격 예측 실습

현대자동차 가격 예측 실습

실습2. 현대자동차 가격 예측

230916

  • 데이터로드 및 확인
  • EDA(sweetbiz사용)
  • 가공데이터 저장
  • 모델링(선형회귀, 결정트리, KNN 알고리즘적용)
    • 학습단계, 예측단계
  • 평가척도 작성
  • 최적의 모델 찾기

## 데이터 로드 및 확인

1
2
3
4
5
6
7
8
9
import pandas as pd

#데이터 로드 -> 커널 : venv
train_df = pd.read_csv('./data/train.csv')
test_df = pd.read_csv('./data/test.csv')

train_df.head()
train_df.info()
train_df.describe()

EDA

  • Sweetbiz로 결측치, 중복값, 피처와 레이블 관계성 확인 ```python import pandas as pd import sweetviz as sv

경고메세지 끄기

import warnings warnings.filterwarnings(action=’ignore’) sv.config_parser.read_string(“[General]\nuse_cjk_font=1”)

df_train = pd.read_csv(‘./data/train.csv’) df_test = pd.read_csv(‘./data/test.csv’)

compare_report = sv.compare([df_train,’Train’],[df_test,’Test’],target_feat=’가격’) compare_report.show_html(r’./image/EDA_Report.html’) #image폴더만들기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- boxplot으로 이상치 확인
```python
# 이상치 확인
import matplotlib.pyplot as plt

plt.figure(figsize=(15, 6))
plt.rc('font', family = "Malgun Gothic") #한글사용
plt.rcParams['axes.unicode_minus']=False #마이너스 부호 깨짐

plt.subplot(1, 2, 1)                
train_df.boxplot()
plt.title('Train')  

plt.subplot(1, 2, 2)             
test_df.boxplot()
plt.title('Test')   

plt.tight_layout()
plt.show()
  • head(), info()으로 데이터 타입 확인하여 인코딩 여부 파악

EDA 결론

1
2
3
4
5
6
7
8
9
10
1.결측치 : 미존재
2.중복값 : Train_df 중복값 1개 존재
3.이상치 : 가격 존재
    - 가격 : 적은 수이므로 잠정적으로 수용하는 것으로 판단
    - 년식, 마력, 하이브리드, 배기량 : 범주형이기 때문에 이상치 X
4.인코딩
    - 종류, 연료, 변속기 인코딩 필요(문자형) => 인코딩 필요
    - 년식, 하이브리드(범주형) => 인코딩 일단 대기
5.Feature & Label Associations(피처와 레이블 관계성) : 가격이 레이블 / 나머지는 피처 => heatmap분석 확인해보니 관계성이 있음 => 학습은 가능할 듯
5.스케일링: 아직모름

1차 데이터 가공 후 저장

train_df.to_csv('./data/train_pre.csv', index=False)

알고리즘(선형회귀모델)

학습단계

1
2
3
4
5
6
7
8
9
10
11
12
13
7. 모델평가 (회귀모델 평가지표)
from sklearn.metrics import r2_score
from sklearn.metrics import mean_squared_error
from sklearn.metrics import mean_absolute_error
from sklearn.metrics import mean_squared_log_error

def evaluate_reg_all(y_test, y_predict):
    MSE = mean_squared_error(y_test,y_predict,squared=True)
    RMSE = mean_squared_error(y_test,y_predict,squared=False)
    MAE = mean_absolute_error(y_test,y_predict)
    R2 = r2_score(y_test,y_predict)
    
    print(f'MSE: {MSE:.3f}, RMSE: {RMSE:.3F}, MAE: {MAE:.3F}, R^2: {R2:.3F}')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import pandas as pd
from sklearn.preprocessing import OneHotEncoder
from sklearn.model_selection import train_test_split
from sklearn.compose import make_column_transformer
from sklearn.linear_model import LinearRegression
# 경고메세지 끄기
import warnings
warnings.filterwarnings(action='ignore')

1. 데이터 로드
train_df = pd.read_csv('./data/train_pre.csv') # 가공데이터
test_df = pd.read_csv('./data/test.csv')

2. 데이터 분석
앞서 완료

3. 데이터 전처리
- 중복제거 : 앞서 완료
- 데이터 분할
y_train_df = train_df['가격'] # 레이블
x_train_df = train_df.drop(['가격'],axis=1) # 피처들

y_test_df = test_df['가격'] # 레이블
x_test_df = test_df.drop(['가격'],axis=1) # 피처들

- 인코딩
transformer = make_column_transformer(
    (OneHotEncoder(), ['종류','연료','변속기']),
    remainder='passthrough')

transformer.fit(x_train_df) # 훈련데이터 넣기

x_train = transformer.transform(x_train_df) #트랜스포머의 transform() 함수는 결과를 넘파이 배열로 리턴 => 아직 fit 아님
x_test = transformer.transform(x_test_df) # 테스트 데이터는 transform만 진행. fitting하면 안됨

4. 모델 생성
model = LinearRegression()

5. 모델 학습
model.fit(x_train,y_train_df) # 피처와 레이블 들어감

6. 모델 검증
print(f'훈련_R2: {model.score(x_train, y_train_df)}') 
print(f'테스트_R2: {model.score(x_test, y_test_df)}')

7. 모델 평가 (회귀모델 평가지표 출력)
y_predict = model.predict(x_test) ## 주의: 테스트 데이터에 대해 평가해야함!
evaluate_reg_all(y_test_df,y_predict)

예측 단계

1
2
3
4
5
6
7
8
9
10
11
12
1. 신규데이터 수집
x_real = [
    [2015, '대형', 6.8, 159, 23, 'LPG', 0,2359, 1935, '수동']
]
x_real_df = pd.DataFrame(x_real, columns=['년식', '종류', '연비', '마력', '토크', '연료', '하이브리드', '배기량', '중량', '변속기'])

2. 인코딩 => 예측을 진행하기전에 동일한 전처리(같은 인코딩 객체) 작업 필요
x = transformer.transform(x_real_df)

3. 결과값
y_real_predict = model.predict(x)
print(f'예측값: {y_real_predict[0]}') # [0]:인덱싱으로 결과값만 출력

+ 직접 transform 안하고 내부적으로 transform 진행하는 skicit-learn으로 진행하는 방법으로 구현 => 파이프라인 사용
위 코드(선형회귀모델)에서 수정할 부분들 참고

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from sklearn.pipeline import make_pipeline

# 학습단계
3. 데이터 전처리
- 인코딩
transformer = make_column_transformer(
    (OneHotEncoder(), ['종류', '연료', '변속기']),
    remainder='passthrough')

4. 모델 생성
#파이프라인을 이용하여 전처리와 모델 순차적으로 실행되도록 함
model = make_pipeline(transformer,LinearRegression())  # 데이터가 transform 먼저한 후에 model에 들어옴

# 예측단계
1. 신규데이터 수집
x_real = [
    [2015, '대형', 6.8, 159, 23, 'LPG', 0,2359, 1935, '수동']
]
x_real_df = pd.DataFrame(x_real, columns=['년식', '종류', '연비', '마력', '토크', '연료', '하이브리드', '배기량', '중량', '변속기'])

2. 인코딩 => 작업 사라짐!!!

3. 결과값
y_real_predict = model.predict(x_real_df)
print(f'예측값: {y_real_predict[0]}') # [0]:인덱싱으로 결과값만 출력

LinearRegression 일때 |R2|MSE|MAE|RMSE| |–|–|–|–| |0.78|1,397,856.93|570.12|1,182.31|

알고리즘(결정트리회귀모델)

학습 단계

1
2
3
4
5
6
7
8
9
10
11
12
from sklearn.metrics import r2_score
from sklearn.metrics import mean_squared_error
from sklearn.metrics import mean_absolute_error
from sklearn.metrics import mean_squared_log_error

def evaluate_reg_all(y_test, y_predict):
    MSE = mean_squared_error(y_test,y_predict,squared=True)
    RMSE = mean_squared_error(y_test,y_predict,squared=False)
    MAE = mean_absolute_error(y_test,y_predict)
    R2 = r2_score(y_test,y_predict)
    
    print(f'MSE: {MSE:.3f}, RMSE: {RMSE:.3F}, MAE: {MAE:.3F}, R^2: {R2:.3F}')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import pandas as pd
import numpy as np
from sklearn.preprocessing import OneHotEncoder
from sklearn.compose import make_column_transformer
from sklearn.tree import DecisionTreeRegressor
from sklearn.pipeline import make_pipeline
# 경고메세지 끄기
import warnings
warnings.filterwarnings(action='ignore')

1. 데이터 로드
train_df = pd.read_csv('./data/train_pre.csv')
test_df = pd.read_csv('./data/test.csv')

2. 데이터 분석

3. 데이터 전처리

- 데이터 분할
x_train = train_df.drop(['가격'], axis=1)
x_test = test_df.drop(['가격'], axis=1)
y_train = train_df['가격']
y_test = test_df['가격']

- 인코딩
transformer = make_column_transformer(
    (OneHotEncoder(), ['종류', '연료', '변속기']),
    remainder='passthrough')

4. 모델 생성
#파이프라인을 이용하여 전처리와 모델 순차적으로 실행되도록 함
model = make_pipeline(transformer,DecisionTreeRegressor(random_state=43, max_depth=5)) # 3 했을 때는 훈련_R2과 테스트_R2의 격차가 크기 때문에 5

5. 모델 학습
model.fit(x_train, y_train)

6. 모델 검증
print(f'훈련_R2: {model.score(x_train, y_train)}') 
print(f'테스트_R2: {model.score(x_test, y_test)}') 

7. 모델 평가 (회귀모델 평가지표 출력)
y_predict = model.predict(x_test) ## 주의: 테스트 데이터에 대해 평가해야함!
evaluate_reg_all(y_test,y_predict)

예측 단계

1
2
3
4
5
6
7
8
9
10
11
1. 신규 데이터 수집
x_real = np.array([
    [2015, '대형', 6.8, 159, 23, 'LPG', 0,2359, 1935, '수동']
])

x_real_df = pd.DataFrame(x_real, columns=['년식', '종류', '연비', '마력', '토크', '연료', '하이브리드', '배기량', '중량', '변속기'])

2. 파이프라인으로 인코딩 없이 결과 도출
y_predict = model.predict(x_real_df)

print(f'예측값: {y_predict[0]}')

DecisionTreeRegressor(random_state=43,max_depth=5) 일때 |R2|MSE|MAE|RMSE| |–|–|–|–| |0.91|549,241.38|367.62|741.11|

DecisionTreeRegressor(random_state=43,max_depth=3) 일때 |R2|MSE|MAE|RMSE| |–|–|–|–| |0.89|658,201.49|471.22|811.30|

알고리즘(k최근접이웃모델)

학습 단계

1
2
3
4
5
6
7
8
9
10
11
12
from sklearn.metrics import r2_score
from sklearn.metrics import mean_squared_error
from sklearn.metrics import mean_absolute_error
from sklearn.metrics import mean_squared_log_error

def evaluate_reg_all(y_test, y_predict):
    MSE = mean_squared_error(y_test,y_predict,squared=True)
    RMSE = mean_squared_error(y_test,y_predict,squared=False)
    MAE = mean_absolute_error(y_test,y_predict)
    R2 = r2_score(y_test,y_predict)
    
    print(f'MSE: {MSE:.3f}, RMSE: {RMSE:.3F}, MAE: {MAE:.3F}, R^2: {R2:.3F}')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import pandas as pd
import numpy as np
from sklearn.preprocessing import OneHotEncoder
from sklearn.compose import make_column_transformer
from sklearn.neighbors import KNeighborsRegressor
from sklearn.pipeline import make_pipeline
# 경고메세지 끄기
import warnings
warnings.filterwarnings(action='ignore')

# 학습단계
1. 데이터 로드
train_df = pd.read_csv('./data/train_pre.csv')
test_df = pd.read_csv('./data/test.csv')

2. 데이터 분석

3. 데이터 전처리

- 데이터 분할
x_train = train_df.drop(['가격'], axis=1)
x_test = test_df.drop(['가격'], axis=1)
y_train = train_df['가격']
y_test = test_df['가격']

- 인코딩
transformer = make_column_transformer(
    (OneHotEncoder(), ['종류', '연료', '변속기']),
    remainder='passthrough')

4. 모델 생성
#파이프라인을 이용하여 전처리와 모델 순차적으로 실행되도록 함
model = make_pipeline(transformer,KNeighborsRegressor(n_neighbors=3))  # 무작정 default = 1로 하면 성능이 overdefault =5 를 지점으로 +- 범위 정하기

5. 모델 학습
model.fit(x_train, y_train)

6. 모델 검증
print(f'훈련_R2: {model.score(x_train, y_train)}') 
print(f'테스트_R2: {model.score(x_test, y_test)}') 

7. 모델 평가 (회귀모델 평가지표 출력)
y_predict = model.predict(x_test) ## 주의: 테스트 데이터에 대해 평가해야함!
evaluate_reg_all(y_test,y_predict)

예측 단계

1
2
3
4
5
6
7
8
9
10
1. 신규 데이터 수집
x_real = np.array([
    [2015, '대형', 6.8, 159, 23, 'LPG', 0,2359, 1935, '수동']
])

x_real_df = pd.DataFrame(x_real, columns=['년식', '종류', '연비', '마력', '토크', '연료', '하이브리드', '배기량', '중량', '변속기'])

2. 파이프라인으로 인코딩 없이 결과 도출
y_predict = model.predict(x_real_df)
print(f'예측값: {y_predict[0]}')

KNeighborsRegressor(n_neighbors=5) 일때 |R2|MSE|MAE|RMSE| |–|–|–|–| |0.59|2,547,216.63|585.21|1,596.00|

KNeighborsRegressor(n_neighbors=3) 일때 |R2|MSE|MAE|RMSE| |–|–|–|–| |0.70|1,841,414.62|493.55|1,356.99|

최적의 모델은?

선형회귀, 결정트리, KNN 알고리즘 중 최적의 모델은 R2이 가장 높은 결정트리

This post is licensed under CC BY 4.0 by the author.