Projekt

Obecné

Profil

« Předchozí | Další » 

Revize 0060a0ae

Přidáno uživatelem Roman Kalivoda před téměř 4 roky(ů)

Re #9056 refactoring

Zobrazit rozdíly:

Server/ServerApp/Predictor/AnomalyDetectionResult.cs
1
//
2
// Author: Roman Kalivoda
3
//
4

  
5
using Microsoft.ML.Data;
6

  
7
namespace ServerApp.Predictor
8
{
9
    class AnomalyDetectionResult
10
    {
11
        [VectorType(3)]
12
        public double[] Prediction { get; set; }
13
    }
14
}
Server/ServerApp/Predictor/FeatureExtractor.cs
7 7
using ServerApp.Parser.Parsers;
8 8
using ServerApp.Parser.OutputInfo;
9 9
using System.Linq;
10
using Microsoft.ML;
11
using log4net;
10 12

  
11 13
namespace ServerApp.Predictor
12 14
{
......
15 17
    /// </summary>
16 18
    class FeatureExtractor
17 19
    {
20
        private static readonly ILog _log = LogManager.GetLogger(typeof(FeatureExtractor));
21

  
18 22
        /// <summary>
19 23
        /// A DataParser instance used to access info objects.
20 24
        /// </summary>
......
46 50
        /// <returns></returns>
47 51
        public List<ModelInput> PrepareTrainingInput(int area)
48 52
        {
49
            List<string> buildings = new List<string>();
53
            List<string> buildings = new List<string>(); 
54
            List<ActivityInfo> attendance = DataParser.AttendanceList;
50 55

  
51 56
            // find all buildings in area
52 57
            foreach (KeyValuePair<string, int> kvp in Configuration.BuildingsToAreas)
......
56 61
                    buildings.Add(kvp.Key);
57 62
                }
58 63
            }
59

  
60
            var res = new List<ModelInput>();
61
            foreach (WeatherInfo val in DataParser.WeatherList)
64
            List<ActivityInfo> activities = attendance.Where(e => buildings.Contains(e.building)).GroupBy(e => e.startTime).Select(g => g.Aggregate((a, b) => new ActivityInfo(null, a.amount + b.amount, a.startTime, -1))).OrderBy(e => e.startTime).ToList();
65
           activities = RejectOutliers(activities);
66
            var inputs = activities.Join(DataParser.WeatherList, activity => activity.startTime, weatherInfo => weatherInfo.startTime, (activity, weatherInfo) => new
62 67
            {
63
                res.Add(new ModelInput
68
                amount = activity.amount,
69
                modelInput = new ModelInput
64 70
                {
65
                    Time = val.startTime,
66
                    Temp = (float)val.temp,
67
                    Hour = val.startTime.Hour,
68
                    Wind = (float)val.wind,
69
                    Rain = (float)val.rain,
70
                });
71
                    Hour = activity.startTime.Hour,
72
                    Temp = (float)weatherInfo.temp,
73
                    Rain = (float)weatherInfo.rain,
74
                    Time = activity.startTime,
75
                    Wind = (float)weatherInfo.wind
76
                }
77
            }).ToList();
78

  
79
            int max = inputs.Select(e => e.amount).Max();
80
            foreach (var input in inputs)
81
            {
82
                double ratio = input.amount / (double)max;
83
                input.modelInput.Label = RatioToLabel(ratio);
71 84
            }
72 85

  
73
            List<ActivityInfo> attendance = DataParser.AttendanceList;
74
            foreach (ModelInput input in res)
86
            return inputs.Select(e => e.modelInput).ToList();
87
        }
88

  
89
        private static List<ActivityInfo> RejectOutliers(List<ActivityInfo> data)
90
        {
91
            MLContext mlContext = new MLContext();
92
            IDataView input = mlContext.Data.LoadFromEnumerable(data);
93
            var pipeline = mlContext.Transforms.Conversion.ConvertType(nameof(ActivityInfo.amount)).Append(mlContext.Transforms.DetectIidSpike(nameof(AnomalyDetectionResult.Prediction), nameof(ActivityInfo.amount), 99.0, data.Count / 4));
94
            ITransformer transformer = pipeline.Fit(mlContext.Data.LoadFromEnumerable(new List<ActivityInfo>()));
95
            IDataView transformedData = transformer.Transform(input);
96
            List<AnomalyDetectionResult> predictions = mlContext.Data.CreateEnumerable<AnomalyDetectionResult>(transformedData, false).ToList();
97
            List<ActivityInfo> result = new List<ActivityInfo>();
98

  
99
            for (int i=0; i<predictions.Count; i++)
75 100
            {
76
                List<int> amounts = new List<int>();
77
                List<int> maxima = new List<int>();
78
                foreach (string building in buildings)
101
                if(predictions[i].Prediction[0] == 1)
102
                {
103
                    _log.Debug($"Rejecting an outlier activity: {predictions[i].Prediction[1]}, p-value: {predictions[i].Prediction[2]}, from: {data[i].startTime}");
104
                } else
79 105
                {
80
                    List<ActivityInfo> temp = attendance.Where(activity => activity.building.Equals(building)).ToList();
81
                    amounts.Add(temp.Where(activity => activity.startTime.Equals(input.Time)).Select(activity => activity.amount).FirstOrDefault());
82
                    maxima.Add(temp.Select(activity => activity.amount).Max());
106
                    result.Add(data[i]);
83 107
                }
84
                double ratio = amounts.Sum() / (double)maxima.Sum();
85
                input.Label = RatioToLabel(ratio);
86 108
            }
87

  
88
            return res;
109
            return result;
89 110
        }
90 111

  
91 112
        private string RatioToLabel(double ratio)
......
134 155

  
135 156
        internal double LabelToRatio(string label)
136 157
        {
137
            if (label.Equals("10%"))
158
            if (label is null)
159
            {
160
                return -1f;
161
            }
162
            else if (label.Equals("10%"))
138 163
            {
139
                return 0.1f;
164
                return 10f;
140 165
            }
141 166
            else if (label.Equals("20%"))
142 167
            {
143
                return 0.2f;
168
                return 20f;
144 169
            }
145 170
            else if (label.Equals("30%"))
146 171
            {
147
                return 0.3f;
172
                return 30f;
148 173
            }
149 174
            else if (label.Equals("40%"))
150 175
            {
151
                return 0.4f;
176
                return 40f;
152 177
            }
153 178
            else if (label.Equals("50%"))
154 179
            {
155
                return 0.5f;
180
                return 50f;
156 181
            }
157 182
            else if (label.Equals("60%"))
158 183
            {
159
                return 0.6f;
184
                return 60f;
160 185
            }
161 186
            else if (label.Equals("70%"))
162 187
            {
163
                return 0.7f;
188
                return 70f;
164 189
            }
165 190
            else if (label.Equals("80%"))
166 191
            {
167
                return 0.8f;
192
                return 80f;
168 193
            }
169 194
            else if (label.Equals("90%"))
170 195
            {
171
                return 0.9f;
196
                return 90f;
172 197
            }
173 198
            else
174 199
            {
175
                return 1.0f;
200
                return 100f;
176 201
            }
177 202
        }
178 203
    }
Server/ServerApp/Predictor/PredictionController.cs
129 129
            return response;
130 130
        }
131 131

  
132
        private Prediction PredictSingle(Request request, DateTime current)
132
        private Prediction PredictSingle(Request request, DateTime predictionTime)
133 133
        {
134 134
            double[] predictedValues = new double[this.Configuration.BuildingsToAreas.Count];
135 135
            string[] predictedLabels = new string[this.Predictors.Count];
......
143 143
                        Rain = (float)request.rain,
144 144
                        Temp = (float)request.temperature,
145 145
                        Wind = (float)request.wind,
146
                        Hour = current.Hour,
147
                        Time = current
146
                        Hour = predictionTime.Hour,
147
                        Time = predictionTime
148 148
                    });
149 149
                }
150 150
                else
151 151
                {
152 152
                    _log.Debug("Retrieving weather info from the weather service.");
153 153
                    weatherService.ParsePrediction();
154
                    WeatherInfo weatherInfo = weatherService.Predictions.Find(info => info.startTime.Equals(current));
154
                    WeatherInfo weatherInfo = weatherService.Predictions.Find(info => info.startTime.Date.Equals(predictionTime.Date) && predictionTime.TimeOfDay.Subtract(info.startTime.TimeOfDay).Hours < info.intervalLength);
155 155
                    if (weatherInfo is null)
156 156
                    {
157 157
                        predictedLabels[i] = null;
......
163 163
                            Rain = weatherInfo.rain,
164 164
                            Temp = (float)weatherInfo.temp,
165 165
                            Wind = (float)weatherInfo.wind,
166
                            Hour = current.Hour,
167
                            Time = current
166
                            Hour = predictionTime.Hour,
167
                            Time = predictionTime
168 168
                        });
169 169
                    }
170 170
                }
......
177 177
            Prediction prediction = new Prediction();
178 178
            prediction.dateTime = new Date
179 179
            {
180
                year = current.Year,
181
                month = current.Month,
182
                day = current.Day,
183
                hour = current.Hour
180
                year = predictionTime.Year,
181
                month = predictionTime.Month,
182
                day = predictionTime.Day,
183
                hour = predictionTime.Hour
184 184
            };
185 185
            prediction.predictions = predictedValues;
186 186
            _log.Debug($"Created prediction for DateTime: {prediction.dateTime}");
Server/ServerApp/Program.cs
34 34

  
35 35
        static void Main(string[] args)
36 36
        {
37
            // setup logging service
37 38
            XmlConfigurator.Configure();
38 39
            // SETUP FOLDERS
39 40
            Config config = FillConfigInfo(args);
Server/ServerApp/ServerApp.csproj
10 10
    <ItemGroup>
11 11
        <PackageReference Include="log4net" Version="2.0.12" />
12 12
        <PackageReference Include="Microsoft.ML" Version="1.5.5" />
13
        <PackageReference Include="Microsoft.ML.TimeSeries" Version="1.5.5" />
13 14
    </ItemGroup>
14 15

  
15 16
    <ItemGroup>
Server/ServerAppFunctionalTests/App.config
1
<?xml version="1.0" encoding="utf-8" ?>
2
<configuration>
3
    <configSections>
4
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
5
    </configSections>
6
    <log4net>
7
        <appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
8
            <param name="File" value="server.log"/>
9
            <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
10
            <appendToFile value="true" />
11
            <rollingStyle value="Size" />
12
            <maxSizeRollBackups value="2" />
13
            <maximumFileSize value="5MB" />
14
            <staticLogFileName value="true" />
15
            <threshold>DEBUG</threshold>
16
            <layout type="log4net.Layout.PatternLayout">
17
                <param name="ConversionPattern" value="%d [%t] %-5p %c %m%n"/>
18
            </layout>
19
        </appender>
20
        <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
21
            <layout type="log4net.Layout.PatternLayout">
22
                <param name="ConversionPattern" value="%d [%t] %-5p %c %m%n"/>
23
            </layout>
24
        </appender>
25
        <appender name="DebugAppender" type="log4net.Appender.DebugAppender">
26
            <layout type="log4net.Layout.PatternLayout">
27
                <conversionPattern value="%date{dd.MM.yyyy HH:mm:ss.ffff} [%thread] %level %logger%exception - %message%newline" />
28
            </layout>
29
        </appender>
30
        <root>
31
            <level value="ALL" />
32
            <appender-ref ref="LogFileAppender" />
33
            <appender-ref ref="ConsoleAppender" />
34
            <appender-ref ref="DebugAppender"/>
35
        </root>
36
    </log4net>
37
</configuration>
Server/ServerAppFunctionalTests/Predictor/PredictionControllerTests.cs
14 14
using ServerApp.Parser.InputData;
15 15
using ServerApp.Connection.XMLProtocolHandler;
16 16
using ServerApp.DataDownload;
17
using log4net.Config;
17 18

  
18 19
namespace ServerApp.Predictor.Tests
19 20
{
20 21
    [TestClass()]
21 22
    public class PredictionControllerTests
22 23
    {
24
        [AssemblyInitialize()]
25
        public static void ClassInit(TestContext context)
26
        {
27
            // setup logging service
28
            XmlConfigurator.Configure();
29
        }
30

  
23 31
        [TestMethod()]
24 32
        public void PredictSingleTimeWeatherTest()
25 33
        {
Server/ServerAppFunctionalTests/ServerAppFunctionalTests.csproj
21 21
        <ProjectReference Include="..\ServerApp\ServerApp.csproj" />
22 22
    </ItemGroup>
23 23

  
24
    <ItemGroup>
25
      <None Update="App.config">
26
        <CopyToOutputDirectory>Always</CopyToOutputDirectory>
27
      </None>
28
    </ItemGroup>
29

  
24 30
</Project>

Také k dispozici: Unified diff