Projekt

Obecné

Profil

Stáhnout (8.17 KB) Statistiky
| Větev: | Tag: | Revize:
1 ebe96ca4 Roman Kalivoda
//
2
// Author: Roman Kalivoda
3
//
4
5
using System;
6
using System.Collections.Generic;
7 d358b79e Roman Kalivoda
using ServerApp.Connection.XMLProtocolHandler;
8 ce0940b5 Roman Kalivoda
using ServerApp.Parser.Parsers;
9
using Newtonsoft.Json;
10
using ServerApp.WeatherPredictionParser;
11 870cd163 Roman Kalivoda
using ServerApp.Parser.OutputInfo;
12 0d31f7e0 Roman Kalivoda
using System.Reflection;
13
using log4net;
14 ebe96ca4 Roman Kalivoda
15
namespace ServerApp.Predictor
16
{
17
    /// <summary>
18
    /// Implentation of the <c>IPredicitionController</c> interface.
19
    /// </summary>
20 ce0940b5 Roman Kalivoda
    public class PredictionController : IPredictionController
21 ebe96ca4 Roman Kalivoda
    {
22 0d31f7e0 Roman Kalivoda
        private static readonly ILog _log = LogManager.GetLogger(typeof(PredictionController));
23
24 ebe96ca4 Roman Kalivoda
        /// <summary>
25 ce0940b5 Roman Kalivoda
        /// Configuration of the <c>Predictor</c>
26 ebe96ca4 Roman Kalivoda
        /// </summary>
27 ce0940b5 Roman Kalivoda
        private PredictorConfiguration Configuration;
28 ebe96ca4 Roman Kalivoda
29 ce0940b5 Roman Kalivoda
        private List<IPredictor> Predictors;
30 ebe96ca4 Roman Kalivoda
31
        /// <summary>
32
        /// A reference to a data parser.
33
        /// </summary>
34 ce0940b5 Roman Kalivoda
        private IDataParser DataParser;
35 ebe96ca4 Roman Kalivoda
36
        /// <summary>
37
        /// A feature extractor instance.
38
        /// </summary>
39 ce0940b5 Roman Kalivoda
        private FeatureExtractor FeatureExtractor;
40
41
        /// <summary>
42
        /// A weather prediction parser service
43
        /// </summary>
44
        private IJsonParser weatherService;
45 870cd163 Roman Kalivoda
46 ebe96ca4 Roman Kalivoda
        /// <summary>
47
        /// Instantiates new prediction controller.
48
        /// </summary>
49
        /// <param name="dataParser">A data parser used to get training data.</param>
50 ce0940b5 Roman Kalivoda
        public PredictionController(IJsonParser weatherService, IDataParser dataParser, string pathToConfig = null)
51 ebe96ca4 Roman Kalivoda
        {
52 0d31f7e0 Roman Kalivoda
            _log.Info("Constructing a new PredictionController instance.");
53 870cd163 Roman Kalivoda
            this.weatherService = weatherService;
54 cdeee9f8 Roman Kalivoda
            // load config or get the default one
55
            if (pathToConfig is null)
56
            {
57
                pathToConfig = PredictorConfiguration.DEFAULT_CONFIG_PATH;
58
            }
59
            try
60
            {
61
                string json = System.IO.File.ReadAllText(pathToConfig);
62
                this.Configuration = JsonConvert.DeserializeObject<PredictorConfiguration>(json);
63 0d31f7e0 Roman Kalivoda
            }
64
            catch (System.IO.IOException e)
65 cdeee9f8 Roman Kalivoda
            {
66 29a3f064 Roman Kalivoda
                Console.WriteLine("Warning: could not find a configuration file, creating a new one:");
67
                Console.WriteLine(e.Message.PadLeft(4));
68 cdeee9f8 Roman Kalivoda
                this.Configuration = PredictorConfiguration.GetDefaultConfig();
69
            }
70
71
            this.DataParser = dataParser;
72
            this.Predictors = new List<IPredictor>();
73
            this.FeatureExtractor = new FeatureExtractor(this.DataParser, this.Configuration);
74 22211075 Roman Kalivoda
75 cdeee9f8 Roman Kalivoda
            for (int i = 0; i < this.Configuration.PredictorCount; i++)
76 ebe96ca4 Roman Kalivoda
            {
77 ce0940b5 Roman Kalivoda
                Predictors.Add(new NaiveBayesClassifier());
78 ebe96ca4 Roman Kalivoda
            }
79 ce0940b5 Roman Kalivoda
            PredictorConfiguration.SaveConfig(PredictorConfiguration.DEFAULT_CONFIG_PATH, Configuration);
80 ebe96ca4 Roman Kalivoda
        }
81
        public List<string> GetPredictors()
82
        {
83 ce0940b5 Roman Kalivoda
            return new List<string>(this.Configuration.BuildingsToAreas.Keys);
84 ebe96ca4 Roman Kalivoda
        }
85
86
        public void Load(string locationKey = null, string path = null)
87
        {
88
            if (locationKey is null)
89
            {
90
                throw new NotImplementedException();
91
            }
92
            else
93
            {
94
                throw new NotImplementedException();
95
            }
96
        }
97
98 d358b79e Roman Kalivoda
        public Response Predict(Request request)
99 ebe96ca4 Roman Kalivoda
        {
100 0d31f7e0 Roman Kalivoda
            _log.Info($"Received a prediction request: endDate={request.useEndDate}, weather={request.useWeather}");
101 870cd163 Roman Kalivoda
            DateTime start = new DateTime(year: request.start.year, month: request.start.month, day: request.start.day, hour: request.start.hour, minute: 0, second: 0);
102
            List<Prediction> predictions = new List<Prediction>();
103
            if (request.useEndDate)
104
            {
105
                DateTime end = new DateTime(year: request.end.year, month: request.end.month, day: request.end.day, hour: request.end.hour, minute: 0, second: 0);
106
                DateTime current = start;
107
                while (current < end)
108
                {
109 0d31f7e0 Roman Kalivoda
                    _log.Debug($"Predicting for date {current.Date.ToShortDateString()}");
110 870cd163 Roman Kalivoda
                    while (current.Hour < Date.MAX_HOUR)
111
                    {
112 0d31f7e0 Roman Kalivoda
                        _log.Debug($"Predicting for time {current.TimeOfDay.ToString()}");
113 870cd163 Roman Kalivoda
                        var prediction = PredictSingle(request, current);
114
                        predictions.Add(prediction);
115
                        current = current.AddHours(this.Configuration.TimeResolution);
116
                    }
117
                    current = current.AddHours(23 - current.Hour + Date.MIN_HOUR);
118
                }
119 0d31f7e0 Roman Kalivoda
            }
120
            else
121 870cd163 Roman Kalivoda
            {
122 0d31f7e0 Roman Kalivoda
                _log.Debug("Predicting for single DateTime.");
123
                predictions.Add(PredictSingle(request, start));
124 870cd163 Roman Kalivoda
            }
125
            var response = new Response();
126
            response.hoursPerSegment = Configuration.TimeResolution;
127
            response.predicitons = predictions.ToArray();
128 0d31f7e0 Roman Kalivoda
            _log.Debug($"Created a response.");
129 870cd163 Roman Kalivoda
            return response;
130 ebe96ca4 Roman Kalivoda
        }
131
132 870cd163 Roman Kalivoda
        private Prediction PredictSingle(Request request, DateTime current)
133
        {
134
            double[] predictedValues = new double[this.Configuration.BuildingsToAreas.Count];
135
            string[] predictedLabels = new string[this.Predictors.Count];
136
            for (int i = 0; i < this.Predictors.Count; i++)
137
            {
138
                if (request.useWeather)
139
                {
140 0d31f7e0 Roman Kalivoda
                    _log.Debug("Predicting for requested weather.");
141 870cd163 Roman Kalivoda
                    predictedLabels[i] = this.Predictors[i].Predict(new ModelInput
142
                    {
143
                        Rain = (float)request.rain,
144
                        Temp = (float)request.temperature,
145
                        Wind = (float)request.wind,
146
                        Hour = current.Hour,
147
                        Time = current
148
                    });
149
                }
150
                else
151
                {
152 0d31f7e0 Roman Kalivoda
                    _log.Debug("Retrieving weather info from the weather service.");
153
                    weatherService.ParsePrediction();
154 1f1235a8 Roman Kalivoda
                    WeatherInfo weatherInfo = weatherService.Predictions.Find(info => info.startTime.Equals(current));
155
                    if (weatherInfo is null)
156 870cd163 Roman Kalivoda
                    {
157 1f1235a8 Roman Kalivoda
                        predictedLabels[i] = null;
158
                    }
159
                    else
160
                    {
161
                        predictedLabels[i] = this.Predictors[i].Predict(new ModelInput
162
                        {
163
                            Rain = weatherInfo.rain,
164
                            Temp = (float)weatherInfo.temp,
165
                            Wind = (float)weatherInfo.wind,
166
                            Hour = current.Hour,
167
                            Time = current
168
                        });
169
                    }
170 870cd163 Roman Kalivoda
                }
171
            }
172
            for (int i = 0; i < predictedValues.Length; i++)
173
            {
174 1f1235a8 Roman Kalivoda
                predictedValues[i] = this.FeatureExtractor.LabelToRatio(predictedLabels[this.Configuration.BuildingsToAreas[TagInfo.buildings[i]]]);
175 870cd163 Roman Kalivoda
            }
176
177
            Prediction prediction = new Prediction();
178
            prediction.dateTime = new Date
179
            {
180
                year = current.Year,
181
                month = current.Month,
182
                day = current.Day,
183
                hour = current.Hour
184
            };
185
            prediction.predictions = predictedValues;
186 0d31f7e0 Roman Kalivoda
            _log.Debug($"Created prediction for DateTime: {prediction.dateTime}");
187 870cd163 Roman Kalivoda
            return prediction;
188
        }
189 ebe96ca4 Roman Kalivoda
190
        public void Train(string locationKey = null)
191
        {
192
            if (locationKey is null)
193
            // train all predictors
194
            {
195 ce0940b5 Roman Kalivoda
                DataParser.Parse(DateTime.MinValue, DateTime.MaxValue, this.Configuration.TimeResolution, wholeDay: false);
196
                for (int i = 0; i < this.Predictors.Count; i++)
197 ebe96ca4 Roman Kalivoda
                {
198 662b2404 Roman Kalivoda
                    // train on all available data
199 ce0940b5 Roman Kalivoda
                    List<ModelInput> data = FeatureExtractor.PrepareTrainingInput(i);
200
                    Console.WriteLine("Training predictor with {0} samples.", data.Count);
201
                    this.Predictors[i].Fit(data);
202 ebe96ca4 Roman Kalivoda
                }
203 ce0940b5 Roman Kalivoda
            }
204
            else
205 ebe96ca4 Roman Kalivoda
            // train specified predictor only
206
            {
207
                throw new NotImplementedException();
208
            }
209
        }
210
211
212
    }
213
}