前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >手撸机器学习算法 - 多项式回归

手撸机器学习算法 - 多项式回归

作者头像
HoLoong
发布2021-06-21 20:22:54
5640
发布2021-06-21 20:22:54
举报
文章被收录于专栏:尼莫的AI小站

系列文章目录:

算法介绍

今天我们来一起学习一个除了线性回归外最最最简单的回归算法:多项式回归

从线性回归到多项式回归

事实上与线性回归相比,多项式回归没有增加任何需要推导的东西,唯一增加的是对原始数据进行多项式特征转换,这有点类似我们在非线性问题中对特征的处理:将

x_1

转换为

x_1^2

,之前我们是通过对数据的探索来决定如何进行转换,在多项式回归中,则是简单的指定一个阶,然后对所有列构建N元N次的方程中的所有项即可,这么说有点抽象,下面举个简单的例子:

对有两个特征的数据做三阶的多项式特征转换:

x_1 + x_2

转换为

x_1^3 + x_2^3 + x_1^2*x_2 + x_2^2*x_1 + x_1^2 + x_2^2 + x_1*x_2 + x_1 + x_2

,可以看到,通过做三阶变换,特征数从两个增长到了九个,多项式特征转换是非常简单且实用的构建特征手段之一,它不仅能构建特征自身的高阶版,同时还能构建特征与特征之间的组合特征,通常效果都不错哦;

代码实现

上面说了,多项式回归与线性回归唯一区别就在多项式特征构建上,因此代码部分也主要关注这一点,关于多项式特征构建,大家既可以基于sklearn库中的方法实现,也可以自己实现,都很简单哈;

sklearn实现多项式特征构建

代码语言:javascript
复制
from sklearn.preprocessing import PolynomialFeatures
poly = PolynomialFeatures(degrees)
X = poly.fit_transform(X)

自己实现多项式特征构建

代码语言:javascript
复制
def build_combs(self,elements,times):
    '''
    构建多项式的元组合
    elements 元数
    times 次数
    '''
    x_list = sum([[i]*times for i in range(elements)],[])
    combs = sum([list(set(combinations(x_list,i))) for i in range(1,times+1)],[])
    return [list(comb) for comb in combs]

def polynomial(self,x):
    '''
    x shape = [1 N]
    '''
    fun = lambda x,y:x*y
    return [reduce(fun,x[comb]) for comb in self.combs]

运行结果

全部代码

多项式回归代码

代码语言:javascript
复制
import numpy as np
from itertools import combinations
from functools import reduce
from 线性回归最小二乘法矩阵实现 import LinearRegression as LR

class PolynomialRegression(LR):
    def __init__(self,X,y,degrees=1):
        self.combs = self.build_combs(X.shape[1],degrees)
        X = np.array([self.polynomial(x) for x in X])
        super(PolynomialRegression,self).__init__(X,y)

    def predict(self,x):
        x = self.polynomial(x)
        return super(PolynomialRegression,self).predict(x)

    def build_combs(self,elements,times):
        '''
        构建多项式的元组合
        elements 元数
        times 次数
        '''
        x_list = sum([[i]*times for i in range(elements)],[]) # 二元二次 [1 1 2 2]
        combs = sum([list(set(combinations(x_list,i))) for i in range(1,times+1)],[]) # 二元二次 [[1 1] [2 2] [1 2] [1] [2]]
        return [list(comb) for comb in combs]

    def polynomial(self,x):
        '''
        x shape = [1 N]
        '''
        fun = lambda x,y:x*y
        return [reduce(fun,x[comb]) for comb in self.combs]

测试代码

代码语言:javascript
复制
import matplotlib.pyplot as plt
import numpy as np
from sklearn.model_selection import train_test_split as tts
from 多项式回归 import PolynomialRegression as PR

rnd = np.random.RandomState(3)
x_min, x_max = 0, 10

def pain(pos=141,xlabel='x',ylabel='y',title='',x=[],y=[],line_x=[],line_y=[]):
    plt.subplot(pos)
    plt.title(title)
    plt.xlabel(xlabel)
    plt.ylabel(ylabel)
    plt.scatter(x,y)
    plt.plot(line_x,line_y)

# 上帝函数 y=f(x)
def f(x):
    return x**5-22*x**4+161*x**3-403*x**2+36*x+938

# 上帝分布 P(Y|X)
def P(X):
    return f(X) + rnd.normal(scale=30, size=X.shape)

# 通过 P(X, Y) 生成数据集 D
X = rnd.uniform(x_min, x_max, 50)   # 通过均匀分布产生 X
y = P(X)                            # 通过 P(Y|X) 产生 y

plt.subplot(332)
plt.scatter(x=X, y=y)
xx = np.linspace(x_min, x_max)
plt.plot(xx, f(xx), 'k--')

X_train,X_test,y_train,y_test = tts(X,y,test_size=0.3,random_state=10086)
X_train,X_test,y_train,y_test = X_train.reshape(-1,1),X_test.reshape(-1,1),y_train.reshape(-1,1),y_test.reshape(-1,1)

for pos,deg in zip([334,335,336,337,338,339],[1,3,5,8,15,20]):
    model = PR(X=X_train,y=y_train,degrees=deg)
    w,b = model.train()
    x_min,x_max = min(X_train),max(X_train)
    line_x = [x_min+(x_max-x_min)*(i/100) for i in range(100)]
    line_y = [model.predict(x) for x in line_x]
    pain(pos,'x','y','DEG='+str(deg),X_train[:,0],y_train[:,0],line_x,line_y)

plt.tight_layout()
plt.show()

最后

可以看到,实际上多项式回归是非常简单的,实际应用上对于很多简单任务的拟合效果也非常好,解释性也不错;

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-06-17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 算法介绍
  • 从线性回归到多项式回归
  • 代码实现
    • sklearn实现多项式特征构建
      • 自己实现多项式特征构建
      • 运行结果
      • 全部代码
        • 多项式回归代码
          • 测试代码
          • 最后
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档