Python实现线性回归2,梯度下降算法

接上篇

4.梯度下降算法

《斯坦福大学公开课 :机器学习课程》吴恩达讲解第二课时,是直接从梯度下降开始讲解,最后采用向量和矩阵的方式推导了解析解,国内很多培训视频是先讲解析解后讲梯度下降,个人认为梯度下降算法更为重要,它是很多算法(逻辑回归、神经网络)都可以共用的,线性回归仅仅是凑巧有全局最小值的解法,有解析解,其他大部分算法都需要遍历数据寻找全局(其实本质上是局部最优)最优解的过程。
解析解直接向量运算存在的问题:(1)矩阵必须是满秩的,如果不是,python也能模糊处理。(2)运算性能,矩阵扩大化后,量级增大对性能影响明显。
梯度下降不仅限于线性回归,非线性和神经网络同样适用。

在线性回归中,θ通过α学习速率在每个J( θ) 减小的维度上进行一个 不定式 θ参数的递减,不断更新 θ{i} 的值直到 J(θ) 收敛,达到最小值。类比于下山,每次尝试找比这个位置低的位置,一步一步到达山底(即我们求的最小值,详细请看参考资料8)

4.1批量梯度下降算法

老师常常教导我们梯度下降算法这么经典的算法,一定要自己动手推导公式,自己用程序来实现以下,我一直嗤之以鼻,线性回归这么简单的算法还需要自己敲代码实现一下吗?最近工作闲暇时,我自己用Python实现了下该算法,不敲不知道,一敲吓一大跳,太多坑在里面了,整整坑在里面2天时间,检查多遍代码最后发现是数据问题,学习率α需要取非常非常小的值才能收敛,否则程序一直处于震荡状态无法找到近似最小值。说了那么多废话,下面直接贴代码,代码里备注说明很完善,很明了,很清晰了,大家应该能看懂吧o( ̄︶ ̄)o
在这里插入图片描述
在这里插入图片描述

def linearRegBgd2(x,y,alpha=0.005,lamba=0.005,loop_max=1000):#alpha = 0.0000001      #学习率步长,learning rate#lamba=0.005     #惩罚系数 '''参考链接:https://blog.csdn.net/mango_badnot/article/details/52328740 已将原作者计算过程进行了大量修改,就相当于是我原创了吧,将原计算的三重for循环重写为一重for循环,将运算修改为了矩阵运算原作者构造的X特征是按行存储的,与常见数据不太一致,X中第一行为特征1,第二行为特征2此函数将使用正常数据,X特征按列存储,每行是一条记录批量梯度下降算法公式:theta=theta + alpha * sum( (y-y_hat) * x)'''np.set_printoptions(precision=4) # 设置numpy输出4位小数n=len(x[0]) # 取第一行数据,查看数据列数theta=np.zeros(n)      # 初始化theta数组,默认全为0for times in range(loop_max):y_hat=np.dot(x,theta.T).reshape((-1,1))loss= (y_hat-y)  #此处是y_hat-y,对应的theta求解处增加了一个负号loss_n=np.array([]) # 为方便直接用矩阵实现sum( (y-y_hat) * x),产生多列loss乘以loss后求和if n==1: # 判断x矩阵有几列,列为1的时候单独处理loss_n=losselse:for i in range(1,n):# 判断x矩阵有几列,列为大于2的时候,产生n列loss#print(i)if i==1:loss_n = np.column_stack((loss, loss))elif i>1:loss_n = np.column_stack((loss_n, loss))theta_old=theta # 记录迭代前的theta#tmp=alpha*(loss_n*x).sum(axis=0)theta=theta - (alpha*(x*loss_n)).sum(axis=0) #+lamba*theta   #使用矩阵求解theta,注意此处的负号,loss*x后按特征列求和作为theta,注意上方本来想实现惩罚项的,但没有想明白怎么实现if (theta-theta_old).all()<0.001: # 判断前后两次theta变换情况,当变化率很小时跳出循环break#print('x:',x,'y:',y,'loss:',loss)#print('y_hat:',y_hat.T)#print('times:',times,'theta:',theta)#print('')return theta

4.2随机梯度下降算法

随机梯度下降就是每一个样本更新一次权值,超过样本范围就循环从第一个样本再循环,同等数据量情况下(数据量不是特别巨大时)训练速度与批量梯度下降要慢一些,但是适合在线学习,来一条数据迭代训练一次。
在这里插入图片描述

def linearRegSgd(x,y,alpha=0.005,lamba=0.005,loop_max=10000):#alpha = 0.0000001      #学习率步长,learning rate#lamba=0.005     #惩罚系数 '''随机梯度下降算法公式:theta=theta + alpha * (y-y_hat) * xalpha=0.01lamba=0.005'''np.set_printoptions(precision=4) # 设置numpy输出4位小数n=len(x[0]) # 取第一行数据,查看数据列数theta=np.zeros(n)      # 初始化theta数组,默认全为0for times in range(loop_max):for i  in range(0,len(x)): # 取其中一条数据进行梯度下降# i=0y_hat=np.dot(x[i],theta.T).reshape((-1,1))loss= (y_hat-y[i])  #此处是y_hat-y,对应的theta求解处增加了一个负号theta_old=theta # 记录迭代前的thetatheta=theta - alpha*x[i]*loss[0] #+lamba*theta#求解theta,注意此处的负号,注意上方本来想实现惩罚项的,但没有想明白怎么实现if (theta-theta_old).all()<0.001: # 判断前后两次theta变换情况,当变化率很小时跳出循环break
#            print('x:',x,'y:',y,'loss:',loss)
#            print('y_hat:',y_hat.T)
#            print('times:',times,'theta:',theta)
#            print('')return theta

4.3 mini-batch梯度下降算法

如果不是每拿到一个样本即更改梯度,而是用若干个样本的平均梯度作为更新方向,这就是Mini-batch梯度下降算法。

def linearRegMgd(x,y,alpha=0.005,lamba=0.005,loop_max=1000,batch_size=9):#alpha = 0.0000001      #学习率步长,learning rate#lamba=0.005     #惩罚系数 '''mini-batch梯度下降算法公式:每次使用batch_size个数据进行计算for i=1 to m: theta=theta + alpha * (y-y_hat) * x'''np.set_printoptions(precision=4) # 设置numpy输出4位小数n=len(x[0]) # 取第一行数据,查看数据列数theta=np.zeros(n)      # 初始化theta数组,默认全为0for times in range(loop_max):for i in range(0,int(len(x)/batch_size)+1):#print('i:',i,x[i*batch_size:(i+1)*batch_size])x_mini=x[i*batch_size:(i+1)*batch_size]y_mini=y[i*batch_size:(i+1)*batch_size]y_hat=np.dot(x_mini,theta.T).reshape((-1,1))loss= (y_hat-y_mini)  #此处是y_hat-y,对应的theta求解处增加了一个负号loss_n=np.array([]) # 为方便直接用矩阵实现sum( (y-y_hat) * x),产生多列loss乘以loss后求和if n==1: # 判断x矩阵有几列,列为1的时候单独处理loss_n=losselse:for i in range(1,n):# 判断x矩阵有几列,列为大于2的时候,产生n列loss#print(i)if i==1:loss_n = np.column_stack((loss, loss))elif i>1:loss_n = np.column_stack((loss_n, loss))theta_old=theta # 记录迭代前的theta#tmp=alpha*(loss_n*x).sum(axis=0)theta=theta - (alpha*(x_mini*loss_n)).sum(axis=0) #+lamba*theta   #使用矩阵求解theta,注意此处的负号,loss*x后按特征列求和作为theta,注意上方本来想实现惩罚项的,但没有想明白怎么实现if (theta-theta_old).all()<0.001: # 判断前后两次theta变换情况,当变化率很小时跳出循环break#print('x:',x,'y:',y,'loss:',loss)#print('y_hat:',y_hat.T)#print('times:',times,'theta:',theta)#print('')return theta

以上梯度下降算法完整代码如下

# -*- coding: utf-8 -*-
"""@Time    : 2018/10/22 17:23@Author  : hanzi5@Email   : **@163.com@File    : linear_regression_bgd.py@Software: PyCharm
"""
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegressiondef load_dataset(n): # 原作者产生数据的函数noise = np.random.rand(n)X = [[x, 1.] for x in range(n)]y = [(0.5 * X[i][0]  + 1. + noise[i]) for i in range(n)]return np.array(X).T, np.array(y).T # 注意X,W,y的维数def linearRegLsq(x,y):# 最小二乘法直接求解thetaxtx = np.dot(x.T, x)if np.linalg.det(xtx) == 0.0: # 判断xtx行列式是否等于0,奇异矩阵不能求逆print('Can not resolve the problem')returntheta_lsq = np.dot(np.dot(np.linalg.inv(np.dot(x.T, x)), x.T), y)return theta_lsqdef linearRegBgd1(x,y,alpha=0.005,lamba=0.005,loop_max=1000):#alpha = 0.0000001      #学习率步长,learning rate#lamba=0.005     #惩罚系数 '''已将原作者计算过程进行了大量修改,已将原作者计算过程进行了大量修改,就相当于是我原创了吧,将原计算的三重for循环重写为一重for循环参考链接:https://blog.csdn.net/mango_badnot/article/details/52328740 原作者构造的X特征是按行存储的,与常见数据不太一致,X中第一行为特征1,第二行为特征2批量梯度下降算法公式:theta=theta + alpha * sum( (y-y_hat) * x)2018-10-22 17:18 测试通过,此函数不做多的备注了,详细备注放在了linearRegBgd2里'''np.set_printoptions(precision=4) # 设置numpy输出4位小数n=len(x) # 取第一行数据,查看数据列数theta=np.zeros(n)      # 初始化theta数组,默认全为0for times in range(loop_max):y_hat=np.dot(x.T,theta)loss= y-y_hatfor i in range(1,n):if i==1:loss_n = np.row_stack((loss, loss))elif i>1:loss_n = np.row_stack((loss_n, loss))theta_old=thetatheta=theta+(alpha*x.T*loss_n.T).sum(axis=0) #+lamba*thetaif (theta-theta_old).all()<0.001:break#print('x:',x,'y:',y,'loss:',loss)#print('times:',times,'theta:',theta)#print('')return thetadef linearRegBgd2(x,y,alpha=0.005,lamba=0.005,loop_max=1000):#alpha = 0.0000001      #学习率步长,learning rate#lamba=0.005     #惩罚系数 '''参考链接:https://blog.csdn.net/mango_badnot/article/details/52328740 已将原作者计算过程进行了大量修改,就相当于是我原创了吧,将原计算的三重for循环重写为一重for循环,将运算修改为了矩阵运算原作者构造的X特征是按行存储的,与常见数据不太一致,X中第一行为特征1,第二行为特征2此函数将使用正常数据,X特征按列存储,每行是一条记录批量梯度下降算法公式:theta=theta + alpha * sum( (y-y_hat) * x)'''np.set_printoptions(precision=4) # 设置numpy输出4位小数n=len(x[0]) # 取第一行数据,查看数据列数theta=np.zeros(n)      # 初始化theta数组,默认全为0for times in range(loop_max):y_hat=np.dot(x,theta.T).reshape((-1,1))loss= (y_hat-y)  #此处是y_hat-y,对应的theta求解处增加了一个负号loss_n=np.array([]) # 为方便直接用矩阵实现sum( (y-y_hat) * x),产生多列loss乘以loss后求和if n==1: # 判断x矩阵有几列,列为1的时候单独处理loss_n=losselse:for i in range(1,n):# 判断x矩阵有几列,列为大于2的时候,产生n列loss#print(i)if i==1:loss_n = np.column_stack((loss, loss))elif i>1:loss_n = np.column_stack((loss_n, loss))theta_old=theta # 记录迭代前的theta#tmp=alpha*(loss_n*x).sum(axis=0)theta=theta - (alpha*(x*loss_n)).sum(axis=0) #+lamba*theta   #使用矩阵求解theta,注意此处的负号,loss*x后按特征列求和作为theta,注意上方本来想实现惩罚项的,但没有想明白怎么实现if (theta-theta_old).all()<0.001: # 判断前后两次theta变换情况,当变化率很小时跳出循环break#print('x:',x,'y:',y,'loss:',loss)#print('y_hat:',y_hat.T)#print('times:',times,'theta:',theta)#print('')return thetadef linearRegSgd(x,y,alpha=0.005,lamba=0.005,loop_max=10000):#alpha = 0.0000001      #学习率步长,learning rate#lamba=0.005     #惩罚系数 '''随机梯度下降算法公式:for i=1 to m: theta=theta + alpha * (y-y_hat) * xalpha=0.01lamba=0.005'''np.set_printoptions(precision=4) # 设置numpy输出4位小数n=len(x[0]) # 取第一行数据,查看数据列数theta=np.zeros(n)      # 初始化theta数组,默认全为0for times in range(loop_max):for i  in range(0,len(x)): # 取其中一条数据进行梯度下降# i=0y_hat=np.dot(x[i],theta.T).reshape((-1,1))loss= (y_hat-y[i])  #此处是y_hat-y,对应的theta求解处增加了一个负号theta_old=theta # 记录迭代前的thetatheta=theta - alpha*x[i]*loss[0] #+lamba*theta#求解theta,注意此处的负号,注意上方本来想实现惩罚项的,但没有想明白怎么实现if (theta-theta_old).all()<0.001: # 判断前后两次theta变换情况,当变化率很小时跳出循环break
#            print('x:',x,'y:',y,'loss:',loss)
#            print('y_hat:',y_hat.T)
#            print('times:',times,'theta:',theta)
#            print('')return thetadef linearRegMgd(x,y,alpha=0.005,lamba=0.005,loop_max=1000,batch_size=9):#alpha = 0.0000001      #学习率步长,learning rate#lamba=0.005     #惩罚系数 '''mini-batch梯度下降算法公式:每次使用batch_size个数据进行计算for i=1 to m: theta=theta + alpha * (y-y_hat) * x'''np.set_printoptions(precision=4) # 设置numpy输出4位小数n=len(x[0]) # 取第一行数据,查看数据列数theta=np.zeros(n)      # 初始化theta数组,默认全为0for times in range(loop_max):for i in range(0,int(len(x)/batch_size)+1):#print('i:',i,x[i*batch_size:(i+1)*batch_size])x_mini=x[i*batch_size:(i+1)*batch_size]y_mini=y[i*batch_size:(i+1)*batch_size]y_hat=np.dot(x_mini,theta.T).reshape((-1,1))loss= (y_hat-y_mini)  #此处是y_hat-y,对应的theta求解处增加了一个负号loss_n=np.array([]) # 为方便直接用矩阵实现sum( (y-y_hat) * x),产生多列loss乘以loss后求和if n==1: # 判断x矩阵有几列,列为1的时候单独处理loss_n=losselse:for i in range(1,n):# 判断x矩阵有几列,列为大于2的时候,产生n列loss#print(i)if i==1:loss_n = np.column_stack((loss, loss))elif i>1:loss_n = np.column_stack((loss_n, loss))theta_old=theta # 记录迭代前的theta#tmp=alpha*(loss_n*x).sum(axis=0)theta=theta - (alpha*(x_mini*loss_n)).sum(axis=0) #+lamba*theta   #使用矩阵求解theta,注意此处的负号,loss*x后按特征列求和作为theta,注意上方本来想实现惩罚项的,但没有想明白怎么实现if (theta-theta_old).all()<0.001: # 判断前后两次theta变换情况,当变化率很小时跳出循环break#print('x:',x,'y:',y,'loss:',loss)#print('y_hat:',y_hat.T)#print('times:',times,'theta:',theta)#print('')return thetaif __name__ == "__main__":path = 'D:/python_data/8.Advertising.csv'data = pd.read_csv(path)  # TV、Radio、Newspaper、Sales#data_matrix = data.as_matrix(columns=['TV', 'Radio', 'Newspaper', 'Sales'])  # 转换数据类型data_array = data.values[:,1:]  # 转换数据类型,去除第一列序号列x = data_array[:, :-1] #去除y对应列的数据,其他列作为xy = data_array[:, -1].reshape((-1,1))# 0、绘制图像,查看数据分布情况plt.plot(data['TV'], y, 'ro', label='TV')plt.plot(data['Radio'], y, 'g^', label='Radio')plt.plot(data['Newspaper'], y, 'mv', label='Newspaer')plt.legend(loc='lower right')plt.grid()plt.show()# 1、使用sklearn LinearRegression包求解θlinreg = LinearRegression()model = linreg.fit(x, y)print('')print('1、sklearn LinearRegression包求解θ:','coef:', linreg.coef_[0],',intercept:', linreg.intercept_)# 2、最小二乘法,直接求解析解θtheta_lsq = linearRegLsq(x,y)print('')print('2、最小二乘法,theta解析解:',theta_lsq.reshape(1,3)[0])# 3、批量梯度下降求解theta# 注意下面两个函数alpha都是非常小的值,取过大的值时,不收敛#x1, y1 = load_dataset(10)#theta1=linearRegBgd1(x1, y1)theta1=linearRegBgd1(x.T, y.T,alpha = 0.0000001)print('')print('3.1、批量梯度下降,linearRegBgd1函数,theta:',theta1)theta2=linearRegBgd2(x, y,alpha = 0.0000001)print('')print('3.2、批量梯度下降,linearRegBgd2函数,theta:',theta2)theta3=linearRegSgd(x, y,alpha = 0.000001,loop_max=10000)print('')print('3.3、随机梯度下降,linearRegSgd函数,theta:',theta3)theta4=linearRegMgd(x, y,alpha = 0.000001,loop_max=10000,batch_size=11)print('')print('3.4、mini-batch梯度下降,linearRegMgd函数,theta:',theta4)

程序运行计算结果:
在这里插入图片描述

数据见以下链接,复制到txt文档中,另存为CSV格式即可。
数据

参考资料:
1、python实现线性回归
2、机器学习:线性回归与Python代码实现
3、python实现简单线性回归
4、Machine-Learning-With-Python
5、《机器学习》西瓜书,周志华
6、机器学习视频,邹博
7、 斯坦福大学公开课 :机器学习课程
8、马同学高等数学 如何直观形象的理解方向导数与梯度以及它们之间的关系?
9、【机器学习】线性回归的梯度下降法

转载于:https://www.cnblogs.com/hanzi5/p/10105622.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/249161.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在centos和redhat上安装docker

前置条件 64-bit 系统kernel 3.101.检查内核版本&#xff0c;返回的值大于3.10即可。$ uname -r 2.使用 sudo 或 root 权限的用户登入终端。 3.卸载旧版本(如果安装过旧版本的话) $ yum remove docker \docker-common \docker-selinux \docker-engine 4.安装需要的软件包 #yum-…

mac 下用 brew 安装mongodb

mac 下安装mongoDB一般俩种方法. (1)下载源码,解压,编译,配置,启动 比较艰难的一种模式. (2)brew install mongodb ,然后就可以悠闲的品一口茶,顺便瞄一眼网易新闻,这是一种傻瓜模式. 但傻瓜模式也有人为干预的时候,粗略说一下使用brew 安装mongodb 1 zhangzhimoke:~/code$…

比较python类的两个instance(对象) 是否相等

http://www.yihaomen.com/article/python/281.htm 比较python类的两个instance(对象) 是否相等 作者:轻舞肥羊 日期:2012-10-25 字体大小: 小 中 大对于同一个Class,可以创建不同的实例(instance), 如何比较这两个 instance 是否相等呢&#xff1f;我们知道&#xff0c;对于计算…

Mybaits插入记录返回主键值

某些情况进行insert时不知道主键值&#xff08;主键为自增&#xff09;&#xff0c;例如系统新增用户时&#xff0c;有用户序号&#xff08;主键 自增&#xff09;&#xff0c;用户名&#xff0c;密码。插入时只需插入用户名和密码&#xff0c;之后取得mysql自增的序号。 如下为…

Mac 解决brew一直卡在Updating Homebrew

运行命令brew install node&#xff0c;结果界面一直卡在Updating Homebrew...上&#xff0c;有两种解决办法 方法一&#xff1a;直接关闭brew每次执行命令时的自动更新&#xff08;推荐&#xff09; vim ~/.bash_profile# 新增一行 export HOMEBREW_NO_AUTO_UPDATEtrue方法二…

CAS单点登录原理简单介绍

1. SSO简介 1.1 单点登录定义 单点登录(Single sign on)&#xff0c;英文名称缩写SSO&#xff0c;SSO的意思就是在多系统的环境中&#xff0c;登录单方系统&#xff0c;就可以在不用再次登录的情况下访问相关受信任的系统。也就是说只要登录一次单体系统就可以。计划在项目中加…

前端跨域通信的几种方式

前言 前端通信类的问题&#xff0c;主要包括以下内容&#xff1a; 1、什么是同源策略及限制 同源策略是一个概念&#xff0c;就一句话。有什么限制&#xff0c;就三句话。能说出来即可。 2、前后端如何通信 如果你不准备&#xff0c;估计也就只能说出ajax。 3、如何创建Aja…

T4((Text Template Transformation Toolkit))模版引擎之基础入门 C#中文本模板(.tt)的应用...

1 关于C#中文本模板(.tt)的简单应用https://blog.csdn.net/zunguitiancheng/article/details/78011145 任何一个傻瓜都能写出计算机能理解的程序&#xff0c;而优秀的程序员却能写出别人能读得懂的程序。—— Martin Fowler 2 T4模版引擎之生成数据库实体类 http://www.cnblogs…

LeetCode412Fizz Buzz

写一个程序&#xff0c;输出从 1 到 n 数字的字符串表示。 1. 如果 n 是3的倍数&#xff0c;输出“Fizz”&#xff1b; 2. 如果 n 是5的倍数&#xff0c;输出“Buzz”&#xff1b; 3.如果 n 同时是3和5的倍数&#xff0c;输出 “FizzBuzz”。 示例&#xff1a; n 15, 返回: [ …

vue+node实现中间层同步调用接口

为了应对业务的复杂性&#xff0c;提高前端的渲染能力&#xff0c;故在项目中引入nodejs做中间层&#xff0c;前端承接vue&#xff0c;后端对接Java。 至于为什么这么搞&#xff0c;网上有好多文章都在讨论&#xff0c;可以说仁者见仁智者见智&#xff0c;这里我们不在深究。 …

ES6学习笔记(二十二)ArrayBuffer

ArrayBuffer ArrayBuffer对象、TypedArray视图和DataView视图是 JavaScript 操作二进制数据的一个接口。它们都是以数组的语法处理二进制数据&#xff0c;所以统称为二进制数组。 二进制数组由三类对象组成。 &#xff08;1&#xff09;ArrayBuffer对象&#xff1a; 代表内存之…

如何正确地使用Java的@deprecated标注

没有什么事情比看到一个没有任何说明的deprecated标注更让人愤怒的事情了。这种做法只能让人困惑&#xff0c;我到底还要不要用这个已经‘废弃’的方法&#xff1f;如果开发者不希望某个方法再被人用的话&#xff0c;就要好好地为deprecated标注写说明。这篇文章就讨论了正确地…

实现div里的img图片水平垂直居中

body结构 <body><div><img src"1.jpg" alt"haha"></div> </body>方法一&#xff1a; 将display设置成table-cell&#xff0c;然后水平居中设置text-align为center&#xff0c;垂直居中设置vertical-align为middle。 <…

[ 懒人神器 ] —— OO一键build:.zip - .jar

懒人神器 更新 大家注意一下&#xff0c;由于在写入MANIFEST的时候&#xff0c;Class-Path路径给的是 ../lib &#xff0c;即上级目录的lib。 所以在对拍时如果手动移动了 jar包的位置&#xff0c;需要保证 lib/ 文件夹在存放jar包的上一级目录下&#xff0c;否则在运行时会报错…

实现Datagrid分页

Html页面&#xff1a; <!DOCTYPE html> <html> <head><meta http-equiv"Content-Type" content"text/html; charsetutf-8" /><title></title><meta charset"utf-8" /><!-- 引入相关CSS --><…

Luogu 3698 [CQOI2017]小Q的棋盘

BZOJ 4813 虽然数据范围很迷人&#xff0c;但是想树形$dp$没有前途。 先发现一个事情&#xff0c;就是我们可以先选择一条链&#xff0c;最后要走到这一条链上不回来&#xff0c;走到链上的点每一个只需要一步&#xff0c;而如果要走这条链之外的点&#xff0c;一个点需要走两步…

h5-plus.webview

这里是链接转载于:https://www.cnblogs.com/yuners/p/10721163.html

解决vue打包后静态资源路径错误的问题

vue项目完成的最后一步就是打包部署上线&#xff0c;但是打包部署的过程往往不是那么一帆风顺的&#xff0c;现将遇到问题和解决方案记录如下。 图片路径问题 起因&#xff1a; 页面中引入资源的方式往往有如下几种 * HTML标签中直接引入图片&#xff0c; 如 <img src&qu…

SQL语句01

SQL(Structured Query Language)&#xff1a;结构化查询语言SQL分类&#xff1a; 数据操纵语言DML&#xff08;Data Manipulation Language&#xff09; SELECT INSERT UPDATE DELETE 数据定义语言DDL&#xff08;Data definition language&#xff09; …

mongoose 笔记

快速启动 首先需要安装MongoDB和Node.js。 然后使用npm下载mongoose&#xff1a; npm install mongoose 接着我们直接在项目中引入mongoose&#xff0c;并且连接数据库就会在本地运行 MongoDB了&#xff1a; // index.js var mongoose require(mongoose); mongoose.connect(…