Day06【基于词向量使用svm实现文本分类】

摘要

本文基于词向量(Word2Vec),使用支持向量机(SVM)作为分类器来预测文本的类别,来实现文本分类任务。代码的功能是加载预训练的Word2Vec模型,并利用该模型将文本转化为向量,再用支持向量机(SVM)进行训练和预测,最后输出分类结果的报告。

以下是代码各部分的详细解释:

1. 导入库和模块

import json
import jieba
import numpy as np
from gensim.models import Word2Vec
from sklearn.metrics import classification_report
from sklearn.svm import SVC
from collections import defaultdict
  • json: 用于解析JSON格式的数据。
  • jieba: 一个中文分词库,用于对文本进行分词。
  • numpy: 用于处理数值计算,特别是数组和矩阵操作。
  • gensim.models.Word2Vec: 用于加载和使用Word2Vec模型。
  • sklearn.metrics.classification_report: 用于输出分类报告,评估分类器性能。
  • sklearn.svm.SVC: 用于支持向量机(SVM)分类器的实现。
  • collections.defaultdict: 用于提供一个默认值字典,但在这段代码中似乎并未使用。

2. LABELS 字典

LABELS = {'健康': 0, '军事': 1, '房产': 2, '社会': 3, '国际': 4, '旅游': 5, '彩票': 6, '时尚': 7, '文化': 8, '汽车': 9, '体育': 10, '家居': 11, '教育': 12, '娱乐': 13, '科技': 14, '股票': 15, '游戏': 16, '财经': 17}

LABELS 是一个字典,用于将文本的标签(如“健康”、“军事”等)转换为对应的数值类别(0 到 17)。这在机器学习中非常常见,因为大部分机器学习算法需要数值化的输入。

3. 加载Word2Vec模型

def load_word2vec_model(path):
    model = Word2Vec.load(path)
    return model

这个函数通过提供的文件路径加载已经训练好的Word2Vec模型。Word2Vec 是一种用于将单词转化为向量的模型,训练过程中会学习到每个单词的词向量表示。这里加载的是一个已经训练好的模型文件。

训练好的词向量文件词向量模型权重文件

4. 加载数据集

def load_sentence(path, model):
    sentences = []
    labels = []
    with open(path, encoding="utf8") as f:
        for line in f:
            line = json.loads(line)
            title, content = line["title"], line["content"]
            sentences.append(" ".join(jieba.lcut(title)))
            labels.append(line["tag"])
    train_x = sentences_to_vectors(sentences, model)
    train_y = label_to_label_index(labels)
    return train_x, train_y

这个函数从给定的路径加载文本数据集。每一行包含新闻的标题和内容,同时还包含标签(新闻的分类)。在加载数据时:

  • 使用 jieba.lcut() 对标题进行中文分词。
  • 将分词后的标题连接成一个字符串,并存储在 sentences 列表中。
  • 标签(tag)也被存储在 labels 列表中。

然后:

  • 使用 sentences_to_vectors() 将分词后的句子转换为词向量(每个句子对应一个向量)。
  • 使用 label_to_label_index() 将标签转化为数值索引(0 到 17)。

5. 标签转化

def label_to_label_index(labels):
    return [LABELS[y] for y in labels]

这个函数将文本标签(如“健康”、“军事”等)转换为对应的数字索引,方便机器学习模型处理。

6. 文本向量化

def sentences_to_vectors(sentences, model):
    vectors = []
    for sentence in sentences:
        words = sentence.split()
        vector = np.zeros(model.vector_size)
        for word in words:
            try:
                vector += model.wv[word]
            except KeyError:
                vector += np.zeros(model.vector_size)
        vectors.append(vector / len(words))
    return np.array(vectors)

这个函数将每个句子转化为一个向量。具体步骤如下:

  • 每个句子被分成单个词(words)。
  • 为每个词查找其在Word2Vec模型中的向量表示,并将这些词向量相加。若词不存在于模型中(KeyError),则为该词使用零向量。
  • 最后将所有词向量的和除以词数,得到该句子的平均词向量。这样每个句子都被表示为一个固定维度的向量。

7. 主函数 main()

def main():
    model = load_word2vec_model("model.w2v")
    train_x, train_y = load_sentence("../data/train_tag_news.json", model)
    test_x, test_y = load_sentence("../data/valid_tag_news.json", model)
    classifier = SVC()
    classifier.fit(train_x, train_y)
    y_pred = classifier.predict(test_x)
    print(classification_report(test_y, y_pred))
  • model = load_word2vec_model("model.w2v"): 加载已经训练好的Word2Vec模型。
  • train_x, train_y = load_sentence("../data/train_tag_news.json", model): 加载训练集数据,将文本转化为词向量(train_x)并获得标签(train_y)。
  • test_x, test_y = load_sentence("../data/valid_tag_news.json", model): 加载验证集数据,同样进行文本转化。
  • classifier = SVC(): 创建一个支持向量机分类器(SVM)。
  • classifier.fit(train_x, train_y): 使用训练集对SVM进行训练。
  • y_pred = classifier.predict(test_x): 使用训练好的模型对测试集进行预测。
  • print(classification_report(test_y, y_pred)): 输出分类报告,评估模型在测试集上的表现(准确率、召回率、F1分数等)。

8. 程序入口

if __name__ == "__main__":
    main()

这行代码确保当该脚本直接运行时,会调用 main() 函数执行程序。

9.运行结果

在这里插入图片描述
根据给出的 分类报告,我们可以从多个角度进行分析:

9.1 总体表现
  1. 准确率(Accuracy):整体准确率为 0.44,即44%的样本被正确分类。这个结果说明,模型的表现相对较差,尤其是在多类别分类任务中。因为准确率并没有达到50%,这表明模型可能在某些类别上的预测结果不理想。
  2. 宏平均(Macro Average)
  3. Precision(精确率):0.46
  4. Recall(召回率):0.44
  5. F1-Score:0.42

宏平均计算的是各个类别的平均值,不考虑类别的不平衡。这里,F1-Score较低,说明模型在整体上可能存在精度与召回率之间的较大差异。

  1. 加权平均(Weighted Average)
  2. Precision(精确率):0.46
  3. Recall(召回率):0.44
  4. F1-Score:0.42

加权平均考虑了每个类别样本数的影响,相比于宏平均,加权平均给大类别更多权重。在这里加权平均和宏平均相似,表明类别分布对模型的影响较大。

9.2各类别的分析

观察每个类别的具体表现:
12. 类别0(健康)
13. Precision: 0.81
14. Recall: 0.95
15. F1-Score: 0.88
16. 支持度(Support): 22
健康类的分类效果较好,召回率非常高(0.95),表明该类别的大部分样本都被正确分类,但精确率(0.81)略低,意味着模型在预测健康类时有些误分类。
17. 类别16(游戏)
18. Precision: 1.00
19. Recall: 0.11
20. F1-Score: 0.20
21. 支持度(Support): 18

游戏类的精确率极高(1.00),意味着当模型预测为游戏类时,几乎所有的预测都是准确的。然而,召回率非常低(0.11),说明模型几乎没有成功识别游戏类的样本。这个不平衡的表现表明,模型可能过于保守,没有积极识别游戏类。

  1. 类别2(房产)
  2. Precision: 0.14
  3. Recall: 0.04
  4. F1-Score: 0.06
  5. 支持度(Support): 26

房产类的分类效果非常差,精确率召回率都很低,尤其是召回率(0.04),表明模型几乎没有识别出房产类的样本。这个类别可能存在样本不足、特征不明显或者模型无法有效区分该类别的原因。
27. 类别1(军事)
28. Precision: 0.19
29. Recall: 0.26
30. F1-Score: 0.22
31. 支持度(Support): 23
军事类也表现不佳,虽然召回率稍高于精确率,但F1-Score仍然较低,表明在该类样本中,模型预测效果差。

9.3. 模型问题和挑战
  • 类别不平衡:从报告中可以看出,不同类别的支持度差异较大,部分类别的样本数量较少(如类别16游戏类支持度为18)。类别不平衡通常会导致模型在某些类别上的表现不佳(如房产类、军事类、游戏类)。
  • 低召回率与低精确率:某些类别的召回率和精确率都较低,尤其是房产类和军事类。这可能意味着模型无法有效识别这些类别,或者这些类别的特征在训练数据中没有很好地被捕捉到。
9.4. 改进建议
  • 数据增强:考虑对训练集进行数据增强,尤其是对于样本较少的类别(如游戏类和房产类)。可以通过添加更多样本或使用过采样/欠采样方法来平衡类别。
  • 模型调优:调整SVM模型的超参数,特别是C和gamma的值,可能会改善分类效果。
  • 特征工程:探索其他的特征工程方法,或使用更多类型的文本特征来丰富模型的输入(例如,TF-IDF、n-grams等)。
  • 其他模型尝试:考虑尝试其他更复杂的模型,如深度学习模型(如BERT、LSTM等),它们可能在处理文本分类任务时能捕捉更复杂的特征。
9.5. 结论

总体来看,模型在不同类别上的表现差异较大。对于某些类别(如健康类),模型的效果不错,而对于其他类别(如房产类、军事类),则表现较差。模型的准确性可以进一步通过优化数据处理、调整模型参数或更换算法来提升。

总结:

这段代码的主要目的是:

  • 利用已训练好的 Word2Vec 模型,将新闻文本的标题转化为词向量。
  • 然后使用支持向量机(SVM)对这些词向量进行训练和分类。
  • 最终输出分类报告,评估模型的性能。

主要使用了:

  • Word2Vec 模型来进行词向量的获取。
  • jieba 分词库处理中文文本。
  • SVC(支持向量机)进行文本分类任务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值