• 本文运用Python绘图包(matplotlib、pandas)对数据进行可视化分析,并使用Powerpoint制作描述性分析报告。

    本文运用Python绘图包(matplotlib、pandas)对数据进行可视化分析,并使用Powerpoint制作描述性分析报告。

    在这里插入图片描述在这里插入图片描述在这里插入图片描述项目来自Kaggle,点击下载数据
    在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述作者:钱奇天

    展开全文
  • 导读:本文将介绍一个智能项目,我们将使用回归建模方式来模拟Capital Bikeshare系统中的自行车共享数据集,并了解温度、风和时间等变量是如何影响自行车租赁需求的...
        

    640?wx_fmt=gif

    导读:本文将介绍一个智能项目,我们将使用回归建模方式来模拟Capital Bikeshare系统中的自行车共享数据集,并了解温度、风和时间等变量是如何影响自行车租赁需求的。


    作者:曼纽尔·阿米纳特吉(Manuel Amunategui)、迈赫迪·洛佩伊(Mehdi Roopaei)

    如需转载请联系大数据(ID:hzdashuju)


    640?wx_fmt=png


    加州大学尔湾分校的UCI机器学习库慷慨贡献了本文所需的数据集:

    https://archive.ics.uci.edu/ml/datasets/bike+sharing+dataset


    在进行本文实验前,请访问UCI网站下载相关数据集。


    提示:

    请访问

    www.apress.com/9781484238721

    单击“Download source code”按钮,跳转至GitHub网站,下载本文所需文件。推荐使用Jupyter Notebook打开chapter2.ipynb文件,以配合阅读本文内容。



    01 共享单车租赁需求回归系数分析


    本文中,我们将构建一个简单直观的模型,并使其与不同的环境因素进行交互,进而了解这些环境因素是如何影响自行车租赁需求的。对用户来说,这会是一种很好的方式,因为这种方式可以让他们确认关于什么会让他们的用户租赁或不租赁自行车的直观判断。


    当然,在有些情况下,他们也会感到很惊讶(比如,冬天骑车的人居然会比夏天还多——本文中,我们将让你亲眼看到这个现象)。


    这个Web应用背后的“大脑”是一个线性回归模型(linear regression model)。它能够发现历史数据集与模型输出结果之间的线性关系。利用这个原理,通过线性回归模型,我们就可推断随着时间推移和不同环境参数的变化,自行车租赁在需求上的变化。最终我们希望看到的是,这个模型能否帮助我们预测未来的自行车租赁需求。


    记住一点,无论何时,只要你打算将一个Python模型扩展到Web应用,那么在添加任何构建Web应用程序所需的额外层之前,必须解决该模型中当前的所有问题和缺陷(bug)。在将任何应用或内容移至云端前,请先把所有简单问题解决掉!遵循这条建议,后续会减少你很多不必要的麻烦。



    02 探索共享单车原始数据集


    虽然是一种兴起不久的服务,共享单车已经受到极大欢迎。根据人工智能与决策支持实验室的Hadi Fanaee-T的说法(来自UCI机器学习数据集信息库讲义笔记):


    与公共汽车或地铁等其他交通服务相反,共享单车模式中,骑行时长、出发和到达位置在系统中都被明确记录。这一功能将自行车共享系统变成了虚拟传感器网络,利用这个网络,可以感知到一个城市的移动性。因此,通过监测这些数据,城市中发生的很多重要事件都有希望被监控到。


    下载的数据集包括两部分:hour.csv和day.csv,特征细节描述如下:



    1. 下载UCI机器学习库数据集


    你可以使用Python命令行或者手工方式,从UCI的机器学习数据仓库中直接下载数据集。数据集下载地址为:


    https://archive.ics.uci.edu/ml/datasets/bike+sharing+dataset


    下载到的数据中包含三个文件:



    在自行车租赁数据中,日数据集day.csv有731行,小时数据集hour.csv有17 379个记录。


    2. Jupyter Notebook配置使用


    在开始使用本文的记事本文件前,我们首先来回顾一些基础知识。从GitHub上下载源代码文件后,打开终端窗口,然后进入chapter2目录。在这个目录中,你将看到两个文件和一个文件夹,如图2所示。


    640?wx_fmt=png

    ▲图2 终端窗口


    requirements_jupyter.txt文件中包含了运行本文Jupyter记事本文件所需的Python库。通过运行“pip3”命令,你可以快速安装依赖库文件(代码清单①)。



    $ pip3 install -r requirements_jupyter.txt


    图2中,chapter2.ipynb文件就是本文的Jupyter Notebook文件。Jupyter Notebook文件的打开方式很多,最流行的是使用“jupyter notebook”命令(代码清单②)。如果在打开过程中出现问题,请参考Jupyter的官方文档。



    $ jupyter notebook


    此命令将会打开一个浏览器窗口,浏览器中会显示默认路径下的全部文件列表,单击chapter2.ipynb文件超链接,如图3所示。


    640?wx_fmt=png

    图3 Jupyter浏览器界面显示的本文文件


    然后,浏览器将打开一个新的Tab窗口和相应的Notebook界面,其中包含了与本文内容相关的全部探索实验代码。本书全部代码都基于Python 3.x编写。如果你使用其他Python版本,则需要调整部分代码片段。


    在打开的Notebook界面上,单击第一个代码框使其高亮,然后单击上方的运行按钮,如图4所示。如果在执行过程中出现错误,则在继续之前请先解决当前错误,因为Jupyter Notebook中每个代码片段的执行都要依赖之前的执行结果(错误可能与Python的版本兼容性有关,或者缺失了必须安装的依赖库文件)。


    640?wx_fmt=png

    图4 Jupyter Notebook代码框高亮显示并准备执行代码


    Jupyter Notebook代码中都提供了使用Python命令行直接下载数据集的方式(如果存在防火墙问题,则需要手动下载)。


    3. 数据集探索


    Python Pandas库中的head()函数提供了查看数据集中前面几行的功能,如代码清单③和图5所示。



    bikes_hour_df_raw.head()


    执行上述命令后,将看到图5中所示的结果。


    640?wx_fmt=png

    图5 bike_df.head()输出结果


    使用head()函数,我们会看到数据集中有日期格式、整数格式和浮点数格式的数据。另外,还能看到一些冗余的特征,如date(dteday)已经通过season、yr、mnth、hr等进行了分类。因此,数据集的dteday特征是可以抛弃不用的(虽然我们会暂时保留它以满足对数据集的探索需求)。


    其他一些特征似乎是多余的,如temp和atemp,这可能需要进一步检查核实。我们还删除了casual和registered特征,因为这些特征无法帮助我们从单个用户的角度来模拟需求,而这正是我们要实现的Web应用程序重点。


    根据季节、天气等因素预测用户注册数量,这可能会得到一个有趣的预测结果,但是这不符合我们当前的需求范围,因此我们将放弃这些特征。


    本文中,我们仅保留真正需要的数据特征,这可以为我们后续分析消除数据混乱,并让我们的分析过程变得更清晰和易于理解,从而更好地实现我们数据科学和Web应用程序的目标。



    bikes_hour_df = bikes_hour_df_raw.drop(['casual', \'registered'], axis=1)
    'registered'], axis=1)


    Pandas Python库中的info()函数也是查看数据集所包含的数据类型、数量和空值的好方法(代码清单⑤)。



    输入:


    bikes_hour_df.info()


    输出:


    RangeIndex: 17379 entries, 0 to 17378Data columns (total 15 columns):instant      17379 non-null int64dteday       17379 non-null objectseason       17379 non-null int64yr            17379 non-null int64mnth          17379 non-null int64hr            17379 non-null int64holiday      17379 non-null int64weekday      17379 non-null int64workingday  17379 non-null int64weathersit  17379 non-null int64temp         17379 non-null float64atemp        17379 non-null float64hum          17379 non-null float64windspeed   17379 non-null float64cnt          17379 non-null int64
    instant      17379 non-null int64
    dteday       17379 non-null object
    season       17379 non-null int64
    yr            17379 non-null int64
    mnth          17379 non-null int64
    hr            17379 non-null int64
    holiday      17379 non-null int64
    weekday      17379 non-null int64
    workingday  17379 non-null int64
    weathersit  17379 non-null int64
    temp         17379 non-null float64
    atemp        17379 non-null float64
    hum          17379 non-null float64
    windspeed   17379 non-null float64
    cnt          17379 non-null int64


    可以看到,使用info()函数,当前保存在内存中的所有数据都是浮点数或整数类型,并且它们都不是空值。如果我们碰巧有空值、日期数据类型或文本数据类型,则在继续建模之前,我们需要先解决这个问题。


    就目前而言,大多数模型都需要数值类型数据,就如我们这里所拥有的一样,到目前为止我们的数据准备一切还算顺利!


    4. 预测结果变量分析


    接下来,我们将研究用以训练模型的结果变量cnt,即自行车租赁总数。Pandas库中的describe()函数是了解量化数据的另一种必备工具。此处,我们将它用于结果变量(也称为模型的标签),如代码清单⑥所示。



    输入:


    bikes_hour_df['cnt'].describe()


    输出:


    count 17379.000000mean  189.463088std   181.387599min   1.00000025%   40.00000050%   142.00000075%   281.000000max   977.000000Name: cnt, dtype: float64
    std   181.387599
    min   1.000000
    25%   40.000000
    50%   142.000000
    75%   281.000000
    max   977.000000
    Name: cnt, dtype: float64


    上述输出结果中,我们可以看到,cnt的值在最小值1和最大值977之间,也就是说在每一个有记录的小时内,自行车租赁数量最小是1辆,最多时是977辆,还可以看到,每小时平均自行车租赁数量是189.5辆。


    另外,还可以确认我们所处理的是一个连续数值变量问题,因此,对于自行车租赁数量的训练和预测,线性回归(或者类似线性回归的模型)将是最佳选择。下面,我们将cnt数据绘制出来,以便更好地理解它,如代码清单⑦和图6所示。



    fig,ax = plt.subplots(1)ax.plot(sorted(bikes_hour_df['cnt']), color='blue')ax.set_xlabel("Row Index", fontsize=12)ax.set_ylabel("Sorted Rental Counts", fontsize=12)ax.set_ylabel("Sorted Rental Counts", fontsize=12)fig.suptitle('Outcome Variable - cnt - Rental Counts')plt.show()
    ax.plot(sorted(bikes_hour_df['cnt']), color='blue')
    ax.set_xlabel("Row Index", fontsize=12)
    ax.set_ylabel("Sorted Rental Counts", fontsize=12)
    ax.set_ylabel("Sorted Rental Counts", fontsize=12)
    fig.suptitle('Outcome Variable - cnt - Rental Counts')
    plt.show()


    绘制结果如图6所示。


    640?wx_fmt=png

    ▲图6 自行车租赁数量排序结果显示,大部分租赁值在0~400范围内;高出部分属于稀有或异常值


    5. 量化特征与租赁统计


    接下来,我们将创建所有浮点类型数据的散点图。我们将基于租赁计数来进行绘制,以显示与租赁计数相关的潜在关系,如图7和图8所示。


    640?wx_fmt=png

    图7 自行车被租赁数量与气温关系散点图(温度值已做归一化处理)


    640?wx_fmt=png

    图8 自行车被租赁数量与体表温度关系散点图(温度值已做归一化处理)


    可以看到,被租用的自行车数量和温度之间存在某种程度的线性关系;天气越温暖,租来的自行车越多。还可以看到,temp和atemp这两个特征具有相似的分布,并且可能出现冗余甚至多重共线性。为了保持单一线性,我们将删除atemp特征(在图9和图10中,仅有temp,而没有atemp特征)。


    640?wx_fmt=png

    图9 自行车租赁数量与湿度关系散点图(湿度值已做归一化处理)


    640?wx_fmt=png

    图10 自行车租赁数量与风速关系散点图(风速值已做归一化处理)


    可以看到,特征hum或者湿度散点图中,所有数据点几乎都密集在一个范围内,尽管边缘处也出现了稀疏点。windspeed特征散点图中,风速与自行车租赁数量之间确实显示了非线性关系,风速越大,自行车租赁数量越少!


    6. 分类特征研究


    在我们已下载的数据集中,除了自行车租赁计数特征cnt外,其他的整数数据都具有分类特征。通过直方图查看时,分类数据会产生许多有趣的信息,如图11所示。


    640?wx_fmt=png

    图11 依据season和weathersit分类的自行车租赁数量直方图


    上图中可以看到,weathersit直方图表明好天气的时候,人们更喜欢租赁自行车;season直方图表明秋天是自行车租赁的高峰季节。


    最后是特征hr或租赁时间直方图,清楚显示上班高峰时间和下午骑行时间段租赁自行车人数最多,而凌晨4点是最不受欢迎的骑行时间,如图12所示。


    640?wx_fmt=png

    图12 按时间分类的自行车租赁数量直方图


    尽管我们可以通过图表绘制方式来了解到很多东西,但是仍然需要进行更彻底和系统的检测,才能做出哪些特征需要保留,哪些特征需要抛弃的决策。



    03 数据建模准备工作


    在大多数数据科学项目中,存在一个数据预处理阶段,在这个阶段会进行数据评估和清理,以实现数据的“模型就绪”。在清理阶段,我们已经放弃了一些无用的数据特征,同时也清除了可能存在的空值,我们也不用担心相关性或多重共线性,因为在最终模型中,我们仅会使用四个简单的特征。


    1. 回归建模


    在统计分析中,回归模型试图预测变量之间的关系。它主要用于分析独立变量与依赖变量的关系,而拟合模型(fitted model)则可用于预测依赖变量的新变化。


    2. 简单线性回归


    线性回归可能是最简单的建模算法。它试图解释一个因变量和一个或多个自变量之间的关系。基本的线性回归方程如图13所示。


    640?wx_fmt=png

    图13 基本线性回归方程


    在上述方程中,y是因变量,β0是常数,β1是回归系数,x是自变量。


    3. 简单线性回归模型


    这里,从一个简单的多线性回归模型开始,我们输入所有变量并获得均方根误差(RMSE)。RMSE最终转化到与结果变量(也称为y轴标签)相同的单位来表示误差(即RMSE值与y值具有相同量纲),因此很容易看出模型在学习/预测自行车租赁方面表现如何,而误差是置信区间的一种表现形式。


    你所关注的是尽可能希望获得较低的RMSE值,因此我们的目标是不断调整数据和模型,直到RMSE值停止继续降低为止。本文中,我们所有建模工作都基于Python scitkit-learn /sklearn库。这是一个很了不起的Python库,几乎可以满足大多数Python用户的建模需求。


    尽管我们只打算进行简单的线性回归,但我们还是用到了sklearn库中的三个函数:train_test_split函数从原始数据中创建两个随机数据集,并从结果中分离特征;linear_model函数运行我们的模型;mean_squared_error函数评估模型的学习效果(代码清单⑧)。



    outcome = 'cnt'# create feature listfeatures = [feat for feat in list(bike_df_model_ready) if feat not in[outcome, 'instant']]# split data into train and test portionsfrom sklearn.model_selection import train_test_splitX_train, X_test, y_train, y_test = train_test_split(bike_df_model_\ready[features],bike_df_model_ready[['cnt']],test_size=0.3,\ random_state=42)
    # create feature list
    features = [feat for feat in list(bike_df_model_ready) if feat not in
    [outcome, 'instant']]
    # split data into train and test portions
    from sklearn.model_selection import train_test_split
    X_train, X_test, y_train, y_test = train_test_split(bike_df_model_\
    ready[features],bike_df_model_ready[['cnt']],test_size=0.3,\ 
    random_state=42)


    train_test_split()函数基于用户指定的种子参数将原始数据集拆分为两个随机数据集。无论何时,如果想要测试不同的方法,并希望确保始终使用相同的拆分以进行不同方法的公平比较,则设置random_state种子参数是个不错的选择。


    test_size参数设置测试拆分的大小,在这里我们将它设置为0.3或30%,因此最终结果将是数据集中70%的数据分配给了训练集,而剩余30%的数据分配给测试集(代码清单⑨)。



    from sklearn import linear_model model_lr = linear_model.LinearRegression()# train the model on training portionmodel_lr.fit(X_train, y_train)import linear_model 
    model_lr = linear_model.LinearRegression()
    # train the model on training portion
    model_lr.fit(X_train, y_train)


    我们事先声明一个LinearRegression()模型,然后调用fit()函数,使用训练数据和训练标签来训练模型。执行上述代码后,模型model_lr即经过训练并准备好进行预测(代码清单⑩)。



    输入:


    predictions = model_lr.predict(X_test)from sklearn.metrics import mean_squared_errorprint("Root Mean squared error: %.2f" % \ sqrt(mean_squared_error(y_test,predictions)))from sklearn.metrics import mean_squared_error
    print("Root Mean squared error: %.2f" % \ sqrt(mean_squared_error(y_test,predictions)))


    输出:


    Root Mean squared error: 143.08


    最后,我们调用函数predict(),并将分配为测试集的剩余30%数据传入函数,然后将预测标签值输入函数mean_squared_error()求取均方根误差值。我们最终得到的RMSE值为143.08,同时我们将其作为后续预测的基准参考值。


    上述结果,也就是我们基于目前选择的数据特征和拆分种子值(我们在train_test_split函数上应用的种子,这可以确保我们每次都得到相同的数据分割)所得到的结果。


    理解这个RMSE值的一种方式,就是我们的模型预测的偏差是143辆自行车(因为它与我们的结果变量处于相同的量纲)。考虑到每小时自行车平均租赁数量大约是190辆,因此,与简单采用自行车租赁的全局平均值相比,我们的模型做得更好。


    我们能否通过几种技术手段(主要包括多项式、非线性建模和利用时间序列),获取更好的预测模型?由于篇幅有限,关于此问题的讨论请见机器学习即服务》一书第2.4节。


    关于作者:曼纽尔·阿米纳特吉(Manuel Amunategui) 是SpringML(谷歌云和Salesforce的优选合作伙伴)的数据科学副总裁,拥有预测分析和国际管理硕士学位。在机器学习、医疗健康建模等方面有着丰富的咨询经验。

    迈赫迪·洛佩伊(Mehdi Roopaei)迈赫迪·洛佩伊(Mehdi Roopaei) 是IEEE、AIAA和ISA的高级成员。他的研究兴趣包括人工智能驱动的控制系统、数据驱动决策、机器学习和物联网(IoT),以及沉浸式分析。


    本文摘编自机器学习即服务:将Python机器学习创意快速转变为云端Web应用程序,经出版方授权发布。


    延伸阅读《机器学习即服务

    点击上图了解及购买

    转载请联系微信:DoctorData


    推荐语:本书涵盖Kubernetes架构、部署、核心资源类型、系统扩缩容、存储卷、网络插件与网络本书由浅入深地介绍了一系列常见的Python数据科学问题。通过本书,你将学习如何构建一个Web应用程序以进行数值或分类预测,如何理解文本分析,如何创建强大的交互界面,如何对数据访问进行安全控制,以及如何利用Web插件实现信用卡付款和捐赠。


    640?


    「大数据」内容合伙人之「鉴书小分队」上线啦!


    最近,你都在读什么书?有哪些心得体会想要跟大家分享?


    数据叔最近搞了个大事——联合优质图书出版商机械工业出版社华章公司发起鉴书活动。


    简单说就是:你可以免费读新书,你可以免费读新书的同时,顺手码一篇读书笔记就行。详情请在大数据公众号后台对话框回复合伙人查看。


    640?


    有话要说?


    Q: 你会在什么时段、什么天气下使用共享单车?

    欢迎留言与大家分享


    猜你想看? 



    更多精彩? 


    在公众号对话框输入以下关键词

    查看更多优质内容!


    PPT | 报告 | 读书 | 书单 | 干货 

    大数据 | 揭秘 | Python | 可视化

    AI | 人工智能 | 5G | 区块链

    机器学习 | 深度学习 | 神经网络

    1024 | 段子 数学 | 高考


    据统计,99%的大咖都完成了这个神操作

    ? 


    640?wx_fmt=png


    觉得不错,请把这篇文章分享给你的朋友

    转载 / 投稿请联系:baiyu@hzbook.com

    更多精彩,请在后台点击“历史文章”查看

    640?wx_fmt=jpeg

    640?wx_fmt=gif点击阅读原文,了解更多

    展开全文
  • 如今,在城市中随处可见共享单车的身影,给人们的生活出行带来了便利。相信大家总会遇到这样的窘境,在APP中能看到很多单车,但走到那里的时候,才发现车并不在那里。有些车不知道藏到了哪里;有些车或许是在高楼的...

    0?wx_fmt=gif&wxfrom=5&wx_lazy=1

    共享经济的浪潮席卷着各行各业,而出行行业是这股大潮中的主要分支。如今,在城市中随处可见共享单车的身影,给人们的生活出行带来了便利。相信大家总会遇到这样的窘境,在APP中能看到很多单车,但走到那里的时候,才发现车并不在那里。有些车不知道藏到了哪里;有些车或许是在高楼的后面,由于有GPS的误差而找不到了;有些车被放到了小区里面,一墙之隔让骑车人无法获得到车。


    那么有没有一个办法通过获得这些单车的数据,来分析这些车是否变成了僵尸车?是否有人故意放到小区里面让人无法获取呢?带着这些问题,笔者开始了研究如何获取这些数据。



    01 从哪里获得数据


    如果你能够看到数据,那么我们总有办法自动化的获取到这些数据。只不过获取数据的方式方法决定了获取数据的效率。


    对于摩拜单车的数据分析这个任务而言,这个爬虫要能够在短时间内(通常是10分钟左右)获取到更多的数据,对于数据分析才有用处。那么数据来源于哪里?


    最直接的来源是摩拜单车的APP。现代的软件设计都讲究前后端分离,而且服务端会同时服务于APP、网页等。在这种趋势下我们只需要搞清楚软件的HTTP请求就好了。一般而言有以下一些工具可以帮忙:


    直接抓包:

    • Wireshark (在路由器或者电脑)

    • Shark for Root (Android)


    用代理进行HTTP请求抓包及调试:

    • Fiddler 4

    • Charles

    • Packet Capture (Android)


    由于我的手机没有root,在路由器上抓包又太多的干扰,对于https也不好弄。所以只能首先采用Fiddler或者Charles的方式试试。


    挂上Fiddler的代理,然后在手机端不停的移动位置,看有没有新的请求。但遗憾的是似乎请求都是去拿高德地图的,并没有和摩拜车相关的数据。


    那怎么一回事?试试手机端的。换成Packet Capture后果然就有流量了,在请求中找到了我最关心的那个:


    这个API请求一看就很显然了,在postman中试了一下能够正确的返回信息,看来就是你了!


    高兴得太早。


    连续爬了几天的数据,将数据进行一分析,发现摩拜单车的GPS似乎一直在跳动,有时候跳动会超过几公里的距离,显然不是一个正常的值。


    难道是他们的接口做了手脚返回的是假数据?我观察到即便在APP中,单车返回的数据也有跳动。有某一天凌晨到第二天早上,我隔段时间刷新一下我家附近的车,看看是否真的如此。


    图片我找不到了,但是观察后得出的结论是,APP中返回的位置确实有问题。有一台车放在一个很偏僻的位置,一会儿就不见了,待会儿又回来了,和我抓下来的数据吻合。


    而且这个跳动和手机、手机号、甚至移动运营商没有关系,说明这个跳动是摩拜接口的问题,也可以从另一方面解释为什么有时候看到车但其实那里没有车。


    这是之前发的一个朋友圈的视频截图,可以看到在营门口附近有一个尖,在那里其实车是停住的,但是GPS轨迹显示短时间内在附近攒动,甚至攒动到很远,又回到那个位置。


    这样的数据对于数据分析来讲根本没法用,我差点就放弃了。


    随着微信小程序的火爆,摩拜单车也在第一时间出了小程序。我一看就笑了,不错,又给我来了一个数据源,试试。


    用Packet Capture抓了一次数据后很容易确定API。抓取后爬取了两三天的数据,发现出现了转机,数据符合正常的单车的轨迹。


    剩下事情,就是提高爬虫的效率了。



    02 其他尝试


    有时候直接分析APP的源代码会很方便的找到API入口,将摩拜的Android端的APP进行反编译,但发现里面除了一些资源文件有用外,其他的文件都是用奇虎360的混淆器加壳的。网上有文章分析如何进行脱壳,但我没有太多时间去钻研,也就算了。


    摩拜单车的API之所以很容易抓取和分析,很大程度上来讲是由于API设计的太简陋:


    • 仅使用http请求,使得很容易进行抓包分析

    • 在这些API中都没有对request进行一些加密,使得自己的服务很容易被人利用。

    • 另外微信小程序也是泄露API的一个重要来源,毕竟在APP中request请求可以通过native代码进行加密然后在发出,但在小程序中似乎还没有这样的功能。


    如果大家有兴趣,可以试着看一下小蓝单车APP的request,他们使用https请求,对数据的request进行了加密,要抓取到他们的数据难度会增加非常多。


    当然了,如果摩拜单车官方并不care数据的事情的话,这样的API设计也是ok的。


    声明:


    此爬虫仅用于学习、研究用途,请不要用于非法用途。任何由此引发的法律纠纷自行负责。


    03 目录结构


        \analysis - jupyter做数据分析
        \influx-importer - 导入到influxdb,但之前没怎么弄好
        \modules - 代理模块
        \web - 实时图形化显示模块,当时只是为了学一下react而已,效果请见这里
        crawler.py - 爬虫核心代码
        importToDb.py - 导入到postgres数据库中进行分析
        sql.sql - 创建表的sql
        start.sh - 持续运行的脚本



    04 思路


    核心代码放在crawler.py中,数据首先存储在sqlite3数据库中,然后去重复后导出到csv文件中以节约空间。

    摩拜单车的API返回的是一个正方形区域中的单车,我只要按照一块一块的区域移动就能抓取到整个大区域的数据。

    left,top,right,bottom定义了抓取的范围,目前是成都市绕城高速之内以及南至南湖的正方形区域。offset定义了抓取的间隔,现在以0.002为基准,在DigitalOcean 5$的服务器上能够15分钟内抓取一次。

        def start(self):
            left = 30.7828453209
            top = 103.9213455517
            right = 30.4781772402
            bottom = 104.2178123382

            offset = 0.002

            if os.path.isfile(self.db_name):
                os.remove(self.db_name)

            try:
                with sqlite3.connect(self.db_name) as c:
                    c.execute('''CREATE TABLE mobike
                        (Time DATETIME, bikeIds VARCHAR(12), bikeType TINYINT,distId INTEGER,distNum TINYINT, type TINYINT, x DOUBLE, y DOUBLE)''')
            except Exception as ex:
                pass

    然后就启动了250个线程,至于你要问我为什么没有用协程,哼哼~~我当时没学~~~其实是可以的,说不定效率更高。

    由于抓取后需要对数据进行去重,以便消除小正方形区域之间重复的部分,最后的group_data正是做这个事情。

            executor = ThreadPoolExecutor(max_workers=250)
            print("Start")
            self.total = 0
            lat_range = np.arange(left, right, -offset)
            for lat in lat_range:
                lon_range = np.arange(top, bottom, offset)
                for lon in lon_range:
                    self.total += 1
                    executor.submit(self.get_nearby_bikes, (lat, lon))

            executor.shutdown()
            self.group_data()

    最核心的API代码在这里。小程序的API接口,搞几个变量就可以了,十分简单。

        def get_nearby_bikes(self, args):
            try:
                url = "https://mwx.mobike.com/mobike-api/rent/nearbyBikesInfo.do"

                payload = "latitude=%s&longitude=%s&errMsg=getMapCenterLocation" % (args[0], args[1])

                headers = {
                    'charset': "utf-8",
                    'platform': "4",
                    "referer":"https://servicewechat.com/wx40f112341ae33edb/1/",
                    'content-type': "application/x-www-form-urlencoded",
                    'user-agent': "MicroMessenger/6.5.4.1000 NetType/WIFI Language/zh_CN",
                    'host': "mwx.mobike.com",
                    'connection': "Keep-Alive",
                    'accept-encoding': "gzip",
                    'cache-control': "no-cache"
                }

                self.request(headers, payload, args, url)
            except Exception as ex:
                print(ex)

    最后你可能要问频繁的抓取IP没有被封么?其实摩拜单车是有IP的访问速度限制的,只不过破解之道非常简单,就是用大量的代理。

    我是有一个代理池,每天基本上有8000以上的代理。在ProxyProvider中直接获取到这个代理池然后提供一个pick函数用于随机选取得分前50的代理。


    请注意,我的代理池是每小时更新的,但是代码中提供的jsonblob的代理列表仅仅是一个样例,过段时间后应该大部分都作废了。

    在这里用到一个代理得分的机制。我并不是直接随机选择代理,而是将代理按照得分高低进行排序。每一次成功的请求将加分,而出错的请求将减分。


    这样一会儿就能选出速度、质量最佳的代理。如果有需要还可以存下来下次继续用。

    class ProxyProvider:
        def __init__(self, min_proxies=200):
            self._bad_proxies = {}
            self._minProxies = min_proxies
            self.lock = threading.RLock()

            self.get_list()

        def get_list(self):
            logger.debug("Getting proxy list")
            r = requests.get("https://jsonblob.com/31bf2dc8-00e6-11e7-a0ba-e39b7fdbe78b", timeout=10)
            proxies = ujson.decode(r.text)
            logger.debug("Got %s proxies", len(proxies))
            self._proxies = list(map(lambda p: Proxy(p), proxies))

        def pick(self):
            with self.lock:
                self._proxies.sort(key = lambda p: p.score, reverse=True)
                proxy_len = len(self._proxies)
                max_range = 50 if proxy_len > 50 else proxy_len
                proxy = self._proxies[random.randrange(1, max_range)]
                proxy.used()
                return proxy

    在实际使用中,通过proxyProvider.pick()选择代理,然后使用。如果代理出现任何问题,则直接用proxy.fatal_error()降低评分,这样后续就不会选择到这个代理了。

        def request(self, headers, payload, args, url):
            while True:
                proxy = self.proxyProvider.pick()
                try:
                    response = requests.request(
                        "POST", url, data=payload, headers=headers,
                        proxies={"https": proxy.url},
                        timeout=5,verify=False
                    )

                    with self.lock:
                        with sqlite3.connect(self.db_name) as c:
                            try:
                                print(response.text)
                                decoded = ujson.decode(response.text)['object']
                                self.done += 1
                                for x in decoded:
                                    c.execute("INSERT INTO mobike VALUES (%d,'%s',%d,%d,%s,%s,%f,%f)" % (
                                        int(time.time()) * 1000, x['bikeIds'], int(x['biketype']), int(x['distId']),
                                        x['distNum'], x['type'], x['distX'],
                                        x['distY']))

                                timespend = datetime.datetime.now() - self.start_time
                                percent = self.done / self.total
                                total = timespend / percent
                                print(args, self.done, percent * 100, self.done / timespend.total_seconds() * 60, total,
                                      total - timespend)
                            except Exception as ex:
                                print(ex)
                        break
                except Exception as ex:
                    proxy.fatal_error()


    抓取了摩拜单车的数据并进行了大数据分析。以下数据分析自1月19日整日的数据,范围成都绕城区域以及至华阳附近(天府新区)内。成都的摩拜单车的整体情况如下:



    05 标准、Lite车型数量相当


    摩拜单车在成都大约已经有6万多辆车,两种类型的车分别占有率为55%和44%,可见更为好骑的Lite版本的占有率在提高。(1为标准车,2为Lite车型)


    0?wx_fmt=jpeg



    06 三成左右的车没有移动过


    数据分析显示,有三成的单车并没有任何移动,这说明这些单车有可能被放在不可获取或者偏僻地方。市民的素质还有待提高啊。



    07 出行距离以3公里以下为主


    数据分析显示3公里以下的出行距离占据了87.2%,这也十分符合共享单车的定位。100米以下的距离也占据了大量的数据,但认为100米以下的数据为GPS的波动,所以予以排除。


    0?wx_fmt=jpeg

    出行距离分布



    08 骑行次数以5次以下居多


    单车的使用频率越高共享的效果越好。从摩拜单车的数据看,在流动的单车中,5次以下占据了60%左右的出行。但1次、2次的也占据了30%左右的份额,说明摩拜单车的利用率也不是很高。


    0?wx_fmt=jpeg

    单车骑行次数


    0?wx_fmt=jpeg单车骑行次数



    09 从单车看城市发展


    从摩拜单车的热图分布来看,成都已经逐步呈现“双核”发展的态势,城市的新中心天府新区正在聚集更多的人和机会。


    0?wx_fmt=jpeg

    双核发展


    原来的老城区占有大量的单车,在老城区,热图显示在东城区占有更多的单车,可能和这里的商业(春熙路、太古里、万达)及人口密集的小区有直接的联系。


    0?wx_fmt=jpeg

    老城区


    而在成都的南部天府新区越来越多也茁壮的发展起来,商业区域和住宅区域区分明显。在晚上,大量的单车聚集在华阳、世纪城、中和,而在上班时间,则大量聚集在软件园附近。


    0?wx_fmt=jpeg

    软件园夜间


    0?wx_fmt=jpeg

    软件园白天


    来源:钱塘大数据


    近期精彩活动(直接点击查看):

    福利 · 阅读 | 免费申请读大数据新书 第21期


    END


    投稿和反馈请发邮件至hzzy@hzbook.com。转载大数据公众号文章,请向原文作者申请授权,否则产生的任何版权纠纷与大数据无关。

    大数据


    为大家提供与大数据相关的最新技术和资讯。


    0?wx_fmt=jpeg0?wx_fmt=jpeg长按指纹 > 识别图中二维码 > 添加关注


    近期精彩文章(直接点击查看):

    华为内部狂转好文,大数据,看这一篇就够了!

    读完这100篇论文,你也是大数据高手!

    如何建立数据分析的思维框架

    百度内部培训资料PPT:数据分析的道与术

    论大数据的十大局限

    打包带走!史上最全的大数据分析和制作工具

    数据揭秘:中国姓氏排行榜

    程序猿分析了42万字歌词后,终于搞清楚民谣歌手唱什么了

    计算机告诉你,唐朝诗人之间的关系到底是什么样的?

    数据分析:微信红包金额分配的秘密

    2000万人口的大北京,上下班原来是这样的(附超炫蝌蚪图)

    大数据等IT职业技能图谱【全套17张,第2版】

    不要跟赌场说谎,它真的比你老婆还了解你

    如果看了这篇文章你还不懂傅里叶变换,那就过来掐死我吧

    不做无效的营销,从不做无效的用户画像开始


    更多精彩文章,请在公众号后台点击“历史文章”查看,谢谢。

    展开全文
  • 共享单车在最近一段时间非常火热,越来越多的研究者对其进行分析,郑宇的这片ppt就是根据共享单车的系统数据进行交通预测
  • 摘要:本文的整理自2017云栖大会-上海峰会上ofo小黄车梅嘉祺的分享讲义,讲义主要分为三部分,分别是唯快不破的共享单车行业,阿里赋能加速小黄车前行及共享单车放慢城市的步调。 在2017云栖大会-上海峰会上,ofo小...

    摘要:本文的整理自2017云栖大会-上海峰会上ofo小黄车梅嘉祺的分享讲义,讲义主要分为三部分,分别是唯快不破的共享单车行业,阿里赋能加速小黄车前行及共享单车放慢城市的步调。

    在2017云栖大会-上海峰会上,ofo小黄车梅嘉祺做了ofo的使命,以及共享单车时代的快与慢的分享。在大数据的时代背景下,数据分析显得尤为重要。作为共享单车的原创者和领骑者,在2015年首创了“无桩单车共享”模式,ofo如今已在全球连接了600万辆共享单车,为全球5个国家,120座城市上亿用户提供了超10亿次高效便捷、绿色低碳的出行服务。ofo也已成为全球最大的、估值最高的共享单车平台。

    828936addde1346e8b90bbd74d903d1dd7dff486

    9ce25a6c874b2b7ac580789c0e086d563d7c7f63

    41e8592b79ddac70db75a4fbd0b6a9039a4dc289

    20583cdd7207b5e089becdc7af378ae2ffe6d85a

    c679ddc46816bcc28cd550feb02a8adcef3381e1

    41e8592b79ddac70db75a4fbd0b6a9039a4dc289

    043f69092ed25addf81d061c5ada09df7609dd13

    cd6d375ec394aacc56b4c1e924f62511c7549270

    b37cf3ca3f024702a86731d1091fde5112a311b2

    6a39396c6a2cab0d06c454eba93341213696cdc2

    e55c073090e240cb59276be9346c7c68a6d166f6

    7f211a36cb71564d2038bf8ed880ab1041cf2c77

    e4b8f278d3c169c4d68d617e53f65bf6c01e691f

    28fa9c7fb1c311bcf03f7c58f8ebfb056ca586e7

    079844e4aa93b267778e5bcdb1ca00052e79379d

    0be58664431c4b7ed6c02ce53b57b522f494f91b

    e01484fe9b2529d882c8fb34f4f43625f44f36fb

    f0839cdb2d26ab404904f55cacc8dbf4f564ff10

    cd15f88301291f19a898afdeb4e93dfc49f5e334


    展开全文
  • 来源:天善智能-秦路-七周成为数据分析师 内容:第一周-数据分析思维,重点内容总结归纳整理。

    数据分析思维的重要性没有思维的数据分析师脑袋中几乎是一团乱麻,不知道问题是否发生;不知道问题在哪;不知道为什么;不知道分析对不对;不确定执行结果;不知道老板给不给加薪。


    三种核心思维(What)

    捋顺思路,将其数据化,落地且贴合业务

    结构化(思维导图辅助)
    1. 将论点归纳和整理

    寻找核心论点

    2. 将论点递进和拆解

    结构拆解,自上而下

    3. 将论点完善和补充

    要求MECE(相互独立,完全穷尽)

    公式化(进一步优化思维导图)
    1. 一切皆可量化[±*/]:
    1. 不同业务叠加可以用加法;
    2. 减法常用来计算业务之间的逻辑关系;
    3. 乘法和除法是各种比例/比率
    2. 最小不可分割:

    直到细化到可以使用原始数据或者某些业务指标

    业务化

    数据分析的思维技巧(Why)

    1. 象限法

    选择两个或三个“独立”的“指标/维度”,将数据进行分类策略驱动,即不同象限的数据对应不同的策略,象限的划分准则需要根据策略/需求来定。如经典的RFM模型(Recency; Frequency; Monetary)。

    2. 多维法

    进一步细分某些维度:用户统计维度,用户行为维度,消费维度,商品维度。精细驱动,可以防止辛普森悖论,也叫钻取(Drill-Down)。

    3. 假设法

    启发思考驱动,在没有直观数据线索或者是进行预测时,对现状做一系列的假设,再进行推理,得出结论。

    4. 指数法

    对数据进行加工。线性加权法,(反)比例法(e.g, 忠诚指数),自然对数法(e.g, 热度)。目标驱动,加工不可直接利用的数据。

    5. 二八法(帕累托图)
    6. 对比法

    “好的数据指标一定是比例或者比率;好的数据分析,一定会用到对比。”一些常用的对比方向:竞争对手,特征和属性,时间同比,时间环比,类别,转化,前后变化。

    7. 漏斗法

    如何再业务时间锻炼分析能力(How)

    1. 保持好奇心
    2. 在生活中练习
    3. 在工作中练习

    小案例

    1. 如何分析找出8月份某线下销售的产品销售额度和去年同比下降了 20%的原因?
    2. 麦肯锡的金字塔思维属于哪种核心思维?
    3. 如何预估上海地区的共享单车投放量?
    4. 在拿不到活动具体数据的情况下,如何证明和衡量活动的有效性呢?
    5. 如何分析一个商品是否该提价?
    6. 为什么啤酒与尿布是错误的?
    展开全文
  • 1 数据分析中的核心思维及思维技巧【学习笔记】1.1 核心思维1.2.思维技巧合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中...
  • 【Udacity数据分析(入门)课程】数据分析的五个步骤:1. Question 提出问题;2. Wrangle 整理数据;3. Explore 探索性数据分析(EDA);4. Draw Conclusions 得出结论;5. Communicate 结果分享
  • 导读:阳春四月,气候转暖。经历了一个冬天蛰伏的共享单车行业,也在美团并购摩拜的一石投掷下,激起了多层涟漪。行业的视线又再次聚集到这里,潜伏的巨头力量又开始涌动。近期,易观...
  • 一、结构化(金字塔) 图1 四原则(或称四步骤) (1)核心论点:寻找金字塔的... (4)验证 :不论是核心论点还是分论点,都应该是可量化的,用数据说话。它们必然是可验证的。 图2 实例 图...
  • 1、数据库是数据存储的集合,列存储组织信息(各属性),行存储表中的明细记录 2、主键唯一,不可为空。 3、order by asc 升序,order by desc 降序 4、where … between …and…/in(…,…)/!=或<>/not in ...
  • 一、基础知识 深度解读Python深拷贝与浅拷贝问题 用Python帮助你抢红包 用 Python 描述 Cookie 和 Session 用Python开发贪吃蛇小游戏 用Python生成抖音字符视频! ...基于 redis 的分布式...
  • ...过去5年,是中国互联网创新飞跃的五年,中国从具有先天人口优势...报告基于丰富的数据、以及鲜活的案例、鲜明的观点从10个方面对中国互联网5年的发展做了全面分析和解读。 报告认为,这五年,中国互联网领
  • 数据早知道,上36dsj看早报!...为此,9月28日,全球智能共享单车首创者与领导者摩拜单车发布“十一小长假共享单车大数据预测报告”,通过大数据人工智能平台“魔方”,以全球180多座城市的历史骑行数据为参考,做出
  • 1、文章信息 《Spatio-Temporal Graph Convolutional Networks: A Deep Learning Framework for Traffic Forecasting》。 2017年第二十七届IJCAI国际人工智能联合会议的一篇会议论文,作者是北京大学数学科学学院...
  • 报告人:葛昱(北京市交通委员会科技处处长) 该报告介绍了基于大数据的公交线网优化项目,主要报告了基于大数据分析得出的关于CBD及东部区域的人口、交通、公交线网特征,为下一步优化做了准备。
  •  共享单车、共享汽车、共享充电宝、共享健身房等,以及伴随着共享经济一同发展的物联网IoT爆发、直播、短视频、人工智能、深度学习、视觉计算等,让我们身处数据大爆炸时代,据统计,在今天我们一天产生的数据量...
  • 本系列部分题目来源于公开网络,取之分享,用之分享,且在撰写答案过程中若引用他人解析则必注明原作者及来源链接。另,不少答案得到寒小阳、管博士、张雨石、王赟、褚博士等七月在线名师审校。 说明:本系列作为...
1 2 3 4 5 ... 11
收藏数 211
精华内容 84
关键字:

ppt 基于共享单车大数据分析