History of citeseer_linqs
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: citeseer_linqs d989911
diff --git a/entries/citeseer_linqs/__init__.py b/entries/citeseer_linqs/__init__.py
new file mode 100644
index 0000000..2f8584c
--- /dev/null
+++ b/entries/citeseer_linqs/__init__.py
@@ -0,0 +1,96 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 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 *
+
+
+title = "CiteSeer computer science papers (LINQS, 2003)"
+description = """A directed citation network of computer science papers, from the version of the CiteSeer dataset distributed by the LINQS group (Lu & Getoor; Sen et al.) as a benchmark for collective classification, also used (as one of the "Planetoid" datasets) in many works on graph neural networks. CiteSeer was a digital library and search engine for scientific papers, built by Giles, Bollacker and Lawrence by automatically crawling the web for papers and extracting their references. This dataset is a selection of 3,312 papers, each classified into one of six topics, chosen such that every paper cites or is cited by at least one other paper of the selection. Each paper is described by the presence or absence of 3,703 words of a vocabulary obtained after stemming and removing stopwords, and discarding words that appear in fewer than 10 papers. The words themselves are not included in the data. This is different data from the one in the `citeseer` entry; see also the `cora_linqs` and `pubmed_linqs` entries.
+
+An edge from paper A to paper B means that A cites B. The citation list refers to 15 papers that are not in the list of papers (17 citations); they are included as nodes without topic and words. The data contain 124 self-loops (papers citing themselves), which are kept.
+
+The network has the following properties:
+
+- `id`: the identifier of the paper in the source data.
+- `subject`: the topic of the paper, one of `Agents`, `AI` (artificial intelligence), `DB` (databases), `HCI` (human-computer interaction), `IR` (information retrieval) and `ML` (machine learning), or empty for the papers missing from the list of papers.
+- `words`: a vector of 3,703 binary values, where the i-th value is 1 if the i-th word of the vocabulary appears in the paper, and 0 otherwise (empty for the papers missing from the list of papers)."""
+tags = ['Informational', 'Citation', 'Unweighted', 'Metadata', 'Text']
+url = ['https://linqs.org/datasets/#citeseer-doc-classification',
+ 'https://web.archive.org/web/20260923154413/https://linqs-data.soe.ucsc.edu/public/lbc/']
+citation = [('C. L. Giles, K. D. Bollacker, S. Lawrence, "CiteSeer: An Automatic Citation Indexing System." Proceedings of the Third ACM Conference on Digital Libraries, 89-98 (1998)', 'https://doi.org/10.1145/276675.276685'),
+ ('Q. Lu, L. Getoor, "Link-based Classification." Proceedings of the Twentieth International Conference on Machine Learning (ICML), 496-503 (2003)', 'https://cdn.aaai.org/ICML/2003/ICML03-066.pdf'),
+ ('P. Sen, G. Namata, M. Bilgic, L. Getoor, B. Gallagher, T. Eliassi-Rad, "Collective Classification in Network Data." AI Magazine 29(3), 93-106 (2008)', 'https://doi.org/10.1609/aimag.v29i3.2157')]
+icon_hash = None
+upstream_license = None
+# The LINQS host (https://linqs-data.soe.ucsc.edu/public/lbc/citeseer.tgz) was
+# unreachable at the time of writing, so we use the Internet Archive's copy
+files = [(('citeseer.tgz:citeseer/citeseer.cites',
+ 'citeseer.tgz:citeseer/citeseer.content'), None, None)]
+archived_urls = {
+ 'citeseer.tgz': 'https://web.archive.org/web/20260923154413id_/https://linqs-data.soe.ucsc.edu/public/lbc/citeseer.tgz'}
+
+def fetch_upstream(force=False):
+ return fetch_archived_files(__name__.split(".")[-1], archived_urls, force,
+ tries=4)
+
+@cache_network()
+@coerce_props()
+@annotate()
+def parse(alts=None):
+ global files
+ name = __name__.split(".")[-1]
+ for fnames, alt, fmt in files:
+ if alts is not None and alt not in alts:
+ continue
+ with ExitStack() as stack:
+ fs = [stack.enter_context(open_upstream_file(name, fn, "r")) for fn in fnames]
+
+ # Content: "<paper_id> <3703 binary word attributes> <class_label>"
+ ids = []
+ subjects = []
+ words = []
+ for line in fs[1]:
+ row = line.split()
+ if not row:
+ continue
+ ids.append(row[0])
+ subjects.append(row[-1])
+ words.append(numpy.array(row[1:-1], dtype=numpy.uint8))
+ idx = {i: v for v, i in enumerate(ids)}
+ assert len(idx) == len(ids)
+
+ # Cites: "<cited> <citing>"; edges go from citing to cited
+ cites = [line.split() for line in fs[0] if line.strip()]
+
+ # Papers cited or citing, but absent from the content file
+ missing = sorted({i for c in cites for i in c} - set(idx))
+ for i in missing:
+ idx[i] = len(ids)
+ ids.append(i)
+ subjects.append("")
+
+ g = Graph(directed=True)
+ g.add_vertex(len(ids))
+ g.vp.id = g.new_vp("string", vals=ids)
+ g.vp.subject = g.new_vp("string", vals=subjects)
+ g.vp.words = g.new_vp("vector<bool>")
+ for v, w in enumerate(words):
+ g.vp.words[v] = w
+ g.add_edge_list([(idx[b], idx[a]) for a, b in cites])
+ yield alt, g