You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用SciPy curve_fit实现对数回归却拟合出直线的问题

问题原因与解决办法

核心问题

你用mdates.date2num(x)将日期转换为数值后,这类数值通常是极大的整数(比如代表从1970年起始的天数,动辄上万),对超大数值取对数后,相邻日期的log值差异极小,最终拟合曲线趋近于直线。另外,curve_fit默认初始参数[1,1]不适用于对数模型,容易导致拟合结果偏离预期。

解决步骤

1. 对日期x做缩放处理

将日期转换为相对天数(以数据中第一个日期为基准,计算后续日期与它的差值),缩小x的取值范围,让log(x)的变化更明显:

# 替换原x处理逻辑
x_days = (x - x.min()).dt.days + 1  # 加1避免出现log(0)的报错

2. 给curve_fit指定初始参数

手动设置初始参数p0,引导拟合算法找到更优解,而非依赖默认值:

log_popt, log_pcov = curve_fit(log_func, x_days, y, p0=[y.mean(), 1])

3. 修改后的完整代码

def plotVideoPerformance(df):
    plt.figure(figsize=(10,5))

    # Data Points
    x = df['period']
    # 确保period是datetime类型,非则先转换
    if not pd.api.types.is_datetime64_any_dtype(x):
        df['period'] = pd.to_datetime(df['period'])
        x = df['period']
    y = df['estimated_revenue_total']
    title = df['title'].unique()

    # 转换为相对天数,优化log计算的数值范围
    x_days = (x - x.min()).dt.days + 1

    # Regression Functions  
    def log_func(x,a,b):
        return a + b * np.log(x)    

    # 设置初始参数,提升拟合精度
    log_popt, log_pcov = curve_fit(log_func, x_days, y, p0=[y.mean(), 1])
    
    log_params = f"a=%.2f,b=%.2f" % tuple(log_popt)

    log_reg = log_func(x_days, *log_popt)

    plt.scatter(x, y)
    plt.plot(x, log_reg, 'b', label=log_params)
    plt.legend()
    plt.title(title[0])
    plt.show()

额外检查点

  • 若数据本身的趋势接近线性,对数回归结果自然会趋近直线,此时需重新评估模型是否匹配数据特征

内容的提问来源于stack exchange,提问作者JieudenCuben

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 21:38:11