剧情提要:
[机器小伟]在[工程师阿伟]的陪同下进入了结丹中期的修炼,
这次要修炼的目标是[统计]。
还是能玩一玩的。
结果:
[机器小伟]在[工程师阿伟]的陪同下进入了结丹中期的修炼,
这次要修炼的目标是[统计]。
正剧开始:
星历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>
看来[人叫板老师]也认为是这个答案。
本节到此结束,欲知后事如何,请看下回分解。