机器学习

第一章:机器学习基础 第二章:线性回归 第三章:逻辑回归 第四章:BP 神经网络 第五章:卷积神经网络 第六章:循环神经网络 第七章:决策树与随机森林 第八章:支持向量机 第九章:隐马尔科夫 第十章:聚类等算法 ...


逻辑回归

基于吴恩达机器学习的习题

逻辑回归github地址


前言

机器学习是从人工智能中产生的一个重要学科分支,是实现智能化的关键


一、基础概念

逻辑回归也被称为广义线性回归模型,它与线性回归模型最大的区别就在于它们的因变量不同,如果是连续的,就是多重线性回归;如果是二项分布,就是逻辑回归。
  Logistic回归虽然名字里带“回归”,但是它实际上是一种分类方法,主要用于两分类问题(即输出只有两种,分别代表两个类别)。逻辑回归就是这样的一个过程:面对一个回归或者分类问题,建立代价函数,然后通过优化方法迭代求解出最优的模型参数,然后测试验证我们这个求解的模型的好坏。
Step:
  (1)寻找h函数(即预测函数);
  (2)构造J函数(损失函数);
  (3)想办法使得J函数最小并求得回归参数(θ)
  二分类问题的概率与自变量之间的关系图形往往是一个S型曲线,采用Sigmoid函数实现,函数形式为:

     在这里插入图片描述
构造预测函数为:
       在这里插入图片描述

sigmoid的函数输出是介于(0,1)之间的,中间值是0.5,公式的含义就很好理解了,因为输出是介于(0,1)之间,也就表明了数据属于某一类别的概率,例如: <0.5则说明当前数据属于A类;>0.5则说明当前数据属于B类。所以我们可以将sigmoid函数看成样本数据的概率密度函数。
  sigmoid函数图

在这里插入图片描述

二、构造损失函数

与多元线性回归所采用的最小二乘法的参数估计方法相对应,最大似然法是逻辑回归所采用的参数估计方法,其原理是找到这样一个参数,可以让样本数据所包含的观察值被观察到的可能性最大。这种寻找最大可能性的方法需要反复计算,对计算能力有很高的要求。最大似然法的优点是大样本数据中参数的估计稳定、偏差小、估计方差小。
  接下来我们使用概率论中极大似然估计的方法去求解损失函数。
  首先得到概率函数为:


           在这里插入图片描述
因为样本数据(m个)独立,所以它们的联合分布可以表示为各边际分布的乘积,取似然函数为:
在这里插入图片描述

取对数似然函数:
在这里插入图片描述
最大似然估计就是要求得使l(θ)取最大值时的θ,这里可以使用梯度上升法求解,求得的θ就是要求的最佳参数:
在这里插入图片描述

基于最大似然估计推导得到代价函数和损失函数如下:
在这里插入图片描述
在这里插入图片描述

三、梯度下降法求解最小值

(1)θ更新过程:
      在这里插入图片描述
      在这里插入图片描述
θ更新过程可以写成:
      在这里插入图片描述

(2)向量化
  训练数据的矩阵形式如下,x的每一行为一条训练样本,而每一列为不同的特称取值:
在这里插入图片描述
g(A)的参数A为一列向量,所以实现g函数时要支持列向量作为参数,并返回列向量。θ更新过程可以改为:
在这里插入图片描述

(3)正则化
过拟合即是过分拟合了训练数据,使得模型的复杂度提高,繁华能力较差(对未知数据的预测能力)
左图即为欠拟合,中图为合适的拟合,右图为过拟合。
在这里插入图片描述

正则化是结构风险最小化策略的实现,是在经验风险上加一个正则化项或惩罚项。正则化项一般是模型复杂度的单调递增函数,模型越复杂,正则化项就越大。
正则项可以取不同的形式,在回归问题中取平方损失,就是参数的L2范数,也可以取L1范数。取平方损失时,模型的损失函数变为:在这里插入图片描述
正则化后的梯度下降算法θ的更新变为:
在这里插入图片描述

四、逻辑回归(吴恩达练习)

# 开发时间 ;2021/5/14 0014 9:24

#建立一个逻辑回归模型来预测一个学生是否被大学录取
# 假设作为一所大学系的管理者,要根据每一位申请人在两次考试中的成绩来确定他们的入学机会。这里有前几年的历史数据
# 可以将其用作逻辑回归的培训集。对于每个培训示例,都有申请者在两次考试中的分数和招生决定。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import scipy.optimize as opt
plt.style.use('seaborn-darkgrid')
from sklearn.metrics import classification_report#这个包是评价报告

path='F:/ML/logistics回归/数据文件/ex2data1.txt'
data=pd.read_csv(path,header=None,names=['exam1','exam2','admitted'])
# print(data.head(5))

plt.figure(figsize=(16,9))
admit=data[data['admitted'].isin([1])]
n_admit=data[data['admitted'].isin([0])]
# print(admit)
# print(n_admit)
plt.scatter(admit['exam1'],admit['exam2'],c='black',marker='+',label='admitted')
plt.scatter(n_admit['exam1'],n_admit['exam2'],c='y',marker='o',label='Not admitted')
plt.xlabel('Exam1_score')
plt.ylabel('Exam2_score')
plt.show()


#逻辑函数
def sigmoid(z):
    return 1/(1+np.exp(-z))
fig, ax = plt.subplots(figsize=(8, 6))
ax.plot(np.arange(-10, 10, step=0.01),
        sigmoid(np.arange(-10, 10, step=0.01)))
ax.set_ylim((-0.1,1.1))
ax.set_xlabel('z', fontsize=18)
ax.set_ylabel('g(z)', fontsize=18)
ax.set_title('sigmoid function', fontsize=18)
plt.show()


#theta数据处理
data.insert(0,'Ones',1)
# print(data)

X=np.array(data.iloc[:,:-1])
y=np.array(data.iloc[:,-1])
theta=np.zeros(X.shape[1])
print(X.shape)
print(y.shape)
print(theta.shape)
# print(cost_fun(X,y,theta))

#代价函数
def cost_fun(theta,X,y):
    # m=X.shape[0]
    #
    # inner_1=-y*np.log(sigmoid(np.dot(X,theta)))
    # inner_2=-(1-y)*np.log(1-sigmoid(np.dot(X,theta)))
    # J_cost=np.sum(inner_1+inner_2)/m
    # return J_cost
    ''' cost fn is -l(theta) for you to minimize'''
    return np.mean(-y * np.log(sigmoid(X @ theta)) - (1 - y) * np.log(1 - sigmoid(X @ theta)))




#梯度下降
def gradient(theta,X,y):
    m=X.shape[0]
    # return (1 / len(X)) * X.T @ (sigmoid(X @ theta) - y)
    return np.dot(X.T,sigmoid(np.dot(X,theta))-y)/m
print(gradient(theta,X,y))

# 使用fimin_tnc或者minimize方法来拟合,学习参数θ
result = opt.fmin_tnc(func=cost_fun, x0=theta, fprime=gradient, args=(X, y))
print(result)
print(result[0])

# 假设函数,预测函数
def predict(theta,X):
    probability=sigmoid(X.dot(theta))
    return [1 if x>=0.5 else 0 for x in probability ]


final_theta = result[0]
print(result)
print(result[0])
predictions = predict(final_theta, X)
correct = [1 if a==b else 0 for (a, b) in zip(predictions, y)]
accuracy = sum(correct) / len(X)
print(accuracy)

# 用skearn中的方法来检验。
from sklearn.metrics import classification_report
print(classification_report(predictions, y))

#决策边界
#线性theta*X=0
#有theta[0]+theta[1]*x1+theta[2]*x2=0
x1=np.arange(130,step=0.1)
x2=-(final_theta[0]+x1*final_theta[1])/final_theta[2]
fig ,ax=plt.subplots(figsize=(8,5))
ax.scatter(admit['exam1'],admit['exam2'],c='b',label='Admitted')
ax.scatter(n_admit['exam1'],n_admit['exam2'],s=50,c='r',marker='x',label='Not Admitted')
ax.plot(x1,x2)
ax.set_xlim(0, 130)
ax.set_ylim(0, 130)
ax.set_xlabel('x1')
ax.set_ylabel('x2')
ax.set_title('Decision Boundary')
plt.show()

在这里插入图片描述

在这里插入图片描述
.

总结

这相当于我对于一个逻辑回归的实践,代码和数据集都可以在我的github上找到,特别感谢吴恩达和黄海广教授。里面有关于概率函数、极大似然估计等知识点的链接,不懂得可点开学习,期待和大家一起讨论。