NLP

DNA序列向量化

milvus

Posted by Wwt on October 11, 2022

本文参考自# 用 AI 识别基因,从向量化 DNA 序列开始,部分有删改

DNA 序列在分子生物学和医药研究中有着广泛的应用,比如基因溯源、物种鉴定、疾病诊断等。如果结合正在兴起的基因大数据,采取大量的样本,会使得实验更加具有说服力,也能够更有效地投入现实应用。

传统的核酸比对算法如BLAST,有着诸多的限制,并不适用于大规模的数据,这使得现实应用不得不在成本和准确率之间作出取舍。为缓解核酸序列数据特性的掣肘问题。将大量DNA序列进行向量化是一个更优的选择。

Milvus作为一款开源的、对海量数据非常友好的一款向量数据库,能够高效地存储和检索核酸序列的向量。在提高效率的同时,Milvus也能够帮助降低项目研究或系统搭建成本。在本文中我们将介绍由Milvus搭建的DNA序列召回系统,将召回回来的序列再传入到BLAST系统中,进行序列比对预测查询序列的物种。

数据处理

基因是带有遗传信息的DNA序列片段,由数个碱基$【A,C,G,T】$排列组合而成。每个生物都有不同的基因组,比如人类基因组中含有3万个左右基因,约30亿个碱基对,每个碱基对有2个对应的碱基。

针对不同的需求和目的,DNA序列可以被各种分类,支持这多样的学术研究和现实应用。 原始的DNA序列数据通常长短不一,长序列较多。为了减少数据处理的成本,业内通常使用k-mer预处理序列,同时能够使DNA序列更接近普通文本的词句结够。而向量话数据则能够进一步提高计算速度,并适用于大数据分析与机器学习。

k-mer

一种常见的DNA序列预处理方式是k-mer,从原始序列第一个碱基开始,以一个碱基为单位每次向后一位,每次取一个长度为$k$的短序列。经过k-mer之后,一条长度为s的长序列就转换成$(s-k+1)$个短序列。通过调节$k$的值,可以提高模型的准确性。转换后短序列可以更好地进行数据读取、特征提取、向量化。

向量化

向量化DNA序列的过程其实是将其当做普通文本,一条被kmer拆分后的序列就像一个句子,拆成单个短序列就是一个单词,碱基则对应字符。因此常见的NLP模型都可以被用来处理DNA序列数据,进行模型训练、特征提取、序列编码。每个模型都有适用的场景,以词袋模型为例,CountVectorizer是一种比较轻便的特征提取方法,对序列长度没有限制,但相似度区分不明显。

Milvus示例

milvus 使用简单的非结构化数据管理,能够将目标对象在万亿条向量数据中根据近似最近邻搜索算法进行比对,以平均延迟以毫秒计的速度召回相似结果。它对海量非结构化的数据非常友好和高效,毫无疑问,能够轻松管理大量DNA序列数据,从而促进生物或基因学的研究与应用。

结合Milvus与Mysql的分类模型结构如下图所示,包括了插入和检索两个流程。在插入milvus之前,该示例首先将所有的DNA序列进行了k-mer处理,然后训练了词袋模型用以特征提取和向量化。

1.png

Milvus下载

使用下面命令

wget https://github.com/milvus-io/milvus/releases/download/v2.0.0-rc8/milvus-standalone-docker-compose.yml -O docker-compose.yml

docker-compose up -d

出现下面结果,说明milvus安装成功。镜像启动后,有三个容器就表示启动成功,milvus负责提供系统的核心功能,Etcd是元数据引擎,用于管理Milvus内部组件的元数据访问和存储如proxy,index和node;MinIO是存储引擎,负责milvus的数据持久化。

Creating milvus-minio … Creating milvus-etcd … Creating milvus-standalone … ting milvus-standalone … done

Milvus 2.0不支持字符串,启动mysql作为docker容器来存储和调用DNA序列的非向量属性。

docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d –name mysql mysql:5.7

到这里为止,向量检索的工具已经准备好,接下来写程序来实现milvus向量检索。

连接向量数据库
from pymilvus import connections
import pymysql
connections.connect(host='localhost', port='19530')
conn = pymysql.connect(host='localhost', user='root', port=3306, password='123456', database='mysql',local_infile=True)
cursor = conn.cursor()
生成向量
from sklearn.feature_extraction.text import CountVectorizer
from sklearn import preprocessing
vcctorizer = feature_extraction.text.CountVectorizer(ngram_range=(3,3),max_fetures=dims)
X = vectorizer.fit_transform(data).to_array()
embeddings = list(preprocessing.mormalize(X))

countvectorizer是属于常见的特征数值计算类,是一个文本特征提取方法。对于每个训练文本,它只考虑每个词汇在该训练文本中出现的频率。CountVectorizer会将文本中词语转换为词频矩阵,通过fit_transform函数计算各个词语出现的次数。

这里考虑到实际应用,处理序列达200G,每条序列向量存成768维,也将耗费巨大的存储空间,我们可以通过主成分分析(PCA)来转换和减少我们输入特征空间。

PCA的一个应用是奇异值分解(SVD),线性代数里重要的一种分解形式,其矩阵的特殊含义可以用来做处理线性相关。在最好的情况下,所有的方差都由少量的新特征来表示。TruncatedSVD类让我们决定要在新空间保留多少特征。如在自然语言处理中,对新闻的分类,就可以采用SVD的方法,而且已取得不错的效果。把新闻中的核心词,用一个向量进行表示,每条新闻一个向量,组成一个矩阵,对矩阵进行SVD分解。这里每条序列一个向量

from sklearn.decomposition import TruncatedSVD
import joblib
svd = TruncatedSVD(n_components=VECTOR_DIMS,random_state=42)
#PCA 降维
X_svd = svd.fit_transform(X)
joblib.dump(svd,SVD_PATH)
#加载PCA模型
svd = joblib.load(SVD_PATH)
svd_vector = svd.transform(X)

以上操作可以将任意高维向量转换成低维向量。

DNA序列物种分类

输入查询序列,在Milvus数据库中搜索与其相似的序列便可以对搜索对象进行物种分类,下图中对未知物种的序列进行搜索,成功根据结果返回可能物种的序列。证明了Milvus向量相似性搜索能够召回相似物种的序列,便于进一步进行分析和预测。