做者:xiaoyu
微信公衆號:Python數據科學
知乎:python數據分析師html
seaborn
的學習內容主要包含如下幾個部分:python
風格管理微信
繪圖方法app
數據集的分佈可視化
結構網格dom
本次將主要介紹數據集的分佈可視化
的使用。python2.7
當處理一個數據集的時候,咱們常常會想要先看看特徵變量是如何分佈的。這會讓咱們對數據特徵有個很好的初始認識,同時也會影響後續數據分析以及特徵工程的方法。本篇將會介紹如何使用 seaborn 的一些工具來檢測單變量和雙變量分佈狀況。函數
首先仍是先導入須要的模塊和數據集。工具
%matplotlib inline import numpy as np import pandas as pd from scipy import stats, integrate import matplotlib.pyplot as plt import seaborn as sns sns.set(color_codes=True) np.random.seed(sum(map(ord, "distributions")))
注意:這裏的數據集是隨機產生的分佈數據,由 numpy 生成,數據類型是ndarray。固然,pandas 的 Series 數據類型也是可使用的,好比咱們常常須要從 DataFrame 表中提取某一特徵(某一列)來查看分佈狀況。
在 seaborn 中,快速觀察單變量分佈的最方便的方法就是使用 distplot()
函數。默認會使用柱狀圖(histogram)來繪製,並提供一個適配的核密度估計(KDE)。學習
x = np.random.normal(size=100) sns.distplot(x);
直方圖是比較常見的,而且在 matplotlib 中已經存在了 hist
函數。直方圖在橫座標的數據值範圍內均等分的造成必定數量的數據段(bins),並在每一個數據段內用矩形條(bars)顯示y軸觀察數量的方式,完成了對的數據分佈的可視化展現。編碼
爲了說明這個,咱們能夠移除 kde plot,而後添加 rug plot(在每一個觀察點上的垂直小標籤)。固然,你也可使用 rug plot 自帶的 rugplot()
函數,可是也一樣能夠在 distplot
中實現:
sns.distplot(x, kde=False, rug=True);
當繪製直方圖時,你最須要肯定的參數是矩形條的數目以及如何放置它們。distplot()
使用了一個簡單的規則推測出默認狀況下最合適的數量,可是或多或少的對 bins 數量進行一些嘗試也許能找出數據的其它特徵:
sns.distplot(x, bins=20, kde=False, rug=True);
核密度估計可能不被你們所熟悉,但它對於繪製分佈的形狀是一個很是有用的工具。就像直方圖那樣,KDE plots 會在一個軸上經過高度沿着其它軸將觀察的密度編碼。
sns.distplot(x, hist=False, rug=True);
繪製 KDE 比繪製直方圖須要更多的計算。它的計算過程是這樣的,每一個觀察點首先都被以這個點爲中心的正態分佈曲線所替代。
x = np.random.normal(0, 1, size=30) bandwidth = 1.06 * x.std() * x.size ** (-1 / 5.) support = np.linspace(-4, 4, 200) kernels = [] for x_i in x: kernel = stats.norm(x_i, bandwidth).pdf(support) kernels.append(kernel) plt.plot(support, kernel, color="r") sns.rugplot(x, color=".2", linewidth=3);
而後,這些替代的曲線進行加和,並計算出在每一個點的密度值。最終生成的曲線被歸一化,以使得曲線下面包圍的面積是1。
density = np.sum(kernels, axis=0) density /= integrate.trapz(density, support) plt.plot(support, density);
咱們能夠看到,若是咱們使用 kdeplot()
函數,咱們能夠獲得相同的曲線。這個函數實際上也被 distplot()
所使用,可是若是你就只想要密度估計,那麼 kdeplot()
會提供一個直接的接口更簡單的操做其它選項。
sns.kdeplot(x, shade=True);
KDE 的帶寬參數(bw)控制着密度估計曲線的寬窄形狀,有點相似直方圖中的 bins 參數的做用。它對應着咱們上面繪製的 KDE 的寬度。默認狀況下,函數會按照一個通用的參考規則來估算出一個合適的值,可是嘗試更大或者更小也可能會有幫助:
sns.kdeplot(x) sns.kdeplot(x, bw=.2, label="bw: 0.2") sns.kdeplot(x, bw=2, label="bw: 2") plt.legend();
如上所述,高斯KDE過程的意味着估計延續了數據集中最大和最小的值。 能夠經過cut
參數來控制繪製曲線的極值值的距離; 然而,這隻影響曲線的繪製方式,而不是曲線如何擬合:
sns.kdeplot(x, shade=True, cut=0) sns.rugplot(x);
你也可使用distplot()
將參數分佈擬合到數據集,並可視化地評估其與觀察數據的對應程度:
x = np.random.gamma(6, size=200) sns.distplot(x, kde=False, fit=stats.gamma);
對於雙變量分佈的可視化也是很是有用的。在 seaborn 中最簡單的方法就是使用 joinplot()
函數,它可以建立一個多面板圖形來展現兩個變量之間的聯合關係,以及每一個軸上單變量的分佈狀況。
mean, cov = [0, 1], [(1, .5), (.5, 1)] data = np.random.multivariate_normal(mean, cov, 200) df = pd.DataFrame(data, columns=["x", "y"])
雙變量分佈最熟悉的可視化方法無疑是散點圖了,在散點圖中每一個觀察結果以x軸和y軸值所對應的點展現。你能夠用 matplotlib 的 plt.scatter
函數來繪製一個散點圖,它也是jointplot()
函數顯示的默認方式。
sns.jointplot(x="x", y="y", data=df)
直方圖 histogram
的雙變量相似圖被稱爲 「hexbin」 圖,由於它展現了落在六角形箱內的觀測量。這種繪圖對於相對大的數據集效果最好。它能夠經過 matplotlib 的 plt.hexbin
函數使用,也能夠做爲 jointplot
的一種類型參數使用。它使用白色背景的時候視覺效果最好。
x, y = np.random.multivariate_normal(mean, cov, 1000).T with sns.axes_style("white"): sns.jointplot(x=x, y=y, kind="hex", color="k");
還使用上面描述的核密度估計過程來可視化雙變量分佈。在 seaborn 中,這種繪圖以等高線圖展現,而且能夠做爲 jointplot()
的一種類型參數使用。
sns.jointplot(x="x", y="y", data=df, kind="kde");
你也能夠用 kdeplot
函數來繪製一個二維的核密度圖形。這能夠將這種繪圖繪製到一個特定的(可能已經存在的)matplotlib軸上,而jointplot()
函數只能管理本身:
f, ax = plt.subplots(figsize=(6, 6)) sns.kdeplot(df.x, df.y, ax=ax) sns.rugplot(df.x, color="g", ax=ax) sns.rugplot(df.y, vertical=True, ax=ax);
若是你但願讓雙變量密度看起來更連續,您能夠簡單地增長 n_levels 參數增長輪廓級數:
f, ax = plt.subplots(figsize=(6, 6)) cmap = sns.cubehelix_palette(as_cmap=True, dark=0, light=1, reverse=True) sns.kdeplot(df.x, df.y, cmap=cmap, n_levels=60, shade=True);
jointplot()
函數使用JointGrid
來管理圖形。爲了得到更多的靈活性,您可能須要直接使用JointGrid
繪製圖形。jointplot()
在繪製後返回JointGrid對象,你能夠用它來添加更多層或調整可視化的其餘方面:
g = sns.jointplot(x="x", y="y", data=df, kind="kde", color="m") g.plot_joint(plt.scatter, c="w", s=30, linewidth=1, marker="+") g.ax_joint.collections[0].set_alpha(0) g.set_axis_labels("$X$", "$Y$");
爲了繪製數據集中多個成對的雙變量,你可使用 pairplot()
函數。這建立了一個軸矩陣,並展現了在一個 DataFrame 中每對列的關係。默認狀況下,它也繪製每一個變量在對角軸上的單變量。
iris = sns.load_dataset("iris") sns.pairplot(iris);
就像 joinplot()
和 JoinGrid
之間的關係,pairplot()
函數創建在 PairGrid
對象之上,直接使用能夠更靈活。
g = sns.PairGrid(iris) g.map_diag(sns.kdeplot) g.map_offdiag(sns.kdeplot, cmap="Blues_d", n_levels=6); /Users/mwaskom/anaconda/lib/python2.7/site-packages/matplotlib/axes/_axes.py:545: UserWarning: No labelled objects found. Use label='...' kwarg on individual plots. warnings.warn("No labelled objects found. "
參考: http://seaborn.pydata.org/tut...
關注微信公衆號Python數據科學,獲取 120G
人工智能 學習資料。