Python数据挖掘与机器学习_通信信用风险评估实战(3)——特征工程

系列目录:

Python数据挖掘与机器学习_通信信用风险评估实战(1)——读数据

Python数据挖掘与机器学习_通信信用风险评估实战(2)——数据预处理

有这么一句话在业界广为流传:数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已。

数据说明

数据使用经数据预处理,合并后的宽表train_user_comm_basic

宽表(train_user_comm_basic)的单特征分析与处理

遍历DataFrame的特征

    for col in df.columns:
        logger.info('%s,%s,%s,%s' % (
            col, df[col].dtype, df[col].unique(), df[col].size))
        logger.info('%s' % (df[col].value_counts()))
        logger.info('%s' % (df[col].describe()))
        logger.info('%s' % ('----------------------------------------'))

根据单特征的分析,进行特征处理。

缺失值处理,依据对通信的业务和数据理解,填充缺失值。AGE列缺失数据6个,用中位数填充。ARPUSP_FEE列缺失数据14个,用0填充。NUM_OF_COMM缺失数据88个,用0填充。

train_user_comm_basic['AGE'] = train_user_comm_basic['AGE'].fillna(train_user_comm_basic['AGE'].median())
train_user_comm_basic = train_user_comm_basic.fillna({'ARPU': 0, 'SP_FEE': 0})
train_user_comm_basic = train_user_comm_basic.fillna({'NUM_OF_COMM': 0})

移除低方差的特征(Removing features with low variance),VarianceThreshold会移除所有方差不满足阈值的特征,默认设置下,它会移除所有方差为0的特征,即那些在所有样本中数值完全相同的特征。 OCCUPATION_IDCITY_IDdate列在所有样本中数值完全相同,可移除,其中CITY_ID由于初赛是抽样数据,在决赛中可能不完全相同,可保留并进行重编码。

类别变量重编码COUNTY_IDTELE_FACSMART_SYSTEM为分类变量,依据所用算法采取两种重编码方案,一是用cat.codes(Label Encoding)重新编码为数字集合,二是如果类别变量列有k个不同取值,用get_dummies(One Hot Encoding)派生出一个k列DataFrame(其值全为1和0)。因TELE_FACSMART_SYSTEM的种类很多,编码后的维度会极大增加,为避免维度灾难,保留TOP10分类取值,其余取值置为其他。

COUNTY_ID_ONE_HOT = pd.get_dummies(train_user_comm_basic['COUNTY_ID'], prefix='COUNTY_ID', drop_first=True)
train_user_comm_basic = pd.concat((train_user_comm_basic, COUNTY_ID_ONE_HOT), axis=1)

data_temp = train_user_comm_basic.groupby('TELE_FAC').size().sort_values()[:-20].index
train_user_comm_basic['TELE_FAC'] = train_user_comm_basic['TELE_FAC'].replace(list(data_temp), '其他')
TELE_FAC_ONE_HOT = pd.get_dummies(train_user_comm_basic['TELE_FAC'], prefix='TELE_FAC', drop_first=True)
train_user_comm_basic = pd.concat([train_user_comm_basic, TELE_FAC_ONE_HOT], axis=1)

train_user_comm_basic['SMART_SYSTEM'] = train_user_comm_basic['SMART_SYSTEM'].fillna('others')
data_temp = train_user_comm_basic.groupby('SMART_SYSTEM').size().sort_values()[:-10].index
train_user_comm_basic['SMART_SYSTEM'] = train_user_comm_basic['SMART_SYSTEM'].replace(list(data_temp), 'others')
SMART_SYSTEM_ONE_HOT = pd.get_dummies(train_user_comm_basic['SMART_SYSTEM'], prefix='SMART_SYSTEM', drop_first=True)
train_user_comm_basic = pd.concat([train_user_comm_basic, SMART_SYSTEM_ONE_HOT], axis=1)

衍生变量FIST_USE_DATE截断到月份取值太多,衍生变量FIST_USE_YEAR,截断到年份。

train_user_comm_basic['FIST_USE_YEAR'] = train_user_comm_basic['FIST_USE_DATE'].str[:4]
data_temp = train_user_comm_basic.groupby('FIST_USE_YEAR').size().sort_values().index[-1]
train_user_comm_basic['FIST_USE_YEAR'][train_user_comm_basic['FIST_USE_YEAR']=='\\N'] = train_user_comm_basic['FIST_USE_YEAR'][train_user_comm_basic['FIST_USE_YEAR']=='\\N'].replace('\\N', data_temp)
train_user_comm_basic['FIST_USE_YEAR'] = train_user_comm_basic['FIST_USE_YEAR'].astype('int64')

宽表(train_user_comm_basic)单特征与分类变量的交叉表分析

交叉表分析,对数据处理前和处理后的每个特征与分类变量计算分组频率,验证数据处理过程是否正确,以及观察单特征与分类变量的关系。

# 特征与目标变量的交叉表输出
def df_crosstab(df):
    logger = create_logger(df_crosstab)
    for col in df.columns:
        print col
        if col == 'RISK_Flag':
            continue
        print pd.crosstab(df[col], df['RISK_Flag'], margins=True)
        logger.info('%s' % (pd.crosstab(df[col],
                                        df['RISK_Flag'],
                                        margins=True)))
        logger.info('%s' % ('----------------------------------------'))

基于树的属性子集进行特征选择

经特征处理后,训练数据的维数为(7000, 80)。高维度数据集容易过拟合。

特征选择:基于树的属性子集选择,把数据输入RandomForestClassifier训练,然后用SelectFromModel提取训练的模型,最后使用transform方法筛选出重要的特征。

训练集和交叉验证集的变量都需要筛选,且筛选原则是一致的,所以把筛选出来的特征的索引或列保存在fea_indexfea_col中。

# -------------feature selection------------------
from sklearn.ensemble import RandomForestClassifier
from sklearn.feature_selection import SelectFromModel
rf = RandomForestClassifier()
feature_set = rf.fit(x, y)

model = SelectFromModel(rf, prefit=True)
feature_set = model.transform(x)

fea_col = []
for A_col in x.columns:
    for B_col in np.arange(feature_set.shape[1]):
        if (x.loc[:, A_col] == feature_set[:, B_col]).all():
            fea_col.append(A_col)

fea_index = []
for A_col in np.arange(x.shape[1]):
    for B_col in np.arange(feature_set.shape[1]):
        if (x.iloc[:, A_col] == feature_set[:, B_col]).all():
            fea_index.append(A_col)
fea_impor = sorted(zip(map(lambda x: round(x, 4), rf.feature_importances_), x.columns), reverse=True)

附1:bug参考资料

索引、选取

e:\work\ml_py27\lib\site-packages\ipykernel_launcher.py:1: DeprecationWarning: 
.ix is deprecated. Please use
.loc for label based indexing or
.iloc for positional indexing

See the documentation here:
http://pandas.pydata.org/pandas-docs/stable/indexing.html#ix-indexer-is-deprecated
  """Entry point for launching an IPython kernel.

Guide to Encoding Categorical Values in Python

http://pbpython.com/categorical-encoding.html


微信公众号「数据分析」,分享数据科学家的自我修养,既然遇见,不如一起成长。
Python数据挖掘与机器学习_通信信用风险评估实战(3)——特征工程_第1张图片

你可能感兴趣的:(Python机器学习,Python)