代码之家  ›  专栏  ›  技术社区  ›  Malior

来自ml.net的正弦预测实际上不起作用

  •  0
  • Malior  · 技术社区  · 7 年前

    我目前正在尝试使用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 回复  |  直到 7 年前
        1
  •  0
  •   Gal Oshri    7 年前

    决策树不太擅长外推(即对训练数据范围之外的数据进行预测)。如果你对训练数据做出预测,分数将不会是恒定的,实际上会有点合理。

    将此问题转化为插值问题的一种方法是将所有输入映射到正弦函数的一个周期中的相应值。如果您添加另一个features列mod(x,2*pi),那么您也可以对测试数据进行很好的预测。

    推荐文章