2012-08-28 22 views
12

當我訓練的IBK分類與我手動創建如下一些訓練數據:weka.core.UnassignedDatasetException創建一個未標記的實例

ArrayList<Attribute> atts = new ArrayList<Attribute>(); 
ArrayList<String> classVal = new ArrayList<String>(); 
classVal.add("C1"); 
classVal.add("C2"); 
atts.add(new Attribute("a")); 
atts.add(new Attribute("b")); 
atts.add(new Attribute("c")); 
atts.add(new Attribute("d")); 
atts.add(new Attribute("@@[email protected]@", classVal)); 

Instances dataRaw = new Instances("TestInstances", atts, 0); 
dataRaw.setClassIndex(dataRaw.numAttributes() - 1); 
double[] instanceValue1 = new double[]{3,0,1,0,0}; 
dataRaw.add(new DenseInstance(1.0, instanceValue1)); 

double[] instanceValue2 = new double[]{2,1,1,0,0}; 
dataRaw.add(new DenseInstance(1.0, instanceValue2)); 

double[] instanceValue3 = new double[]{2,0,2,0,0}; 
dataRaw.add(new DenseInstance(1.0, instanceValue3)); 

double[] instanceValue4 = new double[]{1,3,0,0,1}; 
dataRaw.add(new DenseInstance(1.0, instanceValue4)); 

double[] instanceValue5 = new double[]{0,3,1,0,1}; 
dataRaw.add(new DenseInstance(1.0, instanceValue5)); 

double[] instanceValue6 = new double[]{0,2,1,1,1}; 
dataRaw.add(new DenseInstance(1.0, instanceValue6)); 

然後,我建立了分類:

IBk ibk = new IBk(); 
try { 
    ibk.buildClassifier(dataRaw); 

} catch (Exception e) { 
    e.printStackTrace(); 
} 

我想用未標記的類創建一個新的實例並對此實例進行分類,我嘗試了以下方法,但沒有成功。

IBk ibk = new IBk(); 
try { 
    ibk.buildClassifier(dataRaw); 
    double[] values = new double[]{3,1,0,0,-1}; 
    DenseInstance newInst = new DenseInstance(1.0,values); 
    double classif = ibk.classifyInstance(newInst); 
    System.out.println(classif); 
} catch (Exception e) { 
    e.printStackTrace(); 
} 

我只是得到了以下錯誤

weka.core.UnassignedDatasetException: DenseInstance doesn't have access to a dataset! 
at weka.core.AbstractInstance.classAttribute(AbstractInstance.java:98) 
at weka.classifiers.AbstractClassifier.classifyInstance(AbstractClassifier.java:74) 
at TextCategorizationTest.instancesWithDoubleValues(TextCategorizationTest.java:136) 
at TextCategorizationTest.main(TextCategorizationTest.java:33) 

貌似我做錯了什麼,同時創建一個新的實例。我怎樣才能完全創建一個未標記的實例?

由於提前

回答

12

問題是這一行:

double classif = ibk.classifyInstance(newInst); 

當您嘗試進行分類newInst,Weka中拋出一個異常,因爲newInst沒有實例對象(即數據集)與它相關聯 - 因此它不知道它的類屬性。

,必須先創建一個新的實例對象類似dataRaw,你的未標記的實例添加到它,設置一級指標,然後才嘗試進行分類的,如:

Instances dataUnlabeled = new Instances("TestInstances", atts, 0); 
dataUnlabeled.add(newInst); 
dataUnlabeled.setClassIndex(dataUnlabeled.numAttributes() - 1);   
double classif = ibk.classifyInstance(dataUnlabeled.firstInstance()); 
+3

老兄你的答案是黑客。我已經給出了適用於weka文檔的答案 –

+0

@TaimoorChangaiz爲什麼這個答案是黑客? – Clocker

+0

@ k29,因爲它不符合文件。文件建議正確的方法來做到這一點。 –

-1

見203頁 - 204 WEKA文件。這幫了我很多! (Weka手冊是一個pdf文件,位於您的weka安裝文件夾中,只需打開doucmentation.html,它會指向您的PDF手冊。)

複製粘貼第17章代碼清單的一些片段(使用WEKA API /在內存中創建數據集)應該可以幫助您解決任務。

+0

這本質上是[鏈接唯一答案](http://stackoverflow.com/help/how-to-answer),雖然鏈接是對文檔的引用。請提供一些背景信息(即在第203-204頁上說了些什麼),以便如果將來文檔發生變化,這個答案仍然有幫助 – Cecilia

+0

您是對的。事情是我不記得了。我記得,首先我的問題是找到了WEKA手冊 - 它不是很明顯,它在程序安裝文件夾中(我在網站上搜索它,但是現在它的位置可能更明顯)。所以我認爲提到手冊的位置可能很有用。因爲在此之前,我試圖閱讀javadocs並處理來自論壇的不完整代碼片段 - 這從來沒有導致解決方案。但是,一旦我找到手冊,我就能解決所有問題 - 真的值得一看。 – ndrizza

10

當您將與數據集關聯的新實例分類時,您將看到此錯誤。您必須使用setDataset將您創建的每個新實例與Instances對象相關聯。

//Make a place holder Instances 
//If you already have access to one, you can skip this step 
Instances dataset = new Instances("testdata", attr, 1); 
dataset.setClassIndex(classIdx); 

DenseInstance newInst = new DenseInstance(1.0,values); 

//To associate your instance with Instances object, in this case dataset 
newInst.setDataset(dataset); 

在此之後,您可以分類新創建的實例。

double classif = ibk.classifyInstance(newInst); 

http://www.cs.tufts.edu/~ablumer/weka/doc/weka.core.Instance.html

Detailed Implementation Link

+0

這是最好的答案,因爲您可以直接使用'Instance'而不是使用'Instances.firstInstance()'函數。我在代碼中添加了更多的上下文,以便清楚如何使用這種方法,如果您需要創建一個新的'Instances'。 – Cecilia

+0

謝謝,這確實是正確的答案:) –