Как найти закономерности между многочисленными причинами и результатом в Python?
Для каждого экземпляра у меня есть набор проблем и результат, например:
df = pd.DataFrame({
"problems": [[1,2,3], [1,2,4], [1,4,5], [3,4,5], [1,5,6]],
"results": ["A", "A", "C", "C", "A"]
})
Я хочу найти закономерности во взаимосвязи между проблемами и результатом.
Моей первой мыслью был майнинг правил ассоциации, но это больше для поиска шаблонов внутри проблем (например). Я предполагаю, что машинное обучение могло бы как-то помочь, но меня интересует не только предсказание результата, а модели, которые приводят к этому предсказанию.
Мне были бы интересны паттерны вроде
- Проблема 1 вызывает результат A
- Комбинация задач 4 и 5 дает результат C
Есть мысли по этому поводу? Как я бы реализовал с Python, соответствующие пакеты также приветствуются.
Большое спасибо!
1 ответ
Мне было любопытно, и я проделал кое-какие эксперименты, основываясь на комментарии Даниэля Мёллера в этой теме в tensorflow 2.0 с keras:
Обновление: сделайте заказ больше неважным:
Чтобы сделать заказ больше не матовым, нам нужно удалить информацию о заказе из нашего набора данных. Для этого мы сначала преобразуем его в горячий вектор, а затем берем значение max(), чтобы снова сжать размеры до 3:
x_no_order = tf.keras.utils.to_categorical(x)
Это дает нам горячий вектор, который выглядит так:
array([[[0., 1., 0., 0., 0., 0., 0.],
[0., 0., 1., 0., 0., 0., 0.],
[0., 0., 0., 1., 0., 0., 0.]],
[[0., 1., 0., 0., 0., 0., 0.],
[0., 0., 1., 0., 0., 0., 0.],
[0., 0., 0., 0., 1., 0., 0.]],
[[0., 1., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 1., 0., 0.],
[0., 0., 0., 0., 0., 1., 0.]],
[[0., 0., 0., 1., 0., 0., 0.],
[0., 0., 0., 0., 1., 0., 0.],
[0., 0., 0., 0., 0., 1., 0.]],
[[0., 1., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 1., 0.],
[0., 0., 0., 0., 0., 0., 1.]]], dtype=float32)
Принимая np.max()
из этого вектора дает нам вектор, который знает только о том, какие числа встречаются, без какой-либо информации о позиции, выглядит так:
x_no_order.max(axis=1)
array([[0., 1., 1., 1., 0., 0., 0.],
[0., 1., 1., 0., 1., 0., 0.],
[0., 1., 0., 0., 1., 1., 0.],
[0., 0., 0., 1., 1., 1., 0.],
[0., 1., 0., 0., 0., 1., 1.]], dtype=float32)
Сначала создайте фрейм данных и создайте данные для обучения
Это задача многоклассовой классификации, поэтому я использую токенизатор (наверняка есть лучшие подходы, так как это скорее для текста)
import tensorflow as tf
import numpy as np
import pandas as pd
df = pd.DataFrame({
"problems": [[1,2,3], [1,2,4], [1,4,5], [3,4,5], [1,5,6]],
"results": ["A", "A", "C", "C", "A"]
})
x = df['problems']
y = df['results']
tokenizer = tf.keras.preprocessing.text.Tokenizer()
tokenizer.fit_on_texts(y)
y_train = tokenizer.texts_to_sequences(y)
x = np.array([np.array(i,dtype=np.int32) for i in x])
y_train = np.array(y_train, dtype=np.int32)
** Затем создайте модель **
input_layer = tf.keras.layers.Input(shape=(3))
dense_layer = tf.keras.layers.Dense(6)(input_layer)
dense_layer2 = tf.keras.layers.Dense(20)(dense_layer)
out_layer = tf.keras.layers.Dense(3, activation="softmax")(dense_layer2)
model = tf.keras.Model(inputs=[input_layer], outputs=[out_layer])
model.compile(optimizer="Nadam", loss="sparse_categorical_crossentropy",metrics=["accuracy"])
Обучите модель, подогнав ее
hist = model.fit(x,y_train, epochs=100)
Затем, согласно комментарию Дэниэлса, вы берете последовательность, которую хотите проверить, и маскируете определенные значения, чтобы проверить их влияние.
arr =np.reshape(np.array([1,2,3]), (1,3))
print(model.predict(arr))
arr =np.reshape(np.array([0,2,3]), (1,3))
print(model.predict(arr))
arr =np.reshape(np.array([1,0,3]), (1,3))
print(model.predict(arr))
arr =np.reshape(np.array([1,2,0]), (1,3))
print(model.predict(arr))
Это напечатает этот результат, имейте в виду, что, поскольку y начинается с единицы, первое значение является заполнителем, поэтому второе значение обозначает "A".
[[0.00441748 0.7981055 0.19747704]]
[[0.00103579 0.9863035 0.01266076]]
[[0.0031549 0.9953074 0.00153765]]
[[0.01631758 0.00633342 0.977349 ]]
Здесь мы видим, что, во-первых, A правильно предсказано на 0,7981.. Когда из [1,2,3] мы меняем 3 на 0, поэтому [1,2,0] мы видим, что модель внезапно предсказывает "C". Таким образом, влияние числа 3 на позицию 3 самое большое. Поместив это в функцию, вы можете использовать все имеющиеся у вас обучающие данные и построить статистические показатели для дальнейшего анализа.
Это очень простой подход, но имейте в виду, что это большая область исследований, называемая анализом чувствительности. Если вам интересно, вы можете глубже изучить эту тему.