前回はWeb上からアイドルの基本情報及び、第7回シンデレラガール総選挙の結果を取得するところまで行った。
ただしその情報には欠損が多く、肝心の三村の得票数についても公表されていなかった。
そこで今回は、三村の第7回シンデレラガールズ総選挙における現在地及び、全体の概要をつかむことで次回以降の分析に繋げられるようにしたい。
第7回シンデレラガールズ総選挙データの確認
それではまず、前回取得したシンデレラガール総選挙のデータをもう一度確認してみよう。
ご覧の通り、過去の順位や氏名については漏れがないが、得票数については多くの欠損が見られる。
これは、シンデレラガール総選挙においては上位10名もしくは各アイドル固有のCute,Cool,Passionという属性の上位5名ずつの各得票数飲みが公表されるという制約があるからである。
特に今回は上位の多くをCool、Cute勢が占めたため、16位の南条光以下票数が公表されているアイドルは全てPassionということになる。
## 得票数の傾向の確認
さて、今回のプロジェクトはの目標は今後のシンデレラガール総選挙において三村が最多得票数を獲得しシンデレラガールに輝くことである。
なので各得票数の欠損値の穴埋めにはある程度、妥当と言える基準が求められる。
そのために、まずは順位と得票数の関係を棒グラフで確認する。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
plt.style.use('ggplot')
master_df = pd.read_csv('data/mobamasdata.csv').set_index('名前').rename(columns={'Unnamed: 0':'type'})
senkyo_df = pd.read_csv('data/senkyo7.csv')
# 得票数の数字は「,」付きの文字列なので「,」を削除しFloatに置き換える。
senkyo_df['votes'] = senkyo_df['votes'].str.replace(',','').astype(float)
senkyo_df.plot.bar(x='7th',y='votes')
グラフを見ると傾きが徐々になだらかになっている。
欠損値の穴埋め
このような場合、対数を取ることで、xとyの関係を直線化することができるという話を聞いたことがあったので、
対数化し、最小二乗法を使って近似直線の傾きaと切片bを求めた。
import math
senkyo_df['log_votes'] = senkyo_df['votes'].map(lambda x : math.log(x))
senkyo_df['log_7th'] = senkyo_df['7th'].map(lambda x : math.log(x))
temp_df = senkyo_df.dropna().copy()
X = temp_df['log_7th']
Y = temp_df['log_votes']
A = np.array([X,np.ones(len(X))])
A = A.T
a,b = np.linalg.lstsq(A,Y)[0]
plt.scatter(X,Y)
plt.plot(X,(a*X+b),"g--")
print(a,b)
※最小二乗法の実装についてはこちらを参考にさせていただきました。
ありがとうございます。
問題なく近似直線が取れているようなので、傾き(a=-0.46270145203071894)と切片(b= 14.684553743738004)を使い獲得票数の予想値であるpred_votesを出し、実際のデータと照らし合わせる。
senkyo_df['pred_votes'] =senkyo_df['log_7th'].map(lambda x: math.exp(a*x+b)).astype(int)
plt.plot(senkyo_df['7th'],senkyo_df['pred_votes'])
plt.scatter(senkyo_df['7th'],senkyo_df['votes'])
多少ズレはあるものの、問題なさそうなので今後は欠損をこちらで埋めたものを使っていこうと思う。
##三村の得票数の確認
上位50位までの想定得票数が出たので、三村の想定書く得票数を見ていこうと思う。
とはいえ、既に算出までは完了しているので、Jupyterでは以下のコードを実行するだけで確認できる。
senkyo_df
なお結果が立てに長いため、写真は上位下位で分けて貼り付ける。
- votes:実際の各得票数
- 7th:当該選挙の順位
- pred_votes:推測獲得票数
オーマイゴッド
よりわかりやすく、1位の安倍さんと三村のみしてみよう。
senkyo_df.loc[['三村かな子','安部菜々'],['7th','votes','pred_votes']]
一位の安倍菜々さんが約230万票なのに対し、三村は約40万票ということで、頂点に立つには190万票足りないという結果が出た。
思っていた以上に厳しい結果である。
ただ、登らねばならぬ山が高いことが確認できたことは収穫である。
総投票数等の推測
さて、今回の最後に全体の総得票数等のデータも出してみたいと思う。
ただ、上記の結果に心が折れかけているので、実データがあるものについても予測値を使うことをご容赦いただきたい。
# 全アイドル人数分の順位のnumpy配列を作り対数を取る
l = np.log(np.arange(1,df.shape[0]))
# 想定得票数に変える
pred_votes_all = [int(math.exp(a * x +b)) for x in l]
#以下は簡単な集計
total_votes = sum(pred_votes_all)
top50_votes = sum(pred_votes_all[:50])
other_votes = total_votes - top50_votes
other_member = df.shape[0]-50
votes_of_others = int(other_votes/other_member)
ans_text = '総投票数:{0}\n総投票数(TOP50):{1}\n総投票数(51位以下):{2}\n51位タイ得票集:{3}'
print(ans_text.format(total_votes,top50_votes,other_votes,votes_of_others))
推測では総投票数が約7000万件と出た。数の上では国会議員選挙をも超えているということだろうか。
一番下の51位タイ得票数は51位以下のアイドルに入ったであろう得票を当該人数で割ったものである。
次回以降、残念ながらランク圏外だったアイドルについては全員51位扱いとし、全員が272934票獲得したという形で分析を進めていきたいと思う。
それは、推測が困難だからというよりは、公表されていない順位について推測で上下をつけるのは彼女たちおよびそのプロデューサーさんたちに失礼だと考えるからである。予めご了承願いたい。
次回に向けて
さて、次回は選挙結果と基本情報を結合し、属性ごとの傾向などを見ていこうと考えているが、正直頭がくらくらしている。
それは山の高さや途方もなさに対してではなく、我々のプロデュースが不十分であることが原因で三村の魅力がお茶の間に十分に伝わっていないことに対してである。
もし少しでも三村に興味を持っていただけたのであれば、ぜひ「[桜色の華姫]三村かな子+」で検索していただきたい。