文章目录
数据集下载: https://download.csdn.net/download/QH2107/87613715
或者公众号【智能建造小硕】回复“cnew”获取

一:导入模块
import wordcloud#词云展示库
import numpy as np# numpy数据处理库
import pandas as pd
import jieba # 结巴分词
import jieba.analyse
from collections import Counter# 词频统计库
from PIL import Image # 图像处理库
import matplotlib.pyplot as plt # 图像展示库
from imageio import imread#图片读入
import pyttsx3#音频
from gensim import corpora,models,similarities
import gensim
from sklearn.model_selection import train_test_split#数据集划分
from sklearn.naive_bayes import MultinomialNB#贝叶斯分类器
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfVectorizer
二:数据的读入以及显示
import os
current_path = os.getcwd() #获取当前的路径
print(current_path)
#第一列类别,第二列文本
df_news=pd.read_table(r"..\cnews\cnews.val.txt",names=["category","content"],encoding="utf_8")
df_news=df_news.dropna()#有缺失的数据则删除
df_news.head()#显示新闻文件的前一个
#df_news.tail(1)#显示新闻文件的后一个
category | content | |
---|---|---|
0 | 体育 | 黄蜂vs湖人首发:科比带伤战保罗 加索尔救赎之战 新浪体育讯北京时间4月27日,NBA季后赛... |
1 | 体育 | 1.7秒神之一击救马刺王朝于危难 这个新秀有点牛!新浪体育讯在刚刚结束的比赛中,回到主场的马... |
2 | 体育 | 1人灭掘金!神般杜兰特! 他想要分的时候没人能挡新浪体育讯在NBA的世界里,真的猛男,敢于直... |
3 | 体育 | 韩国国奥20人名单:朴周永领衔 两世界杯国脚入选新浪体育讯据韩联社首尔9月17日电 韩国国奥... |
4 | 体育 | 天才中锋崇拜王治郅 周琦:球员最终是靠实力说话2月14日从土耳其男篮邀请赛回到北京之后,周琦... |
df_news.content.shape#数据的总量
(5000,)
#df_news["category"].value_counts()
df_news.category.unique()#数据的类别
array(['体育', '娱乐', '家居', '房产', '教育', '时尚', '时政', '游戏', '科技', '财经'],
dtype=object)
把新闻文件的内容转化成list格式
content_list=df_news.content.values.tolist()
content_list[0:1]
['黄蜂vs湖人首发:科比带伤战保罗 加索尔救赎之战 新浪体育讯北京时间4月27日,NBA季后赛首轮洛杉矶湖人主场迎战新奥尔良黄蜂,此前的比赛中,双方战成2-2平,因此本场比赛对于两支球队来说都非常重要,赛前双方也公布了首发阵容:湖人队:费舍尔、科比、阿泰斯特、加索尔、拜纳姆黄蜂队:保罗、贝里内利、阿里扎、兰德里、奥卡福[新浪NBA官方微博][新浪NBA湖人新闻动态微博][新浪NBA专题][黄蜂vs湖人图文直播室](新浪体育)']
三:给新闻文本分词
将【文本集】生成【分词列表】
使用jieba.cut函数
content_fenci = []#建立一个空的
for line in content_list:
text = jieba.lcut(line)#给每一条都分词
if len(text) > 1 and text != '\r': #换行
content_fenci.append(text)#分词后的结果放入
content_fenci[0:1] #分词后的三个样本
[['黄蜂',
'vs',
'湖人',
'首发',
':',
'科比',
'带伤',
'战',
'保罗',
' ',
'加索尔',
'救赎',
'之战',
' ',
'新浪',
'体育讯',
'北京',
'时间',
'4',
'月',
'27',
'日',
',',
'NBA',
'季后赛',
'首轮',
'洛杉矶',
'湖人',
'主场',
'迎战',
'新奥尔良',
'黄蜂',
',',
'此前',
'的',
'比赛',
'中',
',',
'双方',
'战成',
'2',
'-',
'2',
'平',
',',
'因此',
'本场',
'比赛',
'对于',
'两支',
'球队',
'来说',
'都',
'非常',
'重要',
',',
'赛前',
'双方',
'也',
'公布',
'了',
'首发',
'阵容',
':',
'湖人队',
':',
'费舍尔',
'、',
'科比',
'、',
'阿泰斯特',
'、',
'加索尔',
'、',
'拜纳姆',
'黄蜂队',
':',
'保罗',
'、',
'贝里',
'内利',
'、',
'阿里',
'扎',
'、',
'兰德',
'里',
'、',
'奥卡福',
'[',
'新浪',
'NBA',
'官方',
'微博',
']',
'[',
'新浪',
'NBA',
'湖人',
'新闻动态',
'微博',
']',
'[',
'新浪',
'NBA',
'专题',
']',
'[',
'黄蜂',
'vs',
'湖人',
'图文',
'直播室',
']',
'(',
'新浪',
'体育',
')']]
df_content=pd.DataFrame({'content':content_fenci})#分词后的数据格式转换成Datafram形式
df_content.head()
content | |
---|---|
0 | [黄蜂, vs, 湖人, 首发, :, 科比, 带伤, 战, 保罗, , 加索尔, 救赎,... |
1 | [1.7, 秒, 神, 之一, 击救, 马刺, 王朝, 于, 危难, , 这个, 新秀, ... |
2 | [1, 人灭, 掘金, !, 神般, 杜兰特, !, , 他, 想要, 分, 的, 时候,... |
3 | [韩国, 国奥, 20, 人, 名单, :, 朴周, 永, 领衔, , 两, 世界杯, 国... |
4 | [天才, 中锋, 崇拜, 王治郅, , 周琦, :, 球员, 最终, 是, 靠, 实力, ... |
四:去停用词,将文本中含有的停止词剔除
df_stopwords=pd.read_csv(r"..\cnews\stopwords.txt",index_col=False,sep="\t",quoting=3,names=['stopword'], encoding='GBK')#读取停用词
#当文本文件中带有英文双引号时,直接用pd.read_csv进行读取会导致行数减少,此时应该对read_csv设置参数quoting=3
#df_stopwords.head(10)
stopwords_list=df_stopwords.stopword.values.tolist()#把停用词表转化成list格式
stopwords_list[:]
['--',
'?',
'“',
'”',
'》',
'--',
'一',
'一下',
'一些',
'一切',
'一则',
'一天',
'一定',
'一方面',
'一旦',
'一时',
...]
采取遍历的方法,已经分词后新闻文本中出现了停用词中的单词则去掉。
def drop_stopwords(contents,stopwords):
content_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))
content_clean.append(line_clean)
return content_clean,all_words
content_clean,all_words = drop_stopwords(content_fenci,stopwords_list)
content_clean[0:1]
all_words[0:10]
['黄蜂', '湖人', '首发', '科比', '带伤', '战', '保罗', ' ', '加索尔', '救赎']
print(content_clean[0:1])
print(all_words[:10])
[['黄蜂', '湖人', '首发', '科比', '带伤', '战', '保罗', ' ', '加索尔', '救赎', '之战', ' ', '新浪', '体育讯', '北京', '时间', 'NBA', '季后赛', '首轮', '洛杉矶', '湖人', '主场', '迎战', '新奥尔良', '黄蜂', '此前', '比赛', '中', '战成', '平', '本场', '比赛', '两支', '球队', '赛前', '公布', '首发', '阵容', '湖人队', '费舍尔', '科比', '阿泰斯特', '加索尔', '拜纳姆', '黄蜂队', '保罗', '贝里', '内利', '阿里', '扎', '兰德', '里', '奥卡福', '新浪', 'NBA', '官方', '微博', '新浪', 'NBA', '湖人', '新闻动态', '微博', '新浪', 'NBA', '专题', '黄蜂', '湖人', '图文', '直播室', '新浪', '体育']]
['黄蜂', '湖人', '首发', '科比', '带伤', '战', '保罗', ' ', '加索尔', '救赎']
all_word=pd.DataFrame(all_words)
all_word.shape
(1299701, 1)
df_clean= pd.DataFrame({'contents_clean':content_clean})
df_clean.head()
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
contents_clean | |
---|---|
0 | [黄蜂, 湖人, 首发, 科比, 带伤, 战, 保罗, , 加索尔, 救赎, 之战, ,... |
1 | [1.7, 神, 击救, 马刺, 王朝, 危难, , 新秀, 牛, 新浪, 体育讯, 刚刚... |
2 | [人灭, 掘金, 神般, 杜兰特, , 想要, 没人能, 挡, 新浪, 体育讯, NBA,... |
3 | [韩国, 国奥, 名单, 朴周, 永, 领衔, , 两, 世界杯, 国脚, 入选, 新浪,... |
4 | [天才, 中锋, 崇拜, 王治郅, , 周琦, 球员, 最终, 实力, 说话, 土耳其, ... |
五:统计词频方式
tf= Counter(all_words)
tf.most_common(500)#显示统计完之后的前500个词
[(' ', 84037),
('\xa0', 20021),
('基金', 9828),
('中', 7715),
('市场', 4436),
('中国', 3948),
('说', 3410),
('公司', 3304),
('新', 2579),
('企业', 2530),
('时间', 2502),
('考试', 2419),
('产品', 2416),
('元', 2291),
('投资', 2288),
('发展', 2286),
('做', 2225),
('北京', 2099),
...]
六:绘制词云
#生成词云
font = r'Dengl.ttf'#导入字体
wcd= wordcloud.WordCloud(font_path=font,background_color='white',max_words=200, max_font_size=80,random_state=30 )
#最大字体的大小80
#设置最大现实的字数 200
# 设置有多少种随机生成状态,即有多少种配色方案 30
wcd.generate_from_frequencies(tf)
plt.imshow(wcd) # 显示词云
plt.axis('off') # 关闭坐标轴
plt.show()
#导入背景图片后的词云
mask = imread('..\mask1.png')#读入图片
wc= wordcloud.WordCloud(font_path=font,mask=mask,background_color='white',scale=4)
#scale : 按照比例进行放大画布,如设置为4,则长和宽都是原来画布的2倍。
wc.generate_from_frequencies(tf)
plt.imshow(wc) # 显示词云
plt.axis('off') # 关闭坐标轴
plt.show()
wc.to_file('ciyun.jpg')#保存词云
七:基于TF-IDF的关键词提取
import jieba.analyse
index = 3 #文档中的第3篇新闻文本
# 词之间相连
content_S_str = "".join(content_clean[index])
print(content_list[index])
print('关键词:')
print(" ".join(jieba.analyse.extract_tags(content_S_str, topK=10, withWeight=False)))
韩国国奥20人名单:朴周永领衔 两世界杯国脚入选新浪体育讯据韩联社首尔9月17日电 韩国国奥队主教练洪明甫17日下午在位于首尔钟路区的足球会馆召开记者会,公布了参加2010年广州亚运会足球赛的国奥队20人名单。在2010年南非世界杯上立功的朴周永(25岁)和金正友(28岁)成功入选。亚运会男子足球赛规定参赛选手年龄不得超过23岁,但作为外卡每队最多可选用3名24岁以上的选手,而洪明补只选了朴周永和金正友两人。在苏格兰出场机会不多的寄诚庸也将参加亚运会。以下是广州亚运会国奥队名单:守门员:金承圭、李范荣;后卫:洪正好、金英权、金周永、张硕元、洪哲、尹锡英、申光勋、吴宰锡;中场:具子哲、寄诚庸、金正友、金民友、徐正镇、金甫炅、曹永哲;前锋:朴周永、朴喜成、池东元。(新体)
关键词:
亚运会 金正友 国奥队 朴周 2010 足球赛 名单 首尔 世界杯 入选
八:语音播报
import pyttsx3
voice=pyttsx3.init()
text = jieba.analyse.extract_tags(content_S_str, topK=6, withWeight=False)
voice.say(" ".join(text))
print("准备语音播报.....")
print(text)
voice.runAndWait() #开始读
准备语音播报.....
['亚运会', '金正友', '国奥队', '朴周', '2010', '足球赛']
九:LDA主题模型
隐含狄利克雷分布(Latent Dirichlet Allocation,LDA),是一种主题模型(topic model),它可以将文档集中每篇文档的主题按照概率分布的形式给出。
def create_LDA(content_clean):
#基于文本集建立【词典】,并获得词典特征数
dictionary = corpora.Dictionary(content_clean)
#基于词典,将【分词列表集】转换成【稀疏向量集】,称作【语料库】
dic = len(dictionary.token2id)
print('词典特征数:%d' % dic)
corpus = [dictionary.doc2bow(sentence) for sentence in content_clean]
lda = gensim.models.LdaModel(corpus=corpus, id2word = dictionary,num_topics = 10,passes=10)
#passes 训练几轮
print('-----------')
for topic in lda.print_topics(num_topics=10, num_words = 5):
print(topic[1])
create_LDA(content_clean)
词典特征数:100035
-----------
0.272*" " + 0.011*" " + 0.008*"阅读" + 0.007*"中" + 0.006*"时间"
0.012*"考试" + 0.007*" " + 0.006*"四六级" + 0.006*"中" + 0.005*"工作"
0.013*"活动" + 0.013*"玩家" + 0.010*"游戏" + 0.007*"中" + 0.007*"手机"
0.010*"中" + 0.009*"比赛" + 0.008*"说" + 0.005*"时间" + 0.005*"球队"
0.068*"基金" + 0.013*"公司" + 0.012*"投资" + 0.011*"市场" + 0.009*"中"
0.476*" " + 0.008*"a" + 0.004*"考生" + 0.004*"四六级" + 0.004*"I"
0.012*"电影" + 0.008*"影片" + 0.006*"导演" + 0.005*"游戏" + 0.005*"中"
0.015*"中国" + 0.012*"企业" + 0.012*"市场" + 0.009*"产品" + 0.008*"发展"
0.007*"应急" + 0.006*"百安居" + 0.005*"恒大" + 0.005*"欧派" + 0.003*"绿城"
0.033*" " + 0.010*"功能" + 0.010*"元" + 0.010*"像素" + 0.009*"拍摄"
十:贝叶斯分类模型两种
###数据集准备
#创建字典,X为内容, y为种类
df_train = pd.DataFrame({"content":content_fenci ,"label":df_news['category']})
#为了方便计算,把对应的label字符类型转换为数字
#映射类型(mapping)
#非空字典
label_mapping = {"体育": 0, "娱乐": 1, "家居": 2, "房产": 3, "教育":4, "时尚": 5,"时政": 6,"游戏": 7,"科技": 8,"财经": 9}
df_train['label'] = df_train['label'].map(label_mapping)
#df_train.head()
#之后将每个新闻信息转换成字符串形式。因为CountVectorizer 和 TfidfVectorizer的输入为字符串形式。
def create_words(data):
words = []
for index in range(len(data)):
try:
words.append( ' '.join(data[index]))
except Exception:
print(index)
return words
#把数据分成测试集和训练集
x_train,x_test,y_train,y_test = train_test_split(df_train['content'].values,df_train['label'].values,random_state=0)
#没有设置 random.seed(),每次取得的结果就不一样,
train_words = create_words(x_train)
test_words = create_words(x_test)
#第一种
#CountVectorizer是属于常见的特征数值计算类,是一个文本特征提取方法。
#对于每一个训练文本,它只考虑每种词汇在该训练文本中出现的频率。
vec = CountVectorizer(analyzer = 'word',max_features=4000,lowercase=False)
#max_feature表示的是最大的特征数
vec.fit(train_words)
#拟合模型,并返回文本矩阵
classifier = MultinomialNB()#多项式朴素贝叶斯
classifier.fit(vec.transform(train_words),y_train)
print("训练集准确率:",classifier.score(vec.transform(test_words), y_test))
训练集准确率: 0.9704
#第二种
#而TfidfVectorizer除了考量某一词汇在当前训练文本中出现的频率之外,
#同时关注包含这个词汇的其它训练文本数目的频率
vectorizer = TfidfVectorizer(analyzer='word',max_features = 40000,lowercase=False)
vectorizer.fit(train_words)
classifier = MultinomialNB()
classifier.fit(vectorizer.transform(train_words),y_train)#学习
print("模型准确率为:",classifier.score(vectorizer.transform(test_words), y_test))
模型准确率为: 0.976
参考资料:https://github.com/HuichuanLI/some_small_recommendation_alog