Datawhale&天池贷款违约预测——Task3 特征工程
1.特征工程目的
特征工程是数据分析中最耗时间和精力的一部分工作。数据和特征决定了机器学习的上限,而模型和算法则是逼近这个上限。因此,特征工程就变得尤为重要了。特征工程的主要工作就是对特征的处理,包括数据预处理,特征选择,甚至降维技术等跟特征有关的工作。
2. 主要内容
2.1 数据预处理
- 缺失值的填充(掌握数据类型,数据类型转换,填充方法等)
- 异常值的处理(3segama原则、箱型图、小提琴图等)
- 数据分箱(固定宽度分箱,分位数分箱,卡方分享等)
代码示例
#导入库
from tqdm import tqdm
from sklearn.preprocessing import LabelEncoder
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
from sklearn.preprocessing import MinMaxScaler
import xgboost as xgb
import lightgbm as lgb
from catboost import CatBoostRegressor
import warnings
warnings.filterwarnings('ignore')
from sklearn.model_selection import StratifiedKFold,KFold
from sklearn.metrics import accuracy_score,f1_score,roc_auc_score,log_loss
缺失值填充
- 指定值填充(-1,999,0等)
- 向上或向下填充
- 用众数填充或者中位数等统计量进行填充
# 缺失值填充——注意数据类型
train=pd.read_csv('train.csv')
testA=pd.read_csv('testA.csv')
train.isnull().sum()
#按照中位数填充数值型特征
train[numerical_fea]=train[numerical_fea].fillna(train[numerical_fea].median())
testA[numerical_fea]=testA[numerical_fea].fillna(train[numerical_fea].median())
train.isnull().sum()
#注意到employmentLength变量没有填充到,数据类型是object
train['employmentLength'].head()
#类型是object
#employmentLength是对象型特征,将它转换到数值特征
def employmentLength_to_int(s):
if pd.isnull(s):
return s ##若s是空返回空
else:
return np.int8(s.split()[0])##不是空 返回数组的第一个位置的值
for data in [train,testA]:
data['employmentLength'].replace(to_replace='10+ years',value='10 years',inplace=True)
data['employmentLength'].replace('< 1 year','0 years',inplace=True)
data['employmentLength']=data['employmentLength'].apply(employmentLength_to_int)
data['employmentLength']=data['employmentLength'].fillna(data['employmentLength'].mode())
data['employmentLength'].value_counts(dropna=False).sort_index()
缺失值填充总结——博客参考
链接: link.
2.2 类别特征编码
- 哑变量编码——pd.get_dummies()函数
- labelEncode——LabelEncoder()函数
- onehot编码——OneHotEncoder()函数
- 等等
代码示例
# 查看类别特征的类型数
cate_features=['grade','subGrade','employmentTitle','homeOwnership','verificationStatus','purpose', 'postCode','regionCode','applicationType','initialListStatus','title', 'policyCode']
for f in cate_features:
print(f,'类型数:',data[f].nunique())
#grade,subGrade是等级特征
for data in[train,testA]: data['grade']=data['grade'].map({'A':1,'B':2,'C':3,'D':4,'E':5,'F':6,'G':7})
#类型在2以上,又不是高维稀疏,且纯分类特征--用哑变量进行编码
for data in [train,testA]:
data=pd.get_dummies(data,columns=['subGrade','homeOwnership','verificationStatus', 'purpose','regionCode'],drop_first=True)
#对subGrade,postCode,title进行编码
#高维类别特征需要进行转换
for col in tqdm(['employmentTitle','postCode','title','subGrade']):
le=LabelEncoder() le.fit(list(train[col].astype(str).values)+list(testA[col].astype(str).values)) train[col]=le.transform(list(train[col].astype(str).values)) testA[col]=le.transform(list(testA[col].astype(str).values))
特征编码总结——博客参考
链接: link.
2.3 特征选择
- filter
- wrapper
- embedded
代码示例
FILTER
#filter基于特征间的关系进行筛选
#方差选择法——计算各个特征的方差,根据设定的阈值,选择方差大于阈值的特征
from sklearn.feature_selection import VarianceThreshold
VarianceThreshold(threshold=3).fit_transform(train,target_train)
#过滤出拥有数值关系的类别特征
def get_numerical_serial_fea(data,feas):
numerical_serial_fea=[]
numerical_noserial_fea=[]
for fea in feas:
temp=data[fea].nunique()
if temp<=10:
numerical_noserial_fea.append(fea)
continue
numerical_serial_fea.append(fea)
return numerical_serial_fea,numerical_noserial_fea
numerical_serial_fea,numerical_noserial_fea=get_numerical_serial_fea(train,numerical_fea)
#Pearson相关系数法
from sklearn.feature_selection import SelectKBest
from scipy.stats import pearsonr
#选择K个最好的特征,返回选择特征后的数据
#第一个参数为计算评估特征是否好的函数,该函数输入特征矩阵和目标向量,
#输出二元组(评分,P值)的数组,数组第i项为第i个特征的评分和P值。在此定义为计算相关系数
#参数k为选择的特征个数
SelectKBest(k=5).fit_transform(train,target_train)
#卡方检验法
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
#参数k为选择的特征个数
SelectKBest(chi2, k=5).fit_transform(train,target_train)
#互信息法
from sklearn.feature_selection import SelectKBest
from minepy import MINE
#由于MINE的设计不是函数式的,定义mic方法将其为函数式的,
#返回一个二元组,二元组的第2项设置成固定的P值0.5
def mic(x, y):
m = MINE()
m.compute_score(x, y)
return (m.mic(), 0.5)
#参数k为选择的特征个数
SelectKBest(lambda X, Y: array(map(lambda x:mic(x, Y), X.T)).T,
k=2).fit_transform(train,target_train)
WRAPPER
#递归特征消除法
from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression
#递归特征消除法,返回特征选择后的数据
#参数estimator为基模型
#参数n_features_to_select为选择的特征个数
RFE(estimator=LogisticRegression(),
n_features_to_select=2).fit_transform(train,target_train)
EMBEDDED
from sklearn.feature_selection import SelectFromModel
from sklearn.linear_model import LogisticRegression
#带L1惩罚项的逻辑回归作为基模型的特征选择
SelectFromModel(LogisticRegression(penalty="l1", C=0.1)).fit_transform(train,target_train)
特征编码总结——博客参考
链接: link.
版权声明:本文为loft_原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。