【问题标题】:Extracting Sequences from Multiple Strings从多个字符串中提取序列
【发布时间】:2018-12-06 05:20:06
【问题描述】:

我正在寻找一种有助于构建和分析不同长度的序列数据的解决方案。我需要为机器学习分类器 (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
...

但更重要的是,为了以后的使用,我需要one-hot encode所有可能的序列,这样最终的结果看起来像:

期望的输出

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))

【问题讨论】:

  • 显示你迄今为止尝试过的内容。
  • @Christopher,这是一个概率问题,您需要找出包含 2,3 和 4 个字母的 ABCDE 的可能结果数
  • 由于没有附加代码,我只提供一个建议 - 使用itertools package 进行排列或组合,只需使用字典作为出现计数器。
  • @Austin 我在示例中插入了一些内容,但是:1)我担心我自己的任何方法都可能成为可能不是最佳解决方案的起点 2)我不知道从哪里开始以及是否有合适的软件包?
  • 能否请您添加您对术语sequence 的确切定义?我看到它在这里被用作combination 的同义词,但我有印象,只允许直接邻居,对吧?否则例如(A,C) 也将是第一行中的一个序列(索引 0)

标签: python keras sequence categorical-data


【解决方案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}

此方法对输入的顺序很敏感。如果它确实重要,那么我必须更新它

【讨论】:

  • 这已经对第一部分有所帮助,谢谢。但是很惊讶你不使用 itertools,因为我经常看到它。
  • 我也是 Python 新手:)
【解决方案2】:

我会尝试将您的步骤作为字符串,将序列作为子字符串:

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

【讨论】:

  • ...但是考虑一下 - 这应该适用于任何可迭代的,而不仅仅是字符串。
  • 我去看看,谢谢。将再等待 1-2 天寻找潜在的替代方案并标记为已解决。
  • 编辑:删除了对itertools的依赖,添加了一个热编码表的0/1表示
【解决方案3】:

我会使用计数器:

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)]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-06-10
    • 1970-01-01
    • 2019-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-02
    • 1970-01-01
    相关资源
    最近更新 更多