メインコンテンツまでスキップ

スペクトル畳み込みが窮地を救う

🎯 まず、この講義で何を学ぶのか

最終ゴール:144種類のアミノ酸から本当に必要な10〜20種類だけを自動的に選び出す魔法のような手法「スペクトル畳み込み」を学びます。これにより、25%ノイズでも正しいペプチドを見つけられるようになります!

でも、ちょっと待ってください。そもそも...

🤔 ステップ0:なぜ「窮地」なの?

前回までの絶望的な状況

問題1:ノイズが多い(25%)
→ 標準アルゴリズムは失敗

問題2:非標準アミノ酸を考慮(144種類)
→ さらに悪化、10%ノイズでも失敗

八方塞がり...?

でも、ちょっと待って

スペクトルに含まれる情報を
本当に全部使っているだろうか?

スペクトルが私たちに伝えているのに、
私たちが聞いていないだけの何かがあるのでは?

💡 ステップ1:小さな例から始めよう

1-1. 問題解決の鉄則

行き詰まったときの戦略:
1. 小さな例を考える
2. パターンを見つける
3. 一般化する

これはプログラミングでも同じ!

1-2. NQELペプチドで考える

# 小さな例:NQELペプチド
ペプチド = "NQEL"
質量 = {
'N': 114,
'Q': 128,
'E': 129,
'L': 113
}

# 実験スペクトル(Eの質量129が欠損!)
実験スペクトル = [0, 113, 114, 128, 227, 242, 257,
355, 356, 370, 371, 484]

# あれ?129がない!
# じゃあEは検出できない...?

🔍 ステップ2:隠れた情報を発見

2-1. ちょっと待って、よく見ると

# QEの質量は?
QE = 128 + 129 = 257 # ← これはスペクトルにある!

# Qの質量は?
Q = 128 # ← これもある!

# じゃあ...
E = QE - Q = 257 - 128 = 129 # Eが計算できた!

2-2. 他にもないか探してみよう

# ELNの質量
ELN = 129 + 113 + 114 = 356 # ← ある!

# LNの質量
LN = 113 + 114 = 227 # ← ある!

# 差を取ると
E = ELN - LN = 356 - 227 = 129 # またEが出た!

2-3. さらにもう一つ

# ペプチド全体(NQEL)
全体 = 484 # ← ある!

# Eを含まない部分(LNQ)
LNQ = 113 + 114 + 128 = 355 # ← ある!

# 差を取ると
E = 全体 - LNQ = 484 - 355 = 129 # 3回目のE!

2-4. 発見

Eの質量129は直接スペクトルにないけど、
質量の「差」として3回も現れている!

これが偶然?いや、違う!
本物のアミノ酸は何度も現れるはず!

🎨 ステップ3:スペクトル畳み込みの誕生

3-1. 畳み込み(Convolution)って何?

定義:スペクトルのすべての質量のペア間の正の差

簡単に言うと:
「全部の組み合わせで引き算して、
どの差が頻繁に出てくるか数える」

3-2. 具体的な計算

def スペクトル畳み込み(スペクトル):
"""
すべてのペアの差を計算
"""
畳み込み = []

for i in range(len(スペクトル)):
for j in range(i + 1, len(スペクトル)):
= スペクトル[j] - スペクトル[i]
if> 0:
畳み込み.append()

return 畳み込み

# 実行例
スペクトル = [0, 113, 227, 370]
畳み込み = スペクトル畳み込み(スペクトル)
# 結果:[113, 227, 370, 114, 257, 143]
# (113-0) (227-0) (370-0) (227-113) (370-113) (370-227)

3-3. 頻度を数える

from collections import Counter

def 頻度分析(畳み込み):
"""
57-200の範囲で頻度を数える
"""
# アミノ酸の質量範囲でフィルター
アミノ酸候補 = [x for x in 畳み込み if 57 <= x <= 200]

# 頻度をカウント
頻度 = Counter(アミノ酸候補)

return 頻度.most_common()

# NQELの例での結果
# 129: 3回(E)← 最多!
# 113: 2回(L)
# 114: 2回(N)
# 128: 2回(Q)

🎯 ステップ4:なぜ畳み込みが効くのか?

4-1. 本物 vs ノイズ

本物のアミノ酸:
- ペプチドの一部として実際に存在
- 様々な組み合わせで現れる
- 差として何度も検出される

ノイズ(偽の質量):
- ランダムに現れる
- 特定の組み合わせを作らない
- 差として現れる頻度が低い

4-2. 統計的な原理

def なぜ効くか():
"""
畳み込みの統計的原理
"""

# 本物のアミノ酸Aがある場合
# A + X の形の質量が複数存在
# Y + A の形の質量も複数存在

# したがって:
# (A + X) - X = A ← 何度も現れる
# (Y + A) - Y = A ← これも

# ノイズNがある場合
# Nは単独で現れることが多い
# N - 何か = ? ← 頻度が低い

return "頻度の差で本物を見分ける!"

4-3. 身近な例で理解

クラスで人気投票をする例:

方法1(従来):
- 全員の名前リストから選ぶ
- 偽名や書き間違いも含まれる

方法2(畳み込み的):
- 「AさんとBさんどっちが好き?」を全組み合わせで聞く
- 本当に人気の人は何度も名前が出る
- 偽名は出現頻度が低い

→ 頻度で本物を見分けられる!

🔧 ステップ5:アルゴリズムの実装

5-1. ConvolutionCycloPeptideSequencing

def 畳み込みシクロペプチドシーケンシング(スペクトル, M=20, N=1000):
"""
スペクトル畳み込みを使った改良版アルゴリズム

Parameters:
- スペクトル: 実験スペクトル
- M: 使用するアミノ酸質量の数
- N: リーダーボードサイズ
"""

# ステップ1:スペクトル畳み込みを計算
畳み込み = スペクトル畳み込み(スペクトル)

# ステップ2:57-200の範囲で頻度分析
頻度 = 頻度分析(畳み込み)

# ステップ3:上位M個の質量を選択
トップM質量 = [質量 for 質量, 回数 in 頻度[:M]]

print(f"選ばれた質量: {トップM質量}")
print(f"144種類から{M}種類に削減!")

# ステップ4:選ばれた質量だけでリーダーボード実行
結果 = リーダーボードアルゴリズム(
スペクトル,
アルファベット=トップM質量,
N=N
)

return 結果

5-2. なぜMを選ぶ必要があるか

def パラメータMの選び方():
"""
M(使用する質量の数)の影響
"""

# M = 10:最も確実な質量のみ
# → 高精度だが、非標準アミノ酸を見逃す可能性

# M = 20:バランス型(推奨)
# → 精度と柔軟性のバランス

# M = 50:多めに取る
# → 柔軟だが、ノイズも含む可能性

return "通常は20前後が最適"

🎉 ステップ6:驚きの実験結果

6-1. Spectrum10(10%ノイズ)での結果

def Spectrum10での実験():
"""
前回失敗した拡張アルファベットでの再挑戦
"""

# 前回(144種類):❌ 失敗
# 98と65という間違った質量を選んでしまった

# 今回(畳み込み):
畳み込み結果 = スペクトル畳み込み(Spectrum10)
トップ10 = 頻度分析(畳み込み結果)[:10]

print("選ばれた質量:")
print(トップ10)
# [99, 113, 114, 128, 129, 147, 163, 186, 97, 145]
# ほとんどが標準アミノ酸!

結果 = リーダーボード(Spectrum10, トップ10)
print(f"結果: {結果}")
# ✅ VKLFPWFNQY(チロシジンB1)正解!

6-2. Spectrum25(25%ノイズ)での奇跡

def Spectrum25での実験():
"""
今まで誰も解けなかった25%ノイズ
"""

# 従来法:全滅
# - 標準アルファベット:❌
# - 拡張アルファベット:❌
# - リーダーボード:❌

# 畳み込み法:
結果 = 畳み込みシクロペプチドシーケンシング(
Spectrum25, M=20, N=1000
)

print(f"結果: {結果}")
# ✅ VKLFPWFNQY(チロシジンB1)
# パーティータイム!🎉

📈 ステップ7:なぜこんなに効果的なのか

7-1. 3つの理由

理由1:情報の最大活用
- 単一の質量だけでなく、質量の「関係性」も使う
- N個の質量から N(N-1)/2 個の情報を抽出

理由2:ノイズへの頑健性
- 本物は複数回現れる
- ノイズは確率的に頻度が低い

理由3:自動的な選択
- 人間が質量を選ぶ必要なし
- データが自分で重要な質量を教えてくれる

7-2. 可視化で理解

import matplotlib.pyplot as plt

def 頻度分布の可視化():
"""
本物とノイズの頻度差を可視化
"""

# 畳み込み後の頻度分布
質量 = range(57, 201)
頻度_本物 = [10, 8, 12, 15, 9, ...] # 本物は高頻度
頻度_ノイズ = [1, 0, 2, 1, 0, ...] # ノイズは低頻度

plt.figure(figsize=(12, 6))
plt.bar(質量, 頻度_本物, alpha=0.7, label='本物')
plt.bar(質量, 頻度_ノイズ, alpha=0.7, label='ノイズ')
plt.axhline(y=5, color='r', linestyle='--', label='閾値')
plt.xlabel('質量')
plt.ylabel('出現頻度')
plt.legend()
plt.title('畳み込み後の頻度分布')

# 閾値以上は本物の可能性が高い!

🚀 ステップ8:さらなる改良

8-1. 重み付き畳み込み

def 重み付き畳み込み(スペクトル):
"""
距離による重み付け
"""

畳み込み = []

for i in range(len(スペクトル)):
for j in range(i + 1, len(スペクトル)):
= スペクトル[j] - スペクトル[i]

# 近い質量の差ほど信頼性が高い
距離 = j - i
重み = 1.0 / 距離

畳み込み.append((, 重み))

return 畳み込み

8-2. 多段階畳み込み

def 多段階アプローチ():
"""
段階的に精度を上げる
"""

# 第1段階:粗い選択(M=30)
粗い候補 = 畳み込み(スペクトル, M=30)

# 第2段階:中間結果で再畳み込み
中間スペクトル = 生成されたスペクトル(粗い候補)

# 第3段階:精密選択(M=15)
精密候補 = 畳み込み(中間スペクトル, M=15)

return 精密候補

💡 ステップ9:実世界での応用

9-1. 創薬への応用

def 創薬での使用例():
"""
未知の抗生物質ペプチドの発見
"""

# 新しい細菌から抽出したペプチド
未知スペクトル = 質量分析(細菌抽出物)

# 畳み込みで候補アミノ酸を特定
候補質量 = 畳み込み分析(未知スペクトル)

# 非標準アミノ酸の発見
非標準 = [m for m in 候補質量 if m not in 標準質量]

if 非標準:
print("新しい非標準アミノ酸を発見!")
print("新薬の可能性!")

return 配列決定(未知スペクトル, 候補質量)

9-2. 品質管理での使用

def 品質チェック():
"""
合成ペプチドの品質確認
"""

期待配列 = "VKLFPWFNQY"
実測スペクトル = 質量分析(合成品)

# 畳み込みで実際の組成を確認
実際の質量 = 畳み込み分析(実測スペクトル)
期待の質量 = [AA_MASS[aa] for aa in 期待配列]

一致率 = len(set(実際の質量) & set(期待の質量)) / len(期待の質量)

if 一致率 > 0.95:
return "品質OK"
else:
return f"不純物の可能性(一致率: {一致率:.1%})"

🎯 まとめ:今日学んだことを整理

レベル1:基本概念

✅ スペクトル畳み込み = 全質量ペアの差 ✅ 頻度分析で本物のアミノ酸を特定 ✅ 144種類から10-20種類に自動削減

レベル2:なぜ効くか

✅ 本物のアミノ酸は複数回現れる ✅ ノイズは頻度が低い ✅ 質量の「関係性」も情報として使う

レベル3:実装のポイント

✅ パラメータM(通常20前後)の選択 ✅ 頻度の閾値設定 ✅ リーダーボードとの組み合わせ

レベル4:成果

✅ 10%ノイズ:問題なく成功 ✅ 25%ノイズ:初めて成功! ✅ 非標準アミノ酸も自動検出

🚨 次回予告

次回は「実践的な考慮事項」について:

  • 計算時間の最適化
  • メモリ使用量の削減
  • 実際の質量分析装置での注意点

お楽しみに!

🤔 練習問題

問題1:畳み込みの計算(基礎)

スペクトル = [0, 100, 200, 300]
このスペクトルの畳み込みを計算してください。
答え
ペアと差:
(100, 0): 100
(200, 0): 200
(300, 0): 300
(200, 100): 100
(300, 100): 200
(300, 200): 100

畳み込み結果:[100, 100, 100, 200, 200, 300]
頻度:100が3回(最多)、200が2回、300が1回

問題2:なぜ効くか(応用)

なぜ畳み込みは25%ノイズでも成功するのに、
通常のアルゴリズムは失敗するのでしょうか?
解答例
理由:
1. 情報量の違い
- 通常:N個の質量だけ
- 畳み込み:N(N-1)/2個の関係性

2. ノイズの影響
- 通常:ノイズも候補になる
- 畳み込み:ノイズは頻度が低く自動除外

3. 探索空間
- 通常:144種類を全て探索
- 畳み込み:10-20種類に自動削減

問題3:改良案(発展)

スペクトル畳み込みをさらに改良するアイデアを
提案してください。
ヒント
考える方向性:
- 質量の精度を考慮(誤差範囲)
- 化学的制約の追加
- 機械学習との組み合わせ
- 複数スペクトルの統合

この資料は細野真宏スタイルで、ソフトウェアエンジニアが段階的に理解できるよう設計されています。「なぜ?」を大切に、一歩ずつ進んでいきましょう!