装修平台网站排名前十名有哪些,阳江市人才最新招聘网,5118关键词挖掘工具,做前端常用的网站及软件版权说明#xff1a;本公号转载文章旨在学习交流#xff0c;不用于任何商业用途#xff0c;版权归原作者所有#xff0c;如有异议#xff0c;敬请后台联络我们#xff0c;议定合作或删除#xff0c;我们将第一时间按版权法规定妥善处理#xff0c;非常感谢#xff01;… 版权说明本公号转载文章旨在学习交流不用于任何商业用途版权归原作者所有如有异议敬请后台联络我们议定合作或删除我们将第一时间按版权法规定妥善处理非常感谢Python机器学习算法实现Authorlouwill本节我们要介绍的是基于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 npimport 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 0 return w, b定义符号函数并进行向量化用于对L1正则化项的梯度计算# 定义符号函数def sign(x): if x 0: return 1 elif x 0: return -1 else: 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) b loss 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_train return y_hat, loss, dw, db定义Lasso训练过程函数# 定义训练过程def lasso_train(X, y, learning_rate0.01, epochs300): 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 * dw b -learning_rate * db loss_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 npfrom sklearn.metrics import r2_scoreclass Lasso(): def __init__(self): pass def 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_test def initialize_params(self, dims): w np.zeros((dims, 1)) b 0 return w, b def sign(self, x): if x 0: return 1 elif x 0: return -1 else: return 0 def l1_loss(self, X, y, w, b, alpha): num_train X.shape[0] num_feature X.shape[1] y_hat np.dot(X, w) b loss 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_train return y_hat, loss, dw, db def 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 * dw b -learning_rate * db loss_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, grads def predict(self, X, params): w params[w] b params[b] y_pred np.dot(X, w) b return y_pred if __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(alpha0.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/