"""
@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()
2.逻辑(斯特)回归 非正则化 学习代码
最新推荐文章于 2022-05-14 16:48:47 发布