统计学习方法读书笔记14-逻辑斯蒂回归代码实现与最大熵代码实现

1.逻辑斯蒂回归代码实现

#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
@author: liujie
@software: PyCharm
@file: logistic.py
@time: 2020/10/23 21:22
"""
import time
import numpy as np
from tqdm import tqdm

def loaddata(filename):
    """
    加载数据
    :param filename: 文件路径
    :return: 返回数据与标签
    """
    # 存放数据与标签
    dataList = []
    labelList = []
    # 打开文件
    fr = open(filename,'r')
    # 遍历文件每一行
    for line in tqdm(fr.readlines()):
        # 对每一行数据按照切割符“,”进行切割,返回字段列表
        curLine = line.strip().split(',')
        # 存放数据,将所有数据除255归一化
        dataList.append([int(num) / 255 for num in curLine[1:]])
        # 存放标签,
        # Mnsit有0-9是个标记,由于是二分类任务,所以将标记0的作为1,其余为0
        if int(curLine[0]) == 0:
            labelList.append(1)
        else:
            labelList.append(0)

    # 返回数据与标签
    return dataList,labelList


def logisticRegression(trainDataList,trainLabelList,iter=200):
    """
    二项逻辑斯蒂回归训练过程
    :param trainDataList: 训练数据
    :param trainLabelList: 训练数据标签
    :param iter: 迭代轮数
    :return: 学习的w
    """
    # 按照书本“6.1.2 二项逻辑斯蒂回归模型”中式6.5的规则,将w与b合在一起,此时x也需要添加一维,数值为1
    for i in tqdm(range(len(trainDataList))):
        trainDataList[i].append(1)

    # 将数据集由列表转换为数组形式,主要是后期涉及到向量的运算,统一转换成数组形式比较方便
    trainDataArr = np.array(trainDataList)
    # 初始化w,维数为样本x维数+1,+1的那一位是b,初始为0
    w = np.zeros(trainDataArr.shape[1])
    # 设置步长
    h = 0.001

    # 迭代iter次进行随机梯度下降
    for i in range(iter):
        # 每次迭代遍历所有样本,进行随机梯度下降
        for j in range(len(trainDataArr)):
            # 随机梯度上升部分
            # 在“6.1.3 模型参数估计”一章中给出了似然函数,我们需要极大化似然函数
            # 但是似然函数由于有求和项,并不能直接对w求导得出最优w,所以针对似然函数求和
            # 部分中每一项进行单独地求导w,得到针对该样本的梯度,并进行梯度上升(因为是
            # 要求似然函数的极大值,所以是梯度上升,如果是极小值就梯度下降。梯度上升是
            # 加号,下降是减号)
            # 求和式中每一项单独对w求导结果为:xi * yi - (exp(w * xi) * xi) / (1 + exp(w * xi))
            # w ,xi均为一维数组,np.dot(w,xi)为向量的内积
            wx = np.dot(w,trainDataArr[j])
            xi = trainDataArr[j]
            yi = trainLabelList[j]

            # 梯度上升
            w += h * (xi * yi - (1 + np.exp(wx) * xi) / (1 + np.exp(wx)))

    # 返回学到的w
    return w


def predict(w,x):
    """
    预测标签
    :param testDataList: 测试数据
    :param w: 训练学到的w
    :return: 返回预测标签
    """
    # dot为两个向量的点积操作,计算得到w * x
    wx = np.dot(w, x)
    # 计算标签为1的概率
    p = np.exp(wx) /(1 + np.exp(wx))

    if p > 0.5:
        return 1
    else:
        return 0


def model_test(testDataList,testLabelList,w):
    """
    验证准确率
    :param testDataList: 测试数据
    :param testLabelList:测试数据标签
    :param w:训练学到的w
    :return:acc
    """
    # 为方便后续计算,将每个样本添加一维
    for i in range(len(testDataList))
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值