300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 独家 | 使用Python实现机器学习特征选择的4种方法(附代码)

独家 | 使用Python实现机器学习特征选择的4种方法(附代码)

时间:2021-02-09 02:07:09

相关推荐

独家 | 使用Python实现机器学习特征选择的4种方法(附代码)

作者:SugandhaLahoti

翻译:李洁

校对:杨光

本文约3500字,建议阅读13分钟。

本文中,我们将研究从数据集中选择特征的不同方法;同时通过使用Python中Scikit-learn(sklearn)库实现讨论了特征选择算法的类型。

注:本文节选自AnkitDixit所著的《集成机器学习》(EnsembleMachineLearning)一书。这本书组合强大的机器学习算法来建立优化模型,可以作为初学者的指南。

在本文中,我们将研究从数据集中选择特征的不同方法;同时通过使用Python中Scikit-learn(sklearn)库实现讨论了特征选择算法的类型:

单变量选择

递归特征消除(RFE)

主成分分析(PCA)

选择重要特征(特征重要度)

我们简要介绍了前三种算法及其实现。然后我们将详细讨论在数据科学社区中广泛使用的选择重要特征(特性重要度)部分的内容。

单变量选择

统计测试可用于选择那些与输出变量关系最强的特征。

scikit-learn库提供了SelectKBest类,它可以与一组不同的统计测试一起使用,以选择特定数量的特征。

下面的例子使用chi²非负性特征的统计测试,从皮马印第安人糖尿病发病数据集中选择了四个最好的特征:

1.#Feature Extraction with Univariate Statistical Tests (Chi-squared for classification)

2.#Import the required packages

3.#Import pandas to read csv import pandas

4.#Import numpy for array related operations import numpy

5.#Import sklearn's feature selection algorithm

6.fromsklearn.feature_selection importSelectKBest

7.#Import chi2 for performing chi square test from sklearn.feature_selection import chi2

8.#URL for loading the dataset

9.url="https://archive.ics.uci.edu/ml/machine-learning-databases/pima-indiansdiabetes/pima-indians-diabetes.data"

10.#Define the attribute names

11.names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']

12.#Create pandas data frame by loading the data from URL

13.dataframe = pandas.read_csv(url, names=names

14.#Create array from data values

15.array = dataframe.values

16.#Split the data into input and target

17.X=array[:,0:8]

18.Y=array[:,8]

19.#We will select the features using chi square

20.test = SelectKBest(score_func=chi2, k=4)

21.#Fit the function for ranking the features by score

22.fit = test.fit(X, Y)

23.#Summarize scores numpy.set_printoptions(precision=3) print(fit.scores_)

24.#Apply the transformation on to dataset

25.features = fit.transform(X)

26.#Summarizeselectedfeaturesprint(features[0:5,:])

你可以看到每个参数的得分,以及所选择的四个参数(得分最高的):plas、test、mass和age。

每个特征的分数为:

1.[111.521411.88717.60553.108 2175.565 127.669 5.393

2.181.304]

被选出的特征是:

1.[[148. 0. 33.650. ]

2.[85. 0. 26.631. ]

3.[183. 0. 23.332. ]

4.[89. 94. 28.121. ]

5.[137. 168. 43.133. ]]

递归特征消除(RFE)

RFE的工作方式是递归地删除参数并在保留的参数上构建模型。它使用模型精度来判断哪些属性(以及属性的组合)对预测目标参数贡献最大。你可以在scikit-learn的文档中了解更多关于RFE类的信息。

下面的示例使用RFE和logistic回归算法来选出前三个特征。算法的选择并不重要,只需要熟练并且一致:

1.#Import the required packages

2.#Import pandas to read csv import pandas

3.#Import numpy for array related operations import numpy

4.#Import sklearn's feature selection algorithm from sklearn.feature_selection import RFE

5.#Import LogisticRegression for performing chi square test from sklearn.linear_model import LogisticRegression

6.#URL for loading the dataset

7.url =

8."https://archive.ics.uci.edu/ml/machine-learning-databases/pima-indians-diabetes/pima-indians-diabetes.data"

9.#Define the attribute names

10.names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']

11.#Create pandas data frame by loading the data from URL

12.dataframe = pandas.read_csv(url, names=names)

13.

14.#Create array from data values

15.array = dataframe.values

16.

17.#Split the data into input and target

18.X=array[:,:8]

19.Y=array[:,8]

20.#Feature extraction

21.model = LogisticRegression() rfe = RFE(model, 3)

22.fit = rfe.fit(X, Y)

23.print("NumFeatures:%d"%fit.n_features_)print("SelectedFeatures:%s"%fit.support_)

24.print("FeatureRanking:%s"%fit.ranking_)

执行完上述代码后,我们可以得到:

1.NumFeatures:3

2.SelectedFeatures:[TrueFalseFalseFalseFalseTrueTrueFalse]

3.FeatureRanking:[12356114]

你可以看到RFE选择了前三个特性,即preg、mass和pedi。这些在support_数组中被标记为True,在ranking_数组中被标记为首选(标记为1)。

主成分分析

PCA使用线性代数将数据集转换为压缩格式。通常,它被认为是一种数据约简技术。PCA的一个属性是,你可以选择转换结果中的维数或主成分的数量。

在接下来的例子中,我们使用PCA并选择了三个主成分:

1.#Import the required packages

2.#Import pandas to read csv import pandas

3.#Import numpy for array related operations import numpy

4.#Import sklearn's PCA algorithm

5.fromsklearn.decomposition importPCA

6.#URL for loading the dataset

7.url =

8."https://archive.ics.uci.edu/ml/machine-learning-databases/pima-indiansdiabetes/pima-indians-diabetes.data"

9.#Define the attribute names

10.names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']

11.dataframe = pandas.read_csv(url, names=names)

12.#Create array from data values

13.array = dataframe.values

14.#Split the data into input and target

15.X=array[:,0:8]

16.Y=array[:,8]

17.#Feature extraction

18.pca = PCA(n_components=3) fit = pca.fit(X)

19.#Summarize components

20.print("ExplainedVariance:%s")%fit.explained_variance_ratio_

21.print(ponents_)

你可以看到,转换后的数据集(三个主成分)与源数据几乎没有相似之处:

1.ExplainedVariance:[0.888546630.061590780.02579012]

2.[[-2.02176587e-03 9.78115765e-02 1.60930503e-02 6.07566861e-02

3.9.93110844e-01 1.40108085e-02 5.37167919e-04 -3.56474430e-03]

4.[ -2.26488861e-02 -9.72210040e-01 -1.41909330e-01 5.78614699e-02 9.46266913e-02 -4.69729766e-02 -8.16804621e-04 -1.40168181e-01

5.[ -2.24649003e-02 1.43428710e-01 -9.22467192e-01 -3.07013055e-01 2.09773019e-02 -1.32444542e-01 -6.39983017e-04 -1.25454310e-01]]

选择重要特征(特性重要度)

特征重要度是一种利用训练好的有监督分类器来选择特征的技术。当我们训练分类器(如决策树)时,我们计算每个参数以创建分割;我们可以使用这个度量作为特征选择器。让我们来详细了解一下。

随机森林由于其相对较好的准确性、鲁棒性和易用性而成为最受欢迎的机器学习方法之一。它们还提供了两种简单易行的特征选择方法——均值降低杂质和均值降低准确度。

随机森林由许多决策树组成。决策树中的每个节点都是一个基于单个特征的条件,其设计目的是将数据集分割成两个,以便相似的响应值最终出现在相同的集合中。选择(局部)最优条件的度量叫做杂质。对于分类问题,它通常是基尼杂质或信息增益/熵,而对于回归树,它是方差。因此,当训练一棵树时,可以通过每个特征减少的树中加权杂质的多少来计算。对于森林,可以对每个特征的杂质减少量进行平均,并根据该方法对特征进行排序。

让我们看一下如何使用随机森林分类器来进行特征选择,并评估特征选择前后分类器的准确性。我们将使用Otto数据集。该数据集可从kaggle免费获得(你需要注册kaggle才能下载该数据集)。你可以从/c/otto-group-product-classifics-challenge/data下载训练集train.csv.zip,然后将解压缩的train.csv文件放在你的工作目录中。

这个数据集描述了超过61,000个产品的93个模糊细节,这些产品被分成10个产品类别(例如,时尚类、电子产品类等)。输入参数是某种类型的不同事件的计数。

训练目标是对新产品作为10个类别中每一个类别的概率数组做出预测,并使用多级对数损失(也称为交叉熵)对模型进行评估。

我们将从导入所有库开始:

1.#Import the supporting libraries

2.#Import pandas to load the dataset from csv file

3.frompandas importread_csv

4.#Import numpy for array based operations and calculations

5.importnumpy as np

6.#Import Random Forest classifier class from sklearn

7.fromsklearn.ensemble importRandomForestClassifier

8.#Import feature selector class select model of sklearn

9.from sklearn.feature_selection

10.importSelectFromModel

11.np.random.seed(1)

定义一个方法用于将我们的数据集分为训练数据和测试数据;我们将在训练数据部分对数据集进行训练,测试数据部分将用于训练模型的评估:

1.#Function to create Train and Test set from the original dataset

2.defgetTrainTestData(dataset,split):

3.np.random.seed(0)

4.training = []

5.testing = []

6.np.random.shuffle(dataset) shape = np.shape(dataset)

7.trainlength = np.uint16(np.floor(split*shape[0]))

8.foriinrange(trainlength):

9.training.append(dataset[i])

10.foriinrange(trainlength,shape[0]):

11.testing.append(dataset[i])

12.training = np.array(training) testing = np.array(testing)

13.returntraining,testing

还需要添加一个函数来评估模型的准确性;以预测输出和实际输出为输入,计算准确率百分比:

1.#Function to evaluate model performance

2.defgetAccuracy(pre,ytest):

3.count = 0

4.foriinrange(len(ytest)):

5.ifytest[i]==pre[i]:

6.count+=1

7.acc = float(count)/len(ytest)

8.returnacc

现在要导入数据集。我们将导入train.csv文件;该文件包含61,000多个训练实例。我们的示例将使用50000个实例,其中使用35,000个实例来训练分类器,并使用15,000个实例来测试分类器的性能:

1.#Load dataset as pandas data frame

2.data = read_csv('train.csv')

3.#Extract attribute names from the data frame

4.feat = data.keys()

5.feat_labels = feat.get_values()

6.#Extract data values from the data frame

7.dataset = data.values

8.#Shuffle the dataset

9.np.random.shuffle(dataset)

10.#We will select 50000 instances to train the classifier

11.inst = 50000

12.

13.#Extract 50000 instances from the dataset

14.dataset=dataset[0:inst,:]

15.

16.#Create Training and Testing data for performance evaluation

17.train,test = getTrainTestData(dataset, 0.7)

18.

19.#Split data into input and output variable with selected features

20.Xtrain=train[:,0:94]ytrain=train[:,94]shape=np.shape(Xtrain)

21.

22.print("Shape of the dataset ",shape)

23.

24.#Print the size of Data in MBs

25.print("SizeofDatasetbeforefeatureselection:%.2fMB"%(Xtrain.nbytes/1e6))

26.

注意下这里的数据大小;由于我们的数据集包含约35000个训练实例,带有94个参数;我们的数据集非常大。让我们来看一下:

1.Shape of the dataset (35000, 94)

2.SizeofDatasetbeforefeatureselection:26.32MB

如你所见,我们的数据集中有35000行和94列,数据大小超过26MB。

在下一个代码块中,我们将配置我们的随机森林分类器;我们会使用250棵树,最大深度为30,随机特征的数量为7。其他超参数将是sklearn的默认值:

1.#Lets select the test data for model evaluation purpose

2.Xtest=test[:,0:94]ytest=test[:,94]

3.

4.#Create a random forest classifier with the following Parameters

5.trees = 250

6.max_feat= 7

7.max_depth = 30

8.min_sample = 2

9.clf = RandomForestClassifier(n_estimators=trees, max_features=max_feat, max_depth=max_depth, min_samples_split= min_sample, random_state=0, n_jobs=-1)

10.

11.#Train the classifier and calculate the training time

12.importtime

13.start = time.time()

14.clf.fit(Xtrain, ytrain)

15.end = time.time()

16.

17.#Lets Note down the model training time

18.print("ExecutiontimeforbuildingtheTreeis:%f"%(float(end)-float(start)))

19.pre = clf.predict(Xtest)

20.

21.#Let'sseehowmuchtimeisrequiredtotrainthemodelonthetrainingdataset:

22.ExecutiontimeforbuildingtheTreeis:2.913641

23.

24.#Evaluate the model performance for the test data

25.acc = getAccuracy(pre, ytest)

26.

27.print("Accuracy of model before feature selection is %.2f"%(100*acc))

模型的精确度是:

1.Accuracy of model before feature selection is 98.82

正如所看到的,我们获得了非常好的精确度,因为我们将几乎99%的测试数据分类为正确的类别。这意味着我们在15,000个实例中对大概14,823个实例进行了正确的分类。

所以,现在问题是:我们应该进一步改进吗?好吧,为什么不呢?如果可能的话,我们一定需要进行更多的改进;在这里,我们将使用特征重要度来选择特征。如你所知,在树的建造过程中,我们使用杂质度量来选择节点。选择杂质最少的参数值作为树中的节点。我们可以使用类似的标准来选择特征。我们可以给杂质更少的特征更多的重要度,这可以使用sklearn库的feature_importances_函数来实现。让我们来看一下每个特征的重要度:

1.#Oncewehavetrainedthemodelwewillrankallthefeaturesforfeatureinzip(feat_labels,clf.feature_importances_):

2.print(feature)

3.('id',0.3334665045183)

4.('feat_1', 0.0036186958628801214)

5.('feat_2', 0.0037243050888530957)

6.('feat_3', 0.011579217472062748)

7.('feat_4', 0.010297382675187445)

8.('feat_5', 0.0010359139416194116)

9.('feat_6', 0.00038171336038056165)

10.('feat_7', 0.0024867672489765021)

11.('feat_8', 0.0096689721610546085)

12.('feat_9', 0.007906150362995093)

13.('feat_10', 0.0022342480802130366)

14.

正如你看到的,每个特征都有不同的重要度,这取决于它对最终预测的贡献值。

我们将使用这些重要度评分来对我们的特征进行排序;在接下来的部分中,我们将选取特征重要度大于0.01的特征进行模型训练:

1.#Select features which have higher contribution in the final prediction

2.sfm = SelectFromModel(clf, threshold=0.01)

3.sfm.fit(Xtrain,ytrain)

4.

这里,我们将根据所选的特征参数转换输入的数据集。在下一个代码块中,我们会转换数据集。然后,我们将检查新数据集的大小和形状:

1.#Transform input dataset

2.Xtrain_1 = sfm.transform(Xtrain)

3.Xtest_1 = sfm.transform(Xtest)

4.

5.#Let's see the size and shape of new dataset

6.print("SizeofDatasetbeforefeatureselection:%.2fMB"%(Xtrain_1.nbytes/1e6))

7.shape = np.shape(Xtrain_1)

8.print("Shape of the dataset ",shape)

9.

10.SizeofDatasetbeforefeatureselection:5.60MB

11.Shape of the dataset (35000, 20)

12.

看到数据集的形状了吗?经过特征选择后,我们只剩下20个特征,这使得数据库的大小从26MB减少到了5.60MB,比原来的数据集减少了80%左右。

在下一个代码块中,我们将使用与前面相同的超参数训练一个新的随机森林分类器,并在测试集上进行了测试。我们来看看修改训练集后得到的精确度是多少:

1.#Model training time

2.start = time.time() clf.fit(Xtrain_1, ytrain) end = time.time()

3.print("ExecutiontimeforbuildingtheTreeis:%f"%(float(end)-float(start)))

4.

5.#Let's evaluate the model on test data

6.pre = clf.predict(Xtest_1) count = 0

7.acc2 = getAccuracy(pre, ytest)

8.print("Accuracy after feature selection %.2f"%(100*acc2))

9.

10.ExecutiontimeforbuildingtheTreeis:1.711518

11.Accuracy after feature selection 99.97

12.

看到了吗!使用修改后的数据集,我们获得了99.97%的准确率,这意味着我们把14,996个实例分到了正确的类别,而之前我们只正确地分类了14,823个实例。

这是我们在特征选择过程中取得的巨大进步;我们可以将所有的结果总结如下表:

上表显示了特征选择的实际优势。可以看到我们显著地减少了特征的数量,这减少了模型的复杂性和数据集的维度。在减小维度后,我们需要更少的训练时间,最终我们克服了过拟合的问题,获得了比以前更高的精确度。

本文我们共探讨了机器学习中特征选择的4种方法。

如果你发现这篇文章很有用,请阅读《集成机器学习》一书,了解关于叠加泛化和其他技术的更多信息。

原文标题:

4 ways to implement feature selection in Python for machine learning

原文链接:

/4-ways-implement-feature-selection-python-machine-learning/

编辑:王菁

校对:林亦霖

译者简介

李洁,香港科技大学电信学硕士毕业生,现任北京师范大学香港浸会大学联合学院数据科学系助教。喜欢数据科学,喜欢阅读,喜欢研究代码和做手工。希望一直保持学习的状态和对生活的热爱,每天都快乐而有进步~

翻译组招募信息

工作内容:需要一颗细致的心,将选取好的外文文章翻译成流畅的中文。如果你是数据科学/统计学/计算机类的留学生,或在海外从事相关工作,或对自己外语水平有信心的朋友欢迎加入翻译小组。

你能得到:定期的翻译培训提高志愿者的翻译水平,提高对于数据科学前沿的认知,海外的朋友可以和国内技术应用发展保持联系,THU数据派产学研的背景为志愿者带来好的发展机遇。

其他福利:来自于名企的数据科学工作者,北大清华以及海外等名校学生他们都将成为你在翻译小组的伙伴。

点击文末“阅读原文”加入数据派团队~

转载须知

如需转载,请在开篇显著位置注明作者和出处(转自:数据派ID:datapi),并在文章结尾放置数据派醒目二维码。有原创标识文章,请发送【文章名称-待授权公众号名称及ID】至联系邮箱,申请白名单授权并按要求编辑。

发布后请将链接反馈至联系邮箱(见下方)。未经许可的转载以及改编者,我们将依法追究其法律责任。

点击“阅读原文”拥抱组织

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。