数据分析常用代码(持续更新)

模型

  • Xgboost
    import xgboost as xgb
    def xgb_model(X_t, X_v, y_t, y_v, test):
        print("XGB model start")
        
        xgb_val = xgb.DMatrix(X_v, label=y_v)
        xgb_train = xgb.DMatrix(X_t, label=y_t)
        xgb_test = xgb.DMatrix(test)
        
        params = {
                  'booster': 'gbtree',
                  'objective': 'binary:logistic',
                  'eval_metric': 'auc',
                #   'gamma': 0.1, # 用于控制是否后剪枝的参数,越大越保守,一般0.1、0.2这样子。
                #   'max_depth': 8, # 构建树的深度,越大越容易过拟合
                #   'alpha': 0, # L1正则化系数
                  'lambda': 10, # 控制模型复杂度的权重值的L2正则化项参数,参数越大,模型越不容易过拟合。
                  'subsample': 0.7, # 随机采样训练样本
                #   'colsample_bytree': 0.5, # 生成树时进行的列采样
                #   'min_child_weight': 3,
                #   这个参数默认是 1,是每个叶子里面 h 的和至少是多少,对正负样本不均衡时的 0-1 分类而言
                #   ,假设 h 在 0.01 附近,min_child_weight 为 1 意味着叶子节点中最少需要包含 100 个样本。
                #   这个参数非常影响结果,控制叶子节点中二阶导的和的最小值,该参数值越小,越容易 overfitting。
                  'silent': True, # 设置成1则没有运行信息输出,最好是设置为0.
                  'eta': 0.01, # 如同学习率
                #   'seed': 1000,
                  'n_jobs': -1, # cpu 线程数
                #   'missing': 1,
                #   'scale_pos_weight': (np.sum(y==0)/np.sum(y==1)) # 用来处理正负样本不均衡的问题,通常取:sum(negative cases) / sum(positive cases)            
                  }
    
        plst = list(params.items())
        num_rounds = 5000 # 迭代次数
        watchlist = [(xgb_train, 'train'), (xgb_val, 'val')]    
        # 训练模型并保存
        # early_stopping_rounds 当设置的迭代次数较大时,early_stopping_rounds 可在一定的迭代次数内准确率没有提升就停止训练
        model = xgb.train(plst, xgb_train, num_rounds, watchlist, early_stopping_rounds=200)
        res = model.predict(xgb_test)    
        print('test prediction finished')
        return res
  • Catboost
    from catboost import CatBoostClassifier
    def cb_model(X_t, X_v, y_t, y_v, test):
        print('cb_model start')
        category=[] # 
        c_list = ['user_id','Product_id','seller']# ,'day'
        for index,value in enumerate(X_t.columns):
            if(value in c_list):
                category.append(index)
                continue
        model= CatBoostClassifier(iterations=1000,learning_rate=0.04,cat_features=category, loss_function='Logloss',
                                logging_level='Verbose',eval_metric='AUC')
        model.fit(X_t,y_t,eval_set=(X_v,y_v),early_stopping_rounds=100)
        res=model.predict_proba(test)[:,1]
        # importance=model.get_feature_importance(prettified=True)# 显示特征重要程度
        # print(importance)
        return res
  • LightGBM
    import lightgbm as lgb
    def lgb_model(X_t, X_v, y_t, y_v, test):
        print('lgb start')
    
        lgb_train = lgb.Dataset(X_t, y_t)
        lgb_eval = lgb.Dataset(X_v, y_v, reference=lgb_train)
    
        # 参数
        params = {        
            'boosting_type': 'gbdt',  # 设置提升类型
            'objective': 'regression',  # 目标函数
            'metric': {'l2', 'auc'},  # 评估函数
            # 'num_leaves': 31,  # 叶子节点数
            'learning_rate': 0.01,  # 学习速率
            'feature_fraction': 0.9,  # 建树的特征选择比例
            'bagging_fraction': 0.8,  # 建树的样本采样比例
            'bagging_freq': 5,  # k 意味着每 k 次迭代执行bagging
            'verbose': 1  # <0 显示致命的, =0 显示错误 (警告), >0 显示信息
        }
    
        # 模型训练
        gbm = lgb.train(params, lgb_train, num_boost_round=500, valid_sets=lgb_eval,             early_stopping_rounds=50)
    
        # 模型保存
        # gbm.save_model('model.txt')
        # 模型加载
        # gbm = lgb.Booster(model_file='model.txt')
    
        # 模型预测
        res = gbm.predict(X_test, num_iteration=gbm.best_iteration)
        return res

     

统计图

  • 特征(列)数据分布情况
    import seaborn as sns
    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt 
    
    '''特征分布图'''
    for column in trains.columns[1:-1]:# 遍历trains中的所有行
        g = sns.kdeplot(trains[column][(trains["fake"] == 1)], color="Red", shade = True)# label为1的
        g = sns.kdeplot(trains[column][(trains["fake"] == 0)], color="Green", shade=True)# label为0的
    
        # g = sns.kdeplot(trains[column], ax=g, color="Green", shade=True)# trains中所有
        # g = sns.kdeplot(tests[column], ax =g, color="Blue", shade= True)# test中所有
    
        g.set_xlabel(column)
        g.set_ylabel("Frequency")
        g = g.legend(["train_fake", "train_normal", "test"])
    
        plt.show()
    
    print("finish")
  • 探索性分析
    import pandas_profiling
    def pd_profiling(df,path):# df为dataframe,path为文件保存路径
        # 用pandas_profiling进行EDA
        profile = pandas_profiling.ProfileReport(df)
        profile.to_file(output_file=path)# 也可直接写"filename.html"

     

数据处理

  • 分箱操作
    def pandas_qcut(col, type, n):
        '''
        type分箱类型cut,qcut
        col是准备分箱的列
        n是组数
        返回值是列,需要再赋值给数据集
        '''
    
        if type=='q':
            col_cut=pd.qcut(col, n, labels=[i for i in range(1, n+1)])
        else:
            col_cut = pd.cut(col, n, labels=[i for i in range(1, n+1)])
        return col_cut
    def pct_rank_qcut(series, n):
        '''
        在python 较新的版本中,pandas.qcut()这个函数中是有duplicates这个参数的,
        它能解决在等频分箱中遇到的重复值过多引起报错的问题
        series:要分箱的列
        n:箱子数
        '''
        edages = pd.Series([i/n for i in range(n)]) # 转换成百分比
        func = lambda x: (edages >= x).argmax() #函数:(edages >= x)返回fasle/true列表中第一次出现true的索引值
        return series.rank(pct=1).astype(float).apply(func) #series.rank(pct=1)每个值对应的百分位数,最终返回对应的组数;rank()函数传入的数据类型若为object,结果会有问题,因此进行了astype

     

  • 对所有列做与标准差的差和其结果绝对值
    def std_abs(data,col_n):    # 传入合并后的数据集,返回一个增加了每列与本列标准差的差,绝对值的列
        data = data.fillna(data.mean())# 不能有空值和字符类型    
        for i in col_n:
            data[i + 'std'] = data[i] - data[i].std()
            data[i + 'std_abs'] = data[i + 'std'].abs()
        print('std_abs finished')
        return data

     

损失函数

  • focal_loss
    def focal_loss(predictions, labels, alpha = 0.25, gamma = 2):
        zeros = np.zeros_like(predictions, dtype=predictions.dtype)
        pos_corr = np.where(labels > zeros, labels - predictions, zeros)
        neg_corr = np.where(labels > zeros, zeros, predictions)
        fl_loss = - alpha*(pos_corr ** gamma)*np.log(predictions)-(1.0 - alpha)*(neg_corr ** gamma)*np.log(1-predictions)
        return np.sum(fl_loss)

     

上一篇:LightGBM综述


下一篇:LightGBM建模