基于机器学习的文本分类!

2023-11-13

↑↑↑关注后"星标"Datawhale

每日干货 & 每月组队学习,不错过

 Datawhale干货 

作者:李露,西北工业大学,Datawhale优秀学习者

据不完全统计,网民们平均每人每周收到的垃圾邮件高达10封左右。垃圾邮件浪费网络资源的同时,还消耗了我们大量的时间。大家对此深恶痛绝,于是识别垃圾邮件并对其进行过滤成为各邮件服务商的重要工作之一。

垃圾邮件识别问题本质上是一个文本分类问题,给定文档p(可能含有标题t),将文档分类为n个类别中的一个或多个。文本分类一般有两种处理思路:基于机器学习的方法和基于深度学习的方法。

本文主要基于机器学习的方法,介绍了特征提取+分类模型在文本分类中的应用。具体目录如下:

一、数据及背景

https://tianchi.aliyun.com/competition/entrance/531810/information(阿里天池-零基础入门NLP赛事)

二、文本表示方法

在机器学习算法的训练过程中,假设给定 个样本,每个样本有 个特征,这样就组成了 的样本矩阵。在计算机视觉中可以把图片的像素看作特征,每张图片都可以视为 的特征图,然后用一个三维矩阵带入计算。

但是在自然语言领域,上述方法却不可行,因为文本的长度是不固定的。文本分类的第一步就是将不定长的文本转换到定长的空间内,即词嵌入。

2.1 One-hot

One-hot方法将每一个单词使用一个离散的向量表示,将每个字/词编码成一个索引,然后根据索引进行赋值。One-hot表示法的一个例子如下:

句子1:我 爱 北 京 天 安 门
句子2:我 喜 欢 上 海

首先对句子中的所有字进行索引

{'我': 1, '爱': 2, '北': 3, '京': 4, '天': 5, '安': 6, '门': 7, '喜': 8, '欢': 9, '上': 10, '海': 11}

一共11个字,因此每个字可以转换为一个11维的稀疏向量:

我:[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
爱:[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
...
海:[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]

2.2 Bags of Words

Bags of Words,也称为Count Vectors,每个文档的字/词可以使用其出现次数来进行表示。例如对于:

句子1:我 爱 北 京 天 安 门
句子2:我 喜 欢 上 海

直接统计每个字出现的次数,并进行赋值:

句子1:我 爱 北 京 天 安 门
转换为 [1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0]
句子2:我 喜 欢 上 海
转换为 [1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1]

可以利用sklearn的CountVectorizer来实现这一步骤。

from sklearn.feature_extraction.text import CountVectorizercorpus = ['This is the first document.','This document is the second document.','And this is the third one.','Is this the first document?',]vectorizer = CountVectorizer()vectorizer.fit_transform(corpus).toarray()

输出为:

[[0, 1, 1, 1, 0, 0, 1, 0, 1],
[0, 2, 0, 1, 0, 1, 1, 0, 1],
[1, 0, 0, 1, 1, 0, 1, 1, 1],
[0, 1, 1, 1, 0, 0, 1, 0, 1]]

2.3 N-gram

N-gram与Count Vectors类似,不过加入了相邻单词组合为新的单词,并进行计数。如果N取值为2,则句子1和句子2就变为:

句子1:我爱 爱北 北京 京天 天安 安门
句子2:我喜 喜欢 欢上 上海

2.4 TF-IDF

TF-IDF分数由两部分组成:第一部分是词语频率(Term Frequency),第二部分是逆文档频率(Inverse Document Frequency)

三、基于机器学习的文本分类

接下来我们将研究文本表示对算法精度的影响,对比同一分类算法在不同文本表示下的算法精度,通过本地构建验证集计算F1得分。

3.1 导入相关的包

import pandas as pdimport numpy as npfrom sklearn.feature_extraction.text import CountVectorizerfrom sklearn.feature_extraction.text import TfidfVectorizerfrom sklearn.linear_model import RidgeClassifierimport matplotlib.pyplot as pltfrom sklearn.metrics import f1_score

3.2 读取数据

train_df = pd.read_csv('./data/train_set.csv', sep='\t', nrows=15000)

3.3 文本分类对比

3.3.1 Count Vectors + RidgeClassifier

vectorizer = CountVectorizer(max_features=3000)train_test = vectorizer.fit_transform(train_df['text'])
clf = RidgeClassifier()clf.fit(train_test[:10000], train_df['label'].values[:10000])
val_pred = clf.predict(train_test[10000:])print(f1_score(train_df['label'].values[10000:], val_pred, average='macro'))

输出为 .

3.3.2 TF-IDF + RidgeClassifier

tfidf = TfidfVectorizer(ngram_range=(1,3), max_features=3000)train_test = tfidf.fit_transform(train_df['text'])
clf = RidgeClassifier()clf.fit(train_test[:10000], train_df['label'].values[:10000])
val_pred = clf.predict(train_test[10000:])print(f1_score(train_df['label'].values[10000:], val_pred, average='macro'))

输出为 .

四、研究参数对模型的影响

4.1 正则化参数对模型的影响

取大小为5000的样本,保持其他参数不变,令 从0.15增加至1.5,画出关于 的图像

sample = train_df[0:5000]n = int(2*len(sample)/3)tfidf = TfidfVectorizer(ngram_range=(2,3), max_features=2500)train_test = tfidf.fit_transform(sample['text'])train_x = train_test[:n]train_y = sample['label'].values[:n]test_x = train_test[n:]test_y = sample['label'].values[n:]
f1 = []for i in range(10):  clf = RidgeClassifier(alpha = 0.15*(i+1), solver = 'sag')  clf.fit(train_x, train_y)  val_pred = clf.predict(test_x)  f1.append(f1_score(test_y, val_pred, average='macro'))
plt.plot([0.15*(i+1) for i in range(10)], f1)plt.xlabel('alpha')plt.ylabel('f1_score')plt.show()

结果如下:

可以看出 不宜取的过大,也不宜过小。 越小模型的拟合能力越强,泛化能力越弱, 越大模型的拟合能力越差,泛化能力越强。

4.2 max_features对模型的影响

分别取max_features的值为1000、2000、3000、4000,研究max_features对模型精度的影响

f1 = []features = [1000,2000,3000,4000]for i in range(4):  tfidf = TfidfVectorizer(ngram_range=(2,3), max_features=features[i])  train_test = tfidf.fit_transform(sample['text'])  train_x = train_test[:n]  train_y = sample['label'].values[:n]  test_x = train_test[n:]  test_y = sample['label'].values[n:]  clf = RidgeClassifier(alpha = 0.1*(i+1), solver = 'sag')  clf.fit(train_x, train_y)  val_pred = clf.predict(test_x)  f1.append(f1_score(test_y, val_pred, average='macro'))
plt.plot(features, f1)plt.xlabel('max_features')plt.ylabel('f1_score')plt.show()

结果如下:

可以看出max_features越大模型的精度越高,但是当max_features超过某个数之后,再增加max_features的值对模型精度的影响就不是很显著了。

4.3 ngram_range对模型的影响

n-gram提取词语字符数的下边界和上边界,考虑到中文的用词习惯,ngram_range可以在(1,4)之间选取

f1 = []tfidf = TfidfVectorizer(ngram_range=(1,1), max_features=2000)train_test = tfidf.fit_transform(sample['text'])train_x = train_test[:n]train_y = sample['label'].values[:n]test_x = train_test[n:]test_y = sample['label'].values[n:]clf = RidgeClassifier(alpha = 0.1*(i+1), solver = 'sag')clf.fit(train_x, train_y)val_pred = clf.predict(test_x)f1.append(f1_score(test_y, val_pred, average='macro'))
tfidf = TfidfVectorizer(ngram_range=(2,2), max_features=2000)train_test = tfidf.fit_transform(sample['text'])train_x = train_test[:n]train_y = sample['label'].values[:n]test_x = train_test[n:]test_y = sample['label'].values[n:]clf = RidgeClassifier(alpha = 0.1*(i+1), solver = 'sag')clf.fit(train_x, train_y)val_pred = clf.predict(test_x)f1.append(f1_score(test_y, val_pred, average='macro'))
tfidf = TfidfVectorizer(ngram_range=(3,3), max_features=2000)train_test = tfidf.fit_transform(sample['text'])train_x = train_test[:n]train_y = sample['label'].values[:n]test_x = train_test[n:]test_y = sample['label'].values[n:]clf = RidgeClassifier(alpha = 0.1*(i+1), solver = 'sag')clf.fit(train_x, train_y)val_pred = clf.predict(test_x)f1.append(f1_score(test_y, val_pred, average='macro'))
tfidf = TfidfVectorizer(ngram_range=(1,3), max_features=2000)train_test = tfidf.fit_transform(sample['text'])train_x = train_test[:n]train_y = sample['label'].values[:n]test_x = train_test[n:]test_y = sample['label'].values[n:]clf = RidgeClassifier(alpha = 0.1*(i+1), solver = 'sag')clf.fit(train_x, train_y)val_pred = clf.predict(test_x)f1.append(f1_score(test_y, val_pred, average='macro'))

输出如下

ngram_range取(1,3)的效果较好。

五、考虑其他分类模型

特征提取使用TF-IDF,与第三节中TF-IDF + RidgeClassifier的特征提取保持一致,再来看下其他几种分类算法的效果。

5.1 LogisticRegression

LogisticRegression的目标函数为:

from sklearn import linear_model


tfidf = TfidfVectorizer(ngram_range=(1,3), max_features=5000)
train_test = tfidf.fit_transform(train_df['text']) # 词向量 15000*max_features


reg = linear_model.LogisticRegression(penalty='l2', C=1.0,solver='liblinear')
reg.fit(train_test[:10000], train_df['label'].values[:10000])


val_pred = reg.predict(train_test[10000:])
print('预测结果中各类新闻数目')
print(pd.Series(val_pred).value_counts())
print('\n F1 score为')
print(f1_score(train_df['label'].values[10000:], val_pred, average='macro'))

输出为0.846470490043.

5.2 SGDClassifier

SGDClassifier使用mini-batch来做梯度下降,在处理大数据的情况下收敛更快

tfidf = TfidfVectorizer(ngram_range=(1,3), max_features=5000)train_test = tfidf.fit_transform(train_df['text']) # 词向量 15000*max_features
reg = linear_model.SGDClassifier(loss="log", penalty='l2', alpha=0.0001,l1_ratio=0.15)reg.fit(train_test[:10000], train_df['label'].values[:10000])
val_pred = reg.predict(train_test[10000:])print('预测结果中各类新闻数目')print(pd.Series(val_pred).value_counts())print('\n F1 score为')print(f1_score(train_df['label'].values[10000:], val_pred, average='macro'))

输出为0.847267047346

5.3 SVM

from sklearn import svmtfidf = TfidfVectorizer(ngram_range=(1,3), max_features=5000)train_test = tfidf.fit_transform(train_df['text']) # 词向量 15000*max_features
reg = svm.SVC(C=1.0, kernel='linear', degree=3, gamma='auto',decision_function_shape='ovr')reg.fit(train_test[:10000], train_df['label'].values[:10000])
val_pred = reg.predict(train_test[10000:])print('预测结果中各类新闻数目')print(pd.Series(val_pred).value_counts())print('\n F1 score为')print(f1_score(train_df['label'].values[10000:], val_pred, average='macro'))

输出为0.884240695943.

对比几种机器学习算法可以看出,在相同的TF-IDF特征提取方法基础上,用SVM得到的分类效果最好。

本文电子版 后台回复 文本分类 获取

“整理不易,三连

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于机器学习的文本分类! 的相关文章

随机推荐

  • hive报错:return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. MetaException(message:Got exceptio

    根据网上搜的解决方案 基本都是说连接的mysql编码不对 改alter database hive character set latin1 但是依然报错 根据后半段报错 MetaException message Got exceptio
  • Linux用dd命令制作启动盘

    1 将U盘格式化成 FAT32 格式 按Ctrl R 打开cmd 输入diskpart 输入list disk select disk 1 输入clean 2 在windows 系统上找到Disk Management 选择disk 1 右
  • linux命令批量修改文件名称

    批量修改文件名称 剔除部分相同的内容 for name in ls a do mv name name x86 64 unknown linux gnu a done 解释说明 ls a 是改目录下所有的 a文件 mv 源文件名 替换文件名
  • Unity学习记录——粒子系统与流动效果

    Unity学习记录 粒子系统与流动效果 前言 本文是中山大学软件工程学院2020级3d游戏编程与设计的最终作业 编程题 粒子光环 1 概述 粒子系统在unity官网与老师课件中的概念定义如下 粒子系统 Unity 手册 一个粒子系统可以模拟
  • Python语言程序设计 最新测验题目汇总 嵩天老师

    测验1 Python基本语法元素 Hello World的条件输出 获得用户输入的一个整数 参考该整数值 打印输出 Hello World 要求 如果输入值是0 直接输出 Hello World 如果输入值大于0 以两个字符一行方式输出 H
  • 草根程序员转型做项目管理走过的点点滴滴之"经验总结"

    本篇总结主要以驻场团队的过往经验为基础开展 与其是较经验总结 称呼为过往会议更贴切 团队内部一次交流记录 随后会继续补充完善 1 沟通交流 a 交流的平等基因 不可怯场 把握一个平等的状态投入到沟通交流中去 b 交流的整段性 不要打断客户的
  • 2021年信息安全保研经历分享

    一 写在前面 1 基本信息 学校 排名 某双非学校 信息安全专业 成绩 综合均是rank1 英语 四级560 六级430 获奖 国家奖学金 蓝桥杯省一 几个校奖 项目 一个很水的校级大创 最终去向 东南网安 南京专硕 总的来说 我就是一个无
  • karma配置及使用

    karma配置及使用 一 定义 Karma不是测试框架 也不是断言库 Karma是一个测试工具 一个允许在多个真实浏览器中执行JavaScript代码的工具 为开发人员提供高效的测试环境 代码可能是设计在浏览器端执行的 在node环境下测试
  • qnx的汽车全液晶仪表-基于qnx系统的汽车仪表-车机系统开发

    如果你认为本系列文章对你有所帮助 请大家有钱的捧个钱场 点击此处赞助 赞助额0 1元起步 多少随意 声明 本文只用于个人学习交流 若不慎造成侵权 请及时联系我 立即予以改正 锋影 e mail 174176320 qq com QNX系统在
  • 3·15报道:“隔空盗刷”资金骗局曝出

    近些年顾客的网上购物等服务愈来愈多 许多犯罪分子根据 ETC卡禁止使用 快递丢失赔付 等骗术 哄骗顾客登陆诈骗网站对它进行行骗 3 15晚会视频表明 陈女士曾收到一条提醒她ETC卡已禁用短信 需登录网页开展签办 接着 陈女士点链接之后发现
  • vue.js——事件循环机制

    一 事件循环机制介绍 JS是单线程的语言 浏览器和Node js定义了各自的Event Loop 事件循环机制 则是用来解决异步问题 将程序分为 主线程 执行栈 与 Event Loop线程 主线程 自上而下依次执行同步任务 Event L
  • 毕业设计 - 基于java web的在线考试系统【源码+论文】

    文章目录 前言 一 项目设计 1 模块设计 2 基本功能 2 1 登录功能 2 2 系统答题 2 3 答题得分 2 4 错题解析 3 实现效果 二 部分源码 项目源码 前言 今天学长向大家分享一个 Java web 项目 可用于毕业设计 课
  • vue新一代的状态管理器之pinia

    Pinia 简介 Pinia 是 Vue 新一代的轻量级状态管理库 相当于 Vuex 也是 Vue 核心团队推荐的状态管理库 同时支持 Vue2 和 Vue3 未来很有可能替代 Vuex 比 Vuex 更容易上手 特性 Pinia 具有以下
  • 探索未来的人机交互方式

    在21世纪 人工智能 AI 已成为科技领域的重要焦点 特别是在 生成式AI 这个细分领域中 所谓的 生成式AI 是指能够创造 理解和生成各种形式内容的人工智能系统 本文将重点探讨 生成式AI 报告中的重点词汇或短语 为您解析它的潜力与未来
  • 线程池+CountDownLatch 处理大集合

    场景 有一个需求 首先从数据库中取出上千条数据 然后需要逐条对数据进行分析 例如分析情感 是否重复等多项分析 解决 将取出来的上千条 分批 多线程处理 public class CountDownLatchTest public stati
  • C++ bitset的用法实例

    C bitset的用法实例 一 bitset 二 代码 三 总结 一 bitset 顾名思义 bitset是位bit的set集合 是可以当做容器使用的一种数据结构 bitset提供了一些很实用的方法 能用来替代C语言的直接按位运算带来的不便
  • 毕设基于深度学习的以图搜图系统 matlab语言

    毕设基于深度学习的以图搜图系统 matlab语言 文章目录 毕设基于深度学习的以图搜图系统 matlab语言 前言 一 实验数据集准备 二 软件设计 1 以图搜纸皮 2 以图搜花 实验总结 前言 随着人工智能的不断发展 深度学习这门技术也越
  • NFT颓势已现:肝不起了,卷不动了

    白名单制度是时候变革了 作者 星球小花 出品 Odaily星球日报 ID o daily 前几天 一位朋友问我 几个月没关注 NFT 了 你们怎么还在抢 PFP 我也反驳了一番 现在有很多圈外流量涌入 巨头纷纷进场 应用遍地开花 不过仔细想
  • C++中typeid的使用

    RTTI Run TimeType Information 运行时类型信息 它提供了运行时确定对象类型的方法 在C 中 为了支持RTTI提供了两个操作符 dynamic cast和typeid The typeid operator pro
  • 基于机器学习的文本分类!

    关注后 星标 Datawhale 每日干货 每月组队学习 不错过 Datawhale干货 作者 李露 西北工业大学 Datawhale优秀学习者 据不完全统计 网民们平均每人每周收到的垃圾邮件高达10封左右 垃圾邮件浪费网络资源的同时 还消