吴恩达机器学习作业ex2:逻辑回归解决二分类

用逻辑回归解决二分类问题
代码已经注释很详细
ALT
第一部分解决上述 能用直线搞定的决策分类问题 拟合仅为直线 不需要加入正则项
代码如下:

import pandas as pds
import matplotlib.pyplot as plt
import numpy as np
def show_data():#进行数据可视化函数 并将X与Y分别取出并返回
    data = pds.read_csv("./ex2data1.txt",names=["n1","n2","result"])
    data_X1 = data[data["result"]==1].values #选取结果为1数据
    data_X2 = data[data["result"]==0].values #选取结果为0的数据
    plt.scatter(data_X1[:,0],data_X1[:,1],c="r",marker='o')#把特征值画上去 进行可视化展示
    plt.scatter(data_X2[:,0],data_X2[:,1],c='g',marker='*')
    plt.xlabel("n1")
    plt.ylabel("n2")#x轴为n1 y轴为n2
    plt.show()
    data.insert(loc=0,column="cons",value=1)#在第一列插入常数特征值1
    X = data.iloc[:,0:-1].values#取出特征值
    Y = data.iloc[:,[-1]].values.reshape(X.shape[0],1)#取出真实值y 并进行维度调整 变成(m,1)的二维矩阵
    return data,X,Y
def sigmoid(z):#激活函数
    #激活函数 y=1/(1+exp(-z))
    return 1/(1+np.exp(-z))
def costfunction(X,Y,theta):#计算代价函数
    m=Y.shape[0]
    A = sigmoid(X@theta) #经过激活函数的m的预测值
    first = Y*np.log(A) #代价函数第一项
    second = (1-Y)*np.log(1-A) #代价函数第二项
    return -np.sum(first+second)/m#记得求和
def grad_descent(X,Y,theta,learning_rate,num):#梯度下降算法
    m = Y.shape[0]
    for i in range(num):#共迭代num次
        A = sigmoid(X@theta)  # 得到经过激活函数的预测值
        print("第{}次迭代的损失为:{}".format(i+1,costfunction(X,Y,theta)))
        theta = theta - learning_rate/m*(X.T@(A-Y))#梯度下降
    return theta

def show_boundary(data,theta):#展示决策界面
    X1 = data[data["result"]==0].values
    X2 = data[data["result"]==1].values
    plt.scatter(X1[:,1],X1[:,2],c="r",marker="*")
    plt.scatter(X2[:,1],X2[:,2],c="g",marker="*")
    x = np.linspace(30,100,200).reshape((200,1))
    xx,yy = np.meshgrid(x,x)#每个点对应的x y就是特征值
    z = np.append(xx.ravel().reshape((40000,1)),yy.ravel().reshape((40000,1)),axis=1)
    #xx yy将其拉伸成为一条直线 得到200*200个样本的特征值x1,x2

    z = np.append(np.ones((200*200,1)),z,axis=1)#添加theta0的特征值常数1

    z = z@theta#得到200*200个样本的预测值
    zz = z.reshape(xx.shape)#将其还原为二维点坐标对应的z
    plt.contour(xx,yy,zz,0)#绘制三维图 z为0时即为决策界面
    #plt.contour函数分别传入x坐标 y坐标 以及对应的z值 绘制等高线 0表示z=0的等高线
    plt.show()
def get_curancy(X,Y,theta):#得到精确度的函数
    y = sigmoid(X@theta) #得到预测值
    m = Y.shape[0]#样本总数
    count = 0#记录正确的样本数
    for i in range(m):
        if y[i] >= 0.5:#大于等于0.5认为正样本 反之认为负样本
            y[i] = 1
        else:
            y[i] = 0
        if y[i] == Y[i]:  # 比较 如果结果正确 则说明是预测了正确的样本
            count = count + 1
    print("精确度为:{}".format(float(count)/m))

def main():
    data,X,Y=show_data()
    learning_rate = 0.001#注意 如果设置太大会报warning 具体原因还不知道
    num =200000#迭代次数
    theta = np.zeros((X.shape[1],1))#初始化(n,1)的二维theta矩阵
    theta = grad_descent(X,Y,theta,learning_rate,num)#通过梯度下降得到最优theta
    show_boundary(data,theta)#进行决策界面展示
    get_curancy(X,Y,theta)#分析准确率
if __name__ == '__main__':
    main()





在这里插入图片描述

第二部分解决如上二分类问题 界面较为复杂 不能单纯用直线分类 需要用特征缩放得到高阶特征值 拟合出复杂曲线 故还得引入正则项
代码如下:

import numpy as np
import pandas as pds
import matplotlib.pyplot as plt
def show_data():#展示数据集并将特征值与结果y返回
    data = pds.read_csv("./ex2data2.txt",names=["n1","n2","result"])
    X1 = data[data["result"]==0].values#选取结果分类为0的
    X2 = data[data["result"]==1].values#选取结果分类为1的
    plt.scatter(X1[:,0],X1[:,1],c="r",marker="*")
    plt.scatter(X2[:,0],X2[:,1],c="g",marker="*")
    plt.show()
    return data.values[:,[0,1]],data.values[:,[-1]],data#返回特征值与对应的结果y
def feature_mapping(X1,X2,n):#特征映射 将x1,x2特征进行组合成高阶特征值 n表示最高次项为多少
    data = {}
    for i in range(n+1):
        for j in range(n+1):
            data["n{}{}".format(i,j)]=np.power(X1,i)*np.power(X2,j)
    #进行特征映射 求解所有可能组合特征 每一种得到的新的特征值放到data字典里
    #上面循环是为了得到各种特征组合 例如x1*x2 x1^2*x2等等 最高到x1^n*x2^n
    data = pds.DataFrame(data)#放到pds中
    data = data.values#取出值 这就是特征映射得到的更多特征值
    return data
def sigmoid(z):#定义sigmoid函数
    return 1/(1+np.exp(-z))
def costfunction(X,Y,theta,lamda):#定义代价函数
    A = sigmoid(X@theta)
    m = Y.shape[0]
    first = Y*np.log(A)
    second = (1-Y)*np.log(1-A)
    res = (lamda/(2*m))*np.sum(theta[1:,0]*theta[1:,0])#代价函数这里新加入的正则项
    return -np.sum(first+second)/m + res
def grad_descent(X,Y,theta,learning_rate,num,lamda):#梯度下降
    m=Y.shape[0]
    for i in range(num):
        A = sigmoid(X@theta)
        res = theta[1:,]
        res = np.insert(res,axis=0,values=0,obj=0)
        theta = theta - learning_rate*(X.T@(A-Y))/m -learning_rate*res*lamda/m#因为加了更高次来进行拟合 我们需要加入正则项 所以梯度下降这也需要改变
        print("第{}次迭代损失为:{}".format(i,costfunction(X,Y,theta,lamda)))
    return theta
def show_border(data,theta):
    X1 = data[data["result"]==0].values
    X2 = data[data["result"]==1].values
    plt.scatter(X1[:,0],X1[:,1],c="r",marker="*")
    plt.scatter(X2[:,0],X2[:,1],c="g",marker="*")
    x = np.linspace(-1.2,1.2,200)
    xx,yy = np.meshgrid(x,x)#生成区间从(-1.2到1.2的200个横坐标和纵坐标组成的点)
    data = feature_mapping(xx.ravel(),yy.ravel(),6)#将验证样本进行特征映射 得到新的特征集
    z = data@theta#带入 得到预测值
    zz = z.reshape(xx.shape)#调整维度,变为(200*200)
    plt.contour(xx,yy,zz,0)#选取得到zz预测为0的即为决策界面
    plt.show()
def get_curancy(X,Y,theta):#验证准确率 X是已经被特征缩放的特征集了
    y = X@theta#得到预测值
    count = 0
    for i in range(len(y)):
        if y[i]>=0.5:
            y[i] = 1
        else:
            y[i] = 0
        if y[i] == Y[i]:
            count = count + 1
    print("准确率为:{}".format(count/len(y)))
def main():
    X,Y,data = show_data()
    X = feature_mapping(X[:,0],X[:,1],6)
    theta = np.zeros((X.shape[1],1))
    learning_rate = 0.01
    num = 500000#迭代次数
    lamda = 0.01#正则项
    theta = grad_descent(X,Y,theta,learning_rate,num,lamda)
    show_border(data,theta)
    get_curancy(X,Y,theta)
if __name__ == '__main__':
    main()
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值