在数据建模中,我们都希望模型能够快速迭代优化并且有较高的准确率。要做到这一点,我们就用使用特征选择技术来消除不必要的变量。
特征选择的作用:
- 更快地训练机器学习模型
- 降低模型的复杂性
- 减少过度拟合,使其更易于解释
特征选择上,除了基于业务经验判别外,如果你对所做业务场景不是特别熟悉的话,利用技术手段就是必选项了。今天我将根据自己的工作经验来分享3种方法:
- 筛选方法
- 包装方法
- 嵌入式方法
筛选方法
在筛选方法上,我分享常用的4种方法:
- 丢弃常量值
- 单变量选择
- 特征重要性
- 热图关联矩阵
丢弃常量值
在此筛选器中,我们可以删除具有常量值的要素,这些要素实际上对解决问题语句并不重要。
在 Python 中,可以使用 sklearn 的 VarianceThreshold
from sklearn.feature_selection import VarianceThreshold
var_thres=VarianceThreshold(threshold=0)
var_thres.fit(data)
data.columns[var_thres.get_support()]
constant_columns = [column for column in data.columns
if column not in data.columns[var_thres.get_support()]]
data.drop(constant_columns,axis=1)
单变量选择
我们可以利用统计方法来筛选特征,比如皮尔逊系数、ANOVA、Chi-Squared等。下面以Chi-Squared示例进行讲解。
要使用 Chi-Squared,我们需要了解以下二点:
- 自由度是逻辑上独立值的最大数量。简单地说,它可以定义为观测值总数减去对观测值的约束数。
- Chi-Square 值越高,结果值更依赖于响应变量,我们可以选择这样的变量进行模型训练
在 Python 中,可以使用 sklearn 中的 SelectKBest 和 chi2 库进行特征选择,代码如下所示:
import pandas as pd
import numpy as np
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
data = pd.read_csv("train.csv")
X = data.iloc[:,0:20] #independent columns
y = data.iloc[:,-1] #target column i.e price range
#apply SelectKBest class to extract top 10 best features
bestfeatures = SelectKBest(score_func=chi2, k=10)
fit = bestfeatures.fit(X,y)
dfscores = pd.DataFrame(fit.scores_)
dfcolumns = pd.DataFrame(X.columns)
#concat two dataframes for better visualization
featureScores = pd.concat([dfcolumns,dfscores],axis=1) featureScores.columns = ['Specs','Score'] #naming the dataframe columns
featureScores
print(featureScores.nlargest(10,'Score')) #print 10 best features
特征重要性
特征重要性是给数据中每个特征打一个分数,分数越高说明特征越重要。通过使用模型的要素重要性属性,可以获取数据集每个要素的要素重要性。
在 python 中,可以通过以下代码完成:
from sklearn.ensemble import ExtraTreesClassifier
import matplotlib.pyplot as plt
model = ExtraTreesClassifier()
model.fit(X,y)
print(model.feature_importances_) #use inbuilt class feature_importances of tree based classifiers
#plot graph of feature importances for better visualization feat_importances = pd.Series(model.feature_importances_, index=X.columns)
feat_importances.nlargest(10).plot(kind='barh') plt.show()
热图关联矩阵
相关性表示变量与目标变量之间的关系。热图便于识别哪些要素与目标变量最相关.
在 Python 中,可以使用如下代码完成
import seaborn as sns
#get correlations of each features in dataset
corrmat = data.corr()
top_corr_features = corrmat.index
plt.figure(figsize=(20,20))
#plot heat map
g=sns.heatmap(data[top_corr_features].corr(),annot=True , cmap=plt.cm.CMRmap_r)
plt.show()
颜色越深表示相关性越高。
包装方法
包装方法常见的有三种:
- 向前选择
- 向后选择
- 递归特征消除
向前选择
向前选择是一种优化特征选择的迭代方法,我们从模型中没有特征开始。在每次迭代中,我们不断添加最佳改进模型的功能,直到添加新变量不会提高模型的性能。
在 python 中,它可以实现为:
1. # step forward feature selection
2.
3. from sklearn.model_selection import train_test_split
4. from sklearn.ensemble import RandomForestRegressor
5. from sklearn.metrics import r2_score
6. from mlxtend.feature_selection import SequentialFeatureSelector as SFS
7. # select numerical columns:
8.
9. numerics = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64']
10. numerical_vars = list(data.select_dtypes(include=numerics).columns)
11. data = data[numerical_vars]
12. # separate train and test sets
13. X_train, X_test, y_train, y_test = train_test_split(
14. X,Y, test_size=0.3, random_state=0)
15. # find and remove correlated features
16. def correlation(dataset, threshold):
17. col_corr = set() # Set of all the names of correlated columns
18. corr_matrix = dataset.corr()
19. for i in range(len(corr_matrix.columns)):
20. for j in range(i):
21. if abs(corr_matrix.iloc[i, j]) > threshold: # we are interested in absolute coeff value
22. colname = corr_matrix.columns[i] # getting the name of column
23. col_corr.add(colname)
24. return col_corr
25.
26. corr_features = correlation(X_train, 0.8)
27. print('correlated features: ', len(set(corr_features)) )
28. # removed correlated features
29. X_train.drop(labels=corr_features, axis=1, inplace=True)
30. X_test.drop(labels=corr_features, axis=1, inplace=True)
31. X_train.fillna(0, inplace=True)
32.
33.
34. # step forward feature selection
35.
36. from mlxtend.feature_selection import SequentialFeatureSelector as SFS
37.
38. sfs1 = SFS(RandomForestRegressor(),
39. k_features=10,
40. forward=True,
41. floating=False,
42. verbose=2,
43. scoring='r2',
44. cv=3)
45.
46. sfs1 = sfs1.fit(np.array(X_train), y_train)
47. X_train.columns[list(sfs1.k_feature_idx_)]
48. sfs1.k_feature_idx_
向后消除
在向后消除中,我们从所有功能开始,并在每次迭代中删除最微不足道的功能,从而提高模型的性能。我们重复此规定,直到在删除功能时未观察到任何改进。
在 python 中,它可以实现为:
49. # step backward feature elimination
50.
51. sfs1 = SFS(RandomForestRegressor(),
52. k_features=10,
53. forward=False,
54. floating=False,
55. verbose=2,
56. scoring='r2',
57. cv=3)
58.
59. sfs1 = sfs1.fit(np.array(X_train), y_train)
60. X_train.columns[list(sfs1.k_feature_idx_)]
61. sfs1.k_feature_idx_
递归特征消除
最贪婪的优化算法,旨在找到性能最好的特征子集。反复创建模型,并在每次迭代中保留最佳或性能最差的特征。
在 python 中,它可以实现为:
from sklearn.svm import SVC
from sklearn.datasets import load_digits
from sklearn.feature_selection import RFE
import matplotlib.pyplot as plt
# Load the digits dataset
digits = load_digits()
X = digits.images.reshape((len(digits.images), -1))
y = digits.target
# Create the RFE object and rank each pixel
svc = SVC(kernel="linear", C=1)
rfe = RFE(estimator=svc, n_features_to_select=1, step=1)
rfe.fit(X, y)
嵌入式方法
LASSO 回归
LASSO 回归 执行 L1 正则化。我们知道正则化是指对机器学习模型的不同参数增加惩罚或惩罚,以减少模型的自由度,从而避免过度拟合。
在 python 中,特征选择可以这样做
#load libraries
from sklearn.model_selection import train_test_split
from sklearn.linear_model import Lasso
from sklearn.feature_selection import SelectFromModel
from sklearn.preprocessing import StandardScaler
# different scales, so it helps the regression to scale them
# separate train and test sets
X_train, X_test, y_train, y_test = train_test_split(
X,Y, test_size=0.3,
random_state=0)
scaler = StandardScaler()
scaler.fit(X_train.fillna(0))
# to force the algorithm to shrink some coefficients
sel_ = SelectFromModel(Lasso(alpha=100))
sel_.fit(scaler.transform(X_train.fillna(0)), y_train)
# make a list with the selected features and print the outputs
selected_feat = X_train.columns[(sel_.get_support())]
显然,LASSO 正则化有助于从数据集中删除非重要要素。
需要主意的是:增加处罚将导致删除的功能数量增加。惩罚越高重要特征被移除的概率越高,可能导致模型性能下降。
Random Forest /Ensemble 技术
随机林是最流行的机器学习算法之一。由于它提供非常好的预测性能、低超拟性和易于解释性,因此它被认为是非常成功的。
在分类中,我们通过 Gini 或信息增益/熵来测量纯度。当我们训练树时,可以计算每个要素减少纯度的量。
在 python 中,实现方法如下:
from sklearn import preprocessing
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn import tree
from sklearn.ensemble import RandomForestClassifier
# Encode categorical variables
X = pd.get_dummies(X, prefix_sep='_')
y = LabelEncoder().fit_transform(y)
# Normalize feature vector
X2 = StandardScaler().fit_transform(X)
# Split the dataset
X_train, X_test, y_train, y_test = train_test_split(X2, y, test_size = 0.30, random_state = 0)
# instantiate the classifier with n_estimators = 100
clf = RandomForestClassifier(n_estimators=100, random_state=0)
# fit the classifier to the training set
clf.fit(X_train, y_train)
# predict on the test set
y_pred = clf.predict(X_test)
推荐一本由美国科学作家 Michael Nielsen编写的非常好的深度学习入门书籍-《Neural Network and Deep Learning》,中文译为《神经网络与深度学习》。
个人认为是目前最好的神经网络与机器学习入门资料。内容非常浅显易懂,很多数学密集的区域作者都有提示。全书贯穿的是 MNIST 手写数字的识别问题,每个模型和改进都有详细注释的代码。非常适合用来入门神经网络和深度学习!
领取方式:
长按扫码,发消息 [神经网络]