目录
过采样(Oversampling)是指在数据处理或机器学习中,增加少数类样本的数量以平衡类别分布。常用于处理类别不平衡问题,通过复制少数类样本或生成新样本来提高模型对少数类的识别能力。




- import pandas as pd
- import matplotlib.pyplot as plt
- import numpy as np
-
-
- # 可视化混淆矩阵
- 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
-
-
- data = pd.read_csv("creditcard.csv")
-
- # 数据标准化: Z标准化
- from sklearn.preprocessing import StandardScaler # 可对多列进行标准化
-
- scaler = StandardScaler()
- a = data[['Amount']] # 取出来变成df数据 因为fit_transform()需要传入df数据
- data['Amount'] = scaler.fit_transform(a) # 对Amount列数据进行标准化
- data = data.drop(['Time'], axis=1) # 删除无用列
-
- # 随机取数据 小数据集
- from sklearn.model_selection import train_test_split
-
- x = data.drop('Class', axis=1)
- y = data.Class
- x_w_train, x_w_test, y_w_train, y_w_test = \
- train_test_split(x, y, test_size=0.2, random_state=0) # 随机取数据
-
- """过采样"""
- from imblearn.over_sampling import SMOTE
-
- oversampler = SMOTE(random_state=0) # 随机种子 保证数据拟合效果
- x_os, y_os = oversampler.fit_resample(x_w_train, y_w_train) # 通过原始训练集的特征和标签数据人工拟合一份训练集和标签
-
- # 绘制条形图 查看样本个数
- plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置字体
- plt.rcParams['axes.unicode_minus'] = False # 解决符号显示为方块的问题
- labels_count = pd.value_counts(y_os) # 统计0有多少个数据,1有多个数据
- plt.title("正负例样本数")
- plt.xlabel("类别")
- plt.ylabel("频数")
- labels_count.plot(kind='bar') # 生成一个条形图,展示每个类别的样本数量。
- plt.show()
-
- x_os_train, x_os_test, y_os_train, y_os_test = \
- train_test_split(x_os, y_os, test_size=0.2, random_state=0) # 随机取数据
-
- # 交叉验证选择较优惩罚因子 λ
- from sklearn.model_selection import cross_val_score # 交叉验证的函数
- from sklearn.linear_model import LogisticRegression
-
- # k折交叉验证选择C参数
- scores = []
- c_param_range = [0.01, 0.1, 1, 10, 100] # 待选C参数
- for i in c_param_range:
- lr = LogisticRegression(C=i, penalty='l2', solver='lbfgs', max_iter=1000) # 创建逻辑回归模型 lbfgs 拟牛顿法
- score = cross_val_score(lr, x_os_train, y_os_train, cv=8, scoring='recall') # k折交叉验证 比较召回率
- score_mean = sum(score) / len(score)
- scores.append(score_mean)
- print(score_mean)
-
- best_c = c_param_range[np.argmax(scores)] # 寻找到scores中最大值的对应的C参数
- print(f"最优惩罚因子为:{best_c}")
-
- # 建立最优模型
- lr = LogisticRegression(C=best_c, penalty='l2', max_iter=1000)
- lr.fit(x_os_train, y_os_train)
-
- # 绘制混淆矩阵
- from sklearn import metrics
-
- x_os_train_predicted = lr.predict(x_os_train) # 训练集特征数据x的预测值
- print(metrics.classification_report(y_os_train, x_os_train_predicted)) # 传入训练集真实的结果数据 与预测值组成矩阵
-
- x_os_test_predicted = lr.predict(x_os_test) # 训练集特征数据x的预测值
- print(metrics.classification_report(y_os_test, x_os_test_predicted)) # 传入训练集真实的结果数据 与预测值组成矩阵
-
- x_w_test_predicted = lr.predict(x_w_test)
- print(metrics.classification_report(y_w_test, x_w_test_predicted))
- import pandas as pd
- import matplotlib.pyplot as plt
- import numpy as np
-
- data = pd.read_csv("creditcard.csv")
-
- # 数据标准化: Z标准化
- from sklearn.preprocessing import StandardScaler # 可对多列进行标准化
-
- scaler = StandardScaler()
- a = data[['Amount']] # 取出来变成df数据 因为fit_transform()需要传入df数据
- data['Amount'] = scaler.fit_transform(a) # 对Amount列数据进行标准化
- data = data.drop(['Time'], axis=1) # 删除无用列
-
- # 随机取数据 小数据集
- from sklearn.model_selection import train_test_split
-
- x = data.drop('Class', axis=1)
- y = data.Class
- x_w_train, x_w_test, y_w_train, y_w_test = \
- train_test_split(x, y, test_size=0.2, random_state=0) # 随机取数据
- """过采样"""
- from imblearn.over_sampling import SMOTE
-
- oversampler = SMOTE(random_state=0) # 随机种子 保证数据拟合效果
- x_os, y_os = oversampler.fit_resample(x_w_train, y_w_train) # 通过原始训练集的特征和标签数据人工拟合一份训练集和标签
-
- # 绘制条形图 查看样本个数
- plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置字体
- plt.rcParams['axes.unicode_minus'] = False # 解决符号显示为方块的问题
- labels_count = pd.value_counts(y_os) # 统计0有多少个数据,1有多个数据
- plt.title("正负例样本数")
- plt.xlabel("类别")
- plt.ylabel("频数")
- labels_count.plot(kind='bar') # 生成一个条形图,展示每个类别的样本数量。
- plt.show()
-
- x_os_train, x_os_test, y_os_train, y_os_test = \
- train_test_split(x_os, y_os, test_size=0.2, random_state=0) # 随机取数据
输出:
- # 交叉验证选择较优惩罚因子 λ
- from sklearn.model_selection import cross_val_score # 交叉验证的函数
- from sklearn.linear_model import LogisticRegression
-
- # k折交叉验证选择C参数
- scores = []
- c_param_range = [0.01, 0.1, 1, 10, 100] # 待选C参数
- for i in c_param_range:
- lr = LogisticRegression(C=i, penalty='l2', solver='lbfgs', max_iter=1000) # 创建逻辑回归模型 lbfgs 拟牛顿法
- score = cross_val_score(lr, x_os_train, y_os_train, cv=8, scoring='recall') # k折交叉验证 比较召回率
- score_mean = sum(score) / len(score)
- scores.append(score_mean)
- print(score_mean)
-
- best_c = c_param_range[np.argmax(scores)] # 寻找到scores中最大值的对应的C参数
- print(f"最优惩罚因子为:{best_c}")
-
- # 建立最优模型
- lr = LogisticRegression(C=best_c, penalty='l2', max_iter=1000)
- lr.fit(x_os_train, y_os_train)
输出:
- 0.9096726221315528
- 0.9106337846987276
- 0.9109523409608787
- 0.9110237415273612
- 0.9110182489533213
- 最优惩罚因子为:10
- # 绘制混淆矩阵
- from sklearn import metrics
-
- x_os_train_predicted = lr.predict(x_os_train) # 训练集特征数据x的预测值
- print(metrics.classification_report(y_os_train, x_os_train_predicted)) # 传入训练集真实的结果数据 与预测值组成矩阵
-
- x_os_test_predicted = lr.predict(x_os_test) # 训练集特征数据x的预测值
- print(metrics.classification_report(y_os_test, x_os_test_predicted)) # 传入训练集真实的结果数据 与预测值组成矩阵
-
- x_w_test_predicted = lr.predict(x_w_test)
- print(metrics.classification_report(y_w_test, x_w_test_predicted))
输出:
- precision recall f1-score support
-
- 0 0.92 0.98 0.94 181855
- 1 0.97 0.91 0.94 182071
-
- accuracy 0.94 363926
- macro avg 0.94 0.94 0.94 363926
- weighted avg 0.94 0.94 0.94 363926
-
- precision recall f1-score support
-
- 0 0.92 0.98 0.95 45599
- 1 0.97 0.91 0.94 45383
-
- accuracy 0.94 90982
- macro avg 0.95 0.94 0.94 90982
- weighted avg 0.94 0.94 0.94 90982
-
- precision recall f1-score support
-
- 0 1.00 0.98 0.99 56861
- 1 0.06 0.94 0.12 101
-
- accuracy 0.98 56962
- macro avg 0.53 0.96 0.55 56962
- weighted avg 1.00 0.98 0.99 56962
过采样适合不同类别数据不均衡的情况,下采样虽然也适合,但是一般情况下过采样要更加优秀