Skip to content

Instantly share code, notes, and snippets.

@Ni55aN
Created February 24, 2017 20:23
Show Gist options
  • Save Ni55aN/9f578ba6b9a06506a660d7508b2ded35 to your computer and use it in GitHub Desktop.
Save Ni55aN/9f578ba6b9a06506a660d7508b2ded35 to your computer and use it in GitHub Desktop.
var head = ['Різновидність лісових угідь', 'Різновид вологості ґрунту', 'Температура повітря ', 'Рівень пожежної безпеки'];
var data = [
['Листові', 'Низька', '20', '1'],
['Листові', 'Низька', '30', '3'],
['Листові', 'Низька', '40', '5'],
['Листові', 'Середня', '20', '1'],
['Листові', 'Середня', '30', '2'],
['Листові', 'Середня', '40', '4'],
['Листові', 'Висока', '20', '1'],
['Листові', 'Висока', '30', '3'],
['Листові', 'Висока', '40', '4'],
['Хвойні', 'Низька', '20', '2'],
['Хвойні', 'Низька', '30', '4'],
['Хвойні', 'Низька', '40', '5'],
['Хвойні', 'Середня', '20', '2'],
['Хвойні', 'Середня', '30', '3'],
['Хвойні', 'Середня', '40', '5'],
['Хвойні', 'Висока', '20', '2'],
['Хвойні', 'Висока', '30', '3'],
['Хвойні', 'Висока', '40', '4']
];
function ID3(data) {
var last = data[0].length - 1;
function Entropy(data) {
var keys = Object.keys(data);
var sum = keys.reduce(function(a, key) {
return a + data[key];
}, 0)
return keys.reduce(function(a, key) {
return a - data[key] / sum * Math.log2(data[key] / sum);
}, 0);
}
function columnDuplicatesCount(data, j) {
var dups = [];
for (var i in data) {
if (!dups[data[i][j]])
dups[data[i][j]] = 0;
dups[data[i][j]]++;
}
return dups;
}
function Gain(general, coeficients, entropies) {
var keys = Object.keys(coeficients);
return general - keys.reduce(function(a, key) {
return a + coeficients[key] * entropies[key];
}, 0);
}
function detectOptions(data) {
var generalDuplicatesCount = columnDuplicatesCount(data, last);
var generalEntropy = Entropy(generalDuplicatesCount);
var gains = [];
if (generalEntropy == 0)
return data[0][last];
for (var col = 0; col < data[0].length - 1; col++) {
var dups = columnDuplicatesCount(data, col);
var coeficients = [];
var entropies = [];
for (var i in dups) {
var filteredData = data.filter(function(a) {
return a[col] == i;
});
var filteredCounts = columnDuplicatesCount(filteredData, last);
coeficients[i] = filteredData.length / data.length;
entropies[i] = Entropy(filteredCounts);
}
gains.push({
col: col,
value: Gain(generalEntropy, coeficients, entropies)
});
}
var maxGain = gains.reduce(function(max, e) {
return max.value <= e.value ? e : max;
}, gains[0]);
var args = columnDuplicatesCount(data, maxGain.col);
var options = [];
for (var i in args) {
var filtered = data.filter(function(a) {
return a[maxGain.col] == i;
})
options[i] = detectOptions(filtered);
}
return {
name: head[maxGain.col],
options: options
};
}
return detectOptions(data);
}
function printTable(id, h, d) {
var s = '';
s += '<tbody>';
s += '<tr>';
for (var i in h)
s += '<th>' + h[i] + '</th>';
s += '</tr>';
for (var i in d) {
s += '<tr>';
for (var j in d[i])
s += '<td>' + d[i][j] + '</td>';
s += '</tr>';
}
s += '</tbody>';
document.getElementById(id).innerHTML = s;
}
function printTree(id, head, data) {
function addSection(data) {
if (typeof data == "string")
return '<section class="mini">' + head[head.length - 1] + ': ' + data + '</section>';
var s = '';
s += '<section>';
s += '<node>' + data.name + '<div>';
for (var i in data.options)
s += '<a>' + i + ' |</a>';
s += '</div></node><br>';
for (var i in data.options)
s += addSection(data.options[i]);
s += '</section>';
return s;
}
document.getElementById(id).innerHTML = addSection(data);
}
window.onload = function() {
printTable('data', head, data);
var id3 = ID3(data);
printTree('ID3', head, id3);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment