private static void DrawPlot(IList <DayInfo> days, IList <DayInfo> anomalies) { days = days.Where(x => x.Date >= new DateTime(2017, 9, 1) && x.Date <= new DateTime(2017, 9, 30)).ToList(); anomalies = anomalies.Where(x => x.Date >= new DateTime(2017, 9, 1) && x.Date <= new DateTime(2017, 9, 30)).ToList(); using (var plot = new PLStream()) { plot.sdev("pngcairo"); // png rendering plot.sfnam("data.png"); // output filename plot.spal0("cmap0_alternate.pal"); // alternate color palette plot.init(); plot.env( 1, // x-axis range days.Count, 0, // y-axis range 150, AxesScale.Independent, // scale x and y independently AxisBox.BoxTicksLabelsAxes); // draw box, ticks, and num ticks plot.lab( "Date", // x-axis label "Count", // y-axis label "Press releases September 2017"); // plot title plot.line( (from x in Enumerable.Range(1, days.Count) select(double) x).ToArray(), (from p in days select(double) p.Count).ToArray()); // plot the spikes plot.col0(2); // blue color plot.schr(3, 3); // scale characters plot.string2( (from s in anomalies select(double) days.ToList().FindIndex(x => x.Date == s.Date) + 1).ToArray(), (from s in anomalies select(double) s.Count + 15).ToArray(), "↓"); plot.eop(); } }
/// <summary> /// The main program entry point. /// </summary> /// <param name="args">The command line parameters.</param> static void Main() { // create the machine learning context var context = new MLContext(); // load the data file Console.WriteLine("Loading data..."); var dataView = context.Data.LoadFromTextFile <SalesRecord>(path: dataPath, hasHeader: true, separatorChar: ','); // get an array of data points var sales = context.Data.CreateEnumerable <SalesRecord>(dataView, reuseRowObject: false).ToArray(); // plot the data var pl = new PLStream(); pl.sdev("pngcairo"); // png rendering pl.sfnam("data.png"); // output filename pl.spal0("cmap0_alternate.pal"); // alternate color palette pl.init(); pl.env( 0, 36, // x-axis range 0, 800, // y-axis range AxesScale.Independent, // scale x and y independently AxisBox.BoxTicksLabelsAxes); // draw box, ticks, and num ticks pl.lab( "Date", // x-axis label "Sales", // y-axis label "Shampoo sales over time"); // plot title pl.line( (from x in Enumerable.Range(0, sales.Count()) select(double) x).ToArray(), (from p in sales select(double) p.Sales).ToArray() ); // build a training pipeline for detecting spikes var pipeline = context.Transforms.DetectIidSpike( outputColumnName: nameof(SalesPrediction.Prediction), inputColumnName: nameof(SalesRecord.Sales), confidence: 95, pvalueHistoryLength: sales.Count() / 4); // 25% of x-range // train the model Console.WriteLine("Detecting spikes..."); var model = pipeline.Fit(dataView); // predict spikes in the data var transformed = model.Transform(dataView); var predictions = context.Data.CreateEnumerable <SalesPrediction>(transformed, reuseRowObject: false).ToArray(); // find the spikes in the data var spikes = (from i in Enumerable.Range(0, predictions.Count()) where predictions[i].Prediction[0] == 1 select(Day: i, Sales: sales[i].Sales)); // plot the spikes pl.col0(2); // blue color pl.schr(3, 3); // scale characters pl.string2( (from s in spikes select(double) s.Day).ToArray(), (from s in spikes select(double) s.Sales + 40).ToArray(), "!"); // build a training pipeline for detecting change points var pipeline2 = context.Transforms.DetectIidChangePoint( outputColumnName: nameof(SalesPrediction.Prediction), inputColumnName: nameof(SalesRecord.Sales), confidence: 95, changeHistoryLength: sales.Count() / 4); // 25% of x-range // train the model Console.WriteLine("Detecting change points..."); var model2 = pipeline2.Fit(dataView); // get predictions transformed = model2.Transform(dataView); predictions = context.Data.CreateEnumerable <SalesPrediction>(transformed, reuseRowObject: false).ToArray(); // find the change points in the data var changes = (from i in Enumerable.Range(0, predictions.Count()) where predictions[i].Prediction[0] == 1 select(Day: i, Sales: sales[i].Sales)); // plot the change points as vertical red lines pl.col0(3); foreach (var c in changes) { pl.line(new double[] { c.Day, c.Day }, new double[] { 0, 800 }); } pl.eop(); Console.WriteLine("Saved output file: data.png"); }
/// <summary> /// The main program entry point. /// </summary> /// <param name="args">The command line parameters.</param> static void Main() { // create the machine learning context var context = new MLContext(); // load the data file Console.WriteLine("Loading data..."); var dataView = context.Data.LoadFromTextFile <MeterData>(path: dataPath, hasHeader: true, separatorChar: ','); // get an array of data points var values = context.Data.CreateEnumerable <MeterData>(dataView, reuseRowObject: false).ToArray(); // plot the data var pl = new PLStream(); pl.sdev("pngcairo"); // png rendering pl.sfnam("data.png"); // output filename pl.spal0("cmap0_alternate.pal"); // alternate color palette pl.init(); pl.env( 0, 90, // x-axis range 0, 5000, // y-axis range AxesScale.Independent, // scale x and y independently AxisBox.BoxTicksLabelsAxes); // draw box, ticks, and num ticks pl.lab( "Day", // x-axis label "Power consumption", // y-axis label "Power consumption over time"); // plot title pl.line( (from x in Enumerable.Range(0, values.Count()) select(double) x).ToArray(), (from p in values select(double) p.Consumption).ToArray() ); // build a training pipeline for detecting spikes var pipeline = context.Transforms.SsaSpikeEstimator( nameof(SpikePrediction.Prediction), nameof(MeterData.Consumption), confidence: 98, pvalueHistoryLength: 30, trainingWindowSize: 90, seasonalityWindowSize: 30); // train the model Console.WriteLine("Detecting spikes..."); var model = pipeline.Fit(dataView); // predict spikes in the data var transformed = model.Transform(dataView); var predictions = context.Data.CreateEnumerable <SpikePrediction>(transformed, reuseRowObject: false).ToArray(); // find the spikes in the data var spikes = (from i in Enumerable.Range(0, predictions.Count()) where predictions[i].Prediction[0] == 1 select(Day: i, Consumption: values[i].Consumption)); // plot the spikes pl.col0(2); // blue color pl.schr(3, 3); // scale characters pl.string2( (from s in spikes select(double) s.Day).ToArray(), (from s in spikes select(double) s.Consumption + 200).ToArray(), "↓"); pl.eop(); }