2016-09-24 69 views
0

我處理區分兩類A和B的這些天,我發現,當B類包含了一些子類B1,B2,B3,......判別與子類

有時區分結果是明確的更好標記B1,B2,B3(子類別標籤),但有時其結果是用於收集子類別和標記只是他們B.

在其他字更好,有時

y=[A, A, A, ..., B1, B1, ..., B2, B2, ... B3, B3, ...] 

較好,但有時候,

y=[A, A, A, ..., B, B, B, ...] 

更好。

我認爲天真地有兩個衝擊作用的結果:

  1. 殼體1包括更多信息
  2. 殼體2中的算法可以更加專注於A的區分和B

但我不確定我的假設是否正確,誰都知道?而在處理這種情況時,如果存在子類別,您有什麼方法可以獲得最佳結果?

回答

0

在這種情況下,您可以使用兩級分類器,它首先預測頂級類別,然後選擇最可能的二級類別。這裏是我用過的一些代碼,

from sklearn.base import BaseEstimator, ClassifierMixin 
import pandas as pd 
import numpy as np 

class TwoLevelClassifier(BaseEstimator, ClassifierMixin): 
    """ 
    A two-level classifier intended to be used with labels taken from a 2-level taxonomy. 
    The labels are pipe-separated class-subclass pairs as "class|subclass". 

    >>> from sklearn.linear_model import LogisticRegression() 
    >>> X = pd.DataFrame([[1,2,3],[4,5,6],[7,8,9]]) 
    >>> y1 = pd.Series(['A','A','B']) 
    >>> y2 = pd.Series(['A1','A2','B1']) 
    >>> y = y1 + "|" + y2 
    >>> clf = TwoLevelClassifier(LogisticRegression(), LogisticRegression()) 
    >>> clf.fit(X,y) 
    """ 

    def __init__(self, classifier1, classifier2): 
     self.classifier1 = classifier1 
     self.classifier2 = classifier2 

    def fit(self, X, y): 
     y1 = y.str.split('|').str[0] 
     y2 = y.str.split('|').str[1] 
     self.classifier1.fit(X, y1) 
     self.classifier2.fit(X, y) 
     self.classes_ = self.classifier2.classes_ 

    def predict_proba(self, X): 
     level1_pred = pd.Series(self.classifier1.predict(X)) 
     probs = pd.DataFrame(self.classifier2.predict_proba(X), columns = self.classifier2.classes_) 
     classes_ = self.classifier2.classes_ 
     mask = np.array(pd.Series(level1_pred).map(lambda x: [y.split('|')[0] == x for y in classes_]).tolist()) 
     probs_filtered = probs.where(mask, 0) 
     return probs_filtered.values 

    def predict(self, X): 
     probs = self.predict_proba(X) 
     return probs.idxmax(axis=1)