如何用熵值法计算栅格数据的权重【附代码】

文摘   科学   2024-04-02 08:30   重庆  

|本文共504字,阅读约需2分钟

1

熵值法

熵值法是一种用于确定多个指标权重的方法,它基于信息熵理论。该方法可以帮助我们在决策过程中对指标进行排序和加权,以便更准确地评估不同指标的重要性。
       熵是信息论中的一个概念,衡量了一个随机变量的不确定性。在熵值法中,通过将每个指标的取值视为一个随机变量,计算每个指标的信息熵来衡量该指标的不确定性。信息熵越高,表示该指标的取值越分散,不确定性越大。

熵值法计算公式如下:

2

所遇问题

        对于excel这一类的面板数据,熵值法的计算就很简单了,运用SPSS、excel这一类数据就可以计算,但面对GIS中以栅格数据为代表的空间数据,如何快速、简洁地进行计算则变得棘手。

        针对栅格数据,应把每一个栅格都作为样本进行看待,即需要将所有栅格数据矢量化,转为要素类,再进行计算。

如果一个区域太大,栅格数量较多,无疑是一个需要大量时间与算力的工作,但如果你和我一样是个懒🐕,则可以试试用代码进行读取计算。

3

算法演示

这里选取了4个指标进行熵值法的计算,分别是高程、坡度、NDVI和距道路距离。首先读取一下数据:

dem_data = read_raster('/home/mw/input/szf5345/ESP/dem.tif')road_data = read_raster('/home/mw/input/szf5345/ESP/road.tif')ndvi_data = read_raster('/home/mw/input/szf5345/ESP/ndvi.tif')slope_data = read_raster('/home/mw/input/szf5345/ESP/slope.tif')
import matplotlib.pyplot as plt;
# 设置子图布局为2x2fig, axs = plt.subplots(nrows=2, ncols=2, figsize=(10, 10))
# 可视化各图层axs[0, 0].imshow(dem_data, cmap='terrain', vmin=dem_data.min(), vmax=dem_data.max())axs[0, 0].set_title('DEM')
axs[0, 1].imshow(road_data, cmap='gray')  # 或选择适合道路数据的其他颜色映射axs[0, 1].set_title('Road')
axs[1, 0].imshow(ndvi_data, cmap='RdYlGn')  # NDVI通常使用红绿渐变的颜色映射axs[1, 0].set_title('NDVI')
axs[1, 1].imshow(slope_data, cmap='PuBuGn')  # 坡度数据可以使用蓝色到棕色的颜色映射axs[1, 1].set_title('Slope')
plt.tight_layout()plt.show()

定义函数进行计算:

def entropy(weights):    total = np.sum(weights)    if total == 0:        return 0    # 避免对0或接近0的值进行对数运算    normalized_weights = weights / total    normalized_weights[normalized_weights == 0] = 1e-11  # 设置一个极小值替代接近0的值    entropy = -np.sum(normalized_weights * np.log2(normalized_weights))    return entropy
def entropy_weight(data):    """    通过熵权法确定权重    :param data: 数据数组,每一行代表一个样本,每一列代表一个指标    :return: 权重数组    """    num_samples, num_indicators = data.shape    entropies = np.zeros(num_indicators)    weights = np.zeros(num_indicators)
   # 检查数据的有效性    valid_columns = np.logical_not(np.isnan(data).all(axis=0))
   # 计算每个指标的信息熵    for i in range(num_indicators):        if valid_columns[i]:            entropies[i] = entropy(data[:, i])            print(f"指标 {i+1} 的信息熵:", entropies[i])
   # 计算每个指标的权重    total_entropy = np.sum(entropies)    valid_entropies = entropies[valid_columns]    for i, entropy_value in enumerate(valid_entropies):        weights[i] = (total_entropy - entropy_value) / total_entropy
   # 归一化权重    weights /= np.sum(weights)
   return weights
# 读取栅格数据,并处理空值def read_raster(file_path):    with rasterio.open(file_path) as src:        data = src.read(1, masked=True).astype(float)  # 读取数据并转换为浮点数类型        return data

权重计算:

# 归一化数据def normalize(data):    min_val = np.nanmin(data)    max_val = np.nanmax(data)    return (data - min_val) / (max_val - min_val)
dem_normalized = normalize(dem_data)road_normalized = normalize(road_data)ndvi_normalized = normalize(ndvi_data)slope_normalized = normalize(slope_data)
# 将数据转换为一维数组,每个像素作为一个样本dem_flat = dem_normalized.flatten()ndvi_flat = ndvi_normalized.flatten()road_flat = road_normalized.flatten()slope_flat = slope_normalized.flatten()
# 合并数据combined_data = np.column_stack((dem_flat, ndvi_flat, road_flat, slope_flat))
# 计算权重weights = entropy_weight(combined_data)print("权重:", weights)

权重结果计算如下:






4

完整代码

公众号后台回复【240402】,即可获取完整的代码及示例数据!(数据仅用于演示,不存在合理性)


喜欢也行,不喜欢也行;如果觉得有用处的话,还请点点右下角的赞/在看,记得关注我哟!

遥感地理阁
专注于地理学、遥感科学、人工智能等领域,合作交流、成果分享等事宜请加Y2theK