正剧开始:
星历2016年04月12日 16:00:33, 银河系厄尔斯星球中华帝国江南行省。
[工程师阿伟]正在和[机器小伟]一起研究[统计]。
小伟想了一下,做了这样一个取随机样本的工具:
<span style="font-size:18px;">>>> ================================ RESTART ================================ >>> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] [10, 1, 9] >>> ================================ RESTART ================================ >>> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] [5, 4, 8] #从N个样本中抽取n个样本 def sample(N, n): a = list(range(1, N+1)); print(a); random.shuffle(a); return a[0:n]; if __name__ == '__main__': print(sample(10, 3));</span>
<span style="font-size:18px;"> if (1) { var config = new PlotConfiguration(); config.init(); config.setPreference(); var r = 20; //config.setSector(1,1,1,1); //config.graphPaper2D(0, 0, r); //config.axis2D(0, 0,180); var stat = new Statistic(); var data = [4,8,15,22,25,14,6,4,2]; var text = []; //初始化各组频数 //0到60岁,5岁一组 for (var i = 0; i < 5; i+=0.5) { text.push(i.toFixed(1)); } stat.init(data, '月用水量(t)', '人数', 1); stat.histogram(text, 0, 0); } </span>
<span style="font-size:18px;"> if (1) { var config = new PlotConfiguration(); config.init(); config.setPreference(); var r = 20; //config.setSector(1,1,1,1); //config.graphPaper2D(0, 0, r); //config.axis2D(0, 0,180); var stat = new Statistic(); var data = [4,8,15,22,25,14,6,4,2]; for (var i = 0; i < data.length; i++) { data[i]/=100; } var text = []; //初始化各组 for (var i = 0; i < 5; i+=0.5) { text.push(i.toFixed(1)); } stat.init(data, '月用水量(t)', '频率', 1); stat.rateHistogram(text, 0, 0); } //频率分布直方图 this.rateHistogram = function(lableArray, xOffset, yOffset, yMin, yMax) { lableArray = lableArray ? lableArray : []; var lables = lableArray.length; xOffset = xOffset ? xOffset : 0; yOffset = yOffset ? yOffset : 0; var colorArray = ['red', 'orange', '#0088FF', 'green', 'cyan', 'blue', '#FF00FF', '#FF8844', 'purple']; var colors = colorArray.length; var height = 380, width = 580; plot.save() .translate(xOffset+60, yOffset+50); plot.setLineWidth(2) .setTextAlign('right'); var max = yMax ? yMax : this.max(); var min = yMin ? yMin : 0; //最大值的末位为0的近似数,比如最大值25,最合适的近似数为30 var dy = Math.round((max-min)/10*100)/100; var size = this.size(); var perH = Math.round((height-100) / 10); var perW = Math.round((width-100) / (size+2)); //宽和高度边界 var wBound = (size+2)*perW, hBound = 10*perH; plot.setLineWidth(5) .strokeRect(0, 0, wBound, hBound); this.axis2D(0, hBound, wBound+20, hBound+20, this.xLabel, this.yLabel); plot.setLineWidth(2); var count = 0; for (var i = hBound; i >-1; i -= perH) { plot.fillText((min+dy*count).toFixed(2), -10, i+10, 30); count++; if (i > 0) { plot.beginPath() .moveTo(0, i) .lineTo(wBound, i) .closePath() .stroke(); } } for (var i = 0; i < size+2; i++) { plot.beginPath() .moveTo(i*perW, 0) .lineTo(i*perW, hBound) .closePath() .stroke(); } var xpos, xpos2; for (var i = 0; i < size; i++) { var h = -(this.statisticalSample[i]-min)/dy*perH; xpos = perW*(1+i); xpos2 = xpos + 0.5*perW; //对于值为0的组,就不多加操作了 if (h < 0) { plot.setFillStyle(colorArray[i%colors]); plot.fillRect(perW*(1+i), hBound, perW, h); if (i == 0) { xpos += 0.75*perW; } else { xpos += 0.5*perW; } plot.setFillStyle('blue'); plot.fillText(this.statisticalSample[i].toString(), xpos, h+hBound-5, 100); } plot.setFillStyle('blue'); plot.setTextAlign('center'); if (i < lables) { plot.fillText(lableArray[i], xpos2-0.5*perW, hBound+30, 100); } //增加x轴的最后一个标注 if (i == size-1) { var n1 = parseFloat(lableArray[i]); var n2 = parseFloat(lableArray[i-1]); var n3 = (2*n1-n2); var s; if (Math.abs(n3-Math.round(n3))<0.001) { s = n3.toFixed(0); } else { s = n3.toFixed(1); } plot.fillText(s, xpos2+0.5*perW, hBound+30, 100); } //plot.fillText(this.statisticalSample[i].toFixed(0), xpos2, hBound+40, 100); } plot.restore(); }</span>
<span style="font-size:18px;"> //一组点 if (1) { var r = 20; config.setSector(1,1,1,1); config.graphPaper2D(0, 0, r); config.axis2D(0, 0,180); //坐标轴设定 var scaleX = 2*r, scaleY = 2*r; var spaceX = 10, spaceY = 10; var xS = -10, xE = 80; var yS = -10, yE = 50; config.axisSpacing(xS, xE, spaceX, scaleX, 'X'); config.axisSpacing(yS, yE, spaceY, scaleY, 'Y'); var X=[ 23,27,39,41,45,49,50,53,54,56,57,58,60,61], Y=[ 9.5,17.8,21.2,25.9,27.5,26.3,28.2,29.6,30.2,31.4,30.8,33.5,35.2,34.6]; var array = []; var size = X.length; for (var i = 0; i < size; i++) { array.push([X[i], Y[i]]); } var transform = new Transform(); var tmp = []; array = transform.scale(transform.translate(array, 0, 0), scaleX/spaceX, scaleY/spaceY); tmp = [].concat(array); shape.pointDraw(tmp, 'green'); //tmp = [].concat(array); //shape.multiLineDraw(tmp, '#CCFF22'); } </span>
进行拟合,这个就是用了最小二乘法的公式了:
<span style="font-size:18px;">>>> X= [23, 27, 39, 41, 45, 49, 50, 53, 54, 56, 57, 58, 60, 61] Y= [9.5, 17.8, 21.2, 25.9, 27.5, 26.3, 28.2, 29.6, 30.2, 31.4, 30.8, 33.5, 35.2, 34.6] 拟合结果: y = 0.57648 x + -0.44780 , r= 0.97074 def linefit(x , y): N = float(len(x)) sx,sy,sxx,syy,sxy=0,0,0,0,0 for i in range(0,int(N)): sx += x[i] sy += y[i] sxx += x[i]*x[i] syy += y[i]*y[i] sxy += x[i]*y[i] a = (sy*sx/N -sxy)/( sx*sx/N -sxx) b = (sy - a*sx)/N r = abs(sy*sx/N-sxy)/math.sqrt((sxx-sx*sx/N)*(syy-sy*sy/N)) return a,b,r def tmp(): X=[ 23,27,39,41,45,49,50,53,54,56,57,58,60,61]; Y=[ 9.5,17.8,21.2,25.9,27.5,26.3,28.2,29.6,30.2,31.4,30.8,33.5,35.2,34.6]; a,b,r=linefit(X,Y) print("X=",X) print("Y=",Y) print("拟合结果: y = %10.5f x + %10.5f , r=%10.5f" % (a,b,r) ) </span>
<span style="font-size:18px;"> if (1) { var r = 20; config.setSector(1,1,1,1); config.graphPaper2D(0, 0, r); config.axis2D(0, 0,180); //坐标轴设定 var scaleX = 2*r, scaleY = 2*r; var spaceX = 10, spaceY = 10; var xS = -10, xE = 80; var yS = -10, yE = 50; config.axisSpacing(xS, xE, spaceX, scaleX, 'X'); config.axisSpacing(yS, yE, spaceY, scaleY, 'Y'); var X=[ 23,27,39,41,45,49,50,53,54,56,57,58,60,61], Y=[ 9.5,17.8,21.2,25.9,27.5,26.3,28.2,29.6,30.2,31.4,30.8,33.5,35.2,34.6]; var array = []; var size = X.length; for (var i = 0; i < size; i++) { array.push([X[i], Y[i]]); } var transform = new Transform(); var tmp = []; array = transform.scale(transform.translate(array, 0, 0), scaleX/spaceX, scaleY/spaceY); tmp = [].concat(array); shape.pointDraw(tmp, 'green'); array = []; for (var i = 0; i < size; i++) { array.push([X[i], taskFun(X[i])]); } array = transform.scale(transform.translate(array, 0, 0), scaleX/spaceX, scaleY/spaceY); tmp = [].concat(array); shape.multiLineDraw(tmp, 'red'); plot.setFillStyle('blue'); plot.fillText('拟合结果: y = 0.57648 x - 0.44780', -270, -170, 200); } } function taskFun(x) { return 0.57648*x -0.44780; } </span>
这位勤奋的小店主,小伟决定要好好算一下他的这些数据。
<span style="font-size:18px;">>>> X= [-5, 0, 4, 7, 12, 15, 19, 23, 27, 31, 36] Y= [156, 150, 132, 128, 130, 116, 104, 89, 93, 76, 54] 拟合结果: y = -2.35170 x + 147.76710 , r= 0.98113 //一组点 if (1) { var r = 20; config.setSector(1,1,1,1); config.graphPaper2D(0, 0, r); config.axis2D(0, 0,180); //坐标轴设定 var scaleX = 2*r, scaleY = 2*r; var spaceX = 10, spaceY = 50; var xS = -10, xE = 50; var yS = -10, yE = 200; config.axisSpacing(xS, xE, spaceX, scaleX, 'X'); config.axisSpacing(yS, yE, spaceY, scaleY, 'Y'); var X=[-5, 0, 4, 7, 12, 15, 19, 23, 27, 31, 36], Y=[ 156, 150, 132, 128, 130, 116, 104, 89, 93, 76, 54]; var array = []; var size = X.length; for (var i = 0; i < size; i++) { array.push([X[i], Y[i]]); } var transform = new Transform(); var tmp = []; array = transform.scale(transform.translate(array, 0, 0), scaleX/spaceX, scaleY/spaceY); tmp = [].concat(array); shape.pointDraw(tmp, 'green'); array = []; for (var i = 0; i < size; i++) { array.push([X[i], taskFun(X[i])]); } array = transform.scale(transform.translate(array, 0, 0), scaleX/spaceX, scaleY/spaceY); tmp = [].concat(array); shape.multiLineDraw(tmp, 'red'); plot.setFillStyle('blue'); plot.fillText('拟合结果: y = -2.35170 x + 147.76710', -270, -170, 300); } if (0) { var config = new PlotConfiguration(); config.init(); config.setPreference(); var r = 20; //config.setSector(1,1,1,1); //config.graphPaper2D(0, 0, r); //config.axis2D(0, 0,180); var X=[-5, 0, 4, 7, 12, 15, 19, 23, 27, 31, 36], Y=[ 156, 150, 132, 128, 130, 116, 104, 89, 93, 76, 54]; var stat = new Statistic(); var data = Y; var text = []; //横坐标 for (var i = 0; i < X.length; i++) { text.push(X[i].toFixed(0)); } stat.init(data, '气温', '卖出热饮(杯)', 1); stat.barChart(text, 0, 0); } } function taskFun(x) { return -2.35170*x + 147.76710; }</span>
看来[人叫板老师]也认为是这个答案。
本节到此结束,欲知后事如何,请看下回分解。