K均值聚類算法對股票K線聚類

證券投資書中對K線分了12種,對於輸入的股票開盤,收盤,最高,最低好像不太適合完全套用,畢竟不是機器說了算,也是人爲分的,總覺得不靠譜(一個屌絲程序員中的毒^_^)。所以還是想要讓機器自己判斷。
之前一直用scikit-learn直接實現,最近一個前端的朋友也想研究,就用javascript幫忙寫了一下,算是記錄一下心得吧。
首先介紹一下K均值聚類算法的原理吧。摘要一下百度百科:K均值聚類算法是先隨機選取K個對象作爲初始的聚類中心。然後計算每個對象與各個種子聚類中心之間的距離,把每個對象分配給距離它最近的聚類中心。聚類中心以及分配給它們的對象就代表一個聚類。一旦全部對象都被分配了,每個聚類的聚類中心會根據聚類中現有的對象被重新計算。這個過程將不斷重複直到滿足某個終止條件。終止條件可以是沒有(或最小數目)對象被重新分配給不同的聚類,沒有(或最小數目)聚類中心再發生變化,誤差平方和局部最小。
按照百度百科的描述,很容易整理出流程:
        創建K個點作爲初始中心;
        判斷是否滿足分類結果
                遍歷數據集中每個數據點
                {
                            計算數據點到每個中心的距離;
                            分配數據點到最近中心所定義的簇
                }
                計算每個簇中所有點的均值並使其作爲該簇新的中心
        滿足分類結果輸出結果

最重要的是計算兩個點的距離,這裏直接使用歐式距離作爲距離函數,實現代碼:

function distEclud(vecA,vecB){
    var sum = 0;
    for(var i = 0;i < vecA.length;i++){
        var deta = vecA[i] - vecB[i];
        sum = sum + deta * deta;
    }
    return Math.sqrt(sum);
}

其次就是隨機產生K個初始中心:

function randCent(dataSet,k){
    //var n = dataSet[0].length;
    //var minJ = $M.min(dataSet,1);
    //var rangeJ = $V.sub($M.max(dataSet,1),minJ);
    var centroids = []
    for(var i = 0;i < k;i++){
        //centroids.push($V.add(minJ,$V.mul(rangeJ,$V.rand(n))));
        centroids.push(dataSet[i]);
    }
    return centroids;
}

上面非註釋代碼是將數據集的K個數據點作爲中心數據,也可以採用註釋的代碼,註釋代碼產生K個隨機數據點,$M.min函數計算矩陣(二維數組)列最小值,$M.max計算最大值,$V.add,$V.mul分別計算數組的加與乘,$V.rand生成n維隨機數組。

接下來就是對數據集進行聚類,實現代碼如下:

function kMeans(dataSet,k){
    var m = dataSet.length;
    var clusterAssment0 = [];
    var clusterAssment1 = [];
    for(var i = 0;i < m;i++){
        clusterAssment0.push(0);
        clusterAssment1.push(1);
    }
    var centroids = randCent(dataSet,k);
    var clusterChanged = true;
    while(clusterChanged){
        clusterChanged = false;

        for(var i = 0;i < m;i++){
            var minDist = 10000000;minIndex = -1;
            for(var j = 0;j < k;j++){
                var distJI = distEclud(centroids[j],dataSet[i]);

                if(distJI < minDist){
                    minDist = distJI;
                    minIndex = j;
                }
            }
            if(clusterAssment0[i] != minIndex){
                clusterChanged = true;
            }
            clusterAssment0[i] = minIndex;
            clusterAssment1[i] = minDist * minDist;
        }
        for(var i = 0;i < k;i++){
            var ptsInClust = $M.subm(dataSet,$V.where(clusterAssment0,"==",i),0);
            if(ptsInClust.length == 0){
                continue;
            }
            centroids[i] = $M.mean(ptsInClust,1);
        }
    }
    return {
        centroids:centroids,
        cluster:clusterAssment0
    };

}

結果返回聚類中心與聚類結果。
以上K均值聚類的代碼已經實現。
接下來就是使用K均值聚類算法應用到股票數據,股票數據我們使用騰訊數據,我們採用2017年浦發銀行的日K作爲數據集合,代碼:
&lt;script src = "http://data.gtimg.cn/flashdata/hushen/daily/17/sh600000.js"&gt;&lt;/script&gt;
對數據的解析代碼如下:

var ev_data = daily_data_17.split("\n");
var open = [];
var high = [], low = [],close = [],volume = [],date = [];bar = [];
for(var i = 1;i < ev_data.length - 1;i++){
    var es = ev_data[i].split(" ");
    date.push(es[0]);
    open.push(es[1]);
    close.push(es[2]);
    high.push(es[3]);
    low.push(es[4]);
    volume.push(es[5]);
    bar.push([es[1],es[2],es[4],es[3],es[5]]);
}

爲了計算K線的形態,股價的大小不能作爲特徵值的大小,開盤、收盤等之間存在關聯,所以我們要對各個數據進行整理,下面是我對數據處理的方式:

var data = [];
for(var i = 1;i < close.length;i++){
    var mean = (parseFloat(close[i]) + parseFloat(open[i]) + parseFloat(high[i]) + parseFloat(low[i]))/4;
    var tmp = [((parseFloat(high[i]) - mean) == 0)?1:(parseFloat(close[i]) - mean)/(parseFloat(high[i]) - mean),
                ((parseFloat(high[i]) - mean) == 0)?1:(parseFloat(low[i]) - mean)/(parseFloat(high[i]) - mean),
                ((parseFloat(high[i]) - mean) == 0)?1:(parseFloat(open[i]) - mean)/(parseFloat(high[i]) - mean),
                (volume[i] - volume[i - 1])/volume[i - 1]
            ]
    data.push(tmp);
}
var max = $M.max(data,1);
var min = $M.min(data,1);
var tz = $M.div_vector($M.sub_vector(data,min,1),$V.sub(max,min),1);

將tz作爲數據集輸入K均值聚類模型,並畫出K線圖和分類圖:
var result = kMeans(tz,12);
聚類結果如下:
0:K均值聚類算法對股票K線聚類

1:K均值聚類算法對股票K線聚類
2:K均值聚類算法對股票K線聚類
3:K均值聚類算法對股票K線聚類
4:K均值聚類算法對股票K線聚類
5:K均值聚類算法對股票K線聚類
6:K均值聚類算法對股票K線聚類
7:K均值聚類算法對股票K線聚類
8:K均值聚類算法對股票K線聚類
9:K均值聚類算法對股票K線聚類
10:K均值聚類算法對股票K線聚類
11:K均值聚類算法對股票K線聚類

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