Predict farm-product prices [KOR]
2021 농산물 가격예측 AI 경진대회
목적
기존 농산물유통 종합정보시스템의 농산물 가격 예측 모형을 개선할 수 있는 새로운 아이디어와 알고리즘을 탐색
문제 접근
- train.csv (2016.01.01 부터 2020.09.28 까지의 21가지 농산물 가격, 거래량 데이터)를 가지고 가격 예측 모델을 생성한다.
- test_files 안에 있는 2020.09.29 부터 2020.11.05 까지의 데이터로 2020년 10월 6일(화) ~ 2020년 11월 12일(목) 기간 내 품목별 1주, 2주, 4주 후 가격을 예측해 leaderboard에서 최종평가전 모델의 public score 확인 가능
- 최종 평가 요소 : 2021년 10월 5일(화) ~ 2021년 11월 11일(목) 기간 내 품목별 1주, 2주, 4주 후 가격을 예측. private score
목록
데이터 전처리
- 데이터 설명
- 데이터 정제
데이터 탐색
- 상관관계 분석
- 다양한 기준별 데이터 분석
신경망을 사용한 예측
- 모델을 생성 하기 위한 전처리
- 모델 생성(LSTM, GRU)
- 예측 방법 개선 (농산물 개별 예측)
- 결과 저장
# 전처리 라이브러리
import pandas as pd
import numpy as np
# 동적 시각화 라이브러리 (동적효과를 위해 plotly 사용)
import plotly.offline as pyo
import plotly.express as px
import plotly.graph_objects as go
# 정적 시각화 라이브러리
import matplotlib.pyplot as plt
import seaborn as sns
# sklearn
from sklearn.model_selection import KFold
from sklearn.metrics import mean_absolute_error, mean_squared_error
from sklearn.model_selection import TimeSeriesSplit
# 머신러닝 / 딥러닝
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, SimpleRNN, LSTM, GRU, Dropout, Flatten, Activation
from tensorflow.keras.optimizers import SGD, RMSprop, Adam
from tensorflow.keras.callbacks import EarlyStopping
from sklearn.metrics import r2_score
# 한글 깨짐 방지
plt.rc('font', family='malgun gothic')
plt.rcParams['axes.unicode_minus'] = False
pd.set_option('max_column', None)
pd.options.display.float_format = '{:.1f}'.format
1. 데이터 전처리¶
1.1 데이터 설명¶
- products.csv : 2016.01.01 부터 2020.11.05 까지의 농산물 거래량과 가격 데이터.
※※※ EDA는 train.csv와 test_files를 합쳐서 products.csv를 만들어 진행했다. 후에 모델 생성은 train.csv로만 하고 test_files는 leaderboard의 성능 평가 용으로 썼다. - 배추, 무, 양파, 건고추, 마늘, 대파, 얼갈이배추, 양배추, 깻잎, 시금치, 미나리, 당근, 파프리카, 새송이, 팽이버섯, 토마토, 청상추, 백다다기, 애호박, 캠벨얼리, 샤인마스캇 - 총 21개 농산물
products = pd.read_csv('data/public_data/products.csv')
products.head()
date | 요일 | 배추_거래량(kg) | 배추_가격(원/kg) | 무_거래량(kg) | 무_가격(원/kg) | 양파_거래량(kg) | 양파_가격(원/kg) | 건고추_거래량(kg) | 건고추_가격(원/kg) | 마늘_거래량(kg) | 마늘_가격(원/kg) | 대파_거래량(kg) | 대파_가격(원/kg) | 얼갈이배추_거래량(kg) | 얼갈이배추_가격(원/kg) | 양배추_거래량(kg) | 양배추_가격(원/kg) | 깻잎_거래량(kg) | 깻잎_가격(원/kg) | 시금치_거래량(kg) | 시금치_가격(원/kg) | 미나리_거래량(kg) | 미나리_가격(원/kg) | 당근_거래량(kg) | 당근_가격(원/kg) | 파프리카_거래량(kg) | 파프리카_가격(원/kg) | 새송이_거래량(kg) | 새송이_가격(원/kg) | 팽이버섯_거래량(kg) | 팽이버섯_가격(원/kg) | 토마토_거래량(kg) | 토마토_가격(원/kg) | 청상추_거래량(kg) | 청상추_가격(원/kg) | 백다다기_거래량(kg) | 백다다기_가격(원/kg) | 애호박_거래량(kg) | 애호박_가격(원/kg) | 캠벨얼리_거래량(kg) | 캠벨얼리_가격(원/kg) | 샤인마스캇_거래량(kg) | 샤인마스캇_가격(원/kg) | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 2016-01-01 | 금요일 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
1 | 2016-01-02 | 토요일 | 80860.0 | 329.0 | 80272.0 | 360.0 | 122787.5 | 1281.0 | 3.0 | 11000.0 | 15019.0 | 5475.0 | 92334.0 | 1704.0 | 6359.0 | 1331.0 | 40028.0 | 348.0 | 4374.9 | 13242.0 | 16550.5 | 2339.0 | 10528.0 | 1729.0 | 13885.0 | 804.0 | 3853.0 | 3703.0 | 15797.0 | 2576.0 | 14634.0 | 1474.0 | 30950.0 | 1621.0 | 5125.0 | 9235.0 | 434.0 | 2109.0 | 19159.0 | 2414.0 | 880.0 | 2014.0 | 0.0 | 0.0 |
2 | 2016-01-03 | 일요일 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
3 | 2016-01-04 | 월요일 | 1422742.5 | 478.0 | 1699653.7 | 382.0 | 2315079.0 | 1235.0 | 699.0 | 4464.0 | 141638.0 | 5210.0 | 994328.1 | 1716.0 | 262615.5 | 1212.0 | 1074699.1 | 345.0 | 122613.5 | 9923.0 | 427435.1 | 2153.0 | 82113.5 | 3960.0 | 558950.2 | 794.0 | 104930.3 | 4871.0 | 277326.5 | 2440.0 | 159800.0 | 1750.0 | 291057.0 | 1834.0 | 38525.5 | 7631.0 | 500702.0 | 2046.0 | 620539.0 | 2018.0 | 2703.8 | 3885.0 | 0.0 | 0.0 |
4 | 2016-01-05 | 화요일 | 1167241.0 | 442.0 | 1423482.3 | 422.0 | 2092960.1 | 1213.0 | 1112.6 | 4342.0 | 126207.8 | 5387.0 | 787716.0 | 1715.0 | 221850.5 | 1197.0 | 825681.9 | 350.0 | 79055.9 | 9529.0 | 334636.8 | 2220.0 | 80144.0 | 3333.0 | 444353.7 | 763.0 | 100699.5 | 5129.0 | 218465.2 | 2437.0 | 153084.0 | 1822.0 | 194626.5 | 1833.0 | 32615.0 | 6926.0 | 147638.0 | 2268.0 | 231958.0 | 2178.0 | 8810.0 | 2853.0 | 0.0 | 0.0 |
1.2 데이터 정제¶
products.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 1771 entries, 0 to 1770 Data columns (total 44 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 date 1771 non-null object 1 요일 1771 non-null object 2 배추_거래량(kg) 1771 non-null float64 3 배추_가격(원/kg) 1771 non-null float64 4 무_거래량(kg) 1771 non-null float64 5 무_가격(원/kg) 1771 non-null float64 6 양파_거래량(kg) 1771 non-null float64 7 양파_가격(원/kg) 1771 non-null float64 8 건고추_거래량(kg) 1771 non-null float64 9 건고추_가격(원/kg) 1771 non-null float64 10 마늘_거래량(kg) 1771 non-null float64 11 마늘_가격(원/kg) 1771 non-null float64 12 대파_거래량(kg) 1771 non-null float64 13 대파_가격(원/kg) 1771 non-null float64 14 얼갈이배추_거래량(kg) 1771 non-null float64 15 얼갈이배추_가격(원/kg) 1771 non-null float64 16 양배추_거래량(kg) 1771 non-null float64 17 양배추_가격(원/kg) 1771 non-null float64 18 깻잎_거래량(kg) 1771 non-null float64 19 깻잎_가격(원/kg) 1771 non-null float64 20 시금치_거래량(kg) 1771 non-null float64 21 시금치_가격(원/kg) 1771 non-null float64 22 미나리_거래량(kg) 1771 non-null float64 23 미나리_가격(원/kg) 1771 non-null float64 24 당근_거래량(kg) 1771 non-null float64 25 당근_가격(원/kg) 1771 non-null float64 26 파프리카_거래량(kg) 1771 non-null float64 27 파프리카_가격(원/kg) 1771 non-null float64 28 새송이_거래량(kg) 1771 non-null float64 29 새송이_가격(원/kg) 1771 non-null float64 30 팽이버섯_거래량(kg) 1771 non-null float64 31 팽이버섯_가격(원/kg) 1771 non-null float64 32 토마토_거래량(kg) 1771 non-null float64 33 토마토_가격(원/kg) 1771 non-null float64 34 청상추_거래량(kg) 1771 non-null float64 35 청상추_가격(원/kg) 1771 non-null float64 36 백다다기_거래량(kg) 1771 non-null float64 37 백다다기_가격(원/kg) 1771 non-null float64 38 애호박_거래량(kg) 1771 non-null float64 39 애호박_가격(원/kg) 1771 non-null float64 40 캠벨얼리_거래량(kg) 1771 non-null float64 41 캠벨얼리_가격(원/kg) 1771 non-null float64 42 샤인마스캇_거래량(kg) 1771 non-null float64 43 샤인마스캇_가격(원/kg) 1771 non-null float64 dtypes: float64(42), object(2) memory usage: 608.9+ KB
date 칼럼의 타입이 object기 때문에, datetime 타입으로 바꿔준다¶
products['date'] = pd.to_datetime(products['date'])
products['date']
0 2016-01-01 1 2016-01-02 2 2016-01-03 3 2016-01-04 4 2016-01-05 ... 1766 2020-11-01 1767 2020-11-02 1768 2020-11-03 1769 2020-11-04 1770 2020-11-05 Name: date, Length: 1771, dtype: datetime64[ns]
cols = products.columns
cols
Index(['date', '요일', '배추_거래량(kg)', '배추_가격(원/kg)', '무_거래량(kg)', '무_가격(원/kg)', '양파_거래량(kg)', '양파_가격(원/kg)', '건고추_거래량(kg)', '건고추_가격(원/kg)', '마늘_거래량(kg)', '마늘_가격(원/kg)', '대파_거래량(kg)', '대파_가격(원/kg)', '얼갈이배추_거래량(kg)', '얼갈이배추_가격(원/kg)', '양배추_거래량(kg)', '양배추_가격(원/kg)', '깻잎_거래량(kg)', '깻잎_가격(원/kg)', '시금치_거래량(kg)', '시금치_가격(원/kg)', '미나리_거래량(kg)', '미나리_가격(원/kg)', '당근_거래량(kg)', '당근_가격(원/kg)', '파프리카_거래량(kg)', '파프리카_가격(원/kg)', '새송이_거래량(kg)', '새송이_가격(원/kg)', '팽이버섯_거래량(kg)', '팽이버섯_가격(원/kg)', '토마토_거래량(kg)', '토마토_가격(원/kg)', '청상추_거래량(kg)', '청상추_가격(원/kg)', '백다다기_거래량(kg)', '백다다기_가격(원/kg)', '애호박_거래량(kg)', '애호박_가격(원/kg)', '캠벨얼리_거래량(kg)', '캠벨얼리_가격(원/kg)', '샤인마스캇_거래량(kg)', '샤인마스캇_가격(원/kg)'], dtype='object')
통계 분석을 진행하기 위해 전체 농산물의 가격과 거래량이 0인 날은 삭제한다¶
# 0 값을 우선 다 NaN로 바꿔준다
products_pure = products.copy()
products_pure = products_pure.replace(0, np.NaN)
# 모든 농산물의 값이 NaN인날은 삭제하기(거래시장이 안열린 날)
products_pure = products_pure.dropna(thresh=3)
products_pure = products_pure.fillna(0)
칼럼명에 띄어쓰기와 단위를 삭제해준다¶
columns = products.columns
imsi = []
for column in columns:
column = column.replace("(", "").replace(")", "").replace("kg", "").replace("_", "").replace("/", "").replace("원", "")
imsi.append(column)
products_pure.columns = imsi
products_pure.head()
date | 요일 | 배추거래량 | 배추가격 | 무거래량 | 무가격 | 양파거래량 | 양파가격 | 건고추거래량 | 건고추가격 | 마늘거래량 | 마늘가격 | 대파거래량 | 대파가격 | 얼갈이배추거래량 | 얼갈이배추가격 | 양배추거래량 | 양배추가격 | 깻잎거래량 | 깻잎가격 | 시금치거래량 | 시금치가격 | 미나리거래량 | 미나리가격 | 당근거래량 | 당근가격 | 파프리카거래량 | 파프리카가격 | 새송이거래량 | 새송이가격 | 팽이버섯거래량 | 팽이버섯가격 | 토마토거래량 | 토마토가격 | 청상추거래량 | 청상추가격 | 백다다기거래량 | 백다다기가격 | 애호박거래량 | 애호박가격 | 캠벨얼리거래량 | 캠벨얼리가격 | 샤인마스캇거래량 | 샤인마스캇가격 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 2016-01-02 | 토요일 | 80860.0 | 329.0 | 80272.0 | 360.0 | 122787.5 | 1281.0 | 3.0 | 11000.0 | 15019.0 | 5475.0 | 92334.0 | 1704.0 | 6359.0 | 1331.0 | 40028.0 | 348.0 | 4374.9 | 13242.0 | 16550.5 | 2339.0 | 10528.0 | 1729.0 | 13885.0 | 804.0 | 3853.0 | 3703.0 | 15797.0 | 2576.0 | 14634.0 | 1474.0 | 30950.0 | 1621.0 | 5125.0 | 9235.0 | 434.0 | 2109.0 | 19159.0 | 2414.0 | 880.0 | 2014.0 | 0.0 | 0.0 |
3 | 2016-01-04 | 월요일 | 1422742.5 | 478.0 | 1699653.7 | 382.0 | 2315079.0 | 1235.0 | 699.0 | 4464.0 | 141638.0 | 5210.0 | 994328.1 | 1716.0 | 262615.5 | 1212.0 | 1074699.1 | 345.0 | 122613.5 | 9923.0 | 427435.1 | 2153.0 | 82113.5 | 3960.0 | 558950.2 | 794.0 | 104930.3 | 4871.0 | 277326.5 | 2440.0 | 159800.0 | 1750.0 | 291057.0 | 1834.0 | 38525.5 | 7631.0 | 500702.0 | 2046.0 | 620539.0 | 2018.0 | 2703.8 | 3885.0 | 0.0 | 0.0 |
4 | 2016-01-05 | 화요일 | 1167241.0 | 442.0 | 1423482.3 | 422.0 | 2092960.1 | 1213.0 | 1112.6 | 4342.0 | 126207.8 | 5387.0 | 787716.0 | 1715.0 | 221850.5 | 1197.0 | 825681.9 | 350.0 | 79055.9 | 9529.0 | 334636.8 | 2220.0 | 80144.0 | 3333.0 | 444353.7 | 763.0 | 100699.5 | 5129.0 | 218465.2 | 2437.0 | 153084.0 | 1822.0 | 194626.5 | 1833.0 | 32615.0 | 6926.0 | 147638.0 | 2268.0 | 231958.0 | 2178.0 | 8810.0 | 2853.0 | 0.0 | 0.0 |
5 | 2016-01-06 | 수요일 | 1045507.5 | 442.0 | 1904372.1 | 409.0 | 1860569.0 | 1263.0 | 1672.0 | 7041.0 | 91531.0 | 5013.0 | 793584.9 | 1620.0 | 199151.0 | 1142.0 | 910812.3 | 327.0 | 78532.8 | 8123.0 | 357749.8 | 2219.0 | 76832.6 | 3133.0 | 396170.4 | 787.0 | 93051.3 | 5120.0 | 187900.4 | 2343.0 | 152693.1 | 1519.0 | 178811.0 | 1999.0 | 31081.4 | 5511.0 | 190011.0 | 2535.0 | 269894.2 | 2503.0 | 7487.0 | 2119.0 | 0.0 | 0.0 |
6 | 2016-01-07 | 목요일 | 1039925.0 | 448.0 | 1438990.2 | 428.0 | 1868011.7 | 1241.0 | 1191.0 | 3908.0 | 349913.8 | 4360.0 | 733312.0 | 1545.0 | 200119.0 | 992.0 | 836339.0 | 315.0 | 75987.7 | 6793.0 | 323944.6 | 2208.0 | 49040.9 | 2259.0 | 241115.0 | 770.0 | 60895.4 | 5095.0 | 181058.6 | 2291.0 | 148757.3 | 1365.0 | 107346.3 | 1921.0 | 27873.6 | 4384.0 | 158516.0 | 2440.0 | 198854.0 | 2533.0 | 4687.8 | 2997.0 | 0.0 | 0.0 |
거래량끼리 가격끼리 각각 모아둔 데이터프레임도 생성한다¶
volume = products_pure.iloc[:, [0,1,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42]]
price = products_pure.iloc[:, [0,1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43]]
2. 데이터 탐색¶
2.1 상관관계 분석¶
농산물의 거래량간의 상관관계와 가격간의 상관관계¶
# 거래량 상관관계
plt.figure(figsize = (14, 8))
volume_corr = volume.corr()
volume_corr = volume_corr.apply(lambda x: round(x ,2))
sns.heatmap(volume_corr, annot=True, cmap = 'Reds')
plt.title('거래량 상관관계')
plt.show()
# 가격 상관관계
plt.figure(figsize = (14, 8))
price_corr = price.corr()
price_corr = price_corr.apply(lambda x: round(x ,2))
sns.heatmap(price_corr, annot=True, cmap = 'Blues')
plt.title('가격 상관관계')
plt.show()
Report¶
[거래량 상관관계]
- 무와 배추거래량의 상관관계는 0.76로 강한 양의 상관관계를 보인다.
- 애호박은 깻잎과의 상관관계가 0.78으로 가장 강한 양의 상관관계를 보인다.
- 토마토와 백다다기의 상관관계는 0.87으로 가장 강한 양의 상관관계를 보인다.
- 반면에 시금치와 캠벨얼리는 -0.47로 음의 상관관계를 나타내고 있다.
- 전체적으로 상품 간 상관관계가 높은 경우가 많고, 특히 특정 상품과 양의 상관관계를 보이는 상품이 다수 있는 것으로 나타났다.
[가격 상관관계]
- 애호박은 백다다기와 깻잎과 각각 0.75, 0.66의 강한 양의 상관관계를 나타내고 있다.
- 얼갈이배추는 시금치, 배추와 각각 0.7, 0.62로 강한 양의 상관관계를 나타내고 있다.
- 양파와 샤인마스캇의 상관관계는 -0.34로 음의 상관관계를 보이고 있고 다른 농산물들도 캠벨얼리와 샤인마스캇과는 높지 않은 상관관계를 보인다.
- 비교적 거래량의 상관관계보다 낮은 수치를 나타내고 있으며, 특정 상품과의 상관관계가 높은 경우가 많다.
샤인마스캇의 거래량과 가격은 독립적인 성향을 보인다. 데이터를 보니 샤인마스캇은 특정 시즌에만 거래된다는 것을 확인 할 수 있었다.
2.2 다양한 기준 별 데이터 분석¶
매년 농산물 총 거래량 분석¶
volume_per_year = volume.groupby(volume['date'].dt.year)
volume_per_year.mean()
배추거래량 | 무거래량 | 양파거래량 | 건고추거래량 | 마늘거래량 | 대파거래량 | 얼갈이배추거래량 | 양배추거래량 | 깻잎거래량 | 시금치거래량 | 미나리거래량 | 당근거래량 | 파프리카거래량 | 새송이거래량 | 팽이버섯거래량 | 토마토거래량 | 청상추거래량 | 백다다기거래량 | 애호박거래량 | 캠벨얼리거래량 | 샤인마스캇거래량 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
date | |||||||||||||||||||||
2016 | 1414406.6 | 1491266.1 | 1858490.1 | 2519.6 | 138167.9 | 622077.0 | 284413.6 | 656146.6 | 94490.5 | 172810.1 | 78805.5 | 303112.7 | 132886.4 | 162517.2 | 126595.7 | 385429.1 | 36058.8 | 472458.0 | 343653.0 | 178252.8 | 465.0 |
2017 | 1436508.1 | 1579836.7 | 1807564.5 | 9973.1 | 161784.8 | 656663.3 | 291072.3 | 713796.5 | 99191.2 | 193746.9 | 82732.6 | 332497.6 | 140583.3 | 163795.6 | 127909.0 | 381697.2 | 39893.9 | 474670.9 | 371709.6 | 151252.4 | 1317.2 |
2018 | 1390877.6 | 1529973.8 | 2027398.9 | 4667.4 | 150563.8 | 687760.6 | 309144.0 | 682106.2 | 92702.8 | 186343.4 | 84021.7 | 318902.0 | 129833.3 | 171119.6 | 120125.8 | 373533.9 | 40327.3 | 491410.4 | 341646.6 | 118443.8 | 3988.1 |
2019 | 1255936.8 | 1465353.1 | 2050290.8 | 1735.5 | 180493.9 | 697983.4 | 307229.1 | 633820.7 | 92451.1 | 178929.2 | 82811.8 | 335733.0 | 142545.6 | 172743.1 | 115743.4 | 362669.4 | 42026.8 | 499997.5 | 374391.5 | 130433.5 | 12881.0 |
2020 | 981213.3 | 1390760.0 | 1873558.5 | 1604.4 | 170529.8 | 660425.4 | 311590.6 | 579760.0 | 88606.6 | 146911.7 | 80507.0 | 313962.7 | 132507.9 | 172603.8 | 116407.6 | 336287.2 | 45816.5 | 529853.8 | 333669.5 | 105985.9 | 36340.3 |
volume_per_year = volume.groupby(volume['date'].dt.year)
volume_per_year_sum = volume_per_year.sum()
plt.figure(figsize = (12,12))
for i in range(4):
plt.subplot(2, 2, i+1)
year_data = volume_per_year_sum.iloc[i, :]
colors = sns.color_palette("Set3", len(year_data.index))
labels = [x[0:-3] for x in year_data.index]
patches, labels, pct_texts = plt.pie(
x = year_data.values,
colors = colors,
labels = labels,
labeldistance = 1.1,
autopct = '%.1f%%',
textprops={'fontsize': 9},
rotatelabels=True,
explode = [0.1, 0.08, 0.06, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
)
for label, pct_text in zip(labels, pct_texts):
pct_text.set_rotation(label.get_rotation())
plt.title(f'201{i+6}년 농산물 총거래량')
plt.axis('equal')
plt.tight_layout()
plt.show()
Report¶
그래프를 통해 대체로 매년 일정한 거래량을 유지하고 있지만 높은 비중을 차지하는 배추는 매년 조금씩 감소하고 있음을 알 수 있다. 또한 일정한 수준으로 양파, 무, 배추의 거래량이 가장 많고, 건고추와 샤인마스캇의 거래량은 매우 낮은 것을 알 수 있다.
월 기준 평균 거래량과 평균 가격 분석¶
products_month = products_pure.copy()
products_month['Month'] = products_month['date'].dt.month
volume_month = products_month.iloc[:, [0,1,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44]]
price_month = products_month.iloc[:, [0,1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,44]]
volume_month_mean = round(volume_month.groupby(['Month']).mean(), 2)
price_month_mean = round(price_month.groupby(['Month']).mean(), 2)
# 월별 농산물 거래량 평균
volume_fig = go.Figure()
for i in range(0,21):
volume_fig.add_trace(go.Scatter(mode = 'lines+markers', x = products_month['Month'].unique(), y= volume_month_mean.iloc[:, i], name = volume_month_mean.columns[i]))
volume_fig.update_xaxes(type = 'category')
volume_fig.update_layout(title = '월별 농산물 거래량 평균', titlefont_size = 20, title_x = 0.5)
volume_fig.update_layout (yaxis_tickformat = 'd')
volume_fig.show()
# 월별 거래 가격 평균
price_fig = go.Figure()
for i in range(0,21):
price_fig.add_trace(go.Scatter(mode = 'lines+markers', x = products_month['Month'].unique(), y= price_month_mean.iloc[:, i], name = price_month_mean.columns[i]))
price_fig.update_xaxes(type = 'category')
price_fig.update_layout(title = '월별 농산물 거래가격 평균', titlefont_size = 20, title_x = 0.5)
price_fig.update_layout (yaxis_tickformat = 'd')
price_fig.show()
Report¶
샤인마스캇 : 샤인마스캇 가격이 6월에 폭등하는 이유는 특정 시즌에 한정적으로 거래가 되어 수요에 비해 상품양이 적기 때문에 사전예약 등으로 가격이 많이 오르는 것으로 판단된다. 거래량은 다른 농산물에 비해 알려진지 오래 되지 않았고 가격도 높아 아직 많이 거래되고 있지 않는 것으로 보인다.
건고추 : 수확시기인 7-10월에 거래량이 증가하여 가격이 대체로 높으며, 수요가 많은 김장철(10-11월)에 거래량이 가장 많아지면서 가격이 낮아졌다가 이후 다시 높아지는 형태를 보인다.
캠벨얼리 : 8-9월이 제철인 과일로 거래량이 급격하게 증가하고 가격은 가장 낮은 시기이다.
양파 : 1-4월에 가격이 가장 높은편이고 거래량도 3-4월에 가장 크게 증가한다. 제철인 6-9월에 저렴하게 구할 수 있고 3월부터 출하되기 때문에 거래량이 급증한다.
무, 배추 : 8월부터 점차 가격이 증가하여 김장철부터 제철인 겨울내내 거래량이 가장 많고, 이후 낮아져 평탄한 형태를 유지한다.
거래량이 높은 배추, 무, 양파의 요일 별 거래량¶
weekday = np.array(['월요일','화요일','수요일','목요일','금요일','토요일'])
volume_part = volume[['요일', '배추거래량', '무거래량', '양파거래량']]
volume_part['요일'] = pd.Categorical(volume_part['요일'],categories=weekday, ordered=True)
result = volume_part.groupby('요일').agg(['sum'])
result_baechu, result_radish, result_onion = result['배추거래량'], result['무거래량'], result['양파거래량']
plt.figure(figsize=(15, 6))
plt.subplot(1, 2, 1)
plt.xticks(range(len(weekday)), result_onion.index)
plt.bar(np.arange(len(result_baechu.index))-0.2, np.reshape(result_baechu.values, (-1, )), label="배추", width=0.2)
plt.bar(np.arange(len(result_radish.index)), np.reshape(result_radish.values, (-1, )), label="무", width=0.2)
plt.bar(np.arange(len(result_onion.index)) + 0.2, np.reshape(result_onion.values, (-1, )), label="양파", width=0.2)
plt.title("배추, 무, 양파 요일별 총거래량")
plt.legend()
plt.subplot(1, 2, 2)
plt.xticks(range(len(weekday)), result_onion.index)
plt.bar(np.arange(len(result_baechu.index)), np.reshape(result_baechu.values, (-1, )), label="배추", width=0.2)
plt.bar(np.arange(len(result_radish.index)), np.reshape(result_radish.values, (-1, )), label="무", width=0.2, bottom=np.reshape(result_baechu.values, (-1, )))
plt.bar(np.arange(len(result_onion.index)), np.reshape(result_onion.values, (-1, )), label="양파", width=0.2, bottom=(np.reshape(result_baechu.values, (-1, )) + np.reshape(result_radish.values, (-1, ))))
plt.title("배추, 무, 양파 요일별 총거래량합")
plt.legend()
plt.show()
<ipython-input-16-23c9f3e33c5b>:3: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
Report¶
- 양파, 무, 배추 순으로 거래량이 많다.
- 월요일에 거래시장이 제일 활발하고 날이 지날수록 점점 떨어져서 토요일에는 거래량이 제일 작다.
3. 신경망을 사용한 예측¶
3.1 모델을 생성 하기 위한 전처리¶
모델 생성을 할 때는 train.csv (2016.01.01 부터 2020.09.28 까지의 21가지 농산물 가격, 거래량 데이터) 사용¶
data = pd.read_csv('data/public_data/train.csv')
data.head()
date | 요일 | 배추_거래량(kg) | 배추_가격(원/kg) | 무_거래량(kg) | 무_가격(원/kg) | 양파_거래량(kg) | 양파_가격(원/kg) | 건고추_거래량(kg) | 건고추_가격(원/kg) | 마늘_거래량(kg) | 마늘_가격(원/kg) | 대파_거래량(kg) | 대파_가격(원/kg) | 얼갈이배추_거래량(kg) | 얼갈이배추_가격(원/kg) | 양배추_거래량(kg) | 양배추_가격(원/kg) | 깻잎_거래량(kg) | 깻잎_가격(원/kg) | 시금치_거래량(kg) | 시금치_가격(원/kg) | 미나리_거래량(kg) | 미나리_가격(원/kg) | 당근_거래량(kg) | 당근_가격(원/kg) | 파프리카_거래량(kg) | 파프리카_가격(원/kg) | 새송이_거래량(kg) | 새송이_가격(원/kg) | 팽이버섯_거래량(kg) | 팽이버섯_가격(원/kg) | 토마토_거래량(kg) | 토마토_가격(원/kg) | 청상추_거래량(kg) | 청상추_가격(원/kg) | 백다다기_거래량(kg) | 백다다기_가격(원/kg) | 애호박_거래량(kg) | 애호박_가격(원/kg) | 캠벨얼리_거래량(kg) | 캠벨얼리_가격(원/kg) | 샤인마스캇_거래량(kg) | 샤인마스캇_가격(원/kg) | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 2016-01-01 | 금요일 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
1 | 2016-01-02 | 토요일 | 80860.0 | 329.0 | 80272.0 | 360.0 | 122787.5 | 1281.0 | 3.0 | 11000.0 | 15019.0 | 5475.0 | 92334.0 | 1704.0 | 6359.0 | 1331.0 | 40028.0 | 348.0 | 4374.9 | 13242.0 | 16550.5 | 2339.0 | 10528.0 | 1729.0 | 13885.0 | 804.0 | 3853.0 | 3703.0 | 15797.0 | 2576.0 | 14634.0 | 1474.0 | 30950.0 | 1621.0 | 5125.0 | 9235.0 | 434.0 | 2109.0 | 19159.0 | 2414.0 | 880.0 | 2014.0 | 0.0 | 0.0 |
2 | 2016-01-03 | 일요일 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
3 | 2016-01-04 | 월요일 | 1422742.5 | 478.0 | 1699653.7 | 382.0 | 2315079.0 | 1235.0 | 699.0 | 4464.0 | 141638.0 | 5210.0 | 994328.1 | 1716.0 | 262615.5 | 1212.0 | 1074699.1 | 345.0 | 122613.5 | 9923.0 | 427435.1 | 2153.0 | 82113.5 | 3960.0 | 558950.2 | 794.0 | 104930.3 | 4871.0 | 277326.5 | 2440.0 | 159800.0 | 1750.0 | 291057.0 | 1834.0 | 38525.5 | 7631.0 | 500702.0 | 2046.0 | 620539.0 | 2018.0 | 2703.8 | 3885.0 | 0.0 | 0.0 |
4 | 2016-01-05 | 화요일 | 1167241.0 | 442.0 | 1423482.3 | 422.0 | 2092960.1 | 1213.0 | 1112.6 | 4342.0 | 126207.8 | 5387.0 | 787716.0 | 1715.0 | 221850.5 | 1197.0 | 825681.9 | 350.0 | 79055.9 | 9529.0 | 334636.8 | 2220.0 | 80144.0 | 3333.0 | 444353.7 | 763.0 | 100699.5 | 5129.0 | 218465.2 | 2437.0 | 153084.0 | 1822.0 | 194626.5 | 1833.0 | 32615.0 | 6926.0 | 147638.0 | 2268.0 | 231958.0 | 2178.0 | 8810.0 | 2853.0 | 0.0 | 0.0 |
volume = data.iloc[:, [0,1,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42]]
price = data.iloc[:, [0,1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43]]
전체기간 내의 농산물의 최대 가격, 최소가격¶
- 건고추 가격의 최대 가격은 17만원으로 이상치가 예상됨
max_volume = volume.iloc[:, 2:].max()
min_volume = volume.iloc[:, 2:].min()
volume_cols = volume.columns[2:]
max_price = price.iloc[:, 2:].max()
min_price = price.iloc[:, 2:].min()
price_cols = price.columns[2:]
trace1 = go.Bar(x = price_cols, y = max_price,
name = '농산물별 최대 가격', marker_color = '#f26dc1')
datas = [trace1]
layout = go.Layout(title_text ='농산물별 최대 가격', titlefont=dict(size=15, color='black'), title_x = 0.5) # 제목
fig = go.Figure(data=datas, layout=layout)
fig.update_layout (yaxis_tickformat = 'd')
pyo.iplot(fig)
머신러닝 모델링을 하기 전, 예측 정확도 향상을 위해 이상치를 삭제 해준다¶
# 건고추 가격의 최대가격이 너무 높은데 이상치인지 아닌지 판단해보기
fig = plt.figure(figsize=(8, 4))
ax1 = fig.add_subplot(1,2,1)
ax2 = fig.add_subplot(1,2,2)
drp_data = price['건고추_가격(원/kg)']
ax1.boxplot(drp_data)
ax2.scatter(range(len(drp_data)), drp_data)
plt.show()
- 건고추 가격에 이상치가 존재하므로 이상치 제거를 해주어야 함
# 다른 농산물들의 이상치 확인
columns = price.iloc[:, 2:].columns
plt.figure(figsize=(10,15))
for i in range(len(columns)):
plt.subplot(7, 3, i+1)
plt.boxplot(price[columns[i]])
plt.title('{}'.format(columns[i]))
plt.tight_layout()
plt.show()
이상치 제거¶
- 이상치가 존재하는 행을 아예 삭제하면 , 월요일 ~ 일요일 (7일) 순환의 규칙이 깨진다.
- 이상치는 최대, 최소 극단값으로 대체한다. (q1 - (iqr 1.5), q3 + (iqr 1.5))
pri_columns = price.columns[2:]
def get_outlier(df, column):
q1, q3 = np.percentile(df[column], [25, 75])
iqr = q3 - q1
lower_bound = q1 - (iqr * 1.5)
upper_bound = q3 + (iqr * 1.5)
outindex_upper = np.where((df[column] > upper_bound))
outindex_lower = np.where((df[column] < lower_bound))
return outindex_upper, outindex_lower, upper_bound, lower_bound
for i in pri_columns:
outindex_upper, outindex_lower, upper_bound, lower_bound = get_outlier(price, i)
data[i] = data[i].replace(price.loc[outindex_upper][i].values, upper_bound)
data[i] = data[i].replace(price.loc[outindex_lower][i].values, lower_bound)
# 이상치 제거 확인
columns = data.iloc[:, 3::2].columns
plt.figure(figsize=(10,15))
for i in range(len(columns)):
plt.subplot(7, 3, i+1)
plt.boxplot(data[columns[i]])
plt.title('{}'.format(columns[i]))
plt.tight_layout()
plt.show()
데이터 정규화¶
week_day_map = {}
for i, d in enumerate(data['요일'].unique()):
week_day_map[d] = i
data['요일'] = data['요일'].map(week_day_map)
norm = data.iloc[:, 1:].max(0)
data.iloc[:, 1:] = data.iloc[:, 1:] / norm
하이퍼 파라미터¶
# device = torch.device("cuda:0") # GPU 사용
# target_n = 21 # 맞춰야하는 품목/품종의 수
# learning_rate = 5e-4 # 학습률
BATCH_SIZE = 128 # 배치사이즈
EPOCHS = 50 # 총 eopochs
# teacher_forcing = False # 교사강요 설정
# n_layers = 3 # rnn레이어 층
dropout = 0.2 # 드롭아웃
window_size = 28 # 28일 데이터를 가지고 예측
future_size = 28 # 미래 28일 데이터를 예측
# hidden_dim = 128 # rnn 히든차원
# save_path = f'./models/best_model.pt' # 모델 저장 경로
3차원 데이터로 변경¶
- 시계열 학습이 가능한 형태로 전처리 (3차원)
- 과거 28일의 변화를 보고 미래 28일을 예측
x_data = [] # feature
y_data = [] # label
for i in range(data.shape[0]-window_size-future_size):
x = data.iloc[i:i+window_size, 1:].to_numpy() # [요일, 농산물1거래량, 농산물1가격, 농산물2거래량, ......]
y = data.iloc[i+window_size:i+window_size+future_size, 3::2].to_numpy() # [농산물1가격, 농산물2가격, ....]
#y_0 = np.zeros([1, y.shape[1]]) # 디코더 첫 입력값 추가
x_data.append(x)
#y_data.append(np.concatenate([y_0, y], axis=0))
y_data.append(y)
x_data = np.array(x_data)
y_data = np.array(y_data)
print(x_data.shape, y_data.shape) # 28은 window_size(timestep)을 뜻한다. (1677, 28, 1)
(1677, 28, 43) (1677, 28, 21)
train / test split¶
x_data_train, x_data_test = x_data[:1400], x_data[1400:]
y_data_train, y_data_test = y_data[:1400], y_data[1400:]
print(x_data_train.shape, ' ', x_data_test.shape)
print(y_data_train.shape, ' ', y_data_test.shape)
(1400, 28, 43) (277, 28, 43) (1400, 28, 21) (277, 28, 21)
3.2 모델 생성¶
LSTM¶
Keras LSTM은 데이터 전처리가 조금 번거롭다. Tensor형태의 3차원을 요구하여, Reshape를 반드시 거쳐야하기 때문!
3.2.1 이상치를 제거 하지 않고 LSTM 수행¶
LSTM 사용을 위한 데이터 다시 불러오기¶
data = pd.read_csv('data/public_data/train.csv')
data['date'] = pd.to_datetime(data['date'])
요일 칼럼을 숫자로 변환¶
week_day_map = {}
for i, d in enumerate(data['요일'].unique()):
week_day_map[d] = i
data['요일'] = data['요일'].map(week_day_map)
데이터 정규화¶
norm = data.iloc[:, 1:].max(0)
data.iloc[:, 1:] = data.iloc[:, 1:] / norm
3차원 데이터로 변경¶
x_data = [] # feature
y_data = [] # label
for i in range(data.shape[0]-window_size-future_size):
x = data.iloc[i:i+window_size, 1:].to_numpy() # [요일, 농산물1거래량, 농산물1가격, 농산물2거래량, ......]
y = data.iloc[i+window_size:i+window_size+future_size, 3::2].to_numpy() # [농산물1가격, 농산물2가격, ....]
#y_0 = np.zeros([1, y.shape[1]]) # 디코더 첫 입력값 추가
x_data.append(x)
#y_data.append(np.concatenate([y_0, y], axis=0))
y_data.append(y)
x_data = np.array(x_data)
y_data = np.array(y_data)
x_data_train, x_data_test = x_data[:1400], x_data[1400:]
y_data_train, y_data_test = y_data[:1400], y_data[1400:]
LSTM 모델 생성¶
model = Sequential()
model.add(LSTM(400, activation = 'leaky_relu', input_shape = (28 ,43), return_sequences=True)) # 타임 스텝, 속성 (timesteps, n_features)
model.add(Dropout(0.3))
model.add(LSTM(300, activation = 'leaky_relu', return_sequences=True))
model.add(Dropout(0.3))
model.add(LSTM(200, activation = 'leaky_relu', return_sequences=True))
model.add(Dropout(0.3))
model.add(Dense(100, activation = 'leaky_relu'))
model.add(Dense(50, activation = 'leaky_relu'))
model.add(Dropout(0.3))
model.add(Dense(21))
model.summary()
WARNING:tensorflow:Layer lstm will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_1 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_2 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. Model: "sequential" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= lstm (LSTM) (None, 28, 400) 710400 _________________________________________________________________ dropout (Dropout) (None, 28, 400) 0 _________________________________________________________________ lstm_1 (LSTM) (None, 28, 300) 841200 _________________________________________________________________ dropout_1 (Dropout) (None, 28, 300) 0 _________________________________________________________________ lstm_2 (LSTM) (None, 28, 200) 400800 _________________________________________________________________ dropout_2 (Dropout) (None, 28, 200) 0 _________________________________________________________________ dense (Dense) (None, 28, 100) 20100 _________________________________________________________________ dense_1 (Dense) (None, 28, 50) 5050 _________________________________________________________________ dropout_3 (Dropout) (None, 28, 50) 0 _________________________________________________________________ dense_2 (Dense) (None, 28, 21) 1071 ================================================================= Total params: 1,978,621 Trainable params: 1,978,621 Non-trainable params: 0 _________________________________________________________________
es = EarlyStopping(monitor='val_loss', patience=5)
optimizer = Adam(learning_rate=0.01)
model.compile(loss='mse', optimizer='adam', metrics=['mse'])
history = model.fit(x_data_train, y_data_train, epochs=100, batch_size=BATCH_SIZE, validation_split=0.3, verbose=1, callbacks=[es])
Epoch 1/100 8/8 [==============================] - 8s 579ms/step - loss: 0.0929 - mse: 0.0929 - val_loss: 0.0480 - val_mse: 0.0480 Epoch 2/100 8/8 [==============================] - 4s 528ms/step - loss: 0.0622 - mse: 0.0622 - val_loss: 0.0348 - val_mse: 0.0348 Epoch 3/100 8/8 [==============================] - 4s 532ms/step - loss: 0.0489 - mse: 0.0489 - val_loss: 0.0301 - val_mse: 0.0301 Epoch 4/100 8/8 [==============================] - 4s 524ms/step - loss: 0.0417 - mse: 0.0417 - val_loss: 0.0272 - val_mse: 0.0272 Epoch 5/100 8/8 [==============================] - 4s 535ms/step - loss: 0.0374 - mse: 0.0374 - val_loss: 0.0258 - val_mse: 0.0258 Epoch 6/100 8/8 [==============================] - 4s 522ms/step - loss: 0.0346 - mse: 0.0346 - val_loss: 0.0253 - val_mse: 0.0253 Epoch 7/100 8/8 [==============================] - 4s 541ms/step - loss: 0.0322 - mse: 0.0322 - val_loss: 0.0241 - val_mse: 0.0241 Epoch 8/100 8/8 [==============================] - 4s 495ms/step - loss: 0.0299 - mse: 0.0299 - val_loss: 0.0232 - val_mse: 0.0232 Epoch 9/100 8/8 [==============================] - 4s 495ms/step - loss: 0.0281 - mse: 0.0281 - val_loss: 0.0224 - val_mse: 0.0224 Epoch 10/100 8/8 [==============================] - 4s 505ms/step - loss: 0.0266 - mse: 0.0266 - val_loss: 0.0216 - val_mse: 0.0216 Epoch 11/100 8/8 [==============================] - 4s 495ms/step - loss: 0.0253 - mse: 0.0253 - val_loss: 0.0206 - val_mse: 0.0206 Epoch 12/100 8/8 [==============================] - 4s 491ms/step - loss: 0.0238 - mse: 0.0238 - val_loss: 0.0198 - val_mse: 0.0198 Epoch 13/100 8/8 [==============================] - 4s 521ms/step - loss: 0.0223 - mse: 0.0223 - val_loss: 0.0186 - val_mse: 0.0186 Epoch 14/100 8/8 [==============================] - 4s 519ms/step - loss: 0.0205 - mse: 0.0205 - val_loss: 0.0181 - val_mse: 0.0181 Epoch 15/100 8/8 [==============================] - 4s 489ms/step - loss: 0.0189 - mse: 0.0189 - val_loss: 0.0176 - val_mse: 0.0176 Epoch 16/100 8/8 [==============================] - 4s 507ms/step - loss: 0.0178 - mse: 0.0178 - val_loss: 0.0167 - val_mse: 0.0167 Epoch 17/100 8/8 [==============================] - 4s 496ms/step - loss: 0.0174 - mse: 0.0174 - val_loss: 0.0166 - val_mse: 0.0166 Epoch 18/100 8/8 [==============================] - 4s 508ms/step - loss: 0.0167 - mse: 0.0167 - val_loss: 0.0174 - val_mse: 0.0174 Epoch 19/100 8/8 [==============================] - 4s 493ms/step - loss: 0.0160 - mse: 0.0160 - val_loss: 0.0168 - val_mse: 0.0168 Epoch 20/100 8/8 [==============================] - 4s 500ms/step - loss: 0.0155 - mse: 0.0155 - val_loss: 0.0173 - val_mse: 0.0173 Epoch 21/100 8/8 [==============================] - 4s 498ms/step - loss: 0.0150 - mse: 0.0150 - val_loss: 0.0169 - val_mse: 0.0169 Epoch 22/100 8/8 [==============================] - 4s 509ms/step - loss: 0.0145 - mse: 0.0145 - val_loss: 0.0171 - val_mse: 0.0171
print(model.evaluate(x_data_test, y_data_test))
9/9 [==============================] - 0s 49ms/step - loss: 0.0229 - mse: 0.0229 [0.022897398099303246, 0.022897396236658096]
loss 변환 과정 시각화¶
epochs = range(1, len(history.history['loss']) + 1)
plt.plot(epochs, history.history['loss'], c = 'r', label = 'loss')
plt.plot(epochs, history.history['val_loss'], label = 'val_loss')
plt.xlabel('epochs')
plt.ylabel('loss')
plt.legend()
plt.show()
모델 평균 설명력 확인¶
pred = model.predict(x_data_test)
r2_list = []
mae_list = []
mse_list = []
for i in range(len(y_data_test)):
r2 = r2_score(y_data_test[i], pred[i])
r2_list.append(r2)
mae = mean_absolute_error(y_data_test[i], pred[i])
mae_list.append(mae)
mse = mean_squared_error(y_data_test[i], pred[i])
mse_list.append(mse)
print('평균 r2', np.mean(r2_list))
print('평균 mae', np.mean(mae_list))
print('평균 mse', np.mean(mse_list))
평균 r2 -0.02402991680236918 평균 mae 0.10558060716763053 평균 mse 0.022897398490453205
설명력 그래프¶
plt.plot(r2_list)
plt.title('test data 예측 설명력')
plt.show()
예측값, 실제값 비교¶
# 예측 값 가격 (바로 밑행에 pred(n) -> n+1번째 날 기준 예측 가격) (n = 1이면 test 데이터셋의 2~29일 예측)
df1 = pd.DataFrame(pred[0], columns = ['배추_가격(원/kg)', '무_가격(원/kg)', '양파_가격(원/kg)', '건고추_가격(원/kg)',
'마늘_가격(원/kg)', '대파_가격(원/kg)', '얼갈이배추_가격(원/kg)', '양배추_가격(원/kg)',
'깻잎_가격(원/kg)', '시금치_가격(원/kg)', '미나리_가격(원/kg)', '당근_가격(원/kg)',
'파프리카_가격(원/kg)', '새송이_가격(원/kg)', '팽이버섯_가격(원/kg)', '토마토_가격(원/kg)',
'청상추_가격(원/kg)', '백다다기_가격(원/kg)', '애호박_가격(원/kg)', '캠벨얼리_가격(원/kg)',
'샤인마스캇_가격(원/kg)'])
norm_price = norm[2::2] # 정규화 풀어주기 위해 가격부분 정규화만 뽑기
norm_df = pd.DataFrame(norm_price).T
df1 = df1.multiply(norm_df.values)
df1.head()
배추_가격(원/kg) | 무_가격(원/kg) | 양파_가격(원/kg) | 건고추_가격(원/kg) | 마늘_가격(원/kg) | 대파_가격(원/kg) | 얼갈이배추_가격(원/kg) | 양배추_가격(원/kg) | 깻잎_가격(원/kg) | 시금치_가격(원/kg) | 미나리_가격(원/kg) | 당근_가격(원/kg) | 파프리카_가격(원/kg) | 새송이_가격(원/kg) | 팽이버섯_가격(원/kg) | 토마토_가격(원/kg) | 청상추_가격(원/kg) | 백다다기_가격(원/kg) | 애호박_가격(원/kg) | 캠벨얼리_가격(원/kg) | 샤인마스캇_가격(원/kg) | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 666.3 | 565.9 | 726.8 | 8221.7 | 3872.4 | 1225.5 | 858.9 | 585.7 | 4586.3 | 2537.9 | 2107.7 | 946.0 | 2696.2 | 1847.5 | 1296.8 | 1734.1 | 2675.6 | 1555.3 | 1479.1 | 3380.4 | 5266.1 |
1 | 682.8 | 597.6 | 768.3 | 8538.8 | 4114.4 | 1314.7 | 927.8 | 617.3 | 4829.7 | 2647.0 | 2295.5 | 988.5 | 2974.1 | 1989.3 | 1412.0 | 1899.7 | 2866.3 | 1656.9 | 1630.7 | 3187.7 | 5025.6 |
2 | 195.4 | 79.1 | 85.6 | 3258.6 | 320.7 | 187.4 | 135.5 | 64.6 | 468.6 | 455.8 | 316.8 | 62.3 | 460.8 | 237.1 | 173.0 | 335.8 | 452.9 | 189.5 | 363.7 | 430.6 | 878.2 |
3 | 661.2 | 608.9 | 812.8 | 7663.0 | 4366.7 | 1388.4 | 978.2 | 630.6 | 4950.8 | 2643.2 | 2416.7 | 1012.2 | 3138.1 | 2054.6 | 1518.0 | 1921.5 | 2998.5 | 1669.7 | 1622.6 | 3104.1 | 5488.6 |
4 | 667.6 | 629.7 | 836.0 | 8234.4 | 4479.2 | 1416.5 | 983.7 | 667.1 | 5107.9 | 2620.3 | 2435.4 | 1043.5 | 3268.0 | 2115.0 | 1551.1 | 2004.6 | 2983.6 | 1724.0 | 1718.9 | 3222.5 | 5280.2 |
# 실제값 가격 (바로 밑행에 y_data_test[n] -> n+1번째 날 기준 가격) (n = 0 이면 y_data_test 데이터셋의 1~28일 값)
real = pd.DataFrame(y_data_test[0], columns = ['배추_가격(원/kg)', '무_가격(원/kg)', '양파_가격(원/kg)', '건고추_가격(원/kg)',
'마늘_가격(원/kg)', '대파_가격(원/kg)', '얼갈이배추_가격(원/kg)', '양배추_가격(원/kg)',
'깻잎_가격(원/kg)', '시금치_가격(원/kg)', '미나리_가격(원/kg)', '당근_가격(원/kg)',
'파프리카_가격(원/kg)', '새송이_가격(원/kg)', '팽이버섯_가격(원/kg)', '토마토_가격(원/kg)',
'청상추_가격(원/kg)', '백다다기_가격(원/kg)', '애호박_가격(원/kg)', '캠벨얼리_가격(원/kg)',
'샤인마스캇_가격(원/kg)'])
real = real.multiply(norm_price.values)
real.head()
배추_가격(원/kg) | 무_가격(원/kg) | 양파_가격(원/kg) | 건고추_가격(원/kg) | 마늘_가격(원/kg) | 대파_가격(원/kg) | 얼갈이배추_가격(원/kg) | 양배추_가격(원/kg) | 깻잎_가격(원/kg) | 시금치_가격(원/kg) | 미나리_가격(원/kg) | 당근_가격(원/kg) | 파프리카_가격(원/kg) | 새송이_가격(원/kg) | 팽이버섯_가격(원/kg) | 토마토_가격(원/kg) | 청상추_가격(원/kg) | 백다다기_가격(원/kg) | 애호박_가격(원/kg) | 캠벨얼리_가격(원/kg) | 샤인마스캇_가격(원/kg) | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 801.0 | 756.0 | 605.0 | 10578.0 | 3012.0 | 985.0 | 828.0 | 659.0 | 5063.0 | 1819.0 | 4129.0 | 1033.0 | 3519.0 | 2100.0 | 1824.0 | 2484.0 | 1891.0 | 2326.0 | 1188.0 | 2713.0 | 12498.0 |
1 | 767.0 | 762.0 | 638.0 | 22637.0 | 3048.0 | 990.0 | 869.0 | 666.0 | 5005.0 | 1809.0 | 4508.0 | 935.0 | 3206.0 | 2102.0 | 1876.0 | 2286.0 | 1930.0 | 2166.0 | 1174.0 | 2872.0 | 12144.0 |
2 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
3 | 767.0 | 869.0 | 649.0 | 10671.0 | 3007.0 | 1076.0 | 972.0 | 677.0 | 5446.0 | 1984.0 | 4020.0 | 1239.0 | 2893.0 | 2139.0 | 1965.0 | 2518.0 | 1921.0 | 2369.0 | 1280.0 | 2921.0 | 12283.0 |
4 | 751.0 | 776.0 | 694.0 | 9958.0 | 3072.0 | 1202.0 | 1069.0 | 739.0 | 6128.0 | 1981.0 | 3804.0 | 1019.0 | 2821.0 | 2108.0 | 1948.0 | 2313.0 | 2063.0 | 2416.0 | 1404.0 | 3062.0 | 11628.0 |
예측값, 실제값 시각화¶
# n번째 날 기준 +1일 ~ +28일 예측값과 실제값 비교
plt.figure(figsize = (15, 6))
plt.plot(df1.iloc[:,0], label = '예측값')
plt.plot(real.iloc[:,0], label = '실제값')
plt.title('배추 실제, 예측값 비교')
plt.legend()
plt.show()
3.2.2 이상치 제거 후 LSTM 수행¶
LSTM 사용을 위한 데이터 다시 불러오기¶
data = pd.read_csv('data/public_data/train.csv')
data['date'] = pd.to_datetime(data['date'])
volume = data.iloc[:, [0,1,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42]]
price = data.iloc[:, [0,1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43]]
이상치 제거¶
pri_columns = price.columns[2:]
def get_outlier(df, column):
q1, q3 = np.percentile(df[column], [25, 75])
iqr = q3 - q1
lower_bound = q1 - (iqr * 1.5)
upper_bound = q3 + (iqr * 1.5)
outindex_upper = np.where((df[column] > upper_bound))
outindex_lower = np.where((df[column] < lower_bound))
return outindex_upper, outindex_lower, upper_bound, lower_bound
for i in pri_columns:
outindex_upper, outindex_lower, upper_bound, lower_bound = get_outlier(price, i)
data[i] = data[i].replace(price.loc[outindex_upper][i].values, upper_bound)
data[i] = data[i].replace(price.loc[outindex_lower][i].values, lower_bound)
요일 칼럼을 숫자로 변환¶
week_day_map = {}
for i, d in enumerate(data['요일'].unique()):
week_day_map[d] = i
data['요일'] = data['요일'].map(week_day_map)
데이터 정규화¶
norm = data.iloc[:, 1:].max(0)
data.iloc[:, 1:] = data.iloc[:, 1:] / norm
3차원 데이터로 변경¶
x_data = [] # feature
y_data = [] # label
for i in range(data.shape[0]-window_size-future_size):
x = data.iloc[i:i+window_size, 1:].to_numpy() # [요일, 농산물1거래량, 농산물1가격, 농산물2거래량, ......]
y = data.iloc[i+window_size:i+window_size+future_size, 3::2].to_numpy() # [농산물1가격, 농산물2가격, ....]
#y_0 = np.zeros([1, y.shape[1]]) # 디코더 첫 입력값 추가
x_data.append(x)
#y_data.append(np.concatenate([y_0, y], axis=0))
y_data.append(y)
x_data = np.array(x_data)
y_data = np.array(y_data)
x_data_train, x_data_test = x_data[:1400], x_data[1400:]
y_data_train, y_data_test = y_data[:1400], y_data[1400:]
LSTM 모델 생성¶
model = Sequential()
model.add(LSTM(400, activation = 'relu', input_shape = (28 ,43), return_sequences=True)) # 타임 스텝, 속성 (timesteps, n_features)
model.add(LSTM(300, activation = 'relu', return_sequences=True))
model.add(Dropout(0.2))
model.add(Dense(200, activation = 'leaky_relu'))
model.add(Dense(100, activation = 'leaky_relu'))
model.add(Dense(50, activation = 'leaky_relu'))
model.add(Dropout(0.2))
model.add(Dense(21))
model.summary()
WARNING:tensorflow:Layer lstm_3 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_4 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. Model: "sequential_1" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= lstm_3 (LSTM) (None, 28, 400) 710400 _________________________________________________________________ lstm_4 (LSTM) (None, 28, 300) 841200 _________________________________________________________________ dropout_4 (Dropout) (None, 28, 300) 0 _________________________________________________________________ dense_3 (Dense) (None, 28, 200) 60200 _________________________________________________________________ dense_4 (Dense) (None, 28, 100) 20100 _________________________________________________________________ dense_5 (Dense) (None, 28, 50) 5050 _________________________________________________________________ dropout_5 (Dropout) (None, 28, 50) 0 _________________________________________________________________ dense_6 (Dense) (None, 28, 21) 1071 ================================================================= Total params: 1,638,021 Trainable params: 1,638,021 Non-trainable params: 0 _________________________________________________________________
es = EarlyStopping(monitor='val_loss', patience=5)
optimizer = Adam(learning_rate=0.001)
model.compile(loss='mse', optimizer='adam', metrics=['mse'])
history = model.fit(x_data_train, y_data_train, epochs=100, batch_size=BATCH_SIZE, validation_split=0.3, verbose=1, callbacks=[es])
Epoch 1/100 8/8 [==============================] - 5s 373ms/step - loss: 0.1997 - mse: 0.1997 - val_loss: 0.1144 - val_mse: 0.1144 Epoch 2/100 8/8 [==============================] - 3s 347ms/step - loss: 0.1164 - mse: 0.1164 - val_loss: 0.0708 - val_mse: 0.0708 Epoch 3/100 8/8 [==============================] - 3s 322ms/step - loss: 0.0845 - mse: 0.0845 - val_loss: 0.0556 - val_mse: 0.0556 Epoch 4/100 8/8 [==============================] - 3s 318ms/step - loss: 0.0715 - mse: 0.0715 - val_loss: 0.0516 - val_mse: 0.0516 Epoch 5/100 8/8 [==============================] - 3s 326ms/step - loss: 0.0631 - mse: 0.0631 - val_loss: 0.0496 - val_mse: 0.0496 Epoch 6/100 8/8 [==============================] - 3s 323ms/step - loss: 0.0570 - mse: 0.0570 - val_loss: 0.0451 - val_mse: 0.0451 Epoch 7/100 8/8 [==============================] - 3s 329ms/step - loss: 0.0516 - mse: 0.0516 - val_loss: 0.0423 - val_mse: 0.0423 Epoch 8/100 8/8 [==============================] - 3s 335ms/step - loss: 0.0472 - mse: 0.0472 - val_loss: 0.0393 - val_mse: 0.0393 Epoch 9/100 8/8 [==============================] - 3s 330ms/step - loss: 0.0441 - mse: 0.0441 - val_loss: 0.0390 - val_mse: 0.0390 Epoch 10/100 8/8 [==============================] - 3s 330ms/step - loss: 0.0417 - mse: 0.0417 - val_loss: 0.0388 - val_mse: 0.0388 Epoch 11/100 8/8 [==============================] - 3s 341ms/step - loss: 0.0392 - mse: 0.0392 - val_loss: 0.0365 - val_mse: 0.0365 Epoch 12/100 8/8 [==============================] - 3s 341ms/step - loss: 0.0371 - mse: 0.0371 - val_loss: 0.0351 - val_mse: 0.0351 Epoch 13/100 8/8 [==============================] - 3s 337ms/step - loss: 0.0352 - mse: 0.0352 - val_loss: 0.0349 - val_mse: 0.0349 Epoch 14/100 8/8 [==============================] - 3s 338ms/step - loss: 0.0338 - mse: 0.0338 - val_loss: 0.0349 - val_mse: 0.0349 Epoch 15/100 8/8 [==============================] - 3s 350ms/step - loss: 0.0326 - mse: 0.0326 - val_loss: 0.0345 - val_mse: 0.0345 Epoch 16/100 8/8 [==============================] - 3s 329ms/step - loss: 0.0311 - mse: 0.0311 - val_loss: 0.0342 - val_mse: 0.0342 Epoch 17/100 8/8 [==============================] - 3s 333ms/step - loss: 0.0299 - mse: 0.0299 - val_loss: 0.0338 - val_mse: 0.0338 Epoch 18/100 8/8 [==============================] - 3s 345ms/step - loss: 0.0290 - mse: 0.0290 - val_loss: 0.0326 - val_mse: 0.0326 Epoch 19/100 8/8 [==============================] - 3s 349ms/step - loss: 0.0280 - mse: 0.0280 - val_loss: 0.0330 - val_mse: 0.0330 Epoch 20/100 8/8 [==============================] - 3s 335ms/step - loss: 0.0272 - mse: 0.0272 - val_loss: 0.0324 - val_mse: 0.0324 Epoch 21/100 8/8 [==============================] - 3s 330ms/step - loss: 0.0261 - mse: 0.0261 - val_loss: 0.0320 - val_mse: 0.0320 Epoch 22/100 8/8 [==============================] - 3s 350ms/step - loss: 0.0255 - mse: 0.0255 - val_loss: 0.0324 - val_mse: 0.0324 Epoch 23/100 8/8 [==============================] - 3s 336ms/step - loss: 0.0246 - mse: 0.0246 - val_loss: 0.0310 - val_mse: 0.0310 Epoch 24/100 8/8 [==============================] - 3s 348ms/step - loss: 0.0237 - mse: 0.0237 - val_loss: 0.0310 - val_mse: 0.0310 Epoch 25/100 8/8 [==============================] - 3s 345ms/step - loss: 0.0230 - mse: 0.0230 - val_loss: 0.0313 - val_mse: 0.0313 Epoch 26/100 8/8 [==============================] - 3s 346ms/step - loss: 0.0220 - mse: 0.0220 - val_loss: 0.0310 - val_mse: 0.0310 Epoch 27/100 8/8 [==============================] - 3s 327ms/step - loss: 0.0216 - mse: 0.0216 - val_loss: 0.0305 - val_mse: 0.0305 Epoch 28/100 8/8 [==============================] - 3s 334ms/step - loss: 0.0210 - mse: 0.0210 - val_loss: 0.0310 - val_mse: 0.0310 Epoch 29/100 8/8 [==============================] - 3s 325ms/step - loss: 0.0204 - mse: 0.0204 - val_loss: 0.0315 - val_mse: 0.0315 Epoch 30/100 8/8 [==============================] - 3s 327ms/step - loss: 0.0197 - mse: 0.0197 - val_loss: 0.0317 - val_mse: 0.0317 Epoch 31/100 8/8 [==============================] - 3s 330ms/step - loss: 0.0190 - mse: 0.0190 - val_loss: 0.0313 - val_mse: 0.0313 Epoch 32/100 8/8 [==============================] - 3s 344ms/step - loss: 0.0186 - mse: 0.0186 - val_loss: 0.0319 - val_mse: 0.0319
print(model.evaluate(x_data_test, y_data_test))
9/9 [==============================] - 0s 35ms/step - loss: 0.0409 - mse: 0.0409 [0.040887221693992615, 0.04088721424341202]
loss 변화과정 시각화¶
epochs = range(1, len(history.history['loss']) + 1)
plt.plot(epochs, history.history['loss'], c = 'r', label = 'loss')
plt.plot(epochs, history.history['val_loss'], label = 'val_loss')
plt.xlabel('epochs')
plt.ylabel('loss')
plt.legend()
plt.show()
모델 평균 설명력 확인¶
pred = model.predict(x_data_test)
r2_list = []
mae_list = []
mse_list = []
for i in range(len(y_data_test)):
r2 = r2_score(y_data_test[i], pred[i])
r2_list.append(r2)
mae = mean_absolute_error(y_data_test[i], pred[i])
mae_list.append(mae)
mse = mean_squared_error(y_data_test[i], pred[i])
mse_list.append(mse)
print('평균 r2', np.mean(r2_list))
print('평균 mae', np.mean(mae_list))
print('평균 mse', np.mean(mse_list))
평균 r2 0.011460544283335941 평균 mae 0.14954752031859941 평균 mse 0.04088721820216871
설명력 그래프¶
plt.plot(r2_list)
plt.title('test data 예측 설명력')
plt.show()
예측값, 실제값 비교¶
# 예측 값 가격 (바로 밑행에 pred(n) -> n+1번째 날 기준 예측 가격) (n = 1이면 test 데이터셋의 2~29일 예측)
df1 = pd.DataFrame(pred[0], columns = ['배추_가격(원/kg)', '무_가격(원/kg)', '양파_가격(원/kg)', '건고추_가격(원/kg)',
'마늘_가격(원/kg)', '대파_가격(원/kg)', '얼갈이배추_가격(원/kg)', '양배추_가격(원/kg)',
'깻잎_가격(원/kg)', '시금치_가격(원/kg)', '미나리_가격(원/kg)', '당근_가격(원/kg)',
'파프리카_가격(원/kg)', '새송이_가격(원/kg)', '팽이버섯_가격(원/kg)', '토마토_가격(원/kg)',
'청상추_가격(원/kg)', '백다다기_가격(원/kg)', '애호박_가격(원/kg)', '캠벨얼리_가격(원/kg)',
'샤인마스캇_가격(원/kg)'])
norm_price = norm[2::2] # 정규화 풀어주기 위해 가격부분 정규화만 뽑기
norm_df = pd.DataFrame(norm_price).T
df1 = df1.multiply(norm_df.values)
df1.head()
배추_가격(원/kg) | 무_가격(원/kg) | 양파_가격(원/kg) | 건고추_가격(원/kg) | 마늘_가격(원/kg) | 대파_가격(원/kg) | 얼갈이배추_가격(원/kg) | 양배추_가격(원/kg) | 깻잎_가격(원/kg) | 시금치_가격(원/kg) | 미나리_가격(원/kg) | 당근_가격(원/kg) | 파프리카_가격(원/kg) | 새송이_가격(원/kg) | 팽이버섯_가격(원/kg) | 토마토_가격(원/kg) | 청상추_가격(원/kg) | 백다다기_가격(원/kg) | 애호박_가격(원/kg) | 캠벨얼리_가격(원/kg) | 샤인마스캇_가격(원/kg) | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 604.0 | 553.7 | 726.8 | 8791.9 | 4036.1 | 1225.2 | 889.7 | 590.4 | 4516.2 | 2232.1 | 2244.8 | 946.8 | 2847.4 | 1972.1 | 1376.0 | 1727.5 | 2564.5 | 1500.5 | 1534.3 | 2914.8 | 5151.2 |
1 | 559.6 | 564.2 | 703.8 | 9364.3 | 4151.0 | 1245.5 | 794.0 | 631.7 | 4769.9 | 2063.0 | 2342.5 | 1001.1 | 2993.9 | 2040.1 | 1507.6 | 1824.3 | 2412.2 | 1532.5 | 1534.8 | 2561.3 | 5751.2 |
2 | 62.3 | 54.0 | 60.0 | 327.9 | 312.8 | 144.7 | 36.5 | 66.9 | 448.5 | 78.2 | -55.6 | 280.8 | 246.4 | 759.9 | 121.5 | 164.8 | 276.5 | 136.6 | 41.6 | 146.5 | 961.3 |
3 | 559.6 | 592.7 | 705.9 | 10215.8 | 4286.6 | 1331.2 | 839.3 | 689.5 | 5115.2 | 2186.1 | 2535.4 | 1113.2 | 3240.9 | 2130.7 | 1739.8 | 1900.9 | 2582.8 | 1558.3 | 1595.2 | 2514.4 | 6478.6 |
4 | 530.5 | 589.9 | 714.7 | 10597.1 | 4362.6 | 1331.0 | 824.6 | 684.7 | 5262.6 | 2163.4 | 2638.4 | 1091.6 | 3280.6 | 2136.6 | 1781.6 | 1940.0 | 2554.7 | 1627.1 | 1683.3 | 2380.5 | 6591.1 |
# 실제값 가격 (바로 밑행에 y_data_test[n] -> n+1번째 날 기준 가격) (n = 0 이면 y_data_test 데이터셋의 1~28일 값)
real = pd.DataFrame(y_data_test[0], columns = ['배추_가격(원/kg)', '무_가격(원/kg)', '양파_가격(원/kg)', '건고추_가격(원/kg)',
'마늘_가격(원/kg)', '대파_가격(원/kg)', '얼갈이배추_가격(원/kg)', '양배추_가격(원/kg)',
'깻잎_가격(원/kg)', '시금치_가격(원/kg)', '미나리_가격(원/kg)', '당근_가격(원/kg)',
'파프리카_가격(원/kg)', '새송이_가격(원/kg)', '팽이버섯_가격(원/kg)', '토마토_가격(원/kg)',
'청상추_가격(원/kg)', '백다다기_가격(원/kg)', '애호박_가격(원/kg)', '캠벨얼리_가격(원/kg)',
'샤인마스캇_가격(원/kg)'])
real = real.multiply(norm_price.values)
real.head()
배추_가격(원/kg) | 무_가격(원/kg) | 양파_가격(원/kg) | 건고추_가격(원/kg) | 마늘_가격(원/kg) | 대파_가격(원/kg) | 얼갈이배추_가격(원/kg) | 양배추_가격(원/kg) | 깻잎_가격(원/kg) | 시금치_가격(원/kg) | 미나리_가격(원/kg) | 당근_가격(원/kg) | 파프리카_가격(원/kg) | 새송이_가격(원/kg) | 팽이버섯_가격(원/kg) | 토마토_가격(원/kg) | 청상추_가격(원/kg) | 백다다기_가격(원/kg) | 애호박_가격(원/kg) | 캠벨얼리_가격(원/kg) | 샤인마스캇_가격(원/kg) | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 801.0 | 756.0 | 605.0 | 10578.0 | 3012.0 | 985.0 | 828.0 | 659.0 | 5063.0 | 1819.0 | 4129.0 | 1033.0 | 3519.0 | 2100.0 | 1824.0 | 2484.0 | 1891.0 | 2326.0 | 1188.0 | 2713.0 | 12498.0 |
1 | 767.0 | 762.0 | 638.0 | 22227.5 | 3048.0 | 990.0 | 869.0 | 666.0 | 5005.0 | 1809.0 | 4508.0 | 935.0 | 3206.0 | 2102.0 | 1876.0 | 2286.0 | 1930.0 | 2166.0 | 1174.0 | 2872.0 | 12144.0 |
2 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 277.0 | 0.0 | 984.5 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
3 | 767.0 | 869.0 | 649.0 | 10671.0 | 3007.0 | 1076.0 | 972.0 | 677.0 | 5446.0 | 1984.0 | 4020.0 | 1239.0 | 2893.0 | 2139.0 | 1965.0 | 2518.0 | 1921.0 | 2369.0 | 1280.0 | 2921.0 | 12283.0 |
4 | 751.0 | 776.0 | 694.0 | 9958.0 | 3072.0 | 1202.0 | 1069.0 | 739.0 | 6128.0 | 1981.0 | 3804.0 | 1019.0 | 2821.0 | 2108.0 | 1948.0 | 2313.0 | 2063.0 | 2416.0 | 1404.0 | 3062.0 | 11628.0 |
예측값, 실제값 시각화¶
# n번째 날 기준 +1일 ~ +28일 예측값과 실제값 비교
plt.figure(figsize = (15, 6))
plt.plot(df1.iloc[:,0], label = '예측값')
plt.plot(real.iloc[:,0], label = '실제값')
plt.title('배추 실제, 예측값 비교')
plt.legend()
plt.show()
Report¶
- LSTM으로 예측한 결과 값은 배추의 가격으로 보았을 때 비교적 예측이 잘되었다. 평균 설명력은 -0.12, 평균 MSE는 0.023이 나왔다. 특이한 점은 이상치를 제거 했을 때 배추의 예측력이 더 떨어졌다는 것이다. 기존 배추의 이상치들이 실제 시장의 가격으로써
GRU¶
Keras GRU 또한 Tensor 형태의 3차원을 위한 Reshape 과정을 진행해야 한다.
3.3.3 이상치를 제거하지 않고 GRU 수행¶
GRU 사용을 위한 데이터 다시 불러오기¶
data = pd.read_csv('data/public_data/train.csv')
data['date'] = pd.to_datetime(data['date'])
요일 칼럼을 숫자로 변환¶
week_day_map = {}
for i, d in enumerate(data['요일'].unique()):
week_day_map[d] = i
data['요일'] = data['요일'].map(week_day_map)
데이터 정규화¶
norm = data.iloc[:, 1:].max(0)
data.iloc[:, 1:] = data.iloc[:, 1:] / norm
3차원 데이터로 변경¶
x_data = [] # feature
y_data = [] # label
for i in range(data.shape[0]-window_size-future_size):
x = data.iloc[i:i+window_size, 1:].to_numpy() # [요일, 농산물1거래량, 농산물1가격, 농산물2거래량, ......]
y = data.iloc[i+window_size:i+window_size+future_size, 3::2].to_numpy() # [농산물1가격, 농산물2가격, ....]
#y_0 = np.zeros([1, y.shape[1]]) # 디코더 첫 입력값 추가
x_data.append(x)
#y_data.append(np.concatenate([y_0, y], axis=0))
y_data.append(y)
x_data = np.array(x_data)
y_data = np.array(y_data)
x_data_train, x_data_test = x_data[:1400], x_data[1400:]
y_data_train, y_data_test = y_data[:1400], y_data[1400:]
GRU 모델 생성¶
model = Sequential()
model.add(GRU(400, activation = 'relu', input_shape = (28 ,43), return_sequences=True)) # 타임 스텝, 속성 (timesteps, n_features)
model.add(GRU(300, activation = 'relu', return_sequences=True))
model.add(Dropout(0.2))
model.add(Dense(200, activation = 'leaky_relu'))
model.add(Dense(100, activation = 'leaky_relu'))
model.add(Dropout(0.2))
model.add(Dense(21))
model.summary()
WARNING:tensorflow:Layer gru will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer gru_1 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. Model: "sequential_2" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= gru (GRU) (None, 28, 400) 534000 _________________________________________________________________ gru_1 (GRU) (None, 28, 300) 631800 _________________________________________________________________ dropout_6 (Dropout) (None, 28, 300) 0 _________________________________________________________________ dense_7 (Dense) (None, 28, 200) 60200 _________________________________________________________________ dense_8 (Dense) (None, 28, 100) 20100 _________________________________________________________________ dropout_7 (Dropout) (None, 28, 100) 0 _________________________________________________________________ dense_9 (Dense) (None, 28, 21) 2121 ================================================================= Total params: 1,248,221 Trainable params: 1,248,221 Non-trainable params: 0 _________________________________________________________________
optimizer = RMSprop(learning_rate=0.001)
es = EarlyStopping(monitor='val_loss', patience=5)
model.compile(loss='mse', optimizer=optimizer, metrics=['mse'])
history = model.fit(x_data_train, y_data_train, epochs=100, batch_size=BATCH_SIZE, validation_split=0.3, verbose=1, callbacks=[es])
Epoch 1/100 8/8 [==============================] - 6s 461ms/step - loss: 0.0693 - mse: 0.0693 - val_loss: 0.0270 - val_mse: 0.0270 Epoch 2/100 8/8 [==============================] - 3s 404ms/step - loss: 0.0366 - mse: 0.0366 - val_loss: 0.0256 - val_mse: 0.0256 Epoch 3/100 8/8 [==============================] - 3s 403ms/step - loss: 0.0323 - mse: 0.0323 - val_loss: 0.0264 - val_mse: 0.0264 Epoch 4/100 8/8 [==============================] - 3s 397ms/step - loss: 0.0298 - mse: 0.0298 - val_loss: 0.0235 - val_mse: 0.0235 Epoch 5/100 8/8 [==============================] - 3s 424ms/step - loss: 0.0262 - mse: 0.0262 - val_loss: 0.0205 - val_mse: 0.0205 Epoch 6/100 8/8 [==============================] - 3s 405ms/step - loss: 0.0239 - mse: 0.0239 - val_loss: 0.0200 - val_mse: 0.0200 Epoch 7/100 8/8 [==============================] - 3s 419ms/step - loss: 0.0224 - mse: 0.0224 - val_loss: 0.0188 - val_mse: 0.0188 Epoch 8/100 8/8 [==============================] - 3s 436ms/step - loss: 0.0210 - mse: 0.0210 - val_loss: 0.0191 - val_mse: 0.0191 Epoch 9/100 8/8 [==============================] - 3s 436ms/step - loss: 0.0198 - mse: 0.0198 - val_loss: 0.0169 - val_mse: 0.0169 Epoch 10/100 8/8 [==============================] - 3s 420ms/step - loss: 0.0203 - mse: 0.0203 - val_loss: 0.0173 - val_mse: 0.0173 Epoch 11/100 8/8 [==============================] - 4s 441ms/step - loss: 0.0179 - mse: 0.0179 - val_loss: 0.0174 - val_mse: 0.0174 Epoch 12/100 8/8 [==============================] - 3s 401ms/step - loss: 0.0172 - mse: 0.0172 - val_loss: 0.0200 - val_mse: 0.0200 Epoch 13/100 8/8 [==============================] - 3s 403ms/step - loss: 0.0178 - mse: 0.0178 - val_loss: 0.0178 - val_mse: 0.0178 Epoch 14/100 8/8 [==============================] - 3s 435ms/step - loss: 0.0166 - mse: 0.0166 - val_loss: 0.0179 - val_mse: 0.0179
print(model.evaluate(x_data_test, y_data_test))
9/9 [==============================] - 0s 45ms/step - loss: 0.0230 - mse: 0.0230 [0.02304500713944435, 0.023045005276799202]
loss 변화과정 시각화¶
epochs = range(1, len(history.history['loss']) + 1)
plt.plot(epochs, history.history['loss'], c = 'r', label = 'loss')
plt.plot(epochs, history.history['val_loss'], label = 'val_loss')
plt.xlabel('epochs')
plt.ylabel('loss')
plt.legend()
plt.show()
모델 평균 설명력 확인¶
pred = model.predict(x_data_test)
r2_list = []
mae_list = []
mse_list = []
for i in range(len(y_data_test)):
r2 = r2_score(y_data_test[i], pred[i])
r2_list.append(r2)
mae = mean_absolute_error(y_data_test[i], pred[i])
mae_list.append(mae)
mse = mean_squared_error(y_data_test[i], pred[i])
mse_list.append(mse)
print('평균 r2', np.mean(r2_list))
print('평균 mae', np.mean(mae_list))
print('평균 mse', np.mean(mse_list))
평균 r2 -0.24365051199052104 평균 mae 0.1019172725788527 평균 mse 0.02304500658444359
설명력 그래프¶
plt.plot(r2_list)
plt.title('test data 예측 설명력')
plt.show()
예측값, 실제값 비교¶
# 예측 값 가격 (바로 밑행에 pred(n) -> n+1번째 날 기준 예측 가격) (n = 1이면 test 데이터셋의 2~29일 예측)
df1 = pd.DataFrame(pred[0], columns = ['배추_가격(원/kg)', '무_가격(원/kg)', '양파_가격(원/kg)', '건고추_가격(원/kg)',
'마늘_가격(원/kg)', '대파_가격(원/kg)', '얼갈이배추_가격(원/kg)', '양배추_가격(원/kg)',
'깻잎_가격(원/kg)', '시금치_가격(원/kg)', '미나리_가격(원/kg)', '당근_가격(원/kg)',
'파프리카_가격(원/kg)', '새송이_가격(원/kg)', '팽이버섯_가격(원/kg)', '토마토_가격(원/kg)',
'청상추_가격(원/kg)', '백다다기_가격(원/kg)', '애호박_가격(원/kg)', '캠벨얼리_가격(원/kg)',
'샤인마스캇_가격(원/kg)'])
norm_price = norm[2::2] # 정규화 풀어주기 위해 가격부분 정규화만 뽑기
norm_df = pd.DataFrame(norm_price).T
df1 = df1.multiply(norm_df.values)
df1.head()
배추_가격(원/kg) | 무_가격(원/kg) | 양파_가격(원/kg) | 건고추_가격(원/kg) | 마늘_가격(원/kg) | 대파_가격(원/kg) | 얼갈이배추_가격(원/kg) | 양배추_가격(원/kg) | 깻잎_가격(원/kg) | 시금치_가격(원/kg) | 미나리_가격(원/kg) | 당근_가격(원/kg) | 파프리카_가격(원/kg) | 새송이_가격(원/kg) | 팽이버섯_가격(원/kg) | 토마토_가격(원/kg) | 청상추_가격(원/kg) | 백다다기_가격(원/kg) | 애호박_가격(원/kg) | 캠벨얼리_가격(원/kg) | 샤인마스캇_가격(원/kg) | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 695.3 | 674.1 | 841.9 | 9807.3 | 4612.4 | 1541.0 | 1076.5 | 720.3 | 5131.2 | 3020.0 | 2825.8 | 1127.2 | 3394.5 | 2166.8 | 1661.3 | 2179.0 | 3403.1 | 1706.6 | 1749.2 | 2965.3 | 6080.2 |
1 | 736.3 | 716.8 | 859.6 | 11258.2 | 4813.3 | 1641.6 | 1080.2 | 774.3 | 5376.4 | 3078.1 | 2990.0 | 1210.5 | 3567.1 | 2257.3 | 1788.6 | 2376.0 | 3421.5 | 1745.6 | 1813.7 | 2877.0 | 6338.2 |
2 | 106.5 | 53.7 | 35.9 | 1683.4 | 160.4 | 120.2 | 26.4 | 40.5 | 412.6 | 262.0 | 133.1 | 66.3 | 9.7 | 119.4 | 98.8 | 189.0 | 120.7 | 48.8 | 115.3 | 3.4 | -230.5 |
3 | 724.7 | 744.8 | 888.8 | 11682.7 | 5032.5 | 1749.2 | 1129.7 | 825.9 | 5520.2 | 3293.8 | 3224.0 | 1280.6 | 3787.4 | 2382.2 | 1917.8 | 2493.7 | 3444.1 | 1814.0 | 1912.2 | 2799.9 | 6447.9 |
4 | 735.0 | 744.0 | 880.8 | 12361.4 | 5003.0 | 1728.6 | 1092.9 | 820.9 | 5539.4 | 3280.0 | 3215.5 | 1285.3 | 3745.8 | 2345.1 | 1888.0 | 2500.1 | 3324.5 | 1822.2 | 1897.8 | 2602.7 | 6444.5 |
# 실제값 가격 (바로 밑행에 y_data_test[n] -> n+1번째 날 기준 가격) (n = 0 이면 y_data_test 데이터셋의 1~28일 값)
real = pd.DataFrame(y_data_test[0], columns = ['배추_가격(원/kg)', '무_가격(원/kg)', '양파_가격(원/kg)', '건고추_가격(원/kg)',
'마늘_가격(원/kg)', '대파_가격(원/kg)', '얼갈이배추_가격(원/kg)', '양배추_가격(원/kg)',
'깻잎_가격(원/kg)', '시금치_가격(원/kg)', '미나리_가격(원/kg)', '당근_가격(원/kg)',
'파프리카_가격(원/kg)', '새송이_가격(원/kg)', '팽이버섯_가격(원/kg)', '토마토_가격(원/kg)',
'청상추_가격(원/kg)', '백다다기_가격(원/kg)', '애호박_가격(원/kg)', '캠벨얼리_가격(원/kg)',
'샤인마스캇_가격(원/kg)'])
real = real.multiply(norm_price.values)
real.head()
배추_가격(원/kg) | 무_가격(원/kg) | 양파_가격(원/kg) | 건고추_가격(원/kg) | 마늘_가격(원/kg) | 대파_가격(원/kg) | 얼갈이배추_가격(원/kg) | 양배추_가격(원/kg) | 깻잎_가격(원/kg) | 시금치_가격(원/kg) | 미나리_가격(원/kg) | 당근_가격(원/kg) | 파프리카_가격(원/kg) | 새송이_가격(원/kg) | 팽이버섯_가격(원/kg) | 토마토_가격(원/kg) | 청상추_가격(원/kg) | 백다다기_가격(원/kg) | 애호박_가격(원/kg) | 캠벨얼리_가격(원/kg) | 샤인마스캇_가격(원/kg) | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 801.0 | 756.0 | 605.0 | 10578.0 | 3012.0 | 985.0 | 828.0 | 659.0 | 5063.0 | 1819.0 | 4129.0 | 1033.0 | 3519.0 | 2100.0 | 1824.0 | 2484.0 | 1891.0 | 2326.0 | 1188.0 | 2713.0 | 12498.0 |
1 | 767.0 | 762.0 | 638.0 | 22637.0 | 3048.0 | 990.0 | 869.0 | 666.0 | 5005.0 | 1809.0 | 4508.0 | 935.0 | 3206.0 | 2102.0 | 1876.0 | 2286.0 | 1930.0 | 2166.0 | 1174.0 | 2872.0 | 12144.0 |
2 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
3 | 767.0 | 869.0 | 649.0 | 10671.0 | 3007.0 | 1076.0 | 972.0 | 677.0 | 5446.0 | 1984.0 | 4020.0 | 1239.0 | 2893.0 | 2139.0 | 1965.0 | 2518.0 | 1921.0 | 2369.0 | 1280.0 | 2921.0 | 12283.0 |
4 | 751.0 | 776.0 | 694.0 | 9958.0 | 3072.0 | 1202.0 | 1069.0 | 739.0 | 6128.0 | 1981.0 | 3804.0 | 1019.0 | 2821.0 | 2108.0 | 1948.0 | 2313.0 | 2063.0 | 2416.0 | 1404.0 | 3062.0 | 11628.0 |
예측값, 실제값 시각화¶
# n번째 날 기준 +1일 ~ +28일 예측값과 실제값 비교
plt.figure(figsize = (15, 6))
plt.plot(df1.iloc[:,0], label = '예측값')
plt.plot(real.iloc[:,0], label = '실제값')
plt.title('배추 실제, 예측값 비교')
plt.legend()
plt.show()
3.2.4 이상치 제거 후 GRU 수행¶
GRU 사용을 위한 데이터 다시 불러오기¶
data = pd.read_csv('data/public_data/train.csv')
data['date'] = pd.to_datetime(data['date'])
volume = data.iloc[:, [0,1,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42]]
price = data.iloc[:, [0,1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43]]
이상치 제거¶
pri_columns = price.columns[2:]
def get_outlier(df, column):
q1, q3 = np.percentile(df[column], [25, 75])
iqr = q3 - q1
lower_bound = q1 - (iqr * 1.5)
upper_bound = q3 + (iqr * 1.5)
outindex_upper = np.where((df[column] > upper_bound))
outindex_lower = np.where((df[column] < lower_bound))
return outindex_upper, outindex_lower, upper_bound, lower_bound
for i in pri_columns:
outindex_upper, outindex_lower, upper_bound, lower_bound = get_outlier(price, i)
data[i] = data[i].replace(price.loc[outindex_upper][i].values, upper_bound)
data[i] = data[i].replace(price.loc[outindex_lower][i].values, lower_bound)
요일 칼럼을 숫자로 변환¶
week_day_map = {}
for i, d in enumerate(data['요일'].unique()):
week_day_map[d] = i
data['요일'] = data['요일'].map(week_day_map)
데이터 정규화¶
norm = data.iloc[:, 1:].max(0)
data.iloc[:, 1:] = data.iloc[:, 1:] / norm
3차원 데이터로 변경¶
x_data = [] # feature
y_data = [] # label
for i in range(data.shape[0]-window_size-future_size):
x = data.iloc[i:i+window_size, 1:].to_numpy() # [요일, 농산물1거래량, 농산물1가격, 농산물2거래량, ......]
y = data.iloc[i+window_size:i+window_size+future_size, 3::2].to_numpy() # [농산물1가격, 농산물2가격, ....]
#y_0 = np.zeros([1, y.shape[1]]) # 디코더 첫 입력값 추가
x_data.append(x)
#y_data.append(np.concatenate([y_0, y], axis=0))
y_data.append(y)
x_data = np.array(x_data)
y_data = np.array(y_data)
x_data_train, x_data_test = x_data[:1400], x_data[1400:]
y_data_train, y_data_test = y_data[:1400], y_data[1400:]
print(x_data_train.shape, ' ', x_data_test.shape)
print(y_data_train.shape, ' ', y_data_test.shape)
(1400, 28, 43) (277, 28, 43) (1400, 28, 21) (277, 28, 21)
GRU 모델 생성¶
model = Sequential()
model.add(GRU(400, activation = 'relu', input_shape = (28 ,43), return_sequences=True)) # 타임 스텝, 속성 (timesteps, n_features)
model.add(Dropout(0.3))
model.add(GRU(300, activation = 'leaky_relu', return_sequences=True))
model.add(Dropout(0.3))
model.add(Dense(200, activation = 'leaky_relu'))
model.add(Dropout(0.3))
model.add(Dense(100, activation = 'leaky_relu'))
model.add(Dropout(0.3))
model.add(Dense(21))
model.summary()
WARNING:tensorflow:Layer gru_2 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer gru_3 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. Model: "sequential_3" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= gru_2 (GRU) (None, 28, 400) 534000 _________________________________________________________________ dropout_8 (Dropout) (None, 28, 400) 0 _________________________________________________________________ gru_3 (GRU) (None, 28, 300) 631800 _________________________________________________________________ dropout_9 (Dropout) (None, 28, 300) 0 _________________________________________________________________ dense_10 (Dense) (None, 28, 200) 60200 _________________________________________________________________ dropout_10 (Dropout) (None, 28, 200) 0 _________________________________________________________________ dense_11 (Dense) (None, 28, 100) 20100 _________________________________________________________________ dropout_11 (Dropout) (None, 28, 100) 0 _________________________________________________________________ dense_12 (Dense) (None, 28, 21) 2121 ================================================================= Total params: 1,248,221 Trainable params: 1,248,221 Non-trainable params: 0 _________________________________________________________________
optimizer = RMSprop(learning_rate=0.001)
es = EarlyStopping(monitor='val_loss', patience=5)
model.compile(loss='mse', optimizer=optimizer, metrics=['mse'])
history = model.fit(x_data_train, y_data_train, epochs=100, batch_size=BATCH_SIZE, validation_split=0.3, verbose=1, callbacks=[es])
Epoch 1/100 8/8 [==============================] - 6s 455ms/step - loss: 0.1774 - mse: 0.1774 - val_loss: 0.0716 - val_mse: 0.0716 Epoch 2/100 8/8 [==============================] - 3s 413ms/step - loss: 0.0900 - mse: 0.0900 - val_loss: 0.0693 - val_mse: 0.0693 Epoch 3/100 8/8 [==============================] - 3s 434ms/step - loss: 0.0789 - mse: 0.0789 - val_loss: 0.0684 - val_mse: 0.0684 Epoch 4/100 8/8 [==============================] - 3s 395ms/step - loss: 0.0698 - mse: 0.0698 - val_loss: 0.0484 - val_mse: 0.0484 Epoch 5/100 8/8 [==============================] - 3s 423ms/step - loss: 0.0611 - mse: 0.0611 - val_loss: 0.0612 - val_mse: 0.0612 Epoch 6/100 8/8 [==============================] - 3s 424ms/step - loss: 0.0583 - mse: 0.0583 - val_loss: 0.0387 - val_mse: 0.0387 Epoch 7/100 8/8 [==============================] - 3s 431ms/step - loss: 0.0514 - mse: 0.0514 - val_loss: 0.0440 - val_mse: 0.0440 Epoch 8/100 8/8 [==============================] - 3s 426ms/step - loss: 0.0464 - mse: 0.0464 - val_loss: 0.0413 - val_mse: 0.0413 Epoch 9/100 8/8 [==============================] - 3s 419ms/step - loss: 0.0499 - mse: 0.0499 - val_loss: 0.0345 - val_mse: 0.0345 Epoch 10/100 8/8 [==============================] - 3s 401ms/step - loss: 0.0414 - mse: 0.0414 - val_loss: 0.0383 - val_mse: 0.0383 Epoch 11/100 8/8 [==============================] - 3s 421ms/step - loss: 0.0404 - mse: 0.0404 - val_loss: 0.0436 - val_mse: 0.0436 Epoch 12/100 8/8 [==============================] - 3s 404ms/step - loss: 0.0400 - mse: 0.0400 - val_loss: 0.0373 - val_mse: 0.0373 Epoch 13/100 8/8 [==============================] - 3s 418ms/step - loss: 0.0378 - mse: 0.0378 - val_loss: 0.0391 - val_mse: 0.0391 Epoch 14/100 8/8 [==============================] - 3s 418ms/step - loss: 0.0380 - mse: 0.0380 - val_loss: 0.0306 - val_mse: 0.0306 Epoch 15/100 8/8 [==============================] - 3s 441ms/step - loss: 0.0361 - mse: 0.0361 - val_loss: 0.0324 - val_mse: 0.0324 Epoch 16/100 8/8 [==============================] - 4s 448ms/step - loss: 0.0310 - mse: 0.0310 - val_loss: 0.0379 - val_mse: 0.0379 Epoch 17/100 8/8 [==============================] - 3s 413ms/step - loss: 0.0344 - mse: 0.0344 - val_loss: 0.0316 - val_mse: 0.0316 Epoch 18/100 8/8 [==============================] - 3s 440ms/step - loss: 0.0312 - mse: 0.0312 - val_loss: 0.0308 - val_mse: 0.0308 Epoch 19/100 8/8 [==============================] - 3s 435ms/step - loss: 0.0311 - mse: 0.0311 - val_loss: 0.0378 - val_mse: 0.0378
print(model.evaluate(x_data_test, y_data_test))
9/9 [==============================] - 0s 40ms/step - loss: 0.0628 - mse: 0.0628 [0.06277406960725784, 0.06277406960725784]
loss 변화과정 시각화¶
epochs = range(1, len(history.history['loss']) + 1)
plt.plot(epochs, history.history['loss'], c = 'r', label = 'loss')
plt.plot(epochs, history.history['val_loss'], label = 'val_loss')
plt.xlabel('epochs')
plt.ylabel('loss')
plt.legend()
plt.show()
모델 평균 설명력 확인¶
pred = model.predict(x_data_test)
r2_list = []
mae_list = []
mse_list = []
for i in range(len(y_data_test)):
r2 = r2_score(y_data_test[i], pred[i])
r2_list.append(r2)
mae = mean_absolute_error(y_data_test[i], pred[i])
mae_list.append(mae)
mse = mean_squared_error(y_data_test[i], pred[i])
mse_list.append(mse)
print('평균 r2', np.mean(r2_list))
print('평균 mae', np.mean(mae_list))
print('평균 mse', np.mean(mse_list))
평균 r2 -0.09565668260397646 평균 mae 0.18290322829276673 평균 mse 0.06277407058599194
설명력 그래프¶
plt.plot(r2_list)
plt.title('test data 예측 설명력')
plt.show()
예측값, 실제값 비교¶
# 예측 값 가격 (바로 밑행에 pred(n) -> n+1번째 날 기준 예측 가격) (n = 1이면 test 데이터셋의 2~29일 예측)
df1 = pd.DataFrame(pred[0], columns = ['배추_가격(원/kg)', '무_가격(원/kg)', '양파_가격(원/kg)', '건고추_가격(원/kg)',
'마늘_가격(원/kg)', '대파_가격(원/kg)', '얼갈이배추_가격(원/kg)', '양배추_가격(원/kg)',
'깻잎_가격(원/kg)', '시금치_가격(원/kg)', '미나리_가격(원/kg)', '당근_가격(원/kg)',
'파프리카_가격(원/kg)', '새송이_가격(원/kg)', '팽이버섯_가격(원/kg)', '토마토_가격(원/kg)',
'청상추_가격(원/kg)', '백다다기_가격(원/kg)', '애호박_가격(원/kg)', '캠벨얼리_가격(원/kg)',
'샤인마스캇_가격(원/kg)'])
norm_price = norm[2::2] # 정규화 풀어주기 위해 가격부분 정규화만 뽑기
norm_df = pd.DataFrame(norm_price).T
df1 = df1.multiply(norm_df.values)
df1.head()
배추_가격(원/kg) | 무_가격(원/kg) | 양파_가격(원/kg) | 건고추_가격(원/kg) | 마늘_가격(원/kg) | 대파_가격(원/kg) | 얼갈이배추_가격(원/kg) | 양배추_가격(원/kg) | 깻잎_가격(원/kg) | 시금치_가격(원/kg) | 미나리_가격(원/kg) | 당근_가격(원/kg) | 파프리카_가격(원/kg) | 새송이_가격(원/kg) | 팽이버섯_가격(원/kg) | 토마토_가격(원/kg) | 청상추_가격(원/kg) | 백다다기_가격(원/kg) | 애호박_가격(원/kg) | 캠벨얼리_가격(원/kg) | 샤인마스캇_가격(원/kg) | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 507.2 | 512.2 | 671.9 | 6558.4 | 3638.4 | 1145.2 | 697.5 | 531.5 | 3862.2 | 1546.4 | 1783.1 | 923.3 | 2682.5 | 1802.6 | 1287.6 | 1731.6 | 1881.3 | 1351.3 | 1346.7 | 2750.8 | 3135.8 |
1 | 469.6 | 493.1 | 635.3 | 5887.0 | 3467.6 | 1097.7 | 631.0 | 506.1 | 3638.1 | 1392.7 | 1607.4 | 908.0 | 2549.2 | 1731.4 | 1214.0 | 1653.8 | 1649.4 | 1277.1 | 1260.8 | 2588.2 | 2684.5 |
2 | 71.7 | 65.3 | 66.0 | 615.6 | 358.7 | 140.1 | 23.5 | 85.6 | 367.4 | 212.1 | 170.0 | 316.5 | 254.5 | 874.1 | 198.2 | 210.8 | 27.9 | 163.5 | 177.6 | 354.5 | 533.7 |
3 | 474.7 | 498.7 | 665.4 | 5607.2 | 3508.4 | 1156.7 | 639.3 | 542.3 | 3752.2 | 1342.4 | 1699.2 | 950.6 | 2751.7 | 1806.9 | 1284.7 | 1719.4 | 1505.3 | 1307.0 | 1328.4 | 2643.3 | 2102.4 |
4 | 510.4 | 549.9 | 716.8 | 6148.2 | 3770.6 | 1249.0 | 697.0 | 573.8 | 4016.3 | 1434.0 | 1821.7 | 1004.5 | 2959.7 | 1895.8 | 1354.9 | 1899.8 | 1563.7 | 1424.8 | 1432.8 | 2798.9 | 2114.7 |
# 실제값 가격 (바로 밑행에 y_data_test[n] -> n+1번째 날 기준 가격) (n = 0 이면 y_data_test 데이터셋의 1~28일 값)
real = pd.DataFrame(y_data_test[0], columns = ['배추_가격(원/kg)', '무_가격(원/kg)', '양파_가격(원/kg)', '건고추_가격(원/kg)',
'마늘_가격(원/kg)', '대파_가격(원/kg)', '얼갈이배추_가격(원/kg)', '양배추_가격(원/kg)',
'깻잎_가격(원/kg)', '시금치_가격(원/kg)', '미나리_가격(원/kg)', '당근_가격(원/kg)',
'파프리카_가격(원/kg)', '새송이_가격(원/kg)', '팽이버섯_가격(원/kg)', '토마토_가격(원/kg)',
'청상추_가격(원/kg)', '백다다기_가격(원/kg)', '애호박_가격(원/kg)', '캠벨얼리_가격(원/kg)',
'샤인마스캇_가격(원/kg)'])
real = real.multiply(norm_price.values)
real.head()
배추_가격(원/kg) | 무_가격(원/kg) | 양파_가격(원/kg) | 건고추_가격(원/kg) | 마늘_가격(원/kg) | 대파_가격(원/kg) | 얼갈이배추_가격(원/kg) | 양배추_가격(원/kg) | 깻잎_가격(원/kg) | 시금치_가격(원/kg) | 미나리_가격(원/kg) | 당근_가격(원/kg) | 파프리카_가격(원/kg) | 새송이_가격(원/kg) | 팽이버섯_가격(원/kg) | 토마토_가격(원/kg) | 청상추_가격(원/kg) | 백다다기_가격(원/kg) | 애호박_가격(원/kg) | 캠벨얼리_가격(원/kg) | 샤인마스캇_가격(원/kg) | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 801.0 | 756.0 | 605.0 | 10578.0 | 3012.0 | 985.0 | 828.0 | 659.0 | 5063.0 | 1819.0 | 4129.0 | 1033.0 | 3519.0 | 2100.0 | 1824.0 | 2484.0 | 1891.0 | 2326.0 | 1188.0 | 2713.0 | 12498.0 |
1 | 767.0 | 762.0 | 638.0 | 22227.5 | 3048.0 | 990.0 | 869.0 | 666.0 | 5005.0 | 1809.0 | 4508.0 | 935.0 | 3206.0 | 2102.0 | 1876.0 | 2286.0 | 1930.0 | 2166.0 | 1174.0 | 2872.0 | 12144.0 |
2 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 277.0 | 0.0 | 984.5 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
3 | 767.0 | 869.0 | 649.0 | 10671.0 | 3007.0 | 1076.0 | 972.0 | 677.0 | 5446.0 | 1984.0 | 4020.0 | 1239.0 | 2893.0 | 2139.0 | 1965.0 | 2518.0 | 1921.0 | 2369.0 | 1280.0 | 2921.0 | 12283.0 |
4 | 751.0 | 776.0 | 694.0 | 9958.0 | 3072.0 | 1202.0 | 1069.0 | 739.0 | 6128.0 | 1981.0 | 3804.0 | 1019.0 | 2821.0 | 2108.0 | 1948.0 | 2313.0 | 2063.0 | 2416.0 | 1404.0 | 3062.0 | 11628.0 |
예측값, 실제값 시각화¶
# n번째 날 기준 +1일 ~ +28일 예측값과 실제값 비교
plt.figure(figsize = (15, 6))
plt.plot(df1.iloc[:,0], label = '예측값')
plt.plot(real.iloc[:,0], label = '실제값')
plt.title('배추 실제, 예측값 비교')
plt.legend()
plt.show()
Report¶
- 양파, 무, 배추 순으로 거래량이 많다.
- 월요일에 거래시장이 제일 활발하고 날이 지날수록 점점 떨어져서 토요일에는 거래량이 제일 작다.
3.3 예측 방법 개선 (농산물 개별 예측)¶
21개 농산물을 한 번에 예측한 결과가 좋지 못했기 때문에 농산물 개별 예측 후 이를 합쳐 이전과 같은 방법으로 예측을 진행.¶
LSTM 개별 예측¶
LSTM 개별 예측을 위한 데이터 다시 불러오기¶
data = pd.read_csv('data/public_data/train.csv')
data['date'] = pd.to_datetime(data['date'])
volume = data.iloc[:, [0,1,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42]]
price = data.iloc[:, [0,1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43]]
이상치 제거¶
# pri_columns = price.columns[2:]
# def get_outlier(df, column):
# q1, q3 = np.percentile(df[column], [25, 75])
# iqr = q3 - q1
# lower_bound = q1 - (iqr * 1.5)
# upper_bound = q3 + (iqr * 1.5)
# outindex_upper = np.where((df[column] > upper_bound))
# outindex_lower = np.where((df[column] < lower_bound))
# return outindex_upper, outindex_lower, upper_bound, lower_bound
# for i in pri_columns:
# outindex_upper, outindex_lower, upper_bound, lower_bound = get_outlier(price, i)
# data[i] = data[i].replace(price.loc[outindex_upper][i].values, upper_bound)
# data[i] = data[i].replace(price.loc[outindex_lower][i].values, lower_bound)
칼럼명에서 불필요한 부분 제거¶
columns = data.columns
imsi = []
for column in columns:
column = column.replace("(", "").replace(")", "").replace("kg", "").replace("_", "").replace("/", "").replace("원", "")
imsi.append(column)
data.columns = imsi
columns = [x[:-2].replace('_', '') for x in data.columns[3::2]]
print(columns)
['배추', '무', '양파', '건고추', '마늘', '대파', '얼갈이배추', '양배추', '깻잎', '시금치', '미나리', '당근', '파프리카', '새송이', '팽이버섯', '토마토', '청상추', '백다다기', '애호박', '캠벨얼리', '샤인마스캇']
요일 칼럼을 숫자로 변환¶
week_day_map = {}
for i, d in enumerate(data['요일'].unique()):
week_day_map[d] = i
data['요일'] = data['요일'].map(week_day_map)
데이터 정규화¶
norm = data.iloc[:, 1:].max(0)
data.iloc[:, 1:] = data.iloc[:, 1:] / norm
21개 농산물 개별 예측 수행¶
mean_r2_list = [] # 21개 농산물 평균 설명력
pred_dict = {} # key = i / value = pred 0 ~ 20
plt.figure(figsize=(20,20))
for i in range(21):
x_data = []
y_data = []
for j in range(data.shape[0] - window_size - future_size):
x = data.iloc[j:j+window_size, [1, i*2+2, i*2+3]].to_numpy()
y = data.iloc[j+window_size:j+window_size+future_size, i*2+3].to_numpy()
x_data.append(x)
y_data.append(y)
x_data = np.array(x_data)
y_data = np.array(y_data)
x_data_train, x_data_test = x_data[:1400], x_data[1400:] # (1400, 28, 3) (277, 28, 3)
y_data_train, y_data_test = y_data[:1400], y_data[1400:] # (1400, 28) (277, 28)
y_data_train = np.reshape(y_data_train, (y_data_train.shape[0], y_data_test.shape[1], 1))
y_data_test = np.reshape(y_data_test, (y_data_test.shape[0], y_data_test.shape[1], 1))
#print(x_data_train.shape, ' ', x_data_test.shape) : (1400, 28, 1)
#print(y_data_train.shape, ' ', y_data_test.shape) : (277, 28, 1)
model = Sequential()
model.add(LSTM(400, activation = 'leaky_relu', input_shape = (28 ,3), return_sequences=True))
model.add(Dropout(0.3))
model.add(LSTM(300, activation = 'leaky_relu', return_sequences=True))
model.add(Dropout(0.3))
model.add(LSTM(200, activation = 'leaky_relu', return_sequences=True))
model.add(Dropout(0.3))
model.add(Dense(100, activation = 'leaky_relu'))
model.add(Dense(50, activation = 'leaky_relu'))
model.add(Dropout(0.3))
model.add(Dense(1))
optimizer = Adam(learning_rate=0.01)
es = EarlyStopping(monitor='val_loss', patience=5)
model.compile(loss='mse', optimizer='adam', metrics=['mse'])
history = model.fit(x_data_train, y_data_train, epochs=100, batch_size=BATCH_SIZE,
validation_split=0.3, verbose=2, callbacks=[es])
print(f'{columns[i]} 농산물 evaluate : ', model.evaluate(x_data_test, y_data_test))
pred = model.predict(x_data_test) # (277, 28, 1)
pred_dict[i] = pred
r2_list = []
for z in range(len(y_data_test)):
r2 = r2_score(y_data_test[z], pred[z])
#print(r2)
r2_list.append(r2)
mean_r2_list.append(np.mean(r2_list))
plt.subplot(7, 3, i+1)
plt.plot(history.history['loss'], color="r", label = 'loss')
plt.plot(history.history['val_loss'], label = 'val_loss')
plt.title(f'{columns[i]} 농산물 평균 설명력 : {np.round(np.mean(r2_list), 2)}')
plt.xlabel('epochs')
plt.ylabel('loss')
plt.legend(loc = "best")
plt.tight_layout()
plt.show()
print(f'21개 농산물 총 평균 설명력: {np.mean(mean_r2_list)}')
WARNING:tensorflow:Layer lstm_5 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_6 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_7 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. Epoch 1/100 8/8 - 7s - loss: 0.0112 - mse: 0.0112 - val_loss: 0.0039 - val_mse: 0.0039 Epoch 2/100 8/8 - 4s - loss: 0.0070 - mse: 0.0070 - val_loss: 0.0053 - val_mse: 0.0053 Epoch 3/100 8/8 - 4s - loss: 0.0065 - mse: 0.0065 - val_loss: 0.0042 - val_mse: 0.0042 Epoch 4/100 8/8 - 4s - loss: 0.0065 - mse: 0.0065 - val_loss: 0.0049 - val_mse: 0.0049 Epoch 5/100 8/8 - 4s - loss: 0.0064 - mse: 0.0064 - val_loss: 0.0044 - val_mse: 0.0044 Epoch 6/100 8/8 - 4s - loss: 0.0064 - mse: 0.0064 - val_loss: 0.0050 - val_mse: 0.0050 9/9 [==============================] - 0s 53ms/step - loss: 0.0067 - mse: 0.0067 배추 농산물 evaluate : [0.006666901987046003, 0.006666901987046003] WARNING:tensorflow:Layer lstm_8 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_9 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_10 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. Epoch 1/100 8/8 - 7s - loss: 0.1352 - mse: 0.1352 - val_loss: 0.0336 - val_mse: 0.0336 Epoch 2/100 8/8 - 4s - loss: 0.0737 - mse: 0.0737 - val_loss: 0.0549 - val_mse: 0.0549 Epoch 3/100 8/8 - 4s - loss: 0.0624 - mse: 0.0624 - val_loss: 0.0347 - val_mse: 0.0347 Epoch 4/100 8/8 - 4s - loss: 0.0574 - mse: 0.0574 - val_loss: 0.0455 - val_mse: 0.0455 Epoch 5/100 8/8 - 4s - loss: 0.0551 - mse: 0.0551 - val_loss: 0.0387 - val_mse: 0.0387 Epoch 6/100 8/8 - 4s - loss: 0.0545 - mse: 0.0545 - val_loss: 0.0368 - val_mse: 0.0368 9/9 [==============================] - 0s 53ms/step - loss: 0.0451 - mse: 0.0451 무 농산물 evaluate : [0.04511337727308273, 0.04511337727308273] WARNING:tensorflow:Layer lstm_11 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_12 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_13 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. Epoch 1/100 8/8 - 7s - loss: 0.0876 - mse: 0.0876 - val_loss: 0.0148 - val_mse: 0.0148 Epoch 2/100 8/8 - 4s - loss: 0.0449 - mse: 0.0449 - val_loss: 0.0253 - val_mse: 0.0253 Epoch 3/100 8/8 - 4s - loss: 0.0381 - mse: 0.0381 - val_loss: 0.0255 - val_mse: 0.0255 Epoch 4/100 8/8 - 4s - loss: 0.0351 - mse: 0.0351 - val_loss: 0.0177 - val_mse: 0.0177 Epoch 5/100 8/8 - 4s - loss: 0.0338 - mse: 0.0338 - val_loss: 0.0173 - val_mse: 0.0173 Epoch 6/100 8/8 - 4s - loss: 0.0334 - mse: 0.0334 - val_loss: 0.0151 - val_mse: 0.0151 9/9 [==============================] - 1s 54ms/step - loss: 0.0252 - mse: 0.0252 양파 농산물 evaluate : [0.025228844955563545, 0.025228846818208694] WARNING:tensorflow:Layer lstm_14 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_15 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_16 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. Epoch 1/100 8/8 - 7s - loss: 0.0019 - mse: 0.0019 - val_loss: 0.0019 - val_mse: 0.0019 Epoch 2/100 8/8 - 4s - loss: 0.0015 - mse: 0.0015 - val_loss: 0.0019 - val_mse: 0.0019 Epoch 3/100 8/8 - 4s - loss: 0.0015 - mse: 0.0015 - val_loss: 0.0019 - val_mse: 0.0019 Epoch 4/100 8/8 - 4s - loss: 0.0015 - mse: 0.0015 - val_loss: 0.0020 - val_mse: 0.0020 Epoch 5/100 8/8 - 4s - loss: 0.0015 - mse: 0.0015 - val_loss: 0.0020 - val_mse: 0.0020 Epoch 6/100 8/8 - 4s - loss: 0.0015 - mse: 0.0015 - val_loss: 0.0019 - val_mse: 0.0019 9/9 [==============================] - 0s 50ms/step - loss: 0.0081 - mse: 0.0081 건고추 농산물 evaluate : [0.008084215223789215, 0.00808421429246664] WARNING:tensorflow:Layer lstm_17 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_18 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_19 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. Epoch 1/100 8/8 - 7s - loss: 0.3031 - mse: 0.3031 - val_loss: 0.0736 - val_mse: 0.0736 Epoch 2/100 8/8 - 4s - loss: 0.1492 - mse: 0.1492 - val_loss: 0.0910 - val_mse: 0.0910 Epoch 3/100 8/8 - 4s - loss: 0.1127 - mse: 0.1127 - val_loss: 0.0525 - val_mse: 0.0525 Epoch 4/100 8/8 - 4s - loss: 0.0982 - mse: 0.0982 - val_loss: 0.0686 - val_mse: 0.0686 Epoch 5/100 8/8 - 4s - loss: 0.0914 - mse: 0.0914 - val_loss: 0.0559 - val_mse: 0.0559 Epoch 6/100 8/8 - 4s - loss: 0.0882 - mse: 0.0882 - val_loss: 0.0638 - val_mse: 0.0638 Epoch 7/100 8/8 - 4s - loss: 0.0857 - mse: 0.0857 - val_loss: 0.0619 - val_mse: 0.0619 Epoch 8/100 8/8 - 4s - loss: 0.0845 - mse: 0.0845 - val_loss: 0.0560 - val_mse: 0.0560 9/9 [==============================] - 0s 54ms/step - loss: 0.0651 - mse: 0.0651 마늘 농산물 evaluate : [0.06509483605623245, 0.06509482860565186] WARNING:tensorflow:Layer lstm_20 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_21 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_22 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. Epoch 1/100 8/8 - 7s - loss: 0.1056 - mse: 0.1056 - val_loss: 0.0308 - val_mse: 0.0308 Epoch 2/100 8/8 - 4s - loss: 0.0601 - mse: 0.0601 - val_loss: 0.0282 - val_mse: 0.0282 Epoch 3/100 8/8 - 4s - loss: 0.0504 - mse: 0.0504 - val_loss: 0.0247 - val_mse: 0.0247 Epoch 4/100 8/8 - 4s - loss: 0.0473 - mse: 0.0473 - val_loss: 0.0244 - val_mse: 0.0244 Epoch 5/100 8/8 - 4s - loss: 0.0455 - mse: 0.0455 - val_loss: 0.0225 - val_mse: 0.0225 Epoch 6/100 8/8 - 4s - loss: 0.0440 - mse: 0.0440 - val_loss: 0.0212 - val_mse: 0.0212 Epoch 7/100 8/8 - 4s - loss: 0.0435 - mse: 0.0435 - val_loss: 0.0252 - val_mse: 0.0252 Epoch 8/100 8/8 - 4s - loss: 0.0438 - mse: 0.0438 - val_loss: 0.0238 - val_mse: 0.0238 Epoch 9/100 8/8 - 4s - loss: 0.0435 - mse: 0.0435 - val_loss: 0.0229 - val_mse: 0.0229 Epoch 10/100 8/8 - 4s - loss: 0.0422 - mse: 0.0422 - val_loss: 0.0219 - val_mse: 0.0219 Epoch 11/100 8/8 - 4s - loss: 0.0416 - mse: 0.0416 - val_loss: 0.0206 - val_mse: 0.0206 Epoch 12/100 8/8 - 4s - loss: 0.0406 - mse: 0.0406 - val_loss: 0.0194 - val_mse: 0.0194 Epoch 13/100 8/8 - 4s - loss: 0.0385 - mse: 0.0385 - val_loss: 0.0189 - val_mse: 0.0189 Epoch 14/100 8/8 - 4s - loss: 0.0376 - mse: 0.0376 - val_loss: 0.0195 - val_mse: 0.0195 Epoch 15/100 8/8 - 4s - loss: 0.0365 - mse: 0.0365 - val_loss: 0.0172 - val_mse: 0.0172 Epoch 16/100 8/8 - 4s - loss: 0.0352 - mse: 0.0352 - val_loss: 0.0151 - val_mse: 0.0151 Epoch 17/100 8/8 - 4s - loss: 0.0333 - mse: 0.0333 - val_loss: 0.0147 - val_mse: 0.0147 Epoch 18/100 8/8 - 4s - loss: 0.0312 - mse: 0.0312 - val_loss: 0.0124 - val_mse: 0.0124 Epoch 19/100 8/8 - 5s - loss: 0.0282 - mse: 0.0282 - val_loss: 0.0110 - val_mse: 0.0110 Epoch 20/100 8/8 - 5s - loss: 0.0255 - mse: 0.0255 - val_loss: 0.0107 - val_mse: 0.0107 Epoch 21/100 8/8 - 4s - loss: 0.0242 - mse: 0.0242 - val_loss: 0.0098 - val_mse: 0.0098 Epoch 22/100 8/8 - 4s - loss: 0.0231 - mse: 0.0231 - val_loss: 0.0080 - val_mse: 0.0080 Epoch 23/100 8/8 - 4s - loss: 0.0220 - mse: 0.0220 - val_loss: 0.0083 - val_mse: 0.0083 Epoch 24/100 8/8 - 4s - loss: 0.0218 - mse: 0.0218 - val_loss: 0.0078 - val_mse: 0.0078 Epoch 25/100 8/8 - 4s - loss: 0.0208 - mse: 0.0208 - val_loss: 0.0094 - val_mse: 0.0094 Epoch 26/100 8/8 - 4s - loss: 0.0202 - mse: 0.0202 - val_loss: 0.0081 - val_mse: 0.0081 Epoch 27/100 8/8 - 4s - loss: 0.0200 - mse: 0.0200 - val_loss: 0.0098 - val_mse: 0.0098 Epoch 28/100 8/8 - 4s - loss: 0.0197 - mse: 0.0197 - val_loss: 0.0082 - val_mse: 0.0082 Epoch 29/100 8/8 - 4s - loss: 0.0197 - mse: 0.0197 - val_loss: 0.0087 - val_mse: 0.0087 9/9 [==============================] - 1s 60ms/step - loss: 0.0127 - mse: 0.0127 대파 농산물 evaluate : [0.012655088678002357, 0.012655087746679783] WARNING:tensorflow:Layer lstm_23 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_24 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_25 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. Epoch 1/100 8/8 - 7s - loss: 0.0703 - mse: 0.0703 - val_loss: 0.0373 - val_mse: 0.0373 Epoch 2/100 8/8 - 4s - loss: 0.0403 - mse: 0.0403 - val_loss: 0.0273 - val_mse: 0.0273 Epoch 3/100 8/8 - 4s - loss: 0.0335 - mse: 0.0335 - val_loss: 0.0260 - val_mse: 0.0260 Epoch 4/100 8/8 - 4s - loss: 0.0307 - mse: 0.0307 - val_loss: 0.0256 - val_mse: 0.0256 Epoch 5/100 8/8 - 4s - loss: 0.0302 - mse: 0.0302 - val_loss: 0.0258 - val_mse: 0.0258 Epoch 6/100 8/8 - 4s - loss: 0.0297 - mse: 0.0297 - val_loss: 0.0256 - val_mse: 0.0256 Epoch 7/100 8/8 - 4s - loss: 0.0296 - mse: 0.0296 - val_loss: 0.0257 - val_mse: 0.0257 Epoch 8/100 8/8 - 4s - loss: 0.0294 - mse: 0.0294 - val_loss: 0.0257 - val_mse: 0.0257 Epoch 9/100 8/8 - 4s - loss: 0.0292 - mse: 0.0292 - val_loss: 0.0256 - val_mse: 0.0256 Epoch 10/100 8/8 - 4s - loss: 0.0289 - mse: 0.0289 - val_loss: 0.0255 - val_mse: 0.0255 Epoch 11/100 8/8 - 4s - loss: 0.0288 - mse: 0.0288 - val_loss: 0.0256 - val_mse: 0.0256 Epoch 12/100 8/8 - 4s - loss: 0.0287 - mse: 0.0287 - val_loss: 0.0258 - val_mse: 0.0258 Epoch 13/100 8/8 - 4s - loss: 0.0285 - mse: 0.0285 - val_loss: 0.0256 - val_mse: 0.0256 Epoch 14/100 8/8 - 4s - loss: 0.0284 - mse: 0.0284 - val_loss: 0.0255 - val_mse: 0.0255 Epoch 15/100 8/8 - 4s - loss: 0.0282 - mse: 0.0282 - val_loss: 0.0253 - val_mse: 0.0253 Epoch 16/100 8/8 - 4s - loss: 0.0277 - mse: 0.0277 - val_loss: 0.0254 - val_mse: 0.0254 Epoch 17/100 8/8 - 4s - loss: 0.0275 - mse: 0.0275 - val_loss: 0.0244 - val_mse: 0.0244 Epoch 18/100 8/8 - 4s - loss: 0.0268 - mse: 0.0268 - val_loss: 0.0237 - val_mse: 0.0237 Epoch 19/100 8/8 - 4s - loss: 0.0261 - mse: 0.0261 - val_loss: 0.0227 - val_mse: 0.0227 Epoch 20/100 8/8 - 4s - loss: 0.0257 - mse: 0.0257 - val_loss: 0.0223 - val_mse: 0.0223 Epoch 21/100 8/8 - 4s - loss: 0.0254 - mse: 0.0254 - val_loss: 0.0217 - val_mse: 0.0217 Epoch 22/100 8/8 - 4s - loss: 0.0250 - mse: 0.0250 - val_loss: 0.0210 - val_mse: 0.0210 Epoch 23/100 8/8 - 4s - loss: 0.0240 - mse: 0.0240 - val_loss: 0.0204 - val_mse: 0.0204 Epoch 24/100 8/8 - 4s - loss: 0.0235 - mse: 0.0235 - val_loss: 0.0199 - val_mse: 0.0199 Epoch 25/100 8/8 - 4s - loss: 0.0224 - mse: 0.0224 - val_loss: 0.0178 - val_mse: 0.0178 Epoch 26/100 8/8 - 4s - loss: 0.0207 - mse: 0.0207 - val_loss: 0.0162 - val_mse: 0.0162 Epoch 27/100 8/8 - 4s - loss: 0.0187 - mse: 0.0187 - val_loss: 0.0151 - val_mse: 0.0151 Epoch 28/100 8/8 - 4s - loss: 0.0174 - mse: 0.0174 - val_loss: 0.0147 - val_mse: 0.0147 Epoch 29/100 8/8 - 4s - loss: 0.0168 - mse: 0.0168 - val_loss: 0.0147 - val_mse: 0.0147 Epoch 30/100 8/8 - 4s - loss: 0.0162 - mse: 0.0162 - val_loss: 0.0148 - val_mse: 0.0148 Epoch 31/100 8/8 - 4s - loss: 0.0160 - mse: 0.0160 - val_loss: 0.0139 - val_mse: 0.0139 Epoch 32/100 8/8 - 4s - loss: 0.0156 - mse: 0.0156 - val_loss: 0.0141 - val_mse: 0.0141 Epoch 33/100 8/8 - 4s - loss: 0.0154 - mse: 0.0154 - val_loss: 0.0139 - val_mse: 0.0139 Epoch 34/100 8/8 - 4s - loss: 0.0153 - mse: 0.0153 - val_loss: 0.0152 - val_mse: 0.0152 Epoch 35/100 8/8 - 4s - loss: 0.0149 - mse: 0.0149 - val_loss: 0.0134 - val_mse: 0.0134 Epoch 36/100 8/8 - 4s - loss: 0.0148 - mse: 0.0148 - val_loss: 0.0138 - val_mse: 0.0138 Epoch 37/100 8/8 - 4s - loss: 0.0147 - mse: 0.0147 - val_loss: 0.0136 - val_mse: 0.0136 Epoch 38/100 8/8 - 4s - loss: 0.0146 - mse: 0.0146 - val_loss: 0.0141 - val_mse: 0.0141 Epoch 39/100 8/8 - 4s - loss: 0.0144 - mse: 0.0144 - val_loss: 0.0125 - val_mse: 0.0125 Epoch 40/100 8/8 - 4s - loss: 0.0141 - mse: 0.0141 - val_loss: 0.0132 - val_mse: 0.0132 Epoch 41/100 8/8 - 4s - loss: 0.0138 - mse: 0.0138 - val_loss: 0.0134 - val_mse: 0.0134 Epoch 42/100 8/8 - 4s - loss: 0.0137 - mse: 0.0137 - val_loss: 0.0162 - val_mse: 0.0162 Epoch 43/100 8/8 - 4s - loss: 0.0143 - mse: 0.0143 - val_loss: 0.0157 - val_mse: 0.0157 Epoch 44/100 8/8 - 4s - loss: 0.0135 - mse: 0.0135 - val_loss: 0.0161 - val_mse: 0.0161 9/9 [==============================] - 0s 50ms/step - loss: 0.0181 - mse: 0.0181 얼갈이배추 농산물 evaluate : [0.018090680241584778, 0.018090680241584778] WARNING:tensorflow:Layer lstm_26 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_27 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_28 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. Epoch 1/100 8/8 - 7s - loss: 0.1125 - mse: 0.1125 - val_loss: 0.0217 - val_mse: 0.0217 Epoch 2/100 8/8 - 4s - loss: 0.0665 - mse: 0.0665 - val_loss: 0.0210 - val_mse: 0.0210 Epoch 3/100 8/8 - 4s - loss: 0.0542 - mse: 0.0542 - val_loss: 0.0292 - val_mse: 0.0292 Epoch 4/100 8/8 - 4s - loss: 0.0498 - mse: 0.0498 - val_loss: 0.0215 - val_mse: 0.0215 Epoch 5/100 8/8 - 4s - loss: 0.0485 - mse: 0.0485 - val_loss: 0.0274 - val_mse: 0.0274 Epoch 6/100 8/8 - 4s - loss: 0.0470 - mse: 0.0470 - val_loss: 0.0232 - val_mse: 0.0232 Epoch 7/100 8/8 - 4s - loss: 0.0461 - mse: 0.0461 - val_loss: 0.0227 - val_mse: 0.0227 9/9 [==============================] - 1s 68ms/step - loss: 0.0638 - mse: 0.0638 양배추 농산물 evaluate : [0.06381167471408844, 0.06381167471408844] WARNING:tensorflow:Layer lstm_29 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_30 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_31 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. Epoch 1/100 8/8 - 7s - loss: 0.0705 - mse: 0.0705 - val_loss: 0.0404 - val_mse: 0.0404 Epoch 2/100 8/8 - 4s - loss: 0.0369 - mse: 0.0369 - val_loss: 0.0306 - val_mse: 0.0306 Epoch 3/100 8/8 - 4s - loss: 0.0322 - mse: 0.0322 - val_loss: 0.0289 - val_mse: 0.0289 Epoch 4/100 8/8 - 4s - loss: 0.0302 - mse: 0.0302 - val_loss: 0.0289 - val_mse: 0.0289 Epoch 5/100 8/8 - 4s - loss: 0.0297 - mse: 0.0297 - val_loss: 0.0281 - val_mse: 0.0281 Epoch 6/100 8/8 - 4s - loss: 0.0293 - mse: 0.0293 - val_loss: 0.0281 - val_mse: 0.0281 Epoch 7/100 8/8 - 4s - loss: 0.0291 - mse: 0.0291 - val_loss: 0.0279 - val_mse: 0.0279 Epoch 8/100 8/8 - 4s - loss: 0.0288 - mse: 0.0288 - val_loss: 0.0276 - val_mse: 0.0276 Epoch 9/100 8/8 - 4s - loss: 0.0286 - mse: 0.0286 - val_loss: 0.0276 - val_mse: 0.0276 Epoch 10/100 8/8 - 4s - loss: 0.0285 - mse: 0.0285 - val_loss: 0.0274 - val_mse: 0.0274 Epoch 11/100 8/8 - 4s - loss: 0.0282 - mse: 0.0282 - val_loss: 0.0269 - val_mse: 0.0269 Epoch 12/100 8/8 - 4s - loss: 0.0277 - mse: 0.0277 - val_loss: 0.0258 - val_mse: 0.0258 Epoch 13/100 8/8 - 4s - loss: 0.0267 - mse: 0.0267 - val_loss: 0.0243 - val_mse: 0.0243 Epoch 14/100 8/8 - 4s - loss: 0.0259 - mse: 0.0259 - val_loss: 0.0241 - val_mse: 0.0241 Epoch 15/100 8/8 - 4s - loss: 0.0258 - mse: 0.0258 - val_loss: 0.0233 - val_mse: 0.0233 Epoch 16/100 8/8 - 4s - loss: 0.0249 - mse: 0.0249 - val_loss: 0.0225 - val_mse: 0.0225 Epoch 17/100 8/8 - 4s - loss: 0.0242 - mse: 0.0242 - val_loss: 0.0220 - val_mse: 0.0220 Epoch 18/100 8/8 - 4s - loss: 0.0232 - mse: 0.0232 - val_loss: 0.0209 - val_mse: 0.0209 Epoch 19/100 8/8 - 4s - loss: 0.0222 - mse: 0.0222 - val_loss: 0.0193 - val_mse: 0.0193 Epoch 20/100 8/8 - 4s - loss: 0.0210 - mse: 0.0210 - val_loss: 0.0181 - val_mse: 0.0181 Epoch 21/100 8/8 - 4s - loss: 0.0198 - mse: 0.0198 - val_loss: 0.0176 - val_mse: 0.0176 Epoch 22/100 8/8 - 4s - loss: 0.0189 - mse: 0.0189 - val_loss: 0.0167 - val_mse: 0.0167 Epoch 23/100 8/8 - 4s - loss: 0.0183 - mse: 0.0183 - val_loss: 0.0164 - val_mse: 0.0164 Epoch 24/100 8/8 - 4s - loss: 0.0177 - mse: 0.0177 - val_loss: 0.0166 - val_mse: 0.0166 Epoch 25/100 8/8 - 4s - loss: 0.0175 - mse: 0.0175 - val_loss: 0.0165 - val_mse: 0.0165 Epoch 26/100 8/8 - 4s - loss: 0.0175 - mse: 0.0175 - val_loss: 0.0159 - val_mse: 0.0159 Epoch 27/100 8/8 - 4s - loss: 0.0170 - mse: 0.0170 - val_loss: 0.0155 - val_mse: 0.0155 Epoch 28/100 8/8 - 4s - loss: 0.0168 - mse: 0.0168 - val_loss: 0.0154 - val_mse: 0.0154 Epoch 29/100 8/8 - 5s - loss: 0.0164 - mse: 0.0164 - val_loss: 0.0153 - val_mse: 0.0153 Epoch 30/100 8/8 - 5s - loss: 0.0162 - mse: 0.0162 - val_loss: 0.0153 - val_mse: 0.0153 Epoch 31/100 8/8 - 4s - loss: 0.0168 - mse: 0.0168 - val_loss: 0.0154 - val_mse: 0.0154 Epoch 32/100 8/8 - 4s - loss: 0.0168 - mse: 0.0168 - val_loss: 0.0148 - val_mse: 0.0148 Epoch 33/100 8/8 - 4s - loss: 0.0165 - mse: 0.0165 - val_loss: 0.0149 - val_mse: 0.0149 Epoch 34/100 8/8 - 4s - loss: 0.0162 - mse: 0.0162 - val_loss: 0.0149 - val_mse: 0.0149 Epoch 35/100 8/8 - 4s - loss: 0.0159 - mse: 0.0159 - val_loss: 0.0151 - val_mse: 0.0151 Epoch 36/100 8/8 - 4s - loss: 0.0162 - mse: 0.0162 - val_loss: 0.0155 - val_mse: 0.0155 Epoch 37/100 8/8 - 4s - loss: 0.0159 - mse: 0.0159 - val_loss: 0.0153 - val_mse: 0.0153 9/9 [==============================] - 0s 55ms/step - loss: 0.0451 - mse: 0.0451 깻잎 농산물 evaluate : [0.04507669061422348, 0.04507669061422348] WARNING:tensorflow:Layer lstm_32 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_33 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_34 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. Epoch 1/100 8/8 - 7s - loss: 0.0341 - mse: 0.0341 - val_loss: 0.0150 - val_mse: 0.0150 Epoch 2/100 8/8 - 4s - loss: 0.0244 - mse: 0.0244 - val_loss: 0.0146 - val_mse: 0.0146 Epoch 3/100 8/8 - 4s - loss: 0.0228 - mse: 0.0228 - val_loss: 0.0120 - val_mse: 0.0120 Epoch 4/100 8/8 - 4s - loss: 0.0210 - mse: 0.0210 - val_loss: 0.0106 - val_mse: 0.0106 Epoch 5/100 8/8 - 4s - loss: 0.0190 - mse: 0.0190 - val_loss: 0.0130 - val_mse: 0.0130 Epoch 6/100 8/8 - 4s - loss: 0.0184 - mse: 0.0184 - val_loss: 0.0119 - val_mse: 0.0119 Epoch 7/100 8/8 - 4s - loss: 0.0192 - mse: 0.0192 - val_loss: 0.0093 - val_mse: 0.0093 Epoch 8/100 8/8 - 4s - loss: 0.0180 - mse: 0.0180 - val_loss: 0.0128 - val_mse: 0.0128 Epoch 9/100 8/8 - 4s - loss: 0.0167 - mse: 0.0167 - val_loss: 0.0088 - val_mse: 0.0088 Epoch 10/100 8/8 - 4s - loss: 0.0154 - mse: 0.0154 - val_loss: 0.0090 - val_mse: 0.0090 Epoch 11/100 8/8 - 4s - loss: 0.0148 - mse: 0.0148 - val_loss: 0.0096 - val_mse: 0.0096 Epoch 12/100 8/8 - 4s - loss: 0.0143 - mse: 0.0143 - val_loss: 0.0095 - val_mse: 0.0095 Epoch 13/100 8/8 - 4s - loss: 0.0141 - mse: 0.0141 - val_loss: 0.0095 - val_mse: 0.0095 Epoch 14/100 8/8 - 4s - loss: 0.0142 - mse: 0.0142 - val_loss: 0.0105 - val_mse: 0.0105 9/9 [==============================] - 0s 52ms/step - loss: 0.0168 - mse: 0.0168 시금치 농산물 evaluate : [0.016849800944328308, 0.016849802806973457] WARNING:tensorflow:Layer lstm_35 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_36 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_37 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. Epoch 1/100 8/8 - 7s - loss: 0.0636 - mse: 0.0636 - val_loss: 0.0364 - val_mse: 0.0364 Epoch 2/100 8/8 - 4s - loss: 0.0402 - mse: 0.0402 - val_loss: 0.0280 - val_mse: 0.0280 Epoch 3/100 8/8 - 4s - loss: 0.0361 - mse: 0.0361 - val_loss: 0.0270 - val_mse: 0.0270 Epoch 4/100 8/8 - 4s - loss: 0.0340 - mse: 0.0340 - val_loss: 0.0242 - val_mse: 0.0242 Epoch 5/100 8/8 - 4s - loss: 0.0313 - mse: 0.0313 - val_loss: 0.0225 - val_mse: 0.0225 Epoch 6/100 8/8 - 4s - loss: 0.0296 - mse: 0.0296 - val_loss: 0.0222 - val_mse: 0.0222 Epoch 7/100 8/8 - 4s - loss: 0.0286 - mse: 0.0286 - val_loss: 0.0221 - val_mse: 0.0221 Epoch 8/100 8/8 - 4s - loss: 0.0271 - mse: 0.0271 - val_loss: 0.0228 - val_mse: 0.0228 Epoch 9/100 8/8 - 4s - loss: 0.0266 - mse: 0.0266 - val_loss: 0.0225 - val_mse: 0.0225 Epoch 10/100 8/8 - 4s - loss: 0.0261 - mse: 0.0261 - val_loss: 0.0247 - val_mse: 0.0247 Epoch 11/100 8/8 - 4s - loss: 0.0262 - mse: 0.0262 - val_loss: 0.0231 - val_mse: 0.0231 Epoch 12/100 8/8 - 4s - loss: 0.0256 - mse: 0.0256 - val_loss: 0.0235 - val_mse: 0.0235 9/9 [==============================] - 0s 53ms/step - loss: 0.0288 - mse: 0.0288 미나리 농산물 evaluate : [0.028807953000068665, 0.028807953000068665] WARNING:tensorflow:Layer lstm_38 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_39 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_40 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. Epoch 1/100 8/8 - 7s - loss: 0.0434 - mse: 0.0434 - val_loss: 0.0176 - val_mse: 0.0176 Epoch 2/100 8/8 - 4s - loss: 0.0220 - mse: 0.0220 - val_loss: 0.0142 - val_mse: 0.0142 Epoch 3/100 8/8 - 4s - loss: 0.0181 - mse: 0.0181 - val_loss: 0.0114 - val_mse: 0.0114 Epoch 4/100 8/8 - 4s - loss: 0.0168 - mse: 0.0168 - val_loss: 0.0115 - val_mse: 0.0115 Epoch 5/100 8/8 - 4s - loss: 0.0164 - mse: 0.0164 - val_loss: 0.0111 - val_mse: 0.0111 Epoch 6/100 8/8 - 4s - loss: 0.0162 - mse: 0.0162 - val_loss: 0.0113 - val_mse: 0.0113 Epoch 7/100 8/8 - 4s - loss: 0.0159 - mse: 0.0159 - val_loss: 0.0109 - val_mse: 0.0109 Epoch 8/100 8/8 - 4s - loss: 0.0155 - mse: 0.0155 - val_loss: 0.0113 - val_mse: 0.0113 Epoch 9/100 8/8 - 4s - loss: 0.0150 - mse: 0.0150 - val_loss: 0.0109 - val_mse: 0.0109 Epoch 10/100 8/8 - 4s - loss: 0.0149 - mse: 0.0149 - val_loss: 0.0109 - val_mse: 0.0109 Epoch 11/100 8/8 - 4s - loss: 0.0148 - mse: 0.0148 - val_loss: 0.0109 - val_mse: 0.0109 Epoch 12/100 8/8 - 4s - loss: 0.0147 - mse: 0.0147 - val_loss: 0.0108 - val_mse: 0.0108 Epoch 13/100 8/8 - 4s - loss: 0.0147 - mse: 0.0147 - val_loss: 0.0113 - val_mse: 0.0113 Epoch 14/100 8/8 - 4s - loss: 0.0148 - mse: 0.0148 - val_loss: 0.0111 - val_mse: 0.0111 Epoch 15/100 8/8 - 4s - loss: 0.0149 - mse: 0.0149 - val_loss: 0.0112 - val_mse: 0.0112 Epoch 16/100 8/8 - 4s - loss: 0.0146 - mse: 0.0146 - val_loss: 0.0111 - val_mse: 0.0111 Epoch 17/100 8/8 - 4s - loss: 0.0145 - mse: 0.0145 - val_loss: 0.0111 - val_mse: 0.0111 9/9 [==============================] - 0s 48ms/step - loss: 0.0162 - mse: 0.0162 당근 농산물 evaluate : [0.01622072234749794, 0.01622072234749794] WARNING:tensorflow:Layer lstm_41 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_42 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_43 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. Epoch 1/100 8/8 - 7s - loss: 0.0351 - mse: 0.0351 - val_loss: 0.0250 - val_mse: 0.0250 Epoch 2/100 8/8 - 4s - loss: 0.0204 - mse: 0.0204 - val_loss: 0.0198 - val_mse: 0.0198 Epoch 3/100 8/8 - 4s - loss: 0.0185 - mse: 0.0185 - val_loss: 0.0191 - val_mse: 0.0191 Epoch 4/100 8/8 - 4s - loss: 0.0179 - mse: 0.0179 - val_loss: 0.0187 - val_mse: 0.0187 Epoch 5/100 8/8 - 4s - loss: 0.0175 - mse: 0.0175 - val_loss: 0.0186 - val_mse: 0.0186 Epoch 6/100 8/8 - 4s - loss: 0.0171 - mse: 0.0171 - val_loss: 0.0190 - val_mse: 0.0190 Epoch 7/100 8/8 - 4s - loss: 0.0169 - mse: 0.0169 - val_loss: 0.0184 - val_mse: 0.0184 Epoch 8/100 8/8 - 4s - loss: 0.0167 - mse: 0.0167 - val_loss: 0.0184 - val_mse: 0.0184 Epoch 9/100 8/8 - 4s - loss: 0.0167 - mse: 0.0167 - val_loss: 0.0183 - val_mse: 0.0183 Epoch 10/100 8/8 - 4s - loss: 0.0164 - mse: 0.0164 - val_loss: 0.0179 - val_mse: 0.0179 Epoch 11/100 8/8 - 4s - loss: 0.0162 - mse: 0.0162 - val_loss: 0.0176 - val_mse: 0.0176 Epoch 12/100 8/8 - 4s - loss: 0.0161 - mse: 0.0161 - val_loss: 0.0176 - val_mse: 0.0176 Epoch 13/100 8/8 - 4s - loss: 0.0159 - mse: 0.0159 - val_loss: 0.0174 - val_mse: 0.0174 Epoch 14/100 8/8 - 4s - loss: 0.0157 - mse: 0.0157 - val_loss: 0.0170 - val_mse: 0.0170 Epoch 15/100 8/8 - 4s - loss: 0.0154 - mse: 0.0154 - val_loss: 0.0165 - val_mse: 0.0165 Epoch 16/100 8/8 - 4s - loss: 0.0147 - mse: 0.0147 - val_loss: 0.0159 - val_mse: 0.0159 Epoch 17/100 8/8 - 4s - loss: 0.0145 - mse: 0.0145 - val_loss: 0.0162 - val_mse: 0.0162 Epoch 18/100 8/8 - 4s - loss: 0.0152 - mse: 0.0152 - val_loss: 0.0163 - val_mse: 0.0163 Epoch 19/100 8/8 - 4s - loss: 0.0146 - mse: 0.0146 - val_loss: 0.0159 - val_mse: 0.0159 Epoch 20/100 8/8 - 4s - loss: 0.0143 - mse: 0.0143 - val_loss: 0.0153 - val_mse: 0.0153 Epoch 21/100 8/8 - 4s - loss: 0.0139 - mse: 0.0139 - val_loss: 0.0152 - val_mse: 0.0152 Epoch 22/100 8/8 - 4s - loss: 0.0135 - mse: 0.0135 - val_loss: 0.0151 - val_mse: 0.0151 Epoch 23/100 8/8 - 4s - loss: 0.0131 - mse: 0.0131 - val_loss: 0.0148 - val_mse: 0.0148 Epoch 24/100 8/8 - 4s - loss: 0.0129 - mse: 0.0129 - val_loss: 0.0140 - val_mse: 0.0140 Epoch 25/100 8/8 - 4s - loss: 0.0122 - mse: 0.0122 - val_loss: 0.0138 - val_mse: 0.0138 Epoch 26/100 8/8 - 4s - loss: 0.0117 - mse: 0.0117 - val_loss: 0.0129 - val_mse: 0.0129 Epoch 27/100 8/8 - 4s - loss: 0.0108 - mse: 0.0108 - val_loss: 0.0125 - val_mse: 0.0125 Epoch 28/100 8/8 - 4s - loss: 0.0114 - mse: 0.0114 - val_loss: 0.0120 - val_mse: 0.0120 Epoch 29/100 8/8 - 4s - loss: 0.0108 - mse: 0.0108 - val_loss: 0.0117 - val_mse: 0.0117 Epoch 30/100 8/8 - 4s - loss: 0.0103 - mse: 0.0103 - val_loss: 0.0116 - val_mse: 0.0116 Epoch 31/100 8/8 - 4s - loss: 0.0098 - mse: 0.0098 - val_loss: 0.0116 - val_mse: 0.0116 Epoch 32/100 8/8 - 4s - loss: 0.0093 - mse: 0.0093 - val_loss: 0.0118 - val_mse: 0.0118 Epoch 33/100 8/8 - 4s - loss: 0.0090 - mse: 0.0090 - val_loss: 0.0121 - val_mse: 0.0121 Epoch 34/100 8/8 - 4s - loss: 0.0090 - mse: 0.0090 - val_loss: 0.0110 - val_mse: 0.0110 Epoch 35/100 8/8 - 4s - loss: 0.0096 - mse: 0.0096 - val_loss: 0.0127 - val_mse: 0.0127 Epoch 36/100 8/8 - 4s - loss: 0.0103 - mse: 0.0103 - val_loss: 0.0118 - val_mse: 0.0118 Epoch 37/100 8/8 - 4s - loss: 0.0098 - mse: 0.0098 - val_loss: 0.0115 - val_mse: 0.0115 Epoch 38/100 8/8 - 4s - loss: 0.0095 - mse: 0.0095 - val_loss: 0.0113 - val_mse: 0.0113 Epoch 39/100 8/8 - 4s - loss: 0.0092 - mse: 0.0092 - val_loss: 0.0113 - val_mse: 0.0113 9/9 [==============================] - 1s 56ms/step - loss: 0.0115 - mse: 0.0115 파프리카 농산물 evaluate : [0.011463094502687454, 0.011463094502687454] WARNING:tensorflow:Layer lstm_44 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_45 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_46 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. Epoch 1/100 8/8 - 7s - loss: 0.1431 - mse: 0.1431 - val_loss: 0.0750 - val_mse: 0.0750 Epoch 2/100 8/8 - 4s - loss: 0.0730 - mse: 0.0730 - val_loss: 0.0502 - val_mse: 0.0502 Epoch 3/100 8/8 - 4s - loss: 0.0589 - mse: 0.0589 - val_loss: 0.0445 - val_mse: 0.0445 Epoch 4/100 8/8 - 4s - loss: 0.0543 - mse: 0.0543 - val_loss: 0.0431 - val_mse: 0.0431 Epoch 5/100 8/8 - 4s - loss: 0.0522 - mse: 0.0522 - val_loss: 0.0421 - val_mse: 0.0421 Epoch 6/100 8/8 - 4s - loss: 0.0513 - mse: 0.0513 - val_loss: 0.0418 - val_mse: 0.0418 Epoch 7/100 8/8 - 4s - loss: 0.0505 - mse: 0.0505 - val_loss: 0.0417 - val_mse: 0.0417 Epoch 8/100 8/8 - 4s - loss: 0.0502 - mse: 0.0502 - val_loss: 0.0417 - val_mse: 0.0417 Epoch 9/100 8/8 - 4s - loss: 0.0501 - mse: 0.0501 - val_loss: 0.0416 - val_mse: 0.0416 Epoch 10/100 8/8 - 4s - loss: 0.0497 - mse: 0.0497 - val_loss: 0.0408 - val_mse: 0.0408 Epoch 11/100 8/8 - 4s - loss: 0.0487 - mse: 0.0487 - val_loss: 0.0392 - val_mse: 0.0392 Epoch 12/100 8/8 - 4s - loss: 0.0471 - mse: 0.0471 - val_loss: 0.0357 - val_mse: 0.0357 Epoch 13/100 8/8 - 4s - loss: 0.0435 - mse: 0.0435 - val_loss: 0.0319 - val_mse: 0.0319 Epoch 14/100 8/8 - 4s - loss: 0.0405 - mse: 0.0405 - val_loss: 0.0307 - val_mse: 0.0307 Epoch 15/100 8/8 - 4s - loss: 0.0385 - mse: 0.0385 - val_loss: 0.0276 - val_mse: 0.0276 Epoch 16/100 8/8 - 4s - loss: 0.0354 - mse: 0.0354 - val_loss: 0.0233 - val_mse: 0.0233 Epoch 17/100 8/8 - 4s - loss: 0.0314 - mse: 0.0314 - val_loss: 0.0195 - val_mse: 0.0195 Epoch 18/100 8/8 - 4s - loss: 0.0272 - mse: 0.0272 - val_loss: 0.0166 - val_mse: 0.0166 Epoch 19/100 8/8 - 4s - loss: 0.0242 - mse: 0.0242 - val_loss: 0.0148 - val_mse: 0.0148 Epoch 20/100 8/8 - 4s - loss: 0.0217 - mse: 0.0217 - val_loss: 0.0135 - val_mse: 0.0135 Epoch 21/100 8/8 - 4s - loss: 0.0205 - mse: 0.0205 - val_loss: 0.0128 - val_mse: 0.0128 Epoch 22/100 8/8 - 4s - loss: 0.0198 - mse: 0.0198 - val_loss: 0.0123 - val_mse: 0.0123 Epoch 23/100 8/8 - 4s - loss: 0.0196 - mse: 0.0196 - val_loss: 0.0123 - val_mse: 0.0123 Epoch 24/100 8/8 - 4s - loss: 0.0193 - mse: 0.0193 - val_loss: 0.0127 - val_mse: 0.0127 Epoch 25/100 8/8 - 4s - loss: 0.0190 - mse: 0.0190 - val_loss: 0.0120 - val_mse: 0.0120 Epoch 26/100 8/8 - 4s - loss: 0.0186 - mse: 0.0186 - val_loss: 0.0119 - val_mse: 0.0119 Epoch 27/100 8/8 - 4s - loss: 0.0185 - mse: 0.0185 - val_loss: 0.0123 - val_mse: 0.0123 Epoch 28/100 8/8 - 4s - loss: 0.0186 - mse: 0.0186 - val_loss: 0.0119 - val_mse: 0.0119 Epoch 29/100 8/8 - 4s - loss: 0.0183 - mse: 0.0183 - val_loss: 0.0120 - val_mse: 0.0120 Epoch 30/100 8/8 - 4s - loss: 0.0183 - mse: 0.0183 - val_loss: 0.0122 - val_mse: 0.0122 Epoch 31/100 8/8 - 4s - loss: 0.0185 - mse: 0.0185 - val_loss: 0.0130 - val_mse: 0.0130 Epoch 32/100 8/8 - 4s - loss: 0.0184 - mse: 0.0184 - val_loss: 0.0120 - val_mse: 0.0120 Epoch 33/100 8/8 - 4s - loss: 0.0181 - mse: 0.0181 - val_loss: 0.0120 - val_mse: 0.0120 9/9 [==============================] - 0s 54ms/step - loss: 0.0140 - mse: 0.0140 새송이 농산물 evaluate : [0.014042362570762634, 0.014042362570762634] WARNING:tensorflow:Layer lstm_47 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_48 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_49 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. Epoch 1/100 8/8 - 7s - loss: 0.0813 - mse: 0.0813 - val_loss: 0.0954 - val_mse: 0.0954 Epoch 2/100 8/8 - 4s - loss: 0.0470 - mse: 0.0470 - val_loss: 0.0572 - val_mse: 0.0572 Epoch 3/100 8/8 - 4s - loss: 0.0400 - mse: 0.0400 - val_loss: 0.0618 - val_mse: 0.0618 Epoch 4/100 8/8 - 4s - loss: 0.0383 - mse: 0.0383 - val_loss: 0.0536 - val_mse: 0.0536 Epoch 5/100 8/8 - 4s - loss: 0.0375 - mse: 0.0375 - val_loss: 0.0538 - val_mse: 0.0538 Epoch 6/100 8/8 - 4s - loss: 0.0366 - mse: 0.0366 - val_loss: 0.0509 - val_mse: 0.0509 Epoch 7/100 8/8 - 4s - loss: 0.0360 - mse: 0.0360 - val_loss: 0.0473 - val_mse: 0.0473 Epoch 8/100 8/8 - 4s - loss: 0.0358 - mse: 0.0358 - val_loss: 0.0486 - val_mse: 0.0486 Epoch 9/100 8/8 - 4s - loss: 0.0354 - mse: 0.0354 - val_loss: 0.0461 - val_mse: 0.0461 Epoch 10/100 8/8 - 4s - loss: 0.0360 - mse: 0.0360 - val_loss: 0.0469 - val_mse: 0.0469 Epoch 11/100 8/8 - 4s - loss: 0.0355 - mse: 0.0355 - val_loss: 0.0503 - val_mse: 0.0503 Epoch 12/100 8/8 - 4s - loss: 0.0349 - mse: 0.0349 - val_loss: 0.0489 - val_mse: 0.0489 Epoch 13/100 8/8 - 4s - loss: 0.0347 - mse: 0.0347 - val_loss: 0.0491 - val_mse: 0.0491 Epoch 14/100 8/8 - 4s - loss: 0.0345 - mse: 0.0345 - val_loss: 0.0481 - val_mse: 0.0481 9/9 [==============================] - 0s 47ms/step - loss: 0.0454 - mse: 0.0454 팽이버섯 농산물 evaluate : [0.04540707543492317, 0.04540707543492317] WARNING:tensorflow:Layer lstm_50 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_51 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_52 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. Epoch 1/100 8/8 - 7s - loss: 0.0424 - mse: 0.0424 - val_loss: 0.0257 - val_mse: 0.0257 Epoch 2/100 8/8 - 4s - loss: 0.0237 - mse: 0.0237 - val_loss: 0.0180 - val_mse: 0.0180 Epoch 3/100 8/8 - 4s - loss: 0.0206 - mse: 0.0206 - val_loss: 0.0165 - val_mse: 0.0165 Epoch 4/100 8/8 - 4s - loss: 0.0194 - mse: 0.0194 - val_loss: 0.0160 - val_mse: 0.0160 Epoch 5/100 8/8 - 4s - loss: 0.0191 - mse: 0.0191 - val_loss: 0.0160 - val_mse: 0.0160 Epoch 6/100 8/8 - 4s - loss: 0.0187 - mse: 0.0187 - val_loss: 0.0153 - val_mse: 0.0153 Epoch 7/100 8/8 - 4s - loss: 0.0186 - mse: 0.0186 - val_loss: 0.0155 - val_mse: 0.0155 Epoch 8/100 8/8 - 4s - loss: 0.0185 - mse: 0.0185 - val_loss: 0.0153 - val_mse: 0.0153 Epoch 9/100 8/8 - 4s - loss: 0.0182 - mse: 0.0182 - val_loss: 0.0155 - val_mse: 0.0155 Epoch 10/100 8/8 - 4s - loss: 0.0181 - mse: 0.0181 - val_loss: 0.0152 - val_mse: 0.0152 Epoch 11/100 8/8 - 4s - loss: 0.0179 - mse: 0.0179 - val_loss: 0.0154 - val_mse: 0.0154 Epoch 12/100 8/8 - 4s - loss: 0.0177 - mse: 0.0177 - val_loss: 0.0148 - val_mse: 0.0148 Epoch 13/100 8/8 - 4s - loss: 0.0173 - mse: 0.0173 - val_loss: 0.0145 - val_mse: 0.0145 Epoch 14/100 8/8 - 4s - loss: 0.0170 - mse: 0.0170 - val_loss: 0.0139 - val_mse: 0.0139 Epoch 15/100 8/8 - 4s - loss: 0.0164 - mse: 0.0164 - val_loss: 0.0131 - val_mse: 0.0131 Epoch 16/100 8/8 - 4s - loss: 0.0159 - mse: 0.0159 - val_loss: 0.0128 - val_mse: 0.0128 Epoch 17/100 8/8 - 4s - loss: 0.0157 - mse: 0.0157 - val_loss: 0.0124 - val_mse: 0.0124 Epoch 18/100 8/8 - 4s - loss: 0.0154 - mse: 0.0154 - val_loss: 0.0123 - val_mse: 0.0123 Epoch 19/100 8/8 - 4s - loss: 0.0149 - mse: 0.0149 - val_loss: 0.0127 - val_mse: 0.0127 Epoch 20/100 8/8 - 4s - loss: 0.0145 - mse: 0.0145 - val_loss: 0.0115 - val_mse: 0.0115 Epoch 21/100 8/8 - 4s - loss: 0.0140 - mse: 0.0140 - val_loss: 0.0112 - val_mse: 0.0112 Epoch 22/100 8/8 - 4s - loss: 0.0135 - mse: 0.0135 - val_loss: 0.0109 - val_mse: 0.0109 Epoch 23/100 8/8 - 4s - loss: 0.0130 - mse: 0.0130 - val_loss: 0.0095 - val_mse: 0.0095 Epoch 24/100 8/8 - 4s - loss: 0.0121 - mse: 0.0121 - val_loss: 0.0088 - val_mse: 0.0088 Epoch 25/100 8/8 - 4s - loss: 0.0112 - mse: 0.0112 - val_loss: 0.0079 - val_mse: 0.0079 Epoch 26/100 8/8 - 4s - loss: 0.0104 - mse: 0.0104 - val_loss: 0.0073 - val_mse: 0.0073 Epoch 27/100 8/8 - 4s - loss: 0.0098 - mse: 0.0098 - val_loss: 0.0072 - val_mse: 0.0072 Epoch 28/100 8/8 - 4s - loss: 0.0092 - mse: 0.0092 - val_loss: 0.0071 - val_mse: 0.0071 Epoch 29/100 8/8 - 4s - loss: 0.0090 - mse: 0.0090 - val_loss: 0.0065 - val_mse: 0.0065 Epoch 30/100 8/8 - 4s - loss: 0.0087 - mse: 0.0087 - val_loss: 0.0065 - val_mse: 0.0065 Epoch 31/100 8/8 - 4s - loss: 0.0085 - mse: 0.0085 - val_loss: 0.0065 - val_mse: 0.0065 Epoch 32/100 8/8 - 4s - loss: 0.0085 - mse: 0.0085 - val_loss: 0.0064 - val_mse: 0.0064 Epoch 33/100 8/8 - 4s - loss: 0.0084 - mse: 0.0084 - val_loss: 0.0060 - val_mse: 0.0060 Epoch 34/100 8/8 - 4s - loss: 0.0084 - mse: 0.0084 - val_loss: 0.0064 - val_mse: 0.0064 Epoch 35/100 8/8 - 4s - loss: 0.0082 - mse: 0.0082 - val_loss: 0.0066 - val_mse: 0.0066 Epoch 36/100 8/8 - 4s - loss: 0.0080 - mse: 0.0080 - val_loss: 0.0067 - val_mse: 0.0067 Epoch 37/100 8/8 - 4s - loss: 0.0079 - mse: 0.0079 - val_loss: 0.0066 - val_mse: 0.0066 Epoch 38/100 8/8 - 4s - loss: 0.0079 - mse: 0.0079 - val_loss: 0.0073 - val_mse: 0.0073 9/9 [==============================] - 0s 53ms/step - loss: 0.0116 - mse: 0.0116 토마토 농산물 evaluate : [0.011595326475799084, 0.011595326475799084] WARNING:tensorflow:Layer lstm_53 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_54 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_55 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. Epoch 1/100 8/8 - 7s - loss: 0.0268 - mse: 0.0268 - val_loss: 0.0150 - val_mse: 0.0150 Epoch 2/100 8/8 - 4s - loss: 0.0200 - mse: 0.0200 - val_loss: 0.0148 - val_mse: 0.0148 Epoch 3/100 8/8 - 4s - loss: 0.0194 - mse: 0.0194 - val_loss: 0.0139 - val_mse: 0.0139 Epoch 4/100 8/8 - 4s - loss: 0.0193 - mse: 0.0193 - val_loss: 0.0141 - val_mse: 0.0141 Epoch 5/100 8/8 - 4s - loss: 0.0191 - mse: 0.0191 - val_loss: 0.0138 - val_mse: 0.0138 Epoch 6/100 8/8 - 4s - loss: 0.0190 - mse: 0.0190 - val_loss: 0.0137 - val_mse: 0.0137 Epoch 7/100 8/8 - 4s - loss: 0.0188 - mse: 0.0188 - val_loss: 0.0134 - val_mse: 0.0134 Epoch 8/100 8/8 - 4s - loss: 0.0186 - mse: 0.0186 - val_loss: 0.0130 - val_mse: 0.0130 Epoch 9/100 8/8 - 4s - loss: 0.0185 - mse: 0.0185 - val_loss: 0.0132 - val_mse: 0.0132 Epoch 10/100 8/8 - 4s - loss: 0.0183 - mse: 0.0183 - val_loss: 0.0128 - val_mse: 0.0128 Epoch 11/100 8/8 - 4s - loss: 0.0181 - mse: 0.0181 - val_loss: 0.0124 - val_mse: 0.0124 Epoch 12/100 8/8 - 4s - loss: 0.0177 - mse: 0.0177 - val_loss: 0.0122 - val_mse: 0.0122 Epoch 13/100 8/8 - 4s - loss: 0.0184 - mse: 0.0184 - val_loss: 0.0133 - val_mse: 0.0133 Epoch 14/100 8/8 - 4s - loss: 0.0182 - mse: 0.0182 - val_loss: 0.0131 - val_mse: 0.0131 Epoch 15/100 8/8 - 4s - loss: 0.0176 - mse: 0.0176 - val_loss: 0.0123 - val_mse: 0.0123 Epoch 16/100 8/8 - 4s - loss: 0.0171 - mse: 0.0171 - val_loss: 0.0127 - val_mse: 0.0127 Epoch 17/100 8/8 - 4s - loss: 0.0169 - mse: 0.0169 - val_loss: 0.0119 - val_mse: 0.0119 Epoch 18/100 8/8 - 4s - loss: 0.0178 - mse: 0.0178 - val_loss: 0.0131 - val_mse: 0.0131 Epoch 19/100 8/8 - 4s - loss: 0.0176 - mse: 0.0176 - val_loss: 0.0121 - val_mse: 0.0121 Epoch 20/100 8/8 - 4s - loss: 0.0170 - mse: 0.0170 - val_loss: 0.0118 - val_mse: 0.0118 Epoch 21/100 8/8 - 4s - loss: 0.0170 - mse: 0.0170 - val_loss: 0.0115 - val_mse: 0.0115 Epoch 22/100 8/8 - 4s - loss: 0.0165 - mse: 0.0165 - val_loss: 0.0121 - val_mse: 0.0121 Epoch 23/100 8/8 - 4s - loss: 0.0163 - mse: 0.0163 - val_loss: 0.0119 - val_mse: 0.0119 Epoch 24/100 8/8 - 4s - loss: 0.0168 - mse: 0.0168 - val_loss: 0.0120 - val_mse: 0.0120 Epoch 25/100 8/8 - 4s - loss: 0.0170 - mse: 0.0170 - val_loss: 0.0118 - val_mse: 0.0118 Epoch 26/100 8/8 - 4s - loss: 0.0165 - mse: 0.0165 - val_loss: 0.0114 - val_mse: 0.0114 Epoch 27/100 8/8 - 4s - loss: 0.0162 - mse: 0.0162 - val_loss: 0.0119 - val_mse: 0.0119 Epoch 28/100 8/8 - 4s - loss: 0.0160 - mse: 0.0160 - val_loss: 0.0138 - val_mse: 0.0138 Epoch 29/100 8/8 - 4s - loss: 0.0153 - mse: 0.0153 - val_loss: 0.0226 - val_mse: 0.0226 Epoch 30/100 8/8 - 4s - loss: 0.0150 - mse: 0.0150 - val_loss: 0.0178 - val_mse: 0.0178 Epoch 31/100 8/8 - 4s - loss: 0.0146 - mse: 0.0146 - val_loss: 0.0121 - val_mse: 0.0121 9/9 [==============================] - 1s 54ms/step - loss: 0.0207 - mse: 0.0207 청상추 농산물 evaluate : [0.020691396668553352, 0.020691394805908203] WARNING:tensorflow:Layer lstm_56 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_57 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_58 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. Epoch 1/100 8/8 - 7s - loss: 0.0618 - mse: 0.0618 - val_loss: 0.0393 - val_mse: 0.0392 Epoch 2/100 8/8 - 4s - loss: 0.0328 - mse: 0.0328 - val_loss: 0.0287 - val_mse: 0.0287 Epoch 3/100 8/8 - 4s - loss: 0.0280 - mse: 0.0280 - val_loss: 0.0286 - val_mse: 0.0286 Epoch 4/100 8/8 - 4s - loss: 0.0266 - mse: 0.0266 - val_loss: 0.0266 - val_mse: 0.0266 Epoch 5/100 8/8 - 4s - loss: 0.0255 - mse: 0.0255 - val_loss: 0.0261 - val_mse: 0.0261 Epoch 6/100 8/8 - 4s - loss: 0.0250 - mse: 0.0250 - val_loss: 0.0256 - val_mse: 0.0256 Epoch 7/100 8/8 - 4s - loss: 0.0246 - mse: 0.0246 - val_loss: 0.0251 - val_mse: 0.0251 Epoch 8/100 8/8 - 4s - loss: 0.0245 - mse: 0.0245 - val_loss: 0.0257 - val_mse: 0.0257 Epoch 9/100 8/8 - 4s - loss: 0.0242 - mse: 0.0242 - val_loss: 0.0254 - val_mse: 0.0254 Epoch 10/100 8/8 - 4s - loss: 0.0239 - mse: 0.0239 - val_loss: 0.0245 - val_mse: 0.0245 Epoch 11/100 8/8 - 4s - loss: 0.0236 - mse: 0.0236 - val_loss: 0.0248 - val_mse: 0.0248 Epoch 12/100 8/8 - 4s - loss: 0.0233 - mse: 0.0233 - val_loss: 0.0237 - val_mse: 0.0237 Epoch 13/100 8/8 - 4s - loss: 0.0226 - mse: 0.0226 - val_loss: 0.0223 - val_mse: 0.0223 Epoch 14/100 8/8 - 4s - loss: 0.0217 - mse: 0.0217 - val_loss: 0.0225 - val_mse: 0.0225 Epoch 15/100 8/8 - 4s - loss: 0.0212 - mse: 0.0212 - val_loss: 0.0222 - val_mse: 0.0222 Epoch 16/100 8/8 - 4s - loss: 0.0205 - mse: 0.0205 - val_loss: 0.0206 - val_mse: 0.0206 Epoch 17/100 8/8 - 4s - loss: 0.0204 - mse: 0.0204 - val_loss: 0.0197 - val_mse: 0.0197 Epoch 18/100 8/8 - 4s - loss: 0.0203 - mse: 0.0203 - val_loss: 0.0201 - val_mse: 0.0201 Epoch 19/100 8/8 - 4s - loss: 0.0196 - mse: 0.0196 - val_loss: 0.0220 - val_mse: 0.0220 Epoch 20/100 8/8 - 4s - loss: 0.0192 - mse: 0.0192 - val_loss: 0.0192 - val_mse: 0.0192 Epoch 21/100 8/8 - 4s - loss: 0.0182 - mse: 0.0182 - val_loss: 0.0180 - val_mse: 0.0180 Epoch 22/100 8/8 - 4s - loss: 0.0174 - mse: 0.0174 - val_loss: 0.0160 - val_mse: 0.0160 Epoch 23/100 8/8 - 4s - loss: 0.0159 - mse: 0.0159 - val_loss: 0.0156 - val_mse: 0.0156 Epoch 24/100 8/8 - 4s - loss: 0.0145 - mse: 0.0145 - val_loss: 0.0142 - val_mse: 0.0142 Epoch 25/100 8/8 - 4s - loss: 0.0138 - mse: 0.0138 - val_loss: 0.0147 - val_mse: 0.0147 Epoch 26/100 8/8 - 4s - loss: 0.0132 - mse: 0.0132 - val_loss: 0.0133 - val_mse: 0.0133 Epoch 27/100 8/8 - 4s - loss: 0.0127 - mse: 0.0127 - val_loss: 0.0137 - val_mse: 0.0137 Epoch 28/100 8/8 - 4s - loss: 0.0123 - mse: 0.0123 - val_loss: 0.0128 - val_mse: 0.0128 Epoch 29/100 8/8 - 4s - loss: 0.0121 - mse: 0.0121 - val_loss: 0.0128 - val_mse: 0.0128 Epoch 30/100 8/8 - 4s - loss: 0.0117 - mse: 0.0117 - val_loss: 0.0132 - val_mse: 0.0132 Epoch 31/100 8/8 - 4s - loss: 0.0115 - mse: 0.0115 - val_loss: 0.0131 - val_mse: 0.0131 Epoch 32/100 8/8 - 4s - loss: 0.0112 - mse: 0.0112 - val_loss: 0.0123 - val_mse: 0.0123 Epoch 33/100 8/8 - 4s - loss: 0.0112 - mse: 0.0112 - val_loss: 0.0124 - val_mse: 0.0124 Epoch 34/100 8/8 - 4s - loss: 0.0111 - mse: 0.0111 - val_loss: 0.0125 - val_mse: 0.0125 Epoch 35/100 8/8 - 4s - loss: 0.0109 - mse: 0.0109 - val_loss: 0.0125 - val_mse: 0.0125 Epoch 36/100 8/8 - 4s - loss: 0.0107 - mse: 0.0107 - val_loss: 0.0132 - val_mse: 0.0132 Epoch 37/100 8/8 - 4s - loss: 0.0109 - mse: 0.0109 - val_loss: 0.0127 - val_mse: 0.0127 9/9 [==============================] - 1s 63ms/step - loss: 0.0236 - mse: 0.0236 백다다기 농산물 evaluate : [0.023571321740746498, 0.023571321740746498] WARNING:tensorflow:Layer lstm_59 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_60 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_61 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. Epoch 1/100 8/8 - 7s - loss: 0.0395 - mse: 0.0395 - val_loss: 0.0161 - val_mse: 0.0161 Epoch 2/100 8/8 - 5s - loss: 0.0234 - mse: 0.0234 - val_loss: 0.0134 - val_mse: 0.0134 Epoch 3/100 8/8 - 4s - loss: 0.0214 - mse: 0.0214 - val_loss: 0.0132 - val_mse: 0.0132 Epoch 4/100 8/8 - 4s - loss: 0.0205 - mse: 0.0205 - val_loss: 0.0129 - val_mse: 0.0129 Epoch 5/100 8/8 - 4s - loss: 0.0202 - mse: 0.0202 - val_loss: 0.0126 - val_mse: 0.0126 Epoch 6/100 8/8 - 4s - loss: 0.0197 - mse: 0.0197 - val_loss: 0.0130 - val_mse: 0.0130 Epoch 7/100 8/8 - 4s - loss: 0.0194 - mse: 0.0194 - val_loss: 0.0128 - val_mse: 0.0128 Epoch 8/100 8/8 - 5s - loss: 0.0195 - mse: 0.0195 - val_loss: 0.0122 - val_mse: 0.0122 Epoch 9/100 8/8 - 5s - loss: 0.0189 - mse: 0.0189 - val_loss: 0.0129 - val_mse: 0.0129 Epoch 10/100 8/8 - 4s - loss: 0.0187 - mse: 0.0187 - val_loss: 0.0128 - val_mse: 0.0128 Epoch 11/100 8/8 - 4s - loss: 0.0185 - mse: 0.0185 - val_loss: 0.0125 - val_mse: 0.0125 Epoch 12/100 8/8 - 4s - loss: 0.0181 - mse: 0.0181 - val_loss: 0.0121 - val_mse: 0.0121 Epoch 13/100 8/8 - 4s - loss: 0.0175 - mse: 0.0175 - val_loss: 0.0119 - val_mse: 0.0119 Epoch 14/100 8/8 - 4s - loss: 0.0171 - mse: 0.0171 - val_loss: 0.0116 - val_mse: 0.0116 Epoch 15/100 8/8 - 4s - loss: 0.0168 - mse: 0.0168 - val_loss: 0.0113 - val_mse: 0.0113 Epoch 16/100 8/8 - 4s - loss: 0.0166 - mse: 0.0166 - val_loss: 0.0108 - val_mse: 0.0108 Epoch 17/100 8/8 - 4s - loss: 0.0159 - mse: 0.0159 - val_loss: 0.0112 - val_mse: 0.0112 Epoch 18/100 8/8 - 4s - loss: 0.0162 - mse: 0.0162 - val_loss: 0.0111 - val_mse: 0.0111 Epoch 19/100 8/8 - 4s - loss: 0.0160 - mse: 0.0160 - val_loss: 0.0100 - val_mse: 0.0100 Epoch 20/100 8/8 - 4s - loss: 0.0156 - mse: 0.0156 - val_loss: 0.0104 - val_mse: 0.0104 Epoch 21/100 8/8 - 4s - loss: 0.0152 - mse: 0.0152 - val_loss: 0.0096 - val_mse: 0.0096 Epoch 22/100 8/8 - 4s - loss: 0.0147 - mse: 0.0147 - val_loss: 0.0096 - val_mse: 0.0096 Epoch 23/100 8/8 - 4s - loss: 0.0144 - mse: 0.0144 - val_loss: 0.0089 - val_mse: 0.0089 Epoch 24/100 8/8 - 5s - loss: 0.0136 - mse: 0.0136 - val_loss: 0.0086 - val_mse: 0.0086 Epoch 25/100 8/8 - 4s - loss: 0.0128 - mse: 0.0128 - val_loss: 0.0079 - val_mse: 0.0079 Epoch 26/100 8/8 - 5s - loss: 0.0122 - mse: 0.0122 - val_loss: 0.0075 - val_mse: 0.0075 Epoch 27/100 8/8 - 4s - loss: 0.0116 - mse: 0.0116 - val_loss: 0.0077 - val_mse: 0.0077 Epoch 28/100 8/8 - 5s - loss: 0.0113 - mse: 0.0113 - val_loss: 0.0081 - val_mse: 0.0081 Epoch 29/100 8/8 - 5s - loss: 0.0119 - mse: 0.0119 - val_loss: 0.0066 - val_mse: 0.0066 Epoch 30/100 8/8 - 4s - loss: 0.0111 - mse: 0.0111 - val_loss: 0.0074 - val_mse: 0.0074 Epoch 31/100 8/8 - 4s - loss: 0.0108 - mse: 0.0108 - val_loss: 0.0069 - val_mse: 0.0069 Epoch 32/100 8/8 - 4s - loss: 0.0110 - mse: 0.0110 - val_loss: 0.0068 - val_mse: 0.0068 Epoch 33/100 8/8 - 4s - loss: 0.0105 - mse: 0.0105 - val_loss: 0.0073 - val_mse: 0.0073 Epoch 34/100 8/8 - 4s - loss: 0.0101 - mse: 0.0101 - val_loss: 0.0073 - val_mse: 0.0073 9/9 [==============================] - 1s 63ms/step - loss: 0.0225 - mse: 0.0225 애호박 농산물 evaluate : [0.022533588111400604, 0.022533588111400604] WARNING:tensorflow:Layer lstm_62 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_63 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_64 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. Epoch 1/100 8/8 - 7s - loss: 0.0111 - mse: 0.0111 - val_loss: 0.0072 - val_mse: 0.0072 Epoch 2/100 8/8 - 4s - loss: 0.0069 - mse: 0.0069 - val_loss: 0.0063 - val_mse: 0.0063 Epoch 3/100 8/8 - 4s - loss: 0.0066 - mse: 0.0066 - val_loss: 0.0062 - val_mse: 0.0062 Epoch 4/100 8/8 - 4s - loss: 0.0064 - mse: 0.0064 - val_loss: 0.0063 - val_mse: 0.0063 Epoch 5/100 8/8 - 5s - loss: 0.0062 - mse: 0.0062 - val_loss: 0.0065 - val_mse: 0.0065 Epoch 6/100 8/8 - 4s - loss: 0.0062 - mse: 0.0062 - val_loss: 0.0063 - val_mse: 0.0063 Epoch 7/100 8/8 - 4s - loss: 0.0060 - mse: 0.0060 - val_loss: 0.0062 - val_mse: 0.0062 Epoch 8/100 8/8 - 4s - loss: 0.0060 - mse: 0.0060 - val_loss: 0.0063 - val_mse: 0.0063 9/9 [==============================] - 0s 50ms/step - loss: 0.0113 - mse: 0.0113 캠벨얼리 농산물 evaluate : [0.011327553540468216, 0.011327553540468216] WARNING:tensorflow:Layer lstm_65 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_66 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. WARNING:tensorflow:Layer lstm_67 will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU. Epoch 1/100 8/8 - 7s - loss: 0.0245 - mse: 0.0245 - val_loss: 0.0748 - val_mse: 0.0748 Epoch 2/100 8/8 - 4s - loss: 0.0194 - mse: 0.0194 - val_loss: 0.0671 - val_mse: 0.0671 Epoch 3/100 8/8 - 4s - loss: 0.0187 - mse: 0.0187 - val_loss: 0.0657 - val_mse: 0.0657 Epoch 4/100 8/8 - 4s - loss: 0.0178 - mse: 0.0178 - val_loss: 0.0626 - val_mse: 0.0626 Epoch 5/100 8/8 - 4s - loss: 0.0173 - mse: 0.0173 - val_loss: 0.0623 - val_mse: 0.0623 Epoch 6/100 8/8 - 4s - loss: 0.0168 - mse: 0.0168 - val_loss: 0.0607 - val_mse: 0.0607 Epoch 7/100 8/8 - 4s - loss: 0.0165 - mse: 0.0165 - val_loss: 0.0595 - val_mse: 0.0595 Epoch 8/100 8/8 - 4s - loss: 0.0163 - mse: 0.0163 - val_loss: 0.0602 - val_mse: 0.0602 Epoch 9/100 8/8 - 4s - loss: 0.0162 - mse: 0.0162 - val_loss: 0.0590 - val_mse: 0.0590 Epoch 10/100 8/8 - 4s - loss: 0.0161 - mse: 0.0161 - val_loss: 0.0606 - val_mse: 0.0606 Epoch 11/100 8/8 - 4s - loss: 0.0159 - mse: 0.0159 - val_loss: 0.0580 - val_mse: 0.0580 Epoch 12/100 8/8 - 4s - loss: 0.0157 - mse: 0.0157 - val_loss: 0.0584 - val_mse: 0.0584 Epoch 13/100 8/8 - 4s - loss: 0.0156 - mse: 0.0156 - val_loss: 0.0609 - val_mse: 0.0609 Epoch 14/100 8/8 - 4s - loss: 0.0156 - mse: 0.0156 - val_loss: 0.0595 - val_mse: 0.0595 Epoch 15/100 8/8 - 4s - loss: 0.0153 - mse: 0.0153 - val_loss: 0.0591 - val_mse: 0.0591 Epoch 16/100 8/8 - 4s - loss: 0.0154 - mse: 0.0154 - val_loss: 0.0607 - val_mse: 0.0607 9/9 [==============================] - 1s 56ms/step - loss: 0.0737 - mse: 0.0737 샤인마스캇 농산물 evaluate : [0.07369455695152283, 0.07369455695152283]
21개 농산물 총 평균 설명력: -0.2778524722825757
shape가 (277, 28, 1)인 개별 예측 결과 21개를 (277, 28, 21) 형태로 변경.¶
zero_df = np.zeros((277, 28, 21))
for a in range(y_data_test.shape[0]):# => 277
for b in range(len(data.columns[2::2])): # => 21 # data.columns[2::2]
pred = pred_dict[b]
for c in range(window_size): # => # 28 window_size
zero_df[a][c][b] = pred[a][c][0]
print(zero_df.shape)
print(zero_df)
(277, 28, 21) [[[0.12369193 0.31623128 0.3274326 ... 0.21181709 0.11545473 0.14606655] [0.12537169 0.35291782 0.34251887 ... 0.1888669 0.11588895 0.18378541] [0.12613182 0.37736392 0.34529901 ... 0.01216372 0.11432691 0.19673014] ... [0.11693095 0.35894796 0.27092239 ... 0.22126527 0.08268423 0.14969231] [0.11666366 0.35844931 0.27237523 ... 0.21975783 0.08364095 0.16146328] [0.11658397 0.36009565 0.27399579 ... 0.21828689 0.08517709 0.16945304]] [[0.12375354 0.31687945 0.32824096 ... 0.21894173 0.11593969 0.14771688] [0.12561554 0.35129485 0.34409478 ... 0.04797793 0.11678773 0.16258946] [0.1264843 0.37711149 0.34640703 ... 0.20636523 0.11575883 0.18375415] ... [0.11668988 0.3584924 0.2721754 ... 0.22021733 0.08361653 0.16131589] [0.11660348 0.36012256 0.27383089 ... 0.2186683 0.08514489 0.16932762] [0.1164389 0.36074048 0.27491513 ... 0.21080787 0.0863869 0.1635019 ]] [[0.12386597 0.31398177 0.32826036 ... 0.0773437 0.11574152 0.09405473] [0.12575582 0.34947574 0.34331447 ... 0.24841334 0.11660416 0.13043675] [0.12663746 0.37710479 0.34421185 ... 0.24711947 0.11563749 0.17854984] ... [0.116621 0.36018568 0.27363747 ... 0.21907856 0.0850587 0.16921532] [0.11645198 0.36078316 0.27475399 ... 0.2111042 0.08629753 0.16342239] [0.11620086 0.36029541 0.27592096 ... 0.20125084 0.08731178 0.15690006]] ... [[0.12390731 0.31508023 0.33420372 ... 0.20669818 0.11643346 0.15144134] [0.12594712 0.3482337 0.35822171 ... 0.12343615 0.11803732 0.16840686] [0.12705594 0.37261963 0.36957884 ... 0.32234174 0.11549006 0.19505849] ... [0.12661041 0.37847006 0.33656067 ... 0.29765594 0.07491215 0.1902815 ] [0.12686868 0.39075151 0.33954787 ... 0.28468239 0.07489488 0.19770007] [0.12701327 0.40093631 0.34264216 ... 0.25985125 0.07488771 0.19178644]] [[0.12386597 0.31398177 0.32826036 ... 0.0773437 0.11574152 0.09405473] [0.12585203 0.34829894 0.34469208 ... 0.28234628 0.1142687 0.14021668] [0.12694073 0.37401789 0.34921098 ... 0.32022905 0.10819271 0.19644754] ... [0.12686732 0.39078361 0.33958602 ... 0.28412244 0.07489695 0.19759507] [0.12701203 0.40095437 0.34274578 ... 0.25938788 0.07488985 0.19171742] [0.12702274 0.40768835 0.34589663 ... 0.2303039 0.07489344 0.18638046]] [[0.12386299 0.31652537 0.32885814 ... 0.23075981 0.11396426 0.15436748] [0.12587482 0.35331732 0.34606218 ... 0.24730442 0.11038075 0.19651648] [0.1270038 0.38052619 0.35044754 ... 0.27601641 0.10272919 0.22662966] ... [0.1270161 0.40100935 0.34252617 ... 0.25957412 0.07488501 0.19174121] [0.12702596 0.40772101 0.34571901 ... 0.23023614 0.07489002 0.18639912] [0.12693574 0.40856197 0.3467406 ... 0.03124557 0.07494838 0.17259187]]]
새로 생성된 데이터를 이용한 예측.¶
data = pd.read_csv('data/public_data/train.csv')
data['date'] = pd.to_datetime(data['date'])
x_data = [] # feature
y_data = [] # label
for i in range(data.shape[0]-window_size-future_size):
x = data.iloc[i:i+window_size, :].to_numpy() # [요일, 농산물1거래량, 농산물1가격, 농산물2거래량, ......]
y = data.iloc[i+window_size:i+window_size+future_size, 2::2].to_numpy() # [농산물1가격, 농산물2가격, ....]
#y_0 = np.zeros([1, y.shape[1]]) # 디코더 첫 입력값 추가
x_data.append(x)
#y_data.append(np.concatenate([y_0, y], axis=0))
y_data.append(y)
x_data = np.array(x_data)
y_data = np.array(y_data)
x_data_train, x_data_test = x_data[:1400], x_data[1400:] # (1400, 28, 3) (277, 28, 3)
y_data_train, y_data_test = y_data[:1400], y_data[1400:] # (1400, 28) (277, 28)
r2_list = []
for i in range(len(y_data_test)):
r2 = r2_score(y_data_test[i], zero_df[i])
r2_list.append(r2)
print('평균 설명력', np.mean(r2_list))
평균 설명력 -3.861584005701784
3.4 결과 저장¶
예측 후 sample_submission.csv를 채운다.¶
- sample_submission.csv : 2020년 10월 6일(화) ~ 2020년 11월 12일(목) 기간 내 품목별 1주, 2주, 4주 후 가격 입력
submission = pd.read_csv('data/sample_submission.csv')
public_date_list = submission[submission['예측대상일자'].str.contains('2020')]['예측대상일자'].str.split('+').str[0].unique()
public_date_list
array(['2020-09-29', '2020-09-30', '2020-10-01', '2020-10-02', '2020-10-03', '2020-10-04', '2020-10-05', '2020-10-06', '2020-10-07', '2020-10-08', '2020-10-09', '2020-10-10', '2020-10-11', '2020-10-12', '2020-10-13', '2020-10-14', '2020-10-15', '2020-10-16', '2020-10-17', '2020-10-18', '2020-10-19', '2020-10-20', '2020-10-21', '2020-10-22', '2020-10-23', '2020-10-24', '2020-10-25', '2020-10-26', '2020-10-27', '2020-10-28', '2020-10-29', '2020-10-30', '2020-10-31', '2020-11-01', '2020-11-02', '2020-11-03', '2020-11-04', '2020-11-05'], dtype=object)
# test_files에 있는 csv를 하나씩 집어 넣고 기존 데이터와 합친 다음, 마지막 28일 값으로 예측한 값을 submission.csv에 채운다.
# result = pd.DataFrame()
# for date in public_date_list:
# test_df = pd.read_csv(f'./data/public_data/test_files/test_{date}.csv')
# new_data = pd.read_csv('./data/public_data/train.csv')
# new_data = pd.concat([new_data, test_df]).iloc[-window_size:]
# # 요일 변환 후 정규화
# week_day_map = {}
# for i, d in enumerate(new_data['요일'].unique()):
# week_day_map[d] = i
# new_data['요일'] = new_data['요일'].map(week_day_map)
# new_data = new_data.iloc[:,1:]/norm
# # 3차원 배열 형식으로 변경
# new_data = new_data.to_numpy()
# new_data = np.expand_dims(new_data, 0)
# # 예측
# new_pred = model.predict(new_data)
# new_pred = pd.DataFrame(new_pred[0])
# # 정규화 풀기
# norm_price = norm[2::2]
# norm_df = pd.DataFrame(norm_price).T
# new_pred = new_pred.multiply(norm_df.values)
# # +7일, +14일, +28일 가격 추출하기
# future_predict_values = new_pred.iloc[[6, 13, 27],:]
# #print(future_predict_values)
# idx = submission[submission['예측대상일자'].str.contains(date)].index
# submission.loc[idx, '배추_가격(원/kg)':] = future_predict_values.values
# submission
# 예측값 출력
# submission.to_csv('dacon_baseline.csv', index=False)