잔차 🐥
* 잔차 : 실제값과 예측값과의 차이
* 잔차 검정 : 정상성, 정규성 등을 만족하는지 확인하는 검정
* 검정하는 함수 : summary(), plot_dignstics()
Best Model을 이용해서 잔차 확인
잔차 검정 - summary()
model.summary()
(해석)
P>|z| : p-value > 0.05 = 유의미하다 = 정상성을 띈다
Heteroskedasticity (H) : 이 값이 클수록 정규분포를 띄고 있다. (수치 약간 낮은 편)
잔차 검정 - plot_diagnostics()
model.plot_diagnostics(figsize=(16, 8))
plt.show()
(해석)
Normal Q-Q( 잔차의 정규성 플롯 ) : 빨간선이 데이터와 일치하면 정규분포를 띄고 있다.
(이 그래프는 양 끝에가 벗어나 있으므로 정규분포 X)
ARIMA 모델 훈련 및 테스트하기
시계열 데이터 훈련 및 테스트 데이터 분리 🐥
- 훈련 및 테스트 데이터 = 9 : 1로 분리
- 시계열 데이터는 train_test_split() 함수를 사용하지 않습니다.
→ 연속성을 띄는 데이터의 특성상, 데이터를 앞/뒤의 비율로 분리합니다.
훈련 및 테스트 데이터 = 9 : 1로 분리
split_ratio = 0.9
split_index = int(len(data) * split_ratio)
train_data = data.iloc[:split_index]
test_data = data.iloc[split_index:]
train_data.shape, test_data.shape
((2265,), (252,))
auto_arima : 모델 설정 및 Best Model 추출
* auto_arima는 훈련과 동시에 베스트 모델을 생성해 줍니다.
model_fit = pm.auto_arima(
y = train_data,
### ndiffs 방법으로 찾은 결정 차수 사용하는것이 좋음
d = n_diffs,
start_p=0, max_p=3,
start_q=0, max_q=3,
m=1, seasonal=False,
stepwise=True,
trace=True
)
model_fit.summary()
Best Model을 이용하여 예측(Predict)하기
시계열 예측하기(forecast) 🐥
* 시계열에서 예측 용어 : forecast 라고 칭합니다.
* 예측 결과 : 예측데이터, 상한가(상한 바운드), 하한가(하한 바운드)
* 결과 시각화 : 기존값과 예측값이 연결된 시각화
* 수행방법 : forecast 함수 생성 후 predict 수행
: 예측결과 반환
향후 예측 함수
- model : Best Model
- n : 예측하려는 향후 기간 (디폴트로 1을 지정했음)
- n_periods : 예측기간 (day일단위)
- return_conf_int : 신뢰구간 반환여부
- fc : 예측결과(y_pred)
- conf_int : 신뢰구간
- asarray(): 배열로 바꾸는 함수 / tolist(): 리스트로 바꾸는 함수
def forecast_n_step(model, n=1):
### 예측하기
fc, conf_int = model.predict(n_periods=n, return_conf_int=True)
# print(fc, conf_int)
### 반환값은 리스트형태로 변환해서 전달
return (
fc.tolist()[0:n],
np.asarray(conf_int).tolist()[0:n]
)
forecast 함수 생성하기
import pandas as pd
def forecast(len, model, index, data=None) :
### 결과값을 담아서 반환할 변수
y_pred = []
pred_upper = []
pred_lower = []
###데이터(data)가 있는 경우
if data is not None :
for new_data in data :
### 예측하기 : 반복수행을 위해 함수로 생성
fc, conf = forecast_n_step(model)
### 예측결과 리스트에 담기
y_pred.append(fc[0])
### 상한가
pred_upper.append(conf[0][1])
### 하한가
pred_lower.append(conf[0][0])
### 시계열에서는 데이터별로 Model을 갱신함
model.update(new_data)
###데이터(data)가 없는 경우
else :
for i in range(len):
fc, conf = forecast_n_step(model)
### 예측결과 리스트에 담기
y_pred.append(fc[0])
### 상한가
pred_upper.append(conf[0][1])
### 하한가
pred_lower.append(conf[0][0])
### 시계열에서는 데이터별로 Model을 갱신함
model.update(fc[0])
### 결과값에 대해서는 시리즈 타입으로
return pd.Series(y_pred, index=index), pred_upper, pred_lower
forecast 함수 호출하기
함수 호출하기
- fc : 예측결과
- upper : 상한가
- lower : 하한가
### model_fit(베스트 모델) / test_data.index (날짜 데이터)
fc, upper, lower = forecast(len(test_data), model_fit, test_data.index, data=test_data)
fc, upper, lower
(Date
2021-10-29 96.433256
2021-11-01 146.727907
2021-11-02 145.113369
2021-11-03 145.121421
2021-11-04 147.463206
...
2022-10-24 101.464312
2022-10-25 102.958099
2022-10-26 104.894401
2022-10-27 95.389597
2022-10-28 92.424132
Length: 252, dtype: float64,
[98.85951738604514,
149.88611770581687,
148.2726676426495,
148.28019180318753,
150.6017662415589,
151.38984642459943,
152.78340487937427,
152.3548547636148,
152.62304610556015,
149.85085927774028,
149.93932365840647,
152.73596394598113,
152.69024603875164,
152.24253442847936,
152.301423067861,
153.82400826446695,
153.25966524767358,
150.35866608742606,
149.9359790285766,
149.94798926821701,
146.18180502482008,
149.06324542394535,
146.01981213926393,
144.64612314064308,
147.00860745749978,
145.78401348382775,
146.91850164909178,
151.11709768634515,
151.9977285476294,
151.31689000061846,
151.8723456784901,
150.02822455870975,
148.20131231335756,
150.4680242911127,
148.25338974203163,
145.99246757560502,
145.656771596219,
147.33128220525225,
150.11351342742003,
150.3902552519584,
151.2248463547664,
149.78026802501938,
149.64920899089864,
149.29160432204966,
147.91291616679135,
148.26340000601732,
147.6811280586026,
141.15301548436008,
140.6040353138782,
140.36119518062947,
141.63962190022798,
143.27593083335984,
144.776413894338,
142.53122443422316,
142.8671947467239,
139.7702715233164,
138.74088662464933,
136.91590127094588,
133.3510216985728,
133.56060731602795,
130.1478103961262,
132.22853418556116,
132.50483922237814,
136.21764029233765,
139.00872002980512,
140.96129813630498,
150.9480493355987,
146.40865069276424,
145.9483799566807,
142.62330037182684,
142.21040802962725,
144.76915778548175,
141.97798278518232,
137.5490650845943,
138.4203208697191,
139.73095804225133,
140.68342292786008,
135.88061611840163,
133.64955839261572,
132.78067664376914,
130.8780778196705,
135.6940372744686,
137.86643675895442,
138.11107930934799,
137.51628599978142,
137.9588170195678,
137.64905764910085,
135.4625051316426,
129.96922435002898,
130.38426794793057,
136.96918061226867,
136.14501767978928,
133.7622135800662,
130.2022793932192,
132.72001636973351,
136.95629071343873,
137.88305691907462,
140.01955999683753,
139.8446915796581,
143.37647781613526,
142.01391508642254,
144.36216713319268,
144.9737096566958,
145.14552541303857,
146.5640929456717,
145.97073641023277,
143.0744645033437,
143.88400364885862,
146.89267973801768,
144.5201449931969,
140.5637658253979,
139.75542028453617,
137.43518173546565,
133.21425381310388,
131.67699046687272,
133.5197263077047,
130.73857756965003,
131.13201607889164,
133.81994230496636,
131.6666142759096,
128.31895284311378,
123.10245519401201,
126.30880377573217,
123.15542499016841,
118.33420284172045,
122.5674903056691,
118.59159592104594,
120.20932057163654,
121.58246611555386,
125.6399902947269,
120.53124874099005,
118.79246086128026,
116.668173438869,
117.70700019273197,
117.45903620048482,
116.44142657506148,
119.73399276055777,
118.28736993175514,
119.85906845903561,
116.06585391988912,
113.97990815066743,
112.78725094242543,
114.81582119047776,
109.6799668841549,
108.95133212966361,
111.65954545505289,
115.9221783958202,
117.46891081930384,
117.44005634268021,
120.95817097512302,
118.16397313871835,
120.1003059854188,
120.73249093511764,
120.5083165953807,
118.44233110567755,
114.86002546103927,
110.41370265220564,
110.43316478589095,
113.6710249649667,
110.22962637732927,
111.03168721481741,
115.30082597506708,
115.44876011325081,
115.9923360605597,
121.6740404309968,
120.23294609196063,
116.00153332561922,
115.61670230763525,
112.89173133463628,
112.38652083777234,
117.09210958253887,
118.6398459504796,
122.48156865464112,
123.63996409250872,
120.02277310172188,
118.2446093152666,
115.68637191949705,
114.79329660244126,
116.11500822779074,
113.44469402779934,
117.71032630208222,
118.26497126327232,
118.3135958186278,
112.13664068824158,
111.39211243657014,
109.09379768111027,
116.44361339918838,
118.29178971606287,
119.7727663555229,
119.11856387319028,
119.14533694926237,
122.15601167465837,
122.3023120662543,
121.65131452543146,
121.54349166492906,
120.94654594869391,
123.88994177479853,
123.38002849473746,
125.83463654333252,
126.42367790808983,
125.8616223677806,
123.87769649053547,
124.15663432172781,
121.73883562179829,
118.50503092046549,
118.18270068916907,
118.11428260346031,
120.96687687648286,
115.13000065333698,
113.55638686800202,
113.47267998570784,
112.51431612793075,
113.93073873934054,
112.21116602060009,
110.88376112423268,
113.75884920799321,
112.97416026296672,
114.9975031928157,
115.40594006144529,
108.97993029655473,
109.11689754785728,
107.52844636426005,
106.94139229483342,
107.32678748402881,
105.31758401209683,
103.4800170931295,
103.93338805705007,
102.69212665445306,
102.1851807876706,
101.56948981559646,
103.99275448682953,
101.7427964681425,
99.52672873476168,
102.59319559482692,
105.76041115198541,
105.69728989654605,
105.63016293769043,
103.14191593884141,
102.08465853081564,
101.53176319323708,
101.6728404476556,
103.09216233208382,
100.74650252670982,
103.93932313809015,
104.94152992571709,
103.69000789192245,
103.95471928444113,
104.85530593383417,
106.34881928730078,
108.28545442777941,
98.80053924787627,
95.83630463788589],
[94.00699438173665,
143.56969646530794,
141.95407101657204,
141.96264922517767,
144.32464477303438,
145.07541132893155,
146.4649780749609,
146.04090692678506,
146.31480598359036,
143.53624145790022,
143.6246053582737,
146.41970054484287,
146.37518843163133,
145.92866249187972,
145.98877792291304,
147.5114706509048,
146.94803574283208,
144.0440109452062,
143.62240548432717,
143.6356516175576,
139.8630782693517,
142.7411190584796,
139.6932734599871,
138.3195433846947,
140.68062451076835,
139.45668477064217,
140.59107256496858,
144.78349874925956,
145.66461278563818,
144.9850841851004,
145.5416888435106,
143.69695988434003,
141.8693465981458,
144.13491041724458,
141.9186815133104,
139.65628045025016,
139.32193680647472,
140.99631812871945,
143.77615950321749,
144.05400633359793,
144.88937616184407,
143.4447679836722,
143.3151114074594,
142.95866422993132,
141.5798273629268,
141.93190007080557,
141.35063910213245,
134.80170826798394,
134.25365963410715,
134.0119656996788,
135.29083831012164,
136.92710361009085,
138.42780150572824,
136.1810377014555,
136.51750651925818,
133.4171421315886,
132.38807349275177,
130.5627540961426,
126.99291350464996,
127.20349890045703,
123.7858015342221,
125.86496223907231,
126.14371878870199,
129.8496780129342,
132.63837655534357,
134.59034453717763,
144.52950686505758,
139.9789094493787,
139.51602988525218,
136.189778200797,
135.77867770100735,
138.33603111247766,
135.54475899308974,
131.10407836259236,
131.97597278404533,
133.28706518316503,
134.24049897225615,
129.42671351110062,
127.19475110211371,
126.32634716020463,
124.42345429678672,
129.22919885052374,
131.40087588356795,
131.6466818066055,
131.05293635800012,
131.49656751723597,
131.18798177583167,
129.000288610206,
123.49308610747696,
123.90922407283851,
130.47496637865274,
129.65143366928075,
127.26726703160857,
123.70210364657787,
126.21776904407938,
130.44733415871738,
131.37471442183724,
133.51053264883956,
133.33684297038837,
136.86374134842157,
135.50124713701942,
137.84781349057604,
138.4605219471216,
138.63357231365808,
140.05215865075013,
139.46037791887667,
136.56096703999546,
137.37128286759824,
140.37723624232203,
138.00298457562414,
134.0403752871912,
133.23283285232645,
130.91114383040505,
126.68294831874944,
125.14547345946994,
126.98748410713355,
124.20426215387288,
124.59884310726243,
127.28489633116924,
125.1302690618658,
121.77864497007704,
116.55023724679651,
119.75261217738677,
116.59500245833728,
111.76472155588895,
115.99123701923627,
112.00878462627303,
113.62572732889444,
114.99751199212132,
119.04965930462963,
113.92851572609926,
112.18992317299617,
110.064317255652,
111.10377877882657,
110.85737038526194,
109.84005758000663,
113.12901985911115,
111.6824864530893,
113.25411677660368,
109.45452595801254,
107.36816332024506,
106.17589890321625,
108.20356631931371,
103.05544469045186,
102.32792280318621,
105.03421193667648,
109.28983922708653,
110.83676681806092,
110.80912411997778,
114.32268736586799,
111.52555318025429,
113.46117078356687,
114.09671429573747,
113.87155437502233,
111.80450047154154,
108.21728669830486,
103.7632608887919,
103.78463157781617,
107.01834811448614,
103.5722380722042,
104.37507372853473,
108.63728745332921,
108.7880607447052,
109.33141720102645,
114.99975567529702,
113.55835376843092,
109.31971085260258,
108.93656245831087,
106.20928631279126,
105.70517787080502,
110.40214548936247,
111.95008051210023,
115.78618997372438,
116.94555281277285,
113.32316103104957,
111.54496663794073,
108.98485581764888,
108.09272032887198,
109.41498286321,
106.74231072416536,
111.00034679370975,
111.5564160800235,
111.60630184863298,
105.41242994059436,
104.66865012274845,
102.36866337867544,
109.6944465390189,
111.54236136532963,
113.02571019768989,
112.37151955483895,
112.39789215193335,
115.40574672773948,
115.55366809434656,
114.9036915930047,
114.79711902426479,
114.20121285400012,
117.14184352283223,
116.63300568395023,
119.08587022269282,
119.67611486803797,
119.11518071736845,
117.13052037215988,
117.4106533458735,
114.99111784032296,
111.75402010793215,
111.43288908032686,
111.3657041065735,
114.21585388111076,
108.36377555004397,
106.79063074972646,
106.70804862491143,
105.75124696800808,
107.16699811383671,
105.44796435625382,
104.12123021844249,
106.99329819540138,
106.20963599856096,
108.23201863921976,
108.64175406462915,
102.19855364349513,
102.33712395453846,
100.74773509144549,
100.1637587335738,
100.5485629959665,
98.5387020711062,
96.70085494661629,
97.15543633410935,
95.91474067426711,
95.40878591054543,
94.79414113676631,
97.21578179440176,
94.96447568038172,
92.74768260795322,
95.81140175345341,
98.97549237237729,
98.91363489448345,
98.84773949461321,
96.3578245455941,
95.30153842017982,
94.74953558302087,
94.89179686794259,
96.31171576330992,
93.96448231512959,
97.15354401126038,
98.15685778023378,
96.90628191516043,
97.17180962555267,
98.07331768151398,
99.5673784503432,
101.50334710359785,
91.97865481056202,
89.01196022731773])
상한가와 하한가의 리스트 타입 데이터를
- 날짜를 인덱스로하는 시리즈 타입으로 변환하기
- 추후 시각화시 결과값의 인덱스와 매핑하여 그리기 위해서...
lower_series = pd.Series(lower, index=test_data.index)
upper_series = pd.Series(upper, index=test_data.index)
lower_series, upper_series
![](https://blog.kakaocdn.net/dn/bCvXOk/btsDxy5qrcY/9x1eJlk98ebnaoiwuGAQrK/img.png)
전체 시각화
훈련데이터, 테스트데이터 시각화
plt.figure(figsize=(20, 6))
plt.title("시계열 분석 결과 시각화")
### 훈련데이터 그리기 (90%)
plt.plot(train_data, label="train_data")
### 테스트데이터 그리기 (10%)
plt.plot(test_data, label="test_data(예측 전 실제값)", c="b")
### 테스트데이터로 예측한 결과 그리기
plt.plot(fc, label="예측결과", c="r")
### 상한가(상한 바운드), 하한가(하한 바운드) 그리기
# alpha=.5 : 투명도 (숫자가 낮을수록 투명해짐)
plt.fill_between(lower_series.index, lower_series, upper_series, alpha=.9, color="b")
plt.legend()
plt.show()
plt.figure(figsize=(20, 6))
plt.title("시계열 분석 결과 시각화")
### 훈련데이터 그리기 (90%)
# plt.plot(train_data, label="train_data")
### 테스트데이터 그리기 (10%)
plt.plot(test_data, label="test_data(예측 전 실제값)", c="b")
### 테스트데이터로 예측한 결과 그리기
plt.plot(fc, label="예측결과", c="r")
### 상한가(상한 바운드), 하한가(하한 바운드) 그리기
# alpha=.5 : 투명도 (숫자가 낮을수록 투명해짐)
plt.fill_between(lower_series.index, lower_series, upper_series, alpha=.5, color="c")
plt.legend()
plt.show()
모델 성능평가
라이브러리
from sklearn.metrics import mean_absolute_error, mean_squared_error
import math
평균제곱오차(MSE)
- np.exp( x ) : 입력 값 x에 대한 지수 함수를 계산하여 반환, e^x
mse = mean_squared_error(np.exp(test_data), np.exp(fc))
mse
4.535004495593973e+128
평균절대오차(MAE)
mae = mean_absolute_error(np.exp(test_data), np.exp(fc))
mae
4.297931556627558e+63
RMSE(Root Mean Squared Error)
- 예측값과 실제값 간의 거리를 나타내는 지표
- 값이 작을수록 모델의 성능이 좋다고 해석
rmse = math.sqrt(mean_squared_error(np.exp(test_data), np.exp(fc)))
rmse
2.129554999429217e+64
MAPE(Mean Absolute Percentage Error)
- 예측값과 실제값 간의 백분율 오차 평균
mape = np.mean(np.abs(np.exp(fc) - np.exp(test_data)) / np.abs(np.exp(test_data)))
mape * 100
11890.702675333598
1년 후 예측하기 (한국 증권거래소) 🐥
* 한국 증권거래소(KRX)의 주식거래일을 기준으로 → 1년 후 예측하기
* 사용 라이브러리
- 한국증권거래소(KRX)의 주식거래일자에 대한 데이터 수집을 위한 라이브러리
- 라이브러리 설치 : pip install exchange_calendars
한국 증권거래소(KRX)의 주식거래일을 기준으로 → 1년 후 예측하기
라이브러리
import exchange_calendars as ecals
주식 거래일자 수집하기
### 원본 인덱스의 마지막 인덱스 일자 이후부터 1년치에 대한 거래일자 수집
# 거래 시작일
start = "2022-11-01"
# 거래 종료일
end = "2023-10-31"
### 한국증권거래소(KRX) code값 : XKRX
k = ecals.get_calendar("XKRX")
k
시작 및 종료 기간 동안의 거래일 정보 가지고 오기
df = pd.DataFrame(k.schedule.loc[start : end])
df
날짜 형태 변환 - open 컬럼을 사용
- open컬럼을 사용하기 위해 날짜 정보를 리스트에 추가하기
data_list = []
for i in df["open"]:
data_list.append(i.strftime("%Y-%m-%d"))
# print(i.strftime("%Y-%m-%d"))
### DatetimeIndex 형태로 변환하기
date_index = pd.DatetimeIndex(data_list)
date_index
1년 후 주가 예측하기
fc2, upper2, lower2 = forecast(len(date_index), model_fit, date_index)
fc2
2022-11-01 96.546121
2022-11-02 96.615374
2022-11-03 96.617080
2022-11-04 96.662884
2022-11-07 96.680745
...
2023-10-25 103.528079
2023-10-26 103.556831
2023-10-27 103.585583
2023-10-30 103.614335
2023-10-31 103.643087
Length: 247, dtype: float64
상한가, 하한가 시리즈 타입으로 변환하기
upper2_series = pd.Series(upper2, index=date_index)
lower2_series = pd.Series(lower2, index=date_index)
upper2_series, lower2_series
시각화
plt.figure(figsize=(20, 6))
plt.title("시계열 분석 결과 시각화")
### 훈련데이터 그리기 (90%)
plt.plot(train_data, label="train_data")
### 테스트데이터 그리기 (10%)
plt.plot(test_data, label="test_data(예측 전 실제값)", c="b")
### 테스트데이터로 예측한 결과 그리기
plt.plot(fc, label="예측결과", c="r")
### 1년 후 주가 예측 그리기
plt.plot(fc2, label="1년 후 예측결과", c="g")
### 상한가(상한 바운드), 하한가(하한 바운드) 그리기
plt.fill_between(lower_series.index, lower_series, upper_series, alpha=.9, color="k")
### 1년 후 예측 → 상한가(상한 바운드), 하한가(하한 바운드) 그리기
plt.fill_between(lower2_series.index, lower2_series, upper2_series, alpha=.9, color="c")
plt.legend(loc = "upper left")
plt.show()
'인공지능 > 딥러닝' 카테고리의 다른 글
[시계열분석] 주식데이터 주가예측 - Prophet 모델 (3) | 2024.01.16 |
---|---|
[시계열 분석] 주식데이터 주가예측 - 주식흐름( 롤링rolling ), ARIMA 모델, AR(자기상관), MA(이동평균), 정상성/비정상성(차분), ADF 테스트(adfuller), ACF plot/PACF plot, ndiffs/auto_arima 함수 (4) | 2024.01.15 |
[YOLO] 이미지 증식 테스트 + 사람이미지 증식 및 4차원 독립변수와 종속변수(라벨링) 생성하기 + (응용)비프음 출력 (41) | 2024.01.11 |
[YOLO] YOLO 카메라 객체탐지 (2) | 2024.01.11 |
[YOLO] YOLO 설치 및 객체탐지 Image사용 (1) | 2024.01.10 |