diff --git a/.gitignore b/.gitignore index 81fc449..47fd2d8 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,5 @@ lib #*.keys .op.* *.pyc -torpy \ No newline at end of file +torpy +*checkpoint.ipynb \ No newline at end of file diff --git a/docs/comparisons.md b/docs/comparisons.md index 2f65dd2..79d7796 100644 --- a/docs/comparisons.md +++ b/docs/comparisons.md @@ -2,34 +2,29 @@ ## Comparison of their designs -| Other cool thing | What is it? | Kind of like... | Decentralized? (P2P?) | Anonymous? (IP address undiscoverable?) | Confidential? (100% E2E encrypted?) | Data robustness? | Identity verification? | Need invitation/server? | What data can user find? | -| --------------------------------------------- | ----------------- | ------------------ | ------------------------------ | --------------------------------------------- | ------------------------------------------- | ----------------------------------- | ------------------------------------- | -------------------------------- | ----------------------------------------- | -| *[Komrade](http://komrade.app)* | *Social network* | *Twitter* | ❌ *No (central server on Tor)* | ✔️ *Yes (everything routed via Tor)* | ✔️ *Yes (100% E2EE)* | *Minimal server (deleted ASAP)* | *Yes (central public key repository)* | ***No (works like twitter)*** | Mixed (global feed; hashtag search only) | -| [Secure Scuttlebutt](https://scuttlebutt.nz/) | Social network | Twitter / Facebook | ✔️ Fully (P2P) | ❌ No (P2P reveals IP; friend networks public) | ⭕ Partly (private E2EE, public unencrypted) | Distributed across friend networks? | Yes? (federated key exchange?) | Yes (need initial pub) | Limited (search friends-of-friends' data) | -| [Diaspora](https://diasporafoundation.org/) | Social network | Twitter | ⭕ Halfway (federated) | ⭕ No (unless via Tor Browser) | ❌ No (unencrypted?) | ? | ? | Yes (need 'pod' server) | | -| [Mastodon](https://joinmastodon.org/) | Social network | Twitter | ⭕ Halfway (federated) | ⭕ No (unless via Tor Browser) | ❌ No (unencrypted?) | ? | ? | Yes (need 'instance' server) | | -| [Matrix](https://matrix.org/) | Co-working space | Slack | ⭕ Halfway (federated) | ❌ No? | ✔️ Yes? (100% E2EE) | ? | Yes (?) | Yes (invited channels only?) | | -| [Briar Messenger](https://briarproject.org/) | Messenger | WhatsApp | ✔️ Fully (P2P) | ✔️ Yes? (Tor) | ✔️ Yes (100% E2EE) | None (needs 24/7 listener) | Partly (public keys traded IRL) | Yes (need initial contact?) | | -| [Cabal Chat](https://cabal.chat/) | Private chatrooms | IRC | ✔️ Fully (P2P) | ❌ No (P2P reveals IP) 1 | ⭕ Mostly (shared key, not E2EE) | Distributed Hash Table | No (?) | Not really (public chat is open) | | -| [Signal](https://signal.org/) | Messenger | WhatsApp | ❌ No? | ❌ No | ✔️ Yes (E2EE, and audited) | ? | ? | No | Only what they send or are sent | - - -Sources: - -1. [Cabal FAQ: What kind of security is involved with Cabal?](https://cabal.chat/faq.html#:~:text=What%20kind%20of%20security%20does,is%20involved%20in%20a%20cabal) +| Other cool thing | What is it? | Kind of like... | Decentralized? (P2P?) | Anonymous? (IP hidden?) | Confidential? (100% E2EE?) | Data robustness? | Identity verification? | Requires invitation/server? | +| --------------------------------------------- | ----------------- | ------------------ | ------------------------------ | --------------------------------------------- | ------------------------------------------- | ------------------------------------- | --------------------------------------- | ---------------------------------- | +| *[Komrade](http://komrade.app)* | *Social network* | *Twitter* | ❌ *No (central server on Tor)* | ✔️ *Yes (everything routed via Tor)* | ✔️ *Yes (100% E2EE)* | ⭕ *Minimal server (deleted ASAP)* | ✔️ *Yes (central public key repository)* | ✔️ *No (works like twitter)* | +| [Secure Scuttlebutt](https://scuttlebutt.nz/) | Social network | Twitter / Facebook | ✔️ Fully (P2P) | ❌ No (P2P reveals IP; friend networks public) | ⭕ Partly (private E2EE, public unencrypted) | ✔️ Distributed across friend networks? | ✔️ Yes? (federated key exchange?) | ❌ Yes (need initial pub) | +| [Diaspora](https://diasporafoundation.org/) | Social network | Twitter | ⭕ Halfway (federated) | ⭕ No (unless via Tor Browser) | ❌ No (unencrypted?) | ✔️ | ? | ❌ Yes (need 'pod' server) | +| [Mastodon](https://joinmastodon.org/) | Social network | Twitter | ⭕ Halfway (federated) | ⭕ No (unless via Tor Browser) | ❌ No (unencrypted?) | ✔️ | ? | ❌ Yes (need 'instance' server) | +| [Matrix](https://matrix.org/) | Co-working space | Slack | ⭕ Halfway (federated) | ❌ No? | ✔️ Yes? (100% E2EE) | ? | ✔️ Yes (?) | ❌ Yes (invited channels only?) | +| [Briar Messenger](https://briarproject.org/) | Messenger | WhatsApp | ✔️ Fully (P2P) | ✔️ Yes? (Tor) | ✔️ Yes (100% E2EE) | ❌ None (needs 24/7 listener) | ⭕ Partly (public keys traded IRL) | ❌ Yes (need initial contact?) | +| [Cabal Chat](https://cabal.chat/) | Private chatrooms | IRC | ✔️ Fully (P2P) | ❌ No (P2P reveals IP) | ⭕ Mostly (shared key, not E2EE) | ✔️ Distributed Hash Table | ❌ No (?) | ✔️ Not really (public chat is open) | +| [Signal](https://signal.org/) | Messenger | WhatsApp | ❌ No? | ❌ No | ✔️ Yes (E2EE, and audited) | ? | ? | ✔️ | ## Comparison of their features -| Other cool thing | DM users (E2EE) | Group chat (E2EE) | Post to world | Post to friends/ties | Symmetric ties ('friends') | Asymmetric ties ('followers) | Like posts | Repost posts | Feed of all posts | Feed of people you follow | -| --------------------------------------------- | --------------- | ----------------- | ------------- | -------------------- | -------------------------- | ---------------------------- | ---------- | ------------ | ----------------- | ------------------------- | -| *[Komrade](http://komrade.app)* | ✔️ | ❌? | ✔️ | ✔️ | ✔️ | ✔️ | ✔️? | ❌ | ✔️ | ✔️ | -| [Secure Scuttlebutt](https://scuttlebutt.nz/) | ✔️ | ❌? | ❌ | ✔️ | ✔️ | ✔️ | ✔️ | ❌? | ❌ | ✔️ | -| [Diaspora](https://diasporafoundation.org/) | ❌? | ❌? | ❌? | ✔️ | ❌ | ✔️ | ✔️ | ✔️? | ❌ | ✔️ | -| [Mastodon](https://joinmastodon.org/) | ❌? | ❌? | ❌? | ✔️ | ❌ | ✔️ | ✔️ | ✔️? | ❌ | ✔️ | -| [Matrix](https://matrix.org/) | ✔️ | ✔️ | ❌? | ✔️ | ✔️ | ❌ | ❌? | ❌? | ❌? | ❌? | -| [Briar Messenger](https://briarproject.org/) | ✔️ | ✔️ | ❌? | ✔️ | ✔️ | ❌ | ❌? | ❌? | ❌? | ❌? | -| [Cabal Chat](https://cabal.chat/) | ? | ✔️ | ❌? | ✔️ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | -| [Signal](https://signal.org/) | ✔️ | ✔️ | ❌ | ❌ | ✔️ | ❌ | ❌ | ❌ | ❌ | ❌ | +| Other cool thing | DM users (E2EE) | Group chat (E2EE) | Post to world | Post to friends/ties | Symmetric ties (friends) | Asymmetric ties (followers) | Like posts | Repost posts | +| --------------------------------------------- | --------------- | ----------------- | ------------- | -------------------- | -------------------------- | ---------------------------- | ---------- | ------------ | +| *[Komrade](http://komrade.app)* | ✔️ | ❌? | ✔️ | ✔️ | ✔️ | ✔️ | ✔️? | ❌ | +| [Secure Scuttlebutt](https://scuttlebutt.nz/) | ✔️ | ❌? | ❌ | ✔️ | ✔️ | ✔️ | ✔️ | ❌? | +| [Diaspora](https://diasporafoundation.org/) | ❌? | ❌? | ❌? | ✔️ | ❌ | ✔️ | ✔️ | ✔️? | +| [Mastodon](https://joinmastodon.org/) | ❌? | ❌? | ❌? | ✔️ | ❌ | ✔️ | ✔️ | ✔️? | +| [Matrix](https://matrix.org/) | ✔️ | ✔️ | ❌? | ✔️ | ✔️ | ❌ | ❌? | ❌? | +| [Briar Messenger](https://briarproject.org/) | ✔️ | ✔️ | ❌? | ✔️ | ✔️ | ❌ | ❌? | ❌? | +| [Cabal Chat](https://cabal.chat/) | ? | ✔️ | ❌? | ✔️ | ❌ | ❌ | ❌ | ❌ | +| [Signal](https://signal.org/) | ✔️ | ✔️ | ❌ | ❌ | ✔️ | ❌ | ❌ | ❌ | diff --git a/docs/comparisons2.ipynb b/docs/comparisons2.ipynb new file mode 100644 index 0000000..942eeed --- /dev/null +++ b/docs/comparisons2.ipynb @@ -0,0 +1,3836 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Comparison data science for no reason" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "with open('comparisons.md') as f:\n", + " doc=f.read()" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "datasets=[]\n", + "dataset=[]\n", + "header=None\n", + "for ln in doc.split('\\n'):\n", + " ln=ln.strip()\n", + " if ln.startswith('|'):\n", + " ln=ln[1:-1]\n", + " if header==None:\n", + " header=[x.strip() for x in ln.split('|')]\n", + " else:\n", + " data=[x.strip() for x in ln.split('|')]\n", + " if not data: continue\n", + " if set(data[0])=={'-'}: continue\n", + " data_d = dict(\n", + " (h,k) for h,k\n", + " in zip(header,data)\n", + " if h and k\n", + " )\n", + "# print(data_d)\n", + " dataset.append(data_d)\n", + " else:\n", + " header=None\n", + " if dataset: datasets.append(dataset)\n", + " dataset=[]" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
What is it?Kind of like...Decentralized? (P2P?)Anonymous? (IP hidden?)Confidential? (100% E2EE?)Data robustness?Identity verification?Requires invitation/server?
Other cool thing
*[Komrade](http://komrade.app)**Social network**Twitter*❌ *No (central server on Tor)*✔️ *Yes (everything routed via Tor)*✔️ *Yes (100% E2EE)*⭕ *Minimal server (deleted ASAP)*✔️ *Yes (central public key repository)*✔️ *No (works like twitter)*
[Secure Scuttlebutt](https://scuttlebutt.nz/)Social networkTwitter / Facebook✔️ Fully (P2P)❌ No (P2P reveals IP; friend networks public)⭕ Partly (private E2EE, public unencrypted)✔️ Distributed across friend networks?✔️ Yes? (federated key exchange?)❌ Yes (need initial pub)
[Diaspora](https://diasporafoundation.org/)Social networkTwitter⭕ Halfway (federated)⭕ No (unless via Tor Browser)❌ No (unencrypted?)✔️?❌ Yes (need 'pod' server)
[Mastodon](https://joinmastodon.org/)Social networkTwitter⭕ Halfway (federated)⭕ No (unless via Tor Browser)❌ No (unencrypted?)✔️?❌ Yes (need 'instance' server)
[Matrix](https://matrix.org/)Co-working spaceSlack⭕ Halfway (federated)❌ No?✔️ Yes? (100% E2EE)?✔️ Yes (?)❌ Yes (invited channels only?)
[Briar Messenger](https://briarproject.org/)MessengerWhatsApp✔️ Fully (P2P)✔️ Yes? (Tor)✔️ Yes (100% E2EE)❌ None (needs 24/7 listener)⭕ Partly (public keys traded IRL)❌ Yes (need initial contact?)
[Cabal Chat](https://cabal.chat/)Private chatroomsIRC✔️ Fully (P2P)❌ No (P2P reveals IP)⭕ Mostly (shared key, not E2EE)✔️ Distributed Hash Table❌ No (?)✔️ Not really (public chat is open)
[Signal](https://signal.org/)MessengerWhatsApp❌ No?❌ No✔️ Yes (E2EE, and audited)??✔️
\n", + "
" + ], + "text/plain": [ + " What is it? \\\n", + "Other cool thing \n", + "*[Komrade](http://komrade.app)* *Social network* \n", + "[Secure Scuttlebutt](https://scuttlebutt.nz/) Social network \n", + "[Diaspora](https://diasporafoundation.org/) Social network \n", + "[Mastodon](https://joinmastodon.org/) Social network \n", + "[Matrix](https://matrix.org/) Co-working space \n", + "[Briar Messenger](https://briarproject.org/) Messenger \n", + "[Cabal Chat](https://cabal.chat/) Private chatrooms \n", + "[Signal](https://signal.org/) Messenger \n", + "\n", + " Kind of like... \\\n", + "Other cool thing \n", + "*[Komrade](http://komrade.app)* *Twitter* \n", + "[Secure Scuttlebutt](https://scuttlebutt.nz/) Twitter / Facebook \n", + "[Diaspora](https://diasporafoundation.org/) Twitter \n", + "[Mastodon](https://joinmastodon.org/) Twitter \n", + "[Matrix](https://matrix.org/) Slack \n", + "[Briar Messenger](https://briarproject.org/) WhatsApp \n", + "[Cabal Chat](https://cabal.chat/) IRC \n", + "[Signal](https://signal.org/) WhatsApp \n", + "\n", + " Decentralized? (P2P?) \\\n", + "Other cool thing \n", + "*[Komrade](http://komrade.app)* ❌ *No (central server on Tor)* \n", + "[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ Fully (P2P) \n", + "[Diaspora](https://diasporafoundation.org/) ⭕ Halfway (federated) \n", + "[Mastodon](https://joinmastodon.org/) ⭕ Halfway (federated) \n", + "[Matrix](https://matrix.org/) ⭕ Halfway (federated) \n", + "[Briar Messenger](https://briarproject.org/) ✔️ Fully (P2P) \n", + "[Cabal Chat](https://cabal.chat/) ✔️ Fully (P2P) \n", + "[Signal](https://signal.org/) ❌ No? \n", + "\n", + " Anonymous? (IP hidden?) \\\n", + "Other cool thing \n", + "*[Komrade](http://komrade.app)* ✔️ *Yes (everything routed via Tor)* \n", + "[Secure Scuttlebutt](https://scuttlebutt.nz/) ❌ No (P2P reveals IP; friend networks public) \n", + "[Diaspora](https://diasporafoundation.org/) ⭕ No (unless via Tor Browser) \n", + "[Mastodon](https://joinmastodon.org/) ⭕ No (unless via Tor Browser) \n", + "[Matrix](https://matrix.org/) ❌ No? \n", + "[Briar Messenger](https://briarproject.org/) ✔️ Yes? (Tor) \n", + "[Cabal Chat](https://cabal.chat/) ❌ No (P2P reveals IP) \n", + "[Signal](https://signal.org/) ❌ No \n", + "\n", + " Confidential? (100% E2EE?) \\\n", + "Other cool thing \n", + "*[Komrade](http://komrade.app)* ✔️ *Yes (100% E2EE)* \n", + "[Secure Scuttlebutt](https://scuttlebutt.nz/) ⭕ Partly (private E2EE, public unencrypted) \n", + "[Diaspora](https://diasporafoundation.org/) ❌ No (unencrypted?) \n", + "[Mastodon](https://joinmastodon.org/) ❌ No (unencrypted?) \n", + "[Matrix](https://matrix.org/) ✔️ Yes? (100% E2EE) \n", + "[Briar Messenger](https://briarproject.org/) ✔️ Yes (100% E2EE) \n", + "[Cabal Chat](https://cabal.chat/) ⭕ Mostly (shared key, not E2EE) \n", + "[Signal](https://signal.org/) ✔️ Yes (E2EE, and audited) \n", + "\n", + " Data robustness? \\\n", + "Other cool thing \n", + "*[Komrade](http://komrade.app)* ⭕ *Minimal server (deleted ASAP)* \n", + "[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ Distributed across friend networks? \n", + "[Diaspora](https://diasporafoundation.org/) ✔️ \n", + "[Mastodon](https://joinmastodon.org/) ✔️ \n", + "[Matrix](https://matrix.org/) ? \n", + "[Briar Messenger](https://briarproject.org/) ❌ None (needs 24/7 listener) \n", + "[Cabal Chat](https://cabal.chat/) ✔️ Distributed Hash Table \n", + "[Signal](https://signal.org/) ? \n", + "\n", + " Identity verification? \\\n", + "Other cool thing \n", + "*[Komrade](http://komrade.app)* ✔️ *Yes (central public key repository)* \n", + "[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ Yes? (federated key exchange?) \n", + "[Diaspora](https://diasporafoundation.org/) ? \n", + "[Mastodon](https://joinmastodon.org/) ? \n", + "[Matrix](https://matrix.org/) ✔️ Yes (?) \n", + "[Briar Messenger](https://briarproject.org/) ⭕ Partly (public keys traded IRL) \n", + "[Cabal Chat](https://cabal.chat/) ❌ No (?) \n", + "[Signal](https://signal.org/) ? \n", + "\n", + " Requires invitation/server? \n", + "Other cool thing \n", + "*[Komrade](http://komrade.app)* ✔️ *No (works like twitter)* \n", + "[Secure Scuttlebutt](https://scuttlebutt.nz/) ❌ Yes (need initial pub) \n", + "[Diaspora](https://diasporafoundation.org/) ❌ Yes (need 'pod' server) \n", + "[Mastodon](https://joinmastodon.org/) ❌ Yes (need 'instance' server) \n", + "[Matrix](https://matrix.org/) ❌ Yes (invited channels only?) \n", + "[Briar Messenger](https://briarproject.org/) ❌ Yes (need initial contact?) \n", + "[Cabal Chat](https://cabal.chat/) ✔️ Not really (public chat is open) \n", + "[Signal](https://signal.org/) ✔️ " + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import pandas as pd\n", + "df1=pd.DataFrame(datasets[0]).set_index('Other cool thing')\n", + "df1" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
DM users (E2EE)Group chat (E2EE)Post to worldPost to friends/tiesSymmetric ties (friends)Asymmetric ties (followers)Like postsRepost posts
Other cool thing
*[Komrade](http://komrade.app)*✔️❌?✔️✔️✔️✔️✔️?
[Secure Scuttlebutt](https://scuttlebutt.nz/)✔️❌?✔️✔️✔️✔️❌?
[Diaspora](https://diasporafoundation.org/)❌?❌?❌?✔️✔️✔️✔️?
[Mastodon](https://joinmastodon.org/)❌?❌?❌?✔️✔️✔️✔️?
[Matrix](https://matrix.org/)✔️✔️❌?✔️✔️❌?❌?
[Briar Messenger](https://briarproject.org/)✔️✔️❌?✔️✔️❌?❌?
[Cabal Chat](https://cabal.chat/)?✔️❌?✔️
[Signal](https://signal.org/)✔️✔️✔️
\n", + "
" + ], + "text/plain": [ + " DM users (E2EE) \\\n", + "Other cool thing \n", + "*[Komrade](http://komrade.app)* ✔️ \n", + "[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ \n", + "[Diaspora](https://diasporafoundation.org/) ❌? \n", + "[Mastodon](https://joinmastodon.org/) ❌? \n", + "[Matrix](https://matrix.org/) ✔️ \n", + "[Briar Messenger](https://briarproject.org/) ✔️ \n", + "[Cabal Chat](https://cabal.chat/) ? \n", + "[Signal](https://signal.org/) ✔️ \n", + "\n", + " Group chat (E2EE) Post to world \\\n", + "Other cool thing \n", + "*[Komrade](http://komrade.app)* ❌? ✔️ \n", + "[Secure Scuttlebutt](https://scuttlebutt.nz/) ❌? ❌ \n", + "[Diaspora](https://diasporafoundation.org/) ❌? ❌? \n", + "[Mastodon](https://joinmastodon.org/) ❌? ❌? \n", + "[Matrix](https://matrix.org/) ✔️ ❌? \n", + "[Briar Messenger](https://briarproject.org/) ✔️ ❌? \n", + "[Cabal Chat](https://cabal.chat/) ✔️ ❌? \n", + "[Signal](https://signal.org/) ✔️ ❌ \n", + "\n", + " Post to friends/ties \\\n", + "Other cool thing \n", + "*[Komrade](http://komrade.app)* ✔️ \n", + "[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ \n", + "[Diaspora](https://diasporafoundation.org/) ✔️ \n", + "[Mastodon](https://joinmastodon.org/) ✔️ \n", + "[Matrix](https://matrix.org/) ✔️ \n", + "[Briar Messenger](https://briarproject.org/) ✔️ \n", + "[Cabal Chat](https://cabal.chat/) ✔️ \n", + "[Signal](https://signal.org/) ❌ \n", + "\n", + " Symmetric ties (friends) \\\n", + "Other cool thing \n", + "*[Komrade](http://komrade.app)* ✔️ \n", + "[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ \n", + "[Diaspora](https://diasporafoundation.org/) ❌ \n", + "[Mastodon](https://joinmastodon.org/) ❌ \n", + "[Matrix](https://matrix.org/) ✔️ \n", + "[Briar Messenger](https://briarproject.org/) ✔️ \n", + "[Cabal Chat](https://cabal.chat/) ❌ \n", + "[Signal](https://signal.org/) ✔️ \n", + "\n", + " Asymmetric ties (followers) \\\n", + "Other cool thing \n", + "*[Komrade](http://komrade.app)* ✔️ \n", + "[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ \n", + "[Diaspora](https://diasporafoundation.org/) ✔️ \n", + "[Mastodon](https://joinmastodon.org/) ✔️ \n", + "[Matrix](https://matrix.org/) ❌ \n", + "[Briar Messenger](https://briarproject.org/) ❌ \n", + "[Cabal Chat](https://cabal.chat/) ❌ \n", + "[Signal](https://signal.org/) ❌ \n", + "\n", + " Like posts Repost posts \n", + "Other cool thing \n", + "*[Komrade](http://komrade.app)* ✔️? ❌ \n", + "[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ ❌? \n", + "[Diaspora](https://diasporafoundation.org/) ✔️ ✔️? \n", + "[Mastodon](https://joinmastodon.org/) ✔️ ✔️? \n", + "[Matrix](https://matrix.org/) ❌? ❌? \n", + "[Briar Messenger](https://briarproject.org/) ❌? ❌? \n", + "[Cabal Chat](https://cabal.chat/) ❌ ❌ \n", + "[Signal](https://signal.org/) ❌ ❌ " + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import pandas as pd\n", + "df2=pd.DataFrame(datasets[1]).set_index('Other cool thing')\n", + "df2" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "df = df1.join(df2)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "def transform(x):\n", + " return 1 if '✔️' in str(x) else 0\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
What is it?Kind of like...Decentralized? (P2P?)Anonymous? (IP hidden?)Confidential? (100% E2EE?)Data robustness?Identity verification?Requires invitation/server?DM users (E2EE)Group chat (E2EE)Post to worldPost to friends/tiesSymmetric ties (friends)Asymmetric ties (followers)Like postsRepost posts
Other cool thing
*[Komrade](http://komrade.app)**Social network**Twitter*❌ *No (central server on Tor)*✔️ *Yes (everything routed via Tor)*✔️ *Yes (100% E2EE)*⭕ *Minimal server (deleted ASAP)*✔️ *Yes (central public key repository)*✔️ *No (works like twitter)*✔️❌?✔️✔️✔️✔️✔️?
[Secure Scuttlebutt](https://scuttlebutt.nz/)Social networkTwitter / Facebook✔️ Fully (P2P)❌ No (P2P reveals IP; friend networks public)⭕ Partly (private E2EE, public unencrypted)✔️ Distributed across friend networks?✔️ Yes? (federated key exchange?)❌ Yes (need initial pub)✔️❌?✔️✔️✔️✔️❌?
[Diaspora](https://diasporafoundation.org/)Social networkTwitter⭕ Halfway (federated)⭕ No (unless via Tor Browser)❌ No (unencrypted?)✔️?❌ Yes (need 'pod' server)❌?❌?❌?✔️✔️✔️✔️?
[Mastodon](https://joinmastodon.org/)Social networkTwitter⭕ Halfway (federated)⭕ No (unless via Tor Browser)❌ No (unencrypted?)✔️?❌ Yes (need 'instance' server)❌?❌?❌?✔️✔️✔️✔️?
[Matrix](https://matrix.org/)Co-working spaceSlack⭕ Halfway (federated)❌ No?✔️ Yes? (100% E2EE)?✔️ Yes (?)❌ Yes (invited channels only?)✔️✔️❌?✔️✔️❌?❌?
[Briar Messenger](https://briarproject.org/)MessengerWhatsApp✔️ Fully (P2P)✔️ Yes? (Tor)✔️ Yes (100% E2EE)❌ None (needs 24/7 listener)⭕ Partly (public keys traded IRL)❌ Yes (need initial contact?)✔️✔️❌?✔️✔️❌?❌?
[Cabal Chat](https://cabal.chat/)Private chatroomsIRC✔️ Fully (P2P)❌ No (P2P reveals IP)⭕ Mostly (shared key, not E2EE)✔️ Distributed Hash Table❌ No (?)✔️ Not really (public chat is open)?✔️❌?✔️
[Signal](https://signal.org/)MessengerWhatsApp❌ No?❌ No✔️ Yes (E2EE, and audited)??✔️✔️✔️✔️
\n", + "
" + ], + "text/plain": [ + " What is it? \\\n", + "Other cool thing \n", + "*[Komrade](http://komrade.app)* *Social network* \n", + "[Secure Scuttlebutt](https://scuttlebutt.nz/) Social network \n", + "[Diaspora](https://diasporafoundation.org/) Social network \n", + "[Mastodon](https://joinmastodon.org/) Social network \n", + "[Matrix](https://matrix.org/) Co-working space \n", + "[Briar Messenger](https://briarproject.org/) Messenger \n", + "[Cabal Chat](https://cabal.chat/) Private chatrooms \n", + "[Signal](https://signal.org/) Messenger \n", + "\n", + " Kind of like... \\\n", + "Other cool thing \n", + "*[Komrade](http://komrade.app)* *Twitter* \n", + "[Secure Scuttlebutt](https://scuttlebutt.nz/) Twitter / Facebook \n", + "[Diaspora](https://diasporafoundation.org/) Twitter \n", + "[Mastodon](https://joinmastodon.org/) Twitter \n", + "[Matrix](https://matrix.org/) Slack \n", + "[Briar Messenger](https://briarproject.org/) WhatsApp \n", + "[Cabal Chat](https://cabal.chat/) IRC \n", + "[Signal](https://signal.org/) WhatsApp \n", + "\n", + " Decentralized? (P2P?) \\\n", + "Other cool thing \n", + "*[Komrade](http://komrade.app)* ❌ *No (central server on Tor)* \n", + "[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ Fully (P2P) \n", + "[Diaspora](https://diasporafoundation.org/) ⭕ Halfway (federated) \n", + "[Mastodon](https://joinmastodon.org/) ⭕ Halfway (federated) \n", + "[Matrix](https://matrix.org/) ⭕ Halfway (federated) \n", + "[Briar Messenger](https://briarproject.org/) ✔️ Fully (P2P) \n", + "[Cabal Chat](https://cabal.chat/) ✔️ Fully (P2P) \n", + "[Signal](https://signal.org/) ❌ No? \n", + "\n", + " Anonymous? (IP hidden?) \\\n", + "Other cool thing \n", + "*[Komrade](http://komrade.app)* ✔️ *Yes (everything routed via Tor)* \n", + "[Secure Scuttlebutt](https://scuttlebutt.nz/) ❌ No (P2P reveals IP; friend networks public) \n", + "[Diaspora](https://diasporafoundation.org/) ⭕ No (unless via Tor Browser) \n", + "[Mastodon](https://joinmastodon.org/) ⭕ No (unless via Tor Browser) \n", + "[Matrix](https://matrix.org/) ❌ No? \n", + "[Briar Messenger](https://briarproject.org/) ✔️ Yes? (Tor) \n", + "[Cabal Chat](https://cabal.chat/) ❌ No (P2P reveals IP) \n", + "[Signal](https://signal.org/) ❌ No \n", + "\n", + " Confidential? (100% E2EE?) \\\n", + "Other cool thing \n", + "*[Komrade](http://komrade.app)* ✔️ *Yes (100% E2EE)* \n", + "[Secure Scuttlebutt](https://scuttlebutt.nz/) ⭕ Partly (private E2EE, public unencrypted) \n", + "[Diaspora](https://diasporafoundation.org/) ❌ No (unencrypted?) \n", + "[Mastodon](https://joinmastodon.org/) ❌ No (unencrypted?) \n", + "[Matrix](https://matrix.org/) ✔️ Yes? (100% E2EE) \n", + "[Briar Messenger](https://briarproject.org/) ✔️ Yes (100% E2EE) \n", + "[Cabal Chat](https://cabal.chat/) ⭕ Mostly (shared key, not E2EE) \n", + "[Signal](https://signal.org/) ✔️ Yes (E2EE, and audited) \n", + "\n", + " Data robustness? \\\n", + "Other cool thing \n", + "*[Komrade](http://komrade.app)* ⭕ *Minimal server (deleted ASAP)* \n", + "[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ Distributed across friend networks? \n", + "[Diaspora](https://diasporafoundation.org/) ✔️ \n", + "[Mastodon](https://joinmastodon.org/) ✔️ \n", + "[Matrix](https://matrix.org/) ? \n", + "[Briar Messenger](https://briarproject.org/) ❌ None (needs 24/7 listener) \n", + "[Cabal Chat](https://cabal.chat/) ✔️ Distributed Hash Table \n", + "[Signal](https://signal.org/) ? \n", + "\n", + " Identity verification? \\\n", + "Other cool thing \n", + "*[Komrade](http://komrade.app)* ✔️ *Yes (central public key repository)* \n", + "[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ Yes? (federated key exchange?) \n", + "[Diaspora](https://diasporafoundation.org/) ? \n", + "[Mastodon](https://joinmastodon.org/) ? \n", + "[Matrix](https://matrix.org/) ✔️ Yes (?) \n", + "[Briar Messenger](https://briarproject.org/) ⭕ Partly (public keys traded IRL) \n", + "[Cabal Chat](https://cabal.chat/) ❌ No (?) \n", + "[Signal](https://signal.org/) ? \n", + "\n", + " Requires invitation/server? \\\n", + "Other cool thing \n", + "*[Komrade](http://komrade.app)* ✔️ *No (works like twitter)* \n", + "[Secure Scuttlebutt](https://scuttlebutt.nz/) ❌ Yes (need initial pub) \n", + "[Diaspora](https://diasporafoundation.org/) ❌ Yes (need 'pod' server) \n", + "[Mastodon](https://joinmastodon.org/) ❌ Yes (need 'instance' server) \n", + "[Matrix](https://matrix.org/) ❌ Yes (invited channels only?) \n", + "[Briar Messenger](https://briarproject.org/) ❌ Yes (need initial contact?) \n", + "[Cabal Chat](https://cabal.chat/) ✔️ Not really (public chat is open) \n", + "[Signal](https://signal.org/) ✔️ \n", + "\n", + " DM users (E2EE) \\\n", + "Other cool thing \n", + "*[Komrade](http://komrade.app)* ✔️ \n", + "[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ \n", + "[Diaspora](https://diasporafoundation.org/) ❌? \n", + "[Mastodon](https://joinmastodon.org/) ❌? \n", + "[Matrix](https://matrix.org/) ✔️ \n", + "[Briar Messenger](https://briarproject.org/) ✔️ \n", + "[Cabal Chat](https://cabal.chat/) ? \n", + "[Signal](https://signal.org/) ✔️ \n", + "\n", + " Group chat (E2EE) Post to world \\\n", + "Other cool thing \n", + "*[Komrade](http://komrade.app)* ❌? ✔️ \n", + "[Secure Scuttlebutt](https://scuttlebutt.nz/) ❌? ❌ \n", + "[Diaspora](https://diasporafoundation.org/) ❌? ❌? \n", + "[Mastodon](https://joinmastodon.org/) ❌? ❌? \n", + "[Matrix](https://matrix.org/) ✔️ ❌? \n", + "[Briar Messenger](https://briarproject.org/) ✔️ ❌? \n", + "[Cabal Chat](https://cabal.chat/) ✔️ ❌? \n", + "[Signal](https://signal.org/) ✔️ ❌ \n", + "\n", + " Post to friends/ties \\\n", + "Other cool thing \n", + "*[Komrade](http://komrade.app)* ✔️ \n", + "[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ \n", + "[Diaspora](https://diasporafoundation.org/) ✔️ \n", + "[Mastodon](https://joinmastodon.org/) ✔️ \n", + "[Matrix](https://matrix.org/) ✔️ \n", + "[Briar Messenger](https://briarproject.org/) ✔️ \n", + "[Cabal Chat](https://cabal.chat/) ✔️ \n", + "[Signal](https://signal.org/) ❌ \n", + "\n", + " Symmetric ties (friends) \\\n", + "Other cool thing \n", + "*[Komrade](http://komrade.app)* ✔️ \n", + "[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ \n", + "[Diaspora](https://diasporafoundation.org/) ❌ \n", + "[Mastodon](https://joinmastodon.org/) ❌ \n", + "[Matrix](https://matrix.org/) ✔️ \n", + "[Briar Messenger](https://briarproject.org/) ✔️ \n", + "[Cabal Chat](https://cabal.chat/) ❌ \n", + "[Signal](https://signal.org/) ✔️ \n", + "\n", + " Asymmetric ties (followers) \\\n", + "Other cool thing \n", + "*[Komrade](http://komrade.app)* ✔️ \n", + "[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ \n", + "[Diaspora](https://diasporafoundation.org/) ✔️ \n", + "[Mastodon](https://joinmastodon.org/) ✔️ \n", + "[Matrix](https://matrix.org/) ❌ \n", + "[Briar Messenger](https://briarproject.org/) ❌ \n", + "[Cabal Chat](https://cabal.chat/) ❌ \n", + "[Signal](https://signal.org/) ❌ \n", + "\n", + " Like posts Repost posts \n", + "Other cool thing \n", + "*[Komrade](http://komrade.app)* ✔️? ❌ \n", + "[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ ❌? \n", + "[Diaspora](https://diasporafoundation.org/) ✔️ ✔️? \n", + "[Mastodon](https://joinmastodon.org/) ✔️ ✔️? \n", + "[Matrix](https://matrix.org/) ❌? ❌? \n", + "[Briar Messenger](https://briarproject.org/) ❌? ❌? \n", + "[Cabal Chat](https://cabal.chat/) ❌ ❌ \n", + "[Signal](https://signal.org/) ❌ ❌ " + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(['*[Komrade](http://komrade.app)*',\n", + " '[Secure Scuttlebutt](https://scuttlebutt.nz/)',\n", + " '[Diaspora](https://diasporafoundation.org/)',\n", + " '[Mastodon](https://joinmastodon.org/)',\n", + " '[Matrix](https://matrix.org/)',\n", + " '[Briar Messenger](https://briarproject.org/)',\n", + " '[Cabal Chat](https://cabal.chat/)',\n", + " '[Signal](https://signal.org/)'],\n", + " ['What is it?',\n", + " 'Kind of like...',\n", + " 'Decentralized? (P2P?)',\n", + " 'Anonymous? (IP hidden?)',\n", + " 'Confidential? (100% E2EE?)',\n", + " 'Data robustness?',\n", + " 'Identity verification?',\n", + " 'Requires invitation/server?',\n", + " 'DM users (E2EE)',\n", + " 'Group chat (E2EE)',\n", + " 'Post to world',\n", + " 'Post to friends/ties',\n", + " 'Symmetric ties (friends)',\n", + " 'Asymmetric ties (followers)',\n", + " 'Like posts',\n", + " 'Repost posts'])" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "index_orig = list(df.index)\n", + "cols_orig = list(df.columns)\n", + "index_orig, cols_orig" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
What is it?Kind of like...Decentralized? (P2P?)Anonymous? (IP hidden?)Confidential? (100% E2EE?)Data robustness?Identity verification?Requires invitation/server?DM users (E2EE)Group chat (E2EE)Post to worldPost to friends/tiesSymmetric ties (friends)Asymmetric ties (followers)Like postsRepost posts
Komrade*Social network**Twitter*❌ *No (central server on Tor)*✔️ *Yes (everything routed via Tor)*✔️ *Yes (100% E2EE)*⭕ *Minimal server (deleted ASAP)*✔️ *Yes (central public key repository)*✔️ *No (works like twitter)*✔️❌?✔️✔️✔️✔️✔️?
SecureScuttlebuttSocial networkTwitter / Facebook✔️ Fully (P2P)❌ No (P2P reveals IP; friend networks public)⭕ Partly (private E2EE, public unencrypted)✔️ Distributed across friend networks?✔️ Yes? (federated key exchange?)❌ Yes (need initial pub)✔️❌?✔️✔️✔️✔️❌?
DiasporaSocial networkTwitter⭕ Halfway (federated)⭕ No (unless via Tor Browser)❌ No (unencrypted?)✔️?❌ Yes (need 'pod' server)❌?❌?❌?✔️✔️✔️✔️?
MastodonSocial networkTwitter⭕ Halfway (federated)⭕ No (unless via Tor Browser)❌ No (unencrypted?)✔️?❌ Yes (need 'instance' server)❌?❌?❌?✔️✔️✔️✔️?
MatrixCo-working spaceSlack⭕ Halfway (federated)❌ No?✔️ Yes? (100% E2EE)?✔️ Yes (?)❌ Yes (invited channels only?)✔️✔️❌?✔️✔️❌?❌?
BriarMessengerMessengerWhatsApp✔️ Fully (P2P)✔️ Yes? (Tor)✔️ Yes (100% E2EE)❌ None (needs 24/7 listener)⭕ Partly (public keys traded IRL)❌ Yes (need initial contact?)✔️✔️❌?✔️✔️❌?❌?
CabalChatPrivate chatroomsIRC✔️ Fully (P2P)❌ No (P2P reveals IP)⭕ Mostly (shared key, not E2EE)✔️ Distributed Hash Table❌ No (?)✔️ Not really (public chat is open)?✔️❌?✔️
SignalMessengerWhatsApp❌ No?❌ No✔️ Yes (E2EE, and audited)??✔️✔️✔️✔️
\n", + "
" + ], + "text/plain": [ + " What is it? Kind of like... \\\n", + "Komrade *Social network* *Twitter* \n", + "SecureScuttlebutt Social network Twitter / Facebook \n", + "Diaspora Social network Twitter \n", + "Mastodon Social network Twitter \n", + "Matrix Co-working space Slack \n", + "BriarMessenger Messenger WhatsApp \n", + "CabalChat Private chatrooms IRC \n", + "Signal Messenger WhatsApp \n", + "\n", + " Decentralized? (P2P?) \\\n", + "Komrade ❌ *No (central server on Tor)* \n", + "SecureScuttlebutt ✔️ Fully (P2P) \n", + "Diaspora ⭕ Halfway (federated) \n", + "Mastodon ⭕ Halfway (federated) \n", + "Matrix ⭕ Halfway (federated) \n", + "BriarMessenger ✔️ Fully (P2P) \n", + "CabalChat ✔️ Fully (P2P) \n", + "Signal ❌ No? \n", + "\n", + " Anonymous? (IP hidden?) \\\n", + "Komrade ✔️ *Yes (everything routed via Tor)* \n", + "SecureScuttlebutt ❌ No (P2P reveals IP; friend networks public) \n", + "Diaspora ⭕ No (unless via Tor Browser) \n", + "Mastodon ⭕ No (unless via Tor Browser) \n", + "Matrix ❌ No? \n", + "BriarMessenger ✔️ Yes? (Tor) \n", + "CabalChat ❌ No (P2P reveals IP) \n", + "Signal ❌ No \n", + "\n", + " Confidential? (100% E2EE?) \\\n", + "Komrade ✔️ *Yes (100% E2EE)* \n", + "SecureScuttlebutt ⭕ Partly (private E2EE, public unencrypted) \n", + "Diaspora ❌ No (unencrypted?) \n", + "Mastodon ❌ No (unencrypted?) \n", + "Matrix ✔️ Yes? (100% E2EE) \n", + "BriarMessenger ✔️ Yes (100% E2EE) \n", + "CabalChat ⭕ Mostly (shared key, not E2EE) \n", + "Signal ✔️ Yes (E2EE, and audited) \n", + "\n", + " Data robustness? \\\n", + "Komrade ⭕ *Minimal server (deleted ASAP)* \n", + "SecureScuttlebutt ✔️ Distributed across friend networks? \n", + "Diaspora ✔️ \n", + "Mastodon ✔️ \n", + "Matrix ? \n", + "BriarMessenger ❌ None (needs 24/7 listener) \n", + "CabalChat ✔️ Distributed Hash Table \n", + "Signal ? \n", + "\n", + " Identity verification? \\\n", + "Komrade ✔️ *Yes (central public key repository)* \n", + "SecureScuttlebutt ✔️ Yes? (federated key exchange?) \n", + "Diaspora ? \n", + "Mastodon ? \n", + "Matrix ✔️ Yes (?) \n", + "BriarMessenger ⭕ Partly (public keys traded IRL) \n", + "CabalChat ❌ No (?) \n", + "Signal ? \n", + "\n", + " Requires invitation/server? DM users (E2EE) \\\n", + "Komrade ✔️ *No (works like twitter)* ✔️ \n", + "SecureScuttlebutt ❌ Yes (need initial pub) ✔️ \n", + "Diaspora ❌ Yes (need 'pod' server) ❌? \n", + "Mastodon ❌ Yes (need 'instance' server) ❌? \n", + "Matrix ❌ Yes (invited channels only?) ✔️ \n", + "BriarMessenger ❌ Yes (need initial contact?) ✔️ \n", + "CabalChat ✔️ Not really (public chat is open) ? \n", + "Signal ✔️ ✔️ \n", + "\n", + " Group chat (E2EE) Post to world Post to friends/ties \\\n", + "Komrade ❌? ✔️ ✔️ \n", + "SecureScuttlebutt ❌? ❌ ✔️ \n", + "Diaspora ❌? ❌? ✔️ \n", + "Mastodon ❌? ❌? ✔️ \n", + "Matrix ✔️ ❌? ✔️ \n", + "BriarMessenger ✔️ ❌? ✔️ \n", + "CabalChat ✔️ ❌? ✔️ \n", + "Signal ✔️ ❌ ❌ \n", + "\n", + " Symmetric ties (friends) Asymmetric ties (followers) \\\n", + "Komrade ✔️ ✔️ \n", + "SecureScuttlebutt ✔️ ✔️ \n", + "Diaspora ❌ ✔️ \n", + "Mastodon ❌ ✔️ \n", + "Matrix ✔️ ❌ \n", + "BriarMessenger ✔️ ❌ \n", + "CabalChat ❌ ❌ \n", + "Signal ✔️ ❌ \n", + "\n", + " Like posts Repost posts \n", + "Komrade ✔️? ❌ \n", + "SecureScuttlebutt ✔️ ❌? \n", + "Diaspora ✔️ ✔️? \n", + "Mastodon ✔️ ✔️? \n", + "Matrix ❌? ❌? \n", + "BriarMessenger ❌? ❌? \n", + "CabalChat ❌ ❌ \n", + "Signal ❌ ❌ " + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_safe = pd.DataFrame(df)\n", + "df_safe.index = [x.split('[')[1].split(']')[0].replace(' ','') for x in index_orig]\n", + "df_safe" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "df.columns = [\n", + " #''.join(x for x in col.split('(')[0] if x.isalpha())\n", + " col\n", + " for col in cols_orig\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
What is it?Kind of like...Decentralized? (P2P?)Anonymous? (IP hidden?)Confidential? (100% E2EE?)Data robustness?Identity verification?Requires invitation/server?DM users (E2EE)Group chat (E2EE)Post to worldPost to friends/tiesSymmetric ties (friends)Asymmetric ties (followers)Like postsRepost posts
Komrade*Social network**Twitter*❌ *No (central server on Tor)*✔️ *Yes (everything routed via Tor)*✔️ *Yes (100% E2EE)*⭕ *Minimal server (deleted ASAP)*✔️ *Yes (central public key repository)*✔️ *No (works like twitter)*✔️❌?✔️✔️✔️✔️✔️?
SecureScuttlebuttSocial networkTwitter / Facebook✔️ Fully (P2P)❌ No (P2P reveals IP; friend networks public)⭕ Partly (private E2EE, public unencrypted)✔️ Distributed across friend networks?✔️ Yes? (federated key exchange?)❌ Yes (need initial pub)✔️❌?✔️✔️✔️✔️❌?
DiasporaSocial networkTwitter⭕ Halfway (federated)⭕ No (unless via Tor Browser)❌ No (unencrypted?)✔️?❌ Yes (need 'pod' server)❌?❌?❌?✔️✔️✔️✔️?
MastodonSocial networkTwitter⭕ Halfway (federated)⭕ No (unless via Tor Browser)❌ No (unencrypted?)✔️?❌ Yes (need 'instance' server)❌?❌?❌?✔️✔️✔️✔️?
MatrixCo-working spaceSlack⭕ Halfway (federated)❌ No?✔️ Yes? (100% E2EE)?✔️ Yes (?)❌ Yes (invited channels only?)✔️✔️❌?✔️✔️❌?❌?
BriarMessengerMessengerWhatsApp✔️ Fully (P2P)✔️ Yes? (Tor)✔️ Yes (100% E2EE)❌ None (needs 24/7 listener)⭕ Partly (public keys traded IRL)❌ Yes (need initial contact?)✔️✔️❌?✔️✔️❌?❌?
CabalChatPrivate chatroomsIRC✔️ Fully (P2P)❌ No (P2P reveals IP)⭕ Mostly (shared key, not E2EE)✔️ Distributed Hash Table❌ No (?)✔️ Not really (public chat is open)?✔️❌?✔️
SignalMessengerWhatsApp❌ No?❌ No✔️ Yes (E2EE, and audited)??✔️✔️✔️✔️
\n", + "
" + ], + "text/plain": [ + " What is it? Kind of like... \\\n", + "Komrade *Social network* *Twitter* \n", + "SecureScuttlebutt Social network Twitter / Facebook \n", + "Diaspora Social network Twitter \n", + "Mastodon Social network Twitter \n", + "Matrix Co-working space Slack \n", + "BriarMessenger Messenger WhatsApp \n", + "CabalChat Private chatrooms IRC \n", + "Signal Messenger WhatsApp \n", + "\n", + " Decentralized? (P2P?) \\\n", + "Komrade ❌ *No (central server on Tor)* \n", + "SecureScuttlebutt ✔️ Fully (P2P) \n", + "Diaspora ⭕ Halfway (federated) \n", + "Mastodon ⭕ Halfway (federated) \n", + "Matrix ⭕ Halfway (federated) \n", + "BriarMessenger ✔️ Fully (P2P) \n", + "CabalChat ✔️ Fully (P2P) \n", + "Signal ❌ No? \n", + "\n", + " Anonymous? (IP hidden?) \\\n", + "Komrade ✔️ *Yes (everything routed via Tor)* \n", + "SecureScuttlebutt ❌ No (P2P reveals IP; friend networks public) \n", + "Diaspora ⭕ No (unless via Tor Browser) \n", + "Mastodon ⭕ No (unless via Tor Browser) \n", + "Matrix ❌ No? \n", + "BriarMessenger ✔️ Yes? (Tor) \n", + "CabalChat ❌ No (P2P reveals IP) \n", + "Signal ❌ No \n", + "\n", + " Confidential? (100% E2EE?) \\\n", + "Komrade ✔️ *Yes (100% E2EE)* \n", + "SecureScuttlebutt ⭕ Partly (private E2EE, public unencrypted) \n", + "Diaspora ❌ No (unencrypted?) \n", + "Mastodon ❌ No (unencrypted?) \n", + "Matrix ✔️ Yes? (100% E2EE) \n", + "BriarMessenger ✔️ Yes (100% E2EE) \n", + "CabalChat ⭕ Mostly (shared key, not E2EE) \n", + "Signal ✔️ Yes (E2EE, and audited) \n", + "\n", + " Data robustness? \\\n", + "Komrade ⭕ *Minimal server (deleted ASAP)* \n", + "SecureScuttlebutt ✔️ Distributed across friend networks? \n", + "Diaspora ✔️ \n", + "Mastodon ✔️ \n", + "Matrix ? \n", + "BriarMessenger ❌ None (needs 24/7 listener) \n", + "CabalChat ✔️ Distributed Hash Table \n", + "Signal ? \n", + "\n", + " Identity verification? \\\n", + "Komrade ✔️ *Yes (central public key repository)* \n", + "SecureScuttlebutt ✔️ Yes? (federated key exchange?) \n", + "Diaspora ? \n", + "Mastodon ? \n", + "Matrix ✔️ Yes (?) \n", + "BriarMessenger ⭕ Partly (public keys traded IRL) \n", + "CabalChat ❌ No (?) \n", + "Signal ? \n", + "\n", + " Requires invitation/server? DM users (E2EE) \\\n", + "Komrade ✔️ *No (works like twitter)* ✔️ \n", + "SecureScuttlebutt ❌ Yes (need initial pub) ✔️ \n", + "Diaspora ❌ Yes (need 'pod' server) ❌? \n", + "Mastodon ❌ Yes (need 'instance' server) ❌? \n", + "Matrix ❌ Yes (invited channels only?) ✔️ \n", + "BriarMessenger ❌ Yes (need initial contact?) ✔️ \n", + "CabalChat ✔️ Not really (public chat is open) ? \n", + "Signal ✔️ ✔️ \n", + "\n", + " Group chat (E2EE) Post to world Post to friends/ties \\\n", + "Komrade ❌? ✔️ ✔️ \n", + "SecureScuttlebutt ❌? ❌ ✔️ \n", + "Diaspora ❌? ❌? ✔️ \n", + "Mastodon ❌? ❌? ✔️ \n", + "Matrix ✔️ ❌? ✔️ \n", + "BriarMessenger ✔️ ❌? ✔️ \n", + "CabalChat ✔️ ❌? ✔️ \n", + "Signal ✔️ ❌ ❌ \n", + "\n", + " Symmetric ties (friends) Asymmetric ties (followers) \\\n", + "Komrade ✔️ ✔️ \n", + "SecureScuttlebutt ✔️ ✔️ \n", + "Diaspora ❌ ✔️ \n", + "Mastodon ❌ ✔️ \n", + "Matrix ✔️ ❌ \n", + "BriarMessenger ✔️ ❌ \n", + "CabalChat ❌ ❌ \n", + "Signal ✔️ ❌ \n", + "\n", + " Like posts Repost posts \n", + "Komrade ✔️? ❌ \n", + "SecureScuttlebutt ✔️ ❌? \n", + "Diaspora ✔️ ✔️? \n", + "Mastodon ✔️ ✔️? \n", + "Matrix ❌? ❌? \n", + "BriarMessenger ❌? ❌? \n", + "CabalChat ❌ ❌ \n", + "Signal ❌ ❌ " + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "df_data = df.applymap(transform).drop('What is it?',1).drop('Kind of like...',1)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Decentralized? (P2P?)Anonymous? (IP hidden?)Confidential? (100% E2EE?)Data robustness?Identity verification?Requires invitation/server?DM users (E2EE)Group chat (E2EE)Post to worldPost to friends/tiesSymmetric ties (friends)Asymmetric ties (followers)Like postsRepost posts
Komrade01101110111110
SecureScuttlebutt10011010011110
Diaspora00010000010111
Mastodon00010000010111
Matrix00101011011000
BriarMessenger11100011011000
CabalChat10010101010000
Signal00100111001000
\n", + "
" + ], + "text/plain": [ + " Decentralized? (P2P?) Anonymous? (IP hidden?) \\\n", + "Komrade 0 1 \n", + "SecureScuttlebutt 1 0 \n", + "Diaspora 0 0 \n", + "Mastodon 0 0 \n", + "Matrix 0 0 \n", + "BriarMessenger 1 1 \n", + "CabalChat 1 0 \n", + "Signal 0 0 \n", + "\n", + " Confidential? (100% E2EE?) Data robustness? \\\n", + "Komrade 1 0 \n", + "SecureScuttlebutt 0 1 \n", + "Diaspora 0 1 \n", + "Mastodon 0 1 \n", + "Matrix 1 0 \n", + "BriarMessenger 1 0 \n", + "CabalChat 0 1 \n", + "Signal 1 0 \n", + "\n", + " Identity verification? Requires invitation/server? \\\n", + "Komrade 1 1 \n", + "SecureScuttlebutt 1 0 \n", + "Diaspora 0 0 \n", + "Mastodon 0 0 \n", + "Matrix 1 0 \n", + "BriarMessenger 0 0 \n", + "CabalChat 0 1 \n", + "Signal 0 1 \n", + "\n", + " DM users (E2EE) Group chat (E2EE) Post to world \\\n", + "Komrade 1 0 1 \n", + "SecureScuttlebutt 1 0 0 \n", + "Diaspora 0 0 0 \n", + "Mastodon 0 0 0 \n", + "Matrix 1 1 0 \n", + "BriarMessenger 1 1 0 \n", + "CabalChat 0 1 0 \n", + "Signal 1 1 0 \n", + "\n", + " Post to friends/ties Symmetric ties (friends) \\\n", + "Komrade 1 1 \n", + "SecureScuttlebutt 1 1 \n", + "Diaspora 1 0 \n", + "Mastodon 1 0 \n", + "Matrix 1 1 \n", + "BriarMessenger 1 1 \n", + "CabalChat 1 0 \n", + "Signal 0 1 \n", + "\n", + " Asymmetric ties (followers) Like posts Repost posts \n", + "Komrade 1 1 0 \n", + "SecureScuttlebutt 1 1 0 \n", + "Diaspora 1 1 1 \n", + "Mastodon 1 1 1 \n", + "Matrix 0 0 0 \n", + "BriarMessenger 0 0 0 \n", + "CabalChat 0 0 0 \n", + "Signal 0 0 0 " + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_data" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "from scipy.spatial.distance import squareform, pdist" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([2.44948974, 3. , 3. , 2.44948974, 2.64575131,\n", + " 3.31662479, 2.64575131, 2.23606798, 2.23606798, 2.44948974,\n", + " 2.64575131, 2.64575131, 3. , 0. , 3. ,\n", + " 3.16227766, 2.44948974, 3.16227766, 3. , 3.16227766,\n", + " 2.44948974, 3.16227766, 1.73205081, 2.64575131, 1.73205081,\n", + " 2.44948974, 2. , 2.44948974])" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pdist(df_data)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "def make_dist(X_dtm,dist_metric='euclidean',standardize=True):\n", + " distmatrix=pdist(X_dtm,metric=dist_metric)\n", + " return pd.DataFrame(squareform(distmatrix), columns=X_dtm.index, index=X_dtm.index)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
KomradeSecureScuttlebuttDiasporaMastodonMatrixBriarMessengerCabalChatSignal
Komrade0.0000002.4494903.0000003.0000002.4494902.6457513.3166252.645751
SecureScuttlebutt2.4494900.0000002.2360682.2360682.4494902.6457512.6457513.000000
Diaspora3.0000002.2360680.0000000.0000003.0000003.1622782.4494903.162278
Mastodon3.0000002.2360680.0000000.0000003.0000003.1622782.4494903.162278
Matrix2.4494902.4494903.0000003.0000000.0000001.7320512.6457511.732051
BriarMessenger2.6457512.6457513.1622783.1622781.7320510.0000002.4494902.000000
CabalChat3.3166252.6457512.4494902.4494902.6457512.4494900.0000002.449490
Signal2.6457513.0000003.1622783.1622781.7320512.0000002.4494900.000000
\n", + "
" + ], + "text/plain": [ + " Komrade SecureScuttlebutt Diaspora Mastodon Matrix \\\n", + "Komrade 0.000000 2.449490 3.000000 3.000000 2.449490 \n", + "SecureScuttlebutt 2.449490 0.000000 2.236068 2.236068 2.449490 \n", + "Diaspora 3.000000 2.236068 0.000000 0.000000 3.000000 \n", + "Mastodon 3.000000 2.236068 0.000000 0.000000 3.000000 \n", + "Matrix 2.449490 2.449490 3.000000 3.000000 0.000000 \n", + "BriarMessenger 2.645751 2.645751 3.162278 3.162278 1.732051 \n", + "CabalChat 3.316625 2.645751 2.449490 2.449490 2.645751 \n", + "Signal 2.645751 3.000000 3.162278 3.162278 1.732051 \n", + "\n", + " BriarMessenger CabalChat Signal \n", + "Komrade 2.645751 3.316625 2.645751 \n", + "SecureScuttlebutt 2.645751 2.645751 3.000000 \n", + "Diaspora 3.162278 2.449490 3.162278 \n", + "Mastodon 3.162278 2.449490 3.162278 \n", + "Matrix 1.732051 2.645751 1.732051 \n", + "BriarMessenger 0.000000 2.449490 2.000000 \n", + "CabalChat 2.449490 0.000000 2.449490 \n", + "Signal 2.000000 2.449490 0.000000 " + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_dist = make_dist(df_data)\n", + "df_dist" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "# df_dist['Signal'].sort_values()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Viz" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "from scipy.cluster.hierarchy import dendrogram, linkage\n", + "from matplotlib import pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 2. , 3. , 0. , 2. ],\n", + " [ 4. , 5. , 1.73205081, 2. ],\n", + " [ 7. , 9. , 2. , 3. ],\n", + " [ 1. , 8. , 2.23606798, 3. ],\n", + " [ 0. , 10. , 2.64575131, 4. ],\n", + " [ 6. , 11. , 2.64575131, 4. ],\n", + " [12. , 13. , 3.31662479, 8. ]])" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Here it is: in a single line, compute a hierarchical clustering of the DTM\n", + "\n", + "hclust = linkage(df_data,method='complete')\n", + "hclust" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "def fancy_dendrogram(*args, **kwargs):\n", + " max_d = kwargs.pop('max_d', None)\n", + " if max_d and 'color_threshold' not in kwargs:\n", + " kwargs['color_threshold'] = max_d\n", + " annotate_above = kwargs.pop('annotate_above', 0)\n", + "\n", + " ddata = dendrogram(*args, **kwargs)\n", + "\n", + " if not kwargs.get('no_plot', False):\n", + " plt.title('Hierarchical Clustering Dendrogram')\n", + " plt.xlabel('sample index or (cluster size)')\n", + " plt.ylabel('distance')\n", + " for i, d, c in zip(ddata['icoord'], ddata['dcoord'], ddata['color_list']):\n", + " x = 0.5 * sum(i[1:3])\n", + " y = d[1]\n", + " if y > annotate_above:\n", + " plt.plot(x, y, 'o', c=c)\n", + " plt.annotate(\"%.3g\" % y, (x, y), xytext=(0, -5),\n", + " textcoords='offset points',\n", + " va='top', ha='center')\n", + " if max_d:\n", + " plt.axhline(y=max_d, c='k')\n", + " return ddata" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [], + "source": [ + "def plot_dendrogram(dtm,linkage_method='complete'):\n", + " \n", + " hclust = linkage(dtm,method=linkage_method)\n", + " \n", + " fig, ax = plt.subplots(figsize=(20, 8))\n", + " plt.title('Hierarchical Clustering Dendrogram (truncated)')\n", + " plt.xlabel('sample index')\n", + " plt.ylabel('distance')\n", + " fancy_dendrogram(\n", + " hclust,\n", + " show_leaf_counts=False, # otherwise numbers in brackets are counts\n", + " leaf_rotation=90.,\n", + " leaf_font_size=12.,\n", + " show_contracted=True, # to get a distribution impression in truncated branches\n", + " labels=dtm.index,\n", + " )\n", + " plt.savefig('fig.hclust-apps.png')\n", + " plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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JEmSJEmSVGlg3QEkSVI9LrpzIj/484M8OWUGqw1akqN23ZAPbD607liSJElqMZZHkiT1QxfdOZGvXXgPM2bOBmDilBl87cJ7ACyQJEmSNBfLI6lN/PaWJ7h43MS6Y0jqI+58YgqvzX59rmMzZs7myxfcze9ufaKmVJL6kr1GDuWALYfVHUOS9BZwzSOpTVw8biL3T5padwxJfUTn4mhBxyWpJ+6fNNVfeklSH+LII6mNbLzqcpz/ya3rjiGpD9jmhOuYOGXGPMeHDlrSv2ckvWkfOe2muiNIkt5CjjySJKkfOmrXDVly0QFzHVty0QEcteuGNSWSJElSq3LkkSRJ/VDHotjutiZJkqQFsTySJKmf+sDmQy2LJEmStEBOW5MkqY965ZVX2GKLLXj729/OiBEjOOaYY+a55tRTT2XTTTdl5MiRbLvtttx///0AXHPNNYwePZpNN92U0aNHc9111/V2fEmSJLUIRx5JktRHLb744lx33XUss8wyzJw5k2233Zbdd9+drbbaas41BxxwAEcccQQAl1xyCUceeSRXXXUVK6+8MpdeeimrrbYa9957L7vuuisTJ7pzkiRJUn9keSRJUh8VESyzzDIAzJw5k5kzZxIRc12z3HLLzbk9ffr0Oec333zzOcdHjBjBjBkzePXVV1l88cV7IbkkSZJaieWRJEl92OzZsxk9ejQPP/wwn/nMZ9hyyy3nueanP/0pP/rRj3jttde6nJ72xz/+kVGjRlkcSZIk9VOueSRJUh82YMAAxo0bx4QJE7j11lu5995757nmM5/5DI888ggnnngi3/72t+c6d9999/GVr3yF0047rbciS5IkqcVYHkmS1A8MGjSIHXfckauuuqrymv3224+LLrpozv0JEybwwQ9+kLPPPpt11123F1JKkiSpFVkeSZLUR02ePJkpU6YAMGPGDK655ho22mijua7597//Pef25Zdfzvrrrw/AlClT2GOPPTjhhBPYZpttei2zJEmSWo9rHkmS1EdNmjSJgw46iNmzZ/P666/z4Q9/mD333JOjjz6aMWPG8P73v59TTjmFv/zlLyy66KKssMIKnHXWWQCccsopPPzwwxx//PEcf/zxAFx99dUMGTKkzpckSZKkGkRm1p2hR8aMGZNjx46tO4bU6z5y2k0AnP/JrWtOIkmSNH++b5Gk9hMRt2fmmK7OOW1NkiRJkiRJlSyPJEmSJEmSVMnySJIkSZIkSZUsjyRJkiRJklTJ8kiSJEmSJEmVLI8kSZIkSZJUyfJIkiRJkiRJlSyPJEmSJEmSVMnySJIkSZIkSZUsjyRJkiRJklTJ8kiSJEmSJEmVLI8kSZIkSZJUyfJIkiRJkiRJlSyPJEmSJEmSVMnySJIkSZIkSZUsjyRJkiRJklTJ8kiSJEmSJEmVLI8kSZIkSZJUyfJIkiRJkiRJlSyPJEmSJEmSVMnySJIkSZIkSZWaVh5FxBIRcWtE3BUR90XEcV1cs3hEnB8RD0fELRGxVrPySJIkSZIkqeeaOfLoVWCnzHw7MBLYLSK26nTNocALmbke8GPgxCbmkSRJkiRJUg81rTzKwkvl3UXLP9npsr2As8rbFwDvjohoViZJkiRJkiT1TFPXPIqIARExDngGuCYzb+l0yVBgPEBmzgJeBFZqZiZJkiRJkiR1X1PLo8ycnZkjgdWBLSJik4V5nIg4PCLGRsTYyZMnv6UZJUmSJEmSVK1XdlvLzCnA9cBunU5NBNYAiIiBwPLAc118/OmZOSYzxwwePLjJaSVJkiRJktShmbutDY6IQeXtJYGdgX91uuwS4KDy9r7AdZnZeV0kSZIkSZIk1WRgEx97VeCsiBhAUVL9PjMvi4jjgbGZeQlwBnBORDwMPA/s18Q8kiRJkiRJ6qGmlUeZeTeweRfHj264/QrwoWZlkCRJkiRJ0pvTK2seSZIkSZIkqT1ZHkmSJEmSJKmS5ZEkSZIkSZIqWR5JkiRJkiSpkuWRJEmSJEmSKlkeSZIkSZIkqZLlkSRJkiRJkipZHkmSJEmSJKmS5ZEkSZIkSZIqWR5JkiRJkiSpkuWRJEmSJEmSKlkeSZIkSZIkqZLlkSRJkiRJkipZHkmSJEmSJKmS5ZEkSZIkSZIqWR5JkiRJkiSpkuWRJEmSJEmSKlkeSZIkSZIkqZLlkSRJkiRJkipZHkmSJEmSJKmS5ZEkSZIkSZIqWR5JkiRJkiSpkuWRJEmSJEmSKlkeSZIkSZIkqZLlkSRJkiRJkipZHkmSJEmSJKmS5ZEkSZIkSZIqWR5JkiRJkiSpkuWRJEmSJEmSKlkeSZIkSZIkqZLlkSRJkiRJkipZHkmSJEmSJKmS5ZEkSZIkSZIqWR5JkiRJkiSpkuWRJEmSJEmSKlkeSZIkSZIkqZLlkSRJkiRJkipZHklt4KI7J3LnE1O45T/Ps80J13HRnRPrjiRJktQl37dIUt9jeSS1uIvunMjXLryH12a/DsDEKTP42oX3+EZMkiS1HN+3SFLfFJlZd4YeGTNmTI4dO7buGC3lt7c8wcXj/Ae5r7rziSlz3oA1WmzAImw+bFDvB1LT7TVyKAdsOazuGJLUFL5v6dt839L/+L5F6jsi4vbMHNPVOUce9QEXj5vI/ZOm1h1DTdLVG7D5HVd7u3/SVH+oktSn+b6lb/N9S//i+xap/xhYdwC9NTZedTnO/+TWdcdQE2xzwnVMnDJjnuNDBy3p17wP+shpN9UdQZKazvctfZfvW/oX37dI/Ycjj6QWd9SuG7LkogPmOrbkogM4atcNa0okSZLUNd+3SFLf5MgjqcV9YPOhAPzgzw/y5JQZrDZoSY7adcM5xyVJklqF71skqW+yPJLawAc2H+qbLkmS1BZ83yJJfY/T1qQWMH78eHbccUc23nhjRowYwcknn9zldX/9618ZOXIkI0aMYPvtt59zfK211mLTTTdl5MiRjBnT5eL4kiRJbwnft0hS/+PII6kFDBw4kB/+8IeMGjWKadOmMXr0aHbeeWc23njjOddMmTKFT3/601x11VUMGzaMZ555Zq7HuP7661l55ZV7O7okSepnfN8iSf2PI4+kFrDqqqsyatQoAJZddlmGDx/OxIlzb3v629/+lr333pthw4YBMGTIkF7PKUmS5PsWSep/LI+kFvPYY49x5513suWWW851/KGHHuKFF15ghx12YPTo0Zx99tlzzkUEu+yyC6NHj+b000/v7ciSJKmf8n2LJPUPTluTWshLL73EPvvsw0knncRyyy0317lZs2Zx++23c+211zJjxgy23nprttpqKzbYYANuuOEGhg4dyjPPPMPOO+/MRhttxHbbbVfTq5AkSf2B71skqf9w5JHUImbOnMk+++zDgQceyN577z3P+dVXX51dd92VpZdempVXXpntttuOu+66C4ChQ4sdTYYMGcIHP/hBbr311l7NLkmS+hfft0hS/2J5JLWAzOTQQw9l+PDhHHnkkV1es9dee3HDDTcwa9YsXn75ZW655RaGDx/O9OnTmTZtGgDTp0/n6quvZpNNNunN+JIkqR/xfYsk9T9OW5NawI033sg555wzZ9tagO9+97s88cQTABxxxBEMHz6c3Xbbjc02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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plot_dendrogram(df_data)" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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JElSpRF1B5AkSRoqLrh1Ej/4031MnjaLMaOW4Iid1uNdm61SdyxJkqQBsXgkSZK0AFxw6ySOPP9OZs2eA8CkabM48vw7ASwgSZKktmbxSNKwd+YNj3LhbZPqjiGpzd366DRemjN3nm2zZs/h87+/g7NufLSmVJLa3Z7jVuEDW61edwxJw5w9jyQNexfeNom7pzxbdwxJba5z4ain7ZLUk7unPOsFLkktwZFHkgSMHb0053x867pjSGpjbzr6KiZNmzXf9lVGLeH7i6R+ed8vr687giQBjjySJElaII7YaT2WWGThebYtscjCHLHTejUlkiRJWjAceSRJkrQAdDTFdrU1SZI01Fg8kiRJWkDetdkqFoskSdKQ47Q1SZIkSZIkVbJ4JEmS1AsTJkxghx12YOzYsWy44YYcf/zx8+0zffp0dt99dzbddFM23HBDTjnlFAAeeeQRxo8fz7hx49hwww058cQTBzu+JElSvzltTZIkqRdGjBjBj370I8aPH8+MGTPYfPPN2XHHHRk7duwr+/zsZz9j7NixXHzxxTz55JOst9567LfffowePZrrr7+exRZbjJkzZ7LRRhuxxx57MGbMmBp/IkmSpN5x5JEkSVIvjB49mvHjxwMwcuRINthgAyZNmjTPPhHBjBkzyExmzpzJcsstx4gRI1h00UVZbLHFAHjxxReZO3fuoOeXJEnqL4tHkiRJffTwww9z6623stVWW82z/VOf+hT33HMPY8aMYeONN+b4449noYWKw60JEyawySabsNpqq/GFL3zBUUeSJKltWDySJEnqg5kzZ7L33ntz3HHHsfTSS8/z2J/+9CfGjRvH5MmTue222/jUpz7Fs88+C8Bqq63GHXfcwQMPPMCpp57K448/Xkd8SZKkPrN4JEmS1EuzZ89m7733Zr/99mOvvfaa7/FTTjmFvfbai4hgnXXWYa211uLee++dZ58xY8aw0UYbce211w5WbEmSpAGxeCRJktQLmclHPvIRNthgAw477LAu91l99dW58sorAXj88ce57777WHvttZk4cSKzZs0C4JlnnuEf//gH66233qBllyRJGghXW5MkSeqF6667jtNPP52NN96YcePGAfDd736XRx99FIBDDjmEr371qxxwwAFsvPHGZCbHHHMMK6ywAn/5y1/43Oc+R0SQmRx++OFsvPHGNf40kiRJvWfxSJIkqRfe/OY3k5nd7jNmzBj+/Oc/z7d9xx135I477mhWNEmSpKZy2pokSZIkSZIqWTySJEmSJElSJYtHkiRJkiRJqmTxSJIkSZIkSZUsHkmSJEmSJKmSxSNJkiRJkiRVsngkSZIkSZKkShaPJEmSJEmSVMnikSRJkiRJkipZPJIkSZIkSVIli0eSJEmSJEmqZPFIkiRJkiRJlSweSZIkSZIkqZLFI0mSJEmSJFWyeCRJkiRJkqRKFo8kSZIkSZJUyeKRJEmSJEmSKlk8kiRJkiRJUiWLR5IkSZIkSapk8UiSJEmSJEmVLB5JkiRJkiSpksUjSZIkSZIkVbJ4JEmSJEmSpEoWjyRJkiRJklTJ4pEkSZIkSZIqWTySJEmSJElSJYtHkiRJkiRJqmTxSJIkSZIkSZUsHkmSJEmSJKmSxSNJkiRJkiRValrxKCJWi4irI+LuiLgrIj7TxT7bR8T0iLit/HNUs/JIkiRJkiSp70Y08Xu/DHwuM2+JiJHAvyPiL5l5d6f9rs3M3ZqYQ5IkSZIkSf3UtJFHmTklM28pb88A7gFWada/J0mSJEmSpAVvUHoeRcSawGbADV08vHVE3B4Rl0fEhhVff3BE3BwRNz/55JPNjCpJkiRJkqQGTS8eRcRSwB+AQzPz2U4P3wKskZmbAj8FLujqe2TmSZm5RWZuseKKKzY1ryRJkiRJkl7V1OJRRCxCUTg6IzPP7/x4Zj6bmTPL25cBi0TECs3MJEmSJEmSpN5r5mprAZwM3JOZP67YZ+VyPyJiyzLPU83KJEmSJEmSpL5p5mprbwL2B+6MiNvKbV8CVgfIzBOBfYBPRMTLwCzg/ZmZTcwkSZIkSZKkPmha8Sgz/wFED/ucAJzQrAySJEmSJEkamEFZbU2SJEmSJEntyeKRJEmSJEmSKlk8kiRJkiRJUiWLR5IkSZIkSapk8UiSJEmSJEmVLB5JkiRJkiSpksUjSZIkSZIkVbJ4JEmSJEmSpEoWjyRJkiRJklTJ4pEkSZIkSZIqWTySJEmSJElSJYtHkiRJkiRJqmTxSJIkSZIkSZUsHkmSJEmSJKmSxSNJkiRJkiRVsngkSZIkSZKkShaPJEmSJEmSVMnikSRJkiRJkipZPJIkSZIkSVIli0eSJEmSJEmqZPFIkiRJkiRJlSweSZIkSZIkqZLFI0mSJEmSJFWyeCRJkiRJkqRKFo8kSZIkSZJUyeKRJEmSJEmSKlk8kiRJkiRJUiWLR5IkSZIkSapk8UiSJEmSJEmVLB5JkiRJkiSpksUjScPaBbdO4tZHp3HDQ0/zpqOv4oJbJ9UdSZIkyWMUSS3F4pGkYeuCWydx5Pl38tKcuQBMmjaLI8+/04MzSZJUK49RJLWayMy6M/TJFltskTfffHPdMQScecOjXHibH2BqX7c+Ou2Vg7JGiy68EJutPmrwA0kLyJ7jVuEDW61edwxJ6pLHkD3zGKV//PyTBiYi/p2ZW3T1mCOP1G8X3jaJu6c8W3cMqd+6OijrbrvUDu6e8qwnZZJamseQPfMYpe/8/JOaa0TdAdTexo5emnM+vnXdMaR+edPRVzFp2qz5tq8yaglf12pb7/vl9XVHkKQeeQzZPY9R+s7PP6m5HHkkadg6Yqf1WGKRhefZtsQiC3PETuvVlEiSJMljFEmtx5FHkoatd222CgA/+NN9TJ42izGjluCIndZ7ZbskSVIdPEaR1GosHkka1t612SoeiEmSpJbjMYqkVuK0NUmSJEmSJFWyeCRpSJswYQI77LADY8eOZcMNN+T444+fb58zzjiDTTbZhI033phtttmG22+/fZ7H58yZw2abbcZuu+02WLElSdIQ5zGKpHbitDVJQ9qIESP40Y9+xPjx45kxYwabb745O+64I2PHjn1ln7XWWotrrrmGZZddlssvv5yDDz6YG2644ZXHjz/+eDbYYAOefdZlhSVJ0oLhMYqkduLII0lD2ujRoxk/fjwAI0eOZIMNNmDSpEnz7LPNNtuw7LLLAvDGN76RiRMnvvLYxIkTufTSS/noRz86eKElSdKQ5zGKpHZi8UjSsPHwww9z6623stVWW1Xuc/LJJ7Pzzju/cv/QQw/l+9//Pgst5NulJElqDo9RJLU632kkDQszZ85k77335rjjjmPppZfucp+rr76ak08+mWOOOQaASy65hJVWWonNN998MKNKkqRhxGMUSe3AnkeShrzZs2ez9957s99++7HXXnt1uc8dd9zBRz/6US6//HKWX355AK677jouuugiLrvsMl544QWeffZZPvjBD/K73/1uMONLkqQhymMUSe3CkUeShrTM5CMf+QgbbLABhx12WJf7PProo+y1116cfvrprLvuuq9s/973vsfEiRN5+OGHOfvss3nrW9/qQZkkSVogPEaR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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plot_dendrogram(df_data.T)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "def tsne(datadf,df_dist=None,n_components=2,resultdf=None):\n", + " if df_dist is None: df_dist=make_dist(datadf)\n", + " m_dist=df_dist.values\n", + " from sklearn.manifold import TSNE\n", + " model = TSNE(n_components=n_components, random_state=0)\n", + " fit = model.fit_transform(m_dist)\n", + " from collections import defaultdict\n", + " newcols=defaultdict(list)\n", + " for i,word in enumerate(datadf.index):\n", + " for ii,xx in enumerate(fit[i]):\n", + " newcols['tsne_V'+str(ii+1)] += [xx]\n", + " if resultdf is None: resultdf=pd.DataFrame(index=datadf.index)\n", + " for k,v in list(newcols.items()): resultdf[k]=v\n", + " return resultdf" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [], + "source": [ + "dtm_tsne = tsne(df_dist)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
tsne_V1tsne_V2label
Komrade-108.958252-208.941483Komrade
SecureScuttlebutt186.487061-98.103249SecureScuttlebutt
Diaspora19.245832160.858780Diaspora
Mastodon170.65882975.445076Mastodon
Matrix-1.386411-35.043739Matrix
BriarMessenger-145.800095106.944611BriarMessenger
CabalChat64.834541-221.825272CabalChat
Signal-196.906036-58.990913Signal
\n", + "
" + ], + "text/plain": [ + " tsne_V1 tsne_V2 label\n", + "Komrade -108.958252 -208.941483 Komrade\n", + "SecureScuttlebutt 186.487061 -98.103249 SecureScuttlebutt\n", + "Diaspora 19.245832 160.858780 Diaspora\n", + "Mastodon 170.658829 75.445076 Mastodon\n", + "Matrix -1.386411 -35.043739 Matrix\n", + "BriarMessenger -145.800095 106.944611 BriarMessenger\n", + "CabalChat 64.834541 -221.825272 CabalChat\n", + "Signal -196.906036 -58.990913 Signal" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dtm_tsne['label']=dtm_tsne.index\n", + "dtm_tsne" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "hovertemplate": "color=Komrade
0=%{x}
1=%{y}
text=%{text}", + "legendgroup": "Komrade", + "marker": { + "color": "#636efa", + "symbol": "circle" + }, + "mode": "markers+text", + "name": "Komrade", + "orientation": "v", + "showlegend": true, + "text": [ + "Komrade" + ], + "type": "scatter", + "x": [ + -0.5371889532432486 + ], + "xaxis": "x", + "y": [ + 1.6690599275270384 + ], + "yaxis": "y" + }, + { + "hovertemplate": "color=SecureScuttlebutt
0=%{x}
1=%{y}
text=%{text}", + "legendgroup": "SecureScuttlebutt", + "marker": { + "color": "#EF553B", + "symbol": "circle" + }, + "mode": "markers+text", + "name": "SecureScuttlebutt", + "orientation": "v", + "showlegend": true, + "text": [ + "SecureScuttlebutt" + ], + "type": "scatter", + "x": [ + 0.5595718609453091 + ], + "xaxis": "x", + "y": [ + 0.7387372968787214 + ], + "yaxis": "y" + }, + { + "hovertemplate": "color=Diaspora
0=%{x}
1=%{y}
text=%{text}", + "legendgroup": "Diaspora", + "marker": { + "color": "#00cc96", + "symbol": "circle" + }, + "mode": "markers+text", + "name": "Diaspora", + "orientation": "v", + "showlegend": true, + "text": [ + "Diaspora" + ], + "type": "scatter", + "x": [ + 1.6860059881786202 + ], + "xaxis": "x", + "y": [ + -0.06589452477227059 + ], + "yaxis": "y" + }, + { + "hovertemplate": "color=Mastodon
0=%{x}
1=%{y}
text=%{text}", + "legendgroup": "Mastodon", + "marker": { + "color": "#ab63fa", + "symbol": "circle" + }, + "mode": "markers+text", + "name": "Mastodon", + "orientation": "v", + "showlegend": true, + "text": [ + "Mastodon" + ], + "type": "scatter", + "x": [ + 1.6860059881786196 + ], + "xaxis": "x", + "y": [ + -0.06589452477227072 + ], + "yaxis": "y" + }, + { + "hovertemplate": "color=Matrix
0=%{x}
1=%{y}
text=%{text}", + "legendgroup": "Matrix", + "marker": { + "color": "#FFA15A", + "symbol": "circle" + }, + "mode": "markers+text", + "name": "Matrix", + "orientation": "v", + "showlegend": true, + "text": [ + "Matrix" + ], + "type": "scatter", + "x": [ + -1.1227200411100027 + ], + "xaxis": "x", + "y": [ + 0.03413532817677556 + ], + "yaxis": "y" + }, + { + "hovertemplate": "color=BriarMessenger
0=%{x}
1=%{y}
text=%{text}", + "legendgroup": "BriarMessenger", + "marker": { + "color": "#19d3f3", + "symbol": "circle" + }, + "mode": "markers+text", + "name": "BriarMessenger", + "orientation": "v", + "showlegend": true, + "text": [ + "BriarMessenger" + ], + "type": "scatter", + "x": [ + -1.223569121311721 + ], + "xaxis": "x", + "y": [ + -0.33510554193784764 + ], + "yaxis": "y" + }, + { + "hovertemplate": "color=CabalChat
0=%{x}
1=%{y}
text=%{text}", + "legendgroup": "CabalChat", + "marker": { + "color": "#FF6692", + "symbol": "circle" + }, + "mode": "markers+text", + "name": "CabalChat", + "orientation": "v", + "showlegend": true, + "text": [ + "CabalChat" + ], + "type": "scatter", + "x": [ + 0.2393460935661281 + ], + "xaxis": "x", + "y": [ + -1.446848658722153 + ], + "yaxis": "y" + }, + { + "hovertemplate": "color=Signal
0=%{x}
1=%{y}
text=%{text}", + "legendgroup": "Signal", + "marker": { + "color": "#B6E880", + "symbol": "circle" + }, + "mode": "markers+text", + "name": "Signal", + "orientation": "v", + "showlegend": true, + "text": [ + "Signal" + ], + "type": "scatter", + "x": [ + -1.2874518152037042 + ], + "xaxis": "x", + "y": [ + -0.5281893023779932 + ], + "yaxis": "y" + } + ], + "layout": { + "annotations": [ + { + "ax": 0, + "ay": 0, + "font": { + "size": 16 + }, + "text": "Decentralized? (P2P?)", + "x": -0.14679498781322306, + "xanchor": "center", + "y": -0.4900741959686681, + "yanchor": "bottom" + }, + { + "ax": 0, + "ay": 0, + "font": { + "size": 16 + }, + "text": "Anonymous? (IP hidden?)", + "x": -0.6086653712596354, + "xanchor": "center", + "y": 0.626654553436534, + "yanchor": "bottom" + }, + { + "ax": 0, + "ay": 0, + "font": { + "size": 16 + }, + "text": "Confidential? (100% E2EE?)", + "x": -1.4418225033622292, + "xanchor": "center", + "y": 0.39456178030931677, + "yanchor": "bottom" + }, + { + "ax": 0, + "ay": 0, + "font": { + "size": 16 + }, + "text": "Data robustness?", + "x": 1.4418225033622298, + "xanchor": "center", + "y": -0.3945617803093167, + "yanchor": "bottom" + }, + { + "ax": 0, + "ay": 0, + "font": { + "size": 16 + }, + "text": "Identity verification?", + "x": -0.3803686148000669, + "xanchor": "center", + "y": 1.1471517840430911, + "yanchor": "bottom" + }, + { + "ax": 0, + "ay": 0, + "font": { + "size": 16 + }, + "text": "Requires invitation/server?", + "x": -0.5480105335232615, + "xanchor": "center", + "y": -0.14373994348049215, + "yanchor": "bottom" + }, + { + "ax": 0, + "ay": 0, + "font": { + "size": 16 + }, + "text": "DM users (E2EE)", + "x": -1.2483876303886634, + "xanchor": "center", + "y": 0.7415999518416786, + "yanchor": "bottom" + }, + { + "ax": 0, + "ay": 0, + "font": { + "size": 16 + }, + "text": "Group chat (E2EE)", + "x": -1.1733869928893845, + "xanchor": "center", + "y": -1.0692051406282475, + "yanchor": "bottom" + }, + { + "ax": 0, + "ay": 0, + "font": { + "size": 16 + }, + "text": "Post to world", + "x": -0.18569746655571534, + "xanchor": "center", + "y": 0.7840777876983394, + "yanchor": "bottom" + }, + { + "ax": 0, + "ay": 0, + "font": { + "size": 16 + }, + "text": "Post to friends/ties", + "x": 0.4450511108846764, + "xanchor": "center", + "y": 0.24812859793960695, + "yanchor": "bottom" + }, + { + "ax": 0, + "ay": 0, + "font": { + "size": 16 + }, + "text": "Symmetric ties (friends)", + "x": -1.2483876303886636, + "xanchor": "center", + "y": 0.7415999518416786, + "yanchor": "bottom" + }, + { + "ax": 0, + "ay": 0, + "font": { + "size": 16 + }, + "text": "Asymmetric ties (followers)", + "x": 1.1733869928893845, + "xanchor": "center", + "y": 1.0692051406282475, + "yanchor": "bottom" + }, + { + "ax": 0, + "ay": 0, + "font": { + "size": 16 + }, + "text": "Like posts", + "x": 1.1733869928893845, + "xanchor": "center", + "y": 1.0692051406282475, + "yanchor": "bottom" + }, + { + "ax": 0, + "ay": 0, + "font": { + "size": 16 + }, + "text": "Repost posts", + "x": 1.1656495864715333, + "xanchor": "center", + "y": -0.06191081860245404, + "yanchor": "bottom" + } + ], + "font": { + "family": "Courier New, monospace", + "size": 22 + }, + "height": 1000, + "legend": { + "title": { + "text": "color" + }, + "tracegroupgap": 0 + }, + "shapes": [ + { + "type": "line", + "x0": 0, + "x1": -0.14679498781322306, + "y0": 0, + "y1": -0.4900741959686681 + }, + { + "type": "line", + "x0": 0, + "x1": -0.6086653712596354, + "y0": 0, + "y1": 0.626654553436534 + }, + { + "type": "line", + "x0": 0, + "x1": -1.4418225033622292, + "y0": 0, + "y1": 0.39456178030931677 + }, + { + "type": "line", + "x0": 0, + "x1": 1.4418225033622298, + "y0": 0, + "y1": -0.3945617803093167 + }, + { + "type": "line", + "x0": 0, + "x1": -0.3803686148000669, + "y0": 0, + "y1": 1.1471517840430911 + }, + { + "type": "line", + "x0": 0, + "x1": -0.5480105335232615, + "y0": 0, + "y1": -0.14373994348049215 + }, + { + "type": "line", + "x0": 0, + "x1": -1.2483876303886634, + "y0": 0, + "y1": 0.7415999518416786 + }, + { + "type": "line", + "x0": 0, + "x1": -1.1733869928893845, + "y0": 0, + "y1": -1.0692051406282475 + }, + { + "type": "line", + "x0": 0, + "x1": -0.18569746655571534, + "y0": 0, + "y1": 0.7840777876983394 + }, + { + "type": "line", + "x0": 0, + "x1": 0.4450511108846764, + "y0": 0, + "y1": 0.24812859793960695 + }, + { + "type": "line", + "x0": 0, + "x1": -1.2483876303886636, + "y0": 0, + "y1": 0.7415999518416786 + }, + { + "type": "line", + "x0": 0, + "x1": 1.1733869928893845, + "y0": 0, + "y1": 1.0692051406282475 + }, + { + "type": "line", + "x0": 0, + "x1": 1.1733869928893845, + "y0": 0, + "y1": 1.0692051406282475 + }, + { + "type": "line", + "x0": 0, + "x1": 1.1656495864715333, + "y0": 0, + "y1": -0.06191081860245404 + } + ], + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "#E5ECF6", + "showlakes": true, + "showland": true, + "subunitcolor": "white" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "polar": { + "angularaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "radialaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "zaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "baxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "caxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Landscape of alternative social media" + }, + "width": 1200, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 1 + ], + "title": { + "text": "PCA Component 1 (Explains 45% of variance in the data)" + } + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 1 + ], + "title": { + "text": "PCA Component 2 (Explains 24% of variance in the data)" + } + } + } + }, + "text/html": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import plotly.express as px\n", + "from sklearn.decomposition import PCA\n", + "from sklearn.preprocessing import StandardScaler\n", + "import numpy as np\n", + "\n", + "features = df_data.columns\n", + "pca = PCA(n_components=2)\n", + "components = pca.fit_transform(df_data)\n", + "\n", + "loadings = pca.components_.T * np.sqrt(pca.explained_variance_)\n", + "total_var = pca.explained_variance_ratio_.sum() * 100\n", + "x_var = pca.explained_variance_ratio_[0] * 100\n", + "y_var = pca.explained_variance_ratio_[1] * 100\n", + "# print(pca.explained_variance_ratio_)\n", + "\n", + "fig = px.scatter(\n", + " components, \n", + " x=0,\n", + " y=1,\n", + " color=df.index,\n", + " text=df.index,\n", + " height=1000,\n", + " width=1200,\n", + " title=f'Landscape of alternative social media',\n", + ")\n", + "fig.update_layout(\n", + " font=dict(\n", + " family=\"Courier New, monospace\",\n", + " size=22,\n", + " ),\n", + " xaxis_title=f'PCA Component 1 (Explains {x_var:.0f}% of variance in the data)',\n", + " yaxis_title=f'PCA Component 2 (Explains {y_var:.0f}% of variance in the data)',\n", + ")\n", + "for i, feature in enumerate(features):\n", + " fig.add_shape(\n", + " type='line',\n", + " x0=0, y0=0,\n", + " x1=loadings[i, 0]*3,\n", + " y1=loadings[i, 1]*3\n", + " )\n", + " fig.add_annotation(\n", + " x=loadings[i, 0]*3,\n", + " y=loadings[i, 1]*3,\n", + " ax=0, ay=0,\n", + " xanchor=\"center\",\n", + " yanchor=\"bottom\",\n", + " text=feature,\n", + " font=dict(size=16)\n", + " )\n", + "fig.show()\n", + "fig.write_image('fig.landscape-alt-soc-media.png')" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [], + "source": [ + "# !pip install -U kaleido\n", + "# !pip install psutil" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.7" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/fig.hclust-apps.png b/docs/fig.hclust-apps.png new file mode 100644 index 0000000..7119961 Binary files /dev/null and b/docs/fig.hclust-apps.png differ diff --git a/docs/fig.landscape-alt-soc-media.png b/docs/fig.landscape-alt-soc-media.png new file mode 100644 index 0000000..505179a Binary files /dev/null and b/docs/fig.landscape-alt-soc-media.png differ diff --git a/komrade/constants.py b/komrade/constants.py index ab604f5..1a3753b 100644 --- a/komrade/constants.py +++ b/komrade/constants.py @@ -1,7 +1,7 @@ # addresses -KOMRADE_URL = '68.66.241.111' KOMRADE_ONION = 'u7spnj3dmwumzoa4.onion' KOMRADE_ONION2 = 'rwg4zcnpwshv4laq.onion' +KOMRADE_URL = KOMRADE_ONION OPERATOR_API_URL = f'http://{KOMRADE_ONION}/op/'