Skip to content

Instantly share code, notes, and snippets.

@Ni55aN
Created March 1, 2017 19:39
Show Gist options
  • Save Ni55aN/731dd5e0ea21c67190f88e85b0357d49 to your computer and use it in GitHub Desktop.
Save Ni55aN/731dd5e0ea21c67190f88e85b0357d49 to your computer and use it in GitHub Desktop.
var AssociationRules = function(transactions, MIN_SUPPORT, MAX_COMBINATION) {
var getOptions = function(data) {
var set = new Set();
data.map(function(el) {
el.map(function(val) {
if (val != null)
set.add(val);
});
});
return Array.from(set);
}
var arrayContains = function(arr, values) {
return values.every(function(e) {
return arr.includes(e);
});
}
function arrayToCombinations(arr, size) {
var result_set = [],
result;
for (var x = 0; x < Math.pow(2, arr.length); x++) {
result = [];
i = arr.length - 1;
do {
if ((x & (1 << i)) !== 0)
result.push(arr[i]);
} while (i--);
if (result.length == size)
result_set.push(result);
}
return result_set;
}
function combinationsToArray(combinations) {
var set = new Set();
combinations.forEach(function(combination) {
set = new Set([...set, ...combination]);
});
return Array.from(set);
}
var options = getOptions(transactions);
var results = [];
var acceptableResults = [];
var targetOptions = options;
var combinationsSize = 1;
while (combinationsSize < MAX_COMBINATION) {
var combinations = arrayToCombinations(targetOptions, combinationsSize);
if (combinations.length == 0) break;
var supports = new Array(combinations.length).fill(0);
combinations.forEach(function(combination, i) {
transactions.forEach(function(transaction) {
if (arrayContains(transaction, combination))
supports[i] += 1 / transactions.length;
});
});
results.push([combinations, supports]);
var acceptableCombinations = combinations.filter(function(comb, i) {
return supports[i] >= MIN_SUPPORT;
});
supports = supports.filter(function(supp) {
return supp >= MIN_SUPPORT;
});
if (acceptableCombinations.length == 0) break;
acceptableResults.push([acceptableCombinations, supports]);
targetOptions = combinationsToArray(acceptableCombinations);
combinationsSize++;
};
return {
all: results,
acceptable: acceptableResults
};
}
<html>
<head>
<style>
html {
text-align: center;
}
body {
margin: 40pt auto;
max-width: 800pt;
text-align: center;
}
table {
border-collapse: collapse;
margin: 2%;
}
td,
th {
padding: 6px 8px;
border: 1px solid #444;
}
</style>
<link rel="javascript" type="text/javascript" href="AssociationRule.js">
<script>
function printTable(arr, needTranspose, rowHeader) {
if (needTranspose)
arr = arr[0].map(function(_, c) {
return arr.map(function(r) {
return r[c];
});
});
var out = '<table>';
arr.forEach(function(row, i) {
out += '<tr>' + (rowHeader ? '<th>' + rowHeader + '<sub>' + (i + 1) + '</sub></th>' : '');
row.forEach(function(el) {
out += '<td>' + el + '</td>';
});
out += '</tr>';
});
out += '</table>';
document.body.innerHTML += out;
}
window.onload = function() {
var transactions = [
["Laptop","Mouse","Router"],
["Monitor","System unit","Headphones"],
["Mouse","Monitor","System unit","Loudspeakers","Mousepad","Keyboard"],
["GPU","CPU","Keyboard"],
["Laptop","Router","Headphones","Mousepad"],
["Mouse","Monitor","System unit","Loudspeakers","Headphones","Mousepad","Keyboard"],
["Router","Monitor","System unit","Mousepad","Keyboard"],
["GPU","CPU"],
["Laptop","Powerbank","Headphones"],
["Mouse","Mousepad","Keyboard"],
["Loudspeakers","Headphones"],
["Router"]
];
printTable(transactions, false, 'Транзакция');
var rules = new AssociationRules(transactions, 0.3, 6);
for (var i in rules.all)
printTable(rules.all[i], true);
for (var i in rules.acceptable)
printTable(rules.acceptable[i], true);
}
</script>
</head>
<body>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment