《特征工程入门与实践》 笔记
目录
特征构建
1.检查数据集
查看数据集各列的类型和等级,等级分类参见
特征工程系列(二)特征理解
2.填充分类特征
2.1 处理分类数据
调用 isnull().sum()查看缺失值
sklearn的Imputer类确实有most_frequent方法用众数来
处理分类数据。不采用这种方法,构建自定义转换器。
例如:
data['a'],fillna(data['a'].value_counts().index[0])
下面我们继续自定义填充器:
from sklearn.base import TransformerMixin
class CustomCategoryImputer(TransformerMixin): #继承TransformerMixin类
def __init__(self, cols=None):
self.cols = cols
def transform(self, df):
X = df.copy()
for col in self.cols:
X[col].fillna(X[col], value_counts().index[0], inplace=True)
return X
def fit(self,*_): # *_表示任意列表
return self
cci=CustomCategoryImputer(cols=['a','b'])
cci.fit_transform(X)
2.2 处理定量数据
from sklearn.impute import SimpleImputer
class CustomQuantitativeImputer(TransformerMixin):
def __init__(self, cols=None, strategy='mean'):
self.cols = cols
self.strategy = strategy
def transform(self, df):
X = df.copy()
impute = SimpleImputer(strategy=self.strategy)
for col in self.cols:
X[col] = impute.fit_transform(X[[col]])
return X
def fit(self, *_):
return self
cqi=CustomQuantitativeImputer(cols=['c'],strategy='mean')
cqi.fit_transform(X)
2.3 放入流水线同时填充
from sklearn.pipeline import Pipeline
imputer = Pipeline([('a', cqi), ('c', cci)])
imputer.fit_transform(X)
3.编码分类变量
3.1 定类等级的编码
主要方法是将分类数据转换为虚拟变量,有两种选择:
- 用pandas 自动找到分类变量并进行编码
- 创建自定义模拟虚拟变量编码器,在流水线上工作
虚拟变量是什么?
虚拟变量的取值是0或1.虚拟变量是定性数据的数值化
虚拟变量陷阱:Dummy Variable Trap
有m个类别是只需要m-1个虚拟变量,否则会出现共线性,使模型参数出现错误。
例如编码 男为[1,0] 女为[0,1] 都存在x+y=1 所以只需要 男[1]女[0] 注意不要 直接认为是 男=1 女=0 我们只是忽略其中一个虚拟变量,这个变量可以直接被推断出来而已。
- 用pandas 自动找到分类变量并进行编码
pandas中有一个get_dummies方法,可以找到所有的分类变量,并将其转换为虚拟变量。
pd.get_dummies(X, columns=['a', 'b'],#要虚拟化的类
prefix_sep='_'))#列名的分隔符a_column
- 自定义虚拟化器在流水线上一次性转换
class CustomDummifier(TransformerMixin):
def __init__(self, cols=None):
self.cols = cols
def transform(self, X):
return pd.get_dummies(X, columns=self.cols)
def fit(self, *_):
return self
cd = CustomDummifier(cols=['a', 'b'])
cd.fit_transform(X)
3.2定序等级的编码
为了在编码中保持顺序,我们使用标签编码器。
# 创建一个列表,定序数据的顺序对应列表索引。
order = ['very big', 'big', 'medium', 'small', 'very small']
# 映射
X['c'].map(lambda x: order.index(x))
自定义流水线
class CustomCutter(TransformerMixin):
def __init__(self, col, bins, labels=True):
# self.labels = labels
self.bins = bins
self.col = col
def transform(self, df):
X = df.copy()
X[self.col] = pd.cut(X[self.col], bins=self.bins)
X
return X
def fit(self, *_):
return self
3.3 连续特征分箱
pandas有一个cut方法,可以用来分箱(binning),或叫分桶(bucketing)
cut方法会把列中的最大值和最小值之间分成bins个箱子,每个箱子等长度,cut函数会输出每一行数据所对应的箱。
pd.cut(X['d'], bins=3, labels=True)
0 (-0.52, 6.333]
1 (6.333, 13.167]
2 (-0.52, 6.333]
3 (6.333, 13.167]
4 NaN
5 (13.167, 20.0]
Name: d, dtype: category
Categories (3, interval[float64]): [(-0.52, 6.333] < (6.333, 13.167] < (13.167, 20.0]]
运用如果labesl=False,会显示整数指示器
0 0.0
1 1.0
2 0.0
3 1.0
4 NaN
5 2.0
Name: d, dtype: float64
下面是流水线代码
class CustomCutter(TransformerMixin):
def __init__(self, col, bins, labels=True):
# self.labels = labels
self.bins = bins
self.col = col
def transform(self, df):
X = df.copy()
X[self.col] = pd.cut(X[self.col], bins=self.bins)
X
return X
def fit(self, *_):
return self
3.4 组装流水线
pipe = Pipeline([('imputer', imputer), ('dummify', cd), ('encode', ce),
('cut', cc)]) # 元组内第一个是命名的名称,第二个是函数
pipe.fit_transform(X)
4.扩展数值特征
多项式特征
在创建更多特征时,一个很好的方法就是使用sklearn的PolynomialFeatures类,这个类会生成新的特征矩阵,里面是原始数据的多项式组合。
df = pd.read_csv('./Desktop/dataset/1.csv')
df.columns = ['index', 'x', 'y', 'z', 'activity']
df['activity'].value_counts(normalize=True)
X=df[['x','y','z']]
y=df['activity']
X
from sklearn.preprocessing import PolynomialFeatures
poly=PolynomialFeatures(degree=2,include_bias=False,interaction_only=True)
X_poly=poly.fit_transform(X)
X_poly.shape
pd.DataFrame(X_poly,columns=poly.get_feature_names())