Librerías
# Importar bibliotecas
import pandas as pd
import os
import matplotlib.pyplot as plt # gráficos
import numpy as np # operaciones matriciales y multidimensionales
import seaborn as sns # visualización de datos
import statsmodels.api as sm # análisis estadísticos y modelado
import plotly.express as px
import plotly.graph_objects as go
from scipy.stats import chi2_contingency
from tabulate import tabulate #Libreria para formatear tablas
from sklearn.metrics import mean_squared_error, mean_absolute_error, mean_absolute_percentage_error
import scipy.stats as stats
from seaborn_qqplot import pplot
from scipy import stats
from statsmodels.graphics.gofplots import qqplot
from statsmodels.stats.outliers_influence import variance_inflation_factor
from scipy.optimize import curve_fit
# Cargar el DataFrame
df = pd.read_csv("sueldo.csv",delimiter=' ')
# Mostrar las primeras filas del DataFrame para verificar la carga
df.head()
ESTADISTICA DESCRIPTIVA
1. Realice un resumen de los datos, indicando para cada variable numérica su valor mínimo, máximo, promedio y desviación estándar y para cada variable categórica una tabla de frecuencias. (2 puntos)
# Descripción de los datos
df.describe()
# Descripción de los datos
df.info()
# Identificación del tipo de datos en el df
tipos_de_datos = df.dtypes
print(tipos_de_datos)
num = df[['wage','educ','exper','tenure']]
cat = df[['female','married','numdep','smsa','indus','position']]
# Variables numéricas
for column in num:
print(f"Variable numérica: {column}")
print(f"Valor mínimo: {df[column].min()}")
print(f"Valor máximo: {df[column].max()}")
print(f"Promedio: {df[column].mean()}")
print(f"Desviación estándar: {df[column].std()}")
print("\n")
# Variables categóricas
for column in cat:
print(f"Variable categórica: {column}")
# Frecuencias
value_counts = df[column].value_counts()
total = len(df)
# Porcentajes de cada categoria dentro de la variable categórica
porcentaje = (value_counts / total * 100).round(2)
tabla_frecuencias = pd.DataFrame({'Frecuencia': value_counts, 'Porcentaje (%)': porcentaje})
print(tabla_frecuencias)
print("\n")
2. Realice un histograma de frecuencias y un boxplot para la variable (wage). Interprete: ¿Qué puede decir de la distribución del salario?. ¿Qué puede decir sobre los valores atípicos? (3 puntos)
# Resumen estadístico de datos de la columna wage
df['wage'].describe()
# Histograma de frecuencia de la variable wage
sns.histplot(data = df, x = "wage", kde = True, color = "#76448A").set_title("Distribución de la variable Wage")
# Ajuste de título y nombre de los ejes
plt.xlabel("Salario USD/hora")
plt.ylabel("Frecuencia")
# Estadísticos de la variable wage
media = df.wage.mean()
mediana = df.wage.median()
std = df.wage.std()
print(f'Media = {media}')
print(f'Mediana = {mediana}')
print(f'Desviación Standard = {std}')
# Cálculo de asimetría y kurtosis de la variable wage
stats.describe(df.wage)
# Suponiendo una distribución normal
pplot(df[["wage"]].dropna(), x="wage", y = stats.norm, kind='qq',
display_kws={"fit":True},
height=5, aspect=2)
# Boxplot dinámico
fig = px.box(df, x='wage', title='Boxplot de Sueldo')
# Actualización de la escala del eje x
fig.update_xaxes(
title_text='Salario USD/hora', # xaxis label
range=[0, df['wage'].max()+5] # Rango personalizado para el eje x
)
fig.show()
# Identificación valores atípicos basados en el boxplot
q1 = df['wage'].quantile(0.25)
q3 = df['wage'].quantile(0.75)
iqr = q3 - q1
lower_bound = q1 - 1.5 * iqr
upper_bound = q3 + 1.5 * iqr
outliers = df[(df['wage'] < lower_bound) | (df['wage'] > upper_bound)]
# Caracterización de los valores atípicos
print("Valores atípicos:")
print(outliers)
# Identificación de outliers según variable y su frecuencia
for column in outliers:
print(f"Variable: {column}")
# Frecuencias
value_counts = outliers[column].value_counts()
total = len(outliers)
# Porcentajes de cada categoria dentro de la variable categórica
porcentaje = (value_counts / total * 100).round(2)
tabla_frecuencias = pd.DataFrame({'Frecuencia': value_counts, 'Porcentaje (%)': porcentaje})
print(tabla_frecuencias)
print("\n")
3. Repita el análisis solicitado en el punto 2 para la variable (exper). (3 puntos)
# Muestra los datos de la columna exper en el DataFrame
df['exper'].describe()
# Histograma de la variable Exper
sns.histplot(data = df, x = "exper",kde = True, color = "#76448A").set_title("Distribución de la variable Exper")
# agrega título y nombre a los ejes
plt.xlabel("Años de experiencia laboral")
plt.ylabel("Frecuencia")
# Estadísticos de la variable exper
media = df.exper.mean()
mediana = df.exper.median()
std = df.exper.std()
moda = df.exper.mode()
print(f'Media = {media}')
print(f'Mediana = {mediana}')
print(f'Desviación Standard = {std}')
print(f'Moda = {moda}')
# Cálculo de asimetría y kurtosis de la variable exper
stats.describe(df.exper)
# Gráfico de probabilidad acumulativa para la variable exper
qqplot(df['exper'], line='s') #'line='s'' muestra la línea diagonal
# Título y ejes
plt.title("Gráfico de Probabilidad Acumulativa")
plt.xlabel("Valores teóricos (cuantiles)")
plt.ylabel("Valores observados")
# Muestra el gráfico
plt.show()
# Boxplot dinámico
fig = px.box(df, x='exper', title='Boxplot de Años de experiencia laboral')
# Actualización de la escala del eje x
fig.update_xaxes(
title_text='Años de experiencia laboral',
range=[0, df['exper'].max()+5]
)
fig.show()
# Identificación de cuantiles
q1 = df['exper'].quantile(0.25)
q3 = df['exper'].quantile(0.75)
print(f'Q1 = {q1}')
print(f'Q3 = {q3}')
4. Haciendo un análisis gráfico ¿Qué tipos de industria presentan mayores salarios en promedio? No considere en su análisis las industrias no categorizadas. Compare con la realidad de Chile, ¿Qué podría concluir? (4 puntos)
# Muestra los datos de la columna indus unique en el DataFrame
df['indus'].unique()
# cuenta los datos de la columna indus unique en el DataFrame
df['indus'].value_counts()
indus = df[df['indus'] != 'others']
# Salario promedio por tipo de industria
salario_mean = indus.groupby('indus')['wage'].mean().reset_index()
salario_mean['wage'] = salario_mean['wage'].round(2)
# Valores del promedio de sueldo en forma descendente
salario_mean = salario_mean.sort_values(by='wage', ascending=False)
# Gráfico de barras
fig = go.Figure()
# Personalización del gráfico
fig.add_trace(go.Bar(x=salario_mean['wage'],
y=salario_mean['indus'],
orientation='h',
text=salario_mean['wage'],
marker_color=['#76448A ' if ind == salario_mean['indus'].iloc[0] else '#283747' for ind in salario_mean['indus']]))
fig.update_traces(marker=dict(size=12, line=dict(width=2, color='red')), selector=dict(mode='markers'))
fig.update_layout(title='Salario Promedio por Tipo de Industria',
xaxis_title='Salario Promedio (USD/Hora)',
yaxis_title='Tipo de Industria',
yaxis=dict(categoryorder='total ascending'))
fig.show()
ANALISIS DE CORRELACION
5. Realice una tabla de contingencia entre las variables (indus) y (position). Luego calcule el estadístico Chi cuadrado y el coeficiente V de Cramer y concluya sobre el grado de relación entre las variables. (2 puntos)
# copia df en df1
df1 = df.copy()
#Realiza una tabla de contingencia de la columna indus y la columna position
contingency_table=pd.crosstab(index=df1['indus'], columns=df1['position'])
#Tabla de contingencia
contingency_table
# Calcular la prueba de chi-cuadrado y el valor p
chi2, p_value, _, _ = chi2_contingency(contingency_table)
print("Chi-square test statistic:", chi2)
print("p-value:", p_value)
def cramers_v(table):
chi2 = chi2_contingency(table)[0]
n = table.sum().sum()
phi2 = chi2 / n
r, k = table.shape
phi2corr = max(0, phi2 - ((k - 1) * (r - 1)) / (n - 1))
rcorr = r - ((r - 1) ** 2) / (n - 1)
kcorr = k - ((k - 1) ** 2) / (n - 1)
return np.sqrt(phi2corr / min((kcorr - 1), (rcorr - 1)))
# Suponiendo que tienes los datos en un DataFrame llamado 'df' y las columnas se llaman 'indus' y 'position'
contingency_table = pd.crosstab(index=df1['indus'], columns=df1['position'])
# Calcular el coeficiente V de Cramer
coeficiente_cramer = cramers_v(contingency_table)
# Mostrar la tabla de contingencia
print("Tabla de Contingencia:")
print(contingency_table)
# Mostrar el coeficiente V de Cramer
print("Coeficiente V de Cramer:", coeficiente_cramer)
6. Realice una tabla de contingencia entre las variables (female) y (married). Luego calcule el estadístico Chi cuadrado y el coeficiente V de Cramer y concluya sobre el grado de relación entre las variables. (2 puntos)
# Realiza una tabla de contingencia entre las variables female y married
contingency_table2=pd.crosstab(index=df1['female'], columns=df1['married'])
# Tabla de contingencia
contingency_table2
# Calcular la prueba de chi-cuadrado y el valor p
chi2, p_value, _, _ = chi2_contingency(contingency_table2)
# Imprimir los resultados
print("Chi-square test statistic:", chi2)
print("p-value:", p_value)
def cramers_v(table):
chi2 = chi2_contingency(table)[0]
n = table.sum().sum()
phi2 = chi2 / n
r, k = table.shape
phi2corr = max(0, phi2 - ((k - 1) * (r - 1)) / (n - 1))
rcorr = r - ((r - 1) ** 2) / (n - 1)
kcorr = k - ((k - 1) ** 2) / (n - 1)
return np.sqrt(phi2corr / min((kcorr - 1), (rcorr - 1)))
# Tabla de contingencia entre las variables 'female' y 'married'
tabla_contingencia2 = pd.crosstab(index=df1['female'], columns=df1['married'])
# Calcular el coeficiente V de Cramer
coeficiente_cramer = cramers_v(tabla_contingencia2)
print("Coeficiente V de Cramer:", coeficiente_cramer)
7. Realice un diagrama de dispersión de la variable de interés (wage) en función de la variable (educ). Analice los hallazgos gráficamente, ¿Existe algún tipo de correlación entre ambas variables?, ¿Cree usted que los años de educación influyen en el ingreso? (2 puntos)
#Muestra los datos df1 de wage en función de la columna educ
df1[['wage', 'educ']].describe()
# Diagrama de dispersión entre las variables wage en funcion de la variable educ
# Análisis de correlación entre las 2 variables.
# Covarianza y Coeficiente de Correlación lineal (Coeficiente de Pearson)
# Covarianza
x = df['educ']
y = df['wage']
covariance = np.cov(x, y)[0, 1]
print(f'Covarianza: {covariance}')
# Coeficiente de Correlación lineal
correlation = np.corrcoef(x, y)[0, 1]
print(f'Coeficiente de Correlación lineal: {correlation}')
# Calcular la matriz de correlación
corr_matrix = df1[['wage', 'educ']].corr()
# Crear la figura de matriz de correlación
fig = go.Figure(data=go.Heatmap(
z=corr_matrix.values,
x=corr_matrix.columns,
y=corr_matrix.index,
colorscale=[[0, '#F5F6F9'], [1, '#4052A2']], # Usar #76448A como color
zmin=-1,
zmax=1,
))
# Agregar texto con los valores de correlación en cada celda
annotations = []
for i in range(len(corr_matrix)):
for j in range(len(corr_matrix)):
annotations.append(
go.layout.Annotation(
text=f"{corr_matrix.iloc[i, j]:.2f}",
x=corr_matrix.columns[j],
y=corr_matrix.index[i],
showarrow=False,
font=dict(color='white'),
)
)
fig.update_layout(
title="Matriz de correlación: wage y educ",
annotations=annotations,
)
# Mostrar la figura
fig.show()
8. Repita los pasos y análisis solicitados en el punto anterior para la variable (exper). Compare ambos hallazgos y realice una hipótesis sobre cuál de las dos variables independientes (educ y exper) explica mejor el comportamiento de la variable dependiente (wage) (2 puntos)
#Muestra los datos df1 de wage y educ
df1[['wage', 'exper']].describe()
# Diagrama de dispersión entre las variables wage en funcion de la variable exper
fig = px.scatter(df, x='exper', y='wage', title='Diagrama de Dispersión: Wage vs. Exper', trendline='ols')
fig.update_traces(marker=dict(size=5), selector=dict(mode='markers'))
# Personalizar el diseño del gráfico
fig.update_layout(xaxis_title='Exper (años de experiencia laboral)', yaxis_title='Wage (salario USD/hr)', showlegend=False)
fig.update_xaxes(showgrid=False)
fig.update_yaxes(showgrid=False)
# Mostrar el gráfico
fig.show()
# Análisis de correlación entre las 2 variables.
# Covarianza y Coeficiente de Correlación lineal (Coeficiente de Pearson)
# Variables
x = df['exper']
y = df['wage']
# Covarianza
covariance = np.cov(x, y)[0, 1]
print(f'Covarianza: {covariance}')
# Coeficiente de Correlación lineal
correlation = np.corrcoef(x, y)[0, 1]
print(f'Coeficiente de Correlación lineal: {correlation}')
# Calcular la matriz de correlación de las variables 'wage' y 'exper'
corr_matrix = df1[['wage', 'exper']].corr()
# Crear la figura de matriz de correlación
fig = go.Figure(data=go.Heatmap(
z=corr_matrix.values,
x=corr_matrix.columns,
y=corr_matrix.index,
colorscale=[[0, '#F5F6F9'], [1, '#4052A2']],
zmin=-1,
zmax=1,
))
# Agregar texto con los valores de correlación en cada celda
annotations = []
for i in range(len(corr_matrix)):
for j in range(len(corr_matrix)):
annotations.append(
go.layout.Annotation(
text=f"{corr_matrix.iloc[i, j]:.2f}",
x=corr_matrix.columns[j],
y=corr_matrix.index[i],
showarrow=False,
font=dict(color='white'),
)
)
fig.update_layout(
title="Matriz de correlación: wage y exper",
annotations=annotations,
)
# Mostrar la figura
fig.show()
9. Obtenga la matriz de correlación entre todas las variables numéricas del dataset (realice una gráfica de intensidad de colores eliminando las variables categóricas de los datos). Valide con esta información sus hipótesis de los puntos 7 y 8 en relación a la correlación entre las variables. (4 puntos)
df_num = df[['educ', 'exper', 'tenure', 'numdep', 'wage']]
df_num.columns
# Calcular la matriz de correlación del dataset completo (todas las variables)
corr_matrix = df_num.corr()
# Crear la figura de matriz de correlación
fig = go.Figure(data=go.Heatmap(
z=corr_matrix.values,
x=corr_matrix.columns,
y=corr_matrix.index,
colorscale=[[0, '#FDFEFE'], [1, '#4052A2']],
zmin=-1,
zmax=1,
))
# Configuración gráfica
annotations = []
for i in range(len(corr_matrix)):
for j in range(len(corr_matrix)):
annotations.append(
go.layout.Annotation(
text=f"{corr_matrix.iloc[i, j]:.2f}",
x=corr_matrix.columns[j],
y=corr_matrix.index[i],
showarrow=False,
font=dict(color='white'),
)
)
fig.update_layout(
title="Matriz de correlación",
annotations=annotations,
)
# Mostrar la figura
fig.show()
ANALISIS DE REGRESION
10. Realice un análisis de regresión lineal simple entre la variable dependiente (wage) y la variable tenure (variable independiente). Entregue los resultados tabulados e interprételos. (2puntos)
#Realice un modelo de regresión lineal simple entre las variables wage y ternure del DataFrame df1 y muestra los resultados tabulados del modelo
X = sm.add_constant(df1['tenure'])
model1 = sm.OLS(df1['wage'], X).fit()
print_model = model1.summary()
print(print_model)
#Crear tabla bonita en latex
tabla_latex = model1.summary().as_latex()
print(tabla_latex)
#Crear tabla
table = tabulate(model1.summary().tables[1], headers='keys', tablefmt='psql')
print(table)
11. Realice un diagrama de dispersión entre ambas variables que incluya la línea recta que mejor ajusta a los datos (puede guiarse por los ejemplos de clases). Gráficamente, ¿se observa una relación lineal? (2 puntos)
# Diagrama de dispersión entre las variables wage en función de la variable educ
fig = px.scatter(df, x='tenure', y='wage', title='Diagrama de Dispersión: Wage vs. Tenure', trendline='ols', trendline_color_override='#F1C40F')
fig.update_traces(marker=dict(size=5), selector=dict(mode='markers'))
# Personalizar el diseño del gráfico
fig.update_layout(xaxis_title='Tenure (Años de antigüedad laboral en su empresa actual)', yaxis_title='Wage (salario USD/hr)', showlegend=False)
fig.update_xaxes(showgrid=False)
fig.update_yaxes(showgrid=False)
# Mostrar el gráfico
fig.show()
# Definición de variables
y = df['wage']
x = df['tenure']
# Covarianza
covariance = np.cov(x, y)[0, 1]
print(f'Covarianza: {covariance}')
# Coeficiente de Correlación lineal
correlation = np.corrcoef(x, y)[0, 1]
print(f'Coeficiente de Correlación lineal: {correlation}')
# Extraer los datos de 'wage' y 'tenure'.
wage = df['wage'] # y
tenure = df['tenure'] # x
# Definir una función cuadrática para ajustar los datos.
def quadratic_function(x, a, b, c):
return a * x**2 + b * x + c
# Ajustar la función cuadrática a los datos.
params, _ = curve_fit(quadratic_function, tenure, wage)
# Extraer los coeficientes ajustados.
a, b, c = params
# Crear una serie de valores 'x' para la gráfica de la función cuadrática.
x_values = np.linspace(min(tenure), max(tenure), 100)
# Calcular los valores 'y' correspondientes usando la función cuadrática ajustada.
y_values = quadratic_function(x_values, a, b, c)
# Crear la gráfica de dispersión.
scatter_fig = px.scatter(x=tenure, y=wage, title='Gráfica de dispersión y ajuste cuadrático', labels={'x': 'tenure', 'y': 'wage'})
scatter_fig.update_traces(marker=dict(size=5), selector=dict(mode='markers'))
# Crear la gráfica de la función cuadrática ajustada.
line_fig = px.line(x=x_values, y=y_values, labels={'x': 'tenure', 'y': 'wage'})
line_fig.update_traces(line=dict(color='#F1C40F'), selector=dict(mode='lines'), name=f'Ajuste cuadrático: {a:.2f}x^2 + {b:.2f}x + {c:.2f}')
# Agregar la fórmula del ajuste cuadrático como una anotación en la gráfica.
formula_text = f'Ajuste cuadrático: {a:.2f}x^2 + {b:.2f}x + {c:.2f}'
scatter_fig.add_annotation(text=formula_text, xref="paper", yref="paper", x=0.95, y=0.95, showarrow=False)
# Combinar las gráficas de dispersión y la función cuadrática ajustada.
combined_fig = scatter_fig.add_trace(line_fig.data[0])
# Personalizar el diseño de la gráfica.
combined_fig.update_layout(showlegend=True)
combined_fig.update_xaxes(showgrid=False)
combined_fig.update_yaxes(showgrid=False)
# Mostrar la gráfica.
combined_fig.show()
12. Realice un análisis de regresión múltiple entre la variable dependiente (wage) y todas las variables independientes del modelo simultáneamente. Entregue una tabla con los resultados de la regresión y analice la significancia estadística de los coeficientes de las variables independientes. (Para las variables categóricas utilice como nivel de referencia aquel con una mayor frecuencia en los datos.) (6puntos)
# copia df en df2
df2 = df.copy()
df2.columns
tabla_frecuencias = pd.crosstab(index=df2['female'], columns="Frecuencia")
print(tabla_frecuencias)
tabla_frecuencias = pd.crosstab(index=df2['married'], columns="Frecuencia")
print(tabla_frecuencias)
tabla_frecuencias = pd.crosstab(index=df2['smsa'], columns="Frecuencia")
print(tabla_frecuencias)
tabla_frecuencias = pd.crosstab(index=df2['indus'], columns="Frecuencia")
print(tabla_frecuencias)
tabla_frecuencias = pd.crosstab(index=df2['position'], columns="Frecuencia")
print(tabla_frecuencias)
df2_dummies = pd.get_dummies(df2, columns=['female','married','smsa','indus', 'position'], drop_first=False, dtype=int)
df2_dummies.head()
df2_dummies.columns
df2_dummies_filtrado= df2_dummies[['educ', 'exper','tenure', 'female_1', 'married_0','numdep',
'smsa_0','indus_ndurman','indus_construc', 'indus_others', 'indus_profserv','indus_services',
'indus_trcommpu','position_clerocc','position_others', 'position_servocc']]
#Regresión lineal múltiple
X3 = df2_dummies_filtrado
# Definir la variable dependiente (variable a predecir)
y = df2['wage']
# Agregar una constante para el término independiente (intercepto)
X3 = sm.add_constant(X3)
# Ajustar el modelo de regresión lineal múltiple
model3 = sm.OLS(y, X3).fit()
# Imprimir el resumen
print(model3.summary())
#Crear tabla bonita en latex
tabla_latex = model3.summary().as_latex()
print(tabla_latex)
#Crear tabla bonita para word o ppt
table = tabulate(model3.summary().tables[1], headers='keys', tablefmt='psql')
print(table)
#Inspeccionar el comportamiento de la variable wage con el resto del data frame
sns.pairplot(df2,hue='wage')
13. ¿Es el modelo anterior significativo estadísticamente? Justifique su respuesta analizando el estadístico F y explicando qué se mide esta prueba de hipótesis. (2puntos)
#Calcula el F-test del modelo de regresión lineal múltiple anterior
# Calcular el F-test
fvalue = model3.fvalue
print('F-statistic:',fvalue)
# Calcular el p-value
pvalue = model3.f_pvalue
print('p-value:',pvalue)
14. Analice la bondad de ajuste del modelo y concluya respecto de su capacidad predictiva. Compare R cuadrado y R cuadrado ajustado. ¿Qué diferencias existen entre ambos? Explique por qué se generan esas diferencias. (4puntos)
from sklearn.metrics import mean_squared_error, mean_absolute_error, mean_absolute_percentage_error
y = df2['wage']
# Predicciones
predicciones_modelo1 = model1.predict(X)
predicciones_modelo3 = model3.predict(X3)
# Cálculo del MSE (Error Cuadrático Medio)
mse_modelo1 = mean_squared_error(y, predicciones_modelo1)
mse_modelo3 = mean_squared_error(y, predicciones_modelo3)
# Cálculo del RMSE (Raíz del Error Cuadrático Medio)
rmse_modelo1 = np.sqrt(mse_modelo1)
rmse_modelo3 = np.sqrt(mse_modelo3)
# Cálculo del MAE (Error Absoluto Medio)
mae_modelo1 = mean_absolute_error(y, predicciones_modelo1)
mae_modelo3 = mean_absolute_error(y, predicciones_modelo3)
# Cálculo del MAPE (Error Porcentual Absoluto Medio)
mape_modelo1 = mean_absolute_percentage_error(y, predicciones_modelo1) * 100
mape_modelo3 = mean_absolute_percentage_error(y, predicciones_modelo3) * 100
# Crear un DataFrame de pandas para mostrar los resultados tabulados
resultados = pd.DataFrame({
'Modelo 1': [mse_modelo1, rmse_modelo1, mae_modelo1, mape_modelo1],
'Modelo 3': [mse_modelo3, rmse_modelo3, mae_modelo3, mape_modelo3]
}, index=['MSE', 'RMSE', 'MAE', 'MAPE (%)'])
# Mostrar los resultados
print(resultados)
15. ¿Qué variables no son estadísticamente significativas?. Entregue su propia intuición de por qué estas variables podrían no explicar el comportamiento de la variable dependiente. (Indicación: Si hay variables categóricas donde una o más categorías resultan ser estadísticamente significativas en el modelo, entonces la variable completa es significativa.) (4puntos)
16. Elimine las variables que usted mencionó en el punto anterior y realice nuevamente un modelo de regresión lineal múltiple. ¿Qué ocurrió? ¿Mejoró el modelo? Explique. (Indicación: Sólo debe eliminar una variable categórica si todas sus categorías resultan ser estadísticamente no significativas) (4puntos)
df3_dummies_filtrado= df2_dummies[['educ','tenure', 'female_1','smsa_0','indus_ndurman',
'indus_others', 'indus_construc','indus_profserv','indus_services',
'indus_trcommpu','position_clerocc','position_others', 'position_servocc']]
#Regresión lineal múltiple
X4 = df3_dummies_filtrado
# Agregar una constante para el término independiente (intercepto)
X4 = sm.add_constant(X4)
# Definir la variable dependiente (variable a predecir)
y = df2['wage']
# Ajustar el modelo de regresión lineal múltiple
model4 = sm.OLS(y, X4).fit()
# Imprimir el resumen
print(model4.summary())
#Crear tabla bonita en latex
tabla_latex = model4.summary().as_latex()
print(tabla_latex)
#Crear tabla bonita para word o ppt
table = tabulate(model4.summary().tables[1], headers='keys', tablefmt='psql')
print(table)
# Calcular el p-value
pvalue = model4.f_pvalue
print('p-value:',pvalue)
17. Considerando este nuevo modelo. Interprete cada uno de los coeficientes de las variables independientes del modelo (Betas). Incluya también una interpretación para el coeficiente del intercepto. (4puntos)
# Imprimir el resumen
print(model4.summary())
18. Considerando este nuevo modelo. ¿Cuál cree usted que es la variable que más influye en el salario? Justifique. (Indicación: Para comparar coeficientes de variables que no tienen las mismas unidades de medidas, usted debe estandarizar las variables antes de realizar el análisis de regresión. La variable dependiente también debe ser estandarizada. Las variables categóricas no requieren ser estandarizadas.) (4puntos)
df3_dummies_filtrado.columns
# ICN con valores estandarizados
# Definir las variables explicativas (todas las columnas excepto la variable a predecir)
X = df3_dummies_filtrado
# Calcula la media y la desviación estándar para cada columna
means = np.mean(X, axis=0)
std_devs = np.std(X, axis=0)
# Estandariza las columnas
X_standardized = (X - means) / std_devs
# Agregar una constante para el término independiente (intercepto)
X_standardized = sm.add_constant(X_standardized)
XtX = np.dot(X_standardized.T,X_standardized)
eigenvalues, _ = np.linalg.eig(XtX)
# Calcular el ICN
ICN = np.sqrt(max(eigenvalues)) / np.sqrt(min(eigenvalues))
print(f"El ICN de la matriz X'X es {ICN}")
#Regresión lineal múltiple
X5 = X_standardized
# Agregar una constante para el término independiente (intercepto)
X5 = sm.add_constant(X5)
# Definir la variable dependiente (variable a predecir)
y = df2['wage']
# Ajustar el modelo de regresión lineal múltiple
model5 = sm.OLS(y, X5).fit()
# Imprimir el resumen
print(model5.summary())
19. Calcule la matriz X’X considerando todas las variables independientes del modelo (sin eliminar ninguna), calcule el rango de esta matriz en Python y explique por qué es importante el valor de esta variable para la resolución del problema utilizando MCO. (Indicación: Las variables categóricas deben estar en formato dummy, es decir, valores 1 o 0. Si la variable categórica tiene más de 2 factores, cada factor debe ser descrito como dummy excepto el nivel base. Por ejemplo, la variable indus se debe transformar en 5 variables binarias, sin incluir “otros” y sin incluir el nivel base, por ejemplo: Construct: 1 si trabaja en construcción, 0 lo contrario) (4puntos).
df4_dummies_filtrado= df2_dummies[['educ', 'exper','tenure', 'female_1', 'married_0','numdep',
'smsa_0','indus_ndurman','indus_construc', 'indus_profserv','indus_services',
'indus_trcommpu','position_clerocc','position_others', 'position_servocc']]
# Definir las variables explicativas (todas las columnas excepto la variable a predecir)
X = df4_dummies_filtrado
#X = df1.drop(columns=['y'])
# Agregar una constante para el término independiente (intercepto)
X = sm.add_constant(X)
# Calcular X'X
XtX = np.dot(X.T, X)
# Calcular el rango de XtX
rango_XtX = np.linalg.matrix_rank(XtX)
print(f"El rango de la matriz X'X es {rango_XtX}")
# ICN con valores estandarizados
# Definir las variables explicativas (todas las columnas excepto la variable a predecir)
X = df4_dummies_filtrado
# Calcula la media y la desviación estándar para cada columna
means = np.mean(X, axis=0)
std_devs = np.std(X, axis=0)
# Estandariza las columnas
X_standardized = (X - means) / std_devs
# Agregar una constante para el término independiente (intercepto)
X_standardized = sm.add_constant(X_standardized)
XtX = np.dot(X_standardized.T,X_standardized)
eigenvalues, _ = np.linalg.eig(XtX)
# Calcular el ICN
ICN = np.sqrt(max(eigenvalues)) / np.sqrt(min(eigenvalues))
print(f"El ICN de la matriz X'X es {ICN}")
20. Compare en términos de R2 ajustado, F-fisher, MSE, RMSE los modelos del punto 12 y el punto 16 y concluya sobre las mejoras en el ajuste y capacidad predictiva. (4puntos).
# Resumen de los modelos
print('Modelo 3')
print(model3.summary())
print('-------'*20)
print('Modelo 4')
print(model4.summary())
r2_model3 = 0.469
r2_adj_model3 = 0.450
r2_model4 = 0.460
r2_adj_model4 = 0.444
print(f'Modelo 3 [R2]= {r2_model3}, [R2_adj]= {r2_adj_model3}')
print(f'Modelo 4 [R2]= {r2_model4}, [R2_adj]= {r2_adj_model4}')
# Capacidad predictiva de los modelos
y = df2['wage']
# Predicciones
predicciones_modelo3 = model3.predict(X3)
predicciones_modelo4 = model4.predict(X4)
# Cálculo del MSE (Error Cuadrático Medio)
mse_modelo3 = mean_squared_error(y, predicciones_modelo3)
mse_modelo4 = mean_squared_error(y, predicciones_modelo4)
# Cálculo del RMSE (Raíz del Error Cuadrático Medio)
rmse_modelo3 = np.sqrt(mse_modelo3)
rmse_modelo4 = np.sqrt(mse_modelo4)
# Cálculo del MAE (Error Absoluto Medio)
mae_modelo3 = mean_absolute_error(y, predicciones_modelo3)
mae_modelo4 = mean_absolute_error(y, predicciones_modelo4)
# Cálculo del MAPE (Error Porcentual Absoluto Medio)
mape_modelo3 = mean_absolute_percentage_error(y, predicciones_modelo3) * 100
mape_modelo4 = mean_absolute_percentage_error(y, predicciones_modelo4) * 100
# Crear un DataFrame de pandas para mostrar los resultados tabulados
resultados = pd.DataFrame({
'Modelo 3': [mse_modelo3, rmse_modelo3, mae_modelo3, mape_modelo3],
'Modelo 4': [mse_modelo4, rmse_modelo4, mae_modelo4, mape_modelo4]
}, index=['MSE', 'RMSE', 'MAE', 'MAPE (%)'])
# Mostrar los resultados
print(resultados)
# F-test para comparar modelos anidados
f_test = model4.compare_f_test(model1)
print('F-statistic:', f_test[0])
print('p-value:', f_test[1])