多项式回归及过拟合欠拟合处理

回顾

  • 什么是回归问题
    • 如果需要处理的标签数据为连续性数据,则该问题为回归问题
  • 什么是线性回归
    • 就是在找寻特征数据和标签数据之间的线性关系,可以使用权重系数来表示。
    • 权重系数的个数一定是和特征维度保持一致。
  • 线性回归的矩阵表达
    • y = wx + b
    • Y = XWt
  • 损失函数
    • 误差平方和/残差平方和
  • 最小二乘法的作用
    • 可以使得损失值进行最小化,在损失值最小化的情况下求解出最优的权重系数W
    • 损失函数对W进行求导,且将一阶导数等于0.
  • 回归模型的评价指标
    • 模型是否能够预测到真实值或者接近真实的值
      • MSE:均方误差
    • 模型是否拟合到了足够的信息
      • R2

实战

  • 房地产估价数据集数据集(house.xlsx)
    • 数据集信息:
      • 房地产估值的市场历史数据集来自台湾新北市新店区。“房地产估价” 是一个回归问题。
    • 属性信息:
      • 输入如下:
        • X1 =交易日期(例如,2013.250 = 2013年3月,2013.500 = 2013年6月,等等)
        • X2 =房屋年龄(单位:年)
        • X3 =到最近的捷运站的距离(单位:米) )
        • X4 =步行生活圈中的便利店的数量(整数)
        • X5 =地理坐标,纬度。(单位:度)
        • X6 =地理坐标,经度。(单位:度)
      • 输出结果如下:
        • Y =单位面积的房价(10000新台币/ Ping,其中Ping是本地单位,1 Ping = 3.3米平方)
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
import pandas as pd
from sklearn.metrics import mean_squared_error as MSE
#读取数据
df = pd.read_excel('./datasets/house.xlsx')
#删除多余的列
df = df.drop(labels='No',axis=1)
#特征 标签
feature =  df.loc[:,df.columns != 'Y house price of unit area']
target = df['Y house price of unit area']
#数据集的切分
x_train,x_test,y_train,y_test = train_test_split(feature,target,test_size=0.2,random_state=2020)

linner = LinearRegression()
linner.fit(x_train,y_train)

y_pred = linner.predict(x_test)
MSE(y_test,y_pred) #55.334060500911804
y_test.max(),y_test.min() #(63.2, 13.8)
linner.score(x_test,y_test) #0.6108181277767183

linner.score(x_train,y_train) #0.5750984249253495
#在测试集和训练集表现都不好,因此为欠拟合

#出现问题:训练好的模型没有很好的拟合到原始的样本数据中标签和特征值之间的线性关系。
  • 使用多项式回归处理上述案例出现的欠拟合问题

二次项

feature =  df.loc[:,df.columns != 'Y house price of unit area']
target = df['Y house price of unit area']
#给原始特征增加高次项特征
from sklearn.preprocessing import PolynomialFeatures
p = PolynomialFeatures(degree=2)
d_2_feature = p.fit_transform(feature)
#数据集的切分
x_train,x_test,y_train,y_test = train_test_split(d_2_feature,target,test_size=0.2,random_state=2020)

linner = LinearRegression().fit(x_train,y_train)
y_pred = linner.predict(x_test)
MSE(y_test,y_pred) #30.83018292349415
linner.score(x_test,y_test) #0.7831616150606915

​ 三次项

feature =  df.loc[:,df.columns != 'Y house price of unit area']
target = df['Y house price of unit area']
#给原始特征增加高次项特征
from sklearn.preprocessing import PolynomialFeatures
p = PolynomialFeatures(degree=3)
d_3_feature = p.fit_transform(feature)
#数据集的切分
x_train,x_test,y_train,y_test = train_test_split(d_3_feature,target,test_size=0.2,random_state=2020)

linner = LinearRegression().fit(x_train,y_train)
y_pred = linner.predict(x_test)
MSE(y_test,y_pred) #34.37178091836353
linner.score(x_test,y_test) #0.7582524411119846

欠拟合&&过拟合

  • 案例1:
    • 现在有一组天鹅的特征数据然后对模型进行训练,然后模型学习到的内容是有翅膀,嘴巴长的就是天鹅。然后使用模型进行预测,该模型可能会将所有符合这两个特征的动物都预测为天鹅,则肯定会有误差的,因为鹦鹉,秃鹫都符合有翅膀和嘴巴长的特征。
      • 原因:模型学习到的天鹅的特征太少了,导致区分标准太粗糙,不能准确的识别出天鹅。
  • 案例2:
    • 更新了样本的特征数据了,增加了一些特征,然后训练模型。模型这次学习到的内容是,有翅膀、嘴巴长、白色、体型像2、脖子长且有弯度的就是天鹅。然后开始使用模型进行预测,现在一组测试数据为鹦鹉,因为鹦鹉的体型小,脖子短不符合天鹅的特征,则预测结果为不是天鹅。然后又有一组特征为黑天鹅,结果因为颜色不是白色,预测成了黑天鹅。
      • 原因:现在模型学习到的特征已经基本可以区分天鹅和其他动物了。但是学习到的特征中有一项是羽毛是白色,那么就会导致将黑天鹅无法识别出来。也就是机器学习到的特征太依赖或者太符合训练数据了。

1.欠拟合&&过拟合

  • 欠拟合:案例1中的场景就可以表示欠拟合
    • 一个假设在训练数据上不能获得很好的拟合,在训练数据以外的数据集上也不能很好的拟合数据,此时认为这个假设出现了欠拟合的现象。(模型过于简单)
  • 过拟合:案例2中的场景就可以表示过拟合
    • 一个假设在训练数据上能够获得比其他假设更好的拟合,但是在训练数据以外的数据集上却不能很好的拟合数据,此时认为这个假设出现了过拟合现象。(模型过于复杂)
欠拟合 过拟合.png

2.欠拟合和过拟合的解决

  • 欠拟合:

    • 原因:模型学习到样本的特征太少
    • 解决:增加样本的特征数量(多项式回归)
  • 过拟合:

    • 原因:原始特征过多,存在一些嘈杂特征。
    • 解决:
      • 进行特征选择,消除关联性大的特征(很难做)
      • 正则化之岭回归(掌握)
  • 模型的复杂度 --》回归出直线or曲线 :

    回归模型算法就是在寻找特征值和目标值之间存在的某种关系,那么这种关系越复杂则表示训练出的模型的复杂度越高,反之越低。

    模型的复杂度由特征和目标之间的关系导致的 , 特征和目标之间的关系不仅仅是线性关系

1.欠拟合的处理:多项式回归

为了解决欠拟合的情 经常要提高线性的次数(高次多项式)建立模型拟合曲线,次数过高会导致过拟合,次数不够会欠拟合。

  • y = w*x + b 一次多项式函数
  • y = w1x^2 + w2x + b 二次多项式函数
  • y = w1x^3 + w2x^2 + w3*x + b 三次多项式函数

高次多项式函数的表示为曲线

线性回归模型y=wx+b只能解决线性(回归出的为直线)问题,多项式回归能够解决非线性回归(回归出的为曲线)问题。

多项式回归可以看成特殊的线性模型

  • 建立二次多项式线性回归模型进行预测

    • 根据二次多项式公式可知,需要给原始特征添加更高次的特征数据x^2.

      • y=w1x∧2+w2x+b
    • 如何给样本添加高次的特征数据呢?

      • 使用sklearn.preprocessing.PolynomialFeatures来进行更高次特征的构造

        • 它是使用多项式的方法来进行的,如果有a,b两个特征,那么它的2次多项式为(1,a,b,a^2,ab, b^2)

        • PolynomialFeatures有三个参

          • degree:控制多项式的度

          • interaction_only: 默认为False,如果指定为True,上面的二次项中没有a2和b2。

          • include_bias:默认为True。如果为False的话,那么就不会有上面的1那一项

            #工具类的基本使用
            from sklearn.preprocessing import PolynomialFeatures
            p = PolynomialFeatures(degree=2)
            p.fit_transform([[3,5]])
            #array([[ 1.,  3.,  5.,  9., 15., 25.]])
            
示例
  • 下面模拟 根据蛋糕的直径大小 预测蛋糕价格
from sklearn.linear_model import LinearRegression
import numpy as np
import matplotlib.pyplot as plt
# 样本的训练数据,特征和目标值
x_train = [[6], [8], [10], [14], [18]] #大小
y_train = [[7], [9], [13], [17.5], [18]]#价格
linner = LinearRegression()
linner.fit(x_train,y_train)
#画图
y_pred = linner.predict(x_train)
plt.scatter(x_train,y_train)
plt.plot(x_train,y_pred)
plt.xlabel('size_x')
plt.ylabel('price_y')
蛋糕1.png
  • 建立二次多项式线性回归模型进行预测
#二次特征的构造
p = PolynomialFeatures(degree=2)
d_2_train = p.fit_transform(x_train)
linner = LinearRegression().fit(d_2_train,y_train)
#画图
y_pred = linner.predict(d_2_train)
plt.scatter(x_train,y_train)
plt.plot(x_train,y_pred)
plt.xlabel('size_x')
plt.ylabel('price_y')
蛋糕2.png
  • 建立3次多项式线性回归模型进行预测
# 3次特征的构造
p = PolynomialFeatures(degree=3)
d_3_train = p.fit_transform(x_train)
linner = LinearRegression().fit(d_3_train,y_train)
#画图
y_pred = linner.predict(d_3_train)
plt.scatter(x_train,y_train)
plt.plot(x_train,y_pred)
plt.xlabel('size_x')
plt.ylabel('price_y')
蛋糕3.png
2.过拟合处理:正则化
- 将过拟合的曲线的凹凸幅度减少就可以将过拟合曲线趋近于拟合曲线了。那么过拟合曲线的凹凸肯定是由y=wx**2+x**3+x**4中的高次项导致的,那么正则化就可以通过不断的尝试发现高次项的特征然后这些特征的权重w调小到0,则高次项的特征没有了,那么凹凸幅度就减少了,就越趋近于拟合曲线了!
- 可以使得高次项的w权重减小,趋近于0.
- LinnerRegression是没有办法进行正则化的,所以该算法模型容易出现过拟合,并且无法解决。
  • L2正则化:
    • 使用带有正则化算法的回归模型(Ridge岭回归)处理过拟合的问题。
3.Ridge岭回归:具备L2正则化的线性回归模型
  • API:from sklearn.linear_model import Ridge

  • Ridge(alpha=1.0):

    • alpha:正则化的力度,力度越大,则表示高次项的权重w越接近于0,导致过拟合曲线的凹凸幅度越小。
      • 取值:0-1小数或者1-10整数
    • coef_:回归系数
  • 使用岭回归可以通过控制正则化力度参数alpha降低高次项特征的权重

x_train = [[6], [8], [10], [14], [18]] #大小
y_train = [[7], [9], [13], [17.5], [18]]#价格
p = PolynomialFeatures(degree=3)
d_3_train = p.fit_transform(x_train)
linner = LinearRegression().fit(d_3_train,y_train)
linner.coef_
#array([[ 0.        , -1.42626096,  0.31320489, -0.01103344]])
from sklearn.linear_model import Ridge
p = PolynomialFeatures(degree=3)
d_3_train = p.fit_transform(x_train)
ridge=Ridge(alpha=0.1)
ridge.fit(d_3_train,y_train)
ridge.coef_
#array([[ 0.        , -0.54302902,  0.23512062, -0.00888958]])
  • 岭回归的优点:
    • 获取的回归系数更符合实际更可靠
    • 在病态数据(异常值多的数据)偏多的研究中有更大的存在意义
模型的保存和加载
  • from sklearn.externals import joblib

    • joblib.dump(model,'xxx.m'):保存
    • joblib.load('xxx.m'):加载
  • import pickle

    • with open('./123.pkl','wb') as fp:
      • pickle.dump(linner,fp)
    • with open('./123.pkl','rb') as fp:
      • linner = pickle.load(fp)
import pickle
with open('./ridge.pkl','wb') as fp:
    pickle.dump(ridge,fp)
ridge=None
with open('./ridge.pkl','rb') as fp:
    ridge=pickle.load(fp)
print(ridge)   
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345