Spaces:
Running
Running
| """测试带偏置的幂律拟合功能""" | |
| import numpy as np | |
| from scipy.optimize import curve_fit | |
| def power_law_with_offset(x, a, b, c): | |
| """带偏置的幂律函数: y = a * x^b + c""" | |
| return a * np.power(x, b) + c | |
| def fit_power_law_with_offset(x_values, y_values): | |
| """ | |
| 使用带偏置的幂律拟合原始数据 | |
| 返回: (params, raw_rmse, log_rmse, fit_x, fit_y) | |
| """ | |
| x_arr = np.array(x_values) | |
| y_arr = np.array(y_values) | |
| # 初始参数估计 | |
| # 使用简单的幂律拟合作为初始值 | |
| log_x = np.log10(x_arr) | |
| log_y = np.log10(y_arr) | |
| slope, intercept = np.polyfit(log_x, log_y, 1) | |
| a_init = 10**intercept | |
| b_init = slope | |
| c_init = 0 # 偏置初始值设为0 | |
| try: | |
| # 使用curve_fit进行非线性拟合 | |
| params, _ = curve_fit( | |
| power_law_with_offset, | |
| x_arr, | |
| y_arr, | |
| p0=[a_init, b_init, c_init], | |
| maxfev=10000 | |
| ) | |
| a, b, c = params | |
| # 计算预测值 | |
| y_pred = power_law_with_offset(x_arr, a, b, c) | |
| # 计算原始空间 RMSE | |
| raw_rmse = np.sqrt(np.mean((y_arr - y_pred) ** 2)) | |
| # 计算对数空间 RMSE | |
| log_y_actual = np.log10(y_arr) | |
| log_y_pred = np.log10(y_pred) | |
| log_rmse = np.sqrt(np.mean((log_y_actual - log_y_pred) ** 2)) | |
| # 生成拟合曲线的点 | |
| x_min, x_max = min(x_values), max(x_values) | |
| fit_x = np.linspace(x_min * 0.8, x_max * 1.2, 100) | |
| fit_y = power_law_with_offset(fit_x, a, b, c) | |
| return params, raw_rmse, log_rmse, fit_x, fit_y | |
| except Exception as e: | |
| print(f"Fitting failed: {e}") | |
| # 如果拟合失败,返回简单幂律拟合结果 | |
| a = a_init | |
| b = b_init | |
| c = 0 | |
| params = (a, b, c) | |
| y_pred = a * np.power(x_arr, b) | |
| # 计算原始空间 RMSE | |
| raw_rmse = np.sqrt(np.mean((y_arr - y_pred) ** 2)) | |
| # 计算对数空间 RMSE | |
| log_y_actual = np.log10(y_arr) | |
| log_y_pred = np.log10(y_pred) | |
| log_rmse = np.sqrt(np.mean((log_y_actual - log_y_pred) ** 2)) | |
| x_min, x_max = min(x_values), max(x_values) | |
| fit_x = np.linspace(x_min * 0.8, x_max * 1.2, 100) | |
| fit_y = a * np.power(fit_x, b) | |
| return params, raw_rmse, log_rmse, fit_x, fit_y | |
| if __name__ == "__main__": | |
| # 测试数据:模拟一些模型参数和压缩率的关系 | |
| # 假设真实关系为 y = 50 * x^(-0.1) + 10 | |
| x_test = np.array([1, 3, 7, 13, 20, 30]) | |
| y_true = 50 * np.power(x_test, -0.1) + 10 | |
| # 添加一些噪声 | |
| np.random.seed(42) | |
| y_test = y_true + np.random.normal(0, 0.5, len(x_test)) | |
| print("测试数据:") | |
| print(f"x: {x_test}") | |
| print(f"y: {y_test}") | |
| print() | |
| # 进行拟合 | |
| params, raw_rmse, log_rmse, fit_x, fit_y = fit_power_law_with_offset(x_test.tolist(), y_test.tolist()) | |
| a, b, c = params | |
| print("拟合结果:") | |
| print(f"a = {a:.4f}") | |
| print(f"b = {b:.4f}") | |
| print(f"c = {c:.4f}") | |
| print(f"Raw RMSE = {raw_rmse:.4f}") | |
| print(f"Log-RMSE = {log_rmse:.4f}") | |
| print() | |
| print(f"拟合公式: y = {a:.2f} * x^{b:.3f} + {c:.2f}") | |
| print() | |
| print("真实参数: a=50, b=-0.1, c=10") | |
| print("拟合成功!" if raw_rmse < 2.0 else "拟合可能需要调整") | |