Найти ближайшую сумму значений x свойств из нескольких объектов - PullRequest
1 голос
/ 21 марта 2019

допустим, у меня есть класс Part с 3 свойствами x, y, z:

class Part {
 constructor(x, y, z) {
    this.x = x
    this.y = y
    this.z = z
  }

  createNewFromParts(...parts){

  }
}

Я хочу, чтобы функция createNewFromParts получала x деталей и находила для каждой детали постоянное число для дублированияего свойства с, так что после того, как все части будут продублированы, сумма каждого значения свойства из всех частей будет ближе всего к исходному свойству части.Я также хочу записать процент успеха.Процент успеха будет рассчитываться по всем 3 свойствам вместе с предыдущими значениями, а не по отдельным лицам.

, например:

const whole = new Part(4,6,10);
const part1 = new Part(1,2,4);
const part2 = new Part(2,2,3);

, в этом примере это просто: умножитьpart1 в 1 и part2 в 2, и это результат сложения будет (5,6,10), что, вероятно, является лучшим совпадением.

Допустим, будет что-то вроде этого:

const whole = new Part(32,10,27);
const part1 = new Part(10,7,15);
const part2 = new Part(15,5,22);

Как я найду константы, дублирующие каждую часть, чтобы получить наилучшее совпадение?

Я хочу найти алгоритм, который найдет константу для каждой части, с которой будет дублироваться, чтобы получить наилучшее совпадение, которое являетсяближе всего к оригиналу.

Оцените помощь:)

1 Ответ

2 голосов
/ 21 марта 2019

Вот подход Наименьших квадратов , который является лишь одним из многих способов решения проблемы

Если вы рассматриваете каждую из ваших частей как вектор с 3 элементами, например, часть 1 будет иметь вид:

enter image description here

Затем вы можете написать линейную систему, которая связывает части P со всей частью Y через вектор коэффициентов A:

enter image description here

Затем можно найти вектор коэффициентов A, который минимизирует сумму квадратов невязок :

enter image description here

Сумма квадратов невязок r - это сумма квадратов разностей между всей вашей частью Y и «наилучшей» оценочной частью enter image description here, где шляпа означает «оценочный».

Решением этой задачи минимизации квадратов невязок являются расчетные коэффициенты, полученные с помощью этого уравнения:

enter image description here

Получив оценку коэффициентов, вы можете вычислить Средняя абсолютная ошибка в процентах (MAPE) следующим образом:

enter image description here

Вот реализация, использующая math.js , которая работает с любым количеством деталей.

function findCoeffs(Y, parts) {
  const P = math.transpose(parts);
  const Pt = parts;
  const PtPinv = math.inv(math.multiply(Pt, P));
  const PtPinvPt = math.multiply(PtPinv, Pt);
  return math.multiply(PtPinvPt, Y);
}

function test(Y, ...parts) {
  const coeffs = findCoeffs(Y, parts);
  const round = n => +n.toFixed(2);
  const disp = ns => JSON.stringify(ns.map(n => Array.isArray(n) ? n.map(round) : round(n)));
  const actual = math.multiply(coeffs, parts);
  const error = math.subtract(Y, actual);
  const errorPercent = error.map((e, i) => Math.abs(e / actual[i]));
  const totalErrorPercent = errorPercent.reduce((sum, e) => sum + e, 0) * 100 / coeffs.length;
  console.log('--------------------------');
  console.log('expected    (Y)  ', disp(Y));
  console.log('parts       (P)  ', disp(parts));
  console.log('coeffs      (A)  ', disp(coeffs));
  console.log('actual      (PA) ', disp(actual));
  console.log('coeff error      ', disp(errorPercent));
  console.log('mean error (MAPE)', round(totalErrorPercent) + '%');
}

test([4, 6, 10], [1, 2, 4], [2, 2, 3]);
test([32, 10, 27], [10, 7, 15], [15, 5, 22]);
test([3.2, 3, 5], [1.1, 1, 1], [1.1, 2, 3], [1, -1, 1]);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script language="JavaScript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/5.8.0/math.min.js"></script>
...