diff options
| author | Adam Janovsky | 2023-06-14 14:58:14 +0200 |
|---|---|---|
| committer | Adam Janovsky | 2023-06-14 14:58:14 +0200 |
| commit | 6789da266bbaf8aca3c530308eb2e7f4b9e2bf70 (patch) | |
| tree | 0eab060877062656331b3b547ad124849a62c8ea /notebooks | |
| parent | 617fa6c71324624f5b4ba9a8693740bb173871bb (diff) | |
| download | sec-certs-6789da266bbaf8aca3c530308eb2e7f4b9e2bf70.tar.gz sec-certs-6789da266bbaf8aca3c530308eb2e7f4b9e2bf70.tar.zst sec-certs-6789da266bbaf8aca3c530308eb2e7f4b9e2bf70.zip | |
add more plots to reference notebook
Diffstat (limited to 'notebooks')
| -rw-r--r-- | notebooks/cc/references.ipynb | 156 |
1 files changed, 155 insertions, 1 deletions
diff --git a/notebooks/cc/references.ipynb b/notebooks/cc/references.ipynb index 15b2a1f4..1a934b38 100644 --- a/notebooks/cc/references.ipynb +++ b/notebooks/cc/references.ipynb @@ -28,6 +28,7 @@ }, "outputs": [], "source": [ + "from __future__ import annotations\n", "import networkx as nx\n", "import networkx.algorithms.community as nx_comm\n", "import matplotlib\n", @@ -38,6 +39,7 @@ "import seaborn as sns\n", "import numpy as np\n", "import sys\n", + "from tqdm import tqdm\n", "from pathlib import Path\n", "\n", "\n", @@ -46,7 +48,7 @@ "\n", "%matplotlib inline\n", "\n", - "matplotlib.use(\"pgf\")\n", + "# matplotlib.use(\"pgf\")\n", "sns.set_theme(style='white')\n", "plt.rcParams[\"axes.linewidth\"] = 0.5\n", "plt.rcParams[\"legend.fontsize\"] = 6.5\n", @@ -152,6 +154,158 @@ ] }, { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def len_if_exists(x) -> int:\n", + " return len(x) if pd.notnull(x) else 0\n", + "\n", + "df_id_rich[\"n_references\"] = df_id_rich.directly_referencing.map(len_if_exists)\n", + "df_id_rich[\"n_trans_references\"] = df_id_rich.indirectly_referencing.map(len_if_exists)\n", + "df_id_rich[\"n_referenced_by\"] = df_id_rich.directly_referenced_by.map(len_if_exists)\n", + "df_id_rich[\"n_trans_referenced_by\"] = df_id_rich.indirectly_referenced_by.map(len_if_exists)\n", + "\n", + "n_ref_smartcards = df_id_rich.loc[(df_id_rich.directly_referencing.notnull()) & (df_id_rich.category == \"ICs, Smart Cards and Smart Card-Related Devices and Systems\")].shape[0]\n", + "n_ref_others = df_id_rich.loc[(df_id_rich.directly_referencing.notnull()) & (df_id_rich.category != \"ICs, Smart Cards and Smart Card-Related Devices and Systems\")].shape[0]\n", + "print(f\"Number of smartcard certificates that reference some other certificate: {n_ref_smartcards}\")\n", + "print(f\"Number of non-smartcard certificates that reference some other certificate: {n_ref_others}\")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Distribution of references and certificate reach" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "df_melted = df_id_rich[[\"n_references\", \"n_trans_references\", \"n_referenced_by\", \"n_trans_referenced_by\"]].melt()\n", + "df_melted[\"incoming\"] = df_melted.variable.map(lambda x: False if x.endswith(\"by\") else True)\n", + "sns.catplot(data=df_melted, kind=\"violin\", x=\"variable\", y=\"value\", col=\"incoming\", sharex=False, sharey=False)\n", + "plt.savefig(RESULTS_DIR / \"violin_n_references.pdf\", bbox_inches=\"tight\")\n", + "plt.show()" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Evolution of certificate reach for top-10 certificates" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "top_10 = df_id_rich.n_trans_referenced_by.sort_values(ascending=False).head(10)\n", + "top_10_cert_ids = df_id_rich.loc[top_10.index].cert_id\n", + "top_10" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: Check if the computation can be vectorized through some time-series or other thing...\n", + "def find_reach_over_time(df: pd.DataFrame, cert_id: str, date_range: pd.DatetimeIndex) -> pd.Series:\n", + " df_copy = df.copy()\n", + " df_copy[\"is_referenced_by\"] = df_copy.indirectly_referencing.map(lambda x: False if pd.isnull(x) else cert_id in x)\n", + " df_subset = df_copy.loc[df_copy.is_referenced_by]\n", + " dct = {}\n", + " for date in date_range:\n", + " dct[date] = df_subset.loc[(date >= df_subset.not_valid_before) & (date < df_subset.not_valid_after)].shape[0]\n", + " return pd.Series(dct, name=cert_id)\n", + "\n", + "certs_with_top_reach = top_10_cert_ids.tolist()\n", + "date_range = pd.date_range(df_id_rich.not_valid_before.min(), df_id_rich.not_valid_before.max())\n", + "data = [find_reach_over_time(df_id_rich, x, date_range) for x in tqdm(certs_with_top_reach)]\n", + "df_reach_evolution = pd.concat(data, axis=1)\n", + "\n", + "df_reach_evolution.index.name = \"date\"\n", + "df_reach_evolution = df_reach_evolution.reset_index()\n", + "\n", + "\n", + "df_reach_evolution_melted = df_reach_evolution.melt(id_vars=\"date\", var_name=\"certificate\", value_name=\"reach\")\n", + "\n", + "g = sns.lineplot(data=df_reach_evolution_melted, x=\"date\", y=\"reach\", hue=\"certificate\")\n", + "g.set(title=\"Certificate reach over time\", xlabel=\"Time\", ylabel=\"Certificate reach\")\n", + "plt.savefig(RESULTS_DIR / \"lineplot_top_certificate_reach.pdf\", bbox_inches=\"tight\")\n", + "plt.show()" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Average number of references & certificate reach over time" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def compute_avg_references(df: pd.DataFrame, smartcards: bool, variable: str) -> pd.DataFrame:\n", + " \"\"\"\n", + " Computes a series where index is date and value is average 'variable' value for certificates that were valid at that time,\n", + " coming from either smardcards or other categories. E.g., variable can be `directly_referencing`.\n", + " \"\"\"\n", + " df_copy = df.copy()\n", + " df_copy[\"target_variable\"] = df[variable].map(lambda x: len(x) if pd.notnull(x) else 0)\n", + "\n", + " date_range = pd.date_range(df_copy.not_valid_before.min(), df_copy.not_valid_before.max())\n", + " dct = {}\n", + " for date in date_range:\n", + " if smartcards:\n", + " dct[date] = df_copy.loc[(date >= df_copy.not_valid_before) & (date < df_copy.not_valid_after) & (df_copy.category == \"ICs, Smart Cards and Smart Card-Related Devices and Systems\")][\"target_variable\"].mean()\n", + " else:\n", + " dct[date] = df_copy.loc[(date >= df_copy.not_valid_before) & (date < df_copy.not_valid_after) & (df_copy.category != \"ICs, Smart Cards and Smart Card-Related Devices and Systems\")][\"target_variable\"].mean()\n", + " series_name = variable + \" smartcards\" if smartcards else variable + \" other categories\"\n", + " return pd.Series(dct, name=series_name) \n", + "\n", + "refs_smartcards = compute_avg_references(df_id_rich, True, \"directly_referencing\")\n", + "trans_refs_smartcards = compute_avg_references(df_id_rich, True, \"indirectly_referencing\")\n", + "refs_others = compute_avg_references(df_id_rich, False, \"directly_referencing\")\n", + "trans_refs_others = compute_avg_references(df_id_rich, False, \"indirectly_referencing\")\n", + "df_avg_num_refs = pd.concat([refs_smartcards, refs_others, trans_refs_smartcards, trans_refs_others], axis=1)\n", + "df_avg_num_refs.index.name = \"date\"\n", + "df_avg_num_refs = df_avg_num_refs.reset_index()\n", + "df_avg_num_refs_melted = df_avg_num_refs.melt(id_vars=[\"date\"], var_name=\"category\", value_name=\"n_references\")\n", + "\n", + "reach_smartcards = compute_avg_references(df_id_rich, True, \"indirectly_referenced_by\")\n", + "reach_others = compute_avg_references(df_id_rich, False, \"indirectly_referenced_by\")\n", + "df_avg_reach = pd.concat([reach_smartcards, reach_others], axis=1)\n", + "df_avg_reach.index.name = \"date\"\n", + "df_avg_reach = df_avg_reach.reset_index()\n", + "df_avg_reach_melted = df_avg_reach.melt(id_vars=[\"date\"], var_name=\"category\", value_name=\"certificate reach\")\n", + "\n", + "g = sns.lineplot(data=df_avg_num_refs_melted, x=\"date\", y=\"n_references\", hue=\"category\")\n", + "g.set(title=\"Average number of references in certificates\", xlabel=\"Time\", ylabel=\"Number of references\")\n", + "plt.savefig(RESULTS_DIR / \"lineplot_avg_n_references.pdf\", bbox_inches=\"tight\")\n", + "plt.show()\n", + "\n", + "g = sns.lineplot(data=df_avg_reach_melted, x=\"date\", y=\"certificate reach\", hue=\"category\")\n", + "g.set(title=\"Average reach of a certificate in time\", xlabel=\"Time\", ylabel=\"Reach\")\n", + "plt.savefig(RESULTS_DIR / \"lineplot_avg_reach.pdf\", bbox_inches=\"tight\")\n", + "plt.show()" + ] + }, + { "attachments": {}, "cell_type": "markdown", "metadata": {}, |
