Одним из вариантов является прямой перевод / преобразование строки путем создания значимого отображения 1 -> 1 (то есть один к одному). В этом случае сохранение порядка выполнимо и имеет значение.
Это простая демонстрация:
data = ['event1,event3,event2,event1', 'event2,event2', 'event1,event2,event3']
def mapper(data):
result = []
for d in data:
events = d.replace(' ', '').split(',')
v = 0
for i, e in enumerate(events):
# for each string: get the sum of char values,
# normalized by their orders
# here 100 is optional, just to make the number small
v += sum(ord(c) for c in e) / (i + 100)
result.append(v)
return result
new_data = mapper(data)
print(new_data)
Вывод:
[23.480727373137086, 11.8609900990099, 17.70393127548049]
Хотя вероятность столкновений очень мала, нет 100% гарантии того, что для набора данных giganti c вообще не будет никаких конфликтов.
Проверьте этот анализ:
# check for clashes on huge dataset
import random as r
import matplotlib.pyplot as plt
r.seed(2020)
def ratio_of_clashes(max_events):
MAX_DATA = 1000000
events_pool = [','.join(['event' + str(r.randint(1, max_events))
for _ in range(r.randint(1, max_events))])
for _ in range(MAX_DATA)]
# print(events_pool[0:10]) # print few to see
mapped_events = mapper(events_pool)
return abs(len(set(mapped_events)) - len(set(events_pool))) / MAX_DATA * 100
n_samples = range(5, 100)
ratios = []
for i in n_samples:
ratios.append(ratio_of_clashes(i))
plt.plot(n_samples, ratios)
plt.title('The Trend of Crashes with Change of Number of Events')
plt.show()
В результате, чем меньше у вас событий или данных, тем меньше коэффициент столкновений, пока он не достигнет некоторого порогового значения, а затем сглаживается - однако это в конце концов неплохо вообще (Лично я могу жить с этим).
Обновление и окончательные мысли:
Я только что заметил, что вы уже используете LSTM, таким образом, порядок крайне важен. В этом случае я настоятельно рекомендую вам кодировать события в целые числа, затем создавать временные ряды, которые идеально вписываются в LSTM, и выполнять следующие действия:
- Предварительно обрабатывать каждую строку и разбивать их на события (как Я сделал в примере).
- Подогнать LabelEncoder на них и преобразовать их в целые числа.
- Масштабировать результат в [0 - 1] путем подгонки MinMaxScaler .
В итоге вы получите что-то вроде этого:
'event1': 1
'event2': 2
'event3': 3
. , .
'eventN': N
и для 'event1, event3, event2, event3' он станет: [1, 3, 2, 3]. Масштабирование -> [0, 1, 0.5, 1].
Таким образом, LSTM более чем способен определить порядок по своей природе. И забудьте о точке размерности, поскольку именно LSTM, основной задачей которой является запоминание и, при необходимости, забывание шагов и порядков шагов!.