如何找到表示两个数组有多少不同的百分比值?
How to find a precent value that represents how much two arrays are different?
我有两个数组。
我想要一个百分比值来描述它们的值有多少不同。
我尝试使用 MSE 和 RMSE:
/**
* Mean Squared Error
* MSE = (1/n) * Ʃ[(r - p)^2]}
*/
export function computeMse(a, b) {
const size = a.length
let error = 0
for (let i = 0; i < size; i++) {
error += Math.pow(b[i] - a[i], 2)
}
return (1 / size) * error
}
/**
* Root Mean Squared Error
* RMSE = √MSE
*/
export function computeRmse(a, b) {
return Math.sqrt(computeMse(a, b))
}
和:
const a = [2354493, 2615706, 1594281, 1570894, 1930709, 2086681]
const b = [2354493, 2224360.55, 1906806.9, 1408769.93, 1609053.96, 2200698.72]
const mse = computeMse(a, b)
const rmse = computeRmse(a, b)
结果是:
mse: 65594986451.87959
rmse: 256115.18200192583
我认为这个结果不正确。
首先,mse 和 rmse 不在 [0, 100] 范围内,然后即使两个数组差别不大,它们的值也非常大。
我哪里错了?
我也试试:
export function computeMape(actual, forecast) {
const size = actual.length
let error = 0
for (let i = 0; i < size; i++) {
error += Math.abs((actual[i] - forecast[i]) / actual[i])
}
return (100 * error) / size
}
与:
const a = [77, 50, 38, 30, 26, 18]
const b = [77, 81.13, 92.77, 101.98, 119.76, 121.26]
然后我得到 mape: 230.10116059379217
...
另一个例子:
const a = [1.15, 1.09, 1.08, 0.78, 0.51, 0.44]
const b = [1.15, 1.61, 1.88, 2.13, 2.3, 2.47]
const mape = computeMape(a, b) // result: 184.53357461497413
假设您有这三个数据集:
红线代表真实数据,绿线代表用户创建的预测数据(测试1),灰线代表用户创建的预测数据(测试2)。事实上,用户可以尝试不同的时间来命中真实数据(这就像一个游戏)。
现在我想return给用户一个反馈,告诉用户他猜测数据趋势的百分比有多么错误。
用户可以做出无数的预测。我想要一个百分比数字来告诉我用户错了多少,以便比较每次尝试。
有可能吗?
同样在这种情况下,我得到 NaN 结果:
const a = [132.6, 114.1, 134.5, 124.5, 144.4, 162.4]
const b = [132.6, 134.15, 134.15, 134.15, 139.19]
为什么?
我想您要查找的度量实际上是 MPE 而不是 MSE。
function mpe(a, f) {
let size = a.length, sum = 0;
for (let i = 0; i < size; i++) {
sum += (a[i] - f[i]) / a[i];
}
return 100 * sum / size;
}
// small demo
forecast = [10, 20, 30]
actual = [10, 20, 30]
for(i = 0; i < 20; i++) {
console.log(actual.join() + ' mpe ' + mpe(actual, forecast).toFixed(1) + '%')
actual[i % 3] += 10;
}
嗯,这取决于100%的意义。如果 100%(在您的情况下)是与实际数据的最大可能偏差,那么您必须在输出上定义一些 限制。
例如,尝试:
function computeError(obj) {
let size = obj.actual.length;
let maxErr = obj.limits[1] - obj.limits[0];
let error = 0;
let i;
for (i = 0; i < size; i++) {
error += Math.abs((obj.actual[i] - obj.forecast[i]) / maxErr);
}
console.log( ((100 * error) / size).toFixed(3), '%' );
}
const testCases = [
{
actual: [2354493, 2615706, 1594281, 1570894, 1930709, 2086681],
forecast: [2354493, 2224360.55, 1906806.9, 1408769.93, 1609053.96, 2200698.72],
limits: [0, 5e6] // [0, 5000000]
},
{
actual: [77, 50, 38, 30, 26, 18],
forecast: [77, 81.13, 92.77, 101.98, 119.76, 121.26],
limits: [0, 2e2] // [0, 200]
},
{
actual: [1.15, 1.09, 1.08, 0.78, 0.51, 0.44],
forecast: [1.15, 1.61, 1.88, 2.13, 2.3, 2.47],
limits: [0, 3e0] // [0, 3]
},
// extra cases
{
actual: [0, 0, 0],
forecast: [1, 1, 1],
limits: [0, 1e0]
},
{
actual: [1, 1, 1],
forecast: [1, 1, 1],
limits: [0, 1e9]
}
];
testCases.forEach(computeError); // calls computeError function on each object
一种愚蠢但实用的方法是简单地考虑误差,根据您喜欢的样本和预测之间的任何距离计算
(标准 1、标准 2 等等)
然后通过您选择的函数将结果值映射到区间 [0;1](满足 f:[0; infty]->[0;1])
例如:
f(err) = e^(-x^2/a^2) with a of your choice
在您的代码中,可能类似于
var err = computeMse(a,b)
function toPercent(err){
const a = 1;
return Math.exp(-x*x/a*a);
}
var percent = toPercent(err)
我有两个数组。
我想要一个百分比值来描述它们的值有多少不同。 我尝试使用 MSE 和 RMSE:
/**
* Mean Squared Error
* MSE = (1/n) * Ʃ[(r - p)^2]}
*/
export function computeMse(a, b) {
const size = a.length
let error = 0
for (let i = 0; i < size; i++) {
error += Math.pow(b[i] - a[i], 2)
}
return (1 / size) * error
}
/**
* Root Mean Squared Error
* RMSE = √MSE
*/
export function computeRmse(a, b) {
return Math.sqrt(computeMse(a, b))
}
和:
const a = [2354493, 2615706, 1594281, 1570894, 1930709, 2086681]
const b = [2354493, 2224360.55, 1906806.9, 1408769.93, 1609053.96, 2200698.72]
const mse = computeMse(a, b)
const rmse = computeRmse(a, b)
结果是:
mse: 65594986451.87959
rmse: 256115.18200192583
我认为这个结果不正确。 首先,mse 和 rmse 不在 [0, 100] 范围内,然后即使两个数组差别不大,它们的值也非常大。
我哪里错了?
我也试试:
export function computeMape(actual, forecast) {
const size = actual.length
let error = 0
for (let i = 0; i < size; i++) {
error += Math.abs((actual[i] - forecast[i]) / actual[i])
}
return (100 * error) / size
}
与:
const a = [77, 50, 38, 30, 26, 18]
const b = [77, 81.13, 92.77, 101.98, 119.76, 121.26]
然后我得到 mape: 230.10116059379217
...
另一个例子:
const a = [1.15, 1.09, 1.08, 0.78, 0.51, 0.44]
const b = [1.15, 1.61, 1.88, 2.13, 2.3, 2.47]
const mape = computeMape(a, b) // result: 184.53357461497413
假设您有这三个数据集:
红线代表真实数据,绿线代表用户创建的预测数据(测试1),灰线代表用户创建的预测数据(测试2)。事实上,用户可以尝试不同的时间来命中真实数据(这就像一个游戏)。
现在我想return给用户一个反馈,告诉用户他猜测数据趋势的百分比有多么错误。
用户可以做出无数的预测。我想要一个百分比数字来告诉我用户错了多少,以便比较每次尝试。
有可能吗?
同样在这种情况下,我得到 NaN 结果:
const a = [132.6, 114.1, 134.5, 124.5, 144.4, 162.4]
const b = [132.6, 134.15, 134.15, 134.15, 139.19]
为什么?
我想您要查找的度量实际上是 MPE 而不是 MSE。
function mpe(a, f) {
let size = a.length, sum = 0;
for (let i = 0; i < size; i++) {
sum += (a[i] - f[i]) / a[i];
}
return 100 * sum / size;
}
// small demo
forecast = [10, 20, 30]
actual = [10, 20, 30]
for(i = 0; i < 20; i++) {
console.log(actual.join() + ' mpe ' + mpe(actual, forecast).toFixed(1) + '%')
actual[i % 3] += 10;
}
嗯,这取决于100%的意义。如果 100%(在您的情况下)是与实际数据的最大可能偏差,那么您必须在输出上定义一些 限制。
例如,尝试:
function computeError(obj) {
let size = obj.actual.length;
let maxErr = obj.limits[1] - obj.limits[0];
let error = 0;
let i;
for (i = 0; i < size; i++) {
error += Math.abs((obj.actual[i] - obj.forecast[i]) / maxErr);
}
console.log( ((100 * error) / size).toFixed(3), '%' );
}
const testCases = [
{
actual: [2354493, 2615706, 1594281, 1570894, 1930709, 2086681],
forecast: [2354493, 2224360.55, 1906806.9, 1408769.93, 1609053.96, 2200698.72],
limits: [0, 5e6] // [0, 5000000]
},
{
actual: [77, 50, 38, 30, 26, 18],
forecast: [77, 81.13, 92.77, 101.98, 119.76, 121.26],
limits: [0, 2e2] // [0, 200]
},
{
actual: [1.15, 1.09, 1.08, 0.78, 0.51, 0.44],
forecast: [1.15, 1.61, 1.88, 2.13, 2.3, 2.47],
limits: [0, 3e0] // [0, 3]
},
// extra cases
{
actual: [0, 0, 0],
forecast: [1, 1, 1],
limits: [0, 1e0]
},
{
actual: [1, 1, 1],
forecast: [1, 1, 1],
limits: [0, 1e9]
}
];
testCases.forEach(computeError); // calls computeError function on each object
一种愚蠢但实用的方法是简单地考虑误差,根据您喜欢的样本和预测之间的任何距离计算 (标准 1、标准 2 等等)
然后通过您选择的函数将结果值映射到区间 [0;1](满足 f:[0; infty]->[0;1])
例如:
f(err) = e^(-x^2/a^2) with a of your choice
在您的代码中,可能类似于
var err = computeMse(a,b)
function toPercent(err){
const a = 1;
return Math.exp(-x*x/a*a);
}
var percent = toPercent(err)