linear_regression.py 5.11 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
'''
    # 선형 회귀 분석

    - EUE에서 사용하는 데이터에 맞추어진 Linear Regression Class 입니다.
    - 기존에 진행한 가중치 값이 있는지 확인합니다.
    - 존재하지 않는 다면, 가중치를 초기화 합니다.
    - 초기화 된 가중치와 함께 linear regression을 진행합니다.
'''

import numpy as np


class LinearRegression:
14
    def __init__(self, train_x, train_t, weights=None, bias=None, delta=1e-4, learning_rate=0.05, err_rate=0.01):
15
16
17
        self.train_x = train_x.T    # (n, 10) -> (10, n)
        self.train_t = train_t.T    # (n, 01) -> (01, n)

18
19
        # weights와 bias가 존재하지 않는 경우, 초기화를 위해 bias를 대표로 확인
        if bias == None:
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
            # Initialize Parameters - w : (1, 10), b : float
            self.weights, self.bias = self.initialize(self.train_x)
        else:
            self.weights = weights.T    # (10, 1) -> (1, 10)
            self.bias = bias

        self.delta = delta
        self.learning_rate = learning_rate
        self.err_rate = err_rate

    def initialize(self, x):
        '''
            ### 가중치 및 편향 초기화 함수
            - Weight : (1, m) 꼴의 행렬
            - Bias : 실수
        '''
        weights = np.random.random((1, x.shape[0]))
        bias = np.random.random()
        return weights, bias

    def predict(self, x, w, b):
        '''
            ### 예측값 계산 함수
            - y_hat = x * w + b
            - (1, n) = (1, 10) * (10, n) + (1, n)
        '''
        y_predict = np.dot(w, x) + b
        return y_predict

    def cost_MAE(self, x, y, w, b):
        '''
            ### 비용 함수
52
            - MAE (Mean Absolute Error) : 1/n * sigma|y_i - y_hat_i|
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
        '''
        y_predict = self.predict(x, w, b)
        n = y_predict.shape[1]
        mae = np.sum(np.abs(y - y_predict)) / n
        return mae

    def cost_MSE(self, x, y, w, b):
        '''
            ### 비용 함수 _ MAE
            - MSE (Mean Square Error) : 1/n * sigma(y_i - y_hat_i)^2
        '''
        y_predict = self.predict(x, w, b)
        n = y_predict.shape[1]
        mse = np.sum((y - y_predict)**2) / n
        return mse

    def gradient(self, x, y, delta, w, b):
        '''
            ### 미분 함수
             - 가중치와 편향에 대한 편미분 값 반환
        '''
        loss_w_delta_plus = self.cost_MSE(x, y, w + delta, b)
        loss_w_delta_minus = self.cost_MSE(x, y, w - delta, b)
        w_grad = (loss_w_delta_plus - loss_w_delta_minus) / (2*delta)

        loss_b_delta_plus = self.cost_MSE(x, y, w, b+delta)
        loss_b_delta_minus = self.cost_MSE(x, y, w, b-delta)
        b_grad = np.sum(loss_b_delta_plus - loss_b_delta_minus) / (2*delta)

        return w_grad, b_grad

    def gradientDescent(self):
85
86
87
88
89
90
91
92
        '''
            ### 경사 하강법
            - Linear Regression Class의 주요 동작 함수 입니다.
            - 가중치와 편향을 비용함수에 넘겨준 뒤 손실을 계산합니다.
            - 가중치와 편향의 각각의 편미분 값을 계산합니다.
            - 편미분 값들과 학습률을 이용해 가중치와 편향 값을 갱신 합니다.
            - 위의 과정을 주어진 손실 값 이하가 되거나 3000번 반복 할 때 까지 반복합니다.
        '''
93
94
95
96
97
98
99

        iteration = 0

        w = self.weights
        b = self.bias

        while iteration <= 3000:
100
101
            loss = self.cost_MSE(self.train_x, self.train_t, w, b)

102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
            grad_w, grad_b = self.gradient(
                self.train_x, self.train_t, self.delta, w, b)

            if iteration % 100 == 0:
                print(iteration, " iters - cost :", loss)
                print("Gradients - W :", grad_w, ", b : ", grad_b)
                print("W : ", w)
                print("b : ", b)
                print("\n")

            if loss <= self.err_rate:
                print("At iter NO.{0} stop the process.\nCost : {1}".format(
                    iteration, loss))
                break

            w = w - (self.learning_rate * grad_w)
            b = b - (self.learning_rate * grad_b)

            iteration += 1

        self.weights = w
        self.bias = b


if __name__ == "__main__":
    print("This is test set.")

    x = np.array([[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6],
                  [5, 6, 7], [6, 7, 8]], dtype=float)
    y = np.array([[2], [3], [4], [5], [6], [7]], dtype=float)
    test_model = LinearRegression(
        x, y, None, None, learning_rate=0.0005)

    print("X : ", test_model.train_x)
    print("T : ", test_model.train_t, " Shape : ", test_model.train_t.shape)
    print("W : ", test_model.weights)
    print("b : ", test_model.bias)
    print("delta : ", test_model.delta)
    print("learning rate : ", test_model.learning_rate)
    print("Error Rate : ", test_model.err_rate)

    test_model.gradientDescent()

    print("After L.R.____")
    print("* Costs *\n", test_model.cost_MSE(test_model.train_x,
                                             test_model.train_t, test_model.weights, test_model.bias))
    print("* Weights *\n", test_model.weights)
    print("* Bias *\n", test_model.bias)