|
@@ -1,124 +1,124 @@
|
1
|
|
-from sqlalchemy import create_engine
|
2
|
|
-import pymysql
|
3
|
|
-import pandas as pd
|
4
|
|
-import numpy as np
|
5
|
|
-
|
6
|
|
-pymysql.install_as_MySQLdb()
|
7
|
|
-engine = create_engine("mysql+mysqldb://root:"+"tokki1127"+"@127.0.0.1/stock", encoding='utf-8')
|
8
|
|
-conn = engine.connect()
|
9
|
|
-
|
10
|
|
-df = pd.read_sql_query("select * from stock_trade where 종목코드 = '000660'", conn)
|
11
|
|
-df.name = "주가변동"
|
12
|
|
-print(df.head())
|
13
|
|
-
|
14
|
|
-import matplotlib.pyplot as plt
|
15
|
|
-# 화면 크기
|
16
|
|
-plt.figure(figsize=(16,8))
|
17
|
|
-
|
18
|
|
-# 인덱스 확인 (그래프의 X축 : DB로 부터 읽어온 값은 DataFrame으로 불러올 시, 0부터 숫자가 붙어있음)
|
19
|
|
-print(df.index)
|
20
|
|
-
|
21
|
|
-# 날짜를 그래프 Y축으로, X축은 디폴트로 0부터 붙은 인덱스 값
|
22
|
|
-#plt.plot(df['날짜'], label='종가 그래프')
|
23
|
|
-
|
24
|
|
-# 날짜 포맷 변경
|
25
|
|
-#df['날짜'] = pd.to_datetime (df.날짜, format = '%Y-%m-%d') # 날짜 포맷이 동일하기 때문에 수행할 필요가 없음
|
26
|
|
-
|
27
|
|
-# 종가를 그래프 Y축으로, X축은 날짜
|
28
|
|
-df.index = df['날짜']
|
29
|
|
-plt.plot(df['종가'], label='종가 그래프')
|
30
|
|
-#plt.show()
|
31
|
|
-print(df)
|
32
|
|
-
|
33
|
|
-
|
34
|
|
-
|
35
|
|
-# 정렬
|
36
|
|
-# df.sort_index() 는 인덱스인 날짜로 정렬
|
37
|
|
-# df.sort_index(ascending=True, axis=0) 역시 인덱스 정렬
|
38
|
|
-# df.sort_index(ascending=True, axis=1) 컬럼 이름으로 왼쪽부터 오른쪽으로 정렬
|
39
|
|
-df = df.sort_index(ascending=True, axis=0) # 수행하지 않아도 이미 DB로부터 읽어올 때 날짜로 정렬
|
40
|
|
-
|
41
|
|
-
|
42
|
|
-
|
43
|
|
-
|
44
|
|
-# 날짜와 목표변수인 종가로 이루어진 DataFrame 만들기
|
45
|
|
-
|
46
|
|
-# Case1. 빈 DataFrame을 만든 후, 복사하기
|
47
|
|
-
|
48
|
|
-# 날짜와 목표변수로 빈 dataframe 만들기
|
49
|
|
-new_data = pd.DataFrame(index=range(0, len(df)), columns=['날짜', '종가'])
|
50
|
|
-print(new_data)
|
51
|
|
-
|
52
|
|
-# 날짜와 목표변수인 종가로 dataframe 에 df값 매칭
|
53
|
|
-for i in range(0,len(df)):
|
54
|
|
- new_data['날짜'][i] = df['날짜'][i]
|
55
|
|
- new_data['종가'][i] = df['종가'][i]
|
56
|
|
-print(new_data.head()) # 날짜와 종가에 대한 데이터
|
57
|
|
-
|
58
|
|
-
|
59
|
|
-# Case2. 기존 DataFrame을 복사한 후, 불 필요한 컬럼 제거
|
60
|
|
-# copy()함수에는 행 또는 열을 제거할 때 사용, axis=1일때 세로 축 삭제, axis=0일때 가로 축 삭제
|
61
|
|
-# drop()함수에는 행 또는 열을 제거할 때 사용, axis=1일때 세로 축 삭제, axis=0일때 가로 축 삭제
|
62
|
|
-new_data = df.copy(deep=True)
|
63
|
|
-new_data = new_data.drop(['시가', '고가', '저가', '거래량', '종목코드'], axis=1)
|
64
|
|
-new_data.index = range(len(df))
|
65
|
|
-print(new_data.head())
|
66
|
|
-
|
67
|
|
-
|
68
|
|
-
|
69
|
|
-
|
70
|
|
-# raw 데이터 생성 완료, 이후에는 validation과 train데이터를 통한 평균제곱근 오차 수행
|
71
|
|
-
|
72
|
|
-# 데이터를 train과 validation 세트로 분할하는 동안 '날짜' 요소가 손상되므로 임의 분할(random splitting)을 사용할 수 없음
|
73
|
|
-# 작년의 데이터를 validation 세트로 설정하고 4년 전의 데이터를 train 세트로 설정
|
74
|
|
-
|
75
|
|
-# splitting into train and validation
|
76
|
|
-print(new_data['날짜'] < '2019-01-01')
|
77
|
|
-train = new_data[new_data['날짜'] < '2019-01-01']
|
78
|
|
-valid = new_data[new_data['날짜'] >= '2019-01-01']
|
79
|
|
-
|
80
|
|
-# shapes of training set
|
81
|
|
-print('\n Shape of training set:')
|
82
|
|
-print(train.shape)
|
83
|
|
-
|
84
|
|
-# shapes of validation set
|
85
|
|
-print('\n Shape of validation set:')
|
86
|
|
-print(valid.shape)
|
87
|
|
-
|
88
|
|
-# validation 세트에 대한 예측을 만들고, 실제 값을 사용하여 RMSE(평균 제곱근 오차)을 점검
|
89
|
|
-# validation 세트에 대한 예측 (Observed value값의 범위를 valid.shape[0] 로 선정)
|
90
|
|
-print('유효성 검사를 위한 행의 수 : %d' % valid.shape[0])
|
91
|
|
-validRaw = valid.shape[0]
|
92
|
|
-preds = [] # 훈련 셋을 각 구간(Observed value값) 마다 이동평균 값을 저장
|
93
|
|
-for i in range(0, validRaw):
|
94
|
|
- a = train['종가'][len(train) - validRaw + i:].sum() + sum(preds)
|
95
|
|
- b = a / validRaw
|
96
|
|
- preds.append(b)
|
97
|
|
-print(preds)
|
98
|
|
-print(len(preds))
|
99
|
|
-
|
100
|
|
-# 실제 값을 사용하여 RMSE(평균 제곱근 오차)을 점검
|
101
|
|
-rms = np.sqrt(np.mean(np.power((np.array(valid['종가']) - preds), 2)))
|
102
|
|
-print('\n RMSE value on validation set:')
|
103
|
|
-print(rms)
|
104
|
|
-
|
105
|
|
-
|
106
|
|
-
|
107
|
|
-# RMSE를 확인하는 것만으로는 모델의 성능을 이해하는 데 도움이되지 않습니다.
|
108
|
|
-# 더 직관적으로 이해하기 위해 이것을 시각화 해 봅시다. 여기에 실제 값과 함께 예측 된 값의 도표을 확인
|
109
|
|
-# Pandas에서는 파생 DataFrame에 수정을 가하는 것을 권장하지 않습니다.(그래서 경고를 띄우는 것이죠.)
|
110
|
|
-# 대신 Pandas는 copy() 메서드를 통해 파생 DataFrame에 독립적인 메모리를 부여한 뒤 여기에 수정을 가하도록 유도하지요.
|
111
|
|
-#valid['예측'] = 0
|
112
|
|
-#valid['예측'] = preds
|
113
|
|
-#print(valid)
|
114
|
|
-
|
115
|
|
-valid = valid.copy();
|
116
|
|
-valid['예측'] = preds
|
117
|
|
-print(valid)
|
118
|
|
-#train.index = train['날짜']
|
119
|
|
-print(train.index)
|
120
|
|
-plt.plot(train['종가'])
|
121
|
|
-#plt.show()
|
122
|
|
-print(valid.index)
|
123
|
|
-plt.plot(valid[['종가', '예측']])
|
|
1
|
+from sqlalchemy import create_engine
|
|
2
|
+import pymysql
|
|
3
|
+import pandas as pd
|
|
4
|
+import numpy as np
|
|
5
|
+
|
|
6
|
+pymysql.install_as_MySQLdb()
|
|
7
|
+engine = create_engine("mysql+mysqldb://root:"+"swhacademy!"+"@192.168.0.41/market", encoding='utf-8')
|
|
8
|
+conn = engine.connect()
|
|
9
|
+
|
|
10
|
+df = pd.read_sql_query("select * from stock_trade where 종목코드 = '000660'", conn)
|
|
11
|
+df.name = "주가변동"
|
|
12
|
+print(df.head())
|
|
13
|
+
|
|
14
|
+import matplotlib.pyplot as plt
|
|
15
|
+# 화면 크기
|
|
16
|
+plt.figure(figsize=(16,8))
|
|
17
|
+
|
|
18
|
+# 인덱스 확인 (그래프의 X축 : DB로 부터 읽어온 값은 DataFrame으로 불러올 시, 0부터 숫자가 붙어있음)
|
|
19
|
+print(df.index)
|
|
20
|
+
|
|
21
|
+# 날짜를 그래프 Y축으로, X축은 디폴트로 0부터 붙은 인덱스 값
|
|
22
|
+#plt.plot(df['날짜'], label='종가 그래프')
|
|
23
|
+
|
|
24
|
+# 날짜 포맷 변경
|
|
25
|
+#df['날짜'] = pd.to_datetime (df.날짜, format = '%Y-%m-%d') # 날짜 포맷이 동일하기 때문에 수행할 필요가 없음
|
|
26
|
+
|
|
27
|
+# 종가를 그래프 Y축으로, X축은 날짜
|
|
28
|
+df.index = df['날짜']
|
|
29
|
+plt.plot(df['종가'], label='종가 그래프')
|
|
30
|
+#plt.show()
|
|
31
|
+print(df)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+# 정렬
|
|
36
|
+# df.sort_index() 는 인덱스인 날짜로 정렬
|
|
37
|
+# df.sort_index(ascending=True, axis=0) 역시 인덱스 정렬
|
|
38
|
+# df.sort_index(ascending=True, axis=1) 컬럼 이름으로 왼쪽부터 오른쪽으로 정렬
|
|
39
|
+df = df.sort_index(ascending=True, axis=0) # 수행하지 않아도 이미 DB로부터 읽어올 때 날짜로 정렬
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+# 날짜와 목표변수인 종가로 이루어진 DataFrame 만들기
|
|
45
|
+
|
|
46
|
+# Case1. 빈 DataFrame을 만든 후, 복사하기
|
|
47
|
+
|
|
48
|
+# 날짜와 목표변수로 빈 dataframe 만들기
|
|
49
|
+new_data = pd.DataFrame(index=range(0, len(df)), columns=['날짜', '종가'])
|
|
50
|
+print(new_data)
|
|
51
|
+
|
|
52
|
+# 날짜와 목표변수인 종가로 dataframe 에 df값 매칭
|
|
53
|
+for i in range(0,len(df)):
|
|
54
|
+ new_data['날짜'][i] = df['날짜'][i]
|
|
55
|
+ new_data['종가'][i] = df['종가'][i]
|
|
56
|
+print(new_data.head()) # 날짜와 종가에 대한 데이터
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+# Case2. 기존 DataFrame을 복사한 후, 불 필요한 컬럼 제거
|
|
60
|
+# copy()함수에는 행 또는 열을 제거할 때 사용, axis=1일때 세로 축 삭제, axis=0일때 가로 축 삭제
|
|
61
|
+# drop()함수에는 행 또는 열을 제거할 때 사용, axis=1일때 세로 축 삭제, axis=0일때 가로 축 삭제
|
|
62
|
+new_data = df.copy(deep=True)
|
|
63
|
+new_data = new_data.drop(['시가', '고가', '저가', '거래량', '종목코드'], axis=1)
|
|
64
|
+new_data.index = range(len(df))
|
|
65
|
+print(new_data.head())
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+# raw 데이터 생성 완료, 이후에는 validation과 train데이터를 통한 평균제곱근 오차 수행
|
|
71
|
+
|
|
72
|
+# 데이터를 train과 validation 세트로 분할하는 동안 '날짜' 요소가 손상되므로 임의 분할(random splitting)을 사용할 수 없음
|
|
73
|
+# 작년의 데이터를 validation 세트로 설정하고 4년 전의 데이터를 train 세트로 설정
|
|
74
|
+
|
|
75
|
+# splitting into train and validation
|
|
76
|
+print(new_data['날짜'] < '2019-01-01')
|
|
77
|
+train = new_data[new_data['날짜'] < '2019-01-01']
|
|
78
|
+valid = new_data[new_data['날짜'] >= '2019-01-01']
|
|
79
|
+
|
|
80
|
+# shapes of training set
|
|
81
|
+print('\n Shape of training set:')
|
|
82
|
+print(train.shape)
|
|
83
|
+
|
|
84
|
+# shapes of validation set
|
|
85
|
+print('\n Shape of validation set:')
|
|
86
|
+print(valid.shape)
|
|
87
|
+
|
|
88
|
+# validation 세트에 대한 예측을 만들고, 실제 값을 사용하여 RMSE(평균 제곱근 오차)을 점검
|
|
89
|
+# validation 세트에 대한 예측 (Observed value값의 범위를 valid.shape[0] 로 선정)
|
|
90
|
+print('유효성 검사를 위한 행의 수 : %d' % valid.shape[0])
|
|
91
|
+validRaw = valid.shape[0]
|
|
92
|
+preds = [] # 훈련 셋을 각 구간(Observed value값) 마다 이동평균 값을 저장
|
|
93
|
+for i in range(0, validRaw):
|
|
94
|
+ a = train['종가'][len(train) - validRaw + i:].sum() + sum(preds)
|
|
95
|
+ b = a / validRaw
|
|
96
|
+ preds.append(b)
|
|
97
|
+print(preds)
|
|
98
|
+print(len(preds))
|
|
99
|
+
|
|
100
|
+# 실제 값을 사용하여 RMSE(평균 제곱근 오차)을 점검
|
|
101
|
+rms = np.sqrt(np.mean(np.power((np.array(valid['종가']) - preds), 2)))
|
|
102
|
+print('\n RMSE value on validation set:')
|
|
103
|
+print(rms)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+# RMSE를 확인하는 것만으로는 모델의 성능을 이해하는 데 도움이되지 않습니다.
|
|
108
|
+# 더 직관적으로 이해하기 위해 이것을 시각화 해 봅시다. 여기에 실제 값과 함께 예측 된 값의 도표을 확인
|
|
109
|
+# Pandas에서는 파생 DataFrame에 수정을 가하는 것을 권장하지 않습니다.(그래서 경고를 띄우는 것이죠.)
|
|
110
|
+# 대신 Pandas는 copy() 메서드를 통해 파생 DataFrame에 독립적인 메모리를 부여한 뒤 여기에 수정을 가하도록 유도하지요.
|
|
111
|
+#valid['예측'] = 0
|
|
112
|
+#valid['예측'] = preds
|
|
113
|
+#print(valid)
|
|
114
|
+
|
|
115
|
+valid = valid.copy();
|
|
116
|
+valid['예측'] = preds
|
|
117
|
+print(valid)
|
|
118
|
+#train.index = train['날짜']
|
|
119
|
+print(train.index)
|
|
120
|
+plt.plot(train['종가'])
|
|
121
|
+#plt.show()
|
|
122
|
+print(valid.index)
|
|
123
|
+plt.plot(valid[['종가', '예측']])
|
124
|
124
|
#plt.show()
|