終了済み: 対戦ゲームデータ分析甲子園

目指せ"Another" バトル優勝!

賞金: 100,000 参加ユーザー数: 560 約2ヶ月前に終了

period と A1-level を用いた A1-player 特定

import os
import pandas as pd
import numpy as np
from tqdm import tqdm_notebook as tqdm
import sys
sys.path.append('PATH')
from scr import config 
pd.set_option("display.max_columns", 300)
pd.set_option("display.max_rows", 300)

# データのロード
train = pd.read_csv(config.INPUT +"train_data.csv")
test = pd.read_csv(config.INPUT + "test_data.csv")
data = pd.concat([train, test]).reset_index(drop=True)

A1-level と period から A1-player を特定

period と A1-level でソートした A1-level を シーケンスとして考えます。

そのシーケンスを先頭から見ていき、同じレベルがくれば同じラベルをはり、レベルアップ最低試合数以上のレベルが続いた後にレベル+1のレベルがきたとき、レベルを更新して同じラベルを付与します。これをすべてのレベルに対してラベルを付与するまで繰り返します。

def get_seq_labels(seq, threshold=0):
    """
    seq : 時系列順のリスト
    threshold : level up のための最低試合数
    
    [3,3,3,4,4,4,4,4,7,7,7,7,2,2,2,1,1,1,2,8,8,8] : level
     => [1,1,1,1,1,1,1,1,2,2,2,2,3,3,3,4,4,4,3,2,2,2] : player id
    というように、レベルに応じてA1の特定を考えます
    
    """
    
    box = np.zeros(len(seq), dtype=int)  # 最終的にラベルが入るボックス
    count = 1  # label

    for _ in (range(1000)):
        # level : 時系列順のレベルでユニークなもの
        # s     : levelの値を格納

        ind = np.where(box == 0)[0][0]
        s = seq[ind]

        renew_box = []
        for i in range(len(seq)):

            if box[i] == 0:

                if s == seq[i]:
                    box[i] = count
                    renew_box.append(seq[i])

                elif (s + 1 == seq[i]) and ((np.array(renew_box)==s).sum() >= threshold):  
                    s += 1
                    box[i] = count

            else:
                continue

        count += 1

        if (box == 0).sum() == 0:
            # box が全部埋まれば break
            break
            
    return box


seq = [3,3,3,4,4,4,4,4,7,7,7,7,2,2,2,1,1,1,2,8,8,8]
box = get_seq_labels(seq)
box
array([1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 3, 2, 2, 2])
sorted_data = data.sort_values(["period", "A1-level"]).reset_index(drop=True)
levels = sorted_data["A1-level"].tolist() # A1 level を時系列順にソートしたリスト

a1_player = get_seq_labels(levels, 15)
a1_player
array([  1,   1,   1, ..., 294, 294, 294])
df = data.sort_values(["period", "A1-level"])[["period", "A1-level","A1-rank", "A1-weapon"]]
df["A1-player"] = a1_player
df
period A1-level A1-rank A1-weapon A1-player
5295 2019-10-10T02:00:00+00:00 63 s prime_becchu 1
15390 2019-10-10T02:00:00+00:00 63 s prime_becchu 1
37652 2019-10-10T02:00:00+00:00 63 s prime_becchu 1
57989 2019-10-10T02:00:00+00:00 63 s prime_becchu 1
61306 2019-10-10T02:00:00+00:00 63 s prime_becchu 1
... ... ... ... ... ...
65018 2020-01-06T00:00:00+00:00 111 x kelvin525_deco 15
79454 2020-01-06T00:00:00+00:00 111 x kelvin525_deco 15
21014 2020-01-06T00:00:00+00:00 401 x furo 294
44399 2020-01-06T00:00:00+00:00 401 x furo 294
50204 2020-01-06T00:00:00+00:00 401 x furo 294

94465 rows × 5 columns

df[df["A1-player"] == 1]
period A1-level A1-rank A1-weapon A1-player
5295 2019-10-10T02:00:00+00:00 63 s prime_becchu 1
15390 2019-10-10T02:00:00+00:00 63 s prime_becchu 1
37652 2019-10-10T02:00:00+00:00 63 s prime_becchu 1
57989 2019-10-10T02:00:00+00:00 63 s prime_becchu 1
61306 2019-10-10T02:00:00+00:00 63 s prime_becchu 1
... ... ... ... ... ...
76149 2020-01-05T18:00:00+00:00 72 x sputtery_clear 1
91914 2020-01-05T18:00:00+00:00 72 x dualsweeper_custom 1
6070 2020-01-05T20:00:00+00:00 72 x dualsweeper_custom 1
27995 2020-01-05T20:00:00+00:00 72 x dualsweeper_custom 1
68757 2020-01-05T20:00:00+00:00 72 x dualsweeper_custom 1

558 rows × 5 columns

df[df["A1-player"] == 300]
period A1-level A1-rank A1-weapon A1-player
9796 2019-12-16T04:00:00+00:00 401 x dualsweeper 300
5150 2019-12-16T06:00:00+00:00 401 x dualsweeper 300
6951 2019-12-16T06:00:00+00:00 401 x dualsweeper 300
12053 2019-12-16T06:00:00+00:00 401 x dualsweeper 300
13261 2019-12-16T06:00:00+00:00 401 x dualsweeper 300
31080 2019-12-16T06:00:00+00:00 401 x dualsweeper 300
34159 2019-12-16T06:00:00+00:00 401 x dualsweeper 300
40014 2019-12-16T06:00:00+00:00 401 x dualsweeper 300
40226 2019-12-16T06:00:00+00:00 401 x dualsweeper 300
40758 2019-12-16T06:00:00+00:00 401 x dualsweeper 300
45012 2019-12-16T06:00:00+00:00 401 x dualsweeper 300
45408 2019-12-16T06:00:00+00:00 401 x dualsweeper 300
46201 2019-12-16T06:00:00+00:00 401 x dualsweeper 300
65362 2019-12-16T06:00:00+00:00 401 x dualsweeper 300
68493 2019-12-16T06:00:00+00:00 401 x dualsweeper 300
71186 2019-12-16T06:00:00+00:00 401 x dualsweeper 300
79714 2019-12-16T06:00:00+00:00 401 x dualsweeper 300
88625 2019-12-16T06:00:00+00:00 401 x dualsweeper 300
89712 2019-12-16T06:00:00+00:00 401 x dualsweeper 300
93603 2019-12-16T06:00:00+00:00 401 x dualsweeper 300
7837 2019-12-16T10:00:00+00:00 401 x dualsweeper 300
16300 2019-12-16T10:00:00+00:00 401 x dualsweeper 300
18166 2019-12-16T10:00:00+00:00 401 x dualsweeper 300
20694 2019-12-16T10:00:00+00:00 401 x dualsweeper 300
28344 2019-12-16T10:00:00+00:00 401 x dualsweeper 300
28449 2019-12-16T10:00:00+00:00 401 x dualsweeper 300
30406 2019-12-16T10:00:00+00:00 401 x dualsweeper 300
40556 2019-12-16T10:00:00+00:00 401 x dualsweeper 300
55685 2019-12-16T10:00:00+00:00 401 x dualsweeper 300
57654 2019-12-16T10:00:00+00:00 401 x dualsweeper 300
58323 2019-12-16T10:00:00+00:00 401 x dualsweeper 300
67476 2019-12-16T10:00:00+00:00 401 x dualsweeper 300
83323 2019-12-16T10:00:00+00:00 401 x dualsweeper 300
90773 2019-12-16T10:00:00+00:00 401 x dualsweeper 300
26218 2019-12-16T12:00:00+00:00 401 NaN dualsweeper 300
75121 2019-12-16T12:00:00+00:00 401 NaN dualsweeper 300
6902 2019-12-16T14:00:00+00:00 401 x dualsweeper 300
18886 2019-12-16T14:00:00+00:00 401 x dualsweeper 300
27640 2019-12-16T14:00:00+00:00 401 x dualsweeper 300
29600 2019-12-16T14:00:00+00:00 401 x dualsweeper 300
33619 2019-12-16T14:00:00+00:00 401 x dualsweeper 300
36569 2019-12-16T14:00:00+00:00 401 x dualsweeper 300
46802 2019-12-16T14:00:00+00:00 401 x dualsweeper 300
52855 2019-12-16T14:00:00+00:00 401 x dualsweeper 300
73086 2019-12-16T14:00:00+00:00 401 x dualsweeper 300
74595 2019-12-16T14:00:00+00:00 401 x dualsweeper 300
85026 2019-12-16T14:00:00+00:00 401 x dualsweeper 300
90748 2019-12-16T14:00:00+00:00 401 x dualsweeper 300
22086 2019-12-17T02:00:00+00:00 401 x dualsweeper 300
42847 2019-12-17T02:00:00+00:00 401 x dualsweeper 300
80203 2019-12-17T02:00:00+00:00 401 x dualsweeper 300
83815 2019-12-17T02:00:00+00:00 401 x dualsweeper 300
93308 2019-12-17T02:00:00+00:00 401 x dualsweeper 300
8551 2019-12-17T02:00:00+00:00 402 x dualsweeper 300
12227 2019-12-17T02:00:00+00:00 402 x dualsweeper 300
23468 2019-12-17T02:00:00+00:00 402 x dualsweeper 300
38148 2019-12-17T02:00:00+00:00 402 x dualsweeper 300
47410 2019-12-17T02:00:00+00:00 402 x dualsweeper 300
48789 2019-12-17T02:00:00+00:00 402 x dualsweeper 300
49082 2019-12-17T02:00:00+00:00 402 x dualsweeper 300
49697 2019-12-17T02:00:00+00:00 402 x dualsweeper 300
61753 2019-12-17T02:00:00+00:00 402 x dualsweeper 300
68161 2019-12-17T02:00:00+00:00 402 x dualsweeper 300
88137 2019-12-17T02:00:00+00:00 402 x dualsweeper 300
91416 2019-12-17T02:00:00+00:00 402 x dualsweeper 300

問題点・注意点

  1. レベルアップ最低マッチ数の設定が甘い
  2. 新規参入A1-playerが丁度シーケンスの対象レベルと重なったとき、同一とみなしてしまう
  3. レベルは不可逆、投稿者は対象期間内のすべてのマッチを投稿している仮定
  4. 武器などでさらに細分化するのもよさそう

何かほかにいい特定方法、実装ミスの指摘や質問などあれば、教えてください!

添付データ

  • identify_A1_player.ipynb?X-Amz-Expires=600&X-Amz-Date=20201204T140228Z&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIP7GCBGMWPMZ42PQ
  • Aws4 request&x amz signedheaders=host&x amz signature=6dfc73f1adbbb94fca1a1d7164387b29f43f812682b8aae1ee3151ca46ec914d
    masato8823
    Favicon
    new user
    コメントするには 新規登録 もしくは ログイン が必要です。