{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":91844,"databundleVersionId":11361821,"sourceType":"competition"}],"dockerImageVersionId":31040,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport os\nimport librosa\nimport librosa.display\nfrom matplotlib import cm\nfrom collections import Counter\nimport glob\nfrom tqdm import tqdm\nimport plotly.express as px\nimport plotly.graph_objects as go\n\n# Set plotting style\nplt.style.use('ggplot')\nsns.set(style=\"whitegrid\")\n\n# Güncellenmiş path'ler\nBASE_PATH = '/kaggle/input/birdclef-2025/'\nOUTPUT_PATH = '/kaggle/working/'\n\n# Taxonomy verisini yükle\ntaxonomy_df = pd.read_csv(f'{BASE_PATH}taxonomy.csv')\n\n# Train verisini yükle\ntry:\n    train_df = pd.read_csv(f'{BASE_PATH}train.csv', nrows=None)\nexcept:\n    train_df = pd.read_csv(f'{BASE_PATH}train.csv', nrows=10000)\n    print(\"Loaded subset due to size constraints\")\n\n# Çıktı dizini\noutput_dir = os.path.join(OUTPUT_PATH, 'data_visualizations')\nos.makedirs(output_dir, exist_ok=True)\n\n# 1. Analyze bird species distribution\ndef analyze_species_distribution():\n    print(\"Analyzing species distribution...\")\n    \n    # Train verisinden tür dağılımını al\n    if not train_df.empty:\n        # Türleri say\n        species_counts = train_df['primary_label'].value_counts()\n        total_samples = len(train_df)\n        \n        # Tür dağılım grafiği\n        plt.figure(figsize=(14, 8))\n        species_counts[:20].plot(kind='bar')\n        plt.title(f'Top 20 Bird Species (Total Samples: {total_samples})')\n        plt.xlabel('Species Code')\n        plt.ylabel('Number of Recordings')\n        plt.xticks(rotation=45)\n        plt.tight_layout()\n        plt.savefig(os.path.join(output_dir, 'species_distribution.png'))\n        plt.show()  # Grafiği göster\n        plt.close()\n        \n        return species_counts\n    else:\n        print(\"Train data not available for species distribution analysis\")\n        return None\n\n# 2. Collection Analysis - YENİ EKLENEN\ndef analyze_collections():\n    print(\"\\nAnalyzing data collections...\")\n    if 'collection' in train_df.columns:\n        fig, axes = plt.subplots(2, 2, figsize=(16, 12))\n        \n        # Collection dağılımı\n        collection_counts = train_df['collection'].value_counts()\n        axes[0,0].pie(collection_counts.values, labels=collection_counts.index, autopct='%1.1f%%')\n        axes[0,0].set_title('Data Collection Distribution')\n        \n        # Collection bazında rating dağılımı\n        if 'rating' in train_df.columns:\n            sns.boxplot(data=train_df, x='collection', y='rating', ax=axes[0,1])\n            axes[0,1].set_title('Rating Distribution by Collection')\n            axes[0,1].tick_params(axis='x', rotation=45)\n        \n        # Collection bazında tür sayısı\n        collection_species = train_df.groupby('collection')['primary_label'].nunique()\n        collection_species.plot(kind='bar', ax=axes[1,0])\n        axes[1,0].set_title('Number of Species by Collection')\n        axes[1,0].tick_params(axis='x', rotation=45)\n        \n        # Collection bazında total kayıt sayısı\n        collection_records = train_df['collection'].value_counts()\n        collection_records.plot(kind='bar', ax=axes[1,1])\n        axes[1,1].set_title('Number of Records by Collection')\n        axes[1,1].tick_params(axis='x', rotation=45)\n        \n        plt.tight_layout()\n        plt.savefig(os.path.join(output_dir, 'collection_analysis.png'))\n        plt.show()  # Grafiği göster\n        plt.close()\n    else:\n        print(\"Collection column not found\")\n\n# 3. Taxonomy Analysis - YENİ EKLENEN\ndef analyze_taxonomy():\n    print(\"\\nAnalyzing taxonomy (class distribution)...\")\n    if not taxonomy_df.empty:\n        # Merge train data with taxonomy for class analysis\n        train_with_taxonomy = train_df.merge(taxonomy_df, on='primary_label', how='left')\n        \n        fig, axes = plt.subplots(2, 2, figsize=(16, 12))\n        \n        # Class dağılımı (Aves, Amphibia, Insecta, etc.)\n        class_counts = train_with_taxonomy['class_name'].value_counts()\n        axes[0,0].pie(class_counts.values, labels=class_counts.index, autopct='%1.1f%%')\n        axes[0,0].set_title('Class Distribution in Training Data')\n        \n        # Class bazında tür sayısı\n        class_species = train_with_taxonomy.groupby('class_name')['primary_label'].nunique()\n        class_species.plot(kind='bar', ax=axes[0,1])\n        axes[0,1].set_title('Number of Species per Class')\n        axes[0,1].tick_params(axis='x', rotation=45)\n        \n        # Class bazında total kayıt sayısı\n        class_records = train_with_taxonomy['class_name'].value_counts()\n        class_records.plot(kind='bar', ax=axes[1,0])\n        axes[1,0].set_title('Number of Records per Class')\n        axes[1,0].tick_params(axis='x', rotation=45)\n        \n        # Top 10 tür her class için\n        if 'Aves' in class_counts.index:\n            birds_only = train_with_taxonomy[train_with_taxonomy['class_name'] == 'Aves']\n            top_birds = birds_only['primary_label'].value_counts()[:10]\n            top_birds.plot(kind='barh', ax=axes[1,1])\n            axes[1,1].set_title('Top 10 Bird Species')\n        \n        plt.tight_layout()\n        plt.savefig(os.path.join(output_dir, 'taxonomy_analysis.png'))\n        plt.show()  # Grafiği göster\n        plt.close()\n\n# 4. Geographic Analysis - YENİ EKLENEN\ndef analyze_geographic_distribution():\n    print(\"\\nAnalyzing geographic distribution...\")\n    if all(col in train_df.columns for col in ['longitude', 'latitude']):\n        fig, axes = plt.subplots(2, 2, figsize=(16, 12))\n        \n        # Geographic scatter plot\n        scatter = axes[0,0].scatter(train_df['longitude'], train_df['latitude'], \n                                   alpha=0.6, s=1)\n        axes[0,0].set_xlabel('Longitude')\n        axes[0,0].set_ylabel('Latitude')\n        axes[0,0].set_title('Recording Locations')\n        \n        # Latitude distribution\n        axes[0,1].hist(train_df['latitude'].dropna(), bins=50, alpha=0.7)\n        axes[0,1].set_xlabel('Latitude')\n        axes[0,1].set_ylabel('Number of Recordings')\n        axes[0,1].set_title('Latitude Distribution')\n        \n        # Longitude distribution\n        axes[1,0].hist(train_df['longitude'].dropna(), bins=50, alpha=0.7)\n        axes[1,0].set_xlabel('Longitude')\n        axes[1,0].set_ylabel('Number of Recordings')\n        axes[1,0].set_title('Longitude Distribution')\n        \n        # Geographic diversity per coordinate\n        if 'collection' in train_df.columns:\n            for collection in train_df['collection'].unique():\n                if pd.notna(collection):\n                    subset = train_df[train_df['collection'] == collection]\n                    axes[1,1].scatter(subset['longitude'], subset['latitude'], \n                                    label=collection, alpha=0.6, s=10)\n            axes[1,1].legend()\n            axes[1,1].set_xlabel('Longitude')\n            axes[1,1].set_ylabel('Latitude')\n            axes[1,1].set_title('Recording Locations by Collection')\n        \n        plt.tight_layout()\n        plt.savefig(os.path.join(output_dir, 'geographic_analysis.png'))\n        plt.show()  # Grafiği göster\n        plt.close()\n\n# 5. Secondary Labels Analysis - YENİ EKLENEN\ndef analyze_secondary_labels():\n    print(\"\\nAnalyzing secondary labels...\")\n    if 'secondary_labels' in train_df.columns:\n        # Secondary label varlığı\n        has_secondary = train_df['secondary_labels'].notna() & (train_df['secondary_labels'] != \"['']\")\n        secondary_stats = has_secondary.value_counts()\n        \n        fig, axes = plt.subplots(2, 2, figsize=(16, 10))\n        \n        # Secondary label varlık grafiği\n        axes[0,0].pie(secondary_stats.values, \n                     labels=['No Secondary Labels', 'Has Secondary Labels'], \n                     autopct='%1.1f%%')\n        axes[0,0].set_title('Records with Secondary Labels')\n        \n        # Primary vs secondary label count\n        train_df['has_secondary'] = has_secondary\n        label_counts = train_df.groupby('primary_label')['has_secondary'].sum().sort_values(ascending=False)\n        label_counts[:15].plot(kind='bar', ax=axes[0,1])\n        axes[0,1].set_title('Top 15 Species with Most Secondary Labels')\n        axes[0,1].tick_params(axis='x', rotation=45)\n        \n        # Collection vs secondary labels\n        if 'collection' in train_df.columns:\n            collection_secondary = train_df.groupby('collection')['has_secondary'].agg(['sum', 'count'])\n            collection_secondary['ratio'] = collection_secondary['sum'] / collection_secondary['count']\n            collection_secondary['ratio'].plot(kind='bar', ax=axes[1,0])\n            axes[1,0].set_title('Secondary Label Ratio by Collection')\n            axes[1,0].tick_params(axis='x', rotation=45)\n        \n        # Secondary label length distribution (for records that have them)\n        secondary_data = train_df[train_df['has_secondary']]\n        if not secondary_data.empty:\n            try:\n                secondary_lengths = secondary_data['secondary_labels'].apply(lambda x: len(eval(x)) if pd.notna(x) and x != \"['']\" else 0)\n                axes[1,1].hist(secondary_lengths, bins=20, alpha=0.7)\n                axes[1,1].set_xlabel('Number of Secondary Labels')\n                axes[1,1].set_ylabel('Count')\n                axes[1,1].set_title('Distribution of Secondary Label Counts')\n            except:\n                axes[1,1].text(0.5, 0.5, 'Could not parse secondary labels', \n                              ha='center', va='center', transform=axes[1,1].transAxes)\n        \n        plt.tight_layout()\n        plt.savefig(os.path.join(output_dir, 'secondary_labels_analysis.png'))\n        plt.show()  # Grafiği göster\n        plt.close()\n\n# 6. Quality and Rating Analysis - YENİ EKLENEN\ndef analyze_quality_ratings():\n    print(\"\\nAnalyzing quality ratings...\")\n    if 'rating' in train_df.columns:\n        fig, axes = plt.subplots(2, 3, figsize=(18, 12))\n        \n        # Rating distribution\n        rating_counts = train_df['rating'].value_counts().sort_index()\n        axes[0,0].bar(rating_counts.index, rating_counts.values)\n        axes[0,0].set_xlabel('Rating')\n        axes[0,0].set_ylabel('Count')\n        axes[0,0].set_title('Rating Distribution')\n        \n        # Rating by collection\n        if 'collection' in train_df.columns:\n            sns.boxplot(data=train_df, x='collection', y='rating', ax=axes[0,1])\n            axes[0,1].set_title('Rating Distribution by Collection')\n            axes[0,1].tick_params(axis='x', rotation=45)\n        \n        # Average rating by species (top 20)\n        species_ratings = train_df.groupby('primary_label')['rating'].mean().sort_values(ascending=False)\n        species_ratings[:20].plot(kind='bar', ax=axes[0,2])\n        axes[0,2].set_title('Top 20 Species by Average Rating')\n        axes[0,2].tick_params(axis='x', rotation=45)\n        \n        # Rating vs record count correlation\n        species_stats = train_df.groupby('primary_label').agg({\n            'rating': 'mean',\n            'primary_label': 'count'\n        }).rename(columns={'primary_label': 'count'})\n        \n        axes[1,0].scatter(species_stats['count'], species_stats['rating'], alpha=0.6)\n        axes[1,0].set_xlabel('Number of Records')\n        axes[1,0].set_ylabel('Average Rating')\n        axes[1,0].set_title('Species Record Count vs Average Rating')\n        \n        # Low quality recordings analysis\n        low_quality = train_df[train_df['rating'] <= 2]\n        if not low_quality.empty:\n            low_q_species = low_quality['primary_label'].value_counts()[:15]\n            low_q_species.plot(kind='bar', ax=axes[1,1])\n            axes[1,1].set_title('Top 15 Species with Low Quality Recordings (≤2)')\n            axes[1,1].tick_params(axis='x', rotation=45)\n        \n        # Rating distribution over time (if we can extract from filename)\n        try:\n            # Extract year from filename if possible\n            train_df['year'] = train_df['filename'].str.extract(r'(\\d{4})')\n            if train_df['year'].notna().any():\n                yearly_ratings = train_df.groupby('year')['rating'].mean()\n                yearly_ratings.plot(kind='line', ax=axes[1,2], marker='o')\n                axes[1,2].set_title('Average Rating by Year')\n                axes[1,2].set_xlabel('Year')\n                axes[1,2].set_ylabel('Average Rating')\n            else:\n                axes[1,2].text(0.5, 0.5, 'No year data found in filenames', \n                              ha='center', va='center', transform=axes[1,2].transAxes)\n        except:\n            axes[1,2].text(0.5, 0.5, 'Could not extract year data', \n                          ha='center', va='center', transform=axes[1,2].transAxes)\n        \n        plt.tight_layout()\n        plt.savefig(os.path.join(output_dir, 'quality_ratings_analysis.png'))\n        plt.show()  # Grafiği göster\n        plt.close()\n\n# 7. Author and License Analysis - YENİ EKLENEN\ndef analyze_authors_licenses():\n    print(\"\\nAnalyzing authors and licenses...\")\n    if all(col in train_df.columns for col in ['author', 'license']):\n        fig, axes = plt.subplots(2, 2, figsize=(16, 12))\n        \n        # Top contributing authors\n        author_counts = train_df['author'].value_counts()[:15]\n        author_counts.plot(kind='barh', ax=axes[0,0])\n        axes[0,0].set_title('Top 15 Contributing Authors')\n        \n        # License distribution\n        license_counts = train_df['license'].value_counts()\n        axes[0,1].pie(license_counts.values, labels=license_counts.index, autopct='%1.1f%%')\n        axes[0,1].set_title('License Distribution')\n        \n        # Author diversity (number of species per author)\n        author_species = train_df.groupby('author')['primary_label'].nunique().sort_values(ascending=False)[:15]\n        author_species.plot(kind='bar', ax=axes[1,0])\n        axes[1,0].set_title('Top 15 Authors by Species Diversity')\n        axes[1,0].tick_params(axis='x', rotation=45)\n        \n        # License vs quality relationship\n        if 'rating' in train_df.columns:\n            license_quality = train_df.groupby('license')['rating'].mean().sort_values(ascending=False)\n            license_quality.plot(kind='bar', ax=axes[1,1])\n            axes[1,1].set_title('Average Quality by License Type')\n            axes[1,1].tick_params(axis='x', rotation=45)\n        \n        plt.tight_layout()\n        plt.savefig(os.path.join(output_dir, 'authors_licenses_analysis.png'))\n        plt.show()  # Grafiği göster\n        plt.close()\n\n# 8. Audio File Structure Analysis - YENİ EKLENEN\ndef analyze_audio_structure():\n    print(\"\\nAnalyzing audio file structure...\")\n    if not train_df.empty and 'filename' in train_df.columns:\n        fig, axes = plt.subplots(2, 2, figsize=(16, 10))\n        \n        # File format distribution\n        train_df['file_format'] = train_df['filename'].str.split('.').str[-1]\n        format_counts = train_df['file_format'].value_counts()\n        axes[0,0].pie(format_counts.values, labels=format_counts.index, autopct='%1.1f%%')\n        axes[0,0].set_title('Audio File Format Distribution')\n        \n        # Files per species\n        files_per_species = train_df['primary_label'].value_counts()\n        axes[0,1].hist(files_per_species.values, bins=50, alpha=0.7)\n        axes[0,1].set_xlabel('Number of Files per Species')\n        axes[0,1].set_ylabel('Number of Species')\n        axes[0,1].set_title('Distribution of Files per Species')\n        \n        # Directory structure analysis\n        train_df['dir_depth'] = train_df['filename'].str.count('/')\n        depth_counts = train_df['dir_depth'].value_counts().sort_index()\n        axes[1,0].bar(depth_counts.index, depth_counts.values)\n        axes[1,0].set_xlabel('Directory Depth')\n        axes[1,0].set_ylabel('Number of Files')\n        axes[1,0].set_title('File Directory Depth Distribution')\n        \n        # Filename length analysis\n        train_df['filename_length'] = train_df['filename'].str.len()\n        axes[1,1].hist(train_df['filename_length'], bins=30, alpha=0.7)\n        axes[1,1].set_xlabel('Filename Length')\n        axes[1,1].set_ylabel('Count')\n        axes[1,1].set_title('Filename Length Distribution')\n        \n        plt.tight_layout()\n        plt.savefig(os.path.join(output_dir, 'audio_structure_analysis.png'))\n        plt.show()  # Grafiği göster\n        plt.close()\n\n# 3. Audio analysis - if audio files are available\ndef analyze_audio_samples():\n    print(\"Analyzing audio samples...\")\n    \n    audio_dir = os.path.join(BASE_PATH, 'train_audio')\n    if not os.path.exists(audio_dir):\n        print(f\"Audio directory {audio_dir} not found. Skipping audio analysis.\")\n        return\n    \n    # List all audio files\n    audio_files = []\n    for root, dirs, files in os.walk(audio_dir):\n        for file in files:\n            if file.endswith('.ogg') or file.endswith('.wav') or file.endswith('.mp3'):\n                audio_files.append(os.path.join(root, file))\n    \n    # If there are too many files, sample a subset\n    if len(audio_files) > 100:\n        import random\n        audio_files = random.sample(audio_files, 100)\n    \n    # Extract audio features\n    durations = []\n    sample_rates = []\n    species = []\n    \n    for audio_file in tqdm(audio_files[:20], desc=\"Processing audio files\"):  # Process a subset\n        try:\n            y, sr = librosa.load(audio_file, sr=None)\n            duration = librosa.get_duration(y=y, sr=sr)\n            durations.append(duration)\n            sample_rates.append(sr)\n            \n            # Extract species from filename\n            species_name = os.path.basename(os.path.dirname(audio_file))\n            species.append(species_name)\n            \n            # Generate and save spectrogram for a few samples\n            if len(durations) <= 5:  # Only create spectrograms for the first 5 files\n                plt.figure(figsize=(10, 4))\n                D = librosa.amplitude_to_db(np.abs(librosa.stft(y)), ref=np.max)\n                librosa.display.specshow(D, sr=sr, x_axis='time', y_axis='log')\n                plt.colorbar(format='%+2.0f dB')\n                plt.title(f'Spectrogram: {species_name}')\n                plt.tight_layout()\n                plt.savefig(os.path.join(output_dir, f'spectrogram_{species_name}_{len(durations)}.png'))\n                plt.close()\n        except Exception as e:\n            print(f\"Error processing {audio_file}: {str(e)}\")\n    \n    # Plot distribution of audio durations\n    plt.figure(figsize=(10, 6))\n    sns.histplot(durations, bins=30, kde=True)\n    plt.title('Distribution of Audio Recording Durations')\n    plt.xlabel('Duration (seconds)')\n    plt.ylabel('Count')\n    plt.tight_layout()\n    plt.savefig(os.path.join(output_dir, 'audio_durations.png'))\n    plt.show()  # Grafiği göster\n    plt.close()\n    \n    # Plot species vs duration\n    plt.figure(figsize=(12, 8))\n    species_df = pd.DataFrame({'species': species, 'duration': durations})\n    sns.boxplot(x='species', y='duration', data=species_df)\n    plt.title('Audio Duration by Species')\n    plt.xlabel('Species')\n    plt.ylabel('Duration (seconds)')\n    plt.xticks(rotation=90)\n    plt.tight_layout()\n    plt.savefig(os.path.join(output_dir, 'duration_by_species.png'))\n    plt.show()  # Grafiği göster\n    plt.close()\n    \n    return durations, species\n\ndef analyze_spectrograms():\n    print(\"\\nSpectrogram directory not available - skipping spectrogram analysis...\")\n    return None, None\n\ndef analyze_ratings():\n    print(\"\\nAnalyzing recording quality ratings...\")\n    if 'rating' in train_df.columns:\n        plt.figure(figsize=(10, 6))\n        sns.countplot(data=train_df, x=\"rating\")\n        plt.title(\"Distribution of Recording Quality Ratings (1-5)\")\n        plt.savefig(os.path.join(output_dir, 'rating_distribution.png'))\n        plt.show()  # Grafiği göster\n        plt.close()\n    else:\n        print(\"Rating column not found in training data\")\n\ndef analyze_locations():\n    print(\"\\nAnalyzing recording locations...\")\n    if all(col in train_df.columns for col in ['longitude', 'latitude', 'collection']):\n        plt.figure(figsize=(12, 8))\n        sns.scatterplot(data=train_df, x=\"longitude\", y=\"latitude\", \n                        alpha=0.5, hue=\"collection\", palette=\"viridis\")\n        plt.title(\"Recording Locations (XC vs. iNat vs. CSA)\")\n        plt.savefig(os.path.join(output_dir, 'recording_locations.png'))\n        plt.show()  # Grafiği göster\n        plt.close()\n    else:\n        print(\"Location data columns missing\")\n\ndef analyze_soundscapes():\n    print(\"\\nAnalyzing sample soundscapes...\")\n    soundscape_path = os.path.join(BASE_PATH, 'train_soundscapes/H02_20230420_074000.ogg')\n    \n    if os.path.exists(soundscape_path):\n        try:\n            soundscape, sr = librosa.load(soundscape_path, sr=32000)\n            \n            plt.figure(figsize=(12, 8))\n            \n            # Waveform\n            plt.subplot(2, 1, 1)\n            librosa.display.waveshow(soundscape, sr=sr)\n            plt.title(\"Soundscape Waveform (Background Noise)\")\n            \n            # Spectrogram\n            plt.subplot(2, 1, 2)\n            S_soundscape = librosa.feature.melspectrogram(y=soundscape, sr=sr)\n            librosa.display.specshow(librosa.power_to_db(S_soundscape), \n                                   x_axis=\"time\", y_axis=\"mel\")\n            plt.colorbar(format='%+2.0f dB')\n            plt.title(\"Soundscape Spectrogram\")\n            \n            plt.tight_layout()\n            plt.savefig(os.path.join(output_dir, 'soundscape_analysis.png'))\n            plt.show()  # Grafiği göster\n            plt.close()\n            \n        except Exception as e:\n            print(f\"Soundscape analysis failed: {str(e)}\")\n    else:\n        print(\"Soundscape file not found\")\n\n# Main execution\nif __name__ == \"__main__\":\n    print(\"Starting BirdClef data visualization and analysis...\")\n    \n    # 1. Tür dağılımı\n    species_counts = analyze_species_distribution()\n    \n    # 2. YENİ ANALİZLER\n    analyze_collections()\n    analyze_taxonomy()\n    analyze_geographic_distribution() \n    analyze_secondary_labels()\n    analyze_quality_ratings()\n    analyze_authors_licenses()\n    analyze_audio_structure()\n    \n    # 3. Ses analizi\n    if not train_df.empty:\n        durations, species = analyze_audio_samples()\n    else:\n        print(\"Skipping audio analysis due to missing data\")\n    \n    # 4. Eski analizler\n    analyze_ratings()\n    analyze_locations()\n    analyze_soundscapes()\n    \n    # 5. Spectrogram analizi (şu an mevcut değil)\n    # spec_count, spec_samples = analyze_spectrograms()\n    # if spec_count:\n    #     print(f\"Analyzed {spec_count} spectrogram samples\")\n    \n    print(f\"\\nAll visualizations saved to: {output_dir}\") \n    print(\"\\n=== ANALYSIS SUMMARY ===\")\n    print(f\"✓ Species distribution analysis\")\n    print(f\"✓ Collection analysis (data sources)\")\n    print(f\"✓ Taxonomy analysis (Aves, Amphibia, Insecta, etc.)\")\n    print(f\"✓ Geographic distribution\")\n    print(f\"✓ Secondary labels analysis\")\n    print(f\"✓ Quality ratings analysis\")\n    print(f\"✓ Authors and licenses analysis\")\n    print(f\"✓ Audio file structure analysis\")\n    print(f\"✓ Audio samples analysis\")\n    # print(f\"✓ Spectrograms analysis\")  # Şu an mevcut değil\n    print(\"✓ Soundscapes analysis\")\n    print(\"✓ All visualizations saved to output directory\")\n    print(\"✓ All visualizations saved to output directory\")\n    print(\"✓ All visualizations saved to output directory\")\n    print(\"✓ All visualizations saved to output directory\")\n    print(\"✓ All visualizations saved to output directory\")\n    print(\"✓ All visualizations saved to output directory\")\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}