1
votes

Goal is to identify top 10 similar rows for each row in dataframe.

I start with following dictionary:

import pandas as pd
import numpy as np
from scipy.spatial.distance import cosine

d = {'0001': [('skiing',0.789),('snow',0.65),('winter',0.56)],'0002': [('drama', 0.89),('comedy', 0.678),('action',-0.42) ('winter',-0.12),('kids',0.12)],'0003': [('action', 0.89),('funny', 0.58),('sports',0.12)],'0004': [('dark', 0.89),('Mystery', 0.678),('crime',0.12), ('adult',-0.423)],'0005': [('cartoon', -0.89),('comedy', 0.678),('action',0.12)],'0006': [('drama', -0.49),('funny', 0.378),('Suspense',0.12), ('Thriller',0.78)],'0007': [('dark', 0.79),('Mystery', 0.88),('crime',0.32), ('adult',-0.423)]}

To put it in dataframe I do following:

col_headers = []
entities = []
for key, scores in d.iteritems():
    entities.append(key)
    d[key] = dict(scores)
    col_headers.extend(d[key].keys())
col_headers = list(set(col_headers))

populate the dataframe:

df = pd.DataFrame(columns=col_headers, index=entities)
for k in d:
    df.loc[k] = pd.Series(d[k])
df.fillna(0.0, axis=1)

One of the issue in addition to my main goal that I have at this point of the code is my dataframe still has NaN. This probably why my result matrix is filled with NaNs.

     Mystery drama  kids winter  funny  snow crime  dark sports Suspense  adult skiing action comedy cartoon Thriller
0004   0.678   NaN   NaN    NaN    NaN   NaN  0.12  0.89    NaN      NaN -0.423    NaN    NaN    NaN     NaN      NaN
0005     NaN   NaN   NaN    NaN    NaN   NaN   NaN   NaN    NaN      NaN    NaN    NaN   0.12  0.678   -0.89      NaN
0006     NaN -0.49   NaN    NaN  0.378   NaN   NaN   NaN    NaN     0.12    NaN    NaN    NaN    NaN     NaN     0.78
0007    0.88   NaN   NaN    NaN    NaN   NaN  0.32  0.79    NaN      NaN -0.423    NaN    NaN    NaN     NaN      NaN
0001     NaN   NaN   NaN   0.56    NaN  0.65   NaN   NaN    NaN      NaN    NaN  0.789    NaN    NaN     NaN      NaN
0002     NaN  0.89  0.12  -0.12    NaN   NaN   NaN   NaN    NaN      NaN    NaN    NaN  -0.42  0.678     NaN      NaN
0003     NaN   NaN   NaN    NaN   0.58   NaN   NaN   NaN   0.12      NaN    NaN    NaN   0.89    NaN     NaN      NaN

To calculate cosine similarity and generate the similarity matrix between rows I do following:

data = df.values
m, k = data.shape

mat = np.zeros((m, m))

for i in xrange(m):
    for j in xrange(m):
        if i != j:
            mat[i][j] = cosine(data[i,:], data[j,:])
        else:
            mat[i][j] = 0.

here is how mat looks like:

[[  0.  nan  nan  nan  nan  nan  nan]
 [ nan   0.  nan  nan  nan  nan  nan]
 [ nan  nan   0.  nan  nan  nan  nan]
 [ nan  nan  nan   0.  nan  nan  nan]
 [ nan  nan  nan  nan   0.  nan  nan]
 [ nan  nan  nan  nan  nan   0.  nan]
 [ nan  nan  nan  nan  nan  nan   0.]]

Assuming NaN issue get fix and mat spits out meaning full similarity matrix. How can I get an output as follows:

{0001:[003,005,002],0002:[0001, 0004, 0007]....}
1

1 Answers

3
votes

One of the issue in addition to my main goal that I have at this point of the code is my dataframe still has NaN.

That's beacause df.fillna does not modify DataFrame, but returns a new one. Fix it and your result will be fine.