HotSpot关联规则算法(2)--挖掘连续型和离散型数据
前篇《》分析了离散型数据的HotSpot关联规则,本篇分析离散型和连续型数据的HotSpot关联规则挖掘。
1. ⾸先看下数据格式(txt⽂档):
@attribute outlook {sunny, overcast, rainy}
@attribute temperature numeric
@attribute humidity numeric
@attribute windy {TRUE, FALSE}
@attribute play {yes, no}
sunny,85,85,FALSE,no
sunny,80,90,TRUE,no
overcast,83,86,FALSE,yes
rainy,70,96,FALSE,yes
rainy,68,80,FALSE,yes
rainy,65,70,TRUE,no
overcast,64,65,TRUE,yes
sunny,72,95,FALSE,no
sunny,69,70,FALSE,yes
rainy,75,80,FALSE,yes
sunny,75,70,TRUE,yes
overcast,72,90,TRUE,yes
overcast,81,75,FALSE,yes
rainy,71,91,TRUE,no
此数据參考weka⾃带数据weather.arff,并且数据格式,⽐⽅写上@attribute 等都是參考weka的数据格式来的。以下代码中使⽤的数据格式如上所述,其格式描写叙述例如以下:1)前m⾏以@attribute开头,代码m个属性。当中最后⼀个为⽬标属性;2)假设属性是数值型,则在attribute后⾯空格跟属性名,再空格跟numeric;假设是离散型。那么attribute后⾯空格跟属性名。再空格使⽤⼤括号把离散值括起来,离散值⽤逗号分隔;3)⽬标属性必须是离散型的(关于⽬标属性应该⼀定要属于离散型的这点要求,事实上仅仅是我代码⾥⾯这样说⽽已,⼀般的HotSpot算法并没有这个要求。
假设⽬标属性⼀定要求是连续型的,能够在lz代码基础上进⾏改动)。
2. 数据读取
《HotSpot关联规则算法(1)》中的数据读取是针对离散型的数据的,所以须要进⾏改动,这⾥改动后仅仅针对离散型数据进⾏编码。连续型数据保持就可以,同⼀时候还需设置⼀个布尔数组指明属性列属于离散型还是连续型。
其读代替码例如以下所看到的:
while ((tempString = adLine()) != null) {
// 第⼀⾏数据是标题
if (tempString.indexOf(HSUtils.FILEFORMAT) == 0) {
String attr = "";
String[] attrStates = null;
if (ains("{")) {
attr = tempString.substring(
HSUtils.FILEFORMAT.length(),
tempString.indexOf("{")).trim();
attrStates = tempString.substring(
tempString.indexOf("{") + 1,
tempString.indexOf("}")).split(",");
for (int i = 0; i < attrStates.length; i++) {
attrStates[i] = attrStates[i].trim();
}
numericList.add(false);
this.attributeStates.put(attr, attrStates);// 在这⾥加⼊就可以
} else {// numeric
if (ains("numeric")) {
attr = tempString.substring(
HSUtils.FILEFORMAT.length(),
tempString.indexOf("numeric")).trim();
numericList.add(true);
} else {
/
/ error 数据格式错误
throw new Exception("数据格式错误,请检查!");
}
}
attrList.add(attr);
line++;
continue;
}
if (flag) {
this.attributes = new String[line];
this.isNumeric = new Boolean[line];
flag = false;
}
String[] tempStrings = tempString.split(splitter);
lists.add(strArr2IntArr(tempStrings));
}
这⾥仅仅贴了while循环⾥⾯的代码,这⾥的代码即针对前⾯描写叙述的数据格式规则进⾏变量初始化(事实上,这⾥使⽤List存储转换后的数据。通常是能够使⽤数组来存储的。把List的数据转为数组就可以。这样在后⾯的操作中能够更快。假设要优化。能够从这⽅⾯⼊⼿)。
3. HotSpot关联规则树的节点定义说明:
因为这⾥添加了连续型属性数据。所以针对单个节点需添加⼀个布尔型变量lessThan,⽤于指明是要⼤
于或者⼩于该节点数据,同⼀时候stateIndex应该是⼀个数值了(当前节点的值),⽽不是离散型数据状态的下标了。
4. 算法伪代码(建树过程)
在算法伪代码中的计算潜在节点时。针对连续型变量使⽤不同的⽅法,在weka源代码中⽤法:evaluateNumeric来进⾏推断。在lz的代码中此部分是全然參考源代码中的代码的,只是有⼀点就是在调⽤evaluateNumeric这个算法后,会针对某⼀列进⾏排序,即⼀个⼆维数组按某列进⾏全局排序。这种⽅法在weka源代码中是使⽤Instances的quickSort⽅法进⾏排序的(使⽤了递归,没细致看)。这⾥lz则是直接把List 转为⼆维数组然后进⾏排序的,其⽅法例如以下:
/**
* 依据attrIndex进⾏排序,attrIndex必须是numeric的此⽅法可能须要优化
* List 使⽤数组是否更快?能够考虑使⽤数组
* @param intData
* @param attrIndex
* @return
*/
private List<float[]> sortBasedOnAttr(List<float[]> intData, final int attrIndex) {
float[][] tmpData = new float[intData.size()][];
Arrays.sort(tmpData,new Comparator<float[]>(){
@Override
public int compare(float[] o1, float[] o2) {
if(o1[attrIndex]==o2[attrIndex]){
return 0;
}
return o1[attrIndex]>o2[attrIndex]?1:-1;
}
});
List<float[]> returnList = new ArrayList<float[]>();
for (int i = 0; i < tmpData.length; i++) {
returnList.add(tmpData[i]);
}
return returnList;
}
同⼀时候,在递归构建孩⼦节点时,⽣成节点规则时,针对数值型和离散型其⽣成⽅式也是不同的。例如以下:
double[] newSplitVals = splitVals.clone();
byte[] newTests = tests.clone();
AttrIndex()] = attrStateSup
.getStateIndex() + 1;
AttrIndex()] = AttrIndex()]?
attrStateSup.isLessThan()?(byte)1:(byte)3:(byte) 2;
HotSpotHashKey key = new HotSpotHashKey(newSplitVals, newTests);
在递归构建孩⼦节点时,使⽤的⼦数据集的⽣成⽅式也须要进⾏调整,例如以下:
/**
* 获取和splitAttributeIndex相同下标的属性以及stateIndex的全部数据
*
* @param intData
* @param splitAttributeIndex
* @param splitValue
* @return
*/
private List<float[]> getSubData(List<float[]> intData,
int splitAttributeIndex, float splitValue,boolean lessThan) {
List<float[]> subData = new ArrayList<float[]>();
for (float[] d : intData) {
if(isNumeric[splitAttributeIndex]){
if(lessThan){
if (d[splitAttributeIndex] <= splitValue) {
subData.add(d);
}
}else{
if (d[splitAttributeIndex] > splitValue) {
subData.add(d);
}
}
}else{
if (d[splitAttributeIndex] == splitValue) {
subData.add(d);
}
}
}
return subData;
}
节点的toString ⽅法,⽤于打印HotSpot关联规则树
/**
* 格式化输出
*/
public String toString(){
String tmp = HSUtils.isNumeric(splitAttrIndex)?this.lessThan?
" <= ":" > ":" = ";
String attrState = HSUtils.isNumeric(splitAttrIndex)?
String.valueOf(this.attrStateIndex):
Attr(this.splitAttrIndex)+tmp
+attrState
+" ("+HSUtils.formatPercent(this.support)+" ["+this.stateCount+"/"+this.allCount+"])"; }
在打印关联规则树时。相同须要推断当前的属性是离散型还是连续型的。
代码输出为:
⽂件读取完毕。且属性和属性的各种状态初始化完毕!
float up属性outlook的状态: [sunny-->0,overcast-->1,rainy-->2,]
属性temperature的状态: [numeric]
属性humidity的状态: [numeric]
属性windy的状态: [TRUE-->0,FALSE-->1,]
属性play的状态: [yes-->0,no-->1,]
规则树例如以下:
play = no (35.71% [5/14])
| temperature > 83.0 (100.00% [1/1])
| humidity > 90.0 (66.67% [2/3])
| | temperature > 70.0 (100.00% [2/2])
| | humidity <= 95.0 (100.00% [2/2])
分享。成长,快乐
脚踏实地,专注
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论