一、背景以及问题
主要研究对象是“XXXX官网”的网站访问情况,本网站是公司用于展示信息以及招商加盟的网址。
目标问题分析:
1)网站用户行为分析,挖掘各种行为特征(针对用户整体,分群),如访问量,访问页面类别,点击次数,停留时间等
2)根据用户访问需求特征(习惯),更加高效,人性化的服务推荐(推荐高相关度的,热门的,未浏览过的等)
二、数据探索性分析
1、相关库的导入
import pandas as pd #数据处理包
from pandas.io.json import json_normalize
import numpy as np #科学计算包
from collections import Counter
import pymysql
import warnings
warnings.filterwarnings("ignore") #忽略警告信息
%matplotlib inline
import matplotlib.pyplot as plt #可视化包
import seaborn
import re # 正则表达式库
import collections # 词频统计库
import jieba # 结巴分词
import wordcloud # 词云展示库
from PIL import Image # 图像处理库
import pyecharts #地理绘图库
from pyecharts.charts import Geo,Map
import json
import pyecharts as pe
2、数据导入
其中第一列数据无字段名,我把他重命名为“序号”
f=open('实时访客.csv',encoding='gbk')
data=pd.read_csv(f)
data=data.rename(columns={"Unnamed: 0":"序号"})
data.shape
![a44f3631528b7a5652e875ad08c7c392.png](https://i-blog.csdnimg.cn/blog_migrate/27b83dfbd77e6d85a4649aab872bd561.png)
这段数据的时间周期是2天,有1344条访问记录,共统计了28个字段
3、字段含义
data.columns
![d56e2cdd63e70722d407847c9e2e445d.png](https://i-blog.csdnimg.cn/blog_migrate/560abffb09be5231031c72ef1ed842d0.png)
访问时间:格式是‘年月日时分’,表明访问的时间
地域:访问者所在的区域
来源:三类,‘网址’,‘渠道’,‘直接访问’,表明用户进入主页的来源是从特定的网址还是通过渠道推广或者是直接输入主页网址进入的
关键词:匹配到的关键字,一般属于推广来的线索才有关键词记录
搜索词:访客实际搜索的词
推广:是和否,判断是否是通过渠道推广来的
入口页面:需要分类判断
访问IP:唯一标识
访客标识码:
访问时长:在页面停留的时间
访问页数:进入的页面
最后停留在:最后访问的页面
上一次访问时间、访问类型:判断是否为新访客,若不是,显示上次访问的时间,可计算其访问的周期
访问频次:计算其一共访问的次数,和访问时间对应,可计算其访问的周期
操作系统、网络服务商、浏览器、语言环境、屏幕分辨率、屏幕颜色、Flash版本、是否支持Cookie、是否支持JAVA:都是访客的访问环境和机型配置等
打开时间:‘时分秒’,具体的打开时间
停留时长、页面地址:在具体哪个页面停留多长时间
3、数据预处理
data.fillna(0)
把其中的缺失值用0来填充
4、访问时间
data1=data[['序号','访问时间']].dropna() #只保留用户首次行为记录的时间
#将脱敏的时间格式化
data1['访问时间']=pd.to_datetime(data1['访问时间'],format="%Y-%m-%d %H:%M")
data1['访问时间'] = data1['访问时间'].astype('str')
data1['hour']=data1['访问时间'].str[11:13] #取小时
data1['hour']=data1['hour'].astype(int)
df1=data1['hour'].value_counts()
df1
![3acef9e0f455047718436ddcc4bf0395.png](https://i-blog.csdnimg.cn/blog_migrate/4af9db6719e8d1f1633ac7571b80c9d8.png)
做一个简单的可视化
df1.plot.barh()
![0ca05724f9daf264f9c4771b78f019f1.png](https://i-blog.csdnimg.cn/blog_migrate/ed59376ab01005e61ffd9ca11bbb39aa.png)
发现上午十点和十一点的访问人数最多,但是看起来感觉比较乱,时间可以重新整理,按照时间顺序作图,考虑分箱
df2=data1['hour'].value_counts().sort_index(ascending=True)#按照时间小时进行排序计数
df2.plot()
x= range(1, 24) #x 轴数据
plt.xticks(x,x[::1],color='blue') #x刻度按照一个单位来显示
![231bf9098fe705b10ac74f9372d64390.png](https://i-blog.csdnimg.cn/blog_migrate/14eb0ce376663e9be6b2d56181dd7097.png)
由此可以发现网站被访问次数的规律,上午七点开始陆续有访客开始访问,十点至十一点到达高峰,接着下午一点和三点又有一个小高潮。
将时间分桶,探索不同时间段的网站访问情况可视化
bin=[-1,3,6,9,12,15,18,21,24]
data1['hour_bin']=pd.cut(data1.hour,bins=bin)
df2=data1['hour_bin'].value_counts()
df2
![d464b7444e5ca403a48aa340647b1f3d.png](https://i-blog.csdnimg.cn/blog_migrate/2f2ec13ee84437f0c646afee260e5c8e.png)
可以找到访问人数最多的时间段,可视化后便于观察
df2.plot.bar()
plt.title("不同时间用户点击情况",color='red')
plt.xticks(color='blue',rotation=45) #设置颜色蓝色,倾斜45度
plt.yticks(color='red')
5、地域分布
#删除某列包含特殊字符的行
data['地域'] =data['地域'][~data['地域'].isin(['其他'])]
#data['地域']=data['地域'][ ~ data['地域'].str.contains('其他')]
对不同地区统计
p0=data['地域'].value_counts()
#或者 p0=data.groupby(data['地域']).size()
p0
![45dc1d630d0f7aba7ecd0da6b46a5c00.png](https://i-blog.csdnimg.cn/blog_migrate/4e49979f246b48e9e4b22dcef8276e23.png)
能发现在本地推广的效果会好一些,外地的访客也有,并且遍布全国各地,考虑制成地图来查看
# 把数据处理成地图需要的格式
[z for z in p0.items()]
from pyecharts.faker import Faker
from pyecharts import options as opts
from pyecharts.charts import Geo
from pyecharts.globals import ChartType, SymbolType
# 画出全国分布图
g0 = Geo()
g0.add_schema(maptype="china")
g0.add("全国分布", [z for z in p0.items()])
#或者: g0.add("geo", [('丽江', 1),('北京', 1)])这样的格式导入数据
g0.set_series_opts(label_opts=opts.LabelOpts(is_show=False))#去掉标识
g0.set_global_opts(
visualmap_opts=opts.VisualMapOpts(is_piecewise=True,max_=500), #显示左下角的颜色控制,设置是否自定义分段,设置最大值
title_opts=opts.TitleOpts(title="地域分布"),
)
g0.render_notebook()
![31f4fd3e7596571131468ce253f0bc14.png](https://i-blog.csdnimg.cn/blog_migrate/105498955c03bf69855331e57026c125.png)
6、来源渠道分析
通过对来源渠道处理分析判断效果,来源分为直访用户,推广用户和外链用户,但是外链用户的链接分很多,可以将来源进行分类后再进行统计
data['用户分类']=data['来源'] #复制一列用户分类列用于分类统计
#data['用户分类'].dropna()
data['来源']=data['来源'].replace(np.nan,'0') #之前运行一直有报错cannot index with vector containing NA / NaN values,经过百度帮助查找到原因,来源作为索引列不能为na,
data['用户分类'][data['来源'].str.contains('(http)|(https)')]= '外链用户' #将含有http关键字的链接网址归为外链用户
data['用户分类'][data['来源'].str.contains('(直接访问)')] = '直访用户' #将直接访问的用户定义为直访用户
data['用户分类'][data['来源'].str.contains('(站内来源)')] = '站内用户'
data['用户分类'][data['来源'].str.contains('(百度)|(百度付费推广)|(百度自然搜索)|(Google)|(搜狗)|(Yahoo)|(360搜索)|(搜狗搜索)|(神马搜索)')] = '搜索引擎用户'
data['用户分类']
![25a5b8eda766422e8592bc589b54a00b.png](https://i-blog.csdnimg.cn/blog_migrate/4d2ba91af465de8ba76cae67af838b9a.png)
统计
one_counts=data['用户分类'].value_counts()
one_counts
或者使用交叉表的方式
one_counts1 = pd.crosstab(['访问次数'], data['用户分类']) #使用交叉表
one_counts1
![d652c50a997c6136126195172f5d2610.png](https://i-blog.csdnimg.cn/blog_migrate/e448f1aeca25329934598e440bf40da4.png)
![7373353b74f0a0fb63191e6325144680.png](https://i-blog.csdnimg.cn/blog_migrate/eb1f4b0b420dfc977fc8506cda795482.png)
可视化
one_counts.plot.bar()
plt.title("用户分类",color='red')
plt.xticks(color='blue',rotation=45) #设置颜色蓝色,倾斜45度
plt.yticks(color='red')
![29b7717e523a92dac629682564c8d0d3.png](https://i-blog.csdnimg.cn/blog_migrate/a6a6ed716a94a715b5838ea4a8937cc1.png)
6、关键词排行
data['搜索词'].replace('--','NaN').dropna()
分词后统计
'''下面的去除特殊字符步骤有报错,expected string or bytes-like object,因此需要将数据格式转变,使用str()转化其数据类型'''
string_data=(str(data['搜索词']))
"""文本预处理"""
pattern = re.compile(u't|n|.|-|:|;|)|(|?|"|--|,|0|1|2|3|4|5|6|7|8|9') # 定义正则表达式匹配模式
string_data = re.sub(pattern, '', string_data) # 将符合模式的字符去除
'''文本分词'''
seg_list_exact = jieba.cut(string_data, cut_all = False) # 精确模式分词
object_list = []
remove_words = [u'的', u',',u'和', u'是', u'随着', u'对于', u'对',u'等',u'能',u'都',u'。',u' ',u'、',u'中',u'在',u'了',
u'通常',u'如果',u'我们',u'需要'] # 自定义去除词库
for word in seg_list_exact: # 循环读出每个分词
if word not in remove_words: # 如果不在去除词库中
object_list.append(word) # 分词追加到列表
'''词频统计'''
word_counts = collections.Counter(object_list) # 对分词做词频统计
word_counts_top10 = word_counts.most_common(10) # 获取前10最高频的词
print (word_counts_top10) # 输出检查
词云展示
# 词频展示
#mask = np.array(Image.open('11.png')) # 定义词频背景
wc = wordcloud.WordCloud(
font_path='C:/Windows/Fonts/simhei.ttf', # 设置字体格式
#mask=mask, # 设置背景图
max_words=200, # 最多显示词数
max_font_size=100,# 字体最大值
width=1000,height=700,background_color='white' #设置宽,高,背景颜色
)
画词云
wc.generate_from_frequencies(word_counts) # 从字典生成词云
#image_colors = wordcloud.ImageColorGenerator(mask) # 从背景图建立颜色方案
#wc.recolor(color_func=image_colors) # 将词云颜色设置为背景图方案
plt.imshow(wc) # 显示词云
plt.axis('off') # 关闭坐标轴
plt.show() # 显示图像
# 将词云图片导出到当前文件夹
wc.to_file('yr.png')
7、入口页面
1),对入口页面进行分类统计 ;2),对具体课程体系进行分类统计
data['入口页面'].value_counts()
"""对具体课程体系进行分类统计"""
data['课程体系']=data['入口页面'] #复制一列用户分类列用于课程体系页面统计
data['入口页面']=data['入口页面'].replace(np.nan,'0')
data['课程体系'][data['入口页面'].str.contains('art')]='美术系界面'
data['课程体系'][data['入口页面'].str.contains('calligraphy')]='书法系界面'
data['课程体系'][data['入口页面'].str.contains('dance')]='舞蹈系界面'
data['课程体系'][data['入口页面'].str.contains('music')]='音乐系界面'
data['课程体系'][data['入口页面'].str.contains('science')]='科艺系界面'
data['课程体系'][data['入口页面'].str.contains('performance')]='表演系界面'
#把不是属于课程体系的网站统一归为“其他”类
data['课程体系'][~ data['入口页面'].str.contains('curriculum|art|calligraphy|dance|music|science|performance')]='其他'
data['课程体系'].value_counts()
可视化
data['课程体系'].value_counts().plot.bar()
plt.title("课程体系点击情况",color='red')
plt.xticks(color='blue',rotation=45) #设置颜色蓝色,倾斜45度
plt.yticks(color='red')
8、访问时长
data['访问时长']=data['访问时长'].str.replace('s',' ') #去除时长的后缀 S
data['访问时长']=data['访问时长'].str.replace("未知","0")#时长未知的用 0 替换
data = data.dropna(subset=['访问时长']) #删除NaN行
data['访问时长']=data['访问时长'].astype(int)
data['访问时长']
透视表
"""对访问时长和访问页面做数据透视"""
data.fillna(0)
data.pivot_table(index=['界面分类','课程体系'],values=['访问时长'],aggfunc=[np.sum])
三、相关结论和建议: