4種更快更簡單實現Python資料視覺化的方法!
熱力圖、二維密度圖、蜘蛛網圖和樹狀圖,這些視覺化方法你都用過嗎?
資料視覺化是 資料科學 或 機器學習 專案中十分重要的一環。通常,你需要在專案初期進行探索性的 資料分析 (EDA),從而對資料有一定的瞭解,而且建立視覺化確實可以使分析的任務更清晰、更容易理解,特別是對於大規模的高維資料集。在專案接近尾聲時,以一種清晰、簡潔而引人注目的方式展示最終結果也是非常重要的,讓你的受眾(通常是非技術人員的客戶)能夠理解。
讀者可能閱讀過我之前的文章「5 Quick and Easy Data Visualizations in Python with Code」,我通過那篇文章向大家介紹了 5 種基礎的資料視覺化方法:散點圖、線圖、直方圖、條形圖和箱形圖。這些都是簡單而強大的視覺化方法,通過它們你可以對資料集有深刻的認識。在本文中,我們將看到另外 4 個數據視覺化方法!本文對這些方法的介紹會更詳細一些,可以在您閱讀了上一篇文章中的基本方法之後接著使用,從而從資料中提取出更深入的資訊。+
進群:960410445 即可獲取數十套PDF哦!
熱力圖
熱力圖(Heat Map)是資料的一種矩陣表示方法,其中每個矩陣元素的值通過一種顏色表示。不同的顏色代表不同的值,通過矩陣的索引將需要被對比的兩項或兩個特徵關聯在一起。熱力圖非常適合於展示多個特徵變數之間的關係,因為你可以直接通過顏色知道該位置上的矩陣元素的大小。通過檢視熱力圖中的其他點,你還可以看到每種關係與資料集中的其它關係之間的比較。顏色是如此直觀,因此它為我們提供了一種非常簡單的資料解釋方式。
現在讓我們來看看實現程式碼。與「matplotlib」相比,「seaborn」可以被用於繪製更加高階的圖形,它通常需要更多的元件,例如多種顏色、圖形或變數。「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()
二維密度圖
二維密度圖(2D Density Plot)是一維版本密度圖的直觀擴充套件,相對於一維版本,其優點是能夠看到關於兩個變數的概率分佈。例如,在下面的二維密度圖中,右邊的刻度圖用顏色表示每個點的概率。我們的資料出現概率最大的地方(也就是資料點最集中的地方),似乎在 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」而非「seaborn」來建立視覺化結果。我們需要讓每個屬性沿圓周等距分佈。我們將在每個角上設定標籤,然後將值繪製為一個點,它到中心的距離取決於它的值/大小。最後,為了顯示更清晰,我們將使用半透明的顏色來填充將屬性點連線起來得到的線條所包圍的區域。
# 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()
樹狀圖
我們從小學就開始使用樹狀圖(Tree Diagram)了!樹狀圖是自然而直觀的,這使它們容易被解釋。直接相連的節點關係密切,而具有多個連線的節點則不太相似。在下面的視覺化結果中,我根據 Kaggle 的統計資料(生命值、攻擊力、防禦力、特殊攻擊、特殊防禦、速度)繪製了一小部分口袋妖怪遊戲的資料集的樹狀圖。
因此,統計意義上最匹配的口袋妖怪將被緊密地連線在一起。例如,在圖的頂部,阿柏怪 和尖嘴鳥是直接連線的,如果我們檢視資料,阿柏怪的總分為 438,尖嘴鳥則為 442,二者非常接近!但是如果我們看看拉達,我們可以看到其總得分為 413,這和阿柏怪、尖嘴鳥就具有較大差別了,所以它們在樹狀圖中是被分開的!當我們沿著樹往上移動時,綠色組的口袋妖怪彼此之間比它們和紅色組中的任何口袋妖怪都更相似,即使這裡並沒有直接的綠色的連線。
對於樹狀圖,我們實際上需要使用「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()