Regularization(Ridged Regression) & Cross Validation

2016-04-15 Borg 更多博文 » 博客 » GitHub »

数据分析 回归分析 笔记

原文链接 https://bigborg.github.io/2016/04/15/note-ml-course2-week4/
注:以下为加速网络访问所做的原文缓存,经过重新格式化,可能存在格式方面的问题,或偶有遗漏信息,请以原文为准。


Regularization

上周已经讲了overfitting,那么当我们所有的数据量特别大的时候,即使有很多个特征模型也很难overfit。
quote

当模型overfit的时候,weights会变得很大,因此如果各个特征都很重要不可去除,可以通过减小weights来减弱overfitting的程度。那么如何衡量w是否过大?可以用w的绝对值相加或者用w的平方相加,注意不能直接把w相加,因为w可能为绝对值很大的负值和正值,这样会相互抵消。 quote

cost function

于是我们训练的时候可以重新定义cost function,通过优化新定义的cost function找到平衡RSS和weights的数量级的模型。 quote

lambda

lambda(不知道是不是这样打)的取值对weights的影响,当lambda越大,weights越来越小,相当于模型的复杂度越来越低,相应的bias越大,variance越小。 quote
quote

把cost function写成矩阵形式如下: quote

gradient of ridged regression cost

和先前的一样的计算方法求导,得出gradient如下 quote

option1: closed-form

法一:直接让gradient等于0,求得最优解 quote
最后的解如下,当lambda大于0时括号内的矩阵总是可逆 quote

option2: gradient descent

法二: 原理和没有regularization的回归模型一样。 quote
在同一次descent中,还是一个一个feature地优化。 quote
代码差不多如下: quote

intercept

一般不regularize intercept,对于closed-form就如下 quote
而对于gradient descent就是在计算partial derivative的时候判断下是不是constant feature,是的话用之前的方法计算。代码大致如下: quote
其实还有种方法,就是预处理原始的数据,使之具有值为0的期望值。

Cross Validation

当数据量很少不够分出足够的validation data的时候可以使用cross validation,即把数据随机分成K份,拿出一份作为validation,这样循环把每一份都拿出来一次,最后取平均的validation error来衡量lambda参数(当然也可以用于优化其它参数如degree)。 quote
quote
quote

不过该方法的缺点是计算量大。 quote

Code

编程时特别要注意使用corss validation之前需要把数据打乱,才能实现随机分配数据为K份。

train_valid_shuffled = graphlab.toolkits.cross_validation.shuffle(train_valid, random_seed=1)

还有regularization用graphlab可以直接在create里设置lambda的值,即l2_penalty。

model=graphlab.linear_regression.create( training_set, l2_penalty=l2_penalty, features=features_list, target=output_name, validation_set=None, verbose=False)

特别注意下标,python的下标是从0开始,最后一位不包括。如range(0,5)实际是[0,1,2,3,4]。在冒号运算中也是如此,如data[3:9]实际9号元素不包括,和R,MATLAB不一样。所以在cross validation的时候要注意每一份开始和结束的位置。corss validation代码如下

def k_fold_cross_validation(k, l2_penalty, data, output_name, features_list): errors=[] for i in xrange(k): start=n*i/k end=n*(i+1)/k-1 validation_set=data[start:end+1] training_set=data[0:start].append(data[end+1:n]) model=graphlab.linear_regression.create( training_set, l2_penalty=l2_penalty, features=features_list, target=output_name, validation_set=None, verbose=False) validation_error=sum((validation_set[output_name]-model.predict(validation_set))2)/len(validation_set) #注意此处不需要加+sum(model.get("coefficients")['value']2),题目要求是validation error #并且该式是在训练模型的时候用于优化带该式的cost fucntion以防止overfitting的,而现在是用validation进行评估 #评估阶段不需要加上该式! errors.append(validation_error)
validation_error=sum(errors)/k
return validation_error,model