text_plain_output_4.png application_vnd.jupyter.stderr_output_3.png application_vnd.jupyter.stderr_output_5.png text_plain_output_2.png application_vnd.jupyter.stderr_output_1.png
from sklearn.ensemble import RandomForestClassifier

from sklearn.metrics import accuracy_score

from sklearn.model_selection import train_test_split, StratifiedKFold, RandomizedSearchCV

import glob

import librosa

import numpy as np

import os

import pandas as pd

import random

def load_metadata(file_path):
    return pd.read_csv(file_path)
def process_audio_file(filename, species, train_audio_path, segment_duration=5):
    file_path = os.path.join(train_audio_path, species, filename)
    try:
        audio_data, sr = librosa.load(file_path)
    except Exception as e:
        print(f'Não foi possível carregar o arquivo {file_path}: {e}')
        return None
    segment_length = segment_duration * sr
    segments = [audio_data[i:i + segment_length] for i in range(0, len(audio_data), segment_length)]
    results = []
    for segment in segments:
        spectrogram = librosa.feature.melspectrogram(y=segment, sr=sr, n_mels=32)
        mfccs = librosa.feature.mfcc(y=segment, sr=sr, n_mfcc=12)
        mean_mfccs = mfccs.mean(axis=1)
        file_features = np.concatenate([spectrogram.flatten(), mean_mfccs])
        results.append((species, filename, file_features))
    return results
def load_and_process_audio_files(metadata_df, selected_species_list, train_audio_path, sample_size=60):
    audio_files = []
    for species in selected_species_list:
        species_path = os.path.join(train_audio_path, species, '*.ogg')
        species_audio_files = glob.glob(species_path)
        audio_files.extend([(os.path.basename(f), species) for f in species_audio_files])
    if len(audio_files) < sample_size:
        audio_files_sample = audio_files
    else:
        audio_files_sample = random.sample(audio_files, sample_size)
    results = []
    with concurrent.futures.ThreadPoolExecutor() as executor:
        results_list = list(executor.map(lambda x: process_audio_file(x[0], x[1], train_audio_path), audio_files_sample))
    for result in results_list:
        if result is not None:
            results.extend(result)
    species_list, filenames, features_list = zip(*results)
    max_features = max([len(features) for features in features_list])
    padded_features = []
    for features in features_list:
        padding_length = max(0, max_features - len(features))
        padded_features.append(np.pad(features, (0, padding_length), mode='constant'))
    results_df = pd.DataFrame({'primary_label': species_list, 'filename': filenames})
    features_df = pd.DataFrame(padded_features, columns=[f'feature_{i}' for i in range(len(padded_features[0]))])
    metadata_features_df = pd.concat([results_df, features_df], axis=1)
    X = metadata_features_df.drop(['primary_label', 'filename'], axis=1)
    y = metadata_features_df['primary_label']
    return (X, y)
def train_model(X_train, y_train, param_dist, stratified_kfold, n_iter=300, n_jobs=-1):
    clf = RandomForestClassifier(random_state=42)
    random_search = RandomizedSearchCV(estimator=clf, param_distributions=param_dist, n_iter=n_iter, cv=stratified_kfold, verbose=2, random_state=42, n_jobs=n_jobs)
    random_search.fit(X_train, y_train)
    best_clf = random_search.best_estimator_
    return best_clf
def evaluate_model(model, X_test, y_test):
    y_pred = model.predict(X_test)
    return accuracy_score(y_test, y_pred)
def process_test_audio_file(filename, test_audio_path, segment_duration=5):
    file_path = os.path.join(test_audio_path, filename)
    try:
        audio_data, sr = librosa.load(file_path)
    except Exception as e:
        print(f'Não foi possível carregar o arquivo {file_path}: {e}')
        return None
    segment_length = segment_duration * sr
    segments = [audio_data[i:i + segment_length] for i in range(0, len(audio_data), segment_length)]
    results = []
    for segment in segments:
        spectrogram = librosa.feature.melspectrogram(y=segment, sr=sr, n_mels=32)
        mfccs = librosa.feature.mfcc(y=segment, sr=sr, n_mfcc=12)
        mean_mfccs = mfccs.mean(axis=1)
        file_features = np.concatenate([spectrogram.flatten(), mean_mfccs])
        results.append(file_features)
    return results
def predict(model, test_features, max_features, species_columns):
    test_padding_length = max(0, max_features - len(test_features))
    test_features_padded = np.pad(test_features, (0, test_padding_length), mode='constant')
    predictions = model.predict_proba(test_features_padded.reshape(1, -1))[0]
    class_probabilities = dict(zip(model.classes_, predictions))
    predictions_aligned = [class_probabilities.get(species, 0) for species in species_columns]
    return predictions_aligned
def main():
    metadata_file_path = os.path.join('/kaggle/input/birdclef-2023/train_metadata.csv')
    metadata_df = load_metadata(metadata_file_path)
    selected_species_list = metadata_df['primary_label'].unique()
    train_audio_path = os.path.join('/kaggle/input/birdclef-2023/train_audio')
    X, y = load_and_process_audio_files(metadata_df, selected_species_list, train_audio_path)
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
    param_dist = {'n_estimators': range(20, 400), 'max_depth': [None] + list(range(1, 10)), 'min_samples_split': range(2, 11), 'min_samples_leaf': range(1, 5), 'bootstrap': [True, False]}
    stratified_kfold = StratifiedKFold(n_splits=4, shuffle=True, random_state=42)
    best_clf = train_model(X_train, y_train, param_dist, stratified_kfold)
    acc = evaluate_model(best_clf, X_test, y_test)
    print('Acurácia do modelo:', acc)
    test_audio_path = os.path.join('/kaggle/input/birdclef-2023/test_soundscapes')
    test_filename = 'soundscape_29201.ogg'
    test_features_list = process_test_audio_file(test_filename, test_audio_path)
    species_columns = sorted(metadata_df['primary_label'].unique())
    submission_df = pd.DataFrame(columns=['row_id'] + species_columns)
    for i, test_features in enumerate(test_features_list):
        if test_features is not None:
            predictions = predict(best_clf, test_features, X.shape[1], species_columns)
            temp_df = pd.DataFrame([predictions], columns=species_columns)
            test_filename_no_ext = os.path.splitext(test_filename)[0]
            temp_df.insert(0, 'row_id', f'{test_filename_no_ext}_{(i + 1) * 5}')
            submission_df = submission_df.append(temp_df, ignore_index=True)
        else:
            print(f'Não foi possível processar o segmento {i + 1} do arquivo de áudio de teste.')
    submission_df.to_csv('submission.csv', index=False)
if __name__ == '__main__':
    main()