首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >基于支持向量回归的股市数据预测

基于支持向量回归的股市数据预测
EN

Code Review用户
提问于 2020-02-04 13:19:45
回答 1查看 83关注 0票数 2

我自己编写了这个支持向量回归(SVR),它遵循日记中的一些公式(参见这里,或这里 (非英语))。日志和下面的代码使用的损失函数是平均绝对百分比误差(MAPE)。

我需要让它运行得更快,因为我将使用这个函数1600次进行评估。如果我使用此代码,它将运行几天,甚至一周运行一次。

我怎样才能让它跑得更快?我是Python的初学者(第一次用Python编写代码)。

我使用的股票市场数据示例:TLKM.CSV

您可以在这里看到代码:SVRpython.py或更低版本:

代码语言:javascript
运行
复制
import csv
import pandas as pd
import numpy as np
import math
import matplotlib.pyplot as plt
import random as Rand
from pandas import DataFrame
from sklearn.model_selection import train_test_split
import pdb
import time
nstart=time.process_time()
#   pdb.set_trace()
# import IPython as IP

data = pd.read_csv("TLKM.csv")

def Distancetrain(d3, d2, d1):
    d=len(d3.index)
    harray=[]
    for i in range(d):
        harray.clear()
        for j in range(d):
            harray.append(((d3.iloc[i]-d3.iloc[j])**2) + ((d2.iloc[i]-d2.iloc[j])**2) + ((d1.iloc[i]-d1.iloc[j])**2))
        if i < 1:
            distancedata=pd.DataFrame(harray)
        else:
            distancedata[i]=harray
    print("distance train")
    print(time.process_time()-nstart)
    return distancedata

def Distancetest(d3train, d2train, d1train, d3test, d2test, d1test):
    dtrain=len(d3train.index)
    dtest=len(d3test.index)
    harray=[]
    for i in range(dtrain):
        harray.clear()
        for j in range(dtest):
            harray.append(((d3test.iloc[j]-d3train.iloc[i])**2) + ((d2test.iloc[j]-d2train.iloc[i])**2) + ((d1test.iloc[j]-d1train.iloc[i])**2))
        if i < 1:
            distancedata=pd.DataFrame(harray)
        else:
            distancedata[i]=harray
    print("distance test")
    print(time.process_time()-nstart)
    return distancedata


def Hessian(dfdistance, sigma, lamda):
    d=len(dfdistance.index)
    col=len(dfdistance.columns)
    hes = np.array([], dtype=np.float64).reshape(0,col)
    tampung = [[0] * col]
    sig2= 2*(sigma**2)
    lam2=lamda**2
    for i in range(d):
        for j in range(col):
            tampung[0][j]=np.exp(-1*((dfdistance.iloc[i][j])/(sig2))) + (lam2)
        hes=np.vstack([hes, tampung])
    dfhessian=pd.DataFrame(hes)
    print("hessian")
    print(time.process_time()-nstart)
    return dfhessian

def Seqlearn(y, dfhessian, gamma, eps, c, itermaxsvr):
    d=len(dfhessian.index)
    a = [[0] * d]
    a_s = [[0] * d]
    la = [[0] * d]
    la_s = [[0] * d]
    E = np.array([], dtype=np.float64).reshape(0,d)
    Etemp = [[0] * d]
    da_s = np.array([], dtype=np.float64).reshape(0,d)
    da = np.array([], dtype=np.float64).reshape(0,d)
    dat_s = [[0] * d]
    dat = [[0] * d]
    tempas = [[0] * d]
    tempa = [[0] * d]
    for i in range(itermaxsvr):
        for j in range(d):
            Rijhelp=0
            for k in range(d):
                Rijhelp = Rijhelp + ((a_s[i][k] - a[i][k])*(dfhessian.iloc[j][k]))
            Etemp[0][j]= y.iloc[j] - Rijhelp
        E=np.vstack([E, Etemp])
        for l in range(d):
            dat_s[0][l]=min(max(gamma*(E[i][l] - eps), -1*(a_s[i][l])), (c - a_s[i][l]))
            dat[0][l]=min(max(gamma*(-(E[i][l]) - eps), -1*(a[i][l])), (c - a[i][l]))
            tempas[0][l]= a_s[i][l] + dat_s[0][l]
            tempa[0][l]= a[i][l] + dat[0][l]
        da_s=np.vstack([da_s, dat_s])
        da=np.vstack([da, dat])

        a=np.vstack([a, tempa])
        a_s=np.vstack([a_s, tempas])
        la=tempa
        la_s=tempas
#       (|da| 0):
            dataxm=np.vstack([dataxm, datax])
    print("predict")
    print(time.process_time()-nstart)
    return dataxm

def Normalization(datain, closemax, closemin):
    dataout=(datain - closemin)/(closemax - closemin)
    return dataout

def SVRf(df, closemax, closemin, c, lamda, eps, sigma, gamma, itermaxsvr):
    result = df.assign(Day_3 = Normalization(df.Day_3, closemax, closemin), Day_2=Normalization(df.Day_2, closemax, closemin), Day_1=Normalization(df.Day_1, closemax, closemin), Actual=Normalization(df.Actual, closemax, closemin))

    X_train, X_test, y_train, y_test, d3_train, d3_test, d2_train, d2_test, d1_train, d1_test, date_train, date_test = train_test_split(result['Index'], result['Actual'], result['Day_3'], result['Day_2'], result['Day_1'], result['Date'], train_size=0.9, test_size=0.1, shuffle=False)

    distancetrain=Distancetrain(d3_train, d2_train, d1_train)
    mhessian=Hessian(distancetrain, sigma, lamda)
    a, a_s = Seqlearn(y_train, mhessian, gamma, eps, c, itermaxsvr)
    distancetest=Distancetest(d3_train, d2_train, d1_train, d3_test, d2_test, d1_test)
    testhessian=Hessian(distancetest, sigma, lamda)
    predict = Predictf(a, a_s, testhessian)
    hasilpre=pd.DataFrame()
    tgltest = date_test
    tgltest.reset_index(drop=True, inplace=True)
    hasilpre['Tanggal'] = tgltest
    hasilpre['Close'] = predict
    deresult = hasilpre.assign(Close=(hasilpre.Close * (closemax - closemin) + closemin))
    n=len(y_test)
    aktualtest = (y_test * (closemax - closemin)) + closemin
    aktualtest.reset_index(inplace=True, drop=True)
    dpredict = pd.Series(deresult['Close'], index=deresult.index)
    hasil = aktualtest - dpredict
    hasil1 = (hasil / aktualtest).abs()
    suma = hasil1.sum()
    mape = (1/n) * suma
    print("MAPE")
    print(mape)
    fitness = 1/(1+mape)
    print(fitness)
    return fitness, mape, hasilpre

Closemax=data['Close'].max()
Closemin=data['Close'].min()
print(Closemax)
print(Closemin)
day3 = data['Close'][0:((-1)-2)]
day2 = data['Close'][1:((-1)-1)]
day2.index = day2.index - 1
day1 = data['Close'][2:((-1)-0)]
day1.index = day1.index - 2
dayact = data['Close'][3:]
dayact.index = dayact.index - 3
dateact = data['Tanggal'][3:]
dateact.index = dateact.index - 3
mydata = pd.DataFrame({'Index':data['Index'][0:((-1)-2)], 'Date':dateact, 'Day_3':day3, 'Day_2':day2, 'Day_1':day1, 'Actual':dayact})
print("data proses",time.process_time()-nstart)

Lamda=0.09
C=200
Eps=0.0013
Sigma=0.11
Gamma=0.004
Itermaxsvr=1000
SVRf(mydata, Closemax, Closemin, C, Lamda, Eps, Sigma, Gamma, Itermaxsvr)

nstop=time.process_time()
print(nstop-nstart)
EN

回答 1

Code Review用户

回答已采纳

发布于 2020-02-05 23:12:00

首先也是最重要的:去给自己买一个带有自动格式化程序的IDE,例如PyCharm、带有Python插件代码 (仅举几个例子,关于代码审查的另一篇文章中有更长的列表)。这将帮助您建立一致的代码样式,这反过来又使您更容易阅读和检查代码。Python附带了一个“正式”Python代码样式指南 (又名PEP 8),这些工具极大地帮助编写了看起来专业的代码。需要特别注意的一些方面:

  • 在作业中使用=前后的空白,例如distancedata = pd.DataFrame(harray)
  • 变量和函数的lower_case_with_underscore名称,例如def distances_train(d3, d2, d1): ...
  • 为代码编写"""documentation"""

一旦您了解了这一点,我强烈建议您看看Jake的一些讨论:

还有一个强烈推荐的读取器,可以使用相同的人在Python:Python数据科学手册中进行数值计算。你要花些时间来解决这个问题,但我保证这是值得的。

我所链接的材料的核心是:循环在普通Python中是缓慢的,所以通常最好尽量避免它们。

我将演示使用Distancetrain

def距离序列(d3,d2,d1):d= len(d3.index) harray = [] in range(d):harray.clear()表示范围(D)中的j:harray.append(d3.iloc-d3.iloc)**2)+ ((d2.iloc-d2.iloc)**2) +((d1.iloc-d1.iloc)**2)远程数据= pd.DataFrame( harray ):distancedata =harray返回距离数据

使这个功能慢下来的东西:

那么,如何才能改善这一点呢?由于远程计算在各种机器学习应用中都是一项非常常见的任务,因此在枕骨C45模块中有很好的库支持。你已经在使用朗皮,熊猫和滑雪,所以有一个很大的机会,枕木也是可用的。

查看上面链接的模块文档,显示了两个非常方便的函数:pdistcdistpdist基本上等同于Distancetrain应该做的事情,当考虑对Distancetest的改进时,cdist将变得非常方便。

通过这个函数,Distancetrain变得非常容易实现:

代码语言:javascript
运行
复制
def as_column(series):
    """Reshapes a pandas series to a numpy column vector"""
    return series.to_numpy(copy=False).reshape((-1, 1))


def distances_train(d3, d2, d1):
    # pdist requires the input to have a shape of (n_samples, n_dimensions)
    np_data = np.concatenate((as_column(d3), as_column(d2), as_column(d1)), axis=1)
    # squareform is used to get the full distance matrix from the half triangle I talked about earlier
    return pd.DataFrame(squareform(pdist(np_data, "sqeuclidean")))

所有这些重塑、连接和转换回数据文件基本上都是不必要的。我只保留它们,以便输出与原始代码兼容。您可以使用np.allclose(arr1, arr2)亲自查看结果是否确实是相同的。

以前必须由Python解释器执行的循环现在在底层库实现中执行。数值Python库通常是用C编写的,因此(在大多数情况下)比普通Python代码编写循环要快得多。

非正式的时间安排产生了以下结果(平均超过10次):

代码语言:javascript
运行
复制
original:  15.3467 s
new:        0.0031 s

差不多快了5000倍!

您可以以相同的方式重写代码的其他部分。只是需要一段时间才能习惯于从更大的数组和矩阵操作的角度来考虑这个问题。要达到这个目的,一种经过尝试和测试的方法是重写部分代码,同时保留旧代码以检查结果是否匹配。有时他们没有,但这不应该阻止你进一步调查它。通常情况下,重写的版本可能是正确的,因为没有复杂的循环等等,它更容易和简单。

也许还可以看看南巴,一种用于Python代码的即时编译器。这有时可以显著加快循环速度(例如,请参阅这里 )。numba并不完全支持您在Python或numpy中所能做的一切,因此实现可能需要一些调整才能正确地使用它。

当然,概要分析也是这一过程中的关键,并在评论中提到过。Python的内置cProfile模块对此非常有用。timeit还可用于可靠地测量较小代码段的执行时间。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/236646

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档