机器学习(2)

在这里插入图片描述

课前:Feature Scaling

参见另一篇博客中的question1

Logistic Regression

虽然名字叫回归,实际是分类问题。比如下图,数据点分两个类别,希望得到的模型最终可以预测一个新的数据点的类别属于哪一类。
在这里插入图片描述
显然此类问题不希望模型去拟合数据点得到一条尽可能囊括更多数据点的拟合曲线,而是希望模型找到两类数据点之间的一个分界线。值得一提的是,logistic回归的分界线是一条直线,除了logistic,也有曲线做分界线的。

1. 确定模型:

既然要找一条直线分界线,我们假设决策边界可以表示为:
在这里插入图片描述
这就与线性回归的假设函数一致了,也是为什么分类问题的模型带“回归”两字的原因。
得到了分界线还不够,还要能判断类别,我们考虑引入区间[0,1],通过引入一个外层函数sigmoid,把这个假设函数归一化到结果在[0,1]之间,这样就可以进行类别判断了,比如结果大于0.5认为是class1,结果小于0.5认为是class2。
(1)sigmoid函数:
在这里插入图片描述
其函数曲线:
在这里插入图片描述

(2)逻辑回归的假设函数
在这里插入图片描述
在这里插入图片描述
至此,逻辑回归的假设函数得到了。

2. 确定损失函数

在这里插入图片描述
损失函数的计算是建立在极大似然估计的背景下的,极大似然是一个求最大的问题,损失函数是一个求最小的问题,二分类下class1和class2的极大似然表示如下:
(1)在这里插入图片描述
以上两个式子,可以改写为一般形式:
(2)在这里插入图片描述
根据极大似然估计可以得到:
(3)每类概率的乘积和
在这里插入图片描述
为了简化计算,取对数将得到:
(4)乘法变成了加法
在这里插入图片描述
我们希望极大似然越大越好
(5)在这里插入图片描述
既然希望极大似然越大越好,对应就希望(5)越小越好,由此得到逻辑回归的损失函数:
(6)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

要找到一组参数θ使得损失函数最小,通常采用梯度下降。
由此可见,逻辑回归的损失函数不是定义的,而是根据最大似然估计推导出来的。

3.多分类问题

One VS All:一对多
每次训练一类,其余剩下的类视为一个大类,如果有k个类别则需要训练k个模型;容易导致样本类不均衡。
One VS One:一对一
任意两类训练一个模型;训练次数过多,每两个类别要训练一个模型
交叉熵:
在这里插入图片描述

Softmax

softmax的形式如下:
在这里插入图片描述
多分类的概率计算如下:在这里插入图片描述
引入指数函数形式:
在这里插入图片描述
对于不同类别zi,变成指数形式,求和求得概率pi,通过交叉熵计算分类在这里插入图片描述
通过softmax多分类问题可如下解决:
在这里插入图片描述

代码

#logistic regrassion
import numpy as np
import matplotlib.pyplot as plt
import random

#创建数据集
data_0=np.random.multivariate_normal(mean=[3,4],cov=[[3,0],[0,1]],size=100)#均值,方差,个数,生成指定维度指定均值指定方差的多维度的变量
#2维,类别2类,类别取值只有两个也就是0和1
data_1=np.random.multivariate_normal(mean=[7,6],cov=[[3,0],[0,2]],size=200)
y_0 = np.array([0]*100)
y_1 = np.array([1]*200)
data_x = np.vstack((data_0,data_1)) #水平方向聚集
data_y = np.hstack((y_0,y_1))        #垂直方向聚集

plt.scatter(data_x[:,0],data_x[:,1],c=data_y)
plt.show()
#生成的数据过于一致,把数据点打乱
data=list(zip(data_x,data_y)) #打包,每个x和y建立联系
random.shuffle(data) #再随机打乱打包好的data
print(data)
#解包
data_x,data_y = zip(*data)
data_x = np.array(data_x)
data_y = np.array(data_y)

#----------------------------数据集创建完成-----------------------

#逻辑回归分开数据集
#第一步,建立模型 sigmoid套在线性函数外面
##先写sigmod
def sigmoid(x):
    return np.array(1/(1+np.exp(-x)))

#写假设函数
def predict(w,b): #datax 300行两列
    hidden = np.dot(data_x,w.T)+b   #sigmoid内层的隐函数,其实就是线性回归的假设函数 x*w+b
    return sigmoid(hidden)
#写梯度
def gradients(y_pred): #datay 的尺寸要进行维度处理 datay[:]      注意尺寸
    #data_y:(300,0)->(300,1)
    #y_pred:(300,1)
    #data_x:(300,2)
    grad_w = np.sum((y_pred-data_y[:,np.newaxis])*data_x,axis=0,keepdims=True)  #data_y[:,np.newaxis].shape

    grad_b = np.sum((y_pred-data_y[:,np.newaxis])*1,axis=0,keepdims=True) #b*x0,x0=1
    # assert grad_w.shape==(1,2)  #检查形状
    # assert grad_b.shape==(1,1)
    return grad_b,grad_w
#计算正确率
def acc(y_pred,threshold=0.5):
    y_predict = np.around(y_pred)  #around  四舍五入
    correct_total = np.mean(np.equal(y_predict,data_y[:,np.newaxis])) #equal判断是否相等
    return correct_total
#梯度下降
#指定学习率,参数初始化
learning_rate = 1e-2
iterations = 1000
w = np.random.rand(1,2)
b = np.random.rand(1,1)

from IPython import display
for i in range(iterations):
    y_pred = predict(w,b)
    grad_w,grad_b = gradients(y_pred)
    w = w -learning_rate*grad_w
    b = b-learning_rate*grad_b
    if i%10 == 0:
        w1 = w[0][0]
        w2 = w[0][1]
        b = b[0][0]
        line_x = np.linspace(-10,20,100)
        line_y = (0.5-b-w1*line_x)/w2
        display.clear_output(wait=True)
        plt.xlim((-5,15))
        plt.ylim((0,10))
        plt.plot(line_x,line_y)
        plt.scatter(data_x[:,0],data_x[:,1],c=data_y)
        plt.title(f'iteration:{i},acc:{round(acc(y_pred),3)}')
        plt.pause(0.2)
        print(acc(y_pred))

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值