Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Finding the Longest Shared Subsequence: Finding...
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
onouyek
February 04, 2022
Programming
310
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Finding the Longest Shared Subsequence: Finding K-mers, Writing Functions, and Using Binary Search
【第10回】ゼロから始めるゲノム解析(Python編)
onouyek
February 04, 2022
More Decks by onouyek
See All by onouyek
Finding Open Reading Frames
onouyek
0
400
Inferring mRNA from Protein: Products and Reductions of Lists
onouyek
0
390
Find a Motif in DNA: Exploring Sequence Similarity
onouyek
0
360
Finding the Hamming Distance: Counting Point Mutations
onouyek
0
470
Creating the Fibonacci Sequence: Writing, Testing, and Benchmarking Algorithms
onouyek
1
510
Transcribing DNA into mRNA: Mutating Strings, Reading and Writing Files
onouyek
0
560
DNA methylation analysis using bisulfite sequencing data
onouyek
0
930
Operations on Genomic Intervals and Genome Arithmetic
onouyek
0
370
Exploratory Data Analysis with Unsupervised Machine Learning
onouyek
0
330
Other Decks in Programming
See All in Programming
PyO3 で既存 Python 評価器を Rust core 化する ー wasm-bindgen でブラウザにも配るための設計
kdash
1
370
片田舎のおっさん、 Swift Buildのダイアモンド問題解決の不具合修正PRを出すが、解決方法がキャッシュをしないようにすることであり、ビルド時間が伸びると言われてマージされないので高速化もする/swiftbuild
yimajo
0
360
MySQLとPostgreSQLって何が違うの?
akagami
PRO
0
160
Foundry Localでエージェント開発
seosoft
0
130
まだ間に合う!今年の夏こそSchemeのマクロ展開器を完全理解!
omasanori
0
630
[PyCon KR 2026] More Variants, More Diversity for AI Accelerators
achimnol
0
130
初めての模倣学習とVLA
natsutan
0
470
MIZARU@SPAJAM2026 第二回予選
1901drama
0
100
From 6 People Classroom Meetup to 100 People Regional Conference / FOSS4G Hiroshima 2026
furukawayasuto
0
100
AWS DevOps Agentで インシデント対応をAIに任せたい
honmarkhunt
4
890
30年振りにコンパイラの定数整数除算を改善した
herumi
9
4.4k
Claude Codeを組織的に動かして月400PRを実現した話
happy_ryo
0
250
Featured
See All Featured
Statistics for Hackers
jakevdp
799
230k
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
0
510
Code Reviewing Like a Champion
maltzj
528
40k
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
6
1.2k
Thoughts on Productivity
jonyablonski
76
5.4k
GraphQLとの向き合い方2022年版
quramy
50
15k
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.6k
Paper Plane (Part 1)
katiecoart
PRO
1
10k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Heart Work Chapter 1 - Part 1
lfama
PRO
8
36k
Optimizing for Happiness
mojombo
378
71k
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
Transcript
【第10回】ゼロから始めるゲノム解析 (Python編) Finding the Longest Shared Subsequence: Finding K-mers, Writing
Functions, and Using Binary Search @onouyek
本勉強会の概要・目的 書籍名 対象者/目的 Mastering Python for Bioinformatics Python・バイオインフォマティクス知識ほぼ ゼロの人を対象に、正しい Pythonのコー
ディング手法について学ぶ 頻度 毎週〜隔週開催予定 登壇者 募集中!
Rosalindとは • 問題解決を通じてバイオインフォマティク ス、プログラミング、およびアルゴリズムを 学習するためのプラットフォーム • 大学やハッカソン、就職の面接にも 600回 以上の採用実績あり 参考:https://qiita.com/_kimoton/items/d534d0fa9b83dd7dc412
概要
環境構築 - 必要パッケージ群のインストール # 公開されているレポジトリからファイル群を取得 $ git clone https://github.com/kyclark/biofx_python $
cd biofx_python # requirements.txtに記載のパッケージをインストール $ pip3 install -r requirements.txt # pylintの設定ファイルをホームディレクトリに移動 $ cp pylintrc ~/.pylintrc # mypyの設定ファイルをホームディレクトリに移動 $ cp mypy.ini ~/.mypy.ini
本日のお題 https://rosalind.info/problems/lcsm/ k個のDNA配列(FASTA形式)から最も長い共通部分文字列を求めよ
前提知識編
最長共通部分文字列 $ cat tests/inputs/1.fa >Rosalind_1 GATTACA >Rosalind_2 TAGACCA >Rosalind_3 ATACA
以下の例ではCA、TA、ACが最長共通部分文字列 >Rosalind_1 GATTACA >Rosalind_2 TAGACCA >Rosalind_3 ATACA >Rosalind_1 GATTACA >Rosalind_2 TAGACCA >Rosalind_3 ATACA >Rosalind_1 GATTACA >Rosalind_2 TAGACCA >Rosalind_3 ATACA
FASTAファイルの読み込み >>> from Bio import SeqIO >>> fh = open('./tests/inputs/1.fa')
>>> recs = SeqIO.parse(fh, 'fasta') >>> type(recs) <class 'Bio.SeqIO.FastaIO.FastaIterator'> Bio.SeqIO.parse()でイテレータを作る >>> fh = open('./tests/inputs/1.fa') >>> seqs = [str(rec.seq) for rec in SeqIO.parse(fh, 'fasta')] >>> seqs ['GATTACA', 'TAGACCA', 'ATACA'] リスト内包表記で配列を取り出す >>> seqs = list(map(lambda rec: str(rec.seq), SeqIO.parse(fh, 'fasta'))) map()を使って取り出す
K-mersの取得 第9回で作ったfind_kmers() def find_kmers(seq: str, k: int) -> List[str]: """
Find k-mers in string """ n = len(seq) - k + 1 return [] if n < 1 else [seq[i:i + k] for i in range(n)] def test_find_kmers() -> None: """ Test find_kmers """ assert find_kmers('', 1) == [] assert find_kmers('ACTG', 1) == ['A', 'C', 'T', 'G'] assert find_kmers('ACTG', 2) == ['AC', 'CT', 'TG'] assert find_kmers('ACTG', 3) == ['ACT', 'CTG'] assert find_kmers('ACTG', 4) == ['ACTG'] assert find_kmers('ACTG', 5) == []
range()によるカウントダウン range()の第3引数でstepを-1にすればカウントダウンできる >>> shortest = min(map(len, seqs)) >>> shortest 5
最短の配列の長さを求める >>> list(range(shortest, 0, -1)) [5, 4, 3, 2, 1] カウントアップしてからreversed()しても同じ結果は得られる >>> list(reversed(range(1, shortest + 1))) [5, 4, 3, 2, 1]
collections.Counter()によるK-mersのカウント >>> from collections import Counter >>> counts = Counter()
第1回で扱ったCounter()でK-mersをカウントできる >>> kmers = [set(find_kmers(seq, shortest)) for seq in seqs] >>> for group in kmers: … counts.update(group) … >>> pprint(counts) Counter({'ATTAC': 1, 'GATTA': 1, 'TTACA': 1, 'AGACC': 1, 'TAGAC': 1, 'GACCA': 1, 'ATACA': 1}) Counter.update()でcountsを更新できる
itertools.chain()によるリスト内リストの結合 >>> from itertools import chain >>> list(chain.from_iterable(kmers)) ['ATTAC', 'GATTA',
'TTACA', 'AGACC', 'TAGAC', 'GACCA', 'ATACA'] chain.from_iterable()でkmersを1つのリストにできる >>> counts = Counter(chain.from_iterable(kmers)) >>> pprint(counts) Counter({'ATTAC': 1, 'GATTA': 1, 'TTACA': 1, 'AGACC': 1, 'TAGAC': 1, 'GACCA': 1, 'ATACA': 1}) Counter()と組み合わせて1行でcountsが作れる
解法編
Solution 1: 線形探索 ①入力配列の中で最も短い配列の長さを求める ②最短の配列長からkをカウントダウンしていく ③common_kmers()で共通配列があったら終了する ① ② ③
(参考)二分探索 第4回で扱った再帰を使った方法 ①highがlowより小さくなったときを終了条件にする ②中間地点の値と探している値が同じ時にmidを返す ③中間地点の値が探している値より大きければhighをmid-1 にしてbinary_search()する ④中間地点の値が探している値より小さければlowをmid+1に してbinary_search()する ① ②
③ ④
Solution 2: 二分探索 今回の問題用に修正した二分探索 ①引数で受け取ったf()とlowとhighから共通k-mersのリスト hiとloを作る ②hiとloがどちらも共通k-mersが存在したらhighの位置を 返す ③共通k-mersがloにあってhiになければhighをmidにして binary_search()する
④hiもloも空の場合は-1を返す ① ② ③ ④ ④
Solution 2: 二分探索 ①lowを1にhighを最短の配列長で二分探索して開始位置を決 める ②開始位置から共通k-mersが見つからなくなるまでカウントアッ プして候補k-mersをcandidatesに追加していく ③max()のkeyオプションで最大長のk-merを出力する ① ②
③
ベンチマーキング hyperfine -L prg ./solution1_kmers_functional.py,./solution2_binary_search.py \ '{prg} tests/inputs/2.fa'
本日学んだこと • K-mersによる共通配列の検索 • itertools.chain()によるリスト内リストの結合 • 二分探索による検索の効率化 • min()、max()のkeyオプション