English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
هذا المقال يقدم خوارزمية Logistic Regression في تعلم الآلة، ونستخدم هذه الخوارزمية لتصنيف البيانات. خوارزمية Logistic Regression هي خوارزمية تعلم مساعد تتطلب تعلم مجال العينة وتكون مناسبة للبيانات العددية والنوعية، مثل، نحتاج إلى�断 ما إذا كانت البيانات تنتمي إلى فئة معينة أو لا بناءً على قيم معايير البيانات (عددية).
أولاً - عينات البيانات
في مثالنا، لدينا بعض عينات البيانات التالية:
عينات البيانات تحتوي على ثلاثة معايير: X0X0،X1X1،X2X2
نحن ن�断 ما إذا كانت البيانات تتوافق مع المتطلبات من خلال هذه الثلاثة معايير X1X1 وX2X2، حيث تكون المتوافقة 1 وغير المتوافقة 0.
تم تخزين تصنيف عينات البيانات في مصفوفة
نحن نكتب الدالة التالية في ملف logRegres.py لتحضير البيانات ونطبعها لمراقبةها:
#coding=utf-8 من numpy import * def loadDataSet(): dataMat = []; labelMat = [] fr = open('testSet.txt') للمخططات في fr.readlines(): lineArr = line.strip().split() dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])]) labelMat.append(int(lineArr[2])) return dataMat,labelMat if __name__=='__main__': dataMat,labelMat=loadDataSet() print 'dataMat:\n',dataMat
نحن ننظر في عينة البيانات هذه:
dataMat: [[1.0, -0.017612, 14.053064], [1.0, -1.395634, 4.662541], [1.0, -0.752157, 6.53862], [1.0, -1.322371, 7.152853], [1.0, 0.423363, 11.054677], [1.0, 0.406704, 7.067335], [1.0, 0.667394, 12.741452], [1.0, -2.46015, 6.866805], [1.0, 0.569411, 9.548755], [1.0, -0.026632, 10.427743], [1.0, 0.850433, 6.920334], [1.0, 1.347183, 13.1755], [1.0, 1.176813, 3.16702], [1.0, -1.781871, 9.097953], [1.0, -0.566606, 5.749003], [1.0, 0.931635, 1.589505], [1.0, -0.024205, 6.151823], [1.0, -0.036453, 2.690988], [1.0, -0.196949, 0.444165], [1.0, 1.014459, 5.754399], [1.0, 1.985298, 3.230619], [1.0, -1.693453, -0.55754], [1.0, -0.576525, 11.778922], [1.0, -0.346811, -1.67873], [1.0, -2.124484, 2.672471], [1.0, 1.217916, 9.597015], [1.0, -0.733928, 9.098687], [1.0, -3.642001, -1.618087], [1.0, 0.315985, 3.523953], [1.0, 1.416614, 9.619232], [1.0, -0.386323, 3.989286], [1.0, 0.556921, 8.294984], [1.0, 1.224863, 11.58736], [1.0, -1.347803, -2.406051], [1.0, 1.196604, 4.951851], [1.0, 0.275221, 9.543647]] [1.0, 0.470575, 9.332488], [1.0, -1.889567, 9.542662], [1.0, -1.527893, 12.150579], [1.0, -1.185247, 11.309318], [1.0, -0.445678, 3.297303], [1.0, 1.042222, 6.105155], [1.0, -0.618787, 10.320986], [1.0, 1.152083, 0.548467], [1.0, 0.828534, 2.676045], [1.0, -1.237728, 10.549033], [1.0, -0.683565, -2.166125], [1.0, 0.229456, 5.921938], [1.0, -0.959885, 11.555336], [1.0, 0.492911, 10.993324], [1.0, 0.184992, 8.721488], [1.0, -0.355715, 10.325976], [1.0, -0.397822, 8.058397], [1.0, 0.824839, 13.730343], [1.0, 1.507278, 5.027866], [1.0, 0.099671, 6.835839], [1.0, -0.344008, 10.717485], [1.0, 1.785928, 7.718645], [1.0, -0.918801, 11.560217], [1.0, -0.364009, 4.7473], [1.0, -0.841722, 4.119083], [1.0, 0.490426, 1.960539], [1.0, -0.007194, 9.075792], [1.0, 0.356107, 12.447863], [1.0, 0.342578, 12.281162], [1.0, -0.810823, -1.466018], [1.0, 2.530777, 6.476801], [1.0, 1.296683, 11.607559], [1.0, 0.475487, 12.040035], [1.0, -0.783277, 11.009725], [1.0, 0.074798, 11.02365], [1.0, -1.337472, 0.468339], [1.0, -0.102781, 13.763651], [1.0, -0.147324, 2.874846], [1.0, 0.518389, 9.887035], [1.0, 1.015399, 7.571882], [1.0, -1.658086, -0.027255], [1.0, 1.319944, 2.171228], [1.0, 2.056216, 5.019981], [1.0, -0.851633, 4.375691], [1.0, -1.510047, 6.061992], [1.0, -1.076637, -3.181888], [1.0, 1.821096, 10.28399], [1.0, 3.01015, 8.401766], [1.0, -1.099458, 1.688274], [1.0, -0.834872, -1.733869], [1.0, -0.846637, 3.849075], [1.0, 1.400102, 12.628781], [1.0, 1.752842, 5.468166], [1.0, 0.078557, 0.059736], [1.0, 0.089392, -0.7153], [1.0, 1.825662, 12.693808], [1.0, 0.197445, 9.744638], [1.0, 0.126117, 0.922311], [1.0, -0.679797, 1.22053], [1.0, 0.677983, 2.556666], [1.0, 0.761349, 10.693862], [1.0, -2.168791, 0.143632], [1.0, 1.38861, 9.341997], [1.0, 0.317029, 14.739025] labelMat: [0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0]
المعطيات الموجودة في العمود الأول من بيانات العينةdataMat، أي القيم المميزةX0X0، جميعها1، هذا يجب أن نلاحظ عند حساب معاملات الترجيح. يوجد في المجموع 100 بيانات عينة، و100 نتائج تصنيف.
إذن، سؤالنا الآن هو:
نحتاج إلى العثور على علاقة بين القيم المميزة في نطاق العينة والنتائج التصنيفية. تصميم وظيفة أو ميزة، لتحقيق تصنيف البيانات المدخلة بناءً على علاقة القيم المميزة في نطاق العينة والنتائج التصنيفية، أي أن النتيجة ستكون1أو0.
ثانيًا، وظيفةSigmoid
لحل المشكلة التي ذكرناها في الفصل السابق، سنقدم أولاً وظيفةSigmoid:
لهذه الوظيفة بعض الخصائص التالية:
عندما z=0z=0، القيمة هي0.50.5
عندما يتزايدzz، القيمة ستقترب من1
عندما ينخفض z بشكل مستمر، تقترب القيمة من 0
لننظر في رسم مسار الدالة:
إذا قمنا بإدخال قيم معلمات الفئةية الثلاثة X0X0، X1X1 وX2X2 في الدالة، فإن النتيجة التي نحصل عليها ستكون قريبة من نتيجة الفئةية الخاصة بنا (قيمة بين 0 و1). إذا كانت النتيجة قريبة من 0، فإننا نعتبرها فئة 0، وإذا كانت النتيجة قريبة من 1، فإننا نعتبرها فئة 1.
كيف يمكن دمجها في الدالة؟ في الواقع، يمكننا فقط إضافتها ببساطة، لأن عندما يزداد z أو ينخفض، فإن قيمة الدالة تقترب من 1 أو 0. نحن نقوم بجعل z=x0+x1+x2z=x0+x1+x2
لكن الواقع هو أن نتائجنا الحسابية والفئةية الفعلية قد تكون هناك خطأ، بل حتى غير صحيحة. من أجل تصحيح هذا المشكلة، قمنا بتعريف معادلة التباين w0w0، w1w1 وw2w2 لثلاثة معلمات عينة X0X0، X1X1 وX2X2، لضبط هذا الخطأ. حتى z=w0x0+w1x1+w2x2
في الواقع، ليس من الصعب التخيل أن قيمة معادلات التباين ww هذه تحدد دقة نتائجنا، بل حتى صحة نتائجنا. بمعنى آخر، تعكس قيمة معادلات التباين ww قواعد الفئةية للمساحة العينية.
إذن، عند إدخال بيانات أخرى غير مجموعة العينات، يمكننا الحصول على نتيجة فئةية قريبة من قواعد الفئةية للمساحة العينية باستخدام معادلات التباين ww الصحيحة.
لكن المشكلة هي كيف يمكننا الحصول على مجموعة معادلات التباين ww مثل هذه؟
ثالثاً، الأسلوب المتدرج في اتجاه النفوذ
الأسلوب المتدرج في اتجاه النفوذ للوظيفة، والذي يتكرر بشكل مستمر حساب قيمة المعاملات لتحقيق أكبر قيمة ممكنة. معادلة التكرار هي كالتالي:
حيث، αα هو طول الخطوة، Δσ(w)Δσ(w) هو نفوذ وظيفة σ(w)σ(w). يرجى الرجوع إلىهنا. وقد تكون قدرة الكاتب على الرياضيات محدودة، لذا لن يقدم الشرح.
في النهاية، يمكننا الحصول على معادلة حساب النفوذ:
إذن، معادلة التكرار هي كالتالي:
شرح المعادلة:
wk+1wk+1 هو نتيجة معادلة التباين للعناصر XX في التكرار الحالي.
wkwk هو نتيجة معادلة التباين للعناصر XX في التكرار السابق.
αα هو طول الخطوة في كل تكرار.
xixi هو العنصر i في مكون XX.
yiyi هي نتيجة الفئةية للسجل i في العينة.
σ(xi,wk)σ(xi,wk) هي نتيجة الفئةية للسجل i في العينة، المحسوبة باستخدام وظيفة sigmoid ومعادلة التباين wkwk.
[yi−σ(xi,wk)][yi−σ(xi,wk)] هي قيمة النتيجة الفئةية المتبادلة للسجل i في العينة، وهي قيمة الخطأ بين قيمة النتيجة الفئةية المحسوبة باستخدام وظيفة sigmoid باستخدام wkwk كمعادلة التباين.
الآن، لدينا معادلة حساب معادلات التباين، وسنقوم بإنشاء دالة في ملف logRegres.py لتحقيق حساب معادلات المساحة العينية، ونطبع النتيجة:
تعريف gradAscent(dataMatIn, classLabels): dataMatrix = mat(dataMatIn) #100 row 3 column #print dataMatrix labelMat = mat(classLabels).transpose() #100 row 1 column #print 'labelMat:\n',labelMat print 'شكل labelMat:rowNum=',شكل (labelMat)[0],'colNum=',شكل (labelMat)[1] rowNum,colNum = شكل (dataMatrix) alpha = 0.001 maxCycles = 500 weights = ones((colNum,1)) #3 row 1 column #print shape(dataMatrix) #print shape(weights) #print shape(labelMat) للدوران k في نطاق maxCycles: #كثيف في عمليات المصفوفات h = sigmoid(dataMatrix*weights) #100 row 1 column #print h error = (labelMat - h) #vector subtraction weights = weights + alpha * dataMatrix.transpose()* error #3 row 1 column return weights if __name__=='__main__': dataMat,labelMat=loadDataSet() #weights=gradAscent(dataMat,labelMat) #print 'dataMat:\n',dataMat #print 'labelMat:\n',labelMat print weights
طباعة النتائج:
معادلة الترجيح: [[ 4.12414349] [ 0.48007329] [-0.6168482 ]
لإثبات دقة المعادلة المراجعة التي حسابناها، لننظر في رسم بياني للنقاط في فضاء النماذج والخط المسطح للمعادلة العكسية. نستخدم z(x1,x2)=w0+w1x1+w2x2 كمعادلة التكييف، ونرسم مسار التكييف في المخطط. نستخدم القيم X1X1 وX2X2 في فضاء النماذج كعنصرين عمودي وأفقي، ونرسم نقاط فضاء النماذج. كود التالي:
تعريف plotBestFit(weights): استيراد matplotlib.pyplot كـ plt dataMat,labelMat=loadDataSet() dataArr = array(dataMat) n = شكل (dataArr)[0] xcord1 = []; ycord1 = [] xcord2 = []; ycord2 = [] for i in range(n): if int(labelMat[i])== 1: xcord1.append(dataArr[i,1]); ycord1.append(dataArr[i,2]) إذاً: xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2]) fig = plt.figure() ax = fig.add_subplot(111) ax.scatter(xcord1, ycord1, s=30, c='red', marker='s') ax.scatter(xcord2, ycord2, s=30, c='green') x = arange(-3.0, 3.0, 0.1) y = (-weights[0]-weights[1]*x)/weights[2] y = y.transpose() ax.plot(x, y) plt.xlabel('X1'); plt.ylabel('X2'); plt.show() if __name__=='__main__': dataMat,labelMat=loadDataSet() weights=gradAscent(dataMat,labelMat) print 'معامل التدرج:\n',weights plotBestFit(weights)
بعد التشغيل، نحصل على الصورة التالية:
بملاحظتنا، خوارزمية معامل التدرج لدينا تعتبر دقيقة نسبيًا، حيث تقسم منحنى التدرج بيانات العينة إلى جزأين وتتطابق مع قواعد تصنيف العينة.
الآن، سنقوم بإنشاء مصفوفة تصنيفية واختبار هذه المصفوفة:
def classify0(targetData,weights): v = sigmoid(targetData*weights) if v>0.5: return 1.0 else : return 0 def testClassify0(): dataMat,labelMat=loadDataSet() examPercent=0.7 row,col=shape(dataMat) exam=[] exam_label=[] test=[] test_label=[] for i in range(row): if i < row*examPercent: exam.append(dataMat[i]) exam_label.append(labelMat[i]) إذاً: test.إضافة(dataMat[i]) test_label.إضافة(labelMat[i]) أوزان=gradAscent(exam,exam_label) errCnt=0 trow,tcol=شكل(test) للمجال i في المدى (0, trow): v=int(classify0(test[i],weights)) إذا v != int(test_label[i]): errCnt += 1 print 'القيمة الحسابية: ',v,' القيمة الأصلية',test_label[i] print 'معدل الخطأ: ',errCnt/trow if __name__=='__main__': #dataMat,labelMat=loadDataSet() #weights=gradAscent(dataMat,labelMat) ##print 'dataMat:\n',dataMat ##print 'labelMat:\n',labelMat #print 'معدل التدرج:\n',weights #plotBestFit(weights) testClassify0()
تحقيق المفسر بسيط للغاية. نستخدم 70 بيانات من العينة السابقة كبيانات اختبارية لدينا، بحساب معادلة الترجيح. ثم نستخدم المفسر لفصل 30 سجل آخر، ونقارن النتائج بالبيانات العينية. في النهاية، نطبع معدل الخطأ. يمكننا رؤية أن معدل الخطأ هو 0، تقريباً مثالي! يمكننا تعديل نسبة بيانات الاختبار في مجال البيانات الأصلي لاختبار عدة مرات. إذن، الخلاصة هي أن دقة خوارزميتنا جيدة!
إذن، هل تم حل المشكلة الآن؟ يبدو أن هناك شيء ما مفقود. دعنا ندرس بعناية طريقة حساب معادلة الترجيح لدينا، لاكتشاف أننا قمنا بعمل ضرب مصفوفة باستخدام مصفوفة البيانات العينية. أي أننا نمر على جميع بيانات العينة من أجل حساب معادلة الترجيح.
إذن، هل تم حل المشكلة الآن؟ يبدو أن هناك شيء ما مفقود. دعنا ندرس بعناية طريقة حساب معادلة الترجيح لدينا، لاكتشاف أننا قمنا بعمل ضرب مصفوفة باستخدام مصفوفة البيانات العينية. أي أننا نمر على جميع بيانات العينة من أجل حساب معادلة الترجيح.
أربعة. تحسين خوارزمية تحسين الجرادة - خوارزمية الجرادة العشوائية
لقد فهمنا الآن معادلة حساب معادلة الترجيح بالطريقة المتكررة
وبعد أن قمنا بتحقيق برنامجنا. سنقوم بتحسين طريقة حساب معادلة الترجيح كما يلي:
تعريف stocGradAscent0(مجال_البيانات, فئة_النقاط): m,n = shape(dataMatrix) الآلفا = 0.01 وزن = ones((n,1)) #تأكيد إلى جميع الواحدات للمجموعة في النطاق(m): h = سجيود(الجمع من (مجال_البيانات[i] * أوزان)) خطأ = فئة_النقاط[i] - h weights = weights + alpha * error * mat(dataMatrix[i]).transpose() return weights
وزن = وزن + ألفا * خطأ * mat(dataMatrix[i]).transpose()
في كل تكرار، يتم حساب معادلة الترجيح باستخدام نقطة واحدة فقط من مجال العينة. يمكننا رؤية دقة هذا الخوارزمية من خلال رسم نموذج نقاط العينة وخط التكيف:
من السهل ملاحظة أن هناك فرق كبير بين هذا الخوارزمية والخوارزمية السابقة. السبب في ذلك هو أن الخوارزمية السابقة تم حسابها من خلال 500 تكرار، بينما الخوارزمية الجديدة تمت من خلال 100 تكرار. لذا، يجب توضيح أن معادلة الترجيح تتقارب مع زيادة عدد التكرارات، وأن عملية التقارب تحتوي على تذبذبات. بمعنى آخر، كلما زاد عدد التكرارات، كلما اقتربنا من القيمة المطلوبة، ولكن نظرًا لأن بيانات العينة غير الخطية، فإن هناك أيضًا بعض الأخطاء في هذا العملية. يمكن للجميع الاستعانة ببعض الكتب مثل وصفها في كتاب 'ممارسة التعلم الآلي'، هنا لا يتم التطرق إلى التفاصيل.
في كل تكرار، يتم سحب عينة عشوائية لتحليل النقاط الموزعة
طول الخطوة في التكرار يقل مع تزايد عدد التكرارات، ولكن لا يكون يساوي 0
تحسين الكود، وطباعة مسار التكيف والنقاط الموزعة للعينات:
تعريف stocGradAscent1(dataMatrix, classLabels, numIter=150): m,n = shape(dataMatrix) وزن = ones((n,1)) #تأكيد إلى جميع الواحدات للمجموعة في النطاق(numIter): dataIndex = range(m) للمجموعة في النطاق(m): ألفا = 4/(1.0+j+i)+0.0001 #يقل ألفا مع التكرار، لا randIndex = int(random.uniform(0,len(dataIndex)))#ذهب إلى 0 بسبب الثابت h = sigmoid(sum(dataMatrix[randIndex]*وزن)) خطأ = classLabels[randIndex] - h وزن = وزن + ألفا * خطأ * mat(dataMatrix[randIndex]).transpose() del(dataIndex[randIndex]) return weights if __name__=='__main__': dataMat,labelMat=loadDataSet() #weights=stocGradAscent0(dataMat,labelMat) weights=stocGradAscent1(dataMat,labelMat) #weights=gradAscent(dataMat,labelMat) #print 'dataMat:\n',dataMat #print 'labelMat:\n',labelMat #print 'معدل التدرج:\n',weights plotBestFit(weights) #testClassify0()
النمط العشوائي للعينات بعد 150 تكرارًا والشكل الم拟合:
من الصعب رؤية أن الدقة قريبة جدًا من الخوارزمية الأولى!
خلاصة
يستخدم خوارزمية Logistic Regression بشكل رئيسي وظيفة Sigmoid لفئة البيانات، والتحديد الدقيق للفئة يعتمد بشكل كبير على المعادلة التربيعية التي يتم حسابها من خلال الفضاء العينات. نستخدم طريقة الارتفاع المتدرج لتحليل المعادلة التربيعية، ونحسن أداء الخوارزمية من خلال استخدام طريقة الارتفاع المتدرج العشوائي.
هذا هو محتوى المقال الكامل حول وصف خوارزمية Logistic Regression في لغة البرمجة Python، آمل أن يكون مفيدًا لكم. يمكن للمهتمين الاستمرار في مراجعة مواقع أخرى على هذا الموقع حول Python وخوارزمياتمقالات مرتبطة، إذا كانت هناك نقاط قصيرة، فلا تتردد في ترك تعليق. شكرًا للأصدقاء على دعم هذا الموقع!
بيان: محتوى هذا المقال تم جمعه من الإنترنت، ملكية حقوق الطبع والنشر للمالك الأصلي، تم جمع المحتوى من قبل المستخدمين على الإنترنت بشكل متعاوني وتحميله بشكل مستقل، لا يمتلك هذا الموقع حقوق الملكية، لم يتم تعديل المحتوى بشكل يدوي، ولا يتحمل هذا الموقع أي مسؤولية قانونية ذات صلة. إذا كنت قد وجدت محتوى يشتبه في حقوق الطبع والنشر، فلا تتردد في إرسال بريد إلكتروني إلى: notice#oldtoolbag.com (عند إرسال البريد الإلكتروني، يرجى استبدال #بـ @) لإبلاغنا، وتقديم الدليل، إذا تم التحقق من ذلك، سيتم حذف المحتوى المزعوم فورًا.