Two conflicting concepts

Sometimes you hear a word or concept that changes how you look at the world. For me, these include speciecism and epistemic injustice.

Speciecism is analogous to racism and sexism, but for species: treating another being differently because they are of another species. Speciecism is about intent; if you eat chickens because they are chickens and not humans, that is speciecist, but if you eat chickens because you concluded from observation that they are incapable of suffering, that is not speciecist.

Epistemic injustice is when someone is wronged in their capacity as a knower. If you unjustly limit somebody’s ability to access or express knowledge, like forbidding them from learning to read or speak, that is an epistemic injustice.

I am an outspoken anti-speciecist and I think we should do what we can to prevent epistemic injustice in all forms. But some animals have learned enough language to meaningfully communicate with humans. Does that mean I should find it reprehensible that there are no schools for animals? I think I should and I think I do, but I feel hesitant to firmly claim the position.

Typed languages, units.

I recently picked up programming again. I used to do it a lot before I went to university, but the constant mind-numbing programming assignments quickly put me off of programming. Apart from the occasional quick bug fix for software I use myself, I haven’t done any serious coding for years.

Until recently, when I needed something coded up during my research. I decided to learn Python, and I like it. It is easy to use, the libraries are extensive and user-friendly, and ipython is a useful tool. There is just one thing that draws my ire: the weak type system. Studying math has given me an appreciation for type checking that is even stricter than most languages.

An example: my length in centimeters plus the outside temperature in °C right now equals 180. This calculation makes no sense, because the units don’t match: you can’t add centimeters to degrees Celcius. But then there’s Python, which just lets you do that.

In [1]: length = 170

In [
2]: temperature = 10

In [
3]: length + temperature
Out[
3]: 180

Most bugs that stem from typos are of this sort. Those bugs are possible because the type system is too weak. If you have two loops, one iterating over i and one over j, basic unit-based type checking would probably flag any instance of i in a place where you should have typed j instead. If you intend to query A[i][j] then it should be possible to let i have row-index type and j have type-index type, making A[j][i] raise a type error.

Another example: Let A \in \mathbb{R}^{n \times n}, x \in \mathbb{R}^n, and we’re interested in the quantity Ax \in \mathbb{R}^n. If you’re like me and you can’t remember what rows and what columns are, then that doesn’t have to impact your ability to symbolically do linear algebra: the quantities xA = A^{\mathsf{T}}x, Ax^{\mathsf{T}} and A^{-1} x don’t “compile”, so any mathematician that reads it will know you typo-ed if you wrote one of those latter expressions. All operations might be matrices acting on vectors, but the matrices A^{-1} and A^{\mathsf{T}} fundamentally take input from different copies of \mathbb{R}^n than the ones that x and x^{\mathsf{T}} live in. That is why matrix operations make sense even if the matrices aren’t square or symmetric: there is only one way to make sense of any operation. Even if you write it wrong in a proof, most people can see what the typo is. But then there’s Python.

In [4]: import numpy as np 

In [5]: x = np.array([1,2])

In [6]: A = np.array([[3,4],[5,6]])

In [7]: np.dot(A,x)
Out[7]: array([11, 17])

In [8]: np.dot(A,np.transpose(x))
Out[8]: array([11, 17])

In [9]: np.dot(x,A)
Out[9]: array([13, 16])

I am like me and I can’t remember what rows and what columns are. I would like the interpreter to tell me the correct way of doing my linear algebra. At least one of the above matrix-vector-products should throw a type error. Considering the history of type systems, it is not surprising that the first languages didn’t introduce unit-based types. Nonetheless, it is a complete mystery to me why modern languages don’t type this way.

A case for donation splitting

TLDR: if welfare compounds then risk-aversion is good.

Within EA circles, the question of splitting donations pops up every once in a while. Should you donate all your money to the singular top-rated charity your singular top-rated cause area, or is there reason to split your donations between various different causes or interventions?

People other than me have written and talked about this under various headers, I’ll list a small subset. Reasons not to diversify (Giving What We Can)Reasons to diversify: the value of information, explore vs exploit (Amanda Askell @ 80k)Reasons both for and against: risk aversion, diminishing returns, EV maximization (Slate Star Codex). In-depth blog post with mahy arguments both for and against (EA forum). Not listed but probably talked about before: splitting your donations gives you extra practice at donating which might lead to you making better donation decisions in the future.

In this post I want to make an argument in favour of splitting donations based on compounding economic returns and measurement error. Specifically, compounding returns favour more consistent growth over a slightly higher but variable growth.

Let’s consider a 100-year time horizon. Suppose that there are 100 charities, C_1,\dots,C_{100}, whose effectiveness is heavily-tailed: donating $1000 to charity C_i allows them to produce i*\$1000 in welfare after a year. Charity evaluator BestowCapably measures the effectiveness of every charity C_i every year j and finds an effectiveness of i + s_{i,j}, where the s_{i,j} are independently normally N(0, \sigma^2) distribution. Let’s assume BestowCapably’s measurement error \sigma does not go down over time.

The way I think of these quantities is that effectiveness is a heavy-tailed distribution and that measurement error is multiplicative (instead of additive).

We assume all welfare gains are reinvested in charity the next year, so that the gains compound over years. The initial welfare is 1. We consider three different donation strategies: donate everything to the single best rated charity, split the donation between the top three rated charities, or split the donation between the top ten rated charities. We plot the compounded welfare after 100 years versus \sigma below.

In the above graph, we see that,for low measurement error, donation splitting is worse than donating everything to the best charity, but for high measurement error, the situation reverses and splitting donations wins out.

Section of doubt

The code I’ve used (included below) to simulate the scenario has a couple researcher degrees of freedom. It is unclear whether measurement error should scale with charity effectiveness. I used Gaussian noise without any justification. My choice of range of \sigma to plot was chosen to have a nice result. The range of charity effecicies has close to no justification. The same stable result can be gotten by donating everything to AMF and nothing to speculative cause areas. The splitting incentive I illustrated only holds at the margin, not for the average donation. Because \sigma is fixed, the magnitude of the effect of donation splitting in this model depends heavily on the number of charities (less charities means greater effect).

Nonetheless, if you care about multi-year impacts, it might be wise to consider more than just short-term expected value. Risk-aversion translates to expected counterfactual impact when results compound.

Appendix: Python code

import random
import matplotlib.pyplot as plt
import math

charitycount = 100
yearstocompound = 100

# The charities are {1,...,n}
# Charity i has effectiveness i
# Effectiveness measurement carries exp noise of size stddev
# Outputs list of (i, i + noise)
def measurecharities(n, stddev):
    charities = []
    for effectiveness in range(1,n+1):
        charities.append((effectiveness,random.gauss(effectiveness,stddev)))
    return charities

# Given list of tuples (x, y),
# calculates the average of x's for
# the k tuples with highest y value.
def avgtop(list, k):
    sortedlist = sorted(list, key=lambda tup: tup[1], reverse=True)
    sum = 0.0
    for i in range(k):
        sum += sortedlist[i][0]
    return sum/k

# Split donations among k charities
for k in [1,3,10]:
    x = []
    y = []
    # We plot the effect for different noise magnitudes
    for stddev in range(1,251):
        logwelfare = 0.0
        for i in range(yearstocompound):
            welfaregain = avgtop(measurecharities(charitycount, stddev), k)
            logwelfare += math.log(welfaregain)
        x.append(stddev)
        y.append(max(1,logwelfare))
    plt.plot(x, y,label=k)
plt.legend()
plt.xlabel('Error in measuring effectiveness')
plt.ylabel('Log(' + str(yearstocompound) + '-year compounded welfare gains)')
plt.title('Donating to top k out of ' + str(charitycount) + ' charities')
plt.show()

Best Things of 2018

Not (best (things of 2018)) but ((best things) of 2018), because recommendations get more interesting if they are rate-limited and less interesting if a recency constraint is imposed.

Best interactive web essay

By internet creators Vi Hart and Nicky Case; Parable of the polygons. Cute little triangles and squares get segregated in ways none of them ever intended against their best wishes.

Best portrait article

Portraying one of the most important trans people of the past few years, Vice Broadly’s piece on Caitlyn Jenner was a nice read.

Best economist’s story

On why setting maximum prices is bad. They Clapped by Michael Munger. Very salient, go read it.

Best academic talk

I see a lot of talks from computer science researchers, and CS people are surprisingly good at giving captivating talks. But, quoting Virginia Woolf,

[..] one must read [any book] as if it were the last volume in a fairly long series, continuing all those other books that I have been glancing at. For books continue each other, in spite of our habit of judging them separately.

Virginia Woolf, A Room of One’s Own, or page 52 in Penguin’s Vintage Mini “Liberty”

And so a talk must be considered in its social context. Based on this principle, the clear winner for this category is this keynote speech by James Mickens of Harvard University at USENIX Security 2018: Why Do Keynote Speakers Keep Suggesting That Improving Security Is Possible? Mickens is a captivating orator, the talk is funny and informative and gives a critical view on an important issue of the present day.

Best internet rabbit-hole

An old one for nostalgia. How to spot photo manipulation. Body By Victoria. Do click the links to follow-up posts, and the rest of the website is worth checking out as well.

Best description of psychologists

This text fragment reflects every interaction I’ve had with psychologists anywhere, both my gatekeepers and psychologists I visited for other reasons.

My anorexic patients sometimes complain of being forced into this mold. They’ll try to go to therapy for their inability to eat a reasonable amount of food, and their therapist will want to spend the whole time talking about their body image issues. When they complain they don’t really have body image issues, they’ll get accused of repressing it. Eventually they’ll just say “Yeah, whatever, I secretly wanted to be a ballerina” in order to make the therapist shut up and get to the part where maybe treatment happens.

Scott Alexander, Del Giudice On The Self-Starvation Cycle

Best video essay

This is not really a contest, Contrapoints’ The Aesthetic is the most beautiful piece of film I’ve seen in years. It is an honest expression of feelings and internal dialogue and conflict that trans women experience. It touches on so many uncomfortable issues without having any single clear message. Contrapoints raises the video essay to form of art. There is so much going on so many levels and I can just keep on watching the thing over and over again. Highly recommended watching for both trans and cis people.

The creator got quite some social media backlash on the video. There is exactly one reaction that I felt was worth watching. Nobody Wins: ContraPoints, The Aesthetic, and Negative Representation by let’s talk about stuff.

Best book

My choice of best book for 2018 is Aphro-ism by Aph Ko and Syl Ko. It is a blog-turned-book, with a number of brilliant essays on, among others, veganism and social justice. I cannot overstate how much I like this book. I learned a lot from reading this book, and not just about the book’s subject matter.

The writings of the Ko sisters are very far from every thought I’ve ever had. This fact is reflected in how much I learned from the book, as well as in how difficult it was to understand it. I’ve re-listened this book 5 times by now. The first time, I understood literally nothing. Each time after that I understood a bit more, and I feel I understand most parts now. Not yet at the level of being to explain the ideas, but at the level of seeing good use value in them.

On the value of anecdotes

What is better, if everyone is wrong about the same 2% of facts, or if everyone is wrong about a different 4% of facts? Depending on how you answer this question, you should act in very different ways. I’ll take vegan advocacy as an example, but the question can be applies more generally.

If you’re in the first group, you would prefer a scientific data-driven approach. You would experiment with many different approaches to advocacy, analyse the data to find the single best way of doing outreach, and make everyone in vegan activism aware that this is the best way to do it.

If you prefer the 2% case, a local algorithm is the way to go. Think about what drove you to become vegan, and continue this strategy. If you were shocked into becoming vegan by a cube of truth, you should be participating in cubes of truth. If you became vegan after your friendly vegan neighbour exemplified that veganism is a pretty normal lifestyle and they allowed you to pick their brain about why they became vegan themselves, then you should become the friendly vegan acquaintance of the people you know yourself.

One interesting question if you enact the local algorithm, is how to weigh anecdotes. The local algorithm described above only considers your data; one alternative algorithm is to use the approach that was effective on the majority of your direct friends that became vegan before you. Another algorithm looks at all your the friends of your friends, or everyone within distance 3 in the friendship-graph. If everyone is connected by everyone by a friendship-path of length 6, then the distance 6 algorithm is exactly the data-driven approach from the second paragraph.

Evolutionary theory suggests that the small-distance algorithms are effective, for the best outreach strategy will eventually out-compete all others. But for the distance 0 or 1 cases, you’re basically working on anecdotal evidence. I’m not sure anymore what the correct value is to place on anecdotes.

Invisible people

Some people are invisible. Not really to eyes and such, but invisible in studies and statistics, we know nothing about them. They’re the dark matter of humans, but please don’t call them dark humans.

Suppose there was a gene, let’s call it gene X, that predisposes you never to participate in any study as a subject. It makes you decline all requests to record your data for research purposes and refuse to ever vote for anything.

Carriers of gene X might be at increased risk for cancer. They might be invulnerable to hemlock. They might all individually have an IQ of exactly 120.2. Maybe they never forget where they left their keys, or grow an extra belly button during their third puberty. Possibly they’re all called Alex and stop aging when 50 years old, only to suddenly die on the day they turn 90 years old. Hell, they might be 20% of the world population, favour the Libertarian Party and think Estonia should have won the last Eurovision song contest. We’d never know because nobody can study them.

On the other hand: suppose there is some subpopulation that always participates in studies, and forms a big fraction of participants in nearly any study. It makes sense to want to be a part of this subpopulation, because that way every study ever will be more descriptive of you. Luckily, you can become part of this group simply by committing to participate in every study you are asked for from now on. Except that reading this post might have caused you to make that commitment while you would never have done so yourself. You can now only become part of a new subpopulation, the one that commits to being studied after reading a participation bias-based suggestion to do so.

Tumblr RSS under GDRP

When the GDRP became effective, Tumblr decided to break its RSS feeds for all EU residents. When you try to fetch https://username.tumblr.com/rss, they’ll serve their GDRP wall instead of your requested file. You can only grab the feed if you possess the correct cookies.

Anyway, here is a hacky fix for your RSS feeds. I’m assuming you possess an http server yourself. I use a Raspberry Pi with lighttpd and selfoss. I’m assuming your user on the server is called beth, you want to follow the user called username on Tumblr and your document root is /home/beth/public.

Create the folder /home/beth/public/rss. Create the file /home/beth/.bin/fetchfeeds.sh with the following contents. Duplicate the last line once for every user you want to follow, and adjust all three occurences of username to fit.

#!/bin/bash

curl --header 'Host: username.tumblr.com' --header 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/71.0.3578.80 Chrome/71.0.3578.80 Safari/537.36' --header 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8' --header 'Accept-Language: nl,en-GB;q=0.9,en;q=0.8' --header 'Cookie: rxx=1jo2mpfhsia.1c2ecvc5&v=1; pfg=1bc46aba34ffeb83e2ef0859447d282cf8a8a2a9f95200a2a705f3afebfe9bef%23%7B%22eu_resident%22%3A1%2C%22gdpr_is_acceptable_age%22%3A1%2C%22gdpr_consent_core%22%3A1%2C%22gdpr_consent_first_party_ads%22%3A1%2C%22gdpr_consent_third_party_ads%22%3A1%2C%22gdpr_consent_search_history%22%3A1%2C%22exp%22%3A1576795974%2C%22vc%22%3A%22%22%7D%237343812268; tmgioct=5c1acbc67c0f570418402840' --header 'Connection: keep-alive' 'https://username.tumblr.com/rss' -o '/home/beth/public/rss/username-tumblr.rss' -L

[The curl command was produced using the CurlWget browser extension.]

Don’t forget to fix the permissions: chmod +x ~/.bin/fetchfeeds.sh. Now put this in your cron table by using the command crontab -e: 0 * * * * ~/.bin/fetchfeeds.sh. This will execute the bash file in the first minute of every hour.

Lastly, put http://localhost/rss/username-tumblr.rss in your RSS reader.