本文是基于《Python数据分析与挖掘实战》的实战部分的第12章的数据——《电子商务网站用户行为分析及服务推荐》做的分析。

由于此章内容很多,因此,分为三个部分进行分享——数据探索(上)、数据预处理(中)、模型构建(下)

本文是继前一篇文章,进行的工作。本文是“数据预处理(中)”部分

1 数据清洗

1.1 查看各个需要删除的规则包含的信息

# 删除规则1:统计中间类型网页(带midques_关键字)
# 读取数据库数据
engine = create_engine('mysql+pymysql://root:@127.0.0.1:3306/jing?charset=utf8')
sql = pd.read_sql('all_gzdata', engine, chunksize = 10000)def countmidques(i): j = i[['fullURL','fullURLId','realIP']].copy()j['type'] = u'非中间类型网页'j['type'][j['fullURL'].str.contains('midques_')]= u'中间类型网页'return j['type'].value_counts()
counts1 = [countmidques(i) for i in sql]
counts1 = pd.concat(counts1).groupby(level=0).sum()
counts1

# 删除规则2:主网址去掉无.html点击行为的用户记录
# 读取数据库数据
engine = create_engine('mysql+pymysql://root:@127.0.0.1:3306/jing?charset=utf8')
sql = pd.read_sql('all_gzdata', engine, chunksize = 10000)def countnohtml(i):j = i[['fullURL','pageTitle','fullURLId']].copy()j['type'] = u'有html页面'j['type'][j['fullURL'].str.contains('\.html')==False] = u'无.html点击行为的用户记录'return j['type'].value_counts()
counts2 = [countnohtml(i) for i in sql]
counts2 = pd.concat(counts2).groupby(level=0).sum()
counts2

# 删除规则3:主网址是律师的浏览信息网页(快车-律师助手)、咨询发布成功、快搜免费发布法律
# *备注:此规则中要删除的记录的网址均不含有.html,所以,规则三需要过滤的信息包含了规则2中需要过滤的
engine = create_engine('mysql+pymysql://root:@127.0.0.1:3306/jing?charset=utf8')
sql = pd.read_sql('all_gzdata', engine, chunksize = 10000)def countothers(i): j = i[['fullURL','pageTitle','fullURLId']].copy()j['type'] = u'其他'   j['pageTitle'].fillna(u'空',inplace=True)j['type'][j['pageTitle'].str.contains(u'快车-律师助手')]= u'快车-律师助手'j['type'][j['pageTitle'].str.contains(u'咨询发布成功')]= u'咨询发布成功'j['type'][(j['pageTitle'].str.contains(u'免费发布法律咨询')) | (j['pageTitle'].str.contains(u'法律快搜'))] = u'快搜免费发布法律咨询'return j['type'].value_counts()
counts3 = [countothers(i) for i in sql]
counts3 = pd.concat(counts3).groupby(level=0).sum()
counts3

# 删除规则4: 去掉网址中问号后面的部分,截取问号前面的部分;去掉主网址不包含关键字
engine = create_engine('mysql+pymysql://root:@127.0.0.1:3306/jing?charset=utf8')
sql = pd.read_sql('all_gzdata', engine, chunksize = 10000)def deletquesafter(i):j = i[['fullURL']].copy()j['fullURL'] = j['fullURL'].str.replace('\?.*','')j['type'] = u'主网址不包含关键字'j['type'][j['fullURL'].str.contains('lawtime')] = u'主网址包含关键字'return jcounts4 = [deletquesafter(i) for i in sql]
counts4 = pd.concat(counts4)
print len(counts4)
counts4['type'].value_counts()

# 删除规则5: 重复数据去除
# 读取数据库数据
engine = create_engine('mysql+pymysql://root:@127.0.0.1:3306/jing?charset=utf8')
sql = pd.read_sql('all_gzdata', engine, chunksize = 10000)def countduplicate(i): j = i[['fullURL','timestamp_format','realIP']].copy()return jcounts5 = [countduplicate(i) for i in sql]
counts5 = pd.concat(counts5)print len(counts5[counts5.duplicated()==True]) #35479
print len(counts5.drop_duplicates()) #801971
a = counts5.drop_duplicates()

1.2 Python访问数据库进行清洗操作

1.2.1 第一步,完成删除规则1,2,4

# 对网址的操作 (只要.html结尾的 & 截取问号左边的值 & 只要包含主网址(lawtime)的&网址中间没有midques_的
# 读取数据库数据
engine = create_engine('mysql+pymysql://root:@127.0.0.1:3306/jing?charset=utf8')
sql = pd.read_sql('all_gzdata', engine, chunksize = 10000)for i in sql:d = i[['realIP', 'fullURL','pageTitle','userID','timestamp_format']].copy() # 只要网址列d['fullURL'] = d['fullURL'].str.replace('\?.*','') # 网址中问号后面的部分d = d[(d['fullURL'].str.contains('\.html')) & (d['fullURL'].str.contains('lawtime')) & (d['fullURL'].str.contains('midques_') == False)] # 只要含有.html的网址# 保存到数据库中d.to_sql('cleaned_one', engine, index = False, if_exists = 'append')

1.2.2 第二步,完成删除规则3

# 对网页标题的操作 (删除 快车-律师助手 & 免费发布法律咨询 & 咨询发布成功 & 法律快搜)
# 读取数据库数据(基于操作1之后)
engine = create_engine('mysql+pymysql://root:@127.0.0.1:3306/jing?charset=utf8')
sql = pd.read_sql('cleaned_one', engine, chunksize = 10000)# 对网址的操作 (只要.html结尾的&只要包含主网址(lawtime)的&网址中间没有midques_的
for i in sql:d = i[['realIP','fullURL','pageTitle','userID','timestamp_format']]# 只要网址列d['pageTitle'].fillna(u'空',inplace=True)d = d[(d['pageTitle'].str.contains(u'快车-律师助手') == False) & (d['pageTitle'].str.contains(u'咨询发布成功') == False) & \(d['pageTitle'].str.contains(u'免费发布法律咨询') == False) & (d['pageTitle'].str.contains(u'法律快搜') == False)\].copy()# 保存到数据库中d.to_sql('cleaned_two', engine, index = False, if_exists = 'append')

注意:最后发现,对于网页标题需要进行的删除的记录的网址中,均没有.html,因此,操作2可以不必做,操作1已完成工作

1.2.3 第三步,完成删除规则5

def dropduplicate(i): j = i[['realIP','fullURL','pageTitle','userID','timestamp_format']].copy()return jcount6 = [dropduplicate(i) for i in sql]
count6 = pd.concat(count6)
print len(count6) # 2012895
count7 = count6.drop_duplicates(['fullURL','userID','timestamp_format']) # 一定要进行二次删除重复,因为不同的块中会有重复值
print len(count7) # 647300
savetosql(count7, 'cleaned_three')

1.3 查看进行删除操作后的表中的总记录数

# 查看all_gzdata表中的记录数
engine = create_engine('mysql+pymysql://root:@127.0.0.1:3306/jing?charset=utf8')
sql = pd.read_sql('all_gzdata', engine, chunksize = 10000)
lens = 0
for i in sql:temp = len(i)lens = temp + lens
print lens # 837450# 查看cleaned_one表中的记录数
engine = create_engine('mysql+pymysql://root:@127.0.0.1:3306/jing?charset=utf8')
sql1 = pd.read_sql('cleaned_one', engine, chunksize = 10000)
lens1 = 0
for i in sql1:temp = len(i)lens1 = temp + lens1
print lens1 # 1341930# 查看cleaned_two表中的记录数
engine = create_engine('mysql+pymysql://root:@127.0.0.1:3306/jing?charset=utf8')
sql2 = pd.read_sql('cleaned_two', engine, chunksize = 10000)
lens2 = 0
for i in sql2:temp = len(i)lens2 = temp + lens2
print lens2 #2012895# 查看cleaned_three表中的记录数
engine = create_engine('mysql+pymysql://root:@127.0.0.1:3306/jing?charset=utf8')
sql3 = pd.read_sql('cleaned_three', engine, chunksize = 10000)
lens3 = 0
for i in sql3:temp = len(i)lens3 = temp + lens3
print lens3 #1294600

2 数据变换

2.1 识别翻页的网址

识别后删除重复(用户ID和处理后的网址相同)的记录

# 读取数据库数据
engine = create_engine('mysql+pymysql://root:@127.0.0.1:3306/jing?charset=utf8')
sql = pd.read_sql('cleaned_three', engine, chunksize = 10000)l0 = 0
l1 = 0
l2 = 0
for i in sql:d = i.copy()# 获取所有记录的个数temp0 = len(d)l0 = l0 + temp0# 获取类似于http://www.lawtime.cn***/2007020619634_2.html格式的记录的个数# 匹配1 易知,匹配1一定包含匹配2x1 = d[d['fullURL'].str.contains('_\d{0,2}.html')]temp1 = len(x1)l1 = l1 + temp1    # 匹配2# 获取类似于http://www.lawtime.cn***/29_1_p3.html格式的记录的个数x2 = d[d['fullURL'].str.contains('_\d{0,2}_\w{0,2}.html')]temp2 = len(x2)l2 = l2 + temp2x1.to_sql('l1', engine, index=False, if_exists = 'append') # 保存x2.to_sql('l2', engine, index=False, if_exists = 'append') # 保存print l0,l1,l2 #1941900 166365 27780
# 注意:在内部循环中,容易删除不完整,所以需要进行全部读取二次筛选删除
# 【初步筛选】
# 读取数据库数据
engine = create_engine('mysql+pymysql://root:@127.0.0.1:3306/jing?charset=utf8')
sql = pd.read_sql('cleaned_three', engine, chunksize = 10000)
l4 = 0
for i in sql:d = i.copy()# 注意!!!替换1和替换2的顺序不能颠倒,否则删除不完整# 替换1 将类似于http://www.lawtime.cn***/29_1_p3.html下划线后面部分"_1_p3"去掉,规范为标准网址 d['fullURL'] = d['fullURL'].str.replace('_\d{0,2}_\w{0,2}.html','.html')#这部分网址有 9260 个# 替换2 将类似于http://www.lawtime.cn***/2007020619634_2.html下划线后面部分"_2"去掉,规范为标准网址d['fullURL'] = d['fullURL'].str.replace('_\d{0,2}.html','.html') #这部分网址有 55455-9260 = 46195 个d = d.drop_duplicates(['fullURL','userID']) # 删除重复记录(删除有相同网址和相同用户ID的)【不完整】因为不同的数据块中依然有重复数据temp = len(d)l4 = l4 + tempd.to_sql('changed_1', engine, index=False, if_exists = 'append') # 保存print l4 # 1643197
# 【二次筛选】
# 删除重复记录
# 读取数据库数据(基于操作2之后)
engine = create_engine('mysql+pymysql://root:@127.0.0.1:3306/jing?charset=utf8')
sql = pd.read_sql('changed_1', engine, chunksize = 10000)def dropduplicate(i): j = i[['realIP','fullURL','pageTitle','userID','timestamp_format']].copy()return jcounts1 = [dropduplicate(i) for i in sql]
counts1 = pd.concat(counts1)
print len(counts1)# 1095216
a = counts1.drop_duplicates(['fullURL','userID'])
print len(a)# 528166
savetosql(a, 'changed_2')
# 查看经过数据变换替换后的数据是否替换干净
# 读取数据库数据
engine = create_engine('mysql+pymysql://root:@127.0.0.1:3306/jing?charset=utf8')
sql = pd.read_sql('changed_2', engine, chunksize = 10000)l0 = 0
l1 = 0
l2 = 0
for i in sql:d = i.copy()# 获取所有记录的个数temp0 = len(d)l0 = l0 + temp0# 获取类似于http://www.lawtime.cn***/2007020619634_2.html格式的记录的个数# 匹配1 易知,匹配1一定包含匹配2x1 = d[d['fullURL'].str.contains('_\d{0,2}.html')]temp1 = len(x1)l1 = l1 + temp1    # 匹配2# 获取类似于http://www.lawtime.cn***/29_1_p3.html格式的记录的个数x2 = d[d['fullURL'].str.contains('_\d{0,2}_\w{0,2}.html')]temp2 = len(x2)l2 = l2 + temp2print l0,l1,l2# 528166 0 0表示已经删除成功

2.2 网址正确分类

手动分析咨询类别和知识类别的网址

# 读取数据库数据
engine = create_engine('mysql+pymysql://root:@127.0.0.1:3306/jing?charset=utf8')
sql = pd.read_sql('changed_2', engine, chunksize = 10000)def countzhishi(i):j = i[['fullURL']].copy()j['type'] = 'else'j['type'][j['fullURL'].str.contains('(info)|(faguizt)')] = 'zhishi'j['type'][j['fullURL'].str.contains('(ask)|(askzt)')] = 'zixun'return j
counts2 = [countzhishi(i) for i in sql]
counts2 = pd.concat(counts2)
counts2['type'].value_counts()

# 统计各个类别占比
a = counts2['type'].value_counts()
b = DataFrame(a)
b.columns = ['num']
b.index.name = 'type'
b['per'] = b['num']/b['num'].sum()*100
b

2.2.1 第一步 *: 手动分析知识类别的网址,得出知识类别下的二级类别有哪些

c = counts2[counts2['type']=='zhishi']d = c[c['fullURL'].str.contains('info')]
print len(d) # 102140
d['iszsk'] = 'else' # 结果显示是空
d['iszsk'][d['fullURL'].str.contains('info')] = 'infoelsezsk' # 102032
d['iszsk'][d['fullURL'].str.contains('zhishiku')] = 'zsk' # 108
d['iszsk'].value_counts()
# 由结果可知,除了‘info'和’zhishifku'没有其他类型,且 【info类型(不包含zhishiku):infoelsezsk】和【包含zhishiku:zsk】类型无相交的部分。
# 因此分析知识类别下的二级类型时,需要分两部分考虑,求每部分的类别,再求并集,即为所有二级类型

2.2.2 第二步 *用正则表达式匹配出网址中二级类别

# 方法:用上面已经处理的'iszsk'列分成两种类别的网址,分别使用正则表达式进行匹配
# 缺点:太慢了!!!!!!!!!!!!!!
import re
# 对于http://www.lawtime.cn/info/jiaotong/jtsgcl/2011070996791.html类型的网址进行这样匹配,获取二级类别名称"jiaotong"
pattern = re.compile('/info/(.*?)/',re.S)
e = d[d['iszsk'] == 'infoelsezsk']
for i in range(len(e)):e.iloc[i,2] = re.findall(pattern, e.iloc[i,0])[0]
print e.head()# 对于http://www.lawtime.cn/zhishiku/laodong/info/***.html类型的网址进行这样匹配,获取二级类别名称"laodong"
# 由于还有一类是http://www.lawtime.cn/zhishiku/laodong/***.html,所以使用'zhishiku/(.*?)/'进行匹配
pattern1 = re.compile('zhishiku/(.*?)/',re.S)
f = d[d['iszsk'] == 'zsk']
for i in range(len(f)):
#     print i f.iloc[i,2] = re.findall(pattern1, f.iloc[i,0])[0]
print f.head()

2.2.3 第三步 *将列名重命名

e.columns = ['fullURL', 'type1', 'type2']
print e.head()f.columns = ['fullURL', 'type1', 'type2']
print f.head()# 将两类处理过二级类别的记录合并,求二级类别的交集
g = pd.concat([e,f])
h = g['type2'].value_counts()# 求两类网址中的二级类别数,由结果可知,两类网址的二级类别的集合的并集满足所需条件
len(e['type2'].value_counts()) # 66
len(f['type2'].value_counts()) # 31
len(g['type2'].value_counts()) # 69print h.head()print h.index # 列出知识类别下的所有的二级类别

2.2.4 第四步 *将二级类别分别存储到数据库中

 detailtypes = h.indexfor i in range(len(detailtypes)):x = g[g['type2'] == h.index[i]]savetosql(x,h.index[i])

2.2.5 第五步 *用正则表达式匹配出网址中三级类别

# 复制e的备份进行处理,避免操作中改变了数据
q = e.copy()
q['type3'] = np.nan
resultype3 = DataFrame([],columns=q.columns)
for i in range(len(h.index)):pattern2 = re.compile('/info/'+h.index[i]+'/(.*?)/',re.S)current = q[q['type2'] == h.index[i]]print current.head()for j in range(len(current)):findresult = re.findall(pattern2, current.iloc[j,0])if findresult == []: # 若匹配结果是空,则将空值进行赋值给三级类别current.iloc[j,3] = np.nanelse:current.iloc[j,3] = findresult[0]resultype3 = pd.concat([resultype3,current])# 将处理后的数据拼接
resultype3.head()
resultype3.set_index('fullURL',inplace=True)
resultype3.head(10)

# 统计婚姻类下面的三级类别的数目
j = resultype3[resultype3['type2'] == 'hunyin']['type3'].value_counts()
print len(j) # 145
j.head()

2.2.6  第六步 *目标:将类别3按照每类降序排列,然后保存

# 方式1
Type3nums = resultype3.pivot_table(index = ['type2','type3'], aggfunc = 'count')
# 方式2: Type3nums = resultype3.groupby([resultype3['type2'],resultype3['type3']]).count()
r = Type3nums.reset_index().sort_values(by=['type2','type1'],ascending=[True,False])
r.set_index(['type2','type3'],inplace = True)
#保存的表名命名格式为“2_2_k此表功能名称”,此表表示生成的第1张表格,功能为Type3nums:得出所有三级类别
r.to_excel('2_2_3Type3nums.xlsx')
r

2.2.7 属性规约

获取后续建模需要的数据

咨询(ask)和婚姻(hunyin)数据

# 将满足需求的存到数据库中去
# 方法一:
# 读取数据库数据
engine = create_engine('mysql+pymysql://root:@127.0.0.1:3306/jing?charset=utf8')
sql = pd.read_sql('changed_2', engine, chunksize = 10000)
l1 = 0
l2 = 0
for i in sql:zixun = i[['userID','fullURL']][i['fullURL'].str.contains('(ask)|(askzt)')].copy()l1 = len(zixun) + l1hunyin = i[['userID','fullURL']][i['fullURL'].str.contains('hunyin')].copy()    l2 = len(hunyin) + l2zixun.to_sql('zixunformodel', engine, index=False,if_exists = 'append')hunyin.to_sql('hunyinformodel', engine, index=False,if_exists = 'append')
print l1,l2 # 393185 16982# 方法二:
m = counts2[counts2['type'] == 'zixun']
n =counts2[counts2['fullURL'].str.contains('hunyin')]
p = m[m['fullURL'].str.contains('hunyin')]
p # 结果为空,可知,包含zixun的页面中不包含hunyin,两者没有交集
savetosql(m,'zixun')
savetosql(n,'hunyin')

备注:本章完整代码请见点击打开链接

《Python数据分析与挖掘实战》第12章(中)——协同推荐相关推荐

  1. python数据分析与挖掘实战-第六章拓展偷漏税用户识别

    第六章分别使用了LM神经网络和CART 决策树构建了 电力窃漏电用户自动识别模型,章末提出了拓展思考–偷漏税用户识别. 第六章及拓展思考完整代码 https://github.com/dengsiyi ...

  2. Python数据分析与挖掘实战学习12

    一.深度学习 1.BP算法 BP(back propagation)神经网络是1986年由Rumelhart和McClelland为首的科学家提出的概念,是一种按照误差逆向传播算法训练的多层前馈神经网 ...

  3. Python数据分析与挖掘实战——第三章

    第三章 数据探索 目录 第三章 数据探索 一.数据探索 二.数据质量分析 1. 主要任务: 2. 缺失值分析 3. 异常值分析 4. 一致性分析 三.数据特征分析 1. 分布分析 2. 对比分析 3. ...

  4. 《Python数据分析与挖掘实战》一第1章 数据挖掘基础1.1 某知名连锁餐饮企业的困惑...

    本节书摘来自华章出版社<Python数据分析与挖掘实战>一书中的第1章,第1.1节,作者 张良均 王路 谭立云 苏剑林,更多章节内容可以访问云栖社区"华章计算机"公众号 ...

  5. 《Python数据分析与挖掘实战》一3.1 数据质量分析

    本节书摘来自华章出版社<Python数据分析与挖掘实战>一书中的第3章,第3.1节,作者 张良均 王路 谭立云 苏剑林,更多章节内容可以访问云栖社区"华章计算机"公众号 ...

  6. 《Python数据分析与挖掘实战》一1.2 从餐饮服务到数据挖掘

    本节书摘来自华章出版社<Python数据分析与挖掘实战>一书中的第1章,第1.2节,作者 张良均 王路 谭立云 苏剑林,更多章节内容可以访问云栖社区"华章计算机"公众号 ...

  7. 《Python数据分析与挖掘实战》第12章(下)——协同推荐

    本文是基于<Python数据分析与挖掘实战>的实战部分的第12章的数据--<电子商务网站用户行为分析及服务推荐>做的分析. 由于此章内容很多,因此,分为三个部分进行分享--数据 ...

  8. 《Python数据分析与挖掘实战》第7章-聚类+绘制雷达图

    本文是基于<Python数据分析与挖掘实战>的第七章的数据--<航空公司客户价值分析>做的分析对部分代码,做出补充,对原文中的雷达图进行了实现. 1. 背景与目标分析 此项目旨 ...

  9. 《Python数据分析与挖掘实战》第11章——应用系统负载分析与磁盘容量预测(时间序列)

    文章目录 1.背景与目标分析 2.2 数据探索 2.1 查看数据信息 2.2 数据平稳性分析 3 数据预处理 3.1 数据清洗 3.2 数据变换--属性构造 4 模型构建 4.1 确定模型-- ARM ...

最新文章

  1. 《自然语言处理中的因果推理》综述论文,以色列理工谷歌等13位NLP大牛阐述因果推理NLP的估计、预测、解释和超越...
  2. 用Core Temp查看服务器CPU温度
  3. C#应用程序单例并激活程序的窗口 使其显示在最前端
  4. 探索多媒体开发最新最佳实践(内附资料下载)
  5. 推荐.neter常用优秀开源项目系列之二
  6. 润乾报表分组求和_实现报表数据预先计算
  7. matlab的灰色关联,五种灰色关联度分析matlab代码
  8. python--从入门到实践--chapter 12 pygame_Alien_Invasion
  9. html贪吃蛇怎么加蛇尾,贪吃蛇制作移动+pc
  10. Java NIO 基础
  11. Ubuntu18.04关闭ibus-daemon自启动
  12. 关键词堆砌生成器_网络推广软件的使用和24种关键词挖掘方法
  13. 鹏业安装算量常见安装问题处理
  14. 神经网络计算棒有什么用,神经网络计算棒怎么用
  15. VC++实现QQ消息群发
  16. jpress连接数据库mysql_通过Tomcat jpress连接不到数据库
  17. DISM用于Win7部署的实验笔记
  18. html 气泡动画效果,CSS 动画实现动态气泡背景的方法
  19. 老熊一亩三分地里的Oracle工具
  20. 使用两种方式,Android 发送文件到指定邮箱(带多个附件)

热门文章

  1. 电子工程管理案例_管理工程学院举办电子商务实训表彰大会
  2. treeSelect树组件设置父节点禁用
  3. Windows Media Player怎么打开RTSP视频源(或其他网络流)?
  4. 《淘宝店铺经营管理一册通》一一1.6 网店日常管理
  5. 装饰器模式代码举例(java语言版)
  6. KCL v0.4.6 重磅发布! 全新的 IDE 插件,Helm/Kustomize/KPT 工具集成
  7. kafka实现消息接受和发送
  8. python编写交互界面设计_Python 如何编写交互界面?
  9. win11如何安装apk安卓应用?
  10. Ansys|关于使用HFSS仿真报错“the password is invalid for INTEL MPl to launch jobs. ”(附有安装方法)