XGBoost與LightGBM文本分類

目錄

用戶評論情感極性判別

一、數據準備

二、數據預處理

三、文本特徵提取

四、將數據轉換爲DMatrix類型

五、構建XGBoost模型

1、XGBoost模型主要參數

(1)通用參數

(2)Booster參數

(3)學習目標參數

2、XGBoost模型

(1)基於XGBoost原生接口的分類

(2)基於Scikit-learn接口的分類

六、使用XGBoost做預測,並對模型進行評估

七、LightGBM文本分類


用戶評論情感極性判別

一、數據準備

訓練集:data_train.csv ,樣本數爲82025,情感極性標籤(0:負面、1:中性、2:正面) 

測試集:data_test.csv ,樣本數爲35157

評論數據主要包括:食品餐飲類,旅遊住宿類,金融服務類,醫療服務類,物流快遞類;部分數據如下:

二、數據預處理

主要進行中文分詞停用詞過濾

預處理後訓練集:clean_train_data.csv

預處理後測試集:clean_test_data.csv

預處理後的部分數據如下:

數據集預處理部分代碼如下:

import pandas as pd
import jieba
#去除停用詞,返回去除停用詞後的文本列表
def clean_stopwords(contents):
    contents_list=[]
    stopwords = {}.fromkeys([line.rstrip() for line in open('data/stopwords.txt', encoding="utf-8")]) #讀取停用詞表
    stopwords_list = set(stopwords)
    for row in contents:      #循環去除停用詞
        words_list = jieba.lcut(row)
        words = [w for w in words_list if w not in stopwords_list]
        sentence=' '.join(words)   #去除停用詞後組成新的句子
        contents_list.append(sentence)
    return contents_list
# 將清洗後的文本和標籤寫入.csv文件中
def after_clean2csv(contents, labels): #輸入爲文本列表和標籤列表
    columns = ['contents', 'labels']
    save_file = pd.DataFrame(columns=columns, data=list(zip(contents, labels)))
    save_file.to_csv('data/clean_data_test.csv', index=False, encoding="utf-8")

if __name__ == '__main__':
    train_data = pd.read_csv('data/data_test.csv', sep='\t',
                             names=['ID', 'type', 'review', 'label']).astype(str)
    labels=[]
    for i in range(len(train_data['label'])):
        labels.append(train_data['label'][i])
    contents=clean_stopwords(train_data['review'])
    after_clean2csv(contents,labels)

三、文本特徵提取

使用sklearn計算訓練集的TF-IDF,並將訓練集和測試集分別轉換爲TF-IDF權重矩陣,作爲模型的輸入。

# coding=utf-8
import pandas as pd
import xgboost as xgb
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn import metrics
from sklearn.model_selection import train_test_split

if __name__ == '__main__':
    train_data = pd.read_csv('data/clean_data_train.csv', sep=',', names=['contents', 'labels']).astype(str)
    cw = lambda x: int(x)
    train_data['labels']=train_data['labels'].apply(cw)

    x_train, x_test, y_train, y_test = train_test_split(train_data['contents'], train_data['labels'], test_size=0.1)

    # 將語料轉化爲詞袋向量,根據詞袋向量統計TF-IDF
    vectorizer = CountVectorizer(max_features=5000)
    tf_idf_transformer = TfidfTransformer()
    tf_idf = tf_idf_transformer.fit_transform(vectorizer.fit_transform(x_train))
    x_train_weight = tf_idf.toarray()  # 訓練集TF-IDF權重矩陣
    tf_idf = tf_idf_transformer.transform(vectorizer.transform(x_test))
    x_test_weight = tf_idf.toarray()  # 測試集TF-IDF權重矩陣

四、將數據轉換爲DMatrix類型

XGBoost 的二進制的緩存文件,加載的數據存儲在對象 DMatrix 中。

    # 將數據轉化爲DMatrix類型
    dtrain = xgb.DMatrix(x_train_weight, label=y_train)
    dtest = xgb.DMatrix(x_test_weight, label=y_test)
    
    # 保存測試集數據,以便模型訓練完成直接調用
    # dtest.save_binary('data/dtest.buffer')

五、構建XGBoost模型

XGBoost有兩大類接口:XGBoost原生接口 和 scikit-learn接口 ,並且XGBoost能夠實現 分類 和 迴歸 兩種任務。

1、XGBoost模型主要參數

XGBoost所有的參數分成了三類:通用參數:宏觀函數控制;Booster參數:控制每一步的booster;目標參數:控制訓練目標的表現。

(1)通用參數

  • booster[默認gbtree]:gbtree:基於樹的模型、gbliner:線性模型
  • silent[默認0]:值爲1時,靜默模式開啓,不會輸出任何信息
  • nthread[默認值爲最大可能的線程數]:這個參數用來進行多線程控制,應當輸入系統的核數。 如果你希望使用CPU全部的核,那就不要輸入這個參數,算法會自動檢測它

(2)Booster參數

這裏只介紹tree booster,因爲它的表現遠遠勝過linear booster,所以linear booster很少用到

  • eta[默認0.3]:和GBM中的 learning rate 參數類似。 通過減少每一步的權重,可以提高模型的魯棒性。常用的值爲0.2, 0.3
  • max_depth[默認6]:這個值爲樹的最大深度。max_depth越大,模型會學到更具體更局部的樣本。常用的值爲6
  • gamma[默認0]:Gamma指定了節點分裂所需的最小損失函數下降值。 這個參數的值越大,算法越保守。這個參數的值和損失函數息息相關。
  • subsample[默認1]:這個參數控制對於每棵樹,隨機採樣的比例。 減小這個參數的值,算法會更加保守,避免過擬合。但是,如果這個值設置得過小,它可能會導致欠擬合。 常用的值:0.7-1
  • colsample_bytree[默認1]:用來控制每棵隨機採樣的列數的佔比(每一列是一個特徵)。 常用的值:0.7-1

(3)學習目標參數

  • objective[默認reg:linear]:這個參數定義需要被最小化的損失函數。binary:logistic二分類的邏輯迴歸,返回預測的概率。multi:softmax 使用softmax的多分類器,返回預測的類別。這種情況下,還需要多設一個參數:num_class(類別數目)。 multi:softprob 和multi:softmax參數一樣,但是返回的是每個數據屬於各個類別的概率。
  • eval_metric[默認值取決於objective參數的取值]:對於有效數據的度量方法。 對於迴歸問題,默認值是rmse,對於分類問題,默認值是error。其他的值:rmse 均方根誤差; mae 平均絕對誤差;logloss 負對數似然函數值;error 二分類錯誤率(閾值爲0.5); merror 多分類錯誤率;mlogloss 多分類logloss損失函數;auc 曲線下面積。
  • seed[默認0]:隨機數的種子 設置它可以復現隨機數據的結果。

2、XGBoost模型

(1)基於XGBoost原生接口的分類

 #基於XGBoost原生接口的分類
 #xgboost模型構建
    param = {'silent': 0, 'eta': 0.3, 'max_depth': 6, 'objective': 'multi:softmax', 'num_class': 3, 'eval_metric': 'merror'}  # 參數
    evallist = [(dtrain, 'train'), (dtest, 'test')]
    num_round = 100  # 循環次數
    xgb_model = xgb.train(param, dtrain, num_round,evallist)
    # 保存訓練模型
    # xgb_model.save_model('data/xgb_model')

(2)基於Scikit-learn接口的分類

#基於Scikit-learn接口的分類
    # 訓練模型
    model = xgb.XGBClassifier(max_depth=6, learning_rate=0.1, n_estimators=100, silent=True, objective='multi:softmax')
    model.fit(x_train_weight, y_train)
    y_predict=model.predict(x_test_weight)

六、使用XGBoost做預測,並對模型進行評估

    '''
    #利用訓練完的模型直接測試
    xgb_model = xgb.Booster(model_file='data/xgb_model')  # init model
    dtest = xgb.DMatrix('data/test.buffer')
    xgb_test(dtest,xgb_model)
    '''

    y_predict = xgb_model.predict(dtest)  # 模型預測
    label_all = ['負面', '中性','正面']
    confusion_mat = metrics.confusion_matrix(y_test, y_predict)
    df = pd.DataFrame(confusion_mat, columns=label_all)
    df.index = label_all
    print('準確率:', metrics.accuracy_score(y_test, y_predict))
    print('confusion_matrix:', df)
    print('分類報告:', metrics.classification_report(y_test, y_predict))

模型分類結果如下:

七、LightGBM文本分類

# coding=utf-8
import pandas as pd
import numpy as np
from sklearn import metrics
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
import lightgbm as lgb
from sklearn.model_selection import train_test_split

if __name__ == '__main__':
    train_data = pd.read_csv('data/clean_data_train.csv', sep=',', names=['contents', 'labels']).astype(str)
    '''
    test_data = pd.read_csv('data/clean_data_test.csv', sep=',', names=['contents', 'labels']).astype(str)
    cw = lambda x: int(x)
    x_train = train_data['contents']
    y_train = np.array(train_data['labels'].apply(cw))
    x_test = test_data['contents']
    y_test = np.array(test_data['labels'].apply(cw))

    '''
    x_train, x_test, y_train, y_test = train_test_split(train_data['contents'], train_data['labels'], test_size=0.1)
    cw = lambda x: int(x)
    x_train = x_train
    y_train = np.array(y_train.apply(cw))
    x_test = x_test
    y_test = np.array(y_test.apply(cw))

    # 將語料轉化爲詞袋向量,根據詞袋向量統計TF-IDF
    vectorizer = CountVectorizer(max_features=5000)
    tf_idf_transformer = TfidfTransformer()
    tf_idf = tf_idf_transformer.fit_transform(vectorizer.fit_transform(x_train))
    x_train_weight = tf_idf.toarray()  # 訓練集TF-IDF權重矩陣
    tf_idf = tf_idf_transformer.transform(vectorizer.transform(x_test))
    x_test_weight = tf_idf.toarray()  # 測試集TF-IDF權重矩陣

    # 創建成lgb特徵的數據集格式
    lgb_train = lgb.Dataset(x_train_weight, y_train)
    lgb_val = lgb.Dataset(x_test_weight, y_test, reference=lgb_train)

    # 構建lightGBM模型
    params = {'max_depth': 5, 'min_data_in_leaf': 20, 'num_leaves': 35,
              'learning_rate': 0.1, 'lambda_l1': 0.1, 'lambda_l2': 0.2,
              'objective': 'multiclass', 'num_class': 3, 'verbose': -1}
    # 設置迭代次數,默認爲100,通常設置爲100+
    num_boost_round = 1000
    # 訓練 lightGBM模型
    gbm = lgb.train(params, lgb_train, num_boost_round, verbose_eval=100, valid_sets=lgb_val)

    # 保存模型到文件
    # gbm.save_model('data/lightGBM_model')

    # 預測數據集
    y_pred = gbm.predict(x_test_weight, num_iteration=gbm.best_iteration)

    y_predict = np.argmax(y_pred, axis=1)  # 獲得最大概率對應的標籤

    label_all = ['負面', '中性', '正面']
    confusion_mat = metrics.confusion_matrix(y_test, y_predict)
    df = pd.DataFrame(confusion_mat, columns=label_all)
    df.index = label_all

    print('準確率:', metrics.accuracy_score(y_test, y_predict))
    print('confusion_matrix:', df)
    print('分類報告:', metrics.classification_report(y_test, y_predict))

分類結果如下:

參考:

1、安裝包下載網址

2、XGBoost學習文檔

3、XGBoost和LightGBM的參數以及調參

4、XGBoost數據比賽之調參

5、LightGBM調參筆記

6、kaggle——泰坦尼克之災(基於LGBM)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章