2.逻辑(斯特)回归 非正则化 学习代码

"""
    @author yokan
    @date 2018/5/16
"""
import numpy as np
import pandas as pd
import matplotlib.pyplot as plot
from scipy.optimize import minimize
#加载数据
def loadfile(file_name,seg_c):
    o_data = np.loadtxt(file_name,delimiter=seg_c)                      #从文本取出数据
    data1,data2 = np.asarray([item for item in o_data if item[2] == 1]) , np.asarray([item for item in o_data if item[2] == 0])
    #把数据分割开,区分出通过和未通过
    return data1,data2,o_data
#框架画图
def drawIndata(data1,data2,xlbl,ylbl):
    x1 = np.c_[data1[:, 0]]
    y1 = np.c_[data1[:, 1]]
    x2 = np.c_[data2[:, 0]]
    y2 = np.c_[data2[:, 1]]
    plot.scatter(x1,y1,s= 30, c= "b", marker= "x",linewidths= 1)
    plot.scatter(x2,y2,s= 30, c= "r",linewidths= 1)
    plot.xlabel(xlbl)
    plot.ylabel(ylbl)

data1,data2,o_data = loadfile("data1.txt",',')
# drawInRect(data1,data2,"subject1 score","subject2 score")
# drawInRect(data1,data2,"subject1 score","subject2 score")

x,y = np.c_[np.ones(len(o_data)),o_data[:, 0:2]],np.c_[o_data[:, 2]]

# plot.show()
#sigmoid函数,是一个控制概率为0-1的函数
def sigmoid(x):
    return (1/(1+np.exp(-x)))
#两个回归都是类似的逻辑,就是求出损失函数,然后求出梯度下降算法,然后梯度下降到最小值,也就是最接近实际的值,然后求出theta就ok了
#不论损失函数和梯度下降都是数学公式推导出来的,具体视频在算法->机器学习->回归
#损失函数
def lossMethod(theta,x,y):
    m = len(y)
    h = sigmoid(x.dot(theta))                             #求出内积,并进行概率化,就是转换成0-1之间的小数,在后面好进行回归
    loss_v = -(1/m)*(np.log(h).T.dot(y) + (np.log(1-h).T.dot(1-y)))       #逻辑回归相关算法
    if np.isnan(loss_v):                                    #判断得到的数据是否合法,合法就直接返回,否则返回正无穷
        return np.inf                                       #需要注意的是,数据合法返回的是False,因为这个函数就是判断是不合法的
    else:
        return loss_v                                       #所以不合法才返回True,nan -> not a number,它不支持字符之类的判定

#梯度下降算法
def gradient_descent(theta,x,y):
    m = len(y)
    h = sigmoid(x.dot(theta.reshape(-1, 1)))                 #需要注意的scipy循环后得到的theta是行向量形式的,不转成列向量形式无法求内积
    grad = (1/m)*x.T.dot(h - y)                                #梯度下降算法
    return grad.flatten()

theta_zero = np.zeros(x.shape[1])
res = minimize(lossMethod, theta_zero, args=(x,y), method=None, jac=gradient_descent, options={'maxiter':400})   #和线性回归一样,循环多次求最完美的theta值
print(res)
## 得到res证明学习完成了,res.x就是要的theta
#预测准确度
def predict(theta,x,accept_bate = 0.5):
    p = sigmoid(x.dot(theta.T)) >= accept_bate
    return(p.astype('int'))                                              #因为最终得到的是个bool值的数组,为了方便后面计算转成0,1形式

print(sigmoid(np.array([1, 45, 85]).dot(res.x.T)))                #测试下学习好的数据
p = predict(res.x, x)
print('精准度 {}%'.format(100*sum(p == y.ravel())/p.size))         #根据大数定律得到数据量越大越接近真正的数值,这数据并不是足够大所以存在准确率
#以下是用matplotlib 进行图形绘制
drawIndata(data1,data2, 'subject1 score', 'subject2 score')
x1_min, x1_max = x[:,1].min(), x[:,1].max(),
x2_min, x2_max = x[:,2].min(), x[:,2].max(),
xx1, xx2 = np.meshgrid(np.linspace(x1_min, x1_max), np.linspace(x2_min, x2_max))
h = sigmoid(np.c_[np.ones((xx1.ravel().shape[0],1)), xx1.ravel(), xx2.ravel()].dot(res.x))
h = h.reshape(xx1.shape)

plot.contour(xx1, xx2, h, [0.5], linewidths=1, colors='b');
plot.show()


阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页