唯物是真 @Scaled_Wurm

プログラミング(主にPython2.7)とか機械学習とか

アドベントカレンダーの参加者は毎年どれぐらい入れ替わっているのか?2016

去年Advent Calendarの参加者が1年間でどれぐらい入れ替わっているのか調べました
sucrose.hatenablog.com
せっかくなので今年も調べてみます

2016年と2015年のQiitaで公開されているアドベントカレンダーを調査の対象とします

2016年の分は466個、2015年の分は377個のアドベントカレンダーが得られました

名寄せがめんどくさかったので、上で得られたアドベントカレンダーのリストの内2016年と2015年のURLが年の部分以外一致するものを対象とします
すると179個のアドベントカレンダーが残りました

去年の著者の内どの程度の割合で今年も書いているか(以下、生存率と呼ぶ)を調べます

結果

今年の参加者が10人以下のアドベントカレンダーは除きました

生存率(おそらく死んではいない。残存率)は40%から50%ぐらいを中心に分布していて去年より高め
生存率の分布は下の図のような感じです
f:id:sucrose:20161201012040p:plain
結果の表です
参加者の生存率が高い順に並んでいます
生存率上位には企業のアドベントカレンダーや専門性の強いものが並んでいて、下位の方には利用者の多そうなものや流行りのものが並んでいる傾向があるように見えます

順位 カレンダー名 生存率 共通の参加者数 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()

読書記録『数学ガールの秘密ノート 場合の数』☆☆☆☆

確率の話とかは出ずに純粋に場合の数の話
中華料理店などにあるような回転するテーブルが英語で"Lazy Susan"と呼ばれるというトリビアが取り上げられていた(すぐ忘れそう

場合の数はよく考えないと、すぐに間違えるので難しい
取り上げてる内容は以下のような感じ

  • 円順列
  • 数珠順列
  • パスカルの三角形
  • ヴェン図
  • 包除原理(3つの集合まで)
  • カタラン数
  • 第2種スターリング数

カタラン数

カタラン数は以下のようなものなどの場合の数になる

  • 格子上の経路を通り対角線の反対側まで行く対角線を超えない経路の数
  • 対応の取れたn個のカッコを並べる場合の数
  • n個の分岐を持つ二分木の数

漸化式で表すと以下のようになる(2つの部分に分けてそれぞれの場合の数を独立に計算してかけ合わせたものの総和)
$$C_0 =1, \quad C_{n+1}=\frac{2(2n+1)}{n+2} \, C_n = \sum_{i=0}^{n}C_i\,C_{n-i}$$
一般項は以下のようになる(本の中の計算だと、対角線を考えずに経路を移動する場合の数を考えて、対角線を超えて目的地と鏡合わせの位置に行く場合の数を引いてくる)
$$C_n = {2n \choose n} - {2n \choose n-1 }= \frac{1}{n+1}{2n \choose n} = \frac{(2n)!}{(n+1)! \, n!}$$
カタラン数 - Wikipedia
カタラン数の意味と漸化式 | 高校数学の美しい物語

第2種スターリング数

第2種スターリング数はn個の要素をk個のグループに分けるときの場合の数
漸化式は以下のようになる(新しい要素が単独でグループになるときの場合の数 + 新しい要素が既存のグループのどこかに追加されるときの場合の数)
$$S(n, k)=S(n-1, k-1) + kS(n-1, k)$$
一般項は以下のようになる
$$S(n,k)=\dfrac{1}{k!}\displaystyle\sum_{i=1}^k(-1)^{k-i}{}_kC_{i}i^n$$
一般項の導出は以下の記事の説明が分かりやすかった
全射の個数の証明とベル数 | 高校数学の美しい物語

スターリング数 - Wikipedia
スターリング数の漸化式と3つの意味 | 高校数学の美しい物語

数学ガールの秘密ノート/場合の数 (数学ガールの秘密ノートシリーズ)

数学ガールの秘密ノート/場合の数 (数学ガールの秘密ノートシリーズ)