物种分布的核密度估计

本例展示了如何使用基于邻居的查询(特别是核密度估计)来处理地理空间数据,使用基于Haversine距离度量的球面坐标。数据集由Phillips等人(2006年)提供。如果可用,示例将使用basemap来绘制南美洲的海岸线和国界。

本示例不执行数据上的任何学习(有关基于此数据集属性的分类示例,请参阅物种分布建模)。它仅显示了在地理坐标中观察到的数据点的核密度估计。这里涉及的两个物种是:

“Bradypus variegatus”,即棕喉树懒。这是一种生活在南美洲的哺乳动物,以其缓慢的动作和悠闲的生活方式而闻名。

“Microryzomys minutus”,也称为森林小稻鼠,是一种生活在秘鲁、哥伦比亚、厄瓜多尔和委内瑞拉的啮齿类动物。

在进行核密度估计之前,首先需要构建地图网格。这可以通过从数据集中获取的批量对象来完成。使用球面坐标来计算核密度估计,并从覆盖范围中绘制海岸线。

以下是实现这一过程的Python代码示例:

import matplotlib.pyplot as plt import numpy as np from sklearn.datasets import fetch_species_distributions from sklearn.neighbors import KernelDensity try: from mpl_toolkits.basemap import Basemap basemap = True except ImportError: basemap = False def construct_grids(batch): ""“构建地图网格”"" xmin = batch.x_left_lower_corner + batch.grid_size xmax = xmin + (batch.Nx * batch.grid_size) ymin = batch.y_left_lower_corner + batch.grid_size ymax = ymin + (batch.Ny * batch.grid_size) xgrid = np.arange(xmin, xmax, batch.grid_size) ygrid = np.arange(ymin, ymax, batch.grid_size) return xgrid, ygrid # 获取物种ID和位置的矩阵/数组 data = fetch_species_distributions() species_names = ["Bradypus Variegatus", "Microryzomys Minutus"] Xtrain = np.vstack([data["train"]["dd lat"], data["train"]["dd long"]]).T ytrain = np.array([d.decode("ascii").startswith("micro") for d in data["train"]["species"]], dtype="int") Xtrain *= np.pi / 180.0 # 将经纬度转换为弧度 # 为等高线图设置数据网格 xgrid, ygrid = construct_grids(data) X, Y = np.meshgrid(xgrid[::5], ygrid[::-1][::5]) land_reference = data.coverages[6][::5, ::5] land_mask = (land_reference > -9999).ravel() xy = np.vstack([Y.ravel(), X.ravel()]).T xy = xy[land_mask] xy *= np.pi / 180.0 # 绘制南美洲的地图和每个物种的分布 fig = plt.figure() fig.subplots_adjust(left=0.05, right=0.95, wspace=0.05) for i in range(2): plt.subplot(1, 2, i + 1) print("- 计算球面坐标中的KDE") kde = KernelDensity(bandwidth=0.04, metric="haversine", kernel="gaussian", algorithm="ball_tree") kde.fit(Xtrain[ytrain == i]) Z = np.full(land_mask.shape[0], -9999, dtype="int") Z[land_mask] = np.exp(kde.score_samples(xy)) Z = Z.reshape(X.shape) levels = np.linspace(0, Z.max(), 25) plt.contourf(X, Y, Z, levels=levels, cmap=plt.cm.Reds) if basemap: print("- 使用basemap绘制海岸线") m = Basemap(projection="cyl", llcrnrlat=Y.min(), urcrnrlat=Y.max(), llcrnrlon=X.min(), urcrnrlon=X.max(), resolution="c") m.drawcoastlines() m.drawcountries() else: print("- 从覆盖范围绘制海岸线") plt.contour(X, Y, land_reference, levels=[-9998], colors="k", linestyles="solid") plt.xticks([]) plt.yticks([]) plt.title(species_names[i]) plt.show()

这段代码首先导入了必要的库,然后定义了一个函数来构建地图网格。接着,它获取了物种ID和位置的数据,并将其转换为弧度。然后,它设置了一个数据网格,并使用核密度估计来计算每个物种的分布。最后,它绘制了南美洲的地图和每个物种的分布。

请注意,这个示例假设已经安装了所有必要的库,包括matplotlib、numpy、sklearn和basemap(如果可用)。如果没有安装basemap,代码将使用其他方法来绘制海岸线。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485