Как выделить и классифицировать признаки только в значимых областях?

Рейтинг: 0Ответов: 2Опубликовано: 22.08.2023

Имеется такие вводные: есть данные, пусть для простоты будут в двухмерном пространстве. Пример на картинке, здесь f1 и f2 - это features (вход), цвет (Y) это - выход. Количество значений выхода известно - здесь количество равно двум (Зеленый и Красный). Количество красных и зеленых точек почти одинаково.

введите сюда описание изображения

Эти данные в общем и целом рандомны. Но среди большого пространства, на самом деле, существуют некие скопления точек одного вида. Например, на картинке выше это: введите сюда описание изображения

То есть мы можем с большой долей вероятности предсказать, что новая точка будет красная, если попала в красный прямоугольник, а зеленая - если попала в зеленый. Если же точка не попала ни в один из этих кластеров - то предсказать результат невозможно.

Собственно вопрос: существует ли алгоритм, который на таком, можно сказать, зашумленном поле сможет найти кластера, где количество одних точек больше других, при этом игнорируя остальное поле, где точек +- одинаково.

Какую это должно решить задачу: здесь я пытаюсь предсказать цвет новой точки по ее координатам (предсказать Y по f1, f2) - но большая часть поля состоит из рандомных значений, поэтому я пытаюсь найти регион, где вероятность выпадения определенного цвета больше, и таким образом я, зная, что точка попадает в такой регион, сказать с бОльшей вероятностью, какого она цвета. Простым подходом у меня не получилось - из-за того, что подавляющая часть данных - рандомна, то нейросеть имеет точность в 0.5 (что логично для рандомных значений) - то есть просто угадывает. Классификация так же не может работать адекватно - из-за тех же причин. Кластеризация не очень подходит - количество исходов мне известно заранее. DBSCAN похож на мою задачу, он опять же выделяет регионы по плотности, а у меня плотность данных +- равномерна на всем поле, отличается только цвет.

Ответы

▲ 1Принят

Хорошо, вот вам пример с искусственными данными и мелким решающим деревом. Чисто для одного кластера. Будет больше кластеров - нужно будет не ограничивать дерево, как я это сделал для наглядности, пусть дальше растёт.

Код

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pylab as plt
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier, plot_tree
from sklearn.metrics import f1_score

# разбрасываем точки
n = 20
X = np.random.rand(n * n, 2)
y = np.random.randint(2, size=n*n)
df = pd.DataFrame({'x1': X[:,0], 'x2': X[:,1], 'y': y})

## перемещаем часть единиц в кластер в углу
idx = df[df.y == 1].sample(frac=0.75).index
df.loc[idx, 'x1'] /= 3
df.loc[idx, 'x2'] /= 3
X = df[['x1', 'x2']]
y = df['y']

# делим данные на трейн/тест
X_train, X_test, y_train, y_test = train_test_split(X, y, shuffle=True, stratify=y)

# строим модель
dtc = DecisionTreeClassifier(max_depth=2, min_impurity_decrease=0.05)
dtc.fit(X_train, y_train)
y_pred = dtc.predict(X_test)

# считаем скор
print('f1 score =', f1_score(y_test, y_pred))

# рисуем графики
plt.figure()
sns.scatterplot(x='x1', y='x2', hue=y, data=X)
plt.title('Все данные')
plt.figure()
sns.scatterplot(x='x1', y='x2', hue=y_test, data=X_test)
plt.title('Тестовые данные')
plt.figure()
sns.scatterplot(x='x1', y='x2', hue=y_pred, data=X_test)
plt.title('Предсказание на тестовых данных')
X_diff = X_test[y_test != y_pred]
y_diff = y_pred[y_test != y_pred]
plt.figure()
sns.scatterplot(x='x1', y='x2', hue=y_diff, data=X_diff)
plt.title('Предсказания, отличающиеся от тестовых данных')

# рисуем наше дерево
plt.figure()
plot_tree(dtc, filled=True);

Вывод:

f1 score = 0.8461538461538461

Графики:

введите сюда описание изображения

введите сюда описание изображения

введите сюда описание изображения

введите сюда описание изображения

Визуализация решающего дерева:

введите сюда описание изображения

Выводы:

Дерево прекрасно выделило кластер в углу графика с помощью всего двух условий. И предсказало класс 1 только в этом углу, собственно. Ну, потому что угадать 1 в остальных местах всё-равно невозможно.

Когда кластеров будет больше и они будут расположены во многих местах, естественно, понадобится больше правил. Но никаких сложностей у дерева всё-равно не должно с этим возникнуть. Главное - не забывать стратифицировать данные, чтобы не получилось так, что в обучающей выборке не окажется достаточного количества представителей обоих классов в каком-либо из кластеров и тогда дерево не сможет этот кластер обнаружить.

Когда кластеров будет очень-очень много, лучше будет видимо всё же перейти к использованию алгоритмов кластеризации, но это другая история, требующая других примеров данных, без которых я не смогу вам с этой задачей помочь. Хотя, видимо, там просто нужно будет найти кластера и для всех точек в кластерах проставить 1, а для всех точек вне кластеров 0. Стандартной какой-то модели для такого подхода вроде бы нет, но используя кластеризацию и несложные ручные действия вы сможете легко это сделать.

▲ 0
  1. K-средних: Это один из наиболее распространенных алгоритмов кластеризации, который использует итеративный подход для разбиения областей на определенное количество кластеров. Алгоритм начинает с инициализации центров кластеров случайными точками, затем он итеративно перераспределяет точки между кластерами, чтобы минимизировать сумму квадратов расстояний между каждой точкой и ее ближайшим центром кластера.

  2. DBSCAN: Это алгоритм кластеризации, который основывается на плотности точек в пространстве. Он начинает с выбора случайной точки и определения всех точек в ее окрестности. Затем он продолжает расширять кластер, добавляя все ближайшие точки, пока не будет достигнута граница плотности. Этот алгоритм может быть особенно полезен для областей, где кластеры имеют различные размеры и формы.

  3. Иерархическая кластеризация: Этот алгоритм начинает с того, что каждая область рассматривается как отдельный кластер. Затем он объединяет близлежащие кластеры, пока все области не будут объединены в один кластер. Этот алгоритм может быть полезен для областей, где кластеры имеют иерархическую структуру или когда требуется разбить области на кластеры различных размеров.