我本月挑戰的動機是讓您超越異常值的傳統定義,將其視為遠離資料中心的觀察值(相對於資料變異量)。 一般來說,我們可以將異常值視為非代表性資料點,即不屬於其餘資料的資料點。 真正的挑戰在於:我們如何定義代表性? 我在下面提供的方法是我對這個問題的看法。
下面的演算法根據點之間的距離將觀察結果分為相似組和不相似組。 與標準的凝聚聚類方法不同,從一組開始。 將分割點定義為相距最遠的觀測值之間的中間值,前提是它們的距離超過 75 個觀測值之間差異的三倍th所有非零距離的分位數和中位數(距離分佈)。 如果沒有切點,則停止。 否則,用兩個新組取代現有組。 使用新組或整個資料集的距離分佈(以較大者為準),對每個新組重複上述過程。 繼續下去,直到沒有群組包含分割點。
findOutliers = Function({vals},{Default Local},
q1 = 3; //Spread Multiplier
q2 = 0.75; //Quantile to define upper bound of spread
distSpread = 0;
nMissing = 0;
tmpTbl = New Table("tmp",New Column("C1",Values(vals)),Private);
sumTbl = tmpTbl << Summary(Group(:C1),Private);
vals = Column(sumTbl,1) << Get Values;
freqs = Column(sumTbl,2) << Get Values;
If(N Row(Loc(vals)) == 1, Return([]));
Close(tmpTbl,No Save);
If(Is Missing(vals[1]),
nMissing = freqs[1];
freqs = freqs[2::N Row(vals)];
vals = vals[2::N Row(vals)];
);
vals = Sort Ascending(vals[Loc Nonmissing(vals)]);
groups = Eval List({vals});
cutPoints = [];
While(N Items(groups) > 0,
newGroups = {};
For Each({nextVals},groups,
distances = nextVals[2::N Row(nextVals)] - nextVals[1::(N Row(nextVals)-1)];
distSpread = Max(distSpread,Median(distances[Loc(distances>0)]) + q1*(Quantile(q2,distances[Loc(distances>0)]) - Median(distances[Loc(distances>0)])));
maxDist = Maximum(distances);
If(maxDist>distSpread,
cutID = Loc(distances==maxDist)[1];
cutPoints |/= (nextVals[cutID+1]+nextVals[cutID])/2;
If(cutID == 1,
Insert Into(newGroups,nextVals[2::N Row(nextVals)]),//ELSE
If(cutID == N Row(distances),
Insert Into(newGroups,nextVals[1::cutID]),
//ELSE
Insert Into(newGroups,nextVals[1::cutID]);
Insert Into(newGroups,nextVals[(cutID+1)::N Row(nextVals)]);
)
)
);
);
groups = newGroups;
);
cutPoints = Sort Ascending(cutPoints);
cutPoints;
);
首先,需要進行一些內務處理來繞過單一值的資料。 根據結果挑戰9 ,我使用 Summary 同時查找資料中的唯一值並對其進行排序。 透過將向量偏移一並取其差來找到距離。 此演算法透過收集分割點並丟棄沒有分割點的群組來進行。 這一直持續到沒有組留下為止。
該演算法相當快,大約需要 1.6 秒來處理所有資料列探測我的機器上的範例資料資料表。 在演算法的頂部,我添加了兩個變量,讓您可以更改 3x 乘數和 75 th分位數。 在下面附加的腳本中,挑戰 11 異常值篩選,我添加了一些額外的窗口裝飾以提供一些介面,允許選擇列並產生包含摘要資訊和直方圖的報告窗口,並將切點繪製為參考線。
我將從 JMP 挑戰賽中抽出一段時間來從事另一個腳本專案。 我將為小型專案整理書面說明和視頻,以幫助新用戶和中級用戶提高他們的 JSL 技能。 我將重點放在常見操作,例如將表放在一起、從多個來源存取資料、建立自訂報告等。 我還將嘗試從事一些更高級的工作,例如表達式處理和模式匹配。 如果您認為有任何有價值的內容,請在此處發布,或向我發送社群訊息或電子郵件( don.mccormack@jmp.com )。