You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

核逻辑回归预测错误求助:提升迭代次数仍无效

核逻辑回归实现问题排查

问题概述

实现核逻辑回归函数时,无法得到预期的正确预测结果,存在指数溢出警告(已临时抑制),即使将迭代次数提升至4000,问题仍未解决。

实现代码

import numpy as np
import warnings

warnings.filterwarnings('ignore')

def monomial_kernel(d):
    def k(x, y, d=d):
        phi_x_y = 0
        prod_xy = np.dot(x.T,y)

        for n in range(d+1):
            phi_x_y += (prod_xy ** n)

        return phi_x_y
        
    return k

def rbf_kernel(sigma):
    def k(x, y, sigma=sigma):
        numerator = np.linalg.norm(x - y) **2
        denominator = 2 * (sigma ** 2)
        
        return np.exp(-numerator / denominator)

    return k

def sigmoid(z):
    if type(z) == np.ndarray:
        z = z[0]
    try:
        return 1 / (1 + np.exp(-z)) 
    except:
        print(z)

def logistic_regression_with_kernel(X, y, k, alpha, iterations):

    n_samples, _ = X.shape
    bias = 0
    kernel_matrix = np.zeros((n_samples, n_samples))
    beta = np.zeros(n_samples)

    #create kernel matrix
    for i in range(n_samples):
        for j in range(n_samples):
            kernel_matrix[i][j] = k(X[i], X[j])
    
    for _ in range(iterations):
        for i in range(n_samples):
            total = 0
            for j in range(n_samples):
                total += beta[j] * kernel_matrix[i][j]
            total += bias
            sigmoid_value = sigmoid(total)
            t = y[i]

            beta += kernel_matrix[i] * alpha * (t - sigmoid_value)
                    
            bias += (alpha * (t - (sigmoid_value))) 

    def model(x, beta=beta, bias=bias, k=k, ref=X):
        z = sum([k(ref[i], x) * beta[i] for i in range(ref.shape[0])]) + bias 

        sig = sigmoid(z)
        # print(sig)
        return round(sig)
    return model

测试用例

def test4():
    
    f = lambda x, y, z, w:  int(x*y*z - y**2*z*w/4 + x**4*w**3/8- y*w/2 >= 0)

    training_examples = [
        ([0.254, 0.782, 0.254, 0.569], 0),
        ([0.237, 0.026, 0.237, 0.638], 0),
        ([0.814, 0.18, 0.814, 0.707], 1),
        ([0.855, 0.117, 0.855, 0.669], 1),
        ([0.776, 0.643, 0.776, 0.628], 1),
        ([0.701, 0.71, 0.701, 0.982], 0),
        ([0.443, 0.039, 0.443, 0.356], 1),
        ([0.278, 0.105, 0.278, 0.158], 0),
        ([0.394, 0.203, 0.394, 0.909], 0),
        ([0.83, 0.197, 0.83, 0.779], 1),
        ([0.277, 0.415, 0.277, 0.357], 0),
        ([0.683, 0.117, 0.683, 0.455], 1),
        ([0.421, 0.631, 0.421, 0.015], 1)
    ]

    X, y = map(np.array, zip(*training_examples))

    h = logistic_regression_with_kernel(X, y, monomial_kernel(10), 0.01, 500)

    test_examples = [
        ([0.157, 0.715, 0.787, 0.644], 0),
        ([0.79, 0.279, 0.761, 0.886], 1),
        ([0.903, 0.544, 0.138, 0.925], 0),
        ([0.129, 0.01, 0.493, 0.658], 0),
        ([0.673, 0.526, 0.672, 0.489], 1),
        ([0.703, 0.716, 0.088, 0.674], 0),
        ([0.276, 0.174, 0.69, 0.358], 1),
        ([0.199, 0.812, 0.825, 0.653], 0),
        ([0.332, 0.721, 0.148, 0.541], 0),
        ([0.51, 0.956, 0.023, 0.249], 0)
    ]
    print(f"{'x' : ^30}{'prediction' : ^11}{'true' : ^6}")
    for x, y in test_examples:
        print(f"{str(x) : ^30}{int(h(x)) : ^11}{y : ^6}")
    #             x               prediction  true
    # [0.157, 0.715, 0.787, 0.644]      0       0
    # [0.79, 0.279, 0.761, 0.886]       1       1
    # [0.903, 0.544, 0.138, 0.925]      0       0
    # [0.129, 0.01, 0.493, 0.658]       0       0
    # [0.673, 0.526, 0.672, 0.489]      1       1
    # [0.703, 0.716, 0.088, 0.674]      0       0
    # [0.276, 0.174, 0.69, 0.358]       1       1
    # [0.199, 0.812, 0.825, 0.653]      0       0
    # [0.332, 0.721, 0.148, 0.541]      0       0
    # [0.51, 0.956, 0.023, 0.249]       0       0

问题排查与修复

1. 多项式核函数实现错误

当前monomial_kernel的实现是对x·y的0到d次方求和,这和标准多项式核完全不符。标准d阶多项式核的形式为K(x,y) = (x·y + c)^d(c为常数,通常取1),它对应将特征映射到所有d阶单项式的组合空间,而原实现仅对x·y的幂次求和,无法捕捉特征间的交叉项,导致模型无法拟合测试用例中的4次多项式决策边界。

修复后的多项式核函数:

def monomial_kernel(d, c=1):
    def k(x, y, d=d, c=c):
        prod_xy = np.dot(x, y)
        return (prod_xy + c) ** d
    return k

如果需要齐次多项式核(无常数项),将c设为0即可。

2. Sigmoid函数数值不稳定

原实现未处理大数值溢出问题,且对数组的处理逻辑错误(仅取数组第一个元素),导致计算结果失真或溢出警告。使用数值稳定的实现可以避免这个问题:

修复后的Sigmoid函数:

def sigmoid(z):
    z = np.asarray(z)
    # 分情况计算避免指数溢出
    return np.where(z >= 0,
                    1 / (1 + np.exp(-z)),
                    np.exp(z) / (1 + np.exp(z)))

3. 模型拟合参数调整

  • 核函数阶数:测试用例中的决策函数最高为4次多项式,选择d=4的多项式核即可满足拟合需求,过高的阶数(如d=10)容易导致过拟合。
  • 学习率与迭代次数:可尝试将学习率调整为0.005,迭代次数设为1000,同时添加L2正则化防止过拟合(可选):

添加正则化的梯度更新代码:

# 定义正则化系数
lambda_ = 0.001

for _ in range(iterations):
    for i in range(n_samples):
        total = np.dot(beta, kernel_matrix[i]) + bias
        sigmoid_value = sigmoid(total)
        t = y[i]
        # 添加L2正则化
        beta += kernel_matrix[i] * alpha * (t - sigmoid_value) - alpha * lambda_ * beta
        bias += alpha * (t - sigmoid_value)

4. 预测函数优化

原model函数中的sum可以用np.dot替换,提升计算效率:

def model(x, beta=beta, bias=bias, k=k, ref=X):
    kernel_vec = np.array([k(ref[i], x) for i in range(ref.shape[0])])
    z = np.dot(beta, kernel_vec) + bias 
    sig = sigmoid(z)
    return round(sig)

修复后测试

使用修复后的代码,调用测试用例时替换核函数为:

h = logistic_regression_with_kernel(X, y, monomial_kernel(4), 0.005, 1000)

此时模型应该能输出符合预期的预测结果。

内容的提问来源于stack exchange,提问作者StrawberryCookie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 05:50:54