اذهب إلى المحتوى

ريم المهدي

الأعضاء
  • المساهمات

    127
  • تاريخ الانضمام

  • تاريخ آخر زيارة

كل منشورات العضو ريم المهدي

  1. 1- تستخدم with في لغة البرمجة بايثون لexception handling وذلك لتفادى توقف البرنامج عن العمل في حالة ظهور خطأ و يجعل ايضاً البرنامج أكثر مقروئية. و تستخدم غالباً للتحكم في حالة التعامل مع الذاكرة أو المعالج streaming لانها تتأكد من أن كل ما تم إستخدامه في البرنامج تم إغلاقه release resources. 2- مثال لبرنامج بإستخدام with و بدون إستخدامها في حالة فتح ملف للكتابة: file = open('myfile', 'w') file.write('hello world!') file.close() في البرنامج السابق فتحنا الملف المعرف بmyfile وقمنا بكتابة العبارة hello world! بداخله ثم قفلنا الملف، و الان يمكننا تنفيذ نفس المثال و لكن بإستخدام try except كالتالي: file = open('myfile', 'w') try: file.write('hello world!') except: file.close() والان يمكننا أن نستخدم with بالطريقة التالية: with open('myfile', 'w') as file: file.write('hello world!') لاحظ أننا لم نقم بعملية قفل الملف التي تتكفل بها عبارة with إذ أن الملف يتم قفله و تحرير كل مساحة تم إستخدامها في الذاكرة بعد الإستخدام مباشرة. أي عملية خطأ تحدث في عملية الكتابة تدخلنا في تنفيذ الجزء الخاص بexcept وقد لا يتم قفل الملف بصورة صحيحة و التي يعتمد عليها معظم التعديلات في الملف. 3- نعم لا مانع من إستخدام العبارة with لانها تؤدي نفس غرض try except لكن مع الميزات الإضافية التي تم ذكرها في 1 و 2. 4- لعلك لاحظت عزيزي @Fahmy Mostafa أن العبارة with تستخدم مع الstreaming، لذلك يمكنك التفكير في الأحوال التي تحتاج فيها إرسال و إستقبال البيانات إما محلياً بالتعامل مع ملفات موجودة بالجهاز كفتح ملف للقراءة و الكتابة، والتعامل مع قواعد البيانات كالمثال الموضح في شرح @عبدالمجيد الجرادي، أو إستقبال و إرسال بيانات خارجياً عن طريق الإنترنت مثلاً. يمكنك مراجعة موقع بايثون للتعرف على streams أكثر.
  2. يمكنك أيضاً طباعة المعلومات الخاصة بأي Class أو Object في بايثون بعدة طرق، منها إستخدام dir، vars أو بإستخدام inspect. في المثال التالي سنقوم بإستخدام dir و التي تطبع كل خصائص Object أو Class مرتبة في شكل قائمة، لاحظ مخرج المثال التالي: class Test: def __init__ (self): self.value = 3 test = Test() dir(test) بعد تعريف Test Class و بداخله دالة الإنشاء التي تعرف متغير قيمته 3، قمنا بتعريف Object وأسميناه test، طباعة dir(test) أنتجت كل خصائص الObject. أما ما قمت بطباعته هو فقط طباعة لObject أو Class نفسه ولا يقوم بعرض المحتويات، راجع المثال التالي: print(test) <__main__.Test object at 0x7f695dfe1e50> طباعة test object أعطانا نفس الناتج الذي حصلت عليه في عملية الطباعة المنفذة في برنامجك، والناتج عبارة عن نسخة (Object) معرف من Class المسمى Test و الموجود داخل main وهو عبارة عن base_program و الموجود في موقع الذاكرة 0x7f695dfe1e50.
  3. يمكنك ذلك بإستخدام ما يعرف بlist comprehension كما في البرنامج التالي: import numpy x = numpy.array([0,1,2]) y = numpy.array([3,4,5]) numpy.array([[x0, y0] for x0 in x for y0 in y]) لابد أنك لاحظت أن الناتج عبارة عن list والتي يمكن تحويلها لarray فيما بعد بإستخدام numpy.array كما أن sklearn لديها دالة مخصصة لهذا النوع من العمليات الرياضية و التي قد تستغرق وقت أطول بإستخدام بعض الدوال المطولة أو الحلقات التكرارية، والدالة تسمى cartesian: from sklearn.utils.extmath import cartesian cartesian((x,y)) الناتج هو عبارة عن حاصل الضرب الديكارتي.
  4. لابد أنك تعلم أن ensemble techniques عموماً تعطي نتائج أفضل من إستخدام مصنف واحد لانها تعطي نتائج أكثر دقة و تتم بإستخدام طريقتين إما Averaging إيجاد القيمة المتوسطة لمجموعة من المصنفات، أو بإستخدام boosting وهي الطريقة التي تتم فيها إستخدام مصنفات بصورة متتالية وكل منها يقوم بإنقاص الbais في النموذج النهائي. من خوارزميات التي تعتمد على القيمة المتوسطة Bagging methods and Random Forest. BaggingClassifier هي إحدي طرق ال bagging methods و التي تأخذ إما مصنف محدد من قبل المستخدم أو تقوم بإستخدام DecisionTreeClassifier كمصنف إفتراضي. لقد قام @Ali Haidar Ahmad بتغطية مثال BaggingClasifier بإستخدام المصنف الإفتراضي DecisionTreeClassifier و سأقوم بإعطاءك مثال بإستخدام SVC كمصنف و إنشاء البيانات عن طريق دالة make_classification التي تنشئ بيانات عشوائية لإستخدامها في عملية التصنيف: from sklearn.svm import SVC from sklearn.ensemble import BaggingClassifier from sklearn.datasets import make_classification X, y = make_classification(n_samples=100, n_features=4) clf = BaggingClassifier(base_estimator=SVC(),n_estimators=10, max_samples=100) clf = clf.fit(X, y) clf.predict([[0, 0, 0, 0]]) أول ثلاثة سطور عبارة عن عمليات إستدعاء للدوال التي سنقوم بإستخدامها، تليها عملية توليد بيانات بإستخدام make_classification والتي تقوم بإنشاء 100 صف لعدد أربعة أعمدة تمثل خصائص البيانات أو ما يسمي ب features وذلك عن طريق تحديد القيمة 4 ل n_features. و الان لنأتي لعملية إستخدام المصنف BaggingClassifier و التي تستقبل SVC كمصنف و تنشئ منه 10 مصنفات أخرى و التي تستخدم البيانات كاملة (max_samples=100) لعملية تدريب كل مصنف SVC النتيجة النهائية التي ينتجها كل مصنف تؤثر في القيمة النهائية لعملية الprediction. بعد ذلك نقوم بتدريب clf و هو المصنف الذي يحتوى على المصنفات العشرة، و أخيراً عملية التوقع للمدخل [0,0,0,0] والذي يقوم بإعطاء الناتج في شكل قيمة واحدة إما صفر أو واحد (لاننا عرفنا y كمتغير به 100 قيمة كلها عبارة عن أصفار أو أحاد حسب الصنف للقيم X المدخلة).
  5. يظهر هذا الخطأ عند التعامل مع الإصدارات القديمة لأحد ال modules و الذى يمكنك تفاديه بتحديث sk-learn و يمكن إجراءه حسب بيئة التشغيل التي تستخدمها، إن كنت تعمل على Google Colab يمكنك فقط إضافة (!) في بداية سطر التنفيذ التالي: pip install --upgrade scikit-learn أما إن كنت تستخدم Anaconda فيمكنك ذلك عن طريق command line بإستخدام نفس السطر أعلاه، في حال لم ينجح هذا في تفادي الخطأ، ما يمكنك فعله هو الحصول على الإصدار الأخير من كوندا أولا كالتالي: conda update conda ومن ثم تحديد البيئة التي تستخدمها (في حال كان عندك أكثر من واحدة لتفادي ظهور أي خطأ): conda activate environment_name و الان يمكنك تحديث sklearn كالتالي: conda update scikit-learn
  6. الطريقة الأخرى لتفادي الوقوع في مشكلة الdefault values لدوال حساب الدقة هو إستدعاء دالة classification_report التي تعمل مع التصنيف الثنائي و المتعدد، و الناتج من هذه الدالة يحتوي على القيم الممكنة الحساب في حالة دوال مثل f1 والتي تكون محسوبة لكل صنف على حدة، بالإضافة لعدد من مقاييس الدقة الأخرى مثل precision و recall و support. from sklearn.metrics import classification_report y_pred = t.predict(x_test) print(classification_report(y_test, y_pred)) في المثال إعلاه تم إستدعاء الدالة classification_report ومن ثم تعريف متغير y_pred ليحتوي على كل القيم المتوقعة من قبل النموذج، أخيراً تم إستدعاء الدالة classification_report والتي تخرج مقاييس الدقة السابق ذكرها بالإضافة لمتوسطات ال macro و weighted (مع العلم أن الmicro لا يظهر إلا في حالة التصنيف المتعدد). يمكنك أيضاً الحصول على قيمة f1 score عن طريق الدالة precision_recall_fscore_support والتي تنتج قيمة f1 score, precision, recall and support، راجع البرنامج التالي: from sklearn.metrics import precision_recall_fscore_support precision_recall_fscore_support(y_test, y_pred, average='macro') مع العلم أن القيمة المتوسطة المحسوبة في الدالة يجب أن تكون إحدي هذه القيم: micro, macro, none, weighted حسب ما هو موضح في الشرح أعلاه.
  7. لابد أن تعلم عزيزي أن هنالك طرق مختلفة للتعامل مع القيم المفقودة، منها طريقة تضمين أو توليد بيانات جديدة بإستخدام البيانات الموجودة أصلا. و يمكننا التعامل معها على مستوى عمود واحد (وهي الطريقة التي يوفرها SimpleImputer) فهو أحد طرق التضمين لمتغير واحد Univariate Imputation. يمكن ايضاً للدالة SimpleImputer التعامل مع البيانات الفئوية Categorical Variables، راجع المثال التالي والذي يقوم بإستبدال القيم غير المعرفة nan values بالقيمة الأكثر شيوعاً حسب ما هو موضح في الإستراتيجية strategy. import pandas as pd df = pd.DataFrame([["a", "x"], [np.nan, "y"], ["a", np.nan], ["b", "y"]], dtype="category") imp = SimpleImputer(strategy="most_frequent") print(imp.fit_transform(df)) يمكنك ملاحظة أن القيمة الأكثر شيوعاً في العمود الأول مختلفة عن العمود الثاني، و بالتالي في حال وجود أكثر من قيمة غير معرفة في عمودين مختلفين يتم التعامل مع كل واحد على حدة، فالأول يأخذ قيمة a و يبدلها معم كل قيمة غير معرفة ، أما الثاني فهو يأخذ القيمة y و يبدلها مع كل قيمة غير معرفة.
  8. إذا كانت عدد الأقسام n_splits المبرمجة في الكود أكبر من عدد البيانات الممرة samples لدالة KFold فإنه ينتج هذا النوع من الأخطاء، يمكننا التأكد من ذلك بالرجوع لبرنامج دالة التقسيم، نجد في أحد أجزاء البرنامج الشرط التالي: if self.n_splits > n_samples: raise ValueError( ("Cannot have number of splits n_splits={0} greater" " than the number of samples: {1}.").format(self.n_splits, n_samples)) و يجب عليك ايضاً الإنتباه لحالة تمرير قيمة 1 للتقسيم و التي تنتج الخطأ المعرف في الدالة ايضاً كالتالي: if n_folds <= 1: raise ValueError( "k-fold cross validation requires at least one" " train / test split by setting n_folds=2 or more," " got n_folds={0}.".format(n_folds)) يمكنك الرجوع لكامل البرنامج من هنا.
  9. لتعديل المتغيرات داخل الدوال أو أي موقع في البرنامج يجب أن نجعل المتغير مقروء لكل أجزاء البرنامج، يمكننا ذلك عن طريق إستخدام الكلمة المحجوزة global والتي نعرفها قبل تغيير قيمة x داخل الدالة f، لكن لنقوم بإستخدامها لا يجب تمريرها بالدالة فهي أصبحت مقروءة بصورة أتوماتيكية، راجع البرنامج التالي: def f(y): global x x = 1 y.append(3) print('In f():', x, y) x = 0 y = [0,1,2] print('Before:', x, y) f(y) print('After: ', x, y) لاحظ للتغيير بداخل الدالة f و جعل x متغير عام مرئي بداخل الدالة و يمكن الوصول لموقعه في الذاكرة و التعديل عليه، و من ثم إسناد قيمة x الجديدة، يجب أيضاً أن تنتبه لمسح x من إستدعاء الدالة f في السطر رقم 10. بالتالي النتيجة تصبح: Before: 0 [0, 1, 2] In f(): 1 [0, 1, 2, 3] After: 1 [0, 1, 2, 3]
  10. يمكننا عمل ذلك عن طريق إستخدام دالة combinations المتوفرة في مكتبة itertools والتي تقوم بإسترجاع كافة التوافيق المحتملة بكل الأطوال الممكنة للمتغير string، لاحظ المثال أدناه: from itertools import combinations string = "01234567890123456789" res = [string[x:y] for x, y in combinations( range(len(string) + 1), r = 2)] print(list(set([i for i in res if len(i)==10]))) بعد إستيراد الدالة، قمنا بتعريف المتغير string ومن ثم إيجاد كل التوافيق اللازمة عن طريق تقسيم النص إلى أجزاء بإستخدام x,y في كل مرة يأخذان قيمتين مختلفتين إبتداء من 0 للمتغير x و 1 للمتغير y، بذلك يمكننا تقسيم string و الحصول على القيم من موقع x و حتى الوصول إلى موقع y (موضح بعملية التقسيم او slicing للمتغير string بقيم [x:y]. أخيراً عملية الإختبار الشرطية لإستخراج النصوص التي يبلغ طولها 10 حروف، و من ثم تحويلها لمجموعة بإستخدام set للحصول على القيم بدون تكرار، و القيم المطبوعة تكون في شكل قائمة بإستخدام دالة list لتقوم بعملية التحويل (إختياري حسب ما يتطلب البرنامج). و بذلك يمكننا الحصول على كل الإحتمالات الممكنة و إستخراج 10 قيم مختلفة بدون تكرار أو إخفاء لقيمة 0 في بداية النص.
  11. حسب تعريف موقع sklearn للخوارزمية، عدد الصور samples يجب أن تساوى في كل من قيم y الممرة للنموذج و المدخل الأول ل X: بالتالي الخطأ هو عملية تحويل مصفوفات Y و Ytest إلى مصفوفات ذات بعدين بإستخدام to_categorical والتي تنتج (6000,10) و (1000,10) على التوالي و الصحيح تمريرها بنفس الشكل 6000,100. import numpy as np from sklearn.naive_bayes import MultinomialNB from tensorflow.keras.utils import to_categorical from tensorflow.keras.datasets import mnist from sklearn.metrics import accuracy_score (X, Y),(Xtest, Ytest) = mnist.load_data() # Y = to_categorical(Y) # Ytest = to_categorical(Ytest) X = np.reshape(X, [-1, X.shape[1]*X.shape[1]]) Xtest = np.reshape(Xtest, [-1, Xtest.shape[1]*Xtest.shape[1]]) M =MultinomialNB() M.fit(X, Y) لاحظ للبرنامج أعلاه، لقد قمت بإخفاء الدالة to_categorical لكل من Y و Ytest و لا تنسى إستبدال المتغير input_size في السطر رقم 10 إلى Xtest.shape[1]*Xtest.shape[1] للحصول على مصفوفة ذات بعدين بدلاً من ثلاثة أبعاد.
  12. يمكنك إنشاء بيانات عشوائية بإستخدام دالة make_classification أو بإستخدام دالة make_blobs، كل منهما تقوم بإنشاء البيانات و إسناد بيانات موزعة طبيعياً normally distributed data لصنف محدد. الفرق أن make_blobs محكمة أكثر في توزيع البيانات، و ذلك بالأخذ في الإعتبار القيمة المركزية و الإنحراف المعياري، لكن make_classification يمكنها إضافة بيانات مختلفة عن الأصناف noisy data بإستخدام طرق مثل تكرار بعض النقاط في البيانات redundancy. لقد قام @Ali Haidar Ahmad بتغطية الجزء المتعلق بmake_classification والان يمكننا أن نلقى النظر إلى make_blobs أيضاً: from sklearn.datasets import make_blobs X, y = make_blobs(n_samples=10, centers=3, n_features=2) بعد إستدعاء الدالة make_blobs من مكتبة sklearn.datasets الان يمكننا التعامل معها مباشرة بتحديد عدد النقاط المراد الحصول عليها n_samples و التصنيفات المراد الحصول عليها بعد إنشاء البيانات و ذلك عن طريق إعطاء قيمة للمتغير centers و أخيراً الصفات المراد الحصول عليها و هي تمثل عدد الأعمدة بالنسبة لمجموعة النقاط n_features. تطبيق المثال أعلاه ينتج مصفوفة ثنائية الأبعاد تمثل X وتحتوي على 10 صفوف و عمودين، و مصفوفة ذات بعد واحد تمثل y و تحتوي على 3 تصنيفات رئيسية ممثله ب 0,1,2.
  13. طريقة CountVectorizer هي إحدى الطرق التي تستخدم لتحويل البيانات النصية لأرقام لنتمكن من عملية تدريب النموذج، وهي أيضاً تعرف ب One-Hot Encoding إذ أنها تضع في كل مكان ظهور الكلمة في الجملة الرقم 1 و إن لم تظهر تحفظه ب0. تقوم هذه الطريقة بتمثيل الكلمات في شكل أرقام تشير إلى موقع الكلمة و بالتالي ينتج عنها مصفوفة الأرقام، هذه العملية تتم عن طريق إتباع الخطوات التالية: 1- تحويل الكلمات للحروف الصغيرة Lowercase 2- إستخدام utf-8 في التكويد 3- تقسيم البيانات إلى وحدات نصية أصغر tokenization 4- التعامل مع كل كلمة على حدة بإعتبارها token منفصل 5- تجاهل الكلمات المكونة من حرف واحد مثل الروابط (ك،و،ب) والان لزيادة دقة النموذج يمكننا ان نقوم بحذف كلمات التوقف و التي تزيد من عرض المصفوفة، تعقيد النموذج، أخذ مساحة كبيرة من الذاكرة، كما أنها تقلل من دقة النموذج. يمكننا حذف كلمات التوقف بثلاث طرق، الأولى تحديد الكلمات في النموذج كالتالي: vec = CountVectorizer(data,stop_words=["all","in","the","is","and"]) X = vec.fit_transform(data) لابد أنك لاحظت نقصان حجم المصفوفة بعد تطبيق الطريقة أعلاه، وذلك ناتج لحذف كلمات التوقف، أما إن أردت معرفة الكلمات المحذوفة مباشرة يمكنك تطبيق هذا السطر البرمجي: vec.stop_words الطريقة الثانية هي بإستخدام قائمة كلمات التحقق الموجودة في مكتبة sklearn (غير محبذة)، و الطريقة الأخيرة هي بتحديد قيمة صغرى minimum document frequency (min_df) أو كبرى maximum document frequency (max_df) لعدد مرات ظهور أو نسبة ظهور الكلمات في البيانات النصية، لاحظ للمثال التالي: vec = CountVectorizer(data, min_df=2) X = vec.fit_transform(data) و إذا كنت ترغب في نموذج ذو جودة أعلى يمكنك أيضاً أن تقوم بإنشاء طريقتك الخاصة في تقسيم النصوص إلى مجموعات أصغر tokens قبل تدريب النموذج، هذا بالإضافة لأي عمليات أخرى مثل إرجاع الكلمات لأصولها مثلا teaching, teacher لهما نفس الأصل و هو الفعل teach. كل هذه العمليات سابقة لتدريب نموذج التصنيف و تفيد في تركيز المعلومات و إنقاص حجم المصفوفة، بالإضافة لزيادة سرعة النموذج و نقص في مساحة الذاكرة.
  14. بالإضافة للإجابة أعلاه، يمكن أيضاً للبرنامج أن ينتج خطأ في الذاكرة إذا كانت البيانات ضخمة في هذه الحالة يمكننا تبديل ترتيب الخطوات في الكود أعلاه لحل المشكلة بتطبيق تحويل نوع البيانات، و من ثم قراءة القيم منها كالتالي: enc = tfidf.fit_transform(data['tweets'].astype('U').values) # أو enc = tfidf.fit_transform(data['tweets'].astype(str).values) كما يمكننا تطبيق دالة lambda لتحويل كل تويت ل numpy string و من ثم إستدعاء الدالة fit_transform كالتالي: enc = tfidf.fit_transform(data['tweets'].apply(lambda x: np.str_(x))) وهي أكثر كفاءة في إستخدام الذاكرة من الطريقة السابقة.
  15. البيانات النصية في بايثون تتم معالجتها قبل تمريرها لأي نموذج تدريبي، منها تحويل النص ألى كلمات و تسمي word tokenization و من ثم تحويل الكلمات إلى أرقام صحيحة او كسرية وهذه العملية تسمي feature extraction أو vectorization. هنالك 3 طرق للقيام بعملية تحويل الكلمات لأرقام، إحداها قام بشرحها @Ali Haidar Ahmadوهي تقوم بإعطاء كل كلمة قيمة رقمية score بناء أهميتها ومع الأخذ في لاعتبار عدد مرات ظهورها. سأقوم بشرح طريقتين أخرتين لتحويل الكلمات إلى قيم رقمية. الأولي: Count Vectorizer وهي من أسهل الطرق وذلك لأنها تقسم الملف النصي لمجموعة كلمات، وبه دالة fit_transform تقوم بتحديد الكلمات الموجودة في الملف النصي و عدد مرات ظهورها. في هذه الحالة يمكننا التطبيق على المثال اعلاه كالتالي: from sklearn.feature_extraction.text import CountVectorizer vectorizer = CountVectorizer() X = vectorizer.fit_transform(Data['Tweet']) بهذا تكون X عبارة عن 2D array الصفوف تمثل عدد الجمل او التويتات، و الأعمدة تمثل عدد الكلمات، مقابل كل كلمة موجودة في الجملة يوجد رقم 1 و 0 في حالة عدم وجودها، يمكنك التحقق بتحويل X الي مصفوفة عن طريق دالة ()X.toarray. و طبعاً في هذه الحالة يمكنك إستنتاج أن طريقة TfidfVectorizer أفضل من التعداد، لكن هل تنفع الطريقتين في حال وجود بيانات نصية كبيرة جداً، للإجابة على هذا السؤال يوجد طريقة أفضل و هي HashingVectorizer و التي تقوم بالمهمة في حال البيانات الضخمة بدون إستهلاك للذاكرة أو بطء ف عملية التحويل. طريقة HashingVectorizer تقوم بعملية تحويل النصوص إلى أرقام بإستخدام طريقة تطبيع عدد مرات ظهور الكلمة normalized token occurrences و بتطبيق عملية ترميز hashing محددة تتحول الكلمات إلى أرقام، بذلك يصبح من السهل تحويل النصوص الضخمة إلى أرقام لتسهل عملية تدريب النموذج و التنبؤ فيما بعد. راجع المثال التالي لتتعرف على كيفية التطبيق على بياناتك: from sklearn.feature_extraction.text import HashingVectorizer vectorizer = HashingVectorizer(n_features=100) X = vectorizer.transform(Data['Tweet']) لاحظ للمتغير n_feature وهو عبارة عن عدد الأعمدة الثابتة لكل التويتات في Data['Tweet'] وهي تمثل ال hash functions، القيم الناتجة من تحويل X إلى مصفوفة و طبعاتها تكون محصورة بين 1و -1 و التي يمكن تحويلها لأرقام صحيحة بتغيير القيم الإبتدائية للدالة HashingVectorizer.
  16. الطريقة الأخرى لحل هذه المشكلة هي تمرير القيم الإبتدائية في دالة الإنشاء constructor function و في حال تم إدخال بيانات عند إنشاء object من person class ستتم أخذ القيم الممررة و إسنادها مباشرة للمتغيرات، و في حال كانت لا توجد بيانات سيتم إدراج الأصفار و القيم النصية الفارغة كقيم إبتدائية. class person: def __init__(self, per_name="", per_age=0, per_address="", per_id=0): self.per_name = per_name self.per_age = per_age self.per_address = per_address self.per_id = per_id والان يمكننا إنشاء object من class person لنا الخيار في تمرير بيانات كما في المثال التالي: p = person("test",20,"test",1234) print(p.per_name,p.per_age,p.per_address,p.per_id) # test 20 test 1234 و إما أن نقوم بإنشاء object بدون أن نمرر أي قيم و في هذه الحالة سيأخذ القيم الإبتدائية في كل الأحوال: p = person() print(p.per_name,p.per_age,p.per_address,p.per_id) # 0 0 القيم المطبوعة في الفراغ لكل من متغيرات الإسم و العنوان و أصفار للرقم الشخصي و العمر. لاحظ قيامي بتحويل علامات الطرح في أسماء المتغيرات لشرطة أفقية (_) و ذلك للإلتزام بشروط التسمية في لغة بايثون. يجب أن تنتبه انه لا يوجد شرط في نوع البيانات المدخلة و الذي يجب أن تطبقه لتفادي إدخال اي بيانات نصية محل بيانات رقمية والعكس.
  17. لقد قمت بإجابة سؤال مطابق لهذا و ستجدي كافة التفاصيل على الرابط: مشكلة عند استخدام pattern - بايثون
  18. يعرف ايضاً F1 Score ب balanced F-score أو F-measure و يستخدم في حالة مشاكل تصنيف البيانات لقياس دقة و كفاءة النموذج و يعتبر أكثر شمولاً من Precision و Recall لأنهما قد يقدمان نتائج غير دقيقة، مثلاً في حالة عدم التوزيع المتساوي للأصناف Imbalanced classes وهي حالة معظم التصنفيات الحقيقية على أرض الواقع. from sklearn.metrics import f1_score #sklearn تحميل الدالة من مكتبة #تجهيز البيانات، تقسيمهاو تدريب النموذج بالإضافة بإختباره f1_score(y_true, y_pred) #تمرير القيم الناتجة من النموذج و الحقيقية للدالة يمكنك إستخدام F1 score دون تمرير parameter في حال كان التصنيف لصنفين فقط binary is the default ولكن في حال كان التصنيف يتضمن أكثر من صنفين يمكننا أن نمرر إحدى القيم لحساب المتوسط: {‘micro’, ‘macro’, ‘samples’,’ weighted’, ‘binary’} يمكنك الرجوع للمثال السابق. كما يمكننا أن نقوم بإستخدام دالة precision_recall_fscore_support والتي ترجع قيم كل من precision، recall،F1score بالإضافة لمعامل رابع يسمي support، القيمة الثالثة الراجعة من الدالة هي قيمة F1 score، راجع المثال التالي: precision_recall_fscore_support(y_true, y_pred, average='macro') لاحظ انه في هذا المثال حددنا نوع F1 score و هو عبارة عن macro. والتي تعني حساب الدقة لكل صنف على حدة و من ثم إيجاد القيمة المتوسطة لها، وهي طريقة لا تأخذ في الحسبان التوزيع غير المتساوي للأصناف. لا تنسى أن تقوم بإستدعاء الدالة عن طريق مكتبة sklearn كالتالي: from sklearn.metrics import precision_recall_fscore_support الطريقة الأخرى للحصول على قيم الF1 score هي بإستخدام دالة classification_report و التي تقوم بإستخراج نتائج الدقة للنموذج في شكل جدول متكامل و المحتوية على F1 score. راجع المثال التالي: from sklearn.metrics import classification_report print(classification_report(y_true, y_pred, labels=mylabels)) الدالة تستقبل قيم النموذج، القيم الحقيقية المتوقع التنبؤ بها، و اخيراً التصنفيات، هذه الدالة تعطي ناتج F1 score في شكل مفصل و محتوي على الدقة محسوبة بثلاث طرق macro، micro، weighted.
  19. لابد أنك تعلم ان من تقنيات تعلم الاَلة التجميع clustering و هو المستخدم بصورة موسعة في عدد من المجالات مثل تقسيم العملاء Customer segmentation، توصيات منتجات أمازون Amazon’s recommendation system، الرابط بين هذه البيانات الضخمة هو غياب العناوين labels، وهنا تأتي خوارزميات عدة مثل K-Means و DBSCAN لتحل المشكلة بالإعتماد إما خصائص البيانات مثل كثافتها أو المسافة بينها و غيرها. ما يميز DBSCAN عن خورازميات اخرى مثل K-Means و Hierarchical Clustering هو عجزهم عن إنشاء مجموعات تعتمد على شكل البيانات إذا قمنا بتمثيلها في مخطط أبعاد dimensional diagram. بالنظر للصورة أعلاه ترى كيف تقوم الخوارزميات بتقسيم البيانات إلى مجموعات مختلفة، و الأن لنرى كيف تقوم خوارزمية DBSCAN بتقسيم البيانات. لاحظ أن الخوارزمية أخذت في الإعتبار القيم الشاذة أو المتطرفة بوضعها في مجموعة مختلفة، حيث انها لا تنتمي إلى أي من المجموعات الأخرى. لعلك لاحظت من الإسم أن DBSCAN تعتمد على كثافة البيانات وهي بعكس K-Means لا تحتاج لتعريف مسبق بعدد المجموعات المراد أخذها في الإعتبار للقيام بعملية التقسيم.
  20. يمكنك أيضاً، @Meezo ML، حفظ النموذج بعد تدريبه على البيانات بإستخدام عملية pickling والتي تحول اي Object في بايثون إلى مجموعة من الBytes المهيكلة، لاحقاً يتم تحويل هذه البيانات المخزنة في شكل Bytes إلى نموذج مرة أخرى. عملية حفظ النموذج model تتم كالتالي: filename = 'model.sav' pickle.dump(model, open(filename, 'wb')) حيث ان model في البرنامج السابق يرمز للنموذج المدرب، و الدالة dump هي المسؤولة عن تحويل النموذج الى شكل بيانات قابلة للتخزين و هي تأخذ 3 قيم، الأولى النموذج المراد حفظه (أو اي Object اخر في بايثون)، ثم إسم الملف الذي تريد التخزين فيه (بالإضافة للمسار إن كنت تريد حفظه في مجلد غير المجلد الذي تطبق فيه البرنامج)، متبوعاً بطريقة الكتابة في الملف وهي في هذه الحالة wb وهي إختصار ل write binary والتي تعني فتح الملف و الكتابة فيه بBytes. لا تنسى أن تقوم بعملية تحميل مكتبة pickle في البداية كالتالي: import pickle و الان لنقوم بعملية تحميل النموذج مرة أخرى يمكننا ذلك بإستخدام دالة load المتوفرة في مكتبة pickle أيضاً كالتالي: loaded_model = pickle.load(open(filename, 'rb')) لقد قمنا بإستخدام طريقة rb لقراءة الملف المحفوظ و هي إختصار ل read bytes. بذلك يكون النموذج تم تحميله في ال Object المسمى ب loaded_model، يمكننا إستخدام loaded_model في اي عمليات تقييم أخرى قد نحتاجها.
  21. الخطأ في برنامج يا @Alaa Jamal هو انه يقوم بإستخراج أي قيمة بعد علامة الدولار، و الصحيح أن يقوم بإستخراج القيم الرقمية فقط بعد العلامة. الأن بعد أن عرفنا الخطأ يمكننا بتعديل برنامج Ali بشكل بسيط ليخرج كافة الإحتمالات الممكنة من أعداد صحيحة و أرقام كسرية أيضاً: re.findall(r"\$[+-]? *(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?", "I bought milk for $1.50 only") حيث أن المدخل هو مثالنا المحتوي على قيمة كسرية و بإستخدام دالة findall و وضع كل الشروط لوجود أرقام صحيحة مثل $59 او ارقام كسرية مثل $0.587 أو $4.4 يمكننا الحصول على الإجابة الصحيحة.
  22. بمراجعة المطلوب في السؤال، أجد انه لا يشترط إدخال قيمة رقمية فقط كما قمت بحله، الحل المذكور في إجابتك صحيح لكن فقط في حال كانت القيمة المدخلة من قبل المستخدم رقمية فقط، أما إن اردنا إدخال كل الإحتمالات فيجب علينا أن نستخدم دالة لفرز الأرقام من المدخل اولاً ثم تطبيق الشرط كالتالي: import re text = input('enter the text') expp = "056\d{7}" newtext = re.findall(r'\d+', text) newtext لقد قمت بحذف شرطية إبتداء النص ب 056 بحذف ^ و ايضاً حذف شرطية الإنتهاء بالسبعة أرقام كاملة و ذلك بحذف $ من نهاية النص، بذلك نتفادي اي خطأ قابل حدوثه من قبل المستخدم، شرطنا الوحيد وجود 056 في مجموعة الأرقام التي قمنا بالحصول عليها بتطبيق دالة findall و بإستخدام شرط إستخراج القيم الرقمية \d ومن ثم نقوم بإدارج الشرط الثاني لفلترة الأرقام و إستخراج المطابق للمطلوب في الأرقام الوطنية كالتالي: exp = re.findall(expp, newtext[0]) print(exp) و الان إن قمنا بإختبار البرنامج بإدخال نفس النص "Hello my Jawwal number is 0560000001 " سنحصل على الرقم 0560000001. يمكننا ملاحظة أننا قمنا بإستدعاء اول قيمة في النص الجديد newtext[0] و ذلك لأن القيمة الراجعة عبارة عن قائمة محتوية على النص. والأن السؤال يتطلب إنشاء دالة، بذلك يمكننا إنشاء الدالة بإستخدام الدوال اعلاه فيصبح البرنامج كاملاً كالتالي: def nationalNo(text, exp = '05[6|9]\d{7}'): return re.findall(expp, (re.findall(r'\d+', text))[0]) nationalNo('Hello my Jawwal number is 0560000001')
  23. لكن ماذا سيحدث إن كانت الكلمات تحتوي على أرقام؟ يمكننا تفادي الأخطاء الناتجة عن وجود أرقام بتحويل القيم أولاً إلى نص str و من ثم تطبيق نستخدم join مثل حل Ali أو ان نقوم بإستخدام طريقة الدمج كما وضح محمد، يمكنك أيضاً مراجعة الحل التالي بإستخدام join مع طريقة list comprehension: listToStr = ' '.join([str(elem) for elem in s]) لاحظ أننا في هذه الطريقة قمنا بتحويل كل كلمة أو رقم لقيمة نصية أولاً و من ثم طبقنا عملية الدمج، يمكننا ايضاً تحويل القيم إلى نصية عن طريق إستخدام map كالتالي: listToStr = ' '.join(map(str, s)) والان إن قمنا بتطبيق هذه الدوال على المثال: s = ['I', 'was', 'born', 'in', 2020] سنحصل على I was born in 2020
  24. لاحظ أن بعض الدوال لا يمكنها إستخراج القيم السالبة و الأرقام المكتوبة بصورة علمية scientific writing مثل 0.000000123 والتي يمكن كتابتها في بايثون بصيغة 1.23E-7، للحصول على دالة أشمل يمكننا إستخراج الأرقام و العلامات مثل - (موجودة في الأرقام السالبة و الأرقام العلمية) من النص و تخطي أي قيم حرفية كالتالي: newstr = ''.join((ch if ch in '0123456789.-e' else ' ') for ch in s) بذلك نحصل على كل الأرقام مجمعة (نتيجة لإتخدام الدالة join) في شكل نص و بوجود فراغات ( الحروف التي تم تخطيها من قبل الشرط if) و نقوم بتحويل النص المحتوي على كل الأرقام الممكنة إلى قائمة بإستخدام split، كما يمكننا تحويل كل الأرقام إلى قيم كسرية (إختياري) كالتالي: listOfNumbers = [float(i) for i in newstr.split()] بذلك تكون كل الأرقام مخزنة في المتغير listOfNumbers.
×
×
  • أضف...