8.8 直方圖长已,分箱和密度
原文:Histograms, Binnings, and Density
譯者:飛龍
協(xié)議:CC BY-NC-SA 4.0
本節(jié)是《Python 數(shù)據(jù)科學手冊》(Python Data Science Handbook)的摘錄。
簡單的直方圖可能是理解數(shù)據(jù)集的第一步灶轰。之前,我們預(yù)覽了 Matplotlib 直方圖函數(shù)(參見“比較,掩碼和布爾邏輯”)扔役,一旦執(zhí)行了常規(guī)的導(dǎo)入,它在一行中創(chuàng)建一個基本直方圖:
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('seaborn-white')
data = np.random.randn(1000)
plt.hist(data);
hist()
函數(shù)有很多調(diào)整計算和顯示的選項警医;這是一個更加自定義的直方圖的例子:
plt.hist(data, bins=30, normed=True, alpha=0.5,
histtype='stepfilled', color='steelblue',
edgecolor='none');
plt.hist
的文檔字符串提供了其他可用自定義選項的更多信息亿胸。我發(fā)現(xiàn)histtype='stepfilled'
和一些透明度alpha
的組合,在比較幾種分布的直方圖時非常有用:
x1 = np.random.normal(0, 0.8, 1000)
x2 = np.random.normal(-2, 1, 1000)
x3 = np.random.normal(3, 2, 1000)
kwargs = dict(histtype='stepfilled', alpha=0.3, normed=True, bins=40)
plt.hist(x1, **kwargs)
plt.hist(x2, **kwargs)
plt.hist(x3, **kwargs);
如果你想簡單地計算直方圖(也就是說预皇,計算給定桶中的點數(shù))而不顯示它侈玄,那么np.histogram()
函數(shù)是可用的:
counts, bin_edges = np.histogram(data, bins=5)
print(counts)
# [ 12 190 468 301 29]
二維直方圖和分箱
就像我們通過將數(shù)字放入桶中,創(chuàng)建一維直方圖一樣吟温,我們也可以通過將點放入通過二維的桶中序仙,來創(chuàng)建二維直方圖。我們將在這里簡要介紹幾種方法鲁豪。我們首先定義一些數(shù)據(jù) - 從多元高斯分布中抽取的x
和y
數(shù)組:
mean = [0, 0]
cov = [[1, 1], [1, 2]]
x, y = np.random.multivariate_normal(mean, cov, 10000).T
plt.hist2d
:二維直方圖
繪制二維直方圖的一種簡單方法是使用 Matplotlib 的plt.hist2d
函數(shù):
plt.hist2d(x, y, bins=30, cmap='Blues')
cb = plt.colorbar()
cb.set_label('counts in bin')
就像plt.hist
一樣潘悼,plt.hist2d
有許多微調(diào)繪圖和分箱的額外選項來,這在函數(shù)的文檔字符串中有很好的概述爬橡。此外治唤,正如plt.hist
在np.histogram
中存在對應(yīng),plt.hist2d
在np.histogram2d
中也存在對應(yīng)堤尾,可以按如下方式使用:
counts, xedges, yedges = np.histogram2d(x, y, bins=30)
對于維度大于 2 的直方圖分箱的推廣肝劲,請參閱np.histogramdd
函數(shù)。
plt.hexbin
:六邊形分箱
二維直方圖創(chuàng)建了橫跨坐標軸的正方形細分。這種細分的另一種自然形狀是正六邊形辞槐。為此掷漱,Matplotlib 提供了plt.hexbin
例程,它將表示在六邊形網(wǎng)格中分箱的二維數(shù)據(jù)集:
plt.hexbin(x, y, gridsize=30, cmap='Blues')
cb = plt.colorbar(label='count in bin')
plt.hexbin
有許多有趣的選項榄檬,包括為每個點指定權(quán)重卜范,以及將每個桶中的輸出更改為任何 NumPy 聚合(權(quán)重的平均值,權(quán)重的標準差等)鹿榜。
核密度估計
另一種評估多維密度的常用方法是核密度估計(KDE)海雪。這將在“深度:核密度估計”中全面討論,但是現(xiàn)在我們只是提到舱殿,KDE 可以被認為是“消去”空間中的點奥裸,并將結(jié)果相加來獲得平滑函數(shù)的一種方式。
scipy.stats
包中存在非郴ο快速和簡單的 KDE 實現(xiàn)湾宙。以下是在此數(shù)據(jù)上使用 KDE 的快速示例:
from scipy.stats import gaussian_kde
# 擬合大小為 [Ndim, Nsamples] 的數(shù)組
data = np.vstack([x, y])
kde = gaussian_kde(data)
# 在常規(guī)網(wǎng)格上評估
xgrid = np.linspace(-3.5, 3.5, 40)
ygrid = np.linspace(-6, 6, 40)
Xgrid, Ygrid = np.meshgrid(xgrid, ygrid)
Z = kde.evaluate(np.vstack([Xgrid.ravel(), Ygrid.ravel()]))
# 將結(jié)果繪制為圖像
plt.imshow(Z.reshape(Xgrid.shape),
origin='lower', aspect='auto',
extent=[-3.5, 3.5, -6, 6],
cmap='Blues')
cb = plt.colorbar()
cb.set_label("density")
KDE 具有平滑長度,可以在細節(jié)和平滑度之間有效地調(diào)整(無處不在的偏差 - 方差權(quán)衡的一個例子)冈绊。有關(guān)選擇合適的平滑長度的文獻非常多:gaussian_kde
使用經(jīng)驗法則侠鳄,試圖為輸入數(shù)據(jù)找到近似最佳的平滑長度。
SciPy 生態(tài)系統(tǒng)中提供了其他 KDE 實現(xiàn)死宣,每個實現(xiàn)都有自己的優(yōu)點和缺點伟恶;例如,參見sklearn.neighbors.KernelDensity
和statsmodels.nonparametric.kernel_density.KDEMultivariate
毅该。對于基于 KDE 的可視化博秫,使用 Matplotlib 往往過于冗長。在“可視化和 Seaborn”中討論的 Seaborn 庫鹃骂,提供了更為簡潔的 API 來創(chuàng)建基于 KDE 的可視化台盯。