Извлечение последовательностей из нескольких строк - PullRequest
0 голосов
/ 27 июня 2018

Я ищу решение, которое поможет структурировать и анализировать данные последовательности различной длины. Мне нужно подготовить данные для классификатора машинного обучения (LSTM). Мой пример ввода выглядит следующим образом:

Input

ID 1 2 3 4
0  A B C D
1  A C D
2  A D B

Где столбцы - это количество шагов последовательности и A,B,C,D,E определенных действий.

Поскольку возможных последовательностей , мы ожидаем:

A,B
B,C
C,D
A,B,C
B,C,D
A,C
A,C,D
C,D
A,D
A,D,B
D,B

Сначала скрипт должен вывести как часто встречаются определенные последовательности и сколько существует последовательностей

(C,D) 2
(A,B,C,D) 1
(A,B) 1
...

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

Желаемый выход :

ID  (A,B) (B,C) (C,D) (A,B,C) (B,C,D) (A,C) (A,C,D) (C,D) (A,D) (A,D,B) (D,B)
0   1     1     1     1       1       0     0       1     0     0    0 
1   0     0     1     0       0       1     1       1     0     0    0
2   0     0     0     0       0       0     0       0     1     1    1

Где (A,B) (B,C) и т. Д. Также могут быть представлены в виде закодированных переменных. Таким образом, я думаю, что данные будут представлены в форме, которая рассматривает последовательности и подпоследовательности для классификации.

В первой части я читал о PrefixSpan, но не смог найти примеры кода для репликации. Поскольку я работаю с scikit-learn и keras, приветствуются соответствующие решения!

Пробовал:

import itertools
import pandas as pd
d = {'1': ['A', 'A', 'A'], '2': ['B', 'C', 'D'], '3': ['C', 'D', 'B'], '4': ['D', '', '']}
df = pd.DataFrame(data=d)
df

list(itertools.combinations(df))

Ответы [ 3 ]

0 голосов
/ 27 июня 2018

Я бы попробовал поставить ваши шаги как строки, последовательности как подстроки:

import pandas as pd

def get_seq(s):
    return [s[a:b] for a in range(len(s)) for b in range(a+2, len(s)+1)]

df = pd.DataFrame({'steps': ['ABCD', 'ACD', 'ADB']})
df['seq'] = df.steps.apply(get_seq)

df
Out: 
  steps                           seq
0  ABCD  [AB, ABC, ABCD, BC, BCD, CD]
1   ACD                 [AC, ACD, CD]
2   ADB                 [AD, ADB, DB]

первый запрошенный результат: счетчик последовательности

all_seq = df.seq.apply(pd.Series).stack().values

all_seq
Out: 
array(['AB', 'ABC', 'ABCD', 'BC', 'BCD', 'CD', 'AC', 'ACD', 'CD', 'AD', 'ADB', 'DB'], dtype=object)

df_count = pd.DataFrame({'seq': all_seq, 'cntr': 1})

df_count.groupby('seq').count().T            # .T only for shorter output here below
Out: 
seq   AB  ABC  ABCD  AC  ACD  AD  ADB  BC  BCD  CD  DB
cntr   1    1     1   1    1   1    1   1    1   2   1

второй запрошенный результат: одна таблица с горячим кодированием

df_ohe = pd.DataFrame()
for seq in set(all_seq):
    df_ohe[seq] = df.steps.str.contains(seq)

df_ohe
Out: 
    ABCD    BCD     AC     AB    ABC     AD    ADB     DB     BC    ACD     CD
0   True   True  False   True   True  False  False  False   True  False   True
1  False  False   True  False  False  False  False  False  False   True   True
2  False  False  False  False  False   True   True   True  False  False  False

или если вам больше нравятся нули и единицы:

df_ohe.astype(int)
Out: 
   ABCD  BCD  AC  AB  ABC  AD  ADB  DB  BC  ACD  CD
0     1    1   0   1    1   0    0   0   1    0   1
1     0    0   1   0    0   0    0   0   0    1   1
2     0    0   0   0    0   1    1   1   0    0   0
0 голосов
/ 27 июня 2018

Я бы использовал Счетчик:

from collections import Counter

def get_all_subsequence(seq):
    return [seq[i:j] for i in range(len(seq)) for j in range(i + 2, len(seq) + 1)]

input = ["ABCD", "ACD", "ADB"]

counter = Counter()
for entry in input:
    counter.update(get_all_subsequence(entry))
print(counter.most_common())
[('CD', 2), ('AB', 1), ('ABC', 1), ('ABCD', 1), ('BC', 1), ('BCD', 1), ('AC', 1), 
('ACD', 1), ('AD', 1), ('ADB', 1), ('DB', 1)]
0 голосов
/ 27 июня 2018

Я не получил то, что является ограничением, чтобы перейти к следующей строке в выводе, но вы можете посчитать вхождение по словарям:

data = ['AB',
'BC',
'CD',
'ABC',
'BCD',
'AC',
'ACD',
'CD',
'AD',
'ADB',
'DB']
matrix={}
for i in data:
    if i in matrix:
        matrix[i] +=1 
    else:
        matrix[i] =1

print(matrix)

вывод: {'BCD': 1, 'AD': 1, 'DB': 1, 'AB': 1, 'ABC': 1, 'AC': 1, 'BC': 1, 'ADB ': 1,' ACD ': 1,' CD ': 2}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...