Разделить разреженную матрицу на обучающую и тестовую

#python #sparse-matrix

#python #разреженная матрица

Вопрос:

Привет, у меня есть разреженная матрица csr, построенная таким образом:

 userid = list(np.sort(matrix.USERID.unique()))  # Get our unique customers
artid = list(matrix.ARTID.unique())  # Get our unique products that were purchased
click = list(matrix.TOTALCLICK)

rows = pd.Categorical(matrix.USERID, categories=userid).codes

# Get the associated row indices
cols = pd.Categorical(matrix.ARTID, categories=artid).codes

# Get the associated column indices
item_sparse = sparse.csr_matrix((click, (rows, cols)), shape=(len(userid), len(artid)))
  

Оригинал matrix содержит взаимодействие пользователя с продуктом на веб-сайте.

В итоге я получаю разреженную матрицу в этом формате

   (0, 4136) 1
  (0, 5553) 1
  (0, 9089) 1
  (0, 24104) 3
  (0, 28061) 2
  (1, 0)    2
  (1, 224)  1
  (1, 226)  1
  (1, 324)  2
  (1, 341)  1
  (1, 530)  1
  (1, 642)  1
  (1, 658)  1
  

Как я могу сгруппировать по этой разреженной матрице по первому индексу (пользователи) и взять, скажем, первые 80% строк для обучающего набора, а остальные 20% для тестового набора. В итоге у меня должно получиться две матрицы

Обучение:

   (0, 4136) 1
  (0, 5553) 1
  (0, 9089) 1
  (1, 0)    2
  (1, 224)  1
  (1, 226)  1
  (1, 324)  2
  (1, 341)  1
  (1, 530)  1
  

тест:

   (0, 24104)    3
  (0, 28061)    2
  (1, 642)      1
  (1, 658)      1
  

Ответ №1:

Вы можете использовать StratifiedShuffleSplit (или альтернативно StratifiedKFold , если вы не хотите перетасовки, но вам нужно будет выполнить 5 разбиений, чтобы получить разделение 80% / 20% на обучающую / тестовую, поскольку вы не можете контролировать размер теста другими способами.) класс в scikit-learn:

 import sklearn.model_selection
import numpy as np

# Array similar to your structure
x = np.asarray([[0,4136,1],[0,5553,1],[0,9089,1],[1,0,2], 
                [1,224,1],[1,226,1],[1,324,2],[1,341,1],[1,530,1]])
# Get train and test indices using x[:,0] to define the 'classes'
cv = sklearn.model_selection.StratifiedShuffleSplit(n_splits=1, test_size=0.2)
# Note, X isn't actually used in the method, np.zeros(n_samples) would also work
# Also note that cv.split is an iterator with 1 element (split), 
# hence getting the first element of the list
train_idx, test_idx = list(cv.split(X=x, y=x[:,0]))[0]

print("Training")
for i in train_idx:
    print(x[i,:2], x[i,2])
print("Test")
for i in test_idx: 
    print(x[i,:2], x[i,2])
  

У меня нет большого опыта работы с разреженными матрицами, поэтому я надеюсь, что вы сможете внести необходимые коррективы из моего примера.

Комментарии:

1. Вы преобразуете разреженную матрицу в плотную, если кто-то использует разреженную матрицу из-за ограничений памяти. Я не чувствую, что это отвечает на вопрос.

Ответ №2:

используйте sklearn api train_test_split, вы зададите этому методу 3 параметра вашей матрицы: соотношение расщепления и случайное состояние. случайное состояние очень полезно, если вы хотите снова разделить с тем же результатом.