|本文共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;
# 设置子图布局为2x2
fig, 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】,即可获取完整的代码及示例数据!(数据仅用于演示,不存在合理性)
喜欢也行,不喜欢也行;如果觉得有用处的话,还请点点右下角的赞/在看,记得关注我哟!