吴恩达-机器学习课后题02-线性不可分

一、题目

设想你是工厂的生产主管,你有一些芯片在两次测试中的测试结果。对于这两次测试,你想决定是否芯片要被接受或抛弃
数据集:ex2data2.txt

2、解题

1、导入数据

data = pd.read_csv(path,names=['test 1','test 2','Accepted'])
print(data.head())

使用data.head() 查看数据是否正确,表头是否添加

2、可视化数据

#数据可视化
fig,ax = plt.subplots()
ax.scatter(data[data['Accepted']==0]['test 1'],data[data['Accepted']==0]['test 2'],c='r',marker='x')
ax.scatter(data['test 1'][data['Accepted']==1],data['test 2'][data['Accepted']==1],c='b',marker='o')
ax.plot()
plt.show()

将内部点全部分为通过和未通过两部分使用不同的方式绘制在散点图上
在这里插入图片描述
可以看出数据大致是线性不可分的情况

3、特征映射(*与线性可分不同,需要更高的维度进行计算)
需要将x1,x2生成更高次幂的数据,然后再进行计算

def feature_mapping(x1,x2,power):
    dic = {}
    #通过双重循环,设置映射集
    for i in np.arange(power+1):#0~power
        for j in np.arange(i+1):
            #将生成的映射放到dic中,对每个dic起一个名字 F**
            dic['F{}{}'.format(i-j,j)]=np.power(x1,i-j)*np.power(x2,j)
    return pd.DataFrame(dic)#转成DataFream格式
#测试
x1 = data['test 1']
# print('x1=',x1)
x2 = data['test 2']
# print('x2=',x2)
dic = feature_mapping(x1,x2,6)
# print(dic.head())

4、构造数据集(注意数据集是从特征映射的集合中取值)

X = dic
X = X.values
print(X.shape)
y = data.iloc[:,-1]
y = y.values
y = y.reshape(len(y),1)

5、构造代价函数(注意,增加了正则化项)
代价函数公式:
在这里插入图片描述
Lamda 越小,越易过拟合
Lamda越大,越易欠拟合

#创建sigmoid函数
def sigmoid(z):
    return 1/(1+np.exp(-z))
#代价函数,与之前的相比,加入了正则化项
def costFunction(X,y,theta,lamda):
    A = sigmoid(X@theta)
    first = y*np.log(A)
    second = (1-y)*np.log(1-A)
    reg = np.sum(np.power(theta[1:],2))/(lamda*(2*len(X))) #正则化项
    return -np.sum(first+second)/len(X)+reg
#测试代价函数
theta = np.zeros((28,1))
lamda = 1
cost_init = costFunction(X,y,theta,lamda)
print(cost_init)

6、构造梯度下降函数:
在这里插入图片描述
由于函数在正常函数之后加入了正则化项,所以梯度下降函数也要做出相应的改动

def gradientDescent(X, y, alpha, theta, iters, lamda):
    costs = []
    for i in range(iters):
        # 插入正则化项:
        reg = theta[1:] * (lamda / len(X))
        # 因为reg是(27,1)而theta是(28,1)所以要在第一行插入(0)
        reg = np.insert(reg, 0, values=0, axis=0)  # 注意语法
        A = sigmoid(X @ theta)
        theta = theta -  (X.T @ (sigmoid(X @ theta) - y))*alpha / len(X) - reg
        cost = costFunction(X, y, theta, lamda)
        costs.append(cost)
        if i % 10000 == 0:
            print(cost)
    return costs, theta

计算得出theta数值和对应的代价函数序列
查看计算结果:

#梯度下降
theta = np.zeros((28,1))
alpha = 0.001
iters = 200000
lamda = 0.001
costs,theta_final = gradientDescent(X,y,alpha,theta,iters,lamda)
print(theta_final)

初始这只theta维度和X行维度相同,alpha以及lamda为0.001,迭代200000次计算得出最终结果

7、将结果以及数据一起展示出来:

x = np.linspace(-1.2,1.2,200)#在-1.2-1.2之间生成200个点
xx,yy = np.meshgrid(x,x) #将xx,yy定义为200*200的网格
z = feature_mapping(xx.ravel(),yy.ravel(),6).values #将xx,yy中的数据转为一位数组,并将xx,yy进行映射
zz = z@theta_final #映射之后进行计算曲线
zz = zz.reshape(xx.shape)#维度更新
fig,ax = plt.subplots()
ax.scatter(data[data['Accepted']==0]['test 1'],data[data['Accepted']==0]['test 2'],c='r',marker='x')
ax.scatter(data[data['Accepted']==1]['test 1'],data['test 2'][data['Accepted']==1],c='b',marker='o')
plt.contour(xx,yy,zz,0)#绘制三维图像,xyz三个轴选择最内层
plt.show()

注意此图是xx、yy经过特征映射得到z之后运算得到zz得到一条线为边界线

结果:
在这里插入图片描述

总体代码:

# Python TR
# Time:2020/12/11 8:29 下午
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

#导入数据
path = '/Users/fengxiaolin/Library/Containers/com.kingsoft.wpsoffice.mac/Data/Library/Application Support/Kingsoft/WPS Cloud Files/userdata/qing/filecache/唐荣的云文档/00000研究生/机器学习/课后题资料/02-logistic_regression/ex2data2.txt'
data = pd.read_csv(path,names=['test 1','test 2','Accepted'])
print(data.head())
#数据可视化


#特征映射
def feature_mapping(x1,x2,power):
    dic = {}
    #通过双重循环,设置映射集
    for i in np.arange(power+1):#0~power
        for j in np.arange(i+1):
            #将生成的映射放到dic中,对每个dic起一个名字 F**
            dic['F{}{}'.format(i-j,j)]=np.power(x1,i-j)*np.power(x2,j)
    return pd.DataFrame(dic)#转成DataFream格式
#测试
x1 = data['test 1']
# print('x1=',x1)
x2 = data['test 2']
# print('x2=',x2)
dic = feature_mapping(x1,x2,6)
# print(dic.head())

#构造数据集
X = dic
X = X.values
print(X.shape)
y = data.iloc[:,-1]
y = y.values
y = y.reshape(len(y),1)

#创建sigmoid函数
def sigmoid(z):
    return 1/(1+np.exp(-z))

#代价函数,与之前的相比,加入了正则化项
def costFunction(X,y,theta,lamda):
    A = sigmoid(X@theta)
    first = y*np.log(A)
    second = (1-y)*np.log(1-A)
    reg = np.sum(np.power(theta[1:],2))*(lamda/(2*len(X))) #正则化项
    return -np.sum(first+second)/len(X)+reg
#测试代价函数
theta = np.zeros((28,1))
lamda = 1
cost_init = costFunction(X,y,theta,lamda)
# print(cost_init)


def gradientDescent(X, y, alpha, theta, iters, lamda):
    costs = []
    for i in range(iters):

        # 插入正则化项:
        reg = theta[1:] * (lamda / len(X))
        # 因为reg是(27,1)而theta是(28,1)所以要在第一行插入(0)
        reg = np.insert(reg, 0, values=0, axis=0)  # 注意语法

        A = sigmoid(X @ theta)
        theta = theta -  (X.T @ (sigmoid(X @ theta) - y))*alpha / len(X) - reg
        cost = costFunction(X, y, theta, lamda)
        costs.append(cost)
        if i % 10000 == 0:
            print(cost)
    return costs, theta

#梯度下降
theta = np.zeros((28,1))
alpha = 0.001
iters = 200000
lamda = 0.001
costs,theta_final = gradientDescent(X,y,alpha,theta,iters,lamda)
print(theta_final)



x = np.linspace(-1.2,1.2,200)#在-1.2-1.2之间生成200个点
xx,yy = np.meshgrid(x,x) #将xx,yy定义为200*200的网格
z = feature_mapping(xx.ravel(),yy.ravel(),6).values #将xx,yy中的数据转为一位数组,并将xx,yy进行映射
zz = z@theta_final #映射之后进行计算曲线
zz = zz.reshape(xx.shape)#维度更新
fig,ax = plt.subplots()
ax.scatter(data[data['Accepted']==0]['test 1'],data[data['Accepted']==0]['test 2'],c='r',marker='x')
ax.scatter(data[data['Accepted']==1]['test 1'],data['test 2'][data['Accepted']==1],c='b',marker='o')
plt.contour(xx,yy,zz,0)#绘制三维图像,xyz三个轴选择最内层
plt.show()

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值