新闻分类任务(LDA模型,多项分布朴素贝叶斯)

新闻分类任务

1.利用gensim建立LDA模型将文本进行主题分类

2.利用多项分布朴素贝叶斯将文本进行分类

数据来源:http://www.sogou.com/labs/resource/list_pingce.php
import jieba
import pandas as pd
import numpy as np

读取文本:将新闻文本转换为dataframe

df_news=pd.read_table('val.txt',names=['category','theme','URL','content'],encoding='utf-8')
df_news=df_news.dropna() # 删去有缺失值的样本
df_news.head()
categorythemeURLcontent
0汽车新辉腾 4.2 V8 4座加长Individual版2011款 最新报价http://auto.data.people.com.cn/model_15782/经销商 电话 试驾/订车U憬杭州滨江区江陵路1780号4008-112233转5864#保常...
1汽车918 Spyder概念车http://auto.data.people.com.cn/prdview_165423....呼叫热线 4008-100-300 服务邮箱 kf@peopledaily.com.cn
2汽车日内瓦亮相 MINI性能版/概念车-1.6T引擎http://auto.data.people.com.cn/news/story_5249...MINI品牌在二月曾经公布了最新的MINI新概念车Clubvan效果图,不过现在在日内瓦车展...
3汽车清仓大甩卖一汽夏利N5威志V2低至3.39万http://auto.data.people.com.cn/news/story_6144...清仓大甩卖!一汽夏利N5、威志V2低至3.39万=日,启新中国一汽强势推出一汽夏利N5、威志...
4汽车大众敞篷家族新成员 高尔夫敞篷版实拍http://auto.data.people.com.cn/news/story_5686...在今年3月的日内瓦车展上,我们见到了高尔夫家族的新成员,高尔夫敞篷版,这款全新敞篷车受到了众...
df_news.shape
(5000, 4)

分词:使用结巴分词器将每条新闻都分成单词

content=df_news.content.values.tolist() # 将每条新闻内容组成列表
print(content[1000])
阿里巴巴集团昨日宣布,将在集团管理层面设立首席数据官岗位(Chief Data Officer),阿里巴巴B2B公司CEO陆兆禧将会出任上述职务,向集团CEO马云直接汇报。>菹ぃ和6月初的首席风险官职务任命相同,首席数据官亦为阿里巴巴集团在完成与雅虎股权谈判,推进“one company”目标后,在集团决策层面新增的管理岗位。0⒗锛团昨日表示,“变成一家真正意义上的数据公司”已是战略共识。记者刘夏
content_S=[]
# 将每条新闻内容都进行分词,并将每条新闻的词作为一个元素传入列表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转化为一个dataframe
df_content=pd.DataFrame({'content_S':content_S})
df_content.head()
content_S
0[经销商,  , 电话,  , 试驾, /, 订车, U, 憬, 杭州, 滨江区, 江陵, ...
1[呼叫, 热线,  , 4, 0, 0, 8, -, 1, 0, 0, -, 3, 0, 0...
2[M, I, N, I, 品牌, 在, 二月, 曾经, 公布, 了, 最新, 的, M, I...
3[清仓, 大, 甩卖, !, 一汽, 夏利, N, 5, 、, 威志, V, 2, 低至, ...
4[在, 今年, 3, 月, 的, 日内瓦, 车展, 上, ,, 我们, 见到, 了, 高尔夫...

文本处理:剔除文本中的停用词

# 创建一个停词表的dataframe
stopwords=pd.read_csv('stopwords.txt',encoding='utf-8',sep='\t',quoting=3,index_col=False,names=['stopword'])
stopwords.head()
stopword
0!
1"
2#
3$
4%
'''
将每条新闻中非停词表中的词传入line_clean,并将其作为每个元素传入content_clean
将所有新闻中非停词表中的词传入all_words,
''' 
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()
contents_clean
0[经销商, 电话, 试驾, 订车, U, 憬, 杭州, 滨江区, 江陵, 路, 号, 转, ...
1[呼叫, 热线, 服务, 邮箱, k, f, p, e, o, p, l, e, d, a,...
2[M, I, N, I, 品牌, 二月, 公布, 最新, M, I, N, I, 新, 概念...
3[清仓, 甩卖, 一汽, 夏利, N, 威志, V, 低至, 万, 启新, 中国, 一汽, ...
4[日内瓦, 车展, 见到, 高尔夫, 家族, 新, 成员, 高尔夫, 敞篷版, 款, 全新,...

观察:文本中每种词的词频

df_all_words=pd.DataFrame({'all_words':all_words})
df_all_words.head()
all_words
0经销商
1电话
2试驾
3订车
4
words_count=pd.DataFrame(df_all_words['all_words'].value_counts()).reset_index()
                                                                   # 还原初始索引
words_count.columns=['alle_words','counts']
# 将每种词的词频总结一个dataframe
words_count.head()
alle_wordscounts
05199
1中国3115
23055
32646
42390

TF-IDF:提取关键词

TF-IDF用于评估一个字词对于语料库中一个文本的重要程度。
TF(词频)=在某一类文本中词条出现的次数/该类中所有词条数目
IDF(逆文本频率)=log(语料库中文本总数)/(包含该词条的文本数+1)
TF-IDF=TF*IDF

import jieba.analyse

index=2400
print(df_news['content'][index])
content_S_str="".join(content_S[index]) # 将content_S中每条新闻的词库连接成字符串
# 返回TF/IDF 权重最大的5个关键词
print("")
print("关键词: "," ".join(jieba.analyse.extract_tags(content_S_str,topK=5,withWeight=False)))
法国VS西班牙、里贝里VS哈维,北京时间6月24日凌晨一场的大战举世瞩目,而这场胜利不仅仅关乎两支顶级强队的命运,同时也是他们背后的球衣赞助商耐克和阿迪达斯之间的一次角逐。T谌胙”窘炫分薇的16支球队之中,阿迪达斯和耐克的势力范围也是几乎旗鼓相当:其中有5家球衣由耐克提供,而阿迪达斯则赞助了6家,此外茵宝有3家,而剩下的两家则由彪马赞助。而当比赛进行到现在,率先挺进四强的两支球队分别被耐克支持的葡萄牙和阿迪达斯支持的德国占据,而由于最后一场1/4决赛是茵宝(英格兰)和彪马(意大利)的对决,这也意味着明天凌晨西班牙同法国这场阿迪达斯和耐克在1/4决赛的唯一一次直接交手将直接决定两家体育巨头在此次欧洲杯上的胜负。8据评估,在2012年足球商品的销售额能总共超过40亿欧元,而单单是不足一个月的欧洲杯就有高达5亿的销售额,也就是说在欧洲杯期间将有700万件球衣被抢购一空。根据市场评估,两大巨头阿迪达斯和耐克的市场占有率也是并驾齐驱,其中前者占据38%,而后者占据36%。体育权利顾问奥利弗-米歇尔在接受《队报》采访时说:“欧洲杯是耐克通过法国翻身的一个绝佳机会!”C仔尔接着谈到两大赞助商的经营策略:“竞技体育的成功会燃起球衣购买的热情,不过即便是水平相当,不同国家之间的欧洲杯效应却存在不同。在德国就很出色,大约1/4的德国人通过电视观看了比赛,而在西班牙效果则差很多,由于民族主义高涨的加泰罗尼亚地区只关注巴萨和巴萨的球衣,他们对西班牙国家队根本没什么兴趣。”因此尽管西班牙接连拿下欧洲杯和世界杯,但是阿迪达斯只为西班牙足协支付每年2600万的赞助费#相比之下尽管最近两届大赛表现糟糕法国足协将从耐克手中每年可以得到4000万欧元。米歇尔解释道:“法国创纪录的4000万欧元赞助费得益于阿迪达斯和耐克竞逐未来15年欧洲市场的竞争。耐克需要笼络一个大国来打赢这场欧洲大陆的战争,而尽管德国拿到的赞助费并不太高,但是他们却显然牢牢掌握在民族品牌阿迪达斯手中。从长期投资来看,耐克给法国的赞助并不算过高。”

关键词:  耐克 阿迪达斯 欧洲杯 球衣 西班牙

LDA:主题模型

LDA主题模型是一种文档生成模型,是一种非监督机器学习技术。它认为一篇文档是有多个主题的,而每个主题又对应着不同的词。一篇文档的构造过程,首先是以一定的概率选择某个主题,然后再在这个主题下以一定的概率选出某一个词,这样就生成了这篇文档的第一个词。不断重复这个过程,就生成了整篇文章(当然这里假定词与词之间是没有顺序的,即所有词无序的堆放在一个大袋子中,称之为词袋,这种方式可以使算法相对简化一些)。

LDA的使用是上述文档生成过程的逆过程,即根据一篇得到的文档,去寻找出这篇文档的主题,以及这些主题所对应的词。

# 导入一个自然语言处理的库gensim,需要传入list of list的结构
from gensim import corpora,models,similarities 

# 将新闻词库中每个词都分配一个id
dictionary=corpora.Dictionary(contents_clean)

# 创建一个词袋向量,形如:[[(a11,b1),...,(a1n,b1n)],..,[(ann),..,(bnn)]]
                         # a表示单个词id,b表示在此文本中出现次数
corpus=[dictionary.doc2bow(sentence) for sentence in contents_clean]
# 建立一个lda模型
lda=models.LdaModel(corpus=corpus,id2word=dictionary,num_topics=20)
                  # 传入词袋      传入词典           分成20个主题
print(lda.print_topic(0,topn=5)) # 打印第一个主题用5个词表示
# 每个词前面是权重
0.020*"男人" + 0.008*"女人" + 0.005*"中" + 0.003*"吃" + 0.003*"比赛"
# 打印20个主题
for topic in lda.print_topics(num_topics=20,num_words=5):
    print(topic[1])
0.020*"男人" + 0.008*"女人" + 0.005*"中" + 0.003*"吃" + 0.003*"比赛"
0.004*"中" + 0.004*"D" + 0.003*"作品" + 0.003*"考试" + 0.003*"中国"
0.013*"万" + 0.010*"号" + 0.008*"考生" + 0.005*"转" + 0.003*"米"
0.006*"中" + 0.005*"比赛" + 0.004*"节目" + 0.004*"说" + 0.004*"中国"
0.012*"电影" + 0.008*"影片" + 0.007*"导演" + 0.006*"中" + 0.005*"主演"
0.004*"志愿" + 0.004*"中国" + 0.004*"说" + 0.004*"中" + 0.002*"发展"
0.011*"a" + 0.006*"e" + 0.006*"n" + 0.006*"s" + 0.005*"o"
0.005*"电影" + 0.005*"中" + 0.004*"中国" + 0.004*"导演" + 0.003*"文化"
0.008*"球队" + 0.007*"中" + 0.005*"选手" + 0.005*"中国" + 0.004*"T"
0.007*"中" + 0.004*"说" + 0.003*"中国" + 0.003*"老师" + 0.002*"高考"
0.007*"中国" + 0.004*"中" + 0.003*"奢侈品" + 0.003*"S" + 0.003*"P"
0.004*"中" + 0.004*"W" + 0.004*"邱" + 0.004*"女性" + 0.004*"a"
0.009*"M" + 0.008*"n" + 0.007*"e" + 0.007*"i" + 0.006*"a"
0.005*"中国" + 0.004*"观众" + 0.004*"队" + 0.003*"北京" + 0.003*"性感"
0.006*"中" + 0.005*"观众" + 0.003*"创作" + 0.003*"学生" + 0.003*"中国"
0.008*"S" + 0.005*"M" + 0.004*"音乐" + 0.004*"V" + 0.004*"C"
0.006*"皮肤" + 0.004*"肌肤" + 0.004*"撒" + 0.003*"L" + 0.003*"贝宁"
0.008*"说" + 0.007*"中" + 0.004*"爱" + 0.004*"饰演" + 0.003*"麽"
0.024*"e" + 0.020*"a" + 0.019*"o" + 0.017*"i" + 0.014*"n"
0.006*"官兵" + 0.005*"比赛" + 0.005*"爆料" + 0.005*"部队" + 0.004*"中"

分类:多项分布朴素贝叶斯

在多项朴素贝叶斯模型中,特征X为离散变量,并且假定服从多项分布,可用于文本分类。
设某文档T=(t1,t2…tk…),tk为在文档中出现过的词,可重复
则:
先验概率:P©=类c下的总词数/整个训练集的总词数
类条件概率:(类c下单词tk在各个文档中出现过的次数之和+1)/(类c下单词总数+|V|)
注:V是训练样本的单词表(即抽取单词,单词出现多次,只算一个),|V|则表示训练样本包含多少种单词。

df_train=pd.DataFrame({'contents_clean':contents_clean,'label':df_news['category']})
df_train.head()
contents_cleanlabel
0[经销商, 电话, 试驾, 订车, U, 憬, 杭州, 滨江区, 江陵, 路, 号, 转, ...汽车
1[呼叫, 热线, 服务, 邮箱, k, f, p, e, o, p, l, e, d, a,...汽车
2[M, I, N, I, 品牌, 二月, 公布, 最新, M, I, N, I, 新, 概念...汽车
3[清仓, 甩卖, 一汽, 夏利, N, 威志, V, 低至, 万, 启新, 中国, 一汽, ...汽车
4[日内瓦, 车展, 见到, 高尔夫, 家族, 新, 成员, 高尔夫, 敞篷版, 款, 全新,...汽车
# 打印出数据集的分类
df_train.label.unique()
array(['汽车', '财经', '科技', '健康', '体育', '教育', '文化', '军事', '娱乐', '时尚'],
      dtype=object)
# 将类别做一个映射
i=0
label_mapping={}
for value in df_train.label.unique():
    i+=1
    label_mapping[value]=i
print(label_mapping)

# 将label映射放入dataframe,也就是将label值用数值代替
df_train['label']=df_train['label'].map(label_mapping)
df_train.head()
{'汽车': 1, '财经': 2, '科技': 3, '健康': 4, '体育': 5, '教育': 6, '文化': 7, '军事': 8, '娱乐': 9, '时尚': 10}
contents_cleanlabel
0[经销商, 电话, 试驾, 订车, U, 憬, 杭州, 滨江区, 江陵, 路, 号, 转, ...1
1[呼叫, 热线, 服务, 邮箱, k, f, p, e, o, p, l, e, d, a,...1
2[M, I, N, I, 品牌, 二月, 公布, 最新, M, I, N, I, 新, 概念...1
3[清仓, 甩卖, 一汽, 夏利, N, 威志, V, 低至, 万, 启新, 中国, 一汽, ...1
4[日内瓦, 车展, 见到, 高尔夫, 家族, 新, 成员, 高尔夫, 敞篷版, 款, 全新,...1
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:
        words.append(' '.join(x_train[line_index]))
    except:
        print(line_index,word_index)
words[0]
'中新网 上海 日电 于俊 父亲节 网络 吃 一顿 电影 快餐 微 电影 爸 对不起 我爱你 定于 本月 父亲节 当天 各大 视频 网站 首映 葜 谱 鞣 剑 保慈 障蚣 钦 呓 樯 埽 ⒌ 缬 埃 ǎ 停 椋 悖 颍 铩 妫 椋 恚 称 微型 电影 新 媒体 平台 播放 状态 短时 休闲 状态 观看 完整 策划 系统 制作 体系 支持 显示 较完整 故事情节 电影 微 超短 放映 微 周期 制作 天 数周 微 规模 投资 人民币 几千 数万元 每部 内容 融合 幽默 搞怪 时尚 潮流 人文 言情 公益 教育 商业 定制 主题 单独 成篇 系列 成剧 唇 开播 微 电影 爸 对不起 我爱你 讲述 一对 父子 观念 缺少 沟通 导致 关系 父亲 传统 固执 钟情 传统 生活 方式 儿子 新派 音乐 达 习惯 晚出 早 生活 性格 张扬 叛逆 两种 截然不同 生活 方式 理念 差异 一场 父子 间 拉开序幕 子 失手 打破 父亲 心爱 物品 父亲 赶出 家门 剧情 演绎 父亲节 妹妹 哥哥 化解 父亲 这场 矛盾 映逋坏 嚼 斫 狻 ⒍ 粤 ⒌ 桨容 争执 退让 传统 尴尬 父子 尴尬 情 男人 表达 心中 那份 感恩 一杯 滤挂 咖啡 父亲节 变得 温馨 镁 缬 缮 虾 N 逄 煳 幕 传播 迪欧 咖啡 联合 出品 出品人 希望 观摩 扪心自问 父亲节 父亲 记得 父亲 生日 哪一天 父亲 爱喝 跨出 家门 那一刻 感觉 一颗 颤动 心 操劳 天下 儿女 父亲节 大声 喊出 父亲 家人 爱 完'
print(len(words))
3750
# 构造一个文本向量的训练集
from sklearn.feature_extraction.text import CountVectorizer

vec=CountVectorizer(max_features=4000,lowercase=False)
vec.fit(words)
words_train=vec.transform(words)
# 利用建立多项分布朴素贝叶斯模型
from sklearn.naive_bayes import MultinomialNB
classifier=MultinomialNB()
classifier.fit(words_train,y_train)
MultinomialNB(alpha=1.0, class_prior=None, fit_prior=True)
# 将测试集数据转化为['string',..,'string']形式
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 求 保对 宣传 内容 要点 提纲挈领 陈述 玻 体现 政府 精神 全市 各界 关心 支持 污染 整治 工作 通俗易懂 超过 字 肮 丶 词 近海 水域 污染 整治 工作 市政府 工作人员 身份 宣传 纲要 提纲挈领 陈述 体现 政府 精神 全市 各界 关心 支持 污染 整治 工作 通俗易懂 提示 归结 作答 要点 包括 污染 情况 原因 解决 对策 作答 思路 情况 原因 对策 意义 逻辑 顺序 安排 文章 结构 病 ⒋ 缶殖 龇 ⅲ 明 结构 解答 应用文 类 试题 考生 材料 整体 出发 大局 出发 高屋建瓴 把握 材料 主题 思想 事件 起因 解决 对策 阅读文章 构建 文章 结构 直至 快速 解答 场 ⒗ 硭 乘悸 罚明 逻辑 应用文 类 试题 严密 逻辑思维 情况 原因 对策 意义 考生 作答 先 弄清楚 解答 思路 统筹安排 脉络 清晰 逻辑 表达 内容 表述 础 把握 明 详略 考生 仔细阅读 分析 揣摩 应用文 类 试题 内容 答题 时要 详略 得当 主次 分明 安排 内容 增加 文章 层次感 阅卷 老师 阅卷 时能 明白 清晰 一目了然 玻埃 保蹦旯 考 考试 申论 试卷 分为 省级 地市级 两套 试卷 能力 大有 省级 申论 试题 考生 宏观 角度看 注重 深度 广度 考生 深谋远虑 地市级 试题 考生 微观 视角 观察 侧重 考查 解决 能力 考生 贯彻执行 作答 区别对待'
# 学习原始文档中所有标记的词汇表,并将测试集转换为文本向量
words_test=vec.transform(test_words)
classifier.score(words_test,y_test) # 返回分类的准确率
0.8088
# 从文本特征提取库中导出tf-idf特征矩阵转换模块
from sklearn.feature_extraction.text import TfidfVectorizer

vectorizer=TfidfVectorizer(analyzer='word',max_features=4000,lowercase=False)
vectorizer.fit(words) # 从原始文本中学习tf和idf
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)
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)
# 返回分类的平均准确率
classifier.score(vectorizer.transform(test_words),y_test)
0.8152
  • 3
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值