随机森林——回归预测股票数据的Python实例

在做项目时要用随机森林,查资料发现大多数都是用随机森林做分类,很少见到有回归的。虽然分类随机森林和回归随机森林代码实现相差不大,但是对于新手小白来说,如果有比较完整的代码直接学习可以节省很多时间,这是我写这篇文章的原因。

随机森林我就不介绍了,其他地方介绍一搜一大堆。

这篇文章关注的是如何用python实现回归随机森林。分为随机森林构建随机森林预测两部分

 

 

 

 

随机森林构建——

  • 随机森林主要的参数有树的棵树、特征的个数和树的最大深度,在mydata定义参数
  • #自定义参数
    def mydata():
        trees=10 #CART回归树的个数
        n_features=6 #特征个数
        max_depth=20 #树的最大深度
        return trees,n_features,max_depth
    

     

  • 读入数据,我用的股票数据是csv格式,将文件名和路径名分开写,方便有需要时将整个文件夹的文件逐个读出
#读入数据 这样路径和文件名分开写,方便以后将整个文件夹的数据导入进来。
def loadCsvDataSet(fileName='E:\\Anaconda3\\mydata\\data'):
    csv_path=os.path.join(fileName,"AMCX.csv")
    df=pd.read_csv(csv_path)
    #print(df.values)
    return df.values

 

 

  • 把数据集划分为训练数据和测试数据。我这里以2018年10月1日为分界线,10月1日以前为训练数据,以后为测试数据。
    
    #把dataset划分成训练数据和测试数据
    def split_train_test_data(dataSet):
        #第五列是adj close
        #即DataSet中取出feature列的值大于value的行,赋值给mat0,
        X_train=dataSet[np.nonzero(dataSet[:,0]<'2018-10-01')[0],:]
        X_test=dataSet[np.nonzero(dataSet[:,0]>'2018-10-01')[0],:]
        y_train=X_train[:,5]
        y_test=X_test[:,5]
        return X_train,X_test,y_train,y_test
                

     

     

  • 分裂数据集。把数据集分成两份
#把dataset划分成训练数据和测试数据
def split_train_test_data(dataSet):
    #第五列是adj close
    #即DataSet中取出feature列的值大于value的行,赋值给mat0,
    X_train=dataSet[np.nonzero(dataSet[:,0]<'2018-10-01')[0],:]
    X_test=dataSet[np.nonzero(dataSet[:,0]>'2018-10-01')[0],:]
    y_train=X_train[:,5]
    y_test=X_test[:,5]
    return X_train,X_test,y_train,y_test
  • 计算方差
#计算方差
def regErr(dataSet):
    #第五列是adj close
    return np.var(dataSet[:,5])*shape(dataSet)[0]
  • 计算平均值

#计算平均值
def regLeaf(dataSet):
    #第五列是adj close
    return np.mean(dataSet[:,5])
  • 选取分割的最优特征

#选取任意的n个特征,在这n个特征中,选取分割时的最优特征
#对每个特征值:
#  将数据集切分成两份
#  计算切分的误差
#  如果当前误差小于当前最小误差,那么将当前切分设定为最佳切分并更新最小误差,返回最佳切分的特征和阈值
#用shape[1]求出dataSet的列数,初始化index bestS和best_feature,bestValue
#S中存储着计算方差
def chooseBestSplit(dataSet,n_features):
    #随机森林不需要进行剪枝
    f=dataSet.shape[1]#shape[0]是指dataset的行数,估计1是指dataset的列数
    index=[]
    bestS=inf
    best_feature,bestValue=0,0
    S=regErr(dataSet)#回归用于计算方差
    for i in range(n_features):
        #从dataset的列数f的范围内有放回地取n_features个数,放到index集合里
        index.append(np.random.randint(f)) #index里存储着所有取出来的行数集合
    #尝试index次分割,每次分割的特征是feature列
    for feature in index:
        for splitVal in set(dataSet[:,feature]):#set是无序无重复的集合,即把dataSet里的数据去除重复值,遍历dataSet里feature列中不重复的数值,逐个数尝试,有没有哪个数用于分割是最优的(最优的意思是:划分后得到的两部分内部区别最小,即类内方差最小)
            #这个binSplitDataSet是上面定义的用于把数据集分为两份的函数
            mat0,mat1=binSplitDataSet(dataSet,feature,splitVal) 
            newS=regErr(mat0)+regErr(mat1)#regErr是求方差
            if bestS>newS:#如果新的news比最优的s小,就把数据更新
                bestfeature=feature
                #splitVal是在feature列下不同的值的数字之一,是切分数据的value
                bestValue=splitVal
                bestS=newS
    #print(bestValue)
    #printf(bestfeature)
    #if(S-bestS)<0.0000001:#如果误差不大就退出 #设置一个可以接受的误差精度,有这个没这么准确,因此我选择去除,大家可以在自己的项目对比要不要这几句话
        #print(regLeaf(dataSet))
        #return None,regLeaf(dataSet) #regLeaf计算dataSet的平均值
    #mat0,mat1=binSplitDataSet(dataSet,bestfeature,bestValue) 
    if(shape(mat0)[0]<10)or(shape(mat1)[0]<10):11
        #print(regLeaf(dataSet))
        return None,regLeaf(dataSet)
    return bestfeature,bestValue

  • 使用递归实现树

#实现树 这里使用递归
#首先调用chooseBestSplit得到返回值bestfeature和bestValue
#然后建立左右子树
#如果深度到指定深度,就返回剩余dataSet的平均值。
#retTree是一个字典,有'bestFeature' 'bestVal' 'right'和'left'
#返回retree
def createTree(dataSet,n_features,max_depth):#min_size是啥啊
    bestfeature,bestValue=chooseBestSplit(dataSet,n_features)
    if bestfeature==None:
        #print(bestValue)
        return bestValue
    retTree={} #retTree中存储着一泼CART回归树
    max_depth-=1
    if max_depth<0: #控制树的深度
        return regLeaf(dataSet) #regLeaf是算平均值的函数
    retTree['bestFeature']=bestfeature
    retTree['bestVal']=bestValue
    lSet,rSet=binSplitDataSet(dataSet,bestfeature,bestValue)
    retTree['right']=createTree(rSet,n_features,max_depth)
    retTree['left']=createTree(lSet,n_features,max_depth)
    return retTree

  • 构建森林

#创建n棵树
#最后将X_train调用createTree存储到Trees中。
#返回Trees.Tress里存储的就是n课树
def RandomForest(dataSet,ops):#这个n应该就是树的个数
    #dataSet=get_Datasets()
    Trees=[]
    for i in range(ops[0]):
        Trees.append((createTree(X_train,ops[1],ops[2]))) #构件训练数据的树
    return Trees

随机森林预测——

  • 森林构建完后是预测。使用递归对单个样本预测
#预测单个数据样本 #这里也用递归 

#先判断树是不是一个字典,如果不是就到达结束递归的条件,返回tree转化成float的值
#如果是一个字典:继续
#如果data中,tree的bestFeature为下标的数值大于tree的bestVal
    #判断左树是否是float类型,是就返回tree的左树
    #否则就从左树继续递归
#否则
    #判断右树是否是float类型,是就返回tree的右树
    #不是float类型就从树的右树进行递归
def TreeForecast(tree,data):
    if not isinstance(tree,dict):#isinstance是判断tree是否是一个字典类型,
        #print(type(tree))
        #print(float(tree))
        return float(tree)
    if data[tree['bestFeature']]>tree['bestVal']:
        if type(tree['left'])=='float':
            return tree['left']
        else:
            return TreeForecast(tree['left'],data)
    else:
        if type(tree['right'])=='float':
            return tree['right']
        else:
            return TreeForecast(tree['right'],data)
  • 使用单棵树预测,在单棵树里调用单个样本预测的函数

#单棵树预测测试集 调用TreeForecast 单个数据集预测样本
#创建一个n行1列的浮点型的数组
#数组里的每一行都用TreeForecast单个数据集预测,赋值给yhat相应列
def createForeCast(tree,dataSet):
    n=len(dataSet)
    #np.mat将数据转换成浮点型
    yhat=np.mat(zeros((n,1)))#创建一个m行1列的浮点型数组
    for i in range(n):
        yhat[i,0]=TreeForecast(tree,dataSet[i,:])
        #print(yhat[i,0])
    return yhat
  • 使用随机森林预测,在函数里调用单棵树预测的函数
#随机森林预测
#遍历每棵树进行预测,取所有树预测出的数据的平均值为预测值
def Predict(Trees,dataSet):
    n=len(dataSet)
    yhat=np.mat(zeros((n,1))) #创造一个n行1列的初始化为0的浮点型数组
    for tree in Trees: #trees里面有n棵树,用每棵树都预测一次  yhat中存储着每棵树的预测数值
        yhat+=createForeCast(tree,dataSet)#createForecast返回的是一个数组
    yhat/=len(Trees)#求出每个数除以树棵树的平均值
    return yhat

实现逻辑:

  1. 调用loadCsvDataSet读入股票数据,通过mydata获取设定的参数(决策树的棵数,特征数和深度)。用split_train_test_data把数据得到训练数据X_train和y_train,测试数据X_test 和y_test。
  2. 使用X_train调用RandomForest创建森林。RandomForest里调用createTree创建每棵树。每棵树的创建都是先调用chooseBestSplit进行最优特征分割,然后在其左右子节点递归调用自身。
  3. 使用X_test调用Predict使用创建的森林进行预测。Predict是遍历所有CART回归树调用createForeCast,在createForecast里将X_test里的所有数据逐行调用treeForecast使用单棵树预测,将所有CART回归树预测到的数取平均数,得到最终的预测值。

 

#明天补充几张图简单讲解一下随机森林实现过程和原理吧

如果这篇文章对您有帮助,麻烦点个赞告诉我,谢谢!不胜感激~

 

参考文章:

https://blog.csdn.net/jiede1/article/details/78245597

https://cloud.tencent.com/developer/article/1043093

https://blog.csdn.net/zwzen1/article/details/79176038

https://book.douban.com/subject/24703171/《机器学习实战》Peter Harrington著

 

  • 56
    点赞
  • 302
    收藏
    觉得还不错? 一键收藏
  • 27
    评论
随机森林是一种常用的机器学习算法,可以用于预测股市风险。它是一种集成学习方法,通过构建多个决策树来进行预测,并综合这些决策树的结果得出最终的预测。 在预测股市风险方面,随机森林可以通过以下步骤进行: 1. 数据准备:首先,需要准备用于训练模型的数据。这些数据可以包括与股市相关的各种指标和因素,如历史股价、市盈率、成交量等。 2. 特征选择:根据你认为对股市风险有影响的因素,从准备好的数据中选择合适的特征。这个过程可以结合领域知识和特征选择算法来进行。 3. 数据拆分:将数据集分为训练集和测试集。训练集用于构建随机森林模型,而测试集用于评估模型的性能。 4. 模型训练:使用训练集中的数据来构建随机森林模型。随机森林算法会同时使用数据的随机子集和随机特征子集来构建多个决策树模型。 5. 模型预测:使用训练好的随机森林模型来进行预测。对于每个测试样本,随机森林会将其输入所有构建的决策树模型中,并综合它们的结果来得出最终的预测。 6. 模型评估:使用测试集中的真实标签与模型预测的结果进行比较,评估模型的性能。常用的评估指标包括准确率、精确率、召回率等。 需要注意的是,股市风险是一个复杂的问题,受多种因素影响,并且股市具有一定的不确定性。因此,随机森林预测股市风险可能只是其中的一种方法,需要结合其他指标和方法来进行综合分析和决策。同时,模型的性能也需要不断优化和验证,以确保其预测能力的准确性和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 27
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值