如何使用逻辑回归和 scikit 学习进行回归而不是分类
How to do regression as opposed to classification using logistic regression and scikit learn
我需要预测的目标变量是probabilities
(与标签相反)。我的训练数据中对应的列也是这种形式。我不想通过对目标设置阈值来创建分类问题来丢失信息。
如果我用二进制标签训练 logistic regression classifier
,sk-learn 逻辑回归 API 允许在预测时获得概率。但是,我需要用概率来训练它。有没有办法在 scikits-learn 或合适的 Python 包中执行此操作,该包可扩展到 1K 维度的 100K 个数据点。
不要在 scikit 学习库中使用 predict
,而是使用 predict_proba
函数
I want the regressor to use the structure of the problem. One such
structure is that the targets are probabilities.
你不能在 scikit-learn
中有非指标概率的交叉熵损失;这在 API 中未实现且不受支持。这是scikit-learn
的限制。
一般来说,根据 scikit-learn
的文档,损失函数的形式为 Loss(prediction, target)
,其中预测是模型的输出,目标是真实值。
在逻辑回归的情况下,预测是 (0,1)
上的值(即 "soft label"),而目标是 0
或 1
(即, "hard label").
对于逻辑回归,您可以根据标签的概率对实例进行过采样,从而将概率近似为目标。例如如果给定样本 class_1
的概率为 0.2
,并且 class_2 has probability
0.8, then generate 10 training instances (copied sample): 8 with
class_2as "ground truth target label" and 2 with
class_1`。
显然这是一种解决方法,效率不是很高,但它应该可以正常工作。
如果您接受上采样方法,您可以 pip install eli5
,并使用 eli5.lime.utils.fit_proba
和来自 scikit-learn
的 Logistic Regression classifier
。
另一种解决方案是在 Tensorflow 中实现(或找到实现?)LogisticRegression
,您可以在其中随意定义损失函数。
在编译此解决方案时,我使用了来自 and 的答案。我建议那些有更多见识的人。
这是一个很好的问题,因为(与人们可能认为的相反)逻辑回归有许多合法用途,如......回归!
如果您坚持真正的逻辑回归,可以使用三种基本方法,另外还有两种方法应该会产生类似的结果。他们都假定你的目标输出在 0 和 1 之间。大多数时候你将不得不生成 training/test 集 "manually," 除非你足够幸运地使用支持带有自定义内核的 SGD-R 的平台和 X 验证支持开箱即用。
请注意,根据您的特定用例,可能需要 "not quite true logistic regression" 选项。这些方法的缺点是,如果您想通过删除弱特征来减少特征 space,则需要更多工作才能查看每个特征的 weight/importance。
使用优化的直接方法
如果您不介意编写一些代码,您可以使用 scipy 优化功能。这非常简单:
- 创建以下类型的函数:
y_o = 反逻辑 (a_0 + a_1x_1 + a_2x_2 + ...)
其中反逻辑 (z) = exp^(z) / (1 + exp^z)
- 使用scipy最小化最小化-1 * [y_t*log(y_o) + (1-y_t)*log(1 - y_o)],对所有数据点求和。为此,您必须设置一个函数,该函数将 (a_0、a_1、...) 作为参数并创建该函数,然后计算损失。
具有自定义损失的随机梯度下降
如果您碰巧使用的平台具有自定义损失的 SGD 回归,那么您可以直接使用它,指定损失为 y_t*log(y_o) + (1- y_t)*log(1 - y_o)
一种方法是 fork sci-kit learn 并将对数损失添加到回归 SGD 求解器中。
转换为分类问题
您可以通过过采样将您的问题转换为分类问题,如@jo9k 所述。但请注意,即使在这种情况下,您也不应使用标准 X 验证,因为数据不再独立。您需要手动将数据分解为 train/test 组,并且仅在将它们分开后才进行过采样。
转换为支持向量机
(编辑:我做了一些测试,发现在我的测试集上 sigmoid 内核表现不佳。我认为它们需要一些特殊的预处理才能按预期工作。带有 sigmoid 内核的 SVM 相当于2 层 tanh 神经网络,它应该适用于结构化的回归任务,其中训练数据输出是概率。我可能会在进一步审查后回过头来。)
您应该会得到与使用带有 sigmoid 核的 SVM 的逻辑回归相似的结果。可以使用sci-kit learn的SVR函数,指定kernel为sigmoid。您可能 运行 在 1000 个特征的 100,000 个数据点上遇到性能问题....这引出了我的最终建议:
使用近似内核转换为 SVM
这种方法给出的结果与真正的逻辑回归有一点距离,但它的性能非常好。过程如下:
使用 sci-kit-learn 的 RBFsampler 为您的数据集显式构造一个近似的 rbf-kernel。
通过该内核处理您的数据,然后使用 sci-kit-learn 的带有铰链损失的 SGDRegressor 在转换后的数据上实现超高性能 SVM。
以上为代码here
我需要预测的目标变量是probabilities
(与标签相反)。我的训练数据中对应的列也是这种形式。我不想通过对目标设置阈值来创建分类问题来丢失信息。
如果我用二进制标签训练 logistic regression classifier
,sk-learn 逻辑回归 API 允许在预测时获得概率。但是,我需要用概率来训练它。有没有办法在 scikits-learn 或合适的 Python 包中执行此操作,该包可扩展到 1K 维度的 100K 个数据点。
不要在 scikit 学习库中使用 predict
,而是使用 predict_proba
函数
I want the regressor to use the structure of the problem. One such structure is that the targets are probabilities.
你不能在 scikit-learn
中有非指标概率的交叉熵损失;这在 API 中未实现且不受支持。这是scikit-learn
的限制。
一般来说,根据 scikit-learn
的文档,损失函数的形式为 Loss(prediction, target)
,其中预测是模型的输出,目标是真实值。
在逻辑回归的情况下,预测是 (0,1)
上的值(即 "soft label"),而目标是 0
或 1
(即, "hard label").
对于逻辑回归,您可以根据标签的概率对实例进行过采样,从而将概率近似为目标。例如如果给定样本 class_1
的概率为 0.2
,并且 class_2 has probability
0.8, then generate 10 training instances (copied sample): 8 with
class_2as "ground truth target label" and 2 with
class_1`。
显然这是一种解决方法,效率不是很高,但它应该可以正常工作。
如果您接受上采样方法,您可以 pip install eli5
,并使用 eli5.lime.utils.fit_proba
和来自 scikit-learn
的 Logistic Regression classifier
。
另一种解决方案是在 Tensorflow 中实现(或找到实现?)LogisticRegression
,您可以在其中随意定义损失函数。
在编译此解决方案时,我使用了来自
这是一个很好的问题,因为(与人们可能认为的相反)逻辑回归有许多合法用途,如......回归!
如果您坚持真正的逻辑回归,可以使用三种基本方法,另外还有两种方法应该会产生类似的结果。他们都假定你的目标输出在 0 和 1 之间。大多数时候你将不得不生成 training/test 集 "manually," 除非你足够幸运地使用支持带有自定义内核的 SGD-R 的平台和 X 验证支持开箱即用。
请注意,根据您的特定用例,可能需要 "not quite true logistic regression" 选项。这些方法的缺点是,如果您想通过删除弱特征来减少特征 space,则需要更多工作才能查看每个特征的 weight/importance。
使用优化的直接方法
如果您不介意编写一些代码,您可以使用 scipy 优化功能。这非常简单:
- 创建以下类型的函数: y_o = 反逻辑 (a_0 + a_1x_1 + a_2x_2 + ...)
其中反逻辑 (z) = exp^(z) / (1 + exp^z)
- 使用scipy最小化最小化-1 * [y_t*log(y_o) + (1-y_t)*log(1 - y_o)],对所有数据点求和。为此,您必须设置一个函数,该函数将 (a_0、a_1、...) 作为参数并创建该函数,然后计算损失。
具有自定义损失的随机梯度下降
如果您碰巧使用的平台具有自定义损失的 SGD 回归,那么您可以直接使用它,指定损失为 y_t*log(y_o) + (1- y_t)*log(1 - y_o)
一种方法是 fork sci-kit learn 并将对数损失添加到回归 SGD 求解器中。
转换为分类问题
您可以通过过采样将您的问题转换为分类问题,如@jo9k 所述。但请注意,即使在这种情况下,您也不应使用标准 X 验证,因为数据不再独立。您需要手动将数据分解为 train/test 组,并且仅在将它们分开后才进行过采样。
转换为支持向量机
(编辑:我做了一些测试,发现在我的测试集上 sigmoid 内核表现不佳。我认为它们需要一些特殊的预处理才能按预期工作。带有 sigmoid 内核的 SVM 相当于2 层 tanh 神经网络,它应该适用于结构化的回归任务,其中训练数据输出是概率。我可能会在进一步审查后回过头来。)
您应该会得到与使用带有 sigmoid 核的 SVM 的逻辑回归相似的结果。可以使用sci-kit learn的SVR函数,指定kernel为sigmoid。您可能 运行 在 1000 个特征的 100,000 个数据点上遇到性能问题....这引出了我的最终建议:
使用近似内核转换为 SVM
这种方法给出的结果与真正的逻辑回归有一点距离,但它的性能非常好。过程如下:
使用 sci-kit-learn 的 RBFsampler 为您的数据集显式构造一个近似的 rbf-kernel。
通过该内核处理您的数据,然后使用 sci-kit-learn 的带有铰链损失的 SGDRegressor 在转换后的数据上实现超高性能 SVM。
以上为代码here