preprocessing.py 8.57 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 makeTimeDIR():
14
    '''
15
16
17
        ### 날짜를 이용한 경로를 생생하는 함수
        - 오늘 날짜를 이용한 경로와 어제 날짜를 이용한 경로를 생성합니다.
        - 생성된 경로는 dictionary 형태로 반환합니다.
18
    '''
19
    # 오늘 날짜로 된 경로 생성
20
    today = datetime.datetime.today()
21
22
23
24
25
26
27
28

    tYear = str(today.year)
    tMonth = str(today.month) if today.month >= 10 else '0' + str(today.month)
    tDay = str(today.day) if today.day >= 10 else '0' + str(today.day)

    today_dir = '/' + tYear + '/' + tYear + tMonth + '/' + tYear + tMonth + tDay

    # 오늘을 기준 하루 전 날짜로 된 경로 생성
29
30
    yesterday = today - datetime.timedelta(days=1)

31
32
    yYear = str(yesterday.year)
    yMonth = str(yesterday.month) if yesterday.month >= 10 else "0" + \
33
        str(yesterday.month)
34
35
    yDay = str(yesterday.day) if yesterday.day >= 10 else "0" + \
        str(yesterday.day)
36

37
38
39
40
41
42
43
44
45
46
47
48
49
    yesterday_dir = "/" + yYear + "/" + yYear + yMonth + "/" + yYear + yMonth + yDay

    time_dir = {"today": today_dir, "yesterday": yesterday_dir}
    return time_dir


def loadRawData(link, time_domain, file_name):
    '''
        ### CSV 파일의 내용을 반환하는 함수
        - 제공 받은 링크를 통해 파일을 읽고 반환합니다.
    '''
    raw_data = []
    time_dir = makeTimeDIR()
50

51
    file_dir = os.getcwd() + link + time_dir[time_domain] + file_name
52

53
54
55
56
57
    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='')
58
59
60
61
62
63
64
65
66
67
68
69
    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):
    '''
70
        ### User Raw Data (CSV 파일 데이터) 가공 함수
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
        - [ 월 / 일 / 시 / 분 / 온도 / 습도 / 광도 ]의 데이터를 변환하는 함수
        - 월 / 일 / 분 제거
        - 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):
    '''
95
        ### Out Raw Data (CSV 파일 데이터) 가공 함수
96
97
98
99
100
101
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
        - [ 월 / 일 / 시 / 분 / 온도 / 습도 / 기압 / 풍속 ] 데이터를 변환하는 함수
        - '분' 을 제거합니다.
        - 같은 시각의 데이터들은 평균을 구해서 데이터로 저장합니다.
        - 외부 데이터는 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


136
def handleLearningParams(raw_w=None):
137
138
139
140
141
    '''
        ### Weights & Bias를 처리하는 함수
        - raw 데이터는 weights와 bias가 합쳐진 상태입니다.
        - raw 데이터를 하나씩 잘라 실수로 변환한 뒤, 마지막의 편향을 잘라냅니다.
    '''
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156

    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


157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
def handleStatsParams(raw_ms=None):
    '''
        ### 평균과 표준편차를 다루는 함수
        - csv 파일로 부터 읽어온 자료를 전체 범주의 평균, 표준편차 그리고 내부 온도에 대한 평균, 표준편차로 나누는 함수 입니다.
    '''
    mean, std = [], []
    raw_mean = raw_ms[0]
    raw_std = raw_ms[1]

    for fig in raw_mean:
        mean.append(float(fig))

    for fig in raw_std:
        std.append(float(fig))

    temp_mean = mean[7]
    temp_std = std[7]

    return mean, std, temp_mean, temp_std


178
179
def combineXdata(user_x, out_dict):
    '''
180
        ### 분리된 입력 데이터를 합치는 함수
181
182
183
184
185
186
        - 사용자 데이터와 외부 데이터를 결합해 입력층의 값으로 가공합니다.
    '''
    train_x = []

    for line in user_x:
        hour, temp, humi, lights = line
187
188
189
190
191
192
193
194
195
196
197
198
199

        # 데이터 수집이 균일하게 이루어지지 않은 경우 처리
        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]
200
201
202
203
204
        train_x.append(x)

    return train_x


205
206
207
208
def Xnormalize(data):
    '''
        ### 정규화 함수
        - 입력 층의 데이터를 정규화 시킵니다.
209
        - 월, 일 데이터의 평균과 표준 편차를 계산하여 값을 수정합니다.
210
211
212
213
214
    '''

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

    mean = np.mean(normalized_data, axis=1)    # 평균 (10, 1)
215
    std_d = np.std(normalized_data, axis=1)    # 표준편차
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244

    # 월, 일의 평균과 표준편차 지정
    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


245
246
247
248
249
250
251
def Tnormalize(data):
    '''
        ### 데이터 정규화 함수
        - 평균과 표준 편차를 이용해 입력된 데이터를 정규화 시킵니다.
        - 현재 입력층의 데이터가 아닌 train 데이터의 참 값을 표준화 시킵니다.
    '''
    n_data = data.T   # (n,1) -> (1,n)
252
253
254
255
256
257
258
259
260
261
262

    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


263
264
def preprocessingData(user_link, out_link):
    '''
265
        # 데이터 분석 전 데이터 전처리 함수
266
267
268
        1. 데이터 로드
        2. 데이터 1차 가공 (handle~RawData)
        3. 데이터 2차 가공 (combineXdata)
269
        4. 데이터 3차 가공 (nomalize~)
270
271
        5. 데이터 넘파이 형식 배열로 변환
        6. 반환
272
    '''
273
274
275
276
    raw_user_data = loadRawData(user_link, "yesterday", "/weather.csv")
    raw_out_data = loadRawData(out_link, "yesterday", "/weather.csv")
    raw_parameters = loadRawData(
        user_link, "yesterday", "/analysis_parameters.csv")
277
278
279

    user_x, train_t = handleUserRawData(raw_user_data)
    out_dict = handleOutRawData(raw_out_data)
280
    weights, bias = handleLearningParams(raw_parameters)
281
282
283

    train_x = combineXdata(user_x, out_dict)

284
285
286
287
    train_x = np.array(train_x)  # (n ,10)
    train_x, mean, std_d = Xnormalize(train_x)

    train_t = np.array(train_t)  # (10,1)
288
    train_t = Tnormalize(train_t)
289
290
291

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

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