如何使用Numpy数组列表训练ML算法?

时间:2019-10-01 20:03:36

标签: python machine-learning deep-learning bioinformatics

我正在尝试开发一种使用LinearSVC的机器学习算法,另一种使用卷积神经网络对DNA序列进行分类的算法。 我不得不对DNA序列进行热编码,然后将每个序列的结果数组存储在列表中。 但是当我进行火车测试拆分步骤时,我无法使用它。

我的DNA序列是这样的(不是我的真实数据集,它只是更大的一个例子。所有序列都在文件seqs_for_test.fasta中):

  

> TE_seq1   CCATAAACTATCTAAATAAGCACTTTTCTGGCTCTCTGGCCCCCCTTCTTCTTTTTGGGAAGGTGACAG   AGGGTAAAAGGGCTCTCTGCCGTGCGAGGCTCCTCACAGACACACAGCAAGAAAGAAGCGCCGCGCAGCA

     

> TE_seq2   GATAGCCCCTCTCCCCCAGCCCCAGTCTGATCCCTAACCCTAACTCCACGGCTCCTGTCTCTACCCCCGTCT   CTTTCTTCTTGTACCCTAGTCCCCCAGATCATTAGCTCCCTGCTCGGGCCCAGGGTTTTAAGAGAAGCCC

     

> TE_seq3   TGACTCAAGTCATGCTACCCAGCCCCGTCTTCTTAAAAATGAGACATGTTGAGACACCCTGCTTTTCGCC   TACAAACACATCCATTCTCTATACTTAGTCTTATTTAAATTCTATCCTCTGTATGTCTAGTCCTGGGGGT

     

> RD_seq4   TGCTCGCCCCCCAGGAAGTGCAGAGACCGCCTGGGTGTGACTGTTTTTAGGCCTAACAAAGGCACAGAAA   CACCCGTGCGGTCTCTGTATCCCCTGGAGGTATTTCTCCCCCCATTAGTTTGCTTGACACTAAGTTTTTAAA

     

> RD_seq5   TAAAAAAAGCTTATTAAGTCCCTAGAACCTGGGACCTATCTACCCAAGTTTTAAAACCTTACTTTTAAGG   CTACATTTTTTTATTTTGACTGTTTTACCATAAGGTCACATATAGGAAACCCCCACTGTCCTAATAAAAA

     

> RD_seq6   CTAATCTCCTGTGTGCGCACTTACATCAGTTTGGGAAGTTGTTCATGATGACTCTGCGACGATCAAGAAG   GACCAGGACTCTCCCTGGACACCTCAGGGACTTCTTGCTGGAGGGCACCATACATCAGTTTGCCAGCAAA

这是我的LinearSVC代码:

import pandas as pd
import numpy as np
from numpy import array
from numpy import argmax
from Bio import SeqIO
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import OneHotEncoder
from sklearn.model_selection import train_test_split


with open('../fasta/seqs_for_test.fasta') as fasta_file:  # Will close handle cleanly
    identifiers = []
    sequences = []
    for seq_record in SeqIO.parse(fasta_file, 'fasta'):  # (generator)
        identifiers.append(seq_record.id)
        sequences.append(seq_record.seq.lower())


s1 = pd.Series(identifiers, name='ID')
s2 = pd.Series(sequences, name='sequence')

# Gathering Series into a pandas DataFrame and rename index as ID column
fasta_frame = pd.DataFrame(dict(ID=s1, sequence=s2)).set_index(['ID'])
fasta_frame


label_serie = pd.Series()
fasta_frame.insert(1, "label", label_serie)

# Transposable element (TE) == 0; Random (RD) == 1.
fasta_frame.loc[fasta_frame.index.str.contains(r'TE_'),'label'] = 0
fasta_frame.loc[fasta_frame.index.str.contains(r'RD_'),'label'] = 1
fasta_frame


# empty list to store ohe array sequences
res_arr = []
for index, row in fasta_frame['sequence'].iteritems():
    # integer encode
    label_encoder = LabelEncoder()
    integer_encoded = label_encoder.fit_transform(row)
    # print(integer_encoded)
    # binary encode
    onehot_encoder = OneHotEncoder(sparse=False)
    integer_encoded = integer_encoded.reshape(len(integer_encoded), 1)
    onehot_encoded = onehot_encoder.fit_transform(integer_encoded)
#     print(index)
#     print(onehot_encoded)
    # append ohe arrays
    res_arr.append(onehot_encoded)

y = fasta_frame['label']
# y

from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(res_arr, 
                                                    y, 
                                                    test_size = 0.20, 
                                                    random_state=42)

# print(x_train)
# print(y_train)
# print(x_test)
# print(y_test)

from sklearn.svm import LinearSVC
from sklearn.metrics import accuracy_score
modelo = LinearSVC()
modelo.fit(x_train, y_train)
previsoes = modelo.predict(y_test)
acuracia = accuracy_score(y_test, previsoes) * 100
print("accuracy was %.2f%%" % acuracia)

我尝试重塑,np.vstack和其他方式,但是没有成功。 如何将数组列表用作训练集?

错误消息:

  

ValueError:找到的数组为暗3。估计值应为<= 2。

1 个答案:

答案 0 :(得分:1)

您的问题是SVM对每个训练示例都期望固定数量的1维n个特征,然后尝试在此n维特征空间中找到一个分离的超平面。如果您对长度为m的DNA序列进行一次热编码,则实际上可以获得m个维数为4的特征。LinearSVC实现不适用于这种情况(我不确定SVM通常是否适用于不是一个特征的特征。 -维,如何看起来像是由任意维特征跨越的空间?)。

如果要使用sklearn的SVM实现,则必须找到一种“正式”将功能尺寸缩小为1的方法。一种可能是展宽序列表示形式。即从一个维度为[140,4]的DNA序列开始,您可以通过将相同维度中的一个热表示串联在一起来创建维度[560,1]的扁平化表示。

也许示例是说明性的:

给出示例性的DNA序列“ AC”单热编码为[[1、0、0、0],[0、1、0、0]。然后,您必须将输入展平为[1、0、0、0、0、1、0、0],以便可以在长度为2的DNA序列上训练SVM。

为什么这样做?

SVM将具有8个权重(忽略偏差项)。第一权重将权衡腺嘌呤作为第一核苷酸出现的重要性。第二权重将权衡具有胞嘧啶作为第一核苷酸的重要性。第五权重将加权腺嘌呤作为第二核苷酸的重要性,依此类推。现在,如果出现“ AC” DNA序列并要对其进行分类,则除了与腺嘌呤相对应的权重作为第一个核苷酸,而胞嘧啶作为第二个核苷酸以外的所有权重都将被忽略。

如果您的DNA序列不是全部固定长度,则必须对其进行零填充。这意味着将其平坦的序列表示形式0附加到其长度与数据集中最长的序列一样长。