DNA Similarity and Classification é uma API REST utilizando a tecnologia InterSystems Vector Search para investigar semelhanças genéticas e classificar eficientemente sequências de DNA. Este é um aplicativo que utiliza técnicas de inteligência artificial, como aprendizado de máquina, aprimorado por recursos de pesquisa vetorial, para classificar famílias genéticas e identificar DNAs semelhantes conhecidos a partir de um DNA de entrada desconhecido.
Análise K-mer: Fundamentos em Análise de Sequência de DNA
A fragmentação de uma sequência de DNA em k-mers é uma técnica fundamental no processamento de dados genéticos. Esta abordagem envolve quebrar a sequência de DNA em subsequências menores de tamanho fixo, conhecidas como k-mers. Por exemplo, se tomarmos a sequência "ATCGTAGCTA" e definirmos k como 3, obteremos os seguintes k-mers: "ATC", "TCG", "CGT", "GTA", "TAG", "AGC", "GCT" e "CTA".
Este processo é realizado deslizando uma janela de tamanho k ao longo da sequência, extraindo cada subsequência de tamanho k e registrando-a como um k-mer. A janela então se move para o próximo conjunto de bases, permitindo a sobreposição entre os k-mers. Esta sobreposição é crucial para garantir que nenhuma informação seja perdida durante o processo de fragmentação.
Os k-mers resultantes retêm informações locais cruciais sobre a estrutura da sequência de DNA. Isto é crítico porque muitas informações biologicamente relevantes estão contidas em regiões específicas do DNA. A análise subsequente destes k-mers pode revelar padrões, identificar regiões conservadas ou semelhantes entre diferentes sequências de DNA e auxiliar na investigação de funções e interações genéticas.
Em resumo, Similaridade e Classificação de DNA oferecem uma abordagem para identificar semelhanças genéticas e classificar sequências de DNA.
Aplicativo
O código a seguir inicializa o projeto, realizando a configuração necessária antes da construção:
ClassMethod init()
{
write "START INIT"
Do ##class(dc.data.DNAClassification).CreateTheModelML()
Do ##class(dc.data.HumanDNA).UploadData()
}
ObjectScriptObjectScript
O UploadData
método implementado no código é responsável por fragmentar sequências de DNA em k-mers, converter esses k-mers em vetores usando um modelo de codificação específico e, em seguida, armazenar esses vetores no banco de dados.
print("Reading dataset")
human_df = pd.read_table('/opt/irisbuild/data/human_data.txt')
human_df = human_df.sample(n=1500, random_state=42)
PythonPython
Para melhorar o desempenho e reduzir o tempo de processamento durante a fase de construção do projeto, é implementado um processo de amostragem, limitando a leitura aos primeiros 1.500 registros do arquivo. Embora esta estratégia acelere o processo, vale a pena notar que uma análise abrangente do arquivo poderia fornecer uma compreensão mais completa dos dados. Porém, devido ao compromisso com a eficiência e ao ritmo de construção, esta abordagem foi adotada.
def getKmers(sequence, size=6, max_length=5000):
kmers = [sequence[x:x+size].lower() for x in range(len(sequence) - size + 1)]
kmers = [kmer for kmer in kmers if len(kmer) > 0]
if len(kmers) == 0:
return [sequence]
return kmers[:max_length]
PythonPython
O parâmetro MAX_LEN em getKmers é usado para limitar o tamanho máximo dos k-mers processados para otimizar o tempo de execução do processo. No entanto, é importante notar que esta abordagem pode não ser ideal em termos de representação completa dos dados de ADN.
print("Creating K-mers groups")
human_df['K_mers'] = human_df['sequence'].apply(getKmers)
print("Combining K-mers into strings")
human_df['K_mers_str'] = human_df['K_mers'].apply(lambda x: ' '.join(x))
print("Download stsb-roberta-base-v2 model")
model = SentenceTransformer('stsb-roberta-base-v2')
print("Encode K_mers")
embeddings = model.encode(human_df['K_mers_str'].tolist(), normalize_embeddings=True)
print("Creating column sequence_vectorized")
human_df['sequence_vectorized'] = embeddings.tolist()
PythonPython
O código vetoriza sequências de DNA usando o modelo de codificação stsb-roberta-base-v2 da biblioteca SentenceTransformer. Esta etapa converte sequências de DNA em vetores numéricos, facilitando sua manipulação vetorial e análise computacional. Após a vetorização, os dados são armazenados no banco de dados para uso futuro. Esta etapa é crucial para garantir que os vetores de sequência de DNA estejam disponíveis para consultas e análises adicionais.
Posteriormente, o método findSimilarity é responsável por encontrar as sequências de DNA mais semelhantes com base em uma entrada de sequência de DNA recebida. Ele fragmenta a sequência de DNA em k-mers e consulta o banco de dados para encontrar as cinco sequências de DNA mais próximas.
ClassMethod findSimilarity(pSequence As %String) As %String [ Language = python ]
{
import iris
from sentence_transformers import SentenceTransformer
results = []
def getKmers(sequence, size=6, max_length=5000):
kmers = [sequence[x:x+size].lower() for x in range(len(sequence) - size + 1)]
kmers = [kmer for kmer in kmers if len(kmer) > 0]
if len(kmers) == 0:
return [sequence]
return kmers[:max_length]
model = SentenceTransformer('stsb-roberta-base-v2')
kmers = getKmers(pSequence)
kmers_str = ' '.join(kmers)
search_vector = model.encode(kmers_str, normalize_embeddings=True).tolist()
stmt = iris.sql.prepare("SELECT TOP 5 ID FROM dc_data.HumanDNA ORDER BY VECTOR_DOT_PRODUCT(kMersVector, TO_VECTOR(?)) DESC ")
rs = stmt.execute(str(search_vector))
class_mapping = {
0: 'G protein coupled receptors',
1: 'tyrosine kinase',
2: 'tyrosine phosphatase',
3: 'synthetase',
4: 'synthase',
5: 'lon channel',
6: 'transcription factor',
}
for idx, row in enumerate(rs):
humanDNA = iris.cls("dc.data.HumanDNA")._OpenId(row[0])
results.append({
"sequence": humanDNA.sequence,
"dnaClass": class_mapping[humanDNA.dnaClass]
})
return results
}
PythonPython
Esses processos são essenciais para o projeto, pois permitem a análise comparativa de sequências de DNA e a identificação de padrões ou semelhanças entre elas.
Aprendizado de Máquina Aplicado
O aprendizado de máquina tem sido utilizado para realizar a classificação de sequências de DNA. A classe DNAClassification contém métodos para treinar um modelo de classificação multinomial Naive Bayes e para classificar sequências de DNA com base neste modelo.
O método CreateTheModelML é responsável por treinar o modelo de classificação. Primeiramente, as sequências de DNA são pré-processadas, transformadas em k-mers e agrupadas. Em seguida, esses grupos k-mer são convertidos em uma representação numérica utilizando a técnica de vetorização. O modelo multinomial Naive Bayes é então treinado com esses dados vetorizados. Após o treinamento, o desempenho do modelo é avaliado por meio de análises como precisão, recall e pontuação F1.
ClassMethod CreateTheModelML()
{
import pandas as pd
def getKmers(sequence, size=6):
kmers = [sequence[x:x+size].lower() for x in range(len(sequence) - size + 1)]
kmers = [kmer for kmer in kmers if len(kmer) > 0]
if len(kmers) == 0:
return [sequence]
return kmers
print("Reading dataset")
human_df = pd.read_table('/opt/irisbuild/data/human_data.txt')
print("Creating K-mers groups")
human_df['K_mers'] = human_df['sequence'].apply(getKmers)
human_df['words'] = human_df.apply(lambda x: getKmers(x['sequence']), axis=1)
human_df = human_df.drop('sequence', axis=1)
human_texts = list(human_df['words'])
for item in range(len(human_texts)):
human_texts[item] = ' '.join(human_texts[item])
y_data = human_df.iloc[:, 0].values
from sklearn.feature_extraction.text import CountVectorizer
cv = CountVectorizer(ngram_range=(4,4))
X_human_dna = cv.fit_transform(human_texts)
print(X_human_dna.shape)
print("PREPARING FIT DATA")
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X_human_dna,
y_data,
test_size = 0.20,
random_state=42)
print("FIT THE MODEL")
from sklearn.naive_bayes import MultinomialNB
classifier = MultinomialNB(alpha=0.1)
classifier.fit(X_train, y_train)
y_pred = classifier.predict(X_test)
print("VALIDATING THE MODEL")
from sklearn.metrics import accuracy_score, f1_score, precision_score, recall_score
print("Confusion matrix\n")
print(pd.crosstab(pd.Series(y_test, name='Actual'), pd.Series(y_pred, name='Predicted')))
def get_metrics(y_test, y_predicted):
accuracy = accuracy_score(y_test, y_predicted)
precision = precision_score(y_test, y_predicted, average='weighted')
recall = recall_score(y_test, y_predicted, average='weighted')
f1 = f1_score(y_test, y_predicted, average='weighted')
return accuracy, precision, recall, f1
accuracy, precision, recall, f1 = get_metrics(y_test, y_pred)
print("accuracy = %.3f \nprecision = %.3f \nrecall = %.3f \nf1 = %.3f" % (accuracy, precision, recall, f1))
print("SAVE THE MODEL")
import joblib
joblib.dump(classifier, '/opt/irisbuild/data/multinomial_nb_model.pkl')
joblib.dump(cv, '/opt/irisbuild/data/cv_to_multinomial_nb_model.pkl')
}
PythonPython
Por outro lado, o método ClassifyDnaSequence é responsável por classificar as sequências de DNA recebidas como entrada. Primeiramente, a sequência é pré-processada e transformada em k-mers. Então, esses k-mers são vetorizados usando o mesmo processo usado durante o treinamento do modelo. O modelo treinado é então carregado e usado para prever a classe da sequência de DNA. O resultado da classificação inclui a classe prevista e as probabilidades associadas a cada classe.
ClassMethod ClassifyDnaSequence(sequence As %String) As %Status
{
import joblib
from sklearn.feature_extraction.text import CountVectorizer
classifier = joblib.load('/opt/irisbuild/data/multinomial_nb_model.pkl')
cv = joblib.load('/opt/irisbuild/data/cv_to_multinomial_nb_model.pkl')
def getKmers(sequence, size=6):
kmers = [sequence[x:x+size].lower() for x in range(len(sequence) - size + 1)]
kmers = [kmer for kmer in kmers if len(kmer) > 0]
if len(kmers) == 0:
return [sequence]
return kmers
k_mers = getKmers(sequence)
k_mers_vec = cv.transform([' '.join(k_mers)])
predicted_class = classifier.predict(k_mers_vec)[0]
probabilities = classifier.predict_proba(k_mers_vec)[0]
class_mapping = {
0: 'G protein coupled receptors',
1: 'tyrosine kinase',
2: 'tyrosine phosphatase',
3: 'synthetase',
4: 'synthase',
5: 'lon channel',
6: 'transcription factor',
}
result = {
"Classification": class_mapping[predicted_class],
"Probabilities": {
class_mapping[class_index]: float(probability)
for class_index, probability in enumerate(probabilities)
}
}
return result
}
ObjectScriptObjectScript
Uso do aplicativo
Os usuários interagem com o sistema enviando sequências de DNA por meio de consultas e podem solicitar uma resposta no formato JSON contendo informações sobre as sequências semelhantes descobertas e suas classificações, simplificando o processo de análise genética.
Abaixo está a API a ser usada: http://localhost:52773/api/dna/find?&dna=<YOUR_DNA>
- dna: Digite a sequência de DNA que você deseja pesquisar
Exemplo: http://localhost:52773/api/dna/find?&dna=ATGAACTGTCCAGCCCCTGTGGAGATCTCCT...
Usando o Postman para visualizar a resposta da API (pode ser feito usando um navegador ou outros aplicativos como o Insomnia):
Projeto: GitHub
Votação: similaridade e classificação de DNA
Muito legal! Parabéns!