Python中Weibull分布三参数系数:同时优化还是分开优化?
Weibull参数系数优化方案选择问题
我需要优化Weibull PDF的scale、shape、location函数的系数,为此编写了两种Python实现方案,想请教哪种选择更合理?
方案一:同时优化所有参数系数
import numpy as np from scipy.optimize import minimize from scipy.stats import weibull_min num_sets = 7 shape_params = np.random.uniform(1.5, 9, num_sets) # shape parameter, k loc_params = np.random.uniform(10, 100, num_sets) # loc parameter, lambda scale_params = np.random.uniform(500, 1500, num_sets) # scale parameter, c # Operating conditions for 9 sets: temperature, PH value, humidity, CO2 concentration conditions = np.random.uniform([80, 6, 30, 400], [95, 8, 80, 600], (num_sets, 4)) # Define the functions for shape, loc, scale parameters def weibull_params(coeffs, conditions): shape = coeffs[0] + coeffs[1] * conditions[:,0] + coeffs[2] * conditions[:,1] + coeffs[3] * conditions[:,2] + coeffs[4] * conditions[:,3] loc = coeffs[5] + coeffs[6] * conditions[:,0] + coeffs[7] * conditions[:,1] + coeffs[8] * conditions[:,2] + coeffs[9] * conditions[:,3] scale = coeffs[10] + coeffs[11] * conditions[:,0] + coeffs[12] * conditions[:,1] + coeffs[13] * conditions[:,2] + coeffs[14] * conditions[:,3] return shape, loc, scale # Objective function to minimize def objective_function(coeffs, conditions, shape_params, loc_params, scale_params): shape, loc, scale = weibull_params(coeffs, conditions) error = np.sum((shape - shape_params)**2 + (loc - loc_params)**2 + (scale - scale_params)**2) return error initial_guess = np.random.uniform(0, 1, 15) result = minimize(objective_function, initial_guess, args=(conditions, shape_params, loc_params, scale_params), method='BFGS') optimized_coeffs = result.x # Calculate and print the optimized Weibull parameters optimized_shape, optimized_loc, optimized_scale = weibull_params(optimized_coeffs, conditions) print("\nOriginal Weibull Parameters:") print("Shape:", shape_params) print("Loc:", loc_params) print("Scale:", scale_params) print("\nOptimized Weibull Parameters:") print("Shape:", optimized_shape) print("Loc:", optimized_loc) print("Scale:", optimized_scale)
方案二:使用三个独立目标函数分别优化
import numpy as np from scipy.optimize import minimize from scipy.stats import weibull_min num_sets = 7 shape_params = np.random.uniform(1.5, 9, num_sets) # shape parameter, k loc_params = np.random.uniform(10, 100, num_sets) # loc parameter, lambda scale_params = np.random.uniform(500, 1500, num_sets) # scale parameter, c # Operating conditions for 9 sets: temperature, PH value, humidity, CO2 concentration conditions = np.random.uniform([80, 6, 30, 400], [95, 8, 80, 600], (num_sets, 4)) def weibull_params(coeffs, conditions): shape = coeffs[0] + coeffs[1] * conditions[:, 0] + coeffs[2] * conditions[:, 1] + coeffs[3] * conditions[:, 2] + coeffs[4] * conditions[:, 3] loc = coeffs[5] + coeffs[6] * conditions[:, 0] + coeffs[7] * conditions[:, 1] + coeffs[8] * conditions[:, 2] + coeffs[9] * conditions[:, 3] scale = coeffs[10] + coeffs[11] * conditions[:, 0] + coeffs[12] * conditions[:, 1] + coeffs[13] * conditions[:, 2] + coeffs[14] * conditions[:, 3] return shape, loc, scale def shape_objective(coeffs, conditions, shape_params): shape, _, _ = weibull_params(coeffs, conditions) error = np.sum((shape - shape_params) ** 2) return error def loc_objective(coeffs, conditions, loc_params): _, loc, _ = weibull_params(coeffs, conditions) error = np.sum((loc - loc_params) ** 2) return error def scale_objective(coeffs, conditions, scale_params): _, _, scale = weibull_params(coeffs, conditions) error = np.sum((scale - scale_params) ** 2) return error initial_guess = np.random.uniform(0, 1, 15) result_shape = minimize(shape_objective, initial_guess, args=(conditions, shape_params), method='BFGS') result_loc = minimize(loc_objective, initial_guess, args=(conditions, loc_params), method='BFGS') result_scale = minimize(scale_objective, initial_guess, args=(conditions, scale_params), method='BFGS') # Extract optimized coefficients from each result optimized_coeffs_shape = result_shape.x optimized_coeffs_loc = result_loc.x optimized_coeffs_scale = result_scale.x # Now you have optimized coefficients for each parameter optimized_shape, optimized_loc, optimized_scale = weibull_params(np.concatenate((optimized_coeffs_shape, optimized_coeffs_loc, optimized_coeffs_scale)), conditions) print("\nOriginal Weibull Parameters:") print("Shape:", shape_params) print("Loc:", loc_params) print("Scale:", scale_params) print("\nOptimized Weibull Parameters:") print("Shape:", optimized_shape) print("Loc:", optimized_loc) print("Scale:", optimized_scale)
你的判断是对的,同时优化所有参数系数的方案(方案一)更合理,原因如下:
- 参数关联性:Weibull分布的shape、loc、scale三个参数并非完全独立,它们共同决定了分布的整体形态。分开优化时,单个参数的最优解可能会破坏三者的内在联系,导致整体分布不符合实际逻辑;而同时优化能兼顾参数间的关联,得到全局更优的系数组合。
- 优化效率:方案一只需执行一次优化流程,计算量更小;方案二需要三次独立优化,不仅耗时更长,还可能因多次初始化导致结果不稳定。
- 结果一致性:方案二中存在明显的代码错误——
np.concatenate会把原本15维的系数变成45维,而weibull_params函数只接受15维输入,直接运行会报错。退一步说,即使修正拼接方式,三个独立优化的结果也可能在部分操作条件下出现参数组合冲突,而方案一的结果是统一优化得到的,能保证所有条件下参数组合的一致性。
内容的提问来源于stack exchange,提问作者newtopy
相关产品推荐
相关产品推荐

