可视化非常棒。然而,很难形成良好的可视化。

此外,将这些可视化呈现给更多的观众需要花费时间和精力。

我们都知道如何制作Bar-Plots,Scatter Plots和Histograms,但我们并没有太注意美化它们。

这会伤害我们 – 我们与同行和经理的信誉。你现在感觉不到,但它发生了。

此外,我发现重用我的代码至关重要。我每次访问新数据集时都需要重新开始吗?一些可重复使用的图表,可以帮助我们找到有关数据FAST的信息。

在这篇文章中,我还将讨论3种很酷的可视化工具:

  • 与图形的分类相关,
  • Pairplots,
  • 使用Seaborn的Swarmplots和Graph Annotations。

简而言之,这篇文章是关于有用和可呈现的图表。


我将使用来自FIFA 19完整播放器数据集的数据来讨论kaggle  - 在最新版FIFA 19数据库中注册的每个玩家的详细属性。

由于数据集有很多列,因此我们只关注分类和连续列的子集。

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
# We dont Probably need the Gridlines. Do we? If yes comment this line
sns.set(style="ticks")
player_df = pd.read_csv("../input/data.csv")
numcols = [
 'Overall',
 'Potential',
'Crossing','Finishing',  'ShortPassing',  'Dribbling','LongPassing', 'BallControl', 'Acceleration',
       'SprintSpeed', 'Agility',  'Stamina',
 'Value','Wage']
catcols = ['Name','Club','Nationality','Preferred Foot','Position','Body Type']
# Subset the columns
player_df = player_df[numcols+ catcols]
# Few rows of data
player_df.head(5)
玩家数据
球员数据

这是一个格式很好的数据,但我们需要对Wage和Value列进行一些预处理(因为它们在Euro中并包含字符串),以使它们成为我们后续分析的数字。

def wage_split(x):
    try:
        return int(x.split("K")[0][1:])
    except:
        return 0
player_df['Wage'] = player_df['Wage'].apply(lambda x : wage_split(x))
def value_split(x):
    try:
        if 'M' in x:
            return float(x.split("M")[0][1:])
        elif 'K' in x:
            return float(x.split("K")[0][1:])/1000
    except:
        return 0
player_df['Value'] = player_df['Value'].apply(lambda x : value_split(x))

与图形的分类相关

简单来说,相关性是两个变量如何一起移动的度量。

例如,在现实世界中,收入和支出是正相关的。如果一个增加另一个也增加。

学业表现和视频游戏的使用是负相关的。增加一个预测另一个减少。

因此,如果我们的预测变量与我们的目标变量正相关或负相关,那么它是有价值的。

当我们试图理解我们的数据时,不同变量之间的相关性是一件非常好的事情。

我们可以轻松地使用Seaborn创建一个非常好的相关图。

corr = player_df.corr()
g = sns.heatmap(corr,  vmax=.3, center=0,
            square=True, linewidths=.5, cbar_kws={"shrink": .5}, annot=True, fmt='.2f', cmap='coolwarm')
sns.despine()
g.figure.set_size_inches(14,10)
    
plt.show()
所有的分类变量在哪里
所有的分类变量在哪里?

但是你注意到有什么问题吗?

是的,此图仅计算数列之间的相关性。

如果我的目标变量是或者怎么办?ClubPosition?

我希望能够在三种不同的情况下获得相关性,并且我们使用以下相关度量来计算这些:

1.数值变量

我们已经以Pearson的相关性的形式得到了这个,它是两个变量如何一起移动的度量。这个范围从[-1,1]

2.分类变量

我们将使用Cramer的V作为分类 – 分类案例。它是两个离散变量的相互关系,并与具有两个或更多个级别的变量一起使用。它是一个对称的度量,因为变量的顺序无关紧要。Cramer(A,B)== Cramer(B,A)。

例如:在我们的数据集,Club并且Nationality必须以某种方式相关。

让我们使用堆叠图检查这一点,这是理解分类变量和分类变量之间分配的绝佳方法。我们使用一部分数据,因为这些数据中有很多国籍和俱乐部。

我们只保留最好的团队(保持FC波尔图只是为了更加多样化的样本)和最常见的国籍。

保留最好的团队和国籍

俱乐部的偏好相当于国籍:了解前者对预测后者有很大帮助。

我们可以看出一名球员是否属于英格兰队,他更有可能在切尔西队或曼联队比赛,而不是在巴塞罗那队或拜仁慕尼黑队或波尔图队。

所以这里有一些信息。Cramer’s V捕获相同的信息。

如果所有俱乐部拥有来自各个国家的球员比例相同,那么Cramer的V就是0。

例如,如果每个俱乐部都喜欢单一国籍Cramer’s V == 1,那么所有英格兰球员都会在曼联,拜仁慕尼黑的全德国球员等等。

在所有其他情况下,其范围为[0,1]

3.数值和分类变量

我们将相关比率用于分类连续案例。

没有太多的数学,它是分散的衡量标准。

鉴于一个数字,我们可以找出它属于哪个类别?

例如:

假设我们的数据集中有两列:SprintSpeedPosition

  • GK: 58(De Gea),52(T。Courtois),58(M.Neuer),43(G。Buffon)
  • CB: 68(D。Godin),59(V。Kompany),73(S.Umtiti),75(M.Benatia)
  • ST: 91(C.Ronaldo),94(G.Bale),80(S.Aguero),76(R.Lewandowski)

正如您所看到的,这些数字可以预测它们所涉及的桶,因此相关比率很高。

如果我知道冲刺速度超过85,我肯定可以说这个玩家在ST玩。

该比率也在[0,1]的范围内


执行此操作的代码取自dython包。我不会在代码中写太多,你可以在我的Kaggle内核中找到它。最终结果如下:

player_df = player_df.fillna(0)
results = associations(player_df,nominal_columns=catcols,return_results=True)
分类与分类,分类与数字,数字与数字
分类与分类,分类与数字,数字与数字。更有趣。

不是很漂亮吗?

通过查看这些数据,我们可以了解足球。例如:

  • 球员的位置与运球能力高度相关。你不会在后面打梅西。对?
  • 与传球和球控制相比,价值与运球相关性更高。规则是始终传球。内马尔我在看着你。
  • 俱乐部和工资有很高的相关性。可以预料。
  • 身体类型和首选脚是高度相关的。这是否意味着如果你是精益,你很可能是左脚?没有多大意义。人们可以进一步调查。

此外,我们可以通过这个简单的图表找到这么多信息,这在没有分类变量的典型相关图中是不可见的。

我把它放在这里 人们可以更多地了解图表并找到更有意义的结果,但重点是这使得生活更容易找到模式。


Pairplots

虽然我谈了很多相关性,但这是一个变化无常的指标。

要理解我的意思,让我们看一个例子。

Anscombe的四重奏包括四个数据集,它们具有几乎相同的1的相关性,但具有非常不同的分布,并且在绘制时看起来非常不同。

Anscombe四重奏 - 相关性可能是善变的。
Anscombe四重奏 – 相关性可能是善变的。

因此,有时绘制相关数据变得至关重要。并单独查看分布。

现在我们的数据集中有很多列。将它们全部绘制成图形会非常费力。

不,这是一行代码。

filtered_player_df = player_df[(player_df['Club'].isin(['FC Barcelona', 'Paris Saint-Germain',
       'Manchester United', 'Manchester City', 'Chelsea', 'Real Madrid','FC Porto','FC Bayern München'])) & 
                      (player_df['Nationality'].isin(['England', 'Brazil', 'Argentina',
       'Brazil', 'Italy','Spain','Germany'])) 
                     ]
# Single line to create pairplot
g = sns.pairplot(filtered_player_df[['Value','SprintSpeed','Potential','Wage']])
可视化的展现数据

非常好。我们在这张图中可以看到这么多。

  • 工资和价值高度相关。
  • 大多数其他值也是相关的。然而,潜在与价值的趋势是不寻常的。我们可以看到当我们达到特定的潜在阈值时,价值如何呈指数级增长。此信息可能有助于建模。可以对潜力进行一些转换以使其更具相关性吗?

警告:没有分类列。

我们可以做得更好吗?我们永远都可以。

g = sns.pairplot(filtered_player_df[['Value','SprintSpeed','Potential','Wage','Club']],hue = 'Club')
加上颜色展现更多信息

更多信息。只需将hue参数添加为分类变量即可Club

  • 波尔图的工资分布过于偏向下方。
  • 我不认为波尔图球员的价值分布很大。波尔图的球员总是在寻找机会。
  • 看看很多粉红点(切尔西)如何在潜力与工资图上形成一个集群。切尔西有很多高潜力球员,工资较低。需要更多的关注。

我已经知道工资/价值子图中的一些要点。

工资500k的蓝点是梅西。此外,比梅西更有价值的橙色点是内马尔。

虽然这个hack仍然无法解决分类问题,但我有一些很酷的东西来研究分类变量分布。虽然个别。


SwarmPlots

如何查看分类数据和数值数据之间的关系?

进入图片Swarmplots,就像他们的名字一样。为每个类别绘制一组点,在y轴上稍微分散,以便更容易看到。

他们是我目前最喜欢绘制这种关系的人。

g = sns.swarmplot(y = "Club",
              x = 'Wage', 
              data = filtered_player_df,
              # Decrease the size of the points to avoid crowding 
              size = 7)
# remove the top and right line in graph
sns.despine()
g.figure.set_size_inches(14,10)
plt.show()
Swarmplot
Swarmplot …

为什么我不使用Boxplots?中位数在哪里?我能描绘一下吗?明显。在顶部覆盖条形图,我们有一个很好看的图形。

g = sns.boxplot(y = "Club",
              x = 'Wage', 
              data = filtered_player_df, whis=np.inf)
g = sns.swarmplot(y = "Club",
              x = 'Wage', 
              data = filtered_player_df,
              # Decrease the size of the points to avoid crowding 
              size = 7,color = 'black')
# remove the top and right line in graph
sns.despine()
g.figure.set_size_inches(12,8)
plt.show()
Swarmplot+Boxplot
Swarmplot + Boxplot,有趣

非常好。我们可以在图表上看到各个点,查看一些统计数据并明确地了解工资差异。

梅西是最右边的一点。但是,我不应该在图表下方的文字中告诉你。对?

该图将在演示文稿中进行。你的老板说。我想在这张图上写下梅西。进入图片注释

max_wage = filtered_player_df.Wage.max()
max_wage_player = filtered_player_df[(player_df['Wage'] == max_wage)]['Name'].values[0]
g = sns.boxplot(y = "Club",
              x = 'Wage', 
              data = filtered_player_df, whis=np.inf)
g = sns.swarmplot(y = "Club",
              x = 'Wage', 
              data = filtered_player_df,
              # Decrease the size of the points to avoid crowding 
              size = 7,color='black')
# remove the top and right line in graph
sns.despine()
# Annotate. xy for coordinate. max_wage is x and 0 is y. In this plot y ranges from 0 to 7 for each level
# xytext for coordinates of where I want to put my text
plt.annotate(s = max_wage_player,
             xy = (max_wage,0),
             xytext = (500,1), 
             # Shrink the arrow to avoid occlusion
             arrowprops = {'facecolor':'gray', 'width': 3, 'shrink': 0.03},
             backgroundcolor = 'white')
g.figure.set_size_inches(12,8)
plt.show()
带注释的统计信息和点群
带注释的统计信息和点群。在演讲中,我走了。
  • 在那里看波尔图。与如此小的工资预算的巨头竞争。
  • 真实和巴塞罗那的这么多高薪球员。
  • 曼彻斯特城的工资中位数最高。
  • 曼联和切尔西相信平等。许多球员聚集在大致相同的工资水平。
  • 我很高兴虽然内马尔比梅西更有价值,但梅西和内马尔的工资差别很大。

在这个疯狂的世界中,似乎是正常的。


结论

所以回顾一下,在这篇文章中,我们讨论了计算和读取不同变量类型之间的相关性,绘制数值数据之间的相关性以及使用Swarmplots绘制分类数据和数值数据。我喜欢我们如何在Seaborn中将图表元素叠加在一起。

此外,如果您想了解有关可视化的更多信息,我想提供一个关于数据可视化的优秀课程,并应用密歇根大学的绘图,这是一个非常好的数据科学专业化的一部分,本身就是Python。看看吧

原文转自towardsdatascience,原文地址