【文本处理与分类】使用cnews新闻数据集进行文本分类(包含分词、词云、文本关键词提取等)


数据集下载: 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)#显示新闻文件的后一个

categorycontent
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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

智能建造小硕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值