Microsoft Fabric에서 시계열 예측 모델 학습 및 평가
이 Notebook에서는 계절 주기가 있는 시계열 데이터를 예측하는 프로그램을 개발합니다. NYC Open Data Portal에서 NYC 재무부에서 게시한 2003년부터 2015년까지의 날짜가 포함된 NYC Property Sales 데이터 세트를 사용합니다.
중요
Microsoft Fabric은 현재 미리 보기로 제공됩니다. 이 정보는 릴리스되기 전에 상당히 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보와 관련하여 명시적이거나 묵시적인 어떠한 보증도 하지 않습니다.
데이터 세트는 13 년 동안 뉴욕시 부동산 시장에서 판매 된 모든 건물의 기록입니다. 스프레드시트의 열 정의는 속성 판매 파일 용어집 을 참조하세요. 데이터 세트는 다음 표와 같습니다.
자치구 | 이웃 | building_class_category | tax_class | block | 많은 | 휴식처 | building_class_at_present | address | apartment_number | zip_code | residential_units | commercial_units | total_units | land_square_feet | gross_square_feet | year_built | tax_class_at_time_of_sale | building_class_at_time_of_sale | sale_price | sale_date |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Manhattan | 알파벳 시티 | 렌탈 07개 - 워크업 아파트 | 0.0 | 384.0 | 17.0 | C4 | 225 이스트 2ND 스트리트 | 10009.0 | 10.0 | 0.0 | 10.0 | 2145.0 | 6670.0 | 1900.0 | 2.0 | C4 | 275000.0 | 2007-06-19 | ||
Manhattan | 알파벳 시티 | 렌탈 07개 - 워크업 아파트 | 2.0 | 405.0 | 12.0 | C7 | 508 이스트 12번가 | 10009.0 | 28.0 | 2.0 | 30.0 | 3872.0 | 15428.0 | 1930.0 | 2.0 | C7 | 7794005.0 | 2007-05-21 |
기록 데이터를 기반으로 월별 부동산 거래량을 예측하는 모델을 빌드합니다. 예측하기 위해 빠르고 자동화된 예측 절차를 제공하고 계절성을 잘 처리하는 Facebook Prophet를 사용합니다.
예언자 설치
먼저 Facebook Prophet를 설치해 보겠습니다. 페이스 북 예언자 (예언자)는 페이스 북에 의해 개발 된 오픈 소스 시계열 예측 라이브러리입니다. 추세, 계절성 및 휴일의 세 가지 기본 구성 요소로 구성된 분해 가능한 시계열 모델을 사용합니다.
추세 구성 요소의 경우, Prophet는 자동 변경 지점 선택과 함께 조각별 일정한 증가율을 가정합니다.
계절성 구성 요소의 경우 Prophet는 푸리에 시리즈를 사용하여 매주 및 매년 계절성을 모델링합니다. 월별 데이터를 사용하므로 주별 계절성이 없으며 휴일을 고려하지 않습니다.
!pip install prophet
1단계: 데이터 로드
데이터 세트 다운로드 및 Data Lakehouse에 업로드
Data Lakehouse(lakehouse)는 데이터에 대한 중앙 리포지토리를 제공하는 데이터 아키텍처입니다. 2003년부터 2015년까지 뉴욕의 5개 자치구의 부동산 판매 기록을 포함하는 15개의 csv 파일이 있습니다. 편의상 이러한 파일은 압축 nyc_property_sales.tar
되어 공용 Blob Storage에서 사용할 수 있습니다.
URL = "https://synapseaisolutionsa.blob.core.windows.net/public/NYC_Property_Sales_Dataset/"
TAR_FILE_NAME = "nyc_property_sales.tar"
DATA_FOLER = "Files/NYC_Property_Sales_Dataset"
TAR_FILE_PATH = f"/lakehouse/default/{DATA_FOLER}/tar/"
CSV_FILE_PATH = f"/lakehouse/default/{DATA_FOLER}/csv/"
import os
if not os.path.exists("/lakehouse/default"):
# ask user to add a lakehouse if no default lakehouse added to the notebook.
# a new notebook will not link to any lakehouse by default.
raise FileNotFoundError(
"Default lakehouse not found, please add a lakehouse for the notebook."
)
else:
# check if the needed files are already in the lakehouse, try to download and unzip if not.
if not os.path.exists(f"{TAR_FILE_PATH}{TAR_FILE_NAME}"):
os.makedirs(TAR_FILE_PATH, exist_ok=True)
os.system(f"wget {URL}{TAR_FILE_NAME} -O {TAR_FILE_PATH}{TAR_FILE_NAME}")
os.makedirs(CSV_FILE_PATH, exist_ok=True)
os.system(f"tar -zxvf {TAR_FILE_PATH}{TAR_FILE_NAME} -C {CSV_FILE_PATH}")
Lakehouse에서 데이터 프레임 만들기
함수는 display
데이터 프레임을 인쇄하고 차트 보기를 자동으로 제공합니다.
df = (
spark.read.format("csv")
.option("header", "true")
.load("Files/NYC_Property_Sales_Dataset/csv")
)
display(df)
2단계: 데이터 전처리
형식 변환 및 필터링
필요한 형식 변환 및 필터링을 수행할 수 있습니다.
- 판매 가격을 정수로 변환해야 합니다.
- 불규칙한 판매 데이터를 제외해야 합니다. 예를 들어 $ 0 판매는 현금 고려 사항없이 소유권 이전을 나타냅니다.
- A 클래스 이외의 빌드 형식을 제외합니다.
분석을 위해 A 클래스 건물의 시장만을 선택하는 이유는 계절적 효과가 A 클래스 건물에 대한 부적격 계수이기 때문입니다. 사용하는 모델은 시계열 분석에서 일반적인 요구 사항인 계절성을 포함하여 다른 많은 모델보다 우수합니다.
# import libs
import pyspark.sql.functions as F
from pyspark.sql.types import *
df = df.withColumn(
"sale_price", F.regexp_replace("sale_price", "[$,]", "").cast(IntegerType())
)
df = df.select("*").where(
'sale_price > 0 and total_units > 0 and gross_square_feet > 0 and building_class_at_time_of_sale like "A%"'
)
monthly_sale_df = df.select(
"sale_price",
"total_units",
"gross_square_feet",
F.date_format("sale_date", "yyyy-MM").alias("month"),
)
display(df)
summary_df = (
monthly_sale_df.groupBy("month")
.agg(
F.sum("sale_price").alias("total_sales"),
F.sum("total_units").alias("units"),
F.sum("gross_square_feet").alias("square_feet"),
)
.orderBy("month")
)
display(summary_df)
시각화
이제 뉴욕에서 부동산 거래 추세의 추세를 살펴 보십시오. 선택한 건물 클래스에서는 매년 계절성이 분명합니다. 피크 구매 시즌은 일반적으로 봄과 가을입니다.
df_pandas = summary_df.toPandas()
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
f, (ax1, ax2) = plt.subplots(2, 1, figsize=(35, 10))
plt.sca(ax1)
plt.xticks(np.arange(0, 15 * 12, step=12))
plt.ticklabel_format(style="plain", axis="y")
sns.lineplot(x="month", y="total_sales", data=df_pandas)
plt.ylabel("Total Sales")
plt.xlabel("Time")
plt.title("Total Property Sales by Month")
plt.sca(ax2)
plt.xticks(np.arange(0, 15 * 12, step=12))
plt.ticklabel_format(style="plain", axis="y")
sns.lineplot(x="month", y="square_feet", data=df_pandas)
plt.ylabel("Total Square Feet")
plt.xlabel("Time")
plt.title("Total Property Square Feet Sold by Month")
plt.show()
3단계: 모델 학습 및 평가
모델 맞춤
모델 맞춤을 수행하려면 시간 축의 이름을 'ds'로 바꾸고 값 축을 'y'로 바꿉니다.
import pandas as pd
df_pandas["ds"] = pd.to_datetime(df_pandas["month"])
df_pandas["y"] = df_pandas["total_sales"]
이제 모델에 맞추겠습니다. '곱하기' 계절성을 사용하도록 선택하면 계절성이 더 이상 예언자가 가정하는 기본값과 같은 일정한 가산 요소가 아니라는 것을 의미합니다. 이전 셀에 표시된 것처럼 월별 총 부동산 판매 데이터를 인쇄했으며 진동 진폭이 일치하지 않습니다. 즉, 간단한 가산성 계절성을 사용하면 데이터에 적합하지 않습니다. 또한 후방 분포의 평균을 제공하는 MCMC(Markov Chain Monte Carlo)를 사용합니다. 기본적으로 Prophet는 Stan의 L-BFGS를 사용하여 모델에 맞습니다. 이 모델은 MAP(후방 확률) 추정치의 최대값을 찾습니다.
from prophet import Prophet
from prophet.plot import add_changepoints_to_plot
m = Prophet(
seasonality_mode="multiplicative", weekly_seasonality=False, mcmc_samples=1000
)
m.fit(df_pandas)
Prophet의 기본 제공 함수를 사용하여 모델 맞춤 결과를 보여 봅시다. 검은색 점은 모델을 학습시키는 데 사용되는 데이터 요소입니다. 파란색 선은 예측이며 연한 파란색 영역은 불확실성 간격을 표시합니다.
future = m.make_future_dataframe(periods=12, freq="M")
forecast = m.predict(future)
fig = m.plot(forecast)
예언자는 조각별 일정한 성장을 가정하므로 학습된 모델의 변경 지점을 그릴 수 있습니다.
fig = m.plot(forecast)
a = add_changepoints_to_plot(fig.gca(), m, forecast)
추세 및 연간 계절성을 시각화합니다. 연한 파란색 영역은 불확실성을 반영합니다.
fig2 = m.plot_components(forecast)
교차 유효성 검사
Prophet의 기본 제공 교차 유효성 검사 기능을 사용하여 기록 데이터에 대한 예측 오류를 측정할 수 있습니다. 다음 매개 변수는 11년간의 학습 데이터로 시작한 다음, 1년 이내에 30일마다 예측을 수행해야 한다는 것을 의미합니다.
from prophet.diagnostics import cross_validation
from prophet.diagnostics import performance_metrics
df_cv = cross_validation(m, initial="11 Y", period="30 days", horizon="365 days")
df_p = performance_metrics(df_cv, monthly=True)
display(df_p)
4단계: MLflow를 사용하여 모델 로그 및 로드
이제 나중에 사용할 수 있도록 학습된 모델을 저장할 수 있습니다.
# setup mlflow
import mlflow
EXPERIMENT_NAME = "aisample-timeseries"
mlflow.set_experiment(EXPERIMENT_NAME)
# log the model and parameters
model_name = f"{EXPERIMENT_NAME}-prophet"
with mlflow.start_run() as run:
mlflow.prophet.log_model(m, model_name, registered_model_name=model_name)
mlflow.log_params({"seasonality_mode": "multiplicative", "mcmc_samples": 1000})
model_uri = f"runs:/{run.info.run_id}/{model_name}"
print("Model saved in run %s" % run.info.run_id)
print(f"Model URI: {model_uri}")
# load the model back
loaded_model = mlflow.prophet.load_model(model_uri)