股票数据集机器学习训练(全免费!)
可以当机器学习课设。股票涨跌预测,选用了一个具有3556行数据,25个特征的真实csv数据集,我将会为此数据集在jupyter 上使用机器学习相关Python库进行数据集的读取分析,根据具体的情况进行数据预处理,步骤包含缺失值重复值检测,选取与目标涨跌%%相关的特征重新定义新数据集,标准化,pca主成分降维,拆分训练集数据和测试集数据。
一、课题简介
可以直接当机器学习课设。
股票涨跌预测,选用了一个具有3556行数据,25个特征的真实csv数据集,我将会为此数据集在jupyter 上使用机器学习相关Python库进行数据集的读取分析,根据具体的情况进行数据预处理,步骤包含缺失值重复值检测,选取与目标涨跌%%相关的特征重新定义新数据集,标准化,pca主成分降维,拆分训练集数据和测试集数据。
我根据此数据集的复杂度选取了随机森林机器学习模型和支持向量机模型进行建模,首先进行交叉验证与网格搜索结合和网格搜索不断的训练评估,选取它们的最优参数,然后得出它们在训练集和测试集评分,用模型预测测试集,得出模型均方误差,最后绘制出预测值和实际值的对比图,加上标题和图例。
二、数据准备
首先导入pandas和numpy,再从sklearn里面导出数据拆分模块和标准化模块。还有均方误差评估模块和matplotlib画图模块,添加上能够正常显示中文的两行代码
#导入模块 import pandas as pd import numpy as np from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.cluster import KMeans from sklearn.metrics import silhouette_score from sklearn.metrics import mean_squared_error from matplotlib import pyplot as plt plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签 plt.rcParams['axes.unicode_minus']=False
数据收集:
用pandas里面的read_csv来导入数据集。指定格式为gb k能够正常显示中文。data.dropna(inplace=True),将数据集中包含缺失值的行进行删除,并替代原数据集,然后显示数据集的前五行。
# 数据读取 data = pd.read_csv( "C:\\Users\\nhean\\Desktop\\股票数据.csv", encoding='gbk') data.dropna(inplace=True) data.head()
代码 | 名称 | 涨幅%% | 现价 | 涨跌 | 买价 | 卖价 | 总量 | 现量 | 涨速%% | ... | 总金额 | 量比 | 振幅%% | 均价 | 内盘 | 外盘 | 内外比 | 买量 | 卖量 | 开盘金额 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 平安银行 | 2.89 | 11.05 | 0.31 | 11.05 | 11.06 | 2110243 | 17125 | 0.00 | ... | 2331358208 | 1.89 | 4.56 | 11.05 | 973030 | 1137212 | 0.86 | 3547 | 9651 | 4028900 |
1 | 2 | 万 科A | -0.61 | 24.30 | -0.15 | 24.30 | 24.31 | 683236 | 8615 | 0.04 | ... | 1671576704 | 0.90 | 3.89 | 24.47 | 339287 | 343949 | 0.99 | 563 | 594 | 2508800 |
2 | 4 | 国农科技 | 0.38 | 15.90 | 0.06 | 15.90 | 15.91 | 2243 | 50 | 0.19 | ... | 3569043 | 0.33 | 2.46 | 15.91 | 1042 | 1201 | 0.87 | 271 | 37 | 1600 |
3 | 5 | 世纪星源 | -0.34 | 2.94 | -0.01 | 2.93 | 2.94 | 57901 | 1275 | 0.34 | ... | 17088052 | 0.86 | 2.71 | 2.95 | 36647 | 21253 | 1.72 | 1390 | 926 | 3300 |
4 | 6 | 深振业A | 0.88 | 5.70 | 0.05 | 5.70 | 5.71 | 413030 | 6352 | 0.18 | ... | 236936288 | 0.71 | 5.13 | 5.74 | 198243 | 214787 | 0.92 | 1193 | 1344 | 847100 |
5 rows × 26 columns
打印详情可以看到有多少行数据集,有多少个特征,和有没有缺失值
#打印详情 data.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 3556 entries, 0 to 3555 Data columns (total 26 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 代码 3556 non-null int64 1 名称 3556 non-null object 2 涨幅%% 3556 non-null float64 3 现价 3556 non-null float64 4 涨跌 3556 non-null float64 5 买价 3556 non-null float64 6 卖价 3556 non-null float64 7 总量 3556 non-null int64 8 现量 3556 non-null int64 9 涨速%% 3556 non-null float64 10 换手%% 3556 non-null float64 11 今开 3556 non-null float64 12 最高 3556 non-null float64 13 最低 3556 non-null float64 14 昨收 3556 non-null float64 15 市盈(动) 3556 non-null float64 16 总金额 3556 non-null int64 17 量比 3556 non-null float64 18 振幅%% 3556 non-null float64 19 均价 3556 non-null float64 20 内盘 3556 non-null int64 21 外盘 3556 non-null int64 22 内外比 3556 non-null float64 23 买量 3556 non-null int64 24 卖量 3556 non-null int64 25 开盘金额 3556 non-null int64 dtypes: float64(16), int64(9), object(1) memory usage: 722.4+ KB 检测重复值显示为零不用进行处理 #重复值检测,无重复 data.duplicated().sum() 0
用 corr() 方法计算每对属性之间的皮尔逊相关系数。相关系数范围 [-1, 1] ,越接近 1 表示有越强的正相关,越接近 -1 表示有越强的负相关。具体看每个属性与房价中位数的相关性。,为负数的可以删去
new_data1= data.drop(['代码', '名称'], axis=1) #用 corr() 方法计算每对属性之间的皮尔逊相关系数。相关系数范围 [-1, 1] ,越接近 1 表示有越强的正相关,越接近 -1 表示有越强的负相关。 cor=new_data1.corr() #具体看每个属性与房价中位数的相关性。 cor['涨幅%%'].sort_values(ascending=False) 幅%% 1.000000 涨跌 0.699442 振幅%% 0.364492 量比 0.263082 买量 0.231196 换手%% 0.104710 涨速%% 0.097853 买价 0.064713 外盘 0.062571 最高 0.057390 最低 0.052498 现价 0.050793 今开 0.048643 均价 0.047879 昨收 0.037048 总金额 0.035917 总量 0.033600 卖价 0.031857 市盈(动) 0.025833 内盘 -0.003812 开盘金额 -0.020553 现量 -0.028021 内外比 -0.085523 卖量 -0.171343 Name: 涨幅%%, dtype: float64
用data.drop删除与分类数无关的特征与我们要预测的涨幅%%特征,axis=1指定删除列 储存在new_data中显示头部5行
new_data = data.drop(['代码', '名称','涨幅%%','内盘','现量','卖量','内外比','开盘金额','卖量'], axis=1) new_data.head()
现价 | 涨跌 | 买价 | 卖价 | 总量 | 涨速%% | 换手%% | 今开 | 最高 | 最低 | 昨收 | 市盈(动) | 总金额 | 量比 | 振幅%% | 均价 | 外盘 | 买量 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 11.05 | 0.31 | 11.05 | 11.06 | 2110243 | 0.00 | 1.23 | 10.78 | 11.27 | 10.78 | 10.74 | 7.09 | 2331358208 | 1.89 | 4.56 | 11.05 | 1137212 | 3547 |
1 | 24.30 | -0.15 | 24.30 | 24.31 | 683236 | 0.04 | 0.70 | 24.50 | 24.90 | 23.95 | 24.45 | 14.70 | 1671576704 | 0.90 | 3.89 | 24.47 | 343949 | 563 |
2 | 15.90 | 0.06 | 15.90 | 15.91 | 2243 | 0.19 | 0.27 | 15.80 | 16.12 | 15.73 | 15.84 | 336.53 | 3569043 | 0.33 | 2.46 | 15.91 | 1201 | 271 |
3 | 2.94 | -0.01 | 2.93 | 2.94 | 57901 | 0.34 | 0.61 | 2.96 | 2.99 | 2.91 | 2.95 | 191.01 | 17088052 | 0.86 | 2.71 | 2.95 | 21253 | 1390 |
4 | 5.70 | 0.05 | 5.70 | 5.71 | 413030 | 0.18 | 3.06 | 5.61 | 5.88 | 5.59 | 5.65 | 9.25 | 236936288 | 0.71 | 5.13 | 5.74 | 214787 | 1193 |
拆分数据集:
我们选择new_data作为特征,'涨幅%%'作为标签,用train_test_split,按测试集占百分之二十拆分,随机种子为42号,这样重新加载不会改变拆分结果
# 特征选择 # 假设我们选择以下列作为特征,'涨幅%%'作为标签 features = new_data labels = data['涨幅%%'] # 拆分数据集为训练集测试集 # test_size: 测试集的比例 # random_state: 随机种子,确保结果可复现 X_train, X_test, y_train, y_test = train_test_split(features, labels, test_size=0.2, random_state=42) # 查看分割后的数据集大小 print(X_train.shape, X_test.shape) (2844, 18) (712, 18)
三、数据预处理
标准化:
使用StandardScaler()进行标准化,对训练集进行训练和数据转换,对测试集进行数据转换,定义转换对象,无报错成功转换
scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train) X_test_scaled = scaler.transform(X_test)
PCA降维:
导入pca,设置主成分为2,对标准化后的训练集进行拟合,对标准化后的训练集数据进行降维,对标准化后的测试集数据进行降维,最后打印维度,降维成功
#导入pca from sklearn.decomposition import PCA #设置主成分为2 pca=PCA(n_components=2) #对标准化后的训练集进行拟合 pca.fit(X_train_scaled) #对标准化后的训练集数据进行降维 X_train_pca=pca.transform(X_train_scaled) #对标准化后的测试集数据进行降维 X_test_pca=pca.transform(X_test_scaled) print('降维后训练集的维度为:',X_train_pca.shape) print('降维后测试集的维度为:',X_test_pca.shape)
降维后训练集的维度为: (2844, 2) 降维后测试集的维度为: (712, 2)
四、建模与评估
模型选取:
鉴于这是一个拥有多个特征和三千多条数据的股票数据集,我选择的第一个模型是支持向量机它在高维数据(股票数据有多种特征)中有优势,能有效处理非线性关系,找到合适的决策边界,对股票价格走势等复杂关系进行分类或预测,第二个模型是随机森林,它可以处理大量的特征,并且能够评估特征的重要性,在复杂的股票数据中筛选出对股价波动等关键因素有重要影响的特征,还能有效减少过拟合,提高模型的泛化能力。
模型1随机森林:
使用到了交叉验证与网格搜索结合的方法,从sklearn导入cross_val_score和随机森林模块,定义一个最高分best_score,随机森林有两个参数分别为n_estimator和random_state,它们分别为n和r,遍历这2个列表,内的参数是不断调优后得到的,原理是不断地训练验证打印最高分存在best_score里面,最后输出它的最优参数
#交叉验证评估与网格搜索结合 from sklearn.model_selection import cross_val_score from sklearn.ensemble import RandomForestRegressor best_score=0 for n in [340,344,350]: for r in [1,2,5]: model1= RandomForestRegressor(n_estimators=n, random_state=r) scores=cross_val_score(model1,X_train_scaled,y_train,cv=5) score=np.mean(scores) if score>best_score: best_score=score best_params={'n_estimators':n,'random_state':r} print('交叉验证的最高分:{:.3f}'.format(best_score)) print('最优参数:{}'.format(best_params)) 交叉验证的最高分:0.950 最优参数:{'n_estimators': 350, 'random_state': 2}
根据上面的选取参数进行最终建模,打印训练集和测试集评分,用测试集进行模型预测计算出均方误差并打印
# 根据交叉验证评估得出的最优参数建模 model1 = RandomForestRegressor(n_estimators=350, random_state=2) model1.fit(X_train_scaled, y_train) #评估模型 print('训练集评分:{:.2f}'.format(model1.score(X_train_scaled,y_train))) print('测试集评分:{:.2f}'.format(model1.score(X_test_scaled ,y_test))) # 模型预测 predictions = model1.predict(X_test_scaled) # 计算均方误差 svr_mse = mean_squared_error(y_test, predictions) print(f"模型的均方误差: {svr_mse:.2f}")
训练集评分:0.99 测试集评分:0.93 模型的均方误差: 0.30
模型2支持向量机:
用网格搜索查找最优参数,支持向量机模型有两个参数,gamma和C,定义列表遍历他们不断地用svm训练打印得分评估,储存在best_score里面,最终打印最高得分和他的参数
#网格搜索找最优参数 from sklearn.svm import SVR best_score=0 for gamma in [0.001,0.01,0.1,1,10]: for C in [90,100,120]: svm=SVR(gamma=gamma,C=C) svm.fit(X_train_scaled,y_train) score=svm.score(X_test_scaled,y_test) if score>best_score: best_score=score best_params={'gamma':gamma,'C':C} print('模型最高分:{:.3f}'.format(best_score)) print('最优参数:{}'.format(best_params))
模型最高分:0.946 最优参数:{'gamma': 0.01, 'C': 120}
根据上面的选取参数进行最终建模,打印训练集和测试集评分,用测试集进行模型预测计算出均方误差并打印
from sklearn.svm import SVR # 用最优参数训练支持向量回归模型 svr_model = SVR(kernel='rbf', C=120, gamma=0.01) svr_model.fit(X_train_scaled, y_train) # 模型预测 svr_predictions = svr_model.predict(X_test_scaled) # 计算均方误差 svr_mse = mean_squared_error(y_test, svr_predictions) print(f"SVR模型的均方误差: {svr_mse:.2f}") #评估模型 print('训练集评分:{:.2f}'.format(svr_model.score(X_train_scaled,y_train))) print('测试集评分:{:.2f}'.format(svr_model.score(X_test_scaled,y_test)))
SVR模型的均方误差: 0.22 训练集评分:0.97 测试集评分:0.95
五、结果分析与展示
模型分析图示:
模型1:
plt.figure(figsize=(10, 6)) 定义图的大小,plt.plot(y_test.values, label='实际值', color='blue')用测试集的值,画出实际值曲线,颜色为蓝色,plt.plot(predictions, label='预测值', linestyle='--', color='red')用预测的结果,画出预测值曲线,线型为虚线,颜色为红色方便对比观察。
# 绘制实际值与预测值对比图 plt.figure(figsize=(10, 6)) plt.plot(y_test.values, label='实际值', color='blue') plt.plot(predictions, label='预测值', linestyle='--', color='red') plt.xlabel('样本点') plt.ylabel('涨幅') plt.title('股票涨幅实际值与预测值对比') plt.legend() plt.grid() plt.show()
模型2:
代码与上面一样,改变了预测值画图的这一行代码,plt.plot(svr_predictions, label='SVR预测值', linestyle='--', color='red'),绘出svr_predictions的数值曲线
# 绘制实际值与预测值对比图 plt.figure(figsize=(10, 6)) plt.plot(y_test.values, label='实际值', color='blue') plt.plot(svr_predictions, label='SVR预测值', linestyle='--', color='red') plt.xlabel('样本点') plt.ylabel('收盘价') plt.title('股票收盘价实际值与预测值对比') plt.legend() plt.grid() plt.show()

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐
所有评论(0)