計劃讓AI幫助編程使用TabPFN模型進行股價推理
原計劃提問的prompt
如何通過akshare庫,獲取股票數據,并生成TabPFN這個模型 可以識別、處理的格式
本意是想讓AI分步執行,先處理股票數據,然后再進行模型訓練,結果豆包超長發揮,直接把后面的模型預測部分也寫了,導致其它兩個模型都需要再附加上模型預測的prompt,
最終除豆包外的prompt
通過akshare庫,獲取股票數據,并生成TabPFN這個模型 可以識別、處理的格式,寫一個完整的預處理示例,并構建一個預測未來 3 天股價漲跌的分類任務
豆包答題
豆包的總體表現中規中矩,只用一句“數據處理”的prompt,它就完成了整個任務,這是沒有預料到的,也就是豆包會搶答了!
但是生成的代碼無法一次跑通,大約修改了2-3次,而且有一個地方AI是改不過來的,必須手工改。當然手工改這個地方其它AI也沒pass。
豆包的代碼
import akshare as ak
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from tabpfn import TabPFNClassifier# 獲取股票數據
stock_data = ak.stock_zh_a_hist(symbol="600519", period="daily", start_date="20200101", end_date="20230101",adjust="qfq")# 數據預處理函數
def prepare_data_for_tabpfn(stock_data, days_ahead=3):df = stock_data.copy()# 動態處理列名original_columns = df.columns.tolist()print(f"原始列名: {original_columns}")if len(original_columns) == 12:df.columns = ['日期', '開盤', '收盤', '最高', '最低', '成交量', '成交額', '振幅', '漲跌幅', '漲跌額', '換手率', '未知列']else:df.columns = [f"col_{i}" for i in range(len(original_columns))]print(f"警告: 列數量不匹配,使用默認列名: {df.columns.tolist()}")# 特征工程df['收盤價_滯后1'] = df['收盤'].shift(1)df['收盤價_滯后2'] = df['收盤'].shift(2)df['收盤價_滯后3'] = df['收盤'].shift(3)df['漲跌幅_1'] = df['收盤'].pct_change(1)df['漲跌幅_2'] = df['收盤'].pct_change(2)df['漲跌幅_3'] = df['收盤'].pct_change(3)df['MA5'] = df['收盤'].rolling(window=5).mean()df['MA10'] = df['收盤'].rolling(window=10).mean()df['MA20'] = df['收盤'].rolling(window=20).mean()df['波動率_5'] = df['漲跌幅_1'].rolling(window=5).std()df['波動率_10'] = df['漲跌幅_1'].rolling(window=10).std()df['成交量_變化'] = df['成交量'].pct_change(1)df['成交量_MA5'] = df['成交量'].rolling(window=5).mean()df['未來漲跌'] = np.where(df['收盤'].shift(-days_ahead) > df['收盤'], 1, 0)df = df.dropna()feature_columns = ['收盤價_滯后1', '收盤價_滯后2', '收盤價_滯后3','漲跌幅_1', '漲跌幅_2', '漲跌幅_3','MA5', 'MA10', 'MA20','波動率_5', '波動率_10','成交量_變化', '成交量_MA5']valid_features = [col for col in feature_columns if col in df.columns]if len(valid_features) < len(feature_columns):missing_features = set(feature_columns) - set(valid_features)print(f"警告: 缺少以下特征: {missing_features}")feature_columns = valid_featuresX = df[feature_columns].valuesy = df['未來漲跌'].valuesfeature_names = feature_columnsX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, shuffle=False)scaler = StandardScaler()X_train = scaler.fit_transform(X_train)X_test = scaler.transform(X_test)return X_train, X_test, y_train, y_test, feature_names# 準備數據
X_train, X_test, y_train, y_test, feature_names = prepare_data_for_tabpfn(stock_data)# 初始化并訓練TabPFN模型
model = TabPFNClassifier(device='cpu')
model.fit(X_train, y_train)# 預測(更新的API調用)
y_pred = model.predict(X_test)
y_prob = model.predict_proba(X_test)[:, 1] # 獲取正類(上漲)的概率# 評估模型
accuracy = np.mean(y_pred == y_test)
print(f"模型準確率: {accuracy:.4f}")# 查看前10個預測結果
print("\n前10個預測結果:")
for i in range(10):print(f"樣本 {i+1}: 實際={y_test[i]}, 預測={y_pred[i]}, 概率={y_prob[i]:.4f}")
豆包的輸出
原始列名: ['日期', '股票代碼', '開盤', '收盤', '最高', '最低', '成交量', '成交額', '振幅', '漲跌幅', '漲跌額', '換手率']模型準確率: 0.5915前10個預測結果:
樣本 1: 實際=1, 預測=1, 概率=0.6773
樣本 2: 實際=0, 預測=0, 概率=0.4536
樣本 3: 實際=1, 預測=1, 概率=0.5055
樣本 4: 實際=1, 預測=0, 概率=0.4203
樣本 5: 實際=1, 預測=1, 概率=0.6198
樣本 6: 實際=1, 預測=1, 概率=0.6163
樣本 7: 實際=1, 預測=1, 概率=0.5240
樣本 8: 實際=1, 預測=1, 概率=0.5556
樣本 9: 實際=0, 預測=1, 概率=0.5418
樣本 10: 實際=1, 預測=0, 概率=0.4687
躍問表現
只用前面一句prompt不行,它沒像豆包那樣幫著把推理、預測也做了,所以要加上一句
prompt
通過akshare庫,獲取股票數據,并生成TabPFN這個模型 可以識別、處理的格式,寫一個完整的預處理示例,并構建一個預測未來 3 天股價漲跌的分類任務
躍問代碼
# 安裝必要的庫(如果尚未安裝)
# pip install akshare pandas sklearn# 導入必要的庫
import akshare as ak
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score# 設置股票代碼和日期范圍
stock_code = "000001" # 示例股票代碼
start_date = "2023-01-01"
end_date = "2023-12-31"# 獲取歷史日線數據
stock_data = ak.stock_zh_a_hist(symbol=stock_code, start_date=start_date, end_date=end_date, adjust="qfq")# 將數據轉換為DataFrame
df = pd.DataFrame(stock_data)# 查看數據
print(df.head())# 數據預處理
# 將日期字段轉換為日期類型
df["日期"] = pd.to_datetime(df["日期"])# 按日期排序
df = df.sort_values(by="日期")# 計算未來3天的漲跌情況
future_3_day_change = df["收盤價"].shift(-3).sub(df["收盤價"])
df["未來3天漲跌"] = future_3_day_change.apply(lambda x: "漲" if x > 0 else "跌")# 刪除NaN值
df.dropna(subset=["未來3天漲跌"], axis=0, how="any")# 查看排序后的數據
print(df.head())# 保存數據為CSV文件
df.to_csv(f"{stock_code}_daily_data.csv", index=False, encoding="utf-8-sig")
print(f"數據已保存到 {stock_code}_daily_data.csv")# 構建分類任務
# 特征和目標變量
X = df[["開盤價", "最高價", "最低價", "成交量"]]
y = df["未來3天漲跌"]# 劃分訓練集和測試集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# 構建隨機森林分類器
clf = RandomForestClassifier(n_estimators=100, random_state=42)# 訓練模型
clf.fit(X_train, y_train)# 預測測試集
y_pred = clf.predict(X_test)# 計算準確率
accuracy = accuracy_score(y_test, y_pred)
print(f"模型準確率為:{accuracy:%.2f}")
這個有報錯,懶得改了
KeyError ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Traceback (most recent call last)
/tmp/ipykernel_35/3161264376.py in <cell line: 0>()
? ? ? 1 # 將日期字段轉換為日期類型
----> 2 df["日期"] = pd.to_datetime(df["日期"])
? ? ? 3?
? ? ? 4 # 按日期排序
? ? ? 5 df = df.sort_values(by="日期")?
修改一次后還有報錯:
AttributeError: 'DataFrame' object has no attribute 'columnss'
放棄了。
?
文心4.5表現
?生成數據集
import akshare as ak
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split# 1. 獲取股票數據
def get_stock_data(stock_code="000001", start_date="20200101", end_date="20250604"):df = ak.stock_zh_a_hist(symbol=stock_code, period="daily", start_date=start_date, end_date=end_date)df['日期'] = pd.to_datetime(df['日期'])df = df.sort_values('日期').reset_index(drop=True)return df# 2. 特征工程
def create_features(df, window=5):# 基礎特征df['return'] = df['收盤'].pct_change()df['volatility'] = df['return'].rolling(window).std()df['ma5'] = df['收盤'].rolling(5).mean()df['ma10'] = df['收盤'].rolling(10).mean()# 技術指標df['rsi'] = compute_rsi(df['收盤'], 14)df['macd'], df['signal'] = compute_macd(df['收盤'])# 未來3天漲跌標簽 (1:漲, 0:跌)df['target'] = (df['收盤'].shift(-3) > df['收盤']).astype(int)# 刪除無效行df = df.dropna().reset_index(drop=True)return df# 3. 技術指標計算函數
def compute_rsi(series, period=14):delta = series.diff()gain = delta.where(delta > 0, 0)loss = -delta.where(delta < 0, 0)avg_gain = gain.rolling(period).mean()avg_loss = loss.rolling(period).mean()rs = avg_gain / avg_lossreturn 100 - (100 / (1 + rs))def compute_macd(series, fast=12, slow=26, signal=9):ema_fast = series.ewm(span=fast).mean()ema_slow = series.ewm(span=slow).mean()macd = ema_fast - ema_slowsignal_line = macd.ewm(span=signal).mean()return macd, signal_line# 4. 數據預處理
def preprocess_data(df):features = df.drop(['日期', '股票代碼', '開盤', '最高', '最低', '收盤', '成交量', '成交額', '振幅', '漲跌幅', '漲跌額', '換手率'], axis=1, errors='ignore')target = df['target']# 標準化from sklearn.preprocessing import StandardScalerscaler = StandardScaler()features_scaled = scaler.fit_transform(features)return features_scaled, target# 5. 主流程
if __name__ == "__main__":# 獲取數據stock_df = get_stock_data("600519") # 茅臺股票# 特征工程feature_df = create_features(stock_df)# 預處理X, y = preprocess_data(feature_df)# 劃分訓練測試集X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=False, random_state=42)# 保存為TabPFN可讀格式np.savez('stock_data.npz', X_train=X_train, X_test=X_test, y_train=y_train, y_test=y_test)print("數據預處理完成,已保存為stock_data.npz")
訓練預測
import numpy as np
from tabpfn import TabPFNClassifier# 加載預處理數據
data = np.load('stock_data.npz')
X_train, X_test = data['X_train'], data['X_test']
y_train, y_test = data['y_train'], data['y_test']# 初始化TabPFN
# classifier = TabPFNClassifier(device='cpu', n_estimators=8)
classifier = TabPFNClassifier(device='cuda', n_estimators=8)
N_ensemble_configurations=32
# 訓練模型
classifier.fit(X_train, y_train)# 預測
y_pred = classifier.predict(X_test)
y_prob = classifier.predict_proba(X_test)[:, 1]# 評估
from sklearn.metrics import accuracy_score, roc_auc_score
print(f"測試集準確率: {accuracy_score(y_test, y_pred):.4f}")
print(f"測試集AUC: {roc_auc_score(y_test, y_prob):.4f}")# 預測未來3天漲跌
latest_data = X_test[-1].reshape(1, -1) # 取最新數據
future_pred = classifier.predict(latest_data)
print(f"未來3天預測結果: {'上漲' if future_pred[0] == 1 else '下跌'}")
?
最終用的是cuda?
輸出結果:
測試集準確率: 1.0000 測試集AUC: 1.0000 未來3天預測結果: 下跌
這個,有點問題吧,這訓練的也太狠了....
總結
當前的AI都不能小瞧了,跟2年前比都有很大提升。
豆包還是比較有趣,它的理解能力不錯,主動性高,但是水平比較平庸。
文心4.5是三者中水平最高的。
躍問,主要是在pandas處理數據那塊就出問題了,再修改了一次之后,我就放棄了。
調試
發現幾個ai都碰到了這個錯誤
TypeError ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Traceback (most recent call last)
/tmp/ipykernel_35/4228700019.py in <cell line: 0>()
? ? ? 8?
? ? ? 9 # 初始化TabPFN
---> 10 classifier = TabPFNClassifier(device='cpu', N_ensemble_configurations=32)
? ? ?11?
? ? ?12 # 訓練模型
TypeError: TabPFNClassifier.__init__() got an unexpected keyword argument 'N_ensemble_configurations'
通過help(TabPFNClassifier) ,看到應該是:
n_estimators