去年Advent Calendarの参加者が1年間でどれぐらい入れ替わっているのか調べました
sucrose.hatenablog.com
せっかくなので今年も調べてみます
2016年と2015年のQiitaで公開されているアドベントカレンダーを調査の対象とします
2016年の分は466個、2015年の分は377個のアドベントカレンダーが得られました
名寄せがめんどくさかったので、上で得られたアドベントカレンダーのリストの内2016年と2015年のURLが年の部分以外一致するものを対象とします
すると179個のアドベントカレンダーが残りました
去年の著者の内どの程度の割合で今年も書いているか(以下、生存率と呼ぶ)を調べます
結果
今年の参加者が10人以下のアドベントカレンダーは除きました
生存率(おそらく死んではいない。残存率)は40%から50%ぐらいを中心に分布していて去年より高め
生存率の分布は下の図のような感じです
結果の表です
参加者の生存率が高い順に並んでいます
生存率上位には企業のアドベントカレンダーや専門性の強いものが並んでいて、下位の方には利用者の多そうなものや流行りのものが並んでいる傾向があるように見えます
順位 | カレンダー名 | 生存率 | 共通の参加者数 | 2016年の参加者数 | 2015年の参加者数 |
---|---|---|---|---|---|
1 | se | 1.000 | 3 | 24 | 3 |
2 | firstserver | 1.000 | 10 | 25 | 10 |
3 | opencv | 0.875 | 7 | 12 | 8 |
4 | allabout | 0.800 | 12 | 19 | 15 |
5 | fablic | 0.786 | 11 | 14 | 14 |
6 | hamee | 0.778 | 14 | 20 | 18 |
7 | nijibox | 0.714 | 15 | 22 | 21 |
8 | crowdworks | 0.700 | 14 | 25 | 20 |
9 | istyle | 0.692 | 9 | 23 | 13 |
10 | basicinc | 0.692 | 9 | 16 | 13 |
11 | access | 0.688 | 11 | 17 | 16 |
12 | speee | 0.667 | 12 | 23 | 18 |
13 | salesforce-app-cloud | 0.667 | 10 | 16 | 15 |
14 | gumi | 0.632 | 12 | 21 | 19 |
15 | dlang | 0.625 | 10 | 18 | 16 |
16 | klab | 0.609 | 14 | 25 | 23 |
17 | freee | 0.600 | 15 | 24 | 25 |
18 | eeic | 0.591 | 13 | 25 | 22 |
19 | cybird | 0.583 | 14 | 22 | 24 |
20 | pepabo | 0.579 | 11 | 24 | 19 |
21 | kintone | 0.560 | 14 | 22 | 25 |
22 | ue4 | 0.520 | 13 | 25 | 25 |
23 | livesense_1 | 0.520 | 13 | 25 | 25 |
24 | gaiax | 0.520 | 13 | 25 | 25 |
25 | wacul | 0.500 | 7 | 14 | 14 |
26 | vim | 0.500 | 12 | 25 | 24 |
27 | mynet | 0.500 | 9 | 25 | 18 |
28 | lang_dev | 0.500 | 5 | 14 | 10 |
29 | gastah | 0.500 | 7 | 11 | 14 |
30 | dwango | 0.480 | 12 | 25 | 25 |
31 | appresso | 0.478 | 11 | 24 | 23 |
32 | erlang | 0.471 | 8 | 12 | 17 |
33 | qt | 0.467 | 7 | 15 | 15 |
34 | sakura | 0.455 | 10 | 23 | 22 |
35 | goodpatch | 0.455 | 10 | 18 | 22 |
36 | dots_girls | 0.450 | 9 | 22 | 20 |
37 | siv3d | 0.444 | 8 | 18 | 18 |
38 | netopscoding | 0.444 | 8 | 16 | 18 |
39 | m3 | 0.444 | 8 | 14 | 18 |
40 | heroku | 0.444 | 8 | 11 | 18 |
41 | pixiv | 0.440 | 11 | 22 | 25 |
42 | oculus-rift | 0.440 | 11 | 25 | 25 |
43 | mixi | 0.440 | 11 | 20 | 25 |
44 | future | 0.440 | 11 | 23 | 25 |
45 | clojure | 0.440 | 11 | 24 | 25 |
46 | webgl | 0.435 | 10 | 12 | 23 |
47 | ouch-hack | 0.435 | 10 | 25 | 23 |
48 | conoha | 0.435 | 10 | 25 | 23 |
49 | r-rstudio | 0.417 | 10 | 25 | 24 |
50 | tech-camp | 0.409 | 9 | 24 | 22 |
51 | postgresql | 0.400 | 10 | 23 | 25 |
52 | linux | 0.400 | 8 | 24 | 20 |
53 | julialang | 0.400 | 6 | 11 | 15 |
54 | http2 | 0.400 | 6 | 13 | 15 |
55 | haskell | 0.400 | 10 | 24 | 25 |
56 | mruby | 0.389 | 7 | 14 | 18 |
57 | productmanager | 0.375 | 6 | 18 | 16 |
58 | sansan | 0.368 | 7 | 15 | 19 |
59 | unity | 0.360 | 9 | 25 | 25 |
60 | ruby | 0.360 | 9 | 22 | 25 |
61 | javaee | 0.360 | 9 | 12 | 25 |
62 | go | 0.360 | 9 | 25 | 25 |
63 | ipu | 0.353 | 6 | 13 | 17 |
64 | shell-script | 0.350 | 7 | 15 | 20 |
65 | gcp | 0.348 | 8 | 25 | 23 |
66 | csharp | 0.348 | 8 | 25 | 23 |
67 | no-girlfriend | 0.333 | 4 | 25 | 12 |
68 | kubernetes | 0.333 | 1 | 25 | 3 |
69 | drupal | 0.333 | 7 | 11 | 21 |
70 | azure | 0.320 | 8 | 25 | 25 |
71 | python | 0.292 | 7 | 25 | 24 |
72 | xamarin | 0.286 | 6 | 25 | 21 |
73 | vue | 0.286 | 4 | 25 | 14 |
74 | symfony | 0.286 | 6 | 11 | 21 |
75 | recruitlifestyle | 0.280 | 7 | 25 | 25 |
76 | nodejs | 0.280 | 7 | 25 | 25 |
77 | java | 0.280 | 7 | 23 | 25 |
78 | swift | 0.261 | 6 | 25 | 23 |
79 | crawler | 0.261 | 6 | 25 | 23 |
80 | php | 0.250 | 6 | 21 | 24 |
81 | ios | 0.250 | 6 | 25 | 24 |
82 | communication | 0.250 | 4 | 15 | 16 |
83 | bluemix | 0.250 | 5 | 23 | 20 |
84 | livesense_2 | 0.240 | 6 | 24 | 25 |
85 | foss4g | 0.240 | 6 | 14 | 25 |
86 | civictech | 0.238 | 5 | 16 | 21 |
87 | scala | 0.227 | 5 | 25 | 22 |
88 | cakephp3 | 0.227 | 5 | 12 | 22 |
89 | math | 0.211 | 4 | 16 | 19 |
90 | android | 0.208 | 5 | 25 | 24 |
91 | slack | 0.200 | 3 | 25 | 15 |
92 | swift2 | 0.190 | 4 | 24 | 21 |
93 | pronama-chan | 0.176 | 3 | 12 | 17 |
94 | gsacademy | 0.176 | 3 | 15 | 17 |
95 | go2 | 0.160 | 4 | 25 | 25 |
96 | dwango2 | 0.160 | 4 | 25 | 25 |
97 | javascript | 0.130 | 3 | 17 | 23 |
98 | go3 | 0.125 | 3 | 24 | 24 |
99 | git | 0.120 | 3 | 25 | 25 |
100 | emacs | 0.091 | 2 | 11 | 22 |
101 | ansible | 0.087 | 2 | 11 | 23 |
102 | unity2 | 0.083 | 2 | 22 | 24 |
103 | docker | 0.083 | 2 | 24 | 24 |
104 | rust-lang | 0.071 | 1 | 24 | 14 |
105 | chainer | 0.050 | 1 | 20 | 20 |
106 | electron | 0.042 | 1 | 17 | 24 |
107 | tensorflow | 0.000 | 0 | 24 | 1 |
108 | react-native | 0.000 | 0 | 12 | 1 |
109 | laravel | 0.000 | 0 | 20 | 3 |
110 | blockchain | 0.000 | 0 | 21 | 3 |
ソースコード
pyqueryを使ってるので入ってなかったらpip install pyqueryとかで入れてください(他にもnumpyやmatplotlibなども使っています
カレンダー数と、上の結果(はてな記法の表形式)を出力するようになっています
# -*- coding: utf-8 -*- import pyquery import time def getCalendarList(year, page): calendar_list = pyquery.PyQuery(url='http://qiita.com/advent-calendar/{}/calendars?page={}'.format(year, page)) title = set() for elm in calendar_list.find('.adventCalendarList_calendarTitle > a'): a = pyquery.PyQuery(elm) href = a.attr('href') title.add(href[22:]) return title def getAuthors(year, name): calendar = pyquery.PyQuery(url='http://qiita.com/advent-calendar/{}/{}'.format(year, name)) author = set() for elm in calendar.find('.adventCalendarCalendar_author a'): a = pyquery.PyQuery(elm) text = a.text() author.add(text) return author if __name__ == '__main__': title2015 = set() for i in range(1, 20): title2015 |= getCalendarList(2015, i) time.sleep(1) title2016 = set() for i in range(1, 25): title2016 |= getCalendarList(2016, i) time.sleep(1) print '2016: {}, 2015: {}, Intersection: {}'.format(len(title2016), len(title2015), len(title2016 & title2015)) result = [] for name in title2016 & title2015: author2016 = getAuthors(2016, name) time.sleep(1) if len(author2016) <= 10: continue author2015 = getAuthors(2015, name) time.sleep(1) result.append((float(len(author2016 & author2015)) / len(author2015), name, len(author2016), len(author2015), len(author2016 & author2015))) result.sort(reverse=True) print u'|*順位|*カレンダー名|*生存率|*共通の参加者数|*2016年の参加者数|*2015年の参加者数|'.encode('utf-8') for i, (score, name, num2016, num2015, num_intersect) in enumerate(result, 1): print '|{0}|<a href="http://qiita.com/advent-calendar/2016/{1}">{1}</a>|{2:.3f}|{3}|{4}|{5}|'.format(i, name, score, num_intersect, num2016, num2015) from pylab import * import numpy as np score = np.array(map(lambda x:x[0], result)) name = np.array(map(lambda x:x[1], result)) hist(score, bins=np.arange(0, 1.1, 0.1), histtype='stepfilled') prop = matplotlib.font_manager.FontProperties(fname=r'C:\Windows\Fonts\meiryo.ttc', size=12) xlabel(u'生存率', fontproperties=prop) ylabel(u'カレンダー数', fontproperties=prop) show()