List of keywords as features
Sure, of course we can use TF-IDF or bag of words. The easiest way is to build a separate TFIDF transformer for every group of keywords and then combine them together using FeatureUnion. Just make sure the custom tokenizer only filters out the keywords in each group that you're looking at. 

from sklearn.pipeline import Pipeline, FeatureUnion
from sklearn.feature_extraction.text import TfidfVectorizer

corpus = [
    "china factory activity shrinks some text here",
    "first time some text here",
    "2 years some text here",
    "combining first time and 2 years here.",
    "adding china factory activity first but doesn't match exactly"
]

# custom tokenizers

keywords1 = lambda x: [x for x in x.split() if x in ["china", "factory", "activity", "shrinks"]]
keywords2 = lambda x: [x for x in x.split() if x in ["first", "time"]]
keywords3 = lambda x: [x for x in x.split() if x in ["2", "years"]]

combined_features = FeatureUnion([
    ('kwd1', TfidfVectorizer(tokenizer=keywords1)),
    ('kwd2', TfidfVectorizer(tokenizer=keywords2)),
    ('kwd3', TfidfVectorizer(tokenizer=keywords3))
])

pipeline = Pipeline([('bow', combined_features)])
output_corpus = pipeline.fit_transform(corpus)


For the deep-learning approach, I would recommend a similar kind of pattern so that the embedding learned from each group would have a different semantic meaning from another group. You'll just need to ensure that the tokenizer only considers the keywords from each group when it is processed. If you're using a pre-build word embedding; you'll just have a filter before it goes into each embedding so that it doesn't "leak" into another topic.

Example using Keras:

from keras import layers
from keras.models import Model
from keras.preprocessing.sequence import pad_sequences

def custom_sequence_tokenizer(txt, vocab):
    vocab_mapper = dict([(word, idx+1) for idx, word in enumerate(vocab)])
    text_split = [vocab_mapper.get(x, 0) for x in txt.split() if x in vocab]
    return text_split

keywords1 = pad_sequences([custom_sequence_tokenizer(x, ["china", "factory", "activity", "shrinks"]) for x in corpus], padding='post', maxlen=10)
keywords2 = pad_sequences([custom_sequence_tokenizer(x, ["first", "time"]) for x in corpus], padding='post', maxlen=10)
keywords3 = pad_sequences([custom_sequence_tokenizer(x, ["2", "years"]) for x in corpus], padding='post', maxlen=10)

input_count1 = layers.Input(shape=(10,), name='in1')
input_count2 = layers.Input(shape=(10,), name='in2')
input_count3 = layers.Input(shape=(10,), name='in3')

# input size is reflection of the vocab size
embed1 = layers.Embedding(5, 8)(input_count1)
embed2 = layers.Embedding(3, 8)(input_count2)
embed3 = layers.Embedding(3, 8)(input_count3)

combine = layers.Concatenate()([embed1, embed2, embed3])

model = Model(inputs=[input_count1, input_count2, input_count3], outputs=combine)
output = model.predict({
    'in1': keywords1,
    'in2': keywords2,
    'in3': keywords3,
})