import numpy as np,matplotlib.pyplot as plt,copy # 显示中文和负号 plt.rcParams['font.sans-serif']=['SimHei'] plt.rcParams['axes.unicode_minus']=False #鸢尾花数据集(三分类)\乳腺癌数据集(二分类)\波士顿数据集(回归)\葡萄酒数据集(三分类) # import sklearn.datasets as dts # iris_data=dts.load_iris()#鸢尾花 # x=iris_data.data # y=iris_data.target # 完成数据集的读取 ex2data1.txt def data_process(): data=np.loadtxt(r'./ex2data1.txt',delimiter=',') x = data[:, :-1] y = data[:, -1:] # 特征缩放:标准化 x_mean=np.mean(x,axis=0) x_std=np.std(x,axis=0,ddof=1) x=(x-x_mean)/x_std # 添加截距项,规范化标签结构 m,n=x.shape x=np.c_[np.ones((m,1)),x] y=np.c_[y] # 洗牌 np.random.seed(5) order=np.random.permutation(m) x=x[order] y=y[order] # 分割训练集和测试集 8:2 num=int(m*0.8) train_x,test_x=np.split(x,[num]) train_y,test_y=np.split(y,[num]) return train_x,train_y,test_x,test_y # 完成线性回归函数 def lh(x,theta): z=x.dot(theta) return z # 实现Sigmoid函数 def sigmoid(z): h=1.0/(1+np.exp(-z)) return h # 实现逻辑回归的代价函数 交叉熵+正则化 #todo是为了做标记,可以直接到达 def loss_func(h,y,lamda,thetaR): m=len(h) R=lamda/(2*m)*np.sum(thetaR**2) J=-1/m*np.sum(y*np.log(h)+(1-y)*np.log(1-h))+R return J # 实现梯度下降函数 def grad_decent(x,h,y,lamda,thetaR): m=len(h) e=h-y dt=1.0/m*x.T.dot(e)+lamda/m*thetaR return dt # 实现逻辑回归模型精度函数 def acc_func(h,y): acc=np.mean(y==(h>=0.5)) return acc # 通过梯度下降训练逻辑回归模型 # TODO def train_model(x,y,alpha=0.99,iters=100,lamda=0.1): m,n=x.shape theta=np.zeros((n,1)) loss_list=[] for i in range(iters): z = lh(x, theta) h=sigmoid(z) thetaR=copy.copy(theta) thetaR[0]=0 loss=loss_func(h,y,lamda,thetaR) loss_list.append(loss) dt=grad_decent(x,h,y,lamda,thetaR) theta=theta-alpha*dt return loss_list,theta train_x,train_y,test_x,test_y=data_process() loss_list001,theta=train_model(train_x,train_y,lamda=0.01) loss_list5,theta1=train_model(train_x,train_y,lamda=5) # 输出迭代过程中的代价函数值 print('\迭代过程中的损失值:',loss_list5) plt.plot(loss_list5,c='m') plt.plot(loss_list001,c='b') plt.show() # 用所得模型对测试集的数据进行预测,并计算准确率 test_z=lh(test_x,theta) test_h=sigmoid(test_z) print('测试集精度:',acc_func(test_h,test_y)) # 使用训练集的X1,X2两组特征画出0-1分布散点图及分割线 m,n=train_x.shape for i in range(m): if train_y[i]==0: plt.plot(train_x[i,1],train_x[i,2],'ob')#'ob'表示样式为o,颜色为b elif train_y[i]==1: plt.plot(train_x[i,1],train_x[i,2],'*r') plt.xlabel('x1') plt.ylabel('x2') #theta0+theta1x1+theta2x2=0 x1_min,x1_max=np.min(train_x[:,1]),np.max(train_x[:,1]) x2_min=(-theta[0]-theta[1]*x1_min)/(theta[2]) x2_max=(-theta[0]-theta[1]*x1_max)/(theta[2]) plt.plot([x1_min,x1_max],[x2_min,x2_max],'m-') plt.show()