• 机器学习:逻辑回归--过采样


    目录

    前言

    一、为什么使用过采样?

    二、代码实现

    1.完整代码

    2.数据预处理

    3.进行过采样

    4.建立模型

    5.绘制混淆矩阵

    总结


    前言

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

     

    一、为什么使用过采样?

    • 当不同类别的数据量不均衡时

     

    • 这会导致某一类别的正确率很低

     

    • 这时可以使用过采样方法:
      • 先分出训练集和测试集
      • 使用过采样方法拟合类别少的数据
      • 使两种类型的数据均衡

     

    • 此时结果不同类别的正确率将会得到提高

     

    二、代码实现

    1.完整代码

    1. import pandas as pd
    2. import matplotlib.pyplot as plt
    3. import numpy as np
    4. # 可视化混淆矩阵
    5. def cm_plot(y, yp):
    6. from sklearn.metrics import confusion_matrix
    7. import matplotlib.pyplot as plt
    8. cm = confusion_matrix(y, yp)
    9. plt.matshow(cm, cmap=plt.cm.Blues)
    10. plt.colorbar()
    11. for x in range(len(cm)):
    12. for y in range(len(cm)):
    13. plt.annotate(cm[x, y], xy=(y, x), horizontalalignment='center',
    14. verticalalignment='center')
    15. plt.ylabel('True label')
    16. plt.xlabel('Predicted label')
    17. return plt
    18. data = pd.read_csv("creditcard.csv")
    19. # 数据标准化: Z标准化
    20. from sklearn.preprocessing import StandardScaler # 可对多列进行标准化
    21. scaler = StandardScaler()
    22. a = data[['Amount']] # 取出来变成df数据 因为fit_transform()需要传入df数据
    23. data['Amount'] = scaler.fit_transform(a) # 对Amount列数据进行标准化
    24. data = data.drop(['Time'], axis=1) # 删除无用列
    25. # 随机取数据 小数据集
    26. from sklearn.model_selection import train_test_split
    27. x = data.drop('Class', axis=1)
    28. y = data.Class
    29. x_w_train, x_w_test, y_w_train, y_w_test = \
    30. train_test_split(x, y, test_size=0.2, random_state=0) # 随机取数据
    31. """过采样"""
    32. from imblearn.over_sampling import SMOTE
    33. oversampler = SMOTE(random_state=0) # 随机种子 保证数据拟合效果
    34. x_os, y_os = oversampler.fit_resample(x_w_train, y_w_train) # 通过原始训练集的特征和标签数据人工拟合一份训练集和标签
    35. # 绘制条形图 查看样本个数
    36. plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置字体
    37. plt.rcParams['axes.unicode_minus'] = False # 解决符号显示为方块的问题
    38. labels_count = pd.value_counts(y_os) # 统计0有多少个数据,1有多个数据
    39. plt.title("正负例样本数")
    40. plt.xlabel("类别")
    41. plt.ylabel("频数")
    42. labels_count.plot(kind='bar') # 生成一个条形图,展示每个类别的样本数量。
    43. plt.show()
    44. x_os_train, x_os_test, y_os_train, y_os_test = \
    45. train_test_split(x_os, y_os, test_size=0.2, random_state=0) # 随机取数据
    46. # 交叉验证选择较优惩罚因子 λ
    47. from sklearn.model_selection import cross_val_score # 交叉验证的函数
    48. from sklearn.linear_model import LogisticRegression
    49. # k折交叉验证选择C参数
    50. scores = []
    51. c_param_range = [0.01, 0.1, 1, 10, 100] # 待选C参数
    52. for i in c_param_range:
    53. lr = LogisticRegression(C=i, penalty='l2', solver='lbfgs', max_iter=1000) # 创建逻辑回归模型 lbfgs 拟牛顿法
    54. score = cross_val_score(lr, x_os_train, y_os_train, cv=8, scoring='recall') # k折交叉验证 比较召回率
    55. score_mean = sum(score) / len(score)
    56. scores.append(score_mean)
    57. print(score_mean)
    58. best_c = c_param_range[np.argmax(scores)] # 寻找到scores中最大值的对应的C参数
    59. print(f"最优惩罚因子为:{best_c}")
    60. # 建立最优模型
    61. lr = LogisticRegression(C=best_c, penalty='l2', max_iter=1000)
    62. lr.fit(x_os_train, y_os_train)
    63. # 绘制混淆矩阵
    64. from sklearn import metrics
    65. x_os_train_predicted = lr.predict(x_os_train) # 训练集特征数据x的预测值
    66. print(metrics.classification_report(y_os_train, x_os_train_predicted)) # 传入训练集真实的结果数据 与预测值组成矩阵
    67. x_os_test_predicted = lr.predict(x_os_test) # 训练集特征数据x的预测值
    68. print(metrics.classification_report(y_os_test, x_os_test_predicted)) # 传入训练集真实的结果数据 与预测值组成矩阵
    69. x_w_test_predicted = lr.predict(x_w_test)
    70. print(metrics.classification_report(y_w_test, x_w_test_predicted))

     

    2.数据预处理

    • 导入数据
    • 对特征进行标准化
    • 随机取出训练集和测试集
    1. import pandas as pd
    2. import matplotlib.pyplot as plt
    3. import numpy as np
    4. data = pd.read_csv("creditcard.csv")
    5. # 数据标准化: Z标准化
    6. from sklearn.preprocessing import StandardScaler # 可对多列进行标准化
    7. scaler = StandardScaler()
    8. a = data[['Amount']] # 取出来变成df数据 因为fit_transform()需要传入df数据
    9. data['Amount'] = scaler.fit_transform(a) # 对Amount列数据进行标准化
    10. data = data.drop(['Time'], axis=1) # 删除无用列
    11. # 随机取数据 小数据集
    12. from sklearn.model_selection import train_test_split
    13. x = data.drop('Class', axis=1)
    14. y = data.Class
    15. x_w_train, x_w_test, y_w_train, y_w_test = \
    16. train_test_split(x, y, test_size=0.2, random_state=0) # 随机取数据

     

    3.进行过采样

    • 使用over_sampling 里的SMOTE模块
    • 对训练集数据进行过采样,拟合数据
    • 查看拟合之后的数据集
    • 从该数据集中分出训练集和测试集
    1. """过采样"""
    2. from imblearn.over_sampling import SMOTE
    3. oversampler = SMOTE(random_state=0) # 随机种子 保证数据拟合效果
    4. x_os, y_os = oversampler.fit_resample(x_w_train, y_w_train) # 通过原始训练集的特征和标签数据人工拟合一份训练集和标签
    5. # 绘制条形图 查看样本个数
    6. plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置字体
    7. plt.rcParams['axes.unicode_minus'] = False # 解决符号显示为方块的问题
    8. labels_count = pd.value_counts(y_os) # 统计0有多少个数据,1有多个数据
    9. plt.title("正负例样本数")
    10. plt.xlabel("类别")
    11. plt.ylabel("频数")
    12. labels_count.plot(kind='bar') # 生成一个条形图,展示每个类别的样本数量。
    13. plt.show()
    14. x_os_train, x_os_test, y_os_train, y_os_test = \
    15. train_test_split(x_os, y_os, test_size=0.2, random_state=0) # 随机取数据

    输出:

     

    4.建立模型

    • 使用k折交叉验证法选出最佳的C参数
    • 训练所使用的数据是从拟合数据里取出来的训练集
    • 建立最优模型
    1. # 交叉验证选择较优惩罚因子 λ
    2. from sklearn.model_selection import cross_val_score # 交叉验证的函数
    3. from sklearn.linear_model import LogisticRegression
    4. # k折交叉验证选择C参数
    5. scores = []
    6. c_param_range = [0.01, 0.1, 1, 10, 100] # 待选C参数
    7. for i in c_param_range:
    8. lr = LogisticRegression(C=i, penalty='l2', solver='lbfgs', max_iter=1000) # 创建逻辑回归模型 lbfgs 拟牛顿法
    9. score = cross_val_score(lr, x_os_train, y_os_train, cv=8, scoring='recall') # k折交叉验证 比较召回率
    10. score_mean = sum(score) / len(score)
    11. scores.append(score_mean)
    12. print(score_mean)
    13. best_c = c_param_range[np.argmax(scores)] # 寻找到scores中最大值的对应的C参数
    14. print(f"最优惩罚因子为:{best_c}")
    15. # 建立最优模型
    16. lr = LogisticRegression(C=best_c, penalty='l2', max_iter=1000)
    17. lr.fit(x_os_train, y_os_train)

    输出:

    1. 0.9096726221315528
    2. 0.9106337846987276
    3. 0.9109523409608787
    4. 0.9110237415273612
    5. 0.9110182489533213
    6. 最优惩罚因子为:10

     

    5.绘制混淆矩阵

    • 分别使用原始数据里取出来的测试集,拟合数据里取出来的训练集和测试集进行混淆矩阵的绘制
    1. # 绘制混淆矩阵
    2. from sklearn import metrics
    3. x_os_train_predicted = lr.predict(x_os_train) # 训练集特征数据x的预测值
    4. print(metrics.classification_report(y_os_train, x_os_train_predicted)) # 传入训练集真实的结果数据 与预测值组成矩阵
    5. x_os_test_predicted = lr.predict(x_os_test) # 训练集特征数据x的预测值
    6. print(metrics.classification_report(y_os_test, x_os_test_predicted)) # 传入训练集真实的结果数据 与预测值组成矩阵
    7. x_w_test_predicted = lr.predict(x_w_test)
    8. print(metrics.classification_report(y_w_test, x_w_test_predicted))

    输出:

    1. precision recall f1-score support
    2. 0 0.92 0.98 0.94 181855
    3. 1 0.97 0.91 0.94 182071
    4. accuracy 0.94 363926
    5. macro avg 0.94 0.94 0.94 363926
    6. weighted avg 0.94 0.94 0.94 363926
    7. precision recall f1-score support
    8. 0 0.92 0.98 0.95 45599
    9. 1 0.97 0.91 0.94 45383
    10. accuracy 0.94 90982
    11. macro avg 0.95 0.94 0.94 90982
    12. weighted avg 0.94 0.94 0.94 90982
    13. precision recall f1-score support
    14. 0 1.00 0.98 0.99 56861
    15. 1 0.06 0.94 0.12 101
    16. accuracy 0.98 56962
    17. macro avg 0.53 0.96 0.55 56962
    18. weighted avg 1.00 0.98 0.99 56962

     

    总结

            过采样适合不同类别数据不均衡的情况,下采样虽然也适合,但是一般情况下过采样要更加优秀

  • 相关阅读:
    通过浏览器F12开发者工具的javascript控制台给Vue表单赋值
    Go :测试涉及NaN的浮点比较(附完整源码)
    JavaWeb初学项目的问题排查思路
    Android Sensor调试
    “蔚来杯“2022牛客暑期多校训练营8 D题: Poker Game: Decision
    土地利用程度综合指数计算/argis教程
    Vue的快速入门(01)
    Django-可重用注册登录系统--项目搭建
    Python Requests 丨爬虫基础入门
    自制快速冒烟测试小工具--基于python多线程
  • 原文地址:https://blog.csdn.net/weixin_65047977/article/details/142185282