数据可视化是任何数据科学或机器学习项目的重要组成部分。我们通常会从探索性数据分析(EDA)开始,以获得对数据的一些见解,然后创建可视化,这确实有助于使事情更清晰,更容易理解,尤其是对于更大,更高维度的数据集。在项目即将结束时,能够以清晰,简洁和令人信服的方式呈现你的最终结果非常重要,只有这样,你的受众(通常是非技术客户)才能够理解。
我曾经写过一篇文章使用Python快速进行简单的数据可视化 ,其中我介绍了5个基本可视化:散点图,线图,直方图,条形图和箱线图。这些都是简单但功能强大的可视化,你可以使用它们洞察你的数据集。而在本文中,我将介绍另外4 个数据可视化!这些可视化将更精细的从你的数据中提取更深入的信息。
基础可视化:https://towardsdatascience.com/5-quick-and-easy-data-visualizations-in-python-with-code-a2284bae952f
热图是数据的矩阵表示,其中矩阵值用颜色来表示。不同的颜色代表不同的大小,矩阵索引将2个项目或特征链接在一起进行比较。热图非常适合显示多个特征变量之间的关系,因为你可以直接将值的大小视为不同的颜色。你还可以通过查看热图中的其他点来查看数据集中每种关系如何与的其他关系进行比较。由于它非常直观,因此颜色确实提供了简单而且直观的解释。
现在我们来看看代码。seaborn库可以用于绘制比matplotlib更高级的图,通常需要更多组件,如许多颜色,图形或变量。matplotlib用于显示图,numpy生成数据,pandas处理数据!绘图只是一个简单的seaborn功能,如果你认为某些东西特别好看,也可以设置颜色映射。
# Importing libs
import seaborn as sns
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# Create a random dataset
data = pd.DataFrame(np.random.random((10,6)), columns=["Iron Man","Captain America","Black Widow","Thor","Hulk", "Hawkeye"])
print(data)
# Plot the heatmap
heatmap_plot = sns.heatmap(data, center=0, cmap='gist_ncar')
plt.show()
二维密度图是一维密度图的简单扩展,相当于后者它的好处是能够看到关于2个变量的概率分布。我们来看看下面的二维密度图。右边的图例用颜色表示每个点的概率。概率最高,也就是我们数据的集中的地方,肉眼观察的话size大约为0.5,speed约为1.4。正如你现在所知,二维密度图非常适合快速识别我们的数据中两个变量最集中的位置,而一维密度图只能识别一个。当你有两个变量对你的输出非常重要并且你希望看到它们俩如何影响输出分布时,这个图非常有用。
它的seaborn的代码同样超级简单!这一次,我们将创建一个偏态分布。如果你发现某些颜色或阴影在视觉上效果更好,那么有非常多的可选参数都会使图看起来更清晰。
# Importing libs
import seaborn as sns
import matplotlib.pyplot as plt
from scipy.stats import skewnorm
# Create the data
speed = skewnorm.rvs(4, size=50)
size = skewnorm.rvs(4, size=50)
# Create and shor the 2D Density plot
ax = sns.kdeplot(speed, size, cmap="Reds", shade=False, bw=.15, cbar=True)
ax.set(xlabel='speed', ylabel='size')
plt.show()
蜘蛛图(spider plot)是展示一对多关系的最佳方式之一。也就是说,你可以绘制并查看几个变量相对于单个变量或类别的值。由于面积和长度在该特定方向上变大,在蜘蛛图中,一个变量相对于其他变量的突出成图十分明显,因为在那个特定的方向上,面积和长度变得更大。如果你想知道关于这些变量的几个类别是如何叠加的,你可以把它们并排画出来。在下图中,很容易比较复仇者(漫威英雄)的不同属性,看看他们的优势在哪里!(请注意,以下这些统计数据是随机设置的)
这次我们将可以直接使用matplotlib创建我们的可视化。我们需要计算每个属性所处的角度,因为我们希望它们沿着圆周长度相等。我们将标签放置在每个计算出的角度,然后将值绘制单个点,点距中心的距离取决于其值的大小。最后,为了清晰起见,我们使用半透明的颜色填充连接属性点的线所包围的区域。
# Import libs
import pandas as pd
import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt
# Get the data
df=pd.read_csv("avengers_data.csv")
print(df)
"""
# Name Attack Defense Speed Range Health
0 1 Iron Man 83 80 75 70 70
1 2 Captain America 60 62 63 80 80
2 3 Thor 80 82 83 100 100
3 3 Hulk 80 100 67 44 92
4 4 Black Widow 52 43 60 50 65
5 5 Hawkeye 58 64 58 80 65
"""
# Get the data for Iron Man
labels=np.array(["Attack","Defense","Speed","Range","Health"])
stats=df.loc[0,labels].values
# Make some calculations for the plot
angles=np.linspace(0, 2*np.pi, len(labels), endpoint=False)
stats=np.concatenate((stats,[stats[0]]))
angles=np.concatenate((angles,[angles[0]]))
# Plot stuff
fig = plt.figure()
ax = fig.add_subplot(111, polar=True)
ax.plot(angles, stats, 'o-', linewidth=2)
ax.fill(angles, stats, alpha=0.25)
ax.set_thetagrids(angles * 180/np.pi, labels)
ax.set_title([df.loc[0,"Name"]])
ax.grid(True)
plt.show()
从小学开始我们就一直在使用树形图!它们十分直观,易于理解。具有直接连接的节点具有紧密关系,而分开连接的节点则正好相反。在下面的可视化中,我绘制了kaggle一个数据集中统计数据的一部分,根据:
HP, Attack, Defense, Special Attack, Special Defense, Speed
因此,统计将最势均力敌的口袋妖怪紧密连接在一起。例如,我们看到在顶部,Arbok和Fearow(阿柏怪和大嘴雀)是直接连接的,如果我们检查数据,就会发现Arbok总分有438,而Fearow有442,非常接近!但到了Raticate(拉达),总分为413,与Arbok和Fearow完全不同,因此他们会被分开!当我们沿着树向上移动时,口袋妖怪越来越多地基于相似度进行分组。即使没有直接的绿线连接,绿线组中的神奇宝贝也会比红线组中的任何口袋妖怪更相似。
对于树形图,我们可以直接用Scipy!在我们的数据集中读取之后,我们将删除字符串列。在这里,这样做是为了直接实现可视化,但在实践中,将这些字符串转换为分类变量会获得更好的比较和结果。我们还设置了数据帧索引,以便我们可以正确地将其用作引用每个节点的列。最后,在Scipy中使用一行代码计算和绘制树!
# Import libs
import pandas as pd
from matplotlib import pyplot as plt
from scipy.cluster import hierarchy
import numpy as np
# Read in the dataset
# Drop any fields that are strings
# Only get the first 40 because this dataset is big
df = pd.read_csv('Pokemon.csv')
df = df.set_index('Name')
del df.index.name
df = df.drop(["Type 1", "Type 2", "Legendary"], axis=1)
df = df.head(n=40)
# Calculate the distance between each sample
Z = hierarchy.linkage(df, 'ward')
# Orientation our tree
hierarchy.dendrogram(Z, orientation="left", labels=df.index)
plt.show()