数据挖掘第七次周报

理论学习

赛题背景

回顾总结整个比赛的知识,首先是赛题用了AUC作为评价指标,这是一个医学上的指标,通过衡量ROC曲线与坐标轴围成的面积评价模型预测结果,它从对阳性和阴性的预测两方面进行了考虑,在许多情况下更为合理,因为阳性没检测出的后果可能更严重。

特征工程

在面对真实数据时,常常会遇到难以直接使用的数据,将这些数据正则化并筛选出对分析真正有用的数据很重要,可以说是整个比赛最关键的一环。
在粗略了解了数据的规模和大致分布后,先找出数据缺失的值,根据语境进行填补,然后将类别型和离散型数据进行处理,将一些字符串数据进行转换。
对于本次比赛,我没考虑过特征之间的关系,有的方法可以利用特征之间的关系生成高维特征,在之后的比赛中可以尝试它的效果。
数据分箱也是非常实用的方法,可以降低复杂性,减少噪声的影响。
特征选择有卡方检验、相关系数等方法,还有递归消除,前者主要是特征间的相关性,后者是进行多轮训练,不断消除若干权值系数的特征。

调参与融合

本次比赛主要实用了XGBoost模型、LightGBM模型和CatBoost模型,这三个也是比赛中很常见的模型,对于数据集的划分,交叉验证法会比简单的划分效果好,更能避免过拟合。调参方面最直接的方法就是贪心调参,这种方法比较好理解,贝叶斯调参考虑了上一次的参数信息,好处是是一个黑箱,适用面很广。模型融合方面这次我使用了stacking,效果得到了提升,在参与类似的数据挖掘比赛时,由于不用考虑实际生产生活的限制,融合大量的模型往往能得到一个较好的结果,在接下来的比赛中我打算尝试更多的方法进行模型融合,作为一个突破口。

实践

print(f'There are {data_train.isnull().any().sum()} columns in train dataset with missing values.')

# nan可视化
missing = data_train.isnull().sum()/len(data_train)
missing = missing[missing > 0]
missing.sort_values(inplace=True)
missing.plot.bar()

one_value_fea_test = [col for col in data_test_a.columns if data_test_a[col].nunique() <= 1]

numerical_fea = list(data_train.select_dtypes(exclude=['object']).columns)
category_fea = list(filter(lambda x: x not in numerical_fea,list(data_train.columns)))

#过滤数值型类别特征
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(data_train,numerical_fea)

#每个数字特征得分布可视化
f = pd.melt(data_train, value_vars=numerical_serial_fea)
g = sns.FacetGrid(f, col="variable",  col_wrap=2, sharex=False, sharey=False)
g = g.map(sns.distplot, "value")

plt.figure(figsize=(8, 8))
sns.barplot(data_train["employmentLength"].value_counts(dropna=False)[:20],
            data_train["employmentLength"].value_counts(dropna=False).keys()[:20])
plt.show()

#转化成时间格式  issueDateDT特征表示数据日期离数据集中日期最早的日期(2007-06-01)的天数
data_train['issueDate'] = pd.to_datetime(data_train['issueDate'],format='%Y-%m-%d')
startdate = datetime.datetime.strptime('2007-06-01', '%Y-%m-%d')
data_train['issueDateDT'] = data_train['issueDate'].apply(lambda x: x-startdate).dt.days

#按照平均数填充数值型特征
data_train[numerical_fea] = data_train[numerical_fea].fillna(data_train[numerical_fea].median())
data_test_a[numerical_fea] = data_test_a[numerical_fea].fillna(data_train[numerical_fea].median())
#按照众数填充类别型特征
data_train[category_fea] = data_train[category_fea].fillna(data_train[category_fea].mode())
data_test_a[category_fea] = data_test_a[category_fea].fillna(data_train[category_fea].mode())

def employmentLength_to_int(s):
    if pd.isnull(s):
        return s
    else:
        return np.int8(s.split()[0])
for data in [data_train, data_test_a]:
    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)
###异常检测 均方差
def find_outliers_by_3segama(data,fea):
    data_std = np.std(data[fea])
    data_mean = np.mean(data[fea])
    outliers_cut_off = data_std * 3
    lower_rule = data_mean - outliers_cut_off
    upper_rule = data_mean + outliers_cut_off
    data[fea+'_outliers'] = data[fea].apply(lambda x:str('异常值') if x > upper_rule or x < lower_rule else '正常值')
    return data
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值