我試圖通過scikit-learn實現一個分層的文本分類器,其中一個「根」分類器將所有輸入字符串排列在一個(或多個)〜50個類別中。對於這些類別中的每一個,我都會訓練一個新的分類器,它可以解決實際的任務。SelectKBest基於(估計)的功能量
這種兩層方法的原因是訓練性能和內存問題(一個分類器應該分開> 1k類的性能不好......)。
這是我的管道看起來像這些「subclassifiers」
pipeline = Pipeline([
('vect', CountVectorizer(strip_accents=None, lowercase=True, analyzer='char_wb', ngram_range=(3,8), max_df=0.1)),
('tfidf', TfidfTransformer(norm='l2')),
('feat', SelectKBest(chi2, k=10000)),
('clf', OneVsRestClassifier(SGDClassifier(loss='log', penalty='elasticnet', alpha=0.0001, n_iter=10))),
])
的現在,我的問題:我使用SelectKBest
到模型的大小限制在一個合理的量,但對於subclassifiers,有有時沒有足夠的輸入數據可用,所以我甚至不獲取到10k的功能限制,這會導致
(...)
File "/usr/local/lib/python3.4/dist-packages/sklearn/feature_selection/univariate_selection.py", line 300, in fit
self._check_params(X, y)
File "/usr/local/lib/python3.4/dist-packages/sklearn/feature_selection/univariate_selection.py", line 405, in _check_params
% self.k)
ValueError: k should be >=0, <= n_features; got 10000.Use k='all' to return all features.
我不知道有多少功能,將不應用CountVectorizer
,但我必須定義管道提前。我的首選解決方案是跳過SelectKBest
這一步,但如果功能少於k
,但我不知道如何在不調用CountVectorizer
兩次(提前一次,一次作爲管道的一部分)的情況下實現此行爲。
對此有何看法?
雖然這可能會起作用,但我想避免libraray函數的子類化以便簡化升級過程。 – Klamann 2015-04-02 12:17:17
除了調用CountVectorizer兩次,我沒有看到任何其他解決方案,我想避免它。無論如何,轉換接口在sckit-learn中應該是穩定的。你爲什麼認爲升級可能是一個問題? – 2015-04-02 12:18:15
你是對的,如果這是唯一的選擇,我寧願創建一個子類,但也許這裏有第三種方式... – Klamann 2015-04-02 12:25:15