聲明: java
1)本文由我bitpeach原創撰寫,轉載時請註明出處,侵權必究。 mysql
2)本小實驗工做環境爲Windows系統下的WEKA,實驗內容主要有三部分,第一是分類挖掘(垃圾郵件過濾),第二是聚類分析,第三是關聯挖掘。 linux
3)本文因爲過長,且實驗報告內的評估觀點有時不必定正確,但願拋磚引玉。 算法
建立目錄:sudo mkdir /usr/weka。 sql
解壓weka到該目錄:unzip weka-3-6-10.zip -d /usr/weka。shell
export WEKAROOT=/usr/weka/weka-3-6-10數據庫
export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$WEKAROOT/weka.jar編程
最後別忘了 source /etc/environment,加載新的配置文件。 vim
固然了WEKAROOT換成別的名字也能夠的,如WEKA_PATH等,切記若是想換名字的話,首先用echo命令查看環境變量參數,指令以下: windows
echo $WEKAROOT
而後使用unset命令刪除掉,指令爲unset WEKAROOT
最後新建一個WEKA_PATH環境,新建方法仍然是往environment文件裏寫入並更新。
運行命令:java -Xmx1000M -jar weka.jar(或者java -jar weka.jar)
Java虛擬機進程能構從操做系統那裏挖到的最大的內存,以字節爲單位,若是在運行java程序的時候,沒有添加-Xmx參數,那麼就是64兆,這是java虛擬機默認狀況下能從操做系統那裏挖到的最大的內存。若是添加了-Xmx參數,將以這個參數後面的值爲準,例如本指令下最大內存就是1000兆。
輸入如下代碼:
#!/bin/bash
cd $WEKAROOT 或 cd $WEKA_PATH
java -Xmx1000M -jar weka.jar
保存退出vim
之後要運行weka,只要在命令行裏直接鍵入命令 weka 就能夠了。這裏附上vim編輯的一些經驗:
在 shell 模式下,鍵入vi 及須要編輯的文件名,便可進入vi。
例如:
vi example.txt
便可編輯 example.txt 文件。若是該文件存在,則編輯界面中會顯示該文件的內容,並將光標定位在文件的第一行;若是文件不存在,則編輯界面中無任何內容。若是須要在進入vi 編輯界面後,將光標置於文件的第n 行,則在vi命令後面加上+n 參數便可。例如須要從example.txt 文件的第5 行開始顯示,則使用以下命令:
vi +5 example.txt
退出 vi 時,須要在末行模式中輸入退出命令q。
若是在文本輸入模式下,首先按ESC 鍵進入命令模式,而後輸入": "進入末行模式。在末行模式下,可以使用以下退出命令:
:q 直接退出若是在文本輸入模式下修改了文檔內容則不能退出
:wq 保存後退出
:x 同 wq
:q! 不保存內容強制退出
官方網站提供兩類Windows下的可執行包,一類是OS直接運行的,另外一類是在JVM裏運行的,我下載的是基於JVM運行的類型的可執行包。
安裝過程沒有什麼可說的,Windows下的安裝過程很是簡單易懂。
運行Weka有兩類方式,一類是經過OS的操做方式運行,如雙擊運行或調用exe等等。還有一類是經過Java命令運行。
OS操做下運行Weka感受上是沒有什麼問題,注意是"感受上"沒有問題!事實上經過OS運行,因爲什麼錯誤也沒有,可能發覺不到Weka的一些Warning。直到你須要某項Weka讀取數據庫的功能操做時,才發現怎麼也運行不通,而殊不知道爲何。
在調用Java命令運行的過程當中就發現,幾個關於數據庫讀取的Warning!處理須要必定時間。相關Warning以下:
>java –Xmx1024M –jar weka.jar Trying to add database driver (JDBC): RmiJdbc.RJDriver - Error, not in CLASSPATH? Trying to add database driver (JDBC): jdbc.idbDriver - Error, not in CLASSPATH? Trying to add database driver (JDBC): org.gjt.mm.mysql.Driver - Error, not in CLASSPATH? Trying to add database driver (JDBC): com.mckoi.JDBCDriver - Error, not in CLASSPATH? Trying to add database driver (JDBC): org.hsqldb.jdbcDriver - Error, not in CLASSPATH? |
查詢網絡論壇,說linux和windows均會出現此類問題,我在Ubunntu和Win8都配置過了,確實都會出現這些Warning。
查詢網絡論壇的一些大神的實驗記錄與心得,兩大OS的解決辦法基本相同,先說說Ubuntu
第一步、下載相關數據驅動包,大約有5個jar包,注意Weka3-6對應的這5個jar包版本各自不一樣,必定要找對版本的這5個jar包。例如:對於Weka(version 3.5.5) 對於RmiJdbc,必定選擇版本3.05或2.5。
名字分別爲:hsqldb.jar,idb.jar,mkjdbc.jar,mysql-connector-java-5.1.6-bin.jar,RmiJdbc.jar。
個人Weka版本爲3-6-11,使用3-6-8版本的此5個jar包,沒有問題。
第二步、解壓後把這5個jar包拷貝到/usr/lib/jvm/jdk1.7.0_25 /jre/lib/ext目錄下,你的路徑可能和個人不同,記着是你的jdk安裝路徑就好了。(吐個槽,在這一點上,Ubuntu比Windows好使多了,複製一下這幾個jar包就好了,就不會報錯了。但是Windows你懂的,修改環境變量起來好累。)
第三步、修改weka數據類型和數據庫數據類型的映射。
(對於這步驟操做,Weka官方wiki提供相關文檔操做方法http://weka.wikispaces.com/Properties+file)
在weka.jar裏面有一個文件/weka/experiment/DatabaseUtils.props,記錄了數據庫操做的相關參數。還有不少文件DatabaseUtils.props.msaccess,DatabaseUtils.props.mssqlserver等,分別對應了各個數據庫的操做參數,
若是你使用msaccess,能夠把DatabaseUtils.props.msaccess的內容覆蓋DatabaseUtils.props。
若是不對DatabaseUtils.props修改,可能在鏈接數據庫時一切順利,但在將數據裝入準備預處理時,卻出現找不到數據類型(can not read from database,unknown data type)之類錯誤。
不要緊,在DatabaseUtils.props加入類型映射就OK了。文件中通常有下面的內容(這裏是我用mysql對應的文件覆蓋了):
# JDBC driver (comma-separated list) jdbcDriver=com.mysql.jdbc.Driver # database URL jdbcURL=jdbc:mysql://server_name:3306/database_name # specific data types string, getString() = 0; --> nominal boolean, getBoolean() = 1; --> nominal double, getDouble() = 2; --> numeric byte, getByte() = 3; --> numeric short, getByte()= 4; --> numeric int, getInteger() = 5; --> numeric long, getLong() = 6; --> numeric float, getFloat() = 7; --> numeric date, getDate() = 8; --> date text, getString() = 9; --> string time, getTime() = 10; --> date BigDecimal,getBigDecimal()=11; -->nominal #mysql-conversion CHAR=0 TEXT=0 |
#mysql-conversion下提供的類型通常是不夠的,好比int unsigned就找不到,
因此要加入int是如何映射到weka類型的。
在# specific data types下找到Int對應的java類型,這裏是
int, getInteger() = 5; --> numeric
因此在#mysql-conversion下新增INT=5
再加上UNSIGNED類型,INT_UNSIGNED=6(由於unsigned比signed多一倍的數,爲防止截斷,要取大的類型)
其餘類型的映射依次類推。
注意INT和UNSIGNED之間的下劃線,缺了的話錯誤解決不了,我就在這裏搞了很久。(Note: in case database types have blanks, one needs to replace those blanks with an underscore, e.g., DOUBLE PRECISION must be listed like this:DOUBLE_PRECISION=2. Notes from http://weka.wikispaces.com/weka_experiment_DatabaseUtils.props#toc4)
第四步,最後最重要的是,把DatabaseUtils.props放到home目錄下,重啓Weka後生效。並請注意:不一樣的數據庫,書寫方法與格式不一樣,上面是MySql類型,還有SQL Server2000或Oracle等等,格式是不一樣的,可百度參考相關格式或論壇博客。
對於找不到jdbc驅動的問題,主要是修改RunWeka.ini,由於多次修改classpath都不成功。乾脆將jar文件的地址加到weka指定的運行時classpath中。RunWeka.ini的位置在Weka總目錄下,與Weka.jar是平行目錄。打開後內容底部有以下內容:
# The classpath placeholder. Add any environment variables or jars to it that # you need for your Weka environment. # Example with an enviroment variable (e.g., THIRD_PARTY_LIBS): # cp=%CLASSPATH%;%THIRD_PARTY_LIBS% # Example with an extra jar (located at D:\libraries\libsvm.jar): # cp=%CLASSPATH%;D:\\\\libraries\\\\libsvm.jar # Or in order to avoid quadrupled backslashes, you can also use slashes "/": # cp=%CLASSPATH%;D:/libraries/libsvm.jar cp=%CLASSPATH% |
根據提示,將jdbc驅動jar文件地址附加到cp變量。
好比mysql jdbc驅動(mysql-connector.jar)在E:/jars/下,則加入下面這句:
cp=%CLASSPATH%;E:/jars/mysql-connector.jar
同時把cp=%CLASSPATH%註釋掉,
結果像
cp=%CLASSPATH%;E:/jars/mysql-connector.jar
#cp=%CLASSPATH%
也就是說若是有5個jar包,須要在一行裏一個一個寫進,而不能用寫一個5個jar包所在的總目錄來省事。(網上有人說把那5個Jar包解壓到weka路徑下,而後修改CLASSPATH也能解決,我試過不少次,都不可行。)
至於數據類型映射,參見上面Linux環境下的配置。
最後將DatabaseUtils.props文件放在跟Weka.jar同一目錄下便可。
解決方法有如下幾種:
1、設置系統裏環境變量,由於你在RunWeka.ini內設置了classpath,結果仍然不識別,我想應該爲系統裏的classpath添加路徑。
2、使用java命令行,利用臨時權限添加classpath的方法
上面兩方法,第一種我試了不少遍沒有成功,第二種java命令會有問題,但最終成功。
第二種方法方法細節:
1、使用以下命令格式,可是中途出現一些問題
java -classpath E:/Weka-3-6/jars/RmiJdbc.jar -jar weka.jar
依然報5個錯誤,以下圖。
查詢相關知識,java的此classpath命令會被-jar屏蔽掉,意思就是說若是java命令裏有-jar參數,則會自動屏蔽-classpath添加參數
2、咱們嘗試修改指令
java -Xbootclasspath/a:/E:/Weka-3-6/jars/Rmijdbc.jar: -jar Weka.jar
運行後發現少了一個錯誤,咱們添加的是Rmijdbc驅動包,減小的錯誤剛好是RJDriverError,說明咱們的目前指令成功,若是須要添加多個jar包,則在路徑後面使用分號,逐步添加五個jar包。不要企圖使用目錄,使用目錄仍然不識別。因此添加五個jar包的java指令確實很長。惟一欣慰的是,指令最後成功了,沒有錯誤。不過請注意一點:由上述的分析咱們知道它只是不報驅動錯誤了,之後咱們使用數據庫,它沒法讀取識別數據庫的類型又是另一碼事。(下面有兩張圖,第一個圖第一個指令是展現企圖使用目錄添加classpath是不正確的,第一個圖第二個指令代表添加具體某一個jar包,成功減小了錯誤。第二個圖第二個指令,一口氣寫了五個jar包,最後是成功的零錯誤,正確經過!。)
二元屬性的英文爲"binary attribute",比較好理解。能夠認爲它是一種特殊的標稱屬性,只有兩個類別或狀態:0或1,其中0一般表示該屬性不出現,而1表示出現。二元屬性又稱布爾屬性,若是兩種狀態對應於true和false的話。
標稱屬性的英文爲"nominal attribute",有時候感到很差理解。標稱屬性值既不是具備有意義的順序,也不是定量的。每一個值表明某種類別、編碼或狀態,所以標稱屬性又被看作是分類的(categorical),因此有時候看到顧客的ID或者鞋碼尺寸SIZE等,總會誤認爲是序號屬性。因此標稱屬性要抓住核心概念:標稱只是一種分類,即標稱數值的數學運算毫無心義。顧客ID有時候會是數值屬性,但注意應用的時候,若是顧客ID之間的數值加減乘除沒有任何意義,則咱們不認爲它是數值屬性,認爲其爲標稱屬性更爲恰當。以年齡爲例,年齡之間經常涉及到加減,因此年齡總認爲是數值屬性,鞋碼大小不太涉及到加減意義,故認爲標稱的。
數值屬性的英文爲"numericattribute",它是定量的,它是可度量的量。抓住這個概念,也就是說它的數值是有意義的,能夠參與加減乘除運算的,其值進行數學運算的結果經常是有意義的。
序數屬性的英文單詞爲"ordinal attribute",也是不太好理解的一個屬性。可是切記序數屬性能夠經過數值屬性離散化獲得,而且序數屬性每每攜帶一種重要意義,就是具備有意義的前後次序。以快餐店售賣可樂大小杯爲例,0表示小杯,1表示中杯,2表示大杯。它們既能夠認爲是序數屬性,也能夠認爲是間接的標稱屬性。或以顧客滿意度調查爲例,0是很不滿意,1是不太滿意,2是通常,3是滿意,4是很是滿意。
WEKA可識別ARFF格式,也可識別CSV電子數據表格式。雖然咱們知道WEKA-Explorer對於二者格式都可以讀取,但對於CSV格式與ARFF格式比較感興趣。
這裏寫出CSV的格式,以weather.csv爲例,其內容以下表所示。至於其arff格式的規範,咱們經過看後續部分,就發現二者實際上經過手動改寫。ARFF格式實際上就是統計了CSV格式的屬性分類,並增強規範。
outlook,temperature,humidity,windy,play 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 |
1、咱們知道WEKA讀取時會自動轉化
2、若是須要人爲干預,須要處理兩個格式的內容,那麼這就是比較有意思的事情了
ARFF文件是Weka默認的儲存數據集文件。每一個ARFF文件對應一個二維表格。表格的各行是數據集的各實例,各列是數據集的各個屬性。
下面是Weka自帶的"weather.arff"文件,在Weka安裝目錄的"data"子目錄下能夠找到。 須要注意的是,在Windows記事本打開這個文件時,可能會由於回車符定義不一致而致使分行不正常。推薦使用UltraEdit這樣的字符編輯軟件察看ARFF文件的內容。
%ARFF file for the weather data with some numric features % @relation weather @attribute outlook {sunny, overcast, rainy} @attribute temperature real @attribute humidity real @attribute windy {TRUE, FALSE} @attribute play {yes, no} @data % % 14 instances % 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 |
識別ARFF文件的重要依據是分行,所以不能在這種文件裏隨意的斷行。空行(或全是空格的行)將被忽略。
以"%"開始的行是註釋,WEKA將忽略這些行。若是你看到的"weather.arff"文件多了或少了些"%"開始的行,是沒有影響的。
除去註釋後,整個ARFF文件能夠分爲兩個部分。第一部分給出了頭信息(Head information),包括了對關係的聲明和對屬性的聲明。第二部分給出了數據信息(Data information),即數據集中給出的數據。雖然Weka也支持其餘一些格式的文件,可是ARFF格式是支持的最好的。所以有必要在數據處理以前把CSV數據集的格式轉換成ARFF。
將CSV轉換爲ARFF最迅捷的辦法是使用WEKA所帶的命令行工具。運行WEKA的主程序,在菜單中找到"Simple CLI"模塊,它可提供命令行功能。在新窗口的最下方(上方是不能寫字的)的輸入框寫上
java weka.core.converters.CSVLoader filename.csv > filename.arff
便可完成轉換。
在WEKA 3.6中提供了一個"Arff Viewer"模塊(在Tools裏),咱們能夠用它打開一個CSV文件將進行瀏覽,而後另存爲ARFF文件。 進入"Exploer"模塊,從上方的按鈕中打開CSV文件而後另存爲ARFF文件亦可。
Excel的XLS文件可讓多個二維表格放到不一樣的工做表(Sheet)中,咱們只能把每一個工做表存成不一樣的CSV文件。打開一個XLS文件並切換到須要轉換的工做表,另存爲CSV類型,點"肯定"、"是"忽略提示便可完成操做。接下來把獲得的CSV文件按照前述步驟轉換爲ARFF便可。
Confusion Matrix是混淆矩陣,提供的評估標準,以下表所示。
Predicted |
C1 |
¬ C1 |
ALL |
|
Actual |
C1 |
True Positives (TP) |
False Negatives (FN) |
P |
¬ C1 |
False Positives (FP) |
True Negatives (TN) |
N |
對於C1事件來講,可將其當作事件中的正面事件,或稱爲真事件,或稱爲陽事件。因爲預測結果爲C1事件,既然結果爲陽事件,正事件。說明實際過程可能由正到正,由負到正,均可成爲真正,假正,說明預測都是正的。故TP可稱爲判正得正或真陽率或真正率,FP則爲判負爲正或假陽率或假正率。同理FN可推理成爲判正得負或真陰率或真反率,TN順理爲判負得負或真陰率或假反率。
準確率(識別率)
召回率(靈敏度)
精度
反映的是分類器的真正例率(TPR,靈敏度)和假正例率(FPR)之間的權衡,簡而言之就說觀察"真判正"佔據"判真"的比率。以下圖所示。
點擊choose按鈕,能夠選擇weka提供的分類器。經常使用的分類器有:
a)bayes下的Naïve Bayes(樸素貝葉斯)和BayesNet(貝葉斯信念網絡)。
b)functions下的LibLinear、LibSVM(這兩個須要安裝擴展包)、Logistic Regression、Linear Regression。
c)lazy下的IB1(1-NN)和IBK(KNN)。
d)meta下的不少boosting和bagging分類器,好比AdaBoostM1。
e)trees下的J48(weka版的C4.5)、RandomForest。
評價模型效果的方法,有四個選項。
a)Use training set:使用訓練集,即訓練集和測試集使用同一份數據,通常不使用這種方法。
b)Supplied test set:設置測試集,可使用本地文件或者url,測試文件的格式須要跟訓練文件格式一致。
c)Cross-validation:交叉驗證,很常見的驗證方法。N-folds cross-validation是指,將訓練集分爲N份,使用N-1份作訓練,使用1份作測試,如此循環N次,最後總體計算結果。
d)Percentage split:按照必定比例,將訓練集分爲兩份,一份作訓練,一份作測試。在這些驗證方法的下面,有一個More options選項,能夠設置一些模型輸出,模型驗證的參數。
這個區域保存分類實驗的歷史,右鍵點擊記錄,能夠看到不少選項。經常使用的有保存或加載模型以及可視化的一些選項。
分類器的輸出結果,默認的輸出選項有Run information,該項給出了特徵、樣本及模型驗證的一些概要信息;Classifier model,給出的是模型的一些參數,不一樣的分類器給出的信息不一樣。最下面是模型驗證的結果,給出了 一些經常使用的一些驗證標準的結果,好比準確率(Precision),召回率(Recall),真陽性率(True positive rate),假陽性率(False positive rate),F值(F-Measure),Roc面積(Roc Area)等。混淆矩陣(Confusion Matrix)給出了測試樣本的分類狀況,經過它,能夠很方便地看出正確分類或錯誤分類的某一類樣本的數量。
爲何要用舊版?
舊版因爲受衆廣,新版雖然新,但API的接口修改沒有那麼普遍。此舊版WEKA增長新版WEKA所沒有的功能,受衆修改的程度也較爲普遍,如增長ID3可視化樹的功能。此版原本自於伍斯特理工學院。軟件下載網址以下:
http://davis.wpi.edu/~xmdv/weka/
下載舊版的WEKA後,安裝包的狀況以下圖所示。
然而直接運行RunWeka是能夠成功的,界面以下:
然而有一個問題,就是點擊該舊版Explorer按鈕後,沒有任何反應或響應。沒有反應的緣由,是由於沒有GL4Java,若是想運行Explorer,必須安裝它(舊版網址也強調了該環境)。
那麼在以下網址尋找一個插件GL4Java:
http://jausoft.com/Files/Java/1.1.X/GL4Java/binpkg/
GL4Java-Installer裏面有主安裝程序,然而主安裝程序須要一些插件輔助安裝
插件的輔助清單以下圖紅色框內標註所示:
將輔助的插件下載並保存與舊版WEKA同一目錄的文件夾內,命名爲"binpkg",文件夾內的目錄結構以下圖所示,binpkg文件夾內放置都是輔助插件:
而後點擊GL4Java內的install.bat,就能夠正常安裝了,安裝界面以下:
切記選中本身安裝JDK的位置,而後點擊Start便可。
注意:RunWeka.bat和install.bat的點擊時不要以管理員身份運行,一旦以管理員身份運行,反而控制檯出不來,因此直接雙擊就好。
在打開舊版的WEKA後,點擊Explorer,能夠出現Explorer界面。
參看分類器挖掘時,咱們在使用ID3分類時,可視化樹的按鈕是灰色的。而使用舊版WEKA後,能夠看到可視化樹的按鈕是能夠點擊的。以下圖所示。
利用weka提供的決策樹算法,對提供的bank-data.csv數據進行決策樹分類挖掘。做業需完成如下內容:
(1)瞭解weka提供的數據預處理功能,去除bank-data數據中的無用屬性(如ID)結構,並對income屬性進行離散化處理;
(2)利用weka提供的多個決策樹概括算法,構建決策樹模型(最後一個屬性pep做爲須要預測的屬性),比較不一樣算法所構建模型的差異;
(3)對各類決策胡算法的預測結果進行分析,並比較分類性能。
讀取bank-data.csv格式數據,以下圖所示。
其中bank-data數據內容呈現出來,以下圖所示。
刪除無用參數ID,以下圖所示。
另存爲ARFF格式,並用UltraEdit打開,觀察數據格式,以下圖所示。
根據ARFF數據格式,展現該數據的屬性以下。
@attribute age numeric @attribute sex {FEMALE,MALE} @attribute region {INNER_CITY,TOWN,RURAL,SUBURBAN} @attribute income numeric @attribute married {NO,YES} @attribute children numeric @attribute car {NO,YES} @attribute save_act {NO,YES} @attribute current_act {NO,YES} @attribute mortgage {NO,YES} @attribute pep {YES,NO} |
其中{YES,NO}是二元屬性,{INNER_CITY,TOWN,RURAL,SUBURBAN}是標稱屬性,至於{FEMALE,MALE}是標稱屬性或二元屬性,而numeric認爲是數值屬性。
說句實話,這些屬性初學時基本分不清,還要對照課件才能分清楚,甚至有時對照課件都會分不清楚。因此以爲不能脫離英文環境,必需要結合英文,增強理解。可參見WEKA的數據準備裏相關知識。
咱們作一些簡單修改,經過觀察WEKA中某一參數的分佈,如children個數,以下圖所示。
children的取值分佈爲離散,WEKA軟件顯示children的Type是Numeric。咱們觀察直方圖,children取值爲0,1,2,3中的一個。咱們修改ARFF格式數據,將
@attribute children numeric
修改成(請注意區分全角半角的符號)
@attribute children {0,1,2,3}
從新使用WEKA讀入,再點擊children參數,發現其Type更改成Nominal。以下圖所示。
這說明了一點,那就是標稱屬性與數值屬性在應用時可能沒有明顯的界限,只要數據屬性服務於咱們的要求就行。
選中income,而後選擇Filter-unsupervised-attribute-Discretize,而後進行後續操做,以下圖所示。
修改income的離散化參數,雙擊choose按鈕旁的命令欄,彈出weka.gui.GenericObjectEditor對話框,最上方兩行分別是取值區間,分紅幾類。修改的參數以下圖所示。
點擊OK,再在命令欄右邊的按鈕,爲保證對照對比income的分類狀況,咱們先觀察不該用離散處理以前的情形,以下圖所示。
點擊Apply,對income應用離散化後的生成數據情形,以下圖所示,顯然將income參數分紅了三部分。
咱們發現一個有趣的事實,那就是age參數也被分紅了三份,以下圖所示。
我猜想多是由於在屬性裏面,因爲咱們剛剛修改了children,僅剩下age和income兩個參數沒有改動,且仍然保持numeric類型,應用離散化時,結果把這兩個都分紅了三類。說明有兩個操做無效:一是隻要符合離散化條件的,weka都作離散化,無論你選不選中income;二是對已有標稱數值的屬性做離散化處理是無效的。
打開classifier,點擊choose,在分類算法中選擇trees-J48,以下圖所示。
選擇完J48分類器後,返回到classifier界面,在TestOptions內勾選交叉驗證(Cross-validation),旁邊的默認值10指的是十折交叉驗證。在MoreOptions中勾選Output predictions。參數設置以下圖所示。
點擊Start,啓動實驗,在右側的classifier ouput內咱們能夠看到J48分類器的分類實驗結果。以下圖所示。
本分類器的分類驗證結果,以下圖所示。
經過右鍵點擊實驗記錄時間點,選擇點擊Visualize Tree,能夠生成可視化生成樹,點擊操做以下圖所示。
由下圖可知,這是預測結果的數據,能夠看到每一個樣本的實際分類,預測分類,預測機率以及是否錯分等信息。
其中咱們將分類結果文字清晰地呈現出來,進行分析。以下表所示。
=== Stratified cross-validation === === Summary === Correctly Classified Instances 510 85% Incorrectly Classified Instances 90 15% Kappa statistic 0.6983 Mean absolute error 0.2209 Root mean squared error 0.3518 Relative absolute error 44.5145% Root relative squared error 70.6212% Total Number of Instances 600 === Detailed Accuracy By Class === TP Rate FP Rate Precision Recall F-Measure ROC Area Class 0.847 0.147 0.829 0.847 0.838 0.862 YES 0.853 0.153 0.869 0.853 0.861 0.862 NO Weighted Avg. 0.85 0.151 0.85 0.85 0.85 0.862 === Confusion Matrix === a b <-- classified as 232 42 | a = YES 48 278 | b = NO |
生成的可視化樹,因爲節點或分類參數較多,部分節點沒法看清,但整體脈絡能夠以下圖所示。
Explorer的Visualize面板,能夠觀察兩兩特徵之間的樣本點分佈情形,以下圖所示。
隨便選一個區域,例如選擇pep和age交叉對應的區域,點擊後會出現新的圖框,以展現pep特徵與age特徵之間的關係。以下圖所示。
迴歸到Classifier面板下的ResultLists右鍵選擇實驗記錄點,而後選擇點擊Visualize Classify Errors,以下圖所示。
選擇Visualize Classify Errors此項參數,而後會生成可視化結果,這個結果實際上對應的是可視化的混淆矩陣圖示,也就是能夠展現誤判機率點(正判反,反判正),正確判別機率點(正判正,反判反),圖像中十字點表示對判,方形點表示誤判,X軸表示實際類別,Y軸表示預測類別。以下圖所示。把鼠標放到點上,點擊後也能跳出特徵點的具體值,方便觀察和研究特徵點離羣緣由或不符合正常結論的緣由。
同理咱們再選取讀取Visualize threshold curve參數,選擇YES(正類),以下圖所示。
Visualize threshold curve參數顯示的是分類置信度在不一樣閾值下,分類效果評價標準的對比狀況,其中就包括ROC曲線(縱軸爲TP,橫軸爲FP),以下圖所示。
下面給出ID3的分類文字結果。
=== Stratified cross-validation === === Summary === Correctly Classified Instances 463 77.1667 % Incorrectly Classified Instances 123 20.5 % Kappa statistic 0.5789 Mean absolute error 0.2112 Root mean squared error 0.4536 Relative absolute error 43.5901 % Root relative squared error 92.1819 % UnClassified Instances 14 2.3333 % Total Number of Instances 600 === Detailed Accuracy By Class === TP Rate FP Rate Precision Recall F-Measure ROC Area Class 0.801 0.219 0.753 0.801 0.776 0.784 YES 0.781 0.199 0.825 0.781 0.803 0.79 NO Weighted Avg. 0.79 0.208 0.792 0.79 0.79 0.787 === Confusion Matrix === a b <-- classified as 213 53 | a = YES 70 250 | b = NO |
下面給出ID3的分類結果的圖片示意。
生成的可視化樹步驟中發現沒法生成ID3分類器,說明WEKA原版軟件沒有提供ID3的可視化樹,故我使用了舊版WEKA,獲得了相關的可視化樹。
(圖片這麼長的緣由,一是分類樹有些寬大,二是我對筆記本電腦使用了擴展屏幕截屏所致。)
至於特徵之間的關係,以下圖所示。
咱們選擇Age和Income之間的關係進行分析,以下圖所示。能夠觀察到年齡越小,收入越高的樣本基本不存在,密集程度較高的是年齡又小收入又少的情形。
其ROC曲線能夠如圖所示:
NBTree是Naive Bayesian分類樹,下面給出分類文字結果。
=== Stratified cross-validation === === Summary === Correctly Classified Instances 502 83.6667 % Incorrectly Classified Instances 98 16.3333 % Kappa statistic 0.6697 Mean absolute error 0.2165 Root mean squared error 0.3592 Relative absolute error 43.6251 % Root relative squared error 72.1096 % Total Number of Instances 600 === Detailed Accuracy By Class === TP Rate FP Rate Precision Recall F-Measure ROC Area Class 0.799 0.132 0.836 0.799 0.817 0.879 YES 0.868 0.201 0.837 0.868 0.852 0.879 NO Weighted Avg. 0.837 0.169 0.837 0.837 0.836 0.879 === Confusion Matrix === a b <-- classified as 219 55 | a = YES 43 283 | b = NO |
在運行狀態中,出現明顯的停滯和計算停留,說明該分類樹收斂慢,計算速度中等,佔用必定時間,沒有J48分類快速。
在這裏咱們簡單展現NBTree的可視化樹
其ROC曲線能夠以下所示:
因爲篇幅過長,這裏再也不列舉其餘幾類分類樹的所有過程。我還測試了隨機樹Random Tree等等其餘分類器的分類效果,測試狀態如圖所示。
在上述三種方法中,由數據分析我能夠看到J48的分類效果最好,達到85%,其次是貝葉斯分類,達到83.7%,最差是ID3分類僅有77.1%。
而在WEKA提供的全部方法中,面對bank數據下,我將全部分類器的結果列舉成表,以供閱覽:
Method Name |
Correctly |
InCorrectly |
TP/FN/FP/TN |
BuildModelTIme |
J48Graft |
85.0000 % |
15.0000 % |
232/42/48/278 |
0.05 sec |
J48 |
85.0000 % |
15.0000 % |
232/42/48/278 |
0.18 sec |
LMT |
84.1667 % |
15.8333 % |
222/52/43/283 |
16.19 sec |
NBTree |
83.6667 % |
16.3333 % |
219/55/43/283 |
7.3 sec |
REPTree |
83.5000 % |
16.5000 % |
229/45/54/272 |
0.02 sec |
SimpleCart |
82.3333 % |
17.6667 % |
213/61/45/281 |
2.04 sec |
LADTree |
81.5000 % |
18.5000 % |
201/73/38/288 |
0.47 sec |
ADTree |
80.5000 % |
19.5000 % |
192/82/35/291 |
0.19 sec |
BFTree |
80.3333 % |
19.6667 % |
217/57/61/265 |
2.07 sec |
RandomForest |
79.8333 % |
20.1667 % |
218/56/65/261 |
0.04 sec |
ID3 |
77.1667 % |
20.5000 % |
213/53/70/250 |
0.13 sec |
RandomTree |
74.8333 % |
25.1667 % |
200/74/77/249 |
0.07 sec |
FT |
72.5000 % |
27.5000 % |
190/84/81/245 |
2.33 sec |
DecisionStump |
68.5000 % |
31.5000 % |
110/164/25/301 |
0.00 sec |
解釋部分算法:DecisionStump是單層決策樹算法,常被做爲boosting的基本學習器。LMT是組合樹結構和Logistic迴歸模型,每一個葉子節點是一個Logistic迴歸模型,準確性比單獨的決策樹和Logistic迴歸方法要好。NBTree是貝葉斯分類法。ADTree是一種基於boosting的決策樹學習算法,其預測準確率比通常決策樹高,並能夠給出預測置信度,實際中常使用它的改良BICA算法。
由觀察可知,J48的分類性能最好。時間收斂快,分類準確。除REPTree外,其他識別率達到80%以上的算法,收斂時間均比J48要長,分類準確性略遜一籌。值得敬佩J48的繼承性與改進性,也向ID3致以敬意,沒有ID3的優勢,C4.5也不會繼承,C4.5的信息增益率和剪枝策略是增強收斂與提升準確的重要手段。
利用weka提供的文本分類器實現英文垃圾郵件的過濾,須要完成內容以下:
(1)瞭解垃圾郵件過濾基本思想;
(2)利用weka的預處理功能將文本轉化爲向量;
(3)利用weka提供的分類算法實現垃圾郵件的過濾,最少使用兩種分類器;
(4)分析分類結果,並對分類器的性能進行比較。實驗過程
小知識:1978年5月3日,星期六。網絡時代第一批垃圾郵件,由美國DEC公司經過互聯網的前身阿帕網發送給了393個接收者。垃圾郵件,指的是不請自來、強行塞入信箱的郵件。在若干年前,郵箱存儲空間廣泛很小,垃圾郵件可以塞爆郵箱,讓人們沒法工做。
簡要分析垃圾郵件過濾的實驗過程。個人初步思路是將語料庫轉化爲向量,而後分析向量模式,過濾敏感詞。最後獲得垃圾樣本的分類。那麼這樣文縐縐的話如何實踐是個問題,能夠說徹底不知道。經過查閱互聯網,明白其中含義。
語料庫轉化爲向量,無非是將語料庫的文字轉化爲arff格式的可讀文本,而且要將文本分詞處理,去標點處理等等,不然不能讀入WEKA進行後續過濾。
分析向量模式,無非是用WEKA分類器去作分析。
咱們既能夠本身使用Java編程或Python編程,將語料庫轉換爲Arff格式,並作相關處理。也可使用WEKA的接口,其提供了文本處理的一條龍服務,堪稱業內楷模。
其命令行接口在Simple CLI按鈕彈出的界面內,以下圖所示:
咱們使用WEKA的兩類功能
TextDirectoryLoader
StringToWordVector
上者具備的功能爲將文本轉換爲ARFF格式,下者具備的功能爲將文本分詞,去標點處理等。
首先將文本語料以以下目錄結構放置,不然WEKA命令行處理失敗:
其次,值得一提bare是老師所給語料庫的文件名,以及二級目錄與末端文件都是老師所給的文件名,也能夠根據本身須要隨意重命名,只要目錄關係正確就行。個人語料庫所有放在test文件夾內,因此個人執行命令語句以下,並如圖所示:
java weka.core.converters.TextDirectoryLoader -dir test > all_text_examples.arff
咱們能夠打開今生成ARFF文件,內容以下圖所示:
觀察可知,WEKA將文本語料庫讀入後,將每一個Part的文件夾內的全部文本歸爲每一類class。每一類的class內的文本有多個,接下來咱們要對每一個class內的每將文本做切割處理分詞。
接下來,使用WEKA讀入文本數據,每一個文件夾內的文本數量狀態能夠以下圖所示:
上面a)文本數據讀入,觀察其中的圖片,能夠看到文本讀入後的類有part1至part7。請注意,這樣的part個數是不對的!這並非說目錄結構不對,而是說文本過濾訓練的模型建模的不對!
既然要訓練模型分爲"不是垃圾郵件(NO)"和"是垃圾郵件(YES)",那麼咱們的訓練集固然在訓練之處,就僅分爲兩個類別纔對。即把垃圾郵件的文本整合在一個文件夾內,不是垃圾郵件的文本整合在另外一個文件夾內,總共才兩個文件夾,而不是以前part1至part7的七個文件夾。
只有分紅兩個文件夾去訓練,這纔是正確的分類結果。若是是part1至part7這樣的設置,到最後訓練出來的模型效果很是差。指標Relative absolute error大約高達98%,說明根本就沒有分類。因此在訓練集上,務必就分紅兩個類,一個類全是正常郵件,另外一個類全是垃圾郵件。以下圖所示:
而後選擇Filter內unsupervised-attribute-StringToWordVector方法,操做如圖所示:
這裏簡要介紹一下StringToWordVector可能須要本身作調整的參數:
-W 須要保留的單詞個數,默認爲1000。這不是最終的特徵維數,可是維數跟此參數是正相關的
-stopwords <file> 輸入停詞文件,文件格式爲每個詞一行。在讀文件到轉化特徵時會自動去掉這些經常使用詞,系統自帶有一套停用詞。
-tokenizer <spec> 自定義所要去除的符號,通常爲標點符號。默認有經常使用的標點符號,但每每是不夠的,因此需本身添加
其餘參數只需默認值便可,能夠按照圖中紅框的顯示值修改好,可如圖所示修改。
在GUI當中,還有一些參數設置須要介紹:lowerCaseTokens是否區分大小寫,默認爲false不區分,這裏通常要設置爲ture,由於同一個詞就會有大小寫的區別。至此文本便被分離成向量化格式。正確的向量化文本應當以下圖所示:
咱們注意到文本向量化的結構大體爲以下,下面使用僞代碼進行示意向量化文本的內容:
@attribute @@class@@ {msg,spam}
@attribute WORD1 numeric
@attribute WORD2 numeric
@attribute WORD3 numeric
@attribute WORD4 numeric
{1 0.693147,2 1.098612,4 1.386294,……,}
{4 2.70805 ,7 1.098612,8 2.639057,……,}
{0 spam,8 4.672829,9 1.791759,13 1.791759,……,}
{0 spam,2 3.218876,4 1.386294,8 2.397895,……,}
這裏class的標籤放在第一列。spam表明垃圾郵件,而沒有標出標籤的表明正常郵件,即msg。爲何spam標記出來而msg沒有,這說明WEKA的命令一脈相承,即便沒有出現msg標籤,也能夠繼續投入使用。
懶惰分類器顧名思義,該算法不須要太操心,投入便可使用,參數使用起來方便,參數設定不須要太專業,天然效果通常。IBk本質上就是距離爲k的k最近鄰分類器。IB1顯然就是距離爲1的k近鄰分類,距離爲1說明只有一個鄰居,也就是說IB1總共分紅兩個類。選擇IBk該分類器的流程以下圖所示:
因爲該垃圾郵件的結論具備二值性,要麼是垃圾郵件,要麼不是垃圾郵件。故在kNN個數上設置爲1,也就是說總共分紅兩個類進行訓練。交叉驗證設爲三份,便於訓練快速。以下圖所示:
因而,最後一步,切記將分析對象調整至class標籤,不然分類不正確。調整對象的操做流程可下圖所示。
最後,咱們的圖片結果以下:
文字結果摘錄以下:
=== Stratified cross-validation === === Summary === Correctly Classified Instances 1942 88.9194 % Incorrectly Classified Instances 242 11.0806 % Kappa statistic 0.5221 Mean absolute error 0.1113 Root mean squared error 0.3326 Relative absolute error 42.6065 % Root relative squared error 92.0846 % Total Number of Instances 2184 === Detailed Accuracy By Class === TP Rate FP Rate Precision Recall F-Measure ROC Area Class 0.959 0.496 0.914 0.959 0.936 0.733 msg 0.504 0.041 0.694 0.504 0.584 0.733 spam Weighted Avg. 0.889 0.425 0.88 0.889 0.882 0.733 === Confusion Matrix === a b <-- classified as 1772 75 | a = msg 167 170 | b = spam |
觀察分類效果,正確分類達到88.9%,這個結果較爲不錯,能夠接受,能夠認爲分類訓練較爲合理。觀察精度precision可知,平均爲88%,查全率大約爲89%。整體效果良好。
咱們使用聚類來作一次分析,請注意垃圾的過濾模型須要分類挖掘,而不是聚類。這裏作聚類僅僅是觀察樣本的區分程度。
選擇SimpleKMeans聚類,將聚類簇數設爲兩個,並將聚類分析對象設定爲class標籤,最後生成結果以下:
文字結果大體以下:
Number of iterations: 11 Within cluster sum of squared errors: 43032.64174958714 === Model and evaluation on training set === Clustered Instances 0 464 ( 21%) 1 1720 ( 79%) Class attribute: @@class@@ Classes to Clusters: 0 1 <-- assigned to cluster 388 1459 | msg 76 261 | spam Cluster 0 <-- spam Cluster 1 <-- msg Incorrectly clustered instances : 649.0 29.7161 % |
由此觀察可知,迭代11次後聚成兩類,聚類失敗的樣本大約爲29%,即有71%的樣本能夠成功聚類,在這71%的可聚在一塊兒的樣本中又有其中的79%聚成1號類,其中的21%聚成0號類。
利用weka提供的k-means算法,對提供的bank-data.csv數據進行決策樹分類挖掘。做業需完成如下內容:
(1)瞭解weka提供的數據預處理功能,去除bank-data數據中的無用屬性(如ID)結構,並對income屬性進行離散化處理;
(2)利用weka提供的k-means算法,進行聚類分析,k選不一樣取值,查看並比較聚類結果;
(3)選擇不一樣的距離函數,從新進行聚類分析,並比較聚類結果。
數據預處理工做和以前在分類挖掘類似。
咱們對bank數據做聚類分析,選擇K-Means算法。操做選項如圖所示:
選擇完畢後,須要對K-Means聚類設置相關參數,主要的設置區域如圖所示:
顯然參數設置的不一樣,爲聚類帶來的效果也不一樣。
主要的參數爲NumCluster和Seed。
前者爲聚類簇數,後者爲種子數。
設置聚成2類以後,生成結果以下:
文字結果大體摘錄以下:
Number of iterations: 3 Within cluster sum of squared errors: 1737.4061909284878 Time taken to build model (full training data) : 0.24 seconds === Model and evaluation on training set === Clustered Instances 0 252 ( 42%) 1 348 ( 58%) Class attribute: pep Classes to Clusters: 0 1 <-- assigned to cluster 121 153 | YES 131 195 | NO Cluster 0 <-- YES Cluster 1 <-- NO Incorrectly clustered instances : 284.0 47.3333 % |
假設咱們將簇數取爲3,隨機數爲10。生成結果以下:
以及主要指標結果:
能夠觀察其可視化結果,如圖所示:
展現年齡與pep的關係
展現收入與pep的關係
展現地域與pep的關係
由上述幾幅圖咱們能夠看出聚類效果並很差,在簇點下聚類點顏色混雜度較高,區分度很差,辨析度不強,不能有效挖掘關係。其重要斷定指標文字結果以下:
Class attribute: pep Classes to Clusters: 0 1 2 <-- assigned to cluster 114 90 70 | YES 125 125 76 | NO Cluster 0 <-- YES Cluster 1 <-- NO Cluster 2 <-- No class Incorrectly clustered instances : 361.0 60.1667 % |
調整參數及生成結果以下
參數 |
NumCluster |
Seed |
squared errors |
Incorrectly instances |
2 |
2 |
10 |
1737.4 |
284.0 47.3333 % |
2 |
20 |
1723.0 |
294.0 49 % |
|
2 |
30 |
1778.3 |
261.0 43.5 % |
|
2 |
40 |
1752.7 |
272.0 45.3333 % |
|
2 |
50 |
1756.1 |
259.0 43.1667 % |
|
2 |
100 |
1773.0 |
271.0 45.1667 % |
|
3 |
3 |
10 |
2143.0 |
361.0 60.1667 % |
3 |
20 |
2121.0 |
378.0 63 % |
|
3 |
30 |
2168.0 |
340.0 56.6667 % |
|
3 |
40 |
2166.0 |
341.0 56.8333 % |
|
3 |
50 |
2159.0 |
319.0 53.1667 % |
|
3 |
100 |
2151.0 |
295.0 49.1667 % |
|
4 |
4 |
10 |
1991.0 |
416.0 69.3333 % |
4 |
20 |
2018.0 |
400.0 66.6667 % |
|
4 |
30 |
2118.0 |
353.0 58.8333 % |
|
4 |
40 |
2071.0 |
393.0 65.5 % |
|
4 |
50 |
2069.0 |
336.0 56 % |
|
4 |
100 |
2046.0 |
349.0 58.1667 % |
|
5 |
5 |
10 |
1916 |
441.0 73.5 % |
5 |
20 |
1935.0 |
416.0 69.3333 % |
|
5 |
30 |
1976.0 |
388.0 64.6667 % |
|
5 |
40 |
1925.0 |
426.0 71 % |
|
5 |
50 |
1956.0 |
378.0 63 % |
|
5 |
100 |
1971.0 |
374.0 62.3333 % |
|
6 |
6 |
10 |
1889.0 |
441.0 73.5 % |
6 |
20 |
1864 |
414.0 69 % |
|
6 |
30 |
1899.0 |
407.0 67.8333 % |
|
6 |
40 |
1914.0 |
434.0 72.3333 % |
|
6 |
50 |
1887.0 |
396.0 66 % |
|
6 |
100 |
1864.0 |
401.0 66.8333 % |
|
7 |
7 |
10 |
1805.0 |
472.0 78.6667 % |
7 |
20 |
1832 |
419.0 69.8333 % |
|
7 |
30 |
1854.0 |
411.0 68.5 % |
|
7 |
40 |
1831.0 |
453.0 75.5 % |
|
7 |
50 |
1805.0 |
414.0 69 % |
|
7 |
100 |
1813.0 |
416.0 69.3333 % |
|
8 |
8 |
10 |
1807.0 |
473.0 78.8333 % |
8 |
20 |
1733 |
445.0 74.1667 % |
|
8 |
30 |
1756.0 |
447.0 74.5 % |
|
8 |
40 |
1702.0 |
459.0 76.5 % |
|
8 |
50 |
1689.0 |
433.0 72.1667 % |
|
8 |
100 |
1745.0 |
450.0 75 % |
|
9 |
9 |
10 |
1750.0 |
482.0 80.3333 % |
9 |
20 |
1688 |
454.0 75.6667 % |
|
9 |
30 |
1718.0 |
451.0 75.1667 % |
|
9 |
40 |
1681.0 |
476.0 79.3333 % |
|
9 |
50 |
1721.0 |
460.0 76.6667 % |
|
9 |
100 |
1657.0 |
465.0 77.5 % |
|
10 |
10 |
10 |
1655.0 |
497.0 82.8333 % |
10 |
20 |
1647.0 |
459.0 76.5 % |
|
10 |
30 |
1707.0 |
455.0 75.8333 % |
|
10 |
40 |
1599.0 |
495.0 82.5 % |
|
10 |
50 |
1608 |
469.0 78.1667 % |
|
10 |
100 |
1617.0 |
470.0 78.3333 % |
在同一狀況下,根據當前Within cluster sum of squared errors,調整"seed"參數,觀察Within cluster sum of squared errors(SSE)變化。採納SSE最小的一個結果。
結合實際狀況,對於pep僅有YES,NO的兩個結果的事實,通常聚簇調整爲2個。再在2個聚簇的條件內選擇合適的方差中心。
鑑於K-Means聚類的操做解釋足夠詳細,這裏有詳有略地介紹實驗內容。以下圖展現選擇聚類方法:
在以下圖所示的按鈕中,點擊cluster的命令行欄,彈出通知,點選choose能夠更換不一樣的距離函數。
咱們當前選擇歐式距離,選擇分析對象爲Pep,再運行start。生成的圖片結果爲:
文字摘錄結果以下:
Time taken to build model (full training data) : 16.32 seconds === Model and evaluation on training set === Clustered Instances 0 599 (100%) 1 1 ( 0%) Class attribute: pep Classes to Clusters: 0 1 <-- assigned to cluster 274 0 | YES 325 1 | NO Cluster 0 <-- NO Cluster 1 <-- No class Incorrectly clustered instances : 275.0 45.8333 % |
對比K-Means聚類,KMeans聚類的參數結果以下。
KMeansIncorrectly clustered instances : 284 43.3333 %
那麼再看看層次聚類的結果
0 1 <-- assigned to cluster
274 0 | YES 45.7%
325 1 | NO 54.3%
對比KMeans聚類
Clustered Instances
0 252 ( 42%)
1 348 ( 58%)
爲何這麼對比,爲何層次聚類的其中某一個樣本單獨做爲一個類。緣由在於層次聚類的規則算法,詳情可參見書籍或互聯網。層次聚類的最後一次操做,固然爲大集合類與最後一個類的合併過程。故WEKA的層次聚類停留在最後一次上。在對比標籤的類上,二者聚類的效果近似,沒有明顯分別。
咱們更換距離函數爲切比雪夫距離公式,測試結果如圖所示。
文字結果摘錄以下。
Time taken to build model (full training data) : 8.87 seconds === Model and evaluation on training set === Clustered Instances 0 1 ( 0%) 1 599 (100%) Class attribute: pep Classes to Clusters: 0 1 <-- assigned to cluster 1 273 | YES 0 326 | NO Cluster 0 <-- YES Cluster 1 <-- NO Incorrectly clustered instances : 273.0 45.5 % |
曼哈頓距離(Manhattan Distance)能夠理解爲一階範數距離,歐式距離(Euclidean Distance)能夠理解爲二階範數距離,切比雪夫距離(Chebyshev Distance)能夠理解爲無窮範數距離。故在更改選擇距離範數的策略上,可能不具備左右影響力,緣由在於距離函數的公式彼此之間相差無幾。
對於K-Means算法,其時間複雜度爲O(tKmn),其中,t爲迭代次數,K爲簇的數目,m爲數據記錄數,n爲維數
空間複雜度爲O((m+K)n),其中,K爲簇的數目,m爲數據記錄數,n爲維數。
以實驗爲例,在簇數爲2的情形下分析bank數據,迭代次數爲3次,數據記錄數大約爲600條,維數爲11維。時間複雜度大約爲3萬,空間複雜度大約爲6千。
對於層次聚類算法,層次聚類的空間複雜度O(m2)。總時間複雜度O(m2logm),其中m是數據記錄數。對於本實驗而言,空間複雜度大約爲36萬,時間複雜度上大約近乎100萬。故顯然在運行時間上,理論分析結果是層次聚類運行時間更長。
根據WEKA分別運行兩算法的時間結果,對比可知以下:
Name |
K-Means(歐氏,2類) |
層次聚類 |
Time |
0.24 sec |
16.32 sec |
可參見垃圾郵件過濾中德聚類分析。
利用weka提供的關聯算法,實現給定數據對象的關聯挖掘。
首先對bank數據進行預處理,預處理的對象包括有"ID","income"和"children"。對於ID要remove,對於income使用離散化過濾,使其在1至4之間,造成三份。children則在文本文件中修改參數,詳細操做在實驗1中應該很是詳細,故再也不贅述。
惟有處理掉全部Numeric數據,所有轉化爲Nominal類型數據,纔可使用Apriori算法,不然該算法按鈕爲灰色不可選狀態。
選擇Apriori算法的操做如圖所示。
對於Apriori的參數窗口,能夠點擊命令行欄彈出。圖片內容如圖所示。
詳細的參數含義以下羅列:
car 若是設爲真,則會挖掘類關聯規則而不是全局關聯規則。 classindex 類屬性索引。若是設置爲-1,最後的屬性被當作類屬性。 delta 以此數值爲迭代遞減單位。不斷減少支持度直至達到最小支持度或產生了知足數量要求的規則。 lowerBoundMinSupport 最小支持度下界。 metricType 度量類型。設置對規則進行排序的度量依據。能夠是:置信度(類關聯規則只能用置信度挖掘),提高度(lift),槓桿率(leverage),確信度(conviction)。 在 Weka中設置了幾個相似置信度(confidence)的度量來衡量規則的關聯程度,它們分別是: a) Lift : P(A,B)/(P(A)P(B)) Lift=1時表示A和B獨立。這個數越大(>1),越代表A和B存在於一個購物籃中不是偶然現象,有較強的關聯度。 b)Leverage :P(A,B)-P(A)P(B) Leverage=0時A和B獨立,Leverage越大A和B的關係越密切。 c) Conviction:P(A)P(!B)/P(A,!B) (!B表示B沒有發生) Conviction也是用來衡量A和B的獨立性。從它和lift的關係(對B取反,代入Lift公式後求倒數)能夠看出,這個值越大, A、B越關聯。 minMtric 度量的最小值。 numRules 要發現的規則數。 outputItemSets 若是設置爲真,會在結果中輸出項集。 removeAllMissingCols 移除所有爲缺省值的列。 significanceLevel 重要程度。重要性測試(僅用於置信度)。 upperBoundMinSupport 最小支持度上界。從這個值開始迭代減少最小支持度。 verbose 若是設置爲真,則算法會以冗餘模式運行。 |
根據實際狀況,咱們將參數設置爲:
% car I - 輸出項集,若設爲false則該值缺省; % numRules N 10 - 規則數爲10; % metricType T 0 – 度量單位選爲置信度,(T1-提高度,T2槓桿率,T3確信度); % minMetric C 0.9 – 度量的最小值爲0.9; % delta D 0.05 - 遞減迭代值爲0.05; % upperBoundMinSupport U 1.0 - 最小支持度上界爲1.0; % lowerBoundMinSupport M 0.5 - 最小支持度下界爲0.5; % significanceLevel S -1.0 - 重要程度爲-1.0; % classIndex c -1 - 類索引爲-1輸出項集設爲真 % (因爲car, removeAllMissingCols, verbose都保持爲默認值False,所以在結果的參數設置爲缺省,若設爲True,則會在結果的參數設置信息中分別表示爲A, R,V) |
那麼配置好參數,咱們應用關聯挖掘算法於bank數據,結果如圖所示。
文字結果摘錄以下:
Apriori ======= Minimum support: 0.1 (60 instances) Minimum metric <confidence>: 0.9 Number of cycles performed: 18
Generated sets of large itemsets: Size of set of large itemsets L(1): 28 Size of set of large itemsets L(2): 232 Size of set of large itemsets L(3): 524 Size of set of large itemsets L(4): 277 Size of set of large itemsets L(5): 33
Best rules found: 1. income='(43758.136667-inf)' 80 ==> save_act=YES 80 conf:(1) 2. age='(50.666667-inf)' income='(43758.136667-inf)' 76 ==> save_act=YES 76 conf:(1) 3. income='(43758.136667-inf)' current_act=YES 63 ==> save_act=YES 63 conf:(1) 4. age='(50.666667-inf)' income='(43758.136667-inf)' current_act=YES 61 ==> save_act=YES 61 conf:(1) 5. children=0 save_act=YES mortgage=NO pep=NO 74 ==> married=YES 73 conf:(0.99) 6. sex=FEMALE children=0 mortgage=NO pep=NO 64 ==> married=YES 63 conf:(0.98) 7. children=0 current_act=YES mortgage=NO pep=NO 82 ==> married=YES 80 conf:(0.98) 8. children=0 mortgage=NO pep=NO 107 ==> married=YES 104 conf:(0.97) 9. income='(43758.136667-inf)' current_act=YES 63 ==> age='(50.666667-inf)' 61 conf:(0.97) 10. income='(43758.136667-inf)' save_act=YES current_act=YES 63 ==> age='(50.666667-inf)' 61 conf:(0.97) |
根據任務要求,調整MetricType參數,能夠獲得下表:
Output |
|
Lift |
Minimum support: 0.25 (150 instances) Minimum metric <lift>: 1.1 Number of cycles performed: 15 Generated sets of large itemsets: Size of set of large itemsets L(1): 21 Size of set of large itemsets L(2): 59 Size of set of large itemsets L(3): 16 Best rules found: 1. age='(-inf-34.333333]' 195 ==> income='(-inf-24386.173333]' 174 conf:(0.89) < lift:(1.88)> lev:(0.14) [81] conv:(4.65) 2. income='(-inf-24386.173333]' 285 ==> age='(-inf-34.333333]' 174 conf:(0.61) < lift:(1.88)> lev:(0.14) [81] conv:(1.72) 3. married=YES 396 ==> mortgage=NO pep=NO 171 conf:(0.43) < lift:(1.24)> lev:(0.06) [33] conv:(1.14) 4. mortgage=NO pep=NO 209 ==> married=YES 171 conf:(0.82) < lift:(1.24)> lev:(0.06) [33] conv:(1.82) 5. married=YES mortgage=NO 261 ==> pep=NO 171 conf:(0.66) < lift:(1.21)> lev:(0.05) [29] conv:(1.31) 6. pep=NO 326 ==> married=YES mortgage=NO 171 conf:(0.52) < lift:(1.21)> lev:(0.05) [29] conv:(1.18) 7. children=0 263 ==> pep=NO 167 conf:(0.63) < lift:(1.17)> lev:(0.04) [24] conv:(1.24) 8. pep=NO 326 ==> children=0 167 conf:(0.51) < lift:(1.17)> lev:(0.04) [24] conv:(1.14) 9. married=YES save_act=YES 277 ==> pep=NO 175 conf:(0.63) < lift:(1.16)> lev:(0.04) [24] conv:(1.23) 10. pep=NO 326 ==> married=YES save_act=YES 175 conf:(0.54) < lift:(1.16)> lev:(0.04) [24] conv:(1.15) |
Leverage |
Minimum support: 0.1 (60 instances) Minimum metric <leverage>: 0.1 Number of cycles performed: 18 Generated sets of large itemsets: Size of set of large itemsets L(1): 28 Size of set of large itemsets L(2): 232 Size of set of large itemsets L(3): 524 Size of set of large itemsets L(4): 277 Size of set of large itemsets L(5): 33 Best rules found: 1. age='(-inf-34.333333]' 195 ==> income='(-inf-24386.173333]' 174 conf:(0.89) lift:(1.88) < lev:(0.14) [81]> conv:(4.65) 2. income='(-inf-24386.173333]' 285 ==> age='(-inf-34.333333]' 174 conf:(0.61) lift:(1.88) < lev:(0.14) [81]> conv:(1.72) 3. age='(-inf-34.333333]' 195 ==> income='(-inf-24386.173333]' current_act=YES 138 conf:(0.71) lift:(1.97) < lev:(0.11) [68]> conv:(2.16) 4. income='(-inf-24386.173333]' current_act=YES 215 ==> age='(-inf-34.333333]' 138 conf:(0.64) lift:(1.97) < lev:(0.11) [68]> conv:(1.86) 5. income='(-inf-24386.173333]' 285 ==> age='(-inf-34.333333]' current_act=YES 138 conf:(0.48) lift:(1.9) < lev:(0.11) [65]> conv:(1.43) 6. age='(-inf-34.333333]' current_act=YES 153 ==> income='(-inf-24386.173333]' 138 conf:(0.9) lift:(1.9) < lev:(0.11) [65]> conv:(5.02) |
Conviction |
Minimum support: 0.25 (150 instances) Minimum metric <conviction>: 1.1 Number of cycles performed: 15 Generated sets of large itemsets: Size of set of large itemsets L(1): 21 Size of set of large itemsets L(2): 59 Size of set of large itemsets L(3): 16 Best rules found: 1. age='(-inf-34.333333]' 195 ==> income='(-inf-24386.173333]' 174 conf:(0.89) lift:(1.88) lev:(0.14) [81] < conv:(4.65)> 2. mortgage=NO pep=NO 209 ==> married=YES 171 conf:(0.82) lift:(1.24) lev:(0.06) [33] < conv:(1.82)> 3. income='(-inf-24386.173333]' 285 ==> age='(-inf-34.333333]' 174 conf:(0.61) lift:(1.88) lev:(0.14) [81] < conv:(1.72)> 4. age='(50.666667-inf)' 191 ==> save_act=YES 151 conf:(0.79) lift:(1.15) lev:(0.03) [19] < conv:(1.44)> 5. save_act=YES pep=NO 235 ==> married=YES 175 conf:(0.74) lift:(1.13) lev:(0.03) [19] < conv:(1.31)> 6. married=YES mortgage=NO 261 ==> pep=NO 171 conf:(0.66) lift:(1.21) lev:(0.05) [29] < conv:(1.31)> 7. pep=NO 326 ==> married=YES 242 conf:(0.74) lift:(1.12) lev:(0.04) [26] < conv:(1.3)> 8. children=0 263 ==> pep=NO 167 conf:(0.63) lift:(1.17) lev:(0.04) [24] < conv:(1.24)> 9. married=YES save_act=YES 277 ==> pep=NO 175 conf:(0.63) lift:(1.16) lev:(0.04) [24] < conv:(1.23)> 10. current_act=YES pep=NO 244 ==> married=YES 177 conf:(0.73) lift:(1.1) lev:(0.03) [15] < conv:(1.22)> |
至此關聯挖掘的實驗結束。
(1)嘗試簡單的WEKA二次開發入門知識;
(2)總結網絡及論壇的各種二次開發經驗與技巧;
(3)實踐二次開發的小實驗。
經過諮詢老師和查閱網絡論壇資料,發現WEKA二次開發過程提供的教程參差不齊。緣由歸結於幾點:
a)WEKA版本衆多,穩定版開發版嘗試的人均不同,操做的順序流程也不盡相同。
b)WEKA的二次開發涉及到Eclipse,不一樣版本的操做軟件集成環境也不盡相同。
c)提供的教程有時不充分,涉及到關鍵的部分時,老是沒有詳細解釋,故須要摸索一條符合實際狀況的道路。
經過結合網絡資料,決定要麼採用WEKA3-4-X的穩定版,要麼採用WEKA3-6-X穩定版本,其中值得一提的是對於WEKA3-5-X網絡論壇網友也有嘗試,應該是成功的,可是侷限在WEKA3-5版本內。二次開發的流程區別在3-4和3-5之間成爲分界嶺,但應當是細節的不一樣。歷屆版本的下載網址見以下:
http://sourceforge.net/projects/weka/files/weka-3-4-windows/
這裏我展現WEKA3-4-10和WEKA3-6-11的二次開發環境配置。
WEKA3-4-10的界面以下:
創建Eclipse的java項目工程,該過程不贅述,而後項目工程的基本目錄結構要有,也就是說,得有src文件夾,連接庫等。繼而開始正式的步驟,右鍵點擊weka項目名,點擊導入,並選擇文件系統,所選的文件系統爲你weka軟件目錄下的weka-src文件(若是是jar包狀態,請解壓後導入),導入操做如圖所示:
而後選擇導入文件的路徑,在這裏請注意!很是重要的是,必定要選擇正確目錄。請與java程序中package的路徑一致,不要跟網絡論壇資料人云亦云!網絡論壇教程資料有時不符合你的實際狀況。
我經過舉例子,下圖中有帶"勾"的目錄,和帶"叉"的目錄。"勾"是正確的目錄,"叉"是錯誤路徑,而"叉"每每都是教程提供的路徑,這是由於java程序中package的內容是weka.xxxxxx。那麼目錄必定要在weka/xxxxx下。
因此導入後,各src下的程序文件都帶有weka的"頭",以下圖細紅框標註所示。若是設置錯誤的路徑,則會提示error,關於沒法找到package路徑的問題。經過設置正確的文件目錄後,基本已無error,大多出現warning,以下圖粗紅框內所示,這是正常現象。如今已經能夠作開發編程,warning並不會影響。
WEKA3-6-11導入的也是WEKA3-6-11目錄下的weka-src,若是weka-src是jar包狀態,請解壓後導入。導入的路徑選擇爲下圖所示,其中紅色框爲路徑節點,藍色框是點擊選擇的目錄路徑,即鼠標點擊紅色框內文件夾名字,再點擊肯定便可:
導入後會出現沒法解析類型的錯誤,以下圖所示。
通常是缺乏動態庫所致,此時須要連接相關的庫。連接的庫jar包所有在weka-src文件夾lib目錄下。可對Eclipse的JRE系統庫上右鍵點選"構建路徑-配置構建路徑",在彈出的窗口中,選擇"添加外部jar",進入剛纔所說的路徑,把三個jar導入。此時Eclipse左側欄產生了"引用庫"內容。
此時再也不提示沒法解析類型錯誤,但仍然有一些錯誤未能解決,例如"覆蓋超類的錯誤"沒有解決,此問題通常是Java編譯器版本設置問題。
修改你的eclipse指定的編譯器版本。在選項裏的java compiler中指定版本至少在5.0以上。在myEclipse中改變編譯器的方法:Project->Properties->JavaCompiler
->ConfigureWorkspace Setting,在彈出的頁面中能夠進行設置。
若是是Eclipse下,請在"窗口-首選項"下的彈出窗口內,操做如圖:
而後點選"java-編譯器",更改一致性級別,調整至1.7,此數值對應編譯5.0版本以上,能夠提供兼容覆蓋超類語法的編譯環境。
至此,全部錯誤都消失,但Warning存在,仍然是不影響二次開發編程的。經過找到"weka gui"下的"guichooser.java",點擊運行,便可看見wekaGUI界面。如須要添加本身的程序,則添加新的java程序,編寫符合weka接口的新程序,再經過可視化界面運行便可。
##########點擊運行,便可看見wekaGUI界面。如須要添加本身的程序,則添加新的java程序,編寫符合weka接口的新程序,再經過可視化界面運行便可。
諮詢老師和查閱互聯網,教程提供各類不對,因此有一句話說得好,要走出本身的特點道路,不要迷信於別人的道路,不要迷失本身的道路,對本身的道路要自信。這句話意味着,不要認爲本身徹底不明白,WEKA和java eclipse實驗作到這個份上,有些知識要本身去觸類旁通,舉一反三。以增長LibSvm的jar包爲例,這裏咱們採用連接至系統路徑中方法,使WEKA的jar包調用。
靈感在於,諮詢老師時,老師建議使用支持向量機的方法去對垃圾郵件做訓練。那麼若是須要該方法訓練,須要下載與WEKA版本對應的jar庫,有兩個,一個是libsvm.jar,另外一個是wlsvm.jar。下載地址能夠是:
http://www.cs.iastate.edu/~yasser/wlsvm/
下圖展現的是WEKA3-4版本就沒有保留LibSvm的位置,故無此項。
下圖展現的是WEKA3-6版本,它雖然保留LibSvm的位置,但若是缺乏其jar包,則顯示爲藍色狀態。因爲個人WEKA爲3-6版本,當時Classify裏的Classifier-functions內Libsvm是藍色的,即未鏈接狀態。即便運行,也會報出錯誤。
所報錯誤以下:
這是因爲沒有相關庫,而強行運行所致。即使下載了相關庫,不進行環境變量的添加,也不行。此時不要迷信別人的方法,也不要迷信個人方法,個人方法是我根據本身的狀況摸索出來的。
首先要配置WEKA安裝目錄下的文件RunWeka.ini配置文件,打開後,觀察其中一句語句。顯然此語句提供的了classpath的路徑。(網上的修改方法徹底忽略此語句,若是不注意到這個細節,則南轅北轍。這也是由於3-6版本較高不一樣於之前的版本的緣故,因此參考別人教程要注意本身的環境。)
而後根據該配置文件的案例,即
# cp=%CLASSPATH%;D:/libraries/libsvm.jar
咱們模仿一下,在上面的這個註釋下方一行,添加一條語句,相似可以下:
cp=%CLASSPATH%;E:/Weka-3-6/wlsvm.jar;E:/Weka-3-6/libsvm.jar;
請注意,上面的指令具有兩個條件,一是你要把這兩個相關庫放在WEKA目錄下,二是指令要寫在註釋行下方。而後保存關閉,點擊RunWeka.bat去更新(記住用管理員權限打開一次,而後再雙擊打開一次。前者方式的打開會打不開,後者的方式會打開。箇中玄妙,惟有實踐者纔會體會)。此時再打開WEKA-Explorer,尋找Libsvm功能時,是黑色的,可選的,可用的,以下所示:
說明此時能夠運行Libsvm成功,至於運行是否成功還未可知。
咱們使用Libsvm庫對垃圾郵件作分類,通常來講調用Libsvm會出現兩個錯誤:
一是,start後報錯:problem evaluating classifier: rand 該問題解決方法是,更新libsvm較高,緣由是libsvm的版本低。更爲重要的是,WLSvm的文件包下載下來時是ZIP壓縮文件,打開后里面會有libsvm,記住不要用WLSvm裏的libsvm,這個libsvm不是WEKA軟件裏連接命名的libsvm。須要下載libsvm.zip壓縮包裏的文件,並引用這裏面的文件。 二是,報錯關於不能處理Could not handle Numeric數據 簡單,把分類關鍵標籤離散化爲二值。以郵件過濾爲例,class標籤要麼是msg表明正常郵件,要麼是spam表明垃圾郵件。咱們只要離散化class的值便可。我本身操做的時候把msg標爲1,spam標爲2。 |
其中離散化成爲Nominal類型的圖片結果以下:
使用Libsvm生成訓練結果的圖片以下:
文字結果摘要以下:
=== Classifier model (full training set) === LibSVM wrapper, original code by Yasser EL-Manzalawy (= WLSVM) Time taken to build model: 27.18 seconds === Stratified cross-validation === === Summary === Correctly Classified Instances 1938 88.7363 % Incorrectly Classified Instances 246 11.2637 % Kappa statistic 0.3849 Mean absolute error 0.1126 Root mean squared error 0.3356 Relative absolute error 43.1037 % Root relative squared error 92.9061 % Total Number of Instances 2184 === Detailed Accuracy By Class === TP Rate FP Rate Precision Recall F-Measure ROC Area Class 1 0.73 0.882 1 0.938 0.635 msg 0.27 0 1 0.27 0.425 0.635 spam Weighted Avg. 0.887 0.617 0.901 0.887 0.859 0.635 === Confusion Matrix === a b <-- classified as 1847 0 | a = msg 246 91 | b = spam |
觀察相關參數,知支持向量機下的精度要比K近鄰懶惰算法還要好,召回率與K懶惰算法不相上下,對於正例判決是滿分,即百分百,足見支持向量機果真大名鼎鼎。
感謝老師的幫助,沒有兩位老師的課上教學和課下指導,我是根本不可能作出來的。對於WEKA的理解和HADOOP的理解又不斷深刻。
本科畢業的時候,個人本科導師就教導過道德經中有云"爲學日益,爲道日損,損之又損,以致於無爲,無爲而無不爲。"求學日益精進,實踐日益漸辛。等到一天,求學不斷進步,實踐不斷圓滿,以致於無爲,無爲也就無不爲了,固然這也是理想的境界,也是不斷追求的境界。
謝謝老師!真的是麻煩您了!
<<<<<<<<< 寫在頁面最底的小額打賞 >>>>>>>>>
若是讀者親願意的話,能夠小額打賞我,感謝您的打賞。您的打賞是個人動力,很是感激。
必讀:如您願意打賞,打賞方式任選其一,本頁面右側的公告欄有支付寶方式打賞,微信方式打賞。
避免因打賞產生法律問題,兩種打賞方式的任一打賞金額上限均爲5元,謝謝您的支持。
若有問題,請24小時內通知本人郵件。