LoginSignup
0
0

More than 3 years have passed since last update.

twitterユーザのフォロワー数でジップ則を確認してあそぶ

Posted at

はじめに

経緯:

twitterからソーシャルネットワークを構築してグラフアルゴリズムとかグラフニューラルネットワークとかで遊びたかったが、twitter apiにはいろいろな制限があることがわかり、若干、残念な気持ちになったので、気晴らしにZipf則で遊ぶことにしました。

モチベーション:

リンクの統計性から、制限の中で取得した部分的なデータがどれくらい欠損しそうで、どれくらい使えそうか、その感覚を掴むこと

分布の確認

ライブラリ

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

データ読み込み。データはこちらから入手しました。

csvファイルがほしい方はこちらから:

![output_12_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239303/e26ce4de-ecbb-c01d-2c90-9d239b957723.png)
# 日本だけの場合
followers_jp_path = './data/top_tweet_user_jp_2019_6 - 日本.csv'
# 世界の場合
followers_all_path = './data/top_tweet_user_jp_2019_6 - 世界.csv'

followers_jp_df = pd.read_csv(followers_jp_path)
followers_all_df = pd.read_csv(followers_all_path)

followers_jp_df['フォロワー数'] = followers_jp_df['フォロワー数'].apply(lambda x: int(x.replace(',', '')))
followers_all_df['フォロワー数'] = followers_all_df['フォロワー数'].apply(lambda x: int(x.replace(',', '')))

lr_jp = LinearRegression()
lr_all = LinearRegression()
followers_jp_df.describe()
順位 フォロワー数
count 200.000000 2.000000e+02
mean 100.500000 1.610835e+06
std 57.879185 9.272718e+05
min 1.000000 8.704910e+05
25% 50.750000 1.011710e+06
50% 100.500000 1.236162e+06
75% 150.250000 1.870343e+06
max 200.000000 7.100674e+06
followers_all_df.describe()
順位 フォロワー数
count 200.000000 2.000000e+02
mean 100.500000 2.631971e+07
std 57.879185 1.800354e+07
min 1.000000 1.289630e+07
25% 50.750000 1.509941e+07
50% 100.500000 1.880868e+07
75% 150.250000 2.976816e+07
max 200.000000 1.095016e+08

日本だけの場合

# ついでに線形モデルでフィットする
followers_jp_arr = followers_jp_df['フォロワー数'].to_numpy()
rank_jp_arr = np.arange(followers_jp_arr.shape[0]) + 1

model_jp = lr_jp.fit(np.log(rank_jp_arr).reshape(-1, 1), np.log(followers_jp_arr))
print(model_jp.coef_, model_jp.intercept_)
[-0.45649609] 16.149661459764342
plt.figure(figsize=(12, 9))
plt.plot(np.log(rank_jp_arr), np.log(followers_jp_arr))
plt.plot(np.log(rank_jp_arr), model_jp.predict(np.log(rank_jp_arr).reshape(-1,1)))

plt.ylabel('log(followers No.)')
plt.xlabel('log(rank)')
Text(0.5, 0, 'log(rank)')

output_12_1.png

世界の場合

# ついでに線形モデルでフィットする
followers_all_arr = followers_all_df['フォロワー数'].to_numpy()
rank_all_arr = np.arange(followers_all_arr.shape[0]) + 1

model_all = lr_all.fit(np.log(rank_all_arr).reshape(-1, 1), np.log(followers_all_arr))
print(model_all.coef_, model_all.intercept_)
[-0.52764815] 19.209526323152097
plt.figure(figsize=(12, 9))
plt.plot(np.log(rank_all_arr), np.log(followers_all_arr))
plt.plot(np.log(rank_all_arr), model_all.predict(np.log(rank_all_arr).reshape(-1,1)))

plt.ylabel('log(followers No.)')
plt.xlabel('log(rank)')
Text(0.5, 0, 'log(rank)')

output_15_1.png

どちらも概ね直線上に載った感じです。
おおよそ

$$
\log{(followers)}
= b - a \log{(rank)}
$$

みたいな感じなので、

$$
followers = C * rank^{-a}
$$

となります。
大雑把にいうと人間社会で注目はかなり一部の人間に集中している、という話です。

係数に関してですが、日本の場合

$$
C = e^{16} \
a = 0.46
$$

世界の場合

$$
C = e^{19} \
a = 0.53
$$

となります。$C$の値はおおよそそれぞれのケースの一番多い人のフォロワー数になっています

np.exp(model_jp.intercept_), followers_jp_arr[0], np.exp(model_all.intercept_), followers_all_arr[0]
(10320692.926087316, 7100674, 220085424.72447222, 109501564)

しかし、日本の場合、1億人目の推定フォロワー数を求めると

rank = 1 * 10 ** 8
np.exp(model_jp.predict(np.log([[rank]])))
array([2300.06504938])

2千人ぐらいとなっていて、明らかに現実と異なります。超フォロワー富裕層である有名人とフォロワー貧困層である一般人の間のどこかに何らかのメカニズムで修正が入るでしょう。

ついでに世界の場合、100億人目のフォロワー数は

rank = 50*10**8
np.exp(model_all.predict(np.log([[rank]])))
array([1678.60178686])

と千5百人程度でした。

考察

zipf則の形成理由は「富めるがさらに富める」ことだそうです。

大量のフォロワーを集めるためにおそらく大量の資本によるプロヂュースが行われていることを考えれば、
ランキングトップ層でのジップ則がおそらく資本によるもので、ビジネス由来の要素が大きいと考えられます。
それが一般人となると影響がなくなってくると推測しています。
しかし資本が介在しなくても資本とは別の理由のジップ則が現れそうだと考えると、
フォロワー数が減少していくと、どこかでジップ則の係数が遷移するところが見えるのではないかと予想しています。

感想

前向きなソリューションが出てきた気がする。
詳細は企業ヒ・ミ・ツ。
やっぱ、EDAは重要。

データはトモダチだぁ〜

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0