最小二乘法线性回归预测-Python3实现

2016年7月1日 6814点热度 0人点赞 0条评论

回归(regression)是监督学习的一个重要问题,回归问题用于预测输入变量(自变量)和输出变量(因变量)之间的关系,特别是当输入变量的值发生变化时,输出变量的值随之发生变化,回归模型正是表示输入变量到输出变量之间映射的函数,回归问题的学习等价于函数拟合;选择一条函数曲线使其很好地拟合已知数据且很好地预测未知数据。

按照输入变量与输出变量之间的关系的类型即模型的类型,回归问题分为线性回归和非线性回归。

回归问题最常用的损失函数是平方损失函数,再次情况下可以由著名的最小二乘法求解。

 

 

好,装逼结束。我要开始乱讲啦。事情是这样的,老师给我扔了些数据,让我做预测。我想好呀,matlab直接上工具箱或者svm,实在不行knn呀简单粗暴。然而,我发现之前看过的资料都是做分类的,并没有用svm做预测的。然后,我就翻看李航的《统计学习方法》默默找模型。然后发现最小二乘法很不错呀,虽然高中就学过,但是中学时期的数据也就只是f(x)这样的一维数据,拟合一条直线出来就没事了。matlab的cftool拟合工具箱也可以做各种各样的拟合,但是我作为一个亲自动手码算法强迫症怎么会懒到用工具箱做出来交给老师呢?(老师也不然让我用工具箱,不然怎么会用最小二乘法。此处拟合一个我的笑脸)。你会在我的代码里看到knn几个字,没错!我想用KNN,然而失败了。真心搞不懂k-邻近值分类怎么能用到预测里?

有人说:

  • k-NN分类中,输出是一个分类族群。一个对象的分类是由其邻居的“多数表决”确定的,k个最近邻居(k为正整数,通常较小)中最常见的分类决定了赋予该对象的类别。若k = 1,则该对象的类别直接由最近的一个节点赋予。
  • k-NN回归中,输出是该对象的属性值。该值是其k个最近邻居的值的平均值。

什么叫k个最近邻居的平均值?我的预测标签和训练集一样大,真心不明白。

 

废话不多说,上数据:

给出以下数据:
日期,位移(mm),温度,湿度(%)
2013/6/1,9.319,22.882,63.516 2013/7/3,9.597,26.262,79.749
2013/6/2,9.374,24.598,62.489 2013/7/4,9.642,25.042,77.529
2013/6/3,9.456,25.182,63.518 2013/7/5,9.643,27.551,72.947
2013/6/4,9.224,27.625,57.256 2013/7/6,9.642,28.211,79.359
2013/6/5,9.098,27.005,56.958 2013/7/2,9.612,28.066,74.861
2013/6/6,9.107,25.808,67.088
2013/6/7,9.137,25.901,62.231
2013/6/8,9.368,24.905,69.855
2013/6/9,9.316,17.14,95.853
2013/6/10,9.413,19.718,71.593
2013/6/11,9.3,20.215,63.575
2013/6/12,9.353,22.769,60.76
2013/6/13,9.492,26.853,52.631
2013/6/14,9.486,25.992,57.511
2013/6/15,9.669,28.488,56.896
2013/6/16,9.509,27.631,63.434
2013/6/17,9.513,29.869,63.099
2013/6/18,9.613,31.942,61.866
2013/6/19,9.501,28.516,68.947
2013/6/20,9.552,26.097,68.83
2013/6/21,9.463,23.075,82.208
2013/6/22,9.321,25.54,75.847
2013/6/23,9.348,26.923,67.275
2013/6/24,9.354,25.169,77.016
2013/6/25,9.375,30.376,70.021
2013/6/26,9.468,26.277,87.107
2013/6/27,9.587,29.091,79.367
2013/6/28,9.659,25.13,92.252
2013/6/29,9.53,29.263,72.26
2013/6/30,9.547,29.406,72.443
2013/7/1,9.531,30.466,69.295
2013/7/2,9.612,28.066,74.861对该样本数据做出预测模型

可也以下载data.csv

Python3.5环境

用到的库

matplotlib

全部代码

# coding: utf-8
from math import exp

__name__ = '__main__'
from numpy import *
import operator
import csv
import matplotlib.pyplot as plt
from functools import reduce
import mpl_toolkits.mplot3d


class ds:
    def getrawdata(self):
        self.timelist = []
        self.displace = []
        self.temperaturelist = []
        self.humiditylit = []
        with open('data.csv', 'rt') as f:
            reader = csv.reader(f)
            for row in reader:
                print(row)
                self.timelist.append(row[0])
                self.displace.append(row[1])
                self.temperaturelist.append(row[2])
                self.humiditylit.append(row[3])
        f.close()

        self.timelabel = str(self.timelist[0])
        self.displable = str(self.displace[0])
        self.temperlabel = str(self.temperaturelist[0])
        self.humidlabel = str(self.humiditylit[0])

        del self.timelist[0:2]
        del self.displace[0:2]
        del self.temperaturelist[0:2]
        del self.humiditylit[0:2]

        self.timelist = list(map(str, self.timelist))
        self.temperaturelist = list(map(float, self.temperaturelist))
        self.displace = list(map(float, self.displace))
        self.humiditylit = list(map(float, self.humiditylit))

        print(self.timelist)
        print(self.displace)
        print(self.temperaturelist)
        print(self.humiditylit)

        return self.timelist, self.displace, self.temperaturelist, self.humiditylit

    def showpic(self):
        #3d示图展示
        ax = plt.subplot(231, projection='3d')
        ax.scatter(self.temperaturelist[:], self.humiditylit[:], self.displace[:], c='y') #绘制数据点
        ax.set_xlabel('temperlabel')
        ax.set_ylabel('humidlabel')
        ax.set_zlabel('displable')
        #3d示图展示

        #2维可视化
        plt.subplot(232)
        plt.plot(self.temperaturelist, self.displace, '*')
        plt.subplot(233)
        plt.plot(self.humiditylit, self.displace, '*')
        plt.subplot(234)
        plt.plot(range(36), self.displace)
        plt.subplot(235)
        plt.plot(range(36), self.temperaturelist)
        plt.subplot(236)
        plt.plot(range(36), self.humiditylit)
        plt.show()
        #2维可视化
        #v = list(map(lambda x: x[0]-x[1], zip(humiditylit, temperaturelist)))
        #plt.subplot(111)
        #plt.plot(range(36), v)
        #plt.show()

class knn:
    def createDataSet(self):
        group = array([[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 0.1]])
        labels = ['A', 'A', 'B', 'B']
        return group, labels

    def classify0(inX, dataSet, labels, k):
        dataSetSize = dataSet.shape[0]
        diffMat = tile(inX, (dataSetSize, 1)) - dataSet  #样本与训练集的差值矩阵
        sqDiffMat = diffMat**2  #差值矩阵平方
        sqDistances = sum(sqDiffMat, axis=1)  #每行和
        distances = sqDistances**0.5  #欧拉距离
        sortedDistIndicies = argsort(distances)   #排序后的下标数组
        #选择距离最小的点
        classCount = {}
        for i in range(k):
            voteIlabel = labels[sortedDistIndicies[i]]  #投票啦
            classCount[voteIlabel] = classCount.get(voteIlabel, 0)+1
        sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
        return sortedClassCount[0][0]

class regression:
    def loadDataSet(fileName):   #general function to parse tab -delimited floats
        numFeat = len(open(fileName).readline().split('\t')) - 1   #get number of fields
        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

    def standRegres(self, xarr, yarr):
        xMat = mat(xarr)
        yMat = mat(yarr).T
        xTx = xMat.T*xMat
        if linalg.det(xTx) == 0.0:
            print("This matrix is singular, cannot do inverse")
            return
        ws = xTx.I * (xMat.T*yMat)
        return ws

#测试
if __name__ == '__main__':
    k_alg = knn()
    rawdata = ds()
    timelist, displace, temperaturelist, humiditylit = rawdata.getrawdata()
    rawdata.showpic()
    v = list(map(lambda x: [x[0], x[1]], zip(humiditylit, temperaturelist)))  #X矩阵
    print(v)

    re = regression()
    w = re.standRegres(v, displace)  #回归系数矩阵
    print("回归系数1", w[0], "回归系数2",  w[1])

    vcopy = v.copy()
    #vcopy.sort()

    displacecopy = vcopy*w   #排序后的预测值
    x1 = list(map(lambda x: x[1], vcopy))  #温度
    x2 = list(map(lambda x: x[0], vcopy))  #湿度

    emp = average(list(map(lambda x: (x[0]-x[1]), zip(displacecopy, displace)))) #经验误差
    print("EMP is", emp)

    tem = float(input("请输入温度值:"))
    hum = float(input("请输入湿度值:"))
    test = [tem, hum]
    print("位移值可能为:", int(test*w))

你会看到这样一幅图:

QQ截图20160701212315

然后预个测:

QQ截图20160701212427

就酱~

 

南国羽

I am a master student of computer science at Uppsala University in Sweden. Computer vision and machine learning are my research interests. I am looking for a Ph.D. position.

文章评论