寫了一段小代碼,主要是用來測試一段序列的k均值聚類效果;
中間想到debug一下,但是想到自己似乎從來沒有正式地接觸過jupyter notebook中地debug,平時也只是多開幾個cell,然后在其他cell中復制粘貼部分代碼,一步一步運行,然后進行print()大法查看變量和數據結構。
import numpy as np
from sklearn.cluster import KMeans
window_size = 3
features = [] #每一個窗口的012顯狀態的頻率
obs_labels = [] #每一個窗口中心位置的顯狀態標簽n_states=3 # 隱狀態數
n_observations=3 # 顯狀態數seq = "MEGDAVEAIVEESETFIKGKERKTYQRRREGGQEEDACHLPQNQTDGGEVVQDVNSSVQMVMMEQLDPTLLQMKTEVMEGTVAPEAEAAVDDTQIITLQVVNMEEQPINIGELQLVQVPVPVTVPVATTSVEELQGAYENEVSKEGLAESEPMICHTLPLPEGFQVVKVGANGEVETLEQGELPPQEDPSWQKDPDYQPPAKKTKKTKKSKLRYTEEGKDVDVSVYDFEEEQQEGLLSEVNAEKVVGNMKPPKPTKIKKKGVKKTFQCELCSYTCPRRSNLDRHMKSHTDERPHKCHLCGRAFRTVTLLRNHLNTHTGTRPHKCPDCDMAFVTSGELVRHRRYKHTHEKPFKCSMCDYASVEVSKLKRHIRSHTGERPFQCSLCSYASRDTYKLKRHMRTHSGEKPYECYICHARFTQSGTMKMHILQKHTENVAKFHCPHCDTVIARKSDLGVHLRKQHSYIEQGKKCRYCDAVFHERYALIQHQKSHKNEKRFKCDQCDYACRQERHMIMHKRTHTGEKPYACSHCDKTFRQKQLLDMHFKRYHDPNFVPAAFVCSKCGKTFTRRNTMARHADNCAGPDGVEGENGGETKKSKRGRKRKMRSKKEDSSDSENAEPDLDDNEDEEEPAVEIEPEPEPQPVTPAPPPAKKRRGRPPGRTNQPKQNQPTAIIQVEDQNTGAIENIIVEVKKEPDAEPAEGEEEEAQPAATDAPNGDLTPEMILSMMDR"
seq_encoded = [ [0 if i in ["K","R","H"] else (1 if i in ["D","E"] else 2) ] for i in seq ]
for i in range(len(seq_encoded) - window_size + 1):window = seq_encoded[i:i+window_size]feature = np.zeros(n_observations)for obs in window:feature[obs[0]] += 1 # 計算0、1、2顯狀態頻數feature /= window_size # 歸一化features.append(feature)obs_labels.append(seq_encoded[i+window_size//2]) # 記錄中心位置的顯狀態標簽features,obs_labels = np.array(features),np.array(obs_labels)# 使用K-means聚類
kmeans = KMeans(n_clusters=n_observations,random_state=2025)
cluster_labels = kmeans.fit_predict(features) #fit+predict# 統計每個簇對應的觀測分布
emission_counts = np.ones((n_states,n_observations)) # 拉普拉斯平滑for cluster_id in range(n_states):cluster_mask = (cluster_labels == cluster_id) # 獲取當前簇的掩碼,如果是當前簇的樣本則為Truecluster_obs = obs_labels[cluster_mask] #取出對應cluster id的觀測標簽for obs in cluster_obs:emission_counts[cluster_id,obs] += 1 # 對于每一個cluster_id是隱狀態,obs是顯狀態,進行計數
# 歸一化
emission_counts /= emission_counts.sum(axis=1, keepdims=True) # 按行歸一化
# 輸出每個簇的觀測分布
for i in range(n_states):print(f"Cluster {i} emission distribution: {emission_counts[i]}")
就拿最基本的斷點操作來舉例,比如說我只想運行代碼到第22行,然后簡單查看一下features,obs_labels的變量值。
如果是以前剛入門的我,可能就是直接另外開一個cell,然后把這前面22行代碼直接復制粘貼,然后單獨運行,運行之后再一步一步print,太low了。
一,現在來介紹一個調試的庫pdb:
jupyter的調試是通過python自帶的pdb庫來實現的。
首先是你的每個cell的code前面,加兩句
import pdb
pdb.set_trace() # 調試用,斷點調試
然后我們手頭上的代碼直接運行:
ctrl+enter
運行之后可以看到彈出的調試命令行框:
一些最基本的調試命令參數:
完整命令 | 簡寫命令 | 描述 |
---|---|---|
args | a | 打印當前函數的參數 |
break | b | 設置斷點 |
clear | cl | 清除斷點 |
condition | 無 | 設置條件斷點 |
continue | c或者cont | 繼續運行,知道遇到斷點或者腳本結束 |
disable | 無 | 禁用斷點 |
enable | 無 | 啟用斷點 |
help | h | 查看pdb幫助 |
ignore | 無 | 忽略斷點 |
jump | j | 跳轉到指定行數運行 |
list | l | 列出腳本清單 |
next | n | 執行下條語句,遇到函數不進入其內部 |
p | p | 打印變量值,也可以用print |
quit | q | 退出 pdb |
return | r | 一直運行到函數返回 |
tbreak | 無 | 設置臨時斷點,斷點只中斷一次 |
step | s | 執行下一條語句,遇到函數進入其內部 |
where | w | 查看所在的位置 |
! | 無 | 在pdb中執行語句 |
比如說我想在這里的第26行設置一個斷點:
我們輸入:
b 26
在輸入b 26之后:對比前面
比如說我現在想看一下features變量的值,我直接在輸入框中輸入features,或者print(features),同樣我可以看一下shape:
查看另外一個變量:
看shape,是一維array:
如果輸出調試信息太多了,可以clear cell的output;
調試完畢之后可以直接q退出。
二,jupyter本身也開發了相應的可視化debug工具
debugger
參考:https://zhuanlan.zhihu.com/p/120215615
參考:https://blog.csdn.net/weixin_41529093/article/details/117535034