多项式回归是一种回归算法(多项式回归是基于线性回归的扩展,多项式回归是用于解决非线性的回归问题).
对于这样的数据,虽然我们可以使用线性回归来拟合这些数据,但是这些数据更像是一条二次曲线,相应的方程是
y = a x 2 + b x + c y = ax^2+ bx + c y=ax2+bx+c
这是式子虽然可以理解为二次方程,但是我们呢可以从另外一个角度来理解这个式子:
如果将 x2 理解为一个特征,将 x 理解为另外一个特征,换句话说,本来我们的样本只有一个特征 x ,现在我们把他看成有两个特征的一个数据集。多了一个特征 x2 ,那么从这个角度来看, 这个式子依旧是一个线性回归的式子,但是从 x的角度来看,它就是一个二次的方程。
以上这样的方式,就是所谓的多项式回归相当于我们为样本多添加了一些特征,这些特征是原来样本的多项式项,增加了这些特征之后,我们可以使用线性回归的思路来更好的处理我们的数据。
多项式回归模型一般都是处理非线性的数据。
做出数据的散点图
算法不能够很好的所有样本数据,算法所训练的模型不能完整的描述数据之间的关系。
(例: 一个二次曲线的数据 用一次曲线来拟合,就会造成欠拟合)
解决方法:
1. 添加多项式特征,这个在机器学习算法里面用的很普遍,例如将线性模型通过添加二次项或者三次项使模型泛化能力更强;
2. 减少正则化参数,正则化的目的是用来防止过拟合的,但是模型出现了欠拟合,则需要减少正则化参数;
3. 更换模型 ,使用非线性模型,比如核SVM 、决策树、深度学习等模型;
4. 调整模型的容量(capacity),模型的容量是指其拟合各种函数的能力。通俗地,就是增加数据量;
算法过度拟合了所有数据,过度表达了数据间的噪音关系。
(就是你使用训练数据拟合模型完美,一用测试数据,就MSE很大,这就是过拟合)
解决方法:
进行交叉验证
交叉验证主要分为两种: K-折交叉验证 和 留一法
普通情况:训练集+测试集 --> 模型 问题:可能过拟合
缺点:每次训练k个模型,相当于整体性能满了k倍
实现代码:
#实现K近邻算法的一个类,一般都使用欧式距离进行测量。 这里仅仅是完成交叉验证,不完整
knn_clf_cv = KNeighborsClassifier()
#导入交叉验证的类 cross_val_score
from sklearn.model_selection import cross_val_score
#进行交叉验证。 参数为(训练出的模型 , train_data , train_label )
cross_val_score(knn_clf_cv,train_data,train_label)
对knn算法进行练习:
import numpy as np
from sklearn import datasets
digits = datasets.load_digits()# 导入数据集
X = digits.data
Y = digits.target
# 数据集训练集分割
from sklearn.model_selection import train_test_split
train_data,test_data ,train_label,test_label =train_test_split(X,Y,test_size=0.2,random_state=666)
from sklearn.neighbors import KNeighborsClassifier
best_k = 0
best_score = 0.0
best_p = 0
for k in range(1,11):
for p in range(1,6):
knn_clf = KNeighborsClassifier(n_neighbors = k,weights='distance',p=p)
knn_clf.fit(train_data,train_label)
scores = cross_val_score(knn_clf_cv,train_data,train_label)
score = np.mean(score)
if score > best_score:
best_p = p
best_score = score
best_k = k
print('best_k',best_k)
print('best_p',best_p)
print('best_score ',best_score)
留一法就是每次留下一个样本做测试集,其他样本做训练集,如果有k个样本,则需要训练k次,测试k次。
优点:完全不受随机影响,最接近模型真实性能指标。
缺点:计算量巨大
随着训练样本的逐渐增多,算法训练出的模型的表现能力。
通过学习曲线,可以查看模型的欠拟合和过拟合情况
通常对于这样一个图,会有两根曲线:
一个是对于训练数据集来说的,模型越复杂,模型准确率越高,因为模型越复杂,对训练数据集的拟合就越好,相应的模型准确率就越高
对于测试数据集来说,在模型很简单的时候,模型的准确率也比较低,随着模型逐渐变复杂,对测试数据集的准确率在逐渐的提升,提升到一定程度后,如果模型继续变复杂,那么我们的模型准确率将会进行下降(欠拟合->正合适->过拟合)
from sklearn.linear_model import LinearRegression #导入最小二乘线性回归模型
train_score = []
test_score = []
for i in range(1,len(train_data)+1):
#获取模型对象
lin_reg = LinearRegression()
#随着样本集的逐渐增加,来观察模型的学习能力
#训练模型
lin_reg.fit(train_data[:i],train_label[:i])
#训练集评测
# predict(x):预测方法,将返回值y_pred
predict_train = lin_reg.predict(train_data[:i])
#将均方误差存起来
train_score.append(mean_squared_error(train_label[:i],predict_train))
#测试集评测
predict_test = lin_reg.predict(test_data)
test_score.append(mean_squared_error(test_label,predict_test))
plt.plot(
[i for i in range(1,len(train_data)+1)],np.sqrt(train_score),label='train_score')
plt.plot([i for i in range(1,len(train_data)+1)],np.sqrt(test_score),label='test_score')
plt.show()
流水线的输入为一连串的数据挖掘步骤,其中最后一步必须是估计器(Estimator),可理解成分类器。前几步是转换器(Transformer)。输入的数据集经过转换器的处理后,输出的结果作为下一步的输入。最后,用位于流水线最后一步的估计器对数据进行分类。
from sklearn.pipeline import Pipeline #导入各种类
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
x = np.random.uniform(-3,3,size = 100)
y = 0.5 - x **2 + x + 3 +np.random.normal(0,1,size=100)
X = x.reshape(-1,1)
'''
Pipeline创建流水线的功能:
跟踪记录各步骤的操作(以方便地重现实验结果)
对各步骤进行一个封装
确保代码的复杂程度不至于超出掌控范围
'''
poly = Pipeline([
# PolynomialFeatures() 生成多项式特征项 例:如果有a,b两个特征,
# degree:控制多项式的度 那么它的2次多项式为(1,a,b,a^2,ab, b^2)
('poly', PolynomialFeatures(degree=2)),
# StandardScaler() 标准化
('std_scaler', StandardScaler()),
# 导入最小二乘线性回归模型
('lin_reg', LinearRegression())
])
#训练模型
poly.fit(X,y)
#预测
poly.predict(X)
polynomial=PolynomialFeatures(degree=2) # 构建多项式回归器对象 # degree是多项式的次数,此处初步的设置为2
import numpy as np
import matplotlib.pyplot as plt
x = np.random.uniform(-3,3,size = 100)
y = 0.5 - x **2 + x + 3 +np.random.normal(0,1,size=100)
plt.scatter(x,y)
plt.show()
from sklearn.linear_model import LinearRegression
X = x.reshape(-1,1)
from sklearn.model_selection import train_test_split
train_data,test_data ,train_label,test_label =train_test_split(X,y,test_size=0.2,random_state=666)
#模型对象
lin_reg = LinearRegression()
#训练模型
lin_reg.fit(train_data,train_label)
lin_reg.score(test_data,test_label)
#添加多项式
X2 = np.hstack([X , X**2])
lin_reg2 = LinearRegression()
#重新训练
lin_reg2.fit(X2,y)
predict_X2 = lin_reg2.predict(X2)
plt.scatter(x,y)
plt.plot(np.sort(x),predict_X2[np.argsort(x)],color='r')
plt.show()