Introdución

El análisis del uso del tiempo permite comprender cómo se distribuyen las actividades diarias de la población y evidenciar desigualdades sociales y de género, en este caso particular, en relación con el trabajo no remunerado. Este tipo de trabajo, que incluye tareas domésticas y de cuidado, suele recaer de manera de desigual entre hombres y mujeres. Por ejemplo, según el Equipo Latinoamericano de Justicia Y Genero (ELA), sostiene que en la mayoría de los hogares las responsabilidades y tareas domésticas, de crianza y de cuidado recaen sobre las mujeres. En Argentina, las mujeres participan en las actividades domésticas no remuneradas en promedio un 89.9%, 20 puntos más que los varones.

En este trabajo se utiliza la Encuesta de Usos del Tiempo de la Ciudad de Buenos Aires (2016) con el objetivo de aplicar técnicas de Machine Learning para modelar y predecir la cantidad de horas diarias dedicadas al trabajo no remunerado a partir de variables sociodemográficas. Se implementa un modelo Random Forest para regresión.

Objetivo

El objetivo principal de este trabajo es predecir la cantidad de horas diarias dedicadas al trabajo no remunerado, analizando el rol del sexo, la edad, la condición laboral y el tipo de día, entre otras variables.

Librerías

library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.5.1
## Warning: package 'ggplot2' was built under R version 4.5.1
## Warning: package 'purrr' was built under R version 4.5.1
## Warning: package 'dplyr' was built under R version 4.5.1
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   4.0.0     ✔ tibble    3.2.1
## ✔ lubridate 1.9.4     ✔ tidyr     1.3.1
## ✔ purrr     1.1.0     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(tidymodels)
## Warning: package 'tidymodels' was built under R version 4.5.2
## ── Attaching packages ────────────────────────────────────── tidymodels 1.4.1 ──
## ✔ broom        1.0.12     ✔ rsample      1.3.2 
## ✔ dials        1.4.2      ✔ tailor       0.1.0 
## ✔ infer        1.1.0      ✔ tune         2.0.1 
## ✔ modeldata    1.5.1      ✔ workflows    1.3.0 
## ✔ parsnip      1.4.1      ✔ workflowsets 1.1.1 
## ✔ recipes      1.3.1      ✔ yardstick    1.3.2
## Warning: package 'broom' was built under R version 4.5.2
## Warning: package 'dials' was built under R version 4.5.2
## Warning: package 'scales' was built under R version 4.5.1
## Warning: package 'infer' was built under R version 4.5.2
## Warning: package 'modeldata' was built under R version 4.5.2
## Warning: package 'parsnip' was built under R version 4.5.2
## Warning: package 'recipes' was built under R version 4.5.2
## Warning: package 'rsample' was built under R version 4.5.2
## Warning: package 'tailor' was built under R version 4.5.2
## Warning: package 'tune' was built under R version 4.5.2
## Warning: package 'workflows' was built under R version 4.5.2
## Warning: package 'workflowsets' was built under R version 4.5.2
## Warning: package 'yardstick' was built under R version 4.5.2
## ── Conflicts ───────────────────────────────────────── tidymodels_conflicts() ──
## ✖ scales::discard() masks purrr::discard()
## ✖ dplyr::filter()   masks stats::filter()
## ✖ recipes::fixed()  masks stringr::fixed()
## ✖ dplyr::lag()      masks stats::lag()
## ✖ yardstick::spec() masks readr::spec()
## ✖ recipes::step()   masks stats::step()
library(stringi)
## Warning: package 'stringi' was built under R version 4.5.2
library(ranger)
## Warning: package 'ranger' was built under R version 4.5.2

Carga del dataset

# Cargar datos de la Encuesta de Usos del Tiempo (CABA 2016)
data <- read.csv("encuesta_uso_tiempo_2016.csv")

# Ver estructura general
glimpse(data)
## Rows: 2,336
## Columns: 27
## $ hogar                      <chr> "1_1", "2_1", "3_1", "4_1", "5_1", "6_1", "…
## $ sexo                       <chr> "Varon", "Varon", "Varon", "Varon", "Varon"…
## $ edad                       <int> 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,…
## $ dia_laborable              <chr> "D\xeda no laborable", "D\xeda no laborable…
## $ trabajo_pago               <dbl> 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0…
## $ trabajo_domestico_no_pago  <dbl> 0.1, 1.0, 0.2, 1.8, 0.0, 3.0, 0.3, 0.3, 0.3…
## $ voluntariados              <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
## $ estudio_educacion          <dbl> 0.0, 8.3, 11.3, 4.0, 8.3, 0.0, 6.7, 8.8, 10…
## $ recreacion                 <dbl> 9.0, 2.7, 2.6, 7.7, 4.7, 4.2, 2.2, 4.9, 1.8…
## $ aplicaciones               <dbl> 7.3, 2.5, 0.3, 3.0, 1.8, 4.8, 4.7, 1.5, 2.5…
## $ tareas_cuidados            <dbl> 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2, 0.0, 0.0…
## $ cuidado_personal           <dbl> 8.2, 10.2, 10.6, 9.5, 9.3, 15.7, 11.8, 9.8,…
## $ trabajo_pago2              <dbl> 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0…
## $ trabajo_domestico_no_pago2 <dbl> 0.1, 1.0, 0.2, 1.3, 0.0, 3.0, 0.2, 0.3, 0.1…
## $ voluntariados2             <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
## $ estudio_educacion2         <dbl> 0.0, 8.3, 11.3, 4.0, 8.3, 0.0, 6.6, 8.8, 10…
## $ recreacion2                <dbl> 8.8, 2.3, 2.1, 7.2, 4.7, 2.3, 1.7, 4.3, 0.9…
## $ aplicaciones2              <dbl> 7.3, 2.5, 0.3, 3.0, 1.8, 4.8, 4.7, 1.5, 2.5…
## $ tareas_cuidados2           <dbl> 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, 0.0, 0.0…
## $ cuidado_personal2          <dbl> 7.9, 9.8, 10.1, 8.5, 9.3, 13.8, 10.9, 9.1, …
## $ dia_tipico                 <chr> "D\xeda at\xedpico", "D\xeda at\xedpico", "…
## $ rango_etario               <chr> "14-24", "14-24", "14-24", "14-24", "14-24"…
## $ nivel_educativo            <chr> "Secundario incompleto", "Secundario incomp…
## $ relacion_parentesco_jefe   <chr> "Hijo/a - Hijastro/a", "Hijo/a - Hijastro/a…
## $ tipo_hogar                 <chr> "Nuclear con nucleo incompleto", "Nuclear c…
## $ quintil_ingreso            <chr> "5to quintil", "5to quintil", "5to quintil"…
## $ estado_ocupacional         <chr> "Inactivo", "Inactivo", "Inactivo", "Inacti…

Variables elegidas

sexo edad nivel_educativo rango_etario tipo_hogar estado_ocupacional dia_laborable

data_ml <- data %>%
  select(
    horas_no_rem = trabajo_domestico_no_pago,
    sexo,
    edad,
    nivel_educativo,
    rango_etario,
    tipo_hogar,
    estado_ocupacional,
    dia_laborable
  ) %>%
  drop_na()

Limpieza

data_ml <- data_ml %>%
  mutate(across(where(is.character),
                ~ stri_trans_general(., "Latin-ASCII")))

División TRAIN/TEST

set.seed(123)
split <- initial_split(data_ml, prop = 0.8)
train_data <- training(split)
test_data  <- testing(split)

Receta

rf_recipe <- recipe(horas_no_rem ~ ., data = train_data) %>%
  step_dummy(all_nominal_predictors()) %>%
  step_normalize(all_numeric_predictors())
rf_model <- rand_forest(
  trees = 500,
  mode = "regression"
) %>%
  set_engine("ranger", importance = "permutation")

Workflow

rf_wf <- workflow() %>%
  add_recipe(rf_recipe) %>%
  add_model(rf_model)

Entrenamiento

rf_fit <- rf_wf %>%
  fit(data = train_data)
rf_fit
## ══ Workflow [trained] ══════════════════════════════════════════════════════════
## Preprocessor: Recipe
## Model: rand_forest()
## 
## ── Preprocessor ────────────────────────────────────────────────────────────────
## 2 Recipe Steps
## 
## • step_dummy()
## • step_normalize()
## 
## ── Model ───────────────────────────────────────────────────────────────────────
## Ranger result
## 
## Call:
##  ranger::ranger(x = maybe_data_frame(x), y = y, num.trees = ~500,      importance = ~"permutation", num.threads = 1, verbose = FALSE,      seed = sample.int(10^5, 1)) 
## 
## Type:                             Regression 
## Number of trees:                  500 
## Sample size:                      1868 
## Number of independent variables:  15 
## Mtry:                             3 
## Target node size:                 5 
## Variable importance mode:         permutation 
## Splitrule:                        variance 
## OOB prediction error (MSE):       4.67181 
## R squared (OOB):                  0.2415566

Evaluación del modelo

results_test <- test_data %>%
  bind_cols(predict(rf_fit, test_data))

metrics(
  results_test,
  truth = horas_no_rem,
  estimate = .pred
)
## # A tibble: 3 × 3
##   .metric .estimator .estimate
##   <chr>   <chr>          <dbl>
## 1 rmse    standard       2.10 
## 2 rsq     standard       0.272
## 3 mae     standard       1.54

En el conjunto de test, el modelo obtuvo los siguientes resultados: - rmse: 2,11 horas - rsq: 0,27 - mae: 1,54 horas

Estos valores indican que en promedio el error absoluto del modelo es de aproximadamente una hora y media en la predicción del tiempo dedicado al trabajo no remunerado.

Gráfico Valores reales vs predichos

ggplot(results_test, aes(x = horas_no_rem, y = .pred)) +
  geom_point(alpha = 0.6) +
  geom_abline(slope = 1, intercept = 0, linetype = "dashed", color = "red") +
  labs(
    title = "Valores reales vs predichos",
    x = "Horas reales de trabajo no remunerado",
    y = "Horas predichas"
  ) +
  theme_minimal()

El grafico muestra que el modelo captura la tendencia general del trabajo no remunerado, concentrando la mayoría de las observaciones cerca de la línea de igualdad. Sin embargo se observa una dispersión creciente a medida que aumentan las horas reales. Esto indicaría que el modelo presenta mayores dificultades para predecir valores extremos.

library(vip)
## Warning: package 'vip' was built under R version 4.5.2
## 
## Adjuntando el paquete: 'vip'
## The following object is masked from 'package:utils':
## 
##     vi
vip(pull_workflow_fit(rf_fit)$fit)
## Warning: `pull_workflow_fit()` was deprecated in workflows 0.2.3.
## ℹ Please use `extract_fit_parsnip()` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

El grafico muestra que:

  • La cantidad de horas dedicadas al trabajo no remunerado varía fuertemente según el ciclo de vida.
  • Las personas dedican más tiempo a tareas domésticas y de cuidado en días no laborables.
  • Existen diferencias sistematicas en la dedicación al trabajo no remunerado según el género y la situación laboral.

Conclusión

El modelo Random Forest permitió aproximar de manera razonable la cantidad de horas dedicadas al trabajo no remunerado. Si bien el poder explicativo del modelo es moderado, los resultados son coherentes.

La importancia de variables como sexo, edad y el estado ocupacional refuerza la evidencia de que el trabajo no remunerado está fuertemente condicionado por factores estructurales y de género.

Un posible análisis futuro podría profundizar en las tareas de cuidado de manera especifica, dado que el presente analisis considera únicamente las horas totales de trabajo nno remunerado sin distienguir entre distintos tipos de actividades.