前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >直播案例 | 使用KNN对新闻主题进行自动分类

直播案例 | 使用KNN对新闻主题进行自动分类

原创
作者头像
数据酷客
修改2020-05-18 14:27:33
1.9K0
修改2020-05-18 14:27:33
举报
视频内容

本案例旨在用新闻主题分类这一简单任务演示机器学习的一般流程。具体地,我们使用了一个搜狐新闻数据集。使用 Python 的 jieba 分词工具对中文新闻进行了分词处理。然后使用 Scikit-learn 工具的 K近邻算法构建 KNN 模型。最后对新闻分类的效果进行了简单的分析。

1 数据读取

搜狐中文新闻数据存放在 train_sample_utf8.csvtest_sample_utf8.csv 两个文件中,在后面的分析中我们分别当做训练集和测试集来使用。我们首先使用 Pandas 中的 read_csv 函数读取。

代码语言:javascript
复制
import pandas as pd
%matplotlib inline
raw_train = pd.read_csv("./input/train_sample_utf8.csv",encoding="utf8")
raw_test = pd.read_csv("./input/test_sample_utf8.csv",encoding="utf8")

查看两个文件的前五行数据。

代码语言:javascript
复制
raw_train.head(5)
代码语言:javascript
复制
raw_test.head(5)
代码语言:javascript
复制
raw_train.shape

(5521, 3)

代码语言:javascript
复制
raw_test.shape

(3111, 2)

可见,训练集包含 5521 条新闻,测试集中包含 3111 条新闻。那么,训练集和测试集中,不同主题的新闻分布如何?我们可以借助 DataFrame 某列的 value_counts 方法完成统计。然后使用 plot 函数进行可视化显示。

代码语言:javascript
复制
import matplotlib.pyplot as plt
plt.figure(figsize=(15, 8))
plt.subplot(1, 2, 1)
raw_train["分类"].value_counts().sort_index().plot(kind="barh",title='训练集新闻主题分布')
plt.subplot(1, 2, 2)
raw_test["分类"].value_counts().sort_index().plot(kind="barh",title='测试集新闻主题分布')

一共包含 12 种主题的新闻,无论是在训练集还是测试集,各个主题的新闻分布较均衡。

2 对新闻内容进行分词

由于新闻为中文,再进一步进行处理之前,我们需要先对新闻内容进行分词。简单来说,分词就是将连在一起的新闻内容中的词进行分割。这里我们使用 Python 中一个著名的中文分析器 jieba 完成这项任务。为了后续方便,我们封装一个 news_cut 函数,它接受的输入为新闻内容,输出为分词后的结果。分词后,词与词之间使用空格进行分隔。

代码语言:javascript
复制
import jieba
def news_cut(text):
    return " ".join(list(jieba.cut(text)))
#简单测试下分词效果
test_content = "六月初的一天,来自深圳的中国旅游团游客纷纷拿起相机拍摄新奇刺激的好莱坞环球影城主题公园场景。"
print(news_cut(test_content))

现在利用封装的分词函数,对训练集和测试集中的新闻内容进行分词处理,分词结果保存到对应 DataFrame 对象的 ”分词文章“ 一列。这里我们使用了 Pandas 中的 Series 对象的 map 函数。它能够接受一个函数,对 Series 中的每一个元素作为该函数的输入,然后将函数的输出返回。

代码语言:javascript
复制
raw_train["分词文章"] = raw_train["文章"].map(news_cut)
raw_test["分词文章"] = raw_test["文章"].map(news_cut)
代码语言:javascript
复制
raw_test.head(5)

3 将新闻表示为向量

代码语言:javascript
复制
#加载停用词
stop_words = []
file = open("./input/stopwords.txt") 
for line in file:
    stop_words.append(line.strip())
file.close()
代码语言:javascript
复制
from sklearn.feature_extraction.text import CountVectorizer
vectorizer = CountVectorizer(stop_words=stop_words)
X_train = vectorizer.fit_transform(raw_train["分词文章"])
X_test = vectorizer.transform(raw_test["分词文章"])

4 构建 KNN 分类器

使用 sklearnneighbors 模块的 KNeighborsClassifier 类构建一个 KNN 分类器。我们将邻居数 n_neighbors 设置为 5 。使用邻居的标签进行投票时,用预测样本与邻居样本的距离的倒数作为权重。然后使用 fit 方法,在训练集中训练模型。

代码语言:javascript
复制
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors=5,weights="distance")
knn.fit(X_train, raw_train["分类"])

5 测试集新闻主题预测

模型训练完成后,可以使用 predict 方法对测试集中的样本进行预测,得到预测标签列表 Y_test

代码语言:javascript
复制
Y_test = knn.predict(X_test)

6 新闻主题分类效果进行评估

下面使用混淆矩阵来分析模型在测试样本上的表现。混淆矩阵从样本的真实标签和模型预测标签两个维度对测试集样本进行分组统计,然后以矩阵的形式展示。借助混淆矩阵可以很好地分析模型在每一类样本上的分类效果。为了更直观地分析,我们借助 Python 中可视化包 seaborn 提供的 heatmap 函数,将混淆矩阵可视化。

代码语言:javascript
复制
from sklearn.metrics import confusion_matrix
import seaborn as sns
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(9, 7))
## 设置正常显示中文
sns.set(font='SimHei')
## 绘制热力图
ax = sns.heatmap(confusion_matrix(raw_test["分类"].values,Y_test),linewidths=.5,cmap="Greens",
                 annot=True, fmt='d',xticklabels=knn.classes_, yticklabels=knn.classes_)
ax.set_ylabel('真实')
ax.set_xlabel('预测')
ax.xaxis.set_label_position('top') 
ax.xaxis.tick_top()
ax.set_title('混淆矩阵热力图')

这还不是一个完美的新闻主题分类器,这个分类器倾向于将主题预测为"教育"或"文化"。要获得更好的效果,我们可能还需要做很多工作,例如更好的文本预处理和表示,尝试不同的 K 值的效果,甚至利用其它的机器学习算法等。感兴趣的同学可以自己进一步进行尝试。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 数据读取
  • 2 对新闻内容进行分词
  • 3 将新闻表示为向量
  • 4 构建 KNN 分类器
  • 5 测试集新闻主题预测
  • 6 新闻主题分类效果进行评估
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档