#4 가게 매출 예측
회귀를 공부하고 분류 강의가 나올 때까지 기다리고 있는 상황에서
딥러닝 강의도 회귀까지 정리했고 할 것이 마땅치 않아
선형 회귀 실습을 해봐야겠다고 생각했다.
데이터를 찾다가 공공 데이터도 있겠지만 어머니 가게 매출 데이터를 뽑아서 해봐야겠다고 생각했다.
하지만 가게 포스 기계에서는 매출만 txt로 뽑을 수 있고
메뉴별 매출이나 시간대별 매출은 제공되지 않는 것 같았다.
그래서 내가 여러 변수를 만들기로 했다.
우선 매출은 데이터로 뽑아 왔고,
매출에 영향을 줄 수 있는 요인은 무엇이 있나 생각해보았다.
날씨도 영향을 줄 것 같고
학교 앞이라 방학 여부도 중요할 것 같았다.
그리고 중요하다고 생각한 것은 요일이었다.
그래서 날씨 데이터를 인터넷에서 뽑고
방학 여부는 1,2,7,8 월 달은 방학이라는 표시를 했다.
요일은 파이썬의 datetime 모듈을 사용했다.
매출 데이터는 2013년 부터 2016년까지 사용했다.
아래의 코드를 사용해 매출 데이터를 예측해봤다.
-----------------------------------------------------------------------
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime
import time
from sklearn import linear_model
from sklearn import cross_validation
def order_data():
f = open("샤브향_정산분석파일.txt")
sales = []
count = 0
for line in f.readlines():
if line[-1] == '\n':
sales.append(line[:-1])
count =count + 1
data = []
count_min = 0
count_max = int((count - 4)/2)
for i in range(count_min,count_max):
data.append(sales[2*i+4])
data = np.asarray(data)
Rdata = []
date = []
sales_record = []
for i in range(len(data)-2):
Rdata.append(data[i][1:-1])
date.append(Rdata[i][:10])
Sdata = Rdata[i][-10:].strip()
sales_record.append(Sdata.replace(',',''))
date = np.asarray(date)
date = pd.to_datetime(date)
sales_record = np.asarray(sales_record)
return date,sales_record
def make_dataframe(date, sales):
dic = {'date' : date , 'sales' : sales, 'weekday' : date.weekday}
df = pd.DataFrame(data = dic, columns=['sales','weekday'])
df.sales = df.sales.astype(int)
df.index = pd.Index(date)
return df
def cut_data(dataframe):
dataframe = dataframe.sort(['sales'], ascending=[0])
num = int(len(dataframe)*0.2)
dataframe_high = dataframe[:num]
dataframe_low = dataframe[-num :]
return dataframe_high,dataframe_low
def divide_set(df):
vacation = []
semester = []
for period in ['2013','2014','2015','2016']:
for i in range(1,13):
string = '-' + str(i)
if string == '-1' or string == '-2' or string == '-7' or string == '-8':
try:
vacation.append(df[period+string])
except:
continue
else:
try:
semester.append(df[period+string])
except:
continue
vacation = pd.concat(vacation)
semester = pd.concat(semester)
return vacation,semester
def cut_data(dataframe):
dataframe = dataframe.sort_values(by='sales', ascending=[0])
num = int(len(dataframe)*0.2)
dataframe_high = dataframe[:num]
dataframe_low = dataframe[-num :]
return dataframe_high,dataframe_low
def load_weather():
text = open('이천평균기온.txt')
res = []
for line in text.readlines():
line = line.strip().split('\t')
res.append(line)
num = int(len(res)/4)
fst = res[:num]
snd = res[num:2*num]
thd = res[2*num:3*num]
fth = res[3*num:]
return fst,snd,thd,fth
def col_data(data,num):
res = []
try:
for j in data[1:]:
res.append(j[num])
except:
pass
return res
def merge_data(data):
month = data[0]
res = []
for i in range(1 , len(month)+1):
res.extend(col_data(data,i))
return res
def weather_df(weather,date):
start = '2013-3-22'
end = '2016-3-22'
period = pd.date_range(start,end,freq='D')
dic = {'date' : period , 'weather' : weather}
df = pd.DataFrame(data = dic , columns=['weather'])
df.index = pd.Index(period)
df = df.drop(period.difference(date))
return df
if __name__ == "__main__":
date, sales = order_data()
df = make_dataframe(date,sales)
fst,snd,thd,fth = load_weather()
weather = []
for data in [fst,snd,thd,fth]:
tmp = merge_data(data)
weather.extend(tmp)
weather = [float(a) for a in weather if not a == '' and not a == ' ']
weatherDF = weather_df(weather,date)
df['temp'] = weatherDF.weather
vacation,semester = divide_set(df)
vacation['vacation'] = 1
semester['vacation'] = 0
vacation_high,vacation_low = cut_data(vacation)
semester_high,semester_low = cut_data(semester)
df = pd.concat([vacation,semester])
df = df.sort_index()
sales_high,sales_low = cut_data(df)
data = df.copy()
data = data.dropna()
target = data.sales
del data['sales']
X_train, X_test, y_train, y_test = cross_validation.train_test_split(data, target, test_size=0.25, random_state=0)
clf = linear_model.Lasso(alpha= 0.01,normalize=True)
clf.fit(X_train,y_train)
print('Coefficients: \n', clf.coef_)
# The mean square error
print("Residual sum of squares: %.2f"
% np.mean((clf.predict(X_test) - y_test) ** 2))
# Explained variance score: 1 is perfect prediction
print('Variance score: %.2f' % clf.score(X_test, y_test))
-----------------------------------------------------------------------
딥러닝 강의도 회귀까지 정리했고 할 것이 마땅치 않아
선형 회귀 실습을 해봐야겠다고 생각했다.
데이터를 찾다가 공공 데이터도 있겠지만 어머니 가게 매출 데이터를 뽑아서 해봐야겠다고 생각했다.
하지만 가게 포스 기계에서는 매출만 txt로 뽑을 수 있고
메뉴별 매출이나 시간대별 매출은 제공되지 않는 것 같았다.
그래서 내가 여러 변수를 만들기로 했다.
우선 매출은 데이터로 뽑아 왔고,
매출에 영향을 줄 수 있는 요인은 무엇이 있나 생각해보았다.
날씨도 영향을 줄 것 같고
학교 앞이라 방학 여부도 중요할 것 같았다.
그리고 중요하다고 생각한 것은 요일이었다.
그래서 날씨 데이터를 인터넷에서 뽑고
방학 여부는 1,2,7,8 월 달은 방학이라는 표시를 했다.
요일은 파이썬의 datetime 모듈을 사용했다.
매출 데이터는 2013년 부터 2016년까지 사용했다.
아래의 코드를 사용해 매출 데이터를 예측해봤다.
-----------------------------------------------------------------------
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime
import time
from sklearn import linear_model
from sklearn import cross_validation
def order_data():
f = open("샤브향_정산분석파일.txt")
sales = []
count = 0
for line in f.readlines():
if line[-1] == '\n':
sales.append(line[:-1])
count =count + 1
data = []
count_min = 0
count_max = int((count - 4)/2)
for i in range(count_min,count_max):
data.append(sales[2*i+4])
data = np.asarray(data)
Rdata = []
date = []
sales_record = []
for i in range(len(data)-2):
Rdata.append(data[i][1:-1])
date.append(Rdata[i][:10])
Sdata = Rdata[i][-10:].strip()
sales_record.append(Sdata.replace(',',''))
date = np.asarray(date)
date = pd.to_datetime(date)
sales_record = np.asarray(sales_record)
return date,sales_record
def make_dataframe(date, sales):
dic = {'date' : date , 'sales' : sales, 'weekday' : date.weekday}
df = pd.DataFrame(data = dic, columns=['sales','weekday'])
df.sales = df.sales.astype(int)
df.index = pd.Index(date)
return df
def cut_data(dataframe):
dataframe = dataframe.sort(['sales'], ascending=[0])
num = int(len(dataframe)*0.2)
dataframe_high = dataframe[:num]
dataframe_low = dataframe[-num :]
return dataframe_high,dataframe_low
def divide_set(df):
vacation = []
semester = []
for period in ['2013','2014','2015','2016']:
for i in range(1,13):
string = '-' + str(i)
if string == '-1' or string == '-2' or string == '-7' or string == '-8':
try:
vacation.append(df[period+string])
except:
continue
else:
try:
semester.append(df[period+string])
except:
continue
vacation = pd.concat(vacation)
semester = pd.concat(semester)
return vacation,semester
def cut_data(dataframe):
dataframe = dataframe.sort_values(by='sales', ascending=[0])
num = int(len(dataframe)*0.2)
dataframe_high = dataframe[:num]
dataframe_low = dataframe[-num :]
return dataframe_high,dataframe_low
def load_weather():
text = open('이천평균기온.txt')
res = []
for line in text.readlines():
line = line.strip().split('\t')
res.append(line)
num = int(len(res)/4)
fst = res[:num]
snd = res[num:2*num]
thd = res[2*num:3*num]
fth = res[3*num:]
return fst,snd,thd,fth
def col_data(data,num):
res = []
try:
for j in data[1:]:
res.append(j[num])
except:
pass
return res
def merge_data(data):
month = data[0]
res = []
for i in range(1 , len(month)+1):
res.extend(col_data(data,i))
return res
def weather_df(weather,date):
start = '2013-3-22'
end = '2016-3-22'
period = pd.date_range(start,end,freq='D')
dic = {'date' : period , 'weather' : weather}
df = pd.DataFrame(data = dic , columns=['weather'])
df.index = pd.Index(period)
df = df.drop(period.difference(date))
return df
if __name__ == "__main__":
date, sales = order_data()
df = make_dataframe(date,sales)
fst,snd,thd,fth = load_weather()
weather = []
for data in [fst,snd,thd,fth]:
tmp = merge_data(data)
weather.extend(tmp)
weather = [float(a) for a in weather if not a == '' and not a == ' ']
weatherDF = weather_df(weather,date)
df['temp'] = weatherDF.weather
vacation,semester = divide_set(df)
vacation['vacation'] = 1
semester['vacation'] = 0
vacation_high,vacation_low = cut_data(vacation)
semester_high,semester_low = cut_data(semester)
df = pd.concat([vacation,semester])
df = df.sort_index()
sales_high,sales_low = cut_data(df)
data = df.copy()
data = data.dropna()
target = data.sales
del data['sales']
X_train, X_test, y_train, y_test = cross_validation.train_test_split(data, target, test_size=0.25, random_state=0)
clf = linear_model.Lasso(alpha= 0.01,normalize=True)
clf.fit(X_train,y_train)
print('Coefficients: \n', clf.coef_)
# The mean square error
print("Residual sum of squares: %.2f"
% np.mean((clf.predict(X_test) - y_test) ** 2))
# Explained variance score: 1 is perfect prediction
print('Variance score: %.2f' % clf.score(X_test, y_test))
-----------------------------------------------------------------------
lasso 선형 회귀를 이용했고 cross validation 을 통해 모델을 평가했다.
물론 시계열 데이터로 회귀를 사용하는게 잘 맞는지는 모르겠지만,
선형 회귀를 공부하고 실습할 수 있는 좋은 계기가 되었다.
정확도는 매우 낮은 편이다.
하지만 1주일간 예측 매출과 실제 매출을 비교해보면 오차범위는 15만원 이내이기 때문에
첫 예측 코드치고 충분히 만족할만한 결과를 도출했다.
댓글
댓글 쓰기