English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Questo documento introduce l'algoritmo di regressione logistica nel machine learning, utilizziamo questo algoritmo per classificare i dati. L'algoritmo di regressione logistica è anche un algoritmo di apprendimento supervisionato che necessita di uno spazio di campione e si adatta a dati numerici e nominali, ad esempio, dobbiamo giudicare se i dati appartengono a una certa classe o meno in base alla grandezza dei valori delle caratteristiche di input (numerici).
1. Dati di campione
Nello nostro esempio, abbiamo i seguenti dati di campione:
I dati di campione hanno tre valori di caratteristica: X0, X1, X2
Judichiamo se i dati corrispondono ai requisiti attraverso i tre valori di caratteristica X1 e X2, quelli che corrispondono sono 1 e quelli che non corrispondono sono 0.
I dati di campione di classificazione sono conservati in un array
Nella file logRegres.py scriviamo la seguente funzione per preparare i dati e visualizzarli:
#coding=utf-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[0]), float(lineArr[1])]) labelMat.append(int(lineArr[2])) return dataMat,labelMat if __name__=='__main__': dataMat,labelMat=loadDataSet() print 'dataMat:\n',dataMat
Osserviamo il seguente campione di dati:
dataMat: L'elenco seguente contiene i valori: [[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]
La prima colonna dei dati di campione dataMat, ossia il valore delle caratteristiche X0, è interamente 1. Questo problema dobbiamo tenerlo a mente quando calcoliamo i parametri di regressione. Tutti i dati di campione sono in totale 100, e i risultati di classificazione corrispondenti sono anche 100.
Allora, il nostro problema attuale è:
Dobbiamo trovare la relazione tra i valori delle caratteristiche nello spazio dei campioni e i risultati di classificazione. Progettiamo una funzione o una funzionalità che, dopo aver inserito un insieme di valori delle caratteristiche, classifichi automaticamente i dati in input in base alla relazione tra i valori delle caratteristiche nello spazio dei campioni e i risultati di classificazione, ovvero il risultato è 1 o 0.
Secondo, la funzione Sigmoid
Per risolvere il problema menzionato nella sezione precedente, presentiamo prima la funzione Sigmoid:
Questa funzione ha le seguenti caratteristiche:
Quando z=0, il valore è 0.5
Quando zz aumenta continuamente, il valore si avvicina a 1
Quando z diminuisce continuamente, il valore si avvicina a 0
Vediamo la curva della funzione:
Se inseriamo i valori dei tre valori di caratteristica X0 X0, X1 X1 e X2 X2 dello spazio dei campioni nella funzione e calcoliamo un risultato, questo risultato sarà vicino al nostro risultato di classificazione (un valore tra 0 e 1). Se questo risultato è vicino a 0, pensiamo che la classificazione sia 0, se il risultato è vicino a 1, pensiamo che la classificazione sia 1.
Come possiamo inserire questo valore in funzione? In realtà, possiamo sommarli semplicemente, perché quando z aumenta o diminuisce, il valore della funzione si avvicina a 1 o 0. Facciamo z = x0 + x1 + x2
Ma nella realtà, i nostri risultati di calcolo e i valori di classificazione effettivi avranno un errore, persino completamente inesatti. Per correggere questo problema, definiamo un coefficiente di regressione w0 w0, w1 w1 e w2 w2 per i tre valori di caratteristica X0 X0, X1 X1 e X2 X2 dello spazio dei campioni, per ridurre l'errore. Anche se z = w0x0 + w1x1 + w2x2
In realtà, non è difficile immaginare che il valore di questo gruppo di coefficienti di regressione w w determini l'accuratezza dei nostri risultati di calcolo, persino la correttezza. Vale a dire, questo gruppo di valori w w riflette le regole di classificazione dello spazio dei campioni.
Quindi, quando introduciamo dati oltre ai campioni di input, possiamo ottenere risultati di classificazione più vicini alle regole di classificazione dello spazio dei campioni con i coefficienti di regressione w w corretti.
Ma come possiamo ottenere questo gruppo di coefficienti di regressione w w?
Terza sezione: metodo di ascensione della derivata
Il metodo di ascensione della derivata è iterare continuamente il calcolo dei valori dei parametri nella direzione della derivata della funzione per trovare un valore di parametri massimo. La formula dell'iterazione è come segue:
Dove α è la lunghezza del passo, Δσ(w) è la derivata della funzione σ(w)σ(w). Per la derivazione della derivata, si prega di consultareEcco:. La capacità matematica dell'autore è limitata, quindi non fornirò spiegazioni.
Infine, possiamo ottenere la formula del calcolo della derivata:
Quindi, la formula dell'iterazione è come segue:
Spiegazione della formula:
wk+1 è il risultato del coefficiente di regressione del campione XX dell'iterazione corrente.
wk è il risultato del coefficiente di regressione del campione XX dell'iterazione precedente.
α è la lunghezza del passo spostato nella direzione della derivata in ogni iterazione.
xi è l'i-esimo elemento dell'elemento di caratteristica XX.
yi è il risultato della classificazione del campione per la registrazione i-esima.
σ(xi,wk)σ(xi,wk) è il valore di risultato della classificazione calcolato per la registrazione i-esima del campione utilizzando la funzione sigmoid e wk come coefficiente di regressione.
[yi−σ(xi,wk)][yi−σ(xi,wk)] è il valore di risultato della classificazione corrispondente alla registrazione i-esima del campione, con un errore rispetto al valore di risultato della classificazione calcolato utilizzando la funzione sigmoid con wk come coefficiente di regressione.
Ora, abbiamo la formula per calcolare i coefficienti di regressione, quindi nel file logRegres.py implementeremo una funzione per calcolare i coefficienti di regressione dello spazio dei campioni e stampare i nostri risultati:
def gradAscent(dataMatIn, classLabels): dataMatrix = mat(dataMatIn) #100 riga 3 colonna #print dataMatrix labelMat = mat(classLabels).transpose() #100 riga 1 colonna #print 'labelMat:\n',labelMat print 'La forma di labelMat:rowNum=',shape(labelMat)[0],'colNum=',shape(labelMat)[1] rowNum,colNum = shape(dataMatrix) alpha = 0.001 maxCycles = 500 weights = ones((colNum,1)) #3 riga 1 colonna #print shape(dataMatrix) #print shape(weights) #print shape(labelMat) for k in range(maxCycles): #operazioni matematiche su matrici pesanti h = sigmoid(dataMatrix*weights) #100 riga 1 colonna #print h error = (labelMat - h) #sottrazione vettoriale weights = weights + alpha * dataMatrix.transpose()* error #3 riga 1 colonna return weights if __name__=='__main__': dataMat,labelMat=loadDataSet() #weights=gradAscent(dataMat,labelMat) #print 'dataMat:\n',dataMat #print 'labelMat:\n',labelMat print weights
Stampa il risultato:
Coefficiente di regressione: [[ 4.12414349] [ 0.48007329] [-0.6168482 ]]
Per verificare l'accuratezza dei coefficienti di retroazione calcolati, osserviamo il grafico dei punti sparsi dello spazio di campione e la curva di adattamento dei coefficienti di regressione. La nostra funzione di adattamento è z(x1,x2)=w0+w1x1+w2x2, e tracciamo la curva di adattamento nel sistema di coordinate. Utilizziamo i valori di X1X1 e X2X2 nello spazio di campione come ascissa e ordinata per tracciare i punti sparsi dello spazio di campione. Il codice è il seguente:
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 'Coefficiente di regressione:\n',weights plotBestFit(weights)
Dopo l'esecuzione, otteniamo l'immagine seguente:
Secondo le nostre osservazioni, l'algoritmo della nostra regressione coefficienti è piuttosto accurato, la curva di adattamento divide i dati di campione in due parti e segue le regole di classificazione del campione.
In questo articolo, implementeremo un classificatore e lo testeremo:
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 'Valore calcolato: ',v,' Valore originale',test_label[i] print 'Tasso di errore: ',errCnt/trow if __name__=='__main__': #dataMat,labelMat=loadDataSet() #weights=gradAscent(dataMat,labelMat) ##print 'dataMat:\n',dataMat ##print 'labelMat:\n',labelMat #print 'Regression coefficients:\n',weights #plotBestFit(weights) testClassify0()
La realizzazione del classificatore è semplice. Utilizziamo 70 dati di campione precedenti come dati di campione di test per calcolare i coefficienti di regressione. Poi utilizziamo il classificatore per classificare i restanti 30 record e confrontare i risultati con i dati di campione. Infine, stampiamo il tasso di errore. Possiamo vedere che il tasso di errore è 0, quasi perfetto! Possiamo modificare la proporzione di test sample nello spazio di campione originale e testare più volte. La conclusione è che l'accuratezza del nostro algoritmo è abbastanza buona!
Allora, il problema è risolto qui? Sembra mancare qualcosa. Studiamo attentamente il nostro metodo di calcolo dei coefficienti di regressione e non è difficile notare che in questo processo abbiamo utilizzato il prodotto di matrice di dati di campione. Questo significa che per calcolare i coefficienti di regressione, abbiamo esaminato tutti i dati di campione.
Torniamo al nostro problema, i dati di campione nel nostro esempio hanno solo 100 voci. Se dobbiamo trattare centinaia di migliaia di dati di campione, la complessità del calcolo dei coefficienti di regressione aumenterà linearmente. Vediamo come ottimizzare questo algoritmo.
Quarto, ottimizzazione dell'algoritmo di salita di gradiente - metodo di salita di gradiente casuale
abbiamo capito l'equazione iterativa di calcolo dei coefficienti di regressione
evidentemente, dopo aver implementato il nostro programma. Improveremo il metodo di calcolo dei coefficienti di regressione nel modo seguente:
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 * error * mat(dataMatrix[i]).transpose() return weights
Ogni volta che si calcola il coefficiente di regressione durante l'iterazione, si utilizza solo un punto campione dello spazio dei campioni. Vediamo la precisione dell'algoritmo attraverso un grafico di dispersione dei campioni e della curva di adattamento generata dal programma:
Non è difficile notare che c'è una differenza abbastanza grande rispetto all'algoritmo precedente. Il motivo è che l'algoritmo precedente ha calcolato i risultati in 500 iterazioni, mentre il secondo solo in 100 iterazioni. Pertanto, è necessario chiarire che i coefficienti di regressione tendono a convergere man mano che aumenta il numero di iterazioni e il processo di convergenza ha oscillazioni. In altre parole, più iterazioni si eseguono, più ci si avvicina al valore desiderato, ma a causa dei dati campione non lineari, c'è anche un errore in questo processo. La relazione tra i coefficienti di regressione e il numero di iterazioni può essere consultata in alcuni testi di riferimento, come la descrizione in 'Machine Learning in Action', senza ulteriori dettagli.
In questo articolo, spieghiamo come migliorare il nostro algoritmo per farlo convergere rapidamente e ridurre le oscillazioni. Il metodo è il seguente:
In ogni iterazione, viene estratto a caso un punto campione per calcolare il vettore di regressione
La lunghezza del passo iterativo diminuisce man mano che aumenta il numero di iterazioni, ma mai uguale a 0
Migliorare il codice e stampare la curva di adattamento e il grafico dei punti campione:
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 * error * 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 'Regression coefficients:\n',weights plotBestFit(weights) #testClassify0()
Default is 150 iterations scatter plot and fitting curve:
It is not difficult to see that the accuracy is very close to the first algorithm!
Summary
The Logistic regression algorithm mainly uses the Sigmoid function to classify data, and the key to the accuracy of classification depends on the regression coefficients calculated from the sample space. We use the gradient ascent method to calculate the regression coefficients, and adopt the stochastic gradient ascent method to improve the performance of the algorithm.
This is the full content of this article about the description of machine learning Logistic regression algorithm in Python language, I hope it will be helpful to everyone. Those who are interested can continue to read other Python andAlgorithmRelated topics, if there are any deficiencies, please leave a message to point them out. Thank you friends for your support to this site!
Declaration: The content of this article is from the network, the copyright belongs to the original author, the content is contributed and uploaded by Internet users spontaneously, this website does not own the copyright, does not edit manually, nor does it bear relevant legal liability. If you find any content suspected of copyright infringement, please send an email to: notice#oldtoolbag.com (when sending an email, please replace # with @) to report it, and provide relevant evidence. Once confirmed, this site will immediately delete the suspected infringing content.