MSTC Staff 的睡眠趋势

June 26, 2008 – 10:38 pm

大约是从去年寒假的时候开始,我就经常在 cc98 的 MSTC 版上发“晚安帖”,就是每天晚上睡觉的时候发一个帖子说一声晚安,后来版面上时常出现一大堆晚安帖的情况,遭到大家的抗议。 :p 后来只好集中到了一个帖子里面,养成了习惯大家也都时常来说晚安。

不管是早有预谋还是心血来潮,我对这个晚安贴的内容分析了一下,得到了类似于下面的结果:


plot_simple.jpg

其中横坐标是日期,纵坐标是睡觉时间,由于大家都睡得比较晚,所以把第二天凌晨的时间也记作当天晚上(如 25:00 就是第二天凌晨 1:00 )。每一条线就代表一个人的睡眠趋势了。由于并不是每个人每天都去那个晚安贴回帖的,所以每条线的横坐标分布并不是很均匀的。上面是只分析了最初几天的数据的情况,下面则是从今年 2 月 24 日到最近的完整数据分析的结果(点击查看原始大小的图片):

plot.jpg

以上是显示可用数据最多的前 5 个人的睡眠趋势,可以看到似乎我一直都是睡得最晚的,不过最近几天 mnxheng 似乎是晚上熬夜看球的缘故,睡眠时间一下子变得很晚。下面是单独显示两者的情况,更加清晰一些:

plot_kid_vs_mnxheng.jpg

还有一些有趣的结果,比如下面是 MSTC 的部分 mm 的情况:

plot_mm.jpg

其中 lam 和 Nancy 都睡得比较晚,Roxxane 作息时间还算健康,不过有一个很突出的点似乎超过了 29:30 ,如果没有记错的话,似乎那天晚上她们组通宵赶 Java 的 project 了。另外,sleepyworm 似乎在这里发帖,所以数据也很少。

程序大致就是用 wget 抓取相关的帖子,用 Hpricot 提取出感兴趣的数据,略微分析一下,最后再通过 gnuplot 将数据画成图。整个过程用 Ruby 粘合在一起。其实我想把图画得更漂亮一些,就像 Open Flash Chart 那种样子,但是由于这里的数据比较特殊,每条线的横坐标并不是相同的,看了许多画图的工具(如 PyCha 和上面说的 Open Flash Chart 之类的),都不方便画这样的图,最后还是选择了 gnuplot 。

虽然这个学期选了数据挖掘导论课,但是如同其他课一样,基本上还没有看过,再过几天就是考试了,也得抓紧复(学)习才是。所以这里其实也只是对数据进行了一下简单的分析,并用可视化的方法展示出来,而没有去做“正统意义上的数据挖掘”(例如:自动将用户分为“健康睡眠用户”和“晚睡用户”,根据睡眠趋势判定两个 id 是否是同一个人的两个马甲、通过过去的趋势预测今天可能的睡眠时间段等等),而且这么小的数据量也确实没法挖掘出什么有意义的东西来吧。

虽然没有什么技术含量,但是还是有不少感触:

  • 尽量用现有的东西,避免 reinvent the wheel 。例如,用这里虽然整个程序都是由 Ruby 脚本写成的,但是下载 web 页面的时候还是调用了 wget ,而不是用 Ruby 内置的 open-uri 来下载。

    实际上我以前也时常写过一些抓取网页的脚本,Python 和 Ruby 都用过,一直都用内置的库来抓取 web 页面,确实很方便,但是和 wget 比起来实在是太不健壮了。在网络条件不好的情况下经常超时出错,在 Python 里要设置 http 超时值似乎要到 socket 底层那里去做,到头来原本简单的程序又变得麻烦起来了。还不如一开始就用 wget 来做,不仅程序健壮,而且诸如重定向之类的问题都会自动解决掉了。

  • 虽然程序并不复杂,但是我还是把它分成了几个比较小的部分:
    1. fetch: 抓取网页。
    2. parse: 解析网页,提取有用数据(每个帖子的作者和发帖时间)。
    3. analyze: 分析数据,就是把每天的帖子按照作者分类,并选出发帖时间最晚的一帖。
    4. convert: 将分析结果转换为 gnuplot 的数据文件格式。
    5. plot: 用 gnuplot 画图。

    分成几个部分有许多好处,比如,功能单一的模块更加容易实现,代码显得很简洁。然而我并没有像传统的 unix pipe 那样直接把他们串联起来:fetch | parse | analyze | convert | plot ,而是让他们依次执行,通过文件来交换数据,这样做也是尽量想把“损失”降到最低吧,如果某一个环节出问题了,不至于要整个过程全部重新执行一遍,像 fetch 这样的过程是比较耗时间的。

  • 我解析 HTML 的时候用了 Hpricot 和正则表达式结合的办法。本来理想情况下用 Hpricot 解析就可以了,但是现实中许多 HTML 页面是非常不标准的(比如 cc98 的页面),创建起来的 DOM 树往往会和“想象中”不太一样,然而正则表达式又不方便处理上下文,所以采用两者结合往往也能达到比较好的效果。
  • gnuplot 的文档真实难读啊,感觉很难从中获取什么信息啊。 -,-bb 而且 gnuplot 似乎不支持中文?
  • 做这些事情还是脚本语言最好用,Ruby 甚至内置了 YAML 的支持,用 YAML 来作数据、配置的存储简直太方便了! :D 希望 Python 以后也能在标准库里添加 YAML 格式的支持。而且脚本这种交互式开发真的很舒服,随时得到反馈,快速建立原型,最后我把程序从最初的 ad hoc 的实现改写为支持增量更新数据的形式也没有花多大工夫。

最后,希望大家的睡眠曲线不要一直那么高啊,要慢慢降到健康水平才行!(不过似乎还是我自己的最高了 -,-bb)总之,还是先复习考试去了!

(Update 2008-06-29) 附上当前的源代码:mstc_goodnight.tar.gz

  1. 6 Responses to “MSTC Staff 的睡眠趋势”

  2. 忍不住用手机看了下Google reader,就到这里来了=.=
    我抓98网页是用grep+w3m的,整成一行一行的文本形式,DOM结构全没了…

    By quark on Jun 27, 2008

  3. 有创新,竟然用这种方法来统计睡觉时间,够专业的

    By shenheng on Jun 27, 2008

  4. 哈哈,我也是google reader到这里来了,这个统计真的挺有趣的,应该发给这些同学,督促他们早点睡觉,kid也要早点睡觉啊

    By bigpiglet on Jun 28, 2008

  5. 哪里能看到代码啊?

    By darren on Jun 29, 2008

  6. @darren,
    我附上源代码了,在文章末尾有下载链接。

    By pluskid on Jun 29, 2008

  1. 1 Trackback(s)

  2. Feb 5, 2009: Free Mind » 2008 ^L 2009

Post a Comment