复合分位回归的求解

复合分位回归

类似分位回归的,给定分位数序列 0 < τ 1 < τ 2 < ⋯ < τ K < 1 0<\tau_1<\tau_2<\cdots<\tau_K<1 0<τ1<τ2<<τK<1,复合分位回归的目的不再是在一个分位点上最小化损失函数,而是在多个分位点上同时最小化check function. 则估计回归系数 β \boldsymbol{\beta} β的估计是通过如下目标函数得到的:
( b ^ 1 , … , b ^ K , β ^ C Q R ) = arg min ⁡ b 1 … , b k , β ∑ k = 1 K { ∑ i = 1 n ρ τ k ( y i − b k − x i ⊤ β ) } (\hat{b}_1,\dots,\hat{b}_K,\hat{\boldsymbol{\beta}}^{\mathrm{CQR}})=\underset{b_1\dots,b_k,\boldsymbol{\beta}}{\argmin}\sum_{k=1}^K\left\{ \sum_{i=1}^n\rho_{\tau_k} (y_i-b_k-\bold{x}_i^{\top}\boldsymbol{\beta})\right\} (b^1,,b^K,β^CQR)=b1,bk,βargmink=1K{i=1nρτk(yibkxiβ)}
通常我们会取等距分位序列: τ k = k K + 1 , k = 1 , 2 , … , K \tau_k=\frac{k}{K+1},k=1,2,\dots,K τk=K+1k,k=1,2,,K. 同时给出估计量的渐近分布: n ( β ^ C Q R − β ∗ ) → N ( 0 , Σ C Q R ) \sqrt{n}(\hat{\boldsymbol{\beta}}^{\mathrm{CQR}}-\boldsymbol{\beta}^*)\to N(0,\boldsymbol{\Sigma}_{\mathrm{CQR}}) n (β^CQRβ)N(0,ΣCQR)其中
Σ C Q R = C − 1 ∑ k , k ′ = 1 K min ⁡ ( τ k , τ k ′ ) ( 1 − max ⁡ ( τ k , τ k ′ ) ) ( ∑ k = 1 K f ( b τ k ∗ ) ) 2 \boldsymbol{\Sigma}_{\mathrm{CQR}}=\bold{C}^{-1}\frac{\sum_{k,k'=1}^K\min(\tau_k,\tau_{k'})(1-\max(\tau_k,\tau_k'))}{(\sum_{k=1}^Kf(b^*_{\tau_k}))^2} ΣCQR=C1(k=1Kf(bτk))2k,k=1Kmin(τk,τk)(1max(τk,τk))
其中 C \bold{C} C
lim ⁡ n → ∞ 1 n X ⊤ X = C \lim_{n\to\infty}\frac{1}{n}\bold{X}^{\top}\bold{X}=\bold{C} nlimn1XX=C

1.1 基于MM算法的Python实现

data = pd.read_csv(r"C:\Users\beida\Desktop\sc\rent.csv")
n = len(data); p = 1
x = np.array(data[["cons", 'area']])y = np.array(data["rent_euro"], dtype=np.float64)
#beta = np.matrix([100, 2.6]).reshape(p, 1)
# np.set_printoptions(precision=8)
tau = np.arange(1, 6)/6
k = len(tau)
maxit = 1000
toler = 0.0001
error = 10000
iteration = 1
p = 2
u = np.zeros(k)
r = np.zeros((n, k))
signw = np.zeros((n, k))
z = np.zeros((n, k))
newX = np.zeros((n, k))
#beta = np.matrix([1, 1], dtype=np.float64).reshape(2, 1)
beta = np.linalg.pinv(x.T.dot(x)).dot(x.T).dot(y)
#print(beta, "ols")while (iteration <= maxit) & (error > toler):betaold = beta.copy()#print(betaold, 'betaold')uv = np.sort(y - x.dot(beta), axis=0)  # yesquantile1 = (n-1)*tau - np.floor((n - 1)*tau)  # yesfor i in range(0, k):u[i] = quantile1[i] * uv[int(np.ceil((n - 1)*tau[i]))] \+ (1-quantile1[i]) * uv[int(np.floor((n - 1)*tau[i]))]yh = x.dot(beta)for i in range(0, k):r[:, i] = y - u[i] - yhsignw[:, i] = (1 - np.sign(r[:, i]))/2 * (1 - tau[i])  \+ (np.sign(r[:, i]) + 1) * tau[i]/2for j in range(0, p):xbeta = beta[j] * x[:, j]for i in range(0, k):z[:, i] = (r[:, i]+xbeta)/x[:, j]newX[:, i] = x[:, j] * signw[:, i]vz = z.flatten()order = vz.argsort()sortz = vz[order]  # yesvnewX = newX.flatten()w = np.abs(vnewX[order])index = np.where(np.cumsum(w) > (np.sum(w)/2))[0][0]# print(index)beta[j] = sortz[index]error = np.sum(np.abs(beta-betaold))iteration = iteration + 1
print("beta:", beta)
print("tau:", tau)
print("cons:", np.percentile((y-x.dot(beta)), tau*100))

结果

> beta: [135.63724592   4.3381923 ]
> tau: [0.16666667 0.33333333 0.5        0.66666667 0.83333333]
> cons: [-114.9981428   -40.30912765   16.70578506   75.41938784  165.26588296]

1.2 基于MM算法的CQR及其R实现

cqrmm(x=x,y=y,tau=tau)
set.seed(1)
n=100
p=2
a=rnorm(n*p, mean = 1, sd =1)
x=matrix(a,n,p)
beta=rnorm(p,1,1)
beta=matrix(beta,p,1)
y=x%*%beta-matrix(rnorm(n,0.1,1),n,1)
tau=1:5/6
# x is 1000*10 matrix, y is 1000*1 vector, beta is 10*1 vector
cqr.mm(x,y,tau)cqrmm = function(x, y, beta, to, m, tau){if (missing(to)){toler = 1e-3}else{toler = to}if (missing(m)){maxit = 200}else{maxit = m}if (missing(tau)){cat('no tau_k input','\n')tau=1:5/6}else{tau=tau}x = xX = x#arma:: mat x=(xr),r,product,xt,denominator;#arma:: vec W,uv,v,y=(yr),delta;#arma:: vec betaold,beta=(betar),quantile,u,yh;#arma::uvec order, index;n=nrow(x)p = ncol(x)k=length(tau)error=10000epsilon=0.9999iteration=1;#u.zeros(k);#r.zeros(n,k);u <- numeric(k)r <- matrix(0, n, k)if (missing(beta)){beta = solve(t(x)%*%x, t(x)%*%y)}else{beta = beta}xt=t(x)product <- matrix(1, p, n)while (iteration<=maxit && error>toler){betaold = beta;yh = x%*% beta; #y_hatuv = sort(y - yh)# u is vec of the quantiles of given vectorquantile = (n-1) * tau - floor((n-1) * tau)for (i in 1:k){	u[i] = quantile[i] * uv[ceiling((n-1) * tau[i])] + (1 - quantile[i]) * uv[floor((n-1) * tau[i])]}for (i in 1:k){r[,i] = y-u[i]-yh;}denominator=1/(abs(r)+epsilon)W = rowSums(denominator)v <- k - 2 * sum(tau) - rowSums(r * denominator)for (i in 1:n){product[,i] = xt[,i]*W[i]}delta = solve(product%*%x, xt%*%v);beta = beta-deltaerror = sum(abs(delta))iteration = iteration + 1}b=quantile(y-X%*%beta, tau)return(list(beta=beta,b=b))
}

1.3 基于EM算法的R语言实现

library(MASS)
library(cqrReg)
set.seed(NULL)
tau.k = 1:5 / 6CQREM = function(X, y, tau, betar, weight, maxit, toler) {if (missing(betar)) {beta = solve(t(X) %*% X, t(X) %*% y)cat(beta,'\n')}if (missing(tau)) {tau.k = 1:5 / 6alpha = tau}K = length(tau)if (missing(weight)) {weight = rep(1, times = K)}if (missing(maxit)) {maxit = 1000}if(missing(toler)){toler = 1e-5}weight = weightalpha = taun = length(y)tau.k = tautheta.1 = (1 - 2 * tau.k) / (tau.k * (1 - tau.k))theta.2 = 2 / (tau.k * (1 - tau.k))error = 10000epsilon = 0.9999iteration = 1while (iteration <= maxit && error > toler) {#for (i in 1:maxit){ rbar = matrix(NA, n, K)mu_new = matrix(NA, n, K)mu = matrix(NA, n, K)w.ik = matrix(NA, n, K)d.ik = matrix(NA, n, K)r = y - X %*% betarfor (k in 1:K) {rbar[, k] <- sum(r - alpha[k])}rbardelta2 = sqrt((theta.1 ^ 2 + 2 * theta.2)) / abs(rbar)delta2delta3 = (theta.2 * weight) / (theta.1 ^ 2 + 2 * theta.2) + abs(rbar) / (sqrt(theta.1 ^ 2 + 2 * theta.2))delta3for (k in 1:K) {w.ik[, k] = delta2[, k] / (theta.2 * weight)[k]}w.ikw.i = rowSums(w.ik)w.iW = diag(w.i)W#svd_W <- svd(W)#U <- svd_W$u#V <- svd_W$v#D <- svd_W$d# 构建逆矩阵#W_inv <- diag(1/D)#W_reg <- W + lambda * diag(nrow(W))for (k in 1:K) {d.ik[, k] = (theta.1 + alpha * delta2)[, k] / (theta.2 * weight)[k]}d.ikd.i = rowSums(d.ik)d.iD = as.vector(d.i)ybar = y - solve(W) %*% Dybarbetabeta_new = solve(t(X) %*% W %*% X) %*% t(X) %*% W %*% ybarbeta_newA = matrix(NA, n, K)for (k in 1:K){A[,k] = (y-X%*%beta_new)*delta2[, k]}alphaalpha_new=colSums(A - n*theta.1)/colSums(delta2)for (k in 1:K) {mu[, k] = X %*% beta_new + alpha_new[k]}weight_new = (2 / (3 * n)) * colSums((y - mu) ^ 2 / (2 * theta.2) * delta2 +(theta.1 ^ 2 + 2 * theta.2) / (2 * theta.2) * delta3 -(theta.1 * (y - mu)) / (theta.2))#alpha_new = colSums(as.numeric((y[1] - t(#  as.matrix(X[1,], row = 1, col = 2)#)) %*% beta) * delta2)alpha_newerror = sum(abs(beta_new))beta = beta_newalpha = alpha_newweight = weight_newiteration = iteration + 1#cat(error,'\n')}b = quantile(y - X %*% beta, tau.k)return(list(beta = beta, b = b))
}n = 300
p = 3
X = matrix(rnorm(n*p, 0, 1), n, p)
y = rnorm(n)
CQREM(X, y, tau=tau.k, maxit = 1000, tol=1e-5)
cqr.mm(X, y, tau= tau.k,toler = 1e-5)>$beta[,1]
[1,] -0.01504609
[2,] -0.14649880
[3,]  0.23344365$b16.66667%    33.33333%          50%    66.66667%    83.33333% 
-0.881195701 -0.428558273 -0.000221886  0.470748757  1.102072419$beta[,1]
[1,]  0.05258097
[2,] -0.05178250
[3,]  0.13393040$b16.66667%     33.33333%           50%     66.66667%     83.33333% 
-0.9269618879 -0.3647195276 -0.0001248183  0.4284496629  1.0367478727 

EM算法的速度显著慢于MM算法,同时在估计结果上也有略微的差异。

1.4 基于凸优化(CVX)的复合分位回归

实际上还有一些暴力的求解方法,比如直接凸优化

library(CVXR)
library(cqrReg)
set.seed(1)
n=100
p=2
a=rnorm(n*p, mean = 1, sd =1)
x=matrix(a,n,p)
beta=rnorm(p,1,1)
beta=matrix(beta,p,1)
y=x%*%beta-matrix(rnorm(n,0.1,1),n,1)
tau=1:5/6
cqr.mm(x,y,tau)
# 假设数据已经定义好
Y <- y # 响应变量
X <- x # 解释变量矩阵
taus <- tau # 分位数向量# 定义决策变量
beta <- Variable(ncol(X))
b <- Variable(length(taus))# 定义分位数损失函数
quantile_loss <- function(residuals, tau) {sum(pos(residuals) * tau + pos(-residuals) * (1 - tau))
}# 构建目标函数的每一部分
objective_parts <- lapply(1:length(taus), function(i) {quantile_loss(Y - b[i] - X %*% beta, taus[i])
})# 合并目标函数的各个部分
objective <- Minimize(Reduce(`+`, objective_parts))# 定义优化问题
problem <- Problem(objective, list())# 求解
result <- solve(problem)# 提取结果
result$getValue(beta)
>          [,1]
> [1,] 1.470763
> [2,] 2.758932result$getValue(b)
>
>            [,1]
> [1,] -1.1859157
> [2,] -0.7531299
> [3,] -0.2539941
> [4,]  0.1203188
> [5,]  0.7931756> cqr.mm(x,y,tau)
$beta[,1]
[1,] 1.508830
[2,] 2.749125$b16.66667%   33.33333%         50%   66.66667%   83.33333% 
-1.21780307 -0.78448530 -0.29961304  0.05043142  0.69900106 

可以看到,与MM算法也存在一些差异

进一步思考

加权复合分位回归

复合分位回归是最小化一系列分位损失函数,但不难看出,CQR是赋予了每个 ρ τ k \rho_{\tau_k} ρτk完全相同的权重,那么就可以考虑不同的权重。这样得到的就是加权的CQR(WCQR)
( α ^ 1 , … , α ^ K , β ^ W C Q R ) = arg ⁡ min ⁡ α 1 , … , α K , β ∑ i = 1 N ∑ k = 1 K ω k ⋅ ρ τ k ( Y i − X i T β − α k ) . \left(\hat{\alpha}_{1}, \ldots, \hat{\alpha}_{K}, \hat{\beta}^{\mathrm{WCQR}}\right)=\arg \min _{\alpha_{1}, \ldots, \alpha_{K}, \beta} \sum_{i=1}^{N} \sum_{k=1}^{K} \omega_{k} \cdot \rho_{\tau_{k}}\left(Y_{i}-X_{i}^{T} \beta-\alpha_{k}\right) . (α^1,,α^K,β^WCQR)=argα1,,αK,βmini=1Nk=1Kωkρτk(YiXiTβαk).
求解原理与CQR类似的,加入设定相同的权重w,那么就应该得到与CQR完全相同的结果

Y <- y # 响应变量
X <- x # 解释变量矩阵
taus <- tau # 分位数向量
w = c(0.2,0.2,0.2,0.2,0.2)
# 定义决策变量
beta <- Variable(ncol(X))
b <- Variable(length(taus))# 定义分位数损失函数
quantile_loss <- function(residuals, tau) {sum(pos(residuals) * tau + pos(-residuals) * (1 - tau))
}# 构建目标函数的每一部分
objective_parts <- lapply(1:length(taus), function(i) {w[i]*quantile_loss(Y - b[i] - X %*% beta, taus[i])
})# 合并目标函数的各个部分
objective <- Minimize(Reduce(`+`, objective_parts))# 定义优化问题
problem <- Problem(objective, list())# 求解
result <- solve(problem)# 提取结果
beta_val <- result$getValue(beta)
b_val <- result$getValue(b)beta_val
b_val> beta_val[,1]
[1,] 1.470763
[2,] 2.758932
> b_val[,1]
[1,] -1.1859157
[2,] -0.7531299
[3,] -0.2539941
[4,]  0.1203188
[5,]  0.7931756

现在设定不同的权重w:


# 生成n个随机数
n <- length(taus)
random_numbers <- runif(n)# 归一化使得它们的总和为1
normalized_numbers <- random_numbers / sum(random_numbers)# 验证它们的总和是否为1
sum(normalized_numbers)Y <- y # 响应变量
X <- x # 解释变量矩阵
taus <- tau # 分位数向量
w = normalized_numbers
# 定义决策变量
beta <- Variable(ncol(X))
b <- Variable(length(taus))# 定义分位数损失函数
quantile_loss <- function(residuals, tau) {sum(pos(residuals) * tau + pos(-residuals) * (1 - tau))
}# 构建目标函数的每一部分
objective_parts <- lapply(1:length(taus), function(i) {w[i]*quantile_loss(Y - b[i] - X %*% beta, taus[i])
})# 合并目标函数的各个部分
objective <- Minimize(Reduce(`+`, objective_parts))# 定义优化问题
problem <- Problem(objective, list())# 求解
result <- solve(problem)# 提取结果
beta_val <- result$getValue(beta)
b_val <- result$getValue(b)> beta_val[,1]
[1,] 1.525781
[2,] 2.736585
> b_val[,1]
[1,] -1.23440023
[2,] -0.79443834
[3,] -0.32373464
[4,]  0.05565281
[5,]  0.79790504

可见估计值有了差异。

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

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

相关文章

文献速递:生成对抗网络医学影像中的应用——基于CycleGAN的图像到图像转换,用于逼真的外科手术训练模型

文献速递&#xff1a;生成对抗网络医学影像中的应用——基于CycleGAN的图像到图像转换&#xff0c;用于逼真的外科手术训练模型 本周给大家分享文献的主题是生成对抗网络&#xff08;Generative adversarial networks, GANs&#xff09;在医学影像中的应用。文献的研究内容包括…

一文掌握分布式锁:Mysql/Redis/Zookeeper实现

目录 一、项目准备spring项目数据库 二、传统锁演示超卖现象使用JVM锁解决超卖解决方案JVM失效场景 使用一个SQL解决超卖使用mysql悲观锁解决超卖使用mysql乐观锁解决超卖四种锁比较Redis乐观锁集成Redis超卖现象redis乐观锁解决超卖 三、分布式锁概述四、Redis分布式锁实现方案…

人大金仓Kingbase数据库备份和还原

前言 最近在项目开发过程中&#xff0c;使用了国产数据库人大金仓&#xff08;即Kingbase数据库&#xff09;&#xff0c;在使用过过程中需要对数据库进行备份与还原&#xff0c;在此对相关的命令进行简单介绍&#xff0c;以备不时之需。 Linux环境下安装人大金仓可参考此篇文…

gnome-control-center 点击喇叭无声(解决过程).

gnome-control-center 点击喇叭无声. ------------------------------------------------------------ author: hjjdebug date: 2023年 12月 22日 星期五 13:38:17 CST descprition: 解决gnome-control-center 点击喇叭无声的问题 -------------------------------------------…

ECMAScript基础入门:猫头虎博主的技术分享

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

Spring中你一定要知道的afterPropertiesSet()

文章目录 功能源码 功能 初始化bean执行的回调方法其一&#xff0c;它不像PostConstruct一样可以有多个&#xff0c;只能调用一次&#xff1b;它执行的时机是在PostConstruct之后&#xff0c;从它的名称也可以看出&#xff0c;他是在属性填充完&#xff0c;也就是bean初始化完…

实力强的大模型都有哪些超能力?

实力强的大模型都有哪些超能力&#xff1f; 前几日&#xff0c;人工智能研究公司OpenAI CEO山姆奥特曼&#xff08;Sam Altman&#xff09;在谈及人工智能这项技术的潜力以及人们对它的担忧时&#xff0c;曾表示“AI发展速度快得吓人&#xff0c;就像停不下来的龙卷风。”可见&…

如何使用 NFTScan NFT API 在 Base 网络上开发 Web3 应用

Base 是 Coinbase 使用 OP Stack 开发的最新以太坊第 2 层&#xff08;L2&#xff09;网络&#xff0c;用于解决以太坊等主要区块链面临的可扩展性和成本挑战。Coinbase 将其描述为“安全、低成本、对开发人员友好的以太坊 L2&#xff0c;旨在将下一个 10 亿用户带入 Web3”。B…

一个抖店内做几个商品链接比较合适?解答下新手问题,建议收藏

我是王路飞。 一个抖店内的商品链接数量&#xff0c;是多一些比较好还是少一些比较好呢&#xff1f; 可能在大多数人看来&#xff0c;当然是多一些比较好了&#xff0c;商品数量更多&#xff0c;基数增加&#xff0c;也能承载更多的进店流量&#xff0c;增加下单几率。 但真…

【Kotlin】一款专门为 Java 程序员打造的快速掌握 Kotlin 技术博客

目录 初识 Kotlin 历史 工作原理 第一个Hello World&#xff01; Kotlin 语法 变量 基本数据类型 函数 和 选择控制&#xff08;if、when&#xff09; if when 循环语句 类和对象 创建和使用 继承 构造 主构造 次构造 接口 定义 实现 权限修饰符 数据类…

测试基础知识总结

什么是软件测试&#xff1f; 答&#xff1a;软件测试是为了软件的产品特性是否满足用户的需求&#xff1b;因为企业的利益与用户直接关联。 调试和测试的区别 ①目的不同 调试&#xff1a;发现并解决软件中存在的缺陷 测试&#xff1a;发现软件中存在的缺陷 ②人员不同 调试&a…

VBA_MF系列技术资料1-247

MF系列VBA技术资料 为了让广大学员在VBA编程中有切实可行的思路及有效的提高自己的编程技巧&#xff0c;我参考大量的资料&#xff0c;并结合自己的经验总结了这份MF系列VBA技术综合资料&#xff0c;而且开放源码&#xff08;MF04除外&#xff09;&#xff0c;其中MF01-04属于定…

在线客服系统推荐:优质选择助您提升客户服务体验

大部分企业依靠在线客服系统和客户达成联系&#xff0c;他为客户和企业之间建立了有效的沟通桥梁。市场上这么多的在线客服系统哪个好呢&#xff1f; 1、明确自己的需求。 这一点是最重要的&#xff0c;要先明确公司使用客服系统是想做售前咨询还是售后服务。不同的需求相对应…

鸿蒙开发之hdc命令行

一、简介 hdc&#xff08;HarmonyOS Device Connector&#xff09;是HarmonyOS为开发人员提供的用于调试的命令行工具&#xff0c;通过该工具可以在windows/linux/mac系统上与真实设备进行交互。 二、环境准备 hdc工具通过HarmonyOS SDK获取&#xff0c;存放于SDK的toolchai…

自然语言处理阅读第三弹

LLM微调 三种方法 Prefix-Tuning/Prompt-Tuning:在模型的输入或隐层添加k个额外可训练的前缀tokens(这些前缀是连续的伪tokens,不对应真实的tokens),只训练这些前缀参数; Prefix-tuning: 对于每个任务,都有一个特定的前缀被添加到输入序列的开始部分。这些前缀相当于任务特…

JavaScript高级 函数进阶篇

函数进阶 1、函数的定义和调用 函数声明方式function关键字&#xff08;命名函数&#xff09;&#xff1b;函数表达式&#xff08;匿名函数&#xff09;&#xff1b;new Function()&#xff08;此处的Function()是一个构造函数&#xff09;&#xff1b;var fn new Function(参…

六个探索性数据分析(EDA)工具,太实用了!

当进行数据分析时&#xff0c;探索性数据分析(EDA)是一个至关重要的阶段&#xff0c;它能帮助我们从数据中发现模式、趋势和异常现象。而选择合适的EDA工具又能够极大地提高工作效率和分析深度。在本文中&#xff0c;笔者将介绍6个极其实用的探索性数据分析(EDA)工具&#xff0…

和宝贝一起迎接冬日里的浪漫~优雅有气质

闪闪发光的刺绣亮片面料 自带闪光&#xff0c;是低调而浪漫的存在 蓬松拼接多层网纱 自带裙撑效果的网纱裙摆唯美飘逸 仿佛冬日里的小公主 热烈轻快的奔向即将到来的节日庆典

Go和Java实现简单工厂模式

Go和Java实现简单工厂模式 本文通过计算器案例来说明简单工厂模式的使用&#xff0c;使用Go语言和Java语言实现。 1、简单工厂模式 简单工厂模式对对象创建管理方式最为简单&#xff0c;只需要创建一个简单的工厂类然后在里面创建对象&#xff0c;该模式通过向工 厂传递类型…

自媒体人福音,正版实用的视频素材网站~

大家平时在创作视频的时候&#xff0c;有没有苦恼过找不到合适的素材呢&#xff1f;网上能找到的大部分素材都是有版权的&#xff0c;不能随便乱用。今天我就来给大家推荐一些用于视频创作的正版素材网站&#xff0c;快快收藏吧! 1.制片帮素材 链接&#xff1a;stock.zhipianb…