<?xml version="1.0"?>
<rss version="2.0"><channel><title>&#x627;&#x644;&#x628;&#x631;&#x645;&#x62C;&#x629;: &#x630;&#x643;&#x627;&#x621; &#x627;&#x635;&#x637;&#x646;&#x627;&#x639;&#x64A;</title><link>https://academy.hsoub.com/programming/artificial-intelligence/?d=2</link><description>&#x627;&#x644;&#x628;&#x631;&#x645;&#x62C;&#x629;: &#x630;&#x643;&#x627;&#x621; &#x627;&#x635;&#x637;&#x646;&#x627;&#x639;&#x64A;</description><language>ar</language><item><title>&#x62A;&#x639;&#x631;&#x641; &#x639;&#x644;&#x649; &#x645;&#x641;&#x647;&#x648;&#x645;  Vibe Coding &#x648;&#x627;&#x633;&#x62A;&#x641;&#x62F; &#x645;&#x646;&#x647; &#x641;&#x64A; &#x628;&#x646;&#x627;&#x621; &#x627;&#x644;&#x62A;&#x637;&#x628;&#x64A;&#x642;&#x627;&#x62A;</title><link>https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D9%85%D9%81%D9%87%D9%88%D9%85-vibe-coding-%D9%88%D8%A7%D8%B3%D8%AA%D9%81%D8%AF-%D9%85%D9%86%D9%87-%D9%81%D9%8A-%D8%A8%D9%86%D8%A7%D8%A1-%D8%A7%D9%84%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-r2609/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2026_04/vibe.png.478a523e6d0b76b5e2c68b0278a5eedd.png" /></p>
<p>
	يبدو أننا نشهد عصرًا جديد من البرمجة ستمكننا جميعًا من إطلاق العنان لإبداعنا وصناعة ما يحلو لنا من مواقع وتطبيقات دون أن نحتاج لامتلاك معرفة تقنية واسعة ونضطر لكتابة الكثير من الأكواد البرمجية لنتفاهم مع الحواسيب ونطلب منها تنفيذ ما نريده. فالمعادلة بدأت تتغير بوتيرة متسارعة مع انتشار تقنيات الذكاء الاصطناعي المساعدة في البرمجة ومن أحدثها مفهوم فايب كودينغ Vibe Coding الذي أتاح لنا التعبير عن أفكارنا بلغة طبيعية وتحويلها لتطبيقات تعمل بمنتهى السهولة.
</p>

<p>
	فهل هذه الثورة التقنية في مجال الذكاء الاصطناعي ستساعد المبرمجين بالفعل أم ستستبدلهم بالكامل، وهل تصلح منهجية Vibe Coding لتطوير كافة أنواع التطبيقات أم أنها تصلح لأنواع دون أخرى؟ دعونا نناقش معًا هذا المفهوم الرائج ونتعرف على أهم أدواته ومنصاته ونطبقه عمليًا لتطوير تطبيق ويب متكامل يتيح لنا تقييم المعالم الأثرية في الوطن العربي لنكتشف من خلال التجربة إمكانياته ومحدودياته، وكيف يمكن للمبرمجين والمستخدمين العاديين الذين لا يملكون خبرات برمجية كبيرة الاستفادة منه بالشكل الأمثل.
</p>

<h2 id="-vibe-coding-">
	ما هو Vibe Coding؟
</h2>

<p>
	إن مصطلح فايب كودينج Vibe Coding هو اتجاه حديث في تطوير البرمجيات طرحه لأول مرة عالم الحاسوب <a href="https://en.wikipedia.org/wiki/Andrej_Karpathy" rel="external nofollow">أندريه كارباثي Andrej Karpathy</a>، أحد المؤسسين المشاركين في شركة OpenAI والمدير السابق لفريق الذكاء الاصطناعي في تسلا يشير إلى أسلوب برمجة يعتمد على النماذج اللغوية الكبيرة LLMs، حيث يصف المطوّر التطبيق المطلوب بلغة طبيعية، ويتولى الذكاء الاصطناعي توليد الكود البرمجي لهذا التطبيق.
</p>

<p>
	يساهم هذا الأسلوب في تسهيل <a href="https://academy.hsoub.com/programming/general/%D8%A8%D8%B1%D9%85%D8%AC%D8%A9-%D8%A7%D9%84%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA/" rel="">برمجة التطبيقات</a> حيث يوفر منصات أو أطر عمل متكاملة تعتمد على وكلاء الذكاء الاصطناعي وتتيح لنا تنفيذ كافة المهام البرمجية المطلوبة بداية من تخطيط بنية التطبيق ثم كتابة أكواده البرمجية وصولًا إلى نشره وتصحيح أخطائه وتحسين مخرجاته، باستمرار كل ذلك من خلال التحاور التفاعلي مع الوكيل الذكي.
</p>

<p>
	لا يقتصر أسلوب Vibe Coding على إرسال موجه واحد prompt وانتظار النتيجة، بل يوفر إطارًا تفاعليًا متكاملًا يسمح لنا بالتواصل المستمر مع وكيل الذكاء الاصطناعي، ومراجعة المخرجات التي نحصل عليها، وتحليلها وتقديم ملاحظات دقيقة لتصحيح أخطائها، وتزويد الوكيل بالمعلومات اللازمة لفهم متطلباتنا بدقة، مما يضمن تطوير تطبيقات تعمل بشكل صحيح وآمن.
</p>

<h2 id="-vibe-coding">
	أهم أدوات Vibe Coding
</h2>

<p>
	تتوفر الكثير من الأدوات والمنصات التي تتيح لنا بناء التطبيقات باستخدام أسلوب Vibe Coding، ومن ضمنها:
</p>

<h3 id="replit">
	Replit
</h3>

<p>
	توفر <a href="https://replit.com" rel="external nofollow">منصة Replit</a> بيئة تطوير سحابية متكاملة تسمح للمستخدمين بإنشاء التطبيقات ونشرها دون الحاجة إلى إعداد بيئة تطوير محلية. تتميز المنصة بدعمها للغة الطبيعية من خلال وكيل ذكي يُعرف باسم Replit Agent يعمل على تثبيت التبعيات، وإنشاء قاعدة البيانات وتوليد الكود تلقائيًا مع إمكانية النشر الفوري للتطبيقات، كما أنها تعرض كامل الكود البرمجي الناتج وتتيح لنا تحميله، ويمكنها استيراد المستودعات من جيت هب بسهولة، ما يجعلها خيارًا مثاليًا للمبرمجين المبتدئين والراغبين في إنشاء نماذج أولية لمشاريعهم بسرعة.
</p>

<p>
	بالنسبة <a href="https://replit.com/pricing" rel="external nofollow">للسعر</a>، توفر المنصة خطط مدفوعة تبدأ من 20 دولار مجانًا، كما توفر خطة مجانية تسمح بإنشاء 3 تطبيقات عامة.
</p>

<h3 id="lovable">
	Lovable
</h3>

<p>
	تعد منصة <a href="https://lovable.dev/" rel="external nofollow">Lovable</a> بيئة تطوير سحابية مدعومة بالذكاء الاصطناعي، وهي مثالية لتجربة أي أفكار جديدة تخطر على البال، فهي تتيح تحويل الأفكار إلى تطبيقات متكاملة دون الحاجة إلى كتابة لسطر برمجي واحد من خلال توفير واجهة محادثة تعتمد على اللغة الطبيعية، كل ما علينا هو وصف ما نريده بوضوح، وستتولى المنصة إنشاء الواجهة الأمامية والخلفية للتطبيق، وإعداد قواعد البيانات وصولًا إلى نشر التطبيق عبر الإنترنت وتوليد وثائقه تلقائيًا، كما تتيح مزامنة الكود مع GitHub، لكنها لا تتيح التعديل المباشر عليه داخل واجهتها وتسمح فقط بإجراء التعديلات على الكود البرمجي للتطبيق عبر جيت هب.
</p>

<p>
	بالنسبة <a href="https://lovable.dev/pricing" rel="external nofollow">للسعر</a>، توفر المنصة خطط تسعير متنوعة، تبدأ بخطة مجانية، ثم تتوفر خطط احترافية مدفوعة تكلف 25 دولار إلى 30 دولار حسب عدد الطلبات المرسلة شهريًا.
</p>

<h3 id="cursor">
	Cursor
</h3>

<p>
	منصة <a href="https://www.cursor.com" rel="external nofollow">Cursor</a> هي بيئة تطوير متقدمة طورتها شركة أنيسفير Anysphere Inc مبنية على محرر الأكواد الشهير فيجوال استوديو كود تدمج الذكاء الاصطناعي لتحسين تجربة البرمجة وتمكننا من توليد وتحريره وتحسينه وإعادة هيكلته واكتشاف أخطائه وطرح أسئلة عنه كل ذلك باستخدام اللغة الطبيعية، لكنها تتطلب إعداد بيئة تطوير محلية وتلائم أكثر المطورين الذين لديهم معرفة جيدة بالبرمجة ويحتاجون لأدوات ذكية تساعدهم في التعامل مع الكود.
</p>

<p>
	توفر المنصة خطة مجانية باسم <a href="https://www.cursor.com/pricing" rel="external nofollow">Hobby</a> تمكننا من تنفيذ 50 طلب، كما توفر عدة خطط مدفوعة، وتتيح لنا تجربة مجانية لمدة أسبوعين للخطة الاحترافية المدفوعة Pro التي تبلغ تكلفتها 20 دولار في الشهر.
</p>

<h3 id="github-copilot-agent-mode">
	GitHub Copilot Agent Mode
</h3>

<p>
	يوفر <a href="https://github.com/features/copilot" rel="external nofollow">GitHub Copilot</a> يسمى وضع الوكيل Agent Mode يحوله إلى من مجرد مساعد برمجي ذكي لمنصة تطويرية ذكية حيث يصبح بإمكانه تنفيذ مهام تطويرية متعددة، كإنشاء تطبيقات متكاملة وإعادة هيكلة أكوادها، واختبارها وتصحيح أخطائها، كما يمكنه تحديث التطبيقات القديمة وترحيلها إلى أطر عمل حديثة، وهو يتكامل مع محرر الأكواد فيجوال ستوديو كود Visual Studio Code ويدعم اختيار نماذج ذكاء اصطناعي مختلفة مثل GPT-4o و Claude 3.5 وGemini 2.0 Flash، كما يتكامل بشكل كبير معGitHub، ويدعم عدة لغات برمجة، لكن ميزة Agent Mode لا تزال حديثة نسبيًا، وقد تكون بعض الاقتراحات غير دقيقة أو غير مناسبة للسياق وتحتاج لمراجعة من قبل المبرمج.
</p>

<p>
	فيما يخص <a href="https://docs.github.com/en/copilot/about-github-copilot/plans-for-github-copilot" rel="external nofollow">التسعير</a> يتيح GitHub Copilot خطة المجانية محدودة بـ50 طلبًا شهريًا، كما يوفر خطط مدفوعة تبدأ بتكلفة 10 دولار شهريًا أو 100 دولار سنويًا، ويمكن أيضًا الاشتراك في الخطط المدفوعة مجانًا لبعض الفئات مثل الطلاب والمعلمين والمساهمين في المشاريع مفتوحة المصدر.
</p>

<h2 id="openhands">
	OpenHands
</h2>

<p>
	أداة <a href="https://github.com/All-Hands-AI/OpenHands" rel="external nofollow">OpenHands</a> هي منصة مفتوحة المصدر لتطوير التطبيقات مدعومة بالذكاء الاصطناعي تتيح لنا تنفيذ مهام تطوير مختلفة مثل إنشاء كود التطبيقات ضمن بيئة آمنة وسهلة التخصيص ومعزولة تعمل ضمن حاويات Docker. لكنها قد لا تناسب المبتدئين لكونها تتطلب إعداد لبيئة العمل يدويًا وهي مثالية للمشاريع التي الجديدة التي نبدأها من الصفر ومن الصعب دمجها في مشاريع قائمة نظرًا لطبيعة عملها المعزولة.
</p>

<p>
	هناك العديد من الأدوات الأخرى التي تدعم أسلوب Vibe Coding ويعتمد اختيار الأداة المناسبة على احتياجاتكم وأهدافكم، ننصح بتجربة بعض الأدوات مع خططها المجانية أو الإصدارات التجريبية منها لمعرفة الأداة الأفضل من بينها. بعد أن تعرفنا على أبرز الأدوات التي تستخدم أسلوب Vibe Coding، دعونا الآن نجرب تطوير تطبيق متكامل باستخدامه.
</p>

<h2 id="-vibe-coding">
	تطوير تطبيق متكامل باستخدام Vibe Coding
</h2>

<p>
	لنتعرف على خطوات إنشاء تطبيق متكامل لتقييم المواقع الأثرية في الوطن العربي وننشئه خطوة خطوة بداية من النموذج الأولي البسيط، وحتى النشر النهائي.
</p>

<h3 id="-vibe-coding">
	الخطوة الأولى: اختيار منصة Vibe Coding
</h3>

<p>
	أول خطوة علينا اتباعها هو اختيار الأداة أو المنصة المناسبة للبرمجة بأسلوب Vibe Coding، سنختار في هذه المقالة منصة <a href="https://replit.com/" rel="external nofollow"><strong>Replit</strong></a> التي توفر -كما وضحنا سابقًا- بيئة تطوير متكاملة تغنينا عن الحاجة لإعداد البيئة البرمجية يدويًا وتتيح لنا التركيز على مهام البرمجة و<a href="https://academy.hsoub.com/programming/general/%D8%AD%D9%84-%D8%A7%D9%84%D9%85%D8%B4%D9%83%D9%84%D8%A7%D8%AA-%D9%88%D8%A3%D9%87%D9%85%D9%8A%D8%AA%D9%87%D8%A7-%D9%81%D9%8A-%D8%A7%D8%AD%D8%AA%D8%B1%D8%A7%D9%81-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D8%A9-r760/" rel="">حل المشكلات</a>.
</p>

<p>
	يمكن بسهولة إنشاء حساب مجاني في المنصة بالضغط على زر Sign up وإدخال بيانات الدخول الخاصة بنا.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="182251" href="https://academy.hsoub.com/uploads/monthly_2026_04/001Replit.png.68367fe98aa17f8579bb609ebdea636a.png" rel=""><img alt="001 إنشاء حساب في منصة Replit.png" class="ipsImage ipsImage_thumbnailed" data-fileid="182251" data-ratio="48.17" data-unique="8yopfrsu0" style="width: 600px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2026_04/001Replit.thumb.png.3a4309759af08d8842b30cc811363b1b.png"></a>
</p>

<p>
	توفر هذه المنصة ثلاث خطط اشتراك يمكن الاختيار فيما بينها، حاليًا سنكتفي بتجربة الخطة المجانية Starter فهي مناسبة لغرض التعلم وتطوير مشاريع بسيطة حيث تتيح لنا تطوير ثلاث تطبيقات مع ميزات ذكاء اصطناعي محدودة.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="JPG" data-fileid="182252" href="https://academy.hsoub.com/uploads/monthly_2026_04/002replit.JPG.69f821caf813868d7ec8c942d05732b2.JPG" rel=""><img alt="002 خطط replit.JPG" class="ipsImage ipsImage_thumbnailed" data-fileid="182252" data-ratio="60.67" data-unique="fva06k4xr" style="width: 600px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2026_04/002replit.thumb.JPG.890c6b36d9b84f6e93039cfff3e79199.JPG"></a>
</p>

<h3 id="-">
	الخطوة الثانية: كتابة الموجهات
</h3>

<p>
	بعد استكمال التسجيل في المنصة ستظهر لنا مساحة العمل Workspace التي تعرض بيئة تطوير متكاملة لإنشاء وتعديل وتشغيل التطبيقات مباشرة دون الحاجة إلى تثبيت أي برامج إضافية. من هنا سنبدأ بكتابة الموجهات اللازمة لعمل التطبيق، لكن قبل البدء بهذه الخطوة من الضروري أن نفكر في التطبيق الذي نرغب بإنشائه ونجهز وصف واضح له لنتمكن من كتابة الموجهات المطلوبة لإنشائه بشكل واضح وتسلسل مناسب.
</p>

<p>
	بالنسبة لهذا المقال، سنجرب تنفيذ فكرة تطبيق الويب بإطار العمل فلاسك Flask يعرض مجموعة من المواقع الأثرية بحيث يختار معلمين مقابل بعضهما كل مرة للتصويت على أحدهما، بعدها تصنف المعالم بناء على تقييمات المستخدمين لها. سنعتمد في التقييم <a href="https://ar.wikipedia.org/wiki/%D9%86%D8%B8%D8%A7%D9%85_%D8%AA%D8%B5%D9%86%D9%8A%D9%81_%D8%A5%D9%8A%D9%84%D9%88" rel="external nofollow">نظام إيلو Elo</a> المستخدم في الألعاب التنافسية مثل الشطرنج والرياضات الإلكترونية ونشاهد كيف يقوم الذكاء الاصطناعي بإنشاء كود التطبيق وجعله يعمل.
</p>

<p>
	لننتبه هنا أنه ليس علينا أن نعطي الموجه الكامل لتفاصيل التطبيق بل يكفي أن نبدأ بموجه بسيط وستتخذ أفكارنا شكلها النهائي من خلال الحوار مع الذكاء الاصطناعي.
</p>

<p>
	<strong>ملاحظة</strong>: سنكتب الموجهات prompts باللغتين العربية والإنجليزية ونعتمد على الانجليزية لأن أغلب بيانات تدريب النماذج اللغوية الضخمة LLMs باللغة الإنجليزية وخاصة تلك التي تتضمن أكواد ومصطلحات برمجية وهي تعطي نتائج أدق، ولكن لازال بالإمكان توجيه الأوامر والطلبات باللغة العربية من هذه الأدوات.
</p>

<p>
	سنبدأ العمل بكتابة موجه بسيط من وكيل الذكاء الاصطناعي لإنشاء نموذج أولي على النحو التالي:
</p>

<blockquote class="ipsQuote" data-gramm="false" data-ipsquote="">
	<div class="ipsQuote_citation">
		اقتباس
	</div>

	<div class="ipsQuote_contents ipsClearfix" data-gramm="false">
		<p>
			<strong>الموجه باللغة الإنجليزية:</strong>
		</p>

		<p>
			Help me build an interactive Flask app for voting and ranking the most famous archaeological landmarks in the Arab world. The app should allow users to vote on landmarks head-to-head, then calculate a ranking for the landmarks based on the chess Elo system. The app should prominently display the matchup along with overall rankings and recent votes.
		</p>

		<p>
			<strong>الموجه باللغة العربية:</strong>
		</p>

		<p>
			ساعدني في بناء تطبيق تفاعلي باستخدام Flask للتصويت وتصنيف أشهر المعالم الأثرية في الوطن العربي. يجب أن يتيح التطبيق للمستخدمين التصويت والاختيار ما بين معلمين أثريين مقابلين لبعضهما، ثم حساب تصنيف هذه المعالم باستخدام نظام Elo المستمد من لعبة الشطرنج. ينبغي أن يعرض التطبيق نتيجة المقارنة الحالية بشكل واضح، إلى جانب التصنيفات الإجمالية وأحدث نتائج التصويت.
		</p>
	</div>
</blockquote>

<p>
	لو رغبنا في جعل التطبيق يعرض المعالم الأثرية ضمن التطبيق من مصدر مرجعي معين يمكن أن نوفره له ضمن على النحو التالي:
</p>

<blockquote class="ipsQuote" data-gramm="false" data-ipsquote="">
	<div class="ipsQuote_citation">
		اقتباس
	</div>

	<div class="ipsQuote_contents ipsClearfix" data-gramm="false">
		<p>
			<strong>الموجه باللغة الإنجليزية:</strong>
		</p>

		<p>
			I want you to rely on the historical landmarks displayed on this page as a source of information. <a href="https://ar.wikipedia.org/wiki/%D9%82%D8%A7%D8%A6%D9%85%D8%A9_%D9%85%D9%88%D8%A7%D9%82%D8%B9_%D8%A7%D9%84%D8%AA%D8%B1%D8%A7%D8%AB_%D8%A7%D9%84%D8%B9%D8%A7%D9%84%D9%85%D9%8A_%D9%81%D9%8A_%D8%A7%D9%84%D8%AF%D9%88%D9%84_%D8%A7%D9%84%D8%B9%D8%B1%D8%A8%D9%8A%D8%A9" rel="external nofollow">https://ar.wikipedia.org/wiki/قائمة_مواقع_التراث_العالمي_في_الدول_العربية</a> 
		</p>

		<p>
			<strong>الموجه باللغة العربية:</strong>
		</p>

		<p>
			أريدك أن تعتمد على المعالم الأثرية المعروضة في هذه الصفحة كمصدر للمعلومات <a href="https://ar.wikipedia.org/wiki/%D9%82%D8%A7%D8%A6%D9%85%D8%A9_%D9%85%D9%88%D8%A7%D9%82%D8%B9_%D8%A7%D9%84%D8%AA%D8%B1%D8%A7%D8%AB_%D8%A7%D9%84%D8%B9%D8%A7%D9%84%D9%85%D9%8A_%D9%81%D9%8A_%D8%A7%D9%84%D8%AF%D9%88%D9%84_%D8%A7%D9%84%D8%B9%D8%B1%D8%A8%D9%8A%D8%A9" rel="external nofollow">https://ar.wikipedia.org/wiki/قائمة_مواقع_التراث_العالمي_في_الدول_العربية</a>
		</p>
	</div>
</blockquote>

<p>
	في هذه الحالة سنلاحظ ظهور خيارين للتعامل مع الرابط المرفق الأول هو التقاط لقطة شاشة Take screenshot من أجل التقاط صورة للمحتوى الموجود في الرابط وهو مفيد إذا كنا نريد حفظ شكل الصفحة أو مشاركتها كصورة. والثاني هو استخراج المحتوى النصي Get text content الذي يجلب المعلومات النصية الموجودة في الصفحة، بدون الصور أو التنسيقات المرئية وهو مفيد إذا كنا نريد تحليل النص واستخدمها في تطبيقنا.
</p>

<p>
	سنكتب الآن الموجه الأول كاملًا كما في الصورة التالية ونرسله بالضغط على زر Start Building:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="JPG" data-fileid="182253" href="https://academy.hsoub.com/uploads/monthly_2026_04/003.JPG.f95e67dcb761c140e15756441ad77bea.JPG" rel=""><img alt="003 كتابة الموجه الأول.JPG" class="ipsImage ipsImage_thumbnailed" data-fileid="182253" data-ratio="59.00" data-unique="xmzxdglo6" style="width: 600px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2026_04/003.thumb.JPG.c4b3aa15354fe0d10c664c1e193181ae.JPG"></a>
</p>

<p>
	<strong>ملاحظة</strong>: إذا كنا غير متأكدين من كيفية وصف فكرتنا بدقة يمكن النقر على خيار Improve prompt لتحسين الموجه وإعادة صياغته قبل إرساله، حيث سيعمل وكيل الذكاء الاصطناعي في هذه الحالة على إضافة أي تفاصيل مطلوبة وتحديد التقنيات أو الأطر المناسبة للمشروع إن لزم وقد يقسم الموجه لعده خطوات قابلة للتنفيذ مما يساهم في تحسين جودة المخرجات وتقليل الأخطاء.
</p>

<p>
	بعد إرسال الموجه ستبدأ المنصة بتحليله وتعرض خطة المشروع Project Plan التي تنظم التطبيق، كما ستقترح إضافة بعض الميزات للتطبيق مثل تخزين بيانات المعالم الأثرية ونتائج التصويت في قواعد بيانات، وإضافة حسابات المستخدمين لتتبع سجل التصويت، وإضافة صفحات تفصيلية للمعالم الأثرية تتضمن معلومات وصور عن كل معلم، وخيارات للبحث حسب معايير متنوعة، كما تظهر لنا المدة التقديرية لإنشاء العرض الأولي للتطبيق والنسخة الأولية الكاملة منه.
</p>

<p>
	بداية لن تختار أيًا من المميزات الإضافية وسنبني التطبيق الأساسي فقط، ويمكننا إضافة ما نريده ميزات لاحقًا متى ما أردنا ذلك، لنضغط على زر Approve plan &amp; start لتبدأ عملية إنشاء التطبيق.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="JPG" data-fileid="182254" href="https://academy.hsoub.com/uploads/monthly_2026_04/004.JPG.6560dd110f6c48f3a5e765c220a69d5a.JPG" rel=""><img alt="004 خطة المشروع.JPG" class="ipsImage ipsImage_thumbnailed" data-fileid="182254" data-ratio="81.33" data-unique="0voeli1dw" style="width: 600px; height: auto;" width="737" src="https://academy.hsoub.com/uploads/monthly_2026_04/004.thumb.JPG.e34213311bfe49ca4dbf788fe4f937c4.JPG"></a>
</p>

<p>
	ليس علينا الآن سوى الانتظار لدقائق معدودة، وترك المنصة تقوم بعملها وتنشئ التطبيق المطلوب باسم Arab World Heritage Sites مع توفير كافة ملفات المشروع وأكواده المطلوبة.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="JPG" data-fileid="182255" href="https://academy.hsoub.com/uploads/monthly_2026_04/005.JPG.0bdc041a4853d0bcb4bb457a604437bf.JPG" rel=""><img alt="005 التطبيق المطلوب والأكواد البرمجية.JPG" class="ipsImage ipsImage_thumbnailed" data-fileid="182255" data-ratio="46.50" data-unique="258x9vatl" style="width: 600px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2026_04/005.thumb.JPG.289a6cac5b8474a816ae2e203e538b88.JPG"></a>
</p>

<h3 id="-">
	الخطوة الثالثة: اختبار التطبيق
</h3>

<p>
	الآن علينا تجربة الكود الناتج من خلال تشغيل التطبيق والتحقق من أدائه
</p>

<p>
	عند الانتهاء سيظهر لنا تطبيق يعرض المعالم الأثرية المختلفة ويسمح لنا بالتصويت عليها ويعرض النتائج في الأسفل كما توضح في الصورة التالية، وعلينا في هذه المرحلة تجربته والتحقق من مظهره ووظائفه.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="182256" href="https://academy.hsoub.com/uploads/monthly_2026_04/006.gif.a487e4399bf41ab0139808aad43460b6.gif" rel=""><img alt="006 التطبيق الأولي.gif" class="ipsImage ipsImage_thumbnailed" data-fileid="182256" data-ratio="41.00" data-unique="q623o67ws" style="width: 900px; height: 369px;" width="900" src="https://academy.hsoub.com/uploads/monthly_2026_04/006.thumb.gif.7fa27598eada6095afd54873c5f59dab.gif"></a>
</p>

<p>
	نفتح التطبيق الناتج في علامة تبويب مستقلة في المتصفح بالنقر على زر New tab الموجود في شريط الأدوات العلوي في التبويب Preview. يبدو أن التطبيق يعمل بشكل صحيح وهو متجاوب مع الهاتف، لكنه يعرض لنا كافة البيانات -ما عدا اسم المعلم الأثري- باللغة الإنجليزية، لذا سنحتاج لتحسينه ليجعل المعلومات باللغة العربية، كما سنضيف له ميزات إضافية في الفقرات التالية.
</p>

<h2 id="-">
	الخطوة الرابعة: تحسين النتائج
</h2>

<p>
	سنكتب موجهات جديدة لتنفيذ مهام تحسينية ومميزات إضافية لتخصيص التطبيق وجعله يعمل وفق متطلباتنا.
</p>

<p>
	أول مهمة تحسينية هي جعل تطبيقنا يعرض المعلومات باللغة العربية بالكامل وبالاتجاه من اليمين لليسار RTL، كما أننا سنعدل تصميمه ليستخدم ألوان قاتمة تتناسب مع عرض المواقع الأثرية كتدرجات البني والألوان الترابية.
</p>

<p>
	لنكتب هذا الموجه لتنفيذ هذا التحسين.
</p>

<blockquote class="ipsQuote" data-gramm="false" data-ipsquote="">
	<div class="ipsQuote_citation">
		اقتباس
	</div>

	<div class="ipsQuote_contents ipsClearfix" data-gramm="false">
		<p>
			<strong>الموجه باللغة الإنجليزية</strong>
		</p>

		<p>
			The app is functioning properly, but it currently displays all content — except for the landmark names — in English. We need the entire application to be in Arabic, with full RTL layout support. Additionally, the current color scheme is too generic. Please update it to reflect earthy tones and shades of brown that better match the theme of historical and archaeological sites.
		</p>

		<p>
			<strong>الموجه باللغة العربية</strong>
		</p>

		<p>
			يعمل التطبيق بشكل صحيح، ولكنه يعرض جميع المحتوى — باستثناء أسماء المعالم — باللغة الإنجليزية. نحتاج إلى أن يكون التطبيق بالكامل باللغة العربية، مع دعم كامل لاتجاه الكتابة من اليمين إلى اليسار RTL. بالإضافة إلى ذلك، فإن نظام الألوان الحالي عام جدًا. الرجاء تحديثه ليعكس درجات ألوان ترابية وظلال من اللون البني، بما يتماشى بشكل أفضل مع طابع المواقع التاريخية والأثرية.
		</p>
	</div>
</blockquote>

<p>
	عند تطبيق الموجه السابق سنحصل على النتيجة التالية التي تعرض الصفحة الرئيسية للتطبيق:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="182257" href="https://academy.hsoub.com/uploads/monthly_2026_04/007.png.0173a89c6094bb29a7a2ed1cfb55efab.png" rel=""><img alt="007 التطبيق بعد التحسين الأول الصفحة الرئيسية.png" class="ipsImage ipsImage_thumbnailed" data-fileid="182257" data-ratio="100.67" data-unique="zdn5ucq27" width="596" src="https://academy.hsoub.com/uploads/monthly_2026_04/007.thumb.png.2c514080590ecb717539dcbcc1d29c23.png"></a>
</p>

<p>
	نلاحظ تحسن مظهر واجهة التطبيق ، وعرض المعلومات بشكل سليم باللغة العربية واعتماد الاتجاه من اليمين لليسار كما طلبنا، لكن تطبيقنا لا يحتفظ بنتائج التصويت التي ندخلها في كل مرة وذلك لأنه يخزن النتائج في الذاكرة عند تشغيل التطبيق فقط ولا يحفظها بشكل دائم ضمن قاعدة بيانات، وبالتالي فإن كافة نتائج التصويت ستفقد بمجرد إعادة تشغيل التطبيق من جديد.
</p>

<p>
	لو تحقننا من ملفات الكود يمكن أن نرى أن التطبيق يخزن بيانات المعالم الأثرية في القاموس <code>landmarks</code> ضمن ملف <code>models.py</code>، ويخزن نتائج التصويت الأخيرة في قائمة بالاسم <code>votes</code> تحفظ آخر 50 نتيجة وتخزنها مؤقتًا في الذاكرة. ولجعل النتائج محفوظة بشكل دائم حتى بعد إعادة تشغيل التطبيق سنحتاج إلى إنشاء قاعدة بيانات مثل SQLite أو PostgreSQL ونحول <code>landmarks</code> و <code>votes</code> إلى جداول، كما سننشئ جدول للمستخدمين للسماح لهم بالتسجيل والتصويت.
</p>

<p>
	بالطبع لن نقوم بهذه التعديلات على الكود بأنفسنا بل سنتبع أيضًا أسلوب Vibe Coding فكل ما نحتاجه هو كتابة موجه نصي بسيط على النحو التالي:
</p>

<blockquote class="ipsQuote" data-gramm="false" data-ipsquote="">
	<div class="ipsQuote_citation">
		اقتباس
	</div>

	<div class="ipsQuote_contents ipsClearfix" data-gramm="false">
		<p>
			<strong>الموجه باللغة الإنجليزية:</strong>
		</p>

		<p>
			To ensure data is persistently stored and accessible across sessions and for all users, we will store it permanently in the database. We'll implement a user authentication system with registration and login functionality, using email and securely encrypted passwords. Voting will be restricted to authenticated users only. Once a user is logged in, each vote will be linked to their account to maintain accurate user-specific data.
		</p>

		<p>
			<strong>الموجه باللغة العربية:</strong>
		</p>

		<p>
			لضمان تخزين بيانات التطبيق بشكل دائم وإمكانية الوصول إليها عبر الجلسات ولكافة المستخدمين، سنقوم بحفظها بشكل دائم في قاعدة بيانات. سننفذ نظام مصادقة للمستخدمين يتضمن التسجيل وتسجيل الدخول باستخدام البريد الإلكتروني وكلمات مرور مشفّرة بشكل آمن. سنتقيد التصويت ليكون للمستخدمين المسجلين فقط. وبمجرد تسجيل دخول المستخدم، سنربط نتائج التصويت بالمستخدمين لنتمكن من عرض نتائج التصويت لكل مستخدم بناءً على البيانات المخزنة.
		</p>
	</div>
</blockquote>

<p>
	من جديد، سنترك المنصة تقوم بعملها لنحصل بعد دقائق على التطبيق المعدل الذي يتضمن حفظ النتائج ووظيفة تسجيل مستخدمين من خلال البريد الإلكتروني وكلمة المرور.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="182258" href="https://academy.hsoub.com/uploads/monthly_2026_04/008.png.adcb16298837831185f1e25a7d605a8b.png" rel=""><img alt="008 إضافة ميزة تسجيل الدخول.png" class="ipsImage ipsImage_thumbnailed" data-fileid="182258" data-ratio="65.50" data-unique="8l2y0c7xx" style="width: 600px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2026_04/008.thumb.png.f934f132b91dbd7f6274a9dce782fe5a.png"></a>
</p>

<p>
	كل ما علينا فعله هو تشغيل التطبيق والتحقق من ان كل شيء يسير على ما يرام وسنجد أننا لم نعد نستطيع التصويت إذا لم نكن مسجلين دخول للموقع، وسنتوجه لصفحة التسجيل في الموقع كي نتمكن من تقييم المواقع الأثرية.
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="182259" href="https://academy.hsoub.com/uploads/monthly_2026_04/009.gif.569262eae669979e713f55fb45afb989.gif" rel=""><img alt="009 التسجيل للتصويت.gif" class="ipsImage ipsImage_thumbnailed" data-fileid="182259" data-ratio="66.67" data-unique="uo1crxa6r" width="900" src="https://academy.hsoub.com/uploads/monthly_2026_04/009.thumb.gif.452fb10fdf8c2ee3e1aad1f423e344bc.gif"></a>
</p>

<p>
	كما سنلاحظ أن نتائج التصويت أصبحت تحفظ عند إعادة تشغيل التطبيق.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2026_04/010.png.e5cd4fa5405ade1dc5f043f6e24b4002.png" data-fileid="182264" data-fileext="png" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="182264" data-ratio="101.69" data-unique="b1wqsgeiv" width="590" alt="010 حفظ نتائج التصويت.png" src="https://academy.hsoub.com/uploads/monthly_2026_04/010.thumb.png.589fa34b63f20d360cfd3b65eac09d98.png"></a><br>
	<span id="cke_bm_4306E" style="display: none;"> </span>
</p>

<p>
	يبدو الأمر رائعًا بالفعل، فخلال أقل من نصف ساعة تمكنا من إنشاء تطبيق مخصص ومتكامل يحقق الوظائف التي نحتاجها، سنكتفي حاليًا بهذه التحسينات ونترك لكم حرية إضافة ما تريدونه على التطبيق من أمور إضافية كإنشاء صفحة مستقلة لكل معلم أثري تتضمن معلوماته الكاملة وتقييمه، أو عرض المواقع الأثرية على خريطة تفاعلية لسهولة الوصول إليها، أو السماح للمستخدمين بإضافة تعليقات عليه وعرضها ،أو دعم نظام إشعارات للمستخدمين حين يتغير ترتيب معلم مفضل لديهم أو غيرها من الأفكار العديدة الأخرى.
</p>

<p>
	ننوه لأن منصة Replit توفر لنا نقاط حفظ تلقائية أثناء تنفيذ تغييرات مهمة على التطبيق،يطلق على كل نقطة اسم checkpoint وهي بمثابة لقطة لحالة التطبيق في لحظة معينة تساعدنا على تتبع سير العمل وتتيح لنا التراجع Rollback لإلغاء التعديلات التي أجريناها في حال كانت غير مناسبة وأردنا العودة لحالة التطبيق السابقة، كما تمكننا من حفظ الكود الناتج من خلال النقر على خيارات التبويب الجانبي Files واختيار الأمر Download as zip ليحفظ لنا كافة الأكواد البرمجية التي أنشأها باسم LandmarkLegends.zip.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="182262" href="https://academy.hsoub.com/uploads/monthly_2026_04/011.png.c5a979230efa259c54e46dace23869c4.png" rel=""><img alt="011 حفظ الكود البرمجي.png" class="ipsImage ipsImage_thumbnailed" data-fileid="182262" data-ratio="48.00" data-unique="znrzpo59s" style="width: 600px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2026_04/011.thumb.png.98c4dbcdb7b1013e92eac61b35ba4f39.png"></a>
</p>

<h2 id="-">
	الخطوة الخامسة: نشر التطبيق
</h2>

<p>
	بعد الانتهاء من تطوير تطبيقنا، نأتي للخطوة الأخيرة وهي نشره وإتاحته للمستخدمين، تتيح لنا منصة Replit نشر تطبيقنا بسهولة كل ما علينا هو الانتقال لمساحة العمل الخاصة بمشروعنا والنقر على زر النشر Deploy في أعلى مساحة العمل لفتح لوحة إعدادات النشر.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="182263" href="https://academy.hsoub.com/uploads/monthly_2026_04/012.png.3bbdba1ae9d69881d50bdfca2b1f890a.png" rel=""><img alt="012 لوحة النشر.png" class="ipsImage ipsImage_thumbnailed" data-fileid="182263" data-ratio="50.83" data-unique="bzoslw44h" style="width: 600px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2026_04/012.thumb.png.a960ae5c37ba19d43a9353ab3c0baa3a.png"></a>
</p>

<p>
	نلاحظ من اللوحة السابقة توفر عدة خيارات للنشر:
</p>

<ul>
	<li>
		Reserved VM الذي يوفر خادم محجوز بموارد مخصصة تضمن تشغيل تطبيقنا دون انقطاع
	</li>
	<li>
		Autoscale يوسع الموارد تلقائيًا حسب استخدام التطبيق
	</li>
	<li>
		Static مناسب للمواقع الثابتة التي لا تتطلب معالجة من طرف الخادم
	</li>
	<li>
		Scheduled مناسب للتطبيقات التي تعمل في أوقات محددة نختارها
	</li>
</ul>

<p>
	بعد تحديد نوع النشر وإعداداته ستتيح لنا المنصة عنوان URL فريد خاص به يمكننا مشاركته مع المستخدمين، ويجب التأكد من أن نمط الخصوصية privacy mode لتطبيقنا هو عام public كي يتمكن الجميع من رؤيته، ويمكن مطالعة <a href="https://docs.replit.com/category/replit-deployments" rel="external nofollow">توثيق Replit</a> للحصول على معلومات إضافية حول عملية النشر.
</p>

<h2 id="-vibe-coding-">
	هل سيلغي Vibe Coding دور المبرمجين
</h2>

<p>
	إن المتابع للتطورات على الساحة التقنية سيلاحظ إثارة الكثير من التساؤلات والمخاوف حول الذكاء الاصطناعي وبالتحديد منهجية Vibe Coding وفيما إذا كانت ستلغي دور المبرمجين في المستقبل، فما الحاجة لتعلم البرمجة إن كان بإمكان أي شخص عادي ليس لدي أي خلفية برمجية إنشاء ما يحلو له من تطبيقات ونشرها من خلال أوامر بسيطة دون الحاجة لكتابة كود طويل ومعقد.
</p>

<p>
	في الواقع يجب أن نقرّ بأن استخدام الذكاء الاصطناعي لصناعة البرمجيات دون فهم جيد للكود الناتج عن هذه التطبيقات أمر محفوف بالمخاطر فضلًا عن كونه قد يؤدي إلى صعوبة في الصيانة والتطوير المستقبلي. وعلى الرغم من أن هذا أسلوب Vibe Coding يوفر تطبيقات متكاملة وتعمل بكفاءة إلا أنه مناسب فقط لتطوير النماذج الأولية السريعة والتطبيقات البسيطة محدودة الموراد والمتطلبات، أو كما قال أندريه كارباثي في <a href="https://x.com/karpathy/status/1886192184808149383?lang=en" rel="external nofollow">تغريدته على منصة X</a> إن هذه المنهجية في البرمجة مناسبة أكثر لمشاريع عطلة نهاية الأسبوع وليس للمشاريع الجادة أو المعقدة.
</p>

<p>
	فلن نستغني عن دور المبرمجين في تطوير تطبيقات معقدة تتطلب خصوصية وأمانًا عاليًا كأنظمة الدفع الإلكتروني أو التطبيقات التي تتعامل مع بيانات حساسة، أو صناعة تطبيقات عالية الموارد تحتاج لبنية تحتية قوية وكود محسن بعناية يضمن تجربة استخدام سلسة كمنصات التجارة الإلكترونية أو تطبيقات الواقع المعزز فهذه التطبيقات ستحتاج بالتأكيد لخبراء ومختصين في البرمجة والتطوير لتنفيذها بكفاءة.
</p>

<p>
	وحتى التطبيقات البسيطة المولدة بتقنيات الذكاء الاصطناعي لن تلغي دور المبرمجين ولن تغنينا عن الحاجة إلى <a href="https://academy.hsoub.com/programming/general/%D8%AA%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D8%A9-r662/" rel="">تعلم البرمجة</a>، فمن ذا الذي سيصحح هذه التطبيقات إذا حدث فيه خطأ أو خلل أمني فيها، أو تبين في مرحلة ما من عملها أنها لا تنفذ بعض المهام بالشكل المطلوب منها، أو أنها تعاني من ثغرات أمنية خطيرةّ في هذه الحالة لن يستطع شخص غير متخصص بالبرمجة من معرفة ما يجري وراء الكواليس واتباع أفضل الممارسات لتحسين كود التطبيق وإصلاح أخطائه.
</p>

<p>
	فما سيحدث فقط هو تحول دور المبرمجين الأساسي من كتابة الكود إلى التوجيه والتحسين وتصحيح المشكلات وسيظل <a href="https://academy.hsoub.com/programming/general/%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D8%A9/" rel="">الفهم الأساسي لمبادئ البرمجة</a> أمرًا لا غنى عنه في تقديم أوامر أكثر دقة للذكاء الاصطناعي وتحليل الكود الناتج وتعديله إذا لزم الأم والتعامل مع المشكلات والأخطاء التقنية التي قد تظهر بكفاءة واحترافية كما يمكن للمبرمجين أنفسهم الاستفادة منه في عملهم كما سنوضح في فقرتنا التالية.
</p>

<h2 id="-vibe-coding-">
	أهمية Vibe Coding للمبرمجين
</h2>

<p>
	يوفر أسلوب Vibe Coding عدة فوائد للمطورين والمبرمجين، لنستعرض أبرزها:
</p>

<h2 id="-">
	تغير طبيعة العمل
</h2>

<p>
	لن تصبح مهمة المطورين والمبرمجين الأساسية هي كتابة الأكواد البرمجية الطويلة وتنقيحها، وإنما ستكون مهمتهم هي التوجيه والإشراف على عمل وكلاء الذكاء الاصطناعي، وستكون أهم مهارة يحتاجونها لهذا الدور هي التواصل الفعال والقدرة على التعبير عن الأفكار بوضوح إلى جانب تقييم وتحسين ما يولده لهم الذكاء الاصطناعي.
</p>

<h3 id="-">
	بناء نماذج أولية بسرعة
</h3>

<p>
	بات بمقدورنا الانتقال من مرحلة الفكرة إلى نموذج أولي قابل للتجربة بفترة وجيزة جدًا فكي نبدأ بتنفيذ تطبيقاتنا لن نحتاج كخطوة أولى سوى لفكرة مبتكرة نعبر عنها بشكل تعليمات واضحة نوفرها لوكيل الذكاء الاصطناعي ونتركه يتولى تفاصيل التنفيذ ونحن نشرب قهوتنا، وهذا يتيح يسرع وتيرة التطوير ويسهل علينا ابتكار خدمات ونماذج أعمال جديدة باستمرار.
</p>

<h2 id="-">
	توفير أسلوب تعلم مبتكر
</h2>

<p>
	سيغير هذا النهج في البرمجة الأساليب التقليدية المملة في تعلم البرمجة التي كانت تتطلب فهمًا جيدًا للمفاهيم التقنية قبل أن نتمكن من بناء أو تطبيق لنا، وأصبحت الآن تركز على تعلم كتابة الموجهات prompts لبناء التطبيق الذي يعمل بكفاءة وتوفير كوده كاملًا وبعدها يمكن أن نطلب من الوكيل الذكي أن يشرح لنا ما قام ونسأل عن وظيفة أي جزء معين من الكود لنحصل على شرح تفصيلي شامل يعزز من فهمنا النظري والعملي بنفس الوقت وهذا بلا شك سيجعل تجربة التعلم أكثر متعة.
</p>

<h3 id="-">
	تحسين مهارات كتابة الموجهات
</h3>

<p>
	فمن خلال التخاطب المستمر مع وكلاء الذكاء الاصطناعي سنطور مهارتنا في هندسة الموجهات Prompt Engineering فهذه المهارة تتطلب فهمًا عميقًا لكيفية صياغة الأوامر والتعليمات بطريقة تضمن الحصول على استجابات دقيقة وذات صلة، وهي بلا شك مهارة ضرورية ومطلوبة بشدة في وقتنا الحالي.
</p>

<h2 id="-">
	الخاتمة
</h2>

<p>
	وصلنا لنهاية مقالنا الذي شرحنا فيه تقنية Vibe Coding وطبقناها عمليًا لتطوير تطبيق ويب متكامل، لا تزال هذه التقنية في مراحلها الأولى، ولكن يمكننا الاستفادة منها كمبرمجين لتسريع عملن في تطوير البرمجيات وتسهيل تعلم البرمجة وفهمها.
</p>

<p>
	فلو كنتم مبتدئين في البرمجة صعبة، وتحتاج للكثير من الوقت قبل التمكن من تنفيذ أفكاركم المبدعة ووضعها موضع التنفيذ فإن تقنية Vibe Coding فرصتكم لبدء رحلتكم مع البرمجة وإنشاء التطبيقات الخاصة بكم، كل ما تحتاجونه هو الحوار مع وكلاء ذكاء اصطناعي وشرح ما تريدون تنفيذه بالتفصيل بلغتكم الطبيعية الواضحة وفهم الأكواد الناتجة وتحسينها وسيغدو التعلم ماتعًا وشيقًا ومفيدًا، هل بدأتم بالفعل بتجربة هذا النمط من البرمجة أم ليس بعد؟ وهل ترون أنه سيكون معيارًا أساسيًا في مستقبل تطوير البرمجيات؟ شاركونا آراءكم وتجاربكم.
</p>

<h2 id="-">
	المصادر
</h2>

<ol>
	<li>
		<a href="https://docs.replit.com/getting-started/intro-replit" rel="external nofollow">دليل البدء مع منصة Replit لإنشاء وتشغيل المشاريع البرمجية</a>
	</li>
	<li>
		<a href="https://de.wikipedia.org/wiki/Vibe_Coding" rel="external nofollow">فايب كودينج Vibe Coding: المفهوم والتعريف العام</a>
	</li>
	<li>
		<a href="https://blankslatedigital.co.uk/blog/artificial-intelligence/what-is-vibe-coding/" rel="external nofollow">ما هو Vibe Coding؟ شرح مبسط لكيفية بناء التطبيقات باستخدام الذكاء الاصطناعي</a>
	</li>
	<li>
		<a href="https://www.designrush.com/agency/software-development/trends/vibe-coding" rel="external nofollow">Vibe Coding: اتجاه حديث في تطوير البرمجيات باستخدام الذكاء الاصطناعي</a>
	</li>
	<li>
		<a href="https://medium.com/@karan.kamat1406/vibe-coding-the-ai-era-of-development-but-with-a-catch-44f021a2ed2e" rel="external nofollow">Vibe Coding: عصر جديد من البرمجة بالذكاء الاصطناعي مع تحدياته</a>
	</li>
	<li>
		<a href="https://momen.app/blogs/what-is-vibe-coding-pros-cons/" rel="external nofollow">ما هو Vibe Coding؟ المزايا والعيوب في تطوير التطبيقات بالذكاء الاصطناعي</a>
	</li>
</ol>
]]></description><guid isPermaLink="false">2609</guid><pubDate>Sun, 19 Apr 2026 13:13:00 +0000</pubDate></item><item><title>&#x627;&#x62E;&#x62A;&#x628;&#x627;&#x631; &#x627;&#x644;&#x628;&#x631;&#x645;&#x62C;&#x64A;&#x627;&#x62A; &#x628;&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; BlackBox AI</title><link>https://academy.hsoub.com/programming/artificial-intelligence/%D8%A7%D8%AE%D8%AA%D8%A8%D8%A7%D8%B1-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D8%A7%D8%AA-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-blackbox-ai-r2605/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2026_03/blackbox.png.73d47e17e75daaec960319375663f1e4.png" /></p>
<p>
	نشرح في هذه المقالة كيفية استخدام أداة الذكاء الاصطناعي BlackBoxAI في اختبار البرامج، وهي المهمة التي تضمن استقرار عمل الأنظمة التي نطورها، خاصة في التطبيقات الحيوية التي تكون تكلفة الخطأ فيها كبيرة مثل تطبيقات التكنولوجيا المالية أو القيادة الذاتية للمركبات، إضافة إلى التصنيفات الأخرى من التطبيقات التي نرغب باختبارها.
</p>

<h2 id="-">
	تعريف اختبار البرامج
</h2>

<p>
	اختبار البرامج Software testing هو تقييم التطبيقات البرمجية التي نطورها من حيث الأداء والوظائف التي تؤديها لنتأكد من استيفاء هذه البرامج للمتطلبات المستهدفة منها وأنها تخلو من الأخطاء والعيوب، وتُختبر البرامج إما آليًا أو يدويًا.
</p>

<p>
	ويقسَّم اختبار البرامج من منظور آخر إلى اختبار وظيفي Functional testing واختبار غير وظيفي Non-Functional testing، حيث تقيس الاختبارات الوظيفية أداء الوظائف الأساسية المطلوبة من النظام مثل التحقق من معالجة البيانات المدخلة بشكل صحيح بينما يقيس الاختبار غير الوظيفي مزايا وصفية وليست وظيفية للنظام، مثل اختبار الأداء Performance testing أو <a href="https://academy.hsoub.com/design/user-experience/%D9%82%D8%A7%D8%A8%D9%84%D9%8A%D8%A9-%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D9%88%D8%A3%D9%87%D9%85%D9%8A%D8%AA%D9%87%D8%A7-%D9%81%D9%8A-%D8%AA%D8%AC%D8%B1%D8%A8%D8%A9-%D8%A7%D9%84%D9%85%D8%B3%D8%AA%D8%AE%D8%AF%D9%85-r728/" rel="">اختبار قابلية الاستخدام Usability</a> أو <a href="https://academy.hsoub.com/programming/html/%D9%85%D8%B9%D8%A7%D9%84%D8%AC%D8%A9-%D9%85%D8%B4%D8%A7%D9%83%D9%84-%D8%B3%D9%87%D9%88%D9%84%D8%A9-%D8%A7%D9%84%D9%88%D8%B5%D9%88%D9%84-accessibility-%D8%A7%D9%84%D8%B4%D8%A7%D8%A6%D8%B9%D8%A9-%D9%84%D9%84%D8%AA%D9%88%D8%A7%D9%81%D9%82-%D9%85%D8%B9-%D8%A7%D9%84%D9%85%D8%AA%D8%B5%D9%81%D8%AD%D8%A7%D8%AA-r1983/" rel="">اختبار سهولة الوصول Accessibility</a>.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="181747" href="https://academy.hsoub.com/uploads/monthly_2026_03/___000.png.a4a0b7e7908b25a2eea45c0d1d131624.png" rel=""><img alt="أنواع_اختبار_البرامج_000.png" class="ipsImage ipsImage_thumbnailed" data-fileid="181747" data-ratio="56.33" data-unique="h2daqxrhe" style="width: 600px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2026_03/___000.thumb.png.1c82031bf611e8eee7520c36e2974828.png"></a>
</p>

<h2 id="-">
	متطلبات العمل
</h2>

<ul>
	<li>
		<p>
			تنزيل محرر أكواد مناسب مثل <a href="https://code.visualstudio.com/download" rel="external nofollow">VS Code</a>
		</p>
	</li>
	<li>
		<p>
			تثبيت <a href="https://marketplace.visualstudio.com/items?itemName=Blackboxapp.blackbox" rel="external nofollow">إضافة BLACKBOXAI في VSCode</a>
		</p>
	</li>
	<li>
		<p>
			تثبيت مكتبات بايثون التالية <code>fastapi</code> و <code>uvicorn</code> و <code>locust</code> باستخدام الطرفية:
		</p>
	</li>
</ul>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_5195_8" style=""><span class="pln">pip install fastapi uvicorn locust</span></pre>

<h2 id="-software-testing-levels">
	مستويات اختبار البرامج Software testing levels
</h2>

<p>
	ذكرنا أول المقال أننا نختبر البرامج لنضمن عملها وأداءها لوظائفها، وأدنى هذه المستويات هو اختبار الوحدة unit test، ثم اختبار التكامل Integration test الذي يقيس توافقية الوحدات البرمجية المختلفة مع بعضها البعض عند دمجها، يلي هذا اختبار النظام بشكل شامل System testing، ثم اختبارات القبول في المستوى النهائي التي ينفذها المستخدم حيث يختبر الوظائف المطلوبة بشكل كامل ليقيس جاهزيتها للتسليم.
</p>

<h2 id="-unit-test">
	اختبار الوحدات البرمجية unit test
</h2>

<p>
	يمثل اختبار الوحدات البرمجية أدنى مستوى من اختبار البرامج حيث يفحص أصغر الأجزاء القابلة للتنفيذ في الشيفرة مثل الدوال البرمجية Functions أو الأصناف classes أو التوابع methods، ويتم هذا الاختبار في بيئة معزولة عن باقي مكونات النظام أو أي أنظمة خارجية مثل <a href="https://academy.hsoub.com/devops/servers/databases/%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-database/" rel="">قواعد البيانات</a> أو <a href="https://academy.hsoub.com/programming/general/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D8%A7%D9%84%D9%88%D8%A7%D8%AC%D9%87%D8%A7%D8%AA-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D8%A9-api-r1314/" rel="">واجهات التطبيقات البرمجية APIs</a> لأن المشكلات التي قد تحدث في هذا المستوى ستؤثر على غيره، فإذا كنا نصمم <a href="https://academy.hsoub.com/programming/python/%D9%85%D8%B4%D8%A7%D8%B1%D9%8A%D8%B9-%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-%D8%B9%D9%85%D9%84%D9%8A%D8%A9-%D8%AA%D9%86%D8%A7%D8%B3%D8%A8-%D8%A7%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86-r2185/#:~:text=%D8%AE%D8%B7%D9%88%D8%A7%D8%AA%20%D8%AA%D9%86%D9%81%D9%8A%D8%B0%D9%87%20%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D9%8B%D8%A7.-,%D9%85%D8%B4%D8%B1%D9%88%D8%B9%20%D8%A2%D9%84%D8%A9%20%D8%AD%D8%A7%D8%B3%D8%A8%D8%A9%20%D8%A8%D9%84%D8%BA%D8%A9%20%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86,-%D9%8A%D8%B9%D8%AF%20%D9%85%D8%B4%D8%B1%D9%88%D8%B9%20%D8%AA%D9%86%D9%81%D9%8A%D8%B0" rel="">برنامج آلة حاسبة</a> سنحتاج للتأكد من عمل كل وظيفة بشكل مستقل، فنختبر دالتي الجمع والطرح وغيرها من الدوال الوظيفية اختبارات مستقلة لنضمن سلاسة وسلامة الانتقال للمستوي التالي الذي يدمج عدة عمليات رياضية معًا.
</p>

<h3 id="-">
	اختبار تحويل الأموال في نظام بنكي
</h3>

<p>
	لنفرض أن لدينا نظام بنكي فيه صنف class اسمه <code>BankAccount</code> مسؤول عن إنشاء كائنات حسابات بنكية، ويحتوي تابع method باسم <code>transfer</code> مسؤول عن تحويل الأموال من حساب لآخر.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_5195_10" style=""><span class="kwd">class</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">:</span><span class="pln">
    </span><span class="kwd">def</span><span class="pln"> __init__</span><span class="pun">(</span><span class="pln">self</span><span class="pun">,</span><span class="pln"> balance</span><span class="pun">:</span><span class="pln"> float</span><span class="pun">):</span><span class="pln">
        self</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">=</span><span class="pln"> balance

    </span><span class="com"># دالة لإيداع الأموال</span><span class="pln">
    </span><span class="kwd">def</span><span class="pln"> transfer</span><span class="pun">(</span><span class="pln">self</span><span class="pun">,</span><span class="pln"> target_account</span><span class="pun">,</span><span class="pln"> amount</span><span class="pun">:</span><span class="pln"> float</span><span class="pun">):</span><span class="pln">
        </span><span class="com"># التحقق من أن الحساب ليس مديونًا أو مفلسًا</span><span class="pln">
        </span><span class="kwd">if</span><span class="pln"> amount </span><span class="pun">&lt;=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">:</span><span class="pln">
            </span><span class="kwd">raise</span><span class="pln"> </span><span class="typ">ValueError</span><span class="pun">(</span><span class="str">"ينبغي أن يكون المبلغ أكبر من الصفر."</span><span class="pun">)</span><span class="pln">
        </span><span class="com"># التحقق من أن الرصيد كافي</span><span class="pln">
        </span><span class="kwd">if</span><span class="pln"> self</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">&lt;</span><span class="pln"> amount</span><span class="pun">:</span><span class="pln">
            </span><span class="kwd">raise</span><span class="pln"> </span><span class="typ">ValueError</span><span class="pun">(</span><span class="str">"الرصيد غير كافي"</span><span class="pun">)</span><span class="pln">

        </span><span class="com"># خصم المبلغ من الحساب المرسل</span><span class="pln">
        self</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">-=</span><span class="pln"> amount
        </span><span class="com"># إيداع المبلغ في الحساب المستهدف</span><span class="pln">
        target_account</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">+=</span><span class="pln"> amount</span></pre>

<p>
	نختبر الآن دالة تحويل الأموال في معزل عن باقي النظام باستخدام أداة BlackBox AI، من خلال توليد حالات اختبار مناسبة باستخدام مكتبة pytest لأنها من أبسط المكتبات المتاحة في لغة بايثون لتنفيذ اختبار على مستوى الوحدة، وبما أننا ثبتنا إضافة BlackBox AI في محرر Vscode فستكون موجودة في القائمة الجانبية في يسار المحرر، ونخبرها أن تنشئ ملف اختبار لوظيفة تحويل الأموال بين الحسابات البنكية كما يلي:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_634_7" style=""><span class="pln">&gt; create a test file in python using pytest library to test the method of transfer in BankAccount class @/BankAccount.py</span></pre>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="181748" href="https://academy.hsoub.com/uploads/monthly_2026_03/____001.png.ad821abd1f95501a4d374eae126a5a86.png" rel=""><img alt="توجيه_أداة_الذكاء_الاصطناعي_001.png" class="ipsImage ipsImage_thumbnailed" data-fileid="181748" data-ratio="99.21" data-unique="k96ytdc2l" style="width: 505px; height: auto;" width="605" src="https://academy.hsoub.com/uploads/monthly_2026_03/____001.thumb.png.438b9a7bcffff4bd08f8626ee26ce4d7.png"></a>
</p>

<p>
	نلاحظ أن BlackBoxAI وضعت خطة لتنفيذ الطلب ثم أنشأت ملف <code>test_BanckAccount.py</code> وتطلب مصادقتنا على التغييرات المقترحة والتي يمكن تصفحها قبل الموافقة عليها أو رفضها.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="181749" href="https://academy.hsoub.com/uploads/monthly_2026_03/___002.png.66fc9b4d68c23040f01f298dece41974.png" rel=""><img alt="خطة_التنفيذ_الأولية_002.png" class="ipsImage ipsImage_thumbnailed" data-fileid="181749" data-ratio="45.33" data-unique="78auadkrc" style="width: 600px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2026_03/___002.thumb.png.307b0ad5bad0b2457f3dd4564a461144.png"></a>
</p>

<p>
	بالنظر في ملف <code>test_BanckAccount.py</code> سنجد أن الأداة قد ولدت الشيفرة التالية:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_5195_16" style=""><span class="kwd">import</span><span class="pln"> pytest
</span><span class="kwd">from</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pln"> </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> test_transfer_successful_transfer</span><span class="pun">():</span><span class="pln">
    account1 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">100</span><span class="pun">)</span><span class="pln">
    account2 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">50</span><span class="pun">)</span><span class="pln">
    account1</span><span class="pun">.</span><span class="pln">transfer</span><span class="pun">(</span><span class="pln">account2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">50</span><span class="pun">)</span><span class="pln">
    </span><span class="kwd">assert</span><span class="pln"> account1</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">==</span><span class="pln"> </span><span class="lit">50</span><span class="pln">
    </span><span class="kwd">assert</span><span class="pln"> account2</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">==</span><span class="pln"> </span><span class="lit">100</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> test_transfer_with_zero_amount</span><span class="pun">():</span><span class="pln">
    account1 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">100</span><span class="pun">)</span><span class="pln">
    account2 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">50</span><span class="pun">)</span><span class="pln">
    </span><span class="kwd">with</span><span class="pln"> pytest</span><span class="pun">.</span><span class="pln">raises</span><span class="pun">(</span><span class="typ">ValueError</span><span class="pun">,</span><span class="pln"> match</span><span class="pun">=</span><span class="str">"ينبغي أن يكون المبلغ أكبر من الصفر."</span><span class="pun">):</span><span class="pln">
        account1</span><span class="pun">.</span><span class="pln">transfer</span><span class="pun">(</span><span class="pln">account2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> test_transfer_with_negative_amount</span><span class="pun">():</span><span class="pln">
    account1 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">100</span><span class="pun">)</span><span class="pln">
    account2 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">50</span><span class="pun">)</span><span class="pln">
    </span><span class="kwd">with</span><span class="pln"> pytest</span><span class="pun">.</span><span class="pln">raises</span><span class="pun">(</span><span class="typ">ValueError</span><span class="pun">,</span><span class="pln"> match</span><span class="pun">=</span><span class="str">"ينبغي أن يكون المبلغ أكبر من الصفر."</span><span class="pun">):</span><span class="pln">
        account1</span><span class="pun">.</span><span class="pln">transfer</span><span class="pun">(</span><span class="pln">account2</span><span class="pun">,</span><span class="pln"> </span><span class="pun">-</span><span class="lit">10</span><span class="pun">)</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> test_transfer_with_insufficient_balance</span><span class="pun">():</span><span class="pln">
    account1 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">50</span><span class="pun">)</span><span class="pln">
    account2 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">100</span><span class="pun">)</span><span class="pln">
    </span><span class="kwd">with</span><span class="pln"> pytest</span><span class="pun">.</span><span class="pln">raises</span><span class="pun">(</span><span class="typ">ValueError</span><span class="pun">,</span><span class="pln"> match</span><span class="pun">=</span><span class="str">"الرصيد غير كافي"</span><span class="pun">):</span><span class="pln">
        account1</span><span class="pun">.</span><span class="pln">transfer</span><span class="pun">(</span><span class="pln">account2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">100</span><span class="pun">)</span></pre>

<p>
	نشغل هذا الملف الاختباري بالأمر التالي في <a href="https://academy.hsoub.com/devops/linux/%D8%B4%D8%B1%D8%AD-%D8%AA%D9%85%D9%87%D9%8A%D8%AF%D9%8A-%D9%84%D8%B3%D8%B7%D8%B1-%D8%A3%D9%88%D8%A7%D9%85%D8%B1-%D9%84%D9%8A%D9%86%D9%83%D8%B3-r810/" rel="">سطر الأوامر Terminal</a>
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_5195_18" style=""><span class="pln">pytest test_BankAccount.py</span></pre>

<p>
	ونحصل على الخرج التالي:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_5195_20" style=""><span class="pln">===========================
platform win32 -- Python 3.9.12, pytest-7.1.1, pluggy-1.0.0
rootdir: F:\AI_tools\Article_4
plugins: anyio-3.5.0
collected 4 items

test_BankAccount.py ....
============================= 4 passed in 0.21s =====================[100%]</span></pre>

<p>
	وهكذا نكون قد تجاوزنا جميع الاختبارات بنجاح، لكن هذا لا يعني أن الشيفرة ليست بها مشاكل، فيجب أن نتأكد من اختبار الحالات المتطرفة من الاستخدام edge cases التي قد تتسبب في انهيارها أو حدوث مشاكل فيها، سواء اعتمدنا على أدوات الذكاء الصناعي أو أجرينا الاختبارات يدويًا.
</p>

<p>
	وينبغي أن نسعى لاختبار أكبر عدد ممكن من السيناريوهات لاكتشاف المشاكل مبكرًا -رغم صعوبة التنبؤ بجميع الحالات المسببة للمشاكل- ذلك أن تكلفة معالجة الأخطاء أثناء مرحلة التطوير أقل من تكلفة إصلاحها بعد إطلاق البرنامج نفسه وتفاعل المستخدمين معه.
</p>

<p>
	لذا سنطلب من BlackBoxAI أن يغطي نطاقًا أوسع من حالات الاستخدام مع التركيز على الحالات المتطرفة لضمان استقرار النظام، كما يمكن مناقشته كذلك في حالات اختبار أخرى من من فهمنا لاحتياج النشاط التجاري -البنك في حالتنا- ومراجعة النتائج التي تعود بها علينا للتأكد من مناسبتها لحالة الاستخدام لدينا فلن تعطل وظيفة عاملة بالفعل، فالأداة عرضة للخطأ مهما بلغت من براعة. على سبيل المثال، نريد التأكد من قدرة النظام على التعامل مع الأخطاء غير المتوقعة، مثل فشل عملية تحويل الأموال لأي سبب:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_5195_22" style=""><span class="pln">&gt; I want to test edge cases to ensure all transactions are atomic, especially when a transaction fails. Specifically, I need to verify that the balance remains unchanged if the sending or receiving process fails, using pytest.</span></pre>

<p>
	اقترحت الأداة بعد هذا الموجه إجراء محاكاة عملية لوقوع خطأ بعد خصم مبلغ من حساب المرسل، ويفشل النظام إذا تم الخصم حقًا من حساب المرسل دون أن يستلم الطرف الثاني أي أموال.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_5195_24" style=""><span class="kwd">import</span><span class="pln"> pytest
</span><span class="kwd">from</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pln"> </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> test_transfer_successful_transfer</span><span class="pun">():</span><span class="pln">
    account1 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">100</span><span class="pun">)</span><span class="pln">
    account2 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">50</span><span class="pun">)</span><span class="pln">
    account1</span><span class="pun">.</span><span class="pln">transfer</span><span class="pun">(</span><span class="pln">account2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">50</span><span class="pun">)</span><span class="pln">
    </span><span class="kwd">assert</span><span class="pln"> account1</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">==</span><span class="pln"> </span><span class="lit">50</span><span class="pln">
    </span><span class="kwd">assert</span><span class="pln"> account2</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">==</span><span class="pln"> </span><span class="lit">100</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> test_transfer_with_zero_amount</span><span class="pun">():</span><span class="pln">
    account1 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">100</span><span class="pun">)</span><span class="pln">
    account2 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">50</span><span class="pun">)</span><span class="pln">
    </span><span class="kwd">with</span><span class="pln"> pytest</span><span class="pun">.</span><span class="pln">raises</span><span class="pun">(</span><span class="typ">ValueError</span><span class="pun">,</span><span class="pln"> match</span><span class="pun">=</span><span class="str">"ينبغي أن يكون المبلغ أكبر من الصفر"</span><span class="pun">):</span><span class="pln">
        account1</span><span class="pun">.</span><span class="pln">transfer</span><span class="pun">(</span><span class="pln">account2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> test_transfer_with_negative_amount</span><span class="pun">():</span><span class="pln">
    account1 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">100</span><span class="pun">)</span><span class="pln">
    account2 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">50</span><span class="pun">)</span><span class="pln">
    </span><span class="kwd">with</span><span class="pln"> pytest</span><span class="pun">.</span><span class="pln">raises</span><span class="pun">(</span><span class="typ">ValueError</span><span class="pun">,</span><span class="pln"> match</span><span class="pun">=</span><span class="str">"ينبغي أن يكون المبلغ أكبر من الصفر"</span><span class="pun">):</span><span class="pln">
        account1</span><span class="pun">.</span><span class="pln">transfer</span><span class="pun">(</span><span class="pln">account2</span><span class="pun">,</span><span class="pln"> </span><span class="pun">-</span><span class="lit">10</span><span class="pun">)</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> test_transfer_with_insufficient_balance</span><span class="pun">():</span><span class="pln">
    account1 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">50</span><span class="pun">)</span><span class="pln">
    account2 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">100</span><span class="pun">)</span><span class="pln">
    </span><span class="kwd">with</span><span class="pln"> pytest</span><span class="pun">.</span><span class="pln">raises</span><span class="pun">(</span><span class="typ">ValueError</span><span class="pun">,</span><span class="pln"> match</span><span class="pun">=</span><span class="str">"الرصيد غير كافي"</span><span class="pun">):</span><span class="pln">
        account1</span><span class="pun">.</span><span class="pln">transfer</span><span class="pun">(</span><span class="pln">account2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">100</span><span class="pun">)</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> test_transfer_mid_transaction_failure</span><span class="pun">():</span><span class="pln">
    </span><span class="str">"""
    محاكاة فشل العملية بعد خصم المبلغ وقبل إيداعه.
    السلوك المتوقع: يجب ألا يفقد المرسل المال إذا فشلت العملية.
    """</span><span class="pln">
    account1 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">100</span><span class="pun">)</span><span class="pln">
    account2 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">50</span><span class="pun">)</span><span class="pln">

    </span><span class="com"># إنشاء حساب يحتوي على خطأ محتمل عند محاولة إعادة تعيين الرصيد</span><span class="pln">
    </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">ProblematicAccount</span><span class="pun">:</span><span class="pln">
        </span><span class="kwd">def</span><span class="pln"> __init__</span><span class="pun">(</span><span class="pln">self</span><span class="pun">,</span><span class="pln"> balance</span><span class="pun">):</span><span class="pln">
            self</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">=</span><span class="pln"> balance

        </span><span class="com"># الحصول على الرصيد بشكل آمن</span><span class="pln">
        </span><span class="com"># getter</span><span class="pln">
        </span><span class="lit">@property</span><span class="pln">
        </span><span class="kwd">def</span><span class="pln"> balance</span><span class="pun">(</span><span class="pln">self</span><span class="pun">):</span><span class="pln">
            </span><span class="kwd">return</span><span class="pln"> self</span><span class="pun">.</span><span class="pln">_balance

        </span><span class="com"># تعيين الرصيد بشكل آمن</span><span class="pln">
        </span><span class="com"># setter</span><span class="pln">
        </span><span class="lit">@balance</span><span class="pun">.</span><span class="pln">setter
        </span><span class="kwd">def</span><span class="pln"> balance</span><span class="pun">(</span><span class="pln">self</span><span class="pun">,</span><span class="pln"> value</span><span class="pun">):</span><span class="pln">
            </span><span class="kwd">if</span><span class="pln"> hasattr</span><span class="pun">(</span><span class="pln">self</span><span class="pun">,</span><span class="pln"> </span><span class="str">'_balance'</span><span class="pun">):</span><span class="pln">  </span><span class="com"># إن كانت القيمة معرفة مسبقًا</span><span class="pln">
                </span><span class="kwd">raise</span><span class="pln"> </span><span class="typ">RuntimeError</span><span class="pun">(</span><span class="str">"Unexpected failure before deposit!"</span><span class="pun">)</span><span class="pln">
            self</span><span class="pun">.</span><span class="pln">_balance </span><span class="pun">=</span><span class="pln"> value

    problem_account </span><span class="pun">=</span><span class="pln"> </span><span class="typ">ProblematicAccount</span><span class="pun">(</span><span class="lit">50</span><span class="pun">)</span><span class="pln">

    </span><span class="com"># اختبار نقل الأموال</span><span class="pln">
    </span><span class="kwd">with</span><span class="pln"> pytest</span><span class="pun">.</span><span class="pln">raises</span><span class="pun">(</span><span class="typ">RuntimeError</span><span class="pun">,</span><span class="pln"> match</span><span class="pun">=</span><span class="str">"Unexpected failure before deposit!"</span><span class="pun">):</span><span class="pln">
        account1</span><span class="pun">.</span><span class="pln">transfer</span><span class="pun">(</span><span class="pln">problem_account</span><span class="pun">,</span><span class="pln"> </span><span class="lit">30</span><span class="pun">)</span><span class="pln">

    </span><span class="com"># التحقق من عدم فقدان المرسل للمال بشكل غير متوقع</span><span class="pln">
    </span><span class="kwd">assert</span><span class="pln"> account1</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">==</span><span class="pln"> </span><span class="lit">100</span><span class="pun">,</span><span class="pln"> </span><span class="str">"Sender lost money unexpectedly!"</span><span class="pln">
    </span><span class="kwd">assert</span><span class="pln"> problem_account</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">==</span><span class="pln"> </span><span class="lit">50</span><span class="pun">,</span><span class="pln"> </span><span class="str">"Receiver should not gain money!"</span></pre>

<p>
	ينبغي أن نحصل على الخرج التالي بتشغيل تلك الشيفرة:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_5195_26" style=""><span class="pln">=========================== short test summary info ========================
FAILED test_BankAccount.py::test_transfer_mid_transaction_failure - AssertionError: Sender lost money unexpectedly!
================ 1 failed, 4 passed in 0.14s =================================</span></pre>

<p>
	ندرك بهذا أن الدالة <code>transfer</code> تحتاج للتعديل لتتمكن من التعامل مع حالات الفشل غير المتوقعة، خاصة تحقيق <a href="https://academy.hsoub.com/devops/servers/databases/%D9%85%D9%82%D8%A7%D8%B1%D9%86%D8%A9-%D8%A8%D9%8A%D9%86-mysql-%D9%88-mongodb-r627/#:~:text=%D8%B0%D8%A7%D8%AA%20%D8%A3%D9%85%D8%A7%D9%86%20%D9%82%D9%88%D9%8A.-,%D8%AE%D8%B5%D8%A7%D8%A6%D8%B5%20ACID,-%D8%AA%D8%B9%D8%AF%20%D8%AE%D8%B5%D8%A7%D8%A6%D8%B5%20ACID" rel="">مبدأ الذرية Atomic</a> الذي ينص على أن العملية ينبغي أن تنجح بالكامل أو تفشل بالكامل، ونحقق ذلك بتطبيق آلية للتراجع في حالة حدوث خطأ غير متوقع، انظر الموجه التالي.
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_5195_28" style=""><span class="pln">&gt; Given that failure on the atomicity test case (test_transfer_mid_transaction_failure) ,fix the  BankAccount.py transfer method.</span></pre>

<p>
	ينبغي أن نحصل على الشيفرة المعدلة لملف <code>BankAccount.py</code>
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_5195_30" style=""><span class="kwd">class</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">:</span><span class="pln">
    </span><span class="kwd">def</span><span class="pln"> __init__</span><span class="pun">(</span><span class="pln">self</span><span class="pun">,</span><span class="pln"> balance</span><span class="pun">:</span><span class="pln"> float</span><span class="pun">):</span><span class="pln">
        self</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">=</span><span class="pln"> balance

    </span><span class="kwd">def</span><span class="pln"> transfer</span><span class="pun">(</span><span class="pln">self</span><span class="pun">,</span><span class="pln"> target_account</span><span class="pun">,</span><span class="pln"> amount</span><span class="pun">:</span><span class="pln"> float</span><span class="pun">):</span><span class="pln">
        </span><span class="com"># التحقق من أن الحساب ليس مديونًا أو مفلسًا</span><span class="pln">
        </span><span class="kwd">if</span><span class="pln"> amount </span><span class="pun">&lt;=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">:</span><span class="pln">
            </span><span class="kwd">raise</span><span class="pln"> </span><span class="typ">ValueError</span><span class="pun">(</span><span class="str">"ينبغي أن يكون المبلغ أكبر من الصفر."</span><span class="pun">)</span><span class="pln">
        </span><span class="com"># التحقق من أن الرصيد كافي</span><span class="pln">
        </span><span class="kwd">if</span><span class="pln"> self</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">&lt;</span><span class="pln"> amount</span><span class="pun">:</span><span class="pln">
            </span><span class="kwd">raise</span><span class="pln"> </span><span class="typ">ValueError</span><span class="pun">(</span><span class="str">"الرصيد غير كافي"</span><span class="pun">)</span><span class="pln">

        </span><span class="com"># حفظ الرصيد الحالي في حالة حدوث خطأ</span><span class="pln">
        original_balance </span><span class="pun">=</span><span class="pln"> self</span><span class="pun">.</span><span class="pln">balance

        </span><span class="kwd">try</span><span class="pun">:</span><span class="pln">
            </span><span class="com"># خصم المبلغ من الحساب المرسل</span><span class="pln">
            self</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">-=</span><span class="pln"> amount
            </span><span class="com"># إيداع المبلغ في الحساب المستهدف</span><span class="pln">
            target_account</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">+=</span><span class="pln"> amount
        </span><span class="kwd">except</span><span class="pln"> </span><span class="typ">Exception</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> e</span><span class="pun">:</span><span class="pln">
            </span><span class="com"># استعادة الرصيد الأصلي في حالة حدوث خطأ</span><span class="pln">
            self</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">=</span><span class="pln"> original_balance
            </span><span class="com"># إعادة رفع الاستثناء</span><span class="pln">
            </span><span class="kwd">raise</span><span class="pln"> e</span></pre>

<p>
	نستخدم في الشيفرة المعدلة آلية استرجاع Rollback في حال حدوث خطأ في عملية التحويل لئلا تتغير أرصدة الحسابات، مما يضمن بقائها متزامنة وسليمة. نحصل على الخرج التالي عند تشغيل الاختبار:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_5195_32" style=""><span class="pln">================================ test session starts ==============
platform win32 -- Python 3.9.12, pytest-7.1.1, pluggy-1.0.0
rootdir: F:\Article_4
plugins: anyio-3.5.0
collected 5 items

test_BankAccount.py .....                                                                                                 [100%]
====================== 5 passed in 0.03s=========================</span></pre>

<h2 id="-">
	اختبار الانحدار
</h2>

<p>
	اختبار الانحدار Regression test هو نوع من اختبارات البرامج Software testing يستخدم لضمان أن تحديث الشيفرة لا يضر بأي وظيفة كانت تعمل سابقًا، وينفذ عادة بعد تطوير وظائف جديدة أو إصلاح أحد <a href="https://academy.hsoub.com/programming/general/%D9%83%D9%8A%D9%81-%D8%AA%D8%AA%D8%B9%D8%A7%D9%85%D9%84-%D9%85%D8%B9-%D8%A7%D9%84%D8%A3%D8%AE%D8%B7%D8%A7%D8%A1-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D8%A9%D8%9F-r2016/" rel="">الأخطاء البرمجية</a>، فإذا أردنا إضافة ميزة جديدة للنظام البنكي مثل فرض رسوم على التحويلات، سنطور هذه الميزة ونختبرها لنتأكد من أنها لم تُحدث انحدارًا في التطبيق الموجود، أي ينبغي أن تظل كل المزايا الأخرى وحالات الاختبار تعمل بكفاءة.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_5195_34" style=""><span class="kwd">class</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">:</span><span class="pln">
    </span><span class="kwd">def</span><span class="pln"> __init__</span><span class="pun">(</span><span class="pln">self</span><span class="pun">,</span><span class="pln"> balance</span><span class="pun">:</span><span class="pln"> float</span><span class="pun">,</span><span class="pln"> fee_percentage</span><span class="pun">:</span><span class="pln"> float </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">):</span><span class="pln">
        self</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">=</span><span class="pln"> balance
        self</span><span class="pun">.</span><span class="pln">fee_percentage </span><span class="pun">=</span><span class="pln"> fee_percentage

    </span><span class="kwd">def</span><span class="pln"> transfer</span><span class="pun">(</span><span class="pln">self</span><span class="pun">,</span><span class="pln"> target_account</span><span class="pun">,</span><span class="pln"> amount</span><span class="pun">:</span><span class="pln"> float</span><span class="pun">):</span><span class="pln">
        </span><span class="com"># التحقق من أن الحساب ليس مديونًا أو مفلسًا</span><span class="pln">
        </span><span class="kwd">if</span><span class="pln"> amount </span><span class="pun">&lt;=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">:</span><span class="pln">
            </span><span class="kwd">raise</span><span class="pln"> </span><span class="typ">ValueError</span><span class="pun">(</span><span class="str">"ينبغي أن يكون المبلغ أكبر من الصفر."</span><span class="pun">)</span><span class="pln">
        </span><span class="com"># حساب الرسوم المفروضة</span><span class="pln">
        fee </span><span class="pun">=</span><span class="pln"> self</span><span class="pun">.</span><span class="pln">get_fee_amount</span><span class="pun">(</span><span class="pln">amount</span><span class="pun">)</span><span class="pln">
        total_amount </span><span class="pun">=</span><span class="pln"> amount </span><span class="pun">+</span><span class="pln"> fee

        </span><span class="com"># التحقق من أن الرصيد كافي</span><span class="pln">
        </span><span class="com"># مضيفين الرسوم إلى تكلفة التحويل</span><span class="pln">
        </span><span class="kwd">if</span><span class="pln"> self</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">&lt;</span><span class="pln"> total_amount</span><span class="pun">:</span><span class="pln">
            </span><span class="kwd">raise</span><span class="pln"> </span><span class="typ">ValueError</span><span class="pun">(</span><span class="str">"الرصيد غير كافي"</span><span class="pun">)</span><span class="pln">

        </span><span class="com"># حفظ الرصيد الحالي في حالة حدوث خطأ</span><span class="pln">
        original_balance </span><span class="pun">=</span><span class="pln"> self</span><span class="pun">.</span><span class="pln">balance

        </span><span class="kwd">try</span><span class="pun">:</span><span class="pln">
            </span><span class="com"># خصم المبلغ من الحساب المرسل</span><span class="pln">
            self</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">-=</span><span class="pln"> total_amount
            </span><span class="com"># إيداع المبلغ في الحساب المستهدف</span><span class="pln">
            </span><span class="com"># لا نودع إلا المبلغ المرسل فقد بدون الرسوم</span><span class="pln">
            target_account</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">+=</span><span class="pln"> amount
        </span><span class="kwd">except</span><span class="pln"> </span><span class="typ">Exception</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> e</span><span class="pun">:</span><span class="pln">
            </span><span class="com"># استعادة الرصيد الأصلي في حالة حدوث خطأ</span><span class="pln">
            self</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">=</span><span class="pln"> original_balance
            </span><span class="com"># إعادة رفع الاستثناء</span><span class="pln">
            </span><span class="kwd">raise</span><span class="pln"> e
    </span><span class="kwd">def</span><span class="pln"> get_fee_amount</span><span class="pun">(</span><span class="pln">self</span><span class="pun">,</span><span class="pln"> transfer_amount</span><span class="pun">:</span><span class="pln"> float</span><span class="pun">):</span><span class="pln">
        </span><span class="str">"""حساب مبلغ الرسوم لتحويل معين"""</span><span class="pln">
        </span><span class="kwd">return</span><span class="pln"> transfer_amount </span><span class="pun">*</span><span class="pln"> self</span><span class="pun">.</span><span class="pln">fee_percentage </span><span class="pun">/</span><span class="pln"> </span><span class="lit">100</span></pre>

<p>
	نحتاج لاختبار الميزة الجديدة لنتأكد من عمل الوظائف السابقة أولًا، حيث نختبر الحالة التي تكون الرسوم فيها 0% ثم اختبار التحويل حين تكون الرسوم أكبر من الصفر -2% مثلًا-، ونوجه BlackBoxAI حينئذ لتوليد ملف يختبر عمل الوظائف السابقة بالإضافة لاختبار الحالات الجديدة. لنستخدم <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A3%D9%81%D8%B6%D9%84-%D9%85%D9%85%D8%A7%D8%B1%D8%B3%D8%A7%D8%AA-%D9%87%D9%86%D8%AF%D8%B3%D8%A9-%D8%A7%D9%84%D9%85%D9%8F%D9%88%D8%AC%D9%91%D9%90%D9%87%D8%A7%D8%AA/" rel="">الموجه</a> التالي:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_5195_38" style=""><span class="pln">&gt; Create a regression test for the newly implemented fee feature on money transfers. Ensure the test verifies that the new functionality works as expected, while also confirming that existing features remain unaffected.</span></pre>

<p>
	ينبغي أن نحصل على ملف اختبار يكون كما يلي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_5195_40" style=""><span class="kwd">import</span><span class="pln"> pytest
</span><span class="kwd">from</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pln"> </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pln">

</span><span class="com"># ---------- اختبارات الانحدار (Regression Tests) ----------</span><span class="pln">
</span><span class="com"># هذه هي الاختبارات الموجودة مسبقًا للتأكد من أن الوظائف الأساسية ما زالت تعمل</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> test_transfer_successful_transfer</span><span class="pun">():</span><span class="pln">
    account1 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">100</span><span class="pun">)</span><span class="pln">
    account2 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">50</span><span class="pun">)</span><span class="pln">
    account1</span><span class="pun">.</span><span class="pln">transfer</span><span class="pun">(</span><span class="pln">account2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">50</span><span class="pun">)</span><span class="pln">
    </span><span class="kwd">assert</span><span class="pln"> account1</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">==</span><span class="pln"> </span><span class="lit">50</span><span class="pln">
    </span><span class="kwd">assert</span><span class="pln"> account2</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">==</span><span class="pln"> </span><span class="lit">100</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> test_transfer_with_zero_amount</span><span class="pun">():</span><span class="pln">
    account1 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">100</span><span class="pun">)</span><span class="pln">
    account2 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">50</span><span class="pun">)</span><span class="pln">
    </span><span class="kwd">with</span><span class="pln"> pytest</span><span class="pun">.</span><span class="pln">raises</span><span class="pun">(</span><span class="typ">ValueError</span><span class="pun">,</span><span class="pln"> match</span><span class="pun">=</span><span class="str">"ينبغي أن يكون المبلغ أكبر من الصفر."</span><span class="pun">):</span><span class="pln">
        account1</span><span class="pun">.</span><span class="pln">transfer</span><span class="pun">(</span><span class="pln">account2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> test_transfer_with_negative_amount</span><span class="pun">():</span><span class="pln">
    account1 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">100</span><span class="pun">)</span><span class="pln">
    account2 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">50</span><span class="pun">)</span><span class="pln">
    </span><span class="kwd">with</span><span class="pln"> pytest</span><span class="pun">.</span><span class="pln">raises</span><span class="pun">(</span><span class="typ">ValueError</span><span class="pun">,</span><span class="pln"> match</span><span class="pun">=</span><span class="str">"ينبغي أن يكون المبلغ أكبر من الصفر"</span><span class="pun">):</span><span class="pln">
        account1</span><span class="pun">.</span><span class="pln">transfer</span><span class="pun">(</span><span class="pln">account2</span><span class="pun">,</span><span class="pln"> </span><span class="pun">-</span><span class="lit">10</span><span class="pun">)</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> test_transfer_with_insufficient_balance</span><span class="pun">():</span><span class="pln">
    account1 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">50</span><span class="pun">)</span><span class="pln">
    account2 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">100</span><span class="pun">)</span><span class="pln">
    </span><span class="kwd">with</span><span class="pln"> pytest</span><span class="pun">.</span><span class="pln">raises</span><span class="pun">(</span><span class="typ">ValueError</span><span class="pun">,</span><span class="pln"> match</span><span class="pun">=</span><span class="str">"الرصيد غير كافي"</span><span class="pun">):</span><span class="pln">
        account1</span><span class="pun">.</span><span class="pln">transfer</span><span class="pun">(</span><span class="pln">account2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">100</span><span class="pun">)</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> test_transfer_mid_transaction_failure</span><span class="pun">():</span><span class="pln">
    </span><span class="str">"""
    محاكاة فشل العملية بعد خصم المبلغ وقبل إيداعه.
    السلوك المتوقع: يجب ألا يفقد المرسل المال إذا فشلت العملية.
    """</span><span class="pln">
    account1 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">100</span><span class="pun">)</span><span class="pln">

    </span><span class="com"># إنشاء حساب يحتوي على خطأ محتمل عند محاولة إعادة تعيين الرصيد</span><span class="pln">
    </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">ProblematicAccount</span><span class="pun">:</span><span class="pln">
        </span><span class="kwd">def</span><span class="pln"> __init__</span><span class="pun">(</span><span class="pln">self</span><span class="pun">,</span><span class="pln"> balance</span><span class="pun">):</span><span class="pln">
            self</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">=</span><span class="pln"> balance

        </span><span class="com"># الحصول على الرصيد بشكل آمن</span><span class="pln">
        </span><span class="lit">@property</span><span class="pln">
        </span><span class="kwd">def</span><span class="pln"> balance</span><span class="pun">(</span><span class="pln">self</span><span class="pun">):</span><span class="pln">
            </span><span class="kwd">return</span><span class="pln"> self</span><span class="pun">.</span><span class="pln">_balance

        </span><span class="com"># تعيين الرصيد بشكل آمن</span><span class="pln">
        </span><span class="lit">@balance</span><span class="pun">.</span><span class="pln">setter
        </span><span class="kwd">def</span><span class="pln"> balance</span><span class="pun">(</span><span class="pln">self</span><span class="pun">,</span><span class="pln"> value</span><span class="pun">):</span><span class="pln">
            </span><span class="kwd">if</span><span class="pln"> hasattr</span><span class="pun">(</span><span class="pln">self</span><span class="pun">,</span><span class="pln"> </span><span class="str">'_balance'</span><span class="pun">):</span><span class="pln">  </span><span class="com"># إن كانت القيمة معرفة مسبقًا</span><span class="pln">
                </span><span class="kwd">raise</span><span class="pln"> </span><span class="typ">RuntimeError</span><span class="pun">(</span><span class="str">"Unexpected failure before deposit!"</span><span class="pun">)</span><span class="pln">
            self</span><span class="pun">.</span><span class="pln">_balance </span><span class="pun">=</span><span class="pln"> value

    problem_account </span><span class="pun">=</span><span class="pln"> </span><span class="typ">ProblematicAccount</span><span class="pun">(</span><span class="lit">50</span><span class="pun">)</span><span class="pln">

    </span><span class="com"># اختبار نقل الأموال</span><span class="pln">
    </span><span class="kwd">with</span><span class="pln"> pytest</span><span class="pun">.</span><span class="pln">raises</span><span class="pun">(</span><span class="typ">RuntimeError</span><span class="pun">,</span><span class="pln"> match</span><span class="pun">=</span><span class="str">"Unexpected failure before deposit!"</span><span class="pun">):</span><span class="pln">
        account1</span><span class="pun">.</span><span class="pln">transfer</span><span class="pun">(</span><span class="pln">problem_account</span><span class="pun">,</span><span class="pln"> </span><span class="lit">30</span><span class="pun">)</span><span class="pln">

    </span><span class="com"># التحقق من عدم فقدان المرسل للمال بشكل غير متوقع</span><span class="pln">
    </span><span class="kwd">assert</span><span class="pln"> account1</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">==</span><span class="pln"> </span><span class="lit">100</span><span class="pun">,</span><span class="pln"> </span><span class="str">"Sender lost money unexpectedly!"</span><span class="pln">
    </span><span class="kwd">assert</span><span class="pln"> problem_account</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">==</span><span class="pln"> </span><span class="lit">50</span><span class="pun">,</span><span class="pln"> </span><span class="str">"Receiver should not gain money!"</span><span class="pln">

</span><span class="com"># ---------- اختبارات الميزة الجديدة (New Feature Tests) ----------</span><span class="pln">
</span><span class="com"># اختبارات للتحقق من ميزة رسوم التحويل الجديدة</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> test_transfer_with_fee</span><span class="pun">():</span><span class="pln">
    </span><span class="str">"""اختبار التحويل مع وجود رسوم"""</span><span class="pln">
    </span><span class="com"># %إنشاء حساب مع رسوم 2</span><span class="pln">
    account1 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">100</span><span class="pun">,</span><span class="pln"> fee_percentage</span><span class="pun">=</span><span class="lit">2</span><span class="pun">)</span><span class="pln">
    account2 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">50</span><span class="pun">)</span><span class="pln">

    </span><span class="com"># تحويل 50 وحدة مع رسوم 1</span><span class="pln">
    account1</span><span class="pun">.</span><span class="pln">transfer</span><span class="pun">(</span><span class="pln">account2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">50</span><span class="pun">)</span><span class="pln">

    </span><span class="com"># التحقق من الأرصدة</span><span class="pln">
    </span><span class="kwd">assert</span><span class="pln"> account1</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">==</span><span class="pln"> </span><span class="lit">49</span><span class="pun">,</span><span class="pln"> </span><span class="str">"Should be 100 - 50 - 1(fee) = 49"</span><span class="pln">
    </span><span class="kwd">assert</span><span class="pln"> account2</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">==</span><span class="pln"> </span><span class="lit">100</span><span class="pun">,</span><span class="pln"> </span><span class="str">"Should be 50 + 50 = 100"</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> test_transfer_with_fee_insufficient_balance</span><span class="pun">():</span><span class="pln">
    </span><span class="str">"""اختبار فشل التحويل عند عدم كفاية الرصيد لتغطية المبلغ والرسوم"""</span><span class="pln">
    </span><span class="com"># إنشاء حساب مع رسوم %10</span><span class="pln">
    account1 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">100</span><span class="pun">,</span><span class="pln"> fee_percentage</span><span class="pun">=</span><span class="lit">10</span><span class="pun">)</span><span class="pln">
    account2 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">50</span><span class="pun">)</span><span class="pln">

    </span><span class="com"># محاولة تحويل مبلغ 95 يتطلب مبلغ 9.5 إضافي للرسوم</span><span class="pln">
    </span><span class="kwd">with</span><span class="pln"> pytest</span><span class="pun">.</span><span class="pln">raises</span><span class="pun">(</span><span class="typ">ValueError</span><span class="pun">,</span><span class="pln"> match</span><span class="pun">=</span><span class="str">"الرصيد غير كافي"</span><span class="pun">):</span><span class="pln">
        account1</span><span class="pun">.</span><span class="pln">transfer</span><span class="pun">(</span><span class="pln">account2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">95</span><span class="pun">)</span><span class="pln">

    </span><span class="com"># التحقق من عدم تغيير الأرصدة</span><span class="pln">
    </span><span class="kwd">assert</span><span class="pln"> account1</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">==</span><span class="pln"> </span><span class="lit">100</span><span class="pln">
    </span><span class="kwd">assert</span><span class="pln"> account2</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">==</span><span class="pln"> </span><span class="lit">50</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> test_get_fee_amount</span><span class="pun">():</span><span class="pln">
    </span><span class="str">"""اختبار حساب مبلغ الرسوم"""</span><span class="pln">
    account </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">1000</span><span class="pun">,</span><span class="pln"> fee_percentage</span><span class="pun">=</span><span class="lit">2.5</span><span class="pun">)</span><span class="pln">

    fee </span><span class="pun">=</span><span class="pln"> account</span><span class="pun">.</span><span class="pln">get_fee_amount</span><span class="pun">(</span><span class="lit">200</span><span class="pun">)</span><span class="pln">
    </span><span class="kwd">assert</span><span class="pln"> fee </span><span class="pun">==</span><span class="pln"> </span><span class="lit">5</span><span class="pun">,</span><span class="pln"> </span><span class="str">"2.5% of 200 should be 5"</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> test_zero_fee_percentage</span><span class="pun">():</span><span class="pln">
    </span><span class="str">"""اختبار أن الحساب يعمل بشكل طبيعي عندما تكون الرسوم صفرًا"""</span><span class="pln">
    account1 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">100</span><span class="pun">,</span><span class="pln"> fee_percentage</span><span class="pun">=</span><span class="lit">0</span><span class="pun">)</span><span class="pln">
    account2 </span><span class="pun">=</span><span class="pln"> </span><span class="typ">BankAccount</span><span class="pun">(</span><span class="lit">50</span><span class="pun">)</span><span class="pln">

    account1</span><span class="pun">.</span><span class="pln">transfer</span><span class="pun">(</span><span class="pln">account2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">50</span><span class="pun">)</span><span class="pln">

    </span><span class="kwd">assert</span><span class="pln"> account1</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">==</span><span class="pln"> </span><span class="lit">50</span><span class="pln">
    </span><span class="kwd">assert</span><span class="pln"> account2</span><span class="pun">.</span><span class="pln">balance </span><span class="pun">==</span><span class="pln"> </span><span class="lit">100</span></pre>

<p>
	بتشغيل ملف الاختبار نجد أنه تجاوز جميع الاختبارات، مما يعني أن الميزة المضافة لم تتسبب في إفساد الميزات الموجودة مسبقًا بالنظام.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="181752" href="https://academy.hsoub.com/uploads/monthly_2026_03/____003.png.12d046377480810b49a0a45e85e4d2e6.png" rel=""><img alt="خطة_تنفيذ_اختبار_الانحدار_003.png" class="ipsImage ipsImage_thumbnailed" data-fileid="181752" data-ratio="39.17" data-unique="3q9mihgqt" style="width: 600px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2026_03/____003.thumb.png.0399eea649f1804ad8dbe5713686d847.png"></a>
</p>

<h2 id="-">
	اختبارات الأداء
</h2>

<p>
	تعد اختبارات الأداء Performance tests أحد الطرق الكمية لقياس المتطلبات غير الوظيفية non-functional requirements مثل قدرة تحمل التطبيق وسرعته في التحميل أو عدد المستخدمين الذين يستطيع التعامل معهم وغيرها من المعايير التي تساعدنا في تحديد حدود الاستخدام المناسبة للتطبيق وتحديد حاجتنا للموارد الحاسوبية من ذاكرة وصول عشوائي RAM أو CPU أو مساحة تخزين.
</p>

<h3 id="-performance-test">
	أنواع اختبارات الأداء Performance test
</h3>

<ul>
	<li>
		<p>
			اختبار الحمل Load test : يقيس أداء النظام تحت الظروف المتوقعة أو الطبيعية وسرعة الرد واستخدام الموارد
		</p>
	</li>
	<li>
		<p>
			اختبار الضغط Stress test : يختبر حدود النظام بتعريضه لحمل أكبر من المتوقع أو الطبيعي، لمعرفة مدى استقرار النظام ونقاط الفشل وقدرة النظام على التعافي
		</p>
	</li>
	<li>
		<p>
			اختبار الحمل المفاجئ Spike test : يختبر أداء النظام تحت حمل عالي ومفاجئ، ويختبر قدرته على التوسع السريع scale up والتعامل مع الضغط المفاجئ
		</p>
	</li>
</ul>

<h3 id="-">
	اختبار الحمل في نظام إدارة مخزون
</h3>

<p>
	نفترض أن لدينا نظام إدارة مخزون Inventory بسيط يعمل من خلال <a href="https://academy.hsoub.com/programming/general/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D8%A7%D9%84%D9%88%D8%A7%D8%AC%D9%87%D8%A7%D8%AA-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D8%A9-api-r1314/" rel="">واجهة تطبيق برمجية <abbr title="Application Programming Interface | واجهة برمجية"><abbr title="Application Programming Interface | واجهة برمجية">API</abbr></abbr></a> مبنية بمكتبة FastAPI ويرتبط بقاعدة بيانات بسيطة من نوع Sqlite تحفظ العناصر وكميتها في جدول.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_5195_43" style=""><span class="kwd">import</span><span class="pln"> sqlite3
</span><span class="kwd">from</span><span class="pln"> fastapi </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">FastAPI</span><span class="pln">

app </span><span class="pun">=</span><span class="pln"> </span><span class="typ">FastAPI</span><span class="pun">()</span><span class="pln">

</span><span class="com"># تهيئة قاعدة البيانات</span><span class="pln">
</span><span class="kwd">def</span><span class="pln"> init_db</span><span class="pun">():</span><span class="pln">
    conn </span><span class="pun">=</span><span class="pln"> sqlite3</span><span class="pun">.</span><span class="pln">connect</span><span class="pun">(</span><span class="str">"inventory.db"</span><span class="pun">)</span><span class="pln">
    cursor </span><span class="pun">=</span><span class="pln"> conn</span><span class="pun">.</span><span class="pln">cursor</span><span class="pun">()</span><span class="pln">

    </span><span class="com"># إنشاء جدول البيانات إذا لم يكن موجودًا</span><span class="pln">
    cursor</span><span class="pun">.</span><span class="pln">execute</span><span class="pun">(</span><span class="str">"CREATE TABLE IF NOT EXISTS inventory (id INTEGER PRIMARY KEY, name TEXT, quantity INTEGER)"</span><span class="pun">)</span><span class="pln">

    </span><span class="com"># إضافة بيانات افتراضية إذا كانت الجدول فارغة</span><span class="pln">
    cursor</span><span class="pun">.</span><span class="pln">execute</span><span class="pun">(</span><span class="str">"SELECT COUNT(*) FROM inventory"</span><span class="pun">)</span><span class="pln">
    </span><span class="kwd">if</span><span class="pln"> cursor</span><span class="pun">.</span><span class="pln">fetchone</span><span class="pun">()[</span><span class="lit">0</span><span class="pun">]</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> </span><span class="lit">0</span><span class="pun">:</span><span class="pln">
        sample_data </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="pln">
            </span><span class="pun">(</span><span class="str">"Laptop"</span><span class="pun">,</span><span class="pln"> </span><span class="lit">10</span><span class="pun">),</span><span class="pln">
            </span><span class="pun">(</span><span class="str">"Keyboard"</span><span class="pun">,</span><span class="pln"> </span><span class="lit">25</span><span class="pun">),</span><span class="pln">
            </span><span class="pun">(</span><span class="str">"Mouse"</span><span class="pun">,</span><span class="pln"> </span><span class="lit">30</span><span class="pun">),</span><span class="pln">
            </span><span class="pun">(</span><span class="str">"Monitor"</span><span class="pun">,</span><span class="pln"> </span><span class="lit">15</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">]</span><span class="pln">
        cursor</span><span class="pun">.</span><span class="pln">executemany</span><span class="pun">(</span><span class="str">"INSERT INTO inventory (name, quantity) VALUES (?, ?)"</span><span class="pun">,</span><span class="pln"> sample_data</span><span class="pun">)</span><span class="pln">
        conn</span><span class="pun">.</span><span class="pln">commit</span><span class="pun">()</span><span class="pln">

    conn</span><span class="pun">.</span><span class="pln">close</span><span class="pun">()</span><span class="pln">

init_db</span><span class="pun">()</span><span class="pln">  </span><span class="com"># تهيئة كائن قاعدة البيانات</span><span class="pln">

</span><span class="com"># دالة لجلب العناصر الموجودة بالمخزون</span><span class="pln">
</span><span class="lit">@app</span><span class="pun">.</span><span class="pln">get</span><span class="pun">(</span><span class="str">"/inventory"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">def</span><span class="pln"> get_inventory</span><span class="pun">():</span><span class="pln">
    conn </span><span class="pun">=</span><span class="pln"> sqlite3</span><span class="pun">.</span><span class="pln">connect</span><span class="pun">(</span><span class="str">"inventory.db"</span><span class="pun">)</span><span class="pln">
    cursor </span><span class="pun">=</span><span class="pln"> conn</span><span class="pun">.</span><span class="pln">cursor</span><span class="pun">()</span><span class="pln">
    cursor</span><span class="pun">.</span><span class="pln">execute</span><span class="pun">(</span><span class="str">"SELECT * FROM inventory"</span><span class="pun">)</span><span class="pln">
    items </span><span class="pun">=</span><span class="pln"> cursor</span><span class="pun">.</span><span class="pln">fetchall</span><span class="pun">()</span><span class="pln">
    conn</span><span class="pun">.</span><span class="pln">close</span><span class="pun">()</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> </span><span class="pun">{</span><span class="str">"inventory"</span><span class="pun">:</span><span class="pln"> items</span><span class="pun">}</span></pre>

<p>
	لتشغيل هذا التطبيق نكتب في الطرفية الأمر التالي :
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_5195_45" style=""><span class="pln">uvicorn inventory_api:app --reload</span></pre>

<p>
	بهذا تصبح واجهة التطبيق البرمجية <abbr title="Application Programming Interface | واجهة برمجية"><abbr title="Application Programming Interface | واجهة برمجية">API</abbr></abbr> تعمل وجاهزة للاستخدام من خلال الرابط المحلي <code>http://127.0.0.1:8000/inventory</code>، أو الرابط <code>http://127.0.0.1:8000/docs#/default/get_inventory_inventory_get</code> الذي يسمح لنا بتجربة نقاط النهاية End-points للواجهة البرمجية <abbr title="Application Programming Interface | واجهة برمجية"><abbr title="Application Programming Interface | واجهة برمجية">API</abbr></abbr> باستخدام واجهة صفحة ويب.
</p>

<p>
	نوجه BlackBoxAI بعدها لتوليد ملف اختبار أداء باستخدام مكتبة Locust والتي ستسمح لنا باختبار واجهة التطبيق البرمجية <abbr title="Application Programming Interface | واجهة برمجية"><abbr title="Application Programming Interface | واجهة برمجية">API</abbr></abbr> بمحاكاة استخدام عدد كبيرة من المستخدمين النظام في نفس الوقت وتساعد في تحليل أداء النظام بعرض رسومات بيانية توضح سرعة الرد وعدد مرات الفشل مقارنة بعدد الطلبات التي نفذها النظام بنجاح وغيرها من المزايا الأخرى.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_5195_47" style=""><span class="kwd">from</span><span class="pln"> locust </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">HttpUser</span><span class="pun">,</span><span class="pln"> task</span><span class="pun">,</span><span class="pln"> between

</span><span class="kwd">class</span><span class="pln"> </span><span class="typ">InventoryUser</span><span class="pun">(</span><span class="typ">HttpUser</span><span class="pun">):</span><span class="pln">
    wait_time </span><span class="pun">=</span><span class="pln"> between</span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2</span><span class="pun">)</span><span class="pln">  </span><span class="com"># كل مستخدم ينتظر بين 1-2 ثانية بين الطلبات</span><span class="pln">

    </span><span class="str">""" inventory محاكاة أكثر من مستخدم يتصل بنقطة النهاية """</span><span class="pln">

    </span><span class="lit">@task</span><span class="pln">
    </span><span class="kwd">def</span><span class="pln"> load_test_inventory</span><span class="pun">(</span><span class="pln">self</span><span class="pun">):</span><span class="pln">
        </span><span class="pun">‫</span><span class="str">"""مستخدم افتراضي يقوم بطلب رابط inventory بشكل متكرر"""</span><span class="pln">
        response </span><span class="pun">=</span><span class="pln"> self</span><span class="pun">.</span><span class="pln">client</span><span class="pun">.</span><span class="pln">get</span><span class="pun">(</span><span class="str">"/inventory"</span><span class="pun">)</span><span class="pln">
        </span><span class="kwd">if</span><span class="pln"> response</span><span class="pun">.</span><span class="pln">status_code </span><span class="pun">!=</span><span class="pln"> </span><span class="lit">200</span><span class="pun">:</span><span class="pln">
            response</span><span class="pun">.</span><span class="pln">failure</span><span class="pun">(</span><span class="str">"Failed to fetch inventory"</span><span class="pun">)</span></pre>

<p>
	نشغل الأمر التالي من خلال الطرفية، حيث نمرر اسم الملف والرابط المحلي المؤدي للموقع.
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_5195_49" style=""><span class="pln">locust -f load_test.py --host=http://127.0.0.1:8000</span></pre>

<p>
	سنحصل على الرابط التالي <code><a href="http://localhost:8089" ipsnoembed="false" rel="external nofollow">http://localhost:8089</a></code> لتجربة أداة الاختبار، حيث نجد عند فتح الصفحة بعض المدخلات التي نستطيع التحكم فيها، مثل عدد المستخدمين، وتزايد ذلك العدد في كل ثانية Ramp up حيث أن أداة الاختبار تضيف هذا العدد من المستخدمين كل ثانية حتى تصل لعدد المستخدمين الأقصى بشكل تدريجي، سنضبط عدد المستخدمين ليكون 1000 مستخدم، ومعدل تزايد المستخدمين ليكون 10 في الثانية.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="181753" href="https://academy.hsoub.com/uploads/monthly_2026_03/__004.png.697f817638196e0a2adbd8ad0170ad29.png" rel=""><img alt="إعدادات_المحاكاة_004.png" class="ipsImage ipsImage_thumbnailed" data-fileid="181753" data-ratio="55.67" data-unique="fgxdxcpt6" style="width: 600px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2026_03/__004.thumb.png.de401f95c38b451fd9093e987723d8f8.png"></a>
</p>

<p>
	نرى هنا الإحصائيات المولدة في الوقت الحقيقي، حيث يرينا الرسم البياني الأول عدد الطلبات المرسلة لواجهة التطبيق البرمجية <abbr title="Application Programming Interface | واجهة برمجية"><abbr title="Application Programming Interface | واجهة برمجية">API</abbr></abbr> في كل ثانية، بينما يظهر الرسم الثاني سرعة تجاوب النظام، أما الرسم الثالث فيظهر عدد المستخدمين الذي ازداد تدريجيًا حتى وصل للحد الأقصى المحدد مسبقًا، ونلاحظ أن النظام كان قادرًا على التعامل مع ألف مستخدم بسهولة ومع عدد من الطلبات يصل إلى 650 طلب في الثانية بدون أي فشل في إجابة الطلبات المرسلة للواجهة البرمجية للتطبيق <abbr title="Application Programming Interface | واجهة برمجية"><abbr title="Application Programming Interface | واجهة برمجية">API</abbr></abbr>.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="181754" href="https://academy.hsoub.com/uploads/monthly_2026_03/__005.png.ad39d1886ac76c5867abcd1b886fad2c.png" rel=""><img alt="احصائيات_الأداء_005.png" class="ipsImage ipsImage_thumbnailed" data-fileid="181754" data-ratio="86.80" data-unique="qsu52rdo5" style="width: 591px; height: auto;" width="691" src="https://academy.hsoub.com/uploads/monthly_2026_03/__005.thumb.png.d23d6084de1f6e265a7c22392ed7712d.png"></a>
</p>

<p>
	يمكننا تعريض النظام لمستوى أعلى من الضغط لنرى نسبة الفشل في إجابة الطلبات، بأن نجعل عدد المستخدمين 100 ألف مثلًا، يزيدون بمعدل 1000 في كل مرة، سيزيد احتمال حدوث الفشل لعجز نظامنا على التعامل مع هذا الكم من الضغط.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="181755" href="https://academy.hsoub.com/uploads/monthly_2026_03/__006.png.e8af56b85a6427ef3077a378e5ab9bf5.png" rel=""><img alt="احصائيات_الفشل_006.png" class="ipsImage ipsImage_thumbnailed" data-fileid="181755" data-ratio="86.80" data-unique="l6b2p5673" style="width: 591px; height: auto;" width="691" src="https://academy.hsoub.com/uploads/monthly_2026_03/__006.thumb.png.38be01aa940d201773d30567bf9b0ecb.png"></a>
</p>

<p>
	وصلت نسبة الفشل إلى 88% حيث فشل 332008 طلب من أصل 377561، وكان متوسط سرعة الإجابة 174 ثانية، وهذا وقت طويل يدل أن النظام لم يستطع تحمل الزيادة في الحمل، كما نرى من الرسومات البيانية الموضحة بالأعلى أن النظام بدأ في التدهور عندما تجاوز عدد المستخدمين 50 ألف تقريبًا، هذه المعلومات تمكننا من تحسين كفاءة النظام تحت الضغط بإجراءات مثل تحجيم عدد الطلبات المسموح للمستخدم إرسالها في فترة زمنية محددة، واستخدام <a href="https://academy.hsoub.com/programming/general/%D9%87%D9%8A%D8%A7%D9%83%D9%84-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-data-structures/#:~:text=underflow%20%5C(%D9%82%D8%B9%D8%B1%20%D8%A7%D9%84%D9%85%D9%83%D8%AF%D8%B3%5C" rel="">رتل Queue</a> لتخزين الطلبات الفائضة عن سعة النظام لتعالج عندما يستطيع النظام استيعاب المزيد من الطلبات، فبدلًا من محاولة معالجة 100 ألف طلب نستطيع تخزين الطلبات في رتل Queue وندفع الطلبات للنظام على هيئة دفعات كل دفعة تتكون من 10000 طلب فقط.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="181756" href="https://academy.hsoub.com/uploads/monthly_2026_03/__007.png.4cf2fd03c0a5a33a3dba682407c34149.png" rel=""><img alt="ملخص_الاحصائيات_007.png" class="ipsImage ipsImage_thumbnailed" data-fileid="181756" data-ratio="30.50" data-unique="of7q2vet0" style="width: 600px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2026_03/__007.thumb.png.aa78950e7e78ee9a99cafd437bfaf7a3.png"></a>
</p>

<h2 id="-">
	خاتمة
</h2>

<p>
	تعرفنا في هذا المقال على كيفية استغلال قدرات أداة الذكاء الاصطناعي BlackBoxAI لتطبيق مبادئ اختبار البرامج Software testing بأنواعها المختلفة، مثل الاختبارات الوظيفية Functional testing كاختبار الوحدة Unit test واختبار الانحدار Regression test بالإضافة للاختبارات غير الوظيفية Non-functional testing التي تركز على اختبار أداء النظام وسرعة استجابته ونقاط الفشل المحتملة للنظام عن طريق محاكاة ظروف استخدام مختلفة، حيث استطعنا توليد الشيفرة المناسبة من خلال استخدام الموجهات Prompts المناسبة في BlackBoxAI وتحسينه حسب حاجتنا لذلك.
</p>

<p>
	وكما أن عملية توجيه أدوات الذكاء الاصطناعي عملية تكرارية ومستمرة فإن عملية اختبار البرامج كذلك تمر بدورات متتابعة من المحاولة والخطأ والتحسين المستمر للوصول لنسبة تغطية كافية لحالات الاختبار والحالات المتطرفة مما يضيق نطاق البحث عند وقوع أخطاء أو مشكلات في برامجنا، فيسهل اكتشافها وحلها بسرعة.
</p>

<h2 id="-">
	اقرأ أيضًا
</h2>

<ul>
	<li>
		<a href="%5Bhttps://academy.hsoub.com/programming/artificial-intelligence/%D8%A3%D9%81%D8%B6%D9%84-%D9%85%D9%85%D8%A7%D8%B1%D8%B3%D8%A7%D8%AA-%D9%87%D9%86%D8%AF%D8%B3%D8%A9-%D8%A7%D9%84%D9%85%D9%8F%D9%88%D8%AC%D9%91%D9%90%D9%87%D8%A7%D8%AA/%5D%5C(https://academy.hsoub.com/programming/artificial-intelligence/%D8%A3%D9%81%D8%B6%D9%84-%D9%85%D9%85%D8%A7%D8%B1%D8%B3%D8%A7%D8%AA-%D9%87%D9%86%D8%AF%D8%B3%D8%A9-%D8%A7%D9%84%D9%85%D9%8F%D9%88%D8%AC%D9%91%D9%90%D9%87%D8%A7%D8%AA/%5C" rel="">أفضل ممارسات هندسة المُوجِّهات Prompt Engineering: نصائح وحيل وأدوات</a>
	</li>
</ul>

<ul>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A7%D9%83%D8%AA%D8%B4%D9%81-%D8%A8%D8%AF%D8%A7%D8%A6%D9%84-chatgpt-%D9%85%D9%81%D8%AA%D9%88%D8%AD%D8%A9-%D8%A7%D9%84%D9%85%D8%B5%D8%AF%D8%B1-r2488/" rel="">اكتشف بدائل ChatGPT مفتوحة المصدر</a>
	</li>
</ul>

<ul>
	<li>
		<a href="https://academy.hsoub.com/devops/servers/databases/%D9%83%D9%8A%D9%81-%D9%88%D9%85%D8%AA%D9%89-%D9%86%D8%B3%D8%AA%D8%AE%D8%AF%D9%85-sqlite-r111/" rel="">كيف ومتى نستخدم SQLite</a>
	</li>
</ul>

<ul>
	<li>
		<p>
			<a href="https://academy.hsoub.com/programming/general/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D8%A7%D9%84%D9%88%D8%A7%D8%AC%D9%87%D8%A7%D8%AA-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D8%A9-api-r1314/" rel="">مدخل إلى الواجهات البرمجية <abbr title="Application Programming Interface | واجهة برمجية"><abbr title="Application Programming Interface | واجهة برمجية">API</abbr></abbr></a>
		</p>
	</li>
	<li>
		<p>
			<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AF%D9%85%D8%AC-%D9%85%D8%B3%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-github-copilot-%D9%85%D8%B9-%D9%85%D8%AD%D8%B1%D8%B1-%D8%A7%D9%84%D8%A3%D9%83%D9%88%D8%A7%D8%AF-vs-code-r2521/" rel="">دمج مساعد الذكاء الاصطناعي GitHub Copilot مع محرر الأكواد VS Code</a>
		</p>
	</li>
</ul>
]]></description><guid isPermaLink="false">2605</guid><pubDate>Mon, 23 Mar 2026 11:17:01 +0000</pubDate></item><item><title>&#x627;&#x644;&#x641;&#x631;&#x642; &#x628;&#x64A;&#x646; &#x62A;&#x639;&#x644;&#x645; &#x627;&#x644;&#x622;&#x644;&#x629; &#x648;&#x627;&#x644;&#x62A;&#x639;&#x644;&#x645; &#x627;&#x644;&#x639;&#x645;&#x64A;&#x642;</title><link>https://academy.hsoub.com/programming/artificial-intelligence/%D8%A7%D9%84%D9%81%D8%B1%D9%82-%D8%A8%D9%8A%D9%86-%D8%AA%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%A2%D9%84%D8%A9-%D9%88%D8%A7%D9%84%D8%AA%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%B9%D9%85%D9%8A%D9%82-r2599/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2026_03/ML-DL.png.b90b31e8cbc7546cf13b7b2931661313.png" /></p>
<p>
	نسمع العديد من المصطلحات التي يخلط فيما بينها ضمن مجال الذكاء الاصطناعي Artificial Intelligence منها مصطلح تعلم الآلة Machine learning والتعلم العميق Deep learning، واللذان يعدان أساسيان في هذا المجال.
</p>

<p>
	بشكل عام يهتم هذين المجالين بمعالجة البيانات لاستخراج المعلومات منها وأحدهما يشمل الآخر، لذا سنوضح في هذا المقال هذه المصطلحات وماذا يشمل كل منها وفي ماذا تستخدم حتى نفهم الفرق بينها، ويمكنك التعرف أكثر على المصطحات الأخرى في مجال الذكاء الاصطناعي من مقال <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A7%D9%84%D9%85%D9%81%D8%A7%D9%87%D9%8A%D9%85-%D8%A7%D9%84%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A9-%D9%84%D8%AA%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%A2%D9%84%D8%A9-r1009" rel="">المفاهيم الأساسية لتعلم الآلة</a>.
</p>

<h2 id="-machine-learning">
	تعلم الآلة Machine learning
</h2>

<p>
	فرع من مجال الذكاء الاصطناعي يستخدم خوارزميات محددة لاستخراج الأنماط patterns والتوقعات من البيانات، ويختلف النظام الذي يستخدم تعلم الآلة عن البرمجة العادية الثابتة بتطوير نموذج الخوارمية وتحسينها تدريجيًا عبر التدريب والاختبار المتكرر للنتائج أثناء معالجة بيانات دون تدخل بشري عبر التعلم من تلك البيانات مما يحسّن دقة النتائج مع الوقت.
</p>

<p>
	يستخدم خوارزميات التصنيف والتنبؤ والتي تحوي على معاملات parameters يمكن ضبطها تلقائيًا أثناء عملية التدريب لتحسين دقتها، فمثلًا عند استخدام خوارزمية شجرة القرار Decision Trees لتصنيف البيانات يعاير النظام بنيتها تلقائيًا، فكلما تدرب على بيانات أكبر وأكثر تنوعًا تحسّنت دقتها في معالجة بيانات جديدة.
</p>

<p>
	من مزايا هذا النوع من التعليم قدرته على التعلم من كمية بيانات صغيرة نسبيًا، ولكنه يعتمد على وجود مزايا مستخرجة مسبقًا من البيانات ولا يمكنه استخراجها بنفسه أي يحتاج لتدخل بشري في هذه المرحلة، وبعدها فقط يمكنه التعلم من تلك المزايا واتخاذ قرارات أفضل مع الوقت.
</p>

<p>
	تطبيقاته كثيرة ومنتشرة بشكل كبير منها أنظمة الاقتراحات في منصات المحتوى كاقتراح فيديوهات للمستخدم قد يرغب بمشاهدتها أو اقتراح المنشورات في وسائل التواصل الاجتماعي، وصولًا إلى تصنيف المحتوى كتصنيف رسائل البريد الالكتروني لاستبعاد السيء منها أو تصنيف المراجعات النصية على المنتجات كإيجابية أو سلبية.
</p>

<p>
	يصنف تعلم الآلة إلى ثلاثة أنواع رئيسية تختلف بحسب نوع المشكلة التي يحلها، وطريقة تعامل النظام مع البيانات وشكلها وطريقة التعلم منها أثناء التدريب، وسنشرحها في الفقرات التالية.
</p>

<h3 id="-supervised-learning">
	التعلم الموجه Supervised Learning
</h3>

<p>
	النوع الأساسي والأكثر استخداماً في تعلم الآلة، حيث يتدرب فيه النظام على البيانات والإجابات الصحيحة المقابلة لها، فيحللها ويستنتج تلقائيًا العلاقة بينها ليصبح قادرًا بعد التدريب على التنبؤ بإجابات بيانات جديدة لم يرها من قبل، وتقسم تلك بيانات وإجاباتها إلى قسمين قسم كبير عادةً يكون 80% منها لتدريب النظام والباقي 20% تستخدم لاختبار دقة وكفاءة النظام.
</p>

<p>
	تنقسم الخوارزميات المستخدمة في التعلم الموجه لنوعين أساسيين بحسب نوع التنبؤات المطلوبة وهي:
</p>

<p>
	<strong>التصنيف Classification</strong> لتقسيم البيانات إلى فئات كتصنيف رسائل البريد الإلكتروني إلى جيدة أو سيئة، ومن الخوارزميات المستخدمة فيه الانحدار اللوجستي Logistic Regression للتصنيف الثنائي، وأشجار القرار Decision Trees لتصنيف القرارات ونتائجها المحتملة
</p>

<p>
	<strong>الانحدار Regression</strong> للتنبؤ بقيم رقمية، كسعر منتج معين أو درجة حرارة الطقس ومن الخوارزميات التي يستخدمها الانحدار الخطي Linear Regression والانحدار متعدد الحدود Polynomial Regression لاكتشاف العلاقة بين البيانات وتتوقع منها القيم للبيانات الجديدة
</p>

<h3 id="-unsupervised-learning">
	التعلم غير الموجه Unsupervised Learning
</h3>

<p>
	يتعلم فيه النظام من البيانات فقط ليستكشف منها الأنماط والبنى المخفية فيها دون تدخل بشري وتنقسم الخوارزميات المستخدمة فيه لثلاث أنواع رئيسية:
</p>

<p>
	<strong>خوارزميات التجميع clustering</strong> وفيها يتم توزيع البيانات المتشابهة في مجموعات، كتصنيف زبائن متجر إلكتروني بحسب المشتريات او الاهتمامات، ومنها خوارزمية تجميع K-Means وخوارزمية التجميع الهيكلية Hierarchical Clustering
</p>

<p>
	<strong>قاعدة الارتباط Association rule</strong> تستكشف العلاقات في البيانات وتستنتج منها قواعد شرطية تُعبّر عن وجود بيانات في حال وجود أخرى
</p>

<p>
	<strong>تقليل الأبعاد Dimensionality Reduction</strong> تهدف لتقليل عدد المزايا أو المتغيرات في البيانات مع الحفاظ قدر الإمكان على المعلومات الموجودة في البيانات ومن خوارزمياتها تحليل مكون المبدأ Principal Component Analysis و التضمين المحلي الخطي Locally Linear Embedding
</p>

<h3 id="-reinforcement-learning">
	التعلم المعزز Reinforcement Learning
</h3>

<p>
	يركز على تعليم وكيل Agent كيف يتخذ قرارات عبر التجربة والخطأ ليحصل على أكبر قدر ممكن من المكافئات من البيئة التي يتفاعل معها ليحقق بالنهاية هدف معين، ومن تطبيقاته نماذج التحكم بالروبوتات العادية والصناعية، ونماذج لعب الألعاب التي تتجاوز مهارتها البشر.
</p>

<p>
	ويقسم إلى نوعين هما <strong>التعزيز الإيجابي Positive Reinforcement</strong> والذي يكافئ الأفعال التي تؤدي لحدث ما و<strong>التعزيز السلبي Negative Reinforcement</strong> والذي يكافئ الأفعال التي تسبب تجنب حدث ما.
</p>

<h2 id="-deep-learning">
	التعلم العميق Deep learning
</h2>

<p>
	فرع متقدم من تعلم الآلة يعتمد على الشبكات العصبية Neural Networks متعددة الطبقات لاستخراج الأنماط والتوقعات من البيانات مباشرة، ويختلف عن تعلم الآلة التقليدي بقدرته على استخراج المزايا تلقائيًا عبر طبقات متتالية دون الحاجة لتدخل بشري، مع تحسين الأداء تدريجيًا عبر التدريب على كميات هائلة من البيانات.
</p>

<p>
	مثلًا عند استخدام شبكة عصبية التفافية Convolutional Neural Network للتعرف على الصور، تتعلم الطبقات الأولى كشف الحواف والأشكال البسيطة، ثم تتطور الطبقات العميقة لاكتشاف وجوه أو أجسام معقدة كلما زادت البيانات المعالجة، مما يحسن الدقة في التصنيف أو التنبؤ، أي يستطيع التعلم العميق استخراج المزايا بنفسه من أي نوع من البيانات.
</p>

<p>
	تُصنف طرق التعلم العميق ضمن الأنواع الثلاثة لتعلم الآلة التي ذكرناها سابقًا، ولكنها تتفوق بتنفيذها في التطبيقات المعقدة، مثل استخدامها لخوارزميات التصنيف Classification والانحدار Regression في التعلم الموجه، واستخدام التجميع Clustering في التعلم غير الموجه، وقدرته الممتازة في التفاعل ضمن البيئات الافتراضية في التعلم المعزز.
</p>

<p>
	من مزاياه قدرته على معالجة بيانات غير مهيكلة كالصور والنصوص بكفاءة عالية، ولكنه يتطلب كميات بيانات ضخمة وموارد معالجة قوية من كروت شاشة وذاكرة، وزمن تدريب طويل مما يجعله أقل كفاءة على بيانات صغيرة مقارنة بتعلم الآلة التقليدي.
</p>

<p>
	تشمل تطبيقاته التعرف على الوجوه والترجمة الآلية الفورية، وتشخيص الأمراض من الأشعة الطبية، والسيارات ذاتية القيادة، ومن التطبيقات التي شهرت هذا المجال وأبرزت قوته كان نموذج ألفا جو AlphaGo الذي استطاع بتطبيق التعلم المعزز التدرب على لعبة Go المعروفة بتعقيدها واستطاع هزيمة أبطال تلك اللعبة.
</p>

<h2 id="-">
	الفرق بين تعلم الآلة والتعلم العميق
</h2>

<p>
	التعلم العميق فرع ضمن مجال تعلم الآلة، وتكمن ميزة وفرق التعلم العميق في مرحلة استخراج المزايا Feature Extraction من البيانات قبل استخلاص النتائج المطلوبة منها، حيث يستطيع استخراج المزايا بنفسه ما يجعله أقوى في معالجة مجال أوسع من البيانات، بينما مجالات تعلم الآلة الأخرى تحتاج لمزايا مجهزة يدويًا مسبقًا بجانب البيانات لتتمكن من استخلاص النتائج المطلوبة منها.
</p>

<p style="text-align: center;">
	<img alt="Pasted-image-20260112152839.png" style="width: 400px; height: auto;" src="https://ana.hsoubcdn.com/apps/notes/files/ab124318-7e96-4a77-a962-2b8e5829121a/8ad9acf6-18cc-4f16-b1f6-98fae23c5de0/Pasted-image-20260112152839.png">
</p>

<p>
	هذا الفرق يجعل طرق تعلم الآلة التقليدية خفيفة وسريعة ولا تحتاج لموارد معالجة قوية ولا حتى لكمية كبيرة من البيانات، على عكس التعلم العميق الذي يتطلب موارد معالجة وكميات بيانات كبيرة على حساب قدرته على معالجة بيانات معقدة والوصول لنتائج لا يمكن لتعلم الآلة التقليدي الوصول إليها، والجدول التالي يوضح أهم الفروقات بين المجالين:
</p>

<table>
	<tbody>
		<tr>
			<td>
				 
			</td>
			<td>
				تعلم الآلة
			</td>
			<td>
				التعلم العميق
			</td>
		</tr>
		<tr>
			<td>
				البنية
			</td>
			<td>
				خوارزميات تتعلم من البيانات وتحسن أداءها مع الخبرة
			</td>
			<td>
				فرع من تعلم الآلة يعتمد على الشبكات العصبونية متعددة الطبقات
			</td>
		</tr>
		<tr>
			<td>
				كمية بيانات التدريب
			</td>
			<td>
				صغيرة إلى متوسطة
			</td>
			<td>
				بيانات ضخمة
			</td>
		</tr>
		<tr>
			<td>
				استخراج المزايا
			</td>
			<td>
				يدوي بتدخل بشري
			</td>
			<td>
				تلقائي يستخرجها مباشرة من البيانات
			</td>
		</tr>
		<tr>
			<td>
				وقت التدريب
			</td>
			<td>
				سريع
			</td>
			<td>
				بطيء
			</td>
		</tr>
		<tr>
			<td>
				قوة وكمية موارد المعالجة
			</td>
			<td>
				قليلة
			</td>
			<td>
				كبيرة
			</td>
		</tr>
		<tr>
			<td>
				الدقة
			</td>
			<td>
				تعتمد على جودة المزايا والخوارزمية المستخدمة
			</td>
			<td>
				عالية في حال وجود بيانات كافية
			</td>
		</tr>
	</tbody>
</table>

<h2 id="-">
	خلاصة
</h2>

<p>
	تعرفنا في هذا المقال عن مجالي تعلم الآلة والتعلم العميق والفرق بينهما إضافة لمتطلبات كل منها، هذا الفرق يوضح متى نختار كل منها للحصول على نتائج جيدة، وتذكر أن مجال تعلم الآلة أوسع ويشمل ضمنه مجال التعلم العميق.
</p>

<h2 id="-">
	اقرأ أيضًا
</h2>

<ul>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A" rel="">الذكاء الاصطناعي: دليلك الشامل</a>
	</li>
	<li>
		كتاب <a href="https://academy.hsoub.com/files/17-%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-%D9%88%D8%AA%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%A2%D9%84%D8%A9/" rel="">مدخل إلى الذكاء الاصطناعي وتعلم الآلة</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A7%D9%84%D9%85%D9%81%D8%A7%D9%87%D9%8A%D9%85-%D8%A7%D9%84%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A9-%D9%84%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-r2478" rel="">المفاهيم الأساسية للذكاء الاصطناعي</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D9%83%D9%84-%D9%85%D8%A7-%D8%AA%D9%88%D8%AF-%D9%85%D8%B9%D8%B1%D9%81%D8%AA%D9%87-%D8%B9%D9%86-%D8%AF%D8%B1%D8%A7%D8%B3%D8%A9-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-r2362" rel="">كل ما تود معرفته عن دراسة الذكاء الاصطناعي</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">2599</guid><pubDate>Tue, 20 Jan 2026 07:40:00 +0000</pubDate></item><item><title>&#x62A;&#x639;&#x631;&#x641; &#x639;&#x644;&#x649; &#x627;&#x644;&#x634;&#x628;&#x643;&#x627;&#x62A; &#x627;&#x644;&#x639;&#x635;&#x628;&#x64A;&#x629; &#x627;&#x644;&#x627;&#x644;&#x62A;&#x641;&#x627;&#x641;&#x64A;&#x629; CNNs</title><link>https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D8%A7%D9%84%D8%B4%D8%A8%D9%83%D8%A7%D8%AA-%D8%A7%D9%84%D8%B9%D8%B5%D8%A8%D9%8A%D8%A9-%D8%A7%D9%84%D8%A7%D9%84%D8%AA%D9%81%D8%A7%D9%81%D9%8A%D8%A9-cnns-r2597/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2026_03/CNNs(2).png.75da8efe0a11de7ec713ef0861cdb678.png" /></p>
<p>
	تُعدُّ الشبكات العصبية Neural Networks نموذجًا حاسوبيًا مستوحى من الدماغ البشري يحلل البيانات ويتعلم منها بعدة طرق، كالتعلم العميق الذي يمكنك الاطلاع عليه أكثر من مقال <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AF%D9%84%D9%8A%D9%84-%D8%A7%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86-%D9%84%D9%81%D9%87%D9%85-%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-%D8%A7%D9%84%D8%AA%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%B9%D9%85%D9%8A%D9%82-r1422/" rel="">دليل المبتدئين لفهم أساسيات التعلم العميق</a>، ومن فروعها الشبكات العصبية الالتفافية Convolutional Neural Networks - CNNs، المصممة لاستخراج المزايا والتعرف على الكائنات من البيانات، وتستخدم خصيصًا في مجال تصنيف الصور وتحليل محتوياتها.
</p>

<p>
	تُمثَّل بيانات الإدخال input data لمعظم الشبكات العصبية بمصفوفة matrix شكلها يعتمد على نوع البيانات، فمثلًا يمكن تمثيل الصور بمصفوفة أبعادها هي الطول حجمه يساوي طول الصورة، والعرض حجمه يساوي عرض الصورة، واللون لكل بكسل pixel في الصورة يتألف من ثلاث ألوان الأحمر والأخضر والأزرق RGB أي حجمه يساوي 3، فيمكن تمثيل الصورة بمصفوفة ثلاثية الأبعاد حجمها الطول×العرض×3.
</p>

<p>
	سنتعرف في هذا المقال على مكونات الشبكات العصبية الالتفافية وطريقة عمل كل منها وأهم التطبيقات العملية التي تستخدم فيها.
</p>

<h2 id="-">
	أنواع وترتيب طبقات الشبكات الالتفافية
</h2>

<p>
	يتميز هذا النوع من الشبكات العصبية بالأداء العالي في التعامل مع البيانات متعددة الأبعاد كالصور والصوتيات والتي تكون دخلًا لهذه الشبكة وتُمثّل على شكل مصفوفة بيانات الإدخال input data، ثم تمرر تلك المصفوفة إلى طبقات الشبكة وهي ثلاث أنواع رئيسية بالترتيب التالي بطبقة واحدة أو أكثر من كل نوع وهي:
</p>

<ol>
	<li>
		الطبقة الالتفافية Convolutional layer
	</li>
	<li>
		طبقة التجميع Pooling layer
	</li>
	<li>
		الطبقة المتصلة كليًا Fully connected layer
	</li>
</ol>

<p>
	تزداد قدرة الشبكة وتعقيد التعرف على مزايا في البيانات مع كل طبقة منها، فمثلًا عند تحليل صورة تُركز الطبقات الابتدائية على تحديد المزايا البسيطة كالألوان والحواف، ثم تُجمّع الطبقات التي تليها تلك المزايا وتستنتج منها مزايا أعقد كالأشكال، وصولًا لطبقات الشبكة النهائية التي تتعرف على الكائنات.
</p>

<h3 id="-convolutional-layer">
	الطبقة الالتفافية Convolutional layer
</h3>

<p>
	هي أساس الشبكات العصبية الالتفافية تحوّل مصفوفة البيانات المدخلة إليها إلى مصفوفة جديدة تعبّر عن المزايا الموجودة ضمنها، حيث تستخدم المُرشّح filter ويسمى أيضًا النواة kernal أو كاشف الميزة feature detector والذي يكون حجمه صغيرًا للالتفاف -لذا سُميت الطبقة بالالتفافية- على أجزاء من مصفوفة الدخل، وفي كل خطوة تُطبّق عملية الضرب النقطي dot product بين المرشح وجزء من مصفوفة الدخل لينتج عنها مصفوفة جديدة تدعى خارطة الميزة feature map أو خارطة التفعيل activation map أو الميزة المُلتفة convolved feature.
</p>

<p>
	تٌجمع بعد ذلك مصفوفات الخرائط الناتجة معًا ويطبق عليها تابع تفعيل مثل التابع ReLU لتسهيل التعامل معها لاحقًا وزيادة كفاءة الشبكة وتحويل قيمها إلى قيم غير خطية، وبذلك يكون خرج هذه الطبقة جاهزًا لمعالجته في الطبقة اللاحقة.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="180850" href="https://academy.hsoub.com/uploads/monthly_2026_01/image.png.e5301874bdce815db3001e8469905121.png" rel=""><img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="180850" data-ratio="50.14" data-unique="gr4lbvhb8" style="width: 700px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2026_01/image.thumb.png.ff7e4d6fd9f128dcc7e933b0baf4ad69.png"></a>
</p>

<p>
	عادة يوضع عدة طبقات متتالية من هذا النوع ضمن الشبكة، ومع تدريب الشبكة تتعاون الطبقات للتعرف على المزايا الموجودة في مصفوفة الدخل بدءًا من المزايا البسيطة وصولًا للتعرف على الكائنات، فمثلَا عند تدريب الشبكة للتعرف على الوجوه ضمن الصور تتعلم الطبقات الأولى التعرف على الخطوط والانحنائات البسطية، ثم تتعرف الطبقات اللاحقة على أشكال أعقد كشكل العيون والفم والأنف، وصولًا للطبقات الأخيرة التي ستتعرف على الوجوه ومكانها ضمن الصورة كما هو موضح في الصورة أدناه.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="180853" href="https://academy.hsoub.com/uploads/monthly_2026_01/image.png.e4ea1da256bb19c31b7841cc10ed34c3.png" rel=""><img alt="image.png" class="ipsImage ipsImage_thumbnailed" data-fileid="180853" data-ratio="100.00" data-unique="qde9kxty3" style="width: 300px; height: auto;" width="600" src="https://academy.hsoub.com/uploads/monthly_2026_01/image.thumb.png.8343cce29d34a163843399332d49c5f3.png"></a>
</p>

<h4 id="-filter-matrix">
	شكل مصفوفة المٌرشح Filter matrix
</h4>

<p>
	يمثل كل مرشح ميزة صغيرة على شكل مصفوفة أوزان weights تُعدّل خلال عملية التدريب لتصحيح عمل الشبكة وتصبح قادرة على استكشاف المزايا التي نبحث عنها، وشكل المصفوفة يماثل شكل مصفوفة بيانات الإدخال من حيث عدد الأبعاد، أما حجم كل بعد يعتمد على مدى قرب المزايا التي نبحث عنها من المعنى الذي يُعبّر عنه البعد المقابل في مصفوفة بيانات الإدخال.
</p>

<p>
	فمثلًا لتحليل صورة مُمثلة بمصفوفة ثلاثية الأبعاد يجب أن تكون المرشحات بنفس الشكل أي ثلاثية الأبعاد أيضًا، أما حجم كل بعد وبما أن طول وعرض الصورة لا يعبر مباشرة عن المزايا الموجودة ضمن الصورة، فحجم الأبعاد المقابلة لها ضمن المرشح تكون صغيرة مثلا بحجم 5×5 أو 3×3، أما بُعد اللون فهو يُعبر عن محتوى الصورة فيكون حجم البعد المقابل له ضمن المرشح مساويًا له أي 3، لتكون حجم المرشحات الممكنة 5×5×3 أو 3×3×3 أو أي قيم أخرى مماثلة.
</p>

<p>
	كلما زاد عدد المرشحات المستخدمة زادت قدرة الشبكة على استخراج مزايا معقدة أكثر، كما يؤثر طول الخطوة Stride التي يخطوها المرشح أثناء عملية المسح على شكل مصفوفة الميزة الناتجة، وقد لا يناسب أحيانًا حجم المرشح لمسح مصفوفة البيانات بشكل كامل عندها نلجأ لإحدى الطرق التالية:
</p>

<ul>
	<li>
		الحشو الصحيح Valid padding بتجاهل عمليات المسح النهائية التي لا تتناسب بالحجم
	</li>
	<li>
		الحشو المماثل Same padding بإضافة أصفار لحواف مصفوفة المرشح ليكون حجم مصفوفة الخرج مساويًا لحجم مصفوفة بيانات الإدخال
	</li>
	<li>
		الحشو الكلي Full padding بإضافة أصفار في حواف مصفوفة البيانات لزيادة حجم مصفوفة الخرج
	</li>
</ul>

<h3 id="-pooling-layer">
	طبقة التجميع Pooling layer
</h3>

<p>
	وظيفتها تقليل أبعاد وشكل المصفوفة الداخلة إليها، وطريقة عملها تشبه طبقة الالتفاف، بتمرير مرشح على المصفوفة المدخلة إليها.
</p>

<p>
	الفرق أن المرشح في هذه الطبقة لا يحوي أوزانًا بل هو دالة تجميع aggregation تُطبّق على أجزاء الدخل وتكتب نتائج ذلك المسح في مصفوفة الخرج الأقل بعدًا، وهناك نوعين من هذه الدوال تختلف في طريقة حساب النتيجة أثناء المسح:
</p>

<ul>
	<li>
		<strong>التجميع الأعظمي</strong> Max pooling يُختار فيه أعلى القيم
	</li>
	<li>
		<strong>التجميع الوسطي</strong> Average pooling يُحسب فيه وسطي القيم
	</li>
</ul>

<p>
	قد نتسائل لماذا نختزل في هذه الطبقة بعض المعلومات المستخرجة التي قد تكون مهمة من الطبقة السابقة، وذلك لعدة أسباب منها التبسيط وزيادة الأداء حيث سنتعامل مع بيانات أقل في الطبقات اللاحقة، وأيضًا تمنع هذه الطبقة الشبكة من الإفراط في التخصيص overfitting فيبقى عمل الشبكة يغطي مجال أكبر من بيانات الإدخال الغير مدرب عليها.
</p>

<h3 id="-fully-connected-layer">
	الطبقة المتصلة كليًا Fully connected layer
</h3>

<p>
	تتكون من طبقات ضمن كل منها أعداد مختلفة من العقد nodes، بحيث تتصل فيها العقد من كل طبقة مع كل العقد في الطبقة التي تليها، وتطبق في كل عقدة أوزان على مدخلات العقدة ثم تطبق على النتيجة دالة تفعيل عادة تكون من نوع softmax وينتج عنها احتمال من صفر إلى واحد، وتكرر هذه العملية في جميع طبقات العقد للوصول إلى الطبقة النهائية.
</p>

<p>
	تستكشف هذه الطبقة الأنماط من المزايا المستخرجة من الطبقات السابقة من الشبكة، وتعطي جوابًا نهائيًا وهو خرج الشبكة ككل.
</p>

<h2 id="-">
	تطبيقات الشبكات العصبية الالتفافية
</h2>

<p>
	من أهم استخدامات هذه الشبكة في مجال الذكاء الاصطناعي هي مهام الرؤية الحاسوبية لتحليل واستخراج المعلومات من الصور والفيديوهات وحتى الصوتيات.
</p>

<p>
	فمثلًا تستخدمها منصات التواصل الاجتماعي في تحليل الصور المنشورة فيها، والمتاجر الرقمية في مسح صور المنتجات وتصنيفها لاقتراحها على الزبائن، وفي المجال الطبي تٌستخدم في تحليل صور الأشعة وتحديد احتمالية وجود الأمراض، ومن أهم التطبيقات لهذه الشبكات هو في مجال النقل لتطوير سيارات ذاتية القيادة وتخفيف أخطاء السائقين لحماية الركاب.
</p>

<h2 id="-">
	خلاصة
</h2>

<p>
	تعتبر الشبكة العصبية الالتفافية من أهم أنواع الشبكات في مجال الذكاء الاصطناعي لتطبيقاتها المختلفة المفيدة، والمزايا والتطبيقات المختلفة التي تقدمها من التعرف على الكائنات إلى استخراج المزايا من البيانات من أنواع مختلفة.
</p>

<p>
	تعرفنا في هذا المقال على والطبقات المكونة لها وعمل كل منها، من طبقة الالتفاف إلى طبقة التجميع وصولًا للطبقة المتصلة كليًا، وعلى أهم التطبيقات التي تٌستخدم فيها تلك الشبكة.
</p>

<h2 id="-2">
	اقرأ أيضًا
</h2>

<ul>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%d8%a7%d9%84%d8%b0%d9%83%d8%a7%d8%a1-%d8%a7%d9%84%d8%a7%d8%b5%d8%b7%d9%86%d8%a7%d8%b9%d9%8a/" rel="">الذكاء الاصطناعي: دليلك الشامل</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/files/17-%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-%D9%88%D8%AA%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%A2%D9%84%D8%A9/" rel="">مدخل إلى الذكاء الاصطناعي وتعلم الآلة</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%d8%a7%d9%84%d9%85%d9%81%d8%a7%d9%87%d9%8a%d9%85-%d8%a7%d9%84%d8%a3%d8%b3%d8%a7%d8%b3%d9%8a%d8%a9-%d9%84%d9%84%d8%b0%d9%83%d8%a7%d8%a1-%d8%a7%d9%84%d8%a7%d8%b5%d8%b7%d9%86%d8%a7%d8%b9%d9%8a-r2478/" rel="">المفاهيم الأساسية للذكاء الاصطناعي</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%d9%83%d9%84-%d9%85%d8%a7-%d8%aa%d9%88%d8%af-%d9%85%d8%b9%d8%b1%d9%81%d8%aa%d9%87-%d8%b9%d9%86-%d8%af%d8%b1%d8%a7%d8%b3%d8%a9-%d8%a7%d9%84%d8%b0%d9%83%d8%a7%d8%a1-%d8%a7%d9%84%d8%a7%d8%b5%d8%b7%d9%86%d8%a7%d8%b9%d9%8a-r2362/" rel="">كل ما تود معرفته عن دراسة الذكاء الاصطناعي</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">2597</guid><pubDate>Mon, 12 Jan 2026 11:02:00 +0000</pubDate></item><item><title>&#x643;&#x64A;&#x641; &#x64A;&#x642;&#x62A;&#x631;&#x62D; &#x639;&#x644;&#x64A;&#x643; &#x62A;&#x64A;&#x643;&#x62A;&#x648;&#x643; &#x627;&#x644;&#x641;&#x64A;&#x62F;&#x64A;&#x648;&#x647;&#x627;&#x62A; &#x627;&#x644;&#x62A;&#x64A; &#x62A;&#x631;&#x64A;&#x62F;&#x647;&#x627; &#x642;&#x628;&#x644; &#x627;&#x644;&#x628;&#x62D;&#x62B; &#x639;&#x646;&#x647;&#x627;&#x61F;</title><link>https://academy.hsoub.com/programming/artificial-intelligence/%D9%83%D9%8A%D9%81-%D9%8A%D9%82%D8%AA%D8%B1%D8%AD-%D8%B9%D9%84%D9%8A%D9%83-%D8%AA%D9%8A%D9%83%D8%AA%D9%88%D9%83-%D8%A7%D9%84%D9%81%D9%8A%D8%AF%D9%8A%D9%88%D9%87%D8%A7%D8%AA-%D8%A7%D9%84%D8%AA%D9%8A-%D8%AA%D8%B1%D9%8A%D8%AF%D9%87%D8%A7-%D9%82%D8%A8%D9%84-%D8%A7%D9%84%D8%A8%D8%AD%D8%AB-%D8%B9%D9%86%D9%87%D8%A7%D8%9F-r2566/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2025_04/4.TikTok.png.7bcdbd8f762834d86314d7e92a39f457.png" /></p>
<p>
	يتساءل العديد من مستخدمي منصة تيكتوك عن كيف يمكن لهذه المنصة أن تقدم لنا محتوى يبدو وكأنه مصمم خصيصًا لنا، حتى قبل أن نبحث عنه؟ لا بد أن هذا السؤال قد تبادر إلى ذهن الكثيرين ممن لاحظوا الدقة اللافتة في الاقتراحات التي تظهر لهم، والتي أثبتت أنها تعتمد بقوة على الخوارزميات في جذب انتباه المستخدمين.
</p>

<p>
	في مجال <a href="https://academy.hsoub.com/programming/general/%D8%B9%D9%84%D9%88%D9%85-%D8%A7%D9%84%D8%AD%D8%A7%D8%B3%D9%88%D8%A8/" rel="">علوم الحاسوب</a>، تُعرف هذه الآليات <strong>بخوارزميات أنظمة التوصية</strong>، وهي تعتمد على تحليل مستمر لسلوك المستخدمين. ويتم بناء هذه الأنظمة على جمع وتحليل كميات هائلة من البيانات المتعلقة بالتفاعلات اليومية، مثل ما يشاهده المستخدم، وما يضغط عليه، أو ما يتجاهله. وبطبيعة الحال، تكوّن هذه البيانات نموذجا شخصيًا يتيح للمنصة تيكتوك وغيرها إمكانية تقديم محتوى مخصص يواكب اهتمامات المستخدم واحتياجاته.
</p>

<p>
	سنتعمق في آلية عمل هذه الخوارزميات عمليًا بهذا المقال، وسنقدم شرحًا تطبيقيًا مبسطًا يوضح كيف تعمل أنظمة التوصية في تيكتوك، مما يسهم في تسهيل فهم هذه التكنولوجيا واستكشاف تطبيقاتها المتنوعة.
</p>

<p>
	سنستخدم للعمل بهذا المقال <a href="https://github.com/Peter-Lankton/tik-tok-data/blob/main/tik_tok_analytics.csv" rel="external nofollow">قاعدة بيانات</a> التي تحتوي على مجموعة من بيانات الفيديوهات التي تتمثل في أسماء الفيديوهات والوسوم المرتبطة بها والعديد من البيانات المختلفة. هذه البيانات ستساعدنا في تطبيق الخوارزميات وقياس التشابه بين الفيديوهات المختلفة، مما يتيح لنا بناء نظام توصية عملي.
</p>

<h2 id="">
	آلية عمل خوارزمية التوصية في منصة تيكتوك
</h2>

<p>
	تقوم <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AE%D9%88%D8%A7%D8%B1%D8%B2%D9%85%D9%8A%D8%A7%D8%AA-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A/" rel="">خوارزميات</a> التوصية التي تعتمدها منصة تيكتوك باقتراح محتوى مخصص يتحسن بمرور الوقت مع استمرار المستخدم في قضاء الوقت على المنصة، ولأجل ذلك يتم العمل على:
</p>

<ul>
	<li>
		<strong>جمع البيانات</strong>: وتشمل أنواع التفاعلات المتمثلة في الاعجابات والتعليقات ومدة المشاهدة وتخطي المحتوى
	</li>
	<li>
		<strong>تصنيف المحتوى حسب النوع</strong>: بتحديد موضوع الفيديو وجودته وملاءمته لاهتمامات المستخدمين، يتم استخدام تقنيات مثل تحليل ميزات الفيديو وتتبع أداء الفيديو
	</li>
	<li>
		<strong>تصنيف المحتوى حسب مبدأ التصفية التعاونية</strong>: تستخدم لتوليد التوقعات بناءً على سلوك المستخدم السابق لاعتماد اقتراحه من عدمه على أصحاب السلوكيات والاهتمامات المتشابهة
	</li>
</ul>

<h3 id="-1">
	تهيئة بيئة العمل لبناء نظام توصية شبيه بنظام توصية تيكتوك
</h3>

<p>
	<a href="https://books.google.fr/books?hl=fr&amp;lr=&amp;id=BglnDwAAQBAJ&amp;oi=fnd&amp;pg=PP1&amp;dq=recommendation+systems+using+python&amp;ots=2C97HSEM9b&amp;sig=JxERrFnzJTmwkGvI3teAA7jfs7U#v=onepage&amp;q=recommendation%20systems%20using%20python&amp;f=false" rel="external nofollow">تعتمد خوارزميات تيكتوك كثيرًا على لغة البرمجة بايثون Python</a>، خاصةً في تقنيات الذكاء الاصطناعي والتعلم الآلي لتطوير خوارزمياتها، بالإضافة إلى لغات برمجية أخرى مثل <a href="https://academy.hsoub.com/programming/cpp/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-c-r802/" rel="">++C</a> و <a href="https://academy.hsoub.com/programming/java/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D9%85%D8%A7-%D9%87%D9%8A%D8%A9-%D8%AC%D8%A7%D9%81%D8%A7-java-r1515/" rel="">Java</a> و <a href="https://academy.hsoub.com/programming/go/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D9%84%D8%BA%D8%A9-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D8%A9-go-r222/" rel="">Go</a>.
</p>

<p>
	لكن نظرًا لأننا سنركز في هذا المقال على خوارزميات التوصية، فسنبني نظام توصية مشابه قائم على لغة بايثون، وسنحتاج لأجل ذلك إلى كل من:
</p>

<ul>
	<li>
		<a href="https://pandas.pydata.org" rel="external nofollow">مكتبة pandas</a>: لقراءة ومعالجة البيانات
	</li>
	<li>
		<a href="https://scikit-learn.org/stable" rel="external nofollow">إطار العمل scikit-learn</a>: لتحويل البيانات النصية إلى شكل يمكن لنموذج التوصية التعامل معه.
	</li>
	<li>
		<a href="https://github.com/Peter-Lankton/tik-tok-data/blob/main/tik_tok_analytics.csv" rel="external nofollow">قاعدة البيانات</a> التي سنعمل على أساسها بهذا المقال
	</li>
</ul>

<p>
	نثبت المكتبات وأطر العمل التي نحتاجها على النحو الآتي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3632_11" style=""><span class="pln">pip install pandas scikit</span><span class="pun">-</span><span class="pln">learn</span></pre>

<h2 id="-2">
	قراءة و تحليل البيانات الضخمة لفهم سلوك المستخدمين
</h2>

<p>
	سنطلب الآن قراءة البيانات وتحميلها من <a href="https://github.com/Peter-Lankton/tik-tok-data/blob/main/tik_tok_analytics.csv" rel="external nofollow">قاعدة البيانات المستخدمة</a> وطباعة أول خمس صفوف منها باستخدام مكتبة Pandas.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3632_13" style=""><span class="pln">    </span><span class="kwd">import</span><span class="pln"> pandas </span><span class="kwd">as</span><span class="pln"> pd  </span><span class="com">#DataFrames للتعامل مع البيانات وتحليلها باستخدام</span><span class="pln">

    </span><span class="pun">رابط</span><span class="pln"> </span><span class="pun">ملف</span><span class="pln"> </span><span class="pun">البيانات</span><span class="pln"> </span><span class="pun">لتيكتوك</span><span class="pln"> </span><span class="pun">بصيغة</span><span class="pln"> </span><span class="pun">خام</span><span class="pln"> </span><span class="pun">(</span><span class="pln">raw</span><span class="pun">)</span><span class="pln"> </span><span class="pun">من</span><span class="pln"> </span><span class="typ">GitHub</span><span class="pln"> </span><span class="com">#</span><span class="pln">
    ratings_url </span><span class="pun">=</span><span class="pln"> </span><span class="str">"https://raw.githubusercontent.com/Peter-Lankton/tik-tok-data/main/tik_tok_analytics.csv"</span><span class="pln">
    ratings </span><span class="pun">=</span><span class="pln"> pd</span><span class="pun">.</span><span class="pln">read_csv</span><span class="pun">(</span><span class="pln">ratings_url</span><span class="pun">)</span><span class="pln">
   </span><span class="pun">عرض</span><span class="pln"> </span><span class="pun">أول</span><span class="pln"> </span><span class="pun">خمس</span><span class="pln"> </span><span class="pun">صفوف</span><span class="pln"> </span><span class="pun">من</span><span class="pln"> </span><span class="pun">البيانات</span><span class="pln"> </span><span class="pun">للتحقق</span><span class="pln"> </span><span class="pun">من</span><span class="pln"> </span><span class="pun">التحميل</span><span class="pln"> </span><span class="pun">بنجاح</span><span class="pln"> </span><span class="com">#</span><span class="pln">
    </span><span class="kwd">print</span><span class="pun">(</span><span class="pln">ratings</span><span class="pun">.</span><span class="pln">head</span><span class="pun">())</span></pre>

<p>
	وكما نلاحظ تتم قراءة خمس صفوف من قاعدة البيانات على النحو الآتي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="JPG" data-fileid="171426" href="https://academy.hsoub.com/uploads/monthly_2025_04/003_.JPG.4c91695b20b7196a3fb2711bd97d142a.JPG" rel=""><img alt="003 نظام التوصية" class="ipsImage ipsImage_thumbnailed" data-fileid="171426" data-unique="oai6bili3" style="width: 800px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_04/003_.thumb.JPG.75d7c75945a86b6590c1faf83eddb7eb.JPG"> </a>
</p>

<p>
	تحتوي البيانات تحتوي على معلومات حول مقاطع فيديو مختلفة مثل اسم الفيديو، التكنولوجيا المستخدمة في الفيديو، ووقت التحميل، اليوم الذي تم فيه رفع الفيديو، وأسئلة وأجوبة، ووجود الترجمة، والمشاهدات، والمشاركات، والتعليقات، والإعجابات، والوسوم؛ وسنستفيد منها لبناء نظام توصيات يقترح ما يجب على المستخدم مشاهدته بعد ذلك، بناءً على تفضيلاته الحالية للفيديو.
</p>

<p>
	ستظهر لنا التعليمة التالية عدد الأعمدة و عدد الصفوف، بالاضافة الى نوع كل عمود و عدد القيم غير الفارغة:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3632_17" style=""><span class="pln">ratings</span><span class="pun">.</span><span class="pln">info</span><span class="pun">()</span></pre>

<p>
	وستكون النتتيجة على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3632_19" style=""><span class="pln">    </span><span class="pun">&lt;</span><span class="kwd">class</span><span class="pln"> </span><span class="str">'pandas.core.frame.DataFrame'</span><span class="pun">&gt;</span><span class="pln">
    </span><span class="typ">RangeIndex</span><span class="pun">:</span><span class="pln"> </span><span class="lit">102</span><span class="pln"> entries</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pln"> to </span><span class="lit">101</span><span class="pln">
    </span><span class="typ">Data</span><span class="pln"> columns </span><span class="pun">(</span><span class="pln">total </span><span class="lit">17</span><span class="pln"> columns</span><span class="pun">):</span><span class="pln">
    </span><span class="com">#   Column        Non-Null Count  Dtype  </span><span class="pln">
    </span><span class="pun">---</span><span class="pln">  </span><span class="pun">------</span><span class="pln">        </span><span class="pun">--------------</span><span class="pln">  </span><span class="pun">-----</span><span class="pln">  
    </span><span class="lit">0</span><span class="pln">   </span><span class="typ">Video_Name</span><span class="pln">    </span><span class="lit">102</span><span class="pln"> non</span><span class="pun">-</span><span class="pln">null    object 
    </span><span class="lit">1</span><span class="pln">   </span><span class="typ">Tech</span><span class="pln">          </span><span class="lit">101</span><span class="pln"> non</span><span class="pun">-</span><span class="pln">null    float64
    </span><span class="lit">2</span><span class="pln">   </span><span class="typ">Upload_time</span><span class="pln">   </span><span class="lit">102</span><span class="pln"> non</span><span class="pun">-</span><span class="pln">null    int64  
    </span><span class="lit">3</span><span class="pln">   </span><span class="typ">Day</span><span class="pln">           </span><span class="lit">102</span><span class="pln"> non</span><span class="pun">-</span><span class="pln">null    int64  
    </span><span class="lit">4</span><span class="pln">   Q_and_A       </span><span class="lit">102</span><span class="pln"> non</span><span class="pun">-</span><span class="pln">null    int64  
    </span><span class="lit">5</span><span class="pln">   has_captions  </span><span class="lit">102</span><span class="pln"> non</span><span class="pun">-</span><span class="pln">null    int64  
    </span><span class="lit">6</span><span class="pln">   </span><span class="typ">Views</span><span class="pln">         </span><span class="lit">102</span><span class="pln"> non</span><span class="pun">-</span><span class="pln">null    int64  
    </span><span class="lit">7</span><span class="pln">   </span><span class="typ">Shares</span><span class="pln">        </span><span class="lit">101</span><span class="pln"> non</span><span class="pun">-</span><span class="pln">null    float64
    </span><span class="lit">8</span><span class="pln">   </span><span class="typ">Comments</span><span class="pln">      </span><span class="lit">102</span><span class="pln"> non</span><span class="pun">-</span><span class="pln">null    int64  
    </span><span class="lit">9</span><span class="pln">   </span><span class="typ">Likes</span><span class="pln">         </span><span class="lit">102</span><span class="pln"> non</span><span class="pun">-</span><span class="pln">null    int64  
    </span><span class="lit">10</span><span class="pln">  </span><span class="typ">Hashtags</span><span class="pln">      </span><span class="lit">83</span><span class="pln"> non</span><span class="pun">-</span><span class="pln">null     object 
    </span><span class="lit">11</span><span class="pln">  </span><span class="typ">Cover</span><span class="pln">         </span><span class="lit">102</span><span class="pln"> non</span><span class="pun">-</span><span class="pln">null    int64  
    </span><span class="lit">12</span><span class="pln">  </span><span class="typ">Length</span><span class="pln">        </span><span class="lit">102</span><span class="pln"> non</span><span class="pun">-</span><span class="pln">null    int64  
    </span><span class="lit">13</span><span class="pln">  avg_watch     </span><span class="lit">102</span><span class="pln"> non</span><span class="pun">-</span><span class="pln">null    int64  
    </span><span class="lit">14</span><span class="pln">  </span><span class="typ">Location</span><span class="pln">      </span><span class="lit">101</span><span class="pln"> non</span><span class="pun">-</span><span class="pln">null    float64
    </span><span class="lit">15</span><span class="pln">  </span><span class="typ">Humor</span><span class="pln">         </span><span class="lit">101</span><span class="pln"> non</span><span class="pun">-</span><span class="pln">null    float64
    </span><span class="lit">16</span><span class="pln">  </span><span class="typ">Hat</span><span class="pln">           </span><span class="lit">100</span><span class="pln"> non</span><span class="pun">-</span><span class="pln">null    float64
    dtypes</span><span class="pun">:</span><span class="pln"> float64</span><span class="pun">(</span><span class="lit">5</span><span class="pun">),</span><span class="pln"> int64</span><span class="pun">(</span><span class="lit">10</span><span class="pun">),</span><span class="pln"> object</span><span class="pun">(</span><span class="lit">2</span><span class="pun">)</span><span class="pln">
    memory usage</span><span class="pun">:</span><span class="pln"> </span><span class="lit">13.7</span><span class="pun">+</span><span class="pln"> KB</span></pre>

<h2 id="-3">
	معالجة البيانات
</h2>

<p>
	سنضيف بهذه المرحلة معالجةً جيدةً لنظام توصيتنا ليكون أقرب إلى نظام التوصية المستخدم على تيكتوك. ونلاحظ كيفية معالجة البيانات وإدخالها بسهولة في النموذج.
</p>

<p>
	وفي أول خطوة من عملية المعالجة سنعمل على إزالة التكرارات، من خلال التحقق مما إذا كانت هناك أي أسماء مكررة للفيديوهات، فهي زائدة عن الحاجة بالنسبة للخوارزمية ويجب إزالتها.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3632_21" style=""><span class="com"># حساب عدد القيم المكررة في العمود</span><span class="pln">
ratings</span><span class="pun">.</span><span class="pln">duplicated</span><span class="pun">(</span><span class="pln">subset</span><span class="pun">=</span><span class="str">'Video_Name'</span><span class="pun">).</span><span class="pln">sum</span><span class="pun">()</span><span class="pln"> </span><span class="com"># 11</span><span class="pln">

</span><span class="com"># إزالة التكرار</span><span class="pln">
df </span><span class="pun">=</span><span class="pln"> ratings</span><span class="pun">.</span><span class="pln">drop_duplicates</span><span class="pun">(</span><span class="pln">subset</span><span class="pun">=</span><span class="str">'Video_Name'</span><span class="pun">)</span><span class="pln">

</span><span class="com"># التأكد من إزالة التكرار</span><span class="pln">
df</span><span class="pun">.</span><span class="pln">duplicated</span><span class="pun">(</span><span class="pln">subset</span><span class="pun">=</span><span class="str">'Video_Name'</span><span class="pun">).</span><span class="pln">sum</span><span class="pun">()</span><span class="pln"> </span><span class="com"># 0</span></pre>

<h3 id="-4">
	أخذ عينات عشوائية
</h3>

<p>
	بعد التأكد من إزالة التكرارات، سنعمل على حل المشاكل التي قد تقع بها الذاكرة، وسنعمل على أخذ عينات عشوائية على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3632_23" style=""><span class="pln">sample_size </span><span class="pun">=</span><span class="pln"> </span><span class="lit">91</span><span class="pln">  </span><span class="com"># عدد البيانات في الصفوف</span><span class="pln">
</span><span class="com"># أخذ العينة</span><span class="pln">
df </span><span class="pun">=</span><span class="pln"> df</span><span class="pun">.</span><span class="pln">sample</span><span class="pun">(</span><span class="pln">n</span><span class="pun">=</span><span class="pln">sample_size</span><span class="pun">,</span><span class="pln"> replace</span><span class="pun">=</span><span class="kwd">False</span><span class="pun">,</span><span class="pln"> random_state</span><span class="pun">=</span><span class="lit">80</span><span class="pun">)</span><span class="pln">

</span><span class="com"># إعادة ضبط الفهرس</span><span class="pln">
df </span><span class="pun">=</span><span class="pln"> df</span><span class="pun">.</span><span class="pln">reset_index</span><span class="pun">()</span><span class="pln">

</span><span class="com"># إزالة عمود 'index' الناتج من reset_index()</span><span class="pln">
df </span><span class="pun">=</span><span class="pln"> df</span><span class="pun">.</span><span class="pln">drop</span><span class="pun">(</span><span class="str">'index'</span><span class="pun">,</span><span class="pln"> axis</span><span class="pun">=</span><span class="lit">1</span><span class="pun">)</span></pre>

<h3 id="-5">
	تنظيف البيانات
</h3>

<p>
	ستحتاج البيانات الموجودة بقاعدة البيانات المستخدمة في هذه المرحلة الى التنظيف، ويكون ذلك من خلال ازالة المسافات البيضاء من عمود Video_Name لتجنب حدوث الأخطاء، إذ لو اعتمدنا التسمية العادية دون تنظيف، فقد يتسبب هذا بالحصول على نظام أقل دقة وصحة؛ فقد يعد الفيديو ?strong math for ml مثلًا و الفيديو strong opinion متشابهين.
</p>

<p>
	توضح الصورة التوضيحية التالية مثالًا عن ازالة المسافات البيضاء من أسماء الفيديوهات:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="JPG" data-fileid="171429" href="https://academy.hsoub.com/uploads/monthly_2025_04/005_.JPG.eb9cc4594b4a3c1633560dd7302c5174.JPG" rel=""><img alt="005 نظام التوصية" class="ipsImage ipsImage_thumbnailed" data-fileid="171429" data-unique="hveon071n" style="width: 700px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_04/005_.JPG.eb9cc4594b4a3c1633560dd7302c5174.JPG"> </a>
</p>

<p>
	وسنتتبع هنا كل مرحلة من مراحل تنظيف قاعدة البيانات، لتشمل كل أسماء الفيديوهات كما هو موضح في الكود كالتالي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3632_28" style=""><span class="kwd">def</span><span class="pln"> clean_Video_Name</span><span class="pun">(</span><span class="typ">Video_Name</span><span class="pun">):</span><span class="pln">
  result </span><span class="pun">=</span><span class="pln"> str</span><span class="pun">(</span><span class="typ">Video_Name</span><span class="pun">).</span><span class="pln">lower</span><span class="pun">()</span><span class="pln"> </span><span class="com"># تحويل النص إلى حروف صغيرة (lowercase)</span><span class="pln">
  </span><span class="kwd">return</span><span class="pun">(</span><span class="pln">result</span><span class="pun">.</span><span class="pln">replace</span><span class="pun">(</span><span class="str">' '</span><span class="pun">,</span><span class="str">''</span><span class="pun">))</span><span class="pln"> </span><span class="com"># إزالة المسافات من النص</span><span class="pln">

  df</span><span class="pun">[</span><span class="str">'Video_Name'</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> df</span><span class="pun">[</span><span class="str">'Video_Name'</span><span class="pun">].</span><span class="pln">apply</span><span class="pun">(</span><span class="pln">clean_Video_Name</span><span class="pun">)</span><span class="pln"> </span><span class="com"># يتم تطبيق التنظيف على كل قيمة في العمود باستخدام الدالة "clean_Video_Name"</span><span class="pln">
  df</span><span class="pun">.</span><span class="pln">head</span><span class="pun">()</span></pre>

<p>
	وستكون النتيجة على النحو:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="JPG" data-fileid="171423" href="https://academy.hsoub.com/uploads/monthly_2025_04/004_.JPG.dc769f17ab85cf4c0aee8337f9935a68.JPG" rel=""><img alt="004 نظام التوصية" class="ipsImage ipsImage_thumbnailed" data-fileid="171423" data-unique="7hbe10izq" style="width: 800px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_04/004_.thumb.JPG.49689dd330974feba3c7c6f1cdc48016.JPG"> </a>
</p>

<p>
	نحوّل الآن بيانات اسم الفيديو والوسوم إلى أحرف صغيرة:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3632_31" style=""><span class="com"># تحويل جميع القيم في عمود "Video_Name" إلى حروف صغيرة (lowercase)</span><span class="pln">
df</span><span class="pun">[</span><span class="str">'Video_Name'</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> df</span><span class="pun">[</span><span class="str">'Video_Name'</span><span class="pun">].</span><span class="pln">str</span><span class="pun">.</span><span class="pln">lower</span><span class="pun">()</span><span class="pln">

</span><span class="com"># تحويل جميع القيم في عمود "Hashtags" إلى حروف صغيرة (lowercase)</span><span class="pln">
df</span><span class="pun">[</span><span class="str">'Hashtags'</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> df</span><span class="pun">[</span><span class="str">'Hashtags'</span><span class="pun">].</span><span class="pln">str</span><span class="pun">.</span><span class="pln">lower</span><span class="pun">()</span><span class="pln">

</span><span class="com"># عرض أول خمس صفوف من DataFrame للتحقق من التغييرات</span><span class="pln">
df</span><span class="pun">.</span><span class="pln">head</span><span class="pun">()</span></pre>

<p>
	بعد ذلك ندمج الأعمدة المستخدمة في نظام التوصية، بحيث يتم تكوين نص واحد لكل صف يتكون من جميع القيم النصية التي كانت موجودة في الأعمدة.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3632_33" style=""><span class="com"># حذف الأعمدة غير المطلوبة</span><span class="pln">
df2 </span><span class="pun">=</span><span class="pln"> df</span><span class="pun">.</span><span class="pln">drop</span><span class="pun">([</span><span class="str">'Tech'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Upload_time'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Day'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Q_and_A'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'has_captions'</span><span class="pun">,</span><span class="pln"> 
            </span><span class="str">'Views'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Shares'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Comments'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Likes'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Cover'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Length'</span><span class="pun">,</span><span class="pln"> 
            </span><span class="str">'avg_watch'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Location'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Humor'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Hat'</span><span class="pun">],</span><span class="pln"> axis</span><span class="pun">=</span><span class="lit">1</span><span class="pun">)</span><span class="pln">

</span><span class="com"># تحقق من الأعمدة المتبقية</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">df2</span><span class="pun">.</span><span class="pln">columns</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">df2</span><span class="pun">.</span><span class="pln">head</span><span class="pun">())</span><span class="pln">

</span><span class="com"># دمج النصوص في الأعمدة المتبقية</span><span class="pln">
df2</span><span class="pun">[</span><span class="str">'Data'</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> df2</span><span class="pun">[</span><span class="pln">df2</span><span class="pun">.</span><span class="pln">columns</span><span class="pun">[</span><span class="lit">1</span><span class="pun">:]].</span><span class="pln">apply</span><span class="pun">(</span><span class="pln">
    </span><span class="kwd">lambda</span><span class="pln"> x</span><span class="pun">:</span><span class="pln"> </span><span class="str">' '</span><span class="pun">.</span><span class="pln">join</span><span class="pun">(</span><span class="pln">x</span><span class="pun">.</span><span class="pln">dropna</span><span class="pun">().</span><span class="pln">astype</span><span class="pun">(</span><span class="pln">str</span><span class="pun">)),</span><span class="pln">
    axis</span><span class="pun">=</span><span class="lit">1</span><span class="pln">
</span><span class="pun">)</span><span class="pln">

</span><span class="com"># عرض النتيجة</span><span class="pln">
    </span><span class="kwd">print</span><span class="pun">(</span><span class="pln">df2</span><span class="pun">[</span><span class="str">'Data'</span><span class="pun">].</span><span class="pln">head</span><span class="pun">())</span></pre>

<p>
	وستكون النتيجة كالتالي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="JPG" data-fileid="171430" href="https://academy.hsoub.com/uploads/monthly_2025_04/006_.JPG.2be246ba1003a4eafb10433506e7242e.JPG" rel=""><img alt="006 نظام التوصية" class="ipsImage ipsImage_thumbnailed" data-fileid="171430" data-unique="lh9kxlws8" style="width: 700px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_04/006_.thumb.JPG.72702f831b620065f65533baa819f102.JPG"> </a>
</p>

<h3 id="dataframe">
	تحويل أطر البيانات Dataframe إلى تمثيلات عددية
</h3>

<p>
	من أجل تحويل النصوص إلى تمثيلات عددية تعبر عن تكرار الكلمات في مجموعة النصوص من أجل تسهيل فهم النصوص وتحليلها بدقة من طرف النموذج، سوف نستخدم دالة ()CountVectorizer من مكتبة Scikit-Learn كالتالي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3632_35" style=""><span class="com"># استيراد CountVectorizer من مكتبة sklearn لتحويل النصوص إلى تمثيل عددي</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> sklearn</span><span class="pun">.</span><span class="pln">feature_extraction</span><span class="pun">.</span><span class="pln">text </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">CountVectorizer</span><span class="pln">

</span><span class="com"># إنشاء كائن CountVectorizer لتحويل النصوص إلى متجهات تمثل تكرار الكلمات</span><span class="pln">
vectorizer </span><span class="pun">=</span><span class="pln"> </span><span class="typ">CountVectorizer</span><span class="pun">()</span><span class="pln">

</span><span class="com"># تطبيق fit_transform على عمود 'Data' في DataFrame df2  لتحويل النصوص إلى تمثيل عددي</span><span class="pln">
</span><span class="com"># fit_transform تقوم بتدريب CountVectorizer على البيانات وتحويل النصوص إلى مصفوفة من التكرارات</span><span class="pln">
vectorized </span><span class="pun">=</span><span class="pln"> vectorizer</span><span class="pun">.</span><span class="pln">fit_transform</span><span class="pun">(</span><span class="pln">df2</span><span class="pun">[</span><span class="str">'Data'</span><span class="pun">])</span></pre>

<h3 id="-6">
	حساب تشابه الفيديوهات لبناء نظام التوصية
</h3>

<p>
	في أنظمة التوصية، الهدف الأساسي هو اقتراح محتوى يتناسب مع اهتمامات المستخدم. يعتمد ذلك على إيجاد تشابه بين المحتوى المعروض والمحتوى الذي سبق أن تفاعل معه المستخدم؛ إذ لو اعتمدنا فقط على التطابق الحرفي بين أسماء الفيديوهات أو الوسوم، فقد نفقد العديد من العلاقات المهمة بين المحتوى، فقد يحدث تشابه بالكلمات أحيانًا رغم وجود اختلاف تام بالمحتوى، بالتالي اقتراح الفيديو بناءً على الكلمات المستخدمة وحدها، لن يكون كافي، ولهذا السبب سنحول أسماء الفيديوهات والوسوم إلى متجهات عددية باستخدام دالة ()CountVectorizer، ثم نحسب درجة التشابه بين هذه المتجهات باستخدام دالة cosine_similarity من مكتبة sklearn.
</p>

<p>
	بمعنى آخر، يمكننا استخدام تشابه جيب التمام لقياس مدى تشابه الفيديوهات من خلال مقارنة تمثيل البيانات. اسم الفيديو والوسم.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3632_37" style=""><span class="com"># استيراد cosine_similarity من مكتبة sklearn  لحساب التشابه بين المتجهات باستخدام مقياس جيب التمام</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> sklearn</span><span class="pun">.</span><span class="pln">metrics</span><span class="pun">.</span><span class="pln">pairwise </span><span class="kwd">import</span><span class="pln"> cosine_similarity

</span><span class="com"># حساب التشابه بين المتجهات التي تم إنشاؤها باستخدام CountVectorizer</span><span class="pln">
</span><span class="com"># سيتم حساب تشابه جيب التمام بين كل زوج من المتجهات</span><span class="pln">
similarities </span><span class="pun">=</span><span class="pln"> cosine_similarity</span><span class="pun">(</span><span class="pln">vectorized</span><span class="pun">)</span><span class="pln">

</span><span class="com"># طباعة مصفوفة التشابه بين الفيديوهات أو النصوص</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">similarities</span><span class="pun">)</span></pre>

<p>
	نلاحظ النتيجة كالتالي :
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="JPG" data-fileid="171425" href="https://academy.hsoub.com/uploads/monthly_2025_04/002_.JPG.2858d4130448f0918128c8d607592e00.JPG" rel=""><img alt="002 نظام التوصية" class="ipsImage ipsImage_thumbnailed" data-fileid="171425" data-unique="vp8dymwr1" style="width: 700px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_04/002_.thumb.JPG.55ad6f27de934979ccbb308a7aff2d98.JPG"> </a>
</p>

<p>
	وكما هو واضح، تتراوح نتائج نسبة التشابه بين 0 و1، و يمثل كل متجه تشابه فيديو بالنسبة إلى فيديو آخر؛ لكن نظرًا لعدم ذكر عناوين الفيديوهات هنا، سنحتاج مجددًا لتعيين هذا المتجه إلى إطار البيانات السابق.
</p>

<p>
	<strong>ملاحظة</strong> : متجه التشابه هو تمثيل عددي يعبّر عن مدى التشابه بين كل فيديو وآخر. يتم حسابه باستخدام دالة Cosine Similarity، بحيث تكون كل قيمة في المتجه مؤشرًا على درجة القرب بين الفيديوهات بناءً على اسم الفيديو والوسم.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3632_39" style=""><span class="com"># تحويل مصفوفة التشابه إلى DataFrame باستخدام pandas</span><span class="pln">
</span><span class="com"># نقوم بتحديد الأعمدة على أنها أسماء الفيديوهات (من العمود 'Video_Name')، والصفوف على أنها الوسوم (من العمود #'Hashtags')</span><span class="pln">
df </span><span class="pun">=</span><span class="pln"> pd</span><span class="pun">.</span><span class="typ">DataFrame</span><span class="pun">(</span><span class="pln">similarities</span><span class="pun">,</span><span class="pln"> columns</span><span class="pun">=</span><span class="pln">df</span><span class="pun">[</span><span class="str">'Video_Name'</span><span class="pun">],</span><span class="pln"> index</span><span class="pun">=</span><span class="pln">df</span><span class="pun">[</span><span class="str">'Hashtags'</span><span class="pun">]).</span><span class="pln">reset_index</span><span class="pun">()</span><span class="pln">

</span><span class="com"># عرض أول 5 صفوف من DataFrame لتفقد النتيجة</span><span class="pln">
df</span><span class="pun">.</span><span class="pln">head</span><span class="pun">()</span></pre>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="171424" href="https://academy.hsoub.com/uploads/monthly_2025_04/001_.png.64e726ca996aafa10ae557c4a679cb8d.png" rel=""><img alt="001 نظام التوصية" class="ipsImage ipsImage_thumbnailed" data-fileid="171424" data-unique="wmyiqcrrm" style="width: 800px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_04/001_.thumb.png.cf8ee62d46a1c99d1ce8cfaceafc08d1.png"> </a>
</p>

<p>
	في هذه المرحلة حولنا متجه التشابه إلى إطار بيانات يحتوي على أسماء الفيديوهات المدرجة رأسيًا وأفقيًا. تمثل قيم إطار البيانات تشابه جيب التمام بين الفيديوهات المختلفة.
</p>

<p>
	نلاحظ أيضًا أن الخط القطري يساوي دائمًا 1.000، وهو يعرض تشابه كل فيديو مع نفسه.
</p>

<h3 id="-7">
	عرض التوصية للمستخدم
</h3>

<p>
	سنستخدم إطار البيانات السابق لعرض توصيات الفيديوهات للمستخدم، بحيث يتم ارجاع أفضل 5 فيديوهات مشابهة في حال إدخال فيديو واحد. كما يلي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3632_41" style=""><span class="com"># إذا كانت لديك مصفوفة التشابه 'similarities' وبيانات الفيديو 'df2'</span><span class="pln">
similarities_df </span><span class="pun">=</span><span class="pln"> pd</span><span class="pun">.</span><span class="typ">DataFrame</span><span class="pun">(</span><span class="pln">
    similarities</span><span class="pun">,</span><span class="pln"> 
    index</span><span class="pun">=</span><span class="pln">df2</span><span class="pun">[</span><span class="str">'Video_Name'</span><span class="pun">],</span><span class="pln"> 
    columns</span><span class="pun">=</span><span class="pln">df2</span><span class="pun">[</span><span class="str">'Video_Name'</span><span class="pun">]</span><span class="pln">
</span><span class="pun">)</span><span class="pln">

</span><span class="com"># دالة للحصول على التوصيات بناءً على الفيديو المدخل</span><span class="pln">
</span><span class="kwd">def</span><span class="pln"> get_recommendations</span><span class="pun">(</span><span class="pln">video_name</span><span class="pun">,</span><span class="pln"> top_n</span><span class="pun">=</span><span class="lit">5</span><span class="pun">):</span><span class="pln">
    </span><span class="kwd">if</span><span class="pln"> video_name </span><span class="kwd">in</span><span class="pln"> similarities_df</span><span class="pun">.</span><span class="pln">columns</span><span class="pun">:</span><span class="pln">
        recommendations </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
            similarities_df</span><span class="pun">[</span><span class="pln">video_name</span><span class="pun">]</span><span class="pln">
            </span><span class="pun">.</span><span class="pln">nlargest</span><span class="pun">(</span><span class="pln">top_n </span><span class="pun">+</span><span class="pln"> </span><span class="lit">1</span><span class="pun">)</span><span class="pln">   </span><span class="com"># الحصول على أفضل N+1 (بما في ذلك الفيديو نفسه)</span><span class="pln">
            </span><span class="pun">.</span><span class="pln">iloc</span><span class="pun">[</span><span class="lit">1</span><span class="pun">:]</span><span class="pln">   </span><span class="com"># إرجاع أسماء الفيديوهات الموصى بها</span><span class="pln">
        </span><span class="pun">)</span><span class="pln">
        </span><span class="kwd">return</span><span class="pln"> recommendations</span><span class="pun">.</span><span class="pln">index</span><span class="pun">.</span><span class="pln">tolist</span><span class="pun">()</span><span class="pln">  
    </span><span class="kwd">else</span><span class="pun">:</span><span class="pln">
        </span><span class="kwd">return</span><span class="pln"> f</span><span class="str">"'{video_name}' not found in the video list."</span><span class="pln">

</span><span class="com"># مثال للاستخدام</span><span class="pln">
input_video </span><span class="pun">=</span><span class="pln"> </span><span class="str">'strongopinionk8s'</span><span class="pln"> </span><span class="com"># نستبدله بالفيديو الذي نرغب في الحصول على التوصيات بناءً عليه</span><span class="pln">
recommended_videos </span><span class="pun">=</span><span class="pln"> get_recommendations</span><span class="pun">(</span><span class="pln">input_video</span><span class="pun">,</span><span class="pln"> top_n</span><span class="pun">=</span><span class="lit">5</span><span class="pun">)</span><span class="pln">

</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"Recommended videos:"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">recommended_videos</span><span class="pun">)</span></pre>

<p>
	وهنا سنلاحظ النتيجة المتمثلة في أحسن خمس فيديوهات مقترحة:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3632_43" style=""><span class="typ">Recommended</span><span class="pln"> videos</span><span class="pun">:</span><span class="pln">
</span><span class="pun">[</span><span class="str">'housefoundation'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'showinghowresucanworks'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'recommendeddatacourses'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'softwareengineering?'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'firstdataanalyticshw'</span><span class="pun">]</span></pre>

<h2>
	الخاتمة
</h2>

<p>
	يمكن القول أن خوارزميات أنظمة التوصية هي جوهر التجربة الرقمية المخصصة التي تقدمها منصات التواصل الاجتماعي؛ فمن خلال تحليل سلوك المستخدمين وتفاعلهم مع المحتوى، يمكن لهذه الخوارزميات أن تقدم توصيات دقيقة تتناسب مع اهتماماتهم الشخصية.
</p>

<p>
	باستخدام تقنيات مثل التعلم الآلي وتحليل البيانات الضخمة، تستمر هذه الأنظمة في تحسين دقة التوصيات مع مرور الوقت، مما يعزز تجربة المستخدم بشكل كبير.
</p>

<h2>
	المصادر
</h2>

<ul>
	<li>
		<a href="https://github.com/Peter-Lankton/tik-tok-data/blob/main/tik_tok_analytics.csv" rel="external nofollow">tik-tok-data</a>
	</li>
	<li>
		<a href="https://medium.com/@pankajjha12104/tiktok-algorithm-with-machine-learning-55e4c47f2fe1" rel="external nofollow">TikTok Algorithm with Machine Learning</a>
	</li>
	<li>
		<a href="https://www.geeksforgeeks.org/recommendation-system-in-python/" rel="external nofollow">Recommendation System in Python</a>
	</li>
	<li>
		<a href="https://knightcolumbia.org/content/understanding-social-media-recommendation-algorithms" rel="external nofollow">Understanding Social Media Recommendation Algorithms</a>
	</li>
	<li>
		<a href="https://github.com/jvonfeldt/TikTokData" rel="external nofollow">TikTokData</a>
	</li>
</ul>

<h2 id="-8">
	اقرأ أيضًا
</h2>

<ul>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A7%D9%84%D8%AA%D9%85%D8%AB%D9%8A%D9%84-%D8%A7%D9%84%D9%85%D8%B1%D8%A6%D9%8A-%D9%84%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-scikit-learn-%D9%85%D8%B9-matplotlib-%D9%88-seaborn-r2553/" rel="">التمثيل المرئي للبيانات باستخدام Scikit-Learn مع Matplotlib و Seaborn</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AE%D9%88%D8%A7%D8%B1%D8%B2%D9%85%D9%8A%D8%A7%D8%AA-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A/" rel="">خوارزميات الذكاء الاصطناعي</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A7%D9%84%D8%AA%D9%81%D8%A7%D8%B9%D9%84-%D9%85%D8%B9-%D8%B1%D8%B3%D8%A7%D8%A6%D9%84-whatsapp-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-r2550/" rel="">التفاعل مع رسائل WhatsApp باستخدام الذكاء الاصطناعي</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">2566</guid><pubDate>Tue, 29 Apr 2025 16:04:01 +0000</pubDate></item><item><title>&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; &#x62E;&#x648;&#x627;&#x631;&#x632;&#x645;&#x64A;&#x629; &#x627;&#x644;&#x627;&#x646;&#x62D;&#x62F;&#x627;&#x631; &#x627;&#x644;&#x644;&#x648;&#x62C;&#x633;&#x62A;&#x64A; Logistic Regression &#x641;&#x64A; Scikit-Learn</title><link>https://academy.hsoub.com/programming/artificial-intelligence/%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%AE%D9%88%D8%A7%D8%B1%D8%B2%D9%85%D9%8A%D8%A9-%D8%A7%D9%84%D8%A7%D9%86%D8%AD%D8%AF%D8%A7%D8%B1-%D8%A7%D9%84%D9%84%D9%88%D8%AC%D8%B3%D8%AA%D9%8A-logistic-regression-%D9%81%D9%8A-scikit-learn-r2563/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2025_04/004.LogisticRegressionScikit-Learn.png.4d954fd4ef10a21675e8c1bdb711e1e6.png" /></p>
<p>
	تعرفنا في <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%AE%D9%88%D8%A7%D8%B1%D8%B2%D9%85%D9%8A%D8%A9-%D8%A3%D9%82%D8%B1%D8%A8-%D8%A7%D9%84%D8%AC%D9%8A%D8%B1%D8%A7%D9%86-k-nearest-neighbors-%D9%81%D9%8A-scikit-learn-r2560/" rel="">المقال السابق</a> على خوارزمية أقرب الجيران K-Nearest Neighbors، ووضحنا كيفية استخدامها عمليًا من خلال تمارين وتطبيقات متنوعة، وسنشرح اليوم خوارزمية أساسية من خوارزميات الذكاء الاصطناعي وهي خوارزمية الانحدار اللوجيستي Logistic Regression مع تطبيقات عملية باستخدام مكتبة ساي كيت ليرن ومجموعة بيانات أزهار آيرس Iris dataset.
</p>

<p>
	سنمر في البداية على جميع الخطوات التي تدربنا عليها في الأجزاء السابقة بإيجاز، ثم سنشرح آلية عمل خوارزمية الانحدار اللوجيستي المستخدمة بشكل أساسي في مهام التصنيف الثنائي binary classification، كما سنتطرق لبعض الطرق التي تسمح لنا باستخدام هذه الخوارزمية مع مهام التصنيف المتعدد multi classification.
</p>

<h2>
	مفهوم الانحدار اللوجيستي
</h2>

<p>
	تحليل الانحدار regression analysis هو أداة إحصائية مفيدة لفهم العلاقة بين متغيرات مختلفة، يساعدنا على تخمين أو توقع كيف يؤثر شيء ما يسمى المتغير المستقل independent variable على شيء آخر يسمى المتغير المعتمد dependent variable. مثلًا يمكننا معرفة كيف يؤثر عدد ساعات الدراسة على درجات الطلاب في الامتحان من خلال تحليل الانحدار واكتشاف العلاقة بين هذين المتغيرين وتحديد إن كان عدد الساعات يؤثر فعلاً في الدرجات أم لا، وفي  مجموعة بيانات  أزهار آيرس يمكننا استخدامه لاستكشاف العلاقة بين طول السبلة Sepal length وعرض البتلة Petal width على سبيل المثال.
</p>

<p>
	هناك نوع خاص من الانحدار يطلق عليه اسم الانحدار اللوجيستي Logistic Regression نستخدمه عندما نريد التنبؤ بنتيجة تصنيف ثنائي binary classification نتيجته إما نعم أو لا، حيث تستخدم خوارزمية الانحدار اللوجيستي logistic regression <a href="https://ar.wikipedia.org/wiki/%D8%AF%D8%A7%D9%84%D8%A9_%D8%B3%D9%8A%D9%86%D9%8A%D8%A9" rel="external nofollow">دالة سينية sigmoid function</a> تسمى بالدالة اللوجيستية logistic function والتي تحوّل المدخلات إلى قيم تقع بين الصفر والواحد مما يجعلها مناسبة لمهام التصنيف الثنائي.
</p>

<p>
	يمكننا أن ننظر إلى طريقة عمل خوارزمية الانحدار اللوجيستي على أنها خوارزمية تتكون من خطوتين الأولى هي إيجاد أفضل معادلة خطية تربط بين المدخلات أو المتغيرات المستقلة وبين المخرجات أي المتغيرات المعتمدة، بحيث نوجد أفضل خط يساير fitting البيانات، كما في خوارزمية توقع الانحدار الخطي.
</p>

<p>
	الخطوة الثانية هي تحويل القيمة المستمرة الخارجة من خوارزمية توقع الانحدار الخطي إلى احتمالية بين الصفر والواحد باستخدام الدالة اللوجيستية logistic function، والتصنيف ذو الاحتمال الأكبر هو توقع النموذج.
</p>

<p>
	يمكننا كذلك استخدام خوارزمية الانحدار اللوجيستي مع مشكلات التصنيف المتعدد multi classification باستخدام خدعة بسيطة تسمى واحد ضد الجميع One Vs All والتي تعرف اختصارًا OVA، حيث نعمل على تدريب عدد من المصنفات الثنائية binary classifiers يساوي عدد التصنيفات classes الموجودة في البيانات، وتكون مهمة كل مصنف classifier التمييز بين تصنيف محدد ونرمز له رقميًا بواحد 1 وما دون ذلك من التصنيفات نرمز لها جميعًا بصفر 0.
</p>

<p>
	يمكننا في مكتبة scikit-learn، استخدام خوارزمية الانحدار اللوجستي لمهام التصنيف المتعدد باستخدام الدالة <code>softmax</code> التي تحدد احتمالية انتماء كل عينة إلى إحدى التصنيفات المتعددة، بحيث يكون مجموع الاحتمالات لجميع التصنيفات classes  مساويًا لواحد، بينما نستخدم الدالة <code>sigmoid</code> في مهام التصنيف الثنائي فقط.
</p>

<h3 id="1dataexploring">
	استكشاف مجموعة البيانات Data Exploring
</h3>

<p>
	سنكتب برنامج بايثون لعرض المعلومات الإحصائية الأساسية لفصائل أزهار آيرس المختلفة Iris-setosa و Iris-versicolor و Iris-virginica على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_9345_11" style=""><span class="kwd">import</span><span class="pln"> pandas </span><span class="kwd">as</span><span class="pln"> pd

iris </span><span class="pun">=</span><span class="pln"> pd</span><span class="pun">.</span><span class="pln">read_csv</span><span class="pun">(</span><span class="str">"iris.csv"</span><span class="pun">)</span><span class="pln">
</span><span class="com"># قائمة بجميع الفصائل</span><span class="pln">
</span><span class="typ">SpeciesList</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> iris</span><span class="pun">.</span><span class="typ">Species</span><span class="pun">.</span><span class="pln">value_counts</span><span class="pun">().</span><span class="pln">index
</span><span class="com"># حلقة تكرارية لحساب الإحصائيات لكل فصيلة</span><span class="pln">
</span><span class="kwd">for</span><span class="pln"> s </span><span class="kwd">in</span><span class="pln"> </span><span class="typ">SpeciesList</span><span class="pun">:</span><span class="pln">
    </span><span class="kwd">print</span><span class="pun">(</span><span class="pln">f</span><span class="str">"Statistics about {s}"</span><span class="pun">)</span><span class="pln">
    </span><span class="com"># حساب الإحصائيات لشريحة البيانات التي تنتمي للفصيلة الحالية</span><span class="pln">
    </span><span class="kwd">print</span><span class="pun">(</span><span class="pln">iris</span><span class="pun">[</span><span class="pln">iris</span><span class="pun">.</span><span class="typ">Species</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> s</span><span class="pun">].</span><span class="pln">describe</span><span class="pun">())</span></pre>

<p>
	يعمل الكود السابق على توليد إحصائيات وصفية لكل فصيلة من فصائل الأزهار الموجودة في المجموعة. حيث يسمح لنا الشرط <code>[iris[iris.Species == s</code> باختيار العينات التي تحقق هذا الشرط، أي أننا سنختار في كل تكرار للحلقة العينات التي تنتمي للفصيلة <code>s</code> ثم سنستخدام التابع <code>data.describe()‎</code> للحصول على معلومات إحصائية تخص هذه العينات، مثل أكبر وأصغر قيمة في البيانات والمتوسط الحسابي للقيم والانحراف المعياري.
</p>

<p>
	عند تنفيذ الكود سنحصل على الخرج التالي:
</p>

<pre class="ipsCode">Statistics about Iris-setosa
             Id  SepalLengthCm  SepalWidthCm  PetalLengthCm  PetalWidthCm
count  50.00000       50.00000     50.000000      50.000000      50.00000
mean   25.50000        5.00600      3.418000       1.464000       0.24400
std    14.57738        0.35249      0.381024       0.173511       0.10721
min     1.00000        4.30000      2.300000       1.000000       0.10000
25%    13.25000        4.80000      3.125000       1.400000       0.20000
50%    25.50000        5.00000      3.400000       1.500000       0.20000
75%    37.75000        5.20000      3.675000       1.575000       0.30000
max    50.00000        5.80000      4.400000       1.900000       0.60000
Statistics about Iris-versicolor
              Id  SepalLengthCm  SepalWidthCm  PetalLengthCm  PetalWidthCm
count   50.00000      50.000000     50.000000      50.000000     50.000000
mean    75.50000       5.936000      2.770000       4.260000      1.326000
std     14.57738       0.516171      0.313798       0.469911      0.197753
min     51.00000       4.900000      2.000000       3.000000      1.000000
25%     63.25000       5.600000      2.525000       4.000000      1.200000
50%     75.50000       5.900000      2.800000       4.350000      1.300000
75%     87.75000       6.300000      3.000000       4.600000      1.500000
max    100.00000       7.000000      3.400000       5.100000      1.800000
Statistics about Iris-virginica
              Id  SepalLengthCm  SepalWidthCm  PetalLengthCm  PetalWidthCm
count   50.00000       50.00000     50.000000      50.000000      50.00000
mean   125.50000        6.58800      2.974000       5.552000       2.02600
std     14.57738        0.63588      0.322497       0.551895       0.27465
min    101.00000        4.90000      2.200000       4.500000       1.40000
25%    113.25000        6.22500      2.800000       5.100000       1.80000
50%    125.50000        6.50000      3.000000       5.550000       2.00000
75%    137.75000        6.90000      3.175000       5.875000       2.30000
max    150.00000        7.90000      3.800000       6.900000       2.50000
Index(['Id', 'SepalLengthCm', 'SepalWidth
</pre>

<h3 id="2datavisualization">
	عرض العلاقة بين البيانات باستخدام التمثيل المرئي Data Visualization
</h3>

<p>
	سننشئ الآن رسم بياني نقطي Scatter plot لعرض العلاقة بين طول السبلة Sepal length وعرض البتلة Petal width، لنحقق ذلك نكتب الكود التالي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_9345_15" style=""><span class="kwd">import</span><span class="pln"> matplotlib</span><span class="pun">.</span><span class="pln">pyplot </span><span class="kwd">as</span><span class="pln"> plt
</span><span class="kwd">import</span><span class="pln"> seaborn </span><span class="kwd">as</span><span class="pln"> sns

iris </span><span class="pun">=</span><span class="pln"> pd</span><span class="pun">.</span><span class="pln">read_csv</span><span class="pun">(</span><span class="str">"iris.csv"</span><span class="pun">)</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">figure</span><span class="pun">(</span><span class="pln">figsize</span><span class="pun">=(</span><span class="lit">7</span><span class="pun">,</span><span class="lit">7</span><span class="pun">),</span><span class="pln"> dpi</span><span class="pun">=</span><span class="lit">150</span><span class="pun">)</span><span class="pln">
sns</span><span class="pun">.</span><span class="pln">scatterplot</span><span class="pun">(</span><span class="pln">data</span><span class="pun">=</span><span class="pln">iris</span><span class="pun">,</span><span class="pln"> x</span><span class="pun">=</span><span class="str">"SepalLengthCm"</span><span class="pun">,</span><span class="pln"> y</span><span class="pun">=</span><span class="str">"PetalWidthCm"</span><span class="pun">,</span><span class="pln"> hue</span><span class="pun">=</span><span class="str">"Species"</span><span class="pun">)</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">show</span><span class="pun">()</span></pre>

<p>
	استوردنا في هذا الكود مكتبة matplotlib لضبط إعدادات الرسم البياني من أبعاد الشكل ودقة الصورة الناتجة، كما استوردنا مكتبة seaborn التي توفر واجهة استخدام سهلة ومرنة للرسم.
</p>

<p>
	بعدها مررنا للدالة <code>sns.scatterplot</code> المعامل <code>data </code>لتحديد مجموعة البيانات التي سنعمل عليها، وحددنا بأن المحور الأفقي سيكون طول السبلات، وأن المحور العمودي سيكون عرض البتلات، ستمثل كل زهرة بنقطة في الشكل الناتج وتلون كل نقطة وفقًا لانتمائها لأحد الفصائل الثلاثة في مجموعة بيانات أزهار آيرس.
</p>

<p>
	عند تنفيذ الكود سنحصل على الرسم البياني التالي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="171212" href="https://academy.hsoub.com/uploads/monthly_2025_04/Iris_sepal_petal.png.15137927a88388fa8dd46d7731cc5d45.png" rel=""><img alt="001 iris sepal petal" class="ipsImage ipsImage_thumbnailed" data-fileid="171212" data-unique="46t5o7ddt" style="width: 500px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_04/Iris_sepal_petal.thumb.png.c46172fe78b250d5e97a20cd98532190.png"> </a>
</p>

<h3 id="3logisticregression">
	تصنيف فصائل الأزهار باستخدام خوارزمية الانحدار اللوجستي
</h3>

<p>
	سنكتب الآن برنامج بايثون لتدريب نموذج الانحدار اللوجيستي Logistic Regression على مجموعة بيانات أزهار آيرس التي تحتوي على ثلاثة فصائل من الأزهار للتمييز فيما بينها، ثم نقيم أداء النموذج على مجموعة الاختبار.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_9345_17" style=""><span class="kwd">import</span><span class="pln"> pandas </span><span class="kwd">as</span><span class="pln"> pd
</span><span class="kwd">from</span><span class="pln"> sklearn</span><span class="pun">.</span><span class="pln">model_selection </span><span class="kwd">import</span><span class="pln"> train_test_split  
</span><span class="kwd">from</span><span class="pln"> sklearn </span><span class="kwd">import</span><span class="pln"> metrics
</span><span class="kwd">from</span><span class="pln"> sklearn</span><span class="pun">.</span><span class="pln">linear_model </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">LogisticRegression</span><span class="pln">

iris </span><span class="pun">=</span><span class="pln"> pd</span><span class="pun">.</span><span class="pln">read_csv</span><span class="pun">(</span><span class="str">"iris.csv"</span><span class="pun">)</span><span class="pln">
</span><span class="com"># Id احذف عمود </span><span class="pln">
</span><span class="com"># لعدم أهميته في عملية التعلم</span><span class="pln">
iris </span><span class="pun">=</span><span class="pln"> iris</span><span class="pun">.</span><span class="pln">drop</span><span class="pun">(</span><span class="str">'Id'</span><span class="pun">,</span><span class="pln">axis</span><span class="pun">=</span><span class="lit">1</span><span class="pun">)</span><span class="pln">
</span><span class="com"># خواص الأزهار</span><span class="pln">
X </span><span class="pun">=</span><span class="pln"> iris</span><span class="pun">.</span><span class="pln">iloc</span><span class="pun">[:,</span><span class="pln"> </span><span class="pun">:-</span><span class="lit">1</span><span class="pun">].</span><span class="pln">values
</span><span class="com"># وسم الأزهار</span><span class="pln">
y </span><span class="pun">=</span><span class="pln"> iris</span><span class="pun">.</span><span class="pln">iloc</span><span class="pun">[:,</span><span class="pln"> </span><span class="lit">4</span><span class="pun">].</span><span class="pln">values

</span><span class="com"># تقسيم مجموعة البيانات إلى مجموعة بيانات تدريب ومجموعة بيانات اختبار </span><span class="pln">
X_train</span><span class="pun">,</span><span class="pln"> X_test</span><span class="pun">,</span><span class="pln"> y_train</span><span class="pun">,</span><span class="pln"> y_test </span><span class="pun">=</span><span class="pln"> train_test_split</span><span class="pun">(</span><span class="pln">X</span><span class="pun">,</span><span class="pln"> y</span><span class="pun">,</span><span class="pln"> test_size</span><span class="pun">=</span><span class="lit">0.20</span><span class="pun">)</span><span class="pln"> 

</span><span class="com"># إنشاء نموذج </span><span class="pln">
model </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LogisticRegression</span><span class="pun">(</span><span class="pln">random_state</span><span class="pun">=</span><span class="lit">0</span><span class="pun">,</span><span class="pln"> multi_class</span><span class="pun">=</span><span class="str">'multinomial'</span><span class="pun">)</span><span class="pln">
model</span><span class="pun">.</span><span class="pln">fit</span><span class="pun">(</span><span class="pln">X_train</span><span class="pun">,</span><span class="pln">y_train</span><span class="pun">)</span><span class="pln">
prediction</span><span class="pun">=</span><span class="pln">model</span><span class="pun">.</span><span class="pln">predict</span><span class="pun">(</span><span class="pln">X_test</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">'The accuracy of the Logistic Regression is'</span><span class="pun">,</span><span class="pln"> metrics</span><span class="pun">.</span><span class="pln">accuracy_score</span><span class="pun">(</span><span class="pln">prediction</span><span class="pun">,</span><span class="pln">y_test</span><span class="pun">))</span></pre>

<p>
	استوردنا في البداية عددًا من الدوال والمكتبات التي ستساعدنا في تدريب وتقييم النموذج، واستدعينا الدالة <code>train_test_split</code> لتقسم خاصيات مجموعة البيانات dataset features ووسوم البيانات dataset labels إلى مجموعتي تدريب واختبار كل منها يمتلك جزءًا من خاصيات مجموعة البيانات والوسوم المقابلة للعينات المختارة، وحددنا نسبة التقسيم باستخدام التعليمة <code>test_size=0.20</code> لجعل عشرين بالمائة من مجموعة البيانات مجموعة اختبار، والنسبة الباقية للتدريب، ستُقسَم البيانات بشكل عشوائي في كل مرة نشغل بها الكود، ثم عرفنا كائن <code>model</code> يطبق خوارزمية الانحدار اللوجيستي ومررنا له المتغير <code>random_state=0</code> لنضمن ثبات نتيجة تدريب النموذج عند تشغيل الكود أكثر من مرة، وحددنا نوع المشكلة بأنه تصنيف متعدد بضبط قيمة المعامل <code>multi_class</code> إلى <code>multinomial</code>.
</p>

<p>
	بعد أن هيئنا إعدادات النموذج سندربه على مجموعة بيانات التدريب باستخدام الدالة <code>model.fit(X_train,y_train)‎</code>، وبعد تدريب النموذج يمكننا استخدامه في تخمين الوسوم لمجموعة الاختبار باستخدام الدالة <code>model.predict(X_test)‎</code>. نخزن الناتج في القائمة <code>prediction</code> التي تحتوي محاولة النموذج لتوقع قيم <code>y_test</code>، ولتقييم دقة النموذج في هذه المحاولة نستخدم الدالة <code>metrics.accuracy_score(prediction,y_test)‎</code> التي تحصي نسبة القيم التي توقعها النموذج بشكل صحيح إلى إجمالي جميع القيم.
</p>

<p>
	عند تنفيذ الكود سنحصل على الخرج التالي:
</p>

<pre class="ipsCode" id="ips_uid_9345_20">The accuracy of the Logistic Regression is 0.9333333333333333
</pre>

<p>
	تعني النتيجة التي حصلنا عليها أن النموذج جيد جدًا في التنبؤ، لأنه أصاب في أكثر من 93% من الحالات فهذه النسبة تمثل نسبة العينات التي صنفها النموذج بشكل صحيح وتعرف باسم دقة النموذج، لكن الدقة ليست دائمًا المقياس الوحيد الكافي، خصوصًا في المشكلات التي يكون فيها عدد العينات في كل فئة غير متوازن لذا قد نحتاج لمقاييس إضافية لتقييم النموذج بشكل عادل.
</p>

<h2 id="-1">
	الخاتمة
</h2>

<p>
	تعرفنا في هذه المقالة على خوارزمية الانحدار اللوجيستي Logistic Regression وكيف تعمل، وطبقناها باستخدام مكتبة ساي كيت ليرن على <span ipsnoautolink="true">مجموعة بيانات أزهار إيرس</span>، وقيمنا دقة النموذج على مجموعة بيانات اختبارية، يمكن مواصلة التدريب على مجموعات بيانات مختلفة أكبر في الحجم وتحتاج للمزيد من المعالجة، حيث تتوفر الكثير من مجموعات البيانات مفتوحة المصدر على <a href="https://www.kaggle.com/datasets" rel="external nofollow">موقع Kaggle</a>.
</p>

<h2 id="-2">
	اقرأ أيضًا
</h2>

<ul>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%AE%D9%88%D8%A7%D8%B1%D8%B2%D9%85%D9%8A%D8%A9-%D8%A3%D9%82%D8%B1%D8%A8-%D8%A7%D9%84%D8%AC%D9%8A%D8%B1%D8%A7%D9%86-k-nearest-neighbors-%D9%81%D9%8A-scikit-learn-r2560/" rel="">استخدام خوارزمية أقرب الجيران k-Nearest Neighbors في Scikit-Learn</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D9%85%D9%83%D8%AA%D8%A8%D8%A9-scikit-learn-%D9%88%D8%A3%D9%87%D9%85-%D8%AE%D9%88%D8%A7%D8%B1%D8%B2%D9%85%D9%8A%D8%A7%D8%AA%D9%87%D8%A7-r2485/" rel="">تعرف على مكتبة Scikit learn وأهم خوارزمياتها</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/python/%D8%A7%D9%84%D8%A7%D9%86%D8%AD%D8%AF%D8%A7%D8%B1-%D8%A7%D9%84%D8%A5%D8%AD%D8%B5%D8%A7%D8%A6%D9%8A-regression-%D9%88%D8%AF%D9%88%D8%B1%D9%87-%D9%81%D9%8A-%D9%85%D9%84%D8%A7%D8%A1%D9%85%D8%A9-%D8%A7%D9%84%D9%86%D9%85%D8%A7%D8%B0%D8%AC-%D8%A7%D9%84%D9%85%D8%AE%D8%AA%D9%84%D9%81%D8%A9-%D9%85%D8%B9-%D8%A3%D9%86%D9%88%D8%A7%D8%B9-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D8%A7%D9%84%D9%85%D8%AA%D8%A7%D8%AD%D8%A9-r1493/" rel="">الانحدار الإحصائي regression ودوره في ملاءمة النماذج المختلفة مع أنواع البيانات المتاحة</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/python/%D8%A7%D9%84%D8%B9%D9%84%D8%A7%D9%82%D8%A7%D8%AA-%D8%A8%D9%8A%D9%86-%D8%A7%D9%84%D9%85%D8%AA%D8%BA%D9%8A%D8%B1%D8%A7%D8%AA-%D8%A7%D9%84%D8%A5%D8%AD%D8%B5%D8%A7%D8%A6%D9%8A%D8%A9-%D9%88%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%AA%D9%86%D9%81%D9%8A%D8%B0%D9%87%D8%A7-%D9%81%D9%8A-%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-r1381/" rel="">العلاقات بين المتغيرات الإحصائية وكيفية تنفيذها في بايثون</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">2563</guid><pubDate>Fri, 25 Apr 2025 13:08:02 +0000</pubDate></item><item><title>&#x62A;&#x62C;&#x631;&#x628;&#x629; &#x62A;&#x637;&#x648;&#x64A;&#x631; &#x646;&#x638;&#x627;&#x645; RAG &#x628;&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; DeepSeek &#x648;Ollama</title><link>https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%AC%D8%B1%D8%A8%D8%A9-%D8%AA%D8%B7%D9%88%D9%8A%D8%B1-%D9%86%D8%B8%D8%A7%D9%85-rag-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-deepseek-%D9%88ollama-r2562/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2025_05/1.----RAG--DeepSeek-Ollama-02.png.bf3b6a13de0202927fc5cc692a3c13df.png" /></p>
<p>
	تخيل أن أمامك كومةً ضخمةً من ملفات PDF، وأنك بحاجة إلى إجابة سريعة على سؤال محدد. البحث اليدوي قد يستغرق ساعات، ولكن ماذا لو كان بالإمكان طرح سؤال على الآلة والحصول على إجابة دقيقة في ثوانٍ؟ أو ربما الحصول على تلخيص نصوص طويلة بلمسة زر واحدة؟
</p>

<p>
	في الواقع، يمكن القيام بالأمر بسهولة، إذ لم يعد العثور على المعلومات الدقيقة واستخراجها أمرًا معقدًا بفضل تقنيات الذكاء الاصطناعي المتقدمة، وأحد أبرزها أنظمة RAG.
</p>

<p>
	أنظمة التوليد المعزز بالاسترجاع أو ما يُعرف اختصارًا بأنظمة RAG هي تقنية متقدمة في الذكاء الاصطناعي تجمع بين استرجاع المعلومات من مصادر خارجية وتوليد النصوص، مما يتيح تقديم إجابات أكثر دقة وأمان. تعمل هذه الأنظمة كوسيط ذكي بين البحث والتوليد، مما يسمح بفهم أعمق للمحتوى، والإجابة على الأسئلة المعقدة، وتلخيص النصوص الطويلة بكفاءة عالية، دون الحاجة إلى إعادة تدريب النموذج على بيانات جديدة باستمرار.
</p>

<h2 id="">
	فكرة المشروع الذي تحتويه المقالة
</h2>

<p>
	يهدف هذا المشروع إلى تطوير  نظام RAG يمكننا من الحصول على المعلومات المطلوبة بسرعة والحصول على ملخصات دقيقة للمفاهيم التي نحتاجها من كتاب <a href="https://academy.hsoub.com/files/7-%D8%B7%D8%B1%D9%8A%D9%82%D9%83-%D8%A5%D9%84%D9%89-%D8%A7%D9%84%D8%B9%D9%85%D9%84-%D8%A7%D9%84%D8%AD%D8%B1-%D8%B9%D8%A8%D8%B1-%D8%A7%D9%84%D8%A5%D9%86%D8%AA%D8%B1%D9%86%D8%AA/" rel="">طريقك إلى العمل الحر عبر الإنترنت</a>، ويسمح بطرح الأسئلة حول محتوى الكتاب والحصول على إجابات موجزة، مما يسهل مراجعة المعلومات واستذكارها بكفاءة.
</p>

<p>
	سنعتمد في العمل على النظام على DeepSeek لاسترجاع المعلومات من الكتاب بدقة، بينما يُستخدم Ollama لإنشاء ردود ذكية قائمة على السياق المسترجع.
</p>

<p>
	مع ذلك هناك أمر مهم جدًا يجب توضيحه، رغم قوة DeepSeek-R1 الذي سنستخدمه في المقال مع اللغات الأجنبية، إلا أنه وللأسف لا يقدم أداءً مثاليًا مع اللغة العربية بسبب محدودية التدريب على النصوص العربية مقارنةً باللغات الأخرى مثل الإنجليزية. ولحل هذه المشكلة، تطلب منا الأمر استخدام نماذج أكبر مثل DeepSeek R1-70B للحصول على النتائج الدقيقة عالية الجودة التي ستجدها بالمقال، لكن تطبيقك لشبيه به، سيعتمد على توفر موارد حاسوبية كافية؛ أما في حال لم تكن هذه الموارد متاحة، فيمكن الاستفادة من نفس الطريقة لتطبيق النظام على نماذج أخرى تدعم اللغة العربية بكفاءة أكبر مثل Qwen، أو استخدامه مع لغات أخرى مثل الإنجليزية التي تتمتع بدعم أفضل.
</p>

<h2 id="-1">
	خطوات العمل على المشروع
</h2>

<p>
	يعتمد مشروعنا على دمج مرحلتين أساسيتين:
</p>

<ol>
	<li>
		<strong>إسترجاع المعلومات</strong>: عند إدخال سؤال، يبدأ النظام بالبحث في قاعدة البيانات التي استخرجها من الكتاب عن أكثر المعلومات ذات الصلة، والتي تساعد في الإجابة على السؤال توليد
	</li>
	<li>
		<strong>توليد النصوص</strong>: بعد استرجاع المعلومات من قاعدة البيانات الخاصة بالكتاب، تُنقل لنموذج توليد النص، لينشئ لنا إجابة دقيقة تعتمد على المعلومات المسترجعة من الكتاب فقط
	</li>
</ol>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="171114" href="https://academy.hsoub.com/uploads/monthly_2025_04/---.png.f05c4892bae83dcf1b88e42de7abb517.png" rel=""><img alt="عملية استرجاع البيانات وتوليدها" class="ipsImage ipsImage_thumbnailed" data-fileid="171114" data-ratio="47.71" data-unique="04sxy7xdt" style="width: 700px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_04/---.thumb.png.87fb2dfa59e41e3ba5c3b1963e0f4d69.png"></a>
</p>

<h2 id="-2">
	تحضير بيئة العمل على المشروع
</h2>

<p>
	من أجل تنفيذ هذا المشروع، سنحتاج إلى الأدوات الآتية:
</p>

<h3 id="-3">
	تحميل مكتبات وأطر عمل لغة بايثون المطلوبة
</h3>

<p>
	سنستعمل في نظامنا المكتبات التالية:
</p>

<ul>
	<li>
		<strong>مكتبة HuggingFace Embeddings</strong>: وهي المكتبة المسئولة عن البصمات الرقمية للنصوص، حجمها خفيف وتلائم الأجهزة الضعيفة نسبيًا
	</li>
	<li>
		<strong>مكتبة PyPDFLoader</strong>: وهي المكتبة المسئولة عن التعامل مع ملفات PDF، سريعة المعالجة ولا تستهلك الكثير من الوقت
	</li>
	<li>
		<strong>مكتبة Faiss</strong>: وهي المكتبة المسئولة عن إنشاء قاعدة بيانات تخزن فيها المعلومات واسترجاعها عند الحاجة، وهي أشهر مكتبة حاليا
	</li>
</ul>

<p>
	وسنستعمل أطر العمل Frameworks التالية:
</p>

<ul>
	<li>
		<strong>إطار العمل Langchain</strong>: وهو البيئة المسئولة عن بناء تطبيقات الذكاء الاصطناعي المتكاملة
	</li>
	<li>
		<strong>إطار العمل Streamlit</strong>: المسئول عن توفير واجهة ويب تفاعلية لعرض النتائج بوضوح، نستعملها لبساطتها ولأنها توفر في ذاكرة الوصول العشوائي RAM
	</li>
</ul>

<p>
	إذا كنا نستعمل مثبّت conda أو mini-conda، فيمكننا تثبيت المكتبات والأطر المطلوبة عبر سطر الأوامر Terminal مباشرةً على النحو الآتي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_8672_11" style=""><span class="com"># تثبيت المكتبات وأطر العمل التي نحتاجها للعمل عبر مثبِّت conda</span><span class="pln">
conda install </span><span class="pun">-</span><span class="pln">c conda</span><span class="pun">-</span><span class="pln">forge streamlit pdfplumber langchain faiss</span><span class="pun">-</span><span class="pln">cpu sentence</span><span class="pun">-</span><span class="pln">transformers pytorch huggingface_hub </span><span class="pun">-</span><span class="pln">y pip install langchain</span><span class="pun">-</span><span class="pln">community langchain</span><span class="pun">-</span><span class="pln">huggingface langchain</span><span class="pun">-</span><span class="pln">ollama arabic</span><span class="pun">-</span><span class="pln">support</span></pre>

<p>
	أما إذا كنا نستخدم pip، فيمكن تثبيت المكتبات والأطر المشار المطلوبة عبر سطر الأوامر على النحو الآتي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_8672_13" style=""><span class="com"># تثبيت المكتبات وأطر العمل التي نحتاجها عبر مثبِّت pip</span><span class="pln">
pip install streamlit pdfplumber langchain langchain</span><span class="pun">-</span><span class="pln">community langchain</span><span class="pun">-</span><span class="pln">huggingface langchain</span><span class="pun">-</span><span class="pln">ollama faiss</span><span class="pun">-</span><span class="pln">cpu sentence</span><span class="pun">-</span><span class="pln">transformers torch huggingface_hub arabic</span><span class="pun">-</span><span class="pln">support</span></pre>

<h3 id="ollamadeepseek">
	تحميل Ollama و DeepSeek
</h3>

<p>
	Ollama هو أداة تتيح إمكانية تشغيل نماذج الذكاء الاصطناعي محليًا بسهولة دون الحاجة إلى إعدادات معقدة ويناسب مكتبة Langchain للتنزيل يمكن التوجه إلى الموقع الرسمي لـ <a href="https://ollama.com/" rel="external nofollow">Ollama</a> والضغط على خيار التنزيل Download من الواجهة الرئيسية كما هو موضح في الصورة الآتية.
</p>

<p style="text-align: center;">
	<img alt="الواجهة-الرئيسية-لموقع-Ollama.png" class="ipsImage ipsImage_thumbnailed" data-fileid="171111" data-ratio="43.69" data-unique="ebf0ouy9m" width="721" src="https://academy.hsoub.com/uploads/monthly_2025_04/---Ollama.png.edef6e66f55dffd288b264dedd80fbbc.png">
</p>

<p>
	بعد ذلك نضغط على خيار DeepSeek-R1 من نفس الواجهة ونختار النموذج المناسب لنا، وننسخ إعداداته التي نحتاجها لمقالنا من أجل تحميل DeepSeek، وهي في هذا المقال على النحو الآتي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_9479_12" style=""><span class="pln">ollama pull deepseek</span><span class="pun">-</span><span class="pln">r1</span><span class="pun">:</span><span class="lit">70b</span></pre>

<p>
	ننسخها إلى سطر الأوامر Terminal، وبعد تحميله نتأكد من أنه قد حُمل بنجاح، بإجراء اختبار ببسيط له نسأله من خلاله عمن يكون، لنحصل على الرد الآتي الذي يوضح أن عملية التثبيت قد تمت بنجاح تام.
</p>

<p style="text-align: center;">
	<img alt="اختبار نجاح تثبيت ديبسيك.png" class="ipsImage ipsImage_thumbnailed" data-fileid="171115" data-ratio="23.61" data-unique="qifiuhwh8" width="771" src="https://academy.hsoub.com/uploads/monthly_2025_04/677539424_.png.cb1b5597593ee3e3de259894746c15e6.png">
</p>

<h2 id="-4">
	بدء كتابة كود المشروع
</h2>

<p>
	سنكتب الكود الآن بتدرج، وأول ما سنفعله هو استدعاء المكتبات والأُطر التي سنحتاجها، والتي سبق وثبتناها مع بداية المقال.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_8672_15" style=""><span class="com"># استدعاء المكتبات والأُطر التي سنحتاجها</span><span class="pln">
</span><span class="kwd">import</span><span class="pln"> tempfile
</span><span class="kwd">import</span><span class="pln"> re
</span><span class="kwd">import</span><span class="pln"> streamlit </span><span class="kwd">as</span><span class="pln"> st
</span><span class="kwd">from</span><span class="pln"> langchain_community</span><span class="pun">.</span><span class="pln">document_loaders </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">PDFPlumberLoader</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> langchain</span><span class="pun">.</span><span class="pln">text_splitter </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">RecursiveCharacterTextSplitter</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> langchain_huggingface </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">HuggingFaceEmbeddings</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> langchain_community</span><span class="pun">.</span><span class="pln">vectorstores </span><span class="kwd">import</span><span class="pln"> FAISS
</span><span class="kwd">from</span><span class="pln"> langchain_ollama </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">OllamaLLM</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> langchain</span><span class="pun">.</span><span class="pln">prompts </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">PromptTemplate</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> langchain_core</span><span class="pun">.</span><span class="pln">output_parsers </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">StrOutputParser</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> langchain_core</span><span class="pun">.</span><span class="pln">runnables </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">RunnablePassthrough</span></pre>

<p>
	بعد ذلك، سنهيّء الواجهة التي سنعرض من خلالها نتائجنا لتتوافق مع اللغة العربية لضمان أن تكون واجهة النظام ستكون من اليمين لليسار.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_8672_17" style=""><span class="com"># تهيئة الواجهة لتتوافق مع اللغة العربية</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> arabic_support </span><span class="kwd">import</span><span class="pln"> support_arabic_text
support_arabic_text</span><span class="pun">(</span><span class="pln">all</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">)</span></pre>

<p>
	بعد ذلك سنتبع ما يلي.
</p>

<h3 id="-5">
	تهيئة الكتاب لإسترجاع المعلومات
</h3>

<p>
	من أجل استرجاع المعلومات ذات الصلة من ملف الكتاب، سنحتاج لاتّباع الخطوات الآتية:
</p>

<ul>
	<li>
		<strong>تحميل المستند</strong>: بحيث يتم رفع ملف PDF وتحميل محتوياته باستخدام PDFPlumberLoader لسرعته في القراءة
	</li>
	<li>
		<strong>تقسيم النصوص</strong>: حيث تُجزَّأ المحتويات إلى مقاطع باستخدام أداة RecursiveCharacterTextSplitter لنحافظ على السياق ونحسن دقة البحث
	</li>
	<li>
		<strong>إرسال البيانات الى مكتبة HuggingFaceEmbeddings</strong><span>: </span>وذلك لانشاء البصمات للنصوص لتُخزن في قاعدة البيانات FAISS
	</li>
</ul>

<p>
	وقد اتبعنا هذه الخطوات لأنه عند كتابنا للسؤال، يجب أن يعمل النظام على البحث في البيانات ذات الصلة، لذا يتم ذلك عبر تحويل النصوص إلى تمثيلات رقمية، إذ نحوّل كل جزء من النص إلى أرقام تعبّر عن معناه، تمامًا مثل بصمة رقمية للنص، ثم نبحث في البيانات عن أقرب تضمينات مطابقة.
</p>

<p>
	ويكون الكود المكتوب على النحو الآتي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_8672_19" style=""><span class="pln"> </span><span class="com"># تحميل وقراءة محتوى الملف </span><span class="pln">
docs </span><span class="pun">=</span><span class="pln"> </span><span class="typ">PDFPlumberLoader</span><span class="pun">(</span><span class="pln">temp_pdf_path</span><span class="pun">).</span><span class="pln">load</span><span class="pun">()</span><span class="pln">

</span><span class="com"># تحويل الكتاب إلى نصوص حاسوبية يمكنه فهمها والبحث فيها بكفاءة</span><span class="pln">
embedder </span><span class="pun">=</span><span class="pln"> </span><span class="typ">HuggingFaceEmbeddings</span><span class="pun">(</span><span class="pln">model_name</span><span class="pun">=</span><span class="str">"sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"</span><span class="pun">)</span><span class="pln">

chunk_size </span><span class="pun">=</span><span class="pln"> max</span><span class="pun">(</span><span class="lit">500</span><span class="pun">,</span><span class="pln"> min</span><span class="pun">(</span><span class="lit">1000</span><span class="pun">,</span><span class="pln"> len</span><span class="pun">(</span><span class="pln">docs</span><span class="pun">)</span><span class="pln"> </span><span class="pun">//</span><span class="pln"> </span><span class="lit">10</span><span class="pun">))</span><span class="pln"> </span><span class="com"># تحديد حجم المقطع حسب طول المستند  </span><span class="pln">
documents </span><span class="pun">=</span><span class="pln"> </span><span class="typ">RecursiveCharacterTextSplitter</span><span class="pun">(</span><span class="pln">
   chunk_size</span><span class="pun">=</span><span class="pln">chunk_size</span><span class="pun">,</span><span class="pln">   </span><span class="com"># تحديد حجم كل مقطع نصي</span><span class="pln">
   chunk_overlap</span><span class="pun">=</span><span class="pln">chunk_size </span><span class="pun">//</span><span class="pln"> </span><span class="lit">5</span><span class="pln">   </span><span class="com"># السماح بتداخل بين المقاطع بنسبة 20% للحفاظ على السياق</span><span class="pln">
</span><span class="pun">).</span><span class="pln">split_documents</span><span class="pun">(</span><span class="pln">docs</span><span class="pun">)</span><span class="pln"> </span><span class="pun">تنفيذ</span><span class="pln"> </span><span class="pun">عملية</span><span class="pln"> </span><span class="pun">التقسيم</span><span class="pln"> </span><span class="pun">على</span><span class="pln"> </span><span class="pun">المستند</span><span class="pln"> </span><span class="pun">المحمّل</span><span class="pln">

</span><span class="com"># انشاء مخزن البيانات ووضع البيانات التي استخرجت من الكتاب في المخزن الخاص بالنظام   </span><span class="pln">
retriever </span><span class="pun">=</span><span class="pln"> FAISS</span><span class="pun">.</span><span class="pln">from_documents</span><span class="pun">(</span><span class="pln">documents</span><span class="pun">,</span><span class="pln"> embedder</span><span class="pun">).</span><span class="pln">as_retriever</span><span class="pun">(</span><span class="pln">search_kwargs</span><span class="pun">={</span><span class="str">"k"</span><span class="pun">:</span><span class="pln"> </span><span class="lit">4</span><span class="pun">})</span></pre>

<p>
	وحتى هذه العملية، نكون قد عالجنا الكتاب وأكملنا تهيئته لإسترجاع المعلومات ذات الصلة منه.
</p>

<h3 id="-6">
	توليد الإجابات النهائية من ملف الكتاب
</h3>

<p>
	لكي نُولد الإجابة النهائية، يجب علينا أولًا تحليل السياق وفهم المعنى المقصود من السؤال، لذا يُستخدم نموذج اللغة لتوليد استجابة مناسبة. يتم أيضًا تعزيز جودة الإجابة من خلال دمج المعلومات المسترجعة مسبقًا مع المعرفة المخزنة داخل النموذج، وأخيرًا نُطبق تقنيات تحسين الصياغة لضمان وضوح الإجابة. وتتم العملية بعدة خطوات وهي:
</p>

<ul>
	<li>
		<strong>تهيئة نموذج اللغة في الكود</strong>: حيث يتم استخدام OllamaLLM وضبط DeepSeek R1 ليكون المصدر الأساسي للإجابة على الأسئلة.
	</li>
	<li>
		<strong>إعداد الأوامر Prompt Engineering</strong>: حيث يتم تصميم إنشاء قالب تعليمات باستخدام PromptTemplate لتوجيه النموذج حول كيفية الإجابة عند البحث في محتوى الكتاب
	</li>
	<li>
		<strong>انشاء سلسلة معالجة الإجابات</strong>: عن طريق دمج نموذج LLM مع تنقية FAISS Retriever لنضمن توليد النموذج الإجابات بناءً على المعلومات المسترجعة فقط، وهذا يوفر دقة الإجابات ويقلل احتمالية توليد معلومات غير صحيحة
	</li>
</ul>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_8672_25" style=""><span class="com"># تهيئة نموذج اللغة</span><span class="pln">
llm </span><span class="pun">=</span><span class="pln"> </span><span class="typ">OllamaLLM</span><span class="pun">(</span><span class="pln">model</span><span class="pun">=</span><span class="str">"deepseek-r1:70b"</span><span class="pun">)</span><span class="pln"> 

</span><span class="com"># إعداد الأوامر، تعريف الأوامر التي يتبعها النظام أثناء البحث في الكتاب    </span><span class="pln">
template </span><span class="pun">=</span><span class="pln"> </span><span class="str">"""
    Use the following context to answer the question concisely in 3-4 sentences.
    If the answer is unknown, respond with "I don't know" without making anything up.
    Answer in Arabic if the given question is in Arabic.     
    Context: {context}  
    Question: {question}  
    Answer:
            """</span><span class="pln">
rag_chain </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
                </span><span class="pun">{</span><span class="str">"context"</span><span class="pun">:</span><span class="pln"> retriever</span><span class="pun">,</span><span class="pln"> </span><span class="str">"question"</span><span class="pun">:</span><span class="pln"> </span><span class="typ">RunnablePassthrough</span><span class="pun">()}</span><span class="pln"> </span><span class="com"># تمرير السياق والسؤال </span><span class="pln">
                </span><span class="pun">|</span><span class="pln"> </span><span class="typ">PromptTemplate</span><span class="pun">.</span><span class="pln">from_template</span><span class="pun">(</span><span class="pln">template</span><span class="pun">)</span><span class="pln"> </span><span class="com"># تجهيز السؤال بالتنسيق المطلوب</span><span class="pln">
                </span><span class="pun">|</span><span class="pln"> llm </span><span class="com"># إرسال البيانات إلى نموذج اللغة لمعالجتها</span><span class="pln">
                </span><span class="pun">|</span><span class="pln"> </span><span class="typ">StrOutputParser</span><span class="pun">()</span><span class="pln"> </span><span class="com"># استخراج الإجابة بصيغة نصية</span><span class="pln">
            </span><span class="pun">)</span></pre>

<p>
	حتى هذه العملية تم توليد الإجابه بناءً على المعلومات المسترجعة.
</p>

<h3 id="-7">
	انشاء واجهة الويب
</h3>

<p>
	استخدمنا في هذا المقال إطار العمل Streamlit لإنشاء واجهة الويب من أجل تسهيل عملية العرض والاستخدام.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_8672_27" style=""><span class="com"># إعداد واجهة التطبيق</span><span class="pln">
st</span><span class="pun">.</span><span class="pln">markdown</span><span class="pun">(</span><span class="str">"&lt;h2 style='text-align: right;'&gt;Ollama و Deepseek بإستخدام Pdf البحث ضمن ملف&lt;/h2&gt;"</span><span class="pun">,</span><span class="pln"> unsafe_allow_html</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">)</span><span class="pln">

uploaded_file </span><span class="pun">=</span><span class="pln"> st</span><span class="pun">.</span><span class="pln">file_uploader</span><span class="pun">(</span><span class="str">"Pdf رفع ملف"</span><span class="pun">,</span><span class="pln"> type</span><span class="pun">=</span><span class="str">"pdf"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">if</span><span class="pln"> uploaded_file </span><span class="kwd">is</span><span class="pln"> </span><span class="kwd">not</span><span class="pln"> </span><span class="kwd">None</span><span class="pun">:</span><span class="pln">
     </span><span class="kwd">with</span><span class="pln"> st</span><span class="pun">.</span><span class="pln">spinner</span><span class="pun">(</span><span class="str">"..جاري المعالجة"</span><span class="pun">):</span><span class="pln">
         </span><span class="kwd">with</span><span class="pln"> tempfile</span><span class="pun">.</span><span class="typ">NamedTemporaryFile</span><span class="pun">(</span><span class="pln">delete</span><span class="pun">=</span><span class="kwd">False</span><span class="pun">,</span><span class="pln"> suffix</span><span class="pun">=</span><span class="str">".pdf"</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> temp_pdf</span><span class="pun">:</span><span class="pln">
             temp_pdf</span><span class="pun">.</span><span class="pln">write</span><span class="pun">(</span><span class="pln">uploaded_file</span><span class="pun">.</span><span class="pln">getvalue</span><span class="pun">())</span><span class="pln">             
             temp_pdf_path </span><span class="pun">=</span><span class="pln"> temp_pdf</span><span class="pun">.</span><span class="pln">name

</span><span class="com"># إدخال المستخدم للسؤال</span><span class="pln">
st</span><span class="pun">.</span><span class="pln">markdown</span><span class="pun">(</span><span class="pln">f</span><span class="str">'&lt;div style="direction: rtl; font-size: 16px; font-weight: bold;"&gt;أدخل سؤالك هنا..&lt;/div&gt;'</span><span class="pun">,</span><span class="pln"> unsafe_allow_html</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
user_input </span><span class="pun">=</span><span class="pln"> st</span><span class="pun">.</span><span class="pln">text_input</span><span class="pun">(</span><span class="str">" "</span><span class="pun">,</span><span class="pln"> key</span><span class="pun">=</span><span class="str">"user_question"</span><span class="pun">,</span><span class="pln"> label_visibility</span><span class="pun">=</span><span class="str">"hidden"</span><span class="pun">)</span></pre>

<h3 id="-8">
	تحسين المخرجات
</h3>

<p>
	في هذا الجزء، ركزنا على تحسين جودة المخرجات الناتجة عن نظام RAG لضمان تقديم إجابات واضحة ومباشرة، ويتم ذلك من خلال تعديل الكود لإزالة أي نصوص تحليلية أو تعليمات غير ضرورية قد تظهر في الاستجابة، مما يجعل النتيجة أكثر تركيزًا على المعلومات المطلوبة فقط
</p>

<p>
	ولتسهيل العملية استخدمنا تعبير نمطي Regular Expression للبحث عن أي نص موجود بين العلامتين <code>&lt;think&gt;</code> و <code>&lt;/think&gt;</code> داخل الإجابة في سطر <code>cleaned_response</code>، ثم يٌحذف لضمان عرض المحتوى النهائي فقط. بعد ذلك، يتم تنظيف النص وإزالة أي فراغات زائدة باستخدام .strip().
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_9479_20" style=""><span class="com"># معالجة إدخال المستخدم</span><span class="pln">
</span><span class="kwd">if</span><span class="pln"> user_input</span><span class="pun">:</span><span class="pln">
    </span><span class="kwd">with</span><span class="pln"> st</span><span class="pun">.</span><span class="pln">spinner</span><span class="pun">(</span><span class="str">"..جاري البحث"</span><span class="pun">):</span><span class="pln">
        response </span><span class="pun">=</span><span class="pln"> rag_chain</span><span class="pun">.</span><span class="pln">invoke</span><span class="pun">(</span><span class="pln">user_input</span><span class="pun">)</span><span class="pln"> </span><span class="com"># استرجاع البيانات ثم توليد الإجابة</span><span class="pln">
    cleaned_response </span><span class="pun">=</span><span class="pln"> re</span><span class="pun">.</span><span class="pln">sub</span><span class="pun">(</span><span class="pln">r</span><span class="str">"&lt;think&gt;.*?&lt;/think&gt;"</span><span class="pun">,</span><span class="pln"> </span><span class="str">""</span><span class="pun">,</span><span class="pln"> response</span><span class="pun">,</span><span class="pln"> flags</span><span class="pun">=</span><span class="pln">re</span><span class="pun">.</span><span class="pln">DOTALL</span><span class="pun">).</span><span class="pln">strip</span><span class="pun">()</span><span class="pln">
        st</span><span class="pun">.</span><span class="pln">markdown</span><span class="pun">(</span><span class="str">"### Answer:"</span><span class="pun">)</span><span class="pln">
        st</span><span class="pun">.</span><span class="pln">write</span><span class="pun">(</span><span class="pln">cleaned_response</span><span class="pun">)</span><span class="pln">  </span><span class="com"># عرض الإجابة النهائية</span><span class="pln">
</span><span class="kwd">else</span><span class="pun">:</span><span class="pln">
       st</span><span class="pun">.</span><span class="pln">info</span><span class="pun">(</span><span class="str">"Pdf من فضلك قم برفع ملف"</span><span class="pun">)</span></pre>

<p>
	ولنفتح واجهة الويب، لا بد من كتابة الأمر التالي في Terminal الخاص بالبرنامج:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_8672_29" style=""><span class="com"># فتح واجهة الويب</span><span class="pln">
streamlit run </span><span class="typ">Project</span><span class="pun">.</span><span class="pln">py  </span></pre>

<p>
	<strong>ملاحظة</strong>: سنغير كلمة Project بناءً على اسم الملف.
</p>

<h2 id="-9">
	اختبار كفاءة النظام
</h2>

<p>
	عند هذه المرحلة جربنا اختبار النظام للتأكد من دقة استرجاع المعلومات، وتوليد الإجابات، وقدرته على تقديم إجابات نموذجية، لضمان إنتاج النموذج أفضل إجابة وأدق تفاصيل.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="171109" href="https://academy.hsoub.com/uploads/monthly_2025_04/RAG.png.5eb17622fe03e0945d0dc7d0e2543a74.png" rel=""><img alt="اختبار كفاءة نظام rag" class="ipsImage ipsImage_thumbnailed" data-fileid="171109" data-unique="xq32irq9h" src="https://academy.hsoub.com/uploads/monthly_2025_04/RAG.thumb.png.e0b0057f63c6cc421b720a8f531dd0e2.png"> </a>
</p>

<p>
	<strong>ملاحظة</strong>: نود لفت الانتباه مجددًا إلى أن النظام في شكله الحالي لا يزال يواجه صعوبةً في دعم اللغة العربية بشكل مثالي، وهو ما دفعنا إلى استخدام موارد حاسوبية عالية في مشروعنا، مثل وحدات معالجة رسومية قوية وذاكرة وصول عشوائي كبيرة، لضمان أداء دقيق. إذا لم تكن هذه الموارد متاحة لبناء نظام مشابه فيمكن بسهولة تطبيق نفس الخطوات التي شرحناها على نماذج أخرى تدعم اللغة العربية بكفاءة أكبر، أو حتى استخدامها مع لغات أخرى مثل الإنجليزية التي تتطلب موارد أقل بكثير للحصول على نتائج مماثلة، مما يتيح إمكانية تحقيق أهدافك بما يتناسب مع إمكانياتك المتوفرة.
</p>

<p>
	في حال عدم توفر الموارد يمكن استعمال النظام باللغة الإنجليزية مثلًا، وبكل بسهولة عن طريق استعمال نموذج لغة أصغر مثل Deepseek R1-7b، عن طريق تحميله عبر سطر الأوامر Terminal: ollama pull deepseek-r1
</p>

<p>
	وبعد التأكد من تحميله، نغير سطر نموذج اللغة في الكود
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_8672_33" style=""><span class="com"># تهيئة نموذج اللغة</span><span class="pln">
llm </span><span class="pun">=</span><span class="pln"> </span><span class="typ">OllamaLLM</span><span class="pun">(</span><span class="pln">model</span><span class="pun">=</span><span class="str">"deepseek-r1"</span><span class="pun">)</span><span class="pln"> </span></pre>

<p>
	ثم نحذف الجزء المتعلق بتهيئة واجهة اللغة العربية من الكود وتصبح هذه هي النتيجة:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="171112" href="https://academy.hsoub.com/uploads/monthly_2025_04/1858543133_.png.301babade0b4c0d75c3c8ea8b5d74454.png" rel=""><img alt="شكل الواجهة الجديدة.png" class="ipsImage ipsImage_thumbnailed" data-fileid="171112" data-ratio="102.92" data-unique="cheu95daa" width="583" src="https://academy.hsoub.com/uploads/monthly_2025_04/.thumb.png.11c387d3f80962fb7d54a694eb81ec39.png"></a>
</p>

<p>
	وكما هو واضح، فالنموذج قادر على فهم الكتاب العربي الذي شاركناه إياه كمدخلات للبحث ضمنها عن جواب، وقد تمكن الإجابة علينا بلغة إنجليزية سليمة بعد أن سألناه باللغة الإنجليزية.
</p>

<h2 id="-10">
	خاتمة
</h2>

<p>
	بهذا نكون قد وصلنا إلى نهاية المقال الذي تعرفنا فيه على كيفية بناء نظام RAG قادر على اختصار الوقت علينا ومساعدتنا في الحصول على ردود دقيقة وسريعة من الملفات التي تحتاج منا عادة لساعات من القراءة والبحث، ووضحنا كيفية تحسين نموذج اللغة لتوليد استجابات ذكية عبر عدة مراحل، بدءًا من إعداد التوجيهات وتصميم قالب الأوامر، مرورًا بتطبيق المشروع ضمن السياق وإنشاء مسارات معالجة، مع التركيز على تعزيز الدقة والترابط لضمان استجابات متسقة وواضحة.
</p>

<h2>
	المصادر
</h2>

<ul>
	<li>
		<a href="https://aws.amazon.com/what-is/retrieval-augmented-generation/" rel="external nofollow">?What is RAG (Retrieval-Augmented Generation)</a>
	</li>
	<li>
		<a href="https://arxiv.org/html/2410.15944" rel="external nofollow">Developing Retrieval Augmented Generation (RAG) based LLM Systems</a>
	</li>
	<li>
		<a href="https://www.coditation.com/blog/how-to-build-a-rag-using-langchain-ollama-and-streamlit" rel="external nofollow">How to build a RAG Using Langchain, Ollama, and Streamlit</a>
	</li>
	<li>
		<a href="https://www.anyscale.com/blog/a-comprehensive-guide-for-building-rag-based-llm-applications-part-1" rel="external nofollow">Building RAG-based LLM Applications</a>
	</li>
	<li>
		<a href="https://discuss.streamlit.io/t/new-component-arabic-support/68508" rel="external nofollow">Streamlit Arabic Support</a>
	</li>
</ul>

<h2 id="-11">
	اقرأ أيضًا
</h2>

<ul>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A7%D8%B3%D8%AA%D9%83%D8%B4%D9%81-%D9%85%D8%B5%D8%B7%D9%84%D8%AD%D8%A7%D8%AA-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-%D8%A7%D9%84%D8%AA%D9%88%D9%84%D9%8A%D8%AF%D9%8A-r2399/" rel="">استكشف مصطلحات الذكاء الاصطناعي التوليدي</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-deepseek-%D9%85%D8%AD%D9%84%D9%8A%D8%A7-%D8%B9%D9%84%D9%89-%D9%85%D8%AD%D8%B1%D8%B1-%D8%A7%D9%84%D8%A3%D9%83%D9%88%D8%A7%D8%AF-vs-code-r2542/" rel="">تشغيل Deepseek محليا على محرر الأكواد </a><a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-deepseek-%D9%85%D8%AD%D9%84%D9%8A%D8%A7-%D8%B9%D9%84%D9%89-%D9%85%D8%AD%D8%B1%D8%B1-%D8%A7%D9%84%D8%A3%D9%83%D9%88%D8%A7%D8%AF-vs-code-r2542/" rel="">VS Code</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A7%D9%84%D8%AA%D9%81%D8%A7%D8%B9%D9%84-%D9%85%D8%B9-%D8%B1%D8%B3%D8%A7%D8%A6%D9%84-whatsapp-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-r2550/" rel="">التفاعل مع رسائل WhatsApp باستخدام الذكاء الاصطناعي</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/advanced/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%B1%D8%A8%D8%B7-%D8%A8%D9%88%D8%AA-%D8%AA%D9%84%D8%BA%D8%B1%D8%A7%D9%85-%D9%85%D8%B9-%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-google-sheets-r2526/" rel="">كيفية ربط بوت تلغرام مع جداول بيانات Google Sheets</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/python/%D8%A7%D9%84%D8%B9%D9%85%D9%84-%D9%85%D8%B9-%D9%85%D8%B3%D8%AA%D9%86%D8%AF%D8%A7%D8%AA-pdf-%D9%88%D9%85%D8%B3%D8%AA%D9%86%D8%AF%D8%A7%D8%AA-word-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-r2387/" rel="">العمل مع مستندات PDF ومستندات Word باستخدام بايثون</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">2562</guid><pubDate>Tue, 22 Apr 2025 16:04:00 +0000</pubDate></item><item><title>&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; &#x62E;&#x648;&#x627;&#x631;&#x632;&#x645;&#x64A;&#x629; &#x623;&#x642;&#x631;&#x628; &#x627;&#x644;&#x62C;&#x64A;&#x631;&#x627;&#x646; k-Nearest Neighbors &#x641;&#x64A; Scikit-Learn</title><link>https://academy.hsoub.com/programming/artificial-intelligence/%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%AE%D9%88%D8%A7%D8%B1%D8%B2%D9%85%D9%8A%D8%A9-%D8%A3%D9%82%D8%B1%D8%A8-%D8%A7%D9%84%D8%AC%D9%8A%D8%B1%D8%A7%D9%86-k-nearest-neighbors-%D9%81%D9%8A-scikit-learn-r2560/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2025_04/03.k-NearestNeighborsScikit-Learn2.png.f17ac103fe5ed80171942ad49eb6777d.png" /></p>
<p>
	في هذا المقال من سلسلة تطبيقات عملية على استخدام مكتبة ساي كيت ليرن سنستعرض خطوة بخطوة كيفية تطبيق واحدة من أشهر خوارزميات تعلم الآلة وهي خوارزمية أقرب الجيران k-Nearest Neighbors  -أو KNN اختصارًا- لتصنيف الأنواع المختلفة من الأزهار الموجودة ضمن مجموعة بيانات آيرس Iris dataset إحدى أكثر مجموعات البيانات استخدامًا في مجال تعلم الآلة والتي تعرفنا عليها في مقال سابق بعنوان <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-%D8%AA%D8%AD%D9%84%D9%8A%D9%84-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-scikit-learn-%D9%85%D8%B9-pandas-r2554/" rel="">أساسيات تحليل البيانات باستخدام Scikit-Learn</a>.
</p>

<h2 id="knearestneighbors">
	آلية عمل خوارزمية k-Nearest Neighbors
</h2>

<p>
	يمكننا تعريف خوارزمية أقرب جار  K-Nearest Neighbors على أنها خوارزمية لا معاملية non-parametric بمعنى أنها لا تملك أوزان أو معاملات تحاول تحسينها كما تتبع <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AE%D9%88%D8%A7%D8%B1%D8%B2%D9%85%D9%8A%D8%A7%D8%AA-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A/" rel="">خوارزميات ذكاء اصطناعي</a> أخرى، فهي تستخدم في مهام التصنيف Classification وتوقع الانحدار Regression، وفي كلا الحالتين تعتمد على المعلومات المتاحة لدى أقرب k من النقاط المجاورة لمجموعة بيانات التدريب، وتختلف طريقة حساب المخرجات حسب مهمة التعلم.
</p>

<h3>
	في حالة التصنيف Classification
</h3>

<p>
	يكون خرج النموذج أحد التصنيفات المحددة، ونقرره بناءً على تصويت الأغلبية من عدد <code>k</code> نقطة مجاورة لها حق التصويت أي يسمح لها بالمشاركة في اتخاذ القرار بشأن تصنيف نقطة معينة، ويكون هذا العدد المحدد <code>k</code> من النقاط المجاورة عددًا صحيحًا موجبًا ويفضل أن يكون فرديًا لمنع أي حالات تعادل في التصويت.
</p>

<p>
	من المهم اختيار قيمة <code>k</code> مناسبة في خوارزمية الجار الأقرب، ويفضل أن تكون قيمة صغيرة نسبيًا، فعندما نحدد عدد النقاط المجاورة <code>k=1</code> سيتأثر قرار النموذج بالضجيج noise في البيانات والنقاط الخارجة outliers وغير المألوفة بشكل كبير، مما يحدث حالة إفراط في التخصيص Overfitting ويضعف قدرته على التعميم لبيانات جديدة، بينما عندما نحدد عدد النقاط المجاورة برقم كبير <code>n</code> يساوي عدد العينات بمجموعة بيانات التدريب سيصبح النموذج أبسط من اللازم وتحدث لديه حالة إفراط في التبسيط Underfitting بالتالي لن يكون قادر على التعبير عن العلاقات المعقدة الموجودة في البيانات وسيأخذ قرارات اعتمادًا على نقاط بعيدة جدًا ولا تؤثر على نقطة الاستفسار الحالية.
</p>

<h3>
	في حالة توقع الانحدار Regression
</h3>

<p>
	يكون خرج النموذج عدد مستمر ناتج عن أخذ متوسط القيم من عدد محدد k من النقاط المجاورة لتقرير قيمة نقطة الاستفسار الحالية.
</p>

<p style="text-align: center;">
	<img alt="00 knearest neighbors algorithm" class="ipsImage ipsImage_thumbnailed" data-fileid="170885" data-ratio="90.00" data-unique="0kxsv899q" style="width: 200px; height: auto;" width="224" src="https://academy.hsoub.com/uploads/monthly_2025_04/k-nearest-neighbors-algorithm.png.15b001fd8e2bd30495e7b826be25b9b2.png">
</p>

<p>
	تعرض الصورة السابقة مثالًا على خوارزمية KNN لمهمة التصنيف، وتمثل النقطة الخضراء نقطة الاستفسار الحالية query point والتي نريد تصنيفها إما لصنف المربعات الزرقاء أو المثلثات الحمراء، فإذا قررنا أن عدد النقاط المجاورة k=3 تصبح النقاط الداخلة في القرار هي النقاط المحاطة بالدائرة المتصلة، وكما نرى فالأغلبية في هذا النطاق للمثلثات الحمراء 2 بينما الأقلية هي المربعات الزرقاء 1، بالتالي يمكننا تصنيف نقطة الاستفسار query point بأنها مثلث أحمر، بينما عند زيادة k لتصبح 5 ننظر للنقاط المحاطة بالدائرة المنقطة فنجد أن الأغلبية صارت للمربعات الزرقاء 3 مقابل 2 من المثلثات الحمراء، بالتالي يصبح التصنيف لنقطة الاستفسار مربع أزرق.
</p>

<p>
	بعد أن تعرفنا على آلية عمل الخوارزمية، لنستعرض مجموعة من التدريبات العملية التي تساعدنا على فهم كيفية استخدام هذه الخوارزمية بشكل فعّال باستخدام مكتبة <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D9%85%D9%83%D8%AA%D8%A8%D8%A9-scikit-learn-%D9%88%D8%A3%D9%87%D9%85-%D8%AE%D9%88%D8%A7%D8%B1%D8%B2%D9%85%D9%8A%D8%A7%D8%AA%D9%87%D8%A7-r2485/" rel="">scikit-learn</a>.
</p>

<h3 id="1datasetsplitting">
	فصل مجموعة البيانات
</h3>

<p>
	من أولى خطوات التحضير لبناء أي نموذج تعلم آلة هي فصل الخصائص Features وهي البيانات التي نستخدمها لتوقع شيء ما عن <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B5%D9%85%D9%8A%D9%85-%D8%A3%D9%86%D8%B8%D9%85%D8%A9-%D9%88%D8%B3%D9%85-%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D8%B9%D8%A7%D9%84%D8%A9-%D9%84%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-%D8%AA%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%A2%D9%84%D8%A9-r2480/" rel="">الوسوم Labels</a> وهي القيم التي نحاول التنبؤ بها، لنكتب برنامج بايثون لتقسيم مجموعة بيانات أزهار آيرس إلى خصائصها كطول و عرض بتلة الزهرة وسبلتها والتي سنخزنها في متغير <code>X</code> ، والوسوم التي سنخزنها في متغير <code>Y</code>. سيحتوي المتغير <code>X</code> أول أربعة أعمدة بينما يحتوي المتغير <code>Y</code> وسم كل زهرة بفصيلتها مثل Setosa أو Versicolor أو Virginica.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_8727_7" style=""><span class="kwd">import</span><span class="pln"> pandas </span><span class="kwd">as</span><span class="pln"> pd
iris </span><span class="pun">=</span><span class="pln"> pd</span><span class="pun">.</span><span class="pln">read_csv</span><span class="pun">(</span><span class="str">"iris.csv"</span><span class="pun">)</span><span class="pln">
</span><span class="com"># Idاحذف عمود  </span><span class="pln">
iris </span><span class="pun">=</span><span class="pln"> iris</span><span class="pun">.</span><span class="pln">drop</span><span class="pun">(</span><span class="str">'Id'</span><span class="pun">,</span><span class="pln">axis</span><span class="pun">=</span><span class="lit">1</span><span class="pun">)</span><span class="pln">
</span><span class="com"># iloc : تسمح باختيار شريحة من الصفوف والأعمدة </span><span class="pln">
</span><span class="com">#  يشير هذا الرمز إلى اختيار جميع العناصر":" </span><span class="pln">
X </span><span class="pun">=</span><span class="pln"> iris</span><span class="pun">.</span><span class="pln">iloc</span><span class="pun">[:,</span><span class="pln"> </span><span class="pun">:-</span><span class="lit">1</span><span class="pun">].</span><span class="pln">values 
y </span><span class="pun">=</span><span class="pln"> iris</span><span class="pun">.</span><span class="pln">iloc</span><span class="pun">[:,</span><span class="pln"> </span><span class="lit">4</span><span class="pun">].</span><span class="pln">values
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"الخصائص:"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">X</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"\nالوسوم:"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">y</span><span class="pun">)</span></pre>

<p>
	كما نلاحظ فقد حذفنا في هذه الخطوة عمود المعرف <code>Id</code> من مجموعة البيانات، كونه لا يحمل أي معنى يتعلق بخصائص الأزهار، واستخدامه قد يؤدي لنموذج متحيز وغير دقيق. واستخدمنا التابع <code>iloc</code> لتحديد الخصائص <code>X</code>، والوسوم <code>Y</code> وأخيرًا، طبعنا كلًا من <code>X</code> و <code>Y</code> للتأكد من صحة التقسيم.
</p>

<p>
	عند تنفيذ الكود سنحصل على الخرج التالي:
</p>

<pre class="ipsCode">الخصائص:
[[5.1 3.5 1.4 0.2]
 [4.9 3.  1.4 0.2]
 [4.7 3.2 1.3 0.2]
 [4.6 3.1 1.5 0.2]
 [5.  3.6 1.4 0.2]
...
 [6.7 3.  5.2 2.3]
 [6.3 2.5 5.  1.9]
 [6.5 3.  5.2 2. ]
 [6.2 3.4 5.4 2.3]
 [5.9 3.  5.1 1.8]]

الوسوم:
['Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa'
 'Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa'
 'Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa'
 'Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa'
 'Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa'
…
 'Iris-virginica' 'Iris-virginica' 'Iris-virginica' 'Iris-virginica'
 'Iris-virginica' 'Iris-virginica' 'Iris-virginica' 'Iris-virginica'
 'Iris-virginica' 'Iris-virginica' 'Iris-virginica' 'Iris-virginica'
 'Iris-virginica' 'Iris-virginica' 'Iris-virginica' 'Iris-virginica'
 'Iris-virginica' 'Iris-virginica' 'Iris-virginica' 'Iris-virginica']
</pre>

<h3 id="2trainingsettestingset">
	تقسيم مجموعة البيانات لمجموعة تدريب ومجموعة اختبار
</h3>

<p>
	نحتاج لتقسيم البيانات إلى بيانات تدريب training وبيانات اختبار testing حتى نتمكن من معرفة فيما إذا كان النموذج يعمل جيدًا على بيانات جديدة لم يرها من قبل، سنكتب كود لتقسيم مجموعة بيانات آيرس إلى مجموعة تدريب تحتوي 80% من البيانات ومجموعة اختبار تحتوي 20%، بحيث يكون عدد العينات المستخدمة في التدريب هو 120 عينة والمستخدمة في الاختبار 30 عينة، ونطبع كلا المجموعتين.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_2882_11" style=""><span class="kwd">import</span><span class="pln"> pandas </span><span class="kwd">as</span><span class="pln"> pd
</span><span class="kwd">from</span><span class="pln"> sklearn</span><span class="pun">.</span><span class="pln">model_selection </span><span class="kwd">import</span><span class="pln"> train_test_split

iris </span><span class="pun">=</span><span class="pln"> pd</span><span class="pun">.</span><span class="pln">read_csv</span><span class="pun">(</span><span class="str">"iris.csv"</span><span class="pun">)</span><span class="pln">
</span><span class="com"># Id احذف العمود    </span><span class="pln">
iris </span><span class="pun">=</span><span class="pln"> iris</span><span class="pun">.</span><span class="pln">drop</span><span class="pun">(</span><span class="str">'Id'</span><span class="pun">,</span><span class="pln">axis</span><span class="pun">=</span><span class="lit">1</span><span class="pun">)</span><span class="pln">
</span><span class="com"># iloc : تسمح لنا باختيار شريحة من الصفوف والأعمدة </span><span class="pln">
</span><span class="com">#  يشير هذا الرمز إلى اختيار جميع العناصر":" </span><span class="pln">
X </span><span class="pun">=</span><span class="pln"> iris</span><span class="pun">.</span><span class="pln">iloc</span><span class="pun">[:,</span><span class="pln"> </span><span class="pun">:-</span><span class="lit">1</span><span class="pun">].</span><span class="pln">values 
y </span><span class="pun">=</span><span class="pln"> iris</span><span class="pun">.</span><span class="pln">iloc</span><span class="pun">[:,</span><span class="pln"> </span><span class="lit">4</span><span class="pun">].</span><span class="pln">values

</span><span class="com"># تقسم هذه الدالة مجموعة البيانات عشوائيًا وفقًا للنسب المحددة</span><span class="pln">
X_train</span><span class="pun">,</span><span class="pln"> X_test</span><span class="pun">,</span><span class="pln"> y_train</span><span class="pun">,</span><span class="pln"> y_test </span><span class="pun">=</span><span class="pln"> train_test_split</span><span class="pun">(</span><span class="pln">X</span><span class="pun">,</span><span class="pln"> y</span><span class="pun">,</span><span class="pln"> test_size</span><span class="pun">=</span><span class="lit">0.20</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"\n70% train data:"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">X_train</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">y_train</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"\n30% test data:"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">X_test</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">y_test</span><span class="pun">)</span></pre>

<p>
	فصلنا في البداية مجموعة البيانات إلى خاصيات <code>X</code> ووسوم <code>Y</code> كما في فعلنا في التطبيق السابق، ثم استدعينا الدالة <code>train_test_split</code> التي تقسم خاصيات ووسوم المجموعة إلى مجموعة تدريب ومجموعة اختبار، وحددنا نسبة التقسيم باستخدام <code>test_size=0.20</code> لجعل 20% من مجموعة البيانات مخصصة للاختبار، بينما 80% منها للتدريب، سيجري تقسيم البيانات عشوائيًا في كل مرة نشغل بها الكود.<br>
	عند تنفيذ الكود السابق سنحصل على خرج مشابه لما يلي:
</p>

<pre class="ipsCode">الخصائص:
[[5.1 3.5 1.4 0.2]
 [4.9 3.  1.4 0.2]
 [4.7 3.2 1.3 0.2]
 [4.6 3.1 1.5 0.2]
 [5.  3.6 1.4 0.2]
 …
 [6.7 3.  5.2 2.3]
 [6.3 2.5 5.  1.9]
 [6.5 3.  5.2 2. ]
 [6.2 3.4 5.4 2.3]
 [5.9 3.  5.1 1.8]]

الوسوم:
['Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa'
 'Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa'
 'Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa'
 'Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa'
 'Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa'
 … 
 'Iris-virginica' 'Iris-virginica' 'Iris-virginica' 'Iris-virginica'
 'Iris-virginica' 'Iris-virginica' 'Iris-virginica' 'Iris-virginica'
 'Iris-virginica' 'Iris-virginica' 'Iris-virginica' 'Iris-virginica'
 'Iris-virginica' 'Iris-virginica' 'Iris-virginica' 'Iris-virginica'
 'Iris-virginica' 'Iris-virginica' 'Iris-virginica' 'Iris-virginica']

70% train data:
[[5.6 2.5 3.9 1.1]
 [5.6 2.9 3.6 1.3]
 [4.7 3.2 1.6 0.2]
 [5.4 3.9 1.7 0.4]
 [5.1 3.8 1.6 0.2]
 … 
 [4.8 3.  1.4 0.1]
 [6.  2.7 5.1 1.6]
 [5.6 2.8 4.9 2. ]
 [7.7 2.6 6.9 2.3]
 [7.2 3.6 6.1 2.5]
 [5.6 3.  4.5 1.5]]
['Iris-versicolor' 'Iris-versicolor' 'Iris-setosa' 'Iris-setosa'
 'Iris-setosa' 'Iris-virginica' 'Iris-versicolor' 'Iris-versicolor'
 'Iris-versicolor' 'Iris-versicolor' 'Iris-virginica' 'Iris-virginica'
 'Iris-setosa' 'Iris-virginica' 'Iris-virginica' 'Iris-setosa'
 'Iris-virginica' 'Iris-virginica' 'Iris-versicolor' 'Iris-setosa'
 …
 'Iris-setosa' 'Iris-virginica' 'Iris-virginica' 'Iris-setosa'
 'Iris-setosa' 'Iris-virginica' 'Iris-versicolor' 'Iris-versicolor'
 'Iris-virginica' 'Iris-setosa' 'Iris-versicolor' 'Iris-virginica'
 'Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-versicolor'
 'Iris-virginica' 'Iris-virginica' 'Iris-virginica' 'Iris-versicolor']

30% test data:
[[5.5 2.3 4.  1.3]
 [6.4 3.1 5.5 1.8]
 [4.8 3.  1.4 0.3]
 [5.  3.2 1.2 0.2]
 [5.6 3.  4.1 1.3]
 …
 [6.4 2.8 5.6 2.2]
 [6.9 3.2 5.7 2.3]
 [6.1 2.6 5.6 1.4]
 [6.5 3.  5.2 2. ]
 [4.8 3.1 1.6 0.2]]
['Iris-versicolor' 'Iris-virginica' 'Iris-setosa' 'Iris-setosa'
 'Iris-versicolor' 'Iris-versicolor' 'Iris-virginica' 'Iris-virginica'
 'Iris-versicolor' 'Iris-virginica' 'Iris-versicolor' 'Iris-versicolor'
 'Iris-versicolor' 'Iris-versicolor' 'Iris-virginica' 'Iris-virginica'
 'Iris-setosa' 'Iris-virginica' 'Iris-setosa' 'Iris-virginica'
 'Iris-setosa' 'Iris-virginica' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa'
 'Iris-virginica' 'Iris-virginica' 'Iris-virginica' 'Iris-virginica'
 'Iris-setosa']
</pre>

<h3 id="3categoricalencoding">
	ترقيم الفصائل النصية
</h3>

<p>
	الأن سنعمل على تطبيق يحوّل فصائل الأزهار في مجموعة بيانات آيرس من أسماء نصية إلى قيم رقمية، ولنفعل ذلك سنحتاج لتحويل كل قيمة إلى رقم ثابت لهذه القيمة، فمثلًا نجعل <code>Iris-setosa:0</code> و <code>Iris-versicolor:1</code> و <code>Iris-virginica:2</code>، ثم نطبع مجموعة بيانات التدريب ومجموعة بيانات الاختبار.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_9124_20" style=""><span class="kwd">import</span><span class="pln"> pandas </span><span class="kwd">as</span><span class="pln"> pd
</span><span class="kwd">from</span><span class="pln"> sklearn</span><span class="pun">.</span><span class="pln">model_selection </span><span class="kwd">import</span><span class="pln"> train_test_split
</span><span class="com"># LabelEncoder استدعي   </span><span class="pln">
</span><span class="com"># والذي سوف نستخدمه لتحويل الفصائل من قيم نصية إلى أرقام ثابته لكل فصيلة</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> sklearn</span><span class="pun">.</span><span class="pln">preprocessing </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">LabelEncoder</span><span class="pln">

iris </span><span class="pun">=</span><span class="pln"> pd</span><span class="pun">.</span><span class="pln">read_csv</span><span class="pun">(</span><span class="str">"iris.csv"</span><span class="pun">)</span><span class="pln">
</span><span class="com"># labelEncoder نهيئ الصنف البرمجي </span><span class="pln">
le </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LabelEncoder</span><span class="pun">()</span><span class="pln">
</span><span class="com"># labelEncoder نستخدم الصنف البرمجي </span><span class="pln">
</span><span class="com"># لتحويل التصنيفات النصية إلى أرقم</span><span class="pln">
iris</span><span class="pun">.</span><span class="typ">Species</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> le</span><span class="pun">.</span><span class="pln">fit_transform</span><span class="pun">(</span><span class="pln">iris</span><span class="pun">.</span><span class="typ">Species</span><span class="pun">)</span><span class="pln">
</span><span class="com"># Id نحذف العمود </span><span class="pln">
</span><span class="com"># حيث لا يحتوي معلومات مهمة للتعلم</span><span class="pln">
iris </span><span class="pun">=</span><span class="pln"> iris</span><span class="pun">.</span><span class="pln">drop</span><span class="pun">(</span><span class="str">'Id'</span><span class="pun">,</span><span class="pln">axis</span><span class="pun">=</span><span class="lit">1</span><span class="pun">)</span><span class="pln">
X </span><span class="pun">=</span><span class="pln"> iris</span><span class="pun">.</span><span class="pln">iloc</span><span class="pun">[:,</span><span class="pln"> </span><span class="pun">:-</span><span class="lit">1</span><span class="pun">].</span><span class="pln">values
y </span><span class="pun">=</span><span class="pln"> iris</span><span class="pun">.</span><span class="pln">iloc</span><span class="pun">[:,</span><span class="pln"> </span><span class="lit">4</span><span class="pun">].</span><span class="pln">values
</span><span class="com"># نقسم مجموعة البيانات إلى مجموعة تدريب ومجموعة اختبار </span><span class="pln">
</span><span class="com"># كل منهما له خصائص ووسوم منفصلة</span><span class="pln">
X_train</span><span class="pun">,</span><span class="pln"> X_test</span><span class="pun">,</span><span class="pln"> y_train</span><span class="pun">,</span><span class="pln"> y_test </span><span class="pun">=</span><span class="pln"> train_test_split</span><span class="pun">(</span><span class="pln">X</span><span class="pun">,</span><span class="pln"> y</span><span class="pun">,</span><span class="pln"> test_size</span><span class="pun">=</span><span class="lit">0.20</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"\n80% train data:"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">X_train</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">y_train</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"\n20% test data:"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">X_test</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">y_test</span><span class="pun">)</span></pre>

<p>
	استخدمنا<code>LabelEncoder()‎</code> لنهيئ الكائن <code>le</code> والذي سنستخدمه لتحويل الفصائل النصية categorical classes لأرقام، حيث نرمز لكل صنف أو اسم برقم ثابت لهذا الصنف، ونستدعي هذا الكائن ليطبّق على البيانات باستخدام <code>le.fit_transform(iris.Species)‎</code> حيث تتعرف هذه الدالة في البداية على الأصناف في عمود Species وتحدد القيم التي ستعطى لكل فصيل category وتسمى هذه العملية <code>fit</code> ويمكن تنفيذها بشكل مستقل، ومن ثم يتم تحويل القيم النصية القديمة إلى الأرقام المقابلة عند تنفيذ عملية <code>transform</code> التي يمكن فصلها لكي تنفّذ بعد عملية <code>fit</code> على أكثر من مجموعة من البيانات التي تتضمن نفس الفصائل، ولكن في كثير من الأحيان نستخدم الدالة التي تدمج الخطوتين معًا.
</p>

<p>
	عند تنفيذ الكود سنحصل على الخرج التالي:
</p>

<pre class="ipsCode">الخصائص:
[[5.1 3.5 1.4 0.2]
 [4.9 3.  1.4 0.2]
 [4.7 3.2 1.3 0.2]
 [4.6 3.1 1.5 0.2]
 [5.  3.6 1.4 0.2]
 …
 [6.7 3.  5.2 2.3]
 [6.3 2.5 5.  1.9]
 [6.5 3.  5.2 2. ]
 [6.2 3.4 5.4 2.3]
 [5.9 3.  5.1 1.8]]

الوسوم:
['Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa'
 'Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa'
 'Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa'
 'Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa'
 'Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa'
 …
 'Iris-virginica' 'Iris-virginica' 'Iris-virginica' 'Iris-virginica'
 'Iris-virginica' 'Iris-virginica' 'Iris-virginica' 'Iris-virginica'
 'Iris-virginica' 'Iris-virginica' 'Iris-virginica' 'Iris-virginica'
 'Iris-virginica' 'Iris-virginica' 'Iris-virginica' 'Iris-virginica'
 'Iris-virginica' 'Iris-virginica' 'Iris-virginica' 'Iris-virginica']

70% train data:
[[5.6 2.5 3.9 1.1]
 [5.6 2.9 3.6 1.3]
 [4.7 3.2 1.6 0.2]
 [5.4 3.9 1.7 0.4]
 [5.1 3.8 1.6 0.2]
 …
 [5.6 2.8 4.9 2. ]
 [7.7 2.6 6.9 2.3]
 [7.2 3.6 6.1 2.5]
 [5.6 3.  4.5 1.5]]
['Iris-versicolor' 'Iris-versicolor' 'Iris-setosa' 'Iris-setosa'
 'Iris-setosa' 'Iris-virginica' 'Iris-versicolor' 'Iris-versicolor'
 'Iris-versicolor' 'Iris-versicolor' 'Iris-virginica' 'Iris-virginica'
 'Iris-setosa' 'Iris-virginica' 'Iris-virginica' 'Iris-setosa'
 'Iris-virginica' 'Iris-virginica' 'Iris-versicolor' 'Iris-setosa'
 …
 'Iris-setosa' 'Iris-virginica' 'Iris-virginica' 'Iris-setosa'
 'Iris-setosa' 'Iris-virginica' 'Iris-versicolor' 'Iris-versicolor'
 'Iris-virginica' 'Iris-setosa' 'Iris-versicolor' 'Iris-virginica'
 'Iris-setosa' 'Iris-setosa' 'Iris-setosa' 'Iris-versicolor'
 'Iris-virginica' 'Iris-virginica' 'Iris-virginica' 'Iris-versicolor']

30% test data:
[[5.5 2.3 4.  1.3]
 [6.4 3.1 5.5 1.8]
 [4.8 3.  1.4 0.3]
 [5.  3.2 1.2 0.2]
 [5.6 3.  4.1 1.3]
 …
 [6.4 2.8 5.6 2.2]
 [6.9 3.2 5.7 2.3]
 [6.1 2.6 5.6 1.4]
 [6.5 3.  5.2 2. ]
 [4.8 3.1 1.6 0.2]]
['Iris-versicolor' 'Iris-virginica' 'Iris-setosa' 'Iris-setosa'
 'Iris-versicolor' 'Iris-versicolor' 'Iris-virginica' 'Iris-virginica'
 'Iris-versicolor' 'Iris-virginica' 'Iris-versicolor' 'Iris-versicolor'
 'Iris-versicolor' 'Iris-versicolor' 'Iris-virginica' 'Iris-virginica'
 'Iris-setosa' 'Iris-virginica' 'Iris-setosa' 'Iris-virginica'
 'Iris-setosa' 'Iris-virginica' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa'
 'Iris-virginica' 'Iris-virginica' 'Iris-virginica' 'Iris-virginica'
 'Iris-setosa']

80% train data:
[[7.7 2.8 6.7 2. ]
 [6.7 3.1 5.6 2.4]
 [5.7 2.6 3.5 1. ]
 [6.3 2.8 5.1 1.5]
 [4.9 3.1 1.5 0.1]
  …
 [4.8 3.  1.4 0.3]
 [6.4 2.9 4.3 1.3]
 [4.8 3.  1.4 0.1]
 [5.5 2.6 4.4 1.2]
 [6.3 2.3 4.4 1.3]]
[2 2 1 2 0 0 0 2 2 2 2 2 0 0 2 2 1 2 1 0 1 2 0 1 2 0 1 2 2 0 1 1 1 2 0 1 0
 1 0 2 2 2 0 2 1 1 0 2 1 2 1 0 0 1 1 2 0 0 2 1 1 2 0 1 1 0 0 2 0 0 1 1 2 1
 0 1 2 2 0 1 0 0 2 0 0 2 0 1 1 2 2 0 0 1 2 0 1 1 1 0 0 1 0 2 2 0 0 0 2 2 0
 2 2 0 2 0 1 0 1 1]

20% test data:
[[6.8 3.2 5.9 2.3]
 [5.4 3.  4.5 1.5]
 [4.3 3.  1.1 0.1]
 [5.6 3.  4.1 1.3]
 [6.7 3.  5.  1.7]
 … 
 [5.8 2.7 3.9 1.2]
 [6.3 2.5 5.  1.9]
 [6.3 3.3 4.7 1.6]
 [5.1 3.7 1.5 0.4]
 [6.9 3.2 5.7 2.3]]
[2 1 0 1 1 0 2 2 2 1 0 2 1 1 1 1 1 2 1 1 1 0 2 0 0 1 2 1 0 2]
</pre>

<h3 id="4knearestneighborsscikitlearn">
	بناء نموذج K-Nearest Neighbors باستخدام ساي كيت ليرن Scikit-Learn
</h3>

<p>
	لنكتب كود برمجي لجعل نسبة تقسيم مجموعات البيانات 70% لمجموعة التدريب و30% لمجموعة الاختبار، حيث يصبح عدد العينات المستخدمة في التدريب 105 عينة وعدد عينات الاختبار 45، ثم نتوقع باستخدام نموذج KNN تصنيفات الفصائل لمجموعة الاختبار مع تحديد عدد النقاط المجاورة ليكون 5.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_9124_22" style=""><span class="kwd">import</span><span class="pln"> pandas </span><span class="kwd">as</span><span class="pln"> pd
</span><span class="kwd">from</span><span class="pln"> sklearn</span><span class="pun">.</span><span class="pln">model_selection </span><span class="kwd">import</span><span class="pln"> train_test_split
</span><span class="com"># نستدعي المُصنف من مكتبة ساي كيت ليرن</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> sklearn</span><span class="pun">.</span><span class="pln">neighbors </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">KNeighborsClassifier</span><span class="pln">
iris </span><span class="pun">=</span><span class="pln"> pd</span><span class="pun">.</span><span class="pln">read_csv</span><span class="pun">(</span><span class="str">"iris.csv"</span><span class="pun">)</span><span class="pln">

iris </span><span class="pun">=</span><span class="pln"> iris</span><span class="pun">.</span><span class="pln">drop</span><span class="pun">(</span><span class="str">'Id'</span><span class="pun">,</span><span class="pln">axis</span><span class="pun">=</span><span class="lit">1</span><span class="pun">)</span><span class="pln">
X </span><span class="pun">=</span><span class="pln"> iris</span><span class="pun">.</span><span class="pln">iloc</span><span class="pun">[:,</span><span class="pln"> </span><span class="pun">:-</span><span class="lit">1</span><span class="pun">].</span><span class="pln">values
y </span><span class="pun">=</span><span class="pln"> iris</span><span class="pun">.</span><span class="pln">iloc</span><span class="pun">[:,</span><span class="pln"> </span><span class="lit">4</span><span class="pun">].</span><span class="pln">values
</span><span class="com"># تقسيم مجموعات البيانات</span><span class="pln">
X_train</span><span class="pun">,</span><span class="pln"> X_test</span><span class="pun">,</span><span class="pln"> y_train</span><span class="pun">,</span><span class="pln"> y_test </span><span class="pun">=</span><span class="pln"> train_test_split</span><span class="pun">(</span><span class="pln">X</span><span class="pun">,</span><span class="pln"> y</span><span class="pun">,</span><span class="pln"> test_size</span><span class="pun">=</span><span class="lit">0.30</span><span class="pun">)</span><span class="pln">

</span><span class="com"># KNN Classifier استدعي</span><span class="pln">
</span><span class="com"># القيمة الافتراضية لعدد النقاط المجاورة التي لها حق التصويت هي 5</span><span class="pln">
knn </span><span class="pun">=</span><span class="pln"> </span><span class="typ">KNeighborsClassifier</span><span class="pun">(</span><span class="pln">n_neighbors</span><span class="pun">=</span><span class="lit">5</span><span class="pun">)</span><span class="pln">
</span><span class="com"># درب النموذج باستخدام مجموعة بيانات التدريب </span><span class="pln">
</span><span class="com"># في عملية التدريب الخاضع للإشراف يستطيع النموذج أن يستخدم وسم البيانات</span><span class="pln">
knn</span><span class="pun">.</span><span class="pln">fit</span><span class="pun">(</span><span class="pln">X_train</span><span class="pun">,</span><span class="pln"> y_train</span><span class="pun">)</span><span class="pln">
</span><span class="com"># استخدم النموذج المدرب لتوقع مجموعة بيانات الاختبار </span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"Response for test dataset:"</span><span class="pun">)</span><span class="pln">
y_pred </span><span class="pun">=</span><span class="pln"> knn</span><span class="pun">.</span><span class="pln">predict</span><span class="pun">(</span><span class="pln">X_test</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">y_pred</span><span class="pun">)</span></pre>

<p>
	استخدمنا دالة <code>knn.fit(X_train, y_train)‎</code> لتدريب الكائن الذي يُطبق خوارزمية KNN في مكتبة ساي كيت ليرن، ولتدريب النموذج استخدمنا مجموعة خاصيات التدريب <code>X_train</code> والوسوم المقابلة لها <code>y_train</code>، وأثناء تهيئة الكائن عرفنا بعض الإعدادات والمعاملات مثل عدد النقاط المجاورة <code>n_neighbors</code>، وبعد تدريب النموذج استخدمناه لتوقع وسوم خاصيات مجموعة الاختبار <code>X_test</code>.
</p>

<p>
	عند تنفيذ الكود سنحصل على الخرج التالي:
</p>

<pre class="ipsCode">Response for test dataset:
['Iris-versicolor' 'Iris-setosa' 'Iris-versicolor' 'Iris-versicolor'
 'Iris-versicolor' 'Iris-versicolor' 'Iris-versicolor' 'Iris-virginica'
 'Iris-versicolor' 'Iris-virginica' 'Iris-virginica' 'Iris-versicolor'
 'Iris-versicolor' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa'
 'Iris-versicolor' 'Iris-setosa' 'Iris-setosa' 'Iris-virginica'
 'Iris-setosa' 'Iris-setosa' 'Iris-virginica' 'Iris-versicolor'
 'Iris-setosa' 'Iris-versicolor' 'Iris-virginica' 'Iris-setosa'
 'Iris-versicolor' 'Iris-versicolor' 'Iris-virginica' 'Iris-setosa'
 'Iris-virginica' 'Iris-setosa' 'Iris-setosa' 'Iris-setosa'
 'Iris-virginica' 'Iris-virginica' 'Iris-versicolor' 'Iris-versicolor'
 'Iris-virginica' 'Iris-virginica' 'Iris-virginica' 'Iris-setosa'
 'Iris-virginica']
</pre>

<p>
	نلاحظ أن النموذج استطاع التعامل مع القيم النصية لتصنيفات الفصائل بشكل مباشر، وهذا ليس السائد في نماذج تعلم الآلة حيث أغلبها يتوقع فقط قيمًا رقمية حيث أن أغلب الخوارزميات تقوم بعمليات رياضية، ولكن كما ذكرنا من قبل فإن خوارزمية KNN لا معاملية non-parametric ولا تقوم بأي عمليات رياضية معقدة، فقط عملية التصويت في حالة التصنيف.
</p>

<p>
	نلاحظ أيضًا أن هذا يعمل فقط مع القيم النصية للوسوم وليس للخاصيات أو الأعمدة الأخرى المستخدمة في التدريب، حيث يحتاج النموذج لحساب المسافة بين نقطة الاستفسار query points وبين جميع النقاط في مجموعة التدريب المخزنة في الذاكرة ليستطيع تقرير أقرب k من النقاط المجاورة مسافةً.
</p>

<h3 id="6kknn">
	اختبار تأثير تغير عدد النقاط المجاورة K في خوارزمية KNN
</h3>

<p>
	سنكتب تطبيق لتقسيم مجموعة بيانات آيرس بنسبة 80% لمجموعة بيانات التدريب و20% لمجموعة بيانات الاختبار، ثم ندرب نموذج KNN على مجموعة بيانات التدريب ونحسب دقة النموذج في توقع وسوم مجموعة الاختبار، لنجرب قيمًا مختلفة لعدد النقاط المجاورة من 1 إلى 9  ونحسب دقة النموذج لكل قيمة.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_9124_24" style=""><span class="kwd">import</span><span class="pln"> pandas </span><span class="kwd">as</span><span class="pln"> pd
</span><span class="kwd">from</span><span class="pln"> sklearn</span><span class="pun">.</span><span class="pln">neighbors </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">KNeighborsClassifier</span><span class="pln"> 
</span><span class="kwd">from</span><span class="pln"> sklearn</span><span class="pun">.</span><span class="pln">model_selection </span><span class="kwd">import</span><span class="pln"> train_test_split  
iris </span><span class="pun">=</span><span class="pln"> pd</span><span class="pun">.</span><span class="pln">read_csv</span><span class="pun">(</span><span class="str">"iris.csv"</span><span class="pun">)</span><span class="pln">

iris </span><span class="pun">=</span><span class="pln"> iris</span><span class="pun">.</span><span class="pln">drop</span><span class="pun">(</span><span class="str">'Id'</span><span class="pun">,</span><span class="pln">axis</span><span class="pun">=</span><span class="lit">1</span><span class="pun">)</span><span class="pln">
X </span><span class="pun">=</span><span class="pln"> iris</span><span class="pun">.</span><span class="pln">iloc</span><span class="pun">[:,</span><span class="pln"> </span><span class="pun">:-</span><span class="lit">1</span><span class="pun">].</span><span class="pln">values
y </span><span class="pun">=</span><span class="pln"> iris</span><span class="pun">.</span><span class="pln">iloc</span><span class="pun">[:,</span><span class="pln"> </span><span class="lit">4</span><span class="pun">].</span><span class="pln">values
</span><span class="com"># تقسيم البيانات</span><span class="pln">
X_train</span><span class="pun">,</span><span class="pln"> X_test</span><span class="pun">,</span><span class="pln"> y_train</span><span class="pun">,</span><span class="pln"> y_test </span><span class="pun">=</span><span class="pln"> train_test_split</span><span class="pun">(</span><span class="pln">X</span><span class="pun">,</span><span class="pln"> y</span><span class="pun">,</span><span class="pln"> test_size</span><span class="pun">=</span><span class="lit">0.20</span><span class="pun">)</span><span class="pln"> 

</span><span class="com"># k احسب الدقة لكل قيمة</span><span class="pln">
</span><span class="com"># k=1,2,...,9</span><span class="pln">
</span><span class="kwd">for</span><span class="pln"> k </span><span class="kwd">in</span><span class="pln"> range</span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">10</span><span class="pun">):</span><span class="pln">
    knn </span><span class="pun">=</span><span class="pln"> </span><span class="typ">KNeighborsClassifier</span><span class="pun">(</span><span class="pln">n_neighbors</span><span class="pun">=</span><span class="pln">k</span><span class="pun">)</span><span class="pln">  
    knn</span><span class="pun">.</span><span class="pln">fit</span><span class="pun">(</span><span class="pln">X_train</span><span class="pun">,</span><span class="pln"> y_train</span><span class="pun">)</span><span class="pln">   
    </span><span class="kwd">print</span><span class="pun">(</span><span class="str">"For k = %d accuracy is"</span><span class="pun">%</span><span class="pln">k</span><span class="pun">,</span><span class="pln">knn</span><span class="pun">.</span><span class="pln">score</span><span class="pun">(</span><span class="pln">X_test</span><span class="pun">,</span><span class="pln">y_test</span><span class="pun">))</span></pre>

<p>
	أنشأنا حلقة تكرارية حيث نجرب قيمًا مختلفة لعدد النقاط المجاورة k وندرب النموذج ونحسب دقته ونطبعها.
</p>

<p>
	عند تنفيذ الكود سنحصل على الخرج التالي:
</p>

<pre class="ipsCode">For k = 1 accuracy is 0.9666666666666667
For k = 2 accuracy is 0.9666666666666667
For k = 3 accuracy is 0.9666666666666667
For k = 4 accuracy is 0.9333333333333333
For k = 5 accuracy is 0.9666666666666667
For k = 6 accuracy is 0.9666666666666667
For k = 7 accuracy is 0.9666666666666667
For k = 8 accuracy is 0.9333333333333333
For k = 9 accuracy is 0.9666666666666667
</pre>

<h3 id="7kknn">
	رسم بياني لدراسة تأثير تغير عدد النقاط المجاورة K في خوارزمية KNN
</h3>

<p>
	لنقسم الآن مجموعة بيانات آيرس بنسبة 80% لمجموعة بيانات التدريب و20% لمجموعة بيانات الاختبار، ثم ندرب نموذج KNN على مجموعة بيانات التدريب ونحسب دقة النموذج في توقع وسوم مجموعة الاختبار، لنجرب قيمًا مختلفة لعدد النقاط المجاورة من 1 إلى 9 ونحسب لكل قيمة دقة النموذج، ونرسم رسمًا بيانيًا جاعلين محور السينات x للقيم المختلفة لعدد النقاط المجاورة K، بينما محور الصادات y للدقة التي حققها النموذج باستخدام قيمة k.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_9124_26" style=""><span class="kwd">import</span><span class="pln"> pandas </span><span class="kwd">as</span><span class="pln"> pd
</span><span class="kwd">import</span><span class="pln"> matplotlib</span><span class="pun">.</span><span class="pln">pyplot </span><span class="kwd">as</span><span class="pln"> plt
</span><span class="kwd">from</span><span class="pln"> sklearn</span><span class="pun">.</span><span class="pln">neighbors </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">KNeighborsClassifier</span><span class="pln"> 
</span><span class="kwd">from</span><span class="pln"> sklearn</span><span class="pun">.</span><span class="pln">model_selection </span><span class="kwd">import</span><span class="pln"> train_test_split  
</span><span class="com"># لضبط عرض النص العربي</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> arabic_reshaper </span><span class="kwd">import</span><span class="pln"> reshape
</span><span class="kwd">from</span><span class="pln"> bidi</span><span class="pun">.</span><span class="pln">algorithm </span><span class="kwd">import</span><span class="pln"> get_display

iris </span><span class="pun">=</span><span class="pln"> pd</span><span class="pun">.</span><span class="pln">read_csv</span><span class="pun">(</span><span class="str">"iris.csv"</span><span class="pun">)</span><span class="pln">

iris </span><span class="pun">=</span><span class="pln"> iris</span><span class="pun">.</span><span class="pln">drop</span><span class="pun">(</span><span class="str">'Id'</span><span class="pun">,</span><span class="pln">axis</span><span class="pun">=</span><span class="lit">1</span><span class="pun">)</span><span class="pln">
X </span><span class="pun">=</span><span class="pln"> iris</span><span class="pun">.</span><span class="pln">iloc</span><span class="pun">[:,</span><span class="pln"> </span><span class="pun">:-</span><span class="lit">1</span><span class="pun">].</span><span class="pln">values
y </span><span class="pun">=</span><span class="pln"> iris</span><span class="pun">.</span><span class="pln">iloc</span><span class="pun">[:,</span><span class="pln"> </span><span class="lit">4</span><span class="pun">].</span><span class="pln">values
</span><span class="com"># تقسيم البيانات</span><span class="pln">
X_train</span><span class="pun">,</span><span class="pln"> X_test</span><span class="pun">,</span><span class="pln"> y_train</span><span class="pun">,</span><span class="pln"> y_test </span><span class="pun">=</span><span class="pln"> train_test_split</span><span class="pun">(</span><span class="pln">X</span><span class="pun">,</span><span class="pln"> y</span><span class="pun">,</span><span class="pln"> test_size</span><span class="pun">=</span><span class="lit">0.20</span><span class="pun">,</span><span class="pln"> random_state</span><span class="pun">=</span><span class="lit">10</span><span class="pun">)</span><span class="pln"> 
</span><span class="com"># random_state معامل يضمن ثبات نتيجة التجربة عند تشغيل الكود مرة أخرى</span><span class="pln">
</span><span class="com"># بدون هذا المعامل ستحصل على نتيجة مختلفة بكل مرة تشغل بها الكود</span><span class="pln">

</span><span class="com"># accuracy نعرف قائمة لحفظ القيم الدقة  </span><span class="pln">
acc </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[]</span><span class="pln">
</span><span class="com"># k احسب الدقة لكل قيمة</span><span class="pln">
</span><span class="com"># k=1,2,...,9</span><span class="pln">
</span><span class="kwd">for</span><span class="pln"> k </span><span class="kwd">in</span><span class="pln"> range</span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">10</span><span class="pun">):</span><span class="pln">
    knn </span><span class="pun">=</span><span class="pln"> </span><span class="typ">KNeighborsClassifier</span><span class="pun">(</span><span class="pln">n_neighbors</span><span class="pun">=</span><span class="pln">k</span><span class="pun">)</span><span class="pln">  
    knn</span><span class="pun">.</span><span class="pln">fit</span><span class="pun">(</span><span class="pln">X_train</span><span class="pun">,</span><span class="pln"> y_train</span><span class="pun">)</span><span class="pln"> 
    score </span><span class="pun">=</span><span class="pln"> knn</span><span class="pun">.</span><span class="pln">score</span><span class="pun">(</span><span class="pln">X_test</span><span class="pun">,</span><span class="pln">y_test</span><span class="pun">)</span><span class="pln"> 
    acc</span><span class="pun">.</span><span class="pln">append</span><span class="pun">(</span><span class="pln">score</span><span class="pun">)</span><span class="pln">

plt</span><span class="pun">.</span><span class="pln">figure</span><span class="pun">(</span><span class="pln">figsize</span><span class="pun">=(</span><span class="lit">10</span><span class="pun">,</span><span class="pln"> </span><span class="lit">5</span><span class="pun">),</span><span class="pln"> dpi</span><span class="pun">=</span><span class="lit">150</span><span class="pun">)</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">plot</span><span class="pun">([</span><span class="pln">k </span><span class="kwd">for</span><span class="pln"> k </span><span class="kwd">in</span><span class="pln"> range</span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">10</span><span class="pun">)],</span><span class="pln"> acc</span><span class="pun">)</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">title</span><span class="pun">(</span><span class="pln">get_display</span><span class="pun">(</span><span class="pln">reshape</span><span class="pun">(</span><span class="str">"العلاقة بين تغير عدد النقاط المجاورة والدقة"</span><span class="pun">)))</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">xlabel</span><span class="pun">(</span><span class="pln">get_display</span><span class="pun">(</span><span class="pln">reshape</span><span class="pun">(</span><span class="str">"k عدد النقاط المجاورة"</span><span class="pun">)))</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">ylabel</span><span class="pun">(</span><span class="pln">get_display</span><span class="pun">(</span><span class="pln">reshape</span><span class="pun">(</span><span class="str">"Accuracy الدقة"</span><span class="pun">)))</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">show</span><span class="pun">()</span></pre>

<p>
	أنشانا في الكود السابق حلقة تكرارية حيث نجرب قيمًا مختلفة لعدد النقاط المجاورة k وندرب النموذج ونحسب دقته ونطبعها، وقد حفظنا دقة النموذج عند كل نقطة k في القائمة <code>acc</code> لنستخدمها في الرسم البياني، ويمكن أن نلاحظ أننا استخدمنا <code>random_state=10</code> لتثبيت تقسيم البيانات العشوائي وجعل الكود يخرج نفس الرسم البياني في كل مرة.
</p>

<p>
	عند تنفيذ الكود سنحصل على الرسم البياني التالي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="170883" href="https://academy.hsoub.com/uploads/monthly_2025_04/001_AccPlot.png.4846d1689c4a4ff0780be83878b3c208.png" rel=""><img alt="001 accplot" class="ipsImage ipsImage_thumbnailed" data-fileid="170883" data-unique="o1kvg2w3h" style="width: 700px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_04/001_AccPlot.thumb.png.b38d278739d7577cbc288086af507a56.png"> </a>
</p>

<h2>
	مقارنة أداء النموذج بين مجموعة بيانات التدريب ومجموعة بيانات الاختبار
</h2>

<p>
	سنكتب برنامج لتقسيم مجموعة بيانات آيرس بنسبة 80% لمجموعة بيانات التدريب و20% لمجموعة بيانات الاختبار، ثم درب نموذج KNN على مجموعة بيانات التدريب ونحسب دقة النموذج في توقع وسوم مجموعة الاختبار، وكذلك دقته في توقع وسوم مجموعة التدريب، لنجرب قيمًا مختلفة لعدد النقاط المجاورة من 1 إلى 9  ونحسب لكل قيمة دقة النموذج، ونرسم رسمًا بيانيًا جاعلين محور السينات x للقيم المختلفة لعدد النقاط المجاورة K، بينما محور الصادات y للدقة التي حققها النموذج باستخدام قيمة k، سنستخدم هذا الرسم البياني للمقارنة بين أداء النموذج على مجموعة التدريب أمام أدائه على مجموعة الاختبار.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_9124_28" style=""><span class="kwd">import</span><span class="pln"> pandas </span><span class="kwd">as</span><span class="pln"> pd
</span><span class="kwd">import</span><span class="pln"> matplotlib</span><span class="pun">.</span><span class="pln">pyplot </span><span class="kwd">as</span><span class="pln"> plt
</span><span class="kwd">from</span><span class="pln"> sklearn</span><span class="pun">.</span><span class="pln">neighbors </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">KNeighborsClassifier</span><span class="pln"> 
</span><span class="kwd">from</span><span class="pln"> sklearn</span><span class="pun">.</span><span class="pln">model_selection </span><span class="kwd">import</span><span class="pln"> train_test_split  
</span><span class="com"># لضبط عرض النص العربي</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> arabic_reshaper </span><span class="kwd">import</span><span class="pln"> reshape
</span><span class="kwd">from</span><span class="pln"> bidi</span><span class="pun">.</span><span class="pln">algorithm </span><span class="kwd">import</span><span class="pln"> get_display

iris </span><span class="pun">=</span><span class="pln"> pd</span><span class="pun">.</span><span class="pln">read_csv</span><span class="pun">(</span><span class="str">"iris.csv"</span><span class="pun">)</span><span class="pln">

iris </span><span class="pun">=</span><span class="pln"> iris</span><span class="pun">.</span><span class="pln">drop</span><span class="pun">(</span><span class="str">'Id'</span><span class="pun">,</span><span class="pln">axis</span><span class="pun">=</span><span class="lit">1</span><span class="pun">)</span><span class="pln">
X </span><span class="pun">=</span><span class="pln"> iris</span><span class="pun">.</span><span class="pln">iloc</span><span class="pun">[:,</span><span class="pln"> </span><span class="pun">:-</span><span class="lit">1</span><span class="pun">].</span><span class="pln">values
y </span><span class="pun">=</span><span class="pln"> iris</span><span class="pun">.</span><span class="pln">iloc</span><span class="pun">[:,</span><span class="pln"> </span><span class="lit">4</span><span class="pun">].</span><span class="pln">values
</span><span class="com"># تقسيم البيانات</span><span class="pln">
X_train</span><span class="pun">,</span><span class="pln"> X_test</span><span class="pun">,</span><span class="pln"> y_train</span><span class="pun">,</span><span class="pln"> y_test </span><span class="pun">=</span><span class="pln"> train_test_split</span><span class="pun">(</span><span class="pln">X</span><span class="pun">,</span><span class="pln"> y</span><span class="pun">,</span><span class="pln"> test_size</span><span class="pun">=</span><span class="lit">0.20</span><span class="pun">,</span><span class="pln"> random_state</span><span class="pun">=</span><span class="lit">21</span><span class="pun">)</span><span class="pln"> 
</span><span class="com"># random_state معامل يضمن ثبات نتيجة التجربة عند تشغيل الكود مرة أخرى</span><span class="pln">
</span><span class="com"># بدون هذا المعامل ستحصل على نتيجة مختلفة بكل مرة تشغل بها الكود</span><span class="pln">

</span><span class="com"># accuracy نعرف قائمة لحفظ القيم الدقة  </span><span class="pln">
test_acc </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[]</span><span class="pln"> 
train_acc </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[]</span><span class="pln">
</span><span class="com"># k احسب الدقة لكل قيمة</span><span class="pln">
</span><span class="com"># k=1,2,...,9</span><span class="pln">
</span><span class="kwd">for</span><span class="pln"> k </span><span class="kwd">in</span><span class="pln"> range</span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">10</span><span class="pun">):</span><span class="pln">
    knn </span><span class="pun">=</span><span class="pln"> </span><span class="typ">KNeighborsClassifier</span><span class="pun">(</span><span class="pln">n_neighbors</span><span class="pun">=</span><span class="pln">k</span><span class="pun">)</span><span class="pln">  
    knn</span><span class="pun">.</span><span class="pln">fit</span><span class="pun">(</span><span class="pln">X_train</span><span class="pun">,</span><span class="pln"> y_train</span><span class="pun">)</span><span class="pln"> 
    test_score </span><span class="pun">=</span><span class="pln"> knn</span><span class="pun">.</span><span class="pln">score</span><span class="pun">(</span><span class="pln">X_test</span><span class="pun">,</span><span class="pln">y_test</span><span class="pun">)</span><span class="pln"> 
    train_score </span><span class="pun">=</span><span class="pln"> knn</span><span class="pun">.</span><span class="pln">score</span><span class="pun">(</span><span class="pln">X_train</span><span class="pun">,</span><span class="pln"> y_train</span><span class="pun">)</span><span class="pln">
    test_acc</span><span class="pun">.</span><span class="pln">append</span><span class="pun">(</span><span class="pln">test_score</span><span class="pun">)</span><span class="pln">
    train_acc</span><span class="pun">.</span><span class="pln">append</span><span class="pun">(</span><span class="pln">train_score</span><span class="pun">)</span><span class="pln">

plt</span><span class="pun">.</span><span class="pln">figure</span><span class="pun">(</span><span class="pln">figsize</span><span class="pun">=(</span><span class="lit">10</span><span class="pun">,</span><span class="pln"> </span><span class="lit">5</span><span class="pun">),</span><span class="pln"> dpi</span><span class="pun">=</span><span class="lit">150</span><span class="pun">)</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">plot</span><span class="pun">([</span><span class="pln">k </span><span class="kwd">for</span><span class="pln"> k </span><span class="kwd">in</span><span class="pln"> range</span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">10</span><span class="pun">)],</span><span class="pln"> test_acc</span><span class="pun">,</span><span class="pln"> label</span><span class="pun">=</span><span class="pln">get_display</span><span class="pun">(</span><span class="pln">reshape</span><span class="pun">(</span><span class="str">"دقة النموذج على بيانات الاختبار"</span><span class="pun">)),</span><span class="pln"> color</span><span class="pun">=</span><span class="str">'salmon'</span><span class="pun">)</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">plot</span><span class="pun">([</span><span class="pln">k </span><span class="kwd">for</span><span class="pln"> k </span><span class="kwd">in</span><span class="pln"> range</span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">10</span><span class="pun">)],</span><span class="pln"> train_acc</span><span class="pun">,</span><span class="pln"> label</span><span class="pun">=</span><span class="pln">get_display</span><span class="pun">(</span><span class="pln">reshape</span><span class="pun">(</span><span class="str">"دقة النموذج على بيانات التدريب"</span><span class="pun">)),</span><span class="pln"> color</span><span class="pun">=</span><span class="str">"skyblue"</span><span class="pun">)</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">title</span><span class="pun">(</span><span class="pln">get_display</span><span class="pun">(</span><span class="pln">reshape</span><span class="pun">(</span><span class="str">"العلاقة بين تغير عدد النقاط المجاورة والدقة"</span><span class="pun">)))</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">xlabel</span><span class="pun">(</span><span class="pln">get_display</span><span class="pun">(</span><span class="pln">reshape</span><span class="pun">(</span><span class="str">"k عدد النقاط المجاورة"</span><span class="pun">)))</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">ylabel</span><span class="pun">(</span><span class="pln">get_display</span><span class="pun">(</span><span class="pln">reshape</span><span class="pun">(</span><span class="str">"Accuracy الدقة"</span><span class="pun">)))</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">legend</span><span class="pun">()</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">show</span><span class="pun">()</span></pre>

<p>
	يختلف هذا التدريب عن السابق في أنه يحسب الدقة على مجموعة التدريب ومجموعة الاختبار وهي استراتيجية شائعة تستخدم لاختبار مدى قدرة النموذج على التعميم generalization، حيث لا ينبغي أن يكون الفرق المطلق بين أداء النموذج على مجموعة التدريب ومجموعة الاختبار كبيرًا، فأن كان أداء النموذج جيد جدًا في مجموعة التدريب وسيئ للغاية فهذا النموذج ليس قابلًا للاستخدام في العالم الحقيقي على البيانات التي لم يرها من قبل، يمكن تشبيه هذه الحالة بالطالب الذي حفظ أسئلة الاختبار وعند تخرجه ليواجه المشاكل الحقيقية فشل فشلًا ذريعًا لأنه في واقع الأمر حفظ البيانات ولم يتعلم منها وتعرف هذه الحالة بالمسايرة المفرطة أو فرط التخصيص overfitting، وفي الحالة التي يكون أداء النموذج سئيًا على كل من مجموعة بيانات الاختبار والتدريب فتعرف هذه الحالة بقلة التخصيص underfitting وهي بساطة النموذج لدرجة تمنعه من تعلم الأنماط المعقدة الموجودة في مجموعة البيانات.
</p>

<p>
	عند تنفيذ الكود سنحصل على الرسم البياني التالي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="170884" href="https://academy.hsoub.com/uploads/monthly_2025_04/002_AccTrainTestPlot.png.883467f27d458a4e505d6b313e6ba6db.png" rel=""><img alt="002 acctraintestplot" class="ipsImage ipsImage_thumbnailed" data-fileid="170884" data-unique="c2vfxpxaz" style="width: 680px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_04/002_AccTrainTestPlot.thumb.png.5cdbe43d6d88f4c11fefe96b56d78aaa.png"> </a>
</p>

<h2 id="">
	الخاتمة
</h2>

<p>
	تناولنا في المقال الثالث من <a href="https://academy.hsoub.com/tags/%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA%20scikit%20learn/" rel="">سلسلة تطبيقات ساي كيت ليرن</a> مجموعة تدريبات على  خوارزمية أقرب الجيران K-Nearest Neighbors واستخدمناها لتصنيف فصائل أزهار آيرس، ودرسنا كيفية تقسيم البيانات لمجموعة تدريب ومجموعة اختبار مع تقييم النموذج وحساب دقة التوقعات،كما تعرفنا على تأثير عدد النقاط المجاورة في هذه الخوارزمية، سنتدرب في <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%AE%D9%88%D8%A7%D8%B1%D8%B2%D9%85%D9%8A%D8%A9-%D8%A7%D9%84%D8%A7%D9%86%D8%AD%D8%AF%D8%A7%D8%B1-%D8%A7%D9%84%D9%84%D9%88%D8%AC%D8%B3%D8%AA%D9%8A-logistic-regression-%D9%81%D9%8A-scikit-learn-r2563/" rel="">المقال القادم</a> على استخدام خوارزمية الانحدار اللوجيستي Logistic Regression وهي أيضًا خوارزمية أساسية من خوازرميات التصنيف Classification وتستخدم في مهام عديدة مثل تشخيص الأمراض وتصنيف رسائل البريد.
</p>

<h2 id="-1">
	اقرأ أيضًا
</h2>

<ul>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A7%D9%84%D8%AA%D9%85%D8%AB%D9%8A%D9%84-%D8%A7%D9%84%D9%85%D8%B1%D8%A6%D9%8A-%D9%84%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-scikit-learn-%D9%85%D8%B9-matplotlib-%D9%88-seaborn-r2553/" rel="">التمثيل المرئي للبيانات باستخدام Scikit-Learn مع Matplotlib و Seaborn</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D9%82%D9%8A%D9%8A%D9%85-%D9%88%D8%A7%D8%AE%D8%AA%D9%8A%D8%A7%D8%B1-%D9%86%D9%85%D8%A7%D8%B0%D8%AC-%D8%AA%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%A2%D9%84%D8%A9-r1635/" rel="">تقييم واختيار نماذج تعلم الآلة</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D9%85%D8%B5%D8%B7%D9%84%D8%AD%D8%A7%D8%AA-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-%D9%84%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86-r2363/" rel="">مصطلحات الذكاء الاصطناعي للمبتدئين</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A8%D9%86%D8%A7%D8%A1-%D9%85%D8%B5%D9%86%D9%81-%D8%A8%D8%A7%D9%84%D8%A7%D8%B9%D8%AA%D9%85%D8%A7%D8%AF-%D8%B9%D9%84%D9%89-%D8%B7%D8%B1%D9%82-%D8%AA%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%A2%D9%84%D8%A9-%D8%A8%D9%84%D8%BA%D8%A9-%D8%A7%D9%84%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D9%85%D9%83%D8%AA%D8%A8%D8%A9-scikit-learn-r1266/" rel="">بناء مصنف بالاعتماد على طرق تعلم الآلة بلغة البايثون واستخدام Scikit-Learn</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">2560</guid><pubDate>Fri, 18 Apr 2025 13:01:00 +0000</pubDate></item><item><title>&#x627;&#x644;&#x62A;&#x645;&#x62B;&#x64A;&#x644; &#x627;&#x644;&#x645;&#x631;&#x626;&#x64A; &#x644;&#x644;&#x628;&#x64A;&#x627;&#x646;&#x627;&#x62A; &#x628;&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; Scikit-Learn &#x645;&#x639; Matplotlib &#x648; Seaborn</title><link>https://academy.hsoub.com/programming/artificial-intelligence/%D8%A7%D9%84%D8%AA%D9%85%D8%AB%D9%8A%D9%84-%D8%A7%D9%84%D9%85%D8%B1%D8%A6%D9%8A-%D9%84%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-scikit-learn-%D9%85%D8%B9-matplotlib-%D9%88-seaborn-r2553/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2025_04/02.Scikit-LearnMatplotlibSeaborn.png.0565c1a2eb3ff44c861a11d04673e4e0.png" /></p>
<p>
	نشرح في هذا المقال التمثيل المرئي لمجموعة بيانات أزهار آيرس Iris dataset باستخدام مكتبة Scikit-Learn ومجموعة من المكتبات المفيدة الأخرى بهدف ملاحظة الأنماط وفهم العلاقات بين الخاصيات المختلفة لمجموعة بيانات الأزهار من خلال عرضها على شكل رسومات بيانية.
</p>

<h2 id="datavisualization">
	أهمية التمثيل المرئي للبيانات Data Visualization
</h2>

<p>
	سنوفر عدة تطبيقات عملية توضح مجموعة مهمة من أنواع الرسومات البيانية plots والتي لا غنى عنها في أي عملية تحليل للبيانات أو التمثيل المرئي للبيانات والنتائج التي تسهل فهم العلاقات واكتشاف الأنماط وعرض نتائج التحليل الإحصائي وتقييم أداء نماذج تعلم الآلة، ليس فقط للمختصين في البرمجة بل للعامة، فالجميع يمكن أن يفهم الرسومات البيانية والتوضيحية التي تسرع من توصيل المعلومات.
</p>

<h3 id="1">
	تمثيل مرئي عام للمعلومات الإحصائية
</h3>

<p>
	سنكتب برنامج بايثون لإنشاء رسم بياني للحصول على المعلومات الإحصائية العامة عن مجموعة بيانات آيرس.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_13_8" style=""><span class="kwd">import</span><span class="pln"> pandas </span><span class="kwd">as</span><span class="pln"> pd
</span><span class="kwd">import</span><span class="pln"> matplotlib</span><span class="pun">.</span><span class="pln">pyplot </span><span class="kwd">as</span><span class="pln"> plt
iris </span><span class="pun">=</span><span class="pln"> pd</span><span class="pun">.</span><span class="pln">read_csv</span><span class="pun">(</span><span class="str">"iris.csv"</span><span class="pun">)</span><span class="pln">
iris</span><span class="pun">.</span><span class="pln">describe</span><span class="pun">().</span><span class="pln">plot</span><span class="pun">(</span><span class="pln">kind </span><span class="pun">=</span><span class="pln"> </span><span class="str">"area"</span><span class="pun">,</span><span class="pln">fontsize</span><span class="pun">=</span><span class="lit">16</span><span class="pun">,</span><span class="pln"> figsize </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="lit">15</span><span class="pun">,</span><span class="lit">8</span><span class="pun">),</span><span class="pln"> table </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">False</span><span class="pun">,</span><span class="pln"> colormap</span><span class="pun">=</span><span class="str">"Accent"</span><span class="pun">)</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">xlabel</span><span class="pun">(</span><span class="str">'Statistics'</span><span class="pun">,)</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">ylabel</span><span class="pun">(</span><span class="str">'Value'</span><span class="pun">)</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">title</span><span class="pun">(</span><span class="str">"General Statistics of Iris Dataset"</span><span class="pun">)</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">show</span><span class="pun">()</span></pre>

<p>
	استوردنا في الكود السابق المكتبة pandas وهي مكتبة بايثون مفيدة لمعالجة البيانات وتحليلها، ومكتبة matplotlib والتي تتخصص في رسم الرسومات البيانية بمختلف أنواعها، وحمّلنا مجموعة البيانات في الكائن <code>iris</code>، ثم استخدمنا الدالة<code>describe()‎</code> الذي تطرقنا له في <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-%D8%AA%D8%AD%D9%84%D9%8A%D9%84-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-scikit-learn-%D9%85%D8%B9-pandas-r2554/" rel="">الدرس السابق </a>لعرض الإحصائيات الهامة عن مجموعة البيانات، بعدها استدعينا<code>plot()‎</code>  ومررنا له إعدادات الرسم مثل نوع الرسم البياني <code>kind=area</code>، وحجم الخط والألوان المستخدمة وأبعاد الرسم البياني وغيرها من الإعدادت، وأخيرًا عرضنا الرسم البياني باستخدام <code>plt.show()‎</code>.
</p>

<p>
	عند تنفيذ الكود السابق سنحصل على الرسم البياني التالي:
</p>

<p style="text-align: center;">
	<img alt="001 التمثيل المرئي للمعلومات الإحصائية العامة" class="ipsImage ipsImage_thumbnailed" data-fileid="170588" data-ratio="100.25" data-unique="5bqczjzev" style="width: 400px; height: auto;" width="589" src="https://academy.hsoub.com/uploads/monthly_2025_04/Iris_jointplot.png.e35f1b39c05cbeddb59fdd214df2f2bc.png">
</p>

<h3 id="2barplot">
	رسم بياني شريطي Bar Plot
</h3>

<p>
	سنكتب الآن برنامج بايثون لإنشاء رسم بياني شريطي لرسم توزيع ثلاث فصائل من الأزهار وبيان تكرار ها في مجموعة البيانات.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_13_12" style=""><span class="kwd">import</span><span class="pln"> pandas </span><span class="kwd">as</span><span class="pln"> pd
</span><span class="kwd">import</span><span class="pln"> seaborn </span><span class="kwd">as</span><span class="pln"> sns
</span><span class="kwd">import</span><span class="pln"> matplotlib</span><span class="pun">.</span><span class="pln">pyplot </span><span class="kwd">as</span><span class="pln"> plt
iris </span><span class="pun">=</span><span class="pln"> pd</span><span class="pun">.</span><span class="pln">read_csv</span><span class="pun">(</span><span class="str">"iris.csv"</span><span class="pun">)</span><span class="pln">
ax</span><span class="pun">=</span><span class="pln">plt</span><span class="pun">.</span><span class="pln">subplots</span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="lit">1</span><span class="pun">,</span><span class="pln">figsize</span><span class="pun">=(</span><span class="lit">10</span><span class="pun">,</span><span class="lit">8</span><span class="pun">))</span><span class="pln">
sns</span><span class="pun">.</span><span class="pln">countplot</span><span class="pun">(</span><span class="pln">data</span><span class="pun">=</span><span class="pln">iris</span><span class="pun">)</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">title</span><span class="pun">(</span><span class="str">"Iris Species Count"</span><span class="pun">)</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">show</span><span class="pun">()</span></pre>

<p>
	أنشأنا باستخدام الدالة<code>plt.subplots()‎</code> شكلًا بيانيًا يمكنه احتواء عدد من الرسومات البيانية الجزئية، ومررنا للدالة عدد الصفوف والأعمدة التي نرغب أن يتكون منها الشكل البياني وهي في حالتنا صف واحد وعمود واحد، أي سيحتوي الشكل البياني على رسم بياني جزئي واحد فقط، ثم ضبطنا أبعاد الرسم البياني، بعدها استخدمنا الدالة<code>sns.countplot()‎</code> لإنشاء رسم شريطي Bar plot وهذه الدالة جزء من مكتبة seaborn التي تستخدم في الخلفية مكتبة matplotlib ولكنها تختصر العديد من الخطوات وتبسّطها حيث يمكن أن ننشئ العديد من الرسومات البيانية المعقدة بسطر برمجي واحد دون الدخول في تفاصيل معقدة.
</p>

<p>
	عند تنفيذ الكود سنحصل على الرسم البياني التالي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="170587" href="https://academy.hsoub.com/uploads/monthly_2025_04/iris_counts.png.ed459822c117d4503bf1a196d88b4cba.png" rel=""><img alt="002 الرسم البياني الشريطي Bar plot" class="ipsImage ipsImage_thumbnailed" data-fileid="170587" data-unique="czxc2cj9g" style="width: 400px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_04/iris_counts.thumb.png.e21aec5530ba33ad97f02e5f62149579.png"> </a>
</p>

<h3 id="3pieplot">
	رسم بياني دائري Pie Plot
</h3>

<p>
	سنكتب الآن برنامج بايثون لإنشاء رسم بياني دائري يوضح توزيع فصائل الأزهار وتكرارها في مجموعة البيانات.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_13_16" style=""><span class="kwd">import</span><span class="pln"> pandas </span><span class="kwd">as</span><span class="pln"> pd
</span><span class="kwd">import</span><span class="pln"> matplotlib</span><span class="pun">.</span><span class="pln">pyplot </span><span class="kwd">as</span><span class="pln"> plt
iris </span><span class="pun">=</span><span class="pln"> pd</span><span class="pun">.</span><span class="pln">read_csv</span><span class="pun">(</span><span class="str">"iris.csv"</span><span class="pun">)</span><span class="pln">
</span><span class="com"># ضبط أبعاد الرسم البياني</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">figure</span><span class="pun">(</span><span class="pln">figsize</span><span class="pun">=(</span><span class="lit">10</span><span class="pun">,</span><span class="lit">8</span><span class="pun">))</span><span class="pln">
labels </span><span class="pun">=</span><span class="pln"> iris</span><span class="pun">[</span><span class="str">'Species'</span><span class="pun">].</span><span class="pln">value_counts</span><span class="pun">().</span><span class="pln">index
</span><span class="com"># وسم كل شريحة</span><span class="pln">
</span><span class="com"># Index(['Iris-setosa', 'Iris-versicolor', 'Iris-virginica'], dtype='object', name='Species')</span><span class="pln">
values </span><span class="pun">=</span><span class="pln"> iris</span><span class="pun">[</span><span class="str">'Species'</span><span class="pun">].</span><span class="pln">value_counts</span><span class="pun">().</span><span class="pln">values
</span><span class="com">#  تكرار كل فصيلة والتي يحسب منها نسبة كل شريحة</span><span class="pln">
</span><span class="com"># array([50, 50, 50], dtype=int64)</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">pie</span><span class="pun">(</span><span class="pln">x</span><span class="pun">=</span><span class="pln">values</span><span class="pun">,</span><span class="pln"> labels</span><span class="pun">=</span><span class="pln">labels</span><span class="pun">,</span><span class="pln"> autopct</span><span class="pun">=</span><span class="str">'%1.1f%%'</span><span class="pun">,</span><span class="pln"> shadow</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">,</span><span class="pln"> explode</span><span class="pun">=[</span><span class="lit">0.1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.1</span><span class="pun">])</span><span class="pln">

plt</span><span class="pun">.</span><span class="pln">title</span><span class="pun">(</span><span class="str">"Iris Species %"</span><span class="pun">)</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">show</span><span class="pun">()</span></pre>

<p>
	استخدمنا هنا الدالة<code>plt.pie()‎</code> لإنشاء الرسم البياني المطلوب ومررنا لها قائمة <code>x=values</code> تتضمن العدد في كل شريحة في الرسم البياني وقائمة أخرى <code>labels=labels</code> تتضمن وسم كل شريحة، وقد حصلنا على القيم ووسومها باستخدام <code>iris['Species'].value_counts()‎</code> فباستخدام التابع <code>index</code> نحصل على القيم الفهرسية أو المفتاحية وهي أسماء فصائل الأزهار وباستخدام التابع <code>values</code> نحصل على عدد كل فصيلة، بينما تحدد باقي العوامل بعض التأثيرات الجمالية مثل طريقة عرض الأرقام في الرسم البياني وإضافة ظل على الرسم، بينما القائمة الممررة للمعامل <code>explode</code> يعبر كل عنصر بها عن مقدار ابتعاد الشريحة عن المركز حيث تجعل القيمة 0.1 كل شريحة تبتعد عن المركز بمسافة قدرها 10% من طول نصف القطر ويمكنكم تجربة تغير هذه القيم وملاحظة التأثير الناتج.
</p>

<p>
	عند تنفيذ الكود سنحصل على الرسم البياني التالي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="170598" href="https://academy.hsoub.com/uploads/monthly_2025_04/Iris_pie.png.a4b258a42fb62a620cb92d1034af199d.png" rel=""><img alt="003 الرسم البياني الدائري Pie plot" class="ipsImage ipsImage_thumbnailed" data-fileid="170598" data-unique="jkqfgtg4l" style="width: 400px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_04/Iris_pie.thumb.png.18ee445325bbd710dee3a41b8f8d4108.png"> </a>
</p>

<h3 id="4scatterplot">
	رسم بياني للنقاط المبعثرة Scatter plot لسبلات الأزهار
</h3>

<p>
	سنرسم في هذا التطبيق رسم نقطي مبعثر يوضح العلاقة بين أبعاد السبلات أي بين طولها وعرضها.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_13_19" style=""><span class="kwd">import</span><span class="pln"> matplotlib</span><span class="pun">.</span><span class="pln">pyplot </span><span class="kwd">as</span><span class="pln"> plt
</span><span class="kwd">import</span><span class="pln"> seaborn </span><span class="kwd">as</span><span class="pln"> sns
iris </span><span class="pun">=</span><span class="pln"> pd</span><span class="pun">.</span><span class="pln">read_csv</span><span class="pun">(</span><span class="str">"iris.csv"</span><span class="pun">)</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">figure</span><span class="pun">(</span><span class="pln">figsize</span><span class="pun">=(</span><span class="lit">10</span><span class="pun">,</span><span class="lit">8</span><span class="pun">))</span><span class="pln">
</span><span class="com"># Plotting </span><span class="pln">
sns</span><span class="pun">.</span><span class="pln">scatterplot</span><span class="pun">(</span><span class="pln">data</span><span class="pun">=</span><span class="pln">iris</span><span class="pun">,</span><span class="pln"> x</span><span class="pun">=</span><span class="str">"SepalLengthCm"</span><span class="pun">,</span><span class="pln"> y</span><span class="pun">=</span><span class="str">"SepalWidthCm"</span><span class="pun">,</span><span class="pln"> hue</span><span class="pun">=</span><span class="str">"Species"</span><span class="pun">)</span><span class="pln">
</span><span class="com"># Titles </span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">xlabel</span><span class="pun">(</span><span class="str">"Sepal Length"</span><span class="pun">)</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">ylabel</span><span class="pun">(</span><span class="str">"Sepal Width"</span><span class="pun">)</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">title</span><span class="pun">(</span><span class="str">"Sepal Length VS Width"</span><span class="pun">)</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">show</span><span class="pun">()</span></pre>

<p>
	استخدمنا الدالة<code>sns.scatterplot()‎</code> لإنشاء رسم بياني للنقاط المبعثرة بين طول السبلة <code>SepalLengthCm</code> وعرض السبلة <code>SepalWidthCm</code> مع تلوين الفصائل المختلفة للأزهار وفقًا لتصنيفها باستخدام المعامل <code>hue</code> وضبطنا قيمته ليلون النقاط المبعثرة اعتمادًا على الوسوم <code>Species</code>، ثم استخدمنا مكتبة matplotlib لضبط إعدادات الرسم والعناوين.
</p>

<p>
	عند تنفيذ الكود سنحصل على الرسم البياني التالي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="170599" href="https://academy.hsoub.com/uploads/monthly_2025_04/Iris_scatter.png.634a49b50ed6a33d0c3da69dc681cf1a.png" rel=""><img alt="004 رسم بياني للنقاط المبعثرة" class="ipsImage ipsImage_thumbnailed" data-fileid="170599" data-unique="1999h80il" style="width: 400px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_04/Iris_scatter.thumb.png.57a7d8053c51face8736989aa17f37a2.png"> </a>
</p>

<h3 id="6histogramplot">
	رسم بياني للمدرّج التكراري Histogram Plot
</h3>

<p>
	سننشئ تطبيق يعرض رسم بياني من نوع Histogram ويوضح التوزيع لأبعاد كل من البتلات Petals والسبلات Sepals.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_13_22" style=""><span class="kwd">import</span><span class="pln"> pandas </span><span class="kwd">as</span><span class="pln"> pd
</span><span class="kwd">import</span><span class="pln"> matplotlib</span><span class="pun">.</span><span class="pln">pyplot </span><span class="kwd">as</span><span class="pln"> plt
iris </span><span class="pun">=</span><span class="pln"> pd</span><span class="pun">.</span><span class="pln">read_csv</span><span class="pun">(</span><span class="str">"iris.csv"</span><span class="pun">)</span><span class="pln">
</span><span class="com"># Drop id column</span><span class="pln">
new_data </span><span class="pun">=</span><span class="pln"> iris</span><span class="pun">.</span><span class="pln">drop</span><span class="pun">(</span><span class="str">'Id'</span><span class="pun">,</span><span class="pln">axis</span><span class="pun">=</span><span class="lit">1</span><span class="pun">)</span><span class="pln">
new_data</span><span class="pun">.</span><span class="pln">hist</span><span class="pun">(</span><span class="pln">edgecolor</span><span class="pun">=</span><span class="str">'black'</span><span class="pun">,</span><span class="pln"> linewidth</span><span class="pun">=</span><span class="lit">1.2</span><span class="pun">)</span><span class="pln">
</span><span class="com"># gcf() -&gt; get current figure </span><span class="pln">
fig</span><span class="pun">=</span><span class="pln">plt</span><span class="pun">.</span><span class="pln">gcf</span><span class="pun">()</span><span class="pln">
fig</span><span class="pun">.</span><span class="pln">set_size_inches</span><span class="pun">(</span><span class="lit">12</span><span class="pun">,</span><span class="lit">12</span><span class="pun">)</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">show</span><span class="pun">()</span></pre>

<p>
	استخدمنا التابع <code>new_data.hist</code> لإنشاء رسم بياني للمدرّج التكراري، حيث يوضح هذا النوع تكرار القيم في كل متغير، وضبطنا لون الحواف لكل شريط في الرسم البياني ليكون باللون الأسود باستخدام <code>edgecolor</code>، وعرض الحواف باستخدام <code>linewidth</code>،  واستخدامنا الدالة <code>plt.gcf</code> للحصول على الشكل البياني الحالي وتخزينه في الكائن <code>fig</code> حتى نتمكن من تعديله بحريّة. مثلًا يمكننا إعادة ضبط أبعاد الشكل البياني باستخدام الدالة <code>fig.set_size_inches(12,12)‎</code> وهي دالة تابعة للكائن <code>fig</code>، ثم عرضنا الرسم البياني على النحو التالي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="170601" href="https://academy.hsoub.com/uploads/monthly_2025_04/Iris_sepal_petal_dim_dist.png.dc90dfb6e894b8dde2bec4f271e46e05.png" rel=""><img alt="005 رسم بياني للمدرّج التكراري " class="ipsImage ipsImage_thumbnailed" data-fileid="170601" data-unique="4w9vt2d9a" style="width: 550px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_04/Iris_sepal_petal_dim_dist.thumb.png.85ad43ac27558a3969c64775262d4082.png"> </a>
</p>

<h3 id="7joinplot">
	رسم بياني مشترك Join Plot
</h3>

<p>
	سنكتب برنامج لإنشاء رسم بياني مشترك يصف توزيع كل متغير من متغيرات الأزهار بشكل منفرد ثم بشكل مشترك في نفس الرسمة البيانية.
</p>

<blockquote class="ipsQuote" data-ipsquote="">
	<div class="ipsQuote_citation">
		اقتباس
	</div>

	<p data-gramm="false">
		ملاحظة : الرسم البياني المشترك join plot هو رسم بياني يوضح علاقة متغيرين من خلال رسم توزيع كل منهما بشكل منفرد على المحور الذي يمثل ذلك المتغير، ومن ثم رسم العلاقة بينهما.
	</p>
</blockquote>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_13_25" style=""><span class="kwd">import</span><span class="pln"> pandas </span><span class="kwd">as</span><span class="pln"> pd
</span><span class="kwd">import</span><span class="pln"> seaborn </span><span class="kwd">as</span><span class="pln"> sns
</span><span class="kwd">import</span><span class="pln"> matplotlib</span><span class="pun">.</span><span class="pln">pyplot </span><span class="kwd">as</span><span class="pln"> plt
iris </span><span class="pun">=</span><span class="pln"> pd</span><span class="pun">.</span><span class="pln">read_csv</span><span class="pun">(</span><span class="str">"iris.csv"</span><span class="pun">)</span><span class="pln">
fig</span><span class="pun">=</span><span class="pln">sns</span><span class="pun">.</span><span class="pln">jointplot</span><span class="pun">(</span><span class="pln">x</span><span class="pun">=</span><span class="str">'SepalLengthCm'</span><span class="pun">,</span><span class="pln"> y</span><span class="pun">=</span><span class="str">'SepalWidthCm'</span><span class="pun">,</span><span class="pln"> data</span><span class="pun">=</span><span class="pln">iris</span><span class="pun">,</span><span class="pln"> color</span><span class="pun">=</span><span class="str">'skyblue'</span><span class="pun">)</span><span class="pln"> 
plt</span><span class="pun">.</span><span class="pln">show</span><span class="pun">()</span></pre>

<p>
	عند تنفيذ الكود سنحصل على الرسم البياني التالي:
</p>

<p>
	 
</p>

<p>
	ويمكننا إظهار مزيد من المعلومات باستخدام خاصية <code>hue</code> والتي تعطى لونًا مختلفًا لكل تصنيف.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_13_27" style=""><span class="pln">fig</span><span class="pun">=</span><span class="pln">sns</span><span class="pun">.</span><span class="pln">jointplot</span><span class="pun">(</span><span class="pln">x</span><span class="pun">=</span><span class="str">'SepalLengthCm'</span><span class="pun">,</span><span class="pln"> y</span><span class="pun">=</span><span class="str">'SepalWidthCm'</span><span class="pun">,</span><span class="pln"> data</span><span class="pun">=</span><span class="pln">iris</span><span class="pun">,</span><span class="pln"> color</span><span class="pun">=</span><span class="str">'skyblue'</span><span class="pun">,</span><span class="pln"> hue</span><span class="pun">=</span><span class="str">"Species"</span><span class="pun">)</span><span class="pln"> </span></pre>

<p>
	عند تنفيذ الكود سنحصل على الرسم البياني التالي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="170590" href="https://academy.hsoub.com/uploads/monthly_2025_04/Iris_jointplot_hue.png.81659f3e0c38cc741970920af67e0978.png" rel=""><img alt="iris jointplot hue" class="ipsImage ipsImage_thumbnailed" data-fileid="170590" data-unique="733kcgbu2" style="width: 400px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_04/Iris_jointplot_hue.png.81659f3e0c38cc741970920af67e0978.png"> </a>
</p>

<h3 id="13gridofplotsforpairsofvariables">
	شبكة رسومات بيانية لأزواج من المتغيرات
</h3>

<p>
	سنكتب برنامج بايثون لإنشاء رسم بياني يوضح العلاقة بين أزواج مختلفة من المتغيرات pairplot، وتحديد أي الفصائل يسهل تميزها عن الأخرى وفصلها.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_13_43" style=""><span class="com"># Import necessary modules</span><span class="pln">
</span><span class="kwd">import</span><span class="pln"> pandas </span><span class="kwd">as</span><span class="pln"> pd
</span><span class="kwd">import</span><span class="pln"> seaborn </span><span class="kwd">as</span><span class="pln"> sns
iris </span><span class="pun">=</span><span class="pln"> pd</span><span class="pun">.</span><span class="pln">read_csv</span><span class="pun">(</span><span class="str">"iris.csv"</span><span class="pun">)</span><span class="pln">
</span><span class="com">#Drop id column</span><span class="pln">
iris </span><span class="pun">=</span><span class="pln"> iris</span><span class="pun">.</span><span class="pln">drop</span><span class="pun">(</span><span class="str">'Id'</span><span class="pun">,</span><span class="pln">axis</span><span class="pun">=</span><span class="lit">1</span><span class="pun">)</span><span class="pln">
sns</span><span class="pun">.</span><span class="pln">pairplot</span><span class="pun">(</span><span class="pln">iris</span><span class="pun">,</span><span class="pln">hue</span><span class="pun">=</span><span class="str">'Species'</span><span class="pun">)</span></pre>

<p>
	تسمح لنا الدالة<code>sns.pairplot()‎</code> برسم العلاقة بين كل المتغيرات في مجموعة البيانات، حيث تقارن كل زوج من المتغيرات برسم بياني لتشكل مصفوفة متكاملة، يمكنك من خلالها ملاحظة العلاقة بين أي زوج من المتغيرات أو الخاصيات في مجموعة البيانات، ونمرر لهذه الدالة بشكل أساسي مجموعة البيانات <code>iris</code> وهذا كافٍ للحصول على نتيجة ولكن يمكننا إضافة المزيد من الألوان والأبعاد في مصفوفة الرسومات البيانية باستخدام معامل <code>hue</code> الذي يميز بين كل تصنيف في مجموعة البيانات بلون مميز في الرسم البياني، مما يسهّل علينا اكتشاف الأنماط المتعلقة بتصنيف محدد، حيث سنلاحظ أن أغلب النقاط التي تنتمي لتصنيف واحد أي لصنف واحد من الأزهار ستتجمع حول بعضها في بعض الأماكن في الرسم البياني.
</p>

<p>
	عند تنفيذ الكود سنحصل على الرسم البياني التالي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="170596" href="https://academy.hsoub.com/uploads/monthly_2025_04/Iris_pairplot.png.fa29873b0e27f428de6bf1a18683b047.png" rel=""><img alt="iris pairplot" class="ipsImage ipsImage_thumbnailed" data-fileid="170596" data-unique="li335e5l0" src="https://academy.hsoub.com/uploads/monthly_2025_04/Iris_pairplot.thumb.png.d8614a24afecb380a0a28c977bff6285.png"> </a>
</p>

<h3 id="14heatmap">
	الخريطة الحرارية Heat map
</h3>

<p>
	سنكتب برنامج بايثون لإيجاد الترابط Correlation بين المتغيرات في مجموعة بيانات آيرس، باستخدام خريطة حرارية Heatmap.
</p>

<p>
	نوجد أولاً مصفوفة الترابط Correlation Matrix
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_13_39" style=""><span class="kwd">import</span><span class="pln"> pandas </span><span class="kwd">as</span><span class="pln"> pd
</span><span class="kwd">import</span><span class="pln"> numpy </span><span class="kwd">as</span><span class="pln"> np
</span><span class="kwd">import</span><span class="pln"> matplotlib</span><span class="pun">.</span><span class="pln">pyplot </span><span class="kwd">as</span><span class="pln"> plt
</span><span class="kwd">import</span><span class="pln"> seaborn </span><span class="kwd">as</span><span class="pln"> sns

iris </span><span class="pun">=</span><span class="pln"> pd</span><span class="pun">.</span><span class="pln">read_csv</span><span class="pun">(</span><span class="str">"iris.csv"</span><span class="pun">)</span><span class="pln">
corr_matrix </span><span class="pun">=</span><span class="pln"> iris</span><span class="pun">.</span><span class="pln">drop</span><span class="pun">(</span><span class="pln">columns</span><span class="pun">=[</span><span class="str">"Id"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"Species"</span><span class="pun">]).</span><span class="pln">corr</span><span class="pun">()</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">corr_matrix</span><span class="pun">)</span></pre>

<p>
	عند تنفيذ الكود سنحصل على الخرج التالي:
</p>

<pre class="ipsCode">               SepalLengthCm  SepalWidthCm  PetalLengthCm  PetalWidthCm
SepalLengthCm       1.000000     -0.109369       0.871754      0.817954
SepalWidthCm       -0.109369      1.000000      -0.420516     -0.356544
PetalLengthCm       0.871754     -0.420516       1.000000      0.962757
PetalWidthCm        0.817954     -0.356544       0.962757      1.000000
</pre>

<p>
	بعدها، نرسم الخريطة الحرارية Heat Map المعبرة عن مصفوفة الترابط Correlation Matrix
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_13_41" style=""><span class="pln">sns</span><span class="pun">.</span><span class="pln">heatmap</span><span class="pun">(</span><span class="pln">corr_matrix</span><span class="pun">,</span><span class="pln"> annot</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">,</span><span class="pln"> cmap</span><span class="pun">=</span><span class="str">"Blues"</span><span class="pun">)</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">show</span><span class="pun">()</span><span class="pln"> </span></pre>

<p>
	عند تنفيذ الكود سنحصل على الرسم البياني التالي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="170586" href="https://academy.hsoub.com/uploads/monthly_2025_04/Iris_corr.png.9bfd2463c3cd3fa8b9e4ed0e3825013b.png" rel=""><img alt="iris corr" class="ipsImage ipsImage_thumbnailed" data-fileid="170586" data-unique="6rdo7le6g" src="https://academy.hsoub.com/uploads/monthly_2025_04/Iris_corr.png.9bfd2463c3cd3fa8b9e4ed0e3825013b.png"> </a>
</p>

<h3 id="17">
	الرسومات البيانية باللغة العربية
</h3>

<p>
	إذا حاولنا إنشاء رسم بياني للحصول على المعلومات الإحصائية العامة عن مجموعة بيانات آيرس، كما فعلنا في التطبيق الأول مع جعل العناوين باللغة العربية، سنلاحظ أن مكتبة Matplotlib لا توفر دعمًا جيدًا للغة العربية وتعرض الأحرف مبعثرة، وكذلك ستظهر كل كلمة معكوسة الاتجاه من اليسار إلى اليمين.
</p>

<p>
	<span id="cke_bm_3746S" style="display: none;"> </span>لنلاحظ نتيجة تنفيذ الكود التالي عند محاولة عرض العناوين العربية قبل استخدام المكتبات الخارجية:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_13_31" style=""><span class="pln">iris</span><span class="pun">.</span><span class="pln">describe</span><span class="pun">().</span><span class="pln">plot</span><span class="pun">(</span><span class="pln">kind </span><span class="pun">=</span><span class="pln"> </span><span class="str">"area"</span><span class="pun">,</span><span class="pln">fontsize</span><span class="pun">=</span><span class="lit">15</span><span class="pun">,</span><span class="pln"> figsize </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="lit">15</span><span class="pun">,</span><span class="lit">8</span><span class="pun">),</span><span class="pln"> table </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">False</span><span class="pun">,</span><span class="pln"> colormap</span><span class="pun">=</span><span class="str">"Accent"</span><span class="pun">)</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">xlabel</span><span class="pun">(</span><span class="str">'الاحصائيات'</span><span class="pun">,)</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">ylabel</span><span class="pun">(</span><span class="str">'القيمة'</span><span class="pun">)</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">title</span><span class="pun">(</span><span class="str">"معلومات احصائية عامة لمجموعة بيانات آيرس"</span><span class="pun">)</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">show</span><span class="pun">()</span></pre>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="170584" href="https://academy.hsoub.com/uploads/monthly_2025_04/Arabic_unrendered.png.6feff5b0725686a884555dbb6f657271.png" rel=""><img alt="حروف عربية متقطعة" class="ipsImage ipsImage_thumbnailed" data-fileid="170584" data-ratio="56.83" data-unique="9ku3031zh" style="width: 600px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_04/Arabic_unrendered.thumb.png.957b3bb4085a85bb17b32ec08f6447a4.png"></a>
</p>

<p>
	لتصحيح هذا الخطأ سنستخدم مكتبتين خارجيتين:
</p>

<ul>
	<li>
		مكتبة arabic_reshaper لحل مشكلة عدم اتصال الحروف ببعضها
	</li>
	<li>
		مكتبة python-bidi لحل مشكلة اتجاه الحروف المعكوس والسماح بدمج مناسب لنصوص عربية مع نصوص أجنبية
	</li>
</ul>

<p>
	نستخدم الأوامر التالية لتثبيت المكتبات:
</p>

<pre class="ipsCode" id="ips_uid_13_46">pip install arabic-reshaper 
pip install python-bidi </pre>

<p>
	الآن إذا حاولنا عرض العناوين العربية بعد استخدام المكتبات الخارجية كما يلي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_13_36" style=""><span class="kwd">import</span><span class="pln"> pandas </span><span class="kwd">as</span><span class="pln"> pd
</span><span class="kwd">import</span><span class="pln"> matplotlib</span><span class="pun">.</span><span class="pln">pyplot </span><span class="kwd">as</span><span class="pln"> plt
</span><span class="kwd">from</span><span class="pln"> bidi</span><span class="pun">.</span><span class="pln">algorithm </span><span class="kwd">import</span><span class="pln"> get_display
</span><span class="kwd">import</span><span class="pln"> arabic_reshaper
</span><span class="kwd">def</span><span class="pln"> arabic</span><span class="pun">(</span><span class="pln">txt</span><span class="pun">):</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> get_display</span><span class="pun">(</span><span class="pln">arabic_reshaper</span><span class="pun">.</span><span class="pln">reshape</span><span class="pun">(</span><span class="pln">txt</span><span class="pun">))</span><span class="pln">
iris </span><span class="pun">=</span><span class="pln"> pd</span><span class="pun">.</span><span class="pln">read_csv</span><span class="pun">(</span><span class="str">"iris.csv"</span><span class="pun">)</span><span class="pln">
iris</span><span class="pun">.</span><span class="pln">describe</span><span class="pun">().</span><span class="pln">plot</span><span class="pun">(</span><span class="pln">kind </span><span class="pun">=</span><span class="pln"> </span><span class="str">"area"</span><span class="pun">,</span><span class="pln">fontsize</span><span class="pun">=</span><span class="lit">16</span><span class="pun">,</span><span class="pln"> figsize </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="lit">15</span><span class="pun">,</span><span class="lit">8</span><span class="pun">),</span><span class="pln"> table </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">False</span><span class="pun">,</span><span class="pln"> colormap</span><span class="pun">=</span><span class="str">"Accent"</span><span class="pun">)</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">xlabel</span><span class="pun">(</span><span class="pln">arabic</span><span class="pun">(</span><span class="str">'الاحصائيات'</span><span class="pun">))</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">ylabel</span><span class="pun">(</span><span class="pln">arabic</span><span class="pun">(</span><span class="str">'القيمة'</span><span class="pun">))</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">title</span><span class="pun">(</span><span class="pln">arabic</span><span class="pun">(</span><span class="str">"معلومات احصائية عامة لمجموعة بيانات آيرس"</span><span class="pun">))</span><span class="pln">
plt</span><span class="pun">.</span><span class="pln">show</span><span class="pun">()</span></pre>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="170583" href="https://academy.hsoub.com/uploads/monthly_2025_04/Arabic_rendered.png.5c89d4e24e045454effd4d52ccba8234.png" rel=""><img alt="حل مشكلة الحروف العربية" class="ipsImage ipsImage_thumbnailed" data-fileid="170583" data-unique="ml24gg9ng" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_04/Arabic_rendered.thumb.png.06286440e8ffa8ecc7a3ae2dd1639625.png"> </a>
</p>

<h2 id="">
	الخاتمة
</h2>

<p>
	تعرفنا في هذا المقال على كيفية تمثيل البيانات بشكل مرئي من خلال أمثلة عملية متنوعة بمكتبة Scikit-Learn  والمكتبات المساعدة، وقد اكتفينا بعرض بعض أنواع فقط ونترك لكم استكشاف أنواع الرسومات المختلفة الأخرى والاستفادة منها في تمثيل البيانات وملاحظة الأنماط والعلاقات الموجودة بينها بسرعة وسهولة.
</p>

<p>
	ترجمة -وبتصرف- للجزء الثاني من مقال<a href="https://www.w3resource.com/machine-learning/scikit-learn/iris/" rel="external nofollow"> Python: Machine learning - Scikit-learn Exercises, Practice, Solution</a>
</p>

<h2 id="-1">
	اقرأ أيضًا
</h2>

<ul>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-%D8%AA%D8%AD%D9%84%D9%8A%D9%84-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-scikit-learn-%D9%85%D8%B9-pandas-r2554/" rel="">أساسيات تحليل البيانات باستخدام Scikit-Learn مع Pandas</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D9%85%D9%83%D8%AA%D8%A8%D8%A9-scikit-learn-%D9%88%D8%A3%D9%87%D9%85-%D8%AE%D9%88%D8%A7%D8%B1%D8%B2%D9%85%D9%8A%D8%A7%D8%AA%D9%87%D8%A7-r2485/" rel="">تعرف على مكتبة Scikit learn وأهم خوارزمياتها</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/general/%D8%AA%D8%AD%D9%84%D9%8A%D9%84-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA/" rel="">الدليل الشامل إلى تحليل البيانات Data Analysis</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A8%D9%86%D8%A7%D8%A1-%D9%85%D8%B5%D9%86%D9%81-%D8%A8%D8%A7%D9%84%D8%A7%D8%B9%D8%AA%D9%85%D8%A7%D8%AF-%D8%B9%D9%84%D9%89-%D8%B7%D8%B1%D9%82-%D8%AA%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%A2%D9%84%D8%A9-%D8%A8%D9%84%D8%BA%D8%A9-%D8%A7%D9%84%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D9%85%D9%83%D8%AA%D8%A8%D8%A9-scikit-learn-r1266/" rel="">بناء مصنف بالاعتماد على طرق تعلم الآلة بلغة البايثون باستخدام مكتبة Scikit-Learn</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A3%D9%81%D8%B6%D9%84-%D8%A3%D8%AF%D9%88%D8%A7%D8%AA-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-%D9%88%D8%AA%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%A2%D9%84%D8%A9-%D9%84%D9%84%D9%85%D8%B7%D9%88%D8%B1%D9%8A%D9%86-%D8%A7%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86-r2507/" rel="">أفضل أدوات الذكاء الاصطناعي وتعلم الآلة للمطورين المبتدئين</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">2553</guid><pubDate>Fri, 11 Apr 2025 13:00:00 +0000</pubDate></item><item><title>&#x627;&#x644;&#x62A;&#x641;&#x627;&#x639;&#x644; &#x645;&#x639; &#x631;&#x633;&#x627;&#x626;&#x644; WhatsApp &#x628;&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; &#x627;&#x644;&#x630;&#x643;&#x627;&#x621; &#x627;&#x644;&#x627;&#x635;&#x637;&#x646;&#x627;&#x639;&#x64A;</title><link>https://academy.hsoub.com/programming/artificial-intelligence/%D8%A7%D9%84%D8%AA%D9%81%D8%A7%D8%B9%D9%84-%D9%85%D8%B9-%D8%B1%D8%B3%D8%A7%D8%A6%D9%84-whatsapp-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-r2550/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2025_04/10.--------WhatsApp.png.f92afbe7a8566d19d969f659f82c7ff6.png" /></p>
<p>
	سنشرح في هذا المقال طريقة بناء أداة ذكية للبحث داخل محادثات واتساب الخاصة بنا بعد تخزينها على هيئة ملفات PDF، تساعدنا هذه الأداة على البحث في محادثاتنا الشخصية و الوصول إلى معلومات محددة فيها بسرعة وكفاءة.
</p>

<p>
	سنوضح خطوة بخطوة طريقة استخراج النصوص من المحادثات وتحليلها، ثم تقسيمها إلى أجزاء صغيرة وتحويلها إلى تمثيلات رقمية Embeddings باستخدام نماذج ذكاء اصطناعي متقدمة مفتوحة المصدر لمعالجة اللغة الطبيعية يمكنها فهم السياق اللغوي حيث سنعتمد في أداتنا على نموذج BERT الذي يوفر إصدارات تدعم اللغة العربية لفهم وتحليل النصوص، وعلى نموذج Qwen لتوليد النصوص والردود التفاعلية، كما سنعتمد على قاعدة بيانات FAISS لنخزن التمثيلات الرقيمة لنصوص المحادثات وتمكين البحث السريع فيها، ونستخدم تقنية التوليد المعزز بالاسترجاع RAG للمساعدة في العثور على المعلومات المهمة في هذه المحادثات كالبحث عن مواعيد الاجتماعات والحجوزات، وتحديثات المشاريع بسرعة دون البحث المطول في سجل المحادثات.
</p>

<p>
	أخيرًا، سنوضح كيفية إنشاء واجهة تفاعلية سهلة الاستخدام تتيح لنا البحث في المحادثات والتفاعل معها بأمان، دون الحاجة إلى رفع بياناته إلى أي خوادم خارجية، مما يضمن الحفاظ على الخصوصية.
</p>

<h2 id="">
	متطلبات العمل
</h2>

<p>
	أهم المتطلبات اللازمة لتنفيذ هذا المقال بنجاح:
</p>

<ul>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D9%85%D8%A7-%D9%87%D9%8A-%D9%85%D9%86%D8%B5%D8%A9-hugging-face-%D9%84%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-r2449/" rel="">الحصول على مفتاح الوصول Token لاستخدام واجهة برمجة التطبيقات <abbr title="Application Programming Interface | واجهة برمجية"><abbr title="Application Programming Interface | واجهة برمجية">API</abbr></abbr> الخاصة بمنصة Hugging Face</a>
	</li>
	<li>
		معرفة أساسية بلغة البرمجة بايثون
	</li>
	<li>
		تثبيت Python على الجهاز مع <a href="https://academy.hsoub.com/programming/python/%D9%85%D8%AD%D8%B1%D8%B1-%D8%A3%D9%83%D9%88%D8%A7%D8%AF-%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86/" rel="">محرر أكواد مناسب</a> مثل Jupyter Notebook أو Visual Studio Code
	</li>
</ul>

<h2 id="-1">
	خطوات التطبيق العملي
</h2>

<p>
	لنستعرض بالتفصيل خطوات التطبيق العملي لأداتنا الذكية للتفاعل مع رسائل واتساب.
</p>

<h3 id="1whatsapppdf">
	الخطوة 1: حفظ محادثات واتساب كملف PDF
</h3>

<p>
	في البداية، نحتاج إلى تصدير محادثات واتساب الخاصة بنا وحفظها بصيغة PDF لتسهيل تحليلها لاحقًا. يتيح تطبيق WhatsApp ميزة تصدير الدردشة، والتي تمكننا من حفظ المحادثات كنصوص. بعد نجاح عملية التصدير، سنحويل المحادثات إلى تنسيق PDF لاستخدامها في التطبيق.
</p>

<p>
	لتصدير المحادثة، نفتح المحادثة المطلوبة، ثم ننقر على قائمة الخيارات أعلى يسار الدردشة ونختار المزيد، ثم نقل الدردشة من القائمة، ونحدد خيار -بدون وسائط- لحفظ النصوص فقط.
</p>

<p style="text-align: center;">
	<img alt="001 نقل سجل المحادثة" class="ipsImage ipsImage_thumbnailed" data-fileid="170492" data-ratio="53.80" data-unique="6ob1xi26q" style="width: 500px; height: auto;" width="685" src="https://academy.hsoub.com/uploads/monthly_2025_04/00---.png.731f0c9cb96603cecf56c4bc2c28bd24.png">
</p>

<p>
	بعد ذلك، يمكن فتح الملف الناتج بصيغة txt في أي تطبيق محرر نصوص مثل Microsoft Word أو Google Docs وتحويله إلى تنسيق pdf.
</p>

<h3 id="2pdf">
	الخطوة 2: استخراج النصوص من ملف PDF
</h3>

<p>
	بعد حفظ محادثات واتساب بصيغة PDF، نحتاج إلى استخراج النصوص منها لمعالجتها وتحليلها. يمكننا تحقيق ذلك باستخدام مكتبة PyMuPDF مع LangChain، حيث تتيح لنا استخراج النصوص بسهولة من جميع صفحات ملف PDF على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_8755_10" style=""><span class="com"># تثبيت المكتبات اللازمة</span><span class="pln">
</span><span class="pun">!</span><span class="pln">pip install langchain_community 
</span><span class="pun">!</span><span class="pln">pip install pymupdf
</span><span class="com"># لتحميل الملف PyMuPDFLoader  استيراد</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> langchain</span><span class="pun">.</span><span class="pln">document_loaders </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">PyMuPDFLoader</span><span class="pln">
</span><span class="com"># PDF تحميل ملف  </span><span class="pln">
loader </span><span class="pun">=</span><span class="pln"> </span><span class="typ">PyMuPDFLoader</span><span class="pun">(</span><span class="str">"اسم الملف.pdf"</span><span class="pun">)</span><span class="pln">
</span><span class="com"># استخراج محتوى الملف</span><span class="pln">
pdf_text </span><span class="pun">=</span><span class="pln"> loader</span><span class="pun">.</span><span class="pln">load</span><span class="pun">()</span><span class="pln">  
</span><span class="com"># دمج النصوص المستخرجة من جميع الصفحات في متغير واحد</span><span class="pln">
text </span><span class="pun">=</span><span class="pln"> </span><span class="str">"  "</span><span class="pun">.</span><span class="pln">join</span><span class="pun">(</span><span class="pln">page</span><span class="pun">.</span><span class="pln">page_content </span><span class="kwd">for</span><span class="pln"> page </span><span class="kwd">in</span><span class="pln"> pdf_text</span><span class="pun">)</span></pre>

<p>
	يعمل الكود أعلاه على تثبيت المكتبات اللازمة وهي المكتبة <code>langchain_community</code> و <code>pymupdf</code> ثم يستخدم الصنف <code>PyMuPDFLoader</code> لتحميل ملف pdf واستخراج محتوياته، حيث يجمع النصوص من جميع صفحات الملف ويخزنها في المتغير <code>text</code> لاستخدامه لاحقًا في معالجة النصوص والبحث فيها.
</p>

<h3 id="3">
	الخطوة 3: تقسيم النصوص إلى أجزاء صغيرة
</h3>

<p>
	بعد استخراج النصوص من ملف pdf، سنحتاج إلى تقسيمها إلى أجزاء أصغر لتحسين كفاءة معالجتها وتحليلها. يساعد هذا التقسيم على تحسين أداء البحث والاسترجاع، كما يسهل على نماذج الذكاء الاصطناعي فهم البيانات بدقة أكبر. سنستخدم أداة CharacterTextSplitter من LangChain لتقسيم النص إلى مقاطع صغيرة بناءً على معايير مثل حجم الجزء، والفاصل بين الأجزاء، ومدى التداخل بينها.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_8755_12" style=""><span class="com"># استيراد أداة تقسيم النصوص</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> langchain</span><span class="pun">.</span><span class="pln">text_splitter </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">CharacterTextSplitter</span><span class="pln">
</span><span class="com"># إعداد معلمات تقسيم النصوص</span><span class="pln">
text_splitter </span><span class="pun">=</span><span class="pln"> </span><span class="typ">CharacterTextSplitter</span><span class="pun">(</span><span class="pln">
    separator</span><span class="pun">=</span><span class="str">"\n"</span><span class="pun">,</span><span class="pln">   
    chunk_size</span><span class="pun">=</span><span class="lit">500</span><span class="pun">,</span><span class="pln">          
    chunk_overlap</span><span class="pun">=</span><span class="lit">100</span><span class="pun">,</span><span class="pln">     
    length_function</span><span class="pun">=</span><span class="pln">len      
</span><span class="pun">)</span><span class="pln">
</span><span class="com"># تقسيم النص إلى أجزاء</span><span class="pln">
chunks </span><span class="pun">=</span><span class="pln"> text_splitter</span><span class="pun">.</span><span class="pln">split_text</span><span class="pun">(</span><span class="pln">text</span><span class="pun">)</span><span class="pln">
</span><span class="com"># طباعة عدد الأجزاء</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">f</span><span class="str">"عدد الأجزاء: {len(chunks)}"</span><span class="pun">)</span></pre>

<p>
	يقسم الكود السابق النص <code>text</code> لأجزاء صغيرة باستخدام الصنف <code>CharacterTextSplitter</code> من LangChain، حيث حددنا هنا الفاصل <code>separator</code> الذي يحدد أماكن تقسيم النص ليكون فاصل الأسطر <code>n\</code>، مع ضبط الحد الأقصى لحجم كل جزء من النص أو عدد الأحرف في كل مقطع <code>chunk_size</code> ليكون <code>500</code> وحددنا عدد الأحرف المتداخلة بين الأجزاء <code>chunk_overlap</code> بقيمة <code>100</code> لضمان الاحتفاظ بالسياق، واستخدمنا الدالة <code>length_function</code> لحساب طول كل جزء، ثم طباعة عدد الأجزاء الناتجة.
</p>

<h2 id="4embeddings">
	الخطوة 4: تحويل النصوص لتمثيلات رقمية Embeddings
</h2>

<p>
	بعد تقسيم النصوص إلى أجزاء صغيرة، نحتاج إلى تحويلها إلى تضمينات أو تمثيلات رقمية Embeddings لنساعد النموذج على فهم السياق والعلاقات بين الكلمات والجمل. تلعب هذه التمثيلات الرقمية Embeddings دورًا أساسيًا في تحسين البحث داخل النصوص وتسمح لنا باسترجاع المعلومات الأكثر صلة بالاستفسارات. 
</p>

<p>
	سنستخدم في هذه الخطوة مكتبة Sentence-Transformers لتحويل الأجزاء النصية إلى تمثيلات رقمية Embeddings. وسنختار نموذج <a href="https://arxiv.org/pdf/2003.00104v4" rel="external nofollow">AraBERT</a>، لأنه مُدّرب خصيصًا على اللغة العربية ويوفّر تمثيلات دقيقة للنصوص العربية ويهدف إلى تحسين أداء المهام اللغوية المختلفة باللغة العربية مثل تصنيف النصوص، وتحليل المشاعر، والترجمة الآلية، والتعرف على الكيانات المُسماة NER. ولكونه مدُرّبًا باستخدام مجموعة ضخمة من النصوص العربية، فهو قادر على فهم التراكيب النحوية والدلالية الخاصة بالعربية بكفاءة.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_8755_14" style=""><span class="com"># SentenceTransformer استيراد </span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> sentence_transformers </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">SentenceTransformer</span><span class="pln">
</span><span class="com"># تحميل نموذج يدعم العربية </span><span class="pln">
model </span><span class="pun">=</span><span class="pln"> </span><span class="typ">SentenceTransformer</span><span class="pun">(</span><span class="str">'aubmindlab/bert-base-arabertv02'</span><span class="pun">)</span><span class="pln">
</span><span class="com"># تحويل الأجزاء النصية إلى تمثيلات رقمية</span><span class="pln">
embeddings </span><span class="pun">=</span><span class="pln"> model</span><span class="pun">.</span><span class="pln">encode</span><span class="pun">(</span><span class="pln">chunks</span><span class="pun">,</span><span class="pln"> convert_to_tensor</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">)</span></pre>

<p>
	يعمل الكود على تحميل نموذج BERT الداعم للغة العربية، ثم يحوّل قائمة <code>chunks</code> التي تحتوي على الأجزاء النصية إلى تمثيلات رقمية Embedding Vectors مع تمكين تحويل النتائج إلى موترات أو تنسورات Tensors لتحسين الأداء في العمليات الحسابية، فالتعلمية <code>convert_to_tensor=True</code> تجعل الخرج كائنًا من نوع Tensor بدلًا من مصفوفة NumPy، مما يسهل التعامل معه عند استخدام مكتبات مثل <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D8%A5%D8%B7%D8%A7%D8%B1-%D8%B9%D9%85%D9%84-%D8%A8%D8%A7%D9%8A-%D8%AA%D9%88%D8%B1%D8%B4-pytorch-%D9%88%D8%A3%D9%87%D9%85%D9%8A%D8%AA%D9%87-%D9%84%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-r2311/" rel="">PyTorch</a>.
</p>

<h2 id="5faiss">
	الخطوة 5: بناء قاعدة بيانات للبحث السريع باستخدام FAISS
</h2>

<p>
	بعد تحويل النصوص إلى تمثيلات رقمية Embeddings، نحتاج إلى تخزينها بطريقة تتيح البحث السريع واسترجاع النصوص الأكثر تطابقًا مع استفسارات المستخدم. لتحقيق ذلك، سنستخدم مكتبة <a href="https://ai.meta.com/tools/faiss/" rel="external nofollow">FAISS</a> وهي اختصار لعبارة Facebook AI Similarity Search والتي تعد مكتبة قوية مفتوحة المصدر طورتها ميتا لتسهيل البحث السريع عن العناصر الأكثر تشابهًا داخل مجموعات بيانات ضخمة من المتجهات vectors.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_8755_16" style=""><span class="com"># FAISS تثبيت مكتبة </span><span class="pln">
pip install faiss</span><span class="pun">-</span><span class="pln">cpu
</span><span class="com"># استيراد المكتبات اللازمة</span><span class="pln">
</span><span class="kwd">import</span><span class="pln"> faiss
</span><span class="kwd">import</span><span class="pln"> numpy </span><span class="kwd">as</span><span class="pln"> np
</span><span class="com"># تحديد أبعاد التمثيلات الرقمية</span><span class="pln">
embedding_dim </span><span class="pun">=</span><span class="pln"> embeddings</span><span class="pun">.</span><span class="pln">shape</span><span class="pun">[</span><span class="lit">1</span><span class="pun">]</span><span class="pln">  
</span><span class="com"># إنشاء قاعدة البيانات</span><span class="pln">
index </span><span class="pun">=</span><span class="pln"> faiss</span><span class="pun">.</span><span class="typ">IndexFlatL2</span><span class="pun">(</span><span class="pln">embedding_dim</span><span class="pun">)</span><span class="pln">
</span><span class="com"># إضافة التمثيلات الرقمية إلى قاعدة البيانات</span><span class="pln">
index</span><span class="pun">.</span><span class="pln">add</span><span class="pun">(</span><span class="pln">np</span><span class="pun">.</span><span class="pln">array</span><span class="pun">(</span><span class="pln">embeddings</span><span class="pun">.</span><span class="pln">cpu</span><span class="pun">()))</span></pre>

<p>
	في هذا الكود ننشئ قاعدة بيانات باستخدام مكتبة FAISS، بهدف تنفيذ عمليات بحث فعّالة عن التشابه بين التمثيلات الرقمية، فبعد تثبيت المكتبة نستوردها إلى جانب استيراد المكتبة <code>numpy</code>. بعد ذلك، نحدد عدد أبعاد التمثيلات الرقمية <code>embedding_dim</code> الناتجة من النموذج وننشئ من خلال التعليمة <code>(faiss.IndexFlatL2(embedding_dim</code>فهرسًا أو قاعدة بيانات تستخدم مربع المسافة الإقليدية Squared Euclidean Distance لمقارنة التمثيلات والعثور على النصوص الأكثر تشابهًا ثم نضيف التمثيلات <code>embeddings</code> إلى قاعدة البيانات مع تحويلها لصيغة مصفوفة NumPy لاستخدامها في البحث السريع عن النصوص.
</p>

<h2 id="6rag">
	الخطوة 6: البحث عن المعلومات باستخدام RAG
</h2>

<p>
	بعد إنشاء قاعدة البيانات باستخدام FAISS، يمكننا الآن البحث داخل محادثات WhatsApp بطريقة ذكية باستخدام التوليد المعزز بالاسترجاع RAG. تساعد هذه التقنية على استرجاع النصوص الأكثر صلة بالاستفسار، مما يؤدي إلى توليد إجابات دقيقة بناءً على البيانات المخزنة.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_8755_18" style=""><span class="com"># دالة البحث عن المعلومات داخل قاعدة البيانات</span><span class="pln">
</span><span class="kwd">def</span><span class="pln"> search_query</span><span class="pun">(</span><span class="pln">query</span><span class="pun">,</span><span class="pln"> top_k</span><span class="pun">=</span><span class="lit">3</span><span class="pun">):</span><span class="pln">
    </span><span class="com"># تحويل الاستفسار إلى تمثيلات رقمية</span><span class="pln">
    query_embedding </span><span class="pun">=</span><span class="pln"> model</span><span class="pun">.</span><span class="pln">encode</span><span class="pun">([</span><span class="pln">query</span><span class="pun">],</span><span class="pln"> convert_to_tensor</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">).</span><span class="pln">cpu</span><span class="pun">().</span><span class="pln">numpy</span><span class="pun">()</span><span class="pln"> 
    </span><span class="com"># البحث عن أقرب النصوص في قاعدة البيانات </span><span class="pln">
    distances</span><span class="pun">,</span><span class="pln"> indices </span><span class="pun">=</span><span class="pln"> index</span><span class="pun">.</span><span class="pln">search</span><span class="pun">(</span><span class="pln">query_embedding</span><span class="pun">,</span><span class="pln"> top_k</span><span class="pun">)</span><span class="pln">
    </span><span class="com"># استرجاع النصوص الأكثر صلة بالاستفسار</span><span class="pln">
    results </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="pln">chunks</span><span class="pun">[</span><span class="pln">i</span><span class="pun">]</span><span class="pln"> </span><span class="kwd">for</span><span class="pln"> i </span><span class="kwd">in</span><span class="pln"> indices</span><span class="pun">[</span><span class="lit">0</span><span class="pun">]]</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> results
</span><span class="com"># مثال على البحث داخل المحادثات</span><span class="pln">
query </span><span class="pun">=</span><span class="pln"> </span><span class="str">"السؤال ؟"</span><span class="pln">
related_texts </span><span class="pun">=</span><span class="pln"> search_query</span><span class="pun">(</span><span class="pln">query</span><span class="pun">)</span><span class="pln">
</span><span class="com"># طباعة النتائج </span><span class="pln">
</span><span class="kwd">for</span><span class="pln"> text </span><span class="kwd">in</span><span class="pln"> related_texts</span><span class="pun">:</span><span class="pln">
    </span><span class="kwd">print</span><span class="pun">(</span><span class="pln">text</span><span class="pun">)</span></pre>

<p>
	يبحث هذا الكود عن النصوص الأكثر صلة بالاستفسار داخل قاعدة البيانات حيث يحول في البداية الاستفسار <code>query</code> إلى تمثيل رقمي. بعد ذلك، يبحث عن أقرب النصوص المخزنة في قاعدة البيانات بناءً على هذا التمثيل الرقمي. وأخيرًا، يعرض لنا أفضل ثلاث نتائج تتطابق مع الاستفسار وبهذا يمكننا العثور على المعلومات المطلوبة بسرعة من مجموعة كبيرة من النصوص.
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="170447" href="https://academy.hsoub.com/uploads/monthly_2025_04/01___.png.7e09e8cd192905aa608d63cd353b94cc.png" rel=""><img alt="01 التوليد المعزز  بالاسترجاع" class="ipsImage ipsImage_thumbnailed" data-fileid="170447" data-unique="1g6ldauxa" src="https://academy.hsoub.com/uploads/monthly_2025_04/01___.thumb.png.ade1534fac4b1c76884c13d56c33ea9c.png"></a>
</p>

<h2 id="7">
	الخطوة 7: توليد الإجابة باستخدام نموذج الذكاء الاصطناعي التوليدي
</h2>

<p>
	بعد استرجاع النصوص ذات الصلة من قاعدة البيانات، يمكننا الآن استخدام نموذج ذكاء اصطناعي توليدي لإنشاء إجابة دقيقة بناءً على الاستفسار والمعلومات المسترجعة من قاعدة البيانات. سنعتمد في هذه الخطوة على نموذج <a href="https://huggingface.co/Qwen" rel="external nofollow">Qwen</a> مفتوح المصدر والذي طورته شركة Alibaba Cloud، وتحديدًا فريق Alibaba DAMO Academy والذي يوفر إصدارات متنوعة بعدة أحجام مختلفة لتناسب مختلف المتطلبات والاحتياجات، بدءًا من النماذج الصغيرة التي يمكن تشغيلها على الأجهزة الشخصية، وصولًا إلى النماذج الضخمة المناسبة للخوادم والسحابة.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_8755_20" style=""><span class="kwd">import</span><span class="pln"> requests
</span><span class="com"># Hugging Face رابط واجهة النموذج على  </span><span class="pln">
API_URL </span><span class="pun">=</span><span class="pln"> </span><span class="str">"https://api-inference.huggingface.co/models/Qwen/Qwen2.5-Coder-32B-Instruct"</span><span class="pln">
</span><span class="com"># Hugging Face نستبدل المفتاح التالي بمفتاح من  </span><span class="pln">
headers </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{</span><span class="str">"Authorization"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"Bearer hf_XXXXXXXXXXXXXXXXXXXX"</span><span class="pun">}</span><span class="pln">
</span><span class="com"># إعداد الموجه</span><span class="pln">
prompt </span><span class="pun">=</span><span class="pln"> f</span><span class="str">"""
[SYSTEM]: أنت نموذج ذكاء اصطناعي متخصص في اللغة العربية.
سيتم إعطاؤك أسئلة مع معلومات ذات صلة.
مهمتك هي الإجابة عن الأسئلة بناءً على المعلومات المعطاة فقط.
[USER]: 
السؤال:
{query}
المعلومات المعطاة:
{related_texts}
[ASSISTANT]:
"""</span><span class="pln">
</span><span class="com"># دالة لإرسال الطلب إلى النموذج واستقبال الرد</span><span class="pln">
</span><span class="kwd">def</span><span class="pln"> query</span><span class="pun">(</span><span class="pln">payload</span><span class="pun">):</span><span class="pln">
    response </span><span class="pun">=</span><span class="pln"> requests</span><span class="pun">.</span><span class="pln">post</span><span class="pun">(</span><span class="pln">API_URL</span><span class="pun">,</span><span class="pln"> headers</span><span class="pun">=</span><span class="pln">headers</span><span class="pun">,</span><span class="pln"> json</span><span class="pun">=</span><span class="pln">payload</span><span class="pun">)</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> response</span><span class="pun">.</span><span class="pln">json</span><span class="pun">()</span><span class="pln">
</span><span class="com"># استدعاء الدالة للحصول على الاستجابة من النموذج</span><span class="pln">
output </span><span class="pun">=</span><span class="pln"> query</span><span class="pun">({</span><span class="str">"inputs"</span><span class="pun">:</span><span class="pln"> prompt</span><span class="pun">})</span><span class="pln">
</span><span class="com"># استخراج النص الناتج من الرد</span><span class="pln">
generated_answer </span><span class="pun">=</span><span class="pln"> output</span><span class="pun">[</span><span class="lit">0</span><span class="pun">][</span><span class="str">'generated_text'</span><span class="pun">].</span><span class="pln">split</span><span class="pun">(</span><span class="str">"[ASSISTANT]:"</span><span class="pun">)[</span><span class="lit">1</span><span class="pun">]</span><span class="pln">
</span><span class="com"># طباعة النتائج </span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">generated_answer</span><span class="pun">)</span></pre>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="170448" href="https://academy.hsoub.com/uploads/monthly_2025_04/02___.png.09652a6e28be5c415ecbe4138fcdd8f5.png" rel=""><img alt="02 نتيجة الطلب المرسل" class="ipsImage ipsImage_thumbnailed" data-fileid="170448" data-unique="rcfybt017" src="https://academy.hsoub.com/uploads/monthly_2025_04/02___.thumb.png.24cfd2e9ef2cfa0b90d7420343849c56.png"> </a>
</p>

<p>
	يتواصل الكود أعلاه مع نموذج Qwen عبر الواجهة البرمجية Hugging Face <abbr title="Application Programming Interface | واجهة برمجية"><abbr title="Application Programming Interface | واجهة برمجية">API</abbr></abbr> ويرسل موجه prompt للنموذج ليطلب منه الإجابة بناءً على المعلومات المعطاة فقط وكما نلاحظ يتضمن الموجه الأقسام <code>[SYSTEM]</code>و <code>[USER]</code> و <code>[ASSISTANT]</code> لتحديد أدوار المحادثة، بعد ذلك ينشئ دالة<code>query</code> لإرسال الطلب إلى النموذج وإرجاع نص يتضمن الإجابة المستندة إلى المعلومات المتوفرة فقط، دون إضافة أي بيانات خارجية وطباعتها.
</p>

<p>
	<strong>ملاحظة</strong>: تقسم المحادثة مع نموذج الذكاء الاصطناعي إلى ثلاثة أقسام وهي: <code>[SYSTEM]</code> لتحديد التعليمات والنظام، و <code>[USER]</code>لعرض السؤال والمعلومات المقدمة للنموذج، و <code>[ASSISTANT]</code>لتحديد المكان الذي يبدأ فيه النموذج بتوليد إجابته. وهذا يساعد على تنظيم الحوار وتوجيه النموذج بحيث يفصل بين السؤال والمعلومات والإجابة، مما يضمن أن يقتصر الرد على الجزء المطلوب دون الخلط مع باقي النص.
</p>

<h2 id="whatsapp-1">
	بناء أداة للتفاعل مع رسائل WhatsApp
</h2>

<p>
	بعد أن تعرفنا على الخطوات الأساسية للتفاعل مع نماذج الذكاء الاصطناعي،سنعمل الآن على تطوير أداة تفاعلية تعتمد على هذه النماذج لتحليل محادثات WhatsApp المخزنة في ملفات PDF، مما يتيح لنا البحث داخل محادثاتنا والحصول على إجابات ذكية بناءً على استفساراتنا. نبدأ بتحميل ملف PDF الخاص بالمحادثات، ثم استخراج النصوص باستخدام PyMuPDF، وتقسيمها إلى مقاطع صغيرة بواسطة CharacterTextSplitter لضمان تحليل دقيق. بعد ذلك، تحول النصوص إلى تمثيلات رقمية Embeddings باستخدام نموذج AraBERT المخصص للغة العربية، ثم تخزنها في قاعدة بيانات FAISS للبحث السريع عن النصوص ذات الصلة. عند إدخال استفسار، تعمل الأداة على البحث عن المقاطع الأكثر صلة بالاستفسار، داخل قاعدة البيانات، ثم ترسلها إلى نموذج Qwen لإنشاء إجابة ذكية تعتمد على البيانات المخزنة، ثم تعرضها عبر واجهة مستخدم تفاعلية مبنية باستخدام مكتبة بايثون تسمى Gradio وهي مكتبة مفتوحة المصدر لإنشاء واجهات مستخدم تفاعلية لنماذج التعلم الآلي والذكاء الاصطناعي تتيح لنا تصميم واجهات سهلة الاستخدام عبر متصفح الويب وتسهل علينا استفساراتنا والحصول على نتائج النموذج بشكل مباشر، دون الحاجة لكتابة أكواد معقدة.
</p>

<p>
	فيما يلي الكود الكامل لبناء واجهة مستخدم تفاعلية مبنية باستخدام مكتبة Gradio تسمح لنا بتحميل ملف pdf المتضمن لمحادثاتنا على الوتساب ومعالجته بنماذج الذكاء الاصطناعي والتفاعل معه وعرض النتيجة.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_8755_22" style=""><span class="kwd">import</span><span class="pln"> requests
</span><span class="kwd">import</span><span class="pln"> faiss
</span><span class="kwd">import</span><span class="pln"> numpy </span><span class="kwd">as</span><span class="pln"> np
</span><span class="kwd">import</span><span class="pln"> gradio </span><span class="kwd">as</span><span class="pln"> gr
</span><span class="kwd">from</span><span class="pln"> sentence_transformers </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">SentenceTransformer</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> langchain</span><span class="pun">.</span><span class="pln">document_loaders </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">PyMuPDFLoader</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> langchain</span><span class="pun">.</span><span class="pln">text_splitter </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">CharacterTextSplitter</span><span class="pln">

</span><span class="com"># تحميل نموذج تحويل النصوص إلى تمثيلات رقمية </span><span class="pln">
model </span><span class="pun">=</span><span class="pln"> </span><span class="typ">SentenceTransformer</span><span class="pun">(</span><span class="str">'aubmindlab/bert-base-arabertv02'</span><span class="pun">)</span><span class="pln">

</span><span class="com"># نموذج الذكاء الاصطناعي التوليدي</span><span class="pln">
API_URL </span><span class="pun">=</span><span class="pln"> </span><span class="str">"https://api-inference.huggingface.co/models/Qwen/Qwen2.5-Coder-32B-Instruct"</span><span class="pln">
</span><span class="com"># Hugging Face نستبدل المفتاح التالي بمفتاح من  </span><span class="pln">
headers </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{</span><span class="str">"Authorization"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"Bearer hf_XXXXXXXXXXXXXXXXXXXX"</span><span class="pun">}</span><span class="pln">

</span><span class="com"># دالة معالجة الملف وتحويله إلى تمثيلات رقمية</span><span class="pln">
</span><span class="kwd">def</span><span class="pln"> process_pdf</span><span class="pun">(</span><span class="pln">pdf_file</span><span class="pun">):</span><span class="pln">
    loader </span><span class="pun">=</span><span class="pln"> </span><span class="typ">PyMuPDFLoader</span><span class="pun">(</span><span class="pln">pdf_file</span><span class="pun">.</span><span class="pln">name</span><span class="pun">)</span><span class="pln">
    pages </span><span class="pun">=</span><span class="pln"> loader</span><span class="pun">.</span><span class="pln">load</span><span class="pun">()</span><span class="pln">

    text </span><span class="pun">=</span><span class="pln"> </span><span class="str">"\n"</span><span class="pun">.</span><span class="pln">join</span><span class="pun">([</span><span class="pln">page</span><span class="pun">.</span><span class="pln">page_content </span><span class="kwd">for</span><span class="pln"> page </span><span class="kwd">in</span><span class="pln"> pages</span><span class="pun">])</span><span class="pln">

    </span><span class="com"># تقسيم النص إلى أجزاء صغيرة</span><span class="pln">
    text_splitter </span><span class="pun">=</span><span class="pln"> </span><span class="typ">CharacterTextSplitter</span><span class="pun">(</span><span class="pln">separator</span><span class="pun">=</span><span class="str">"\n"</span><span class="pun">,</span><span class="pln"> chunk_size</span><span class="pun">=</span><span class="lit">500</span><span class="pun">,</span><span class="pln"> chunk_overlap</span><span class="pun">=</span><span class="lit">100</span><span class="pun">,</span><span class="pln"> length_function</span><span class="pun">=</span><span class="pln">len</span><span class="pun">)</span><span class="pln">
    chunks </span><span class="pun">=</span><span class="pln"> text_splitter</span><span class="pun">.</span><span class="pln">split_text</span><span class="pun">(</span><span class="pln">text</span><span class="pun">)</span><span class="pln">

    </span><span class="com"># تحويل الأجزاء إلى تمثيلات رقمية</span><span class="pln">
    embeddings </span><span class="pun">=</span><span class="pln"> model</span><span class="pun">.</span><span class="pln">encode</span><span class="pun">(</span><span class="pln">chunks</span><span class="pun">,</span><span class="pln"> convert_to_tensor</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">).</span><span class="pln">cpu</span><span class="pun">().</span><span class="pln">numpy</span><span class="pun">()</span><span class="pln">

    </span><span class="com"># إنشاء قاعدة بيانات </span><span class="pln">
    embedding_dim </span><span class="pun">=</span><span class="pln"> embeddings</span><span class="pun">.</span><span class="pln">shape</span><span class="pun">[</span><span class="lit">1</span><span class="pun">]</span><span class="pln">
    index </span><span class="pun">=</span><span class="pln"> faiss</span><span class="pun">.</span><span class="typ">IndexFlatL2</span><span class="pun">(</span><span class="pln">embedding_dim</span><span class="pun">)</span><span class="pln">
    index</span><span class="pun">.</span><span class="pln">add</span><span class="pun">(</span><span class="pln">embeddings</span><span class="pun">)</span><span class="pln">

    </span><span class="kwd">return</span><span class="pln"> index</span><span class="pun">,</span><span class="pln"> chunks

</span><span class="com"># دالة البحث داخل المحادثات</span><span class="pln">
</span><span class="kwd">def</span><span class="pln"> search_query</span><span class="pun">(</span><span class="pln">query</span><span class="pun">,</span><span class="pln"> index</span><span class="pun">,</span><span class="pln"> documents</span><span class="pun">,</span><span class="pln"> top_k</span><span class="pun">=</span><span class="lit">3</span><span class="pun">):</span><span class="pln">
    query_embedding </span><span class="pun">=</span><span class="pln"> model</span><span class="pun">.</span><span class="pln">encode</span><span class="pun">([</span><span class="pln">query</span><span class="pun">],</span><span class="pln"> convert_to_tensor</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">).</span><span class="pln">cpu</span><span class="pun">().</span><span class="pln">numpy</span><span class="pun">()</span><span class="pln">
    distances</span><span class="pun">,</span><span class="pln"> indices </span><span class="pun">=</span><span class="pln"> index</span><span class="pun">.</span><span class="pln">search</span><span class="pun">(</span><span class="pln">query_embedding</span><span class="pun">,</span><span class="pln"> top_k</span><span class="pun">)</span><span class="pln">
    results </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="pln">documents</span><span class="pun">[</span><span class="pln">i</span><span class="pun">]</span><span class="pln"> </span><span class="kwd">for</span><span class="pln"> i </span><span class="kwd">in</span><span class="pln"> indices</span><span class="pun">[</span><span class="lit">0</span><span class="pun">]]</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> results

</span><span class="com"># دالة استدعاء النموذج التوليدي</span><span class="pln">
</span><span class="kwd">def</span><span class="pln"> generate_answer</span><span class="pun">(</span><span class="pln">pdf_file</span><span class="pun">,</span><span class="pln"> query</span><span class="pun">):</span><span class="pln">
    index</span><span class="pun">,</span><span class="pln"> documents </span><span class="pun">=</span><span class="pln"> process_pdf</span><span class="pun">(</span><span class="pln">pdf_file</span><span class="pun">)</span><span class="pln">
    related_texts </span><span class="pun">=</span><span class="pln"> search_query</span><span class="pun">(</span><span class="pln">query</span><span class="pun">,</span><span class="pln"> index</span><span class="pun">,</span><span class="pln"> documents</span><span class="pun">)</span><span class="pln">

    prompt </span><span class="pun">=</span><span class="pln"> f</span><span class="str">"""
    [SYSTEM]: أنت نموذج ذكاء اصطناعي متخصص في اللغة العربية.
    سيتم إعطاؤك أسئلة مع معلومات ذات صلة.
    مهمتك هي الإجابة عن الأسئلة بناءً على المعلومات المعطاة فقط.

    [USER]: 
    السؤال:
    {query}

    المعلومات المعطاة:
    {related_texts}

    [ASSISTANT]:
    """</span><span class="pln">

    response </span><span class="pun">=</span><span class="pln"> requests</span><span class="pun">.</span><span class="pln">post</span><span class="pun">(</span><span class="pln">API_URL</span><span class="pun">,</span><span class="pln"> headers</span><span class="pun">=</span><span class="pln">headers</span><span class="pun">,</span><span class="pln"> json</span><span class="pun">={</span><span class="str">"inputs"</span><span class="pun">:</span><span class="pln"> prompt</span><span class="pun">})</span><span class="pln">
    output </span><span class="pun">=</span><span class="pln"> response</span><span class="pun">.</span><span class="pln">json</span><span class="pun">()</span><span class="pln">

    </span><span class="kwd">return</span><span class="pln"> output</span><span class="pun">[</span><span class="lit">0</span><span class="pun">][</span><span class="str">'generated_text'</span><span class="pun">].</span><span class="pln">split</span><span class="pun">(</span><span class="str">"[ASSISTANT]:"</span><span class="pun">)[</span><span class="lit">1</span><span class="pun">]</span><span class="pln">

</span><span class="com"># Gradio إنشاء واجهة تفاعلية باستخدام </span><span class="pln">
</span><span class="kwd">with</span><span class="pln"> gr</span><span class="pun">.</span><span class="typ">Blocks</span><span class="pun">()</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> app</span><span class="pun">:</span><span class="pln">
    gr</span><span class="pun">.</span><span class="typ">Markdown</span><span class="pun">(</span><span class="str">"# <span class="ipsEmoji">📂</span> WhatsApp أداة للتفاعل مع محادثات <span class="ipsEmoji">🔍</span>"</span><span class="pun">)</span><span class="pln">

    pdf_input </span><span class="pun">=</span><span class="pln"> gr</span><span class="pun">.</span><span class="typ">File</span><span class="pun">(</span><span class="pln">label</span><span class="pun">=</span><span class="str">"<span class="ipsEmoji">📄</span> PDF تحميل ملف المحادثة بصيغة "</span><span class="pun">)</span><span class="pln">
    user_input </span><span class="pun">=</span><span class="pln"> gr</span><span class="pun">.</span><span class="typ">Textbox</span><span class="pun">(</span><span class="pln">label</span><span class="pun">=</span><span class="str">"<span class="ipsEmoji">📝</span> أدخل سؤالك هنا"</span><span class="pun">)</span><span class="pln">
    search_button </span><span class="pun">=</span><span class="pln"> gr</span><span class="pun">.</span><span class="typ">Button</span><span class="pun">(</span><span class="str">"<span class="ipsEmoji">🔎</span> بحث وتحليل"</span><span class="pun">)</span><span class="pln">
    output_box </span><span class="pun">=</span><span class="pln"> gr</span><span class="pun">.</span><span class="typ">Textbox</span><span class="pun">(</span><span class="pln">label</span><span class="pun">=</span><span class="str">"<span class="ipsEmoji">🤖</span> الإجابة:"</span><span class="pun">)</span><span class="pln">

    search_button</span><span class="pun">.</span><span class="pln">click</span><span class="pun">(</span><span class="pln">generate_answer</span><span class="pun">,</span><span class="pln"> inputs</span><span class="pun">=[</span><span class="pln">pdf_input</span><span class="pun">,</span><span class="pln"> user_input</span><span class="pun">],</span><span class="pln"> outputs</span><span class="pun">=</span><span class="pln">output_box</span><span class="pun">)</span><span class="pln">
</span><span class="com"># تشغيل التطبيق</span><span class="pln">
app</span><span class="pun">.</span><span class="pln">launch</span><span class="pun">()</span></pre>

<p>
	إذا شغلنا الكود أعلاه سنحصل على النتيجة التالية:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="170449" href="https://academy.hsoub.com/uploads/monthly_2025_04/03__.png.30ad8373332aacc98e3aef7c4f7c6175.png" rel=""><img alt="03 أداة تفاعلية" class="ipsImage ipsImage_thumbnailed" data-fileid="170449" data-unique="atxgcq9ib" src="https://academy.hsoub.com/uploads/monthly_2025_04/03__.thumb.png.193f2201c0e2ff5e5431ac1ec4de7bfc.png"> </a>
</p>

<h2 id="-2">
	تطبيقات عملية للأداة
</h2>

<p>
	يمكننا الاستفادة من هذه الأداة الذكية في تطبيقات متعددة، لنستعرض بعضًا منها:
</p>

<h3 id="-3">
	استرجاع المواعيد والمهام المجدولة
</h3>

<p>
	يمكن استخدام هذه الأداة لاسترجاع المواعيد والمهام المجدولة داخل محادثات واتساب بسهولة، حيث يمكن البحث عن التواريخ أو الأحداث المهمة داخل محادثاتنا باستخدام استعلامات بسيطة، مما يسهل تنظيم المهام اليومية والوصول إلى المعلومات بسرعة دون الحاجة إلى التمرير يدويًا عبر المحادثات الطويلة. في المثال التالي، لدينا مجموعة لطلاب جامعيين، ونريد أن نعرف موعد الاختبار. يمكن ببساطة إدخال استعلام مثل:
</p>

<blockquote class="ipsQuote" data-ipsquote="">
	<div class="ipsQuote_citation">
		اقتباس
	</div>

	<p data-gramm="false">
		متى موعد الاختبار القادم؟ وستعمل الأداة على البحث داخل المحادثات المخزنة في ملف PDF لتحديد الرسائل التي تحتوي على معلومات ذات صلة، مثل التواريخ والتفاصيل المتعلقة بالاختبار، ثم تعرض الأجزاء الأكثر تطابقًا. بعد ذلك، ترسل هذه المعلومات إلى نموذج الذكاء الاصطناعي التوليدي، والذي سيرد بإجابة دقيقة استنادًا إلى البيانات المسترجعة.
	</p>
</blockquote>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="170450" href="https://academy.hsoub.com/uploads/monthly_2025_04/04__.png.86aa2cdaca7fc772d7f21745d6d917b6.png" rel=""><img alt="04 موعد الاختبار" class="ipsImage ipsImage_thumbnailed" data-fileid="170450" data-unique="cv9q1dlpv" src="https://academy.hsoub.com/uploads/monthly_2025_04/04__.png.86aa2cdaca7fc772d7f21745d6d917b6.png"> </a>
</p>

<h3 id="-4">
	البحث السريع عن المعلومات المهمة وتلخيص أهم المواضيع
</h3>

<p>
	تتيح لنا الأداة للمستخدمين البحث بسرعة عن المعلومات المهمة داخل محادثات WhatsApp المخزنة، بالإضافة إلى تلخيص أهم المواضيع التي تمت مناقشتها. فعند إدخال استعلام مثل:
</p>

<blockquote class="ipsQuote" data-ipsquote="">
	<div class="ipsQuote_citation">
		اقتباس
	</div>

	<p data-gramm="false">
		أريد أهم الأمور في هذه المحادثة؟ ستعمل الأداة على تحليل النصوص المستخرجة وتحديد النقاط البارزة مثل القرارات المهمة، والمهام، أو أي معلومات ذات صلة. ثم تلخص هذه المعلومات باستخدام نموذج الذكاء الاصطناعي التوليدي، مما يساعدنا على فهم محتوى المحادثة بشكل سريع دون الحاجة لقراءتها بالكامل. وهذه الميزة مفيدة خصوصًا عند التعامل مع محادثات طويلة أو مجموعات نشطة تحتوي على كميات كبيرة من الرسائل.
	</p>
</blockquote>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="170451" href="https://academy.hsoub.com/uploads/monthly_2025_04/05__.png.5a237769a6fdc7f5c6710a0641e39236.png" rel=""><img alt="05 محادثة طلاب" class="ipsImage ipsImage_thumbnailed" data-fileid="170451" data-unique="84g59hdhi" src="https://academy.hsoub.com/uploads/monthly_2025_04/05__.thumb.png.ff8446cd4cb8a87f80e9468e67466b83.png"> </a>
</p>

<h3 id="-5">
	البحث في المحادثات القانونية
</h3>

<p>
	تساعد هذه الأداة في البحث داخل المحادثات القانونية لاستخراج المعلومات المهمة بسرعة، مما يسهل على المستخدمين العثور على النصوص المتعلقة بالاستشارات القانونية السابقة دون الحاجة إلى البحث اليدوي. على سبيل المثال، إذا كان هناك محادثة مع محامٍ، وأراد المستخدم معرفة معلومة معينة مثل:
</p>

<blockquote class="ipsQuote" data-ipsquote="">
	<div class="ipsQuote_citation">
		اقتباس
	</div>

	<p data-gramm="false">
		هل يمكن للمستأجر إنهاء العقد إذا كانت هناك عيوب في العقار؟ يمكنه إدخال الاستفسار، وستعمل الأداة على تحليل المحادثات واسترجاع الإجابات القانونية ثم توليد الرد المناسب.
	</p>
</blockquote>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="170452" href="https://academy.hsoub.com/uploads/monthly_2025_04/06___.png.3a0fb7cbba9fbc028478ad7828785aed.png" rel=""><img alt="06 محادثة مع المحامي" class="ipsImage ipsImage_thumbnailed" data-fileid="170452" data-unique="op9ydnite" src="https://academy.hsoub.com/uploads/monthly_2025_04/06___.thumb.png.3a3ec09ec4047ebebe19cf268de1c541.png"> </a>
</p>

<h3 id="-6">
	البحث في المحادثات الطبية
</h3>

<p>
	يمكن استخدام هذه الأداة للبحث داخل المحادثات الطبية مع الأطباء أو الصيادلة لاستخراج المعلومات المهمة حول الأدوية والجرعات والإرشادات الطبية. على سبيل المثال، إذا أراد المستخدم معرفة:
</p>

<blockquote class="ipsQuote" data-ipsquote="">
	<div class="ipsQuote_citation">
		اقتباس
	</div>

	<p data-gramm="false">
		ما هي الجرعة التي يجب أن أتناولها من الدواء؟ يمكنه إدخال الاستفسار، وستعمل الأداة على تحليل المحادثات واسترجاع معلومات الجرعات والإرشادات الطبية وتوليد الإجابة المناسبة.
	</p>
</blockquote>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="170453" href="https://academy.hsoub.com/uploads/monthly_2025_04/07___.png.55a9424b1940c32006db4addfc5d8541.png" rel=""><img alt="07 محادثة مع الطبيب" class="ipsImage ipsImage_thumbnailed" data-fileid="170453" data-unique="xd80xuuur" src="https://academy.hsoub.com/uploads/monthly_2025_04/07___.png.55a9424b1940c32006db4addfc5d8541.png"> </a>
</p>

<h3 id="-7">
	البحث في محادثات العمل
</h3>

<p>
	تساعد هذه الأداة في البحث داخل محادثات العمل لاستخراج آخر التحديثات حول المشاريع والمهام الجارية. على سبيل المثال، إذا أراد المستخدم معرفة:
</p>

<blockquote class="ipsQuote" data-ipsquote="">
	<div class="ipsQuote_citation">
		اقتباس
	</div>

	<p data-gramm="false">
		ما هي المهام المتبقية في المشروع؟ يمكنه إدخال الاستفسار، وستعمل الأداة على تحليل المحادثات واسترجاع التحديثات وعرضها بشكل مختصر.
	</p>
</blockquote>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="170454" href="https://academy.hsoub.com/uploads/monthly_2025_04/08__.png.1529bc5173633c1ef23095469db95b2c.png" rel=""><img alt="08 محادثة عمل" class="ipsImage ipsImage_thumbnailed" data-fileid="170454" data-unique="scv9bhyq4" src="https://academy.hsoub.com/uploads/monthly_2025_04/08__.png.1529bc5173633c1ef23095469db95b2c.png"> </a>
</p>

<h2 id="-8">
	نصائح لتحسين وتطوير الأداة
</h2>

<p>
	دعونا نستعرض عدة أفكار لتحسين تطبيق التفاعل مع رسائل واتساب وتحسين نتائجه:
</p>

<h3 id="pdf">
	استخدام طرق أخرى لقراءة ملفات PDF
</h3>

<p>
	تواجه بعض المكتبات في لغة Python تحديات في التعامل مع النصوص باللغة العربية، حيث يمكن أن يحدث فقدان في الحروف أو التنسيق عند استخراج النصوص من ملفات PDF. لتحسين ذلك، يمكن تجربة مكتبات أخرى مثل pdfplumber أو PyPDF2 التي قد توفر دقة أكبر في استخراج النصوص العربية. بالإضافة إلى ذلك، يمكن دمج تقنيات التعرف على النصوص OCR في حالة الملفات التي تحتوي على صور نصية، مما يضمن استخراج النصوص بدقة أعلى.
</p>

<h3 id="embeddings">
	استخدام نماذج تضمين أفضل Embeddings
</h3>

<p>
	لتحسين دقة تمثيلات النصوص، يمكن استخدام نماذج تضمين Embeddings مختلفة، أو تحسين النموذج الحالي عبر التدريب المستمر باستخدام بيانات محلية. هذا سيساعد في تخصيص النموذج بشكل أفضل للمجال المطلوب، مما يعزز التفاعل مع النصوص العربية ويزيد من دقة استرجاع المعلومات.
</p>

<h3 id="-9">
	تجربة نماذج توليدية مختلفة
</h3>

<p>
	من أجل توليد إجابات دقيقة وواقعية، يمكن تجربة نماذج توليدية مختلفة مثل Llama أو GPT-3. كما يمكن النظر في استخدام نماذج متخصصة في مجالات معينة مثل الاستفسارات القانونية أو الاستشارات الطبية، لتحسين جودة الإجابات في تلك المجالات. تحسين إعدادات النماذج أو إعادة تدريبها باستخدام بيانات محلية سيسهم في تحسين الأداء العام.
</p>

<h3 id="whatsapp-2">
	تحميل رسائل WhatsApp بطريقة تلقائية
</h3>

<p>
	لتسريع عملية تحميل الرسائل، يمكن تطوير أداة تلقائية لتحميل المحادثات مباشرة من WhatsApp. يمكن أن توفر هذه الطريقة تحديثات مباشرة للمحادثات، مما يسهل الوصول إلى الملفات بسرعة ومرونة أكبر. كما يمكن أتمتة عملية التحميل بشكل دوري لضمان تحديث البيانات بشكل مستمر.
</p>

<h3 id="-10">
	ربط الأداة بأدوات أخرى
</h3>

<p>
	لزيادة فعالية الأداة، يمكن دمجها مع أدوات أخرى مثل أداة التذكير بالمواعيد أو أداة متابعة المهام. على سبيل المثال، يمكن ربط الأداة بتقويم شخصي لتنبيه المستخدم بشأن المواعيد أو الاجتماعات المستخلصة من المحادثات. كما يمكن دمج الأداة مع أنظمة إدارة المشاريع مثل Trello للاستفادة من الذكاء الاصطناعي في تتبع المهام والتحديثات، مما يعزز إنتاجية المستخدم ويسهل إدارة العمل بشكل متكامل.
</p>

<h2 id="-11">
	الخاتمة
</h2>

<p>
	في هذا المقال، استعرضنا كيفية بناء أداة ذكية تعتمد على الذكاء الاصطناعي لمعالجة وتحليل محادثات WhatsApp المخزنة في ملفات PDF، باستخدام تقنية التوليد المعزز بالاسترجاع RAG لاسترجاع المعلومات بدقة وتقديم إجابات فعالة. كما ناقشنا التطبيقات العملية للأداة في مجالات متنوعة، مثل الاستشارات القانونية وتحليل المحادثات الطبية، مما يبرز إمكانياتها في تحسين الوصول إلى المعلومات المهمة بسرعة وسهولة، كما استعرضنا طرقًا متعددة لتحسين الأداة، مثل تحسين استخراج النصوص من ملفات PDF باللغة العربية، وتجربة نماذج تضمين أكثر دقة، وتطوير حلول لتحميل المحادثات بشكل تلقائي. ندعوكم لتجربة تطوير أداة خاصة بكم تساعدكم على التفاعل مع بياناتكم الشخصية بأمان وفعالية، وتعزز إنتاجيتكم وتوفر وقتكم، ولو كان لديكم أية تساؤلات أو أفكار تطويرية على الأداة يمكنكم تركها في قسم التعليقات أسفل المقال.
</p>

<h2 id="-12">
	اقرأ أيضًا
</h2>

<ul>
	<li>
		<a href="https://academy.hsoub.com/programming/python/%D8%A8%D9%86%D8%A7%D8%A1-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82-%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-%D9%8A%D8%AC%D9%8A%D8%A8-%D8%B9%D9%84%D9%89-%D8%A3%D8%B3%D8%A6%D9%84%D8%A9-%D9%85%D9%84%D9%81-pdf-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-r2265/" rel="">بناء تطبيق بايثون يجيب على أسئلة ملف PDF باستخدام الذكاء الاصطناعي</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A8%D9%86%D8%A7%D8%A1-%D8%B1%D9%88%D8%A8%D9%88%D8%AA-%D8%AF%D8%B1%D8%AF%D8%B4%D8%A9-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-%D9%88-openai-api-r2483/" rel="">بناء روبوت دردشة باستخدام بايثون و OpenAI <abbr title="Application Programming Interface | واجهة برمجية"><abbr title="Application Programming Interface | واجهة برمجية">API</abbr></abbr></a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/sql/%D9%83%D8%AA%D8%A7%D8%A8%D8%A9-%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-sql-%D8%A8%D8%B3%D9%87%D9%88%D9%84%D8%A9-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-code-llama-r2537/" rel="">كتابة استعلامات SQL بسهولة باستخدام الذكاء الاصطناعي</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-code-llama-%D9%84%D9%83%D8%AA%D8%A7%D8%A8%D8%A9-%D9%88%D8%AA%D8%B5%D8%AD%D9%8A%D8%AD-%D8%A3%D9%83%D9%88%D8%A7%D8%AF-css-r2531/" rel="">استخدام نموذج الذكاء الاصطناعي Code Llama لكتابة وتصحيح أكواد CSS </a>
	</li>
</ul>
]]></description><guid isPermaLink="false">2550</guid><pubDate>Tue, 08 Apr 2025 15:00:00 +0000</pubDate></item><item><title>&#x623;&#x633;&#x627;&#x633;&#x64A;&#x627;&#x62A; &#x62A;&#x62D;&#x644;&#x64A;&#x644; &#x627;&#x644;&#x628;&#x64A;&#x627;&#x646;&#x627;&#x62A; &#x628;&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; Scikit-Learn &#x645;&#x639; Pandas</title><link>https://academy.hsoub.com/programming/artificial-intelligence/%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-%D8%AA%D8%AD%D9%84%D9%8A%D9%84-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-scikit-learn-%D9%85%D8%B9-pandas-r2554/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2025_04/001.Scikit-LearnPandas.png.717b9196014760996e31d655555a3a3d.png" /></p>
<p>
	نتناول في <a href="https://academy.hsoub.com/tags/%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA%20scikit%20learn/" rel="">هذه السلسلة</a> مجموعة متنوعة من التطبيقات العملية حول تعلم الآلة Machine Learning باستخدام إطار عمل ساي كيت ليرن Scikit-Learn الذي يوفر حزمة من الأدوات البرمجية مفتوحة المصدر تشمل خوارزميات تعلم الآلة كخوارزميات التصنيف Classification وتوقع الانحدار Regression وخوارزميات العنقدة Clustering، وقد صمم هذا الإطار ليعمل بكفاءة مع العديد من مكتبات بايثون القوية مثل NumPy و SciPy.
</p>

<p>
	الهدف من هذه السلسلة إرشاد المبتدئين من خلال مجموعة من التدريبات العملية المكتوبة بلغة بايثون وإطار عمل ساي كيت ليرن Scikit-Learn، فالتطبيق وحل التدريبات واحدة من أفضل طرق التعلم واكتساب المهارات لذا ننصح بمحاولة إيجاد الحل بأنفسكم قبل النظر في الأكواد المرفقة لتحقيق استفادة أفضل.
</p>

<h2 id="">
	ما هي مجموعة بيانات أزهار آيرس؟
</h2>

<p>
	سنستخدم في التطبيقات العملية مجموعة بيانات أزهار آيرس أو السوسن Iris dataset وهي مجموعة بيانات من عدة متغيرات استخدمت بواسطة عالم الإحصاء والأحياء رونالد فيشر في <a href="https://lgross.utk.edu/Math589Fall2020/RAFisher1936measurementsFlowerTaxa.pdf" rel="external nofollow">ورقته البحثية</a> لعام 1936، وهي تسمى أيضًا مجموعة بيانات اندرسون نسبة للعالم الذي جمعها ليحلل التغيرات الشكلية بين الفصائل الثلاث لهذه الأزهار.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="170634" href="https://academy.hsoub.com/uploads/monthly_2025_04/iris_flower_dataset.png.1a6e8619a5d625dd9ee6951930437864.png" rel=""><img alt="001 مجموعة بيانات iris flower " class="ipsImage ipsImage_thumbnailed" data-fileid="170634" data-ratio="37.57" data-unique="5kst0lkvx" style="width: 503px; height: auto;" width="503" src="https://academy.hsoub.com/uploads/monthly_2025_04/iris_flower_dataset.png.1a6e8619a5d625dd9ee6951930437864.png"> </a>
</p>

<p>
	تتكون مجموعة البيانات من 50 عينة لكل فصيلة من الفصائل الثلاثة للأزهار، وهي Iris setosa و Iris virginica و Iris versicolor وقيست أربعة خصائص لكل عينة وهي:
</p>

<ul>
	<li>
		طول البتلة Petal length
	</li>
	<li>
		عرض البتلة Petal width
	</li>
	<li>
		طول السبلة Sepal length
	</li>
	<li>
		عرض السبلة Sepal width 
	</li>
</ul>

<p>
	وباستخدام هذه التوليفة من الخصائص استطاع فيشر تطوير نموذج تميز خطي Linear discrimination قادر على التفريق بين الفصائل وبعضها.
</p>

<p style="text-align: center;">
	<img alt="002 سمات زهرة ايرس" class="ipsImage ipsImage_thumbnailed" data-fileid="170640" data-ratio="88.97" data-unique="561890b87" style="width: 399px; height: auto;" width="399" src="https://academy.hsoub.com/uploads/monthly_2025_04/754428670_.png.d5b67487d00ed0fe922608f18ab60298.png">
</p>

<h2 id="pandas">
	تطبيقات أساسية باستخدام مكتبة باندا Pandas
</h2>

<p>
	سنتعرف على مجموعة من التطبيقات التي تستخدم مكتبة باندا Pandas لتحليل واستكشاف مجموعة البيانات والتي تعد خطوة أساسية في أي <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AE%D8%B7%D9%88%D8%A7%D8%AA-%D8%AA%D9%86%D9%81%D9%8A%D8%B0-%D9%85%D8%B4%D8%B1%D9%88%D8%B9-%D8%B9%D9%86-%D8%AA%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%A2%D9%84%D8%A9-%D9%81%D9%8A-%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-%D8%A7%D9%84%D8%AC%D8%B2%D8%A1-%D8%A7%D9%84%D8%A3%D9%88%D9%84-r1357/" rel="">مشروع لتعلم الآلة</a>.
</p>

<h3 id="1pandasdataframe">
	تحميل مجموعة البيانات إلى إطار البيانات DataFrame
</h3>

<p>
	سنكتب برنامج بلغة برمجة بايثون لتحميل <a href="https://www.kaggle.com/datasets/uciml/iris" rel="external nofollow">مجموعة بيانات آيرس</a> من ملف csv إلى البنية  pandas  التي توفرها مكتبة dataframe ونطبع شكل البيانات ونوعها وأول ثلاثة صفوف منها.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_1606_11" style=""><span class="kwd">import</span><span class="pln"> pandas </span><span class="kwd">as</span><span class="pln"> pd
data </span><span class="pun">=</span><span class="pln"> pd</span><span class="pun">.</span><span class="pln">read_csv</span><span class="pun">(</span><span class="str">"iris.csv"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"Shape of the data:"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">data</span><span class="pun">.</span><span class="pln">shape</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"\nData Type:"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">type</span><span class="pun">(</span><span class="pln">data</span><span class="pun">))</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"\nFirst 3 rows:"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">data</span><span class="pun">.</span><span class="pln">head</span><span class="pun">(</span><span class="lit">3</span><span class="pun">))</span></pre>

<p>
	النمط DataFrame هو نمط توفره مكتبة pandas لتنظيم البيانات وتخزينها على هيئة جدول، وقد استوردنا في الكود السابق مكتبة pandas وقرأنا البيانات المطلوبة من الملف <code>iris.csv</code> وخزناها في متغير <code>data</code> من النمط DataFrame، ثم عرضنا عدد الأبعاد -أي عدد الصفوف والأعمدة الموجود في هذا الكائن- باستخدام التابع <code>shape</code> ونوع بياناته باستخدام التابع <code>type</code> وعرضنا أول 3 صفوف من البيانات فقط باستخدام التعليمة <code>data.head(3)‎</code>.
</p>

<p>
	عند تنفيذ الكود، نحصل على الخرج التالي:
</p>

<pre class="ipsCode">Shape of the data:
(150, 6)

Data Type:
&lt;class 'pandas.core.frame.DataFrame'&gt;

First 3 rows:
   Id  SepalLengthCm  SepalWidthCm  PetalLengthCm  PetalWidthCm      Species
0   1            5.1           3.5            1.4           0.2  Iris-setosa
1   2            4.9           3.0            1.4           0.2  Iris-setosa
2   3            4.7           3.2            1.3           0.2  Iris-setosa
</pre>

<h3 id="2">
	استعراض خصائص مجموعات بيانات آيرس
</h3>

<p>
	الآن، سكتب برنامج بايثون باستخدام ساي كيت ليرن Scikit-Learn لطباعة مفاتيح الأعمدة Keys وعدد الصفوف وعدد الأعمدة وأسماء الخاصيات والوصف لمجموعة بيانات آيرس.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_1606_13" style=""><span class="kwd">import</span><span class="pln"> pandas </span><span class="kwd">as</span><span class="pln"> pd
iris_data </span><span class="pun">=</span><span class="pln"> pd</span><span class="pun">.</span><span class="pln">read_csv</span><span class="pun">(</span><span class="str">"iris.csv"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"\nKeys of Iris dataset:"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">iris_data</span><span class="pun">.</span><span class="pln">keys</span><span class="pun">())</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"\nNumber of rows and columns of Iris dataset:"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">iris_data</span><span class="pun">.</span><span class="pln">shape</span><span class="pun">)</span><span class="pln"> </span></pre>

<p>
	استخدمنا هنا أيضًا بنية DataFrame كما في المثال السابق لتخزين البيانات ضمن متغير باسم <code>iris_data</code> وعرضنا المفاتيح أو أسماء الأعمدة في مجموعة البيانات باستخدام الدالة <code>iris_data.keys()‎</code> والتي تمثل المتغيرات أو الخصائص المختلفة بيانات الأزهار، وعرضنا أخيرًا عدد الصفوف والأعمدة باستخدام الدالة <code>iris_data.shape</code>.
</p>

<p>
	سنحصل على الخرج التالي من تنفيذ الكود أعلاه:
</p>

<pre class="ipsCode">Keys of Iris dataset:
Index(['Id', 'SepalLengthCm', 'SepalWidthCm', 'PetalLengthCm', 'PetalWidthCm',
       'Species'],
      dtype='object')

Number of rows and columns of Iris dataset:
(150, 6)
</pre>

<h3 id="3">
	عرض عدد العينات وعدد القيم المفقودة في مجموعة بيانات آيرس
</h3>

<p>
	فيما يلي كود بايثون لمعرفة عدد العينات في مجموعة بيانات الأزهار، وعدد القيم المفقودة فيها.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_1606_15" style=""><span class="kwd">import</span><span class="pln"> pandas </span><span class="kwd">as</span><span class="pln"> pd
iris </span><span class="pun">=</span><span class="pln"> pd</span><span class="pun">.</span><span class="pln">read_csv</span><span class="pun">(</span><span class="str">"iris.csv"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">iris</span><span class="pun">.</span><span class="pln">info</span><span class="pun">())</span></pre>

<p>
	استوردنا مجموعة البيانات بشكل بنية جدول DataFrame وخزناها في متغير باسم <code>iris</code> وطبعنا المعلومات التي نحتاجها باستخدام الدالة <code>iris.info()‎</code> التي تعرض بعض المعلومات المهمة مثل عدد العينات ونوع العمود الفهرسي Index column وكذلك عدد القيم الفعلية <code>non-null</code> ونوع البيانات لكل عمود، بالإضافة للذاكرة RAM المستهلكة لتخزين البيانات.
</p>

<p>
	نحصل على الخرج التالي من تنفيذ الكود أعلاه:
</p>

<pre class="ipsCode">&lt;class 'pandas.core.frame.DataFrame'&gt;
RangeIndex: 150 entries, 0 to 149
Data columns (total 6 columns):
 #   Column         Non-Null Count  Dtype  
---  ------         --------------  -----  
 0   Id             150 non-null    int64  
 1   SepalLengthCm  150 non-null    float64
 2   SepalWidthCm   150 non-null    float64
 3   PetalLengthCm  150 non-null    float64
 4   PetalWidthCm   150 non-null    float64
 5   Species        150 non-null    object 
dtypes: float64(4), int64(1), object(1)
memory usage: 7.2+ KB
None
</pre>

<h3 id="4densematricesdensematricesnumpyscipy">
	المصفوفات المتناثرة Dense Matrices والمصفوفات عالية الكثافة Dense Matrices باستخدام NumPy و Scipy
</h3>

<p>
	سنعمل في هذه الفقرة على إنشاء مصفوفة ثنائية الأبعاد 2D array مليئة بالواحد في كل عناصرها لواقعة على القطر الرئيسي والقيمة الصفر فيما دون ذلك، ثم نحول المصفوفة من نوع NumPy array إلى مصفوفة SciPy sparse matrix أي مصفوفة متناثرة بتنسيق CSR هو أحد تنسيقات مكتبة SciPy لتمثيل المصفوفات.
</p>

<p>
	وتعرف المصفوفة المتناثرة بأنها مصفوفة تحتوي في الغالب على أصفار Sparse matrix، وعلى النقيض تمامًا فإن المصفوفة الي يكون غالب عناصرها قيم لا تساوي الصفر تسمى  مصفوفة عالية الكثافة Dense matrix، ويعرف معدل التناثر sparsity على أنه عدد العناصر الصفرية مقسومة على إجمالي العناصر بالمصفوفة، ويساوي أيضًا 1 مطروحًا منه معدل الكثافة Density للمصفوفة، وباستخدام هذه التعريفات يمكننا تصنيف مصفوفة بأنها متناثرة sparse إن كان معدل تناثرها Sparsity أكبر من 0.5.
</p>

<p>
	تكمن فائدة تحويل المصفوفة من NumPy array إلى صيغة مصفوفة متناثرة الصفوف CSR باستخدام SciPy خطوة مفيدة وفعالة وتسرع الوصول إلى العناصر ذات القيمة الفعلية غير الصفرية داخل المصفوفة، حيث تتيح صيغة CSR تخزين المصفوفة بشكل مضغوط دون الحاجة إلى تخزين الأصفار، مما يقلل من استهلاك الذاكرة ويزيد من كفاءة المعالجة.
</p>

<p>
	تبرز أهمية هذا التحويل بشكل خاص عند إجراء عمليات رياضية أو تحليل بيانات على مصفوفات كبيرة، حيث يسهم تجاهل الأصفار في تسريع الحسابات دون التأثير على النتائج.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_1606_17" style=""><span class="kwd">import</span><span class="pln"> numpy </span><span class="kwd">as</span><span class="pln"> np
</span><span class="kwd">from</span><span class="pln"> scipy </span><span class="kwd">import</span><span class="pln"> sparse
eye </span><span class="pun">=</span><span class="pln"> np</span><span class="pun">.</span><span class="pln">eye</span><span class="pun">(</span><span class="lit">4</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"NumPy array:\n"</span><span class="pun">,</span><span class="pln"> eye</span><span class="pun">)</span><span class="pln">
sparse_matrix </span><span class="pun">=</span><span class="pln"> sparse</span><span class="pun">.</span><span class="pln">csr_matrix</span><span class="pun">(</span><span class="pln">eye</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"\nSciPy sparse CSR matrix:\n"</span><span class="pun">,</span><span class="pln"> sparse_matrix</span><span class="pun">)</span></pre>

<p>
	بعد أن استوردنا مكتبتي NumPy و SciPy استخدمنا الدالة <code>np.eye()‎</code> لإنشاء مصفوفة ثنائية الأبعاد تتكون جميع عناصرها من أصفار فيما عدا عناصر القطر الرئيسي للمصفوفة حيث تساوي عناصره الواحد، ومررنا للدالة العدد 4 وهو عدد الصفوف، وثم خزنا الناتج في الكائن <code>eye</code> وطبعنا المصفوفة التي يخزنها الكائن قبل أن تحويلها، واستخدمنا الدالة <code>sparse.csr_matrix(eye)‎</code> لتحويل المصفوفة للصيغة المضغوطة CSR، وطبعنا الكائن الذي يحتوي المصفوفة الجديدة لنقارن بين الصيغتين.
</p>

<p>
	سنحصل على الخرج التالي من تنفيذ الكود أعلاه:
</p>

<pre class="ipsCode">NumPy array:
 [[1. 0. 0. 0.]
 [0. 1. 0. 0.]
 [0. 0. 1. 0.]
 [0. 0. 0. 1.]]

SciPy sparse CSR matrix:
   (0, 0)    1.0
  (1, 1)    1.0
  (2, 2)    1.0
  (3, 3)    1.0
</pre>

<p>
	نلاحظ أن صيغة CSR لا تعرض كل عناصر المصفوفة، بل تُظهر العناصر التي تحتوي على أرقام غير صفرية فقط. وبما أن المصفوفة تحتوي على 1 في كل موقع قطري سنجد تساوي دليل الصف مع دليل العمود.
</p>

<h3 id="5pandas">
	عرض الاحصائيات الأساسية عن مجموعة بيانات آيرس باستخدام باندا Pandas
</h3>

<p>
	لعرض المعلومات الاحصائية الأساسية عن مجموعة البيانات مثل المتوسط والانحراف المعياري والتوزيع وغيرها من المعلومات نكتب الكود التالي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_1606_21" style=""><span class="kwd">import</span><span class="pln"> pandas </span><span class="kwd">as</span><span class="pln"> pd
data </span><span class="pun">=</span><span class="pln"> pd</span><span class="pun">.</span><span class="pln">read_csv</span><span class="pun">(</span><span class="str">"iris.csv"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">data</span><span class="pun">.</span><span class="pln">describe</span><span class="pun">())</span></pre>

<p>
	استخدمنا التابع <code>data.describe()‎</code> للحصول على إحصائيات عن الكائن <code>data</code> من نوع DataFrame، مثل عدد القيم count والمتوسط الحسابي mean والانحراف المعياري standard deviation والتوزيع المئوي percentiles وهي إحصائية تقيس الترتيب النسبي لموقع نقطة في مجموعة البيانات، فمثلًا عند قولنا أن التوزيع المئوي 25% يساوي 38.25 فهذا يعني أن 25% من القيم الموجودة في البيانات أقل من هذا العدد، وتوجد ثلاث توزيعات مئوية أساسية هي 25% و 50% و75% تمثل الأرباع Q1 و Q2 و Q3 على الترتيب، ويعرف Q2 خاصةً بالوسيط median وهو الرقم الوسيط بين مجموعة من القيم المرتبة، وتعرض أيضًا القيمة العظمى لكل عمود، ولا تأخذ هذه الدالة في الاعتبار القيم المفقودة <code>NAN</code>، ولا تعمل إلا على الأعمدة الرقمية Numerical.
</p>

<p>
	نحصل على الخرج التالي من تنفيذ الكود أعلاه:
</p>

<pre class="ipsCode">               Id  SepalLengthCm  SepalWidthCm  PetalLengthCm  PetalWidthCm
count  150.000000     150.000000    150.000000     150.000000    150.000000
mean    75.500000       5.843333      3.054000       3.758667      1.198667
std     43.445368       0.828066      0.433594       1.764420      0.763161
min      1.000000       4.300000      2.000000       1.000000      0.100000
25%     38.250000       5.100000      2.800000       1.600000      0.300000
50%     75.500000       5.800000      3.000000       4.350000      1.300000
75%    112.750000       6.400000      3.300000       5.100000      1.800000
max    150.000000       7.900000      4.400000       6.900000      2.500000
</pre>

<h3>
	معرفة عدد عينات كل نوع Categorical values باستخدام Pandas
</h3>

<p>
	لنحصل على عدد عينات كل فصيلة من الفصائل في مجموعة بيانات الأزهار نكتب الكود على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_1606_23" style=""><span class="kwd">import</span><span class="pln"> pandas </span><span class="kwd">as</span><span class="pln"> pd
data </span><span class="pun">=</span><span class="pln"> pd</span><span class="pun">.</span><span class="pln">read_csv</span><span class="pun">(</span><span class="str">"iris.csv"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"Observations of each species:"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">data</span><span class="pun">[</span><span class="str">'Species'</span><span class="pun">].</span><span class="pln">value_counts</span><span class="pun">())</span><span class="pln"> </span></pre>

<p>
	استخدمنا الدالة <code>value_counts()‎</code> على العمود <code>Species</code> الذي يحتوى وسمًا لكل عينة في مجموعة البيانات، تسمح هذه الدالة بالحصول على عدد العينات في كل تصنيف، بمعنى أخر سنعرف كم عينة تنتمي لكل فصيلة من الأزهار. سنحصل على الخرج التالي من تنفيذ الكود أعلاه:
</p>

<pre class="ipsCode">Observations of each species:
Iris-setosa        50
Iris-versicolor    50
Iris-virginica     50
Name: Species, dtype: int64
</pre>

<p>
	نلاحظ من الخرج السابق أن البيانات تحتوي على 150 زهرة موزعة بالتساوي على الفصائل الثلاثة.
</p>

<h3 id="7dataframepandas">
	حذف عمود من DataFrame باستخدام Pandas
</h3>

<p>
	لحذف عمود <code>Id</code> وطباعة أول خمسة صفوف حصلنا عليها بعد حذفه نكتب الكود التالي.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_1606_26" style=""><span class="kwd">import</span><span class="pln"> pandas </span><span class="kwd">as</span><span class="pln"> pd
data </span><span class="pun">=</span><span class="pln"> pd</span><span class="pun">.</span><span class="pln">read_csv</span><span class="pun">(</span><span class="str">"iris.csv"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"Original Data:"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">data</span><span class="pun">.</span><span class="pln">head</span><span class="pun">())</span><span class="pln">
new_data </span><span class="pun">=</span><span class="pln"> data</span><span class="pun">.</span><span class="pln">drop</span><span class="pun">(</span><span class="str">'Id'</span><span class="pun">,</span><span class="pln">axis</span><span class="pun">=</span><span class="lit">1</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"After removing id column:"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">new_data</span><span class="pun">.</span><span class="pln">head</span><span class="pun">())</span><span class="pln"> </span></pre>

<p>
	لحذف عمود من بنية DataFrame نستخدم الدالة <code>drop()‎</code> ونمرر لها اسم العمود المطلوب والمعامل <code>axis</code> وهو معامل يقبل قيمتين إما 0 وتعني أننا نريد حذف عمود، أو 1 والتي تعني أننا نريد حذف صف، ثم نستدعي <code>new_data.head()‎</code> لعرض أول خمسة صفوف من مجموعة البيانات الجديدة التي حصلنا عليها.
</p>

<p>
	سنحصل على الخرج التالي من تنفيذ الكود أعلاه:
</p>

<pre class="ipsCode">Original Data:
   Id  SepalLengthCm  SepalWidthCm  PetalLengthCm  PetalWidthCm      Species
0   1            5.1           3.5            1.4           0.2  Iris-setosa
1   2            4.9           3.0            1.4           0.2  Iris-setosa
2   3            4.7           3.2            1.3           0.2  Iris-setosa
3   4            4.6           3.1            1.5           0.2  Iris-setosa
4   5            5.0           3.6            1.4           0.2  Iris-setosa
After removing id column:
   SepalLengthCm  SepalWidthCm  PetalLengthCm  PetalWidthCm      Species
0            5.1           3.5            1.4           0.2  Iris-setosa
1            4.9           3.0            1.4           0.2  Iris-setosa
2            4.7           3.2            1.3           0.2  Iris-setosa
3            4.6           3.1            1.5           0.2  Iris-setosa
4            5.0           3.6            1.4           0.2  Iris-setosa
</pre>

<h3 id="8panda">
	اختيار شرائح معينة من مجموعة البيانات باستخدام Panda
</h3>

<p>
	للوصول إلى أول أربع خلايا من كل صف في مجموعة البيانات المخزنة في بنية DataFrame واستخدم أسماء الأعمدة بالإضافة للفهرس للوصول للخلايا المحددة سنكتب كود بايثون التالي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_1606_28" style=""><span class="kwd">import</span><span class="pln"> pandas </span><span class="kwd">as</span><span class="pln"> pd
data </span><span class="pun">=</span><span class="pln"> pd</span><span class="pun">.</span><span class="pln">read_csv</span><span class="pun">(</span><span class="str">"iris.csv"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"Original Data:"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">data</span><span class="pun">.</span><span class="pln">head</span><span class="pun">())</span><span class="pln">
new_data </span><span class="pun">=</span><span class="pln"> data</span><span class="pun">.</span><span class="pln">drop</span><span class="pun">(</span><span class="str">'Id'</span><span class="pun">,</span><span class="pln">axis</span><span class="pun">=</span><span class="lit">1</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"After removing id column:"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">new_data</span><span class="pun">.</span><span class="pln">head</span><span class="pun">())</span><span class="pln">
x </span><span class="pun">=</span><span class="pln"> data</span><span class="pun">.</span><span class="pln">iloc</span><span class="pun">[:,</span><span class="pln"> </span><span class="pun">[</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="lit">4</span><span class="pun">]].</span><span class="pln">values
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">x</span><span class="pun">)</span><span class="pln"> </span></pre>

<p>
	يسمح لنا التابع <code>data.iloc[]‎</code> باختيار شريحة معينة من مجموعة البيانات، حيث نحدد قبل الفاصلة الأولى الصفوف التي نريد أن تدخل في الاختيار، وبعد الفاصلة الأعمدة التي نريد أن تدخل في الاختيار، وفي حالتنا اخترنا عرض قيم جميع الصفوف باستخدام الرمز <code>:</code> والموجودة في أعمدة محددة <code>[1,2,3,4]</code>.
</p>

<p>
	سنحصل على الخرج التالي من تنفيذ الكود أعلاه:
</p>

<pre class="ipsCode">Original Data:
   Id  SepalLengthCm  SepalWidthCm  PetalLengthCm  PetalWidthCm      Species
0   1            5.1           3.5            1.4           0.2  Iris-setosa
1   2            4.9           3.0            1.4           0.2  Iris-setosa
2   3            4.7           3.2            1.3           0.2  Iris-setosa
3   4            4.6           3.1            1.5           0.2  Iris-setosa
4   5            5.0           3.6            1.4           0.2  Iris-setosa
After removing id column:
   SepalLengthCm  SepalWidthCm  PetalLengthCm  PetalWidthCm      Species
0            5.1           3.5            1.4           0.2  Iris-setosa
1            4.9           3.0            1.4           0.2  Iris-setosa
2            4.7           3.2            1.3           0.2  Iris-setosa
3            4.6           3.1            1.5           0.2  Iris-setosa
4            5.0           3.6            1.4           0.2  Iris-setosa
[[5.1 3.5 1.4 0.2]
 [4.9 3.  1.4 0.2]
 [4.7 3.2 1.3 0.2]
 [4.6 3.1 1.5 0.2]
 [5.  3.6 1.4 0.2]
 … 
 [6.7 3.  5.2 2.3]
 [6.3 2.5 5.  1.9]
 [6.5 3.  5.2 2. ]
 [6.2 3.4 5.4 2.3]
 [5.9 3.  5.1 1.8]]
</pre>

<h2 id="-1">
	الخاتمة
</h2>

<p>
	استكشفنا في هذه المجموعة من التدريبات مجموعة بيانات آيرس، وتعرفنا على خواصها والمعلومات الإحصائية الأساسية عنها، واستعرضنا تطبيقات عملية للتعامل مع بنية DataFrame لتخزين البيانات وتعديلها بطرق مختلفة، يمكن تجربة المزيد من الأكواد لاستكشاف هذه البيانات والتعرف عليها بشكل جيد قبل الانتقال <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A7%D9%84%D8%AA%D9%85%D8%AB%D9%8A%D9%84-%D8%A7%D9%84%D9%85%D8%B1%D8%A6%D9%8A-%D9%84%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-scikit-learn-%D9%85%D8%B9-matplotlib-%D9%88-seaborn-r2553/" rel="">للمقالة القادمة</a> التي سنتدرب بها على إنشاء الرسومات البيانية لفهم العلاقات بين خواص مجموعة بيانات آيرس بشكلٍ مرئي.
</p>

<h2 id="-2">
	اقرأ أيضًا
</h2>

<ul>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A8%D9%86%D8%A7%D8%A1-%D9%85%D8%B5%D9%86%D9%81-%D8%A8%D8%A7%D9%84%D8%A7%D8%B9%D8%AA%D9%85%D8%A7%D8%AF-%D8%B9%D9%84%D9%89-%D8%B7%D8%B1%D9%82-%D8%AA%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%A2%D9%84%D8%A9-%D8%A8%D9%84%D8%BA%D8%A9-%D8%A7%D9%84%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D9%85%D9%83%D8%AA%D8%A8%D8%A9-scikit-learn-r1266/" rel="">بناء مصنف بالاعتماد على طرق تعلم الآلة بلغة البايثون باستخدام مكتبة Scikit-Learn</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AE%D8%B7%D9%88%D8%A7%D8%AA-%D8%AA%D9%86%D9%81%D9%8A%D8%B0-%D9%85%D8%B4%D8%B1%D9%88%D8%B9-%D8%B9%D9%86-%D8%AA%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%A2%D9%84%D8%A9-%D9%81%D9%8A-%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-%D8%A7%D9%84%D8%AC%D8%B2%D8%A1-%D8%A7%D9%84%D8%A3%D9%88%D9%84-r1357/" rel="">خطوات تنفيذ مشروع عن تعلم الآلة في بايثون: الجزء الأول</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A8%D9%86%D8%A7%D8%A1-%D9%85%D8%B5%D9%86%D9%81-%D8%A8%D8%A7%D9%84%D8%A7%D8%B9%D8%AA%D9%85%D8%A7%D8%AF-%D8%B9%D9%84%D9%89-%D8%B7%D8%B1%D9%82-%D8%AA%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%A2%D9%84%D8%A9-%D8%A8%D9%84%D8%BA%D8%A9-%D8%A7%D9%84%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D9%85%D9%83%D8%AA%D8%A8%D8%A9-scikit-learn-r1266/" rel="">خطوات تنفيذ مشروع عن تعلم الآلة في بايثون: الجزء الثاني</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AE%D8%B7%D9%88%D8%A7%D8%AA-%D8%AA%D9%86%D9%81%D9%8A%D8%B0-%D9%85%D8%B4%D8%B1%D9%88%D8%B9-%D8%B9%D9%86-%D8%AA%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%A2%D9%84%D8%A9-%D9%81%D9%8A-%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-%D8%A7%D9%84%D8%AC%D8%B2%D8%A1-%D8%A7%D9%84%D8%AB%D8%A7%D9%84%D8%AB-r1359/" rel="">خطوات تنفيذ مشروع عن تعلم الآلة في بايثون: الجزء الثالث</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">2554</guid><pubDate>Fri, 04 Apr 2025 15:00:00 +0000</pubDate></item><item><title>&#x645;&#x641;&#x627;&#x647;&#x64A;&#x645; &#x623;&#x633;&#x627;&#x633;&#x64A;&#x629; &#x644;&#x644;&#x62A;&#x639;&#x627;&#x645;&#x644; &#x645;&#x639; &#x628;&#x627;&#x64A; &#x62A;&#x648;&#x631;&#x634; PyTorch</title><link>https://academy.hsoub.com/programming/artificial-intelligence/%D9%85%D9%81%D8%A7%D9%87%D9%8A%D9%85-%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A9-%D9%84%D9%84%D8%AA%D8%B9%D8%A7%D9%85%D9%84-%D9%85%D8%B9-%D8%A8%D8%A7%D9%8A-%D8%AA%D9%88%D8%B1%D8%B4-pytorch-r2540/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2025_03/970917259_.jpg.170a4a0a6c7e3f895615b0ef3043b74b.jpg" /></p>
<p>
	يعد باي تورش PyTorch أحد أشهر أطر عمل التعلم العميق Deep Learning، فهو الخيار الأول للباحثين في هذا المجال، وتزداد باستمرار أعداد الشركات ومراكز الأبحاث التي تتبنى استخدامه نظرًا لمرونته الكبيرة التي تساعد على تنفيذ الأفكار المختلفة.
</p>

<p>
	سنتعرف في هذه المقالة على مفاهيم أساسية في إطار عمل باي تورش PyTorch مثل مفهوم التفاضل التلقائي automatic differentiation، ومفهوم المخططات الرسومية الحسابية computation graphs، وكيفية تحقيق الاستفادة العظمى من المكتبات والأدوات التي يوفرها باي تورش واستخدامها لتطبيق هذه المفاهيم.
</p>

<h2 id="">
	المتطلبات السابقة
</h2>

<p>
	يتطلب فهم هذه المقالة توفر الإلمام بالمواضيع التالية:
</p>

<ol>
	<li>
		معرفة ب<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D9%85%D8%A7-%D9%87%D9%88-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A/" rel="">أساسيات الذكاء الاصطناعي</a> و<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AF%D9%84%D9%8A%D9%84-%D8%A7%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86-%D9%84%D9%81%D9%87%D9%85-%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-%D8%A7%D9%84%D8%AA%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%B9%D9%85%D9%8A%D9%82-r1422/" rel="">التعلم العميق</a>
	</li>
	<li>
		فهم قاعدة التسلسل chain rule، وهي صيغة رياضية مستخدمة في تدريب نماذج التعلم العميق
	</li>
	<li>
		تنزيل إطار عمل باي تورش على الجهاز المحلي لتجربة الأكواد والأمثلة العملية
	</li>
</ol>

<h2 id="automaticdifferentiation">
	التفاضل التلقائي Automatic Differentiation
</h2>

<p>
	قبل مناقشة الهياكل الأساسية المستخدمة في باي تورش، سنوضح بداية مفهوم التفاضل التلقائي automatic differentiation -أو autograd اختصارًا- ودوره في التعلم العميق، فعملية حساب المشتقات أساسية في مجال التعلم العميق لدورها في تحسين أداء الشبكات العصبية. لكن تعقيدها يتزايد مع تعقيد النماذج، لذا طُورت تقنيات متقدمة مثل التفاضل التلقائي للتعامل مع هذا الأمر بكفاءة عالية. 
</p>

<p>
	تعمل هذه التقنية -كما سنشرح لاحقًا- على إنشاء رسم بياني حسابي يتتبع العلاقات بين المتغيرات، مما يسمح بحساب المشتقات بشكل تلقائي ودقيق عبر طبقات الشبكة العصبية. حيث تحتوي الشبكات العصبية على ملايين المعاملات والأوزان التي تحتاج لتعلمها من خلال التدريب، وخلال عملية  التدريب سنحتاج لحساب المشتقات Derivatives لمعرفة كيفية تحديث هذه المعاملات بما يضمن تحسين أداء النموذج.
</p>

<p>
	فالتفاضل التلقائي هو العمود الفقري لإطار عمل باي تورش PyTorch ولجميع مكتبات وأطر التعلم العميق، ويساعدنا محرك التفاضل التلقائي المدمج في باي تورش PyTorch والمعروف أيضًا بمحرك  Autograd في فهم آلية عمل التفاضل التلقائي والأساس الذي بنيت عليه أطر عمل الذكاء الاصطناعي.
</p>

<p>
	تمتلك معماريات الشبكات العصبية ملايين المعاملات parameters القابلة للتعلم، وتمر عملية تدريب أي شبكة عصبية بمرحلتين وهما:
</p>

<ol>
	<li>
		مرحلة الانتشار الأمامي Forward pass التي تحسب قيمة الخسارة باستخدام دالة خسارة loss function
	</li>
	<li>
		مرحلة الانتشار الخلفي Backward pass التي يحسب قيم التدرجات gradients لتحديث المعاملات القابلة للتعلم
	</li>
</ol>

<p>
	يكون الانتشار الأمامي forward pass في غاية البساطة، فالمخرجات للطبقة الحالية هي مدخلات الطبقة التالية ويستمر هذا النمط في التكرار، ولكن الانتشار الخلفي backward pass أكثر تعقيدًا من الناحية الحسابية، فهو يتطلب استخدام قاعدة السلسلة التفاضلية chain rule من أجل حساب التدرجات بالنسبة لمعاملات دالة الخسارة loss function، بمعنى أبسط تُخبرنا التدرجات بكيفية تعديل الأوزان والمعاملات في الشبكة العصبية لتقليل الخسارة.
</p>

<blockquote class="ipsQuote" data-ipsquote="">
	<div class="ipsQuote_citation">
		اقتباس
	</div>

	<p data-gramm="false">
		التدرج gradient ∇ هو رمز لعملية رياضية تفاضلية مثل حرف d المستخدم في عملية التفاضل أو ∂ المستخدم للتفاضل الجزئي، ويختلف في كونه يجري تفاضل متجه vector مكون من عدة عناصر، حيث نشتق كل عنصر في هذه المتجه بالنسبة للبعد أو المحور الذي يمثله، وبالتالي دخل هذه العملية متجه وخرجها متجه.
	</p>
</blockquote>

<h2 style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="169712" href="https://academy.hsoub.com/uploads/monthly_2025_03/gradient_eq.jpg.a4a342696fd80b51c911cba4b6ea5cd8.jpg" rel=""><img alt="gradient eq" class="ipsImage ipsImage_thumbnailed" data-fileid="169712" data-ratio="62.00" data-unique="ychnzs4rw" style="width: 300px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_03/gradient_eq.thumb.jpg.65b1003e6c08d90b9672744391a04962.jpg"></a>
</h2>

<h2 id="-1">
	مثال بسيط
</h2>

<p>
	لنلقِ النظر على شبكة عصبية في غاية البساطة، تتكون من 5 عصبونات أو عقد neurons، وتعرض هذه الصورة الشبكة العصبية التي نتحدث عنها.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169708" href="https://academy.hsoub.com/uploads/monthly_2025_03/computation_graph_forward.png.3b7ce519184126620dae5477eef56bca.png" rel=""><img alt="computation graph forward" class="ipsImage ipsImage_thumbnailed" data-fileid="169708" data-unique="w3pqzoldf" style="width: 400px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/computation_graph_forward.png.3b7ce519184126620dae5477eef56bca.png"> </a>
</p>

<p>
	تصف المعادلات التالية هذه الشبكة العصبية البسيطة:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169714" href="https://academy.hsoub.com/uploads/monthly_2025_03/eq1.png.117b7d0824447b20e7f731c8f1e3e847.png" rel=""><img alt="eq1" class="ipsImage ipsImage_thumbnailed" data-fileid="169714" data-unique="l2b1ny28i" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/eq1.thumb.png.06b590ef8caa3463aece0abec1a494a8.png"> </a>
</p>

<p>
	لنحسب التدرجات التصحيحية لكل معامل قابل للتعلم <code>w:</code>
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169715" href="https://academy.hsoub.com/uploads/monthly_2025_03/eq2.png.f935f5b04d0e8be5724e5789ad19ca61.png" rel=""><img alt="eq2" class="ipsImage ipsImage_thumbnailed" data-fileid="169715" data-unique="7w69wikj3" style="width: 250px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/eq2.thumb.png.7efc083c02b5d8be4ae7f17d74bfeb1e.png"> </a>
</p>

<p>
	حُسِبَت جميع هذه التدرجات gradients باستخدام قاعدة السلسلة chain rule، ويمكن أن نلاحظ أن جميع التدرجات الفردية في الجانب الأيمن من المعادلة يمكن حسابها بشكل مباشر بما أن البسط هو دالة ضمنية لتلك الموجودة في المقام.
</p>

<h2 id="-2">
	المخططات البيانية الحسابية Computation Graphs
</h2>

<p>
	يمكن أن نحسب التدرجات gradients لشبكتنا العصبية يدويًا لأنها شبكة بسيطة للغاية، ولكن ماذا لو أردنا إجراء حسابات لشبكة تتكون من 152 طبقة، أو شبكة تمتلك عددًا كبيرًا من التفرعات. يتطلب تصميم برنامج لبناء <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF-%D8%B4%D8%A8%D9%83%D8%A9-%D8%B9%D8%B5%D8%A8%D9%8A%D8%A9-%D8%B5%D9%86%D8%B9%D9%8A%D8%A9-%D9%88%D8%AA%D8%AF%D8%B1%D9%8A%D8%A8%D9%87%D8%A7-%D9%84%D9%84%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D8%A7%D9%84%D9%88%D8%AC%D9%88%D9%87-r1198/" rel="">الشبكات العصبية الاصطناعية ANN</a> إيجاد طريقة تمكننا من حساب التدرج التصحيحي gradient بسهولة لمختلف المعماريات التي يمكن تكونيها، فنحن لا نريد أن ينشغل المطور بالتعامل اليدوي مع عملية حساب التدرج gradient عند حدوث أي تغيير في تصميم الشبكة.
</p>

<p>
	يمكننا تحقيق هذا المبدأ باستخدام <a href="https://academy.hsoub.com/programming/general/%D9%87%D9%8A%D8%A7%D9%83%D9%84-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-data-structures/" rel="">هيكل بيانات</a> يسمى المخطط البياني الحسابي computation graph، وتتشابه هذه البنية في الشكل مع الرسم التوضيحي للشبكة العصبية البسيطة، مع وجود بعض الاختلافات، حيث أن العقد nodes في المخطط الحسابي هي معاملات operators وهي معاملات حسابية في أغلب الحالات كالجمع والطرح والضرب والقسمة، عدا في حالة واحدة حيث نحتاج لتعريف معامل operator يعبر عن عملية إنشاء المستخدم لمتغير مخصص.
</p>

<p>
	نلاحظ في الصورة التالية أننا رمزنا للمتغيرات الطرفية leaf variables بالرموز التالية <code>a, w1, w2, w3, w4</code> من أجل التوضيح وسهولة التعامل، ولكنها ليست جزءًا أصيلًا من <a href="https://academy.hsoub.com/programming/advanced/%D9%85%D9%81%D9%87%D9%88%D9%85-%D8%A7%D9%84%D8%B1%D8%B3%D9%88%D9%85-%D8%A7%D9%84%D8%AA%D8%AE%D8%B7%D9%8A%D8%B7%D9%8A%D8%A9-graphs-%D9%81%D9%8A-%D8%A7%D9%84%D8%AE%D9%88%D8%A7%D8%B1%D8%B2%D9%85%D9%8A%D8%A7%D8%AA-r1293/" rel="">المخطط الرسومي graph</a>، فما تمثله هو الحالة الخاصة التي ينشئ فيها المستخدم المتغيرات الخاصة به.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169707" href="https://academy.hsoub.com/uploads/monthly_2025_03/computation_graph.png.630c332bec6f91741826dcdeaf0c6614.png" rel=""><img alt="computation graph" class="ipsImage ipsImage_thumbnailed" data-fileid="169707" data-unique="stdff89d1" style="width: 400px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/computation_graph.png.630c332bec6f91741826dcdeaf0c6614.png"> </a>
</p>

<p>
	أنشئت المتغيرات التالية <code>b,c,d</code> كنتيجة للعمليات الحسابية، بينما تكون المتغيرات <code>a,w1,w2,w3,w4</code> معرّفة ومدخلة بواسطة المستخدم، وبما أنها ليست متغيرات ناتجة أن أي عملية حسابية، فسنرمز للعقد التي تعبر عنها باسم المتغير الذي أنشأه المستخدم. وهذا ينطبق على كل العقد الطرفية leaf nodes في المخطط الحسابي.
</p>

<h2 id="computingthegradients">
	حساب التدرجات Gradients
</h2>

<p>
	بعد التعرف على بعض المفاهيم الأساسية، لنتعرف الآن على آلية حساب التدرجات gradients باستخدام المخطط الحسابي computation graph، يمكن اعتبار كل عقدة node في المخطط -باستثناء العقد الطرفية- دالة تستقبل مدخلات وتعالجها وتدفع بالمخرجات لتنتشر خلال المخطط.
</p>

<p>
	لنلقِ نظرة على العقدة التي تخرج المتغير  <code>d</code> بعد معالجة المدخلات <code>w4×c</code> و <code>w3×b</code>، يمكننا التعبير عنها كدالة على النحو التالي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169716" href="https://academy.hsoub.com/uploads/monthly_2025_03/eq3.png.2ca01203dcc85037f6eef5f61210c85e.png" rel=""><img alt="eq3" class="ipsImage ipsImage_thumbnailed" data-fileid="169716" data-unique="0g6hq8pyc" style="width: 200px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/eq3.thumb.png.854c1af1ced636e0e69da6979f66e2c5.png"> </a>
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169709" href="https://academy.hsoub.com/uploads/monthly_2025_03/d_mini.png.2968d809f902831e720d1fb179231abc.png" rel=""><img alt="d mini" class="ipsImage ipsImage_thumbnailed" data-fileid="169709" data-unique="1hwzzs1z2" style="width: 200px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/d_mini.png.2968d809f902831e720d1fb179231abc.png"> </a>
</p>

<p>
	حيث تعبر <code>d</code> عن مخرجات الدالة <code>f(x,y)=x+y.</code>
</p>

<p>
	يمكننا الآن وببساطة حساب التدرجات gradients للدالة <code>f</code> بالنسبة لمدخلاتها، وفق المعادلة التالية:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169717" href="https://academy.hsoub.com/uploads/monthly_2025_03/eq4.png.47d06e48019cefdf0e1eb36f65ef6a87.png" rel=""><img alt="eq4" class="ipsImage ipsImage_thumbnailed" data-fileid="169717" data-unique="7slymhfmn" style="width: 200px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/eq4.thumb.png.10beca4ecda37edefc237ad8bc9350ab.png"> </a>
</p>

<p>
	بعد حساب التدرجات gradients سنعمل على وسم الأسهم في الاتجاه المعاكس لها بقيمة التدرج الخاص بها، كما في الصورة التالية:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169713" href="https://academy.hsoub.com/uploads/monthly_2025_03/d_mini_grad.png.2c1bdaef831efd5c463c6a729c44a7c8.png" rel=""><img alt="d mini grad" class="ipsImage ipsImage_thumbnailed" data-fileid="169713" data-unique="lrwdsvq0d" style="width: 200px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/d_mini_grad.png.2c1bdaef831efd5c463c6a729c44a7c8.png"> </a>
</p>

<p>
	توضح الصورة التالية المخطط الحسابي كاملًا بعد أن طبقنا هذه على الخطوات عند كل العقد:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169711" href="https://academy.hsoub.com/uploads/monthly_2025_03/full_graph.png.f3c1333dfe6002040cbd0b2e3b4b26dc.png" rel=""><img alt="full graph" class="ipsImage ipsImage_thumbnailed" data-fileid="169711" data-unique="ra71cux4d" style="width: 500px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/full_graph.png.f3c1333dfe6002040cbd0b2e3b4b26dc.png"> </a>
</p>

<p>
	تاليًا، سنصف الخوارزمية التي تحسب القيمة المشتقة عند أي عقدة في المخطط الحسابي بالنسبة لدالة الخسارة <code>L</code>. لنقل أننا نريد حساب الاشتقاق التالي :
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169718" href="https://academy.hsoub.com/uploads/monthly_2025_03/eq5.png.ce977b46d884529b6cc620124f136013.png" rel=""><img alt="eq5" class="ipsImage ipsImage_thumbnailed" data-fileid="169718" data-unique="l6q3k74et" style="width: 250px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/eq5.thumb.png.a23ad397d77011bb1d39c99f1dcc079a.png"> </a>
</p>

<p>
	سنتبع أولًا كل المسارات الممكنة من <code>d</code> إلى <code>w4 </code>وفي حالتنا هناك مسار واحد يصل بين المتغيرين، ثم سنضرب قيم الحواف أو الوصلات edges الواقعة على هذا المسار. يمكن أن نلاحظ أن حاصل الضرب الناتج هو نفسه الذي حصلنا عليه عند استخدام قاعدة السلسلة chain rule، وإذا كان هناك أكثر من مسار يربط المتغير بدالة الخسارة <code>L</code> نضرب الوصلات في كل مسار ثم نجمع حاصل الضرب من كل مسار، كما في المثال التالي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169719" href="https://academy.hsoub.com/uploads/monthly_2025_03/eq6.png.0facc1f3254a948213d2c56a6d78aa9f.png" rel=""><img alt="eq6" class="ipsImage ipsImage_thumbnailed" data-fileid="169719" data-unique="aw8dpeyy3" style="width: 400px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/eq6.thumb.png.258d33cf73bfcefaf614c1abef92458d.png"> </a>
</p>

<h2 id="pytorchautograd">
	حساب التفاضل التلقائي في PyTorch Autograd
</h2>

<p>
	بعد أن تعرفنا بشكل مفصل على ماهية المخطط الحسابي computational graph، لنستكشف الآن آلية تطبيق المخطط الحسابي في باي تورش PyTorch بشكل آلي، سنستخدم هيكل بيانات يسمى التنسور أو المُوتِر Tensor وهو أساسي في باي تورش PyTorch، حيث يشبه نوعًا ما <a href="https://academy.hsoub.com/programming/python/%D9%85%D9%81%D8%A7%D9%87%D9%8A%D9%85-%D9%85%D8%AA%D9%82%D8%AF%D9%85%D8%A9-%D8%AD%D9%88%D9%84-%D9%85%D9%83%D8%AA%D8%A8%D8%A9-numpy-%D9%81%D9%8A-%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-r1809/" rel="">مصفوفات مكتبة نمباي NumPy arrays</a>، ولكن على النقيض من نمباي NumPy، فإن التنسورات tensors مصممة للاستفادة من قدرات الحوسبة الفائقة على التوزاي التي توفرها وحدات المعالجة الرسومية GPUs، ويتشابه الكود وقواعد كتابته مع تلك الموجودة في نمباي NumPy.
</p>

<p>
	للنشئ tensor من 3 صفوف و 5 اعمدة، ونهيأه بقيم عشوائية كما يلي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3975_29" style=""><span class="typ">In</span><span class="pln"> </span><span class="pun">[</span><span class="lit">1</span><span class="pun">]:</span><span class="pln">  </span><span class="kwd">import</span><span class="pln"> torch

</span><span class="typ">In</span><span class="pln"> </span><span class="pun">[</span><span class="lit">2</span><span class="pun">]:</span><span class="pln"> tsr </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="typ">Tensor</span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="lit">5</span><span class="pun">)</span><span class="pln">

</span><span class="typ">In</span><span class="pln"> </span><span class="pun">[</span><span class="lit">3</span><span class="pun">]:</span><span class="pln"> tsr
</span><span class="typ">Out</span><span class="pun">[</span><span class="lit">3</span><span class="pun">]:</span><span class="pln"> 
tensor</span><span class="pun">([[</span><span class="pln"> </span><span class="lit">0.0000e+00</span><span class="pun">,</span><span class="pln">  </span><span class="lit">0.0000e+00</span><span class="pun">,</span><span class="pln">  </span><span class="lit">8.4452e-29</span><span class="pun">,</span><span class="pln"> </span><span class="pun">-</span><span class="lit">1.0842e-19</span><span class="pun">,</span><span class="pln">  </span><span class="lit">1.2413e-35</span><span class="pun">],</span><span class="pln">
        </span><span class="pun">[</span><span class="pln"> </span><span class="lit">1.4013e-45</span><span class="pun">,</span><span class="pln">  </span><span class="lit">1.2416e-35</span><span class="pun">,</span><span class="pln">  </span><span class="lit">1.4013e-45</span><span class="pun">,</span><span class="pln">  </span><span class="lit">2.3331e-35</span><span class="pun">,</span><span class="pln">  </span><span class="lit">1.4013e-45</span><span class="pun">],</span><span class="pln">
        </span><span class="pun">[</span><span class="pln"> </span><span class="lit">1.0108e-36</span><span class="pun">,</span><span class="pln">  </span><span class="lit">1.4013e-45</span><span class="pun">,</span><span class="pln">  </span><span class="lit">8.3641e-37</span><span class="pun">,</span><span class="pln">  </span><span class="lit">1.4013e-45</span><span class="pun">,</span><span class="pln">  </span><span class="lit">1.0040e-36</span><span class="pun">]])</span></pre>

<p>
	لنضمن قيام باي تورش PyTorch بإنشاء مخطط حسابي للموترات tensor الذي عرفناه، ينبغي علينا ضبط قيمة المتغير <code>requires_grad</code> إلى <code>True</code>، فبدون هذه الخطوة سيكون الموتر مجرد هيكل بيانات تقليدي كالذي توفره مكتبة نمباي NumPy يمكن استخدامه للعمليات الجبر الخطي السريعة.
</p>

<p>
	قد يكون استخدام باي تورش لإنشاء موترات أمرًا مربكًا في البداية، حيث توجد عدة طرق لإنشاء الموترات tensors، فتسمح بعض الطرق بتمرير تعريف المتغير <code>requires_grad</code> بشكل صريح في الدالة المُنشأة، وطرقًا أخرى تجعلنا نضبط هذا المتغير يدويًا بعد إنشاء الموتر tensor.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3975_31" style=""><span class="pln">t1 </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">((</span><span class="lit">3</span><span class="pun">,</span><span class="lit">3</span><span class="pun">),</span><span class="pln"> requires_grad </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">True</span><span class="pun">)</span><span class="pln"> 
t2 </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="typ">FloatTensor</span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="lit">3</span><span class="pun">)</span><span class="pln"> </span><span class="com"># لا تسمح هذه الدالة بضبط هذا المتغير وقت الإنشاء </span><span class="pln">
</span><span class="com"># لكن يمكن ضبطه بعد الإنشاء</span><span class="pln">
t2</span><span class="pun">.</span><span class="pln">requires_grad </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">True</span></pre>

<p>
	تحدد الخاصية <code>requires_grad</code> فيما إذا كان على باي تورش تتتبع العمليات الرياضية التي تنفذ على الموتر حتى يتمكن لاحقًا من حساب التدرجات gradients أثناء الانتشار الخلفي، فإذا كانت قيمته <code>True</code> يجري تتبع العمليات وحساب التدرجات لاحقًا، وفي حال كانت <code>False</code> لن يكون هناك تتبع للعمليات، ولن تحسب التدرجات.
</p>

<p>
	وعند إنشاء موتر tensor كنتيجة لعملية على موتر آخر يضبط هذه الخاصية بالقيمة <code>True</code> فإن الموتر الناتج سيمتلكها أيضًا، فيلزم على الأقل أن يكون أحد الموترات tensors الداخلة في العملية قد فعّل هذه الخاصية أثناء إنشائه لتنتشر من خلال الموتر الناتج عن هذه العملية حتى إن لما تكن مفعلة في باقي الموترات.
</p>

<p>
	كما يمتلك كل موتر tensor خاصية تسمى <code>grad_fn</code> ، والتي تشير إلى إلى معامل رياضي operator يقوم بإنشاء المتغير، وحينما تكون خاصية <code>requires_grad</code> غير مفعلة <code>False</code> فتكون <code>grad_fn</code> قيمتها <code>None</code>.
</p>

<p>
	سنجد في مثال <code>d=f(w3b,w4c)</code>، أن دالة التدرج grad function ستكون هي عملية الجمع، حيث تجمع الدالة <code>f</code> المدخلات معًا، وستكون عملية الجمع عقدة في المخطط الحسابي الذي يخرج  <code>d</code>، وفي حالة كون العقدة طرفية أي متغير معرف بواسطة المستخدم فستكون دالة التدرج الخاصة به <code>grad_fn=None</code>.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3975_33" style=""><span class="kwd">import</span><span class="pln"> torch 
a </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">((</span><span class="lit">3</span><span class="pun">,</span><span class="lit">3</span><span class="pun">),</span><span class="pln"> requires_grad </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
w1 </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">((</span><span class="lit">3</span><span class="pun">,</span><span class="lit">3</span><span class="pun">),</span><span class="pln"> requires_grad </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
w2 </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">((</span><span class="lit">3</span><span class="pun">,</span><span class="lit">3</span><span class="pun">),</span><span class="pln"> requires_grad </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
w3 </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">((</span><span class="lit">3</span><span class="pun">,</span><span class="lit">3</span><span class="pun">),</span><span class="pln"> requires_grad </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
w4 </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">((</span><span class="lit">3</span><span class="pun">,</span><span class="lit">3</span><span class="pun">),</span><span class="pln"> requires_grad </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
b </span><span class="pun">=</span><span class="pln"> w1</span><span class="pun">*</span><span class="pln">a 
c </span><span class="pun">=</span><span class="pln"> w2</span><span class="pun">*</span><span class="pln">a
d </span><span class="pun">=</span><span class="pln"> w3</span><span class="pun">*</span><span class="pln">b </span><span class="pun">+</span><span class="pln"> w4</span><span class="pun">*</span><span class="pln">c 
L </span><span class="pun">=</span><span class="pln"> </span><span class="lit">10</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> d
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"The grad fn for a is"</span><span class="pun">,</span><span class="pln"> a</span><span class="pun">.</span><span class="pln">grad_fn</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"The grad fn for d is"</span><span class="pun">,</span><span class="pln"> d</span><span class="pun">.</span><span class="pln">grad_fn</span><span class="pun">)</span></pre>

<p>
	ينتج تشغيل هذا الكود الخرج التالي:
</p>

<pre class="ipsCode">The grad fn for a is None
The grad fn for d is &lt;AddBackward0 object at 0x1033afe48&gt;
</pre>

<h3 id="function">
	دوال الصنف Autograd.Function
</h3>

<p>
	تُنفَّذ جميع العمليات الحسابية في باي تورش PyTorch من خلال الصنف البرمجي <code>torch.nn.Autograd.Function</code>، الذي يشكل جزءًا أساسيًا من آلية التفاضل التلقائي. يعتمد هذا الصنف على دالتين رئيسيتين: الأولى هي دالة الانتشار الأمامي <code>backward</code> والتي تحسب المخرجات بناءً على المدخلات السابقة، مما يمثل العملية الحسابية التي تجريها الطبقة أثناء تمرير البيانات عبر النموذج. أما الدالة الثانية فهي دالة الانتشار الخلفي <code>backward</code> التي تتولى حساب التدرجات من خلال استقبالها من الطبقات التالية في الشبكة.
</p>

<p>
	يمكن ملاحظة أن اتجاه انتشار التدرجات gradients يكون عكسيًا، أي من المخرجات نحو المدخلات، وليس العكس. هذا يعني أن التدرجات القادمة من الدالة <code>f</code> تنتقل من الطبقات الأخيرة في النموذج إلى الطبقات الأولى. وتعدّل الأوزان في كل طبقة بناءً على مدى تأثيرها على الخطأ النهائي. يتم ذلك عن طريق ضرب التدرج القادم من الطبقة التالية في التدرج المحلي الخاص بتلك الطبقة، مما يساعد على حساب مقدار التغيير اللازم لكل وزن حتى تتحسن دقة النموذج.
</p>

<p>
	وبالتالي، تتلقى كل طبقة معلومات من الطبقة التي تليها حول كيفية تغيير أوزانها لتقليل الخطأ، ويستمر هذا التدفق العكسي حتى تصل التحديثات إلى أول طبقة في النموذج. هذا هو جوهر عملية الانتشار الخلفي التي تتيح للنموذج التعلم من الأخطاء وتحسين أدائه بمرور الوقت.
</p>

<h3>
	مثال عملي
</h3>

<p>
	لنفهم الأمر بمثال عملي لنفرض أن لدينا دالة حسابية بسيطة تمثل جزءًا من شبكة عصبية<code>d = f(w3b , w4c)‎</code>
</p>

<p>
	<code>d</code> هنا هي موتر tensor، ودالة التدرج <code>grad_fn</code> هي <code>&lt;ThAddBackward&gt;</code> وهي عملية جميع بسيطة حيث أن الدالة التي أنشئت <code>d</code> تجمع المدخلات، وتتلقى دالة الانتشار الأمامي <code>forward</code> مدخلات دالة التدرج <code>grad_fn</code> حيث تتلقى <code>w3b</code> و <code>w4c</code> وتجمع المدخلات في دالة التدرج، ثم تتدفق النتيجة للأمام بعد أن تحفظ في الموتر <code>d</code>.
</p>

<p>
	وتتلقى دالة التراجع <code>backward</code> الخاصة بالدالة <code>&lt;ThAddBackward&gt;</code> التدرجات الداخلة incoming gradient من الطبقات التالية لها كمدخلات أي الطبقات التي على يمين الطبقة الحالية، ما نحاول حسابه هو الاشتقاق الجزئي لدالة الخسارة <code>L</code> بالنسبة للمتغير <code>d</code> والتي تتكون من كل القيم الموجودة على الوصلات edges التي تربط بين <code>L</code> و <code>d</code>، ويمكن الوصول لقيم التدرجات gradients بالنسبة للمتغير <code>d</code> حيث تخزن في <code>grad</code> وهو خاصية للموتر، فتصل لها من خلال <code>d.grad</code>.
</p>

<p>
	نحسب بعد هذا التدرجات المحلية local gradients، أي التفاضل الجزئي للمتغير  <code>d</code> أس الدالة التي تجمع بالنسبة للمدخلات <code>w4c</code> ومرة أخرى بالنسبة للمدخل <code>w3b</code>. تُضرب التدرجات gradients القادمة من الطبقات التالية مع التدرجات المحسوبة محليًا بواسطة دالة التراجع، ومن ثم ترسل التدرجات لتنتشر تراجعيًا ناحية المدخلات محفزة تفاعلًا متسلسلًا، تشغّل فيه دالة التراجع لحساب تدرجات الدالة <code>grad_fn</code> المرتبطة بالمدخلات السابقة.
</p>

<p>
	نوضح الأمر بمثال، تقوم دالة التراجع <code>backward</code> المرتبطة بالدالة <code>&lt;ThAddBackward&gt;</code> الخاصة بالمتغير <code>d</code> بتحفيز دالة التراجع للمدخلات <code>grad_fn</code> والتي بدورها تحفز دالة التراجع للمدخل <code>w4c</code>، لاحظ أن <code>w4c</code> هو موتر انتقالي أي أنه مُنشَأ لحفظ ناتج العملية الوسيطة ودالة التدرجات gradient الخاصة به هي <code>&lt;ThMulBackward&gt;</code>، وحينما تستدعي هذه دالة التراجع <code>backward</code> لحساب عملية التدرجات <code>gradients</code> يمرر لها تدرج الاشتقاق الجزئي لدالة الخسارة <code>L</code> بالنسبة إلى المتغير <code>d</code> مضروبة في الاشتقاق الجزئي للمتغير <code>d</code> بالنسبة للمتغير <code>w4c</code>، وتوضح الصورة التالية المعادلة المعبرة عن هذه العملية:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169710" href="https://academy.hsoub.com/uploads/monthly_2025_03/eq7.png.bde15e36f95ceee912a10b92f40f0e92.png" rel=""><img alt="eq7" class="ipsImage ipsImage_thumbnailed" data-fileid="169710" data-unique="w5cbfkemj" style="width: 150px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/eq7.thumb.png.2af456603f2f4a7b2d83cdc4453e1f96.png"> </a>
</p>

<p>
	ويحين الدور الآن على المتغير <code>w4c</code>، فتصبح المعادلة المكتوبة في الأعلى هي المدخلات لهذه العقدة في عملية الانتشار التراجعي لحساب التدرجات gradients، كما كان الأمر في الخطوة الثالثة بالنسبة للمتغير <code>d</code> حيث كانت المدخلات هي الاشتقاق الجزئي لدالة الخسارة بالنسبة للمتغير  <code>d</code>.
</p>

<p>
	لنطبق الأمر من خلال خوارزمية تحسب عملية الانتشار الخلفي باستخدام المخطط الحسابي computation graph، هذا ليس التطبيق الكامل لهذه الدالة ولكنه مثال توضيحي بسيط.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3975_37" style=""><span class="kwd">def</span><span class="pln"> backward</span><span class="pun">(</span><span class="pln">self</span><span class="pun">,</span><span class="pln"> incoming_gradients</span><span class="pun">):</span><span class="pln">
    </span><span class="com"># اضبط قيمة التدرج للموتر الحالي</span><span class="pln">
    self</span><span class="pun">.</span><span class="typ">Tensor</span><span class="pun">.</span><span class="pln">grad </span><span class="pun">=</span><span class="pln"> incoming_gradients

    </span><span class="com"># حلقة تكرارية لتنفيذ الانتشار التراجعي للتدرجات </span><span class="pln">
    </span><span class="kwd">for</span><span class="pln"> inp </span><span class="kwd">in</span><span class="pln"> self</span><span class="pun">.</span><span class="pln">inputs</span><span class="pun">:</span><span class="pln">
        </span><span class="kwd">if</span><span class="pln"> inp</span><span class="pun">.</span><span class="pln">grad_fn </span><span class="kwd">is</span><span class="pln"> </span><span class="kwd">not</span><span class="pln"> </span><span class="kwd">None</span><span class="pun">:</span><span class="pln">
            </span><span class="com"># احسب التدفقات القادمة تجاه المُدخل الحالي</span><span class="pln">
            </span><span class="com"># Compute new incoming gradients for the input</span><span class="pln">
            new_incoming_gradients </span><span class="pun">=</span><span class="pln"> incoming_gradients </span><span class="pun">*</span><span class="pln"> local_grad</span><span class="pun">(</span><span class="pln">self</span><span class="pun">.</span><span class="typ">Tensor</span><span class="pun">,</span><span class="pln"> inp</span><span class="pun">)</span><span class="pln">
            </span><span class="com"># استدعِ دالة التراجع بشكل تعاودي </span><span class="pln">
            </span><span class="com"># Recursively call</span><span class="pln">
            inp</span><span class="pun">.</span><span class="pln">grad_fn</span><span class="pun">.</span><span class="pln">backward</span><span class="pun">(</span><span class="pln">new_incoming_gradients</span><span class="pun">)</span></pre>

<p>
	نجد في هذا الكود أن <code>self.Tensor</code> هو موتر <code>Tensor</code> منشئ بواسطة <code>Autograd.Function</code>، والتي كانت في مثالنا <code>d</code>، وقد شرحنا سابقًا مفهوم التدرجات القادمة incoming gradients والتدرجات المحلية local gradients.
</p>

<p>
	لنحسب المشتقات في الشبكة العصبية، سنحتاج لاستدعاء دالة التراجع <code>backward</code> وتطبيقها على <code>Tensor</code> الذي يمثل الخسارة loss، ونستمر في الرجوع للخلف backtrack خلال المخطط الحسابي بداية من العقدة التي تمثل دالة التدرج <code>grad_fn</code> الخاصة بدالة الخسارة.
</p>

<p>
	وشرحنا سابقًا أن دالة التراجع <code>backward</code> تستدعى بشكل <a href="https://academy.hsoub.com/programming/general/%D9%85%D9%81%D9%87%D9%88%D9%85-%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D9%88%D8%AF%D9%8A%D8%A9-recursion-r1387/" rel="">تعاودي recursive</a>، فأثناء تتبع أثر التفرعات خلال الشبكة الحسابية نستدعي هذه الدالة، والتي بدورها تستدعي نفسها عندما تتراجع للمستوى السابق وهكذا حتى نصل لحالة التوقف الأساسية base case وهي العقد الطرفية leaf node والتي تكون دالة التدرج <code>grad_fn</code> فيه عديمة القيمة <code>None</code>.
</p>

<p>
	ننبه لأن باي تورش PyTorch يعطي خطأ Error عندما نحاول استدعاء دالة التراجع <code>backward</code> وتطبيقها على موتر تتكون عناصره من متجهات متعددة القيم vector-valued Tensor، ويعني هذا أن دالة التراجع <code>backward</code> تعمل على موترات تحتوي قيمًا رقمية أحادية scalers.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3975_39" style=""><span class="kwd">import</span><span class="pln"> torch 
a </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">((</span><span class="lit">3</span><span class="pun">,</span><span class="lit">3</span><span class="pun">),</span><span class="pln"> requires_grad </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
w1 </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">((</span><span class="lit">3</span><span class="pun">,</span><span class="lit">3</span><span class="pun">),</span><span class="pln"> requires_grad </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
w2 </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">((</span><span class="lit">3</span><span class="pun">,</span><span class="lit">3</span><span class="pun">),</span><span class="pln"> requires_grad </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
w3 </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">((</span><span class="lit">3</span><span class="pun">,</span><span class="lit">3</span><span class="pun">),</span><span class="pln"> requires_grad </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
w4 </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">((</span><span class="lit">3</span><span class="pun">,</span><span class="lit">3</span><span class="pun">),</span><span class="pln"> requires_grad </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
b </span><span class="pun">=</span><span class="pln"> w1</span><span class="pun">*</span><span class="pln">a 
c </span><span class="pun">=</span><span class="pln"> w2</span><span class="pun">*</span><span class="pln">a
d </span><span class="pun">=</span><span class="pln"> w3</span><span class="pun">*</span><span class="pln">b </span><span class="pun">+</span><span class="pln"> w4</span><span class="pun">*</span><span class="pln">c 
L </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="lit">10</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> d</span><span class="pun">)</span><span class="pln">
L</span><span class="pun">.</span><span class="pln">backward</span><span class="pun">()</span></pre>

<p>
	سوف يعطي تشغيل هذا الكود الخطأ التالي:
</p>

<pre class="ipsCode">RuntimeError: grad can be implicitly created only for scalar outputs
</pre>

<p>
	يرجع سبب هذا الخطأ لكون قيم التدرجات gradient قابلة لأن تحسب بالنسبة لقيم رقمية أحادية scalers، السبب هو طريقة تعريف التدرج gradient definition، حيث لا يمكنها أن تفاضل متجهًا بالنسبة لمتجه آخر، ولتحقيق ذلك نستخدم عملية رياضية مختلفة تسمى Jacobian وهي خارج نطاق اهتمامنا في هذا المقال.
</p>

<p>
	تكمن المشكلة في توقع دالة التراجع بأن تكون المخرجات قيمة واحدة أو رقم واحد وليست متجهًا. يمكننا تجاوز هذه المشكلة بطريقتين، حيث يمكننا إجراء تعديل بسيط على الكود السابق بضبط قيمة <code>L</code> لتكون مجموع كل الأخطاء، سوف يحل هذا مشكلتنا.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3975_41" style=""><span class="kwd">import</span><span class="pln"> torch 
a </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">((</span><span class="lit">3</span><span class="pun">,</span><span class="lit">3</span><span class="pun">),</span><span class="pln"> requires_grad </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
w1 </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">((</span><span class="lit">3</span><span class="pun">,</span><span class="lit">3</span><span class="pun">),</span><span class="pln"> requires_grad </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
w2 </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">((</span><span class="lit">3</span><span class="pun">,</span><span class="lit">3</span><span class="pun">),</span><span class="pln"> requires_grad </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
w3 </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">((</span><span class="lit">3</span><span class="pun">,</span><span class="lit">3</span><span class="pun">),</span><span class="pln"> requires_grad </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
w4 </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">((</span><span class="lit">3</span><span class="pun">,</span><span class="lit">3</span><span class="pun">),</span><span class="pln"> requires_grad </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
b </span><span class="pun">=</span><span class="pln"> w1</span><span class="pun">*</span><span class="pln">a 
c </span><span class="pun">=</span><span class="pln"> w2</span><span class="pun">*</span><span class="pln">a
d </span><span class="pun">=</span><span class="pln"> w3</span><span class="pun">*</span><span class="pln">b </span><span class="pun">+</span><span class="pln"> w4</span><span class="pun">*</span><span class="pln">c 

</span><span class="com">#  L = (10 - d) استبدلنا هذا </span><span class="pln">
</span><span class="com"># بهذا </span><span class="pln">
L </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="lit">10</span><span class="pln"> </span><span class="pun">-</span><span class="pln">d</span><span class="pun">).</span><span class="pln">sum</span><span class="pun">()</span><span class="pln">
L</span><span class="pun">.</span><span class="pln">backward</span><span class="pun">()</span></pre>

<p>
	يمكننا الوصول للتدرجات الآن بكل سهولة من خلال استدعاء خاصية <code>grad</code> الموجودة في الموتر <code>Tensor</code>.
</p>

<p>
	لنشرح الطريقة الثانية مفترضين أننا نحتاج -لأي سبب من الأسباب- لاستخدام دالة <code>backward</code> على دالة متجهة vector function، يمكننا تجاوز الخطأ بتمرير موتر <code>torch.ones</code> للدالة بأبعاد مطابقة للموتر الذي نحاول تمريره لدالة التراجع.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3975_43" style=""><span class="com"># L.backward() استبدل </span><span class="pln">
L</span><span class="pun">.</span><span class="pln">backward</span><span class="pun">(</span><span class="pln">torch</span><span class="pun">.</span><span class="pln">ones</span><span class="pun">(</span><span class="pln">L</span><span class="pun">.</span><span class="pln">shape</span><span class="pun">))</span></pre>

<p>
	ويمكن أن نلاحظ أننا مررنا لدالة <code>backward</code> التدرجات القادمة incoming gradients من مدخلاتها، وبهذا جعلنا الدالة تتلقى التدرجات gradients على هيئة موترات مليئة بالواحد Tensor of ones بنفس أبعاد <code>L</code>، مما يجعلها قابلة للانتشار الخلفيbackward propagation بشكل مبسط.
</p>

<p>
	تمكننا هذه الطريقة من الحصول على تدرجات gradients أي موتر <code>Tensor</code>، وتحديث الأوزان والمعاملات من خلال خوارزمية التحسين التي نفضلها.
</p>

<pre class="ipsCode">w1 = w1 - learning_rate * w1.grad
</pre>

<h2 id="pytorchtensorflow">
	أبرز الاختلافات بين باي تورش PyTorch و تنسورفلو Tensorflow المخططات الحسابية
</h2>

<p>
	ينشئ باي تورش PyTorch مخططات حسابية ديناميكية Dynamic Computation Graph أي أنها تولد بشكل مرن تلقائيًا عند الحاجة، واستخدام دالة الانتشار الأمامي <code>forward</code> هو المحفز لإنشاء المتغيرات التي سنستخدمها لاحقًا في خطوة الانتشار الخلفي، وبالتالي قبل استدعاء دالة الانتشار الأمامي <code>forward</code> لن توجد أي عقدة تحمل موتر بخاصية دالة التدرج <code>grad_fn</code>.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4458_12" style=""><span class="com"># لا يوجد أي شبكة حسابية حتى الآن، فهنا نعرف مجرد عقدة طرفية </span><span class="pln">
a </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">((</span><span class="lit">3</span><span class="pun">,</span><span class="lit">3</span><span class="pun">),</span><span class="pln"> requires_grad </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">True</span><span class="pun">)</span><span class="pln"> 
</span><span class="com"># ينطبق نفس الأمر هنا، مجرد تعريفنا لموتر</span><span class="pln">
w1 </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">((</span><span class="lit">3</span><span class="pun">,</span><span class="lit">3</span><span class="pun">),</span><span class="pln"> requires_grad </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">True</span><span class="pun">)</span><span class="pln">  
</span><span class="com"># هنا يتم إنشاء شبكة حسابية بها دالة ضرب سيتم استخدامها لحساب التدرجات </span><span class="pln">
b </span><span class="pun">=</span><span class="pln"> w1</span><span class="pun">*</span><span class="pln">a   </span><span class="com">#Graph with node `mulBackward` is created.</span></pre>

<p>
	أنشئت الشبكة الحسابية هنا كنتيجة لتشغيل دالة الانتشار الأمامي <code>forward</code> الخاصة بعدة موترات tensors،  وفقط عند استدعائها تُخصّص مساحات تخزينية ومتغيرات وسيطة لتحتفظ بالقيم الانتقالية التي ستستخدم في حساب التدرجات gradient لاحقًا عندما تستدعى دالة التراجع <code>backward</code> ، وتُحرّر المساحات التخزينية المخصصة فور الانتهاء من حساب التدرجات gradients في العقد غير الطرفية، وعندما تستدعى دالة الانتشار الأمامي <code>forward</code> على نفس المجموعة من الموترات Tensors، يعاد استخدام المساحات التخزينية للعقد الطرفية من التشغيل السابق للشبكة، بينما تنشأ وتخصص من جديد تلك المساحات الانتقالية أو الوسيطة عند وصول دالة الانتشار الأمامي لها.
</p>

<p>
	إن حاولنا استدعاء دالة التراجع <code>backward</code> أكثر من مرة على عقد غير طرفية non-leaf nodes، سنحصل على الخطأ التالي:
</p>

<pre class="ipsCode">RuntimeError: Trying to backward through the graph a second time, but the buffers have already been freed. Specify retain_graph=True when calling backward the first time.
</pre>

<p>
	يرجع هذا الخطأ لتحرير المساحات التخزينية التي أنشئت سابقًا للعقد غير الطرفية عند استدعاء دالة <code>backward</code> ، فلا يوجد طريق تنتشر فيه خلفيًا من خلاله عند استدعاء الدالة مرة أخرى، الأمر أشبه بعبور جسر من الحبال ثم قطع الحبال، للعبور مجددًا سنحتاج لإنشاءها من جديد، ولكن يمكنك أن نلغي هذا التأثير بضبط خاصية متاحة في دالة <code>backward</code> وهي <code>retain_graph</code> لتكون <code>True</code>.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4458_14" style=""><span class="pln">loss</span><span class="pun">.</span><span class="pln">backward</span><span class="pun">(</span><span class="pln">retain_graph </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">True</span><span class="pun">)</span></pre>

<p>
	عند تفعيل هذه الخاصية سنتمكن من استخدام التراجع الخلفي backpropagation على نفس المخطط الحسابي، حيث ستتراكم التدرجات gradients، أي في المرة القادمة التي ننفذ فيها التراجع الخلفي ستضاف قيم التدرجات إلى تلك الموجودة سابقًا والمخزنة من الدورة السابقة.
</p>

<p>
	يناقض هذا طريقة عمل المخططات الحسابية الثابتة Static Computation Graphs التي يستخدمها تنسورفلو TensorFlow، حيث يعرف المخطط الحسابي قبل تشغيل البرنامج. ويجري تشغيله عن طريق إدخال القيم المعرفة مسبقًا.
</p>

<p>
	تسمح المخططات الحسابية الديناميكية dynamic graph بالتغيير في معمارية المخطط أثناء التشغيل، حيث يتم إنشاء المخطط فقط عند تشغيل جزء محدد من الكود. ويعني هذا أيضًا أن المخطط يمكن أن يعاد تعريفه أثناء تشغيل البرنامج، وكما وضحنا فهذا غير ممكن في المخطط الثابت حيث يعرف  المخطط وينشأ قبل تشغيل البرنامج.
</p>

<p>
	ويسهل تقفي أثر الأخطاء والمشاكل التي قد تحدث مع المخططات الديناميكية المرنة حيث يمكننا معرفة مصدر الخطأ، فلن نستطيع إكمال الانتشار إن وجدنا مشكلة بجزء معين، على النقيض من المخططات الثابتة حيث يتم الانتشار في مسارات معرفة مسبقًا.
</p>

<table>
	<thead>
		<tr>
			<th>
				وجه المقارنة
			</th>
			<th>
				مخطط حسابي ديناميكي
			</th>
			<th>
				مخطط حسابي ثابت
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				إطار العمل
			</td>
			<td>
				باي تورش PyTorch
			</td>
			<td>
				تنسورفلو TensorFlow
			</td>
		</tr>
		<tr>
			<td>
				تعريف المخطط
			</td>
			<td>
				وقت التشغيل
			</td>
			<td>
				قبل التشغيل
			</td>
		</tr>
		<tr>
			<td>
				طريقة التشغيل
			</td>
			<td>
				يؤجل التشغيل حتى البناء الكامل للمخطط الرسومي
			</td>
			<td>
				يتم التشغيل بشكل متزامن مع بناء المخطط الرسومي
			</td>
		</tr>
		<tr>
			<td>
				المرونة
			</td>
			<td>
				مرن للغاية، يمكن تغير المعمارية وقت التشغيل
			</td>
			<td>
				أقل مرونة، فنحتاج لإعادة بناء المخطط عند كل تعديل
			</td>
		</tr>
		<tr>
			<td>
				الأداء
			</td>
			<td>
				أبطء نسبيًا، حيث تفسر كل عملية على حدة وقد يوجد تكرار
			</td>
			<td>
				أسرع حيث يتم تحسين المخطط قبل تشغيله وتفادي التكرار
			</td>
		</tr>
		<tr>
			<td>
				التحسين
			</td>
			<td>
				مساحة محدودة للتحسين، حيث تنفذ جميع العمليات فورًا
			</td>
			<td>
				مع معرفتنا بهيكل المخطط كاملًا يمكن تطبيق خوارزميات تحسن ترتيبه وطريقة تشغيله بسهولة
			</td>
		</tr>
		<tr>
			<td>
				كفاءة التخزين
			</td>
			<td>
				أقل كفاءة، فكل عملية يحجز لها مساحة مخصوصة حتى وإن كانت مكررة.
			</td>
			<td>
				أكثر كفاءة، فيعاد استخدام المتغيرات المتكررة.
			</td>
		</tr>
		<tr>
			<td>
				اكتشاف المشاكل وحل الأخطاء
			</td>
			<td>
				أسهل
			</td>
			<td>
				أصعب
			</td>
		</tr>
		<tr>
			<td>
				المعماريات المناسبة
			</td>
			<td>
				مناسب للغاية للمعماريات المرنة، مثل الشبكات العصبية التكرارية RNN، التي تتعامل مع متسلسلات من المدخلات مثل الجمل، ومرونة باي تورش تمكننا من التعامل مع حجم جمل متغير.
			</td>
			<td>
				أنسب للمعماريات الثابتة، مثل الشبكات العصبية الالتفافية CNN
			</td>
		</tr>
		<tr>
			<td>
				مجال الاستخدام
			</td>
			<td>
				المجال البحثي، وتطوير المعماريات الجديدة، ولكنه قد لا يكون محسنًا بما يكفي لبيئات التشغيل
			</td>
			<td>
				يشيع استخدامه في بيئات التشغيل وعملية الاستدلال، حيث تكون الشبكة محسنة بدرجة فائقة وقابلة للنقل والتشغيل في بيئات مختلفة.
			</td>
		</tr>
	</tbody>
</table>

<h2 id="-3">
	ملاحظات إضافية
</h2>

<p>
	لنتعرف الآن على بعض الملاحظات والطرق التي يمكن أن نستخدمها لتغيير سلوك المخطط الحسابي في باي تورش PyTorch.
</p>

<h3>
	الخاصية <code>requires_grad</code>
</h3>

<p>
	تكون هذه الخاصية المتعلقة بالموترات Tensors في غاية الأهمية، عندما تريد أن تجمد بعض الطبقات في الشبكة العصبية ولا تريد أن يتم تدريبها، حيث يمكنك ببساطة أن تجعل قيمة هذه الخاصية <code>False</code>، وبالتالي لن تكون هذه الموترات داخلة في عملية حساب التدرجات gradients.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169720" href="https://academy.hsoub.com/uploads/monthly_2025_03/requires_grad.png.1d366493d5dfc01eae6858d9170bfb2c.png" rel=""><img alt="requires grad" class="ipsImage ipsImage_thumbnailed" data-fileid="169720" data-unique="1bs4afjtq" style="width: 400px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/requires_grad.thumb.png.fd45ed5c1157a4bf7f29d4d3072e1195.png"> </a>
</p>

<p>
	ولن تنتشر لهم أي تدرجات gradients نتيجة لإيقاف هذه الخاصية، ولا للطبقات التي تعتمد عليها، ونلاحظ أن هذه الخاصية في الأصل قابلة للانتشار فعند تنفيذ عملية على موترات أحدها مفعل به هذه الخاصية، فسيكون الموتر الناتج يحمل هذه الخاصية مفعلة <code>True</code>.
</p>

<h3>
	الخاصية <code>torch.no_grad</code>
</h3>

<p>
	نحتاج أحيانًا إلى تخزين بعض المدخلات والمتغيرات الانتقالية مؤقتًا أثناء حساب التدرجات gradients، لنستخدمهم في خطوات قادمة لحساب شيء آخر، فمثلًا تدرج المتغير <code>b=w1*a</code> بالنسبة لمدخلاته <code>w1</code> و <code>a</code> يساوي <code>w1</code> و <code>a</code> فنحتاج تخزين هذه المتغيرات لاستخدامها لاحقًا في حساب التدرجات أثناء الانتشار الخلفي، ولهذا أثر ثقيل على استخدام الذاكرة.
</p>

<p>
	والاستدلال بحد ذاته لا يتطلب منا إعادة حساب التدرجات gradients، وبالتالي لسنا بحاجة لتخزينها بشكل دائم، في الواقع نحن لانحتاج أن ننشئ المخطط الحسابي وقت الاستدلال حيث سيؤدي هذا لهدر الذاكرة.
</p>

<p>
	يقدم باي تورش PyTorch حلًا لهذه المشكلة، من خلال مدير السياق context manager، المسمى <code>torch.no_grad</code> والذي يعطل عملية حساب التدرجات gradients في أي سياق يتطلب تحديث أوزان النموذج أو ربما تقييمه، ويوفر هذا الكثير من الذاكرة، حيث لا ننشئ المتغيرات الوسيطة ولا المخطط الحسابي.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_4458_16" style=""><span class="kwd">with</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">no_grad</span><span class="pun">:</span><span class="pln">
         </span><span class="pun">كود</span><span class="pln"> </span><span class="pun">الاستدلال</span><span class="pln"> </span><span class="pun">هنا</span></pre>

<h2 id="-4">
	الخاتمة
</h2>

<p>
	تعرفنا في مقال اليوم على آلية عمل التفاضل التلقائي ومحرك التفاصل المستخدم في باي تورش PyTorch والمسمى Autograd، والذي يجعل من التعامل مع باي تورش PyTorch أسهل  وأبسط،  بعد فهم هذه الأساسيات يمكن التعمق في فهم النماذج المعقدة، وكيف يمكن بناؤها بواسطة باي تورش.
</p>

<p>
	ترجمة وبتصرف لمقال <a href="https://www.digitalocean.com/community/tutorials/pytorch-101-understanding-graphs-and-automatic-differentiation#introduction" rel="external nofollow">PyTorch 101, Understanding Graphs, Automatic Differentiation and Autograd</a> لصاحبه Ayoosh Kathuria
</p>

<h2 id="-5">
	اقرأ أيضًا
</h2>

<ul>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D8%AF%D9%88%D8%A7%D9%84-%D8%A7%D9%84%D8%AE%D8%B3%D8%A7%D8%B1%D8%A9-loss-functions-%D9%81%D9%8A-pytorch-r2539/" rel="">تعرف على دوال الخسارة Loss Functions في PyTorch</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A3%D9%81%D8%B6%D9%84-%D9%85%D9%85%D8%A7%D8%B1%D8%B3%D8%A7%D8%AA-%D9%87%D9%86%D8%AF%D8%B3%D8%A9-%D8%A7%D9%84%D9%85%D9%8F%D9%88%D8%AC%D9%91%D9%90%D9%87%D8%A7%D8%AA/" rel="">أفضل ممارسات هندسة المُوجِّهات Prompt Engineering: نصائح وحيل وأدوات</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%AF%D8%B1%D9%8A%D8%A8-%D8%A7%D9%84%D9%85%D9%8B%D9%83%D9%8A%D9%91%D9%8E%D9%81%D8%A7%D8%AA-peft-adapters-%D8%A8%D8%AF%D9%84-%D8%AA%D8%AF%D8%B1%D9%8A%D8%A8-%D9%86%D9%85%D8%A7%D8%B0%D8%AC-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-%D8%A8%D8%A7%D9%84%D9%83%D8%A7%D9%85%D9%84-r2377/" rel="">تدريب المًكيَّفات PEFT Adapters بدل تدريب نماذج الذكاء الاصطناعي بالكامل</a>
	</li>
	<li>
		ت<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D8%A5%D8%B7%D8%A7%D8%B1-%D8%B9%D9%85%D9%84-%D8%A8%D8%A7%D9%8A-%D8%AA%D9%88%D8%B1%D8%B4-pytorch-%D9%88%D8%A3%D9%87%D9%85%D9%8A%D8%AA%D9%87-%D9%84%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-r2311/" rel="">عرف على إطار عمل باي تورش PyTorch وأهميته لتطبيقات الذكاء الاصطناعي</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">2540</guid><pubDate>Fri, 28 Mar 2025 12:06:01 +0000</pubDate></item><item><title>&#x62A;&#x634;&#x63A;&#x64A;&#x644; Deepseek &#x645;&#x62D;&#x644;&#x64A;&#x627; &#x639;&#x644;&#x649; &#x645;&#x62D;&#x631;&#x631; &#x627;&#x644;&#x623;&#x643;&#x648;&#x627;&#x62F; VS Code</title><link>https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-deepseek-%D9%85%D8%AD%D9%84%D9%8A%D8%A7-%D8%B9%D9%84%D9%89-%D9%85%D8%AD%D8%B1%D8%B1-%D8%A7%D9%84%D8%A3%D9%83%D9%88%D8%A7%D8%AF-vs-code-r2542/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2025_03/DeepseekVSCode.png.e236c8636d2423100df5be91a7b7e5cf.png" /></p>
<p>
	يشهد عالم البرمجة اليوم تسارعًا رهيبًا، إذ يحتاج المطورون إلى أدوات فعالة تساعدهم في تحسين جودة الكود، واكتشاف الأخطاء، وتسريع عملية التطوير. عادةً ما يلجأ المبرمجون إلى البحث اليدوي أو مراجعة الأكواد بأنفسهم، مما يستهلك وقتًا طويلًا وقد يكون غير دقيق. لهذا السبب، فإن دمج تقنيات الذكاء الاصطناعي مع بيئات التطوير تحسن من تجربة البرمجة وزيادة الإنتاجية.
</p>

<p>
	يعتبر Deepseek أحد الحلول القوية في هذا المجال، إذ يمكنه تقديم المساعدة في كتابة الكود، وتصحيحه، واقتراح تحسينات ذكية. مع ذلك يشاع استخدامه خارجيًا وأثناء وصله بالإنترنت، وهذا قد يسبب بعض المشاكل الأمنية للمبرمجين. مع ذلك، هناك طريقة ستمكننا كمبرمجين من استخدامه محليًا داخل محرر الأكواد الذي نستعمله، ودون الحاجة لوصله بالانترنت.
</p>

<p>
	سنشرح في هذا المقال كيفية ربط محرر الأكواد VS Code بنموذج Deepseek الغني عن التعريف، لنحصل على تجربة برمجية أكثر سلاسة وكفاءة، مع الاستفادة من إمكانيات الذكاء الاصطناعي بطريقة آمنة ومتكاملة.
</p>

<h2 id="">
	متطلبات عملية الربط والتشغيل
</h2>

<p>
	لتنفيذ عملية الربط، سنحتاج إلى تحميل وضبط الأمور الآتية:
</p>

<ul>
	<li>
		<strong>تثبيت محرر الأكواد Visual Studio Code</strong>: يمكن تحميله من <a href="https://code.visualstudio.com/download" rel="external nofollow">الموقع الرسمي لمحرر VS Code</a>  واتباع خطوات التثبيت المعتادة لأي برنامج، وإن كان متاح لدينا فلا داعي للقيام بهذه الخطوة
	</li>
	<li>
		<strong>تحميل وتثبيت أولاما Ollama</strong><span>:</span> وهي أداة مخصصة لتشغيل نماذج الذكاء الاصطناعي محليًا
	</li>
	<li>
		<strong>تثبيت ديبسيك Deepseek</strong>: نحمله من Ollama، وسنحمل نموذج Deepseek-R1
	</li>
	<li>
		<strong>تثبيت إضافة Continue.Dev</strong>: لربط ديبسك مع محرر الأكواد VS Code
	</li>
</ul>

<h2 id="ollama">
	تثبيت أداة أولاما Ollama
</h2>

<p>
	ننزل أداة أولاما Ollama من <a href="https://ollama.com/" rel="external nofollow">الموقع الرسمي لها</a>، وفقًا لنظام التشغيل الخاص بنا، ثم نثبته.
</p>

<p style="text-align: center;">
	<img alt="تحميل أولاما Olaama.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="170294" data-ratio="44.57" data-unique="kqfsakokw" style="width: 700px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_04/Olaama.jpg.2a7fb8d48c0426c0c0a657e66b18e9db.jpg">
</p>

<p>
	نحمل النسخة التي تناسب حاسوبنا، ثم نثبّت البرنامج بالضغط على خيار التثبيت <strong>Install</strong> كما هو موضح بالصورة الآتية:
</p>

<p style="text-align: center;">
	<img alt="تثبيت أولاما Ollama.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="170293" data-ratio="47.43" data-unique="g34mc10yg" style="width: 700px; height: auto;" width="879" src="https://academy.hsoub.com/uploads/monthly_2025_04/Ollama.jpg.cf9fe9bad1dbc8ed24f4799132059193.jpg">
</p>

<h2 id="deepseek">
	تثبيت نموذج Deepseek
</h2>

<p>
	بعد تثبيت أولاما Ollama سنبقى ضمن نفس <a href="https://ollama.com/" rel="external nofollow">الموقع الرسمي لأولاما</a> ونحمل منه نموذج Deepseek-r1 إما عن طريق البحث عن اسم Deepseek من خيار البحث بالصفحة الأساسية لأولاما كما هو موضح بالصورة الآتية:
</p>

<p style="text-align: center;">
	<img alt="البحث عن نموذج Deepseek-r1 في أولاما Ollama.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="170267" data-ratio="54.33" data-unique="yrqmlnfah" style="width: 700px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_04/Deepseek-r1Ollama.jpg.61041bbef5f7a8a823e815c12fd21dd3.jpg">
</p>

<p>
	<strong>ملاحظة</strong><span>:</span> يمكننا الوصول إلى DeepSeek-R1 بطريقة أخرى أيضًا، من خلال العودة إلى نفس <a href="https://ollama.com" rel="external nofollow">الواجهة الرئيسية لأولاما</a> ثم الضغط على خيار DeepSeek-R1، لننتقل مباشرةً الى <a href="https://ollama.com/library/deepseek-r1" rel="external nofollow">DeepSeek-R1</a>.
</p>

<p>
	سنجد هنا العديد من خيارات النماذج لديبسيك Deepseek، نختار أيّ واحد نريده حسب مساحة المتوفرة لدينا في الحاسوب، ثم ننسخ التعليمة الموجودة كما هو موضح بالصورة:
</p>

<p style="text-align: center;">
	<img alt="اختيار نموذج لديبسيك Deepseek المناسب للحاسوب.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="170268" data-ratio="54.33" data-unique="7uqsm3gkm" style="width: 750px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_04/Deepseek.jpg.a3b85918aa53b9a5aaf182c9bdc5a0c6.jpg">
</p>

<p>
	في هذا الإعداد، اخترنا نموذج Deepseek 1.5b نظرًا لتوازنه بين الأداء الجيد والاستهلاك المعتدل للموارد، كما أنه لا يتطلب مساحة تخزين كبيرة، على عكس النماذج الأخرى التي تكون أكثر استهلاكًا للموارد. ومع ذلك، فإن اختيار النموذج الأمثل يعتمد على حجم المشروع وتعقيده، حيث أن المشاريع الصغيرة أو المتوسطة قد تستفيد من النماذج الخفيفة لتقليل استهلاك الموارد، بينما قد تتطلب المشاريع الكبيرة أو المعقدة، التي تحتاج إلى معالجة بيانات ضخمة أو فهم لغوي متقدم، استخدام نماذج أكبر ذات قدرات أعلى، حتى وإن كانت أكثر استهلاكًا للموارد.
</p>

<p>
	نضغط على خيار النسخ حيث يشير سهم الرقم 2 بالصورة أعلاه، ثم نتوجه إلى سطر الأوامر CMD بالحاسوب، ونلصق التعليمة <code>ollama run deepseek-r1:1.5b</code> التي نسخناها من الموقع ستظهر لنا الشاشة كالتالي:
</p>

<p style="text-align: center;">
	<img alt="لصق تعليمة ollama run deepseek-r1.1.5b.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="170274" data-ratio="54.33" data-unique="rhz514ddr" style="width: 700px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_04/ollamarundeepseek-r1.1_5b.jpg.e0bb3799c3bbcce99af90111241065f3.jpg">
</p>

<p>
	سوف نتأكد الآن من أن عملية تثبيت Deepseek-R1 قد تمت بنجاح من خلال طرح سؤال يستفسر عمن يكون، ونرى رده.
</p>

<p style="text-align: center;">
	<img alt="اختبار نجاح عملية تثبيت Deepseek-R1.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="170275" data-ratio="54.33" data-unique="xr503do5n" style="width: 700px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_04/Deepseek-R1.jpg.cf96032d450e432454f410e5a143bd38.jpg">
</p>

<p>
	حسب الرد الذي تحصلنا نكون قد تأكدنا من أن العملية تمت بنجاح
</p>

<h2 id="continuedev">
	تثبيت إضافة Continue.Dev
</h2>

<p>
	Continue.Dev هي إضافة مميزة متاحة على محرر الأكواد VSCode، تتيح التفاعل مع نماذج الذكاء الاصطناعي داخل بيئة التطوير، مما يسهل على المبرمجين تحسين الأكواد وتطويرها بكفاءة. سوف نرى خطوات تثبيت هذه الاضافة كالتالي:
</p>

<p>
	نفتح محرر الأكواد VS Code الذي ثبتناه وننتقل إلى متجر الإضافات، نكتب Continue ثم نختار الإضافة Continue - Codestral Claude, and more من بين الخيارات التي ستظهر معنا.
</p>

<p style="text-align: center;">
	<img alt="البحث عن إضافة Continue.Dev في محرر الأكواد VS Code.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="170278" data-ratio="54.33" data-unique="es4przlyl" style="width: 700px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_04/Continue.DevVSCode.jpg.8e4511c095bc3a7f3f1fcf4c64d5b898.jpg">
</p>

<p>
	نضغط الآن على خيار تثبيت Install وننتظر حتى يتم التثبيت.
</p>

<p style="text-align: center;">
	<img alt="تثبيت إضافة Continue.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="170269" data-ratio="54.33" data-unique="xvubcfxxj" style="width: 700px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_04/Continue.jpg.ff9c146e43c542363e4f48464cc6f17e.jpg">
</p>

<p>
	في هذه المرحلة ستظهر لدينا أيقونة الإضافة Continue على شريط المحرر كما هو موضح في الصورة الآتية:
</p>

<p style="text-align: center;">
	<img alt="أيقونة الإضافة Continue.Dev.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="170276" data-ratio="54.33" data-unique="0hm8dpkmf" style="width: 700px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_04/Continue_Dev.jpg.a2f41c64f031002a045575d0fce7441b.jpg">
</p>

<p>
	نبدأ الآن بضبط إعدادات الإضافة بالضغط على أيقونة الإعدادات ونفتح ملف configuration الخاص بالاضافة باتباع الخطوات الثلاث الموضحة بالصورة على التوالي:
</p>

<p style="text-align: center;">
	<img alt="الإعدادات configuration في إضافة Continue.Dev.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="170270" data-ratio="54.33" data-unique="zaw2mojlw" style="width: 700px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_04/configurationContinue_Dev.jpg.8b191e0721189ecd6d26b80fa90fca15.jpg">
</p>

<p>
	سنجد أن الإعدادات الافتراضية بملف الإعدادات configuration كالتالي:
</p>

<p style="text-align: center;">
	<img alt="ملف الإعدادات configuration في إضافة Continue.Dev.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="170277" data-ratio="54.33" data-unique="d791tcoor" style="width: 700px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_04/configurationContinue_Dev.jpg.0235c5b0050cdbd4ed7d1c13418732bd.jpg">
</p>

<p>
	ما علينا سوى ضبطها بما يتوافق مع النموذج المحمل معنا، وننسخ المعلومات الآتية واحدة واحدة إلى الكود المتاح بالملف، أو نستبدل الأجزاء التي تحتاج لتعديلات مباشرةً إلى الكود الآتي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_3286_47" style=""><span class="pln">  </span><span class="pun">]:</span><span class="pln"> </span><span class="str">"models"</span><span class="pln"> 
  </span><span class="pun">}</span><span class="pln">
     </span><span class="pun">,</span><span class="pln"> </span><span class="str">"title"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"DeepSeek Coder"</span><span class="pln">
     </span><span class="pun">,</span><span class="pln"> </span><span class="str">"model"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"deepseek-r1:1.5b"</span><span class="pln">
      </span><span class="str">"provider"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"ollama"</span><span class="pln">
   </span><span class="pun">{</span><span class="pln">
 </span><span class="pun">,</span><span class="pln"> </span><span class="pun">[</span><span class="pln">
 </span><span class="pun">}:</span><span class="pln">  </span><span class="str">"tabAutocompleteModel"</span><span class="pln"> 
   </span><span class="pun">,</span><span class="pln"> </span><span class="str">"title"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"Tab Autocomplete Model"</span><span class="pln">
</span><span class="pun">,</span><span class="pln">    </span><span class="str">"provider"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"ollama"</span><span class="pln">
    </span><span class="str">"model"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"deepseek-coder:1.5b-base"</span><span class="pln">
</span><span class="pun">,{</span></pre>

<p>
	كما توضح الصورة الآتية:
</p>

<p style="text-align: center;">
	<img alt="ضبط الإعدادات بملف الإعدادات configuration .jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="170285" data-ratio="54.33" data-unique="ke73qbaqq" style="width: 700px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_04/configuration.jpg.5cc07878e23f81c17a2208c3963a9d3e.jpg">
</p>

<p>
	<strong>ملاحظة</strong>: يجب أن يكون اسم النموذج في الاعدادات هو نفس النموذج الذي قمنا بتحميله كما هو موضح في الصورة و نتأكد من حفظ التعديلات.
</p>

<p>
	عند هذه المرحلة ستظهر لنا أداة Deepseek كما هو موضح في الصورة وبنفس الاسم الذي أطلقناه عليها DeepSeek Coder:
</p>

<p style="text-align: center;">
	<img alt="ظهور أداة DeepSeek Coder في محرر الأكواد VS Code.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="170271" data-ratio="54.33" data-unique="u4xjjxj3a" style="width: 700px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_04/DeepSeekCoderVSCode.jpg.19a84ebc294de21732dc5a1be269f9d2.jpg">
</p>

<p>
	للتأكد من ضبط الأمور، سنجرب تشغيل النموذج كالآتي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="JPG" data-fileid="169787" href="https://academy.hsoub.com/uploads/monthly_2025_03/20.JPG.5939550622f3fe9993ff2d701578a4fb.JPG" rel=""><img alt="اختبار تشغيل DeepSeek Coder في محرر الأكواد VS Code" class="ipsImage ipsImage_thumbnailed" data-fileid="169787" data-ratio="44.31" data-unique="cxxn89z8w" style="width: 700px; height: auto;" width="700" src="https://academy.hsoub.com/uploads/monthly_2025_03/20.thumb.JPG.ff4a37f1018581501ed311e06c9455a9.JPG"> </a>
</p>

<p>
	وبهذا سنقول عملية تثبيت ديبسيك Deepseek محليًا بمحرر فيجوال ستوديو كود VS Code قد اكتملت بنجاح. والآن سنبدأ باستخدامه واختبار جودته.
</p>

<h2 id="-1">
	تجربة تشغيل الكود
</h2>

<p>
	كما سبق ووضحنا، يمكن الاستفادة من ديبسيك في الأعمال البرمجية بأكثر من طريقة، وأول طريقة سنتحدث عنها ونجربها هي طلب كود منه.
</p>

<p>
	سنطلب من Deepseek كتابة كود برمجي لإنشاء متتالية فيبوناتشي للأعداد بين 0 و 100، ثم تشغيله على الـ Terminal في Visual Studio Code كالآتي:
</p>

<p style="text-align: center;">
	<img alt="تجربة تشغيل الكود في ديبسيك Deepseek.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="170279" data-ratio="54.33" data-unique="1raxd4o72" style="width: 700px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_04/Deepseek.jpg.bced4622a0189d6f42437bffa07d39e2.jpg">
</p>

<p>
	وكما هو واضح، لقد حصلنا على كود كامل متوافق مع المطلوب. لنقله إلى الكود الفعلي الذي نعمل عليه، سنضغط على أيقونة تطبيق الكود Apply، ليظهر الكود في الملف المقابل مباشرةً كما هو موضح في الصورة التالية:
</p>

<p style="text-align: center;">
	<img alt="نتيجة تجربة تشغيل الكود في ديبسيك Deepseek.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="170280" data-ratio="54.29" data-unique="2jhmpnman" style="width: 700px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_04/Deepseek.jpg.3cc1d01e5bb797a83895cb795a41f1f2.jpg"><img alt="نتيجة تجربة تشغيل الكود في ديبسيك Deepseek.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="170280" data-ratio="54.33" data-unique="ffigi0b89" style="width: 0px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_04/Deepseek.jpg.3cc1d01e5bb797a83895cb795a41f1f2.jpg">
</p>

<p>
	وعند اختبارنا للكود، ستظهر النتيجة بكل سهولة ودقة كما هو موضح بالصورة الآتية:
</p>

<p style="text-align: center;">
	<img alt="نتيجة اختبار تشغيل الكود في ديبسيك Deepseek.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="170286" data-ratio="54.33" data-unique="kzqjqq74y" style="width: 700px; height: 310px;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_04/Deepseek.jpg.d471f7811796bf933eb99df2f1010db8.jpg">
</p>

<h2 id="-2">
	تصحيح الأخطاء
</h2>

<p>
	سنجرب في هذه المرة إعطاء نموذج ديبسيك كود به بعض الأخطاء ونطلب منه تصحيحها. لنفترض أنه لدينا كود برمجي بلغة بايثون لحساب القاسم المشترك الأكبر لعددين صحيحين GCD، ونريد إيجاد الخطأ في الكود وبعد ذلك تصحيحه. الكود الخاطئ هو التالي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3286_60" style=""><span class="kwd">def</span><span class="pln"> pgcd</span><span class="pun">(</span><span class="pln">a</span><span class="pun">,</span><span class="pln"> b</span><span class="pun">):</span><span class="pln">
   </span><span class="str">"""حساب القاسم المشترك الأكبر لعددين باستخدام خوارزمية إقليدس"""</span><span class="pln">
   </span><span class="kwd">while</span><span class="pln"> b </span><span class="pun">!=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">:</span><span class="pln">
       a </span><span class="pun">=</span><span class="pln"> b         a </span><span class="pun">=</span><span class="pln"> b </span><span class="com"># خطأ في الحساب: لم يتم تحديث b بالقيمة الصحيحة</span><span class="pln">
       b </span><span class="pun">=</span><span class="pln"> a </span><span class="pun">%</span><span class="pln"> b      </span><span class="com"># سيؤدي ذلك إلى خطأ منطقي لأنه يستخدم a بعد تحديثه</span><span class="pln">
  </span><span class="kwd">return</span><span class="pln"> a             </span><span class="com"># خطأ في المسافة البادئة </span><span class="pln">

</span><span class="com"># الكود الرئيسي</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"احسب القاسم المشترك الأكبر"</span><span class="pun">)</span><span class="pln">
number1 </span><span class="pun">=</span><span class="pln"> int</span><span class="pun">(</span><span class="pln">input</span><span class="pun">(</span><span class="str">"ادخل الرقم الاول : "</span><span class="pun">))</span><span class="pln">
number2 </span><span class="pun">=</span><span class="pln"> int</span><span class="pun">(</span><span class="pln">input</span><span class="pun">(</span><span class="str">"ادخل الرقم الثاني : "</span><span class="pun">))</span><span class="pln">

result </span><span class="pun">=</span><span class="pln"> pgcd</span><span class="pun">(</span><span class="pln">number1</span><span class="pun">,</span><span class="pln"> number2</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pln"> </span><span class="pun">(</span><span class="pln">f</span><span class="str">"القاسم المشترك الأكبر بين {number1} و {number2} هو : {result}"</span><span class="pun">)</span></pre>

<p>
	الأخطاء الموجودة في الكود الذي سنشاركه بالمحرر ونسأل ديبسيك عن صحته هي كالتالي:
</p>

<ol>
	<li>
		<strong>خطأ في الحساب</strong><span>:</span>

		<ul style="margin-right: 40px;">
			<li>
				في الحلقة while، يجب تحديث a وb بالقيم الصحيحة (a, b = b, a % b)
			</li>
			<li>
				الكود الحالي يعيد تعيين a = b قبل استخدامه، مما يؤدي إلى حساب خاطئ. 
			</li>
		</ul>
	</li>
	<li>
		<strong>خطأ في المسافة البادئة</strong>:
	</li>
</ol>

<ul style="margin-right: 40px;">
	<li>
		return a ليس بمحاذاة while ويؤدي إلى خطأ عند التشغيل.
	</li>
</ul>

<p>
	سنرى الآن إن كان ديبسيك Deepseek سينتبه لها ويحلها أم لا. لفعل ذلك، سنفتح أولًا ملف الكود كالتالي كما هو موضح في الصورة:
</p>

<p style="text-align: center;">
	<img alt="تصحيح أخطاء الكود باستخدام Deepseek.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="170282" data-ratio="54.33" data-unique="hi01u5y8c" style="width: 700px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_04/Deepseek.jpg.022e3af06ebfa56abeccc0f6e9be432b.jpg">
</p>

<p>
	نعين الملف الذي نريد فتحه على محرر الأكواد فيجوال ستوديو كود، والذي سيفتح مباشرةً على محرر الأكواد Visual Studio Code بمجرد الضغط عليه وتعيينه. ما علينا سوى تحديد الكود الذي نريد اختباره، وسيظهر لنا اختصار لوحة المفاتيح Ctrl+L، نضغط عليه وسينتقل مباشرةً للدردشة مع Deepseek.
</p>

<p>
	سنوضح هذه الخطوة بالتفصيل في الصورة التالية:
</p>

<p style="text-align: center;">
	<img alt="اكتشاف الأخطاء الموجودة بالكود باستخدام Deepseek.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="170283" data-ratio="54.33" data-unique="cud0mbszg" style="width: 700px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_04/Deepseek.jpg.9d7f21d49c95e5e42946c1b881ccd175.jpg">
</p>

<p>
	نطلب من Deepseek تصحيح الأخطاء الموجودة بالكود المشارك معه، وسيعيد لنا النتيجة الآتية، وسنضغط على خيار Apply لتنفيذ التصحيح في الكود الموجود بالملف مباشرةً.
</p>

<p style="text-align: center;">
	<img alt="كيفية تصحيح الأخطاء الموجودة بالكود البرمجي عبر Deepseek.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="170284" data-ratio="54.33" data-unique="c95wk7nzl" style="width: 700px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_04/Deepseek.jpg.787a1adb089db5bb77e3f421176977d2.jpg">
</p>

<p>
	وكما نلاحظ، لقد صحح دييبسيك الخطأين المتعمّدين اللذين تحدثنا عنهما بالأعلى، والعملية تمت بنجاح
</p>

<p style="text-align: center;">
	<img alt="تصحيح الأخطاء عبر Deepseek.jpeg" class="ipsImage ipsImage_thumbnailed" data-fileid="170281" data-ratio="54.33" data-unique="6fhufekqk" style="width: 700px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_04/Deepseek.jpeg.52fa38e66e357de418dac3cd660f3d91.jpeg">
</p>

<h2 id="deepseek-1">
	أمان الكود و البيانات و استراتيجيات الحماية في ظل استخدام Deepseek
</h2>

<p>
	في ظل استخدام نماذج الذكاء الاصطناعي مثل Deepseek، يصبح تأمين الكود والبيانات أمرًا بالغ الأهمية، إذ قد يكون هناك خطر تسرب بيانات شخصية إذا لم يتم تشفير المدخلات والمخرجات كما يجب. ولهذا السبب سنوضح في ما يلي بعض التدابير لحماية البيانات في ظل استخدام Deepseek
</p>

<h3 id="-3">
	تعطيل تسجيل المدخلات الحساسة
</h3>

<p>
	يجب أن نتأكد من عدم تسجيل المدخلات التي تحتوي على بيانات حساسة، على سبيل المثال :
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3286_70" style=""><span class="kwd">import</span><span class="pln"> os

sensitive_data </span><span class="pun">=</span><span class="pln"> </span><span class="str">"1234-5678-9012-3456"</span><span class="pln">      </span><span class="com">#  بيانات حساسة مثل رقم بطاقة على سبيل المثال</span><span class="pln">
os</span><span class="pun">.</span><span class="pln">environ</span><span class="pun">[</span><span class="str">"SENSITIVE_INFO"</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> sensitive_data  </span><span class="com"># تخزينها كمتغير بيئي بدلاً من ملف</span></pre>

<h3 id="-4">
	منع إرسال البيانات عبر الإنترنت
</h3>

<p>
	نتأكد من أن Deepseek لا يرسل البيانات إلى الإنترنت. ويمكننا حظر اتصالات الشبكة عبر الجدار الناري للحماية Firewall باستخدام Windows Defender Firewall بجهاز الحاسوب الخاص بنا في حال استخدام نظام ويندوز، أو استخدام جدران الحماية المدمجة في أنظمة التشغيل الأخرى في حال استخدام أنظمة أخرى، مثل جدار pf على macOS وجدار UFW Uncomplicated Firewall على Linux.
</p>

<p>
	<strong>ملاحظة</strong>: تجدر الإشارة إلى أن Deepseek عند وصله بفيجوال ستوديو كود سيعمل داخل محرر الأكواد فقط ولا يمتلك صلاحيات للوصول إلى الملفات أو البيانات خارج بيئة التطوير، مع ذلك الخطوات التي نقوم بها هي من أجل أخذ الحيطة لا أكثر.
</p>

<h2 id="deepseekvs">
	إيقاف تشغيل Deepseek في محرر الأكواد VS : الإيقاف المؤقت و الإيقاف الكلي
</h2>

<p>
	في مرحلة ما، قد نحتاج أو نرغب في إيقاف تشغيل Deepseek R1 في Visual Studio Code، وهنا علينا اتباع الخطوات الآتية حسب طبيعة الإيقاف الذي نرغب به
</p>

<h3 id="-5">
	الإيقاف المؤقت
</h3>

<p>
	من أجل إيقاف عمل ديب سيك مؤقتا بمحرر الأكواد VS Code، سنكتفي بفصله عن الرابط بينه وبين المحرر، وسنبحث عن أداة continue في Extensions ثم نضغط على خيار الإيقاف المؤقت Disable كما هو موضح كالتالي:
</p>

<p style="text-align: center;">
	<img alt="الإيقاف المؤقت لعمل ديبسيك في محرر الأكواد.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="170272" data-ratio="54.33" data-unique="6iyt9zukr" style="width: 700px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_04/1732050919_.jpg.827b3e7fdd9158e13d789125784a6766.jpg">
</p>

<h3 id="-6">
	الإيقاف النهائي
</h3>

<p>
	من أجل التوقف كليًا عن استخدام ديبسيك في محرر أكوادنا، سنضغط على خيار إزالة التثبيت Uninstall بدلا من خيار Disable.
</p>

<p style="text-align: center;">
	<img alt="إلغاء تثبيت إضافة Continue.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="170273" data-ratio="54.33" data-unique="ajhkotxed" style="width: 700px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_04/Continue.jpg.2df9d624082b9ac3b6abe673f8e304a4.jpg">
</p>

<p>
	بعد ذلك نزيل Ollama كليا من إعدادات جهاز الحاسوب بحذف تثبيته أيضًا بالضغط على خيار Uninstall.
</p>

<p style="text-align: center;">
	<img alt="إلغاء تثبيت أولاما Ollama من الحاسوب.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="170292" data-ratio="54.33" data-unique="3duvq00zt" style="width: 700px; height: 415px;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_04/Ollama.jpg.0a641d74ef738ee675d4eb914130b1d9.jpg">
</p>

<p>
	<strong>ملاحظة</strong>: بمجرد إزالة اولا ما يتوقف تشغيل Deepseek تلقائيا.
</p>

<h2 id="-7">
	الخاتمة
</h2>

<p>
	إلى هنا نصل الى نهاية مقالنا، الذي وضحنا فيه كيفية تشغيل نموذج الذكاء الاصطناعي Deepseek على محرر الأكواد VS Code، للحصول على تجربة سهلة وسريعة ومرنة خلال عملنا البرمجي، مما يساعدنا في تسريع ورفع كفاءة تصحيح الأخطاء، واقتراح حلول ذكية، وتوليد أكواد متوافقة مع المعايير الحديثة.
</p>

<h2 id="-8">
	المصادر
</h2>

<ul>
	<li>
		<a href="https://janusai.pro/ar/how-to-install-and-use-deepseek-r1-on-your-local-computer/" rel="external nofollow">كيفية تثبيت DeepSeek R1 واستخدامه على حاسوبك المحلي</a>
	</li>
	<li>
		<a href="https://www.youtube.com/watch?v=cqFRE9c8048&amp;t=309s" rel="external nofollow">How to use Deepseekk-R1 for free in Visual Studio Code</a>
	</li>
</ul>

<h2 id="-9">
	اقرأ أيضًا
</h2>

<ul>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AF%D9%85%D8%AC-%D9%85%D8%B3%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-github-copilot-%D9%85%D8%B9-%D9%85%D8%AD%D8%B1%D8%B1-%D8%A7%D9%84%D8%A3%D9%83%D9%88%D8%A7%D8%AF-vs-code-r2521/" rel="">دمج مساعد الذكاء الاصطناعي GitHub Copilot مع محرر الأكواد VS Code</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/general/%D8%A3%D8%B4%D9%87%D8%B1-%D8%A5%D8%B6%D8%A7%D9%81%D8%A7%D8%AA-visual-studio-code-r2069/" rel="">أشهر إضافات Visual Studio Code</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-%D9%84%D9%83%D8%AA%D8%A7%D8%A8%D8%A9-%D9%88%D8%AA%D8%B5%D8%AD%D9%8A%D8%AD-%D8%A3%D9%83%D9%88%D8%A7%D8%AF-css-r2531/" rel="">استخدام الذكاء الاصطناعي لكتابة وتصحيح أكواد CSS</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">2542</guid><pubDate>Tue, 25 Mar 2025 12:04:00 +0000</pubDate></item><item><title>&#x62A;&#x639;&#x631;&#x641; &#x639;&#x644;&#x649; &#x62F;&#x648;&#x627;&#x644; &#x627;&#x644;&#x62E;&#x633;&#x627;&#x631;&#x629; Loss Functions &#x641;&#x64A; &#x628;&#x627;&#x64A; &#x62A;&#x648;&#x631;&#x634; PyTorch</title><link>https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D8%AF%D9%88%D8%A7%D9%84-%D8%A7%D9%84%D8%AE%D8%B3%D8%A7%D8%B1%D8%A9-loss-functions-%D9%81%D9%8A-%D8%A8%D8%A7%D9%8A-%D8%AA%D9%88%D8%B1%D8%B4-pytorch-r2539/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2025_03/89417460_.jpg.26a5beb7cfab120745d4d5f82183d0e2.jpg" /></p>
<p>
	يعد مفهوم دوال الخسارة Loss Functions أساسيًا في تدريب نماذج تعلم الآلة، فلا توجد طريقة لتحفيز النموذج على التخمين بشكل صحيح بدون استخدام دالة خسارة، ويمكن أن نعرّف دالة الخسارة على أنها دالة رياضية تستخدم لقياس أداء النموذج في تنفيذ مهمة على مجموعة بيانات محددة، ومن خلال معرفة أداء النموذج على مجموعة بيانات محددة سنحصل على نظرة عامة تمكننا من اتخاذ قرارات خلال عملية التدريب كاستخدام نموذج أقوى أو حتى تغير دالة الخسارة المستخدمة لنوع آخر.
</p>

<p>
	سنستكشف في هذه المقالة دوال الخسارة المختلفة في باي تورش PyTorch. وكيف يتيح باي تورش للمستخدمين استخدام دوال الخسارة المطورة مسبقًا، أو بناء دالة خسارة مخصصة وأمثلة عملية توضح كيفية عملها.
</p>

<h2 id="">
	متطلبات المقال
</h2>

<p>
	يتطلب فهم هذا المقال فهمًا جيدًا <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A7%D9%84%D9%85%D9%81%D8%A7%D9%87%D9%8A%D9%85-%D8%A7%D9%84%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A9-%D9%84%D8%AA%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%A2%D9%84%D8%A9-r1009/#%D8%A7%D9%84%D8%B4%D8%A8%D9%83%D8%A7%D8%AA-%D8%A7%D9%84%D8%B9%D8%B5%D8%A8%D9%8A%D8%A9" rel="">للشبكات العصبية الاصطناعية</a> المكونة من طبقات متصلة تحتوي كل طبقة على عدد من العقد التي تسمى عصبون neuron. حيث تتعلم هذه الشبكات وتخمن القيم من خلال عملية التدريب training وتُضبط فيها الأوزان weights ومقدار الانحياز biases وهي معاملات تتحكم في درجة قوة التواصل بين العقد المختلفة، وهي تحاكي في طريقة عملها الخلايا العصبية الطبيعية.
</p>

<p>
	ولفهم الشبكات العصبية بشكل متعمق نحتاج لمعرفة أنواع الطبقات المختلفة وهي: طبقة المدخلات input layer والطبقة المخفية hidden layer وطبقة المخرجات output layer، ومعرفة بدوال التنشيط activation functions وخوارزميات التحسين optimization algorithms مثل الانحدار المتدرج gradient descent ودوال الخسارة وغيرها.
</p>

<p>
	كما يحتاج فهم المقال للإلمام بأساسيات لغة <a href="https://academy.hsoub.com/programming/python/%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-%D9%84%D8%BA%D8%A9-%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-python-r2325/" rel="">بايثون Python</a> والتعامل مع إطار عمل <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D8%A5%D8%B7%D8%A7%D8%B1-%D8%B9%D9%85%D9%84-%D8%A8%D8%A7%D9%8A-%D8%AA%D9%88%D8%B1%D8%B4-pytorch-%D9%88%D8%A3%D9%87%D9%85%D9%8A%D8%AA%D9%87-%D9%84%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-r2311/" rel="">باي تورش PyTorch</a> لفهم الأكواد المكتوبة.
</p>

<h2 id="lossfunctions">
	ما هي دوال الخسارة Loss Functions
</h2>

<p>
	تستخدم دوال الخسارة بشكل أساسي لتقييم أداء نموذج تعلم الآلة في تنفيذ مهمة على مجموعة بيانات محددة، فهي تحسب الفرق بين القيمة الحقيقية الصحيحة <code>Y</code> وبين القيمة المتوقعة <code>^Y</code>، فعندما يخمن نموذج قيم قريبة جدًا من القيم الفعلية في كل من مجموعة بيانات التدريب ومجموعة بيانات الاختبار فهذا يعني أن النموذج موثوق ويُعتمد عليه.
</p>

<p>
	فدوال الخسارة loss functions توفر لنا معلومات مفيدة عن أداء النموذج، ولكن هذا ليس الدور الوحيد لدالة الخسارة، فهناك طرق أخرى أكثر موثوقية لتقييم النماذج مثل الصحة accuracy أو F-scores. في حين تبرز أهمية دوال الخسارة loss functions بشكل أساسي خلال عملية التدريب، وتساعدنا على دفع أوزان ومعاملات النموذج في الاتجاه الذي يقلل من الخسارة. وتقليل الخسارة يعني بالضرورة زيادة احتمالية التخمين الصحيح للقيم بواسطة نموذج تعلم الآلة، وهذا التحسن في التخمين ليس ممكنًا بدون استخدام دالة خسارة.
</p>

<p>
	تختلف أنواع دوال الخسارة loss functions باختلاف المشكلة التي نحاول حلها، حيث تصمم كل دالة بعناية لضمان تدفق التصحيح التدريجي gradient flow المناسب خلال عملية التدريب، ولكن من المهم معرفة دورها في عملية التدريب والتحسن المستمر.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169694" href="https://academy.hsoub.com/uploads/monthly_2025_03/loosediagram.png.6b979128cc8817f7a1af3856db7269cb.png" rel=""><img alt="مخطط تدريب نموذج تعلم الآلة" class="ipsImage ipsImage_thumbnailed" data-fileid="169694" data-ratio="71.25" data-unique="1ow008o6q" style="width: 400px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_03/loosediagram.thumb.png.b6444fbaebaf6b08094ba24ad3dc3f9c.png"></a>
</p>

<p>
	قد يصعب فهم الرموز الرياضية المعبرة عن معادلات الخسارة loss functions، حيث يتملص بعض المطورين من محاولة فهم هذه المعادلات الرياضية ويتعاملون معها على أنها صندوق أسود مجهول التفاصيل، ولكن فهم ما بداخل هذا الصندوق يعزز فهم دوال الخسارة ويساعدنا على تحديد الدالة الأفضل،  سنشرح في الفقرات التالية أشهر دوال الخسارة في باي تورش، ولكن قبل هذا لنرى أين نضع هذا الصندوق، وكيف نستخدم دوال الخسارة في باي تورش؟
</p>

<h2 id="lossfunctionspytorch">
	دوال الخسارة في باي تورش PyTorch
</h2>

<p>
	يأتي باي تورش PyTorch معززًا بالكثير من دوال الخسارة الأساسية سهلة الاستخدام، وتُجمع كافة دوال الخسارة في وحدة برمجية واحدة باسم nn module والتي تُعدّ الوحدة الأساسية لبناء الشبكات العصبية الاصطناعية ANNs في بايتورش.
</p>

<p>
	يمكن إضافة دالة خسارة loss function للكود الخاص بنا بسهولة كتابة سطر برمجي واحد. لننظر معًا للمثال التالي لإضافة دالة خسارة متوسط مربع الخطأ Mean Squared Error loss function -أو MSE اختصارًا- في باي تورش PyTorch.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_6292_9" style=""><span class="kwd">import</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">nn </span><span class="kwd">as</span><span class="pln"> nn
MSE_loss_fn </span><span class="pun">=</span><span class="pln"> nn</span><span class="pun">.</span><span class="typ">MSELoss</span><span class="pun">()</span></pre>

<p>
	تستخدم هذه الدالة في حساب الفرق بين قيم التخمينات والقيم الفعلية بالتنسيق التالي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_6292_11" style=""><span class="com">#predicted_value هو التخمين القادم من الشبكة العصبية </span><span class="pln">
</span><span class="com">#target القيم الفعلية الموجودة في مجموعة البيانات</span><span class="pln">
</span><span class="com">#loss_value الخسارة بين قيمة التخمين والقيمة الفعلية</span><span class="pln">
</span><span class="typ">Loss_value</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> MSE_loss_fn</span><span class="pun">(</span><span class="pln">predicted_value</span><span class="pun">,</span><span class="pln"> target</span><span class="pun">)</span></pre>

<p>
	بعد أن كونا فكرة أولية عن طريقة عمل دوال الخسارة في باي تورش PyTorch، لنتعمق أكثر في كواليس عمل عدد من هذه الدوال.
</p>

<h2 id="pytorch">
	دوال الخسارة في باي تورش PyTorch
</h2>

<p>
	تقع معظم دوال الخسارة  في باي تورش PyTorch تحت واحدة من التصنيفات الثلاثة التالية:
</p>

<ul>
	<li>
		دوال خسارة الانحدار regression loss functions
	</li>
	<li>
		دوال خسارة التصنيف classification loss functions
	</li>
	<li>
		دوال خسارة الترتيب ranking loss functions
	</li>
</ul>

<p>
	تهتم دوال خسارة الانحدار regression loss functions بالقيم والمتغيرات المستمرة continuous وهي المتغيرات التي يمكنها أن تأخذ عددًا لا نهائيًا من القيم بين رقمين، وأحد الأمثلة على هذا النوع من المتغيرات هو الأسعار، فمثلًا هل يمكن إحصاء كل الأسعار الممكنة للمنازل في منطقتنا؟ بالطبع لا ولكن يمكننا حصرها في نطاق عددي.
</p>

<p>
	تتعامل دوال خسارة التصنيف classification loss functions مع المتغيرات والقيم المتقطعة أو المنفصلة discrete، ومثال على هذا النوع من المهام عندما تحاول تميز كائن على أنه أحد التصنيفات المحددة ولتكن صندوق أو قلم أو زجاجة.
</p>

<p>
	تتوقع دوال خسارة الترتيب ranking loss functions المسافة النسبية بين القيم، وأحد التطبيقات عليها سيكون التوثيق من خلال صورة الوجه حيث نريد أن نعرف هوية صاحب الوجه بمقارنة صورته بعدد من الصور المعلومة هويتها لدينا وترتيبها حسب درجة التشابه، فالصور التي تنتمي لهذا الشخص يفترض أن تتشابه معه بنسبة كبيرة أكثر من تلك التي لأشخاص آخرين.
</p>

<h3 id="meanabsoluteerrorl1">
	دالة متوسط الخطأ المطلق Mean Absolute Error أو دالة الخسارة L1
</h3>

<p>
	تحسب دالة خسارة متوسط الخطأ المطلق MAE متوسط المجموع المطلق للفروق بين قيم التخمينات والقيم الفعلية. فتحسب أولًا الفرق بين قيمة التخمين والقيمة الفعلية عند كل عنصر في الموتر tensor، ونراكم المجموع المطلق لهذه الفروق التي حصلنا عليها في الخطوة السابقة، وفي النهاية نحسب متوسط هذا المجموع التراكمي بقسمته على العدد الكلي لتخمينات النموذج ونقارنها بالقيم الفعلية، للحصول على متوسط الخطأ المطلق MAE، وتعتبر دالة الخسارة هذه موثوقة للغاية في التعامل مع التشويش noise في البيانات. وتعرف هذه الدالة بمسمى آخر وهو دالة L1.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169696" href="https://academy.hsoub.com/uploads/monthly_2025_03/MAE.png.b2b5b42e2ffe05d185e6bdc708d526fe.png" rel=""><img alt="دالة متوسط الخطأ المطلق" class="ipsImage ipsImage_thumbnailed" data-fileid="169696" data-ratio="48.00" data-unique="dwof2x8tv" style="width: 280px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_03/MAE.thumb.png.c701e6b183dd702965ca5ff8a96ef14a.png"></a>
</p>

<p>
	وفيما يلي كود برمجي يُعرّف ويستخدم دالة خسارة من نوع MAE  أو L1:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3705_7" style=""><span class="kwd">import</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">nn </span><span class="kwd">as</span><span class="pln"> nn

</span><span class="com">#size_average &amp; reduce are deprecated</span><span class="pln">
</span><span class="com"># لا يوصى باستخدامهما فمن المحتمل تغيرهما في النسخ المستقبلية</span><span class="pln">

</span><span class="com">#reduction تحدد العملية التي ستحسب بعد حساب الفروق المطلقة لكل القيم</span><span class="pln">
</span><span class="str">'''
`none` 
 tensor تعني أننا لن نقوم بأي عملية على الفروق المطلقة وسنخرجها كتنسور
`sum` 
سنجمع جميع الفروق المطلقة لكل القيم دون أخذ المتوسط
`mean` القيمة الافتراضية لهذا المعامل
سنجمع جميع الفروق المطلقة ونأخذ متوسطها بقسمة المجموع على عدد العناصر في المخرجات

'''</span><span class="pln">

</span><span class="typ">Loss_fn</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> nn</span><span class="pun">.</span><span class="pln">L1Loss</span><span class="pun">(</span><span class="pln">size_average</span><span class="pun">=</span><span class="kwd">None</span><span class="pun">,</span><span class="pln"> reduce</span><span class="pun">=</span><span class="kwd">None</span><span class="pun">,</span><span class="pln"> reduction</span><span class="pun">=</span><span class="str">'mean'</span><span class="pun">)</span><span class="pln">

input </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="lit">5</span><span class="pun">,</span><span class="pln"> requires_grad</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
target </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="lit">5</span><span class="pun">)</span><span class="pln">
output </span><span class="pun">=</span><span class="pln"> loss_fn</span><span class="pun">(</span><span class="pln">input</span><span class="pun">,</span><span class="pln"> target</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">output</span><span class="pun">)</span><span class="pln"> </span><span class="com">#tensor(0.7772, grad_fn=&lt;L1LossBackward&gt;)</span></pre>

<h3 id="meansquarederror">
	متوسط مربع الخطأ Mean Squared Error
</h3>

<p>
	يتشابه متوسط مربع الخطأ MSE مع متوسط الخطأ المطلق MAE، لكن الفرق بينهما هو أن MSE يحسب مربع الفرق بين القيم المتوقعة والحقيقية، بينما يحسب MAE القيمة المطلقة للفرق. وبسبب وجود التربيع في MSE، تعطي هذه الدالة وزنًا أكبر للأخطاء الكبيرة، وهي أكثر حساسية للقيم الشاذة أو الضوضاء في البيانات مقارنة بالدالة MAE الأقل حساسية للقيم الشاذة لأنها لا تضخم الأخطاء الكبيرة بنفس الطريقة.
</p>

<p>
	ويعد متوسط مربع الخطأ المطلق المعيار الثاني Second norm أو L2 ويعرف أيضًا بالمعيار الإقليدي Euclidean norm أو المسافة الإقليدية، وهو نفس القانون المعروف لحساب المسافة بين نقطتين في الإحداثيات.
</p>

<p style="text-align: center;">
	<img alt="دالة متوسط مربع الخطأ" class="ipsImage ipsImage_thumbnailed" data-fileid="169695" data-ratio="47.00" data-unique="3wn9qknfv" style="width: 280px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_03/MSE.png.3f8a546fb49b3f00ef4ff31abd6ad9ed.png">
</p>

<p>
	فيما يلي كود برمجي يُعرّف ويستخدم دالة خسارة من نوع MSE أو L2:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_6292_16" style=""><span class="kwd">import</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">nn </span><span class="kwd">as</span><span class="pln"> nn

loss </span><span class="pun">=</span><span class="pln"> nn</span><span class="pun">.</span><span class="typ">MSELoss</span><span class="pun">(</span><span class="pln">size_average</span><span class="pun">=</span><span class="kwd">None</span><span class="pun">,</span><span class="pln"> reduce</span><span class="pun">=</span><span class="kwd">None</span><span class="pun">,</span><span class="pln"> reduction</span><span class="pun">=</span><span class="str">'mean'</span><span class="pun">)</span><span class="pln">
</span><span class="com">#ينطبق نفس الشرح السابق عن هذه المعاملات</span><span class="pln">

input </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="lit">5</span><span class="pun">,</span><span class="pln"> requires_grad</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
target </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="lit">5</span><span class="pun">)</span><span class="pln">
output </span><span class="pun">=</span><span class="pln"> loss</span><span class="pun">(</span><span class="pln">input</span><span class="pun">,</span><span class="pln"> target</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">output</span><span class="pun">)</span><span class="pln"> </span><span class="com">#tensor(0.9823, grad_fn=&lt;MseLossBackward&gt;)</span></pre>

<h3 id="crossentropyloss">
	خسارة الإنتروبيا المتقاطعة Cross-Entropy Loss
</h3>

<p>
	تستخدم دالة خسارة الإنتروبيا المتقاطعة Cross Entropy في مسائل <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B5%D9%86%D9%8A%D9%81-%D8%A7%D9%84%D8%B4%D8%AE%D8%B5%D9%8A%D8%A7%D8%AA-%D8%A8%D8%A7%D9%84%D8%A7%D8%B9%D8%AA%D9%85%D8%A7%D8%AF-%D8%B9%D9%84%D9%89-%D8%AA%D8%BA%D8%B1%D9%8A%D8%AF%D8%A7%D8%AA%D9%87%D9%85-%D8%A7%D9%84%D8%B9%D8%B1%D8%A8%D9%8A%D8%A9-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%B9%D9%85%D9%8A%D9%82-r1630/" rel="">التصنيف classification</a> والتي تتعامل مع تصنفيات محددة ومعدودة لقياس الفرق بين التوزيع الحقيقي للفئات والتوزيع الذي يتنبأ به النموذج. فتقيس الفرق بين توزيع الاحتماليات لكل مجموعة معطاة من المتغيرات العشوائية، ويغلب استخدام دالة <code>softmax</code> كطبقة المخرجات عند استخدم الإنتروبيا المتقاطعة كدالة خسارة، حيث تحوّل دالة <code>softmax</code> القيم الداخلة في المتجه أو التنسور tensor لتكون بين الصفر والواحد، ومجموع العناصر الخارجة ليساوي الواحد لتحقق شروط الاحتمالات، وتبقى القيمة العظمى في المتجه هي القيمة الأكبر بعد تطبيق الدالة.
</p>

<p>
	وبالمقارنة مع دالة <code>hardmax</code> التي تستخرج القيمة العظمى من متجه وتُعيّنها إلى 1، بينما تتجاهل باقي العناصر وتحواها إلى 0  فإن دالة <code>softmax</code> تحافظ على المعلومات النسبية لجميع القيم، مما يجعلها مناسبة أكثر لترتيب الاحتمالات فهي تعطي قيمًا احتمالية لكل تصنيف. وتتكون دالة <code>softmax</code> من جزأين الأول هو عدد أويلر <code>e</code> مرفوعًا لأس قيمة التخمين لتصنيف معين في المتجه حيث يمثل كل عنصر أحد التصنيفات المحددة.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169675" href="https://academy.hsoub.com/uploads/monthly_2025_03/exp_i.png.1d6446aedd713db7531f934870af7663.png" rel=""><img alt="exp i" class="ipsImage ipsImage_thumbnailed" data-fileid="169675" data-ratio="68.00" data-unique="a3lb2ybj9" style="width: 200px; height: auto;" width="300" src="https://academy.hsoub.com/uploads/monthly_2025_03/exp_i.thumb.png.e20633447f88ef79fccf5544ad9ce9ce.png"> </a>
</p>

<p>
	حيث أن <code>y_i</code> هي خرج من الشبكة العصبية الاصطناعية لتصنيف معين، وتعطينا هذه الدالة رقمًا قريبًا من الصفر ولكنه لا يكون أبدًا مساويًا للصفر، وتقترب قيمة الدالة من الواحد عندما تكون <code>y_i</code> قيمة كبيرة سالبة، وعندما تكون قيمة كبيرة موجبة تعطي الدالة رقمًا موجبًا كبيرًا، كما نلاحظ في المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_6292_24" style=""><span class="kwd">import</span><span class="pln"> numpy </span><span class="kwd">as</span><span class="pln"> np

np</span><span class="pun">.</span><span class="pln">exp</span><span class="pun">(</span><span class="lit">34</span><span class="pun">)</span><span class="pln"> </span><span class="com">#583461742527454.9</span><span class="pln">
np</span><span class="pun">.</span><span class="pln">exp</span><span class="pun">(-</span><span class="lit">34</span><span class="pun">)</span><span class="pln"> </span><span class="com">#1.713908431542013e-15</span></pre>

<p>
	أما الجزء الثاني من الدالة فهو عملية توحيد normalization حيث تضمن هذه الخطوة أن دالة <code>softmax</code> تعطي دائمًا قيمة احتمالات بين الصفر والواحد. توضح الصورة التالية الخطوات التي قمنا بها:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169685" href="https://academy.hsoub.com/uploads/monthly_2025_03/softmax_parts.png.44d5592a9e16a66bc02af27997265dd7.png" rel=""><img alt="softmax parts" class="ipsImage ipsImage_thumbnailed" data-fileid="169685" data-ratio="56.33" data-unique="oss1whv41" style="width: 400px; height: auto;" width="300" src="https://academy.hsoub.com/uploads/monthly_2025_03/softmax_parts.thumb.png.e537f65abf5467dc56023e5603735df9.png"> </a>
</p>

<p>
	ويمكننا جمع الخطوات في معادلة واحدة تعبر عن استخدامنا لدالة <code>softmax</code> لتحول متجه المخرجات لاحتمالات كل تصنيف، مثلًا في مهمة التمييز بين صور القطط والكلاب قد يكون احتمال كون الصورة المدخلة للشبكة العصبية قطة هو <code>0.80</code> بينما احتمال أن تكون الصورة لكلب <code>0.20</code> مما يسهل علينا فهم التصنيفات بشكل احتمالات قابلة للترتيب.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169698" href="https://academy.hsoub.com/uploads/monthly_2025_03/softmax.png.330f363029ba317277f4ccded03ce943.png" rel=""><img alt="softmax " class="ipsImage ipsImage_thumbnailed" data-fileid="169698" data-ratio="38.33" data-unique="txhuegw8a" style="width: 300px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_03/softmax.thumb.png.2a55cf04bce61d9f801f2a4d00a94026.png"></a>
</p>

<p>
	يجمع باي تورش في الوحدة <code>nn</code> كلًا من الإنتروبيا المتقاطعة Cross-entropy و احتمالية اللوغاريتم السالب Negative Log-Likelihood لدالة <code>softmax</code> في دالة خسارة واحدة.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169684" href="https://academy.hsoub.com/uploads/monthly_2025_03/softmax_cross_entropy.png.f3320972b2bc79cf520c7ebf92833d91.png" rel=""><img alt="softmax cross entropy" class="ipsImage ipsImage_thumbnailed" data-fileid="169684" data-ratio="56.33" data-unique="90bkq9imu" style="width: 450px; height: auto;" width="300" src="https://academy.hsoub.com/uploads/monthly_2025_03/softmax_cross_entropy.thumb.png.13411d15e374f8baf658a2eca33ec8f1.png"> </a>
</p>

<h3 id="negativeloglikelihoodnllloss">
	دالة خسارة احتمالية اللوغاريتم السالب
</h3>

<p>
	تعمل دالة خسارة احتمالية اللوغاريتم السالب Negative Log-Likelihood loss -أو NLL اختصارًا- بشكل مشابه لدالة خسارة الإنتروبيا المتقاطعة Cross-Entropy، وكما ذكرنا سابقًا تجمع دالة الإنتروبيا المتقاطعة CE طبقة لوغاريتم الدالة العظمى الناعمة log-softmax مع احتمالية اللوغاريتم السالب NLL من أجل حساب قيمة خسارة الإنتوربية المتقاطعة. ويعني هذا أنه يمكننا الحصول على قيمة خسارة الإنتروبيا المتقاطعة CE باستخدام احتمالية اللوغاريتم السالب NLL بجعل الطبقة الأخيرة من الشبكة العصبية طبقة log-softmax بدلًا من دالة <code>softmax</code> التقليدية.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169680" href="https://academy.hsoub.com/uploads/monthly_2025_03/NLL.png.3a9a3909abca46ee97f453fc0844f7f1.png" rel=""><img alt="nll" class="ipsImage ipsImage_thumbnailed" data-fileid="169680" data-ratio="56.25" data-unique="jwbscm2yq" style="width: 400px; height: auto;" width="400" src="https://academy.hsoub.com/uploads/monthly_2025_03/NLL.thumb.png.eb0bd3a7aeb1450ec6ac9c7937bdffae.png"> </a>
</p>

<p>
	وفيما يلي كود برمجي ينجز تصنيف متعدد الفئات Multi-class Classification باستخدام الدالة <code>softmax</code> و <code>NLL</code><span>:</span>
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_9316_7" style=""><span class="pln">m </span><span class="pun">=</span><span class="pln"> nn</span><span class="pun">.</span><span class="typ">LogSoftmax</span><span class="pun">(</span><span class="pln">dim</span><span class="pun">=</span><span class="lit">1</span><span class="pun">)</span><span class="pln">
loss </span><span class="pun">=</span><span class="pln"> nn</span><span class="pun">.</span><span class="typ">NLLLoss</span><span class="pun">()</span><span class="pln">
</span><span class="com"># أبعاد المدخلات</span><span class="pln">
</span><span class="com">#  N x C = 3 x 5</span><span class="pln">
input </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="lit">5</span><span class="pun">,</span><span class="pln"> requires_grad</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
</span><span class="com"># يجب أن تكون قيمة كل عنصر في تنسور الهدف أو القيم الفعلية أحد التصنيفات المحددة بالفعل</span><span class="pln">
</span><span class="com">#  0 &lt;= value &lt; C</span><span class="pln">
</span><span class="com"># C ---&gt; يعبر عن آخر تصنيف اعتبارًا أن أول تصنيف سنرمز له بالصفر </span><span class="pln">
target </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">tensor</span><span class="pun">([</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">4</span><span class="pun">])</span><span class="pln">
</span><span class="com"># المخرجات وهنا نطبق دالة لوغاريتم دالة القيمة العظمي على المدخلات</span><span class="pln">
</span><span class="com"># ثم نحسب مقدار الخسارة بين بينها وبين متجه الهدف أو القيم الفعلية</span><span class="pln">
output </span><span class="pun">=</span><span class="pln"> loss</span><span class="pun">(</span><span class="pln">m</span><span class="pun">(</span><span class="pln">input</span><span class="pun">),</span><span class="pln"> target</span><span class="pun">)</span><span class="pln">
output</span><span class="pun">.</span><span class="pln">backward</span><span class="pun">()</span><span class="pln">
</span><span class="com"># حساب الخسارة لتنسورات ثنائية الأبعاد يمكن على سبيل المثال أن تستخدم مع الصور</span><span class="pln">
N</span><span class="pun">,</span><span class="pln"> C </span><span class="pun">=</span><span class="pln"> </span><span class="lit">5</span><span class="pun">,</span><span class="pln"> </span><span class="lit">4</span><span class="pln">
loss </span><span class="pun">=</span><span class="pln"> nn</span><span class="pun">.</span><span class="typ">NLLLoss</span><span class="pun">()</span><span class="pln">
</span><span class="com"># أبعاد المدخلات</span><span class="pln">
</span><span class="com"># N x C x height x width</span><span class="pln">
data </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">(</span><span class="pln">N</span><span class="pun">,</span><span class="pln"> </span><span class="lit">16</span><span class="pun">,</span><span class="pln"> </span><span class="lit">10</span><span class="pun">,</span><span class="pln"> </span><span class="lit">10</span><span class="pun">)</span><span class="pln">
conv </span><span class="pun">=</span><span class="pln"> nn</span><span class="pun">.</span><span class="typ">Conv2d</span><span class="pun">(</span><span class="lit">16</span><span class="pun">,</span><span class="pln"> C</span><span class="pun">,</span><span class="pln"> </span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="lit">3</span><span class="pun">))</span><span class="pln">
m </span><span class="pun">=</span><span class="pln"> nn</span><span class="pun">.</span><span class="typ">LogSoftmax</span><span class="pun">(</span><span class="pln">dim</span><span class="pun">=</span><span class="lit">1</span><span class="pun">)</span><span class="pln">
target </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">empty</span><span class="pun">(</span><span class="pln">N</span><span class="pun">,</span><span class="pln"> </span><span class="lit">8</span><span class="pun">,</span><span class="pln"> </span><span class="lit">8</span><span class="pun">,</span><span class="pln"> dtype</span><span class="pun">=</span><span class="pln">torch</span><span class="pun">.</span><span class="pln">long</span><span class="pun">).</span><span class="pln">random_</span><span class="pun">(</span><span class="lit">0</span><span class="pun">,</span><span class="pln"> C</span><span class="pun">)</span><span class="pln">
output </span><span class="pun">=</span><span class="pln"> loss</span><span class="pun">(</span><span class="pln">m</span><span class="pun">(</span><span class="pln">conv</span><span class="pun">(</span><span class="pln">data</span><span class="pun">)),</span><span class="pln"> target</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">output</span><span class="pun">)</span><span class="pln"> </span><span class="com">#tensor(1.4892, grad_fn=&lt;NllLoss2DBackward&gt;)</span><span class="pln">

</span><span class="com">#credit NLLLoss — PyTorch 1.9.0 documentation</span></pre>

<h3 id="binarycrossentropyloss">
	دالة خسارة الإنتروبيا المتقاطعة للتصنيفات الثنائية Binary Cross-Entropy Loss
</h3>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169677" href="https://academy.hsoub.com/uploads/monthly_2025_03/Logistic-curve.png.1e07e055b1df3acc6ac61d196ed4e4a8.png" rel=""><img alt="logistic curve" class="ipsImage ipsImage_thumbnailed" data-fileid="169677" data-ratio="66.67" data-unique="lvld6gsjm" style="width: 300px; height: auto;" width="480" src="https://academy.hsoub.com/uploads/monthly_2025_03/Logistic-curve.png.1e07e055b1df3acc6ac61d196ed4e4a8.png"></a>
</p>

<p>
	دالة خسارة الإنتروبيا المتقاطعة الثنائية Binary CE هي حالة خاصة من الإنتروبيا المتقاطعة CE وتستخدم عند تصنيف البيانات لأحد تصنيفين، ولذلك تسمى ثنائية حيث نرمز لأحد التصنيفين بصفر وللآخر بواحد، ونهدف عند استخدامها لجعل النموذج يخمّن رقمًا قريبًا من الصفر عندما يكون التصنيف الفعلي هو الصفر ورقمًا قريبًا للواحد إن كان التصنيف الفعلي واحد، وتكون في الغالب الطبقة الأخيرة في الشبكة العصبية عند استخدام هذه النوع من دوال حساب الخسارة طبقة تستخدم <a href="https://ar.wikipedia.org/wiki/%D8%AF%D8%A7%D9%84%D8%A9_%D8%B3%D9%8A%D9%86%D9%8A%D8%A9" rel="external nofollow">دالة سينية Sigmoid</a> وبالتحديد الدالة اللوجستية logistic function وهي نوع خاص من الدوال السينية sigmoid functions والتي تضمن أن المخرجات رقمًا قريبًا من الواحد أو الصفر ليحقق شروط الاحتمالات.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169728" href="https://academy.hsoub.com/uploads/monthly_2025_03/BCE_loss.png.64d53bef54978fd4ded98b5faf11466d.png" rel=""><img alt="BCE loss" class="ipsImage ipsImage_thumbnailed" data-fileid="169728" data-ratio="44.00" data-unique="fwzv8v5ut" style="width: 400px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_03/BCE_loss.thumb.png.840b5de0416f3be3d614c0269e463c6a.png"></a><a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169677" href="https://academy.hsoub.com/uploads/monthly_2025_03/Logistic-curve.png.1e07e055b1df3acc6ac61d196ed4e4a8.png" rel=""> </a>
</p>

<p>
	وفيما يلي كود يحسب دالة الخسارة للانحدار اللوجستي باستخدام الدالة <code>BCE</code><span>:</span>
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_6292_30" style=""><span class="kwd">import</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">nn </span><span class="kwd">as</span><span class="pln"> nn

m </span><span class="pun">=</span><span class="pln"> nn</span><span class="pun">.</span><span class="typ">Sigmoid</span><span class="pun">()</span><span class="pln">
loss </span><span class="pun">=</span><span class="pln"> nn</span><span class="pun">.</span><span class="typ">BCELoss</span><span class="pun">()</span><span class="pln">
input </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> requires_grad</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
target </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">empty</span><span class="pun">(</span><span class="lit">3</span><span class="pun">).</span><span class="pln">random_</span><span class="pun">(</span><span class="lit">2</span><span class="pun">)</span><span class="pln">
output </span><span class="pun">=</span><span class="pln"> loss</span><span class="pun">(</span><span class="pln">m</span><span class="pun">(</span><span class="pln">input</span><span class="pun">),</span><span class="pln"> target</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">output</span><span class="pun">)</span><span class="pln"> </span><span class="com">#tensor(0.4198, grad_fn=&lt;BinaryCrossEntropyBackward&gt;)</span></pre>

<h3 id="binarycrossentropylosswithlogits">
	دالة خسارة الإنتروبيا المتقاطعة للتصنيفات الثنائية مع لوغاريتم الفرص Binary Cross-Entropy Loss with Logits
</h3>

<p>
	لو سألنا أحدهم ما هي فرص فوز فريقك المفضل في المباراة؟ يمكن أن يجيب باحتمال مباشر مثل 40%، ويمكن يعبر عن فرص فوز الفريق فيقول يفوز الفريق مرتين من كل خمس مرات، فهذه نفس النسبة ولكن بطريقة مختلفة. حيث يعبر الاحتمال Probability عن فرصة وقوع الحدث من إجمالي جميع الحالات الممكنة، وتعبر الفرص odds عن نسبة احتمال وقوع الحدث إلى احتمال عدم وقوعه، ويستخدم لوغاريتم الفرص Logits أو <code>log(odds)‎</code> لتحويل الاحتمالات لقيم يمكن استخدامها بسهولة في الحسابات الرياضية، ويضمن أن النتائج تتبع توزيعًا خطيًا بدلاً من أن تكون مقيدة بين الصفر والواحد.
</p>

<p>
	ذكرنا سابقًا أن دالة خسارة الإنتروبيا المتقاطعة الثنائية BCE تُسبق بطبقة بها الدالة السينية اللوجيستية logistic sigmoid لضمان أن المخرجات بين الواحد والصفر. وتُجمَع دالة خسارة الإنتروبيا المتقاطعة للتصنيفات الثنائية Binary Cross-Entropy Loss مع لوغاريتم الفرص Logits الطبقتين في طبقة واحدة، ووفقًا <a href="https://pytorch.org/docs/stable/generated/torch.nn.BCEWithLogitsLoss.html#torch.nn.BCEWithLogitsLoss" rel="external nofollow">لتوثيق باي تورش PyTorch</a> فهذا يجعلها أكثر استقرارًا عند إجراء العمليات الحسابية حيث يمكنها الاستفادة من تحويل الضرب إلى جمع بفضل اللوغاريتم.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3705_9" style=""><span class="kwd">import</span><span class="pln"> torch
</span><span class="kwd">import</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">nn </span><span class="kwd">as</span><span class="pln"> nn

</span><span class="com"># 64 تصنيفًا </span><span class="pln">
</span><span class="com"># حجم الدفعة الواحدة 10</span><span class="pln">
target </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">ones</span><span class="pun">([</span><span class="lit">10</span><span class="pun">,</span><span class="pln"> </span><span class="lit">64</span><span class="pun">],</span><span class="pln"> dtype</span><span class="pun">=</span><span class="pln">torch</span><span class="pun">.</span><span class="pln">float32</span><span class="pun">)</span><span class="pln">  </span><span class="com"># 64 classes, batch size = 10</span><span class="pln">
</span><span class="com"># المخرجات التي سنجرب عليها</span><span class="pln">
</span><span class="com"># هذا مثال افتراضي</span><span class="pln">
</span><span class="com">#  ولكن عندما تكون هذه المخرجات من الشبكة العصبية</span><span class="pln">
</span><span class="com">#  قبل مرورها في الدالة اللوجستية تسمي</span><span class="pln">
</span><span class="com"># logit / prediction </span><span class="pln">
output </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">full</span><span class="pun">([</span><span class="lit">10</span><span class="pun">,</span><span class="pln"> </span><span class="lit">64</span><span class="pun">],</span><span class="pln"> </span><span class="lit">1.5</span><span class="pun">)</span><span class="pln"> 
</span><span class="com"># جميع الأوزان هنا متساوية بواحد</span><span class="pln">
pos_weight </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">ones</span><span class="pun">([</span><span class="lit">64</span><span class="pun">])</span><span class="pln"> 
criterion </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">nn</span><span class="pun">.</span><span class="typ">BCEWithLogitsLoss</span><span class="pun">(</span><span class="pln">pos_weight</span><span class="pun">=</span><span class="pln">pos_weight</span><span class="pun">)</span><span class="pln">
loss </span><span class="pun">=</span><span class="pln"> criterion</span><span class="pun">(</span><span class="pln">output</span><span class="pun">,</span><span class="pln"> target</span><span class="pun">)</span><span class="pln">  </span><span class="com"># -log(sigmoid(1.5))</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">loss</span><span class="pun">)</span><span class="pln"> </span><span class="com">#tensor(0.2014)</span></pre>

<h3 id="smoothl1loss">
	دالة خسارة المعيار الأول المرنة Smooth L1 loss
</h3>

<p>
	تستفيد دالة خسارة المعيار الأول Smooth L1 loss من مزايا كل من متوسط مربع الخطأ MSE ومتوسط الخطأ المطلق MAE من خلال معامل تحكم بيتا beta، وقُدم المعيار لأول مرة في الورقة البحثية <a href="https://arxiv.org/abs/1504.08083" rel="external nofollow">Fast R-CNN </a>. ويستخدم المعيار مربع الفرق عندما يكون الفرق المطلق بين القيم الفعلية والقيم المتوقعة أقل من بيتا beta فيصبح المعيار المستخدم MSE، ويرسم معدل الخسارة لمتوسط مربع الخطأ بشكل منحني متصل ومستمر، مما يجعل الدالة قابلة للاشتقاق عند كل القيم مما يمكننا من حساب معدل التدرج التصحيحي gradients لكل هذه القيم، ولكن عندما تصبح قيمة الخطأ عالية تظهر مشكلة تزايد التدرج بشكل خارج عن السيطرة يوصف بالإنفجاري gradient explosion حيث تصبح قيم التدرج gradients عالية وعند ضربها في الأوزان بشكل مستمر نحصل على أرقام ضخمة تؤدي في النهاية إلى عدم استيعاب المتغيرات لحجم الأرقام وعدم قدرة النظام على التعلم فيما يعرف بالفوران overflow، ولذلك عندما تبدأ هذه الظاهرة في الحدوث نستخدم معيار قيمة الخطأ المطلق MAE والذي يجعل الزيادة في قيم التدرج شبه ثابتة أي خطية عند كل القيم، ونحدد وقت التغيير بناءً على معامل التحكم بيتا beta.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169682" href="https://academy.hsoub.com/uploads/monthly_2025_03/Smooth_L1.png.5c87330b8695d186b358354d0f2f0cd5.png" rel=""><img alt="smooth l1" class="ipsImage ipsImage_thumbnailed" data-fileid="169682" data-unique="ji2hn5qdr" style="width: 250px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/Smooth_L1.thumb.png.c846f54596085a4178477db06c247cab.png"> </a>
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3705_11" style=""><span class="kwd">import</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">nn </span><span class="kwd">as</span><span class="pln"> nn

loss </span><span class="pun">=</span><span class="pln"> nn</span><span class="pun">.</span><span class="typ">SmoothL1Loss</span><span class="pun">()</span><span class="pln">
input </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="lit">5</span><span class="pun">,</span><span class="pln"> requires_grad</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
target </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="lit">5</span><span class="pun">)</span><span class="pln">
output </span><span class="pun">=</span><span class="pln"> loss</span><span class="pun">(</span><span class="pln">input</span><span class="pun">,</span><span class="pln"> target</span><span class="pun">)</span><span class="pln">

</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">output</span><span class="pun">)</span><span class="pln"> </span><span class="com">#tensor(0.7838, grad_fn=&lt;SmoothL1LossBackward&gt;)</span></pre>

<h3 id="hingeembeddingloss">
	دالة الخسارة المفصلية التضمينية Hinge Embedding loss
</h3>

<p>
	تستخدم هذه الدالة في الغالب مع مهام التعلم غير الخاضع للإشراف unsupervised learning لقياس درجة التشابه بين مُدخلين كل منهما عبارة عن <a href="https://ar.wikipedia.org/wiki/%D9%85%D9%88%D8%AA%D8%B1" rel="external nofollow">تنسور tensor</a>، يمثًل هو تنسور المدخلات input tensor والآخر تنسور الوسم labels tensor وتكون الوسوم في هذه الحالة أحد قيمتين <code>1</code> أو <code>1-</code>، وتٌحلّ من خلالها المسائل التي تحتوي على تضمين غير خطي non-linear embeddings ومهام التعلم غير الخاضع للإشراف.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169676" href="https://academy.hsoub.com/uploads/monthly_2025_03/hinge_emb_loss.png.d8d04b63660955def67d717daeb554a2.png" rel=""><img alt="hinge emb loss" class="ipsImage ipsImage_thumbnailed" data-fileid="169676" data-unique="t9w7nlcol" style="width: 400px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/hinge_emb_loss.thumb.png.edd1b32880e32bbf6417a8960f95de47.png"> </a>
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3705_13" style=""><span class="kwd">import</span><span class="pln"> torch
</span><span class="kwd">import</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">nn </span><span class="kwd">as</span><span class="pln"> nn

input </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="lit">5</span><span class="pun">,</span><span class="pln"> requires_grad</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
target </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="lit">5</span><span class="pun">)</span><span class="pln">

hinge_loss </span><span class="pun">=</span><span class="pln"> nn</span><span class="pun">.</span><span class="typ">HingeEmbeddingLoss</span><span class="pun">()</span><span class="pln">
output </span><span class="pun">=</span><span class="pln"> hinge_loss</span><span class="pun">(</span><span class="pln">input</span><span class="pun">,</span><span class="pln"> target</span><span class="pun">)</span><span class="pln">
output</span><span class="pun">.</span><span class="pln">backward</span><span class="pun">()</span><span class="pln">

</span><span class="kwd">print</span><span class="pun">(</span><span class="str">'input: '</span><span class="pun">,</span><span class="pln"> input</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">'target: '</span><span class="pun">,</span><span class="pln"> target</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">'output: '</span><span class="pun">,</span><span class="pln"> output</span><span class="pun">)</span><span class="pln">

</span><span class="com">#input:  tensor([[ 1.4668e+00,  2.9302e-01, -3.5806e-01,  1.8045e-01,  #1.1793e+00],</span><span class="pln">
</span><span class="com">#       [-6.9471e-05,  9.4336e-01,  8.8339e-01, -1.1010e+00,  #1.5904e+00],</span><span class="pln">
</span><span class="com">#       [-4.7971e-02, -2.7016e-01,  1.5292e+00, -6.0295e-01,  #2.3883e+00]],</span><span class="pln">
</span><span class="com">#       requires_grad=True)</span><span class="pln">
</span><span class="com">#target:  tensor([[-0.2386, -1.2860, -0.7707,  1.2827, -0.8612],</span><span class="pln">
</span><span class="com">#        [ 0.6747,  0.1610,  0.5223, -0.8986,  0.8069],</span><span class="pln">
</span><span class="com">#        [ 1.0354,  0.0253,  1.0896, -1.0791, -0.0834]])</span><span class="pln">
</span><span class="com">#output:  tensor(1.2103, grad_fn=&lt;MeanBackward0&gt;)</span></pre>

<h3 id="marginrankingloss">
	دالة خسارة الترتيب الهامشية Margin Ranking Loss
</h3>

<p>
	تنتمي دالة الترتيب الهامشية إلى دوال خسارة الترتيب التي تهدف لقياس المسافة النسبية بين مجموعة من المدخلات في مجموعة بيانات. ويُدخل للدالة مدخلان ووسم إما <code>1</code> أو <code>1-</code>، فإذا كان الوسم <code>1</code> سنفترض أن المُدخل الأول يملك ترتيبًا أعلى من المُدخل الثاني، والعكس صحيح فإذا كان الوسم <code>1-</code> يكون ترتيب المٌدخل الثاني أعلى، ويمكن أن نرى هذه العلاقة في المعادلة التالية:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="169706" href="https://academy.hsoub.com/uploads/monthly_2025_03/margin_ranking_loss.jpg.c6219d808c8546c377046ca2fa6f0545.jpg" rel=""><img alt="margin ranking loss" class="ipsImage ipsImage_thumbnailed" data-fileid="169706" data-ratio="29.50" data-unique="v15l0bntu" style="width: 400px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_03/margin_ranking_loss.thumb.jpg.03d843fe2c37669b30e5e102e6cb474b.jpg"></a>
</p>

<p>
	يوضح الكود التالي حساب الخسارة بين مُدخلين <code>input1</code> و <code>input2</code> باستخدام الدالة <code>MarginRankingLoss</code>:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_9016_19" style=""><span class="kwd">import</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">nn </span><span class="kwd">as</span><span class="pln"> nn

loss </span><span class="pun">=</span><span class="pln"> nn</span><span class="pun">.</span><span class="typ">MarginRankingLoss</span><span class="pun">()</span><span class="pln">
input1 </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> requires_grad</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
input2 </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> requires_grad</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
target </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">(</span><span class="lit">3</span><span class="pun">).</span><span class="pln">sign</span><span class="pun">()</span><span class="pln">
output </span><span class="pun">=</span><span class="pln"> loss</span><span class="pun">(</span><span class="pln">input1</span><span class="pun">,</span><span class="pln"> input2</span><span class="pun">,</span><span class="pln"> target</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">'input1: '</span><span class="pun">,</span><span class="pln"> input1</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">'input2: '</span><span class="pun">,</span><span class="pln"> input2</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">'output: '</span><span class="pun">,</span><span class="pln"> output</span><span class="pun">)</span><span class="pln">

</span><span class="com">#input1:  tensor([-1.1109,  0.1187,  0.9441], requires_grad=True)</span><span class="pln">
</span><span class="com">#input2:  tensor([ 0.9284, -0.3707, -0.7504], requires_grad=True)</span><span class="pln">
</span><span class="com">#output:  tensor(0.5648, grad_fn=&lt;MeanBackward0&gt;)</span></pre>

<h3 id="tripletmarginloss">
	دالة الخسارة الثلاثية الهامشية Triplet Margin loss
</h3>

<p>
	تقيس هذه الدالة التشابه بين المُدخلات باستخدام ثلاث عينات من البيانات. فتستخدم الدالة عينة المرساة anchor sample، وعينة سالبة لا تنتمي لنفس التصنيف، وعينة إيجابية تنتمي لنفس تصنيف عينة المرساة، ونهدف إلى تعظيم المسافة بين عينة المرساة والعينة الموجبة وتقليص المسافة بين عينة المرساة والعينة السالبة بحيث لا تقل عن قيمة هامشية محددة، وباستخدام هذه الدالة الثلاثية الهامشية triplet margin نريد تخمين درجة عالية من التشابه بين المرساة anchor والعينة الموجبة، وتشابه ضعيف منخفض بين عينة المرساة anchor والعينة السالبة.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169686" href="https://academy.hsoub.com/uploads/monthly_2025_03/triplet_loss.png.8ef00b4b849dc3377e7a1b0d5005bf3e.png" rel=""><img alt="triplet loss" class="ipsImage ipsImage_thumbnailed" data-fileid="169686" data-unique="rms64wub8" style="width: 400px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/triplet_loss.thumb.png.c2ceee4cf4f8b254e6887b395780fc82.png"> </a>
</p>

<p>
	يوضح الكود التالي استخدام دالة الخسارة <code>TripletMarginLoss</code>:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_5452_10" style=""><span class="kwd">import</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">nn </span><span class="kwd">as</span><span class="pln"> nn

triplet_loss </span><span class="pun">=</span><span class="pln"> nn</span><span class="pun">.</span><span class="typ">TripletMarginLoss</span><span class="pun">(</span><span class="pln">margin</span><span class="pun">=</span><span class="lit">1.0</span><span class="pun">,</span><span class="pln"> p</span><span class="pun">=</span><span class="lit">2</span><span class="pun">)</span><span class="pln">
anchor </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">(</span><span class="lit">100</span><span class="pun">,</span><span class="pln"> </span><span class="lit">128</span><span class="pun">,</span><span class="pln"> requires_grad</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
positive </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">(</span><span class="lit">100</span><span class="pun">,</span><span class="pln"> </span><span class="lit">128</span><span class="pun">,</span><span class="pln"> requires_grad</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
negative </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">(</span><span class="lit">100</span><span class="pun">,</span><span class="pln"> </span><span class="lit">128</span><span class="pun">,</span><span class="pln"> requires_grad</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
output </span><span class="pun">=</span><span class="pln"> triplet_loss</span><span class="pun">(</span><span class="pln">anchor</span><span class="pun">,</span><span class="pln"> positive</span><span class="pun">,</span><span class="pln"> negative</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">output</span><span class="pun">)</span><span class="pln">  </span><span class="com">#tensor(1.1151, grad_fn=&lt;MeanBackward0&gt;)</span></pre>

<h3 id="cosineembeddingloss">
	دالة خسارة تضمين جيب التمام اCosine Embedding Loss
</h3>

<p>
	تقيس دالة خسارة تضمين جيب التمام Cosine Embedding Loss الخسارة بين اثنين من المدخلات وتنسور من الوسوم قيم عناصره إما <code>1</code> أو <code>1-</code>، وتستخدم عندما نريد قياس درجة التشابه أو القرب بين مُدخلين.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169688" href="https://academy.hsoub.com/uploads/monthly_2025_03/cos_loss.png.08ca5e973b7598d9f3d0826b55b2d4f8.png" rel=""><img alt="cos loose" class="ipsImage ipsImage_thumbnailed" data-fileid="169688" data-ratio="30.25" data-unique="ezr7q6uw8" style="width: 400px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_03/cos_loss.thumb.png.41d82eb030f820b27bb413ecf087ab0a.png"></a>
</p>

<p>
	وتحسب الدالة درجة التشابه بحساب مسافة جيب تمام الزاوية Cosine distance بين نقطتين أو متجهين في الفضاء. حيث تتناسب مسافة جيب التمام Cosine distance مع الزاوية بين المتجهين، فكلما قلت الزاوية قلت المسافة بين المتجهين وكلما كان المتجهان أقرب كلما كانت الكائنات التي يصفانها متشابهة.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169681" href="https://academy.hsoub.com/uploads/monthly_2025_03/similarity_cos.png.a60464806e6d2d4ab42622cdbc65562b.png" rel=""><img alt="similarity cos" class="ipsImage ipsImage_thumbnailed" data-fileid="169681" data-unique="itysuvlc1" style="width: 260px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/similarity_cos.thumb.png.c577ea8a134af032643258e1b1761033.png"> </a>
</p>

<p>
	يوضح الكود التالي استخدام دالة الخسارة <code>CosineEmbeddingLoss</code>:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_5452_14" style=""><span class="kwd">import</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">nn </span><span class="kwd">as</span><span class="pln"> nn

loss </span><span class="pun">=</span><span class="pln"> nn</span><span class="pun">.</span><span class="typ">CosineEmbeddingLoss</span><span class="pun">()</span><span class="pln">
input1 </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="lit">6</span><span class="pun">,</span><span class="pln"> requires_grad</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
input2 </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="lit">6</span><span class="pun">,</span><span class="pln"> requires_grad</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
target </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">(</span><span class="lit">3</span><span class="pun">).</span><span class="pln">sign</span><span class="pun">()</span><span class="pln">
output </span><span class="pun">=</span><span class="pln"> loss</span><span class="pun">(</span><span class="pln">input1</span><span class="pun">,</span><span class="pln"> input2</span><span class="pun">,</span><span class="pln"> target</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">'input1: '</span><span class="pun">,</span><span class="pln"> input1</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">'input2: '</span><span class="pun">,</span><span class="pln"> input2</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">'output: '</span><span class="pun">,</span><span class="pln"> output</span><span class="pun">)</span><span class="pln">

</span><span class="com">#input1:  tensor([[ 1.2969e-01,  1.9397e+00, -1.7762e+00, -1.2793e-01, #-4.7004e-01,</span><span class="pln">
</span><span class="com">#         -1.1736e+00],</span><span class="pln">
</span><span class="com">#        [-3.7807e-02,  4.6385e-03, -9.5373e-01,  8.4614e-01, -1.1113e+00,</span><span class="pln">
</span><span class="com">#          4.0305e-01],</span><span class="pln">
</span><span class="com">#        [-1.7561e-01,  8.8705e-01, -5.9533e-02,  1.3153e-03, -6.0306e-01,</span><span class="pln">
</span><span class="com">#          7.9162e-01]], requires_grad=True)</span><span class="pln">
</span><span class="com">#input2:  tensor([[-0.6177, -0.0625, -0.7188,  0.0824,  0.3192,  1.0410],</span><span class="pln">
</span><span class="com">#        [-0.5767,  0.0298, -0.0826,  0.5866,  1.1008,  1.6463],</span><span class="pln">
</span><span class="com">#        [-0.9608, -0.6449,  1.4022,  1.2211,  0.8248, -1.9933]],</span><span class="pln">
</span><span class="com">#       requires_grad=True)</span><span class="pln">
</span><span class="com">#output:  tensor(0.0033, grad_fn=&lt;MeanBackward0&gt;)</span></pre>

<h3 id="kullbackleiblerdivergence">
	دالة خسارة تباعد كولباك ليبلر Kullback Leibler Divergence
</h3>

<p>
	تستخدم هذه الدالة في تقدير الخسارة لنماذج تعلم الآلة التي تحاول تعلم توزيع احتمالات probability distribution عن طريق حساب كمية المعلومات المفقودة في عملية التقريب، ونرمز للتوزيع الفعلي الذي نحاول تعليمه للآلة بالرمز <code>P</code> وللتوزيع التقريبي بالرمز <code>Q</code> ، وتعمل هذه الدالة على قياس التشابه بين التوزيع الفعلي <code>P</code> والتقريبي <code>Q</code> وبالتالي دفع خوارزمية تعلم الآلة نحو إنتاج توزيع قريب من التوزيع الفعلي قدر الإمكان. ويلاحظ أن مقدار الخسارة في المعلومات عند استخدام التوزيع التقريبي <code>Q</code> لتقدير التوزيع الفعلي <code>P</code> ليس مساويًا للعملية العكسية التي تستخدم التوزيع الفعلي <code>P</code> لتقدير التوزيع التقريبي <code>Q</code> ولذلك يعد تباعد كولباك ليبلر KL divergence غير متماثل Not symmetric.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169674" href="https://academy.hsoub.com/uploads/monthly_2025_03/DKL_loss.png.c81fa54bbecb88ee70f34ee32fa45e6f.png" rel=""><img alt="dkl loss" class="ipsImage ipsImage_thumbnailed" data-fileid="169674" data-unique="tv4i97xv4" style="width: 300px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/DKL_loss.thumb.png.a45ca06f5c52a4730f881ef55ade2a9f.png"> </a>
</p>

<p>
	يوضح الكود التالي استخدام الدالة <code>KLDivLoss</code>:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_5452_17" style=""><span class="kwd">import</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">nn </span><span class="kwd">as</span><span class="pln"> nn

loss </span><span class="pun">=</span><span class="pln"> nn</span><span class="pun">.</span><span class="typ">KLDivLoss</span><span class="pun">(</span><span class="pln">size_average</span><span class="pun">=</span><span class="kwd">None</span><span class="pun">,</span><span class="pln"> reduce</span><span class="pun">=</span><span class="kwd">None</span><span class="pun">,</span><span class="pln"> reduction</span><span class="pun">=</span><span class="str">'mean'</span><span class="pun">,</span><span class="pln"> log_target</span><span class="pun">=</span><span class="kwd">False</span><span class="pun">)</span><span class="pln">
input1 </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="lit">6</span><span class="pun">,</span><span class="pln"> requires_grad</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
input2 </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="lit">6</span><span class="pun">,</span><span class="pln"> requires_grad</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">)</span><span class="pln">
output </span><span class="pun">=</span><span class="pln"> loss</span><span class="pun">(</span><span class="pln">input1</span><span class="pun">,</span><span class="pln"> input2</span><span class="pun">)</span><span class="pln">

</span><span class="kwd">print</span><span class="pun">(</span><span class="str">'output: '</span><span class="pun">,</span><span class="pln"> output</span><span class="pun">)</span><span class="pln"> </span><span class="com">#tensor(-0.0284, grad_fn=&lt;KlDivBackward&gt;)</span></pre>

<h3 id="-1">
	بناء دالة خسارة مخصصة
</h3>

<p>
	توجد طريقتان لبناء دالة خسارة خاصة بنا تتناسب مع المشكلة التي نحاول حلها، الأولى عن طريق تحقيقها داخل صنف class والثانية عن طريق تحقيقها كدالة مستقلة، وسنستعرض كلا الطريقتين.
</p>

<p>
	تُعدّ طريقة الدالة المستقلة أسهل لبناء دالة خسارة مخصصة، حيث تُمرّر المُدخلات المطلوبة للدالة وتجري بعض العمليات عليها في جسم الدالة باستخدام العوامل والدوال البرمجية الأخرى المتاحة في باي تورش PyTorch أو من أي مصدر آخر، ومن ثم تعيد قيمة تمثّل الخسارة.
</p>

<p>
	يوضح المثال التالي تعريف دالة مخصصة لحساب متوسط مربع الخطأ <code>MSE</code>:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_1982_7" style=""><span class="kwd">def</span><span class="pln"> custom_mean_square_error</span><span class="pun">(</span><span class="pln">y_predictions</span><span class="pun">,</span><span class="pln"> target</span><span class="pun">):</span><span class="pln">
  square_difference </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">square</span><span class="pun">(</span><span class="pln">y_predictions </span><span class="pun">-</span><span class="pln"> target</span><span class="pun">)</span><span class="pln">
  loss_value </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">mean</span><span class="pun">(</span><span class="pln">square_difference</span><span class="pun">)</span><span class="pln">
  </span><span class="kwd">return</span><span class="pln"> loss_value</span></pre>

<p>
	نمرر لهذه الدالة الخاصة تنسور التخمينات predictions tensor وتنسور الوسوم labels tensor ونستخدم بعض الدوال لحساب مربع الفرق بين التنسورين tensors ومن ثم نأخذ المتوسط ونعيده كقيمة الخسارة.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_1982_9" style=""><span class="pln">y_predictions </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="lit">5</span><span class="pun">,</span><span class="pln"> requires_grad</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">);</span><span class="pln">
target </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">randn</span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="lit">5</span><span class="pun">)</span><span class="pln">
pytorch_loss </span><span class="pun">=</span><span class="pln"> nn</span><span class="pun">.</span><span class="typ">MSELoss</span><span class="pun">();</span><span class="pln">
p_loss </span><span class="pun">=</span><span class="pln"> pytorch_loss</span><span class="pun">(</span><span class="pln">y_predictions</span><span class="pun">,</span><span class="pln"> target</span><span class="pun">)</span><span class="pln">
loss </span><span class="pun">=</span><span class="pln"> custom_mean_square_error</span><span class="pun">(</span><span class="pln">y_predictions</span><span class="pun">,</span><span class="pln"> target</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">'custom loss: '</span><span class="pun">,</span><span class="pln"> loss</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="str">'pytorch loss: '</span><span class="pun">,</span><span class="pln"> p_loss</span><span class="pun">)</span><span class="pln">

</span><span class="com">#custom loss:  tensor(2.3134, grad_fn=&lt;MeanBackward0&gt;)</span><span class="pln">
</span><span class="com">#pytorch loss:  tensor(2.3134, grad_fn=&lt;MseLossBackward&gt;)</span></pre>

<p>
	ونقارن في هذا المقطع البرمجي بين دالتنا المخصصة والدالة المدمجة بإطار عمل باي تورش PyTorch framework ويمكنك أن تلاحظ اتفاق الدالتين في القيم النهائية مما يعني أن الدالة مبنية بشكل صحيح.
</p>

<h3 id="-2">
	بناء صنف برمجي مخصص لحساب الخسارة
</h3>

<p>
	يوصى بهذه الطريقة لكونها الطريقة التي يستخدمها باي تورش PyTorch في الكود المصدري، ففي هذه الطريقة نعرّف دالة الخسارة داخل صنف يرث من الصنف الأساسي <code>nn.Module</code> وهذا يسمح لدالة الخسارة المخصصة بالعمل بطريقة مشابهة للطبقات التقليدية في باي تورش، مما يسهّل دمجها واستخدامها ضمن الشبكات العصبية الاصطناعية ANN بنفس الطريقة التي تُستخدم بها الطبقات الأخرى.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_1982_11" style=""><span class="kwd">class</span><span class="pln"> </span><span class="typ">Custom_MSE</span><span class="pun">(</span><span class="pln">nn</span><span class="pun">.</span><span class="typ">Module</span><span class="pun">):</span><span class="pln">
  </span><span class="kwd">def</span><span class="pln"> __init__</span><span class="pun">(</span><span class="pln">self</span><span class="pun">):</span><span class="pln">
    super</span><span class="pun">(</span><span class="typ">Custom_MSE</span><span class="pun">,</span><span class="pln"> self</span><span class="pun">).</span><span class="pln">__init__</span><span class="pun">();</span><span class="pln">

  </span><span class="kwd">def</span><span class="pln"> forward</span><span class="pun">(</span><span class="pln">self</span><span class="pun">,</span><span class="pln"> predictions</span><span class="pun">,</span><span class="pln"> target</span><span class="pun">):</span><span class="pln">
    square_difference </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">square</span><span class="pun">(</span><span class="pln">predictions </span><span class="pun">-</span><span class="pln"> target</span><span class="pun">)</span><span class="pln">
    loss_value </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">mean</span><span class="pun">(</span><span class="pln">square_difference</span><span class="pun">)</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> loss_value

  </span><span class="kwd">def</span><span class="pln"> __call__</span><span class="pun">(</span><span class="pln">self</span><span class="pun">,</span><span class="pln"> predictions</span><span class="pun">,</span><span class="pln"> target</span><span class="pun">):</span><span class="pln">
     square_difference </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">square</span><span class="pun">(</span><span class="pln">y_predictions </span><span class="pun">-</span><span class="pln"> target</span><span class="pun">)</span><span class="pln">
     loss_value </span><span class="pun">=</span><span class="pln"> torch</span><span class="pun">.</span><span class="pln">mean</span><span class="pun">(</span><span class="pln">square_difference</span><span class="pun">)</span><span class="pln">
     </span><span class="kwd">return</span><span class="pln"> loss_value</span></pre>

<h2 id="-3">
	الخاتمة
</h2>

<p>
	ناقشنا في هذا المقال العديد من دوال الخسارة loss functions المتوفرة في باي تورش PyTorch وتعمقنا في آلية عمل هذه الدوال والعلاقات الرياضية المعبرة عنها، قد يكون اختيار الدالة المناسبة مهمة صعبة، ولكن بفهمك الجيد لمحتوى هذه المقالة والرجوع للتوثيق الخاص بإطار عمل باي تورش PyTorch ستتمكن من اختيار دالة الخسارة المناسبة لمشكلتك بدقة.
</p>

<p>
	ترجمة وبتصرف لمقالة <a href="https://www.digitalocean.com/community/tutorials/pytorch-loss-functions#hinge-embedding-loss" rel="external nofollow">PyTorch Loss Functions</a> لصاحبها Henry Ansah Fordjour.
</p>

<h2 id="-4">
	اقرأ أيضًا
</h2>

<ul>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D8%A5%D8%B7%D8%A7%D8%B1-%D8%B9%D9%85%D9%84-%D8%A8%D8%A7%D9%8A-%D8%AA%D9%88%D8%B1%D8%B4-pytorch-%D9%88%D8%A3%D9%87%D9%85%D9%8A%D8%AA%D9%87-%D9%84%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-r2311/" rel="">تعرف على إطار عمل باي تورش PyTorch وأهميته لتطبيقات الذكاء الاصطناعي</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%B7%D8%B1%D9%8A%D9%82%D8%A9-%D8%A7%D9%84%D8%B5%D9%82%D9%84-fine-tune-%D9%84%D9%86%D9%85%D9%88%D8%B0%D8%AC-%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-%D9%85%D9%8F%D8%AF%D8%B1%D9%91%D9%8E%D8%A8-%D9%85%D9%8F%D8%B3%D8%A8%D9%82%D9%8B%D8%A7-r2367/" rel="">طريقة الصقل Fine-Tune لنموذج ذكاء اصطناعي مُدرَّب مُسبقًا</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D8%A3%D9%87%D9%85-%D9%83%D8%AA%D8%A8-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-%D8%A7%D9%84%D9%85%D8%AC%D8%A7%D9%86%D9%8A%D8%A9-r2330/" rel="">تعرف على أهم كتب الذكاء الاصطناعي المجانية</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D9%85%D9%83%D8%AA%D8%A8%D8%A9-scikit-learn-%D9%88%D8%A3%D9%87%D9%85-%D8%AE%D9%88%D8%A7%D8%B1%D8%B2%D9%85%D9%8A%D8%A7%D8%AA%D9%87%D8%A7-r2485/" rel="">تعرف على مكتبة Scikit learn وأهم خوارزمياتها</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">2539</guid><pubDate>Fri, 21 Mar 2025 12:00:00 +0000</pubDate></item><item><title>&#x623;&#x641;&#x643;&#x627;&#x631; &#x645;&#x634;&#x627;&#x631;&#x64A;&#x639; &#x630;&#x643;&#x627;&#x621; &#x627;&#x635;&#x637;&#x646;&#x627;&#x639;&#x64A; &#x62A;&#x646;&#x627;&#x633;&#x628; &#x627;&#x644;&#x645;&#x628;&#x62A;&#x62F;&#x626;&#x64A;&#x646;</title><link>https://academy.hsoub.com/programming/artificial-intelligence/%D8%A3%D9%81%D9%83%D8%A7%D8%B1-%D9%85%D8%B4%D8%A7%D8%B1%D9%8A%D8%B9-%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-%D8%AA%D9%86%D8%A7%D8%B3%D8%A8-%D8%A7%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86-r2535/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2025_03/8.jpg.42072c28878ecd1c11df781dd80488c6.jpg" /></p>
<p>
	نستعرض في هذا المقال ثمانية أفكار لمشاريع ذكاء اصطناعي مميزة تناسب المبتدئين المهتمين بتعلم الذكاء الاصطناعي والتخصص فيه، فقد بدأ الذكاء الاصطناعي يغير بيئة العمل تدريجيًا، واتجهت معظم الأنشطة التجارية في الآونة الأخيرة نحو استخدام تقنيات الذكاء الاصطناعي وتعلم الآلة لتسيير أعمالها، ومن المتوقع زيادة استخدام الذكاء الاصطناعي في السنوات القادمة ما يبرز أهمية هذا المجال والطلب الكبير عليه في سوق العمل. 
</p>

<h2>
	أهمية تنفيذ مشاريع الذكاء الاصطناعي
</h2>

<p>
	لاشك أن العمل على مشاريع عملية من أكثر الطرق فعالية  <a href="https://academy.hsoub.com/artificial-intelligence/" rel="">لتعلم الذكاء الاصطناعي</a> واكتساب خبرة كافية فيه، فضلًا عن كونه يوفر لنا فرصة مميزة لبناء معرض أعمال تعزز فرصتنا في الحصول على عمل.
</p>

<p>
	تتنوع أفكار المشاريع التي يمكن العمل عليها كتحليل المشاعر sentiment analysis ومنشورات منصات التواصل الاجتماعي، أو التعرف على أنواع النباتات من الصور وغيرها من الأفكار المتنوعة التي تحل مشكلات عملية، فتطبيق معلوماتنا على مشاريع ذكاء اصطناعي تحل مشكلات حقيقية يبرز مهاراتنا للأشخاص المهتمين بتوظيف المواهب التقنية والراغبين في التعاون معنا في مشاريع أخرى.
</p>

<p>
	يمكن البدء بمشاريع جانبية بسيطة كفرصة للتعلم وتطوير المهارات، بعدها يمكن العمل على تطوير مشاريع تجارية تساعد عملاء حقيقيين في تبني الذكاء الاصطناعي وقدراته في الأنشطة التجارية والمبيعات والتجارة الإلكترونية، وسنستعرض معًا ثمانية أفكار لمشاريع ممتعة في الذكاء الاصطناعي تناسب المبتدئين، وتساعدهم على بدء رحلة التعلم.
</p>

<ol>
</ol>

<h2 id="5">
	خمسة نصائح قبل البدء في مشروع الذكاء الاصطناعي
</h2>

<p>
	قد يعتقد البعض أن البدء في مشروع ذكاء اصطناعي مهمة شاقة، ولكن تقسيم أي مشروع إلى وحدات أصغر يسهل إدارتها وتطويرها سيجعل المهمة أسهل ويساعد على خروجها للنور، لذلك سنقدم في البداية بعض النصائح العملية التي تساعدنا على البدء:
</p>

<h3 id="1">
	1. اختيار مشروع يوافق شغفنا
</h3>

<p>
	من الأفضل أن نبدأ بمشروع يجعلنا نشعر بالحماس والشغف حياله، ويفضل أن يرتبط بأحد اهتماماتنا أو هواياتنا، كأن يكون المشروع بناء <a href="https://academy.hsoub.com/apps/web/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D8%A8%D9%88%D8%AA-%D8%A7%D9%84%D9%85%D8%AD%D8%A7%D8%AF%D8%AB%D8%A9-%D8%A7%D9%84%D8%B0%D9%83%D9%8A-%D8%B4%D8%A7%D8%AA-%D8%AC%D9%8A-%D8%A8%D9%8A-%D8%AA%D9%8A-chatgpt-r863/" rel="">نظام محادثة ذكي</a> يقترح تمارين رياضية مخصصة لاحتياجات كل مستخدم، أو نظام ترشيح لاقتراح الموسيقى المناسبة لحالتك المزاجية، أو حتى مساعد مشغل بالذكاء الاصطناعي يساعد في التصميم الداخلي للمنازل من خلال عرض مظاهر مختلفة لتصميم الغرف، فاختيار فكرة توافق شغفنا سيجعلنا متحمسين دومًا وقادرين على تخطي التحديات التي نواجهها.
</p>

<h3 id="2">
	2. التركيز على أهداف صغيرة قابلة للتحقيق
</h3>

<p>
	بدلًا من التركيز على حل المشاكل المعقدة مرةً واحدة، علينا التركيز على تجزئتها لأهدافٍ أصغر قابلة للتحقيق بسهولة، فمثلًا يمكن البدء بنظام <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B5%D9%86%D9%8A%D9%81-%D8%A7%D9%84%D8%B5%D9%88%D8%B1-%D9%88%D8%A7%D9%84%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D8%A7%D9%84%D9%88%D8%AC%D9%87-%D9%81%D9%8A-%D9%85%D8%AC%D8%A7%D9%84-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-r1197/" rel="">تصنيف للصور</a> image classification بدلًا من البدء مباشرةً ببناء نظام متكامل لاكتشاف الكائنات object detection، فتحقيق المكاسب الصغيرة المتراكمة يعزز ثقتنا بأنفسنا عندما نقابل تحديات جديدة مثل تجربة تقنية أو إطار عمل للمرة الأولى.
</p>

<h3 id="3">
	3. اختيار البنية التحتية المناسبة
</h3>

<p>
	عندما نحاول بناء مشاريع ذكاء اصطناعي مثل نظام للتعرف على الكائنات في الوقت الحقيقي باستخدام <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A7%D9%84%D9%85%D9%81%D8%A7%D9%87%D9%8A%D9%85-%D8%A7%D9%84%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A9-%D9%84%D8%AA%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%A2%D9%84%D8%A9-r1009/#%D8%A7%D9%84%D8%B4%D8%A8%D9%83%D8%A7%D8%AA-%D8%A7%D9%84%D8%B9%D8%B5%D8%A8%D9%8A%D8%A9-%D8%A7%D9%84%D8%AA%D9%84%D8%A7%D9%81%D9%8A%D9%81%D9%8A%D8%A9:~:text=%D9%81%D9%8A%20%D8%A7%D9%84%D9%88%D9%82%D8%AA%20%D8%A7%D9%84%D8%AD%D8%A7%D8%B6%D8%B1.-,%D8%A7%D9%84%D8%B4%D8%A8%D9%83%D8%A7%D8%AA%20%D8%A7%D9%84%D8%B9%D8%B5%D8%A8%D9%8A%D8%A9%20%D8%A7%D9%84%D8%AA%D9%84%D8%A7%D9%81%D9%8A%D9%81%D9%8A%D8%A9%20(Convolutional%20Neural%20Networks),-%D8%A3%D8%AD%D8%AF%D8%AB%D8%AA%20%D8%A8%D9%86%D9%8A%D8%A9%20%D8%A7%D9%84%D8%B4%D8%A8%D9%83%D8%A7%D8%AA" rel="">الشبكات العصبية الالتفافية</a> Convolutional Neural Networks أو نجرب توليد النصوص باستخدام نماذج المحولات <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AC%D9%88%D9%84%D8%A9-%D8%B3%D8%B1%D9%8A%D8%B9%D8%A9-%D9%84%D9%84%D8%A8%D8%AF%D8%A1-%D9%85%D8%B9-%D9%85%D9%83%D8%AA%D8%A8%D8%A9-%D8%A7%D9%84%D9%85%D8%AD%D9%88%D9%91%D9%84%D8%A7%D8%AA-transformers-r2351/" rel="">Transformers</a>، فنحن بحاجة لاختيار البنية التحتية المناسبة لمتطلبات مشروعنا. فتحتاج أغلب مشاريع الذكاء الاصطناعي وتعلم الآلة <a href="https://academy.hsoub.com/programming/advanced/%D8%A7%D9%84%D9%81%D8%B1%D9%82-%D8%A8%D9%8A%D9%86-%D9%88%D8%AD%D8%AF%D8%A9-%D8%A7%D9%84%D9%85%D8%B9%D8%A7%D9%84%D8%AC%D8%A9-%D8%A7%D9%84%D9%85%D8%B1%D9%83%D8%B2%D9%8A%D8%A9-cpu-%D9%88%D9%88%D8%AD%D8%AF%D8%A9-%D8%A7%D9%84%D9%85%D8%B9%D8%A7%D9%84%D8%AC%D8%A9-%D8%A7%D9%84%D8%B1%D8%B3%D9%88%D9%85%D9%8A%D8%A9-gpu-r2527/" rel="">وحدات المعالجة الرسومية GPUs</a> لقدراتها على المعالجة على التوازي parallel processing مما يسرِّع بشكل ملحوظ عملية تدريب نماذج الذكاء الاصطناعي واستخدامها في التنبؤ والاستدلال inference، خاصة عند التعامل مع النماذج اللغوية الضخمة <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D9%88%D9%84%D9%8A%D8%AF-%D8%A7%D9%84%D9%86%D8%B5%D9%88%D8%B5-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%A7%D9%84%D9%86%D9%85%D8%A7%D8%B0%D8%AC-%D8%A7%D9%84%D9%84%D8%BA%D9%88%D9%8A%D8%A9-%D8%A7%D9%84%D9%83%D8%A8%D9%8A%D8%B1%D8%A9-llms-r2380/" rel="">LLMs</a>. وعلينا أن نأخذ في الاعتبار بعض العوامل عند اختيارنا للمنصة التي توفر وحدات المعالجة الرسومية GPU مثل عدد وحدات كودا CUDA الموجودة في وحدة المعالجة الرسومية، وسعة تخزين ذاكرة الفيديو VRAM، وسعة مرور البيانات bandwidth من الذاكرة حيث أن لهذه المعايير تأثير في سرعة التدريب وسرعة الاستدلال وتكلفة التشغيل.
</p>

<p>
	ويمكننا -في حال تطوير مشروع يحتاج إلى بنية تحتية قوية- الوصول للبنية التحتية اللازمة لتدريب وتشغيل النماذج من خلال مزودي الخدمات السحابية cloud provider، ولكن في كثير من الأحيان تكون المشاريع الجانبية التي نطورها بهدف التعلم، لذا لا تكون هناك ميزانية أو جدوى من دفع مبالغ طائلة لتطوير المشروع، وفي هذه الحالة يمكن اللجوء لبدائل مجانية، أو استخدام الخطة المجانية أو الرصيد المتوفر للحسابات الجديدة على منصات مزودي الخدمات السحابية لتجربة خدماتهم، وكذلك هناك خيار استخدام <a href="https://academy.hsoub.com/apps/productivity/%D9%86%D8%A8%D8%B0%D8%A9-%D8%AA%D8%B9%D8%B1%D9%8A%D9%81%D9%8A%D8%A9-%D8%B9%D9%86-google-colab-%D9%88%D9%85%D8%A7%D8%B0%D8%A7-%D9%8A%D9%82%D8%AF%D9%85-%D9%84%D9%84%D9%85%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D9%86-r741/" rel="">كولاب collab</a> أو <a href="https://www.kaggle.com/" rel="external nofollow" target="_blank">كاجل Kaggle</a> وكلاهما منصات مملوكة لجوجل وتوفران استخدامًا محدودًا ولكنهما مناسبان لأغلب المشروعات الجانبية، فمثلًا يوفر كاجل Kaggle وحدات معالجة رسومية GPUs يمكن استخدامها بسعة متجددة أسبوعية لمدة 30 ساعة شرط أن يكون الحساب موثقًا برقم هاتف، وهي فترة كافية لتجربة تدريب النماذج الصغيرة ومتوسطة الحجم أو <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%B7%D8%B1%D9%8A%D9%82%D8%A9-%D8%A7%D9%84%D8%B5%D9%82%D9%84-fine-tune-%D9%84%D9%86%D9%85%D9%88%D8%B0%D8%AC-%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-%D9%85%D9%8F%D8%AF%D8%B1%D9%91%D9%8E%D8%A8-%D9%85%D9%8F%D8%B3%D8%A8%D9%82%D9%8B%D8%A7-r2367/" rel="">صقل نموذج</a> لغوي ضخم.
</p>

<h3 id="4">
	4. جمع البيانات المطلوبة للمشروع
</h3>

<p>
	كي نتمكن من بناء أي مشروع ذكاء اصطناعي وتعلم آلة، سنحتاج إلى البيانات، وتوفر مواقع مثل <a href="https://www.kaggle.com/datasets" rel="external nofollow" target="_blank">كاجل Kaggle</a> أو <a href="https://archive.ics.uci.edu/datasets" rel="external nofollow" target="_blank">مستودع جامعة كاليفورنيا للتعلم الآلي UCI Machine Learning Repository</a> مجموعات بيانات غنية ومجانية للاستخدام في تطوير النماذج وتحليل البيانات، ويفضل اختيار قواعد بيانات موثقة جيدًا حتى نفهم هيكلة البيانات وكيفية التعامل معها.
</p>

<h3 id="5-1">
	5. التعاون مع الآخرين لتجنب التشتت
</h3>

<p>
	قد يكون مشروع الذكاء الاصطناعي في البداية غير واضح، وهذا قد يشتتنا من وفرة وتنوع الأدوات والطرق المتاحة لتحقيق الهدف، يمكن حل هذه المشكلة بالتعاون النشط مع الآخرين في تطوير مشاريعك مما سيجعلها تجربة ممتعة وإنتاجية أكثر.  كما يمكننا الانضمام للمجتمعات التقنية المهتمة بالذكاء الاصطناعي في حال واجهنا أي مشكلة، فهي أماكن مناسبة لطرح الأسئلة ومشاركة مشاريع الذكاء الاصطناعي وإيجاد رفقاء للعمل على المشاريع، وكذلك يتيح لنا GitHub <a href="https://academy.hsoub.com/programming/workflow/git/%D9%83%D9%8A%D9%81-%D8%AA%D8%B3%D8%A7%D9%87%D9%85-%D9%81%D9%8A-%D9%85%D8%B4%D8%A7%D8%B1%D9%8A%D8%B9-%D9%85%D9%81%D8%AA%D9%88%D8%AD%D8%A9-%D8%A7%D9%84%D9%85%D8%B5%D8%AF%D8%B1-%D8%B9%D9%84%D9%89-github-r265/" rel="">المساهمة في المشاريع مفتوحة المصدر</a> مما يكسبنا خبرة عملية وتواصل قوي مع المطورين الخبراء في تطوير البرمجيات مفتوحة المصدر.
</p>

<p>
	إن التفاعل مع المجتمع ومشاريعه أو المساهمة في المناقشات الجارية بشأن الذكاء الاصطناعي يمكن أن يشكل فرصةً ثمينةً للتواصل مع <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D9%85%D9%86-%D9%87%D9%88-%D9%85%D9%87%D9%86%D8%AF%D8%B3-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-%D9%88%D9%85%D8%A7-%D8%A3%D8%A8%D8%B1%D8%B2-%D9%85%D9%87%D8%A7%D9%85%D9%87-r2319/" rel="">مهندسي ذكاء اصطناعي</a> خبراء يوفرون تقييمًا ومراجعةً مفيدة للغاية على مشاريع المبتدئين ويساهمون في تطوير أفكارهم وتشجيعهم على التطور المستمر والتعلم الفعال.
</p>

<h2 id="8-1">
	ثمانية أفكار مشاريع ذكاء اصطناعي تناسب المبتدئين
</h2>

<p>
	لنتعرف معًا على أبرز أفكار المشاريع المناسبة لشخص مبتدئ.
</p>

<h3 id="1aichatbotsystem">
	1. نظام دردشة آلي بالذكاء الاصطناعي AI Chatbot System
</h3>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="169377" href="https://academy.hsoub.com/uploads/monthly_2025_03/001.AIchatbot.jpg.09329dacc63c4c49a7e40f6a61a824b1.jpg" rel=""><img alt="001 AI chatbot" class="ipsImage ipsImage_thumbnailed" data-fileid="169377" data-ratio="52.25" data-unique="ixso7fcce" style="width: 400px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_03/001.AIchatbot.thumb.jpg.4b6a67756bf387c946f0798677484c91.jpg"></a>
</p>

<p>
	بناء نظام دردشة آلي بالذكاء الاصطناعي هو أحد أوضح مشاريع الذكاء الاصطناعي التي يمكن البدء منها من ناحية طريقة التنفيذ وخطواتها، فباستخدام معالجة اللغات الطبيعية و <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AE%D9%88%D8%A7%D8%B1%D8%B2%D9%85%D9%8A%D8%A7%D8%AA-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A/" rel="">خوارزميات تعلم الآلة</a> يمكن إنشاء نظام دردشة آلي يرد على استفسارات المستخدم. وتسهّل مكتبات مثل تنسرفلو <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D9%85%D9%86%D8%B5%D8%A9-%D8%AA%D9%86%D8%B3%D8%B1%D9%81%D9%84%D9%88-tensorflow-%D9%84%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-r2491/" rel="">Tensorflow</a> وباي تورش <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D8%A5%D8%B7%D8%A7%D8%B1-%D8%B9%D9%85%D9%84-%D8%A8%D8%A7%D9%8A-%D8%AA%D9%88%D8%B1%D8%B4-pytorch-%D9%88%D8%A3%D9%87%D9%85%D9%8A%D8%AA%D9%87-%D9%84%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-r2311/" rel="">PyTorch</a> من عملية بناء هذا النوع من الأنظمة بتوفيرها نماذج مدرّبة وأدوات سهلة الاستخدام للتعامل مع المدخلات والردود النصية. فباستخدام هذه الأدوات يمكن بناء نظام محادثة آلي chatbot بدون التعمق كثيرًا في الخوارزميات المعقدة مما يجعل هذا المشروع مناسبًا للمبتدئين.
</p>

<p>
	المهارات التي نحتاجها لهذا المشروع هي لغة البرمجة بايثون Python، ومعالجة اللغات الطبيعية NLP، والتعلم العميق DL، وأطر عمل الذكاء الاصطناعي مثل باي تورش <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D8%A5%D8%B7%D8%A7%D8%B1-%D8%B9%D9%85%D9%84-%D8%A8%D8%A7%D9%8A-%D8%AA%D9%88%D8%B1%D8%B4-pytorch-%D9%88%D8%A3%D9%87%D9%85%D9%8A%D8%AA%D9%87-%D9%84%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-r2311/" rel="">PyTorch</a> أو تنسورفلو TensorFlow، ودمج واجهة التطبيقات البرمجية <abbr title="Application Programming Interface | واجهة برمجية"><abbr title="Application Programming Interface | واجهة برمجية">API</abbr></abbr> integration
</p>

<p>
	من الأفكار الجيدة لتطبيقات دردشة آلية بالذكاء الاصطناعي نظام محادثة آلي chatbot يستخدم النصوص المستخلصة من برامج البودكاست المفضلة، مما يسمح بالدردشة مع المستضيف والضيوف حول المواضيع التي تغطيها البرامج، أو تصميم مدرب لياقة بدنية مخصص لكل مستخدم من خلال نظام دردشة آلي يخصص التدريب بناءً على معلومات المستخدم، وأهدافه، ومؤشراته الحيوية التي تجمعها الأجهزة الذكية القابلة للارتداء، أو نظام دردشة آلي يجيب عن الأسئلة التي تخص منطقة سكننا من خلال بيانات صفحات التواصل الاجتماعي ومصادر الأخبار المحلية.
</p>

<h3 id="2spamfiltering">
	2. فلترة الرسائل المزعجة Spam Filtering
</h3>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="169378" href="https://academy.hsoub.com/uploads/monthly_2025_03/002.Spamfiltering.jpg.247ca5a53fd7c95775c583d2dc93ca2f.jpg" rel=""><img alt="002 Spam filtering" class="ipsImage ipsImage_thumbnailed" data-fileid="169378" data-ratio="52.25" data-unique="5o80b26t9" style="width: 400px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_03/002.Spamfiltering.thumb.jpg.7be6c6f63529b400845e63168d047610.jpg"></a>
</p>

<p>
	يمكن تطبيق العديد من تقنيات الذكاء الاصطناعي في مشروع لفلترة الرسائل المزعجة spam filtering حيث نبني مُصنِّفًا لرسائل البريد الإلكتروني لتحديد ما إذا كانت الرسالة مزعجة أم لا. ولتحليل نص رسالة البريد الإلكتروني وتحديد الأنماط المثيرة للشك يمكن استخدام معالجة اللغات الطبيعية. وأبسط شكل للمشروع يتم من خلال مصنِّفات تحسب احتمالية كون رسالة البريد الإلكتروني مزعجة بناءً على ورود بعض الكلمات المفتاحية بها والتي وجدت من قبل في رسائل مزعجة. ويمكنك تجربة خوارزمية متجهات الدعم الآلي support vector machine من أجل تصنيف رسائل البريد الإلكتروني من خلال صفات الرسالة مثل بيانات المرسل ومحتوى الرسالة.
</p>

<p>
	ولنصبح أكثر تمكنًا يمكن استخدام نماذج التعلم العميق مثل الشبكات العصبية الالتفافية Convolution Neural Network أو الشبكات العصبية التكرارية Recurrent Neural Network لاكتشاف الأنماط المعقدة في النصوص أو معلومات عن البيانات المرسلة والأنماط الموجودة في الملفات المرفقة.
</p>

<p>
	المهارات التي نحتاجها لهذا المشروع هي: خوارزميات التعلم الآلي التصنيفية وخوارزمية متجهات الدعم الآلي SVM ولغة البرمجة بايثون Python، ومعالجة اللغات الطبيعية NLP، والتعلم العميق DL، ومعالجة البيانات Data preprocessing.
</p>

<h3 id="3translatorapp">
	3. تطبيق ترجمة بالذكاء الاصطناعي
</h3>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="169379" href="https://academy.hsoub.com/uploads/monthly_2025_03/003.Translatorapp.jpg.6ac70f6b2df85cb573cc062d5e726830.jpg" rel=""><img alt="003 Translator App" class="ipsImage ipsImage_thumbnailed" data-fileid="169379" data-ratio="52.25" data-unique="bu65pidxf" style="width: 400px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_03/003.Translatorapp.thumb.jpg.6e5c120139e63669541fdf247add4048.jpg"></a>
</p>

<p>
	يساعد بناء تطبيق ترجمة ذكي على تعلم بناء نماذج قادرة على التعامل مع مهام مثل تحديد اللغة language detection والترجمة وهيكلة الجمل، فيمكن استخدام معالجة اللغات الطبيعية Natural Language Processing، والترجمة الآلية العصبية Neural Maching Translation لإنشاء تطبيق لترجمة النصوص بين اللغات المختلفة. وباستخدام <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-%D9%85%D9%83%D8%AA%D8%A8%D8%A9-%D8%A7%D9%84%D9%85%D8%AD%D9%88%D9%91%D9%84%D8%A7%D8%AA-transformers-r2352/" rel="">معمارية المحولات Transformers</a> يمكننا تطوير نظام قادر على فهم سياق النص وتوفير ترجمة دقيقة له.
</p>

<p>
	للبدء في هذا المشروع سنحتاج لجمع مجموعات بيانات متعددة اللغات توفر نصوصًا وما يوازيها من ترجمة في لغات أخرى. وبمجرد تدريب نموذجنا الخاص فيمكن دمج واجهات التطبيق البرمجية مثل Google Translator أو DeepL لتحسين قدرات التطبيق في الترجمة في الوقت الحقيقي، تساعدنا هذه التطبيقات في تجنب بناء نظام ترجمة من الصفر وتجعلنا نركز على تحسين تجربة المستخدم.
</p>

<p>
	المهارات التي نحتاجها لتنفيذ هذا المشروع هي: لغة البرمجة بايثون Python، ومعالجة اللغات الطبيعية NLP، والترجمة الآلية العصبية NMT، وتقنيات معمارية المحولات transformer model techniques، ودمج واجهة التطبيق البرمجية <abbr title="Application Programming Interface | واجهة برمجية"><abbr title="Application Programming Interface | واجهة برمجية">API</abbr></abbr>.
</p>

<h3 id="4-1">
	4. التعرف على الأرقام المكتوبة بخط اليد
</h3>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="169380" href="https://academy.hsoub.com/uploads/monthly_2025_03/004.Handwrittendigitrecognition.jpg.d3c4be4058bc9c499dcefa4464c70331.jpg" rel=""><img alt="004 Handwritten digit recognition" class="ipsImage ipsImage_thumbnailed" data-fileid="169380" data-ratio="52.25" data-unique="nsrp85rm1" style="width: 400px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_03/004.Handwrittendigitrecognition.thumb.jpg.be57751ee359e2022b166387c0898f8d.jpg"></a>
</p>

<p>
	ننشئ في مشروع التعرف على الأرقام المكتوبة بخط اليد نموذجًا يتعرف ويصنف آليًا الأرقام من صفر إلى تسعة الموجودة في الصور. ولبناء النموذج سنحتاج أولًا لمعالجة الصور للتأكد من أبعادها الموحدة ومن تحويلها لصور بتدرج الرمادي يمكن التعبير عنها ببيانات أقل من الصور الملونة مما يسرع من معالجة الصور ويسهل التعامل معها، وتلي هذه الخطوة استخدام <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A7%D9%84%D9%85%D9%81%D8%A7%D9%87%D9%8A%D9%85-%D8%A7%D9%84%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A9-%D9%84%D8%AA%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%A2%D9%84%D8%A9-r1009/#%D8%A7%D9%84%D8%B4%D8%A8%D9%83%D8%A7%D8%AA-%D8%A7%D9%84%D8%B9%D8%B5%D8%A8%D9%8A%D8%A9-%D8%A7%D9%84%D8%AA%D9%84%D8%A7%D9%81%D9%8A%D9%81%D9%8A%D8%A9:~:text=%D9%81%D9%8A%20%D8%A7%D9%84%D9%88%D9%82%D8%AA%20%D8%A7%D9%84%D8%AD%D8%A7%D8%B6%D8%B1.-,%D8%A7%D9%84%D8%B4%D8%A8%D9%83%D8%A7%D8%AA%20%D8%A7%D9%84%D8%B9%D8%B5%D8%A8%D9%8A%D8%A9%20%D8%A7%D9%84%D8%AA%D9%84%D8%A7%D9%81%D9%8A%D9%81%D9%8A%D8%A9%20(Convolutional%20Neural%20Networks),-%D8%A3%D8%AD%D8%AF%D8%AB%D8%AA%20%D8%A8%D9%86%D9%8A%D8%A9%20%D8%A7%D9%84%D8%B4%D8%A8%D9%83%D8%A7%D8%AA" rel="">الشبكات العصبية الالتفافية</a> لتدريب نموذج يتعرف على الأنماط الموجودة في الصورة التي تميز كل رقم عن الآخر، وتعد مجموعة بيانات <a href="https://www.kaggle.com/competitions/digit-recognizer" rel="external nofollow" target="_blank">MNIST digit</a> من الأشهر استخدامًا لتدريب نماذج التعرف على الأرقام العربية، وإذا أردنا التميز فيمكن تجربة مجموعات بيانات أخرى مثل <a href="https://datacenter.aucegypt.edu/shazeem/" rel="external nofollow" target="_blank">MADBase</a> وهي مجموعة بيانات للأرقام العربية الشرقية أو الهندية (۰-۹)، ويمكن التوسع أكتر في المشروع وتطبيق تقنيات التعرف البصري على الحروف Optical Charachter Recognition أو OCR اختصارًا، وهذا يتجاوز التعرف على الأرقام إلى التعرف على نصوص كاملة في تنسيقات وخطوط وأحجام مختلفة، ويستخدم في تطبيقات مثل استخراج الأرقام والحروف من لوحات السيارات أو التعرف على الكلمات المكتوبة في اللافتات الإعلانية أو غيرها. يسمح لنا هذا المشروع بتجربة تطوير أفكار لتطبيقات حقيقية مثل المعالجة الآلية للاستمارات المكتوبة بخط اليد، أو بناء نظام للتعرف على أرقام الهواتف المحمولة.
</p>

<p>
	المهارات التي نحتاجها لهذا المشروع: لغة البرمجة بايثون Python، والشبكات العصبية الالتفافية CNN، وخوارزميات معالجة الصور، وأطر عمل ذكاء اصطناعي مثل <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D8%A5%D8%B7%D8%A7%D8%B1-%D8%B9%D9%85%D9%84-%D8%A8%D8%A7%D9%8A-%D8%AA%D9%88%D8%B1%D8%B4-pytorch-%D9%88%D8%A3%D9%87%D9%85%D9%8A%D8%AA%D9%87-%D9%84%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-r2311/" rel="">باي تورش PyTorch</a>
</p>

<h3 id="5-2">
	5. تصنيف الصور Image Classification
</h3>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="169381" href="https://academy.hsoub.com/uploads/monthly_2025_03/005.Imageclassification.jpg.10bfa2fe715f2367c3e2bcdd1edf2759.jpg" rel=""><img alt="005 Image classification" class="ipsImage ipsImage_thumbnailed" data-fileid="169381" data-ratio="52.25" data-unique="n5gav9tk3" style="width: 400px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_03/005.Imageclassification.thumb.jpg.a3955cd1f9bb5aef1ea22e6df18e51ee.jpg"></a>
</p>

<p>
	يمكن من خلال مشروع تصنيف الصور بناء نموذج يتعرف على العناصر الموجودة في الصور ويصنفها إلى أحد الأصناف المحددة مسبقًا آليًا. يبدأ المشروع بمجموعة بيانات تحتوي آلاف الصور المجمعة في أقسام مثل صور حيوانات أو مركبات أو أي من الكائنات الموجودة في حياتنا اليومية. بدايةً علينا أن نعالج الصور لجعلها موحدة الحجم والتنسيق، وبعد ذلك ندرب النموذج باستخدام شبكة عصبية التفافية CNN ليتعلم الأنماط البصرية بالصورة مثل الأشكال والألوان والخامات، ثم يمكن بعد ذلك تدريب واختبار النموذج لتصنيف صور جديدة لم يرها من قبل. وتكمن روعة هذه الفكرة في مدى إمكانية تنفيذها في العديد من التطبيقات الحياتية مثل التعرف على الوجوه، وتحليل الصور الطبية، وحتى تقنيات المركبات ذاتية القيادة.
</p>

<p>
	المهارات التي تحتاجها  لتنفيذ هذا المشروع هي: معرفة بإطار عمل لمعالجة الصور مثل openCV، والشبكات العصبية الالتفافية CNN، وأحد أطر عمل الذكاء الاصطناعي مثل تنسورفلو TensorFlow أو باي تورش PyTorch.
</p>

<h3 id="6">
	6. مساعد آلي لإعادة هيكلة الكود
</h3>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="169382" href="https://academy.hsoub.com/uploads/monthly_2025_03/006.Coderefactoringhelper.jpg.debb940a223e38688c39c240418d67a0.jpg" rel=""><img alt="006 code refactoring helper" class="ipsImage ipsImage_thumbnailed" data-fileid="169382" data-ratio="52.25" data-unique="7myjhj5sv" style="width: 400px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_03/006.Coderefactoringhelper.thumb.jpg.b5638fbf14b899754f4d57218e52db45.jpg"></a>
</p>

<p>
	يمكننا تطوير أداة المستخدمين في تحسين وتنقيح الأكواد الموجودة بدون تغيير وظيفتها. سنحتاج لإنشاء نموذج ذكاء اصطناعي يبحث عن المشكلات في الكود ويجد الأجزاء التي يمكن كتابتها بطرق أفضل وأكثر كفاءةً مثل <a href="https://academy.hsoub.com/programming/general/%D9%83%D9%8A%D9%81-%D8%AA%D9%83%D8%AA%D8%A8-%D9%83%D9%88%D8%AF-%D8%A8%D8%B1%D9%85%D8%AC%D9%8A-%D9%85%D8%AB%D9%84-%D9%85%D9%87%D9%86%D8%AF%D8%B3%D9%8A-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D8%A7%D8%AA-r2506/" rel="">مهندسي البرمجيات</a> المحترفين. يمكن البدء بجمع أمثلة من الأكواد الفوضوية والمحسنة من مصادر مفتوحة المصدر مثل جت هاب Github، وتدريب الذكاء الاصطناعي باستخدام تقنيات تعلم الآلة للتعرف على الأنماط، ومن ثم <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AF%D9%85%D8%AC-%D9%85%D8%B3%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-github-copilot-%D9%85%D8%B9-%D9%85%D8%AD%D8%B1%D8%B1-%D8%A7%D9%84%D8%A3%D9%83%D9%88%D8%A7%D8%AF-vs-code-r2521/" rel="">دمجه مع محرر الأكواد</a> أو <span style="display: none;"> </span><a href="https://academy.hsoub.com/programming/workflow/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D8%A8%D9%8A%D8%A6%D8%A9-%D8%A7%D9%84%D8%AA%D8%B7%D9%88%D9%8A%D8%B1-%D8%A7%D9%84%D9%85%D8%AA%D9%83%D8%A7%D9%85%D9%84%D8%A9-ide-r1513/" rel="">بيئة التطوير المتكاملة IDE</a> من أجل اقتراحات تحسينية في الزمن الحقيقي. وبمجرد التأكد من عمل الأداة بشكل صحيح يمكننا  توسيع اختصاصاتها لتشمل <a href="https://academy.hsoub.com/programming/general/%D8%A3%D9%86%D9%88%D8%A7%D8%B9-%D9%84%D8%BA%D8%A7%D8%AA-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D8%A9/" rel="">لغات برمجة</a> أكثر وميزات متقدمة مثل التأكد من أمان الكود وتخصيص الأسلوب.
</p>

<p>
	المهارات التي نحتاجها لتنفيذ هذا المشروع هي: معالجة اللغات الطبيعية NLP، ولغة البرمجة بايثون Python، ومعرفة بطريقة تطوير إضافات لبيئة التطوير المتكاملة IDE plugin development.
</p>

<h3 id="7">
	7. نظام ترشيح للأفلام
</h3>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="169383" href="https://academy.hsoub.com/uploads/monthly_2025_03/007.Movierecommendationsystem.jpg.cbbb06837ecb6a63f4db29ed95cb4442.jpg" rel=""><img alt="007 Movie Recommendation System" class="ipsImage ipsImage_thumbnailed" data-fileid="169383" data-ratio="52.25" data-unique="x5flo4rae" style="width: 400px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_03/007.Movierecommendationsystem.thumb.jpg.86872b8507420a6f060ba3b6318ba0be.jpg"></a>
</p>

<p>
	يسمح لنا بناء نظام لترشيح الأفلام بتخصيص تجربة اقتراح الأفلام من خلال محرك الترشيحات الذي يتوقع أي الأفلام سيستمتع بها المستخدمون بناءً على تفضيلاتهم السابقة. نحتاج للبدء بمجموعة بيانات مثل <a href="https://grouplens.org/datasets/movielens/" rel="external nofollow" target="_blank">MovieLens</a> تحتوي على تقييمات المستخدم وتفاصيل الأفلام وأنواعها. سنحلل في هذا المشروع سلوك المستخدم ونحدد الأنماط من أجل اقتراح أفلام لم يشاهدها المستخدمون من قبل ولكن من المحتمل أن يحبوها. لتحقيق هذا، يمكن استخدام تقنيات مثل الترشيح التعاوني collaborative filtering والذي يوجِد أوجه التشابه بين المستخدمين أو الأفلام بناءً على تصنيفهم وتصفية المحتوى، وتقترح هذه الطريقة الأفلام المشابهة لتلك التي أحبها المستخدم في السابق، بمجرد تمكننا من تنفيذ المشروع، سنكتسب المهارات اللازمة لتطبيق أنظمة الترشيح في سياقات مختلفة، وبالرغم من أن النظام الذي نطوره قد لا يكون قابلًا للتشغيل مع مستخدمين حقيقين إلا أنه يوفر تدريبًا جيدًا يمكّننا من بناء أنظمة مشابهة، سواءً من أجل منصات بث الأفلام والمسلسلات أو منصات التجارة الإلكترونية أو حتى منصات التواصل الاجتماعي.
</p>

<p>
	المهارات التي نحتاجها لتنفيذ هذا المشروع هي<span>: </span>الترشيح التعاوني Collaborative filtering، والتصفية حسب المحتوى content-based filtering وتحليل مصفوفة آراء المستخدمين Matrix Factorization، ولغة البرمجة بايثون Python، وخوارزميات تعلم الآلة.
</p>

<h3 id="8-2">
	8. محلل السير الذاتية
</h3>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="jpg" data-fileid="169376" href="https://academy.hsoub.com/uploads/monthly_2025_03/008.Resumeparser.jpg.8e9731579bc043d2c224e6f19555f1ef.jpg" rel=""><img alt="008 resume parser" class="ipsImage ipsImage_thumbnailed" data-fileid="169376" data-ratio="52.25" data-unique="5oscholjq" style="width: 400px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_03/008.Resumeparser.thumb.jpg.304da772485e89c10aa9174b32d1ed67.jpg"></a>
</p>

<p>
	يمكن بناء مشروع محلل للسير الذاتية يستخرج المعلومات المهمة آليًا من السير الذاتية مثل الاسم ومعلومات التواصل والتعليم وخبرة العمل. سنبدأ بجمع السير الذاتية من مجموعات البيانات الموجودة في مصادر مفتوحة مثل <a href="https://www.kaggle.com/datasets/snehaanbhawal/resume-dataset" rel="external nofollow" target="_blank">كاجل Kaggle</a> بتنسيقات مختلفة مثل PDF أو Word أو غيرها، وباستخدام تقنيات معالجة اللغات الطبيعية NLP سنحلل ونفصل النصوص الموجودة. بتحديدنا لأنماط محددة في التواريخ أو المسميات الوظيفية أو أسماء الشركات سنتمكن من تدريب النموذج لاكتشاف المعلومات الضرورية. ويمكن أيضًا استخدام التعرف على الكيانات المسماة Named Entity Recognition‎  -أو NER اختصارًا- للتعرف على كيانات مثل الجامعات والدرجات العلمية والمهارات. ويمكن بمجرد تحليل البيانات تخزينها بشكل مهيكل في قاعدة بيانات تسهّل الوصول للبيانات ومقارنتها. ولتحسين هذا المشروع وتطويره يمكننا دمجه في نظام لتتبع المتقدمين على الوظائف لمساعدة فرق الموارد البشرية على التعامل مع عدد ضخم من السير الذاتية بكفاءة ودقة.
</p>

<p>
	المهارات التي نحتاجها لتنفيذ هذا المشروع هي: التعرف على الكيانات المسماة NER، ولغة بايثون Python، ومعالجة اللغات الطبيعية NLP، واستخراج البيانات وتحليلها.
</p>
<iframe allowfullscreen="" class="ipsEmbed_finishedLoading" data-controller="core.front.core.autosizeiframe" data-embedauthorid="3889" data-embedcontent="" data-embedid="embed5027965654" src="https://academy.hsoub.com/files/29-%D8%B9%D8%B4%D8%B1%D8%A9-%D9%85%D8%B4%D8%A7%D8%B1%D9%8A%D8%B9-%D8%B9%D9%85%D9%84%D9%8A%D8%A9-%D8%B9%D9%86-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A/?do=embed" style="overflow: hidden; height: 468px; max-width: 500px; margin:auto;"></iframe>

<h2 id="-1">
	الخلاصة
</h2>

<p>
	تناولنا في هذه المقالة بعض أفكار مشاريع الذكاء الاصطناعي المفيدة للمهتمين بتعلم الذكاء الاصطناعي. قد نواجه أثناء تطبيق هذه المشاريع العديد من التحديات والعقبات، لكننا بالمقابل سنتعلم التعامل مع الخوارزميات والأدوات والمكتبات البرمجية بكفاءة ونصقل خبرتنا البرمجية ونبني معرض أعمال متميز. وللمهتمين بتعلم المهارات اللازمة لتنفيذ هذه المشاريع بسرعة وتطبيقها بفعالية، تقدم أكاديمية حسوب <a href="https://academy.hsoub.com/store/12-%D8%AF%D9%88%D8%B1%D8%A9-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A/" rel="">دورة الذكاء الاصطناعي</a> المتميزة التي توفر الكثير من الوقت في تعلم الذكاء الاصطناعي من خلال دمج الجانب النظري والتطبيقي، وتحتوي العديد من التطبيقات والأمثلة العملية المفيدة بدايةً من التعامل مع البيانات وتحليلها وصولًا إلى تطبيقات متقدمة مثل النماذج اللغوية الضخمة، والتي تضمن لك بناء معرض أعمال قوي والحصول على فرصة عمل مناسبة.
</p>

<p>
	ترجمة وبتصرف لمقال <a href="https://www.digitalocean.com/resources/articles/ai-side-project-ideas#8-resume-parser" rel="external nofollow" target="_blank">8 AI Side Project Ideas for Beginners</a> لصاحبته <a href="https://www.digitalocean.com/resources/authors/sujathar" rel="external nofollow" target="_blank">Sujatha R</a>.
</p>

<h2 id="-2">
	اقرأ أيضًا
</h2>

<ul>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A3%D9%85%D8%AB%D9%84%D8%A9-%D8%B9%D9%84%D9%89-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-r2396/" rel="">أمثلة على الذكاء الاصطناعي</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D8%A3%D9%87%D9%85-%D9%85%D8%B4%D8%A7%D8%B1%D9%8A%D8%B9-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-r2372/" rel="">تعرف على أهم مشاريع الذكاء الاصطناعي</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A7%D9%84%D9%85%D8%B9%D8%A7%D9%84%D8%AC%D8%A9-%D8%A7%D9%84%D9%85%D9%8F%D8%B3%D8%A8%D9%82%D8%A9-%D9%84%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%82%D8%A8%D9%84-%D8%AA%D9%85%D8%B1%D9%8A%D8%B1%D9%87%D8%A7-%D9%84%D9%86%D9%85%D8%A7%D8%B0%D8%AC-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-r2365/" rel="">المعالجة المُسبقة للبيانات قبل تمريرها لنماذج الذكاء الاصطناعي</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%B7%D8%B1%D9%8A%D9%82%D8%A9-%D8%A7%D9%84%D8%B5%D9%82%D9%84-fine-tune-%D9%84%D9%86%D9%85%D9%88%D8%B0%D8%AC-%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-%D9%85%D9%8F%D8%AF%D8%B1%D9%91%D9%8E%D8%A8-%D9%85%D9%8F%D8%B3%D8%A8%D9%82%D9%8B%D8%A7-r2367/" rel="">طريقة الصقل Fine-Tune لنموذج ذكاء اصطناعي مُدرَّب مُسبقًا</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">2535</guid><pubDate>Fri, 14 Mar 2025 12:00:00 +0000</pubDate></item><item><title>&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; Code Llama &#x644;&#x643;&#x62A;&#x627;&#x628;&#x629; &#x648;&#x62A;&#x635;&#x62D;&#x64A;&#x62D; &#x623;&#x643;&#x648;&#x627;&#x62F; CSS</title><link>https://academy.hsoub.com/programming/artificial-intelligence/%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-code-llama-%D9%84%D9%83%D8%AA%D8%A7%D8%A8%D8%A9-%D9%88%D8%AA%D8%B5%D8%AD%D9%8A%D8%AD-%D8%A3%D9%83%D9%88%D8%A7%D8%AF-css-r2531/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2025_03/1.---CSS---.png.40046efc2bb22e1125aa4947dfffe5ac.png" /></p>
<p>
	سنتعرف في هذا المقال على كيفية استخدام نموذج الذكاء الاصطناعي Code Llama في كتابة وتحسين أكواد CSS ونوضح كيفية توليد الأكواد باستخدام أوامر مكتوبة بلغة طبيعية، بالإضافة إلى تصحيح الأخطاء الشائعة وتحسين الأداء. كما سنستعرض عدة أمثلة عملية توضح كيفية دمج Code Llama في حالات عديدة تفيد <a href="https://academy.hsoub.com/programming/general/%D8%AA%D8%B7%D9%88%D9%8A%D8%B1-%D8%A7%D9%84%D9%88%D8%A7%D8%AC%D9%87%D8%A9-%D8%A7%D9%84%D8%A3%D9%85%D8%A7%D9%85%D9%8A%D8%A9-frontend-web-development/" rel="">مطوري الواجهة الأمامية</a> في عملهم.
</p>

<h2 id="codellama">
	ما هو Code Llama؟
</h2>

<p>
	Code Llama هو نموذج ذكاء اصطناعي مفتوح المصدر طورته شركة ميتا في أغسطس 2023، وهو مبني على نموذج <a href="https://www.llama.com/llama2/" rel="external nofollow">Llama 2</a> مع تحسينات مخصصة لمعالجة وتوليد الأكواد البرمجية. دُرّب النموذج على مجموعات بيانات متخصصة في البرمجة، مما جعله أداة قوية لمساعدة المطورين في كتابة الأكواد، وتصحيحها، وتحسينها، بالإضافة إلى تسريع عمليات التطوير.
</p>

<h2 id="">
	المتطلبات
</h2>

<p>
	نحتاج المتطلبات التالية لتنفيذ خطوات هذا المقال:
</p>

<ul>
	<li>
		معرفة أساسية بلغات تطوير الويب <a href="https://academy.hsoub.com/programming/html/" rel="">HTML</a> و <a href="https://academy.hsoub.com/programming/css/" rel="">CSS</a>
	</li>
	<li>
		معرفة <a href="https://academy.hsoub.com/programming/python/%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D8%A9-%D8%A8%D9%84%D8%BA%D8%A9-%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-r1815/" rel="">بأساسيات لغة بايثون</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/python/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-3-%D9%88%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF-%D8%A8%D9%8A%D8%A6%D8%AA%D9%87-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D8%A9-%D8%B9%D9%84%D9%89-%D9%88%D9%8A%D9%86%D8%AF%D9%88%D8%B2-10-r710/" rel="">تثبيت بايثون</a> على الجهاز المحلي
	</li>
	<li>
		تثبيت <a href="https://academy.hsoub.com/programming/python/%D9%85%D8%AD%D8%B1%D8%B1-%D8%A3%D9%83%D9%88%D8%A7%D8%AF-%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86/" rel="">محرر أكواد بايثون</a> مثل Jupyter Notebook أو Visual Studio Code
	</li>
	<li>
		جهاز حاسوب بمواصفات جيدة، يجب أن لا تقل الذاكرة RAM عن 8 جيجابايت ويفضل أن تكون 16 جيجابايت
	</li>
</ul>

<h2 id="codellamaollamalangchain">
	تثبيت Code Llama واستخدامه محليًا
</h2>

<p>
	سنعمل على تثبيت Code Llama واستخدامه محليًا عن طريق Ollama و LangChain يُعد Ollama أداة قوية لإدارة النماذج اللغوية الذكية وتشغيلها محليًا وتقدم Ollama مجموعة من النماذج اللغوية التي يمكن تنزيلها وتشغيلها بسهولة، من بينها Code Llama و <a href="https://www.deepseek.com/" rel="external nofollow">Deepseek-r1</a> و <a href="https://www.llama.com/" rel="external nofollow">Llama 3.3</a>. بالإضافة إلى النسخ الأساسية التي توفرها الشركات المنتجة للنماذج، كما تقدم أيضًا نسخًا محسَّنة باستخدام تقنيات التكميم Quantization لجعل النماذج أكثر كفاءة وأقل استهلاكًا للذاكرة، مع الحفاظ على أداء جيد. لتثبيت Code Llama واستخدامه محليًا عن طريق Ollama، علينا أولًا تثبيت Ollama على حاسوبنا، ثم تثبيت النموذج الذي نرغب في استخدامه وهو في حالتنا Code Llama كما سنشرح في الفقرات التالية.
</p>

<h3 id="ollama">
	تثبيت Ollama
</h3>

<p>
	لتثبيت Ollama على جهازنا المحلي، نذهب إلى رابط تحميل <a href="https://ollama.com/download" rel="external nofollow">Ollama</a> ونختار النسخة المناسبة لنظام تشغيلنا. في حالتنا سننزل الملف OllamaSetup.exe لنظام تشغيل ويندوز ثم نثبت Ollama عبر تشغيل هذا الملف. بعد اكتمال التثبيت، سيكون Ollama جاهزًا للاستخدام.
</p>

<h3 id="codellama-1">
	تثبيت وتشغيل Code Llama
</h3>

<p>
	يمكننا تحميل وتشغيل Code Llama بسهولة من خلال Ollama. للقيام بذلك نذهب إلى رابط نموذج <a href="https://ollama.com/library/codellama" rel="external nofollow">Code Llama</a> على موقع Ollama، ثم نختار النسخة المناسبة. يمكن عرض جميع النسخ المتاحة عبر النقر على View all كما توضح الصورة التالية:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169290" href="https://academy.hsoub.com/uploads/monthly_2025_03/001___.png.820f9afa50e313a943fc1ce260235b75.png" rel=""><img alt="001 نسخ النموذج المتاحة" class="ipsImage ipsImage_thumbnailed" data-fileid="169290" data-ratio="68.50" data-unique="1rob7ii8x" style="width: 600px; height: auto;" width="900" src="https://academy.hsoub.com/uploads/monthly_2025_03/001___.thumb.png.d31b7767047bcce04adc49619885a7c4.png"></a>
</p>

<p>
	بعد اختيار النسخة المناسبة، ننسخ كود تثبيت النموذج الظاهر أعلى يمين الصفحة، ثم نفتح <a href="https://academy.hsoub.com/devops/linux/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D8%B7%D8%B1%D9%81%D9%8A%D9%91%D8%A9-%D9%84%D9%8A%D9%86%D9%83%D8%B3-linux-terminal-r18/" rel="">الطرفية</a>، وننفّذ الكود لتثبيت النموذج باستخدام Ollama.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169291" href="https://academy.hsoub.com/uploads/monthly_2025_03/002__.png.927e11a1b936746de99962ec986689b1.png" rel=""><img alt="002 تثبيت النموذج" class="ipsImage ipsImage_thumbnailed" data-fileid="169291" data-unique="3otke7hcx" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/002__.thumb.png.2db9902cc85a795c1d493aa6597001f9.png"> </a>
</p>

<p>
	بهذا نكون قد نجحنا في تشغيل Code Llama على جهازنا، ويمكننا الاستفادة من إمكانياته في كتابة وتحسين أكواد CSS. قبل استعراض أمثلة عملية لاستخدام النموذج دعونا نستعرض أهم الأوامر التي توفرها Ollama للتعامل مع نماذج الذكاء الاصطناعي.
</p>

<h3 id="ollama-1">
	أوامر مهمة لاستخدام Ollama
</h3>

<p>
	فيما يلي مجموعة أوامر Ollama تساعدنا في التعامل مع نماذج الذكاء الاصطناعي:
</p>

<table>
	<thead>
		<tr>
			<th>
				الأمر
			</th>
			<th>
				الوظيفة
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				ollama run
			</td>
			<td>
				تشغيل النموذج وإذا لم يكن مثبتًا، سيجري تنزيله تلقائيًا
			</td>
		</tr>
		<tr>
			<td>
				ollama pull
			</td>
			<td>
				تنزيل وتثبيت النموذج
			</td>
		</tr>
		<tr>
			<td>
				ollama rm
			</td>
			<td>
				حذف النموذج من الجهاز
			</td>
		</tr>
		<tr>
			<td>
				ollama list
			</td>
			<td>
				عرض جميع النماذج المثبتة
			</td>
		</tr>
		<tr>
			<td>
				ollama ps
			</td>
			<td>
				عرض قائمة بالنماذج التي تعمل حاليًا
			</td>
		</tr>
	</tbody>
</table>

<h3 id="langchain">
	استخدام LangChain
</h3>

<p>
	بعد تثبيت Ollama وتشغيل Code Llama، يمكننا الاستفادة من LangChain لتسهيل التعامل مع النموذج وإدارته برمجيًا داخل التطبيقات. حيث يعد LangChain إطار عمل متكامل مصمم لتبسيط استخدام النماذج اللغوية داخل المشاريع البرمجية، وهو يوفر أدوات مرنة تتيح للمطورين التفاعل مع هذه النماذج بطريقة منظمة ويتيح لنا دمج النماذج الذكية بسهولة داخل التطبيقات دون الحاجة إلى تشغيل أوامر معقدة يدويًا عبر الطرفية Terminal، مما يسهل التشغيل التلقائي للمهام، ويسرّع عملية التطوير ويعزز الإنتاجية.
</p>

<p>
	لتشغيل Code Llama باستخدام LangChain نحتاج أولًا إلى تثبيت لغة بايثون على الجهاز، بالإضافة إلى تثبيت محرر أكواد أو بيئة عمل مناسبة لتشغيل الأوامر البرمجية، سنستخدم في مقالنا Jupyter Notebook وهي بيئة عمل تفاعلية شائعة تتيح تنفيذ الأوامر البرمجية وتجربة النماذج الذكية بسلاسة. 
</p>

<p>
	بعد تجهيز بيئة العمل، سنبدأ بتثبيت المكتبات الأساسية التي نحتاجها لتشغيل LangChain و Ollama باستخدام الأوامر التالية:
</p>

<pre class="ipsCode">!pip install langchain 
!pip install langchain_community 
!pip install ollama
</pre>

<p>
	بعد ذلك، يمكننا استدعاء النموذج المطلوب من خلال Ollama بمساعدة LangChain:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_2848_6" style=""><span class="kwd">from</span><span class="pln"> langchain_community</span><span class="pun">.</span><span class="pln">llms </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Ollama</span><span class="pln">
codellama </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Ollama</span><span class="pun">(</span><span class="pln">model</span><span class="pun">=</span><span class="str">"codellama:7b-instruct-q2_K"</span><span class="pun">)</span></pre>

<p>
	يمكننا استخدام الأمر <code>invoke</code> لتوليد الكود وعرضه مرة واحدة:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_2848_8" style=""><span class="pln">response </span><span class="pun">=</span><span class="pln"> codellama</span><span class="pun">.</span><span class="pln">invoke</span><span class="pun">(</span><span class="str">"اكتب كود CSS يقوم بجعل جميع عناصر &lt;p&gt; في الصفحة بمحاذاة وسطية مع تغيير لون النص إلى الأحمر"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">response</span><span class="pun">)</span></pre>

<p>
	بدلاً من انتظار توليد الكود دفعة واحدة، يمكننا استخدام الأمر <code>stream</code> لعرض الكود بشكل تدريجي أثناء التوليد:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_2848_10" style=""><span class="kwd">for</span><span class="pln"> chunk </span><span class="kwd">in</span><span class="pln"> codellama</span><span class="pun">.</span><span class="pln">stream</span><span class="pun">(</span><span class="str">"اكتب كود CSS يقوم بجعل جميع عناصر &lt;p&gt; في الصفحة بمحاذاة وسطية مع تغيير لون النص إلى الأحمر"</span><span class="pun">):</span><span class="pln">
    </span><span class="kwd">print</span><span class="pun">(</span><span class="pln">chunk</span><span class="pun">,</span><span class="pln"> end </span><span class="pun">=</span><span class="pln"> </span><span class="str">""</span><span class="pun">)</span></pre>

<p>
	عند تشغيل أحد الأوامر السابقة، سيُولد النموذج كود مشابه لما يلي:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_2848_14" style=""><span class="pln">p {
    text-align: center;
    color: red;
}</span></pre>

<p>
	نلاحظ في بعض الأحيان عند توليد الكود أن النموذج قد يضيف تعليقات أو شروحات باللغة الإنجليزية، أو يقدم لنا أكثر من طريقة لكتابة الكود، لاحظ الصورة التالية:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169292" href="https://academy.hsoub.com/uploads/monthly_2025_03/003___1.png.a3db84095808926be15d95316be157cb.png" rel=""><img alt="003 نتيجة الطلب المرسل1" class="ipsImage ipsImage_thumbnailed" data-fileid="169292" data-unique="8xzq96fkr" style="width: 750px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/003___1.thumb.png.19e90bf9898d45d861d55d8e802bfe0b.png"> </a>
</p>

<p>
	في الخطوات القادمة، سنعمل على ضبط النموذج لتوليد الأكواد بدقة وتحكم أكبر.
</p>

<h2 id="csscodellama">
	حالات مختلفة لتوليد أكواد CSS باستخدام Code Llama
</h2>

<p>
	يمكننا استخدام Code Llama لإنشاء أكواد CSS بعدة طرق كما في الأمثلة التالية:
</p>

<h3 id="htmlcss">
	توليد أكواد HTML مع CSS
</h3>

<p>
	للاستفادة المثلى من نموذج Code Llama سنطلب منه مساعدتنا في توليد كود HTML و CSS بناءً على وصف نصي بسيط.على سبيل المثال، يمكننا إعطاء وصف بسيط للعنصر الذي نريد تصميمه مثل زر أو بطاقة، وسيُولد النموذج الكود المطلوب. في المثال التالي، سنطلب من Code Llama توليد كود HTML و CSS لإنشاء زر بتنسيق معين. سنرسل المُوجّه prompt التالي للنموذج:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_2848_16" style=""><span class="com"># تحديد المُوجّه </span><span class="pln">
prompt </span><span class="pun">=</span><span class="pln"> </span><span class="str">"""
[system] أنت مساعد ذكي متخصص في كتابة أكواد HTML و CSS بطريقة منظمة ومفهومة.

[user] أريد منك إنشاء كود HTML و CSS لزر أزرق بنص أبيض، وعند تمرير الفأرة عليه يصبح لونه أخضر.
"""</span><span class="pln">
</span><span class="com"># تنفيذ الطلب وطباعة الكود الناتج </span><span class="pln">
</span><span class="kwd">for</span><span class="pln"> chunk </span><span class="kwd">in</span><span class="pln"> codellama</span><span class="pun">.</span><span class="pln">stream</span><span class="pun">(</span><span class="pln">prompt</span><span class="pun">):</span><span class="pln">
    </span><span class="kwd">print</span><span class="pun">(</span><span class="pln">chunk</span><span class="pun">,</span><span class="pln"> end </span><span class="pun">=</span><span class="pln"> </span><span class="str">""</span><span class="pun">)</span></pre>

<p>
	سيُولد النموذج كود مشابه لما يلي:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_2848_18" style=""><span class="pln">HTML:
</span><span class="tag">&lt;button</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"my-button"</span><span class="tag">&gt;</span><span class="pln">Click me</span><span class="tag">&lt;/button&gt;</span><span class="pln">
CSS:
.my-button {
  background-color: #2277ff;
  color: #fff;
}
.my-button:hover {
  background-color: #339900;
  color: #fff;
}</span></pre>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169293" href="https://academy.hsoub.com/uploads/monthly_2025_03/004___2.png.be1731780ad45796e1fa13cda81fc11e.png" rel=""><img alt="004 نتيجة الطلب المرسل2" class="ipsImage ipsImage_thumbnailed" data-fileid="169293" data-unique="ewohl6j73" style="width: 750px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/004___2.thumb.png.d5a80b44c6a6e594abfd8d4f8e30b291.png"> </a>
</p>

<p>
	يمكننا ضبط المُوجّه بالشكل الذي نرغب فيه حتى نصل للنتيجة المطلوبة، لنلاحظ المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_2848_20" style=""><span class="pln">prompt </span><span class="pun">=</span><span class="pln"> </span><span class="str">"""
[system] أنت مساعد ذكي متخصص في كتابة أكواد HTML و CSS بطريقة منظمة ومفهومة.
يجب أن تلتزم بمعايير كتابة الكود النظيف وتوفير التعليقات التوضيحية داخل الأكواد.

[user] أريد منك إنشاء كود HTML و CSS لزر أزرق بنص أبيض، وعند تمرير الفأرة عليه يصبح لونه أخضر.
"""</span></pre>

<h3 id="csshtml">
	توليد كود CSS لتنسيق كود HTML
</h3>

<p>
	في هذا المثال، سنعرض كيف يمكن لكود Code Llama توليد كود CSS لينسق كود HTML موجود مسبقًا. سنبدأ بتهيئة النموذج:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_2848_22" style=""><span class="com"># Code Llama تهيئة نموذج </span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> langchain_community</span><span class="pun">.</span><span class="pln">llms </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Ollama</span><span class="pln">
codellama </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Ollama</span><span class="pun">(</span><span class="pln">model</span><span class="pun">=</span><span class="str">"codellama:7b-instruct-q2_K"</span><span class="pun">)</span></pre>

<p>
	ثم نجهز كود HTML الذي سنرسله للنموذج:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_2848_24" style=""><span class="pln"># HTML كود 
html_code = """
</span><span class="tag">&lt;div</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"card"</span><span class="tag">&gt;</span><span class="pln">
    </span><span class="tag">&lt;img</span><span class="pln"> </span><span class="atn">src</span><span class="pun">=</span><span class="atv">"profile.jpg"</span><span class="pln"> </span><span class="atn">alt</span><span class="pun">=</span><span class="atv">"Profile Image"</span><span class="tag">&gt;</span><span class="pln">
    </span><span class="tag">&lt;h2&gt;</span><span class="pln">John Doe</span><span class="tag">&lt;/h2&gt;</span><span class="pln">
    </span><span class="tag">&lt;p&gt;</span><span class="pln">Web Developer</span><span class="tag">&lt;/p&gt;</span><span class="pln">
</span><span class="tag">&lt;/div&gt;</span><span class="pln">
"""</span></pre>

<p>
	بعد ذلك، نحدد المُوجّه ونضيف إليه كود HTML:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_2848_26" style=""><span class="com"># تحديد المُوجّه </span><span class="pln">
prompt </span><span class="pun">=</span><span class="pln"> f</span><span class="str">"""
[system] أنت مساعد ذكاء اصطناعي متخصص في CSS. 
مهمتك هي توليد كود CSS بناءً على كود HTML المقدم لك.
يجب أن يكون الكود متجاوبًا ويستخدم Flexbox لتنظيم العناصر.
[user] هذا هو كود HTML:
{html_code}
قم بإنشاء كود CSS مناسب لهذا الهيكل.
"""</span></pre>

<p>
	وأخيرًا، نرسل المُوجّه للنموذج:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_2848_28" style=""><span class="com"># تنفيذ الطلب وطباعة الكود الناتج </span><span class="pln">
</span><span class="kwd">for</span><span class="pln"> chunk </span><span class="kwd">in</span><span class="pln"> codellama</span><span class="pun">.</span><span class="pln">stream</span><span class="pun">(</span><span class="pln">prompt</span><span class="pun">):</span><span class="pln">
    </span><span class="kwd">print</span><span class="pun">(</span><span class="pln">chunk</span><span class="pun">,</span><span class="pln"> end </span><span class="pun">=</span><span class="pln"> </span><span class="str">""</span><span class="pun">)</span></pre>

<p>
	سيُولد النموذج كودًا مشابهًا لهذا:
</p>

<pre class="ipsCode prettyprint lang-css prettyprinted" id="ips_uid_2848_30" style=""><span class="pun">*</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">box-sizing</span><span class="pun">:</span><span class="pln"> border-box</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
body </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">font-family</span><span class="pun">:</span><span class="pln"> Arial</span><span class="pun">,</span><span class="pln"> sans-serif</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">margin</span><span class="pun">:</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">padding</span><span class="pun">:</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="pun">.</span><span class="pln">card </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">display</span><span class="pun">:</span><span class="pln"> flex</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">flex-direction</span><span class="pun">:</span><span class="pln"> column</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">align-items</span><span class="pun">:</span><span class="pln"> center</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">justify-content</span><span class="pun">:</span><span class="pln"> center</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">height</span><span class="pun">:</span><span class="pln"> </span><span class="lit">200px</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">background-color</span><span class="pun">:</span><span class="pln"> </span><span class="lit">#f7f7f7</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">border</span><span class="pun">:</span><span class="pln"> </span><span class="lit">1px</span><span class="pln"> solid </span><span class="lit">#ddd</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">border-radius</span><span class="pun">:</span><span class="pln"> </span><span class="lit">5px</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">padding</span><span class="pun">:</span><span class="pln"> </span><span class="lit">10px</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="pun">.</span><span class="pln">card img </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">width</span><span class="pun">:</span><span class="pln"> </span><span class="lit">100%</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">height</span><span class="pun">:</span><span class="pln"> auto</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">margin-bottom</span><span class="pun">:</span><span class="pln"> </span><span class="lit">20px</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="pun">.</span><span class="pln">card h2 </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">font-size</span><span class="pun">:</span><span class="pln"> </span><span class="lit">18px</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">margin</span><span class="pun">:</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">padding</span><span class="pun">:</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="pun">.</span><span class="pln">card p </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">font-size</span><span class="pun">:</span><span class="pln"> </span><span class="lit">14px</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">margin-top</span><span class="pun">:</span><span class="pln"> </span><span class="lit">5px</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">padding-left</span><span class="pun">:</span><span class="pln"> </span><span class="lit">20px</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">padding-right</span><span class="pun">:</span><span class="pln"> </span><span class="lit">20px</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span></pre>

<h2 id="csscodellama-1">
	تصحيح أكواد CSS باستخدام Code Llama
</h2>

<p>
	إذا كان لدينا كود CSS يحتوي على أخطاء، يمكننا استخدام Code Llama لاكتشاف الأخطاء وتصحيحها. يمكن أن يشمل ذلك تصحيح الأخطاء النحوية في CSS مثل نسيان فاصلة منقوطة أو أقواس، وإصلاح القيم غير الصحيحة للخصائص.
</p>

<p>
	على سبيل المثال سنقدّم للنموذج كود CSS يضم مجموعة من الخصائص التي تتضمن بعض الأخطاء، وذلك لاختبار قدرته على تصحيحها.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_2848_32" style=""><span class="com">#Code Llama تهيئة نموذج </span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> langchain_community</span><span class="pun">.</span><span class="pln">llms </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Ollama</span><span class="pln">
codellama </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Ollama</span><span class="pun">(</span><span class="pln">model</span><span class="pun">=</span><span class="str">"codellama:7b-instruct-q2_K"</span><span class="pun">)</span><span class="pln">

</span><span class="com"># كود يحتوي على أخطاء</span><span class="pln">
css_code_with_errors </span><span class="pun">=</span><span class="pln"> </span><span class="str">"""
.card {
    width: 300px
    background-color: white;
    border-radius: 10px;
    box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1)
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    color: 100px;
}
"""</span><span class="pln">
</span><span class="com"># إعداد المُوجّه </span><span class="pln">
prompt </span><span class="pun">=</span><span class="pln"> f</span><span class="str">"""
[system] أنت مساعد برمجي متخصص في CSS. مهمتك هي تصحيح وتحسين كود CSS المقدم من المستخدم.

[user] هذا هو كود CSS الخاص بي، لكنه يحتوي على بعض الأخطاء. الرجاء تصحيحه وتحسينه:
{css_code_with_errors}
"""</span><span class="pln">
</span><span class="com"># تنفيذ الطلب وطباعة الكود الناتج </span><span class="pln">
</span><span class="kwd">for</span><span class="pln"> chunk </span><span class="kwd">in</span><span class="pln"> codellama</span><span class="pun">.</span><span class="pln">stream</span><span class="pun">(</span><span class="pln">prompt</span><span class="pun">):</span><span class="pln">
    </span><span class="kwd">print</span><span class="pun">(</span><span class="pln">chunk</span><span class="pun">,</span><span class="pln"> end </span><span class="pun">=</span><span class="pln"> </span><span class="str">""</span><span class="pun">)</span></pre>

<p>
	سيُولد النموذج كود صحيح مشابه لما يلي:
</p>

<pre class="ipsCode prettyprint lang-css prettyprinted" id="ips_uid_2848_34" style=""><span class="pun">.</span><span class="pln">card </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">width</span><span class="pun">:</span><span class="pln"> </span><span class="lit">300px</span><span class="pun">;</span><span class="pln">  </span><span class="com">/* ;  وضع  */</span><span class="pln">
  </span><span class="kwd">background-color</span><span class="pun">:</span><span class="pln"> white</span><span class="pun">;</span><span class="pln">
  </span><span class="kwd">border-radius</span><span class="pun">:</span><span class="pln"> </span><span class="lit">10px</span><span class="pun">;</span><span class="pln">
  </span><span class="kwd">box-shadow</span><span class="pun">:</span><span class="pln"> </span><span class="lit">0px</span><span class="pln"> </span><span class="lit">4px</span><span class="pln"> </span><span class="lit">8px</span><span class="pln"> rgba</span><span class="pun">(</span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.1</span><span class="pun">);</span><span class="pln">
  </span><span class="kwd">text-align</span><span class="pun">:</span><span class="pln"> center</span><span class="pun">;</span><span class="pln">
  </span><span class="kwd">display</span><span class="pun">:</span><span class="pln"> flex</span><span class="pun">;</span><span class="pln">
  </span><span class="kwd">flex-direction</span><span class="pun">:</span><span class="pln"> column</span><span class="pun">;</span><span class="pln">
  </span><span class="kwd">align-items</span><span class="pun">:</span><span class="pln"> center</span><span class="pun">;</span><span class="pln">
  </span><span class="kwd">color</span><span class="pun">:</span><span class="pln"> black</span><span class="pun">;</span><span class="pln">  </span><span class="com">/* تغيير خاصية اللون بقيمة صحيحة*/</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	نلاحظ أن النموذج قد أضاف الفاصلة المنقوطة <code>;</code> في نهاية كل خاصية، كما صحح اسم اللون حيث استبدل التعليمة <code>color: 100px</code> بالتعليمة التالية <code>color: black</code>.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169295" href="https://academy.hsoub.com/uploads/monthly_2025_03/006___4.png.da1d43f204a5cd2e1ad3621891a81e67.png" rel=""><img alt="006 نتيجة الطلب المرسل4" class="ipsImage ipsImage_thumbnailed" data-fileid="169295" data-unique="5m738mxnv" style="width: 750px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/006___4.thumb.png.05d76c1fa99d45fbb7b93306c632bce2.png"> </a>
</p>

<h2 id="csscodellama-2">
	تحسين أكواد CSS باستخدام Code Llama
</h2>

<p>
	إلى جانب تصحيح الأخطاء، يمكن استخدام Code Llama لتحسين أكواد CSS وجعلها أكثر كفاءة وقابلة للصيانة وذلك من خلال إزالة الأكواد غير الضرورية، ودمج الخصائص المتكررة، واستخدام المتغيرات، وجعل التصميم <a href="https://academy.hsoub.com/design/user-experience/%D8%A7%D9%84%D8%AA%D8%B5%D9%85%D9%8A%D9%85-%D8%A7%D9%84%D9%85%D8%AA%D8%AC%D8%A7%D9%88%D8%A8-responsive-design-r751/" rel="">متجاوب</a> مع مختلف الشاشات
</p>

<p>
	في المثال التالي، سنطلب من النموذج استخدام المتغيرات لتعزيز قابلية إعادة الاستخدام، وتسهيل تعديل القيم عبر الكود:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_2848_36" style=""><span class="com"># Code Llama تهيئة نموذج </span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> langchain_community</span><span class="pun">.</span><span class="pln">llms </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Ollama</span><span class="pln">
codellama </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Ollama</span><span class="pun">(</span><span class="pln">model</span><span class="pun">=</span><span class="str">"codellama:7b-instruct-q2_K"</span><span class="pun">)</span><span class="pln">
</span><span class="com"># CSS  كود </span><span class="pln">
css_code </span><span class="pun">=</span><span class="pln"> </span><span class="str">"""
.card-title {
    font-size: 16px;
    font-weight: bold;
    color: black;
}
.card-content {
    font-size: 16px;
    color: black;
}
"""</span><span class="pln">
</span><span class="com"># إعداد المُوجّه </span><span class="pln">
prompt </span><span class="pun">=</span><span class="pln"> f</span><span class="str">"""
[system] أنت مساعد برمجي متخصص في CSS. 
مهمتك هي تحسين أكواد CSS

[user] هذا هو كود CSS 
الرجاء تحسينه عن طريق
استخدام CSS Variables

{css_code}
"""</span><span class="pln">

</span><span class="com"># تنفيذ الطلب وطباعة الكود الناتج </span><span class="pln">
</span><span class="kwd">for</span><span class="pln"> chunk </span><span class="kwd">in</span><span class="pln"> codellama</span><span class="pun">.</span><span class="pln">stream</span><span class="pun">(</span><span class="pln">prompt</span><span class="pun">):</span><span class="pln">
    </span><span class="kwd">print</span><span class="pun">(</span><span class="pln">chunk</span><span class="pun">,</span><span class="pln"> end </span><span class="pun">=</span><span class="pln"> </span><span class="str">""</span><span class="pun">)</span></pre>

<p>
	سيُولد النموذج كود صحيح مشابه لما يلي:
</p>

<pre class="ipsCode prettyprint lang-css prettyprinted" id="ips_uid_2848_38" style=""><span class="pun">:</span><span class="pln">root </span><span class="pun">{</span><span class="pln">
    </span><span class="pun">--</span><span class="kwd">font-size</span><span class="pun">:</span><span class="pln"> </span><span class="lit">16px</span><span class="pun">;</span><span class="pln">
    </span><span class="pun">--</span><span class="kwd">font-weight</span><span class="pun">:</span><span class="pln"> bold</span><span class="pun">;</span><span class="pln">
    </span><span class="pun">--</span><span class="kwd">color</span><span class="pun">:</span><span class="pln"> black</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="pun">.</span><span class="pln">card-title </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">font-size</span><span class="pun">:</span><span class="pln"> var</span><span class="pun">(--</span><span class="pln">font-size</span><span class="pun">);</span><span class="pln">
    </span><span class="kwd">font-weight</span><span class="pun">:</span><span class="pln"> var</span><span class="pun">(--</span><span class="pln">font-weight</span><span class="pun">);</span><span class="pln">
    </span><span class="kwd">color</span><span class="pun">:</span><span class="pln"> var</span><span class="pun">(--</span><span class="pln">color</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="pun">.</span><span class="pln">card-content </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">font-size</span><span class="pun">:</span><span class="pln"> var</span><span class="pun">(--</span><span class="pln">font-size</span><span class="pun">);</span><span class="pln">
    </span><span class="kwd">color</span><span class="pun">:</span><span class="pln"> var</span><span class="pun">(--</span><span class="pln">color</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span></pre>

<h2 id="cssscssless">
	تحويل كود CSS إلى SCSS أو LESS
</h2>

<p>
	إحدى الميزات المفيدة لنموذج Code Llama قدرته على تحويل الأكواد البرمجية من تنسيق إلى آخر، مما يسهل على المطورين العمل مع <a href="https://academy.hsoub.com/programming/general/%D8%A5%D8%B7%D8%A7%D8%B1-%D8%B9%D9%85%D9%84-framework/" rel="">أطر عمل</a> مختلفة أو تحويل التنسيقات حسب الحاجة. على سبيل المثال، يمكن استخدام Code Llama لتحويل كود CSS إلى <a href="https://academy.hsoub.com/programming/css/sass/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D9%84%D8%BA%D8%A9-sass-r2288/" rel="">SCSS</a> أو LESS للاستفادة من ميزات مثل المتغيرات والخصائص المدمجة والدوال المساعدة.
</p>

<p>
	على سبيل المثال سنطلبن من النموذج تحويل كود CSS إلى SCSS كما يلي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_2848_40" style=""><span class="com"># Code Llama تهيئة نموذج </span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> langchain_community</span><span class="pun">.</span><span class="pln">llms </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Ollama</span><span class="pln">
codellama </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Ollama</span><span class="pun">(</span><span class="pln">model</span><span class="pun">=</span><span class="str">"codellama:7b-instruct-q2_K"</span><span class="pun">)</span><span class="pln">
</span><span class="com"># CSS  كود </span><span class="pln">
css_code </span><span class="pun">=</span><span class="pln"> </span><span class="str">"""
.button {
    background-color: blue;
    color: white;
    padding: 10px 20px;
    border-radius: 5px;
    border: none;
}
.button:hover {
    background-color: darkblue;
}
"""</span><span class="pln">
</span><span class="com"># إعداد المُوجّه </span><span class="pln">
prompt </span><span class="pun">=</span><span class="pln"> f</span><span class="str">"""
[system] أنت مساعد برمجي متخصص في CSS.
[user] أريد تحويل كود CSS إلى SCSS
{css_code}
"""</span><span class="pln">

</span><span class="com"># تنفيذ الطلب وطباعة الكود الناتج </span><span class="pln">
</span><span class="kwd">for</span><span class="pln"> chunk </span><span class="kwd">in</span><span class="pln"> codellama</span><span class="pun">.</span><span class="pln">stream</span><span class="pun">(</span><span class="pln">prompt</span><span class="pun">):</span><span class="pln">
    </span><span class="kwd">print</span><span class="pun">(</span><span class="pln">chunk</span><span class="pun">,</span><span class="pln"> end </span><span class="pun">=</span><span class="pln"> </span><span class="str">""</span><span class="pun">)</span></pre>

<p>
	سنحصل على النتيجة التالية:
</p>

<pre class="ipsCode prettyprint lang-css prettyprinted" id="ips_uid_2848_42" style=""><span class="pun">$</span><span class="kwd">primary-color</span><span class="pun">:</span><span class="pln"> </span><span class="lit">#337ab7</span><span class="pun">;</span><span class="pln">
</span><span class="pun">$</span><span class="kwd">secondary-color</span><span class="pun">:</span><span class="pln"> </span><span class="lit">#23527c</span><span class="pun">;</span><span class="pln">
</span><span class="pun">$</span><span class="kwd">padding</span><span class="pun">:</span><span class="pln"> </span><span class="lit">10px</span><span class="pln"> </span><span class="lit">20px</span><span class="pun">;</span><span class="pln">
</span><span class="pun">$</span><span class="kwd">border-radius</span><span class="pun">:</span><span class="pln"> </span><span class="lit">5px</span><span class="pun">;</span><span class="pln">
</span><span class="pun">$</span><span class="kwd">border</span><span class="pun">:</span><span class="pln"> none</span><span class="pun">;</span><span class="pln">
</span><span class="pun">.</span><span class="pln">button </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">background-color</span><span class="pun">:</span><span class="pln"> </span><span class="pun">$</span><span class="pln">primary-color</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">color</span><span class="pun">:</span><span class="pln"> white</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">padding</span><span class="pun">:</span><span class="pln"> </span><span class="pun">$</span><span class="pln">padding</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">border-radius</span><span class="pun">:</span><span class="pln"> </span><span class="pun">$</span><span class="pln">border-radius</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">border</span><span class="pun">:</span><span class="pln"> </span><span class="pun">$</span><span class="pln">border</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="pun">.</span><span class="kwd">button</span><span class="pun">:</span><span class="pln">hover </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">background-color</span><span class="pun">:</span><span class="pln"> darken</span><span class="pun">($</span><span class="pln">primary-color</span><span class="pun">,</span><span class="pln"> </span><span class="lit">10%</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span></pre>

<h2>
	شرح أكواد CSS باستخدام Code Llama
</h2>

<p>
	من المميزات المفيدة التي يمكن أن يوفرها Code Llama شرح الأكواد البرمجية لمساعدة المطورين أو المتعلمين على فهمها بسهولة. إذ يمكننا إرسال كود برمجي مثل CSS أو HTML إلى النموذج وطلب شرح الغرض من الكود أو توفير توضيح مفصل لكل سطر كما في المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_2848_44" style=""><span class="com"># Code Llama تهيئة نموذج </span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> langchain_community</span><span class="pun">.</span><span class="pln">llms </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Ollama</span><span class="pln">
codellama </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Ollama</span><span class="pun">(</span><span class="pln">model</span><span class="pun">=</span><span class="str">"codellama:7b-instruct-q2_K"</span><span class="pun">)</span><span class="pln">
</span><span class="com"># CSS  كود </span><span class="pln">
css_code </span><span class="pun">=</span><span class="pln"> </span><span class="str">"""

.card-title {
    font-size: 16px;
    font-weight: bold;
    color: black;
}

.card-content {
    font-size: 16px;
    color: black;
}
"""</span><span class="pln">

</span><span class="com"># إعداد المُوجّه </span><span class="pln">
prompt </span><span class="pun">=</span><span class="pln"> f</span><span class="str">"""
[system] أنت مساعد برمجي متخصص في CSS. مهمتك هي شرح كل سطر من الأكواد المقدمة، مع توضيح دور كل خاصية وكيف تؤثر على التصميم.

[user] هذا هو كود CSS الخاص بي، الرجاء شرحه بالكامل:
الرجاء تقديم شرح مفصل للأكواد باللغة العربية
{css_code}
"""</span><span class="pln">
</span><span class="com"># تنفيذ الطلب وطباعة الكود الناتج </span><span class="pln">
</span><span class="kwd">for</span><span class="pln"> chunk </span><span class="kwd">in</span><span class="pln"> codellama</span><span class="pun">.</span><span class="pln">stream</span><span class="pun">(</span><span class="pln">prompt</span><span class="pun">):</span><span class="pln">
    </span><span class="kwd">print</span><span class="pun">(</span><span class="pln">chunk</span><span class="pun">,</span><span class="pln"> end </span><span class="pun">=</span><span class="pln"> </span><span class="str">""</span><span class="pun">)</span></pre>

<p>
	نلاحظ من خلال النتائج السابقة أن جودة الشرح باللغة الإنجليزية أفضل من جودة الشرح باللغة العربية. يعود ذلك إلى أن النموذد دُرّب بشكل أساسي على معلومات باللغة الإنجليزية، مما يجعل قدرته على معالجة اللغة الإنجليزية أفضل مقارنة باللغات الأخرى.
</p>

<p>
	توضح الصورة التالية شرح الكود باللغة الإنجليزية:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169298" href="https://academy.hsoub.com/uploads/monthly_2025_03/009___.png.cff52813407aa44c67132c1f789cf84a.png" rel=""><img alt="009 جودة الشرح إنجليزي" class="ipsImage ipsImage_thumbnailed" data-fileid="169298" data-unique="16q4t91jp" style="width: 750px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/009___.thumb.png.e7da90708cc092a8c7b61b0bc8e61f49.png"> </a>
</p>

<p>
	وتوضح الصورة التالية شرح الكود باللغة العربية:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169299" href="https://academy.hsoub.com/uploads/monthly_2025_03/010___.png.ce7c1ceff0a9e4e27b547fba41328ae5.png" rel=""><img alt="010 جودة الشرح عربي" class="ipsImage ipsImage_thumbnailed" data-fileid="169299" data-unique="1n8ue4kvf" style="width: 750px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/010___.thumb.png.f09a6d564f91e630e856ad385e1c657a.png"> </a>
</p>

<h2 id="csscodellama-4">
	بناء أداة تفاعلية لتوليد وتحسين أكواد CSS
</h2>

<p>
	سنعمل في هذه الفقرة على تطوير أداة تفاعلية تعتمد على نموذج Code Llama لمساعدة المطورين في توليد وتصحيح وتحسين وشرح أكواد CSS بفعالية وسلاسة. سنستخدم LangChain للتفاعل مع النموذج، كما سنستخدم <a href="https://www.gradio.app/" rel="external nofollow">Gradio</a> لإنشاء واجهة مستخدم سهلة الاستخدام. تتضمن الأداة أربع وظائف رئيسية وهي: 
</p>

<ul>
	<li>
		توليد كود CSS بناءً على وصف نصي للمستخدم
	</li>
	<li>
		تصحيح الأكواد التي تحتوي على أخطاء
	</li>
	<li>
		تحسين الأكواد لجعلها أكثر كفاءة
	</li>
	<li>
		شرح الأكواد لتعزيز فهمها ومعرفة مكوناتها ووظائفها
	</li>
</ul>

<p>
	سنستدعي نموذج Code Llama عبر Ollama و LangChain، ليولّد لنا النتائج بناءً على مدخلات المستخدم. ستُنفَّذ كل عملية من خلال دوال مخصصة داخل الكود، مع واجهة مستخدم تفاعلية أُنشئت باستخدام Gradio لتوفير تفاعل سريع وسهل.
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_2848_46" style=""><span class="com"># تثبيت المكتبات الأساسية</span><span class="pln">
</span><span class="com">#!pip install langchain </span><span class="pln">
</span><span class="com">#!pip install langchain_community </span><span class="pln">
</span><span class="com">#!pip install ollama</span><span class="pln">
</span><span class="com">#!pip install gradio</span><span class="pln">

</span><span class="com"># استدعاء المكتبات اللازمة</span><span class="pln">
</span><span class="kwd">import</span><span class="pln"> gradio </span><span class="kwd">as</span><span class="pln"> gr
</span><span class="kwd">from</span><span class="pln"> langchain_community</span><span class="pun">.</span><span class="pln">llms </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Ollama</span><span class="pln">

</span><span class="com"># Code Llama تهيئة نموذج </span><span class="pln">
codellama </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Ollama</span><span class="pun">(</span><span class="pln">model</span><span class="pun">=</span><span class="str">"codellama:7b-instruct-q2_K"</span><span class="pun">)</span><span class="pln">

</span><span class="com"># دالة توليد الأكواد</span><span class="pln">
</span><span class="kwd">def</span><span class="pln"> generate_code</span><span class="pun">(</span><span class="pln">prompt</span><span class="pun">):</span><span class="pln">
    system_prompt </span><span class="pun">=</span><span class="pln"> </span><span class="str">"[system] أنت مساعد برمجي متخصص في CSS. مهمتك هي توليد كود نظيف ومفهوم بناءً على وصف المستخدم."</span><span class="pln">
    full_prompt </span><span class="pun">=</span><span class="pln"> f</span><span class="str">"{system_prompt}\n[user] {prompt}"</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> codellama</span><span class="pun">.</span><span class="pln">invoke</span><span class="pun">(</span><span class="pln">full_prompt</span><span class="pun">)</span><span class="pln">

</span><span class="com"># دالة تصحيح الأكواد</span><span class="pln">
</span><span class="kwd">def</span><span class="pln"> fix_css</span><span class="pun">(</span><span class="pln">css_code</span><span class="pun">):</span><span class="pln">
    system_prompt </span><span class="pun">=</span><span class="pln"> </span><span class="str">"[system] أنت مساعد متخصص في تصحيح أكواد CSS. قم بإصلاح الأخطاء في الكود التالي."</span><span class="pln">
    full_prompt </span><span class="pun">=</span><span class="pln"> f</span><span class="str">"{system_prompt}\n[user] كود CSS به أخطاء:\n{css_code}"</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> codellama</span><span class="pun">.</span><span class="pln">invoke</span><span class="pun">(</span><span class="pln">full_prompt</span><span class="pun">)</span><span class="pln">

</span><span class="com"># دالة تحسين الأكواد</span><span class="pln">
</span><span class="kwd">def</span><span class="pln"> improve_css</span><span class="pun">(</span><span class="pln">css_code</span><span class="pun">):</span><span class="pln">
    system_prompt </span><span class="pun">=</span><span class="pln"> </span><span class="str">"[system] أنت مساعد خبير في تحسين أكواد CSS. قم بتحسين الكود ليصبح أكثر كفاءة."</span><span class="pln">
    full_prompt </span><span class="pun">=</span><span class="pln"> f</span><span class="str">"{system_prompt}\n[user] كود CSS يحتاج تحسينًا:\n{css_code}"</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> codellama</span><span class="pun">.</span><span class="pln">invoke</span><span class="pun">(</span><span class="pln">full_prompt</span><span class="pun">)</span><span class="pln">

</span><span class="com"># دالة شرح الأكواد</span><span class="pln">
</span><span class="kwd">def</span><span class="pln"> explain_css</span><span class="pun">(</span><span class="pln">css_code</span><span class="pun">):</span><span class="pln">
    system_prompt </span><span class="pun">=</span><span class="pln"> </span><span class="str">"[system] أنت مساعد متخصص في شرح أكواد CSS بطريقة مفهومة."</span><span class="pln">
    full_prompt </span><span class="pun">=</span><span class="pln"> f</span><span class="str">"{system_prompt}\n[user] أريد شرحًا لهذا الكود:\n{css_code}"</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> codellama</span><span class="pun">.</span><span class="pln">invoke</span><span class="pun">(</span><span class="pln">full_prompt</span><span class="pun">)</span><span class="pln">

</span><span class="com"># إنشاء واجهة المستخدم</span><span class="pln">
</span><span class="kwd">with</span><span class="pln"> gr</span><span class="pun">.</span><span class="typ">Blocks</span><span class="pun">()</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> demo</span><span class="pun">:</span><span class="pln">
    gr</span><span class="pun">.</span><span class="typ">Markdown</span><span class="pun">(</span><span class="str">"# <span class="ipsEmoji">🖥️</span> مساعد الذكاء الاصطناعي لـ CSS<span class="ipsEmoji">🚀</span>"</span><span class="pun">)</span><span class="pln">

    </span><span class="kwd">with</span><span class="pln"> gr</span><span class="pun">.</span><span class="typ">Tab</span><span class="pun">(</span><span class="str">"<span class="ipsEmoji">📝</span> CSS توليد كود "</span><span class="pun">):</span><span class="pln">
        prompt_input </span><span class="pun">=</span><span class="pln"> gr</span><span class="pun">.</span><span class="typ">Textbox</span><span class="pun">(</span><span class="pln">label</span><span class="pun">=</span><span class="str">"أدخل وصفًا لما تريد توليده"</span><span class="pun">,</span><span class="pln"> placeholder</span><span class="pun">=</span><span class="str">"مثال: زر أزرق بتأثير عند التحويم"</span><span class="pun">)</span><span class="pln">
        generate_btn </span><span class="pun">=</span><span class="pln"> gr</span><span class="pun">.</span><span class="typ">Button</span><span class="pun">(</span><span class="str">"<span class="ipsEmoji">🔹</span> توليد الكود"</span><span class="pun">)</span><span class="pln">
        generated_code_output </span><span class="pun">=</span><span class="pln"> gr</span><span class="pun">.</span><span class="typ">Code</span><span class="pun">(</span><span class="pln">label</span><span class="pun">=</span><span class="str">"الكود الناتج"</span><span class="pun">)</span><span class="pln">
        generate_btn</span><span class="pun">.</span><span class="pln">click</span><span class="pun">(</span><span class="pln">generate_code</span><span class="pun">,</span><span class="pln"> inputs</span><span class="pun">=</span><span class="pln">prompt_input</span><span class="pun">,</span><span class="pln"> outputs</span><span class="pun">=</span><span class="pln">generated_code_output</span><span class="pun">)</span><span class="pln">

    </span><span class="kwd">with</span><span class="pln"> gr</span><span class="pun">.</span><span class="typ">Tab</span><span class="pun">(</span><span class="str">"<span class="ipsEmoji">✅</span> CSS تصحيح كود "</span><span class="pun">):</span><span class="pln">
        css_input </span><span class="pun">=</span><span class="pln"> gr</span><span class="pun">.</span><span class="typ">Code</span><span class="pun">(</span><span class="pln">label</span><span class="pun">=</span><span class="str">"أدخل كود يحتوي على أخطاء"</span><span class="pun">,</span><span class="pln"> language</span><span class="pun">=</span><span class="str">"css"</span><span class="pun">)</span><span class="pln">
        fix_btn </span><span class="pun">=</span><span class="pln"> gr</span><span class="pun">.</span><span class="typ">Button</span><span class="pun">(</span><span class="str">"<span class="ipsEmoji">🔹</span> تصحيح الكود"</span><span class="pun">)</span><span class="pln">
        fixed_css_output </span><span class="pun">=</span><span class="pln"> gr</span><span class="pun">.</span><span class="typ">Code</span><span class="pun">(</span><span class="pln">label</span><span class="pun">=</span><span class="str">"الكود المصحح"</span><span class="pun">)</span><span class="pln">
        fix_btn</span><span class="pun">.</span><span class="pln">click</span><span class="pun">(</span><span class="pln">fix_css</span><span class="pun">,</span><span class="pln"> inputs</span><span class="pun">=</span><span class="pln">css_input</span><span class="pun">,</span><span class="pln"> outputs</span><span class="pun">=</span><span class="pln">fixed_css_output</span><span class="pun">)</span><span class="pln">

    </span><span class="kwd">with</span><span class="pln"> gr</span><span class="pun">.</span><span class="typ">Tab</span><span class="pun">(</span><span class="str">"<span class="ipsEmoji">🚀</span> CSS تحسين كود"</span><span class="pun">):</span><span class="pln">
        css_input_improve </span><span class="pun">=</span><span class="pln"> gr</span><span class="pun">.</span><span class="typ">Code</span><span class="pun">(</span><span class="pln">label</span><span class="pun">=</span><span class="str">"أدخل كود لتحسينه"</span><span class="pun">,</span><span class="pln"> language</span><span class="pun">=</span><span class="str">"css"</span><span class="pun">)</span><span class="pln">
        improve_btn </span><span class="pun">=</span><span class="pln"> gr</span><span class="pun">.</span><span class="typ">Button</span><span class="pun">(</span><span class="str">"<span class="ipsEmoji">🔹</span> تحسين الكود"</span><span class="pun">)</span><span class="pln">
        improved_css_output </span><span class="pun">=</span><span class="pln"> gr</span><span class="pun">.</span><span class="typ">Code</span><span class="pun">(</span><span class="pln">label</span><span class="pun">=</span><span class="str">"الكود المحسن"</span><span class="pun">)</span><span class="pln">
        improve_btn</span><span class="pun">.</span><span class="pln">click</span><span class="pun">(</span><span class="pln">improve_css</span><span class="pun">,</span><span class="pln"> inputs</span><span class="pun">=</span><span class="pln">css_input_improve</span><span class="pun">,</span><span class="pln"> outputs</span><span class="pun">=</span><span class="pln">improved_css_output</span><span class="pun">)</span><span class="pln">

    </span><span class="kwd">with</span><span class="pln"> gr</span><span class="pun">.</span><span class="typ">Tab</span><span class="pun">(</span><span class="str">"<span class="ipsEmoji">📖</span>  CSS شرح كود "</span><span class="pun">):</span><span class="pln">
        css_input_explain </span><span class="pun">=</span><span class="pln"> gr</span><span class="pun">.</span><span class="typ">Code</span><span class="pun">(</span><span class="pln">label</span><span class="pun">=</span><span class="str">"أدخل كود لشرحه"</span><span class="pun">,</span><span class="pln"> language</span><span class="pun">=</span><span class="str">"css"</span><span class="pun">)</span><span class="pln">
        explain_btn </span><span class="pun">=</span><span class="pln"> gr</span><span class="pun">.</span><span class="typ">Button</span><span class="pun">(</span><span class="str">"<span class="ipsEmoji">🔹</span> شرح الكود"</span><span class="pun">)</span><span class="pln">
        explained_output </span><span class="pun">=</span><span class="pln"> gr</span><span class="pun">.</span><span class="typ">Textbox</span><span class="pun">(</span><span class="pln">label</span><span class="pun">=</span><span class="str">"الشرح الناتج"</span><span class="pun">)</span><span class="pln">
        explain_btn</span><span class="pun">.</span><span class="pln">click</span><span class="pun">(</span><span class="pln">explain_css</span><span class="pun">,</span><span class="pln"> inputs</span><span class="pun">=</span><span class="pln">css_input_explain</span><span class="pun">,</span><span class="pln"> outputs</span><span class="pun">=</span><span class="pln">explained_output</span><span class="pun">)</span><span class="pln">

</span><span class="com"># تشغيل التطبيق</span><span class="pln">
demo</span><span class="pun">.</span><span class="pln">launch</span><span class="pun">()</span></pre>

<p>
	فيما يلي صورة واجهة Gradio التفاعلية:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="169300" href="https://academy.hsoub.com/uploads/monthly_2025_03/011__.png.8736d351c100ab833b868343c18cfdd0.png" rel=""><img alt="011 أداة تفاعلية" class="ipsImage ipsImage_thumbnailed" data-fileid="169300" data-unique="qxzs31igk" src="https://academy.hsoub.com/uploads/monthly_2025_03/011__.png.8736d351c100ab833b868343c18cfdd0.png"> </a>
</p>

<h2 id="codellama-2">
	نصائح لتحسين أداء نتائج نموذج Code Llama
</h2>

<p>
	فيما يلي عدة نصائح للحصول على أفضل النتائج من استخدام Code Llama لكتابة أكواد CSS:
</p>

<h3 id="-1">
	كتابة موجه دقيق وواضح
</h3>

<p>
	من أهم الخطوات لتحسين نتائج النماذج اللغوية تقديم موجّه prompt دقيق. كلما كانت التعليمات واضحة، كانت الاستجابة أكثر دقة وفعالية. لذا يجب أن نكون محددين في طلبنا مثل: أريد كود CSS لزر أزرق يتحول إلى اللون الأحمر عند التحويم أو تمرير مؤشر الفأرة فوقه، بدلاً من قول: أريد كود CSS لزر. فهذا التحديد يساعد النموذج على فهم المتطلبات بشكل أفضل وتوليد نتائج أكثر تطابقًا مع ما نحتاجه.
</p>

<h3 id="-2">
	الانتباه للأخطاء التي ينتجها النموذج وتكرار المحاولة
</h3>

<p>
	على الرغم من قوة Code Llama، قد تظهر بعض الأخطاء في الأكواد المُولدة، مثل التنسيق غير الصحيح أو الأكواد غير المحسنة. من الضروري ملاحظة هذه الأخطاء وتصحيحها يدويًا أو باستخدام النموذج نفسه لإعادة التصحيح. كما يمكن تكرار المحاولة باستخدام موجّه prompt مختلف أو تحسين التعليمات المقدمة للنموذج للحصول على نتائج أكثر دقة وجودة.
</p>

<h3 id="-3">
	استخدام نموذج أكبر
</h3>

<p>
	في حال لم تكن النتائج مرضية بالنموذج المستخدم مثل 7b-instruct-q2_K، يمكن أن نجرب نموذجًا أكبر إذا كان متاحًا، حيث أن النماذج الأكبر تتمتع بقدرة أكبر على معالجة طلبات أكثر تعقيدًا. كما أنها تستطيع تقديم أكواد دقيقة وأكثر تنوعًا، مما يعزز من فعالية الاستجابة وجودتها.
</p>

<h3 id="-4">
	إعادة ضبط وتدريب النموذج
</h3>

<p>
	قد نحتاج إلى إعادة تدريب النموذج أو ضبطه fine-tuning إذا كان لدينا مجموعة بيانات خاصة أو سيناريوهات دقيقة. فعلى الرغم من أن Code Llama نموذج قوي وفعال، إلا أن بعض الحالات قد تتطلب تخصيص النموذج لاحتياجات محددة.
</p>

<h3 id="-5">
	استخدام اللغة الإنجليزية
</h3>

<p>
	للحصول على أفضل النتائج، يفضل استخدام اللغة الإنجليزية عند كتابة الموجهات prompts للنموذج. ففي العديد من النماذج، قد تؤدي الكتابة باللغة الإنجليزية إلى فهم أفضل وتوفير استجابات أكثر دقة، بينما يمكن أن تواجه النماذج صعوبة في التعامل مع بعض اللغات الأخرى.
</p>

<h3 id="-6">
	استخدام جهاز قوي للحصول على أداء أسرع
</h3>

<p>
	تعتمد سرعة استجابة النموذج على قوة الجهاز المستخدم. لذا، يفضل تشغيل Code Llama على أجهزة ذات قدرات معالجة عالية، كما يمكن استخدام <a href="https://academy.hsoub.com/programming/advanced/%D8%A7%D9%84%D9%81%D8%B1%D9%82-%D8%A8%D9%8A%D9%86-%D9%88%D8%AD%D8%AF%D8%A9-%D8%A7%D9%84%D9%85%D8%B9%D8%A7%D9%84%D8%AC%D8%A9-%D8%A7%D9%84%D9%85%D8%B1%D9%83%D8%B2%D9%8A%D8%A9-cpu-%D9%88%D9%88%D8%AD%D8%AF%D8%A9-%D8%A7%D9%84%D9%85%D8%B9%D8%A7%D9%84%D8%AC%D8%A9-%D8%A7%D9%84%D8%B1%D8%B3%D9%88%D9%85%D9%8A%D8%A9-gpu-r2527/" rel="">وحدة معالجة رسومية GPU</a> قوية للحصول على أداء أسرع وكفاءة أعلى.
</p>

<h2 id="-7">
	الخاتمة
</h2>

<p>
	استعرضنا في هذا المقال كيفية استخدام Code Llama لتوليد و تصحيح وتحسين وشرح أكواد CSS. وتعلمنا أهمية استخدام Ollama و LangChain لتشغيل النموذج محليًا، بالإضافة إلى شرح كيفية بناء واجهة تفاعلية باستخدام Gradio. نرجو أن نكون قد وضحنا لك كافة إمكانيات النموذج ودوره في تسريع عملية البرمجة وتحسين أكواد CSS وتصحيح أخطائها. ومن المفيد اتباع النصائح التي وفرناها في الختام للحصول على أفضل أداء من نموذج Code Llama وتحقيق نتائج مرضية.
</p>

<h2 id="-8">
	اقرأ أيضًا
</h2>

<ul>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A8%D9%86%D8%A7%D8%A1-%D8%B1%D9%88%D8%A8%D9%88%D8%AA-%D8%AF%D8%B1%D8%AF%D8%B4%D8%A9-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-%D9%88-openai-api-r2483/" rel="">بناء روبوت دردشة باستخدام بايثون و OpenAI <abbr title="Application Programming Interface | واجهة برمجية"><abbr title="Application Programming Interface | واجهة برمجية">API</abbr></abbr></a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A3%D9%81%D8%B6%D9%84-%D9%85%D9%85%D8%A7%D8%B1%D8%B3%D8%A7%D8%AA-%D9%87%D9%86%D8%AF%D8%B3%D8%A9-%D8%A7%D9%84%D9%85%D9%8F%D9%88%D8%AC%D9%91%D9%90%D9%87%D8%A7%D8%AA/" rel="">أفضل ممارسات هندسة المُوجِّهات Prompt Engineering: نصائح وحيل وأدوات</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%B7%D8%B1%D9%8A%D9%82%D8%A9-%D8%A7%D9%84%D8%B5%D9%82%D9%84-fine-tune-%D9%84%D9%86%D9%85%D9%88%D8%B0%D8%AC-%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-%D9%85%D9%8F%D8%AF%D8%B1%D9%91%D9%8E%D8%A8-%D9%85%D9%8F%D8%B3%D8%A8%D9%82%D9%8B%D8%A7-r2367/" rel="">طريقة الصقل Fine-Tune لنموذج ذكاء اصطناعي مُدرَّب مُسبقًا</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A3%D9%81%D9%83%D8%A7%D8%B1-%D9%85%D8%B4%D8%A7%D8%B1%D9%8A%D8%B9-%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-%D8%AA%D9%86%D8%A7%D8%B3%D8%A8-%D8%A7%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86-r2535/" rel="">أفكار مشاريع ذكاء اصطناعي تناسب المبتدئين</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">2531</guid><pubDate>Tue, 11 Mar 2025 12:00:00 +0000</pubDate></item><item><title>&#x62F;&#x645;&#x62C; &#x645;&#x633;&#x627;&#x639;&#x62F; &#x627;&#x644;&#x630;&#x643;&#x627;&#x621; &#x627;&#x644;&#x627;&#x635;&#x637;&#x646;&#x627;&#x639;&#x64A; GitHub Copilot &#x645;&#x639; &#x645;&#x62D;&#x631;&#x631; &#x627;&#x644;&#x623;&#x643;&#x648;&#x627;&#x62F; VS Code</title><link>https://academy.hsoub.com/programming/artificial-intelligence/%D8%AF%D9%85%D8%AC-%D9%85%D8%B3%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-github-copilot-%D9%85%D8%B9-%D9%85%D8%AD%D8%B1%D8%B1-%D8%A7%D9%84%D8%A3%D9%83%D9%88%D8%A7%D8%AF-vs-code-r2521/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2025_03/GithubCopilot.png.92dd9ba7cacf9395fe7a723cfae68a44.png" /></p>
<p>
	أصبحت أدوات الذكاء الاصطناعي من الأساسيات التي لا غنى عنها للمبرمجين اليوم، حيث تساعد هذه الأدوات في زيادة الإنتاجية، والتخلص من المهام التكرارية، والتفرغ لحل المشكلات البرمجية الأكثر أهمية، وقد اخترنا لكم في هذه المقالة واحدة من أدوات الذكاء الاصطناعي القوية والمفيدة لأي مبرمج وهي المساعد الذكي GitHub Copilot الذي أصبح يوفر خطة استخدام مجانية من خلال دمجه مع  <a href="https://academy.hsoub.com/programming/workflow/%D9%85%D8%AD%D8%B1%D8%B1%D8%A7%D8%AA-%D8%A7%D9%84%D8%B4%D9%8A%D9%81%D8%B1%D8%A7%D8%AA-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D8%A9/" rel="">محرر الأكواد Visual Studio Code</a>، حيث سنوضح أهم الميزات التي يوفرها هذا المساعد الذكي، ونوضح حالات استخدامه المختلفة لكتابة أكواد محسنة وموثقة جيدًا واكتشاف الأخطاء وحلها بكفاءة من داخل المحرر مباشرة دون الحاجة لنسخ فقرات الكود ولصقها في <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D9%85%D8%B4%D8%A7%D8%B1%D9%83%D8%A9-%D9%86%D9%85%D9%88%D8%B0%D8%AC-%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-%D8%B9%D9%84%D9%89-%D9%85%D9%86%D8%B5%D8%A9-hugging-face-r2378/" rel="">نماذج الذكاء الاصطناعي</a> الخارجية.
</p>

<h2 id="">
	المتطلبات
</h2>

<p>
	نحتاج قبل بدء استكشاف المساعد البرمجي GitHub Copilot إلى التأكد من تجهيز بيئة عملنا بإعداد الأمور التالية:
</p>

<ul>
	<li>
		<a href="https://code.visualstudio.com/download" rel="external nofollow">تنزيل محرر الأكواد فيجوال ستوديو كود VS Code</a>
	</li>
	<li>
		إنشاء حساب على منصة <a href="https://github.com/" rel="external nofollow">GitHub</a>
	</li>
	<li>
		تنزيل إضافة <a href="https://marketplace.visualstudio.com/items?itemName=GitHub.copilot" rel="external nofollow">GitHub Copilot</a> و <a href="https://marketplace.visualstudio.com/items?itemName=GitHub.copilot-chat" rel="external nofollow">GitHub Copilot Chat</a> لمحرر الأكواد VS Code
	</li>
</ul>

<p>
	<strong>ملاحظة</strong>: قد تكون الإضافات المطلوبة محمّلة بالفعل في محرر الأكواد، وفي هذا الحالة سنتخطى خطوة تنزيلها.
</p>

<h2 id="githubcopilotvscode">
	خطوات ربط GitHub Copilot بمحرر أكواد VS code
</h2>

<p>
	يمكننا من خلال محرر الأكواد VS code الاستفادة من تجربة وصول محدودة لاستخدام GitHub Copilot حيث تُمنح لنا خمسون محادثة لاستخدامها في الاستفسار من المساعد البرمجي و 2000 مرة لإكمال الكود البرمجي تجدد شهريًا، وسنتطرق في نهاية المقال لكيفية الحصول على الخطة المميزة pro بالمجان للطلبة والمعلمين والمساهمين في المشاريع مفتوحة المصدر بما يتوافق مع بعض الشروط التي تضعها منصة GitHub.
</p>

<p>
	بمجرد أن نفتح محرر أكواد VS code سنجد أيقونة بها شعار Github Copilot، نضغط عليها أو نفتح القائمة المنسدلة حيث سنجد خيار باسم<br>
	Use AI features with Copilot for Free وباختياره تفتح نافذة جانبية ترحيبية وتطالبنا بالموافقة على الشروط والأحكام من خلال الضغط على زر Use Copilot for Free، وننصح بالاطلاع عليها قبل الموافقة.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="168921" href="https://academy.hsoub.com/uploads/monthly_2025_03/000_github-copilot-setup.png.7024f59e97f08514d1eba1017a9378f5.png" rel=""><img alt="000 github copilot setup" class="ipsImage ipsImage_thumbnailed" data-fileid="168921" data-unique="fv7mwibkh" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/000_github-copilot-setup.thumb.png.c98b1457144a027b1babaaab38aba5cd.png"> </a>
</p>

<p>
	كي نتمكن من فتح نافذة الحوار مع المساعد البرمجي يمكننا استخدام الأيقونة أو اختصار الوصول السريع من لوحة المفاتيح <code>Ctrl+ALT+I</code>. وفي حال لم نتمكن من العثور على هذه الأيقونة أو وجدناها غير مفعلة فعلينا تسجيل الدخول إلى حساب Github الخاص بنا وربطه بمحرر الأكواد، من خلال أيقونة الحسابات Accounts الموجودة أسفل يسار الصفحة في محرر الأكواد فوق أيقونة الإعدادات، فمن خلالها نصادق على وصول محرر الأكواد VS code لحسابنا على Github والذي تحتاجه <a href="https://marketplace.visualstudio.com/items?itemName=GitHub.copilot" rel="external nofollow">إضافة Github Copilot</a> للعمل.
</p>

<h2 id="-1">
	اختيار نموذج الذكاء الاصطناعي
</h2>

<p>
	يوفر Github Copilot لمستخدميه في الخطة المجانية إمكانية اختيار نموذج الذكاء الاصطناعي المشغِّل لمساعد الذكاء الاصطناعي، حيث يتاح حاليًا نموذجان فقط هما GPT 4o و Claude 3.5 sonnet.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="168922" href="https://academy.hsoub.com/uploads/monthly_2025_03/001_github_copilot_model_choose.png.5ca0b2772b09e01e9bc843ee42e2fe81.png" rel=""><img alt="001 github copilot model choose" class="ipsImage ipsImage_thumbnailed" data-fileid="168922" data-unique="iavqts5x3" style="width: 500px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/001_github_copilot_model_choose.thumb.png.87619cedbeae9cb8b495b91cee3d6b3c.png"> </a>
</p>

<p>
	بينما تتيح الخطط المميزة المدفوعة الوصول إلى نماذج أقوى مثل OpenAI o1 و OpenAI o1-mini.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="168923" href="https://academy.hsoub.com/uploads/monthly_2025_03/002_github_copilot_model_choose_pro.png.555fab94c0e5546bc7ead3e84a677740.png" rel=""><img alt="002 github copilot model choose pro" class="ipsImage ipsImage_thumbnailed" data-fileid="168923" data-unique="c5jc6e77b" style="width: 500px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/002_github_copilot_model_choose_pro.thumb.png.9addbb468939af40ca3d33e6dff31c79.png"> </a>
</p>

<p>
	<strong>ملاحظة</strong>: قد تتغير هذه النماذج بمرور الوقت وتطور إلى نماذج أخرى، من الأفضل حاليًا استخدام GPT4o أو Claude Sonnet 3.5 في تعديل ملفات الكود، بينما يفضل استخدام o1 لفهم وشرح الكود، وقد يختلف الأمر حسب حالة الاستخدام التي نتعامل معها لذا يمكن التبديل بين النماذج المتاحة  ومقارنة نتائجها لنقرر الأنسب حسب كل حالة.
</p>

<h2>
	حالات استخدام Github Copilot ضمن محرر الأكواد 
</h2>

<p>
	بعد ربط أداة الذكاء الاصطناعي بمحرر الأكواد، يمكننا الاستفادة من هذه الأداة في العديد من حالات الاستخدام العملية التي تسهل عملنا البرمجي وتزيد إنتاجيتنا. لنسعرض في الفقرات التالية أهم الحالات التي يمكننا الاستفادة منها من دمج مساعد الذكاء الاصطناعي GitHub Copilot مع محرر الأكواد.
</p>

<h3 id="-2">
	اقتراح إكمال الكود البرمجي
</h3>

<p>
	لننشئ مجلدًا جديدًا و نفتحه في المحرر VS code، ثم ننشئ ملفًا باسم <code>binary_search.py</code> لنكتب<a href="https://wiki.hsoub.com/Algorithms/binary_search" rel="external"> خوارزمية البحث الثنائي</a> وهي خوازرمية بحث مشهورة بكفاءتها، لنجرب أولًا كتابة تعريف دالة تستقبل مجموعة من الأرقام في مصفوفة Array، ونرى كيف سيقترح علينا المساعد البرمجي الكود المناسب للبحث ضمنها.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="168924" href="https://academy.hsoub.com/uploads/monthly_2025_03/003_github_copilot_binary_search_1.png.41b10c8fe3d91ae68debb1a86b64851b.png" rel=""><img alt="003 github copilot binary search 1" class="ipsImage ipsImage_thumbnailed" data-fileid="168924" data-unique="6zeb218k8" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/003_github_copilot_binary_search_1.thumb.png.ac41e7a769f3c383fb671cbd07143370.png"> </a>
</p>

<p>
	بمجرد أن نكتب تعريف الدالة البرمجية سنلاحظ ظهور كود بلون رمادي خافت، هذا الكود هو اقتراح المساعد البرمجي ويمكننا الوقوف عليه بالمؤشر ورؤية شريط به بعض عناصر التحكم، فمثلًا قد نرى 1/2 والتي تعني أن هذا هو أحد اقتراحين، ويمكن أن نتجاهل الاقتراحات بمتابعة الكتابة أو يمكننا قبول الاقتراحات بالضغط على زر Accept أو على مفتاح <code>Tab</code> على لوحة المفاتيح، وكذلك يمكننا التحكم بمقدار ما نريد قبوله من الاقتراح باستمرار الضغط على زر <code>Ctrl</code> مع أحد أزرار الأسهم.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="168925" href="https://academy.hsoub.com/uploads/monthly_2025_03/004_github_copilot_options_small.gif.1c48b76822d3616d7bc01b6e0c3e303e.gif" rel=""><img alt="004 github copilot options small" class="ipsImage ipsImage_thumbnailed" data-fileid="168925" data-unique="0ik4c5915" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/004_github_copilot_options_small.thumb.gif.47f72edf8c48dd61c566b1bf793e3dc9.gif"> </a>
</p>

<p>
	يمكننا أيضًا كتابة تعليق يصف ما نريد وبمجرد النزول سطرًا سيقترح المساعد البرمجي كود ينفذ التعليق.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="gif" data-fileid="168926" href="https://academy.hsoub.com/uploads/monthly_2025_03/005_github_copilot_options_2.gif.919eedaa624497aa59c13d87cfb06ab6.gif" rel=""><img alt="005 github copilot options 2" class="ipsImage ipsImage_thumbnailed" data-fileid="168926" data-unique="unhdot8vj" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/005_github_copilot_options_2.thumb.gif.0611bf19e41327a1959331cb627886f9.gif"> </a>
</p>

<h3 id="-3">
	تعديل عدة ملفات بأوامر مكتوبة وصوتية
</h3>

<p>
	يتميز مساعد Github Copilot عن باقي أدوات الذكاء الاصطناعي الخارجية في وصوله للسياق البرمجي وقاعدة الأكواد التي نعمل عليها، وقدرته على التعديل على الملفات في الوقت الفعلي، ولا يقتصر الأمر على تعديل ملف واحد فيمكننا تعديل عدة ملفات بذات الوقت.
</p>

<p>
	لنجرب ميزة تعديل عدة ملفات معًا من خلال تطبيق خوارزميات ترتيب مشهورة سنكتبها في نفس ملف binary_sort كما في الصورة التالية:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="168927" href="https://academy.hsoub.com/uploads/monthly_2025_03/006_github_copilot_example_1.png.466485187d13915d68e51368ec7017a8.png" rel=""><img alt="006 github copilot example 1" class="ipsImage ipsImage_thumbnailed" data-fileid="168927" data-unique="01uk108kf" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/006_github_copilot_example_1.thumb.png.2ae3fbaea5a94f9e8082d3fdbc0996c7.png"> </a>
</p>

<p>
	يمكننا بالطبع توليد هذه الدوال بمساعدة Github Copilot، كما نلاحظ هنا فإن اسم الملف لا يعبر عن الخوارزمية المطبقة -وهذا خطأ مقصود- لنرى كيف سيتعامل معه المساعد في خطوة لاحقة.
</p>

<p>
	لنفتح الآن نافذة الحوار ونكتب <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A3%D9%81%D8%B6%D9%84-%D9%85%D9%85%D8%A7%D8%B1%D8%B3%D8%A7%D8%AA-%D9%87%D9%86%D8%AF%D8%B3%D8%A9-%D8%A7%D9%84%D9%85%D9%8F%D9%88%D8%AC%D9%91%D9%90%D9%87%D8%A7%D8%AA/" rel="">الموجّه prompt</a> المناسب لطلب تعديل الملفات ويمكن استخدام أيقونة الميكروفون لتوجيه أمر صوتي.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="168928" href="https://academy.hsoub.com/uploads/monthly_2025_03/007_github_copilot_example_2.png.af48765b21e984eabb9c61757023ee7e.png" rel=""><img alt="007 github copilot example 2" class="ipsImage ipsImage_thumbnailed" data-fileid="168928" data-unique="ms5q5jynq" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/007_github_copilot_example_2.thumb.png.3784ca7b2726153a0dee646b3eb6aea1.png"> </a>
</p>

<p>
	سيقترح Github Copilot التعديلات المناسبة وسيظهر لنا الاختلافات بين الملفات القديمة والتي أنشئت حديثًا، سنرى الأكواد التي حذفت مظللة بلون أحمر والتي أضيفت بلون أخضر، ولكن لن تطبق أو تضاف هذه التعديلات حتى نقبلها بالضغط على زر Accept.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="168929" href="https://academy.hsoub.com/uploads/monthly_2025_03/008_github_copilot_example_3.png.58ca7b1f3186b76a683007784c52b3c4.png" rel=""><img alt="008 github copilot example 3" class="ipsImage ipsImage_thumbnailed" data-fileid="168929" data-unique="8wfdm57i1" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/008_github_copilot_example_3.thumb.png.51abe0c79b162d45eb7ef41c6739fc83.png"> </a>
</p>

<h3 id="githubcopilot-1">
	تحسين الكود البرمجي
</h3>

<p>
	يمكننا مناقشة المساعد البرمجي Github Copilot في آلية كتابة كودنا البرمجي وكيفية تحسينه أو حل مشكلاته من خلال نافذة الحوار والتي تعد واحدة طرق متعددة للتواصل مع المساعد البرمجي، حيث يمكننا التواصل معه أيضًا من خلال محرر الأكواد بشكل مباشر وتفاعلي، أو من خلال سطر الأوامر أو الطرفية terminal المدمجة بمحرر أكواد VS code، أو من خلال واجهة VS code المحسنة لنجعل تجربة الاستخدام أكثر سلاسة.
</p>

<p>
	بملاحظة المثال السابق في تعديل الملفات سنجد عدة مشاكل واضحة، تحتاج لتصحيح بشري، ولهذا من المهم جدًا أن <strong>لاتسلم بصحة الكود المولد من أدوات الذكاء الاصطناعي دون مراجعته وتعديله</strong>، فأداة Github Copilot شأنها شأن أي أداة ذكاء اصطناعي آخرى فهي مفيدة لزيادة إنتاجيتك إن كنت بالفعل على دراية بالكود والمنطق المراد تنفيذه.
</p>

<p>
	تتمثل الأخطاء التي قام بها المساعد الذكي في حذف الدوال الأخرى من الملف الأول فقط، وبالتالي سنحتاج تصحيح هذا الخطأ بالإضافة لتحديث  وتصحيح تسمية الملف الأول binary_sort إلى binary_seach فهو ليس <a href="https://wiki.hsoub.com/Algorithms/Sorting_Algorithms" rel="external">خوارزمية ترتيب</a> إنما <a href="https://wiki.hsoub.com/Algorithms/Searching_Algorithms" rel="external">خوارزمية بحث</a> وهو خطأ مقصود نريد أن نختبر قدرته على اكتشافه.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="168930" href="https://academy.hsoub.com/uploads/monthly_2025_03/009_github_copilot_example_4.png.5cc27289d4622b7befc1e0a51b590a2e.png" rel=""><img alt="009 github copilot example 4" class="ipsImage ipsImage_thumbnailed" data-fileid="168930" data-unique="2yoaz41gg" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/009_github_copilot_example_4.thumb.png.b8ec90003dc4da9701253c5c1c71c0b2.png"> </a>
</p>

<p>
	سنجد أن المساعد اكتشف المشكلات بالفعل ووضحها لنا في قائمة مرقمة، كما في الصورة التالية، ويمكننا أن نطلب منه تطبيقها.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="168931" href="https://academy.hsoub.com/uploads/monthly_2025_03/010_github_copilot_example_4-fix.png.90c3223123fd71bd3f2c00d9fd638d72.png" rel=""><img alt="010 github copilot example 4 fix" class="ipsImage ipsImage_thumbnailed" data-fileid="168931" data-unique="irwy0oroa" src="https://academy.hsoub.com/uploads/monthly_2025_03/010_github_copilot_example_4-fix.thumb.png.e1cbb70246ab3203e4d8118c40211830.png"> </a>
</p>

<p>
	سيطبق المساعد الذكي هذه التعديلات، ولكن بتصفح الملفات نلاحظ أنه يقترح علينا كمُراجِع للكود code reviewing تعديل أو تصحيح بعض الأشياء، وهذه قد تكون ميزة مفيدة لاكتشاف الأخطاء أو المشاكل.
</p>

<p>
	يمكننا النقاش أيضًا حول تطبيق خوارزمية معينة وكيفية تحسينها كما في المثال التالي.
</p>

<p>
	كتبنا بداية الكود التالي <a href="https://academy.hsoub.com/python/" rel="">بلغة بايثون</a> والذي يتضمن تنفيذ لخوارزميتي الترتيب بالإدراج Insertion Sort والترتيب بالدمج Merge Sort من أجل ترتيب العناصر داخل قائمة وذلك قبل المناقشة والتحسين:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3509_11" style=""><span class="kwd">def</span><span class="pln"> insertion_sort</span><span class="pun">(</span><span class="pln">arr</span><span class="pun">):</span><span class="pln">
    </span><span class="kwd">for</span><span class="pln"> i </span><span class="kwd">in</span><span class="pln"> range</span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> len</span><span class="pun">(</span><span class="pln">arr</span><span class="pun">)):</span><span class="pln">
        key </span><span class="pun">=</span><span class="pln"> arr</span><span class="pun">[</span><span class="pln">i</span><span class="pun">]</span><span class="pln">
        j </span><span class="pun">=</span><span class="pln"> i </span><span class="pun">-</span><span class="pln"> </span><span class="lit">1</span><span class="pln">
        </span><span class="kwd">while</span><span class="pln"> j </span><span class="pun">&gt;=</span><span class="pln"> </span><span class="lit">0</span><span class="pln"> </span><span class="kwd">and</span><span class="pln"> arr</span><span class="pun">[</span><span class="pln">j</span><span class="pun">]</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> key</span><span class="pun">:</span><span class="pln">
            arr</span><span class="pun">[</span><span class="pln">j</span><span class="pun">+</span><span class="lit">1</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> arr</span><span class="pun">[</span><span class="pln">j</span><span class="pun">]</span><span class="pln">
            j </span><span class="pun">-=</span><span class="pln"> </span><span class="lit">1</span><span class="pln">
        arr</span><span class="pun">[</span><span class="pln">j</span><span class="pun">+</span><span class="lit">1</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> key


</span><span class="kwd">def</span><span class="pln"> merge_sort</span><span class="pun">(</span><span class="pln">arr</span><span class="pun">):</span><span class="pln">
    </span><span class="kwd">if</span><span class="pln"> len</span><span class="pun">(</span><span class="pln">arr</span><span class="pun">)</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">1</span><span class="pun">:</span><span class="pln">
        mid </span><span class="pun">=</span><span class="pln"> len</span><span class="pun">(</span><span class="pln">arr</span><span class="pun">)</span><span class="pln"> </span><span class="pun">//</span><span class="pln"> </span><span class="lit">2</span><span class="pln">
        left_half </span><span class="pun">=</span><span class="pln"> arr</span><span class="pun">[:</span><span class="pln">mid</span><span class="pun">]</span><span class="pln">
        right_half </span><span class="pun">=</span><span class="pln"> arr</span><span class="pun">[</span><span class="pln">mid</span><span class="pun">:]</span><span class="pln">


        merge_sort</span><span class="pun">(</span><span class="pln">left_half</span><span class="pun">)</span><span class="pln">
        merge_sort</span><span class="pun">(</span><span class="pln">right_half</span><span class="pun">)</span><span class="pln">


        i </span><span class="pun">=</span><span class="pln"> j </span><span class="pun">=</span><span class="pln"> k </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pln">


        </span><span class="kwd">while</span><span class="pln"> i </span><span class="pun">&lt;</span><span class="pln"> len</span><span class="pun">(</span><span class="pln">left_half</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">and</span><span class="pln"> j </span><span class="pun">&lt;</span><span class="pln"> len</span><span class="pun">(</span><span class="pln">right_half</span><span class="pun">):</span><span class="pln">
            </span><span class="kwd">if</span><span class="pln"> left_half</span><span class="pun">[</span><span class="pln">i</span><span class="pun">]</span><span class="pln"> </span><span class="pun">&lt;</span><span class="pln"> right_half</span><span class="pun">[</span><span class="pln">j</span><span class="pun">]:</span><span class="pln">
                arr</span><span class="pun">[</span><span class="pln">k</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> left_half</span><span class="pun">[</span><span class="pln">i</span><span class="pun">]</span><span class="pln">
                i </span><span class="pun">+=</span><span class="pln"> </span><span class="lit">1</span><span class="pln">
            </span><span class="kwd">else</span><span class="pun">:</span><span class="pln">
                arr</span><span class="pun">[</span><span class="pln">k</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> right_half</span><span class="pun">[</span><span class="pln">j</span><span class="pun">]</span><span class="pln">
                j </span><span class="pun">+=</span><span class="pln"> </span><span class="lit">1</span><span class="pln">
            k </span><span class="pun">+=</span><span class="pln"> </span><span class="lit">1</span><span class="pln">


        </span><span class="kwd">while</span><span class="pln"> i </span><span class="pun">&lt;</span><span class="pln"> len</span><span class="pun">(</span><span class="pln">left_half</span><span class="pun">):</span><span class="pln">
            arr</span><span class="pun">[</span><span class="pln">k</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> left_half</span><span class="pun">[</span><span class="pln">i</span><span class="pun">]</span><span class="pln">
            i </span><span class="pun">+=</span><span class="pln"> </span><span class="lit">1</span><span class="pln">
            k </span><span class="pun">+=</span><span class="pln"> </span><span class="lit">1</span><span class="pln">


        </span><span class="kwd">while</span><span class="pln"> j </span><span class="pun">&lt;</span><span class="pln"> len</span><span class="pun">(</span><span class="pln">right_half</span><span class="pun">):</span><span class="pln">
            arr</span><span class="pun">[</span><span class="pln">k</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> right_half</span><span class="pun">[</span><span class="pln">j</span><span class="pun">]</span><span class="pln">
            j </span><span class="pun">+=</span><span class="pln"> </span><span class="lit">1</span><span class="pln">
            k </span><span class="pun">+=</span><span class="pln"> </span><span class="lit">1</span></pre>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="168932" href="https://academy.hsoub.com/uploads/monthly_2025_03/011_github_copilot_example_5.png.0163a3662ddfe9134090ffd6d95217b3.png" rel=""><img alt="011 github copilot example 5" class="ipsImage ipsImage_thumbnailed" data-fileid="168932" data-unique="7ua68wb9q" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/011_github_copilot_example_5.thumb.png.01965e2e2e434e94b03c675ad8a7e2d6.png"> </a>
</p>

<p>
	وفيما يلي الكود بعد التحسين واستخدام أسلوب يدمج بين خوارزميتي الترتيب لجمع ميزاتهما معًا:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3509_14" style=""><span class="com"># This file contains implementation of merge sort algorithm.</span><span class="pln">


</span><span class="kwd">def</span><span class="pln"> insertion_sort</span><span class="pun">(</span><span class="pln">arr</span><span class="pun">):</span><span class="pln">
    </span><span class="kwd">for</span><span class="pln"> i </span><span class="kwd">in</span><span class="pln"> range</span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> len</span><span class="pun">(</span><span class="pln">arr</span><span class="pun">)):</span><span class="pln">
        key </span><span class="pun">=</span><span class="pln"> arr</span><span class="pun">[</span><span class="pln">i</span><span class="pun">]</span><span class="pln">
        j </span><span class="pun">=</span><span class="pln"> i </span><span class="pun">-</span><span class="pln"> </span><span class="lit">1</span><span class="pln">
        </span><span class="kwd">while</span><span class="pln"> j </span><span class="pun">&gt;=</span><span class="pln"> </span><span class="lit">0</span><span class="pln"> </span><span class="kwd">and</span><span class="pln"> arr</span><span class="pun">[</span><span class="pln">j</span><span class="pun">]</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> key</span><span class="pun">:</span><span class="pln">
            arr</span><span class="pun">[</span><span class="pln">j</span><span class="pun">+</span><span class="lit">1</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> arr</span><span class="pun">[</span><span class="pln">j</span><span class="pun">]</span><span class="pln">
            j </span><span class="pun">-=</span><span class="pln"> </span><span class="lit">1</span><span class="pln">
        arr</span><span class="pun">[</span><span class="pln">j</span><span class="pun">+</span><span class="lit">1</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> key


</span><span class="kwd">def</span><span class="pln"> merge_sort</span><span class="pun">(</span><span class="pln">arr</span><span class="pun">,</span><span class="pln"> threshold</span><span class="pun">=</span><span class="lit">10</span><span class="pun">):</span><span class="pln">
    </span><span class="kwd">if</span><span class="pln"> len</span><span class="pun">(</span><span class="pln">arr</span><span class="pun">)</span><span class="pln"> </span><span class="pun">&lt;=</span><span class="pln"> threshold</span><span class="pun">:</span><span class="pln">
        insertion_sort</span><span class="pun">(</span><span class="pln">arr</span><span class="pun">)</span><span class="pln">
        </span><span class="kwd">return</span><span class="pln"> arr
    </span><span class="kwd">if</span><span class="pln"> len</span><span class="pun">(</span><span class="pln">arr</span><span class="pun">)</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">1</span><span class="pun">:</span><span class="pln">
        mid </span><span class="pun">=</span><span class="pln"> len</span><span class="pun">(</span><span class="pln">arr</span><span class="pun">)</span><span class="pln"> </span><span class="pun">//</span><span class="pln"> </span><span class="lit">2</span><span class="pln">
        left_half </span><span class="pun">=</span><span class="pln"> arr</span><span class="pun">[:</span><span class="pln">mid</span><span class="pun">]</span><span class="pln">
        right_half </span><span class="pun">=</span><span class="pln"> arr</span><span class="pun">[</span><span class="pln">mid</span><span class="pun">:]</span><span class="pln">


        merge_sort</span><span class="pun">(</span><span class="pln">left_half</span><span class="pun">,</span><span class="pln"> threshold</span><span class="pun">)</span><span class="pln">
        merge_sort</span><span class="pun">(</span><span class="pln">right_half</span><span class="pun">,</span><span class="pln"> threshold</span><span class="pun">)</span><span class="pln">


        i </span><span class="pun">=</span><span class="pln"> j </span><span class="pun">=</span><span class="pln"> k </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pln">
        </span><span class="kwd">while</span><span class="pln"> i </span><span class="pun">&lt;</span><span class="pln"> len</span><span class="pun">(</span><span class="pln">left_half</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">and</span><span class="pln"> j </span><span class="pun">&lt;</span><span class="pln"> len</span><span class="pun">(</span><span class="pln">right_half</span><span class="pun">):</span><span class="pln">
            </span><span class="kwd">if</span><span class="pln"> left_half</span><span class="pun">[</span><span class="pln">i</span><span class="pun">]</span><span class="pln"> </span><span class="pun">&lt;</span><span class="pln"> right_half</span><span class="pun">[</span><span class="pln">j</span><span class="pun">]:</span><span class="pln">
                arr</span><span class="pun">[</span><span class="pln">k</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> left_half</span><span class="pun">[</span><span class="pln">i</span><span class="pun">]</span><span class="pln">
                i </span><span class="pun">+=</span><span class="pln"> </span><span class="lit">1</span><span class="pln">
            </span><span class="kwd">else</span><span class="pun">:</span><span class="pln">
                arr</span><span class="pun">[</span><span class="pln">k</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> right_half</span><span class="pun">[</span><span class="pln">j</span><span class="pun">]</span><span class="pln">
                j </span><span class="pun">+=</span><span class="pln"> </span><span class="lit">1</span><span class="pln">
            k </span><span class="pun">+=</span><span class="pln"> </span><span class="lit">1</span><span class="pln">


        </span><span class="kwd">while</span><span class="pln"> i </span><span class="pun">&lt;</span><span class="pln"> len</span><span class="pun">(</span><span class="pln">left_half</span><span class="pun">):</span><span class="pln">
            arr</span><span class="pun">[</span><span class="pln">k</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> left_half</span><span class="pun">[</span><span class="pln">i</span><span class="pun">]</span><span class="pln">
            i </span><span class="pun">+=</span><span class="pln"> </span><span class="lit">1</span><span class="pln">
            k </span><span class="pun">+=</span><span class="pln"> </span><span class="lit">1</span><span class="pln">


        </span><span class="kwd">while</span><span class="pln"> j </span><span class="pun">&lt;</span><span class="pln"> len</span><span class="pun">(</span><span class="pln">right_half</span><span class="pun">):</span><span class="pln">
            arr</span><span class="pun">[</span><span class="pln">k</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> right_half</span><span class="pun">[</span><span class="pln">j</span><span class="pun">]</span><span class="pln">
            j </span><span class="pun">+=</span><span class="pln"> </span><span class="lit">1</span><span class="pln">
            k </span><span class="pun">+=</span><span class="pln"> </span><span class="lit">1</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> arr


</span><span class="com"># test the merge_sort function with some test cases</span><span class="pln">
sample </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="lit">5</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">9</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">5</span><span class="pun">,</span><span class="pln"> </span><span class="lit">6</span><span class="pun">]</span><span class="pln">
merge_sort</span><span class="pun">(</span><span class="pln">sample</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">sample</span><span class="pun">)</span></pre>

<h3>
	تخصيص تجربة الاستخدام
</h3>

<p>
	قد نرغب في بعض الأحيان بأن يتبع المساعد البرمجي أسلوبًا معينًا نستخدمه في كتابة أكوادنا ولذلك نكثر في تفصيل التعليمات وتوضيحها له، ولكن هناك طريقة أفضل حيث يمكن أن نوضح للمساعد البرمجي أسلوبًا معينًا نطبقه على كامل المشروع ضمن ملف تعليمات بحيث لا نكون مضطرين لتوضيح تعليمات التخصيص في كل أمر نطلبه منه.
</p>

<p>
	للقيام بذلك سننشئ مجلدًا باسم <code>github.</code> ثم نضيف له ملفًا باسم <code>copilot-instructions.md</code> حيث سنكتب في هذا الملف التعليمات اللازمة والأسلوب الذي نحب كتابة الكود به كي يتبعها مساعدنا البرمجي.
</p>

<p>
	لاحظ المثال التالي حيث نوضح بداية كيف سيكتب لنا Github Copilot الجمل الشرطية بصيغة مختصرة تسمى <a href="https://academy.hsoub.com/programming/javascript/%D8%A7%D9%84%D8%B9%D8%A8%D8%A7%D8%B1%D8%A7%D8%AA-%D8%A7%D9%84%D8%B4%D8%B1%D8%B7%D9%8A%D8%A9-%D9%88%D8%A7%D8%AA%D8%AE%D8%A7%D8%B0-%D8%A7%D9%84%D9%82%D8%B1%D8%A7%D8%B1-%D9%81%D9%8A-%D8%AC%D8%A7%D9%81%D8%A7-%D8%B3%D9%83%D8%B1%D9%8A%D8%A8%D8%AA-r2271/#:~:text=%D8%A7%D9%84%D8%B9%D8%A7%D9%85%D9%84%20%D8%A7%D9%84%D8%AB%D9%84%D8%A7%D8%AB%D9%8A%20Ternary%20operator" rel="">العامل الثلاثي Ternary operator</a>، ثم نوضح <a href="https://academy.hsoub.com/programming/python/%D8%A7%D9%84%D8%AA%D8%B9%D9%84%D9%8A%D9%82%D8%A7%D8%AA-comments-%D9%88%D8%A3%D9%86%D9%88%D8%A7%D8%B9%D9%87%D8%A7-%D9%81%D9%8A-%D9%84%D8%BA%D8%A9-%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-r2026/#:~:text=%D8%A7%D9%84%D9%8A%D9%88%D9%86%D9%8A%D9%83%D9%88%D8%AF%20%D8%A7%D9%84%D8%B9%D9%85%D9%84%D9%8A%22.-,%D8%B3%D9%84%D8%A7%D8%B3%D9%84%20%D8%A7%D9%84%D8%AA%D9%88%D8%AB%D9%8A%D9%82%20%D8%A7%D9%84%D9%86%D8%B5%D9%8A%D8%A9%20Docstrings,-%D8%B3%D9%84%D8%A7%D8%B3%D9%84%20%D8%A7%D9%84%D8%AA%D9%88%D8%AB%D9%8A%D9%82%20%D8%A7%D9%84%D9%86%D8%B5%D9%8A%D8%A9" rel="">أسلوب توثيق</a> الكود البرمجي الذي نرغب باستخدامه.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="168933" href="https://academy.hsoub.com/uploads/monthly_2025_03/012_github_copilot_custom_instructions_1.png.79841154c3c63ca10edfbf0cef8e2bc9.png" rel=""><img alt="012 github copilot custom instructions 1" class="ipsImage ipsImage_thumbnailed" data-fileid="168933" data-unique="tb0r4opq9" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/012_github_copilot_custom_instructions_1.thumb.png.994b77e16f29bfe467022c31e95b316c.png"> </a>
</p>

<p>
	لنختبر المخرجات بعض إضافة هذا التعديل.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="168934" href="https://academy.hsoub.com/uploads/monthly_2025_03/013_github_copilot_custom_nstructions_2.png.313ad73b338d3b90d97693a238de6eda.png" rel=""><img alt="013 github copilot custom nstructions 2" class="ipsImage ipsImage_thumbnailed" data-fileid="168934" data-unique="kv827tx42" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/013_github_copilot_custom_nstructions_2.thumb.png.412a2f4c7ff719ba2e024374945446ce.png"> </a>
</p>

<p>
	نلاحظ أن توثيق الكود بهذه الطريقة سيمكننا من معرفة معلومات عن الدالة عند تحديدها أو استخدامها في أي مكان آخر كما في المثال التالي.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="168935" href="https://academy.hsoub.com/uploads/monthly_2025_03/014_github_copilot_custom_instructions_3.png.f3b944ef73b391ad4bb0f6ec5f0fff38.png" rel=""><img alt="014 github copilot custom instructions 3" class="ipsImage ipsImage_thumbnailed" data-fileid="168935" data-unique="vtev0g3on" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/014_github_copilot_custom_instructions_3.thumb.png.3e957a0c8c52ba29e4f54673b9309b3e.png"> </a>
</p>

<h3>
	مراجعة وتدقيق الكود
</h3>

<p>
	يمكننا استخدام Github Copilot لتدقيق ومراجعة الكود أو تلخيص التغيرات قبل <a href="https://academy.hsoub.com/programming/workflow/git/%D8%A5%D9%86%D8%B4%D8%A7%D8%A1-%D8%B7%D9%84%D8%A8-%D8%B3%D8%AD%D8%A8-%D8%B9%D9%84%D9%89-github-r1581/" rel="">طلب سحب Pull request</a> الكود لمستودع الأكواد على Github فهذا يقلل <a href="https://academy.hsoub.com/programming/general/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D9%85%D9%84-%D9%85%D8%B9-%D8%A7%D9%84%D8%A3%D8%AE%D8%B7%D8%A7%D8%A1-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D8%A9-r1342/" rel="">الأخطاء البرمجية</a> ويحسن جودة الأكواد المرفوعة.
</p>

<p>
	سنتبع الخطوات التالية لاستخدام هذه الميزة :
</p>

<ol>
	<li>
		نتوجه لمستودع الأكواد على Github ونطلب سحب Pull جديد أو نستخدم طلب موجود بالفعل
	</li>
	<li>
		نفتح قائمة Reviewers ونختار منها Github Copilot
	</li>
	<li>
		سيراجع المساعد الكود ويدققه لنا ثم يقدم اقتراحاته
	</li>
	<li>
		يمكننا التعامل مع التعليقات والمراجعات التي يوفرها Github Copilot كالمراجعة البشرية بقبولها أو رفضها
	</li>
</ol>

<p>
	سنجرب هذه الميزة عن طريق إنشاء مستودع أكواد Repository جديد على منصة Github ونضيف ملف بايثون <code>math_utils.py</code> يحتوي على دالة برمجية لقسمة رقمين، ولكن بها خطأ حيث لم نأخذ بعين الاعتبار الحالة التي يكون المقسوم عليه صفر، وسنفترض أن أحد المساهمين لاحظ هذه المشكلة وقام بطلب<span ipsnoautolink="true"> اشتقاق Fork لمستودع الأكواد</span> ليصلح المشكلة، وبعد ذلك طلب <a href="https://academy.hsoub.com/programming/workflow/git/%D8%A5%D9%86%D8%B4%D8%A7%D8%A1-%D8%B7%D9%84%D8%A8-%D8%B3%D8%AD%D8%A8-%D8%B9%D9%84%D9%89-github-r1581/" rel="">سحب الملف Pull Request</a> إلى المستودع الأصلي.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="168936" href="https://academy.hsoub.com/uploads/monthly_2025_03/015_github_copilot_PR_1.png.2de6bf19ef402ba25bac8b4ef7962155.png" rel=""><img alt="015 github copilot pr 1" class="ipsImage ipsImage_thumbnailed" data-fileid="168936" data-unique="wh1fpjals" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/015_github_copilot_PR_1.thumb.png.9ee479fee05a4100234a4751c1959f78.png"> </a>
</p>

<p>
	في حال كنت صاحب مستودع الأكواد، فلا حاجة لاشتقاق المستودع Forking حيث يمكن إنشاء تفريعة Branch ثم طلب سحبها Pull Request.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="168937" href="https://academy.hsoub.com/uploads/monthly_2025_03/016_github_copilot_PR_2.png.93b4dda86ad1a158dbc321c347e1a738.png" rel=""><img alt="016 github copilot pr 2" class="ipsImage ipsImage_thumbnailed" data-fileid="168937" data-unique="fdeowr86e" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/016_github_copilot_PR_2.thumb.png.d7b6013d87c8f0e0a8a5774de7d4f1f2.png"> </a>
</p>

<p>
	لنصحح الدالة بإضافة حالة شرطية عند كون المقسوم عليه صفرًا ونطبع رسالة الخطأ لتنبيه المستخدم.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="168938" href="https://academy.hsoub.com/uploads/monthly_2025_03/017_github_copilot_PR_3.png.9c29d0beb17f230dc1e78d313e6ebd60.png" rel=""><img alt="017 github copilot pr 3" class="ipsImage ipsImage_thumbnailed" data-fileid="168938" data-unique="ywidy40k4" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/017_github_copilot_PR_3.thumb.png.c9850e08e79170272d75586ec10f514c.png"> </a>
</p>

<p>
	ثم نطلب سحب Pull هذا التفريع Branch الذي يحتوي التصحيح للفرع الأصلي والرئيسي.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="168939" href="https://academy.hsoub.com/uploads/monthly_2025_03/018_github_copilot_PR_4.png.0c9031cd30ea153904eb1d751616cfbd.png" rel=""><img alt="018 github copilot pr 4" class="ipsImage ipsImage_thumbnailed" data-fileid="168939" data-unique="nnao31tn1" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/018_github_copilot_PR_4.thumb.png.ece34bd621243f4701fcfd62ef7ba1b8.png"> </a>
</p>

<p>
	نلاحظ أنه Github Copilot قد لا يظهر لدينا في قائمة Reviewers ولكن يمكننا استخدامه لتلخيص طلب السحب Pull Request وهذا ما سنقوم به، حيث أن هذه الميزة لاتزال تجريبية وليست متاحة لدى الجميع.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="168940" href="https://academy.hsoub.com/uploads/monthly_2025_03/019_github_copilot_PR_5.png.56c7471b8511185b576b8115f21be26f.png" rel=""><img alt="019 github copilot pr 5" class="ipsImage ipsImage_thumbnailed" data-fileid="168940" data-unique="e6d15pwrf" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/019_github_copilot_PR_5.thumb.png.d303d76ab1cf40844cff459039bbda4f.png"> </a>
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="168941" href="https://academy.hsoub.com/uploads/monthly_2025_03/019_github_copilot_PR_6.png.cdaf0602652d2cf0792079b6d4aaa8bf.png" rel=""><img alt="019 github copilot pr 6" class="ipsImage ipsImage_thumbnailed" data-fileid="168941" data-unique="7nugfx1ae" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/019_github_copilot_PR_6.thumb.png.49986b2ee0122b3cd1f0eabd9aa11cb3.png"> </a>
</p>

<h3 id="githubcopilot-2">
	استخدام GitHub Copilot كخبير برمجي
</h3>

<p>
	يتميز Github Copilot بميزة أخرى تجعله من أدوات الذكاء الاصطناعي البرمجية الفريدة، حيث يمكنه أن يعمل كخبير متخصص نستدعيه عند الوقوع في مشكلة أو عندما نرغب في معرفة آلية تنفيذ شيء ما، وهذا من خلال واجهة الحوار حيث يمكننا استدعاء الخبير من خلال رمز <code>@</code> الذي يتيح قائمة من الخبراء الافتراضيين لنسألهم، مثلًا <code>vscode@</code> يمكننا أن نسأله عن أي شيء يخص محرر الأكواد.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="168942" href="https://academy.hsoub.com/uploads/monthly_2025_03/020_github_copilot_experts-1.png.9a6fed1b4dfdeae6006d58b9eb5a86a0.png" rel=""><img alt="020 github copilot experts 1" class="ipsImage ipsImage_thumbnailed" data-fileid="168942" data-unique="kq0msg9rm" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/020_github_copilot_experts-1.thumb.png.070107c9661507a42fdec8f9ec4e70b8.png"> </a>
</p>

<p>
	نرى في هذا المثال كيف طلبنا من الخبير أن يوضح لنا كيفية تغير مظهر وتنسيق محرر الأكواد، فأخرج لنا زرًا عندما نضغط عليه يقودنا لقائمة اختيارات يمكننا من خلالها اختيار المظهر الذي نريده.
</p>

<pre class="ipsCode" id="ips_uid_9990_30">@vscode how to change the Theme?</pre>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="168943" href="https://academy.hsoub.com/uploads/monthly_2025_03/021_github_copilot_experts_2.png.dbcfaf58c7c6d71d4aa72e6b70ef87d4.png" rel=""><img alt="021 github copilot experts 2" class="ipsImage ipsImage_thumbnailed" data-fileid="168943" data-unique="kuz5m49nu" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/021_github_copilot_experts_2.thumb.png.774e651f88790645e0ba62f43dd3f683.png"> </a>
</p>

<p>
	لا يتوقف الأمر عند محرر الأكواد فيوجد أكثر من خبير، مثل خبير سطر الأوامر Terminal، لنفترض أننا نريد أن ننشئ في مجلد للمحاضرات Lectures، عشرة مجلدات فرعية منه وبكل منها ملف نصي فارغ برقم المحاضرة، والتي سنملؤها لاحقًا بملاحظات عن هذه المحاضرة، يمكن بالطبع محاولة فعل هذا بشكل يدوي لكن قد يستغرق الأمر وقتًا طويلًا لذا من الأفضل استخدام سطر الأوامر لتنفيذ هذه العملية بمساعدة Github Copilot.
</p>

<pre class="ipsCode" id="ips_uid_9990_33">@terminal I want to create 10 folders names Lecture{i}, i the number of lecture, and for each lecture it would contain a text file named as lecture{i}_notes.txt</pre>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="168944" href="https://academy.hsoub.com/uploads/monthly_2025_03/022_github_copilot_experts_3.png.64dea086833f6ecb46de4ab83518a445.png" rel=""><img alt="022 github copilot experts 3" class="ipsImage ipsImage_thumbnailed" data-fileid="168944" data-unique="ko2xxziyc" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/022_github_copilot_experts_3.thumb.png.2532a93312a1f142676a28812d6e6141.png"> </a>
</p>

<p>
	لنفتح واجهة سطر الأوامر من خلال أحد الأزار السريعة من نافذة الحوار أو من قائمة View ثم نختار Terminal لنتمكن من وضع الأمر المولد وتشغيله، نلاحظ أن الأمر مكتوب باستخدام Powershell لأننا في حالتنا نستخدم نظام تشغيل ويندوز Windows ولكن يمكن أن نطلب استخدام Bash في حال استخدام <a href="https://academy.hsoub.com/devops/linux/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D9%84%D9%8A%D9%86%D9%83%D8%B3-r799/" rel="">نظام لينكس</a>، وكما نرى فقد استطاع الأمر إنشاء الملفات التي طلبناها دون أية مشكلات، وهذه الميزة مفيدة للغاية عندما نرغب في تنفيذ بعض الأوامر من <a href="https://academy.hsoub.com/devops/linux/%D9%83%D9%8A%D9%81-%D8%AA%D8%B3%D8%AA%D8%AE%D8%AF%D9%85-%D8%B7%D8%B1%D9%81%D9%8A%D8%A9-%D9%84%D9%8A%D9%86%D9%83%D8%B3-%D8%A8%D8%A7%D8%AD%D8%AA%D8%B1%D8%A7%D9%81-r367/" rel="">الطرفية</a> ولكننا لا نتذكر الكلمات المفتاحية أو طريقة كتابة الأمر.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="168945" href="https://academy.hsoub.com/uploads/monthly_2025_03/023_github_copilot_experts_4.png.9f9e28bbf9b09ee38ce6adda09bd7f17.png" rel=""><img alt="023 github copilot experts 4" class="ipsImage ipsImage_thumbnailed" data-fileid="168945" data-unique="g8ocdh60v" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/023_github_copilot_experts_4.thumb.png.ec7d3d26d454f0b9b5411c76d7ecdfba.png"> </a>
</p>

<h2 id="githubcopilot-3">
	حالات استخدام إضافية لمساعد Github Copilot
</h2>

<p>
	استعرضنا في الفقرات السابقة أبرز حالات استخدام مساعد Github Copilot في محرر الأكواد، لكن في الواقع تتخطى حالات استخدام مساعد Github Copilot ملفات الكود العادية التي نتعامل معها في <a href="https://academy.hsoub.com/programming/general/%D9%85%D8%AC%D8%A7%D9%84%D8%A7%D8%AA-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D8%A9/" rel="">تخصصات البرمجة</a> الشائعة كتطوير الواجهات الأمامية أو الخلفية، لتصل إلى البيئات المخصصة <a href="https://academy.hsoub.com/programming/general/%D9%87%D9%86%D8%AF%D8%B3%D8%A9-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA/" rel="">لمهندسي البيانات</a> وتعلم الآلة المتمثلة في jupyter notebook، ولتجربة هذه الميزات سنستخدم مجموعة بيانات بسيطة وهي مجموعة بيانات لبعض ركاب سفينة تايتنك الغارقة والتي يمكنك العثور عليها في<a href="https://www.kaggle.com/competitions/titanic/data" rel="external nofollow"> موقع كاجل Kaggle</a>.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="168946" href="https://academy.hsoub.com/uploads/monthly_2025_03/025_github_copilot_notebooks.png.1391f82d926db2b96e8388be11bfdac0.png" rel=""><img alt="025 github copilot notebooks" class="ipsImage ipsImage_thumbnailed" data-fileid="168946" data-unique="dca71q33z" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/025_github_copilot_notebooks.thumb.png.7838230b6c824303d7ce83dbcaab372a.png"> </a>
</p>

<p>
	لنعرض بضعة صفوف من مجموعة البيانات
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_3509_26" style=""><span class="kwd">import</span><span class="pln"> pandas ad pd


</span><span class="com"># حمل مجموعة بيانات تيتانيك</span><span class="pln">
titanic_df </span><span class="pun">=</span><span class="pln"> pd</span><span class="pun">.</span><span class="pln">read_csv</span><span class="pun">(</span><span class="str">'titanic.csv'</span><span class="pun">)</span><span class="pln">


</span><span class="com"># اطبع الصفوف الأولى من البيانات</span><span class="pln">
titanic_df</span><span class="pun">.</span><span class="pln">head</span><span class="pun">()</span></pre>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="168947" href="https://academy.hsoub.com/uploads/monthly_2025_03/026_github_copilot_notebooks_1.png.24fa1f4c7e2078b72ad5397a2a4f0b63.png" rel=""><img alt="026 github copilot notebooks 1" class="ipsImage ipsImage_thumbnailed" data-fileid="168947" data-unique="h2ly78ibq" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/026_github_copilot_notebooks_1.thumb.png.830612ea9d5d10d5cd8f59c9faff9f24.png"> </a>
</p>

<p>
	باختيار زر التوليد Generate يمكننا طرح أسئلة أو توجيه أوامر بشكل كتابي أو من خلال الصوت ثم الموافقة على الاقتراح المولد أو طلب تعديله ليناسب حالة الاستخدام.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="168948" href="https://academy.hsoub.com/uploads/monthly_2025_03/027_github_copilot_notebooks_2.png.308f403615dedca12af23013c0e94996.png" rel=""><img alt="027 github copilot notebooks 2" class="ipsImage ipsImage_thumbnailed" data-fileid="168948" data-unique="4fe39cjcq" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/027_github_copilot_notebooks_2.thumb.png.af41342622c04c198d2b95c66407bbfa.png"> </a>
</p>

<p>
	فور الموافقة على الاقتراح بالضغط على قبول وتشغيل Accept &amp; Run سنجد الرسم البياني التالي كمخرج.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="168950" href="https://academy.hsoub.com/uploads/monthly_2025_03/028_github_copilot_notebooks_3.png.db7aaa22e95c4385a0da668188dba050.png" rel=""><img alt="028 github copilot notebooks 3" class="ipsImage ipsImage_thumbnailed" data-fileid="168950" data-unique="up7e00bhc" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/028_github_copilot_notebooks_3.png.db7aaa22e95c4385a0da668188dba050.png"> </a>
</p>

<p>
	يوحي الرسم البياني بمعلومة هامة بخصوص نسب النجاة، فكما نرى نسبة النجاة في النساء أكبر، ونسبة الهلاك في الرجال أكبر، قد يكون هذا عائدًا بنسبة كبيرة للأولوية المعطاة للنساء والأطفال في قوارب النجاة ولكن هل يمكن للمساعد البرمجي فهم الرسومات البيانية وتلخيص الملاحظات الخاصة بها، لنختبر هذا.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="168949" href="https://academy.hsoub.com/uploads/monthly_2025_03/027_github_copilot_notebooks_4.png.3e8a5b47364d35f62fb22055e0101e40.png" rel=""><img alt="027 github copilot notebooks 4" class="ipsImage ipsImage_thumbnailed" data-fileid="168949" data-unique="loiej7do2" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/027_github_copilot_notebooks_4.thumb.png.fbfc402a4e6c26fa397ab58763545ab9.png"> </a>
</p>

<p>
	كما نلاحظ في السؤال الأول استطاع مساعدنا الذكي أن يستنتج ما يدل عليه الرسم البياني من نسبة نجاة أعلى للنساء، وكذلك بعد سؤاله عن سبب هذه قد استطاع توضيح السبب، وكما نلاحظ أيضًا فعند سؤاله باللغة العربية سيجيب باللغة العربية.
</p>

<p>
	لنوضح ميزة أخرى من خلال استخدام خلية كود يمكننا استخدام الرمز <code>:q</code> وطرح سؤال ثم سيجيب عنه المساعد البرمجي في نفس الخلية برمز مشابه به الإجابة <code>:a</code> كما في الصورة التالية.
</p>

<pre class="ipsCode" id="ips_uid_9990_42">titanic_df.head(3)

q: what does SibSp mean?</pre>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="168951" href="https://academy.hsoub.com/uploads/monthly_2025_03/028_github_copilot_notebooks_5.png.9a5a2ab77476409f8cddc853337cb266.png" rel=""><img alt="028 github copilot notebooks 5" class="ipsImage ipsImage_thumbnailed" data-fileid="168951" data-unique="2nuhytx9t" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/028_github_copilot_notebooks_5.thumb.png.6884e4da8c279b0df1993526a040404c.png"> </a>
</p>

<h2 id="pro">
	الحصول على الخطة المميزة من Github Copilot مجانًا
</h2>

<p>
	يمكن للطلبة أو المعلمين أو المساهمين في مشاريع مفتوحة المصدر الحصول على الخطة المميزة من Github Copilot بالمجان، فبالنسبة للطلبة يمكنهم رفع ما يثبت هذا من خلال هذه <a href="https://education.github.com/discount_requests/application?type=student" rel="external nofollow">الصفحة</a> التابعة لمنصة Github، أما المعلمون فيمكنهم من خلال هذه <a href="https://github.com/education/teachers" rel="external nofollow">الرابط</a> معرفة المميزات التي توفرها المنصة للمعلمين.
</p>

<p>
	يختلف الأمر قليلًا بالنسبة للمساهمين في المشاريع مفتوحة المصدر حيث ينبغي أن يصلوا لبعض الشروط التي تحددها المنصة ولا توجد طريقة للتقديم بشكل مباشر إنما ترسل إشعارات من خلال منصة Github للمساهمين الذين تجدهم مستحقين للخطة المميزة.
</p>

<p>
	بمجرد الحصول على الخطة المميزة كطالب برفع الإثباتات المطلوبة مثل الإيميل الجامعي وبطاقة الطالب التعريفية، سيعالج الطلب في بضعة أيام، وفي حال قبوله ستفتح ميزات متعددة لا تقتصر على الوصول لمساعد Github Copilot فقط، وإنما لمزايا أخرى يمكنك الاطلاع عليها من <a href="https://github.com/education" rel="external nofollow">هنا</a>، ولتفعيل الحساب المميز يجب تسجيل الخروج من حساب Github المحفوظ على محرر أكواد VS code وتسجيل الدخول إلى الحساب الذي جرى تفعيل الخطة المميزة عليها.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="168952" href="https://academy.hsoub.com/uploads/monthly_2025_03/029_github_copilot_logout.png.6057fd7dfff7a0d7a66408ee9e64a70b.png" rel=""><img alt="029 github copilot logout" class="ipsImage ipsImage_thumbnailed" data-fileid="168952" data-unique="o1oslb3sq" style="width: 600px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/029_github_copilot_logout.thumb.png.dada445068774d0126fbafd481250dce.png"> </a>
</p>

<p>
	للتأكد من تفعيل النسخة المميزة Pro يمكن مراجعة النماذج المتاحة للاستخدام، من خلال واجهة الحوار.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="168953" href="https://academy.hsoub.com/uploads/monthly_2025_03/030_github_copilot_models.png.3417b3912d9ffddcd4deb15f16b6a1d7.png" rel=""><img alt="030 github copilot models" class="ipsImage ipsImage_thumbnailed" data-fileid="168953" data-unique="14gum81g4" style="width: 500px; height: auto;" src="https://academy.hsoub.com/uploads/monthly_2025_03/030_github_copilot_models.thumb.png.38209b17eb57f2367db7ea127bbba151.png"> </a>
</p>

<h2 id="-4">
	الخاتمة
</h2>

<p>
	تعرفنا في هذه المقالة عن أبرز الميزات التي توفرها أداة الذكاء الاصطناعي كوبايلوت Github Copilot للمبرمجين والمطورين عند دمجها في محرر الأكواد فيجوال ستوديو كود، حيث يمكنها مراجعة وتحسين الأكواد التي نعمل عليها، أو إكمال وتوقع الأكواد التي نريد كتابتها وغيرها من الفوائد الأخرى التي تساعدنا في توفير وقتنا وتعزيز إنتاجيتنا كمطورين، وتطرقنا في ختام المقال لكيفية الحصول على الخطة المميزة Pro بالمجان والتي تسمح لنا بالوصول لمزيد من المميزات والنماذج القوية، هل جربتم دمج هذه الأداة مع محرر الأكواد؟ شاركونا تجربتكم في التعليقات أسفل المقال.
</p>

<h2 id="-5">
	اقرأ أيضًا
</h2>

<ul>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D9%85%D9%86%D8%B5%D8%A9-%D8%AA%D9%86%D8%B3%D8%B1%D9%81%D9%84%D9%88-tensorflow-%D9%84%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-r2491/" rel="">تعرف على منصة تنسرفلو TensorFlow للذكاء الاصطناعي</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/workflow/git/%D9%81%D9%87%D9%85-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%AD%D9%83%D9%85-%D8%A8%D8%A7%D9%84%D8%A5%D8%B5%D8%AF%D8%A7%D8%B1%D8%A7%D8%AA-git-%D9%88%D8%A3%D9%87%D9%85%D9%8A%D8%A9-%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85%D9%87-%D9%81%D9%8A-%D9%85%D8%B4%D8%A7%D8%B1%D9%8A%D8%B9-%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86-r2034/" rel="">فهم نظام التحكم بالإصدارات Git وأهمية استخدامه في مشاريع بايثون</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/workflow/git/%D8%A7%D9%84%D8%A5%D8%B4%D8%B1%D8%A7%D9%81-%D8%B9%D9%84%D9%89-%D9%85%D8%B4%D8%A7%D8%B1%D9%8A%D8%B9-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D8%A7%D8%AA-%D9%85%D9%81%D8%AA%D9%88%D8%AD%D8%A9-%D8%A7%D9%84%D9%85%D8%B5%D8%AF%D8%B1-%D8%B9%D8%A8%D8%B1-%D8%BA%D9%8A%D8%AA-%D9%87%D8%A8-github-r1585/" rel="">الإشراف على مشاريع البرمجيات مفتوحة المصدر عبر غيت هب GitHub</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/workflow/git/%D8%A7%D9%84%D8%AF%D9%84%D9%8A%D9%84-%D8%A7%D9%84%D9%85%D8%B1%D8%AC%D8%B9%D9%8A-%D9%84%D9%84%D8%B9%D9%85%D9%84-%D8%B9%D9%84%D9%89-%D9%86%D8%B8%D8%A7%D9%85-%D8%BA%D9%8A%D8%AA-git-r1587/" rel="">الدليل المرجعي للعمل على نظام غيت Git</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">2521</guid><pubDate>Tue, 04 Mar 2025 13:00:00 +0000</pubDate></item><item><title>&#x635;&#x64A;&#x63A;&#x629; &#x645;&#x644;&#x641;&#x627;&#x62A; GGUF &#x648;&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645;&#x647;&#x627; &#x641;&#x64A; &#x62A;&#x62E;&#x632;&#x64A;&#x646; &#x646;&#x645;&#x627;&#x630;&#x62C; Transformers</title><link>https://academy.hsoub.com/programming/artificial-intelligence/%D8%B5%D9%8A%D8%BA%D8%A9-%D9%85%D9%84%D9%81%D8%A7%D8%AA-gguf-%D9%88%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85%D9%87%D8%A7-%D9%81%D9%8A-%D8%AA%D8%AE%D8%B2%D9%8A%D9%86-%D9%86%D9%85%D8%A7%D8%B0%D8%AC-transformers-r2517/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2025_02/GGUFTransformers.png.bf610412cfc661b14f96fcded8269fb2.png" /></p>
<p>
	سننتعرف في مقال اليوم على صيغة ملفات GGUF التي تستخدم لتخزين النماذج للاستدلال Inference باستخدام مكتبة <a href="https://github.com/ggerganov/ggml" rel="external nofollow">GGML</a> والمكتبات الأخرى التي تعتمد عليها مثل <a href="https://github.com/ggerganov/llama.cpp" rel="external nofollow">llama.cpp</a> أو <a href="https://github.com/ggerganov/whisper.cpp" rel="external nofollow">whisper.cpp</a> الشهيرتين. يدعم مستودع <a href="https://huggingface.co/docs/hub/en/gguf" rel="external nofollow">Hub</a> هذه الصيغة مع ميزات تسمح بالفحص السريع للموترات Tensors والبيانات الوصفية داخل الملف.
</p>

<p>
	صُمِّمت هذه الصيغة بوصفها "صيغة ملف واحد"، حيث يحتوي الملف الواحد عادةً على كلٍّ من سمات الضبط Configuration Attributes ومفردات المرمِّز Tokenizer Vocabulary وسمات أخرى، بالإضافة إلى جميع الموترات المُراد تحميلها في النموذج. تأتي هذه الملفات بصيغ مختلفة وفقًا لنوع تكميم Quantization الملف، لذا اطّلع على <a href="https://huggingface.co/docs/hub/en/gguf#quantization-types" rel="external nofollow">بعض منها</a>.
</p>

<h2 id="gguf">
	استخدامات صيغة GGUF
</h2>

<p>
	يفيد استخدام صيغة GGUF في العديد من الجوانب تشمل:
</p>

<ol>
	<li>
		تخزين النماذج بكفاءة حيث تسهل ملفات GGUF تخزين جميع المعلومات المتعلقة بالنموذج في ملف واحد، مما يبسط عملية تحميل وتشغيل النماذج في بيئات مختلفة
	</li>
	<li>
		تدعم صيغة GGUF أنواعًا مختلفة من التكميم مثل F32، Q4_K، و Q6_K، مما يساعد على تقليل حجم النماذج مع الحفاظ على أدائها
	</li>
	<li>
		تتكامل مع مكتبات التحويل حيث يمكن استخدام ملفات GGUF مع مكتبة المحولات transformers لتحميل النماذج والمرمزين مباشرةً، مما يسهل عملية الاستدلال أو التدريب المخصص
	</li>
</ol>

<h2 id="gguftransformers">
	دعم صيغة GGUF ضمن مكتبة المحولات Transformers
</h2>

<p>
	لقد أُضفيت القدرة على تحميل ملفات <code>gguf</code> ضمن <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D9%85%D9%83%D8%AA%D8%A8%D8%A9-%D8%A7%D9%84%D9%85%D8%AD%D9%88%D9%91%D9%84%D8%A7%D8%AA-transformers-%D9%85%D9%86-%D9%85%D9%86%D8%B5%D8%A9-hugging-face-r2340/" rel="">مكتبة المحوِّلات <code>transformers</code></a> لتقديم مزيد من إمكانات التدريب أو <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%B7%D8%B1%D9%8A%D9%82%D8%A9-%D8%A7%D9%84%D8%B5%D9%82%D9%84-fine-tune-%D9%84%D9%86%D9%85%D9%88%D8%B0%D8%AC-%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-%D9%85%D9%8F%D8%AF%D9%8E%D8%B1%D9%91%D9%8E%D8%A8%D9%92-%D9%85%D9%8F%D8%B3%D8%A8%D9%82%D9%8B%D8%A7-r2367/" rel="">الصقل Fine-tuning</a> لنماذج gguf قبل تحويل هذه النماذج مرةً أخرى إلى صيغة <code>gguf</code> لاستخدامها ضمن نظام <code>ggml</code> البيئي، ويجب إلغاء تكميم النموذج إلى صيغة fp32 عند تحميله قبل تحميل الأوزان المُراد استخدامها في<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D8%A5%D8%B7%D8%A7%D8%B1-%D8%B9%D9%85%D9%84-%D8%A8%D8%A7%D9%8A-%D8%AA%D9%88%D8%B1%D8%B4-pytorch-%D9%88%D8%A3%D9%87%D9%85%D9%8A%D8%AA%D9%87-%D9%84%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-r2311/" rel=""> إطار عمل PyTorch</a>.
</p>

<p>
	<strong>ملاحظة</strong>: لا يزال الدعم في مراحله الأولى والمساهمات مرحَّبٌ بها لترسيخ هذا الدعم على أنواع التكميم وبنى النماذج المختلفة.
</p>

<p>
	سنوضّح فيما يلي بنى النماذج وأنواع التكميم المدعومة حاليًا.
</p>

<h3 id="">
	أنواع التكميم المدعومة
</h3>

<p>
	تُحدَّد أنواع التكميم المدعومة الأولية وفقًا لملفات التكميم الشائعة التي جرت مشاركتها على مستودع Hub وهي:
</p>

<ul>
	<li>
		F32
	</li>
	<li>
		Q2_K
	</li>
	<li>
		Q3_K
	</li>
	<li>
		Q4_0
	</li>
	<li>
		Q4_K
	</li>
	<li>
		Q5_K
	</li>
	<li>
		Q6_K
	</li>
	<li>
		Q8_0
	</li>
</ul>

<p>
	اطّلع على مثال من محلّل <a href="https://wiki.hsoub.com/Python" rel="external">بايثون Python</a> الممتاز ‎<a href="https://github.com/99991/pygguf" rel="external nofollow">99991/pygguf</a>‎ لإلغاء تكميم Dequantize الأوزان.
</p>

<p>
	<strong>ملاحظة</strong>: التكميم هو عملية ضغط تقلل من حجم النموذج عن طريق تقريب القيم داخل النموذج إلى نطاقات أقل دقة، مما يقلل من متطلبات التخزين والذاكرة.
</p>

<h3 id="-1">
	بنى النماذج المدعومة
</h3>

<p>
	بنى النماذج المدعومة حاليًا هي البنى الشائعة جدًا على مستودع Hub، وهي:
</p>

<ul>
	<li>
		LLaMa
	</li>
	<li>
		Mistral
	</li>
	<li>
		Qwen2
	</li>
</ul>

<h2 id="gguf-1">
	مثال لاستخدام صيغة ملفات GGUF
</h2>

<p>
	يمكننا تحميل ملفات <code>gguf</code> في مكتبة <code>transformers</code> من خلال تحديد الوسيط <code>gguf_file</code> لتوابع <code>from_pretrained</code> لكلٍّ من المرمِّزات والنماذج. وفيما يلي كيفية تحميل المرمِّز والنموذج، حيث يمكن تحميلهما من الملف نفسه:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_868_9" style=""><span class="kwd">from</span><span class="pln"> transformers </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">AutoTokenizer</span><span class="pun">,</span><span class="pln"> </span><span class="typ">AutoModelForCausalLM</span><span class="pln">

model_id </span><span class="pun">=</span><span class="pln"> </span><span class="str">"TheBloke/TinyLlama-1.1B-Chat-v1.0-GGUF"</span><span class="pln">
filename </span><span class="pun">=</span><span class="pln"> </span><span class="str">"tinyllama-1.1b-chat-v1.0.Q6_K.gguf"</span><span class="pln">

tokenizer </span><span class="pun">=</span><span class="pln"> </span><span class="typ">AutoTokenizer</span><span class="pun">.</span><span class="pln">from_pretrained</span><span class="pun">(</span><span class="pln">model_id</span><span class="pun">,</span><span class="pln"> gguf_file</span><span class="pun">=</span><span class="pln">filename</span><span class="pun">)</span><span class="pln">
model </span><span class="pun">=</span><span class="pln"> </span><span class="typ">AutoModelForCausalLM</span><span class="pun">.</span><span class="pln">from_pretrained</span><span class="pun">(</span><span class="pln">model_id</span><span class="pun">,</span><span class="pln"> gguf_file</span><span class="pun">=</span><span class="pln">filename</span><span class="pun">)</span></pre>

<p>
	وبهذا يمكننا الآن الوصول إلى الإصدار الكامل غير المكمَّم من النموذج في نظام PyTorch البيئي، والذي يمكن دمجه مع مجموعة كبيرة من الأدوات الأخرى. يُوصَى باستخدام ملف <code>convert-hf-to-gguf.py</code> من نموذج llama.cpp للتحويل مرةً أخرى إلى ملف <code>gguf</code>.
</p>

<p>
	نوضّح فيما يلي كيفية إكمال السكربت السابق لحفظ النموذج وتصديره مرةً أخرى إلى صيغة <code>gguf</code>:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_868_11" style=""><span class="pln">tokenizer</span><span class="pun">.</span><span class="pln">save_pretrained</span><span class="pun">(</span><span class="str">'directory'</span><span class="pun">)</span><span class="pln">
model</span><span class="pun">.</span><span class="pln">save_pretrained</span><span class="pun">(</span><span class="str">'directory'</span><span class="pun">)</span><span class="pln">

</span><span class="pun">!</span><span class="pln">python $</span><span class="pun">{</span><span class="pln">path_to_llama_cpp</span><span class="pun">}/</span><span class="pln">convert</span><span class="pun">-</span><span class="pln">hf</span><span class="pun">-</span><span class="pln">to</span><span class="pun">-</span><span class="pln">gguf</span><span class="pun">.</span><span class="pln">py $</span><span class="pun">{</span><span class="pln">directory</span><span class="pun">}</span></pre>

<p>
	ترجمة -وبتصرّف- للقسم <a href="https://huggingface.co/docs/transformers/gguf" rel="external nofollow">GGUF and interaction with Transformers</a> من توثيقات Hugging Face.
</p>

<h2 id="-2">
	اقرأ أيضًا
</h2>

<ul>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A7%D8%B3%D8%AA%D9%83%D8%B4%D8%A7%D9%81-%D8%A7%D9%84%D8%A3%D8%AE%D8%B7%D8%A7%D8%A1-%D9%88%D8%A5%D8%B5%D9%84%D8%A7%D8%AD%D9%87%D8%A7-%D9%81%D9%8A-%D9%85%D9%83%D8%AA%D8%A8%D8%A9-%D8%A7%D9%84%D9%85%D8%AD%D9%88%D9%84%D8%A7%D8%AA-transformers-r2509/" rel="">استكشاف الأخطاء وإصلاحها في مكتبة المحولات Transformers</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D9%85%D9%83%D8%AA%D8%A8%D8%A9-%D8%A7%D9%84%D9%85%D8%AD%D9%88%D9%91%D9%84%D8%A7%D8%AA-transformers-%D9%85%D9%86-%D9%85%D9%86%D8%B5%D8%A9-hugging-face-r2340/" rel="">تعرف على مكتبة المحوّلات Transformers من منصة Hugging Face</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-%D9%85%D9%83%D8%AA%D8%A8%D8%A9-%D8%A7%D9%84%D9%85%D8%AD%D9%88%D9%91%D9%84%D8%A7%D8%AA-transformers-r2352/" rel="">تثبيت مكتبة المحوّلات Transformers</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">2517</guid><pubDate>Wed, 26 Feb 2025 16:00:00 +0000</pubDate></item><item><title>&#x627;&#x633;&#x62A;&#x643;&#x634;&#x627;&#x641; &#x627;&#x644;&#x623;&#x62E;&#x637;&#x627;&#x621; &#x648;&#x625;&#x635;&#x644;&#x627;&#x62D;&#x647;&#x627; &#x641;&#x64A; &#x645;&#x643;&#x62A;&#x628;&#x629; &#x627;&#x644;&#x645;&#x62D;&#x648;&#x644;&#x627;&#x62A; Transformers</title><link>https://academy.hsoub.com/programming/artificial-intelligence/%D8%A7%D8%B3%D8%AA%D9%83%D8%B4%D8%A7%D9%81-%D8%A7%D9%84%D8%A3%D8%AE%D8%B7%D8%A7%D8%A1-%D9%88%D8%A5%D8%B5%D9%84%D8%A7%D8%AD%D9%87%D8%A7-%D9%81%D9%8A-%D9%85%D9%83%D8%AA%D8%A8%D8%A9-%D8%A7%D9%84%D9%85%D8%AD%D9%88%D9%84%D8%A7%D8%AA-transformers-r2509/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2025_02/Transformers_.png.2e6e058d3bbc3fc1d93e9047d60d026a.png" /></p>
<p>
	نوضح في هذا المقال بعض المشكلات الشائعة التي قد يواجهها المطورون أثناء تدريب أو استخدام نماذج مكتبة المحولات Transformers، ونشرح كيفية إيجاد حلول فعالة لها.
</p>

<h2 id="">
	مشكلة تشغيل المكتبة في بيئات محمية بجدار حماية
</h2>

<p>
	قد تكون بعض <a href="https://academy.hsoub.com/devops/servers/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D8%AE%D8%A7%D8%AF%D9%85-%D8%A7%D9%84%D9%88%D9%8A%D8%A8-r574/" rel="">الخوادم</a> أو الأجهزة التي تحتوي على وحدات معالجة الرسوميات GPU وتعمل في بيئات سحابية أو ضمن شبكات داخلية محمية <a href="https://academy.hsoub.com/devops/security/firewalls/" rel="">بجدار حماية Firewall</a> لا تسمح لها بالاتصال بالإنترنت، مما يؤدي إلى حدوث خطأ في الاتصال، عندها إذا حاول السكربت تنزيل أوزان النموذج أو مجموعات البيانات من الإنترنت عبر مكتبة Transformers، فسوف تتوقف عملية التنزيل وتظهر رسالة خطأ مشابهة للرسالة التالية:
</p>

<pre class="ipsCode">ValueError: Connection error, and we cannot find the requested files in the cached path.
Please try again or make sure your Internet connection is on.
</pre>

<p>
	لحل هذه المشكلة، نحتاج لتشغيل مكتبة المحولات Transformers في <span ipsnoautolink="true">وضع عدم الاتصال بالإنترنت</span> لتجنب حدوث هذا الخطأ.
</p>

<h2 id="cuda">
	نفاد ذاكرة CUDA
</h2>

<p>
	هو خطأ شائع يحدث عندما نحاول تشغيل نموذج <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AF%D9%84%D9%8A%D9%84-%D8%A7%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86-%D9%84%D9%81%D9%87%D9%85-%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-%D8%A7%D9%84%D8%AA%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%B9%D9%85%D9%8A%D9%82-r1422/" rel="">تعلم عميق</a> كبير على وحدة معالجة الرسوميات GPU لكن الذاكرة المتاحة لا تكفي لتحميل النموذج أو البيانات المطلوبة. فتدريب النماذج الكبيرة التي تحتوي على ملايين المعاملات أمر صعب بدون استخدام العتاد المناسب، وفي حال نفاد ذاكرة وحدة معالجة الرسوميات GPU سنحصل على رسالة خطأ كالتالي:
</p>

<pre class="ipsCode">CUDA out of memory. Tried to allocate 256.00 MiB (GPU 0; 11.17 GiB total capacity; 9.70 GiB already allocated; 179.81 MiB free; 9.85 GiB reserved in total by PyTorch)
</pre>

<p>
	وفيما يلي بعض الحلول المحتملة التي يمكننا تجربتها لتقليل استخدام الذاكرة:
</p>

<ul>
	<li>
		تقليل حجم الدفعة المتمثل بالقيمة <a href="https://huggingface.co/docs/transformers/main_classes/trainer#transformers.TrainingArguments.per_device_train_batch_size" rel="external nofollow"><code>per_device_train_batch_size</code></a> في الصنف <a href="https://huggingface.co/docs/transformers/v4.44.0/en/main_classes/trainer#transformers.TrainingArguments" rel="external nofollow">TrainingArguments</a>
	</li>
	<li>
		استخدام تقنية <a href="https://huggingface.co/docs/transformers/main_classes/trainer#transformers.TrainingArguments.gradient_accumulation_steps" rel="external nofollow"><code>gradient_accumulation_steps</code></a> في الصنف TrainingArguments لزيادة حجم الدفعة الإجمالي بفعالية، حيث تسمح لنا هذه التقنية باستخدام دفعات أصغر أثناء التدريب مع تراكم التدرجات عبر عدة دفعات
	</li>
</ul>

<p>
	<strong>ملاحظة</strong>: اطلع على <a href="https://huggingface.co/docs/transformers/performance" rel="external nofollow">دليل الأداء</a> على منصة Huggingface لمزيد من التفاصيل حول تقنيات توفير الذاكرة.
</p>

<h2 id="tensorflow">
	تعذر تحميل نموذج تنسرفلو المحفوظ
</h2>

<p>
	يحفظ التابع <a href="https://www.tensorflow.org/tutorials/keras/save_and_load#save_the_entire_model" rel="external nofollow"><code>model.save</code></a> في إطار عمل تنسرفلو <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D9%85%D9%86%D8%B5%D8%A9-%D8%AA%D9%86%D8%B3%D8%B1%D9%81%D9%84%D9%88-tensorflow-%D9%84%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-r2491/" rel="">TensorFlow</a> النموذج بالكامل متضمنًا البنية والأوزان وضبط التدريب في ملف واحد، ولكن قد نواجه خطأ عند محاولة تحميل ملف النموذج مرة أخرى لأن مكتبة المحولات Transformers قد لا تحمّل جميع العناصر المرتبطة بإطار عمل تنسرفلو TensorFlow في ملف النموذج. 
</p>

<p>
	يُوصَى باتباع الخطوات التالية لتجنب المشكلات المتعلقة بحفظ وتحميل نماذج TensorFlow:
</p>

<ul>
	<li>
		حفظ أوزان النموذج مع لاحقة الملف <code>h5</code> باستخدام <a href="https://www.tensorflow.org/tutorials/keras/save_and_load#save_the_entire_model" rel="external nofollow"><code>model.save_weights</code></a>، ثم إعادة تحميل النموذج باستخدام التابع <a href="https://huggingface.co/docs/transformers/v4.44.0/en/main_classes/model#transformers.TFPreTrainedModel.from_pretrained" rel="external nofollow"><code>from_pretrained()‎</code></a> كما يلي:
	</li>
</ul>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_9896_11" style=""><span class="pun">&gt;&gt;&gt;</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> transformers </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">TFPreTrainedModel</span><span class="pln">
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> tensorflow </span><span class="kwd">import</span><span class="pln"> keras

</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> model</span><span class="pun">.</span><span class="pln">save_weights</span><span class="pun">(</span><span class="str">"some_folder/tf_model.h5"</span><span class="pun">)</span><span class="pln">
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> model </span><span class="pun">=</span><span class="pln"> </span><span class="typ">TFPreTrainedModel</span><span class="pun">.</span><span class="pln">from_pretrained</span><span class="pun">(</span><span class="str">"some_folder"</span><span class="pun">)</span></pre>

<ul>
	<li>
		حفظ النموذج باستخدام <code>‎~TFPretrainedModel.save_pretrained</code> وتحميله مرة أخرى باستخدام التابع <a href="https://huggingface.co/docs/transformers/v4.44.0/en/main_classes/model#transformers.TFPreTrainedModel.from_pretrained" rel="external nofollow"><code>from_pretrained()‎</code></a>:
	</li>
</ul>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_9896_13" style=""><span class="pun">&gt;&gt;&gt;</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> transformers </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">TFPreTrainedModel</span><span class="pln">

</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> model</span><span class="pun">.</span><span class="pln">save_pretrained</span><span class="pun">(</span><span class="str">"path_to/model"</span><span class="pun">)</span><span class="pln">
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> model </span><span class="pun">=</span><span class="pln"> </span><span class="typ">TFPreTrainedModel</span><span class="pun">.</span><span class="pln">from_pretrained</span><span class="pun">(</span><span class="str">"path_to/model"</span><span class="pun">)</span></pre>

<p>
	هذا يجعل عملية الحفظ أكثر توافقًا مع مكتبة المحولات عند تحميل النماذج مرة أخرى.
</p>

<h2 id="importerror">
	خطأ الاستيراد ImportError
</h2>

<p>
	يوجد خطأ شائع آخر قد نواجهه وهو خطأ الاستيراد <code>ImportError</code> الذي يحدث عند محاولة استيراد مكتبة أو كائن معين، ولكن النظام لا يستطيع العثور عليه في المكان المحدد، ويقع هذا الخطأ خاصةً عند إصدار نموذج حديث ولكننا لا نزال نستخدم إصدار قديم من المكتبة لا يدعم ميزاته الجديدة.
</p>

<p>
	على سبيل المثال، إذا حاولنا استيراد الصنف <code>ImageGPTImageProcessor</code> من المكتبة <code>transformers</code> ولم يستطع النظام العثور عليه ستظهر رسالة خطأ كالتالي:
</p>

<pre class="ipsCode">ImportError: cannot import name 'ImageGPTImageProcessor' from 'transformers' (unknown location)
</pre>

<p>
	لحل هذا النوع من الأخطاء، علينا التأكد من تثبيت أحدث إصدار من مكتبة Transformers للوصول إلى أحدث النماذج من خلال الأمر التالي:
</p>

<pre class="ipsCode">pip install transformers --upgrade
</pre>

<h2 id="cuda-1">
	خطأ CUDA
</h2>

<p>
	يحدث هذا الخطأ عادةً أثناء تنفيذ العمليات الحسابية على وحدة معالجة الرسوميات GPU، وهو يتعلق بخطأ عام في الشيفرة البرمجية للجهاز ويعرض رسالة كالتالي:
</p>

<pre class="ipsCode">RuntimeError: CUDA error: device-side assert triggered
</pre>

<p>
	لحل هذا الخطأ علينا محاولة تشغيل الشيفرة البرمجية على وحدة المعالجة المركزية CPU أولًا للحصول على رسالة خطأ توصيفية واضحة، لذا نضيف متغير البيئة التالي لبداية شيفرتنا البرمجية للتبديل إلى وحدة المعالجة المركزية:
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_9896_17" style=""><span class="pun">&gt;&gt;&gt;</span><span class="pln"> </span><span class="kwd">import</span><span class="pln"> os

</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> os</span><span class="pun">.</span><span class="pln">environ</span><span class="pun">[</span><span class="str">"CUDA_VISIBLE_DEVICES"</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">""</span></pre>

<p>
	كما يوجد خيار آخر يساعدنا على تشخيص الحل، وهو الحصول على تعقّب أفضل أثناء استخدام وحدة معالجة الرسوميات GPU، لذا نضيف متغير البيئة التالي إلى بداية الشيفرة البرمجية لجعل التعقّب يشير بوضوح إلى مصدر الخطأ كالتالي:
</p>

<pre class="ipsCode">&gt;&gt;&gt; import os

&gt;&gt;&gt; os.environ["CUDA_LAUNCH_BLOCKING"] = "1"
</pre>

<p>
	سيتسبب هذا الأمر في تمكين الوضع المتزامن، حيث تُنفذ العمليات على GPU بشكل متسلسل خطوة بخطوة، بدلاً من العمل على التوازي وبهذا يمكننا تحديد موقع الخطأ بشكل أفضل.
</p>

<h2 id="paddingtokens">
	خرج خاطئ بسبب خطأ بالتعامل مع رموز الحشو Padding Tokens
</h2>

<p>
	عند تدريب النماذج على نصوص بأطوال مختلفة قد نحتاج لاستخدام رموز الحشو Padding Tokens وهي رموز ليس لها معنى في البيانات المدخلة ولكنها تُستخدم فقط لتعبئة السلاسل النصية بحيث يكون طولها متساوي، وتكون قيمة هذه الرموز عادةً صفرًا أو أي قيمة أخرى تحددها أثناء التدريب.
</p>

<p>
	في حال لم نتعامل مع هذه الرموز بشكل صحيح باستخدام ما يسمى قناع الانتباه attention mask والذي يحدد ما هي الرموز التي يجب على النموذج تجاهلها فقد نحصل على خرج غير صحيح، وبما أن مكتبة Transformers قد لا تقوم تلقائيًا بإنشاء قناع لبعض النماذج، لذا يجب إضافته يدويًا لتجنب أخطاء كهذه.
</p>

<p>
	على سبيل المثال قد يكون التمثيل الرقمي لدخل النموذج <code>hidden_state</code> غير صحيح إذا كانت معرّفات الدخل <code>input_ids</code> تتضمن رموز الحشو ولا تتجاهلها بشكل صحيح. لتوضيح ذلك، لنحمّل نموذجًا Model ومرمِّزًا Tokenizer، حيث يمكن الوصول إلى معرّف <code>pad_token_id</code> الخاص بالنموذج لمعرفة قيمته، قد تكون قيمة معرّف <code>pad_token_id</code> هي <code>None</code> لبعض النماذج وهذا يعني أن النموذج لا يستخدم رموز حشو، ولكن يمكن ضبطها يدويًا.
</p>

<p>
	لنستورد نموذج BERT المدرب مسبقًا والذي يحدد معرّف الحشو <code>pad_token_id</code> لتكون صفر <span>:</span>
</p>

<pre class="ipsCode prettyprint lang-py prettyprinted" id="ips_uid_9896_19" style=""><span class="pun">&gt;&gt;&gt;</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> transformers </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">AutoModelForSequenceClassification</span><span class="pln">
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> </span><span class="kwd">import</span><span class="pln"> torch

</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> model </span><span class="pun">=</span><span class="pln"> </span><span class="typ">AutoModelForSequenceClassification</span><span class="pun">.</span><span class="pln">from_pretrained</span><span class="pun">(</span><span class="str">"google-bert/bert-base-uncased"</span><span class="pun">)</span><span class="pln">
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> model</span><span class="pun">.</span><span class="pln">config</span><span class="pun">.</span><span class="pln">pad_token_id
</span><span class="lit">0</span></pre>

<p>
	سيكون الخرج الذي نحصل عليه للتسلسل الأول بدون تقنيع رموز الحشو كالتالي:
</p>

<pre class="ipsCode" id="ips_uid_9896_32">&gt;&gt;&gt; input_ids = torch.tensor([[7592, 2057, 2097, 2393, 9611, 2115], [7592, 0, 0, 0, 0, 0]])
&gt;&gt;&gt; output = model(input_ids)
&gt;&gt;&gt; print(output.logits)
tensor([[ 0.0082, -0.2307],
        [ 0.1317, -0.1683]], grad_fn=&lt;AddmmBackward0&gt;)</pre>

<p>
	ويكون الخرج الفعلي للتسلسل الثاني :
</p>

<pre class="ipsCode">&gt;&gt;&gt; input_ids = torch.tensor([[7592]])
&gt;&gt;&gt; output = model(input_ids)
&gt;&gt;&gt; print(output.logits)
tensor([[-0.1008, -0.4061]], grad_fn=&lt;AddmmBackward0&gt;)
</pre>

<p>
	يجب توفير قناع انتباه <code>attention_mask</code> لنموذجنا لتجاهل رموز الحشو وتجنب هذا الخطأ الخفي، فهو لا يعطينا رسالة خطأ صريحة، سيتطابق الآن خرج التسلسل الثاني مع الخرج الفعلي:
</p>

<pre class="ipsCode">&gt;&gt;&gt; attention_mask = torch.tensor([[1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0]])
&gt;&gt;&gt; output = model(input_ids, attention_mask=attention_mask)
&gt;&gt;&gt; print(output.logits)
tensor([[ 0.0082, -0.2307],
        [-0.1008, -0.4061]], grad_fn=&lt;AddmmBackward0&gt;)
</pre>

<p>
	لا تنشئ مكتبة المحولات Transformers قناع انتباه <code>attention_mask</code> تلقائيًا لرمز الحشو دائمًا وذلك لأن:
</p>

<ul>
	<li>
		بعض النماذج لا تحتوي على رمز حشو
	</li>
	<li>
		في بعض الحالات، نحتاج للاهتمام برموز الحشو وأخذها بعين الاعتبار أثناء المعالجة
	</li>
</ul>

<h2 id="-1">
	خطأ استخدام نموذج غير مناسب للمهمة
</h2>

<p>
	من المهم التأكد من استخدام النموذج المناسب لكل مهمة محددة، فإذا جربنا تحميل نموذج غير متوافق مع المهمة ستظهر رسالة خطأ مشابهة للتالي:
</p>

<pre class="ipsCode">ValueError: Unrecognized configuration class XYZ for this kind of AutoModel
</pre>

<p>
	يوصى باستخدام الصنف <a href="https://huggingface.co/docs/transformers/v4.44.0/en/model_doc/auto#transformers.AutoModel" rel="external nofollow">AutoModel</a> لتحميل نسخ مدربة مسبقًا من النماذج، حيث يساعد هذا الصنف في تحديد وتحميل البنية الصحيحة تلقائيًا من نقطة تحقق معينة بناءً على الضبط، فإذا ظهر الخطأ عند تحميل نموذج من نقطة تحقق، فهذا يعني أن الصنف التلقائي لم يتمكن من العثور على ربط صحيح بين الضبط ونوع النموذج الذي نحاول تحميله، ولا يدعم النموذج الذي نحاول تحميله المهمة المطلوبة.
</p>

<p>
	على سبيل المثال، سنرى هذا الخطأ إذا حاولنا استخدام نموذج GPT2 للإجابة على الأسئلة، لأن GPT2 ليس مخصصًا لهذه المهمة.
</p>

<pre class="ipsCode">&gt;&gt;&gt; from transformers import AutoProcessor, AutoModelForQuestionAnswering

&gt;&gt;&gt; processor = AutoProcessor.from_pretrained("openai-community/gpt2-medium")
&gt;&gt;&gt; model = AutoModelForQuestionAnswering.from_pretrained("openai-community/gpt2-medium")
ValueError: Unrecognized configuration class &lt;class 'transformers.models.gpt2.configuration_gpt2.GPT2Config'&gt; for this kind of AutoModel: AutoModelForQuestionAnswering.
Model type should be one of AlbertConfig, BartConfig, BertConfig, BigBirdConfig, BigBirdPegasusConfig, BloomConfig, ...
</pre>

<h2 id="-2">
	الخاتمة
</h2>

<p>
	حاولنا في هذا المقال تسليط الضوء على أبرز المشكلات التي قد نواجهها عند التعامل مع مكتبة المحوِّلات Transformers، قد لا يحتوي المقال على جميع المشكلات لكن في حال واجهتك مشكلة ما وصعب عليك حلها لا تتردد في كتابة مشكلتك في قسم <a href="https://academy.hsoub.com/questions/" rel="">الأسئلة والأجوبة</a> في أكاديمية حسوب حيث سيجيبك عدد من المختصين عليها بالتفصيل، كما يمكنك أيضًا طلب المساعدة في <a href="https://discuss.huggingface.co/" rel="external nofollow">منتديات منصة Huggingface </a>التي تتضمن فئات محددة يمكنك نشر سؤالك فيها مثل فئة <a href="https://discuss.huggingface.co/c/beginners/5" rel="external nofollow">المبتدئين</a> أو <a href="https://discuss.huggingface.co/c/transformers/9" rel="external nofollow">Transformers</a>، وتأكّد من كتابة وصف جيد لمشكلتك مع توفير بعض الأكواد البرمجية. وعند وجود خطأ يتعلق بالمكتبة Transformers بلغ عنها في مستودع المكتبة، وحاول تضمين أكبر قدر ممكن من المعلومات التي تصف الخطأ للمساعدة على معرفته بصورة أفضل وإصلاحه بسرعة وسهولة.
</p>

<p>
	ترجمة -وبتصرّف- للقسم <a href="https://huggingface.co/docs/transformers/troubleshooting" rel="external nofollow">Troubleshoot</a> من توثيقات Hugging Face.
</p>

<h2>
	اقرأ أيضًا
</h2>

<ul>
	<li>
		<span ipsnoautolink="true">المقال السابق: <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D9%82%D9%8A%D8%A7%D8%B3-%D8%A3%D8%AF%D8%A7%D8%A1-%D9%86%D9%85%D8%A7%D8%B0%D8%AC-%D8%A7%D9%84%D9%85%D8%AD%D9%88%D9%84%D8%A7%D8%AA-transformers-r2504/" rel="">قياس أداء نماذج المحولات Transformers</a></span>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-%D9%85%D9%83%D8%AA%D8%A8%D8%A9-%D8%A7%D9%84%D9%85%D8%AD%D9%88%D9%91%D9%84%D8%A7%D8%AA-transformers-r2352/" rel="">تثبيت مكتبة المحوّلات Transformers</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D9%82%D9%8A%D8%A7%D8%B3-%D8%A3%D8%AF%D8%A7%D8%A1-%D9%86%D9%85%D8%A7%D8%B0%D8%AC-%D8%A7%D9%84%D9%85%D8%AD%D9%88%D9%84%D8%A7%D8%AA-transformers-r2504/" rel="">قياس أداء نماذج المحولات Transformers</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D9%85%D9%86%D8%B5%D8%A9-%D8%AA%D9%86%D8%B3%D8%B1%D9%81%D9%84%D9%88-tensorflow-%D9%84%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-r2491/" rel="">تعرف على منصة تنسرفلو TensorFlow للذكاء الاصطناعي</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">2509</guid><pubDate>Wed, 12 Feb 2025 15:00:00 +0000</pubDate></item><item><title>&#x623;&#x641;&#x636;&#x644; &#x623;&#x62F;&#x648;&#x627;&#x62A; &#x627;&#x644;&#x630;&#x643;&#x627;&#x621; &#x627;&#x644;&#x627;&#x635;&#x637;&#x646;&#x627;&#x639;&#x64A; &#x648;&#x62A;&#x639;&#x644;&#x645; &#x627;&#x644;&#x622;&#x644;&#x629; &#x644;&#x644;&#x645;&#x637;&#x648;&#x631;&#x64A;&#x646; &#x627;&#x644;&#x645;&#x628;&#x62A;&#x62F;&#x626;&#x64A;&#x646;</title><link>https://academy.hsoub.com/programming/artificial-intelligence/%D8%A3%D9%81%D8%B6%D9%84-%D8%A3%D8%AF%D9%88%D8%A7%D8%AA-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-%D9%88%D8%AA%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%A2%D9%84%D8%A9-%D9%84%D9%84%D9%85%D8%B7%D9%88%D8%B1%D9%8A%D9%86-%D8%A7%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86-r2507/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2025_02/-------.png.de5927841ea35637129ee55147a57648.png" /></p>
<p>
	تتقدم التقنيات بسرعة في أيامنا، ويأتي الذكاء الاصطناعي وتعلم الآلة في طليعة هذه التقنيات، إذ تُطوَّر أدوات الذكاء الاصطناعي الجديدة بانتظام، وتغير من طريقة تنفيذنا للمهام في مختلف الصناعات، وتنوع الأساليب التي يتبعها المطورون لابتكار الحلول البرمجية، فالذكاء الاصطناعي وتعلم الآلة اليوم من الأدوات القوية التي يمكنها أن تساعدنا في حل المشكلات المختلفة، وتحسّن كفاءة عملنا، وتكشف عن قراءات مهمة من بيانات كان من المستحيل اكتشافها في السابق.
</p>

<p>
	لكن تنوّع الأدوات المتاحة وكثرتها قد تشعر المبتدئين بالارتباك، لذا سنساعدكم في مقالنا هذا على اختيار الأدوات المناسبة لتحسين مهارات الذكاء الاصطناعي المختلفة وتسريع تنفيذ الحلول العملية مثل إنشاء روبوتات الدردشة، وتطبيقات التعرف على الصور، وتحليل المشاعر، وأنظمة التوصية وغيرها من المهام. وقد اخترنا الأدوات التي سنذكرها أدناه بناءً على مميزاتها وبساطتها ووجود مجتمع داعم لها.
</p>

<h3 id="paperspace">
	أولًا: منصة Paperspace
</h3>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="167068" href="https://academy.hsoub.com/uploads/monthly_2025_02/001-paperspace-gradient.png.e756105a7e8b810db87bf10771fd99f8.png" rel=""><img alt="001 paperspace gradient" class="ipsImage ipsImage_thumbnailed" data-fileid="167068" data-ratio="55.00" data-unique="hanhiharz" style="width: 200px; height: auto;" width="200" src="https://academy.hsoub.com/uploads/monthly_2025_02/001-paperspace-gradient.png.e756105a7e8b810db87bf10771fd99f8.png"> </a>
</p>

<p>
	تُعدّ <a href="https://www.paperspace.com/" rel="external nofollow" target="_blank">Paperspace</a> منصة ممتازة لبدء رحلة تعلم <a href="https://academy.hsoub.com/artificial-intelligence/" rel="">الذكاء الاصطناعي</a> و<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%A2%D9%84%D8%A9/" rel="">تعلم الآلة</a>، فهي توفر وحدة معالجة رسومية سحابية cloud-based GPU منخفضة التكلفة وجاهزة للاستخدام، وبالتالي لن نحتاج لامتلاك جهاز حاسوب قوي لتطوير <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A3%D9%81%D9%83%D8%A7%D8%B1-%D9%85%D8%B4%D8%A7%D8%B1%D9%8A%D8%B9-%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-%D8%AA%D9%86%D8%A7%D8%B3%D8%A8-%D8%A7%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86-r2535/" rel="">مشاريع الذكاء الاصطناعي</a> والتعلم العميق  ولن نقلق بشأن توفير العتاد الملائم.
</p>

<p>
	كما يمكن الاستفادة من <a href="https://www.paperspace.com/artificial-intelligence" rel="external nofollow" target="_blank">Paperspace Gradient</a>، وهي مجموعة أدوات مصممة لتسريع العمل على المشاريع، وتشتمل على أداة قوية لإدارة المهام، ودعم الحاويات ومنصة <a href="https://academy.hsoub.com/programming/python/%D9%85%D8%AD%D8%B1%D8%B1-%D8%A3%D9%83%D9%88%D8%A7%D8%AF-%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86/#Jupyter-Notebook" rel="">Jupyter notebook</a> التفاعلية، وتتكامل مع العديد من لغات البرمجة، كما توفر منصة Paperspace إمكانية الوصول إلى <a href="https://academy.hsoub.com/programming/general/%D8%A5%D8%B7%D8%A7%D8%B1-%D8%B9%D9%85%D9%84-framework/" rel="">أطر عمل</a> التعلم العميق الشائعة مثل تنسرفلو <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D9%85%D9%86%D8%B5%D8%A9-%D8%AA%D9%86%D8%B3%D8%B1%D9%81%D9%84%D9%88-tensorflow-%D9%84%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-r2491/" rel="">TensorFlow</a> وباي تورش <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D8%A5%D8%B7%D8%A7%D8%B1-%D8%B9%D9%85%D9%84-%D8%A8%D8%A7%D9%8A-%D8%AA%D9%88%D8%B1%D8%B4-pytorch-%D9%88%D8%A3%D9%87%D9%85%D9%8A%D8%AA%D9%87-%D9%84%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-r2311/" rel="">PyTorch</a> مما يجعل التجريب والتطوير أمرًا سهلًا وسلسًا.
</p>

<p>
	ومع استحواذ شركة DigitalOcean مؤخرًا على منصة Paperspace يمكن للشركات نشر نماذج تعلم الآلة من خلال استخدام وحدات معالجة الرسوميات <a href="https://www.paperspace.com/nvidia-h100" rel="external nofollow" target="_blank">NVIDIA H100 GPUs</a> منخفضة التكلفة، والتي تعد من أقوى وحدات معالجة الرسوميات لتدريب نماذج الذكاء الاصطناعي وتعلم الآلة.
</p>

<h3 id="paperswithcode">
	ثانيًا: منصة Papers with code
</h3>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="167069" href="https://academy.hsoub.com/uploads/monthly_2025_02/002-paperswithcode.png.cb8edec1aa7f0a71dd069fe4ed1ad65c.png" rel=""><img alt="002 paperswithcode" class="ipsImage ipsImage_thumbnailed" data-fileid="167069" data-ratio="102.50" data-unique="elrtp1n7k" style="width: 200px; height: auto;" width="200" src="https://academy.hsoub.com/uploads/monthly_2025_02/002-paperswithcode.png.cb8edec1aa7f0a71dd069fe4ed1ad65c.png"> </a>
</p>

<p>
	توفر منصة <a href="https://paperswithcode.com/" rel="external nofollow" target="_blank">Papers with Code</a> أحدث الأوراق البحثية مع شيفرتها البرمجية على <a href="https://github.com/paperswithcode" rel="external nofollow" target="_blank">Github</a>، ومجموعات بياناتها <a href="https://paperswithcode.com/datasets" rel="external nofollow" target="_blank">datasets</a> التي ساهم بها  المجتمع. ولعل اسم المنصة يعطينا فكرة واضحة عن الغرض منها، وقد اكتسبت هذه المنصة مؤخرًا شعبية كبيرة، ووسعت نظامها لدعم الأبحاث في مجال تعلم الآلة ووفرت بيئة كاملة للمساهمات مفتوحة المصدر تسهل على <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D9%85%D9%86-%D9%87%D9%88-%D9%85%D9%87%D9%86%D8%AF%D8%B3-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-%D9%88%D9%85%D8%A7-%D8%A3%D8%A8%D8%B1%D8%B2-%D9%85%D9%87%D8%A7%D9%85%D9%87-r2319/" rel="">مهندسي الذكاء الاصطناعي</a>، و<a href="https://academy.hsoub.com/programming/general/%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA/" rel="">علماء البيانات</a>، والباحثين والطلاب تبادل الأفكار وتعزيز الخبرات التطويرية.
</p>

<p>
	تتمثل مهمة منصة Papers with Code في إنشاء مورد مجاني يحتوي على أوراق بحثية في مجال تعلم الآلة مع تضمين الأكواد البرمجية ومجموعات البيانات والدوال، وجداول التقييم المستخدمة مع كل بحث. ويمكن تصفح بعض نماذج <a href="https://paperswithcode.com/sota" rel="external nofollow" target="_blank">State of the Art models</a> للاطلاع على أحدث تطورات هذا المجال.
</p>

<h3 id="tensorflow">
	ثالثًا: مكتبة تنسرفلو TensorFlow
</h3>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="167070" href="https://academy.hsoub.com/uploads/monthly_2025_02/003-TensorFlow.png.7986c4cf8376f15b2c8696c947141918.png" rel=""><img alt="003 tensorflow" class="ipsImage ipsImage_thumbnailed" data-fileid="167070" data-ratio="55.50" data-unique="8tegwkdok" style="width: 200px; height: auto;" width="200" src="https://academy.hsoub.com/uploads/monthly_2025_02/003-TensorFlow.png.7986c4cf8376f15b2c8696c947141918.png"> </a>
</p>

<p>
	تُعدّ مكتبة تنسرفلو <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D9%85%D9%86%D8%B5%D8%A9-%D8%AA%D9%86%D8%B3%D8%B1%D9%81%D9%84%D9%88-tensorflow-%D9%84%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-r2491/" rel="">TensorFlow</a> التي طورتها Google، إحدى المكتبات مفتوحة المصدر الأكثر انتشارًا في مشاريع تعلم الآلة و<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AF%D9%84%D9%8A%D9%84-%D8%A7%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86-%D9%84%D9%81%D9%87%D9%85-%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-%D8%A7%D9%84%D8%AA%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%B9%D9%85%D9%8A%D9%82-r1422/" rel="">التعلم العميق</a>. فواجهتها سهلة الاستخدام تجعلها خيارًا مثاليًا للمستخدمين الجدد، كما تتميز مكتبة TensorFlow ببيئة واسعة الموارد، وتتضمن برامج تعليمية وتوثيقات ومجتمع داعم يضم الكثير من المستخدمين وهي خيار مثالي لبدء <a href="https://academy.hsoub.com/artificial-intelligence/" rel="">تعلم الذكاء الاصطناعي</a> وتعلم الآلة باستخدام واجهة برمجة التطبيقات عالية المستوى كيراس Keras، والتي دمجت مع تنسرفلو لتبسيط إنشاء الشبكات العصبية وتدريبها.
</p>

<h3 id="pytorch">
	رابعًا: إطار باي تورش PyTorch
</h3>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="167071" href="https://academy.hsoub.com/uploads/monthly_2025_02/004-Pytorch.png.714b8c3a7106a268c27baff88dc94c24.png" rel=""><img alt="004 pytorch" class="ipsImage ipsImage_thumbnailed" data-fileid="167071" data-ratio="65.00" data-unique="i1v3okt3w" style="width: 200px; height: auto;" width="200" src="https://academy.hsoub.com/uploads/monthly_2025_02/004-Pytorch.png.714b8c3a7106a268c27baff88dc94c24.png"> </a>
</p>

<p>
	يُعدّ باي تورش <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D8%A5%D8%B7%D8%A7%D8%B1-%D8%B9%D9%85%D9%84-%D8%A8%D8%A7%D9%8A-%D8%AA%D9%88%D8%B1%D8%B4-pytorch-%D9%88%D8%A3%D9%87%D9%85%D9%8A%D8%AA%D9%87-%D9%84%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-r2311/" rel="">PyTorch</a> من أطر العمل المفضلة بلغة البرمجة بايثون في مجال <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AF%D9%84%D9%8A%D9%84-%D8%A7%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86-%D9%84%D9%81%D9%87%D9%85-%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-%D8%A7%D9%84%D8%AA%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%B9%D9%85%D9%8A%D9%82-r1422/" rel="">التعلم العميق</a>، وهو يشتهر بمرونته وسهولة استخدامه ورسوماته البيانية الديناميكية وقدرته الممتازة على تصحيح الأخطاء. ويمتاز مجتمع باي تورش PyTorch بكونه نشطًا جدًا، ويقدم الكثير من الموارد والبرامج التعليمية لتسهيل تعلم مجال التعلم العميق.
</p>

<h3 id="scikitlearn">
	خامسًا: مكتبة ساي كيت ليرن Scikit-Learn
</h3>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="167072" href="https://academy.hsoub.com/uploads/monthly_2025_02/005-Scikit-Learn.png.98f34fc148f06d398479b9a273cfe40c.png" rel=""><img alt="005 scikit learn" class="ipsImage ipsImage_thumbnailed" data-fileid="167072" data-ratio="40.00" data-unique="i8tavmnip" style="width: 200px; height: auto;" width="200" src="https://academy.hsoub.com/uploads/monthly_2025_02/005-Scikit-Learn.thumb.png.77e6ac841c20d2cf49ba9cf362bc77c5.png"> </a>
</p>

<p>
	مكتبة ساي كيت ليرن <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D9%85%D9%83%D8%AA%D8%A8%D8%A9-scikit-learn-%D9%88%D8%A3%D9%87%D9%85-%D8%AE%D9%88%D8%A7%D8%B1%D8%B2%D9%85%D9%8A%D8%A7%D8%AA%D9%87%D8%A7-r2485/" rel="">Scikit-Learn</a> هي إحدى مكتبات لغة بايثون القوية المصممة بدقة لتطبيقات تعلم الآلة البسيطة والفعالة. وهي خيار ممتاز للمبتدئين وتوفر واجهة برمجة تطبيقات <a href="https://academy.hsoub.com/programming/general/%D9%85%D8%A7-%D9%87%D9%8A-%D8%A7%D9%84%D9%88%D8%A7%D8%AC%D9%87%D8%A9-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D8%A9-%D9%84%D9%84%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-api%D8%9F-r1512/" rel=""><abbr title="Application Programming Interface | واجهة برمجية"><abbr title="Application Programming Interface | واجهة برمجية">API</abbr></abbr></a> واضحة ومتسقة، كما تقدم مجموعة <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AE%D9%88%D8%A7%D8%B1%D8%B2%D9%85%D9%8A%D8%A7%D8%AA-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A/" rel="">خوارزميات ذكاء اصطناعي</a> قوية أبرزها خوارزميات التصنيف classification، وخوارزميات الانحدار أو التوقع regression، وخوارزميات العنقدة clustering وغيرها، ويمكن مطالعة <a href="https://scikit-learn.org/0.21/documentation.html" rel="external nofollow" target="_blank">التوثيقات الرسمية</a> والأمثلة التوضيحية للمكتبة لفهم هذه الخوارزميات وتنفيذها بفاعلية.
</p>

<h3 id="jupyternotebook">
	سادسًا: منصة Jupyter Notebook
</h3>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="167073" href="https://academy.hsoub.com/uploads/monthly_2025_02/006-Jupyter-Notebook.png.87021b53ad4ef819e5614d1762d66568.png" rel=""><img alt="006 jupyter notebook" class="ipsImage ipsImage_thumbnailed" data-fileid="167073" data-ratio="56.50" data-unique="5ypybt9yz" style="width: 200px; height: auto;" width="200" src="https://academy.hsoub.com/uploads/monthly_2025_02/006-Jupyter-Notebook.thumb.png.024d88dd9b85fa56c64908dae60d1536.png"> </a>
</p>

<p>
	منصة <a href="https://jupyter.org/" rel="external nofollow" target="_blank">Jupyter Notebook</a> هي بيئة تطوير تفاعلية تتيح إنشاء ونشر مستندات تجمع بين الشيفرة البرمجية المباشرة live code والمعادلات equations والتمثيل المرئي للبيانات visualization، ويمكنها التعامل مع لغات برمجية عدة، بما في ذلك لغة بايثون Python ولغة R ما يجعلها أداة مثالية لتجربة <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D8%A3%D9%87%D9%85-%D9%85%D8%B4%D8%A7%D8%B1%D9%8A%D8%B9-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-r2372/" rel="">مشاريع الذكاء الاصطناعي</a> وتعلم الآلة.
</p>

<h3 id="ibmwatsonstudio">
	سابعًا: منصة IBM Watson Studio
</h3>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="167074" href="https://academy.hsoub.com/uploads/monthly_2025_02/007-IBMWatson-Studio.png.04072e96e2e76db3c5994809968b82f9.png" rel=""><img alt="007 ibm watson studio" class="ipsImage ipsImage_thumbnailed" data-fileid="167074" data-ratio="35.50" data-unique="op7iogbac" style="width: 300px; height: auto;" width="200" src="https://academy.hsoub.com/uploads/monthly_2025_02/007-IBMWatson-Studio.thumb.png.5d65d54cc0aee72532bb1ebb4e11b820.png"> </a>
</p>

<p>
	منصة <a href="https://www.ibm.com/cloud/watson-studio" rel="external nofollow" target="_blank">IBM Watson Studio</a> هي منصة سحابية تقدم أدوات وخدمات متنوعة لمطوري الذكاء الاصطناعي وعلماء البيانات. فهي تبسِّط عملية تطوير تطبيقات وخدمات الذكاء الاصطناعي وتعلم الآلة من خلال تقديم توفير بيئات معّدة مسبقًا، وميزات تعاونية، وتمنح إمكانية الوصول لخدمات الذكاء الاصطناعي الخاصة بشركة IBM. وبالتالي فهي خيار مناسب للمبتدئين الراغبين في تجربة الذكاء الاصطناعي دون تعقيدات.
</p>

<h3 id="huggingface">
	ثامنًا: منصة Hugging Face
</h3>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="167075" href="https://academy.hsoub.com/uploads/monthly_2025_02/008-huggingface_logo.png.d53041719e2a56c2a547c06312b1fb8e.png" rel=""><img alt="008 huggingface logo" class="ipsImage ipsImage_thumbnailed" data-fileid="167075" data-ratio="96.00" data-unique="b3cbi09bx" style="width: 200px; height: auto;" width="200" src="https://academy.hsoub.com/uploads/monthly_2025_02/008-huggingface_logo.png.d53041719e2a56c2a547c06312b1fb8e.png"> </a>
</p>

<p>
	تقدم منصة <a href="https://huggingface.co/" rel="external nofollow" target="_blank">Hugging Face</a> مجموعة أدوات ذكاء اصطناعي متنوعة، بما في ذلك <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D9%85%D9%83%D8%AA%D8%A8%D8%A9-%D8%A7%D9%84%D9%85%D8%AD%D9%88%D9%91%D9%84%D8%A7%D8%AA-transformers-%D9%85%D9%86-%D9%85%D9%86%D8%B5%D8%A9-hugging-face-r2340/" rel="">مكتبة المحولات Transformers</a>، وهي مكتبة مخصصة تتضمن أحدث نماذج معالجة اللغات الطبيعية NLP وتتميز ببساطتها وسهولة استخدامها، مما يجعلها خيارًا مناسبًا للمبتدئين الذين يستكشفون طريقهم في مجال <a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A3%D8%B3%D8%A6%D9%84%D8%A9-%D9%88%D8%A5%D8%AC%D8%A7%D8%A8%D8%A7%D8%AA-%D8%AD%D9%88%D9%84-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-%D9%88%D9%85%D8%B9%D8%A7%D9%84%D8%AC%D8%A9-%D8%A7%D9%84%D9%84%D8%BA%D8%A9-%D8%A7%D9%84%D8%B7%D8%A8%D9%8A%D8%B9%D9%8A%D8%A9-nlp-r2496/" rel="">معالجة اللغة الطبيعية NLP</a>. كما أن الدعم الواسع الذي تقدمه منصة Hugging Face والنماذج الكثيرة المسبقة التدريب تسهّل عملية التعلم.
</p>

<h2 id="-1">
	نصائح لبدء تعلم الذكاء الاصطناعي وتعلم الآلة
</h2>

<p>
	بعد أن تعرّفنا على مجموعة منتقاة من أفضل أدوات الذكاء الاصطناعي وتعلم الآلة، سنقدم لك بعض النصائح لتحسين رحلتك في تعلم الذكاء الاصطناعي وتعلم الآلة كمبتدئ.
</p>

<h3>
	تعلم الأساسيات
</h3>

<p>
	يتوجب البدء بتعلم أساسيات الذكاء الاصطناعي وتعلم الآلة ودراسة مفاهيمه ومصطلحاته، بما في ذلك التعلم الخاضع للإشراف supervised learning، والتعلم غير الخاضع للإشراف unsupervised learning، والشبكات العصبية neural networks. هناك العديد من الدورات التدريبية والبرامج التعليمية المتاحة عبر الإنترنت والتي تساعد على تعلم هذه المفاهيم.
</p>

<div class="banner-container ipsBox ipsPadding">
	<div class="inner-banner-container">
		<p class="banner-heading">
			دورة الذكاء الاصطناعي
		</p>

		<p class="banner-subtitle">
			احترف برمجة الذكاء الاصطناعي AI وتحليل البيانات وتعلم كافة المعلومات التي تحتاجها لبناء نماذج ذكاء اصطناعي متخصصة.
		</p>

		<div>
			<a class="ipsButton ipsButton_large ipsButton_primary ipsButton_important" href="https://academy.hsoub.com/learn/artificial-intelligence" rel="">اشترك الآن</a>
		</div>
	</div>

	<div class="banner-img">
		<a href="https://academy.hsoub.com/learn/artificial-intelligence" rel=""><img alt="دورة الذكاء الاصطناعي AI" src="https://academy.hsoub.com/learn/assets/images/courses/artificial-intelligence.png"></a>
	</div>
</div>

<h3>
	التدريب العملي
</h3>

<p>
	إذا اكتفينا بدراسة مفاهيم الذكاء الاصطناعي وتعلم الآلة وركزنا فقط على الجانب النظري فلن نحرز أي تقدم، بل يتوجب علينا تطبيق كل ما نتعلمه وتنفيذ مشاريع صغيرة مع زيادة تعقيدها تدريجيًا. إذ يُعدّ التجريب مفتاحًا لفهم هذه التقنيات، وللاطلاع على مشاريع عديدة تناسب المبتدئين ننصحك بكتاب عشرة مشاريع عملية عن الذكاء الاصطناعي من أكاديمية حسوب.
</p>
<iframe allowfullscreen="" class="ipsEmbed_finishedLoading" data-controller="core.front.core.autosizeiframe" data-embedauthorid="3889" data-embedcontent="" data-embedid="embed6732902577" src="https://academy.hsoub.com/files/29-%D8%B9%D8%B4%D8%B1%D8%A9-%D9%85%D8%B4%D8%A7%D8%B1%D9%8A%D8%B9-%D8%B9%D9%85%D9%84%D9%8A%D8%A9-%D8%B9%D9%86-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A/?do=embed" style="overflow: hidden; height: 468px; max-width: 500px; margin:auto;"></iframe>

<h3>
	استكشاف مجموعات البيانات Datasets
</h3>

<p>
	لا يمكن تنفيذ مشاريع الذكاء الاصطناعي مجموعات البيانات فهي حجر الزاوية لبناء النماذج وبدونها لا يمكن للنموذج تعلم الأنماط أو اتخاذ القرارات، لذا سنحتاج للتعرف على مجموعات البيانات ذات الصلة باهتمامنا والاستفادة منها في مشاريعنا. على سبيل المثال تُعدّ منصة <a href="https://www.kaggle.com/" rel="external nofollow" target="_blank">Kaggle</a> كنزًا لمجموعات البيانات وهي تستضيف مسابقات عديدة في علوم البيانات من شأنها تعزيز فهمنا وصقل مهاراتنا.
</p>

<h3>
	الانضمام إلى المجتمعات التقنية
</h3>

<p>
	لا شك أن طرح الأسئلة والنقاش مع المطورين المختصين في مجتمعات الذكاء الاصطناعي وتعلم الآلة المتخصصة مثل PaperSpace و GitHub و Stack Overflow وReddit و<a href="https://io.hsoub.com/artificial_intelligence" rel="external" target="_blank">مجتمع حسوب IO</a> يساعدنا كثيرة في حل مشكلاتنا وتسريع <a href="https://academy.hsoub.com/questions/24984-%D9%83%D9%8A%D9%81-%D8%A7%D8%AA%D8%B9%D9%84%D9%85-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A/" rel="">رحلتنا التعليمية</a> وتعزيز خبراتنا في هذا التخصص.
</p>

<h2>
	الاطلاع على كل جديد
</h2>

<p>
	يتطور مجال الذكاء الاصطناعي وتعلم الآلة بسرعة ولذا لا بد من متابعة أحدث المستجدات عبر الإنترنت، وقراءة الأخبار والتقارير التقنية، والاطلاع على الأوراق البحثية للبقاء على اطلاع بأحدث التطورات في هذا المجال سريع التقادم.
</p>

<h2 id="-2">
	الخاتمة
</h2>

<p>
	يمكن أن تكون رحلتنا في مجال الذكاء الاصطناعي وتعلم الآلة كمبتدئين تجربة مثيرة ومثمرة إذا حرصنا على بناء أساس متين واستخدامنا الأدوات التي تسهل علينا التعلم والفهم. ولنتذكر أن التعلم عملية مستمرة، لذا علينا الحفاظ على حماسنا والتدرب بجد والاستمتاع بما نتعلمه وتطبيقه في مشاريع فعلية تجسد فائدة ما نتعلمه.
</p>

<p>
	ترجمة وبتصرّف للمقال <a href="https://www.digitalocean.com/community/tutorials/top-ai-and-ml-tools-for-new-developers-to-get-started#top-ai-and-ml-tools-for-new-developers-to-get-started-with" rel="external nofollow" target="_blank">Top AI and ML Tools for New Developers to Get Started With</a> لكاتبه Anish Singh Walia.
</p>

<h2>
	اقرأ أيضًا
</h2>

<ul>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D8%A3%D9%81%D8%B6%D9%84-%D8%AF%D9%88%D8%B1%D8%A7%D8%AA-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-r2332/" rel="">تعرف على أفضل دورات الذكاء الاصطناعي</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%AA%D8%B9%D8%B1%D9%81-%D8%B9%D9%84%D9%89-%D8%A3%D9%87%D9%85-%D9%83%D8%AA%D8%A8-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A-%D8%A7%D9%84%D9%85%D8%AC%D8%A7%D9%86%D9%8A%D8%A9-r2330/" rel="">تعرف على أهم كتب الذكاء الاصطناعي المجانية</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D9%85%D9%83%D8%AA%D8%A8%D8%A7%D8%AA-%D9%88%D8%A3%D8%B7%D8%B1-%D8%B9%D9%85%D9%84-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A/" rel="">مكتبات وأطر عمل الذكاء الاصطناعي: القوة الكامنة خلف الأنظمة الذكية</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D9%84%D8%BA%D8%A7%D8%AA-%D8%A8%D8%B1%D9%85%D8%AC%D8%A9-%D8%A7%D9%84%D8%B0%D9%83%D8%A7%D8%A1-%D8%A7%D9%84%D8%A7%D8%B5%D8%B7%D9%86%D8%A7%D8%B9%D9%8A/" rel="">لغات برمجة الذكاء الاصطناعي</a>
	</li>
	<li>
		<a href="https://academy.hsoub.com/programming/artificial-intelligence/%D8%A7%D9%83%D8%AA%D8%B4%D9%81-%D8%A8%D8%AF%D8%A7%D8%A6%D9%84-chatgpt-%D9%85%D9%81%D8%AA%D9%88%D8%AD%D8%A9-%D8%A7%D9%84%D9%85%D8%B5%D8%AF%D8%B1-r2488/" rel="">اكتشف بدائل ChatGPT مفتوحة المصدر</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">2507</guid><pubDate>Mon, 10 Feb 2025 15:07:00 +0000</pubDate></item></channel></rss>
