You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

utils.py 4.1 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import os
  2. import pickle
  3. import random
  4. from itertools import combinations
  5. import numpy as np
  6. import pandas as pd
  7. from lightgbm import LGBMClassifier, Booster
  8. from sklearn.feature_extraction.text import TfidfVectorizer
  9. from sklearn.model_selection import train_test_split, StratifiedShuffleSplit
  10. from sklearn.naive_bayes import MultinomialNB
  11. from sklearn.metrics import accuracy_score, f1_score
  12. super_classes = ["comp", "rec", "sci", "talk", "misc"]
  13. super_classes_select2 = list(combinations(super_classes, 2))
  14. super_classes_select3 = list(combinations(super_classes, 3))
  15. class TextDataLoader:
  16. def __init__(self, data_root, train: bool = True):
  17. self.data_root = data_root
  18. self.train = train
  19. def get_idx_data(self, idx=0):
  20. if self.train:
  21. X_path = os.path.join(self.data_root, "uploader", "uploader_%d_X.pkl" % (idx))
  22. y_path = os.path.join(self.data_root, "uploader", "uploader_%d_y.pkl" % (idx))
  23. if not (os.path.exists(X_path) and os.path.exists(y_path)):
  24. raise Exception("Index Error")
  25. with open(X_path, "rb") as f:
  26. X = pickle.load(f)
  27. with open(y_path, "rb") as f:
  28. y = pickle.load(f)
  29. else:
  30. X_path = os.path.join(self.data_root, "user", "user_%d_X.pkl" % (idx))
  31. y_path = os.path.join(self.data_root, "user", "user_%d_y.pkl" % (idx))
  32. if not (os.path.exists(X_path) and os.path.exists(y_path)):
  33. raise Exception("Index Error")
  34. with open(X_path, "rb") as f:
  35. X = pickle.load(f)
  36. with open(y_path, "rb") as f:
  37. y = pickle.load(f)
  38. return X, y
  39. def generate_uploader(data_x, data_y, n_uploaders=50, n_samples=5, data_save_root=None):
  40. if data_save_root is None:
  41. return
  42. os.makedirs(data_save_root, exist_ok=True)
  43. for i, labels in enumerate(super_classes_select3[:n_uploaders // n_samples]):
  44. indices = [idx for idx, label in enumerate(data_y) if label.split('.')[0] in labels]
  45. for j in range(n_samples):
  46. # sample 50% data to selected_X and selected_y
  47. selected_indices = random.sample(indices, len(indices) // 2)
  48. selected_X = data_x[selected_indices]
  49. selected_y = data_y[selected_indices].codes
  50. X_save_dir = os.path.join(data_save_root, "uploader_%d_X.pkl" % (i * n_samples + j))
  51. y_save_dir = os.path.join(data_save_root, "uploader_%d_y.pkl" % (i * n_samples + j))
  52. with open(X_save_dir, "wb") as f:
  53. pickle.dump(selected_X, f)
  54. with open(y_save_dir, "wb") as f:
  55. pickle.dump(selected_y, f)
  56. print("Saving to %s" % (X_save_dir))
  57. def generate_user(data_x, data_y, n_users=50, data_save_root=None):
  58. if data_save_root is None:
  59. return
  60. os.makedirs(data_save_root, exist_ok=True)
  61. for i, labels in enumerate(super_classes_select2[:n_users]):
  62. indices = [idx for idx, label in enumerate(data_y) if label.split('.')[0] in labels]
  63. selected_X = data_x[indices]
  64. selected_y = data_y[indices].codes
  65. X_save_dir = os.path.join(data_save_root, "user_%d_X.pkl" % (i))
  66. y_save_dir = os.path.join(data_save_root, "user_%d_y.pkl" % (i))
  67. with open(X_save_dir, "wb") as f:
  68. pickle.dump(selected_X, f)
  69. with open(y_save_dir, "wb") as f:
  70. pickle.dump(selected_y, f)
  71. print("Saving to %s" % (X_save_dir))
  72. # Train Uploaders' models
  73. def train(X, y, out_classes):
  74. vectorizer = TfidfVectorizer(stop_words="english")
  75. X_tfidf = vectorizer.fit_transform(X)
  76. clf = MultinomialNB(alpha=0.1)
  77. clf.fit(X_tfidf, y)
  78. return vectorizer, clf
  79. def eval_prediction(pred_y, target_y):
  80. if not isinstance(pred_y, np.ndarray):
  81. pred_y = pred_y.detach().cpu().numpy()
  82. if len(pred_y.shape) == 1:
  83. predicted = np.array(pred_y)
  84. else:
  85. predicted = np.argmax(pred_y, 1)
  86. annos = np.array(target_y)
  87. total = predicted.shape[0]
  88. correct = (predicted == annos).sum().item()
  89. return correct / total