在Python中实现机器学习功能的4种方法
- 来源 | 愿码(ChainDesk.CN)内容编辑
- 愿码Slogan | 连接每个程序员的故事
- 网站 | http://chaindesk.cn
- 愿码愿景 | 打造全学科IT系统免费课程,助力小白用户、初级工程师0成本免费系统学习、低成本进阶,帮助BAT一线资深工程师成长并利用自身优势创造睡后收入。
- 官方公众号 | 愿码 | 愿码服务号 | 区块链部落
- 免费加入愿码全思维工程师社群 | 任一公众号回复“愿码”两个字获取入群二维码
本文阅读时长:13min
在本文中,我们将介绍从数据集中选择要素的不同方法; 并使用Scikit-learn(sklearn)库讨论特征选择算法的类型及其在Python中的实现 :
- 单变量特征选择
- 递归特征消除(RFE)
- 主成分分析(PCA)
- 特征选择 (feature importance)
单变量特征选择
统计测试可用于选择与输出变量具有最强关系的那些特征。
scikit-learn库提供SelectKBest类,可以与一组不同的统计测试一起使用,以选择特定数量的功能。
以下示例使用chi平方(chi ^ 2)统计检验非负特征来选择Pima Indians糖尿病数据集中的四个最佳特征:
#Feature Extraction with Univariate Statistical Tests (Chi-squared for classification)
#Import the required packages
#Import pandas to read csv import pandas
#Import numpy for array related operations import numpy
#Import sklearn's feature selection algorithm
from sklearn.feature_selection import SelectKBest
#Import chi2 for performing chi square test from sklearn.feature_selection import chi2
#URL for loading the dataset
url ="https://archive.ics.uci.edu/ml/machine-learning-databases/pima-indians diabetes/pima-indians-diabetes.data"
#Define the attribute names
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
#Create pandas data frame by loading the data from URL
dataframe = pandas.read_csv(url, names=names)
#Create array from data values
array = dataframe.values
#Split the data into input and target
X = array[:,0:8]
Y = array[:,8]
#We will select the features using chi square
test = SelectKBest(score_func=chi2, k=4)
#Fit the function for ranking the features by score
fit = test.fit(X, Y)
#Summarize scores numpy.set_printoptions(precision=3) print(fit.scores_)
#Apply the transformation on to dataset
features = fit.transform(X)
#Summarize selected features print(features[0:5,:])
每个属性的分数和所选的四个属性(分数最高的分数):plas,test,mass和age。
每个功能的分数:
[111.52 1411.887 17.605 53.108 2175.565 127.669 5.393
181.304]
特色:
[[148. 0. 33.6 50. ]
[85. 0. 26.6 31. ]
[183. 0. 23.3 32. ]
[89. 94. 28.1 21. ]
[137. 168. 43.1 33. ]]
递归特征消除(RFE)
RFE通过递归删除属性并在剩余的属性上构建模型来工作。它使用模型精度来识别哪些属性(和属性组合)对预测目标属性的贡献最大。以下示例使用RFE和逻辑回归算法来选择前三个特征。算法的选择并不重要,只要它技巧性和一致性:
#Import the required packages
#Import pandas to read csv import pandas
#Import numpy for array related operations import numpy
#Import sklearn's feature selection algorithm from sklearn.feature_selection import RFE
#Import LogisticRegression for performing chi square test from sklearn.linear_model import LogisticRegression
#URL for loading the dataset
url =
"https://archive.ics.uci.edu/ml/machine-learning-databases/pima-indians-dia betes/pima-indians-diabetes.data"
#Define the attribute names
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
#Create pandas data frame by loading the data from URL
dataframe = pandas.read_csv(url, names=names)
#Create array from data values
array = dataframe.values
#Split the data into input and target
X = array[:,0:8]
Y = array[:,8]
#Feature extraction
model = LogisticRegression() rfe = RFE(model, 3)
fit = rfe.fit(X, Y)
print("Num Features: %d"% fit.n_features_) print("Selected Features: %s"% fit.support_) print("Feature Ranking: %s"% fit.ranking_)
执行后,我们将获得:
Num Features: 3
Selected Features: [ True False False False False True True False]
Feature Ranking: [1 2 3 5 6 1 1 4]
您可以看到RFE选择了前三个功能,如preg,mass和pedi。这些在support_数组中标记为True,并在ranking_数组中标记为选项1。
主成分分析(PCA)
PCA使用线性代数将数据集转换为压缩形式。通常,它被认为是数据简化技术。PCA的一个属性是您可以选择转换结果中的维数或主成分数。
在以下示例中,我们使用PCA并选择三个主要组件:
#Import the required packages
#Import pandas to read csv import pandas
#Import numpy for array related operations import numpy
#Import sklearn's PCA algorithm
from sklearn.decomposition import PCA
#URL for loading the dataset
url =
"https://archive.ics.uci.edu/ml/machine-learning-databases/pima-indians diabetes/pima-indians-diabetes.data"
#Define the attribute names
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
dataframe = pandas.read_csv(url, names=names)
#Create array from data values
array = dataframe.values
#Split the data into input and target
X = array[:,0:8]
Y = array[:,8]
#Feature extraction
pca = PCA(n_components=3) fit = pca.fit(X)
#Summarize components
print("Explained Variance: %s") % fit.explained_variance_ratio_
print(fit.components_)
您可以看到转换后的数据集(三个主要组件)与源数据几乎没有相似之处:
Explained Variance: [ 0.88854663 0.06159078 0.02579012]
[[ -2.02176587e-03 9.78115765e-02 1.60930503e-02 6.07566861e-02
9.93110844e-01 1.40108085e-02 5.37167919e-04 -3.56474430e-03]
[ -2.26488861e-02 -9.72210040e-01 -1.41909330e-01 5.78614699e-02 9.46266913e-02 -4.69729766e-02 -8.16804621e-04 -1.40168181e-01
[ -2.24649003e-02 1.43428710e-01 -9.22467192e-01 -3.07013055e-01 2.09773019e-02 -1.32444542e-01 -6.39983017e-04 -1.25454310e-01]]
特征选择 (feature importance)
特征重要性是用于使用训练有监督的分类器来选择特征的技术。当我们训练分类器(例如决策树)时,我们会评估每个属性以创建分裂; 我们可以将此度量用作特征选择器。让我们详细了解它。
随机森林是最受欢迎的 机器学习方法之一,因为它们具有相对较好的准确性,稳健性和易用性。它们还提供了两种直接的特征选择方法 - 平均降低杂质和平均降低精度。
随机森林由许多决策树组成。决策树中的每个节点都是单个要素上的条件,旨在将数据集拆分为两个,以便类似的响应值最终出现在同一个集合中。选择(局部)最佳条件的度量称为杂质。对于分类,它通常是基尼系数
杂质或信息增益/熵,对于回归树,它是方差。因此,当训练树时,可以通过每个特征减少树中的加权杂质的程度来计算它。对于森林,可以对每个特征的杂质减少进行平均,并且根据该度量对特征进行排序。
让我们看看如何使用随机森林分类器进行特征选择,并评估特征选择前后分类器的准确性。我们将使用Otto数据集。
该数据集描述了超过61,000种产品的93个模糊细节,这些产品分为10个产品类别(例如,时装,电子产品等)。输入属性是某种不同事件的计数。
目标是将新产品的预测作为10个类别中每个类别的概率数组,并使用多类对数损失(也称为交叉熵)来评估模型。
我们将从导入所有库开始:
#Import the supporting libraries
#Import pandas to load the dataset from csv file
from pandas import read_csv
#Import numpy for array based operations and calculations
import numpy as np
#Import Random Forest classifier class from sklearn
from sklearn.ensemble import RandomForestClassifier
#Import feature selector class select model of sklearn
from sklearn.feature_selection
import SelectFromModel
np.random.seed(1)
让我们定义一种方法将数据集拆分为训练和测试数据; 我们将在训练部分训练我们的数据集,测试部分将用于评估训练模型:
#Function to create Train and Test set from the original dataset def getTrainTestData(dataset,split):
np.random.seed(0) training = [] testing = []
np.random.shuffle(dataset) shape = np.shape(dataset)
trainlength = np.uint16(np.floor(split*shape[0]))
for i in range(trainlength): training.append(dataset[i])
for i in range(trainlength,shape[0]): testing.append(dataset[i])
training = np.array(training) testing = np.array(testing)
return training,testing
我们还需要添加一个函数来评估模型的准确性; 它将预测和实际输出作为输入来计算百分比准确度:
#Function to evaluate model performance
def getAccuracy(pre,ytest): count = 0
for i in range(len(ytest)):
if ytest[i]==pre[i]: count+=1
acc = float(count)/len(ytest)
return acc
这是加载数据集的时间。我们将加载train.csv文件; 此文件包含超过61,000个训练实例。我们将在我们的示例中使用50000个实例,其中我们将使用35,000个实例来训练分类器,并使用15,000个实例来测试分类器的性能:
#Load dataset as pandas data frame
data = read_csv('train.csv')
#Extract attribute names from the data frame
feat = data.keys()
feat_labels = feat.get_values()
#Extract data values from the data frame
dataset = data.values
#Shuffle the dataset
np.random.shuffle(dataset)
#We will select 50000 instances to train the classifier
inst = 50000
#Extract 50000 instances from the dataset
dataset = dataset[0:inst,:]
#Create Training and Testing data for performance evaluation
train,test = getTrainTestData(dataset, 0.7)
#Split data into input and output variable with selected features
Xtrain = train[:,0:94] ytrain = train[:,94] shape = np.shape(Xtrain)
print("Shape of the dataset ",shape)
#Print the size of Data in MBs
print("Size of Data set before feature selection: %.2f MB"%(Xtrain.nbytes/1e6))
我们在这里注意数据大小; 因为我们的数据集包含大约35000个具有94个属性的训练实例; 我们的数据集的大小非常大。让我们来看看:
Shape of the dataset (35000, 94)
Size of Data set before feature selection: 26.32 MB
如您所见,我们的数据集中有35000行和94列,超过26 MB数据。
在下一个代码块中,我们将配置随机林分类器; 我们将使用250棵树,最大深度为30,随机要素的数量为7.其他超参数将是sklearn的默认值:
#Lets select the test data for model evaluation purpose
Xtest = test[:,0:94] ytest = test[:,94]
#Create a random forest classifier with the following Parameters
trees = 250
max_feat = 7
max_depth = 30
min_sample = 2
clf = RandomForestClassifier(n_estimators=trees,
max_features=max_feat,
max_depth=max_depth,
min_samples_split= min_sample, random_state=0,
n_jobs=-1)
#Train the classifier and calculate the training time
import time
start = time.time() clf.fit(Xtrain, ytrain) end = time.time()
#Lets Note down the model training time
print("Execution time for building the Tree is: %f"%(float(end)- float(start)))
pre = clf.predict(Xtest)
Let's see how much time is required to train the model on the training dataset:
Execution time for building the Tree is: 2.913641
#Evaluate the model performance for the test data
acc = getAccuracy(pre, ytest)
print("Accuracy of model before feature selection is %.2f"%(100*acc))
我们模型的准确性是:
特征选择前的模型精度为98.82
正如您所看到的,我们正在获得非常好的准确性,因为我们将近99%的测试数据分类到正确的类别中。这意味着我们正在对15,000个正确类中的14,823个实例进行分类。
那么,现在我的问题是:我们是否应该进一步改进?好吧,为什么不呢?如果可以的话,我们肯定会寻求更多的改进; 在这里,我们将使用功能重要性来选择功能。如您所知,在树木构建过程中,我们使用杂质测量来选择节点。选择具有最低杂质的属性值作为树中的节点。我们可以使用类似的标准进行特征选择。我们可以更加重视杂质较少的功能,这可以使用sklearn库的feature_importances_函数来完成。让我们找出每个功能的重要性:
#Once我们培养的模型中,我们的排名将所有功能的功能在拉链(feat_labels,clf.feature_importances_):
print(feature)
('id', 0.33346650420175183)
('feat_1', 0.0036186958628801214)
('feat_2', 0.0037243050888530957)
('feat_3', 0.011579217472062748)
('feat_4', 0.010297382675187445)
('feat_5', 0.0010359139416194116)
('feat_6', 0.00038171336038056165)
('feat_7', 0.0024867672489765021)
('feat_8', 0.0096689721610546085)
('feat_9', 0.007906150362995093)
('feat_10', 0.0022342480802130366)
正如您在此处所看到的,每个要素都基于其对最终预测的贡献而具有不同的重要性。
我们将使用这些重要性分数来排列我们的功能; 在下面的部分中,我们将选择功能重要性大于0.01的模型训练功能:
#Select features which have higher contribution in the final prediction
sfm = SelectFromModel(clf, threshold=0.01) sfm.fit(Xtrain,ytrain)
在这里,我们将根据所选的特征属性转换输入数据集。在下一个代码块中,我们将转换数据集。然后,我们将检查新数据集的大小和形状:
#Transform input dataset
Xtrain_1 = sfm.transform(Xtrain) Xtest_1 = sfm.transform(Xtest)
#Let's see the size and shape of new dataset print("Size of Data set before feature selection: %.2f MB"%(Xtrain_1.nbytes/1e6))
shape = np.shape(Xtrain_1)
print("Shape of the dataset ",shape)
Size of Data set before feature selection: 5.60 MB Shape of the dataset (35000, 20)
你看到数据集的形状了吗?在功能选择过程之后,我们只剩下20个功能,这将数据库的大小从26 MB减少到5.60 MB。这比原始数据集减少了约80%。
在下一个代码块中,我们将训练一个新的随机森林分类器,它具有与之前相同的超参数,并在测试数据集上进行测试。让我们看看修改训练集后得到的准确度:
#Model training time
start = time.time() clf.fit(Xtrain_1, ytrain) end = time.time()
print("Execution time for building the Tree is: %f"%(float(end)- float(start)))
#Let's evaluate the model on test data
pre = clf.predict(Xtest_1) count = 0
acc2 = getAccuracy(pre, ytest)
print("Accuracy after feature selection %.2f"%(100*acc2))
Execution time for building the Tree is: 1.711518 Accuracy after feature selection 99.97
你能看到!! 我们使用修改后的数据集获得了99.97%的准确率,这意味着我们在正确的类中对14,996个实例进行了分类,而之前我们只正确地对14,823个实例进行了分类。
这是我们在功能选择过程中取得的巨大进步; 我们可以总结下表中的所有结果:
评估标准 | 在选择特征之前 | 选择功能后 |
---|---|---|
功能数量 | 94 | 20 |
数据集的大小 | 26.32 MB | 5.60 MB |
训练时间 | 2.91秒 | 1.71秒 |
准确性 | 98.82% | 99.97% |
上表显示了特征选择的实际优点。您可以看到我们显着减少了要素数量,从而降低了数据集的模型复杂性和维度。尺寸减小后我们的训练时间缩短,最后,我们克服了过度拟合问题,获得了比以前更高的精度。
如果您发现这篇文章很有用,记得转发~