はじめに
よくビジネス記事などで、平均給与ランキングという記事があるが、
いささか平均というものは魔術でゴニョゴニョされることが多いので、
こういう指標だとどうなの?というのをチュートリアル的に書いてみたいと思う。
基本的にこの解析は雑 なので、あまり結果を鵜呑みにしない方が良い。
余談
この記事は、年始にデスクトップを整理していたら出てきて、削除しようと思ったけどいちおう結論まで出ていたから供養しようと投稿するもので、真面目に企業を査定しようとするものではありません。
アイデア
まず、平均年齢が上がれば年収が増えるという直感がある。
一般に同じ会社の中から適当に社員をサンプリングしてきたとき、年齢が高い方が身に付ける能力や技能は高く、さらには役職に付く可能性も高く、同時に年収も高い傾向にある、という経験則からである。
また、従業員数が増えれば役職の数も増えると考えられ、それらが平均年収に寄与するのかどうか、ということも知りたい。
そこで、平均年齢、従業員数をそれぞれ説明変数とし、平均年収を予測するモデルを構築する。
必要なモジュールのインポート
pip や anaconda で簡単に環境づくりできる時代なので、各モジュールのインストールは省略する。
ここでは、numpy
、pandas
、sklearn
、xgboost
をインストールする必要がある(xgboost
だけ少し複雑かもしれない)。
import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression, RidgeCV, Lasso
from sklearn.ensemble import RandomForestRegressor
from xgboost import XGBRegressor
データの読み込み
publickey さんからデータを拝借し、csv にしておく。
- IT系上場企業の平均給与を業種別にみてみた 2018年版[前編] ~ ネットベンチャー、ゲーム、メディア系
https://www.publickey1.jp/blog/18/it_2018.html - IT系上場企業の平均給与を業種別にみてみた 2018年版[後編] ~ パッケージソフトウェア系、SI/システム開発系、クラウド/キャリア系企業
https://www.publickey1.jp/blog/18/it_2018_si.html
このデータを data/salary.csv
として保存する。
データを2次公開してよいかどうかは微妙なところなので、各々でこの作業を行ってほしい。
df = pd.read_csv('./data/salary.csv')
学習モデルを定義
従業員数と平均年齢を説明変数として、年収との間に相関があるのでは?という直感から、そういうモデルを組み立てる。
基本的には DataFrame から説明変数を抜き出すところ以外は変わらないので、そこだけメソッド化。
def prepare_for_model_n_worker_describes_salary(df):
x = [[v] for v in df['n_workers'].values]
y = df['mean_salary'].values
return (x, y)
def prepare_for_model_age_describes_salary(df):
x = [[v] for v in df['mean_age'].values]
y = df['mean_salary'].values
return (x, y)
どのアルゴリズムが良いか比較する
各種リグレッサーを使って比較。
自由度が高いモデルは overfitting に注意。
regressors = [
LinearRegression(),
RidgeCV(),
Lasso(),
RandomForestRegressor(),
XGBRegressor(),
]
scores = {}
n = 10
# n回繰り返して平均を取る
for i in range(n):
#
# サンプリングの仕方が雑だけど、ざっと比較できれば良い(ちゃんとクロスバリデーション書くの面倒くさい)
# sklearn にクロスバリデーションが簡単に書けるやつがあるのは知ってるよ
# でも DataFrame 突っ込めるんだっけ?とか、API 調べるの面倒だよ
# 何なら読んでくれた人にコメントで書いておいてほしい
#
df_train = df.sample(n=int(df.shape[0]/2))
x_w_train, y_w_train = prepare_for_model_n_worker_describes_salary(df_train)
x_a_train, y_a_train = prepare_for_model_age_describes_salary(df_train)
df_test = df.sample(n=int(df.shape[0]/2))
x_w_test, y_w_test = prepare_for_model_n_worker_describes_salary(df_test)
x_a_test, y_a_test = prepare_for_model_age_describes_salary(df_test)
for reg in regressors:
name = reg.__class__.__name__
if name not in scores:
scores[name] = {'n_workers': [], 'ages': []}
reg.fit(x_w_train, y_w_train)
score = reg.score(x_w_test, y_w_test)
scores[name]['n_workers'].append(score)
reg.fit(x_a_train, y_a_train)
score = reg.score(x_a_test, y_a_test)
scores[name]['ages'].append(score)
# 平均スコアの比較
for reg in regressors:
name = reg.__class__.__name__
ms_w = np.mean(np.array(scores[name]['n_workers']))
ms_a = np.mean(np.array(scores[name]['ages']))
print('scores by {},\n\tn_workers = {}\n\tages = {}\n'.format(name, ms_w, ms_a))
scores by LinearRegression,
n_workers = -0.10807971772977312
ages = 0.43705004393376373
scores by RidgeCV,
n_workers = -0.10807969763739456
ages = 0.43700566128245233
scores by Lasso,
n_workers = -0.10807527879694716
ages = 0.437042904756201
scores by RandomForestRegressor,
n_workers = 0.34281493519643963
ages = 0.49390979300492993
scores by XGBRegressor,
n_workers = 0.37043473644605884
ages = 0.5042511965145637
細かいことはさておき
XGBoostRegressor がどちらの指標でも良いっぽい。
平均年齢の方に関しては、線形モデルでもそこそこ精度が出ているので、年齢との相関は強いっぽいなぁ、雑な解析だけど。
なので XGBoost を使って予測してみる
結果は csv にして spreadsheet で表示する。
pandas でグラフ表示すればいいじゃん!というのはごもっともなんだけど、スプレッドシートの方が直感的で早い。
後でこねくり回すわけでなければスプレッドシートの方が可視化とかにも簡単(このデータ数ならば)。
※ train_*
のメソッドが見当たらないけど、おそらく第一引数のモデルを学習しているだけ
reg_w = XGBRegressor()
reg_a = XGBRegressor()
x_w, y_w = prepare_for_model_n_worker_describes_salary(df)
reg_w = train_n_worker_describes_salary(reg_w, x_w, y_w)
x_a, y_a = prepare_for_model_age_describes_salary(df)
reg_a = train_age_describes_salary(reg_a, x_a, y_a)
diffs_w = []
diffs_a = []
pred_w = reg_w.predict(x_w)
pred_a = reg_a.predict(x_a)
count = 0
result = {}
for d in df.itertuples():
actual = d.mean_salary
expected_w = pred_w[count]
expected_a = pred_a[count]
ratio_w = actual / expected_w
ratio_a = actual / expected_a
count += 1
result[d.name] = {
'name': d.name,
'expected_w': expected_w,
'expected_a': expected_a,
'actual': actual,
'ratio_w': ratio_w,
'ratio_a': ratio_a,
}
df_result = pd.DataFrame(result).T
df_result.to_csv('samary_of_salary.csv')
結果
見にくくなるので、最下部に tsv の生データを貼り付けている。
expected(X) が指標 X
から期待される年収なのに対し、actual が実際の平均年収、
ratio(X) は指標 X
の期待年収と実際の年収との比である。
ただし、ratio(product) は ratio(n workers) と ratio(mean age) の積で、
従業員数と平均年齢の両方の影響を加味した比である。
注目すべきは ratio(...)で、ratio(n workers) が大きいほど、
この従業員数にしては平均給与が高い!という意味になる(予測モデルが妥当ならばという条件付き)。
同様に、ratio(mean age) が大きいほど、この平均年齢にしては平均給与が高い!という意味になる(同上)。
つまり、両ratio が高い企業は、他に比べて良く人材に投資している企業だと考えることができる。
ただし、ここには業種、業態、役員数、役職者数などの変数が入っていないため、
実際には給与が高いのは役員手前の役職持ちだけで、平社員は他企業に比べて低い、なんてこともあり得る。
他のどの統計もそうだが、一般にこの指標が高いからこの企業は優良だ、というのは難しく、
多角的に見て、こういった指標で切ったときにこうなっているから、この企業ではここを見なければいけない、
という論理展開が必要である。
※ ratio(product) で降順
name expected(n workers) expected(mean age) actual ratio(n workers) ratio(mean age) ratio(product)
(株)オービック 773.7681274 655.1433105 877 1.13341448 1.338638411 1.517232158
テクマトリックス(株) 576.3709717 642.0036621 746 1.294305294 1.161987141 1.503966109
(株)ミクシィ 576.3709717 522.5099487 666 1.155505799 1.274616879 1.472827195
東洋ビジネスエンジニアリング(株) 595.1005859 753.4799194 807 1.356073274 1.071030533 1.452395882
ソースネクスト(株) 623.1326904 623.7352295 749 1.201991183 1.200830039 1.44338712
(株)ジャストシステム 751.9296875 833.3251953 951 1.264745914 1.141211145 1.443342132
(株)ディー・エヌ・エー 642.9976196 637.8458252 757 1.177298293 1.186807172 1.397226058
ISID 699.3291626 827.1504517 897 1.282657793 1.084446002 1.390973115
(株)ユーザベース 563.3231812 592.6373901 672 1.192920907 1.133914281 1.352670052
(株)三菱総合研究所 793.4802246 886.6829834 975 1.228764082 1.099603825 1.351153685
(株)野村総合研究所 1064.203491 957.4052124 1166 1.095655116 1.217875133 1.33437112
トレンドマイクロ(株) 758.9573364 833.3251953 915 1.205601364 1.098010723 1.323763225
任天堂(株) 878.0438843 702.6268311 903 1.028422401 1.285177224 1.321705047
インフォテリア(株) 609.8165894 675.8973389 737 1.208560103 1.090402281 1.317816693
(株)サイバーエージェント 699.3291626 538.7087402 703 1.005249084 1.30497233 1.311822239
ヤフー(株) 745.1188965 603.0393677 767 1.029365922 1.271890429 1.309240664
(株)NTTデータイントラマート 610.6682739 642.0036621 716 1.172485997 1.115258436 1.307624899
クックパッド(株) 591.1740723 572.6190796 650 1.099506948 1.135135072 1.248088898
LINE(株) 699.3291626 590.2640381 715 1.022408385 1.211322313 1.23846609
KDDI(株) 865.4657593 820.6074219 936 1.081498592 1.140618492 1.233577293
(株)Gunosy 602.3768921 549.0093384 638 1.059137574 1.162093166 1.230816536
(株)カカクコム 624.0244141 604.8148804 681 1.091303456 1.125964361 1.228768799
日本オラクル(株) 900.0001831 955.5774536 1027 1.141110879 1.074742812 1.226400715
(株)LIFULL 624.0244141 642.4219971 701 1.123353485 1.091183059 1.225784292
グリー(株) 758.9573364 672.2853394 779 1.026408156 1.158734178 1.189334211
楽天(株) 728.9985352 590.2640381 707 0.9698236223 1.197769057 1.161624725
(株)NTTデータ 830.8305664 702.6268311 821 0.9881677844 1.168472315 1.154646699
(株)マネーフォワード 578.4611816 572.6190796 614 1.061436825 1.072266052 1.138142674
(株)朝日ネット 602.3768921 675.8973389 679 1.127201274 1.004590433 1.132375615
(株)セック 591.1740723 642.0036621 653 1.104581596 1.017128154 1.12350104
バリューコマース(株) 578.4611816 587.9794922 617 1.066622998 1.049356327 1.119267591
(株)ブロードバンドタワー 602.3768921 642.0036621 657 1.090679288 1.023358649 1.116156083
伊藤忠テクノソリューションズ(株) 804.5678101 819.8688965 855 1.062682336 1.04284966 1.108217913
(株)ドリコム 587.0799561 554.1394043 600 1.022007299 1.082760034 1.106588657
ソフトバンク・テクノロジー(株) 655.1060791 623.7352295 668 1.019682188 1.070967244 1.092046223
(株)デジタルガレージ 595.1005859 587.9794922 617 1.036799517 1.049356327 1.087972132
(株)コロプラ 604.1364136 492.9030457 568 0.9401850099 1.152356442 1.083428253
新日鉄住金ソリューションズ(株) 804.5678101 833.3251953 837 1.040310076 1.004409809 1.044897645
(株)大塚商会 766.689209 819.8688965 808 1.053882056 0.9855234214 1.03862545
(株)オウケイウェイヴ 563.3231812 587.9794922 586 1.040255433 0.9966333993 1.036753309
(株)ユビキタスAIコーポレーション 641.7440796 758.2072144 709 1.104801778 0.9351005722 1.033100775
ウォンテッドリー(株) 506.3501587 507.0843811 514 1.015107809 1.013638004 1.028951853
日本ユニシス(株) 804.5678101 758.2072144 790 0.9818936206 1.041931526 1.023065919
日本ファルコム(株) 506.3501587 590.2640381 550 1.086204854 0.9317863948 1.012110905
(株)gumi 576.3709717 604.8148804 593 1.028851259 0.9804652948 1.008752953
ビジネスコンサルタント 647.6647339 642.4219971 646 0.9974296364 1.005569552 1.002984873
(株)オービック 647.6647339 642.4219971 646 0.9974296364 1.005569552 1.002984873
アイティメディア(株) 610.6682739 702.6268311 656 1.074232981 0.9336392677 1.002946093
(株)enish 566.3271484 604.8148804 586 1.03473761 0.9688915055 1.002548481
(株)エニグモ 509.8183899 554.1394043 531 1.041547364 0.9582426297 0.9980550848
エキサイト(株) 578.4611816 603.0393677 584 1.009575091 0.9684276538 0.9777004366
(株)レアジョブ 587.5178833 604.8148804 589 1.002522675 0.9738517009 0.9763084123
(株)クラウドワークス 566.3271484 492.9030457 522 0.9217287242 1.059031801 0.9761400305
(株)はてな 563.3231812 538.7087402 543 0.9639226969 1.007965825 0.9716011368
(株)ユーザーローカル 641.7440796 553.9151611 587 0.9146948428 1.059729073 0.9693287175
(株)駅探 509.8183899 653.8118896 568 1.114122227 0.8687514085 0.9678952541
(株)ベリサーブ 615.4140015 652.8118286 623 1.012326659 0.9543331979 0.9660969378
(株)SRAホールディングス 657.1419678 682.7514648 658 1.001305703 0.9637474746 0.9650058425
KLab(株) 576.3709717 554.1394043 554 0.9611865053 0.999748431 0.9609447005
サイオス(株) 680.9452515 820.6074219 729 1.070570649 0.8883663254 0.9510589138
(株)テラスカイ 578.4611816 623.7352295 585 1.011303815 0.9378979611 0.9484997864
富士通(株) 829.2805176 794.8381958 790 0.9526330153 0.9939129802 0.9468343193
サイボウズ(株) 587.0799561 637.8458252 595 1.013490571 0.9328273017 0.9454116748
(株)インタースペース 527.368103 523.9463501 511 0.9689626602 0.9752906951 0.9450202664
(株)インターネットイニシアティブ 763.3681641 623.7352295 669 0.876379225 1.072570489 0.9399784937
フリービット(株) 578.4611816 604.4632568 573 0.9905591217 0.9479484378 0.9389989719
ネットワンシステムズ(株) 769.1536255 833.3251953 773 1.005000788 0.9276090587 0.9322478353
(株)NTTドコモ 856.6231079 957.4052124 874 1.020285341 0.9128841045 0.9314022701
(株)セゾン情報システムズ 655.1060791 733.6549683 668 1.019682188 0.9105097476 0.9284305715
GMOインターネット(株) 576.3709717 546.3873291 540 0.9368965936 0.9883098879 0.9259441674
(株)ASJ 506.3501587 604.4632568 532 1.050656331 0.8801196665 0.9247032997
日本プロセス(株) 576.3709717 642.0036621 584 1.013236316 0.909652132 0.9216925751
(株)ソリトンシステムズ 576.3709717 755.1387329 633 1.098251007 0.8382565645 0.9206161161
(株)ネオジャパン 563.3231812 590.2640381 553 0.9816744961 0.936868866 0.9197002719
(株)ファンコミュニケーションズ 518.9317627 523.9463501 499 0.961590783 0.9523875868 0.9158071253
(株)電算システム 576.3709717 652.8118286 587 1.018441297 0.8991871383 0.9157693154
(株)エイチーム 518.9317627 532.6176147 502 0.9673718899 0.9425148288 0.9117623512
(株)アドウェイズ 576.3709717 529.3322144 527 0.9143416756 0.9955940442 0.9103131265
TIS(株) 728.9985352 675.8973389 669 0.9176973173 0.9897952863 0.9083324788
(株)みんなのウェディング 563.3231812 590.2640381 549 0.9745737764 0.9300922377 0.9064435045
ネットイヤーグループ(株) 610.6682739 642.0036621 592 0.9694297629 0.9221131201 0.8939239034
(株)リブセンス 591.1740723 529.3322144 527 0.8914464025 0.9955940442 0.8875187291
(株)ラック 642.9976196 675.8973389 621 0.9657889564 0.9187785841 0.8873462099
(株)ぐるなび 631.7301636 587.9794922 574 0.9086157874 0.9762245242 0.8870130147
エン・ジャパン(株) 606.3043213 460.5044556 495 0.8164216922 1.074908167 0.8775783443
SCSK(株) 766.689209 792.5020752 726 0.9469286792 0.9160859293 0.867468039
(株)ネクソン 591.1740723 603.0393677 556 0.9405013279 0.921996191 0.8671386419
(株)マクロミル 603.6443481 534.8388672 528 0.8746872254 0.9872132195 0.8635027918
(株)メルカリ 600.772522 492.9030457 502 0.8355908129 1.01845587 0.851012368
富士ソフト(株) 653.9989014 623.7352295 586 0.89602597 0.9395012055 0.841817479
さくらインターネット(株) 587.0799561 642.0036621 561 0.9555768243 0.8738267912 0.8350086301
(株)ブランジスタ 515.0378418 450.776886 440 0.8543061583 0.9760926385 0.8338819521
(株)キャリアデザインセンター 576.3709717 460.5044556 466 0.8085070604 1.011933749 0.8181555804
(株)オークファン 587.5178833 581.1178589 525 0.8935898207 0.9034311921 0.807296917
(株)オールアバウト 566.3271484 579.4524536 514 0.9076026135 0.8870443067 0.8050837311
(株)イード 555.630127 623.7352295 525 0.9448731711 0.8417032984 0.7953028647
(株)パピレス 509.8183899 523.9463501 460 0.9022820854 0.8779524849 0.7921607989
GMOペパボ(株) 574.8297729 532.6176147 491 0.8541659168 0.9218621135 0.7874231973
(株)SHIFT 576.3709717 590.2640381 517 0.8969917387 0.8758792111 0.7856564164
(株)カプコン 676.6923218 604.4632568 563 0.8319881605 0.931404835 0.7749177953
(株)コア 603.6443481 724.6617432 579 0.9591740597 0.798993469 0.7663738093
ディップ(株) 616.184021 460.5044556 465 0.7546446908 1.009762217 0.762011696
ジョルダン(株) 566.3271484 614.4620972 514 0.9076026135 0.8365039965 0.7592132134
(株)メンバーズ 524.5172119 450.776886 423 0.8064558996 0.9383799683 0.7567620616
(株)エヌアイデイ 603.6443481 702.6268311 562 0.9310117816 0.7998555921 0.7446749798
アウンコンサルティング(株) 444.492981 450.776886 385 0.8661554096 0.8540810587 0.7397669292
(株)ボルテージ 518.9317627 460.5044556 416 0.8016468251 0.9033571662 0.7241734042
クルーズ(株) 563.3231812 492.9030457 448 0.7952806044 0.9089008558 0.7228312219
(株)ザッパラス 566.3271484 590.2640381 491 0.8669900452 0.831831127 0.7211893063
(株)フルスピード 515.0378418 538.7087402 434 0.8426565289 0.8056301441 0.6788695007
ソーバル(株) 603.6443481 603.0393677 494 0.8183626692 0.8191836661 0.6703893315
(株)オウチーノ 509.8183899 587.9794922 448 0.8787442919 0.761931336 0.6695428123
AppBank(株) 506.3501587 517.3466187 389 0.7682430692 0.7519136803 0.5776524735
(株)Aiming 498.0993652 410.3424072 340 0.6825947265 0.8285763158 0.5655818237
(株)日本一ソフトウェア 526.8168945 522.5099487 388 0.7364987798 0.7425695931 0.5469015992
GMOクラウド(株) 566.3210449 493.6746216 379 0.6692317077 0.7677121396 0.5137773062