def batch_predict_rois(flist, tuned_clfs, params, path_audio_db='./'): """ Predict the labels of rois in a list of audio files. Parameters ---------- flist: pandas DataFrame list of audio filenames to be analysed. Column name must be 'fname' tuned_clfs: dict data structure with tuned classifiers by grid search or random search params: dict data structure with the same parameters used to train the classifiers. Keys to be included: 'sample_rate_wav', 'flims', 'tlen', 'th', 'opt_spec', 'opt_shape_str' path_audio_db: str, default current directory path pointing to the directory where the audio files are located. Note that all files in flist must be in the same directory Returns ------- predictions: dict data structure with name of audio files as keys. Each element in the dictionary has a DataFrame with predictions for every region interest found. Predictions are given as probabilities for three different classifiers, namely Random Forest ('rf'), Adaboost ('adb') and Support Vector Machines ('svm'). """ t_start = time.time() # compute processing time # Load params and variables clf_svm = tuned_clfs['svm'].best_estimator_ clf_rf = tuned_clfs['rf'].best_estimator_ clf_adb = tuned_clfs['adb'].best_estimator_ flims = params['flims'] tlen = params['tlen'] th = params['th'] opt_spec = params['opt_spec'] opt_shape = opt_shape_presets(params['opt_shape_str']) sample_rate_std = params['sample_rate_wav'] # Batch: compute rois, features and predict through files predictions = dict() for idx, fname in enumerate(flist['fname']): print(idx+1, '/', len(flist), fname) # fname = flist['fname'][0] s, fs = sound.load(path_audio_db+fname) # Check sampling frequency on file if fs==sample_rate_std: pass else: print('Warning: sample rate mismatch, resampling audio file to standard', sample_rate_std, 'Hz') s = resample(s, fs, sample_rate_std, res_type='kaiser_fast') fs = sample_rate_std rois = find_rois_cwt(s, fs, flims, tlen, th) if rois.empty: #print('< No detection on file >') predictions[fname] = -1 else: # filter rois shorter than 25% of tlen idx_rm = (rois.max_t - rois.min_t) < tlen*0.25 rois.drop(index=np.where(idx_rm)[0], inplace=True) rois.reset_index(inplace=True, drop=True) if rois.empty: print('< No detection on file >') predictions[fname] = -1 else: # compute features rois_features = compute_rois_features(s, fs, rois, opt_spec, opt_shape, flims) # predict X = rois_features.loc[:,rois_features.columns.str.startswith('shp')] #X['frequency'] = preprocessing.scale(X['frequency']) # new! scale frequency pred_rf = pd.DataFrame(data=clf_rf.predict_proba(X), columns=[s + '_rf' for s in clf_rf.classes_.astype('str')]) pred_adb = pd.DataFrame(data=clf_adb.predict_proba(X), columns=[s + '_adb' for s in clf_adb.classes_.astype('str')]) pred_svm = pd.DataFrame(data=clf_svm.predict_proba(X), columns=[s + '_svm' for s in clf_svm.classes_.astype('str')]) # save to variable pred_proba_file = pd.concat([rois, pred_rf, pred_adb, pred_svm], axis=1) predictions[fname] = pred_proba_file t_stop = time.time() # compute processing time print('Batch process completed. Processing time: ', np.round(t_stop - t_start,2),'s') return predictions
def batch_feature_rois_no_verb(rois_list, params_features, path_audio): """ Computes features for a list of files Parameters: ---------- params_features: dict Dictionary with the basic parameters to feed find_rois: 'flims', 'tlen', and 'th'. path_flist : str Path to a *.txt file with the list of audio filenames to process path_audio : str Path to the place were the dataset of audio files are stored path_save : str Path with the file name to save the csv Returns: ------- info_features: dic Dictionary with features and all the parameters used to compute the features. Included keys: features, parameters_df, opt_shape, opt_spectro """ ## TODO: when the time limits are too short, the function has problems # load parameters flims = params_features['flims'] opt_spec = params_features['opt_spec'] opt_shape = opt_shape_presets(params_features['opt_shape_str']) # load detection data features = [] for idx, file in enumerate(rois_list): # unpack file values fname = file['fname'] rois_tf = file['rois'] #print(idx+1, '/', len(rois_list), fname) if rois_tf.empty: #print('< No detection on file >') features.append({'fname':fname, 'features': pd.DataFrame()}) else: # load materials: sound, spectrogram s, fs = sound.load(path_audio+fname) im, dt, df, ext = sound.spectrogram(s, fs, nperseg=opt_spec['nperseg'], overlap=opt_spec['overlap'], fcrop=flims, rescale=False, db_range=opt_spec['db_range']) # format rois to bbox ts = np.arange(ext[0], ext[1], dt) f = np.arange(ext[2],ext[3]+df,df) rois_bbox = format_rois(rois_tf, ts, f, fmt='bbox') # roi to image blob im_blobs = rois_to_imblobs(np.zeros(im.shape), rois_bbox) # get features: shape, center frequency im = normalize_2d(im, 0, 1) bbox, params, shape = shape_features(im, im_blobs, resolution='custom', opt_shape=opt_shape) _, cent = centroid(im, im_blobs) cent['frequency']= f[round(cent.y).astype(int)] # y values to frequency # format rois to time-frequency rois_out = format_rois(bbox, ts, f, fmt='tf') # combine into a single df aux_df = pd.concat([rois_out, shape, cent.frequency], axis=1) # aux_df['fname'] = fname features.append({'fname':fname, 'features': aux_df}) # Arranges the data into a dictionary info_features = {'features': features, 'parameters_df': params, 'opt_shape': opt_shape, 'opt_spectro': opt_spec} return info_features