-
Notifications
You must be signed in to change notification settings - Fork 0
/
Learn.cs
124 lines (100 loc) · 4.21 KB
/
Learn.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using Accord;
using Accord.MachineLearning;
using Accord.MachineLearning.DecisionTrees;
using Accord.MachineLearning.DecisionTrees.Learning;
using Accord.MachineLearning.DecisionTrees.Rules;
using Accord.Math;
using Accord.Math.Distances;
using Accord.Math.Optimization.Losses;
using Accord.Statistics.Filters;
using Accord.Statistics.Kernels;
namespace eTracker
{
public class Learn
{
public DecisionTree Tree { get; set; }
public string Rules { get; set; }
public string Code { get; set; }
public string[] InputNames = new[] { "Age", "L1", "Word" };
public Codification CodeBook { get; set; }
public Learn()
{
try
{
//http://accord-framework.net/docs/html/T_Accord_MachineLearning_DecisionTrees_Learning_C45Learning.htm
using (var db = new DatabaseEntities())
{
var allItems = db.Records.ToList();
DataTable data = new DataTable("e-Tracker Values");
data.Columns.Add("Id", typeof(int));
data.Columns.Add("Age", typeof(string));
data.Columns.Add("L1", typeof(string));
data.Columns.Add("Word", typeof(string));
data.Columns.Add("Synonym", typeof(string));
allItems.ForEach(r =>
{
r.DetailRecords.ToList().ForEach(dr =>
{
data.Rows.Add(dr.Id, r.Age, r.L1, dr.UnknownWord, dr.SelectedSynonism);
});
});
// Create a new codification codebook to convert
// the strings above into numeric, integer labels:
CodeBook = new Codification() {DefaultMissingValueReplacement = Double.NaN};
// Learn the codebook
CodeBook.Learn(data);
// Use the codebook to convert all the data
DataTable symbols = CodeBook.Apply(data);
// Grab the training input and output instances:
int[][] inputs = symbols.ToJagged<int>(InputNames);
int[] outputs = symbols.ToArray<int>("Synonym");
// Create a new learning algorithm
var teacher = new C45Learning()
{
Attributes = DecisionVariable.FromCodebook(CodeBook, InputNames),
};
// Use the learning algorithm to induce a new tree:
Tree = teacher.Learn(inputs, outputs);
// To get the estimated class labels, we can use
int[] predicted = Tree.Decide(inputs);
// The classification error (~0.214) can be computed as
double error = new ZeroOneLoss(outputs).Loss(predicted);
// Moreover, we may decide to convert our tree to a set of rules:
DecisionSet rules = Tree.ToRules();
// And using the codebook, we can inspect the tree reasoning:
string ruleText = rules.ToString(CodeBook, "Synonym",
System.Globalization.CultureInfo.InvariantCulture);
Rules = ruleText;
Code = Tree.ToCode("Rules");
}
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
public string Query(string[] queryValues)
{
try
{
int[] query = CodeBook.Transform(InputNames, queryValues);
// And then predict the label using
int predicted = Tree.Decide(query);
// We can translate it back to strings using
return CodeBook.Revert("Synonym", predicted);
}
catch (Exception e)
{
Console.WriteLine(e);
return "Cannot Predict!";
}
}
}
}