Apriori算法是数据挖掘中频繁模式挖掘的第一课。也是最基本的算法。
网上的apriori算法多是java实现,于是我尝试着用nodejs写出了算法全部过程。
其中外部有一个内容为
I1,I2,I5
I2,I4
I2,I3
I1,I2,I4
I1,I3
I2,I3
I1,I3
I1,I2,I3,I5
I1,I2,I3
的名为data.txt的数据文件。
代码中假设了最小支持度为2。
const min_sup=2;
var fs=require("fs");
var lineReader = require('line-reader');
//数组去重
Array.prototype.unique = function()
{
var n = {},r=[]; //n为hash表,r为临时数组
for(var i = 0; i < this.length; i++) //遍历当前数组
{
if (!n[this[i]]) //如果hash表中没有当前项
{
n[this[i]] = true; //存入hash表
r.push(this[i]); //把当前数组的当前项push到临时数组里面
}
}
return r;
}
var dataArr=[];
lineReader.eachLine('data.txt', function(line, last) {
var row=line.split(",");
dataArr.push(row);
if (last) {
var Ck1=freq1Gen(dataArr);
while(Ck1.length!==0){
Ck=Ck1;
Ck1=freqKGen(Ck);
}
console.log(Ck);
return false
}
});
/*
var I1='I1',I2='I2',I3='I3',I4='I4',I5='I5';
var dataArr=[
[I1,I2,I5],
[I2,I4],
[I2,I3],
[I1,I2,I4],
[I1,I3],
[I2,I3],
[I1,I3],
[I1,I2,I3,I5],
[I1,I2,I3],
];*/
//1.计算候选集C1
function freq1Gen(data){
var buffer=[];
var isShow=false;
for (var i = data.length - 1; i >= 0; i--) {
for (var j = data[i].length - 1; j >= 0; j--) {
isShow=false;
for (var k = buffer.length - 1; k >= 0; k--) {
if (buffer[k].name==data[i][j]) {
buffer[k].count++;
isShow=true;
break;
}
}
if (isShow==false) {
buffer.push({
name:data[i][j],
count:1
})
}
}
}
var ret=[];
for (var i = buffer.length - 1; i >= 0; i--) {
if (buffer[i].count>=min_sup) {
ret.push([buffer[i].name]);
}
}
return ret;
}
//2.计算候选集C(k+1)
function freqKGen(data){
var candi=[];
for(var i=0;i<data.length;i++){
for(var j=i+1;j<data.length;j++){
candi.push(data[i].concat(data[j]).unique());
}
}
candi=unique(candi);
var buffer=[];
for (var i = candi.length - 1; i >= 0; i--) {
buffer.push({arr:candi[i],count:0});
}
//计算支持数
for (var i = buffer.length - 1; i >= 0; i--) {
for (var j = dataArr.length - 1; j >= 0; j--) {
if(isContain(dataArr[j],buffer[i].arr)){
buffer[i].count++;
}
}
}
//剪枝
var ret=[];
for (var i = buffer.length - 1; i >= 0; i--) {
if(buffer[i].count>=min_sup){
ret.push(buffer[i].arr);
}
}
return ret;
}
//判断arr1是否包含arr2
function isContain(arr1,arr2){
for (var i = arr2.length - 1; i >= 0; i--) {
if(!arr1.includes(arr2[i])){
return false;
}
}
return true;
}
function unique(arr){
var toDel=[]
for(var i=0;i<arr.length;i++){
for(var j=i+1;j<arr.length;j++){
if (arr[i].length==arr[j].length) {
var flag=true;
for(var k=0;k<arr[j].length;k++){
if (!arr[i].includes(arr[j][k])) {
flag=false;
break;
}
}
if (flag) {
toDel.push(i);
break;
}
}
}
}
for (var i = toDel.length - 1; i >= 0; i--) {
arr.splice(toDel[i],1);
}
return arr;
}