DataFound 2019用户画像竞赛分析

DataFound 2019用户画像竞赛分析

1. 数据解释

  • 列对应的中文
['用户编码', '用户实名制是否通过核实', '用户年龄', '是否大学生客户', '是否黑名单客户', '是否4G不健康客户','用户网龄(月)', '用户最近一次缴费距今时长(月)', '缴费用户最近一次缴费金额(元)', '用户近6个月平均消费值(元)','用户账单当月总费用(元)', '用户当月账户余额(元)', '缴费用户当前是否欠费缴费', '用户话费敏感度', '当月通话交往圈人数','是否经常逛商场的人', '近三个月月均商场出现次数', '当月是否逛过福州仓山万达', '当月是否到过福州山姆会员店', '当月是否看电影','当月是否景点游览', '当月是否体育场馆消费', '当月网购类应用使用次数', '当月物流快递类应用使用次数','当月金融理财类应用使用总次数', '当月视频播放类应用使用次数', '当月飞机类应用使用次数', '当月火车类应用使用次数','当月旅游资讯类应用使用次数', '信用分']
  • 列对应的英文
['uid','true_name_flag','age','uni_student_flag','blk_list_flag','4g_unhealth_flag','net_age_till_now','top_up_month_diff','top_up_amount','recent_6month_avg_use','total_account_fee','curr_month_balance','curr_overdue_flag','cost_sensitivity','connect_num','freq_shopping_flag','recent_3month_shopping_count','wanda_flag','sam_flag','movie_flag','tour_flag','sport_flag','online_shopping_count','express_count','finance_app_count','video_app_count','flight_count','train_count','tour_app_count','score']

2. 特征提取

  • 充值金额:
    • 整数和小数对应不同的充值渠道。比如说整数对应现金渠道,小数对应在线支付。
  • 算充话费的稳定性
    • 用户账单当月总费用(元) / 用户近6个月平均消费值(元)
  • 当月话费使用率
    • 当月话费总额 / 当月剩余话费
  • 计算除用户ID以外的所有的列的和
    • 整体考虑

3. 用到的求和函数

  • 计算各列数据总和并作为新列添加到末尾
df['col_sum'] = df.apply(lambda x: x.sum(), axis=1)
  • 计算各行数据总和并作为新行添加到末尾
df.loc['row_sum'] = df.apply(lambda x: x.sum())

4. 代码实现

# 包导入

import time
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import pandas as pd
import lightgbm as lgb
from sklearn.model_selection import StratifiedKFold
from sklearn.preprocessing import LabelEncoder

# 输入数据
data_path = '../input/'
train_data = pd.read_csv(data_path + 'train_dataset.csv')
test_data = pd.read_csv(data_path + 'test_dataset.csv')
sample_sub = pd.read_csv(data_path + 'submit_example.csv')

# 预处理
train_data.head(1)
print(train_data.columns)

train_data.columns = ['uid','true_name_flag','age','uni_student_flag','blk_list_flag',\
                     '4g_unhealth_flag','net_age_till_now','top_up_month_diff','top_up_amount',\
                     'recent_6month_avg_use','total_account_fee','curr_month_balance',\
                     'curr_overdue_flag','cost_sensitivity','connect_num','freq_shopping_flag',\
                     'recent_3month_shopping_count','wanda_flag','sam_flag','movie_flag',\
                     'tour_flag','sport_flag','online_shopping_count','express_count',\
                     'finance_app_count','video_app_count','flight_count','train_count',\
                     'tour_app_count','score']
test_data.columns = train_data.columns[:-1]


# 特征提取
# top up amount, 充值金额是整数,和小数,应该对应不同的充值途径?

def produce_offline_feat(train_data):
    train_data['top_up_amount_offline'] = 0
    train_data['top_up_amount_offline'][(train_data['top_up_amount'] % 10 == 0) & train_data['top_up_amount'] != 0] = 1
    return train_data


train_data = produce_offline_feat(train_data)
test_data = produce_offline_feat(test_data)


def produce_fee_rate(train_data):
    # 看importance,当月话费 和最近半年平均话费都很高,算一下当月/半年 -->稳定性
    train_data['current_fee_stability'] = train_data['total_account_fee'] / (train_data['recent_6month_avg_use'] + 1)
    
    # 当月话费/当月账户余额
    train_data['use_left_rate'] = train_data['total_account_fee'] / (train_data['curr_month_balance'] + 1)
    return train_data


train_data = produce_fee_rate(train_data)
test_data = produce_fee_rate(test_data)


# 训练
def display_importances(feature_importance_df_):
    cols = feature_importance_df_[["feature", "importance"]].groupby("feature").mean().sort_values(by="importance", ascending=False)[:40].index
    best_features = feature_importance_df_.loc[feature_importance_df_.feature.isin(cols)]
    plt.figure(figsize=(8, 10))
    sns.barplot(x="importance", y="feature", data=best_features.sort_values(by="importance", ascending=False))
    plt.title('LightGBM Features (avg over folds)')
    plt.tight_layout()
    plt.show()
    plt.savefig('feature_importance.jpg')

# para
params = {
    'learning_rate': 0.01,
    'boosting_type': 'gbdt',
    'objective': 'regression_l1',
    'metric': 'mae',
    'feature_fraction': 0.6,
    'bagging_fraction': 0.8,
    'bagging_freq': 2,
    'num_leaves': 31,
    'verbose': -1,
    'max_depth': 5,
    'lambda_l2': 5,
    'lambda_l1': 0,
    'nthread': 8
}

# para
params2 = {
    'learning_rate': 0.01,
    'boosting_type': 'gbdt',
    'objective': 'regression_l2',
    'metric': 'mae',
    'feature_fraction': 0.6,
    'bagging_fraction': 0.8,
    'bagging_freq': 2,
    'num_leaves': 31,
    'verbose': -1,
    'max_depth': 5,
    'lambda_l2': 5,
    'lambda_l1': 0,
    'nthread': 8,
    'seed': 89
}

cv_pred_all = 0
en_amount = 3
for seed in range(en_amount):
    NFOLDS = 5
    train_label = train_data['score']
    kfold = StratifiedKFold(n_splits=NFOLDS, shuffle=True, random_state=seed)
    kf = kfold.split(train_data, train_label)
    
    train_data_use = train_data.drop(['uid', 'score', 'blk_list_flag'], axis=1)
    test_data_use = test_data.drop(['uid', 'blk_list_flag'], axis=1)
    
    cv_pred = np.zeros(test_data.shape[0])
    valid_best_l2_all = 0
    
    feature_importance_df = pd.DataFrame()
    count = 0
    for i, (train_fold, validate) in enumerate(kf):
        print('fold: ', i, ' training')
        X_train, X_validate, label_train, label_validate = train_data_use.iloc[train_fold, :], train_data_use.iloc[validate, :], train_label[train_fold], train_label[validate]
        dtrain = lgb.Dataset(X_train, label_train)
        dvalid = lgb.Dataset(X_validate, label_validate, reference=dtrain)
        bst = lgb.train(params, dtrain, num_boost_round=10000, valid_sets=dvalid, verbose_eval=-1, early_stopping_rounds=50)
        cv_pred += bst.predict(test_data_use, num_iteration=bst.best_iteration)
        valid_best_l2_all += bst.best_score['valid_0']['l1']
        
        fold_importance_df = pd.DataFrame()
        fold_importance_df["feature"] = list(X_train.columns)
        fold_importance_df["importance"] = bst.feature_importance(importance_type='split', iteration=bst.best_iteration)
        fold_importance_df["fold"] = count + 1
        feature_importance_df = pd.concat([feature_importance_df, fold_importance_df], axis=0)
        count += 1

cv_pred /= NFOLDS
valid_best_l2_all /= NFOLDS

cv_pred_all += cv_pred
cv_pred_all /= en_amount
print('cv score for valid is: ', 1 / (1 + valid_best_l2_all))

cv_pred_all2 = 0
en_amount = 3
for seed in range(en_amount):
    NFOLDS = 5
    train_label = train_data['score']
    kfold = StratifiedKFold(n_splits=NFOLDS, shuffle=True, random_state=(seed + 2019))
    kf = kfold.split(train_data, train_label)
    
    train_data_use = train_data.drop(['uid', 'score', 'blk_list_flag'], axis=1)
    test_data_use = test_data.drop(['uid', 'blk_list_flag'], axis=1)
    
    cv_pred = np.zeros(test_data.shape[0])
    valid_best_l2_all = 0
    
    feature_importance_df = pd.DataFrame()
    count = 0
    for i, (train_fold, validate) in enumerate(kf):
        print('fold: ', i, ' training')
        X_train, X_validate, label_train, label_validate = train_data_use.iloc[train_fold, :], train_data_use.iloc[validate, :], train_label[train_fold], train_label[validate]
        dtrain = lgb.Dataset(X_train, label_train)
        dvalid = lgb.Dataset(X_validate, label_validate, reference=dtrain)
        bst = lgb.train(params2, dtrain, num_boost_round=10000, valid_sets=dvalid, verbose_eval=-1, early_stopping_rounds=50)
        cv_pred += bst.predict(test_data_use, num_iteration=bst.best_iteration)
        valid_best_l2_all += bst.best_score['valid_0']['l1']
    
        fold_importance_df = pd.DataFrame()
        fold_importance_df["feature"] = list(X_train.columns)
        fold_importance_df["importance"] = bst.feature_importance(importance_type='split', iteration=bst.best_iteration)
        fold_importance_df["fold"] = count + 1
        feature_importance_df = pd.concat([feature_importance_df, fold_importance_df], axis=0)
        count += 1

cv_pred /= NFOLDS
valid_best_l2_all /= NFOLDS

cv_pred_all2 += cv_pred

cv_pred_all2 /= en_amount
print('cv score for valid is: ', 1/(1+valid_best_l2_all))
display_importances(feature_importance_df)

# 提交
test_data_sub = test_data[['uid']]
test_data_sub['score'] = (cv_pred_all2 + cv_pred_all) / 2
test_data_sub.columns = ['id', 'score']
test_data_sub['score1'] = cv_pred_all
test_data_sub['score2'] = cv_pred_all2
test_data_sub['score'] = test_data_sub['score'].apply(lambda x: int(np.round(x)))
test_data_sub[['id', 'score']].to_csv('../output/result_bagging.csv', index=False)

5. 特征分析结果

image
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容

  • 第一章数和数的运算 一概念 (一)整数 1整数的意义 自然数和0都是整数。 2自然数 我们在数物体的时候,用来表示...
    meychang阅读 2,586评论 0 5
  • ORA-00001: 违反唯一约束条件 (.) 错误说明:当在唯一索引所对应的列上键入重复值时,会触发此异常。 O...
    我想起个好名字阅读 5,167评论 0 9
  • From 17 to 18 嗨,我叫佩奇。 时而躁动如火,时而温柔似水。时而安静得像活在象牙塔里,时而混...
    留我一人沉浮阅读 413评论 0 0
  • 画赋 国色天香尚自哀, 悲声泣自玉瓶来。 清风细雨斜疏影, 零落成尘亦笑开。
    红袖当空阅读 919评论 1 0
  • 前段时间,万科在广州推出了一款极小户型公寓:27-34㎡Loft+双钥匙设计 项目类型应该是酒店式公寓一类,所以层...
    良有方阅读 5,514评论 0 1