我是一个机器学习的新手(不是数学家),我通过视频和书籍自学机器学习。我对朴素贝叶斯、支持向量机、决策树等算法有基本的理解,并且我正在使用机器学习来建模股票市场的每日回报。我希望使用非线性回归算法进行我的机器学习,所以选择了支持向量机回归,因为它很流行。我使用交易日和EMA差异作为特征向量(X),价格变化作为标签(Y)。以下是我的代码
library("quantmod")#添加库library("lubridate")#使得处理日期更加容易library("e1071")#提供svm访问stockData <- new.env()tickers <- 'AAPL'startDate = as.Date("2015-11-01")#我们想要查看的日期范围的开始日期symbol = getSymbols(tickers,from=startDate, auto.assign=F)#从雅虎财经获取苹果的每日OHLCV数据DayofWeek<-wday(symbol, label=TRUE)#查找星期几Class<- Cl(symbol) - Op(symbol)#价格变化EMA5<-EMA(Cl(symbol),n = 5)#我们正在计算基于开盘价的5周期EMAEMA10<-EMA(Cl(symbol),n = 10)#然后是基于开盘价的10周期EMAEMACross <- EMA5 - EMA10#正值对应于5周期EMA高于10周期EMAEMACross<-round(EMACross,2)DataSet2<-data.frame(DayofWeek,EMACross, Class)DataSet2<-DataSet2[-c(1:10),]#我们需要移除10周期移动平均仍在计算的实例m<-nrow(DataSet2)n<-round((nrow(DataSet2)*2)/3)TrainingSet<-DataSet2[1:n,]#我们将使用2/3的数据来训练模型TestSet<-DataSet2[(n+1):m,]#并使用1/3的数据来测试未见数据EMACrossModel<-svm( Cl(symbol) ~ ., data=TrainingSet) summary(EMACrossModel)pred<-predict(EMACrossModel,TestSet[,-3])
当我运行上述代码时,我得到了这个错误
> EMACrossModel<-svm( Cl(symbol) ~ ., data=TrainingSet) Error in model.frame.default(formula = Cl(symbol) ~ ., data = TrainingSet, : variable lengths differ (found for 'DayofWeek')
所以我的问题是(请原谅我有不止一个问题)
1) 如何解决上述问题?2) 在SVM回归中,我可以同时使用定性数据(例如:周一、周二、周三等)和定量数据(例如1.0、0.1、100等)吗?3) 我如何绘制上述结果和SVM决策边界?
已编辑
DataSet2
DayofWeek EMA AAPL.Close2015-11-16 Mon -2.77 2.8000032015-11-17 Tues -2.51 -1.2299962015-11-18 Wed -1.67 1.5299992015-11-19 Thurs -0.89 1.1400002015-11-20 Fri -0.32 0.1000062015-11-23 Mon -0.23 -1.5199972015-11-24 Tues 0.00 1.5499952015-11-25 Wed 0.00 -1.1800002015-11-27 Fri -0.03 -0.4800032015-11-30 Mon 0.02 0.3100052015-12-01 Tues -0.09 -1.4100042015-12-02 Wed -0.31 -1.0599972015-12-03 Thurs -0.57 -1.3500062015-12-04 Fri -0.10 3.7399982015-12-07 Mon 0.05 -0.7000042015-12-08 Tues 0.12 0.7100062015-12-09 Wed -0.24 -2.0199962015-12-10 Thurs -0.35 0.1299972015-12-11 Fri -0.83 -2.0100022015-12-14 Mon -1.15 0.3000032015-12-15 Tues -1.56 -1.4500042015-12-16 Wed -1.56 0.2699962015-12-17 Thurs -1.82 -3.0399942015-12-18 Fri -2.30 -2.8800052015-12-21 Mon -2.23 0.0500032015-12-22 Tues -2.07 -0.1699992015-12-23 Wed -1.64 1.3400042015-12-24 Thurs -1.40 -0.9700012015-12-28 Mon -1.37 -0.7699962015-12-29 Tues -0.98 1.7799992015-12-30 Wed -0.92 -1.260002
修改后的代码可以运行,但给出了不同的答案
这些是修改
EMACrossModel<-ksvm( Cl(symbol[1:n]) ~ ., data=TrainingSet,kernel="rbfdot",C=10) #kernlab librariespred<-predict(EMACrossModel,TestSet)
结果
> EMACrossModelSupport Vector Machine object of class "ksvm" SV type: eps-svr (regression) parameter : epsilon = 0.1 cost C = 10 Gaussian Radial Basis kernel function. Hyperparameter : sigma = 0.294836572886287 Number of Support Vectors : 17 Objective Function Value : -49.1082 Training error : 0.138329 > pred [,1] [1,] 119.7267 [2,] 119.9733 [3,] 120.7236 [4,] 121.8324 [5,] 121.5632 [6,] 121.4652 [7,] 119.6438 [8,] 119.6962 [9,] 119.0775[10,] 116.4956
我期望的预测结果是这样的
[,1]-1.3279961.229939-1.1300000.100006-1.519997-0.480003 1.310005-1.410004-1.0599971.350006-2.7399981.700004
我的猜测是我的当前代码使用股票价格而不是价格变化作为Y,并用它来建模EMACrossModel。我猜对了吗?如果是的,我该如何解决这个问题?
回答:
关于第一个问题你通过移除一些数据形成了你的训练集。然而,你没有限制你的symbol集:
EMACrossModel<-svm( Cl(symbol[1:n]) ~ ., data=TrainingSet)
我刚刚意识到你更可能想要的是:
EMACrossModel<-svm( AAPL.Close ~ ., data=TrainingSet)
一般来说,公式:Cl(symbol[1:n]) ~ .定义了什么被学习。目前它是“symbol”。然而,我假设你想预测AAPL.Close列。公式是R中的一个通用概念(https://stat.ethz.ch/R-manual/R-devel/library/stats/html/formula.html)。值得花一些时间来理解这些。编辑基于你上面的评论,这似乎得到了确认。结果是
-0.1926745 0.3578645 0.1830046 0.6362871 -0.3760084 -0.1443156 0.2615674 0.2589130 -0.4779677 -0.5928780
编辑结束
关于第二个问题,这取决于实现(和内核),但在这里似乎是这种情况。
关于你的第三个问题。E1071包包含一个示例:
data(cats, package = "MASS")m <- svm(Sex~., data = cats)plot(m, cats)
编辑我刚刚意识到这个绘图函数只适用于分类器,而不适用于回归。然而,你可以轻松构建自己的绘图函数。为了简单起见,我首先将星期几转换为数字。
DataSet2$DayofWeek <- as.numeric(DataSet2$DayofWeek)
并重建分类器之后,你可以通过以下方式可视化分类器
### 通过生成覆盖数据范围的网格来绘制支持向量机的结果#首先生成DataSet2EMA的最大值和最小值之间的100个数字序列plot.ema.vec <- seq(min(DataSet2$EMA),max(DataSet2$EMA),(max(DataSet2$EMA)-min(DataSet2$EMA))/100)#生成一组人造数据点,1:7是星期几#可以替换为c("Mon",...,"Sun")datagrid <- expand.grid(1:7,plot.ema.vec)#根据数据集设置网格的名称,以便分类器可以使用数据作为输入names(datagrid) <- names(DataSet2[,1:2])#计算分类器的预测grid.pred <- predict(EMACrossModel,datagrid)#将预测标准化到[0,1]范围内以用作颜色cols <- (grid.pred-min(grid.pred))/(max(grid.pred)-min(grid.pred))#绘制数据的决策plot(datagrid$DayofWeek,datagrid$EMA , col=rgb(blue=cols,red=1-cols,green=0))