通过加权回归拟合三维数据线

时间:2016-03-14 18:23:15

标签: c# 3d machine-learning linear-regression curve-fitting

我正在尝试使用Singular Value Decomposition method(SVD)来计算3D线性回归LINE。

这很好用。现在,我想概括加权回归的方法。

如何使用SVD计算optimale beta?下面是我使用CSML package的C#代码。 LinearRegression()函数工作得很好。 WeightedLinearRegression()没有,我认为这是因为我不能简单地定义

weighted_mult_mat = M_tr * W * M;

CODE:

 public static Vector3D WeightedLinearRegression(List<Point3D> pts, List<double> weights) {

        // normalisation
        double sum = weights.Sum();
        if (sum != weights.Count) {
            for (int i = 0; i < weights.Count; i++ ) {
                weights[i] = weights[i] / sum;
            }
        }

        Point3D avg = pts.average();

        // populate Matrix M
        CSML.Matrix M = new CSML.Matrix(pts.Count, 3); // init

       // populate matrix M
        for (int i = 1; i < pts.Count + 1; i++) {
            M[i, 1] = new Complex(pts[i - 1].X - avg.X);
            M[i, 2] = new Complex(pts[i - 1].Y - avg.Y);
            M[i, 3] = new Complex(pts[i - 1].Z - avg.Z);
        }

        CSML.Matrix M_tr = M.Transpose();

        // populate weights matrix
        CSML.Matrix W = new CSML.Matrix(pts.Count, pts.Count); // init

        for (int i = 1; i < pts.Count + 1; i++) {
            W[i, i] = new Complex(weights[i-1]);
        }

        // compute matrix
        CSML.Matrix weighted_mult_mat = new CSML.Matrix();
        weighted_mult_mat = M_tr * W;
        weighted_mult_mat = weighted_mult_mat * M;
        var weighted_dense_mat = new DenseMatrix(3, 3);
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                weighted_dense_mat[i, j] = weighted_mult_mat[i + 1, j + 1].Re;
            }
        }
        var weighted_svd = weighted_dense_mat.Svd(true);
        var weighted_vt = weighted_svd.VT;
        Vector3D weighted_dirVect = new Vector3D(weighted_vt[0, 0], weighted_vt[0, 1], weighted_vt[0, 2]);
        weighted_dirVect.Normalize();




        return weighted_dirVect;

    }

public static Vector3D LinearRegression(List<Point3D> pts) {

        Point3D avg = pts.average();

        // populate Matrix M
        CSML.Matrix M = new CSML.Matrix(pts.Count, 3); // init

        // populate matrix M
        for (int i = 1; i < pts.Count + 1; i++) {
            M[i, 1] = new Complex(pts[i - 1].X - avg.X);
            M[i, 2] = new Complex(pts[i - 1].Y - avg.Y);
            M[i, 3] = new Complex(pts[i - 1].Z - avg.Z);
        }

        CSML.Matrix M_tr = M.Transpose();

        CSML.Matrix mult_mat = new CSML.Matrix();
        mult_mat = M_tr * M;

       var dense_mat = new DenseMatrix(3, 3);

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                dense_mat[i, j] = mult_mat[i + 1, j + 1].Re ;
            }
        }

        var svd = dense_mat.Svd(true);

        var vt = svd.VT;

        Vector3D dirVect = new Vector3D(vt[0, 0], vt[0, 1], vt[0, 2]);

        dirVect.Normalize();

        return dirVect;

}

0 个答案:

没有答案