如何通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式(并进行了训练、推理)
本文对比了豆包、跃问和文心4.5三款AI在股票预测任务中的表现。测试要求使用akshare库获取股票数据并预处理为TabPFN模型可处理的格式,构建未来3天股价涨跌预测任务。豆包表现最主动,仅凭简单提示就完成了数据获取、预处理和模型预测全流程,但代码需2-3次修改才能运行;跃问在数据处理环节出错后放弃;文心4.5表现最好,但出现了准确率100%的过拟合结果。测试还发现TabPFNClassifie
计划让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_features
X = df[feature_columns].values
y = df['未来涨跌'].values
feature_names = feature_columns
X_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_loss
return 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_slow
signal_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 StandardScaler
scaler = 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
更多推荐
所有评论(0)