1

私はよく分離可能な非常に小さく簡単なデータセットでロジスティック回帰を実行します。しかし、モデルが最適な決定境界を見つけることができないことに気付きました。私のミスはどこですか?正則化項もあります - エラーがモデルを蹴るだけのものではありませんので、ロジスティック回帰は最適な決定境界を見つけません

import pandas as pd 
import seaborn as sns 
import matplotlib.pyplot as plt 
import numpy as np 
from sklearn import linear_model 

sm_df = pd.DataFrame() 
sm_df['x'] = [0.5,4.0,1.0,2.5,2.0,3.5,1.0,3.0, 1.0, 2.0] 
sm_df['y'] = [1.0,3.5,1.0,3.5,1.0, 4.5, 2.0,3.0, 0.0, 2.5] 
sm_df['Bad_data'] = [True, False, True, False, True, False, True, False, True, False] 

log = linear_model.LogisticRegression() 

log.fit(sm_df[['x','y']], sm_df['Bad_data']) 
test_score = log.score(sm_df[['x','y']], sm_df['Bad_data']) 
print("test score: ", test_score) 

# Create scatterplot of dataframe 
sns.lmplot('x', # Horizontal axis 
      'y', # Vertical axis 
      data=sm_df, # Data source 
      fit_reg=False, # Don't fix a regression line 
      hue="Bad_data", # Set color 
      scatter_kws={"marker": "D", # Set marker style 
         "s": 100}) # S marker size 

plt.xlabel('x') 
plt.ylabel('y') 

# to plot desision bountdary 
w0 = log.intercept_ 
w1, w2 = log.coef_[0] 

X = np.array([0,4]) 
x2 = np.array([-w0/w2, -w0/w2 -w1*4/w2]) 
plt.plot(X, x2) 
t_x = [1.5] 
t_y = [1.8] 
pr = log.predict([1.5,1.8]) 
plt.scatter(t_x, # Horizontal axis 
      t_y, c='r') # S marker size 
plt.annotate(pr, ([1.5,1.9])) 

my plot:

+0

のようなものでこれを行うことができます。 LogisticRegression)を '' liblinear ''から他のものへと変換します。 'log = linear_model.LogisticRegression(solver = 'newton-cg')' –

+1

実装上の理由から、デフォルトのソルバー 'liblinear'はインターセプトにペナルティを課しますが、それはお勧めできません。他のすべてのソルバは傍受にペナルティを課さず、正しい境界を与える必要があります。 – TomDLT

+0

興味深い。ありがとう@TomDLT。ちょっと、私は答えと一緒に上記のコメントの意味を把握しようとしました。 – sascha

答えて

1

理由があります。正規化項をもっと小さくすると、

log = linear_model.LogisticRegression(C=10.) 

となり、この例ではすべての点が正しく分類されます。これは、モデルがポイントを正確に分類することと、正規化については相対的に分類することのほうが相対的に重要になるためです。引数Cは正規化強度の逆数であり、デフォルトでは1です。

ここで必要なのは、データが標準化されていないことです。ロジスティック回帰を適用する前にデータを標準化すると(xとyの平均と分散が1になります)、C=1と完全にフィットします。あなたは、[既定のソルバー](http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html#sklearn.linear_modelを変更することができます

sm_df['x'] = (sm_df['x'] - sm_df['x'].mean())/sm_df['x'].std() 
sm_df['y'] = (sm_df['y'] - sm_df['y'].mean())/sm_df['y'].std() 
+0

ありがとう、ジェレミー!できます。十分に分離可能なデータセットがあるときは、正規化に注意を払う必要はありません。 –

+0

並べ替えデータが標準化されていないためにCを大きくしなければならない理由の1つは、モデルにはデータに合わせて大きな係数が必要です(正規化は大きな係数を失うことになります)。私はこれを反映するために私の答えを更新しました。もう1つの理由は、正規化の目的は、データの過剰適合を防ぐことです。基本的には、すべてのトレーニングデータを正しく取得するのは難しくありません(しかし、目に見えないデータの方が一般化する可能性があります)。 –

関連する問題