HotSpot關聯規則演算法(2)-- 挖掘連續型和離散型資料,hotspot離散

來源:互聯網
上載者:User

HotSpot關聯規則演算法(2)-- 挖掘連續型和離散型資料,hotspot離散

本篇代碼可在 (明天更新)下載。

前篇《HotSpot關聯規則演算法(1)-- 挖掘離散型資料》分析了離散型資料的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,nosunny,80,90,TRUE,noovercast,83,86,FALSE,yesrainy,70,96,FALSE,yesrainy,68,80,FALSE,yesrainy,65,70,TRUE,noovercast,64,65,TRUE,yessunny,72,95,FALSE,nosunny,69,70,FALSE,yesrainy,75,80,FALSE,yessunny,75,70,TRUE,yesovercast,72,90,TRUE,yesovercast,81,75,FALSE,yesrainy,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 = reader.readLine()) != null) {// 第一行資料是標題if (tempString.indexOf(HSUtils.FILEFORMAT) == 0) {String attr = "";String[] attrStates = null;if (tempString.contains("{")) {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 {// numericif (tempString.contains("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];attrList.toArray(this.attributes);// 複製值到數組中numericList.toArray(this.isNumeric);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()][];intData.toArray(tmpData);Arrays.sort(tmpData,new Comparator<float[]>(){@Overridepublic 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();newSplitVals[attrStateSup.getAttrIndex()] = attrStateSup.getStateIndex() + 1;newTests[attrStateSup.getAttrIndex()] = isNumeric[attrStateSup.getAttrIndex()]?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):HSUtils.getAttrState(splitAttrIndex, (int)attrStateIndex); return HSUtils.getAttr(this.splitAttrIndex)+tmp+attrState+"  ("+HSUtils.formatPercent(this.support)+" ["+this.stateCount+"/"+this.allCount+"])";}

在列印關聯規則樹時,同樣需要判斷當前的屬性是離散型還是連續型的。


代碼輸出為:

檔案讀取完成,且屬性和屬性的各種狀態初始化完成!屬性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])



分享,成長,快樂

腳踏實地,專註

轉載請註明blog地址:http://blog.csdn.net/fansy1990



相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.