搜不鸟了
量化交易-年复合收益率超过180%的策略-8
策略分析1、上升:快线(37 tema)穿过慢线(74 tema)快线穿过慢线,token价格进入上升通道2、下跌通道:慢线(74 tema)穿过快线(37 tema)慢线穿过快线,token价格进入下降通道通过以上2个场景,证实:快慢线策略是可以抓住价格的上升和下降趋势。接着我们再来看一个异常场景:红框截图部分,我们会发现快线围绕慢线频繁上下穿越,这是因为这段时间价格处于一个震荡时期,导致token价格变化不大,价格的小幅震荡都会导致快线频繁穿越慢线。因此如果我们用单条快慢线策略会导致我们的策略频繁止损或开单,导致策略出现较大损失。策略优化1、均线策略优化我们又加入了2条均线(117 tema&150 tema)。37 tema&74 tema 在短期震荡的场景 很难识别 价格的趋势。我们加入2条时间维度更长的均线;所以我们判断策略可以变为:# 上升通道判断:
37 tema > 74 tema & 117 tema > 150 tema
# 下跌通道判断:
37 tema < 74 tema & 117 tema < 150 tema因此我们可以避免由于短期价格震荡导致的单条均线策略无法有效判断价格的趋势。2、均线参数调优接着我们要思考第二个问题,策略面向的不是一个交易对,且长均线具体使用多少时间周期的均线?117天、150天 还是 300天,到底哪个周期是目前交易对最优的?这个问题我们可以抽象一下:1、我们需要设置n条均线2、均线的周期设置为m天接下来就是参数组合的问题:# buy_ma_count:买入的n条均线 buy_ma_gap:买入的均线周期
buy_ma_count = IntParameter(1, count_max, default=7, space="buy")
buy_ma_gap = IntParameter(1, gap_max, default=7, space="buy")
# sell_ma_count:卖出的n条均线 sell_ma_gap:卖出的均线周期
sell_ma_count = IntParameter(1, count_max, default=7, space="sell")
sell_ma_gap = IntParameter(1, gap_max, default=94, space="sell")接下来交给超参数调优模块:freqtrade hyperopt --config user_data/config.json --hyperopt-loss SharpeHyperOptLossDaily --strategy MultiMaStrategy -e 200 --timerange 20220101-20220601算法通过200epoch后,我们会得到一个收益相对较高的参数组合:# Buy hyperspace params:
buy_params = {
"buy_ma_count": 15, # 设置15条买入均线
"buy_ma_gap": 37, # 均线买入周期37天
}
# Sell hyperspace params:
sell_params = {
"sell_ma_count": 20,# 设置20条卖出均线
"sell_ma_gap": 53,# 卖出均线周期为53天
}3、策略收益既然最优参数&策略已经确定,我们来看一下多均线回归策略的收益:回测结果:半年回测收益率:53.71%年度复合收益率(CAGR):182.7%收益最高的交易对:SHIB/USDT 67.74%
搜不鸟了
机器学习-朴素贝叶斯-10
1、概念贝叶斯分类是一类分类算法的总称,这类算法均以贝叶斯定理为基础,故统称为贝叶斯分类。而朴素朴素贝叶斯分类是贝叶斯分类中最简单,也是常见的一种分类方法。朴素贝叶斯算法的核心思想是通过考虑特征概率来预测分类,即对于给出的待分类样本,求解在此样本出现的条件下各个类别出现的概率,哪个最大,就认为此待分类样本属于哪个类别。贝叶斯定理中很重要的概念是先验概率、后验概率和条件概率。先验概率:事件发生前的预判概率。可以是基于历史数据的统计,可以由背景常识得出,也可以是人的主观观点给出。一般都是单独事件概率。举个例子:如果我们对西瓜的色泽、根蒂和纹理等特征一无所知,按照常理来说,西瓜是好瓜的概率是 。那么这个概率 就被称为先验概率。后验概率:事件发生后求的反向条件概率。或者说,基于先验概率求得的反向条件概率。概率形式与条件概率相同。举个例子:假如我们了解到判断西瓜是否好瓜的一个指标是纹理。一般来说,纹理清晰的西瓜是好瓜的概率大一些,大概是75% 。如果把纹理清晰当作一种结果,然后去推测好瓜的概率,那么这个概率 P(好瓜|纹理清晰) 就被称为后验概率。2、朴素贝叶斯公式贝叶斯定理(Bayes Theorem,也称贝叶斯公式)是基于假设的先验概率、给定假设下观察到不同数据的概率,提供了一种计算后验概率的方法,朴素贝叶斯公式:P(A)是先验概率,一般都是人主观给出的。贝叶斯中的先验概率一般特指它。P(B)是先验概率,在贝叶斯的很多应用中不重要(因为只要最大后验不求绝对值),需要时往往用全概率公式计算得到。P(B|A)是条件概率,又叫似然概率,一般是通过历史数据统计得到。P(A|B)是后验概率,一般是我们求解的目标。换个表达形式就会明朗很多,如下:我们最终求的p(类别|特征)即可!就相当于完成了我们的任务。2.1、条件独立假设与朴素贝叶斯朴素贝叶斯处理过程3、朴素贝叶斯分类实例给定数据如下:问题是:如果一对男女朋友,男生想女生求婚,男生的四个特点分别是不帅,性格不好,身高矮,不上进,请你判断一下女生是嫁还是不嫁?通过问题我们转换为朴素贝叶斯求解:3.1、求解后验概率p(不帅、性格不好、身高矮、不上进|嫁)因为我们用的是朴素贝叶斯方法,因此我们假定事件之间相互独立,互不影响,那么:P(不帅、性格不好、身高矮、不上进|嫁) = P(不帅|嫁)*P(性格不好|嫁)*P(身高矮|嫁)*P(不上进|嫁)因此,我们需要先求出 P(不帅|嫁)、P(性格不好|嫁)、P(身高矮|嫁)、P(不上进|嫁)的后验概率。p(不帅|嫁) = 3/6 = 1/2同理可求得:p(性格不好|嫁)=1/6p(身高矮|嫁)=1/6p(不上进|嫁)=1/6P(不帅、性格不好、身高矮、不上进|嫁) =1/2 * 1/6 * 1/6 * 1/6 = 1/4323.2、求得p(嫁)先验概率通过统计样本可得:p(嫁)=6/12 = 1/2然后可以求解分母:P(不帅、性格不好、身高矮、不上进) = P(不帅)*P(性格不好)*P(身高矮)*P(不上进)因此我们可以通过样本统计得出:P(不帅)=4/12=1/3P(性格不好)=4/12=1/3P(身高矮)=7/12P(不上进)=4/12=1/3P(不帅、性格不好、身高矮、不上进)=1/3 * 1/3 * 7/12 * 1/3 = 7/324最后我们将先验概率代入:P(嫁|不帅、性格不好、身高矮、不上进) = (1/432 * 1/2)/ (7/324) = 324/6048 =3/56P(不嫁|不帅、性格不好、身高矮、不上进) = 1-P(嫁|不帅、性格不好、身高矮、不上进) = 53/56所以我们根据朴素贝叶斯算法可以给这个女生答案,是不嫁!4、平滑处理1)为什么需要平滑处理使用朴素贝叶斯,有时候会面临零概率问题。零概率问题,指的是在计算实例的概率时,如果某个量x,在观察样本库(训练集)中没有出现过,会导致整个实例的概率结果是0。在文本分类的问题中,当「一个词语没有在训练样本中出现」时,这个词基于公式统计计算得到的条件概率为 0,使用连乘计算文本出现概率时也为 0。这是不合理的,不能因为一个事件没有观察到就武断的认为该事件的概率是 0。2)拉普拉斯平滑及依据假定训练样本很大时,每个分量 x 的计数加 1 造成的估计概率变化可以忽略不计,但可以方便有效的避免零概率问题。对应到文本分类的场景中,如果使用多项式朴素贝叶斯,假定特征 xi表示某个词在样本中出现的次数(当然用TF-IDF表示也可以)。拉普拉斯平滑处理后的条件概率计算公式为:5、朴素贝叶斯分类的优缺点优点:(1) 算法逻辑简单,易于实现(2)分类过程中时空开销小缺点:理论上,朴素贝叶斯模型与其他分类方法相比具有最小的误差率。但是实际上并非总是如此,这是因为朴素贝叶斯模型假设属性之间相互独立,这个假设在实际应用中往往是不成立的,在属性个数比较多或者属性之间相关性较大时,分类效果不好。6、代码演示-朴素贝叶斯分类sklearndata iris# load the iris dataset
from sklearn.datasets import load_iris
iris = load_iris()
# store the feature matrix (X) and response vector (y)
X = iris.data
y = iris.target
# splitting X and y into training and testing sets
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.4, random_state=1)
# training the model on training set
from sklearn.naive_bayes import GaussianNB
gnb = GaussianNB()
gnb.fit(X_train, y_train)
# making predictions on the testing set
y_pred = gnb.predict(X_test)
# comparing actual response values (y_test) with predicted response values (y_pred)
from sklearn import metrics
print("Gaussian Naive Bayes model accuracy(in %):", metrics.accuracy_score(y_test, y_pred)*
搜不鸟了
机器学习-损失函数-12
机器学习损失函数概念在机器学习中,损失函数是代价函数的一部分,而代价函数则是目标函数的一种类型。Loss function,即损失函数:用于定义单个训练样本与真实值之间的误差;Cost function,即代价函数:用于定义单个批次/整个训练集样本与真实值之间的误差;Objective function,即目标函数:泛指任意可以被优化的函数。1. 回归损失(Regression Loss)1.1 均方差损失 Mean Squared Error Loss均方差 Mean Squared Error (MSE)损失是机器学习、深度学习回归任务中最常用的一种损失函数,也称为 L2 Loss。其基本形式如下:从直觉上理解均方差损失,这个损失函数的最小值为 0(当预测等于真实值时),最大值为无穷大。下图是对于真实值通常为了计算方便,我们通常最大化对数似然 Log-Likelihood:可以看到这个实际上就是均方差损失的形式。也就是说在模型输出与真实值的误差服从高斯分布的假设下,最小化均方差损失函数与极大似然估计本质上是一致的1.2、平均绝对误差损失 Mean Absolute Error Loss平均绝对误差 Mean Absolute Error (MAE)是另一类常用的损失函数,也称为 L1 Loss。其基本形式如下:与上面推导 MSE 时类似,我们可以得到的负对数似然实际上就是 MAE 损失的形式MAE 与 MSE 区别MSE 通常比 MAE 可以更快地收敛MAE 对于 outlier 更加 robust1.3、Huber LossHuber Loss则是一种将 MSE 与 MAE 结合起来,取两者优点的损失函数,也被称作 Smooth Mean Absolute Error Loss 。其原理很简单,就是在误差接近 0 时使用 MSE,误差较大时使用 MAE,公式为:Huber Loss 的特点1、Huber Loss 结合了 MSE 和 MAE 损失,在误差接近 0 时使用 MSE,使损失函数可导并且梯度更加稳定;2、在误差较大时使用 MAE 可以降低 outlier 的影响,使训练对 outlier 更加健壮。3、缺点是需要额外地设置一个δ超参数。3、分类损失函数1、hinge loss首先我们已知SVM软间隔的目标函数为:其中:它事实上是一个利用Hinge Loss的ERM,加上了一个L2正则项。如果上式ℓ取Logistic Loss的话,其实就等价于带正则项的Logistic Regression。函数图像如图:2、交叉熵损失 Cross Entropy Loss(Softmax交叉熵)对于分类问题,最常用的损失函数是交叉熵损失函数 Cross Entropy Loss。2.1、二分类将两条式子合并成一条:假设数据点之间独立同分布,则似然可以表示为:对似然取对数,然后加负号变成最小化负对数似然,即为交叉熵损失函数的形式:下图是对二分类的交叉熵损失函数的可视化,蓝线是目标值为 0 时输出不同输出的损失,黄线是目标值为 1 时的损失。可以看到约接近目标值损失越小,随着误差变差,损失呈指数增长。2.2、多分类Softmax 函数将每个维度的输出范围都限定在 (0,1)之间,同时所有维度的输出和为 1,用于表示一个概率分布。其中 k∈K表示 K 个类别中的一类,同样的假设数据点之间独立同分布,可得到负对数似然为:其中 ci是样本 xi的目标类,这个就是应用于多分类的交叉熵损失函数 Softmax Loss 3、KL散度由于我们希望两个分布尽量相近,因此我们最小化 KL 散度。同时由于上式第一项信息熵仅与最优分布本身相关,因此我们在最小化的过程中可以忽略掉,变成最小化:这个是针对单个训练样本的损失函数,如果考虑整个数据集,则:可以看到通过最小化交叉熵的角度推导出来的结果和使用最大 化似然得到的结果是一致的。
搜不鸟了
机器学习-KNN(K近邻算法)-15
1、KNN介绍上一篇我们讲过Kmeans,初学者常常把这两者搞混,虽然KNN是有监督算法,Kmeans是无监督算法,但KNN和Kmeans确实有相同之处:两者都有“近朱者赤近墨者黑”的思想,将距离近的样本点划为同一类别;虽然两者名称中都有“K”,但是:KNN中的K指的是近邻个数,也就是最近的K个点 ;Kmeans中的K指的是最终聚类的个数,也就是要将所有点分成K类。2.K近邻算法步骤K近邻算法的计算流程:2.1)K近邻算法工作原理存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每个数据与所属分类的对应关系。输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相似数据(最近邻)的分类标签。一般来说,只选择样本数据集中前 N个最相似的数据。K 一般不大于 20,最后,选择 K个中出现次数最多的分类,作为新数据的分类。2.2)K近邻算法参数选择如何选择一个最佳的K值取决于数据。一般情况下,在分类时较大的 K值能够减小噪声的影响,但会使类别之间的界限变得模糊。一个较好的K值能通过各种启发式技术(见超参数优化)来获取。噪声和非相关性特征的存在,或特征尺度与它们的重要性不一致会使K近邻算法的准确性严重降低。对于选取和缩放特征来改善分类已经做了很多研究。一个普遍的做法是利用进化算法优化功能扩展,还有一种较普遍的方法是利用训练样本的互信息进行选择特征。在二元(两类)分类问题中,选取K为奇数有助于避免两个分类平票的情形。在此问题下,选取最佳经验K值的方法是自助法。说明: KNN 没有显示的训练过程,它是「懒惰学习」的代表,它在训练阶段只是把数据保存下来,训练时间开销为 0,等收到测试样本后进行处理。3.K近邻算法的缺点与改进3.1)K近邻算法的优缺点不同类别的样本点,分布在空间的不同区域。K近邻是基于空间距离较近的样本类别来进行分类,本质上是对于特征空间的划分。优点:精度高、对异常值不敏感、无数据输入假定。缺点:计算复杂度高、空间复杂度高。适用数据范围:数值型和标称型。3.2)K近邻算法的核心要素:距离度量准则K近邻算法依赖于空间中相近的点做类别判断,判断距离远近的度量标准非常重要距离的度量标准,对很多算法来说都是核心要素(比如无监督学习的 聚类算法也很大程度依赖距离度量),也对其结果有很大的影响。Lp距离(又称闵可夫斯基距离,Minkowski Distance)不是一种距离,而是一组距离的定义。参数�=1p=1时为曼哈顿距离(又称L1距离或程式区块距离),表示两个点在标准坐标系上的绝对轴距之和。参数�=2p=2时为欧氏距离(又称L2距离或欧几里得度量),是直线距离常见的两点之间或多点之间的距离表示法。参数�→∞p→∞时,就是切比雪夫距离(各坐标数值差的最大值)。3.3)K近邻算法的核心要素:K的大小对于 KNN 算法而言,K的大小取值也至关重要,如果选择较小的K值,意味着整体模型变得复杂(模型容易发生过拟合),模型学习的近似误差(approximation error)会减小,但估计误差(estimation error)会增大。如果选择较大的K值,就意味着整体的模型变得简单,减少学习的估计误差,但缺点是学习的近似误差会增大。3.4)K近邻算法的缺点与改进我们看到,对于样本 X,通过 KNN 算法,我们显然可以得到 X 应属于红色类别。但对于样本 Y,KNN 算法判定的结果是 Y应属于蓝色类别,然而从距离上看 Y和红色的批次样本点更接近。因此,原始的 KNN 算法只考虑近邻不同类别的样本数量,而忽略掉了距离KNN 还存在如下缺点:样本库容量依赖性较强对 KNN 算法在实际应用中的限制较大:有不少类别无法提供足够的训练样本,使得 KNN 算法所需要的相对均匀的特征空间条件无法得到满足,使得识别的误差较大。K值的确定: KNN 算法必须指定 K值,K值选择不当则分类精度不能保证。3.5、改进:1、标准化 提升计算速度,标准差标准化:2、浓缩训练样本,从原始训练样本集中选择最优的参考子集进行K近邻寻找,从而减少训练样本的存储量和提高计算效率4、代码实现:Iris分类-KNN• sklearnimport numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
X, y = make_blobs(n_samples = 500, n_features = 2, centers = 4,cluster_std = 1.5, random_state = 4)
plt.style.use('seaborn')
plt.figure(figsize = (10,10))
plt.scatter(X[:,0], X[:,1], c=y, marker= '*',s=100,edgecolors='black')
plt.show()
PythonCopy
from sklearn.metrics import accuracy_score
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state = 0)
knn5 = KNeighborsClassifier(n_neighbors = 5)
knn1 = KNeighborsClassifier(n_neighbors=1)
knn5.fit(X_train, y_train)
knn1.fit(X_train, y_train)
y_pred_5 = knn5.predict(X_test)
y_pred_1 = knn1.predict(X_test)
print("Accuracy with k=5", accuracy_score(y_test, y_pred_5)*100)
print("Accuracy with k=1", accuracy_score(y_test, y_pred_1)*100)
plt.figure(figsize = (15,5))
plt.subplot(1,2,1)
plt.scatter(X_test[:,0], X_test[:,1], c=y_pred_5, marker= '*', s=100,edgecolors='black')
plt.title("Predicted values with k=5", fontsize=20)
plt.subplot(1,2,2)
plt.scatter(X_test[:,0], X_test[:,1], c=y_pred_1, marker= '*', s=100,edgecolors='black')
plt.title("Predicted values with k=1", fontsize=20)
plt.show()
PythonCopy
搜不鸟了
量化交易--交易策略超参数优化-5
上一节我们经过简单优化后实现了第一个盈利的策略,但我们依然需要思考一下策略参数是不是最优的,是否还有优化的空间?本节我们将基于 freqtrade 的Hyperopt模块,对我们的策略参数进行优化,Hyperopt本质上还是基于scikit-optimize进行开发的。我们先简单介绍一下原理,超参数优化一般有三种方式:1、网格搜索(Grid Search)网格搜索是暴力搜索,在给定超参搜索空间内,尝试所有超参组合,最后搜索出最优的超参组合,主要缺点是耗时,不适应大量参数的穷举,如下图:2、随机搜索(Randomized Search)随机搜索是在搜索空间中采样出超参组合,然后选出采样组合中最优的超参组合。随机搜索的好处如下图所示: 网格搜索和随机搜索的对比[2]网格搜索不会care这个参数是否为important parameter,对于所有参数一视同仁,穷举所有的情况,寻找最优参数组合;而随机搜索会有更多的参数值参与到important parameter中,减少搜索范围,提升搜索效率。3、贝叶斯优化(Bayesian Optimization)调优的目的是要找到一组最优的超参组合,能使目标函数f达到全局最小值。举个例子,若学习率设置过大,模型可能会在代价函数的全局最优点附近不断来回震荡,甚至跳出全局最优点,而设置过小,又可能会陷入局部最优,因此调学习率这一参数,是为了让模型能收敛到代价函数的全局最小值。可是在机器学习中,目标函数f常是被称作expensive blackbox function,计算开销大且不一定为凸函数。为此,贝叶斯优化出现了,它特别适合针对expensive blackbox function找到全局最优。 随机采样10个点的目标函数f(x)[4]贝叶斯优化使用了高斯过程(gasussian processes, GP)去构建代理模型,基于给定的输入和输出,GP会推断出一个模型(这里为代理模型)。假设我们从expensive step的f(x)采样了4个点,然后我们把这4个点交给GP,它会返回一个代理模型绿色实线就是GP的代理模型,绿色条带是输出分布的标准差(即为Uncertainty)。我们有了代理模型,后续我们去找下一个合适的超参值,就能带入到计算开销相对较小的代理模型中,评估给定超参值的情况。对上述原理感兴趣的小伙伴,还可以再深入了解一下。Code实现我们HyperOpt的超参数调优代码:(相对比较简单)# Hyperoptable parameters
buy_rsi = IntParameter(low=1, high=50, default=30, space='buy', optimize=True, load=True)
sell_rsi = IntParameter(low=50, high=100, default=70, space='sell', optimize=True, load=True)
short_rsi = IntParameter(low=51, high=100, default=70, space='sell', optimize=True, load=True)
exit_short_rsi = IntParameter(low=1, high=50, default=30, space='buy', optimize=True, load=True)将买入参数变量替换至买入策略中:同理将卖出参数变量替换至卖出策略中:启动参数调优,设置为500epoch:docker-compose run --rm freqtrade hyperopt --config user_data/config.json --hyperopt-loss SharpeHyperOptLossDaily --strategy HyperIndexStrategy -e 500参数调优结果从截图中可以看到,500 epoch运行完成后,best结果是在第141个epoch中得到,最大收益率1.6%,最大回撤2.02%。给出最优参数(买入、卖出、ROI、止损)组合如下:
搜不鸟了
机器学习-XGBoost-07
1、XGBoost算法XGBoost 是 eXtreme Gradient Boosting 的缩写称呼,它是一个非常强大的 Boosting 算法工具包,优秀的性能(效果与速度)让其在很长一段时间内霸屏数据科学比赛解决方案榜首,现在很多大厂的机器学习方案依旧会首选这个模型。XGBoost 在并行计算效率、缺失值处理、控制过拟合、预测泛化能力上都变现非常优秀。本文我们给大家详细展开介绍 XGBoost,包含「算法原理」和「工程实现」两个方面。2、算法原理可视化解读关于 XGBoost 的原理,其作者陈天奇本人有一个非常详尽的Slides做了系统性的介绍,我们在这里借助于这个资料给大家做展开讲解。2.1、监督学习核心要素符号(Notations):��∈��xi∈Rd表示训练集中的第i个样本。模型(Model):对于已知的��xi如何预测��^yi^?线性模型(Linear Model):�^=∑������y^=∑jwjxij(包括线性回归和逻辑回归),预测值��^yi^根据不同的任务有不同的解释:线性回归(Linear Regression): ��^yi^表示预测的分数。逻辑回归(Logistic Regression):1/(1+�−�^�)1/(1+e−y^i) 预测了实例为正的概率。其他:例如在排名任务中 ��^yi^可以是排名分数。2.2、监督学习进阶知识Ridge回归(L2正则化):• Ridge 是线性模型(Linear Model),用的是平方损失(Square Loss),正则化项是 L2 Norm。Lasso回归(L1正则化):• Lasso是线性模型(Linear Model),用的是平方损失(Square Loss),正则化项是L1 Norm。逻辑回归:• 逻辑回归是线性模型(Linear Model),用的是逻辑损失(Logistic Loss),正则化项是 L2 Norm。2.3、目标函数及偏差方差权衡优化训练损失函数(Training Loss)有助于建立预测模型,很好地拟合训练数据至少能让你更接近潜在的训练数据的分布。优化正则化项(Regularization)有助于建立简单的模型:模型越简单,未来预测的方差越小,预测越稳定。3、XGBoost算法原理案例:如上图所示,将左侧的数据输入到模型1中,会得到预测收入。预测收入和真实的收入之间的差值记做残差。由于这个模型1有一定的能力,但是能力比较弱,遗留了一些问题。这个残差就能表征这个遗留的问题。紧接着,再训练一个模型2去预测这些样本,只不过目标值改为刚刚得到的残差。上图所示,预测的结果不再是收入,而是模型1得到的残差。上图中的模型2还会得到残差,但是我们发现第一行样本的残差已经为零了。也就是说第一个样本,通过模型1和模型2能够预测对收入。但是除了第一行,其他的还是有残差的,这时候可以在这基础上训练一个模型3上图所示,在刚刚 模型2得到的残差(准确的说是模型1和模型2共同作用的结果) 的基础上去拟合,得到模型3。这时候的残差可以理解为是前两个模型遗留下来的问题。该模型去预测模型2的残差,我们发现通过前三个模型的预测,得到的残差是上图中最新的残差这一列。这时候最新的残差都是非常小了,如果能达到我们满意的标准,我们就可以停下。这样我们就得到了三个不同的模型。如下图所示,最终的预测就是三个模型预测的结果和。如下图:我们解决问题的步骤:如何构造目标函数 -> 目标函数直接优化难,如何近似? -> 如何把树的结构引入到目标函数?-> 仍然难优化,要不要使用贪心算法?3.1 构建目标函数首先举个例子,用多棵树来预测张三、李四的薪资。如下图所示,用年龄这个因素构建的树预测张三的值为12,用工作年限这个因素构建的树张三为2. 两个相加就是对张三薪资的预测:12+2=14。假设已经训练了�K颗树,则对于第�i个样本的最终预测值为:��xi是样本的特征,��(��)fk(xi)是用第�k颗树��xi样本进行预测。将结果加在一起就得到了最终的预测值�^�y^i,而该样本的真实label是��yi。这样我们就能构建损失函数了。构建的目标函数如下:损失函数计算模型预测值和真实值的 loss,其中�l是损失函数,可以是 MSE、Cross Entropy 等等。第二项是正则项,来控制模型的复杂度,防止过拟合。这个正则项可以类比 L2 正则。3.2叠加式的训练3.3用泰勒级数近似目标函数3.4如何用参数表示一颗树3.5、定义树的复杂度3.6、新的目标函数经过上面的一步步的简化,我们把最初的目标函数:简化为了:紧接着,看下图,假设第一个叶节点上(即 15 的地方)有样本[1, 3]落在这里 ,第二个节点有样本[2]落在这个地方,样本[4,5]落在了第三个叶子结点处这里 :所以:二次函数求最优解问题。知识回顾,典型的二次函数:最小点的值为:3.7、如何寻找树的形状?。所以,使用贪心的方式,选择新的树目标函数值较小的那颗树。比如下面这个例子,我们有样本[1、2、3、4、5、6、7、8],第一颗树把这些样本分为了两部分,左侧的叶子结点是[7,8],右侧节点是[1,2,3,4,5,6]。此时我们知道了树的结构,可以根据如下的公式计算出此时树的最小目标函数值:紧接着,我们根据新的特征对叶子结点再次进行了分割,得到了如下的树的形状:紧接着计算两颗树最小目标函数值的差:4.XGBoost工程优化4.1、并行列块设计XGBoost 将每一列特征提前进行排序,以块(Block)的形式储存在缓存中,并以索引将特征值和梯度统计量对应起来,每次节点分裂时会重复调用排好序的块。而且不同特征会分布在独立的块中,因此可以进行分布式或多线程的计算。4.2、缓存访问优化4.3、核外块计算数据量非常大的情形下,无法同时全部载入内存。XGBoost 将数据分为多个 blocks 储存在硬盘中,使用一个独立的线程专门从磁盘中读取数据到内存中,实现计算和读取数据的同时进行。为了进一步提高磁盘读取数据性能,XGBoost 还使用了两种方法:① 压缩 block,用解压缩的开销换取磁盘读取的开销。② 将 block 分散储存在多个磁盘中,提高磁盘吞吐量。5.XGBoost vs GBDTGBDT和这里的 XGBoost 做一个对比总结:GBDT 是机器学习算法,XGBoost 在算法基础上还有一些工程实现方面的优化。GBDT 使用的是损失函数一阶导数,相当于函数空间中的梯度下降;XGBoost 还使用了损失函数二阶导数,相当于函数空间中的牛顿法。正则化:XGBoost 显式地加入了正则项来控制模型的复杂度,能有效防止过拟合。列采样:XGBoost 采用了随机森林中的做法,每次节点分裂前进行列随机采样。缺失值:XGBoost 运用稀疏感知策略处理缺失值,GBDT无缺失值处理策略。并行高效:XGBoost 的列块设计能有效支持并行运算,效率更优。6、Codeimport xgboost as xgb
from xgboost import plot_importance
from matplotlib import pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_boston
# 导入数据集
boston = load_boston()
X ,y = boston.data,boston.target
# Xgboost训练过程
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=0)
model = xgb.XGBRegressor(max_depth=5,learning_rate=0.1,n_estimators=160,silent=True,objective='reg:gamma')
model.fit(X_train,y_train)
# 对测试集进行预测
ans = model.predict(X_test)
# 显示重要特征
plot_importance(model)
plt.show()
PythonCopy
from sklearn.model_selection import train_test_split
from sklearn import metrics
from sklearn.datasets import make_hastie_10_2
from xgboost.sklearn import XGBClassifier
X, y = make_hastie_10_2(random_state=0)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=0)##test_size测试集合所占比例
clf = XGBClassifier(
silent=0 ,#设置成1则没有运行信息输出,最好是设置为0.是否在运行升级时打印消息。
#nthread=4,# cpu 线程数 默认最大
learning_rate= 0.3, # 如同学习率
min_child_weight=1,
# 这个参数默认是 1,是每个叶子里面 h 的和至少是多少,对正负样本不均衡时的 0-1 分类而言
#,假设 h 在 0.01 附近,min_child_weight 为 1 意味着叶子节点中最少需要包含 100 个样本。
#这个参数非常影响结果,控制叶子节点中二阶导的和的最小值,该参数值越小,越容易 overfitting。
max_depth=6, # 构建树的深度,越大越容易过拟合
gamma=0, # 树的叶子节点上作进一步分区所需的最小损失减少,越大越保守,一般0.1、0.2这样子。
subsample=1, # 随机采样训练样本 训练实例的子采样比
max_delta_step=0,#最大增量步长,我们允许每个树的权重估计。
colsample_bytree=1, # 生成树时进行的列采样
reg_lambda=1, # 控制模型复杂度的权重值的L2正则化项参数,参数越大,模型越不容易过拟合。
#reg_alpha=0, # L1 正则项参数
#scale_pos_weight=1, #如果取值大于0的话,在类别样本不平衡的情况下有助于快速收敛。平衡正负权重
#objective= 'multi:softmax', #多分类的问题 指定学习任务和相应的学习目标
#num_class=10, # 类别数,多分类与 multisoftmax 并用
n_estimators=100, #树的个数
seed=1000 #随机种子
#eval_metric= 'auc'
)
clf.fit(X_train,y_train,eval_metric='auc')
#设置验证集合 verbose=False不打印过程
clf.fit(X_train, y_train,eval_set=[(X_train, y_train), (X_val, y_val)],eval_metric='auc',verbose=False)
#获取验证集合结果
evals_result = clf.evals_result()
y_true, y_pred = y_test, clf.predict(X_test)
print"Accuracy : %.4g" % metrics.accuracy_score(y_true, y_pred)
#回归
#m_regress = xgb.XGBRegressor(n_estimators=1000,seed=0)
PythonCopy
params = {'objective': 'reg:squarederror',
# 默认reg:linear。 reg:squarederror,代表要解决的问题时分类还是回归,取值可以很多,一般只关心是分类还是回归,
# 在回归问题objective一般使用reg:squarederror ,即MSE均方误差或者:reg:linear , reg:logistic , count:poisson 。
# 二分类问题一般使用binary:logistic,rank:pairwise
# 多分类问题一般使用multi:softmax
搜不鸟了
量化交易-策略改进-4
TA-LIB金融分析库TA-Lib,全称“Technical Analysis Library”, 即技术分析库,是Python金融量化的高级库,涵盖了150多种股票、期货交易软件中常用的技术分析指标,如MACD、RSI、KDJ、动量指标、布林带等等。TA-Lib可分为10个子板块:Overlap Studies(重叠指标),Momentum Indicators(动量指标),Volume Indicators(交易量指标),Cycle Indicators(周期指标),Price Transform(价格变换),Volatility Indicators(波动率指标),Pattern Recognition(模式识别),Statistic Functions(统计函数),Math Transform(数学变换)和Math Operators(数学运算),见下图。TA-Lib在国外应用非常广泛,是Python量化投资分析的主要利器之一(另外两个是Pandas和zipline)其中 Overlap Studies Functions重叠指标 是我们的常用指标:移动平均线是技术分析理论中应用最普遍的指标之一,主要用于确认、跟踪和判断趋势,提示买入和卖出信号,在单边市场行情中可以较好的把握市场机会和规避风险。但是,移动平均线一般要与其他的技术指标或基本面相结合来使用,特别是当市场处于盘整行情时,其买入卖出信号会频繁出现,容易失真。具体案例如下图:布林带(Bollinger Band),由压力线、支撑线价格平均线组成,一般情况价格线在压力线和支撑线组成的上下区间中游走,区间位置会随着价格的变化而自动调整。布林线的理论使用原则是:当股价穿越最外面的压力线(支撑线)时,表示卖点(买点)出现。当股价延着压力线(支撑线)上升(下降)运行,虽然股价并未穿越,但若回头突破第二条线即是卖点或买点。在实际应用中,布林线有其滞后性,相对于其他技术指标在判断行情反转时参考价值较低,但在判断盘整行情终结节点上成功率较高。具体案例如下图:此次使用的相关指标应该有个了解了,接着我们应用到我们的策略中。策略开发策略准备阶段配置#策略准备配置
minimal_roi = {
"60": 0.01,
"30": 0.03,
"20": 0.04,
"0": 0.05
}
#收益率时长要求
stoploss = -0.15 #适当放开止损率
timeframe = '5m'
order_types = {
'entry': 'limit',
'exit': 'limit',
'stoploss': 'market',
'stoploss_on_exchange': False
}策略引入指标:#引入上一节中的指标:bb_xxxx,rsi、tema
# RSI、
dataframe['rsi'] = ta.RSI(dataframe)
# Bollinger bands
bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2)
dataframe['bb_upperband'] = bollinger['upper']
dataframe['bb_middleband'] = bollinger['mid']
dataframe['bb_lowerband'] = bollinger['lower']
# TEMA - Triple Exponential Moving Average
dataframe['tema'] = ta.TEMA(dataframe, timeperiod=9)策略买入&卖出的逻辑:# 买入逻辑
dataframe.loc[
(
(qtpylib.crossed_above(dataframe['rsi'], 30)) & #当前市恐慌
(dataframe['tema'] <= dataframe['bb_middleband']) & # 由下而上穿过bb_mid
(dataframe['tema'] > dataframe['tema'].shift(1)) & # 当前额指标值大于前一个时段
(dataframe['volume'] > 0) # 要求成交量大于0
),
'enter_long'] = 1
PythonCopy# 卖出逻辑
dataframe.loc[
(
(qtpylib.crossed_above(dataframe['rsi'], 64)) &
(dataframe['tema'] > dataframe['bb_middleband']) &
(dataframe['tema'] < dataframe['tema'].shift(1)) &
(dataframe['volume'] > 0)
),
'exit_long'] = 1 接着我们看一下回测效果:# 回测
docker-compose run --rm freqtrade backtesting --config user_data/config.json --strategy MutilIndexStrategy --timerange 20220409-20220509 -i 5m总结一下核心数据:1、一共进行5个交易对,回测时间一个月,净亏损65USDT2、表现最好交易对:TRX/USDT,表现最差交易对:ADA/USDT整体还是一个亏损的策略,接着我们优化一下:只采用表现最好的交易对TRX/USDT(注:通常情况下不存在一个交易策略可以对大部分的交易对或行情生效,通常我们会为一种行情或交易对定制交易对)# 回测
docker-compose run --rm freqtrade backtesting --config user_data/config.json --strategy MutilIndexStrategy --pair TRX/USDT --timerange 20220409-20220509 -i 5m效果总结:1、回测时间一个月,整体盈利12USDT,收益率1.2%2、单日最大盈利6.4USDT,单日最大亏损-3.2USDT整体看收益和最大回撤都比较小,是一个相对稳定的策略。接着我们需要思考以下2个问题:1、如果新增交易指标,如何确定指标的阈值?2、现有的策略是否还有提升空间,是否可以通过调整阈值来提升收益率?以上不管哪种情况,我们都需要不断的尝试不同的 指标+阈值 的组合,这个组合优化是非常大的,人力很难穷尽,那么是否有办法自动帮我们找出最优的参数组合?下一节我们接着介绍利用Hyperopt进行超参数优化,使用贝叶斯搜索和ML回归算法在搜索超空间中快速找到使目标值最小化的参数组合
搜不鸟了
机器学习-线性回归-01
1、什么是线性回归?线性:两个变量之间的关系是一次函数关系的非线性:两个变量之间的关系不是一次函数关系的2、应用场景房价预测流量预测票房预测....3、表达式&优化函数表达式: w是x的系数,b是偏置项目标函数(Loss Function) 利用梯度下降法求 J 的最小值,从而推导出w和b4、为什么需要正则化4.1、L1正则化(Lasso回归)L1正则化项:L1如何解决过拟合问题特征稀疏性4.2、L2正则化(岭回归)L2正则化项:L2如何解决过拟合问题拟合过程中通常都倾向于让权值尽可能小参数很小,数据偏移得多一点也不会对结果造成什么影响,鲁棒性更强参数:5、代码实现:房价回归预测-LinearRegression# encoding: utf-8
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
# 1.获取数据集
boston_data = load_boston()
x = pd.DataFrame(boston_data.data) # 波士顿房价data
y = boston_data.target # 波士顿房价真实值
x.columns = boston_data.feature_names # 特征赋值
#特征14个:
#CRIM: 城镇人均犯罪率
#ZN: 住宅用地所占比例
#INDUS: 城镇中非住宅用地所占比例
#CHAS: 虚拟变量,用于回归分析
#NOX: 环保指数
#RM: 每栋住宅的房间数
#AGE: 1940 年以前建成的自住单位的比例
#DIS: 距离 5 个波士顿的就业中心的加权距离
#RAD: 距离高速公路的便利指数
#TAX: 每一万美元的不动产税率
#PTRATIO: 城镇中的教师学生比例
#B: 城镇中的黑人比例
#LSTAT: 地区中有多少房东属于低收入人群
#MEDV: 自住房屋房价中位数(也就是均价)
#x.columns
# 2.划分训练集、测试集
xtrain,xtest,ytrain,ytest = train_test_split(x,y,test_size=0.2,random_state=125)
# 3.建立线性回归模型
model = LinearRegression().fit(xtrain,ytrain)
# 4.1 获取预测值
y_pred = model.predict(xtest)
# 4.2 获取回归系数
y_w = model.coef_
# 4.3 获取截距
y_w0 = model.intercept_
# 4.4 将回归系数与特征对应
compare_feature = [*zip(xtrain.columns,y_w)]
compare_feature
# 5.预测结果可视化
plt.rcParams['font.sans-serif'] = 'SimHei'
fig = plt.figure(figsize=(10,6))
plt.plot(range(ytest.shape[0]),ytest,color='black',linestyle='-',linewidth=1.5)
plt.plot(range(y_pred.shape[0]),y_pred,color='red',linestyle='-.',linewidth=1.5)
plt.xlim((0,102))
plt.ylim((0,55))
plt.legend(['真实值','预测值'])
plt.show()
PythonCopy
搜不鸟了
机器学习-LightGBM-08
1、LightGBM介绍LightGBM 是微软开发的 boosting 集成模型,和 XGBoost 一样是对 GBDT 的优化和高效实现,原理有一些相似之处,但它很多方面比 XGBoost 有着更为优秀的表现。官方给出的这个工具库模型的优势如下:更快的训练效率低内存使用更高的准确率支持并行化学习可处理大规模数据支持直接使用 category 特征在实验中,LightGBM 比 XGBoost 快将近 10倍,内存占用率大约为 XGBoost 的 1/6,准确率也略有提升2、LightGBM的背景 GBDT 在每一次迭代的时候,都需要遍历整个训练数据多次。如果把整个训练数据一次性装进内存,会明显限制训练数据的大小。如果不装进内存,反复地读写训练数据又会消耗非常大的时间。面对工业级海量的数据,普通的 GBDT 算法无法满足需求。 LightGBM 提出的主要原因之一,就是为了解决上述大数据量级下的 GBDT 训练问题,以便工业实践中能支撑大数据量并保证效率。3. XGBoost 优缺点XGB优缺点归纳如下:3.1、精确贪心算法多轮迭代时,都需要遍历整个训练数据多次。如果把整个训练数据装进内存则会限制训练数据的大小;如果不装进内存,反复地读写训练数据又会消耗非常大的时间。优点:可以找到精确的划分条件。缺点:计算量巨大、内存占用巨大、易产生过拟合。3.2、Level-wise生长方式XGBoost 采用 Level-wise 的增长策略:基于层进行生长,直到达到停止条件。这种增长策略方便并行计算每一层的分裂节点,提高了训练速度,但同时也因为节点增益过小增加了很多不必要的分裂,增加了计算量优点:可以使用多线程、可以加速精确贪心算法。缺点:效率低下,可能产生不必要的叶结点。3.3、对cache优化不友好对cache优化不友好。在预排序后,特征对梯度的访问是一种随机访问,并且不同的特征访问的顺序不一样,无法对cache进行优化4、LightGBM优势LightGBM优势:基于 Histogram 的决策树算法带深度限制的 Leaf-wise 的叶子生长策略直方图做差加速直接支持类别特征(Categorical Feature)Cache命中率优化基于直方图的稀疏特征优化多线程优化4.1 LightGBM:直方图算法LightGBM 使用的是直方图算法,算法思想:将连续的浮点特征离散成 k个离散值,并构造宽度为 k 的 histogram 。遍历训练数据,统计每个离散值在直方图中的累计统计量。在进行特征选择时,只需要根据直方图的离散值,遍历寻找最优的分割点。1、内存优化:直方图算法可以很大程度降低内存消耗,它不仅不需要额外存储预排序的结果,还可以只保存特征离散化后的值(一般用 位整型存储就足够了)2、计算优化:应用直方图算法,计算代价也大幅降低,预排序算法每遍历一个特征值就需要计算一次分裂的增益,而直方图算法只需要计算 k次(可以认为是常数)4.2、直方图算法的理解和注意点如下:使用分桶 bin 替代原始数据相当于增加了正则化。使用分桶 bin 意味着很多数据的细节特征丢失,相似的数据如果划分到相同的桶中,数据之间的差异就无法捕获了。分桶 bin 数量决定了正则化的程度,bin 越少惩罚越严重,欠拟合风险越高。因为预先设定了 bin 的范围,构建直方图时不需要对数据进行排序。直方图保存「划分阈值」、「当前 bin 内样本数」、「当前 bin 内所有样本的一阶梯度和」。阈值的选取是按照直方图从小到大遍历,使用了上面的一阶梯度和,目的是得到划分之后 损失函数 最大的特征及阈值。5、决策树生长策略(LightGBM)原理5.1、树生长策略调整直方图算法之上,LightGBM 进行进一步的优化。它没有使用大多数 GBDT 工具使用的按层生长(Level-wise)的决策树生长策略,而使用了带有深度限制的按叶子生长(Leaf-wise)算法。5.2、XGBoost :Level-wiseXGBoost 采用的是Level-wise(按层生长)策略生长的,能够同时分裂同一层的叶子,从而进行多线程优化,不容易过拟合。但不加区分的对待同一层的叶子,带来了很多没必要的开销。因为实际上很多叶子的分裂增益较低,没必要进行搜索和分裂。5.3、LightGBM :Leaf-wiseLightGBM 采用 Leaf-wise(按叶子生长)生长策略,每次从当前所有叶子中找到分裂增益最大(一般也是数据量最大)的一个叶子,然后分裂,如此循环。Leaf-wise 可以降低更多的误差,得到更好的精度。Leaf-wise 的缺点是可能会长出比较深的决策树,产生过拟合。因此 LightGBM 在 Leaf-wise 之上增加了一个最大深度的限制,在保证高效率的同时防止过拟合5.4、直方图差加速LightGBM 另一个优化是 Histogram (直方图)做差加速。整个构建过程中可以观察到:一个叶子的直方图可以由它的父亲节点的直方图与它兄弟的直方图做差得到。6. LightGBM的工程优化6.1 直接支持类别特征实际上大多数机器学习工具都无法直接支持类别特征,一般需要把类别特征,通过 one-hot 编码,转化到多维的特征,降低了空间和时间的效率我们知道对于决策树来说并不推荐使用 one-hot 编码,尤其当类别特征中类别个数很多的情况下,会存在以下问题:问题1:可能无法在这个类别特征上进行切分使用 one-hot 编码的话,意味着在每一个决策节点上只能使用one vs rest类别值很多时,每个类别上的数据可能会比较少,这时候切分会产生不平衡,这意味着切分增益也会很小问题2:影响决策树的学习就算可以在这个类别特征进行切分,也会把数据切分到很多零碎的小空间上而决策树学习时利用的是统计信息,在这些数据量小的空间上,统计信息不准确,学习会变差6.2、LightGBM 类别型特征处理方式LightGBM 采用了 Many vs Many 的切分方式解决 one-hot 编码带来的问题,用 LightGBM 可以直接输入类别特征算法流程如图所示:① 在枚举分割点之前,先把直方图按每个类别的均值进行排序。② 接着按照均值的结果依次枚举最优分割点。求解类别型特征的最优切分的具体流程如下:① 离散特征建立直方图的过程统计该特征下每一种离散值出现的次数,并从高到低排序,并过滤掉出现次数较少的特征值。然后为每一个特征值,建立一个 bin 容器,对于在 bin 容器内出现次数较少的特征值直接过滤掉,不建立 bin 容器② 计算分裂阈值的过程先看该特征下划分出的 bin 容器的个数,如果 bin 容器的数量小于 4,直接使用 one vs other 方式,逐个扫描每一个 bin 容器,找出最佳分裂点。对于 bin 容器较多的情况,先进行过滤,只让子集合较大的 bin 容器参加划分阈值计算,对每一个符合条件的 bin 容器进行公式计算,得到一个值,根据该值对 bin 容器从小到大进行排序,然后分从左到右、从右到左进行搜索,得到最优分裂阈值。公式如下:这里为什么不是 label 的均值呢?其实上例中只是为了便于理解,只针对了学习一棵树且是回归问题的情况。这时候一阶导数是Y,二阶导数是 1),没有搜索所有的 bin 容器,而是设定了一个搜索 bin 容器数量的上限值,程序中设定是 32,即参数 max_num_cat。LightGBM 中对离散特征实行的是 many vs many 策略,这 32 个 bin 中最优划分的阈值的左边或者右边所有的 bin 容器就是一个 many 集合,而其他的 bin 容器就是另一个 many 集合。③ 对于连续特征,划分阈值只有一个。对于离散值可能会有多个划分阈值,每一个划分阈值对应着一个 bin 容器编号7.并行支持与优化LightGBM 原生支持并行学习,目前支持「特征并行」和「数据并行」的两种,LightGBM 针对这两种并行方法都做了优化。特征并行:在不同机器在不同的特征集合上分别寻找最优的分割点,然后在机器间同步最优的分割点。数据并行:让不同的机器先在本地构造直方图,然后进行全局的合并,最后在合并的直方图上面寻找最优分割点。7.1、特征并行LightGBM 在特征并行算法中,通过在本地保存全部数据避免对数据切分结果的通信。7.2、数据并行Lightgbm在数据并行中使用分散规约(Reduce scatter)把直方图合并的任务分摊到不同的机器,降低通信和计算,并利用直方图做差,进一步减少了一半的通信量。基于投票的数据并行则进一步优化数据并行中的通信代价,使通信代价变成常数级别。在数据量很大的时候,使用投票并行可以得到非常好的加速效果7.3、Cache命中率优化LightGBM 所使用直方图算法对 Cache 天生友好:首先,所有的特征都采用相同的方式获得梯度(区别于XGBoost的不同特征通过不同的索引获得梯度),只需要对梯度进行排序并可实现连续访问,大大提高了缓存命中率;其次,因为不需要存储行索引到叶子索引的数组,降低了存储消耗,而且也不存在 Cache Miss的问题。8. LightGBM的优缺点8.1 优点这部分主要总结下 LightGBM 相对于 XGBoost 的优点,从内存和速度两方面进行介绍。(1)速度更快LightGBM 采用了直方图算法将遍历样本转变为遍历直方图,极大的降低了时间复杂度;LightGBM 在训练过程中采用单边梯度算法过滤掉梯度小的样本,减少了大量的计算;LightGBM 采用了基于 Leaf-wise 算法的增长策略构建树,减少了很多不必要的计算量;LightGBM 采用优化后的特征并行、数据并行方法加速计算,当数据量非常大的时候还可以采用投票并行的策略;LightGBM 对缓存也进行了优化,增加了缓存命中率;(2)内存更小XGBoost使用预排序后需要记录特征值及其对应样本的统计值的索引,而 LightGBM 使用了直方图算法将特征值转变为 bin 值,且不需要记录特征到样本的索引,将空间复杂度从 降低为 ,极大的减少了内存消耗;LightGBM 采用了直方图算法将存储特征值转变为存储 bin 值,降低了内存消耗;LightGBM 在训练过程中采用互斥特征捆绑算法减少了特征数量,降低了内存消耗。8.2 缺点可能会长出比较深的决策树,产生过拟合。因此LightGBM在Leaf-wise之上增加了一个最大深度限制,在保证高效率的同时防止过拟合;Boosting族是迭代算法,每一次迭代都根据上一次迭代的预测结果对样本进行权重调整,所以随着迭代不断进行,误差会越来越小,模型的偏差(bias)会不断降低。由于LightGBM是基于偏差的算法,所以会对噪点较为敏感;在寻找最优解时,依据的是最优切分变量,没有将最优解是全部特征的综合这一理念考虑进去;9.Codeimport lightgbm as lgb
from sklearn import datasets
from sklearn.model_selection import train_test_split
import numpy as np
from sklearn.metrics import roc_auc_score, accuracy_score
# 加载数据
iris = datasets.load_iris()
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.3)
# 转换为Dataset数据格式
train_data = lgb.Dataset(X_train, label=y_train)
validation_data = lgb.Dataset(X_test, label=y_test)
# 参数
params = {
'learning_rate': 0.1,
'lambda_l1': 0.1,
'lambda_l2': 0.2,
'max_depth': 4,
'objective': 'multiclass', # 目标函数
'num_class': 3,
}
# 模型训练
gbm = lgb.train(params, train_data, valid_sets=[validation_data])
# 模型预测
y_pred = gbm.predict(X_test)
y_pred = [list(x).index(max(x)) for x in y_pred]
print(y_pred)
# 模型评估
print(accuracy_score(y_test, y_pred))
搜不鸟了
机器学习-支持向量机(SVM)-09
一、SVM简介支持向量机(support vector machines, SVM)是一种二分类模型,它的基本模型是定义在特征空间上的间隔最大的线性分类器,间隔最大使它有别于感知机;SVM还包括核技巧,这使它成为实质上的非线性分类器。SVM的的学习策略就是间隔最大化,可形式化为一个求解凸二次规划的问题,也等价于正则化的合页损失函数的最小化问题。SVM的的学习算法就是求解凸二次规划的最优化算法。支持向量机学习方法,针对不同的情况,有由简至繁的不同模型:线性可分支持向量机(linear support vector machine in linearly separable case):训练数据线性可分的情况下,通过硬间隔最大化(hard margin maximization),学习一个线性的分类器,即线性可分支持向量机(亦称作硬间隔支持向量机)。线性支持向量机(linear support vector machine):训练数据近似线性可分的情况下,通过软间隔最大化(soft margin maximization),学习一个线性的分类器,称作线性支持向量机(又叫软间隔支持向量机)。非线性支持向量机(non-linear support vector machine):训练数据线性不可分的情况下,通过使用核技巧(kernel trick)及软间隔最大化,学习非线性分类器,称作非线性支持向量机。支持向量机可以借助核技巧完成复杂场景下的非线性分类,当输入空间为欧式空间或离散集合、特征空间为希尔贝特空间时,核函数(kernel function)表示将输入从输入空间映射到特征空间得到的特征向量之间的内积二、SVM的优化目标2.1、线性可分 SVM 与硬间隔最大化SVM 模型它不仅仅希望把两类样本点区分开,还希望找到鲁棒性最高、稳定性最好的决策边界(对应图中的黑色直线)当向量 x 为二维向量时, f(x) 表示二维空间中的一条直线。当向量 x 为三维向量时,f(x) 表示三维空间中的一个平面。当向量x 的 n维向量( fn>3)时,f(x) 表示 n 维空间中的 n-1 维超平面。当有一个新的点 x 需要预测属于哪个分类的时候,我们用 sign(f(x)) 就可以预测了。 sign表示符号函数:公式:根据svm的设定,当样本点分类正确的时候,有:y(xi)>0,yi=+1y(xi)<0,yi=−1根据上面两个公式可以推出: y·y(xi)>0回到重点,我们怎样才能取得一个最优的划分直线 f(x)呢?下图的直线表示几条可能的f(x):我们希望这条直线满足「最大间隔」原则,也就是如下图的形态。图中位于红色和蓝色线上的图标就是所谓的支持向量(support vector):决策边界就是f(x),红色和蓝色的线是支持向量(support vector)所在的面,红色、蓝色线之间的间隙就是我们要最大化的分类间的间隙M(Margin Width)2.2、几何间隔(重要)① 根据以上定义, SVM 模型的「求解最大分割超平面问题」可以表示为以下约束最优化问题:上面公式中 s.t 是 subject to 的缩写,也就是限制条件的意思。2.3、对偶算法求解线性可分支持向量机的最优化问题,我们很多时候会将它转化为对偶问题(dual problem)来求解,也就是应用「拉格朗日对偶性」,通过求解「对偶问题(dual problem)」得到「原始问题(primal problem)」的最优解,即线性可分支持向量机的对偶算法(dual algorithm)。这样做有一些优点:对偶问题往往更容易求解。引入自然核函数,进而可以推广到非线性分类问题。① 我们首先构建拉格朗日函数(Lagrange function)。为此,对每一个不等式约束引进拉格朗日乘子(Lagrange multiplier) 也就是说,这里的决策函数只依赖于输入�x 和训练样本输入的内积。上式亦称作线性可分 SVM 的对偶形式。2.4、线性 SVM 与软间隔最大化我们前面提到的是线性可分的情况,但实际应用中完全线性可分的情况太少见了。如下图就是一个典型的线性不可分的分类图(我们没有办法找到一条直线,把空间划分为 2个区域,一个区域只有黑点,一个区域只有白点)。要对其进行切分,有2种方案:方案1:用曲线去将其完全分开,即非线性的决策边界,这会和之后谈到的核函数关联。方案2:还是使用直线,不过不追求完全可分,会适当包容一些分错的情况,在这个过程中我们会在模型中加入惩罚函数,尽量让分错的点不要太多太离谱。对分错点的惩罚函数就是这个点到其正确位置的距离图上黄色、蓝色的直线分别为支持向量所在的边界,黑色的线为决策函数,那些绿色的线表示分错的点到其相应的决策面的距离,这样我们可以在原函数上面加上一个惩罚函数,并且带上其限制条件为:当C很大的时候,分错的点就会更少,但是过拟合的情况可能会比较严重。当C很小的时候,分错的点可能会很多,不过可能由此得到的模型也会不太正确。实际我们也会调整和选择合适的 C值。经过这个变换之后,我们可以同样求解一个拉格朗日对偶问题,得到原问题的对偶问题的表达式:在线性不可分情况下得到的对偶问题,不同的地方就是α的范围从 [0,+∞)[0,+∞),变为了[0,C),增加的惩罚ξ 没有为对偶问题增加太多复杂度。2.5、非线性 SVM 与核函数如果我们要处理的分类问题更加复杂,甚至不能像上面一样近似线性可分呢,这种情况下找到的超平面分错的程度太高不太可接受。对于这样的问题,一种解决方案是将样本从原始空间映射到一个更高维的特征空间,使得样本在这个特征空间内线性可分,然后再运用 SVM 求解,如下图所示:上述两个核函数分别为多项式核和高斯核,高斯核甚至是将原始空间映射为无穷维空间,比较常用的核函数就是高斯核函数3. SVM 总结3.1、模型总结支持向量机(Support vector machines, SVM)是一种二分类模型,它的基本模型是定义在特征空间上的间隔最大的线性分类器,他的学习策略就是间隔最大化,同时该方法可以形式化为一个求解图二次规划。SVM由简至繁可分为三类:线性可分支持向量机、硬间隔(hard-margin svm);线性支持向量机、软间隔(soft-margin svm);非线性支持向量机、Kernel SVM。SVM中存在三宝:间隔、对偶、核技巧3.2、模型优缺点(1)SVM模型优点SVM 是一个凸优化问题,求得的解一定是全局最优而不仅仅是局部最优。不仅适用于线性问题,还适用于非线性问题(借助核技巧)。模型鲁棒性好,决策边界只取决于支持向量而不是全部数据集。中小样本量数据集上效果优异。无需依赖整个数据。泛化能力比较强。(2)SVM模型缺点二次规划问题求解将涉及n阶矩阵的计算(其中n为样本的个数),计算量随样本量上涨厉害,因此 SVM 不适用于超大数据集。原始 SVM 仅适用于二分类问题。(当然, SVM 的推广SVR也适用于回归问题;我们也可以通过one-vs-one,one-vs-rest等思路组合 SVM 来解决多分类问题)。对非线性问题没有通用解决方案,有时候很难找到一个合适的核函数。对于核函数的高维映射解释力不强,尤其是径向基函数。SVM 对缺失数据敏感。4、代码演示-SVMsklearndata irisimport numpy as np
import matplotlib.pyplot as plt
from sklearn import svm, datasets
iris = datasets.load_iris()
X = iris.data[:, :2] #只取前两维特征,方便可视化
y = iris.target
# 线性可分
svc = svm.SVC(kernel='linear', C=1).fit(X, y)
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
h = (x_max / x_min) / 100
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
plt.subplot(1, 1, 1)
Z = svc.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, cmap=plt.cm.Paired, alpha=0.8)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Paired)
plt.xlabel('Sepal length')
plt.ylabel('Sepal width')
plt.xlim(xx.min(), xx.max())
plt.title('SVC with linear kernel')
plt.show()
#使用多项式核函数
#svc = svm.SVC(kernel='poly', degree=3).fit(X, y)
#使用rbf核函数(高斯核函数)
# svc = svm.SVC(kernel='rbf', C=1).fit(X, y)
PythonCopy
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm, datasets
iris = datasets.load_iris()
X = iris.data[:, :2] #只取前两维特征,方便可视化
y = iris.target
#
#svc = svm.SVC(kernel='linear', C=1).fit(X, y)
#使用多项式核函数
svc = svm.SVC(kernel='poly', degree=3).fit(X, y)
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
h = (x_max / x_min) / 100
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
plt.subplot(1, 1, 1)
Z = svc.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, cmap=plt.cm.Paired, alpha=0.8)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Paired)
plt.xlabel('Sepal length')
plt.ylabel('Sepal width')
plt.xlim(xx.min(), xx.max())
plt.title('SVC with poly kernel')
plt.show()
#使用多项式核函数
#svc = svm.SVC(kernel='poly', degree=3).fit(X, y)
#使用rbf核函数(高斯核函数)
# svc = svm.SVC(kernel='rbf', C=1).fit(X, y)
PythonCopy
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm, datasets
iris = datasets.load_iris()
X = iris.data[:, :2] #只取前两维特征,方便可视化
y = iris.target
#
#svc = svm.SVC(kernel='linear', C=1).fit(X, y)
#使用rbf核函数(高斯核函数)
svc = svm.SVC(kernel='rbf', C=1).fit(X, y)
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
h = (x_max / x_min) / 100
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
plt.subplot(1, 1, 1)
Z = svc.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, cmap=plt.cm.Paired, alpha=0.8)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Paired)
plt.xlabel('Sepal length')
plt.ylabel('Sepal width')
plt.xlim(xx.min(), xx.max())
plt.title('SVC with rbf kernel')
plt.show()
#使用多项式核函数
#svc = svm.SVC(kernel='poly', degree=3).fit(X, y)
#使用rbf核函数(高斯核函数)
# svc = svm.SVC(kernel='rbf', C=1).fit(X, y)
PythonCopy
gamma 值越大,SVM 就会倾向于越准确的划分每一个训练集里的数据,这会导致泛化误差较大和过拟合问题。
C:错误项的惩罚参数 C。它还控制平滑决策边界和正确分类训练点之间的权衡。
搜不鸟了
量化交易-最强辅助(可视化)-6
本节主要介绍如何做可视化&以及如何通过可视化来优化我们的量化交易策略。本节主要是提供一个策略优化的思路,最终上线的策略一定在足够的回测数据以不断调优的过程中诞生。可视化 图1 图2 图3 图4 图5图1介绍:左侧是我们策略执行的所有交易对列表,右侧是我们选中的某个交易对的蜡烛图、指标、趋势线以及买入&卖出的明细节点(是我们需要重点关注的)图2介绍:将图1右侧图表部分放大,通常分析的买入&卖出时机是我们需要关注的重点图表,很强大后面再详细介绍(是我们需要重点关注的)图3介绍:是某个交易对的交易概况,最大收益率、最大回撤、累积收益率、每笔交易的买入&卖出价格、关单理由(止损、收益达预期等)图4介绍:是我们整个策略的交易大盘情况,交易胜率、策略当前余额、每日收益、交易明细、当前开单情况图5介绍:记录我们策略的所有交易log,方便对照排查策略优化交易策略优化一般2个思路:让挣钱的策略盈利更高让亏钱的策略由亏转盈盈利策略优化:TRX/USDT 是我们策略中盈利的一个交易对,上图中有交易明细接着我们看一下具体的交易图表:买入判断:卖出判断:总结:1、从交易入场时机&出场时机看,我们两次的交易是盈利的2、买入&卖出时机的条件:tema>bb_lower & rsi<40,出场时机:tema>bb_upper3、从上面图表中我们会发现2个问题:策略并非在最低点买入,也并非在最高点卖出策略后续其实还有套利机会,但都被错过如上图我们优化买入时机如下:买入时机:adx<30 & tema>bb_lower & tema<bb_upper卖出时机:adx>60 & tema>bb_upper & rsi>70亏损策略优化:XRP/USDT的交易对,我们会发现在这个交易对,币价一直下跌,但策略却在一直开单,开的越多,亏损越大。原因:显然策略认为开单地点为短时段内的谷点。原始策略判断:买入时机:tema>bb_lower & rsi<40出场时机:tema>bb_upper策略优化思路:1、需要尽量避免下跌趋势中不断开单2、需要设置一个严格止损条件(上图:10分钟内下跌超过20%)优化策略时机:tema>bb_lower & rsi < 35 & rsi>adx & rsi(上个时间点)<=adx(上个时间点)tema>bb_upper & rsi>65 & rsi<adxstop_loss=-0.1(-10%)OK,以上基于可视化图表指标如何快速针对我们量化交易策略进行简单优化。优化策略如何设置判断条件阈值,主要依赖可视化图表提供的明细,另外已开个人经验
搜不鸟了
量化交易-EasyStrategy-2
布林带算法规则:林加通道也称为布林线(Bollinger Band)是由三条线组成,在中间的通常为 20 天平均线,而在上下的两条线则分别为 Up 线和 Down 线,算法是首先计出过去 20 日收巿价的布林线标准差SD(Standard Deviation) ,通常再乘 2 得出 2 倍标准差,Up 线为 20 天平均线加 2 倍标准差,Down 线则为 20 天平均线减 2 倍标准差 (上下两条蓝线:Bollinger Band)交易信号:股价由下向上穿越下轨线(LOWER)时,可视为买进信号股价长时间在中轨与上轨(UPER)间运行后,由上向下跌破中轨为卖出信号。接着我们定义几个简单的参数:inimal_roi = {
"40": 0.0, #运行40分钟且收益率>0%,则退出
"30": 0.01, #运行30分钟且收益率>1%,则退出
"20": 0.02, #运行20分钟且收益率>2%,则退出
"0": 0.04 #刚启动运行且收益率>4%,则退出
}
trailing_stop = False # 不启用追踪止损(动态止损的概念)
stoploss = -0.1 #单次交易损失超过10%,则触发止损
timeframe = '5m' #交易数据5m曲线
order_types = {
'entry': 'limit', #进场采用限价单
'exit': 'limit', #退出采用限价单
'stoploss': 'market', #止损时采用事假单
'stoploss_on_exchange': False #不启用交易所止损(后面再细讲)
}接着写我们核心的交易策略代码。我们的蜡烛数据已经准备好了,都是5min曲线数据。构建 Bollinger bands 指标:bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2)
dataframe['bb_upperband'] = bollinger['upper'] #bolling up line
dataframe['bb_midband'] = bollinger['mid'] # bolling standard line
dataframe['bb_lowerband'] = bollinger['lower'] #bolling down line买入策略:dataframe.loc[
(
(dataframe['close'] > dataframe['bb_midband'])
#这里逻辑简单点 收盘价大于标准价
),
'buy'] = 1卖出策略:dataframe.loc[
(
(dataframe['close'] > dataframe['bb_upperband'])
# 收盘价高于bolling up line
),
'sell'] = 1核心策略实现了,我们跑个回测看看效果:docker-compose run--rm freqtrade download-data --pairs ETH/BTC --exchange binance --days 5 -t 1h1、累计交易了314次,Tot Profit USDT(累积收益)-92.87USDT,(Tot Profit)收益率-9.29%2、LTC/USDT(为一个交易对),类似股票代码。不同交易对的Tot Profit USDT求和 就是最终的收益1、Starting balance初始资金1000USDT2、Final balance最终剩余资金907.13USDT3、Absolute profit绝对收益-92.87USDT4、Best Pair收益最好的交易对 ADA/USDT 2.11%5、Worst Pair收益最差的交易对 ETC/USDT -39.29%6、Best day收益最好的一天 11.654 USDT7、Worst day收益最差的一天 -29.955USDT8、Days win/draw/lose : 17天盈利/4天震荡/10天亏损优化:基于回测数据,我们再简单的优化一下策略:# 新增指标RSI
dataframe['rsi'] = ta.RSI(dataframe)
# 买入信号
dataframe.loc[
(
(qtpylib.crossed_above(dataframe['rsi'], 40)) &
(dataframe['close'] > dataframe['bb_midband'])
),
'buy'] = 1
#卖出信号
populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(
(qtpylib.crossed_above(dataframe['rsi'], 70)) &
(dataframe['close'] > dataframe['bb_midband'])
),
'sell'] = 1接着回测看一下效果:策略优化以后,明显可以看到策略亏损缩小至-34USDT。1、Starting balance初始资金1000USDT2、Final balance最终剩余资金965.346USDT3、Absolute profit绝对收益-34.654USDT4、Best Pair收益最好的交易对 ADA/USDT 2.11%5、Worst Pair收益最差的交易对 XRP/USDT -39.29%6、Best day收益最好的一天 3.542 USDT(最高收益&最大亏损都有明显缩小)7、Worst day收益最差的一天 -16.785USDT8、Days win/draw/lose : 19天盈利/1天震荡/11天亏损下一次再讲如何设计策略&分析指标与币价的关系
搜不鸟了
量化交易-开篇介绍-1
1、什么是量化交易量化交易是指以先进的数学模型替代人为的主观判断,利用计算机技术从庞大的历史数据中筛选能带来超额收益的多种“大概率”事件以制定策略,极大地减少了投资者情绪波动的影响,避免在市场极度狂热或悲观的情况下作出非理性的投资决策。一种科学化、体系化的投资方法,通过金融衍生品的对冲,基于大数据的策略,能够持续稳健的获利,哪怕是在大熊市中,量化投资表现也非常稳健散户苦等牛市,量化穿越牛熊!2、量化交易的案例2018 年 9 月 19 日,管理规模高达一万亿人民币的平安资管,宣布裁撤权益投资部门,全力转向量化和委外,这个消息震动整个资管行业。其实在过去几年,国际金融行业中,这种趋势一直在持续。2015 年 3 月,管理资产高达 1650 亿美元的桥水基金组建了新的人工智能团队,该团队将设计交易演算法,通过历史资料和统计概率预测未来。截止 2016 年底,高盛 600 名交易员只剩 2 人,现在三分之一的员工是计算机工程师,接下来高盛还将使 IPO 过程中约 146 个步骤获得自动化。2017 年 3 月底,全球最大资产管理公司贝莱德集团宣布,将裁去一批主动型基金经理,并用量化投资策略取而代之。2017 年 5 月 19 日,微软人工智能首席科学家、IEEE Fellow 邓力加入对冲基金公司 Citadel 担任首席人工智能官。3、需要具备什么条件基本能力要求:能熟练运用Python,常用的函数算法库:pandas、numpy、ta-lib等能看懂策略,能初步写一个自己的策略,国内的量化策略主要分为三种:Alpha策略CTA策略高频交易策略4、开始量化交易下面这个截图是基于freqtrade写的一个高频交易策略回测结果:上面的数据使用的是比特币数据,币圈的数据以及交易API是完全公开的,从量化交易策略转为实盘模式成本较低;另外币圈交易所的数据获取成本较低,直接调用交易所API即可策略依赖:1、freqtrade框架2、TA-Lib库3、python>=3.8.x4、pip5、docker
搜不鸟了
机器学习-模型评估-11
1.模型评估的目标模型评估的目标是选出泛化能力强的模型完成机器学习任务。泛化能力强的模型能很好地适用于未知的样本,模型的错误率低、精度高。机器学习任务中,我们希望最终能得到准确预测未知标签的样本、泛化能力强的模型。我们需要一整套方法及评价指标:评估方法:为保证客观地评估模型,对数据集进行的有效划分实验方法。性能指标:量化地度量模型效果的指标。2.离线与在线实验方法A/B Test是目前在线测试中最主要的方法。A/B Test是为同一个目标制定两个方案让一部分用户使用A方案,另一部分用户使用B方案,记录下用户的使用情况并进行评估AB Test实验流程:2.1、评估指标在离线评估中,经常使用准确率(Accuracy)、查准率(Precision)、召回率(Recall)、ROC、AUC、PRC等指标来评估模型。在线评估与离线评估所用的评价指标不同,一般使用一些商业评价指标,如用户生命周期值(Customer Lifetime value)、广告点击率(Click Through Rate)、用户流失率(Customer Churn Rate)等指标3、常见模型评估方法介绍3.1 留出法留出法直接将数据集D划分为两个互斥集合,其中一个集合为训练集S,另一个作为测试机T,即:训练集S具体划分为训练集和验证集,训练集构建模型,验证集对该模型进行参数择优,选择最优模型,测试机T测试最优模型的泛化能力。留出法数据划分的注意点:随机划分不一定能保证有效性,因为如果T中正好只取到某一种特殊类型数据,从而带来了额外的误差。此时处理方法要视具体情况而定,如当数据明显的分为有限类时,可以采用分层抽样方式选择测试数据,保证数据分布比例的平衡。单次划分不一定能得到合适的测试集,一般多次重复「划分 - 训练 - 测试求误差」的步骤,取误差的平均值。划分的验证集,太大或者太小都不合适,常用做法是选择1/5 - 1/3 左右数据当作验证集用于评估。3.2 K折交叉验证"交叉验证法"(cross validation)先将数据集D划分为k个大小相似的互斥子集:每个子集Di通过分层采样得到,然后用k-1个子集的并集作为训练集,余下的子集作为测试集;这样就获得k组训练/测试集,从而进行k次训练和测试,最后返回的是这k个测试结果的均值。通常把交叉验证法称为“k折交叉验证法”,k最常用的取值是10,此时称为10折交叉验证。如下图:数据量一般较小的时候,K设大一点;数据量大的时候,K可以设小一点。一般K=10。当k=m即样本总数时,叫做留一法。每次的测试集只有一个样本,要进行m次的训练和预测3.3 自助法(Bootstrap)数据量较少,很难通过已有的数据来估计数据的整体分布,Bootstrap 是一种用小样本估计总体值的一种非参数方法,在进化和生态学研究中应用十分广泛。Bootstrap通过有放回抽样生成大量的伪样本,通过对伪样本进行计算,获得统计量的分布,从而估计数据的整体分布。每次随机从D中挑出一个样本,将其拷贝放入训练集;然后再将该样本放回初始数据集中,重复执行m次后,得到包含m个样本的训练集D^’。数据集D中未出现在D^’中的所有样本作为测试集。即通过自助采样,初始数据集D中有约36.8%的样本未出现在采样数据集D^’中。适用于数据集较小、较难划分训练/测试集。但产生的训练集改变了初始数据集的分布,引入估计偏差。4、回归问题常用的评估指标回归类问题场景下,我们会得到连续值的预测结果,比对标准答案,我们有 MAE、MSE、RMSE 等评估指标(准则)可以衡量预测结果相对实际情况的偏离程度,它们的取值越小说明回归模型的预测越准,模型性能越好。4.1、平均绝对误差 MAE平均绝对误差(Mean Absolute Error,MAE),又叫平均绝对离差,是所有标签值与回归模型预测值的偏差的绝对值的平均。优点:直观地反映回归模型的预测值与实际值之间的偏差。准确地反映实际预测误差的大小。不会出现平均误差中误差符号不同而导致的正负相互抵消。缺点:不能反映预测的无偏性(估算的偏差就是估计值的期望与真实值的差值。无偏就要求估计值的期望就是真实值)。4.2、平均绝对百分误差 MAPE平均绝对百分误差(Mean Absolute Percentage Error,MAPE)是对 MAE 的一种改进,考虑了绝对误差相对真实值的比例。优点:考虑了预测值与真实值的误差。考虑了误差与真实值之间的比例。4.3、均方误差 MSEMAE虽能较好衡量回归模型的好坏,但是绝对值的存在导致函数不光滑,在某些点上不能求导。可以考虑将绝对值改为残差的平方,就得到了均方误差。均方误差(Mean Square Error,MSE)相对于平均绝对误差而言,均方误差求的是所有标签值与回归模型预测值的偏差的平方的平均。优点:准确地反映实际预测误差的大小。放大预测偏差较大的值。比较不同预测模型的稳定性。缺点:不能反映预测的无偏性。4.4、均方根误差 RMSE均方根误差(Root-Mean-Square Error,RMSE),也称标准误差,是在均方误差的基础上进行开方运算。RMSE会被用来衡量观测值同真值之间的偏差。5.分类问题常用的评估指标5.1、混淆矩阵很多评估指标可以基于混淆矩阵计算得到,如下图所示:5.2、Accuracy 精确率对于分类问题,精确率(Accuracy)指分类正确的样本数占样本总数的比例,是最常用的指标,可以总体上衡量一个预测的性能。一般情况(数据类别均衡)下,模型的精度越高,说明模型的效果越好。5.3、 Precision 查准率Precision (查准率),又称正确率、准确率,表示在模型识别为正类的样本中,真正为正类的样本所占的比例。一般情况下,查准率越高,说明模型的效果越好。宁愿漏掉,不可错杀:在识别垃圾邮件的场景中可能偏向这一种思路,因为不希望很多的正常邮件被误杀,这样会造成严重的困扰。因此,查准率(Precision)将是一个被侧重关心的指标。5.4、 Recall 查全率Recall (查全率),又称召回率,表示的是,模型正确识别出为正类的样本的数量占总的正类样本数量的比值。一般情况下,Recall 越高,说明有更多的正类样本被模型预测正确,模型的效果越好。宁愿错杀,不可漏掉:在金融风控领域大多偏向这种思路,希望系统能够筛选出所有有风险的行为或用户,然后交给人工鉴别,漏掉一个可能造成灾难性后果。因此,查全率(Recall)将是一个被侧重关心的指标。5.5、Fβ-Score 和 F1-Score理论上来说,Precision 和 Recall 都是越高越好,但更多时候它们两个是矛盾的,经常无法保证二者都很高。此时,引入一个新指标 ,用来综合考虑 Precision 与 Recall。• β=1时,Fβ−Score就是F1−Score,综合平等考虑 Precision 和 Recall 的评估指标,当 F1值较高时则说明模型性能较好。β<1时,更关注 Precision。β>1时,更关注 Recall。5.6、ROC使用 True Positive Rate(TPR,真正例率)和False Positive Rate(FPR,假正例率)两个指标来绘制 ROC 曲线。TPR、FPR公式:算法对样本进行分类时,都会有置信度,即表示该样本是正样本的概率。通过置信度可以对所有样本进行降序排序,再逐个样本地选择阈值,比如排在某个样本之前的都属于正例,该样本之后的都属于负例。每一个样本作为划分阈值时,都可以计算对应的 TPR 和 FPR,那么就可以绘制 ROC 曲线。ROC曲线(Receiver Operating Characteristic Curve)全称是「受试者工作特性曲线」。综合考虑了概率预测排序的质量,体现了学习器在不同任务下的「期望泛化性能」的好坏,反映了TPR和FPR随阈值的变化情况ROC曲线越接近左上角,表示该分类器的性能越好。也就是说模型在保证能够尽可能地准确识别小众样本的基础上,还保持一个较低的误判率,即不会因为要找出小众样本而将很多大众样本给误判。一般来说,如果ROC是光滑的,那么基本可以判断没有太大的overfitting。5.7、AUCROC曲线的确能在一定程度上反映模型的性能,但它并不是那么方便。ROC曲线的AUC值恰好就做到了这一点。AUC(Area Under ROC Curve)是 ROC 曲线下面积,其物理意义是,正样本的预测结果大于负样本的预测结果的概率,本质是AUC反应的是分类器对样本的排序能力。AUC值越大,就能够保证ROC曲线越靠近左上方。6、样本均衡与采样6.1、样本均衡问题很多算法都有一个基本假设,那就是数据分布是均匀的。当把这些算法直接应用于实际数据时,大多数情况下都无法取得理想的结果,因为实际数据往往分布得很不均匀,都会存在「长尾现象」多数样本数量多,信息量大,容易被模型充分学习,模型容易识别这类样本少数样本数量少,信息量少,模型没有充分学习到它们的特征,很难识别这类样本解决这一问题的基本思路是,让正负样本在训练过程中拥有相同的话语权(比如利用采样与加权等方法)。样本类别不均衡的情况下,最常见的处理方式是「数据采样」与「样本加权」6.2 数据采样1、欠采样 / 下采样欠采样技术是将数据从原始数据集中移除。从多数类集合中筛选样本集E。将这些样本从多数类集合中移除。2、过采样 / 上采样随机过采样:首先在少数类集合中随机选中一些少数类样本。然后通过复制所选样本生成样本集合 。将它们添加到少数类集合中来扩大原始数据集从而得到新的少数类集合。6.3 加权除了上采样和下采样这种采样方式以外,还可以通过加权的方式来解决数据不均衡问题,即对不同类别分错的代价不同,对于小众样本,如果分错了会造成更大的损失
搜不鸟了
机器学习-梯度提升决策树-05
1.GBDT算法GBDT(Gradient Boosting Decision Tree),全名叫梯度提升决策树,是一种迭代的决策树算法,又叫 MART(Multiple Additive Regression Tree),它通过构造一组弱的学习器(树),并把多颗决策树的结果累加起来作为最终的预测输出。该算法将决策树与集成思想进行了有效的结合。GBDT中的树是回归树(不是分类树),GBDT用来做回归预测,调整后也可以用于分类。1.1 应用场景1、用于自动挖掘有效特征、特征组合2、作为LR模型中的特征,提高CTR预估3、GBDT应用于淘宝的搜索及预测业务1.2 Boosting核心思想Boosting方法训练基分类器时采用串行的方式,各个基分类器之间有依赖。它的基本思路是将基分类器层层叠加,每一层在训练的时候,对前一层基分类器分错的样本,给予更高的权重。测试时,根据各层分类器的结果的加权得到最终结果。Bagging 与 Boosting 的串行训练方式不同,Bagging 方法在训练过程中,各基分类器之间无强依赖,可以进行并行训练。2、GBDT详解GBDT的原理所有弱分类器的结果相加等于预测值。每次都以当前预测为基准,下一个弱分类器去拟合误差函数对预测值的残差(预测值与真实值之间的误差)。GBDT的弱分类器使用的是树模型(cart)。如图是一个非常简单的帮助理解的示例,我们用 GBDT 去预测年龄:第一个弱分类器(第一棵树)预测一个年龄(如20岁),计算发现误差有10岁;第二棵树预测拟合残差,预测值 6,计算发现差距还有 4 岁;第三棵树继续预测拟合残差,预测值 3,发现差距只有 1 岁了;第四课树用 1 岁拟合剩下的残差,完成。最终,四棵树的结论加起来,得到30岁这个标注答案(实际工程实现里,GBDT 是计算负梯度,用负梯度近似残差)GBDT计算流程1、GBDT与负梯度近似残差回归任务下,GBDT在每一轮的迭代时对每个样本都会有一个预测值,此时的损失函数为均方差损失函数:损失函数的负梯度计算如下:「均方误差损失」时,每一次拟合的值就是(真实值-预测值),即残差。2、GBDT训练过程我们来借助1个简单的例子理解一下 GBDT 的训练过程。假定训练集只有4个人(A、B、C、D),他们的年龄分别是(14,16,24,26)。其中,A、B分别是高一和高三学生;C、D分别是应届毕业生和工作两年的员工。我们先看看用回归树来训练,得到的结果如下图所示:接下来改用 GBDT 来训练。由于样本数据少,我们限定叶子节点最多为2(即每棵树都只有一个分枝),并且限定树的棵树为2。 最终训练得到的结果如下图所示:上图中的树很好理解:A、B年龄较为相近,C、D年龄较为相近,被分为左右两支,每支用平均年龄作为预测值。我们计算残差(即「实际值」-「预测值」),所以 A 的残差 14-15=-1 。这里 A的「预测值」是指前面所有树预测结果累加的和,在当前情形下前序只有一棵树,所以直接是15 ,其他多树的复杂场景下需要累加计算作为 A 的预测值。上图中的树就是残差学习的过程了:把 A、B、C、D 的值换作残差 -1、1、-1、1,再构建一棵树学习,这棵树只有两个值 1 和 -1,直接分成两个节点:A、C 在左边,B、D在右边。这棵树学习残差,在我们当前这个简单的场景下,已经能保证预测值和实际值(上一轮残差)相等了。我们把这棵树的预测值累加到第一棵树上的预测结果上,就能得到真实年龄,这个简单例子中每个人都完美匹配,得到了真实的预测值。A:高一学生,购物较少,经常问学长问题,真实年龄 14 岁,预测年龄A=15-1=14B:高三学生,购物较少,经常被学弟提问,真实年龄 16 岁,预测年龄B=15+1=16C:应届毕业生,购物较多,经常问学长问题,真实年龄 24 岁,预测年龄C=25-1=24D:工作两年员工,购物较多,经常被学弟提问,真实年龄 26 岁,预测年龄D=25+1=26综上,GBDT 需要将多棵树的得分累加得到最终的预测得分,且每轮迭代,都是在现有树的基础上,增加一棵新的树去拟合前面树的预测值与真实值之间的残差。3.梯度提升 vs 梯度下降下面我们来对比一下「梯度提升」与「梯度下降」。这两种迭代优化算法,都是在每1轮迭代中,利用损失函数负梯度方向的信息,更新当前模型,只不过:梯度下降中,模型是以参数化形式表示,从而模型的更新等价于参数的更新。• 梯度提升中,模型并不需要进行参数化表示,而是直接定义在函数空间中,从而大大扩展了可以使用的模型种类。3.GBDT优缺点1. 优点预测阶段,因为每棵树的结构都已确定,计算速度快。适用稠密数据,泛化能力和表达能力都不错,数据科学竞赛榜首常见模型。可解释性不错,鲁棒性亦可,能够自动发现特征间的高阶关系。2. 缺点GBDT 在高维稀疏的数据集上,效率较差,且效果表现不如 SVM 或神经网络。适合数值型特征,在 NLP 或文本特征上表现弱。训练过程无法并行,工程加速只能体现在单颗树构建过程中。4.随机森林 vs GBDT1. 相同点都是集成模型,由多棵树组构成,最终的结果都是由多棵树一起决定。RF 和 GBDT 在使用 CART 树时,可以是分类树或者回归树。2. 不同点训练过程中,随机森林的树可以并行生成,而 GBDT 只能串行生成。随机森林的结果是多数表决表决的,而 GBDT 则是多棵树累加之。随机森林对异常值不敏感,而 GBDT 对异常值比较敏感。随机森林降低模型的方差,而 GBDT 是降低模型的偏差。5、代码演示-GBDT数据集 随机生成sklearn可视化决策树插件 Download:https://graphviz.org/download/决策树插件安装文档:https://blog.csdn.net/u012744245/article/details/103360769## 使用Sklearn调用GBDT模型拟合数据并可视化
import numpy as np
import pydotplus
import os
from sklearn.ensemble import GradientBoostingRegressor
os.environ["PATH"]+=os.pathsep+'C:/Program Files/Graphviz/bin/' #指定路径
import sklearn
sklearn.__version__
X = np.arange(1, 11).reshape(-1, 1)
y = np.array([5.16, 4.73, 5.95, 6.42, 6.88, 7.15, 8.95, 8.71, 9.50, 9.15])
gbdt = GradientBoostingRegressor(max_depth=4, criterion ='mse').fit(X, y)
from IPython.display import Image
from pydotplus import graph_from_dot_data
from sklearn.tree import export_graphviz
## 拟合训练5棵树
sub_tree = gbdt.estimators_[4, 0]
dot_data = export_graphviz(sub_tree, out_file=None, filled=True, rounded=True, special_characters=True, precision=2)
graph = pydotplus.graph_from_dot_data(dot_data)
Image(graph.create_png())
搜不鸟了
机器学习-最大期望算法-EM-13
1、EM概念EM 算法,全称 Expectation Maximization Algorithm。期望最大算法是一种无监督分类算法,用于含有隐变量(Hidden Variable)的概率参数模型的最大似然估计或极大后验概率估计。EM 算法的核心思想非常简单,分为两步:Expection-Step 和 Maximization-Step。E-Step 主要通过观察数据和现有模型来估计参数,然后用这个估计的参数值来计算似然函数的期望值;而 M-Step 是寻找似然函数最大化时对应的参数。由于算法会保证在每次迭代之后似然函数都会增加,所以函数最终会收敛。2、算法原理通过不断迭代这个E-M步骤,P、Q就能收敛。3、案例假设有两枚硬币 A 和 B,他们的随机抛掷的结果如下图所示:我们很容易估计出两枚硬币抛出正面的概率:现在我们加入隐变量,抹去每轮投掷的硬币标记:3.1 计算从期望的角度来看,对于第一轮抛掷,使用硬币 A 的概率是 0.45,使用硬币 B 的概率是 0.55。同理其他轮。这一步我们实际上是估计出了 Z 的概率分布,这部就是 E-Step。结合硬币 A 的概率和上一张投掷结果,我们利用期望可以求出硬币 A 和硬币 B 的贡献。以第二轮硬币 A 为例子,计算方式为:于是我们可以得到:这步就对应了 M-Step,重新估计出了参数值。如此反复迭代,我们就可以算出最终的参数值。上述讲解对应下图:
搜不鸟了
量化交易-特征分析-3
数据概况1、首先我们需要了解一下数据的情况candles = load_my_pair_history(data_location,'ETH_USDT-5m-futures.json')
print("Loaded " + str(len(candles)) + f" rows of data for {pair} from {data_location}")
candles.head() #展示部分数据从上图可以直观的看到我们除日期外,还有5个与币价相关的字段2、接着我们加入用于分析的相关指标from freqtrade.resolvers import StrategyResolverfrom freqtrade.data.dataprovider import DataProviderstrategy = StrategyResolver.load_strategy(config)strategy.dp = DataProvider(config, None, None)
# Generate buy/sell signals using strategydf = strategy.analyze_ticker(candles, {'pair': pair})df.tail()检查一下数据的完整性:df.info()我们会发现有些指标存在缺失值,比如:sar、tema等,行数不足9572.(ps:其实没有问题,这个跟统计口径相关,后续抽空再讲)再看看数据的分布的情况:df.describe()这里展示了每个指标的平均值、标准差、25%分位、50%分位、最大、最小值等。获得这些指标有助于我们下一步的分析工作特征关系挖掘1、通过统计学的方法,我可以快速拿到特征(指标)与目标值之间的关系随机森林回归模型#随机森林回归模型model_rf = RandomForestRegressor(n_estimators=50,random_state=315).fit(train_X, train_y)
perm = PermutationImportance(model_rf, random_state=1).fit(val_X, val_y)
eli5.show_weights(perm, feature_names = val_X.columns.tolist(),top=30)我们可以得到tema指标的权重是最高的线性回归模型:# Linear Regression
model_lr = LinearRegression().fit(train_X, train_y)
perm = PermutationImportance(model_lr, random_state=1).fit(val_X, val_y)
eli5.show_weights(perm, feature_names = val_X.columns.tolist(),top=30)通过线性回归模型,我们接着筛选出一批相关性较高的指标:bb_middleband、bb_lowerband、bb_upperband、macd、tema等那么以上指标的相关性具体在哪,我们需要通过图表来分析。import matplotlib.pyplot as plt
# 折线图
y_close = df['close'][:1000]
y_tema= df['tema'][:1000]
y_middleband = df['bb_middleband'][:1000]
y_lowerband = df['bb_lowerband'][:1000]
y_upperband = df['bb_upperband'][:1000]
x = df['date'][:1000]
plt.figure(figsize=(20, 10))
plt.plot(x,y_close,'',label="close")
plt.plot(x,y_lowerband,'',label="low")
plt.plot(x,y_upperband,'',label="up")
plt.plot(x,y_tema,'',label="tema")
plt.xlabel('date')
plt.ylabel('close')
plt.title('ETH/USDT')
plt.legend()
plt.show()通过上面的图表,我们可以明显看到tema、upper、low与收盘价的走势几乎保持一致,也就是说我们可以利用这些指标作为我们买入和卖出的信号2、我们也需要利用一些强度信号,作为信息补充。这里推荐使用rsi上图是RSI和币价的走势图,我们会发现RSI的高峰几乎都对应上了币价的短期高点,RSI的谷峰对应了币价的低点。特征相关性热力图那么特征之间的关系我们也需要了解分析一下,我们通过heatmap来绘制热力图:df_coor=df.iloc[:1000,1:22].corr()
df_coor.head()
plt.subplots(figsize=(10,10),dpi=1080,facecolor='w')# 设置画布大小,分辨率,和底色
fig=sns.heatmap(df_coor,annot=True, vmax=1, square=True, cmap="Blues", fmt='.2g')#annot为热力图上显示数据;fmt='.2g'为数据保留两位有效数字,square呈现正方形,vmax最大值为1通过上面的热力图我们得到4组比较强的关系特征组合:1、bb_xxx 与 close的强关系2、sar 与 close 的强关系3、tema 与 bb_xxx 指标的强关系4、rsi 与 bb_percent指标的强关系OK,至此我们从27个指标中初步筛选了一批与币价具有相关性的指标。下一步我们需要利用这些筛选出来的指标作为我们量化交易策略的指标,具体使用方式会在下一节中再详解。
搜不鸟了
量化交易-如何评估赚钱的策略-7
本文主要介绍如何评估策略优劣,以及如何结合策略进行仓位管理。我们如果想通过策略获取收益,那么策略本身获取的收益必须要大于策略的亏损。赚钱策略的核心:不在于交易胜率,而在于交易盈亏比(It doesn't matter how often, but how much!)如果一个策略在10次交易中赚取0.1$,但在一次交易中亏损1$,单看交易胜率确实很高,但策略最终亏损。概念介绍来看一道题:1、一笔交易有80%的概率损失100$,20%的概率赚取200$
2、一笔交易有100%的概率损失30$问:我们选择策略1还是策略2?接着我们需要先了解几个概念:Win rate(W)、 Lose rate(L),Risk Reward Ratio(R)、Expectancy(E)Win rate and Lose rate如果一笔交易的最终余额(扣除交易手续费、初始成本) 0,则为一笔盈利交易;如果一笔交易的最终余额(扣除交易手续费、初始成本) 0,则为一笔亏损交易;那么 我们可以得到W(交易胜率):同理,我们可以得到L(交易败率):Risk Reward Ratio(R)风险回报率(risk reward ratio)是在给定投资额的情况下,策略的预期收益除以策略的预期亏损的比率。Example:假如一个新币 dycoin 今天是 10.0$, 最近市场利好,可能近期 dycoin 可以涨到15.0$一枚。当然新币dycoin上市也存在风险,如果项目方跑路,那么dycoin很有可能归零。我们目前手上持有100$,预计分十次投资,每次投资10$。基于这个例子,我们先计算一下我们的预期收益公式:因此预期收益为:当然如果dycoin由于项目方跑路,那么我们的亏损就是100$.实际我们在策略执行过程中会设置止损,假设是15%,也就是dycoin跌到8.5$时,我们终止交易。那么我们预期亏损公式:同理我们的预期亏损额:因此 Risk Reward Ratio(R):也就意味着我们每投入1$,预期收益可以获得3.33$。注:上面只考虑了单次交易、单次价格波动,对于一个策略执行而言,可能涉及上千笔交易,上千次价格波动,这种情况下如何计算风险回报率,后面再写,其实思路是一样的Expectancy (E)通过结合 Win Rate(W) 和 风险回报率(R)来得到我们的交易期望值(E),交易期望值表示在一笔投资交易中我们预期可以获得的期望收益值。Example:假设有一个策略,win rate W=0.28, risk reward ratio R = 5,可以理解为我们做5次投资,有28%的概率获得利润。因此 Expectancy (E):因此 E 可以理解为 我们每损失1$,可以赚取1.68$的收益我们来看一下如下表格,选择哪个策略是最优策略:大家可以根据前面的知识点做一个最有策略排序,文末公布答案。仓位管理以上的内容,我们应该了解了如何合理评估一个策略的优劣,接着需要跟实际执行的仓位结合起来。策略线上运行期间仓位控制的主要影响因素:风险资本投入率(Allowed risk per trade)止损率(stoploss)每笔交易投入资本:Allowed capital at risk = (Capital available_percentage) X (Allowed risk per trade)
Plain textCopy止损率是通过历史K线数据计算得出(Hyperopt);结合止损率可以得出我们每笔交易的投入仓位:Position size = (Allowed capital at risk) / StoplossExample:假设我们钱包中有10个ETH,且资本投入率(Capital available_percentage)50%,10∗0.5=510∗0.5=5ETH;每笔交易风险资本投入率1%(可以理解为亏多少钱)。因此我们每笔交易投入的资本为:5∗0.01=0.055∗0.01=0.05ETH。Trade 1: 策略在BNB/ETH市场中发现买入信号,根据历史数据得出BNB/ETH的stoploss为2%。因此在BNB/ETH交易对中,我们预估的投入仓位(position size): 0.05/0.02=2.50.05/0.02=2.5ETH ,因此策略在BNB/ETH交易对中投入了2.5ETHTrade 2:策略接着在DOT/ETH交易对中发现买入信号,此时Trade 1还未关单,DOT/ETH的stoploss为4%,因此我们可以得出在DOT/ETH中我们投入仓位为: 0.05/0.04=1.250.05/0.04=1.25ETH。Trade 3:策略此时又在BTC/ETH中发现了一个买入信号,同理我们可以计算出此交易对的投入仓位:0.05/0.01=50.05/0.01=5ETH,且Trade1和Trade2还未关单,因此在BTC/ETH交易对中我们能投入的资本:5−1.25−2.5=1.255−1.25−2.5=1.25ETHTrade 4:策略在BNB/ETH交易对检测到了卖出信号,当策略卖出退出后,最终获得利润1ETH,因此我们钱包总额为11ETH,可以投入的风险资本更新为11*0.5=5.5ETH总结:本文主要介绍如何评估策略的优劣,以及策略在实际执行过程中,面对多个交易对时,如何进行仓位管理。
搜不鸟了
机器学习-聚类算法(clustering)-14
1、聚类算法详解聚类(Clustering)是最常见的无监督学习算法,它指的是按照某个特定标准(如距离)把一个数据集分割成不同的类或簇,使得同一个簇内的数据对象的相似性尽可能大,同时不在同一个簇中的数据对象的差异性也尽可能地大聚类算法做的事情,就是对无标签的数据,基于数据分布进行分群分组,使得相似的数据尽量落在同一个簇内我们先对比区分一下聚类和分类:聚类是一种无监督学习,而分类是一种有监督的学习。聚类只需要人工指定相似度的标准和类别数就可以,而分类需要从训练集学习分类的方法。1.1案例将数据点按照距离远近分成3类:2、主流聚类算法主流的聚类算法可以分成两类:划分聚类(Partitioning Clustering)和层次聚类(Hierarchical Clustering)划分聚类算法会给出一系列扁平结构的簇(分开的几个类),它们之间没有任何显式的结构来表明彼此的关联性。常见算法有 K-Means / K-Medoids、Gaussian Mixture Model (高斯混合模型)、Spectral Clustering(谱聚类)、Centroid-based Clustering等。层次聚类会输出一个具有层次结构的簇集合,因此能够比划分聚类输出的无结构簇集合提供更丰富的信息。层次聚类可以认为是是嵌套的划分聚类。常见算法有 Single-linkage、Complete-linkage、Connectivity-based Clustering等。后文我们会重点展开讲一下 K-Means 算法、Single-linkage 算法和 Complete-linkage 算法2.1 K-Means聚类算法聚类算法要把 n个数据点按照分布分成 K类(很多算法的K是人为提前设定的)。我们希望通过聚类算法得到 K个中心点,以及每个数据点属于哪个中心点的划分中心点可以通过迭代算法来找到,满足条件:所有的数据点到聚类中心的距离之和是最小的。中心点确定后,每个数据点属于离它最近的中心点。在进入「如何寻找中心点」这个核心问题之前,我们先解决几个小问题:1、数据点到中心点的距离:我们一般选择几何距离,就是L2距离的平方。2、中心点是否唯一:对于多个中心点的情况,全局最优是一个相当难的问题。理论上存在一个全局最优解,但是不一定能找到。既然全局最优解不好找,那我们退而求其次,看能不能找到局部最优解3、聚类结果如何表示: 采用空间分割的方式,将空间分割成多个多边形,每个多边形对应一个 cluster中心。2.2 K-Means算法步骤K-Means 采用 EM算法 迭代确定中心点。流程分两步:① 更新中心点:初始化的时候以随机取点作为起始点;迭代过程中,取同一类的所有数据点的重心(或质心)作为新中心点。② 分配数据点:把所有的数据点分配到离它最近的中心点。重复上面的两个步骤,一直到中心点不再改变为止。过程如图所示:• 左侧Assignments:一开始随机选取三个点,作为三个类的中心,基于其它点和这三个中心点的距离分配簇;每一类重新计算和分配中心。• 右侧Refitted Means:根据新的中心点,重新分配所有的数据点(原来属于绿色中心点的1个点,此次迭代后变成属于红色中心点了)。下图的示例展示了 K-Means 动态迭代收敛的过程:图(a)上有一群散落的点,我们设定簇数K=2 。图(b)为随机找2个点作为中心初始化后,第一次分类的结果。可以看到,红蓝分界线在这群点的中央穿过。这显然有问题,不过没关系,算法继续往下走。对红蓝两类分别计算它们的中心。图(c)可以看到,一个落在左下方这一团里,另一个落在右上方那一团里。以新的中心点进行第二次分类。图(d)的分界线就基本是已经可以把两团分开了。图(f)、(g)显示后续重复计算你「中心点-分类数据点」的过程已经收敛,数据点分配基本不动了,聚类完成。2.3.K-Means缺点与改进我们将 K-Means 算法的一些缺点总结如下:缺点1:中心点是所有同一类数据点的质心,所以聚类中心点可能不属于数据集的样本点。缺点2:计算距离时我们用的是L2距离的平方。对离群点很敏感,噪声(Noisy Data)和离群点(Outlier)会把中心点拉偏,甚至改变分割线的位置。2.4、K-Medoids算法(K-Means改进)针对 K-Means 算法的缺点改进得到了 K-Medoids 算法:(1)限制聚类中心点必须来自数据点。求中心点的计算方法,由原来的直接计算重心,变成计算完重心后,在重心附近找一个数据点作为新的中心点。K-Medoids 重拟合步骤比直接求平均的 K-Means 要复杂一些。(2)为避免平方计算对离群点的敏感,把平方变成绝对值。总结来说,K-Medoids 算法的迭代过程与 K-Means 是一致的,不同点如下所示:起始点不是随机点,而是任意选择数据集中的点。距离使用L1距离,而不是L2距离。新的中心点,也不是同类所有点的重心,而是同一类别所有数据点中,离其它点最近的点。下图是 K-Means 和 K-Medoids 两个算法的一个系统对比:4.层次聚类算法4.1)层次聚类 vs 划分聚类层次聚类最后得到的是一个树状层次化结构。从层次化聚类转换为划分聚类很简单,在层次化聚类的某一层进行切割,就得到1个划分聚类。如下图所示:4.2)Single-Linkage 算法这个算法是构造一棵二叉树,用叶节点代表数据,而二叉树的每一个内部节点代表一个聚类。如图所示:这是一个从下而上的聚类。这棵树是先有叶子,顺着叶子逐渐长树枝,树枝越长越大一直到树根。4.3)Complete-Linkage算法与 Single-Linkage 算法相似,Complete-Linkage 的迭代思路是一样的,不同的是在合并类时,Single-Linkage 是用两个类中距离最小的两个点作为类之间的距离,而 Complete-Linkage 恰恰相反,用距离最远的两个数据点之间的距离作为这两个类之间的距离总的来说,层次聚类的计算复杂度是�(�3)O(n3)级别,算是很高的了。可以用优先队列的数据结构对算法加速,加速后能减低到的级别.5.DB-SCAN算法5.1)DB-SCAN算法在前面的内容中我们介绍了划分聚类和层次聚类的算法,接下来我们学习另外一个聚类算法:DB-SCAN 算法。DB-SCAN 是一个基于密度的聚类。如下图中这样不规则形态的点,如果用 K-Means,效果不会很好。而通过 DB-SCAN 就可以很好地把在同一密度区域的点聚在一类中。5.2)DB-SCAN算法的关键概念5.3)DB-SCAN算法伪代码这个过程用直白的语言描述就是:对于一个数据集,先规定最少点密度 MinPts 和半径范围。先找出核心对象:如果在半径范围内点密度大于 MinPts,则这个点是核心对象。把所有的核心对象放到一个集合中。从这个核心对象集合中,随机找一个核心对象,判断其它的数据点与它是否密度直达,如果是,则归入聚类簇中。继续判断其它点与聚类簇中的点是否密度直达,直到把所有的点都检查完毕,这时候归入聚类簇中的所有点是一个密度聚类。6、代码演示-K-means&DB-Scan数据集 irissklearnDBScan
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.cluster import DBSCAN
%matplotlib inline
X1, y1=datasets.make_circles(n_samples=5000, factor=.6,
noise=.05)
X2, y2 = datasets.make_blobs(n_samples=1000, n_features=2, centers=[[1.2,1.2]], cluster_std=[[.1]],
random_state=9)
X = np.concatenate((X1, X2))
#展示样本数据分布
plt.scatter(X[:, 0], X[:, 1], marker='o')
plt.show()
#eps和min_samples 需要进行调参
y_pred = DBSCAN(eps = 0.1, min_samples = 10).fit_predict(X)
#分类结果
plt.scatter(X[:, 0], X[:, 1], c=y_pred)
plt.show()
PythonCopy
#k-means
from sklearn import datasets
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
iris = datasets.load_iris()
X, y = iris.data, iris.target
data = X[:,[1,3]] # 为了便于可视化,只取两个维度
plt.scatter(data[:,0],data[:,1]);
# Generate some data
X, y = make_blobs(n_samples=400, centers=4, cluster_std=0.60, random_state=0)
# kmeans clustering
kmeans = KMeans(4, random_state=0)
kmeans.fit(X) # 训练模型
labels = kmeans.predict(X) # 预测分类
plt.scatter(X[:, 0], X[:, 1], c=labels, s=40, cmap='viridis')
plt.show()
PythonCopy
搜不鸟了
机器学习-决策树-03
决策树:决策树(decision tree)是一个树结构(可以是二叉树或非二叉树)。其每个非叶节点表示一个特征属性上的测试,每个分支代表这个特征属性在某个值域上的输出,而每个叶节点存放一个类别。使用决策树进行决策的过程就是从根节点开始,测试待分类项中相应的特征属性,并按照其值选择输出分支,直到到达叶子节点,将叶子节点存放的类别作为决策结果。构建树的原则我们构建一棵决策树的基本想法就是,我们希望决策树每个叶子节点包含的样本尽可能属于同一个类别,即结点的“纯度”越来越高决策树划分选择的方法根据构建树的原则来看,即使得每个结点的纯度尽可能小,那么我们需要一些指标评价“纯度”这个概念。信息熵和基尼指数是两个常用的指标。决策树算法:1、熵(Entropy)信息熵(information entropy)是度量样本集合纯度的常用指标;假定当前样本集合D中第k类样本所占的比例为 pk(k=1,2,…,|Y|) ,则D的信息熵为:Ent(D)的值越小,D的纯度越高(约定:若p=0则plog2p=0)2、信息增益(Information Gain)一般而言,信息增益越大,则意味着用属性a来进行划分所获得的纯度提升越大:ID3就是以信息增益为准则来选择划分属性的3、增益率实际上,信息增益对可取值数目较多的属性有所偏好(如编号,在西瓜集中若以编号为划分属性,则其信息增益最大),为减少由于偏好而带来的不利影响,C4.5算法使用增益率(gain ratio)来选择最优划分属性其中:称为属性a的固有值(intrinsic value),属性a的可能数目越多,则IV(a)的值通常越大然而,增益率准则对可取值数目较少的属性有所偏好,C4.5采用的是先从候选划分属性中找出信息增益高于平均水平的属性,再从中选择增益率最高的4、基尼指数CART(Classification and Regression Tree)使用基尼指数(Gini index)来选择划分属性,数据集的纯度可用基尼值来度量属性a的基尼指数定义为:在属性集合A中寻找:CART决策树使用基尼指数作为属性划分的标准5、剪枝处理剪枝(pruning)是决策树学习算法对付过拟合的主要手段,基本策略有预剪枝(prepruning)和后剪枝(post-pruning)预剪枝:在决策树的生成过程中,对每个节点在划分前先进行估计,若当前节点的划分不能带来泛化性能提升则停止划分后剪枝:先生成一个完整的树,然后自底向上对非叶节点考察,若将该节点对应的子数替换为叶节点能提升泛化性能则替换5.1 预剪枝预剪枝的关键在于是否继续进行划分:在上面的西瓜的例子当中,如果我们使用脐部进行划分,那么图中②、③和⑥分别包含编号为{1 , 2 , 3 , 14} 、{6 , 7 , 15 , 17} 和{10 , 16} 的训练样例,因此这3个结点分别被标记为叶结点“好瓜”、"好瓜"、"坏瓜"此时,验证集中编号为{4 , 5 , 8 ,11, 12} 的样例被分类正确,验证集精度为5/7 x 100% = 71.4% > 42.9%。于是,用"脐部"进行划分得以确定。预剪枝使决策树的很多分支都没有展开,不仅降低了过拟合的风险,还显著减少了训练时间和测试时间,但是可能会引起过拟合5.2 后剪枝后剪枝通常比预剪枝保留更多的分值,一般情况下,后剪枝欠拟合风险很小,泛化性能优于预剪枝,但其训练时间比未剪枝和预剪枝都要大得多连续与缺失值连续值处理在C4.5决策树算法当中,使用二分法对连续的数值进行处理:我们可以考察包含n-1个元素的候选划分点集合我们将每个区间的中位点作为候选划分点,然后我们使用想离散值属性一样来考察这些划分点,选取最优的划分点进行样本集合的划分,例如:对上图表格当中的例子而言,设置密度为:根据Gain的计算公式可以得到属性”密度“的信息增益位0.262,对应于划分点0.381。同时按照之前的离散值的计算方法,计算离散属性的信息增益的值:Gain(D ,色泽) = 0.109; Gain(D ,根蒂) = 0.143;Gain(D ,敲声) = 0.141; Gain(D ,纹理) = 0.381;Gain(D ,脐部) = 0.289; Gain(D , 触感) = 0.006;Gain(D ,密度) = 0.262; Gain(D ,含糖率) = 0.349.可以发现纹理的信息增益是最大的,所以我们选择”纹理“作为根节点作为划分属性,然后每个结点划分过程递归进行,最终生成如图所示的决策树:缺失值的处理一些数据由于敏感等原因,部分数据可能会出现缺失的情况,例如下面的情况:在决策树的C4.5算法当中,我们使用了没有缺失值的样本子集进行树的构建。以上述表格为例子举例,没有缺失值的样例子集包含编号为{2,3,4,6,7,8,9,10,11,12,14,15,16,17}的14个样例(总共有17个样例)。那么相应的信息熵为:其分别在”色泽“属性上取值为”青绿“,”乌黑“以及”浅白“的样本子集,那么有:因此在样本子集上,其信息增益为:那么在样本集上的”色泽“的信息增益为,要乘以其没有缺失的样例数量除以全部的样例数量:在上述文章提及的变量为,其中每个样本的权重 wk为1:决策树算法优缺点优点:决策树具有高度可解释性;需要很少的数据预处理;适用于低延迟应用。劣势:1. 很可能对噪声数据产生过拟合。决策树越深,由噪声产生过拟合的可能性就越大。一种解决方案是对决策树进行剪枝。代码演示-Decision Tree数据集 irissklearn可视化决策树插件 Download:https://graphviz.org/download/决策树插件安装文档:https://blog.csdn.net/u012744245/article/details/103360769# -*- coding: utf-8 -*-
"""
Created on Wed Jul 31 16:51:08 2019
@author: 86182
"""
from sklearn.datasets import load_iris
from sklearn import tree
import pydotplus
#用于划分训练集与测试集
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
#加载数据
iris = load_iris()
#划分训练集与测试集
(training_inputs, testing_inputs, training_classes, testing_classes)
=train_test_split(iris.data, iris.target,test_size=0.4, random_state=1)
# 构建模型
clf = tree.DecisionTreeClassifier()
clf = clf.fit(training_inputs, training_classes)
#测试值预测
y_predict = clf.predict(testing_inputs)
#预测值和测试值打分
score = classification_report(testing_classes, y_predict)
print(score)
# 保存模型
with open("iris.dot", 'w') as f:
f = tree.export_graphviz(clf, out_file=f)
# 画图,保存到pdf文件
# 设置图像参数
dot_data = tree.export_graphviz(clf, out_file=None,
feature_names=iris.feature_names,
class_names=iris.target_names,
filled=True, rounded=True,
special_characters=True)
graph = pydotplus.graph_from_dot_data(dot_data)
# 保存图像到pdf文件
graph.write_pdf("irsi.pdf")
搜不鸟了
机器学习-逻辑回归-02
一、Logistic回归定义logistic回归又称logistic回归分析,是一种广义的线性回归分析模型,逻辑回归的原理是用逻辑函数把线性回归的结果(-∞,∞)映射到(0,1)逻辑回归是分类算法,大家都熟悉线性回归,一般形式是Y=aX+b,y的取值范围是[-∞, +∞]如何实现分类:把Y的结果带入一个非线性变换的Sigmoid函数中,即可得到S取值范围(0,1),可以看成是一个概率分布应用场景预测一个用户是否点击特定的商品判断用户的性别预测用户是否会购买给定的品类判断一条评论是正面的还是负面的逻辑函数表达式:函数图:函数中z无论取什么值,其结果都在[0,-1]的区间内,我们假设分类的阈值是0.5,那么超过0.5的归为A分类,低于0.5的归为B分类,阈值是可以自己设定的。二、逻辑函数的导函数逻辑函数的表达式为:导函数为:可做如下转换:逻辑函数是一个连续且任意阶可导的函数三、如何求解逻辑回归中的参数?1、极大似然函数举个例子;如果我们已经积累了大量的违约客户和正常客户的样本数据,利用极大似然函数由果溯因,估计出使得目前结果的可能性最大参数(系数)θ,有了参数我们就可以求任何一个客户违约的概率了。我们假设信贷违约的后验概率:相应的可以得到客户不违约的概率:如果令:违约的后验概率可以写成:不违约的后验概率可以写成:对于某一个客户,我们采集到了样本数据(x,y)。对于这个样本,他的标签是y的概率可以定义成:其中y∈{0,1}。当y=0时,上式为不违约的后验概率,当y=1时,上式为违约的后验概率。现在我们有m个客户的观测样本:将每一个样本发生的概率相乘,就是这个合成在一起得到的合事件发生的总概率(利用概率中的乘法公式),即为似然函数,可以写成:其中θ为待求参数。注:我们总是希望出现目前结果的可能性最大,所以想要得到极大化似然函数对应的参数θ。为便于求解,我们引入不改变函数单调性的对数函数ln,把连乘变成加法,得到对数似然函数:至此,可以用梯度上升法求解对数似然函数,求出使得目前结果的可能性最大的参数θ。2、最小化损失函数方式二我们基于对数似然函数构造损失函数,用梯度下降法求出使得损失最小对应的参数θ损失函数需求满足两个条件:1、损失函数 可以衡量 模型的好坏2、参数可导,便于求解最优解,也就是损失函数的最小值结合上式中的极大似然函数,如果取整个数据集上的平均对数似然损失,我们可以得到:其中J(θ)为损失函数,由对数似然函数前面添加负号取平均得到。即在逻辑回归模型中,最大化似然函数和最小化损失函数实际上是等价的(求最大化对数似然函数对应的参数θ和求最小化平均对数似然损失对应的参数θ是一致的),即:四. 逻辑回归常用的求解方法梯度求解基本步骤如下:选择下降方向(梯度方向,∇J(θ))选择步长,更新参数 θi=θi−1−αi∇J(θi−1)重复以上两步直到满足终止条件4.1 一阶方法梯度下降、随机梯度下降、mini 随机梯度下降降法。随机梯度下降不但速度上比原始梯度下降要快,局部最优化问题时可以一定程度上抑制局部最优解的发生4.2 二阶方法:牛顿法、拟牛顿法:牛顿法其实就是通过切线与x轴的交点不断更新切线的位置,直到达到曲线与x轴的交点得到方程解。在实际应用中我们因为常常要求解凸优化问题,也就是要求解函数一阶导数为0的位置,而牛顿法恰好可以给这种问题提供解决方法牛顿法首先选择一个点作为起始点,并进行一次二阶泰勒展开得到导数为0的点进行一个更新,直到达到要求,这时牛顿法也就成了二阶求解问题,比一阶方法更快拟牛顿法: 不用二阶偏导而是构造出Hessian矩阵的近似正定对称矩阵的方法称为拟牛顿法。拟牛顿法的思路就是用一个特别的表达形式来模拟Hessian矩阵或者是他的逆使得表达式满足拟牛顿条件。主要有DFP法(逼近Hession的逆)、BFGS(直接逼近Hession矩阵)、 L-BFGS(可以减少BFGS所需的存储空间)。五.可以进行多分类吗?方式一:1.将类型class1看作正样本,其他类型全部看作负样本,然后我们就可以得到样本标记类型为该类型的概率p1。2.然后再将另外类型class2看作正样本,其他类型全部看作负样本,同理得到p2。3.以此循环方式二:1.多元逻辑回归 Softmax更合适一些。Softmax 回归是直接对逻辑回归在多分类的推广,模型通过 softmax 函数来对概率建模六.逻辑回归有什么优点LR能以概率的形式输出结果,而非只是0,1判定。LR的可解释性强,可控度高训练快,feature engineering容易出效果因为结果是概率,可以做ranking model七. 逻辑回归有哪些应用CTR预估/推荐系统的learning to rank/各种分类场景。某搜索引擎厂的广告CTR预估基线版是LR。某电商搜索排序/广告CTR预估基线版是LR。某电商的购物搭配推荐用了大量LR。某新闻app排序基线是LR八. 逻辑回归为什么要对特征进行离散化非线性!逻辑回归属于广义线性模型,表达能力受限;单变量离散化为N个后,每个变量有单独的权重,相当于为模型引入了非线性,能够提升模型表达能力,加大拟合; 离散特征的增加和减少都很容易,易于模型的快速迭代;速度快!稀疏向量内积乘法运算速度快,计算结果方便存储,容易扩展;鲁棒性!离散化后的特征对异常数据有很强的鲁棒性:比如一个特征是年龄>30是1,否则0。如果特征没有离散化,一个异常数据“年龄300岁”会给模型造成很大的干扰;方便交叉与特征组合:离散化后可以进行特征交叉,由M+N个变量变为M*N个变量,进一步引入非线性,提升表达能力;稳定性:特征离散化后,模型会更稳定,比如如果对用户年龄离散化,20-30作为一个区间,不会因为一个用户年龄长了一岁就变成一个完全不同的人。当然处于区间相邻处的样本会刚好相反,所以怎么划分区间是门学问;简化模型:特征离散化以后,起到了简化了模型,降低了模型过拟合的风险。九、代码演示-LogisticRegression数据集 irissklearn## logistcs regresion
# encoding: utf-8
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
# 1.加载数据
iris = datasets.load_iris()
X = iris.data[:, :3] #取特质
Y = iris.target
# 2.拆分测试集、训练集。
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=100)
# 3.标准化特征值 min-max / starnder deviion (平均值 + 方差=1)
sc = StandardScaler()
sc.fit(X_train)
X_train_std = sc.transform(X_train)
X_test_std = sc.transform(X_test)
# 4. 训练逻辑回归模型
logreg = linear_model.LogisticRegression(C=1e5,max_iter=100, solver='liblinear',multi_class='ovr')
logreg.fit(X_train, Y_train)
# 5. 预测
##多元逻辑回归 Softmax 回归更合适一些。Softmax 回归是直接对逻辑回归在多分类的推广,相应的模型也可以叫做多元逻辑回归(Multinomial Logistic Regression)。
#模型通过 softmax 函数来对概率建模
y_pred= logreg.predict_proba(X_test_std)
acc = logreg.score(X_test_std,Y_test)
print('Train/Test split results:')
print("准确率为 %2.3f" % acc)
搜不鸟了
量化交易-策略效果跟踪-9
开仓详情开仓交易对:SHIB/USDT;开仓价:0.00001081止损价:0.00001029(-4.80%)仓位:28.4USDT策略开仓截图:关仓详情关仓时间:6月6号 16:36持仓时间:2天1小时31分(2971.2min)开仓价格:0.00001081关仓价格:0.00001130利润:4.36%策略关仓截图:策略汇总情况:具体我们看一下K线图:简要说明:1、整体趋势是一个下跌行情2、策略抓住了一个相对低点并买入3、策略抓住了短期内行情反弹相对高点卖出4、策略卖出后币价开始下跌这波时机踩点还相对比较精确,说明策略对币价这阶段运行情况比较适应,可以持续观察。什么时候我们需要关停策略?1、策略在最近一段时间的收益率明显下降甚至为负2、行情在最近一段时间发生较大变化3、历史经验量化交易的天生优势就是摒弃人性的弱点,不会因短期行情波动而做出冲动交易,更没有“杀涨追跌”的情绪,也不会被外部人为环境干扰。
搜不鸟了
机器学习-回归树-06
1、决策树回归算法核心思想1.1、决策树结构回顾决策树的典型结构如下图所示:主流的决策树算法有:ID3:基于信息增益来选择分裂属性(每步选择信息增益最大的属性作为分裂节点,树可能是多叉的)。C4.5:基于信息增益率来选择分裂属性(每步选择信息增益率最大的属性作为分裂节点,树可能是多叉的)。CART:基于基尼系数来构建决策树(每步要求基尼系数最小,树是二叉的)。其中:CART树全称Classification And Regression Tree,即可以用于分类,也可以用于回归,这里指的回归树就是 CART 树,ID3和C4.5不能用于回归问题。具体如下图:2、回归树算法原理回归树的构建核心问题:如何选择划分点?如何决定树中叶节点的输出值?假设X和Y分别为输入和输出变量,并且Y是连续变量,给定训练数据集D,考虑如何生成回归树。一个回归树对应着输入空间(即特征空间)的一个划分以及在划分的单元上的输出值。假设已将输入空间划分为M个单元 R1,R2,…RM ,并且在每个单元 Rm上有一个固定的输出值 Cm ,于是回归树模型可以表示为:当输入空间的划分确定时,可以用平方误差:表示回归树对于训练数据的预测误差;用平方误差最小的准则求解每个单元上的最优输出值。易知,单元Rm上的 Cm的最优值 C^m 是Rm上的所有输入实例 Xi对应的输出 Yi 的均值,即:2.1、问题1:怎样对输入空间进行划分?即如何选择划分点?CART回归树采用启发式的递归二分方法对输入空间进行划分,「自顶向下的贪婪式递归方案」,指的是每一次的划分,只考虑当前最优,而不回头考虑之前的划分选择第j个变量 X^j 和它取的值s,作为切分变量(splitting variable)和切分点(splitting point),并定义两个区域:然后寻找最优切分变量j和最优切分点s。具体地,求解:对固定输入变量j可以找到最优切分点s。2.2、问题2:如何决定树中叶节点的输出值?用选定的最优切分变量j和最优切分点s划分区域并决定相应的输出值:和遍历所有输入变量,找到最优的切分变量j,构成一个对(j, s)。依此将输入空间划分为两个区域。接着,对每个区域重复上述划分过程,直到满足停止条件为止。这样就生成一颗回归树。这样的回归树通常称为最小二乘回归树(least squares regression tree)。 如果已将输入空间划分为M个区域R1,R2,…Rm,并且在每个区域Rm上有一个固定的输出值C^m,于是回归树模型可以表示为:2.3 算法流程3、回归树案例本示例来源于李航著的《统计学习方法》第5章决策树习题中的5.2题。已知如图3所示的训练数据,试用平方误差损失准则生成一个二叉回归树找最优切分变量j和最优切分点s的方法为:其中:和例如,取s=1。此时 R1={1} , R2={2,3,4,5,6,7,8,9,10} ,这两个区域的输出值分别为:C1=4.50C2=1/9(4.75+4.91+5.34+5.80+7.05+7.90+8.23+8.70+9.00)=6.85根据上面的计算方法,可以得到下表:把 C1,C2 的值代入到均方差中,如下:C(1)=0+{(4.75−6.85)^2+(4.91−6.85)^2+(5.34−6.85)^2+(5.80−6.85)^2+(7.05−6.85)^2+(7.90−6.85)^2+(8.23−6.85)^2+(8.70−6.85)^2+(9.00−6.85)^2}=22.65同理,可以获得下表:显然取s=5时,m(s)最小。因此,第一个最优切分变量为j=5.8、最优切分点为s=5。3.1、用选定的(j,s)划分区域,并决定输出值:两个划分的区域分别是: R1={1,2,3,4,5},R2={6,7,8,9,10} 。输出值用公式:和得 C1=5.06,C2=8.183.2、对两个子区域继续调用算法流程中的步骤(1),(2)对 R1 继续进行划分:取切分点分别为:[1, 2, 3, 4, 5],则各个区域的输出值c如下表:计算m(s):s=3时,m(3)最小。之后的递归过程同上,我就不在赘述啦!最后,如下图所示给出完整的二叉回归树:4.、关于回归树的若干问题4.1、CART实现分类树与回归树的区别?CART分类树是一种二分递归分割的技术,分割方法采用基于最小距离的基尼指数估计函数,将当前的样本集分为两个子样本集,使得生成的的每个非叶子节点都有两个分支。因此,CART算法生成的决策树是结构简洁的二叉树。CART分类树是针对目标变量是离散型变量,通过二叉树将数据进行分割成离散类的方法。而回归树则是针对目标变量是连续性的变量,通过选取最优分割特征的某个值,然后数据根据大于或者小于这个值进行划分进行树分裂最终生成回归树。4.2、树形结构为什么不需要归一化?因为数值缩放不影响分裂点位置,对树模型的结构不造成影响。 按照特征值进行排序的,排序的顺序不变,那么所属的分支以及分裂点就不会有不同。而且,树模型是不能进行梯度下降的,因为构建树模型(回归树)寻找最优点时是通过寻找最优分裂点完成的,因此树模型是阶跃的,阶跃点是不可导的,并且求导没意义,也就不需要归一化。4.3、既然树形结构(如决策树、RF)不需要归一化,那为何非树形结构比如Adaboost、SVM、LR、KNN、K-Means之类则需要归一化?对于线性模型,特征值差别很大时,运用梯度下降的时候,损失等高线是椭圆形,需要进行多次迭代才能到达最优点。 但是如果进行了归一化,那么等高线就是圆形的,促使SGD往原点迭代,从而导致需要的迭代次数较少。4.4、决策树如何剪枝?决策树的剪枝基本策略有预剪枝 (Pre-Pruning)和后剪枝 (Post-Pruning)。预剪枝:其中的核心思想就是,在每一次实际对结点进行进一步划分之前,先采用验证集的数据来验证如果划分是否能提高划分的准确性。如果不能,就把结点标记为叶结点并退出进一步划分;如果可以就继续递归生成节点。后剪枝:后剪枝则是先从训练集生成一颗完整的决策树,然后自底向上地对非叶结点进行考察,若将该结点对应的子树替换为叶结点能带来泛化性能提升,则将该子树替换为叶结点。在第3节回归树的示例中,我没有对生成的二叉回归树进行剪枝,感兴趣的同学可以自己尝试实现预剪枝和后剪枝,来避免生成的二叉回归树过拟合。5、代码演示-Regression Tree数据集 irissklearnimport numpy as np
import matplotlib.pyplot as plt
from sklearn.tree import DecisionTreeRegressor
from sklearn import linear_model
# Data set
x = np.array(list(range(1, 11))).reshape(-1, 1)
y = np.array([4.50, 4.75, 4.91, 5.34, 5.80, 7.05, 7.90, 8.23, 8.70, 9.00]).ravel()
# Fit regression model
model1 = DecisionTreeRegressor(max_depth=1)
model2 = DecisionTreeRegressor(max_depth=3)
model3 = linear_model.LinearRegression()
model1.fit(x, y)
model2.fit(x, y)
model3.fit(x, y)
# Predict
X_test = np.arange(0.0, 10.0, 0.01)[:, np.newaxis]
y_1 = model1.predict(X_test)
y_2 = model2.predict(X_test)
y_3 = model3.predict(X_test)
# Plot the results
plt.figure()
plt.scatter(x, y, s=20, edgecolor="black",
c="darkorange", label="data")
plt.plot(X_test, y_1, color="cornflowerblue",
label="max_depth=1", linewidth=2)
plt.plot(X_test, y_2, color="yellowgreen", label="max_depth=3", linewidth=2)
plt.plot(X_test, y_3, color='red', label='liner regression', linewidth=2)
plt.xlabel("data")
plt.ylabel("target")
plt.title("Decision Tree Regression")
plt.legend()
plt.show()
搜不鸟了
机器学习-随机森林-04
1.什么是随机森林Random Forest(随机森林)是一种基于树模型的Bagging的优化版本,一棵树的生成肯定还是不如多棵树,因此就有了随机森林,解决决策树泛化能力弱的特点。(可以理解成三个臭皮匠顶过诸葛亮)而同一批数据,用同样的算法只能产生一棵树,这时Bagging策略可以帮助我们产生不同的数据集。Bagging策略来源于bootstrap aggregation:从样本集(假设样本集N个数据点)中随机重采样选出N个样本(有放回的采样,样本数据点个数仍然不变为N),在所有样本上,对这n个样本建立分类器(ID3\C4.5\CART\SVM\LOGISTIC),重复以上两步m次,获得m个分类器,最后根据这m个分类器的投票结果,决定数据属于哪一类。如下图所示:随机森林产生的原因:单个决策树对训练数据往往具有较好的分类效果,但是对于未知新样本分类效果较差。为了提升模型对未知样本的分类效果,所以将多个简单的决策树组合起来,形成泛化能力更强的模型——随机森林。2、什么是Bootstrapping&Bagging2.1、BootstrappingBootstrapping算法,指的就是利用有限的样本资料经由多次有放回的重复抽样。如:在原样本中有放回的抽样,抽取n次。每抽一次形成一个新的样本,重复操作,形成很多新样本。1、有放回采样2、强调偏差3、串行执行,速度较慢4、可以提升泛化性能2.2 Bagging思想Bagging是bootstrap aggregating。思想就是从总体样本当中随机取一部分样本进行训练(均匀采样),通过多次这样的结果,进行投票获取平均值作为结果输出,这就极大可能的避免了不好的样本数据,从而提高准确度。因为有些是不好的样本,相当于噪声,模型学入噪声后会使准确度不高。1、均匀采样2、强调方差3、并行生成,速度快4、可以提升泛化性能bagging举个例子:假设有1000个样本,如果按照以前的思维,是直接把这1000个样本拿来训练,但现在不一样,先抽取800个样本来进行训练,假如噪声点是这800个样本以外的样本点,就很有效的避开了。重复以上操作,提高模型输出的平均值。3、随机森林影响因素3.1 随机森林分类效果的影响因素森林中任意两棵树的相关性:相关性越大,错误率越大;森林中每棵树的分类能力:每棵树的分类能力越强,整个森林的错误率越低。减小特征选择个数m,树的相关性和分类能力也会相应的降低;增大m,两者也会随之增大。所以关键问题是如何选择最优的m(或者是范围),这也是随机森林唯一的一个参数。3.2 学习器组合可能会带来三大好处:由于学习任务的假设空间往往很大,可能有很多假设再训练集上达到相同性能,结合多学习器会提升泛化性能学习算法往往会陷入局部极小,经过多次结合,可降低陷入糟糕局部极小点的风险某些学习任务的真实假设可能不在当前学习算法所考虑的假设空间中,通过结合多个学习器会使假设空间扩大,可能会学得更好的近似4 随机森林优缺点4.1 优点:RF简单,容易实现,计算开销小,性能强大。它的扰动不仅来自于样本扰动,还来自于属性扰动,这使得它的泛化性能进一步上升。4.2 缺点:它在训练和预测时都比较慢,而且如果需要区分的类别很多时,随机森林的表现并不会很好。5、代码演示-Random Forest数据集 irissklearn#!/usr/bin/env python
# coding: utf-8
# ### 导入随面森林的相关库文件.
from sklearn.ensemble import RandomForestClassifier # 导入随机森林的包
# from sklearn.model_selection import train_test_split # 这个用于后台数据的分割
from sklearn.preprocessing import StandardScaler # 数据的标准化
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
#导入iris数据
# * Sepal.Length(花萼长度),单位是cm;
# * Sepal.Width(花萼宽度),单位是cm;
# * Petal.Length(花瓣长度),单位是cm;
# * Petal.Width(花瓣宽度),单位是cm;
# * 种类:Iris Setosa(山鸢尾)、Iris Versicolour(杂色鸢尾),以及Iris Virginica(维吉尼亚鸢尾) 共三种
from sklearn import datasets # 导入iris自带数据库文件
iris_data = datasets.load_iris()
iris_feature = iris_data.data[:151:2]
iris_target = iris_data.target[:151:2]
# 数据标准化
scaler = StandardScaler() # 标准化转换
# Compute the mean and std to be used for later scaling.
scaler.fit(iris_feature) # 训练标准化对象
print(type(iris_target))
iris_feature = scaler.transform(iris_feature) # 转换数据集
feature_train, feature_test, target_train, target_test = train_test_split(iris_feature, iris_target,test_size=0.3, random_state=0)
# 数据训练
clf = RandomForestClassifier(n_estimators=30)
clf.fit(feature_train, target_train)
# predict_results = clf.predict(feature_test)
#预测
target_feature = scaler.transform(feature_test) # 转换数据集
y_predict=clf.predict(target_feature)
#预测值和测试值打分
score = classification_report(target_test, y_predict)
print(score)
搜不鸟了
量化交易实战与策略优化
从"开篇介绍量化交易"到"策略效果跟踪",本课程深入研究量化交易的各个环节。学员将学到EasyStrategy的实际应用、特征分析、策略改进、超参数优化,以及如何通过可视化辅助和评估策略的盈利效果。通过年复合收益率超过180%的策略案例,帮助学员更好地理解和实践量化交易。适合有志于深入研究和优化量化策略的投资者和交易者。
搜不鸟了
机器学习算法实战
从"神经网络基础"到"K近邻算法实践",本课程深入探讨机器学习领域的关键算法。学员将逐步学习神经网络、反向传播、线性回归、逻辑回归、决策树、随机森林、XGBoost、LightGBM、支持向量机等算法的原理和应用。