【Qiita API】[統計学•機械学習] 今までの投稿記事のまとめと分析やってみた。

主に統計学、機械学習、データ分析関連の記事で、Qiitaへ投稿し始めて半年くらいになりました。ちょっと今までの記事をQiita APIを使いながら振り返ってみようと思います。(以下2015/8/10時点のデータから算出)

最初にデータを眺めて、その次にそれらの内容を生成したPythonコードと、PythonからQiita APIを使う方法の解説をします。

# 1.データを眺める

## 投稿記事のストック数順

上位5位で73%を占めていますね。人気記事は偏るのですね・・・。
最下位の「[ピザで理解する分数の割り算の意味](http://qiita.com/kenmatsu4/items/05f6590b1160657c391e)」とか個人的には結構気に入っているのですが、全然ストックされませんね :sweat_smile: 

| ストック数 | 割合(%)|累積(%)| タイトル |
|:----------:|:----------:|:----------:|:----------|
|750|28.1|28.1|[【機械学習】ディープラーニング フレームワークChainerを試しながら解説してみる。](http://qiita.com/kenmatsu4/items/7b8d24d4c5144a686412)|
|595|22.3|50.4|[【数学】固有値・固有ベクトルとは何かを可視化してみる](http://qiita.com/kenmatsu4/items/2a8573e3c878fc2da306)|
|318|11.9|62.3|[【統計学】初めての「標準偏差」（統計学に挫折しないために）](http://qiita.com/kenmatsu4/items/e6c6acb289c02609e619)|
|163|6.1|68.4|[スタバのTwitterデータをpythonで大量に取得し、データ分析を試みる その１](http://qiita.com/kenmatsu4/items/23768cbe32fe381d54a2)|
|124|4.6|73.1|[【ディープラーニング】ChainerでAutoencoderを試して結果を可視化してみる。](http://qiita.com/kenmatsu4/items/99d4a54d5a57405ecaf8)|
|82|3.1|76.1|[【更新】確率的勾配降下法とは何か、をPythonで動かして解説する](http://qiita.com/kenmatsu4/items/d282054ddedbd68fecb0)|
|55|2.1|78.2|[スタバのTwitterデータをpythonで大量に取得し、データ分析を試みる その２](http://qiita.com/kenmatsu4/items/8d88e0992ca6e443f446)|
|52|1.9|80.1|[スタバのTwitterデータをpythonで大量に取得し、データ分析を試みる その３](http://qiita.com/kenmatsu4/items/02034e5688cc186f224b)|
|50|1.9|82.0|[【統計学】ROC曲線とは何か、アニメーションで理解する。](http://qiita.com/kenmatsu4/items/550b38f4fa31e9af6f4f)|
|45|1.7|83.7|[スタバTwitterデータ位置情報のビジュアライゼーションと分析](http://qiita.com/kenmatsu4/items/114f3cff815aa5037535)|
|44|1.6|85.4|[Twitter Stream APIデータに対して初歩的な感情分析を試みる。](http://qiita.com/kenmatsu4/items/52ab6deffdd61e7d8c0f)|
|44|1.6|87.0|[主成分分析PCAを用いて手書き数字を分析する。その１](http://qiita.com/kenmatsu4/items/c61ce5d85667f499c3c8)|
|40|1.5|88.5|[複雑怪奇な正規分布の数式の意味を読み解く](http://qiita.com/kenmatsu4/items/74b8a9f696507af410a4)|
|31|1.2|89.7|[手書き数字をpythonでもてあそぶ その１](http://qiita.com/kenmatsu4/items/1105b804a5a5ffdbeec3)|
|28|1.0|90.7|[【統計学】一般化線形混合モデル(GLMM)を理解するための可視化。](http://qiita.com/kenmatsu4/items/da59a6fccde0cee4ef49)|
|28|1.0|91.8|[【統計学】正規分布とカイ二乗分布の関係を可視化してみる。](http://qiita.com/kenmatsu4/items/b6318d66fcfe78b84d83)|
|24|0.9|92.7|[Pythonを使った回帰分析の概念の解説 その１](http://qiita.com/kenmatsu4/items/8b4e908d7c93d046110d)|
|21|0.8|93.4|[Pythonでグラフデータベース Neo4j入門 for ビギナー (Mac OSX向け)](http://qiita.com/kenmatsu4/items/f75616461dc5c63ecfe1)|
|20|0.7|94.2|[【統計学】中心極限定理のイメージをグラフで掴む](http://qiita.com/kenmatsu4/items/351284ef430bcfd2c8ed)|
|20|0.7|94.9|[Word Cloudで文章の単語出現頻度を可視化する。[Python]](http://qiita.com/kenmatsu4/items/9b6ac74f831443d29074)|
|20|0.7|95.7|[【機械学習】k-nearest neighbor method(k最近傍法)を自力でpythonで書いて、手書き数字の認識をする](http://qiita.com/kenmatsu4/items/c91f5740808022decaae)|
|17|0.6|96.3|[世界で最も影響力のある100人の技術系ツイッターユーザー情報をpythonで取得する。](http://qiita.com/kenmatsu4/items/955250b95f9233417f48)|
|16|0.6|96.9|[【統計学】【R】分位点回帰を使ってみる。](http://qiita.com/kenmatsu4/items/03739db76aa010b7c6fe)|
|15|0.6|97.5|[手書き数字をpythonでもてあそぶ その２（識別する）](http://qiita.com/kenmatsu4/items/2d21466078917c200033)|
|14|0.5|98.0|[Pythonを使った回帰分析の概念の解説 番外編１](http://qiita.com/kenmatsu4/items/c25b2003fb9faf7a783e)|
|12|0.4|98.5|[【統計学】Q-Qプロットの仕組みをアニメーションで理解する。](http://qiita.com/kenmatsu4/items/59605dc745707e8701e0)|
|11|0.4|98.9|[pythonを使った回帰分析の概念の解説 その２](http://qiita.com/kenmatsu4/items/1e37da1d55292035d985)|
|11|0.4|99.3|[主成分分析PCAを用いて手書き数字を分析する。その２](http://qiita.com/kenmatsu4/items/9b9ac93e5c90d859ea0b)|
|8|0.3|99.6|[[python] 乱数生成 備忘録](http://qiita.com/kenmatsu4/items/c1a64cf69bc8c9e07aa2)|
|6|0.2|99.8|[MacでPythonからアニメーションGIFを生成する環境設定](http://qiita.com/kenmatsu4/items/573ca0733b192d919d0e)|
|5|0.2|100.0|[ピザで理解する分数の割り算の意味](http://qiita.com/kenmatsu4/items/05f6590b1160657c391e)|


## カテゴリ別に分類

大きく「機械学習」「統計学」「数学」「データ分析」「その他」のカテゴリで記事を書いています。

| 機械学習 |
|:----------|
|[【機械学習】ディープラーニング フレームワークChainerを試しながら解説してみる。](http://qiita.com/kenmatsu4/items/7b8d24d4c5144a686412)|
|[【ディープラーニング】ChainerでAutoencoderを試して結果を可視化してみる。](http://qiita.com/kenmatsu4/items/99d4a54d5a57405ecaf8)|
|[【更新】確率的勾配降下法とは何か、をPythonで動かして解説する](http://qiita.com/kenmatsu4/items/d282054ddedbd68fecb0)|
|[主成分分析PCAを用いて手書き数字を分析する。その１](http://qiita.com/kenmatsu4/items/c61ce5d85667f499c3c8)|
|[手書き数字をpythonでもてあそぶ その１](http://qiita.com/kenmatsu4/items/1105b804a5a5ffdbeec3)|
|[【機械学習】k-nearest neighbor method(k最近傍法)を自力でpythonで書いて、手書き数字の認識をする](http://qiita.com/kenmatsu4/items/c91f5740808022decaae)|
|[手書き数字をpythonでもてあそぶ その２（識別する）](http://qiita.com/kenmatsu4/items/2d21466078917c200033)|
|[主成分分析PCAを用いて手書き数字を分析する。その２](http://qiita.com/kenmatsu4/items/9b9ac93e5c90d859ea0b)|
<br>

| 統計学 |
|:----------|
|[【統計学】初めての「標準偏差」（統計学に挫折しないために）](http://qiita.com/kenmatsu4/items/e6c6acb289c02609e619)|
|[【統計学】ROC曲線とは何か、アニメーションで理解する。](http://qiita.com/kenmatsu4/items/550b38f4fa31e9af6f4f)|
|[複雑怪奇な正規分布の数式の意味を読み解く](http://qiita.com/kenmatsu4/items/74b8a9f696507af410a4)|
|[【統計学】一般化線形混合モデル(GLMM)を理解するための可視化。](http://qiita.com/kenmatsu4/items/da59a6fccde0cee4ef49)|
|[【統計学】正規分布とカイ二乗分布の関係を可視化してみる。](http://qiita.com/kenmatsu4/items/b6318d66fcfe78b84d83)|
|[Pythonを使った回帰分析の概念の解説 その１](http://qiita.com/kenmatsu4/items/8b4e908d7c93d046110d)|
|[【統計学】中心極限定理のイメージをグラフで掴む](http://qiita.com/kenmatsu4/items/351284ef430bcfd2c8ed)|
|[【統計学】【R】分位点回帰を使ってみる。](http://qiita.com/kenmatsu4/items/03739db76aa010b7c6fe)|
|[Pythonを使った回帰分析の概念の解説 番外編１](http://qiita.com/kenmatsu4/items/c25b2003fb9faf7a783e)|
|[【統計学】Q-Qプロットの仕組みをアニメーションで理解する。](http://qiita.com/kenmatsu4/items/59605dc745707e8701e0)|
|[pythonを使った回帰分析の概念の解説 その２](http://qiita.com/kenmatsu4/items/1e37da1d55292035d985)|
|[[python] 乱数生成 備忘録](http://qiita.com/kenmatsu4/items/c1a64cf69bc8c9e07aa2)|
<br>

| 数学 |
|:----------|
|[【数学】固有値・固有ベクトルとは何かを可視化してみる](http://qiita.com/kenmatsu4/items/2a8573e3c878fc2da306)|
|[ピザで理解する分数の割り算の意味](http://qiita.com/kenmatsu4/items/05f6590b1160657c391e)|
<br>

| データ分析 |
|:----------|
|[スタバのTwitterデータをpythonで大量に取得し、データ分析を試みる その１](http://qiita.com/kenmatsu4/items/23768cbe32fe381d54a2)|
|[スタバのTwitterデータをpythonで大量に取得し、データ分析を試みる その２](http://qiita.com/kenmatsu4/items/8d88e0992ca6e443f446)|
|[スタバのTwitterデータをpythonで大量に取得し、データ分析を試みる その３](http://qiita.com/kenmatsu4/items/02034e5688cc186f224b)|
|[スタバTwitterデータ位置情報のビジュアライゼーションと分析](http://qiita.com/kenmatsu4/items/114f3cff815aa5037535)|
|[Twitter Stream APIデータに対して初歩的な感情分析を試みる。](http://qiita.com/kenmatsu4/items/52ab6deffdd61e7d8c0f)|
<br>

| その他 |
|:----------|
|[Pythonでグラフデータベース Neo4j入門 for ビギナー (Mac OSX向け)](http://qiita.com/kenmatsu4/items/f75616461dc5c63ecfe1)|
|[Word Cloudで文章の単語出現頻度を可視化する。[Python]](http://qiita.com/kenmatsu4/items/9b6ac74f831443d29074)|
|[世界で最も影響力のある100人の技術系ツイッターユーザー情報をpythonで取得する。](http://qiita.com/kenmatsu4/items/955250b95f9233417f48)|
|[MacでPythonからアニメーションGIFを生成する環境設定](http://qiita.com/kenmatsu4/items/573ca0733b192d919d0e)|

# タグ別

タグ別に見ていきます。基本的にPythonを使っているので、記事数のトップはPythonです。
ストック/記事 比で見ると、圧倒的に「ディープラーニング」「DeepLearning」「Chainer」が高いですね。昨今のディープラーニングの盛り上がりが見て取れます。

「数学」「機械学習」も、割とストック率が高そうです。

| タグ | 記事数 | ストック数 | ストック/記事 比 |
|:----------:|:----------:|:----------:|:----------:|
|[Python](http://qiita.com/tags/Python)|30|2664|88.8|
|[statistics](http://qiita.com/tags/statistics)|22|1589|72.2|
|[統計学](http://qiita.com/tags/統計学)|17|1274|74.9|
|[機械学習](http://qiita.com/tags/機械学習)|9|1127|125.2|
|[Twitter](http://qiita.com/tags/Twitter)|6|376|62.7|
|[自然言語処理](http://qiita.com/tags/自然言語処理)|6|379|63.2|
|[数学](http://qiita.com/tags/数学)|6|1054|175.7|
|[matplotlib](http://qiita.com/tags/matplotlib)|5|63|12.6|
|[MongoDB](http://qiita.com/tags/MongoDB)|4|314|78.5|
|[MachineLearning](http://qiita.com/tags/MachineLearning)|4|148|37.0|
|[DeepLearning](http://qiita.com/tags/DeepLearning)|2|874|437.0|
|[統計](http://qiita.com/tags/統計)|2|35|17.5|
|[scikit-learn](http://qiita.com/tags/scikit-learn)|2|55|27.5|
|[ディープラーニング](http://qiita.com/tags/ディープラーニング)|2|874|437.0|
|[スクレイピング](http://qiita.com/tags/スクレイピング)|2|37|18.5|
|[Chainer](http://qiita.com/tags/Chainer)|2|874|437.0|
|[データベース](http://qiita.com/tags/データベース)|1|21|21.0|
|[データビジュアリゼーション](http://qiita.com/tags/データビジュアリゼーション)|1|45|45.0|
|[統計検定](http://qiita.com/tags/統計検定)|1|12|12.0|
|[考え方](http://qiita.com/tags/考え方)|1|5|5.0|
|[パターン認識](http://qiita.com/tags/パターン認識)|1|50|50.0|
|[メモ](http://qiita.com/tags/メモ)|1|5|5.0|
|[R](http://qiita.com/tags/R)|1|16|16.0|
|[データ分析](http://qiita.com/tags/データ分析)|1|40|40.0|
|[可視化](http://qiita.com/tags/可視化)|1|20|20.0|
|[math](http://qiita.com/tags/math)|1|82|82.0|
|[numpy](http://qiita.com/tags/numpy)|1|8|8.0|
|[グラフデータベース](http://qiita.com/tags/グラフデータベース)|1|21|21.0|
|[BeautifulSoup](http://qiita.com/tags/BeautifulSoup)|1|17|17.0|
|[統計モデリング](http://qiita.com/tags/統計モデリング)|1|28|28.0|
|[neo4j](http://qiita.com/tags/neo4j)|1|21|21.0|
|[統計学入門](http://qiita.com/tags/統計学入門)|1|11|11.0|

グラフにしてみるとこんな感じです。


![stock_article.png](https://qiita-image-store.s3.amazonaws.com/0/50670/5a9be22d-b4a3-fafb-e95a-fd2c437c1fa9.png)


## ストックユーザー

同じ方が結構ストックしてくれているのかなと想像していましたが、結構一見さんも多いようです。
下記の表は、よくストックしていただいている常連の方々です。ありがとうございます :relaxed: 

| 順位 | ストック数 |
|:----------:|:----------:|
| 1 | 22 |
| 2 | 18 |
| 3 | 13 |
| 4 | 10 |
| 5 | 10 |
| 6 | 10 |
| 7 | 9 |
| 8 | 9 |
| 9 | 9 |
| 10 | 9 |
| 11 | 8 |
| 12 | 8 |
| 13 | 8 |
| 14 | 8 |
| 15 | 8 |
| 16 | 8 |
| 17 | 7 |
| 18 | 7 |
| 19 | 7 |
| 20 | 7 |


ストック数が多いユーザーさん上位150のグラフです。ユニークユーザー数は1771でした。

![stock_num.png](https://qiita-image-store.s3.amazonaws.com/0/50670/8aa7765d-7c96-3afa-6021-5040577e50d5.png)


ストック数のヒストグラムです。想像以上に1〜5ストックに寄っています。リピート率が低い・・・ :weary: 
今後はリピートしてもらえるような記事を書けるよう、精進します！

![stock_hist.png](https://qiita-image-store.s3.amazonaws.com/0/50670/454c69bb-92a8-0dcf-3c34-bf67f07dadcd.png)




# 2.Pythonコードの解説

## Qiita APIからデータを取得する

アクセストークンはQiitaの
[設定] → [アプリケーション] → [新しくトークンを発行する]
で発行できます。下記の'＜アクセストークン＞'に取得したトークンを設定してください。

```py
%matplotlib inline
import requests
import json, sys
from collections import defaultdict
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.style.use('ggplot')

key = '＜アクセストークン＞'
auth_str = 'Bearer %s'%(key)
headers = {'Authorization': auth_str}
cnt = 0
data_list = []
users = defaultdict(int)

```

ストックユーザーとストック数を取得するget_stockers関数を定義します。

```py
# ------------------- 記事毎ストック数取得 -----------------------#
def get_stockers(_id):
    global headers
    url = 'https://qiita.com/api/v2/items/{}/stockers'.format(_id)
    cnt = 0
    _sum = 0
    while True:
        cnt += 1
        payload = {'page': cnt, 'per_page': 20}
        res = requests.get(url, params=payload, headers=headers)
        data = res.json()
        for d in data:
            users[d['id']] += 1
        num = len(data)
        if num == 0:
            break
        _sum += num
        
    return _sum
```

下記のループで自分の投稿した記事一式を取得し、それに紐づくストックユーザー情報を取得してリストに保持します。

```py
# ------------------- 記事情報取得 -----------------------#
url = 'https://qiita.com/api/v2/authenticated_user/items'

while True:
    cnt += 1
    sys.stdout.write("{}, ".format(cnt))
    payload = {'page': cnt, 'per_page': 20}
    res = requests.get(url, params=payload, headers=headers)
    data = res.json()
    if len(data) == 0:
        break
    data_list.extend(data)

res = []

```

取得したデータから必要な情報を抜き出して整理します。また、プライベート記事（限定共有投稿）は除きます。

```py
# ------------------- データの整形 -----------------------#
for i, d in enumerate(data_list):
    sys.stdout.write("{}, ".format(i))

    # プライベート記事は除く
    if d['private'] == True:
        continue
        
    article_info = {}
    for k in ['id', 'title', 'private', 'created_at', 'tags', 'url']:
        article_info[k] = d[k]
    
    article_info['stock'] = get_stockers(d['id'])
    res.append(article_info)
```

下記で記事一式とストック数、割合をそのままマークダウンのテーブルとして貼り付けられるような形で出力します。

```py
sum_of_stocks = np.sum([r['stock'] for r in res]).astype(np.float32)

cum = 0
print "| ストック数 | 割合(%)|累積(%)| タイトル |"
print "|:----------:|:----------:|:----------:|:----------|"
for i in np.argsort([r['stock'] for r in res])[::-1]:
    r = res[i]
    ratio = r['stock']/sum_of_stocks*100
    cum += ratio
    print "|{0}|{1:.1f}|{2:.1f}|[{3}]({4})|".format(r['stock'], ratio, cum, r['title'].encode('utf-8'),r['url'])

```

タグ周りの集計をします。

```py
# Tag集計
tag_cnt = defaultdict(int)
for r in res:
    for t in r['tags']:
        tag_cnt[t['name']] += 1

# タグ別ストック数
tag_stock_cnt = defaultdict(int)
for t in tag_cnt.keys():
    for r in res:
        for _t in r['tags']:
            if t == _t['name']:
                tag_stock_cnt[t] += r['stock']
tag_stock_dict = {}
for t, cnt in tag_stock_cnt.items():
    tag_stock_dict[t] = cnt

# DataFrameに入れられるよう加工
tag_list = []
ind_list = []
for k, t in tag_cnt.items():
    ind_list.append(k)
    tag_list.append((t , tag_stock_dict[k]))

# データフレームの生成
tag_list = np.array(tag_list)
df = pd.DataFrame(tag_list, index=ind_list, columns=['cnt', 'stocks'])

n = float(len(tag_cnt))
df['cnt_ratio'] = df['cnt']/n
df['stock_ratio'] = df['stocks']/sum_of_stocks

# タグ別ストック数とストック比の表示
df_tag = df.sort(columns='cnt', ascending=False)

print "| タグ | 記事数 | ストック数 | ストック/記事 比 |"
print "|:----------:|:----------:|:----------:|:----------:|"
for d in df_tag.iterrows():
    print "|[{0}](http://qiita.com/tags/{0})|{1}|{2}|{3:.1f}|".format(d[0].encode('utf-8'), int(d[1][0]), int(d[1][1]), d[1][1]/d[1][0])



# グラフ表示
df[['cnt_ratio','stock_ratio']].sort(columns='cnt_ratio', ascending=False).plot(kind="bar", figsize=(17, 8), alpha=0.7, 
                                title="The ratio of article and stocks for each tag.")
```

次にユーザーに関数集計、表示を行います。

```py
# User集計
id_list = []
cnt_list = []
for _id, cnt in users.items():
    id_list.append((_id, cnt))

df = pd.DataFrame(id_list, columns=["id","cnt"])

# 上位20名表示
print "| 順位 | ストック数 |"
print "|:----------:|:----------:|"
for i, d in enumerate(df.sort(columns="cnt", ascending=False)['cnt'][:20]):
    print "| {} | {} |".format(i+1, d)


# ストック数の多いユーザー順 棒グラフ
df.sort(columns="cnt", ascending=False)[:150].plot(kind="bar", figsize=(17, 8), alpha=0.6, xticks=[], 
                                                   title="The number of stocks from 1 user.", width=1, color="blue")


# ストック数のヒストグラム
df['cnt'].plot(kind="hist", figsize=(13, 10), alpha=0.7, color="Green", bins=25, xlim=(1,26),
              title="Histgram of stocked users.")

```