吴恩达机器学习作业2:Logistic Regression python实现

吴恩达机器学习作业 python 实现:Logistic Regression

1.检查加载数据,进行可视化

定义函数对数据可视化

def plotdata(path):
    data1 = np.loadtxt(path, delimiter=',')

    pos_index = np.where(data1[:, 2] == 1)
    neg_index = np.where(data1[:, 2] == 0)

    plt.scatter(data1[pos_index, 0], data1[pos_index, 1], c='b', marker='x', label='Addmited')
    plt.scatter(data1[neg_index, 0], data1[neg_index, 1], c='r', marker='o', label='Unaddmited')
    plt.xlabel('Feature 1')
    plt.ylabel('Feature 2')

    plt.legend()

加载数据

path = r'ex2data1.txt'
data1 = np.loadtxt(path, delimiter=',')
plotdata(path)
plt.show()

根据散点图显示的边界确定使用线性边界,所以不用进行特征缩放
在这里插入图片描述

2.定义Sigmod函数

注意传入的参数Z可以是一个矩阵(在python中为二维数组)

def sigmod(z):

    ans = 1 / (1 + np.exp(-z))

    return ans

3.代价函数 Cost Function

在实现代价函数的过程中,仍然使用向量化来避免for循环的使用

def computecost(theta, X, y):

    hx = sigmod(np.dot(X, theta))
    cost = -np.mean(np.multiply(y, np.log(hx)) + np.multiply(1-y, np.log(1-hx)))

    return cost

4.梯度下降

梯度下降的实现依旧是使用向量化来避免循环

值得注意:hx 是一个一维数组,hx.shape = (100,),如果传入的y在初始化数据时就进行reshape变成(100,1),这时  err.shape = (100,100)而不是(100,1)。原因是 hx 自动扩充为(100,100)的二维数组。解决的办法是传入 y 之前不要 reshape 即可。而对 hx 进行 reshape 让 err 维度正确 却会导致返回的 grad 是二维数组(在下面自动优化函数中二维数组将会导致优化函数的传参失败)
def gradient(theta, X, y):

    m = X.shape[0]
    hx = sigmod(np.dot(X, theta))
    err = hx - y

    grad = np.dot(X.T, err) / m

计算的无正则化、theta 为0向量时的代价与得到的梯度
在这里插入图片描述

5. fminunc 函数在python 中的替代

result = op.minimize(fun=computecost, x0=initial_theta, args=(X, y), method='TNC', jac=gradient)

在开头引用的库

import scipy.optimize as op

minimize函数传入的参数解释:

  1. fun - 表示要求得最小值的函数 因此代价函数传给 fun
  2. x0 - 表示 fun 中的初始自变量 即对应的代价函数中的 theta 为 初始自变量
  3. args - 表示 fun 中除了自变量自外的固定变量
  4. method - 表示优化的算法
  5. jac - 表示 fun 函数自变量的梯度算法

注意:initial_theta 、gradient返回值 是一维数组!!!!
reshape之后变成二维数组传入自动优化函数将会bug (对应4中提到的维度问题)

确定minimiz函数的参数维度无误 :

print(X.shape, initial_theta.shape, y.shape)
print(np.shape(grad))

运行结果:
在这里插入图片描述
最优化函数结果 :

  1. x 表示最终自变量的使得fun最小的取值 ,即让costFunction最小的theta
  2. 如果message输出:Linear search failed 是计算代价函数使用的log里面出现了负数(在第二部分的练习才会出现)

在这里插入图片描述

5.预测被录取的概率

print(sigmod(np.dot(result.x, [1, 45, 85])))

在这里插入图片描述

6.决策边界 (类似 ax+by+c= 0,求出y即可)

xplot_points = [X[:, 1].min(), X[:, 2].max()]
yplot_points = [X[:, 1].min()*op_theta[1]+op_theta[0], X[:, 1].max()*op_theta[1]+op_theta[0]]/(-op_theta[2])

plotdata(path)
plt.plot(xplot_points, yplot_points, c='y', label='Boundary Line')
plt.legend()
plt.show()

结果:
在这里插入图片描述

第二部分练习:

1.代价函数和梯度下降

没有太大变化,只是加入了正则化对theta进行惩罚:

def computecost2(theta, x, y, lambda_test):

    hx = sigmod(np.dot(x, theta))
    cost = -np.mean(np.multiply(y, np.log(hx)) + np.multiply(1-y, np.log(1-hx))) + lambda_test * np.mean(theta[1:])

    return cost


def gradient2(theta, x, y, lambda_test):

    m = X.shape[0]
    hx = sigmod(np.dot(X, theta))
    err = hx - y

    grad = np.dot(X.T, err) / m
    grad[1:] = grad[1:] + (lambda_test/m) * np.array(theta[1:])
    return grad

2.特征变量的映射

进行映射的原因是发现对data2进行数据可视化之后,线性的决策边界并不能将两个类别分开,因此选择更多的特征来描述边界:
在这里插入图片描述
映射代码:

def mapfeature(x1, x2):
    #若  m = x1.shape[0]
    # 当输入的不是一维的数组或者多维的矩阵时,m不存在,转换成矩阵后则为0
    temp = np.mat(x1)
    m = temp.shape[1]

    out = np.ones(m)

# 每个Featuer的最高次数等于6
    degree = 6
    for i in range(1, degree+1):

        for j in range(i+1):
            add = np.power(x1, i-j) * np.power(x2, j)
            out = np.vstack([out, add])

    return out.T

3.自动寻找 cost Function 为最小值的theta

result = op.minimize(fun=computecost2, args=(X, y, lambda_test), jac=gradient2, x0=initial_theta2, method='TNC')

与上面的优化函数使用没有什么不同
结果:

     fun: 0.04733255576368678
     jac: array([ 4.57959287e-04, -6.00677802e-05,  5.13905638e-05,  3.16235378e-05,
       -6.58358654e-05,  2.65673577e-04, -2.46359925e-05, -1.96059695e-05,
       -7.00014378e-05, -8.48880946e-05, -5.47619182e-05, -1.31191872e-04,
       -2.31736077e-05,  6.84331601e-06, -7.28501958e-05,  2.97037692e-05,
       -2.98836862e-05, -9.32059615e-05, -6.10395839e-06,  2.51302987e-05,
       -1.57621275e-04, -1.13892355e-05, -7.45965584e-05, -3.00943452e-05,
       -5.94147294e-05, -1.36079733e-05,  4.72813245e-05, -1.35909497e-04])
 message: 'Linear search failed'
    nfev: 59
     nit: 3
  status: 4
 success: False
       x: array([ 1.27422003,  0.62478645,  1.18590385, -2.02173837, -0.9170824 ,
       -1.41319104,  0.12444365, -0.36770527, -0.36458182, -0.18067802,
       -1.46506508, -0.06288704, -0.61999798, -0.27174439, -1.20129288,
       -0.23663762, -0.20901446, -0.05490418, -0.27804409, -0.29276915,
       -0.46790817, -1.04396472,  0.02082839, -0.29638539,  0.00961552,
       -0.32917183, -0.13804216, -0.93550855])
 

message: ‘Linear search failed’ 虽然出现了,不过已经接近最优解了

4.绘制等高图

xx = np.linspace(-1, 1.5, 30)
yy = np.linspace(-1, 1.5, 30)

z = np.zeros((xx.size, yy.size))

for i in range(0, xx.size):
    for j in range(0, yy.size):
        z[i][j] = np.dot(mapfeature(xx[i], yy[j]), theta_opt)

z = z.T
cs = plt.contour(xx, yy, z, [0], colors='b')
注意使用矩阵Z的转置步骤,这里yy表示原特征(没有映射之前)第二个特征的取值范围,理应是对应矩阵Z的列,但是在for中随之变化的是行向量,因此进行转置,这样才能和1中的点对应。

结果:
在这里插入图片描述
至此,吴恩达机器学习第二部分练习总体完成。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值