ML.NET的正弦预测无法真正发挥作用

时间:2018-10-17 15:12:16

标签: c# .net ml.net

我目前正在尝试ML.NET,但是在第一个项目中我陷入了困境。我正在尝试预测正弦值。

  1. 使用正弦函数(y = sin(x))生成X和Y值列表
  2. 使用该列表供ML.NET学习
  3. 对下一个X值进行Y预测
  4. 将这些预测添加到列表中

结果:对于以下任何数字,我总是得到一个结果。 正弦正像可变函数一样。

这是当前代码:

class Program
{
    private const string FILEPATH = @"sinus.txt";
    private const float XSTART = 0f;
    private const float XEND = 20f;
    private const float XSTEP = 0.1f;
    private const float XEND_FORECAST = 30f;

    static void Main(string[] args)
    {
        GenerateSinusList();

        var pipeline = new LearningPipeline();
        pipeline.Add(new TextLoader(FILEPATH).CreateFrom<Sinus>(separator: ';'));
        pipeline.Add(new ColumnConcatenator("Features", "X"));
        pipeline.Add(new FastTreeRegressor());

        var model = pipeline.Train<Sinus, SinusForecast>();
        PredictUpcomingValues(model);

        Console.WriteLine("done");
        Console.ReadLine();
    }

    static void PredictUpcomingValues(PredictionModel<Sinus, SinusForecast> model)
    {
        using (var sw = System.IO.File.AppendText(FILEPATH))
        {
            sw.WriteLine();
            for (double i = XEND + XSTEP; i < XEND_FORECAST; i += XSTEP)
            {
                var prediction = model.Predict(new Sinus() { X = (float)i });
                var t = string.Format("{0};{1}", i, prediction.ResultY);
                sw.WriteLine(t.Replace(',', '.')); //Quick localization fixSine
            }
            sw.Close();
        }
    }

    static void GenerateSinusList()
    {
        var sinus = GenerateSine(XSTART, XEND, XSTEP);
        var text = string.Join(System.Environment.NewLine, sinus.Select(x => string.Format("{0:};{1}", x.Key, x.Value)));
        System.IO.File.WriteAllText(FILEPATH, text.Replace(',', '.'));

    }

    static Dictionary<float, float> GenerateSine(float from, float to, float step)
    {
        Dictionary<float, float> result = new Dictionary<float, float>((int)((to - from) / step) + 1);

        for (double i = from; i < to; i += step)
        {
            result[(float)i] = (float)Math.Sin(i);
        }
        return result;
    }

    public class Sinus
    {
        [Column("0")]
        public float X;

        [Column("1", name: "Label")]
        public float Y;
    }

    public class SinusForecast
    {
        [ColumnName("Score")]
        public float ResultY;
    }

}

此结果:每个值> 20返回0.5429355。该列表如下所示:

  • ...
  • 19.4; 0.523066
  • 19.5; 0.6055401
  • 19.6; 0.6819639
  • 19.7; 0.7515736
  • 19.8; 0.8136739
  • 19.9; 0.8676443
  • 20.1; 0.5429355 <<先预测
  • 20.2; 0.5429355
  • 20.3; 0.5429355
  • 20.4; 0.5429355
  • 20.5; 0.5429355
  • 20.6; 0.5429355
  • ...

编辑:我正在使用ML 0.4.0

1 个答案:

答案 0 :(得分:0)

决策树在推算方面不是很擅长(即根据训练数据范围之外的数据进行预测)。如果您对训练数据进行预测,则分数将不会保持恒定,实际上会有些合理。

将其转化为插值问题的一种方法是,在正弦函数的一个周期内将所有输入映射到其对应的值。如果添加另一个功能列mod(X,2 * Pi),则对测试数据的预测也很好。