美文网首页
机器学习算法——多元线性回归

机器学习算法——多元线性回归

作者: 猛犸象和剑齿虎 | 来源:发表于2022-12-24 14:54 被阅读0次

    数据来源合鲸社区-工业产生的蒸汽量预测

    1.1 背景描述

    针对当前中央提出碳中和策略,我们提取其中部分关键信息,得知火力发电的基本原理是:燃料在燃烧时加热水生成蒸汽,蒸汽压力推动汽轮机旋转,然后汽轮机带动发电机旋转,产生电能。在这一系列的能量转化中,影响发电效率的核心是锅炉的燃烧效率,即燃料燃烧加热水产生高温高压蒸汽。锅炉的燃烧效率的影响因素很多,包括锅炉的可调参数,如燃烧给量,一二次风,引风,返料风,给水水量;以及锅炉的工况,比如锅炉床温、床压,炉膛温度、压力,过热器的温度等。

    经脱敏后的锅炉传感器采集的数据(采集频率是分钟级别),根据锅炉的工况,预测产生的蒸汽量。

    环境要求:飞桨 PaddlePaddle 2.2 及以上版本

    数据说明 数据分成训练数据(train.txt)和测试数据(test.txt),其中字段”V0”-“V37”,这38个字段是作为特征变量,”target”作为目标变量。选手利用训练数据训练出模型,预测测试数据的目标变量,排名结果依据预测结果的MSE(mean square error)。

    模型选择

    根据特征变量预测目标变量归类为机器学习中有监督学习回归问题。

    1.3 源数据解析

    求解回归问题有两种方案: 第一种是用矩阵直接求出w的值,然后做预测就行,但是前提是矩阵不能是奇异矩阵。 第二种是采用梯度下降法求出w和b的局部最优解。

    1.3.1 首先采用第一种方案-矩阵法

    获取数据

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    df=pd.read_csv("zhengqi_train.txt",sep='\t')
    df
    
    image.png
    训练集数据由38个特征值和1个目标值构成,首先要做的是将特征值和目标值分开。矩阵运算有个公式: image.png

    我们用这个构造一个求w的函数。

    def standRegres(df):
        xMat = np.mat(df.iloc[:,:-1].values) # 提取特征
        yMat = np.mat(df.iloc[:,-1].values).T # 提取标签
        xTx = xMat.T*xMat
        if np.linalg.det(xTx) ==0:
            print('这是个奇异矩阵,不能求解逆矩阵') #行列式为0,则该矩阵为奇异矩阵,无法求解逆矩阵
        return
        w = xTx.I * (xMat.T*yMat)
        return w
    

    这里需要提前判断xTx是否是满秩矩阵。若不满秩,则无法对其进行求逆矩阵的操作。定义完函数后,即可测试运行效果。这里需要注意的是,当使用矩阵分解来求解多元线性回归时,必须添加一列全为1的列,用于表征线性方程截距。

    测试一下

    ex = pd.DataFrame(np.ones([df.shape[0],1]))
    ex
    X=df.iloc[:,:-1]
    
    Y=df.iloc[:,-1]
    
    df = pd.concat([ex,X,Y],axis=1)
    ws = standRegres(df)
    
    这是个奇异矩阵,不能求解逆矩阵
    

    由于得出的是奇异矩阵,说明想通过简单的线性代数求解是不行的,只能采用梯度下降的方法来做。

    第二种方法:梯度下降法

    原始线性方程

    f_{\mathbf{w},b}(\mathbf{x}) = w_0x_0 + w_1x_1 +... + w_{n-1}x_{n-1} + b \tag{1}
    f_{\mathbf{w},b}(\mathbf{x}) = \mathbf{w} \cdot \mathbf{x} + b \tag{2}

    向量点乘公式python函数

    def predict(x, w, b): 
        p = np.dot(x, w) + b     
        return p 
    

    多元线性回归的损失函数

    J(\mathbf{w},b) = \frac{1}{2m} \sum\limits_{i = 0}^{m-1} (f_{\mathbf{w},b}(\mathbf{x}^{(i)}) - y^{(i)})^2 \tag{3}

    f_{\mathbf{w},b}(\mathbf{x}^{(i)}) = \mathbf{w} \cdot \mathbf{x}^{(i)} + b \tag{4}

    def compute_cost(X, y, w, b): 
        m = X.shape[0]
        cost = 0.0
        for i in range(m):                                
            f_wb_i = np.dot(X[i], w) + b           
            cost = cost + (f_wb_i - y[i])**2       
        cost = cost / (2 * m)                         
        return cost
    

    多元梯度下降原理公式

    \begin{align*} \text{repeat}&\text{ until convergence:} \; \lbrace \newline\; & w_j = w_j - \alpha \frac{\partial J(\mathbf{w},b)}{\partial w_j} \tag{5} \; & \text{for j = 0..n-1}\newline &b\ \ = b - \alpha \frac{\partial J(\mathbf{w},b)}{\partial b} \newline \rbrace \end{align*}

    \begin{align} \frac{\partial J(\mathbf{w},b)}{\partial w_j} &= \frac{1}{m} \sum\limits_{i = 0}^{m-1} (f_{\mathbf{w},b}(\mathbf{x}^{(i)}) - y^{(i)})x_{j}^{(i)} \tag{6} \\ \frac{\partial J(\mathbf{w},b)}{\partial b} &= \frac{1}{m} \sum\limits_{i = 0}^{m-1} (f_{\mathbf{w},b}(\mathbf{x}^{(i)}) - y^{(i)}) \tag{7} \end{align}

    梯度函数

    def compute_gradient(X, y, w, b): 
        """
        Computes the gradient for linear regression 
        Args:
          X (ndarray (m,n)): Data, m examples with n features
          y (ndarray (m,)) : target values
          w (ndarray (n,)) : model parameters  
          b (scalar)       : model parameter
          
        Returns:
          dj_dw (ndarray (n,)): The gradient of the cost w.r.t. the parameters w. 
          dj_db (scalar):       The gradient of the cost w.r.t. the parameter b. 
        """
        m,n = X.shape           #(number of examples, number of features)
        dj_dw = np.zeros((n,))
        dj_db = 0.
    
        for i in range(m):                             
            err = (np.dot(X[i], w) + b) - y[i]   
            for j in range(n):                         
                dj_dw[j] = dj_dw[j] + err * X[i, j]    
            dj_db = dj_db + err                        
        dj_dw = dj_dw / m                                
        dj_db = dj_db / m                                
            
        return dj_db, dj_dw
    

    梯度下降函数

    def gradient_descent(X, y, w_in, b_in, cost_function, gradient_function, alpha, num_iters): 
        """
        Performs batch gradient descent to learn theta. Updates theta by taking 
        num_iters gradient steps with learning rate alpha
        
        Args:
          X (ndarray (m,n))   : Data, m examples with n features
          y (ndarray (m,))    : target values
          w_in (ndarray (n,)) : initial model parameters  
          b_in (scalar)       : initial model parameter
          cost_function       : function to compute cost
          gradient_function   : function to compute the gradient
          alpha (float)       : Learning rate
          num_iters (int)     : number of iterations to run gradient descent
          
        Returns:
          w (ndarray (n,)) : Updated values of parameters 
          b (scalar)       : Updated value of parameter 
          """
        
        # An array to store cost J and w's at each iteration primarily for graphing later
        J_history = []
        w = copy.deepcopy(w_in)  #avoid modifying global w within function
        b = b_in
        
        for i in range(num_iters):
    
            # Calculate the gradient and update the parameters
            dj_db,dj_dw = gradient_function(X, y, w, b)   ##None
    
            # Update Parameters using w, b, alpha and gradient
            w = w - alpha * dj_dw               ##None
            b = b - alpha * dj_db               ##None
          
            # Save cost J at each iteration
            if i<100000:      # prevent resource exhaustion 
                J_history.append( cost_function(X, y, w, b))
    
            # Print cost every at intervals 10 times or as many iterations if < 10
            if i% math.ceil(num_iters / 10) == 0:
                print(f"Iteration {i:4d}: Cost {J_history[-1]:8.2f}   ")
            
        return w, b, J_history #return final w,b and J history for graphing
    

    导入我们的训练集得出训练参数w和b

    import copy, math
    
    df1=pd.read_csv("zhengqi_train.txt",sep='\t')
    w_init=np.array(Y)
    X_train=np.array(df1.iloc[:,:-1]).T
    y_train=np.array(df1.iloc[:,-1])
    df1
    # initialize parameters
    initial_w = np.zeros_like(w_init)
    
    initial_b = 0.
    # some gradient descent settings
    iterations = 1000
    alpha = 5.0e-7
    # run gradient descent 
    w_final, b_final, J_hist = gradient_descent(X_train, y_train, initial_w, initial_b,
                                                        compute_cost, compute_gradient, 
                                                        alpha, iterations)
    print(f"b,w found by gradient descent: {b_final:0.2f},{w_final} ")
    m,_ = X_train.shape
    for i in range(m):
        print(f"prediction: {np.dot(X_train[i], w_final) + b_final:0.2f}, target value: {y_train[i]}")
    
    image.png

    通过sklearn库实现

    通过sklearn库还是比较方便的,前面的部分都是理解算法过程的,实际编写代码还是通过库比较方便。

    from sklearn.linear_model import LinearRegression
    reg = LinearRegression()
    reg.fit(df1.iloc[:,:-1].values,df1.iloc[:,-1].values)
    print(reg.coef_) # 查看系数
    reg.intercept_ # 查看截距
    
    image.png

    通过判定系数来查看下模型是否准确

    ####判定系数
    from sklearn.metrics import mean_squared_error,r2_score
    yhat = reg.predict(df1.iloc[:,:-1])
    yhat
    y = df1.iloc[:,-1].values
    mean_squared_error(y,yhat)
    r2_score(y,yhat)
    
    image.png

    0.889的判定系数还算可以。

    最后一步:将测试集放入模型输出预测结果

    通过计算好的w和b值将测试集的数据进行拟合得出结果

    df2=pd.read_csv("zhengqi_test.txt",sep='\t')
    df2
    reg.coef_
    df2['prdit']=np.dot(df2,reg.coef_)+reg.intercept_
    df2
    
    image.png

    不管是简单的线性回归或者是多元线性回归对拟合的数据都不是特别的优秀,原因是数据可能是非线性关系,或者可以通过2次或者多次方程拟合更为优秀的模型,但是线性回归是基础。

    相关文章

      网友评论

          本文标题:机器学习算法——多元线性回归

          本文链接:https://www.haomeiwen.com/subject/pimbqdtx.html