5

我有2599個文件,從1到5的文件五個標記文本分類任務是如何使用scikit-learn和matplotlib繪製不平衡數據集的SVC分類?

label | texts 
---------- 
5  |1190 
4  |839 
3  |239 
1  |204 
2  |127 

所有準備將此劃文本具有非常低的性能數據,並同時獲得約不明確的指標警告:

Accuracy: 0.461057692308 

score: 0.461057692308 

precision: 0.212574195636 

recall: 0.461057692308 

    'precision', 'predicted', average, warn_for) 
confussion matrix: 
[[ 0 0 0 0 153] 
    'precision', 'predicted', average, warn_for) 
[ 0 0 0 0 94] 
[ 0 0 0 0 194] 
[ 0 0 0 0 680] 
[ 0 0 0 0 959]] 

clasification report: 
      precision recall f1-score support 

      1  0.00  0.00  0.00  153 
      2  0.00  0.00  0.00  94 
      3  0.00  0.00  0.00  194 
      4  0.00  0.00  0.00  680 
      5  0.46  1.00  0.63  959 

avg/total  0.21  0.46  0.29  2080 

顯然,這是事實,我有一個不平衡的數據集發生的事情,所以我發現這個paper這裏作者提出了幾個aproaches來解決這個問題:

The problem is that with imbalanced datasets, the learned boundary is too close to the positive instances. We need to bias SVM in a way that will push the boundary away from the positive instances. Veropoulos et al [14] suggest using different error costs for the positive (C +) and negative (C -) classes

我知道,這可能是非常複雜的,但SVC提供了幾個超參數,所以我的問題是:有沒有什麼辦法偏見SVC在與超參數,提供SVC分類推邊界遠離獨到之處實例的方式?。我知道這可能是一個困難的問題,但任何幫助是值得歡迎的,這要歸功於前輩們。

from sklearn.feature_extraction.text import TfidfVectorizer 
import numpy as np 
tfidf_vect= TfidfVectorizer(use_idf=True, smooth_idf=True, sublinear_tf=False, ngram_range=(2,2)) 
from sklearn.cross_validation import train_test_split, cross_val_score 

import pandas as pd 
df = pd.read_csv('/path/of/the/file.csv', 
        header=0, sep=',', names=['id', 'text', 'label']) 



reduced_data = tfidf_vect.fit_transform(df['text'].values) 
y = df['label'].values 



from sklearn.decomposition.truncated_svd import TruncatedSVD 
svd = TruncatedSVD(n_components=5) 
reduced_data = svd.fit_transform(reduced_data) 

from sklearn import cross_validation 
X_train, X_test, y_train, y_test = cross_validation.train_test_split(reduced_data, 
                y, test_size=0.33) 

#with no weights: 

from sklearn.svm import SVC 
clf = SVC(kernel='linear', class_weight={1: 10}) 
clf.fit(reduced_data, y) 
prediction = clf.predict(X_test) 

w = clf.coef_[0] 
a = -w[0]/w[1] 
xx = np.linspace(-5, 5) 
yy = a * xx - clf.intercept_[0]/w[1] 


# get the separating hyperplane using weighted classes 
wclf = SVC(kernel='linear', class_weight={1: 10}) 
wclf.fit(reduced_data, y) 

ww = wclf.coef_[0] 
wa = -ww[0]/ww[1] 
wyy = wa * xx - wclf.intercept_[0]/ww[1] 

# plot separating hyperplanes and samples 
import matplotlib.pyplot as plt 
h0 = plt.plot(xx, yy, 'k-', label='no weights') 
h1 = plt.plot(xx, wyy, 'k--', label='with weights') 
plt.scatter(reduced_data[:, 0], reduced_data[:, 1], c=y, cmap=plt.cm.Paired) 
plt.legend() 

plt.axis('tight') 
plt.show() 

但我什麼也沒有,我不能明白髮生了什麼,這是劇情:

weighted vs normal

則:

#Let's show some metrics[unweighted]: 
from sklearn.metrics.metrics import precision_score, \ 
    recall_score, confusion_matrix, classification_report, accuracy_score 
print '\nAccuracy:', accuracy_score(y_test, prediction) 
print '\nscore:', clf.score(X_train, y_train) 
print '\nrecall:', recall_score(y_test, prediction) 
print '\nprecision:', precision_score(y_test, prediction) 
print '\n clasification report:\n', classification_report(y_test, prediction) 
print '\n confussion matrix:\n',confusion_matrix(y_test, prediction) 

#Let's show some metrics[weighted]: 
print 'weighted:\n' 

from sklearn.metrics.metrics import precision_score, \ 
    recall_score, confusion_matrix, classification_report, accuracy_score 
print '\nAccuracy:', accuracy_score(y_test, prediction) 
print '\nscore:', wclf.score(X_train, y_train) 
print '\nrecall:', recall_score(y_test, prediction) 
print '\nprecision:', precision_score(y_test, prediction) 
print '\n clasification report:\n', classification_report(y_test, prediction) 
print '\n confussion matrix:\n',confusion_matrix(y_test, prediction) 

這是即時通訊使用的data。我該如何解決這個問題,並以正確的方式策劃這個問題?在此先感謝傢伙!

從這個問題的答案我刪除此行:

# 
# from sklearn.decomposition.truncated_svd import TruncatedSVD 
# svd = TruncatedSVD(n_components=5) 
# reduced_data = svd.fit_transform(reduced_data) 


# 
# w = clf.coef_[0] 
# a = -w[0]/w[1] 
# xx = np.linspace(-10, 10) 
# yy = a * xx - clf.intercept_[0]/w[1] 

# ww = wclf.coef_[0] 
# wa = -ww[0]/ww[1] 
# wyy = wa * xx - wclf.intercept_[0]/ww[1] 
# 
# # plot separating hyperplanes and samples 
# import matplotlib.pyplot as plt 
# h0 = plt.plot(xx, yy, 'k-', label='no weights') 
# h1 = plt.plot(xx, wyy, 'k--', label='with weights') 
# plt.scatter(reduced_data[:, 0], reduced_data[:, 1], c=y, cmap=plt.cm.Paired) 
# plt.legend() 
# 
# plt.axis('tight') 
# plt.show() 

This where the results: 

Accuracy: 0.787878787879 

score: 0.779437105112 

recall: 0.787878787879 

precision: 0.827705441238 

這個指標的改善。 如何繪製這個結果以獲得像文檔一樣的好例子。我想看看兩架超飛機的行爲?。多謝你們!

+1

'顯然這是由於我有一個不平衡的數據集的事實發生的 - 根據你所說的,我根本沒有發現這一點。你能告訴我們你的代碼甚至數據嗎? – IVlad 2015-02-12 11:05:14

+1

沒有SVD和沒有觸及class_weight參數,你會得到什麼?嘗試首先關注性能,然後再進行繪圖。 – IVlad 2015-02-15 09:17:10

+0

@Ivlad不使用從不平衡數據集這個文檔的例子是我得到的性能:'精度:0.461057692308 評分:0.461057692308 精度:0.212574195636 召回:0.461057692308'這是我可以用網格搜索做到最好。 – tumbleweed 2015-02-15 18:10:20

回答

2

如果我理解你正確輸入您有:

1190 5個標記文本 1409的1-4標記文本

的您可以嘗試做一個sequental分類。首先威脅的所有5個標籤爲1,所有其他爲0火車這個任務

二分類,從數據集中退出所有5個例。訓練分類器對1-4個標籤進行分類。

在分類運行第一分類器,如果它返回0 - 運行第二分類器,以獲得最終的標籤。

雖然我不認爲這種分佈是真的偏斜和不平衡的(它應該像5%的90%,10% - 所有的休息,真的是傾斜的,所以引入偏見可能是有趣的SVC)。因此,我認爲你可能想嘗試一些其他的分類算法,因爲看起來像你的選擇不適合這個任務。或者也許你需要在SVC中使用不同的內核(我假設你使用線性內核,嘗試一些不同的東西 - 也許是RBF或多項式)。

+0

我正在使用rbf,我嘗試了多項,RF,LR和svc,它具有最佳性能。 – tumbleweed 2015-02-13 00:07:49

+0

感謝您的反饋意見。任何想法如何偏向SVC分類器? – tumbleweed 2015-02-13 20:44:31

+1

我相信klubow提供了一些有用的信息。在scikit-learn中,您可以閱讀有關正確使用unballanced類別的方法:http://scikit-learn.org/stable/auto_examples/svm/plot_separating_hyperplane_unbalanced.html請記住,您需要手動調整課程權重最佳性能,或嘗試使用GridSearchCV自動調整它們(儘管您需要使用一些特定的評分指標,否則您將得不到好的結果)。 – 2015-02-14 21:20:42

1

您可能要檢查SVM分類 或 平衡你的數據(https://github.com/fmfn/UnbalancedDataset/blob/master/UnbalancedDataset.py

+0

對於這個問題,我需要設置什麼樣的class_weight來偏向SVM?謝謝您的幫助! – tumbleweed 2015-02-13 20:43:38

+0

我編輯過,感謝您的幫助! – tumbleweed 2015-02-15 04:59:51

+0

這幫了我很多,想知道如何繪製這個?我只想公平對待賞金的東西。 – tumbleweed 2015-02-25 19:35:30

2

作爲一個簡單的解決方案class_weight參數(http://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html),只需乘實例在小班和平衡實例的數量。即使這看起來很愚蠢,它在鑽機配置中也不需要。

使用這種方法的想法是模仿每個班級的縮放學習率對其班級規模的行爲。也就是說,在基於梯度的優化方法中,您應該按照每個類的類大小成反比地調整學習速率,以防止模型忽略其他類的類。

如果你的問題很大,而且你正在使用批量更新,那麼不要預訂所有的數據集和計數類,而應該考慮微型批處理和動態調整學習率,批量。

這意味着如果您的母校學習率爲0.01,並且在一批實例中您有0.4個A級和0.6個B級,那麼您需要將每個班級的最終學習率調整爲班級的master_learning率A(表示保持不變),2/3 * B級的master_learning率。因此,您可以爲A級提供更寬的級別,反之可提高B級級別。

我選擇走,特別是對於大型問題和擴充數據更小的類通過複製實例或作爲更強大的選擇,向複製的實例添加一些噪聲和差異。以這種方式,(取決於你的問題),你也可以訓練一個對小變化更強健的模型(這對於特別是圖像分類問題是非常常見的)。

+1

您是否有任何關於此功能的聲明參考?我沒有看到它與SVM一起工作。 – IVlad 2015-02-13 18:05:05

+0

事實上,我正在考慮做這個事情.... gust複製和粘貼,以平衡這一點。這個問題的理論解釋是什麼?感謝您的反饋 – tumbleweed 2015-02-13 20:42:04

+1

您只需平衡每個班級的模型更新次數。從理論上講,設定學習率與每個班的實例數成反比是更有意義的。通過設置實例的數量,您可以以天真的方式模仿相同的行爲。 – erogol 2015-02-13 20:48:57

4

通過減少數據5SVD特點:

svd = TruncatedSVD(n_components=5) 
reduced_data = svd.fit_transform(reduced_data) 

你失去了很多的信息。只是通過刪除這些行我得到78%準確性。

離開參數設置class_weight它似乎比刪除它好。我沒有嘗試給它其他的價值。

研究使用k-fold cross validationgrid search來調整模型的參數。如果您想減少數據的維度,則還可以使用pipeline,以便確定要在不影響性能的情況下減少多少。 Here是一個示例,顯示如何使用網格搜索來調整整個管道。

至於繪圖,你只能繪製2D或3D數據。在使用更多維度訓練之後,您可以將數據減少到2或3維並繪製該維度。繪圖示例見here。代碼看起來與你正在繪製的內容相似,並且我得到了與你相似的結果。問題在於你的數據有許多特徵,你只能將事物繪製成2D或3D曲面。這通常會讓它看起來很奇怪,很難說出發生了什麼。

我建議你不要打算繪圖,因爲它不會告訴你很多數據的高維度。使用網格搜索進行k-fold交叉驗證,以獲得最佳參數,如果您想查看過度擬合,請改爲繪製learning curves

所有這些結合起來會告訴你更多關於你的模型的行爲,而不是繪製超平面。

+0

事實上,我使用網格搜索,但它需要很長的搜索...一長... – tumbleweed 2015-02-15 17:43:26

+0

感謝您的幫助。我刪除了這些行,並得到以下異常:'Traceback(最近一次調用最後一次): 文件「/Users/user/test.py」,第35行,在中 a = -w [0]/w [1] 文件「/usr/local/lib/python2.7/site-packages/scipy/sparse/csr.py」,第253行,在__getitem__中 return self._get_row_slice(row,col) 文件「/ usr/local/lib/python2.7/site-packages/scipy/sparse/csr.py「,第320行,在_get_row_slice中 raise IndexError('index(%d)out of range'%i) IndexError:index(1)out範圍 '。任何想法如何解決這個問題? – tumbleweed 2015-02-15 17:51:23

+1

@ml_guy - 我也評論了'w = clf.coef_ [0] a = -w [0]/w [1] xx = np.linspace(-5,5) yy = a * xx - clf。 intercept_ [0]/w [1]'爲了解決這個問題。我也評論了繪圖代碼。 – IVlad 2015-02-15 18:06:19

2

您可能已經嘗試將class-weight設置爲auto,但我想檢查一下。

也許平衡實驗(oversampling or undersampling)可以幫助,它的一些lib已經被klubow建議。

+0

隨着班級重量自動這是結果:'準確性:0.453846153846 得分:0.458315519453 回憶:0.453846153846 精度:0.205976331361'指標下降.. – tumbleweed 2015-02-21 19:54:52

相關問題