03-多分类回归

二分类回归,解决的是两个分类的问题,类似判断题

多分类回归,解决多种情况分类的问题,类似选择题

例如:

根据一个人收入水平和工作情况, 预测他买什么类型的车 ?

  • 福特
  • 宾利
  • 奥迪
  • 宝马

根据一个人的年龄,预测他买什么类型的手机?

  • 苹果
  • 安卓
  • 非智能机

根据你手写的动作姿势,预测你写的什么字?

从二分类到多分类

年龄 喜好
5 看电视
15 看电视
25 读书
35 读书
45 读书
55 广场舞
65 广场舞

数据编码方案1:

年龄 喜好 编码
5 看电视 1
15 看电视 1
25 读书 2
35 读书 2
45 读书 2
55 广场舞 3
65 广场舞 3

数据编码方案2:

年龄 喜好 是否喜欢看电视 是否喜欢读书 是否喜欢广场舞
5 看电视 1 0 0
15 看电视 1 0 0
25 读书 0 1 0
35 读书 0 1 0
45 读书 0 1 0
55 广场舞 0 0 1
65 广场舞 0 0 1

思考:

  1. 为什么不用第一种方案

  2. 第二种方案有什么好处

复杂问题简单化,大问题,拆分成小问题

image-20191120120445497

代码实战

image-20191120120918759

 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
def sigmoid(z):
    return 1 / (1 + np.exp(-z))
import numpy as np
data = np.array([
    [5,1],
    [15,1],
    [25,0],
    [35,0],
    [45,0],
    [55,0],
    [65,0]
])
feature = data[:,0:1]
ones = np.ones((len(feature),1))
Feature = np.hstack((feature ,ones))
Label = data[:,-1:]
weight = np.ones((2,1))

msehistory = []
learningrate = 1


##关键代码
changeweight  = np.zeros((2,1))

def sigmoid(z):
    return 1 / (1 + np.exp(-z))

def gradentdecent():
    global changeweight
    global weight,learningrate
    mse = np.sum(np.power((sigmoid(np.dot(Feature,weight))-Label),2))
    msehistory.append(mse)
    if len(msehistory)>=2:
        if(msehistory[-1]>msehistory[-2]):
            learningrate = learningrate /2
        else :
            learningrate = learningrate * 1.1

    change = np.dot(Feature.T,(sigmoid(np.dot(Feature,weight))-Label))
    ###关键代码
    changeweight = changeweight + change**2       
    weight = weight - learningrate* change/np.sqrt(changeweight)
    ###关键代码
    return change

训练

1
2
3
4
5
for i in range(10000):
    change = gradentdecent()
    if(np.sum(np.square(change))<0.01):
        print("i={},change={},weight={}".format(i,change,weight))
        break

预测

1
2
value = np.array([[20,1]])
sigmoid(np.dot(value,weight))
1
array([[0.43418653]]) 看电视概率

同理

array([[0.45294096]]) 读书概率 array([[0.00405116]]) 广场舞概率

image-20191120123749456

边际概率和条件概率

0.434 是独立,是想看电视的概率, 不是想看电视同时不想看书,不想跳广场舞的概率。

在看电视的同时,可能还可能想看书,看电视

我们需要的是一个条件概率,希望计算的是,看电视,不看书,不跳广场舞。

条件概率的和应该是1, 独立边际概率的和可能不是1

条件概率 类似扔筛子。 每个面的概率的和加起来是1. 如果你摇到了1号点, 这个概率意思是,是1号点,不是2,3,4,5,6

softmax

把边际概率转换为条件概率

从sigmoid函数到 softmax函数

image-20191120141106045

image-20191120141943792

代码实操

 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
def sigmoid(z):
    return 1 / (1 + np.exp(-z))
import numpy as np
data = np.array([
    [5,0],
    [15,0],
    [25,0],
    [35,0],
    [45,0],
    [55,1],
    [65,1]
])
feature = data[:,0:1]
ones = np.ones((len(feature),1))
Feature = np.hstack((feature ,ones))
Label = np.array([
    [1,0,0],
    [1,0,0],
    [0,1,0],
    [0,1,0],
    [0,1,0],
    [0,0,1],
    [0,0,1]
])
weight = np.ones((2,3))

msehistory = []
learningrate = 1


##关键代码
changeweight  = np.zeros((2,3))

def sigmoid(z):
    return 1 / (1 + np.exp(-z))

def gradentdecent():
    global changeweight
    global weight,learningrate
    mse = np.sum(np.power((sigmoid(np.dot(Feature,weight))-Label),2))
    msehistory.append(mse)
    if len(msehistory)>=2:
        if(msehistory[-1]>msehistory[-2]):
            learningrate = learningrate /2
        else :
            learningrate = learningrate * 1.1

    change = np.dot(Feature.T,(sigmoid(np.dot(Feature,weight))-Label))
    ###关键代码
    changeweight = changeweight + change**2       
    weight = weight - learningrate* change/np.sqrt(changeweight)
    ###关键代码
    return change
1
2
3
4
5
for i in range(10000):
    change = gradentdecent()
    if(np.sum(np.square(change))<0.01):
        print("i={},change={},weight={}".format(i,change,weight))
        break

sigmoid边际概率

1
2
value = np.array([[20,1]])
sigmoid(np.dot(value,weight))

softmax条件概率

1
2
3
value = np.array([[60,1]])
np.set_printoptions(suppress=True)
np.exp(np.dot(value,weight))/np.sum(np.exp(np.dot(value,weight)))