직무적성검사
인적성 수리 문제
Linear Regression을 통해 얻게되는 모델의 예측값은 연속적인 숫자값이 나옵니다.
만약 연속적인 숫자를 예측하는 것이 아니라 분류를 예측하려면 어떻게 해야할까요? 기존의 linear regression이 아닌 다른 방식을 사용하여야 합니다.
예를 들어 시험을 쳤을 경우 시험 결과로 Fail과 Pass로 분류될 수 있습니다.
결과가 Fail또는 Pass가 나오기 때문에 이진 분류(binary classification)라고 합니다.
이진 분류를 구현해보겠습니다.
import numpy as np
from sklearn import linear_model
import mglearn
import matplotlib.pyplot as plt
# 데이터 셋을 가지고 옵니다.
(x, y) = mglearn.datasets.make_forge()
# print(type(x)) # <class 'numpy.ndarray'>
# print(x.shape) # (26, 2)
# print(x) # [[ 9.96346605 4.59676542], [11.0329545 -0.16816717], ... ]
# print(type(y)) # <class 'numpy.ndarray'>
# print(y.shape) # (26,)
# print(y) # [1 0 1 0 0 1 1 0 1 1 1 1 0 0 1 1 1 0 0 1 0 0 0 0 1 0]
# 1열을 x축으로, 2열을 y축으로 좌표를 찍겠습니다.
mglearn.discrete_scatter(x[:,0], x[:,1], y)
# 모델을 만들고 학습합니다.
model = linear_model.LinearRegression()
model.fit(x[:,0].reshape(-1,1), x[:,1].reshape(-1,1))
# 1차 직선을 그립니다.
plt.plot(x[:,0], x[:,0] * model.coef_.ravel() + model.intercept_, color='r')
plt.show()
이것을 구현하기 위해서는 linear regression을 변형하여 logistic regression으로 구현할 수 있습니다.
logistic regression과 linear regression은 둘다 직선이 되는데 linear regression으로는 불가능할까요?
불가능한 이유는 linear regression은 linear하게 값이 증가하는 모델인데 반해 이진분류는 True 또는 False로 표현되기 때문입니다.
이진분류를 Linear Regression으로 구현해보겠습니다.
import numpy as np
from sklearn import linear_model
import matplotlib.pyplot as plt
x_data = np.array([1, 2, 5 ,8 ,10, 30]) # 공부시간
t_data = np.array([0, 0, 0, 1, 1, 1]) # 합격여부(0: Fail, 1:Pass)
# 모델을 만들고 학습시킵니다.
model = linear_model.LinearRegression()
model.fit(x_data.reshape(-1,1), t_data.reshape(-1,1))
# 예측합니다.
print(model.predict([[7]])) # [[0.41831972]] => 불합격인건가요..
# 그래프를 그려봅니다.
plt.scatter(x_data, t_data)
plt.plot(x_data, x_data * model.coef_.ravel() + model.intercept_, color='r')
plt.show()
이진분류는 확률값이 나옵니다. 0.5미만이면 False, 0.5 이상이면 True 이런식으로 판단하기 때문입니다.
하지만, 위의 그래프의 Linear Regression으로 모델을 만들면 0~1사이가 아닌 1.2의 확률값이 예측이 어려워집니다.
이를 해결하는 방법은 S모양의 sigmoid 함수입니다.
sigmoid 함수를 통해 구현된 모델이 생성되면 loss함수를 사용하여 오차를 구해야합니다. 이 또한 linear regression에서 사용했던 mse를 사용할 수는 없습니다. 왜냐하면 logistic regression model은 꼬불꼬불한 그래프가 그려지기 때문입니다. 이를 해결하기 위해서는 MSE대신 Cross Entropy를 사용할 수 있습니다. 이것은 기존의 linear regression에서 activation 과정을 추가하면 됩니다.
import numpy as np
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Flatten, Dense
from tensorflow.keras.optimizers import SGD
from sklearn import linear_model
x_data = np.arange(2,21,2).reshape(-1,1)
t_data = np.array([0,0,0,0,0,0,1,1,1,1]).reshape(-1,1)
# sklearn구현
sklearn_model = linear_model.LogisticRegression()
sklearn_model.fit(x_data, t_data.ravel())
# 13시간 공부하면 합격인가요 불합격인가요?
print(sklearn_model.predict([[13]])) # => 0 불합격으로 판별해요!
print(sklearn_model.predict_proba([[13]])) # [[0.50009391 0.49990609]]
# Tensorflow keras 구현
keras_model = Sequential()
keras_model.add(Flatten(input_shape=(1,)))
keras_model.add(Dense(units=1, activation='sigmoid'))
keras_model.compile(optimizer=SGD(learning_rate=1e-3), loss='binary_crossentropy')
keras_model.fit(x_data, t_data, epochs=500, verbose=1)
print(keras_model.predict([[13]])) # [[0.6098874]]
이제 저희는 모델을 만들어보았으니 평가(Evaluation)을 해보아야 합니다. Linear Regression에서는 평가를 할때 skit-learn을 사용했었는데요. Logistic Regression에서는 다른 방법을 사용해야 합니다. Logistic Regression 모델을 평가하기 위해서는 평가 기준이 필요하고 이 기준은 여러개가 있습니다. Linear Regression과 같이 Training Data Set을 이용해서 평가를 진행하면 안됩니다.
데이터는 아래와 같이 Original Data Set을 Training Data, Validation Data, Test Data로 나눌 수 있습니다.
Overfitting을 피할 수 있는 방법은 무엇인가요?
Leave a comment