当前位置:   article > 正文

python数据分析之利用多种机器学习方法实现文本分类、情感预测_python进行文本情感分析

python进行文本情感分析

       大家好,我是带我去滑雪!

       文本分类是一种机器学习和自然语言处理(NLP)任务,旨在将给定的文本数据分配到预定义的类别或标签中。其目标是为文本数据提供自动分类和标注,使得可以根据其内容或主题进行组织、排序和分析。文本分类在各种应用场景中广泛应用,包括情感分析、垃圾邮件过滤、新闻分类、推荐系统等。
       文本分类的关键步骤包括:

  • 数据准备:准备训练集和测试集的文本数据,每个文本数据都经过标记或分类。
  • 特征提取:从文本数据中提取有用的特征来表示文本。常见的特征提取方法包括词袋模型(Bag-of-Words Model)、TF-IDF(Term Frequency-Inverse Document Frequency)、词嵌入(Word Embeddings)等。
  • 训练模型:使用已标记的训练数据来训练分类模型。常见的机器学习算法包括朴素贝叶斯(Naive Bayes)、支持向量机(Support Vector Machines,SVM)、决策树(Decision Trees)、随机森林(Random Forests)等。最近,深度学习方法如卷积神经网络(Convolutional Neural Networks,CNN)和循环神经网络(Recurrent Neural Networks,RNN)也被广泛应用于文本分类任务。
  • 模型评估:使用预留的测试数据对训练好的模型进行评估,计算分类模型的准确性、精确度、召回率等指标。
  • 预测和应用:使用已训练的模型对新的未标记文本数据进行分类和预测。

       本期首先利用python抓取百度贴吧中的评论获得文本数据,再对文本数据进行中文分词、数据清洗、特征提取、TF-IDF权重计算等数据预处理,再进行一定的数据分析和数据可视化,最后运用朴素贝叶斯、神经网络、支持向量机、随机森林、逻辑回归、K近邻、决策树、梯度提升共计8种机器学习对文本数据进行分类。

目录

1、抓取百度贴吧评论获取文本数据

(1)代码

(2)部分数据展示

2、数据预处理

(1)中文分词

(2)文本情感打分

(3)将文本数据转化为向量

(4)计算TF-IDF权重

 3、数据分析与可视化

(1)统计得分区间数量

(2)得分区间数据可视化

(3)绘制词云图

(4)关键词TOP10

(5)计算积极评论与消极评论数量并数据可视化

4、使用8种机器学习对文本数据进行分类

(1)随机划分,按总样本数的20%划分,即测试集(784个)与训练集(3135个)

(2)调用模型,并对比测试集精度


1、抓取百度贴吧评论获取文本数据

(1)代码

import requests

import time

from bs4 import BeautifulSoup

def get_html(url):

    try:

        kv = {'user-agent':'Mozilla/4.0'} #伪装客户端

        r = requests.get(url,headers = kv,timeout=30)

        r.raise_for_status()

        r.encoding = 'UTF-8'

        #print(r.text[:1000])

        return r.text

    except:

        return "ERROR"

def get_content(url):

    comments = [] 

    html = get_html(url)

    soup = BeautifulSoup(html,'lxml')

    #with open('b.txt','a+',encoding='utf-8') as f1:

            #f1.write(soup.prettify())

    liTags = soup.find_all('li', attrs={'class': 'j_thread_list clearfix thread_item_box'})

    for li in liTags:

        comment = {} 

        try:

            comment['title'] = li.find('a',attrs={'class':'j_th_tit'}).text.strip()

            comment['link'] = "http://tieba.baidu.com" + li.find('a',attrs={'class': 'j_th_tit'})['href']

            comment['name'] = li.find('span',attrs={'class': 'tb_icon_author'}).text.strip()

            comment['time'] = li.find('span', attrs={'class': 'pull-right is_show_create_time'}).text.strip()

            comment['replyNum'] = li.find('span', attrs={'class': 'threadlist_rep_num center_text'}).text.strip()

            comments.append(comment)

        except:

            print('出了点小问题')

    return comments

def Out2File(dict):

    with open('大学吧的评论最新.txt','a+',encoding='utf-8') as f:

        for comment in dict:

            f.write('标题: {} \t 链接:{} \t 发帖人:{} \t 发帖时间:{} \t 回复数量: {} \n'.format(

                comment['title'], comment['link'], comment['name'], comment['time'], comment['replyNum']))

        print('当前页面爬取完成')

       

def main(base_url, deep):

    url_list = [] #存取需要爬取的帖子链接

    for i in range(0, deep):

        url_list.append(base_url + '&pn=' + str(50 * i))

    print('所有的网页已经下载到了本地,开始筛选信息。。。。')

    #循环写入数据

    for url in url_list:

        content = get_content(url)

        Out2File(content)

    print('所有信息都已经保存完毕!')

base_url = 'http://tieba.baidu.com/f?kw=大学&ie=utf-8&'

deep =200

if __name__ == '__main__':

main(base_url,deep)

输出结果:

所有的网页已经下载到了本地,开始筛选信息。。。。
当前页面爬取完成
当前页面爬取完成
当前页面爬取完成
当前页面爬取完成
当前页面爬取完成
当前页面爬取完成
当前页面爬取完成
当前页面爬取完成
当前页面爬取完成
当前页面爬取完成
当前页面爬取完成
当前页面爬取完成
当前页面爬取完成

             eq?%5Cvdots

(2)部分数据展示

1好好画画啦
2求各专业大佬
3欢迎报考北邮
4话费充值需要dd
5兼职有没有来的
6在校大学生一枚
7滴滴,喜欢的看过来
8大学生进!!!
9有什么快速挣钱的好方法?
10大学,要挣米,来,???带一手
11大学宿舍限电是普遍现象吗,一般限多少瓦
12你们认为大学生打工,什么工作最好
13家人们该不该
14兼职介绍,有没有
15稳稳的一天
16创建一个资源共享群,亲们留下你们的微信,我拉你们进群
17假期的小工作
18寻说明书系统说明,撰写选手
19加QQ!!!..
20有兼职群吗

2、数据预处理

(1)中文分词

        爬取到的评论,使用Python爬取了中文数据集之后,首先需要对数据集进行中文分词处理。由于英文中的词与词之间是采用空格关联的,按照空格可以直接划分词组,所以不需要进行分词处理,而中文汉字之间是紧密相连的,并且存在语义,词与词之间没有明显的分隔点,所以需要借助中文分词技术将语料中的句子按空格分割,变成一段段词序列。使用中文分词技术及Jiaba中文分词工具。

       分词后的评论并不是所有的词都与文档内容相关,往往存在一些表意能力很差的辅助性词语,比如中文词组“我们”、“的”、“可以”等,英文词汇“a”、“the”等。这类词在自然语言处理或数据挖掘中被称为停用词(Stop Words),它们是需要进行过滤的。通常借用停用词表或停用词字典进行过滤,这里所用的停用词表可以在文末进行获取。

 import pandas as pd

import numpy as np

import matplotlib.pyplot as plt

import seaborn as sns

import networkx as nx

plt.rcParams['font.sans-serif'] = ['KaiTi']  #指定默认字体 SimHei黑体

plt.rcParams['axes.unicode_minus'] = False   #解决保存图像是负号'

import jieba

stop_list  = pd.read_csv("停用词.txt",index_col=False,quoting=3,sep="\t",names=['stopword'], encoding='utf-8')

#Jieba分词函数

def txt_cut(juzi):

    lis=[w for w in jieba.lcut(juzi) if w not in stop_list.values]

    return (" ").join(lis)

df=pd.read_csv('E:/工作/硕士/data.csv',encoding="ANSI")

df['cutword']=df['PL'].astype('str').apply(txt_cut)

df=df[['PL','cutword']]

df

输出结果:

8364555081d74ef9aa300676245a3a71.png

(2)文本情感打分

import pandas as pd

data1 = pd.read_csv('E:/工作/硕士/博客//data.csv',encoding="ANSI")

from snownlp import SnowNLP

data1['emotion'] = data1['PL'].apply(lambda x:SnowNLP(x).sentiments)

data1.to_excel('评论情感打分值.xlsx',index=False)#保存数据,具体数据看表格

      部分结果展示:

序号PLemotion
1周末了,同学们,哪里可以下单机游戏玩?0.936292288
2大学生等一个0.753614865
3每位同学顺利毕业??是我最大的心愿??0.994685253
4了解过咸鱼吧0.5
5学习通看完了吗,没看完找我呀0.761398932
6特凉列肮删0.066063183
7有没有安徽的0.77536362
8寄快递也可以赚钱,你们满意嘛?0.112413565
9618可以组队的羊毛群,(超红口令很早就知道)0.100694453
10大家晚上好0.529099344
11同学们大家好0.87008235
12放纵的代价0.738870215
13大学生第一次上台演讲ppt0.853786676
14有没有正常的0.353878603
15纯绿色搬砖,多劳多得0.154165573

(3)将文本数据转化为向量

from sklearn.feature_extraction.text import TfidfVectorizer

from sklearn.model_selection import train_test_split

#取出X和y

X = df['text']

y = df['label']

#创建一个TfidfVectorizer的实例

vectorizer = TfidfVectorizer()

#使用Tfidf将文本转化为向量

X = vectorizer.fit_transform(X)

#看看特征形状

X.shape

(4)计算TF-IDF权重

data1 = {'word': vectorizer.get_feature_names_out(),

        'tfidf': X.toarray().sum(axis=0).tolist()}

df1 = pd.DataFrame(data1).sort_values(by="tfidf" ,ascending=False,ignore_index=True)

df1

       部分结果展示:

7550e7c7ebca4818b3f8a8b91e0ca65c.png

 3、数据分析与可视化

(1)统计得分区间数量

from itertools import groupby

score_list =data1['emotion']

step = 0.1

for k, g in groupby(sorted(score_list), key=lambda x: x//step):

print('{}-{}: {}'.format(k*step, (k+1)*step+1, len(list(g))))

输出结果:

5a0d34c6f8d240b1a8eadc84d6a2392f.png

(2)得分区间数据可视化

%matplotlib inline

from matplotlib import pyplot as plt

from matplotlib import font_manager

a = ["0-0.1", "0.1-0.2","0.2-0.3","0.3-0.4","0.4-0.5","0.5-0.6","0.6-0.7","0.7-0.8","0.8-0.9","0.9-1"]

b = [265,248,259,329,348,319,329,375,439,1064]

plt.figure(figsize=(20,8),dpi=300)

my_font=font_manager.FontProperties(fname=r"C:\Windows\Fonts\STSONG.TTF",size=12)

rects=plt.bar(a,b,width=0.3,color=['red','green','blue','cyan','yellow','gray'])

plt.xticks(a,fontproperties=my_font,rotation=45)

plt.xlabel("情感得分区间",fontproperties=my_font,fontsize=20)

plt.ylabel("数量",fontproperties=my_font,fontsize=20) #rotation='horizontal'

#plt.grid(alpha=0.5)

for rect in rects:

    y=rect.get_height()

    x=rect.get_x()+rect.get_width()/2

    plt.text(x,y+0.5,str(y),ha="center",fontsize=15)

plt.title("情感分区间条形图",fontproperties=my_font,fontsize=20)

plt.savefig("squares2.png",

            bbox_inches ="tight",

            pad_inches = 1,

            transparent = True,

            facecolor ="w",

            edgecolor ='w',

            dpi=300,

            orientation ='landscape')

输出结果:

5b1b2ae7a3a148b186e3ddd82e7d23f3.png

(3)绘制词云图

from wordcloud import WordCloud

import jieba

w = WordCloud(font_path="msyh.ttc",background_color="white",max_words=500,width=1000,height=600)   #font_path="msyh.ttc",设置字体,否则显示不出来

text = ''

for s in data1['PL']:

    text += s

data_cut = ' '.join(jieba.lcut(text))

w.generate(data_cut)

image = w.to_file('词云图.png')

输出结果:

75ae78745f15490caa5d742a00faee43.png

(4)关键词TOP10

from jieba import analyse

key_words = jieba.analyse.extract_tags(sentence=text, topK=10, withWeight=True, allowPOS=())

key_words

输出结果:

c3b91d2cf81e4bdfabf40148b6e86b94.png

(5)计算积极评论与消极评论数量并数据可视化

#计算积极评论与消极评论各自的数目

pos = 0

neg = 0

for i in data1['emotion']:

    if i >= 0.5:

        pos += 1

    else:

        neg += 1

print('积极评论,消极评论数目分别为:')

pos,neg

输出结果:

631ff73d18214ab49aca862b5c3ba94c.png

import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif']=['SimHei']

plt.rcParams['axes.unicode_minus'] = False

pie_labels='postive','negative'

plt.pie([pos,neg],labels=pie_labels,autopct='%1.1f%%',shadow=True)

plt.savefig("squares3.png",

            bbox_inches ="tight",

            pad_inches = 1,

            transparent = True,

            facecolor ="w",

            edgecolor ='w',

            dpi=300,

            orientation ='landscape')

输出结果:

6695cf8076094d3481c6d9cd0578dc78.png

4、使用8种机器学习对文本数据进行分类

(1)随机划分,按总样本数的20%划分,即测试集(784个)与训练集(3135个)

 X_train, X_test, y_train, y_test =train_test_split(X,y,test_size=0.2,stratify=y,random_state = 0)

#可以检查一下划分后数据形状

X_train.shape,X_test.shape, y_train.shape, y_test.shape

(2)调用模型,并对比测试集精度

from sklearn.linear_model import LogisticRegression

from sklearn.naive_bayes import MultinomialNB

from sklearn.neighbors import KNeighborsClassifier

from sklearn.tree import DecisionTreeClassifier

from sklearn.ensemble import RandomForestClassifier

from sklearn.ensemble import GradientBoostingClassifier

from sklearn.svm import SVC

from sklearn.neural_network import MLPClassifier

model1 =  LogisticRegression(C=1e10,max_iter=10000)
model2 = MultinomialNB()
model3 = KNeighborsClassifier(n_neighbors=50)
model4 = DecisionTreeClassifier(random_state=77)
model5= RandomForestClassifier(n_estimators=500,  max_features='sqrt',random_state=10)
model6 = GradientBoostingClassifier(random_state=123)
model9 = SVC(kernel="rbf", random_state=77)
model10 = MLPClassifier(hidden_layer_sizes=(16,8), random_state=77, max_iter=10000)
model_list=[model1,model2,model3,model4,model5,model6,model9,model10]
model_name=['逻辑回归','朴素贝叶斯','K近邻','决策树','随机森林','梯度提升','支持向量机','神经网络']
scores=[]
for i in range(len(model_list)):
    model_C=model_list[i]
    name=model_name[i]
    model_C.fit(X_train, y_train)
    s=model_C.score(X_test, y_test)
    scores.append(s)
    print(f'{name}方法在测试集的准确率为{round(s,3)}')
plt.figure(figsize=(7,3),dpi=128)
sns.barplot(y=model_name,x=scores,orient="h")
plt.xlabel('模型准确率')
plt.ylabel('模型名称')
plt.xticks(fontsize=10,rotation=45)
plt.title("不同模型文本分类准确率对比")
plt.savefig("squares4.png",
            bbox_inches ="tight",
            pad_inches = 1,
            transparent = True,
            facecolor ="w",
            edgecolor ='w',
            dpi=300,
            orientation ='landscape')

输出结果:

7fe30765acb6449ca2d9579415eb4998.png

需要数据集的家人们可以去百度网盘(永久有效)获取:

链接:https://pan.baidu.com/s/1E59qYZuGhwlrx6gn4JJZTg?pwd=2138
提取码:2138 


更多优质内容持续发布中,请移步主页查看。

若有问题可邮箱联系:1736732074@qq.com 

博主的WeChat:TCB1736732074

   点赞+关注,下次不迷路!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/72825
推荐阅读
相关标签
  

闽ICP备14008679号