Простой пример машинного обучения в согласии.net

Я новичок в машинном обучении и новичок в accord.net (пишу на C#).

Я хочу создать простой проект, в котором я просматриваю простые временные ряды данных, которые колеблются, а затем хочу, чтобы accept.net изучил их и предсказал, каким будет следующее значение.

Вот как должны выглядеть данные (временной ряд):

X – Y

1 - 1

2 - 2

3 - 3

4 - 2

5 - 1

6 - 2

7 - 3

8 - 2

9 - 1

Затем я хочу, чтобы он предсказывал следующее:

X – Y

10 - 2

11 - 3

12 - 2

13 - 1

14 - 2

15 - 3

Можете ли вы, ребята, помочь мне с некоторыми примерами того, как это решить?


person RHC    schedule 13.11.2016    source источник


Ответы (1)


Простой способ сделать это — использовать дерево решений Accord ID3.

Хитрость заключается в том, чтобы решить, какие входные данные использовать — вы не можете просто тренироваться на X — дерево ничего не узнает о будущих значениях X из этого — однако вы можете построить некоторые функции, полученные из X (или предыдущих значений Y ) будет полезно.

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

Я попытался построить дерево решений Accord ID3, чтобы решить эту проблему ниже. Я использовал несколько разных значений x % n в качестве функций, надеясь, что дерево сможет найти ответ на основе этого. На самом деле, если бы я добавил (x-1) % 4 в качестве функции, он мог бы сделать это на одном уровне только с этим атрибутом, но я думаю, что смысл в том, чтобы позволить дереву найти шаблоны.

И вот код для этого:

    // this is the sequence y follows
    int[] ysequence = new int[] { 1, 2, 3, 2 };

    // this generates the correct Y for a given X
    int CalcY(int x) => ysequence[(x - 1) % 4];

    // this generates some inputs - just a few differnt mod of x
    int[] CalcInputs(int x) => new int[] { x % 2, x % 3, x % 4, x % 5, x % 6 };


    // for http://stackoverflow.com/questions/40573388/simple-accord-net-machine-learning-example
    [TestMethod]
    public void AccordID3TestStackOverFlowQuestion2()
    {
        // build the training data set
        int numtrainingcases = 12;
        int[][] inputs = new int[numtrainingcases][];
        int[] outputs = new int[numtrainingcases];

        Console.WriteLine("\t\t\t\t x \t y");
        for (int x = 1; x <= numtrainingcases; x++)
        {
            int y = CalcY(x);
            inputs[x-1] = CalcInputs(x);
            outputs[x-1] = y;
            Console.WriteLine("TrainingData \t " +x+"\t "+y);
        }

        // define how many values each input can have
        DecisionVariable[] attributes =
        {
            new DecisionVariable("Mod2",2),
            new DecisionVariable("Mod3",3),
            new DecisionVariable("Mod4",4),
            new DecisionVariable("Mod5",5),
            new DecisionVariable("Mod6",6)
        };

        // define how many outputs (+1 only because y doesn't use zero)
        int classCount = outputs.Max()+1;

        // create the tree
        DecisionTree tree = new DecisionTree(attributes, classCount);

        // Create a new instance of the ID3 algorithm
        ID3Learning id3learning = new ID3Learning(tree);

        // Learn the training instances! Populates the tree
        id3learning.Learn(inputs, outputs);

        Console.WriteLine();
        // now try to predict some cases that werent in the training data
        for (int x = numtrainingcases+1; x <= 2* numtrainingcases; x++)
        {
            int[] query = CalcInputs(x);

            int answer = tree.Decide(query); // makes the prediction

            Assert.AreEqual(CalcY(x), answer); // check the answer is what we expected - ie the tree got it right
            Console.WriteLine("Prediction \t\t " + x+"\t "+answer);
        }
    }

Это вывод, который он производит:

                 x   y
TrainingData     1   1
TrainingData     2   2
TrainingData     3   3
TrainingData     4   2
TrainingData     5   1
TrainingData     6   2
TrainingData     7   3
TrainingData     8   2
TrainingData     9   1
TrainingData     10  2
TrainingData     11  3
TrainingData     12  2

Prediction       13  1
Prediction       14  2
Prediction       15  3
Prediction       16  2
Prediction       17  1
Prediction       18  2
Prediction       19  3
Prediction       20  2
Prediction       21  1
Prediction       22  2
Prediction       23  3
Prediction       24  2

Надеюсь, это поможет.

РЕДАКТИРОВАТЬ: после комментариев ниже пример изменен для обучения предыдущим значениям цели (Y), а не функциям, полученным из временного индекса (X). Это означает, что вы не можете начать обучение в начале своей серии, так как вам нужна предыстория предыдущих значений Y. В этом примере я начал с x = 9 только потому, что это сохраняет ту же последовательность.

        // this is the sequence y follows
    int[] ysequence = new int[] { 1, 2, 3, 2 };

    // this generates the correct Y for a given X
    int CalcY(int x) => ysequence[(x - 1) % 4];

    // this generates some inputs - just a few differnt mod of x
    int[] CalcInputs(int x) => new int[] { CalcY(x-1), CalcY(x-2), CalcY(x-3), CalcY(x-4), CalcY(x - 5) };
    //int[] CalcInputs(int x) => new int[] { x % 2, x % 3, x % 4, x % 5, x % 6 };


    // for http://stackoverflow.com/questions/40573388/simple-accord-net-machine-learning-example
    [TestMethod]
    public void AccordID3TestTestStackOverFlowQuestion2()
    {
        // build the training data set
        int numtrainingcases = 12;
        int starttrainingat = 9;
        int[][] inputs = new int[numtrainingcases][];
        int[] outputs = new int[numtrainingcases];

        Console.WriteLine("\t\t\t\t x \t y");
        for (int x = starttrainingat; x < numtrainingcases + starttrainingat; x++)
        {
            int y = CalcY(x);
            inputs[x- starttrainingat] = CalcInputs(x);
            outputs[x- starttrainingat] = y;
            Console.WriteLine("TrainingData \t " +x+"\t "+y);
        }

        // define how many values each input can have
        DecisionVariable[] attributes =
        {
            new DecisionVariable("y-1",4),
            new DecisionVariable("y-2",4),
            new DecisionVariable("y-3",4),
            new DecisionVariable("y-4",4),
            new DecisionVariable("y-5",4)
        };

        // define how many outputs (+1 only because y doesn't use zero)
        int classCount = outputs.Max()+1;

        // create the tree
        DecisionTree tree = new DecisionTree(attributes, classCount);

        // Create a new instance of the ID3 algorithm
        ID3Learning id3learning = new ID3Learning(tree);

        // Learn the training instances! Populates the tree
        id3learning.Learn(inputs, outputs);

        Console.WriteLine();
        // now try to predict some cases that werent in the training data
        for (int x = starttrainingat+numtrainingcases; x <= starttrainingat + 2 * numtrainingcases; x++)
        {
            int[] query = CalcInputs(x);

            int answer = tree.Decide(query); // makes the prediction

            Assert.AreEqual(CalcY(x), answer); // check the answer is what we expected - ie the tree got it right
            Console.WriteLine("Prediction \t\t " + x+"\t "+answer);
        }
    }

Вы также можете рассмотреть возможность обучения различиям между предыдущими значениями Y, что будет лучше работать, когда абсолютное значение Y не так важно, как относительное изменение.

person reddal    schedule 13.11.2016
comment
Это великолепно, я многому научился из этого примера (как создавать входные и выходные данные). Пример работал отлично. Но в реальном случае я не могу использовать значение X для расчетов, так как это временной ряд (например, x1 = 3:00, x2 = 4:00, x3 = 5:00), поэтому у меня есть только временной ряд всех значений Y и хотите найти здесь шаблон, чтобы помочь предсказать, каким будет следующее значение Y .... если это имеет смысл? - person RHC; 26.11.2016
comment
Конечно, более естественно использовать предыдущие значения цели (Y) для временных рядов - по крайней мере, когда фактическое время не имеет значения, а связь между значениями - это то, где лежит шаблон. - person reddal; 26.11.2016
comment
Я отредактирую ответ, чтобы добавить, как можно изменить пример для обучения предыдущим значениям Y. - person reddal; 26.11.2016
comment
Большое спасибо, я очень ценю ваш быстрый ответ и помощь. БЛАГОДАРЮ ВАС. - person RHC; 26.11.2016
comment
Спасибо @reddal, если выходные данные Y являются реальными числами и нет определенного числа для подсчета классов, что вы предлагаете делать. например у нас есть ряд чисел, таких как {0,4, 0,9, 0,3, 1,2, 0,7}, и теперь мы хотим предсказать следующее значение. - person Yashil; 12.01.2017
comment
Я использую SimpleLinearRegression, может быть есть лучший способ. - person Yashil; 12.01.2017
comment
Не могли бы вы предложить фреймворк и образцы ML в соответствии с некоторыми конкретными проблемами, пожалуйста? Итак, мы поняли проблему, мы знаем, как готовить входные значения, мы знаем, какой алгоритм выбран для прогнозирования, и мы можем попытаться что-то предсказать. Спасибо! - person DmitryBoyko; 22.10.2018