毎日テキストマイニング

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

2018/7/17【25日目】Pythonでn-gramを実装していく

今日は自然言語処理のテキストに良く出てくるn-gramについて実装していきたいと思います。

n-gramとは

大学受験の時に、『英単語ピーナッツほど美味しいものはない』という単語帳がありましたが、「形容詞+名詞」や「動詞+名詞」をひたすらノートに書いていくというものでした。まさにあれがn-gramというものらしいです。

例をあげると「know」と「how」だけですと、「知る」と「どのように」という意味ですが、「know how」になると「やり方」になるように、2つ以上の単語で置き換えができない組み合わせをコロケーションというらしいです。

n-gramはこれらのコロケーションを見つけるために、2文字ずつ(バイグラム)、3文字ずつ(スリーグラム)、4文字ずつ(フォーグラム)といったぐらいに言葉を集めることだそうです。

物は試しにとりあえず実装していきます。

実装

とりあえず、ライブラリでpython-ngramというのがあり、一番簡単そうなので、まずはこれを使ってみます。

github.com

tweet = "SHOWROOM「こみの部屋」ありがとうございました〜??チームKについてたくさんお話できたかな!舞台、プロレスと今年も一緒に夏を過ごしそうです??? https://t.co/qxc047jzLg"

import ngram
index = ngram.NGram(N=2)

for two_gram in index.ngrams(index.pad(tweet)):
    print(two_gram)

実行結果

$S
SH
HO
OW
WR
RO
OO
OM
M「
「こ
こみ
みの
の部
(省略)

それぽいのができました。ただ、これだとKnow howというようなコロケーションは一生作れなさそうですね。 できれば単語ごとに分けていきたいような気がします。

ちょっと調べてみましたが、いいライブラリがなさそうなので自分で実装してみます。 まずは単語にばらして配列に代入。

import MeCab

tagger = MeCab.Tagger ("")

kaisekiyou = tweet.split('¥n')
string = ' '.join(kaisekiyou)
mecab = tagger.parse(string)
kaigyou = mecab.splitlines()

word = []

for tango_list in kaigyou:
    tab = tango_list.split('\t')
    words = tab[0]
    word.append(words)
print(word)

実行結果。

['SHOWROOM', '「', 'こみの部屋', '」', 'ありがとう', 'ござい', 'まし', 'た', '〜', '??', 'チームK', 'について', 'たくさん', 'お話', 'でき', 'た', 'か', 'な', '!', '舞台', '、', 'プロレス', 'と', '今年', 'も', '一緒', 'に', '夏', 'を', '過ごし', 'そう', 'です', '???', 'https', '://', 't', '.', 'co', '/', 'qxc', '047', 'jzLg', 'EOS']

とりあえず単語ごとに配列に代入しました。 これを1個ずつスライドして新しい配列にすれば良さそうです。 配列に2つずつ追加するには、数字でfor文を回して、2つずつappedすれば良さそうです。

bigram_list = []
for i in range(len(word)-1):
    bigram_list.append((word[i], word[i+1]))

実行結果

[('SHOWROOM', '「'), ('「', 'こみの部屋'), ('こみの部屋', '」'), ('」', 'ありがとう'), ('ありがとう', 'ござい'), ('ござい', 'まし'), ('まし', 'た'), ('た', '〜'), ('〜', '??'), ('??', 'チームK'), ('チームK', 'について'), ('について', 'たくさん'), ('たくさん', 'お話'), ('お話', 'でき'), ('でき', 'た'), ('た', 'か'), ('か', 'な'), ('な', '!'), ('!', '舞台'), ('舞台', '、'), ('、', 'プロレス'), ('プロレス', 'と'), ('と', '今年'), ('今年', 'も'), ('も', '一緒'), ('一緒', 'に'), ('に', '夏'), ('夏', 'を'), ('を', '過ごし'), ('過ごし', 'そう'), ('そう', 'です'), ('です', '???'), ('???', 'https'), ('https', '://'), ('://', 't'), ('t', '.'), ('.', 'co'), ('co', '/'), ('/', 'qxc'), ('qxc', '047'), ('047', 'jzLg'), ('jzLg', 'EOS')]

お、良さそうにできています。 明日はこれを使って何か分析ぽいことをしたいと思います。

ちなみに3グラムの時はこんな感じですね。

three_list = []
for i in range(len(word)-2):
    three_list.append((word[i], word[i+1], word[i+2]))

今日の結果

本日のAKBメンバーによる呟きは45件でした。 久しぶりに画像を作ってみます。

f:id:rimt:20180718220440p:plain

{'あおい': 13, '楽しい': 11, '嬉しい': 8, '暑い': 5, 'すごい': 3, '可愛い': 2, '優しい': 2, '凄い': 2, '面白い': 2, '少ない': 1, '黒い': 1, 'ない': 1, 'すっごい': 1, '暖かい': 1, 'うれしい': 1, 'たのしい': 1, '大きい': 1})

'公演': 27, '今日': 17, 'さん': 16, 'あおい': 13, '楽しい': 11, '嬉しい': 8, '暑い': 5, '笑': 5, '皆さん': 5, 'ん': 5, 'みんな': 4, '出演': 4, '福岡': 4, '日': 4, '私': 4, 'みなさん': 4, 'たくさん': 4, 'ちゃん': 4,

'公演': 27, 'する': 27, '今日': 17, 'さん': 16, 'あおい': 13, '楽しい': 11, '嬉しい': 8, 'なる': 6, '暑い': 5, '笑': 5, '皆さん': 5, 'ん': 5, 'せる': 5, '頑張る': 5, 'くださる': 5, 'ゆう': 5,

こんな感じでした。

今日勉強したこと

2018/7/16【24日目】高速で学ぶ統計学その4

連休中に学ぶと言ったのですが、難しすぎて全然進まなかったですね。とりあえず今日正規分布までは行って終わりたいと思います。そのうちその5に続きます。

最小2乗法の計算方法

最小2乗法のイメージがわかったところで公式を確認してみます。 f:id:rimt:20180717234011p:plain

シータがパラメータというやつで、これから求めるものです。 iがxとyの場所を表しています。それで、全体を2乗してマイナスを消し、2分の1をかけると求められるらしいです。 まぁ、実際に試していかないとよくわからないですね。。。とりあえず、今はこれで進むみます。

標本分布

分析の対象になる変数が特定されたら、母集団におけるその変数の分布図を求める必要があって、それを母集団分布というらしいです。それで、母集団といのはほとんどの場合、把握するのは難しいそうです。そこで、登場するのが正規分布正規分布は平均が一番高く、左右対象になる分布のことだそうです。

正規分布はmatplotlibで簡単に出るそうなので、出力してみます。xは昨日から登場していますが、リツイートの回数です。

import seaborn as sns
%matplotlib inline
sns.distplot(x, color = 'black')

実行結果

f:id:rimt:20180717234011p:plain

左右対称にならないですね。 Wikipediaによると、正規分布になるには条件があるらしいですね。

正規分布(せいきぶんぷ、英: normal distribution)またはガウス分布(英: Gaussian distribution)は、平均値の付近に集積するようなデータの分布を表した連続的な変数に関する確率分布である。

調べてみました、サイコロを振ってでた数というのは正規分布になるらしいのでやってみます。

saikoro = [4,1,6,5,5,1,4,1,2,2]
sns.distplot(saikoro,color = 'black')

実行結果

f:id:rimt:20180717235528p:plain

確かに、真ん中を頂点に左右ほぼ対象になってますね。 これの平均と分散をみてみたいと思います。

print(sp.mean(saikoro))
print(sp.var(saikoro, ddof=0))
3.1
3.29

この場合、平均6.3、分散3.29の正規分布というらしいです。

あまり進まなかったのですが、統計学はひとまずこの辺りで、明日からテキストマイニングに戻ります。

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

回帰直線を求める

1つ前の投稿でxをいじりましたが、このようにxの値に対して、yはさまざまな値になりますので、yの平均に注目することがあるそうです。これをyの条件付き平均というらしいです。

式にするとこうなるそうです。

yの平均 = a + bx

簡単な1次式ですね。yの平均を予測値、bを回帰係数というらしい。回帰係数とは当てはめられた回帰直線の傾き、だそうでまた意味がわからない。この回帰係数bと切片のaを求めるのに使うのが最小2乗法だそうです。

最小2乗法とは

xの時、yの値はいくつという時に丁度良い線を引く際にそれぞれのyに近い場所に線を引きたいと思いますが、そのyとの距離が最小の線を求めるのが、最小2乗法というらしいです。

つまり、こういう線を引きたい時に、yとの距離を最小にする線を求めるモデルということだと思います。scikit-learnの公式ページにサンプルがありましたので、そのままコピペして確かめてみたいと思います。

import matplotlib.pyplot as plt
from sklearn import datasets, linear_model
from sklearn.metrics import mean_squared_error, r2_score

diabetes_X_train = x[:-20]
diabetes_X_test = x[-20:]

diabetes_y_train = y[:-20]
diabetes_y_test = y[-20:]
regr = linear_model.LinearRegression()
regr.fit(diabetes_X_train, diabetes_y_train)
diabetes_y_pred = regr.predict(diabetes_X_test)
print('Coefficients: \n', regr.coef_)
# The mean squared error
print("Mean squared error: %.2f"
      % mean_squared_error(diabetes_y_test, diabetes_y_pred))
# Explained variance score: 1 is perfect prediction
print('Variance score: %.2f' % r2_score(diabetes_y_test, diabetes_y_pred))
plt.scatter(diabetes_X_test, diabetes_y_test,  color='black')
plt.plot(diabetes_X_test, diabetes_y_pred, color='blue', linewidth=3)

plt.xticks(())
plt.yticks(())

plt.show()

実行結果。

Reshape your data either using array.reshape(-1, 1) if your data has a single feature or array.reshape(1, -1) if it contains a single sample.

リシェイプをしろという、エラーがでました。 言われたまま、reshape(-1, 1) というメソッドを使ってみます。

x
0       33
1       73
2     1370
(以下、省略)

これが、

x_reshape = x.reshape(-1, 1)
x_reshape
array([[  33],
       [  73],
       [1370],

こうなりました。どうやらarray配列にしないといけなかったようです。yのreshapeも追加して再実行してみます。

import matplotlib.pyplot as plt
import numpy as np
from sklearn import datasets, linear_model
from sklearn.metrics import mean_squared_error, r2_score

x_reshape = x.reshape(-1, 1)
y_reshape = y.reshape(-1, 1)

diabetes_X_train = x_reshape[:-20]
diabetes_X_test = x_reshape[-20:]

diabetes_y_train = y_reshape[:-20]
diabetes_y_test = y_reshape[-20:]

regr = linear_model.LinearRegression()
regr.fit(diabetes_X_train, diabetes_y_train)
diabetes_y_pred = regr.predict(diabetes_X_test)

plt.scatter(diabetes_X_test, diabetes_y_test,  color='black')
plt.plot(diabetes_X_test, diabetes_y_pred, color='blue', linewidth=3)

plt.show()

f:id:rimt:20180716200055p:plain

うまく線が引けました。 サンプルが長すぎて、読み込むのが辛いですが、1行ずつみていきたいと思います。

diabetes_X_train = x_reshape[:-20]
diabetes_X_test = x_reshape[-20:]
  • diabetes_X_train = x_reshape[:-20]

xの配列から始めの20個を学習データとして取得、なぜ[:-20]というわかりずらいす取得の仕方をしているのか謎ですね。

  • diabetes_X_test = x_reshape[-20:]

こっちは、xの配列から終わりの20個を学習データとして取得。

regr = linear_model.LinearRegression()
regr.fit(diabetes_X_train, diabetes_y_train)
diabetes_y_pred = regr.predict(diabetes_X_test)
  • regr = linear_model.LinearRegression()

回帰直線のモデルを取得

  • regr.fit(diabetes_X_train, diabetes_y_train)

fitメソッドでモデルに学習データをfitさせる

  • diabetes_y_pred = regr.predict(diabetes_X_test)

学習したデータをpredictメソッドでx全体に適用させる。

plt.scatter(diabetes_X_test, diabetes_y_test,  color='black')
plt.plot(diabetes_X_test, diabetes_y_pred, color='blue', linewidth=3)

plt.show()
  • plt.scatter(diabetes_X_test, diabetes_y_test, color='black')

xとyの散布図を作る

  • plt.plot(diabetes_X_test, diabetes_y_pred, color='blue', linewidth=3)

線を引く

  • plt.show()

図を出力

だそうです。sikit-learnを使うと、どこで計算をしているのか全くわからないですが、つまりはこういう線を引くのが1つの目的だそうです。

全然高速ではなくなってきましたが、まだまだ続きます。

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を超える数値ってあんまりないんですね。

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

2018/7/14【22日目】高速で学ぶ統計学その1

データもたまってきましたので、連休中に統計学を高速で学びたいと思います。 やり方としましては、

  1. 『心理統計学の基礎』で統計の基礎を学び、
  2. 『あたらしいPythonで学ぶ統計学の教科書』で実装し、
  3. 統計学入門』で定義を確認していきたいとおもいます。

それではやっていきます。

用語の確認

  • 横断的研究

    ある1つの時点で集団を比較する研究

  • 縦断的研究

    同一の集団について2つ以上の時点でデータを取って比較する研究

今回のは同一の集団について日付毎に行なっているので、おそらく縦断的研究になるのでしょう。

  • 母集団

    仮説が少なくとも暗黙的に想定している対象集団

  • サンプル

    実際にデータを収集する対象集団

今回の例でいうとAKB48が母集団で、Twiiterからデータを取得しているメンバーがサンプルですね。もしくは一人の全Tweetが母集団で100個取り出したのがサンプル。

  • 変数

    統計学の変数は、個人内で変化する値のことらしい。 今回の例でいうと、呟きとか、リツイート数とかのこと。

  • 相関

    2つの間の区別をつけず対等にみる見方。

  • 相関関係

    2つの変数間の関係のこと。統計学では2つの変数の間に直線関係に近い傾向があるときに「相関関係がある」、と言える。 Twiiterで言うと、リツイート数が高いとファボ数が高いとか、呟きの回数が多いとフォロワーが多いとか、の間稀。

代表値とは

  • 代表値

    分布全体を1つの値で表す数値。平均値や中央値、または最大値や最小値を使うことが多い。

  • 平均値

    分布全体の平均値。

  • 中央値

    値を順番に並んでいって、丁度真ん中にある数値。 平均は大きく外れた値(外れ値)の影響を受けやすいので、どちらかと言うと中央値の方が的確になりやすい。

以下、Pythonでの表し方。使用しているデータは7月14日から15日のメンバー全員を対象にしたTweet毎のリツイートされた回数を記録した1列の68行のデータです。

import numpy as np
import scipy as sp

favorite_count = pd.read_csv(‘retweet_count.csv',
                   sep='\n',
                   encoding='utf-8',)
#平均の出し方。NumPyでも可
print(int(sp.average(favorite_count, axis = 0)))
#meanを使っても平均を出せる。NumPyでも可
print(int(sp.mean(favorite_count, axis = 0)))
#中央値はmedian()。NumPyでも可
print(int(sp.median(favorite_count, axis = 0)))

実行結果。

220
220
108

小数点以下まで出すと、後で詰みそうなので、intを使って整数にしています。 220が平均値、108が中央値です。結構違いますね。SciPyを使うと簡単に表示ができますね。

どれだけ離れているかを表す。

  • 平均偏差

    各データが中央値から平均してどれだけ離れているかを示す。 どれだけ離れているかを示すものなので、「平均からの平均偏差」と「中央値からの平均偏差」の2種類がある。(マイナスの値になることがあるが)この数値には絶対値を使われている。

  • 分散

    平均偏差を絶対値ではなく、2乗してマイナスの数を消す方法。2乗になるので単位が変わる

  • 標準偏差

    分散に√をかけて単位を戻した数値。

このどれだけ離れているかがわかることによって、分布の広がりを表す散布図を得られる。偏差値は平均が50が標準偏差が10になるように標準化された分布らしいです。偏差値のようにある平均と標準偏差を持った変数は標準得点といい、標準得点を求めることを標準化というらしいです。

以下、pythonでの表し方。

#分散
print(int(sp.var(retweet_count, ddof=0)))
#標準偏差
print(int(sp.std(retweet_count, ddof=1)))

実行結果。

76486
278

なお、ddofという引数はDelta Degrees of Freedomというものを表しており、現状は何を表しているのか謎です。分散の時は0、標準偏差の時は1を指定するらしいです。

また、平均偏差だけはSciPyにないらしく、statsmodelsを使います。論文などでは平均偏差を使われることはなく、標準偏差が用いられるそうです。

from statsmodels import robust
print(int(robust.mad(retweet_count, axis=0)))

実行結果

79

標準化の手続き

何をやっているかというと、元の数字から平均を引いて、平均を0にして、標準偏差で割っているそうです。 ちなみに標準偏差はシグマで表すそうです。

heikin = int(sp.mean(retweet_count))
sigma = sp.std(retweet_count, ddof = 1)
hyouzyunka = (retweet_count - heikin) / sigma
#平均
print(sp.mean(hyouzyunka))
#標準偏差
print(sp.std(hyouzyunka, ddof = 1))

実行結果。

retweet    0.00285
dtype: float64
retweet    1.0
dtype: float64

平均がほぼ0、標準偏差が1になりました。

まだ全然意味がわからないので、その2に続きます。

2018/7/14【22日目】高速で学ぶ統計学その1

データもたまってきましたので、連休中に統計学を高速で学びたいと思います。 やり方としましては、

  1. 『心理統計学の基礎』で統計の基礎を学び、
  2. 『あたらしいPythonで学ぶ統計学の教科書』で実装し、
  3. 統計学入門』で定義を確認していきたいとおもいます。

それではやっていきます。

用語の確認

  • 横断的研究

    ある1つの時点で集団を比較する研究

  • 縦断的研究

    同一の集団について2つ以上の時点でデータを取って比較する研究 今回のは同一の集団について日付毎に行なっているので、おそらく縦断的研究になるのでしょう。

  • 母集団

    仮説が少なくとも暗黙的に想定している対象集団

  • サンプル

    実際にデータを収集する対象集団 今回の例でいうとAKB48が母集団で、Twiiterからデータを取得しているメンバーがサンプルですね。もしくは一人の全Tweetが母集団で100個取り出したのがサンプル。

  • 変数

    統計学の変数は、個人内で変化する値のことらしい。 今回の例でいうと、呟きとか、リツイート数とかのこと。

  • 相関

    2つの間の区別をつけず対等にみる見方。

  • 相関関係

    2つの変数間の関係のこと。統計学では2つの変数の間に直線関係に近い傾向があるときに「相関関係がある」、と言える。 Twiiterで言うと、リツイート数が高いとファボ数が高いとか、呟きの回数が多いとフォロワーが多いとか、の間稀。

代表値とは

  • 代表値

    分布全体を1つの値で表す数値。平均値や中央値、または最大値や最小値を使うことが多い。

  • 平均値

    分布全体の平均値。

  • 中央値

    値を順番に並んでいって、丁度真ん中にある数値。 平均は大きく外れた値(外れ値)の影響を受けやすいので、どちらかと言うと中央値の方が的確になりやすい。

以下、Pythonでの表し方。使用しているデータは7月14日から15日のメンバー全員を対象にしたTweet毎のリツイートされた回数を記録した1列の68行のデータです。

import numpy as np
import scipy as sp

favorite_count = pd.read_csv(‘retweet_count.csv',
                   sep='\n',
                   encoding='utf-8',)
#平均の出し方。NumPyでも可
print(int(sp.average(favorite_count, axis = 0)))
#meanを使っても平均を出せる。NumPyでも可
print(int(sp.mean(favorite_count, axis = 0)))
#中央値はmedian()。NumPyでも可
print(int(sp.median(favorite_count, axis = 0)))

実行結果。

220
220
108

小数点以下まで出すと、後で詰みそうなので、intを使って整数にしています。 220が平均値、108が中央値です。結構違いますね。SciPyを使うと簡単に表示ができますね。

どれだけ離れているかを表す。

  • 平均偏差

    各データが中央値から平均してどれだけ離れているかを示す。 どれだけ離れているかを示すものなので、「平均からの平均偏差」と「中央値からの平均偏差」の2種類がある。(マイナスの値になることがあるが)この数値には絶対値を使われている。

  • 分散

    平均偏差を絶対値ではなく、2乗してマイナスの数を消す方法。2乗になるので単位が変わる

  • 標準偏差

    分散に√をかけて単位を戻した数値。 このどれだけ離れているかがわかることによって、分布の広がりを表す散布図を得られる。偏差値は平均が50が標準偏差が10になるように標準化された分布らしいです。偏差値のようにある平均と標準偏差を持った変数は標準得点といい、標準得点を求めることを標準化というらしいです。

以下、pythonでの表し方。

#分散
print(int(sp.var(retweet_count, ddof=0)))
#標準偏差
print(int(sp.std(retweet_count, ddof=1)))

実行結果。

76486
278

なお、ddofという引数はDelta Degrees of Freedomというものを表しており、現状は何を表しているのか謎です。分散の時は0、標準偏差の時は1を指定するらしいです。 また、平均偏差だけはSciPyにないらしく、statsmodelsを使います。論文などでは平均偏差を使われることはなく、標準偏差が用いられるそうです。

from statsmodels import robust
print(int(robust.mad(retweet_count, axis=0)))

実行結果

79

標準化の手続き

何をやっているかというと、元の数字から平均を引いて、平均を0にして、標準偏差で割っているそうです。 ちなみに標準偏差はシグマで表すそうです。

heikin = int(sp.mean(retweet_count))
sigma = sp.std(retweet_count, ddof = 1)
hyouzyunka = (retweet_count - heikin) / sigma
#平均
print(sp.mean(hyouzyunka))
#標準偏差
print(sp.std(hyouzyunka, ddof = 1))

実行結果。

retweet    0.00285
dtype: float64
retweet    1.0
dtype: float64

平均がほぼ0、標準偏差が1になりました。

まだ全然意味がわからないので、その2に続きます。

2018/7/13【21日目後半】第1回AKBネガティブ・ポジティブ総選挙

1日経ってしまいましたが、昨日からの続きです。こんな感じのコードで6月15日から7月15日までの呟きを分析します。 ポジティブ率で順位を付けてみましたので、第1回AKBネガティブ・ポジティブ総選挙とでも呼んでおきます(別に誰も投票はしてないですが)。

コードはこんな感じです。

sougou = []
for list_keisiki in list_bara:
    tagger = MeCab.Tagger ("")
    string = ' '.join(list_keisiki)
    mecab = tagger.parse(string)
    kaigyou = mecab.split('\n')
    total_score = []
    for tango_list in kaigyou:
        tab = tango_list.split('\t')
        if tab[0] in npjp_dic:
            pn_score = npjp_dic[tab[0]]
            total_score.append(pn_score)
        else:
            pn_score = 0
            total_score.append(pn_score)
    total = sum(total_score)
    sougou.append(total)
    print(total)

sougou_goukei = sum(sougou)
positive = 0
negative = 0

for tandoku in sougou:
    print(tandoku)
    if tandoku > 0:
        positive += 1
    else:
        negative += 1

print("名前:” + "浅井七海" + "(" + "48_asainanami" + ")")
print("合計値:” + str(sougou_goukei))
print("平均ネガポジ数:” + str(sougou_goukei /nagasa))
print("---------------------")
print("1ヶ月のTweet数:” + str(nagasa))
print("ポジティブな数:” + str(positive))
print("ネガティブな数:” + str(negative))
print("ポジティブ率:” + str(positive / nagasa * 100) +"%")

では結果をどうぞ。

46位から40位

46位:岩立沙穂 (yahho_sahho)(22位)

  • 合計値:-57.3086741752
  • 平均ネガポジ数:-1.46945318398
  • 1ヶ月のTweet数:39
  • ポジティブな数:4
  • ネガティブな数:35
  • ポジティブ率:10.256410256410255%

45位:入山杏奈(iriyamaanna1203)

  • 合計値:-48.9071772501
  • 平均ネガポジ数:-2.57406196053
  • 1ヶ月のTweet数:19
  • ポジティブな数:2
  • ネガティブな数:17
  • ポジティブ率:10.526315789473683%

44位:宮崎美穂(730myao)

  • 合計値:-37.8895568753
  • 平均ネガポジ数:-1.18404865235
  • 1ヶ月のTweet数:32
  • ポジティブな数:5
  • ネガティブな数:27
  • ポジティブ率:15.625%

43位:大森美優(omorimyu_pon)(88位)

  • 合計値:-53.4960851787
  • 平均ネガポジ数:-1.24409500416
  • 1ヶ月のTweet数:43
  • ポジティブな数:7
  • ネガティブな数:36
  • ポジティブ率:16.27906976744186%

42位:前田彩佳(akb4816ayaka)

  • 合計値:-46.7980908835
  • 平均ネガポジ数:-1.08832769497
  • 1ヶ月のTweet数:43
  • ポジティブな数:7
  • ネガティブな数:36
  • ポジティブ率:16.27906976744186%

41位:北澤早紀(Sakii_Kitazawa)

  • 合計値:-66.5294499326
  • 平均ネガポジ数:-1.84804027591
  • 1ヶ月のTweet数:36
  • ポジティブな数:6
  • ネガティブな数:30
  • ポジティブ率:16.666666666666664%

40位:竹内美宥(take_miyu112)

  • 合計値:-48.6482612647
  • 平均ネガポジ数:-1.62160870882
  • 1ヶ月のTweet数:30
  • ポジティブな数:5
  • ネガティブな数:25
  • ポジティブ率:16.666666666666664%

割と予想通りの圏外メンバーが並んでいましたが、ダントツにネガティブなスコアを出したのは総選挙22位の岩立沙穂 (yahho_sahho)でした。確かにTweet内容をみてみると引っかかりそうな点は多いですね。

39位から30位

39位:岡田奈々 (okadanana_1107)(5位)

  • 合計値:-57.2790456121
  • 平均ネガポジ数:-1.14558091224
  • 1ヶ月のTweet数:50
  • ポジティブな数:9
  • ネガティブな数:41
  • ポジティブ率:18.0%

38位:市川愛美 (IckwMnm0826)

  • 合計値:-59.6689452936
  • 平均ネガポジ数:-1.57023540246
  • 1ヶ月のTweet数:38
  • ポジティブな数:7
  • ネガティブな数:31
  • ポジティブ率:18.421052631578945%

37位:田北香世子(kayoyon213)

  • 合計値:-60.8027543536
  • 平均ネガポジ数:-1.48299400863
  • 1ヶ月のTweet数:41
  • ポジティブな数:8
  • ネガティブな数:33
  • ポジティブ率:19.51219512195122%

36位:下口ひなな(177__shimo719)

  • 合計値:-74.4391800101
  • 平均ネガポジ数:-2.12683371457
  • 1ヶ月のTweet数:35
  • ポジティブな数:7
  • ネガティブな数:28
  • ポジティブ率:20.0%

35位:大家志津香(ooyachaaan1228)(100位)

  • 合計値:-99.3892567831
  • 平均ネガポジ数:-1.80707739606
  • 1ヶ月のTweet数:55
  • ポジティブな数:11
  • ネガティブな数:44
  • ポジティブ率:20.0%

34位:横山由依 (ui_yoko1208)(6位)

  • 合計値:-48.4599353416
  • 平均ネガポジ数:-1.03106245408
  • 1ヶ月のTweet数:47
  • ポジティブな数:10
  • ネガティブな数:37
  • ポジティブ率:21.27659574468085%

33位:馬嘉伶 @macyacyarin(macyacyarin)(97位)

  • 合計値:-88.244565562
  • 平均ネガポジ数:-2.10106108481
  • 1ヶ月のTweet数:42
  • ポジティブな数:9
  • ネガティブな数:33
  • ポジティブ率:21.428571428571427%

32位:佐藤妃星(ki_cyaco48)

  • 合計値:-45.5354416261
  • 平均ネガポジ数:-1.23068761152
  • 1ヶ月のTweet数:37
  • ポジティブな数:8
  • ネガティブな数:29
  • ポジティブ率:21.62162162162162%

31位:後藤萌咲(moe_goto0520)(65位)

  • 合計値:-63.5910151206
  • 平均ネガポジ数:-1.63053884925
  • 1ヶ月のTweet数:39
  • ポジティブな数:9
  • ネガティブな数:30
  • ポジティブ率:23.076923076923077%

30位:篠崎彩奈(ayana18_48)(94位)

  • 合計値:-44.5300719623
  • 平均ネガポジ数:-1.48433573208
  • 1ヶ月のTweet数:30
  • ポジティブな数:7
  • ネガティブな数:23
  • ポジティブ率:23.333333333333332%

すでに大本命の岡田奈々横山由依が出てきてしまいました。早くもAKBトップ2がネガティブな存在になってしまいましたので、もう誰が上位に来るのかわからないです。

29位から20位

29位:谷口めぐ(o_megu1112)(33位)

  • 合計値:-67.4557676593
  • 平均ネガポジ数:-1.34911535319
  • 1ヶ月のTweet数:50
  • ポジティブな数:12
  • ネガティブな数:38
  • ポジティブ率:24.0%

28位:高橋朱里(juri_t_official)(12位)

  • 合計値:-32.3293206536
  • 平均ネガポジ数:-0.87376542307
  • 1ヶ月のTweet数:37
  • ポジティブな数:9
  • ネガティブな数:28
  • ポジティブ率:24.324324324324326%

27位:小嶋真子(mak0_k0jima)(19位)

  • 合計値:-27.6969217123
  • 平均ネガポジ数:-1.20421398749
  • 1ヶ月のTweet数:23
  • ポジティブな数:6
  • ネガティブな数:17
  • ポジティブ率:26.08695652173913%

26位:込山榛香(912_komiharu)(52位)

  • 合計値:-80.6832593703
  • 平均ネガポジ数:-1.5223256485
  • 1ヶ月のTweet数:53
  • ポジティブな数:14
  • ネガティブな数:39
  • ポジティブ率:26.41509433962264%

25位:中西智代梨(chiyori_n512)

  • 合計値:-46.76495018
  • 平均ネガポジ数:-1.37543971118
  • 1ヶ月のTweet数:34
  • ポジティブな数:9
  • ネガティブな数:25
  • ポジティブ率:26.47058823529412%

24位:西川怜(rei_1025_48)

  • 合計値:-40.4769756347
  • 平均ネガポジ数:-0.941325014761
  • 1ヶ月のTweet数:43
  • ポジティブな数:13
  • ネガティブな数:30
  • ポジティブ率:30.23255813953488%

23位:山内瑞葵(MizukiYamauchi)(92位)

  • 合計値:-51.0712922327
  • 平均ネガポジ数:-1.2159831484
  • 1ヶ月のTweet数:42
  • ポジティブな数:13
  • ネガティブな数:29
  • ポジティブ率:30.952380952380953%

22位:野澤玲奈(RENAN0ZAWA)

  • 合計値:-30.2126421576
  • 平均ネガポジ数:-1.04181524682
  • 1ヶ月のTweet数:29
  • ポジティブな数:9
  • ネガティブな数:20
  • ポジティブ率:31.03448275862069%

21位:達家真姫宝(makiho_1019)

  • 合計値:-29.4547049371
  • 平均ネガポジ数:-0.775123814134
  • 1ヶ月のTweet数:38
  • ポジティブな数:12
  • ネガティブな数:26
  • ポジティブ率:31.57894736842105%

20位:峯岸みなみ(chan__31)(32位)

  • 合計値:-27.715149385
  • 平均ネガポジ数:-0.894037076935
  • 1ヶ月のTweet数:31
  • ポジティブな数:10
  • ネガティブな数:21
  • ポジティブ率:32.25806451612903%

29位の谷口めぐ(33位)が初めて出てきた中間層のメンバーですね。野球だと3割打てば一流だと言われますが、ここからはポジティブ率が3割を超えるメンバーになります。

19位から10位

19位:向井地美音(mionnn_48)(13位)

  • 合計値:-45.610983475
  • 平均ネガポジ数:-0.894333009314
  • 1ヶ月のTweet数:51
  • ポジティブな数:17
  • ネガティブな数:34
  • ポジティブ率:33.33333333333333%

18位:大川莉央(rio_rin48)

  • 合計値:-42.0239729149
  • 平均ネガポジ数:-1.27345372469
  • 1ヶ月のTweet数:33
  • ポジティブな数:11
  • ネガティブな数:22
  • ポジティブ率:33.33333333333333%

17位:村山彩希(yuirii_murayama)

  • 合計値:-36.688692288
  • 平均ネガポジ数:-0.87354029257
  • 1ヶ月のTweet数:42
  • ポジティブな数:14
  • ネガティブな数:28
  • ポジティブ率:33.33333333333333%

16位:福岡聖菜(seina_fuku48)(31位)

  • 合計値:-63.6991646616
  • 平均ネガポジ数:-1.02740588164
  • 1ヶ月のTweet数:62
  • ポジティブな数:21
  • ネガティブな数:41
  • ポジティブ率:33.87096774193548%

15位:久保怜音(AKB48K5)(75位)

  • 合計値:-33.508123904
  • 平均ネガポジ数:-0.881792734316
  • 1ヶ月のTweet数:38
  • ポジティブな数:13
  • ネガティブな数:25
  • ポジティブ率:34.21052631578947%

14位:佐々木優佳里(yukari__0828)(44位)

  • 合計値:-21.0462879258
  • 平均ネガポジ数:-0.553849682258
  • 1ヶ月のTweet数:38
  • ポジティブな数:13
  • ネガティブな数:25
  • ポジティブ率:34.21052631578947%

13位:田口愛佳(48manaka_16)

  • 合計値:-23.7021609517
  • 平均ネガポジ数:-0.526714687816
  • 1ヶ月のTweet数:45
  • ポジティブな数:16
  • ネガティブな数:29
  • ポジティブ率:35.55555555555556%

12位:武藤十夢(tommuto1125)(7位)

  • 合計値:-31.6116452071
  • 平均ネガポジ数:-0.71844648198
  • 1ヶ月のTweet数:44
  • ポジティブな数:16
  • ネガティブな数:28
  • ポジティブ率:36.36363636363637%

11位:茂木忍(mogi0_0216)

  • 合計値:-14.61976645
  • 平均ネガポジ数:-0.541472831481
  • 1ヶ月のTweet数:27
  • ポジティブな数:10
  • ネガティブな数:17
  • ポジティブ率:37.03703703703704%

10位浅井七海(48_asainanami)

  • 合計値-15.6690662851
  • 平均ネガポジ数-0.522302209504
  • 1ヶ月のTweet数30
  • ポジティブな数12
  • ネガティブな数18
  • ポジティブ率40.0%

3割3分3厘には3人も並ぶ激戦区でした。7位の武藤十夢(tommuto1125)が出ましたので、これでトップ勢は出尽くしました。別に上に行くほど幸せにはならないというやつですかね。

9位から3位

9位:藤田奈那(fujitanana_1228)

  • 合計値:-22.8761807006
  • 平均ネガポジ数:-0.714880646895
  • 1ヶ月のTweet数:32
  • ポジティブな数:13
  • ネガティブな数:19
  • ポジティブ率:40.625%

8位:武藤小麟(muto_orin)

  • 合計値:-22.554203372
  • 平均ネガポジ数:-0.5638550843
  • 1ヶ月のTweet数:40
  • ポジティブな数:17
  • ネガティブな数:23
  • ポジティブ率:42.5%

7位:樋渡結依(yui_hiwata430)

  • 合計値:-30.6489596353
  • 平均ネガポジ数:-0.828350260412
  • 1ヶ月のTweet数:37
  • ポジティブな数:16
  • ネガティブな数:21
  • ポジティブ率:43.24324324324324%

6位:千葉恵里(erii_20031027)

  • 合計値:-16.5471177256
  • 平均ネガポジ数:-0.435450466463
  • 1ヶ月のTweet数:38
  • ポジティブな数:17
  • ネガティブな数:21
  • ポジティブ率:44.73684210526316%

5位:山邊歩夢(ayuchan0203)

  • 合計値:-8.06534531044
  • 平均ネガポジ数:-0.16802802730
  • 1ヶ月のTweet数:48
  • ポジティブな数:22
  • ネガティブな数:26
  • ポジティブ率:45.83333333333333%

4位:湯本亜美(ami_15chans)

  • 合計値:-29.3536918827
  • 平均ネガポジ数:-0.77246557586
  • 1ヶ月のTweet数:38
  • ポジティブな数:19
  • ネガティブな数:19
  • ポジティブ率:50.0%

9位から4位は圏外勢が躍進しました。ポジティブなのはいいことだと思います。いよいよベスト3の発表です。

3位

3位:鈴木くるみ (akb48kururun)

  • 合計値:-4.0945732383
  • 平均ネガポジ数:-0.104989057392
  • 1ヶ月のTweet数:39
  • ポジティブな数:21
  • ネガティブな数:18
  • ポジティブ率:53.84615384615385%

2位

2位:加藤玲奈 (katorena_710)(36位)

  • 合計値:-5.90791883872
  • 平均ネガポジ数:-0.131287085305
  • 1ヶ月のTweet数:45
  • ポジティブな数:25
  • ネガティブな数:20
  • ポジティブ率:55.55555555555556%

1位

1位:川本紗矢 (sayaya_0388)(41位)

  • 合計値:6.662321873
  • 平均ネガポジ数:0.154937717977
  • 1ヶ月のTweet数:43
  • ポジティブな数:25
  • ネガティブな数:18
  • ポジティブ率:58.139534883720934%

1位は総選挙41位の川本紗矢(sayaya_0388)でした。これだけマイナスがつきやすい辞書で、メンバーの中で唯一合計値がマイナスではないのは驚きです。Tweet内容を見てみますと、確かにめちゃくちゃポジティブな内容が多いです。もはや圧倒的ポジティブ!

ベスト3位のメンバーには来年の総選挙に期待です。

勝手な雑感

スコア化することにより、今まで気づかなかったネガティブな表現がみえてきましたので面白かったです。 これを応用すれば性格診断や交流分析などにも使えそうなので、そちらも勉強していきたいと思います。