Población

cienciadatos

La población del dataset de salarios de Data Science presenta las siguientes características:

Variables Numéricas

Variables Categóricas

Estos datos reflejan un conjunto variado en términos de títulos de puestos y ubicación, con un énfasis en el mercado de EE. UU

set.seed(975)
DB <- read_csv("DataScience_salaries_2024.csv", show_col_types = FALSE)
DB=as.data.frame(unclass(DB), stringsAsFactors = TRUE)
str(DB)
## 'data.frame':    14838 obs. of  11 variables:
##  $ work_year         : num  2021 2021 2020 2021 2022 ...
##  $ experience_level  : Factor w/ 4 levels "EN","EX","MI",..: 3 3 3 3 4 3 4 1 2 1 ...
##  $ employment_type   : Factor w/ 4 levels "CT","FL","FT",..: 3 3 3 3 3 3 3 3 3 3 ...
##  $ job_title         : Factor w/ 153 levels "Admin & Data Analyst",..: 90 22 90 131 114 131 87 90 109 145 ...
##  $ salary            : num  30400000 11000000 11000000 8500000 7500000 7000000 7000000 6600000 6000000 5500000 ...
##  $ salary_currency   : Factor w/ 23 levels "AUD","BRL","CAD",..: 5 10 10 13 12 13 12 10 12 13 ...
##  $ salary_in_usd     : num  40038 36259 35735 77364 95386 ...
##  $ employee_residence: Factor w/ 88 levels "AD","AE","AM",..: 16 39 39 48 43 48 43 39 43 48 ...
##  $ remote_ratio      : num  100 50 50 50 50 50 50 100 50 50 ...
##  $ company_location  : Factor w/ 77 levels "AD","AE","AM",..: 15 75 35 43 39 43 39 35 39 43 ...
##  $ company_size      : Factor w/ 3 levels "L","M","S": 1 1 1 3 1 3 1 2 1 1 ...
sprintf("El número de filas para la base de datos es: %d", nrow(DB))
## [1] "El número de filas para la base de datos es: 14838"
# Calcular el total de cada nivel en el dataset completo
experience_counts <- table(DB$experience_level) 
experience_counts
## 
##   EN   EX   MI   SE 
## 1148  441 3553 9696

Tipo de muestreo: Muestreo aleatorio estratificado

Muestra 1

Este dataset contiene información sobre salarios de profesionales en ciencia de datos. Algunas de las variables clave que podrían servir para estratificar la muestra son:

Para una estratificación idónea, se selecciona la variable experience_level. Que esta categorizada en cuatro niveles.

# Definir los parámetros
N <- 14838       # Tamaño de la población
Z <- 1.96        # Valor Z para un 95% de nivel de confianza
p <- 0.5         # Proporción estimada
E <- 0.05        # Margen de error

# Calcular el tamaño de muestra
n <- (N * Z^2 * p * (1 - p)) / ((N - 1) * E^2 + Z^2 * p * (1 - p))
n <- ceiling(n)  # Redondear al siguiente número entero

# Mostrar el tamaño de muestra
sprintf("La muestra significativa de la población es: %d", n)
## [1] "La muestra significativa de la población es: 375"
# Se saca el tamaño representativo de la muestra del estrato
# n_h = (N_h/N)*n
N = 14838
N_h.EN=nrow(subset(DB, experience_level == "EN"))
n_h.EN= (N_h.EN/N)*n
sprintf("El tamaño de la muestra para el primer estrato es: %s", round(n_h.EN,0))
## [1] "El tamaño de la muestra para el primer estrato es: 29"
N_h.EX=nrow(subset(DB, experience_level == "EX"))
n_h.EX= (N_h.EX/N)*n
sprintf("El tamaño de la muestra para el segundo estrato es: %s", round(n_h.EX,0))
## [1] "El tamaño de la muestra para el segundo estrato es: 11"
N_h.MI=nrow(subset(DB, experience_level == "MI"))
n_h.MI= (N_h.MI/N)*n
sprintf("El tamaño de la muestra para el tercer estrato es: %s", round(n_h.MI,0))
## [1] "El tamaño de la muestra para el tercer estrato es: 90"
N_h.SE=nrow(subset(DB, experience_level == "SE"))
n_h.SE= (N_h.SE/N)*n
sprintf("El tamaño de la muestra para el cuarto estrato es: %s", round(n_h.SE,0))
## [1] "El tamaño de la muestra para el cuarto estrato es: 245"
# Se saca la muestra aleatoria de cada estrato, con el tamaño especificado para cada estrato
# Definir el tamaño de la muestra redondeado para el nivel de experiencia "EN"
tamañomuestra.EN <- round(n_h.EN, 0)
# Filtrar el dataset para el nivel de experiencia "EN" y tomar una muestra aleatoria sin reemplazo
muestra.EN <- DB %>%
  filter(experience_level == "EN") %>%
  sample_n(size = tamañomuestra.EN, replace = FALSE)
# Mostrar la muestra seleccionada
sprintf("El número de filas para la muestra del primer estrato es: %d", nrow(muestra.EN))
## [1] "El número de filas para la muestra del primer estrato es: 29"
tamañomuestra.EX <- round(n_h.EX, 0)
muestra.EX <- DB %>%
  filter(experience_level == "EX") %>%
  sample_n(size = tamañomuestra.EX, replace = FALSE)
sprintf("El número de filas para la muestra del segundo estrato es: %d", nrow(muestra.EX))
## [1] "El número de filas para la muestra del segundo estrato es: 11"
tamañomuestra.MI <- round(n_h.MI, 0)
muestra.MI <- DB %>%
  filter(experience_level == "MI") %>%
  sample_n(size = tamañomuestra.MI, replace = FALSE)
sprintf("El número de filas para la muestra del tercer estrato es: %d", nrow(muestra.MI))
## [1] "El número de filas para la muestra del tercer estrato es: 90"
tamañomuestra.SE <- round(n_h.SE, 0)
muestra.SE <- DB %>%
  filter(experience_level == "SE") %>%
  sample_n(size = tamañomuestra.SE, replace = FALSE)
sprintf("El número de filas para la muestra del cuarto estrato es: %d", nrow(muestra.SE))
## [1] "El número de filas para la muestra del cuarto estrato es: 245"
# Unión de las muestras para el totala de la muestra estratificada
muestra.estratificada = rbind(muestra.EN, muestra.EX, muestra.MI, muestra.SE)
sprintf("El número de filas para la muestra estratificada es: %d", nrow(muestra.estratificada))
## [1] "El número de filas para la muestra estratificada es: 375"

Estimador puntual

# Densidad del salario en dolares
options(scipen=10)
plot(density(DB$salary_in_usd, na.rm = TRUE),
     main = "Densidad de Salarios",
     xlab = "Salario",
     ylab = "Densidad",
     col = "blue",
     lwd = 2)

# Media poblacional
salario_promedio <- mean(DB$salary_in_usd)
sprintf("El salario promedio de la muestra problacional es: %s", round(salario_promedio,2))
## [1] "El salario promedio de la muestra problacional es: 149874.72"
# Densidad de salario en dolares normalizado
options(scipen=10)
DB$salary_log <- log(DB$salary_in_usd)

plot(density(DB$salary_log, na.rm = TRUE),
     main = "Densidad de Salarios Normalizada",
     xlab = "Salario",
     ylab = "Densidad",
     col = "blue",
     lwd = 2)

# Densidad de la muestra
options(scipen=10)
plot(density(muestra.estratificada$salary_in_usd, na.rm = TRUE),
     main = "Densidad de la muestra estratificada de salarios",
     xlab = "Salario",
     ylab = "Densidad",
     col = "green",
     lwd = 2)

Estimador Insesgado Muestra 1

# Media muestral de la muestra 1
salario_estratificado_promedio <- mean(muestra.estratificada$salary_in_usd)
sprintf("El salario estratificado promedio de la muestra 1 es: %s", round(salario_estratificado_promedio,2))
## [1] "El salario estratificado promedio de la muestra 1 es: 149400.89"
# Densidad de la muestra del salario en dolares normalizado
options(scipen=10)
muestra.estratificada$salary_log <- log(muestra.estratificada$salary_in_usd)

plot(density(muestra.estratificada$salary_log, na.rm = TRUE),
     main = "Densidad de la muestra estratificada de Salarios Normalizada",
     xlab = "Salario",
     ylab = "Densidad",
     col = "green",
     lwd = 2)

# Densidad de salarios problacionales - muestrales
plot(density(DB$salary_log, na.rm = TRUE),
     main = "Densidad de Salarios",
     xlab = "Salario",
     ylab = "Densidad",
     col = "blue",
     lwd = 2)

lines(density(muestra.estratificada$salary_log, na.rm = TRUE), col = "red", lwd = 2)

# Agregar una leyenda para identificar cada curva
legend("topright", 
       legend = c("Salario Poblacional", "Salario Muestral"),
       col = c("blue", "red"),
       lwd = 2)

Muestra 2

# Se saca el tamaño representativo de la muestra del estrato
# n_h = (N_h/N)*n
n2 = 1000
N2 = 14838
N_h.EN2=nrow(subset(DB, experience_level == "EN"))
n_h.EN2= (N_h.EN2/N2)*n2
sprintf("El tamaño de la muestra 2 para el primer estrato es: %s", round(n_h.EN2,0))
## [1] "El tamaño de la muestra 2 para el primer estrato es: 77"
N_h.EX2=nrow(subset(DB, experience_level == "EX"))
n_h.EX2= (N_h.EX2/N2)*n2
sprintf("El tamaño de la muestra 2 para el segundo estrato es: %s", round(n_h.EX2,0))
## [1] "El tamaño de la muestra 2 para el segundo estrato es: 30"
N_h.MI2=nrow(subset(DB, experience_level == "MI"))
n_h.MI2= (N_h.MI2/N2)*n2
sprintf("El tamaño de la muestra 2 para el tercer estrato es: %s", round(n_h.MI2,0))
## [1] "El tamaño de la muestra 2 para el tercer estrato es: 239"
N_h.SE2=nrow(subset(DB, experience_level == "SE"))
n_h.SE2= (N_h.SE2/N2)*n2
sprintf("El tamaño de la muestra 2 para el cuarto estrato es: %s", round(n_h.SE2,0))
## [1] "El tamaño de la muestra 2 para el cuarto estrato es: 653"
# Se saca la muestra aleatoria de cada estrato, con el tamaño especificado para cada estrato
# Definir el tamaño de la muestra redondeado para el nivel de experiencia "EN"
tamañomuestra.EN2 <- round(n_h.EN2, 0)
# Filtrar el dataset para el nivel de experiencia "EN" y tomar una muestra aleatoria sin reemplazo
muestra.EN2 <- DB %>%
  filter(experience_level == "EN") %>%
  sample_n(size = tamañomuestra.EN2, replace = FALSE)
# Mostrar la muestra seleccionada
sprintf("El número de filas para la muestra 2 del primer estrato es: %d", nrow(muestra.EN2))
## [1] "El número de filas para la muestra 2 del primer estrato es: 77"
tamañomuestra.EX2 <- round(n_h.EX2, 0)
muestra.EX2 <- DB %>%
  filter(experience_level == "EX") %>%
  sample_n(size = tamañomuestra.EX2, replace = FALSE)
sprintf("El número de filas para la muestra 2 del segundo estrato es: %d", nrow(muestra.EX2))
## [1] "El número de filas para la muestra 2 del segundo estrato es: 30"
tamañomuestra.MI2 <- round(n_h.MI2, 0)
muestra.MI2 <- DB %>%
  filter(experience_level == "MI") %>%
  sample_n(size = tamañomuestra.MI2, replace = FALSE)
sprintf("El número de filas para la muestra del tercer estrato es: %d", nrow(muestra.MI2))
## [1] "El número de filas para la muestra del tercer estrato es: 239"
tamañomuestra.SE2 <- round(n_h.SE2, 0)
muestra.SE2 <- DB %>%
  filter(experience_level == "SE") %>%
  sample_n(size = tamañomuestra.SE2, replace = FALSE)
sprintf("El número de filas para la muestra del cuarto estrato es: %d", nrow(muestra.SE2))
## [1] "El número de filas para la muestra del cuarto estrato es: 653"
# Unión de las muestras para el totala de la muestra estratificada
muestra.estratificada2 = rbind(muestra.EN2, muestra.EX2, muestra.MI2, muestra.SE2)
sprintf("El número de filas para la muestra estratificada es: %d", nrow(muestra.estratificada2))
## [1] "El número de filas para la muestra estratificada es: 999"
# Densidad de la muestra 2 del salario en dolares normalizado
muestra.estratificada2$salary_log <- log(muestra.estratificada2$salary_in_usd)

Estimador Insesgado muestra 2

# Media muestral de la muestra 2
salario_estratificado_promedio2 <- mean(muestra.estratificada2$salary_in_usd)
sprintf("El salario estratificado promedio de la muestra 2 es: %s", round(salario_estratificado_promedio2,2))
## [1] "El salario estratificado promedio de la muestra 2 es: 147656.52"

Estimador Eficiente de las muestras

# Varianza de la muestra 1
salario_estratificado_varianza <- var(muestra.estratificada$salary_log)
sprintf("La varianza del salario estratificado  de la muestra 1 es: %s", round(salario_estratificado_varianza,2))
## [1] "La varianza del salario estratificado  de la muestra 1 es: 0.2"
# Varianza de la muestra 2
salario_estratificado_varianza2 <- var(muestra.estratificada2$salary_log)
sprintf("La varianza del salario estratificado  de la muestra 2 es: %s", round(salario_estratificado_varianza2,2))
## [1] "La varianza del salario estratificado  de la muestra 2 es: 0.23"
# Calculamos eficiencia varianza.muestra1 < varianza.muestra2
print(sprintf("La varianza de la muestra 1 es %s y la varianza de la muestra 2 es %s, por lo tanto Var.muestra1 < Var.muestra2 lo que nos indica que existe eficiencia en la muestra estratificada con respecto a la segunda muestra.", 
              round(salario_estratificado_varianza, 2), 
              round(salario_estratificado_varianza2, 2)))
## [1] "La varianza de la muestra 1 es 0.2 y la varianza de la muestra 2 es 0.23, por lo tanto Var.muestra1 < Var.muestra2 lo que nos indica que existe eficiencia en la muestra estratificada con respecto a la segunda muestra."
Conclusión

Dado que la varianza de la muestra 1 (0.2) es menor que la varianza de la muestra 2 (0.23), se puede concluir que la muestra 1 es más eficiente que la muestra 2 en términos de la precisión de la estimación del parámetro. En el contexto de un muestreo estratificado, esta menor varianza sugiere que la muestra 1 está proporcionando una estimación del parámetro con menor dispersión y, por lo tanto, con mayor exactitud.

Esto indica que la muestra 1, con menor varianza, es más representativa de la población que la muestra 2, lo que valida la eficacia del muestreo estratificado en la muestra 1 para reducir la variabilidad en comparación con la segunda muestra.

Estimador Consistente de las muestras

# Calculamos la consistenta Si la media poblacional es igual a la media muestral
consistencia.muestra1 = ((salario_promedio - salario_estratificado_promedio)/salario_promedio)*100
consistencia.muestra2 = ((salario_promedio - salario_estratificado_promedio2)/salario_promedio)*100
print(sprintf("La consistencia de la muestra 1 es %s y la consistencia de la muestra 2 es %s, lo que nos indica que existe consistencia en la muestra 1 estratificada con respecto a la segunda muestra.", 
              round(consistencia.muestra1, 2), 
              round(consistencia.muestra2, 2)))
## [1] "La consistencia de la muestra 1 es 0.32 y la consistencia de la muestra 2 es 1.48, lo que nos indica que existe consistencia en la muestra 1 estratificada con respecto a la segunda muestra."
Conclusión

Dado que los valores de consistencia para la muestra 1 y la muestra 2 son bajos, podemos concluir que ambas muestras estratificadas son consistentes con respecto a la media poblacional de salarios. Esto implica que, a pesar de tener diferentes varianzas y configuraciones, ambas muestras estratificadas son representativas de la población en cuanto al salario promedio.

Estimadores de verosimilitud de las muestras

# Función de verosimilitud para una distribución normal
log_likelihood <- function(par, data) {
  mu <- par[1]
  sigma <- par[2]
  -sum(dnorm(data, mean = mu, sd = sigma, log = TRUE))
}

# Encontrar estimadores de máxima verosimilitud muestra 1
inicializacion <- c(mean(muestra.estratificada$salary_in_usd), sd(muestra.estratificada$salary_in_usd))
estimadores_mle <- optim(par = inicializacion, fn = log_likelihood, data = muestra.estratificada$salary_in_usd)
# Encontrar estimadores de máxima verosimilitud muestra 2
inicializacion2 <- c(mean(muestra.estratificada2$salary_in_usd), sd(muestra.estratificada2$salary_in_usd))
estimadores_mle2 <- optim(par = inicializacion, fn = log_likelihood, data = muestra.estratificada2$salary_in_usd)

# Resultados
cat("Estimador MLE para la media muestra 1:", estimadores_mle$par[1], "\n")
## Estimador MLE para la media muestra 1: 149379.7
cat("Estimador MLE para la desviación estándar muestra 1:", estimadores_mle$par[2], "\n")
## Estimador MLE para la desviación estándar muestra 1: 66647.15
cat("Estimador MLE para la media muestra 2:", estimadores_mle2$par[1], "\n")
## Estimador MLE para la media muestra 2: 147630.6
cat("Estimador MLE para la desviación estándar muestra 2:", estimadores_mle2$par[2], "\n")
## Estimador MLE para la desviación estándar muestra 2: 66658.17
Conclusión

Las estimaciones del MLE para la media y la desviación estándar muestran que ambas muestras representan la población de manera similar. La consistencia entre las medias y desviaciones estándar indica que la estrategia de muestreo utilizada es efectiva para capturar las características centrales de la población. Además, el hecho de que las diferencias sean mínimas sugiere que ambas muestras están bien seleccionadas y son representativas en términos de la tendencia central y dispersión de los datos de salarios.

Intervalos de confianza de las muestras

# Cálculo de la media y la desviación estándar de la muestra 1
media_muestral <- mean(muestra.estratificada$salary_log)
desviacion_muestral <- sd(muestra.estratificada$salary_log)
n <- length(muestra.estratificada$salary_log)
# Cálculo de la media y la desviación estándar de la muestra 2
media_muestral2 <- mean(muestra.estratificada2$salary_log)
desviacion_muestral2 <- sd(muestra.estratificada2$salary_log)
n2 <- length(muestra.estratificada2$salary_log)

# Nivel de confianza muestra 1
nivel_confianza <- 0.95
alpha <- 1 - nivel_confianza
# Nivel de confianza muestra 2
nivel_confianza2 <- 0.95
alpha2 <- 1 - nivel_confianza2

# Valor crítico para un intervalo del 95% (distribución t de Student) de la muestra 1
t_critico <- qt(1 - alpha/2, df = n - 1)
# Valor crítico para un intervalo del 95% (distribución t de Student) de la muestra 2
t_critico2 <- qt(1 - alpha2/2, df = n2 - 1)

# Error estándar de la muestra 1
error_estandar <- desviacion_muestral / sqrt(n)
# Error estándar de la muestra 2
error_estandar2 <- desviacion_muestral2 / sqrt(n)

# Intervalo de confianza de la muestra 1
limite_inferior <- media_muestral - t_critico * error_estandar
limite_superior <- media_muestral + t_critico * error_estandar
# Intervalo de confianza de la muestra 2
limite_inferior2 <- media_muestral2 - t_critico2 * error_estandar2
limite_superior2 <- media_muestral2 + t_critico2 * error_estandar2

cat("Intervalo de Confianza del 95% para la media de la muestra 1: [", limite_inferior, ",", limite_superior, "]\n")
## Intervalo de Confianza del 95% para la media de la muestra 1: [ 11.77368 , 11.86542 ]

Testeando el intervalo de confianza

Se desea hallar la proporción de empleados que tienen un entry level de la población a partir de la muestra, para ello se va a establecer un intervalo de confianza del 95% y luego comparar la realidad con respecto a la población.

N = 14838
N_h.EN=nrow(subset(DB, experience_level == "EN"))
proporcion_poblacional.EN = N_h.EN/N
print(sprintf("El %s %s de la población son trabajadores que tienen un entry level",round(proporcion_poblacional.EN*100,2),"%"))
## [1] "El 7.74 % de la población son trabajadores que tienen un entry level"
tamaño_muestral = as.numeric(nrow(muestra.estratificada))
n_h.EN = nrow(subset(muestra.estratificada, experience_level == "EN")) 
proporcional_muestral.EN = as.numeric(n_h.EN/tamaño_muestral)

valor_critico <- 1.96 #intervalo de confianza del 95%
error_estandar.proporcional = sqrt((proporcional_muestral.EN * (1 - proporcional_muestral.EN)) / tamaño_muestral)

# Intervalo de confianza de la muestra 1
limite_inferior <- proporcional_muestral.EN - valor_critico * error_estandar.proporcional
limite_superior <- proporcional_muestral.EN + valor_critico * error_estandar.proporcional

cat("Con una confianza del 95% podemos inferir que la proporción poblacional de los empleados que se encuentran en un entry level a partir de los datos de la población se encuentra entre un: [", round(limite_inferior*100,2), "%,", round(limite_superior*100,2), "%]\n")
## Con una confianza del 95% podemos inferir que la proporción poblacional de los empleados que se encuentran en un entry level a partir de los datos de la población se encuentra entre un: [ 5.03 %, 10.44 %]
cat("Al compararlo con el valor de la población vemos que el intervalo de confianza es cierto dado a que la proporcion poblacional es de un 7%, ahora revisemos si con un 99% de confianza el intervalo se cierra un poco más")
## Al compararlo con el valor de la población vemos que el intervalo de confianza es cierto dado a que la proporcion poblacional es de un 7%, ahora revisemos si con un 99% de confianza el intervalo se cierra un poco más
valor_critico <- 2.576 #intervalo de confianza del 95%
error_estandar.proporcional = sqrt((proporcional_muestral.EN * (1 - proporcional_muestral.EN)) / tamaño_muestral)

# Intervalo de confianza de la muestra 1
limite_inferior <- proporcional_muestral.EN - valor_critico * error_estandar.proporcional
limite_superior <- proporcional_muestral.EN + valor_critico * error_estandar.proporcional

cat("Con una confianza del 99% podemos inferir que la proporción poblacional de los empleados que se encuentran en un entry level a partir de los datos de la población se encuentra entre un: [", round(limite_inferior*100,2), "%,", round(limite_superior*100,2), "%]\n")
## Con una confianza del 99% podemos inferir que la proporción poblacional de los empleados que se encuentran en un entry level a partir de los datos de la población se encuentra entre un: [ 4.18 %, 11.29 %]

Conclusión El intervalo de confianza a medida que aumenta su severidad (95% a 99%) no se volvió un intervalo más pequeño sino que se aumentó.Esto sucede porque, para ser más seguros de que el verdadero parámetro poblacional está dentro del intervalo, se necesita considerar un rango más amplio de valores.