Python机器学习算法实现

Author:louwill

第13讲和第14讲我们来关注一下回归模型的两个变种模型。本节我们要介绍的是基于L1正则化的Lasso模型,下一节介绍基于L2正则化的Ridge模型。在正式介绍这两种模型之前,笔者还是想带大家复习一下过拟合和正则化等机器学习关键问题。

正则化与L1范数

正则化是防止模型过拟合的核心技术之一,关于欠拟合和过拟合的问题,这里笔者就不再展开来说,不了解的朋友可以看看笔者很早之前写的一篇文章:谈谈过拟合。

总的来说,监督机器学习的核心原理莫过于如下公式:

该公式可谓是机器学习中最核心最关键最能概述监督学习的核心思想的公式了:所有的有监督机器学习,无非就是正则化参数的同时最小化经验误差函数。最小化经验误差是为了极大程度的拟合训练数据,正则化参数是为了防止过分的拟合训练数据。你看,多么简约数学哲学。正如之前所说,监督机器学习是为了让我们建立的模型能够发现数据中普遍的一般的规律,这个普遍的一般的规律无论对于训练集还是未知的测试集,都具有较好的拟合性能。

继续回到公式。第一项经验误差函数在机器学习中无疑地位重要,但它不是笔者今天要讲的,今天要讲的是公式的第二项:正则化项。第二项中 λ 为正则化系数,通常是大于 0 的,是一种调整经验误差项和正则化项之间关系的系数。λ = 0 时相当于该公式没有正则化项,模型全力讨好第一项,将经验误差进行最小化,往往这也是最容易发生过拟合的时候。随着 λ 逐渐增大,正则化项在模型选择中的话语权越来越高,对模型的复杂性的惩罚也越来越厉害。所以,在实际的训练过程中,λ 作为一种超参数很大程度上决定了模型生死。

系数 λ 说完了,然后就是正则化项,正则化项形式有很多,但常见的也就是 L1 和 L2 正则化。本节我们先来看L1。

在说常见的 L1 和 L2 之前,先来看一下 L0 正则化。L0 正则化也就是 L0 范数,即矩阵中所有非 0 元素的个数。如何我们在正则化过程中选择了 L0 范数,那该如何理解这个 L0 呢?其实非常简单,L0 范数就是希望要正则化的参数矩阵 W 大多数元素都为 0。如此简单粗暴,让参数矩阵 W 大多数元素为 0 就是实现稀疏而已。说到这里,权且打住,想必同样在机器学习领域摸爬滚打的你一定想问,据我所知稀疏性不通常都是用 L1 来实现的吗?这里个中缘由笔者不去细讲了,简单说结论:在机器学习领域,L0 和 L1 都可以实现矩阵的稀疏性,但在实践中,L1 要比 L0 具备更好的泛化求解特性而广受青睐。先说了 L1,但还没解释 L1 范数是什么,L1 范数就是矩阵中各元素绝对值之和,正如前述所言,L1 范数通常用于实现参数矩阵的稀疏性。至于为啥要稀疏,稀疏有什么用,通常是为了特征选择和易于解释方面的考虑。

Lasso

Lasso的全称叫做Least absolute shrinkage and selection operator,直译过来为最小收缩与选择算子。其本质就是在常规的线性回归的基础上对参数加了一个L1正则化约束。其形式如下所示:

规约到线性回归模型上,上式的第一项就是MSE损失,第二项则是L1正则化项。我们同样按照之前线性回归的打法来对其进行实现,只是需要注意一下L1正则化项的求导处理。我们来看具体的实现代码。

导入相关package并读入示例数据:

import numpy as np
import pandas as pddata = np.genfromtxt('mystery.dat', delimiter = ',')
# 选择特征与标签
x = data[:,0:100]
y = data[:,100].reshape(-1,1)
# 加一列
X = np.column_stack((np.ones((x.shape[0],1)),x))# 划分训练集与测试集
X_train, y_train = X[:70], y[:70]
X_test, y_test = X[70:], y[70:]
print(X_train.shape, y_train.shape, X_test.shape, y_test.shape)

定义参数初始化函数:

# 定义参数初始化函数
def initialize(dims):w = np.zeros((dims, 1))b = 0return w, b

定义符号函数并进行向量化,用于对L1正则化项的梯度计算:

# 定义符号函数
def sign(x):if x > 0:return 1elif x < 0:return -1else:return 0# 利用numpy对符号函数进行向量化
vec_sign = np.vectorize(sign)
vec_sign(np.zeros((3,1)))

在MSE损失函数的基础上定义Lasso损失:

# 定义lasso损失函数
def l1_loss(X, y, w, b, alpha):num_train = X.shape[0]num_feature = X.shape[1]y_hat = np.dot(X, w) + bloss = np.sum((y_hat-y)**2)/num_train + np.sum(alpha*abs(w))dw = np.dot(X.T, (y_hat-y)) /num_train + alpha * vec_sign(w)db = np.sum((y_hat-y)) /num_trainreturn y_hat, loss, dw, db

定义Lasso训练过程函数:

# 定义训练过程
def lasso_train(X, y, learning_rate=0.01, epochs=300):loss_list = []w, b = initialize(X.shape[1])for i in range(1, epochs):y_hat, loss, dw, db = l1_loss(X, y, w, b, 0.1)w += -learning_rate * dwb += -learning_rate * dbloss_list.append(loss)if i % 50 == 0:print('epoch %d loss %f' % (i, loss))params = {'w': w,'b': b}grads = {'dw': dw,'db': db}return loss, loss_list, params, grads

执行训练:

# 执行训练示例
loss, loss_list, params, grads = lasso_train(X_train, y_train, 0.01, 500)

可以看到,在L1的约束下,在训练过程中有不少对标签贡献率低的特征的系数都变成了0。这就是L1的作用,一定程度上可以进行特征选择和实现稀疏化。

最后可以简单写一个Lasso回归的class来对上述过程进行封装:

import numpy as np
from sklearn.metrics import r2_scoreclass Lasso():def __init__(self):passdef prepare_data(self):data = np.genfromtxt('./example.dat', delimiter = ',')x = data[:, 0:100]y = data[:, 100].reshape(-1, 1)X = np.column_stack((np.ones((x.shape[0], 1)), x))X_train, y_train = X[:70], y[:70]X_test, y_test = X[70:], y[70:]return X_train, y_train, X_test, y_testdef initialize_params(self, dims):w = np.zeros((dims, 1))b = 0return w, bdef sign(self, x):if x > 0:return 1elif x < 0:return -1else:return 0def l1_loss(self, X, y, w, b, alpha):num_train = X.shape[0]num_feature = X.shape[1]y_hat = np.dot(X, w) + bloss = np.sum((y_hat - y) ** 2) / num_train + np.sum(alpha*abs(w))dw = np.dot(X.T, (y_hat - y)) / num_train + alpha*np.vectorize(self.sign)(w)db = np.sum((y_hat - y)) / num_trainreturn y_hat, loss, dw, dbdef lasso_train(self, X, y, learning_rate, epochs):loss_list = []w, b = self.initialize_params(X.shape[1])for i in range(1, epochs):y_hat, loss, dw, db = self.l1_loss(X, y, w, b, 0.1)w += -learning_rate * dwb += -learning_rate * dbloss_list.append(loss)if i % 300 == 0:print('epoch %d loss %f' % (i, loss))params = {'w': w,'b': b}grads = {'dw': dw,'db': db}return loss, loss_list, params, gradsdef predict(self, X, params):w = params['w']b = params['b']y_pred = np.dot(X, w) + breturn y_predif __name__ == '__main__':lasso = Lasso()X_train, y_train, X_test, y_test = lasso.prepare_data()loss, loss_list, params, grads = lasso.lasso_train(X_train, y_train, 0.01, 3000)print(params)y_pred = lasso.predict(X_test, params)print(r2_score(y_test, y_pred))

以上是基于numpy的手动实现Lasso的过程,下面再来看Lasso在sklearn中的实现。

# 导入线性模型模块
from sklearn import linear_model
# 创建lasso模型实例
sk_lasso = linear_model.Lasso(alpha=0.1)
# 对训练集进行拟合
sk_lasso.fit(X_train, y_train)
# 打印模型相关系数
print("sklearn Lasso intercept :", sk_lasso.intercept_)
print("\nsklearn Lasso coefficients :\n", sk_lasso.coef_)
print("\nsklearn Lasso number of iterations :", sk_lasso.n_iter_)

以上就是本节内容,下一节我们继续来看基于L2正则化的Ridge回归。

更多内容可参考笔者GitHub地址:

https://github.com/luwill/machine-learning-code-writing

参考资料:

https://www.analyticsvidhya.com/blog/2017/06/a-comprehensive-guide-for-linear-ridge-and-lasso-regression/

往期精彩:

数学推导+纯Python实现机器学习算法10:线性不可分支持向量机

数学推导+纯Python实现机器学习算法8-9:线性可分支持向量机和线性支持向量机

数学推导+纯Python实现机器学习算法6:感知机

数学推导+纯Python实现机器学习算法5:决策树之CART算法

数学推导+纯Python实现机器学习算法4:决策树之ID3算法

数学推导+纯Python实现机器学习算法3:k近邻

数学推导+纯Python实现机器学习算法2:逻辑回归

数学推导+纯Python实现机器学习算法1:线性回归

往期精彩回顾适合初学者入门人工智能的路线及资料下载机器学习及深度学习笔记等资料打印机器学习在线手册深度学习笔记专辑《统计学习方法》的代码复现专辑
AI基础下载机器学习的数学基础专辑获取一折本站知识星球优惠券,复制链接直接打开:https://t.zsxq.com/yFQV7am本站qq群1003271085。加入微信群请扫码进群:

【机器学习基础】数学推导+纯Python实现机器学习算法13:Lasso回归相关推荐

  1. 【机器学习基础】数学推导+纯Python实现机器学习算法30:系列总结与感悟

    Python机器学习算法实现 Author:louwill Machine Learning Lab 终于到了最后的总结.从第一篇线性回归的文章开始到现在,已经接近有两年的时间了.当然,也不是纯写这3 ...

  2. 【机器学习基础】数学推导+纯Python实现机器学习算法24:HMM隐马尔可夫模型

    Python机器学习算法实现 Author:louwill Machine Learning Lab HMM(Hidden Markov Model)也就是隐马尔可夫模型,是一种由隐藏的马尔可夫链随机 ...

  3. 【机器学习基础】数学推导+纯Python实现机器学习算法28:CRF条件随机场

    Python机器学习算法实现 Author:louwill Machine Learning Lab 本文我们来看一下条件随机场(Conditional Random Field,CRF)模型.作为概 ...

  4. 【机器学习基础】数学推导+纯Python实现机器学习算法27:EM算法

    Python机器学习算法实现 Author:louwill Machine Learning Lab 从本篇开始,整个机器学习系列还剩下最后三篇涉及导概率模型的文章,分别是EM算法.CRF条件随机场和 ...

  5. 【机器学习基础】数学推导+纯Python实现机器学习算法26:随机森林

    Python机器学习算法实现 Author:louwill Machine Learning Lab 自从第14篇文章结束,所有的单模型基本就讲完了.而后我们进入了集成学习的系列,整整花了5篇文章的篇 ...

  6. 【机器学习基础】数学推导+纯Python实现机器学习算法25:CatBoost

    Python机器学习算法实现 Author:louwill Machine Learning Lab 本文介绍GBDT系列的最后一个强大的工程实现模型--CatBoost.CatBoost与XGBoo ...

  7. 【机器学习基础】数学推导+纯Python实现机器学习算法24:LightGBM

    Python机器学习算法实现 Author:louwill Machine Learning Lab 第17讲我们谈到了竞赛大杀器XGBoost,本篇我们来看一种比XGBoost还要犀利的Boosti ...

  8. 【机器学习基础】数学推导+纯Python实现机器学习算法23:kmeans聚类

    Python机器学习算法实现 Author:louwill Machine Learning Lab 聚类分析(Cluster Analysis)是一类经典的无监督学习算法.在给定样本的情况下,聚类分 ...

  9. 【机器学习基础】数学推导+纯Python实现机器学习算法22:最大熵模型

    Python机器学习算法实现 Author:louwill Machine Learning Lab 最大熵原理(Maximum Entropy Principle)是一种基于信息熵理论的一般原理,在 ...

  10. 【机器学习基础】数学推导+纯Python实现机器学习算法21:马尔可夫链蒙特卡洛...

    Python机器学习算法实现 Author:louwill Machine Learning Lab 蒙特卡洛(Monte Carlo,MC)方法作为一种统计模拟和近似计算方法,是一种通过对概率模型随 ...

最新文章

  1. 小猿圈之学习java web需要有什么基础?
  2. Nature子刊:Salmon不比对快速宏基因组基因定量
  3. SetWindowRgn注意点
  4. 依赖注入Dagger2详解
  5. linux线程同步(2)-条件变量
  6. 上海php黑名单,php判断ip黑名单程序代码实例
  7. 一天一种设计模式之六-----工厂方法模式
  8. 输入一个三位正整数,输出百位数,十位数,个位数
  9. 【Windows】XShell中使用小键盘和ALT键(作Meta键),使BackSpace正常
  10. 网络发展之网络电话应用
  11. Go语言的变量、函数、Socks5代理服务器
  12. 针对github权限导致hexo部署失败的解决方案
  13. 区块链 solidity 快排
  14. 禁用EnableViewState和启用EnableViewStat时请注意
  15. Linux下source命令详解
  16. UVALive 7461 - Separating Pebbles
  17. 计算LTE 峰值速率
  18. CSS伪元素(以:after为例)插入图片
  19. 基于安卓的掌上二手图书交易app
  20. 阿里云OSS 图片处理

热门文章

  1. 背景全透明 background: transparent
  2. 【转贴】大型ORACLE数据库优化设计方案
  3. ansible(基础)
  4. 用ASP.net判断上传文件类型的三种方法
  5. poj2318 TOYS
  6. Reflector 插件-Reflexil
  7. linux python pip卸载,Python pip的安装及卸载
  8. java正则表达式 文件后缀名_正则表达式 判断文件名后缀是否为 csv xls xlsx
  9. 记住这9点,SCI论文结果轻松写
  10. 编程语言学习--C语言学习资料