首页 > 其他分享 >抖音用户浏览行为数据分析与挖掘

抖音用户浏览行为数据分析与挖掘

时间:2022-12-19 15:34:54浏览次数:38  
标签:数据分析 浏览 df author item 抖音 user groupby opts

一、选题的背景 

  本项目是大数据—基于抖音用户数据集的可视化分析。抖音作为当下非常热门的短视频软件,其背后的数据有极高的探索价值。本项目根据1048576条用户行为数据,利用python工具进行由浅入深的内容分析,目的是挖掘其中各类信息,更好地进行内容优化、产品运营。分析视频数据。

  (1)分析用户之间的互动数据,包括视频播放量、点赞数量、转发和评论关注度等。分析的目的是用户对您的视频的欢迎程度和刺激用户的痒点。微信有一定粉丝的朋友也可以使用AB测试方法,即在发布前可以向不同的人展示相同的视频内容,看看哪些人更受欢迎,然后收集意见进行优化和调整。

  (2)同行视频数据分析。这里主要分析同行的基本信息,如头像、昵称和签名。还有对方作品的更新频率、最受欢迎的作品、创意和对方的封面标题。或者那句话,只有了解自己和同行,你才能赢得每一场战斗。如果你能把你所有的同龄人都集中在你的账号上,你想不火都不行。

  (3)热门视频数据分析。如果你想制作热门视频,你必须经常刷热门视频,因为用户的口味变化非常快,热门视频代表了用户当前的偏好和内容趋势。你不仅要多看,还要拆解每一部作品的火背后的原因,这样你就会逐渐形成自己的方法论和网感。

二、大数据分析设计方案

  1.本数据集的数据内容与数据特征分析

    逻辑回归模型:
     逻辑回归模型是针对线性可分问题的一种易于实现而且性能优异的分类模型。 它假设数据服从 伯努利分布,通过 极大化似然函数 的方法,运用 梯度下降法来求解参数,来达到将数据二分类的目的。
    朴素贝叶斯模型:
     一种简单但极为强大的预测建模算法。假设每个输入变量是独立的。这是一个强硬的假设,实际情况并不一定,但是这项技术对于绝大部分的复杂问题仍然非常有效朴素贝叶斯模型由两种类型的概率组成:

     1.每个类别的概率P(Cj)

     2.每个属性的条件概率P(Ai|Cj)

    单棵决策树模型:

     单层决策树(decision stump),也称决策树桩,它是一种简单的决策树,通过给定的阈值,进行分类。从树(数据结构)的观点来看,它由根节点(root)与叶子节点(leaves)直接相连。用作分类器(classifier)的 decision stump 的叶子节点也就意味着最终的分类结果。从实际意义来看,decision stump 根据一个属性的一个判断就决定了最终的分类结果,比如根据水果是否是圆形判断水果是否为苹果,这体现的是单一简单的规则(或叫特征)在起作用。显然 decision stump 仅可作为一个 weak base learning algorithm(它会比瞎猜 12 稍好一点点,但好的程度十分有限),常用作集成学习中的 base algorithm,而不会单独作为分类器。

    随机森林:
     随机森林是一种比较新的机器学习模型(非线性基于树的模型)集成学习方法。上世纪八十年代Breiman等人发明分类树算法,通过反复二分数据进行分类或回归,计算量大大降低,2001年 Breiman把分类树组合成随机森林,即在变量(列)的使用和数据(行)的使用上进行随机化,生成很多分类树,再汇总分类树结果。随机森林在运算量没有显著提高前提下提高了预测精度,随机森林对多元共线性不敏感,结果对缺失数据和非平衡数据比较稳健,可以很好地预测多达几千个解释变量的作用,被誉为当前最好算法之一。
    模型AUC曲线:
    AUC(Area Under Curve)被定义为ROC曲线下与坐标轴围成的面积,显然这个面积的数值不会大于1。又由于ROC曲线一般都处于y=x这条直线的上方,所以AUC的取值范围在0.5和1之间。AUC越接近1.0,检测方法真实性越高;等于0.5时,则真实性最低,无应用价值。

三、数据分析步骤(70 分)

1.数据源

请说明数据源采用的哪一个开放的数据集?如果是采集的,请说明采集来源

与方式。

https://aistudio.baidu.com/aistudio/datasetdetail/63963/0

2.数据清洗

 

3.大数据分析过程及采用的算法

利用统计分析、数据挖掘和机器学习方法,对数据进行分析处理,获得分析结果,是数据分析处理流程的重要步骤。

●常规的统计方法

●通过使用机器学习的方法,处理采集到的数据。

逻辑回归、朴素贝叶斯、单棵决策树、随机森林

 

●使用的第三方库

如 sklearn 等,或其它

 使用的库

4.数据可视化

数据可视化借助于图形化手段,将数据分析结果直观、清晰、有效地展现出

来。使得用户可以从不同的维度观察数据,对数据有更深入地理解。

说明每个可视化图形表示的意义

1、城市的占比分布

 

 2、使用抖音频率观看时间的分布

 3、#作品时长与播放量、完播率、点赞率的关系

 

 4、#用户观看时段与播放量、完播率、点赞率的关系

 

  1. 附完整程序源代码(以及输出结果)

#导入需要的库
import pandas as pd
import numpy as np
from pyecharts.charts import *
from pyecharts import options as opts
from sklearn.cluster import KMeans
import joblib
from sklearn import metrics
from scipy.spatial.distance import cdist
from matplotlib import ticker
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_curve, auc
from sklearn import ensemble
from sklearn.model_selection import GridSearchCV
import matplotlib.pyplot as plt
%matplotlib inline
plt.rcParams['font.size'] = 20
# 中文乱码解决方法
plt.rcParams['font.family'] = ['Arial Unicode MS','Microsoft YaHei','SimHei','sans-serif']
plt.rcParams['axes.unicode_minus'] = False

#简单数据处理
df = pd.read_csv('douyin_dataset.csv')
df.head()

#删除无效键
del df['Unnamed: 0']
df.head()

# 数据基本信息基本信息
df.info(null_counts = True)
#验证数据无缺失

#用户特征统计分析
user_df = pd.DataFrame()
user_df['uid'] = df.groupby('uid')['like'].count().index.tolist() # 将所有用户的uid提取为uid列
user_df.set_index('uid', inplace=True) # 设置uid列为index,方便后续数据自动对齐
user_df['浏览量'] = df.groupby('uid')['like'].count() # 统计对应uid下的浏览量
user_df['点赞量'] = df.groupby('uid')['like'].sum() # 统计对应uid下的点赞量
user_df['观看作者数'] = df.groupby(['uid']).agg({'author_id':pd.Series.nunique}) # 观看作者数
user_df['观看作品数'] = df.groupby(['uid']).agg({'item_id':pd.Series.nunique}) # 观看作品数
user_df['观看作品平均时长'] = df.groupby(['uid'])['duration_time'].mean() # 浏览作品平均时长
user_df['观看配乐数'] = df.groupby(['uid']).agg({'music_id':pd.Series.nunique}) # 观看作品中配乐的数量
user_df['完整观看数'] = df.groupby('uid')['finish'].sum() # 统计对应uid下的完整观看数
# 统计对应uid用户去过的城市数量
user_df['去过的城市数'] = df.groupby(['uid']).agg({'user_city':pd.Series.nunique})
# 统计对应uid用户看的作品所在的城市数量
user_df['观看作品城市数'] = df.groupby(['uid']).agg({'item_city':pd.Series.nunique})
user_df.describe()

# 保存提取的特征,方便后续使用
user_df.to_csv('用户特征.csv', encoding='utf_8_sig')

#作者特征统计分析
author_df = pd.DataFrame()
author_df['author_id'] = df.groupby('author_id')['like'].count().index.tolist()
author_df.set_index('author_id', inplace=True)
author_df['总浏览量'] = df.groupby('author_id')['like'].count()
author_df['总点赞量'] = df.groupby('author_id')['like'].sum()
author_df['总观完量'] = df.groupby('author_id')['finish'].sum()
author_df['总作品数'] = df.groupby('author_id').agg({'item_id':pd.Series.nunique})

item_time = df.groupby(['author_id', 'item_id']).mean().reset_index()
author_df['作品平均时长'] = item_time.groupby('author_id')['duration_time'].mean()

author_df['使用配乐数量'] = df.groupby('author_id').agg({'music_id':pd.Series.nunique})
author_df['发布作品日数'] = df.groupby('author_id').agg({'real_time':pd.Series.nunique})

# pd.to_datetime(df['date'].max()) - pd.to_datetime(df['date'].min()) # 作品时间跨度为40,共计40天
author_days = df.groupby('author_id')['date']
_ = pd.to_datetime(author_days.max()) - pd.to_datetime(author_days.min())
author_df['创作活跃度(日)'] = _.astype('timedelta64[D]').astype(int) + 1
author_df['去过的城市数'] = df.groupby(['author_id']).agg({'item_city':pd.Series.nunique})
author_df.describe()

# 保存提取的特征,方便后续使用
author_df.to_csv('作者特征.csv', encoding='utf_8_sig')

#作品特征统计分析
item_df = pd.DataFrame()
item_df['item_id'] = df.groupby('item_id')['like'].count().index.tolist()
item_df.set_index('item_id', inplace=True)
item_df['浏览量'] = df.groupby('item_id')['like'].count()
item_df['点赞量'] = df.groupby('item_id')['like'].sum()
item_df['发布城市'] = df.groupby('item_id')['item_city'].mean()
item_df['背景音乐'] = df.groupby('item_id')['music_id'].mean()

# 保存提取的特征,方便后续使用
author_df.to_csv('作品特征.csv', encoding='utf_8_sig')

 

# 后续运行已经形成文件,就可以直接读取,避免大量计算时间
user_df = pd.read_csv('用户特征.csv', index_col=0)
user_df.head()

# 后续运行已经形成文件,就可以直接读取,避免大量计算时间
author_df = pd.read_csv('作者特征.csv', index_col=0)
author_df.head()

#3作品特征分析
item_df = pd.read_csv('作品特征.csv')
item_df.head()

# 绘图函数预定义
def line_chart(t, data):
chart = (
Line(init_opts = opts.InitOpts(theme='light',width='600px', height='400px'))
.add_xaxis([i[0] for i in data])
.add_yaxis(
'',
[i[1] for i in data],
is_symbol_show=False,
areastyle_opts=opts.AreaStyleOpts(opacity=1, color="cyan"))
.set_global_opts(
title_opts=opts.TitleOpts(title=t),
xaxis_opts=opts.AxisOpts(type_="category", boundary_gap=True),
yaxis_opts=opts.AxisOpts(
type_="value",
axistick_opts=opts.AxisTickOpts(is_show=True),
splitline_opts=opts.SplitLineOpts(is_show=True),),))
return chart

def pie_chart(t, data_pair):
# 新建一个饼图
chart = (
Pie(init_opts=opts.InitOpts(theme='light',width='600px', height='400px'))
.add('', data_pair ,radius=["30%", "45%"], # 半径范围,内径和外径
label_opts=opts.LabelOpts(formatter="{b}: {d}%") # 标签设置,{d}表示显示百分比)
.set_global_opts(
title_opts=opts.TitleOpts(
title=t),
legend_opts=opts.LegendOpts(pos_left="0%",pos_top="55",orient='vertical')))
return chart

def tree_chart(t, data):
chart = (
TreeMap(init_opts=opts.InitOpts(theme='light', width='700px', height='500px'))
.add(
"城市用户数", # 系列名称
data, # 数据
leaf_depth=1, # 叶子节点深度 城市为1
label_opts=opts.LabelOpts(position="inside", formatter='{b}城\n{c}用户'), # 标签设置
levels=[ # 针对每一层的样式设置
opts.TreeMapLevelsOpts(
treemap_itemstyle_opts=opts.TreeMapItemStyleOpts(
border_color="#555", border_width=4, gap_width=4)),
opts.TreeMapLevelsOpts(
color_saturation=[0.3, 0.6], # 颜色饱和度范围
treemap_itemstyle_opts=opts.TreeMapItemStyleOpts(
border_color_saturation=0.7, gap_width=2, border_width=2))])
.set_global_opts(
title_opts=opts.TitleOpts(
title=t, pos_left='center',
title_textstyle_opts=opts.TextStyleOpts(color='#00BFFF', font_size=20)),
legend_opts=opts.LegendOpts(is_show=False)))
return chart

def bar_chart(t, data):
chart = (
Bar(init_opts=opts.InitOpts(theme='light',width='700px',height='500px'))
.add_xaxis([x[0] for x in data])
.add_yaxis('', [x[1] for x in data],
itemstyle_opts={ # 图元样式
'shadowBlur': 10, # 光影大小
'shadowColor': 'rgba(0, 0, 0, 0.5)', # 阴影颜色
'shadowOffsetY': 5,
'shadowOffsetX': 5, # 偏移量
'barBorderRadius': [0, 10, 10, 0], # 圆角设置},
# 标签设置
label_opts=opts.LabelOpts(
is_show=True, # 显示标签
position='insideRight', # 显示位置
formatter='{c}' # 显示内容 {c}显示数值))
.set_global_opts(
title_opts=opts.TitleOpts(title=t),
xaxis_opts=opts.AxisOpts(position='top'),
visualmap_opts=opts.VisualMapOpts( # 视觉组件
is_show=False,
max_=200,
min_=10,
dimension=0, # 指定使用的数据维度
range_color=['#ffffff', '#00704a'] # 颜色范围)))
return chart

# 用户浏览
#浏览量分析
#简单的对浏览量进行分级并可视化比例了,这里主要是因为没有时间数据,字段中的real_time为作品提交时间,无法用于对用户进行浏览量的日活等进行分析
bins = [0, 5, 10, 25, 50, 100, 1951]
data = pd.cut(user_df['浏览量'], bins, right=True,labels=[f'({bins[x]},{bins[x+1]}]' for x in range(len(bins)-1)]).value_counts().reset_index().values.tolist()
pie_chart('不同浏览量用户占比', data).render_notebook()

# 点赞数
bins = [-1, 0, 1, 36]
data = pd.cut(user_df['点赞量'], bins, right=True,labels=[f'({bins[x]},{bins[x+1]}]' for x in range(len(bins)-1)]).value_counts().reset_index().sort_values(by='index').values.tolist()
pie_chart('不同点赞量用户占比', data).render_notebook()

#用户浏览量
temp = user_df['浏览量'].sort_values(ascending=False).reset_index().cumsum()['浏览量']
temp = temp/temp.max()
data = temp.reset_index().values.tolist()
line_chart('用户浏览量', data).render_notebook()

# 用户点赞百分比
_ = temp.tolist()
for j in range(10):
j /= 10
for i in _:
if i>=j:
flag = i
break
c = _.index(flag)/len(_)
print(f'{c:4.1%} 的用户点了{j:3.0%} 的赞')

#数据处理
item_df = pd.DataFrame()
item_df['id'] = df.groupby('item_id')['like'].count().index.tolist()
item_df['背景音乐'] = df.groupby('item_id')['music_id'].mean().tolist()
item_df['发布城市'] = df.groupby('item_id')['item_city'].mean().tolist()
item_df['浏览量'] = df.groupby('item_id')['like'].count().tolist()
item_df['点赞量'] = df.groupby('item_id')['like'].sum().tolist()
item_df['点赞率'] = item_df['点赞量']/item_df['浏览量']
item_df.describe()

#作品浏览量分布
bins = [0, 1, 2, 4, 1600]
item_df['浏览量等级'] = pd.cut(item_df['浏览量'], bins, labels=[f'({bins[x]},{bins[x+1]}]' for x in range(len(bins)-1)])
data = item_df.groupby('浏览量等级')['id'].count().reset_index().values.tolist()
pie_chart('不同浏览量作品占比', data).render_notebook()

#作品点赞分布
bins = [0, 1, 2, 3, 4, 5, 6, 7, 10, 35]
item_df['点赞等级'] = pd.cut(item_df['点赞量'], bins, labels=[f'[{bins[x]},{bins[x+1]})' for x in range(len(bins)-1)], right=False)
data = item_df.groupby('点赞等级')['id'].count().reset_index().values.tolist()
pie_chart('点赞数分布', data).render_notebook()

user_df = df.groupby('user_city').agg({'uid':pd.Series.nunique}).sort_index()
user_df['用户浏览量'] = df.groupby('user_city')['like'].count()
user_df['用户点赞数'] = df.groupby('user_city')['like'].sum()
user_df['城市作品数'] = df.groupby('item_city').agg({'item_id':pd.Series.nunique})['item_id']
user_df['城市作品浏览量'] = df.groupby('item_city')['like'].count()
user_df['城市作品点赞数'] = df.groupby('item_city')['like'].sum()
user_df.info(null_counts=True)

#发现存在空值,因为有三个城市是没有作品但是有用户的,所以使用0进行填充
user_df.rename (columns = {'uid':'用户数'},inplace = True)
user_df.fillna(0, inplace=True)
user_df.describe()

#城市用户数分布
user_df.rename (columns = {'uid':'用户数'},inplace = True)
data = user_df['用户数'].reset_index().values.tolist()
data = [{'value': i[1], 'name':i[0]} for i in data]
tree_chart('城市用户数分布图', data).render_notebook()

#城市作品数排名(前10)
data = user_df['城市作品数'].sort_values().reset_index().values.tolist()[-10:]
bar_chart('城市作品数前十', data).reversal_axis().render_notebook()

#用户观看时间分布
#观看时间前10的时间点
user_time = df.groupby('H',as_index=False)['uid'].count().rename(columns={
'uid': 'count'}).sort_values(by='count',ascending=False)
x=user_time.head(10)['H']
y=user_time.head(10)['count']

chart_time = Bar()
chart_time.add_xaxis(x.tolist())
chart_time.add_yaxis('',y.tolist())

chart_time.set_global_opts(title_opts=opts.TitleOpts(title='使用频率最高的前10个时间点'))
chart_time.render_notebook()
#从上图可看出,用户观看视频时间节点,主要在19-24点之间,该时间点正好在晚上下班期间

#创作者前10的城市
item_city = df.groupby('item_city',as_index=False)['uid'].count().rename(columns={
'uid': 'count'}).sort_values(by='count',ascending=False)
x=item_city.head(10)['item_city']
y=item_city.head(10)['count']

chart_item_city = Bar()
chart_item_city.add_xaxis(x.tolist())
chart_item_city.add_yaxis('',y.tolist())

chart_item_city.set_global_opts(title_opts=opts.TitleOpts(title='创作者数量前10的城市'))
chart_item_city.render_notebook()
#创作者前10城市和观看者前10城市,可以看出这俩的地域标签十分明显,可以作为不同用户的特征标签之一

#浏览量前10的作品
item_uv = df.groupby('item_id',as_index=False)['uid'].count().rename(columns={
'uid': 'count'}).sort_values(by='count',ascending=False)

## 因数据较多,故暂时只分析浏览量前10的作品信息
#for i in range(len(item)):
# item['作品时长'][i]=df[df['item_id'] == item['item_id'][i]]['duration_time'].unique()[0]

x=item_uv.head(10)['item_id']
y=item_uv.head(10)['count']

chart_item_uv = Bar()
chart_item_uv.add_xaxis(x.tolist())
chart_item_uv.add_yaxis('',y.tolist())

chart_item_uv.set_global_opts(title_opts=opts.TitleOpts(title='浏览量前10的作品'))
chart_item_uv.render_notebook()

#作品时长与播放量、完播率、点赞率的关系
fig2,duration_axes=plt.subplots(3,1,figsize=(12,8),sharex=True)

# 查看作品时长的播放量分布
duration_axes1=plt.subplot(311)
plt.plot(df.groupby('duration_time').count()['uid'])
duration_axes1.set_title('作品时长与播放量的关系')
duration_axes1.set_xlabel('作品时长')
duration_axes1.set_ylabel('播放量')
duration_axes1.xaxis.set_minor_locator(ticker.MultipleLocator(1))
duration_axes1.set_xlim(0,60)

# 查看作品时长的完播率分布
duration_axes2=plt.subplot(312)
plt.plot(df.groupby('duration_time').mean()['finish'])
duration_axes2.set_title('作品时长与完播率的关系')
duration_axes2.set_xlabel('作品时长')
duration_axes2.set_ylabel('完播率')
duration_axes2.xaxis.set_minor_locator(ticker.MultipleLocator(1))
duration_axes2.set_xlim(0,60)

# 查看作品时长的点赞率分布
duration_axes3=plt.subplot(313)
plt.plot(df.groupby('duration_time').mean()['like'])
duration_axes3.set_title('作品时长与点赞率的关系')
duration_axes3.set_xlabel('作品时长')
duration_axes3.set_ylabel('点赞率')
duration_axes3.xaxis.set_minor_locator(ticker.MultipleLocator(1))
duration_axes3.set_xlim(0,60)
plt.subplots_adjust(hspace=0.6)
plt.subplots_adjust(left=None, bottom=None, right=None, top=2, wspace=None, hspace=0.5)

#观察结果:
#1.播放量较高的作品,时长集中在在6-11s之间,其中时长9-10s的作品播放量最高,时长21s附近也有一定播放量,22s以上的播放量较少;
#2.时长43s前,作品完播率基本维持在40%左右,43s后完播率剧烈波动,没有规律可言;
#3.时长在2-12s间,作品点赞率在1%上下波动,12s之后的点赞率剧烈波动,没有明显规律,43s后更是接近0。

#结论:
#1.建议视频创作者的作品时长在6-11s之间,能够获得更高的播放量,最好别超过21s;
#2.作品时长跟完播率和点赞率没有直接关系。

#用户观看时段与播放量、完播率、点赞率的关系
df.H=df.H.astype('int')

# 查看播放量的24小时分布
plt.figure(figsize=(16,12))
h_axes1=plt.subplot(411)
plt.plot(df.groupby('H').count()['uid'])
plt.axhline(df.groupby('H').count()['uid'].mean(),ls='--',color='orange')
h_axes1.set_title('用户观看时段分布')
h_axes1.xaxis.set_minor_locator(ticker.MultipleLocator(1))

# 查看活跃用户的24小时分布
h_axes2=plt.subplot(412)
plt.plot(df.groupby('H').nunique()['uid'])
plt.axhline(df.groupby('H').nunique()['uid'].mean(),ls='--',color='orange')
h_axes2.set_title('活跃用户观看时段分布')
h_axes2.xaxis.set_minor_locator(ticker.MultipleLocator(1))

# 查看完播率的24小时分布
h_axes3=plt.subplot(413)
plt.plot(df.groupby('H').mean()['finish'])
h_axes3.set_title('完播率与用户观看时段的关系')

# 查看点赞率的24小时分布
h_axes4=plt.subplot(414)
plt.plot(df.groupby('H').mean()['like'])
h_axes4.set_title('点赞率与用户观看时段的关系')
plt.subplots_adjust(hspace=0.35)
plt.subplots_adjust(left=None, bottom=None, right=None, top=2, wspace=None, hspace=0.5)
#观察结果:
#1.综合播放量和活跃用户时间分布来看,19点到次日5点播放量明显高于平均水平,说明这段时间是用户的活跃时段;
#2.作品完播率和点赞率没有随时间呈现规律变化,说明用户在不同时段观看视频对完播率和点赞率没有影响。

#结论:
#1.19点到次日5点是用户的活跃时段,建议在这段时间内投稿,能够获得更高播放量;
#2.用户观看的时段对完播率和点赞率没有影响。

#播放来源分析
channel=df.groupby('channel').count()['uid']
channel.div(channel.sum()).sort_values(ascending=False)

import numpy as np
import pandas as pd

from pyecharts.charts import *
from pyecharts import options as opts

from sklearn.cluster import KMeans
import joblib
from sklearn import metrics
from scipy.spatial.distance import cdist
user_feature = pd.read_csv('用户特征.csv', index_col=0)
author_feature = pd.read_csv('作者特征.csv', index_col=0)

user_data = user_feature[(user_feature['完整观看数']>=1)&(user_feature['浏览量']>=5)]
print(len(user_data)/len(user_feature))

author_data = author_feature[(author_feature['总观完量']>=1)&(author_feature['总浏览量']>=3)]
print(len(author_data)/len(author_feature))

#kmeans聚类方法
def km(data, name):
K = range(2, 10) # K值选取范围
X = data # 数据
# scores = { 'SSE': [], 'sc': [], 'sse': []}
scores = {'sc': [], 'sse': []}
for _k in K:
# 初始化模型并进行聚类 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
kmeans = KMeans(n_clusters=_k, init='k-means++', random_state=0)
kmeans.fit(X)
_y = kmeans.predict(X) # 预测结果
# 计算模型评估指标 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
sse = sum(np.min(cdist(X,kmeans.cluster_centers_,'euclidean'),axis=1))/X.shape[0]
sc = metrics.silhouette_score(X, _y) # 计算轮廓系数
joblib.dump(kmeans, f'{name}{_k}聚类.model')
# 储存评估值 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# scores['SSE'].append(SSE)
scores['sse'].append(sse)
scores['sc'].append(sc)
print(f'聚{_k}类计算完成', end='\t')
joblib.dump(scores, f'{name}聚类指标.score')
print('指标储存完毕')
return scores

#绘制sse和sc曲线
def draw(k, sse, sc):
chart = (
Line(init_opts=opts.InitOpts(
theme='light',
width='350px',
height='350px'
))
.add_xaxis(k)
.add_yaxis('sse', sse, yaxis_index=0, label_opts=opts.LabelOpts(is_show=False))
.add_yaxis('sc', sc, yaxis_index=1, label_opts=opts.LabelOpts(is_show=False))
.extend_axis(yaxis=opts.AxisOpts())
.set_global_opts(
title_opts=opts.TitleOpts(title='聚类效果'),
xaxis_opts=opts.AxisOpts(type_="category", boundary_gap=True),
yaxis_opts=opts.AxisOpts(
type_="value",
axistick_opts=opts.AxisTickOpts(is_show=True),
splitline_opts=opts.SplitLineOpts(is_show=True),
),
)
)
return chart

#模型训练与保存
user_score = km(user_data, '用户')

#类聚k值选择
user_score = joblib.load(f'用户聚类指标.score')
draw([str(x) for x in range(2,10)], user_score['sse'], user_score['sc']).render_notebook()

#通过综合肘部法则和sc值,选择k=4作为用户类聚模型

user_km = joblib.load(f'用户4聚类.model')
user_centers = pd.DataFrame(user_km.cluster_centers_, columns=user_feature.columns)
user_centers['人数']=pd.Series(user_km.predict(user_data)).value_counts()
user_centers

#模型训练与保存
author_score = km(author_data, '作者')

#类聚k值选择
author_score = joblib.load(f'作者聚类指标.score')
draw([str(x) for x in range(2,10)], author_score['sse'], author_score['sc']).render_notebook()

#类聚效果
author_km = joblib.load(f'作者4聚类.model')
author_centers = pd.DataFrame(author_km.cluster_centers_, columns=author_df.columns)
author_centers['人数'] = pd.Series(author_km.predict(author_data)).value_counts()
author_centers

#数据读取
df = pd.read_csv('douyin_dataset.csv')
del df['Unnamed: 0'], df['H'], df['date'], df['finish'], df['channel']
df.head()

#数据抽样处理
df_like = df[df['like']==1]
df_dislike = df[df['like']==0]
data = pd.concat([df_like[::20], df_dislike[::40]], axis=0)
print(len(data)/len(df))

#时间数据处理
flag = pd.to_datetime('2019-01-01 00:00:00')
data['real_time'] = pd.to_datetime(data['real_time'])
data['real_time'] = pd.to_timedelta( data['real_time'] - flag).dt.total_seconds()
data.head()

#数据集划分
xtrain,xtest, ytrain, ytest = \
train_test_split(
data.drop('like', axis=1), # X
data['like'],test_size=0.3, # Y
random_state=0 # random_seed)

#模型预训练
#函数
def train(name, model):
model = model.fit(xtrain, ytrain)
print(f'{name}准确率: \t{model.score(xtest, ytest)}')
return model

#模型训练
# 逻辑回归
lgs = train('lgs', LogisticRegression(solver='liblinear', C=100.0,random_state=1))
# 朴素贝叶斯
gnb = train('gnb', GaussianNB().fit(xtrain,ytrain))
# 单棵决策树
clf = train('clf', DecisionTreeClassifier(class_weight='balanced',random_state=0))
# 随机森林
rfc = train('rfc', RandomForestClassifier(n_estimators=100, class_weight='balanced',random_state=0))

#模型AUC曲线
def my_auc(model):
y_test_proba = model.predict_proba(xtest)
false_positive_rate, recall, thresholds = roc_curve(ytest, y_test_proba[:, 1])
roc_auc = auc(false_positive_rate, recall)
return false_positive_rate, recall, roc_auc

lgs_auc = my_auc(lgs)
gnb_auc = my_auc(gnb)
clf_auc = my_auc(clf)
rfc_auc = my_auc(rfc)

# 画图 画出俩模型的ROC曲线
plt.plot(lgs_auc[0], lgs_auc[1], color='cyan', label='AUC_lgs=%0.3f' % lgs_auc[2])
plt.plot(gnb_auc[0], gnb_auc[1], color='blue', label='AUC_gnb=%0.3f' % gnb_auc[2])
plt.plot(clf_auc[0], clf_auc[1], color='green', label='AUC_clf=%0.3f' % clf_auc[2])
plt.plot(rfc_auc[0], rfc_auc[1], color='yellow', label='AUC_rfc=%0.3f' % rfc_auc[2])
plt.legend(loc='best', fontsize=12, frameon=False)
plt.plot([0, 1], [0, 1], 'r--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.0])
plt.ylabel('Recall')
plt.xlabel('Fall-out')
plt.show()

#模型训练
rfc0 = RandomForestClassifier(n_estimators=1000,
max_features=6,
class_weight='balanced',
random_state=0)
rfc0 = train('rfc++', rfc0)

df.head()

#也就是只要全都预测不点赞,也能有99.03的准确率,模型稍微准一点,还行,但是auc值低是硬伤

四、总结(10 分)

对本课程设计的整体完成情况做一个总结,包括:

  1. 通过对数据分析和挖掘,得到哪些有益的结论?是否达到预期的目标?

  通过对本次的数据分析的处理和一些运用,逐渐了解了一些对数据的处理,在数据中,把整个数据在进行小数据的分析,把数据分为用户特征、作者特征、作品特征、再对数据进行画图更加直观的体现出数据,让人能够一目了然。

  1. 自己在完成此设计过程中,得到哪些收获?以及要改进的建议?

     在做这个项目的时候还是遇到了许多问题,起先就是需要的库版本不对应,一开始的sklearn的库很难导进,后面在通过百度等方法后成功解决了。通过本次发现自己还是有很多不足的地方需要加强,同时自己也是缺乏练习,和对这些模块的运用还不能够随心所欲,希望自己能够加强。

 

标签:数据分析,浏览,df,author,item,抖音,user,groupby,opts
From: https://www.cnblogs.com/any0/p/16992125.html

相关文章