分類

関連:
ロジスティック回帰

マルチラベル分類問題
 
 
 
非常に簡単な例をつくる.

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.linear_model import LogisticRegression


physics = np.random.randint(0, 100, size=1000)
economics = np.random.randint(0, 100, size=1000)
admit = np.where((physics + economics) >= 120, 'yes', 'no')
admit_bi = ((physics + economics) >= 120).astype(int)
sum_ = (physics+economics)

df = pd.DataFrame(
    {
        'physics': physics,
        'economics': economics,
        'sum': sum_,
        'admit': admit,
        'admit_bi': admit_bi
    }
)

sns.lmplot(x='physics', y='economics', hue='admit', data=df, fit_reg=False)

FireShot Capture 263 - JupyterLab Alpha Preview - http___localhost_8888_lab

合計120点以上で合格,それ未満は不合格というケース.
データ点が十分にあれば,プロットからみてとれるし,

df.loc[df['admit_bi']==1, 'sum'].min(), df.loc[df['admit_bi']==0, 'sum'].max()

(120, 119)

境界が合計120にあるというのがすぐ分かる.

分類境界を求める方法として有名なのは,ロジスティック回帰.

sns.regplot(x=sum_, y=admit_bi, logistic=True)

FireShot Capture 264 - JupyterLab Alpha Preview - http___localhost_8888_lab

statsmodelのlogisticはちょいちょいミスる.

clf = LogisticRegression(C=1e5)
clf.fit(df['sum'].reshape(-1, 1), df['admit_bi'])

# and plot the result
plt.figure(1, figsize=(8, 6))
plt.clf()
plt.scatter(sum_, admit_bi, color='black', zorder=20)
X_test = np.linspace(80, 200, 280)


def model(x):
    return 1 / (1 + np.exp(-x))
loss = model(X_test * clf.coef_ + clf.intercept_).ravel()
plt.plot(X_test, loss, color='red', linewidth=3)

FireShot Capture 265 - JupyterLab Alpha Preview - http___localhost_8888_lab

境界が120近辺にあることが分かる.

線をビシっと引けそうなので,LDAでも良いが,敢えてLDAを使う理由もないので,
ここではLinearSVCを用いて,2値平面を分ける決定境界を求める.

from sklearn.svm import LinearSVC

clf = LinearSVC(C=.1, fit_intercept = True, loss= 'hinge')
clf.fit(df[['physics', 'economics']], df['admit_bi'])

h = 1
x_min, x_max = df['physics'].min() - 2 * h, df['physics'].max() + 2 * h
y_min, y_max = df['economics'].min() - 2 * h, df['economics'].max() + 2 * h
x_0, x_1 = np.meshgrid(
    np.arange(x_min, x_max, h),
    np.arange(y_min, y_max, h)
)
Z = clf.predict(np.c_[x_0.ravel(), x_1.ravel()])
Z = Z.reshape(x_0.shape)

plt.contourf(x_0, x_1, Z, alpha=0.1)
plt.scatter(df['physics'], df['economics'], c=df['admit_bi'], alpha=0.3)

FireShot Capture 266 - JupyterLab Alpha Preview - http___localhost_8888_lab

うーん…….汚いグラフ……(´・ω・`)

plt.figure(figsize=(13, 10))
plt.contourf(x_0, x_1, Z, alpha=0.1)
plt.scatter(df['physics'], df['economics'], c=df['admit_bi'], cmap=sns.diverging_palette(240, 10, n=2, as_cmap=True))

FireShot Capture 267 - JupyterLab Alpha Preview - http___localhost_8888_lab

100 * clf.score(df[['physics', 'economics']], df['admit_bi'])

97.5

パラメータをTuningしなくてももう少し良いかと思ったけど,思ったより悪い.

やっぱり,LDAも試す.

from sklearn.discriminant_analysis import LinearDiscriminantAnalysis

lda = LinearDiscriminantAnalysis()
lda.fit(df[['physics', 'economics']], df['admit_bi'])

Z = lda.predict(np.c_[x_0.ravel(), x_1.ravel()])
Z = Z.reshape(x_0.shape)
plt.figure(figsize=(13, 10))
plt.contourf(x_0, x_1, Z, alpha=0.1)
plt.scatter(df['physics'], df['economics'], c=df['admit_bi'], cmap=sns.diverging_palette(240, 10, n=2, as_cmap=True))

FireShot Capture 268 - JupyterLab Alpha Preview - http___localhost_8888_lab

lda.score(df[['physics', 'economics']], df['admit_bi'])

0.999
 
 
 
せっかくなので.

・ランダムフォレスト

from sklearn.ensemble import RandomForestClassifier

rfc = RandomForestClassifier()
rfc.fit(df[['physics', 'economics']], df['admit_bi'])

Z = rfc.predict(np.c_[x_0.ravel(), x_1.ravel()])
Z = Z.reshape(x_0.shape)
plt.figure(figsize=(13, 10))
plt.contourf(x_0, x_1, Z, alpha=0.1)
plt.scatter(df['physics'], df['economics'], c=df['admit_bi'], cmap=sns.diverging_palette(240, 10, n=2, as_cmap=True))

FireShot Capture 269 - JupyterLab Alpha Preview - http___localhost_8888_lab

rfc.score(df[['physics', 'economics']], df['admit_bi'])

0.999

・SVC(kernel=’rbf’) + GridSearch

from sklearn import svm
from sklearn.grid_search import GridSearchCV


params = [
    {
        'kernel': ['rbf'], 
        'gamma': [2**i for i in range(-21, 20)],
        'C':[2**i for i in range(-11, 15)]
    }
]

svc = svm.SVC()
gscv = GridSearchCV(svc, params, cv=3, n_jobs=-1)
gscv.fit(df[['physics', 'economics']], df['admit_bi'])

print(gscv.best_estimator_)
print(gscv.best_score_)
print(gscv.best_params_)

svc = svm.SVC(**gscv.best_params_)
svc.fit(df[['physics', 'economics']], df['admit_bi'])

Z = svc.predict(np.c_[x_0.ravel(), x_1.ravel()])
Z = Z.reshape(x_0.shape)
plt.figure(figsize=(13, 10))
plt.contourf(x_0, x_1, Z, alpha=0.1)
plt.scatter(df['physics'], df['economics'], c=df['admit_bi'], cmap=sns.diverging_palette(240, 10, n=2, as_cmap=True))

SVC(C=16384, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape=’ovr’, degree=3, gamma=3.0517578125e-05,
kernel=’rbf’, max_iter=-1, probability=False, random_state=None,
shrinking=True, tol=0.001, verbose=False)
1.0
{‘C’: 16384, ‘gamma’: 3.0517578125e-05, ‘kernel’: ‘rbf’}

FireShot Capture 270 - JupyterLab Alpha Preview - http___localhost_8888_lab

svc.score(df[['physics', 'economics']], df['admit_bi'])

1.0

 
 
 

関連:
TensorFlowで線形分類器による分類

回帰モデル

SVC(kernel=’linear’)とLinearSVC

広告
カテゴリー: 未分類 パーマリンク

分類 への3件のフィードバック

  1. ピンバック: Sympyで線形システムを解く | 粉末@それは風のように (日記)

  2. ピンバック: shapeに注意 | 粉末@それは風のように (日記)

  3. ピンバック: 分離超平面を3Dプロット | 粉末@それは風のように (日記)

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中