History of deezer_friends
The changes to the source code of this entry in the repository, newest first, each with the differences it made to the entry's files. They are also listed on GitLab.
[entries] New entry: deezer_friends 673ca33
diff --git a/entries/deezer_friends/__init__.py b/entries/deezer_friends/__init__.py
new file mode 100644
index 0000000..026abdb
--- /dev/null
+++ b/entries/deezer_friends/__init__.py
@@ -0,0 +1,88 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2020-2026 Tiago de Paula Peixoto <tiago@skewed.de>
+#
+# This program is free software: you can redistribute it and/or modify it under
+# the terms of the GNU Affero General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Affero General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+from .. import *
+
+import csv
+import json
+
+title = "Deezer user friendships (2017, 2020)"
+description = r"""Social networks of users of the music streaming service Deezer, collected from its public API by B. Rozemberczki and collaborators for benchmarks of node embedding and classification methods. Nodes are users, and an undirected edge connects two users who are friends (follow each other). The users were reindexed for anonymity. There are two data sets:
+
+- GEMSEC (collected in November 2017): three networks of users from Croatia (`HR`), Hungary (`HU`) and Romania (`RO`). Each user has the list of music genres they like, compiled by the authors from the songs the user liked (84 distinct genres).
+- `deezer_europe` (FEATHER, collected in March 2020): a network of 28,281 users from European countries. Each user has a list of binary features, extracted from the artists liked by the user (only the indices of the features are given, not their meaning; 6,159 users have none), and a binary gender label, which the authors derived from the user's name; which value stands for which gender is not documented.
+
+The networks have the following properties:
+
+- GEMSEC networks: `genres`, the list of music genres liked by the user (e.g. "Pop", "Rap/Hip Hop").
+- `deezer_europe`: `gender`, the binary gender label (stored as a Boolean: false and true for the labels 0 and 1 of the data); `features`, the indices of the user's binary features."""
+tags = ['Social', 'Online', 'Unweighted', 'Metadata']
+url = ['https://snap.stanford.edu/data/gemsec-Deezer.html',
+ 'https://snap.stanford.edu/data/feather-deezer-social.html',
+ 'https://github.com/benedekrozemberczki/datasets']
+citation = [('B. Rozemberczki, R. Davies, R. Sarkar, and C. Sutton, "GEMSEC: Graph Embedding with Self Clustering." Proceedings of the 2019 IEEE/ACM International Conference on Advances in Social Networks Analysis and Mining (ASONAM), 65-72 (2019).', 'https://doi.org/10.1145/3341161.3342890'),
+ ('B. Rozemberczki and R. Sarkar, "Characteristic Functions on Graphs: Birds of a Feather, from Statistical Descriptors to Parametric Models." Proceedings of the 29th ACM International Conference on Information and Knowledge Management (CIKM), 1325-1334 (2020).', 'https://doi.org/10.1145/3340531.3411866')]
+icon_hash = None
+upstream_license = ('MIT License', 'https://github.com/benedekrozemberczki/datasets/blob/3b19135105432cbca65765c1113b91c395ed9d44/LICENSE')
+upstream_prefix = 'https://snap.stanford.edu/data'
+files = [((f'gemsec_deezer_dataset.tar.gz:deezer_clean_data/{c}_edges.csv',
+ f'gemsec_deezer_dataset.tar.gz:deezer_clean_data/{c}_genres.json'), c, None)
+ for c in ['HR', 'HU', 'RO']]
+files += [(('deezer_europe.zip:deezer_europe/deezer_europe_edges.csv',
+ 'deezer_europe.zip:deezer_europe/deezer_europe_target.csv',
+ 'deezer_europe.zip:deezer_europe/deezer_europe_features.json'),
+ 'deezer_europe', None)]
+
+def fetch_upstream(force=False):
+ return fetch_upstream_files(__name__.split(".")[-1], upstream_prefix, files,
+ force)
+
+@cache_network()
+@coerce_props()
+@annotate()
+def parse(alts=None):
+ name = __name__.split(".")[-1]
+ for fnames, alt, fmt in files:
+ if alts is not None and alt not in alts:
+ continue
+ with open_upstream_file(name, fnames[0], "rb") as f:
+ E = numpy.loadtxt(f, delimiter=",", skiprows=1, dtype="int64")
+ g = Graph(directed=False)
+ # nodes are indexed consecutively from zero, and all appear in the
+ # edge lists
+ g.add_vertex(E.max() + 1)
+ g.add_edge_list(E)
+ with open_upstream_file(name, fnames[-1], "r") as f:
+ feats = json.load(f)
+ assert len(feats) == g.num_vertices()
+ if alt == "deezer_europe":
+ g.vp.features = g.new_vp("vector<int32_t>")
+ for v, x in feats.items():
+ g.vp.features[int(v)] = x
+ with open_upstream_file(name, fnames[1], "r") as f:
+ rows = list(csv.DictReader(f))
+ assert len(rows) == g.num_vertices()
+ g.vp.gender = g.new_vp("int16_t")
+ for r in rows:
+ g.vp.gender[int(r["id"])] = int(r["target"])
+ else:
+ g.vp.genres = g.new_vp("vector<string>")
+ for v, x in feats.items():
+ g.vp.genres[int(v)] = x
+ yield alt, g