# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: scale
#     language: python
#     name: scale
# ---

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.layers import Dense, DenseFeatures, Lambda, Add, Dot, Activation, Layer
from tensorflow.keras import Model
from tensorflow.keras.initializers import GlorotNormal
from Layer_FM import Layer_FM
import numpy as np

from utils.conf_process import myconfigparser
from utils.feature_process import tuple_feature_process
from utils.active_method import activate
from utils.optimizer_method import get_optimizer
from utils.distribut_conf import set_dist_env

EMBEDDING_SIZE = 8
HIDDEN_UNITS = [32, 8]
BATCH_SIZE = 4


def build_model_columns(conf_path):

    deep_columns = list()
    sparse_cols = []
    dense_cols = []

    sparse_col_names = []
    dense_col_names = []

    default_dict = {}
    embedding_nums = 0

    cfg = myconfigparser()
    cfg.read(conf_path)
    sections = cfg.sections()

    for part_key in sections:

        items_lst = cfg.items(part_key)

        if part_key == "deep":
            for items in items_lst:
                feature_name = items[0].strip()
                feature_col,default_val,embedding_num = tuple_feature_process(items,int(EMBEDDING_SIZE))
                embedding_nums += embedding_num
                if feature_name not in default_dict:
                    default_dict[feature_name] = default_val
                deep_columns.append(feature_col)
                # if isinstance(feature_col, tf.feature_column.indicator_column):
                #     sparse_cols.append(feature_col)
                #     sparse_col_names.append(feature_name)
                # else:
                #     dense_cols.append(feature_col)
                #     dense_col_names.append(feature_name)

    #获取所有特征列(cfg取出的格式为[(特征名，具体值)])
    columns = cfg.items("use")[0][1].strip().split(",")
    sparse_cols_names = cfg.items("sparse_feature")[0][1].strip().split(",")
    numeric_cols_names = cfg.items("numeric_feature")[0][1].strip().split(",")
    default_dict["label"] = 0
    cols_default = list(map(lambda x:["-1"] if x not in default_dict else [default_dict[x]], columns))
    return deep_columns, columns, cols_default,embedding_nums, sparse_cols_names, numeric_cols_names


deep_columns, columns, cols_default, embedding_num, sparse_cols_names, numeric_cols_names = build_model_columns('data/feature_engineering.conf')

# ## Split sparse and numeric feature columns

# +

sparse_feature_cols = filter(lambda col: col.name.split('_indicator')[0] in sparse_cols_names, deep_columns)
numeric_feature_cols = filter(lambda col: col.name in numeric_cols_names, deep_columns)
sparse_feature_cols = list(sparse_feature_cols)
numeric_feature_cols = list(numeric_feature_cols)
print(sparse_feature_cols)
print(numeric_feature_cols)
# -

# ## Generate dataset from csv

LABEL_COLUMN = 'label'
def get_dataset(file_path, **kwargs):
  dataset = tf.data.experimental.make_csv_dataset(
      file_path,
      batch_size=5, # Artificially small to make examples easier to show.
      label_name=LABEL_COLUMN,
      na_value="?",
      num_epochs=1,
      ignore_errors=True,
      **kwargs)
  return dataset


raw_train_data = get_dataset('data/train.data.csv', column_names=columns)


def show_batch(dataset):
  
  for batch, label in dataset.take(1):
    for key, value in batch.items():
      print("{:20s}: {}".format(key,value.numpy()))


show_batch(raw_train_data)

sparse_train_data = get_dataset('data/train.data.csv', column_names=columns,select_columns=sparse_cols_names.copy()) # use copy to avoid make_csv_dataset changes the select_columns from str list to index list
numeric_train_data = get_dataset('data/train.data.csv', column_names=columns,select_columns=numeric_cols_names.copy())
show_batch(sparse_train_data)
print()
show_batch(numeric_train_data)

# ## 

sp_feature_names = sparse_cols_names.copy()
sp_feature_names.remove('label')
sp_feature_names

num_feature_names = numeric_cols_names.copy()
num_feature_names.remove('label')
num_feature_names

sparse_train_batch, labels_batch = next(iter(sparse_train_data))

sparse_train_batch

# ## Customize FM layer



# ## Generate Inputs Layer

sp_features_len = len(sp_feature_names)
num_features_len = len(num_feature_names)
print(sp_features_len)
print(num_features_len)

sparse_inputs = {
    colname : tf.keras.layers.Input(shape=(), name=colname, dtype=tf.string, sparse=True) for colname in sp_feature_names
}
numeric_inputs = {
    colname : tf.keras.layers.Input(shape=(), name=colname, dtype='float32', sparse=False) for colname in num_feature_names
}
print(sparse_inputs)
print(numeric_inputs)

# ## Model Definition

# +
sp_dense = DenseFeatures(sparse_feature_cols, name='sparse_input_layer')(sparse_inputs)
num_dense = DenseFeatures(numeric_feature_cols, name='numeric_input_layer')(numeric_inputs)

#---linear---
both = tf.keras.layers.concatenate([sp_dense, num_dense], name='both')
first_order = Dense(1, input_shape=both.shape, name='first_order')(both)

#---fm---
fm_inputs = {'sparse': sp_dense, 'numeric': num_dense}
second_order, v_em = Layer_FM(sp_features_len, num_features_len, EMBEDDING_SIZE, name='FM')(fm_inputs)

# ---deep---
field_size = sp_features_len + num_features_len
deep_inputs = tf.reshape(v_em, shape=(-1, field_size*EMBEDDING_SIZE))
for layer_id, num_hidden_units in enumerate(HIDDEN_UNITS):
    layer_name = 'deep_%d'%(layer_id)
    deep_inputs = Dense(num_hidden_units, activation='relu', kernel_initializer=GlorotNormal(), name=layer_name)(deep_inputs)
y_deep = Dense(1, activation='relu', kernel_regularizer=tf.keras.regularizers.l2)(deep_inputs)

outputs = first_order+second_order+y_deep

outputs = Activation('sigmoid')(outputs)
model = Model([sparse_inputs, numeric_inputs], outputs)

# -

model.summary()

from tensorflow.keras.utils import plot_model
plot_model(model, to_file='model.png')



StarcoderdataJupyterScriptsDedupFiltered