ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

自定义线性回归模型

2021-10-10 12:34:51  阅读:246  来源: 互联网

标签:return 自定义 模型 STOP np thresh 线性 theta data


此篇文章将我最近所学的线性回归模型给放在了上面,有需要学习的同学可以参考

代码使用Pycharm进行编写,并将结果进行了可视化展示:

"""
-*-Code-*-
作者:LIANGQISE
日期:2021年10月06日
"""
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

import os
path = 'LogiReg_data.txt'
pdData = pd.read_csv(path, header=None, names=['Exam1', 'Exam2', 'Admitted'])

# 画图
# 指定正例负例,找到DataFrame中Admitted列中为0,和1的值;为1为正例为0为负例
positive = pdData[pdData['Admitted'] == 1]
negative = pdData[pdData['Admitted'] == 0]

# 开始画图
fig, ax = plt.subplots(figsize = (10,5))  # 画图域的长宽
ax.scatter(positive['Exam1'],positive['Exam2'],s = 30,c = 'b', marker = 'o',label = 'Admitted')  #散点图
ax.scatter(negative['Exam1'],negative['Exam2'],s = 30,c = 'r', marker = 'x',label = 'Not Admitted')
ax.set_xlabel('Exam1 Score')
ax.set_ylabel('Exam2 Score')
# plt.show()

# 算法实现

# sigmiod函数
def sigmoid(z):
    return 1/(1+np.exp(-z))

# 返回预测结果值
def model(X, theta):
    return sigmoid(np.dot(X, theta.T))   # 矩阵乘法,将结果返回到sigmoid中

# 将参数增加一列,'ones'表示列名,1表示填充列的值
pdData.insert(0,'Ones',1)

orig_data = pdData.values # 将其转换为数组形式
cols = orig_data.shape[1] # 得到数据的列数
X = orig_data[:,0:cols-1] # X为数据的前三列
y = orig_data[:,cols-1:cols] #y为数据的第四列
# theta为当前参数,通常需要对其进行占位,用0进行填充
theta = np.zeros([1,3]) #一行三列的theta参数

### 损失函数(对数似然函数取负号)
def cost(X, y, theta):   #X数据,y标签,theta参数
    left = np.multiply(-y, np.log(model(X, theta)))  #对数似然函数的左边,model为计算Sigmoid值的函数,multiply数组和矩阵对应位置相乘,输出与相乘数组/矩阵的大小一致
    right = np.multiply(1-y, np.log(1-model(X, theta))) # 对数似然函数的右边
    return np.sum(left - right)/(len(X))

### 计算梯度
def gradient(X, y, theta):
    grad = np.zeros(theta.shape)  #占位,和theta大小一样
    error = (model(X,theta)-y).ravel() #ravel()方法将数组维度拉成一维数组,表示yi
    for j in range(len(theta.ravel())):   # 遍历每一个theta,因为对每一个theta求偏导
        term = np.multiply(error, X[:,j])
        grad[0,j] = np.sum(term)/len(X)

    return grad

### 比较3中不同梯度下降算法

STOP_ITER = 0  # 按照迭代次数进行停止
STOP_COST = 1  # 按照损失差异进行停止
STOP_FRAD = 2  # 根据梯度差异进行停止

def stopCriterion(type, value, threshold):
    # 设定三种不同的停止策略
    if type == STOP_ITER:  return value > threshold
    elif type == STOP_COST: return abs(value[-1] - value[-2]) < threshold
    elif type == STOP_FRAD: return  np.linalg.norm(value) < threshold

# 迭代更新准备
import numpy.random
# 洗牌
def shuffleData(data):
    np.random.shuffle(data)  # 打乱顺序
    cols = data.shape[1]     # 得到数据的列数
    X = data[:, 0:cols-1]
    y = data[:, cols-1:]
    return X,y
# 开始进行梯度下降
import time
def descent(data, theta, batchSize, stopType, thresh, alpha): # alpha学习率
    # 梯度下降
    init_time = time.time()  # 时间计算
    i = 0 # 迭代次数
    k = 0 # batch
    X,y = shuffleData(data)
    grad = np.zeros(theta.shape) # 计算的梯度
    costs = [cost(X,y,theta)] # 损失值
# 开始更新参数
    while True:
        grad = gradient(X[k:k+batchSize], y[k:k+batchSize], theta)
        k += batchSize # 取batch数量个数据
        if k >= n:
            k = 0
            X, y = shuffleData(data) # 重新洗牌
        theta = theta - alpha*grad # 参数更新
        costs.append(cost(X, y, theta)) # 计算新的损失
        i += 1

        if stopType == STOP_ITER: value = i
        elif stopType == STOP_COST: value = costs
        elif stopType == STOP_FRAD: value = grad
        if stopCriterion(stopType,value,thresh):break
    return  theta, i - 1, costs, grad, time.time()-init_time

# 功能性函数
def runExpe(data, theta, batchSize, stopType, thresh, alpha):
    theta, iter, costs, grad, dur = descent(data, theta, batchSize, stopType, thresh, alpha)  # 对值进行初始化和求解
    name = 'Original' if (data[:,1]>2).sum() > 1 else 'Scaled'
    name += 'data - learning rate:{} -'.format(alpha)
    # 根据当前策略选择初始化的方式,和停止方式
    if batchSize == n: strDescType = 'Gradient'
    elif batchSize == 1: strDescType = 'Stochastic'
    else: strDescType = 'Mini-batch({})'.format(batchSize)
    name += strDescType + 'descent - Stop:'
    if stopType == STOP_ITER: strStop = '{} iterations'.format(thresh)
    elif stopType == STOP_COST: strStop = 'costs change < {}'.format(thresh)
    else: strStop = 'gradient norm < {}'.format(thresh)
    name += strStop
    # 进行显示的辅助函数
    print(
        '***{}\nTheta: {} - Iter: {} - Last cost: {:03.2f} - Duration: {:03.2f}s'.format(
        name, theta, iter, costs[-1], dur
    ))
    fig, ax = plt.subplots(figsize = (12,4))
    ax.plot(np.arange(len(costs)), costs, 'r')
    ax.set_xlabel('Iterations')
    ax.set_ylabel('Cost')
    ax.set_title(name.upper() + ' - Error vs. Iteration')
    return theta

# 设定迭代次数
n = 100   #对整体进行梯度下降
# runExpe(orig_data, theta, n, STOP_ITER, thresh=50000, alpha=0.000001)
# 不选择迭代次数,根据损失值停止
# runExpe(orig_data, theta, n, STOP_COST, thresh=0.000001, alpha=0.001)
# Mini batch为16
import sklearn
from sklearn import preprocessing as pp

scaled_data = orig_data.copy()
scaled_data[:,1:3] = pp.scale(orig_data[:,1:3])
runExpe(orig_data, theta, n, STOP_ITER, thresh=5000, alpha=0.001)
plt.show()

码超级详细,注释仅为个人理解,如果有不对的地方还请指出

想要一起学习的可以加好友本人QQ:920133676,并免费提供完整学习视频和数据集。

标签:return,自定义,模型,STOP,np,thresh,线性,theta,data
来源: https://blog.csdn.net/LIANGQISE/article/details/120684723

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有