朴素贝叶斯实战-文本主题分类

本文介绍了一种基于BCDI2018数据集的汽车用户观点主题及情感识别方法,通过预处理、文本向量化及模型预测实现对汽车评论主题(如动力、价格等)的情感分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

本文采用的是BCDI2018汽车行业用户观点主题及情感识别任务中的语料集链接,这些语料集的格式如下:

字段名称类型描述说明
content_idInt数据ID/
contentString文本内容/
subjectString主题提取或依据上下文归纳出来的主题
sentiment_valueInt情感分析分析出的情感
sentiment_wordString情感词情感词

其中训练集数据中主题被分为10类,包括:动力、价格、内饰、配置、安全性、外观、操控、油耗、空间、舒适性,情感分为3类,分别用数字0、1、-1表示中立、正向、负向。

思路

文本预处理

1、将文本分成一个个单词,并去掉停用词、标点符号,用jieba分词工具,对中文比较友好,可以将一个文本变成: 我爱网易 – > 我,爱,网易
2、将主题换成数字标签,将主题:动力、价格、内饰、配置、安全性等数值化,变成数字:

12345678910
动力价格内饰配置安全性外观操控油耗空间舒适性
文本向量化

利用TfidfVectorizer工具对文本提取特征,这里因为有参数需要设置,其中有一个参数ngram_range=(1,2),这个参数跟提取出的特征有关,其中1代表最小连续单词数,2代表最大连续单词数,解释就上下面的例子:
我爱网易食堂 – > 我,爱,网易,食堂 – > 我,爱,我爱,网易,爱网易,网易,网易食堂
分词后的单词可以连续的再组成一个新的单词作为特征,在利用TfidfVectorizer计算这个新单词的TF-IDF值,这样就可以作为特征值使用,把所有的数据处理后就是如下的矩阵:
R m ∗ ( n + 1 ) = a 11 a 12 ⋯ a 1 n b 1 a 21 a 22 ⋯ a 2 n b 2 ⋮ ⋯ ⋱ ⋮ ⋮ a m 1 a m 2 ⋯ a m n b m \begin{aligned} \mathbb{R}^{m*(n+1)}=\begin{array} {|ccccc|} a_{11}&a_{12}&\cdots&a_{1n}&b_1\\ a_{21}&a_{22}&\cdots&a_{2n}&b_2\\ \vdots&\cdots&\ddots&\vdots&\vdots\\ a_{m1}&a_{m2}&\cdots&a_{mn}&b_m\\ \end{array} \end{aligned} Rm(n+1)=a11a21am1a12a22am2a1na2namnb1b2bm
其中 m = 9947 , n = 15547 m=9947,n=15547 m=9947n=15547

模型预测

拿训练的数据集来预测,训练好了模型之后开始用模型来预测训练集,了解预测的情况、准确率等等。

代码

import pandas as pd
import numpy as np
import jieba
import jieba.analyse
from sklearn.feature_extraction.text import  TfidfTransformer,TfidfVectorizer
from sklearn.metrics import mean_squared_error
from scipy.sparse import csr_matrix, hstack
from sklearn.metrics import f1_score,accuracy_score,classification_report
import sklearn.metrics as metrics
from sklearn.preprocessing import LabelEncoder
from collections import Counter
import pickle as pk
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import MultinomialNB
from sklearn.cross_validation import cross_val_score

# 数据路径
testFile="D:\\Data\\opinion_analyse\\test_public\\test_public.csv"
trainFile="D:\\Data\\opinion_analyse\\train\\train.csv"

subjectList=["动力","价格","内饰","配置","安全性","外观","操控","油耗","空间","舒适性"]


def micro_avg_f1(y_true, y_pred):
    return metrics.f1_score(y_true, y_pred, average='micro')

punct = set(u''':!),.:;?]}¢'"、。〉》」』】〕〗〞︰︱︳﹐、﹒
﹔﹕﹖﹗﹚﹜﹞!),.:;?|}︴︶︸︺︼︾﹀﹂﹄﹏、~¢
々‖•·ˇˉ―--′’”([{£¥'"‵〈《「『【〔〖([{£¥〝︵︷︹︻
︽︿﹁﹃﹙﹛﹝({“‘-—_…''')

def processing_data(data):
    wordList = jieba.cut(data)
    resultOne = [word for word in list(wordList) if word not in punct]
    return ' '.join(resultOne)

def get_data():
    train = pd.read_csv(trainFile)
    test = pd.read_csv(testFile)
    
    content = test['content']   # 测试数据集的正文
    
    lbl =  LabelEncoder()  # 用来将数据数值化
    # lbl.fit(train['subject'])      # 获取所有的subject
    lbl.fit(subjectList)
    nb_classes = len(list(lbl.classes_))  # 将subject 归并
    pk.dump(lbl, open('label_encoder.sav','wb'))  # 将数据序列化到磁盘中

    subject = lbl.transform(train['subject'])    # 数值化后的数字 输出给 subject,已经转化为class,然后把 替换为数值

    sentiment_value = []            # 情感值
    for i in list(train['sentiment_value']):
        sentiment_value.append(i)

    subject_num= []                 # 主题
    for i in subject:
        subject_num.append(i)

    #print(np.array(sentiment_value).reshape(-1,1)[:,0])
    data = pd.concat([train, test])   # 数据结果合并在一起,这个合并,两者有共同的列名就叠加在一起,不同的列名都算作不同列,没有数据的填NAN
    
    return data,train.shape[0],np.array(sentiment_value).reshape(-1,1)[:,0],test['content_id'],test['content'],np.array(subject_num).reshape(-1,1)[:,0]
     # .shape[0]  取行数


def pre_process():
  
    data,train_row_num,y,content_id,content,subject_value = get_data()
    print('train_row_num=',train_row_num)
    print("-------------")

    data['cut_comment'] = data['content'].map(processing_data)  # 分词
    
    print('TfidfVectorizer')
    tf = TfidfVectorizer(min_df=3,max_df= 0.001,max_features=None,ngram_range=(1,2),analyzer='word')   #  按照字符来做特征,最大范围是两个字符,最小是一个字符
    discuss_tf = tf.fit_transform(data['cut_comment'])
    return discuss_tf[:train_row_num],discuss_tf[train_row_num:],y,content_id,content,subject_value       
    
    #  nrw_train : 表示 训练集的行数,也就是记录个数


#预处理
train,test,sentiment_value,content_id,content,subject_value= pre_process()

xtrain, xvalid, ytrain, yvalid = train_test_split(train, subject_value, stratify=subject_value, random_state=42,test_size=0.3, shuffle=True)

print('xtrain.shape=',xtrain.shape)
model_NB = MultinomialNB(alpha=1.0, class_prior=None, fit_prior=True)
model_NB.fit(xtrain, ytrain)  #特征数据直接灌进来
result = model_NB.predict(xtrain)

num=0
for i in range(result.shape[0]):
    if result[i] == ytrain[i]:
        num+=1

print('num=',num,'rowNum=',len(result),"pre=",(num/len(result)))
print(res[:2])
print(ytrain[:2])

#print("多项式贝叶斯分类器20折交叉验证得分: ", np.mean(cross_val_score(model_NB, xtrain, ytrain, cv=20, scoring='roc_auc')))

参考博客

BCDI2018-汽车行业用户观点主题及情感识别
数据集
scikit-learn 朴素贝叶斯类库使用小结
朴素贝叶斯的三个常用模型:高斯、多项式、伯努利
数据集也可以去官网下,官网就是第一个链接。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值