我有一個十進制數字的有序資料集。這些資料總是相似的——但并不總是相同的。預期資料是幾個 0 - 5 個大數字,然后是幾個 (10 - 90) 平均數字,然后是較小的數字。在某些情況下,平均數字中可能會混入大量數字'請參閱以下陣列。
let expectedData = [35.267,9.267,9.332,9.186,9.220,9.141,9.107,9.114,9.098,9.181,9.220,4.012,0.132];
let expectedData = [35.267,32.267,9.267,9.332,9.186,9.220,9.141,9.107,30.267,9.114,9.098,9.181,9.220,4.012,0.132];
我試圖通過獲取前面沒有高數字和后面數字低的平均值來分析資料。中間高/低可以保持在平均水平。我在下面有一個部分解決方案。現在我有點強迫它,但解決方案并不完美。在較小的資料集上,第一次平均計算受到大數字的影響。
我的問題是: 有沒有辦法處理這類問題,即識別數字陣列中的模式?
我的演算法是:
- 獲取陣列的平均值
- 計算高于/低于平均值
- 洗掉高于平均水平的前 (n) 個元素
- 洗掉低于平均水平的結束元素
- 重新計算平均值
在 JavaScript 中我有:(這是部分遺漏低于平均水平)
let total= expectedData.reduce((rt,cur)=> {return rt cur;}, 0);
let avg = total/expectedData.length;
let aboveAvg = avg*0.1 avg;
let remove = -1;
for(let k=0;k<expectedData.length;k ) {
if(expectedData[k] > aboveAvg) {
remove=k;
} else {
if(k==0) {
remove = -1;//no need to remove
}
//break because we don't want large values from middle removed.
break;
}
}
if(remove >= 0 ) {
//remove front above average
expectedData.splice(0,remove 1);
}
//remove belows
//recalculate average
uj5u.com熱心網友回復:
我相信您正在尋找一些例外值檢測演算法。Stack Overflow 上已經有很多與此相關的問題。
然而,每種例外值檢測演算法都有其自身的優點。
這里有幾個
https://mathworld.wolfram.com/Outlier.html
高例外值是第三個四分位數 1.5 * 四分位數間距 (IQR) 之外的任何值
低例外值是第一個四分位數以下的任何值 - 1.5 * IQR
格拉布斯的測驗
- 您可以在這里查看它如何滿足您的期望
除了這 2 個,這里是一個比較計算器。您可以訪問它以根據需要使用其他演算法。
uj5u.com熱心網友回復:
我會嘗試獲得一個與滯后/帶濾波器相結合的滑動視窗,以便首先檢測高值峰值。
然后,當您的滑動視窗前進時,您可以將之前的第一個值(現在是分析值中的最后一個)添加到全域總和中,并將總值的數量加 1。
當您遇到峰值(=導致滯后移動或溢位帶狀濾波器的東西)時,您可以洗掉這些值(可能代價高昂),或者更好的是,將值設定為,NaN以便您可以安全地忽略它。
您應該在滑動視窗內繼續計算滑動平均值,以便能夠自動更正滯后/頻帶濾波器,因此它只會拒絕峰值的起始值(結束值是下一個峰值的起始值) ,但是一旦值穩定到一個新的水平,值將再次保持。
滑動視窗的大小將設定需要保持多少連續的“穩定”值,或者換句話說,當你達到一個新的水平時,有多少 UNstable 值被拒絕。
uj5u.com熱心網友回復:
為此,您可以檢查值的模式(四舍五入),然后取模式周圍某個范圍內的所有數字。該范圍可以取自資料本身,例如通過取值10%的max - min。這可以幫助您過濾資料。您可以選擇適合您需要的百分比。像這樣的東西:
let expectedData = [35.267,9.267,9.332,9.186,9.220,9.141,9.107,9.114,9.098,9.181,9.220,4.012,0.132];
expectedData.sort((a, b) => a - b);
/// Get the range of the data
const RANGE = expectedData[ expectedData.length - 1 ] - expectedData[0];
const WINDOW = 0.1; /// Window of selection 10% from left and right
/// Frequency of each number
let dist = expectedData.reduce((acc, e) => (acc[ Math.floor(e) ] = (acc[ Math.floor(e) ] || 0) 1, acc), {});
let mode = Object.entries(dist).sort((a, b) => b[1] - a[1])[0][0];
let newData = expectedData.filter(e => mode - RANGE * WINDOW <= e && e <= mode RANGE * WINDOW);
console.log(newData);
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/452514.html
標籤:javascript 算法
下一篇:R:定制旅行商問題
