逻辑回归,也叫作 logistic 回归。虽然名字中带有“回归”,但它实际上是分类方法,主要解决的是二分类问题,当然它也可以解决多分类问题,只是二分类更常见一些。
应用场景:
- 广告点击率
- 是否为垃圾邮件
- 是否患病
- 金融诈骗
- 虚假账号
原理
在逻辑回归中使用了 Logistic 函数,也称为 Sigmoid 函数。Sigmoid 函数是在深度学习中经常用到的函数之一,函数公式为:
函数的图形如下所示,类似 S 状:
在 sklearn 中,我们使用 LogisticRegression() 函数构建逻辑回归分类器,函数里有一些常用的构造参数:
penalty:惩罚项,取值为 l1 或 l2,默认为 l2。当模型参数满足高斯分布的时候,使用 l2,当模型参数满足拉普拉斯分布的时候,使用 l1;
solver:代表的是逻辑回归损失函数的优化方法。有 5 个参数可选,分别为 liblinear、lbfgs、newton-cg、sag 和 saga。默认为 liblinear,适用于数据量小的数据集,当数据量大的时候可以选用 sag 或 saga 方法。 max_iter:算法收敛的最大迭代次数,默认为 10。 n_jobs:拟合和预测的时候 CPU 的核数,默认是 1,也可以是整数,如果是 -1 则代表 CPU 的核数。
模型评估指标
举个例子,对于机场安检中恐怖分子的判断,就不能采用准确率对模型进行评估。恐怖分子的比例是极低的,因此当用准确率做判断时,如果准确率高达 99.999%,就说明这个模型一定好么?
其实正因为现实生活中恐怖分子的比例极低,就算不能识别出一个恐怖分子,也会得到非常高的准确率。因为准确率的评判标准是正确分类的样本个数与总样本数之间的比例。因此非恐怖分子的比例会很高,就算识别不出来恐怖分子,正确分类的个数占总样本的比例也会很高,也就是准确率高。实际上应该更关注恐怖分子的识别。
数据预测的四种情况:TP、FP、TN、FN。第二个字母 P 或 N 代表预测为正例还是负例,P 为正,N 为负。第一个字母 T 或 F 代表的是预测结果是否正确,T 为正确,F 为错误。‘
所以四种情况分别为:
- TP:预测为正,判断正确;
- FP:预测为正,判断错误;
- TN:预测为负,判断正确;
- FN:预测为负,判断错误。
精确率 P = TP/ (TP+FP),对应上面恐怖分子这个例子,在所有判断为恐怖分子的人数中,真正是恐怖分子的比例。
召回率 R = TP/ (TP+FN),也称为查全率。代表的是恐怖分子被正确识别出来的个数与恐怖分子总数的比例。
有一个指标综合了精确率和召回率,可以更好地评估模型的好坏。这个指标叫做 F1,用公式表示为:
F1 作为精确率 P 和召回率 R 的调和平均,数值越大代表模型的结果越好。
实例
信用卡诈骗分析
import pandas as pd from matplotlib import pyplot as plt import seaborn as sns import numpy as np from sklearn.preprocessing import StandardScaler from sklearn.model_selection import train_test_split from sklearn.linear_model import LogisticRegression from sklearn.metrics import confusion_matrix, precision_recall_curve import itertools class CreditFraud: # 混淆矩阵可视化 def plot_confusion_matrix(self, cm, classes, normalize=False, title='Confusion matrix', cmap=plt.cm.Blues): plt.rcParams['font.sans-serif'] = ['SimHei'] plt.figure() plt.imshow(cm, interpolation='nearest', cmap=cmap) plt.title(title) plt.colorbar() tick_marks = np.arange(len(classes)) plt.xticks(tick_marks, classes, rotation=0) plt.yticks(tick_marks, classes) thresh = cm.max() / 2 for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])): plt.text(j, i, cm[i, j], horizontalalignment='center', color='white' if cm[i, j] > thresh else 'black') plt.tight_layout() plt.ylabel('True label') plt.xlabel('Predicted label') plt.show() # 显示模型评估结果 def show_metrics(self, cm): tp = cm[1, 1] fn = cm[1, 0] fp = cm[0, 1] tn = cm[0, 0] print('精确率:{:.3f}'.format(tp / (tp + fp))) print('召回率:{:.3f}'.format(tp / (tp + fn))) print('f1值:{:.3f}'.format(2 * (((tp / (tp + fp)) * (tp / (tp + fn))) / ((tp / (tp + fp)) + (tp / (tp + fn)))))) # 绘制精确率-召回率曲线 def plot_precision_recall(self, recall, precision): plt.rcParams['font.sans-serif'] = ['SimHei'] plt.step(recall, precision, color='b', alpha=0.2, where='post') plt.fill_between(recall, precision, step='post', alpha=0.2, color='b') plt.plot(recall, precision, linewidth=2) plt.xlim([0.0, 1]) plt.ylim([0.0, 1.05]) plt.xlabel('召回率') plt.ylabel('精确率') plt.title('精确率-召回率 曲线') plt.show() # 显示交易笔数,欺诈交易笔数 def show(self, data): # 设置plt正确显示中文 plt.rcParams['font.sans-serif'] = ['SimHei'] # 绘制类别分布 plt.figure() ax = sns.countplot(x='Class', data=data) plt.title('类别分布') plt.show() num = len(data) num_fraud = len(data[data['Class'] == 1]) print('总交易笔数:', num) print('诈骗交易笔数:', num_fraud) print('诈骗交易比例:{:.6f}'.format(num_fraud / num)) # 诈骗和正常交易可视化 f, (ax1, ax2) = plt.subplots(2, 1, sharex='True', figsize=(10, 8)) bins = 50 ax1.hist(data.Time[data.Class == 1], bins=bins, color='deeppink') ax1.set_title('诈骗交易') ax2.hist(data.Time[data.Class == 0], bins=bins, color='deepskyblue') ax2.set_title('正常交易') plt.xlabel('时间') plt.ylabel('交易次数') plt.show() def logic_regress(self, data): self.show(data) # 对Amount进行标准化 data['Amount_Norm'] = StandardScaler().fit_transform(data['Amount'].values.reshape(-1, 1)) # 特征选择 y = np.array(data.Class.tolist()) # y = data.Class.values data_new = data.drop(['Time', 'Amount', 'Class'], axis=1) X = np.array(data_new.values) trian_x, test_x, train_y, test_y = train_test_split(X, y, test_size=0.1, stratify=y, random_state=33) # 逻辑回归分类 clf = LogisticRegression(n_jobs=-1) clf.fit(trian_x, train_y) predict_y = clf.predict(test_x) # 预测样本的置信分数 score_y = clf.decision_function(test_x) # 计算混淆矩阵 cm = confusion_matrix(test_y, predict_y) class_names = [0, 1] # 显示混淆矩阵 self.plot_confusion_matrix(cm, classes=class_names, title='逻辑回归 混淆矩阵') # 显示模型评估分数 self.show_metrics(cm) # 计算精确率、召回率、阈值用于可视化 precision, recall, thresholds = precision_recall_curve(test_y, score_y) self.plot_precision_recall(recall, precision) if __name__ == '__main__': data_ori = pd.read_csv(r'C:\My_data\Study\数据分析实战\credit_fraud\creditcard.csv') print(data_ori.describe()) credit = CreditFraud() credit.logic_regress(data_ori)
近期有很多朋友通过私信咨询有关Python学习问题。为便于交流,点击蓝色自己加入讨论解答资源基地