09
2017
06

基于关联规则算法处理工程计价清单的自动组价数据挖掘

一、关联规则的定义和属性
 
考察一些涉及许多物品的事务:事务1 中出现了物品甲,事务2 中出现了物品乙,事务3 中则同时出现了物品甲和乙。那么,物品甲和乙在事务中的出现相互之间是否有规律可循呢?在数据库的知识发现中,关联规则就是描述这种在一个事务中物品之间同时出现的规律的知识模式。更确切的说,关联规则通过量化的数字描述物品甲的出现对物品乙的出现有多大的影响。
 
现实中,这样的例子很多。例如超级市场利用前端收款机收集存储了大量的售货数据,这些数据是一条条的购买事务记录,每条记录存储了事务处理时间,顾客购买的物品、物品的数量及金额等。这些数据中常常隐含形式如下的关联规则:在购买铁锤的顾客当中,有70 %的人同时购买了铁钉。这些关联规则很有价值,商场管理人员可以根据这些关联规则更好地规划商场,如把铁锤和铁钉这样的商品摆放在一起,能够促进销售。


二、关联规则的应用背景


而在工程造价领域,根据不同的清单进行组价,而组价的规则千变万化,对于一个有经验的预算员来说可能驾轻就熟,但是每条清单进行处理也需要一定的时间;而对于一名新近的预算员来说,组价就会变得异常的困难。因此自动(一键)组价功能的功能价值就更加的凸显。


在实现这个算法前有几点假设:

1、清单、子目数据已经正常收集在某一个DB中;

2、已经做好初步去重工作;

3、特定项目特征,工作内容组合的清单已经映射成唯一一条清单(代码中简单的现已清单编码来进行演示);


三、关联规则的应用实现



主要函数实现代码:


// 数据初始化,计算每个元素的权重,并去除小于一定权重的元素
function InitData(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;  
}

// 计算数组中的子集的权重,进行剪枝
function GenArr(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=[];  
    var lock = false;
    for (var i = buffer.length - 1; i >= 0; i--) {  
        if(buffer[i].count>=min_sup){  
            if (!lock){
                result = [];
                lock = true;
	    }
	    ret.push(buffer[i].arr);  
	    result.push({arr:buffer[i].arr, count:buffer[i].count});
        }  
    }  
    return ret;  
}


四、结果检视:

Input:

Output:

« 上一篇 下一篇 »

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

扫一扫,加我为微信好友