Python 实战之淘宝手机销售分析(数据清洗、可视化、数据建模、文本分析)

文章目录

  • 一、数据介绍
  • 二、数据清洗
  • 三、可视化分析
      • 淘宝在售手机价格区间统计
      • 商品现价&原价对比
      • 手机类型分布词云图
      • 绘制手机品牌词云图
      • 不同品牌手机总销量比较
      • 月销量气泡图
      • 收藏量与价格分析
      • 不同价格等级总销量饼图
      • 总销售额构成分析
      • TOP10 手机价格等级构成
      • 各发货省不同价格等级销售情况
  • 四、数据建模
  • 五、文本分析
    • SnowNLP 情感分析
    • LDA 主题模型

一、数据介绍

链接: https://pan.baidu.com/s/1GVQ5rv3ElNDLOkaDzuD6Jw 密码:5h6g

本文数据爬取了淘宝全网手机销售数据,其中包括:

  • cellphone.csv
    该数据集包括淘宝网在售的手机商品信息,包括爬取信息、商品信息、评分收藏信息等;
Index Column Non-Null Count Dtype
0 爬取时间(__time) 1691 non-null object
1 爬取链接(__url) 1691 non-null object
2 商品ID(product_id) 1691 non-null int64
3 商品名称(name) 1691 non-null object
4 商品描述(description) 1587 non-null object
5 商品参数(params) 1691 non-null object
6 商品现价(current_price) 1691 non-null object
7 商品原价(original_price) 1691 non-null object
8 月销量(month_sales_count) 1684 non-null float64
9 库存(stock) 1675 non-null float64
10 发货地址(shipping_address) 1691 non-null object
11 商品发布时间(product_publish_time) 1691 non-null int64
12 店铺ID(shop_id) 1691 non-null int64
13 店铺名称(shop_name) 1691 non-null object
14 商品链接URL(url) 1691 non-null object
15 评分(总分5.0分)(score) 1680 non-null float64
16 收藏数(stores_count) 1691 non-null int64
17 累计评价数(comments_count) 1679 non-null float64
18 商品评价印象标签(impresses) 1691 non-null object
19 Unnamed: 19 0 non-null float64
  • count_add_comments.csv
    该数据集包含上述手机商品的评价信息,包含图片的评价条数、追评条数等;
Index Column Non-Null Count Dtype
0 图片(picNum) 1232 non-null float64
1 追评(used) 1176 non-null float64
2 ID(id) 1691 non-null int64
3 Unnamed: 3 0 non-null float64
  • comments.csv
    该数据集包含上数据手机商品的具体评价,包括评价时间、评价内容等;
Index Column Non-Null Count Dtype
0 商品ID(id) 376760 non-null int64
1 评价时间(time) 376760 non-null object
2 评价内容(content) 376759 non-null object
3 爬取链接(spurl) 376760 non-null object
4 爬取时间(sptime) 376760 non-null object
5 Unnamed: 5 0 non-null float64

二、数据清洗

导入数据

  • 发现商品描述、月销量、库存、评分、累计评价数存在缺失
1
2
3
4
5
6
import pandas as pd
import numpy as np

phone=pd.read_csv('cellphone.csv')

add_comments=pd.read_csv('count_add_comments.csv')

缺失值处理+合并

  • 先对phone 进行处理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#删除空白列
phone=phone.drop(columns=['Unnamed: 19'])

#先获取列名,在此基础上进行更改
phone.columns
phone.columns=['爬取时间', '爬取链接', '商品ID', '商品名称',
       '商品描述', '商品参数', '商品现价',
       '商品原价', '月销量', '库存',
       '发货地址', '商品发布时间',
       '店铺ID', '店铺名称', '商品链接URL', '评分',
       '收藏数' ,'累计评价数', '商品评价印象标签']

#商品描述、月销量、库存、评分、累计评价数存在缺失

#查看月销量为0的商品信息
phone[phone['月销量'].isnull()].info()
#对销量为零的数据进行 0 填充
phone['月销量']=phone['月销量'].fillna(0)

#处理库存(0 填充)、评分(删除空白数据)、累计评价数(0填充)
phone['库存']=phone['库存'].fillna(0)
phone['累计评价数']=phone['累计评价数'].fillna(0)
phone=phone.dropna(subset=['评分'])

#重新梳理 index
phone.index=np.arange(len(phone))
  • 再对add_comments和 phone 进行数据合并
1
df=pd.merge(phone,add_comments,left_on='商品ID',right_on='ID(id)')

  • 最后对合并后的df进行列名梳理,删去重复的商品 ID
1
2
3
4
5
6
7
8
df.columns=['爬取时间', '爬取链接', '商品ID', '商品名称',
       '商品描述', '商品参数', '商品现价',
       '商品原价', '月销量', '库存',
       '发货地址', '商品发布时间',
       '店铺ID', '店铺名称', '商品链接URL', '评分',
       '收藏数' ,'累计评价数', '商品评价印象标签','图片', '追评', 'ID(id)', 'Unnamed: 3']
df=df.drop(columns=['Unnamed: 3'])
df=df.drop(columns=['ID(id)'])

清洗时间参数

  • time.localtime():能将 int 格式的时间数据转化
    如:time.localtime(1548475512)
    输出结果:time.struct_time(tm_year=2019, tm_mon=1, tm_mday=26, tm_hour=12, tm_min=5, tm_sec=12, tm_wday=5, tm_yday=26, tm_isdst=0)

  • time.strftime(’%Y-%m-%d’,time.localtime(1548475512)):输出既定格式的时间信息;
    输出结果:‘2019-01-26’

关于时间有关格式化信息
%y 两位数的年份表示(00-99)
%Y 四位数的年份表示(000-9999)
%m 月份(01-12)
%d 月内中的一天(0-31)
%H 24小时制小时数(0-23)
%I 12小时制小时数(01-12)
%M 分钟数(00-59)
%S 秒(00-59)
%a 本地简化星期名称
%A 本地完整星期名称
%b 本地简化的月份名称
%B 本地完整的月份名称
%c 本地相应的日期表示和时间表示
%j 年内的一天(001-366)
%p 本地A.M.或P.M.的等价符
%U 一年中的星期数(00-53)星期天为星期的开始
%w 星期(0-6),星期天为星期的开始
%W 一年中的星期数(00-53)星期一为星期的开始
%x 本地相应的日期表示
%X 本地相应的时间表示
%Z 当前时区的名称
%% %号本身

1
2
import time
df['商品发布时间']=df['商品发布时间'].apply(lambda op:time.strftime('%Y-%m-%d',time.localtime(op)))

清洗价格数据
目前得到的‘商品现价’、‘商品原价’两列均为价格区间的表示格式,我们无法获取完整的价格,在此取其均值;

1
2
3
4
5
6
def get_price(s):
    price=s.split('-')
    l=[float(i) for i in price]
    return np.mean(l)
df['商品现价']=df['商品现价'].apply(get_price)
df['商品原价']=df['商品原价'].apply(get_price)

清洗发货城市数据
目前发货城市数据为省+城市名的表示方式,我们要将省份+城市数据提取出来;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#获得中国全部的省级单位名称,找到全部的省级单位
#将每一个地址的省份提取出来,剩下的就是城市
pro_list=['北京',
 '天津',
 '上海',
 '重庆',
 '河北',
 '山西',
 '辽宁',
 '吉林',
 '黑龙江',
 '江苏',
 '浙江',
 '安徽',
 '福建',
 '江西',
 '山东',
 '河南',
 '湖北',
 '湖南',
 '广东',
 '海南',
 '四川',
 '贵州',
 '云南',
 '陕西',
 '甘肃',
 '青海',
 '台湾',
 '内蒙古',
 '广西',
 '西藏',
 '宁夏',
 '新疆',
 '香港',
 '澳门']
def get_city(address):
    for i in pro_list:
        if i in address:
            city=address.replace(i,'')
            if len(city)==0:
                city=i
            return city

def get_province(address):
    for i in pro_list:
        if i in address:
            province=i
            return province

df['发货城市']=df['发货地址'].apply(get_city)
df['发货省份']=df['发货地址'].apply(get_province)

价格分箱

1
2
3
import matplotlib.pyplot as plt
price_=df['商品现价'].value_counts().sort_index()
plt.plot(price_.index,price_)

在这里插入图片描述发现价格大致以 1000 元为一个等级,呈现分区分布;
于是创建价格等级字段,以便后续进行分析;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def get_price_level(p):
    level=p//1000
    if level==0:
        return '0~999'
    if level==1:
        return '1000~1999'
    if level==2:
        return '1999~2999'
    if level==3:
        return '2999~3999'
    if level==4:
        return '3999~4999'
    if level>=5:
        return '5000+'
    else:
        return '计算出错'
df['价格等级']=df['商品现价'].apply(get_price_level)

手机参数信息提取
手机参数信息以字典形式保存,创建一个函数,将每个键值对提取出来,以列的形式呈现;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
target=['后置摄像头',
 '摄像头类型',
 '视频显示格式',
 '分辨率',
 '触摸屏类型',
 '屏幕尺寸',
 '网络类型',
 '网络模式',
 '键盘类型',
 '款式',
 '运行内存RAM',
 '存储容量',
 '品牌',
 '华为型号',
 '电池类型',
 '核心数',
 '机身颜色',
 '手机类型',
 '操作系统',
 'CPU品牌',
 '产品名称']
for t in target:
    def get_pram(p):
        for i in eval(p):
            if i['label']==t:
                return i['value']
    df[t]=df['商品参数'].apply(get_pram)

至此,数据清洗过程大致完成,后续借助Matplotlib 和 Tableau 进行简要的可视化分析

三、可视化分析

淘宝在售手机价格区间统计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
plt.rcParams['font.family']=['Arial Unicode MS']
plt.figure(figsize=(10,5),dpi=200)

#发现手机原价数据有异常,进行清洗
df=df.drop(df[df['商品原价']>10000].index)

x=df['价格等级']
y=df.groupby('价格等级').count().reset_index

plt.hist(x,bins=12,color='green',align='mid')
plt.title('淘宝在售手机价格区间统计')
plt.xlabel('价格区间')
plt.ylabel('淘宝在售手机数')

plt.savefig('淘宝在售手机价格区间统计')
plt.show()

在这里插入图片描述

商品现价&原价对比

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#先筛选评分 >4.5的具有分析意义的手机商品
df1=df[df['评分']>4.5]

price1=df1.groupby('品牌')['商品原价'].mean().reset_index()
labels=price1['品牌']

price1=price1['商品原价'].astype(int)
price2=df1.groupby('品牌')['商品现价'].mean().reset_index()
price2=price2['商品现价'].astype(int)

x = np.arange(len(labels))  
width = 0.4

fig, ax = plt.subplots(figsize=(40,20))
rects1 = ax.bar(x - width/2, price1, width, label='商品原价')
rects2 = ax.bar(x + width/2, price2, width, label='商品现价')
ax.set_ylabel('价格',fontsize=30)
ax.set_title('手机现价及原价对比',fontsize=50)
ax.set_xticks(x)
plt.xticks(rotation=90)
ax.set_xticklabels(labels)
ax.legend(fontsize=30)

#数据标签设置
def autolabel(rects):
    for rect in rects:
        height = rect.get_height()
        ax.annotate('{}'.format(height),
                    xy=(rect.get_x() + rect.get_width() / 2, height),
                    xytext=(0, 3),  # 3 points vertical offset
                    textcoords="offset points",
                    ha='center', va='bottom',fontsize=20)


autolabel(rects1)
autolabel(rects2)

plt.tick_params(labelsize=30)
labels = ax.get_xticklabels() + ax.get_yticklabels()

fig.tight_layout()

plt.savefig('手机销售现价&原价对比')
plt.show()

在这里插入图片描述

手机类型分布词云图

手机具体参数含有手机类型的参数,针对淘宝全网所有售卖手机的商品信息,提取包含手机类型的字段,对其类型进行清洗及统计,查看在售手机类型情况;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from wordcloud import WordCloud
from imageio import imread
plt.rcParams['font.family']=['Arial Unicode MS']

df=df[df['手机类型'].notnull()]
df['手机类型']=[i.replace('不祥','不详') for i in df['手机类型']]
df['手机类型']=[i.replace('不详4','不详') for i in df['手机类型']]
df['手机类型']=[i.replace('老年机','老人手机') for i in df['手机类型']]
df['手机类型']=[i.replace('老年手机','老人手机') for i in df['手机类型']]
df['手机类型']=[i.replace('功能机','功能手机') for i in df['手机类型']]
df['手机类型']=[i.replace('老人机','老人手机') for i in df['手机类型']]
df['手机类型']=[i.replace('4G+手机','4G手机') for i in df['手机类型']]
get_type=[i.split('\xa0') for i in df['手机类型'].tolist()]
phone_type=[]
for i in get_type:
    phone_type+=i
word_count=pd.Series(phone_type).value_counts()
font='/Users/zhaosiqi/Library/Fonts/simhei.ttf'
wc = WordCloud(max_words=100,
               scale=12,
               max_font_size=200,
               random_state=30,
               background_color='white',
               font_path=font)

wc2 = wc.fit_words(word_count)

plt.figure(figsize=(15,10))
plt.imshow(wc2)
plt.axis("off")
plt.show()
wc.to_file("手机类型词云图.png")

在这里插入图片描述由此发现市面上在售手机大多为智能手机,且其拍照功能炙手可热,也成为商家销售的卖点;

而手机起步时代,对于手机的噱头,包括音乐手机、商务手机,女性手机等等,已不再成为卖点,市面上相关类型手机也逐渐下架;

绘制手机品牌词云图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
word_count=pd.Series(df['品牌'].tolist()).value_counts()
font='/Users/zhaosiqi/Library/Fonts/simhei.ttf'
back_pic=imread('pic.jpg')
wc = WordCloud(max_words=100,
               scale=12,
               max_font_size=50,
               random_state=30,
               background_color='white',
               mask=back_pic,
               font_path=font)

wc2 = wc.fit_words(word_count)

plt.figure(figsize=(15,10))
plt.imshow(wc2)
plt.axis("off")
plt.show()
wc.to_file("手机品牌词云图.png")

在这里插入图片描述国内销售市场上,销售量总体维持着以下情况:
华为、荣耀为第一梯队;
三星、小米、OPPO、Vivo、Apple 等品牌为第二梯队;
魅族、美图、飞利浦等品牌为第三梯队;
从第一款 Iphone 发布在国际市场上就保持着良好成绩的 Apple 公司,由于近年产品迭代速度较慢,且价格较贵,在国内销售情况并不十分突出;

--------------------以下图表由 Tableau 绘制-----------------

不同品牌手机总销量比较

此次爬取数据中并未包含总销售量数据,但根据淘宝的系统设置,无论买家是否主动评价,交易成功后将会自动留下评价信息,故在这里可以视‘累计评价数’为总销售量进行分析;

在这里插入图片描述

月销量气泡图

在这里插入图片描述数据爬取时间为2019 年2月1日,则月销量代表爬取日期往前推 30 天,即 2019 年1 月全月的销售情况;
整体来看,荣耀、华为、小米、Vivo 占据了当月国内手机市场销售的半壁江山;

收藏量与价格分析

在这里插入图片描述
其中圆形图标大小代表该品牌手机的平均价格;
而条形图高低代表该品牌手机的收藏量;

不同价格等级总销量饼图

在这里插入图片描述

总销售额构成分析

在这里插入图片描述

TOP10 手机价格等级构成

在这里插入图片描述

各发货省不同价格等级销售情况

在这里插入图片描述

四、数据建模

  • 此处尝试以月销量为目标值,利用各种回归模型进行建模,但预测效果均不太好,后续有其他尝试再进行更新;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#对屏幕尺寸进行处理,转化为浮点型,纳入特征值中
df=df[df['屏幕尺寸'].notnull()]
df['屏幕尺寸']=[float(i.replace('英寸','')) for i in df['屏幕尺寸']]

#绘制热力图
f=df[['商品现价','商品原价','库存','评分','收藏数','累计评价数','追评','屏幕尺寸','累计评价数','图片','月销量']]
target=df['月销量']
df['商品折扣']=df['商品现价']/df['商品原价']

corr=f.corr()
import seaborn as sns
plt.figure(figsize=(12,9))
sns.heatmap(corr,annot=True)
plt.show()

在这里插入图片描述
根据热力图相关信息,库存、收藏数、累计评价数、追评数、图片数等都与月销量有较强的相关性,故舍弃其他特征,暂时将这几个数据列为特征值进行建模分析;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
features=df[['库存','收藏数','累计评价数','累计评价数','屏幕尺寸','商品折扣']]
from sklearn.preprocessing import StandardScaler,MinMaxScaler
from sklearn.linear_model import LinearRegression,Ridge
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import RandomForestRegressor,GradientBoostingRegressor
from xgboost import XGBRegressor
from lightgbm import LGBMRegressor
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error

def model_test(estimators,x_train,x_test,y_train,y_test):
    for key,estimator in estimators.items():
        estimator.fit(x_train,y_train)
        y_predict=estimator.predict(x_test)
        mse=mean_squared_error(y_test,y_predict)
        print('----------------MSE of %s-------------'%(key),mse)
        scores=estimator.score(x_test,y_test)
        print('----------------Score of %s-------------'%(key),scores)
        print('\n')
       
estimators={}
estimators['Linear']=LinearRegression()
estimators['ridge'] = Ridge()
estimators['forest'] = RandomForestRegressor()
estimators['gbdt'] = GradientBoostingRegressor()
estimators['light'] = LGBMRegressor()
estimators['xgb'] = XGBRegressor()

x_train,x_test,y_train,y_test=train_test_split(features,target,test_size=0.25)    

std_x=StandardScaler()
std_y=StandardScaler()
x_train=std_x.fit_transform(x_train)
x_test=std_x.transform(x_test)
   
y_train=std_y.fit_transform(y_train.values.reshape(-1,1))
y_test=std_y.transform(y_test.values.reshape(-1,1))


model_test(estimators,x_train,x_test,y_train,y_test)

最后运行结果:
----------------MSE of Linear------------- 0.2444868135647999
----------------Score of Linear------------- 0.8342966651118264

----------------MSE of ridge------------- 0.2434147057213362
----------------Score of ridge------------- 0.8350232967138806

----------------MSE of forest------------- 0.581285474209155
----------------Score of forest------------- 0.6060280708228011

----------------MSE of gbdt------------- 0.7016777783281599
----------------Score of gbdt------------- 0.5244310063573885

----------------MSE of light------------- 0.745090845811169
----------------Score of light------------- 0.49500737424091323

----------------MSE of xgb------------- 0.7981978840571146
----------------Score of xgb------------- 0.4590135583983481

除线性回归及岭回归拟合效果较好外,其他模型没有比较好的得分,对特征进行多次增删调整后,也无太大变化;

五、文本分析

SnowNLP 情感分析

SnowNLP是一个python写的类库,可以方便的处理中文文本内容,是受到了TextBlob的启发而写的,由于现在大部分的自然语言处理库基本都是针对英文的,于是写了一个方便处理中文的类库。

这里主要用到 SnowNLP库中的情绪判断,用与判断买家评论信息的情绪;
该 API 返回值为为正面情绪的概率,越接近1表示正面情绪,越接近0表示负面情绪,例如:

1
2
3
4
5
6
7
8
text1 = '这部电影真心棒,全程无尿点'
text2 = '这部电影简直烂到爆'
s1 = SnowNLP(text1)
s2 = SnowNLP(text2)
print(text1, s1.sentiments) # 这部电影真心棒,全程无尿点
0.9842572323704297
print(text2, s2.sentiments) # 这部电影简直烂到爆
0.0566960891729531

此外 SnowNLP 还具有分词、词性标注(动词、名词等分类)、断句、拼音、繁转简、关键词抽取等功能;

本文中买家的评论信息可以用作情感分析的数据集,但由于全网评价条目过多,我们创建一个规则:
正面情绪概率>0.6 称之为积极情绪;
正面情绪概率<0.4 称之为消极情绪;
正面情绪概率<0.6 & >0.4 称之为平和情绪;

下面创建了一个函数,对 30 万余条评价,按指定列字段进行分类情感分析:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
from snownlp import SnowNLP
cmt=pd.read_csv('comments.csv')
cmt=cmt.dropna(subset=['评价内容(content)'])
cmt.index=np.arange(len(cmt))
#创建分类标签的情感分析函数
def Marks_emotion(column,content):
    def emotion(content):
        s=[np.round(SnowNLP(i).sentiments,2) for i in content]
        positive=0
        negative=0
        smooth=0
        for i in s:
            if i >0.6:
                positive+=1
            elif i<0.4:
                negative+=1
            else:
                smooth+=1
        counts=positive+negative+smooth
        print('积极情绪',str(int(positive/counts*100))+'%')
        print('消极情绪',str(int(negative/counts*100))+'%')
        print('平和情绪',str(int(smooth/counts*100))+'%')  
   
    for i in df[column].unique():
        uid=df[df[column]==i]['商品ID']
        def funci(ID):
            for i in uid:
                if ID==i:
                    return True
            return False
        whether_ture=cmt['商品ID(id)'].apply(funci)
        comments=pd.Series(cmt[whether_ture][content])
        print(i,'情感分析结果:')
        emotion(comments)
       
       
Marks_emotion('品牌','评价内容(content)')

注:由于数据量过于庞大,上述代码需要至少1小时才能跑完,故如果只是用于测试,可以利用随机取数的方法,进行抽样分析,参考代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
from snownlp import SnowNLP
cmt=pd.read_csv('comments.csv')
cmt=cmt.dropna(subset=['评价内容(content)'])
cmt.index=np.arange(len(cmt))
#创建分类标签的情感分析
def Marks_emotion(column,content):
    def emotion(content):
        s=[np.round(SnowNLP(i).sentiments,2) for i in content]
        positive=0
        negative=0
        smooth=0
        for i in s:
            if i >0.6:
                positive+=1
            elif i<0.4:
                negative+=1
            else:
                smooth+=1
        counts=positive+negative+smooth
        print('积极情绪',str(int(positive/counts*100))+'%')
        print('消极情绪',str(int(negative/counts*100))+'%')
        print('平和情绪',str(int(smooth/counts*100))+'%')  
   
    for i in df[column].unique():
        uid=df[df[column]==i]['商品ID']
        def funci(ID):
            for i in uid:
                if ID==i:
                    return True
            return False
        whether_ture=cmt['商品ID(id)'].apply(funci)
        comments=pd.Series(cmt[whether_ture][content])
        if len(comments)>1000:
            index=np.random.randint(1,len(comments),1000)
            comments=comments.iloc[index]
            print(i,'品牌手机情感分析结果:')
            emotion(comments)
               
Marks_emotion('品牌','评价内容(content)')

输出结果如下:
Huawei/华为 品牌手机情感分析结果:
积极情绪 75%
消极情绪 17%
平和情绪 6%

纽曼 品牌手机情感分析结果:
积极情绪 76%
消极情绪 14%
平和情绪 9%

Meizu/魅族 品牌手机情感分析结果:
积极情绪 68%
消极情绪 24%
平和情绪 6%

Samsung/三星 品牌手机情感分析结果:
积极情绪 65%
消极情绪 26%
平和情绪 8%

DOOV/朵唯 品牌手机情感分析结果:
积极情绪 88%
消极情绪 8%
平和情绪 3%

Philips/飞利浦 品牌手机情感分析结果:
积极情绪 78%
消极情绪 14%
平和情绪 7%

OPPO 品牌手机情感分析结果:
积极情绪 76%
消极情绪 17%
平和情绪 6%

honor/荣耀 品牌手机情感分析结果:
积极情绪 72%
消极情绪 21%
平和情绪 6%

Xiaomi/小米 品牌手机情感分析结果:
积极情绪 71%
消极情绪 21%
平和情绪 7%

Apple/苹果 品牌手机情感分析结果:
积极情绪 59%
消极情绪 31%
平和情绪 9%

Nokia/诺基亚 品牌手机情感分析结果:
积极情绪 68%
消极情绪 21%
平和情绪 9%

小辣椒 品牌手机情感分析结果:
积极情绪 78%
消极情绪 15%
平和情绪 6%

守护宝 品牌手机情感分析结果:
积极情绪 78%
消极情绪 14%
平和情绪 7%

Coolpad/酷派 品牌手机情感分析结果:
积极情绪 85%
消极情绪 12%
平和情绪 2%

BIRD/波导 品牌手机情感分析结果:
积极情绪 79%
消极情绪 13%
平和情绪 6%

K-Touch/天语 品牌手机情感分析结果:
积极情绪 81%
消极情绪 13%
平和情绪 4%

vivo 品牌手机情感分析结果:
积极情绪 81%
消极情绪 12%
平和情绪 5%

UniscopE/优思 品牌手机情感分析结果:
积极情绪 82%
消极情绪 10%
平和情绪 7%

Meitu/美图 品牌手机情感分析结果:
积极情绪 79%
消极情绪 15%
平和情绪 4%

360 品牌手机情感分析结果:
积极情绪 73%
消极情绪 20%
平和情绪 6%

nubia/努比亚 品牌手机情感分析结果:
积极情绪 74%
消极情绪 20%
平和情绪 5%

AGM(手机) 品牌手机情感分析结果:
积极情绪 73%
消极情绪 19%
平和情绪 6%

创星(手机) 品牌手机情感分析结果:
积极情绪 75%
消极情绪 19%
平和情绪 5%

ZTE/中兴 品牌手机情感分析结果:
积极情绪 74%
消极情绪 18%
平和情绪 6%

Konka/康佳 品牌手机情感分析结果:
积极情绪 88%
消极情绪 6%
平和情绪 5%

索爱 品牌手机情感分析结果:
积极情绪 85%
消极情绪 8%
平和情绪 6%

Haier/海尔 品牌手机情感分析结果:
积极情绪 78%
消极情绪 13%
平和情绪 8%

Changhong/长虹 品牌手机情感分析结果:
积极情绪 77%
消极情绪 15%
平和情绪 7%

SMARTISAN/锤子 品牌手机情感分析结果:
积极情绪 78%
消极情绪 14%
平和情绪 7%

YEPEN/誉品 品牌手机情感分析结果:
积极情绪 82%
消极情绪 12%
平和情绪 5%

OnePlus/一加 品牌手机情感分析结果:
积极情绪 70%
消极情绪 20%
平和情绪 9%

21KE 品牌手机情感分析结果:
积极情绪 72%
消极情绪 18%
平和情绪 8%

几米 品牌手机情感分析结果:
积极情绪 93%
消极情绪 3%
平和情绪 3%

LDA 主题模型

潜在狄利克雷模型(Latent Dirichlet Allocation)是贝叶斯学习的话题模型,是潜在语义分析的扩展,主要用于文本数据挖掘、图像处理等领域。

此处将模型封装为了一个函数,是为一个简单的引用。后续将进行 LDA 模型原理的详细讲解。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import jieba
import lda
from collections import Counter

string=open(r'stopwords.txt',encoding='utf-8').read()
filterwords=string.split('\n')

def word_cut(coms):
    b=[]
    for i in jieba.cut(coms):
        if i not in filterwords:
            b.append(i)
    return b
def get_vector(sentence,vocab):
    temp=[]
    for word in vocab:
        if word in sentence:
            temp.append(1)
        else:
            temp.append(0)
    return temp
def get_lda(params):
    corpora_words=[]
    for i in params:
        ss=word_cut(i)
        corpora_words.append(ss)
    words=[]
    for i in corpora_words:
        words+=i
    word_count=Counter(words)
    vocab=[]
    for word in word_count.keys():
        if word_count[word]>1:
            vocab.append(word)
    X=[]
    for se in corpora_words:
        X.append(get_vector(se,vocab))
    X=np.array(X)
    lda_model=lda.LDA(n_topics=10,n_iter=1500,random_state=1)
    lda_model.fit(X)
    topic_word=lda_model.topic_word_
    for i in range(5):
        index=np.argsort(topic_word[i])[::-1]
        print('主题',i,':',end='')
        for j in np.array(vocab)[index][0:10]:
            print(j,end=' ')
        print()
       
get_lda(pd.Series(cmt['评价内容(content)'].iloc[:1000]))

输出结果:
主题 0 :东西 买 好评 评论 特别 天猫 淘宝 老板 评价 字
主题 1 :苏宁 快递 物流 好 手机 不错 买 满意 很快 快
主题 2 :不错 好 值得 手机 质量 购买 买 华为 支持 正品
主题 3 :买 老人 喜欢 好 不错 挺 声音 手机 妈妈 机
主题 4 :手机 送 不错 客服 收到 几天 好评 挺 一段时间 赞