AAclust: Selecting redundancy-reduced scale sets

The Amino Acid clustering (AAclust) class is k-optimized clustering wrapper for selecting redundancy-reduced sets of numerical scales, introduced in [Breimann24a].

You will learn

  • Tool: AAclust

  • Input: a numeric matrix X (e.g. df_scales), optional n_clusters

  • Output: a redundancy-reduced subset via labels_ and medoids_

  • Best used for: selecting redundancy-reduced scale sets (or representative proteins)

  • Related protocol: P7: Select & reduce features

  • Related API: AAclust, AAclustPlot

We load an example scale dataset to showcase it:

import aaanalysis as aa
aa.options["verbose"] = False

# Load the full amino acid scale set (scales as columns; transposed for clustering)
df_scales = aa.load_scales()
X = df_scales.T

AAclust can utilize any clustering model that uses the n_clusters parameter:

from sklearn.cluster import KMeans

# AAclust with KMeans (default)
aac = aa.AAclust(model_class=KMeans)

By fitting AAclust, its three-step algorithm is performed to select an optimized n_clusters (k). The three steps involve (1) an estimation of lower bound of k, (2) refinement of k, and (3) an optional cluster merging. Various results are saved as attributes:

# Fit clustering model (KMeans by default)
aac = aa.AAclust()
aac.fit(X)
# Get output parameters
n_clusters = aac.n_clusters
print("n_clusters: ", n_clusters)
n_clusters:  56

Instead of optimizing the number of clusters, we can pre-define it using the n_clusters parameter:

# Fit clustering model with pre-selected k
labels = aac.fit(X, n_clusters=5).labels_

We can visualize the clustering results and the obtained cluster centers using the respective plotting AAclustPlot class. For scales, pass the scales DataFrame directly via df_scales; it is transposed internally, so you never call .T yourself. All data points are shown in the PCA plot with the cluster centers highlighted by an ‘x’:

import matplotlib.pyplot as plt

aac_plot = aa.AAclustPlot()
aa.plot_settings()
fig, ax = aac_plot.centers(df_scales=df_scales, labels=labels)
plt.tight_layout()
plt.show()
../_images/tutorial3a_aaclust_1_output_11_0.png

To obtain redundancy-reduced scale sets, AAclust selects one medoid per cluster, which is the scale closest to the center of the respective cluster. These can be highlighted using the medoids() method:

aac_plot = aa.AAclustPlot()
aa.plot_settings()
fig, ax = aac_plot.medoids(df_scales=df_scales, labels=labels)
plt.tight_layout()
plt.show()
../_images/tutorial3a_aaclust_2_output_13_0.png

A one-call shortcut: select_scales

The fit → medoid → map-back-to-columns sequence above is the canonical scale-selection workflow, so AAclust bundles it into a single call. select_scales clusters the scales in df_scales and returns the columns of the representative (medoid) scales, one per cluster, without the manual transpose and medoid-name bookkeeping. The fitted attributes (labels_, medoid_names_, …) remain available on the instance afterwards.

# One-call redundancy reduction: return the representative (medoid) scale per cluster
df_scales_selected = aac.select_scales(df_scales, n_clusters=100)
aa.display_df(df_scales_selected, n_rows=10, show_shape=True)
DataFrame shape: (20, 100)
  ANDN920101 SIMZ760101 ARGP820103 AURR980114 ROBB760106 ROBB760113 MEIH800101 BIGC670101 BIOV880101 MEEJ810102 BROC820102 COHE430101 ONEK900101 BUNA790103 ROBB760101 FAUJ880101 RACS820112 QIAN880133 QIAN880123 KARS160101 LINS030101 CHAM830107 CHAM830108 LINS030104 CHOC760103 CHOP780101 ROBB760102 QIAN880109 QIAN880115 LEVM780105 WOLS870103 FINA910102 CHOP780214 CHOP780215 CIDH920105 PONP930101 GEIM800101 KARS160121 CEDJ970104 DAYM780201 NADH010102 WOLR790101 FAUJ880111 AURR980106 FASG760105 FINA910101 LINS030106 FAUJ880112 KLEP840101 MITS020101 GEIM800102 PALJ810105 GRAR740101 MIYS990105 MEIH800102 FUKS010102 HOPT810101 ROSG850101 ISOY800102 ISOY800106 MAXF760104 YUTK870104 OOBM850105 LEVM760103 RICJ880103 NAKH900103 NAKH900104 NAKH900109 NAKH920105 OOBM770104 OOBM850104 CORJ870107 PRAM820102 KUMS000103 QIAN880104 QIAN880117 SUYM030101 QIAN880130 QIAN880137 RACS820103 MUNV940102 RICJ880101 RICJ880113 RICJ880114 ROBB760107 SNEP660101 SUEM840102 TANS770108 VASM830101 VASM830102 VELV850101 BASU050102 ZIMJ680101 GEOR030106 AURR980118 KOEH090102 NADH010107 GEOR030102 KARS160110 LINS030117
AA                                                                                                                                                                                                        
A 0.494000 0.268000 0.504000 0.746000 0.342000 0.101000 0.556000 0.164000 0.476000 0.221000 0.567000 0.500000 1.000000 0.691000 0.921000 0.305000 0.427000 0.291000 0.133000 0.100000 0.152000 0.000000 0.000000 0.093000 0.627000 0.174000 0.484000 0.754000 0.554000 0.247000 0.466000 0.024000 0.124000 0.044000 0.393000 0.471000 0.725000 0.248000 0.905000 0.707000 0.749000 0.979000 0.000000 0.412000 0.852000 0.154000 0.046000 0.000000 0.500000 0.000000 0.620000 0.276000 0.000000 0.492000 0.420000 0.512000 0.453000 0.147000 0.270000 0.543000 0.034000 0.966000 0.465000 0.999000 0.118000 0.329000 0.224000 0.829000 0.442000 0.899000 0.567000 0.446000 0.823000 1.000000 0.842000 0.455000 0.403000 0.358000 0.116000 0.287000 0.000000 0.250000 0.632000 0.324000 0.333000 0.653000 0.103000 0.097000 0.437000 0.617000 0.295000 0.275000 0.270000 0.516000 0.356000 0.174000 0.282000 0.250000 0.863000 0.186000
C 0.864000 0.258000 0.387000 0.219000 0.747000 0.849000 0.370000 0.323000 0.936000 0.420000 0.000000 0.033000 0.739000 0.819000 0.445000 0.422000 1.000000 0.369000 0.676000 0.200000 0.433000 0.000000 1.000000 0.000000 0.746000 0.661000 0.387000 0.645000 0.297000 0.469000 1.000000 0.024000 0.584000 0.658000 0.647000 0.760000 0.176000 0.776000 0.095000 0.017000 1.000000 0.837000 0.000000 0.000000 0.164000 0.154000 0.000000 0.000000 0.500000 0.000000 1.000000 0.157000 1.000000 0.016000 0.220000 0.000000 0.375000 0.429000 0.986000 0.510000 0.189000 0.929000 0.000000 0.932000 0.147000 0.000000 0.300000 0.000000 0.111000 0.751000 0.543000 0.725000 0.136000 0.000000 0.544000 0.000000 0.888000 1.000000 0.388000 0.000000 0.420000 0.188000 0.526000 0.471000 0.820000 0.496000 0.337000 0.000000 0.521000 0.734000 0.657000 0.866000 0.482000 0.000000 0.000000 0.115000 1.000000 0.246000 0.557000 0.000000
D 1.000000 0.206000 0.000000 0.314000 0.234000 0.790000 0.852000 0.324000 0.191000 0.138000 0.358000 0.000000 0.754000 0.745000 0.555000 0.382000 0.509000 0.735000 0.362000 0.400000 0.451000 1.000000 0.000000 0.588000 0.237000 0.908000 0.813000 0.340000 0.475000 0.037000 0.766000 0.081000 0.933000 0.246000 0.034000 0.021000 0.516000 0.683000 0.581000 0.759000 0.371000 0.459000 0.000000 0.431000 0.098000 1.000000 0.754000 1.000000 0.000000 0.000000 0.240000 0.622000 0.502000 0.825000 0.700000 0.655000 1.000000 0.216000 0.041000 0.642000 0.215000 0.934000 0.317000 0.993000 0.588000 0.075000 0.000000 0.286000 0.012000 0.755000 0.986000 0.000000 0.585000 0.400000 0.684000 0.491000 0.474000 0.274000 0.727000 0.923000 0.270000 0.688000 0.263000 0.118000 0.099000 0.091000 0.909000 1.000000 0.976000 0.225000 1.000000 0.008000 0.208000 0.404000 0.658000 1.000000 0.824000 0.091000 0.293000 0.186000
E 0.420000 0.210000 0.032000 0.805000 0.000000 0.092000 0.889000 0.488000 0.106000 0.227000 0.212000 0.200000 0.826000 0.745000 1.000000 0.372000 0.586000 0.398000 0.286000 0.500000 0.616000 1.000000 0.000000 0.804000 0.288000 0.248000 1.000000 0.754000 0.653000 0.000000 0.445000 0.081000 0.360000 0.096000 0.000000 0.092000 0.945000 0.710000 0.797000 0.724000 0.263000 0.435000 0.000000 1.000000 0.459000 0.423000 0.923000 1.000000 0.000000 0.183000 0.760000 0.228000 0.335000 0.857000 0.780000 1.000000 1.000000 0.315000 0.000000 0.576000 0.056000 0.935000 0.518000 0.969000 0.088000 0.112000 0.059000 0.378000 0.000000 0.665000 0.808000 0.233000 0.551000 0.621000 0.833000 0.227000 0.336000 0.326000 0.512000 0.916000 0.048000 0.438000 0.789000 0.235000 0.613000 0.223000 0.077000 0.000000 0.608000 0.531000 0.046000 0.061000 0.212000 0.610000 0.548000 0.802000 0.540000 0.404000 0.396000 0.349000
F 0.877000 0.887000 0.670000 0.680000 0.703000 0.328000 0.000000 0.783000 1.000000 0.862000 0.903000 0.567000 0.812000 1.000000 0.622000 0.702000 0.539000 0.301000 0.429000 0.700000 0.744000 0.000000 1.000000 0.082000 0.831000 0.119000 0.265000 0.764000 0.446000 0.679000 0.514000 0.024000 0.292000 0.105000 0.844000 0.665000 0.549000 0.842000 0.365000 0.198000 0.915000 0.859000 0.000000 0.314000 0.557000 0.154000 0.000000 0.000000 0.500000 0.000000 0.380000 0.307000 0.000000 0.000000 0.000000 0.128000 0.141000 0.811000 0.676000 0.351000 0.056000 0.934000 0.449000 0.969000 0.029000 0.382000 0.806000 0.536000 0.288000 0.305000 0.413000 0.950000 0.340000 0.350000 0.798000 0.655000 0.689000 0.232000 0.455000 0.000000 0.301000 0.562000 0.053000 0.206000 0.396000 0.612000 0.233000 0.395000 0.269000 0.023000 0.749000 1.000000 0.896000 0.712000 0.521000 0.068000 0.547000 0.536000 0.208000 0.326000
G 0.025000 0.032000 0.170000 0.077000 0.266000 1.000000 0.852000 0.000000 0.388000 0.177000 0.374000 0.133000 0.696000 0.596000 0.000000 0.000000 0.603000 0.828000 0.629000 0.000000 0.000000 0.000000 0.000000 0.144000 0.593000 1.000000 0.000000 0.498000 0.693000 0.284000 0.494000 0.049000 0.994000 0.868000 0.115000 0.275000 0.000000 0.000000 0.797000 0.267000 0.561000 1.000000 0.000000 0.142000 0.869000 0.154000 0.123000 0.000000 0.500000 0.000000 0.020000 1.000000 0.269000 0.492000 0.560000 0.605000 0.531000 0.000000 0.054000 0.000000 1.000000 0.967000 0.866000 0.000000 0.500000 0.323000 0.291000 0.754000 0.363000 1.000000 0.638000 0.352000 1.000000 0.286000 0.000000 1.000000 0.776000 0.737000 0.264000 0.570000 0.639000 0.812000 0.000000 0.059000 0.027000 0.000000 0.000000 0.148000 0.143000 0.455000 0.040000 0.000000 0.033000 0.210000 0.562000 0.328000 0.143000 0.000000 0.863000 0.023000
H 0.840000 0.387000 0.053000 0.562000 0.323000 0.454000 0.407000 0.561000 0.579000 0.044000 0.508000 0.233000 0.739000 0.851000 0.598000 0.714000 0.457000 0.443000 0.638000 0.600000 0.640000 0.000000 1.000000 0.423000 0.271000 0.440000 0.155000 0.847000 0.782000 0.235000 0.601000 0.024000 0.449000 0.009000 0.475000 0.326000 0.769000 0.683000 0.122000 0.414000 0.439000 0.432000 1.000000 0.279000 0.000000 0.154000 0.400000 0.000000 0.500000 0.209000 0.540000 0.032000 0.211000 0.492000 0.380000 0.197000 0.453000 0.575000 0.541000 0.530000 0.114000 0.970000 0.459000 0.969000 0.294000 0.089000 0.424000 0.082000 0.005000 0.464000 0.814000 0.610000 0.483000 0.136000 0.360000 0.545000 0.646000 0.737000 0.198000 0.000000 0.357000 0.562000 0.842000 1.000000 0.405000 0.372000 0.000000 0.356000 0.745000 0.345000 0.191000 0.305000 0.358000 0.612000 1.000000 0.650000 0.134000 0.201000 0.355000 0.419000
I 0.000000 0.990000 0.543000 0.893000 1.000000 0.151000 0.037000 0.663000 0.885000 0.552000 0.788000 1.000000 0.797000 0.745000 0.561000 1.000000 0.349000 0.049000 0.514000 0.400000 0.530000 0.000000 0.000000 0.010000 1.000000 0.000000 0.077000 0.690000 0.297000 1.000000 0.318000 0.024000 0.000000 0.026000 1.000000 1.000000 0.462000 0.604000 0.541000 0.672000 0.909000 0.989000 0.000000 0.392000 0.885000 0.000000 0.000000 0.000000 0.500000 0.000000 0.460000 0.047000 0.000000 0.079000 0.060000 0.191000 0.250000 0.588000 0.878000 0.464000 0.052000 1.000000 0.251000 0.975000 0.029000 0.565000 0.824000 0.547000 0.683000 0.568000 0.257000 0.969000 0.313000 0.500000 0.588000 0.727000 0.516000 0.200000 0.306000 0.811000 0.221000 0.375000 0.105000 0.206000 0.324000 0.934000 0.714000 0.615000 0.570000 0.070000 0.000000 0.917000 1.000000 0.457000 0.644000 0.000000 0.347000 0.161000 0.033000 0.140000
K 0.506000 0.516000 0.004000 0.970000 0.329000 0.613000 1.000000 0.694000 0.000000 0.000000 0.368000 0.733000 0.942000 0.691000 0.665000 0.451000 0.392000 0.456000 0.238000 0.500000 0.768000 0.000000 1.000000 1.000000 0.034000 0.495000 0.071000 0.872000 0.644000 0.136000 0.040000 0.000000 0.331000 0.368000 0.247000 0.000000 0.769000 0.660000 0.743000 0.328000 0.000000 0.467000 1.000000 0.402000 0.557000 0.038000 0.831000 0.000000 1.000000 0.530000 0.520000 0.362000 0.120000 1.000000 1.000000 0.784000 1.000000 0.325000 0.149000 0.616000 0.233000 0.956000 1.000000 1.000000 0.176000 0.151000 0.153000 0.246000 0.004000 0.743000 0.291000 0.027000 0.027000 0.543000 0.421000 0.618000 0.351000 0.558000 0.413000 1.000000 0.142000 0.438000 0.895000 0.588000 0.054000 0.562000 0.012000 0.247000 0.559000 0.688000 0.294000 0.112000 0.521000 0.536000 0.822000 0.809000 0.536000 0.195000 0.433000 1.000000
L 0.272000 0.835000 0.989000 0.923000 0.747000 0.076000 0.259000 0.663000 0.867000 0.696000 0.913000 1.000000 0.942000 0.691000 0.720000 0.618000 0.543000 0.204000 0.438000 0.400000 0.567000 0.000000 0.000000 0.041000 0.746000 0.110000 0.200000 0.936000 0.317000 0.469000 0.325000 0.024000 0.129000 0.149000 0.773000 0.734000 0.747000 0.604000 1.000000 0.190000 0.901000 0.995000 0.000000 0.284000 0.885000 0.154000 0.000000 0.000000 0.500000 0.000000 0.620000 0.000000 0.000000 0.016000 0.180000 0.326000 0.250000 0.626000 0.473000 0.682000 0.042000 0.990000 0.351000 0.968000 0.029000 1.000000 0.935000 1.000000 1.000000 0.562000 0.394000 1.000000 0.340000 0.643000 1.000000 0.064000 0.591000 0.326000 0.215000 0.000000 0.104000 0.375000 0.316000 0.206000 0.000000 1.000000 0.428000 0.123000 0.717000 0.771000 0.000000 0.920000 0.821000 0.690000 0.671000 0.012000 0.364000 0.513000 0.218000 0.186000

Next application: selecting representative proteins

AAclust clusters any numerical feature matrix, not only scales. Because a medoid is a real sample rather than a synthetic centroid, clustering proteins by their feature vectors and keeping one medoid per cluster yields a redundancy-reduced set of representative proteins, each an actual entry from df_seq. select_proteins does this in one call and reports a cluster label, an is_representative flag, and dist_to_rep (the distance of each protein to its cluster representative, i.e. a redundancy score).

Below, the per-protein matrix comes from CPP features. The same call accepts other per-protein representations just as well, such as pooled protein-language-model embeddings or structural (e.g. DSSP) features, which the data-representations tutorial demonstrates.

# Build a per-protein CPP feature matrix (one row per protein)
df_seq = aa.load_dataset(name="DOM_GSEC", n=25)
labels = list(df_seq["label"])
sf = aa.SequenceFeature()
df_parts = sf.get_df_parts(df_seq=df_seq)
cpp = aa.CPP(df_scales=df_scales, df_parts=df_parts)
df_feat = cpp.run(labels=labels)
X = sf.feature_matrix(df_parts=df_parts, features=df_feat["feature"])
print("X (n_proteins, n_features):", X.shape)
X (n_proteins, n_features): (50, 100)
# Select one representative protein (cluster medoid) per cluster
df_repr = aac.select_proteins(df_seq=df_seq, X=X, n_clusters=10)
aa.display_df(df_repr, n_rows=10, show_shape=True)
DataFrame shape: (50, 12)
  entry gene sequence label tmd_start tmd_stop jmd_n tmd jmd_c cluster is_representative dist_to_rep
1 Q14802 FXYD3 MQKVTLGLLVFLAGF...PGETPPLITPGSAQS 0 37 59 NSPFYYDWHS LQVGGLICAGVLCAMGIIIVMSA KCKCKFGQKS 8 0 1.465234
2 Q86UE4 MTDH MAARSWQDELAQQAE...SPKQIKKKKKARRET 0 50 72 LGLEPKRYPG WVILVGTGALGLLLLFLLGYGWA AACAGARKKR 3 0 1.379094
3 Q969W9 PMEPA1 MHRLMGVNSTAAAAA...AIWSKEKDKQKGHPL 0 41 63 FQSMEITELE FVQIIIIVVVMMVMVVVITCLLS HYKLSARSFI 7 0 1.704990
4 P53801 PTTG1IP MAPGVARGPTPYWRL...GLFKEENPYARFENN 0 97 119 RWGVCWVNFE ALIITMSVVGGTLLLGIAICCCC CCRRKRSRKP 7 1 0.000000
5 Q8IUW5 RELL1 MAPRALPGSAVLAAA...EVPATPVKRERSGTE 0 59 81 NDTGNGHPEY IAYALVPVFFIMGLFGVLICHLL KKKGYRCTTE 7 0 1.294481
6 P01135 TGFA MVPSAGQLALFALGI...LLKGRTACCHSETVV 0 99 121 AVVAASQKKQ AITALVVVSIVALAVLIITCVLI HCCQVRKHCE 8 1 0.000000
7 O43914 TYROBP MGGLEPCSRLLLLPL...SDVYSDLNTQRPYYK 0 42 64 DCSCSTVSPG VLAGIVMGDLVLTVLIALAVYFL GRLVPRGRGA 9 0 1.563711
8 P05556 ITGB1 MNLQPIFWIGLISSV...KSAVTTVVNPKYEGK 0 729 751 ENPECPTGPD IIPIVAGVVAGIVLIGLALLLIW KLLMIIHDRR 9 1 0.000000
9 P16234 PDGFRA MGTSHPAFLVLGCLL...DIGIDSSDLVEDSFL 0 527 549 VAPTLRSELT VAAAVLVLLVIVIISLIVLVVIW KQKPRYEIRW 0 0 1.123703
10 P50895 BCAM MEPPDAPAQARGAPR...SGGARGGSGGFGDEC 0 549 571 TVSPQTSQAG VAVMAVAVSVGLLLLVVAVFYCV RRKGGPCCRQ 2 0 1.325820

The medoid of each cluster is a representative protein, so is_representative sums to the number of clusters and dist_to_rep is 0 for the representatives. To obtain a fixed number of representatives, set n_clusters; to let AAclust choose it, leave n_clusters=None and tune min_th. Use return_data="filtered" to get only the representative proteins together with their feature matrix:

# Keep only the representative proteins (and their feature rows)
df_repr_only, X_repr = aac.select_proteins(df_seq=df_seq, X=X, n_clusters=10,
                                           return_data="filtered")
print("representative proteins:", df_repr_only.shape[0])
aa.display_df(df_repr_only, n_rows=10, show_shape=True)
representative proteins: 10
DataFrame shape: (10, 12)
  entry gene sequence label tmd_start tmd_stop jmd_n tmd jmd_c cluster is_representative dist_to_rep
1 Q14802 FXYD3 MQKVTLGLLVFLAGF...PGETPPLITPGSAQS 0 37 59 NSPFYYDWHS LQVGGLICAGVLCAMGIIIVMSA KCKCKFGQKS 2 1 0.000000
2 P53801 PTTG1IP MAPGVARGPTPYWRL...GLFKEENPYARFENN 0 97 119 RWGVCWVNFE ALIITMSVVGGTLLLGIAICCCC CCRRKRSRKP 8 1 0.000000
3 P05556 ITGB1 MNLQPIFWIGLISSV...KSAVTTVVNPKYEGK 0 729 751 ENPECPTGPD IIPIVAGVVAGIVLIGLALLLIW KLLMIIHDRR 5 1 0.000000
4 Q9BZ11 ADAM33 MGWRPRRARGTPLLL...DPQADQVQMPRSCLW 0 13 35 WRPRRARGTP LLLLLLLLLLWPVPGAGVLQGHI PGQPVTPHWV 0 1 0.000000
5 Q7Z6A9 BTLA MKTLPAMLGTGKLFW...VKEAPTEYASICVRS 0 153 175 PSKDEMASRP WLLYRLLPLGGLPLLITTCFCLF CCLRRHQGKQ 4 1 0.000000
6 P15509 CSF2RA MLLLVTSLLLCELPH...GKGYREEVLTVKEIT 0 324 346 EFGSDDGNLG SVYIYVLLIVGTLVCGIVLGFLF KRFLRIQRLF 7 1 0.000000
7 Q03157 Aplp1 MGPTSPAARGQGRRW...HGYENPTYRFLEERP 1 585 607 APSGTGVSRE ALSGLLIMGAGGGSLIVLSLLLL RKKKPYGTIS 3 1 0.000000
8 P19022 CDH2 MCRIAGALRTLLPLL...PRFKKLADMYGGGDD 1 724 746 RIVGAGLGTG AIIAILLCIIILLILVLMFVVWM KRRDKERQAK 9 1 0.000000
9 D3ZZK3 Epha4 MAGIFYFILFSFLFG...MRTQMQQMHGRMVPV 1 548 570 RIIGDGANST VLLVSVSGSVVLVVILIAAFVIS RRRSKYSQAK 6 1 0.000000
10 Q61483 Dll1 MGRRSALALAVVSAL...VLSAEKDECVIATEV 1 545 567 HMESQGGPFP WVAVCAGVVLVLLLLLGCAAVVV CVRLKLQKHQ 1 1 0.000000

Visualizing the representative proteins

The protein clustering is visualized with the same medoids() method, but here the input is the per-protein feature matrix X (samples × features), passed as-is: proteins need no transpose, unlike the df_scales form used for scales above. The method projects X into PCA space and marks the representative protein (medoid) of each cluster.

# Visualize the protein clusters and their representatives (medoids) in PCA space
aac_plot = aa.AAclustPlot()
aa.plot_settings()
fig, ax = aac_plot.medoids(X, labels=df_repr["cluster"])
plt.tight_layout()
plt.show()
../_images/tutorial3a_aaclust_3_output_22_0.png

Feature-space vs. sequence-identity redundancy

select_proteins reduces redundancy in CPP feature space (physicochemical similarity). A complementary tool, filter_seq() (CD-HIT; requires the pro extra), reduces redundancy by sequence identity, keeping one representative per cluster of similar sequences. Both annotate the proteins with the same cluster / is_representative columns, so they compose, but they answer different questions.

# Sequence-identity redundancy reduction with CD-HIT (requires aaanalysis[pro])
df_cdhit = aa.filter_seq(df_seq, method="cd-hit", similarity_threshold=0.7)
n_cpp = int(df_repr["is_representative"].sum())
n_seq = int(df_cdhit["is_representative"].sum())
print(f"representatives by select_proteins (CPP feature space): {n_cpp} of {len(df_seq)}")
print(f"representatives by filter_seq    (sequence identity):   {n_seq} of {len(df_seq)}")
aa.display_df(df_cdhit, n_rows=10, show_shape=True)
representatives by select_proteins (CPP feature space): 10 of 50
representatives by filter_seq    (sequence identity):   50 of 50
DataFrame shape: (50, 4)
  entry cluster identity_with_rep is_representative
1 Q9ERC8 0 100.000000 1
2 Q63155 1 100.000000 1
3 Q8VHS2 2 100.000000 1
4 P08069 3 100.000000 1
5 Q15303 4 100.000000 1
6 Q6ZRH7 5 100.000000 1
7 P16234 6 100.000000 1
8 D3ZZK3 7 100.000000 1
9 P54763 8 100.000000 1
10 O94985 9 100.000000 1

At a 70% identity threshold, CD-HIT finds these sequences non-redundant and keeps all of them, while select_proteins still compresses them to 10 physicochemical representatives. The two tools are complementary, not interchangeable: use filter_seq() to drop near-duplicate sequences before training, and select_proteins to pick a diverse, interpretable subset in feature space.

For further details, see our Feature Engineering API, AAontology Usage Principles, and AAclust Usage Principles.