# Multi-label classification model in python?

Assume you have the following artificial dataset

import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(100, 4), columns=list('ABCD'))
df['sex']  = [np.random.choice(['male', 'female']) for x in range(len(df))]
df['weight'] = [np.random.choice(['underweight',
'normal', 'overweight', 'obese']) for x in range(len(df)) ]


This produce the following artificial dataset

df.head()
Out[50]:
A         B         C         D     sex       weight
0  0.955136  0.802256  0.317182 -0.708615  female       normal
1  0.463615 -0.860053 -0.136408 -0.892888    male        obese
2 -0.855532 -0.181905 -1.175605  1.396793  female   overweight
3 -1.236216 -1.329982  0.531241  2.064822    male  underweight
4 -0.970420 -0.481791 -0.995313  0.672131    male        obese


I am trying to know both the sex and the weigh based on the value of the features A,B,C,D. I learned that this a multi-label classification problem and there is a nice python library that should help (e.g. scikit-multilearn ). However I do not know how this is achieved. Can someone show me how I could train a model and test its accuracy on this artificial dataset? Specifically: 1. Assuming that A,B,C,D are the feature and sex and weight are the label, how to create a test and training sets? The following will not work

X=df[list('ABCD')]
y=[['sex','weight']]
X_train, X_test, y_train, y_test = train_test_split(X, y)

1. How to you train and test the model?
• I am not sure how that library works, but check this: depends-on-the-definition.com/…. I have created a NN following this blog instruction for multi-label classification and worked just fine. Let me know if you still have problem or confused. Oct 28, 2018 at 7:15
• @MajidMortazavi thanks. I will take a look at the library Oct 28, 2018 at 7:16

First of all you would need to encode your target columns.We can use sklearn.preprocessing.MultiLabelBinarizer here:

from sklearn.preprocessing import MultiLabelBinarizer
mlb = MultiLabelBinarizer()

X=df[list('ABCD')]
Y=pd.DataFrame(mlb.fit_transform(df[['sex','weight']].values), columns=mlb.classes_, index=df.index)


yields:

In [75]: Y
Out[75]:
female  male  normal  obese  overweight  underweight
0        1     0       0      1           0            0
1        1     0       0      0           0            1
2        1     0       1      0           0            0
3        1     0       1      0           0            0
4        1     0       0      0           0            1
5        1     0       1      0           0            0
6        0     1       0      0           0            1
7        1     0       1      0           0            0
8        0     1       0      0           0            1
9        0     1       0      0           0            1
..     ...   ...     ...    ...         ...          ...
90       1     0       0      1           0            0
91       0     1       0      0           0            1
92       1     0       0      0           0            1
93       1     0       0      0           1            0
94       1     0       1      0           0            0
95       1     0       0      0           0            1
96       0     1       0      0           0            1
97       0     1       0      0           1            0
98       1     0       0      0           1            0
99       1     0       1      0           0            0

[100 rows x 6 columns]


Example:

from sklearn.neighbors import KNeighborsClassifier

knc = KNeighborsClassifier()

X_train, X_test, Y_train, Y_test = train_test_split(X, Y)

knc.fit(X_train, Y_train)
Y_pred = knc.predict(X_test)


One option is to combine the labels into a single column with a larger number of classes from the combinations of the original columns. Something of the form y = [0, 1, 2, 3, 4, 5, 6, 7, 8], where:

0 = female, underweight
1 = female, normal
2 = female, overweight
...
7 = male, overweight
8 = male, obese


This will give you a single column (pd.Series) for y. You can use train_test_split as you have in the question.

• Thanks for your suggestion. I was looking for something more elegant but this is a good starting point Oct 28, 2018 at 10:12
• Indeed! I would only have offered it as a comment for that reason, but I don't have sufficient reputation to do so yet. That said, whenever I've done multi-classification models I've used the above approach – its not pretty but it works and it's fast. Oct 28, 2018 at 10:22