data <- read.csv("Grupo_5.csv")
Observamos los primeros registros:
head(data)
## ID Edad Salario Experiencia Ciudad Nivel_Educativo Horas_Trabajo_Semana
## 1 1 47 35465 27 Ponce Primaria 39
## 2 2 31 30399 37 Bayamón Secundaria NA
## 3 3 29 32214 36 San Juan Secundaria 46
## 4 4 56 28196 38 San Juan Primaria 57
## 5 5 45 66854 10 San Juan Universitario 25
## 6 6 34 22328 32 San Juan Primaria NA
## Estado_Civil Sector_Laboral Cantidad_Hijos Propietario_Vivienda Rango_Salario
## 1 Soltero Independiente NA No Medio
## 2 Soltero Público NA Sí Medio
## 3 Soltero Independiente 1 Sí Medio
## 4 Independiente 5 Sí Bajo
## 5 Casado Privado 0 No Alto
## 6 Soltero Independiente 3 No Bajo
Resumen estadistico de nuestra base de datos:
summary(data)
## ID Edad Salario Experiencia
## Min. : 1.00 Min. :18.00 Min. :20393 Min. : 1.00
## 1st Qu.: 25.75 1st Qu.:32.00 1st Qu.:32892 1st Qu.:13.00
## Median : 50.50 Median :41.00 Median :45581 Median :22.00
## Mean : 50.50 Mean :43.14 Mean :47654 Mean :21.61
## 3rd Qu.: 75.25 3rd Qu.:56.00 3rd Qu.:61180 3rd Qu.:32.00
## Max. :100.00 Max. :65.00 Max. :79430 Max. :39.00
## NA's :5 NA's :7 NA's :17
## Ciudad Nivel_Educativo Horas_Trabajo_Semana Estado_Civil
## Length:100 Length:100 Min. :20.00 Length:100
## Class :character Class :character 1st Qu.:28.25 Class :character
## Mode :character Mode :character Median :39.00 Mode :character
## Mean :38.71
## 3rd Qu.:47.75
## Max. :60.00
## NA's :10
## Sector_Laboral Cantidad_Hijos Propietario_Vivienda Rango_Salario
## Length:100 Min. :0.0 Length:100 Length:100
## Class :character 1st Qu.:1.0 Class :character Class :character
## Mode :character Median :3.0 Mode :character Mode :character
## Mean :2.7
## 3rd Qu.:4.0
## Max. :5.0
## NA's :10
Indentificamos valores faltantes:
colSums(is.na(data))
## ID Edad Salario
## 0 5 7
## Experiencia Ciudad Nivel_Educativo
## 17 0 0
## Horas_Trabajo_Semana Estado_Civil Sector_Laboral
## 10 0 0
## Cantidad_Hijos Propietario_Vivienda Rango_Salario
## 10 0 0
Variables con valores faltantes:
+ Edad → 5 valores faltantes
+ Salario → 7 valores faltantes
+ Experiencia → 17 valores faltantes
+ Horas_Trabajo_Semana → 10 valores faltantes
+Cantidad_Hijos → 10 valores faltantes
Verificamos Inconsistencias en los datos:
sum(duplicated(data))
## [1] 0
sapply(data, function(x) if(is.character(x) | is.factor(x)) unique(x))
## $ID
## NULL
##
## $Edad
## NULL
##
## $Salario
## NULL
##
## $Experiencia
## NULL
##
## $Ciudad
## [1] "Ponce" "Bayamón" "San Juan" "" "Caguas"
##
## $Nivel_Educativo
## [1] "Primaria" "Secundaria" "Universitario" ""
##
## $Horas_Trabajo_Semana
## NULL
##
## $Estado_Civil
## [1] "Soltero" "" "Casado" "Divorciado"
##
## $Sector_Laboral
## [1] "Independiente" "Público" "Privado" ""
##
## $Cantidad_Hijos
## NULL
##
## $Propietario_Vivienda
## [1] "No" "Sí" ""
##
## $Rango_Salario
## [1] "Medio" "Bajo" "Alto" ""
Valores vacíos (““) en las siguientes columnas:
Ciudad
Nivel_Educativo
Estado_Civil
Sector_Laboral
Propietario_Vivienda
Rango_Salario
boxplot(data$Edad, main="Boxplot de Edad")
boxplot(data$Salario, main="Boxplot de Salario")
boxplot(data$Experiencia, main="Boxplot de Experiencia")
Elegimos estas tres variables para analizar si tiene datos atipicos ya que suelen ser propensas en otros estudios estadisticos a contener outlier. Sin embargo, en este caso no tienen datos atipicos.
Al analizar nuestra base de datos, identificamos diversos problemas que requieren preprocesamiento. En primer lugar, encontramos valores faltantes en varias variables clave: Edad (5), Salario (7), Experiencia (17), Horas de Trabajo por Semana (10) y Cantidad de Hijos (10). Esto sugiere la necesidad de una estrategia de imputación adecuada para evitar sesgos en el análisis. En cuanto a las inconsistencias, verificamos que no hay registros duplicados, lo cual es positivo. Sin embargo, detectamos errores tipográficos y valores en blanco en variables categóricas como Ciudad, Nivel Educativo, Estado Civil, Sector Laboral, Propietario de Vivienda y Rango Salarial, lo que podría afectar la interpretación de los datos. Además, en la variable Ciudad encontramos valores vacíos, lo que indica datos posiblemente mal ingresados. Estos problemas deben corregirse para asegurar la calidad del análisis posterior.
Valores Faltantes:
• Edad: Imputación con media
• Salario: Imputación con media
• Experiencia: Imputación con media
• Horas_Trabajo_Semana: Imputación con mediana
• Cantidad_Hijos: Imputación con mediana
Variables Categoricas
• Ciudad: Imputación con moda
• Nivel_Educativo: Imputación con moda
• Estado_Civil: Imputación con moda
• Sector_Laboral: Imputación con moda
• Propietario_Vivienda: Imputación con moda
• Rango_Salario: Imputación con moda
library(tidyverse)
## ── 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 3.5.1 ✔ tibble 3.2.1
## ✔ lubridate 1.9.3 ✔ tidyr 1.3.1
## ✔ purrr 1.0.2
## ── 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(dplyr)
Se utilizó la media porque estas variables suelen seguir una distribución normal, No tienen datos atipicos.La media es adecuada cuando no hay valores atípicos significativos que puedan distorsionar la tendencia central de los datos.Mantiene la estructura original de la variable sin introducir sesgos.
Se usó la mediana debido a la posible asimetría en la distribución de los horarios de trabajo.Evita el impacto de valores extremos, como personas que trabajan muy pocas o muchas horas semanales.
Se aplicó la mediana porque es una variable discreta (conteo). La media podría generar valores decimales, lo que no tiene sentido en este tipo de variable.
Verifico si hay variables constantes
sapply(data[, c("Ciudad", "Nivel_Educativo", "Estado_Civil", "Sector_Laboral", "Propietario_Vivienda", "Rango_Salario")], function(x) length(unique(x)))
## Ciudad Nivel_Educativo Estado_Civil
## 5 4 4
## Sector_Laboral Propietario_Vivienda Rango_Salario
## 4 3 4
library(mice)
##
## Attaching package: 'mice'
## The following object is masked from 'package:stats':
##
## filter
## The following objects are masked from 'package:base':
##
## cbind, rbind
# 1. Imputación con la media para variables numéricas
data$Edad[is.na(data$Edad)] <- mean(data$Edad, na.rm = TRUE)
data$Salario[is.na(data$Salario)] <- mean(data$Salario, na.rm = TRUE)
data$Experiencia[is.na(data$Experiencia)] <- mean(data$Experiencia, na.rm = TRUE)
# 2. Imputación con la mediana para variables numéricas
data$Horas_Trabajo_Semana[is.na(data$Horas_Trabajo_Semana)] <- median(data$Horas_Trabajo_Semana, na.rm = TRUE)
data$Cantidad_Hijos[is.na(data$Cantidad_Hijos)] <- median(data$Cantidad_Hijos, na.rm = TRUE)
# 3. Imputación con la moda para variables categóricas
mode_function <- function(x) {
x <- x[!is.na(x) & x != ""] # Excluir valores vacíos y NA
uniq_x <- unique(x)
return(uniq_x[which.max(tabulate(match(x, uniq_x)))])
}
# variables categóricas
categorical_vars <- c("Ciudad", "Nivel_Educativo", "Estado_Civil", "Sector_Laboral", "Propietario_Vivienda", "Rango_Salario")
# Aplicar imputación con la moda a cada variable categórica
for (var in categorical_vars) {
data[[var]][is.na(data[[var]]) | data[[var]] == ""] <- mode_function(data[[var]])
}
# 4. Verificación final: Revisar si quedan valores faltantes
colSums(is.na(data))
## ID Edad Salario
## 0 0 0
## Experiencia Ciudad Nivel_Educativo
## 0 0 0
## Horas_Trabajo_Semana Estado_Civil Sector_Laboral
## 0 0 0
## Cantidad_Hijos Propietario_Vivienda Rango_Salario
## 0 0 0
data_imputaciones <- data %>% select(Edad, Salario, Experiencia, Horas_Trabajo_Semana, Cantidad_Hijos)
# Crear una copia de data_imputaciones
data_comparaciones <- data_imputaciones
# Aplicar imputaciones inversas
data_comparaciones$Edad[is.na(data_comparaciones$Edad)] <- median(data_imputaciones$Edad, na.rm = TRUE)
data_comparaciones$Salario[is.na(data_comparaciones$Salario)] <- median(data_imputaciones$Salario, na.rm = TRUE)
data_comparaciones$Experiencia[is.na(data_comparaciones$Experiencia)] <- median(data_imputaciones$Experiencia, na.rm = TRUE)
data_comparaciones$Horas_Trabajo_Semana[is.na(data_comparaciones$Horas_Trabajo_Semana)] <- mean(data_imputaciones$Horas_Trabajo_Semana, na.rm = TRUE) #
data_comparaciones$Cantidad_Hijos[is.na(data_comparaciones$Cantidad_Hijos)] <- mean(data_imputaciones$Cantidad_Hijos, na.rm = TRUE)
# Verificar que se aplicaron las imputaciones correctamente
colSums(is.na(data_comparaciones))
## Edad Salario Experiencia
## 0 0 0
## Horas_Trabajo_Semana Cantidad_Hijos
## 0 0
Ahora compararemos las dos imputaciones realizadas a cada variable.
# 1. Crear una tabla comparativa con estadísticas por variable
comparison <- data.frame(
Variable = c("Edad", "Salario", "Experiencia", "Horas_Trabajo_Semana", "Cantidad_Hijos"), Media_MediaMediana = sapply(data_imputaciones, mean),
Mediana_MediaMediana = sapply(data_imputaciones, median),
SD_MediaMediana = sapply(data_imputaciones, sd),
Media_MedianaMedia = sapply(data_comparaciones, mean),
Mediana_MedianaMedia = sapply(data_comparaciones, median),
SD_MedianaMedia = sapply(data_comparaciones, sd))
print(comparison)
## Variable Media_MediaMediana
## Edad Edad 43.13684
## Salario Salario 47654.06452
## Experiencia Experiencia 21.61446
## Horas_Trabajo_Semana Horas_Trabajo_Semana 38.74000
## Cantidad_Hijos Cantidad_Hijos 2.73000
## Mediana_MediaMediana SD_MediaMediana Media_MedianaMedia
## Edad 43.06842 13.461213 43.13684
## Salario 47654.06452 16765.316091 47654.06452
## Experiencia 21.61446 10.002860 21.61446
## Horas_Trabajo_Semana 39.00000 10.853124 38.74000
## Cantidad_Hijos 3.00000 1.549552 2.73000
## Mediana_MedianaMedia SD_MedianaMedia
## Edad 43.06842 13.461213
## Salario 47654.06452 16765.316091
## Experiencia 21.61446 10.002860
## Horas_Trabajo_Semana 39.00000 10.853124
## Cantidad_Hijos 3.00000 1.549552
Observamos que ambas imputaciones tuvieron el mismo efecto en las variables.
library(ggplot2)
library(plotly)
##
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
##
## last_plot
## The following object is masked from 'package:stats':
##
## filter
## The following object is masked from 'package:graphics':
##
## layout
library(dplyr)
library(tidyr)
# 1. Convertir los datos en formato largo para comparación de imputaciones
data_long <- bind_rows(
data_imputaciones %>% mutate(Origen = "Media-Mediana"),
data_comparaciones %>% mutate(Origen = "Mediana-Media")
) %>%
pivot_longer(cols = c(Edad, Salario, Experiencia, Horas_Trabajo_Semana, Cantidad_Hijos),
names_to = "Variable", values_to = "Valor")
# 2. Crear el gráfico de densidad comparando estrategias de imputación
p1 <- ggplot(data_long, aes(x = Valor, color = Origen, fill = Origen, text = paste("Origen:", Origen))) +
geom_density(alpha = 0.2) +
facet_wrap(~Variable, scales = "free") +
labs(title = "Comparación de Estrategias de Imputación", x = "Valor", y = "Densidad") +
theme_minimal()
# 3. Hacer el gráfico interactivo con Plotly
ggplotly(p1, tooltip = c("text", "x", "y"))
Podemos observar que ambas imputaciones obtuvieron un impacto similar en los datos. Ambas técnicas preservaron la estructura y distribución de los datos de manera comparable. En otras palabras, tanto la imputación por media como la imputación por mediana no alteraron significativamente las características originales de las variables.
En nuestra base de datos, la imputación de valores faltantes con media, mediana y moda no alteró significativamente la distribución ni la estructura de los datos.
Las variables Edad, Salario y Experiencia fueron imputadas con media, ya que siguen una distribución normal y no presentaron valores atípicos significativos. En contraste, Horas_Trabajo_Semana y Cantidad_Hijos se imputaron con mediana para evitar la influencia de valores extremos y preservar la variabilidad de los datos.
Al comparar las estrategias, observamos que ambas generaron resultados similares, lo que sugiere que cualquiera de las dos puede utilizarse sin afectar el análisis posterior. Sin embargo, en casos con valores atípicos, la mediana sería una opción más segura para evitar sesgos.
Para las variables categóricas, la imputación con moda mantuvo la distribución original sin generar valores artificiales, asegurando coherencia en el análisis.
En conclusión, la elección del método de imputación debe basarse en la distribución de los datos y la presencia de valores atípicos para garantizar resultados representativos y confiables.
Convertir variables Categoricas a Facatores
data <- data %>%
mutate(across(c(Ciudad, Nivel_Educativo, Estado_Civil,
Sector_Laboral, Propietario_Vivienda, Rango_Salario),
as.factor))
# Verificar los cambios
str(data)
## 'data.frame': 100 obs. of 12 variables:
## $ ID : int 1 2 3 4 5 6 7 8 9 10 ...
## $ Edad : num 47 31 29 56 45 ...
## $ Salario : num 35465 30399 32214 28196 66854 ...
## $ Experiencia : num 27 37 36 38 10 ...
## $ Ciudad : Factor w/ 4 levels "Bayamón","Caguas",..: 3 1 4 4 4 4 1 1 4 3 ...
## $ Nivel_Educativo : Factor w/ 3 levels "Primaria","Secundaria",..: 1 2 2 1 3 1 1 1 3 3 ...
## $ Horas_Trabajo_Semana: num 39 39 46 57 25 39 32 56 43 20 ...
## $ Estado_Civil : Factor w/ 3 levels "Casado","Divorciado",..: 3 3 3 2 1 3 2 2 2 1 ...
## $ Sector_Laboral : Factor w/ 3 levels "Independiente",..: 1 3 1 1 2 1 2 2 1 2 ...
## $ Cantidad_Hijos : num 3 3 1 5 0 3 4 2 2 4 ...
## $ Propietario_Vivienda: Factor w/ 2 levels "No","Sí": 1 2 2 2 1 1 1 1 1 1 ...
## $ Rango_Salario : Factor w/ 3 levels "Alto","Bajo",..: 3 3 3 2 1 2 3 3 2 2 ...
Discretización de Variables Numéricas en Categorías
# Discretización de Edad en Grupos
data <- data %>%
mutate(Grupo_Edad = case_when(
Edad < 25 ~ "Joven",
Edad >= 25 & Edad < 45 ~ "Adulto",
Edad >= 45 & Edad < 65 ~ "Adulto Mayor",
Edad >= 65 ~ "Tercera Edad"
))
# Discretización de Salario en Rango
data <- data %>%
mutate(Grupo_Salario = cut(Salario,
breaks = c(20000, 35000, 50000, 65000, 80000),
labels = c("Bajo", "Medio-Bajo", "Medio", "Alto"),
include.lowest = TRUE))
# Verificar la transformación
table(data$Grupo_Edad)
##
## Adulto Adulto Mayor Joven Tercera Edad
## 46 41 10 3
table(data$Grupo_Salario)
##
## Bajo Medio-Bajo Medio Alto
## 29 31 21 19
Interpretación de las Transformaciones Realizadas Después de aplicar la discretización a Edad y Salario, los datos quedaron categorizados de la siguiente manera:
Discretización de Edad (Grupo_Edad) La variable Edad fue transformada en cuatro grupos:
Interpretación: La mayoría de las observaciones pertenecen a los grupos Adulto y Adulto Mayor, lo que indica que la base de datos tiene una mayor representación de personas entre 25 y 65 años. El grupo Joven (<25 años) tiene solo 10 individuos, lo que sugiere una baja presencia de personas jóvenes en el conjunto de datos. La Tercera Edad (≥ 65 años) es el grupo más pequeño con 3 personas.
Discretización de Salario (Grupo_Salario) La variable Salario fue categorizada en cuatro rangos:
Interpretación: La mayoría de los datos están en los grupos Bajo y Medio-Bajo, lo que indica que los salarios más frecuentes están entre 20,000 y 50,000. Hay menos personas en el rango Alto, lo que sugiere que los salarios elevados son menos comunes en la base de datos.
Conversión de Variables Categóricas a Factores Las variables categóricas en nuestra base de datos incluyen Ciudad, Nivel_Educativo, Estado_Civil, Sector_Laboral, Propietario_Vivienda y Rango_Salario. Convertirlas en factores permite que los modelos estadísticos y de machine learning las interpreten correctamente y evita errores en los análisis.
Discretización de Edad La variable Edad es numérica, pero en muchos análisis es útil agruparla en rangos etarios. Esto permite interpretar los resultados de manera más clara y facilita comparaciones entre diferentes grupos de edad.
Discretización de Salario La variable Salario es continua, pero los análisis de ingresos suelen hacerse por rangos salariales para facilitar la interpretación de patrones y comparaciones entre distintos niveles económicos.
# Cargar librerías necesarias
library(plotly)
library(ggplot2)
library(dplyr)
library(reshape2) # Asegurar que reshape2 está cargado
##
## Attaching package: 'reshape2'
## The following object is masked from 'package:tidyr':
##
## smiths
# Seleccionar solo las variables numéricas
numeric_vars <- data %>% select(where(is.numeric))
# Verificar si hay suficientes variables numéricas
if (ncol(numeric_vars) > 1) {
# Calcular la matriz de correlación
cor_matrix <- cor(numeric_vars, use = "complete.obs")
# Convertir la matriz en un formato adecuado para Plotly
cor_df <- melt(cor_matrix)
# Crear el mapa de calor con Plotly
heatmap <- plot_ly(
data = cor_df,
x = ~Var1,
y = ~Var2,
z = ~value,
type = "heatmap",
colorscale = "Viridis"
) %>%
layout(title = "Mapa de calor de correlaciones entre variables numéricas",
xaxis = list(title = "Variables"),
yaxis = list(title = "Variables"))
# Mostrar el gráfico interactivo
heatmap
} else {
print("No hay suficientes variables numéricas en la base de datos para calcular la correlación.")
}
El mapa de calor revela varias correlaciones clave entre las variables. La edad y el salario están fuertemente correlacionados de manera positiva, sugiriendo que a medida que aumenta la edad, también tiende a aumentar el salario, posiblemente debido a la experiencia. Además, horas de trabajo por semana y cantidad de hijos muestran una correlación positiva moderada, lo que podría indicar que las personas con más hijos tienden a trabajar más horas. El ID no parece tener una relación significativa con ninguna otra variable, lo que es esperable dado que es solo un identificador único.
# Verificar que la variable Rango_Salario sea un factor
data$Rango_Salario <- as.factor(data$Rango_Salario)
# Crear el gráfico de barras con ggplot2
bar_plot <- ggplot(data, aes(x = Rango_Salario, y = Cantidad_Hijos, fill = Rango_Salario)) +
geom_col(stat = "summary", fun = "mean") + # Mostrar la media de cantidad de hijos por rango de salario
labs(title = "Cantidad Promedio de Hijos según Rango de Salario",
x = "Rango de Salario",
y = "Cantidad Promedio de Hijos") +
theme_minimal() +
theme(legend.position = "none") # Ocultar la leyenda porque el fill es redundante
## Warning in geom_col(stat = "summary", fun = "mean"): Ignoring unknown
## parameters: `stat` and `fun`
# Convertirlo en un gráfico interactivo con ggplotly
bar_plot_interactive <- ggplotly(bar_plot)
# Mostrar el gráfico
bar_plot_interactive
El gráfico muestra que las personas con un rango de salario medio tienen el mayor número promedio de hijos, seguido por aquellos con un rango de salario alto, quienes tienen menos hijos en promedio, y los de rango bajo tienen la cantidad más baja. Esto sugiere que, en este conjunto de datos, las personas con salarios más altos tienden a tener menos hijos, mientras que las de salario medio tienen más hijos, posiblemente debido a factores socioeconómicos o decisiones personales relacionadas con el bienestar económico.
# Asegurar que las variables numéricas están correctamente definidas
data$Experiencia <- as.numeric(data$Experiencia)
data$Salario <- as.numeric(data$Salario)
# Crear el gráfico de dispersión con ggplot2
scatter_plot <- ggplot(data, aes(x = Experiencia, y = Salario)) +
geom_point(color = "blue", alpha = 0.6) + # Puntos en azul con transparencia
geom_smooth(method = "lm", color = "red", se = TRUE) + # Línea de tendencia en rojo con intervalo de confianza
labs(title = "Relación entre Salario y Experiencia",
x = "Años de Experiencia",
y = "Salario") +
theme_minimal()
# Convertirlo en un gráfico interactivo con ggplotly
scatter_plot_interactive <- ggplotly(scatter_plot)
## `geom_smooth()` using formula = 'y ~ x'
# Mostrar el gráfico
scatter_plot_interactive
El gráfico de dispersión con la línea de regresión muestra una relación negativa entre salario y años de experiencia, ya que la línea de tendencia muestra una ligera disminución del salario a medida que aumentan los años de experiencia. Esto sugiere que en este conjunto de datos, las personas con más experiencia tienden a tener salarios más bajos, aunque con una alta dispersión de los datos. La banda sombreada alrededor de la línea de regresión indica el intervalo de confianza, lo que resalta la variabilidad de los salarios con respecto a la experiencia.
Este trabajo permitió aplicar técnicas de preprocesamiento, imputación de datos, transformación de variables y análisis exploratorio para mejorar la calidad del conjunto de datos y obtener conclusiones significativas.
Se identificaron valores faltantes y se aplicaron estrategias adecuadas: media para variables con distribución normal (Edad, Salario, Experiencia), mediana para variables con posible sesgo (Horas de Trabajo por Semana y Cantidad de Hijos) y moda para variables categóricas. La comparación de imputaciones mostró que ambas estrategias ofrecieron resultados similares sin alterar significativamente la distribución de los datos.
Las variables numéricas se discretizaron para facilitar su interpretación. Edad se agrupó en categorías (Joven, Adulto, Adulto Mayor y Tercera Edad), mientras que Salario se dividió en rangos (Bajo, Medio-Bajo, Medio y Alto). Esto permitió analizar tendencias dentro del conjunto de datos.
El análisis exploratorio reveló patrones importantes:
- Edad y Salario tienen una correlación positiva, lo
que sugiere que los salarios aumentan con la edad.
- Horas de Trabajo por Semana y Cantidad de Hijos están
moderadamente relacionadas, indicando que las personas con más
hijos tienden a trabajar más horas.
- Las personas con salarios medianos tienen más hijos en
promedio, mientras que quienes ganan menos o más tienen menos
hijos.
- Existe una relación negativa entre Experiencia y
Salario, lo que indica que la experiencia no siempre es un
factor determinante en los ingresos, posiblemente por influencia del
sector laboral o la formación académica.
Las técnicas aplicadas garantizaron la validez del análisis, permitiendo identificar tendencias sin introducir sesgos. En general, este trabajo demuestra la importancia del preprocesamiento de datos para obtener resultados confiables y mejorar la interpretación de la información.