<jupyter_start><jupyter_text>Regresion polinomialLa regresion polinomial es una alternativa a la regresion lineal en donde se consideran potencias mayores a uno de las caracteristicas; esto nos lleva a modelos mas complejos y que generan curva de aproximacion, cuyo grado de complejidad dependera del grado del polinomio aplicado o solicitado. Cabe anotar, que la regresion polinomial sigue siendo considerada una regresion lineal multiple debido a como aparecen los pesos $w$:$$y=w_0+w_1x+w_2x^2+\dots+w_dx^d$$<jupyter_code>import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
# Creando datos de prueba
# ============================================================
X = np.array([258.0, 270.0, 294.0, 320.0, 342.0, 368.0, 396.0, 446.0, 480.0, 586.0])[:, np.newaxis]
y = np.array([236.4, 234.4, 252.8, 298.6, 314.2, 342.2, 360.8, 368.0, 391.2, 390.8])
X
# Agregar lementos cuadraticos a la matriz x
# ===========================================================
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
lr = LinearRegression()
pr = LinearRegression()

quadratic = PolynomialFeatures(degree=2)
X_quad = quadratic.fit_transform(X)
X_quad
# Observando cambios es X
# ===========================================================

a = pd.DataFrame(X_quad)#, columns = ['w0', 'x', 'x^2'])
b = pd.DataFrame(X, columns = ['X'])
pd.concat([a, b], axis = 1)
# Ajustando regresion lineal
lr.fit(X, y)
X_fit = np.arange(250, 600, 10)[:, np.newaxis]
y_lin_fit = lr.predict(X_fit)

# Ajustando una regresion polinomial
pr.fit(X_quad, y)
y_quad_fit = pr.predict(quadratic.fit_transform(X_fit))

# plot results
fig, ax = plt.subplots(figsize = (8, 6))
ax.scatter(X, y, label='puntos de entrenamiento')
ax.plot(X_fit, y_lin_fit, label='Ajuste lineal', linestyle='--')
ax.plot(X_fit, y_quad_fit, label='Ajuste cuadratico')
ax.legend(loc='upper left')
from sklearn.metrics import mean_squared_error
from sklearn.metrics import r2_score
y_lin_pred = lr.predict(X)
y_quad_pred = pr.predict(X_quad)
print(f'MSE entrenamiento lineal: {mean_squared_error(y, y_lin_pred)}, Cuadratico: {mean_squared_error(y, y_quad_pred)}')
print(f'R^2 entrenamiento lineal: {r2_score(y, y_lin_pred)}, cuadratico: {r2_score(y, y_quad_pred)}')<jupyter_output>MSE entrenamiento lineal: 569.7796663183207, Cuadratico: 61.330214517447715
R^2 entrenamiento lineal: 0.8317053837891232, cuadratico: 0.9818850241163604<jupyter_text>EJERCICIOSUtilice el archivo `housing.data.txt` que utilizamos durante las clases anteriores para modelar la relacion entra las variables `LSTAT` y `MEDV`; es conveniente que divida los datos en entrenamiento y prueba. Utilice tres regresiones: lineal, cuadratica y cubica; calcule los $R^2$ y grafique las relaciones. Procure que su grafica sea como la siguiente:![image.png](attachment:image.png)  Relaciones no lineales mediante arboles de decisionEste tipo de regresion se puede entender como la suma de funciones lineales por partes. Visto de otra manera, se subdivide el espacio en regiones mas manejables sobre las que se hace las regresiones.Una de sus ventajas es que no es necesario transformar las caracterisitcas de ninguna manera.<jupyter_code>def lin_regplot(X, y, model):
    plt.scatter(X, y, c='steelblue', edgecolor='white', s=70)
    plt.plot(X, model.predict(X), color='black', lw=2)    
    return None
from sklearn.tree import DecisionTreeRegressor

fig, ax = plt.subplots()
tree = DecisionTreeRegressor(max_depth=3)
tree.fit(X, y)

sort_idx = X.flatten().argsort()

lin_regplot(X[sort_idx], y[sort_idx], tree)
y_pred = tree.predict(X)
print(f'MSE entrenamiento lineal: {mean_squared_error(y, y_pred)}')
print(f'R^2 entrenamiento lineal: {r2_score(y, y_pred)}')<jupyter_output>MSE entrenamiento lineal: 132.93999999999997
R^2 entrenamiento lineal: 0.9607337930754188<jupyter_text>EJERCICIOAplique una regresion usando arboles de decision usando a las mismas caracteristicas del ejercicio anterior. Busque que no se genere sobreajuste en el conjunto de entrenamiento respecto al conjunto de test. Si no es posible evitar el sobreajuste con los hiperparametros de la regresion, considere usar extraccion de caracteristicas.  Regresion con bosques aleatoriosAl igual que en la seccion de clasificacion, este metodo consiste en el manejo de multiples arboles de decision que crean el bosque aleatorio. Este modelo es menos propenso al sobreajuste, y es bastante util para trata problemas con los *outliers*.<jupyter_code>from sklearn.ensemble import RandomForestRegressor

forest = RandomForestRegressor(n_estimators=1000, criterion='mse', random_state=1, n_jobs=-1)
forest.fit(X, y)

y_pred = forest.predict(X)

print(f'MSE entrenamiento: {mean_squared_error(y, y_pred)}')
print(f'R^2 entrenamiento: {r2_score(y, y_pred)}')

fig, ax = plt.subplots()
sort_idx = X.flatten().argsort()
lin_regplot(X[sort_idx], y[sort_idx], forest)
fig, ax = plt.subplots()

ax.scatter(y_pred, y_pred - y, c='red', edgecolor='k', marker='o', s=45, alpha=0.9, label='entrenamiento')
ax.set_xlabel('Valores predichos')
ax.set_ylabel('Residuos')
ax.legend(loc='best')
ax.hlines(y=0, xmin=240, xmax=400, lw=2, color='black', linestyle = '--')<jupyter_output><empty_output><jupyter_text>EJERCICIOAplique una regresion usando bosques aleatorios a las mismas caracteristicas del ejercicio anterior. Busque que no se genere sobreajuste en el conjunto de entrenamiento respecto al conjunto de test. Si no es posible evitar el sobreajuste con los hiperparametros de la regresion, considere usar extraccion de caracteristicas.  Maquinas de soporte vectorial para regresionYa hemos tenido la oportunidad de trabajar con SVM para el caso de la clasificacion; ahora las usaremos para realizar regresiones en las cuales tendremos ligeros cambios, pero antes de mencionarlos, cabe anotar que las SVM son utilies para realizar regresiones lineales y no lineales.El concepto basico es el mismo, generar una banda en torno a los datos tratando de contener la mayor cantidad posible. Las matematicas envueltas en el proceso no vienen al caso, por lo tanto no las trataremos en detalle, pero cabe anotar que es similar a lo visto en clasificacion. Es importante aclarar que es buena idea realizar escalamiento antes de...<jupyter_code>from sklearn.svm import SVR
svm = SVR(kernel = 'rbf', C=100, gamma = 0.00009) # regresion no lineal
svm.fit(X, y) # No se realizo escalamiento pues es puramente ilustrativo
y_pred = svm.predict(X)
print(f'MSE entrenamiento: {mean_squared_error(y, y_pred)}')
print(f'R^2 entrenamiento: {r2_score(y, y_pred)}')

fig, ax = plt.subplots()
sort_idx = X.flatten().argsort()
lin_regplot(X[sort_idx], y[sort_idx], svm)<jupyter_output>MSE entrenamiento: 28.39618310655674
R^2 entrenamiento: 0.9916126793912264
{'fraction_non_alphanumeric': 0.12092130518234165, 'fraction_numerical': 0.04089768197253802, 'mean_word_length': 6.33911159263272, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 1, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '453056', 'license': 'MIT', 'n_tokens_mistral': 2629, 'n_tokens_neox': 2425, 'n_words': 728, 'path': 'Semana-15/Polinomial.ipynb', 'repo_name': 'bel4212a/Curso-ciencia-de-datos', 'size': '6773'}