패스트캠퍼스 챌린지

패스트캠퍼스 챌린지 43일차

Sabrine 2022. 3. 7. 02:30

12~ 13

도착시간을 빠름, 보통, 늦음 등급 데이터로 만들기(3가지 군집 데이터로 분류)

[Routine Code]

1. Mount Drive(Google Drive 연결)

from google.colab import drive

drive.mount('/gdrive')

2. Korean Encoding

!sudo apt-get install -y fonts-nanum

!sudo fc-cache -fv

!rm ~/.cache/matplotlib -rf

** Runtime Restart 필요한 코드 재시작

3. Matplotlib

# Import pyplot as a alias 'plt'

import matplotlib.pyplot as plt

# 폰트를 Nanum폰트로 지정

plt.rc('font', family='NanumBarunGothic')

4. Load Data

# Load a file under "data" folder

file = "/gdrive/My Drive/data/data_2021_1_12.csv"

import pandas as pd

data = pd.read_csv(file)

5. 서울 기준 각 영업소까지 거리

#101 서울, 105 기흥, 110 목천, 115 대전, 120 황간, 125 남구미, 130 동김천, 135 경주, 140 부산

#101 서울(406.94), 105 기흥(387.19), 110 목천(329.91), 115 대전(271.94), 120 황간(222.38), 125 남구미(167.25), 130 동김천(192.00), 135 경주(68.26), 140 부산(0)

- 실제 거리(실수)

#Distance from Seoul : 0, 19.75, 77.03, 135, 184.56, 214.94, 239.69, 338.68, 406.94

- 정수(올림)

# Distance from Seoul : 0, 20, 77, 135, 185, 240, 215, 339, 407

** map() : 값을 치환하는 함수

data['도착영업소코드'] = data['도착영업소코드'].map({105: 20, 110: 77, 115: 135, 120: 185, 125: 240, 130: 215, 135: 339, 140: 407})

6. 데이터 프레임 작성

- 도착영업소코드 컬럼명을 거리로 변경

data.rename(columns={'도착영업소코드': '거리'}, inplace=True)

- 거리가 부산(407)인 데이터만 추출

data_destination = data[data['거리'].isin([407])]

- 3개의 요인('집계시', '요일', '거리')groupby를 하고, '통행시간'의 평균값을 낸 데이터 프레임 생성

data_time = data_destination.groupby(['집계시','요일','거리'])['통행시간'].mean()

- 거리(407)값이 있는 축의 위치 변경

data_distance = data_time.unstack(level=-1)

- Null 값 제거 처리

data_distance.dropna()

- 1차원 도표로 변형

data_out = data_distance.reset_index()

- describe() : 통계치 계산

stat = data_out.describe()

print(stat)

** 25%, 75% 값을 사용할 예정이다.

- 25%, 75%의 통행시간 데이터를 추출

value_25 = stat[407][4]

value_75 = stat[407][6]

print(value_25, value_75)

** stat 또한 객체이다.

- Grade라는 컬럼을 새로 만들어서, 초기값 0을 삽입

data_out['Grade'] = 0

- Grade 계산용 함수 작성

def get_grade(input):

    if input > value_25:

        if input > value_75: output = 2

        else: output = 1

    else: output = 0

return output

** 25% 보다 적은 값은 0, 25%보다 크고 75%보다 적으면 1, 75%보다 크면 2

- data_grade라는 새로운 데이터 프레임 생성(time, day, grade라는 컬럼을 가지고 있음)

data_grade = pd.DataFrame(columns=['time', 'day', 'grade'])

- data_out의 수만큼 Loop를 돌면서 data_grade 데이터 프레임에 값을 삽입한다.

** grade컬럼 입력 값은 get_grade함수를 통해 계산된 값이 입력된다.

** iterrows() : 인덱스 한 개씩 루프를 돌 때 사용한다.

for index, item in data_out.iterrows():

    print(index, item['집계시'], item['요일'])

    data_grade = data_grade.append({

        'time': item['집계시'],

        'day': item['요일'],

        'grade': get_grade(item[407])

}, ignore_index=True)

** ignore_index=True : 인덱스는 참조하지 않음.

** Grade 컬럼의 값은 0~2 사이의 값이다.

- 데이터 프레임을 (Tensorflow에서 사용하기 위해서)리스트로 변경

# Dataframe to List

data_list = data_grade.values.tolist()

- 모델 학습

# Generate Train dataset

x_train = [ r[:2] for r in data_list ]

y_train = [ int(r[-1]) for r in data_list ]

- 필요한 라이브러리 import

import tensorflow as tf

import numpy as np

# One hot encode [0, 1, 2] to [[1,0,0], [0,1,0], [0,0,1]]

# 2진법으로 변경 : 01,0,0

y_one_hot = tf.keras.utils.to_categorical(y_train)

- 상수 설정 : 미분 계수, 학습 횟수

learning_rate = 1e-2

learning_epochs = 1000

- 모델링

# Stochastic gradient descent (SGD) Optimizer

sgd = tf.keras.optimizers.SGD(learning_rate=learning_rate)

** 모델 종류 Sequential

** Layer(Output)종류 Dense, 개수 3, Input2개임.

model = tf.keras.models.Sequential()

model.add(tf.keras.layers.Dense(3, input_shape=(2,), activation='softmax'))

** activation='softmax' : multinomial classification이기 때문에 softmax사용

model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])

** loss='categorical_crossentropy' : 최저값 계산 방법

- 모델 구조 확인

model.summary()

- 학습

# Train the model

history = model.fit(np.array(x_train), np.array(y_one_hot), epochs=learning_epochs)

** one hot구조는 numpy를 사용하지 않으면 에러가 발생한다.

** 학습 데이터 양이 적어서 정확도가 57%정도 밖에 되지 않는다.

- 학습 결과 그래프 생성

plt.figure(figsize=(10,10))

plt.plot(history.history['loss'])

plt.show()

- 100번 단위로 학습 결과 출력

print("%20s %20s %20s" % ('학습량', '비용', '정확도')+'\n')

for step in range(learning_epochs):

    if step % 100 == 0:

        cost_val = history.history['loss'][step]

        acc_val = history.history['accuracy'][step]

        print("%20i %20.5f %20.5f" % (step, cost_val, acc_val))

** 정확도가 70~80%정도인 것이 좋음.

- input format생성 (목요일 14)

Time = 14 #@param {type:"slider", min:0, max:23, step:1}

Day = 3 #@param {type:"slider", min:0, max:6, step:1}

- 선택한 시간과 요일 조건에 해당하는 데이터 생성

time_condition = data_out['집계시'] == Time

day_condition = data_out['요일'] == Day

selected_data = data_out[time_condition & day_condition]

- 예상 Prediction

input = [Time, Day]

result = model.predict(np.array([input]))

grade_list = ['빠름', '보통', '느림']

grade_index = np.argmax(result[0])

grade = grade_list[grade_index]

print("%30s" % ('속도 등급')+'\n')

print("%30s" % (grade)+'\n')

print(result[0], grade_index)

** result[0]probability의 리스트이다.

** Probability가 가장 큰 것을 취득.

** 1번째가 3개 중에 가장 큰 값이므로 grade1이 나온다.



기재: 본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

https://bit.ly/37BpXiC

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr