python机器学习爬虫Python中文社区数据挖掘

美团网数据分析——到底有多少人知道这些餐厅?!

2018-04-09  本文已影响562人  我叫钱小钱

特别声明:本文仅兴趣交流,需要数据的简友也可以在下面留言,代码在GitHub上需要自取,转载请联系作者。

本文使用Python、Mysql作为获取数据以及存储清洗的工具,其他还会涉及制作图表(Echarts)、编辑图片(大众点评网)、文案编写(mark down语法)、gif录制(ScreenToGif)、百度地图SDK、排版及润句等。边想边做边学,哪里不会学哪里,看在那么多道工序的份上请不要吝啬您手中赞,点穿屏幕的底下留言给你换个IphonX~

就是出于好奇心皮一下,也没那么多精力做同行业的数据整合,只是想了解有哪些餐厅一辈子都吃不起、哪些店是当下热门、上海餐饮地理分布情况是怎样的、本文也就围绕着以上几个大点,开始美团数据探索之旅。


  1. 数据来源(细节部分不做展开,代码已公开在GitHub上)
  2. 基础分析(可以跳过,一些基本的数据分析方法、流程)
  3. 进阶分析(分析价值,空间数据20180414已更新,代金券分析 )
from pyecharts import Liquid

liquid = Liquid(title="样本数",subtitle='样本总量29876 剔除均价和评分为0的数据所剩的数量26793')
liquid.add("Liquid", [0.89, 0.7, 0.5, 0.3], is_liquid_outline_show=False)
liquid
from pyecharts import Bar,Grid

df = df.head(10)
title = df['title']
avg_price =  df['avg_price']
avg_score = df['avg_score']
comment_num = df['comment_num']

bar = Bar(title="餐饮商家前十排行",subtitle='数据来源神秘组织:*团',width=800,height=400)
bar.add("人均", title, avg_price, mark_point=["min", "max"],mark_line=["average"])
bar.add("评论数", title, comment_num,mark_point=["max"],is_label_show=True, xaxis_rotate=30)

grid = Grid(height=500)
grid.add(bar, grid_bottom="30%")

  • 【黄公子】 人均 2665 RMB
    隐藏在老式洋房里的一家人均千元的定制私房菜,仪式感十足,每天只接受10位顾客的预定,简友们谁家宽裕的可以带我去遛遛 =。=


  • 【洋房火锅】人均 901 RMB
    火锅中的劳斯莱斯...A级和牛600~800,涮一片牛肉小两百...我的天...贫穷真的限制我了我的想象 =。=

from pyecharts import Bar,Grid

sql3 = '''#sql3
select distinct a.sub_id,a.sub_name,
b.poi_id,b.title,b.avg_price,b.avg_score,b.comment_num,b.address from meituan_classify_info as a
inner join meituan_shop_info as b on a.sub_id = b.sub_id and a.class_type = b.class_type
where a.class_type = 1 and a.sub_id not in(24,393,395) and b.avg_price <> 0 and b.avg_score <> 0 
and CONCAT(b.sub_id,b.poi_id) not in ('6342030772','4050576755','6350576755','4052163162','2006068147006','5452800270','4087812358','6387812358','543311762')
order by b.comment_num desc limit 10;
'''
df3 = pd.read_sql(sql3,conn)
data = sorted(df3[['title','comment_num']].values ,key=lambda x: x[1],reverse=True)
attr = [i[0] for i in data]
val = [i[1] for i in data]

bar = Bar()
bar.add('comment_num', attr, val,is_label_show=True,xaxis_rotate=30)
grid3 = Grid(height=500)
grid3.add(bar, grid_bottom="30%")

【燕烤猪蹄店】人均 10 RMB

  • 评论数量第一的竟然是家烤猪蹄店...!! 但为何以如此高的评论数位居榜首?是否存在刷榜行为? 对这块了解的请留言告知~(图3是本尊,喜欢的请点赞!)

from pyecharts import Boxplot

sql = '''select distinct sub_id,sub_name from meituan_classify_info where class_type = 1 and sub_id not in(24,393,395)'''
df = pd.read_sql(sql,conn)

sql2 = '''select distinct poi_id,avg_price,sub_id from meituan_shop_info where class_type = 1 and avg_price <> 0 and avg_score <> 0'''
df2 = pd.read_sql(sql2,conn)

x_axis = []
y_axis = []
for i in df.index:
    sub_id = df.loc[i].values[0]
    sub_name = df.loc[i].values[1]  
    avg_price = df2[df2['sub_id'] == sub_id ]['avg_price'].values
    x_axis.append(sub_name)
    y_axis.append(avg_price)
    
boxplot = Boxplot("菜系数据分布情况")
_yaxis = boxplot.prepare_data(y_axis)   # 转换数据
tp_dict = {k:v for k,v in zip(x_axis,_yaxis)}
idx_tp = sorted([(max(v),k) for k,v in zip(x_axis,_yaxis)])

# 根据max排序
x_ax = []
y_ax = []
for i in idx_tp:
    x_ax.append(i[1])
    y_ax.append(tp_dict[i[1]])
boxplot.add('boxplot', x_ax,y_ax,is_datazoom_show=True, datazoom_type='both',xaxis_rotate=30)

grid = Grid()
grid.add(boxplot, grid_bottom="20%")
from pyecharts import Pie

sorted_df = sorted(df4[['sub_name','cnt']].values, key=lambda x:x[1],reverse=True)
attr = [i[0] for i in sorted_df]
val = [i[1] for i in sorted_df]
    
pie = Pie("*团各大菜系店铺数", title_pos='center', width=800)

pie.add("菜系", attr, val, center=[50, 50], is_random=True,
        radius=[35,65], rosetype='radius',legend_orient='vertical',legend_pos='left',
        is_legend_show=True, is_label_show=True)

# 这里有几个知识点,地理坐标系一共分为几类
# 1.GPS设备获取的角度坐标,wgs84坐标
# 2.国测局坐标,gcj02坐标
# 3.百度经纬度坐标,bd09ll坐标
# 由于坐标信息都是经过加密处理,需要统一坐标才能够使用

sql = '''select round(lng,4),round(lat,4),count(*) * 10 from meituan_shop_map
        group by round(lng,4),round(lat,4);'''
cur.execute(sql)
result = cur.fetchall()
# 将坐标聚类,清洗
hotmap = [{"lng": float(i[0]), "lat": float(i[1]), "count": int(i[2])} for i in result]

  1. 明显的两大区域,分别是以静安寺为中心向南京西路延伸段、人民广场至南京路延申段,两大商业区餐饮商铺成均匀及延续分布,说明不仅店多而且分布广。

  2. 次级区域分别有,上海火车站(不夜城)、中山公园、八佰伴、长寿路
    说明这些地区也有相当部分市场。

  3. 高热集中区域有,陆家嘴、环球港、中山公园、华东大学、马当路地铁站,铜川路等,这些高热特征他们都分布在地铁枢纽区域,地域小店铺分布密集。





  1. 点评极值差异相当大,那么用log10去对评论进行收敛
  2. 价格虽越贵越好吃的概率较大,但为了找到性价比最高的店,这里将价格作为降权处理
  3. 评分最大5分最小0分,将0分提出,也同样对其进行收敛处理
  4. 对3个指标的线性加权,再用算法进行归一化处理(var - min) / (max - min) 就得到了最后的评分
select
    poi_id, title
    ,(result - min_rst) / (max_rst - min_rst) as convergence
    ,comment_num ,comnt ,avg_price ,price ,avg_score ,score, result , max_rst , min_rst
from(
    select 
        poi_id, title
        ,comment_num
        ,ifnull(log(20,comment_num),0) as comnt
        ,avg_price
        ,log10(avg_price) as price
        ,avg_score
        ,ifnull(log2(avg_score),0) as score
        ,ifnull(log(20,comment_num),0) - log10(avg_price) + ifnull(log2(avg_score),0) as result
        ,1 as inner_col
    from meituan_shop_info
    where sub_id = 20059 and avg_price <> 0
) as x 
left join 
(
    select 
    max(ifnull(log(20,comment_num),0) - log10(avg_price) + ifnull(log2(avg_score),0)) as max_rst
    ,min(ifnull(log(20,comment_num),0) - log10(avg_price) + ifnull(log2(avg_score),0)) as min_rst
    ,1 as inner_col
    from meituan_shop_info
    where sub_id = 20059 and avg_price <> 0
) as y on x.inner_col = y.inner_col
order by convergence desc


# 300 - 600价位之间
where x.avg_price between 300 and 600
300-500日料推荐
唉~ 我肯定是吃不起了,虽然我吃不起,但是!!也要满足看客老爷们,千万别问我是谁,大家都叫我雷锋!!!

上面有没有你吃过的店呢?接下来我们看下上面排第一的"舞泽"这家店~


  • 【舞泽】人均 313 RMB
    很多料理都是采用蒸的方法来烹饪的,「生冻雪蟹」「蒸海鲜」「帝王蟹」「茶泡饭」都是特色,这些我都是听说的,等赚到钱了一定要去吃一下~

舞泽

  • ps:科普科普个小知识,IPad研磨工艺就是出自5个人小作坊——小林研业
    小林研业

上一篇 下一篇

猜你喜欢

热点阅读