[PYTHON] Implementierung der logistischen Regression mit Partikelgruppenoptimierungsmethode

Ich habe vor einiger Zeit in diesem Artikel einen genetischen Algorithmus geschrieben, aber diesmal habe ich versucht, einen Optimierungsalgorithmus zu erstellen, der mit derselben Idee erstellt wurde.

Was ist Partikelgruppenoptimierung?

Ich sehe oft Fische und Vögel, die sich in Gruppen bewegen. Selbst wenn diese Schwärme Feinde oder Nahrung finden, führen sie optimale Bewegungen mit ungestörten Bewegungen aus. Es ist eine Methode, dies zur Funktionsoptimierung zu nutzen.

Referenzen gibt es hier Einführung in den evolutionären Berechnungsalgorithmus Partikelgruppenoptimierung und nichtlineares System

Implementierung

Ich habe nichts Kompliziertes getan und es auf einfachste Weise implementiert.

functions.py


import random

# min~Zahlen Sie zufällig zwischen max
def randRange(a : float,b : float) -> float:
    return a + (b-a)*random.random()

#Erzeugen Sie n Partikel

def makeParticles(n : int,ranges : dict) -> list:
    ls = [{key:0 for key in ranges.keys()} for key in range(n)]
    for i in range(n):
        for key in ranges.keys():
            a,b = ranges[key]
            ls[i][key] = randRange(a,b)
    return ls

#Fügen Sie die gleichen Elemente von zwei Diktaten hinzu
def dictAdd(*dic : dict) -> dict:
    ansDic = {}
    for key in dic[0].keys():
        ansDic[key] = 0
        for i in range(len(dic)):
            ansDic[key] += dic[i][key]
    return ansDic

#Subtrahieren Sie die gleichen Elemente von zwei Diktaten
def dictDiff(dic1 : dict,dic2 : dict) -> dict:
    ansDic = {}
    for key in dic1.keys():
        ansDic[key] = dic1[key] - dic2[key]
    return ansDic

#Produkt der gleichen Elemente von zwei Diktaten
def dictMul(dic1 : dict, dic2 : dict) -> dict:
    ansDic = {}
    for key in dic1.keys():
        ansDic[key] = dic1[key] * dic2[key]

#Multiplizieren Sie jedes Element des Diktats
def dictNumMul(dic : dict,n) -> dict:
    ansDic = {}
    for key in dic.keys():
        ansDic[key] = dic[key] * n
    return ansDic

PSO.py


import functions as func
import numpy as np
import copy

"""
time_max Maximale Anzahl von Iterationen
swam_Größe Anzahl der Partikel
Trägheit Trägheitskoeffizient
ap Persönlicher bester Beschleunigungskoeffizient
ag Global Best Acceleration Factor
"""


class PSO:
    def __init__(self,time_max = 1000,swam_size = 100,
                inertia = 0.9,ap = 0.8,ag = 0.8):
        self.time_max = time_max
        self.swam_size = swam_size
        self.inertia = inertia
        self.ap = ap
        self.ag = ag
        self.pBest = [np.inf for i in range(swam_size)]
        self.gBest = np.inf
        self.gPosi = {}

    """
Übergeben Sie die zu minimierende Funktion an das Argument f der Optimierungsfunktion
Dikt für Para-Argument
    {"Argumentname":[Mindestwert,Maximalwert]}
Ich gebe es so weiter.
    """
    #Erhalten Sie die zu optimierende Funktion und ihre Argumente
    def optimize(self,f,para):
        self.function = f
        self.particleInitialization(para)
        self.Update()
        for i in range(self.time_max):
            self.move()
            self.Update()
        return self.gPosi,self.gBest

    #Initialisieren Sie die Partikel
    def particleInitialization(self,ls : dict):
        self.particle = func.makeParticles(self.swam_size,ls)
        self.pPosi = copy.deepcopy(self.particle)
        self.velocity = [{key:0 for key in ls.keys()} for i in range(self.swam_size)]

    #Bewegung
    def move(self):
        for i in range(self.swam_size):
            v0 = func.dictNumMul(self.velocity[i],self.inertia)
            v1 = func.dictNumMul(func.dictDiff(self.pPosi[i],self.particle[i]),self.ap*func.randRange(0,1))
            v2 = func.dictNumMul(func.dictDiff(self.gPosi,self.particle[i]),self.ag*func.randRange(0,1))
            v = func.dictAdd(v0,v1,v2)
            self.particle[i] = func.dictAdd(self.particle[i],v)
            self.velocity[i] = v

    #Aktualisieren Sie die persönliche Bestleistung und die globale Bestleistung
    def Update(self):
        for i in range(self.swam_size):
            cost = self.function(**self.particle[i])
            if cost < self.pBest[i]:
                self.pBest[i] = cost
                self.pPosi[i] = copy.deepcopy(self.particle[i])
            if cost < self.gBest:
                self.gBest = cost
                self.gPosi = copy.deepcopy(self.particle[i])

Versuchen Sie es mit

main.py


import PSO

#Definieren Sie die Funktion, die Sie minimieren möchten

def f(x,y):
    return x**4+4*x**3-8*(x+1)**2-1 + y**4 + x**3 - 5*(y - 2)**2 - 3*x
def main():
    pso = PSO.PSO(time_max=1000)
    #Frühe Partikel-10000<x<10000,-10000<y<Generieren Sie im Bereich von 10000 und minimieren Sie
    a,b = pso.optimize(f,{"x":[-10000,10000],"y":[-10000,10000]})
    print("Koordinate",a,"Mindestwert",b)

if __name__ == "__main__":
    main()

Ausgabe Koordinaten {'x': -4.412547925687121, 'y': -2.187602966185929} Mindestwert -196.17514912856427

Ich konnte es minimieren.

[Ergebnisse mit wolframalpha](https://www.wolframalpha.com/input/?i=minimize%5Bx%5E4%2B4x%5E3-8%28x%2B1%29%5E2-1+%2B+ y% 5E4 +% 2B + x% 5E3 + - + 5 *% 28y + - + 2% 29% 5E2 + - + 3 * x% 5D)

Nachtrag

Bis zu diesem Zeitpunkt habe ich es hochgeladen, aber es ist wirklich langweilig. Daher möchte ich eine logistische Regression mithilfe der Partikelgruppenoptimierungsmethode durchführen.

Hier wird die Klassifizierungsgrenze durch Minimieren der Kreuzentropiefehlerfunktion durch das Partikelgruppenoptimierungsverfahren vorhergesagt.

logistic.py


import functions as func
import math
import PSO
import numpy
#Grenze beim Beschriften generierte Zufallszahlen
def f(x,y):
    if x + 2 * y < 11:return 1
    else:return 0

#Sigmaid-Funktion
def sigmoid(x):
    if 600 > x > -600:
        return 1/(1 + math.exp(-x))
    elif x > 0:
        return 1
    else:
        return 0

#Unendlich zurückgeben, wenn es Null ist
def llog(x):
    if x == 0:
        return -numpy.inf
    return math.log(x)

#Generieren Sie Daten mit Zufallszahlen
data = [[func.randRange(0,10),func.randRange(0,10)] for i in range(100)]
label = [f(x,y) for x,y in data]

#Kostenfunktion zu minimieren
def loss(w1,w2,b):
    ent = 0
    for i in range(len(data)):
        x = sigmoid(data[i][0]*w1 + data[i][1]*w2 + b)
        y = label[i]
        ent -= y * llog(x) + (1-y) * llog(1-x)
    return ent

def main():
    pso = PSO.PSO()
    a,b = pso.optimize(loss,{"w1":[-100,100],"w2":[-100,100],"b":[-100,100]})
    print(a,b)

    #Bewerten Sie, ob das erstellte Modell die Trainingsdaten richtig klassifizieren kann
    c = 0
    for i in range(100):
        n = sigmoid(data[i][0]*a["w1"] + data[i][1]*a["w2"] + a["b"])
        ans = 1 if n > 0.5 else 0
        if ans == label[i]:
            c += 1
    print("Klassifizierungsgenauigkeit",c/100)

if __name__ == "__main__":
    main()

Ergebnis

{'w1': -5.345994566644921, 'w2': -10.19111400412491, 'b': 56.97834543330356} 2.744570556357321 Klassifizierungsgenauigkeit 1.0

Ich konnte es fest einordnen.

Recommended Posts

Implementierung der logistischen Regression mit Partikelgruppenoptimierungsmethode
Informationen zu Parametern der Partikelgruppenoptimierung (PSO)
Implementierung der logistischen Regression mit NumPy
Logistische Regressionsanalyse Selbst erstellt mit Python
PRML Kapitel 4 Bayesianische logistische Regression Python-Implementierung
Logistische Rückgabe
Logistische Rückgabe
Probieren Sie Theano mit Kaggles MNIST-Daten ~ Logistic Return ~ aus
Implementieren Sie mit stan ein zeitdiskretes logistisches Regressionsmodell
Methode der Regressionsanalyse
Implementierung der Gradientenmethode 1
Vorsichtsmaßnahmen bei der Durchführung einer logistischen Regression mit Statsmodels
Lösen des Irisproblems mit scikit-learn ver1.0 (logistische Regression)