Advertisement

中文文本分类-新闻分类[数据挖掘]

阅读量:

以10种新闻类型为基础开展文本分类工作,并基于准确率、召回率以及F1值等指标对分类效果展开评估。

python版本:python 3.6
分类方法:朴素贝叶斯

需导入的相关库

复制代码
    import os
    import time
    import numpy as np
    import pandas as pd
    import jieba
    from jieba import analyse
    from sklearn.utils import shuffle
    from sklearn.model_selection import train_test_split
    from sklearn.feature_extraction.text import CountVectorizer,TfidfVectorizer #词集转换成向量
    from sklearn.naive_bayes import MultinomialNB #朴素贝叶斯多分类
    from sklearn.metrics import classification_report
    import gensim #自然语言处理库
    from gensim import corpora,models,similarities

上述某些库源 在Windows环境下似乎与Python 3.7版本之间存在版本不兼容的问题,在Linux系统上能够顺利运行并无此类困扰。基于此原因 我们决定转而采用Python 3.6作为替代方案

对数据源选取数据规模

大家可以从现有网络资源中选择所需的数据集,并从中筛选出所需数量的数据样本作为研究依据。我的研究数据集是通过自建爬虫完成获取的,在获取过程中进行了必要的预处理工作以保证数据质量。经过清洗处理后得到的数据集已经去除了空行、重复项以及杂乱无章的信息等杂质

第一步:获取原始数据

复制代码
    #读取数据源,注释掉的是拼接数据的部分,有需要的可以参考
    def con_data():
    # df1 = pd.read_csv('chinanews00.csv',names=['category','theme','URL','content'])
    # df2 = pd.read_csv('chinanews11.csv',names=['category','theme','URL','content'])
    # data = pd.concat([df1,df2],axis=0,ignore_index=True) #拼接表格
    data = pd.read_csv('chinanews.csv',names=['category','theme','URL','content'])
    df = data.groupby('category').count()#展示数据规模
    print(df)
    # print(data.shape)
    return data

在实验阶段时处理了大量数据;然而,在当前情境下出于便于重复使用的目的,我们将各类数据规模缩减至1,000条;这样的操作相对快捷

在实验阶段时处理了大量数据;然而,在当前情境下出于便于重复使用的目的,我们将各类数据规模缩减至1, 但又不完全等于 万的数据量;这样的操作相对快捷

复制代码
    #分组选行
    def group(data,amount,file_path):
    df = data.groupby('category').head(amount)
    df.to_csv(file_path,mode='a',header=None, index=False, encoding="utf-8-sig")

于是就有了目标数据 eg: test.csv

文本分类

1、读入待分类数据

复制代码
    def read_file():
    data = pd.read_csv('test.csv',names=['category','theme','URL','content'])
    df = data.groupby('category').count()#展示数据规模
    print(df)
    return data

数据规模:

在这里插入图片描述

样本长这样:

在这里插入图片描述

2、对数据进行切割
这一过程并非必须执行,原因在于不同类型的新闻文章长度存在显著差异:有些较长且详细丰富,有些则较短且信息精炼。因此,在理论上,则需剔除那些过于冗长或过于简短的内容(即所谓的过长或过短的文章),使所有新闻文本的长度趋于一致。如果不进行剔除处理,则可能会影响分类效果。

3、jieba分词并去停用词

复制代码
    def separate_words(data):
    content = data.content.values.tolist() #将文本内容转换为list格式
    	#读入停用词表
    stopwords = pd.read_csv("stopwords.txt",index_col=False,sep="\t",quoting=3,names=['stopword'], encoding='utf-8') #list
    stopwords = stopwords.stopword.values.tolist()
    print("正在分词,请耐心等候......")
    contents_clean = []
    all_words = []
     
    for line in content:
        current_segment = jieba.lcut(line) #jieba分词
        current_segment = [x.strip() for x in current_segment if x.strip()!=''] #去掉分词后出现的大量空字符串
        if len(current_segment) > 1 and current_segment != "\r\n":
            line_clean = []
            for word in current_segment:
                if word in stopwords:
                    continue
                line_clean.append(word)
                all_words.append(str(word))
            contents_clean.append(line_clean)        
    print('------------分词完成-----------')
    return contents_clean, all_words

结果是这样的:

在这里插入图片描述

在其中,在我的研究过程中会遇到很多需要处理的数据词语组合中,“all_words”这一概念具有重要的研究价值,在这种情况下就可以通过它来进行一些特定的数据处理工作 在这种情况下 我会根据我的词频分析结果绘制一张图表 这张图表展示了剔除了一些不符合实际的高频词汇后生成的内容

在这里插入图片描述

4、标签转换
中文标签改为数字标签,便于分类

转换之前的标签:

在这里插入图片描述
复制代码
    #标签转换
    label_mappping = {'汽车':1,'财经':2, '法治':3, '社会':4, '体育':5, '国际':6, '文化':7, '军事':8, '娱乐':9, '台湾':0}
    df_train["label"] = df_train["label"].map(label_mappping)
    print(df_train.head())
    print("--------------------------------------3------------------------------------------")

转换之后的结果:

在这里插入图片描述

5、切分数据集
按1:1切分

复制代码
    #切分数据集
    x_train,x_test,y_train,y_test = train_test_split(df_train["contents_clean"].values,df_train["label"].values,test_size=0.5)

启动训练流程 因为当前的数据内容被逗号分隔开 所以需要移除非必要使用空格连接的词之间

复制代码
    def format_transform(x): #x是数据集(训练集或者测试集)
    words =[]
    for line_index in range(len(x)):
        try:
            words.append(" ".join(x[line_index]))
        except:
            print("数据格式有问题")
    return words
复制代码
    #训练
    words_train = format_transform(x_train) 
    vectorizer = TfidfVectorizer(analyzer='word', max_features=4000,ngram_range=(1, 3),lowercase = False)
    vectorizer.fit(words_train)#转为向量格式
    classifier = MultinomialNB()
    classifier.fit(vectorizer.transform(words_train), y_train)

7、测试,并查看相关结果

复制代码
    words_test = format_transform(x_test)
    score = classifier.score(vectorizer.transform(words_test), y_test)
    print("----------------------------------分类结果报告-----------------------------------------")
    print("分类准确率:" + str(score))
    print("训练时间:" + str(round((end_1-start_1), 2)) + '秒')
    print("测试时间:" + str(round((end_2-start_2), 2)) + '秒')
    y_predict=classifier.predict(vectorizer.transform(words_test))
    print(classification_report(y_test,y_predict))

出来的结果是这样的:

在这里插入图片描述

emmmm,这个分类结果不是很理想。。。可以通过调参提高分类结果准确率。

全部评论 (0)

还没有任何评论哟~