diff --git a/pandas_task.ipynb b/pandas_task.ipynb new file mode 100644 index 0000000..a3f72c8 --- /dev/null +++ b/pandas_task.ipynb @@ -0,0 +1,379 @@ +{ + "cells": [ + { + "cell_type": "code", + "source": [ + "!pip install navec\n", + "!pip install pymystem3\n", + "!wget https://github.com/railbotan/pandas_task/raw/main/works.csv\n", + "!wget http://download.cdn.yandex.net/mystem/mystem-3.0-linux3.1-64bit.tar.gz\n", + "!wget https://storage.yandexcloud.net/natasha-navec/packs/navec_hudlit_v1_12B_500K_300d_100q.tar\n", + "# Mystem google collab fix\n", + "!tar -xvf mystem-3.0-linux3.1-64bit.tar.gz\n", + "!cp mystem /root/.local/bin/mystem" + ], + "metadata": { + "id": "_kX6MyXP7Olc" + }, + "id": "_kX6MyXP7Olc", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "id": "b608bf7d", + "metadata": { + "id": "b608bf7d" + }, + "source": [ + "# ДЗ\n", + "Решение задачи с использованием NLP библиотек.\n", + "Основные: navec - для векторизации слов, Mystem - для лемматизации.\n", + "https://github.com/natasha/navec\n", + "https://yandex.ru/dev/mystem/\n", + "### Принцип работы:\n", + "#### Задание 1 (Сравнение специальности и места работы)\n", + "- Лемматизация входной строки (удаление знаков препинания, привод слов к начальной форме.)\n", + "- Векторизация слов.\n", + "- Поиск косинусного расстояния между словами.\n", + "- Вычисляем среднее всех косинусных расстояний.\n", + "#### Задание 2, 3\n", + "##### фильтрация датафрейма по принципу:\n", + "- Лемматизация входной строки.\n", + "- Поиск вхождений в лемматизированную строку." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "ac08ae0a", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "ac08ae0a", + "outputId": "c75bdc66-50a7-4726-bcaf-1c2cdbf837b5" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "[nltk_data] Downloading package stopwords to /root/nltk_data...\n", + "[nltk_data] Package stopwords is already up-to-date!\n", + "--2021-12-12 04:46:46-- https://storage.yandexcloud.net/natasha-navec/packs/navec_hudlit_v1_12B_500K_300d_100q.tar\n", + "Resolving storage.yandexcloud.net (storage.yandexcloud.net)... 213.180.193.243, 2a02:6b8::1d9\n", + "Connecting to storage.yandexcloud.net (storage.yandexcloud.net)|213.180.193.243|:443... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 53012480 (51M) [application/x-tar]\n", + "Saving to: ‘navec_hudlit_v1_12B_500K_300d_100q.tar.1’\n", + "\n", + "navec_hudlit_v1_12B 100%[===================>] 50.56M 16.5MB/s in 3.1s \n", + "\n", + "2021-12-12 04:46:50 (16.5 MB/s) - ‘navec_hudlit_v1_12B_500K_300d_100q.tar.1’ saved [53012480/53012480]\n", + "\n" + ] + } + ], + "source": [ + "import pandas as pd\n", + "import xml.etree.ElementTree as ET\n", + "from nltk.corpus import stopwords\n", + "from string import punctuation\n", + "from navec import Navec\n", + "import numpy as np\n", + "import scipy.spatial.distance as ds\n", + "from pymystem3 import Mystem\n", + "import nltk\n", + "nltk.download(\"stopwords\")\n", + "mystem = Mystem() \n", + "russian_stopwords = stopwords.words(\"russian\")\n", + "path = 'navec_hudlit_v1_12B_500K_300d_100q.tar'\n", + "navec = Navec.load(path)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "33fe0e5d", + "metadata": { + "id": "33fe0e5d" + }, + "outputs": [], + "source": [ + "f = open(\"works.csv\", encoding=\"utf-8\")\n", + "cv = pd.read_csv(f).dropna()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "300cf1e1", + "metadata": { + "id": "300cf1e1" + }, + "outputs": [], + "source": [ + "m = Mystem()\n", + "def preprocess_text(text):\n", + " tokens = mystem.lemmatize(text.lower())\n", + " tokens = [token for token in tokens if token not in russian_stopwords\\\n", + " and token != \" \" \\\n", + " and token.strip() not in punctuation]\n", + " return tokens" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "0cfc3df8", + "metadata": { + "id": "0cfc3df8" + }, + "outputs": [], + "source": [ + "def vectorise_text(tokens):\n", + " return [navec[t] for t in tokens if t in navec]" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "6cb9fa2a", + "metadata": { + "id": "6cb9fa2a" + }, + "outputs": [], + "source": [ + "def compare_victorise_text(v_tokens1, v_tokens2):\n", + " arr = []\n", + " for i in v_tokens1:\n", + " for j in v_tokens2:\n", + " arr.append(ds.cosine(i, j))\n", + " if len(arr) == 0:\n", + " return(1)\n", + " return np.mean(arr)" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "09c85950", + "metadata": { + "id": "09c85950" + }, + "outputs": [], + "source": [ + "def fast_compare(str1, str2):\n", + " tokens1 = preprocess_text(i)\n", + " tokens2 = preprocess_text(j)\n", + " v_tokens1 = vectorise_text(tokens1)\n", + " v_tokens2 = vectorise_text(tokens2)\n", + " return compare_victorise_text(v_tokens1, v_tokens2)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "38095597", + "metadata": { + "id": "38095597" + }, + "outputs": [], + "source": [ + "def filter_fn(row, search_str):\n", + " return search_str in preprocess_text(row)" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "id": "b5f70663", + "metadata": { + "id": "b5f70663" + }, + "outputs": [], + "source": [ + "def get_top(count,df, return_value, search_str, filter_by):\n", + " return df[df[filter_by].apply(lambda x: filter_fn(x, search_str))][return_value].str.lower().value_counts().head(count)\n" + ] + }, + { + "cell_type": "markdown", + "id": "9eda0559", + "metadata": { + "id": "9eda0559" + }, + "source": [ + "### У какого количества людей профессия и должность не совпадают\n", + "Пример смыслового сравнения строк на данном датасете. Где 0 - Максимальное совпадение, 1 - максимальная разность." + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "id": "0e9ac57d", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "0e9ac57d", + "outputId": "325a8f35-a837-4899-c2c2-97ad542322bd" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Медсестра -> Фельдшер 0.5186181366443634 - 0\n", + "Руководитель проектов -> Менеджер 0.6206537783145905 - 0\n", + "юрист -> юрист с отличием 0.4752016607671976 - 0\n", + "Ведущий специалист отдела сопровождения исполнения контрактов -> Магистр 0.9017206504164884 - 1\n", + "специалист по просроченной задолженности -> Художественный руководитель студии Декоративно-прикладного творчества, преподаватель 0.8946782189554402 - 2\n", + "Кассир-консультант -> Бакалавр 0.8008965440094471 - 3\n", + "Кредитный эксперт -> Экономист 0.7352558933198452 - 4\n", + "Начальник склада -> экономист по специальности \"Бухгалтерский учет, анализ и аудит\" 0.9287371191506585 - 5\n", + "Главный специалист отдела земельных отношений -> Бакалавр 0.9712797600775958 - 6\n", + "старший чабан -> нет 1 - 7\n", + "Ведущий Инженер-конструктор -> инженер 0.33541155854860943 - 7\n", + "помощник бурильщика КРС -> бакалавр 0.8409424610435963 - 8\n", + "Ведущий специалист службы электрических режимов -> Инженер 0.7358635663986206 - 9\n", + "педагог дополнительного образования -> Педагог - психолог 0.6395544037222862 - 9\n", + "МЕХАНИК -> механик 0.0 - 9\n", + "Руководитель подразделения садово-парковое хозяйство – заместитель директора -> Психолог. Преподаватель психологии 0.8305769980108987 - 10\n", + "Заместитель директора -> экономист 0.6902629733085632 - 10\n", + "старший аудитор -> экономист 0.7776699140667915 - 11\n", + "Руководитель центра поддержки клиентов -> Экономист 0.8725750199519098 - 12\n", + "ведущий специалист -> юрист 0.5545924305915833 - 12\n", + "инженер ПТО -> инженер путей сообщения - строитель 0.8144546046387404 - 13\n", + "Продавец-консультант -> Конструктор-модельер 0.7072819471359253 - 13\n", + "Оператор связи 3 класса -> Оператор электронно-вычислительных и вычислительных машин 0.7714040076567067 - 14\n", + "ГИП - Главный инженер по проектированию - Замгендиректора по качеству -> Инженер-строитель 0.6899436535313725 - 14\n", + "менеджер по закупкам -> менеджер 0.49301973450928926 - 14\n", + "Электромеханик -> Техник 0.751757487654686 - 15\n", + "Аккумуляторщик -> Менеджер (по отраслям) 1 - 16\n", + "Менеджер отдела продаж -> 4 разряд 0.9158282391726971 - 17\n", + "Продавец -> Бакалавр 0.9387829862535 - 18\n", + "бухгалтер -> экономист 0.5468444228172302 - 18\n", + "Библиотекарь -> Библиотечный работник 0.6404210776090622 - 18\n", + "...", + "Итог: 718\n" + ] + } + ], + "source": [ + "count = 0\n", + "for i, j in zip(cv[[\"jobTitle\", \"qualification\"]].jobTitle, cv[[\"jobTitle\", \"qualification\"]].qualification):\n", + " comparation_res = fast_compare(i, j)\n", + " if (comparation_res >= 0.72): count += 1\n", + " print(i, \"->\", j, comparation_res, \"-\", count)\n", + "print(\"Итог:\",count)" + ] + }, + { + "cell_type": "markdown", + "id": "9071f9e6", + "metadata": { + "id": "9071f9e6" + }, + "source": [ + "#### Итог: 718\n", + "P.S Всё зависит от порога которым мы выберем, в данном случае - 0.72\n", + "### Люди с каким образованием становятся менеджерами (топ-5):" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "id": "02586c4a", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "02586c4a", + "outputId": "4ac2307c-b0ab-42fe-fa40-0634c041839d" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "бакалавр 10\n", + "менеджер 8\n", + "экономист 6\n", + "специалист 6\n", + "экономист-менеджер 4\n", + "Name: qualification, dtype: int64\n" + ] + } + ], + "source": [ + "print(get_top(5, cv, \"qualification\", \"менеджер\", \"jobTitle\"))" + ] + }, + { + "cell_type": "markdown", + "id": "775e8cbd", + "metadata": { + "id": "775e8cbd" + }, + "source": [ + "### Кем работают люди, которые по диплому являются инженерами (топ-5)" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "id": "0fe08f3e", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "0fe08f3e", + "outputId": "0746d5fe-df76-4209-eebd-7324508f2b30" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "главный инженер 3\n", + "заместитель директора 3\n", + "ведущий инженер-конструктор 2\n", + "инженер лесопользования 2\n", + "директор 2\n", + "Name: jobTitle, dtype: int64\n" + ] + } + ], + "source": [ + "print(get_top(5, cv, \"jobTitle\", \"инженер\" , \"qualification\"))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.8.8" + }, + "colab": { + "name": "pandas_task.ipynb", + "provenance": [] + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file