用多任务 Lasso 在多个输出间共享特征选择

用多任务 Lasso 在多个输出间共享特征选择

The scikit-learn developers;中文编译、结构整理与静态审核:未完纪。

来源:Joint feature selection with multi-task Lasso。核对日期:2026-10-08。

输入矩阵X有100个样本30个特征,输出Y有40个任务;MultiTaskLasso对同一特征的40个系数共同施加组稀疏惩罚,得到40乘30系数矩阵。
未完纪原创技术示意图,根据本文机制绘制;不是运行截图。未完纪

同一批样本可能有多个回归目标。如果这些目标背后依赖的是同一小组特征,分别训练模型会浪费这层共同结构:某个目标噪声较大时,单独的Lasso可能选错或漏掉特征。MultiTaskLasso把多个输出一起拟合,对同一特征在不同任务中的系数施加组稀疏约束。

scikit-learn这个完整示例特意构造“有效特征相同、系数幅度不同”的数据,再观察两个模型的非零位置。它解释的是共享支持机制,并不证明联合模型对任何多输出问题都更好。

共享的是什么

设输入 X 有 n 个样本、p 个特征,输出 Y 有 T 个任务。把系数写成 W,形状为 (p,T),多任务Lasso的目标包含平方拟合误差和 α × Σⱼ ||W[j,:]||₂。后者先取每个特征跨所有任务的二范数,再对特征求和,鼓励整组系数同时变为零。

这里的“共享”是选择同一组特征的倾向,不是要求不同任务的系数值相同,也不严格保证某个已选特征在每个任务中的单个系数都非零。模型也没有显式的时间平滑项;即使任务顺序被画成时间,它也不因此变成时间序列预测器。

生成一个已知真值的问题

# Authors: The scikit-learn developers
# SPDX-License-Identifier: BSD-3-Clause
import numpy as np

rng = np.random.RandomState(42)
n_samples, n_features, n_tasks = 100, 30, 40
n_relevant_features = 5
coef = np.zeros((n_tasks, n_features))
times = np.linspace(0, 2 * np.pi, n_tasks)
for k in range(n_relevant_features):
    coef[:, k] = np.sin((1.0 + rng.randn(1)) * times + 3 * rng.randn(1))

X = rng.randn(n_samples, n_features)
Y = np.dot(X, coef.T) + rng.randn(n_samples, n_tasks)

coef 的形状是 (40,30):一行对应一个任务,一列对应一个特征。只有前五列被赋予非零的正弦系数,其余二十五列保持为零。各有效特征的频率与相位随机,因此幅度随任务索引变化,但共同使用的特征集合是预先设定的。

X 的形状为 (100,30),与 coef.T 相乘后得到 (100,40) 的无噪声输出,再叠加同形状的高斯噪声。随机种子让此构造便于重复对照;本文保留原文的 RandomState 而没有换成另一套随机数API,避免悄悄改变样本。

分别拟合与联合拟合

from sklearn.linear_model import Lasso, MultiTaskLasso

coef_lasso_ = np.array([
    Lasso(alpha=0.5).fit(X, y).coef_ for y in Y.T
])
coef_multi_task_lasso_ = MultiTaskLasso(alpha=1.0).fit(X, Y).coef_

独立Lasso遍历的是 Y.T,每次取一个任务的100个输出值,最终把40组长度为30的系数组成矩阵。MultiTaskLasso一次接收全部输出,其 coef_ 同样是 (40,30),便于逐项比较。

原文分别用 alpha=0.5 与 alpha=1.0。两个惩罚项的结构不同,不能把这些固定数字当成公平调参已经完成的证据。这个实验还没有独立测试集,不能根据训练得到的系数图断言泛化误差下降。

第一张图看非零位置

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(8, 5))
plt.subplot(1, 2, 1)
plt.spy(coef_lasso_)
plt.xlabel("Feature")
plt.ylabel("Time (or Task)")
plt.text(10, 5, "Lasso")
plt.subplot(1, 2, 2)
plt.spy(coef_multi_task_lasso_)
plt.xlabel("Feature")
plt.ylabel("Time (or Task)")
plt.text(10, 5, "MultiTaskLasso")
fig.suptitle("Coefficient non-zero location")

横轴是特征,纵轴是任务。spy 标出非零系数的位置;它没有直接展示系数正负或大小。根据数据真值,值得关注的是前五列是否被恢复,以及其余列是否出现误选。联合惩罚倾向于形成跨任务一致的列结构,独立拟合则可能在不同任务间零散地选择。

这段绘图代码沿用原示例。本文配图另用原创机制示意图,避免把没有运行的拟合过程包装成实际结果。原站提供的两张图可以通过正文源链接查看,作者归属仍为scikit-learn developers。

第二张图看一个特征的系数轨迹

feature_to_plot = 0
plt.figure()
lw = 2
plt.plot(coef[:, feature_to_plot], color="seagreen",
         linewidth=lw, label="Ground truth")
plt.plot(coef_lasso_[:, feature_to_plot], color="cornflowerblue",
         linewidth=lw, label="Lasso")
plt.plot(coef_multi_task_lasso_[:, feature_to_plot], color="gold",
         linewidth=lw, label="MultiTaskLasso")
plt.legend(loc="upper center")
plt.axis("tight")
plt.ylim([-1.1, 1.1])
plt.show()

这里固定观察第0个特征,比较40个任务中的真值、独立估计和联合估计。支持图回答“选择了哪些特征”,这张曲线图回答“选中之后估计的幅度怎样”。两者不能互相替代:选中正确特征仍可能有收缩偏差,曲线看起来平滑也不说明模型显式学习了时间动力学。

任务索引可以解释成顺序测量,但代码没有构造未来预测任务,也没有按时间划分训练集和测试集。不要把横轴上的时间用词扩展成该方法已经通过时间序列验证。

把示例迁移到真实数据时

首先核实多个输出是否真的共享有效特征。如果不同任务分别依赖完全不同的因素,共享稀疏性可能成为错误约束。其次考虑特征尺度:真实输入各列尺度不一致时,正则化会受到影响,应在训练折内部完成适当预处理,避免验证信息泄露。

之后分别调参,用独立验证或交叉验证检查每个目标及整体误差;若数据来自时间或群组结构,拆分方式也应尊重这一结构。本文没有执行这些扩展实验,因此不提供虚构的得分、速度或最优参数。静态检查未发现本示例片段包含网络操作、秘密或命令注入路径,但这一观察不等于模型依赖或真实应用不存在其他问题。

来源、版本与检查说明

2026-10-08读取的stable页面标题为scikit-learn 1.9.1。stable URL可能变化,本文保留原RandomState(42)与固定alpha以便对照;未安装包或执行示例,也未复测网页显示的运行时间。

原文示例代码标注 Authors: The scikit-learn developers,SPDX-License-Identifier: BSD-3-Clause。下方附上该代码所适用的完整 BSD-3-Clause 许可文本;此代码许可不因此覆盖原网页所有说明文字或本中文编译,正文翻译转载另有授权。原创机制图不使用原图像素,不代表本次拟合结果。

另外,官方页面页脚标注 © Copyright 2007–2026, scikit-learn developers (BSD License),但没有在该行指出网页说明文字对应的BSD变体。本文保留这项版权/许可线索,并明确 BSD-3-Clause 文件只用于带 SPDX 标记的代码示例;不将它推断为整页说明文字或中文译编的许可证。本文正文的翻译转载另有授权。

本文仅对源代码和配置做静态检查,未进行安装、运行或性能测试。文中的期望结果属于原文说明或逻辑推导,不能当作本次实测结果。

BSD-3-Clause 代码许可全文
BSD 3-Clause License

Copyright (c) 2007-2026 The scikit-learn developers.
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容