线性回归算法

1.简单线性回归
在回归分析中,只包括一个自变量和一个因变量,且二者的关系可用一条直线近似表示,这种回归分析称为一元线性回归分析;简单线性回归是属于回归(regression),即label为连续数值型,即用一条直线,最大程度的拟合样本特征和样本数据标记之间的关系
建模过程,就是找到一个模型,最大程度的拟合我们的数据,最大的拟合数据,本质上就是找到没有拟合的部分,也就是损失的部分尽量小,就是损失函数(loss function)(也有算法是衡量拟合的程度,称函数为效用函数。
对于简单线性回归而言,就是损失函数就是使误差平方和最小,可以适用最小二乘法求出。

2.损失函数
损失函数描述了单个样本预测值和真实值之间误差的程度,用来度量模型一次预测的好坏。

常用损失函数有:
a.0-1损失函数:用来表述分类问题,当预测分类错误时,损失函数值为1,正确为0;
b.平方损失函数:用来描述回归问题,用来表示连续性变量,为预测值与真实值差值的平方;
c.绝对损失函数:用在回归模型,用距离的绝对值来衡量;
d.对数损失函数:是预测值Y和条件概率之间的衡量,此损失函数用到了极大似然估计的思想;

3.用代码实现简单线性回归

#构造数据,画图
import numpy as np
import matplotlib.pyplot as plt

x = np.array([1.,2.,3.,4.,5.])
y = np.array([1.,3.,2.,3.,5,])

plt.scatter(x,y)
plt.axis([0,6,0,6])
plt.show()

对于简单的线性回归方程,用代码计算a,b

# 首先要计算x和y的均值
x_mean = np.mean(x)
y_mean = np.mean(y)

# a的分子num、分母d
num = 0.0
d = 0.0
for x_i,y_i in zip(x,y):   # zip函数打包成[(x_i,y_i)...]的形式
    num = num + (x_i - x_mean) * (y_i - y_mean)
    d = d + (x_i - x_mean) ** 2
a = num / d
b = y_mean - a * x_mean


#在求出a、b之后,可以计算出y的预测值,首先绘制模型直线

y_hat = a * x + b
plt.scatter(x,y)    # 绘制散点图
plt.plot(x,y_hat,color='r')    # 绘制直线
plt.axis([0,6,0,6])
plt.show()

#预测

x_predict = 6
y_predict = a * x_predict + b
print(y_predict)

在计算参数a时:发现有这样一个步骤:向量w和向量v,每个向量的对应项,相乘再相加。其实这就是两个向量“点乘”
可以使用numpy中的dot运算,非常快速地进行向量化运算

#对于 y = wx + b,  若 w, x都是向量,那么,可以用两种方式来计算,第一是for循环:

y = 0
for i in range(n):
    y += w[i]*x[i]
    y += b

另一种方法就是用向量化的方式实现:
y = np.dot(w,x) + b

向量化是非常常用的加速计算的方式

3.多元线性回归
在回归分析中,如果回归分析中包括两个或两个以上的自变量,且因变量和自变量之间是线性关系,则称为多元线性回归分析。
“一类机器学习的建模推导思想:通过分析问题,确定问题的损失函数或者效用函数,然后通过最优化损失函数或者效用函数,获得机器学习的模型。”

代码实现:

import numpy as np
from .metrics import r2_score

class LinearRegression:

def __init__(self):
        """初始化Linear Regression模型"""
        self.coef_ = None    # 系数(theta0~1 向量)
        self.interception_ = None   # 截距(theta0 数)
        self._theta = None  # 整体计算出的向量theta

    def fit_normal(self, X_train, y_train):
        """根据训练数据X_train,y_train训练Linear Regression模型"""
        assert X_train.shape[0] == y_train.shape[0], \
            "the size of X_train must be equal to the size of y_train"
        # 正规化方程求解
        X_b = np.hstack([np.ones((len(X_train), 1)), X_train])
        self._theta = np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y_train)

        self.interception_ = self._theta[0]
        self.coef_ = self._theta[1:]
        return self

    def predict(self, X_predict):
        """给定待预测的数据集X_predict,返回表示X_predict的结果向量"""
        assert self.interception_ is not None and self.coef_ is not None, \
            "must fit before predict"
        assert X_predict.shape[1] == len(self.coef_), \
            "the feature number of X_predict must be equal to X_train"
        X_b = np.hstack([np.ones((len(X_predict), 1)), X_predict])
        y_predict = X_b.dot(self._theta)
        return y_predict

    def score(self, X_test, y_test):
        """很倔测试机X_test和y_test确定当前模型的准确率"""
        y_predict = self.predict(self, X_test)
        return r2_score(y_test, y_predict)
    
    def __repr__(self):
        return "LinearRegression()"

备注:
a.np.hstack(tup):参数tup可以是元组,列表,或者numpy数组,返回结果为numpy的数组。按列顺序把数组给堆叠起来;
b.np.ones():返回一个全1的n维数组,有三个参数:shape(用来指定返回数组的大小)、dtype(数组元素的类型)、order(是否以内存中的C或Fortran连续(行或列)顺序存储多维数据)。后两个参数都是可选的,一般只需设定第一个参数。(类似的还有np.zeros()返回一个全0数组);
c.numpy.linalg模块包含线性代数的函数。使用这个模块,可以计算逆矩阵、求特征值、解线性方程组以及求解行列式等。inv函数计算逆矩阵;
d.T:array的方法,对矩阵进行转置;dot:点乘.

直接调用代码:

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets

boston = datasets.load_boston()

X = boston.data
y = boston.target

X = X[y<50.0]
y = y[y<50.0]

X.shape
y.shape

from myAlgorithm.model_selection import train_test_split
from myAlgorithm.LinearRegression import LinearRegression

X_train, X_test, y_train, y_test = train_test_split(X, y, seed = 666)

reg = LinearRegression()
reg.fit_normal(X_train, y_train)

reg.coef_
reg.interception_
reg.score(X_test, y_test)

参考:
https://mp.weixin.qq.com/s/gJU4oJufOFNF_I3MO7gYlA
https://mp.weixin.qq.com/s/siFRKWLhGOGJCCMjzB7R7A

你可能感兴趣的:(机器学习)