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老師曾多次教導我對于一個問題,最應該想的就是怎麼利用自己已有的知識進行求解,條條大路通羅馬,拘泥于一種方法往往會思維受限,鑽入死胡同。我想分享給大家,也希望大家通過數學模組化都能有所收獲,學到更多的知識,提高分析和解決問題的能力!