支持向量机(SVM)是一种强大的机器学习算法,用于分类和回归分析。它是基于找到两个类之间的最佳边界,最大限度地提高它们之间的差距的想法。然而,SVM的挑战在于它需要大量的计算能力,并且对特征的选择很敏感。这可能会使模型更加复杂,更难解释。
单变量特征选择是一种用于选择数据集中最重要特征的方法。这种方法背后的思想是评估每个特征与目标变量的关系,并选择具有最强相关性的特征。对每个特征重复此过程,并根据定义的标准(如最高相关性或统计显著性)选择最佳特征。
在单变量特征选择中,重点是单个特征及其对目标变量的贡献,而不是考虑特征之间的关系。这种方法简单而直接,但它没有考虑到功能之间的任何交互或依赖关系。
单变量特征选择在处理大量特征时非常有用,其目标是降低数据的维度并简化建模过程。在目标变量和单个特征之间的关系不复杂并且可以通过简单的统计分析来理解的情况下,它对于特征选择也很有用。
语法: sklearn.feature_selection.SelectKBest(score_func=< function f_classif>, *, k=10)
根据k个最高分数选择特征。
参数:
score_fun:在score_fun中我们可以使用f_classif,f_regression,chi2,mutual_info_classif,GenericUnivariateSelect等,默认值为f_classif用于分类数据,它接受两个数组X和y,并返回一对数组(scores,pvalues)或一个带有scores的数组。
k:我们可以分配整数值表示我们想要的特征的数量或“all””,默认值为10
ANOVA代表方差分析,是一种用于确定因变量(标签)与一个或多个自变量(要素)之间关系的统计技术。它测量不同数据组之间的变异性,并有助于确定哪个自变量对因变量有显著影响。
在机器学习中,ANOVA用作特征和标签之间的单变量特征选择方法。这意味着它有助于识别数据集中对目标变量影响最大的最重要特征。
单变量统计检验是一类用于分析单个变量分布的统计检验。这些测试的目的是确定变量是否存在显著变化,并确定数据中的任何模式或关系。一些常见的单变量统计检验包括:
F分数,也称为F统计量,是ANOVA中使用的两个方差的比率。其计算为组间方差与组内方差的比值。F分数用于检验各组均值相等的假设。
方法:
F分数可以计算如下:
F =(MSB / MSW)
其中:
MSB =组间均方(组间方差)
MSW =组内均方(组内方差)
F分数用于检验零假设,即各组的均值相等。如果计算的F分数大于F分布的临界值,则拒绝零假设,并得出结论,各组平均值之间存在显著差异。
下面是一个在Scikit Learn中进行ANOVA的例子,我们将其用作score_fun:
f_classif:在第一个示例中,SelectKBest(f_classif,k=2),使用的评分函数是f_classif,用于分类问题。f_classif评分函数计算每个特征和目标变量之间的ANOVA(方差分析)F值,并选择具有最高F值的特征作为前k个特征。在处理分类问题时,这是一种有用的技术,因为它有助于识别最重要的特征以进行准确的预测。
f_regression:在第二个示例,SelectKBest(f_regression,k=5)中,使用的评分函数是f_regression,它用于回归问题。f_regression scoring函数计算每个特征与目标变量之间的F值,并选择具有最高F值的特征作为前k个特征。在处理回归问题时,这是一种有用的技术,因为它有助于识别做出准确预测的最重要特征。
chi2:该检验用于确定两个分类变量之间是否存在显著关联。该测试计算预期发生频率与观察到的发生频率之间的差异。
示例1
在本文中,我们将使用scikit-learn库中的iris数据集,并在训练SVM之前对数据应用单变量特征选择。iris数据集包含150个样本,具有四个特征:萼片长度,萼片宽度,花瓣长度和花瓣宽度。目标是使用支持向量机的iris花分为三个不同的种类,根据他们的特征。
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
iris = load_iris(as_frame=True)
df = iris.frame
X = df.drop(['target'], axis = 1)
y = df['target']
X_train, X_test, y_train, y_test = train_test_split(X,
y,
test_size=0.2,
random_state=42)
单变量特征选择
我们将使用sklearn.feature_selection模块中的SelectKBest类来执行单变量特征选择。
在这种情况下,SelectKBest(f_classif,k=2),使用的评分函数是f_classif,用于分类问题。f_classif评分函数计算每个特征和目标变量之间的ANOVA(方差分析)F值,并选择具有最高F值的特征作为前k个特征。在处理分类问题时,这是一种有用的技术,因为它有助于识别最重要的特征以进行准确的预测。
我们将k参数设置为2,这意味着我们将保留数据集中的两个最佳特征。
from sklearn.feature_selection import SelectKBest, f_classif
selector = SelectKBest(f_classif, k=2)
selector.fit(X_train, y_train)
print('Number of input features:', selector.n_features_in_)
print('Input features Names :', selector.feature_names_in_)
print('Input features scores :', selector.scores_)
print('Input features pvalues:', selector.pvalues_)
print('Output features Names :', selector.get_feature_names_out())
输出
Number of input features: 4
Input features Names : ['sepal length (cm)' 'sepal width (cm)' 'petal length (cm)'
'petal width (cm)']
Input features scores : [ 84.80836804 41.29284269 925.55642345 680.77560309]
Input features pvalues: [1.72477507e-23 2.69962606e-14 1.93619072e-72 3.57639330e-65]
Output features Names : ['petal length (cm)' 'petal width (cm)']
现在,我们将使用selector.transform来选择花瓣长度和花瓣宽度,以训练和测试特征。
X_train_selected = selector.transform(X_train)
X_test_selected = selector.transform(X_test)
应用SVM分类器来训练模型
现在我们已经选择了最好的两个特征,我们将使用这些特征训练SVM分类器:
from sklearn.svm import SVC
clf = SVC(kernel='linear', C=1, random_state=42)
clf.fit(X_train_selected, y_train)
评估SVM分类器的性能
最后,我们将通过计算SVM分类器在测试集上的准确度来评估SVM分类器的性能:
from sklearn.metrics import accuracy_score
y_pred = clf.predict(X_test_selected)
accuracy = accuracy_score(y_test, y_pred)
print("Accuracy:", accuracy)
输出
Accuracy: 1.0
这意味着SVM分类器仅使用两个特征就能够对100%的测试样本进行正确分类。通过减少模型中的特征数量,我们使其更简单,更易于解释,同时仍然实现了良好的性能。
完整代码:
# Import the necesssary libraries
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
from sklearn.feature_selection import SelectKBest, f_classif
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score
# Load the datasets
iris = load_iris(as_frame=True)
df = iris.frame
X = df.drop(['target'], axis = 1)
y = df['target']
# Split train and test datasets
X_train, X_test, y_train, y_test = train_test_split(X,
y,
test_size=0.2,
random_state=42)
# Select the best features
selector = SelectKBest(f_classif, k=2)
selector.fit(X_train, y_train)
print('Number of input features:', selector.n_features_in_)
print('Input features Names :', selector.feature_names_in_)
print('Input features scores :', selector.scores_)
print('Input features pvalues:', selector.pvalues_)
print('Output features Names :', selector.get_feature_names_out())
X_train_selected = selector.transform(X_train)
X_test_selected = selector.transform(X_test)
# Train the classifier
clf = SVC(kernel='linear', C=1, random_state=42)
clf.fit(X_train_selected, y_train)
# Prediction
y_pred = clf.predict(X_test_selected)
# Evaluation
accuracy = accuracy_score(y_test, y_pred)
print("\n Accuracy:", accuracy)
输出
Number of input features: 4
Input features Names : ['sepal length (cm)' 'sepal width (cm)' 'petal length (cm)'
'petal width (cm)']
Input features scores : [ 84.80836804 41.29284269 925.55642345 680.77560309]
Input features pvalues: [1.72477507e-23 2.69962606e-14 1.93619072e-72 3.57639330e-65]
Output features Names : ['petal length (cm)' 'petal width (cm)']
Accuracy: 1.0
示例2
在这个例子中,我们使用了sklearn.feature_selection模块中的SelectKBest类。f_regression函数用作评分函数,它是特征和目标之间的ANOVA F值。fit方法用于使选择器适合数据,scores_ attribute用于获取每个特征的分数。最后,我们对分数进行排序,并获得对目标变量影响最大的前5个特征的名称。
在第一个示例中,SelectKBest(f_regression,k=5),使用的评分函数是f_regression,用于回归问题。f_regression scoring函数计算每个特征与目标变量之间的F值,并选择具有最高F值的特征作为前k个特征。在处理回归问题时,这是一种有用的技术,因为它有助于识别做出准确预测的最重要特征。
k的值决定了将被选择的特征的数量。在第一个示例中,k=5,因此将基于其F值选择前5个特征。在第二个示例中,k=2,因此将基于其F值选择前2个特征。
from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split
from sklearn.svm import SVR
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import f_regression
from sklearn.metrics import mean_squared_error
# Load the diabetes dataset
data = load_diabetes(as_frame=True)
df = data.frame
X = df.drop(['target'], axis = 1)
y = df['target']
# Split train and test datasets
X_train, X_test, y_train, y_test = train_test_split(X,
y,
test_size=0.2,
random_state=42)
# Create the feature selector
selector = SelectKBest(f_regression, k=3)
# Fit the selector to the data
selector.fit(X_train, y_train)
print('Number of input features:', selector.n_features_in_)
print('Input features Names :', selector.feature_names_in_)
# Get the scores for each feature
print('Input features scores :', selector.scores_)
# Get the pvalues for each feature
print('Input features pvalues:', selector.pvalues_)
# Print the names of the best features
print('Output features Names :', selector.get_feature_names_out())
X_train_selected = selector.transform(X_train)
X_test_selected = selector.transform(X_test)
# Train the classifier
reg = SVR(kernel='rbf')
reg.fit(X_train_selected, y_train)
# Prediction
y_pred = reg.predict(X_test_selected)
mse = mean_squared_error(y_test, y_pred)
print("\Mean Squared Error :", mse)
输出
Number of input features: 10
Input features Names : ['age' 'sex' 'bmi' 'bp' 's1' 's2' 's3' 's4' 's5' 's6']
Input features scores : [1.40986700e+01 1.77755064e-02 2.02386965e+02 8.65580384e+01
1.45561098e+01 8.63143031e+00 6.07087750e+01 7.74171182e+01 1.53967806e+02 6.31023038e+01]
Input features pvalues: [2.02982942e-04 8.94012908e-01 1.39673719e-36 1.49839640e-18
1.60730187e-04 3.52250747e-03 7.56195523e-14 6.36582277e-17 1.45463546e-29 2.69104622e-14]
Output features Names : ['bmi' 'bp' 's5']
\Mean Squared Error : 3668.63356096246
总之,单变量特征选择是一个有用的技术,以减少SVM模型的复杂性。