技术生活

使用python实现简单的线性回归

简单的理解, 所谓回归分析( Regression Analysis ),就是分析一下几个变量之间的是否相关、相关方向与强度,然后建立一个模型,用于预测研究者感兴趣的变量。比如说,根据已有的员工的学历、经验年限、性别、所在城市、所事行业、目前薪资等资料,预测一下给定学历、年限、性别、所在城市、所事行业的员工的薪资。

线性回归(linear regression) 是最简单的回归分析,它是利用称为线性回归方程的最小二乘函数对一个或多个自变量和因变量之间关系进行建模的一种回归分析。这种函数是一个或多个称为回归系数的模型参数的线性组合。只有一个自变量的情况称为简单回归(simple regression),大于一个自变量情况的叫做多元回归(multivariable linear regression),自变量指数大于1的情况叫做多项式回归(ploynomial regression)。

下面以三段python代码记录一下三种类型的回归分析的python做法:

一、简单回归。

说白了就是f(x) = ax这种形式的数据,鉴诸以往,验之未来。

1.引用python package。

import random
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures

2.准备一些测试用的数据。注意输入数据x,它是一个二维数组,每行只有一列。

    # Simple Linear Regression With scikit-learn
    # for given equation: y = 5.5 + 4.7 * x,
    # create a dataset for input(x) and output(y)
    y = []
    x = []
    for i in range(0, 2):
        x.append(list([i]))
        y.append(5.5 + 4.7 * i)

    print("x for equation: y = 5.5 + 4.7 * x:")
    print(x)
    print("y for equation: y = 5.5 + 4.7 * x:")
    print(y)

3.创建一个线性回归模型并且适配一下测试数据。

    # Create a model and fit it
    model = LinearRegression().fit(x, y)
    # Get results
    r_sq = model.score(x, y)
    print('coefficient of determination:', r_sq)
    print('intercept:', model.intercept_)
    print('slope:', model.coef_)

4.预测一下旧的和新的数据。

    # Predict response
    y_pred = model.predict(x)
    print('predicted response:', y_pred, sep='\n')

    # Predict new data
    x_new = [list([item]) for item in range(10, 16)]
    print('x_new:', x_new, sep='\n')
    y_new = model.predict(x_new)
    print('predicted new:', y_new, sep='\n')

二、多元回归。

说白了就是f(x) = b0 + b1 * x1 + b2 * x2 – b3 * x3 这种形式的数据,其中b0, b1, b2, b3是常量,x1, x2, x3是自变量。 方程最终的结果,受这一大堆常量b和自变量x的影响。我们要做的,就是要根据历史数据中自变量x和最终结果f(x),找出这一大堆b到底以怎么的权重来影响最终结果。比如说:性别、学历、行业等因素到底是多大的权重来影响薪资?我们的任务就是找到这一大堆权重值(b0, b1, b2, b3)。知道了各个权重,我们就可以预测未来的新数据了。

1.创建测试数据。注意输入数据x,二维数组,每行有三列。

    # Multiple Linear Regression With scikit-learn
    # for given equation: y = 3.6 + 2.5 * a + 4.7 * m - 5.4 * n,
    # create a dataset for input(a, m, n) and output(y)
    y = []
    x = []
    for i in range(0, 6):
        a = random.randint(0, 100)
        m = random.randint(0, 100)
        n = random.randint(0, 100)
        x.append(list([a, m, n]))
        y.append(3.6 + 2.5 * a + 4.7 * m - 5.4 * n)

    print("[a, m, n] for equation: y = 3.6 + 2.5 * a + 4.7 * m - 5.4 * n:")
    print(x)
    print("y for equation: y = 3.6 + 2.5 * a + 4.7 * m - 5.4 * n:")
    print(y)

2.创建线性回归模型并适配一下测试数据。

    # Create a model and fit it
    model = LinearRegression().fit(x, y)
    # Get results
    r_sq = model.score(x, y)
    print('coefficient of determination:', r_sq)
    print('intercept:', model.intercept_)
    print('slope:', model.coef_)

3.预测旧数据和新数据。

    # Predict response
    y_pred = model.predict(x)
    print('predicted response:', y_pred, sep='\n')

    # Predict new data
    x_new = [list([random.randint(0, 100), random.randint(0, 100), random.randint(0, 100)]) for item in range(10, 16)]
    print('x_new:', x_new, sep='\n')
    y_new = model.predict(x_new)
    print('predicted new:', y_new, sep='\n')

三、多项式回归。

现实世界的情况嘛,毕竟复杂。不是说一件事情,就受一个因素影响(如f(x)=b0 + b1*x1)。很多情况,也不是说受多个因素以权重的方式来影响(f(x) = b0 + b1 * x1 + b2 * x2 – b3 * x3)。也可能是指数的方式来影响,比如: f(x) = (x1 + x2) (x1 + x2),注意这里的(x1 + x2),它是以指数2(即平方)的方式来影响最终结果。

多项回归就是为了解决这种情况。这里只模拟一下平方的情况,立方或高次方的情况,略过。

1.创建模拟数据。

    # Polynomial Regression With scikit-learn
    # Combinations of polynomial:
    # [a] combinations of a square polynomial: [1, a, a*a]
    # [a, b] combinations of a square polynomial: [1, a, b, a*a, ab, b*b]

    # for given equation: y = 3 - (5 * a) + (6 * b) + 4 * (a * a) - 7 * a * b + 2 * (b * b),
    # create a dataset for input(a, b) and output(y)
    y = []
    x = []
    for i in range(0, 6):
        random.seed(i ^ 3 - 35)
        a = random.randint(-100, 100)
        random.seed(i ^ 2 + 67)
        b = random.randint(-100, 100)
        x.append(list([a, b]))
        value = 3 - (5 * a) + (6 * b) + 4 * (a * a) - 7 * a * b + 2 * (b * b)
        y.append(value)
    print("[a] for equation: y = 3 - (5 * a) + (6 * b) + 4 * (a * a) - 7 * a * b + 2 * (b * b):")
    print(x)
    print("y for equation: y = 3 - (5 * a) + (6 * b) + 4 * (a * a) - 7 * a * b + 2 * (b * b):")
    print(y)

2.转换一下测试数据。注意这个参数degree=2,意思就是指数是2的情况。

为什么要转换呢?因为多项式回归最终还是以多元线性回归的方式来实现。

比方说,对于只有一个自变量x但指数是2的情况,那么它的多项式组合就是:b0 + b1 * x + x * x。那么,我们输入一行一列x(比如说:[[3]]),经转换后就变成了一行三列(形如:[[b0, b1*3, 9]])。从形式上可以看出,最终的结果f(x)就会像多元回归那样分别受b0, b1*3, 9的影响,我们要做的就是求出b0和b1,看它们最终分别是以多大的权重来影响f(x)的即可。

同理,对于有两个自变量x1,x2指数是2的情况,那么它的多项式组合就是:b0 + (b1 * x1) + (b2 * x2) + b3 * (x1 * x1) + b4 * x1 * x2 + b5 * (x2 * x2)。如果我们输入一行两列数据x(比如说:[[2,3]]),经转换后变成了一行六列(形如:[[b0, b1 * 2, b2 * 3, b3 * 2 * 2, b4 * 2 * 3, b5 * 3 * 3]])。从形式上可以看出,最终结果fx(x)也会像多元回归那样分别受 b0, b1 * 2, b2 * 3, b3 * 2 * 2, b4 * 2 * 3, b5 * 3 * 3 的影响,我们要做的就是求出b0, b1, b2, b3, b4, b5, 看它们最终分别是以多大的权重来影响f(x)的即可。

其整体思路就是:通过降次来进行多项式的展开,然后使用多元回归求得展开后多项式的多个权重,来实现回归分析。

更多个变量的更高级指数的回归分析,原理相同,此处略过。

    # Transform input data
    x_ = PolynomialFeatures(degree=2).fit_transform(x)
    print("transform result for x:")
    print(x_)

3.创建线性回归模型并适配转换后的数据。

    # Create a model and fit it
    model = LinearRegression(fit_intercept=False).fit(x_, y)
    # Get results
    r_sq = model.score(x_, y)
    print('coefficient of determination:', r_sq)
    print('intercept:', model.intercept_)
    print('equation: y = 3 - (5 * a) + (6 * b) + 4 * (a * a) - 7 * a * b + 2 * (b * b)')
    print("expected slope:[3, -5, 6, 4, -7, 2]")
    print('slope:', model.coef_)

4.预测旧数据和新数据。

    # Predict response
    print('predicted [[28, 47]]:')
    print('expected:{}'.format(3 - (5 * 28) + (6 * 47) + 4 * (28 * 28) - 7 * 28 * 47 + 2 * (47 * 47)))
    x = [[28, 47]]
    x_ = PolynomialFeatures(degree=2).fit_transform(x)
    y_pred = model.predict(x_)
    print('predicted result:', y_pred, sep='\n')

当然,现实的情况,远不止像上面讲的那么简单。这里仅仅记录一下线性回归的原理和使用python来进行线性回归的方法。算是对了解更深层次的逻辑回归、机器学习、神经网络甚至于深度学习的一个基础吧。

参考:

1.https://zh.wikipedia.org/wiki/%E8%BF%B4%E6%AD%B8%E5%88%86%E6%9E%90
2.https://zh.wikipedia.org/wiki/%E7%B7%9A%E6%80%A7%E5%9B%9E%E6%AD%B8
3.https://realpython.com/linear-regression-in-python/

源代码:

1.https://github.com/bumblezhou/python_machine_learning/blob/master/linear_regression.py

One thought on “使用python实现简单的线性回归

发表评论

电子邮件地址不会被公开。 必填项已用*标注