交叉验证的基本思想是把在某种意义下将原始数据(dataset)进行分组,一部分做为训练集(train set),另一部分做为验证集(validation set or test set),首先用训练集对分类器进行训练,再利用验证集来测试训练得到的模型(model),以此来做为评价分类器的性能指标。
K折交叉验证,初始采样分割成K个子样本,一个单独的子样本被保留作为验证模型的数据,其他K-1个样本用来训练。交叉验证重复K次,每个子样本验证一次,平均K次的结果或者使用其它结合方式,最终得到一个单一估测。这个方法的优势在于,同时重复运用随机产生的子样本进行训练和验证,每次的结果验证一次,10折交叉验证是最常用的。
sklearn是机器学习中一个常用的python第三方模块,里面对一些常用的机器学习方法进行了封装,在进行机器学习任务时,并不需要每个人都实现所有的算法,只需要简单的调用sklearn里的模块就可以实现大多数机器学习任务。
机器学习任务通常包括分类(Classification)和回归(Regression),常用的分类器包括SVM、KNN、贝叶斯、线性回归、逻辑回归、决策树、随机森林、xgboost、GBDT、boosting、神经网络NN。常见的降维方法包括TF-IDF、主题模型LDA、主成分分析PCA等等。
import pandas as pd
import numpy as np
from sklearn.model_selection import StratifiedKFold
import warnings
import lightgbm as lgb
from sklearn.metrics import roc_auc_score
warnings.filterwarnings('ignore')
def get_data():
train=pd.read_csv('/home/kesci/input/round11379/train_round_1.csv')
test=pd.read_csv('/home/kesci/input/round11379/test_round_1.csv')
data = pd.concat([train, test], axis=0, ignore_index=True)
data = data.fillna(-1)
return data
def split_train_test(data):
train_data = data[data['purchase'] != -1]
test_data = data[data['purchase'] == -1]
submit = test_data[['user_id','Product_id']].copy()
train_data = train_data.drop(['user_id','Product_id','seller'], axis=1)
test_data = test_data.drop(['user_id','Product_id','seller'], axis=1)
test_data = test_data.drop(['purchase','favorite'], axis=1)
return train_data,test_data,submit
def train_lgb(train_x, train_y, test_x,test_y,res,col):
kfold = StratifiedKFold(n_splits=5, shuffle=True, random_state=2019)#shuffle:是否在每次分割之前打乱顺序
lgb_paras ={
'learning_rate': 0.1,
'boosting_type': 'gbdt',
'objective': 'binary',
'metric': 'auc',
'num_leaves': 63,
'feature_fraction': 0.8,
'bagging_fraction': 0.8,
'bagging_freq': 5,
'seed': 1,
'bagging_seed': 1,
'feature_fraction_seed': 7,
'min_data_in_leaf': 20,
'nthread': -1,
'verbose': -1
}
scores=[]
test_pred = np.zeros(len(test_x))
for n_fold,(tr_idx, val_idx) in enumerate(kfold.split(train_x, train_y)):
print(f'the {n_fold} training start ...')
tr_x, tr_y, val_x, val_y = train_x.iloc[tr_idx], train_y[tr_idx], train_x.iloc[val_idx], train_y[val_idx]
train_set = lgb.Dataset(tr_x, tr_y)
val_set = lgb.Dataset(val_x, val_y)
lgb_model = lgb.train(lgb_paras, train_set,
valid_sets=[val_set], early_stopping_rounds=50, num_boost_round=40000, verbose_eval=50)
val_pred = lgb_model.predict(
val_x, num_iteration=lgb_model.best_iteration)
test_pred+=lgb_model.predict(
test_x, num_iteration=lgb_model.best_iteration)/ kfold.n_splits
val_score = roc_auc_score(val_y, val_pred)
scores.append(val_score)
print('cv: ', scores)
print('cv : ', np.mean(scores))
res[col]=test_pred
return res
if __name__ == "__main__":
for fea in ['purchase', 'favorite']:
if fea == 'purchase':
data = get_data()
train, test_x, submit_purchase = split_train_test(data)
train_x = train.drop(['purchase', 'favorite'], axis=1)
train_y = train['purchase']
submit_purchase = train_lgb(train_x, train_y, test_x, submit_purchase, 'purchase', 10)
del data, train, test_x, train_x, train_y
submit_purchase.columns = ['user_id', 'product_id', 'pred_purchase']
else:
data = get_data()
train, test_x, submit_favorite = split_train_test(data)
train_x = train.drop(['purchase', 'favorite'], axis=1)
train_y = train['favorite']
submit_favorite = train_lgb(train_x, train_y, test_x, submit_favorite, 'favorite', 5)
del data, train, test_x, train_x, train_y
submit_favorite.columns = ['user_id', 'product_id', 'pred_favorite']
可以作为一个base,以后直接套用。
n_splits:折叠次数,默认为3,至少为2。
shuffle:是否在每次分割之前打乱顺序。
random_state:随机种子,在shuffle==True时使用,默认使用np.random。
split(X, y):
X:array-like,shape(n_sample,n_features),训练数据集。
y:array-like,shape(n_sample),标签。
返回值:训练集数据的index与验证集数据的index。
objs: series,dataframe或者是panel构成的序列lsit
axis: 需要合并链接的轴,0是行,1是列
ignore_index:置true,合并的两个表就睡根据列字段对齐,然后合并。
import numpy as np
import pandas as pd
#创建一个Dataframe
data1=pd.DataFrame(np.arange(16).reshape(4,4),columns=list('ABCD'))
print(data1)
print(data1.iloc[0])# 按索引index取行值
print(data1.loc[:,'A'])# loc按属性值取值
print(data1.iloc[:,[0]])#按索引index取列值
输出:
A B C D
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
3 12 13 14 15
A 0
B 1
C 2
D 3
Name: 0, dtype: int64
0 0
1 4
2 8
3 12
Name: A, dtype: int64
A
0 0
1 4
2 8
3 12
StratifiedKFold用法类似Kfold,但是它是分层采样,确保训练集,验证集中各类别样本的比例与原始数据集中相同。因此一般使用StratifiedKFold。