Anteriormente exploramos o Lasso tradicional para problemas de regressão com uma única variável target. Analogamente, o MultiTaskLasso estende essa abordagem para problemas com múltiplos targets, permitindo que o modelo aprenda tarefas relacionadas de forma conjunta.
Conceito Fundamental do MultiTaskLasso
Primordialmente, o MultiTaskLasso é uma generalização do Lasso para problemas de regressão multivariada. Decerto, ele assume que as diferentes tarefas de regressão compartilham a mesma estrutura esparsa nas features relevantes.
Conforme a documentação do scikit-learn, o MultiTaskLasso impõe que as mesmas features sejam selecionadas para todas as tarefas. Similarmente ao Lasso tradicional, ele promove esparsidade, mas de forma coerente através de todas as tarefas.
Formulação Matemática
O objetivo do MultiTaskLasso é minimizar a seguinte função:
\(\min_{W} \frac{1}{2n}||XW – Y||_F^2 + \alpha||W||_{21}\)Onde:
- X é a matriz de features \((n \times p)\)
- Y é a matriz de targets \((n \times k)\)
- W é a matriz de coeficientes \((p \times k)\)
- α é o parâmetro de regularização
- ||W||₂₁ é a norma mista L₂₁ (soma das normas L₂ das linhas)
Características Principais
Inegavelmente, o MultiTaskLasso possui propriedades únicas para problemas multivariados:
- Seleção coerente de features: Mesmas features selecionadas para todos os targets
- Norma mista L₂₁: Penaliza linhas inteiras da matriz de coeficientes
- Aprendizado multitarefa: Aprende tarefas relacionadas conjuntamente
- Transferência de conhecimento: Informação compartilhada entre tarefas
Comparação: Lasso vs MultiTaskLasso
Embora relacionados, existem diferenças fundamentais:
- Lasso: Um target, seleção independente de features
- MultiTaskLasso: Múltiplos targets, seleção conjunta de features
- MultiTaskLasso: Assume estrutura comum entre tarefas
Aplicações Práticas
Atualmente, o MultiTaskLasso é aplicado em diversos cenários:
- Problemas de recomendação: Múltiplos ratings para prever
- Análise de sensores: Múltiplos sinais correlacionados
- Bioinformática: Expressão gênica múltipla
- Visão computacional: Múltiplos atributos de imagem
Exemplo Prático: MultiTaskLasso em Ação
Ademais, vejamos um exemplo completo demonstrando o uso do MultiTaskLasso:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
''' Aplicação do MultiTaskLasso para Regressão Multivariada Este exemplo demonstra como o MultiTaskLasso pode ser usado para prever múltiplos targets simultaneamente com seleção conjunta de features ''' import numpy as np import matplotlib.pyplot as plt from sklearn.datasets import make_regression from sklearn.linear_model import MultiTaskLasso, Lasso from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.metrics import mean_squared_error, r2_score # Gerar dataset com múltiplos targets correlacionados n_samples = 1000 n_features = 20 n_tasks = 3 # Número de targets n_informative = 8 # Features realmente informativas print("Configuração do Dataset Multitarefa:") print(f"Número de amostras: {n_samples}") print(f"Número de features: {n_features}") print(f"Número de targets (tarefas): {n_tasks}") print(f"Features informativas: {n_informative}") # Gerar dados com estrutura comum entre tarefas X, Y = make_regression(n_samples=n_samples, n_features=n_features, n_targets=n_tasks, n_informative=n_informative, noise=15, random_state=42) # Adicionar correlação entre os targets correlation_matrix = np.array([[1.0, 0.7, 0.5], [0.7, 1.0, 0.6], [0.5, 0.6, 1.0]]) L = np.linalg.cholesky(correlation_matrix) Y = Y @ L.T print(f"\nDimensões: X {X.shape}, Y {Y.shape}") # Dividir em treino e teste X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3, random_state=42) # Normalizar os dados scaler_X = StandardScaler() scaler_Y = StandardScaler() X_train_scaled = scaler_X.fit_transform(X_train) X_test_scaled = scaler_X.transform(X_test) Y_train_scaled = scaler_Y.fit_transform(Y_train) Y_test_scaled = scaler_Y.transform(Y_test) print(f"\n--- Comparação: MultiTaskLasso vs Lasso Individual ---") # MultiTaskLasso (abordagem conjunta) multi_lasso = MultiTaskLasso(alpha=0.1, max_iter=10000, random_state=42) multi_lasso.fit(X_train_scaled, Y_train_scaled) Y_pred_multi = multi_lasso.predict(X_test_scaled) mse_multi = mean_squared_error(Y_test_scaled, Y_pred_multi) r2_multi = r2_score(Y_test_scaled, Y_pred_multi) print(f"\nMultiTaskLasso:") print(f"MSE total: {mse_multi:.4f}") print(f"R² total: {r2_multi:.4f}") print(f"Features selecionadas: {np.sum(np.any(multi_lasso.coef_ != 0, axis=1))}") # Lasso individual para cada tarefa (abordagem independente) individual_results = [] individual_coefs = [] for task in range(n_tasks): lasso = Lasso(alpha=0.1, max_iter=10000, random_state=42) lasso.fit(X_train_scaled, Y_train_scaled[:, task]) y_pred = lasso.predict(X_test_scaled) mse = mean_squared_error(Y_test_scaled[:, task], y_pred) r2 = r2_score(Y_test_scaled[:, task], y_pred) individual_results.append({'mse': mse, 'r2': r2}) individual_coefs.append(lasso.coef_) # Calcular médias para Lasso individual avg_mse_individual = np.mean([r['mse'] for r in individual_results]) avg_r2_individual = np.mean([r['r2'] for r in individual_results]) print(f"\nLasso Individual (média entre tarefas):") print(f"MSE médio: {avg_mse_individual:.4f}") print(f"R² médio: {avg_r2_individual:.4f}") # Análise da matriz de coeficientes print(f"\n--- Análise da Matriz de Coeficientes ---") # Coeficientes do MultiTaskLasso multi_coef = multi_lasso.coef_ print(f"\nMultiTaskLasso - Estrutura de coeficientes:") print(f"Dimensões da matriz W: {multi_coef.shape}") print(f"Features com coeficientes não-zero em todas tarefas: {np.sum(np.all(multi_coef != 0, axis=1))}") print(f"Features com coeficientes não-zero em alguma tarefa: {np.sum(np.any(multi_coef != 0, axis=1))}") print(f"Features com coeficientes zero em todas tarefas: {np.sum(np.all(multi_coef == 0, axis=1))}") # Visualização dos resultados plt.figure(figsize=(15, 10)) # Plot 1: Matriz de coeficientes do MultiTaskLasso plt.subplot(2, 3, 1) im = plt.imshow(multi_coef, aspect='auto', cmap='RdBu_r', vmin=-1, vmax=1) plt.colorbar(im) plt.xlabel('Tarefa') plt.ylabel('Feature') plt.title('Matriz de Coeficientes - MultiTaskLasso') # Plot 2: Comparação de coeficientes por feature plt.subplot(2, 3, 2) for task in range(n_tasks): plt.plot(multi_coef[:, task], 'o-', label=f'Tarefa {task+1}', alpha=0.7) plt.xlabel('Feature') plt.ylabel('Valor do Coeficiente') plt.title('Coeficientes por Tarefa') plt.legend() plt.grid(True, alpha=0.3) # Plot 3: Features selecionadas plt.subplot(2, 3, 3) features_selected = np.any(multi_coef != 0, axis=1) plt.bar(['Selecionadas', 'Não Selecionadas'], [np.sum(features_selected), np.sum(~features_selected)], color=['lightcoral', 'lightblue']) plt.title('Seleção de Features') plt.ylabel('Número de Features') # Plot 4: Comparação de performance plt.subplot(2, 3, 4) models = ['MultiTaskLasso', 'Lasso Individual'] mses = [mse_multi, avg_mse_individual] plt.bar(models, mses, color=['lightgreen', 'skyblue']) plt.ylabel('MSE') plt.title('Comparação de Performance') plt.xticks(rotation=45) # Plot 5: Correlação entre targets verdadeiros plt.subplot(2, 3, 5) corr_true = np.corrcoef(Y_test_scaled.T) im = plt.imshow(corr_true, cmap='coolwarm', vmin=-1, vmax=1) plt.colorbar(im) plt.title('Correlação - Targets Verdadeiros') plt.xlabel('Tarefa') plt.ylabel('Tarefa') # Plot 6: Correlação entre previsões plt.subplot(2, 3, 6) corr_pred = np.corrcoef(Y_pred_multi.T) im = plt.imshow(corr_pred, cmap='coolwarm', vmin=-1, vmax=1) plt.colorbar(im) plt.title('Correlação - Previsões MultiTaskLasso') plt.xlabel('Tarefa') plt.ylabel('Tarefa') plt.tight_layout() plt.show() # Análise de variação do parâmetro alpha print(f"\n--- Análise de Sensibilidade ao Parâmetro Alpha ---") alphas = [0.001, 0.01, 0.1, 1, 10] n_features_selected = [] mse_scores = [] for alpha in alphas: model = MultiTaskLasso(alpha=alpha, max_iter=10000, random_state=42) model.fit(X_train_scaled, Y_train_scaled) Y_pred = model.predict(X_test_scaled) mse = mean_squared_error(Y_test_scaled, Y_pred) n_selected = np.sum(np.any(model.coef_ != 0, axis=1)) n_features_selected.append(n_selected) mse_scores.append(mse) print(f"Alpha: {alpha:6.3f} | Features: {n_selected:2d} | MSE: {mse:.4f}") # Visualização da seleção de features vs alpha plt.figure(figsize=(12, 5)) plt.subplot(1, 2, 1) plt.semilogx(alphas, n_features_selected, 'o-', linewidth=2) plt.xlabel('Alpha') plt.ylabel('Número de Features Selecionadas') plt.title('Seleção de Features vs Alpha') plt.grid(True, alpha=0.3) plt.subplot(1, 2, 2) plt.semilogx(alphas, mse_scores, 'o-', linewidth=2) plt.xlabel('Alpha') plt.ylabel('MSE') plt.title('Performance vs Alpha') plt.grid(True, alpha=0.3) plt.tight_layout() plt.show() # Resumo final print(f"\n--- Resumo Final ---") print(f"Vantagem do MultiTaskLasso em MSE: {(avg_mse_individual - mse_multi)/avg_mse_individual*100:.1f}%") print(f"Features compartilhadas selecionadas: {np.sum(np.all(multi_coef != 0, axis=1))}") print(f"Consistência na seleção: {np.sum(np.all(multi_coef != 0, axis=1)) / np.sum(np.any(multi_coef != 0, axis=1)):.1%}") |
Vantagens do MultiTaskLasso
Embora mais complexo, o MultiTaskLasso oferece benefícios significativos:
Vantagens Principais
- Seleção coerente: Mesmo conjunto de features para todas tarefas
- Transferência de aprendizado: Tarefas se beneficiam mutuamente
- Modelos mais robustos: Menor variância através de tarefas
- Interpretabilidade: Estrutura comum facilita análise
Quando Usar MultiTaskLasso
O MultiTaskLasso é particularmente adequado quando:
- As tarefas estão correlacionadas ou relacionadas
- Há estrutura comum nas features relevantes
- Deseja-se consistência na seleção de features
- Os dados são escassos para tarefas individuais
Considerações Práticas
Algumas considerações importantes para uso eficaz:
- Normalize os dados antes de aplicar o modelo
- Use validação cruzada para selecionar o parâmetro alpha
- Considere MultiTaskElasticNet para combinar L1 e L2
- Verifique a correlação entre targets antes de usar
Enfim, o MultiTaskLasso representa uma ferramenta poderosa para problemas de regressão multivariada onde as tarefas compartilham estrutura subjacente, permitindo aprendizado mais eficiente e modelos mais interpretáveis.
Referência: https://scikit-learn.org/0.21/modules/linear_model.html#multi-task-lasso