PolynomialFeatures 和 LinearRegression returns 不良系数
PolynomialFeatures and LinearRegression returns undesirable coefficients
import os
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
csv_path = os.path.join('', 'graph.csv')
graph = pd.read_csv(csv_path)
y = graph['y'].copy()
x = graph.drop('y', axis=1)
pipeline = Pipeline([('pf', PolynomialFeatures(2)), ('clf', LinearRegression())])
pipeline.fit(x, y)
predict = [[16], [20], [30]]
plt.plot(x, y, '.', color='blue')
plt.plot(x, pipeline.predict(x), '-', color='black')
plt.plot(predict, pipeline.predict(predict), 'o', color='red')
plt.show()
我的graph.csv:
x,y
1,1
2,2
3,3
4,4
5,5
6,5.5
7,6
8,6.25
9,6.4
10,6.6
11,6.8
产生的结果:
它显然在产生错误的预测;每个 x,y 应该增加。
我错过了什么?我尝试改变学位,但情况并没有好转。例如,当我使用 4 的次数时,y 会非常非常迅速地增加。
What am I missing?
也许 PolynomialFeatures
转换没有按照您的预期进行?它通常用于生成特征交互,而不是逼近多项式函数 本身 .
当我运行你的代码时,那么拟合的管道对应如下等式:
y = 1.36105 * x - 0.0656177 * x^2 - 0.370606
预测模型由 x^2
项主导,与负系数相关联。
这是过度拟合的一个很好的例子。您的回归量太过难以拟合,但 x 和 y 遵循线性趋势,因此可能需要拟合线性方程(度数=1)。
或者您甚至可以尝试使用 Lasso 或 Ridge 正则化引入一些偏差,但前提是您想要拟合 2 阶或更高阶的曲线
with each x, y should increase.
您的数据确实存在 线性 正趋势,如果您对其拟合线性回归量(即 1 次多项式),您将在样本数据外的预测:
但是您已经对 二次 回归量进行了建模,因此它尽可能将二次曲线拟合到这些点。您的模型正在学习数据中的轻微 'bend' 作为曲线中的固定点,因此它会随着您向右延伸而减小:
如果您认为这种行为显然是错误的,那么您一定对数据的分布有一些假设。如果是这样,您应该使用这些来驱动您的模型选择。
I tried changing degrees, but it doesn't get much better. When I use degree of 4 for example, y increases very very rapidly.
您可以选择更高阶的多项式,如果您认为二次多项式不够灵活以映射数据的潜在趋势。但是多项式的行为可能会在数据极值之外出现很大差异:
Cubic
Quartic
Quintic
如您所见,多项式越复杂,它对特定数据点样本的确切趋势建模的灵活性就越大,但超出数据范围的泛化性就越差。
这被称为 overfitting。
有很多策略可以避免这种情况,例如:
- 收集更多数据
- 给您的数据添加噪音
- 添加正则化项
- 选择更简单的模型
在这种情况下,最简单的方法是后者 - 如果您怀疑您的数据遵循线性趋势,对其拟合线性模型。
@iacob 提供了一个非常好的答案,我只会扩展。
如果您确定 with each x, y should increase
,那么您的数据点可能遵循对数缩放模式。为此调整您的代码会产生这条曲线:
下面是代码片段,如果它符合您要查找的内容:
import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
csv_path = os.path.join('', 'graph.csv')
graph = pd.read_csv(csv_path)
y = graph['y'].copy()
x = graph.drop('y', axis=1)
x_log = np.log(x)
pipeline = Pipeline([('pf', PolynomialFeatures(1)), ('clf', LinearRegression())])
pipeline.fit(x_log, y)
predict = np.log([[16], [20], [30]])
plt.plot(np.exp(x_log), y, '.', color='blue')
plt.plot(np.exp(x_log), pipeline.predict(x_log), '-', color='black')
plt.plot(np.exp(predict), pipeline.predict(predict), 'o', color='red')
plt.show()
请注意,我们只是对 x 数据点 ( x_log
) 的对数进行多项式回归(此处线性回归就足够了)。
import os
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
csv_path = os.path.join('', 'graph.csv')
graph = pd.read_csv(csv_path)
y = graph['y'].copy()
x = graph.drop('y', axis=1)
pipeline = Pipeline([('pf', PolynomialFeatures(2)), ('clf', LinearRegression())])
pipeline.fit(x, y)
predict = [[16], [20], [30]]
plt.plot(x, y, '.', color='blue')
plt.plot(x, pipeline.predict(x), '-', color='black')
plt.plot(predict, pipeline.predict(predict), 'o', color='red')
plt.show()
我的graph.csv:
x,y
1,1
2,2
3,3
4,4
5,5
6,5.5
7,6
8,6.25
9,6.4
10,6.6
11,6.8
产生的结果:
它显然在产生错误的预测;每个 x,y 应该增加。
我错过了什么?我尝试改变学位,但情况并没有好转。例如,当我使用 4 的次数时,y 会非常非常迅速地增加。
What am I missing?
也许 PolynomialFeatures
转换没有按照您的预期进行?它通常用于生成特征交互,而不是逼近多项式函数 本身 .
当我运行你的代码时,那么拟合的管道对应如下等式:
y = 1.36105 * x - 0.0656177 * x^2 - 0.370606
预测模型由 x^2
项主导,与负系数相关联。
这是过度拟合的一个很好的例子。您的回归量太过难以拟合,但 x 和 y 遵循线性趋势,因此可能需要拟合线性方程(度数=1)。 或者您甚至可以尝试使用 Lasso 或 Ridge 正则化引入一些偏差,但前提是您想要拟合 2 阶或更高阶的曲线
with each x, y should increase.
您的数据确实存在 线性 正趋势,如果您对其拟合线性回归量(即 1 次多项式),您将在样本数据外的预测:
但是您已经对 二次 回归量进行了建模,因此它尽可能将二次曲线拟合到这些点。您的模型正在学习数据中的轻微 'bend' 作为曲线中的固定点,因此它会随着您向右延伸而减小:
如果您认为这种行为显然是错误的,那么您一定对数据的分布有一些假设。如果是这样,您应该使用这些来驱动您的模型选择。
I tried changing degrees, but it doesn't get much better. When I use degree of 4 for example, y increases very very rapidly.
您可以选择更高阶的多项式,如果您认为二次多项式不够灵活以映射数据的潜在趋势。但是多项式的行为可能会在数据极值之外出现很大差异:
Cubic | Quartic | Quintic |
如您所见,多项式越复杂,它对特定数据点样本的确切趋势建模的灵活性就越大,但超出数据范围的泛化性就越差。
这被称为 overfitting。
有很多策略可以避免这种情况,例如:
- 收集更多数据
- 给您的数据添加噪音
- 添加正则化项
- 选择更简单的模型
在这种情况下,最简单的方法是后者 - 如果您怀疑您的数据遵循线性趋势,对其拟合线性模型。
@iacob 提供了一个非常好的答案,我只会扩展。
如果您确定 with each x, y should increase
,那么您的数据点可能遵循对数缩放模式。为此调整您的代码会产生这条曲线:
下面是代码片段,如果它符合您要查找的内容:
import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
csv_path = os.path.join('', 'graph.csv')
graph = pd.read_csv(csv_path)
y = graph['y'].copy()
x = graph.drop('y', axis=1)
x_log = np.log(x)
pipeline = Pipeline([('pf', PolynomialFeatures(1)), ('clf', LinearRegression())])
pipeline.fit(x_log, y)
predict = np.log([[16], [20], [30]])
plt.plot(np.exp(x_log), y, '.', color='blue')
plt.plot(np.exp(x_log), pipeline.predict(x_log), '-', color='black')
plt.plot(np.exp(predict), pipeline.predict(predict), 'o', color='red')
plt.show()
请注意,我们只是对 x 数据点 ( x_log
) 的对数进行多项式回归(此处线性回归就足够了)。