貝葉斯分類對股票走勢預測

    上一文介紹了K均值對股票K線分類,該文對它做一個應用,通過貝葉斯分類器進行股票走勢的預測。
    好多炒股的大牛都說看K線判斷次日的漲跌,按照這個思路,我們將前六根k線做爲輸入,漲幅超過2個點爲1作爲輸出訓練貝葉斯分類器,然後輸入當日的前六根K線作爲輸入,來預測明日的股票走勢。
    首先介紹一下貝葉斯分類器。
    貝葉斯分類器的分類原理是通過某對象的先驗概率,利用貝葉斯公式計算出其後驗概率,即該對象屬於某一類的概率,選擇具有最大後驗概率的類作爲該對象所屬的類。(摘自百度百科)說白了就是貝葉斯公式:
    P( C = ci | X = x) = P( X = x | C = ci) * P( C = ci) / P( X = x)
    其中X = ( X1 , X2 , ... , Xn)表示輸入的特徵,也就是我們的6根K線,C爲類集合( c1 , c2 , ... , cm),當輸入爲x,輸出爲ci類的概率最大即爲輸出的類別,即:
    P( C = ci | X = x) = Max{ P( C = c1 | X = x) , P( C = c2 | X = x ) , ... , P( C = cm | X = x ) }
    這裏我們假定輸入的K線相互獨立,那麼
    P( X = x | C = ci)  = P( x= x1 | C = ci)*P( x= x2 C = ci)... P( x= xn | C = ci)
    又因爲對於確定的輸入X,P(X=x)爲常數,所以判別函數可以修改爲:
        F(P( C = ci | X = x)) = G(Max{  P( X = x | C = c1) * P( C = c1),  P( X = x | C = c2 * P( C = c2), ... ,  P( X = x | C = cm) * P( C = cm)});
        其中,G爲判別函數。

按照上面的思路,我們編碼,這裏直接貼代碼吧,看不懂 都可以留言:
function Bayes(){}
Bayes.prototype.train = function(trainMatrix,trainCategory){
var cateMaps = new Map();
for(var i = 0;i < trainCategory.length;i++){
    if(!cateMaps.containsKey(trainCategory[i])){
        cateMaps.put(trainCategory[i],0);
    }
    cateMaps.put(trainCategory[i],cateMaps.get(trainCategory[i]) + 1);
}
cateMaps.each(function(key,value){
    cateMaps.put(key,cateMaps.get(key)/trainCategory.length);
});
var labelsTree = new Map();
var labelsCount = new Map();

for(var i = 0;i <trainMatrix.length;i++){
    if(!labelsTree.containsKey(trainCategory[i])){
        labelsTree.put(trainCategory[i],new Map());
        labelsCount.put(trainCategory[i],new Map());
    }
    for(var j = 0;j < trainMatrix[0].length;j++){
        if(!(labelsTree.get(trainCategory[i]).containsKey(j))){
            labelsTree.get(trainCategory[i]).put(j,new Map());
        }
        labelsTree.get(trainCategory[i]).get(j).put(trainMatrix[i][j],labelsTree.get(trainCategory[i]).get(j).get(trainMatrix[i][j],0) + 1);
        labelsCount.get(trainCategory[i]).put(j,labelsCount.get(trainCategory[i]).get(j,0) + 1);
    }
}
console.log(labelsTree);
this.cateMaps = cateMaps;
this.labelsTree = labelsTree;
this.labelsCount = labelsCount;
console.log(this.labelsTree)
}
Bayes.prototype.predict = function(inputX){
var predictMap = new Map();
var labels = this.cateMaps.keySet();
var sm = 0;
for(var i = 0;i < labels.length;i++){
    var Pc = this.cateMaps.get(labels[i]);
    var P_w = 1;
    for(var j = 0;j < inputX.length;j++){
        var P_w_j_fz = 0,P_w_j_fm = 0;
        for(var k = 0;k < labels.length;k++){
            P_w_j_fz += this.labelsTree.get(labels[k]).get(j).get(inputX[j],0);
            P_w_j_fm += this.labelsCount.get(labels[k]).get(j);
        }

        P_w = P_w * P_w_j_fz/P_w_j_fm;
    }
    var P_w_c = 1;
    for(var j = 0;j < inputX.length;j++){
        P_w_c = P_w_c * this.labelsTree.get(labels[i]).get(j).get(inputX[j],0)/this.labelsCount.get(labels[i]).get(j);
    }
    predictMap.put(labels[i],P_w_c*Pc);
    sm += P_w_c*Pc;
    console.log(P_w);
}
for(var i = 0;i < labels.length;i++){
    predictMap.put(labels[i],predictMap.get(labels[i])/sm);
}
return predictMap;
}

上述是基於javascript貝葉斯分類器。
接下來根據上一文的K均值聚類歸類好的K線構建構建訓練數據集,實現方法:

function inputMean(series,close){
        var data = [],labels = [],x = [];
        var kcount = 6;//k線數量
        var cast = 1;
        for(var i = 0;i < series.length - kcount - cast + 1;i++){
            var tmp = [];
            for(var j = 0;j < kcount;j++){
                tmp.push(series[i + j]);
            }

            labels[i] = ((close[i + kcount + cast] - close[i + kcount])/close[i + kcount]*100 > 2)?'1':'0';
            data.push(tmp);
        }
        for(var i = 0;i < series.length - kcount+1;i++){
            var tmp = [];
            for(var j = 0;j < kcount;j++){
                tmp.push(series[i + j]);
            }
            x.push(tmp);
        }
        return[data,labels,x];
    }

上面代碼將計算6根K線作爲輸入,次日漲幅超過2%爲1類,否則爲0類,輸出訓練集data與結果集label,接下來我們將輸入集與結果集輸入貝葉斯分類器訓練。

        dt = inputMean(result.cluster,close);
        var bayes = new Bayes();
        bayes.train(dt[0],dt[1]);

將訓練後的分類器對數據進行分類:

        var test = [];
        var tx = [];
        for(var i = 0;i < dt[2].length;i++){
            test.push(((bayes.predict(dt[2][i]).get(1) > bayes.predict(dt[2][i]).get(0))?1:0));
            //test.push(bayes.predict(dt[2][i]).get(1))
            tx.push(date[i + 6]);
        }

將預測結果與真實值繪圖比較:
貝葉斯分類對股票走勢預測

對歷史數據的預測準確率基本可以達到80%以上(這裏包括訓練集,所以不太準確)。
綜上,貝葉斯分類與K均值聚類可以作爲股票買賣的參考,當然不值得迷信(哈哈)。因爲自己一直在研究,源碼有點亂,等整理好了再上傳git吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章