我正在尝试确定双打列表中是否存在数据异常值。基本上,如果任何东西低于10%的限制或高于90%。我有以下代码工作,但它与负数无法正常工作,我没有看到有什么问题。有没有更好的方法来接近那里,或者代码或数学中是否有明显的东西?
public bool DataHasOutliers(IEnumerable<double> results, Limits limits)
{
foreach (double result in results)
{
//detect if any result values are in the low or high regions of the acceptable limits
double deltaAbsolute = (limits.High - limits.Low) < 0 ? (limits.High - limits.Low) * -1 : limits.High - limits.Low;
double absoluteResult = result < 0 ? result * -1 : result;
double lowLimitAbsolute = limits.Low < 0 ? limits.Low * -1 : limits.Low;
double upperThreshold = 0.9 * deltaAbsolute + limits.Low;
double lowerThreshold = 0.1 * deltaAbsolute + limits.Low;
if (absoluteResult >= upperThreshold)
{
"".Dump("Upper threshold violated");
return true;
}
if (absoluteResult <= lowerThreshold)
{
"".Dump("Lower threshold violated");
return true;
}
}
return false;
}
public class Limits
{
public double High { get; set; }
public double Low { get; set; }
public string Error { get; set; }
}
答案 0 :(得分:2)
如果限制为[-10, 0]
且结果为-5
,则使用当前代码,您有效地检查5
是否在[11, 19]
中,这是不正确。
我建议保持边界的符号增加/减少它们的范围的1/10,然后在这个减小的范围内检查原始结果值:
double deltaAbsolute = Math.Abs(limits.High - limits.Low);
double lowerThreshold = limits.Low + 0.1 * deltaAbsolute;
double upperThreshold = limits.High - 0.1 * deltaAbsolute;
if (result >= upperThreshold)
{
"".Dump("Upper threshold violated");
return true;
}
if (result <= lowerThreshold)
{
"".Dump("Lower threshold violated");
return true;
}
答案 1 :(得分:0)
为什么要在循环中重新计算限制。
如果高>那么你不需要任何绝对的东西。
public bool DataHasOutliers(IEnumerable<double> results, Limits limits)
{
if(limits.High < limits.Low)
{
throw new ArgumentOutOfRangeException();
}
double delta = limits.High - limits.Low;
double upperThreshold = 0.9 * delta + limits.Low;
double lowerThreshold = 0.1 * delta + limits.Low;
foreach (double result in results)
{
//detect if any result values are in the low or high regions of the acceptable limits
if (result >= upperThreshold)
{
"".Dump("Upper threshold violated");
return true;
}
if (result <= lowerThreshold)
{
"".Dump("Lower threshold violated");
return true;
}
}
return false;
}