唯物是真 @Scaled_Wurm

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

Qiitaのアドベントカレンダーの購読数とストック数の関係を調べてみた

Qiitaのアドベントカレンダーのランキングが公開されていました
現時点の購読数とストック数のランキングがジャンル別に見られるようになっています


購読数とストック数で上位のランキングが結構違ったので、どんな分布をしているのか調べてみました

データ

購読数とストック数のランキングの両方に載っているアドベントカレンダーを対象とする(購読数とストック数がどちらも1以上)

結果

グラフにしてみると以下のようになる
ほとんどのアドベントカレンダーが左下にあって団子になっている
左上の方には異常にストック数が多い企業のアドベントカレンダーが並んでいて、たぶん内容に統一性がないので購読数が少なくて、代わりに仕事でやっていて質が高いのか、ストック数が多い傾向があると思われる
相関係数を計算してみるとピアソンの積率相関係数が0.40、スピアマンの順位相関係数が0.48ぐらいでそれなりに相関があるかもなーという感じ(p<0.01)
グラフを見ても相関があるのかどうかわかりづらいけど、左下の部分にあるアドベントカレンダーの数が多いのでこんな感じの結果になっているのかも
f:id:sucrose:20151219190205p:plain

まとめ

購読数とストック数には多少は正の相関がありそう
ただし記事が一つバズると数百単位でストック数が増えてランダム性が大きいのと、企業のアドベントカレンダーは購読数が伸びづらいのが理由で2つのランキングの上位は異なっていると思われる
というか(一部の?)企業のアドベントカレンダーのストック数強いですね……

ソースコード

最近Seabornを触り始めたので試しに使ってグラフをかいてみた
Seabonのグラフに回帰直線をかいてくれる機能は、何故か推定された回帰直線の傾きとかを取得する機能がないのが謎

いろいろライブラリを使っているので必要なのを入れてから実行してください

# -*- coding: utf-8 -*-

import pyquery
import time
import seaborn as sns
import matplotlib.font_manager
import numpy as np
import scipy.stats as stats

def getInfo(url):
    info_list = pyquery.PyQuery(url=url)
    result = {}
    for elem1, elem2 in zip(info_list.find('.adventCalendarRankingListItem_name > a'), info_list.find('.adventCalendarRankingListItem_rate')):
        a = pyquery.PyQuery(elem1)
        href = a.attr('href')
        value = pyquery.PyQuery(elem2).text()
        result[href[22:]] = (a.text(), int(value))
    return result

if __name__ == '__main__':
    subscription = getInfo('http://qiita.com/advent-calendar/2015/ranking/subscriptions/all')
    stock = getInfo('http://qiita.com/advent-calendar/2015/ranking/stocks/all')

    arr_subscription = []
    arr_stock = []
    arr_label = []
    for i in subscription:
        if i not in stock:
            continue
        arr_subscription.append(subscription[i][1])
        arr_stock.append(stock[i][1])
        arr_label.append(i)
    
    print u'ピアソンの積率相関係数:', stats.pearsonr(arr_subscription, arr_stock)
    print u'スピアマンの順位相関係数:', stats.spearmanr(arr_subscription, arr_stock)
    
    sns.regplot(x=np.array(arr_subscription), y=np.array(arr_stock), robust=True, scatter_kws={'alpha':0.7, 's':40})
    prop = matplotlib.font_manager.FontProperties(fname=r'C:\Windows\Fonts\meiryo.ttc', size=12)
    sns.plt.xlabel(u'購読数', fontproperties=prop)
    sns.plt.ylabel(u'ストック数', fontproperties=prop)
    sns.plt.xlim((0, 400))
    sns.plt.ylim((0, 2000))
    sns.plt.xkcd()
    for i in xrange(len(arr_label)):
        if arr_stock[i] >= 500 or arr_subscription[i] >= 200:
            sns.plt.text(arr_subscription[i] + 3, arr_stock[i] + 30 + 50 * (arr_label[i] == 'dwango2'), arr_label[i], fontsize=14)
    sns.plt.title(u'Qiitaアドベントカレンダー2015の購読数とストック数の関係', fontproperties=prop)
    sns.plt.text(230, 1900, u'相関係数(Pearson\'s r): {:.2f}'.format(stats.pearsonr(arr_subscription, arr_stock)[0]), fontsize=14, fontproperties=prop)
    sns.plt.show()