2017-11-09 6 views
3

この質問は、Python 3の統計モデルとその一般的な線形モデルクラスに関するものです。このコンバージェンスエラーを修正するにはどうすればよいですか? 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をどのようにして収束させるのですか?代わりがありますか?

答えて

3

Tweedie分布のフィッティングパラメータは簡単ではないようです。実際には、パラメータwは、すべての観測値がx_iの場合にのみ有効です。つまり、enter image description hereです。そうでなければ、負の実数を非整数に昇格できないため、予測に使用される値は未定義です電力値。

したがって、ほとんどのオプティマイザでは、この関係はすべての反復で維持される必要があり、データに異なる桁の値が含まれている場合は特に維持するのが難しくなります。

はその後、私はこの問題に対処するには、2つの主要なソリューション

  • 最も簡単な1を参照してください。陽性であることが、あなたの係数wを強制します。あなたの場合のように、すべての観測値x_iが肯定的であれば、実行可能なセットにとどまります。これは、ニュートンソルバ例えば、コールバックを使用して行うことができる。

    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) 
    

    これは、すべての時間を収束するが、すべての係数が正された溶液に到達する、すなわち全く阻害効果はありません。

  • もう1つの解決策は、共役ソルバを調べることです。何らかの理由で、これらの制約をうけてパフォーマンスが向上します。これは、共役勾配"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:あなたのケースでは、あなたは以下の設定を試すことができます私は、トゥイーディー分布の専門家ではないが、私は同じ問題に直面しているディストリビューションのような他のポアソンに取り組んでいます。

+0

解決策の1つ(明日)を試して、それが機能することを確認する際に賞金を授与します。 –

関連する問題