特征选择与特征提取

这篇具有很好参考价值的文章主要介绍了特征选择与特征提取。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、 特征选择

  卷积解决的问题:卷积负责提取图像中的局部特征.

1、特征

  特征意为可作为事物特点的象征、标志等。在一些实际问题中,我们得到的样本数据都是多个维度的,即一个样本是用多个特征来表征的。比如在预测房价的问题中,影响房价y的因素有房子面积x1、卧室数量x2等,我们得到的样本数据就是(x1,x2)这样一些样本点,这里的x1、 x2又被称为特征。

  为什么要进行特征选择?
  在现实生活中,一个对象往往具有很多属性(以下称为特征),这些特征大致可以被分成三种主要的类型:
  • 相关特征:对于学习任务(例如分类问题)有帮助,可以提升学习算法的效果;
  • 无关特征:对于我们的算法没有任何帮助,不会给算法的效果带来任何提升;
  • 冗余特征:不会对我们的算法带来新的信息,或者这种特征的信息可以由其他的特征推断出。
  但是对于一个特定的学习算法来说,哪一个特征是有效的是未知的。因此,需要从所有特征中选择出对于学习算法有益的相关特征。

  进行特征选择的目的是:
  • 降维
  • 降低学习任务的难度
  • 提升模型的效率

2、特征选择

(1)定义
  从N个特征中选择其中M(M<=N)个子特征,并且在M个子特征中,准则函数可以达到最优解。用具体函数评价系统所采取策略优劣的准则时,称为准则函数。
  特征选择想要做的是:选择尽可能少的子特征,模型的效果不会显著下降,并且结果的类别分布尽可能的接近真实的类别分布。
(2)怎么进行特征选择?

特征选择主要包括四个过程:
	1. 生成过程:生成候选的特征子集;
	2. 评价函数:评价特征子集的好坏;
	3. 停止条件:决定什么时候该停止;
	4. 验证过程:特征子集是否有效;

特征选择与特征提取
  生成过程是一个搜索过程,这个过程主要有以下三个策略:

1. 完全搜索:根据评价函数做完全搜索。完全搜索主要有两种:穷举搜索和非穷
举搜索;

2. 启发式搜索:根据一些启发式规则在每次迭代时,决定剩下的特征是应该被选
择还是被拒绝。这种方法很简单并且速度很快。

3. 随机搜索:每次迭代时会设置一些参数,参数的选择会影响特征选择的效果。
由于会设置一些参数(例如最大迭代次数)

  停止条件用来决定迭代过程什么时候停止,生成过程和评价函数可能会对于怎么选择停止条件产生影响。停止条件有以下四种选择:

1. 达到预定义的最大迭代次数;
2. 达到预定义的最大特征数;
3. 增加(删除)任何特征不会产生更好的特征子集;
4. 根据评价函数,产生最优特征子集;

  评价函数主要用来评价选出的特征子集的好坏, 一个特征子集是最优的往往指相对于特定的评价函数来说的。评价函数主要用来度量一个特征(或者特征子集)可以区分不同类别的能力。根据具体的评价方法主要有三类:

  • 过滤式(ilter): 先进行特征选择,然后去训练学习器,所以特征选择的过程与学习器无关。相当于先对于特征进行过滤操作,然后用特征子集来训练分类器。对每一维的特征“打分”,即给每一维的特征赋予权重,这样的权重就代表着该维特征的重要性,然后依据权重排序。

  • 包裹式(wrapper): 直接把最后要使用的分类器作为特征选择的评价函数,对于特定的分类器选择最优的特征子集。将子集的选择看作是一个搜索寻优问题,生成不同的组合,对组合进行评价,再与其他的组合进行比较。这样就将子集的选择看作是一个优化问题.

  • Filter和Wrapper组合式算法: 先使用Filter进行特征选择,去掉不相关的特征,降低特征维度;然后利用Wrapper进行特征选择。

  •嵌入式( embedding):把特征选择的过程与分类器学习的过程融合一起,在学习的过程中进行特征选择。其主要思想是:在模型既定的情况下学习出对提高模型准确性最好的属性。这句话并不是很好理解,其实是讲在确定模型的过程中,挑选出那些对模型的训练有重要意义的属性。

  一般有5种比较常见的评价函数:

1. 距离度量:如果 X 在不同类别中能产生比 Y 大的差异,那么就说明 X 要好于 Y;

2. 信息度量:主要是计算一个特征的信息增益(度量先验不确定性和期望, 后验不确定性
之间的差异);

3. 依赖度量:主要用来度量从一个变量的值预测另一个变量值的能力。最常见的是相关系
数:用来发现一个特征和一个类别的相关性。如果 X 和类别的相关性高于 Y与类别的相关
性,那么X优于Y。对相关系数做一点改变,用来计算两个特征之间的依赖性,值代表着两
个特征之间的冗余度。

4. 一致性度量:对于两个样本,如果它们的类别不同,但是特征值是相同的,那么它们是
不一致的;否则是一致的。找到与全集具有同样区分能力的最小子集。严重依赖于特定的
训练集 和 最小特征偏见(Min-Feature bias)的用法;找到满足可接受的不一致率(用户
指定的参数)的最小规模的特征子集。

5. 误分类率度量:主要用于Wrapper式的评价方法中。使用特定的分类器,利用选择的特
征子集来预测测试集的类别,用分类器的准确率来作为指标。这种方法准确率很高,但是
计算开销较大

3、扩展——特征选择算法(有兴趣和精力可了解)

特征选择与特征提取

拓展–完全搜索:

  广度优先搜索(Breadth First Search): 主要采用完全搜索策略和距离度量评价函数。使用广度优先算法遍历所有可能的特征子集,选择出最优的特征子集。

  主要采用完全搜索和距离度量。 B&B从所有的特征上开始搜索,每次迭代从中去掉一个特征,每次给评价函数的值一个限制条件。因为评价函数满足单调性原理(一个特征子集不会好于所有包含这个特征子集的更大的特征子集),所以如果一个特征使得评价函数的值小于这个限制,那么就删除这个特征。类似于在穷举搜索中进行剪枝。

  定向搜索(Beam Search): 主要采用完全搜索策略和误分类率作为评价函数。选择得分最高的特征作为特征子集,把它加入到一个有长度限制的队列中,从头到尾依次是性能最优到最差的特征子集。每次从队列总取得分最高的子集,然后穷举向该子集中加入一个特征后所有的特征集,按照得分把这些子集加入到队列中。

  最优优先搜索(Best First Search): 和定位搜索类似,不同点在于不限制队列的长度。

拓展–启发式搜索:

  序列前向选择(SFS , Sequential Forward Selection):使用误分类率作为评价函数。从空集开始搜索,每次把一个特征加入到这个特征子集中,使得评价函数达到最优值。如果候选的特征子集不如上一轮的特征子集,那么停止迭代,并将上一轮的特征子集作为最优的特征选择结果。

  广义序列前向选择(GSFS , Generalized Sequential Forward Selection): 该方法是SFS算法的加速算法,它可以一次性向特征集合中加入r个特征。在候选特征中选择一个规模为r的特征子集,使得评价函数取得最优值。

  序列后向选择(SBS , Sequential Backward Selection): 把误分类率作为评价函数。从特征的全集开始搜索,每次从特征子集中去掉一个特征,使得评价函数达到最优值。

  广义序列后向选择(GSBS, Generalized Sequential Backward Selection): 该方法是SBS的加速,可以一次性的从特征子集中去除一定数量的特征。是实际应用中的快速特征选择算法,性能相对较好。但是有可能消除操作太快,去除掉重要的信息,导致很难找到最优特征子集。

  双向搜索(BDS , Bi-directional Search): 分别使用SFS和SBS同时进行搜索,只有当两者达到一个相同的特征子集时才停止搜索。为了保证能够达到一个相同的特征子集,需要满足两个条件:
  被SFS选中的特征不能被SBS去除;
  被SBS去除的特征就不能SFS选择;

拓展–随机搜索:

  LVF(Las Vegas Filter) :使用一致性度量作为评价函数。使用拉斯维加斯算法随机搜索子集空间,这样可以很快达到最优解。对于每一个候选子集,计算它的不一致性,如果大于阈值,则去除这个子集。否则,如果这个候选子集中的特征数量小于之前最优子集的数量,则该子集作为最优子集。这个方法在有噪声的数据集达到最优解,它是很简单被实现而且保证产生比较好的特征子集。但是在一些特定问题上,它会花费比启发式搜索更多的时间,因为它没有利用到先验知识。

拓展–遗传算法:

  使用误分类率作为评价函数。随机产生一批特征子集,然后使用评价函数对于子集进行评分,通过选择、交叉、突变操作产生下一代特征子集,并且得分越高的子集被选中产生下一代的几率越高。经过N代迭代之后,种群中就会形成评价函数值最高的特征子集。它比较依赖于随机性,因为选择、交叉、突变都由一定的几率控制,所以很难复现结果。

遗传算法的过程如下:
1. 随机产生初始种群;
2. 在非支配排序后,通过遗传算法的三个算子(选择算子,交叉算子,变异算子)进
行变更操作得到第一代种群;
3. 将父代种群与子代种群合并得到大小为N的初始化种群;
4. 对包括N个个体的种群进行快速非支配排序;
5. 对每个非支配层中的个体进行拥挤度计算;
6. 根据非支配关系及个体的拥挤度选取合适的个体组成新的父代种群;
7. 通过遗传算法的基本变更操作产生新的子代种群;
8. 重复 37 直到满足程序结束的条件(即遗传进化代数);

二、 特征提取

特征是什么: 常见的特征有边缘、角、区域等。

特征提取: 是通过属性间的关系,如组合不同的属性得到新的属性,这样就改
变了原来的特征空间。

特征选择: 是从原始特征数据集中选择出子集,是一种包含的关系,没有更改原始的特征空间。

目前图像特征的提取主要有两种方法:传统图像特征提取方法 和 深度学习方法。

1. 传统的特征提取方法:基于图像本身的特征进行提取;
2. 深度学习方法:基于样本自动训练出区分图像的特征分类器;

特征提取的主要目的是为了排除信息量小的特征,减少计算量等:

特征选择(feature selection)和特征提取(Feature extraction)都属于降维(Dimensionreduction)

三、特征提取主要方法——PCA(主成分分析)

1、PCA算法是如何实现的?

  简单来说,就是将数据从原始的空间中转换到新的特征空间中,例如原始的空间是三维的(x,y,z), x、 y、 z分别是原始空间的三个基,我们可以通过某种方法,用新的坐标系(a,b,c)来表示原始的数据,那么a、 b、 c就是新的基,它们组成新的特征空间。在新的特征空间中,可能所有的数据在c上的投影都接近于0,即可以忽略,那么我们就可以直接用(a,b)来表示数据,这样数据就从三维的(x,y,z)降到了二维的(a,b)。

  如何求新的基(a,b,c) ,一般步骤如下:

1. 对原始数据零均值化(中心化),
2. 求协方差矩阵,
3. 对协方差矩阵求特征向量和特征值,这些特征向量组成了新的特征空间。

PCA–零均值化(中心化)

  中心化即是指变量减去它的均值,使均值为0。其实就是一个平移的过程,平移后使得所有数据的中心是(0,0)
特征选择与特征提取
  只有中心化数据之后,计算得到的方向才能比较好的“概括”原来的数据。此图形象的表述了,中心化的几何意义,就是将样本集的中心平移到坐标系的原点O上。
特征选择与特征提取

PCA降维的几何意义:

  我们对于一组数据,如果它在某一坐标轴上的方差越大,说明坐标点越分散,该属性能够比较好的反映源数据。所以在进行降维的时候,主要目的是找到一个超平面,它能使得数据点的分布方差呈最大,这样数据表现在新的坐标轴上时候已经足够分散了。

知识补充:
	超平面是n维欧氏空间中余维度等于一的线性子空间,也就是必须是(n-1)维度。这是平
面中的直线、空间中的平面之推广(n大于3才被称为“超”平面),是纯粹的数学概念,不是
现实的物理概念。因为是子空间,所以超平面一定经过原点。
	在几何体中,超平面是一维小于其环境空间的子空间。 如果空间是3维的,那么它的超
平面是二维平面,而如果空间是二维的,则其超平面是一维线。 该概念可以用于定义子空间
维度概念的任何一般空间。

方差:关于样本方差分母为什么是n-1理解
特征选择与特征提取
特征选择与特征提取
PCA算法的优化目标就是:
  ① 降维后同一维度的方差最大
  ② 不同维度之间的相关性为0

PCA–协方差矩阵:

  协方差就是一种用来度量两个随机变量关系的统计量。同一元素的协方差就表示该元素的方差,不同元素之间的协方差就表示它们的相关性。
特征选择与特征提取
协方差的性质:
特征选择与特征提取
特征选择与特征提取

PCA–协方差矩阵:

特征选择与特征提取
特征选择与特征提取
比如,三维(x,y,z)的协方差矩阵:
特征选择与特征提取
特征选择与特征提取
协方差矩阵的特点:
  • 协方差矩阵计算的是不同维度之间的协方差, 而不是不同样本之间的。
  • 样本矩阵的每行是一个样本, 每列为一个维度, 所以我们要按列计算均值。
  • 协方差矩阵的对角线就是各个维度上的方差

  特别的,如果做了中心化,则协方差矩阵为(中心化矩阵的协方差矩阵公式):
特征选择与特征提取

对协方差矩阵求特征值、特征矩阵:

  A为n阶矩阵,若数λ和n维非0列向量x满足Ax=λx,那么数λ称为A的特征值, x称为A的对应于特征值λ的特征向量

  式Ax=λx也可写成( A-λE)x=0, E是单位矩阵, 并且|A-λE|叫做A 的特征多项式。 当特征多项式等于0的时候,称为A的特征方程,特征方程是一个齐次线性方程组, 求解特征值的过程其实就是求解特征方程的解。

  对于协方差矩阵A,其特征值( 可能有多个)计算方法为:
特征选择与特征提取
示例:
特征选择与特征提取
特征选择与特征提取
  通过特征值的计算我们可以得到主成分所占的百分比,用来衡量模型的好坏。对于前k个特征值所保留下的信息量计算方法如下:
特征选择与特征提取
  对数字图像矩阵做特征值分解,其实是在提取这个图像中的特征,这些提取出来的特征是一个个的向量,即对应着特征向量。而这些特征在图像中到底有多重要,这个重要性则通过特征值来表示。

  比如一个100x100的图像矩阵A分解之后,会得到一个100x100的特征向量组成的矩阵Q,以及一个100x100的只有对角线上的元素不为0的矩阵E,这个矩阵E对角线上的元素就是特征值,而且还是按照从大到小排列的(取模,对于单个数来说,其实就是取绝对值),也就是说这个图像A提取出来了100个特征,这100个特征的重要性由100个数字来表示,这100个数字存放在对角矩阵E中。

  所以归根结底,特征向量其实反应的是矩阵A本身固有的一些特征,本来一个矩阵就是一个线性变换,当把这个矩阵作用于一个向量的时候,通常情况绝大部分向量都会被这个矩阵A变换得“面目全非”,但是偏偏刚好存在这么一些向量,被矩阵A变换之后居然还能保持原来的样子,于是这些向量就可以作为矩阵的核心代表了。

  于是我们可以说:一个变换(即一个矩阵)可以由其特征值和特征向量完全表述,这是因为从数学上看,这个矩阵所有的特征向量组成了这个向量空间的一组基底。而矩阵作为变换的本质其实就是把一个基底下的东西变换到另一个基底表示的空间中。

2、PCA–鸢尾花实例

  我们通过Python的sklearn库来实现鸢尾花数据进行降维,数据本身是4维的,降维后变成2维。其中样本总数为150,鸢尾花的类别有三种。
特征选择与特征提取

#coding=utf-8

import numpy as np
class PCA():
    def __init__(self,n_components):
        self.n_components = n_components
    
    def fit_transform(self,X):
        self.n_features_ = X.shape[1]
        # 求协方差矩阵
        X = X - X.mean(axis=0)
        self.covariance = np.dot(X.T,X)/X.shape[0]
        # 求协方差矩阵的特征值和特征向量
        eig_vals,eig_vectors = np.linalg.eig(self.covariance)
        # 获得降序排列特征值的序号
        idx = np.argsort(-eig_vals)
        # 降维矩阵
        self.components_ = eig_vectors[:,idx[:self.n_components]]
        # 对X进行降维
        return np.dot(X,self.components_)
 
# 调用
pca = PCA(n_components=2)
X = np.array([[-1,2,66,-1], [-2,6,58,-1], [-3,8,45,-2], [1,9,36,1], [2,10,62,1], [3,5,83,2]])  #导入数据,维度为4
newX=pca.fit_transform(X)
print(newX)                  #输出降维后的数据
#!/usr/bin/env python
# encoding=gbk

import matplotlib.pyplot as plt
import sklearn.decomposition as dp
from sklearn.datasets.base import load_iris

x,y=load_iris(return_X_y=True) #加载数据,x表示数据集中的属性数据,y表示数据标签
pca=dp.PCA(n_components=2) #加载pca算法,设置降维后主成分数目为2
reduced_x=pca.fit_transform(x) #对原始数据进行降维,保存在reduced_x中
red_x,red_y=[],[]
blue_x,blue_y=[],[]
green_x,green_y=[],[]
for i in range(len(reduced_x)): #按鸢尾花的类别将降维后的数据点保存在不同的表中
    if y[i]==0:
        red_x.append(reduced_x[i][0])
        red_y.append(reduced_x[i][1])
    elif y[i]==1:
        blue_x.append(reduced_x[i][0])
        blue_y.append(reduced_x[i][1])
    else:
        green_x.append(reduced_x[i][0])
        green_y.append(reduced_x[i][1])
plt.scatter(red_x,red_y,c='r',marker='x')
plt.scatter(blue_x,blue_y,c='b',marker='D')
plt.scatter(green_x,green_y,c='g',marker='.')
plt.show()

3、PCA算法的优缺点

优点:
1. 完全无参数限制的。在PCA的计算过程中完全不需要人为的设定参数或是根据任何经验
模型对计算进行干预,最后的结果只与数据相关,与用户是独立的。

2. 用PCA技术可以对数据进行降维,同时对新求出的“主元”向量的重要性进行排序,根据
需要取前面最重要的部分,将后面的维数省去,可以达到降维从而简化模型或是对数据进
行压缩的效果。同时最大程度的保持了原有数据的信息。

3. 各主成分之间正交,可消除原始数据成分间的相互影响。

4. 计算方法简单,易于在计算机上实现。
缺点:
1. 如果用户对观测对象有一定的先验知识,掌握了数据的一些特征,却无法通过参数化
等方法对处理过程进行干预,可能会得不到预期的效果,效率也不高。

2. 贡献率小的主成分往往可能含有对样本差异的重要信息。

四、拓展–sklearn库

Sklearn库
  sklearn是机器学习中一个常用的python第三方模块,是进行数据挖掘和分析的便捷高效工具。sklearn对一些常用的机器学习方法进行了封装,在进行机器学习任务时,只需要简单的调用sklearn里的模块就可以实现大多数机器学习任务。sklearn建立于Numpy、SciPy和Matplotlib的基础上。
特征选择与特征提取

#coding=utf-8

import numpy as np
from sklearn.decomposition import PCA
X = np.array([[-1,2,66,-1], [-2,6,58,-1], [-3,8,45,-2], [1,9,36,1], [2,10,62,1], [3,5,83,2]])  #导入数据,维度为4
pca = PCA(n_components=2)   #降到2维
pca.fit(X)                  #训练
newX=pca.fit_transform(X)   #降维后的数据
# PCA(copy=True, n_components=2, whiten=False)
print(pca.explained_variance_ratio_)  #输出贡献率
print(newX)                  #输出降维后的数据

注:本文章参考了百度百科、他人技术博客、八斗学院教程资料、计算机视觉书籍等综合整理而来,如有侵权,联系删除!水平有限,欢迎各位指导交流!文章来源地址https://www.toymoban.com/news/detail-403641.html

到了这里,关于特征选择与特征提取的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Scikit-Learn中的特征选择和特征提取详解

    机器学习在现代技术中扮演着越来越重要的角色。不论是在商业界还是科学领域,机器学习都被广泛地应用。在机器学习的过程中,我们需要从原始数据中提取出有用的特征,以便训练出好的模型。但是,如何选择最佳的特征是一个关键问题。在本文中,我们将探讨特征选择

    2024年02月10日
    浏览(68)
  • 模式识别 第7、8章 特征的选择和提取

    目录 一、基本概念 1.问题的提出 2.基本概念 3.特征选择 4.特征的评价准则 二、类别可分离性判据 1.常用的特征判据 1. 基于类内类间距离的可分性判据  2. 基于概率分布的可分性判据  3. 基于熵的可分性判据 三、特征选择的最优和次优算法 1.特征选择的最优算法 1. 最优算法

    2024年02月03日
    浏览(42)
  • 【RT-DETR有效改进】利用EMAttention加深网络深度提高模型特征提取能力(特征选择模块)

    本文给大家带来的改进机制是 EMAttention注意力机制 ,它的 核心思想是 ,重塑部分通道到批次维度,并将通道维度分组为多个子特征,以保留每个通道的信息并减少计算开销。EMA模块通过编码全局信息来重新校准每个并行分支中的通道权重,并通过跨维度交互来捕获像素级别

    2024年02月21日
    浏览(47)
  • Python | 基于LendingClub数据的分类预测研究Part01——问题重述+特征选择+算法对比

    欢迎交流学习~~ 专栏: 机器学习深度学习 本文利用Python对数据集进行数据分析,并用多种机器学习算法进行分类预测。 具体文章和数据集可以见我所发布的资源:发布的资源 问题一: 在数据集 lending-club 中筛选不同属性,确定至少三组对应训练集及测试集,选用同一种机器

    2023年04月08日
    浏览(41)
  • 机器学习图像特征提取—SIFT特征提取原理及代码实现

    目录 1 SIFT简介 2 SIFT原理及特点 2.1 SIFT算法特点 2.2 SIFT特征检测 3 SIFT代码实现        SIFT,即尺度不变特征变换(Scale-invariant feature transform,SIFT),是用于图像处理领域的一种描述。这种描述具有尺度不变性,可在图像中检测出关键点,是一种局部特征描述子。       SIF

    2024年02月06日
    浏览(45)
  • 【机器学习】特征工程 - 字典特征提取

    「作者主页」: 士别三日wyx 「作者简介」: CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」: 对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 特征工程就是从 「原始数据」 中提取 「特征」 ,以供 「算法」 和 「模型

    2024年02月11日
    浏览(51)
  • 机器学习图像特征提取—颜色(RGB、HSV、Lab)特征提取并绘制直方图

    目录 1 颜色特征 1.1 RGB色彩空间 1.2 HSV色彩空间 1.3 Lab色彩空间 2 使用opencv-python对图像颜色特征提取并绘制直方图 2.1 RGB颜色特征和直方图 2.2 HSV颜色特征和直方图 2.3 Lab颜色特征和直方图 RGB色彩模式是工业界的一种颜色标准,是通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以

    2024年02月08日
    浏览(60)
  • 【机器学习】特征工程 - 文本特征提取TfidfVectorizer

    「作者主页」: 士别三日wyx 「作者简介」: CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」: 对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 对 「文本」 进行特征提取时,一般会用 「单词」 作为特征,即特征词。

    2024年02月12日
    浏览(40)
  • 【特征提取】Hog特征原理简介与代码实践

    在【模式识别】SVM实现人脸表情分类一文中,我曾使用Hog特征+SVM的方式实现表情分类,但对于Hog特征的原理并未做深入整理。此篇将结合 scikit-image 来简单分析Hog特征的原理和维度关系。因为没看过原论文,因此自己的理解可能会有偏差,如有错误,欢迎评论区指正。 在进入

    2023年04月21日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包