【问题标题】:How can I use this Node.js library to calculate a polynomial regression?如何使用这个 Node.js 库来计算多项式回归?
【发布时间】:2015-08-16 01:53:56
【问题描述】:

我需要一种算法来计算给定输入向量的多项式回归。我找到了this Node.js library,它似乎提供了我需要的东西。

查看文档,我看到我需要传递一个二维数据数组:

var data = [[0,1],[32, 67] .... [12, 79]];
var result = regression('polynomial', data, 4);

但我不清楚

  1. 为什么输入数据是二维的?
  2. 每个数组中的值是什么意思?在示例中,[0,1] 代表什么(什么变量是 0,什么变量是 1?)。

基本上,此算法旨在计算股票市场分析中使用的指标的数据。所以我的输入是一组价格:[14.26, 14.27, 14.27, 14.28, 14.29, 14.27, 14.27, 14.28. ...]

【问题讨论】:

  • 我在评论中添加是因为它不能解决您的问题,但 Node.js 真的是解决您问题的最佳技术吗?它可能是有问题的,因为它是单线程的并且基于事件循环。这对 IO 来说很棒,但对于 CPU 密集型的工作来说则不然。如果您知道自己在做什么,那就太好了,不要介意此消息。否则,我建议您寻找另一种语言来完成受 CPU 限制的工作,即使 Node.js 有办法解决这个问题。
  • 这是个好建议。虽然我只是回测试一个交易策略,所以我现在并不担心优化。如果我需要扩大规模,我肯定会考虑这个。
  • 我的数学很生疏,但多项式回归的目的不就是为 xy 之间的关系建模吗?如果我是一个赌徒,我敢打赌这些数组应该是 (x, y) 对。您的股票价格似乎是因变量 y,那么自变量 x 是什么?可以这么说,我的钱是准时的。
  • Node.js 中的繁重数学计算?这就像在 C 中做网络服务器
  • @webduvet,这仅用于简单的回测,不适用于生产。

标签: node.js regression polynomial-math


【解决方案1】:

游戏有点晚了,但这可能对其他人有用。

我建议阅读一下什么是回归以及它们是如何计算的。手动做一些...

https://www.khanacademy.org/math/statistics-probability/describing-relationships-quantitative-data

简短的回答是创建一个包含 x 和 y 值的数组:

for(var i=data.length-1; i>=0 ; i--){
    data[i] = [i,data[i]];
}

我看到原始数据的一个大问题是它忽略了“x”。在这种情况下,“x”可能是日期,但是通过将数据存储在数组中,我们假设日期是连续的。考虑到您正在使用的数据,这似乎不太可能:我预计周末和节假日的数据会出现缺口。

基于这个假设,这里有一个例子来说明如何实现你所说的。这在很多类型的数据中都很有用:

debugger;
// get some stock data: daily close prices
var data = [{Date:"2016-09-23",Close:85.81},{Date:"2016-09-22",Close:86.35},...];

// Before we can use this data, we need to format 
// it for display and processing. Basically, just 
// make sure that everything is in the right order 
// and such...
var metrics = {
    mindate : moment(data[0].Date),
    maxdate : moment(data[0].Date),
};
data.forEach(function(rec){
    // cast the date to something more friendly
    rec.Date = moment(rec.Date);
    // get the min and max
    if(metrics.mindate.isAfter (rec.Date)){ metrics.mindate = moment(rec.Date); }
    if(metrics.maxdate.isBefore(rec.Date)){ metrics.maxdate = rec.Date; }
});
metrics.days = metrics.maxdate.diff(metrics.mindate,'days');

// One thing you will notice about stock data
// is that the markets are not open on holidays
// this means that we do not have data about 
// what the price was during those days, also
// the distance between our datapoints Friday and 
// Monday is not 1 day. Some work is necessary to 
// make it clear that there is a gap
data.forEach(function(rec){
    rec.day = rec.Date.diff(metrics.mindate,'days');
});

// At this point the data is probably ready
// for the regression library, we just need
// to format it correclty
var d = [];
data.forEach(function(rec){
    var x = rec.day;
    var y = rec.Close;
    d.push([x,y]);
});
var result = regression('polynomial', d, 4);


// Now that the regressino has been calculated, we
// can make use of it. First let's determine what
// data was missing from our original dataset
// (basically teh weekends and holidays)
for(var i=data.length-2; i>=0;i--){
    for(var day=data[i+1].day-1;day>data[i].day;day--){
        data.push({
            day:day,
            Date:moment(metrics.mindate).add(day,'days'),
            Close:null,
            Est:null
        });
    }
}
// While we are at, let's project a couple days into 
// the future
var lastday = metrics.days;
for(var day=metrics.days+30; day>=metrics.days; day--){
        data.push({
            day:day,
            Date:moment(metrics.mindate).add(day,'days'),
            Close:null,
            Est:null
        });
}

// for convenience sake, copy it back into our 
// original dataset
data.forEach(function(rec){
    rec.Est = 0;
    for(var i=result.equation.length-1; i>=0; i--){
        rec.Est += result.equation[i] * Math.pow(rec.day,i);
    }
});

// better sort it at this point
data.sort(function(a,b){
    if(a.day < b.day) return -1;
    if(a.day > b.day) return 1;
    return 0;
});
// Now that processing is complete, we can use
// the data in some manner that is meaningful
// in this case, I display the data with the
// gaps filled in, as well as a projection
data.forEach(function(rec){
    $('table#prices').append(
            '<tr><td>{{day}}</td><td>{{Date}}</td><td>{{Close}}</td><td>{{Est}}</td></tr>'
.replace(/{{day}}/g,rec.day)                .replace(/{{Date}}/g,rec.Date.format('YYYY-MM-DD'))
                .replace(/{{Close}}/g,rec.Close || '')
                .replace(/{{Est}}/g,rec.Est || '')
        );
});
$('pre#est').html(
    metrics.mindate.format('YYYY-MM-DD') 
    + ' -> ' + metrics.maxdate.format('YYYY-MM-DD') 
    + ' (' + metrics.days + ' days)'
    + '\n' + result.string
);

要处理的东西很多,所以这里有一个小提琴:

https://jsfiddle.net/v95evuv8/6/

这取决于regression.jsmoment.js(用于日期操作)

cmets 包含有关 doint this 实用性的问题。在聚合结果集时,我在 CouchDB 中做了类似的事情(减少到回归参数并监控偏离预期的回归),并且还经常在基于 Web 的报告的图表中显示回归线。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-17
    • 1970-01-01
    • 1970-01-01
    • 2021-04-19
    • 2018-10-01
    相关资源
    最近更新 更多