CoderCastrov logo
CoderCastrov
Data Science Zen
просмотров
8 мин чтение
#Наука о данных
Table Of Content

В 2022 году, ближе к концу года, вы пытаетесь найти цифровые издания дхармы, но вам нужна помощь в поиске ваших ценных текстов. И вот, внезапно, вы находите своего спасителя: веб-сайт под названием Zen Marrow! Там есть все возможные тексты, относящиеся к зен-буддизму, которые вам могут понадобиться, но есть один нюанс: все это может быть более организовано. Zen Marrow также может быть поисковой системой, которая предоставляет отрывки из текстов на основе ключевых запросов: введите ключевое слово или фразу и получите совпадения этой фразы в тексте. Однако вам нужен весь лес, а не только одно дерево. Вы понимаете, что когда вы получаете результаты вашего запроса, помимо отрывка с вашим ключевым словом(ами), у вас также есть возможность поделиться разделом, скопировав его URL.

У каждого URL отрывка есть несколько характеристик: ссылка на сам веб-сайт, номер отрывка (его ID) и текст, из которого он взят (его индекс). Каждый раздел отсортирован по порядку для каждого отрывка в индексе: ID 1 - первая глава или случай, ID 2 - вторая и т.д., пока не будет достигнут последний ID отрывка. Если весь этот текст был загружен сюда, то возможно создать, возможно, никогда ранее не виданные цифровые копии этих текстов! Что касается того, как это может быть возможно, то немного программирования может помочь:

# Импортируем классы webdriver и By из модуля selenium
from selenium import webdriver
from selenium.webdriver.common.by import By

# Инициализируем пустую строку для хранения текста из выбранных узлов
output = ""

# Создаем экземпляр webdriver и загружаем URL
driver = webdriver.Chrome()

# Перебираем диапазон ID от a до z (т.е. от 1 до 100)
for i in range(1, 100):
    # Строим URL с использованием форматирования строк и текущего ID
    url = f"https://zenmarrow.com/single?id={i}&index=indexgoeshere"

    # Загружаем URL в webdriver
    driver.get(url)

    # Ждем полной загрузки страницы
    driver.implicitly_wait(10)  # секунды

    # Выбираем узел с классом "case-title"
    case_title = driver.find_element(By.CLASS_NAME, "case-title")

    # Выбираем узел с классом "case-text"
    case_text = driver.find_element(By.CLASS_NAME, "case-text")

    # Получаем текст выбранных узлов
    title = case_title.text
    text = case_text.text

    # Добавляем текст к выходной строке, с переводом строки между заголовком и текстом
    output += title
    output += "\n\n"
    output += text
    output += "\n\n"

# Закрываем webdriver
driver.close()

# Записываем выходную строку в текстовый файл
with open("имя_текста.txt", "w") as f:
    f.write(output)

[ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: пожалуйста, парсите веб-страницы ответственно.]

После этого у вас теперь есть удобная папка с текстами о Зене под рукой; вы могли бы также сохранить их в архиве, чтобы сэкономить другим людям труд и деньги в будущем.


Конечно, это отличается от того, как заканчивается история. Я понял, что могу сделать из этого небольшой проект по анализу данных, и я сделал это. Поскольку мы имеем дело с текстовыми фрагментами, кажется очевидным провести текстовый анализ этой библиотеки, но как? Не беспокойтесь, у нас есть четыре опорных пункта текстового анализа, которые мы будем использовать сегодня: анализ частотности слов, анализ коллокаций, анализ темы и распознавание именованных сущностей. Вот краткое описание каждого из них:

  • Анализ частотности слов - это метод анализа текстового корпуса путем подсчета количества раз, когда каждое слово появляется. Это может быть полезно для определения наиболее часто используемых слов в тексте и для определения слов, которые необычны или неожиданны в контексте текста.
  • Анализ коллокаций - это метод анализа сопоставления слов в текстовом корпусе. Коллокация - это группа слов, часто встречающихся вместе, таких как "крепкий кофе" или "сильный дождь". Анализ коллокаций может использоваться для определения общих фраз или идиом в тексте и для определения слов, которые семантически связаны друг с другом.
  • Анализ темы - это метод определения и анализа основных тем или идей в текстовом корпусе. Это может быть сделано путем частого определения ключевых слов или фраз, встречающихся в тексте, а затем классификации их по темам на основе их значений и отношений друг к другу.
  • Распознавание именованных сущностей (NER) - это техника обработки естественного языка, которая включает идентификацию и извлечение именованных сущностей из текстового корпуса. Именованные сущности включают имена собственные, такие как люди, организации, места и другие сущности, именованные или упомянутые в тексте. NER может извлекать структурированную информацию из неструктурированного текста и часто используется в задачах, таких как извлечение информации и классификация документов.

Начнем с верхней части, вот код для каждой программы для каждого типа текстового анализа:

frequencies.py:

import os
import string
from collections import Counter

# Установите путь к директории
directory = "ЗдесьПутьКДиректорииСТекстовымиФайлами"

# Инициализируйте список для хранения слов из всех текстовых файлов
all_words = []

# Прочитайте список стоп-слов из соответствующего файла
with open("stop_words.txt", "r") as f:
    stop_words = f.read().split()

# Переберите файлы в директории
for filename in os.listdir(directory):
    # Обрабатывайте только текстовые файлы
    if filename.endswith(".txt"):
        # Откройте текстовый файл и прочитайте его содержимое
        with open(os.path.join(directory, filename), "r") as f:
            for line in f:
                # Игнорируйте строки, которые заканчиваются на число, так как они обычно содержат только заголовок
                if not line[-1].isdigit():
                    # Разделите строку на список слов и добавьте их в список всех слов
                    all_words.extend(word.strip(string.punctuation).lower() for word in line.split() if word.strip(string.punctuation).lower() not in stop_words)

# Подсчитайте частоту каждого слова с помощью класса Counter
word_counts = Counter(all_words)

# Откройте файл для записи частоты слов и запишите в него результаты
with open("word_frequencies.txt", "w") as f:
    for word, count in word_counts.most_common():
        f.write(f"{word}: {count}\n")

collocations.py:

import os
import re
from collections import Counter
from nltk import collocations

# Установите директорию, содержащую текстовые файлы
directory = "."

# Инициализируйте список для хранения коллокаций
collocations_list = []

# Переберите каждый текстовый файл в директории
for file in os.listdir(directory):
    if file.endswith(".txt"):
        # Откройте файл и прочитайте его содержимое
        with open(os.path.join(directory, file), "r") as f:
            text = f.read()

        # Удалите все знаки препинания и символы из текста
        text = re.sub(r'[^\w\s]', '', text)

        # Разделите текст на список токенов (слова и знаки препинания)
        tokens = text.split()

        # Используйте модуль коллокаций NLTK для поиска биграмм в тексте
        bigram_finder = collocations.BigramCollocationFinder.from_words(tokens)

        # Используйте поиск биграмм для создания списка биграмм и их частотности
        bigrams = bigram_finder.ngram_fd.items()

        # Добавьте биграммы и их частотность в список коллокаций
        collocations_list.extend(bigrams)

# Запишите коллокации в текстовый файл
with open("collocations.txt", "w") as f:
  f.write(str(collocations_list))

themes.py:

import os
import spacy

# Загрузка предварительно обученной модели обработки естественного языка с использованием spacy
nlp = spacy.load("en_core_web_sm")

def generate_themes(directory):
    themes = {}

    for file in os.listdir(directory):
        with open(os.path.join(directory, file), "r") as f:
            contents = f.read()
            # Извлечение тем из текста с использованием spacy
            doc = nlp(contents)
            for entity in doc.ents:
                theme = entity.text
                if theme in themes:
                    themes[theme] += 1
                else:
                    themes[theme] = 1

    return themes

# Вызов функции и передача пути каталога в качестве аргумента
themes = generate_themes(".")

# Запись тем и их количества в текстовый файл, отсортированных по количеству в порядке убывания
with open("themes.txt", "w") as f:
    for theme, count in sorted(themes.items(), key=lambda x: x[1], reverse=True):
        f.write(f'{theme}: {count}\n')

entities.py:

import nltk
import spacy
import os

# Установка NLTK для анализа коллокаций и идентификации темы
nltk.download("collocations")
nltk.download("punkt")
nltk.download("stopwords")

# Установка spaCy для распознавания именованных сущностей
nlp = spacy.load("en_core_web_sm")

# Перебор файлов .txt в директории
for file in os.listdir("ZenDirectoryGoesHere"):
    if file.endswith(".txt"):
        # Чтение текста из файла
        with open(file, 'r') as f:
            text = f.read()
        
        # Предварительная обработка текста для анализа коллокаций и идентификации темы
        tokens = nltk.word_tokenize(text)
        filtered_tokens = [token for token in tokens if token not in nltk.corpus.stopwords.words("english")]
        bigrams = nltk.bigrams(filtered_tokens)
        finder = nltk.BigramCollocationFinder.from_words(bigrams)
        finder.apply_freq_filter(3)
        collocations = finder.nbest(nltk.collocations.BigramAssocMeasures().pmi, 10)
        themes = nltk.Text(filtered_tokens).collocations()
        
        # Выполнение распознавания именованных сущностей с использованием spaCy
        doc = nlp(text)
        entities = [(entity.text, entity.label_) for entity in doc.ents]
        
        # Запись результатов анализа в файл .txt
        with open("entities.txt", "w") as f:
            f.write(str(entities))

После небольшой ручной предварительной обработки и подачи данных в matplotlib, word cloud и другие библиотеки, мы получаем эту галерею красивых изображений:

Collocations Entities Word frequencies Themes

Выглядит красиво, но что это все значит? Давайте пройдемся по каждому изображению по очереди и разберем его.

АНАЛИЗ ЧАСТОТЫ СЛОВ:

Это достаточно просто, по оси x (freqs, для частоты) отображается количество вхождений слов, обозначенных на оси y. Далее у нас есть:

АНАЛИЗ КОЛЛОКАЦИЙ:

Круговое расположение, каждая биграмма (пара слов) связана друг с другом, и если когда-либо возникает ситуация, когда одно и то же слово может находиться в нескольких парах, это факт выражается несколькими стрелками.

АНАЛИЗ ТЕМЫ:

Для каждой обнаруженной темы также указывается количество раз, которое эта тема появляется. Чем больше появлений темы, тем больше размер шрифта этой темы будет иметь на облаке слов, поэтому тема с наибольшим количеством появлений будет отображаться самым крупным шрифтом по сравнению с другими, и наоборот для темы с наименьшим количеством появлений.

РАСПОЗНАВАНИЕ ИМЕНОВАННЫХ СУЩНОСТЕЙ:

Для каждого типа сущности, присутствующей в тексте (обозначенного на оси x), общий процент встречаемости этого типа отмечен на оси y. Обратите внимание, что в процессе обработки многие потенциальные люди были ошибочно помечены как произведения искусства (например, Линдзи и "Следователи пути"), поэтому если бы это не было так, этот график был бы в основном заполнен сущностями "человек".

ВЫВОД:

Итак, это означает... но что это говорит нам о Зене в целом? Все, что мы знаем наверняка, это то, что истинный путь к просветлению включает в себя много прокрутки плохо организованных отрывков текста на Zen Marrow (не благодаря их зен-фантастическому пользовательскому интерфейсу)!