유전 알고리즘이란?

유전 알고리즘은 다윈의 ‘적자생존’의 개념을 최적화 문제를 해결하는데 적용한 것이다. 생물체가 적응하면서 진화해가는 것을 모방하여 최적해를 찾는 방법이다.

알고리즘 구성

  1. 초기 후보해 집합을 생성
  2. 선택 연산
  3. 교차 연산
  4. 돌연변이 연산

사용할 데이터셋

유전 알고리즘으로 예측하기

데이터 가져오기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# ----------------주어진 데이터셋--------------------
f = open('Tesla.csv', 'r')
rdr = csv.reader(f)

arr = []
arr2 = []
arr3 = []

for line in rdr:
    # Open
    arr.append(float(line[1]))
    # High
    arr2.append(float(line[2]))
    # Low
    arr3.append(float(line[3]))

# High와 Low의 평균값
avg = []
for i in range(len(arr2)):
    av = (arr2[i] + arr3[i]) / 2
    avg.append(float(av))

초기 후보해 집합을 생성

1
2
3
4
Openmin = 2
Openmax = 300
Avgmin = 2
Avgmax = 300
1
2
3
# 초기 식 y = ax
def expression(t, h):
    return h / t
1
2
3
4
5
6
7
8
9
# 초기 a 4개 구하기
def init(Open1, Open2, Avg1, Avg2):
    a = []
    for i in range(4):
        OPEN = rn.randint(Open1, Open2)
        AVG = rn.randint(Avg1, Avg2)

        a.append(math.ceil(expression(OPEN, AVG)))
    return a

선택 연산

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 선택 연산
def selection(Aarr):
    ratio = []
    for i in range(4):
        if i == 0:
            ratio.append(Aarr[0] / sum(Aarr))
        else:
            ratio.append(ratio[i - 1] + Aarr[i] / sum(Aarr))

    sx = []
    for i in range(4):
        p = rn.random()
        if p < ratio[0]:
            sx.append(Aarr[0])
        elif p < ratio[1]:
            sx.append(Aarr[1])
        elif p < ratio[2]:
            sx.append(Aarr[2])
        else:
            sx.append(Aarr[3])
    return sx

교차 연산

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# bin() format
def binformat(x):
    binformat = '{0:>8}'.format(bin(x)).replace("b", "0").replace(" ", "0").replace("-", "0")
    return binformat


# int to binary
def int2Bin(str):
    binlist = []
    for i in range(4):
        binsrting = binformat(str[i])
        binlist.append(binsrting)
    return binlist

1
2
3
4
5
6
7
8
9
10
11
12
# 교차 연산
def crossover(arr):
    strarr = []
    for i in range(2):
        bita = str(arr[i])
        bitb = str(arr[i + 1])

        strarr.append(bita[:5] + bitb[5:])
        strarr.append(bitb[:5] + bita[5:])

    return strarr

돌연변이 연산

1
2
3
4
5
6
7
8
9
# 돌연변이 한 값 저장하기
def mutation(mut):
    mutarr = []
    mutint = list(map(str, mut))
    for i in range(4):
        mutinv = float(invert(mutint[i]))
        mutarr.append(mutinv)
    return mutarr

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 돌연변이 연산
def invert(char):
    ran = rn.random()
    a = int(char, 2)  # 숫자
    b = int("1000", 2)

    for i in range(5):
        p = 1 / 30
        if ran < p:
            if char[4:5] == "1":
                aa = a - b

            elif char[4:5] == "0":
                aa = a + b
            return aa
        return a

데이터 산점도

# pandas library로 DataFrame 지정

MSEGrapg = pd.DataFrame(
{"aValue": x, "MSE": y}
)

OpPrice = pd.DataFrame(
{"temp": arr, "hum": avg}
)

predictgraph = pd.DataFrame(
{"temp2": RanOpenprice, "hum2": yPredict}
)

# 그래프 그리기

plt.figure()

# 기존 데이터의 그래프를 그린다

one = plt.scatter(OpPrice['temp'], OpPrice['hum'], marker="o")

# 예측된 기울기로 그래프를 예측한다.

two = plt.scatter(predictgraph["temp2"], predictgraph["hum2"], marker="x")
plt.legend(handles=(one, two), labels=("Initial data", "predicted data"), loc="upper left")
plt.xlabel('Open_Price')
plt.ylabel('Average_Price')
plt.savefig("Tesla.png")

plt.figure()

# MSE 평가지표 그래프

MSEleg = plt.scatter(MSEGrapg['aValue'], MSEGrapg['MSE'], marker="o")
plt.xlabel('Inclination')
plt.ylabel('MSE')
plt.savefig("TeslaMSE.png")

# 그래프 띄우기

plt.show()

산점도 사진.png

MSE(평균 제곱 오차)

MSE 그래프

출력한 값들이다.

init: [35, 2, 4, 1]
selection: [35, 35, 35, 35]
inttobin: ['00100011', '00100011', '00100011', '00100011']
cross: ['00100011', '00100011', '00100011', '00100011']
mutationed: [35.0, 35.0, 35.0, 35.0]
MSEarr: [67913541.24469241, 135827082.48938468, 203740623.734077, 271654164.97876936]
예측된 기울기: 35.0

최소 MSE를 만족하는 기울기: 1.0

정리

code

REFERENCES