2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу Пред.  1, 2, 3, 4, 5  След.
 
 Re: Экстрополяция двоичной последовательности
Сообщение05.03.2010, 12:09 
Супермодератор
Аватара пользователя


29/07/05
8248
Москва
Скажите честно, Вы хотите предсказывать рост/падение курсов валют или что-нибудь в этом роде?

 Профиль  
                  
 
 Re: Экстрополяция двоичной последовательности
Сообщение05.03.2010, 12:13 


03/03/10
26
ИСН в сообщении #294757 писал(а):
Именно это она и делает. И именно она Вам и нужна.


1010101

По предложенному алгоритму после 1 должна быть единичка, поскольку 1 встречается чаще.
НО не факт, что это правильно, поскольку после 1 всегда идет 0, то с большей вероятностью, можно предположить, что для данной последовательности скорее всего после 1 будет стоять ноль!

Тут надо статистику скрещивать с марковостью ...
Нет опыта с нейросетями, но возможно они тоже могут помочь ...

-- Пт мар 05, 2010 12:19:26 --

PAV в сообщении #294760 писал(а):
Скажите честно, Вы хотите предсказывать рост/падение курсов валют или что-нибудь в этом роде?


Да, но не финансовые показатели, а некие физические процессы.

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

Я не хочу отходить от темы форума. Мне все равно нужен алгоритм или программа для экстраполяции двоичной последовательности.

 Профиль  
                  
 
 Re: Экстрополяция двоичной последовательности
Сообщение05.03.2010, 12:22 
Супермодератор
Аватара пользователя


29/07/05
8248
Москва
Iura в сообщении #294761 писал(а):
По предложенному алгоритму после 1 должна быть единичка, поскольку 1 встречается чаще.


Ничего подобного. Вы просто не просекли суть алгоритма.

-- Пт мар 05, 2010 12:24:28 --

Iura в сообщении #294761 писал(а):
Я не хочу отходить от темы форума. Мне все равно нужен алгоритм или программа для экстраполяции двоичной последовательности.


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

 Профиль  
                  
 
 Re: Экстрополяция двоичной последовательности
Сообщение05.03.2010, 12:27 


03/03/10
26
PAV в сообщении #294765 писал(а):
Iura в сообщении #294761 писал(а):
По предложенному алгоритму после 1 должна быть единичка, поскольку 1 встречается чаще.


Ничего подобного. Вы просто не просекли суть алгоритма.

-- Пт мар 05, 2010 12:24:28 --

Iura в сообщении #294761 писал(а):
Я не хочу отходить от темы форума. Мне все равно нужен алгоритм или программа для экстраполяции двоичной последовательности.


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


нашел новое описание
http://ltwood.wikidot.com/heshby:shannon

Возможно и был не прав

 Профиль  
                  
 
 Re: Экстрополяция двоичной последовательности
Сообщение06.03.2010, 07:46 


03/03/10
26
Нашел что искал - "Прогнозирование стохастических последовательностей" (http://www.mathnet.ru/php/getFT.phtml?j ... n_lang=rus), но есть проблема - я не математик и мне сложно понять всех деталей статьи. Кто нибудь может помочь выделить из статьи "выделить" алгоритм (для написания программы) для прогнозирования ?

 Профиль  
                  
 
 Re: Экстрополяция двоичной последовательности
Сообщение06.03.2010, 11:38 
Супермодератор
Аватара пользователя


29/07/05
8248
Москва
По-моему, с прикладной точки зрения эта статья бесполезна.

 Профиль  
                  
 
 Re: Экстрополяция двоичной последовательности
Сообщение06.03.2010, 12:18 


03/03/10
26
:( но само направление верное

 Профиль  
                  
 
 Re: Экстрополяция двоичной последовательности
Сообщение19.03.2010, 18:12 
Заслуженный участник


26/07/09
1559
Алматы
Поигрался немножко на выходных с гадалкой и появилось непреодолимое желание ещё пофлудить в этой темке, хоть она, возможно, уже и успела уплыть за пределы актуальности.

2Iura
Цитата:
Нашел что искал - "Прогнозирование стохастических последовательностей"

Нашли что искать. :) За мозгодробительными формулировками этой статьи, по-сути, скрывается оптимистичное заключение о разрешимости вашей задачи. Да и заканчивается она немного с черным юморком как-то, "Во время работы над этой статьей умер _ Колмогоров".

Цитата:
нашел новое описание
http://ltwood.wikidot.com/heshby:shannon

О, а мне понравился подход автора этой программульки с выбором оптимальных параметров гадалки (количества учитываемых ходов, как человека так и собственных).

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

Но сначала напишу простейший неинтерактивный вариант гадалки (одна штука; учет двух ходов с каждой стороны), играющей против генератора псевдослучайных чисел и печатающей качество предсказания в процентах (пример на C):
код: [ скачать ] [ спрятать ]
Используется синтаксис C
#include <stdio.h>
#include <stdlib.h>

int S[2][2][3][3][2], a[3], b[3];

int main(void)
{
    int i, *p, c=0;

    for(i=0; i<350; i++)
    {
        p=S[a[1]] [a[2]] [b[1]] [b[2]];
        a[0]=a[1]; a[1]=a[2]; b[0]=b[1]; b[1]=b[2];
        if((a[2]=rand()%2)==(b[2]=p[0]==p[1]?2:p[0]<p[1])) c++;
        p[a[2]]++;
    }

    printf("%d%%", 100*c/i);

    return 0;
}
 


  • (Оффтоп)

    Кстати, есть сомнения в правильности понимания мной алгоритма Гадалки Шеннона. Если что не так, поправьте меня, пожалуйста (человекочитабельный и обобщенный вариант, не страдающий от синдрома запиндюривания всего кода в одну строку, см. ниже).

  • (Оффтоп)

    Младшие биты числа, возвращенного rand()'ом нешибко-то случайны. Увеличится ли "случайность" бит (эксперимент показывает, что да) если их значения получать по-прежнему как rand()%2, но предварительно делать ещё один вызов этой функции вхолостую, i.e. на деле использовать значение выражения (rand(), rand()%2)?

А вот пример (в этот раз на C++) предиктора на основе набора гадалок (с различными параметрами, и, соответственно, с различной предсказательной способностью относительно данной последовательности):
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
#include <deque>
#include <map>
#include <vector>
#include <algorithm>
#include <functional>
#include <numeric>
#include <cstdlib>

namespace Fun
{
    int TossACoin() {return rand()%2;}

    // "Abstract" predictor.
    class cPredictor
    {
        public:
            cPredictor():
                CorrectPredictionsCount(0),
                PredictionsCount(0),
                PredictedValue(0) {}

            int Predict() {return NewPrediction(0);};

            void Correct(int RealBit)
            {
                if(PredictedBit()==RealBit) CorrectPrediction();
            };

            // Returns the rate (quality) of correct predictions.
            int Rate() const
            {
                if(!PredictionsCount) return 0; // Prevent div by zero.

                return 100*CorrectPredictionsCount/PredictionsCount;
            }

        protected:
            void CorrectPrediction() {CorrectPredictionsCount++;}

            int NewPrediction(int PredictedBit)
            {
                PredictionsCount++;

                return PredictedValue=PredictedBit;
            }

            int PredictedBit() const {return PredictedValue;};

        private:
            int CorrectPredictionsCount, PredictionsCount, PredictedValue;
    };

    struct cCheater: cPredictor
    {
        int Predict() {return NewPrediction(TossACoin());};
    };

    class cDaemon: public cPredictor
    {
        public:
            explicit cDaemon
                (
                    int RealBits=2,
                    int PredictedBits=2,

                    // Factor of "forgetfulness."
                    float CorrectingFactor=1,

                    // Minimal difference between probabilities.
                    float Threshold=0
                ):
                    LastBits(RealBits+PredictedBits+2, 0),
                    CorrectingFactor(CorrectingFactor),
                    Threshold(Threshold) {}

            // Returns the most probable value of the next bit.
            int Predict()
            {
                // Forget old bits.
                LastBits.pop_front();
                LastBits.pop_front();

                // Just find a desired value in the
                // associative array Statistics.
                return NewPrediction(Statistics[LastBits].Value(Threshold));
            }

            // Adjusts the statistical model.
            void Correct(int RealBit)
            {
                if(PredictedBit()==RealBit) CorrectPrediction();

                // Remember that current real bit follows
                // the bits from LastBits.
                // FIXME: Reference to Statistics[LastBits] can be cached.
                Statistics[LastBits].Correct(RealBit, CorrectingFactor);

                // Save (in stack-like LastBits) RealBit &
                // PredictedBit for future use.
                LastBits.push_back(RealBit);
                LastBits.push_back(PredictedBit());
            }

            int Weight() const {return LastBits.size()-2;}

        private:

            // FIXME: How to "parametrize" this class with
            //        CorrectingFactor & Threshold?
            class cPrediction
            {
                public:
                    cPrediction():
                        One(0),
                        Zero(0),
                        Increment(1) {}

                    void Correct(int Bit, float CorrectingFactor)
                    {
                        // This can improve (when CorrectingFactor>1)
                        // prediction quality by reducing the
                        // influence of very old bits.
                        Increment*=CorrectingFactor;

                        // Increase the probability of a given
                        // bit at the next trials.
                        Bit? One+=Increment: Zero+=Increment;
                    }

                    int Value(float Threshold) const
                    {
                        // Try to predict the next bit by comparing
                        // probabilities of each case.
                        if(One-Zero>Threshold) return 1;
                        if(Zero-One>Threshold) return 0;

                        return 2; // Uncertain result.
                    }

                private:
                    float One, Zero, Increment, CorrectingFactor, Threshold;
            };

            // FIXME: There is a more efficient way to store these bits.
            typedef std::deque<int> cBits;

            // FIXME: A container std::map is too slow, use
            //        something like hash_map instead.
            typedef std::map<cBits, cPrediction> cStatistics;

            // The stochastic model of an input sequence.
            cStatistics Statistics;

            // Last bits, both real and predicted.
            cBits LastBits;

            float CorrectingFactor, Threshold;
    };

    // FIXME: What about multithreading?
    class cSupervisor: public cPredictor
    {
        public:
            explicit cSupervisor
                (
                    int MaximalRealBits,
                    int MaximalPredictedBits,
                    bool OptimizeCorrectingFactor=false
                )
            {
                // Create daemons with all possible
                // values of the parameters.
                // FIXME: Does the STL provide means to
                //        deal with Cartesian product?
                for(int i=0; i<MaximalRealBits; i++)
                    for(int j=0; j<MaximalPredictedBits; j++)
                        if(OptimizeCorrectingFactor)
                            for(float k=1; k<2; k+=0.05)
                                Daemons.push_back(cDaemon(i, j, k));
                        else
                            Daemons.push_back(cDaemon(i, j));
            }

            int Predict()
            {
                // Find the best daemon and ask for prediction.
                // FIXME: Function std:: max_element is very suitable here
                //        but it's so difficult to express appropriate
                //        comparison criterion...
                return NewPrediction(std::accumulate
                    (
                        Daemons.begin(),
                        Daemons.end(),
                        (int)2,
                        Rating()
                    ));
            }

            void Correct(int RealBit)
            {
                if(PredictedBit()==RealBit) CorrectPrediction();

                // Simply dispatch RealBit to each daemon.
                std::for_each
                    (
                        Daemons.begin(),
                        Daemons.end(),
                        std::bind2nd // Yes, it's currying.
                            (
                                std::mem_fun_ref(&cDaemon::Correct),
                                RealBit
                            )
                    );
            }

        private:
            std::vector<cDaemon> Daemons;

            struct Rating: std::binary_function<int, cDaemon, int>
            {
                Rating(): Rate(-1), Weight(0) {}

                int operator () (int LastPrediction, cDaemon &Daemon)
                {
                   int Rate=Daemon.Rate(),
                       Weight=Daemon.Weight(),
                       Prediction=Daemon.Predict();

                   if(Rate>this->Rate||Rate==this->Rate&&Weight<this->Weight)
                   {
                       // Store the best results.
                       this->Rate=Rate;
                       this->Weight=Weight;

                       return Prediction;
                   }

                   return LastPrediction;
                }

                private: int Rate, Weight;
            };
    };
}
 


N.B., это очень "тормознутая" реализация и предназначена только для демонстрации. Буду рад если кто-нибудь перепишет/исправит/доработает приведенный мной код.

Третий параметр (CorrectingFactor) в конструкторе cDaemon'а позволяет улучшить качество предсказания за счет забывания начала игры (значение параметра для этого должно быть немного больше единицы). Четвертый параметр (Threshold) равен минимальной разнице между вероятностями значений следующего хода, т.е., если вероятности (частоты) различаются незначительно, то гадалка дает неопределнный ответ (по-умолчанию этот параметр равен нулю и неопределенный ответ дается только в случае полной равноправности ожидаемых значений предсказываемого хода).

Пример игры против ГПСЧ:
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
#include <iostream>

const int IterationsCount=350;

int main()
{
    Fun::cSupervisor Supervisor(5, 5, true);

    for(int Counter=0; Counter<IterationsCount; Counter++)
    {
        Supervisor.Predict();
        Supervisor.Correct(Fun::TossACoin());
    }

    std::cout << "Prediction quality is "
        << Supervisor.Rate() << '%' << std::endl;

    return 0;
}
 


В только что приведеном примере можно заменить cSupervisor на cCheater (i.e. предиктор, пытающийся угадать последовательность "подбрасыванием монетки") и убедиться, что при игре ГПСЧ vs. ГПСЧ качество угадывание составляет 50% (вполне логично). Также можно заменить cSupervisor на cDaemon и увидеть, что качество предсказаний уменьшилось (опять ожидаемый результат).

Пример игры против человека:
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
#include <iostream>

int main()
{
    Fun::cSupervisor Supervisor(5, 5, true);

    while(1)
    {
        int Prediction=Supervisor.Predict();
        std::cout << "> ";
        int Real;
        std::cin >> Real;
        Supervisor.Correct(Real);
        std::cout << "Prediction: " << Prediction << std::endl;
    }

    return 0;
}
 


P.S.:
Немного отойду от основной темы. Все тот-же ltwood, автор heshby, утверждает, что человеку обыграть его программку не так-то просто. Ok, согласен. Также программульке туго приходится против ГПСЧ. Это понятно. Но, мне кажется, простой способ почти честно обыграть heshby существует и он очень прост. Действительно, что если заставить играть гадалку против аналогичной гадалки, но инвертирующей свои предсказания?

То есть, чтобы победить, просто запускаем две копии программки и пытаемся предсказать с помощью одной из них предсказания другой, после чего вбиваем противоположный ответ в атакуемую гадалку. :) Возможна ли такая стратегия (типа антигравитации Мюнхгаузена)?

В любом случае, представляется разумной концепция игры одного предсказателя против другого. В общем, что если написать некую функцию Fun::Play(...), которая будет принимать в своих аргументах двух предсказателей и возвращать качество игры, ну допустим, первого из них? Можно, например, заставить играть cCheater'а против себя: Fun::Play(Fun::cCheater(), Fun::cCheater(), ...); или устроить поединок cDaemon vs. cCheater: Fun::Play(Fun::cDaemon(10, 10), Fun::cCheater(), ...); или же организовать игру с человеком: Fun::Play(Fun::cSupervisor(5, 5, true), Fun::сPerson()). Я не реализовал пока такую функцию из-за сложностей с неопределенными ответами (ответ 2).

P.P.S.:
Вообще, думаю, тема предсказания (экстраполяции) последовательностей далеко не исчерпывается простейшими алгоритмами вроде Гадалки Шеннона и дискуссия может быть продолжена.

(Оффтоп)

А нельзя ли темку двинуть в дискуссионные или в cs (после чего удалить эту просьбу :) )?

 Профиль  
                  
 
 Re: Экстрополяция двоичной последовательности
Сообщение19.03.2010, 19:23 
Супермодератор
Аватара пользователя


29/07/05
8248
Москва
 i  Тема перенесена в корневой раздел Computer Scienceх.

 Профиль  
                  
 
 Re: Экстрополяция двоичной последовательности
Сообщение19.03.2010, 20:01 
Заслуженный участник


26/07/09
1559
Алматы
Есть ли связь между предсказанием очередных битов последовательности и задачей сжатия данных?

 Профиль  
                  
 
 Re: Экстрополяция двоичной последовательности
Сообщение19.03.2010, 22:12 


03/03/10
26
Circiter в сообщении #299473 писал(а):
Есть ли связь между предсказанием очередных битов последовательности и задачей сжатия данных?


Свези нет.

Проведу аналогию, но это только аналогия!

Представь, что у тебя есть оцифрованный радиосигнал. Сам сигнал близок к белому шуму, если рассматривать амплитуды в десятеричном представлении. Если смотреть на значения в двоичное представление, то наблюдается закономерность (пусть слабая, но все же).

Если я для примера перешлю данные для N бит, ты сможешь с помощью своего скрипта рассчитать значение N+1 бит?
Я бы это сделал сам, но не установлен на компе visual c++.

 Профиль  
                  
 
 Re: Экстрополяция двоичной последовательности
Сообщение19.03.2010, 23:09 
Заслуженный участник


26/07/09
1559
Алматы
2Iura
Цитата:
Свези нет.

Ну как же нет? Мне кажется, это почти одно и тоже. В самом деле, возможность предсказать очередную порцию данных свидетельствует об избыточности информации, а сжатие как раз таки и призвано с ней (избыточностью) бороться.

Предлагаю такой конструктивный пример-доказательство. Стохастический предсказатель легко переделать в простенький компрессор/архиватор (с потерями). Достаточно вычесть из каждого элемента последовательности (не обязательно бинарной) его предсказанное значение. Результирующая последовательность будет теперь состоять преимущественно из небольших (если предсказание было качественным) чисел (ошибок предсказаний). Теперь можно близкие к нулю элементы заменить нулями и получить легко (e.g., через RLE) сжимаемую разреженную последовательность. Ч.т.д. :)

Цитата:
Если я для примера перешлю данные для N бит, ты сможешь с помощью своего скрипта рассчитать значение N+1 бит?

С помощью моей программульки? Могу попробовать (только не знаю когда в следующий раз вылезу в интернет :) ). Можете прямо в этой теме данные выложить, модераторы стерпят. :) А я здесь же напишу результат, который смогут проверить другие участники (в том числе и вы). Ok?

А каковы, позвольте поинтересоваться, ваши успехи?

P.S.: Я все-же считаю, что предсказываться лучше будут исходные данные, без перевода в двоичное представление. В свою очередь предложу такую аналогию: как легче предсказать цвет пикселя на изображении, работая с самой матрицей пикселей или же с бинарным потоком соответствующего файла? Ответ очевиден... Структурированность информации очень помогает предсказанию, а "линеаризация" при переводе в двоичное представление делает последовательность гораздо менее предсказуемой (например, при сжатии/предсказании изображений важно учитывать именно двумерность информации).

 Профиль  
                  
 
 Re: Экстрополяция двоичной последовательности
Сообщение20.03.2010, 03:20 
Заслуженный участник


26/07/09
1559
Алматы
С предложенным в предыдущем сообщении алгоритмом компрессии, кажется, не все гладко. Нехватает комплементарного ему алгоритма распаковки. :) То есть, вроде-бы понятно, что нужно те-же действия в обратном порядке произвести, но вот с деталями не все ясно...

Дело в том, что для распаковки сжатой последовательности тоже нужен предсказатель, а для его работы нужна, по крайней мере, прореженная ("уменьшенная") копия исходного сигнала. При этом неочевидно, будут ли сжатая последовательность вместе с прореженной копией исходной весить меньше чем эта самая изначальная последовательность; то есть, неочевидно, действительно ли такой алгоритм является сжимающим... Хотелось бы услышать комментарии...

-- Сб мар 20, 2010 07:03:01 --

2Iura
Думаю, вам (да и мне :) ) не помешало бы раздобыть лекции по теории информации, теории кодирования. Вообще, такие темы как энтропийное кодирование, сжатие, избыточность, те же марковские процессы, теория игр, etc, имеют прямое отношение к обсуждаемому вопросу, уверяю вас. Короче говоря, пришли к тому, с чего тема начиналась. :)

 Профиль  
                  
 
 Экстрополяция битовой последовательности... и что лежит рядо
Сообщение20.03.2010, 04:06 


16/03/10
212
Может немного не в тему, (а может, и много :) ) но, возможно, интересный факт.
Пусть Юра генерирует битовую последовательнось, а Павел ее предсказывает. Если Паша угадал следующий бит, то Юра ему должен 1руб, если не угадал, то Паша должен Юре 1руб. Игра равная? Конечно.
Но вот пусть теперь Юра не знает о результате Пашиного угадывания на каждом шаге (расчет делает судья после N шагов в конце), А Паша знает каждый раз - угадал он или нет. Вопрос. Есть ли у Паши преимущество? Как ни странно, вроде, нет.

Еще один жизненный факт, который пользователю Iura не поможет, но все же...
В 60 (или 70)-х годах в Воронежском университете был один преподаватель (П), который предложил студентам написать на листе бумаге двоичную последовательность, как можно более случайную. Запрещено было пользоваться монетой, костями и прочими естественными датчиками случайных чисел. Потом П честно подал на вход своей волшебной программы (вы удивитесь, но уже тогда были компьютеры и программы!) эти биты по одному с целью предсказать каждый следующий бит. Так вот: П угадал не просто больше 50%, а сильно больше! Практически 90! Только у "самых умных" угадано было что-то типа 75%.

К чему это я? Да к тому, что если закономерность есть, то предсказать, наверное, можно сильно больше 80%.

А кстати, на вопрос, о том КАК именно из головы написать "наиболее случайную" битовую последовательность (с точки зрения алгоритмического предсказателя) тоже есть ответ, но это уже другая история...

 Профиль  
                  
 
 Re: Экстрополяция двоичной последовательности
Сообщение20.03.2010, 04:19 
Заслуженный участник


26/07/09
1559
Алматы
2VoloCh
Цитата:
А кстати, на вопрос, о том КАК именно из головы написать "наиболее случайную" битовую последовательность (с точки зрения алгоритмического предсказателя) тоже есть ответ, но это уже другая история...

А можно хотя-бы кусочек послушать?

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 70 ]  На страницу Пред.  1, 2, 3, 4, 5  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group