使用 patsy cr 的自然三次样条
Natural cubic spline using patsy cr
我正在尝试使用 patsy
库制作自然三次样条。
这是我的代码:
import numpy as np
from sklearn.linear_model import LinearRegression
from patsy import cr
import matplotlib.pyplot as plt
x = df.age #some data
y = df.wage
x_basis = cr(x, df=15)
model = LinearRegression().fit(x_basis, y)
y_hat = model.predict(x_basis)
plt.scatter(x, y)
plt.plot(x, y_hat, 'r')
plt.show()
输出如下:
我认为应该有一行。我该如何解决这个问题?
Bruh,在传递给 patsy 函数之前对您的值进行排序。
DSBA广场教师助理团队
这只是一个策划问题。 plt.plot 函数默认绘制不带标记的 线图 。由于您的数据未按 x
变量排序,因此该行来回跳转使结果看起来很乱。我生成了示例数据并使用 plt.plot
默认值绘制,然后隐藏线条并添加标记。结果是
使用默认 plt.plot
个参数
下面的其余代码(为方便起见不再重复)
spline_basis = patsy.cr(x, df=3)
model = LinearRegression().fit(spline_basis, y)
y_spline = model.predict(spline_basis)
plt.scatter(x, y)
plt.plot(x, y_spline, color="red")
plt.show()
与plt.plot
当marker='.'
和ls=''
下面的其余代码(为方便起见不再重复)
spline_basis = patsy.cr(x, df=3)
model = LinearRegression().fit(spline_basis, y)
y_spline = model.predict(spline_basis)
plt.scatter(x, y)
plt.plot(x, y_spline, ls="", marker=".", color="red") # Only this changed
plt.show()
通过重新排序数据
下面的其余代码(为方便起见不再重复)
如果你想画一个线图,你可以重新排序数据进行拟合,像这样:
spline_basis = patsy.cr(x, df=3)
model = LinearRegression().fit(spline_basis, y)
y_spline = model.predict(spline_basis)
plt.scatter(x, y)
xsorted, ysorted = zip(*[(X, Y) for (X, Y) in sorted(zip(x, y_spline))]) # simple reordering
plt.plot(xsorted, ysorted, color="red")
plt.show()
使用新数据进行预测
通常,创建模型用于预测。这个想法是使用 训练数据 创建模型,然后使用一些 新数据 的模型。这个新数据可以是任何东西。如果已排序,则可以将其绘制为线图。在这种情况下,您可以创建新的 x 值,例如
new_x = np.linspace(10, 100, 100)
并计算它们的预测 y 值。为此,您只需要知道(并保存)几个值。实际上,只有 df
、lower_bound
、upper_bound
和 model._coef
.
中的 4 个浮点数
# Fit model
spline_basis = patsy.cr(x, df=3, lower_bound=x.min(), upper_bound=x.max())
model = LinearRegression().fit(spline_basis, y)
y_train = model.predict(spline_basis)
# Use model
new_x = np.linspace(10, 100, 100) # 100 points
spline_basis_new = patsy.cr(new_x, df=3, lower_bound=x.min(), upper_bound=x.max())
new_y = model.predict(spline_basis_new)
plt.scatter(x, y)
plt.plot(x, y_train, color="red", ls="", marker=".")
plt.plot(new_x, new_y, color="green")
plt.show()
其余代码
from matplotlib import pyplot as plt
import numpy as np
import patsy
from sklearn.linear_model import LinearRegression
def dummy_data():
np.random.seed(1)
x = np.random.choice(np.arange(18, 81), size=4000)
def model(x):
a = 83 / 107520
b = -895 / 5376
c = 17747 / 1680
d = -622 / 7
return a * x ** 3 + b * x ** 2 + c * x + d
def noisemodel(x):
an = -0.0591836734693878
bn = 5.25510204081633
cn = -31.6326530612245
return an * x ** 2 + bn * x + cn
y = model(x)
ynoise = np.array([np.random.randn() * noisemodel(_) for _ in x])
return x, y + ynoise
x, y = dummy_data()
我正在尝试使用 patsy
库制作自然三次样条。
这是我的代码:
import numpy as np
from sklearn.linear_model import LinearRegression
from patsy import cr
import matplotlib.pyplot as plt
x = df.age #some data
y = df.wage
x_basis = cr(x, df=15)
model = LinearRegression().fit(x_basis, y)
y_hat = model.predict(x_basis)
plt.scatter(x, y)
plt.plot(x, y_hat, 'r')
plt.show()
输出如下:
我认为应该有一行。我该如何解决这个问题?
Bruh,在传递给 patsy 函数之前对您的值进行排序。
DSBA广场教师助理团队
这只是一个策划问题。 plt.plot 函数默认绘制不带标记的 线图 。由于您的数据未按 x
变量排序,因此该行来回跳转使结果看起来很乱。我生成了示例数据并使用 plt.plot
默认值绘制,然后隐藏线条并添加标记。结果是
使用默认 plt.plot
个参数
下面的其余代码(为方便起见不再重复)
spline_basis = patsy.cr(x, df=3)
model = LinearRegression().fit(spline_basis, y)
y_spline = model.predict(spline_basis)
plt.scatter(x, y)
plt.plot(x, y_spline, color="red")
plt.show()
与plt.plot
当marker='.'
和ls=''
下面的其余代码(为方便起见不再重复)
spline_basis = patsy.cr(x, df=3)
model = LinearRegression().fit(spline_basis, y)
y_spline = model.predict(spline_basis)
plt.scatter(x, y)
plt.plot(x, y_spline, ls="", marker=".", color="red") # Only this changed
plt.show()
通过重新排序数据
下面的其余代码(为方便起见不再重复)
如果你想画一个线图,你可以重新排序数据进行拟合,像这样:
spline_basis = patsy.cr(x, df=3)
model = LinearRegression().fit(spline_basis, y)
y_spline = model.predict(spline_basis)
plt.scatter(x, y)
xsorted, ysorted = zip(*[(X, Y) for (X, Y) in sorted(zip(x, y_spline))]) # simple reordering
plt.plot(xsorted, ysorted, color="red")
plt.show()
使用新数据进行预测
通常,创建模型用于预测。这个想法是使用 训练数据 创建模型,然后使用一些 新数据 的模型。这个新数据可以是任何东西。如果已排序,则可以将其绘制为线图。在这种情况下,您可以创建新的 x 值,例如
new_x = np.linspace(10, 100, 100)
并计算它们的预测 y 值。为此,您只需要知道(并保存)几个值。实际上,只有 df
、lower_bound
、upper_bound
和 model._coef
.
# Fit model
spline_basis = patsy.cr(x, df=3, lower_bound=x.min(), upper_bound=x.max())
model = LinearRegression().fit(spline_basis, y)
y_train = model.predict(spline_basis)
# Use model
new_x = np.linspace(10, 100, 100) # 100 points
spline_basis_new = patsy.cr(new_x, df=3, lower_bound=x.min(), upper_bound=x.max())
new_y = model.predict(spline_basis_new)
plt.scatter(x, y)
plt.plot(x, y_train, color="red", ls="", marker=".")
plt.plot(new_x, new_y, color="green")
plt.show()
其余代码
from matplotlib import pyplot as plt
import numpy as np
import patsy
from sklearn.linear_model import LinearRegression
def dummy_data():
np.random.seed(1)
x = np.random.choice(np.arange(18, 81), size=4000)
def model(x):
a = 83 / 107520
b = -895 / 5376
c = 17747 / 1680
d = -622 / 7
return a * x ** 3 + b * x ** 2 + c * x + d
def noisemodel(x):
an = -0.0591836734693878
bn = 5.25510204081633
cn = -31.6326530612245
return an * x ** 2 + bn * x + cn
y = model(x)
ynoise = np.array([np.random.randn() * noisemodel(_) for _ in x])
return x, y + ynoise
x, y = dummy_data()