1. 前言
1.1 KDE簡(jiǎn)介
核密度估計(jì)(Kernel Density Estimation,簡(jiǎn)稱KDE)是用于估計(jì)連續(xù)隨機(jī)變量概率密度函數(shù)的非參數(shù)方法。它的工作原理是在每個(gè)數(shù)據(jù)點(diǎn)周圍放置一個(gè)“核”(通常是某種平滑的、對(duì)稱的函數(shù)),然后將這些核加起來,形成一個(gè)整體的估計(jì)。這可以被視為對(duì)直方圖的平滑,使得得到的密度函數(shù)更連續(xù)、更平滑。
KDE的主要組件是核函數(shù)和帶寬。核函數(shù)確定了每個(gè)數(shù)據(jù)點(diǎn)對(duì)估計(jì)的貢獻(xiàn)的形狀,而帶寬決定了核的寬度,影響估計(jì)的平滑程度。正確選擇這兩個(gè)組件對(duì)于獲得有意義的估計(jì)至關(guān)重要。
優(yōu)點(diǎn):
-
非參數(shù)性:KDE不假設(shè)數(shù)據(jù)遵循任何特定的概率分布,使其具有很高的靈活性,能夠適應(yīng)多種不同的數(shù)據(jù)形態(tài)。
-
平滑性:與傳統(tǒng)的直方圖相比,KDE提供的概率密度估計(jì)是平滑的,它可以揭示數(shù)據(jù)中的細(xì)微特征而不是粗糙的組塊。
-
數(shù)據(jù)探索:KDE對(duì)于初步的數(shù)據(jù)探索和可視化非常有用,可以幫助我們直觀地了解數(shù)據(jù)的分布和形狀。
-
核的選擇:KDE允許使用不同的核,例如高斯核、三角核等,這為不同的應(yīng)用和數(shù)據(jù)特點(diǎn)提供了選擇的靈活性。
缺點(diǎn):
-
計(jì)算復(fù)雜性:KDE的計(jì)算復(fù)雜性可以高,特別是當(dāng)數(shù)據(jù)集很大時(shí),因?yàn)樗枰紤]每個(gè)數(shù)據(jù)點(diǎn)與其他所有數(shù)據(jù)點(diǎn)的關(guān)系。
-
帶寬選擇:帶寬是KDE中最關(guān)鍵的參數(shù)。不合適的帶寬選擇可能導(dǎo)致估計(jì)過于嘈雜(過小的帶寬)或過于平滑(過大的帶寬)。盡管有帶寬選擇的方法,但它們通常需要額外的計(jì)算和調(diào)優(yōu)。
-
邊界問題:在數(shù)據(jù)分布的邊界附近,KDE可能不會(huì)提供良好的估計(jì)。這是因?yàn)樵谶吔绺浇?,核函?shù)可能會(huì)延伸到數(shù)據(jù)的實(shí)際范圍之外,導(dǎo)致邊界處的估計(jì)偏低。
-
高維數(shù)據(jù):隨著數(shù)據(jù)維度的增加,KDE面臨“維度災(zāi)難”。在高維空間中,數(shù)據(jù)點(diǎn)之間的距離變得相對(duì)更遠(yuǎn),這使得密度估計(jì)變得更加困難。
1.2 KDE應(yīng)用領(lǐng)域
核密度估計(jì)(KDE)是一種廣泛應(yīng)用的統(tǒng)計(jì)方法,它在多個(gè)領(lǐng)域都有其應(yīng)用。以下是一些KDE部分應(yīng)用領(lǐng)域的具體實(shí)例:
-
數(shù)據(jù)探索和可視化:
考慮一個(gè)電商網(wǎng)站,其中的產(chǎn)品有各種價(jià)格。為了了解大多數(shù)產(chǎn)品的價(jià)格范圍,數(shù)據(jù)分析師可以使用KDE來估計(jì)價(jià)格分布。這不僅能夠揭示價(jià)格的中心趨勢(shì),還可以揭示價(jià)格的多模態(tài)分布(例如,低端、中端和高端產(chǎn)品可能有明顯的價(jià)格聚類)。 -
異常檢測(cè):
在信用卡欺詐檢測(cè)中,可以使用KDE來估計(jì)正常的交易行為分布,例如交易金額和交易時(shí)間。然后,任何明顯偏離這個(gè)估計(jì)的交易都可能被標(biāo)記為可疑,然后進(jìn)一步進(jìn)行調(diào)查。 -
地理空間分析:
在城市治安管理中,警察部門可以利用KDE來分析報(bào)告的犯罪事件的地理位置,以確定犯罪的“熱點(diǎn)”地區(qū)。這可以幫助他們更有效地部署警力和資源。 -
圖像處理:
在醫(yī)學(xué)圖像分析中,KDE可以用于估計(jì)某一區(qū)域(如腫瘤)的像素強(qiáng)度分布。這有助于區(qū)分正常組織和異常組織,并可以用于自動(dòng)檢測(cè)和標(biāo)記潛在的問題區(qū)域。 -
生物信息學(xué):
考慮一項(xiàng)研究,旨在分析不同類型的細(xì)胞在特定環(huán)境下的基因表達(dá)。KDE可以用于估計(jì)特定基因在各種條件下的表達(dá)水平分布,從而幫助研究人員了解基因的激活和抑制模式。 -
市場(chǎng)研究:
一個(gè)汽車制造商想要了解其競(jìng)爭(zhēng)對(duì)手車型的價(jià)格分布。使用KDE,他們可以揭示市場(chǎng)上的價(jià)格段,并據(jù)此確定他們自己車型的定價(jià)策略。
2. diy數(shù)據(jù)集實(shí)戰(zhàn)演示
2.1 導(dǎo)入函數(shù)
import numpy as np
import matplotlib.pyplot as plt
from sklearn.neighbors import KernelDensity
from sklearn.model_selection import GridSearchCV
2.2 自定義數(shù)據(jù)
生成一個(gè)數(shù)據(jù)集,其中數(shù)據(jù)來自兩個(gè)不同的分布:一個(gè)對(duì)數(shù)正態(tài)分布和一個(gè)正態(tài)分布。兩個(gè)分布各生成1000個(gè)數(shù)據(jù)點(diǎn),并將這些數(shù)據(jù)點(diǎn)連接在一起:
- 對(duì)數(shù)正態(tài)分布使用均值0和標(biāo)準(zhǔn)差0.3。
- 正態(tài)分布使用均值3和標(biāo)準(zhǔn)差1。
def generate_data(rand=None):
if rand is None:
rand = np.random.RandomState()
dat1 = rand.lognormal(0, 0.3, 1000)
dat2 = rand.normal(3, 1, 1000)
x = np.concatenate((dat1, dat2))
return x
data = generate_data(np.random.RandomState(17))
data[:10]
# array([1.08641118, 0.57327576, 1.20583266, 1.41000519, 1.3650037 ,
# 1.76119346, 0.96704574, 0.89706191, 1.04561216, 0.876924 ])
2.3 可視化數(shù)據(jù)
- 展示數(shù)據(jù)點(diǎn)的順序和相對(duì)位置
- 展示數(shù)據(jù)的分布情況
x_train = generate_data()[:, np.newaxis]
fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(10, 5))
ax[0].scatter(np.arange(len(x_train)), x_train, c='red')
ax[0].set_xlabel('Sample no.')
ax[0].set_ylabel('Value')
ax[0].set_title('Scatter plot')
ax[1].hist(x_train, bins=50)
ax[1].set_title('Histogram')
fig.subplots_adjust(wspace=.3)
plt.show()
2.4 KDE建模
x_test = np.linspace(-1, 7, 2000)[:, np.newaxis]
model = KernelDensity().fit(x_train)
log_dens = model.score_samples(x_test)
plt.fill_between(x_test.ravel(), np.exp(log_dens), color='pink')
plt.show()
3. 參數(shù)探討
3.1 帶寬
帶寬(bandwidth)是核密度估計(jì)(KDE)中的一個(gè)關(guān)鍵參數(shù),它決定了估計(jì)的平滑程度。選擇合適的帶寬對(duì)于獲得有意義的密度估計(jì)至關(guān)重要。
bandwidths = [0.01, 0.05, 0.1, 0.5, 1, 4]
fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(10, 7))
for ax, b in zip(axes.ravel(), bandwidths):
kde_model = KernelDensity(kernel='gaussian', bandwidth=b).fit(x_train)
score = kde_model.score_samples(x_test)
ax.fill(x_test, np.exp(score), c='pink')
ax.set_title(f"h={b}")
fig.subplots_adjust(hspace=0.5, wspace=.3)
plt.show()
3.2 選擇最佳帶寬
常見的就這四種方法:
-
經(jīng)驗(yàn)法則:一些常見的方法,如Silverman’s rule,可以為一般情況提供一個(gè)好的起點(diǎn)。但這些方法可能不適用于所有數(shù)據(jù)集。
-
交叉驗(yàn)證:使用交叉驗(yàn)證選擇帶寬是一種常見方法。這涉及到將數(shù)據(jù)分成訓(xùn)練集和驗(yàn)證集,然后對(duì)于不同的帶寬值,使用訓(xùn)練集進(jìn)行擬合,并使用驗(yàn)證集計(jì)算對(duì)數(shù)似然評(píng)分。選擇使得評(píng)分最大化的帶寬值。
-
可視化:像您之前的代碼那樣,通過為不同的帶寬值繪制KDE,可以幫助直觀地選擇一個(gè)合適的帶寬。
-
數(shù)據(jù)的范圍和分辨率:帶寬的絕對(duì)值通常與數(shù)據(jù)的范圍和單位有關(guān)。例如,如果數(shù)據(jù)是以米為單位的距離測(cè)量值,那么0.01米的帶寬與100米的帶寬意味著完全不同的事情。
這里用的是交叉驗(yàn)證:
bandwidth = np.arange(0.05, 2, .05)
grid = GridSearchCV(KernelDensity(kernel='gaussian'), {'bandwidth': bandwidth})
grid.fit(x_train)
kde = grid.best_estimator_
log_dens = kde.score_samples(x_test)
plt.fill_between(x_test.ravel(), np.exp(log_dens), color='cyan')
plt.title('Optimal estimate with Gaussian kernel')
plt.show()
print(f"optimal bandwidth: {kde.bandwidth:.2f}")
# optimal bandwidth: 0.15
3.2 核函數(shù)
Kernel | Name | Description |
---|---|---|
cosine | 余弦 | 形狀類似于余弦曲線的一部分,平滑地從中心下降到零。 |
epanechnikov | Epanechnikov | 這是一個(gè)凸的、平滑的、有界的核,常被用作默認(rèn)核,因?yàn)樗谀承├碚撔再|(zhì)上優(yōu)于其他核。 |
exponential | 指數(shù) | 這是一個(gè)從中心點(diǎn)開始快速下降的核,類似于高斯核,但下降得更快。 |
gaussian | 高斯或正態(tài) | 這是最常用的核,其形狀是標(biāo)準(zhǔn)的正態(tài)分布曲線。它為數(shù)據(jù)點(diǎn)提供了平滑的、無界的權(quán)重。 |
linear | 線性 | 這是一個(gè)三角形的核,從中心線性下降到零。 |
tophat | 平頂帽 | 這是一個(gè)矩形的核,它在一個(gè)固定的范圍內(nèi)為數(shù)據(jù)點(diǎn)提供均勻的權(quán)重,然后突然下降到零。 |
吐槽一點(diǎn),“Epanechnikov” 核函數(shù)并沒有一個(gè)廣泛接受的中文名字。它是以俄羅斯統(tǒng)計(jì)學(xué)家Urii Epanechnikov的名字命名的。文獻(xiàn)常見被翻譯成 “埃潘尼克尼科夫” 核。
kernels = ['cosine', 'epanechnikov', 'exponential', 'gaussian', 'linear', 'tophat']
fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(10, 7))
x_range = np.arange(-2, 2, 0.1)[:, None]
for ax, k in zip(axes.ravel(), kernels):
kde_model = KernelDensity(kernel=k).fit([[0]])
score = kde_model.score_samples(x_range)
ax.fill(x_range, np.exp(score), c='blue')
ax.set_title(k)
fig.subplots_adjust(hspace=0.5, wspace=.3)
plt.show()
3.4 挑選合適核函數(shù)
這里直接用剛剛的最佳帶寬0.15即可
def my_scores(estimator, X):
scores = estimator.score_samples(X)
scores = scores[scores != float('-inf')]
return np.mean(scores)
kernels = ['cosine', 'epanechnikov', 'exponential', 'gaussian', 'linear', 'tophat']
h_vals = np.arange(0.05, 1, .1)
fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(10, 7))
for ax, k in zip(axes.ravel(), kernels):
grid = GridSearchCV(KernelDensity(kernel=k), {'bandwidth': h_vals}, scoring=my_scores)
grid.fit(x_train)
kde = grid.best_estimator_
log_dens = kde.score_samples(x_test)
ax.fill(x_test.ravel(), np.exp(log_dens), c='cyan')
ax.set_title(f"{k} h={kde.bandwidth:.2f}")
fig.subplots_adjust(hspace=.5, wspace=.3)
plt.show()
還是用交叉驗(yàn)證:
grid = GridSearchCV(KernelDensity(),
{'bandwidth': h_vals, 'kernel': kernels},
scoring=my_scores)
grid.fit(x_train)
best_kde = grid.best_estimator_
log_dens = best_kde.score_samples(x_test)
plt.fill_between(x_test.ravel(), np.exp(log_dens), color='cyan')
plt.title(f"Best Kernel: {best_kde.kernel} h={best_kde.bandwidth:.2f}")
plt.show()
文章來源:http://www.zghlxwxcb.cn/news/detail-733664.html
4. 討論
核密度估計(jì)(KDE)是一種非參數(shù)方法,用于估計(jì)隨機(jī)變量的概率密度函數(shù)。通過在每個(gè)觀測(cè)數(shù)據(jù)點(diǎn)處放置一個(gè)核函數(shù)并將它們相加,KDE提供了數(shù)據(jù)的平滑估計(jì),可以捕捉數(shù)據(jù)的復(fù)雜分布特性,而不受特定參數(shù)分布的限制。文章來源地址http://www.zghlxwxcb.cn/news/detail-733664.html
到了這里,關(guān)于機(jī)器學(xué)習(xí)實(shí)戰(zhàn):Python基于KDE核密度估計(jì)進(jìn)行分布估計(jì)(十六)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!