机器学习-Logisitic回归

  (1)说明:当y为一系列离散值时,问题转为分类问题。比如我们要根据一个肿瘤的大小判断肿瘤是为良性还是为恶性。

  (2)假设函数:如下图,如果使用线性的方程作为假设函数,肿瘤大小作为横坐标,是否为恶性作为纵坐标。当y值小于0.5时判定为良性,大于0.5时判定为恶性。但有两个缺点:①经过计算会出现y值远大于1的情况,这是不符合常理的,因为概率不会大于1 ②假如在x轴很远的位置有一个数据,会导致斜率变小,本来应为恶性的肿瘤却被判定为良性。

    

 

 

    下图为Logisitic回归的假设函数,可以看出他是一个增函数,并且值区间为0~1开区间,符合我们得要求。如果最终得出值为0.7,我们可以说有70%得概率为恶心肿瘤。

    

 

  (3)决策边界:通过上面得图可以看出,当值小于0.5时判定为良性,大于0.5时判定为恶性。当函数值为0.5时,h(x)为0。也就是说h(x)大于0时判定为恶性,小于0时判定为良性(这里的h(x)就是之前线性回归的假设函数,就是theta * X)。这个边界值称为决策边界。

    

 

  (4)代价函数:之前的代价函数并不是个凸函数,有很个局部最优解。用梯度下降的时候,选择不同的起始点可能得到不同的最优解。

    

     h(x)值域为0~1,所以两种情况的作用域都是0~1。y=1时是单调递减,在h(x)为1时趋近于0,h(x)为0时趋近于正无穷;y=0时单调递增,与上面相反。如果预测错误则返回一个很大的代价值用于惩罚。

     为了方便计算要把两个结合到一起: - [y * (log(h(x))) + (1 - y) * log(1 - h(x))] 

    

  (5)求偏导之后

  

  (6)代码:梯度下降之前也要进行特征缩放

  1 #coding=utf-8
  2 from sklearn.linear_model import LogisticRegression
  3 import matplotlib.pyplot as plt
  4 import numpy as np
  5 import math
  6 import copy
  7 np.set_printoptions(suppress=True)
  8 
  9 def test(arr):
 10     res = 0
 11     for i in arr:
 12         res += math.fabs(i)
 13     return res
 14 
 15 
 16 
 17 #读取文件
 18 def readDate(path):
 19     x_data = []
 20     y_data = []
 21     fd = open(path, 'r')
 22     for line in fd.readlines():
 23         lineArr = line.strip().split()
 24         x_data.append([1, lineArr[0], lineArr[1]])
 25         y_data.append([lineArr[2]])
 26 
 27     x_data = np.array(x_data).astype(np.float)
 28     y_data = np.array(y_data).astype(np.float)
 29     return x_data, y_data
 30 
 31 #sigmoid
 32 def h(x_data, p):
 33     plus = np.dot(x_data, p)
 34     for i in range(len(plus)):
 35         plus[i][0] = 1 / (1 + math.exp(-plus[i][0]))
 36     return plus
 37 
 38 #特征缩放
 39 def scale(arr):
 40     param = []
 41     for i in range(1, arr.shape[1]):
 42         col = arr[:,i]
 43         mean = np.mean(col)
 44         std = np.std(col)
 45 
 46         std = 1 if std == 0 else std
 47         param.insert(i, {'mean':mean, 'std':std})
 48         for j in range(0, len(col)):
 49             arr[j][i] = (col[j] - mean) / std
 50     return arr, param
 51 
 52 
 53 
 54 def J(x_data, y_data, p, a):
 55     global m
 56     sub = h(x_data, p) - y_data
 57     deviation = np.dot(x_data.T, sub)
 58     return a / m * deviation
 59 
 60 #整理参数
 61 def build(p, param):
 62     f = 1       #常数项
 63     for i in range(1, len(p)):
 64         f -= param[i - 1]['mean'] / param[i - 1]['std'] * p[i][0]
 65         p[i] = format(p[i][0] / param[i - 1]['std'], '0.2f')
 66 
 67     p[0] = format(f + p[0][0], '0.2f')
 68     return p
 69 
 70 
 71 #画图
 72 def plotPoint(x_data, y_data, p):
 73     xcordt = []
 74     ycordt = []
 75     xcordf = []
 76     ycordf = []
 77     n = len(y_data)
 78     for i in range(n):
 79         if int(y_data[i][0]) == 1:
 80             xcordt.append(x_data[i,1])
 81             ycordt.append(x_data[i,2])
 82         else:
 83             xcordf.append(x_data[i, 1])
 84             ycordf.append(x_data[i, 2])
 85 
 86     fig = plt.figure()
 87     ax = fig.add_subplot(111)
 88     ax.scatter(xcordt, ycordt, s=30, c='red', marker='s')
 89     ax.scatter(xcordf, ycordf, s=30, c='green')
 90 
 91     #函数曲线
 92     x = np.arange(-3, 3, 0.1)
 93     y = -(p[0][0] + p[1][0] * x) / p[2][0]
 94     ax.plot(x,y)
 95     plt.show()
 96 
 97 
 98 if __name__  == '__main__':
 99     path = 'testSet.txt'
100     a = 0.5
101     x_data, y_data = readDate(path)
102     x_bak = copy.deepcopy(x_data)
103     x_data, param = scale(x_data)
104 
105     m = len(x_data)
106     p = np.zeros([len(x_data[0]), 1])
107 
108     step = 2000
109     for i in range(step):
110         j = J(x_data, y_data, p, a)
111         p -= j
112 
113 
114     p = build(p, param)
115     plotPoint(x_bak, y_data, p)

 

  

 

posted @ 2020-06-24 18:54  Dahouzi  阅读(223)  评论(0编辑  收藏  举报