机器学习(七):贝叶斯之新闻分类器

一、文档与关键词提取

1、 停用词

在一篇文档中,有很多停用词,比如“今天”、“明天”、“一下”…这些词对文本的分析都没有用处,跟主题没有关系。

2、Tf-idf:关键词提取

TF(Term Frequency)即为词频
举例:对《中国的蜜蜂养殖》进行词频统计
(1)首先去除掉停用词

(2)计算词频
词频(TF) = 某个词在文章中出现的次数/文章所有词的总数
“中国”、“蜜蜂”、“养殖”这三个词的出现次数一样多,那重要性是一样的吗?

(3)逆文档频率(IDF)
“中国”是很常见的词,与文本的主题不太相关,而“蜜蜂”、“养殖”出现在一个文档里不那么常见。如果某个词比较少见,但是它在这篇文章中多次出现,那么它很可能就反映了这篇文章的特性 正是我们所需要的关键词。
逆文档频率(IDF) = log(语料库的文档总数/(包含该词的文档数+1))

(4) TF-IDF = 词频(TF) * 逆文档频率(IDF)

3、相似度

在这里插入图片描述
在这里插入图片描述
计算相似度步骤:
(1)预处理:语料清洗
删去停用词以及以及重复的词(赞、给个好评等)
(2)分词
(3)词频
(4)词频向量
(5)余弦相似度计算相似度

二、新闻分类器

1、 数据

数据集来源:http://www.sogou.com/labs/resource/ca.php
对新闻进行分类,当前新闻是属于文化类,还是汽车类、娱乐类等。

import pandas as pd
import jieba
df_news = pd.read_table('./data/val.txt',names=['category','theme','URL','content'],encoding='utf-8')
df_news = df_news.dropna()
df_news.head()

输出:
在这里插入图片描述

df_news.shape

输出:

(5000, 4)

可以看出是5000行4列

2、 分词:使用结巴分词器

# 将content这一列的内容转换为列表
content = df_news.content.values.tolist()
print (content[1000])

输出:

阿里巴巴集团昨日宣布,将在集团管理层面设立首席数据官岗位(Chief Data Officer),阿里巴巴B2B公司CEO陆兆禧将会出任上述职务,向集团CEO马云直接汇报。>菹ぃ和6月初的首席风险官职务任命相同,首席数据官亦为阿里巴巴集团在完成与雅虎股权谈判,推进“one company”目标后,在集团决策层面新增的管理岗位。0⒗锛团昨日表示,“变成一家真正意义上的数据公司”已是战略共识。记者刘夏

(1)对该条新闻进行分词:

content_S = []# 存放分词
for line in content:
    current_segment = jieba.lcut(line)
    if len(current_segment) > 1 and current_segment != '\r\n': #换行符
        content_S.append(current_segment)
content_S[1000]

输出:

['阿里巴巴',
 '集团',
 '昨日',
 '宣布',
 ',',
 '将',
 '在',
 '集团',
 '管理',
 ....]

(2)对所有的新闻进行分词的整合

# 清洗,去掉停用词
df_content=pd.DataFrame({'content_S':content_S})
df_content.head()

输出:
在这里插入图片描述
(3)展示停用词

stopwords=pd.read_csv("stopwords.txt",index_col=False,sep="\t",quoting=3,names=['stopword'], encoding='utf-8')
stopwords.head(20)

输出:
在这里插入图片描述
(4)遍历清洗停用词

def drop_stopwords(contents,stopwords):
   contents_clean = []# 放清理后的分词
   all_words = []
   for line in contents:
       line_clean=[]
       for word in line:
           if word in stopwords:
               continue
           line_clean.append(word)
           all_words.append(str(word))
       contents_clean.append(line_clean)
   return contents_clean,all_words

contents = df_content.content_S.values.tolist()
stopwords = stopwords.stopword.values.tolist()
contents_clean,all_words = drop_stopwords(contents,stopwords)
# 展示清理后的词
df_content = pd.DataFrame({'contents_clean':contents_clean})
df_content.head()

输出:
在这里插入图片描述

# 所有的词
df_all_words = pd.DataFrame({'all_words':all_words})
df_all_words.head()

输出:
在这里插入图片描述
(5)计算词频

# 算词频,并排序
import numpy
words_count = df_all_words.groupby(by=['all_words'])['all_words'].agg({"count":numpy.size})
words_count = words_count.reset_index().sort_values(by=["count"],ascending=False)
words_count.head()

输出:
在这里插入图片描述

# 词云
from wordcloud import WordCloud
import matplotlib.pyplot as plt
%matplotlib inline
import matplotlib
matplotlib.rcParams['figure.figsize'] = (10.0, 5.0)

wordcloud=WordCloud(font_path="./data/simhei.ttf",background_color="white",max_font_size=80)
word_frequence = {x[0]:x[1] for x in words_count.head(100).values}
wordcloud=wordcloud.fit_words(word_frequence)
plt.imshow(wordcloud)

输出:
在这里插入图片描述

3、 TF-IDF:整个文章关键词提取

import jieba.analyse
index = 2000
print(df_news['content'][index])
# 词之间相连接
content_S_str = "".join(content_S[index])
# topK=n表示提取n个关键词
print(" ".join(jieba.analyse.extract_tags(content_S_str, topK=5, withWeight=False)))

输出:
6月24日,是梅西25岁的生日。《世界体育报》特地为梅西提前做了个专题,梅西手持一件印有他姓氏和25号号码的巴塞罗那球衣,跳蚤提前许下了生日愿望。!拔颐窍氯季的目标,和之前永远相同,那就是踢出漂亮的足球,并且赢得尽可能多的冠军奖杯。”梅西许愿,“如果能再次赢得西甲和欧冠冠军的话,那会非常美妙,我们将会努力再给球迷带来一次双冠王的喜悦。下赛季我的儿子将会出生,对于我来说,这将是一个特殊的赛季。我希望,下赛季对于巴萨而言也会是一个特殊的赛季。”6杂诎腿,梅西永远感激于心:“我永远感激巴萨为我所做的一切,我的病曾经需要巨额治疗资金,巴萨照顾好了我生活的方方面面,巴萨给了我踢足球的机会。这太美妙了,因为巴萨让我梦想成真。”<唇25岁的梅西,一共为巴萨出场329次,跳蚤打进253球,并且已经连续拿到了3个金球奖杯。在团队荣誉方面,梅西代表巴萨和阿根廷国青队拿到了21个冠军头衔。在个人荣誉方面,梅西也拿到了13个奖项,其中包括3个金球奖、1个世界足球先生奖项,2个欧洲金靴奖、2个西甲金靴奖、4个欧冠金靴和1个世青赛金靴。除了世界杯和美洲杯外,梅西拿到了能拿的一切荣誉。在25岁的年龄段上,梅西的成就已经超越了贝利、克鲁伊夫、马拉多纳和迪斯蒂法诺这四大球王。#玻邓甑谋蠢虽然拿到了世界杯冠军,但总奖杯数仅为18个,比梅西少3个。在个人荣誉方面,贝利在国家队只拿了1959年美洲杯金靴。贝利的绝大多数个人荣誉,都是他在巴西国内联赛或者州内部联赛的金靴。25岁的克鲁伊夫拿到了8个冠军和2个个人奖项,25岁的马拉多纳拿到了5个冠军和6个个人奖项,25岁的迪斯蒂法诺拿到了4个冠军和2个个人奖项。无论比团队荣誉还是个人奖项,梅西都是这一年龄段的史上最佳。
梅西 巴萨 拿到 奖项 冠军

4、 LDA:主题模型

主题包含什么词,比如娱乐类新闻包含哪些关键词,所起到的重要程度是多少。格式要求:list of list形式,分词好的的整个语料(相当于是每一条新闻都是分词好的list,然后整合所有新闻都是分词好的list)

from gensim import corpora,models,similarities
import gensim
#做映射,相当于词袋。比如词语“今天”用1代表,‘明天“用2代表
dictionary = corpora.Dictionary(contents_clean)
corpus = [dictionary.doc2bow(sentence) for sentence in contents_clean]
lda = gensim.models.ldamodel.LdaModel(corpus=corpus, id2word=dictionary, num_topics=20) #类似Kmeans自己指定K值,20表示20个主题
# 表示第一类分类主题,找出其中最具代表性的5个词
print(lda.print_topic(1, topn=5))

输出:
0.004*“万” + 0.004*“纹身” + 0.003*“中” + 0.003*“M” + 0.003*“J”

# 打印20种分类主题,找出其中最具代表性的5个词
for topic in lda.print_topics(num_topics=20,num_words=5):
    print(topic[1])

输出:

0.006*"女人" + 0.006*"中" + 0.005*"男人" + 0.005*"说" + 0.004*"性感"
0.004*"万" + 0.004*"纹身" + 0.003*"中" + 0.003*"M" + 0.003*"J"
0.005*"中" + 0.004*"学校" + 0.004*"食物" + 0.003*"学生" + 0.003*"导师"
0.006*"中" + 0.005*"天籁" + 0.003*"女主角" + 0.003*"C" + 0.003*"号"
0.030*"a" + 0.030*"e" + 0.023*"o" + 0.022*"i" + 0.022*"n"
0.004*"中" + 0.003*"祝福" + 0.003*"性爱" + 0.003*"M" + 0.003*"短发"
....

5、基于贝叶斯算法进行新闻分类

(1)按分类展示

df_train = pd.DataFrame({'contents_clean':contents_clean,'label':df_news['category']})
df_train.tail()

输出:
在这里插入图片描述
(2)展示所有标签

df_train.label.unique()

输出:
array([‘汽车’, ‘财经’, ‘科技’, ‘健康’, ‘体育’, ‘教育’, ‘文化’, ‘军事’, ‘娱乐’, ‘时尚’], dtype=object)
(3)用数字代表标签

label_mapping = {"汽车": 1, "财经": 2, "科技": 3, "健康": 4, "体育":5, "教育": 6,"文化": 7,"军事": 8,"娱乐": 9,"时尚": 0}
df_train['label'] = df_train['label'].map(label_mapping)
df_train.head()

输出:
在这里插入图片描述
(3)切分数据,在训练集上训练

# 切分数据
from sklearn.model_selection import train_test_split
x_train, x_test, y_train,y_test = train_test_split(df_train['contents_clean'].values,df_train['label'].values,random_state=1)
x_train[0][1]

输出:
‘上海’

words = []
for line_index in range(len(x_train)):
    try:
        #x_train[line_index][word_index] = str(x_train[line_index][word_index])
        words.append(' '.join(x_train[line_index]))
    except:
        print (line_index,word_index)
words[0] 

输出:

‘中新网 上海 日电 于俊 父亲节 网络 吃 一顿 电影 快餐 微 电影 爸 对不起 我爱你 定于 本月 父亲节 当天 各大 视频 网站 首映 葜 谱 鞣 剑 保慈 障蚣 钦 呓 樯 埽 ⒌ 缬 埃 ǎ 停 椋 悖 颍 铩 妫 椋 恚 称 微型 电影 新 媒体 平台 播放 状态 短时 休闲 状态 观看 完整 策划 系统 制作 体系 支持 显示 较完整 故事情节 电影 微 超短 放映 微 周期 制作 天 数周 微 规模 投资 人民币 几千 数万元 每部 内容 融合 幽默 搞怪 时尚 潮流 人文 言情 公益 教育 商业 定制 主题 单独 成篇 系列 成剧 唇 开播 微 电影 爸 对不起 我爱你 讲述 一对 父子 观念 缺少 沟通 导致 关系 父亲 传统 固执 钟情 传统 生活 方式 儿子 新派 音乐 达 习惯 晚出 早 生活 性格 张扬 叛逆 两种 截然不同 生活 方式 理念 差异 一场 父子 间 拉开序幕 子 失手 打破 父亲 心爱 物品 父亲 赶出 家门 剧情 演绎 父亲节 妹妹 哥哥 化解 父亲 这场 矛盾 映逋坏 嚼 斫 狻 ⒍ 粤 ⒌ 桨容 争执 退让 传统 尴尬 父子 尴尬 情 男人 表达 心中 那份 感恩 一杯 滤挂 咖啡 父亲节 变得 温馨 镁 缬 缮 虾 N 逄 煳 幕 传播 迪欧 咖啡 联合 出品 出品人 希望 观摩 扪心自问 父亲节 父亲 记得 父亲 生日 哪一天 父亲 爱喝 跨出 家门 那一刻 感觉 一颗 颤动 心 操劳 天下 儿女 父亲节 大声 喊出 父亲 家人 爱 完’

知识点补充:分词向量化,计算词频
方案一:

from sklearn.feature_extraction.text import CountVectorizer
texts = ["dog cat fish","dog cat cat","fish bird","bird"]
cv = CountVectorizer()
cv_fit = cv.fit_transform(texts)
# 提取出词语
print(cv.get_feature_names())
print(cv_fit.toarray())
print(cv_fit.toarray().sum(axis=0))

输出:

['bird', 'cat', 'dog', 'fish']
[[0 1 1 1]
 [0 2 1 0]
 [1 0 0 1]
 [1 0 0 0]]
[2 3 2 2]
几个词之间进行组合

方案二:

from sklearn.feature_extraction.text import CountVectorizer
texts = ["dog cat fish","dog cat cat","fish bird","bird"]
# 几个词之间进行组合
cv = CountVectorizer(ngram_range=(1,4))
cv_fit = cv.fit_transform(texts)
# 提取出词语
print(cv.get_feature_names())
print(cv_fit.toarray())
print(cv_fit.toarray().sum(axis=0))

输出:

['bird', 'cat', 'cat cat', 'cat fish', 'dog', 'dog cat', 'dog cat cat', 'dog cat fish', 'fish', 'fish bird']
[[0 1 0 1 1 1 0 1 1 0]
 [0 2 1 0 1 1 1 0 0 0]
 [1 0 0 0 0 0 0 0 1 1]
 [1 0 0 0 0 0 0 0 0 0]]
[2 3 1 1 2 2 1 1 2 1]

(4)计算词频(TF)

from sklearn.feature_extraction.text import CountVectorizer
CountVectorizer会将文本中的词语转换为词频矩阵,它通过fit_transform函数计算各个词语出现的次数。
vec = CountVectorizer(analyzer = 'word', max_features=400,lowercase=False)
vec.fit(words)

输出:参数

CountVectorizer(analyzer='word', binary=False, decode_error='strict',
        dtype=<class 'numpy.int64'>, encoding='utf-8', input='content',
        lowercase=False, max_df=1.0, max_features=400, min_df=1,
        ngram_range=(1, 1), preprocessor=None, stop_words=None,
        strip_accents=None, token_pattern='(?u)\\b\\w\\w+\\b',
        tokenizer=None, vocabulary=None)

1)引入贝叶斯

from sklearn.naive_bayes import MultinomialNB
classifier = MultinomialNB()
classifier.fit(vec.transform(words), y_train)

输出:

MultinomialNB(alpha=1.0, class_prior=None, fit_prior=True)

2)在测试集上验证

test_words = []
for line_index in range(len(x_test)):
    try:
        test_words.append(' '.join(x_test[line_index]))
    except:
        print(line_index,word_index)
test_words[0]

输出:
‘国家 公务员 考试 申论 应用文 类 试题 实质 一道 集 概括 分析 提出 解决问题 一体 综合性 试题 说 一道 客观 凝练 申发 论述 文章 题目 分析 历年 国考 申论 真题 公文 类 试题 类型 多样 包括 公文 类 事务性 文书 类 题材 从题 干 作答 材料 内容 整合 分析 无需 太 创造性 发挥 纵观 历年 申论 真题 作答 应用文 类 试题 文种 格式 作出 特别 重在 内容 考查 行文 格式 考生 平常心 面对 应用文 类 试题 准确 把握 作答 领会 内在 含义 把握 题材 主旨 材料 结构 轻松 应对 应用文 类 试题 R 弧 ⒆ 钒 盐 展文 写作 原则 T 材料 中来 应用文 类 试题 材料 总体 把握 客观 考生 材料 中来 材料 中 把握 材料 准确 理解 题材 主旨 T 政府 角度 作答 应用文 类 试题 更应 注重 政府 角度 观点 政府 角度 出发 原则 表述 观点 提出 解决 之策 考生 作答 站 政府 人员 角度 看待 提出 解决问题 T 文体 结构 形式 考查 重点 文体 结构 大部分 评分 关键点 解答 方法 薄 ⒆ ス 丶 词 明 方向 作答 题目 题干 作答 作答 方向 作答 角度 关键 向导 考生 仔细阅读 题干 作答 抓住 关键词 作答 方向 相关 要点 整理 作答 思路 年国考 地市级 真 题为 例 潦惺姓 府 宣传 推进 近海 水域 污染 整治 工作 请 给定 资料 市政府 工作人员 身份 草拟 一份 宣传 纲要 R 求 保对 宣传 内容 要点 提纲挈领 陈述 玻 体现 政府 精神 全市 各界 关心 支持 污染 整治 工作 通俗易懂 超过 字 肮 丶 词 近海 水域 污染 整治 工作 市政府 工作人员 身份 宣传 纲要 提纲挈领 陈述 体现 政府 精神 全市 各界 关心 支持 污染 整治 工作 通俗易懂 提示 归结 作答 要点 包括 污染 情况 原因 解决 对策 作答 思路 情况 原因 对策 意义 逻辑 顺序 安排 文章 结构 病 ⒋ 缶殖 龇 ⅲ 明 结构 解答 应用文 类 试题 考生 材料 整体 出发 大局 出发 高屋建瓴 把握 材料 主题 思想 事件 起因 解决 对策 阅读文章 构建 文章 结构 直至 快速 解答 场 ⒗ 硭 乘悸 罚明 逻辑 应用文 类 试题 严密 逻辑思维 情况 原因 对策 意义 考生 作答 先 弄清楚 解答 思路 统筹安排 脉络 清晰 逻辑 表达 内容 表述 础 把握 明 详略 考生 仔细阅读 分析 揣摩 应用文 类 试题 内容 答题 时要 详略 得当 主次 分明 安排 内容 增加 文章 层次感 阅卷 老师 阅卷 时能 明白 清晰 一目了然 玻埃 保蹦旯 考 考试 申论 试卷 分为 省级 地市级 两套 试卷 能力 大有 省级 申论 试题 考生 宏观 角度看 注重 深度 广度 考生 深谋远虑 地市级 试题 考生 微观 视角 观察 侧重 考查 解决 能力 考生 贯彻执行 作答 区别对待’

3) 预测结果值

classifier.score(vec.transform(test_words), y_test)

输出:
0.7248
(5)计算TF-DF

from sklearn.feature_extraction.text import TfidfVectorizer

vectorizer = TfidfVectorizer(analyzer='word', max_features=4000,  lowercase = False)
vectorizer.fit(words)

输出:

TfidfVectorizer(analyzer='word', binary=False, decode_error='strict',
        dtype=<class 'numpy.int64'>, encoding='utf-8', input='content',
        lowercase=False, max_df=1.0, max_features=4000, min_df=1,
        ngram_range=(1, 1), norm='l2', preprocessor=None, smooth_idf=True,
        stop_words=None, strip_accents=None, sublinear_tf=False,
        token_pattern='(?u)\\b\\w\\w+\\b', tokenizer=None, use_idf=True,
        vocabulary=None)

1)在训练集上训练贝叶斯

from sklearn.naive_bayes import MultinomialNB
classifier = MultinomialNB()
classifier.fit(vectorizer.transform(words), y_train)

输出:

MultinomialNB(alpha=1.0, class_prior=None, fit_prior=True)

2)在测试集上验证

classifier.score(vectorizer.transform(test_words), y_test)

输出:
0.81520000000000004

  • 0
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值