티스토리 뷰
로지스틱 회귀 (Logistic Regression)¶
- 로지스틱 회귀는 LinearSVM 과 같이 각 클래스를 직선 또는 평면 으로 가른다.
- 시그모이드 함수는 계단함수를 표현하기 위함. 스위치 개념. 확률을 알려주는 함수
회귀함수를 구하여 시그모이드 함수에 대입> 분류하는데 많이 이용되지만 회귀라고 불리우는 이유
In [2]:
import numpy as np
import matplotlib.pyplot as plt
In [3]:
from sklearn.datasets import make_blobs
X, y = make_blobs(400, 2, [[0,0],[5,5]], [2,3])
plt.scatter(X[:,0], X[:,1], c=y, s=60, alpha=0.3)
plt.colorbar()
plt.title('make_blobs() - 400 samples')
Out[3]:
In [16]:
%%time
from sklearn.linear_model import LogisticRegression
model = LogisticRegression()
model.fit(X, y)
score = model.score(X, y)
score
In [5]:
display(model.coef_, model.intercept_)
In [6]:
import mglearn
plt.figure(figsize=[8,6])
mglearn.plots.plot_2d_classification(model, X, cm='Reds', alpha=0.3)
mglearn.discrete_scatter(X[:,0], X[:,1], y)
Out[6]:
LinearSVM 적용¶
In [15]:
%%time
from sklearn.svm import LinearSVC
model = LinearSVC(C=1)
model.fit(X, y)
score = model.score(X, y)
print(score)
In [14]:
display(model.coef_, model.intercept_)
위에 구한 기울기와 달라보이지만 ax+by+c=0에서 a와 b의 비율이 중요한 것이므로 기울기는 유사하다고 볼 수 있다.
In [9]:
import mglearn
plt.figure(figsize=[8,6])
mglearn.plots.plot_2d_classification(model, X, eps=0.5, cm='spring')
mglearn.discrete_scatter(X[:,0], X[:,1],y)
Out[9]:
In [14]:
def sigmoid(x):
return 1/(1+np.exp(-x))
In [16]:
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure(figsize=[10,8])
ax = Axes3D(fig)
a = np.arange(-4,12,0.2)
b = np.arange(-4,12,0.2)
xx, yy = np.meshgrid(a,b)
ax.plot_surface(xx, yy, model.coef_[0,0]*xx + model.coef_[0,1]*yy + model.intercept_[0],
shade=True, alpha=0.1, color='b')
ax.plot_wireframe(xx, yy, model.coef_[0,0]*xx + model.coef_[0,1]*yy + model.intercept_[0],
rstride=2, cstride=2, color='0.5')
ax.scatter(X[:,0], X[:,1], y, c=y, s=60)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('target')
ax.view_init(60, 70)
In [17]:
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = Axes3D(fig)
a = np.arange(-4, 12, 0.2)
b = np.arange(-4, 12, 0.2)
xx, yy = np.meshgrid(a,b)
ax.plot_surface(xx, yy, xx + yy, alpha=0.1)
ax.scatter(X[:,0], X[:,1], y, c=y, s=60)
Out[17]:
In [71]:
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure(figsize=[10,8])
ax = Axes3D(fig)
a = np.arange(-4,12,0.2)
b = np.arange(-4,12,0.2)
xx, yy = np.meshgrid(a,b)
ax.plot_surface(xx, yy, sigmoid(model.coef_[0,0]*xx + model.coef_[0,1]*yy + model.intercept_[0]),
shade=True, alpha=0.3, color='b')
ax.plot_wireframe(xx, yy, sigmoid(model.coef_[0,0]*xx + model.coef_[0,1]*yy + model.intercept_[0]),
rstride=2, cstride=2, color='0.5')
ax.scatter(X[:,0], X[:,1], y, c=y, s=60)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('target')
ax.view_init(20, -80)
pridict_proba를 사용하면 각 속성에 속할 확률을 알려준다.
In [74]:
display(model.predict_proba(X)[:10], y[:10])
In [77]:
model.decision_function(X)[:10]
Out[77]:
클래스가 3개인 경우¶
In [20]:
from sklearn.datasets import make_blobs
X, y = make_blobs(300, 2, [[0,0],[-10,10],[10,10]], [1,3,5])
# 300: 각 샘플개수, 2는 속성(축)개수, [0,0]과 [-10,10], [10, 10]를 중심으로 한다.
# 각각 표준편차가 1, 2 이다.
plt.scatter(X[:,0], X[:,1], c=y, alpha=0.5)
plt.colorbar()
Out[20]:
In [21]:
from sklearn.linear_model import LogisticRegression
model = LogisticRegression()
model.fit(X, y)
score = model.score(X, y)
score
Out[21]:
In [25]:
display(model.coef_, model.intercept_)
# 밑에 그림에서 Y자 모양 세 직선을 말하는게 아니라 점선 3개의 기울기와 y절편을 의미
# w0 + w1x1 + w2x2 = 0
In [23]:
import mglearn
plt.figure(figsize=[10,8])
mglearn.plots.plot_2d_classification(model, X, cm='Reds', alpha=0.3)
mglearn.discrete_scatter(X[:,0], X[:,1], y)
Out[23]:
In [29]:
plt.figure(figsize=[10,8])
mglearn.plots.plot_2d_classification(model, X, cm='spring', alpha=0.3)
mglearn.discrete_scatter(X[:,0], X[:,1], y)
w=model.coef_
b=model.intercept_
rng = np.array([X[:,0].min(), X[:,0].max()])
for i in range(3):
plt.plot(rng, -(w[i,0]*rng + b[i])/w[i,1], ':', lw=4)
# 점선 3개는 실제로 시그모이드 평면 3개이다.
In [88]:
display(model.predict_proba(X)[:10], y[:10])
# 3개가 나오는 이유는 클래스 각각에 대해서 포함 될 수 있는 확률을 의미한다.
# 이 숫자를 보고 그림이 그려진 이유를 파악할 수 있다.
In [36]:
9.08637445e-01+ 8.79690768e-03+ 8.25656473e-02
Out[36]:
In [89]:
model.decision_function(X)[:10]
Out[89]:
Iris 데이터 - 속성 2개로 제한¶
In [90]:
from sklearn.datasets import load_iris
iris = load_iris()
col1 = 0
col2 = 1
X = iris.data[:, [col1,col2]]
y = iris.target
X.shape, y.shape
Out[90]:
In [92]:
plt.scatter(X[:,0], X[:,1], c=y, s=60)
plt.colorbar()
Out[92]:
In [93]:
from sklearn.linear_model import LogisticRegression
model = LogisticRegression()
model.fit(X, y)
score = model.score(X, y)
score
Out[93]:
In [94]:
display(model.coef_, model.intercept_)
In [95]:
import mglearn
plt.figure(figsize=[10,8])
mglearn.plots.plot_2d_classification(model, X, cm='Reds', alpha=0.3)
mglearn.discrete_scatter(X[:,0], X[:,1], y)
Out[95]:
In [96]:
plt.figure(figsize=[10,8])
mglearn.plots.plot_2d_classification(model, X, cm='Reds', alpha=0.3)
mglearn.discrete_scatter(X[:,0], X[:,1], y)
rng = np.array([X[:,0].min(), X[:,0].max()])
for i in range(3):
plt.plot(rng, -(model.coef_[i,0]*rng + model.intercept_[i])/model.coef_[i,1], ':', lw=4)
Iris 데이터 - 모든 속성 사용¶
In [43]:
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
iris = load_iris()
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target)
X_train.shape, X_test.shape
Out[43]:
In [44]:
from sklearn.linear_model import LogisticRegression
model = LogisticRegression()
model.fit(X_train, y_train)
score_train = model.score(X_train, y_train)
score_test = model.score(X_test, y_test)
print(score_train, score_test)
In [45]:
display(model.coef_, model.intercept_)
옵션(C) 변경 및 과적합 판단¶
In [46]:
Cs = [0.001, 0.01, 0.1, 1, 10, 100, 1000]
s1 = []
s2 = []
for c in Cs:
model = LogisticRegression(C=c)
model.fit(X_train, y_train)
score_train = model.score(X_train, y_train)
score_test = model.score(X_test, y_test)
s1.append(score_train)
s2.append(score_test)
plt.plot(s1,'bo:')
plt.plot(s2,'rs-')
plt.legend(['train','test'])
plt.xticks(range(len(Cs)),Cs)
plt.ylim(0,1)
plt.xlabel('C')
plt.ylabel('score')
Out[46]:
시그모이드(sigmoid) 함수 적용¶
In [109]:
plt.figure(figsize=[12,8])
for col in range(4):
plt.subplot(2,2,col+1)
plt.scatter(iris.data[:,col], iris.target + np.random.normal(0,0.03,size=len(y)), c=iris.target, s=30, alpha=0.3)
plt.yticks([0,1,2], ['Setosa', 'Versicolor', 'Virginica'], rotation=90)
plt.title(iris.feature_names[col], fontsize=15)
In [111]:
X = iris.data[:,[2]]
y = iris.target.copy(); y[y==2]=1
plt.scatter(X[:,0], y, c=y, s=30)
plt.colorbar()
Out[111]:
In [112]:
def sigmoid(t):
return 1/(1+np.exp(-t))
In [122]:
rng = np.arange(-5,5,0.1)
plt.plot(rng, sigmoid(rng))
plt.hlines([0,0.5,1],-5,5,linestyles='dotted')
plt.vlines([0],0,1,linestyles='dotted')
plt.title('Sigmoid')
Out[122]:
In [137]:
plt.scatter(X[:,0], y, c=y, s=30)
plt.colorbar()
rng = np.arange(1,7,0.1)
plt.plot(rng, sigmoid(2*(rng-2.5)), 'r--')
Out[137]:
In [126]:
model = LogisticRegression()
model.fit(X, y)
display(model.score(X, y), model.coef_, model.intercept_)
In [136]:
plt.scatter(X[:,0], y, c=y, s=30)
plt.colorbar()
rng = np.arange(1,7,0.1)
plt.plot(rng, sigmoid(model.coef_[0,0]*rng+model.intercept_[0]), 'r--')
plt.vlines([-model.intercept_[0]/model.coef_[0,0]],0,1,linestyles='dotted')
plt.text(3, 0.5, 'boundary = %.3f' % (-model.intercept_[0]/model.coef_[0,0]))
Out[136]:
관련 기술¶
- 공식
$$ sigmoid(t) = \frac{1}{1 + e^{-t}} $$
$$ t = w \cdot x + b $$
$$ sigmoid(t) = \frac{1}{1 + e^{-(w \cdot x + b)}} $$
$$ t = w_0 \cdot x_0 + w_1 \cdot x_1 + ... + b $$ - 소프트맥스(softmax) 함수
- 크로스 엔트로피 (cross entropy)
소프트 맥스 w1 , w2, w3 >>> R1 = e^w1/(e^w1+e^w2+e^w3), R1+R2+R3=1. 1로 맞춤
크로스 엔트로피 : 로지스틱에서 비용함수개념(로그랑 잘맞음)
'beginner > 파이썬 머신러닝 기초' 카테고리의 다른 글
지도학습 - kernel SVM (0) | 2019.03.07 |
---|---|
유방암 데이터 분석 (3) | 2019.03.05 |
지도학습 - LinearSVM_2 (0) | 2019.03.05 |
지도학습 - LinearSVM_1 (0) | 2019.03.05 |
1월 지하철 승하차 인원 분석 (0) | 2019.02.28 |