2016-11-13 5 views
5

Я новичок в обучении машинам и новичок в accord.net (код C#).Простой пример обучения машинам в формате .cd

Я хочу создать простой проект, где я смотрю на простой временной ряд данных, которые колеблются, а затем я хочу, чтобы accord.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 

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

ответ

9

Простым способом сделать это было бы использование дерева решений соглашения 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 не так важно, как относительное изменение.

+0

Это замечательно, я много наклоняюсь из этого примера (как создавать входы и выходы) Пример работал отлично. Но в «реальном случае» я не могу использовать значение X для вычислений, так как это временная серия (например, x1 = 3:00 AM, x2 = 4: 00am, x3 = 5: 00am), поэтому я только имеют временную серию всех значений Y и хотите найти здесь, чтобы помочь предсказать, что будет следующим значением Y .... если это произойдет? – RHC

+0

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

+0

Я отредактирую ответ, чтобы добавить, как пример может быть изменен для обучения по предыдущим значениям Y. – reddal

Смежные вопросы