chalet_jornal / audience_targeting.py
Medon90ae's picture
Update audience_targeting.py
cd3d5ae verified
import pandas as pd
import numpy as np
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt
import seaborn as sns
import os
from collections import Counter
def create_audience_segments(audience_data):
"""
إنشاء شرائح الجمهور باستخدام التعلم الآلي
"""
try:
# تحويل البيانات إلى DataFrame
if not isinstance(audience_data, pd.DataFrame):
audience_data = pd.DataFrame(audience_data)
# التحقق من وجود بيانات
if audience_data.empty:
print("بيانات الجمهور فارغة")
return None
# تحديد الميزات الرقمية للتصنيف
numeric_features = []
for col in ['booking_frequency', 'avg_stay_duration', 'price_sensitivity', 'response_rate']:
if col in audience_data.columns:
numeric_features.append(col)
# التحقق من وجود ميزات كافية
if not numeric_features:
print("لا توجد ميزات رقمية كافية للتصنيف")
return None
# استخراج الميزات الرقمية
X = audience_data[numeric_features].values
# تطبيع البيانات
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# تحديد عدد المجموعات المثالي (يمكن تحسينه باستخدام طريقة Elbow)
n_clusters = min(4, len(audience_data))
# استخدام K-means للتصنيف
kmeans = KMeans(n_clusters=n_clusters, random_state=42)
clusters = kmeans.fit_predict(X_scaled)
# إضافة معرفات المجموعات إلى البيانات الأصلية
audience_data['cluster'] = clusters
return {
'segmented_data': audience_data,
'kmeans_model': kmeans,
'scaler': scaler,
'features': numeric_features
}
except Exception as e:
print(f"خطأ في إنشاء شرائح الجمهور: {str(e)}")
return None
def analyze_audience_segments(segmented_data):
"""
تحليل شرائح الجمهور وإرجاع خصائص كل شريحة
"""
try:
# التحقق من وجود بيانات
if not isinstance(segmented_data, pd.DataFrame) or 'cluster' not in segmented_data.columns:
print("البيانات غير صالحة للتحليل")
return {}
segments = {}
for cluster_id in segmented_data['cluster'].unique():
cluster_data = segmented_data[segmented_data['cluster'] == cluster_id]
# تحليل خصائص الشريحة
segment_profile = {
'size': len(cluster_data),
'avg_booking_frequency': cluster_data['booking_frequency'].mean() if 'booking_frequency' in cluster_data.columns else 0,
'avg_stay_duration': cluster_data['avg_stay_duration'].mean() if 'avg_stay_duration' in cluster_data.columns else 0,
'price_sensitivity': cluster_data['price_sensitivity'].mean() if 'price_sensitivity' in cluster_data.columns else 0,
'response_rate': cluster_data['response_rate'].mean() if 'response_rate' in cluster_data.columns else 0
}
# إضافة توزيع الفئات العمرية إذا كانت موجودة
if 'age_range' in cluster_data.columns:
segment_profile['age_distribution'] = cluster_data['age_range'].value_counts().to_dict()
# إضافة توزيع الحالة العائلية إذا كانت موجودة
if 'family_status' in cluster_data.columns:
segment_profile['family_status_distribution'] = cluster_data['family_status'].value_counts().to_dict()
# إضافة توزيع الاهتمامات إذا كانت موجودة
if 'interests' in cluster_data.columns:
all_interests = []
for interests_str in cluster_data['interests']:
if isinstance(interests_str, str):
interests = [i.strip() for i in interests_str.split(',')]
all_interests.extend(interests)
interest_counts = Counter(all_interests)
# ترتيب الاهتمامات حسب الشيوع
sorted_interests = sorted(interest_counts.items(), key=lambda x: x[1], reverse=True)
segment_profile['top_interests'] = {k: v for k, v in sorted_interests[:5]} if sorted_interests else {}
segments[f'Segment {cluster_id}'] = segment_profile
return segments
except Exception as e:
print(f"خطأ في تحليل شرائح الجمهور: {str(e)}")
return {}
def create_segment_visualization(segmented_data, features):
"""
إنشاء رسوم بيانية لتوضيح شرائح الجمهور
"""
try:
# التحقق من وجود بيانات
if not isinstance(segmented_data, pd.DataFrame) or 'cluster' not in segmented_data.columns:
print("البيانات غير صالحة للتصور")
fig, ax = plt.subplots(figsize=(8, 6))
ax.text(0.5, 0.5, 'لا توجد بيانات كافية لإنشاء الرسوم البيانية',
horizontalalignment='center', verticalalignment='center', transform=ax.transAxes)
return fig
# التحقق من وجود الميزات
valid_features = [f for f in features if f in segmented_data.columns]
if len(valid_features) < 2:
print("لا توجد ميزات كافية للتصور")
fig, ax = plt.subplots(figsize=(8, 6))
ax.text(0.5, 0.5, 'لا توجد ميزات كافية لإنشاء الرسوم البيانية',
horizontalalignment='center', verticalalignment='center', transform=ax.transAxes)
return fig
# إنشاء الرسوم البيانية
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
# تعيين نمط الخط لدعم اللغة العربية
plt.rcParams['font.family'] = 'Arial'
# رسم توزيع تكرار الحجز حسب الشريحة
if 'booking_frequency' in valid_features:
sns.boxplot(x='cluster', y='booking_frequency', data=segmented_data, ax=axes[0, 0])
axes[0, 0].set_title('توزيع تكرار الحجز حسب الشريحة')
axes[0, 0].set_ylabel('تكرار الحجز')
axes[0, 0].set_xlabel('الشريحة')
else:
axes[0, 0].text(0.5, 0.5, 'لا توجد بيانات لتكرار الحجز',
horizontalalignment='center', verticalalignment='center', transform=axes[0, 0].transAxes)
# رسم توزيع مدة الإقامة حسب الشريحة
if 'avg_stay_duration' in valid_features:
sns.boxplot(x='cluster', y='avg_stay_duration', data=segmented_data, ax=axes[0, 1])
axes[0, 1].set_title('توزيع مدة الإقامة حسب الشريحة')
axes[0, 1].set_ylabel('متوسط مدة الإقامة (أيام)')
axes[0, 1].set_xlabel('الشريحة')
else:
axes[0, 1].text(0.5, 0.5, 'لا توجد بيانات لمدة الإقامة',
horizontalalignment='center', verticalalignment='center', transform=axes[0, 1].transAxes)
# رسم توزيع حساسية السعر حسب الشريحة
if 'price_sensitivity' in valid_features:
sns.boxplot(x='cluster', y='price_sensitivity', data=segmented_data, ax=axes[1, 0])
axes[1, 0].set_title('توزيع حساسية السعر حسب الشريحة')
axes[1, 0].set_ylabel('حساسية السعر (0-1)')
axes[1, 0].set_xlabel('الشريحة')
else:
axes[1, 0].text(0.5, 0.5, 'لا توجد بيانات لحساسية السعر',
horizontalalignment='center', verticalalignment='center', transform=axes[1, 0].transAxes)
# رسم توزيع معدل الاستجابة حسب الشريحة
if 'response_rate' in valid_features:
sns.boxplot(x='cluster', y='response_rate', data=segmented_data, ax=axes[1, 1])
axes[1, 1].set_title('توزيع معدل الاستجابة حسب الشريحة')
axes[1, 1].set_ylabel('معدل الاستجابة')
axes[1, 1].set_xlabel('الشريحة')
else:
axes[1, 1].text(0.5, 0.5, 'لا توجد بيانات لمعدل الاستجابة',
horizontalalignment='center', verticalalignment='center', transform=axes[1, 1].transAxes)
plt.tight_layout()
return fig
except Exception as e:
print(f"خطأ في إنشاء الرسوم البيانية: {str(e)}")
fig, ax = plt.subplots(figsize=(8, 6))
ax.text(0.5, 0.5, f'خطأ في إنشاء الرسوم البيانية: {str(e)}',
horizontalalignment='center', verticalalignment='center', transform=ax.transAxes)
return fig
def generate_targeted_content(chalet_data, segment_profile):
"""
توليد محتوى مستهدف بناءً على ملف تعريف الشريحة
"""
try:
# التحقق من وجود بيانات
if not isinstance(chalet_data, dict) or not isinstance(segment_profile, dict):
print("البيانات غير صالحة لتوليد المحتوى")
return {}
content_recommendations = {}
# تحديد نوع المحتوى المناسب
if 'price_sensitivity' in segment_profile and segment_profile['price_sensitivity'] > 0.7:
content_recommendations['content_type'] = 'قيمة وتوفير'
content_recommendations['key_messages'] = [
f"قيمة استثنائية في {chalet_data.get('location', 'الموقع')}",
"أسعار تنافسية مع خدمات ممتازة",
"عروض خاصة للإقامات الطويلة"
]
elif 'avg_stay_duration' in segment_profile and segment_profile['avg_stay_duration'] > 5:
content_recommendations['content_type'] = 'إقامة طويلة'
content_recommendations['key_messages'] = [
f"استمتع بإقامة مريحة وطويلة في {chalet_data.get('name', 'الشاليه')}",
"مرافق متكاملة للإقامات الطويلة",
"خصومات خاصة للإقامات الأسبوعية والشهرية"
]
elif 'top_interests' in segment_profile and any(interest in str(segment_profile['top_interests']).lower() for interest in ['عائلة', 'أطفال', 'family']):
content_recommendations['content_type'] = 'عائلي'
content_recommendations['key_messages'] = [
f"عطلة عائلية مثالية في {chalet_data.get('name', 'الشاليه')}",
"أنشطة ترفيهية للأطفال والكبار",
"مساحات آمنة ومريحة للعائلات"
]
else:
content_recommendations['content_type'] = 'فاخر'
content_recommendations['key_messages'] = [
f"تجربة فاخرة في {chalet_data.get('name', 'الشاليه')}",
"مرافق حصرية ومميزة",
"خدمة شخصية على أعلى مستوى"
]
# تحديد الصور المناسبة
if content_recommendations['content_type'] == 'عائلي':
content_recommendations['image_focus'] = ['مساحات عائلية', 'ملاعب أطفال', 'مسبح آمن']
elif content_recommendations['content_type'] == 'فاخر':
content_recommendations['image_focus'] = ['تصميم داخلي فاخر', 'إطلالة مميزة', 'مرافق حصرية']
elif content_recommendations['content_type'] == 'قيمة وتوفير':
content_recommendations['image_focus'] = ['المرافق الأساسية', 'المساحات المشتركة', 'موقع مميز']
else:
content_recommendations['image_focus'] = ['المساحات الواسعة', 'المطبخ المجهز', 'مناطق العمل']
# تحديد قنوات التسويق المناسبة
if 'response_rate' in segment_profile and segment_profile['response_rate'] > 0.15:
content_recommendations['marketing_channels'] = ['إعلانات فيسبوك', 'إنستغرام', 'البريد الإلكتروني']
else:
content_recommendations['marketing_channels'] = ['منصات حجز السفر', 'جوجل', 'مواقع المراجعات']
return content_recommendations
except Exception as e:
print(f"خطأ في توليد المحتوى المستهدف: {str(e)}")
return {}
def load_audience_data_from_file(file_path):
"""
تحميل بيانات الجمهور من ملف
"""
try:
if not os.path.exists(file_path):
print(f"الملف {file_path} غير موجود")
return pd.DataFrame()
# تحديد نوع الملف
if file_path.endswith('.csv'):
df = pd.read_csv(file_path)
elif file_path.endswith('.xlsx'):
df = pd.read_excel(file_path)
else:
print(f"نوع الملف غير مدعوم: {file_path}")
return pd.DataFrame()
return df
except Exception as e:
print(f"خطأ في تحميل بيانات الجمهور: {str(e)}")
return pd.DataFrame()
def save_audience_segments(segmented_data, file_path):
"""
حفظ شرائح الجمهور في ملف
"""
try:
# التحقق من وجود بيانات
if not isinstance(segmented_data, pd.DataFrame) or segmented_data.empty:
print("البيانات فارغة أو غير صالحة")
return False
# تحديد نوع الملف
if file_path.endswith('.csv'):
segmented_data.to_csv(file_path, index=False)
elif file_path.endswith('.xlsx'):
segmented_data.to_excel(file_path, index=False)
else:
print(f"نوع الملف غير مدعوم: {file_path}")
return False
return True
except Exception as e:
print(f"خطأ في حفظ شرائح الجمهور: {str(e)}")
return False
def extract_audience_from_bookings(bookings_data):
"""
استخراج بيانات الجمهور من بيانات الحجوزات
"""
try:
# التحقق من وجود بيانات
if not isinstance(bookings_data, pd.DataFrame) or bookings_data.empty:
print("بيانات الحجوزات فارغة أو غير صالحة")
return pd.DataFrame()
# código existente...
# Aquí está el problema, la función termina abruptamente
bookings
# Debe completarse con algo como:
return audience_data
except Exception as e:
print(f"خطأ في استخراج بيانات الجمهور: {str(e)}")
return pd.DataFrame()