Shanraq.org Shanraq.org
IT

AI без LLM: создаем свою модель ИИ Урок 23 из 30

Урок 23. Учимся распознавать тип вопроса по примерам

Ученик замечает, что в карточках о времени часто есть «қашан», а в карточках о месте — «қайда». Мы дадим программе посчитать такие совпадения. Это маленький классификатор: он выбирает один из известных видов вопроса, не знает фактов о кружке и не строит свободный текст.

Текст переведён с помощью ИИ.

Зачем это нужно

Ученик замечает, что в карточках о времени часто есть «қашан», а в карточках о месте — «қайда». Мы дадим программе посчитать такие совпадения. Это маленький классификатор: он выбирает один из известных видов вопроса, не знает фактов о кружке и не строит свободный текст.

До программы

Возьмите examples.json из папки шага 23; там 13 открытых карточек из конвертов обучения и настройки; контрольный конверт пока закрыт. Признак — заметная часть вопроса. Для каждого слова берём целое слово и его первые четыре буквы: word[:4] означает «от начала до позиции 4, саму позицию 4 не включать». Короткое слово может дать тот же признак дважды; в этом учебном счётчике мы оставляем оба вклада. weights хранит, сколько раз признак встретился в обучающих вопросах каждого типа. feature not in weights означает, что запись ещё надо создать.

Скопируйте examples.json в ту же папку, что и программа. Печатать все 13 карточек повторно не нужно: формат объяснён в уроке 22.

Из корня проекта перейдите в папку шага и запустите программу:

cd course/kazakh-ai/step-23
python3 classifier.py

В Windows вместо последней команды выполните py classifier.py.

import json

with open("examples.json", encoding="utf-8") as file:
    rows = json.load(file)
weights = {}
for row in rows:
    if row["split"] == "train":
        words = row["text"].lower().replace("?", "").replace(",", "").split()
        for word in words:
            for feature in [word, word[:4]]:
                if feature not in weights:
                    weights[feature] = {"уақыт": 0, "орын": 0}
                weights[feature][row["label"]] += 1
for row in rows:
    if row["split"] == "tune":
        scores = {"уақыт": 0, "орын": 0}
        words = row["text"].lower().replace("?", "").replace(",", "").split()
        for word in words:
            for feature in [word, word[:4]]:
                if feature in weights:
                    scores["уақыт"] += weights[feature]["уақыт"]
                    scores["орын"] += weights[feature]["орын"]
        if scores["уақыт"] > scores["орын"]:
            prediction = "уақыт"
        elif scores["орын"] > scores["уақыт"]:
            prediction = "орын"
        else:
            prediction = "білмеймін"
        print(row["text"], "→", prediction)

Файлы шага.

Как работает код

Код читает для обучения только train. weights[feature][row["label"]] += 1 прибавляет счётчик признака для человеческой метки. Затем для каждого вопроса tune суммирует знакомые счётчики в scores. Больший счёт побеждает; при равенстве выводим білмеймін. Это частоты, не вероятности и не уверенность. На вопрос Шахмат қашан және қайда өтеді? Уақыты қандай? классификатор ошибочно выбирает время: два признака времени перевесили один признак места. В следующем уроке добавим явное правило остановки.

Опорная карта

train → слова и первые 4 буквы → счётчики по меткам → tune → сравнить два счёта → тип или отказ.

Вспомните и проверьте

Закройте код и объясните, почему Шахмат нешеде? получает отказ: в обучении не было слова нешеде, а название кружка одинаково часто встречалось с обеими метками. Эталон вывода для пяти tune вопросов: уақыт, орын, білмеймін, білмеймін, уақыт. Подсказка: посчитайте, сколько раз встречались признаки қашан, қайда и уақыты. Частая ошибка: считать большой счёт доказательством, что вопрос однозначен.

Если вы нашли ошибку или опечатку в тексте статьи, то сообщите нам об этом

Комментарии (0)

Пока нет комментариев. Будьте первым.