美文网首页机器学习机器学习与模式识别IT相关
美国西雅图人们使用自行车情况分析与预测(进阶)

美国西雅图人们使用自行车情况分析与预测(进阶)

作者: YoghurtIce | 来源:发表于2015-12-31 19:59 被阅读875次

    这篇博客和美国西雅图人们使用自行车情况分析与预测(初步)是姊妹篇,是对前一篇博客的延续,更多的背景信息这里不多介绍,可以去以上提到的博客中找到,同样的所有数据和源代码都是可以重现的。
    和上一篇博客不同的是,这篇博客不在建立模型去预测未来的情况,而是立足于数据,从数据中找出有趣的东西来,换句话说,我们不再像上一篇博客一样去使用有监督的机器学习方法,取而代之,我们使用无监督的学习方法,类似聚类,把具有相似行为的使用自行车的人们进行聚类,挖掘出一些有趣的玩意。

    Part 1: 数据来源

    这篇博客和上篇博客使用的数据基本一致,我们可以在github下载,或者我在博客结尾会给出我本人的联系方式,找我要也行。

    %matplotlib inline
    import matplotlib.pyplot as plt
    import numpy as np
    import pandas as pd
    import seaborn; seaborn.set()  # 这是更高级一点的库,绘图更酷炫
    
    data = pd.read_csv(r"E:\研究生阶段课程作业\python\好玩的数据分析\SeattleBike-master\Fremont_Bridge.csv",index_col = "Date", parse_dates = True)
    data.sample(n = 5)   #随机抽样5个样本
    
    随机抽样5行数据
    data.columns = ["West","East"]   #原来的列名太长,蛋疼,改的简单一些
    data.fillna(0,inplace=True)  #填充null值,用0填充,同时就地填充:就是直接对data进行填充,不用一系列的赋值之类的操作
    data['total'] = data.West + data.East  #增加一个新列,计算每个时刻的经过这座桥的自行车总数
    ![Uploading 5_633120.png . . .]
    
    data.resample('w',how = 'sum').plot()
    
    每周桥上不同方向和总数的自行车数量变化图

    到目前为止,好像和上篇博客没有什么不同,处理方法也是一致的,好啦,下面开始放大招了

    #因为我们想知道人们在不同日期使用自行车的习惯,我们对数据进行透视
    data_pivoted = data.pivot_table(values = ["West","East"], index = data.index.date,columns = data.index.hour,fill_value = 0)
    data_pivoted.sample(n = 10)
    
    经过透视表操作后的数据

    经过处理后的数据列有48维,为了可视化需要,我们对48列进行降维

    from sklearn.decomposition import PCA          #使用自带的pca进行降维
    xpca = PCA(n_components = 2).fit_transform(x)    #只保留2维
    
    total_trips = data_pivoted.sum(1)       #计算每一天的经过自行车总数
    plt.scatter(xpca[:, 0], xpca[:, 1], c=total_trips,
                cmap='cubehelix')
    plt.colorbar(label='total trips');
    

    很明显,我们可以看出这些数据明显可以分成两类,下面要做的就很简单了,聚类开始登场。首先我们使用kmeans

    #首先使用kmeans,聚类的数目为2:
    from sklearn.cluster import KMeans
    kmeans_model = KMeans(n_clusters=2, random_state=1)
    kmeans_model.fit(xpca)
    labels = kmeans_model.labels_
    #对聚类结果进行可视化
    plt.scatter(xpca[:,0],xpca[:,1],c = labels)
    plt.colorbar(label='total trips');
    
    kmeans

    果然kmeans表现的还是那么菜,聚类的效果并不完美,下面我们使用高斯混合模型聚类

    #使用高斯混合模型,进行聚类
    from sklearn.mixture import GMM
    gmm = GMM(2, covariance_type='full', random_state=0)
    gmm.fit(xpca)
    cluster_label = gmm.predict(xpca)
    plt.scatter(xpca[:, 0], xpca[:, 1], c=cluster_label);
    
    9.png

    还是高斯混合模型靠谱啊,多试几种方法,找出最适合你的方法吧

    data_pivoted["Cluster"] = cluster_label
    data_new = data.join(data_pivoted["Cluster"],on = data.index.date)  
    data_new.sample(10)
    
    增加了一个所属类别
    #对两个聚类按照时间分别作图
    #data_new_0        #包含cluster为0的所有数据
    #data_new_1        #包含cluser为1的所有数据
    data_new_0 = data_new[data_new.Cluster == 0]
    data_new_1 = data_new[data_new.Cluster == 1]
    
    by_hour_0 = data_new_0.groupby(data_new_0.index.time).mean()
    by_hour_1 = data_new_1.groupby(data_new_1.index.time).mean()
    
    by_hour_0[["West","East","total"]].plot()
    plt.xlabel("time")
    plt.ylabel("mean of bikes")
    
    第一个类中,自行车数量变化图

    这个结果相当耐人寻味,我们可以看到,差不多在早上八点左右,自行车数量到达第一个巅峰,然后下午五点左右,自行车数量到达第二个巅峰。是不是这些日子都是工作日呢,大家骑着自行车去上班,换句话说,第一个聚类难道都是工作日。这个问题有待继续解答,我们再看第二个聚类的情况.

    by_hour_1[["West","East","total"]].plot()
    plt.xlabel("time")
    plt.ylabel("mean of bikes")
    
    12.png

    和第一个聚类相比,这个结果没有出现明显的波峰,大约在下午两年的时候,自行车数量最多,好吧,你肯定在猜测,这些日子是不是周末呢。大家吃过中饭,骑车出来浪呢。为了搞清楚这些疑问,我们计算每个日期对应的星期几。

    plt.scatter(xpca[:,0],xpca[:,1],c = data_pivoted.index.dayofweek,cmap=plt.cm.get_cmap('jet', 7))
    cb = plt.colorbar(ticks=range(7))
    cb.set_ticklabels(['Mon', 'Tues', 'Wed', 'Thurs', 'Fri', 'Sat', 'Sun'])
    
    13.png

    我们可以得出这样的结论,周六和周末,人们对自行车的使用有着很大的相似,而周一到周五人们对自行车的使用也很相似,结合前面的聚类结果
    但是我们很奇怪的发现一个现象:有一些工作日的人们表现的和周末很相似,这些特别的日子具体是神马日子的,是不是节假日,另外和其他的工作日相比,周五表现的和周末很暧昧不清,这我们需要思考
    另外在工作日的聚类中,我们发现竟然没有一个非工作日的(至少从图中没有发现特例),结果真是这样吗,我们需要进一步的使用数据进行分析

    days = ['Mon', 'Tues', 'Wed', 'Thurs', 'Fri', 'Sat', 'Sun']     #分别对应“dayofweek”:[0,1,2,3,4,5,6]
    def get_weekday(index):
        return days[index.dayofweek]
    data_new_0["weekday"] = data_new_0.index.map(get_weekday)
    data_new_0_exception = data_new_0[data_new_0.weekday.isin(["Sat","Sun"])]#在第一个聚类中,找特例,换句话说,就是找出这样的周六周末,人们对自行车的使用像工作日一样
    len(data_new_0_exception)   #结果和我们在上图可视化的结果一样,没有一个周六周末,人们使用自行车像工作日一样
    out:0
    

    没有一个周末,人们使用自行车和工作日一样,这也能从侧面看出,看来美帝真心不加班啊,不像天朝,加班累成狗。

    data_new_1['weekday'] = data_new_1.index.map(get_weekday)
    data_new_1_exception = data_new_1[data_new_1.weekday.isin(['Mon', 'Tues', 'Wed', 'Thurs', 'Fri'])]#在第2个聚类中,找特例
    len(data_new_1_exception):
    out:600
    

    倒是有不少天,人们在工作日的时候和周六周末使用自行车的习惯差不多,我们猜测这些工作日很可能是假期,真的是这样吗,我们来验证一下。

    date = set(data_new_1_exception.index.date)
    #列出从2012-2016年,美国的所有假期
    from pandas.tseries.holiday import USFederalHolidayCalendar
    cal = USFederalHolidayCalendar()
    holidays = cal.holidays('2012', '2016', return_name=True)
    holidays_all = pd.concat([holidays,
                             "Day Before " + holidays.shift(-1, 'D'),
                             "Day After " + holidays.shift(1, 'D')])
    holidays_all = holidays_all.sort_index()
    holidays_all.ix[(date)]
    

    不出意外,这些表现反常的工作日,全部都在假期中。大家都放假了,当然开始骑车去浪了

    最后一个问题,为什么周五的数据,可视化的时候,有几个点表现的特别反常,这几天究竟发生了什么

    fri_day = (data_pivoted.index.dayofweek == 4)   #周5为true,其他为false
    plt.scatter(xpca[:, 0], xpca[:, 1], c='gray', alpha=0.2)
    plt.scatter(xpca[fri_day, 0], xpca[fri_day, 1], c='yellow');
    
    15.png
    weird_fridays = pivoted.index[fridays & (Xpca[:, 0] < -600)]weird_fridays
    weird_fridays
    out: Index([2013-05-17, 2014-05-16, 2015-05-15], dtype='object')
    

    果然是,周五的这几个奇异点,果然有情况,我查阅了一下资料,这三天是一年一度的
    自行车日。。。。。果然没有无缘无故的爱

    总结

    关于西雅图市人们使用自行车习惯的数据分析到此就结束了,数据蕴含着很多信息等待我们去挖掘。英文过得去的话,建议直接看原文章,如果有不懂的话,再结合这中文译文进行参照,如果你对python和机器学习,数据挖掘等感兴趣,我们也可以一起学习,一起分享好玩的文章。

    QQ 1527927373
    EMAIL 1527927373@qq.com

    相关文章

      网友评论

        本文标题:美国西雅图人们使用自行车情况分析与预测(进阶)

        本文链接:https://www.haomeiwen.com/subject/koebhttx.html