[从头学数学] 第175节 统计

在星历2016年的某一天,银河系厄尔斯星球上的工程师阿伟与机器小伟共同探讨统计学。小伟设计了一个随机样本工具,并运用最小二乘法进行数据拟合。他们对数据的深入分析得到了[人叫板老师]的认可,揭示了统计学在解决实际问题中的应用。
摘要由CSDN通过智能技术生成
剧情提要:
[机器小伟]在[工程师阿伟]的陪同下进入了结丹中期的修炼,
这次要修炼的目标是[统计]。

正剧开始:

星历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>


看来[人叫板老师]也认为是这个答案。





本节到此结束,欲知后事如何,请看下回分解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值