切片項が付かない
そうです。切片項が付かないんです。何度コードを回してもエラーもないし、切片項もないんです。
背景
kaggleのコンペのために回帰分析で予測モデルを作っていたところ、statsmodels.OLS(train_y, train_X).fit()のところで、よくエラーが生じていました。
適用するデータには欠損値がないし、ダミー化もしている。処理も間違っていなさそうなのに、なんでじゃい!!とずっと困惑しておりました。
そこで、あることに気づいたのです。そうです。直前のtrain_X = statsmodels.add_constant(train_x)のところでtrain_Xに切片項'const'が加えられていないのです。
何回回しても付かない。なのにモデル作成時の方には'const'が付いている。モデル作成時と処理はほとんど変わらない。でもモデル当てはめ時のデータには'const'が付かない...。
ネットという大海を浮遊、もしくは森林をさまよっていた際に、とあるオアシス(記事)にたどり着きました。
そうです、「公式ドキュメント」です。
解説
まず、重回帰分析について簡単に御説明します。回帰分析とは、とあるデータの特徴について、そのばらつきから傾向を調べるために作られた手法です。要するに、バラバラになっている各データの全体像を説明できるような直線を探すのです。
この全体の傾向を表す直線の、y切片にあたる部分が「切片項」です。この直線は
y = α_1x_1 + α_2x_2 + ... + β
などと表されます。このβの部分が切片項です。
で、なぜこの切片項が付かないかというと、付かないんじゃなくてもともと付いていたんです。
は?と思われるかもしれませんが、とにかく、このstatsmodelsのadd_constant関数には、元々データに切片項が含まれていた場合どうするか、というところまで設定されていたのです。要するに、データのバラツキが原点から広がっていそうか(切片項が「0」)、すこし上の方の点から始まっているか(切片項が「存在する」)、みたいなことまで気にしていた、ということですかね。
has_constantという引数のデフォルトが'skip'になっていて、元々切片項を含むデータの場合は切片項'const'を加えない、という設定になっていたようです。それで、データによっては、モデル作成時には切片項が加えられて、予測したいデータを当てはめる際には加えられなくて、'const'の有無による列数の不一致でエラー、みたいなことになっていたようでした。
では、どうすればよいかというと、has_constant='add'とすればよいのです。これで、元々切片項を含むデータにもさらなる切片項'const'を加えるようになりました。また、元々切片項を含むかどうかを調べたい場合は、has_constant='raise'とすることで、切片項を含んでいる場合はエラーにより教えてくれるようになります。
import statsmodels.api as sm
# x = sm.add_constant(df, has_constant='raise') 既に切片項を持っている場合は、エラーを出す
x = sm.add_constant(df, has_constant='add') # 既に切片項を持っていても、さらに切片項を加える
まとめ
というわけで、statsmodelsの設定をデフォルトから変更すればよい、というだけの話でした。そもそも、元々切片項があるものにさらに切片項を加えてよいのか、元々切片項がないものとあるものに対して同じモデルを適用してよいのか、という疑問が残りますが、調べる限りでは、決定係数の性質に違いをもたらすわけではなく、複数モデルの比較時やモデルの当てはめ方を見る際に注意した方が良い、という程度でした。定数項自体は、除かないほうが良い、という研究論文もありました。
現時点では、どちらの場合も切片項を加える設定にすることが最善の対処法と考えていますが、もしこの辺りの事情にお詳しい方がいらっしゃいましたら、御教示いただけると幸いです。それではまたごきげんよう~。