使用accord.net将数据分类为已知模式

时间:2017-11-19 22:32:23

标签: c# machine-learning classification hidden-markov-models accord.net

首先我要说的是,我对机器学习的了解非常非常有限。但我想我可以利用我的情况来学习它。

我的问题域演变了18种众所周知的模式。这些模式一旦在系统中创建,就按照它们的顺序分配给用户。

现在的重点是从不同的系统导入用户数据,并且模式信息不包含在其中。存在模式以确保每个用户获得工作计划。对于正在导入的用户,我必须通过观察他们的时间表来确定他们的模式。重要的是要注意,他们当前的时间表完全不符合任何已知模式是很常见的,所以我要做的就是找到最可能已知的模式。

通过Accord的分类分类器阅读我认为序列分类可能非常适合这个问题,所以我尝试使用它,如下所示:

class Program
{
    static void Main(string[] args)
    {
        int[][] inputs =
        {
            new[] {1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 3, 3, 3, 3, 3, 1, 1}, //pattern 1
            new[] {1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 3, 3, 3, 3, 3, 1}, //pattern 2
            new[] {1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 3, 3, 3, 3, 3}, //pattern 3
            new[] {3, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 3, 3, 3, 3}, //pattern 4
            new[] {3, 3, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 3, 3, 3}, //pattern 5
            new[] {3, 3, 3, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 3, 3}, //pattern 6
            new[] {3, 3, 3, 3, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 3}, //pattern 7
            new[] {3, 3, 3, 3, 3, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1}, //pattern 8
            new[] {1, 3, 3, 3, 3, 3, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1}, //pattern 9
            new[] {1, 1, 3, 3, 3, 3, 3, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1}, //pattern 10
            new[] {1, 1, 1, 3, 3, 3, 3, 3, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1}, //pattern 11
            new[] {1, 1, 1, 1, 3, 3, 3, 3, 3, 1, 1, 1, 1, 2, 2, 2, 2, 2}, //pattern 12
            new[] {2, 1, 1, 1, 1, 3, 3, 3, 3, 3, 1, 1, 1, 1, 2, 2, 2, 2}, //pattern 13
            new[] {2, 2, 1, 1, 1, 1, 3, 3, 3, 3, 3, 1, 1, 1, 1, 2, 2, 2}, //pattern 14
            new[] {2, 2, 2, 1, 1, 1, 1, 3, 3, 3, 3, 3, 1, 1, 1, 1, 2, 2}, //pattern 15
            new[] {2, 2, 2, 2, 1, 1, 1, 1, 3, 3, 3, 3, 3, 1, 1, 1, 1, 2}, //pattern 16
            new[] {2, 2, 2, 2, 2, 1, 1, 1, 1, 3, 3, 3, 3, 3, 1, 1, 1, 1}, //pattern 17
            new[] {1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 3, 3, 3, 3, 3, 1, 1, 1} //pattern 18
        };

        int[] outputs =
        {
            0, 
            1,
            2,
            3,
            4,
            5,
            6,
            7,
            8,
            9,
            10,
            11,
            12,
            13,
            14,
            15,
            16,
            17
        };

        int[][] actualData =
        {
            new[] {3,3,1,1,1,1,2,2,2,2,2,1,1,1,1,3,3,3} // should be pattern 5
        };

        // Create the Hidden Conditional Random Field using a set of discrete features
        var function = new MarkovDiscreteFunction(states: 3, symbols: 3, outputClasses: 18);
        var classifier = new HiddenConditionalRandomField<int>(function);

        // Create a learning algorithm
        var teacher = new HiddenResilientGradientLearning<int>(classifier)
        {
            MaxIterations = 1000
        };

        // Run the algorithm and learn the models
        teacher.Learn(inputs, outputs);

        // Compute the classifier answers for the given inputs
        int[] answers = classifier.Decide(actualData);

        foreach (var answer in answers)
        {
            Console.WriteLine(answer);
        }
    }
}

我期望输出为模式5,因为它们完全匹配,但事实并非如此。我尝试通过重复模式将模型与更多输入进行训练,将输入与正确的模式相关联。实际数据包含超过18个值。但它没有帮助它匹配,实际上使它“更糟”。

在我理想的情况下,程序将能够始终正确地猜测已知模式并找到与它们不匹配的数据中的最佳候选者。我在这里选择了错误的道路吗?

1 个答案:

答案 0 :(得分:0)

该示例代码在Accord 3.8中引发了异常。如果更改以下行,它将在执行18次迭代后执行并预测正确的类:

var function = new MarkovDiscreteFunction(states: 18, symbols: 18, outputClasses: 18)