机器学习 基于线性回归预测鲍鱼年龄 AHU实验

本文适用于该题目的实验报告

1.实验内容

本实验通过运用线性回归方法预测鲍鱼年龄。

2.实验目标

通过本实验掌握并实现基于线性回归方法预测鲍鱼年龄。

3.实验知识点

  • 线性回归

4.实验环境

  • python 3.6.5

5.预备知识

  • Python编程基础

代码部分

导入数据

计算回归系数

局部加权线性回归

测试函数

代码部分


导入数据

#导入实验需要的库numpy、matplotlib.pyplot
#!/usr/bin/env python
#-*- coding:utf-8 -*-
from numpy import *
import matplotlib.pyplot as plt

         from numpy import * 将 numpy 库中的所有内容导入到当前项目中,调用里面的函数xxx时候,是可以直接写xxx(),而import numpy as np前面要加np.xxx()

打开一个用tab键分隔的文本文件
parameters:
    fileName -文件名
return:
    dataMat -数据矩阵
    labelMat -目标值向量

def loadDataSet(fileName): 
    
    #得到列数,不包括最后一列,默认最后一列值为目标值(标签label)
    numFeat = len(open(fileName).readline().split('\t')) - 1 
    #定义初始数据集
    dataMat = []; labelMat = []
    #读取文件内容
    fr = open(fileName)
    #构造数据集
    
    for line in fr.readlines():
        lineArr =[]
        curLine = line.strip().split('\t')
        for i in range(numFeat):
            lineArr.append(float(curLine[i]))
        dataMat.append(lineArr)
        labelMat.append(float(curLine[-1]))

    return dataMat,labelMat


  • 计算回归系数

        多元线性回归模型的普通最小二乘参数估计量为:

机器学习 基于线性回归预测鲍鱼年龄 AHU实验_第1张图片

        计算最佳拟合直线,通过给定的参数x、y。来计算最佳的w值,代码实现最小二乘法。

def standRegres(xArr,yArr):
    xMat = np.mat(xArr); yMat = np.mat(yArr).T
    xTx = xMat.T * xMat                            
    if np.linalg.det(xTx) == 0.0:
        print("矩阵为奇异矩阵,不能求逆")
        return
    ws = xTx.I * (xMat.T*yMat)            #根据文中推导的公示计算回归系数
    return ws
  • 局部加权线性回归

计算回归系数
parameters:
    testPoint -待预测数据
    xArr -给定输入值
    yArr -给定输出值
    k -高斯核的k值,决定对附近的点赋予多大的权重
return:
    testPoint * ws -回归系数的估计值
        为了避免线性回归出现欠拟合的现象,多元线性回归结果是一个高维的超平面,我们在预测时想要这个超平面有一些凹凸,来解决欠拟合的问题(类比一元,拟合结果是一条直直的线,我们想避免预测结果过于“一刀切”,让他局部弯曲一点),局部加权回归允许在估计中引入一 些偏差,从而降低预测的均方误差。

        给定了高斯核k,利用它,我们给待预测点附近的每个点赋予一定的权重K。

        此时的损失函数是:

机器学习 基于线性回归预测鲍鱼年龄 AHU实验_第2张图片

         写成矩阵形式就是:

         求解回归系数矩阵:

         高斯核函数,形式如下:

机器学习 基于线性回归预测鲍鱼年龄 AHU实验_第3张图片

        代码: 

def lwlr(testPoint, xArr, yArr, k=1.0):
    
    ### Start Code Here ###
    xMat = np.mat(xArr); yMat = np.mat(yArr).T
    m = np.shape(xMat)[0]
    weights = np.mat(np.eye((m)))                                        #创建权重对角矩阵
    for j in range(m):                                                  #遍历数据集计算每个样本的权重
        diffMat = testPoint - xMat[j, :]                                 
        weights[j, j] = np.exp(diffMat * diffMat.T/(-2.0 * k**2))
    xTx = xMat.T * (weights * xMat)                                        
    if np.linalg.det(xTx) == 0.0:
        print("矩阵为奇异矩阵,不能求逆")
        return
    ws = xTx.I * (xMat.T * (weights * yMat)) 
    ### End Code Here ###
    
    return testPoint*ws
  • 测试函数

"""
测试函数
parameters:
    testArr -测试数据集
    xArr -给定输入值
    yArr -给定输出值
    k -高斯核的k值
return:
    yHat -预测值
"""
def lwlrTest(testArr, xArr, yArr,k=1.0):
    m = shape(xArr)[0]
    yHat = zeros(m)
    for i in range(m):
        yHat[i] = lwlr(testArr[i],xArr,yArr,k)
    return yHat
"""
计算预测误差的平方和
parameters:
    yArr -给定y值
    yHatArr -预测y值
return:
    ((yArr-yHatArr)**2).sum() -误差矩阵
"""
def rssError(yArr,yHatArr):
    return ((yArr-yHatArr)**2).sum()
if __name__=='__main__':
    abX,abY = loadDataSet('linear_regression_abalone/abalone.txt') #根据自己文件地址改
    yHat01 = lwlrTest(abX[0:99],abX[0:99],abY[0:99],0.1)
    yHat1 = lwlrTest(abX[0:99],abX[0:99],abY[0:99],1)
    yHat10 = lwlrTest(abX[0:99],abX[0:99],abY[0:99],10)
    print("使用局部加权线性回归预测误差:")
    print("核为0.1时:",rssError(abY[0:99],yHat01.T))
    print("核为1时:",rssError(abY[0:99],yHat1.T))
    print("核为10时:",rssError(abY[0:99],yHat10.T))
    yHat01 = lwlrTest(abX[100:199],abX[0:99],abY[0:99],0.1)
    yHat1 = lwlrTest(abX[100:199],abX[0:99],abY[0:99],1)
    yHat10 = lwlrTest(abX[100:199],abX[0:99],abY[0:99],10)
    print("使用局部加权线性回归预测误差在新数据上的表现:")
    print("核为0.1时:",rssError(abY[100:199],yHat01.T))
    print("核为1时:",rssError(abY[100:199],yHat1.T))
    print("核为10时:",rssError(abY[100:199],yHat10.T))
    ws = standRegres(abX[0:99],abY[0:99])
    yHat = mat(abX[100:199])*ws
    print("使用标准线性回归预测误差为:",rssError(abY[100:199],yHat.T.A))
使用局部加权线性回归预测误差:
核为0.1时: 56.78868743048742
核为1时: 429.8905618704059
核为10时: 549.1181708828803
使用局部加权线性回归预测误差在新数据上的表现:
核为0.1时: 57913.51550155909
核为1时: 573.5261441894984
核为10时: 517.5711905381573
使用标准线性回归预测误差为: 518.6363153245542

        可以看到,当k=0.1时,训练集误差小,但是应用于新的数据集之后,误差反而变大了。这就是经常说道的过拟合现象。我们训练的模型,我们要保证测试集准确率高,这样训练出的模型才可以应用于新的数据,也就是要加强模型的普适性。可以看到,当k=1时,局部加权线性回归和简单的线性回归得到的效果差不多。这也表明一点,必须在未知数据上比较效果才能选取到最佳模型。那么最佳的核大小是10吗?或许是,但如果想得到更好的效果,应该用10个不同的样本集做10次测试来比较结果。

        本次实验展示了如何使用局部加权线性回归来构建模型,可以得到比普通线性回归更好的效果。局部加权线性回归的问题在于,每次必须在整个数据集上运行。也就是说为了做出预测,必须保存所有的训练数据。

参考:

本校cg平台提示代码与下文链接极其相似Python3《机器学习实战》学习笔记(十一):线性回归基础篇之预测鲍鱼年龄_线性回归 jack 崔_Jack-Cui的博客-CSDN博客

尚在学习,如有新理解将会更新。

你可能感兴趣的:(机器学习,线性回归,python)