這個專案屬於哪個課程 | 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)技術,對微博平臺上的使用者評論進行情感傾向性判定的研究與應用。
專案的主要目標是透過對微博評論的情感分析,瞭解廣大使用者的情緒狀態、觀點傾向,從而為情緒監測、品牌聲譽管理、市場分析等領域提供有價值的資料支援。
具體而言,本專案包括以下幾個階段:
- 資料收集:透過爬蟲技術或API介面從微博平臺獲取評論資料。考慮到資料的多樣性和真實性,往往會選取帶有使用者圖片和文字雙重資訊的評論資料。
- 資料預處理:清洗資料,去除噪聲,如HTML標籤、特殊字元等;然後進行分詞處理,把文字分解為更易分析的單元,如詞、短語等。
- 特徵工程:從預處理後的文字中提取特徵,如詞頻、詞向量、語法結構等,為機器學習模型準備輸入。
- 模型訓練:使用機器學習演演算法TestCNN訓練模型。深度學習框架常被用於構建複雜的網路模型。
- 情感分析:將訓練好的模型應用於新的資料集上,輸出情感分析結果,如正面情緒、負面情緒或中性情緒。
- 結果分析與應用:根據模型輸出的情感分析結果,進行資料視覺化、趨勢分析等,為情緒監測、品牌管理、市場分析等領域提供依據。
- 搭建網頁:使用streamlit搭建網頁,展示爬取的資料以及視覺化結果。
微博評論情感分析專案在實施過程中可能會遇到資料量大、語言多樣、情感表達複雜等挑戰。因此,專案往往需要結合最新的NLP技術,如深度學習、遷移學習等,以及領域專業知識,才能達到較好的分析效果。
專案需求
微博評論情感分析的需求主要來源於以下幾個方面:
- 情緒監測:透過分析微博評論的情感傾向,可以瞭解公眾對於某一事件、話題或產品的情緒態度,為情緒監測提供資料支援。
- 品牌聲譽管理:企業可以透過微博評論情感分析瞭解消費者對其產品或服務的滿意度和不滿意度,以及消費者對品牌形象的評價,從而更好地進行品牌聲譽管理。
- 市場分析:透過對微博評論的情感分析,可以瞭解消費者對某一產品或服務的需求、喜好和期望,為企業市場策略的制定提供參考。
- 輿論引導:政府和媒體可以透過微博評論情感分析瞭解公眾對某一事件或政策的看法和態度,從而進行輿論引導和輿情管理。
- 個性化推薦:微博平臺可以根據使用者的評論情感傾向,為使用者推薦更符合其興趣和需求的內容,提高使用者體驗。
- 社交網路分析:透過分析微博評論的情感傾向,可以瞭解社交網路中使用者之間的關係和影響力,為社交網路分析提供資料支援。
為了滿足上述需求,微博評論情感分析專案需要具備以下特點:
- 準確性:能夠準確識別微博評論的情感傾向,避免誤判和漏判。
- 實時性:能夠快速處理大量評論資料,實時反饋情感分析結果。
- 魯棒性:能夠應對不同語言風格、語境和噪聲環境的干擾,保持穩定的資料分析效果。
- 可擴充套件性:能夠適應不同領域的需求,靈活擴充套件情感分析的應用範圍。
- 隱私保護:在資料收集和分析過程中,確保使用者隱私得到保護,遵守相關法律法規。
專案目標
微博評論情感分析的目標主要包括以下幾點:
- 情緒識別:準確識別評論表達的情緒傾向,如正面情緒、負面情緒或中性情緒。這是情感分析的基礎任務,也是其他應用場景的前提。
- 情感分類:對評論進行細緻的情感分類,如憤怒、喜悅、悲傷等,以便更深入地瞭解使用者的情感狀態。
- 觀點提取:從評論中提取出使用者對某一事件、話題或產品的觀點和看法,為輿情分析、市場調查等領域提供有價值的資訊。
- 情緒監測:透過對微博評論的情感分析,實時監測公眾情緒的變化趨勢,為情緒監測和輿情管理提供資料支援。
- 市場趨勢預測:透過分析使用者對產品或服務的情感態度,預測市場趨勢和消費者需求,為企業市場策略制定提供參考。
- 個性化推薦:根據使用者的情感傾向,為使用者推薦更符合其興趣和需求的內容,提高使用者體驗。
- 社交網路分析:透過分析微博評論的情感傾向,研究社交網路中使用者之間的關係和影響力,為社交網路分析提供資料支援。
總之,微博評論情感分析的目標是透過對評論資料的情感分析,為情緒監測、市場分析、個性化推薦等各個領域提供有價值的資訊和資料支援。
專案開展技術路線
微博評論情感分析的專案開展技術路線可以分為以下幾個階段:
- 資料收集:
- 使用爬蟲技術或微博API獲取微博評論資料。
- 資料預處理:
- 對原始資料進行預處理
- 模型選擇與訓練:
- 使用TestCNN模型進行訓練
- 情感分析:
- 將訓練好的模型應用於新的資料集上,輸出情感分析結果
- 結果分析與視覺化:
- 對情感分析結果進行資料視覺化、趨勢分析等,以便更直觀地展示和分析資料。
- 搭建網頁:
- 使用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()
- 使用微博評論的api介面
- 第一頁的評論是沒有max_id,返回的響應max_id為下一頁評論的params
- 層層獲取一頁的評論知道達到規定的頁數或標識改變
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")
- 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)
-
該函式從輸入字串中提取點贊數和情感資訊,並更新字典 lk_em_dict,其中儲存了不同情感類別的點贊總數。
-
這個函式是為了後續生成點贊-情感關係的柱狀圖。
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")
)
-
接受一個字典 dic,其中包含不同情感類別的點贊數資訊。
-
使用 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. 最後,將生成的詞雲圖儲存為圖片檔案。