回归分析是一种很重要的预测建模技术。主要是研究自变量与因变量之间的因果关系。本文将会从数学角度与代码角度分析不同类型的回归。当你想预测连续型的非独立变量,或者对一系列独立变量或输入项有所反应时,就会使用到回归分析。如果非独立变量是二分的,那么我们将会使用到逻辑回归。

对于回归技术的分类,在这里我不想过多细分,但是一般回归会依赖于三个方面进行区分:
+自变量数目
+回归函数曲线的形状
+因变量的类型

首先我们来了解下面几种常用的回归算法模型

简单线性回归(Simple Linear Regression)

简单线性回归是最基础的一种回归模型,自变量只有一个,函数曲线为直线,因变量为连续型,自变量可以是连续的或者是离散的。函数表示如下:

其中 y 是因变量, x是自变量, β0 和 β1 属于起始值和系数,ε 为偏移量,为了使得到的函数模型更加准确,最后会加上偏移量。

线性回归一般使用最小二乘法来求解函数模型级求解 β0 和 β1 。 方法如下:最小二乘法

如图中四个点为数据(x,y):(1,6)(2,5)(3,7)(4,10)。我们需要根据红色的数据来求蓝色的曲线。目前我们已知这四个点匹配直线y= β1 + β2x 。所以我们要找到符合这条直线的最佳情况,即最合适的β0 和 β1。

最小二乘法就是尽量取两边方差的最小值,这样可以找到最拟合的曲线。

然后我们我们同时对β0和β1求其偏导数

这样我们很容易就解除方程组的解

所以我们就得到了直线 y=3.5 + 1.4x

用Python和Java代码表示如下:

# -*- coding: utf-8 -*-
"""
Created on Thu Dec 01 00:02:49 2016 @author: steve
""" def SLR(x,y):
intercept = 0.0
slope = 0.0
n = len(x) sumx = 0.0
sumy = 0.0
sumx2 = 0.0 # 第一次循环,得到平均值
for i in range(n):
sumx += x[i]
sumy += y[i]
sumx2 += x[i]*x[i] xbar = sumx/n
ybar = sumy/n xxbar = 0.0
yybar = 0.0
xybar = 0.0 # 第二次循环,得到方差
for i in range(n):
xxbar += (x[i] - xbar) * (x[i] - xbar);
yybar += (y[i] - ybar) * (y[i] - ybar);
xybar += (x[i] - xbar) * (y[i] - ybar); # 计算斜率和intercept
slope = xybar / xxbar
intercept = ybar - slope * xbar print "slope is {}, intercept is {}".format(slope, intercept)
## 其他统计变量我就不写了。 x=[1,2,3,4]
y=[6,5,7,10]
SLR(x,y)
package regression;

public class SLR {

	// 这是用二分法做的简单线性回归

	private final double intercept, slope;
private final double r2;
private final double svar0, svar1; public SLR(double[] x, double[] y) { if (x.length != y.length) {
throw new IllegalArgumentException("lengths doesn't match!!!");
} int n = x.length; // 第一次循环,找到 所有x和y的平均值 double sumx = 0.0;
double sumy = 0.0;
double sumx2 = 0.0; for (int i=0; i<n; i++) {
sumx += x[i];
sumy += y[i];
sumx2 += x[i]*x[i];
} double xbar = sumx / n;
double ybar = sumy / n; // 第二次计算,求出方差
double xxbar = 0.0;
double yybar = 0.0;
double xybar = 0.0;
for (int i = 0; i < n; i++) {
xxbar += (x[i] - xbar) * (x[i] - xbar);
yybar += (y[i] - ybar) * (y[i] - ybar);
xybar += (x[i] - xbar) * (y[i] - ybar);
}
System.out.println(xxbar);
System.out.println(yybar);
System.out.println(xybar);
slope = xybar / xxbar; //求偏导数的过程
intercept = ybar - slope * xbar; // 其他的统计数据
double rss = 0.0; // residual sum of squares
double ssr = 0.0; // regression sum of squares
for (int i = 0; i < n; i++) {
double fit = slope*x[i] + intercept;
rss += (fit - y[i]) * (fit - y[i]);
ssr += (fit - ybar) * (fit - ybar);
} int degreesOfFreedom = n-2;
r2 = ssr / yybar;
double svar = rss / degreesOfFreedom;
svar1 = svar / xxbar;
svar0 = svar/n + xbar*xbar*svar1; } public double intercept() {
return intercept; } 大专栏  Dykin's blogn class="kd">public double slope() {
return slope; } public double R2() {
return r2;
} public double slopeStdErr() {
return Math.sqrt(svar1);
} public double interceptStdErr() {
return Math.sqrt(svar0);
} //这是预测方法,在机器学习中的函数
public double predict(double x) {
return slope*x + intercept;
} public String toString() {
StringBuilder s = new StringBuilder();
s.append(String.format("%.2f n + %.2f", slope(), intercept()));
s.append(" (R^2 = " + String.format("%.3f", R2()) + ")");
return s.toString();
} }

多元线性回归类似于简单线性回归,只不过自变量不止一个,但是过程和方法与简单线性回归一样。这里我只把代码放出来。




多项式回归(Polynomial Regression)

如果一个方程,自变量的指数大于1,那么所有拟合这个方程的点就符合多项式回归。

多项式回归有个很重要的因素就是指数(degree)。如果我们发现数据的分布大致是一条曲线,那么很可能符合多项式回归,但是我们不知道degree是多少。所以我们只能一个个去试,直到找到最拟合分布的degree。这个过程我们可以交给数据科学软件完成。需要注意的是,如果degree选择过大的话可能会导致函数过于拟合, 意味着对数据或者函数未来的发展很难预测,也许指向不同的方向。

这个回归的计算需要用到矩阵数据结构。有的编程语言可能需要导入外库。

我们对所有拟合这个公式的点,用矩阵表示他们的关系

如果用矩阵符号表示:

多项式回归向量的系数(使用最小二乘法):

Java 和 Python 代码如下:



package regression;
import Jama.Matrix;
import Jama.QRDecomposition; public class PR { private final int N;
private final int degree;
private final Matrix beta;
private double SSE;
private double SST; public PR(double[] x, double[] y, int degree) {
this.degree = degree;
N = x.length; // build Vandermonde matrix
double[][] vandermonde = new double[N][degree+1];
for (int i = 0; i < N; i++) {
for (int j = 0; j <= degree; j++) {
vandermonde[i][j] = Math.pow(x[i], j);
}
}
Matrix X = new Matrix(vandermonde); // 从向量中增加一个矩阵
Matrix Y = new Matrix(y, N); // 找到最小的平方值
QRDecomposition qr = new QRDecomposition(X);
beta = qr.solve(Y); // 得到y的平均值
double sum = 0.0;
for (int i = 0; i < N; i++)
sum += y[i];
double mean = sum / N; // total variation to be accounted for
for (int i = 0; i < N; i++) {
double dev = y[i] - mean;
SST += dev*dev;
} // variation not accounted for
Matrix residuals = X.times(beta).minus(Y);
SSE = residuals.norm2() * residuals.norm2();
} public double beta(int j) {
return beta.get(j, 0);
} public int degreee() {
return degree;
} public double R2() {
return 1.0 - SSE/SST;
} public double predict(double x) { double y = 0.0;
for (int j = degree; j>=0; j--) {
y = beta(j) + (x*y);
}
return y;
} public String toString() {
String s = "";
int j = degree; // 忽略系数为0.
while (Math.abs(beta(j)) < 1E-5)
j--; // create remaining terms
for (j = j; j >= 0; j--) {
if (j == 0) s += String.format("%.2f ", beta(j));
else if (j == 1) s += String.format("%.2f N + ", beta(j));
else s += String.format("%.2f N^%d + ", beta(j), j);
}
return s + " (R^2 = " + String.format("%.3f", R2()) + ")";
} }

逻辑回归(Logistic Regression)

逻辑回归是我最喜欢的一种回归,因为表达的是概率事件。

Probit model

逐步回归(Stepwise Regression)

岭回归(Ridge Regression)

套索回归(Lasso Regression)

弹性网(Elastic net)

本文参考了Sunil Ray的7 Types of Regression Techniques you should know!

Dykin's blog的更多相关文章

  1. 日向blog开发记录

    一点历史关于,Sonne Blog 2016.03.25springmvc + hibernate框架搭建.2016.04.21日向blog首页.2016.04.24分页实现.2016.04.30登录 ...

  2. blog (后续更新)

    设计Model(设计数据库) from django.db import models # Create your models here. class BlogsPost(models.Model) ...

  3. tensorflow 一些好的blog链接和tensorflow gpu版本安装

    pading :SAME,VALID 区别  http://blog.csdn.net/mao_xiao_feng/article/details/53444333 tensorflow实现的各种算法 ...

  4. http://blog.csdn.net/java2000_wl/article/details/8627874

    http://blog.csdn.net/java2000_wl/article/details/8627874

  5. [Android Pro] http://blog.csdn.net/wuyinlei/article/category/5773375

    http://blog.csdn.net/wuyinlei/article/category/5773375

  6. android 蓝牙 http://blog.csdn.net/u012843100/article/details/52384219

    http://blog.csdn.net/u012843100/article/details/52384219

  7. 【三】用Markdown写blog的常用操作

    本系列有五篇:分别是 [一]Ubuntu14.04+Jekyll+Github Pages搭建静态博客:主要是安装方面 [二]jekyll 的使用 :主要是jekyll的配置 [三]Markdown+ ...

  8. django开发个人简易Blog—nginx+uwsgin+django1.6+mysql 部署到CentOS6.5

    前面说完了此项目的创建及数据模型设计的过程.如果未看过,可以到这里查看,并且项目源码已经放大到github上,可以去这里下载. 代码也已经部署到sina sea上,地址为http://fengzhen ...

  9. 使用Hexo搭建专属Blog

    喜欢折腾的自己最开始在博客园有仿写几篇Blog,虽也可以自己改变风格,可是到底不是独立的一块儿地方,要知道独立的才是自己的;有属于自己独立的域名和Blog,真真是一件很爽的存在.在各种大牛的分享下在G ...

随机推荐

  1. 关于Linux下Oracle安装后启动的问题

    1.首先,切换成oracle用户,启动监听服务.(中间的横杠必须加上,不然会出现command not found 的错误) 命令1:su  -  oralce 命令2:lsnrctl start 参 ...

  2. 测试Java程序执行耗费的时间

    package test; public class Main { public static void main(String[] args) { long start = System.curre ...

  3. 884A. Book Reading#抽空学习好孩子(模拟)

    题目出处:http://codeforces.com/problemset/problem/884/A 题目大意:每天时间分两部分,工作和学习,工作优先,闲暇读书,问第几天读完 #include< ...

  4. 第一个----关于GPIO的总结

    首先,自己本来报的是单片机的  ,但是因为队友的脑残,给我报成了嵌入式,哎,惨啊,就得从头看这个云里雾里的东西,但是没办法,都报名了  不能呢个交白卷,不然自己就是逃兵了,还有20天就比赛了  我得加 ...

  5. javascript获取数组最后一个元素(三种方法)

    JavaScript 获取Array末尾元素 一.JavaScript pop() 方法 pop() 方法用于删除并返回数组的最后一个元素. 注意:pop() 方法将删除 arrayObject 的最 ...

  6. eclipse安装tfs插件

    Eclipse安装TFS插件   1.打开Eclipse.点击菜单栏上的 “Help”——>选择“Install New Software”. 2.在弹出框中输入点击“Add”. 3.在弹出框中 ...

  7. mac环境下创建bash_profile文件并写入内容 更改php环境变量

    1. 启动终端Terminal 2. 进入当前用户的home目录 输入cd ~ 3. 创建.bash_profile 输入touch .bash_profile 4. 编辑.bash_profile文 ...

  8. day31-hmac模块检测客户端是否合法

    #如果客户端知道服务端的ip地址和端口,就可以连接服务端,信息不安全. #使用os.urandam随机生成32位bytes,然后hmac加密之后再发送给客户端. #server: import soc ...

  9. Andriod常用控件介绍&相关属性(初学方便查询)

    一.TextView(显示控件) android:id(给当前控件定义唯一的标识符)——示例:android:id = "@+id/text_view" android:layou ...

  10. Contiguous Repainting

    题目描述 There are N squares aligned in a row. The i-th square from the left contains an integer ai. Ini ...