• 机器学习复习(8)——逻辑回归


    1. ### numpy版本为1.20.3
    2. import numpy as np
    3. ### 定义sigmoid函数
    4. def sigmoid(x):
    5. z = 1 / (1 + np.exp(-x))
    6. return z
    7. # 定义参数初始化函数
    8. def initialize_params(dims):
    9. W = np.zeros((dims, 1))#初始化W为0
    10. b = 0
    11. return W, b
    1. X: 输入特征矩阵,大小为 m×n,其中 m 是样本数量,n 是特征数量。
    2. y: 输出标签向量,大小为 m×1,包含每个样本的真实标签(0或1)。
    3. W: 权值参数,大小为 n×1,代表特征权重。
    4. b: 偏置参数,是一个标量,代表模型的偏置项。

     

    1. ### 定义对数几率回归模型主体
    2. def logistic(X, y, W, b):
    3. '''
    4. 输入:
    5. X: 输入特征矩阵
    6. y: 输出标签向量
    7. W: 权值参数
    8. b: 偏置参数
    9. 输出:
    10. a: 逻辑回归模型输出
    11. cost: 损失
    12. dW: 权值梯度
    13. db: 偏置梯度
    14. '''
    15. # 训练样本量
    16. num_train = X.shape[0]
    17. # 训练特征数
    18. num_feature = X.shape[1]
    19. # 逻辑回归模型输出
    20. a = sigmoid(np.dot(X, W) + b)
    21. # 交叉熵损失
    22. cost = -1/num_train * np.sum(y*np.log(a) + (1-y)*np.log(1-a))
    23. # 权值梯度
    24. dW = np.dot(X.T, (a-y))/num_train#dot()函数是矩阵乘法,eg:[n,m]@[m,p]=[n,p]
    25. # 偏置梯度
    26. db = np.sum(a-y)/num_train
    27. # 压缩损失数组维度
    28. cost = np.squeeze(cost) #压缩损失值的维度,以确保输出的损失值是一个标量而不是一个数组。例如:[[3.]]变成了3.0
    29. return a, cost, dW, db#返回逻辑回归模型输出、损失、权值梯度、偏置梯度

     

    • 模型输出(a)的计算:使用sigmoid函数作为激活函数,计算模型的输出。公式为 a=\sigma(XW+b),其中 σ 是sigmoid函数,它将线性回归输出转换为概率值(介于0和1之间)。

    • 交叉熵损失(cost)的计算:使用交叉熵损失函数来衡量模型预测值与真实值之间的差异。对于二分类问题,交叉熵损失的公式为 -\frac1m\sum_{i=1}^m[y^{(i)}\log(a^{(i)})+(1-y^{(i)})\log(1-a^{(i)})],其中 m 是样本数量。这个损失函数针对每个样本计算预测值与实际值的差异,然后取平均值。

    • 权值梯度(dW)和偏置梯度(db)的计算:这两个梯度用于根据损失函数的梯度下降法更新权值和偏置。权值梯度计算公式为 dW=\frac1mX^T(a-y),偏置梯度计算公式为 db=\frac1m\sum_{i=1}^m(a^{(i)}-y^{(i)})。这里,X^{T}是特征矩阵的转置,确保梯度与权重矩阵的维度一致。

    • 损失压缩:最后,使用 np.squeeze(cost) 压缩损失值的维度,以确保输出的损失值是一个标量而不是一个数组。

    1. ### 定义对数几率回归模型训练过程
    2. def logistic_train(X, y, learning_rate, epochs):
    3. '''
    4. 输入:
    5. X: 输入特征矩阵
    6. y: 输出标签向量
    7. learning_rate: 学习率
    8. epochs: 训练轮数
    9. 输出:
    10. cost_list: 损失列表
    11. params: 模型参数
    12. grads: 参数梯度
    13. '''
    14. # 初始化模型参数
    15. W, b = initialize_params(X.shape[1]) #X.shape[1]表示特征数
    16. # 初始化损失列表
    17. cost_list = []
    18. # 迭代训练
    19. for i in range(epochs):
    20. # 计算当前次的模型计算结果、损失和参数梯度
    21. a, cost, dW, db = logistic(X, y, W, b)
    22. # 参数更新
    23. W = W -learning_rate * dW
    24. b = b -learning_rate * db
    25. # 记录损失
    26. if i % 100 == 0:
    27. cost_list.append(cost)
    28. # 打印训练过程中的损失
    29. if i % 100 == 0:
    30. print('epoch %d cost %f' % (i, cost))
    31. # 保存参数
    32. params = {
    33. 'W': W,
    34. 'b': b
    35. }
    36. # 保存梯度
    37. grads = {
    38. 'dW': dW,
    39. 'db': db
    40. }
    41. return cost_list, params, grads
    1. ### 定义预测函数
    2. def predict(X, params):
    3. '''
    4. 输入:
    5. X: 输入特征矩阵
    6. params: 训练好的模型参数
    7. 输出:
    8. y_prediction: 转换后的模型预测值
    9. '''
    10. # 模型预测值
    11. y_prediction = sigmoid(np.dot(X, params['W']) + params['b'])#模型预测值
    12. # 基于分类阈值对概率预测值进行类别转换
    13. for i in range(len(y_prediction)):
    14. if y_prediction[i] > 0.5:
    15. y_prediction[i] = 1
    16. else:
    17. y_prediction[i] = 0
    18. return y_prediction

     

    输入参数

    1. X: 输入特征矩阵,大小m×n,其中 m 是样本数量,n 是特征数量。这代表要进行预测的新数据集。
    2. params: 训练好的模型参数,是一个字典,包含了权重 W 和偏置 b。其中,W 是权值参数,大小为 n×1,而 b 是偏置参数,是一个标量。

    输出参数

    • y_prediction: 转换后的模型预测值,是一个大小为 m×1 的向量,包含了对每个样本的二分类预测结果(0或1)。
    • 模型预测值的计算:首先,函数使用sigmoid函数计算模型的预测概率。这一步是通过对输入特征矩阵 X 和模型参数 W 进行矩阵乘法,然后加上偏置 b,并将结果通过sigmoid函数转换为概率值。计算公式为y_{\text{prediction}}= \sigma ( X W + b ) ,其中 σ 是sigmoid函数。

    • 概率到分类的转换:接下来,函数遍历预测概率向量 y_{\text{prediction}},将每个概率值与分类阈值(通常为0.5)进行比较。如果概率值大于0.5,则将该样本的预测类别设置为1(表示属于正类);如果概率值小于或等于0.5,则将预测类别设置为0(表示属于负类)。这个步骤将连续的概率预测转换为明确的类别预测,便于后续的分类任务。

    • 返回预测结果:最后,函数返回转换后的预测值 y_{\text{prediction}}

    1. # 导入matplotlib绘图库
    2. import matplotlib.pyplot as plt
    3. # 导入生成分类数据函数
    4. # from sklearn.datasets.samples_generator import make_classification
    5. from sklearn.datasets import make_classification
    6. # 生成100*2的模拟二分类数据集
    7. X, labels = make_classification(
    8. n_samples=100,
    9. n_features=2,
    10. n_redundant=0,
    11. n_informative=2,
    12. random_state=1,
    13. n_clusters_per_class=2)
    14. # 设置随机数种子
    15. rng = np.random.RandomState(2)
    16. # 对生成的特征数据添加一组均匀分布噪声
    17. X += 2 * rng.uniform(size=X.shape)
    18. # 标签类别数
    19. unique_lables = set(labels)
    20. # 根据标签类别数设置颜色
    21. colors = plt.cm.Spectral(np.linspace(0,1,len(unique_lables)))
    22. # 绘制模拟数据的散点图
    23. for k,col in zip(unique_lables, colors):
    24. x_k=X[labels==k]
    25. plt.plot(x_k[:,0],x_k[:,1],'o',markerfacecolor=col,markeredgecolor="k",
    26. markersize=14)
    27. plt.title('Simulated binary data set')
    28. plt.show();

     

    1. print(X.shape, labels.shape)
    2. labels = labels.reshape((-1, 1))
    3. data = np.concatenate((X, labels), axis=1)
    4. print(data.shape)
    5. # 训练集与测试集的简单划分
    6. offset = int(X.shape[0] * 0.9)
    7. X_train, y_train = X[:offset], labels[:offset]
    8. X_test, y_test = X[offset:], labels[offset:]
    9. y_train = y_train.reshape((-1,1))
    10. y_test = y_test.reshape((-1,1))
    11. print('X_train=', X_train.shape)
    12. print('X_test=', X_test.shape)
    13. print('y_train=', y_train.shape)
    14. print('y_test=', y_test.shape)
    15. cost_list, params, grads = logistic_train(X_train, y_train, 0.01, 1000)
    16. y_pred = predict(X_test, params)
    17. print(y_pred)
    18. sigmoid(np.dot(X_test, params['W']) + params['b'])
    19. from sklearn.metrics import accuracy_score, classification_report
    20. # print(accuracy_score(y_test, y_pred))
    21. print(classification_report(y_test, y_pred))
    22. def accuracy(y_test, y_pred):
    23. correct_count = 0
    24. for i in range(len(y_test)):
    25. for j in range(len(y_pred)):
    26. if y_test[i] == y_pred[j] and i == j:
    27. correct_count +=1
    28. accuracy_score = correct_count / len(y_test)
    29. return accuracy_score
    30. accuracy_score_test = accuracy(y_test, y_pred)
    31. print(accuracy_score_test)
    32. y_train_pred = predict(X_train, params)
    33. accuracy_score_train = accuracy(y_train, y_train_pred)
    34. print(accuracy_score_train)
    35. ### 绘制逻辑回归决策边界
    36. def plot_decision_boundary(X_train, y_train, params):
    37. '''
    38. 输入:
    39. X_train: 训练集输入
    40. y_train: 训练集标签
    41. params:训练好的模型参数
    42. 输出:
    43. 决策边界图
    44. '''
    45. # 训练样本量
    46. n = X_train.shape[0]
    47. # 初始化类别坐标点列表
    48. xcord1 = []
    49. ycord1 = []
    50. xcord2 = []
    51. ycord2 = []
    52. # 获取两类坐标点并存入列表
    53. for i in range(n):
    54. if y_train[i] == 1:
    55. xcord1.append(X_train[i][0])
    56. ycord1.append(X_train[i][1])
    57. else:
    58. xcord2.append(X_train[i][0])
    59. ycord2.append(X_train[i][1])
    60. # 创建绘图
    61. fig = plt.figure()
    62. ax = fig.add_subplot(111)
    63. # 绘制两类散点,以不同颜色表示
    64. ax.scatter(xcord1, ycord1,s=32, c='red')
    65. ax.scatter(xcord2, ycord2, s=32, c='green')
    66. # 取值范围
    67. x = np.arange(-1.5, 3, 0.1)
    68. # 决策边界公式
    69. y = (-params['b'] - params['W'][0] * x) / params['W'][1]
    70. # 绘图
    71. ax.plot(x, y)
    72. plt.xlabel('X1')
    73. plt.ylabel('X2')
    74. plt.show()
    75. plot_decision_boundary(X_train, y_train, params)
    76. from sklearn.linear_model import LogisticRegression
    77. clf = LogisticRegression(random_state=0).fit(X_train, y_train)
    78. y_pred = clf.predict(X_test)
    79. print(classification_report(y_test, y_pred))

  • 相关阅读:
    安全物理环境(设备和技术注解)
    1990-2021年上市公司债务融资成本数据(原始数据+stata处理代码+计算结果)
    [附源码]计算机毕业设计JAVA 宠物医院管理系统
    shell循环语句
    软件版本号详解
    基于MobileNet的轻量级卷积神经网络实现玉米螟虫不同阶段识别分析
    JavaScript垃圾回收机制
    「开源系统」mybatis-plus代码生成工具(自己基于官方的封装的,打包成了maven插件的方式)
    Angular 由一个bug说起之四:jsonEditor使用不当造成的bug
    记:谷歌开发者大会2022——共码未来
  • 原文地址:https://blog.csdn.net/xty123abc/article/details/136422886