C# 在一系列数字中查找异常
我有一张号码表C# 在一系列数字中查找异常,c#,C#,我有一张号码表 var nums = new List<double> {1,2,2.4,2.6,1.5,3,1.9}; var nums=新列表{1,2,2.4,2.6,1.5,3,1.9}; 假设列表中的项目正态分布;在这样的系列中,我想过滤掉异常(可以是1和3,因为它们似乎是偏差最大的值)。我必须处理动态序列,它们的值可能会发生变化,因此无法在条件检查中硬编码任何值。对您的请求有一个非常笼统的回答:您需要定义异常是什么。这是你的谓词。然后根据谓词过滤列表 var nums
var nums = new List<double> {1,2,2.4,2.6,1.5,3,1.9};
var nums=新列表{1,2,2.4,2.6,1.5,3,1.9};
假设列表中的项目正态分布;在这样的系列中,我想过滤掉异常(可以是
1
和3
,因为它们似乎是偏差最大的值)。我必须处理动态序列,它们的值可能会发生变化,因此无法在条件检查中硬编码任何值。对您的请求有一个非常笼统的回答:您需要定义异常是什么。这是你的谓词。然后根据谓词过滤列表
var nums = new List<double> {1,2,2.4,2.6,1.5,3,1.9};
Predicate<double> anomalyPredicate = IsNoAnomaly; // Definition of a predicate
List<double> listWithoutAnomalies= nums.FindAll(anomalyPredicate); // Find every item that is not an anomaly
var nums=新列表{1,2,2.4,2.6,1.5,3,1.9};
谓词异常预测=不正常;//谓词的定义
ListListWithoutExceptionals=nums.FindAll(异常预测);//找到所有不是异常的项目
让我们假设异常情况是数字为3或更大。那么你有:
private static bool IsNoAnomaly(double d)
{
return d < 3;
}
私有静态布尔值不正常(双d)
{
返回d<3;
}
但当然,ISNOA通常可能是任何布尔返回函数
编辑:另一个示例:如果在运行时确定了一个可能未达到或超过的阈值\u currentThreshold,则函数将为:
private static bool IsNoAnomaly(double d)
{
return d < _currentThreshold;
}
私有静态布尔值不正常(双d)
{
返回d<\u currentThreshold;
}
如果假定nums
项的分布为正态分布,我们可以将超出[mean-k*sigma..mean+k*sigma]
范围(sigma
代表标准偏差)的值视为异常值,其中k
通常为2
(95%),3
(99.76%),有时甚至5
。
如果是你的情况,你可以实施
public static IEnumerable<T> Anomaly<T>(IEnumerable<T> source,
Func<T, double> map,
double maxSigma = 3.0) {
if (null == source)
throw new ArgumentNullException("source");
else if (null == map)
throw new ArgumentNullException("map");
T[] data = source.ToArray();
if (data.Length <= 1)
yield break;
double s = 0.0;
double s2 = 0.0;
foreach (var item in data) {
double x = map(item);
s += x;
s2 += x * x;
}
double mean = s / data.Length;
double sigma = Math.Sqrt(s2 / data.Length - (s / data.Length) * (s / data.Length));
double leftMargin = mean - maxSigma * sigma;
double rightMargin = mean + maxSigma * sigma;
foreach (var item in data) {
double x = map(item);
if (x < leftMargin || x > rightMargin)
yield return item;
}
}
到目前为止您尝试过什么?定义“异常”以及为什么
1.5
也不是异常?我认为1.5和1.9是奇数,因为其余的将按升序排列,没有它们。你如何知道什么是异常,什么是正常的?你应用了什么逻辑,说“3”是异常?除非我了解到,我不确定是否能够帮助1
与3
以外的其他值保持距离,否则这也会是异常现象吗?这应该在不指定筛选值的情况下完成。可以。只需填写你需要的内容。不要写d<3,写你需要的任何东西,这只是一个例子。如果过滤器是可变值的,则写入d<\u currentFilterValue或其他内容。在我的情况下,将有一个值范围,我们不知道哪个值将是阈值。它完全是动态的。但您需要知道确定某个值是否在该范围内的算法。算法本身不可能是动态的。好吧,现在我明白OP的意思了…@Nebr:对于一些问题,水晶球是不可或缺的。。。我必须承认我有一个不公平的优势:我目前的项目是在一个电信数据库中进行异常检测。
var nums = new List<double> { 1, 2, 2.4, 2.6, 1.5, 3, 1.9 };
// k = 3 (typical criterium of 3 sigma deviation - 99.76%) - empty output
Console.Write(string.Join(", ", Anomaly(nums, x => x, 3)));
// k = 1 (unusual criterium of just 1 sigma deviation - 67%) the output is "1, 3"
Console.Write(string.Join(", ", Anomaly(nums, x => x, 1)));