做一个最简单的预言家
A. 看,这牛市定大涨,我就指着这股发财了!
B. 大佬,真的吗,我跟你买定了!
A. 当然,相信鱼哥的预言能力,昨天特意把最近几个月的股市数据做了一波回归分析,发现就这支增长的趋势最明显,大有明天破3000的势头。听我的准不亏!
B. 嗯嗯,嗯
。。。
旁白:几天后,股市动荡,大量股票下行,A、B赔的只剩一个裤头
回归分析的理论价值
结果总是由多个因子影响。例如举例如下:原料到成品的生产效益=成品收益(线性收益)+原料成本(线性减益)+员工成本(对数减益)+质保成本(对数减益)+产品良品率(指数增益),以致于说还有其他成本和收益鉴于个人水平也说不透。如下面这张图:
海拔\沸点 海拔/沸点关系图
有一定物理学基础的读者一定知道沸点与海拔是线性关系,甚至能拿出公式直接得出上图关系的观点。我们这边不阐述物理观点,逆反我们常识中的因果关系。观察第一张图中,我们可以大致的总结出随着海拔提高,其沸点的数据在下降。如何归纳出这种关系,就是我们要考虑的重点了。
线性回归
线性回归模型公式表达
比如说我们去预测一个学校的总的打印数量,很明显,在没有放假和考试的影响下,打印量放到一个大的纬度下(比如一个月),几乎是一个定值,而放假的天数,则几乎是这个定值的相反数,考试的次数则是一个正相关的定值。我们可以表达如下
每月打印张数
平常天数、休假天数、考试天数就是所谓的因子,而我们进行线性归纳就是要考量出这些因子的影响程度。当然上述的公式没有去考虑不稳定因数,进行归纳分析抓住主要因子其实是最重要的。
下图又展示了一种多因子的影响关系。
水泥强度分析单因子线性回归分析
世界万物繁杂多变,单纯的单因子和线性关系肯定不能实际表现出事物的变化。但是为嘛还要说单因子线性回归分析呢?因为简单啊。而且很多情况下,总有一个因子影响力是最大的。例如如下的情景:
打印机租赁服务中,我们需要评估租赁服务使用的物联网卡是否有流量异常?先对现行的租赁服务进行流量使用评估:
流量=打印次数*每次服务端交互流量+客户端更新+报错资讯+定期心跳汇报+有可能的异常流量。
可以看到除了打印次数*每次服务端交互流量和有可能的异常流量以外,其他的流量使用都可以称为不重要因子或者是已知因子。而我们要评估正是有可能的异常流量,所以我们可以把此主要因子剔除分析,可以说打印服务的流量使用可以定义成如下的公式:
这就是最简单的单因子线性回归公式
单因子线性回归
因为不定因子的存在,我们没有没有办法,得出纯正的X与Y的线性关系,所以下面进入纯数学的领域了。
数学意义上的单因子线性回归分析
其实不定因子简单点来说,就是误差,如果要求得最优解,就是要误差小。可能有人就会说当
很明显这是可行的,但是差两个2和差一个4绝对不应该等同而言。所以回归分析引用了方差来解决问题(放大过大的误差,线性回归中叫做最小化残差平方和)
用方差来代表误差
最小化残差平方和
使用微分法求极值:将上式分别对和做一阶偏微分,并令其等于0:(我这边太懒了,公式很难做,直接截维基百科的图了,大家见谅)
偏微分
此二元一次线性方程组可用克莱姆法则求解
根据这张图,我们可以很顺利的总结出下面的小程序,有问题详见程式备注
#!/usr/bin/python
def average_value(lists):#平均值
sum = 0
for number_list in lists:
sum+=number_list
return sum/len(lists)
def regression_b(Y_lists,X_lists,avg_y,avg_x):#计算^b
sum_b = 0
sum_a = 0
for i in range(0,len(Y_lists)):
sum_b+=(X_lists[i]-avg_x)*(Y_lists[i]-avg_y)#分子
for j in range(0,len(Y_lists)):
sum_a+=(X_lists[j]-avg_x)*(X_lists[j]-avg_x)#分母
return sum_b/sum_a
def regression_a(avg_x,avg_y,b):#计算^a
return avg_y-avg_x*b
def regression(lists,lines):#计算回归方程
y = lists
if len(lines) == 0 :#若基准序列X不存在,我们另序列X为(1,2,...,n)
x = list(range(1,len(y)+1))
elif len(lines) != len(lists):
print("ERROR")
return
print(x)
print(y)
avg_y = average_value(y)
avg_x = average_value(x)
b = regression_b(y,x,avg_y,avg_x)
a = regression_a(avg_x,avg_y,b)
print("y="+str(round(b,3))+"x"+("+" if a>0 else "") +str(round(a,3)))
lists = [9,12,11,8,15,12,16,7,13,13,17]
lines = []
regression(lists,lines)
如此我们可以得到斜率来标识单因子的影响。
至于多因子线性甚至非线性,那是机器学习的锅,有可能的话鱼会涉及,但是不要苛求。最好大家在这边学习基础,再到外面看看世面吧!
网友评论