机器学习练习题3.3编程实现对率回归

参考代码

版权声明:参考代码为博主huzimu_原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/huzimu_/article/details/123760239

########################################################################我做了什么?

对代码进行部分修改并注解,将查询到的代码解释以及链接附上,从0学习记录

########################################################################

代码、结果、csv

import numpy as np
import pandas as pd

import matplotlib.pyplot as plt




from sklearn import linear_model


# Sigmoid 函数 p58 形似S的连续函数
def sigmoid(s):
    s = 1 / (1 + np.exp(-s))  #3.17
    return s
# 3.27
def J_cost(X, y, beta):
    """

    :param X: array , shape(num_sample, num_features)
    :param y: array, shape(num_sample, 1)
    :param beta: array, shape(num_features+1, 1)
    :return: 公式3.27的结果,即对数似然相反数的值
    """
    X_hat = np.c_[X, np.ones((X.shape[0], 1))]  # 公式3.9上方矩阵
    # mp.c_ 用于连接两个矩阵 https://blog.csdn.net/qq_33728095/article/details/102512600
    # ones函数用于创建指定长度或形状的全1数组,np.ones(3,1) 创建三行一列的全1数组 https://blog.csdn.net/weixin_44884379/article/details/112171669
    # shape[0]读取矩阵第一维度的长度,即数组的行数 https://blog.csdn.net/wzk4869/article/details/126022909
    y = y.reshape(-1, 1)  # 改成m行n列的矩阵格式,-1表示自动计算行或列数  https://blog.csdn.net/a8039974/article/details/119925040?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167774109816782427446849%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=167774109816782427446849&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-119925040-null-null.142^v73^insert_down4,201^v4^add_ask,239^v2^insert_chatgpt&utm_term=reshape&spm=1018.2226.3001.4187
    beta = beta.reshape(-1, 1)
    lbeta = -y*np.dot(X_hat, beta) + np.log(1 + np.exp(np.dot(X_hat, beta)))
    # np.dot响亮的点积和矩阵乘法 https://blog.csdn.net/Liang_xj/article/details/85003467?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167773576816800192253961%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=167773576816800192253961&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-85003467-null-null.142^v73^insert_down4,201^v4^add_ask,239^v2^insert_chatgpt&utm_term=np.dot&spm=1018.2226.3001.4187
    return lbeta.sum()

# 公式3.30 beta的一阶导数


def gradient(X, y, beta):
    """

    :param X:
    :param y:
    :param beta:
    :return:
    """
    X_hat = np.c_[X, np.ones((X.shape[0], 1))]
    y = y.reshape(-1, 1)
    beta = beta.reshape(-1, 1)
    p1 = np.exp(np.dot(X_hat, beta)) / (1 + np.exp(np.dot(X_hat, beta)))
    grad = (-X_hat*(y-p1)).sum(0)
    # sum(0) 每一列求和 https://blog.csdn.net/maple05/article/details/107943144?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-107943144-blog-118693790.pc_relevant_3mothn_strategy_recovery&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-107943144-blog-118693790.pc_relevant_3mothn_strategy_recovery&utm_relevant_index=2
    return grad.reshape(-1, 1)

# 梯度下降,更新beta


def update_parameters_gradDesc(X, y, beta, learning_rate, num_iterations, print_cost):
    """

    :param X:
    :param y:
    :param beta:
    :param learning_rate:
    :param num_iterations:
    :param print_cost:
    :return:
    """
    for i in range(num_iterations):
        grad = gradient(X, y, beta)
        beta -= learning_rate * grad

        if (i % 100 == 0) & print_cost:
            print('{}th iteration, cost is {}'.format(i, J_cost(X, y, beta)))
    return beta

# 牛顿法,海森因矩阵


def hessian(X, y, beta):
    """
    根据公式3.31求lbeta二阶导
    :param X:
    :param y:
    :param beta:
    :return:
    """
    X_hat = np.c_[X, np.ones((X.shape[0], 1))]
    y = y.reshape(-1, 1)
    beta = beta.reshape(-1, 1)
    p1 = np.exp(np.dot(X_hat, beta)) / (1 + np.exp(np.dot(X_hat, beta)))
    m, n = X.shape
    P = np.eye(m) * p1 * (1 - p1)  # np.eye(m)为单位阵,P为方阵
    assert P.shape[0] == P.shape[1]  # assert断言函数,为真继续执行,为假报错 https://blog.csdn.net/weixin_61561736/article/details/124886522?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167774221816782425188373%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=167774221816782425188373&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-124886522-null-null.142^v73^insert_down4,201^v4^add_ask,239^v2^insert_chatgpt&utm_term=assert&spm=1018.2226.3001.4187
    hess = np.dot(np.dot(X_hat.T, P), X_hat)  # .T 转置
    return hess

# 牛顿法更新参数


def update_parameter_Newton(X, y, beta, num_iterations, print_cost):
    """
    根据公式3.29更新beta
    :param X:
    :param y:
    :param beta:
    :param num_iterations:
    :param print_cost:
    :return:
    """
    for i in range(num_iterations):
        grad = gradient(X, y, beta)
        hess = hessian(X, y, beta)
        beta -= np.dot(np.linalg.inv(hess), grad)  # np.linalg.inv矩阵求逆

        if (i % 100 == 0) & print_cost:
            print('{}th iteration, cost is {}'.format(i, J_cost(X, y, beta)))
    return beta

# 初始化beta


def initialize_beta(n):
    beta = np.random.randn(n + 1, 1) * 0.5 + 1
    # randn产生的样本符合正态分布 https://blog.csdn.net/u012149181/article/details/78913167?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167774570616800222825721%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=167774570616800222825721&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-78913167-null-null.142^v73^insert_down4,201^v4^add_ask,239^v2^insert_chatgpt&utm_term=np.random.randn&spm=1018.2226.3001.4187
    return beta

# 对数几率模型


def logistic_beta(X, y, num_interation=100, learning_rate=1.2, print_cost=False, method='gradDesc'):
    """

    :param X: array shape(num_sample, num_feature)
    :param y:
    :param num_interation: 迭代次数
    :param learning_rate: 学习率
    :param print_cost: 是否打印对数似然相反数
    :param method: 所用方法
    :return:
    """
    m, n = X.shape
    beta = initialize_beta(n)

    if method == 'gradDesc':
        return update_parameters_gradDesc(X, y, beta, learning_rate, num_interation, print_cost)
    elif method == 'Newton':
        return update_parameter_Newton(X, y, beta, num_interation, print_cost)
    else:
        return ValueError('Unknown error of %s' % method)

#预测


def predict(X, beta):
    X_hat = np.c_[X, np.ones((X.shape[0], 1))]
    beta.reshape(-1, 1)
    p1 = np.exp(np.dot(X_hat, beta)) / (1 + np.exp(np.dot(X_hat, beta)))
    p1[p1 > 0.5] = 1
    p1[p1 <= 0.5] = 0
    temp = np.c_[X, p1]
    print(temp)
    return p1

if __name__ == '__main__':
    data_path = r'G:\pythonProject\machinelearning\watermelon3.csv'
    # 加载数据
    data = pd.read_csv(data_path, encoding='ISO-8859-1').values
    # print(data)
    is_good = data[:, 2] == 'yes'  # : 表示全部行的数据 9-第九列
    is_bad = data[:, 2] == 'no'
    # 7,8列数据,密度、含糖量
    X = data[:, 0:2].astype(float)
    y = data[:, 2]
    y[y == 'yes'] = 1
    y[y == 'no'] = 0
    y = y.astype(int)

    # 绘图:密度为行,含糖量为列,好瓜为黑圈,坏瓜为红x
    plt.scatter(data[:, 0][is_good], data[:, 1][is_good], c='k', marker='o')
    plt.scatter(data[:, 0][is_bad], data[:, 1][is_bad], c='r', marker='x')

    plt.xlabel('density')
    plt.ylabel('sugar')

    # 可视化模型结果gradDesc
    beta = logistic_beta(X, y, num_interation=1000, learning_rate=2, print_cost=True, method='gradDesc')
    w1, w2, intercept = beta
    #预测结果
    predict(X, beta)
    x1 = np.linspace(0, 1)
    # 创建数值序列 https://blog.csdn.net/neweastsun/article/details/99676029?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167774351316800215063759%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=167774351316800215063759&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-99676029-null-null.142^v73^insert_down4,201^v4^add_ask,239^v2^insert_chatgpt&utm_term=np.linspace&spm=1018.2226.3001.4187
    y1 = -(w1 * x1 + intercept) / w2
    plt.plot(x1, y1, label=r'my_logistic_gradDesc')

    # 可视化模型结果gradDesc
    beta = logistic_beta(X, y, num_interation=1000, learning_rate=2, print_cost=True, method='Newton')
    w1, w2, intercept = beta
    #预测结果
    predict(X, beta)
    x1 = np.linspace(0, 1)
    y1 = -(w1 * x1 + intercept) / w2
    plt.plot(x1, y1, label=r'my_logistic_Newton')

    # # 可视化sklearn Logistic regression 模型结果
    # # 注意sklearn的逻辑回归中,C越大表示正则化程度越低
    # Ir = linear_model.LogisticRegression(solver='lbfgs', c=100)
    # Ir.fit(X,y)
    #
    # Ir_beta = np.c_[Ir.coef_, Ir.intercept_]
    # print('cost of sklearn logistic: {}'.format(J_cost(X, y, beta)))
    #
    # w1_sk, w2_sk = Ir.coef_[0, :]
    #
    # x2 = np.linspace(0, 1)
    # y2 = -(w1_sk * x2 + Ir.intercept_) / w2_sk
    #
    # plt.plot(x2, y2, label=r'sklearn logistic')

    plt.legend(loc='upper right')  # 图例位置
    plt.show()

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值