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

ريم المهدي

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

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

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

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

  1. في البداية قبل تنفيذ عملية التصنيف يمكنك مراجعة شكل البيانات الداخلة و خصوصاً y لانها التي تستخدم في عملية المقارنة بين القيم الحقيقية و المتوقعة من قبل النموذج، بذلك طريقة حساب الدقة للنموذج. لاحظ في البيانات المدخلة أن y لديها 45 صنف مختلف: np.array(np.unique(train_labels, return_counts=True)).T هنالك دالة OneHotEncoder التي تحول القيم الداخلة من أرقام الى التمثيل المقابل لها بإستخدام المصفوفات، راجع البرنامج التالي وهو عبارة عن تحويل 3 قيم فقط كمثال: import pandas as pd y = np.array([0,1,2]).reshape(-1,1) #تعريف القيم from sklearn.preprocessing import OneHotEncoder #مناداة OneHotEncoder من الموديول enc = OneHotEncoder(handle_unknown='ignore') # التعريف enc.fit_transform(y).toarray() #تطبيق عملية التحويل فبالتالي التعديل في برنامج يكون كالتالي: import numpy as np from keras import models from keras import layers from keras.datasets import reuters from sklearn.preprocessing import OneHotEncoder (train_data, train_labels), (test_data, test_labels) = reuters.load_data(num_words=1000) def vectorize_sequences(sequences, dimension=1000): results = np.zeros((len(sequences), dimension)) for i, sequence in enumerate(sequences): results[i, sequence] = 1. return results x_train = vectorize_sequences(train_data) x_test = vectorize_sequences(test_data) enc = OneHotEncoder(handle_unknown='ignore') train_labels1 = enc.fit_transform(train_labels.reshape(-1,1)).toarray() test_labels1 = enc.fit_transform(test_labels.reshape(-1,1)).toarray() model = models.Sequential() model.add(layers.Dense(64, activation='relu', input_shape=(1000,))) model.add(layers.Dense(64, activation='relu')) model.add(layers.Dense(46, activation='softmax')) model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy']) history = model.fit(x_train, train_labels1, epochs=8, batch_size=512, validation_split=0.2)
  2. يمكن حل هذه المشكلة بإستخدام الدالة product في المصفوفات و دالة itertools التي تسمح بالمرور على عناصر المصفوفات واحد تلو الأخر: import numpy as np #إنشاء المصفوفات x = np.array([0, 1, 2]) y = np.array([3, 4, 5]) # إنشاء مصفوفة فارغة لإضافة الناتج فيها لاحقا all = [] # إستخدام الحلقات مع دالة الضرب لإيجاد الناتج و إضافته للمصفوفة for r in itertools.product(x, y): all.append([r[0],r[1]]) np.array(all)
  3. بالإضافة إلى ما ذكره @Ali Haidar Ahmad في إجابته يمكننا أيضاً أن نقول هنالك فوارق أخرى بين numpy arrays & lists: المصفوفات لها طول ثابت على عكس القوائم، و في حالة الإضافة للمصفوفة يتم مسح الأصلية و إنشاء واحدة أخرى بنفس الطول + 1. العناصر في القوائم يمكن أن تكون من أنواع مختلفة و لكن العناصر في المصفوفات تكون من نفس النوع، يمكن أن تحتوي عناصر مختلفة لكن لن يتم تنفيذ العمليات الحسابية مثلاً في هذه الحالة. يمكن للمصفوفات التعامل مع العمليات الحسابية و الإحصائية، و العمليات الجبرية و البحث على البيانات الضخمة بصورة أكثر كفاءة و أقل كود. from numpy import arange from timeit import Timer #تحديد عدد البيانات المدخلة Nelements = 10000 #إنشاء قائمة و مصفوفة بنفس الطول x = arange(Nelements) y = range(Nelements) #تعريف دالة الجمع لإستخدامها في قياس المدة الزمنية t_numpy = Timer("x.sum()", "from __main__ import x") t_list = Timer("sum(y)", "from __main__ import y") #طباعة الزمن الناتج من تنفيذ العملية print("numpy: %.3e" % (t_numpy.timeit(Nelements)/Nelements,)) print("list: %.3e" % (t_list.timeit(Nelements)/Nelements,)) البرنامج السابق عبارة عن نموذج يوضح الفرق في سرعة التعامل مع كل من المصفوفات و القوائم التي تصل إلى فرق 10 أضعاف السرعة للمصفوفات مقابل القوائم. numpy: 9.865e-06 list: 1.839e-04
  4. هل قمت بالمحاولة؟ يمكنك مشاركته هنا و إرسال أي أخطاء قد تواجهك. كبداية يمكنك إستخدام حلقة for لتمكين المستخدم من إدخال 10 أرقام، و الدالة input لقراءة الرقم.
  5. إن كنت تعمل على Anaconda فهي تأتي ب (version 1.15.4) numpy مثبت، لذا يمكنك عمل upgrade لها كالتالي: pip install numpy --upgrade و يمكنك أيضاً التأكد من أنك قمت بتثبيت numpy كما ذكر @Ali Haidar Ahmadبإستخدام conda إن كنت تعمل على conda environment. conda install -c anaconda numpy
  6. هي أحد الخوارزميات التي تقوم بإختيار بعض من التباديل الممكنة لمجموعة بيانات و تقسيمها لعمليات تدريب و إختبار النموذج، بذلك فهي أحد خوارزميات الCross_validation. تعتمد shufflesplit على 4 مدخلات تتحكم في البيانات المقسمة: n_splits عدد التقسيمات test_size نسبة بيانات الإختبار (0.1%) كقيمة إفتراضية إذا لم يتم تحديدها. train_size باقي نسبة الإختبار. random_state قيمة رقمية للتحكم في إنتاج نفس البيانات كل مرة. import numpy as np from sklearn.model_selection import ShuffleSplit X = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [3, 4], [5, 6]]) y = np.array([1, 2, 1, 2, 1, 2]) rs = ShuffleSplit(n_splits=2, test_size=.25, random_state=0) #rs = ShuffleSplit(n_splits=200, test_size=.25, random_state=0) #rs = ShuffleSplit(n_splits=5, train_size=0.5, test_size=.75,random_state=0) for train_index, test_index in rs.split(X): print("TRAIN:", train_index, "TEST:", test_index) لاحظ البرنامج أعلاه و الذي يقوم بتقسيم البيانات بإستخدام sufflesplit و إخراج عينتين تمثلان مؤشرات البيانات لكل من التدريب و الإختبار مقسمة بنسبة 75% و 25% على التوالي، لاحظ أن ربع البيانات المدخلة الكلية 1.5 من أصل 6 عينات، لكن تم إخراج مؤشرين. TRAIN: [1 3 0 4] TEST: [5 2] TRAIN: [4 0 2 5] TEST: [1 3] يمكنك أيضاً تفعيل السطر 6 و 7 لترى الناتج، لابد أن تعلم أن shufflesplit تعطي الخطأ التالي في حال كان مجموع نسب التدريب و الإختبار أعلى من 1. ValueError: The sum of test_size and train_size = 1.25, should be in the (0, 1) range. Reduce test_size and/or train_size.
  7. خوارزمية Stochastic Gradient Descent(SGD) هو أحد خوارزميات الoptimization التي لا تتبع لنوع معين من خوارزميات الذكاء الإصطناعي، و هي طريقة لتدريب البيانات بإستخدام convex loss function. يمكن إستخدام SDG لعمليات classifiaction, regression بإستخدام SGDClassifier, SGDRegressor على التوالي. import numpy as np from sklearn.linear_model import SGDClassifier X = np.array([[-1, -1], [-2, -1], [1, 1], [2, 1]]) Y = np.array([1, 1, 2, 2]) clf = SGDClassifier() clf.fit(X, Y) print(clf.predict([[-0.8, -1]])) البرنامج أعلاه عبارة عن مثال لإستخدام SGDClassifier لتدريب 4 مدخلات و التي تحتوي على 2features. في البرنامج أدناه، SGDRegressor تستقبل عدد 10 عينات لكل منها 5features للقيام بعملية التدريب. import numpy as np from sklearn.linear_model import SGDRegressor n_samples, n_features = 10, 5 y = np.random.randn(n_samples) X = np.random.randn(n_samples, n_features) reg = SGDRegressor() reg.fit(X, y) وهي عبارة عن iterative algorithm حيث أن عملية التدريب تتطلب مجموعة خطوات لتزيد من دقة النموذج، حيث أن كل خطوة تنبؤ لقيمة عينة تتم بإستخدام parameters ثم مقارنة القيم المتوقعة مع الحقيقية و حساب الخطأ و من ثم تعديل الparameters، هنالك طرق مختلفة للتعديل لكن أشهرها back-propagation والتي تستخدم في artificial neural networks. والان مجموعة القيم التي تؤخذ في المرة الواحدة تسمى batch و الان لنعرف الفروقات بين batch, stochastic, mini-batch: Batch Gradient Descent : حجم الbatch = عدد العينات Stochastic Gradient Descent : حجم الbatch = عينة واحدة Mini-Batch Gradient Descent : عينة واحدة < حجم الbatch < حجم العينات إستخدام SGDClassifier, SGDRegressor بدون تغيير في parameters عبارة عن SDG و الذي يتم بنداء عينة كل مرة لتحسين النموذج، لكن لتحديد batch أو mini-batch يمكننا إستخدام الدالة partial_fit والتي تكون مهمتها تدريب العينة، تنفيذ النموذج و مقارنة النتائج لتحسين parameters لعدد محدد من العينات، لاحظ البرنامج التالي: def iter_minibatches(batchsize, datasetsize): batchstart = 0 while batchstart < datasetsize: batchrows = range(batchstart,batchstart+batchsize) X_batch, y_batch = getrows(batchrows) yield X_batch, y_batch batchstart += batchsize batchcreator = iter_minibatches(batchsize=2, datasetsize=10) n_samples, n_features = 10, 5 y = np.random.randn(n_samples) X = np.random.randn(n_samples, n_features) reg = SGDRegressor() for X, y in batchcreator: reg.partial_fit(X, y) y_predicted = reg.predict(X_test) لاحظ أن البرنامج المنفذ عبارة عن mini-batch SGDRegressor و الذي يمكن تحويله لbatch بزيادة chunck_size لعدد العينات الكلي في مجموعة التدريب.
  8. يمكنك البحث عن سطر معين في ملف و إستبداله بإستخدام البرنامج أدناه: import fileinput import sys def replaceAll(file,searchExp,replaceExp): for line in fileinput.input(file, inplace=1): if searchExp in line: line = line.replace(searchExp,replaceExp) sys.stdout.write(line) replaceAll("/fooBar.txt","foo","bar") كما يمكن أيضاً الكتابة في ملف جديد بعد إستبدال السطر كما هو موضح في البرنامج التالي: fin = open("foo.txt", "rt") fout = open("bar.txt", "wt") for line in fin: fout.write(line.replace('foo', 'bar')) fin.close() fout.close() أو بالكتابة في نفس الملف بعد قراءة المحتويات في شكل string و فتح الملف مرة أخرى للكتابة: fin = open("foo.txt", "rt") data = fin.read() data = data.replace('foo', 'bar') fin.close() fin = open("foo.txt", "wt") fin.write(data) fin.close()
  9. العبارات True, False تتبع للقيم البوليانية في بايثون، و يمكن التعبير عنهما بأرقام تأخذ قيمتين 1,0 على التوالي. بذلك يمكن إجراء كافة العمليات الحسابية عليهما، لاحظ المثال أدناه: print(True == 1) #True print(False == 0) #True print(True + (False / True)) #1.0 print(0 + False + True) #1 not 1 #False لكن إن تم إستخدام True, False كقيمة راجعة من دالة، يمكن أن تتغير قيمتها حسب البرنامج، مثلاً: def print_and_true(): print("I got called") return True not print_and_true() # I got called # False القيمة الراجعة من الدالة print_and_true عبارة عن False لأنه تم إستخدام not قبل مناداة الدالة. def print_and_return(x): print(f"I am returning {x}") return x True and print_and_return(True) # I am returning True # True True and print_and_return(False) # I am returning True # False False and print_and_return(True) # False False and print_and_return(False) # False في المثال السابق لاحظ عدم مناداة الدالة لأن القيمة الأولى للboolean operator كانت عبارة عن False ففي هذه الحالة لا داعي لتنفيذ ما يليها.
  10. كيف يتم معالجة السلاسل الزمنية التي تحتوى على إزاحة (كما في الصورة) و التوقع بقيمة أقل إختلاف عن القيمة الحقيقية؟
  11. لدي مجموعة بيانات نصية (مقالات) و أريد أن أصنفها (X: words of the articles, y: class) لكن عدد المقالات غير متوازن أي صنف يحتوى على عدد كبير و الأخر على عدد بسيط. هل يوجد طريقة مثل SMOTE لموازنة البيانات في حال كانت النصية؟ شكراً
  12. يمكنك إيجاد عنصر في قائمة بإستخدام الدالة index للقوائم وذلك بتحويل المصفوفات كما موضح في البرنامج التالي: def find(myarray, elements): myarray = myarray.tolist() elements = elements.tolist() indices = [] for element in elements: indices.append(myarray.index(element)) return indices والان لتنفيذ المثال يمكننا مناداة الدالة المعرفة: import numpy as np x = np.array([[0, 1], # 0 [2, 3], # 1 [4, 5], # 2 [6, 7], # 3 [8, 9]]) # 4 xx = np.array([[0, 1], [4, 5], [8, 9]]) find(x,xx)
  13. LDA هو أحد خوارزميات التصنيف الخطي، و التي تقوم بإنشاء نموذج إحتمالي لكل صنف بالإعتماد على توزيع البيانات، و بذلك العينات الجديدة تصنف بالرجوع للإحتمالية الشرطية لإنتمائها لأحد الأصناف و بالتالي إمكانية إختيار الصنف ذو الإحتمالية الأعلى. كل هذا يتم عن طريق إجراء بعض الحسابات الإحصائية مثل الوسط الحسابي mean و الإنحراف المعياري standard deviation. خوارزمية LDA تفترض ان المدخلات عبارة عن قيم رقمية numeric values موزعة طبيعياً normally distributed ولديها نفس التباين variance، بالرغم من إعتماد LDA على هذه الفرضيات في توزيع العينة بالنسبة لمجموعة الأصناف إلا أنه من النماذج التي تعطي نتائج فعالة. سأقوم هنا بعرض مثال للمصنف و الذي يقوم بتحديد أفضل solver حسب البيانات المدخلة، في هذا المثال تم توليد البيانات بإستخدام make_classification: # إستدعاء الدوال من المكتبات from sklearn.datasets import make_classification from sklearn.model_selection import GridSearchCV from sklearn.discriminant_analysis import LinearDiscriminantAnalysis # تعريف مجموعة البيانات و التي تحتوي على 1000 عينة كل منها له 10 خصائص X, y = make_classification(n_samples=1000, n_features=10) # solver تعريف النموذج بدون تحديد ل model = LinearDiscriminantAnalysis() # محفوظ كمفاتيح solver لحفظ مدخلات النموذج كإسم dictionary تعريف grid = dict() grid['solver'] = ['svd', 'lsqr', 'eigen'] # تعريف دالة البحث عن الحلول بإستخدام نماذج تستخدم search = GridSearchCV(model, grid, scoring='accuracy', n_jobs=-1) # تطبيق عملية البحث results = search.fit(X, y) # طباعة النتائج print('Mean Accuracy: %.3f' % results.best_score_) print('Config: %s' % results.best_params_) في هذا البرنامج قمنا بإختبار ال solver المناسب للبيانات التي تحتوى على 10 خصائص features، البحث عن النموذج الأفضل نٌفذ بإستخدام GridSearchCV (يمكنك مراجعة هذه الصفحة لمزيد من التفاصيل) والتي تستقبل كل من النموذج LDA و مدخلات النموذج أو parameters و دالة التقييم scoring والتي هي عبارة عن مقياس الدقة accuracy، و n_jobs هنا ترمز لعدد المعالجات التي إنجازها بالتوازي و العدد -1 تعني إستخدام كافة المعالجات. بعد ذلك تم البحث عن النموذج الأفضل بالتدريب بإستخدام الدالة fit لدالة البحث، أخيراً تم طباعة الsolver الأعلى دقة.
  14. سؤال جيد، هنالك العديد من الدوال، العبارات والقيم التي تمثل عبارة خاطئة منها العبارة المنطقية False نفسها، القيمة صفر لأي متغير، القائمة الفارغة[] empty dictionary {} و أيضاً العبارة None. راجع الأمثلة التالية: x = None if x: print('if x') else: print('if not') #if not x = {} if x: print('if x') else: print('if not') #if not x = [] if x: print('if x') else: print('if not') #if not x = 0 if x: print('if x') else: print('if not') #if not في الأمثلة السابقة نفذنا الشرط مع كل من ما تم ذكره سابقاً، و في حال كانت قيمة x تساوى 0,None,[],{} طبقنا شرط if x والتي تعني في حال كان الشرط صحيح if x == True نطبع عبارة if x (يمكنك إستبدالها بأي شي أخر ك True مثلاً لكن لم نستخدمها هنا لتفادي التشوش مع العبارات الصحيحة أو الخاطئة بوليانياً). لكن مثلا إن قمنا بإضافة أي عنصر في القائمة أو dictionary أو حتى تغيير قيمة x فإن النتيجة ستكون بطباعة الجملة الأولى الموجودة داخل شرط if، راجع المثال التالي: x = 42 if x: print('if x') else: print('if not') #if x و بالتعميم فإن الدالة append ترجع None فبذلك نفهم أن تحويلها للقيمة البوليانية هو ما سيعطينا قيمة false. x = [] print(bool(x)) print(bool(x.append(123))) print(bool(x)) False False True البرنامج أعلاه هو نفسه ما قمت بتطبيقه لكن مع إستدعاء الدالة bool التي ترجع القيمة البوليانية للمتغير أو الدالة و غيره. بعد تعريف القائمة الفارغة و التي عرفنا أن قيمتها البوليانية ستمثل False بعدها قمنا بنداء الدالة لتحديد القيمة الراجعة من عملية الإضافة والتي ستكون False و لكن القيمة البوليانية للقائمة بعد الإضافة تتغير من False إلى True.
  15. حسناً لا أعلم تماماً ما هي فكرتك في حل هذه المشكلة لكن لدي إفتراضين على حسب الخطأ الناتج من البرنامج: اولاً أنك تريد إستخدام نموذج تصنيفي كما إقترح @Ali Haidar Ahmad في الإجابة السابقة، فبالتالي لحل المشكلة يمكننا إستخدام SVC التصنيفي بدلاً من نموذج SVR الذي ينتج قيم رقمية، بذلك يكون التعديل فقط في المصنف الممرر لدالة ال baggingclassifier و يصبح كالتالي: from sklearn.ensemble import BaggingClassifier from sklearn.model_selection import train_test_split from sklearn.metrics import confusion_matrix from sklearn.datasets import load_breast_cancer import seaborn as sns import matplotlib.pyplot as plt from sklearn.svm import SVC Data = load_breast_cancer() X = Data.data y = Data.target X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=44, shuffle =True) clf = BaggingClassifier(base_estimator=SVC(),n_estimators=150, random_state=444) clf.fit(X_train, y_train) print('BaggingClassifier Train Score is : ' , clf.score(X_train, y_train)) print('BaggingClassifier Test Score is : ' , clf.score(X_test, y_test)) c = confusion_matrix(y_test, clf.predict(X_test)) print('Confusion Matrix is : \n', c) sns.heatmap(c, center = True) plt.show() أو أنك فقط تحاول التجريب و قمت بتعريف أي نموذج للتدريب و الحصول على النتائج لتعرف أيها أكثر دقة، فبالتالي، النموذج الأتوماتيكي في هذه الحالة هو DecisionTreeClassifier، يمكن أن نمسح base_estimator من النموذج BaggingClassifier أو أن نسند له القيمة None: from sklearn.ensemble import BaggingClassifier from sklearn.model_selection import train_test_split from sklearn.metrics import confusion_matrix from sklearn.datasets import load_breast_cancer import seaborn as sns import matplotlib.pyplot as plt Data = load_breast_cancer() X = Data.data y = Data.target X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=44, shuffle =True) clf = BaggingClassifier(base_estimator=None,n_estimators=150, random_state=444) clf.fit(X_train, y_train) print('BaggingClassifier Train Score is : ' , clf.score(X_train, y_train)) print('BaggingClassifier Test Score is : ' , clf.score(X_test, y_test)) c = confusion_matrix(y_test, clf.predict(X_test)) print('Confusion Matrix is : \n', c) sns.heatmap(c, center = True) plt.show() يمكنك أيضاً زيارة صفحة sklearn لتتعرف على المعلومات الممررة لنموذج BaggingClassifier من هنا.
  16. يمكنك الوصول لقيم المفاتيح في أي dictionary عن طريق إستخدام الدالة get الفرق الوحيد بين الdictionary العادي و المعقد هو قيم المفاتيح التي تكون في نفسها مفتاح لقيمة أخرى، راجع البرنامج التالي: dataDict = { "a":{ "x": 1, "y": 2, "z": 3 }, "b":{ "x": 1, "y": { "x": 1, "y": 2, "z": 3 }, "z": 3 } } dataDict.get('b').get('y').get('z') لاحظ أن طريقة النداء تتدرج من المفتاح الأول b و الذي يقود للمفتاح الثاني y والذي يقود للمفتاح الثالث z الذي قيمته تساوي 3. print(dataDict['b']) print(dataDict['b']['y']['z']) {'x': 1, 'y': {'x': 1, 'y': 2, 'z': 3}, 'z': 3} 3 يمكننا أيضاً نداء المفتاح وحده (طريقة indexing)، لاحظ الإستدعاء لقيمة المفتاح b و التي تنتج الإجابة {'x': 1, 'y': {'x': 1, 'y': 2, 'z': 3}, 'z': 3} بذلك يمكننا أيضاً معاملتها بصورة dictionary بداخل dictionary كما في السطر الثاني والتي ستقود مباشرة للإجابة 3. لاحظ أنه يمكنك الوصول للقيمة بالطريقتين لكن للإجابة على سؤال أي الطرق أسرع لابد من أن نحسب سرعة التنفيذ لكل من الطرق في الإجابات والمقارنة بين أزمانها، و هنالك عدة طرق لقياس الزمن أسهلها هي نداء العبارة timeit% قبل كل إستدعاء لأي دالة.
  17. المشكلة تظهر لأن remove تقوم بحذف أول ظهور لأحد الحروف في القائمة، الحروف التي سيتم حذفها ستتأثر بطول القائمة و بالحروف الموجودة بها، و بما أن الحذف ينقص من عدد الحروف بالقائمة و العبارة return ترجع القائمة الجديدة فمن الأغلب أنه في بعض المرات التي ظهرت فيها بعض الحروف متتالية تم حذف إحداها و تم تمرير القائمة الجديدة مرة أخرى (inconsistency problem). يمكن حل المشكلة بإستخدام عدد من الطرق الأخرى، مثلاً list comprehension: def anti_vowel(c): vowels = ('a', 'e', 'i', 'o', 'u') return ''.join([l for l in c if l not in vowels]) anti_vowel("Hellooo, world! Woooords!") # Hll, wrld! Wrds! الناتج عبارة عن كل الحروف و علامات الترقيم ما عدا التي تم تحديدها في vowels set. يمكن أيضاً إستخدام regular expression، عن طريق إستخدام الدالة sub التي تقوم بالبحث عن واحد أو مجموعة حروف في نص محدد و إستبداله بما يتم تمريره في المدخل الثاني للدالة. import re def anti_vowel(s): return re.sub(r'[AEIOU]', '', s, flags=re.IGNORECASE) anti_vowel("Hellooo, world! Woooords!") لاحظ هنا تحديد مدخل أخير للدالة و التي يتغاضى فيها عن وجود الحروف الكبيرة أو الصغيرة (إختياري) و يبحث عن الأحرف المحددة بغض النظر عن نوعها. الطريقة الثالثة هي إستخدام translate وهي دالة تستقبل dictionary بالحروف التي سيتم إستبدالها و القيم الجديدة لها، راجع المثال التالي: dictionary = str.maketrans(dict.fromkeys('aeiouAEIOU')) "Hellooo, world! Woooords!".translate(dictionary) وفيه تم إستخدام maketrans لإنشاء mapping table من الحروف المدخلة كبيرها و صغيرها، حيث أن الحروف ستمثل المفاتيح بدون قيم values are None، و أخيراً نمرر الجدول لدالة الترجمة.
  18. في الخطأ المذكور أعلاه لديك عدد 4 أصناف بحساب عينة واحدة لكل صنف بإستثناء الصنف 4 الذي لديه عينتين، فبالتالي لا يمكن التقسيم لثلاثة أجزاء للقيام بعملية التحقق، على الأقل يجب أن يساوي أحد الأصناف القيمة الموضوعة ل n_splits. لاحظ أنه يمكن لبرنامج العمل في حال كان عدد الأقسام 2 لانها تحقق الشرط (الصنف 4 يحتوي على عينتين). import numpy as np from sklearn.model_selection import StratifiedKFold X = np.array([[1,4],[2,1],[3,4],[7,8],[2,8]]) y = np.array([2,2,1,3,4]) skf = StratifiedKFold(n_splits=2) print(skf.get_n_splits(X, y)) for train_index, test_index in skf.split(X, y): print("TRAIN:"+str(train_index)+'\n'+"TEST:"+str(test_index),end='\n\n') X_train, X_test = X[train_index], X[test_index] y_train, y_test = y[train_index], y[test_index] print('X_train:\n '+str(X_train),end='\n\n') print('X_test:\n '+str(X_test),end='\n\n') print('y_train:\n '+str(y_train),end='\n\n') print('y_test:\n' +str(y_test),end='\n\n') لكن بعد تنفيذ البرنامج يظهر إشعار التنبيه التالي: /usr/local/lib/python3.7/dist-packages/sklearn/model_selection/_split.py:667: UserWarning: The least populated class in y has only 1 members, which is less than n_splits=2. % (min_groups, self.n_splits)), UserWarning) والذي بلفت إنتباهك للأصناف التي تحتوي فقط على عنصر واحد مثل 1و2و3. و الان لتفادي ذلك الخطأ يمكنك زيادة عدد العينات في البرنامج بمعدل 3 أو أكثر لكل صنف على حدة، راجع المثال أدناه: import numpy as np from sklearn.model_selection import StratifiedKFold X = np.array([[1,4],[2,1],[3,4],[7,8],[2,8],[1,4],[2,1],[3,4],[7,8],[2,8],[1,4],[2,1],[3,4],[7,8],[2,8]]) y = np.array([2,2,1,3,4,2,2,1,3,4,2,2,1,3,4]) skf = StratifiedKFold(n_splits=3) print(skf.get_n_splits(X, y)) for train_index, test_index in skf.split(X, y): print("TRAIN:"+str(train_index)+'\n'+"TEST:"+str(test_index),end='\n\n') X_train, X_test = X[train_index], X[test_index] y_train, y_test = y[train_index], y[test_index] print('X_train:\n '+str(X_train),end='\n\n') print('X_test:\n '+str(X_test),end='\n\n') print('y_train:\n '+str(y_train),end='\n\n') print('y_test:\n' +str(y_test),end='\n\n') البرنامج يحتوي على نفس البيانات الموجودة في المثال الذي أنتج الخطأ و لكن بزيادة عدد العينات بمعدل 3 عينات أقلاها لكل صنف.
  19. هذا الخطأ ينتج بالطبع حسب نوع البيانات المدخلة و توزيعها، أعلم عزيزي@Meezo ML أن هذا الخطأ ناتج عن إستخدام stratify والذي يمكنك التخلص منه فقط بالمسح، راجع السطر التالي: X,X_val, y, y_val=train_test_split(data,label,test_size=0.2) لكن دعنا نفهم لماذا نتج هذا الخطأ من الأساس، stratify هو عبارة عن مدخل لدالة التقسيم والذي يمكننا إستخدامه فقط في حالة البيانات التصنيفية categorical variables و الذي يقوم بتقسيم البيانات بين التدريب و التقييم training and validation بصورة تتناسب مع توزيع البيانات الأساسية، مثلاً إذا كان لدينا صنفين في y أحدهما يمثل 25% من البيانات و الأخر 75% فإن stratify تقوم بتقسيم البيانات بين التدريب و التحقق بنفس النسبة لكل من مجموعتي البيانات. from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split iris = load_iris() X = iris.data y = iris.target X1 = pd.DataFrame(X).drop(pd.DataFrame(X).index[10:50]).drop(pd.DataFrame(X).index[70:100]).drop(pd.DataFrame(X).index[140:]) y1 = pd.DataFrame(y).drop(pd.DataFrame(y).index[10:50]).drop(pd.DataFrame(y).index[70:100]).drop(pd.DataFrame(y).index[140:]) y1.value_counts() x_train, x_test, y_train, y_test = train_test_split(X1,y1,stratify=y1) اولاً قمنا بإستدعاء الدوال لتحميل بيانات Iris وتقسيم البيانات بإستخدام train_test_split و من ثم حملنا البيانات وقسمناها إلى مدخلات و مخرجات X,y و حذفنا عدد من السطور في كل من المدخلات و المخرجات (للتأكد من تنفيذ stratify، مع العلم أنها يمكن أن تعمل حتى لو كانت الأصناف متساوية كما في حالة Iris والتي يتساوى فيها التصنيفات بعدد 50 لكل صنف) الناتج من الحذف يعطي التقسيم التالي: 2 40 1 20 0 10 بمعدل 40 عينة من الصنف الأول، 20 من الثاني و 10 من الأخير. و أخيراً عملية التقسيم تأخذ X1,y1 كمدخلات مع stratify الذي يستقبل y1 وبالتالي إن قمنا بطباعة أعداد التصنيفات في y_test سنحصل على نفس توزيع المدخلات. y_test.value_counts() 2 10 1 5 0 3
  20. مثلما تم التوضيح في المثال السابق، فإن مشكلة النموذج تكمن في عدم توافقية شكل المدخلات مع المخرجات X,y. لذلك لابد من التأكد من شكل المدخل X.shape, y.shape قبل تطبيق النموذج في البيانات. مثلاً للقيام بعملية تدريب نموذج بالإعتماد على عمودين من بيانات بوسطن (أحد البيانات المتوفرة في مكتبة sklearn)، نقوم بالتالي: import pandas as pd from sklearn.linear_model import LinearRegression from sklearn.datasets import load_boston boston = load_boston() X = pd.DataFrame(boston.data[:,-4]) y = pd.DataFrame(boston.target) lr = LinearRegression() lr.fit(X,y) في البدء قمنا بإستدعاء الدوال اللازمة، ثم حملنا مجموعة بيانات بوسطن، منها قمنا بإختيار عمودين، عمود feature من بيانات المدخلات X وهو الرابع من أخر الأعمدة (-4) و عمود المخرجات وهو يمثل الأسعار target، إن قمت بطباعة شكل البيانات: print(X.shape, y.shape) (506, 1) (506, 1) فإنك تحصل على عدد مطابق للصفوف و الأعمدة في كل من X,y حيث القيمة الأولى تشير لعدد العينات samples و القيمة الثانية تشير لعدد الخصائص المستخدمة للوصول للسعر feature وهي واحدة. لاحظ أنك إن لم تقم بعملية التحويل ل dataframe لبيانات X فإن النموذج لن يعرف عدد الخصائص المراد تدريبه عليها و ينتج خطأ. كما يمكنك أيضاً تحويل فقط بيانات المدخلات X و ترك y كما هي في شكل عدد من الصفوف بدون تحديد الأعمدة كالتالي: import pandas as pd from sklearn.linear_model import LinearRegression from sklearn.datasets import load_boston boston = load_boston() X = pd.DataFrame(boston.data[:,-4]) y = boston.target lr = LinearRegression() lr.fit(X,y) و بذلك تدخل البيانات حسب الشكل المطلوب للنموذج، يمكنك مراجعة موقع sklearn لمزيد من التفاصيل.
  21. LeavePOut هي إحدى إستراتيجيات ال Cross validation و التي تهتم بالتحقق من دقة النموذج و ذلك بتقسيم جزء محدد من بيانات التدريب و معاملتها كبيانات للإختبار و مقارنة نتائجها مع القيم الحقيقة لإماكنية تعديل Hyperparameters للنموذج. بالإعتماد على فرضية أن بعض البيانات تكون Independent and Identically Distributed (i.i.d.) أن البيانات تولد بنفس الطريقة، بذلك للقيام بعملية التحقق من دقة النموذج لابد من وجود طرق تساعد على تدريب النموذج للتعرف أغلب البيانات و توزيعها و خصائصها. من هذه الطرق LeavePOut وهي مشابهة جداً ل LeaveOneOut و من الأسم لابد أنك لاحظت انها تعتمد على ترك قيمة وحيدة للتحقق و تدرب النموذج ببقية البيانات، وفي حالة وجود n عينة، يتدرب النموذج على n-1 عينة فبالتالي يوجد تباين عالي في بيانات الإختبار لاحقاً. \documentclass{article} \usepackage{amsmath} \begin{document} $\binom nk= \binom 4 1= \frac{4!}{1!(4-1)!} = \frac{4*3!}{1(3!)!} = 4$ \end{document} دعنا نلقى نظرة على مثال مبسط لتطبيق LeaveOneOut و الذي سيرينا الفرق بينه و بين LeavePOut: from sklearn.model_selection import LeaveOneOut X = [1, 2, 3, 4] loo = LeaveOneOut() for train, test in loo.split(X): print("%s %s" % (train, test)) بعد إستدعاء الدالة LeaveOneOut قمنا بتعريف قائمة تحتوي على أربع قيم، و من ثم عرفنا الدالة و بإستخدام حلقة for التكرارية قمنا بتخزين ناتج إستدعاء دالة التقسيم split والتي ترجع مؤشرات البيانات المقسمة إلى تدريب و إختبار (في هذه حالة تدريب النموذج على بيانات حقيقية سترمز بيانات الإختبار إلى بيانات التحقق و ستكون هنالك بيانات منفصلة للإختبار). لاحظ ناتج عملية التقسيم: [1 2 3] [0] [0 2 3] [1] [0 1 3] [2] [0 1 2] [3] القوائم التي تحتوي على ثلاث قيم و هي تشير لمؤشرات بيانات التدريب train كما موضح في البرنامج و القيمة الأخيرة تشير لمؤشرات بيانات الإختبار. والان لنلقى نظرة على LeavePOut وهي مشابهة لLeaveOneOut و تنشئ كافة بيانات التدريب و التحقق بترك P عينة من مجموعة البيانات بدلاً من ترك عينة واحدة في كل مرة كما في LeaveOneOut. وبذلك يجب أن تكون قيمة ال P أكبر من 1 (وإلا فإنها ستكون مساوية لLeaveOneOut) و أقل من n. from sklearn.model_selection import LeavePOut X = [1, 2, 3, 4] lpo = LeavePOut(p=2) for train, test in lpo.split(X): print("%s %s" % (train, test)) لنحاول حساب مجموعات المؤشرات المتوقع إنشاؤها بتحديد P=2 في المثال السابق: \documentclass{article} \usepackage{amsmath} \begin{document} $\binom np= \binom 4 2= \frac{4!}{2!(4-2)!} = \frac{4*3*2!}{2*1(2!)!} = 6$ \end{document} بالتالي رياضياً حسب التعريف نتوقع الحصول على 6 مجموعات، والان فلنراجع ناتج التنفيذ: [2 3] [0 1] [1 3] [0 2] [1 2] [0 3] [0 3] [1 2] [0 2] [1 3] [0 1] [2 3] وهو مساوي لعدد المجموعات المحسوبة، لاحظ أن المؤشرات تتداخل و هي طريقة أكثر إستهلاكاً للذاكرة من طرق أخرى مثل K-Folds والتي لا تسمح بتداخل المؤشرات في المجموعات.
  22. يمكن إيجاد الصفوف الفريدة بأكثر من طريقة، منها بإستخدام unique كما هو موضح في الإجابة أعلاه، أو بإستخدام الدالة vstack كما في المثال التالي: import numpy as np a = np.array([ [1, 1, 1, 0, 0, 0], [0, 0, 1, 1, 0, 0], [0, 0, 1, 1, 0, 0], [1, 1, 1, 0, 0, 0], [0, 0, 1, 1, 0, 0]]) print(np.vstack({tuple(row) for row in a})) print(np.vstack(set(map(tuple, a)))) بعد إستدعاء الدالة numpy تم تعريف المصفوفة، و من بعدها الدالة vstack من numpy (التي تحول المدخل إلى مكدس رأسي) و بإستخدام خاصية المجموعة التي تقوم بإختيار القيم غير المكررة فقط من الصفوف الموجودة في المصفوفة a. أما في السطر الأخير فقد تم عمل نفس الشئ بتحويل الصفوف إلى مدخلات للمجموعة بإستخدام دالة map والتي تحول أي صف إلى tuple أولا و من ثم تنفذ عملية التحويل إلى مجموعة و في الأخير تحويل الناتج إلى مكدس رأسي. طريقة أخرى لإستخراج الصفوف الفريدة بإستخدام طريقة إقصاء الصفوف المكررة عن طريق الدالة drop_duplicates() والتي تستخدم مع dataframe، راجع البرنامج التالي: import pandas as pd pd.DataFrame(a).drop_duplicates().values والتي نحول فيها المصفوفة إلى dataframe لنتمكن من إستخدام الدالة الخاصة بالإقصاء و من ثم لتحويل الناتج إلى مصفوفة نستدعى الدالة values. لكن عزيزي @Fahmy Mostafa إن كنت تريد الحصول على أسرع طريقة، يمكنك التأكد بإستخدام العبارة timeit والتي تعطيك الزمن المتوسط (لأسرع 5 نتائج) من تنفيذ الدالة 1000 مرة، و حسب التنفيذ و الشرح الموضح في الموقع بأخر الإجابة vstack تعتبر أسرع طريقة: timeit np.vstack(set(map(tuple, a))) #10000 loops, best of 5: 25.1 µs per loop timeit np.vstack({tuple(row) for row in a}) #10000 loops, best of 5: 24.3 µs per loop timeit np.unique(a, axis=0) #10000 loops, best of 5: 107 µs per loop timeit pd.DataFrame(a).drop_duplicates().values #1000 loops, best of 5: 1.39 ms per loop يمكنك مراجعة الصورة التالية أيضاً: والتي توضح إختلاف سرعات التنفيذ للدوال المستخدمة في إيجاد الصفوف الفريدة، يمكنك مراجعة موقع GitHub لتتعرف على المزيد من التفاصيل.
  23. يمكنك أن تقوم بإستيراد sklearn أولاً ثم التأكد من الإصدارة و عمل ترفيع لأخر إصدارة بإستخدام البرنامج التالي: import sklearn sklearn.__version__ !pip install -U scikit-learn # or using conda هذه الخطوة مهمة لتفادي أي أخطاء قد تنتج من إستخدام دوال في إصدارات قديمة. و القيام بعملية إستدعاء مودل SimpleImputer من الموديول sklearn.impute كما هو موضح في الإجابة أعلاه. راجع المثال التالي و الذي يقوم بإستخدام SimpleImputer لملء ثلاث خانات في مصفوفة: import numpy as np from sklearn.impute import SimpleImputer imp_mean = SimpleImputer(missing_values=np.nan, strategy='mean') X = [[np.nan, 2, 3], [4, np.nan, 6], [10, np.nan, 9]] imp_mean.fit_transform(X) في أول سطرين تم إستدعاء الدوال numpy و SimpleImputer ومن ثم تعريف الدالة SimpleImputer و التي تحتوي على إستراتيجية التعبئة للقيم المفقودة في المصفوفة و في هذه الحالة هي القيمة المتوسطة لكل feature أو عمود في البيانات، بالإضافة لتحديد القيم المفقودة معرفة بnp.nan . في السطر الرابع قمنا بتعريف مصفوفة البيانات التي نريد تعبئتها، و أخيراً نقوم بإستخدام fit_transform للمصفوفة، والناتج يكون المصفوفة معبأة بالقيم المولدة بإستخدام SimpleImputer. array([[ 7., 2., 3.], [ 4., 2., 6.], [10., 2., 9.]])
  24. يمكننا أن نحول dataframe إلى مصفوفة عن طريق إستخدام .values أيضاً إذ أنها تخرج الناتج في شكل مصفوفة كما هو موضح في المثال التالي: import numpy as np import pandas as pd df = pd.DataFrame([ {'var1': 'a', 'var2': 1}, {'var1': 'b', 'var2': 1}, {'var1': 'c', 'var2': 1}, {'var1': 'd', 'var2': 2}, {'var1': 'e', 'var2': 2}, {'var1': 'f', 'var2': 2}]) df.values أو يمكننا الحصول على البيانات كاملة بالإضافة لindex بإضافة الدالة reset_index() وتصبح الدالة كالتالي: df.reset_index().values كما يمكننا الحصول على البيانات بالindex أيضاً بإستخدام الدالة to_records() كالتالي: df.to_records() لكن بالطبع التحويل بإستخدام الدالة المخصصة لذلك هي أفضل مثلما هو موضح في الإجابتين السابقتين و ذلك لتفادي أي أخطاء قد تنتج. كما يمكننا الحصول على مصفوفة بإستخدام الدالة asarray التي تستقبل dataframe كمدخل و ترجع مصفوفة البيانات أو إستخدام الدالة array التي تقوم بنفس العملية، البرنامج التالي يوضح طريقة إستخدام الدالتين: np.asarray(df) np.array(df)
  25. يمكننا إستخدام إحدى الطرق التالية: الطريقة الأولى: العبارة where والتي تستخدم لتطبيق الشروط مع البيانات الضخمة، وفيها يتم التحقق من شرط معين و تمرير قيمة ليتم إسنادها في العمود الجديد مقابل كل قيمة، و قيمة أخرى في حال عدم توفر الشرط، راجع المثال التالي: import pandas as pd import numpy as np df = pd.DataFrame({ 'Type': ['A', 'B', 'O', 'B'], 'Set': ['A', 'B', 'B', 'A']}) df['test'] = np.where(df['Set'] == 'A', 'group1', 'group2') df في البدء قمنا بإستدعاء المكتبات numpy , pandas ثم عرفنا dataframe يحتوى على العمودين و بياناتهما، أخيراً قمنا بتعريف عبارة where و التي تستقبل 3 متغيرات، الأولى عبارة عن الشرط، الثاني القيمة في حال تحقق الشرط، و الثالثة هي القيمة في حال عدم تحقق الشرط. في هذه الحالة الشرط يقوم بالتحقق من القيم في كل سطر لوحده و تطبيق القيمة المختارة في السطر المقابل له في العمود الجديد. الطريقة الثانية: هي بالتعويض بإستخدام شرط داخل دالة dataframe.loc والتي تحدد عدد من الأسطر بناء على ما بالقوسين المربعين، راجع المثال التالي: df.loc[df['Set'] == 'A', 'test'] = 'group1' df.loc[df['Set'] == 'B', 'test'] = 'group2' df في البرنامج السابق نقوم بإختيار القيم التي تحتوي على 'A' في عمود Set و من ثم إسناد القيمة group1 لها في العمود المسمي test، نفس الطريقة مطبقة بالسطر الثاني. الطريقة الثالثة: هي بإستخدام list comprehension وهي من أبسط الطرق التي تعتمد على إنشاء قائمة بناء على الشرط المتحقق في كل سطر من القيم الموجودة في Set، راجع المثال التالي: df['test'] = ['group1' if x =='A' else 'group2' for x in df['Set']] df الطريقة الرابعة: هي بإستخدام دالة map و التي تعتمد على المدخلات في شكل dictionary حيث أن كل القيم الممرة تمثل Keys and values و المفاتيح تمثل القيم في العمود Set و الvalues ترمز للقيم التي سيتم إدراجها في العمود الجديد test في حال توافقها مع إحدي المدخلات A أو B راجع البرنامج التالي: test ={'A' : 'group1', 'B' : 'group2'} df['test'] = df['Set'].map(test) df
×
×
  • أضف...