综合设计——多源异构数据采集与融合应用综合实践

发布时间 2023-12-14 23:22:31作者: boki酱
这个项目属于哪个课程 2023数据采集与融合技术
作业要求 综合设计——多源异构数据采集与融合应用综合实践
组名 汪汪队
项目主题 微博评论情感分析
项目简介 项目需求:1. 情绪监测、2. 品牌声誉管理、3. 市场分析、4. 舆论引导、5. 个性化推荐、6. 社交网络分析

项目目标: 1. 情绪识别、2. 情感分类、3. 观点提取、4. 情绪监测、5. 市场趋势预测、6. 个性化推荐、7. 社交网络分析

项目开展技术路线:1. 数据收集、2. 数据预处理、3. 模型选择与训练、4. 情感分析、5. 结果分析与可视化、6. 搭建网页
团队成员学号 组长:102102130张明康

组员:
102102131张铭玮
102102128汪伟杰
102102129张昊
102102133陈灿铭
这个项目的目标 1. 情绪识别:准确识别评论表达的情绪倾向,如正面情绪、负面情绪或中性情绪。这是情感分析的基础任务,也是其他应用场景的前提。
2. 情感分类:对评论进行细致的情感分类,如愤怒、喜悦、悲伤等,以便更深入地了解用户的情感状态。
3. 观点提取:从评论中提取出用户对某一事件、话题或产品的观点和看法,为舆情分析、市场调查等领域提供有价值的信息。
4. 情绪监测:通过对微博评论的情感分析,实时监测公众情绪的变化趋势,为情绪监测和舆情管理提供数据支持。
5. 市场趋势预测:通过分析用户对产品或服务的情感态度,预测市场趋势和消费者需求,为企业市场策略制定提供参考。
6. 个性化推荐:根据用户的情感倾向,为用户推荐更符合其兴趣和需求的内容,提高用户体验。
7. 社交网络分析:通过分析微博评论的情感倾向,研究社交网络中用户之间的关系和影响力,为社交网络分析提供数据支持。
参考文献 【深度学习】详解TextCNN
[NLP] 文本分类之TextCNN模型原理和实现(超详细)
Python数据可视化:折线图、柱状图、饼图代码
【干货】Python:wordcloud库绘制词云图
python绘制雷达图(详细)

项目介绍

微博评论情感分析项目是基于自然语言处理(NLP)技术,对微博平台上的用户评论进行情感倾向性判定的研究与应用。
项目的主要目标是通过对微博评论的情感分析,了解广大用户的情绪状态、观点倾向,从而为情绪监测、品牌声誉管理、市场分析等领域提供有价值的数据支持。
具体而言,本项目包括以下几个阶段:


  1. 数据收集:通过爬虫技术或API接口从微博平台获取评论数据。考虑到数据的多样性和真实性,往往会选取带有用户图片和文本双重信息的评论数据。
  2. 数据预处理:清洗数据,去除噪声,如HTML标签、特殊字符等;然后进行分词处理,把文本分解为更易分析的单元,如词、短语等。
  3. 特征工程:从预处理后的文本中提取特征,如词频、词向量、语法结构等,为机器学习模型准备输入。
  4. 模型训练:使用机器学习算法TestCNN训练模型。深度学习框架常被用于构建复杂的网络模型。
  5. 情感分析:将训练好的模型应用于新的数据集上,输出情感分析结果,如正面情绪、负面情绪或中性情绪。
  6. 结果分析与应用:根据模型输出的情感分析结果,进行数据可视化、趋势分析等,为情绪监测、品牌管理、市场分析等领域提供依据。
  7. 搭建网页:使用streamlit搭建网页,展示爬取的数据以及可视化结果。

微博评论情感分析项目在实施过程中可能会遇到数据量大、语言多样、情感表达复杂等挑战。因此,项目往往需要结合最新的NLP技术,如深度学习、迁移学习等,以及领域专业知识,才能达到较好的分析效果。

项目需求

微博评论情感分析的需求主要来源于以下几个方面:


  1. 情绪监测:通过分析微博评论的情感倾向,可以了解公众对于某一事件、话题或产品的情绪态度,为情绪监测提供数据支持。
  2. 品牌声誉管理:企业可以通过微博评论情感分析了解消费者对其产品或服务的满意度和不满意度,以及消费者对品牌形象的评价,从而更好地进行品牌声誉管理。
  3. 市场分析:通过对微博评论的情感分析,可以了解消费者对某一产品或服务的需求、喜好和期望,为企业市场策略的制定提供参考。
  4. 舆论引导:政府和媒体可以通过微博评论情感分析了解公众对某一事件或政策的看法和态度,从而进行舆论引导和舆情管理。
  5. 个性化推荐:微博平台可以根据用户的评论情感倾向,为用户推荐更符合其兴趣和需求的内容,提高用户体验。
  6. 社交网络分析:通过分析微博评论的情感倾向,可以了解社交网络中用户之间的关系和影响力,为社交网络分析提供数据支持。

为了满足上述需求,微博评论情感分析项目需要具备以下特点:

  • 准确性:能够准确识别微博评论的情感倾向,避免误判和漏判。
  • 实时性:能够快速处理大量评论数据,实时反馈情感分析结果。
  • 鲁棒性:能够应对不同语言风格、语境和噪声环境的干扰,保持稳定的数据分析效果。
  • 可扩展性:能够适应不同领域的需求,灵活扩展情感分析的应用范围。
  • 隐私保护:在数据收集和分析过程中,确保用户隐私得到保护,遵守相关法律法规。

项目目标

微博评论情感分析的目标主要包括以下几点:


  1. 情绪识别:准确识别评论表达的情绪倾向,如正面情绪、负面情绪或中性情绪。这是情感分析的基础任务,也是其他应用场景的前提。
  2. 情感分类:对评论进行细致的情感分类,如愤怒、喜悦、悲伤等,以便更深入地了解用户的情感状态。
  3. 观点提取:从评论中提取出用户对某一事件、话题或产品的观点和看法,为舆情分析、市场调查等领域提供有价值的信息。
  4. 情绪监测:通过对微博评论的情感分析,实时监测公众情绪的变化趋势,为情绪监测和舆情管理提供数据支持。
  5. 市场趋势预测:通过分析用户对产品或服务的情感态度,预测市场趋势和消费者需求,为企业市场策略制定提供参考。
  6. 个性化推荐:根据用户的情感倾向,为用户推荐更符合其兴趣和需求的内容,提高用户体验。
  7. 社交网络分析:通过分析微博评论的情感倾向,研究社交网络中用户之间的关系和影响力,为社交网络分析提供数据支持。

总之,微博评论情感分析的目标是通过对评论数据的情感分析,为情绪监测、市场分析、个性化推荐等各个领域提供有价值的信息和数据支持。

项目开展技术路线

微博评论情感分析的项目开展技术路线可以分为以下几个阶段:


  1. 数据收集
    • 使用爬虫技术或微博API获取微博评论数据。
  2. 数据预处理
    • 对原始数据进行预处理
  3. 模型选择与训练
    • 使用TestCNN模型进行训练
  4. 情感分析
    • 将训练好的模型应用于新的数据集上,输出情感分析结果
  5. 结果分析与可视化
    • 对情感分析结果进行数据可视化、趋势分析等,以便更直观地展示和分析数据。
  6. 搭建网页
    • 使用streamlit搭建网页,展示爬取的数据以及可视化结果

在整个技术路线中,可能需要应对数据量大、语言多样、情感表达复杂等挑战。因此,项目开展过程中需要结合最新的自然语言处理(NLP)技术和领域专业知识,以达到较好的情感分析效果。

我完成的任务

数据的采集与部分图形绘制

爬取微博评论和图片

import requests
import selenium
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.common.by import By
import time
import csv
from lxml import etree
import os

headers = {
    # 登录添加自己的cookies
    'Cookie': '',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36',
}
 
url = 'https://m.weibo.cn/comments/hotflow'
f = open('spider.csv', mode='w+', encoding='utf-8', newline='')
writer = csv.writer(f)

def get(msgid):
    data = {
        'id': msgid,
        'mid': msgid,
        'max_id_type': 0,
    }
    print(type(data['id']))
    resp = requests.get(url=url, headers=headers, params=data).json()
    max_id = resp['data']['max_id']
    mid_t = resp['data']['max_id_type']
    data_list = resp['data']['data']
    for dicts in data_list:
        
        testt = dicts['source'].replace("来自","")
        # user_name = dicts['user']['screen_name']  # 用户名
        like_count = dicts['like_count']  # 点赞该评论数
        text = dicts['text'].split('<')[0].replace(",","z")  # 评论
        # user_url = dicts['user']['profile_url']  # 用户微博链接
        created_at = dicts['created_at']  # 评论时间
        writer.writerow([text,testt, created_at,like_count])
        # print(1)
        # time.sleep(3)  # 睡一下
        # print(2)
        # print( text + " "+ str(like_count)+" "+ testt +" "+str(created_at))
    # input()
    get2(max_id,msgid,mid_t)
 
def get2(max_id,msgid,mid_t):
    a = 1
    mid_t = mid_t
    while True:
        data2 = {
            'id': msgid,
            'mid': msgid,
            'max_id': max_id,
            'max_id_type': mid_t
        }
        # resp2 = requests.get(url=url, headers=headers, params=data2).json()
        resp2 = requests.get(url=url, headers=headers, params=data2).json()
        if resp2['ok'] != 1:
            break
        print(resp2)
        # input()
        max_id = resp2['data']['max_id']
        mid_t = resp2['data']['max_id_type']
        # print(resp2)
        data_list = resp2['data']['data']
        for dicts in data_list:
            testt = dicts['source'].replace("来自","")
            # user_name = dicts['user']['screen_name']  # 用户名
            like_count = dicts['like_count']  # 点赞该评论数
            text = dicts['text'].split('<')[0].replace(",","")  # 评论
            # user_url = dicts['user']['profile_url']  # 用户微博链接
            created_at = dicts['created_at']  # 评论时间
            writer.writerow([text,testt, created_at,like_count])
            # print( text + " "+ str(like_count)+" "+ testt +" "+str(created_at))
        if a == 20:  # 我没爬完,10页左右
            break
        if data2['max_id_type'] != 0:
            break
        a += 1

def get_images_selenium(msgid):
    if not os.path.exists('images'):
        os.makedirs('images')

    chrome_path = r'C:\Users\Jack\AppData\Local\Programs\Python\Python310\Scripts\chromedriver.exe'
    chrome_options = Options()
    chrome_options.add_argument('--headless') 
    chrome_options.add_argument('--disable-gpu')
    driver= webdriver.Chrome(options=chrome_options,executable_path=chrome_path)

    try:
        url = f'https://m.weibo.cn/detail/{msgid}'
        driver.get(url)

        time.sleep(5)

        img_elements = driver.find_elements(By.XPATH, "//div/ul/li/div/img[@class='f-bg-img']")
        page_source = driver.page_source
        print(page_source)
        print(img_elements)

        for index, img_element in enumerate(img_elements):
            src = img_element.get_attribute('src')
            print(src)
            img_name = f"{msgid}_img_{index}"

            img_data = requests.get(url=src, headers=headers).content
            img_path = f'./images/{img_name}.jpg'
            with open(img_path, 'wb') as fp:
                fp.write(img_data)
                print(f"{img_name} downloaded successfully!")

    finally:
        driver.quit()

def main(spidermsg):
    headers['Referer'] = spidermsg
    msgid = headers['Referer'].split('detail/')[1]
    get(int(msgid))
    get_images_selenium(msgid)
    return "数据收集成功!"
 
# if __name__ == '__main__':
#     main()
  1. 使用微博评论的api接口
  2. 第一页的评论是没有max_id,返回的响应max_id为下一页评论的params
  3. 层层获取一页的评论知道达到规定的页数或标识改变

selenium图片爬取

import requests
import selenium
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.common.by import By
import time
import os

headers = {
    
    'Cookie': '',
    'Referer': 'https://weibo.com/',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36',
}

def get_images_selenium(msgid):
    if not os.path.exists('images'):
        os.makedirs('images')

    chrome_path = r'C:\Users\Jack\AppData\Local\Programs\Python\Python310\Scripts\chromedriver.exe'
    chrome_options = Options()
    chrome_options.add_argument('--headless') 
    chrome_options.add_argument('--disable-gpu')
    driver= webdriver.Chrome(options=chrome_options,executable_path=chrome_path)

    try:
        url = f'https://m.weibo.cn/detail/{msgid}'
        driver.get(url)

        time.sleep(5)

        img_elements = driver.find_elements(By.XPATH, "//div/ul/li/div/img[@class='f-bg-img']")
        page_source = driver.page_source
        print(page_source)
        print(img_elements)

        for index, img_element in enumerate(img_elements):
            src = img_element.get_attribute('src')
            print(src)
            img_name = f"{msgid}_img_{index}"

            img_data = requests.get(url=src, headers=headers).content
            img_path = f'./images/{img_name}.jpg'
            with open(img_path, 'wb') as fp:
                fp.write(img_data)
                print(f"{img_name} downloaded successfully!")

    finally:
        driver.quit()

# if __name__ == '__main__':
#     get_images_selenium("4978555123404345")
  1. selenium爬取图片遇到的问题是图片反盗,头加Referer伪装域名即可

图形绘制

def like_emo(str,lk_em_dict):
    # lk_em_dict = {}s
    j = str.split(',')[4]
    emo = j.split('\n')[0]
    lkcnt = str.split(',')[3]
    if (emo in lk_em_dict) == True:
        lk_em_dict[emo] += int(lkcnt)
    else:
        lk_em_dict[emo] = int(lkcnt)
  1. 该函数从输入字符串中提取点赞数和情感信息,并更新字典 lk_em_dict,其中存储了不同情感类别的点赞总数。

  2. 这个函数是为了后续生成点赞-情感关系的柱状图。


def lk_em_graphic(dic):
a=[]
b=[]

for key in dic:
    a.append(key)        
    b.append(dic[key])
size=[]
t=sum(b)#统计总的发表篇幅
label=a

plt.rcParams['font.sans-serif']=['Microsoft JhengHei']
#计算每种类型所占的比例
for u in b:
    size.append(u)
    # plt.plot(size)
colors = ["#5D7599","#ABB6C8","#DADADA","#F7F0C6","#C2C4B6","#B6B4C2","#AAC9CE"]
plt.figure(figsize = (10,10))  
plt.title("情绪-点赞关系柱状图", fontsize=15,fontweight='bold')
plt.xlabel("情绪", fontsize=15,fontweight='bold')
plt.ylabel("总点赞数", fontsize=15,fontweight='bold')
# 修改坐标轴字体及大小
plt.yticks(fontproperties='Times New Roman', size=15,weight='bold')#设置大小及加粗
plt.xticks(fontproperties='Times New Roman', size=15)
# 设置标题
plt.rcParams['font.sans-serif'] = ['KaiTi']  # 用来正常显示中文标签,如果想要用新罗马字体,改成 Times New Roman
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
plt.tight_layout()  # 解决绘图时上下标题重叠现象

#画线
plt.bar(a, b, color=colors, width=0.5)
# plt.plot(a,b)
plt.savefig("pics/lk_emo.jpg",bbox_inches='tight',pad_inches=0.0) 
# plt.show()
c = (
    Bar(init_opts=opts.InitOpts(
                            width='700px',
                            height='400px',
                            page_title='page',
                            )).add_xaxis(a)
    .add_yaxis("点赞数",b)
    .render("emolk.html")

)
  1. 接受一个字典 dic,其中包含不同情感类别的点赞数信息。

  2. 使用 Matplotlib 生成情感-点赞关系的柱状图,并将图表保存为 HTML 文件。

def wdc(str):
ls = jieba.lcut(str) # 生成分词列表
text = ' '.join(ls) # 连接成字符串


stopwords = ["我","你","她","的","是","了","在","也","和","就","都","这","啊啊啊"] # 去掉不需要显示的词
import numpy as np
from PIL import Image
mk = np.array(Image.open("wdbg.png"))
wc = wordcloud.WordCloud(font_path="msyh.ttc",
mask = mk,
width = 500,
height = 500,
background_color='white',
max_words=200,
stopwords=stopwords)
# msyh.ttc电脑本地字体,写可以写成绝对路径
wc.generate(text) # 加载词云文本
wc.to_file("pics/wdc.png") # 保存词云文件
  1. 该函数使用 jieba 进行中文分词,生成词云图。在生成词云时,去除了一些常见的停用词,并指定了字体、背景图等参数。

  2. 最后,将生成的词云图保存为图片文件。

参考文献

  1. Python数据可视化:折线图、柱状图、饼图代码

  2. 【干货】Python:wordcloud库绘制词云图

  3. 解决微博图床 403 全失效

  4. 爬虫之微博评论爬取方法