最小化逻辑回归的负对数似然性,scipy返回警告:“由于精度损失,未必实现所需的错误。”

时间:2017-11-04 17:47:13

标签: numpy optimization machine-learning scipy logistic-regression

我试图弄清楚为什么scipy优化不会收敛于逻辑回归函数的最小负对数似然的解决方案(如下所示)。

对于较小的数据集似乎会收敛,但对于较大的数据集,scipy会返回警告:“由于精度损失,未必实现所需的错误。”

我认为这是一个表现良好的优化问题,所以我很担心我错过了一个明显的错误。

任何人都可以在我的实施中发现错误或提出我可能会尝试的建议吗?

我正在使用默认方法,但我对其他各种miminize允许的方法运气不佳。

非常感谢!

实施的快速摘要。我正在尽量减少以下陈述:

enter image description here

需要注意的是,由于b是常数,我使用的是指数 - (w * x + b)。我想我已经实现了这个功能正确,但也许我没有看到什么。由于数据是关于最小化函数的常量,我只输出一个保留其中数据的函数定义;因此,要最小化的函数仅接受权重。

数据是格式的pandas数据框:rows == samples,columns == attributes,但是LAST column == label(0或1)。我已经转换了所有数据以确保它是连续的,并且我将其归一化为平均值为0且标准偏差为1.我也从[0,0.1]之间的随机权重开始,对待首重为'b'。

def get_optimization_func_call(data, sheepda):
    #
    # Extract pos/neg data without label
    pos_df = data[data[LABEL] == 1].as_matrix()[:, :-1]
    neg_df = data[data[LABEL] == 0].as_matrix()[:, :-1]

    #
    # Def evaluation of positive terms by row
    def eval_pos_row(pos_row, w, b):
        cur_exponent = np.dot(w, pos_row) + b
        cur_val = expit(cur_exponent)
        if cur_val == 0:
            print("pos", cur_exponent)
        return (-1 * np.log(cur_val))

    #
    # Def evaluation of positive terms by row
    def eval_neg_row(neg_row, w, b):
        cur_exponent = np.dot(w, neg_row) + b
        cur_val = 1.0 - expit(cur_exponent)
        if cur_val == 0:
            print("neg", cur_exponent)
        return (-1 * np.log(cur_val))

    #
    #  Define the function used for optimization
    def log_likelihood(weights):
        #
        # Separate weights
        w = weights[1:]
        b = weights[0]
        #
        # Ge the norm of weights
        w_norm = np.dot(w, w)
        #
        # Sum over positive examples
        pos_sum = np.sum(
            np.apply_along_axis(eval_pos_row, 1, pos_df, w, b)
        )
        neg_sum = np.sum(
            np.apply_along_axis(eval_neg_row, 1, neg_df, w, b)
        )
        #
        return (0.5 * w_norm) + sheepda * (pos_sum + neg_sum)

    return log_likelihood


w = uniform.rvs(size=20) / 10.0
LL = get_optimization_func_call(clean_test_data, 0.5)

res = minimize(LL, w, options={"maxiter": 1e4, "disp": True})

0 个答案:

没有答案