// 1. 페이지의 에서 최대한 위에 이 코드를 붙여넣으세요. // 아래의 메타 태그를 복사해 사이트 홈페이지의 섹션에 붙여 넣어주세요. //2. 여는 태그 바로 뒤에 코드를 붙여넣으세요.

새소식

반응형
AI/ML*DL 시작하기

선형회귀(Linear Regression) 연습

  • -
반응형

카글(Kaggle)의 데이터셋을 활용하여 이전에 정리했던 선형회귀 모델을 실습하고자 합니다.

 

선형회귀 모델의 경우 앞서말 한 바와 같이 데이터의 선형성(Linear)을 뛰는 것이 중요합니다. 

 

하지만 비선형적인(Non-Linear) 데이터들이 훨씬 많이 분포합니다.

 

이번 포스팅은 카글의 데이터셋을 활용해서 선형회귀모델을 적용시키는 것에 의미를 두고자합니다.

 

테스트용으로 사용할 데이터셋은 city_temperature.csv 파일입니다.

 

나라별 주요 도시의 평균온도가 나와있습니다. 저는 그 중 서울의 여름 온도를 사용하도록 하겠습니다.

 

혹시나 데이터가 필요하신분들은 하단 링크를 통해 다운받으시면 됩니다.

https://drive.google.com/drive/folders/1LFNWWpE5QGzNIkkz4YFck3dFAcwaBO50?usp=sharing

 

 

 

Pandas를 활용하여 csv파일을 정리해보도록 하겠습니다.

 

먼저 Python에서 필요한 라이브러리들을 Importing할 수 있도록 하겠습니다. 

 

import tensorflow as tf
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt

data_frame = pd.read_csv('./data/Linear_Regression/city_temperature.csv')
# 판다스를 이용하여 CSV 데이터를 확인하고 처리한다.
print(data_frame)

정상적으로 동작한다면 아래와 같은 print의 결과를 확인하실 수 있을것입니다. 

 

여러 나라의 도시 데이터들중에서 서울의 온도만 가져오도록 하겠습니다.

df_kor = data_frame[data_frame['City'] == 'Seoul']
df_6 = df_kor[(data_frame['Year']==2019)&(data_frame['Month']==6)]

dataset = df_6.values.tolist()
x_data = makeX(dataset)
scale_x_data = MinMaxScaler(x_data)
y_data = makeY(dataset)

Pandas의 데이터 프레임에 'City'중에서 'Seoul'만 가지고 와서 df_kor이라는 데이터 프레임을 만들어줍니다.

 

이제 2019년과 6월 온도만 가지고 오도록 하겠습니다. 

 

df_6값을 출력시켜보면 아래와 같은 것을 확인하실 수 있습니다.

이제  x,y데이터를 만들어 보도록 하겠습니다.

 

x값은 날짜가 되고, y데이터는 평균 온도로 만들도록 하겠습니다.

def makeX(dataset):
    x_data=[]
    for i in dataset:
        #data = str(i[6])+str(i[4])+str(i[5])
        if i[5] <= 9:
            i[5] = str(0)+str(i[5])
            
        data = str(i[4])+str(i[5])

        x_data.append(float(data))
    return x_data

def makeY(dataset):
    # 화씨 기준을 섭씨로 변환하여 데이터 입력
    y_data = []
    for i in dataset:
        y_data.append( float("%0.2f"%((i[7]-32)/1.8))) #섭씨 변환공식 적용
    return y_data

def MinMaxScaler(data):
    numerator = data-np.min(data,0)
    denumerator = np.max(data,0)-np.min(data,0)
    result = numerator/(denumerator +1e-7)
    return result

makeX 함수의 경우 8월10을 810으로 변환하여 x_data를 만들어주게 됩니다.

 

x_data의 범위가 너무 크면 NaN(Not a Number) 값이 나올 수 있기에, Normalization처리를 해줍니다.

(*Normalization은 MinMaxScaler함수를 참조하시면 됩니다, x_data의 값을 0~1사이로 바꿔주게 됩니다.)

 

그리고 현재 평균 온도는 화씨로 되어있기에 섭씨로 바꿔줍니다.(makeY함수 참조)

 

이제 Data와 선형회귀 모델을 Matplot으로 출력하여 그래프로 비교해보도록 하겠습니다.

 

W = tf.Variable(tf.random_uniform([1],-100.0,100.0))
b = tf.Variable(tf.random_uniform([1],-100.0,100.0))

X = tf.placeholder(tf.float32)
Y = tf.placeholder(tf.float32)

hypothesis = W * X + b
cost = tf.reduce_mean(tf.square(hypothesis-Y))
rate = tf.Variable(0.01)
optimizer = tf.train.GradientDescentOptimizer(rate)
train = optimizer.minimize(cost)
init = tf.initialize_all_variables()
test_data = [614.,615.,616.]

with tf.Session() as sess:
    sess.run(init)
    for step in range(5001):
        sess.run(train, feed_dict={X: scale_x_data, Y: y_data})
        if step %20 ==0:
            print(step, sess.run(cost, feed_dict={X: scale_x_data, Y: y_data}), sess.run(W), sess.run(b))
    r = sess.run(W)
    t = sess.run(b)
    print(sess.run(hypothesis, feed_dict={X: MinMaxScaler(test_data)}))     
    
test_xdata = np.arange(601,630,1)
x1 = MinMaxScaler(test_xdata)
print('X1:',x1)
y1 = r*x1+t

plt.plot(x_data,y_data,'b',label='Data')
plt.plot(test_xdata,y1,'r',label='Prediction')
plt.title('Linear Regression')
plt.xlabel('year')
plt.ylabel('temp')
plt.legend(loc='upper right')
plt.xticks(fontsize=14, color='w')
plt.yticks(fontsize=14, color='w')
plt.show()

 

전체 코드를 실행하게 되면 아래와 같은 그래프를 확인하실 수 있습니다

파란색 그래프는 실제 y데이터를 나타내며, 빨간색 그래프는 선형회귀모델을 나타냅니다. 

 

6월 데이터(파랑색)를 보면 선형성(linear)을 가지고 있다고 보기는 힘들죠? 그러다 보니 선형회귀 모델의 예측값과 실제 값은 오차가 클 수 밖에 없습니다.

 

test_x 데이터에 6/14,6/15,6/16에 대한 예측 값과 차이는 아래와 같습니다.

  예측값 실제값 오차
6/14 19.59 24 +5
6/15 21.89 26 +5
6/16 24.20 27 +3

 

평균 온도 데이터만 가지고 미래 온도를 예측한다는건 사실 말이 안되기도 하고, 그리고 선형회귀로 한다는건 더욱이 말이 안되는 것일겁니다. 

 

이번 포스팅은 Pandas를 이용하여 x,y데이터를 만들고, 선형회귀모델에 적용시켜 예측 결과를 본것에 중점을 맞추시면 좋을 것 같습니다.

 

반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.