preface
在上一章节我们聊了 python 大数据分析的基本模块, 下面就说说 2 个项目吧, 第一个是进行淘宝商品数据的挖掘, 第二个是进行文本相似度匹配好了, 废话不多说, 赶紧上车
淘宝商品数据挖掘
自己写个爬虫爬吧, 爬到后入库(mysql)
数据清洗:
所谓的数据清洗, 就是把一些异常的缺失的数据处理掉, 处理掉不一定是说删除, 而是说通过某些方法将这个值补充上去, 数据清洗目的在于为了让我们数据的可靠, 因为脏数据会对数据分析产生影响 拿到数据后, 我们进行数据清洗分为两方面:
缺失值发现: 可以查找
异常值发现: 画图分析
缺失值: 在下载数据搜集数据的时候刚好就缺失可以通过查找的方法去发现
异常值: 不一定就是异常, 可能就是客观存在, 但是这个值对于总的数据来说是一个就比较特殊点可以通过画散点图发现
这两方面的处理方法如下:
缺失值处理: 均值 / 中位数插补固定值临近插补回归分析插值法(拉格朗日插值, 牛顿插值)
异常值处理: 视为缺失, 平均值修正, 不处理
方法解释:
均值 / 中位数插补: 在缺失位置插入一个总数据的均值或者中位数
固定值:: 在缺失位置插入一个固定值
临近插补: 看这个缺失位置附近的值是什么, 就把附近的某一个值插到缺失位置, 这类应用场景应用于物以类聚的场景
回归分析: 等日后用上的时候在研究
插值法: 此算法复杂, 暂未研究, 等日后用上的时候在研究
视为缺失: 可以看成缺失值, 然后通过缺失值来处理
平均值修正: 通过平均值来替代这个值
不处理: 不处理这个值
开始分析:
表结构介绍:
淘宝商品表结构如下:
title: 商品名称
link: 商品 URL
price: 商品价钱
comment: 商品评论数量
- mysql> desc taob;
- +---------+-------------+------+-----+---------+-------+
- | Field | Type | Null | Key | Default | Extra |
- +---------+-------------+------+-----+---------+-------+
- | title | varchar(50) | YES | | NULL | |
- | link | varchar(60) | NO | PRI | NULL | |
- | price | int(30) | YES | | NULL | |
- | comment | int(30) | YES | | NULL | |
- +---------+-------------+------+-----+---------+-------+
对于上面四个字段, 比较好处理的就是价钱和评论数, 比如价钱是 0(没有采集到的数据), 可以通过刚才平均值或者中位数来填充, 对于异常值, 比如某个评论 10W+, 那么也可以采用平均值修正
Python 环境介绍:
依赖于 pymysql,numpy,pandas,matplotlib, 请自己先安装可以参考我上篇博文: www.cnblogs.com/liaojiafa/p
拿代码说话:
获取数据
- conn = pymysql.connect(host='192.168.56.4',user='root',passwd='123456',db='csdn',charset='utf8')
- sql='select * from taob'
- data = pandas.read_sql(sql,conn)
- print(data.head(1))
- # 数据样例如下, 和 mysql 字段相匹配的:
0 买 2 袋减 2 元 印尼进口菲那菲娜虾味木薯片油炸大龙虾片零食品 400g
- link price comment 0 https: //item.taobao.com/item.htm?id=44350560220 50 2577
可以看看数据的中位数和均值:
- print(data.describe())
- price comment
- count 9616.00000 9616.000000
- mean 64.49324 562.239601 # 均值
- std 176.10901 6078.909643
- min 0.00000 0.000000
- 25% 20.00000 16.000000
- 50% 36.00000 58.000000 # 中位数
- 75% 66.00000 205.000000
- max 7940.00000 454037.000000
对 price 列的数据清洗
缺失值的处理:
我们先了解下这样的判断方法:
- a={1:'a',2:'b'}
- print([a[1]=='a'])
上述代码打印结果必然是 True, 小括号 ([]) 相当于 if 判断了, 返回的值为布尔值
下面对 price 为 0 的值 (也就是缺失值) 进行处理
data['price'][(data['price'] == 0)] = None# 对 price 的缺失值统统赋值为 None, 方便下面处理 data['price'][(data['price'] == 0)] = 64# 也可以这样写, 直接把 price 的缺失值设置为 price 的平均数 64. 那么下面的
for 循环设置 price 的缺失值就不需要写
对上面这段代码拆分来看:
(data['price']==0) 判断 data['price']列中哪行 price 的值等于 0, 等于的返回 True, 不等于返回 False
data['price'][(data['price']==0)] 这语句就是一下子把所有 price=0 的给取出来了 , 然后哪行的 price 等于 0 就 赋值为 None
- for i in data.columns: # 遍历 data 的每列
- for j in range(len(data)): # 遍历 data 的每一行了
- if data[i].isnull()[j]: # i 在这是一维 (列),data[i] 等于把这一列的值取出来了, j 在这里是二维 (行),i 相当于 XY 轴的 X 轴, j 相当于 XY 轴的 Y 轴, data[i].isnull 是判断整列的某一个值是 nan 那么就返回 True,data[i].isnull[j] 是逐行逐行的判断是否为 nan 了, 是的话返回 True 从而进行下面代码块的处理
- data[i][j]=64 # 缺失值设置为均值
异常值处理:
1. 找到异常值: 通过画散点图(横轴: 价格, 纵轴: 评论数)
我们这里的话要选取评论数, 价钱通常的方法就是说通过遍历每一行的数据, 取每一行中的 price 值, 但是呢这个方法效率低下
对此我们可以采用转置方法, 把 price 列转置为一行, 这样就能够快速取到这价钱的数据, 还有评论数
下面请看代码:
- dataT=data.T # 转置下数据
- prices = dataT.values[2] # 取第 3 行数据
- comments = dataT.values[3] # 取第 4 行数据
- pylab.plot(prices,comments,'o') # 画散点图
- pylab.xlabel('prices')
- pylab.ylabel('comments')
- pylab.title("The Good's price and comments")
- pylab.show()
处理异常数据, 我这里定义的异常数据就是评论数超过 20W, 价格大于 2000, 请看代码:
- line = len(data.values) # 取行数
- col = len(data.values[0]) # 取列数
- davalues = data.values #取 data 的所有值
- for i in range(0,line): # 遍历行数
- for j in range(0,col): #遍历列数
- if davalues[i][3]>200000: #判断评论数
- #print('comments==i,j',i,j,davalues[i][j])
- davalues[i][j] = 562 # 评论数取平均值
- if davalues[i][2]>2000:
- davalues[i][j] = 64 # 价钱取平均值
- prices2=davalues.T[2]
- comments2=davalues.T[3]
- pylab.plot(prices2,comments2,'or')
- pylab.xlabel('prices')
- pylab.ylabel('comments')
- pylab.title("The Good's price and comments")
- pylab.show()
此时, 我们看图:
显然我们已经对评论数超过 20W, 价格大于 2000 的数据处理了, 但是呢上图显示的还是不够漂亮, 因为异常点与正常点的差距太大了, 导致正常点与正常点之间的间隔非常小, 小到黏在一块了, 所以我们还需要在处理下, 把评论数超过 2000, 价格大于 300 的处理掉, 这样的话, 正常点就能够很好的展现在图上, 代码如下:
- line = len(data.values) # 取行数
- col = len(data.values[0]) # 取列数
- davalues = data.values #取 data 的所有值
- for i in range(0,line): # 遍历行数
- for j in range(0,col): #遍历列数
- if davalues[i][3]>2000: #判断评论数,=== 主要修改这行
- #print('comments==i,j',i,j,davalues[i][j])
- davalues[i][j] = 562 # 评论数取平均值
- if davalues[i][2]>300: # ==== 主要修改这行
- davalues[i][j] = 64 # 价钱取平均值
- prices2=davalues.T[2]
- comments2=davalues.T[3]
- pylab.plot(prices2,comments2,'or')
- pylab.xlabel('prices')
- pylab.ylabel('comments')
- pylab.title("The Good's price and comments")
- pylab.show()
- full example:
- import pymysql
- import numpy
- import pandas
- from matplotlib import pylab
- # 缺失值处理
- #======
- data['price'][(data['price']==0)]=64 # 对 price 的缺失值统统赋值为平均数
- # 异常值处理:
- # 1. 找到异常值: 通过画散点图(横轴: 价格, 纵轴: 评论数)
- # 我们这里的话要选取评论数, 价钱通常的方法就是说通过遍历每一行的数据, 取每一行中的 price 值, 但是呢这个方法效率低下,
- # 对此我们可以采用转置方法, 把 price 列转置为一行, 这样就能够快速取到这价钱的数据, 还有评论数
- # 处理异常数据, 我这里定义的异常数据就是评论数超过 20W, 价格大于 2000
- conn = pymysql.connect(host='192.168.56.4',user='root',passwd='123456',db='csdn',charset='utf8')
- sql='select * from taob'
- data = pandas.read_sql(sql,conn)
- line = len(data.values) # 取行数
- col = len(data.values[0]) # 取列数
- davalues = data.values #取 data 的所有值
- for i in range(0,line): # 遍历行数
- for j in range(0,col): #遍历列数
- if davalues[i][3]>2000: #判断评论数
- #print('comments==i,j',i,j,davalues[i][j])
- davalues[i][j] = 562 # 评论数取平均值
- if davalues[i][2]>300:
- davalues[i][j] = 64 # 价钱取平均值
- prices2=davalues.T[2]
- comments2=davalues.T[3]
- pylab.plot(prices2,comments2,'or')
- pylab.xlabel('prices')
- pylab.ylabel('comments')
- pylab.title("The Good's price and comments")
- pylab.show()
生成的图如下:
这张图就很直观的看出, 价钱和评论数的关系了, 价钱在 100 以内的, 评论数也比较多, 价钱越高, 评论数相对来说越少
数据集成与数据离散化
数据集成: 不同来源的数据集合在一起, 需要注意格式保持一致
for example:
我这里有 2 个表数据, 淘宝与京东的, 淘宝的表就如上面所述的一样, 标题, url, 价钱, 评论, 那么京东的下标为 2 的列也必须是价钱, 只有数据格式保持一致, 才能分析
数据离散化: 处理连续数据较好的方法离散化就是指数据不集中, 分散了
for example:
一个班的考试成绩就是从 0-100 分之间, 这个数据是在 100 以内连续的, 那么我们对这个数据分析的时候就可以这么做, 把连续的数据或者近似连续的数据整合在一个点附近, 比如 0-60 分为及格, 60-80 为良好.....
商品数据分布分析实战
我们在这里要分析商品数据的分布, 看评论数与价钱的在哪个数量段的分布最多 首先我们需要计算出价钱和评论的最值, 其次在计算最值之间的极差, 最后计算组距 (极差 / 组数, 组数自己根据情况定义) 下面请看代码:
- # 数据分布:
- # 1 求最值
- # 2 计算极差
- # 3 组距: 极差 / 组数
- da2=davalues.T
- # print('=======')
- # print(data['price'])
- pricemax = da2[2].max()
- pricemin = da2[2].min()
- commentmax = da2[3].max()
- commentmin = da2[3].min()
- # 极差
- pricerg = pricemax - pricemin
- commentrg = commentmax -commentmin
- # 组距
- pricedst = pricerg/10
- commentdst = pricerg/10
- # 绘制直方图
- # numpy.arrange(最小值, 最大值, 组距)
- # 价钱直方图
- pricesty = numpy.arange(pricemin,pricemax,pricedst)
- pylab.hist(da2[2],pricesty)
- pylab.show()
- # 评论直方图
- commentty = numpy.arange(commentmin,commentmax,commentdst)
- pylab.hist(da2[3],pricesty)
- pylab.show()
评论直方图如下:
结论:
从上图中我们可以看出, 评论数最多的集中在 100 元以内的商品, 评论数也间接的说明了购买数, 因为购买后才能够评论
所以可以根据这个来直方图来给商品定价
价钱直方图如下:
结论:
从上图中我们可以看出, 商品价钱最多的集中在 50 元以内的商品
- code full example:
- #!/usr/bin/env python
- # __author__:Leo
- import pymysql
- import numpy
- import pandas
- from matplotlib import pylab
- conn = pymysql.connect(host='192.168.56.4',user='root',passwd='123456',db='csdn',charset='utf8')
- sql='select * from taob'
- data = pandas.read_sql(sql,conn)
- # 缺失值处理
- data['price'][(data['price']==0)]=64 # 对 price 的缺失值统统赋值为 price 的平均数
- # 异常值处理:
- # 1. 找到异常值: 通过画散点图(横轴: 价格, 纵轴: 评论数)
- # 我们这里的话要选取评论数, 价钱通常的方法就是说通过遍历每一行的数据, 取每一行中的 price 值, 但是呢这个方法效率低下,
- # 对此我们可以采用转置方法, 把 price 列转置为一行, 这样就能够快速取到这价钱的数据, 还有评论数
- line = len(data.values) # 取行数
- col = len(data.values[0]) # 取列数
- davalues = data.values #取 data 的所有值
- for i in range(0,line): # 遍历行数
- for j in range(0,col): #遍历列数
- if davalues[i][3]>2000: #判断评论数
- #print('comments==i,j',i,j,davalues[i][j])
- davalues[i][j] = 562 # 评论数取平均值
- if davalues[i][2]>300:
- davalues[i][j] = 64 # 价钱取平均值
- prices2=davalues.T[2]
- comments2=davalues.T[3]
- pylab.plot(prices2,comments2,'or')
- pylab.xlabel('prices')
- pylab.ylabel('comments')
- pylab.title("The Good's price and comments")
- pylab.show()
- # 数据分布:
- # 1 求最值
- # 2 计算极差
- # 3 组距: 极差 / 组数
- da2=davalues.T
- # print('=======')
- # print(data['price'])
- pricemax = da2[2].max()
- pricemin = da2[2].min()
- commentmax = da2[3].max()
- commentmin = da2[3].min()
- # 极差
- pricerg = pricemax - pricemin
- commentrg = commentmax -commentmin
- # 组距
- pricedst = pricerg/10
- commentdst = pricerg/10
- # 绘制直方图
- # numpy.arrange(最小值, 最大值, 组距)
- # 价钱直方图
- pricesty = numpy.arange(pricemin,pricemax,pricedst)
- pylab.hist(da2[2],pricesty)
- pylab.show()
- # 评论直方图
- commentty = numpy.arange(commentmin,commentmax,commentdst)
- pylab.hist(da2[3],pricesty)
- pylab.show()
好了, 淘宝商城数据预处理实战到此告一段落, 下面我将继续搞文本相似度匹配
来源: https://juejin.im/entry/5a79b8b2f265da4e88379179