# app.py import pandas as pd from transformers import pipeline import gradio as gr import numpy as np import os from PIL import Image # Görüntü işleme için Pillow kütüphanesi # 1. Kaggle Veri Setini Yükle (Örnek bir Spotify veri seti kullanacağız) DATA_URL = "https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2020/2020-01-21/spotify_songs.csv" DATA_PATH = "spotify_songs.csv" print("Veri seti indiriliyor...") try: if not os.path.exists(DATA_PATH): import requests response = requests.get(DATA_URL) response.raise_for_status() with open(DATA_PATH, 'wb') as f: f.write(response.content) print(f"Veri seti {DATA_PATH} konumuna başarıyla indirildi.") else: print(f"Veri seti {DATA_PATH} zaten mevcut, indirme atlandı.") df = pd.read_csv(DATA_PATH) df = df[['track_name', 'track_artist', 'playlist_genre', 'valence', 'energy', 'tempo', 'danceability']] df = df.dropna() df = df.drop_duplicates(subset=['track_name', 'track_artist']) df = df.rename(columns={'playlist_genre': 'genre', 'track_name': 'name', 'track_artist': 'artist'}) print("Veri seti başarıyla yüklendi ve işlendi. Toplam şarkı sayısı:", len(df)) except Exception as e: print(f"Veri seti yüklenirken veya işlenirken bir hata oluştu: {e}") print("Lütfen alternatif bir CSV dosyası deneyin veya manuel yükleyin.") df = pd.DataFrame(columns=['name', 'artist', 'genre', 'valence', 'energy', 'tempo', 'danceability']) # 2. Hugging Face Duygu Analizi Modeli Yükle (Metin için) print("\nHugging Face duygu analizi modeli yükleniyor (Metin için)...") sentiment_analyzer = pipeline("sentiment-analysis", model="distilbert-base-uncased-finetuned-sst-2-english") print("Metin duygu modeli yüklendi.") # 3. Hugging Face Görüntü Sınıflandırma Modeli Yükle (Görsel için) # Bu model, sıfır atışlı görüntü sınıflandırma için kullanılır (yani önceden eğitilmemiş etiketlerle bile çalışır) print("\nHugging Face sıfır-atış görüntü sınıflandırma modeli yükleniyor (Görsel için)...") image_classifier = pipeline("zero-shot-image-classification", model="openai/clip-vit-base-patch32") print("Görüntü sınıflandırma modeli yüklendi.") # Görüntü sınıflandırma için aday etiketler (bu etiketler müzik ruh halleriyle ilişkilendirilecek) candidate_image_labels = [ "happy photo", "sad photo", "energetic photo", "calm photo", "romantic photo", "mysterious photo", "party photo", "nature scene", "city scene", "travel photo", "food photo", "work photo", "bright photo", "dark photo", "warm colors", "cool colors", "adventure", "relaxation", "celebration", "reflection", "serenity" ] # 4. Duygu ve Enerji Aralığı Tanımları mood_mappings = { "Mutlu ve Coşkulu": {"valence": [0.7, 1.0], "energy": [0.7, 1.0]}, "Hüzünlü ve Melankolik": {"valence": [0.0, 0.3], "energy": [0.0, 0.4]}, "Sakin ve Huzurlu": {"valence": [0.5, 0.8], "energy": [0.2, 0.6]}, "Enerjik ve Canlı": {"valence": [0.6, 1.0], "energy": [0.8, 1.0]}, "Gergin ve Dramatik": {"valence": [0.2, 0.5], "energy": [0.6, 0.9]}, "Romantik ve Duygusal": {"valence": [0.6, 0.9], "energy": [0.3, 0.7]}, "Gizemli ve Derin": {"valence": [0.3, 0.6], "energy": [0.4, 0.7]}, "Parti ve Eğlence": {"valence": [0.7, 1.0], "energy": [0.8, 1.0]}, "Odaklanma ve Çalışma": {"valence": [0.4, 0.7], "energy": [0.3, 0.6]}, "Seyahat ve Keşif": {"valence": [0.6, 0.9], "energy": [0.6, 0.9]}, } available_genres = df['genre'].unique().tolist() available_genres.sort() # 5. Şarkı Önerme Fonksiyonu def get_song_recommendations(story_text, uploaded_image, selected_mood, selected_genre, num_recommendations=5): if df.empty: return "Veri seti yüklenemediği için öneri yapılamıyor. Lütfen kontrol edin." # ----- Metin Duygu Analizi ----- text_sentiment_score = 0.5 # Varsayılan nötr if story_text: try: sentiment_result = sentiment_analyzer(story_text)[0] text_sentiment_score = sentiment_result['score'] if sentiment_result['label'] == 'POSITIVE' else (1 - sentiment_result['score']) except Exception as e: print(f"Metin duygu analizi sırasında hata oluştu: {e}. Varsayılan nötr duygu atanıyor.") # ----- Görsel Analizi ----- image_valence_adjustment = 0 image_energy_adjustment = 0 if uploaded_image is not None: try: print("Görsel analizi yapılıyor...") # Gradio'dan gelen görsel PIL Image objesi olarak gelir. image_results = image_classifier(images=uploaded_image, candidate_labels=candidate_image_labels) print(f"Görsel analiz sonuçları: {image_results}") # Basit bir şekilde görsel sonuçları valence/energy'ye yansıtma # Daha sofistike bir mapping yapılabilir. for res in image_results: label = res['label'] score = res['score'] if score > 0.6: # Yüksek güvenli tahminleri kullan if "happy photo" in label or "bright photo" in label or "celebration" in label: image_valence_adjustment += 0.1 * score image_energy_adjustment += 0.05 * score elif "sad photo" in label or "dark photo" in label or "reflection" in label: image_valence_adjustment -= 0.1 * score image_energy_adjustment -= 0.05 * score elif "energetic photo" in label or "party photo" in label or "city scene" in label or "adventure" in label: image_energy_adjustment += 0.1 * score elif "calm photo" in label or "nature scene" in label or "relaxation" in label or "serenity" in label: image_energy_adjustment -= 0.05 * score image_valence_adjustment += 0.03 * score # Hafif pozitiflik elif "romantic photo" in label: image_valence_adjustment += 0.05 * score image_energy_adjustment -= 0.03 * score except Exception as e: print(f"Görsel analizi sırasında hata oluştu: {e}. Görsel analizi atlanıyor.") # ----- Hedef Valence ve Energy Aralığı Belirleme ----- target_valence_range = list(mood_mappings[selected_mood]["valence"]) target_energy_range = list(mood_mappings[selected_mood]["energy"]) # Metin duygu sentimentini valence aralığına dahil edelim. text_sentiment_adjustment = (text_sentiment_score - 0.5) * 0.4 # -0.2 ile +0.2 arasında ayarlama target_valence_range[0] = max(0, target_valence_range[0] + text_sentiment_adjustment) target_valence_range[1] = min(1, target_valence_range[1] + text_sentiment_adjustment) # Görsel duygu adjustment'ını uygulayalım target_valence_range[0] = max(0, target_valence_range[0] + image_valence_adjustment) target_valence_range[1] = min(1, target_valence_range[1] + image_valence_adjustment) target_energy_range[0] = max(0, target_energy_range[0] + image_energy_adjustment) target_energy_range[1] = min(1, target_energy_range[1] + image_energy_adjustment) # Aralıkları 0-1 arasında tut target_valence_range = [min(1, max(0, tv)) for tv in target_valence_range] target_energy_range = [min(1, max(0, te)) for te in target_energy_range] #print(f"Nihai Hedef Valence Aralığı: {target_valence_range}, Nihai Hedef Energy Aralığı: {target_energy_range}") # ----- Filtreleme ve Puanlama ----- filtered_songs = df[df['genre'] == selected_genre].copy() if filtered_songs.empty: return f"'{selected_genre}' türünde şarkı bulunamadı. Lütfen başka bir tür seçin." filtered_songs['valence_diff'] = filtered_songs['valence'].apply( lambda x: min(abs(x - target_valence_range[0]), abs(x - target_valence_range[1])) ) filtered_songs['energy_diff'] = filtered_songs['energy'].apply( lambda x: min(abs(x - target_energy_range[0]), abs(x - target_energy_range[1])) ) filtered_songs['fit_score'] = 1 / (filtered_songs['valence_diff'] + filtered_songs['energy_diff'] + 0.01) recommended_songs = filtered_songs.sort_values(by='fit_score', ascending=False).head(num_recommendations) if recommended_songs.empty: return "Seçimlerinize uygun şarkı bulunamadı. Daha geniş kriterler deneyin." results = [] for index, row in recommended_songs.iterrows(): results.append(f"• {row['name']} - {row['artist']} ({row['genre']})") return "\n".join(results) # 6. Gradio Arayüzü Oluştur print("\nGradio arayüzü başlatılıyor...") iface = gr.Interface( fn=get_song_recommendations, inputs=[ gr.Textbox(lines=3, placeholder="Instagram hikayenizi buraya yazın (örneğin: 'Gün batımında sahilde yürüyorum, huzur veren bir an')", label="Hikaye Metni (İsteğe Bağlı)"), gr.Image(type="pil", label="Hikaye Görseli (İsteğe Bağlı, JPG/PNG)"), # Yeni görsel girdi gr.Dropdown(list(mood_mappings.keys()), label="Hikayenin Ruh Hali"), gr.Dropdown(available_genres, label="Müzik Türü"), ], outputs=gr.Textbox(label="Önerilen Şarkılar", lines=5), title="🌟 Akıllı Hikaye Müzik Önerici (Görsel ve Metin Analizli) 🌟", description="Hikaye metninizi ve/veya görselinizi yükleyerek, ayrıca ruh hali ve müzik türü seçerek Instagram hikayeniz için mükemmel şarkı önerileri alın. Öneriler Kaggle veri seti ve Hugging Face NLP/Görsel analiz ile güçlendirilmiştir.", allow_flagging="never" ) iface.launch(share=False)