我想对2D数据点进行代数曲线拟合,但由于各种原因--不可能同时将大量样本数据放在内存中,而迭代所有这些数据是一个昂贵的过程。
(这样做的原因是,实际上我需要同时对数千条曲线进行拟合,这些数据是我正在读取的磁盘上的千兆字节数据,因此它是血)。
请注意,多项式系数的数量将是有限的(也许5-10),所以精确的拟合是不可能的,但是这是可以的,因为我试图在带有随机噪声的多数据中找到一个底层模式。我理解如何使用遗传算法来拟合数据集的曲线,但这需要通过大量的样本数据,因此对我的应用程序来说是不切实际的。
是否有一种方法可以用数据的一次传递来拟合一条曲线,其中必须从一个样本到另一个样本的状态是最小的?
我应该补充的是,数据的本质是,点可能位于X轴上0.0至1.0之间的任何位置,但Y值始终为1.0或0.0。
因此,在Java中,我需要一个具有以下接口的类:
public interface CurveFit {
public void addData(double x, double y);
public List<Double> getBestFit(); // Returns the polynomial coefficients
}实现此功能的类不需要在其实例字段中保存大量数据,即使是数百万个数据点,也不超过1 of。这意味着,您不能只是存储数据,因为您让它做多次通过它以后。
编辑:有些人建议,在一次传球中找到一条最优曲线可能是不可能的,但是不需要最优的拟合,就像我们在一次传球中能得到的一样接近。
一种方法的基本原理可能是,如果我们有一种方法,从一条曲线开始,然后修改它,使它稍微接近新的数据点--实际上是一种梯度下降的形式。希望有足够的数据(和数据将是充足的),我们得到了一个相当好的曲线。也许这会激励一些人找到解决方案。
发布于 2009-11-13 23:15:22
我相信我是根据修改后的这代码找到了我自己问题的答案。对那些感兴趣的人来说,我的Java代码是这里。
发布于 2009-11-11 17:52:02
是的,这是个投影。为
y = X beta + error 如果低胁迫项是向量,而X是矩阵,则有解向量。
\hat{beta} = inverse(X'X) X' y如OLS页面所示。您几乎从来没有想直接计算这个,而是使用LR,QR或SVD分解。统计文献中有大量的参考文献。
如果您的问题只有一个参数(因此x也是一个向量),那么这就简化为y和x之间交叉乘积的求和。
发布于 2009-11-13 06:22:22
如果您不介意得到一条直线“曲线”,那么对于任何数量的数据,您只需要六个变量。下面是我即将出版的书中的源代码;我相信您可以理解DataPoint类是如何工作的:
H:
#ifndef __INTERPOLATION_H
#define __INTERPOLATION_H
#include "DataPoint.h"
class Interpolation
{
private:
int m_count;
double m_sumX;
double m_sumXX; /* sum of X*X */
double m_sumXY; /* sum of X*Y */
double m_sumY;
double m_sumYY; /* sum of Y*Y */
public:
Interpolation();
void addData(const DataPoint& dp);
double slope() const;
double intercept() const;
double interpolate(double x) const;
double correlate() const;
};
#endif // __INTERPOLATION_HInterpolation.cpp:
#include <cmath>
#include "Interpolation.h"
Interpolation::Interpolation()
{
m_count = 0;
m_sumX = 0.0;
m_sumXX = 0.0;
m_sumXY = 0.0;
m_sumY = 0.0;
m_sumYY = 0.0;
}
void Interpolation::addData(const DataPoint& dp)
{
m_count++;
m_sumX += dp.getX();
m_sumXX += dp.getX() * dp.getX();
m_sumXY += dp.getX() * dp.getY();
m_sumY += dp.getY();
m_sumYY += dp.getY() * dp.getY();
}
double Interpolation::slope() const
{
return (m_sumXY - (m_sumX * m_sumY / m_count)) /
(m_sumXX - (m_sumX * m_sumX / m_count));
}
double Interpolation::intercept() const
{
return (m_sumY / m_count) - slope() * (m_sumX / m_count);
}
double Interpolation::interpolate(double X) const
{
return intercept() + slope() * X;
}
double Interpolation::correlate() const
{
return m_sumXY / sqrt(m_sumXX * m_sumYY);
}https://stackoverflow.com/questions/1716874
复制相似问题