吴恩达第五次作业

该作是第五次的机器学习的编程作业,为了看看数据有没有高偏差或者高方差


import numpy as np
import scipy.io as sio
import scipy.optimize as opt
import pandas as pd
import matplotlib.pyplot as plt
def load_data():#运用scipy来加载matlab的数据
    data=sio.loadmat("ex5data1.mat")
    #map函数的作用是将第一个参数作用到第二个参数中,也就是将这些数据变为一维矩阵
    return map(np.ravel,[data['X'],data['y'],data['Xtest'],data['ytest'],data['Xval'],data['yval']])
#顺带一提 pd.DateFrame中的向量是一维的,他很难去构建一个二维向量
X,y,Xtest,ytest,Xval,yval=load_data()
fig,ax=plt.subplots(figsize=(12,8))
ax.scatter(X,y,c='r',)
ax.set_ylabel('flow')
ax.set_xlabel('water')
plt.show()
#往里面加入常数项,增加一个特征变量,采用np.insert(插入的向量(不能为一维),插入的位置,插入的数值,插入行还是列)
X,Xtest,Xval=[np.insert(x.reshape(x.shape[0],1),0,np.ones(x.shape[0]),axis=1) for x in (X,Xtest,Xval)]
#代价函数的非正则化形式
def cost(theta,X,y):
    m=X.shape[0]
    j=X@theta-y
    square=j.T@j
    return square/(2*m)
#向量梯度的非正则化形式,运用的是向量乘积的形式
def grident(theta,X,y):
    result=X.T@(X@theta-y)
    return result/X.shape[0]
#向量梯度的正则化形式,第一项的常数项不需要正则化所以复制theta矩阵,并设theta[0】=0
def regulised_grident(theta,X,y,l=1):
    m=X.shape[0]
    regulised_result=theta.copy()
    regulised_result[0]=0
    regulised_result=(l/m)*theta
    return grident(theta,X,y)+regulised_result
#代价函数的正则化形式,同样常数项不需要正则化,但计算的时候也是需要带入,所以不直接取0值
def regulised_cost(theta,X,y,l=1):
    m=X.shape[0]
    regulised_reg=(l/(2*m))*np.power(theta[1:],2).sum()
    return cost(theta,X,y)+regulised_reg
theta=np.ones(X.shape[1])
print(grident(theta,X,y))
#掉包侠,带入梯度的一步步长,以及正则化代价函数
#注意minmize中的y需要为一维向量
def minmize(X,y,l=1):
    theta=np.ones(X.shape[1])
    res=opt.minimize(fun=regulised_cost,x0=theta,jac=regulised_grident,args=(X,y,l),method='TNC')
    return res
#最后计算出来的theta矩阵
final_theta=minmize(X,y,l=0).get('x')
a=final_theta[0]
b=final_theta[1]
plt.scatter(X[:,1],y,label="training data",c='r')
plt.plot(X[:,1],X[:,1]*b+a,label='precision')
plt.legend('best')
plt.show()
train_cost,cv_cosr=[],[];
m=X.shape[0];
#for循环的目的主要是看随着样本的增加,看看训练集代价和交错训练集代价的关系
for i in range(1,m+1):
    res=minmize(X[:i,:],y[:i],l=0)
    tc=regulised_cost(res.x,X[:i,:],y[:i],l=0)
    tv=regulised_cost(res.x,Xval,yval,l=0)
    train_cost.append(tc)
    cv_cosr.append(tv)
#注意arrange函数起始从第一个参数开始但是不包括最后一个函数
plt.plot(np.arange(1,m+1),train_cost,c='r',label="train cost")
plt.plot(np.arange(1,m+1),cv_cosr,label="cv_cost")
plt.legend('best')
plt.show()
#这个函数的主要作用就是将增加特征的数量,power的作用就是将
def expand_feature(X,power,as_ndarray=False):
    data={"f{}".format(i):np.power(X,i) for i in range(1,power+1) }
    df=pd.DataFrame(data)
    return df.values if as_ndarray else df
X,y,Xtest,ytest,Xval,yval=load_data()
print(expand_feature(X,3))
#准备多项式的回归
#为了最大程度减少某些特征对于代价函数的影响,我们将特征归一化
def normalize_function(df):
    #apply函数作用是对Dataframe中的数据进行处理,lambda可以看作是一个函数,函数返回column
    return df.apply(lambda column:(column-column.mean())/column.std())
#这个函数的作用是为了能将特征增加作用在X,Xval上
def prepare_ploydate(*args,powers):
    def prepare(x):
        df=expand_feature(x,powers)
        nndf=normalize_function(df).values
        return np.insert(nndf,0,np.ones(nndf.shape[0]),axis=1)
    return [prepare(x) for x in args]
Xn,Xnval,Xntest=prepare_ploydate(X,Xval,Xtest,powers=8)
def plot_learning(X,y,Xval,yval,l=0):
#这个函数编写的主要目的是想看看求出来的theta矩阵参数作用在训练集上的代价与交叉集代价的区别
    train_cost,cv_cost=[],[]
    m=X.shape[0]
    for i in range(1,m+1):
        res=minmize(X[:i,:],y[:i],l=l)
        tc=cost(res.x,X[:i,:],y[:i])
        cc=cost(res.x,Xval,yval)
        train_cost.append(tc)
        cv_cost.append(cc)
    plt.plot(np.arange(1,m+1),train_cost,label="train_cost")
    plt.plot(np.arange(1,m+1),cv_cost,label="cv_cost")
    plt.legend(loc=1)
#从图中可以看到交互集有着非常高的代价,但是随着加入的样本的增多,能显著减少代价,属于高偏差
plot_learning(Xn,y,Xnval,yval,l=100)
plt.show()
train_cost,cv_cost=[],[]
#为了找出最好的惩罚函数,我们假设几个惩罚函数
candidate=[0,0.001,0.003,0.3,0.5,1,10]
for i in candidate:
    res=minmize(Xn,y,l=i)
    tc=cost(res.x,Xn,y)
    cc=cost(res.x,Xnval,yval)
    train_cost.append(tc)
    cv_cost.append(cc)
for i in candidate:
    theta=minmize(Xn,y,i).x
    print('cosr(l={})={}'.format(i,cost(theta,Xntest,ytest)))


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值