Плотность числового ряда - страница 3

 
Vladimir:
Вспомнил один способ кластеризации. Как-то так: в множестве выделяются группы элементов (кластеры), такие, что максимальное расстояние между элементами одного кластера меньше минимального расстояния от любого элемента этого кластера до элемента, не входящего в этот кластер. Расстояние можно брать обычное, модуль разности вещественных чисел. Конечно, такой кластер будет не обязательно один. Может быть, Вам и не нужна ровно одна группа, может, их стоит сравнивать друг с другом еще и по другим признакам. Например, среднее время возникновения уровня в группе.

Это интересно, но пока не получается понять, как определить, что числа в кластере - путем тупого перебора? Тогда, предположу, появятся группы, которые будут наслаиваться друг на друга так как, если определять кластер путем поиска наименьшей дельты, но большей по отношению к остальным элементам, то выкидывая из такого кластера часть элементом мы будем смещать сам кластер - тут важны будут расстояния между кластерами, если он существенны, то все должно получиться.

 

Vladimir:

Расстояние между двумя точками на вещественной оси мы все измеряем как модуль их разности. В математике это принято называть метрикой. Как измерять расстояние на плоскости между  точками, парами чисел, каждое из которых вещественное? Опять у нас есть готовое привычное решение - евклидово расстояние, корень квадратный из суммы квадратов покоординатных разностей. А у математиков есть и другие метрики на плоскости, например, наибольший модуль из двух разностей, сумма модулей разностей (http://ad.cctpu.edu.ru/Math_method/math/45.htm). И это всего лишь в случае пар чисел. Только двух чисел, и всегда двух. А Вам нужно ввести меру близости в гораздо более сложной ситуации. В группе не два числа, и в разных группах их разное число.

 Нам надо определить наибольшую группу, или одинаковые группы по количеству элементов в них. Моим недостатком является неумение правильно читать сложные формулы, поэтому приходиться все пытаться понять из примеров и комментариев к ним.

 

Vladimir:

Есть в математике метрики, измеряющие расстояние между двумя функциями. Но вновь, всегда между двумя. Опять Вам не подходит, у вас группа.

Вот почему важно самому досконально понять, что именно нужно. Пишите, может быть, удастся это формализовать до алгоритма получения числовой характеристики близости в множестве.

Однако подумайте и об отказе от попыток ее создать. В ссылке выше сказано, каким требованиям должна удовлетворять метрика. Они не сдуру там появились, без любого из них будут возникать странные эффекты. Сообщением выше я привел пример, как отказаться от столь всеобъемлющих попыток - пусть точки в группе будут ближе попарно друг к другу на вещественной оси, чем к элементам вне точки. Не надо будет изобретать что-то очень нетривиальное.

 Так правильно, первоначально мы и определяем близость двух точек, а потом пытаемся исключить то расстояние, которое велико - в этом и вопрос, как определить велико это расстояние или нет? Именно на этом сейчас алгоритм дал сбой - при появлении расстояния на порядок больше.

 
Dmitry Fedoseev:
Не написал - сначала разницы посчитать. Потом все остальное. 
Так разницы посчитали в столбце "Дельта", что делать дальше предлагаете?
 

Тестирую такой алгоритм фильтрации данных перед обработкой:

1. Суммируем  последовательно две дельты и умножаем значение на два

2. Находим среднее значение получившегося числового ряда

3. Составляем новый числовой ряд, если значение меньше среднего значения

4. Повторяем пункт 2-3 пока числовой ряд не будет меньше половины первоначального ряда


№ П./П.ЧислоДельта53,3325,829,60
1 10        
2 20 10      
3 30 10 40 40  
4 40 10 40 40  
5 50 10 40 40  
6 51 1 22 22 22
7 52 1 4 4 4
8 53 1 4 4 4
9 54 1 4 4 4
10 60 6 14 14 14
11 70 10 32 32  
12 80 10 40 40  
13 120 40 100    
14 150 30 140    
15 190 40 140    
16 210 20 120    
17 223 13 66    
18 232 9 44 44  
19 250 18 54    
20 260 10 56    

 5. После фильтрации делаем уже расчет по вышеописанному алгоритму

№ П./П.ЧислоДельтаБлизкие значенияБлизость подрядМаксимальноеПлотныеПлотностьПлотность v2
1 40       4      
2 50 10 0 0   50    
3 51 1 1 1   51 0,80 1,00
4 52 1 1 2   52    
5 53 1 1 3   53    
6 54 1 1 4   54    
7 60 6 0 0        

Пробовал разные цифры - получался правдоподобный вариант, буду рад услышать критические замечания.
 
-Aleks-:
Так разницы посчитали в столбце "Дельта", что делать дальше предлагаете?
А что вы кругами ходите? Уже давно написано здесь
 
Dmitry Fedoseev:
А что вы кругами ходите? Уже давно написано здесь

 

Здесь Вы утверждаете "Наиболее длинный участок, когда исходный ряд ниже среднего.", но это, как я понял, недостаток моего алгоритма, после чего принято решение сделать фильтр - я его сделал и теперь алгоритм не тупит так очевидно, когда числа существенно отличаются друг от друга.

 
-Aleks-:

 

Здесь Вы утверждаете "Наиболее длинный участок, когда исходный ряд ниже среднего.", но это, как я понял, недостаток моего алгоритма, после чего принято решение сделать фильтр - я его сделал и теперь алгоритм не тупит так очевидно, когда числа существенно отличаются друг от друга.

В чем недостаток то?

Фильтр не является заменителем алгоритма. Фильтр является добавлением к алгоритму.

 
Dmitry Fedoseev:

В чем недостаток то?

Фильтр не является заменителем алгоритма. Фильтр является добавлением к алгоритму.

Недостаток я не знаю в чём - мне его может быть пока и не видно.

Думаю, что теперь надо попробовать это закодировать - поможете, если у меня возникнут трудности? 

 
-Aleks-:

Недостаток я не знаю в чём - мне его может быть пока и не видно.

Думаю, что теперь надо попробовать это закодировать - поможете, если у меня возникнут трудности? 

Сначала начните. А то может и не возникнет трудностей. Но раньше времени я не буду думать ни о чем, а то который раз выясняется, что я то не о том думаю то не так думаю... 
 
Dmitry Fedoseev:
а то который раз выясняется, что я то не о том думаю то не так думаю... 
Это и делает людей уникальными...
 

Приступил к разработке алгоритма - пока делаю фильтр. Возникла сложность в синхронизации двух столбцов - "Число" и "Дельта"

Буду рад идеям, как устранить неточность:

 

//+------------------------------------------------------------------+
//|                                              Test_FindOblast.mq4 |
//|                        Copyright 2017, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   int massivSize=19; //размер массива  
   double Digit[19]=
     {
      10,
      20,
      30,
      40,
      50,
      51,
      52,
      53,
      54,
      60,
      70,
      80,
      120,
      150,
      190,
      210,
      223,
      232,
      250,
      260
     };
   double summDelta[19-1];
   int N=massivSize-1;//Количество оставшихся цифровых значений
   double avrMass=0;//Среднее значение массива дельт

//-Фильтр
//1. Суммируем  последовательно две дельты и умножаем значение на два
   for(int i=1;i<massivSize;i++)
     {
      summDelta[i-1]=((Digit[i]-Digit[i-1])+(Digit[i+1]-Digit[i]))*2;
     }
   for(int i=0;i<massivSize-1;i++) printf("summDelta[%d] = %G",i,summDelta[i]);

//2. Находим среднее значение получившегося числового ряда
//3. Составляем новый числовой ряд, если значение меньше среднего значения
//4. Повторяем пункт 2-3 пока числовой ряд не будет меньше половины первоначального ряда
   for(int Z=0;N>massivSize/2;Z++)
     {
      int SizeMass=ArraySize(summDelta);//Узнаем размер массива
      avrMass=iMAOnArray(summDelta,0,SizeMass,0,0,0);
      Print("Среднее значение получившегося числового ряда",Z,"=",avrMass);

      for(int i=0;i<SizeMass;i++)
        {            
         if(summDelta[i]>avrMass)
           {
            summDelta[i]=0;
            Digit[i]=0;
            N--;
           }
        }

         Print("N=",N);
         ArraySort(summDelta,WHOLE_ARRAY,0,MODE_DESCEND);
         ArraySort(Digit,WHOLE_ARRAY,0,MODE_DESCEND);
         if(N!=0)
           {
            ArrayResize(summDelta,N,0);
            for(int i=0;i<N;i++) printf("summDelta[%d] = %G",i,summDelta[i]);
            ArrayResize(Digit,N+1,0);
            for(int i=0;i<N+1;i++) printf("Digit[%d] = %G",i,Digit[i]);          
           }
         else
           {
            for(int i=0;i<N;i++) printf("summDelta[%d] = %G",i,summDelta[i]);            
            for(int i=0;i<N+1;i++) printf("Digit[%d] = %G",i,Digit[i]);  
            return;
           }
     }
      int SizeMass=ArraySize(summDelta);//Узнаем размер массива
      avrMass=iMAOnArray(summDelta,0,SizeMass,0,0,0);
      Print("Среднее значение получившегося числового ряда=",avrMass);

//-Основной алгоритм
//1. Находим разницу между числами - это как раз их близость друг от друга.

//2. Если число меньше среднего значения дельт, получившихся из п.1, то - 1, а если нет - 0.

//3. Если значение из п.2 равно 1, то суммируем значение с предыдущим итогом, если нет - 0.

//4. Находим максимальное значение из пункта 3.

//5. Определяем диапазон - находим значение из пункта 4 и ищем вверх из пункта 3 число с нулевым значением, потом увеличиваем найденное число на единицу.
//Таким образом мы получаем диапазон чисел, плотность которых наибольшая по отношению к другим.
  }
//+------------------------------------------------------------------+
Причина обращения: