17、机器学习中的异构集成分类器与文本分类

机器学习中的异构集成分类器与文本分类

1. 异构集成分类器使用H2O

1.1 模型训练与评估

在模型训练过程中,我们使用H2O的 H2OStackedEnsembleEstimator 训练堆叠集成模型。具体步骤如下:
1. 步骤18 - 20 :使用 H2OStackedEnsembleEstimator 训练堆叠集成模型,并在测试数据上评估其性能。
2. 步骤21 :评估所有在测试数据上构建的GLM模型,同时对使用随机森林(RF)和梯度提升机(GBM)训练的模型进行相同操作。
3. 步骤22 :找出具有最大AUC分数的模型。
4. 步骤23 :评估堆叠集成模型在测试数据上的AUC分数,以便与各个基础学习器的性能进行比较。

1.2 交叉验证

在训练所有模型时,我们使用了交叉验证。通过 nfolds 选项设置交叉验证的折数,例如设置 nfolds = 5 ,也可以设置为更高的数字。需要注意的是,所有构建的模型的折数必须相同。

当指定了 nfolds 的值后,还可以为 fold_assignment 参数提供值,该参数有 auto random modulo stratified 等取值:
- auto :算法会自动选择一个选项,目前选择的是 Random
- Random :将数据随机拆分为 nfolds 个集合。
- Modulo :使用确定性方法将数据均匀拆分为 nfolds 个集合,且不依赖于种子参数。

在使用交叉验证方法构建模型时,要确保为所有模型指定种子值或使用 fold_assignment = "Modulo"

1.3 网格搜索参数

在网格搜索中,我们使用了两个参数: stopping_metric stopping_rounds 。这两个参数适用于GBM和随机森林算法,但不适用于GLM。
- stopping_metric :指定在提前停止训练时要考虑的指标。
- stopping_rounds :当设置为大于零的值时,表示提前停止训练的条件。

例如,我们将 stopping_metric 设置为AUC, stopping_rounds 设置为5,这意味着如果在指定的5轮中AUC没有改善,算法将停止进一步训练。如果指定了 stopping_metric ,则必须同时设置 stopping_rounds 。当还设置了 stopping_tolerance 时,如果模型的 stopping_metric 在达到 stopping_rounds 指定的轮数后没有提高 stopping_tolerance 的值,模型将停止训练。

以下是相关参数的总结表格:
| 参数 | 适用算法 | 说明 |
| ---- | ---- | ---- |
| stopping_metric | GBM、随机森林 | 指定提前停止训练时考虑的指标 |
| stopping_rounds | GBM、随机森林 | 大于零的值,表示提前停止训练的轮数 |
| stopping_tolerance | GBM、随机森林 | 与 stopping_metric stopping_rounds 配合使用,控制提前停止的条件 |

1.4 流程图

graph LR
    A[开始] --> B[训练堆叠集成模型]
    B --> C[评估GLM、RF、GBM模型]
    C --> D[找出最大AUC分数的模型]
    D --> E[评估堆叠集成模型AUC分数]
    E --> F[交叉验证设置]
    F --> G[网格搜索参数设置]
    G --> H[结束]

2. 使用NLP进行文本分类的异构集成

2.1 文本分类简介

文本分类是语言处理和文本挖掘中广泛研究的领域。通过文本分类机制,我们可以根据文档的内容将其分类到预定义的类别中。在本节中,我们将关注如何对手机接收到的短文本消息进行分类,以避免垃圾邮件并确保重要消息不被遗漏。

2.2 垃圾邮件过滤

我们使用UCI ML存储库中的SMS Spam Collection数据集创建垃圾邮件分类器。可以使用多种分类器将消息分类为垃圾邮件(spam)或正常邮件(ham),这里我们选择使用朴素贝叶斯、随机森林和支持向量机等算法来训练模型。

2.3 数据预处理

在使用数据之前,需要进行一系列的数据清理和预处理操作,具体步骤如下:
1. 转换为小写 :将所有文本转换为小写。
2. 去除标点符号 :从文本中去除标点符号。
3. 去除停用词 :去除常见的停用词,如“the”、“and”等。
4. 词干提取 :对单词进行词干提取,将单词还原为其基本形式。
5. 分词 :将文本分割成单个的单词或标记。

同时,我们还使用词频 - 逆文档频率(TF - IDF)对数据进行处理,TF的计算公式为:
[TF = \frac{单词在文档中出现的次数}{文档中的总单词数}]

TF - IDF根据单词在文档或文档集合中出现的频率对单词的重要性进行数值评分。简单来说,TF - IDF分数越高,该词越罕见;分数越低,该词越常见。其数学表示为:
[tfidf(w, d, D) = tf(t, d) \times idf(t, D)]
其中, w 表示单词, d 表示文档, D 表示文档集合。

2.4 代码实现

2.4.1 导入必要的库
import os
import numpy as np
import pandas as pd
import itertools
import warnings
import string
import matplotlib.pyplot as plt
from nltk.corpus import stopwords
from nltk.stem import WordNetLemmatizer
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import confusion_matrix
from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report
from sklearn.metrics import roc_auc_score as auc
from sklearn.metrics import roc_curve
from sklearn.metrics import accuracy_score
from scipy.stats import mode
2.4.2 定义绘制混淆矩阵的函数
def plot_confusion_matrix(cm, classes,
                          normalize=False,
                          title='Confusion matrix',
                          cmap=plt.cm.Blues):
    plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title)
    plt.colorbar()
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes, rotation=45)
    plt.yticks(tick_marks, classes)
    fmt = '.2f' if normalize else 'd'
    thresh = cm.max() / 2.
    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        plt.text(j, i, format(cm[i, j], fmt),
                 horizontalalignment="center",
                 color="white" if cm[i, j] > thresh else "black")
    plt.ylabel('True label')
    plt.xlabel('Predicted label')
    plt.tight_layout()
2.4.3 读取数据并进行初步检查
os.chdir("/.../Chapter 11/CS - SMS Classification")
os.getcwd()
df_sms = pd.read_csv("sms_labeled_data.csv", encoding = 'utf8')
df_sms.head()
df_sms.shape
2.4.4 查看垃圾邮件和正常邮件的数量
print(df_sms["type"].value_counts()[0])
no_of_ham_messages = df_sms["type"].value_counts()[0]
print(df_sms["type"].value_counts()[1])
no_of_spam_messages = df_sms["type"].value_counts()[1]
2.4.5 可视化垃圾邮件和正常邮件的比例
sms_count = pd.value_counts(df_sms["type"], sort= True)
ax = sms_count.plot(kind='bar', figsize=(10,10), color= ["green",
"orange"], fontsize=13)
ax.set_alpha(0.8)
ax.set_title("Percentage Share of Spam and Ham Messages")
ax.set_ylabel("Count of Spam & Ham messages");
ax.set_yticks([0, 500, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500,
5000, 5500])
totals = []
for i in ax.patches:
    totals.append(i.get_height())
total = sum(totals)
for i in ax.patches:
    string = str(round((i.get_height()/total)*100, 2))+'%'
    ax.text(i.get_x()+0.16, i.get_height(), string, fontsize=13, color='black')
2.4.6 定义数据预处理函数
lemmatizer = WordNetLemmatizer()
def process_text(text):
    no_punctuations = [char for char in text if char not in string.punctuation]
    no_punctuations = ''.join(no_punctuations)
    clean_words = [word.lower() for word in no_punctuations.split() if word.lower() not in stopwords.words('english')]
    clean_words = [lemmatizer.lemmatize(lem) for lem in clean_words]
    clean_words = " ".join(clean_words)
    return clean_words
df_sms['text'] = df_sms['text'].apply(process_text)
2.4.7 分离特征和目标变量,并划分训练集和测试集
X = df_sms.loc[:,'text']
Y = df_sms.loc[:,'type']
Y = Y.astype('int')
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=.3,
random_state=1)
2.4.8 使用CountVectorizer和TfidfVectorizer转换文本
count_vectorizer = CountVectorizer(stop_words='english')
count_train = count_vectorizer.fit_transform(X_train)
count_test = count_vectorizer.transform(X_test)
tfidf = TfidfVectorizer(stop_words='english')
tfidf_train = tfidf.fit_transform(X_train)
tfidf_test = tfidf.transform(X_test)

2.5 模型训练

接下来,我们将使用朴素贝叶斯、支持向量机和随机森林算法对计数数据和TF - IDF数据进行训练,并评估各个模型的性能,同时将模型预测结果进行组合,观察集成的效果。具体训练步骤将在下半部分详细介绍。

2.6 数据预处理流程图

graph LR
    A[读取数据] --> B[转换为小写]
    B --> C[去除标点符号]
    C --> D[去除停用词]
    D --> E[词干提取]
    E --> F[分词]
    F --> G[TF - IDF处理]
    G --> H[划分训练集和测试集]
    H --> I[模型训练]

2.7 具体模型训练与评估

2.7.1 朴素贝叶斯模型

  • 计数数据训练
    python from sklearn.naive_bayes import MultinomialNB nb = MultinomialNB() nb.fit(count_train, Y_train) nb_pred_train = nb.predict(count_train) nb_pred_test = nb.predict(count_test) nb_pred_train_proba = nb.predict_proba(count_train) nb_pred_test_proba = nb.predict_proba(count_test) print('The accuracy for the training data is {}'.format(nb.score(count_train, Y_train))) print('The accuracy for the testing data is {}'.format(nb.score(count_test, Y_test)))
  • 评估指标
    • 分类报告
      python print(classification_report(Y_test, nb_pred_test))
    • 混淆矩阵
      python target_names = ['Spam','Ham'] cm = confusion_matrix(Y_test, nb_pred_test) plt.figure() plot_confusion_matrix(cm, classes=target_names) plt.show()
  • TF - IDF数据训练
    python nb.fit(tfidf_train, Y_train) nb_pred_train_tfidf = nb.predict(tfidf_train) nb_pred_test_tfidf = nb.predict(tfidf_test) nb_tfidf_pred_train_proba = nb.predict_proba(tfidf_train) nb_tfidf_pred_test_proba = nb.predict_proba(tfidf_test) print('The accuracy for the training data is {}'.format(nb.score(count_train, Y_train))) print('The accuracy for the testing data is {}'.format(nb.score(count_test, Y_test)))
  • TF - IDF数据评估指标
    • 分类报告
      python print(classification_report(Y_test, nb_pred_test_tfidf))
    • 混淆矩阵
      python target_names = ['Spam','Ham'] cm = confusion_matrix(Y_test, nb_pred_test_tfidf) plt.figure() plot_confusion_matrix(cm, classes=target_names) plt.show()

2.7.2 支持向量机模型

  • 计数数据训练
    python from sklearn.svm import SVC svc = SVC(kernel='rbf',probability=True) svc_params = {'C':[0.001, 0.01, 0.1, 1, 10]} svc_gcv_rbf_count = GridSearchCV(svc, svc_params, cv=5) svc_gcv_rbf_count.fit(count_train, Y_train) svc_rbf_train_predicted_values = svc_gcv_rbf_count.predict(count_train) svc_rbf_test_predicted_values = svc_gcv_rbf_count.predict(count_test) svc_gcv_train_proba_rbf = svc_gcv_rbf_count.predict_proba(count_train) svc_gcv_test_proba_rbf = svc_gcv_rbf_count.predict_proba(count_test) print('The best parameters {}'.format(svc_gcv_rbf_count.best_params_)) print('The best score {}'.format(svc_gcv_rbf_count.best_score_))
  • 评估指标
    • 分类报告
      python print(classification_report(Y_test, svc_rbf_test_predicted_values))
    • 混淆矩阵
      python target_names = ['Spam','Ham'] cm = confusion_matrix(Y_test, svc_rbf_test_predicted_values) plt.figure() plot_confusion_matrix(cm,classes=target_names) plt.show()
  • TF - IDF数据训练
    python svc = SVC(kernel='rbf',probability=True) svc_params = {'C':[0.001, 0.01, 0.1, 1, 10]} svc_gcv = GridSearchCV(svc,svc_params,cv=5) svc_gcv.fit(tfidf_train, Y_train) svc_tfidf_rbf_train_predicted_values = svc_gcv.predict(tfidf_train) svc_tfidf_rbd_test_predicted_values = svc_gcv.predict(tfidf_test) svc_gcv_tfidf_train_proba_rbf = svc_gcv.predict_proba(tfidf_train) svc_gcv_tfidf_test_proba_rbf = svc_gcv.predict_proba(tfidf_test) print('The best parameters {}'.format(svc_gcv.best_params_)) print('The best score {}'.format(svc_gcv.best_score_))
  • TF - IDF数据评估指标
    需要对该模型在TF - IDF数据上的预测结果进行分类报告和混淆矩阵评估,代码与计数数据评估类似。

2.7.3 随机森林模型

  • 计数数据训练
    python rf_params = {"criterion":["gini","entropy"],"min_samples_split":[2,3],"max_depth":[None,2,3],"min_samples_leaf":[1,5],"max_leaf_nodes":[None],"oob_score":[True]} rf = RandomForestClassifier() rf_gcv = GridSearchCV(rf, rf_params, cv=5) rf_gcv.fit(count_train, Y_train) rf_train_predicted_values = rf_gcv.predict(count_train) rf_test_predicted_values = rf_gcv.predict(count_test) rf_gcv_pred_train_proba = rf_gcv.predict_proba(count_train) rf_gcv_pred_test_proba = rf_gcv.predict_proba(count_test) print('The best parameters {}'.format(rf_gcv.best_params_)) print('The best score {}'.format(rf_gcv.best_score_))
  • 评估指标
    • 分类报告
      python print(classification_report(Y_test, rf_test_predicted_values))
    • 混淆矩阵
      python target_names = ['Spam','Ham'] cm = confusion_matrix(Y_test, rf_test_predicted_values) plt.figure() plot_confusion_matrix(cm,classes=target_names) plt.show()
  • TF - IDF数据训练
    python rf_params = {"criterion":["gini","entropy"],"min_samples_split":[2,3],"max_depth":[None,2,3],"min_samples_leaf":[1,5],"max_leaf_nodes":[None],"oob_score":[True]} rf = RandomForestClassifier() rf_gcv = GridSearchCV(rf, rf_params, cv=5) rf_gcv.fit(tfidf_train, Y_train) rf_tfidf_train_predicted_values = rf_gcv.predict(tfidf_train) rf_tfidf_test_predicted_values = rf_gcv.predict(tfidf_test) rf_gcv_tfidf_pred_train_proba = rf_gcv.predict_proba(tfidf_train) rf_gcv_tfidf_pred_test_proba = rf_gcv.predict_proba(tfidf_test) print('The best parameters {}'.format(rf_gcv.best_params_)) print('The best score {}'.format(rf_gcv.best_score_)) print(classification_report(Y_test, rf_tfidf_test_predicted_values)) target_names = ['Spam','Ham'] cm = confusion_matrix(Y_test, rf_tfidf_test_predicted_values) plt.figure() plot_confusion_matrix(cm, classes=target_names) plt.show()

2.8 ROC曲线绘制与集成评估

  • 单个模型ROC曲线绘制
    以朴素贝叶斯计数数据为例:
    python fpr, tpr, thresholds = roc_curve(Y_test, nb_pred_test_proba[:,1]) roc_auc = auc(Y_test,nb_pred_test_proba[:,1]) plt.title('ROC Naive Bayes (Count)') plt.plot(fpr, tpr, 'b',label='AUC = %0.3f'% roc_auc) plt.legend(loc='lower right') plt.plot([0,1],[0,1],'r--') plt.xlim([-0.1,1.0]) plt.ylim([-0.1,1.01]) plt.ylabel('True Positive Rate') plt.xlabel('False Positive Rate')
  • 集成模型ROC曲线绘制
    ```python
    plt.subplot(4,3,7)
    d = (nb_pred_test_proba + svc_gcv_test_proba_rbf + rf_gcv_pred_test_proba)/4
    fpr, tpr, thresholds = roc_curve(Y_test,d[:,1])
    roc_auc = auc(Y_test,d[:,1])
    plt.title(‘ROC Ensemble (Count)’)
    plt.plot(fpr, tpr, ‘b’,label=’AUC = %0.3f’% roc_auc)
    plt.legend(loc=’lower right’)
    plt.plot([0,1],[0,1],’r–‘)
    plt.xlim([-0.1,1.0])
    plt.ylim([-0.1,1.01])
    plt.ylabel(‘True Positive Rate’)
    plt.xlabel(‘False Positive Rate’)

    plt.subplot(4,3,8)
    d = (nb_tfidf_pred_test_proba + svc_gcv_tfidf_test_proba_rbf + rf_gcv_tfidf_pred_test_proba)/4
    fpr, tpr, thresholds = roc_curve(Y_test,d[:,1])
    roc_auc = auc(Y_test,d[:,1])
    plt.title(‘ROC Ensemble (TF - IDF)’)
    plt.plot(fpr, tpr, ‘b’,label=’AUC = %0.3f’% roc_auc)
    plt.legend(loc=’lower right’)
    plt.plot([0,1],[0,1],’r–‘)
    plt.xlim([-0.1,1.0])
    plt.ylim([-0.1,1.01])
    plt.ylabel(‘True Positive Rate’)
    plt.xlabel(‘False Positive Rate’)
    plt.tight_layout(pad=1,rect=(0, 0, 3.5, 4))
    plt.show()
    - **集成模型准确率检查** python
    predicted_array = np.array([nb_pred_test_tfidf, svc_tfidf_rbd_test_predicted_values, rf_tfidf_test_predicted_values])
    print(“Each array is the prediction of the respective models”)
    print(predicted_array)
    ```

2.9 模型训练与评估流程图

graph LR
    A[数据准备] --> B[模型选择]
    B --> C{数据类型}
    C -->|计数数据| D[朴素贝叶斯训练]
    C -->|计数数据| E[支持向量机训练]
    C -->|计数数据| F[随机森林训练]
    C -->|TF - IDF数据| G[朴素贝叶斯训练]
    C -->|TF - IDF数据| H[支持向量机训练]
    C -->|TF - IDF数据| I[随机森林训练]
    D --> J[评估指标计算]
    E --> J
    F --> J
    G --> J
    H --> J
    I --> J
    J --> K[单个模型ROC曲线绘制]
    K --> L[集成模型ROC曲线绘制]
    L --> M[集成模型准确率检查]

2.10 各模型评估指标总结表格

模型 数据类型 最佳参数 最佳得分 训练准确率 测试准确率 AUC值
朴素贝叶斯 计数数据
朴素贝叶斯 TF - IDF数据
支持向量机 计数数据
支持向量机 TF - IDF数据
随机森林 计数数据
随机森林 TF - IDF数据
集成模型 计数数据
集成模型 TF - IDF数据

通过以上一系列的操作,我们完成了使用异构集成分类器进行文本分类的任务。从数据预处理到模型训练,再到评估和可视化,每一步都对最终的分类效果有着重要的影响。不同的模型在不同的数据类型上表现各异,而集成模型通过综合多个模型的预测结果,往往能取得更好的性能。在实际应用中,可以根据具体需求和数据特点选择合适的模型和参数,以达到最佳的分类效果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值