股票价格预测与机器学习最佳实践
1. 股票价格预测
1.1 数据准备
在进行股票价格预测前,需将数据划分为训练集和测试集。以某股票数据为例,选择 1988 年到 2014 年的数据作为训练集,2015 年的数据作为测试集。
import datetime
# 训练集时间范围
start_train = datetime.datetime(1988, 1, 1, 0, 0)
end_train = datetime.datetime(2014, 12, 31, 0, 0)
data_train = data.ix[start_train:end_train]
# 测试集时间范围
start_test = datetime.datetime(2015, 1, 1, 0, 0)
end_test = datetime.datetime(2015, 12, 31, 0, 0)
data_test = data.ix[start_test:end_test]
# 特征列和目标列
X_columns = list(data.drop(['close'], axis=1).columns)
y_column = 'close'
X_train = data_train[X_columns]
y_train = data_train[y_column]
X_test = data_test[X_columns]
y_test = data_test[y_column]
训练集有 6553 个样本,每个样本为 37 维;测试集有 252 个样本。
print(X_train.shape) # (6553, 37)
print(y_train.shape) # (6553,)
print(X_test.shape) # (252, 37)
1.2 模型训练与评估
1.2.1 SGD 线性回归
SGD 算法对特征尺度差异较大的数据敏感,因此需对特征进行标准化处理。
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(X_train)
X_scaled_train = scaler.transform(X_train)
X_scaled_test = scaler.transform(X_test)
接着,通过网格搜索寻找最优参数。
from sklearn.linear_model import SGDRegressor
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
param_grid = {
"alpha": [3e-06, 1e-5, 3e-5],
"eta0": [0.01, 0.03, 0.1],
}
lr = SGDRegressor(penalty='l2', n_iter=1000)
grid_search = GridSearchCV(lr, param_grid, cv=5, scoring='neg_mean_absolute_error')
grid_search.fit(X_scaled_train, y_train)
# 选择最佳模型并预测
lr_best = grid_search.best_estimator_
predictions = lr_best.predict(X_scaled_test)
# 评估模型
print('MSE: {0:.3f}'.format(mean_squared_error(y_test, predictions)))
print('MAE: {0:.3f}'.format(mean_absolute_error(y_test, predictions)))
print('R^2: {0:.3f}'.format(r2_score(y_test, predictions)))
1.2.2 随机森林回归
from sklearn.ensemble import RandomForestRegressor
param_grid = {
"max_depth": [30, 50],
"min_samples_split": [3, 5, 10],
}
rf = RandomForestRegressor(n_estimators=1000)
grid_search = GridSearchCV(rf, param_grid, cv=5, scoring='neg_mean_absolute_error')
grid_search.fit(X_train, y_train)
# 选择最佳模型并预测
rf_best = grid_search.best_estimator_
predictions = rf_best.predict(X_test)
# 评估模型
print('MSE: {0:.3f}'.format(mean_squared_error(y_test, predictions)))
print('MAE: {0:.3f}'.format(mean_absolute_error(y_test, predictions)))
print('R^2: {0:.3f}'.format(r2_score(y_test, predictions)))
1.2.3 支持向量回归(SVR)
from sklearn.svm import SVR
param_grid = {
"C": [1000, 3000, 10000],
"epsilon": [0.00001, 0.00003, 0.0001],
}
svr = SVR(kernel='linear')
grid_search = GridSearchCV(svr, param_grid, cv=5, scoring='neg_mean_absolute_error')
grid_search.fit(X_scaled_train, y_train)
# 选择最佳模型并预测
svr_best = grid_search.best_estimator_
predictions = svr_best.predict(X_scaled_test)
# 评估模型
print('MSE: {0:.3f}'.format(mean_squared_error(y_test, predictions)))
print('MAE: {0:.3f}'.format(mean_absolute_error(y_test, predictions)))
print('R^2: {0:.3f}'.format(r2_score(y_test, predictions)))
各模型评估结果如下:
| 模型 | MSE | MAE | R² |
| ---- | ---- | ---- | ---- |
| SGD 线性回归 | 28600.696 | 125.777 | 0.907 |
| 随机森林回归 | 36437.311 | 147.052 | 0.881 |
| 支持向量回归 | 27099.227 | 123.781 | 0.912 |
2. 机器学习最佳实践
2.1 机器学习工作流程
解决机器学习问题的任务可总结为四个阶段:
1. 数据准备
2. 训练集生成
3. 算法训练、评估与选择
4. 部署与监控
graph LR
A[数据准备] --> B[训练集生成]
B --> C[算法训练、评估与选择]
C --> D[部署与监控]
2.2 数据准备阶段的最佳实践
2.2.1 完全理解项目目标
在收集数据前,需明确项目目标和业务问题,这有助于确定数据来源,并需要足够的领域知识和专业技能。例如,预测 DJIA 指数未来价格时,应收集其过去的表现数据。
2.2.2 收集所有相关字段
对于每个数据源,建议收集与项目相关的所有字段,尤其是重新收集数据耗时或不可能的情况。例如,在股票价格预测中,收集包括开盘价、最高价、最低价和成交量等所有字段的数据。
2.2.3 保持字段值的一致性
需统一字段中的值,确保相同含义的值表示一致。例如,在“性别”字段中,统一使用“M”和“F”。同时,同一字段的值格式也应一致。
2.2.4 处理缺失数据
处理缺失数据有三种基本策略:
1. 丢弃包含任何缺失值的样本
2. 丢弃任何样本中包含缺失值的字段
3. 基于属性的已知部分推断缺失值(缺失值插补)
以下是使用 scikit-learn 进行缺失值插补的示例:
import numpy as np
from sklearn.preprocessing import Imputer
# 原始数据
data_origin = [[30, 100],
[20, 50],
[35, np.nan],
[25, 80],
[30, 70],
[40, 60]]
# 均值插补
imp_mean = Imputer(missing_values='NaN', strategy='mean')
imp_mean.fit(data_origin)
data_mean_imp = imp_mean.transform(data_origin)
print(data_mean_imp)
# 中位数插补
imp_median = Imputer(missing_values='NaN', strategy='median')
imp_median.fit(data_origin)
data_median_imp = imp_median.transform(data_origin)
print(data_median_imp)
# 新样本插补
new = [[20, np.nan],
[30, np.nan],
[np.nan, 70],
[np.nan, np.nan]]
new_mean_imp = imp_mean.transform(new)
print(new_mean_imp)
通过一个糖尿病数据集的示例,比较丢弃缺失值和插补缺失值对预测结果的影响。
from sklearn import datasets
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import cross_val_score
# 加载数据集
dataset = datasets.load_diabetes()
X_full, y = dataset.data, dataset.target
# 模拟含缺失值的数据集
m, n = X_full.shape
m_missing = int(m * 0.25)
np.random.seed(42)
missing_samples = np.array([True] * m_missing + [False] * (m - m_missing))
np.random.shuffle(missing_samples)
missing_features = np.random.randint(low=0, high=n, size=m_missing)
X_missing = X_full.copy()
X_missing[np.where(missing_samples)[0], missing_features] = np.nan
# 丢弃含缺失值的样本
X_rm_missing = X_missing[~missing_samples, :]
y_rm_missing = y[~missing_samples]
regressor = RandomForestRegressor(random_state=42, max_depth=10, n_estimators=100)
score_rm_missing = cross_val_score(regressor, X_rm_missing, y_rm_missing).mean()
print('Score with the data set with missing samples removed: {0:.2f}'.format(score_rm_missing))
# 均值插补
imp_mean = Imputer(missing_values='NaN', strategy='mean')
X_mean_imp = imp_mean.fit_transform(X_missing)
score_mean_imp = cross_val_score(regressor, X_mean_imp, y).mean()
print('Score with the data set with missing values replaced by mean: {0:.2f}'.format(score_mean_imp))
# 完整数据集评估
score_full = cross_val_score(regressor, X_full, y).mean()
print('Score with the full data set: {0:.2f}'.format(score_full))
结果表明,在该示例中插补策略效果更好,但不能保证插补策略总是更有效,因此建议通过交叉验证比较不同策略的性能。
2.3 训练集生成阶段的最佳实践
2.3.1 确定具有数值的分类特征
一般来说,分类特征传达定性信息,但当特征采用离散且可数的数值时,判断其是分类特征还是数值特征的关键在于是否具有数学含义。例如,产品评级是数值特征,而月份或星期几是分类特征。
2.3 训练集生成阶段的最佳实践(续)
2.3.2 数据预处理
数据预处理通常包括分类特征编码、特征缩放、特征选择和降维等操作。
-
分类特征编码
:对于分类特征,需要将其转换为数值形式,以便机器学习算法能够处理。常见的编码方法有独热编码(One-Hot Encoding)、标签编码(Label Encoding)等。例如,使用
sklearn.preprocessing
中的
OneHotEncoder
进行独热编码:
from sklearn.preprocessing import OneHotEncoder
import numpy as np
# 示例数据
X = np.array([['red'], ['blue'], ['green']])
# 创建编码器
encoder = OneHotEncoder()
# 拟合数据并进行编码
X_encoded = encoder.fit_transform(X).toarray()
print(X_encoded)
-
特征缩放
:特征缩放可以使不同特征具有相同的尺度,避免某些特征对模型的影响过大。常见的特征缩放方法有标准化(Standardization)和归一化(Normalization)。前面在股票价格预测中使用的
StandardScaler就是进行标准化的工具。 -
特征选择
:特征选择可以减少特征的数量,提高模型的训练效率和泛化能力。常见的特征选择方法有过滤法(Filter)、包装法(Wrapper)和嵌入法(Embedded)。例如,使用
sklearn.feature_selection中的SelectKBest进行过滤法特征选择:
from sklearn.feature_selection import SelectKBest, f_classif
from sklearn.datasets import load_iris
# 加载数据集
iris = load_iris()
X, y = iris.data, iris.target
# 创建特征选择器
selector = SelectKBest(score_func=f_classif, k=2)
# 拟合数据并进行特征选择
X_selected = selector.fit_transform(X, y)
print(X_selected.shape)
-
降维
:降维可以将高维数据转换为低维数据,减少数据的复杂度。常见的降维方法有主成分分析(PCA)、线性判别分析(LDA)等。例如,使用
sklearn.decomposition中的PCA进行主成分分析:
from sklearn.decomposition import PCA
import numpy as np
# 示例数据
X = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 创建PCA对象
pca = PCA(n_components=2)
# 拟合数据并进行降维
X_reduced = pca.fit_transform(X)
print(X_reduced.shape)
2.3.3 特征工程
特征工程是指从原始数据中提取和构造特征的过程,它可以提高模型的性能。常见的特征工程方法有特征组合、特征变换、特征衍生等。例如,在股票价格预测中,可以构造移动平均线、相对强弱指数(RSI)等衍生特征。
2.4 算法训练、评估与选择阶段的最佳实践
2.4.1 选择合适的算法
根据问题的类型(如分类、回归)和数据的特点(如数据规模、特征数量、数据分布等)选择合适的算法。例如,对于线性可分的问题,可以选择线性回归、逻辑回归等线性算法;对于非线性问题,可以选择决策树、随机森林、支持向量机等非线性算法。
2.4.2 超参数调优
超参数是指在模型训练前需要手动设置的参数,如学习率、正则化系数等。超参数的选择会影响模型的性能,因此需要进行调优。常见的超参数调优方法有网格搜索(Grid Search)、随机搜索(Random Search)等。在前面的股票价格预测中,我们使用了网格搜索来寻找最优的超参数。
2.4.3 模型评估
使用合适的评估指标来评估模型的性能,如准确率、召回率、F1值、均方误差(MSE)、平均绝对误差(MAE)、决定系数(R²)等。根据问题的类型和业务需求选择合适的评估指标。例如,在分类问题中,通常使用准确率、召回率和F1值;在回归问题中,通常使用MSE、MAE和R²。
2.5 系统部署与监控阶段的最佳实践
2.5.1 模型部署
将训练好的模型部署到生产环境中,使其能够处理实际的数据。常见的模型部署方式有API接口、批处理作业等。例如,使用
Flask
框架创建一个简单的API接口来部署模型:
from flask import Flask, request, jsonify
import numpy as np
import joblib
# 加载模型
model = joblib.load('model.pkl')
# 创建Flask应用
app = Flask(__name__)
# 定义API接口
@app.route('/predict', methods=['POST'])
def predict():
data = request.get_json(force=True)
X = np.array(data['features']).reshape(1, -1)
prediction = model.predict(X)
return jsonify({'prediction': prediction.tolist()})
if __name__ == '__main__':
app.run(debug=True)
2.5.2 模型监控
在模型部署后,需要对模型的性能进行监控,及时发现模型性能下降的情况,并采取相应的措施进行调整。常见的模型监控指标有准确率、召回率、F1值、MSE、MAE、R²等。可以使用监控工具(如Prometheus、Grafana等)来实现模型监控。
3. 总结
本文介绍了股票价格预测的方法和机器学习的最佳实践。在股票价格预测中,我们使用了SGD线性回归、随机森林回归和支持向量回归三种模型,并通过网格搜索寻找最优的超参数。在机器学习最佳实践中,我们介绍了机器学习的工作流程,以及数据准备、训练集生成、算法训练、评估与选择、系统部署与监控等阶段的最佳实践。通过遵循这些最佳实践,可以提高机器学习项目的成功率和效率。
在实际应用中,还可以进一步探索和优化这些方法,例如考虑其他的特征和模型,使用更复杂的超参数调优方法,以及加强模型的监控和维护等。同时,结合不同的数据源和领域知识,也可以提高模型的性能和预测能力。
| 阶段 | 最佳实践 |
|---|---|
| 数据准备 | 完全理解项目目标、收集所有相关字段、保持字段值的一致性、处理缺失数据 |
| 训练集生成 | 确定具有数值的分类特征、数据预处理、特征工程 |
| 算法训练、评估与选择 | 选择合适的算法、超参数调优、模型评估 |
| 系统部署与监控 | 模型部署、模型监控 |
graph LR
A[数据准备] --> B[训练集生成]
B --> C[算法训练、评估与选择]
C --> D[系统部署与监控]
D --> E[持续优化]
通过不断地学习和实践,我们可以更好地掌握机器学习的方法和技巧,解决更多实际的问题。希望本文对大家有所帮助。
超级会员免费看

被折叠的 条评论
为什么被折叠?



