当目标变量是一个比例时如何使用sklearn

m33*_*lky 1 python scikit-learn

有一些标准方法可以预测比例,例如逻辑回归(没有阈值处理)和β回归.关于这个已经有过讨论:

http://scikit-learn-general.narkive.com/4dSCktaM/using-logistic-regression-on-a-continuous-target-variable

http://scikit-learn-general.narkive.com/lLVQGzyl/beta-regression

我不知道sklearn框架内是否存在解决方法.

kaz*_*ase 7

存在一个解决办法,但它本质上不是sklearn框架.

如果您有一个比例目标变量(值范围0-1),则scikit-learn会遇到两个基本困难:

  • 分类器(例如逻辑回归)仅将类标签作为目标变量处理.作为一种解决方法,您可以简单地将概率阈值设置为0/1并将其解释为类标签,但是您会丢失大量信息.
  • 回归模型(例如线性回归)不限制目标变量.您可以根据比例数据对它们进行训练,但不能保证看不见的数据的输出将被限制在0/1范围内.但是,在这种情况下,有一个强大的解决方法(下图).

有多种方法可以在数学上形成逻辑回归.其中之一是广义线性模型,它基本上将逻辑回归定义为对数转换概率的正态线性回归.通常,这种方法需要复杂的数学优化,因为概率是未知的,需要与回归系数一起估算.

但是,在您的情况下,概率是已知的.这意味着你可以简单地转换它们y = log(p / (1 - p)).现在它们涵盖了从-oo到的整个范围,oo并且可以作为LinearRegression模型[*] 的目标变量.当然,然后需要再次转换模型输出以产生概率p = 1 / (exp(-y) + 1).

import numpy as np
from sklearn.linear_model import LinearRegression


class LogitRegression(LinearRegression):

    def fit(self, x, p):
        p = np.asarray(p)
        y = np.log(p / (1 - p))
        return super().fit(x, y)

    def predict(self, x):
        y = super().predict(x)
        return 1 / (np.exp(-y) + 1)


if __name__ == '__main__':
    # generate example data
    np.random.seed(42)
    n = 100
    x = np.random.randn(n).reshape(-1, 1)
    noise = 0.1 * np.random.randn(n).reshape(-1, 1)
    p = np.tanh(x + noise) / 2 + 0.5

    model = LogitRegression()
    model.fit(x, p)

    print(model.predict([[-10], [0.0], [1]]))
    # [[  2.06115362e-09]
    #  [  5.00000000e-01]
    #  [  8.80797078e-01]]
Run Code Online (Sandbox Code Playgroud)
  • 还有许多其他选择.一些非线性回归模型可以在0-1范围内自然地工作.例如,随机森林回归量永远不会超过他们训练过的目标变量的范围.简单地说明概率,你就会得到概率.具有适当输出激活功能的神经网络(tanh我猜)也可以很好地处理概率,但是如果你想使用它们,那么有更多专业的库而不是sklearn.

[*]你实际上可以插入任何 可以使该方法更强大的线性回归模型,但它不再完全等同于逻辑回归.