logo Netzschleuder network catalog, repository, and centrifuge

History of lastfm_asia

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: lastfm_asia by Tiago de Paula Peixoto 8544e21
diff --git a/entries/lastfm_asia/__init__.py b/entries/lastfm_asia/__init__.py
new file mode 100644
index 0000000..80cf83c
--- /dev/null
+++ b/entries/lastfm_asia/__init__.py
@@ -0,0 +1,77 @@
+#! /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 = "LastFM Asia mutual followers (2020)"
+description = r"""A social network of users of the music website Last.fm from Asian countries, collected from its public API in March 2020 by B. Rozemberczki and R. Sarkar (FEATHER study) for benchmarks of node classification methods. Nodes are users, and an undirected edge connects two users who follow each other (a mutual follower relationship). The user names were replaced by consecutive indices. Each user has a list of binary features extracted from the artists the user liked (only the indices of the features are given, not the artists; 173 users have no features), and a country label, derived from the country field of the user profile, which is the target of the classification task proposed with the data. The countries are given only as indices from 0 to 17, without their names.
+
+This network is unrelated to the other Last.fm entries (`lastfm`, `lastfm_aminer`, `lastfm_finland`, `lastfm_friendships`), which were collected at other times and with other selections of users.
+
+The network has the following properties:
+
+- `country`: the index of the user's country (0 to 17; the names are not given).
+- `features`: the indices of the user's binary (artist) features."""
+tags = ['Social', 'Online', 'Unweighted', 'Metadata']
+url = ['https://snap.stanford.edu/data/feather-lastfm-social.html',
+       'https://github.com/benedekrozemberczki/datasets']
+citation = [('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'
+# (sic: the directory in the archive is "lasftm_asia")
+files = [(('lastfm_asia.zip:lasftm_asia/lastfm_asia_edges.csv',
+           'lastfm_asia.zip:lasftm_asia/lastfm_asia_target.csv',
+           'lastfm_asia.zip:lasftm_asia/lastfm_asia_features.json'), None, 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")
+        with open_upstream_file(name, fnames[1], "r") as f:
+            rows = list(csv.DictReader(f))
+        N = len(rows)
+        assert sorted(int(r["id"]) for r in rows) == list(range(N))
+        assert E.max() < N
+        g = Graph(directed=False)
+        g.add_vertex(N)
+        g.add_edge_list(E)
+        g.vp.country = g.new_vp("int32_t")
+        for r in rows:
+            g.vp.country[int(r["id"])] = int(r["target"])
+        with open_upstream_file(name, fnames[2], "r") as f:
+            feats = json.load(f)
+        assert len(feats) == N
+        g.vp.features = g.new_vp("vector<int32_t>")
+        for v, x in feats.items():
+            g.vp.features[int(v)] = x
+        yield alt, g