Использование Apache математики для линейной регрессии с весами - PullRequest
0 голосов
/ 03 января 2019

Я уже некоторое время использую Apache math для выполнения множественной линейной регрессии с использованием OLSMultipleLinearRegression. Теперь мне нужно расширить свое решение, включив в него весовой коэффициент для каждой точки данных.

Я пытаюсь повторить фитл функции MATLAB.

У меня есть вызов MATLAB как:

table_data = table(points_scored, height, weight, age);
model = fitlm( table_data, 'points_scored ~ -1, height, weight, age', 'Weights', data_weights)

Из «модели» я получаю коэффициенты регрессии для роста, веса, возраста.

В Java код, который у меня сейчас есть (примерно):

double[][] variables = double[grades.length][3];
// Fill in variables for height, weight, age, 
...

OLSMultipleLinearRegression regression = new OLSMultipleLinearRegression();
regression.setNoIntercept(true);
regression.newSampleData(points_scored, variables);

Похоже, нет способа добавить веса в OLSMultipleLinearRegression. Кажется, есть способ добавить вес в LeastSquaresBuilder. Однако я не могу понять, как именно это использовать. Моя самая большая проблема (я думаю) - это создание ожидаемых якобиан.

Вот большая часть того, что я пробовал:

double[] points_scored = //fill in points scored
double[] height = //fill in 
double[] weight = //fill in
double[] age = // fill in

MultivariateJacobianFunction distToResidual= coeffs -> {
  RealVector value = new ArrayRealVector(points_scored.length);
  RealMatrix jacobian = new Array2DRowRealMatrix(points_scored.length, 3);

  for (int i = 0; i < measures.length; ++i) {
    double residual = points_scored[i];
    residual -= coeffs.getEntry(0) * height[i];  
    residual -= coeffs.getEntry(1) * weight[i];  
    residual -= coeffs.getEntry(2) * age[i];  
    value.setEntry(i, residual);
    //No idea how to set up the jacobian here
   }

   return new Pair<RealVector, RealMatrix>(value, jacobian);
};

double[] prescribedDistancesToLine = new double[measures.length];
Arrays.fill(prescribedDistancesToLine, 0);
double[] starts = new double[] {1, 1, 1};

LeastSquaresProblem problem = new LeastSquaresBuilder().
            start(starts).
            model(distToResidual).
            target(prescribedDistancesToLine).
            lazyEvaluation(false).
            maxEvaluations(1000).
            maxIterations(1000).
            build();
 LeastSquaresOptimizer.Optimum optimum = new LevenbergMarquardtOptimizer().optimize(problem);

Поскольку я не знаю, как определить значения якобиана, я только что нанес удар в темноте и не получил коэффициента, который был бы близок к ответам MATLAB. Как только эта часть заработает, я знаю, что добавление весов должно быть довольно простой дополнительной строкой в ​​LeastSquaresBuilder.

Заранее спасибо за любую помощь!

...