Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

for education #3

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
135 changes: 113 additions & 22 deletions chapter1/spam-fighting-blacklist.ipynb
Original file line number Diff line number Diff line change
@@ -1,27 +1,43 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## В этом коде используется черный список (Blacklist) для борьбы со спамом в электронной почте"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"import pickle\n",
"import email_read_util"
"# Импорт необходимых модулей\n",
"import os # Модуль для работы с операционной системой\n",
"import pickle # Модуль для сериализации и десериализации объектов Python\n",
"import email_read_util # Модуль для чтения и обработки электронных писем"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Download 2007 TREC Public Spam Corpus\n",
"1. Read the \"Agreement for use\"\n",
"### Скачайте общедоступный корпус спама TREC 2007 года выпуска\n",
"1. Прочитайте \"Соглашение об использовании\"\n",
" https://plg.uwaterloo.ca/~gvcormac/treccorpus07/\n",
"\n",
"2. Download 255 MB Corpus (trec07p.tgz) and untar into the 'chapter1/datasets' directory\n",
"2. Загрузите корпус объемом 255 МБ (trec07p.tgz) и распакуйте в каталог \"глава 1/наборы данных\"\n",
"\n",
"3. Check that the below paths for 'DATA_DIR' and 'LABELS_FILE' exist"
"3. Убедитесь, что указанные ниже пути для \"DATA_DIR\" и \"LABELS_FILE\" существуют"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Загрузка данных:\n",
"### Данные загружаются из каталога datasets/trec07p/data/. Также загружаются метки классов (спам/не спам) из файла datasets/trec07p/full/index. Черный список содержит известные серверы, распространяющие спам, и блокирует письма с таких серверов."
]
},
{
Expand All @@ -30,9 +46,10 @@
"metadata": {},
"outputs": [],
"source": [
"DATA_DIR = 'datasets/trec07p/data/'\n",
"LABELS_FILE = 'datasets/trec07p/full/index'\n",
"TRAINING_SET_RATIO = 0.7"
"# Определение директории с данными и файла с метками\n",
"DATA_DIR = 'datasets/trec07p/data/' # Путь к директории с данными\n",
"LABELS_FILE = 'datasets/trec07p/full/index' # Путь к файлу с метками\n",
"TRAINING_SET_RATIO = 0.7 # Пропорция разделения набора данных на тренировочный и тестовый"
]
},
{
Expand All @@ -41,9 +58,10 @@
"metadata": {},
"outputs": [],
"source": [
"labels = {}\n",
"spam_words = set()\n",
"ham_words = set()"
"# Инициализация пустых структур данных\n",
"labels = {} # Словарь для хранения меток (имя файла: метка)\n",
"spam_words = set() # Множество слов, характерных для спама\n",
"ham_words = set() # Множество слов, характерных для нормальной корреспонденции"
]
},
{
Expand All @@ -52,7 +70,12 @@
"metadata": {},
"outputs": [],
"source": [
"# Read the labels\n",
"# Чтение и обработка файла меток\n",
"with open(LABELS_FILE) as f:\n",
" for line in f:\n",
" line = line.strip()\n",
" label, key = line.split()\n",
" labels[key.split('/')[-1]] = 1 if label.lower() == 'ham' else 0# Чтение и обработка файла меток\n",
"with open(LABELS_FILE) as f:\n",
" for line in f:\n",
" line = line.strip()\n",
Expand All @@ -66,12 +89,28 @@
"metadata": {},
"outputs": [],
"source": [
"# Split corpus into train and test sets\n",
"# Разделение корпуса на тренировочный и тестовый наборы\n",
"filelist = os.listdir(DATA_DIR)\n",
"X_train = filelist[:int(len(filelist)*TRAINING_SET_RATIO)]\n",
"X_test = filelist[int(len(filelist)*TRAINING_SET_RATIO):]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Код загружает данные о транзакциях с кредитными картами и обучает модель на основе черного списка"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Построение/загрузка \"черного списка\":\n",
"### Черный список содержит слова, которые характерны для спам-сообщений и не характерны для нормальных писем.\n",
"### Если файл blacklist.pkl уже существует, черный список загружается из него. В противном случае он строится на основе данных обучающего набора и сохраняется для последующего использования."
]
},
{
"cell_type": "code",
"execution_count": 6,
Expand All @@ -86,6 +125,7 @@
}
],
"source": [
"# Построение или загрузка списка слов-маркеров для спама (blacklist)\n",
"if not os.path.exists('blacklist.pkl'):\n",
" for filename in X_train:\n",
" path = os.path.join(DATA_DIR, filename)\n",
Expand All @@ -105,13 +145,16 @@
"else:\n",
" blacklist = pickle.load(open('blacklist.pkl', 'rb') )\n",
"\n",
" # Печать сообщения о построении или загрузке blacklist\n",
"print('Blacklist of {} tokens successfully built/loaded'.format(len(blacklist)))"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"metadata": {
"scrolled": false
},
"outputs": [
{
"data": {
Expand Down Expand Up @@ -1125,22 +1168,36 @@
}
],
"source": [
"# Импорт модуля NLTK для работы с естественным языком\n",
"from nltk.corpus import words\n",
"word_set = set(words.words())\n",
"# Поиск пересечения blacklist и множества английских слов из NLTK\n",
"word_set.intersection(blacklist)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Анализ текста:\n",
"### Для каждого электронного письма из тестового набора:\n",
"### Текст сообщения анализируется на наличие слов из черного списка. Подсчитывается количество ложноположительных (FP), ложноотрицательных (FN), истинноположительных (TP) и истинноотрицательных (TN) результатов."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"fp = 0\n",
"tp = 0\n",
"fn = 0\n",
"tn = 0\n",
"# Инициализация переменных для подсчета статистики классификации\n",
"fp = 0 # Ложноположительные (ошибочно определенные как спам)\n",
"tp = 0 # Истинноположительные (правильно определенные как спам)\n",
"fn = 0 # Ложноотрицательные (ошибочно определенные как не спам)\n",
"tn = 0 # Истинноотрицательные (правильно определенные как не спам)\n",
"\n",
"\n",
"# Проверка каждого письма из тестового набора и классификация по наличию слов из blacklist\n",
"for filename in X_test:\n",
" path = os.path.join(DATA_DIR, filename)\n",
" if filename in labels:\n",
Expand All @@ -1161,6 +1218,14 @@
" fn = fn + 1"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Визуализация:\n",
"### Строится матрица ошибок для оценки результатов классификации. Выводится процентное соотношение каждой ячейки матрицы ошибок относительно общего количества наблюдений."
]
},
{
"cell_type": "code",
"execution_count": 9,
Expand All @@ -1180,6 +1245,7 @@
}
],
"source": [
"# Вывод матрицы ошибок в HTML-таблице\n",
"from IPython.display import HTML, display\n",
"conf_matrix = [[tn, fp],\n",
" [fn, tp]]\n",
Expand Down Expand Up @@ -1208,6 +1274,7 @@
}
],
"source": [
"# Вывод процентной матрицы ошибок в HTML-таблице\n",
"count = tn + tp + fn + fp\n",
"percent_matrix = [[\"{:.1%}\".format(tn/count), \"{:.1%}\".format(fp/count)],\n",
" [\"{:.1%}\".format(fn/count), \"{:.1%}\".format(tp/count)]]\n",
Expand All @@ -1217,6 +1284,15 @@
" for row in percent_matrix))))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Оценка точности классификации:\n",
"### Вычисляется и выводится процент точности классификации, основанный на количестве правильно классифицированных объектов.\n",
"### Результаты показывают, что классификация имеет точность около 68.6%."
]
},
{
"cell_type": "code",
"execution_count": 11,
Expand All @@ -1231,13 +1307,28 @@
}
],
"source": [
"# Вывод процента правильно классифицированных писем\n",
"print(\"Classification accuracy: {}\".format(\"{:.1%}\".format((tp+tn)/count)))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Этот метод - один из старейших способов фильтрации спама."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
Expand All @@ -1251,7 +1342,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.3"
"version": "3.10.9"
}
},
"nbformat": 4,
Expand Down
Loading