毎日テキストマイニング

180日間、毎日テキストマイニングをするブログです

2018/7/15【23日目】高速で学ぶ統計学その2

相関関係

相関関係は昨日も確認しましたが、相関関係は2つの変数の関係性を表しているそうです。右上がりの直線に並ぶと「相関関係がある」といい、右下がりの直線に並ぶと「負の相関関係がある」というそうです。変数が並ばずにバラバラになる場合は「相関関係がない」というそうです。

それで、この相関関係に使う指標のことを共分散というらしいです。それぞれの(x, y)の点について、(x_i - xの平均値)(y_i - yの平均値)を掛けた値がその点における共分散だそうです。この共分散の最大値は相関関係の代表的な値として相関係数と呼ぶらしいです。この相関係数は最大値、最小値がわからないと使い勝手が悪いので、相関係数を-1から1になるように調整したのがピアソンの積率相関係数だそうです。

言葉だけですと全くわからないので、図を作って視覚化してみます。2つの変数が必要なのでretweetとfavoriteの2つのデータを用意します。ファボが多く付いていれば、その分リツイートも多いはずなので、この2つなら相関関係があると思います。図を作成するのにはmatplotlibを使えば良いそうなので、今回初めて使ってみます。

import matplotlib.pyplot as plt
import pandas as pd

re_favo = pd.read_csv('re_favo.csv',
                      sep=',',
                      encoding='utf-8')

x = re_favo["retweet"]
y = re_favo["favorite"]

plt.plot(x, y, 'o')
plt.show()

f:id:rimt:20180716143658p:plain

x軸がリツイート数で、y軸がファボ数です。どうでも良いですが、ファボ数は桁が違いますね。リツイートするのって心理的に負担が大きいのでしょうかね?

図に関しましては思った通り右上がりなので、「相関関係がある」と言えそうです。この図の相関係数を計算してみたい思います。

N = len(re_favo)
x_mu = sp.mean(x)
y_mu = sp.mean(y)

cov = sum((x - x_mu) * (y - y_mu) /(N - 1))
x_bunsan = sp.var(x, ddof=1)
y_bunsan = sp.var(y, ddof=1)

soukankeisu = cov / (x_bunsan * y_bunsan)
print(soukankeisu)

covというのが共分散です。全部の点の値を出して、全体で割っています。 実行結果。

1.98625790571e-06

共分散をxの分散とyの分散をかけたもので割ると相関係数が出るらしく、1.98625790571e-06というのが相関係数ぽいです。確かにこの数値が何をいいたいのか全くわからないです。

これをピアソンの積率相関係数にしてわかりやすくします。

N = len(re_favo)
x_mu = sp.mean(x)
y_mu = sp.mean(y)

cov = sum((x - x_mu) * (y - y_mu) /(N - 1))
x_bunsan = sp.var(x, ddof=1)
y_bunsan = sp.var(y, ddof=1)

piason = cov / sp.sqrt(x_bunsan * y_bunsan)
print(piason)

xの標準偏差とyの標準偏差にルートをかけただけです。 実行結果

0.949367142795

-1から1の間に入りました。1に近いほど「相関関係がある」と言えて、-1に違いほど「負の相関関係がある」と言えるそうです。0に近いと「相関関係がない」ですね。この場合、十分に相関関係がある、と言えそうですね。

標準化

続けて上のデータを標準化したいと思います。リツイートとファボ数のように相関関係がある場合、xの値に応じてyがどの程度変化するのかを考えるそうです。というわけでxを標準化してみます。

#xの平均
x_mu = int(sp.mean(x))
#xの標準偏差
sigma = sp.std(x, ddof = 1)
#xの標準化
x_standard = (x - x_mu) / sigma

#標準化した後の平均
print(sp.mean(x_standard))
#標準化した後の標準偏差
print(sp.std(x_standard, ddof = 1))

実行結果

0.0017100382634870626
1.0000000000000002

ほぼ標準化できたと思いますので、プロットしてみます。

plt.plot(x_standard, y, 'o')
plt.show()

f:id:rimt:20180716144136p:plain

おー、ちゃんとxが低い値になってますね。偏差値的にいうと、0が偏差値50、1が偏差値60、2が偏差値70、3が偏差値80くらいだそうです。 やっぱり偏差値60を超える数値ってあんまりないんですね。

難しすぎて放り投げたくなりますが、もう少し続けます。