image.png
学习数据分析,熟悉pandas, numpy这两个数据分析必备武器,再利用seaborn画图,这个比matplpotlib更容易使用.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings("ignore")
train = pd.read_csv('../input/train.csv')
train.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4357336 entries, 0 to 4357335
Data columns (total 26 columns):
Id int64
groupId int64
matchId int64
assists int64
boosts int64
damageDealt float64
DBNOs int64
headshotKills int64
heals int64
killPlace int64
killPoints int64
kills int64
killStreaks int64
longestKill float64
maxPlace int64
numGroups 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(20)
memory usage: 864.3 MB
- groupId -用于标识匹配中的组的整数ID。 如果同一组玩家在不同的比赛中比赛,他们每次都会有不同的groupId
- matchId - 用于标识匹配的整数ID。 训练和测试集中都没有匹配项。
- assists - 伤害敌方数量,最后敌方被队友杀掉
- boosts - 使用的增强项数。
- damageDealt - 造成的总伤害。 注意:减去自己造成的伤害
- DBNOs - 击倒的敌人数量
- headshotKills - 爆头击毙的敌方玩家数量
- heals - 使用的治疗项目数
- killPlace - 在杀死的敌方玩家数量的比赛排名。
- killPoints - 基于杀戮的玩家外部排名. (把它想象成一个Elo排名只会杀死很重要)
- kills - 杀死的敌方玩家数量。
- killStreaks - 在很短的时间内杀死敌方玩家的最大数量
- longestKill - 玩家和玩家在死亡时被杀的最长距离. 这可能会产生误导,因为击倒一个玩家并且开走可能会导致最长的杀戮统计数据。
- maxPlace - 我们在比赛中的位置。 这可能与numGroups不匹配,因为有时数据会跳过展示位置.
- numGroups - 我们在比赛中有数据的组.
- revives -这名队员复活队友的次数.
- rideDistance - 以米为单位测量车辆总行驶距离
- roadKills -在车辆中的杀人次数
- swimDistance - 游泳的总距离以米为单位
- teamKills - 该玩家杀死队友的次数
- vehicleDestroys - 被摧毁的车辆数量
- walkDistance - 徒步旅行的总距离以米为单位
- weaponsAcquired - 拾取的武器数量
- winPoints - 基于赢的玩家外部排名。 (将此视为Elo排名,只有获胜才有意义。)
- winPlacePerc - 预测的目标。 这是一个百分位获胜位置,其中1对应于第一名,0对应于比赛中的最后一名。 它是根据maxPlace计算的,而不是numGroups,因此匹配中可能缺少块
train.head()
image.png
好了,现在我们已经看到了数据,让我们来探索一下。
杀人者
print("平均每一个人杀 {:.4f} 玩家, 一次杀{}个人就打败99% 玩家 , 杀人最多玩家一次杀了{}.".format(train['kills'].mean(),train['kills'].quantile(0.99), train['kills'].max()))
平均每一个人杀0.9345玩家, 一次杀7个人就打败99% 玩家 , 杀人最多玩家一次杀了60.
让我们描绘一下杀人数。
data = train.copy()
data.loc[data['kills'] > data['kills'].quantile(0.99)] = '8+'
plt.figure(figsize=(15,10))
sns.countplot(data['kills'].astype('str').sort_values())
plt.title("Kill Count",fontsize=15)
plt.show()
image.png
大多数人无法杀死一个人。 那么他们能造成伤害吗?
data = train.copy()
data = data[data['kills']==0]
plt.figure(figsize=(15,10))
plt.title("Damage Dealt by 0 killers",fontsize=15)
sns.distplot(data['damageDealt'])
plt.show()
image.png
好吧,大多数人都没有给别人造成伤害。 我们来研究一下例外情况。
print("{} 玩家 ({:.4f}%) 不用杀一个人就可以赢得比赛".format(len(data[data['winPlacePerc']==1]), 100*len(data[data['winPlacePerc']==1])/len(train)))
data1 = train[train['damageDealt'] == 0].copy()
print("{} 玩家 ({:.4f}%) 不用伤害任何人就可以躺赢比赛".format(len(data1[data1['winPlacePerc']==1]), 100*len(data1[data1['winPlacePerc']==1])/len(train)))
16722 玩家 (0.3838%) 不用杀一个人就可以赢得比赛
4262 玩家 (0.0978%) 不用伤害任何人就可以躺赢比赛
杀人数量和赢率排位关系
sns.jointplot(x="winPlacePerc", y="kills", data=train, height=10, ratio=3, color="r")
plt.show()
image.png
非常明显,杀人与获胜有关。 最后让我们根据杀人数量(0杀,1-2杀,3-5杀,6-10杀和10+杀)组成玩家。
kills = train.copy()
kills['killsCategories'] = pd.cut(kills['kills'], [-1, 0, 2, 5, 10, 60], labels=['0_kills','1-2_kills', '3-5_kills', '6-10_kills', '10+_kills'])
plt.figure(figsize=(15,8))
sns.boxplot(x="killsCategories", y="winPlacePerc", data=kills)
plt.show()
image.png
跑步者
image.png
print("平均每人走{:.1f}m, 走了{}m就可以击败99%的人, 而马拉松冠军走了 {}m.".format(train['walkDistance'].mean(), train['walkDistance'].quantile(0.99), train['walkDistance'].max()))
平均每人走1055.1m,走了4138.0m就可以击败99%的人,而马拉松冠军走了17300.0m。
data = train.copy()
data = data[data['walkDistance'] < train['walkDistance'].quantile(0.99)]
plt.figure(figsize=(15,10))
plt.title("Walking Distance Distribution",fontsize=15)
sns.distplot(data['walkDistance'])
plt.show()
image.png
print("{} 名玩家 ({:.4f}%) 走了0米. 这意味着他们落地成灰了或者他们是断线了(更有可能)".format(len(data[data['walkDistance'] == 0]), 100*len(data1[data1['walkDistance']==0])/len(train)))
94306名玩家(2.0581%)走了0米。 这意味着他们落地成灰了或者他们是断线了(更有可能)。
sns.jointplot(x="winPlacePerc", y="walkDistance", data=train, height=10, ratio=3, color="lime")
plt.show()
image.png
显然,步行与胜率有很高的相关性。走到最后的人,就是赢家!
治疗师
print("普通人使用 {:.1f} 次治疗项目, 使用{}次就超过99%的人, 而最厉害的救死扶伤者使用{}次.".format(train['heals'].mean(), train['heals'].quantile(0.99), train['heals'].max()))
print("普通人使用 {:.1f} 次增强物品, 使用{}次就超过99% 的人, 而有人最多使用{}次.".format(train['boosts'].mean(), train['boosts'].quantile(0.99), train['boosts'].max()))
普通人使用1.2次治疗项目,使用11.0次就超过99%的人,而最厉害的救死扶伤者使用59次.
普通人使用1.0次增强物品,使用7.0次就超过99%的人,而有人最多使用18次.
data = train.copy()
data = data[data['heals'] < data['heals'].quantile(0.99)]
data = data[data['boosts'] < data['boosts'].quantile(0.99)]
f,ax1 = plt.subplots(figsize =(20,10))
sns.pointplot(x='heals',y='winPlacePerc',data=data,color='lime',alpha=0.8)
sns.pointplot(x='boosts',y='winPlacePerc',data=data,color='blue',alpha=0.8)
plt.text(4,0.6,'Heals',color='lime',fontsize = 17,style = 'italic')
plt.text(4,0.55,'Boosts',color='blue',fontsize = 17,style = 'italic')
plt.xlabel('Number of heal/boost items',fontsize = 15,color='blue')
plt.ylabel('Win Percentage',fontsize = 15,color='blue')
plt.title('Heals vs Boosts',fontsize = 20,color='blue')
plt.grid()
plt.show()
image.png
sns.jointplot(x="winPlacePerc", y="heals", data=train, height=10, ratio=3, color="lime")
plt.show()
image.png
sns.jointplot(x="winPlacePerc", y="boosts", data=train, height=10, ratio=3, color="blue")
plt.show()
image.png
所以补血和增强物品,肯定与胜率相关.
在每个图中,当值为0时,存在异常行为。
单挑, 二人和组队
游戏中有3种游戏模式。 一个人可以单独作战,或与朋友(二人组),或与其他3个朋友(小队)一起玩。 100名玩家加入同一台服务器,因此在二人组的情况下,最大的队伍是50,而在小队的情况下,最大队伍是25。
solos = train[train['numGroups']>50]
duos = train[(train['numGroups']>25) & (train['numGroups']<=50)]
squads = train[train['numGroups']<=25]
print(" 有{} ({:.2f}%) 单人作战, {} 个({:.2f}%) 二人组队和 {} 个({:.2f}%) 三人或以上组队".format(len(solos), 100*len(solos)/len(train), len(duos), 100*len(duos)/len(train), len(squads), 100*len(squads)/len(train),))
有563279个(12.93%)单人作战, 3070150个(70.46%)二人组队和723907个(16.61%)三人或以上组队
f,ax1 = plt.subplots(figsize =(20,10))
sns.pointplot(x='kills',y='winPlacePerc',data=solos,color='black',alpha=0.8)
sns.pointplot(x='kills',y='winPlacePerc',data=duos,color='#CC0000',alpha=0.8)
sns.pointplot(x='kills',y='winPlacePerc',data=squads,color='#3399FF',alpha=0.8)
plt.text(37,0.6,'Solos',color='black',fontsize = 17,style = 'italic')
plt.text(37,0.55,'Duos',color='#CC0000',fontsize = 17,style = 'italic')
plt.text(37,0.5,'Squads',color='#3399FF',fontsize = 17,style = 'italic')
plt.xlabel('Number of kills',fontsize = 15,color='blue')
plt.ylabel('Win Percentage',fontsize = 15,color='blue')
plt.title('Solo vs Duo vs Squad Kills',fontsize = 20,color='blue')
plt.grid()
plt.show()
image.png
嗯,非常有趣. 一个人和二人组的表现相同,但是当打小队时杀人并不重要的参数。
变量之间的相关性
f,ax = plt.subplots(figsize=(15, 15))
sns.heatmap(train.corr(), annot=True, linewidths=.5, fmt= '.1f',ax=ax)
plt.show()
image.png
就目标变量(winPlacePerc)而言,存在一些高中高相关变量。 最高正相关是walkDistance,最高负相关killPlace。
让我们放大到与目标相关的前5个最正相关变量。
k = 5 #number of variables for heatmap
f,ax = plt.subplots(figsize=(11, 11))
cols = train.corr().nlargest(k, 'winPlacePerc')['winPlacePerc'].index
cm = np.corrcoef(train[cols].values.T)
sns.set(font_scale=1.25)
hm = sns.heatmap(cm, cbar=True, annot=True, square=True, fmt='.2f', annot_kws={'size': 10}, yticklabels=cols.values, xticklabels=cols.values)
plt.show()
image.png
游戏最多可以有100名玩家互相争斗。 但大多数时候游戏都不是“满员”。 没有变量可以为我们提供加入的玩家数量。 所以让我们创建一个。
train['playersJoined'] = train.groupby('matchId')['matchId'].transform('count')
data = train.copy()
data = data[data['playersJoined']>49]
plt.figure(figsize=(15,10))
sns.countplot(data['playersJoined'])
plt.title("Players Joined",fontsize=15)
plt.show()
image.png
有兴趣的朋友可以下载数据,自己玩一下
链接: https://pan.baidu.com/s/1wYYq4P67zhY87UiB8H8raA 提取码: mcqj