机器学习之特征选择(Feature Selection)

1 引言

特征提取和特征选择作为机器学习的重点内容,可以将原始数据转换为更能代表预测模型的潜在问题和特征的过程,可以通过挑选最相关的特征,提取特征和创造特征来实现。要想学习特征选择必然要了解什么是特征提取和特征创造,得到数据的特征之后对特征进行精炼,这时候就要用到特征选择。本文主要介绍特征选择的三种方法:过滤法(filter)、包装法(wrapper)和嵌入法(embedded)。

特征提取(Feature Extraction):从文字,图像,声音等其他非结构化数据中提取新信息作为特征。比如说,从淘宝宝贝的名称中提取出产品类别,产品颜色,是否是网红产品等等。

特征创造(Feature Creation):把现有特征进行组合,或互相计算,得到新的特征。比如说,我们有一列特征是速度,一列特征是距离,我们就可以通过让两列相处,创造新的特征:通过距离所花的时间。

特征选择(Feature Selection):从所有的特征中,选择出有意义,对模型有帮助的特征,以避免必须将所有特征都导入模型去训练的情况。

2 Filter过滤法

过滤法可以理解为在机器学习算法之前的预处理,过滤法特征选择的过程完全独立与任何机器学习算法。根据对特征经过统计检验之后得到的分数,来筛选掉一些相对来说无用的特征,从而优化特征集。

过滤法适用场景:在需要遍历特征或升维的算法之前,对特征进行过滤。

过滤法的目的:在维持算法表现的前提下,帮助算法降低计算成本。

2.1 方差过滤

Variance Threshold是通过特征本身方差来筛选特征的类。比如一个特征本身的方差很小,就表示样本在这个特征上基本没有差异,可能特征中的大多数值都一样,甚至整个特征的取值都相同,那这个特征对于样本区分没有什么作用。所以无论接下来的特征工程要做什么,都要优先消除方差为0的特征。VarianceThreshold有重要参数threshold,表示方差的阈值,表示舍弃所有方差小于threshold的特征,不填默认为0,即删除所有的记录都相同的特征。下面代码简单的实现了方差过滤:

    
  1. import pandas as pd
  2. from sklearn.feature_selection import VarianceThreshold
  3.  
  4. data = pd.read_csv(r"./train.csv")
  5. = data.iloc[:,1:]
  6. = data.iloc[:,0]
  7. print(x.shape)
  8. selector = VarianceThreshold()
  9. x_var0 = selector.fit_transform(x)
  10. print(x_var0.shape)

从结果中可以看到原本数据中有784个特征,经过阈值为 0 的方差过滤之后,剩下708个特征,也就是说之前有76个特征的方差都为0。剩下的708个特征还是比较多的,并不能满足我们的需求,此时我们还需要进一步的特征选择。由于单纯调整阈值比较抽象,我们并不知道特定阈值下会留下多少个特征,留下特征过多或者过少都对我们的结果不利,所以我们可以留下指定数量的特征,比如留下一半的特征,找到特征方差的中位数,再将这个中位数作为 threshold 的值就可以让特征总数减半,代码如下:

    
  1. import pandas as pd
  2. import numpy as np
  3. from sklearn.feature_selection import VarianceThreshold
  4.  
  5.  
  6. data = pd.read_csv(r"./train.csv")
  7. = data.iloc[:,1:]
  8. = data.iloc[:,0]
  9. print(x.shape)
  10. selector = VarianceThreshold(np.median(x.var().values))
  11. x_feature_selection = selector.fit_transform(x)
  12. print(x_feature_selection.shape)

如果特征是二分类,特征的取值就是伯努利随机变量,这些变量的方差计算公式为:Var[X] = p (1 - p),其中 X 为特征矩阵,p为二分类特征中的一类在这个特征中所占的概率。那么假设 p = 0.8,即二分类中某种分类占到80%以上的时候删除特征。代码如下

    
  1. import pandas as pd
  2. import numpy as np
  3. from sklearn.feature_selection import VarianceThreshold
  4. data = pd.read_csv(r"./train.csv")
  5. = data.iloc[:,1:]
  6. = data.iloc[:,0]
  7. print(x.shape)
  8. selector = VarianceThreshold(0.8 *(1-0.8))
  9. x_feature_selection = selector.fit_transform(x)
  10. print(x_feature_selection.shape)

K-近邻算法(KNN)是一种比较简单的分类算法,其原理是利用每个样本到其他样本点的距离来判断每个样本点的相似度,然后对样本进行分类。KNN必须遍历每个特征和样本,因而特征越多,KNN所需要的计算力也就越大。

随机森林或随机决策森林是用于分类,回归和其他任务的集成学习方法,其通过在训练时构建多个决策树并输出作为类的模式(分类)或平均预测(回归)的类来操作。个别树木。随机决策森林纠正决策树过度拟合其训练集的习惯。随机森林随机的选取特征进行分值,本身的运算非常迅速。

实验证明,对特征进行方差过滤之后,KNN的准确率稍有提升,运行时间降低了三分之一。随机森林的准确率略低于KNN,但是花费的算力非常少,不到KNN计算时间的百分之 1 。另外随机森林的准确率略微上升,运行时间并没与什么变化。因此方差过滤并不是适用于所有的算法,因为过滤之后模型可能变好也可能变性能下降。我们就需要针对数据集去进行尝试,也就是调参,选出最优的参数,画学习曲线就可以找到比较好的参数点。但是现实中一般不会花费太多时间在方差过滤的调参上,而是使用阈值为 0 或者阈值很小的方差进行过滤,消除一些明显用不到的特征然后选取其他的特征选择方法继续削减特征数量。

2.2 相关性过滤

一般情况下特征如果和标签的相关性比较大的话,这样的特征能够为我们提供大量的信息。如果特征与标签无关,只会白白浪费我们的算力,还可能给模型带来噪声。在 sklearn 中有三种常用的方法来评判特征和标签之间的相关性:卡方、F检验和互信息。

卡方过滤

卡方过滤是专门针对离散型标签(即分类问题)的相关性过滤。卡方检验类feature_selection.chi2计算每个非负特征和标签之间的卡方统计量,并依照卡方统计量由高到低为特征排名。再结合feature_selection.SelectKBest这个可以输入”评分标准“来选出前K个分数最高的特征的类,我们可以借此除去最可能独立于标签,与我们分类目的无关的特征。下面代码简单实现了卡方过滤:

    
  1. from sklearn.ensemble import RandomForestClassifier as RFC
  2. from sklearn.model_selection import cross_val_score
  3. from sklearn.feature_selection import SelectKBest
  4. from sklearn.feature_selection import chi2
  5.  
  6.  
  7. #留下300个特征
  8. X_fschi = SelectKBest(chi2, k=300).fit_transform(X_fsvar, y)
  9. X_fschi.shape
  10. #验证模型效果
  11. cross_val_score(RFC(n_estimators=10,random_state=0),X_fschi,y,cv=5).mean()

K值变化时,模型的评分也会跟着变化,手动去调整一个一个参数的话效率非常低,我们可以使用学习曲线来获得一个最优的超参数K。代码如下:

    
  1. import pandas as pd
  2. import numpy as np
  3. from sklearn.feature_selection import VarianceThreshold
  4. from sklearn.ensemble import RandomForestClassifier as RFC
  5. from sklearn.model_selection import cross_val_score
  6. from sklearn.feature_selection import SelectKBest
  7. from sklearn.feature_selection import chi2
  8. import matplotlib.pyplot as plt
  9. data = pd.read_csv(r"./train.csv")
  10. = data.iloc[:,1:]
  11. = data.iloc[:,0]
  12. # print(x.shape)
  13. selector = VarianceThreshold(np.median(x.var().values))
  14. x_fsvar = selector.fit_transform(x)
  15. score = []
  16. for i in range(390,200,-10):
  17.     x_fschi = SelectKBest(chi2,= i).fit_transform(x_fsvar,y)
  18.     once = cross_val_score(RFC(n_estimators=10,random_state=0),x_fschi,y,cv=5).mean()
  19.     score.append(once)
  20. plt.plot(range(390,200,-10),score)
  21. plt.show()

从曲线中我们可以看到,随着K值不断的在呢个价模型的表现不断上升,这说明K越大越好,数据中所有的特征都是和标签相关的。但是这个程序运行时间比较长,我们可以用另一种更好的方法选择 K :看 p 值选K。

卡方阿金艳的本质是推测数据之间的差异,卡方检验返回卡方值和 P 值两个统计量,其中卡方值很难界定有效的范围,而 p 值我们一般使用 0.01 或 0.05 作为显著性水平,即p值判断的边界。

p值<=0.05 或0.01>0.05 或 0.01
数据差异差异不是自然形成的这些差异是很自然的样本误差
相关性两组数据是相关的两组数据是相互独立的
原假设拒绝原假设,接受备择假设接受原假设

卡方值大,p值小于0.05的特征是和标签相关联的特征。调用 SelectKBest,可以直接从chi实例化后的模型中获取各个特征所对应的卡方值和 p 值。我们只需要算出来p值大于0.05 的特征有几个,这个个数就是我们想要得到的K值。这里得到的 p 值全为 0,也就是说对于该数据集,方差过滤已经把所有和标签无关的特征都剔除了。

    
  1. chivalue, pvalues_chi = chi2(X_fsvar,y)
  2. print(chivalue)
  3. print(pvalues_chi)
  4.  
  5.  
  6. #k取多少?我们想要消除所有p值大于设定值,比如0.05或0.01的特征:
  7. = chivalue.shape[0] - (pvalues_chi > 0.05).sum()
  8.  
  9.  
  10. #X_fschi = SelectKBest(chi2, k=填写具体的k).fit_transform(X_fsvar, y)
  11. #cross_val_score(RFC(n_estimators=10,random_state=0),X_fschi,y,cv=5).mean()

F检验

F检验,又称ANOVA,方差齐性检验,是用来捕捉每个特征与标签之间的线性关系的过滤方法。它即可以做回归也可以做分类,因此包含feature_selection.f_classif(F检验分类)和feature_selection.f_regression(F检验回归)两个类。其中F检验分类用于标签是离散型变量的数据,而F检验回归用于标签是连续型变量的数据。

和卡方检验一样,这两个类需要和类SelectKBest连用,并且我们也可以直接通过输出的统计量来判断我们到底要设置一个什么样的K。需要注意的是,F检验在数据服从正态分布时效果会非常稳定,因此如果使用F检验过滤,我们会先将数据转换成服从正态分布的方式。

F检验的本质是寻找两组数据之间的线性关系,其原假设是”数据不存在显著的线性关系“。它返回F值和p值两个统计量。和卡方过滤一样,我们希望选取p值小于 0.05 或 0.01 的特征,这些特征与标签时显著线性相关的,而p值大于0.05或0.01的特征则被我们认为是和标签没有显著线性关系的特征,应该被删除。以F检验的分类为例,我们继续在数字数据集上来进行特征选择:

  
  1. chivalue, pvalues_chi = chi2(X_fsvar,y)
  2. chivalue
  3. pvalues_chi
  4. #k取多少?我们想要消除所有p值大于设定值,比如0.05或0.01的特征:
  5. = chivalue.shape[0] - (pvalues_chi > 0.05).sum()
  6. #X_fschi = SelectKBest(chi2, k=填写具体的k).fit_transform(X_fsvar, y)
  7. #cross_val_score(RFC(n_estimators=10,random_state=0),X_fschi,y,cv=5).mean()
  8. from sklearn.feature_selection import f_classif
  9. F, pvalues_f = f_classif(X_fsvar,y)
  10. F
  11. pvalues_f
  12. = F.shape[0] - (pvalues_f > 0.05).sum()
  13. #X_fsF = SelectKBest(f_classif, k=填写具体的k).fit_transform(X_fsvar, y)
  14. #cross_val_score(RFC(n_estimators=10,random_state=0),X_fsF,y,cv=5).mean()

得到的结论和我们用卡方过滤得到的结论一模一样:没有任何特征的p值大于0.01,所有的特征都是和标签相关,因此不需要进行相关性过滤。

互信息法

互信息法是用来捕捉每个特征与标签之间的任意关系(包括线性和非线性关系)的过滤方法。和F检验相似,它既可以做回归也可以做分类,并且包含两个类feature_selection.mutual_info_classif(互信息分类)和feature_selection.mutual_info_regression(互信息回归)。这两个类的用法和参数都和F检验一模一样,不过互信息法比F检验更加强大,F检验只能够找出线性关系,而互信息法可以找出任意关系。

互信息法不返回 p 值或 F 值类似的统计量,它返回“每个特征与目标之间的互信息量的估计”,这个估计量在[0,1]之间取值,为0则表示两个变量独立,为1则表示两个变量完全相关。以互信息分类为例的代码如下

  
  1. from sklearn.feature_selection import mutual_info_classif as MIC
  2. result = MIC(X_fsvar,y)
  3. = result.shape[0] - sum(result <= 0)
  4. #X_fsmic = SelectKBest(MIC, k=填写具体的k).fit_transform(X_fsvar, y)
  5. #cross_val_score(RFC(n_estimators=10,random_state=0),X_fsmic,y,cv=5).mean()

最终得到的互信息量都大于 0,表明所有特征都和标签相关。

3 Embedded嵌入法

嵌入法是一种算法自己决定使用哪些特征的方法,即特征选择和算法训练同时进行。在使用嵌入法时,我们先使用某些机器学习的算法和模型进行训练,得到各个特征的权值系数,根据权值系数从大到小选择特征。这些权值系数往往代表了特征对于模型的某种贡献或某种重要性,比如决策树和树的集成模型中的feature_importances_属性,可以列出各个特征对树的建立的贡献,我们就可以基于这种贡献的评估,找出对模型建立最有用的特征。因此相比于过滤法,嵌入法的结果会更加精确到模型的效用本身,对于提高模型效力有更好的效果。并且,由于考虑特征对模型的贡献,因此无关的特征(需要相关性过滤的特征)和无区分度的特征(需要方差过滤的特征)都会因为缺乏对模型的贡献而被删除掉,可谓是过滤法的进化版。

由于嵌入法时算法自身决定哪些特征可以使用,很难去界定一个标准来判断特征是否是有效的,所以并不会像过滤法那样根据统计知识和指标来对特征进行衡量(如p值应当低于显著水平 0.05)。针对不同的算法,模型的权值系数也会不同,所以不同模型的嵌入法使用起来也是不一样的。此外,由于嵌入法选取特征时是根据算法来决定的,也就是说特征选择的过程伴随着算法的训练过程,那么整个过程非常耗时耗力,这也是嵌入法的一个缺陷。下面我们会以随机森林和决策树模型来学习一下嵌入法。

 feature_selection.SelectFromModel

   
  1. class sklearn.feature_selection.SelectFromModel (estimator, threshold=None, prefit=False, norm_order=1,max_features=None)
参数说明
estimator使用的模型评估器,只要是带feature_importances或者coef_属性,或带有

l1 和 l2 惩罚项的模型都可以使用。

threshold特征重要性的阈值,重要性低于这个阈值的特征都将被删除
prefit默认False,后的模型直接传递给构造函数。如果为True,则必须直接调用

fit和transform,不能使用fit_transform,并且SelectFromModel不能与

cross_val_score,GridSearchCV和克隆估计器的类似实用程序一起使用。

norm_orderK可输入非零整数,正无穷,负无穷,默认值为1。载频鼓起的coef_属性高

于一维的情况下,用于过滤低于阈值的系数的向量的番薯的阶数。

max_features在阈值设定下,要选择的最大特征数。要禁用阈值并仅根据max_features

选择,请设置threshold = -np.inf

前两个参数 estimator 和 threshold在实际应用过程中比较重要,需要我们重点学习。以随机森林为例,借助学习曲线帮助我们寻找最佳特征值。

  
  1. from sklearn.feature_selection import SelectFromModel
  2. from sklearn.ensemble import RandomForestClassifier as RFC
  3. import numpy as np
  4. import matplotlib.pyplot as plt
  5.  
  6. RFC_ = RFC(n_estimators =10,random_state=0)
  7. print(X_embedded.shape)
  8. #模型的维度明显被降低了
  9. #画学习曲线来找最佳阈值
  10.  
  11.  
  12. RFC_.fit(X,y).feature_importances_
  13. threshold = np.linspace(0,(RFC_.fit(X,y).feature_importances_).max(),20)
  14. score = []
  15. for i in threshold:
  16. X_embedded = SelectFromModel(RFC_,threshold=i).fit_transform(X,y)
  17. once = cross_val_score(RFC_,X_embedded,y,cv=5).mean()
  18. score.append(once)
  19. plt.plot(threshold,score)
  20. plt.show()
  21. X_embedded = SelectFromModel(RFC_,threshold=0.00067).fit_transform(X,y)
  22. X_embedded.shape
  23. print(cross_val_score(RFC_,X_embedded,y,cv=5).mean())

通过学习曲线我们可以得到一个最佳的阈值,使得模型的分数达到 96%以上。因此嵌入法可以实现特征的选择。

4 Wrapper包装法

包装法也是一个特征选择和算法训练同时进行的方法,与嵌入法十分相似,它也是依赖于算法自身的选择,比如coef_属性或feature_importances_属性来完成特征选择。但不同的是,我们往往使用一个目标函数作为黑盒来帮助我们选取特征,而不是自己输入某个评估指标或统计量的阈值。包装法在初始特征集上训练评估器,并且通过coef_属性或通过feature_importances_属性获得每个特征的重要性。然后,从当前的一组特征中修剪最不重要的特征。在修剪的集合上递归地重复该过程,直到最终到达所需数量的要选择的特征。区别于过滤法和嵌入法的一次训练解决所有问题,包装法要使用特征子集进行多次训练,因此它所需要的计算成本是最高的。

图中的算法值得并不是我们最终涌过来导入数据的分类和回归算法(即不是随机森林),而是专业的数据挖掘算法,即我们的目标函数。这些数据挖掘算法的核心功能就是选取最佳特征子集。

最典型的目标函数是递归特征消除法(Recursive feature elimination,简写为RFE)。它是一种贪婪的优化算法,旨在找到性能最佳的特征子集。 它反复创建模型,并在每次迭代时保留最佳特征或剔除最差特征,下一次迭代时,它会使用上一次建模中没有被选中的特征来构建下一个模型,直到所有特征都耗尽为止。 然后,它根据自己保留或剔除特征的顺序来对特征进行排名,最终选出一个最佳子集。包装法的效果是所有特征选择方法中最利于提升模型表现的,它可以使用很少的特征达到很优秀的效果。除此之外,在特征数目相同时,包装法和嵌入法的效果能够匹敌,不过它比嵌入法算得更见缓慢,所以也不适用于太大型的数据。相比之下,包装法是最能保证模型效果的特征选择方法。

 feature_selection.RFE

class sklearn.feature_selection.RFE (estimator, n_features_to_select=None, step=1, verbose=0)

参数说明
estimator使用的模型评估器。
n_feature_to_select所需特征数
step每次迭代中希望移除的特征数

RFE类中有两个比较重要的属性,.support_:返回所有的特征的是否最后被选中的布尔矩阵,以及.ranking_返回特征的按数次迭代中综合重要性的排名。类feature_selection.RFECV会在交叉验证循环中执行RFE以找到最佳数量的特征,增加参数cv,其他用法都和RFE一模一样。

  
  1. import pandas as pd
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. from sklearn.ensemble import RandomForestClassifier as RFC
  5. from sklearn.model_selection import cross_val_score
  6. from sklearn.feature_selection import RFE
  7.  
  8.  
  9. data = pd.read_csv(r"./train.csv")
  10. = data.iloc[:,1:]
  11. = data.iloc[:,0]
  12. # print(x.shape)
  13. RFC_ = RFC(n_estimators=10,random_state=0)
  14. score = []
  15. for i in range(1,751,50):
  16.     x_wrapper = RFE(RFC_,n_features_to_select=i,step=50).fit_transform(x,y)
  17.     once = cross_val_score(RFC_,x_wrapper,y,cv=5).mean()
  18.     score.append(once)
  19. plt.figure(figsize=[20,5])
  20. plt.plot(range(1,751,50),score)
  21. plt.xticks(range(1,751,50))
  22. plt.show()

结果可以看到,使用包装法之后,只需要 50 个特征,模型的表现就已经达到了 90% 以上,比嵌入法和过滤法得到的特征子集要好很多。

5 总结

本文讲了过滤法、嵌入法和包装法三种特征选择方法。三种方法中过滤法最为简单快速,需要的计算时间也最短,但是也较为粗略,实际应用过程中,通常只作为数据的预处理,剔除掉部分明显不需要的特征,然后使用其他方法进一步特征选择。嵌入式和包装法更为精确,更适合具体到算法中去调整。计算量也较大,相应的运行时间也比较长。当数据量比较大时,优先使用方差过滤和互信息法对数据进行预处理,然后在使用其他的特征选择方法。使用逻辑回归时,优先使用嵌入法。使用支持向量机时,优先使用包装法。

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

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

相关文章

算法100例(持续更新)

算法100道经典例子&#xff0c;按算法与数据结构分类 1、祖玛游戏2、找下一个更大的值3、换根树状dp4、一笔画完所有边5、树状数组&#xff0c;数字1e9映射到下标1e56、最长回文子序列7、超级洗衣机&#xff0c;正负值传递次数8、Dijkstra9、背包问题&#xff0c;01背包和完全背…

React Hooks 全解: 常用 Hooks 及使用场景详解

React Hooks 是 React 16.8 版本引入的一项重要特性,它极大地简化和优化了函数组件的开发过程。 React 中常用的 10 个 Hooks,包括 useState、useEffect、useContext、useReducer、useCallback、useMemo、useRef、useLayoutEffect、useImperativeHandle 和 useDebugValue。这些…

计算机网络——实现smtp和pop3邮件客户端

实验目的 运用各种编程语言实现基于 smtp 协议的 Email 客户端软件。 实验内容 1. 选择合适的编程语言编程实现基于 smtp 协议的 Email 客户端软件。 2. 安装 Email 服务器或选择已有的 Email 服务器&#xff0c;验证自己的 Email 客户端软件是否能进行正常的 Email 收发功…

GAMS104 现代游戏引擎 2

渲染的难点可以分为一下三部分&#xff1a;如何计算入射光线、如何考虑材质以及如何实现全局光照。 渲染的难点之一在于阴影&#xff0c;或者说是光的可见性。如何做出合适的阴影效果远比想象中要难得多&#xff0c;在实践中往往需要通过大量的技巧才能实现符合人认知的阴影效…

OpenHarmony实例应用:【常用组件和容器低代码】

介绍 本篇Codelab是基于ArkTS语言的低代码开发方式实现的一个简单实例。具体实现功能如下&#xff1a; 创建一个低代码工程。通过拖拽的方式实现任务列表和任务信息界面的界面布局。在UI编辑界面实现数据动态渲染和事件的绑定。 最终实现效果如下&#xff1a; 相关概念 低代…

Tuxera Ntfs for mac 2023中文解锁版安装、密钥下载与激活教程 Tuxera激活码 tuxera破解

Tuxera Ntfs for mac2023是Mac中专用于读写外置存储的工具&#xff0c;具有强大的磁盘管理和修复功能&#xff0c;它在Mac上完全读写NTFS格式硬盘&#xff0c;快捷的访问、编辑、存储和传输文件。能够在 Mac 上读写 Windows NTFS 文件系统。Tuxera NTFS 实现在Mac OS X系统读写…

2024妈妈杯数学建模A 题思路分析-移动通信网络中 PCI 规划问题

# 1 赛题 A 题 移动通信网络中 PCI 规划问题 物理小区识别码(PCI)规划是移动通信网络中下行链路层上&#xff0c;对各覆盖 小区编号进行合理配置&#xff0c;以避免 PCI 冲突、 PCI 混淆以及 PCI 模 3 干扰等 现象。 PCI 规划对于减少物理层的小区间互相干扰(ICI)&#xff0c;增…

mysql搭建主从

mysql搭建主从: 1:拉取mysql镜像 docker pull mysql2:创建主从对应目录 3:建立一个简易的mysql docker run -it --name mytest -e MYSQL_ROOT_PASSWORD123 -d mysql4:进入这个简易的mysql;从中获取my.cnf文件 docker exec -it mytest bash5:从容器中将my.cnf拷贝到 /3306/c…

rspack 使用构建vue3脚手架

基于 Rust 的高性能 Web 构建工具。rspack 主要适配 webpack 生态&#xff0c;对于绝大多数 webpack 工具库都是支持的。 启动速度快&#xff1b;增量热更新快。兼容 webpack 生态&#xff1b;内置了 ts、jsx、css、css modules 等开箱即用。生产优化&#xff0c;tree shaking…

树莓派驱动开发--搭建环境篇(保姆级)

前言&#xff1a;树莓派的环境搭建关系到之后的驱动开发&#xff0c;故一个好的环境能让你顺手完成驱动开发&#xff01;我使用的是64位树莓派4b&#xff01;有显示屏的前提&#xff01;&#xff01;&#xff01;&#xff08;因为wifi连接太刁钻了&#xff09; 一、ubantu相关 …

Linux如何安装kernel-debuginfo包以支持获取未压缩内核映像vmlinux?(yum | wget、rpm -ivh)

基础信息 本文以AnolisOS为例子&#xff0c;Centos和Ubuntu类似&#xff0c;核心都是安装kernel-debuginfo和kernel-debuginfo-common的rpm包 并且需要和内核版本子版本完全一致&#xff08;本质是使用同一份代码编译的&#xff09;假设系统安装的是8.6版本&#xff1a;比如ht…

【软件设计师】计算机软考下午题试题六,Java设计模式之简单工厂模式。

【软件设计师】计算机软考下午题试题六&#xff0c;Java设计模式之简单工厂模式。 代码如下&#xff1a; //简单工厂模式 public class SimpleFactory {public static void main(String[] args) {Product ProductAFactory.createProduct("A");ProductA.info();Produc…

C++11 数据结构2 线性表的链式存储,实现,测试

线性表的链式存储 --单链表 前面我们写的线性表的顺序存储(动态数组)的案例&#xff0c;最大的缺点是插入和删除时需要移动大量元素&#xff0c;这显然需要耗费时间&#xff0c;能不能想办法解决呢&#xff1f;链表。 链表为了表示每个数据元素与其直接后继元素之间的逻辑关系…

-bash:./app:没有那个文件或目录(已解决)

目录下有文件&#xff0c;并且权限也是够的&#xff0c;都是就是是没有。 解决方法&#xff1a; 进入/bin&#xff0c;执行命令 file bash 如上图&#xff0c;可以发现&#xff0c;bash是32-bit&#xff0c; 进入app所在目录&#xff0c;执行 file app 如上图&#xff0…

Java 基于微信小程序的校园失物招领小程序,附源码

博主介绍&#xff1a;✌程序员徐师兄、8年大厂程序员经历。全网粉丝15w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

数字经济专家高泽龙担任工信部元宇宙标准化委员会委员

数字经济专家高泽龙受聘担任工信部元宇宙标准化委员会委员&#xff0c;出席工作组成立大会暨第一次全体委员会议。 第一届元宇宙国标、团标以及标委会工作组会议顺利召开&#xff01; 同时&#xff0c;正式成为工信部中国人工智能产业发展联盟科技伦理工作组成员&#xff01;

jmeter使用之生成html测试报告

测试的最终结果是需要给出一份报告&#xff0c;那么在用jmeter测试时怎么生成一份报告呢&#xff0c;以下针对jmeter如何生成html报告进行简单介绍 一、首先把测试脚本写好二、利用命令生成html报告 命令&#xff1a;jmeter -n -t 【Jmx脚本位置】-l 【结果文件result.jtl存放…

桥接模式:解耦抽象与实现的设计艺术

在软件设计中&#xff0c;桥接模式是一种结构型设计模式&#xff0c;旨在将抽象部分与其实现部分分离&#xff0c;使它们可以独立地变化。这种模式通过提供更加灵活的代码结构帮助软件开发人员处理不断变化的需求&#xff0c;特别是在涉及多平台应用开发时。本文将详细介绍桥接…

sql注入之宽字节注入

1.1 宽字节注入原理 宽字节注入&#xff0c;在 SQL 进行防注入的时候&#xff0c;一般会开启 gpc&#xff0c;过滤特殊字符。 一般情况下开启 gpc 是可以防御很多字符串型的注入&#xff0c;但是如果数据库编码不 对&#xff0c;也可以导致 SQL 防注入绕过&#xff0c;达到注入…

【网站项目】农产品自主供销小程序

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…