热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Python如何通过朴素贝叶斯和LSTM分别实现新闻文本分类

这篇文章主要介绍Python如何通过朴素贝叶斯和LSTM分别实现新闻文本分类,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完

这篇文章主要介绍Python如何通过朴素贝叶斯和LSTM分别实现新闻文本分类,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

    数据处理与分析

    本次大赛提供的材料是由csv格式编写,只需调用python中的pandas库读取即可。为了更直观的观察数据,我计算了文档的平均长度,以及每个标签分别对应的文档。(sen字典与tag字典的获取方法会在后文中展示,此步只用来呈现数据分布,运行时可先跳过)

    import matplotlib.pyplot as plt
    from tqdm import tqdm
    import time
    from numpy import *
    import pandas as pd
    
    print('count: 200000') #词典sen中,每个标签对应其所有句子的二维列表
    print('average: '+str(sum([[sum(sen[i][j]) for j in range(len(sen[i]))] for i in sen])/200000))
    x = []
    y = []
    for key,value in tag.items(): #词典tag中,每个标签对应该标签下的句子数目
        x.append(key)
        y.append(value)
    plt.bar(x,y)
    plt.show()

    最终我们得到了以下结果:

    Python如何通过朴素贝叶斯和LSTM分别实现新闻文本分类

    平均文档长约907词,每个标签对应的文档数从标签0至13逐个减少。

    基于机器学习的文本分类–朴素贝叶斯

    1. 模型介绍

    朴素贝叶斯分类器的基本思想是利用特征项和类别的联合概率来估计给定文档的类别概率。假设文本是基于词的一元模型,即文本中当前词的出现依赖于文本类别,但不依赖于其他词及文本的长度,也就是说,词与词之间是独立的。根据贝叶斯公式,文档Doc属于Ci类的概率为

    Python如何通过朴素贝叶斯和LSTM分别实现新闻文本分类

    文档Doc采用TF向量表示法,即文档向量V的分量为相应特征在该文档中出现的频度,文档Doc属于Ci类文档的概率为

    Python如何通过朴素贝叶斯和LSTM分别实现新闻文本分类

    其中,TF(ti,Doc)是文档Doc中特征ti出现的频度,为了防止出现不在词典中的词导致概率为0的情况,我们取P(ti|Ci)是对Ci类文档中特征ti出现的条件概率的拉普拉斯概率估计:

    Python如何通过朴素贝叶斯和LSTM分别实现新闻文本分类

    这里,TF(ti,Ci)是Ci类文档中特征ti出现的频度,|V|为特征集的大小,即文档表示中所包含的不同特征的总数目。

    2. 代码结构

    我直接通过python自带的open()函数读取文件,并建立对应词典,设定停用词,这里的停用词选择了words字典中出现在100000个文档以上的所有词。训练集取前19万个文档,测试集取最后一万个文档。

    train_df = open('./data/train_set.csv').readlines()[1:]
    train = train_df[0:190000]
    test = train_df[190000:200000]
    true_test = open('./data/test_a.csv').readlines()[1:]
    tag = {str(i):0 for i in range(0,14)}
    sen = {str(i):{} for i in range(0,14)}
    words={}
    stop_words = {'4149': 1, '1519': 1, '2465': 1, '7539': 1, ...... }

    接着,我们需要建立标签词典和句子词典,用tqdm函数来显示进度。

    for line in tqdm(train_df):
        cur_line = line.split('\t')
        cur_tag = cur_line[0]
        tag[cur_tag] += 1
        cur_line = cur_line[1][:-1].split(' ')
        for i in cur_line:
            if i not in words:
                words[i] = 1
            else:    
                words[i] += 1
            if i not in sen[cur_tag]:
                sen[cur_tag][i] = 1
            else:
                sen[cur_tag][i] += 1

    为了便于计算,我定义了如下函数,其中mul()用来计算列表中所有数的乘积,prob_clas() 用来计算P(Ci|Doc),用probability()来计算P(ti|Ci),在probability() 函数中,我将输出结果中分子+1,分母加上字典长度,实现拉普拉斯平滑处理。

    def mul(l):
        res = 1
        for i in l:
            res *= i
        return res
    def prob_clas(clas):
        return tag[clas]/(sum([tag[i] for i in tag]))
    def probability(char,clas):  #P(特征|类别)
        if char not in sen[clas]:
            num_char = 0
        else:
            num_char = sen[clas][char]
        return (1+num_char)/(len(sen[clas])+len(words))

    在做好所有准备工作,定义好函数后,分别对测试集中的每一句话计算十四个标签对应概率,并将概率最大的标签储存在预测列表中,用tqdm函数来显示进度。

    PRED = []
    for line in tqdm(true_test):
        result = {str(i):0 for i in range(0,14)}
        cur_line = line[:-1].split(' ')
        clas = cur_tag
        for i in result:
            prob = []
            for j in cur_line:
                if j in stop_words:
                    continue
                prob.append(log(probability(j,i)))
            result[i] = log(prob_clas(i))+sum(prob)
        for key,value in result.items():
            if(value == max(result.values())):
                pred = int(key)
        PRED.append(pred)

    最后把结果储存在csv文件中上传网站,提交后查看成绩。(用此方法编写的csv文件需要打开后删去第一列再上传)

    res=pd.DataFrame()
    res['label']=PRED
    res.to_csv('test_TL.csv')

    3. 结果分析

    在训练前19万个文档,测试后一万个文档的过程中,我不断调整停用词取用列表,分别用TF和TF-IDF向量表示法进行了测试,结果发现使用TF表示法准确性较高,最后取用停用词为出现在十万个文档以上的词。最终得出最高效率为0.622。

    Python如何通过朴素贝叶斯和LSTM分别实现新闻文本分类

    在提交至网站后,对五万个文档进行测试的F1值仅有 0.29左右,效果较差。

    Python如何通过朴素贝叶斯和LSTM分别实现新闻文本分类

    基于深度学习的文本分类–LSTM

    1. 模型介绍

    除了传统的机器学习方法,我使用了深度学习中的LSTM(Long Short-Term Memory)长短期记忆网络,来尝试处理新闻文本分类,希望能有更高的准确率。LSTM它是一种时间循环神经网络,适合于处理和预测时间序列中间隔和延迟相对较长的重要事件。LSTM 已经在科技领域有了多种应用。基于 LSTM 的系统可以学习翻译语言、控制机器人、图像分析、文档摘要、语音识别图像识别、手写识别、控制聊天机器人、预测疾病、点击率和股票、合成音乐等等任务。我采用深度学习库Keras来建立LSTM模型,进行文本分类。

    对于卷积神经网络CNN和循环网络RNN而言,随着时间的不断增加,隐藏层一次又一次地乘以权重W。假如某个权重w是一个接近于0或者大于1的数,随着乘法次数的增加,这个权重值会变得很小或者很大,造成反向传播时梯度计算变得很困难,造成梯度爆炸或者梯度消失的情况,模型难以训练。也就是说一般的RNN模型对于长时间距离的信息记忆很差,因此LSTM应运而生。

    Python如何通过朴素贝叶斯和LSTM分别实现新闻文本分类

    LSTM长短期记忆网络可以更好地解决这个问题。在LSTM的一个单元中,有四个显示为黄色框的网络层,每个层都有自己的权重,如以 σ 标记的层是 sigmoid 层,tanh是一个激发函数。这些红圈表示逐点或逐元素操作。单元状态在通过 LSTM 单元时几乎没有交互,使得大部分信息得以保留,单元状态仅通过这些控制门(gate)进行修改。第一个控制门是遗忘门,用来决定我们会从单元状态中丢弃什么信息。第二个门是更新门,用以确定什么样的新信息被存放到单元状态中。最后一个门是输出门,我们需要确定输出什么样的值。总结来说 LSTM 单元由单元状态和一堆用于更新信息的控制门组成,让信息部分传递到隐藏层状态。

    2. 代码结构

    首先是初始数据的设定和包的调用。考虑到平均句长约900,这里取最大读取长度为平均长度的2/3,即max_len为600,之后可通过调整该参数来调整学习效率。

    from tqdm import tqdm
    import pandas as pd
    import time
    import matplotlib.pyplot as plt
    import seaborn as sns
    from numpy import *
    from sklearn import metrics
    from sklearn.preprocessing import LabelEncoder,OneHotEncoder
    from keras.models import Model
    from keras.layers import LSTM, Activation, Dense, Dropout, Input, Embedding
    from keras.optimizers import rmsprop_v2
    from keras.preprocessing import sequence
    from keras.callbacks import EarlyStopping
    from keras.models import load_model
    import os.path
    
    max_words = 7549 #字典最大编号
    # 可通过调节max_len调整模型效果和学习速度
    max_len = 600 #句子的最大长度
    stop_words = {}

    接下来,我们定义一个将DataFrame的格式转化为矩阵的函数。该函数输出一个长度为600的二维文档列表和其对应的标签值。

    def to_seq(dataframe):
        x = []
        y = array([[0]*int(i)+[1]+[0]*(13-int(i)) for i in dataframe['label']])
        for i in tqdm(dataframe['text']):
            cur_sentense = []
            for word in i.split(' '):
                if word not in stop_words: #最终并未采用停用词列表
                    cur_sentense.append(word)
            x.append(cur_sentense)
        return sequence.pad_sequences(x,maxlen=max_len),y

    接下来是模型的主体函数。该函数输入测试的文档,测试集的真值,训练集和检验集,输出预测得到的混淆矩阵。具体代码介绍,见下列代码中的注释。

    def test_file(text,value,train,val):
        ## 定义LSTM模型
        inputs = Input(name='inputs',shape=[max_len])
        ## Embedding(词汇表大小,batch大小,每个新闻的词长)
        layer = Embedding(max_words+1,128,input_length=max_len)(inputs)
        layer = LSTM(128)(layer)
        layer = Dense(128,activation="relu",name="FC1")(layer)
        layer = Dropout(0.5)(layer)
        layer = Dense(14,activation="softmax",name="FC2")(layer)
        model = Model(inputs=inputs,outputs=layer)
        model.summary()
        model.compile(loss="categorical_crossentropy",optimizer=rmsprop_v2.RMSprop(),metrics=["accuracy"])
        
        ## 模型建立好之后开始训练,如果已经保存训练文件(.h6格式),则直接调取即可
        if os.path.exists('my_model.h6') == True:
            model = load_model('my_model.h6')
        else:
            train_seq_mat,train_y = to_seq(train)
            val_seq_mat,val_y = to_seq(val)
            model.fit(train_seq_mat,train_y,batch_size=128,epochs=10,  #可通过epochs数来调整准确率和运算速度
                          validation_data=(val_seq_mat,val_y))
            model.save('my_model.h6') 
        ## 开始预测
        test_pre = model.predict(text)
        ##计算混淆函数
        confm = metrics.confusion_matrix(argmax(test_pre,axis=1),argmax(value,axis=1))
        print(metrics.classification_report(argmax(test_pre,axis=1),argmax(value,axis=1)))
        return confm

    训练过程如下图所示。

    Python如何通过朴素贝叶斯和LSTM分别实现新闻文本分类

    为了更直观的表现结果,定义如下函数绘制图像。

    def plot_fig(matrix):
        Labname = [str(i) for i in range(14)]
        plt.figure(figsize=(8,8))
        sns.heatmap(matrix.T, square=True, annot=True,
                    fmt='d', cbar=False,linewidths=.8,
                    cmap="YlGnBu")
        plt.xlabel('True label',size = 14)
        plt.ylabel('Predicted label',size = 14)
        plt.xticks(arange(14)+0.5,Labname,size = 12)
        plt.yticks(arange(14)+0.3,Labname,size = 12)
        plt.show()
        return

    最后,只需要通过pandas读取csv文件,按照比例分为训练集、检验集和测试集(这里选用比例为15:2:3),即可完成全部的预测过程。

    def test_main():
        train_df = pd.read_csv("./data/train_set.csv",sep='\t',nrows=200000)
        train = train_df.iloc[0:150000,:]
        test = train_df.iloc[150000:180000,:]
        val = train_df.iloc[180000:,:]
        test_seq_mat,test_y = to_seq(test)
        Confm = test_file(test_seq_mat,test_y,train,val)
        plot_fig(Confm)

    在获得预测结果最高的一组参数的选取后,我们训练整个train_set文件,训练过程如下,训练之前需删除已有的训练文件(.h6),此函数中的test行可随意选取,只是为了满足test_file()函数的变量足够。此函数只是用于训练出学习效果最好的数据并储存。

    def train():
        train_df = pd.read_csv("./data/train_set.csv",sep='\t',nrows=200000)
        train = train_df.iloc[0:170000,:]
        test = train_df.iloc[0:10000,:]
        val = train_df.iloc[170000:,:]
        test_seq_mat,test_y = to_seq(test)
        Confm = test_file(test_seq_mat,test_y,train,val)
        plot_fig(Confm)

    在获得最优的训练数据后,我们就可以开始预测了。我们将竞赛中提供的测试集带入模型中,加载储存好的训练集进行预测,得到预测矩阵。再将预测矩阵中每一行的最大值转化为对应的标签,储存在输出列表中即可,最后将该列表写入'test_DL.csv'文件中上传即可。(如此生成的csv文件同上一个模型一样,需手动打开删除掉第一列)

    def pred_file():
        test_df = pd.read_csv('./data/test_a.csv')
        test_seq_mat = sequence.pad_sequences([i.split(' ') for i in tqdm(test_df['text'])],maxlen=max_len)
        
        inputs = Input(name='inputs',shape=[max_len])
        ## Embedding(词汇表大小,batch大小,每个新闻的词长)
        layer = Embedding(max_words+1,128,input_length=max_len)(inputs)
        layer = LSTM(128)(layer)
        layer = Dense(128,activation="relu",name="FC1")(layer)
        layer = Dropout(0.5)(layer)
        layer = Dense(14,activation="softmax",name="FC2")(layer)
        model = Model(inputs=inputs,outputs=layer)
        model.summary()
        model.compile(loss="categorical_crossentropy",optimizer=rmsprop_v2.RMSprop(),metrics=["accuracy"])
        model = load_model('my_model.h6')
        
        test_pre = model.predict(test_seq_mat)
    
        pred_result = [i.tolist().index(max(i.tolist())) for i in test_pre]
        res=pd.DataFrame()
        res['label']=pred_result
        res.to_csv('test_DL.csv')

    整理后,我们只需要注释掉对应的指令行即可进行训练或预测。

    #如果想要训练,取消下行注释,训练之前需先删除原训练文件(.h6)
    #train()
    
    #如果想要查看模型效果,取消下行注释(训练集:检验集:测试集=15:2:3)
    # test_main()
    
    #如果想预测并生成csv文件,取消下行注释
    # pred_file()

    3. 结果分析

    最终获得的混淆矩阵如下图所示,14个标签预测的正确率均达到了80%以上,有11个标签在90%以上,有6个标签在95%以上。

    Python如何通过朴素贝叶斯和LSTM分别实现新闻文本分类

    绘制出来的预测结果如下图所示,可见预测效果相当理想,每个标签的正确率都尤为可观,预测错误的文本数相比于总量非常少。

    Python如何通过朴素贝叶斯和LSTM分别实现新闻文本分类

    最终上传网站得到结果,F1值达90%以上,效果较好。

    Python如何通过朴素贝叶斯和LSTM分别实现新闻文本分类

    以上是“Python如何通过朴素贝叶斯和LSTM分别实现新闻文本分类”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注编程笔记行业资讯频道!


    推荐阅读
    • 不同优化算法的比较分析及实验验证
      本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
    • 也就是|小窗_卷积的特征提取与参数计算
      篇首语:本文由编程笔记#小编为大家整理,主要介绍了卷积的特征提取与参数计算相关的知识,希望对你有一定的参考价值。Dense和Conv2D根本区别在于,Den ... [详细]
    • keras归一化激活函数dropout
      激活函数:1.softmax函数在多分类中常用的激活函数,是基于逻辑回归的,常用在输出一层,将输出压缩在0~1之间,且保证所有元素和为1,表示输入值属于每个输出值的概率大小2、Si ... [详细]
    • python机器学习之数据探索
      🐱今天我们来讲解数据建模之前需要处理的工作,也就是数据探索的过程,很多同学会说,不就是处理缺失值,异常值&# ... [详细]
    • 代码如下:#coding:utf-8importstring,os,sysimportnumpyasnpimportmatplotlib.py ... [详细]
    • TensorFlow入门上
      前置准备在阅读本文之前,请确定你已经了解了神经网络的基本结构以及前向传播、后向传播的基本原理,如果尚未了解,可以查看下文。神经网络初探​chrer.com也可以直接在我博客阅读Te ... [详细]
    • YOLOv7基于自己的数据集从零构建模型完整训练、推理计算超详细教程
      本文介绍了关于人工智能、神经网络和深度学习的知识点,并提供了YOLOv7基于自己的数据集从零构建模型完整训练、推理计算的详细教程。文章还提到了郑州最低生活保障的话题。对于从事目标检测任务的人来说,YOLO是一个熟悉的模型。文章还提到了yolov4和yolov6的相关内容,以及选择模型的优化思路。 ... [详细]
    • 本文介绍了机器学习手册中关于日期和时区操作的重要性以及其在实际应用中的作用。文章以一个故事为背景,描述了学童们面对老先生的教导时的反应,以及上官如在这个过程中的表现。同时,文章也提到了顾慎为对上官如的恨意以及他们之间的矛盾源于早年的结局。最后,文章强调了日期和时区操作在机器学习中的重要性,并指出了其在实际应用中的作用和意义。 ... [详细]
    • 本文介绍了在Python张量流中使用make_merged_spec()方法合并设备规格对象的方法和语法,以及参数和返回值的说明,并提供了一个示例代码。 ... [详细]
    • 本文介绍了使用Spark实现低配版高斯朴素贝叶斯模型的原因和原理。随着数据量的增大,单机上运行高斯朴素贝叶斯模型会变得很慢,因此考虑使用Spark来加速运行。然而,Spark的MLlib并没有实现高斯朴素贝叶斯模型,因此需要自己动手实现。文章还介绍了朴素贝叶斯的原理和公式,并对具有多个特征和类别的模型进行了讨论。最后,作者总结了实现低配版高斯朴素贝叶斯模型的步骤。 ... [详细]
    • Opencv提供了几种分类器,例程里通过字符识别来进行说明的1、支持向量机(SVM):给定训练样本,支持向量机建立一个超平面作为决策平面,使得正例和反例之间的隔离边缘被最大化。函数原型:训练原型cv ... [详细]
    • 开发笔记:图像识别基于主成分分析算法实现人脸二维码识别
      篇首语:本文由编程笔记#小编为大家整理,主要介绍了图像识别基于主成分分析算法实现人脸二维码识别相关的知识,希望对你有一定的参考价值。 ... [详细]
    • React提供三种方式创建Refs:字符串Refs(将被废弃)回调函数RefsReact.createRef(从React16.3开始)第一种方式不推荐使用,原因在此,并且可能会在之后的版本移除。classMyComponentextendsReact.Component{constructor(props){sup ... [详细]
    • 「爆干7天7夜」入门AI人工智能学习路线一条龙,真的不能再透彻了
      前言应广大粉丝要求,今天迪迦来和大家讲解一下如何去入门人工智能,也算是迪迦对自己学习人工智能这么多年的一个总结吧,本条学习路线并不会那么 ... [详细]
    • 鄂维南:从数学角度,理解机器学习的「黑魔法」,并应用于更广泛的科学问题...
      作者|Hertz来源|科学智能AISI北京时间2022年7月8日晚上22:30,鄂维南院士在2022年的国际数学家大会上作一小时大会报告(plenarytalk)。今 ... [详细]
    author-avatar
    手机用户2602922511
    这个家伙很懒,什么也没留下!
    PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
    Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有