Added cm and updated graph titles for clarity
Browse files- analysis.ipynb +0 -0
- inference.py +4 -3
- inference_analysis.ipynb +80 -0
- inference_main.py +11 -1
- inference_more.ipynb +0 -303
- output/version_9/confusion_matrix_inference_9.csv +3 -0
- test.ipynb +0 -93
- train_analysis.ipynb +0 -0
analysis.ipynb
DELETED
The diff for this file is too large to render.
See raw diff
|
|
inference.py
CHANGED
@@ -29,11 +29,12 @@ def evaluate_model(model, data_loader, device, labels):
|
|
29 |
outputs = predict(model, titles, texts, device)
|
30 |
predictions.extend(outputs.cpu().numpy())
|
31 |
|
32 |
-
labels = labels.cpu()
|
33 |
-
# Calculate metrics
|
34 |
predicted_labels = [1 if p > 0.5 else 0 for p in predictions]
|
|
|
|
|
35 |
accuracy = accuracy_score(labels, predicted_labels)
|
36 |
f1 = f1_score(labels, predicted_labels)
|
37 |
auc_roc = roc_auc_score(labels, predictions)
|
38 |
|
39 |
-
return accuracy, f1, auc_roc
|
|
|
29 |
outputs = predict(model, titles, texts, device)
|
30 |
predictions.extend(outputs.cpu().numpy())
|
31 |
|
32 |
+
labels = labels.cpu().numpy() # Convert labels to NumPy array for consistency
|
|
|
33 |
predicted_labels = [1 if p > 0.5 else 0 for p in predictions]
|
34 |
+
|
35 |
+
# Calculate metrics
|
36 |
accuracy = accuracy_score(labels, predicted_labels)
|
37 |
f1 = f1_score(labels, predicted_labels)
|
38 |
auc_roc = roc_auc_score(labels, predictions)
|
39 |
|
40 |
+
return accuracy, f1, auc_roc, labels, predicted_labels
|
inference_analysis.ipynb
ADDED
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"cells": [
|
3 |
+
{
|
4 |
+
"cell_type": "code",
|
5 |
+
"execution_count": 5,
|
6 |
+
"metadata": {},
|
7 |
+
"outputs": [
|
8 |
+
{
|
9 |
+
"name": "stderr",
|
10 |
+
"output_type": "stream",
|
11 |
+
"text": [
|
12 |
+
"C:\\Users\\kimi\\AppData\\Local\\Temp\\ipykernel_6488\\2691833235.py:5: MatplotlibDeprecationWarning: The seaborn styles shipped by Matplotlib are deprecated since 3.6, as they no longer correspond to the styles shipped by seaborn. However, they will remain available as 'seaborn-v0_8-<style>'. Alternatively, directly use the seaborn API instead.\n",
|
13 |
+
" plt.style.use(\"seaborn-whitegrid\")\n"
|
14 |
+
]
|
15 |
+
},
|
16 |
+
{
|
17 |
+
"data": {
|
18 |
+
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAIYCAYAAAD9+F0NAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAABFgElEQVR4nO3de3zP9f//8fv7bZttTtsi50ptiByWw8zZNGfSkEo+jUo5fArlFDnkrIM+iELah1ZEFkMayaeSrZFIUZsSSk6zxWzZ6fdHP+9v717Dlvd74/W6XT+X9+XSXq/n+/V+vN9ePh67P5+v19uWl5eXJwAAAFiGvbgLAAAAQNGiAQQAALAYGkAAAACLoQEEAACwGBpAAAAAi6EBBAAAsBgaQAAAAIuhAQQAALAYGkDAwrgPPAqquM4VzlHAPWgAUSS++eYbjRo1Sm3btlX9+vXVvn17TZgwQUePHnXba27atEnt2rVTvXr1NHHiRJcdt1atWpo/f77Ljne116pVq5ZeeeWVfPfn5uaqVatWqlWrltauXVuoY69evVqzZ8++6rj+/furf//+hTr25UydOlVz586VJK1du1a1atXSsWPHrvq8tWvX6oEHHtDdd9+tBg0aqGvXrpo7d67Onz/vGBMWFub4vC73GDt2rOM91apVSw888MBlX3PEiBFOzymo+fPnq1atWpfdP3bsWIWFhRXqmAX5rI4dO/aPzoOCSE5O1oMPPnjVcdnZ2YqKitJ9992nhg0bKjg4WPfdd5+WLl2qixcvFvp1/36OJicnKywsTL///nuhjwXAmUdxFwDzi46O1owZMxQSEqJnnnlGN998s44cOaKlS5cqLi5Ob731lurWrevy150yZYpuu+02zZo1SxUrVnTZcVetWqVKlSq57HhXY7fbtXnzZo0cOdKwLzExUSdPnvxHx120aJGaNm161XGTJk36R8f/u/j4eMXFxemjjz4q1PMWLFig119/XZGRkRo8eLA8PT21f/9+LV26VJ9//rlWrlwpT09PLViwwKnJGDZsmOrUqaMhQ4Y4tgUEBDj+22636+uvv9bx48dVuXJlp9fMyMjQ9u3b/9kbNaEPP/xQe/bsueq4559/Xh999JEef/xx1atXT3l5edq1a5fmzZunr776SgsXLizU6/79HA0MDFRYWJimT59eoF9eAFweDSDcavfu3Zo+fbr69eun8ePHO7aHhISoffv2ioiI0Lhx47R+/XqXv3ZqaqpatGihkJAQlx63YcOGLj3e1dx9993atWuXvv32W0OjvHHjRt155506cOCA214/MDDQJceZOXOm/vWvf8nX17fAz7l48aKWLFmigQMHOjXAzZs31+23366hQ4dq69at6ty5s+rUqeP0XC8vLwUEBFz2z6tOnTpKTk7W5s2bNWDAAKd927ZtU8mSJVWmTJmCv0GL+/XXXxUTE6MpU6aob9++ju2tWrVSQECAZsyYoX379ql+/frX9DqDBg1S27Zt9a9//cstvzgCVsEUMNzqzTffVJkyZfJNrwICAjR27Fh16NDBaSpv06ZNioiIUHBwsFq0aKGJEycqLS3NsX/+/PkKDw/X9u3b1b17d911113q2LGjYmJiJEkJCQmOKbjXXnvNMXWW39RbftNmK1asUKdOnVSvXj21atVKkydPdqrv71PAJ0+e1Lhx49SmTRvVr19fvXv31scff+z0OrVq1VJ0dLTGjx+vpk2bKjg4WE899ZROnz591c+wadOmKl++vD788EOn7dnZ2YqLi1PXrl0Nzzl48KCGDRumZs2aqW7dumrVqpWmTZumzMxMSX9Ol/7yyy+KiYlxfD5r165VnTp1tHr1arVs2VKtW7dWUlKS0xTw8uXLDZ9XYmKi7rzzTs2bN++y72H79u36/vvv1a1bt6u+3786f/68MjMz810H1qZNG40YMULVq1cv1DEv8fX1VZs2bQyfq/TnOdipUyd5eBTN78g7duzQQw89pEaNGjmS8uPHj1/xOXFxcerRo4fq16+v++67TwcPHjSMKei5+fclDX+dxp4/f74WLFhw2bGXnD59Wnl5efn+WXXv3l0jR45U2bJlHdtSU1M1ceJENW/eXPXq1dP999+vnTt3Ovbnd45K0s0336xmzZpp8eLFV/x8AFwZDSDcJi8vT59//rlCQ0Pl4+OT75hOnTpp2LBhKl26tCRp4cKFGjFihBo0aKB58+Zp6NCh+uijj9S/f39H8yJJp06d0gsvvKB//etfWrx4sapVq6axY8fq0KFDqlu3rlatWiVJ6t27t1atWqWbb765QDVv3LhRs2fPVr9+/fTmm29q6NChWrdunaZNm5bv+NOnT6t379768ssvNWLECM2fP19Vq1bV0KFDDanm3LlzlZubq1deeUWjR4/W9u3bNWPGjKvWZLfb1bFjR23evNlp+86dO/XHH3+oXbt2TttPnjypfv36KSMjQ7NmzdKSJUvUuXNnrVixQlFRUZL+nFatUKGC2rRp4/T55OTk6PXXX9e0adM0fPhwQ/rXv39/NW3aVLNnz1ZKSorS09M1duxY3XXXXU5TrX+3fv16NWzY0DDVejUBAQFq0KCB3nzzTY0ZM0Zbt25VSkqKJMnT01NPPvmk7rrrrkId86+6dOmivXv36tdff3VsO3/+vD799NNCN6t/l52dne/j7w3SunXrNHDgQFWsWFGvvPKKxo0bpz179qhv3746c+ZMvsfetm2bnnrqKQUFBWnBggXq3LmzRo0a5TSmMOfmlfTp00e9e/eW9Ofyhz59+uQ7rnbt2qpcubJmzpypKVOm6NNPP3X84hQQEKAnnnhCt912myTpjz/+0COPPKKPP/5YI0aM0IIFC1SpUiU99thjjibwcueoJHXu3Fkff/yx0tPTC/w+ADhjChhuc/bsWf3xxx+qVq1agcanpaVp0aJF6tOnj9O6s5o1a6pfv35au3atHnroIUl/rtGaPn26QkNDJUm33Xab2rVrp//9738aOHCgY9qvUqVKhZqyTUhIUNWqVdWvXz/Z7XY1bdpUvr6+Onv2bL7j33rrLaWkpOjDDz90JFFt2rRRZGSk5syZo27duslutzvex8yZMx3P3bdvn6Gpu5wuXbooOjpa+/fvdzQ8mzZtUvv27eXt7e009ocfftCdd96p//znP47Gunnz5tq5c6cSExP15JNPqk6dOpedIn3yySfVtm3bfOuw2WyaMWOGevTooRdffFFeXl5KSUnRsmXLrpiWxcfH55tUFsS8efM0atQoffDBB/rggw9ks9kUFBSke+65R5GRkSpXrtw/Oq4ktW3bVr6+vtq8ebMGDhwoSdqyZYsCAgLUqFGjf3xcSVecnqxataqkPy/iefHFF9W8eXPHxTHSn9P+Xbp00bJlywyNnfRnsl23bl29/PLLkqTWrVtLkuNnqXDn5pVUqlTJseb1Sn+XvLy8tHjxYo0ePVrvvPOO3nnnHdntdtWtW1edOnXSww8/7DhX161bp4MHD+q9995TgwYNHO+hf//+eumll/T+++9f8RytV6+esrKytGvXLrVp0+aq7wGAEQkg3ObSPy45OTkFGv/111/r4sWL6t69u9P2xo0bq2rVqkpISHDa/td/FC79A3XhwoVrqFhq1qyZDh8+rIiICC1cuFDfffedunfvrkceeSTf8V9++aWCg4MN05A9evTQqVOn9OOPP+Zb76WaMzIyClRXo0aNVLFiRcd05cWLF7V169Z8U6qWLVvq7bffVsmSJfXTTz/pk08+0euvv66UlJQCXYlZs2bNK+6vXr26xowZo5iYGK1atUrPPfecbr311suOz8jI0JkzZwr8i8DfVapUSStWrNDGjRs1ZswYtWnTRr/88osWLlyoLl266PDhw//ouJLk7e2tsLAwp2ngjRs3qkuXLrLZbP/4uJK0Zs2afB9/TWx/+uknnTp1ynDO33LLLQoODjac85KUmZmpb7/9Vu3bt3fa3rlzZ6efC3NuukrNmjX1wQcfaM2aNRo+fLhCQkKUlJSkF198UT179nSktzt37lSFChVUt25dRzKak5Ojdu3aaf/+/U5LPvJzqYEuyBXkAPJHAwi38fPzU6lSpZym1/7uwoULSk1NlSTH/+mXL1/eMK58+fI6d+6c07a/Titfajav9Z5hXbp00csvvyxfX18tWLBA9913n9q3b6+NGzfmOz4tLe2y9Upyul3F36fB7XZ7geu12Wzq1KmTIzH87LPPZLfb1aJFC8PY3NxcvfTSS2ratKk6deqkKVOm6LvvvlPJkiUL9Fo33XTTVcd07txZJUuWlIeHh1q2bHnFsZc+g8Jc/JGfwMBADRw4UG+88YYSEhL0wgsvKDU19bK3yCmozp07a9++fTp27JjOnj2rnTt3/uO08q/q1auX78PPz88x5tK5X9BzXvrznMvLy3O6olmSYZlDYc5NV6tXr54GDx6sqKgoxcfH6+mnn9ZPP/2kJUuWSPrzfZ86dUp169Z1esyZM0fSn0s8ruTS36W/rs0FUDg0gHCrli1bKiEhQX/88Ue++9euXavQ0FDt2bPHMZWX34URp06dkr+//zXVYrPZDGlkfolht27d9M477yghIUGvvvqq/Pz8NGrUKJ04ccIwtly5cpetV9I11/xXXbp00bFjx/TNN99o06ZN6tChgzw9PQ3jFi9erKioKI0fP167du3S9u3bNW/ePEPDcC2mTZsmb29vlS9fXhMmTLji2EufwT9pOP773/+qWbNmhqTU09NTffv2VZs2bZScnFzo4/5V69atVaZMGX300UfasmWLqlWrdk3rCgvjUjNYmHPez89Pdrvd8JxLzeQlhTk3C/L34mpmz56tTp06Gbb7+PhoyJAhql27tuPPqkyZMrrtttsum5JeLS2+dC658u8XYDU0gHCrgQMHKjU11Wl90yVnzpzR0qVLdeutt6phw4Zq0KCBvLy8FBsb6zRu165d+vXXX3X33XdfUy2lSpVyrEu85KuvvnIaM3z4cA0bNkzSn/9Ide7cWUOGDFFOTk6+99tr0qSJ9uzZY7ih9fr161WhQoUrTo0WVsOGDVW1alXFxsZq27Ztl02pdu/ercDAQPXu3dtxG5MTJ07ohx9+UG5urmNcQdZ/5Wfr1q1av369xo4dq0mTJjnuxXc5Xl5eqlChwlWvas1PYGCgzp49qxUrVhj25eTk6OjRo1edsr4aLy8vtW/fXnFxcfrwww9dkv4VVI0aNVShQgXDOX/06FF9/fXX+Z7zJUuWVHBwsOLi4pwS5G3btjmNK+i5Wbp0af32229OY/7+96Ig50qNGjX0008/adOmTYZ96enpOnnypOPPqmnTpjp+/Lhuuukmp3R0586dWrp0qUqUKHHF1710LlWpUuWqdQHIHxeBwK0aNmyop59+Wq+++qoOHTqk++67T/7+/kpKStKyZcuUnp6uxYsXy2azyc/PT4MGDdKCBQvk6emp9u3b69ixY/rPf/6jwMBARUREXFMt7dq104oVK/Tcc8+pT58+jhou/WMj/bkGcNKkSZo9e7Zat26t33//XQsWLNBtt92m2rVrG445YMAArV+/XgMGDNCwYcPk7++vDz74QPHx8ZoxY8Y/brIup1OnTlq+fLn8/PwuexPn+vXra+HChVq8eLEaNmyon3/+WW+88YYuXrzolKSVLVtW3333nb788ssC35stJSVFkyZNUosWLXTfffdJkjp27KjZs2erRYsWl70lS4sWLQxNxSXvv/9+vhdyREZGqkWLFurWrZteeeUVff/99+rYsaMCAgL022+/aeXKlfrtt9/06quvFqj2K+nSpYueeOIJ2e32KyaaR44cUUpKisvuBWm32zVy5EiNGzdOI0aMUM+ePXX27FktWLBA5cqVM9yf8JKRI0fqkUce0bBhw9S3b18dPnxYixYtchpT0HOzbdu22rhxo+rXr68aNWooJiZGP//8s9OxLt2+ZcOGDWrQoEG+f849e/ZUbGysRo8erYSEBLVp00Zly5bV4cOHtXz5cnl7ezsutImIiNDbb7+tAQMG6Mknn1TlypX1xRdfaMmSJXr44Ycdyfbfz9FLF5Hs3r1bPj4+aty48TV8+oC10QDC7QYPHqw6deooOjpaM2fOVGpqqipVqqTWrVvrySefdPot/t///rfKly+vt99+W6tXr5afn586deqk4cOHX/ZWMgXVokULjRkzRitWrFBcXJzq1q2rBQsWOH0d2AMPPKCsrCytXLlS77zzjry9vRUaGqpRo0blO91aoUIFvfvuu3r55Zc1ffp0ZWVlqXbt2lq4cKFhkb4rdOnSRW+++aY6d+582ebyiSee0NmzZ7V8+XK99tprqly5su69917ZbDa98cYbSktLU7ly5TRw4EDNmDFDjz76qN56660Cvf6UKVOUnp6uKVOmOLY9//zz6tKli5577jktX74834snOnbsqNjYWJ08edKwVu1y3w4RGRkpSXrxxRcVEhKidevWacKECbpw4YICAgLUokULzZw58x/fB/CvmjdvrrJly6py5cq64447Ljtu4cKFiomJ0ffff3/Nr3lJRESESpUqpTfeeENDhw5V6dKl1apVK40cOVIVKlTI9zmNGzfWkiVL9Morr2jYsGGqVq2aZsyYoSeffNIxpqDn5rhx45Sdna0XX3xRHh4e6tKli5555hmnRrhDhw5at26dxo4dq969e2vy5MmGmry8vPTmm29q+fLl2rx5szZu3KjMzEzdfPPNCgsL0+DBgx3rS319fRUdHa2XX35ZL774os6dO6eqVavqmWeecTSJkgzn6KWG79NPP1Xbtm0NV8ADKDhbHt+0DcDN8vLydO+996pjx44aOnRocZdzTTp06KC4uLjiLsOyjh07pg4dOmjNmjWGb38BUHCsAQTgdjabTc8++6zefffdG/rKzffee89lX42Hf2bp0qXq1KkTzR9wjUgAARSZSZMmqWzZsnrmmWeKu5R/5Mcff1TlypWveTkC/pnk5GQ99thjiomJ4Qpg4BrRAAIAAFgMU8AAAAAWQwMIAABgMTSAAAAAFkMDCAAAYDE33I2gfYKHFXcJANzk5M55xV0CADcp4118mZO7e4eMPQvcenx3uOEaQAAAgEKxMeH5d3wiAAAAFkMCCAAAzC2f7yi3OhJAAAAAiyEBBAAA5sYaQAM+EQAAAIshAQQAAObGGkADEkAAAACLIQEEAADmxhpAAxpAAABg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nHCMufPOO/Xwww/L09NTLVq0UMeOHbVu3bqr1gUANzKmgAETmzRpktMawPzcfPPNjv/+5ZdflJKSoiZNmji25eXlKSsrS2fOnNGJEydUt25dp+dXr1493+OeOnVKVapUcdp29913G8alpKTowoULevrpp2W3/9/vpFlZWY5pW39/f6fG8ZZbbrnie7rEbrdr+fLlio2Nla+vr2rVqqXz5887rT+sVq2a03MqV66sH3744ap1AcCNjAYQsDibzeb470qVKumWW27R5s2bHdvOnz+vM2fOKCAgQJUqVdLRo0ednv/bb78pKCjIcNzKlSvr+PHjTtvmzp2rHj16OG3z9/dXyZIltWzZMjVs2NCx/ccff1TFihV14MABpaSkKD09XaVKlXK8ZkFERUVpx44dio2NVfny5SVJTz75pNOYkydPOv189OhRVa1a9ap1AcCNjClgAA7t2rVTenq6li5dqosXL+r333/XmDFjNGLECNlsNvXq1Utbt27VJ598ouzsbMXExGjv3r35HisiIkKrVq3Svn37lJubq/fff1/R0dGOxiojI0PZ2dmy2+3q3bu3Xn75Zf3222/Kzc1VTEyMunXrpp9//lnBwcGqUaOGpk2bpoyMDP38889atmxZgd7P+fPn5eHhIU9PT2VnZ2vdunX67LPPlJWV5Rizb98+vf/++8rKytInn3yibdu2qU+fPletCwBuZCSAABxKly6tqKgozZo1S0uXLlVubq5CQkK0aNEiSVKjRo00Z84czZo1SyNGjFCzZs2cLij5q+7du+v333/XqFGjdOrUKQUGBmrJkiUKCAhQkyZNdNNNN6lJkyZauXKlxowZo/nz5+uhhx5Samqqqlevrnnz5jnWFy5evFgTJ05U8+bNVb58ebVv315xcXFXfT8DBw7UDz/8oHbt2qlkyZKqU6eOHnroIcXHxzvGNG/eXB9//LGmTZumatWq6T//+Y/jda9WFwDcqGx53IwLAADAUpgCBgAAsBgaQAAAAIuhAQQAALAYGkAAAACLoQEEAACwGBpAAAAAi6EBBAAAsBgaQAAAAIuhAQQAALAYGkAAAACLoQEEAACwmP8H2L1BvjXMszQAAAAASUVORK5CYII=",
|
19 |
+
"text/plain": [
|
20 |
+
"<Figure size 800x600 with 2 Axes>"
|
21 |
+
]
|
22 |
+
},
|
23 |
+
"metadata": {},
|
24 |
+
"output_type": "display_data"
|
25 |
+
}
|
26 |
+
],
|
27 |
+
"source": [
|
28 |
+
"import matplotlib.pyplot as plt\n",
|
29 |
+
"import seaborn as sns\n",
|
30 |
+
"import pandas as pd\n",
|
31 |
+
"\n",
|
32 |
+
"plt.style.use(\"seaborn-whitegrid\")\n",
|
33 |
+
"\n",
|
34 |
+
"version = 9\n",
|
35 |
+
"\n",
|
36 |
+
"# Read confusion matrix from CSV\n",
|
37 |
+
"cm_df = pd.read_csv(\n",
|
38 |
+
" f\"./output/version_{version}/confusion_matrix_inference_{version}.csv\"\n",
|
39 |
+
")\n",
|
40 |
+
"cm = cm_df.values\n",
|
41 |
+
"\n",
|
42 |
+
"# Plotting\n",
|
43 |
+
"plt.figure(figsize=(8, 6))\n",
|
44 |
+
"sns.heatmap(cm, annot=True, fmt=\"d\", cmap=\"Blues\")\n",
|
45 |
+
"plt.title(\"Confusion Matrix (LSTM, Holdout Set)\")\n",
|
46 |
+
"plt.ylabel(\"True label\")\n",
|
47 |
+
"plt.xlabel(\"Predicted label\")\n",
|
48 |
+
"plt.show()"
|
49 |
+
]
|
50 |
+
},
|
51 |
+
{
|
52 |
+
"cell_type": "code",
|
53 |
+
"execution_count": null,
|
54 |
+
"metadata": {},
|
55 |
+
"outputs": [],
|
56 |
+
"source": []
|
57 |
+
}
|
58 |
+
],
|
59 |
+
"metadata": {
|
60 |
+
"kernelspec": {
|
61 |
+
"display_name": "torch",
|
62 |
+
"language": "python",
|
63 |
+
"name": "python3"
|
64 |
+
},
|
65 |
+
"language_info": {
|
66 |
+
"codemirror_mode": {
|
67 |
+
"name": "ipython",
|
68 |
+
"version": 3
|
69 |
+
},
|
70 |
+
"file_extension": ".py",
|
71 |
+
"mimetype": "text/x-python",
|
72 |
+
"name": "python",
|
73 |
+
"nbconvert_exporter": "python",
|
74 |
+
"pygments_lexer": "ipython3",
|
75 |
+
"version": "3.10.11"
|
76 |
+
}
|
77 |
+
},
|
78 |
+
"nbformat": 4,
|
79 |
+
"nbformat_minor": 2
|
80 |
+
}
|
inference_main.py
CHANGED
@@ -3,6 +3,7 @@ import pandas as pd
|
|
3 |
from preprocessing import preprocess_text, load_tokenizer, prepare_data
|
4 |
from data_loader import create_data_loader
|
5 |
from inference import load_model, evaluate_model
|
|
|
6 |
import os
|
7 |
|
8 |
version = 9
|
@@ -78,7 +79,16 @@ def run_evaluation(model_path, tokenizer_path, device):
|
|
78 |
data_loader = create_data_loader(titles, texts, batch_size=32, shuffle=False)
|
79 |
|
80 |
# Evaluate
|
81 |
-
accuracy, f1, auc_roc = evaluate_model(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
return accuracy, f1, auc_roc
|
83 |
|
84 |
|
|
|
3 |
from preprocessing import preprocess_text, load_tokenizer, prepare_data
|
4 |
from data_loader import create_data_loader
|
5 |
from inference import load_model, evaluate_model
|
6 |
+
from sklearn.metrics import confusion_matrix
|
7 |
import os
|
8 |
|
9 |
version = 9
|
|
|
79 |
data_loader = create_data_loader(titles, texts, batch_size=32, shuffle=False)
|
80 |
|
81 |
# Evaluate
|
82 |
+
accuracy, f1, auc_roc, y_true, y_pred = evaluate_model(
|
83 |
+
model, data_loader, device, labels
|
84 |
+
)
|
85 |
+
|
86 |
+
# Generate and save confusion matrix
|
87 |
+
cm = confusion_matrix(y_true, y_pred)
|
88 |
+
cm_df = pd.DataFrame(cm)
|
89 |
+
cm_filename = f"./output/version_{version}/confusion_matrix_inference_{version}.csv"
|
90 |
+
cm_df.to_csv(cm_filename, index=False)
|
91 |
+
print(f"Confusion Matrix saved to {cm_filename}")
|
92 |
return accuracy, f1, auc_roc
|
93 |
|
94 |
|
inference_more.ipynb
DELETED
@@ -1,303 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"cells": [
|
3 |
-
{
|
4 |
-
"cell_type": "code",
|
5 |
-
"execution_count": 1,
|
6 |
-
"metadata": {},
|
7 |
-
"outputs": [
|
8 |
-
{
|
9 |
-
"name": "stdout",
|
10 |
-
"output_type": "stream",
|
11 |
-
"text": [
|
12 |
-
"GPU is available: True\n"
|
13 |
-
]
|
14 |
-
}
|
15 |
-
],
|
16 |
-
"source": [
|
17 |
-
"import torch\n",
|
18 |
-
"import torch.nn as nn\n",
|
19 |
-
"import pandas as pd\n",
|
20 |
-
"from model import LSTMModel\n",
|
21 |
-
"from data_loader import create_data_loader\n",
|
22 |
-
"from sklearn.model_selection import train_test_split\n",
|
23 |
-
"from sklearn.metrics import f1_score, roc_auc_score\n",
|
24 |
-
"from keras_preprocessing.sequence import pad_sequences\n",
|
25 |
-
"from torch.utils.data import DataLoader\n",
|
26 |
-
"from data_loader import NewsDataset"
|
27 |
-
]
|
28 |
-
},
|
29 |
-
{
|
30 |
-
"cell_type": "code",
|
31 |
-
"execution_count": 1,
|
32 |
-
"metadata": {},
|
33 |
-
"outputs": [],
|
34 |
-
"source": [
|
35 |
-
"version = 7"
|
36 |
-
]
|
37 |
-
},
|
38 |
-
{
|
39 |
-
"cell_type": "code",
|
40 |
-
"execution_count": 2,
|
41 |
-
"metadata": {},
|
42 |
-
"outputs": [
|
43 |
-
{
|
44 |
-
"name": "stdout",
|
45 |
-
"output_type": "stream",
|
46 |
-
"text": [
|
47 |
-
"Cleaned data found.\n"
|
48 |
-
]
|
49 |
-
}
|
50 |
-
],
|
51 |
-
"source": [
|
52 |
-
"data_path = './data_2/WELFake_Dataset.csv'\n",
|
53 |
-
"cleaned_path = f'./output/version_{version}/cleaned_news_data_{version}.csv'\n",
|
54 |
-
"\n",
|
55 |
-
"# Load data\n",
|
56 |
-
"df = pd.read_csv(cleaned_path)\n",
|
57 |
-
"df.dropna(inplace=True)\n",
|
58 |
-
"print(\"Cleaned data found.\")"
|
59 |
-
]
|
60 |
-
},
|
61 |
-
{
|
62 |
-
"cell_type": "code",
|
63 |
-
"execution_count": 3,
|
64 |
-
"metadata": {},
|
65 |
-
"outputs": [],
|
66 |
-
"source": [
|
67 |
-
"from preprocessing import preprocess_text, load_tokenizer, prepare_data\n",
|
68 |
-
"tokenizer = load_tokenizer(f'./output/version_{version}/tokenizer_{version}.pickle')"
|
69 |
-
]
|
70 |
-
},
|
71 |
-
{
|
72 |
-
"cell_type": "code",
|
73 |
-
"execution_count": 4,
|
74 |
-
"metadata": {},
|
75 |
-
"outputs": [],
|
76 |
-
"source": [
|
77 |
-
"train_val, test = train_test_split(df, test_size=0.2, random_state=42)\n",
|
78 |
-
"train, val = train_test_split(\n",
|
79 |
-
"\ttrain_val, test_size=0.25, random_state=42) # 0.25 * 0.8 = 0.2"
|
80 |
-
]
|
81 |
-
},
|
82 |
-
{
|
83 |
-
"cell_type": "code",
|
84 |
-
"execution_count": 5,
|
85 |
-
"metadata": {},
|
86 |
-
"outputs": [],
|
87 |
-
"source": [
|
88 |
-
"# Tokenize the data\n",
|
89 |
-
"X_train_title = tokenizer.texts_to_sequences(train['title'])\n",
|
90 |
-
"X_train_text = tokenizer.texts_to_sequences(train['text'])\n",
|
91 |
-
"X_val_title = tokenizer.texts_to_sequences(val['title'])\n",
|
92 |
-
"X_val_text = tokenizer.texts_to_sequences(val['text'])\n",
|
93 |
-
"X_test_title = tokenizer.texts_to_sequences(test['title'])\n",
|
94 |
-
"X_test_text = tokenizer.texts_to_sequences(test['text'])\n",
|
95 |
-
"\n",
|
96 |
-
"# Padding sequences\n",
|
97 |
-
"max_length = 500\n",
|
98 |
-
"X_train_title = pad_sequences(X_train_title, maxlen=max_length)\n",
|
99 |
-
"X_train_text = pad_sequences(X_train_text, maxlen=max_length)\n",
|
100 |
-
"X_val_title = pad_sequences(X_val_title, maxlen=max_length)\n",
|
101 |
-
"X_val_text = pad_sequences(X_val_text, maxlen=max_length)\n",
|
102 |
-
"X_test_title = pad_sequences(X_test_title, maxlen=max_length)\n",
|
103 |
-
"X_test_text = pad_sequences(X_test_text, maxlen=max_length)"
|
104 |
-
]
|
105 |
-
},
|
106 |
-
{
|
107 |
-
"cell_type": "code",
|
108 |
-
"execution_count": 6,
|
109 |
-
"metadata": {},
|
110 |
-
"outputs": [],
|
111 |
-
"source": [
|
112 |
-
"device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")"
|
113 |
-
]
|
114 |
-
},
|
115 |
-
{
|
116 |
-
"cell_type": "code",
|
117 |
-
"execution_count": 7,
|
118 |
-
"metadata": {},
|
119 |
-
"outputs": [],
|
120 |
-
"source": [
|
121 |
-
"model = LSTMModel(len(tokenizer.word_index) + 1).to(device)\n",
|
122 |
-
"\n",
|
123 |
-
"# Convert data to PyTorch tensors\n",
|
124 |
-
"train_data = NewsDataset(torch.tensor(X_train_title), torch.tensor(\n",
|
125 |
-
"\tX_train_text), torch.tensor(train['label'].values))\n",
|
126 |
-
"val_data = NewsDataset(torch.tensor(X_val_title), torch.tensor(\n",
|
127 |
-
"\tX_val_text), torch.tensor(val['label'].values))\n",
|
128 |
-
"test_data = NewsDataset(torch.tensor(X_test_title), torch.tensor(\n",
|
129 |
-
"\tX_test_text), torch.tensor(test['label'].values))\n",
|
130 |
-
"\n",
|
131 |
-
"train_loader = DataLoader(train_data, batch_size=32,\n",
|
132 |
-
"\t\t\t\t\t\t\tshuffle=True, num_workers=6, pin_memory=True, persistent_workers=True)\n",
|
133 |
-
"val_loader = DataLoader(val_data, batch_size=32,\n",
|
134 |
-
"\t\t\t\t\t\tshuffle=False, num_workers=6, pin_memory=True, persistent_workers=True)\n",
|
135 |
-
"test_loader = DataLoader(test_data, batch_size=32,\n",
|
136 |
-
"\t\t\t\t\t\t\tshuffle=False, num_workers=6, pin_memory=True, persistent_workers=True)\n",
|
137 |
-
"\n",
|
138 |
-
"criterion = nn.BCELoss()\n",
|
139 |
-
"optimizer = torch.optim.Adam(model.parameters(), lr=0.001)"
|
140 |
-
]
|
141 |
-
},
|
142 |
-
{
|
143 |
-
"cell_type": "code",
|
144 |
-
"execution_count": 8,
|
145 |
-
"metadata": {},
|
146 |
-
"outputs": [
|
147 |
-
{
|
148 |
-
"name": "stdout",
|
149 |
-
"output_type": "stream",
|
150 |
-
"text": [
|
151 |
-
"Test Accuracy: 98.70%, F1 Score: 0.9868, AUC-ROC: 0.9984\n"
|
152 |
-
]
|
153 |
-
}
|
154 |
-
],
|
155 |
-
"source": [
|
156 |
-
"model.load_state_dict(torch.load(f\"./output/version_{version}/best_model_{version}.pth\", map_location=device))\n",
|
157 |
-
"\n",
|
158 |
-
"# Testing\n",
|
159 |
-
"model.eval()\n",
|
160 |
-
"true_labels = []\n",
|
161 |
-
"predicted_labels = []\n",
|
162 |
-
"predicted_probs = []\n",
|
163 |
-
"\n",
|
164 |
-
"with torch.no_grad():\n",
|
165 |
-
"\tcorrect = 0\n",
|
166 |
-
"\ttotal = 0\n",
|
167 |
-
"\tfor titles, texts, labels in test_loader:\n",
|
168 |
-
"\t\ttitles, texts, labels = titles.to(device), texts.to(\n",
|
169 |
-
"\t\t\tdevice), labels.to(device).float()\n",
|
170 |
-
"\t\toutputs = model(titles, texts).squeeze()\n",
|
171 |
-
"\n",
|
172 |
-
"\t\tpredicted = (outputs > 0.5).float()\n",
|
173 |
-
"\t\ttotal += labels.size(0)\n",
|
174 |
-
"\t\tcorrect += (predicted == labels).sum().item()\n",
|
175 |
-
"\t\ttrue_labels.extend(labels.cpu().numpy())\n",
|
176 |
-
"\t\tpredicted_labels.extend(predicted.cpu().numpy())\n",
|
177 |
-
"\t\tpredicted_probs.extend(outputs.cpu().numpy())\n",
|
178 |
-
"\n",
|
179 |
-
"test_accuracy = 100 * correct / total\n",
|
180 |
-
"f1 = f1_score(true_labels, predicted_labels)\n",
|
181 |
-
"auc_roc = roc_auc_score(true_labels, predicted_probs)\n",
|
182 |
-
"\n",
|
183 |
-
"print(\n",
|
184 |
-
"\tf'Test Accuracy: {test_accuracy:.2f}%, F1 Score: {f1:.4f}, AUC-ROC: {auc_roc:.4f}')\n",
|
185 |
-
"\n",
|
186 |
-
"# Create DataFrame and Save to CSV\n",
|
187 |
-
"confusion_data = pd.DataFrame(\n",
|
188 |
-
"\t{'True': true_labels, 'Predicted': predicted_labels})\n",
|
189 |
-
"confusion_data.to_csv('confusion_matrix_data.csv', index=False)"
|
190 |
-
]
|
191 |
-
},
|
192 |
-
{
|
193 |
-
"cell_type": "code",
|
194 |
-
"execution_count": 36,
|
195 |
-
"metadata": {},
|
196 |
-
"outputs": [
|
197 |
-
{
|
198 |
-
"name": "stdout",
|
199 |
-
"output_type": "stream",
|
200 |
-
"text": [
|
201 |
-
" title \\\n",
|
202 |
-
"0 Trump’s creating just the kind of legal chaos ... \n",
|
203 |
-
"\n",
|
204 |
-
" text \n",
|
205 |
-
"0 Donald Trump’s request to the Supreme Court o... \n",
|
206 |
-
"outputs: 0.5209237933158875\n"
|
207 |
-
]
|
208 |
-
},
|
209 |
-
{
|
210 |
-
"ename": "TypeError",
|
211 |
-
"evalue": "iteration over a 0-d array",
|
212 |
-
"output_type": "error",
|
213 |
-
"traceback": [
|
214 |
-
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
215 |
-
"\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)",
|
216 |
-
"Cell \u001b[1;32mIn[36], line 30\u001b[0m\n\u001b[0;32m 28\u001b[0m outputs \u001b[38;5;241m=\u001b[39m predict(model, titles, texts, device)\n\u001b[0;32m 29\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124moutputs: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00moutputs\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m---> 30\u001b[0m \u001b[43mpredictions\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mextend\u001b[49m\u001b[43m(\u001b[49m\u001b[43moutputs\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcpu\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnumpy\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 31\u001b[0m predicted_labels \u001b[38;5;241m=\u001b[39m [\u001b[38;5;241m1\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m p \u001b[38;5;241m>\u001b[39m \u001b[38;5;241m0.5\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;241m0\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m p \u001b[38;5;129;01min\u001b[39;00m predictions]\n\u001b[0;32m 33\u001b[0m \u001b[38;5;28mprint\u001b[39m(predictions)\n",
|
217 |
-
"\u001b[1;31mTypeError\u001b[0m: iteration over a 0-d array"
|
218 |
-
]
|
219 |
-
}
|
220 |
-
],
|
221 |
-
"source": [
|
222 |
-
"import numpy as np\n",
|
223 |
-
"from inference import predict, load_model\n",
|
224 |
-
"predictions = []\n",
|
225 |
-
"\n",
|
226 |
-
"user_title = input(\"Enter title: \")\n",
|
227 |
-
"user_text = input(\"Enter text: \")\n",
|
228 |
-
"\n",
|
229 |
-
"\n",
|
230 |
-
"# Creating the DataFrame with the user's input\n",
|
231 |
-
"df = pd.DataFrame({'title': [user_title], 'text': [user_text]})\n",
|
232 |
-
"print(df.head())\n",
|
233 |
-
"\n",
|
234 |
-
"df['title'] = df['title'].apply(preprocess_text)\n",
|
235 |
-
"df['text'] = df['text'].apply(preprocess_text)\n",
|
236 |
-
"\n",
|
237 |
-
"tokenizer = load_tokenizer(f\"./output/version_{version}/tokenizer_{version}.pickle\")\n",
|
238 |
-
"model = load_model(f\"./output/version_{version}/best_model_{version}.pth\", len(tokenizer.word_index) + 1)\n",
|
239 |
-
"title = prepare_data(df[\"title\"], tokenizer)\n",
|
240 |
-
"text = prepare_data(df[\"text\"], tokenizer)\n",
|
241 |
-
"\n",
|
242 |
-
"# Create DataLoader\n",
|
243 |
-
"data_loader = create_data_loader(\n",
|
244 |
-
" title, text, batch_size=32, shuffle=False)\n",
|
245 |
-
"model.eval()\n",
|
246 |
-
"model.to(device)\n",
|
247 |
-
"for titles, texts in data_loader:\n",
|
248 |
-
" titles, texts = titles.to(device), texts.to(device)\n",
|
249 |
-
" outputs = predict(model, titles, texts, device)\n",
|
250 |
-
" print(f\"outputs: {outputs}\")\n",
|
251 |
-
" # predictions.extend(outputs.cpu().numpy())\n",
|
252 |
-
"predicted_labels = [1 if p > 0.5 else 0 for p in predictions]\n",
|
253 |
-
"\n",
|
254 |
-
"print(predictions)\n",
|
255 |
-
"print(predicted_labels)"
|
256 |
-
]
|
257 |
-
},
|
258 |
-
{
|
259 |
-
"cell_type": "code",
|
260 |
-
"execution_count": 18,
|
261 |
-
"metadata": {},
|
262 |
-
"outputs": [
|
263 |
-
{
|
264 |
-
"name": "stdout",
|
265 |
-
"output_type": "stream",
|
266 |
-
"text": [
|
267 |
-
" title text\n",
|
268 |
-
"0 hello title hello this is text\n"
|
269 |
-
]
|
270 |
-
}
|
271 |
-
],
|
272 |
-
"source": [
|
273 |
-
"user_title = input(\"Enter title: \")\n",
|
274 |
-
"user_text = input(\"Enter text: \")\n",
|
275 |
-
"\n",
|
276 |
-
"# Creating the DataFrame with the user's input\n",
|
277 |
-
"df = pd.DataFrame({'title': [user_title], 'text': [user_text]})\n",
|
278 |
-
"print(df.head())"
|
279 |
-
]
|
280 |
-
}
|
281 |
-
],
|
282 |
-
"metadata": {
|
283 |
-
"kernelspec": {
|
284 |
-
"display_name": "torch",
|
285 |
-
"language": "python",
|
286 |
-
"name": "python3"
|
287 |
-
},
|
288 |
-
"language_info": {
|
289 |
-
"codemirror_mode": {
|
290 |
-
"name": "ipython",
|
291 |
-
"version": 3
|
292 |
-
},
|
293 |
-
"file_extension": ".py",
|
294 |
-
"mimetype": "text/x-python",
|
295 |
-
"name": "python",
|
296 |
-
"nbconvert_exporter": "python",
|
297 |
-
"pygments_lexer": "ipython3",
|
298 |
-
"version": "3.10.11"
|
299 |
-
}
|
300 |
-
},
|
301 |
-
"nbformat": 4,
|
302 |
-
"nbformat_minor": 2
|
303 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
output/version_9/confusion_matrix_inference_9.csv
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:09d71ceae9eb13f58f314dd4c57a5437eab58a7f9419cb5ffa85857cabe9e6b1
|
3 |
+
size 22
|
test.ipynb
DELETED
@@ -1,93 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"cells": [
|
3 |
-
{
|
4 |
-
"cell_type": "code",
|
5 |
-
"execution_count": 1,
|
6 |
-
"metadata": {},
|
7 |
-
"outputs": [
|
8 |
-
{
|
9 |
-
"name": "stdout",
|
10 |
-
"output_type": "stream",
|
11 |
-
"text": [
|
12 |
-
"GPU is available: True\n"
|
13 |
-
]
|
14 |
-
},
|
15 |
-
{
|
16 |
-
"name": "stderr",
|
17 |
-
"output_type": "stream",
|
18 |
-
"text": [
|
19 |
-
"c:\\Users\\kimi\\anaconda3\\envs\\torch\\lib\\site-packages\\spacy\\util.py:910: UserWarning: [W095] Model 'en_core_web_sm' (3.5.0) was trained with spaCy v3.5.0 and may not be 100% compatible with the current version (3.7.2). If you see errors or degraded performance, download a newer compatible model or retrain your custom model with the current spaCy version. For more details and available updates, run: python -m spacy validate\n",
|
20 |
-
" warnings.warn(warn_msg)\n"
|
21 |
-
]
|
22 |
-
}
|
23 |
-
],
|
24 |
-
"source": [
|
25 |
-
"import torch\n",
|
26 |
-
"import torch.nn as nn\n",
|
27 |
-
"import pandas as pd\n",
|
28 |
-
"from model import LSTMModel\n",
|
29 |
-
"from preprocessing import preprocess_text\n",
|
30 |
-
"from data_loader import create_data_loader\n",
|
31 |
-
"from sklearn.model_selection import train_test_split\n",
|
32 |
-
"from sklearn.metrics import f1_score, roc_auc_score\n",
|
33 |
-
"from keras.preprocessing.text import Tokenizer\n",
|
34 |
-
"from keras_preprocessing.sequence import pad_sequences\n",
|
35 |
-
"import pickle\n",
|
36 |
-
"import train as tr\n",
|
37 |
-
"from torch.utils.data import Dataset, DataLoader\n",
|
38 |
-
"from data_loader import NewsDataset"
|
39 |
-
]
|
40 |
-
},
|
41 |
-
{
|
42 |
-
"cell_type": "code",
|
43 |
-
"execution_count": null,
|
44 |
-
"metadata": {},
|
45 |
-
"outputs": [],
|
46 |
-
"source": [
|
47 |
-
"fake_path = './data_1/Fake.csv'\n",
|
48 |
-
"true_path = './data_1/True.csv'\n",
|
49 |
-
"\n",
|
50 |
-
"print(\"No cleaned data found. Cleaning data now...\")\n",
|
51 |
-
"# Load the datasets\n",
|
52 |
-
"true_news = pd.read_csv('data_1/True.csv')\n",
|
53 |
-
"fake_news = pd.read_csv('data_1/Fake.csv')\n",
|
54 |
-
"\n",
|
55 |
-
"# Add labels\n",
|
56 |
-
"true_news['label'] = 1\n",
|
57 |
-
"fake_news['label'] = 0\n",
|
58 |
-
"\n",
|
59 |
-
"# Combine the datasets\n",
|
60 |
-
"df = pd.concat([true_news, fake_news], ignore_index=True)\n",
|
61 |
-
"\n",
|
62 |
-
"# Drop unnecessary columns\n",
|
63 |
-
"df.drop(columns=['subject', 'date'], inplace=True)\n",
|
64 |
-
"\n",
|
65 |
-
"df['title'] = df[0]['title'].apply(preprocess_text)\n",
|
66 |
-
"df['text'] = df[0]['text'].apply(preprocess_text)\n",
|
67 |
-
"\n",
|
68 |
-
"df.to_csv('test.csv', index=False)"
|
69 |
-
]
|
70 |
-
}
|
71 |
-
],
|
72 |
-
"metadata": {
|
73 |
-
"kernelspec": {
|
74 |
-
"display_name": "torch",
|
75 |
-
"language": "python",
|
76 |
-
"name": "python3"
|
77 |
-
},
|
78 |
-
"language_info": {
|
79 |
-
"codemirror_mode": {
|
80 |
-
"name": "ipython",
|
81 |
-
"version": 3
|
82 |
-
},
|
83 |
-
"file_extension": ".py",
|
84 |
-
"mimetype": "text/x-python",
|
85 |
-
"name": "python",
|
86 |
-
"nbconvert_exporter": "python",
|
87 |
-
"pygments_lexer": "ipython3",
|
88 |
-
"version": "3.10.11"
|
89 |
-
}
|
90 |
-
},
|
91 |
-
"nbformat": 4,
|
92 |
-
"nbformat_minor": 2
|
93 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
train_analysis.ipynb
ADDED
The diff for this file is too large to render.
See raw diff
|
|