这更像是一个算法问题,你说你有一个像4 6 2 4 9 5 23 54 33这样的模式,最后三个数字是一个热门。我想知道如何以编程方式(或数学方式)检测到这一点。
目前,我正在考虑使用尾随平均值来扫描数据,让我们说过去3个值。如果新值(23)突然远高于该平均值,我们标记可能连续的开始。下面的数字不应该偏离太多,以至于认为热潮仍在继续。
这听起来像是一种有效的方法吗?这些问题是否已存在任何算法?
答案 0 :(得分:4)
好的。我已经给了这个镜头但是在我开始之前我必须说这不是基于任何算法(至少:我没有故意将它基于现有算法)并且它有一些缺陷(它没有考虑到对于负数/零)并且可能有许多边缘情况需要解决。
为了找到两个数字之间的距离以确定它们是否相似我发现this simple formula:
百分比差异=(L - S)/ S
其中L代表“最大”,S代表“最小”。
首先,输出5个随机序列,其中50个值介于1和40之间:
7 14 34 13 4 1 3 34 10 29 25 32 28 39 14 32 37 30 21 27 28 27 26 25 27 34 15 36 3 29 32 35 8 32 20 5 30 4 17 16 27 35 7 34 7 37 14 31 38 23
Possible hot streak (treshold 0,95): 27 - 28 - 27
Possible hot streak (treshold 0,95): 28 - 27 - 26
Possible hot streak (treshold 0,95): 27 - 26 - 25
9 16 17 3 11 19 28 10 25 10 25 6 31 21 37 29 24 35 20 9 2 34 14 6 1 33 21 31 19 30 20 23 38 19 21 16 19 6 21 1 17 20 18 7 30 22 4 26 37 17
Possible hot streak (treshold 0,8): 17 - 20 - 18
14 18 12 30 22 15 3 12 3 18 38 36 31 35 30 3 8 13 39 21 11 19 14 19 31 22 16 7 15 19 29 34 33 2 16 3 12 8 37 6 14 7 4 4 2 21 29 22 17 27
Possible hot streak (treshold 0,8): 38 - 36 - 31
Possible hot streak (treshold 0,8): 36 - 31 - 35
Possible hot streak (treshold 0,8): 31 - 35 - 30
Possible hot streak (treshold 0,8): 29 - 34 - 33
14 31 26 16 6 35 5 32 38 39 38 35 36 24 29 4 3 29 20 28 31 39 15 34 8 4 15 11 18 11 32 34 30 28 5 38 9 17 35 21 37 19 9 37 8 18 11 20 14 37
Possible hot streak (treshold 0,95): 38 - 39 - 38
18 39 3 29 36 14 17 32 9 3 20 33 15 28 8 5 6 9 19 30 35 25 34 38 30 13 30 17 27 29 33 35 36 20 33 33 31 2 31 30 21 16 9 33 2 5 4 21 30 3
Possible hot streak (treshold 0,9): 33 - 35 - 36
Possible hot streak (treshold 0,9): 33 - 33 - 31
我合并的想法相当简单:给定一个项目列表,迭代它,从当前索引开始对前3个进行分组,看看它们是否在可接受的阈值范围内。如果是,请继续,直到找到当前阈值内的所有组合。如果没有设置阈值的组合,则从阈值中减去0.05(又名:更宽松)并重新开始。
应该注意,该算法基本上在序列中搜索标准化的值组。您可以通过以下方法改进: - 运行算法后 - 计算被视为热条纹的3个值的总和,并获取该阈值中值的最大总和。这应该给你最高的条件。所以这个算法的作用就是找到条纹,所有你要做的就是找到热条纹(这是微不足道的)。
还有一些方面可以改进,只采用周围值较低的序列,但这取决于您想要采用算法的距离。
这种方法的一个好处是它已经部分地这样做了(你会注意到序列通常位于总数据集的较高部分),因为用于确定两个数字之间差异的公式。
值3和2将返回0.5的百分比差异,而值30和29将为0.03,因此后者将更快地被算法拾取。在这方面,你已经自动收集热条纹,但它没有考虑周围的值,以便更加精确。
代码:
void Main()
{
for(int i = 0; i < 5; i++){
var list = GetList();
DisplayList(list);
GetHotStreaks(list);
}
}
private static Random rand = new Random();
private List<int> GetList(){
var list = new List<int>();
for(int i = 0; i < 50; i++){
list.Add(rand.Next(1, 40));
}
return list;
}
private void DisplayList(List<int> list){
for(int i = 0; i < list.Count; i++){
Console.Write(list[i] + " ");
}
Console.WriteLine();
}
private void GetHotStreaks(List<int> list){
double treshold = 0.95;
bool found = false;
while(treshold > 0.0){
for(int i = 0; i < list.Count - 2; i++){
if(AreWithinRange(list[i], list[i + 1], list[i + 2], treshold)){
Console.WriteLine (string.Format("Possible hot streak (treshold {0}): {1} - {2} - {3}", treshold, list[i], list[i + 1], list[i + 2]));
found = true;
}
}
if(found){
Console.WriteLine ();
return;
}
treshold -= 0.05;
}
}
private bool AreWithinRange(int val1, int val2, int val3, double treshold){
return AreWithinRange(val1, val2, treshold) && AreWithinRange(val2, val3, treshold);
}
// http://www.oracle.com/webfolder/technetwork/data-quality/edqhelp/Content/processor_library/matching/comparisons/percent_difference.htm
private bool AreWithinRange(int val1, int val2, double treshold){
double max = Math.Max(val1, val2);
double min = Math.Min(val1, val2);
double pd = (max - min) / min;
//Console.WriteLine ("Values: val1: {0}\t val2: {1}\t PD: {2}\t T: {3}", val1, val2, pd, treshold);
return pd <= 1 - treshold;
}
答案 1 :(得分:0)
我认为你应该看一下FIR filters,特别是离散时间FIR滤波器。
基本上它们是算法的通用版本(如果我理解正确的话)。
当条纹被视为 hot 时,您需要更严格地定义(如果您将其视为定性属性)。 FIR滤波器在信号处理中非常成熟,并且(如果使用正确的参数)基本上输出的分数等于当前条纹的热度。
这假设您没有对条纹长度施加任何严格限制,但您希望得分取决于条纹长度。
FIR也可以检测到被中断的条纹,我不确定你的用例中是否需要这样做。
我认为如果条纹突然没有启动,你的算法可能会出现问题,因此标记条纹开始的阈值可能不会超过。
答案 2 :(得分:0)
您的问题与股票交易商在寻找价格出现意外上涨(通常是成交量)的股票时所寻找的并不相同。
Moving averages 简单移动平均线只是平均过去的n个数字。相比之下,指数移动平均线对最后一个数字的加权比第一个更重。
我建议EMA与SMA的比率大于,比如说2表示热条纹。
人们也可以使用更短,更快移动的移动平均线而不是更长,更慢移动的平均值。当速度越快越慢时,你可能会开始寻找热条纹。
Oscillators 当价格位于其范围的顶部或底部时,振荡器可以通知您。
我建议相对强弱指数高于70表示热潮。