目标变量成比例时如何使用sklearn
问题内容:
有预测比例的标准方法,例如逻辑回归(无阈值)和beta回归。已经有关于此的讨论:
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
框架内是否存在解决方法。
问题答案:
存在一个解决办法,但它本质上不是 内 的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]]
- 还有许多其他选择。一些非线性回归模型可以在0-1范围内自然工作。例如,随机森林回归算法将永远不会超出其训练目标变量的范围。只需将概率放入,您将获得概率。具有适当的输出激活功能(
tanh
,我猜想)的神经网络也可以很好地解决概率问题,但是,如果您要使用这些神经网络,则比sklearn还要专门的库。
[*]实际上,您可以插入 任何 线性回归模型,这可以使方法更强大,但现在不再完全等同于逻辑回归。