【问题标题】:How do I fix this convergence error? Python 3 statsmodels如何解决此收敛错误? Python 3 统计模型
【发布时间】:2018-04-22 14:47:34
【问题描述】:

这个问题与 Python 3 statsmodels 及其一般线性模型类有关。

每当我的内生变量有一个值数组,使得这些值之间的距离超过一个数量级时,GLM 不会收敛并引发异常。这是我的意思的一个编码示例。

import pandas as pd
import pyarrow.parquet as pq
import numpy as np
import statsmodels.api as sm
import matplotlib.pyplot as plt
import math 

col = ["a", \
       "b", \
       "c", \
       "d", \
       "e", \
       "f", \
       "g", \
       "h"]

df = pd.DataFrame(np.random.randint(low=1, high=100, size=(20, 8)), columns=col)
df["a"] = [0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01]
df2 = pd.DataFrame(np.random.randint(low=1, high=100, size=(20, 8)), columns=col)
df2["a"] = np.random.randint(low=10000, high=99999, size=(20, 1))
df3 = pd.DataFrame(np.random.randint(low=1, high=100, size=(20, 8)), columns=col)
df3["a"] = [0.01, \
            0.01, \
            0.01, \
            0.01, \
            0.01, \
            0.01, \
            np.random.randint(low=10000, high=99999), \
            0.01, \
            0.01, \
            0.01, \
            0.01, \
            0.01, \
            np.random.randint(low=10000, high=99999), \
            0.01, \
            0.01, \
            0.01, \
            0.01, \
            0.01, \
            0.01, \
            0.01]
try:
    actual = df[["a"]]

    fml1 = "a ~ log(b) + c + d + e + f + g"

    data1 = df[["b", "c", "d", "e", "f", "g"]]

    model = sm.GLM(actual, data1, formula=fml1, family=sm.families.Tweedie(link_power=1.1)).fit()
    model_pred = model.predict()
    print("SUCCESS")
except:
    print("FAILURE")
try:
    actual = df2[["a"]]

    fml1 = "a ~ log(b) + c + d + e + f + g"

    data1 = df2[["b", "c", "d", "e", "f", "g"]]

    model = sm.GLM(actual, data1, formula=fml1, family=sm.families.Tweedie(link_power=1.1)).fit()
    model_pred = model.predict()
    print("SUCCESS")
except:
    print("FAILURE")
try:
    actual = df3[["a"]]

    fml1 = "a ~ log(b) + c + d + e + f + g"

    data1 = df3[["b", "c", "d", "e", "f", "g"]]

    model = sm.GLM(actual, data1, formula=fml1, family=sm.families.Tweedie(link_power=1.1)).fit()
    model_pred = model.predict()
    print("SUCCESS")
except:
    print("FAILURE")

如果您运行此代码,您应该只在最后一组数据上获得异常。为什么是这样?如何让 GLM 收敛?有替代品吗?

【问题讨论】:

    标签: python pandas numpy matplotlib statsmodels


    【解决方案1】:

    Tweedie 分布的拟合参数似乎并不容易。实际上,一组参数 仅当所有观测值 点积的正性都得到验证时才有效,即,否则预测中使用的值未定义为负实数提升到非整数幂值。

    因此,在大多数优化器中,这种关系应在所有迭代中保持,并且很难保持,尤其是在数据包含不同数量级的值时。

    然后,我看到了解决这个问题的两个主要解决方案

    • 最简单的一个:强制您的系数 为正。与您的情况一样,所有观察结果 都是肯定的,您将保留在可行集中。这可以使用牛顿求解器和回调来完成,例如:

          model = sm.GLM(actual, data1, formula=fml1,
                         family=sm.families.Tweedie(link_power=1.1))
      
          def callback(x):
              x[x < 0] = 0
      
          result = model.fit(method='newton', disp=True, start_params=np.ones(6),
                             callback=callback)
      

      这每次都会收敛,但会达到所有系数都为正的解,即没有抑制作用。

    • 另一种解决方案可能是查看共轭求解器。由于某些原因,它们在这些约束下表现更好。这可以使用共轭梯度"cg" 和牛顿共轭梯度"ncg" 方法来完成。 他们可能不会每次都收敛,但很有可能会。您可以使用start_params 向量,但它不是一门精确的科学。在您的情况下,您可以尝试以下设置:

      model = sm.GLM(actual, data1, formula=fml1,
                     family=sm.families.Tweedie(link_power=1.1))
      result = model.fit(method='cg', disp=True, start_params=0.1 * np.ones(6))
      

    PS:我不是 Tweedie 发行版方面的专家,但我一直在研究其他类似 Poisson 的发行版,它们面临同样的问题。

    【讨论】:

    • 当我尝试其中一种解决方案(即明天)并验证它是否有效时,我将奖励您。
    猜你喜欢
    • 2016-05-05
    • 1970-01-01
    • 1970-01-01
    • 2016-01-25
    • 1970-01-01
    • 1970-01-01
    • 2013-06-21
    • 1970-01-01
    • 2021-02-10
    相关资源
    最近更新 更多