学习《深入浅出python量化交易交易实战》第三章(笔记1)

1.学习《深入浅出python量化交易交易实战》第三章(笔记1)

记录学习过程中的代码、疑问和心得

3.1 机器学习

  • 有监督学习 supervised learning
  • 无监督学习 unsupervised learning

1. 分类和回归

在有监督学习当中,常见的两种任务就是分类(classification)和回归(regression)。

  • 分类:是指给定样本的分类标签,训练模型使其可以姜新的样本归入正确的分类中(这时模型的目标时离散的);
  • 回归:是指给定样本的目标值,许年模型使其可以预测出新样本对应的述职(这时模型的目标就是连续的);

简化为容易理解的语言就是:
加入药预测某只股票是涨还是跌,这时模型所做的就是分类工作,如果要预测它时涨到1元,还是10元,这时模型所做的就是回归的工作。

2. 模型性能的评估

如果使用算法来进行交易的话,我们最关心的就是模型是否可以准确地预测股票的涨幅或者跌幅。
因为,模型是不可能100%准确的,所以需要我们对模型的性能今习惯评估,以便找到最可用的模型。

要达到这个目的,我们需要掌握的数据集(dataset)拆分为训练集(trainset)和验证集(testset),
使用训练集训练模型,并使用验证集来评估模型是否可用。

假设有某股票100天的价格数据,就可以将前80天的数据作为训练集,将后20天的数据作为验证集,同时评估模型分别在
训练集与验证集中的准确率。

  • 过拟合(over-fitting):训练集的得分高,而验证集得分低
  • 欠拟合(under-fitting):训练集和验证集得分都很低
    要解决过拟合和欠拟合的问题,我们需要调整参数、补充数据,或进行更细致的特征工程。

3.2 机器学习工具的基本使用方法

python中实现各种不同的机器学习算法是非常容易的,有各种个样的第三方库可以直接调用,如:scilit-learn,TendorFlow,Pytorch,keras等。

1. KNN算法的基本原理(K-Nearest Neighbor, K最临近)

KNN

2. KNN算法用于分类

1. 载入数据并查看
from sklearn.datasets import load_iris
iris = load_iris()
print('keys:', iris.keys())
print('feature_names:', iris.feature_names)
print('target:', iris.target)

输出结果如下:
在这里插入图片描述
keys:从keys的输出我们可以看到数据集存储了若干个key,其中我们需要重点关注的是:frature_name(特征标签)和target(分类标签)

features_names从输出结果中可以看出有:

  • sepal length 萼片长度
  • sepal width 萼片宽度
  • petal length 花瓣长度
  • petal width 花瓣宽度

iris.target的输出:
在这里插入图片描述

从以上输出可以看出,系统返回了一个数组,数组中有0、1和2。这说明数据集中的样本分类3类,分别为0、1、2这三个数字来表示。

这个数据集的目的是:根据样本鸢尾花鹅片和花瓣的长度及宽度,结合分类标签来训练模型,一遍让模型可以预测出某一种鸢尾花属于哪个分类。

2. 拆分数据集

Iris 鸢尾花数据集
Iris 鸢尾花数据集是一个经典数据集,在统计学习和机器学习领域都经常被用作示例。
数据集内包含
3 类共 150 条记录,每类各 50 个数据,每条记录都有
4 项特征:花萼长度、花萼宽度、花瓣长度、花瓣宽度,
可以通过这4个特征预测鸢尾花卉属于(iris-setosa, iris-versicolour, iris-virginica)中的哪一品种。

# 2. 拆分数据集
# 将样本的特征和标签分别复制给x和y
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

iris = load_iris()
x, y = iris.data, iris.target
print(x.shape)  # 拆分前 (150, 4) 样本数据量工150个,每个样本有4个特征

# 将x,y拆分为训练集和验证集
x_train, x_test, y_train, y_test = train_test_split(x, y)
print('x_train:', x_train.shape)  # 拆分后训练集合 (112, 4)
print('x_test:', x_test.shape)  # 拆分后验证集合 (38, 4)
print('y_train:', y_train.shape)  # 拆分后训练集合 (112,)
print('y_test:', y_test.shape)  # 拆分后验证集合 (38,)

在这里插入图片描述

通过拆分,训练集中的样本数为112个,其余38个为验证集。

3. 训练模型并评估准确率

接下来训练一个最简单的KNN模型,代码如下:

from sklearn.neighbors import KNeighborsClassifier
# 3. 训练模型并评估准确率
# 创建KNN分类器,参数保持默认设置
knn_clf = KNeighborsClassifier()
# 使用训练集拟合模型
knn_clf.fit(x_train, y_train)

# 查看模型在训练集和验证集中的准确率
print('训练集准确率:%.3f' % knn_clf.score(x_train, y_train))
print('验证集准确率:%.3f' % knn_clf.score(x_test, y_test))

在这里插入图片描述

从输出结果可以看出,训练集和验证集准确率都很高,是一个不错的成绩。

需要说明的是,在scikit-learn中,KNN可以通过调节n_neighbors参数来改进模型的性能。在不手动制定的情况下,KNN
默认在近邻参数n_neighbors为5。那么这个参数是最优的吗?我们可以使用网络搜索法来找到模型的最优参数:


# 导入网络搜索
from sklearn.model_selection import GridSearchCV

# 定义一个从1-10的n_neighbors
n_neighbors = tuple(range(1, 11, 1))  # [1-11)每个一个数取值,存储元祖,(1,2,3,...10)
# 创建网络搜索实例,estimator用KNN分类器
# 把刚刚定义的n_neighbors传入给param_grid参数
# cv参数指交叉验证次数为5
cv = GridSearchCV(estimator=KNeighborsClassifier(),
                  param_grid={'n_neighbors': n_neighbors},
                  cv=5)
# 使用网络搜索拟合数据集
cv.fit(x, y)

# 查看最优参数
print('最优参数:', cv.best_params_)  # {'n_neighbors': 6}

在这里插入图片描述

从以上代码运行结果可以看到,程序将网格搜索找到的最优参数返回,即:{'n_neighbors': 6},也就是说为6时,模型准确率最高

使用最优参数查看准确率
# 使用最优参数查看训练集和验证集的准确率

# 创建KNN分类器,参数保持默认设置
knn_clf_best = KNeighborsClassifier(n_neighbors=6)
# 使用训练集拟合模型
knn_clf_best.fit(x_train, y_train)

# 查看模型在训练集和验证集中的准确率
print('knn_clf_best:训练集准确率:%.3f' % knn_clf_best.score(x_train, y_train))
print('knn_clf_best:验证集准确率:%.3f' % knn_clf_best.score(x_test, y_test))

在这里插入图片描述
可以看出,采用最优参数后,训练集合准确率有所提升。

3. KNN算法用于回归

3. KNN算法用于回归(波士顿房价–回归问题)

由于该书的出版时间较早,我当前安装的scilit-learn版本中以移除了boston房价数据集,运行书中代码出现以下提示:

scilit-learn-1.2版本移除了boston数据,原因如下:
大致意思是原来的数据集中被加入了影响数据有效性的因素,并且没有证明这些因素的有效性,因此将其移除。

The Boston housing prices dataset has an ethical problem: as
investigated in [1], the authors of this dataset engineered a
non-invertible variable "B" assuming that racial self-segregation had a
positive impact on house prices [2]. Furthermore the goal of the
research that led to the creation of this dataset was to study the
impact of air quality but it did not give adequate demonstration of the
validity of this assumption.

The scikit-learn maintainers therefore strongly discourage the use of
this dataset unless the purpose of the code is to study and educate
about ethical issues in data science and machine learning.

因此我们需要寻找替代的数据,我们可以使用替代方式:

  1. 获取原始波士顿住房数据
import pandas as pd
import numpy as np

data_url = "http://lib.stat.cmu.edu/datasets/boston"
raw_df = pd.read_csv(data_url, sep="\s+", skiprows=22, header=None)
data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]])
target = raw_df.values[1::2, 2]
  1. 替代数据集包括加州住房数据集
from sklearn.datasets import fetch_california_housing
ca_housing = fetch_california_housing()
  1. Ames住房数据集
from sklearn.datasets import fetch_openml

ames_housing = fetch_openml(name="house_prices", as_frame=True)

1. 载入数据集并查看,拆分数据并训练模型

这里我们使用加州房价的数据来实现代码

# 1. 载入数据集并查看
# 加州房价数据集
from sklearn.datasets import fetch_california_housing

ca_housing = fetch_california_housing()
print('加州房价数据:', ca_housing.keys())
print('feature_names:', ca_housing.feature_names)


#2. 拆分数据集并训练模型
# 与分类任务一样,在回归任务中,我们也要使用训练集来训练模型,并使用验证集来验证模型的性能。
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsRegressor

# 将岩本特征和售价赋值给项x,y
x, y = ca_housing.data, ca_housing.target
x_train, x_test, y_train, y_test = train_test_split(x, y)

print('查看拆分的结果 x_train:', x_train.shape)
print('查看拆分的结果 x_test:', x_test.shape)
print('查看拆分的结果 y_train:', y_train.shape)
print('查看拆分的结果 y_test:', y_test.shape)

# 创建一个实例,参数保持默认设置
knn_reg = KNeighborsRegressor()
# 拟合训练集数据
knn_reg.fit(x_train, y_train)
# 查看模型在训练和验证集的性能表现
print('训练集准确率:%.3f' % knn_reg.score(x_train, y_train)) # 0.452
print('验证集准确率:%.3f' % knn_reg.score(x_test, y_test)) # 0.131


在这里插入图片描述
结果训练集和验证集分数都很低,说明模型出现了欠拟合的问题。我们需要对数据进行处理,或者对模型进行调优

欠拟合(under-fitting):训练集和验证集得分都很低

3. 模型评估的不同方法和改进

使用网格搜索寻找最优参数

print('================网格搜索找最优参数=================')

n_neighbors = tuple(range(1, 21, 1))
cv_reg = GridSearchCV(estimator=KNeighborsRegressor(),
                      param_grid={'n_neighbors': n_neighbors},
                      cv=5)

cv_reg.fit(x, y)

print('最优参数best_params_:', cv_reg.best_params_)
print('最优得分best_score_:', cv_reg.best_score_)

print('================使用最优参数查看训练和验证集的准确率=================')
best_n_neighbors = cv_reg.best_params_['n_neighbors']
print('best_n_neighbors:', best_n_neighbors)
knn_reg_best = KNeighborsRegressor(n_neighbors=best_n_neighbors)
knn_reg_best.fit(x_train, y_train)
print('训练集准确率:%.3f' % knn_reg_best.score(x_train, y_train))
print('验证集准确率:%.3f' % knn_reg_best.score(x_test, y_test))

在这里插入图片描述

注:
  1. 代入当使用网格搜索的最优参数时,得到的准确率结果反而降低了(书中是提高了的),我用例boston,california, amse的数据都是一样的结果?
  2. 网格搜索方法的结果cv_reg.best_score_与手动传如最佳参数的训练集和验证集准确率区别时什么,书中没有说明?
    希望有懂的解答一下。

分类模型和回归模型score()算法区别
分类:knn_clf.score(), 回归:knn_reg.score()
书中提到分类法和回归法的.score()内部实现的算法是不同的,由于本人对这方面没有基础,先贴原文,以后补充了相关基础后再回来理解。
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝with黑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值