Introdução
Neste laboratório, aprenderemos a aproximar uma função com polinómios até um determinado grau utilizando regressão de ridge. Apresentaremos duas formas diferentes de o fazer, dados n_samples de pontos 1D x_i:
PolynomialFeatures: gera todos os monómios até um grau especificado. Isto fornece-nos a matriz de Vandermonde comn_sampleslinhas edegree + 1colunas.SplineTransformer: gera funções de base B-spline. Uma função de base de uma B-spline é uma função polinomial por partes de graudegreeque é não nula apenas entredegree+1nós consecutivos.
Utilizaremos a função make_pipeline para adicionar características não lineares e mostrar como estes transformadores são adequados para modelar efeitos não lineares com um modelo linear. Desenvolveremos o gráfico da função, dos pontos de treino e da interpolação utilizando características polinomiais e B-splines. Também representaremos separadamente todas as colunas de ambos os transformadores e demonstraremos os nós da spline. Finalmente, demonstraremos o uso de splines periódicas.
Dicas de Máquina Virtual
Após o arranque da máquina virtual, clique no canto superior esquerdo para mudar para a aba Notebook para aceder ao Jupyter Notebook para a prática.
Por vezes, pode ser necessário esperar alguns segundos para o Jupyter Notebook terminar de carregar. A validação das operações não pode ser automatizada devido a limitações no Jupyter Notebook.
Se tiver problemas durante o aprendizado, não hesite em contactar o Labby. Forneça feedback após a sessão e resolveremos o problema rapidamente para si.
Preparar os Dados
Começamos por definir uma função que pretendemos aproximar e preparar o seu gráfico.
def f(x):
"""Função a ser aproximada por interpolação polinomial."""
return x * np.sin(x)
## Intervalo completo que queremos representar graficamente
x_plot = np.linspace(-1, 11, 100)
## Para tornar mais interessante, apenas fornecemos um pequeno subconjunto de pontos para treino.
x_train = np.linspace(0, 10, 100)
rng = np.random.RandomState(0)
x_train = np.sort(rng.choice(x_train, size=20, replace=False))
y_train = f(x_train)
## Criar versões de matrizes 2D destes arrays para alimentar os transformadores
X_train = x_train[:, np.newaxis]
X_plot = x_plot[:, np.newaxis]
Interpolação com Características Polinomiais
Utilizaremos PolynomialFeatures para gerar características polinomiais e ajustar um modelo de regressão de ridge aos dados de treino. Em seguida, representaremos graficamente a função, os pontos de treino e a interpolação utilizando características polinomiais.
## representar graficamente a função
lw = 2
fig, ax = plt.subplots()
ax.set_prop_cycle(
color=["black", "teal", "yellowgreen", "gold", "darkorange", "tomato"]
)
ax.plot(x_plot, f(x_plot), linewidth=lw, label="ground truth")
## representar graficamente os pontos de treino
ax.scatter(x_train, y_train, label="pontos de treino")
## características polinomiais
for degree in [3, 4, 5]:
model = make_pipeline(PolynomialFeatures(degree), Ridge(alpha=1e-3))
model.fit(X_train, y_train)
y_plot = model.predict(X_plot)
ax.plot(x_plot, y_plot, label=f"grau {degree}")
ax.legend(loc="lower center")
ax.set_ylim(-20, 10)
plt.show()
Interpolação com B-Splines
Usaremos SplineTransformer para gerar funções de base B-spline e ajustar um modelo de regressão de ridge aos dados de treino. Em seguida, representaremos graficamente a função, os pontos de treino e a interpolação usando B-splines.
## B-spline com 4 + 3 - 1 = 6 funções de base
model = make_pipeline(SplineTransformer(n_knots=4, degree=3), Ridge(alpha=1e-3))
model.fit(X_train, y_train)
y_plot = model.predict(X_plot)
ax.plot(x_plot, y_plot, label="B-spline")
ax.legend(loc="lower center")
ax.set_ylim(-20, 10)
plt.show()
Representando os Transformadores
Representamos todas as colunas de ambos os transformadores separadamente para fornecer mais informações sobre as bases de características geradas.
fig, axes = plt.subplots(ncols=2, figsize=(16, 5))
pft = PolynomialFeatures(degree=3).fit(X_train)
axes[0].plot(x_plot, pft.transform(X_plot))
axes[0].legend(axes[0].lines, [f"grau {n}" for n in range(4)])
axes[0].set_title("PolynomialFeatures")
splt = SplineTransformer(n_knots=4, degree=3).fit(X_train)
axes[1].plot(x_plot, splt.transform(X_plot))
axes[1].legend(axes[1].lines, [f"spline {n}" for n in range(6)])
axes[1].set_title("SplineTransformer")
## representar os nós do spline
knots = splt.bsplines_[0].t
axes[1].vlines(knots[3:-3], ymin=0, ymax=0.8, linestyles="dashed")
plt.show()
Splines Periódicas
Demonstramos o uso de splines periódicas utilizando o SplineTransformer e especificando manualmente os nós. Ajustamos um modelo de regressão de ridge aos dados de treino e representamos graficamente a função, os pontos de treino e a interpolação usando splines periódicas.
def g(x):
"""Função a ser aproximada por interpolação spline periódica."""
return np.sin(x) - 0.7 * np.cos(x * 3)
y_train = g(x_train)
## Estender os dados de teste para o futuro:
x_plot_ext = np.linspace(-1, 21, 200)
X_plot_ext = x_plot_ext[:, np.newaxis]
lw = 2
fig, ax = plt.subplots()
ax.set_prop_cycle(color=["black", "tomato", "teal"])
ax.plot(x_plot_ext, g(x_plot_ext), linewidth=lw, label="verdade fundamental")
ax.scatter(x_train, y_train, label="pontos de treino")
for transformer, label in [
(SplineTransformer(degree=3, n_knots=10), "spline"),
(
SplineTransformer(
degree=3,
knots=np.linspace(0, 2 * np.pi, 10)[:, None],
extrapolation="periodic",
),
"spline periódica",
),
]:
model = make_pipeline(transformer, Ridge(alpha=1e-3))
model.fit(X_train, y_train)
y_plot_ext = model.predict(X_plot_ext)
ax.plot(x_plot_ext, y_plot_ext, label=label)
ax.legend()
fig.show()
Resumo
Neste laboratório, aprendemos como aproximar uma função com polinómios até um determinado grau utilizando regressão de ridge. Mostramos duas formas diferentes de fazer isto, dados n_samples de pontos 1D x_i. Usámos a função make_pipeline para adicionar características não lineares e demonstramos como estes transformadores são adequados para modelar efeitos não lineares com um modelo linear. Representámos graficamente a função, os pontos de treino e a interpolação utilizando características polinomiais e B-splines. Também representámos separadamente todas as colunas de ambos os transformadores e mostramos os nós da spline. Finalmente, demonstramos o uso de splines periódicas.