Machine Learning for user modelling
What you have is a classification problem. Given a user and their features, pick the best content for him.

There are many classifiers that are for this task. I would say that your main problem is that most of your features are categorical and not numerical.

Data preparation

With Sklearn for example, you can use LabelEncoder to transform categorical to numerical.

Below is an example of how to do this. You generate X, which is your features matrix. Each row is a user and the columns are the features.

Here are some dummy users I created. You data structure might be different, so you can try to make it like this, or do some more work on it.

users = [
    {
        'id': 1,
        'nationality': 'american',
        'company': 'xyz',
        'role': 'ceo',
        'content.id': 1001
    },
    {
        'id': 2,
        'nationality': 'american',
        'company': 'abc',
        'role': 'cto',
        'content.id': 1002
    },
    {
        'id': 3,
        'nationality': 'canadian',
        'company': 'fgh',
        'role': 'cto',
        'content.id': 1001
    }
]


Now, you can encode your categories. This means that for every word in your data, you assign a number to it. The LabelEncoder can do this for you. With this, you generate X, which is your feature matrix, where every row represents a user.

from sklearn.preprocessing import LabelEncoder

nationality_encoder = LabelEncoder().fit([user['nationality'] for user in users])
company_encoder = LabelEncoder().fit([user['company'] for user in users])
role_encoder = LabelEncoder().fit([user['role'] for user in users])

X = []
for user in users:
    X.append([
        nationality_encoder.transform([user['nationality']])[0],
        company_encoder.transform([user['company']])[0],
        role_encoder.transform([user['role']])[0]
    ])
print(X)
&gt;&gt; [[0, 2, 0], 
&gt;&gt;  [0, 0, 1],
&gt;&gt;  [1, 1, 1]]


Then you can generate y, which are your labels. The content.id of each user. Here I assume you have the user-content pairs like you said you did. This vector has the same length as X. Each row of X is associate to the ordered values in y. So the user in X[2] has the content.id in y[2].

y = [user['content.id'] for user in users]
print(y)
&gt;&gt; [1001, 1002, 1001]


Classifier

Now you have your X and y, your features and labels.

Not all classifier will perform well with categorical data, but I would suggest you start with a DecisionTreeClassifier.

Here is an example:

from sklearn.tree import DecisionTreeClassifier

decision_tree = DecisionTreeClassifier()
decision_tree.fit(X, y)


New predictions

Now that you have a trained tree, you can predict the content.id for users that do not have it.

Suppose you have this new user:

new_user = {
        'id': 999,
        'nationality': 'american',
        'company': 'fgh',
        'role': 'ceo'
    }


You can apply the same transformation to get the X for him. However, now you do not know y, which is what you are trying to find out.

new_user_X = [[
    nationality_encoder.transform([new_user['nationality']])[0],
    company_encoder.transform([new_user['company']])[0],
    role_encoder.transform([new_user['role']])[0]
]]


Use the decision_tree you created to make a prediction. In this dummy example, the new_user should have content.id == 1.

new_user_content = decision_tree.predict(new_user_X)
print(new_user_content)
&gt;&gt; [1]