NBSVM的Python實現

來源:互聯網
上載者:User

標籤:完整   .sh   cto   基礎   elf   並且   模型   http   組成   

NBSVM

樸素貝葉斯(Naive Bayers))和支援向量機(SVM)是文本分類常用的基本模型。在不同的資料集、不同的特徵和不同的參數下,兩者的效果有所差異。一般來說NB在短文本上的表現要優於SVM,而SVM在長文本上的表現更佳。

NBSVM來自論文<Baselines and Bigrams Simple, Good Sentiment and Topic Classification>,是作者提出的一種新型的分類方法,它將NB和SVM結合起來,原理可以概括為一句話:

"Trust NB unless SVM is very confident"

作者在不同的資料集上進行了實驗,都取得了比單獨的NB和SVM更好的效果,具體結果和原理方法可參見原論文。

作者也提供了matlab代碼,本文將用python對nbsvm進行簡單demo實現。

問題描述

實現一個小型的中文新聞文本分類問題。訓練集資料由11類新聞群組成,文本已經做好了分詞;每類新聞有1600條,對應的標籤由1到11。測試集由11*160條資料群組成。 實驗資料和對比的結果來自知乎專欄,詳細地址見參考。

演算法步驟

  1. 向量化,TF-IDF特徵提取 
    count_v0= CountVectorizer();  counts_all = count_v0.fit_transform(train_x +test_x);count_v1= CountVectorizer(vocabulary=count_v0.vocabulary_);  counts_train = count_v1.fit_transform(train_x);   print ("the shape of train is "+repr(counts_train.shape)  )count_v2 = CountVectorizer(vocabulary=count_v0.vocabulary_);  counts_test = count_v2.fit_transform(test_x);  print ("the shape of test is "+repr(counts_test.shape)  )  tfidftransformer = TfidfTransformer();    train_x = tfidftransformer.fit(counts_train).transform(counts_train);test_x = tfidftransformer.fit(counts_test).transform(counts_test); 
  2. 計算log-count-ratio

    為了簡化問題,我們將多分類(N類)問題轉化為若干個二分類問題,因此需要將標籤轉化為One-Hot編碼形式,相應的y_i取值為1和0。

    def pr(x, y_i, y):     p = x[y==y_i].sum(0) # axis = 0    return (p+1) / ((y==y_i).sum()+1) #正則化 r = sparse.csr_matrix(np.log(pr(x,1,y) / pr(x,0,y)))
  3. 用 x·r (elementwise-product)代替線性分類器中的原來的訓練資料x,作為NBSVM的訓練資料。
    x_nb = x.multiply(r)
  4. 使用新的訓練資料和訓練標籤,進行分類器訓練,這裡用的LR分類器。
    clf = LogisticRegression(C=1, dual=False, n_jobs=1).fit(x_nb, y)
  5. 預測測試集,也將測試集的資料進行同樣的x_test·r 處理。
    clf.predict(x_test.multiply(r))

實驗結果

在驗證集的準確率達到0.8565。下表是其他方法在該資料集上分類的實驗效果。

可以看出,nbsvm在不僅提高了樸素貝葉斯和SVM方法的單獨作用,而且與深度學習的方法相比用時更少,效果絲毫不遜色。

感想

文本分類模型中,由於資料集和特徵的差異,最優的基礎分類模型往往沒有確定答案。針對這個問題,NBSVM通過訓練一個權重係數(可以看作是對模型的一種正則化)將兩種最常見的基礎分類模型很好的結合起來,形成一種通用性強、效果更佳的基本模型。

筆者後續對nbsvm應用在更大規模的資料集上(10W+),發現nbsvm的效能越能拉開單獨的nb和svm的效能,並且也好於大多數淺層的深度學習模型。因此,nbsvm可以作為文本分類的一個很好的baseline模型。

NBSVM 完整代碼

class NbSvmClassifier(BaseEstimator,ClassifierMixin):    def __init__(self, C=1.0, dual=False, n_jobs=1):        self.C = C        self.dual = dual        self.n_jobs = n_jobs    def predict(self, x):        # Verify that model has been fit        check_is_fitted(self, [‘_r‘, ‘_clf‘])        return self._clf.predict(x.multiply(self._r))    def predict_proba(self, x):        # Verify that model has been fit        check_is_fitted(self, [‘_r‘, ‘_clf‘])        return self._clf.predict_proba(x.multiply(self._r))    def fit(self, x, y):        # Check that X and y have correct shape        x, y = check_X_y(x, y, accept_sparse=True)        def pr(x, y_i, y):            p = x[y==y_i].sum()            print (p)            print ((y==y_i).sum())            return (p+1) / ((y==y_i).sum()+1)                 self._r = sparse.csr_matrix(np.log(pr(x,1,y) / pr(x,0,y))) #pr(x,1,y) number of positve samples    pr(x,0,y) number of negatve samples               x_nb = x.multiply(self._r)        self._clf = LogisticRegression(C=self.C, dual=self.dual, n_jobs=self.n_jobs).fit(x_nb, y)        return self

 

完整代碼地址:https://github.com/sanshibayuan/NBSVM

參考:

https://github.com/sidaw/nbsvm

https://nlp.stanford.edu/~sidaw/home/projects:nbsvm

https://zhuanlan.zhihu.com/p/26729228

NBSVM的Python實現

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.