nlp-problem

该问题可归类为监督性学习的分类问题。解决该问题的方法有:

  1. 普通的概率模型:如朴素贝叶斯,该模型最主要的缺点是无法捕捉词与词之间的上下文关系,特征与特征之间组合关系,因为该模型假设词与词之间是相互独立。

  2. 树型模型,如随机森林,提升树(xgboost,gdbt).该模型虽然很好地解决特征组合问题,但是对稀疏矩阵的效果不好,
    特别是对针对当下的文本分类问题,因为one-hot处理后,形成巨大稀疏矩阵,几乎不可分割。

  3. 词向量化,比如word2vec,该模型是把词 word embedding 化,这样主要优点是很好捕捉上下关系。
    #基本思想是根据上下文预测中间词(cbow), 或者中间词预测上下文(skip-gram,基于词思想提出用于分类模型的fast-text model,该模与word2vec区别是预测的是分类

  4. 深度学习,比如lstm,相比rnn,该模型能防止梯度弥散,同时能捕捉更长的上下文关系。因为权重共享,很难判断那个词对最终结果影响最明显。我们可加入attention层。深度学习虽然能很好拟好数据分布情况,但是对设备要求高。数据量大,网络层深,网络复杂等,这些都需要好的显卡支撑。当然为了提高运行速度,可充分利用预训练数据,比如bert

因此这里我们选用fast-text model,设备要求低,训练快,很好捕捉上下文关系,准确率高。

import json
import pandas as pd
import matplotlib.pyplot as plt
import random
import os
import fasttext 
import numpy as np

import json
def loadData()
    '''
    导入数据
    '''
    data = []
    with open("nlp-problem//News_Category_Dataset_v2.json",'r',encoding='utf8') as f:
        for line in f.readlines():
            d = json.loads(line)
            data.append(d)

def count_catagory(data):
    '''
    统计每个类别的数据
    '''
    nums_catagory= {}
    for i in range(len(data)):
        if data[i]['category'] in nums_catagory:
            nums_catagory[data[i]['category']] +=1
        else:
            nums_catagory[data[i]['category']] =nums_catagory.setdefault(data[i]['category'],0)+1
    return nums_catagory


def SegmentationCombine(data):
    '''
    1.分词,这里直接把每个单词独立切分成一个词,因为fast-text会自动捕获单词与单词之间关系,
    不需要准确地切分成词组或者短语
    2.大写转为小写
    3.把标签值转 __label__ENTERTAINMENT 形式
    '''
    SegData=[]
    for num in range(len(data)):
        words = [word for word in re.sub("[^a-zA-Z]"," ",data[num]['headline'].lower()).split(' ') if len(word) >1]
        SegData.append('__'+'label'+'__'+data[num]['category']+' '+','+' '+' '.join(words))
    return SegData

def WriteTxt(prename,train_data):
    '''
    保存已经加工好的数据
    '''   
    data_file = 'nlp-problem/{}_class.txt'.format(str(prename))
    with open(data_file, 'w', encoding='utf-8') as data_f:
        for values in train_data:
            data_f.write(values)
            data_f.write('\n')

def train_model(ipt=None, opt=None, model='', dim=dim, epoch=epoch, lr=lr, loss='softmax'):
    '''
    训练模型
    ipt:文件路径
    opt:保存路径
    model:name
    dim:投影层的维度
    epoch:训练轮数
    lr:学习率
    loss:损失函数
    '''
    np.set_printoptions(suppress=True)
    if os.path.isfile(model):
        classifier = fasttext.load_model(model)
    else:
        classifier = fasttext.train_supervised(ipt, label='__label__', dim=dim, epoch=epoch,
                                         lr=lr, wordNgrams=2, loss=loss)
        classifier.save_model(opt)
    return classifier

def CalPrecision(file):
    '''
    计算准确率,召回率
    输入test文件路径
    '''

    total,recall,precision={},{},{}
    with open(file,encoding='utf-8') as f:
        for line in f:
            label, content = line.split(',', 1)
            total[label.strip().strip('')] = total.setdefault(label.strip().strip(),0)+1 
            PredictedLabels = classifier.predict(content.strip('\n'))[0][0] 
            recall[PredictedLabels] = recall.setdefault(PredictedLabels,0)+1
            if label.strip() == PredictedLabels.strip():
                precision[label.strip()]=precision.setdefault(label.strip(),0)+1
        for k,_ in precision.items():
            pre = precision[k] / (total.get(k,precision[k])+0.0001)
            rec =  precision[k] / (recall.get(k,precision[k])+0.0001)
            F1 = (2 * pre * rec) / ((pre + rec)+0.0001)
            print("{} : precision: {}  recall: {}  F1: {}".format(k.strip('__label__'),pre,rec,F1))


def predict(content,k):
    '''
    content:预测文本
    k:输出的topics数
    '''
    words = [word for word in re.sub("[^a-zA-Z]"," ",content.lower()).split(' ') if len(word) >1]
    pred = classifier.predict(' '.join(words),k)
    return pred


if __name__ ='__main__':
    proportion = 0.9
    dim = 100
    lr = 5
    epoch = 5
    data =loadData() # 导入数据
    WriteTxt('train',trainClass) # 保存训练数据
    WriteTxt('test',testClass) #保存测试数据
    model = 'F://VS_python//nlp-problem//fasttext.model'
    Train_file = 'F://VS_python//nlp-problem//train_class.txt'
    Test_file='F://VS_python//nlp-problem//test_class.txt'
    classifier = train_model(ipt=Train_file,
                        opt=model,
                        model=model,
                        dim=dim, epoch=epoch, lr=0.5
                        )



    #test:
    # content='senate blocks government funding bill tied to abortion'
    # predict(content,5)
CalPrecision(Test_file)

在这里插入图片描述

content='senate blocks government funding bill tied to abortion'
predict(content,5)

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值