我正在寻找一种解决方案,可帮助构建和分析不同长度的序列数据。我需要为机器学习分类器(LSTM)准备数据。我的输入示例如下:
输入
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))
答案 0 :(得分:1)
我没有得到输出下一行的限制,但是您可以按字典来计算出现次数:
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}
此方法对输入顺序敏感。如果有关系,那么我必须对其进行更新
答案 1 :(得分:1)
我会尝试将您的步骤作为字符串,将序列作为子字符串:
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
答案 2 :(得分:1)
我要使用一个计数器:
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)]