2020年的C題是一道典型的數據分析的題目,基於大數據分析處理進行相關建模。對於這道題而言,最難之處莫過於各個數據項關係的梳理總結,以及對數據的挖掘建模。網上很多大神給了很多高級的方法(深度學習、神經網絡等)。其實作爲小白,很多參賽的同學並不瞭解這方面的算法,以及背後的數學原理,很多人指望一兩個高級算法就能解決問題,只想着盲目套用,只會貽誤比賽的時間。
以下皆是本人對這題的一些粗淺的看法,僅供參考。
問題解決的要點:
一、數據的預處理
對於數據的預處理,個人首推Excel,簡單方便快捷
導入數據:
題目所給數據時tsv文本形式的數據,需要導入Excel進行數據的預處理
原始數據集的各個數據項:
marketplace | customer_id | review_id | product_id | product_parent | product_title | product_category |
---|---|---|---|---|---|---|
所屬地區/國家簡寫碼 | 用戶的ID | 評論的唯一標識ID | 產品的ID | 產品所屬父類的標識ID | 產品的標題 | 產品所屬類別 |
star_rating | helpful_votes | total_votes | vine | verified_purchase | review_headline | review_body | review_date |
---|---|---|---|---|---|---|---|
產品星級 | 贊成數(點贊數) | 評論總的獲贊數(贊成與反對) | Amazon Vine的一個認證,評論具有一定的可信度和準確性 | 是否以較低折扣購買相關產品 | 評論的標題 | 評論的內容 | 評論的日期 |
注:對於verified_purchase,我是基於對英文註釋的理解,也有很多人將其理解爲購買認證,即評論的人是否在亞馬遜平臺上購買了相關產品。亞馬遜上好像不買東西也可以評論,迷之操作。
利用Excel可以數據查重,缺失值填充,數據轉換等預處理操作,至於怎麼利用Excel進行各種預處理的操作就不贅述了
例如:可以利用Excel查重,確定數據集的各個數據項之間的關係,可以發現顧客數據項不是唯一的,即不是每一個數據都對應一個用戶,存在一個顧客購買多個產品的現象,產品的ID以及產品父類也是,只有每個評論的ID是唯一的。這樣的一些處理分析可以讓我們更加了解這個數據集中各個數據項之間的關係。
這裏就想提醒兩個容易忽視的基本操作:
1、文本信息數值化
數據分析,分析的是數據,一般我們很不喜歡處理非數值的信息,因此需要將非數值的一些文本信息數值化,查找替換,將非數值的信息數值化便於後面的數據處理分析。
2、顧客評論標題以及評論內容的預處理
由於顧客評論中可能存在許多拼寫錯誤,我們可以利用Excel的拼寫檢查對這部分的信息進行預處理。方便之後的評論種類的劃分,以及評論的情感分析。
二、產品的綜合評價
對於產品的綜合評價,初始考慮使用主成分分析,將影響產品評價的幾個量關聯起來,進行數據降維,再計算因子得分,按總分排序來對排名靠前產品進行,但結果並不理想(捂臉)。【這裏用的是Excel的數據透視表,去除部分無關信息,以產品ID爲行標籤將同一個產品ID的數據整合】
分析結果:
後面就直接結合主成分分析結果利用對原始數據集比對分析,再綜合層次分析法(權重+結合數據)進行對產品的綜合評定(爛尾)。
三、評論種類的區分
本題解題的另一個關鍵是將評論劃分種類,可以簡單地劃分爲好評、差評或者好評、中評、差評,可以將劃分好種類的評論簡單地利用數字-1,0,1來表示。評論的種類劃分可以基於以下幾步:
1、基於評論標題以及內容進行提詞
對數據項中的評論部分進行提取,利用python正則表達式進行字符匹配並分詞,將評論提取爲一個個的詞彙,去除提取的詞彙中的常用停用詞,無效字符,數字等,構建相關產品的常用評論詞彙庫。【提詞過程的代碼可以多跑幾次,觀察提詞結果再優化】
2、分析提詞結果構造產品評論詞庫
基於提取的相關產品的常用詞彙庫,選取部分對劃分評論種類有用的詞,對詞庫中的詞進行劃分,構建產品評論相關詞庫。【下面爲初步結果,可以結合代碼進行優化】
3、依據詞庫對評論種類進行劃分
對與這部分可以直接利用Python NLTK
進行比對,但考慮到NLTK相關語料庫下載速度驚人,直接忽略。結合常用評價詞彙修正詞庫,加入部分常用詞彙,構建評論判別詞彙庫,對評論進行判別歸類,將評論分爲三類:好評、中評、差評。簡單直接的方式就是自己構建詞庫進行分析,以下方法如果詞庫構建較爲完善,結合評論內容,顧客所打星級,對初步劃分結果進行修正,基本可以得到較好的評論分類結果。【網上也有很多簡單粗暴的方式利用NLTK的相關詞庫以及算法直接莽】
參考代碼:
# -*- coding: utf-8 -*-
"""
Created on Fri Mar 2020
@author: Good
"""
# NLP python自然語言處理
import re
import numpy as np
import pandas as pd
from nltk.corpus import stopwords
# 導入相關數據
data = pd.read_csv('C:/Users/Good/Desktop/Problem_C_Data/pacifier.tsv',sep = '\t')
# 獲取數據標籤
data_label = data.columns.values.tolist()
# 缺失觀測的檢測填充
print('數據集中是否存在缺失值:',any(data.isnull()))
data.fillna(method = 'ffill')
print('缺失值已前向填充!')
#------------------------------------------------------------------------------
# 獲取語言文本
review_headline = pd.DataFrame(data.loc[:,data_label[12]])
review_body = pd.DataFrame(data.loc[:,data_label[13]])
# 情感詞庫
positive = ['happy','great','five','four','good','perfect','love','loves',
'faster','excllent','super','thanks','amazing','powerful','quickly',
'fine','awesome','nice','helpful','like']
negative = ['one','two','bad','no','abandon','amiss','badly','blind','awful'
'terrible','awfulness','helpless','useless']
# 以上詞庫僅初始詞庫,爲了更好的效果,可以多跑幾次,完善詞庫,這裏僅做參考
#------------------------------------------------------------------------------
# 對文本信息進行相關處理,構造單詞列表,並對評論進行歸類
# 基於評論標題的評論分類
sentiment = np.zeros((np.size(review_headline),1))
for i in range(0,np.size(review_headline)):
review_headline.iloc[i,0] = str(review_headline.iloc[i,0])
review_headline.iloc[i,0] = review_headline.iloc[i,0].lower()
review_headline.iloc[i,0] = re.sub(r'[0-9]|\s|\,|\.|\!|\-|\(|\)|\<|\>|\:|/|\*|\;|\?|\`',
' ',review_headline.iloc[i,0])
for k in '&#$':
review_headline.iloc[i,0] = re.sub(k,'',review_headline.iloc[i,0])
temp = review_headline.iloc[i,0].split()
handle_temp = []
for m in range(0,np.size(temp)):
if temp[m] not in stopwords.words('english'):
handle_temp.append(temp[m])
for j in handle_temp:
if j in positive:
sentiment[i,0] = 1
elif j in negative:
sentiment[i,0] = -1
#------------------------------------------------------------------------------
# 基於評論內容的評論分類,對初步分類結果進行修正
for i in range(0,np.size(review_body)):
review_body.iloc[i,0] = str(review_body.iloc[i,0])
review_body.iloc[i,0] = review_body.iloc[i,0].lower()
review_body.iloc[i,0] = re.sub(r'[0-9]|\s|\,|\.|\!|\-|\(|\)|\<|\>|\:|/|\*|\;|\?|\`',
' ',review_body.iloc[i,0])
for k in '&#$':
review_body.iloc[i,0] = re.sub(k,'',review_body.iloc[i,0])
temp = review_body.iloc[i,0].split()
body_temp = []
for n in range(0,np.size(temp)):
if temp[n] not in stopwords.words('english'):
body_temp.append(temp[n])
for j in body_temp:
if j in positive and sentiment[i,0] == 0:
sentiment[i,0] = 1
elif j in negative and sentiment[i,0] == 0:
sentiment[i,0] = -1
#------------------------------------------------------------------------------
# 基於評論星級,點贊數的評論歸類的三次修正
star_rating = pd.DataFrame(data.loc[:,data_label[7]])
for i in range(0,np.size(star_rating)):
if star_rating.iloc[i,0] > 3 and sentiment[i,0] == -1:
sentiment[i,0] = 1
elif star_rating.iloc[i,0] == 3 and sentiment[i,0] == 1:
sentiment[i,0] = 0
elif star_rating.iloc[i,0] == 3 and sentiment[i,0] == -1:
sentiment[i,0] = -1
elif star_rating.iloc[i,0] < 3 and sentiment[i,0] == 1:
sentiment[i,0] = 0
四、評論的情感分析
情感分析與上述評論分析有很多相似的地方,最簡單直接的方式就是根據評論中正面詞彙以及反面詞彙的個數進行加權平均,可以直接考慮利用Python textblob
庫,網上有現成的代碼,不過推薦自己寫,這樣可以通過建模學到更多的東西。
這裏的權重,如果嫌麻煩可以直接就對半開,如果想要客觀公正的話,可以構建程度詞庫,結合程度詞權重的方式進行模型的優化,例如:extremely等程度詞在正面情感詞彙前面可以怎樣(可以對程度詞劃分級別,賦予權值,相關資料中提供了程度詞詞庫)。主要思想就是,將正面情感詞彙與負面情感詞彙進行加權平均得到情感傾向。【很多NLP智能算法的做法與我這上面的想法類似,不過過程更規範,識別更準確,不過思想是相通的,也有利用機器學習的算法做的,可以去了解一下】
五、相關資料
1、題目(PDF) 鏈接:https://pan.baidu.com/s/1mJOawF3gibrQFnQwDaMNIQ 提取碼:d60g
2、題目(Word) 鏈接:https://pan.baidu.com/s/1nn3E5MBdt6H4iqtYgXdyAg 提取碼:dowd
3、數據 鏈接:https://pan.baidu.com/s/1FXrNLUYA0Ev64-HYcYHhlA 提取碼:18mm
4、網上搜集的詞庫 鏈接:https://pan.baidu.com/s/1Tpk0PIev2slGZ0XYY_P2Lg 提取碼:b482
六、小結
給大家也是我自己的建議,不要老想着利用某個超級算法解決問題,坐等拿獎。對於一些算法,如果我們能掌握其原理,並能靈活運用最好,如若知識水平不夠,不妨嘗試利用自己已有的知識去解決這類問題。我非常喜歡的xu老師曾多次教導我對於一個問題,最應該想的就是怎麼利用自己已有的知識進行求解,條條大路通羅馬,拘泥於一種方法往往會思維受限,鑽入死衚衕。我想分享給大家,也希望大家通過數學建模都能有所收穫,學到更多的知識,提高分析和解決問題的能力!