emoji表情
import emoji
emoji.emojize(':laughing:',use_aliases=True)
打印信息
tf.logging.info('simple is great')
打印参数模板 左对齐
arg_dict = {'lr':0.1,'num_epoch':20,'batch_size':64}
for k,v in enumerate(arg_dict):
if k == 0:
print('----------arg start---------')
print(f'{v}'.ljust(20),arg_dict.get(v))
print('----------arg end-----------')
argparse设置参数
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--lr', default='0.1', type=float, help='learning rate')
parser.add_argument('--num_epoch', default='10', type=int, help='num epoch')
parser.add_argument('--batch_size', default='64', type=int, help='batch size')
args = parser.parse_args(args=[])
print(args)
print(args.lr, args.num_epoch, args.batch_size)
清除内存里的所有文件 使用这个后需要重新导包
%reset -f
对于多表的连接,主表和从表都有uid 对于从表 除了可以根据uid统计cate num 进行merge外
还可以统计从表中去重后uid的次数 具体方法:通过下面这种方式进行主从表的对应 比merge要快!!
def get_tax_info_count(id):
return len(change_info[change_info['id'] == id])
data['news_count'] = data['id'].apply(lambda x: get_tax_info_count(x))
1 one-hot 加权交叉特征 对能one-hot的做one-hot,之后再统一乘上某列 数值 特征, 类似 加权的感觉。
2 对于 一个类别型特征 或者 日期 先统计其 value_counts 然后 groupby uid 求counts的 max min mean等统计特征。
3 更多的统计特征np.mean,np.max,np.min,np.std,sp.stats.skew,sp.stats.kurtosis sp为scipy.stats
4 偏离值特征,统计完 max min sum mean 后,用 原特征 去和merge后的统计特征 做运算。 例如: df['a'] - df['a_b_mean'] ,除了sum的用除法之外
1 tfidf的改进版本 : S-TFIWF 详情可见:'https://github.com/coderSkyChen/2016CCF_BDCI_Sougou/blob/master/project/3-main/STFIWF.py'
2 使用不同的方法 做特征时 ,假如做好 tfidf 和 word2vec 模型有多层 或者模型是stacking结构时,可以先训练tfidf 再把Word2vec加到stacking的下一层。
3 如果三个属性中至少有一个属性缺失,那么就放弃该样本,因为他们认为这样的样本是不可靠的。
'''
使用字典建立对应的关系 然后使用apply 可用于给有序的特征进行编码 。比直接label encoder靠谱。
'''
def gradeTrans(x):
dict = {'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5, 'F': 6, 'G': 7}
result = dict[x]
return result
data['grade'] = data['grade'].apply(lambda x: gradeTrans(x))
'''
2020华为digix第一的方案:
1 对于有时间因素的数据 对于更接近测试集时间的数据 给予更大的权重 例如测试集是8天 让第七天的权重是 1 则第二天的权重是 2/7
2 假如我们做了一份很完整的特征 我们还可以通过额外两种方式 进一步获取有差异性的特征。
2.1 去除很多冗余的特征 用部分特征去训练
2.2 采用滑窗的方式 去构造相同的特征
2.3 将三个差异性的模型的结果进行融合 不过理所应当的是 主模型的权重应当大一些
3 特征映射 特征弱化 前提是:测试集其实不是最近的第八天的用户。因为我们定义了新用户后 看每一天新用户的曝光占比 第八天的和前七天存在明显的差异
对于这样的情况 问题就在于 这些是实际的老用户 但是却符合新用户的分布 我们需要对其进行修正 主要是第三点提分很明显。
4 使用joblib进行并行化训练 具体的参考 https://github.com/digix2020/digix2020_ctr_rank1/blob/main/ctr/full.py 最下面的部分代码
'''
设置不同权重:
weight = X_train['pt_d'] / X_train['pt_d'].max()
lgb_train = lgb.Dataset(X_train[feature], y_train, weight = weight)
特征映射:
def adjust(df, key, feature):
if key == 'uid':
mean7 = df[df['pt_d'] < 8][feature].mean()
std7 = df[df['pt_d'] < 8][feature].std()
mean8 = df[(df['pt_d'] >= 8) & (df['coldu'] == 1)][feature].mean()
std8 = df[(df['pt_d'] >= 8) & (df['coldu'] == 1)][feature].std()
df.loc[(df['pt_d'] >= 8) & (df['coldu'] == 1), feature]= ((df[(df['pt_d'] >= 8) & (df['coldu'] == 1)][feature] - mean8) / std8 * std7 + mean7)
return df
用在这些地方:
print('开始构造count特征')
cate_cols = [...]
for f in tqdm(cate_cols):
tmp = df[f].map(df[f].value_counts())
if tmp.var() > 1:
df[f + '_count'] = tmp
df = adjust(df, f, f + '_count') #用在这里 或者是 用在 uid cate group by nunique这种特征上。
特征弱化:
df = df.reset_index()
df_trans = df[df['pt_d']==7][['index']].sample(frac=0.3, random_state=1)
df_trans['trans'] = 1
df = df.merge(df_trans,on='index',how='left')
df.loc[df['trans'] == 1, 'uid_rate'] = df[df['pt_d'] < 7]['label'].mean()
'''
华为digix 第二名的方案
1 看验证集中不在训练集中uid 测试集中不在训练集的uid
发现测试集的更多 于是直接删掉训练集中一些uid的log 我理解的是 删掉那些在验证集上存在的uid的log 增大验证集新uid的比例 使其与test同分布
2 使用所有天数的来做特征 然后他只取得是最近一天的拿来训练 这样数据量很小 且快
我觉得可以加权把不同天的模型结果进行融合
'''
'''
样本筛选
基于模型的策略
比如二分类问题,当train中的预测概率在0.5附近时,我们选择删除掉这些样本 可能效果会有所提升 因为这些样本是难以训练的
基于数据的策略
例如推荐中 有位置偏差 我们更倾向于取前几个曝光位置的未点击记录作为负样本 而不取全部
例如时间维度上一段时间的数据 我们去与test最接近的一段时间拿来训练 可能效果更好
'''
对于信用贷款数据类的 只有唯一的uid 可以把其他的id相加起来 再做label encoder或用其进行聚合特征的运算。
对于浮点数的特征 可以用df[num] - np.floor(df[num]) 得到一列新的特征。
假如有 train_1.csv train_2.csv train_3.csv 可用列表的形式进行读取
train_list = [pd.read_csv(f'train_{i}' for i in range(1,4))]
for i, train in enumerate(train_list):
train.to_csv(f'train_tmp_{i}' for i in range(1,4))
df_train = pd.concat(train_list)
未完待续......
网友评论