في عصرنا الرقمي الحالي، يجب على المحترفين في جميع الصناعات مواكبة الفعاليات القادمة، والمؤتمرات، والورش العمل. ومع ذلك، يشكل العثور بكفاءة على الأحداث التي تتناسب مع اهتمامات الشخص في بحر المعلومات الإلكترونية الواسعة الإمكانيات تحديًا كبيرًا.
يقدم هذا المدونة حلًا مبتكرًا لهذه المشكلة: تطبيق شامل مصمم لتجزئة البيانات المتعلقة بالأحداث من Facebook وتحليل البيانات المجزئة باستخدام MyScale. بينما يرتبط MyScale عادة بمكونات تكنولوجيا RAG أو يستخدم كقاعدة بيانات بأشكال متعددة، فإن قدراته تتجاوز هذه العوالم. سنستخدمه لتحليل البيانات، مستفيدين من وظيفة البحث الشعاعي لتحليل الأحداث التي تكون متماثلة سماويًا، مما يوفر نتائج ورؤى أفضل.
قد تلاحظ أن Grok AI استخدم قاعدة بيانات Qdrant بأشكال متعددة كمحرك بحث لاسترداد المعلومات الحية من بيانات X (سابقًا تعرف باسم Twitter). يمكنك أيضًا تقييم قوة قواعد البيانات بأشكال متعددة في هذا الطريق باستخدام MyScale من خلال دمج MyScale مع منصات أخرى مثل Apify لتعزيز مهام الحياة اليومية من خلال تطوير تطبيقات شخصية بسيطة.
لذا في هذه المدونة، دعونا نطور تطبيقًا يأخذ فقط اسم مدينة كمدخل ويجزئ جميع الأحداث ذات الصلة من Facebook. ثم سنجري تحليل البيانات والبحث السماوي باستخدام قدرات SQL المتقدمة لـ MyScale.
أدوات وتقنيات
سنستخدم عدة أدوات، بما في ذلك Apify و MyScale و OpenAI، لتطوير هذا التطبيق المفيد.
- Apify: منصة التنقيب عن البيانات والأتمتة الشهيرةالمتصفح التي تحسن بشكل كبير عملية جمع البيانات. توفر القدرة على قواص البيانات ومن ثم تغذيتها إلى نظم التعلم اللغوي العميق. هذا يتيح لنا تدريب نظم التعلم اللغوي العميق على بيانات الوقت الفعلي وتطوير التطبيقات.
- MyScale: MyScale هي قاعدة بيانات SQL في شكل متجه نستخدمها لتخزين ومعالجة البيانات المنظمة وغير المنظم بطريقة محسنة.
- OpenAI: سنستخدم نموذج
text-embedding-3-small
من OpenAI للحصول على إدخالات النص ومن ثم حفظ تلك الإدخالات في MyScale لتحليل البيانات والبحث الدلالي.
كيفية إعداد MyScale و Apify
لبدء إعداد MyScale و Apify، ستحتاج إلى إنشاء دليل جديد وملف بايثون. يمكنك القيام بذلك عن طريق فتح المحطة النصية أو سطر الأوامر وإدخال الأوامر التالية:
mkdir MyScale
cd MyScale
touch main.ipynb
لنقوم بتثبيت الحزم. انسخ الأمر التالي، والصقه في المحطة الخاصة بك. ستوفر هذه الحزم الأدوات والمكتبات التي نحتاجها لتطوير تطبيقنا.
pip install openai apify-client clickhouse-connect pandas numpy
هذا يجب أن يثبت جميع التبعيات في نظامك. للتأكد من تثبيت كل شيء بشكل صحيح، يمكنك إدخال الأمر التالي في المحطة.
pip freeze | egrep '(openai|apify-client|clickhouse-connect|pandas|numpy)'
يجب أن يشمل هذا جميع الوظائف المثبتة مع إصداراتها. إذا وجدت أي وظائف مفقودة، قد تحتاج إلى إعادة تشغيل أمر التثبيت لهذا الحزمة المحددة. الآن، نحن جاهزون لكتابة شفرتنا بعد التثبت.
ملاحظة: سنعمل في دفتر ملاحظات Python. ضع في اعتبارك كل كتلة شفرة وحدة ملاحظة.
كيفية جلب البيانات باستخدام Apify
الآن، سنستخدم واجهة برمجة التطبيقات Apify لجلب بيانات الأحداث في مدينة نيويورك باستخدام ماسح الأحداث الفيسبوك.
import pandas as pd
from apify_client import ApifyClient
# تهيئة ApifyClient برمز API الخاص بك
client = ApifyClient("Enter_your_apify_key_here")
# تحضير مدخلات الممثل
run_input = {
"searchQueries": ["Sport New York"],
"startUrls": [],
"maxEvents": 50,
}
# تشغيل الممثل وانتظار إكماله
run = client.actor("UZBnerCFBo5FgGouO").call(run_input=run_input)
df_columns = ['Name', 'Datetime', 'Description', 'Users_Going', 'Users_Interested', 'Users_Responded', 'City', 'Organized_By', 'Street_Address']
dataframe1 = pd.DataFrame(columns=df_columns)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
# استخدام تجميع قاموس لاستبدال قيم None بسلسلة فارغة
row = {
'Name': item.get('name', ''),
'Datetime': item.get('dateTimeSentence', ''),
'Description': item.get('description', ''),
'Users_Going': item.get('usersGoing', ''),
'Users_Interested': item.get('usersInterested', ''),
'Users_Responded': item.get('usersResponded', ''),
'City': item.get('location', {}).get('city', '') if item.get('location') else '',
'Organized_By': item.get('organizedBy', ''),
'Street_Address': item.get('location', {}).get('streetAddress', '') if item.get('location') else ''
}
# تأكد من استبدال جميع قيم None بسلسلة فارغة
row = {k: (v if v is not None else '') for k, v in row.items()}
dataframe1 = dataframe1._append(row, ignore_index=True)
# تنظيف البيانات
dataframe1['Description'] = dataframe1['Description'].replace('\\n', '', regex=True)
يعطينا هذا السطر بيانات تفاصيل الأحداث القادمة في شكل pandas
DataFrame.
ملاحظة: لا تنس إضافة تصنيف API الخاص بك في ال스크립ت أعلاه. يمكنك العثور على رمز API الخاص بك على صفحة التكاملات في وحدة تحكم Apify.
معالجة البيانات قبل التنفيذ
عندما نجمع البيانات الأولية، تأتي بأشكال مختلفة. في هذا السُّرب، سنجمع تواريخ الأحداث إلى تنسيق واحد بحيث يمكن أداء فلترة البيانات بكفاءة أكبر.
# استدعاء المكتبات الضرورية لمعالجة البيانات وتحليل التواريخ
import pandas as pd
import numpy as np
from datetime import datetime
from dateutil import parser
# تابع لتحليل سلاسل التواريخ التي قد تمثل نطاقًا أو تاريخًا واحدًا
def parse_dates(date_str):
# التحقق مما إذا كانت سلسلة التاريخ تحتوي على شرطة، مما يشير إلى نطاق
if '-' in date_str:
parts = date_str.split('-')
# إذا تم تقسيم السلسلة إلى جزأين، فهو نطاق صالح
if len(parts) == 2:
try:
# تحليل تواريخ البداية والنهاية، وتنسيقها إلى تنسيق قابل للقراءة
start_date = parser.parse(parts[0], fuzzy=True).strftime('%a, %b %d')
end_date = parser.parse(parts[1], fuzzy=True).strftime('%a, %b %d')
return start_date, end_date
except ValueError:
# في حالة حدوث خطأ في التحليل، لا تفعل شيئًا (سيتم التعامل معه أدناه)
pass
# إذا لم يكن نطاقًا أو إذا فشل تحليل النطاق، حاول تحليله كتاريخ واحد
try:
parsed_date = parser.parse(date_str, fuzzy=True)
# قم بتنسيق التاريخ الفردي لـ start_date وتنسيق مختلف لـ end_date
start_date = parsed_date.strftime('%a, %b %d AT %I:%M %p EDT')
end_date = parsed_date.strftime('%a, %b %d') # Omitting time for end_date
return start_date, end_date
except ValueError:
# إرجاع NaN لكل من التواريخ إذا فشل التحليل
return np.nan, np.nan
# تابع لاستخراج تفاصيل التاريخ والوقت واليوم من سلسلة التاريخ
def extract_date_time_day(date_str):
try:
# تحليل سلسلة التاريخ، مما يسمح ببعض المرونة في تنسيق الإدخال
parsed_date = parser.parse(date_str, fuzzy=True)
# استخراج وتنسيق أجزاء التاريخ والوقت واليوم
date = parsed_date.strftime('%Y-%m-%d')
day = parsed_date.strftime('%a')
# تحديد ما إذا كانت السلسلة الأصلية تشمل مكون الوقت
time_component = parsed_date.strftime('%I:%M %p') not in date_str
time = parsed_date.strftime('%H:%M:%S') if not time_component else np.nan
except ValueError:
# إذا فشل التحليل، اضبط التاريخ والوقت واليوم على NaN
date, time, day = np.nan, np.nan, np.nan
return date, time, day
# تطبيق وظيفة parse_dates عبر إسقاط البيانات، مما يخلق أعمدة جديدة للتواريخ البدئية والنهائية
dataframe1[['Start_Date', 'End_Date']] = dataframe1.apply(lambda row: pd.Series(parse_dates(row['Datetime'])), axis=1)
# حذف الصفوف حيث يكون Start_Date هو NaN، مما يشير إلى عدم نجاح التحليل
dataframe = dataframe1.dropna(subset=['Start_Date'])
# تطبيق extract_date_time_day لتقسيم تواريخ البداية والنهاية إلى أعمدة تاريخ ووقت ويوم منفصلة
dataframe['Start_Date'], dataframe['Start_Time'], dataframe['Start_Day'] = zip(*dataframe['Start_Date'].apply(extract_date_time_day))
dataframe['End_Date'], _, dataframe['End_Day'] = zip(*dataframe['End_Date'].apply(extract_date_time_day))
# إزالة العمود الأصلي 'Datetime' لأنه لم يعد ضروريًا
dataframe=dataframe.drop(['Datetime'], axis=1)
# تحويل 'Start_Date' و'End_Date' إلى تنسيق datetime، استخراج جزء التاريخ فقط
dataframe['Start_Date'] = pd.to_datetime(dataframe['Start_Date']).dt.date
dataframe['End_Date'] = pd.to_datetime(dataframe['End_Date']).dt.date
# تحويل 'Start_Time' إلى تنسيق datetime، والاحتفاظ بمعلومات الوقت
dataframe['Start_Time'] = pd.to_datetime(dataframe['Start_Time'])
يستخدم هذا المقطع من الكود pandas
مع حزم datetime
و dateutil
في Python لتنسيق البيانات.
توليد العلامات المصاحبة
لفهم والبحث في الأحداث بعمق، سنولد العلامات المصاحبة من وصف كل حدث باستخدام text-embedding-3-small
. تلتقط هذه العلامات المصاحبة الجوهر الدلالي لكل حدث، مما يسهم في إرجاع نتائج أفضل من قبل التطبيق.
# استيراد مكتبة OpenAI للوصول إلى واجهة البرمجة.
from openai import OpenAI
# تهيئة عميل OpenAI بمفتاح API.
openai_client = OpenAI(api_key="your_openai_api_key_here")
# وظيفة للحصول على العلامات المصاحبة للنصوص
def get_embedding(text, model="text-embedding-3-small"):
return openai_client.embeddings.create(input=text, model=model).data
embeddings = get_embedding(dataframe["Description"].tolist())
# استخراج متجهات العلامات المصاحبة من كائن العلامات المصاحبة
vectors = [embedding.embedding for embedding in embeddings]
array = np.array(vectors)
embeddings_series = pd.Series(list(array))
# إضافة العلامات المصاحبة كعمود جديد في الجدول الشيك.
dataframe['Description_Embeddings'] = embeddings_series
الآن، سنضيف الجدول الجديد DataFrame
مع العلامات المصاحبة إلى MyScale.
التواصل مع MyScale
كما ناقشنا في البداية، سنستخدم MyScale كقاعدة بيانات بمتجهات لتخزين وإدارة البيانات. هنا، سنتصل بـ MyScale في استعداد لتخزين البيانات.
import clickhouse_connect
client = clickhouse_connect.get_client(
host='host_name_here',
port=443,
username='username_here',
password='passwd_here'
)
هذا الإعداد للاتصال يضمن قدرة التطبيق على التواصل مع MyScale، واستخدام قوة SQL لمعالجة وتحليل البيانات.
ملاحظة: انظر تفاصيل الاتصال لمزيد من المعلومات حول كيفية الاتصال بمجموعة MyScale.
إنشاء الجداول والفهارس باستخدام MyScale
الآن سننشئ جدول وفقا لجدول البيانات الخاص بنا. ستتم تخزين جميع البيانات في هذا الجدول، بما في ذلك العلامات المصاحبة.
client.command("""
CREATE TABLE default.Events (
Name String,
Description String,
Users_Going Int64,
Users_Interested Int64,
Users_Responded Int64,
City String,
Organized_By String,
Street_Address String,
Start_Date Date32,
End_Date Nullable(Date32),
Start_Time Nullable(DateTime64),
Start_Day String,
End_Day String,
Description_Embeddings Array(Float32),
CONSTRAINT check_data_length CHECK length(Description_Embeddings) = 1536
) ENGINE = MergeTree()
ORDER BY (Name);
""")
تعد العبارات ال SQL المذكورة أعلاه إنشاء جدول يسمى Events
على العنقود. تضمن الـ CONSTRAINT
أن كل المتجهات المتضمنة لها نفس الطول 1536
.
تخزين البيانات وإنشاء فهرس في MyScale
في هذه الخطوة، نقوم بإدخال البيانات المعالجة في MyScale. وهذا يتضمن إدخال البيانات بالجر لضمان تخزين واسترجاع فعال.
batch_size = 10 # Adjust based on your needs
num_batches = len(dataframe) // batch_size
for i in range(num_batches):
start_idx = i * batch_size
end_idx = start_idx + batch_size
batch_data = dataframe[start_idx:end_idx]
# print(batch_data["Description_Embeddings"])
client.insert("default.Events", batch_data.to_records(index=False).tolist(), column_names=batch_data.columns.tolist())
print(f"Batch {i+1}/{num_batches} inserted.")
client.command("""
ALTER TABLE default.Events
ADD VECTOR INDEX vector_index Description_Embeddings
TYPE MSTG
""")
باستخدام pandas
، ينقل الكود المذكور أعلاه مجموعتنا البيانات المعدة فعالًا إلى قاعدة البيانات MyScale.
تحليل البيانات باستخدام MyScale
أخيرًا، نستخدم قدرات MyScale التحليلية لإجراء التحليل وتمكين البحث الدلالي. من خلال تنفيذ عبارات SQL، يمكننا تحليل الأحداث حسب الموضوعات والمواقع والتواريخ. لذا، دعونا نحاول كتابة بعض الاستعلامات.
استعلام SQL بسيط
دعونا نحاول أولاً الحصول على أفضل 10 نتائج من الجدول.
results=client.query("""
SELECT Name,Description FROM default.Events LIMIT 10
""")
for row in results.named_results():
print(row["Name"])
print(row['Description'])
سيعيد هذا الاستعلام ببساطة أفضل 10 نتائج من جدول events
.
اكتشاف الأحداث حسب العلاقة الدلالية
دعونا نحاول العثور على أفضل 10 أحداث قادمة بنفس المزاج للحدث المرجعي، مثل هذا: “أحد أطول العروض الممتدة في البلاد – تعمل منذ عام 1974 … الآن في سنتنا الخامسين !!! من سكانكتادي”. ويتم ذلك من خلال مقارنة التضمين الدلالي لوصف الأحداث، مؤكدين الشبه في الموضوعات والمشاعر.
embeddings=get_embedding(["One of the Longest Running Shows in the Country - Operating since 1974 ...NOW our 50th YEAR !!!Our Schenectady"])
embedding=embeddings[0].embedding
results = client.query(f"""
SELECT Name, Description,
distance(Description_Embeddings, {embedding}) as dist FROM default.Events ORDER BY dist LIMIT 10
""")
for row in results.named_results():
print("Title of the event ", row["Name"])
print("Description of the event ", row['Description'])
print("Distance : ", row["dist"])
الأحداث الشهيرة حسب الشعبية
هذا الاستعلام يصنف أعلى 10 أحداث حسب عدد الحضور والمستخدمين المهتمين، مما يسلط الضوء على الأحداث الشهيرة من مهرجانات المدن الكبيرة إلى المؤتمرات الكبرى. إنه المثالي لمن يسعى للانضمام إلى التجمعات الكبيرة والنشطة.
results = client.query(f"""
SELECT Name, City, Users_Going, Users_Interested, Users_Responded
FROM default.Events
ORDER BY Users_Going DESC, Users_Interested DESC
LIMIT 10
""")
for row in results.named_results():
print("Event Name ", row["Name"])
print("City ", row["City"])
print("Users Going ", row["Users_Going"])
print("Interested Users ", row["Users_Interested"])
الأحداث المحلية الشهيرة في نيويورك
بجمع الأهمية والشهرة، يحدد هذا الاستعلام أحداث مماثلة في مدينة نيويورك ذات الصلة بحدث معين ويصنفها حسب الحضور، مما يقدم قائمة مستخرجة من الأحداث التي تعكس الثقافة الحية في المدينة وتجذب الاهتمام المحلي.
embeddings=get_embedding(["One of the Longest Running Shows in the Country - Operating since 1974 ...NOW our 50th YEAR !!!Our Schenectady"])
embeddi=embeddings[0].embedding
results = client.query(f"""
SELECT Name,City, Description, Users_Going,distance(Description_Embeddings, {embeddi}) as dist
FROM default.Events
WHERE City LIKE '%New York%' and dist < 1.5
ORDER BY Users_Going DESC,dist
LIMIT 10
""")
for row in results.named_results():
print("Event Name ", row["Name"])
print("Description ", row["Description"])
print("Users Going ", row["Users_Going"])
منظمو الأحداث الرائدون
هذا الاستعلام يصنف أفضل 10 منظمين للأحداث حسب العدد الإجمالي للحضور والمستخدمين المهتمين، مما يبرز أولئك الذين يتفوقون في إنشاء الأحداث الجذابة وجذب الجماهير الكبيرة. يوفر رؤى لمخططي الأحداث والحضور المهتمين بالأحداث الأولى.
# أي عميل جذب أكبر عدد من المستخدمين
results = client.query(f"""
SELECT Organized_By, SUM(Users_Going + Users_Interested) AS Total_Users
FROM default.Events
GROUP BY Organized_By
ORDER BY Total_Users DESC
Limit 10
""")
for row in results.named_results():
print("Event Name ", row["Organized_By"])
print("Total_Users ", row["Total_Users"])
تنفيذ RAG
كان لدينا سابقاً استكشاف MyScale لتحليل البيانات، مما أظهر قدراته في تعزيز سير عملنا في البيانات. بالمضي قدماً، سنتابع خطوة إضافية من خلال تنفيذ Retrieval-Augmented Generation (RAG)، إطار عمل مبتكر يجمع بين قاعدة علم خارجية مع LLMs. ستساعدك هذه الخطوة على فهم بياناتك بشكل أفضل واكتشاف رؤى أكثر تفصيلاً. بعد ذلك، سترى كيفية استخدام RAG مع MyScale، مما سيجعل العمل مع البيانات أكثر إثارة وإنتاجية.
from langchain.chat_models import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
query="Can you please suggest me some events related to basketball"
# استخدم طريقة get_embedding المعرفة فيما سبق، والتي تقبل قائمة من الجمل
embeddings=get_embedding([query])
embeddings=embeddings[0].embedding
results = client.query(f"""
SELECT Name, City, Users_Going, Description, distance(Description_Embeddings, {embeddings}) as dist
FROM default.Events
ORDER BY Users_Going DESC,dist
LIMIT 5
""")
PROMPT_TEMPLATE = """
Your objective is to formulate a response to a question using only the information provided below:
{context}
---
Your task is to carefully analyze the provided context and provide an answer to the following question based solely on the information given:
{question}
"""
# اجمع وصف النتائج العليا.
descriptions = [row["Description"] for row in results.named_results()]
context_text = "\n\n---\n\n".join(descriptions)
prompt_template = ChatPromptTemplate.from_template(PROMPT_TEMPLATE)
prompt = prompt_template.format(context=context_text, question=query)
model = ChatOpenAI(openai_api_key="your_api_key_here")
response_text = model.predict(prompt)
formatted_response = f"Response: {response_text}\n"
print(formatted_response)
خلال هذا المقال، لاحظنا أن MyScale هو أكثر من مجرد قاعدة بيانات بُعدية يمكن استخدامها لتطوير جميع أنواع التطبيقات. يمكننا استخدامه كقاعدة بيانات SQL بسيطة أو للتطبيقات الذكية عالية المستوى، مما يغطي غالبية مجال التطوير. نشجعك على التجربة واستكشاف الميزات المتقدمة عن طريق التسجيل في الطلبة المجانية والحصول على تخزين بُعدي مجاني بقيمة 5 ملايين.
الخاتمة
لقد استكشفنا قدرات ووظائف MyScale مع Apify Scraper من خلال عملية تطوير تطبيق تحليل الأحداث. أظهرت MyScale قدراتها الاستثنائية في البحث البُعدي عالي الأداء بينما تحتفظ جميع وظائف قواعد البيانات SQL، مما يساعد المطورين على إجراء عمليات بحث معنوية باستخدام بناء جملة SQL المألوف بشكل أفضل من حيث السرعة والدقة.
قدرات MyScale ليست محدودة لهذا التطبيق فقط: يمكنك اعتمادها لتطوير أي تطبيقات AI باستخدام طريقة RAG.
إذا كان لديك أي تعليقات أو اقتراحات، يرجى التواصل معنا.
Source:
https://dzone.com/articles/performing-advanced-facebook-event-data-analysis-w