Last update: 28 December 2019
Carl Nordlund, The institute for analytical sociology, Linköping university, Sweden
This is a practical user-guide to Spindel 1.0, a software client built to demonstrate a novel, dichotomization-free approach to direct blockmodeling of valued and binary networks. The underlying arguments and full specification (including pseudocode) of the proposed approach is found in the following 2019 Social Networks journal article:
• Nordlund, C. 2020. Direct blockmodeling of valued and binary networks: a dichotomization-free approach, Social Networks, Vol. 61, pp. 128-143 https://doi.org/10.1016/j.socnet.2019.10.004 [Preprint]
The actual software client (Windows .NET, written in C#) is available for download here: https://demesta.com/page1.php?page=academia#software
…and you are either reading this user documentation through the client help panel or online at this URL: https://demesta.com/spindel/index.html
Also note that Spindel 1.0 is very much in Beta - and that the ambition is to implement a LOT more functionality into it. So this is very much a work-in-progress (and both the software and documentation will be updated shortly).
In its current version, Spindel works with five kinds of data structures: matrices, partitions, block images, blockmodels and actorsets.
Actorsets: An actorset represents a set of actors/nodes of a network. Matrices and partitions each point to specific actorsets; an actorset can thus have several networks or partitions referencing it. In Spindel 1.0, actorsets are defined when loading a network (a matrix), and they can't be manipulated once loaded. The currently used actorsets can be inspected in the drop-down menu in the top-left Selector area of the client.
Matrices: Each Matrix represents a (1-mode) network. These can either be binary or valued, and they can't contain self-ties. Matrices can either be imported from csv-style text files (File/Open data structure/Matrix) or one of the pre-installed matrix files can be loaded (File/Open sample data/[list of example networks]). To import csv-style text files, it is recommended to use tab-separated data cells, and to have unique actor labels on the first row and the first column. Consult the format of the files in the SampleData folder where Spindel 1.0 is installed. Currently loaded matrices will appear under the "M" tab in the top-left Selector area.
Partitions: Each partition is attached to a specific actorset and represents a particular partition of the actors in that actorset into two or more non-overlapping subsets. Partitions are the results of a direct blockmodeling search. When a partition is stored, it will appear under the "P" tab in the top-left Selector area.
Blockimages: Representing a reduced version of a network, a block image consists of two or more positions, where the number of blocks is the square of the number of positions. For instance, a classical Galtung-style core-periphery blockimage consists of two positions – a core and a periphery – with a total of 4 intra- and inter-positional blocks: a complete or regular intra-core block, a null intra-peripheral block, and a regular block in respective core-periphery block. A blockimage is not attached to a specific actorset or matrix; rather, a blockimage just contains references to specific ideal blocks in each of its block positions. Blockimages in Spindel 1.0 are created (see below), and they can either be "multiblocked" (each block position could contain two or more ideal block types) or standard (each block position only contains one possible ideal block). When a blockimage is created, it will appear under the "BI" tab in the top-left Selector area.
Blockmodels: These represent a specific result from a blockmodel analysis and is referencing all other objects: a specific matrix object, a specific blockimage, and a specific partition (with the number of positions in the blockimage and partition being the same). A blockmodel also contains details about the specific solution: the criteria function used, the goodness-of-fit score, the corresponding ideal matrix and, in the case of conventional blockmodeling, observed number of inconsistencies per block. For multiblocked blockimages, i.e. where several ideal blocks are tested, the blockmodel also contains info about which specific ideal blocks were chosen as the most optimal ones.
While working, Spindel 1.0 generates several additional data structures of the above types. As different data structures are generated, tabs will appear in the top-left Selector field, containing matrices, partitions, block images, and blockmodels respectively. To inspect a specific data structure, double-click on the specific data astructure. It will then be shown in the main, right-hand area. There are 4 link-buttons in the Selector field as well, for either selecting All data structures in the current tab, to Inverse the selections in the current tab, to Clear the selection in the current tab and to Clear all selected structures in all tabs.
To delete one or more data structures, mark them in their respective selectors. Use CTRL and left-click to choose multiple. Then go to the Data Structures menu item and choose "Remove selected". Note that all selected data structures will then be removed, even those that might be selected in tabs not currently visible.
All data structures in Spindel 1.0 can be stored in a common dataset file. If you wish to save your work and continue later, use Save dataset (or Save dataset as… to make a copy) in the File menu. The dataset file will get a .cns file extension: it is a simple text file where all data structures are aggregated. (Spindel 1.0 uses the same datafile format as Ceunet, another software project…)
Spindel 1.0 comes pre-installed with several demonstrational datasets, including those used in the Social Networks article. To load one of the pre-installed matrices, choose File/Open sample data/ and choose a file. It will then appear under the "M" tab. Note that this will also create an actorset for this matrix.
You can also import your own text files to Spindel 1.0, using the File/Open data structure/Matrix menu option. The Load Matrix panel will then appear to the right. Choose the text file you want to import and the field separator that your text file is using. Note that the first row and the first column must contain the labels for the actors/nodes. It should look like this (assuming that you have semicolon as field separators; this data the same as in is Fig 3 in the article):
To create a blockimage, use the menu option Data structures/Create blockimage… The panel for creating blockimages will appear.
In the first step, decide how many positions (k) your blockimage will have. This defaults to 3. Click the Prepare button to create an empty blockimage.
You can now start entering block names in the block positions. Available block types right now are nul (null blocks), com (complete blocks), reg (regular blocks), and dnc (do-not-care blocks). A block can either contain a single ideal block – e.g. "nul" – or two or more ideal block types – e.g. "nul,com". You can also pre-fill all blocks using the Fill pattern text input and the Fill button, e.g. by setting all blocks to "nul", and you can also pre-fill all blocks with either "nul,com" or "nul,reg". Click the [clear] button to clear the block image. For exporative analyses, it is better not to specify the block image: then it is better to use the "nul,com" or "nul,reg" optioins.
Once you have filled all blocks in your blockimage, click "Verify". If there is something wrong (such as an empty block or a non-recognized block type), the block turns red. Fix the error and click "Verify" again.
Once the blockimage is verified, you can give it a name. Then you are given two options for storing the blockimage: either storing this as a single blockimage, or to store all varieties. These options relate to whether you have stated several types of ideal blocks in at least one of the blocks. This would be the case if you have "nul,com" in all blocks.
Storing it as a singular blockimage then results in this being stored as a multiblocked blockimage. The multiple ideal blocks are stored in the blocks of the blockimage. Multiblocked blockimages are specifically useful in the conventional inconsistency-based criteria functions: then we only need one blockimage with which to fit the various ideal and empirical blocks with each other.
Storing it as all varieties means that we are "unfolding" the possibly multiblocked block image. For a 3-positional blockimage with "nul,com" in each of the 9 blocks, this would then result in a total of 88 unique blockimages, each of these then holding only a singular ideal block per block position. To filter out isomorphic block images as well as blockimages that contain "structurally equivalent" positions, Spindel 1.0 uses a clever heuristic that combines concatenated eigenvalues with a recursive permutation test. The block images resulting from this "unfolding" are thus covering all non-trivial and unique (non-isomorphic) varieties of the multiblocked blockimage. These varieties are specifically useful in the weighted correlation coefficient approach.
Given a matrix and one or more blockimages, you are now ready to do direct blockmodeling! Go to the Blockmodeling menu and choose Direct blockmodeling. The Direct blockmodeling panel appears, with plenty of options.
First, select the network (matrix) that you want to work with. The dropdown menu should contain all matrix objects that you have in the Selector matrix tab. However, if there is any missing, click the "Refresh" button up in the toolbar (under the top menu) and check the dropdown menus again.
Then, select the blockimage or blockimages that you want to explore. You can either choose a given blockimage in the "Single blockimage" dropdown menu, or to use several or all of the blockimages you have in the program. If you want to do conventional inconsistency-based (Hamming) binary blockmodeling and find the most optimal blockimage, you are recommended to select a single multiblocked blockimage here. However, if you want to do blockmodeling using the weighted correlation coefficient approach, you have to select all the "unfolded" blockimages from such a multiblocked blockimage. If so, you can either select the specific blockimages you want to use in the top-left selector, and choose the "Selected blockimages" option, or you can choose the "All blockimages" option (assuming that you want to use all blockimages in the top-left selector). An additional option is the "Store optimal for each" checkbox: whereas only available in the non-single-blockimage options, this will store the optimal solution for each of the blockimages. This can also be useful for the inconsistency-based approach, if you are testing which out of several archetypical structures (core-periphery, hierarchy, transitive structure etc) that a network is most similar to.
Next, a search heuristic must be chosen. The first one uses a depth-first local optimization heuristic. Starting with a random seed partition and its goodness-of-fit value, neighboring partitions are explored (using moves and switches), where equally good or better partitions are explored in the next iteration. Once an optimal value has been found (or for a maximum number of iterations per run), this is repeated (number of restarts), comparing found results with the best found so far for this blockimage and matrix. It is very advisable to rerun the optimization algorithm multiple times, and increasing the number of restarts and iterations per run as much as possible.
The second "search" heuristic is the exhaustive search. This simply iterates through all possible permutations, calculating the goodness-of-fit for each partition and comparing with the optimal solution so far. This option is obviously only feasible for small networks.
The third heuristic is not a search heuristic, but rather a way to test specific partitions. Given one or more selected partitions in the top-left Selector field, this option obtains the solutions for these partitions, given the blockimage(s) and the matrix above. All these results are stored.
Next, the criteria function is to be chosen. Right now, only the conventional binary approach – "Binary (Hamming)" – and the weighted correlation coefficient approach – "Weighted correlations" – are implemented. Note that the latter approach does not work well with multiblocked blockmodels; rather, the weighted correlation coefficient approach must be done on each of the varieties "unfolded" from a multiblocked blockimage.
Click the "Search" button to run the search. If the search takes a while, a progress/status window will appear, indicating how far the search has gone. Once finished, the found optimal solutions will be given in the bottom-left "Solutions" field, as a list showing the goodness-of-fit, the matrix, the blockimage, and the "partition string" of this particular solution.
With solutions in the bottom-left "Solutions" list, you can click the Fit values to display the blockmodels. In addition to the actual blockmodel that is being shown, you are also given the fit (above the blockmodel) and the criteria function used (either binaryHamming or wcc). Below the blockmodel, there are three additional fields. To the left are the particular data structures that are associated with this blockmodel. Whereas the Matrix, Blockimage and Actorset are already visible in the Selectors field, there is also a Partition and an idealMatrix given here that are not yet stored in the dataset that is currently active in Spindel 1.0. Although the Blockmodel is a data structure that evidently exists in Spindel 1.0, it is not yet stored in the dataset that you are currently working in. It is not always we want to store all blockmodels/solutions that we find – first we want to inspect them.
To store the Blockmodel you are currently viewing, click the "Store blockmodel" button in the top-right of the panel. This will lead to 3 new data structures being added to the top-left Selector tabs. First, the Blockmodel itself will appear under the "BM" tab. Then, the particular partition for this blockmodel will appear under the "P" tab. Finally, the ideal matrix for the blockmodel (which is a matrix indicating which ties that are identified as prominent and non-prominent) will be stored as well under the "M" tab. You can inspect these data structures independently as well. Now when the blockmodel is stored, you can also access this again by double-clicking the specific blockmodel in the BM selector tab.
There are two additional fields in the panel for viewing a blockmodel. The "Block image" field displays the optimal blockimage for the particular blockmodel. In case that the blockimage is multiblocked, this display will show the ideal blocks that were found to be the most optimal. The "Penalties" field is only active when doing "binaryHamming" (inconsistency-based) blockmodeling. This indicates the number of inconsistencies per block location. For the "wcc" approach, this is not applicable.
Once you have done some blockmodeling, you might want to save your work so you can revisit it and come back later. Then use File/Save datas (or Save dataset as…). This will store all data structures in a single file, so you can later on load this dataset file.