NLP09-加强1-对比SVM

news/2025/2/27 8:57:26

支持向量机(SVM)

(一)导入 SVM 相关库

(二) 修改模型初始化

(三) 比较

朴素贝叶斯分类

SVM分类


支持向量机(SVM)

代码修改基于NLP09-朴素贝叶斯问句分类(3/3)

(一)导入 SVM 相关库

python">from sklearn.svm import SVC  # 导入 SVM

(二) 修改模型初始化

python">    # 模型训练
    def train_model(self):
        self.to_vect()
        # 使用 SVM 替换朴素贝叶斯
        svm_model = SVC(kernel='linear', C=1.0)  # 线性核函数,C 是正则化参数
        svm_model.fit(self.train_vec, self.train_y)
        self.model = svm_model

详细解释SVM

参见 机器学习——支持向量机(SVM)

python"># 使用 SVM 替换朴素贝叶斯
        svm_model = SVC(kernel='linear', C=1.0)  # 线性核函数,C 是正则化参数

(三) 比较

性能评估指标主要是:准确性、精确率、召回率、F1-Score

朴素贝叶斯分类

为了进行性能评估,我们需要使用 train_test_split 来分割数据集,并使用 sklearn.metrics 来计算准确性、精确率、召回率和 F1-Score。下面是修改后的完整代码,包含了数据集划分和各项评估指标的计算:

python">import os.path
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
from common import constant
from ch import data_loader, nlp_util


class QuestionClassify:
    def __init__(self):
        self.train_x = None
        self.train_y = None
        self.tfidf_vec = None
        self.train_vec = None
        self.model = None
        self.question_category_dict = None

    # 文本向量化
    def to_vect(self):
        if self.tfidf_vec is None:
            # 加载训练数据
            self.train_x, self.train_y = data_loader.load_train_data()
            # 初始化一个Tfidf
            self.tfidf_vec = TfidfVectorizer()
            # 确保 self.train_x 是字符串列表
            if isinstance(self.train_x[0], list):
                self.train_x = [" ".join(doc) for doc in self.train_x]
            self.train_vec = self.tfidf_vec.fit_transform(self.train_x).toarray()

    # 模型训练
    def train_model(self):
        self.to_vect()
        # 使用 train_test_split 划分训练集和测试集
        X_train, X_test, y_train, y_test = train_test_split(self.train_vec, self.train_y, test_size=0.2, random_state=42)

        # 使用朴素贝叶斯模型
        nb_model = MultinomialNB(alpha=0.01)
        nb_model.fit(X_train, y_train)  # 训练模型
        self.model = nb_model

        # 预测并计算评估指标
        y_pred = self.model.predict(X_test)

        # 计算并打印评估指标
        accuracy = accuracy_score(y_test, y_pred)
        precision = precision_score(y_test, y_pred, average='weighted')
        recall = recall_score(y_test, y_pred, average='weighted')
        f1 = f1_score(y_test, y_pred, average='weighted')

        print(f"Accuracy: {accuracy:.4f}")
        print(f"Precision: {precision:.4f}")
        print(f"Recall: {recall:.4f}")
        print(f"F1-Score: {f1:.4f}")

    # 模型预测
    def predict(self, question):
        # 词性标注做电影相关实体的抽取
        question_cut = nlp_util.movie_pos(question)
        # 原问句列表(刘德华演过哪些电影)
        question_src_list = []
        # 转换后的问句(nr演过哪些电影)
        question_pos_list = []

        for item in question_cut:
            question_src_list.append(item.word)
            if item.flag in ['nr', 'nm', 'nnt']:
                question_pos_list.append(item.flag)
            else:
                question_pos_list.append(item.word)
        question_pos_text = [" ".join(question_pos_list)]
        # 文本向量化
        question_vect = self.tfidf_vec.transform(question_pos_text).toarray()

        # 输入模型进行预测,得到结果
        predict = self.model.predict(question_vect)[0]
        return predict

    def init_question_category_dict(self):
        # 读取问题(类别-描述)映射文件
        question_category_path = os.path.join(constant.DATA_DIR, "question_classification.txt")
        with open(question_category_path, "r", encoding="utf-8") as file:
            question_category_list = file.readlines()
        self.question_category_dict = {}
        for category_item in question_category_list:
            category_id, category_desc = category_item.strip().split(":")
            self.question_category_dict[int(category_id)] = category_desc

    def get_question_desc(self, category):
        if self.question_category_dict is None:
            self.init_question_category_dict()
        return self.question_category_dict[category]


if __name__ == "__main__":
    classify = QuestionClassify()
    classify.train_model()  # 训练模型并打印评估指标
    result = classify.predict("刘德华和成龙合作演过哪些电影呢?&&")
    print(classify.get_question_desc(result))
    print(result)

修改代码解析:

python"># 使用 train_test_split 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(self.train_vec, self.train_y, test_size=0.2, random_state=42)

详见 NLP06-Scikit-Learn 机器学习库(鸢尾花为例)的数据集拆分部分。

python">        # 预测并计算评估指标
        y_pred = self.model.predict(X_test)

        # 计算并打印评估指标
        accuracy = accuracy_score(y_test, y_pred)
        precision = precision_score(y_test, y_pred, average='weighted')
        recall = recall_score(y_test, y_pred, average='weighted')
        f1 = f1_score(y_test, y_pred, average='weighted')

 这几个指标是常用的分类模型评估指标。

(1) 准确率(Accuracy)

(2) 精确率(Precision)

(3) 召回率(Recall)

(4) F1-Score

输出结果:

SVM分类

python">import os.path
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.svm import SVC  # 导入 SVM
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
from common import constant
from ch import data_loader, nlp_util


class QuestionClassify:
    def __init__(self):
        self.train_x = None
        self.train_y = None
        self.tfidf_vec = None
        self.train_vec = None
        self.model = None
        self.question_category_dict = None

    # 文本向量化
    def to_vect(self):
        if self.tfidf_vec is None:
            # 加载训练数据
            self.train_x, self.train_y = data_loader.load_train_data()
            # 初始化一个Tfidf
            self.tfidf_vec = TfidfVectorizer()
            # 确保 self.train_x 是字符串列表
            if isinstance(self.train_x[0], list):
                self.train_x = [" ".join(doc) for doc in self.train_x]
            self.train_vec = self.tfidf_vec.fit_transform(self.train_x).toarray()

    # 模型训练
    def train_model(self):
        self.to_vect()
        # 使用 train_test_split 划分训练集和测试集
        X_train, X_test, y_train, y_test = train_test_split(self.train_vec, self.train_y, test_size=0.2, random_state=42)

        # 使用 SVM(支持向量机)替换朴素贝叶斯
        svm_model = SVC(kernel='linear', C=1.0)  # 线性核函数,C 是正则化参数
        svm_model.fit(X_train, y_train)  # 训练模型
        self.model = svm_model

        # 预测并计算评估指标
        y_pred = self.model.predict(X_test)

        # 计算并打印评估指标
        accuracy = accuracy_score(y_test, y_pred)
        precision = precision_score(y_test, y_pred, average='weighted', zero_division=0)
        recall = recall_score(y_test, y_pred, average='weighted', zero_division=0)
        f1 = f1_score(y_test, y_pred, average='weighted')

        print(f"Accuracy: {accuracy:.4f}")
        print(f"Precision: {precision:.4f}")
        print(f"Recall: {recall:.4f}")
        print(f"F1-Score: {f1:.4f}")

    # 模型预测
    def predict(self, question):
        # 词性标注做电影相关实体的抽取
        question_cut = nlp_util.movie_pos(question)
        # 原问句列表(刘德华演过哪些电影)
        question_src_list = []
        # 转换后的问句(nr演过哪些电影)
        question_pos_list = []

        for item in question_cut:
            question_src_list.append(item.word)
            if item.flag in ['nr', 'nm', 'nnt']:
                question_pos_list.append(item.flag)
            else:
                question_pos_list.append(item.word)
        question_pos_text = [" ".join(question_pos_list)]
        # 文本向量化
        question_vect = self.tfidf_vec.transform(question_pos_text).toarray()

        # 输入模型进行预测,得到结果
        predict = self.model.predict(question_vect)[0]
        return predict

    def init_question_category_dict(self):
        # 读取问题(类别-描述)映射文件
        question_category_path = os.path.join(constant.DATA_DIR, "question_classification.txt")
        with open(question_category_path, "r", encoding="utf-8") as file:
            question_category_list = file.readlines()
        self.question_category_dict = {}
        for category_item in question_category_list:
            category_id, category_desc = category_item.strip().split(":")
            self.question_category_dict[int(category_id)] = category_desc

    def get_question_desc(self, category):
        if self.question_category_dict is None:
            self.init_question_category_dict()
        return self.question_category_dict[category]


if __name__ == "__main__":
    classify = QuestionClassify()
    classify.train_model()  # 训练模型并打印评估指标
    result = classify.predict("刘德华和成龙合作演过哪些电影呢?&&")
    print(classify.get_question_desc(result))
    print(result)

输出结果:

 分析:

 朴素贝叶斯表现更好,可能原因如下:

  • 数据集较小:如果数据集较小,朴素贝叶斯可能会比 SVM 表现更好,因为 SVM 需要更多的数据来找到最优超平面。
  • 特征独立性假设成立:在文本分类任务中,词语之间的独立性假设可能并不会显著影响朴素贝叶斯的性能。
  • 参数调优不当:如果 SVM 的参数(如 C、kernel、gamma)没有调优好,性能可能会较差。
  • 类别分布均衡:如果数据集的类别分布较为均衡,朴素贝叶斯的性能可能会更好。


http://www.niftyadmin.cn/n/5869838.html

相关文章

CSS3 圆角:实现与优化指南

CSS3 圆角:实现与优化指南 随着网页设计的发展,CSS3 圆角已经成为了现代网页设计中不可或缺的元素之一。本文将详细讲解 CSS3 圆角的基本用法、实现方式以及优化技巧,帮助您在网页设计中更好地运用这一功能。 一、CSS3 圆角基本用法 1.1 基…

【论文笔记-ICCV 2023】ControlNet:为文本到图像扩散模型添加条件控制

ControlNet:为文本到图像扩散模型添加条件控制 ControlNet 是一种神经网络架构,可以通过空间定位、特定于任务的图像条件来增强大型预训练文本到图像扩散模型。 ControlNet 将其他条件注入神经网络的块中,如下图。 神经块将特征图 x 作为输…

在 Mac mini M2 上 MaxKb配置ollama,API域名无效的解决方案

环境说明 docker方案安装与使用的maxkb 本地ollama安装deekseek r1 解决方案 参考https://bbs.fit2cloud.com/t/topic/4165 mac m1用户,根据github的以下回复,成功绑定域名api 如果你想调用本地的ollama 中的大模型,域名试试:…

说说 Spring MVC 的执行流程

Spring MVC 是一个基于 Java 的轻量级、开源的 Web 框架,用于构建 Web 应用程序。它通过将请求处理的各个阶段解耦,使得开发更加灵活和模块化。以下是 Spring MVC 的执行流程,从用户发起请求到返回响应的整个过程: --- ### 1. 用…

分享---rpc运维事故处理

事故案例03 - Qserver RPC调用大量失败 一、事故背景 Queryserver是内部的核心服务,负责处理数据查询请求并支持分布式缓存功能。为优化缓存一致性,新增了分布式锁逻辑:在查询请求命中缓存时需先获取分布式锁(基于Tair实现&…

Flutter系列教程之(6)——Tab导航与ListView使用

目录 Tab导航 ListView的使用 Tab导航 效果图: 与原生的Android不同,flutter中使用Tab的步骤还算简单,不用写Adapter return DefaultTabController(//必传参数1length: 2,child: Scaffold(appBar: AppBar(title:Text(tab演示, style: TextStyle(color: Colors.white, fontS…

为什么要划分vlan

划分VLAN(Virtual Local Area Network,虚拟局域网)的原因主要包括以下几个方面: 控制广播风暴: 在传统的局域网中,广播风暴是一个常见问题,即一个广播包会在整个网络中传播,消耗大量…

区块链仿真工具SimBlock使用

1. Environment requirements SimBlock 可以在 Windows、MacOS、Ubuntu Linux 或任何支持 Java 的 Unix 平台上运行。 它需要以下版本的 JDK 和 Gradle。 请注意,SimBlock 的仓库中包含 Gradle Wrapper,因此您也可以自动安装 Gradle(我们稍…