逻辑回归——详解
本文翻译自 「towardsdatascience.com」,原文链接:
https://towardsdatascience.com/logistic-regression-detailed-overview-46c4da4303bc
逻辑回归在二十世纪初期被用在生物科学中,后来,它被应用于许多社会科学领域。我们可以在因变量(目标值)是分类值的情况下使用它。
比如,
- 预测一个邮件是否是垃圾邮件
- 判断肿瘤是否是恶性的
假设我们需要辨别垃圾邮件。如果使用线性回归,则需要根据可能的分类设置阈值。
如果结果实际上是恶性的,但预测值是0.4,而阈值是0.5,那么我们的到的结果会是非恶性的。
通过这个例子,我们会发现线性回归不适合分类问题。线性回归是无界限的,而逻辑回归的值域被严格限制为 0 到 1。
。。。上面这段在说啥啊歪果仁的思维搞不懂,难道是我翻译水平问题?
让我把原文贴出来:
Consider a scenario where we need to classify whether an email is spam or not. If we use linear regression for this problem, there is a need for setting up a threshold based on which classification can be done. Say if the actual class is malignant, predicted continuous value 0.4 and the threshold value is 0.5, the data point will be classified as not malignant which can lead to serious consequence in real time.
From this example, it can be inferred that linear regression is not suitable for classification problem. Linear regression is unbounded, and this brings logistic regression into picture. Their value strictly ranges from 0 to 1.
我的理解,逻辑回归并不是回归而是分类,是一种定性的分析,线性回归用来预测数值,是定量的,不适合用在分类上。
援引知乎上的一个例子:
预测明天的气温是多少度,属于回归问题。
预测明天是阴、晴还是雨,属于分类问题。
简单逻辑回归
模型
Output = 0 or 1
假设 Z = WX + B
hΘ(x) = sigmoid (Z)
Sigmoid 函数:
如果‘Z’为无穷大,Y(预测值)为1,如果‘Z’为负无穷,则 Y(预测值)为0。
假设分析
假设的输出是估计概率。它表示预测值是真值的可信度。考虑下面的例子,
X = [x0 x1] = [1 IP-Address]
根据 x1 的值,假设我们得到的估计概率是 0.8,那就说明这个邮件有百分之八十的概率是垃圾邮件。
把上述问题的数学过程如下:
这体现了“逻辑回归”这个名称的由来。通过线性回归拟合数据,而后使用逻辑函数来预测分类的结果。
逻辑回归的类型
1.二分类逻辑回归
分类结果只有两种。比如:邮件是否为垃圾邮件。
2.多分类逻辑回归
三种以上无序的分类。比如:更喜欢哪种食物(蔬菜,非素食,素食)
3.有序逻辑回归
三种以上有序分类。比如:电影的评级,从 1 到 5。
决策边界
我们需要设置阈值以预测数据的分类。根据这个阈值,可以把得到的估计概率也进行分类。
比如,预测值 ≥ 0.5 ,则可以把邮件分类为垃圾邮件。
决策边界可以是线性的或者非线性的。可以通过增加多项式阶数来获得复杂的决策边界。
逻辑回归的损失函数(代价函数)
为什么线性回归的损失函数不能用于逻辑回归呢?
线性函数使用均方差作为损失函数。如果被用在逻辑回归上,它会成为参数(theta)的非凸函数。而只有当函数是凸函数时,梯度下降才会收敛到全局最小值。
损失函数解析
简化的损失函数
为什么损失函数是这样?(最大似然解释)
这种副作用是由于我们训练时需要通过最小化损失函数来最大化概率。假设样本是独立同分布的,则降低损失函数会增加最大似然值。
梯度下降算法公式推导
Python 实现
def weightInitialization(n_features):
w = np.zeros((1,n_features))
b = 0
return w,b
def sigmoid_activation(result):
final_result = 1/(1+np.exp(-result))
return final_result
def model_optimize(w, b, X, Y):
m = X.shape[0]
#Prediction
final_result = sigmoid_activation(np.dot(w,X.T)+b)
Y_T = Y.T
cost = (-1/m)*(np.sum((Y_T*np.log(final_result)) + ((1-Y_T)*(np.log(1-final_result)))))
#
#Gradient calculation
dw = (1/m)*(np.dot(X.T, (final_result-Y.T).T))
db = (1/m)*(np.sum(final_result-Y.T))
grads = {"dw": dw, "db": db}
return grads, cost
def model_predict(w, b, X, Y, learning_rate, no_iterations):
costs = []
for i in range(no_iterations):
#
grads, cost = model_optimize(w,b,X,Y)
#
dw = grads["dw"]
db = grads["db"]
#weight update
w = w - (learning_rate * (dw.T))
b = b - (learning_rate * db)
#
if (i % 100 == 0):
costs.append(cost)
#print("Cost after %i iteration is %f" %(i, cost))
#final parameters
coeff = {"w": w, "b": b}
gradient = {"dw": dw, "db": db}
return coeff, gradient, costs
def predict(final_pred, m):
y_pred = np.zeros((1,m))
for i in range(final_pred.shape[1]):
if final_pred[0][i] > 0.5:
y_pred[0][i] = 1
return y_pred
成本与迭代次数的关系
这个系统的训练和测试精度为 100%
本实现针对二元逻辑回归。对于二元以上的数据,需要使用 softmax 回归。
完整代码: