private static void Main(string[] args) { if (args.Length < 3 || args.Length > 6) { Console.WriteLine(Help); return; } var parser = new EventsParser(); IList <EventModel> events = null; try { events = parser.ParseFromCSV(args[0]); } catch (FormatException e) { Console.WriteLine(e.Message); Console.WriteLine(Strings.WrongFileFormat); Console.WriteLine(Strings.Tweets); return; } if (events == null) { Console.WriteLine(Strings.FileNotFound); return; } ISymptomAlgorithm symtopmAlgorithm; IDetectionMethod method; var isFastTest = false; switch (args[1].ToLower()) { case "bow": symtopmAlgorithm = new BagOfWords(); break; case "tf-idf": symtopmAlgorithm = new TermFrequencyInverseDocumentFrequency(); break; case "ft": isFastTest = true; symtopmAlgorithm = new FastTest(args[2]); break; default: Console.WriteLine(Strings.SymptomAlgorithmError); Console.WriteLine(Strings.Bow); return; } switch (args[isFastTest ? 3 : 2].ToLower()) { case "mdm": method = new MinimalDistanceMethod(); break; case "knn": if (args.Length < 4 || !int.TryParse(args[isFastTest ? 4 : 3], out var k) || k <= 0) { Console.WriteLine(Strings.PositiveIntegerError); Console.WriteLine(Strings.KNN); return; } method = new KNearestNeighbors(k); break; default: Console.WriteLine(Strings.DetectionMethodError); Console.WriteLine(Strings.MDM); return; } Console.WriteLine("Generating symtoms..."); symtopmAlgorithm.GenerateSymptoms(events); Console.WriteLine("Symptoms generated successfully."); Console.WriteLine($"There are { events.Count(s => s.SymptomModel != null) } symptoms."); Console.WriteLine("\nMaking etalons..."); var symptomLength = events[0].SymptomModel.Length; var etalons = new List <ClusterModel>(); foreach (var e in events) { var exist = etalons.Where(etalon => e.EventType == etalon.Type).FirstOrDefault(); if (exist != null) { exist.Events.Add(e); continue; } etalons.Add(new ClusterModel { Type = e.EventType, Events = new List <EventModel> { e } }); } etalons.ForEach(e => Console.WriteLine($"Created etalon { e.Type }")); Console.WriteLine("\nDetection..."); var clusters = method.Detect(events, etalons); Console.WriteLine("Detecting done."); var output = args.Last(); if (output.LastIndexOf('.') > 0 && output.Substring(output.LastIndexOf('.')).ToLower().CompareTo(".csv") == 0) { Console.WriteLine("\nWriting result into csv file...\n"); var classifiedEvents = clusters.Select(c => c.Clone() as ClusterModel).ToList(); classifiedEvents.ForEach(c => c.Events.ForEach(e => e.EventType = c.Type)); try { parser.ParseIntoCSV(output, classifiedEvents.SelectMany(c => c.Events.Select(e => e)).ToList()); } catch (Exception e) { Console.WriteLine(e.Message); return; } } else { Console.WriteLine(Environment.NewLine + Strings.OutputError + Environment.NewLine); } Console.WriteLine("Results:"); double correctResults = clusters.Sum(c => c.Events.Count(e => e.EventType == c.Type)); double all = clusters.Sum(c => c.Events.Count); var precision = correctResults / all; var recall = (correctResults / Math.Abs((all - correctResults))) / 100; var fMeasure = (2 * (precision * recall)) / (precision + recall); Console.WriteLine($"Precision: { precision }\nRecall: { recall }\nF-measure: { fMeasure }\n"); foreach (var c in clusters) { foreach (var e in c.Events) { if (e.EventType != c.Type) { Console.WriteLine($"Cluster { c.Type } contain wrong classified { e.EventType }"); } } } }