延續昨天,我們拿到了各個券商分點5/13~5/16 對所羅門進行買賣的籌碼資訊
,
既然資料收集的部分解決了,下一步來做資料前處理,接著用模型來訓練。
原本DAY10 爬蟲拿資料? 來學習怎麼畫股價K線圖! Step(2/2): 自己爬股價 這篇是以台積電舉例,
現在再用一次這段程式碼,抓所羅門2359今年5月的股價
。
按照DAY9決定欄位! 天下沒有白吃的午餐,股價、籌碼資料的其他來源? 決定的欄位,
股價資料
的這些欄位資料和籌碼資料
開盤價, 收盤價, 最高價, 最低價, 成交量
104 106 99.9 104.5 15868.696 (2024/5/13)
104 114.5 101 114.5 38083.434 (2024/5/14)
120 125.5 120 125.5 23445.998 (2024/5/15)
130 134.5 118 120 95284.736 (2024/5/16)
121 132 119 132 59619.378 (2024/5/17)
把 昨天 拿到的籌碼資料,
先以日期
排序(由小到大)整個資料表,接著把日期
放到最前面的欄位,把總數
刪去。
現在大概變這樣
日期 券商代碼 買進(張) 賣出(張) 買賣超(張)
2024/05/13 1020 99 81 18
2024/05/13 1021 14 93 -79
2024/05/13 1022 5 23 -18
. . .
開始工人智慧! ctrl+c,ctrl+v,把股價按照日期填在後面。
日期 券商代碼 買進(張) 賣出(張) 買賣超(張) 開盤價 最高價 最低價 收盤價 成交量
2024/05/13 1020 99 81 18 104 106 99.9 104.5 15868.696
2024/05/13 1021 14 93 -79 104 106 99.9 104.5 15868.696
2024/05/13 1022 5 23 -18 104 106 99.9 104.5 15868.696
2024/05/13 1023 45 19 26 104 106 99.9 104.5 15868.696
2024/05/13 1024 8 5 3 104 106 99.9 104.5 15868.696
. . .
大概變成這樣,取名Merged_to_train.xlsx
好了。
地理資訊
合併!DAY13 拿到的券商地點,存成了PLUS_lat_lng_address.xlsx
含金量滿滿的文章? Step(1/4):關鍵分點籌碼爬蟲,之前拿到的券商地點,要怎麼處理?
橫坐標、縱坐標
#讀取
PLUS_lat_lng = pd.read_excel('PLUS_lat_lng_address.xlsx')
#PLUS_lat_lng.head()
# 把欄位重新命名成 lat, lng
PLUS_lat_lng = PLUS_lat_lng.rename(columns={
'緯度': 'lat',
'經度': 'lng'
})
PLUS_lat_lng.head()
券商代碼 券商名稱 開業日 地址 lat lng
0 1020 合庫 2011-12-02 台北市大安區忠孝東路四段285號 25.041682 121.554221
1 1021 合庫- 台中 2011-12-02 台中市西區民權路91號 24.138065 120.679533
2 1022 合庫-台南 2011-12-02 台南市北區成功路48號 22.998140 120.207742
3 1023 合庫-高雄 2011-12-02 高雄市大勇路97號 22.624785 120.284190
4 1024 合庫-嘉義 2011-12-02 嘉義市國華街279號 23.480549 120.448310
轉換成TWD97座標制
# 轉換
result = PLUS_lat_lng.apply(lambda row: wgs84_to_twd97(row['lat'], row['lng']), axis=1)
PLUS_lat_lng['橫坐標'], PLUS_lat_lng['縱坐標'] = zip(*result)
print(PLUS_lat_lng.head())
# 將新的資料存 Excel
PLUS_lat_lng.to_excel('PLUS_lat_lng_橫縱.xlsx', index=False)
把地理位置的資訊接上去
import pandas as pd
# 讀取兩個CSV文件
df1 = pd.read_excel('E:/時空資料分析/關鍵分點籌碼分析_實測/PLUS_lat_lng_橫縱.xlsx')
df2 = pd.read_excel('E:/時空資料分析/關鍵分點籌碼分析_實測/Merged_to_train.xlsx')
# 將"代號"列設為索引
df2 = df2.set_index('券商代碼')
# 使用資料表df1的"代碼"列作為索引,並將df1的特定列合併到df2
df2 = df2.join(df1.set_index('券商代碼')[['橫坐標', '縱坐標']], how='left')
## 不能這樣合併後直接用哦,因為裡面有重複資料 !!!!
# 將結果寫入新的CSV文件
df2.to_excel('Merged_to_train_ALL.xlsx', index=True)
日期 買進(張) 賣出(張) 買賣超(張) 開盤價 最高價 最低價 收盤價 成交量 橫坐標 縱坐標
券商代碼
1020 2024/05/13 99 81 18 104 106.0 99.9 104.5 15868.696 305924 2770508
1021 2024/05/13 14 93 -79 104 106.0 99.9 104.5 15868.696 217429 2670350
1022 2024/05/13 5 23 -18 104 106.0 99.9 104.5 15868.696 168780 2544296
1023 2024/05/13 45 19 26 104 106.0 99.9 104.5 15868.696 176418 2502912
1024 2024/05/13 8 5 3 104 106.0 99.9 104.5 15868.696 193646 2597605
... ... ... ... ... ... ... ... ... ... ... ...
9A9W 2024/05/16 451 389 62 130 134.5 118.0 120.0 95284.736 213376 2672724
9A9x 2024/05/16 124 139 -15 130 134.5 118.0 120.0 95284.736 281093 2764818
9A9X 2024/05/16 124 139 -15 130 134.5 118.0 120.0 95284.736 248958 2743608
9A9Y 2024/05/16 105 97 8 130 134.5 118.0 120.0 95284.736 297253 2767298
9A9Z 2024/05/16 11 3 8 130 134.5 118.0 120.0 95284.736 305450 2772146
3183 rows × 11 columns
有點強迫症,然後再手動把 橫坐標、縱坐標
移動到中間,調整成 DAY9預想合併的欄位一樣。
日期
->(日期時間類型)券商代號
->(用於區分不同的券商分點)買進(張)、賣出(張)、買賣超(張)
->(交易行為、籌碼資訊)橫坐標、縱坐標
->(券商分點地理位置)開盤價、最高價、最低價、收盤價、成交量
(股價資訊、交易量)
import numpy as np
import pandas as pd
df = pd.read_excel('E:/時空資料分析/關鍵分點籌碼分析_實測/Merged_to_train_ALL.xlsx')
df.info() # 看一下資料型態
# 缺失值處理
df = df.fillna(method='ffill')
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3183 entries, 0 to 3182
Data columns (total 12 columns):Column Non-Null Count Dtype
0 日期 3183 non-null object
1 券商代碼 3183 non-null object
2 買進(張) 3183 non-null object
3 賣出(張) 3183 non-null object
4 買賣超(張) 3183 non-null object
5 橫坐標 3183 non-null int64
6 縱坐標 3183 non-null int64
7 開盤價 3183 non-null int64
8 最高價 3183 non-null float64
9 最低價 3183 non-null float64
10 收盤價 3183 non-null float64
11 成交量 3183 non-null float64
dtypes: float64(4), int64(3), object(5)
from sklearn.preprocessing import MinMaxScaler
# 對數值資料做標準化
scaler = MinMaxScaler()
scaled_data = scaler.fit_transform(df[['買進(張)', '賣出(張)', '買賣超(張)', '開盤價', '最高價', '最低價', '收盤價', '成交量']])
引入ConvLSTM的模型要用到的工具
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import ConvLSTM2D, Dense, Flatten
from tensorflow.keras.optimizers import Adam
# 創建時間序列資料
def create_sequences(data, time_steps=1):
X, y = [], []
for i in range(len(data)-time_steps):
X.append(data[i:(i+time_steps)])
y.append(data[i+time_steps, -1])
return np.array(X), np.array(y)
time_steps = 10
X, y = create_sequences(scaled_data, time_steps)
把資料重新塑形
# 重塑以適應 ConvLSTM 輸入
X = X.reshape((X.shape[0], time_steps, 1, X.shape[2], 1))
# 建立 ConvLSTM 模型
model = Sequential([
ConvLSTM2D(filters=64, kernel_size=(1, 2), input_shape=(time_steps, 1, X.shape[3], 1), return_sequences=True),
ConvLSTM2D(filters=32, kernel_size=(1, 2), return_sequences=False),
Flatten(),
Dense(50, activation='relu'),
Dense(1)
])
model.compile(optimizer=Adam(learning_rate=0.001), loss='mse')
model.summary()
# 訓練模型
history = model.fit(X, y, epochs=50, batch_size=32, validation_split=0.1)
# 預測
predictions = model.predict(X)
---> X = X.reshape((X.shape[0], time_steps, 1, X.shape[2], 1))
IndexError: tuple index out of range
資料維度的地方發生了問題
。不太確定要怎麼改,跟chatGPT討論一下:
在重塑數據時,X.shape 沒有你期望的四個維度導致的。
- 首先,檢查 create_sequences 函數的輸出,確保 X 和 y 的形狀正確。
print(X.shape) # 應該是 (樣本數, time_steps, 特徵數)
print(y.shape) # 應該是 (樣本數,)
2.根據 X 的形狀進行重塑。如果 X 的形狀是 (樣本數, time_steps, 特徵數),那麼你需要將其重塑為 (樣本數, time_steps, 1, 特徵數, 1)。
# 創建時間序列數據
def create_sequences(data, time_steps=1):
X, y = [], []
for i in range(len(data)-time_steps):
X.append(data[i:(i+time_steps)])
y.append(data[i+time_steps, -1])
return np.array(X), np.array(y)
time_steps = 10
X, y = create_sequences(scaled_data, time_steps)
# 檢查一下 X 的形狀
print("Original X shape:", X.shape)
# 重塑資料適應 ConvLSTM 輸入
X = X.reshape((X.shape[0], time_steps, 1, X.shape[2], 1))
# 再檢查 X 的形狀
print("Reshaped X shape:", X.shape)
看了chatGPT給的修改過的程式碼,真的很想吐槽,大哥您根本就沒改@@''
你就只是在中間加入Print阿。
按照修改改了一下,結果跑出了一個新的錯誤??? (剛才怎麼沒有跑出來)
錯誤太長,只放錯誤的原因和錯誤位置就好。
---> scaled_data = scaler.fit_transform(df[['買進(張)', '賣出(張)', '買賣超(張)', '開盤價', '最高價', '最低價', '收盤價', '成交量']])
ValueError: could not convert string to float: '2,795'"
沒辦法把字串轉換成浮點數,因為資料裡面有物件(object)
的型態,
dtypes: float64(4), int64(3), object(5)
0 日期 3183 non-null object
1 券商代碼 3183 non-null object
2 買進(張) 3183 non-null object
3 賣出(張) 3183 non-null object
4 買賣超(張) 3183 non-null object
逗點
,讓資料型態呈現為非數值
。日期 券商代碼 買進(張) 賣出(張) 買賣超(張) 橫坐標 縱坐標 開盤價 最高價 最低價 收盤價 成交量
ex. 2024/05/16 8560 1,222 1,154 68 301804 2771069 130 134.5 118 120 95284.736
# 移除數值欄位中的非數值字符,再轉換為float格式
cols_to_convert = ['買進(張)', '賣出(張)', '買賣超(張)', '開盤價', '最高價', '最低價', '收盤價', '成交量']
for col in cols_to_convert:
df[col] = df[col].astype(str).str.replace(',', '').astype(float)
每日記錄:
先改到這邊,感覺自己對ConvLSTM非常不熟,只有上課和看文章學到的概念,不太懂怎麼應用 0..0
明天找程式強者我朋友討論一下。
參考文章&資料來源