Advertisement
Guest User

Untitled

a guest
Dec 17th, 2018
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.78 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.ComponentModel.DataAnnotations;
  5. using System.Globalization;
  6. using System.IO;
  7. using System.Linq;
  8. using System.Reflection;
  9. using Studia.Models;
  10.  
  11. namespace Studia
  12. {
  13. public static class Program
  14. {
  15. public static bool Logging { get; set; }
  16.  
  17. public static void Log(string message)
  18. {
  19. if(Logging)
  20. File.AppendAllLines("log.txt", new List<string>() { DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ": " + message });
  21. }
  22.  
  23. public static List<InputData> ParseData()
  24. {
  25. var lines = File.ReadAllLines(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + @"\data.dat");
  26. return lines.Select(line => line.Split(','))
  27. .Select(inputParameters => new InputData()
  28. {
  29. Preg = double.Parse(inputParameters[0], CultureInfo.InvariantCulture),
  30. Plas = double.Parse(inputParameters[1], CultureInfo.InvariantCulture),
  31. Pres = double.Parse(inputParameters[2], CultureInfo.InvariantCulture),
  32. Skin = double.Parse(inputParameters[3], CultureInfo.InvariantCulture),
  33. Insu = double.Parse(inputParameters[4], CultureInfo.InvariantCulture),
  34. Mass = double.Parse(inputParameters[5], CultureInfo.InvariantCulture),
  35. Pedi = double.Parse(inputParameters[6], CultureInfo.InvariantCulture),
  36. Age = double.Parse(inputParameters[7], CultureInfo.InvariantCulture),
  37. Result = (inputParameters[8].ToLower().Trim() == "tested_positive")
  38. })
  39. .ToList();
  40. }
  41.  
  42. public static double EuklidesDistance(InputData a, InputData b) => Math.Pow((a.GetWeight - b.GetWeight), 2);
  43. public static double ManhatanDistance(InputData a, InputData b) => Math.Abs(a.GetWeight - b.GetWeight);
  44.  
  45. public static List<InputData> GetKnn(this List<InputData> data, InputData measuredData, int k, Func<InputData, InputData, double> calculateDistanceMethod)
  46. {
  47. data.ForEach(measure =>
  48. {
  49. measure.Distance = calculateDistanceMethod(measure, measuredData);
  50. Log($"For measure: {measure.ToString()} distance is {measure.Distance}");
  51. });
  52. var orderedData = data.OrderBy(measure => measure.Distance).ToList();
  53. k = orderedData.Count - k > 0 ? k : 0;
  54. var neighbours = orderedData.Take(5).ToList();
  55. Log($"SELECTED {k} neighbors:");
  56. foreach (var neighbor in neighbours)
  57. Log($"For neighbor: {neighbor} distance is {neighbor.Distance}");
  58. return neighbours;
  59. }
  60.  
  61. public static InputData ReadPatientsData()
  62. {
  63. var request = new InputData();
  64. typeof(InputData).GetProperties()
  65. .Where(prop => prop.GetCustomAttributes(typeof(RangeAttribute)).Any())
  66. .ToList()
  67. .ForEach(prop =>
  68. {
  69. var description = prop.GetCustomAttribute<DescriptionAttribute>();
  70. Console.WriteLine(description.Description);
  71. var range = prop.GetCustomAttribute<RangeAttribute>();
  72. Console.WriteLine($"Range between <{(double)range.Minimum};{(double)range.Maximum}>");
  73. Console.WriteLine("Enter value: ");
  74.  
  75. double value;
  76. while (!double.TryParse(Console.ReadLine(), out value) || value < (double)range.Minimum || value > (double)range.Maximum)
  77. {
  78. Console.WriteLine("Wrong value, try again");
  79. }
  80. prop.SetValue(request, value);
  81. Log($"Patients data, entered property value {value} for {prop.Name} in range <{(double)range.Minimum};{(double)range.Maximum}>" );
  82. });
  83. return request;
  84. }
  85.  
  86.  
  87. static void Main(string[] args)
  88. {
  89. Logging = args.Any() && args[0] == "log";
  90.  
  91. Console.WriteLine("From National Institute of Diabetes and Digestive and Kidney Diseases. Several constraints were placed on the selection of these instances from a larger database. In particular, all patients here are females at least 21 years old of Pima Indian heritage. ");
  92. Console.WriteLine("The class label represents if the person has not diabetes (tested_negative) or the person has diabetes (tested_positive). ");
  93.  
  94. var data = ParseData();
  95. Console.Write("Enter k (kNN) parameter: ");
  96. var k = int.Parse(Console.ReadLine());
  97. var patientsData = ReadPatientsData();
  98.  
  99. // TestCase k = 5 100%
  100. // var measure = new InputData()
  101. // {
  102. // Preg = 3,
  103. // Plas = 150,
  104. // Pres = 76,
  105. // Skin = 0,
  106. // Insu = 0,
  107. // Mass = 21,
  108. // Pedi = 0.207,
  109. // Age = 37
  110. // };
  111.  
  112. Console.WriteLine("Choose distance algorithm");
  113. Console.WriteLine("1.Manhatan");
  114. Console.WriteLine("2.Euklides");
  115. Func<InputData, InputData, double> distanceMethod = null;
  116. if (Console.ReadLine() == "1")
  117. distanceMethod = ManhatanDistance;
  118. else
  119. distanceMethod = EuklidesDistance;
  120.  
  121. var neighbors = data.GetKnn(patientsData, k, distanceMethod);
  122. Log($"For measurements: {patientsData}");
  123.  
  124. var positive = neighbors.Count(x => x.Result);
  125. var negative = neighbors.Count(x => !x.Result);
  126. if(positive > negative)
  127. Console.WriteLine("tested_positive");
  128. else if (positive == negative)
  129. Console.WriteLine("50%");
  130. else
  131. Console.WriteLine("tested_negative");
  132. Console.WriteLine($"Positive: {positive}, Negative: {negative}");
  133. Log($"Positive: {positive}, Negative: {negative}");
  134. Console.ReadLine();
  135. }
  136. }
  137. }
  138.  
  139.  
  140.  
  141.  
  142. using System.ComponentModel;
  143. using System.ComponentModel.DataAnnotations;
  144.  
  145. namespace Studia.Models
  146. {
  147. public class InputData
  148. {
  149. [Description("Number of times pregnant ")]
  150. [Range(0.0, 17.0)]
  151. public double Preg { get; set; }
  152. [Description("Plasma glucose concentration a 2 hours in an oral glucose tolerance test ")]
  153. [Range(0.0, 199.0)]
  154. public double Plas { get; set; }
  155. [Description("Diastolic blood pressure (mm Hg) ")]
  156. [Range(0.0, 122.0)]
  157. public double Pres { get; set; }
  158. [Description("Triceps skin fold thickness (mm) ")]
  159. [Range(0.0, 99.0)]
  160. public double Skin { get; set; }
  161. [Description("2-Hour serum insulin (mu U/ml) ")]
  162. [Range(0.0, 846.0)]
  163. public double Insu { get; set; }
  164. [Description("Body mass index (weight in kg/(height in m)^2) ")]
  165. [Range(0.0, 67.1)]
  166. public double Mass { get; set; }
  167. [Description("Diabetes pedigree function")]
  168. [Range(0.078, 2.42)]
  169. public double Pedi { get; set; }
  170. [Description("Age (years)")]
  171. [Range(21.0, 81.0)]
  172. public double Age { get; set; }
  173. public bool Result { get; set; }
  174.  
  175. public override string ToString()
  176. {
  177. return $"Preg: {Preg}; Plas: {Plas}; Pres: {Pres}; Skin: {Skin}; Insu: {Insu}; Mass:{Mass}; Pedi:{Pedi}; Age:{Age}";
  178. }
  179.  
  180. public double GetWeight => (Preg + Plas + Pres + Skin + Insu + Mass + Pedi + Age);
  181. public double Distance { get; set; }
  182. }
  183. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement