主流机器学习模型模板代码+经验分享[xgb, lgb, Keras, LR]

刷比赛利器,感谢分享的人。

摘要

最近打各种比赛,在这里分享一些General Model,稍微改改就能用的

环境: python 3.5.2

XGBoost调参大全: http://blog.csdn.net/han_xiaoyang/article/details/52665396 
XGBoost 官方API: 
http://xgboost.readthedocs.io/en/latest//python/python_api.html


Preprocess

[python] view plain copy
  1. # 通用的预处理框架  
  2.   
  3. import pandas as pd  
  4. import numpy as np  
  5. import scipy as sp  
  6.   
  7. # 文件读取  
  8. def read_csv_file(f, logging=False):  
  9.     print("==========读取数据=========")  
  10.     data =  pd.read_csv(f)  
  11.     if logging:  
  12.         print(data.head(5))  
  13.         print(f, "包含以下列")  
  14.         print(data.columns.values)  
  15.         print(data.describe())  
  16.         print(data.info())  
  17.     return data  


Logistic Regression

[python] view plain copy
  1. # 通用的LogisticRegression框架  
  2.   
  3. import pandas as pd  
  4. import numpy as np  
  5. from scipy import sparse  
  6. from sklearn.preprocessing import OneHotEncoder  
  7. from sklearn.linear_model import LogisticRegression  
  8. from sklearn.preprocessing import StandardScaler  
  9.   
  10. # 1. load data  
  11. df_train = pd.DataFrame()  
  12. df_test  = pd.DataFrame()  
  13. y_train = df_train['label'].values  
  14.   
  15. # 2. process data  
  16. ss = StandardScaler()  
  17.   
  18.   
  19. # 3. feature engineering/encoding  
  20. # 3.1 For Labeled Feature  
  21. enc = OneHotEncoder()  
  22. feats = ["creativeID""adID""campaignID"]  
  23. for i, feat in enumerate(feats):  
  24.     x_train = enc.fit_transform(df_train[feat].values.reshape(-11))  
  25.     x_test = enc.fit_transform(df_test[feat].values.reshape(-11))  
  26.     if i == 0:  
  27.         X_train, X_test = x_train, x_test  
  28.     else:  
  29.         X_train, X_test = sparse.hstack((X_train, x_train)), sparse.hstack((X_test, x_test))  
  30.   
  31. # 3.2 For Numerical Feature  
  32. # It must be a 2-D Data for StandardScalar, otherwise reshape(-1, len(feats)) is required  
  33. feats = ["price""age"]  
  34. x_train = ss.fit_transform(df_train[feats].values)  
  35. x_test  = ss.fit_transform(df_test[feats].values)  
  36. X_train, X_test = sparse.hstack((X_train, x_train)), sparse.hstack((X_test, x_test))  
  37.   
  38. # model training  
  39. lr = LogisticRegression()  
  40. lr.fit(X_train, y_train)  
  41. proba_test = lr.predict_proba(X_test)[:, 1]  



LightGBM

1. 二分类


[python] view plain copy
  1. import lightgbm as lgb  
  2. import pandas as pd  
  3. import numpy as np  
  4. import pickle  
  5. from sklearn.metrics import roc_auc_score  
  6. from sklearn.model_selection import train_test_split  
  7.   
  8. print("Loading Data ... ")  
  9.   
  10. # 导入数据  
  11. train_x, train_y, test_x = load_data()  
  12.   
  13. # 用sklearn.cross_validation进行训练数据集划分,这里训练集和交叉验证集比例为7:3,可以自己根据需要设置  
  14. X, val_X, y, val_y = train_test_split(  
  15.     train_x,  
  16.     train_y,  
  17.     test_size=0.05,  
  18.     random_state=1,  
  19.     stratify=train_y ## 这里保证分割后y的比例分布与原数据一致  
  20. )  
  21.   
  22. X_train = X  
  23. y_train = y  
  24. X_test = val_X  
  25. y_test = val_y  
  26.   
  27.   
  28. # create dataset for lightgbm  
  29. lgb_train = lgb.Dataset(X_train, y_train)  
  30. lgb_eval = lgb.Dataset(X_test, y_test, reference=lgb_train)  
  31. # specify your configurations as a dict  
  32. params = {  
  33.     'boosting_type''gbdt',  
  34.     'objective''binary',  
  35.     'metric': {'binary_logloss''auc'},  
  36.     'num_leaves'5,  
  37.     'max_depth'6,  
  38.     'min_data_in_leaf'450,  
  39.     'learning_rate'0.1,  
  40.     'feature_fraction'0.9,  
  41.     'bagging_fraction'0.95,  
  42.     'bagging_freq'5,  
  43.     'lambda_l1'1,    
  44.     'lambda_l2'0.001,  # 越小l2正则程度越高  
  45.     'min_gain_to_split'0.2,  
  46.     'verbose'5,  
  47.     'is_unbalance'True  
  48. }  
  49.   
  50. # train  
  51. print('Start training...')  
  52. gbm = lgb.train(params,  
  53.                 lgb_train,  
  54.                 num_boost_round=10000,  
  55.                 valid_sets=lgb_eval,  
  56.                 early_stopping_rounds=500)  
  57.   
  58. print('Start predicting...')  
  59.   
  60. preds = gbm.predict(test_x, num_iteration=gbm.best_iteration)  # 输出的是概率结果  
  61.   
  62. # 导出结果  
  63. threshold = 0.5  
  64. for pred in preds:  
  65.     result = 1 if pred > threshold else 0  
  66.   
  67. # 导出特征重要性  
  68. importance = gbm.feature_importance()  
  69. names = gbm.feature_name()  
  70. with open('./feature_importance.txt''w+') as file:  
  71.     for index, im in enumerate(importance):  
  72.         string = names[index] + ', ' + str(im) + '\n'  
  73.         file.write(string)  


2. 多分类

[python] view plain copy
  1. import lightgbm as lgb  
  2. import pandas as pd  
  3. import numpy as np  
  4. import pickle  
  5. from sklearn.metrics import roc_auc_score  
  6. from sklearn.model_selection import train_test_split  
  7.   
  8. print("Loading Data ... ")  
  9.   
  10. # 导入数据  
  11. train_x, train_y, test_x = load_data()  
  12.   
  13. # 用sklearn.cross_validation进行训练数据集划分,这里训练集和交叉验证集比例为7:3,可以自己根据需要设置  
  14. X, val_X, y, val_y = train_test_split(  
  15.     train_x,  
  16.     train_y,  
  17.     test_size=0.05,  
  18.     random_state=1,  
  19.     stratify=train_y ## 这里保证分割后y的比例分布与原数据一致  
  20. )  
  21.   
  22. X_train = X  
  23. y_train = y  
  24. X_test = val_X  
  25. y_test = val_y  
  26.   
  27.   
  28. # create dataset for lightgbm  
  29. lgb_train = lgb.Dataset(X_train, y_train)  
  30. lgb_eval = lgb.Dataset(X_test, y_test, reference=lgb_train)  
  31. # specify your configurations as a dict  
  32. params = {  
  33.     'boosting_type''gbdt',  
  34.     'objective''multiclass',  
  35.     'num_class'9,  
  36.     'metric''multi_error',  
  37.     'num_leaves'300,  
  38.     'min_data_in_leaf'100,  
  39.     'learning_rate'0.01,  
  40.     'feature_fraction'0.8,  
  41.     'bagging_fraction'0.8,  
  42.     'bagging_freq'5,  
  43.     'lambda_l1'0.4,  
  44.     'lambda_l2'0.5,  
  45.     'min_gain_to_split'0.2,  
  46.     'verbose'5,  
  47.     'is_unbalance'True  
  48. }  
  49.   
  50. # train  
  51. print('Start training...')  
  52. gbm = lgb.train(params,  
  53.                 lgb_train,  
  54.                 num_boost_round=10000,  
  55.                 valid_sets=lgb_eval,  
  56.                 early_stopping_rounds=500)  
  57.   
  58. print('Start predicting...')  
  59.   
  60. preds = gbm.predict(test_x, num_iteration=gbm.best_iteration)  # 输出的是概率结果  
  61.   
  62. # 导出结果  
  63. for pred in preds:  
  64.     result = prediction = int(np.argmax(pred))  
  65.   
  66. # 导出特征重要性  
  67. importance = gbm.feature_importance()  
  68. names = gbm.feature_name()  
  69. with open('./feature_importance.txt''w+') as file:  
  70.     for index, im in enumerate(importance):  
  71.         string = names[index] + ', ' + str(im) + '\n'  
  72.         file.write(string)  


XGBoost

1. 二分类

[python] view plain copy
  1. import numpy as np  
  2. import pandas as pd  
  3. import xgboost as xgb  
  4. import time  
  5. from sklearn.model_selection import StratifiedKFold  
  6.   
  7.   
  8. from sklearn.model_selection import train_test_split  
  9. train_x, train_y, test_x = load_data()  
  10.   
  11. # 构建特征  
  12.   
  13.   
  14. # 用sklearn.cross_validation进行训练数据集划分,这里训练集和交叉验证集比例为7:3,可以自己根据需要设置  
  15. X, val_X, y, val_y = train_test_split(  
  16.     train_x,  
  17.     train_y,  
  18.     test_size=0.01,  
  19.     random_state=1,  
  20.     stratify=train_y  
  21. )  
  22.   
  23. # xgb矩阵赋值  
  24. xgb_val = xgb.DMatrix(val_X, label=val_y)  
  25. xgb_train = xgb.DMatrix(X, label=y)  
  26. xgb_test = xgb.DMatrix(test_x)  
  27.   
  28. # xgboost模型 #####################  
  29.   
  30. params = {  
  31.     'booster''gbtree',  
  32.     # 'objective': 'multi:softmax',  # 多分类的问题、  
  33.     # 'objective': 'multi:softprob',   # 多分类概率  
  34.     'objective''binary:logistic',  
  35.     'eval_metric''logloss',  
  36.     # 'num_class': 9,  # 类别数,与 multisoftmax 并用  
  37.     'gamma'0.1,  # 用于控制是否后剪枝的参数,越大越保守,一般0.1、0.2这样子。  
  38.     'max_depth'8,  # 构建树的深度,越大越容易过拟合  
  39.     'alpha'0,   # L1正则化系数  
  40.     'lambda'10,  # 控制模型复杂度的权重值的L2正则化项参数,参数越大,模型越不容易过拟合。  
  41.     'subsample'0.7,  # 随机采样训练样本  
  42.     'colsample_bytree'0.5,  # 生成树时进行的列采样  
  43.     'min_child_weight'3,  
  44.     # 这个参数默认是 1,是每个叶子里面 h 的和至少是多少,对正负样本不均衡时的 0-1 分类而言  
  45.     # ,假设 h 在 0.01 附近,min_child_weight 为 1 意味着叶子节点中最少需要包含 100 个样本。  
  46.     # 这个参数非常影响结果,控制叶子节点中二阶导的和的最小值,该参数值越小,越容易 overfitting。  
  47.     'silent'0,  # 设置成1则没有运行信息输出,最好是设置为0.  
  48.     'eta'0.03,  # 如同学习率  
  49.     'seed'1000,  
  50.     'nthread': -1,  # cpu 线程数  
  51.     'missing'1,  
  52.     'scale_pos_weight': (np.sum(y==0)/np.sum(y==1))  # 用来处理正负样本不均衡的问题,通常取:sum(negative cases) / sum(positive cases)  
  53.     # 'eval_metric': 'auc'  
  54. }  
  55. plst = list(params.items())  
  56. num_rounds = 2000  # 迭代次数  
  57. watchlist = [(xgb_train, 'train'), (xgb_val, 'val')]  
  58.   
  59. # 交叉验证  
  60. result = xgb.cv(plst, xgb_train, num_boost_round=200, nfold=4, early_stopping_rounds=200, verbose_eval=True, folds=StratifiedKFold(n_splits=4).split(X, y))  
  61.   
  62. # 训练模型并保存  
  63. # early_stopping_rounds 当设置的迭代次数较大时,early_stopping_rounds 可在一定的迭代次数内准确率没有提升就停止训练  
  64. model = xgb.train(plst, xgb_train, num_rounds, watchlist, early_stopping_rounds=200)  
  65. model.save_model('../data/model/xgb.model')  # 用于存储训练出的模型  
  66.   
  67. preds = model.predict(xgb_test)  
  68.   
  69. # 导出结果  
  70. threshold = 0.5  
  71. for pred in preds:  
  72.     result = 1 if pred > threshold else 0  


CatBoost

没用过,听老铁说还行


Keras

1. 二分类

[python] view plain copy
  1. import numpy as np  
  2. import pandas as pd  
  3. import time  
  4. from sklearn.model_selection import train_test_split  
  5. from matplotlib import pyplot as plt  
  6.   
  7. from keras.models import Sequential  
  8. from keras.layers import Dropout  
  9. from keras.layers import Dense, Activation  
  10. from keras.utils.np_utils import to_categorical  
  11.   
  12. # coding=utf-8  
  13. from model.util import load_data as load_data_1  
  14. from model.util_combine_train_test import load_data as load_data_2  
  15. from sklearn.preprocessing import StandardScaler # 用于特征的标准化  
  16. from sklearn.preprocessing import Imputer  
  17.   
  18. print("Loading Data ... ")  
  19. # 导入数据  
  20. train_x, train_y, test_x = load_data()  
  21.   
  22. # 构建特征  
  23. X_train = train_x.values  
  24. X_test  = test_x.values  
  25. y = train_y  
  26.   
  27. imp = Imputer(missing_values='NaN', strategy='mean', axis=0)  
  28. X_train = imp.fit_transform(X_train)  
  29.   
  30. sc = StandardScaler()  
  31. sc.fit(X_train)  
  32. X_train = sc.transform(X_train)  
  33. X_test  = sc.transform(X_test)  
  34.   
  35.   
  36. model = Sequential()  
  37. model.add(Dense(256, input_shape=(X_train.shape[1],)))  
  38. model.add(Activation('tanh'))  
  39. model.add(Dropout(0.3))  
  40. model.add(Dense(512))  
  41. model.add(Activation('relu'))  
  42. model.add(Dropout(0.3))  
  43. model.add(Dense(512))  
  44. model.add(Activation('tanh'))  
  45. model.add(Dropout(0.3))  
  46. model.add(Dense(256))  
  47. model.add(Activation('linear'))  
  48. model.add(Dense(1)) # 这里需要和输出的维度一致  
  49. model.add(Activation('sigmoid'))  
  50.   
  51. # For a multi-class classification problem  
  52. model.compile(loss='binary_crossentropy',  
  53.               optimizer='rmsprop',  
  54.               metrics=['accuracy'])  
  55.   
  56. epochs = 100  
  57. model.fit(X_train, y, epochs=epochs, batch_size=2000, validation_split=0.1, shuffle=True)  
  58.   
  59. # 导出结果  
  60. threshold = 0.5  
  61. for index, case in enumerate(X_test):  
  62.     case =np.array([case])  
  63.     prediction_prob = model.predict(case)  
  64.     prediction = 1 if prediction_prob[0][0] > threshold else 0  

2. 多分类

[python] view plain copy
  1. import numpy as np  
  2. import pandas as pd  
  3. import time  
  4. from sklearn.model_selection import train_test_split  
  5. from matplotlib import pyplot as plt  
  6.   
  7. from keras.models import Sequential  
  8. from keras.layers import Dropout  
  9. from keras.layers import Dense, Activation  
  10. from keras.utils.np_utils import to_categorical  
  11.   
  12. # coding=utf-8  
  13. from model.util import load_data as load_data_1  
  14. from model.util_combine_train_test import load_data as load_data_2  
  15. from sklearn.preprocessing import StandardScaler # 用于特征的标准化  
  16. from sklearn.preprocessing import Imputer  
  17.   
  18. print("Loading Data ... ")  
  19. # 导入数据  
  20. train_x, train_y, test_x = load_data()  
  21.   
  22. # 构建特征  
  23. X_train = train_x.values  
  24. X_test  = test_x.values  
  25. y = train_y  
  26.   
  27. # 特征处理  
  28. sc = StandardScaler()  
  29. sc.fit(X_train)  
  30. X_train = sc.transform(X_train)  
  31. X_test  = sc.transform(X_test)  
  32. y = to_categorical(y) ## 这一步很重要,一定要将多类别的标签进行one-hot编码  
  33.   
  34.   
  35. model = Sequential()  
  36. model.add(Dense(256, input_shape=(X_train.shape[1],)))  
  37. model.add(Activation('tanh'))  
  38. model.add(Dropout(0.3))  
  39. model.add(Dense(512))  
  40. model.add(Activation('relu'))  
  41. model.add(Dropout(0.3))  
  42. model.add(Dense(512))  
  43. model.add(Activation('tanh'))  
  44. model.add(Dropout(0.3))  
  45. model.add(Dense(256))  
  46. model.add(Activation('linear'))  
  47. model.add(Dense(9)) # 这里需要和输出的维度一致  
  48. model.add(Activation('softmax'))  
  49.   
  50. # For a multi-class classification problem  
  51. model.compile(optimizer='rmsprop',  
  52.               loss='categorical_crossentropy',  
  53.               metrics=['accuracy'])  
  54.   
  55. epochs = 200  
  56. model.fit(X_train, y, epochs=epochs, batch_size=200, validation_split=0.1, shuffle=True)  
  57.   
  58. # 导出结果  
  59. for index, case in enumerate(X_test):  
  60.     case = np.array([case])  
  61.     prediction_prob = model.predict(case)  
  62.     prediction = np.argmax(prediction_prob)  


处理正负样本不均匀的案例

有些案例中,正负样本数量相差非常大,数据严重unbalanced,这里提供几个解决的思路

[python] view plain copy
  1. # 计算正负样本比例  
  2. positive_num = df_train[df_train['label']==1].values.shape[0]  
  3. negative_num = df_train[df_train['label']==0].values.shape[0]  
  4. print(float(positive_num)/float(negative_num))  


主要思路

1. 手动调整正负样本比例
2. 过采样 Over-Sampling
对训练集里面样本数量较少的类别(少数类)进行过采样,合成新的样本来缓解类不平衡,比如SMOTE算法
3. 欠采样 Under-Sampling
4. 将样本按比例一一组合进行训练,训练出多个弱分类器,最后进行集成

框架推荐

Github上大神写的相关框架,专门用来处理此类问题: 
https://github.com/scikit-learn-contrib/imbalanced-learn


写在最后

实践永远是检验真理的不二选择

多打打比赛,对各种业务环境下的任务都能有所了解,也能学习新技术。


你可能感兴趣的:(Kaggle+天池竞赛)