文章目录
相关介绍
逻辑回归
逻辑回归是一种预测分类结果的线性模型。它使用逻辑函数(通常是Sigmoid函数)来将线性模型的输出转换为概率。逻辑回归的目标是最小化预测概率和实际标签之间的误差,这通常通过梯度下降等优化算法实现。
不平衡数据集
在许多实际应用中,数据集往往是不平衡的,即某些类别的样本数量远多于其他类别。这种不平衡可能导致模型偏向于多数类,从而影响少数类的预测性能。
下采样
下采样是一种处理不平衡数据集的方法,通过减少多数类的样本来平衡数据集。在下采样过程中,可以从多数类中随机选择样本进行删除,直到多数类和少数类的样本数量达到一个相对平衡的状态。
逻辑回归与下采样结合
将逻辑回归与下采样结合使用,可以处理不平衡数据集上的二分类问题。具体步骤如下:
- 下采样:从多数类中随机选择样本进行删除,以减少多数类的样本数量,使数据集更加平衡。
- 逻辑回归模型训练:使用下采样后的平衡数据集训练逻辑回归模型。
- 模型评估:使用适当的评估指标(如准确率、召回率、F1分数等)评估模型的性能。
下采样运用
1.导入相关包
import matplotlib.pylab as plt
import numpy as np
import pandas as pd
from pylab import mpl
def cm_plot(y, yp):
from sklearn.metrics import confusion_matrix
import matplotlib.pyplot as plt
cm = confusion_matrix(y, yp)
plt.matshow(cm, cmap=plt.cm.Blues)
plt.colorbar()
for x in range(len(cm)):
for y in range(len(cm)):
plt.annotate(cm[x, y], xy=(y, x), horizontalalignment='center', verticalalignment='center')
plt.ylabel('True label')
plt.xlabel('Predicted label')
return plt
导入相关的包,并绘制混淆矩阵,其中对应包的作用如下:
- pandas:用于数据处理和分析。
- matplotlib.pyplot:用于绘制图形,这里主要用于绘制散点图来直观展示“广告投入”与“销售额”之间的关系。
- numpy:提供了高性能的多维数组对象以及这些数组的操作。
2.数据预处理
- 读取数据:使用pandas库读取creditcard.csv文件。
- 查看数据:通过data.head()查看数据的前5行。
- 数据标准化:使用StandardScaler对Amount列进行标准化处理,使其符合正态分布。
- 删除无用列:删除Time列,因为它对欺诈检测不是很有用。
"""第一步,数据预处理"""
data = pd.read_csv(r"./creditcard.csv")
data.head() # 默认打印前5行
"""绘制图像,查看正负样本个数"""
mpl.rcParams['font.sans-serif'] = ['Microsoft YaHei']
mpl.rcParams['axes.unicode_minus'] = False
lables_count = pd.value_counts(data['Class'])
plt.title("正负样本数")
plt.xlabel("类别")
plt.ylabel("频数")
lables_count.plot(kind='bar')
plt.show()
"""数据标准化,查看正负样本个数"""
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
a = data[['Amount']]
data['Amount'] = scaler.fit_transform(data[['Amount']])
data = data.drop(['Time'], axis=1)
3.数据下采样与合并
- 下采样:由于数据集中正常交易(类别0)和欺诈交易(类别1)的数量极不均衡,因此使用下采样技术来平衡数据集。
- 合并数据集:将下采样后的正常交易数据和欺诈交易数据合并成一个新的数据集data_c。
"""下采样解决样本不均衡问题"""
positive_eg = data[data['Class'] == 0]
negative_eg = data[data['Class'] == 1]
np.random.seed(seed=4)
positive_eg = positive_eg.sample(len(negative_eg))
data_c = pd.concat([positive_eg, negative_eg])
print(data_c)
4.绘制下采样图像
绘制图像:再次绘制正负样本数的条形图,以验证下采样的效果
"""绘制图像,查看正负样本个数"""
mpl.rcParams['font.sans-serif'] = ['Microsoft YaHei']
mpl.rcParams['axes.unicode_minus'] = False
lables_count = pd.value_counts(data_c['Class'])
plt.title("正负样本数")
plt.xlabel("类别")
plt.ylabel("频数")
lables_count.plot(kind='bar')
plt.show()
5. 划分数据集
划分数据集:使用train_test_split函数将数据集划分为训练集和测试集,以及一个更小的训练集(X_train_w, y_train_w)用于交叉验证。
from sklearn.model_selection import train_test_split
X = data.drop('Class', axis=1)
y = data.Class
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
X_train_w, X_test_w, y_train_w, y_test_w = train_test_split(X, y, test_size=0.2, random_state=0)
6. 模型训练与评估
- 模型训练:使用逻辑回归模型进行训练。
- 交叉验证:通过交叉验证(cross_val_score)来找到最佳的正则化参数C,这里使用召回率(recall)作为评分指标。使用最佳参数C建立最终模型,并在训练集和测试集上进行预测。
- 打印报告:打印分类报告(classification_report),包括精确度、召回率、F1分数等指标。
- 绘制混淆矩阵:使用自定义的cm_plot函数绘制混淆矩阵,以可视化模型性能。
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
scores = []
c_param_range = [0.01, 0.1, 1, 10, 100] # 参数
for i in c_param_range: # 第1词循环的时候C=0.01,
lr = LogisticRegression(C=i, penalty='l2', solver='lbfgs', max_iter=1000)
score = cross_val_score(lr, X_train_w, y_train_w, cv=8, scoring='recall')
score_mean = sum(score) / len(score) # 交叉验证后的召回率
scores.append(score_mean) # 所有交叉验证的召回率
print(score_mean)
best_c = c_param_range[np.argmax(scores)] # 寻找scores中最大值对应的C
# 建立最优模型
lr = LogisticRegression(C=best_c, penalty='l2', solver='lbfgs', max_iter=1000)
lr.fit(X_train_w, y_train_w)
# 绘制混淆矩阵
from sklearn import metrics
train_predicted_w = lr.predict(X_train_w)
print(metrics.classification_report(y_train_w, train_predicted_w))
cm_plot(y_train_w, train_predicted_w).show()
test_predicted_w = lr.predict(X_test_w) # 小数据测试
print(metrics.classification_report(y_test_w, test_predicted_w))
cm_plot(y_test_w, test_predicted_w).show()
train_predicted = lr.predict(X_train)
print(metrics.classification_report(y_train, train_predicted))
cm_plot(y_train, train_predicted).show()
test_predicted = lr.predict(X_test)
print(metrics.classification_report(y_test, test_predicted))
cm_plot(y_test, test_predicted).show()
7. 阈值调整与性能评估
- 阈值调整:通过调整预测概率的阈值来探索不同阈值对召回率的影响。逻辑回归模型输出的是属于每个类别的概率,通过调整这个阈值(默认为0.5),可以改变预测结果。
- 计算召回率:对于每个阈值,计算召回率,并打印分类报告和混淆矩阵。
thresholds = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]
recalls = []
for i in thresholds:
y_predict_proba = lr.predict_proba(X_test)
y_predict_proba = pd.DataFrame(y_predict_proba)
y_predict_proba = y_predict_proba.drop([0], axis=1)
# 当预测概率大于i,0.1,0.2,预测的标签设置1
y_predict_proba[y_predict_proba[[1]] > i] = 1
# 当预测概率小于等于i 预测的标签设置为0
y_predict_proba[y_predict_proba[[1]] <= i] = 0
recall = metrics.recall_score(y_test, y_predict_proba[1])
recalls.append(recall)
print(metrics.classification_report(y_test, y_predict_proba[1]))
# cm_plot(y_test, y_predict_proba[1]).show()
print("{} Recall metric in the testing dataset: {:.3f}".format(i, recall))
总结
1.下采样的优点
- 减少计算量:下采样通过减少数据的尺寸,使得后续处理层需要处理的参数数量减少,从而加速了训练和推理过程。这对于处理大规模数据集或实时应用尤为重要。
- 提高鲁棒性:通过聚合相邻像素的信息,下采样可以使网络对图像中的小变化(如平移、旋转等)更加鲁棒。这种特性有助于提升模型在复杂场景下的泛化能力。
- 特征抽象:随着网络深度的增加,下采样有助于捕获更高层次的抽象特征。这些特征对于许多任务(如分类、目标检测等)来说是至关重要的。
- 防止过拟合:通过减少特征图的尺寸,下采样可以作为一种正则化手段,有助于防止网络在训练数据上过拟合。这对于提升模型的泛化性能具有重要意义。
- 增大感知野:下采样使得每个神经元能够覆盖更大的输入区域,从而增大感知野。这有助于网络捕捉更全局的信息,对于理解图像的整体结构非常有帮助。
2.下采样的缺点
- 信息丢失:下采样过程中会丢失一些细节信息,如边缘信息等。这些信息对于某些任务(如需要精细边缘检测的图像分割任务)来说非常重要。因此,在设计网络结构时,需要权衡下采样层的位置和数量,以确保在保留足够信息的同时实现高效的特征提取。
- 精度损失:强力的下采样虽然能够减少计算量并提高鲁棒性,但也会在一定程度上损失精度。因此,在实际应用中需要根据具体任务的需求来选择合适的下采样策略。