文章目录
- 一、什么是过采样方法?
- 二、使用过采样方法实现逻辑回归分类问题
- 三、过采样的优缺点
本篇内容是 基于Python的scikit-learn库中sklearn.linear_model 类中的 LogisticRegression()逻辑回归方法实现的,其内容中只是在处理训练集的方法上与以下链接内容里的不同,在其他的方面都是一样的,可以放在一起看。
- 《机器学习》—— 通过下采样方法实现逻辑回归分类问题:
https://blog.csdn.net/weixin_73504499/article/details/141367509
一、什么是过采样方法?
- 过采样(Over-sampling)是数据预处理中的一种技术,主要用于处理不平衡数据集(imbalanced datasets)问题。在不平衡数据集中,某些类别的样本数量远多于其他类别,这可能导致机器学习模型在训练时偏向于多数类,从而忽略了少数类,进而在预测时表现出对少数类的低准确率。
- 过采样的基本思想是通过增加少数类(即样本数量较少的类别)的样本来改善数据集的平衡性。
- 本篇我们使用过采样方法中的合成少数类过采样技术(SMOTE, Synthetic Minority Over-sampling Technique)对数据集进行过采样操作
- 合成少数类过采样技术(SMOTE, Synthetic Minority Over-sampling Technique)是一种复杂的过采样方法,它通过生成新的少数类样本来增加其数量。SMOTE算法首先选择少数类中的一个样本,然后在其最近的k个邻居(这些邻居也属于少数类)中随机选择一个样本,并在两个样本之间的连线上随机生成一个新的样本。这个过程可以重复多次,以生成足够数量的新样本。
二、使用过采样方法实现逻辑回归分类问题
-
具体步骤:
- 1、读取并查看数据
- 2、数据标准化
- 3、切分原始数据
- 4、过采样解决样本不均衡问题
- 5、训练模型并建立最优模型
- 6、传入测试数据集进行测试
-
1、读取并查看数据
-
这里有一份含有28万+数据的csv文件
-
通过pandas方法读取此文件
# 通过pandas方法读取creditcard.csv文件,并用data变量接收 data = pd.read_csv("creditcard.csv") data.head() # 查看data的前几行,默认是5行
-
如下图所示:
-
这个数据的最后一列“Class”标签用来标注是否正常,0表示正常,1表示异常
-
我们可以通过画出条形图来观察两类标签的样本个数
import matplotlib.pyplot as plt """绘制条形图,查看正负样本个数""" labels_count = pd.Series.value_counts(data['Class']) plt.title("正负例样本数") plt.xlabel("类别") plt.ylabel("帧数") labels_count.plot(kind='bar') plt.show()
-
结果如下:
-
可以看出0和1标签的样本数据个数相差的非常多,0标签有28万+,而1标签只有几百多,这便是不平衡数据集
-
-
2、数据标准化
- 我们数据的倒数第二(Amount)列可以看出,这一列的特征数值,比其他列特征数值要大很多,如果不做调整就传入模型训练,将会占有很大的权重,导致最后的结果很大的程度上都只受这一个特征的影响
- 通过观察,可以发现,前面的特征数据都是在-1~1之间,所以我们可以用Z标准化的方法,改变其数值范围
from sklearn.preprocessing import StandardScaler """数据标准化:Z标准化""" scaler = StandardScaler() # a = data[['Amount']] # 返回dataframe数据,而不是series # 用StandardScaler中的fit_transform实现Z标准化 data['Amount'] = scaler.fit_transform(data[['Amount']]) # 删除无用列(第一列没有作用) data = data.drop(['Time'], axis=1)
- 结果如下:
-
3、切分原数据
- 对原始数据进行切分,切出20%作为测试集,其余的为训练集
# 切分数据集 x_whole = data.drop('Class', axis=1) # # 去除标签列作为训练数据 y_whole = data.Class # 得到标签列 # 划分出20%的测试集,并抛出随机种子,为了后面每次的运行,随机划分的都是相同的数据 x_train_w, x_test_w, y_train_w, y_test_w = train_test_split(x_whole, y_whole, test_size=0.2, random_state=0)
- 对原始数据进行切分,切出20%作为测试集,其余的为训练集
-
4、过采样解决样本不均衡问题
-
使用SMOTE算法通过生成新的少数类样本来增加其数量
-
对过采样处理后的数据进行切分,构造训练集和测试集
# 进行过采样操作 from imblearn.over_sampling import SMOTEoversampler = SMOTE(random_state=0) # 随机种子 os_x_train, os_y_train, = oversampler.fit_resample(x_train_w, y_train_w) # 人工拟合数据 # os_x_train:用于再次切分的训练数据 # os_y_train:用于再次切分的标签数据 # 切分过采样后的训练数据和标签数据,划分训练集和测试集,切分出30%测试集 os_x_train_s, os_x_test_s, os_y_train_s, os_y_test_s = train_test_split(os_x_train, os_y_train, test_size=0.3, random_state=0)
-
可以再次通过绘制条形图观察数据
"""绘制图形,查看正负样本个数""" # 通过标签数据来查看 labels_count = pd.Series.value_counts(os_y_train) plt.title("正负例样本数") plt.xlabel("类别") plt.ylabel("帧数") labels_count.plot(kind='bar') plt.show()
-
结果如下:
-
可以看出通过SMOT算法,让1标签的数据量增加到与0标签相同的数量
-
-
5、训练模型并建立最优模型
-
交叉验证选择较优惩罚因子
-
建立最优模型
# 交叉验证选择较优惩罚因子 scores = [] c_param_range = [0.01, 0.1, 1, 10, 100] # 参数 for i in c_param_range: # 第1次循环的时候C=0.01,5个逻辑回归模型lr = LogisticRegression(C=i, penalty='l2', solver='lbfgs', max_iter=1000)score = cross_val_score(lr, os_x_train_s, os_y_train_s, cv=10, scoring='recall') # 交叉验证score_mean = sum(score) / len(score) # 交叉验证后的值 召回率scores.append(score_mean) # 存放所有的交叉验证召回率print(score_mean) # 将不同的C参数分别传入模型, 分别看看哪个模型效果更好best_c = c_param_range[np.argmax(scores)] # 找到scores中最大的值对应的C参数 print("........最优惩罚因子为:{}........".format(best_c))"""建立最优模型""" lr = LogisticRegression(C=best_c, penalty='l2', max_iter=1000) lr.fit(os_x_train_s, os_y_train_s)
-
运行结果为:
-
-
6、传入测试数据集进行测试
-
predict 方法接受一个数组(或类似数组的结构,如列表的列表、Pandas DataFrame等),其中包含了要预测的目标变量的新数据点。然后,它使用训练好的模型对这些数据点进行预测,并返回一个包含预测结果的数组。
-
metrics.classification_report 是 scikit-learn(一个流行的 Python 机器学习库)中的一个函数,用于展示主要分类指标的文本报告。这个函数特别适用于评估分类模型的性能,尤其是在处理多类分类问题时。它提供了每个类别的精确度(precision)、召回率(recall)、F1 分数(F1-score)和支持度(support,即每个类别的真实样本数量)的详细报告。
from sklearn import metrics# 传入过采样后切分出的训练集进行测试 test_predicted_s = lr.predict(os_x_test_s) print(metrics.classification_report(os_y_test_s, test_predicted_s))# 传入原数据切分后的测试集进行测试 test_predicted_w = lr.predict(x_test_w) print(metrics.classification_report(y_test_w, test_predicted_w))
-
结果如下:
-
下面是未使用过采样方法,使用原数据进行模型测试后的结果
-
对比两次不同数据训练出的结果可以看出,通过过采样的方法处理数据后可以大大提高模型的性能
-
三、过采样的优缺点
-
优点:
- 平衡数据集:过采样通过增加少数类样本的数量,有助于平衡训练数据集中各个类别之间的比例,从而提高机器学习模型对少数类别的分类性能。
- 不引入偏见:在合成新的少数类样本时,过采样方法(如SMOTE算法)并不依赖于多数类样本,因此不会引入对多数类的任何偏见。
-
缺点:
- 过拟合风险:过度依赖过采样可能导致模型对训练数据过拟合,从而在未知数据上表现不佳。这是因为模型可能过于关注少数类的特征,而忽略了数据的整体分布。
- 增加计算成本:过采样方法需要合成新的样本,这会增加数据集的规模,进而增加训练和预测的计算成本。
- 引入噪声:在合成新的少数类样本时,过采样方法可能引入一定程度的噪声,这可能对模型的性能产生不利影响。
- 类别平衡失衡:过采样可能会导致数据集类别的平衡性失衡,特别是当过采样比例过高时,会使得多数类样本的比例相对较低,从而可能导致模型对多数类样本的分类性能下降。