Kaggle: CAFA 5 Protein Function Prediction.

Przez ostatnie 4 miesiące pracowaliśmy wraz z Michaliną nad projektem na konkurs Kaggle CAFA 5 Protein Function Prediction. Było to nasze pierwsze uczestnictwo w konkursie na platformie Kaggle, ale udało nam się ostatecznie zająć 37 miejsce, na 1675 zespołów. 

Czego dotyczył konkurs?

https://www.kaggle.com/competitions/cafa-5-protein-function-prediction

W ramach konkursu mieliśmy przewidzieć funkcje (GO) dla określonych białek, wykorzystując jedynie sekwencje aminokwasowe oraz kilka kluczowych informacji, takich jak Taxon ID, subontologia (BP, CCO, MF) i nazwa źródłowego organizmu. To zadanie określiliśmy jako klasyfikację wieloetykietową, ponieważ jednemu białku można przypisać wiele różnych funkcji. Istniało pewne ograniczenie, polegające na tym, że dla jednego białka można było przypisać maksymalnie 500 funkcji w danej subontologii.

Feature Extraction

Po dogłębnym zapoznaniu się z informacjami umieszczonymi w opisie konkursu i danymi, przeszliśmy do wyekstrahowania cech z sekwencji aminokwasowej. Zaczęliśmy od bardzo prostych metod takich jak liczenie długości sekwencji aminokwasowej i zliczanie poszczególnych aminokwasów występujących w łańcuchu. Dodaliśmy kilka fizykochemicznych właściwości liczonych przy użyciu biblioteki BioPython. Następnie użyliśmy publicznych zbiorów danych, które korzystając z modeli T5 / ESM-2 przekształcają sekwencje aminokwasów w osadzenia wektorowe (vector embedding). Do tego dodaliśmy hierarchiczną klasyfikację gatunków z bazy NCBI (National Center for Biotechnology Information) Taxonomy, dzięki temu, na podstawie taxonId każdemu organizmowi przepisaliśmy: królestwo, gromadę, klasę, rząd i gatunek. To wszystko razem połączone stanowiło nasze predyktory. 

Modele

Z uwagi na sprzętowe ograniczenia nasz cały dataset zdecydowaliśmy się podzielić. Długo zastanawialiśmy się jak właściwie powinniśmy podzielić nasz zbiór. Próbowaliśmy użyć klastrowania przy pomocy KMeans, dzielić zbiór według długości sekwencji aminokwasów, według superkrólestwa i subontologii, wybieraliśmy tylko białka, które przypisane były do najczęściej występujących top1500 go_id (przy czym liczbę top zmienialiśmy w zakresie 500 – 3000). 

Jeżeli chodzi o same modele to zaczynaliśmy od podstaw Machine Learningu, czyli Random Foresta, XGBoosta, lecz szybko doszliśmy do wniosku, że to sieci neuronowe będą dawały lepsze rezultaty. Skupiliśmy się na prostych sieciach pisanych w PyTorchu i Tensorflow. Wypróbowaliśmy sieć CNN i.. koniec końców to połączenie CNN z klasycznymi sieciami gęstymi napisanymi w Tensorflow dało nam najlepsze wyniki. 

Sieci CNN

Sieci konwolucyjne (CNN) – znane głównie z zastosowań w dziedzinie Computer Vision (CV) – okazały się niezwykle skuteczne również w analizie sekwencji białek. CNN są znane z ich zdolności do ekstrakcji hierarchicznych cech z obrazów. Podobnie jak w przypadku obrazów, sekwencje aminokwasów również mają pewną hierarchię cech. Na przykład, kilka kolejnych aminokwasów może tworzyć motyw lub domenę białka. CNN są w stanie wykryć te cechy na różnych poziomach abstrakcji, co pozwala na identyfikację istotnych obszarów w sekwencji białka. CNN wykazują inwariantność translacji, co oznacza, że mogą rozpoznawać cechy niezależnie od ich położenia w sekwencji. To jest ważne w przypadku analizy sekwencji białek, gdzie te same cechy występują czasem w różnych miejscach. 

Architektura sieci została zaczerpnięta z ogólnodostępnych konkursowych notebooków. Wprowadzona zmiana dotyczyła podziału całego datasetu na trzy mniejsze ze względu na subontologię oraz powiększeniu targetu z 500 go_id na 1500. Każdy z trzech zbiorów został przepuszczony przez sieć, a otrzymane predykcje złączone w jedno. 

Wrażenia

Choć nutka żalu wkradła się, gdy nie przekroczyliśmy progu scoru 0.6, to patrząc na całą naszą drogę od początku do końca, na nasz progres, zdobytą wiedzę, doświadczenie, jesteśmy zadowoleni i dumni z zajmowanego obecnie 37 miejsca (na 1675). Ten projekt pokazał, że czas, wytrwałość i konsekwencja są kluczowe do osiągnięcia sukcesu.

Wpis na linkedin: klik

Kod python:

Format FASTA jest powszechnie używany do przechowywania sekwencji biologicznych, takich jak sekwencje białek lub nukleotydów. Funkcja ta używa biblioteki SeqIO do analizy pliku FASTA i zbiera informacje takie jak identyfikator UniProt, opis, sekwencja i dodatkowe metadane z każdej sekwencji FASTA zapisanej w pliku. Następnie zwraca te dane jako ramkę danych pandas, gdzie każda kolumna odpowiada innemu rodzajowi informacji o sekwencjach biologicznych zawartych w pliku FASTA.

NCBI (National Center for Biotechnology Information) Taxonomy to baza danych, która hierarchicznie klasyfikuje organizmy na różnych poziomach taksonomicznych, takich jak królestwo, rodzina, gatunek, itp. Jest ona szeroko wykorzystywana w badaniach biologicznych, do analizy ewolucji i filogenezy organizmów.

Przygotowanie danych:

from Bio import SeqIO
from Bio.SeqUtils.ProtParam import ProteinAnalysis

def read_fasta(fastaPath):
    fasta_sequences = SeqIO.parse(open(fastaPath), 'fasta')
    columns = defaultdict(list)
    for fasta in fasta_sequences:
        columns['UniProt ID'].append(fasta.id)
        columns['description'].append(fasta.description)
        columns['seq'].append(str(fasta.seq))
        for key, value in fasta.annotations.items():
            columns[key].append(value)
    return pd.DataFrame(columns)

#############################################################################
# Wczytanie danych:

regex = r'OS=(.+?(?=\sOX=|\sGN=|\sPE=|\sSV=|$))'

train = pd.read_csv("/kaggle/input/cafa-5-protein-function-prediction/Train/train_terms.tsv",
                          sep="\t",
                          header=None, 
                          names=['UniProt ID', 'go_id', 'ontology'],
                          skiprows=1)\
.assign(GO=lambda x: x['go_id'].str.extract(r':(\d+)').astype(int))\
.merge(read_fasta("/kaggle/input/cafa-5-protein-function-prediction/Train/train_sequences.fasta")\
       .assign(OS = lambda x: x['description']\
               .str\
               .extract(regex)),
       how = 'inner',
       on='UniProt ID',)\
.merge(pd.read_csv("/kaggle/input/cafa-5-protein-function-prediction/Train/train_taxonomy.tsv",
                   sep="\t",
                   header=None,
                   names=['UniProt ID', 'taxon ID'],
                   skiprows=1),
       how = 'inner',
       on = 'UniProt ID')\
        .assign(seq_length=lambda x: x["seq"].apply(len))\
.sort_values('UniProt ID')\
.drop(columns = {'GO','description','OS', 'seq_length'})

train_embedding = pd.DataFrame(np.load('/kaggle/input/cafa-5-ems-2-embeddings-numpy/train_embeddings.npy'),
                              index = np.load('/kaggle/input/cafa-5-ems-2-embeddings-numpy/train_ids.npy'))\
.reset_index()\
.rename(columns={'index': 'UniProt ID'})\
.sort_values('UniProt ID')


train_physical = pd.read_csv('/kaggle/input/cafa5-features/train_features.csv', sep = ',')


test = (
    read_fasta("/kaggle/input/cafa-5-protein-function-prediction/Test (Targets)/testsuperset.fasta")
    .assign(taxon_ID=lambda x: x['description'].str.split('\t').str[1])
    .assign(seq_length=lambda x: x["seq"].apply(len)) 
    .drop('description', axis=1)
    .astype({'taxon_ID': int})
    .merge(
        pd.read_csv("/kaggle/input/cafa-5-protein-function-prediction/Test (Targets)/testsuperset-taxon-list.tsv",
                    sep="\t",
                    header=None,
                    encoding='unicode_escape',
                    names=['taxon_ID', 'OS'],
                    skiprows=1),
        how='inner',
        on='taxon_ID'
    )
)

test_embedding = pd.DataFrame(np.load('/kaggle/input/cafa-5-ems-2-embeddings-numpy/test_embeddings.npy'),
                              index = np.load('/kaggle/input/cafa-5-ems-2-embeddings-numpy/test_ids.npy'))\
.reset_index()\
.rename(columns={'index': 'UniProt ID'})\
.sort_values('UniProt ID')

test_physical = pd.read_csv('/kaggle/input/cafa5-features/test_features.csv', sep = ',')

#############################################################################
# Predyktory z bazy NCBI:

from ete3 import NCBITaxa
ncbi = NCBITaxa()

taxids = list(train['taxon ID'].unique())

taxid_kingdom_dict = {}

for taxid in taxids:
    try:
        lineage = ncbi.get_lineage(taxid)
        lineage_dict = ncbi.get_rank(lineage)
        taxonomy_dict = {rank: ncbi.get_taxid_translator([id])[id] for id, rank in lineage_dict.items()}

        taxid_kingdom_dict[taxid] = taxonomy_dict
        
    except:
        taxid_kingdom_dict[taxid] = {'Unknown': 'Unknown'}
        
train_taxon = pd.DataFrame.from_dict(taxid_kingdom_dict, orient='index')[['superkingdom', 'family', 'genus', 'species', 'phylum', 'class', 'order', 'clade']]\
.fillna('Unknown')\
.reset_index()\
.rename(columns = {'index':'taxon ID'})


taxids = list(test['taxon_ID'].unique())

taxid_kingdom_dict = {}

for taxid in taxids:
    try:
        lineage = ncbi.get_lineage(taxid)
        lineage_dict = ncbi.get_rank(lineage)
        taxonomy_dict = {rank: ncbi.get_taxid_translator([id])[id] for id, rank in lineage_dict.items()}

        taxid_kingdom_dict[taxid] = taxonomy_dict
        
    except:
        taxid_kingdom_dict[taxid] = {'Unknown': 'Unknown'}
        
test_taxon = pd.DataFrame.from_dict(taxid_kingdom_dict, orient='index')[['superkingdom', 'family', 'genus', 'species', 'phylum', 'class', 'order', 'clade']]\
.fillna('Unknown')\
.reset_index()\
.rename(columns = {'index':'taxon_ID'})


#############################################################################
# Połączenie utworzonych predyktorów w jeden zbiór:

train = train\
.merge(train_taxon, how = 'left', on = 'taxon ID')

for col in ['superkingdom', 'family', 'genus', 'species', 'phylum', 'class', 'order', 'clade']:

    temp_df = train.groupby(col)['go_id'].nunique().reset_index()
    
    temp_df.rename(columns = {'go_id': f'{col}_count'}, inplace = True)
    
    train = pd.merge(train, temp_df, on = col, how = 'left')


train = train\
.drop_duplicates(subset = 'UniProt ID')\
.merge(train_physical, how = 'left', on = 'UniProt ID')\
.merge(train_embedding, how = 'left', on = 'UniProt ID')

test = test\
.merge(test_physical, how = 'left', on = 'UniProt ID')\
.merge(test_taxon, how = 'left', on = 'taxon_ID')\
.merge(test_embedding, how = 'left', on = 'UniProt ID')

for column in ['superkingdom', 'family', 'genus', 'species', 'phylum', 'class', 'order', 'clade']:
    test = test.merge(train[[column, f'{column}_count']].drop_duplicates(),
                     how = 'left',
                     on = column)\
    .fillna(0)



#############################################################################
# Zapis przygotowanych zbiorów do formatu parquet:

test.columns = test.columns.astype(str)
train.columns = train.columns.astype(str)

test\
.rename(columns =  {"taxon_ID":'taxon ID'})\
.to_parquet(f'test.parquet', compression='gzip')

train\
.to_parquet(f'train.parquet', compression='gzip')

Model – sieć gęsta

Funkcja create_binary_matrix przyjmuje zestaw danych w postaci ramki danych dataset, gdzie zawarte są informacje na temat przypisania identyfikatorów UniProt i identyfikatorów Gene Ontology (GO). Następnie tworzy macierz binarną, w której każdy wiersz reprezentuje jeden identyfikator UniProt, a każda kolumna reprezentuje jeden identyfikator GO. Wartości w tej macierzy są typu bool, a ich ustawienie na True oznacza przypisanie danego identyfikatora UniProt do identyfikatora GO.

Plik counts używany jest do puszczania modelu w pętli. Nie trenujemy jednego modelu na wszystkich białkach, bierzemy kolejno:

  • 1500 białek z największą liczbą funkcji, trenujemy model i przepuszczamy przez niego zbiór testowy,
  • białka o liczbie funkcji 1501-3000 z rangkingu najpopularniejszych, trenujemy model i przepuszczamy przez niego zbiór testowy,
  • itd.
def create_binary_matrix(dataset):
    unique_go_ids = dataset['go_id'].unique()
    unique_uniprot_ids = dataset['UniProt_ID'].unique()


    go_id_map = {go_id: i for i, go_id in enumerate(unique_go_ids)}
    uniprot_id_map = {uniprot_id: i for i, uniprot_id in enumerate(unique_uniprot_ids)}


    matrix = np.zeros((len(unique_uniprot_ids), len(unique_go_ids)), dtype=bool)

    for _, row in dataset.iterrows():
        uniprot_id = row['UniProt_ID']
        go_id = row['go_id']
        matrix[uniprot_id_map[uniprot_id], go_id_map[go_id]] = True

    return pd.DataFrame(matrix, index=unique_uniprot_ids, columns=unique_go_ids)\
    .reset_index()\
    .rename(columns={'index': 'UniProt_ID'})


counts = pd.read_csv("/kaggle/input/cafa-5-protein-function-prediction/Train/train_terms.tsv",
                          sep="\t",
                          header=None, 
                          names=['UniProt ID', 'go_id', 'ontology'],
                          skiprows=1)['go_id'].value_counts().reset_index()



columns_to_scale = ['taxon ID', 'superkingdom_count', 'family_count',
    'genus_count', 'species_count', 'phylum_count', 'class_count',
    'order_count', 'clade_count', 'Eprotein', 'IP/mol weight', 'Hphb',
    'helix', 'turn', 'sheet', 'instability_index', 'length', 'aromaticity',
    'charge_at_pH']


batch_size = 256
epochs = 30

n = 1500
step = 1500
j = 1500


X_test  = pd.read_parquet('/kaggle/input/testextendedparquet/test.parquet')\
.drop(columns = {'superkingdom', 'family', 'genus', 'species', 'phylum', 'class', 'order', 'clade'})\
.set_index('UniProt ID')


early_stop = EarlyStopping(monitor='val_loss', patience=10, verbose=1, restore_best_weights=True)

for i in range(0, n, step):
    
#############################################################################
# WCZYTANIE I SKALOWANIE DANYCH:
    
    segment_start = i
    segment_end = i + step
    filtr = list(counts.iloc[segment_start:segment_end]['go_id'].unique())

    X = pd.read_parquet('/kaggle/input/trainextendedparquet/train.parquet')\
        .sort_values(by='UniProt ID')\
        .rename(columns={'UniProt ID': 'UniProt_ID'})\
        .set_index('UniProt_ID')\
        .drop(columns={'ontology'})

    y = create_binary_matrix(pd.read_parquet('/kaggle/input/binarymatrixparquet')\
                             .rename(columns = {'UniProt ID':'UniProt_ID'}))\
    .sort_values(by='UniProt_ID')\
    .set_index('UniProt_ID')[filtr]


    X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.1, random_state=42)

    X_train_scaled = X_train.copy()
    X_val_scaled = X_val.copy()


    scaler = MinMaxScaler()
    X_train_scaled[columns_to_scale] = scaler.fit_transform(X_train[columns_to_scale])
    X_val_scaled[columns_to_scale] = scaler.transform(X_val[columns_to_scale])
    
#############################################################################
# BUDOWA MODELU:

    model = Sequential()
    model.add(BatchNormalization(input_shape=(X_train_scaled.shape[1],))) 
    model.add(Dense(512, activation='relu')) 
    model.add(Dropout(0.15)) 
    model.add(Dense(256, activation='relu'))
    model.add(Dropout(0.15)) 
    model.add(Dense(256, activation='relu'))
    model.add(Dropout(0.15))
    model.add(Dense(y_train.shape[1], activation='sigmoid')) 
    
    model.compile(loss='binary_crossentropy', optimizer='adam', metrics=[AUC(curve='PR', multi_label=True)])


    print(f"\033[1mModel,\033[0m")
    print('\n')
    print(model.summary())
    print('\n')
    
#############################################################################
# TRENING:

    history = model.fit(X_train_scaled,
                       y_train, validation_data=(X_val_scaled, y_val), 
                    epochs=epochs, batch_size=batch_size, callbacks=[early_stop])
    
#############################################################################
#PREDYKCJA I ZAPIS DANYCH:
    
    print('\n')
    print('---------------------------------------------------------------')
    print('\n\n\n')

    temp_results = pd.DataFrame(columns=y_train.columns)
    results = []

    X_test = X_test.reset_index().rename(columns = {'UniProt ID':'UniProt_ID'}).set_index('UniProt_ID')

    X_test_scaled = X_test.copy()

    unique_ids = X_test.reset_index()['UniProt_ID'].unique()
    batches = [unique_ids[i:i + 500] for i in range(0, len(unique_ids), 500)]

    X_test_scaled[columns_to_scale]  = scaler.transform(X_test[columns_to_scale])
    


    for batch in tqdm(batches, desc='Processing UniProt ID batches'):
        
        X_test_batch = X_test_scaled.loc[X_test_scaled.index.isin(batch)].values

        y_pred_batch = model.predict(X_test_batch, verbose = None)

        temp = temp_results.copy()

        for k, uni in enumerate(batch):
            y_pred_temp = y_pred_batch[k]
            temp.loc[uni] = y_pred_temp


        results.append(temp\
                       .reset_index()\
                       .melt(id_vars=['index'], var_name='UniProt ID', value_name='value')\
                      .query('value >= 0.01'))


    df = pd.concat(results)\
    .rename(columns = {'UniProt ID':'go_id', 'index':'UniProt_ID',})\
    .assign(value = lambda x:x['value']\
            .round(3))\
    .to_csv(f"submission_{j}.tsv",header=False, index=False, sep="\t")

    j+=1500
    
    break

Model – CNN.

def normalize_data(df, columns_to_normalize):
    scaler = MinMaxScaler()
    df[columns_to_normalize] = scaler.fit_transform(df[columns_to_normalize])

    return df

columns_to_normalize = ['Eprotein', 'IP/mol weight', 'Hphb', 'helix', 
            'turn', 'sheet', 'instability_index', 'length', 'aromaticity', 
            'charge_at_pH', 'superkingdom_count', 'family_count', 'genus_count', 
            'species_count', 'phylum_count', 'class_count', 'order_count', 'clade_count',
            'A', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 
            'T', 'V', 'W', 'Y']

train = pd.read_parquet('/kaggle/input/train-v3')
train = normalize_data(train, columns_to_normalize)
train = train.sort_values('UniProt ID')

test = pd.read_parquet('/kaggle/input/test-v3')
test.rename(columns={'taxon_ID': 'taxon ID'}, inplace=True)
test = normalize_data(test, columns_to_normalize)

def prepare_data(temp_train, ontology):
    temp_train = temp_train[temp_train['ontology'] == ontology]
    temp_train = temp_train.sort_values(by='UniProt ID')

    temp_train_uniprot_ids = temp_train['UniProt ID'].tolist()

    temp_binary_matrix = binary_matrix[binary_matrix['UniProt ID'].isin(temp_train_uniprot_ids)].copy()

    temp_y = create_binary_matrix(temp_binary_matrix)
    temp_y = temp_y.sort_values(by='UniProt ID')
    temp_y.set_index('UniProt ID', inplace=True)

    num_columns_to_select = 1500
    selected_columns = temp_y.sum().sort_values(ascending=False).head(num_columns_to_select).index
    temp_y = temp_y[selected_columns]

    columns = ['Eprotein', 'IP/mol weight', 'Hphb', 'helix', 
               'turn', 'sheet', 'instability_index', 'length', 'aromaticity', 
               'charge_at_pH', 'superkingdom_count', 'family_count', 'genus_count', 
               'species_count', 'phylum_count', 'class_count','order_count',
              'A', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 
                'T', 'V', 'W', 'Y']

    for j in range(0, 1279):
        columns.append(f'{j}')

    X = temp_train[columns]
    y = temp_y
    
    return X, y, temp_y

class CNN1D(nn.Module):
    def __init__(self, input_dim, num_classes):
        super(CNN1D, self).__init__()
        self.conv1 = nn.Conv1d(in_channels=1, out_channels=3, kernel_size=3, dilation=1, padding=1, stride=1)
        self.pool1 = nn.MaxPool1d(kernel_size=2, stride=2)
        self.conv2 = nn.Conv1d(in_channels=3, out_channels=8, kernel_size=3, dilation=1, padding=1, stride=1)
        self.pool2 = nn.MaxPool1d(kernel_size=2, stride=2)
        self.fc1 = nn.Linear(in_features=int(8 * input_dim/4), out_features=864)
        self.fc2 = nn.Linear(in_features=864, out_features=num_classes)

    def forward(self, x):
        x = x.reshape(x.shape[0], 1, x.shape[1])
        x = self.pool1(nn.functional.tanh(self.conv1(x)))
        x = self.pool2(nn.functional.tanh(self.conv2(x)))
        x = torch.flatten(x, 1)
        x = nn.functional.tanh(self.fc1(x))
        x = self.fc2(x)
        return x
    
    
def train_cnn1d(X, y, num_epochs=5, batch_size=64, learning_rate=0.001):
    X = np.array(X, dtype=np.float32)
    y = np.array(y, dtype=np.float32)
    X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.1, random_state=42)

    train_dataset = TensorDataset(torch.tensor(X_train), torch.tensor(y_train))
    train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
    val_dataset = TensorDataset(torch.tensor(X_val), torch.tensor(y_val))
    val_loader = DataLoader(val_dataset, batch_size=batch_size)

    input_dim = X_train.shape[1]
    num_classes = y_train.shape[1]
    model = CNN1D(input_dim=input_dim, num_classes=num_classes)

    criterion = nn.BCEWithLogitsLoss()
    optimizer = optim.Adam(model.parameters(), lr=learning_rate)

    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    model.to(device)

    for epoch in range(num_epochs):
        model.train()
        train_loss = 0.0
        for inputs, labels in tqdm(train_loader):
            inputs, labels = inputs.to(device), labels.to(device)

            optimizer.zero_grad()

            outputs = model(inputs)

            loss = criterion(outputs, labels)
            loss.backward()

            optimizer.step()

            train_loss += loss.item()

        train_loss /= len(train_loader)

        model.eval()
        val_loss = 0.0
        with torch.no_grad():
            for inputs, labels in val_loader:
                inputs, labels = inputs.to(device), labels.to(device)

                outputs = model(inputs)

                loss = criterion(outputs, labels)
                val_loss += loss.item()

        val_loss /= len(val_loader)

        print(f"Epoch [{epoch+1}/{num_epochs}] - Train Loss: {train_loss:.4f} - Val Loss: {val_loss:.4f}")

    print("Training finished.")
    
    return model

def make_predictions(model, test_data, columns, temp_y):
    X_test = test_data[columns].values
    X_test = X_test.astype(np.float32)

    model.eval()

    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    X_test_tensor = torch.tensor(X_test).to(device)

    with torch.no_grad():
        probabilities = torch.sigmoid(model(X_test_tensor))

    submission_df = pd.DataFrame(probabilities.cpu().numpy(), columns=temp_y.columns, index=test_data['UniProt ID'])

    submission_df = submission_df.reset_index().melt(id_vars=['UniProt ID'], var_name='GO Term Id', value_name='Prediction')
    submission_df['Prediction'] = submission_df['Prediction'].round(3)
    submission_df = submission_df[submission_df['Prediction'] >= 0.01]

    return submission_df


X, y, temp_y = prepare_data(train, 'MFO')
trained_model = train_cnn1d(X, y, num_epochs=5, batch_size=64, learning_rate=0.001)

predictions_df_MFO = make_predictions(trained_model, test, columns, temp_y)
predictions_df_MFO['UniProt ID'].value_counts().head()
predictions_df_MFO.sort_values(by=['UniProt ID', 'Prediction'], ascending=[True, False], inplace = True)
predictions_df_MFO = predictions_df_MFO.groupby('UniProt ID').head(500).reset_index(drop=True)

X, y, temp_y = prepare_data(train, 'BPO')
trained_model = train_cnn1d(X, y, num_epochs=5, batch_size=64, learning_rate=0.001)
predictions_df_BPO = make_predictions(trained_model, test, columns, temp_y)
predictions_df_BPO['UniProt ID'].value_counts().head()
predictions_df_BPO.sort_values(by=['UniProt ID', 'Prediction'], ascending=[True, False], inplace = True)
predictions_df_BPO = predictions_df_BPO.groupby('UniProt ID').head(500).reset_index(drop=True)

X, y, temp_y = prepare_data(train, 'CCO')
trained_model = train_cnn1d(X, y, num_epochs=5, batch_size=64, learning_rate=0.001)
predictions_df_CCO = make_predictions(trained_model, test, columns, temp_y)
predictions_df_CCO['UniProt ID'].value_counts().head()
predictions_df_CCO.sort_values(by=['UniProt ID', 'Prediction'], ascending=[True, False], inplace = True)
predictions_df_CCO = predictions_df_CCO.groupby('UniProt ID').head(500).reset_index(drop=True)

sub = pd.concat([predictions_df_MFO, predictions_df_BPO, predictions_df_CCO])

Zobacz także:

  • Piotr Szymański

    Kategoria:

    Hejka! Zapraszam na skrót z minionych dwóch tygodni, który przyswoić możecie przy ciepłej herbatce w te mroczne, szare dni. W opublikowanym przez Google 14 listopada ostrzeżeniu wskazano kilka najważniejszych rodzajów oszustw internetowych. Uwagę zwrócono między na niebezpieczne techniki ataków typu cloaking, które nabierają nowego wymiaru dzięki wykorzystaniu sztucznej inteligencji. Cloaking polega na ukrywaniu przed użytkownikiem […]
  • Piotr Szymański

    Kategoria:

    Hejka po dłuższej przerwie! Zaczynamy świeżym tematem. Raptem kilkanaście godzin temu do użytkowników trafiła, zapowiedziana 25 lipca, funkcja SearchGPT od OpenAI, umożliwiająca, w przeciwieństwie do tradycyjnych modeli językowych, na integrację z internetem w czasie rzeczywistym. SearchGPT ma dostęp do aktualnych informacji z sieci, co pozwala na udzielanie odpowiedzi opartych na najnowszych danych. Ponadto SearchGPT dostarcza […]
  • Piotr Szymański

    Kategoria:

    Hejson! Dzisiejsza konsumpcja mediów ma to do siebie, że odbywa się na 5-6 calowym ekranie telefonu. Ma też to do siebie, że zanim zdjęcie dotrze do Ciebie, to przejdzie przez 6 konwersacji na jedynym słusznym messengerze, zatem zostanie 6-cio krotnie skompresowane. W międzyczasie, jak będziecie mieli pecha, to jakiś wujek zrobi screena, zamiast zapisać zdjęcie […]
  • Piotr Szymański

    Kategoria:

    Hej! Robimy bardzo dużo zdjęć, a co za tym idzie – wiele z nich jest niechlujnych, z zabałagnionym tłem. Możemy jednak chcieć wykorzystać je do pochwalenia się naszym ryjkiem na jakimś publicznym profilu, gdyż np. naturalne, miękkie światło korzystnie eksponuje naszą facjatę. Podejścia mogą być dwa – albo zdecydujemy się na blur bądź zupełne usunięcie […]
  • Piotr Szymański

    Kategoria:

    Strzałeczka. Nvidia przejęła OctoAI, startup specjalizujący się w optymalizacji modeli uczenia maszynowego. To już piąta akwizycja Nvidii w 2024 roku, co czyni aktualnie nam panujący rok rekordowym pod względem liczby przejęć. OctoAI, założone w 2019 roku przez Luisa Ceze, skupiło się na tworzeniu oprogramowania zwiększającego wydajność modeli uczenia maszynowego na różnych platformach sprzętowych. Oprogramowanie OctoAI […]