我应该在Python脚本中同时优化威布尔分布函数的所有三个参数吗?

问题描述 投票:0回答:1

我想优化威布尔 PDF 的尺度、形状和位置函数的系数。

这是代码:

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)

我尝试了两种方法,我相信同时优化所有参数对我来说更有意义。

python mathematical-optimization scipy-optimize weibull
1个回答
0
投票

最好同时优化所有参数。

只要尝试并确保初始猜测相当接近最大峰值和正确的位置以及正确的比例,您就不会有太大困难。

如果您尝试一次只做一个,您可能会陷入从一侧弹到另一侧的对角山谷中。每次你单独改变一个参数时,它都无法移动很远,因为会撞到谷壁。

允许它使用参数的任何线性组合使拟合代码有机会找到最速下降的方向,从而更快地改善拟合。良好的拟合例程通常使用共轭梯度,选择下一个搜索方向与他们最近使用的方向正交。

© www.soinside.com 2019 - 2024. All rights reserved.