仅使用python+numpy实现的逻辑回归模型

仅使用python+numpy实现的逻辑回归模型

代码库Github链接为:https://github.com/Resulte/logistic-regression-model
(希望您去Github的时候可以顺手给个Star)

数据集说明

数据集在dataset目录下,分为下面三个文件

  • trainset.json: 内包含训练集数据,由1000条数据组成的列表,每条数据由一组输入数据和一个label值,输入数据为一个长度为9的数组,label为0则代表该输入数据属于第0类,label为1则代表该输入数据属于第1类。

  • devset.json: 内包含验证集数据,格式同trainset.json,由200条数据组成的列表,每条数据由一组输入数据和一个label值,输入数据为一个长度为9的数组,label为0则代表该输入数据属于第0类,label为1则代表该输入数据属于第1类。

  • testset.json: 内包含测试数据,是一个由100条测试数据组成的二维数组,形状为[100,9]

模型说明

本模型将会采用 梯度下降法 训练一个逻辑回归模型,并使用此模型对testset.json中的数据进行预测。

在完成函数拟合后,将会使用得出的二分类模型对testset.json中的100条测试数据进行预测,并将此文件补充为与trainset.json相同格式的文件。

本算法只会采用python的numpy库自行实现模型的训练和测试。

第一步:加载数据集

# 加载数据集
def load_data(dirname = TRAIN_DIR):
    data = []
    with open(dirname, "r") as data_file:
        data = json.load(data_file)
    data_x = [i[0] for i in data]
    data_y = [i[1] for i in data]

    return np.array(data_x), np.array(data_y)

第二步:训练模型

训练模型的时候可以同时画训练集&验证集的loss曲线,还有计算训练集&验证集的准确率。

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

# 回归模型
def model(data_x, weights):
    return sigmoid(np.dot(data_x, weights.T))

# 损失值计算
def loss(data_x, data_y, weights):
    model_value = model(data_x, weights).ravel()
    left = np.multiply(-data_y, np.log(model_value))
    right = np.multiply(1 - data_y, np.log(1 - model_value))
    return np.mean(left - right)

# 梯度计算
def gradient(data_x, data_y, weights):
    grad = np.zeros(weights.shape)
    error = (model(data_x, weights)).ravel() - data_y
    for j in range(len(weights.ravel())):
        term = np.multiply(error, data_x[:, j])
        grad[0, j] = np.sum(term) / len(data_x)
    return grad

# loss曲线绘画
def draw_loss(train_loss, valid_loss):
    plt.plot(train_loss, c='b', label='train loss')
    plt.plot(valid_loss, c='r', label='valid loss')
    plt.legend(loc=0, ncol=1)
    plt.xlabel('iternations')
    plt.ylabel('loss')
    plt.savefig('./train和valid的loss曲线图.png')
    plt.show()

# 模型预测值计算
def predict(data_x, weights):
    return [1 if x > 0.5 else 0 for x in model(data_x, weights)]

# 准确率计算
def accuracy(real_val, predict_val):
    correct = [1 if real_val[i] == predict_val[i] else 0 for i in range(len(real_val))]
    return np.sum(correct) / len(real_val)

# 训练模型
def train(batchSize, threshold, learning_rate):
    batch = 0
    epoch = 0

    # 加载训练&验证集
    train_x, train_y = load_data(TRAIN_DIR)
    valid_x, valid_y = load_data(VALID_DIR)

    # 初始化weights
    weights = np.zeros((1, train_x.shape[1]))

    # 初始化loss
    train_loss = [loss(train_x, train_y, weights)]
    valid_loss = [loss(valid_x, valid_y, weights)]

    # 初始化梯度
    grad = np.zeros(weights.shape)

    # 梯度下降
    while True:
        grad = gradient(train_x[batch : batch + batchSize], train_y[batch : batch + batchSize], weights)
        # 参数更新
        weights = weights - learning_rate * grad
        train_loss.append(loss(train_x, train_y, weights))
        valid_loss.append(loss(valid_x, valid_y, weights))
        epoch += 1

        if epoch > threshold:
            break;
    
    # 画训练集&验证集的loss曲线
    draw_loss(train_loss, valid_loss)

    # 计算训练集&验证集的准确率
    print("训练集准确率:", accuracy(train_y, predict(train_x, weights)))
    print("验证集准确率:", accuracy(valid_y, predict(valid_x, weights)))
    
    return weights

第三步:测试模型

测试的时候,需要预测数据集:

# 测试模型
def test(weights):
    # 加载测试集
    test_data = []
    with open(TEST_DIR, "r") as data_file:
        test_data = json.load(data_file)
    test_data = np.array(test_data)

    # 预测测试集
    test_predict = predict(test_data, weights)

    # 输出测试结果
    new_test_data=[[test_data[i].tolist(), test_predict[i]] for i in range(len(test_predict))]
    with open(OUTPUT_DIR, "w") as file:
        json.dump(new_test_data, file)

输出结果

训练集&验证集的loss曲线图如下:
在这里插入图片描述
准确率为:

训练集准确率: 0.826
验证集准确率: 0.825
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值