本文讨论了Logistic回归的基础知识及其在Python中的实现。逻辑回归基本上是一种监督分类算法。在分类问题中,目标变量(或输出)y对于给定的一组特征(或输入)X,只能采用离散值。
与普遍看法相反,逻辑回归是一种回归模型。 该模型建立回归模型以预测给定数据条目属于编号为“1”的类别的概率。 就像线性回归假设数据遵循线性函数一样,Logistic回归使用sigmoid函数对数据进行建模。
只有当决策阈值进入图片时,逻辑回归才成为分类技术。 阈值的设置是Logistic回归的一个非常重要的方面,并且取决于分类问题本身。
阈值的决定主要受精度和召回值的影响。 理想情况下,我们希望精度和召回都是1,但很少这种情况。 在Precision-Recall权衡的情况下,我们使用以下参数来决定thresold:
1.低精度/高回调:在我们想要减少假阴性数量而不必减少误报数量的应用中,我们选择具有低精度值或高回调值的决策值。 例如,在癌症诊断应用中,如果患者被错误地诊断为患有癌症,我们不希望任何受影响的患者被归类为不受影响而没有给予足够的注意。 这是因为,可以通过其他医学疾病来检测不存在癌症,但是在已经被拒绝的候选者中不能检测到疾病的存在。
2.高精度/低回调:在我们希望减少误报数量而不必减少假阴性数量的应用中,我们选择具有高精度值或低回调值的决策值。例如,如果我们对客户进行分类,他们是否会对个性化广告做出积极或消极的反应,我们希望绝对确定客户会对广告做出积极反应,否则,负面反应会导致客户的潜在销售损失。
根据类别数量,Logistic回归可分为:
二项式:目标变量只能有两种可能的类型:“0”或“1”代表“赢”与“损失”,“通过”与“失败”,“死”与“活着”等。
多项式:目标变量可以具有3种或更多种未被排序的可能类型(即类型没有定量意义),例如“疾病A”与“疾病B”对比“疾病C”。
顺序:它处理具有有序类别的目标变量。 例如,测试分数可以分类为:“非常差”,“差”,“好”,“非常好”。 在这里,每个类别可以给出分数,如0,1,2,3。
首先,我们探索最简单的Logistic回归形式,即二项Logistic回归。
考虑一个示例数据集,该数据集将学习小时数与考试结果进行映射。结果只能采用两个值,即通过(1)或失败(0):
HOURS(X)0.500.751.001.251.501.752.002.252.502.753.003.253.503.754.004.254.504.755.005.50PASS(Y)00000010101010111111
所以我们有:
即y是分类目标变量,它只能采用两种可能的类型:“0”或“1”。
为了概括我们的模型,我们假设:
被称为学习率,需要明确设置。
让我们在样本数据集上看到上面技术的python实现:
import csvimport numpy as npimport matplotlib.pyplot as plt def loadCSV(filename): ''' function to load dataset ''' with open(filename,"r") as csvfile: lines = csv.reader(csvfile) dataset = list(lines) for i in range(len(dataset)): dataset[i] = [float(x) for x in dataset[i]] return np.array(dataset) def normalize(X): ''' function to normalize feature matrix, X ''' mins = np.min(X, axis = 0) maxs = np.max(X, axis = 0) rng = maxs - mins norm_X = 1 - ((maxs - X)/rng) return norm_X def logistic_func(beta, X): ''' logistic(sigmoid) function ''' return 1.0/(1 + np.exp(-np.dot(X, beta.T))) def log_gradient(beta, X, y): ''' logistic gradient function ''' first_calc = logistic_func(beta, X) - y.reshape(X.shape[0], -1) final_calc = np.dot(first_calc.T, X) return final_calc def cost_func(beta, X, y): ''' cost function, J ''' log_func_v = logistic_func(beta, X) y = np.squeeze(y) step1 = y * np.log(log_func_v) step2 = (1 - y) * np.log(1 - log_func_v) final = -step1 - step2 return np.mean(final) def grad_desc(X, y, beta, lr=.01, converge_change=.001): ''' gradient descent function ''' cost = cost_func(beta, X, y) change_cost = 1 num_iter = 1 while(change_cost > converge_change): old_cost = cost beta = beta - (lr * log_gradient(beta, X, y)) cost = cost_func(beta, X, y) change_cost = old_cost - cost num_iter += 1 return beta, num_iter def pred_values(beta, X): ''' function to predict labels ''' pred_prob = logistic_func(beta, X) pred_value = np.where(pred_prob >= .5, 1, 0) return np.squeeze(pred_value) def plot_reg(X, y, beta): ''' function to plot decision boundary ''' # labelled observations x_0 = X[np.where(y == 0.0)] x_1 = X[np.where(y == 1.0)] # plotting points with diff color for diff label plt.scatter([x_0[:, 1]], [x_0[:, 2]], c='b', label='y = 0') plt.scatter([x_1[:, 1]], [x_1[:, 2]], c='r', label='y = 1') # plotting decision boundary x1 = np.arange(0, 1, 0.1) x2 = -(beta[0,0] + beta[0,1]*x1)/beta[0,2] plt.plot(x1, x2, c='k', label='reg line') plt.xlabel('x1') plt.ylabel('x2') plt.legend() plt.show() if __name__ == "__main__": # load the dataset dataset = loadCSV('dataset1.csv') # normalizing feature matrix X = normalize(dataset[:, :-1]) # stacking columns wth all ones in feature matrix X = np.hstack((np.matrix(np.ones(X.shape[0])).T, X)) # response vector y = dataset[:, -1] # initial beta values beta = np.matrix(np.zeros(X.shape[1])) # beta values after running gradient descent beta, num_iter = grad_desc(X, y, beta) # estimated beta values and number of iterations print("Estimated regression coefficients:", beta) print("No. of iterations:", num_iter) # predicted labels y_pred = pred_values(beta, X) # number of correctly predicted labels print("Correctly predicted labels:", np.sum(y == y_pred)) # plotting regression line plot_reg(X, y, beta) |
---|
Estimated regression coefficients: [[ 1.70474504 15.04062212 -20.47216021]]
No. of iterations: 2612
Correctly predicted labels: 100
意:梯度下降是估算
的众多方法之一。
基本上,这些是更高级的算法,一旦您定义了成本函数和渐变,就可以在Python中轻松运行。这些算法是:
使用这些算法中的任何一种优于梯度下降的优点/缺点:
好处
缺点
在Multiomial Logistic回归中,输出变量可以具有两个以上可能的离散输出。考虑一下数字数据集。这里,输出变量是数字值,它可以取出(0,12,3,4,5,6,7,8,9)中的值。
下面给出了使用scikit实现Multinomial Logisitc回归 - 学习对数字数据集进行预测。
from sklearn import datasets, linear_model, metrics # load the digit datasetdigits = datasets.load_digits() # defining feature matrix(X) and response vector(y)X = digits.datay = digits.target # splitting X and y into training and testing setsfrom sklearn.model_selection import train_test_splitX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.4, random_state=1) # create logistic regression objectreg = linear_model.LogisticRegression() # train the model using the training setsreg.fit(X_train, y_train) # making predictions on the testing sety_pred = reg.predict(X_test) # comparing actual response values (y_test) with predicted response values (y_pred)print("Logistic Regression model accuracy(in %):", metrics.accuracy_score(y_test, y_pred)*100) |
---|
Logistic Regression model accuracy(in %): 95.6884561892
最后,这里有一些关于Logistic回归思考的观点:
本文由Nikhil Kumar撰写。