0
$\begingroup$

I'm working on a deep learning model in TensorFlow to predict if two records within a database refer to the same person. I'm trying to use text features (in the form of embeddings) and numeric features together, but am struggling to combine these features together as their shapes differ. The model takes the following as inputs (one for each record):

  1. First Name
  2. Last Name
  3. House Number
  4. Street
  5. City
  6. State
  7. NumericVar1 (always a whole, positive number like age)
  8. NumericVar2 (always a whole, positive number like age)
  9. NumericVar3 (always a whole, positive number like age)

Variables 1-6 are represented by their embeddings from the FastText model (an array of length 300) and variables 7-9 are whole positive numbers that are attributes for each record.

Each record has these attributes, so there are really 18 inputs to the model, though I keep them split by source (db1 and db2). The output is binary (0=Unmatched/1=Matched), indicating that the records are the same person.

I'd like to take both text embeddings and numeric inputs and use that to make a prediction if the record pairs refer to the same person.

I built a model that took in four inputs:

  1. db1_num_inputs: The numeric inputs from record 1. Size=(3,1)
  2. db1_embedded_inputs: The embedded text for record 1. Size=(6,300)
  3. db2_num_inputs: The numeric inputs from record 2. Size=(3,1)
  4. db2_embedded_inputs: The embedded text for record 2. Size=(6,300)

To handle the differing input sizes, I applied a Dense layer after each input and then concatenated these Dense layers. I'm concerned this is not optimal. I've noticed that if I train with just embeddings, the model performs better than if I add the numeric information.

Is there a more efficient or recommended approach to combine text embeddings and numeric features with differing dimensions for tasks like duplicate detection?

I can't share the data or code, but I wrote the following snippet, which is representative of what I'm trying to do.

##################
## Libraries
##################

import tensorflow as tf
import numpy as np

##################
## Prepare Data
##################

"""
Each record has the following attributes:
1. First Name
2. Last Name
3. House Number
4. Street
5. City
6. State
7. ZIP
8. NumericVar1
9. NumericVar2
10. NumeriVar3

For 1-6, values are embedded into arrays of length 300 and stored in an array

For 8-10, values are stored in a separate array
"""

N = 3000
shape = (6, 300)

# Set seed
np.random.seed(1)

# Generate db1 "embeddings"

db1_embeddings = np.random.rand(N, *shape)

# Generate db1 numerical data
db1_numeric = np.random.randint(1, 10, size=(N, 3))

# Generate db2 "embeddings"
db2_embeddings = np.random.rand(N, *shape)

# Generate db2 numerical data
db2_numeric = np.random.randint(1, 10, size=(N, 3))

# Generate Y data (0=Unmatched, 1=Matched)
Y = np.random.randint(0, 2, size=N)

##################
## DNN
##################

# db1 numeric inputs
db1_num_inputs = tf.keras.layers.Input(shape=(3, 1))
db1_num_inputs_processed = tf.keras.layers.Dense(units=100, activation="relu")(
    db1_num_inputs
)

# db1 embedded inputs
db1_embedded_inputs = tf.keras.layers.Input(shape=(6, 300))
db1_embedded_inputs_processed = tf.keras.layers.Dense(units=100, activation="relu")(
    db1_embedded_inputs
)

# db2 numeric inputs
db2_num_inputs = tf.keras.layers.Input(shape=(3, 1))
db2_num_inputs_processed = tf.keras.layers.Dense(units=100, activation="relu")(
    db2_num_inputs
)

# db2 embedded inputs
db2_embedded_inputs = tf.keras.layers.Input(shape=(6, 300))
db2_embedded_inputs_processed = tf.keras.layers.Dense(units=100, activation="relu")(
    db2_embedded_inputs
)

# Combine inputs
combined = tf.keras.layers.concatenate(
    [
        db1_num_inputs_processed,
        db1_embedded_inputs_processed,
        db2_num_inputs_processed,
        db2_embedded_inputs_processed,
    ],
    axis=1,
)

# Flatten
flatten = tf.keras.layers.Flatten()(combined)

hidden1 = tf.keras.layers.Dense(units=100, activation="relu")(flatten)
hidden2 = tf.keras.layers.Dense(units=100, activation="relu")(hidden1)
outputs = tf.keras.layers.Dense(units=1, activation="sigmoid")(hidden2)

# Build model
model = tf.keras.Model(
    inputs=[
        db1_num_inputs,
        db1_embedded_inputs,
        db2_num_inputs,
        db2_embedded_inputs,
    ],
    outputs=outputs,
)

# Compile
model.compile(
    optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
    loss="binary_crossentropy",
    metrics=["accuracy"],
)

# Train
model.fit(
    x=[db1_numeric, db1_embeddings, db2_numeric, db2_embeddings],
    y=Y,
    batch_size=10,
    epochs=5,
)
```
$\endgroup$

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.