回归(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))
你会看到这样一幅图:
然后预个测:
就酱~
文章评论