2013-02-19 16 views
1

大多數機器學習分類器在遇到沒有前面看到的特徵的實例時,會將該示例與訓練數據中最頻繁的類分類。爲什麼不能線性預測多數類?

這似乎不是liblinear-java的情況,我想知道這是爲什麼。下面是一些示例代碼,我構造物,其中有兩個功能,一個樣的問題,訓練數據有4倍之多0標籤爲1標籤:

Problem problem = new Problem(); 
problem.l = 5; 
problem.n = 2; 
problem.x = new FeatureNode[][] { 
    new FeatureNode[] { new FeatureNode(1, 1) }, 
    new FeatureNode[] { new FeatureNode(1, 1) }, 
    new FeatureNode[] { new FeatureNode(1, 1) }, 
    new FeatureNode[] { new FeatureNode(1, 1) }, 
    new FeatureNode[] { new FeatureNode(2, 1) }, 
}; 
problem.y = new int[] {0, 0, 0, 0, 1}; 

Parameter parameter = new Parameter(SolverType.L2R_L2LOSS_SVC, 1.0, 0.01); 
Model model = Linear.train(problem, parameter); 

現在讓我們來測試這對一個新的功能,3,這沒有在訓練數據中。由於訓練過的模型對特徵3一無所知,我預計預測的類將是0,這是訓練數據中最常見的類。

FeatureNode[] instance = new FeatureNode[] { new FeatureNode(3, 1) }; 
int prediction = Linear.predict(model, instance); 
System.err.println(prediction); 

最後一行打印出1但是。這是爲什麼?

+0

這取決於分隔線的設置位置,您可以添加模型的學習參數嗎?我相信它是在1/1和2/1之間,所以2/1以上的所有東西都會被分類爲1,所有的東西都會低於0. – 2013-02-19 10:19:52

+0

只是猜測:是的,你的假設是正確的,它應該指派具有最高存在的類。問題在於算法如何處理看不見的功能:a)代碼中可能存在一個錯誤(看不見的分配給第一類),或者b)解算器被定義爲以這種方式執行(出於某種理論原因)。我會檢查解算器應該如何工作,或者我會在其他一些sw中嘗試相同的ML算法(R,Weka,...) – xhudik 2013-02-19 10:20:28

+0

似乎未指定的特徵值默認爲零。您的測試實例因此對分類器顯示爲'(0,0)'。如果你不使用偏差,分界線會穿過這個點,所以兩個輸出同樣可能(不管訓練集是多少)。畢竟,我沒有看到像這樣的測試中的重點。如果數據中缺少值,將它們設置爲零(隱式)可能不是使用SVM時的最佳策略。嘗試找到一些解釋缺失數據的學習算法。 – 2013-02-21 08:36:12

回答

2

我相信這是liblinear命令行版本的「-B」(偏見)參數旨在解決的問題。如果您直接創建FeatureNode s,則該參數不可用,但它與在每個FeatureNode[]開頭添加new FeatureNode(1, 1)基本相同。如果我遵循這種方法,並在培訓和分類期間添加額外的偏差特徵,則一切正常。下面是代碼如下所示:

Problem problem = new Problem(); 
problem.l = 5; 
problem.n = 3; 
problem.x = new FeatureNode[][] { 
    new FeatureNode[] { new FeatureNode(1, 1), new FeatureNode(2, 1) }, 
    new FeatureNode[] { new FeatureNode(1, 1), new FeatureNode(2, 1) }, 
    new FeatureNode[] { new FeatureNode(1, 1), new FeatureNode(2, 1) }, 
    new FeatureNode[] { new FeatureNode(1, 1), new FeatureNode(2, 1) }, 
    new FeatureNode[] { new FeatureNode(1, 1), new FeatureNode(3, 1) }, 
}; 
problem.y = new int[] {0, 0, 0, 0, 1}; 

Parameter parameter = new Parameter(SolverType.L2R_L2LOSS_SVC, 1.0, 0.01); 
Model model = Linear.train(problem, parameter); 
FeatureNode[] instance = new FeatureNode[] { new FeatureNode(1, 1), new FeatureNode(4, 1) }; 
int prediction = Linear.predict(model, instance); 

弄清楚爲什麼偏置功能是必要的,我挖成liblinear-java代碼位。這裏的預測碼的樣子:

for (int i = 0; i < nr_w; i++) 
    dec_values[i] = 0; 

for (FeatureNode lx : x) { 
    int idx = lx.index; 
    // the dimension of testing data may exceed that of training 
    if (idx <= n) { 
     for (int i = 0; i < nr_w; i++) { 
      dec_values[i] += w[(idx - 1) * nr_w + i] * lx.value; 
     } 
    } 
} 

因此,在功能訓練過程中從未見過的情況下,我們只得到全零的dec_values(決定值)陣列,這意味着所有類都具有相等可能性。所以至關重要的是,在分類過程中看到的每個實例中至少有一個在訓練期間看到的特徵。

添加具有常數值的「偏差」特徵(例如1)可解決此問題,從而允許模型學習應用於任何新實例的默認權重。在上面的代碼中,該模型學習偏差特徵的權重0.0869565217391306,這意味着該模型正確學習贊成類超過類1

相關問題