def train(**kwargs): for k_, v_ in kwargs: setattr(config, k_, v_) train_dataset, val_dataset, test_dataset = Ali(config) train_loader = dataloader(dataset=train_dataset, batch_size=config.batch_size, shuffle=True, drop_last=True) val_loader = dataloader(dataset=val_dataset, batch_size=config.batch_size) model = DeepFM() # testing if config.test_flag: test_loader = dataloader(dataset=test_dataset, batch_size=config.batch_size) model.load_state_dict(torch.load(os.path.join(config.model_path, '_best'))) test(model, test_loader, config.output_path) criterion = torch.nn.BCELoss() optimizer = Adam(model.parameters, lr=config.lr, betas=(config.beta1, config.beta2)) best_val_loss = 1e6 if torch.cuda.is_available(): model.cuda() criterion.cuda() # resume training start = 0 if config.resume: model_epoch = [int(fname.split('_')[-1]) for fname in os.listdir(config.model_path) if 'best' not in fname] start = max(model_epoch) model.load_state_dict(torch.load(os.path.join(config.model_path, '_epoch_{start}'))) if start >= config.epochs: print('Training already Done!') return for i in range(start, config.epochs): for ii, (c_data, labels) in enumerate(train_loader): c_data = to_var(c_data) labels = to_var(labels) pred = model(c_data) loss = criterion(pred, labels, criterion) loss.backward() optimizer.step() if (ii + 1) % config.eval_every == 0: val_loss = val(model, val_loader) print(f'''epochs: {i + 1}/{config.epochs} batch: {ii + 1}/{len(train_loader)}\t train_loss: {loss.data[0] / c_data.size(0)}, val_loss: {val_loss}''') torch.save(model.state_dict(), os.path.join(config.model_path, '_epoch_{i}')) if val_loss < best_val_loss: torch.save(model.state_dict(), os.path.join(config.model_path, '_best'))
def test_train_deepfm(train_data): conf = { "dim": 10, "num_iter": 5, "opt_cls": optim.Adam, "opt_kwargs": { "lr": 1e-3 }, "deep_layers": [32, 32], "deep_activation": F.relu } conf.update(train_data.conf) model = DeepFM(**conf) train_model(model, train_data.train_iter, train_data.test, conf)
def run_base_model_dfm(dfTrain,dfTest,folds,dfm_params): fd = FeatureDictionary(dfTrain=dfTrain, dfTest=dfTest, numeric_cols=config.NUMERIC_COLS, ignore_cols = config.IGNORE_COLS) data_parser = DataParser(feat_dict= fd) # Xi_train :列的序号 # Xv_train :列的对应的值 Xi_train,Xv_train,y_train = data_parser.parse(df=dfTrain,has_label=True) Xi_test,Xv_test,ids_test = data_parser.parse(df=dfTest) print(dfTrain.dtypes) dfm_params['feature_size'] = fd.feat_dim dfm_params['field_size'] = len(Xi_train[0]) y_train_meta = np.zeros((dfTrain.shape[0],1),dtype=float) y_test_meta = np.zeros((dfTest.shape[0],1),dtype=float) _get = lambda x,l:[x[i] for i in l] gini_results_cv = np.zeros(len(folds),dtype=float) gini_results_epoch_train = np.zeros((len(folds),dfm_params['epoch']),dtype=float) gini_results_epoch_valid = np.zeros((len(folds),dfm_params['epoch']),dtype=float) for i, (train_idx, valid_idx) in enumerate(folds): Xi_train_, Xv_train_, y_train_ = _get(Xi_train, train_idx), _get(Xv_train, train_idx), _get(y_train, train_idx) Xi_valid_, Xv_valid_, y_valid_ = _get(Xi_train, valid_idx), _get(Xv_train, valid_idx), _get(y_train, valid_idx) dfm = DeepFM(**dfm_params)# **kwargs: 不定长参数字典:init必须指定相应的参数项,但是传递的kwargs里面的key不定长 dfm.fit(Xi_train_, Xv_train_, y_train_, Xi_valid_, Xv_valid_, y_valid_) y_train_meta[valid_idx,0] = dfm.predict(Xi_valid_, Xv_valid_) y_test_meta[:,0] += dfm.predict(Xi_test, Xv_test) gini_results_cv[i] = gini_norm(y_valid_, y_train_meta[valid_idx]) gini_results_epoch_train[i] = dfm.train_result gini_results_epoch_valid[i] = dfm.valid_result y_test_meta /= float(len(folds)) # save result if dfm_params["use_fm"] and dfm_params["use_deep"]: clf_str = "DeepFM" elif dfm_params["use_fm"]: clf_str = "FM" elif dfm_params["use_deep"]: clf_str = "DNN" print("%s: %.5f (%.5f)" % (clf_str, gini_results_cv.mean(), gini_results_cv.std())) filename = "%s_Mean%.5f_Std%.5f.csv" % (clf_str, gini_results_cv.mean(), gini_results_cv.std()) # _make_submission(ids_test, y_test_meta, filename) # _plot_fig(gini_results_epoch_train, gini_results_epoch_valid, clf_str) return y_train_meta, y_test_meta
def _run_base_model_dfm(dfTrain, dfTest, folds, dfm_params, label2current_service): fd = FeatureDictionary(dfTrain=dfTrain, dfTest=dfTest, numeric_cols=config.NUMERIC_COLS, ignore_cols=config.IGNORE_COLS) data_parser = DataParser(feat_dict=fd) Xi_train, Xv_train, y_train = data_parser.parse(df=dfTrain, has_label=True) Xi_test, Xv_test, ids_test = data_parser.parse(df=dfTest) dfm_params["feature_size"] = fd.feat_dim dfm_params["field_size"] = len(Xi_train[0]) xx_score = [] cv_pred = [] y_train_meta = np.zeros((dfTrain.shape[0], 1), dtype=float) y_test_meta = np.zeros((dfTest.shape[0], 1), dtype=float) _get = lambda x, l: [x[i] for i in l] for i, (train_idx, valid_idx) in enumerate(folds): Xi_train_, Xv_train_, y_train_ = _get(Xi_train, train_idx), _get( Xv_train, train_idx), _get(y_train, train_idx) Xi_valid_, Xv_valid_, y_valid_ = _get(Xi_train, valid_idx), _get( Xv_train, valid_idx), _get(y_train, valid_idx) dfm = DeepFM(**dfm_params) dfm.fit(Xi_train_, Xv_train_, y_train_, Xi_valid_, Xv_valid_, y_valid_) xx_pred = dfm.predict(Xi_valid_, Xv_valid_) xx_score.append(f1_score(y_valid_, xx_pred, average='macro')) y_test = dfm.predict(Xi_test, Xv_test) if i == 0: cv_pred = np.asarray(y_test).reshape(-1, 1) else: cv_pred = np.hstack((cv_pred, np.asarray(y_test).reshape(-1, 1))) submit = [] for line in cv_pred: submit.append(np.argmax(np.bincount(line))) # 保存结果 df_test = pd.DataFrame() df_test['id'] = list(ids_test) df_test['predict'] = submit df_test['predict'] = df_test['predict'].map(label2current_service) df_test.to_csv('result.csv', index=False) print(xx_score, np.mean(xx_score)) return y_train_meta, y_test_meta
def main(): # build ordinal dataset dao = Dao() dao.build() X_train, X_test, y_train, y_test = dao.fetch_dataset() features_info = dao.features_info # pu learning dataset instance dataset = PUDataset(y_train, X_train) f1_scores = [] pu_f1_scores = [] labeled_rates = [0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1] for labeled_rate in labeled_rates: # fetch ordinal pu dataset y_train, X_train = dataset.fetch_pu_dataset(labeled_rate, val_split=False) # fetch pu dataset with val y_train_pu, X_train_pu, X_val_pos = dataset.fetch_pu_dataset( labeled_rate, val_split=True) # train ordinal model auc = tf.keras.metrics.AUC() optimizer = tf.keras.optimizers.Adam(lr=0.01, decay=0.1) model = BaseModel(features_info) model.compile(optimizer=optimizer, loss="binary_crossentropy", metrics=[auc]) model.fit(x=X_train, y=y_train, epochs=100, batch_size=100000) # train pu model auc = tf.keras.metrics.AUC() pu_optimizer = tf.keras.optimizers.Adam(lr=0.01, decay=0.1) pu_model = BaseModel(features_info) pu_model.compile(optimizer=pu_optimizer, loss="binary_crossentropy", metrics=[auc]) pu_model.fit(x=X_train_pu, y=y_train_pu, epochs=100, batch_size=100000) print(labeled_rate) # evaluate ordinal model y_pred = np.ravel(model.predict(X_test)) precision, recall, f1_score, _ = precision_recall_fscore_support( y_test, binarize(y_pred)) f1_scores.append(f1_score[1]) print("ordinal model") print("F1 score: {}".format(f1_score[1])) print("Precision: {}".format(precision[1])) print("Recall: {}".format(recall[1])) # evaluate pu model y_pred_pu = np.ravel(pu_model.predict(X_test)) y_val_pos_pred = np.ravel(pu_model.predict(X_val_pos)) y_pred_pu = calibrate_pu(y_pred_pu, y_val_pos_pred) precision, recall, f1_score, _ = precision_recall_fscore_support( y_test, binarize(y_pred_pu)) pu_f1_scores.append(f1_score[1]) print("pu model") print("F1 score: {}".format(f1_score[1])) print("Precision: {}".format(precision[1])) print("Recall: {}".format(recall[1])) # plot fig = plt.figure() plt.title("DeepFM with/without PU learning") plt.plot(labeled_rates, pu_f1_scores, label='PU Adapted DeepFM') plt.plot(labeled_rates, f1_scores, label='DeepFM') plt.xlabel('labeled sample rate of all positive samples') plt.ylabel('F1 Score') plt.legend() plt.gca().invert_xaxis() fig.savefig("result.png")
if len(sys.argv) < 2 or sys.argv[1] not in [ 'lr', 'lrcross', 'deepfm', 'dnn', 'widedeep' ]: print('usage train.py lr|lrcross|dnn|widedeep|deepfm') sys.exit(1) with open('../dataset.pkl', 'rb') as f: train_set = pickle.load(f) test_set = pickle.load(f) cate_list = pickle.load(f) user_count, item_count, cate_count = pickle.load(f) if sys.argv[1] == 'deepfm': from deepfm import DeepFM model = DeepFM(user_count=user_count, item_count=item_count, cate_count=cate_count, cate_list=cate_list) elif sys.argv[1] == 'lr': from lr import LR model = LR(user_count=user_count, item_count=item_count, cate_count=cate_count, cate_list=cate_list) elif sys.argv[1] == 'lrcross': from lrcross import LR model = LR(user_count=user_count, item_count=item_count, cate_count=cate_count, cate_list=cate_list) elif sys.argv[1] == 'dnn': from dnn import DNN
# coding = utf-8 from args import * from dice import dice from deepfm import DeepFM import sys nrows = None if len(sys.argv) >= 2: nrows = int(sys.argv[1]) if __name__ == '__main__': train = pd.read_csv(train_path, nrows=None).fillna('0') test = pd.read_csv(test_path, nrows=None).fillna('0') for s in features: train[s] = train[s].apply(str) test[s] = test[s].apply(str) train_x, train_y = train[features].values, train['label'].values.reshape((-1,1)) test_x, test_y = test[features].values, test['label'].values.reshape((-1,1)) model = DeepFM(features, feature_tags, activate=dice) model.fit(train_x, train_y, X_valid=test_x, y_valid=test_y)
def deepfm_test(self): train_x, train_y = DeepFM.df2xy(self._ratings) #test_x, test_y = DeepFM.df2xy(self.test_data_) params = { 'n_uid': self._ratings.userid.max(), 'n_mid': self._ratings.itemid.max(), # 'n_genre': self.n_genre_, 'k': self._k, 'dnn_dim': [64, 64], 'dnn_dr': 0.5, 'filepath': '../data/deepfm_weights.h5' } """ train """ model = DeepFM(**params) train_history = model.fit(train_x, train_y, epochs=self._epochs, batch_size=2048, validation_split=0.1) history = pd.DataFrame(train_history.history) history.plot() plt.savefig("../data//history.png") """ test """ results = model.evaluate(train_x, train_y) print("Validate result:{0}".format(results)) """ predict """ y_hat = model.predict(train_x) print(np.shape(y_hat)) # print(np.shape(test_y)) """ Run Recall and Precision Metrics """ n_users = np.max(self._ratings.userid.values) + 1 n_items = np.max(self._ratings.itemid.values) + 1 print("n_users={0} n_items={1}".format(n_users, n_items)) # Convert to sparse matrix to run standard metrics sparse_train = sparse.coo_matrix((self._ratings.rating.values, (self._ratings.userid.values, self._ratings.itemid.values)), shape=(n_users, n_items)) # sparse_test = sparse.coo_matrix((self.test_data_.rating.values, \ # (self.test_data_.uid.values, self.test_data_.mid.values)), \ # shape=(n_users, n_items)) # pd.DataFrame(data=sparse_test.tocsr().todense().A).to_csv("./testdata.csv") # test_prediced test_predicted = self._ratings.copy() test_predicted.rating = np.round(y_hat) sparse_predicted = sparse.coo_matrix((test_predicted.rating.values, \ (test_predicted.userid.values, test_predicted.itemid.values)), \ shape=(n_users, n_items)) sparse_train_1up = sparse_train.multiply(sparse_train >= 1) # sparse_test_1up = sparse_test.multiply(sparse_test >= 1) predicted_arr = sparse_predicted.tocsr().todense().A predicted_ranks = metrics.rank_matrix(predicted_arr) precision_ = metrics.precision_at_k(predicted_ranks, sparse_train, k=self._k) recall_ = metrics.recall_at_k(predicted_ranks, sparse_train, k=self._k) print("{0}.xdeepfm_test train precision={1:.4f}% recall={2:.4f}% @k={3}".format( __class__.__name__, precision_ * 100, recall_ * 100, self._k))
dnn_output = DNN(dnn_hidden_units, dnn_activation, l2_reg_dnn, dnn_dropout, dnn_use_bn, seed)(dnn_input) dnn_logit = tf.keras.layers.Dense( 1, use_bias=False, kernel_initializer=tf.keras.initializers.glorot_normal(seed=seed))(dnn_output) final_logit = add_func([linear_logit, fm_logit, dnn_logit]) output = PredictionLayer(task)(final_logit) model = tf.keras.models.Model(inputs=inputs_list, outputs=output) feature_names = get_feature_names(linear_feature_columns + dnn_feature_columns) # 3.generate input data for model train, test = train_test_split(data, test_size=0.2, random_state=2020) train_model_input = {name:train[name] for name in feature_names} test_model_input = {name:test[name] for name in feature_names} # 4.Define Model,train,predict and evaluate model = DeepFM(linear_feature_columns, dnn_feature_columns, task='binary') model.compile("adam", "binary_crossentropy", metrics=['binary_crossentropy'], ) history = model.fit(train_model_input, train[target].values, batch_size=256, epochs=10, verbose=2, validation_split=0.2, ) pred_ans = model.predict(test_model_input, batch_size=256) print("test LogLoss", round(log_loss(test[target].values, pred_ans), 4)) print("test AUC", round(roc_auc_score(test[target].values, pred_ans), 4))
l.backward() optimizer.step() train_l_sum += l.item() train_acc_sum += (outputs.argmax(dim=1) == y).sum().item() n += y.shape[0] print('epoch %d loss %f train acc %f' % (epoch + 1, train_l_sum / n, train_acc_sum / n)) if __name__ == '__main__': device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') raw_data, cat_cols, num_cols = load_data() train_data = preprocess_data(raw_data, cat_cols, num_cols) # train_data['label'] = raw_data['label'] train_data['label'] = raw_data['Label'] cat_tuple_list = get_cat_tuple_list(train_data, cat_cols) X = torch.tensor(train_data.drop(['label'], axis=1).values, dtype=torch.float) y = torch.tensor(train_data.label.values, dtype=torch.long) dataset = Data.TensorDataset(X, y) data_iter = Data.DataLoader(dataset=dataset, batch_size=128, shuffle=True) model = DeepFM(num_cols, cat_cols, cat_tuple_list) # print(model) loss = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=0.001) # print(model) train(model, data_iter, device, optimizer, loss, epochs=100)