吴恩达机器学习-编程练习-ex2.2

本文介绍了如何在Python中实现Sigmoid函数、逻辑回归的代价函数和梯度,以及模拟MATLAB的fminunc优化函数。通过代码实践,得出决策边界的参数,并展示了最终结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.实现sigmoid function
在开始练习实际的代价函数之前,我们先回顾一下logistic的基本假设和Sigmoid函数:
在这里插入图片描述

函数G即Sigmoid函数,这个Sigmoid函数的形式是:

在这里插入图片描述

然后我们在python中实现一下这个算法,令这个算法对单值和矩阵都生效

python中实现sigmoid函数:

import numpy as np

def sigmoid(x):
    y = 1/(1+np.exp(-x))
    return y

if __name__ == '__main__':
    # x = 0
    x = np.array([1,3,2,0])
    s = sigmoid(x)
    print(s)

输出

[0.73105858 0.95257413 0.88079708 0.5 ]

2.代价函数和梯度

我们先回顾一下代价函数的形式:
在这里插入图片描述
而代价函数的梯度是一个有相同θ的向量:
在这里插入图片描述
接下来我们在python中实现这两个函数,先上结果代码

import numpy as np
import sigmoid

def costFunction(theta,x,y):
    m = len(y)
    #直接用*连接两个矩阵会报错,所以我们使用numpy中的矩阵乘法函数matmul
    matmul = np.matmul(x,theta)
    h = sigmoid.sigmoid(matmul)
    #代价函数的python翻译,注意,这里原式是级数求和,但矩阵乘法的本质就是对应元素求和,所以这里矩阵相乘就相当于是矩阵求和
    #另外,注意matlab中y'相当于是y求转置,所以翻译成python就是y.T
    J = (1/m)*((np.matmul(-y.T,np.log(h))-np.matmul((1-y).T,np.log(1-h))))
    grad = (1 / m) * np.matmul(x.T,h-y)
    return J,grad

#调用数据进行验证
if __name__ == '__main__':
    path = 'C:\\Users\Administrator\PycharmProjects\Clear\ml\ex2\ex2data1.txt'
    df = np.genfromtxt(path,delimiter=',')
    #这里注意,在array中取某列采用的形式是0:2或者2:3,如果只用2取一列的话会出问题(取的是1维矩阵,另一种方法取的是2维矩阵)
    x = df[:,0:2]
    y = df[:,2:3]
    #给出矩阵的大小
    [m, n] = np.shape(x)
    #生成全1矩阵
    ones = np.ones((m,1))
    #横向拼接矩阵
    x = np.hstack((ones,x))
    #生成全0矩阵
    theta = np.zeros((3,1))
    [cost, grad] = costFunction(theta, x, y)
    print(cost,grad)

将matlab中的代码在python中实现,可以说是踩了不少坑。

需要注意的是,import sigmoid是我们刚刚写好的sigmoid function,在这里被调用。

3.模拟matlab中的fminunc优化函数

Octave / MATLAB的fminunc是一个优化求解器,可以找到无约束函数的最小值。 对于逻辑回归,我们希望使用参数θ优化成本函数J(θ)

这里偷了个懒,直接在网上找到前人的足迹,说scipy中的minimize可以进行替代。同时,该函数的参数theta一定需要是一个一维数组,引用他的描述就是

需要注意的是fun关键词参数里面的函数,需要把优化的theta放在第一个位置,X,y,放到后面。并且,theta在传入的时候一定要是一个一维shape(n,)的数组,不然会出错。
然后jac是梯度,这里的有两个地方要注意,第一个是传入的theta依然要是一个一维shape(n,),第二个是返回的梯度也要是一个一维shape(n,)的数组。
总之,关键在于传入的theta一定要是一个1D shape(n,)的,不然就不行。我之前为了方便已经把theta塑造成了一个(n,1)的列向量,导致使用minimize时会报错。所以,学会用help看说明可谓是相当重要啊~

然后贴出实现函数的源码

import numpy as np
import pandas as pd
import scipy.optimize as op


def LoadData(filename):
    data = pd.read_csv(filename, header=None)
    data = np.array(data)
    return data


def ReshapeData(data):
    m = np.size(data, 0)
    X = data[:, 0:2]
    Y = data[:, 2]
    Y = Y.reshape((m, 1))
    return X, Y


def InitData(X):
    m, n = X.shape
    initial_theta = np.zeros(n + 1)
    VecOnes = np.ones((m, 1))
    X = np.column_stack((VecOnes, X))
    return X, initial_theta


def sigmoid(x):
    z = 1 / (1 + np.exp(-x))
    return z


def costFunction(theta, X, Y):
    m = X.shape[0]
    J = (-np.dot(Y.T, np.log(sigmoid(X.dot(theta)))) - np.dot((1 - Y).T, np.log(1 - sigmoid(X.dot(theta))))) / m
    return J


def gradient(theta, X, Y):
    m, n = X.shape
    theta = theta.reshape((n, 1))
    grad = np.dot(X.T, sigmoid(X.dot(theta)) - Y) / m
    return grad.flatten()


if __name__ == '__main__':
    data = LoadData('C:\\Users\Administrator\PycharmProjects\Clear\ml\ex2\ex2data1.txt')
    X, Y = ReshapeData(data)
    X, initial_theta = InitData(X)
    result = op.minimize(fun=costFunction, x0=initial_theta, args=(X, Y), method='TNC', jac=gradient)
    print(result)

最后结果如下,符合MATLAB里面用fminunc优化的结果(fminunc:cost:0.203,theta:-25.161,0.206,0.201)

fun: array([0.2034977])
     jac: array([8.95038682e-09, 8.16149951e-08, 4.74505693e-07])
 message: 'Local minimum reached (|pg| ~= 0)'
    nfev: 36
     nit: 17
  status: 0
 success: True
       x: array([-25.16131858,   0.20623159,   0.20147149])

4.绘制决策边界

使用优化函数计算出的theta就是决策边界的参数

#绘制决策边界
#matlab中取列1,输入1;python取列1,输入0,因为array从0开始取值
#绘制决策边界只需要两个端点
plot_x = [min(x[:,1])-2,  max(x[:,1])+2]
plot_y = (-1/theta[2])*(theta[1]*plot_x + theta[0])
scatter(X,Y,marker = '*',color = 'r')
scatter(X2,Y2,marker = '+',color = 'y')
plot(plot_x,plot_y)
show()

结果展示
在这里插入图片描述
符合预期的输出

Programming Exercise 1: Linear Regression Machine Learning Introduction In this exercise, you will implement linear regression and get to see it work on data. Before starting on this programming exercise, we strongly recom- mend watching the video lectures and completing the review questions for the associated topics. To get started with the exercise, you will need to download the starter code and unzip its contents to the directory where you wish to complete the exercise. If needed, use the cd command in Octave/MATLAB to change to this directory before starting this exercise. You can also find instructions for installing Octave/MATLAB in the “En- vironment Setup Instructions” of the course website. Files included in this exercise ex1.m - Octave/MATLAB script that steps you through the exercise ex1 multi.m - Octave/MATLAB script for the later parts of the exercise ex1data1.txt - Dataset for linear regression with one variable ex1data2.txt - Dataset for linear regression with multiple variables submit.m - Submission script that sends your solutions to our servers [?] warmUpExercise.m - Simple example function in Octave/MATLAB [?] plotData.m - Function to display the dataset [?] computeCost.m - Function to compute the cost of linear regression [?] gradientDescent.m - Function to run gradient descent [†] computeCostMulti.m - Cost function for multiple variables [†] gradientDescentMulti.m - Gradient descent for multiple variables [†] featureNormalize.m - Function to normalize features [†] normalEqn.m - Function to compute the normal equations ? indicates files you will need to complete † indicates optional exercises
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值