自动文本分类技术将人类从繁琐的手工分类中解放出来,使分类任务变的更为高效,为 进一步的数据挖掘和分析奠定基础。对于新闻来说,简短的新闻简介是新闻内容的高度总结, 针对短文本的分类研究一直是自动文本分类技术的研究热点。本文基于 CCTV 网页中的数据, 采用 TF-IDF 和朴素贝叶斯分类算法相结合,捕捉短文本表达的语义,对短文本自动文本分 类进行智能化实现,为新闻网站的新闻分类实现提供参考,最后根据 kappa 系数对预测结果 进行评价。
关键字:TF-IDF;朴素贝叶斯;新闻;文本分类;
kappa 系数
1 背景介绍
新闻,是人们获取信息,了解时事热点的重要途径,尤其是近年来,新闻行业数字化发 展迅猛,新闻网络平台的普及,极大地满足了人们“足不出户而知天下事”的心愿。网络平 台上新闻报道、新闻评论、网友发声等文本数据快速增加。将这些文本数据正确归类,可以 更好地组织、利用这些信息,因此快速、准确地完成新闻分类任务具有十分重要的意义。
面对规模巨大且不断增长的文本信息,依靠人工将海量的文本信息分类是不现实的。近些年来,借助机器学习技术完成分类任务已成为主流,计算机可以通过不断学习获得经验技能,对未知的问题可以给出一个正确的分类标签。因此,通过机器学习,可以对新闻平台上的大量数据进行自动化分类,帮助用户提高检索效率,提升用户阅读体验,同时可以在分类的基础上分析与挖掘有用的信息,协助网站运营人员了解用户需求,让信息更有效的被利用, 这也是本文的研究意义所在。
2 数据分析
一般来说,文本分类模型需要提前标注好类别的语料作为训练集,属于有监督的学习,核心问题是选择合适的分类算法,构建分类模型。本文利用 TF-IDF 对短文本数据进行特征提取和朴素贝叶斯算法进行数据分类,集成构成模型。具体文本分类步骤如下:
1)预处理:填补文本中的缺失值,删除重复值
2)中文分词:使用 python 中的 jieba 库为文本分词,并去除停用词。
3)构建词向量空间:统计文本词频,生成文本的词向量空间。
4)权重策略 —TF-IDF 方法:使用 TF-IDF 发现特征词,并抽取为反应文档主题的特征。
5)分类器:使用朴素贝叶斯算法训练器分类。
6)评价分类结果:用
kappa 系数对
分类器的测试结果评价分析。
2.1 分布特征
首先,将数据整体进行描述性分布分析,对本文数据集进行新闻类别数量分布以及发文 时间分布进行统计,结果如图。
图 2.1 新闻类别分布
从上图可看出,数据整体分布不太均匀,两极分化较为严重。其中书画、人物、国内、 健康、社会、国际分布大体一致,是数据的主要组成部分;法治、生活次之;科技、教育、 文娱、三农、农经、军事、经济分布一致,但是数据占比很低。结合现实生活可知,人们对 健康、人物、社会等主题的新闻往往关注度较高,故相应的新闻报道就会偏多。
图 2.2 新闻时间分布
从上图可看出,本文爬取的新闻数据是从 2020 年 12 月至 2021 年 4 月的。其中本年 4 月份的数据占比最多,而其他月份的数据分布较均匀,可见,新闻的时效性很强,系统将会优先自动推荐临近时间的新闻给用户,而历史数据次之。
2.2 数据预处理
本文的数据来源是 CCTV 频道的新闻数据。文本预处理是文本分类常见且必须的步骤,通过清除不一致或无实体语义的字符,以及过滤分词后的停用词,都可以尽可能的降低文本
噪声带来的分类性能上的影响。并且可以有效的降低模型占用的内存,提高模型的泛化能力。 本文在文本数据预处理上主要采用了字符清洗、分词、去停用词。目前业界常见的分词工具包括 jieba 分词、清华的分词工具以及斯坦福的分词包。其中 jieba 分词在词性标注、分词准确率、分词粒度和性能上都相对较好,因此本文主要采用 jieba 进行文本分词操作。 由于新闻标题数据长度较短,语义表述较为简洁,因此不能采用全部的 jieba 停用词表, 本文仅对一些非常常见的停用词进行了过滤,例如“呢”,“吗”、“的”等词,既最大程度的保证了语义的完整性,又尽可能的去掉了停用词。
2.3 TF-IDF 挖掘文本特征
文本数据属于非结构化数据,一般要转换成结构化的数据,一般是将文本转换成“文档
-词频矩阵”,矩阵中的元素使用词频或者 TF-IDF。TF-IDF 的主要思想是:如果某一个词或短语在一篇文章中出现的频率高,并且在其他文章中很少出现,则认为此词或短语具有很好的类别区分能力,适合用于分类。
TF − IDF = TF ∗ IDF
IDF 主要思想:如果包含词条 t 的文档越少,也就是 n 越小,IDF 越大,则说明词条 t 具有很好的区分能力。
TF 指的是某一个给定的词语在该文件中出现的频率,这是对词数的归一化,IDF 是一个 词语重要性的度量,IDF=log(D/Dn),其中对数以 2 为底,D 为文本总数,Dn 为该词在 n 个网页中出现过。
2.4 朴素贝叶斯分类器
贝叶斯分类是一类分类算法的总称,这类算法均以贝叶斯定理为基础,故统称为贝叶斯 分类。朴素贝叶斯算法是其中应用最为广泛的分类算法之一。朴素贝叶斯分类器是一系列以 假设特征之间强(朴素)独立下运贝叶斯定理为基础的简单概率分类器。它基于一个简单的假 定:属性之间在确定目标值的情况下彼此条件独立。朴素贝叶斯分类器的一个优势在于只需 要根据少量的训练数据估计出必要的参数(变量的均值和方差)。
贝叶斯定理是一个与随机事件 A 和 B 的边缘概率相关的定理。其中 P(AIB)是在 B 发生
的情况下 A 发生的可能性。
朴素贝叶斯的思想大体上是:对于待分类项来说,解出各个类别在此项出现时出现的概 率,此待分类项的类别就是最大概率的分类。朴素贝叶斯分类模型的优势有:
1)时间复杂度、空间复杂度较低;
2)算法逻辑清晰简便,易于理解和转化为具体程序;
3)算法效果不易受其他因素干扰,模型健壮性良好。
在条件独立性假设的基础上,朴素贝叶斯分类器假设一个属性对指定类别的影响与其他 属性无关,朴素贝叶斯分类算法的最小的误分类率是在条件独立性假设生效的情况下同。但 朴素贝叶斯假设在实际中往往并不成立,多少影响了朴素贝叶斯分类器的分类效果。
2.5 Kappa 系数
kappa 系数是用在统计学中评估一致性的一种方法,取值范围是[-1,1],实际应用中, 一般[0,1],与 ROC 曲线中一般不会出现下凸形曲线的原理类似。这个系数的值越高,则 代表模型实现的分类准确度越高。
其中,
ܲ
0
表示总体分类精度,
ܲ
݁
表示 SUM(第 i 类真实样本数*第 i 类预测出来的样本数)/ 样本总数平方。
系数 | 0-0.2 | 0.2-0.4 | 0.4-0.6 | 0.6-0.8 | 0.8-1 |
一致系数 | 极低 | 一般 | 中等 | 高度 | 几乎完全一致 |
表 2.5 评价指标优劣表
3 分类结果
依据上述分类原理,首先利用训练数据进行模型训练,然后将训练好的模型对验证数据 进行预测以此来验证训练出模型的泛化能力。预测的分类结果如下: (书画: 0, 人物: 1, 国际:2, 国内: 3, 健康: 4, 社会: 5, 法治: 6, 生活: 7, 科技: 8, 教育: 9, 文娱: 10, 农经: 11, 三农: 12, 军事: 13, 经济: 14)
分类准确率:0.6059661620658949
precision | recall | f1-score | support | |
0 | 0.57 | 0.95 | 0.71 | 298 |
1 | 0.47 | 0.76 | 0.58 | 241 |
2 | 0.66 | 0.91 | 0.77 | 236 |
3 | 0.59 | 0.61 | 0.60 | 259 |
4 | 0.81 | 0.86 | 0.83 | 264 |
5 | 0.50 | 0.62 | 0.55 | 259 |
6 | 0.83 | 0.42 | 0.56 | 146 |
7 | 0.69 | 0.15 | 0.25 | 133 |
8 | 1.00 | 0.02 | 0.04 | 92 |
9 | 0.75 | 0.04 | 0.08 | 68 |
10 | 0.00 | 0.00 | 0.00 | 66 |
11 | 0.00 | 0.00 | 0.00 | 48 |
12 | 1.00 | 1.00 | 1.00 | 47 |
13 | 0.00 | 0.00 | 0.00 | 50 |
14 | 0.00 | 0.00 | 0.00 | 39 |
precision | recall | f1-score | support | |
accuracy | 0.61 | 2246 | ||
macro avg | 0.52 | 0.42 | 0.40 | 2246 |
weighted avg | 0.59 | 0.61 | 0.54 | 2246 |
Kappa:0.5562815523035762 |
从上述结果可知,基于 TF-IDF 和朴素贝叶斯算法训练出来的模型在测试集上分类的正确率0.61,分类结果较为精确。对于新闻中的每个主题,可以清楚地看出模型对每个类别的精确率、召回率、F1 值、以及准确预测的个数。可以发现,编号为“12”即三农的各个指标系数都达到了 1,说明本文训练的模型能够完美地识别出该类主题的新闻;而对于编号为“10、11、13、14”即文娱、农经、军事、经济的各个指标系数都为 0,可见本文的模型对这四类主题的新闻的特征都没有提取到位,还需要进一步对这些方面着重注意来优化模型;而剩余的主题都在中等偏上水平。最后的 Kappa 系数是专门对多分类指标的综合评价指标,其值为 0.56,接近于 0.6,故此次模型的分类准确率高。
4 结论
针对中文短文本的特点,本文以新闻标题为实验数据,利用 TF-IDF 有效地提取新闻标题中语义信息,构建了基于朴素贝叶斯的分类模型,实现了网络新闻平台上新闻标题的自动分类,对新闻网站的建设及更深一步的信息挖掘,有一定的推动意义。未来,可以以此为基础,分析用户的阅读新闻的类型喜好,实现新闻个性化推荐,给用户带来更良好的体验与服务。
5 未来展望
本文主要介绍了在现今社会中,新闻文本自动分类的必要性和需求,重点介绍了文本分类的主要流程、基本原理和方法。虽然中文新闻文本分类技术在前辈学者的研究下已经有了一定的进展,但仍有许多方面需要进一步的研究和努力。
附件:
import pandas as pd
import matplotlib.pyplot as plt
import warnings
plt.rcParams["font.family"] = "SimHei"
plt.rcParams["axes.unicode_minus"] = False
plt.rcParams["font.size"] = 15
warnings.filterwarnings("ignore")
#读取数据
news = pd.read_csv("news (1).csv", encoding="gbk")
print(news.head())
###缺失值处理
news.info()
##使用新闻简介填充缺失的新闻标题
index = news[news.标题.isnull()].index
news["标题"][index]=news["brief"][index]
##使用新闻标题填充缺失的新闻简介
index = news[news.brief.isnull()].index
news["brief"][index]=news["标题"][index]
news.isnull().sum()
#重复值处理
print(news[news.duplicated()])
news.drop_duplicates(inplace=True)
#新闻类别分布
###数据探索 描述性分析
t = news["新闻类别"].value_counts()
print(t)
t.plot(kind="bar")
#事件发生时间
t = news["发布时间"].str.split("-", expand=True)
t2 = t[[0,1]].value_counts()
t2.plot(kind="bar")
#文本内容清洗
import re ####文本的处理 sub调用编译后的正则对象对文本进行处理
re_obj = re.compile(r"['~`!#$%^&*()_+-=|\';:/.,?><~·!@#¥%……&*()——+-=“:’;、。,?》《{}':【】《》‘’“”\s]+")
def clear(text):
return re_obj.sub("", text)
news["brief"] = news["brief"].apply(clear)
news.sample(10)
#分词
import jieba
def cut_word(text): ###分词,使用jieba的lcut方法分割词,生成一个列表,
####cut() 生成一个生成器, 不占用空间或者说占用很少的空间,使用list()可以转换成列表
return jieba.lcut(text)
news["brief"] = news["brief"].apply(cut_word)
news.sample(5)
print(news["brief"].head())
#停用词处理
def get_stopword(): ####删除停用词,就是在文中大量出现,对分类无用的词 降低存储和减少计算时间
s = set() ###通过hash处理后的键映射数据 列表则是通过下标的顺序存储映射数据
with open("中文停用词表.txt", encoding="gbk") as f:
for line in f:
s.add(line.strip())
return s
def remove_stopword(words):
return [word for word in words if word not in stopword]
stopword = get_stopword()
news["brief"] = news["brief"].apply(remove_stopword)
news.sample(5)
print(news["brief"].head())
#标签转换
label_mappping = {"书画": 0, "人物": 1, "国际":2,"国内": 3,"健康": 4,"社会": 5,"法治": 6,"生活": 7,"科技": 8,"教育": 9,"文娱": 10,
"农经": 11,"三农": 12,"军事": 13,"经济": 14}
news["新闻类别"] = news["新闻类别"].map(label_mappping)
print(news.head())
print("--------------------------------------3------------------------------------------")
#切分数据
from sklearn.model_selection import train_test_split
x =news["brief"]
y = news["新闻类别"]
x_train, x_test, y_train, y_test = train_test_split(x.values, y.values, test_size=0.5)
def format_transform(X): #x是数据集(训练集或者测试集)
words =[]
for line_index in range(len(X)):
try:
words.append(" ".join(X[line_index]))
except:
print("数据格式有问题")
return words
#训练
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
words_train = format_transform(x_train)
vectorizer = TfidfVectorizer(analyzer='word', max_features=4000,ngram_range=(1, 3),lowercase = False)
vectorizer.fit(words_train)#转为向量格式
classifier = MultinomialNB()
classifier.fit(vectorizer.transform(words_train), y_train)
#测试查验相关结果
from sklearn.metrics import classification_report
words_test = format_transform(x_test)
score = classifier.score(vectorizer.transform(words_test), y_test)
print("----------------------------------分类结果报告-----------------------------------------")
print("分类准确率:" + str(score))
y_predict = classifier.predict(vectorizer.transform(words_test))
print(classification_report(y_test, y_predict))
#评价指标
from sklearn.metrics import cohen_kappa_score
kappa = cohen_kappa_score(y_test, y_predict)
print(kappa)