Мамкин Data Scientist

Итак, перед нами игра PUBG, суть ее заключается в следующем: 100 игроков с пустыми руками выбрасываются из самолета на остров, где должны найти оружие и убить всех.

Команда PUBG предоставляет данные о 65к игр и просит предсказать место, которое займет игрок.

Я хочу показать самые первые шаги, когда к вам в руки попадают данные

Ну шо, погнали

Для начала давайте взглянем на данные

In [1]:
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
In [2]:
import warnings
warnings.filterwarnings('ignore')
In [3]:
data = pd.read_csv('train_V2.csv')
data.head(5)
Out[3]:
Id groupId matchId assists boosts damageDealt DBNOs headshotKills heals killPlace ... revives rideDistance roadKills swimDistance teamKills vehicleDestroys walkDistance weaponsAcquired winPoints winPlacePerc
0 7f96b2f878858a 4d4b580de459be a10357fd1a4a91 0 0 0.00 0 0 0 60 ... 0 0.0000 0 0.00 0 0 244.80 1 1466 0.4444
1 eef90569b9d03c 684d5656442f9e aeb375fc57110c 0 0 91.47 0 0 0 57 ... 0 0.0045 0 11.04 0 0 1434.00 5 0 0.6400
2 1eaf90ac73de72 6a4a42c3245a74 110163d8bb94ae 1 0 68.00 0 0 0 47 ... 0 0.0000 0 0.00 0 0 161.80 2 0 0.7755
3 4616d365dd2853 a930a9c79cd721 f1f1f4ef412d7e 0 0 32.90 0 0 0 75 ... 0 0.0000 0 0.00 0 0 202.70 3 0 0.1667
4 315c96c26c9aac de04010b3458dd 6dc8ff871e21e6 0 0 100.00 0 0 0 45 ... 0 0.0000 0 0.00 0 0 49.75 2 0 0.1875

5 rows × 29 columns

Каждый уважающий себя Data Scientist должен скролить csv вправо, затем влево, бурча себе под нос "suka blat chto eto za huyna"

Когда этот ритуал неувенчался успехом, следует почитать описание признаков

DBNOs - Number of enemy players knocked.

assists - Number of enemy players this player damaged that were killed by teammates.

boosts - Number of boost items used.

damageDealt - Total damage dealt. Note: Self inflicted damage is subtracted.

headshotKills - Number of enemy players killed with headshots.

heals - Number of healing items used.

Id - Player’s Id

killPlace - Ranking in match of number of enemy players killed.

killPoints - Kills-based external ranking of player. (Think of this as an Elo ranking where only kills matter.) If there is a value other than -1 in rankPoints, then any 0 in killPoints should be treated as a “None”.

killStreaks - Max number of enemy players killed in a short amount of time.

kills - Number of enemy players killed.

longestKill - Longest distance between player and player killed at time of death. This may be misleading, as downing a player and driving away may lead to a large longestKill stat.

matchDuration - Duration of match in seconds.

matchId - ID to identify match. There are no matches that are in both the training and testing set.

matchType - String identifying the game mode that the data comes from. The standard modes are “solo”, “duo”, “squad”, “solo-fpp”, “duo-fpp”, and “squad-fpp”; other modes are from events or custom matches.

rankPoints - Elo-like ranking of player. This ranking is inconsistent and is being deprecated in the API’s next version, so use with caution. Value of -1 takes place of “None”.

revives - Number of times this player revived teammates.

rideDistance - Total distance traveled in vehicles measured in meters.

roadKills - Number of kills while in a vehicle.

swimDistance - Total distance traveled by swimming measured in meters.

teamKills - Number of times this player killed a teammate.

vehicleDestroys - Number of vehicles destroyed.

walkDistance - Total distance traveled on foot measured in meters.

weaponsAcquired - Number of weapons picked up.

winPoints - Win-based external ranking of player. (Think of this as an Elo ranking where only winning matters.) If there is a value other than -1 in rankPoints, then any 0 in winPoints should be treated as a “None”.

groupId - ID to identify a group within a match. If the same group of players plays in different matches, they will have a different groupId each time.

numGroups - Number of groups we have data for in the match.

maxPlace - Worst placement we have data for in the match. This may not match with numGroups, as sometimes the data skips over placements.

winPlacePerc - The target of prediction. This is a percentile winning placement, where 1 corresponds to 1st place, and 0 corresponds to last place in the match. It is calculated off of maxPlace, not numGroups, so it is possible to have missing chunks in a match.

Так уже лучше, теперь мы понимаем, что целевой признак "winPlacePerc", и он распределен от 0 до 1, это конечно же нам наруку. Перед нами типичная задача регрессии

Посмотрим общую информацию о признаках

In [4]:
print(data.info())
print(data.shape)
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4446966 entries, 0 to 4446965
Data columns (total 29 columns):
Id                 object
groupId            object
matchId            object
assists            int64
boosts             int64
damageDealt        float64
DBNOs              int64
headshotKills      int64
heals              int64
killPlace          int64
killPoints         int64
kills              int64
killStreaks        int64
longestKill        float64
matchDuration      int64
matchType          object
maxPlace           int64
numGroups          int64
rankPoints         int64
revives            int64
rideDistance       float64
roadKills          int64
swimDistance       float64
teamKills          int64
vehicleDestroys    int64
walkDistance       float64
weaponsAcquired    int64
winPoints          int64
winPlacePerc       float64
dtypes: float64(6), int64(19), object(4)
memory usage: 983.9+ MB
None
(4446966, 29)

В нашем распоряжении 29 бравых солдат, 4 из которых категорильные

Еще немного информации

In [5]:
data.describe()
Out[5]:
assists boosts damageDealt DBNOs headshotKills heals killPlace killPoints kills killStreaks ... revives rideDistance roadKills swimDistance teamKills vehicleDestroys walkDistance weaponsAcquired winPoints winPlacePerc
count 4.446966e+06 4.446966e+06 4.446966e+06 4.446966e+06 4.446966e+06 4.446966e+06 4.446966e+06 4.446966e+06 4.446966e+06 4.446966e+06 ... 4.446966e+06 4.446966e+06 4.446966e+06 4.446966e+06 4.446966e+06 4.446966e+06 4.446966e+06 4.446966e+06 4.446966e+06 4.446965e+06
mean 2.338149e-01 1.106908e+00 1.307171e+02 6.578755e-01 2.268196e-01 1.370147e+00 4.759935e+01 5.050060e+02 9.247833e-01 5.439551e-01 ... 1.646590e-01 6.061157e+02 3.496091e-03 4.509322e+00 2.386841e-02 7.918208e-03 1.154218e+03 3.660488e+00 6.064601e+02 4.728216e-01
std 5.885731e-01 1.715794e+00 1.707806e+02 1.145743e+00 6.021553e-01 2.679982e+00 2.746294e+01 6.275049e+02 1.558445e+00 7.109721e-01 ... 4.721671e-01 1.498344e+03 7.337297e-02 3.050220e+01 1.673935e-01 9.261157e-02 1.183497e+03 2.456544e+00 7.397004e+02 3.074050e-01
min 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 1.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 ... 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00
25% 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 2.400000e+01 0.000000e+00 0.000000e+00 0.000000e+00 ... 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 1.551000e+02 2.000000e+00 0.000000e+00 2.000000e-01
50% 0.000000e+00 0.000000e+00 8.424000e+01 0.000000e+00 0.000000e+00 0.000000e+00 4.700000e+01 0.000000e+00 0.000000e+00 0.000000e+00 ... 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 6.856000e+02 3.000000e+00 0.000000e+00 4.583000e-01
75% 0.000000e+00 2.000000e+00 1.860000e+02 1.000000e+00 0.000000e+00 2.000000e+00 7.100000e+01 1.172000e+03 1.000000e+00 1.000000e+00 ... 0.000000e+00 1.909750e-01 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 1.976000e+03 5.000000e+00 1.495000e+03 7.407000e-01
max 2.200000e+01 3.300000e+01 6.616000e+03 5.300000e+01 6.400000e+01 8.000000e+01 1.010000e+02 2.170000e+03 7.200000e+01 2.000000e+01 ... 3.900000e+01 4.071000e+04 1.800000e+01 3.823000e+03 1.200000e+01 5.000000e+00 2.578000e+04 2.360000e+02 2.013000e+03 1.000000e+00

8 rows × 25 columns

Один чувак из команды PUBG сказал, что в этом датасете есть один перец, который единственый зашел на матч и для него нет целевого признака, давайте найдем этого победителя по жизни

In [6]:
np.sum(data.isnull())
Out[6]:
Id                 0
groupId            0
matchId            0
assists            0
boosts             0
damageDealt        0
DBNOs              0
headshotKills      0
heals              0
killPlace          0
killPoints         0
kills              0
killStreaks        0
longestKill        0
matchDuration      0
matchType          0
maxPlace           0
numGroups          0
rankPoints         0
revives            0
rideDistance       0
roadKills          0
swimDistance       0
teamKills          0
vehicleDestroys    0
walkDistance       0
weaponsAcquired    0
winPoints          0
winPlacePerc       1
dtype: int64
In [7]:
data[data['winPlacePerc'].isnull()]
Out[7]:
Id groupId matchId assists boosts damageDealt DBNOs headshotKills heals killPlace ... revives rideDistance roadKills swimDistance teamKills vehicleDestroys walkDistance weaponsAcquired winPoints winPlacePerc
2744604 f70c74418bb064 12dfbede33f92b 224a123c53e008 0 0 0.0 0 0 0 1 ... 0 0.0 0 0.0 0 0 0.0 0 0 NaN

1 rows × 29 columns

Вот он красавец, благополучно дропаем его без всяких сожалений

In [8]:
data.drop(data[data['winPlacePerc'].isnull()].index.values, inplace=True)

Выбросы

Итак, с чего бы я начал анализ этих данных? Раз это игра, значит в ней обязательно есть либо багаюзеры, либо читеры, либо еще какие-нибудь черти, которые портят или искажают игровой процесс, эти pidori обязательно ухудшат качество модели, так что давайте искать АНОМАЛИИ

Сегодня я сильно не буду вдаваться в Feature Engineering, но создать эту пару признаков все же считаю своим долгом

Люди, которые не двигались всю игру и кого-то настреляли полюбому нечистые на душу

In [9]:
data['totalDistance'] = data['rideDistance'] + data['walkDistance'] + data['swimDistance']
data['killsWithoutMoving'] = ((data['kills'] > 0) & (data['totalDistance'] == 0))

Посмотрим на этих петухов

In [10]:
display(data[data['killsWithoutMoving']].head(5))
print('размерность:', data[data['killsWithoutMoving']].shape)
Id groupId matchId assists boosts damageDealt DBNOs headshotKills heals killPlace ... roadKills swimDistance teamKills vehicleDestroys walkDistance weaponsAcquired winPoints winPlacePerc totalDistance killsWithoutMoving
1824 b538d514ef2476 0eb2ce2f43f9d6 35e7d750e442e2 0 0 593.0 0 0 3 18 ... 0 0.0 0 0 0.0 8 0 0.8571 0.0 True
6673 6d3a61da07b7cb 2d8119b1544f87 904cecf36217df 2 0 346.6 0 0 6 33 ... 0 0.0 0 0 0.0 22 0 0.6000 0.0 True
11892 550398a8f33db7 c3fd0e2abab0af db6f6d1f0d4904 2 0 1750.0 0 4 5 3 ... 0 0.0 0 0 0.0 13 0 0.8947 0.0 True
14631 58d690ee461e9d ea5b6630b33d67 dbf34301df5e53 0 0 157.8 0 0 0 69 ... 0 0.0 0 0 0.0 7 1500 0.0000 0.0 True
15591 49b61fc963d632 0f5c5f19d9cc21 904cecf36217df 0 0 100.0 0 1 0 37 ... 0 0.0 0 0 0.0 10 0 0.3000 0.0 True

5 rows × 31 columns

размерность: (1535, 31)

Давайте до свидания

In [11]:
data.drop(data[data['killsWithoutMoving'] == True].index, inplace=True)

Так, давайте следующий подозрительный признак

In [12]:
plt.figure(figsize=(10, 5))
sns.countplot(data['roadKills'])
plt.show()
In [13]:
data['roadKills'].value_counts()
Out[13]:
0     4432434
1       11247
2        1298
3         297
4          72
5          36
6          20
7          11
8           7
11          2
10          2
9           2
18          1
14          1
Name: roadKills, dtype: int64
In [14]:
data[data['roadKills'] > 10]
Out[14]:
Id groupId matchId assists boosts damageDealt DBNOs headshotKills heals killPlace ... roadKills swimDistance teamKills vehicleDestroys walkDistance weaponsAcquired winPoints winPlacePerc totalDistance killsWithoutMoving
2733926 c3e444f7d1289f 489dd6d1f2b3bb 4797482205aaa4 0 0 1246.0 0 0 0 1 ... 14 5.297 0 0 1277.0 0 1371 0.4286 1282.302 False
2767999 34193085975338 bd7d50fa305700 a22354d036b3d6 0 0 1102.0 0 0 0 1 ... 11 0.000 0 0 816.6 5 1533 0.4713 4934.600 False
2890740 a3438934e3e535 1081c315a80d14 fe744430ac0070 0 8 2074.0 0 1 11 1 ... 18 0.000 0 0 3150.0 4 1568 1.0000 5876.000 False
3524413 9d9d044f81de72 8be97e1ba792e3 859e2c2db5b125 0 3 1866.0 0 5 7 1 ... 11 0.000 0 0 1041.0 10 1606 0.9398 7853.000 False

4 rows × 31 columns

Чуваков, которые зашли поиграть в Need for speed, мы тоже кикаем, особенно угарный c3e444f7d1289f, который проехал 5 метров и задавил 14 тел. Окей, пока

In [15]:
data.drop(data[data['roadKills'] > 10].index, inplace=True)

Теперь перейдем к самому очевидному признаку, который стоит проверить, убийствам

In [16]:
plt.figure(figsize=(10,5))
sns.distplot(data['kills'],bins=15)
plt.show()

Pizdec, больше 70 убийств при 100 игроках? Это точно читеры, на корм рыбам

In [17]:
display(data[data['kills'] > 30].head(5))
print(data[data['kills'] > 30].shape)
Id groupId matchId assists boosts damageDealt DBNOs headshotKills heals killPlace ... roadKills swimDistance teamKills vehicleDestroys walkDistance weaponsAcquired winPoints winPlacePerc totalDistance killsWithoutMoving
57978 9d8253e21ccbbd ef7135ed856cd8 37f05e2a01015f 9 0 3725.0 0 7 0 2 ... 0 0.0 0 0 48.82 48 1500 0.8571 48.82 False
87793 45f76442384931 b3627758941d34 37f05e2a01015f 8 0 3087.0 0 8 27 3 ... 0 0.0 0 0 780.70 45 1500 1.0000 780.70 False
156599 746aa7eabf7c86 5723e7d8250da3 f900de1ec39fa5 21 0 5479.0 0 12 7 4 ... 0 0.0 0 0 23.71 61 0 0.7000 23.71 False
160254 15622257cb44e2 1a513eeecfe724 db413c7c48292c 1 0 4033.0 0 40 0 1 ... 0 0.0 1 0 718.30 16 1500 1.0000 718.30 False
180189 1355613d43e2d0 f863cd38c61dbf 39c442628f5df5 5 0 3171.0 0 6 15 1 ... 0 0.0 0 0 71.51 41 0 1.0000 71.51 False

5 rows × 31 columns

(95, 31)
In [18]:
data.drop(data[data['kills'] > 30].index, inplace=True)

Есть еще кое какой подозрительный признак, longestKill - дистанция при убийстве, давайте взглянем

In [19]:
plt.figure(figsize=(10,5))
sns.distplot(data['longestKill'], bins=15)
plt.show()

Основная масса - это убийства на ~100 метрах, чуваки, убивающие с 1км+, что вы такое?

In [20]:
display(data[data['longestKill'] > 1000].head(5))
print(data[data['longestKill'] > 1000].shape)
Id groupId matchId assists boosts damageDealt DBNOs headshotKills heals killPlace ... roadKills swimDistance teamKills vehicleDestroys walkDistance weaponsAcquired winPoints winPlacePerc totalDistance killsWithoutMoving
240005 41c2f5c0699807 9faecf87ab4275 634edab75860b3 5 0 1284.0 8 5 7 18 ... 0 0.0 0 0 48.87 38 1500 0.5385 48.87 False
324313 ef390c152bcc3d 30fd444be3bbc1 4f7f8d6cf558b4 2 0 1028.0 0 0 0 9 ... 0 0.0 0 0 1264.00 26 0 1.0000 2981.00 False
803632 4e7e6c74e3c57d 94698690918933 da91b0c3d875f8 0 0 196.8 0 0 0 51 ... 0 0.0 0 0 1074.00 22 0 0.0000 3159.00 False
895411 1f5ba6e0cfb968 512ea24b831be3 5fb0d8b1fc16cf 4 0 1012.0 11 5 0 5 ... 0 0.0 0 0 569.50 18 0 0.9091 569.50 False
1172437 303a93cfa1f46c 8795d39fd0df86 9c8962b58bb3e3 2 1 329.3 0 0 2 45 ... 0 0.0 0 0 832.50 9 1500 0.2857 832.50 False

5 rows × 31 columns

(18, 31)

Боюсь, придется пожертвовать этими элитными снайперами

In [21]:
data.drop(data[data['longestKill'] > 1000].index, inplace=True)

Давайте переходить к гонщикам наскар, марафонцам и водолазам

Посмотрим, сколько игроки накатывают на тачках за игру

In [22]:
plt.figure(figsize=(10,5))
sns.distplot(data['rideDistance'], bins=15)
plt.show()
In [23]:
display(data[data['rideDistance'] > 20000].head(5))
print(data[data['rideDistance'] > 20000].shape)
Id groupId matchId assists boosts damageDealt DBNOs headshotKills heals killPlace ... roadKills swimDistance teamKills vehicleDestroys walkDistance weaponsAcquired winPoints winPlacePerc totalDistance killsWithoutMoving
28588 6260f7c49dc16f b24589f02eedd7 6ebea3b4f55b4a 0 0 99.2 0 0 1 30 ... 0 0.0 0 0 376.6 6 0 0.6421 26306.6 False
63015 adb7dae4d0c10a 8ede98a241f30a 8b36eac66378e4 0 0 0.0 0 0 0 55 ... 0 0.0 0 0 185.4 0 0 0.5376 22065.4 False
70507 ca6fa339064d67 f7bb2e30c3461f 3bfd8d66edbeff 0 0 100.0 0 0 0 26 ... 1 0.0 0 0 467.5 3 0 0.8878 28917.5 False
72763 198e5894e68ff4 ccf47c82abb11f d92bf8e696b61d 0 0 0.0 0 0 0 46 ... 0 0.0 1 0 687.2 9 0 0.7917 21197.2 False
95276 c3fabfce7589ae 15529e25aa4a74 d055504340e5f4 0 7 778.2 0 1 2 2 ... 2 0.0 0 0 923.2 6 0 0.9785 26733.2 False

5 rows × 31 columns

(150, 31)

150 человек просто катаются всю игру по карте

Избавляемся от них по наработанной схеме

In [24]:
data.drop(data[data['rideDistance'] > 20000].index, inplace=True)

Теперь к дайверам

In [25]:
plt.figure(figsize=(10,5))
sns.distplot(data['swimDistance'], bins=15)
plt.show()
In [26]:
display(data[data['swimDistance'] > 2000].head(5))
print(data[data['swimDistance'] > 2000].shape)
Id groupId matchId assists boosts damageDealt DBNOs headshotKills heals killPlace ... roadKills swimDistance teamKills vehicleDestroys walkDistance weaponsAcquired winPoints winPlacePerc totalDistance killsWithoutMoving
177973 c2e9e5631f4e54 23213058f83abe f01eb1073ef377 0 5 78.12 1 0 1 47 ... 0 2295.0 0 0 1002.0 4 1466 0.9592 3297.0 False
274258 ba5e3dfb5a0fa0 383db055216ec2 d6e13468e28ab4 0 4 53.32 0 0 16 39 ... 0 2148.0 0 0 2276.0 5 0 0.9600 10113.0 False
1005337 d50c9d0e65fe2a 4996575c11abcb 668402592429f8 0 1 503.00 4 3 1 6 ... 0 2718.0 0 0 4691.0 5 1516 1.0000 10740.0 False
1195818 f811de9de80b70 d08ddf7beb6252 8a48703ab52ec8 0 7 352.30 3 1 6 4 ... 0 2668.0 0 0 415.1 10 1499 1.0000 3083.1 False
1227362 a33e917875c80e 5b72674b42712b 5fb0d8b1fc16cf 0 1 589.20 3 1 1 46 ... 0 3823.0 0 0 995.3 9 0 1.0000 4818.3 False

5 rows × 31 columns

(12, 31)

Чтоб вы понимали как это выглядит

и так всю игру, тоже удаляем

In [27]:
data.drop(data[data['swimDistance'] > 2000].index, inplace=True)

Пешие

Все стандартно

In [28]:
plt.figure(figsize=(10,5))
sns.distplot(data['walkDistance'], bins=15)
plt.show()
In [29]:
display(data[data['walkDistance'] > 10000].head(5))
print(data[data['walkDistance'] > 10000].shape)
Id groupId matchId assists boosts damageDealt DBNOs headshotKills heals killPlace ... roadKills swimDistance teamKills vehicleDestroys walkDistance weaponsAcquired winPoints winPlacePerc totalDistance killsWithoutMoving
23026 8a6562381dd83f 23e638cd6eaf77 b0a804a610e9b0 0 1 0.00 0 0 0 44 ... 0 9.882 0 0 13530.0 7 0 0.8163 13540.3032 False
34344 5a591ecc957393 6717370b51c247 a15d93e7165b05 0 3 23.22 0 0 1 34 ... 0 40.870 0 0 10030.0 7 1533 0.9474 10070.9073 False
49312 582685f487f0b4 338112cd12f1e7 d0afbf5c3a6dc9 0 4 117.20 1 0 1 24 ... 0 36.750 0 0 12410.0 3 0 0.9130 12446.7588 False
68590 8c0d9dd0b4463c c963553dc937e9 926681ea721a47 0 1 32.34 0 0 1 46 ... 0 45.820 0 0 11590.0 3 1563 0.8333 12483.6200 False
94400 d441bebd01db61 7e179b3366adb8 923b57b8b834cc 1 1 73.08 0 0 3 27 ... 0 45.630 0 0 10440.0 6 1488 0.8194 11490.6300 False

5 rows × 31 columns

(219, 31)
In [30]:
data.drop(data[data['walkDistance'] > 10000].index, inplace=True)

А вот еще забавный признак weaponsAcquired - сколько оружий поднял игрок за матч

In [31]:
plt.figure(figsize=(10,5))
sns.distplot(data['weaponsAcquired'], bins=15)
plt.show()

Зачем подбирать более 100 оружий? Не знаете? Я тоже не знаю, но они мне не нравятся

Голову с плеч

In [32]:
display(data[data['weaponsAcquired'] > 80].head(5))
print(data[data['weaponsAcquired'] > 80].shape)
Id groupId matchId assists boosts damageDealt DBNOs headshotKills heals killPlace ... roadKills swimDistance teamKills vehicleDestroys walkDistance weaponsAcquired winPoints winPlacePerc totalDistance killsWithoutMoving
233643 7c8c83f5f97d0f b33b210a52a2f8 2e8a0917a71c43 0 0 67.11 0 0 0 44 ... 0 0.00 0 0 1307.0 128 1577 0.7111 3187.00 False
1437471 8f0c855d23e4cd 679c3316056de8 fbaf1b3ae1d884 1 0 100.00 0 0 0 24 ... 0 47.21 0 0 2400.0 102 0 0.8929 5299.21 False
1449293 db54cf45b9ed1c 898fccaeeb041d 484b4ae51fe80f 0 0 0.00 0 0 0 54 ... 0 0.00 0 0 653.1 95 0 0.5600 653.10 False
1592744 634a224c53444e 75fa7591d1538c f900de1ec39fa5 9 0 1726.00 0 3 0 9 ... 0 0.00 0 0 980.8 94 0 0.2000 2888.80 False
1834515 e927e9020f7e0d 60d6b714a7308f 8e265af296007b 1 1 26.46 0 0 1 51 ... 0 0.00 0 0 2835.0 96 0 0.9200 2835.00 False

5 rows × 31 columns

(17, 31)
In [33]:
data.drop(data[data['weaponsAcquired'] > 80].index, inplace=True)

Ну и последний признак, который мы сегодня рассмотрим heals

In [34]:
plt.figure(figsize=(10,5))
sns.distplot(data['heals'], bins=15)
plt.show()

Уф

Эти ребята точно что-то скрывают, посмотрим на них

In [35]:
display(data[data['heals'] > 40].head(5))
print(data[data['heals'] > 40].shape)
Id groupId matchId assists boosts damageDealt DBNOs headshotKills heals killPlace ... roadKills swimDistance teamKills vehicleDestroys walkDistance weaponsAcquired winPoints winPlacePerc totalDistance killsWithoutMoving
18405 63ab976895d860 927eeba5614c4f 69473402649f11 0 2 0.0 0 0 47 43 ... 0 0.000 0 0 1387.0 6 0 0.9368 6854.000 False
54463 069ddee7c9d26a 58ab5a1ce8e06f 942416b6caf21e 1 4 182.0 0 1 43 21 ... 0 292.400 0 0 2791.0 7 0 0.9615 3083.400 False
126439 c45bd6917146e2 81ab9f863957cb 4335664c6716fa 0 2 0.0 0 0 52 49 ... 0 3.443 0 0 1340.0 3 1543 0.8333 1343.443 False
259351 86910c38335c2f 2738398928d28c 7d2911e944bfaa 0 10 0.0 0 0 42 45 ... 0 0.000 0 0 1510.0 6 0 0.8646 7444.000 False
268747 a007734fbc6ebf 5bf702dfa1e5d4 ad6b5669d33a2c 0 5 0.0 0 0 48 43 ... 0 0.000 0 0 1968.0 9 0 0.8370 5816.000 False

5 rows × 31 columns

(115, 31)

дааа, явно что-то не так, убираем

In [36]:
data.drop(data[data['heals'] > 40].index, inplace=True)
In [37]:
data.shape
Out[37]:
(4444800, 31)

Мы удалили более 2000 игроков и исключили практически все аномалии из данных, неплохой старт, конечно же это не вся работа, которую надо проделать, но начало положено, за тобой Feature Engineering, подбор алгоритма и т.д.

Гуд лак