1.线性回归与逻辑回归
2.多元梯度下降
3.梯度上升
4.正规方程

线性回归与逻辑回归

线性回归

在统计学中,线性回归(Linear Regression)是利用称为线性回归方程的最小平方函数对一个或多个自变量和因变量之间关系进行建模的一种回归分析。这种函数是一个或多个称为回归系数的模型参数的线性组合。只有一个自变量的情况称为简单回归,大于一个自变量情况的叫做多元回归。

逻辑回归

以胃癌病情分析为例,选择两组人群,一组是胃癌组,一组是非胃癌组,两组人群必定具有不同的体征与生活方式等。因此因变量就为是否胃癌,值为“是”或“否”,自变量就可以包括很多了,如年龄、性别、饮食习惯、幽门螺杆菌感染等。

预测房价

多元梯度下降

假设函数

这里n=5,含有5个参数

这里需要注意的是,在原有自变量的基础上,需要主观添加一个均为1的偏移量,即公式中的x0。

假如有两个特征值,即3个参数将会得到如图所示的损失函数

损失函数

m:样本数

表示每个theta

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# coding=utf-8

import numpy as np
import random
from numpy import genfromtxt


def getData(dataSet):
m, n = np.shape(dataSet)
trainData = np.ones((m, n))
trainData[:, :-1] = dataSet[:, :-1]
trainLabel = dataSet[:, -1]
return trainData, trainLabel


def batchGradientDescent(x, y, theta, alpha, m, maxIterations):
xTrains = x.transpose()
for i in range(0, maxIterations):
hypothesis = np.dot(x, theta)
loss = hypothesis - y
# print loss
gradient = np.dot(xTrains, loss) / m
theta = theta - alpha * gradient
return theta


def predict(x, theta):
m, n = np.shape(x)
xTest = np.ones((m, n+1))
xTest[:, :, :, :-1] = x
yP = np.dot(xTest, theta)
return yP


dataPath = r"data.csv"
dataSet = genfromtxt(dataPath, delimiter=',')
trainData, trainLabel = getData(dataSet)
m, n = np.shape(trainData)
theta = np.ones(n)
alpha = 0.1
maxIteration = 5000
theta = batchGradientDescent(
trainData, trainLabel, theta, alpha, m, maxIteration)

梯度上升

对于梯度下降法来说,在神经网络中用到,最小化误差的一种优化方法

在梯度上升法是在逻辑回归中求概率最大值,即求最大似然函数的最大值用到的方法

算法实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from numpy import *
import numpy as np


def loadDataSet():
dataMat = []
labelMat = []
fr = open('testSet.txt')
for line in fr.readlines():
lineArr = line.strip().split()
dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])
labelMat.append(int(lineArr[2]))
return dataMat, labelMat


def sigmoid(inX):
return 1.0/(1+exp(-inX))


def gradAscent(dataMatIn, classLabels):
dataMatrix = mat(dataMatIn)
labelMatix = mat(classLabels).transpose()
m = dataMatrix.shape[0]
n = dataMatrix.shape[1]
alpha = 0.001
maxCycles = 500
weights = ones((n, 1))
for k in range(maxCycles):
h = sigmoid(dataMatrix*weights)
error = (labelMatix - h)
weights = weights + alpha * dataMatrix.transpose() * error
return weights
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#字符串的split用法
1.按某一个字符分割
>>> str = ('www.google.com')
>>> str
'www.google.com'
>>> str.split('.')
['www', 'google', 'com']
2.按某一个字符分割,且分割n次。如按‘.’分割1
str.split('.'1)
>>>str
>>>['www', 'google.com']
3.按某一字符串分割。如:‘||’
str = ('WinXP||Win7||Win8||Win8.1')
>>> str
>>> str.split('||')
['WinXP', 'Win7', 'Win8', 'Win8.1']
4.按某一字符串分割,且分割n次。如:按‘||’分割2
>>> str = ('WinXP||Win7||Win8||Win8.1')
>>> str.split('||',2)
['WinXP', 'Win7', 'Win8||Win8.1']

#strip()函数
1. 当rm为空时,默认删除空白符(包括'\n', '\r', '\t', ' ')
>>> a=' Hello World '
>>> a
' Hello World '
>>> a.strip()
'Hello World'
>>> x='\t\r\npython'
>>> x
'\t\r\npython'
>>> x.strip()
'python'
2.rm删除序列是只要边(开头或结尾)上的字符在删除序列内,就删除掉。
>>> aString='123love'
>>> aString
'123love'
>>> aString.strip('12')
'3love'
#zeros函数和ones函数
>>>from numpy import *
>>> a=zeros((3,4))
>>> a
array([[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]])
>>> from numpy import *
>>> a=ones((3,4))
>>> a
array([[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.]])
>>> from numpy import *
>>> a=eye(3)
>>> a
array([[ 1., 0., 0.],
[ 0., 1., 0.],
[ 0., 0., 1.]])
numpy.eye(N,M=None, k=0, dtype=<type 'float'>)
第一个参数:输出方阵(行数=列数)的规模,即行数或列数

第三个参数:默认情况下输出的是对角线全“1”,其余全“0”的方阵,
如果k为正整数,则在右上方第k条对角线全“1”其余全“0”,
k为负整数则在左下方第k条对角线全“1”其余全“0”。
>>> a=eye(3,4,k=1)
>>> a
array([[0., 1., 0., 0.],
[0., 0., 1., 0.],
[0., 0., 0., 1.]])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#转置有三种方式,transpose方法、T属性以及swapaxes方法。
In [1]: import numpy as np

In [2]: arr = np.arange(20).reshape(4,5)#生成一个4行5列的数组

In [3]: arr
Out[3]:
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19]])

In [4]: arr.T #求转置
Out[4]:
array([[ 0, 5, 10, 15],
[ 1, 6, 11, 16],
[ 2, 7, 12, 17],
[ 3, 8, 13, 18],
[ 4, 9, 14, 19]])

>>> import numpy as np
>>> A = np.arange(16)
>>> A
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
>>> A = A.reshape(2,2,4)#将A变换为三维矩阵
>>> A
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7]],

[[ 8, 9, 10, 11],
[12, 13, 14, 15]]])
>>> A.shape
(2, 2, 4)
说明这是一个2*2*4的数组(矩阵),返回的是一个元组,可以对元组进行索引,也就是0,1,2
A.transpose((0,1,2)) #保持A不变
A.transpose((1,0,2)) #将 0轴 和 1轴 交换

正规方程(normal equation)

一种直接求解参数的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
octave:1> X = [1,2104,5,1,45;1,1416,3,2,40;1,1534,3,2,30;1,852,2,1,36]
X =

1 2104 5 1 45
1 1416 3 2 40
1 1534 3 2 30
1 852 2 1 36

octave:2> y = [460;232;315;178]
y =

460
232
315
178

octave:3> pinv(X'*X)*X'*y
ans =

188.40032
0.38663
-56.13825
-92.96725
-3.73782

#举例验证

octave:4> ex = [1,852,2,1,36]
ex =

1 852 2 1 36

octave:5> ex*ans
ans = 178.00

正规方程与梯度下降的比较

推导过程

Logistic regression

Logistic本质上是一个基于条件概率的判别模型(DiscriminativeModel)。利用了Sigmoid函数值域在[0,1]这个特性。
直接使用线性回归的输出作为概率是有问题的,因为其值有可能小于0或者大于1,这是不符合实际情况的,逻辑回归的输出正是[0,1]区间。

Logistic 回归通过使用其固有的 logistic 函数估计概率,来衡量因变量(我们想要预测的标签)与一个或多个自变量(特征)之间的关系。

sigmoid 函数

Sigmoid 函数是一个 S 形曲线,它可以将任意实数值映射到介于 0 和 1 之间的值,但并不会取到 0/1。然后使用阈值分类器将 0 和 1 之间的值转换为 0 或 1。

决策边界

为什么使用sigmoid function

**