preprocessing.py 7.23 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
'''
    # initialize.py

    - Data 전처리를 목적으로 하는 파일입니다.
'''

import os
import datetime
import csv
import numpy as np


13
def loadRawData(link, file_name):
14
    '''
15
        ### CSV 파일의 내용을 반환하는 함수
16
17
18
19
20
21
22
23
24
25
26
27
28
29
        - 제공 받은 링크를 통해 파일을 읽고 반환합니다.
    '''
    raw_data = []
    today = datetime.datetime.today()
    yesterday = today - datetime.timedelta(days=1)

    yMonth = yesterday.month if yesterday.month >= 10 else "0" + \
        str(yesterday.month)
    yDay = yesterday.day if yesterday.day >= 10 else "0"+str(yesterday.day)

    time_dir = "/" + str(yesterday.year) + "/" + \
        str(yesterday.year) + str(yMonth) + "/" + \
        str(yesterday.year) + str(yMonth) + str(yDay)

30
    file_dir = os.getcwd() + link + time_dir + file_name
31

32
33
34
35
36
    if not os.path.isfile(file_dir):
        print("File doesn't exist on {0}".format(file_dir))
        return None

    data_file = open(file_dir, 'r', newline='')
37
38
39
40
41
42
43
44
45
46
47
48
    csv_data = csv.reader(data_file)

    for line in csv_data:
        raw_data.append(line)

    data_file.close()

    return raw_data


def handleUserRawData(user_data):
    '''
49
        ### User Raw Data (CSV 파일 데이터) 가공 함수
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
        - [ 월 / 일 / 시 / 분 / 온도 / 습도 / 광도 ]의 데이터를 변환하는 함수
        - 월 / 일 / 분 제거
        - test_data(분이 제거된 데이터)와 true_data(단위 시간 후 실제 온도)로 나누기
    '''
    user_x = []
    train_t = []

    isFirstLine = True

    for line in user_data:
        _, _, hour, _, temp, humi, lights = line
        user_x.append([int(hour), float(temp), float(humi), float(lights)])
        if isFirstLine:
            isFirstLine = False
        else:
            train_t.append([float(temp)])

    train_t.append(train_t[-1])

    return (user_x, train_t)


def handleOutRawData(out_data):
    '''
74
        ### Out Raw Data (CSV 파일 데이터) 가공 함수
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
        - [ 월 / 일 / 시 / 분 / 온도 / 습도 / 기압 / 풍속 ] 데이터를 변환하는 함수
        - '분' 을 제거합니다.
        - 같은 시각의 데이터들은 평균을 구해서 데이터로 저장합니다.
        - 외부 데이터는 Dictionary Data로 최종 반환됩니다.
        - Dictionary의 Key는 '시'가 됩니다.
    '''

    out_dict = {}
    key = None
    counter = 1

    sum_temp, sum_humi, sum_pressure, sum_wind_speed = 0, 0, 0, 0

    for line in out_data:
        month, day, hour, _, temp, humi, pressure, wind_speed = line

        if key == None:
            key = int(hour)
            counter = 1
            sum_temp, sum_humi, sum_pressure, sum_wind_speed = float(
                temp), float(humi), float(pressure), float(wind_speed)

        if key == hour:
            counter += 1
            sum_temp += float(temp)
            sum_humi += float(humi)
            sum_pressure += float(pressure)
            sum_wind_speed += float(wind_speed)
        else:
            out_dict[key] = [int(month), int(day), key, sum_temp/counter, sum_humi /
                             counter, sum_pressure/counter, sum_wind_speed/counter]

            key = int(hour)
            counter = 1
            sum_temp, sum_humi, sum_pressure, sum_wind_speed = float(
                temp), float(humi), float(pressure), float(wind_speed)

    return out_dict


115
def handleParameters(raw_w):
116
117
118
119
120
    '''
        ### Weights & Bias를 처리하는 함수
        - raw 데이터는 weights와 bias가 합쳐진 상태입니다.
        - raw 데이터를 하나씩 잘라 실수로 변환한 뒤, 마지막의 편향을 잘라냅니다.
    '''
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

    if raw_w == None:
        return None, None

    weights = []

    for line in raw_w:
        for fig in line:
            weights.append([float(fig)])

    bias = weights.pop()[0]

    return weights, bias


136
137
def combineXdata(user_x, out_dict):
    '''
138
        ### 분리된 입력 데이터를 합치는 함수
139
140
141
142
143
144
        - 사용자 데이터와 외부 데이터를 결합해 입력층의 값으로 가공합니다.
    '''
    train_x = []

    for line in user_x:
        hour, temp, humi, lights = line
145
146
147
148
149
150
151
152
153
154
155
156
157

        # 데이터 수집이 균일하게 이루어지지 않은 경우 처리
        if hour in out_dict:
            key_hour = hour
        else:
            minimum = 4
            key_hour = None
            for h in range(hour-3, hour + 3):
                if h in out_dict and abs(h - hour) < minimum:
                    minimum = abs(h-hour)
                    key_hour = h

        x = out_dict[key_hour] + [temp, humi, lights]
158
159
160
161
162
        train_x.append(x)

    return train_x


163
164
165
166
def Xnormalize(data):
    '''
        ### 정규화 함수
        - 입력 층의 데이터를 정규화 시킵니다.
167
        - 월, 일 데이터의 평균과 표준 편차를 계산하여 값을 수정합니다.
168
169
170
171
172
    '''

    normalized_data = data.T   # (n,10) -> (10,n)

    mean = np.mean(normalized_data, axis=1)    # 평균 (10, 1)
173
    std_d = np.std(normalized_data, axis=1)    # 표준편차
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202

    # 월, 일의 평균과 표준편차 지정
    new_mean = []
    for i, fig in enumerate(list(mean)):
        if i == 0:
            new_mean.append(6.5)
        elif i == 1:
            new_mean.append(16.0)
        else:
            new_mean.append(fig)
    new_mean = np.array(new_mean).reshape((-1, 1))

    new_std_d = []
    for i, fig in enumerate(list(std_d)):
        if i == 0:
            new_std_d.append(3.45205253)
        elif i == 1:
            new_std_d.append(8.94427191)
        else:
            new_std_d.append(fig)
    new_std_d = np.array(new_std_d).reshape((-1, 1))

    normalized_data = (normalized_data - new_mean) / new_std_d

    normalized_data = normalized_data.T

    return normalized_data, new_mean, new_std_d


203
204
205
206
207
208
209
def Tnormalize(data):
    '''
        ### 데이터 정규화 함수
        - 평균과 표준 편차를 이용해 입력된 데이터를 정규화 시킵니다.
        - 현재 입력층의 데이터가 아닌 train 데이터의 참 값을 표준화 시킵니다.
    '''
    n_data = data.T   # (n,1) -> (1,n)
210
211
212
213
214
215
216
217
218
219
220

    mean = np.mean(n_data, axis=1)    # 평균
    std_d = np.std(n_data, axis=1)     # 표준편차

    n_data = (n_data - mean) / std_d

    n_data = n_data.T

    return n_data


221
222
def preprocessingData(user_link, out_link):
    '''
223
        # 데이터 분석 전 데이터 전처리 함수
224
225
226
        1. 데이터 로드
        2. 데이터 1차 가공 (handle~RawData)
        3. 데이터 2차 가공 (combineXdata)
227
        4. 데이터 3차 가공 (nomalize~)
228
229
        5. 데이터 넘파이 형식 배열로 변환
        6. 반환
230
    '''
231
232
    raw_user_data = loadRawData(user_link, "/weather.csv")
    raw_out_data = loadRawData(out_link, "/weather.csv")
233
    raw_parameters = loadRawData(user_link, "/analysis_parameters.csv")
234
235
236

    user_x, train_t = handleUserRawData(raw_user_data)
    out_dict = handleOutRawData(raw_out_data)
237
    weights, bias = handleParameters(raw_parameters)
238
239
240

    train_x = combineXdata(user_x, out_dict)

241
242
243
244
    train_x = np.array(train_x)  # (n ,10)
    train_x, mean, std_d = Xnormalize(train_x)

    train_t = np.array(train_t)  # (10,1)
245
    train_t = Tnormalize(train_t)
246
247
248

    weights = np.array(weights) if weights != None else None
    bias = float(bias) if bias != None else None
249

250
    return train_x, train_t, weights, bias, mean, std_d