贝叶斯算法(新闻分类任务)

文章目录

  • 前言介绍
  • 一、新闻数据集处理
  • 二、文本分词(jibe分词器)
  • 三、去停用词
      • 停用词表是什么?
      • 使用停用词表过滤文件
  • 四、构建文本特征
    • 4.1)统计词频
    • 4.2)词云展示
    • 4.3)TF-IDF :提取关键词
    • 4.4)数据集标签制作
  • 五、建立模型
    • 5.1)数据集切分
    • 5.2)使用词袋模型的特征来建模
      • 5.2.1)制作词袋模型特征
      • 5.2.2)建模&观察结果
    • 5.3)使用TF-IDF特征建模

前言介绍

内容介绍:建立新闻文章分类模型,使用TF-IDF和词袋模型构建特征,基于贝叶斯算法来完成分类任务。 本文仅作课程学习记录使用,若内容有误请提出指正。

处理流程:新闻数据集处理–文本分词 – 去停用词–构建文本特征–贝叶斯分类

  • 构建文本特征:将文本转化成可以用数字表示的特征 ,其中两种方案:1)词袋模型特征; 2)TF-IDF特征
  • 贝叶斯分类:基于贝叶斯算法来完成最终的分类任务

数据介绍:来自若干新闻站点2012年6月—7月期间国内,国际,体育,社会,娱乐等18个频道的新闻数据,提供URL和正文信息
格式说明:数据格式为

<doc>
<url>页面URL</url>
<docno>页面ID</docno>
<contenttitle>页面标题</contenttitle>
<content>页面内容</content>
</doc>

注意:content字段去除了HTML标签,保存的是新闻正文文本
数据来源:http://www.sogou.com/labs/resource/ca.php

一、新闻数据集处理

#导入模块包
import pandas as pd
import jieba

#导入数据
df_news = pd.read_table('./data/data.txt',names=['category','theme','URL','content'],encoding='utf-8')
df_news = df_news.dropna()
df_news.tail()

df_news.shape #查看数据规模

贝叶斯算法(新闻分类任务)_第1张图片
爬取的新闻数据,需要我们对文本数据进行很多预处理才能使用

字段含义:
Category:当前新闻所属的类别,一会我们要进行分别任务,这就是标签了。
Theme:新闻的主题,这个咱们先暂时不用,大家在练习的时候也可以把它当作特征。
URL:爬取的界面的链接,方便检验爬取数据是不是完整的,这个咱们暂时也不需要。
Content:新闻的内容,这些就是一篇文章了,里面的内容还是很丰富的。

二、文本分词(jibe分词器)

使用jieba分词器前,要将文章转换成list, 使用.tolist()

content = df_news.content.values.tolist() #将文章转换成list
print (content[1000]) #随便选择其中第1000个看

#结巴分词
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) #保存分词的结果

#结果展示
df_content=pd.DataFrame({'content_S':content_S}) #将结果转换成表格展示
df_content.head()

贝叶斯算法(新闻分类任务)_第2张图片

三、去停用词

分词后,有很多词是不重要的,也是需要过滤的目标。可以使用停用词表过滤文件,或者根据根据词频设定停用词,出现越多的词越不重要。

停用词表是什么?

首先需要选择一个合适的停用词库,这些网上有很多现成的,但是都没那么完整,所以还需要自己添加一些。

#stopwords.txt 停用字符文件
stopwords=pd.read_csv("stopwords.txt",index_col=False,sep="\t",quoting=3,names=['stopword'], encoding='utf-8')
stopwords.head(20)#查看停用字符文件

贝叶斯算法(新闻分类任务)_第3张图片

使用停用词表过滤文件

#过滤文本:将不在停用表的单词加入到line_clean文件里
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.tolist() #修改,原代码报错:stopwords.stopword.values.tolist()
contents_clean,all_words = drop_stopwords(contents,stopwords)

#结果展示
df_content=pd.DataFrame({'contents_clean':contents_clean})
df_content.head()

贝叶斯算法(新闻分类任务)_第4张图片

四、构建文本特征

4.1)统计词频

可以用groupby()、count() 统计词频

#词频统计
counts = {}
for word in all_words:
    counts[word] = counts.get(word, 0) + 1
items = list(counts.items())
items.sort(key=lambda x:x[1], reverse=True)
for i in range(10):
    word, count = items[i]
    print("{0:<10}{1:>5}".format(word, count))
words_count=items

4.2)词云展示

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[:100]}
wordcloud=wordcloud.fit_words(word_frequence)
plt.imshow(wordcloud)

贝叶斯算法(新闻分类任务)_第5张图片

4.3)TF-IDF :提取关键词

介绍链接:百度百科
通用词:如果一个词通篇出现可能就不重要,比如中国;一个单词在别的文章不出现,但是在这篇文章出现很多次,就很有可能是关键词。

import jieba.analyse #工具包
index = 2400 #随便使用一篇文章
content_S_str = "".join(content_S[index]) #把分词的结果组合在一起,形成一个句子
print (content_S_str) #打印这个句子
print ("  ".join(jieba.analyse.extract_tags(content_S_str, topK=5, withWeight=False)))#选出来5个核心词

贝叶斯算法(新闻分类任务)_第6张图片

4.4)数据集标签制作

新闻的分类有很多种,汽车、财经、科技、健康、体育、教育……, 这一步需要将这些分类制作成数值型标签。

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

df_train.label.unique() #查看一共有多少个标签

#下面将文字标签转换成数字
label_mapping = {"汽车": 1, "财经": 2, "科技": 3, "健康": 4, "体育":5, "教育": 6,"文化": 7,"军事": 8,"娱乐": 9,"时尚": 0} 
df_train['label'] = df_train['label'].map(label_mapping) #构建一个映射方法
df_train.head()

贝叶斯算法(新闻分类任务)_第7张图片

五、建立模型

5.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 = x_train.flatten()
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]        

贝叶斯算法(新闻分类任务)_第8张图片

print (len(words)) # 统计有多少个词

结果显示一共有3750个词。

5.2)使用词袋模型的特征来建模

5.2.1)制作词袋模型特征

from sklearn.feature_extraction.text import CountVectorizer
vec = CountVectorizer(analyzer='word', max_features=4000,  lowercase = False) #限制条件max_features特征最大长度为4000
feature = vec.fit_transform(words)

如果不进行限制max_features,最终得到的向量长度为85093,这会使得特征长度过大,而且里面很多都是词频很低的词语,也会导致特征过于稀疏。

5.2.2)建模&观察结果

from sklearn.naive_bayes import MultinomialNB #贝叶斯模型
classifier = MultinomialNB() 
classifier.fit(feature, y_train)

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

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]

贝叶斯算法(新闻分类任务)_第9张图片

#模型评估
classifier.score(vec.transform(test_words), y_test)

0.804

表示该模型最后分类

5.3)使用TF-IDF特征建模

from sklearn.feature_extraction.text import TfidfVectorizer

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

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

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

最后结果是0.8152,比词袋模型有所提高。

你可能感兴趣的:(数据分析项目笔记,机器学习算法,自然语言处理,python,数据分析)