机器学习python——正则化逻辑回归(吴恩达课后作业)

通过芯片在两种测试中的测试结果,建立正则化逻辑回归算法模型,来决定芯片是否通过测试(拥有过去芯片测试的数据集)

一、导入库和数据集

import numpy as np
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
matplotlib.rcParams['font.sans-serif']=['SimHei']#用黑体显示中文
matplotlib.rcParams['axes.unicode_minus']=False # 可以显示负号
df=pd.read_csv('C:/Users/Administrator/AppData/Local/Temp/Temp1_machine-learning-ex2.zip/machine-learning-ex2/ex2/ex2data2.txt',
              names=['测试一','测试二','接受'])

在这里插入图片描述

二、可视化

positive=df[df['接受'].isin([1])]
negetive=df[df['接受'].isin([0])]
fig,ax=plt.subplots(figsize=(8,5))
ax.scatter(positive['测试一'],positive['测试二'],label='接受')
ax.scatter(negetive['测试一'],negetive['测试二'],marker='x',label='未接受')
box=ax.get_position()
ax.set_position([box.x0,box.y0,box.width,box.height*0.8])
ax.legend(loc='center left',bbox_to_anchor=(0.2,1.12),ncol=3)
ax.set_xlabel('测试一')
ax.set_ylabel('测试二')
plt.show()

结果为
在这里插入图片描述
*由图可以发现,该数据集没有线性的决策边界,所以不能直接用logistic回归(theta.T X=0得到的是线性的决策边界)

三、特征映射

为了能很好的拟合,所以我们要进行特征映射,从而得到非线性的决策边
1.定义特征映射函数

def feature_mapping(x1,x2,power):
    data={}
    for i in np.arange(power+1):
        for p in np.arange(i+1):
            data["f{}{}".format(i-p,p)]=np.power(x1,i-p)*np.power(x2,p)
    return pd.DataFrame(data)

与下边的等价

def feature_mapping(x1,x2,power):
    data={"f{}{}".format(i-p,p):np.power(x1,i-p)*np.power(x2,p)
          for i in np.arange(power+1)
          for p in np.arange(i+1)}
    return pd.DataFrame(data)

2.将特征变量进行特征映射

x1=df['测试一']
x1=x1.values
x2=df['测试二']
x2=x2.values
df2=feature_mapping(x1,x2,6)

在这里插入图片描述
x 1 , x 2 x_1,x_2 x1,x2经映射变为: 1 , x 1 , x 2 , x 1 2 , x 2 2 , x 1 x 2 , x 1 3 , x 2 3 , x 1 2 x 2 , x 1 x 2 2 , x 1 4 , x 2 4 , x 1 2 x 2 2 , x 1 3 x 2 , x 1 x 2 3 , x 1 5 , x 2 5 , x 1 4 x 2 , x 1 x 2 4 , x 1 3 x 2 2 , x 1 2 x 2 3 , x 1 6 , x 2 6 , x 1 5 x 2 , x 1 x 2 5 , x 1 4 x 2 2 , x 1 2 x 2 4 , x 1 3 x 2 3 1,\quad x_1,x_2,\quad x_1^2,x_2^2,x_1x_2,\quad x_1^3,x_2^3,x_1^2x_2,x_1x_2^2,\quad x_1^4,x_2^4,x_1^2x_2^2,x_1^3x_2,x_1x_2^3,\quad x_1^5,x_2^5,x_1^4x_2,x_1x_2^4,x_1^3x_2^2,x_1^2x_2^3,\quad x_1^6,x_2^6,x_1^5x_2,x_1x_2^5,x_1^4x_2^2,x_1^2x_2^4,x_1^3x_2^3 1,x1,x2,x12,x22,x1x2,x13,x23,x12x2,x1x22,x14,x24,x12x22,x13x2,x1x23,x15,x25,x14x2,x1x24,x13x22,x12x23,x16,x26,x15x2,x1x25,x14x22,x12x24,x13x23
3.重新选取变量

X=df2.values  # 将特征映射后得到的变量定义为X
y=df['接受'].values
theta=np.zeros(X.shape[1])

在这里插入图片描述
注意:
特征映射将低维特征向量(本例中为二维)转化为高维特征向量(本例中为28维),因为特征向量的个数变多,所以需要用正则化,否则容易出现过拟合。

四、正则化logistic回归

正则化后的代价函数:
在这里插入图片描述
1.正则化后的代价函数

#定义sigmoid函数
def sigmoid(z):
    return 1/(1+np.exp(-z))
#定义代价函数
def cost(theta,X,y):
    first=y@np.log(sigmoid(X@theta))
    second=(1-y)@np.log(1-sigmoid(X@theta))
    return (first+second)/(-len(X))
#定义正则化代价函数
def costReg(theta,X,y,lam=1):
    _theta=theta[1:]
    reg=(lam/(2*len(X)))*(_theta@_theta)
    return cost(theta,X,y)+reg
 
costReg(theta,X,y)    # 0.6931471805599454

2.定义正则化后的梯度函数(偏导数)

def gradient(theta,X,y):
    return (X.T@(sigmoid(X@theta)-y))/(len(X))
def gradientReg(theta,X,y,lam=1):
    reg=(lam/len(X))*theta
    reg[0]=0    # 第一项没有惩罚因子
    return gradient(theta,X,y)+reg
(gradientReg(theta,X,y)).shape   #(28,)

在这里插入图片描述
3.使用高级优化算法

import scipy.optimize as opt
result=opt.fmin_tnc(func=costReg,x0=theta,fprime=gradientReg,args=(X,y,2))

在这里插入图片描述
与下边是等价的

opt.minimize(fun=costReg,x0=theta,args=(X,y,2),method='TNC',jac=gradientReg)

在这里插入图片描述

4.定义预测函数,将求得的参数finally_theta和X(特征映射后的)带入预测函数中,并计算预测精度

def predict(theta,X):
    probability=sigmoid(X@theta)
    return [1 if x>=0.5 else 0 for x in probability ]
finally_theta=result[0]
predictions=predict(finally_theta,X)
correct=[1 if a==b else 0 for (a,b) in zip(predictions,y)]
accuracy=sum(correct)/len(X)
accuracy     # 0.8305084745762712

或者用sklearn中的方法进行评估

from sklearn.metrics import classification_report 
print(classification_report(predictions,y))

结果如下:
在这里插入图片描述
5.决策边界

x = np.linspace(-1, 1.5, 250)
xx, yy = np.meshgrid(x, x)   #生成网格点坐标矩阵
# 得到的xx,yy是array形式,维度为(250,250)
z = feature_mapping(xx.ravel(), yy.ravel(), 6).values  # xx.ravel()将xx一维化(62500,)
z = z @ finally_theta  #z.shape (62500,)
z = z.reshape(xx.shape)

fig,ax=plt.subplots(figsize=(8,6))
ax.scatter(positive['测试一'],positive['测试二'],label='接受')
ax.scatter(negetive['测试一'],negetive['测试二'],marker='x',label='未接受')
# 设置图例显示在图的上方
box = ax.get_position()
ax.set_position([box.x0,box.y0,box.width,box.height*0.8])
ax.legend(loc='center left',bbox_to_anchor=(0.2,1.12),ncol=3)
ax.set_xlabel('测试一')
ax.set_ylabel('测试二')
ax.set_title('决策边界lambda为2')
plt.contour(xx,yy,z,0) # 生成等高线,0是指图像一分为二
plt.show()

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值