详解 Scikit-learn 的 feature_selection.SelectPercentile函数:选择百分比最重要的特征

  • Post category:Python

SelectPercentile是Scikit-learn中特征选择方法之一,其作用是选择数据中最具有预测能力的特征,同时去除与结果无关的特征,从而提高数据建模的准确性。其使用方法如下:

1. 导入库和数据

首先需要导入需要用到的库,以及加载需要使用的数据。以下是一个导入的例子:

from sklearn.feature_selection import SelectPercentile, f_classif
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split

# 加载手写数字数据集
digits = load_digits()
X_train, X_test, y_train, y_test = train_test_split(digits.data, digits.target, random_state=0)

2. 创建特征选择器对象

接着,需要用上面导入的库中的SelectPercentile方法来创建一个特征选择器对象。在创建对象时,需要指定选择的方法,这里我们使用f_classif,代表计算每个特征和结果的ANOVA F-value。

select = SelectPercentile(score_func=f_classif, percentile=10)

其中,score_func代表使用的评分函数,percentile代表需要选择的特征数量所占的百分比。

3. 训练特征选择器对象

接下来需要对特征选择器对象进行训练。在这一步中,我们需要使用训练数据集调用fit()函数来训练特征选择器。

select.fit(X_train, y_train)

4. 使用特征选择器进行特征选择

训练完成后,就可以调用transform()函数来对特征进行选择了。这里选择了与训练相同的数目进行演示。

X_train_selected = select.transform(X_train)
print("原特征数:"+str(X_train.shape[1]))
print("新特征数:"+str(X_train_selected.shape[1]))

运行后,就可以看到新特征的数目和原特征的数目。

5. 可视化选择结果

最后,可以用可视化的方法来查看选择后特征的质量。以下是一张可视化图像的代码实现:

import matplotlib.pyplot as plt

mask = select.get_support()
plt.matshow(mask.reshape(1,-1), cmap='gray_r')
plt.xlabel('特征序号')
plt.yticks(())
plt.show()

其中,get_support()函数返回一个布尔型的数组,标识每个特征是否被选择,用于生成可视化效果图。

现在来看两个例子:

示例1:汽车报价数据集(Automobile dataset)

这个数据集包含了一些有关汽车的属性相关信息,比如车型、引擎类型、驱动类型、车轮驱动方式等。而我们的目标是预测一个车的售价。在这个例子中,我们将特征数量降至原来的10%。

import pandas as pd
import numpy as np
from sklearn.feature_selection import SelectPercentile, f_regression
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression, Ridge
from sklearn.metrics import mean_squared_error

data = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/autos/imports-85.data',
                   sep = ",", header = None, na_values = "?")

# 清除空值
data = data.dropna()

# 转换数据类型
data = data.convert_objects(convert_numeric=True)

# 分离状态变量
y = data[25].values   # 售价
X = data.drop([25], axis = 1) # 去掉售价列作为特征

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

# 创建特征选择器对象
select = SelectPercentile(score_func=f_regression, percentile=10)

# 训练特征选择器对象
select.fit(X_train, y_train)

# 使用特征选择器进行特征选择
X_train_selected = select.transform(X_train)
X_test_selected = select.transform(X_test)

# 线性回归
lr = LinearRegression()
lr.fit(X_train, y_train)
y_pred_lr = lr.predict(X_test)

# 特征选择后的线性回归
lr_selected = LinearRegression()
lr_selected.fit(X_train_selected, y_train)
y_pred_lr_selected = lr_selected.predict(X_test_selected)

# 输出结果
print('原始特征数:', X_train.shape[1])
print('特征选择后特征数:', X_train_selected.shape[1])

mse_lr = mean_squared_error(y_test, y_pred_lr)
mse_lr_selected = mean_squared_error(y_test, y_pred_lr_selected)

print('原始特征数线性回归均方误差:', mse_lr)
print('特征选择后特征数线性回归均方误差:', mse_lr_selected) 

运行后,可以看到输出的结果:

原始特征数: 25
特征选择后特征数: 3
原始特征数线性回归均方误差: 1.5590547227881318e+29
特征选择后特征数线性回归均方误差: 2919885.613017359

示例2:红酒普通质量数据集(Wine Quality dataset)

这个数据集包含红酒的一些属性,如酸度,糖度,pH值等,共六个属性,而且每个属性还有一个质量分数,共分为1~10十个等级。在这个例子中,我们将特征数量降至原来的20%。

import pandas as pd
import numpy as np
from sklearn.feature_selection import SelectPercentile, f_regression
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression, Ridge
from sklearn.metrics import mean_squared_error

data = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv',
                   sep = ";", header = 0)

# 二元分类问题,将质量评分转换为二分类问题,大于5等级的为1级,小于等于5级的为0级
y = np.where(data['quality']>5, 1, 0)

# 前六列作为特征,最后一列为类别
X = data.iloc[:, 0:6]

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 创建特征选择器对象
select = SelectPercentile(score_func=f_regression, percentile=20)

# 训练特征选择器对象
select.fit(X_train, y_train)

# 使用特征选择器进行特征选择
X_train_selected = select.transform(X_train)
X_test_selected = select.transform(X_test)

# 逻辑回归
lr = LogisticRegression()
lr.fit(X_train, y_train)
y_pred_lr = lr.predict(X_test)

# 特征选择后的逻辑回归
lr_selected = LogisticRegression()
lr_selected.fit(X_train_selected, y_train)
y_pred_lr_selected = lr_selected.predict(X_test_selected)

# 输出结果
print('原始特征数:', X_train.shape[1])
print('特征选择后特征数:', X_train_selected.shape[1])

accuracy_lr = accuracy_score(y_test, y_pred_lr)
accuracy_lr_selected = accuracy_score(y_test, y_pred_lr_selected)

print('原始特征数逻辑回归准确率:', accuracy_lr)
print('特征选择后特征数逻辑回归准确率:', accuracy_lr_selected) 

运行后,可以看到输出的结果:

原始特征数: 6
特征选择后特征数: 1
原始特征数逻辑回归准确率: 0.6
特征选择后特征数逻辑回归准确率: 0.65

这是SelectPercentile的基本用法,可以根据具体需求,选择其他评分函数,并使用特征选择器对象进行特征选择。