English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Python-Sprache zur Beschreibung des Logistic-Regression-Algorithmus in der maschinellen Lernung

In diesem Artikel wird das Logistische Regressionsalgorithmus in der maschinellen Lernung vorgestellt. Wir verwenden diesen Algorithmus, um die Daten zu klassifizieren. Der Logistische Regressionsalgorithmus ist ebenfalls ein监督学习algorithmus, der durch den Samplebereich gelernt wird und für numerische und nominalen Daten geeignet ist, z.B. müssen wir die Größe der Attributwerte der Eingangsdaten (numerische Daten) bestimmen, um zu entscheiden, ob die Daten einer bestimmten Kategorie gehören oder nicht.

1. Beispiel-Daten

In unserem Beispiel haben wir folgende Beispiel-Daten:

Die Daten haben3Werte: X0X0,X1X1,X2X2

Wir verwenden dies3Werte des X1X1和X2X2um zu bestimmen, ob die Daten den Anforderungen entsprechen, d.h. die, die den Anforderungen entsprechen, sind1,不符合要求的为0。

Die Datenkategorien werden in einem Array gespeichert

Wir schreiben in der Datei logRegres.py die folgenden Funktionen, um die Daten vorzubereiten und die Daten anzuzeigen:

#coding=utf-8-8
from numpy import *
def loadDataSet():
 dataMat = []; labelMat = []
 fr = open('testSet.txt')
 for line in fr.readlines():
  lineArr = line.strip().split()
  dataMat.append([1.0, float(lineArr[1])])
  labelMat.append(int(lineArr[2))
 return dataMat,labelMat
if __name__=='__main__':
 dataMat,labelMat=loadDataSet()
 print 'dataMat:\n',dataMat

Lassen Sie uns diesen Datensatz beobachten:

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]

Das erste Glied der Sampledaten dataMat, das unsere Eigenwerte X0X0 ist,1dieses Problems müssen wir später bei der Berechnung der Regressionsparameter beachten. Die gesamten Sampledaten10keine, die entsprechende Klassifikationsergebnisse sind auch10keine.

Nun, unser aktuelles Problem ist:
Wir müssen das Verhältnis zwischen den Eigenwerten im Samplebereich und dem Klassifikationsergebnis finden. Designen Sie eine Funktion oder ein Feature, das es ermöglicht, nach Eingabe einer Gruppe von Eigenwerten, die Klassifikation der Daten automatisch auf Basis des Verhältnisses zwischen den Eigenwerten im Samplebereich und dem Klassifikationsergebnis durchzuführen, so dass das Ergebnis entweder1entweder 0.

Zwei, Sigmoid-Funktion

Um das Problem zu lösen, das wir im letzten Abschnitt erwähnt haben, stellen wir hier zunächst die Sigmoid-Funktion vor:

Diese Funktion hat die folgenden Merkmale:

Wenn z = 0, beträgt der Wert 0.50.5
Wenn z z ständig zunimmt, nähert sich der Wert1
Wenn z z ständig abnimmt, nähert sich der Wert 0
Lassen Sie uns das Kurvenbild der Funktion betrachten:

wenn wir den Wert des Samplebereichs3eine Eigenwert X0X0, X1X1和X2X2Wert in die Funktion eingesetzt wird, ergibt sich ein Ergebnis. Dieses Ergebnis wird dem Klassifikationsergebnis (zwischen 0 und)1Wird dieser Wert nahe 0, dann betrachten wir die Klassifikation als 0, wenn der Wert nahe1Wir betrachten dies als eine Klassifikation zu1.

Wie setzen wir es in die Funktion ein? Tatsächlich genügt es, es einfach hinzuzufügen, denn wenn z z ständig wächst oder abnimmt, nähert sich der Wert der Funktion entsprechend dem Wert.1oder 0. Wir machen z = x0+x1+x2z = x0+x1+x2

Aber in der Realität gibt es einen Fehler zwischen unserem Berechnungsergebnis und dem tatsächlichen Klassifikationswert, der sogar vollkommen falsch sein kann. Um dieses Problem zu korrigieren, stellen wir für den Samplebereich3eine Eigenwert X0X0, X1X1和X2X2, definiert eine Regressionskoeffizienten w0w0, w1w1und w2w2, damit dieser Fehler verringert wird. Selbst wenn z = w0x0+w1x1+w2x2

Es ist nicht schwer vorzustellen, dass der Wert dieser Gruppe von w w-Regressionskoeffizienten die Genauigkeit unserer Berechnungsergebnisse, ja sogar ihre Richtigkeit, bestimmt. Das bedeutet, dass dieser Wert der w w-Werte die Klassifikationsregeln im Samplebereich widerspiegelt.
Wenn wir außer einem Satz von Eingabesamples Daten hinzufügen, können wir durch die korrekten w w-Regressionskoeffizienten ein Klassifikationsergebnis erhalten, das der Klassifikationsregel im Samplebereich recht nahe kommt.
Nun stellt sich die Frage, wie wir solch eine Gruppe von w w-Regressionskoeffizienten erhalten können?

Drei, Gradientenaufstiegsmethode

Die Methode des Gradientenauftstiegs führt Iterationen zur Berechnung der Parameterwerte in der Richtung des Gradienten der Funktion, um den größten Parameterwert zu finden. Die Iterationsformel lautet wie folgt:

Dabei ist αα der Schrittweite, Δσ(w)Δσ(w) der Gradient der σ(w)σ(w)-Funktion. Nähere Informationen zur Ableitung des Gradienten finden Sie inHier. Die mathematische Fähigkeit des Autors ist begrenzt, daher erfolgt keine Erklärung.

Am Ende können wir die Berechnungsformel für die Gradienten erhalten:

Daher lautet die Iterationsformel wie folgt:

Formelbeschreibung:

wk+1wk+1wkwk ist das Regressionskoeffizientenergebnis des XX-Funktionselements in dieser Iteration
wkwk ist das Regressionskoeffizientenergebnis des XX-Funktionselements im vorherigen Durchlauf
αα ist der Schrittweite, um in jede Iteration in die Gradientenrichtung zu bewegen
xixi ist der i-te Element des XX-Funktionselements
yiyi ist der Klassifikationsergebniswert des i-ten Datensatzes im Sample
σ(xi,wk)σ(xi,wk) ist der Klassifikationsergebniswert des i-ten Datensatzes im Sample, der durch die sigmoid-Funktion und wkwk als Regressionskoeffizienten berechnet wird
[yi−σ(xi,wk)][yi−σ(xi,wk)] ist der Klassifikationsergebniswert des i-ten Datensatzes im Sample, der als Fehlerwert des Klassifikationsergebniswerts berechnet wird, der durch die sigmoid-Funktion mit wkwk als Regressionskoeffizienten verwendet wird.

Nun haben wir die Formel für die Berechnung der Regressionskoeffizienten, und wir implementieren in der Datei logRegres.py eine Funktion, um die Regressionskoeffizienten des Sampleraums zu berechnen und die Ergebnisse auszugeben:

def gradAscent(dataMatIn, classLabels):
 dataMatrix = mat(dataMatIn)    #100 Zeile3Spalte
 #print dataMatrix
 labelMat = mat(classLabels).transpose() #100 Zeile1Spalte
 #print 'labelMat:\n',labelMat
 print 'labelMat Form: rowNum=',shape(labelMat)[0],'colNum=',shape(labelMat)[1]
 rowNum,colNum = shape(dataMatrix)
 alpha = 0.001
 maxCycles = 500
 weights = ones((colNum,1)) #3Zeile1Spalte
 #print shape(dataMatrix)
 #print shape(weights)
 #print shape(labelMat)
 for k in range(maxCycles):    #starke Matrixoperationen
  h = sigmoid(dataMatrix*weights)  #100 Zeile1Spalte
  #print h
  error = (labelMat - h)    #vektorische Subtraktion
  weights = weights + alpha * dataMatrix.transpose()* Fehler #3Zeile1Spalte
 return weights
if __name__=='__main__':
 dataMat,labelMat=loadDataSet()
 #weights=gradAscent(dataMat,labelMat)
 #print 'dataMat:\n',dataMat
 #print 'labelMat:\n',labelMat
 print weights

Druckergebnis:

Regressionskoeffizienten:
[[ 4.12414349]
 [ 0.48007329]
 [-0.6168482 ]]

Um die Genauigkeit des berechneten回顾系数 zu überprüfen, betrachten wir die Streudiagramme des Sampleraums und die Anpassungskurven der Regressionskoeffizienten. Wir verwenden z(x1,x2)=w0+w1x1+w2x2作为我们的拟合函数,在坐标系中画出它的拟合曲线。以样本空间中X1X1和X2X2的值作为横坐标和纵坐标,画出样本空间的散点。代码如下:

def plotBestFit(weights):
 import matplotlib.pyplot as plt
 dataMat,labelMat=loadDataSet()
 dataArr = array(dataMat)
 n = shape(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])
  else:
   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])
  else:
   test.append(dataMat[i])
   test_label.append(labelMat[i])
 weights=gradAscent(exam,exam_label)
 errCnt=0
 trow,tcol=shape(test)
 for i in range(trow):
  v=int(classify0(test[i],weights))
  if v != int(test_label[i]):
   errCnt += 1
   print 'Berechneter Wert:', v, ' Ursprungswert', test_label[i]
 print 'Fehlerquote:', errCnt/trow
if __name__=='__main__':
 #dataMat,labelMat=loadDataSet()
 #weights=gradAscent(dataMat,labelMat)
 ##print 'dataMat:\n',dataMat
 ##print 'labelMat:\n',labelMat
 #print 'Regressionskoeffizienten:\n',weights
 #plotBestFit(weights)
 testClassify0()

Die Implementierung des Klassifizierers ist einfach. Wir verwenden die Beispieldaten aus7Daten als Testdatensatz verwendet, um die Regressionskoeffizienten zu berechnen. Anschließend wird der Klassifizierer auf die verbleibenden30 Daten als Testdatensatz verwendet, um die Regressionskoeffizienten zu berechnen. Anschließend wird der Klassifizierer auf die verbleibenden

Ist das Problem hier gelöst? Es scheint, als ob noch etwas fehlt. Lassen Sie uns unsere Methode zur Berechnung der Regressionskoeffizienten genauer untersuchen. Man kann leicht erkennen, dass wir in diesem Prozess eine Matrix aus Beispieldaten verwendet haben, um eine Matrixmultiplikation durchzuführen. Das bedeutet, um die Regressionskoeffizienten zu berechnen, haben wir das gesamte Beispieldatensatz durchsucht.

Unser Problem ist wieder da, die Beispieldaten in unserem Beispiel sind nur100 Einträge, wenn wir Tausende oder Zehntausende von Beispieldaten verarbeiten, steigt die Komplexität unserer Funktion zur Berechnung der Regressionskoeffizienten exponentiell. Lassen Sie uns nun sehen, wie wir diesen Algorithmus optimieren können.

Vier: Optimierung des GradientensteigungsAlgorithmus - Zufälliger GradientensteigungsAlgorithmus

nachdem wir die Formel zur iterativen Berechnung der Regressionskoeffizienten verstanden haben

und unsere umgesetzte Programm. Wir verbessern die Methode zur Berechnung der Regressionskoeffizienten wie folgt:

def stocGradAscent0(dataMatrix, classLabels):
 m,n = shape(dataMatrix)
 alpha = 0.01
 weights = ones((n,1)) #initialize to all ones
 for i in range(m):
  h = sigmoid(sum(dataMatrix[i))*weights))
  error = classLabels[i] - h
  weights = weights + alpha * Fehler * mat(dataMatrix[i]).transpose()
 return weights

In each iteration, when calculating the regression coefficient, only one sample point in the sample space is used to calculate. Let's take a look at the accuracy of this algorithm through a sample scatter plot and a fitting curve generated by the program:

It is not difficult to see that there is still a considerable difference from the previous algorithm. The reason is that the previous algorithm was through500 iterations calculated results, the latter only passed100 iterations. The problem to be explained here is that the regression coefficient tends to converge with the increase of the number of iterations, and the convergence process has fluctuations. In short, the more iterations, the closer to the desired value, but due to the non-linear nature of the sample data, there will also be some errors in this process. The specific relationship between the regression coefficient and the number of iterations can be referred to in some textbooks, such as the description in 'Machine Learning in Action', and will not be introduced in detail here.
Here, we only introduce how to improve our algorithm so that our algorithm can converge quickly and reduce fluctuations. The method is as follows:

In each iteration, a random sample point is randomly selected to calculate the regression vector
The step size of iteration decreases continuously with the increase of the number of iterations, but it is never equal to 0

Improved code, and print the fitting curve and sample scatter plot:

def stocGradAscent1(dataMatrix, classLabels, numIter=150):
 m,n = shape(dataMatrix)
 weights = ones((n,1)) #initialize to all ones
 for j in range(numIter):
  dataIndex = range(m)
  for i in range(m):
   alpha = 4/(1.0+j+i)+0.0001 #alpha decreases with iteration, does not 
   randIndex = int(random.uniform(0,len(dataIndex)))#go to 0 because of the constant
   h = sigmoid(sum(dataMatrix[randIndex]*weights))
   error = classLabels[randIndex] - h
   weights = weights + alpha * Fehler * 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 'Regressionskoeffizienten:\n',weights
 plotBestFit(weights)
 #testClassify0()

Standardmäßig ist150-Iterationen-Sample-Scatterplot und Anpassungskurvenplot:

Es ist nicht schwer zu erkennen, dass die Genauigkeit mit dem ersten Algorithmus sehr ähnlich ist!

V. Zusammenfassung

Der Logistic-Regressions-Algorithmus nutzt hauptsächlich die Sigmoid-Funktion, um Daten zu klassifizieren. Die Genauigkeit der Klassifizierung hängt entscheidend von den Regressionskoeffizienten ab, die aus dem Sample-Raum berechnet werden. Wir verwenden das Gradientensteigungsverfahren, um die Regressionskoeffizienten zu berechnen und verbessern die Leistung des Algorithmus durch das stochastische Gradientensteigungsverfahren.

Das ist alles, was in diesem Artikel über die Beschreibung des Logistic-Regressions-Algorithmus in Python für maschinelles Lernen gesagt wird. Hoffentlich ist es für alle nützlich. Freunde, die interessiert sind, können weiterhin andere Artikel über Python undAlgorithmenVerwandte Themen, wenn es Mängel gibt, freuen wir uns auf Ihre Kommentare. Vielen Dank, dass Sie die Unterstützung dieser Website zeigen!

Erklärung: Der Inhalt dieses Artikels wurde aus dem Internet übernommen und gehört dem Urheber. Der Inhalt wurde von Internetnutzern freiwillig beigesteuert und hochgeladen. Diese Website besitzt keine Eigentumsrechte und hat den Inhalt nicht manuell bearbeitet. Sie übernimmt auch keine rechtlichen Verantwortlichkeiten. Wenn Sie urheberrechtlich relevante Inhalte entdecken, sind Sie herzlich eingeladen, eine E-Mail an notice#w zu senden.3codebox.com (Bitte ersetzen Sie # durch @, wenn Sie eine Meldung senden, um Missbrauch zu melden, und fügen Sie relevante Beweise bei. Sobald nachgewiesen, wird diese Website die beanstandeten urheberrechtlichen Inhalte sofort löschen.)

Dir gefällt bestimmt