Social Proximity

Social proximity for new friendships - HackMD

Social proximity for new friendships

I have asked the SIMSOC list for help on how to calculate social proximity with the purpose of growing a friendship network in an agent-based simulation model, specifying a set of elements that characterise my agents. Social proximity as I plan to use it is studied in different bodies of literature under different names: homophily, conformity, and social distance (well, the inverse thereof). The frame here is, in (WJ) words:

there is an increased interest for integrating behaviour theoretical insights in a modelling framework. Specifically when processes of behavioural change are the topic of interest, be it farmers’ choice behaviour, recycling behaviour or citizens’ future mobility, the aforementioned examples indicate that the integration of different psychological mechanisms in a modelling framework contributes to the development of policy relevant models. Because the psychological drivers and dynamics of behaviour are included in these models, they can address social psychological responses to policy that go beyond the capacity of traditional economic and spatial models. (WJ)

My attempt was motivated by practical reasons, being in the process of implementing a simulation where this will be used as an ingredient. In other words, I need to calculate it to let a network where another phenomenon is being studied. To make it clear, what I needed was a set of weights that could, independent of context (and I know that sounds wrong; there might be nothing about this subject that is independent from context), weight the factors against each other. For example, I could use a statement telling that the difference in age, measured in years, is to be weighted twice as much as a difference in gender.

My starting point was the review paper from Dunbar (2018) which proposed ethnicity, age, religion, education, and social values as the basis for friendship - but, even as it ranked the factors, didn’t extend to proposing numerical weights for those.

In my simulation, the variables that my agents have are gender, education-level (4 levels), wealth-level (4 levels), job-level (4 levels), age, number-of-children. I also have friendship networks which can be used for several kinds of calculations; but as the network would also extend on the basis of social proximity, I am afraid of logical recursion there. Note that I am purposefully detaching this discussion from the main purpose of the simulation to keep the matter self-contained.

So, the objective was to find function of difference in gender, education-level, wealth-level, job-level, age, number-of-children, number-of-friends returning a measure between 0 and 1. Something practical, a snippet of code with factor weights; in short, something that would take the place of my 1.0s in the following netlogo snippet:

to-report factors-social-proximity
  report (list
    ;     var-name     weight    normalized-reporter
    (list "age"        1.0       [ -> ifelse-value (abs (age - [ age ] of myself) > 18) [ 0 ] [ 1 - abs (age - [ age ] of myself) / 18 ] ])
    (list "gender"     1.0       [ -> ifelse-value (male? = [ male? ] of myself) [ 1 ][ 0 ] ])
    (list "wealth"     1.0       [ -> ifelse-value (wealth-level = [ wealth-level ] of myself) [ 1 ][ 0 ] ])
    (list "job"        1.0       [ -> ifelse-value (job-level = [ job-level ] of myself) [ 1 ][ 0 ] ])
    (list "education"  1.0       [ -> ifelse-value (education-level = [ education-level ] of myself) [ 1 ][ 0 ] ])

Here, I sum up the answers from the SIMSOC list and from direct connections, together with a few references from the literature. In short, what I find is:

1 no precedent has emerged in the sense of an algorithm; this comes as a surprise and I remain confident that something might be found if we keep looking.
2 there’s no “one fit all” solution; at the very least, gender difference should make the calculation diverge on different algorithms

Maybe the single most important point that was made, on which I completely agree, is the following:

What you might want to do is try multiple schemes and see how sensitive your model is to this. (KC)

Factors suggested

Collaboration is a basis for community and it generally requires both social proximity and spatial proximity. However, there are some scenarios where social proximity seems more important and others where spatial proximity seems more important. (It all gets very confusing when so much communication is done between people using virtual means!) (…)
…so people are more likely to socialise with each other and have social proximity if they go to the same places and or have the same interests. (AT)

Social proximity, as I am looking for it, seems to be the inverse of social distance - this is measured since the 1930’s with the Bogardus scale. The Bogardus scale aims to measure social distance towards abstract groups characterized by, for example, an ethnic or religious connotation. It works through agreement or disagreement with a series of statements about potential joint activities with members of those group in roles ranging from spouse to exclusion. I haven’t found, however, any direct correlation or causation of factors leading to a value in the Bogardus scale. Moreover, social distance is designed towards groups, and thus not immediately leading to the formation of new friendship.

there is no standard measure. Also for friendship networks - people often use not just number of friends in common - but also number of friends not in common - people also consider triad as much of the work on new tie formation is based on triad closure.
how much gender, age, ethnicity, religion etc are weighted varies by culture. Also withing cultures these factors are non-linearly related. For example, gender based friendship is low before 7 years of age, then very strong then it drops again in the 30’s in some cultures. In other cultures religious based ties are high until one is 18 and then high again after age 60. (KC)

So, summing up, here are the factors suggested:

  • spatial proximity
  • education
  • also number of friends not in common, aka triad closure (KC)

Of these factors, our model cannot consider spatial proximity - this re-enters the algorithm anyway through the importance of co-workers (and schoolmates). Triad closure seems a good addition to what we had initially considered. The importance of existing relationships is also indirectly supported by Chen et al. (2009):

relationship based algorithms outperform content similarity ones in terms of user response.

Interaction of factors

…the probability of two agents interacting (is) dependent on their similarity. This produces a network where in principle all agents can interact, but the more similar the agent, the more likely they interact. (WJ)

Ok for similarity, but the probability might depend on the specific kind of interaction. Children don’t look for similar tutors, most people look for complementarity rather than for similarity. Palchykov et al. (2012) notice peaks in selection of “best friends” of the opposite gender - although this decreases with the second, third friend and so on. All this is a characteristic of the link more than the network, and the same individual could very well express different attitudes on different links. Akerlof (1997), while calculating an utility function for a representative agent in social interaction, considers separately both conformism and status seeking as giving rise to opposite utility functions for social interaction. However, Akerlof doesn’t have the issue of weights - he coalesces it all in a single value of social position (whose natural interpretation is educational attainment).

With these kind of variables I would be looking for a socially plausible set of metrics. So for example, ‘birds of a feather flock together’ would lead to stronger bonds between people with similar characteristics. Conversely, ‘opposites attract’ would allow for example for the prevalence of inter gender relationships in the family as well as for organic solidarities in the form of complementary divisions of labour. (AP)

social drivers such as conformism, anti-conformism and non-conformism as well as social learning strategies, imitation and social comparison processes.

Individuals usually participate in multiple networks of each type, and one of the key differentiators might be the number of different such networks, and the similarity of these networks between individuals. (AP)

Age and gender have a complex and culture-dependent relation.

how much gender, age, ethnicity, religion etc are weighted varies by culture. Also within cultures these factors are non-linearly related. For example, gender based frienship is low before 7 years of age, then very strong then it drops again in the 30’s in some cultures. In other cultures religious based ties are high until one is 18 and then high again after age 60. (KC)

In other words, focusing on social distance tells just half of the story. While several social interactions seem to be dictated by distance

personally am a bit suspicious of ‘social distance’. It takes us part of the way, but not the whole way. It uses only ascribed characteristics. What about complementarity, what about admiration? (HG)

Relations with a different age class and gender, intuitively, might enjoy complementarity more than similarity - however, we need some data to support and quantify this effect.

Effects suggested:

  • ‘birds of a feather flock together’
  • ‘opposites attract’

Experimental approach

Perhaps we could resort to an experimental approach - given time and resources. On this line, we could seek help from projects as IBSEN (

When a simulation needs to be fed real data, often an experiment is a good approach. To measure feeling of closeness, there could be different approaches.

We could give respondents photos of all combinations of variables under investigation (OK, there are about 2,000 combinations, let´s say they judge 100 /randomly/ selected) with short CV accenting characteristics under investigation and measure feeling of closeness for pairs of respondent´s and object´s characteristics. You might measure feeling on scale 0-100 or via Q-sort technique (every respondent sort 100 photos according pseudo normal distribution: 5 closest, 5 farthest, 7 less close, 7 less far, 9 even less close, 9 even less far … etc.) (FK)

The result: our code for social proximity

modelling human behaviour in computer models forces the researcher to develop running code, and hence make inferences on the causal mechanisms for the simulated agent (WJ)

… thus, after the discussion, I have modified the initial snippet as follows. Age and genders stay, for the moment, the same, as this model is about friendship and not (not only, not necessarily) about “best friends.” I have kept wealth as one of the factor, but I have left out, assigning them a weight of zero, job, education, and retired state, as they are strongly correlated in the model. The main addition here is the snippet testing for potential triad closure.

to-report factors-social-proximity  ; person reporter. Self is ego, myself is alter
  let ego self
  let alter myself
  report (list
    ;     var-name     weight    normalized-reporter
    (list "age"        1.0       [ -> ifelse-value (abs (age - [ age ] of ego) > 18) [ 0 ] [ 1 - abs (age - [ age ] of ego) / 18 ] ])
    (list "gender"     1.0       [ -> ifelse-value (male? = [ male? ] of ego) [ 1 ][ 0 ] ])
    (list "wealth"     1.0       [ -> ifelse-value (wealth-level = [ wealth-level ] of ego) [ 1 ][ 0 ] ])
    (list "job"        0.0       [ -> ifelse-value (job-level = [ job-level ] of ego) [ 1 ][ 0 ] ])
    (list "education"  1.0       [ -> ifelse-value (education-level = [ education-level ] of ego) [ 1 ][ 0 ] ])
    (list "retired"    0.0       [ -> ifelse-value (retired? = [ retired? ] of ego) [ 1 ][ 0 ] ])
    (list "closure"    1.0       [ -> ifelse-value (any? (other [ friendship-link-neighbors ] of alter) with
                                      [ friendship-link-neighbor? ego ]) [ 1 ][ 0 ] ])


Thanks to all who answered; snippets copied from the message I recevied are marked with the initial of the author: Alan Penn (AP), Andy Turner (AT), Frantisek Kalvas (FK), Gertjan Hofstede (HG), Kathleen Carley (KC), Wander Jager (WJ). They are used, of course, in my interpretation; most of the messages can be retrieved from the SIMSOC list. I am also indebted to Ignacio Tamarit Ramírez.


Akerlof, G. A. (1997). Social Distance and Social Decisions. Econometrica, 65(5), 1005–1027.
Chen, J., Geyer, W., Dugan, C., Muller, M., & Guy, I. (2009). Make new friends, but keep the old: recommending people on social networking sites (pp. 201–210). Presented at the Proceedings of the 27th international conference on Human factors in computing systems, ACM.
Dunbar, R. I. M. (2018). The Anatomy of Friendship. Trends in Cognitive Sciences, 22(1), 32–51.
Jager, W. (2017). Enhancing the Realism of Simulation (EROS): On Implementing and Developing Psychological Theory in Social Simulation. Journal of Artificial Societies and Social Simulation, 20(3).
Palchykov, V., Kaski, K., Kertész, J., Barabási, A.-L., & Dunbar, R. I. M. (2012). Sex differences in intimate relationships. Scientific Reports, 2, 370.
Sherif, M., & Hovland, C. I. (1961). Social judgment: Assimilation and contrast effects in communication and attitude change. Oxford, England: Yale Univer. Press.

On the crisis

It was interesting to find in a classic (Hobsbawm’s Age of Extremes, 1994) the prophecy on the failures of economic theory to deal with crises:

As unemployment soared, it did not seem plausible … that public works would not increase employment at all, because the money spent on them would merely be diverted from the private sector, which would otherwise have generated just as much employment.

Economists who simply advised leaving the economy alone, governments whose first instincts, apart from protecting the gold standard by deflationary policies, was to stick to financial orthodoxy, balance budgets and cut costs, were visibly not making the situation better.

…us who lived through the years of the Great Slump still find it almost impossible to understand how the orthodoxies of the pure free market, then so obviously discredited once again came to preside over a global period of depression in the late 1980s and 1990s, which, once again, they were equally unable to understand or to deal with.

Another case where I came to think that we don’t really need a simulation to understand.

Reading one year of JASSS (2013)

To answer a comment by a reviewer, I decided to read (well, browse) a whole year of JASSS papers and to mark down which of them contained constructs that correspond to mental representations and which ones didn’t. As I went reading, it was obvious that my simple grid wasn’t very good; that in some cases, it’s hard to tell if you have only “simple” agents – that is, agents following the KISS principle – or not. At the same time, I got immediately greedy: I started to collect more data in the grid – some of them when I had already moved forward, and I didn’t feel like going back to fill the previous slots.

I don’t know if this can be of any use but to myself – but here it is just in case. Note that I’m publishing it as an editable google spreadsheet, so if you feel I made some mistake, you can just go and correct them.

The editable spreadsheet (if I have made no uploading mistakes) is here

How to quickly run a Jason project

How to open an existing project in the default iEdit Jason environment?

For those of you that don’t want to start Eclipse every time you need to test a Jason project (as an example, located in ./Donwloads/TestProject), the mechanism is

  1. open jEdit
  2. go to menu plugins – Jason – new project
  3. select as root location the directory immediately ABOVE the one you’re looking for (in the example, ./Downloads)
  4. put as project name the exact name of the directory, not the name of the .mas2j file that might be different (in the example, TestProject)
  5. if the name of the .mas2j file is NOT same as the project, the editor will propose an empty .mas2j file. Close it without saving, remove it from the directory, and proceed to open the real .mas2j file.

You’re all set.

Running Jason by command line

Simple enough it should be somethihg like:

java -Xms2000M -Xmx2000M -XX:NewSize=1500M 
  -classpath './lib/jason.jar:./lib/c4jason.jar:./lib/cartago.jar:./bin/classes' 
  jason.infra.centralised.RunCentralisedMAS ModelName.mas2j

Test it – of course, this line assumes that the directory structure is such that the instruction is issued in the main Jason directory (so the ./lib/jason.jar works) and that the classes are placed in .bin/classes.

Notes on Jason

In this post, I will list some ideas I got about Jason from the Simulation module in the course at the university of Bologna. Specifically, I will focus on these ways of writing agentspeak code that is correct but looks not natural to those who are knowedgable (for me, it’s good ‘ole Fran who first helped me to the exoteric aspects of this way of thinking.

So, without further ado, let’s list some classic “mistakes.” We start from code written from two excellent students. We have a list of [value, key], for example, [[1,a][2,b][3,c]] and a list of names, [ a,c, d]. We want to keep items in the first list only if they have the name in second. The result must be sorted.

Solution 1:

!updateList([[1,a][2,b][3,c]], [a,c,d], []).

+!updateList(Couples, Names, Res) <-
	.length(Couples, CouplesLength);
	//CouplesLength = CouplesLength; // ??
	if (CouplesLength > 0) {
		.nth(0, Couples, CurrentCouple)
		.delete(0, Couples, TailCouples);
		.nth(1, CurrentCouple, CurrentName); 
		if (.member(CurrentName, Names)) {
			.concat([CurrentCouple], Res, NewRes);
			!updateList(TailCouples, Names, NewRes);
		} else {
			// do nothing, thus losing the current couple.
			!updateList(TailCouples, Names, Res);
	else {
		// ultima esecuzione del piano per il ciclo in corso
		.sort(Res, SortedRes);

This solution works – but * it doesn’t use the context, instead it uses nested if as if we were in java; * it doesn’t process the list in the logical [H|T] way; * accesses elements inside a list with .nth instead of just unifying them.

A solution that does the same but only using logical style programming is the following:

!updateList([[1,a][2,b][3,c]], [a,c,d], []).

// update the ones I know.
+!updateList([[Value, Name]| T], Names, Res): .member(Name, Names) <-
	.concat([[Value, Name]], Res, NewRes);
	!updateList(T, Names, NewRes).

// drop the ones I don't know.
+!updateWages([[Value, Name]| T], Names, Res) <-
	!updateList(T, Old, Res).

// wrap it up	
+!updateWages([], Names, Res) <-
		.sort(Res, SortedRes);

Which one is more readable? Which one is easiest to maintain?

← Older Newer →