2016-06-16 34 views
5

Ho un dizionario con le chiavi come user_ids e valori come elenco di movie_ids piaciuto da quell'utente con #unique_users = 573000 e # unique_movies = 16000.convert dizionario in sparse matrix

{1: [51, 379, 552, 2333, 2335, 4089, 4484], 2: [51, 379, 552, 1674, 1688, 2333, 3650, 4089, 4296, 4484], 5: [783, 909, 1052, 1138, 1147, 2676], 7: [171, 321, 959], 9: [3193], 10: [959], 11: [131,567,897,923],..........}

Ora voglio convertire questo in in una matrice con righe come user_ids e colonne come movies_id con i valori 1 per i film che l'utente ha voluto vale a dire che sarà 573000 * 16000

definitiva devo moltiplica questa matrice con la sua trasposizione per avere una matrice di co-occorrenza con dim (# unique_movies, # unique_movies).

Inoltre, quale sarà la complessità temporale dell'operazione X '* X in cui X è come (500000,12000).

risposta

1

Penso che sia possibile costruire uno dok_matrix vuoto e riempire i valori. Quindi trasporre e convertire in csr_matrix per moltiplicazioni di matrice efficienti.

import numpy as np 
import scipy.sparse as sp 
d = {1: [51, 379, 552, 2333, 2335, 4089, 4484], 2: [51, 379, 552, 1674, 1688, 2333, 3650, 4089, 4296, 4484], 5: [783, 909, 1052, 1138, 1147, 2676], 7: [171, 321, 959], 9: [3193], 10: [959], 11: [131,567,897,923]} 

mat = sp.dok_matrix((573000,16000), dtype=np.int8) 

for user_id, movie_ids in d.items(): 
    mat[user_id, movie_ids] = 1 

mat = mat.transpose().tocsr() 
print mat.shape 
+0

ma poi per ciclo sarà di 57300 iterazioni in quanto è il numero di utenti distinti nel dizionario –

+0

@chiragyadav Penso che dovrebbe essere efficiente perché hai già indicizzato i tuoi dati nel dizionario e dok_matrix è efficiente per la costruzione matrice in modo incrementale. –

+0

'importazione scipy.sparse come sp mat = sp.dok_matrix ((576808,11287), DTYPE = np.int8) per UID, brand_list in user_pref_dict.items(): mat [uid, brand_list] = 1' provato il codice sopra ma gettando l'errore sotto: indice (131) fuori range -11287 a 11286) –

2
df = {1: [51, 379, 552, 2333, 2335, 4089, 4484], 2: [51, 379, 552, 1674, 1688, 2333, 3650, 4089, 4296, 4484], 5: [783, 909, 1052, 1138, 1147, 2676], 7: [171, 321, 959], 9: [3193], 10: [959], 11: [131,567,897,923],..........} 
df2 = pd.DataFrame.from_dict(df, orient='index') 
df2 = df2.stack().reset_index() 
df2.level_1=1 
df2.pivot(index='level_0',columns=0,values='level_1').fillna(0) 

Questo converte il dict in un dataframe, seguita impilando per ottenere userids e movieIDs in colonne separate, quindi tutti i valori della colonna level_1 inutilizzata è impostato a 1. Ultima dichiarazione crea un ripieno tabella pivot combinazioni inesistenti con zeri.

0

È possibile creare csr_matrix in una volta (come questo formato: csr_matrix((data, (row_ind, col_ind))). Ecco un frammento su come farlo.

import scipy.sparse as sp 
d = {0: [0,1], 1: [1,2,3], 
    2: [3,4,5], 3: [4,5,6], 
    4: [5,6,7], 5: [7], 
    6: [7,8,9]} 
row_ind = [k for k, v in d.items() for _ in range(len(v))] 
col_ind = [i for ids in d.values() for i in ids] 
X = sp.csr_matrix(([1]*len(row_ind), (row_ind, col_ind))) # sparse csr matrix 

È possibile utilizzare matrice X per trovare matrice di co-occorrenza successiva (cioè X.T * X) (credito github @ daniel-Acuna). Immagino che ci sia un modo più veloce per convertire il dizionario della lista in row_ind, col_ind.