2022. 5. 25. 19:38ใ๐งช Data Science/Analytics
๋น์ ์ NEWYORK์์ ํ์ ๊ธฐ์ฌ๋ก ์ผํ๊ณ ์๋ค.
ํ์๋ Yellow Taxi์ด๋ค.
ํ์ ๊ธฐ์ฌ๋ก ์์กดํ๊ธฐ ์ํด์ ๋ค์๊ณผ ๊ฐ์ ๋ ธ๋ ฅ์ด ํ์ํ๋ค.
1) ๊ทผ๋ฌด ์๊ฐ ๋์, ์๋์ ์ต๋ํ ๋ง์ด ํ์ธ ๊ฒ (์๋)
2) ๋ง์ ์๊ธ + ํ๋ถํ ํ (์๊ธ)
3) ํ๊ธ ๊ฒฐ์ ๋ ์๋์ ํฌํจ์ํค์ง ์๊ณ ์ฌ์ฉํ๊ธฐ (์ธ๊ธ ์ ์ฝ)
์ฒซ ๋ฒ์งธ ๋ ธ๋ ฅ์ ์ด์ ํฌ์คํ ์์ ๋ค๋ค๋ค.
์ด๋ฒ ํฌ์คํ ์์ ๋ง์ ์๊ธ๊ณผ ํ์ ๋ฐ๋ ๋ฐฉ๋ฒ, ํ๊ธ ๊ฒฐ์ ํ๋ ์๋์ ๋ฐ๋ ๋ฐฉ๋ฒ์ ์์๋ณด๊ฒ ๋ค.
[Data]
๋ฐ์ดํฐ๋ SparkSQL ํฌ์คํ ์์ ์ ์ฒ๋ฆฌํ Yellow Taxi ๋ฐ์ดํฐ(cleaned)๋ฅผ ์ฌ์ฉํ๋๋ก ํ๊ฒ ๋ค.
NEWYORK Yellow Taxi์ ์ดํ์ 2021.01~2021.07๊น์ง ๋ชจ๋ ๋ชจ์๋์ ๋ฐ์ดํฐ๋ค.
[Yellow Taxi Data: https://mengu.tistory.com/50]
Basic Setting
from matplotlib import font_manager, rc
font_path = 'C:\\WINDOWS\\Fonts\\HBATANG.TTF'
font = font_manager.FontProperties(fname=font_path).get_name()
rc('font', family=font)
import os
import findspark
findspark.init(os.environ.get("SPARK_HOME"))
import pyspark
from pyspark import SparkConf, SparkContext
import pandas as pd
import faulthandler
faulthandler.enable()
from pyspark.sql import SparkSession
spark = SparkSession.builder.master('local').appName("taxi-analysis").getOrCreate()
# ๋ฐ์ดํฐ๊ฐ ์๋ ํ์ผ
zone_data = "C:/DE study/data-engineering/01-spark/data/taxi_zone_lookup.csv"
trip_files = "C:/DE study/data-engineering/01-spark/data/trips/*"
# ๋ฐ์ดํฐ ๋ก๋
trips_df = spark.read.csv(f"file:///{trip_files}", inferSchema = True, header = True)
zone_df = spark.read.csv(f"file:///{zone_data}", inferSchema = True, header = True)
# ๋ฐ์ดํฐ ์คํค๋ง
trips_df.printSchema()
zone_df.printSchema()
# ๋ฐ์ดํฐ createOrReplaceTempView()
trips_df.createOrReplaceTempView("trips")
zone_df.createOrReplaceTempView("zone")
# ์ธ๋งํ column๋ง ๋ชจ์๋์.
query = '''
SELECT
t.VendorID,
TO_DATE(t.tpep_pickup_datetime) AS pickup_date,
HOUR(t.tpep_pickup_datetime) AS pickup_time,
TO_DATE(t.tpep_dropoff_datetime) AS dropoff_date,
HOUR(t.tpep_dropoff_datetime) AS dropoff_time,
t.passenger_count,
t.trip_distance,
t.payment_type,
t.fare_amount,
t.tip_amount,
t.tolls_amount,
t.total_amount,
pz.Zone as pzone,
dz.Zone as dzone
FROM
trips t
LEFT JOIN
zone pz
ON
t.PULocationID == pz.LocationID
LEFT JOIN
zone dz
ON
t.DOLocationID == dz.LocationID
'''
taxi_df = spark.sql(query)
taxi_df.createOrReplaceTempView("taxi")
spark.sql('select * from taxi').show(5)
+--------+-----------+-----------+------------+------------+---------------+-------------+------------+-----------+----------+------------+------------+-----------------+--------------+
|VendorID|pickup_date|pickup_time|dropoff_date|dropoff_time|passenger_count|trip_distance|payment_type|fare_amount|tip_amount|tolls_amount|total_amount| pzone| dzone|
+--------+-----------+-----------+------------+------------+---------------+-------------+------------+-----------+----------+------------+------------+-----------------+--------------+
| 2| 2021-03-01| 0| 2021-03-01| 0| 1| 0.0| 2| 3.0| 0.0| 0.0| 4.3| NV| NV|
| 2| 2021-03-01| 0| 2021-03-01| 0| 1| 0.0| 2| 2.5| 0.0| 0.0| 3.8| Manhattanville|Manhattanville|
| 2| 2021-03-01| 0| 2021-03-01| 0| 1| 0.0| 2| 3.5| 0.0| 0.0| 4.8| Manhattanville|Manhattanville|
| 1| 2021-03-01| 0| 2021-03-01| 0| 0| 16.5| 1| 51.0| 11.65| 6.12| 70.07|LaGuardia Airport| NA|
| 2| 2021-03-01| 0| 2021-03-01| 0| 1| 1.13| 1| 5.5| 1.86| 0.0| 11.16| East Chelsea| NV|
+--------+-----------+-----------+------------+------------+---------------+-------------+------------+-----------+----------+------------+------------+-----------------+--------------+
only showing top 5 rows
# cleaning -------------------------------------------------------------------
# data clearning
# fare, tip, tolls ์ ๋ํ ๊ฒ์ ๋์ค์ df ๋ง๋ค๋ ์ ์ฒ๋ฆฌํด์ฃผ์.
query = '''
SELECT
*
FROM
taxi t
WHERE
t.total_amount < 2000
AND t.total_amount > 0
AND t.trip_distance < 100
AND t.passenger_count < 6
AND t.pickup_date >= '2021-01-01'
AND t.pickup_date < '2021-08-01'
AND t.dropoff_date >= '2021-01-01'
AND t.dropoff_date < '2021-08-03'
'''
df_c = spark.sql(query)
df_c.createOrReplaceTempView('cleaned')
์ ๋ต 2. ๋ง์ ์๊ธ & ๋ง์ ํ
๋ง์ ์๋์ ๋ฐ์ผ๋ฉด์, ์๊ธ๊ณผ ํ๊น์ง ๋ง์ด ๋ฒ์ด๋ค์ผ ์ ์๋ค๋ฉด ์์
์ด ์ ์ ํ ๊ฒ์ด๋ค.
์ด๋ค ์ํฉ์์ ์๊ธ๊ณผ ํ์ด ๋ง์ด ๋์ฌ๊น? ์๊ธ๊ณผ ํ์ด ๋์ ๊ฒฝ์ฐ๋ฅผ ๋ถ์ํด๋ณด๊ณ , ๋๋์๊ฐ ์ผ๋ถ ์นผ๋ผ ๋ง์ผ๋ก ์๊ธ๊ณผ ํ์ ์์ธกํด๋ณด์. ์๋์ด ์ฝํ์ ๋, ์๊ธ๊ณผ ํ์ด ๋ง์ด ๋์ฌ ๊ฒ์ผ๋ก ์์ธกํ๋ฉด ์ฝ์ ์๋ฝํ๋ API๋ฅผ ๋ง๋ค์ด๋ณด์.
(1) ์๊ธ & ํ ๋ถ์
A. ์์ผ๊ณผ fare, distance, tip์ ๊ด๊ณ
๋จผ์ ์์ผ๋ณ๋ก fare, distance, tip์ ํ๊ท ์ ๋น๊ตํ๋ค.
์ํ์๋ชฉ๊ธํ ์ผ์ ๊ฑฐ๋ฆฌ, ์๊ธ, ํ์ ์ํฅ์ ์คฌ์๊น?
# ์์ผ๋ณ fare, distance, tip ํ๊ท
query = '''
SELECT
DATE_FORMAT(c.pickup_date, 'EEEE') AS day_of_week,
MEAN(c.trip_distance) AS distance_mean,
MEAN(c.fare_amount) AS fare_mean,
MEAN(c.tip_amount) AS tip_mean
FROM
cleaned c
GROUP BY
day_of_week
'''
weekday_df = spark.sql(query).toPandas()
# ๊ทธ๋ํ ๊ทธ๋ฆฌ๊ธฐ
for i in ['distance_mean', 'fare_mean', 'tip_mean']:
fig, ax = plt.subplots(figsize=(16,6))
plt.title(i, fontsize = 30)
sns.barplot(
x = 'day_of_week',
y = i,
data = weekday_df
)
์์ผ๋ณ ๊ฑฐ๋ฆฌ๋ ์์์ผ -> ์ผ์์ผ๋ก ํฅํ ์๋ก ์ปค์ง๋ค. ์ฃผ๋ง์ ์ถํด๊ทผ๋ณด๋จ ์๋ค๋ฅธ ๊ณณ์ ๋๋ฌ ๊ฐ๊ฑฐ๋ ๋จผ ๊ณณ์ ๋ณผ ์ผ์ ๊ฐ๋ ์ผ์ด ๋ ๋ง์์ ์ด๋ฐ ์์์ด ๋์จ ๊ฒ์ผ๋ก ๋ณด์ธ๋ค.
fare๋ ์์ผ๋ณ๋ก ํฌ๊ฒ ์ฐจ์ด๊ฐ ๋๋ณด์ด์ง ์๋๋ค. fare๊ฐ distance์ฒ๋ผ ์์์ผ -> ์ผ์์ผ๋ก ์ปค์ง๋ ์์์ ๋ ์ง๋ง, distance๊ฐ ์ปค์ก๊ธฐ์ ๋น์ฐํ ์์์ด๋ค. ์์ผ ์์ฒด๊ฐ fare์ ํฐ ์ํฅ์ ์ฃผ๋ ๊ฒ ๊ฐ์ง๋ ์๋ค..
fare์ ๋ฐํด, ํ์ ์ ์๋ฏธํ๋ค๊ณ ๋ณผ ์ ์๋ค. ์ ์ด์ ํ์ ๋ณด๋์ค์ ๋๋์ด๊ธฐ์ 1๋ฌ๋ฌ๋ง ๋ฐ์๋ ๊ฐ๊ฟ์ด๋ค. ์ผ์์ผ์ ์ฌ๋๋ค์ด ๊ธฐ๋ถ์ด ์ข์์ง tip์ ๋ ๋ง์ด ์ค๋ค. ์ด๋ผ? ์์์ ๊ฑฐ๋ฆฌ๊ฐ ์ผ์์ผ๋ก ๊ฐ์๋ก ๋์ด๋ฌ๋ค. ํ๋ ์์์ผ -> ์ผ์์ผ๋ก ๊ฐ์๋ก ์กฐ๊ธ์ฉ ๋์ด๋๋ ์์์ธ๋ฐ, ๊ทธ๋ ๋ค๋ฉด tip๊ณผ distance๊ฐ ๊ด๊ณ์๋ ๊ฒ์ด ์๋๊น?
B. Distance์ Fare, Tip ๊ณผ์ ๊ด๊ณ
๊ฑฐ๋ฆฌ์ ์๊ธ ๋ฐ ํ ์ฌ์ด์ ๊ด๊ณ๋ฅผ ๋ฐํ๊ธฐ ์ํด ์ฐํฌ๋ ๊ทธ๋ํ๋ฅผ ๊ทธ๋ ธ๋ค. ์ด์ด ํผ์ด์จ ์๊ด๊ณ์๋ฅผ ์ฌ์ฉํ ํ, ํํธ๋งต์ ๊ทธ๋ ธ๋ค.
query = '''
SELECT
c.trip_distance,
c.fare_amount,
c.tip_amount
FROM
cleaned c
WHERE
c.fare_amount > 0
AND c.fare_amount < 100
AND c.tip_amount > 0
AND c.tip_amount < 100
'''
distance_df = spark.sql(query).toPandas()
for i in ['fare_amount', 'tip_amount']:
fig, ax = plt.subplots(figsize=(16,6))
plt.title(i, fontsize = 30)
sns.scatterplot(
x = 'trip_distance',
y = i,
data = distance_df
)
fig, ax = plt.subplots(figsize=(16,6))
plt.title("Person Correlation of Features", fontsize = 30)
sns.heatmap(distance_df.corr(), cmap=colormap, annot=True)
[๊ฑฐ๋ฆฌ์ ์๊ธ ๋ฐ์ดํฐ์ ์ฐํฌ๋]
์๊ธ์ ์ ์ด์ ๊ฑฐ๋ฆฌ์ ๋น๋กํจ์ผ๋ก ๊ทธ๋ํ๋ ๋น์ฐํ ๊ฒฐ๊ณผ๋ค.
[๊ฑฐ๋ฆฌ์ ํ ๋ฐ์ดํฐ์ ์ฐํฌ๋]
ํ์ ์๊ธ๋งํผ์ด๋ ๊ฑฐ๋ฆฌ์ ๋น๋กํ์ง ์๋ค.
๊ฑฐ๋ฆฌ๊ฐ 10 mile ์ดํ์ธ ๊ฒฝ์ฐ, ํ์ด ๋ฒ์๊ฐ ๊ฑฐ์ ๋น์ทํ๋ค. ํ์ง๋ง 10 mile์ด ๋์ด๊ฐ์๋ก ํ๋ ์กฐ๊ธ์ฉ ์ฆ๊ฐํจ์ ํ์ธํ ์ ์๋ค.
[๊ฑฐ๋ฆฌ, ์๊ธ, ํ์ ์๊ด๊ด๊ณ ํํธ๋งต]
๊ฑฐ๋ฆฌ & ํ์ ์๊ด๊ด๊ณ : 0.78
๊ฑฐ๋ฆฌ & ์๊ธ์ ์๊ด๊ด๊ณ : 0.95
์๊ธ & ํ์ ์๊ด๊ด๊ณ : 0.81
์ด๋ค์ ๋งค์ฐ ์ค์ํ ๊ฒฐ๊ณผ๋ค. ํนํ ์๊ธ์ด ์ปค์ง ์๋ก ํ๋ ์ปค์ง๋ค๋ ๊ฒ์, ๊ณง ๊ฑฐ๋ฆฌ๊ฐ ๋ฉ์ด์ง๋ฉด ํ๋ ์ปค์ง ํ๋ฅ ์ด ํผ์ ์๋ฏธํ๋ค.
C. ์ฅ์๋ณ Fare, Tip ๊ด๊ณ ๋ถ์
์ฅ์์ ๋ฐ๋ผ์ ์๊ธ๊ณผ ํ์ด ๋ฌ๋ผ์ง๊น? ํ์ธํ ๊ฒฐ๊ณผ, ์ฅ์์ ๋ฐ๋ผ ์๊ธ๊ณผ ํ์ ํ๊ท ์ด ์ฒ์ฐจ๋ง๋ณ๋ก ๋๋จ์ ํ์ธํ๋ค. ๋ฐ์ดํฐ์ ํฌํจ๋ ์ฅ์๊ฐ ์๋ ๋ง์์, Top 5์ผ๋ก ์๊ธ๊ณผ ํ์ด ๋์ ์ฅ์๋ฅผ ์ถ๋ ธ๋ค.
# pzone
query = '''
SELECT
c.pzone,
MEAN(c.trip_distance) AS distance_mean,
MEAN(c.fare_amount) AS fare_mean,
MEAN(c.tip_amount) AS tip_mean
FROM
cleaned c
GROUP BY
c.pzone
ORDER BY
fare_mean desc
LIMIT 5
'''
pzone_df = spark.sql(query).toPandas()
# ๊ทธ๋ํ ๊ทธ๋ฆฌ๊ธฐ
fig, ax = plt.subplots(figsize=(16,6))
plt.title('Top 5 pzone in fare_mean', fontsize = 30)
sns.barplot(
x = 'pzone',
y = 'fare_mean',
data = pzone_df
)
--------
# pzone
query = '''
SELECT
c.pzone,
MEAN(c.trip_distance) AS distance_mean,
MEAN(c.fare_amount) AS fare_mean,
MEAN(c.tip_amount) AS tip_mean
FROM
cleaned c
GROUP BY
c.pzone
ORDER BY
tip_mean desc
LIMIT 5
'''
pzone_df = spark.sql(query).toPandas()
# ๊ทธ๋ํ ๊ทธ๋ฆฌ๊ธฐ
fig, ax = plt.subplots(figsize=(16,6))
plt.title('Top 5 pzone in tip_mean', fontsize = 30)
sns.barplot(
x = 'pzone',
y = 'tip_mean',
data = pzone_df
)
-------
# dzone
query = '''
SELECT
c.dzone,
MEAN(c.trip_distance) AS distance_mean,
MEAN(c.fare_amount) AS fare_mean,
MEAN(c.tip_amount) AS tip_mean
FROM
cleaned c
GROUP BY
c.dzone
ORDER BY
fare_mean desc
LIMIT 5
'''
dzone_df = spark.sql(query).toPandas()
# ๊ทธ๋ํ ๊ทธ๋ฆฌ๊ธฐ
fig, ax = plt.subplots(figsize=(16,6))
plt.title('Top 5 dzone in fare_mean', fontsize = 30)
sns.barplot(
x = 'dzone',
y = 'fare_mean',
data = dzone_df
)
--------
# dzone
query = '''
SELECT
c.dzone,
MEAN(c.trip_distance) AS distance_mean,
MEAN(c.fare_amount) AS fare_mean,
MEAN(c.tip_amount) AS tip_mean
FROM
cleaned c
GROUP BY
c.dzone
ORDER BY
tip_mean desc
LIMIT 5
'''
dzone_df = spark.sql(query).toPandas()
# ๊ทธ๋ํ ๊ทธ๋ฆฌ๊ธฐ
fig, ax = plt.subplots(figsize=(16,6))
plt.title('Top 5 dzone in tip_mean', fontsize = 30)
sns.barplot(
x = 'dzone',
y = 'tip_mean',
data = dzone_df
)
[Pickup zone : ์๊ธ TOP 5]
์น์ฐจ ์ง์ญ ์ค ์๊ธ Top 5๋ ๋ค์๊ณผ ๊ฐ๋ค.
1์. Charleston/Tottenville
2์. Prince's Bay/Annadale
3์. Great Kills Park
4์. Rossville/Woodrow
5์. Arden Heights
[Pickup zone : ํ TOP 5]
์น์ฐจ ์ง์ญ ์ค ํ์ด ๊ฐ์ฅ ๋ง์ Top 5์ด๋ค. ์๊ธ์ด ๋ง์ด ๋์ค๋ ์ง์ญ๊ณผ ๋ค์ ๋ค๋ฆ์ ํ์ธํ ์ ์๋ค.
1์. Oakwood
2์. Newark Airport
3์. NA
4์. Port Richmond
5์. Flushing Meadows-Corona Park
[Dropoff zone : ์๊ธ TOP 5]
ํ์ฐจ ์ง์ญ ์ค ์๊ธ์ด Top 5์ธ ๊ณณ๋ค์ด๋ค. ์น์ฐจ ์ง์ญ Top 5์ ๊ฝค ๋น์ทํ๋ค!
1์. Charleston/Tottenville
2์. Prince's Bay/Annadale
3์. Rossville/Woodrow
4์. Arden Heights
5์. NA
[Dropoff zone : ํ TOP 5]
ํ์ฐจ ์ง์ญ ์ค ํ์ด Top 5์ธ ๊ณณ๋ค์ด๋ค. ์น์ฐจ ์ง์ญ ํ Top 5์ ๊ฑฐ์ ๋น์ทํ๋ฉฐ, JFK Airport๋ง ๋ค๋ฅด๋ค.
1์. Oakwood
2์. NA
3์. Oakwood
4์. JFK Airport
5์. Prince's Bay/Annadale
์ด ๋ชจ๋๋ฅผ ๋ด์ ์ง๋์ ๋ํ๋ด๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
์ด์ ํฌ์คํ ์์ ์์๋ณธ ์๋์ด ๋ง์ ์ง์ญ์ ๋ด์ญ ๋ฒํ๊ฐ์๋ค.
ํ์ง๋ง ์๊ธ, Tip์ด ๋ง์ ์ง์ญ์ ๊ทธ๋ณด๋ค ๋ฉ์งํ ๋จ์ด์ง ๊ณณ๋ค์ด๋ค. ์ด๊ณณ๋ค์ ๋ณดํต ๋ฒํ๊ฐ์ ๋จ์ด์ ธ ์๊ธฐ์, ์น์ฐจํ๋ฉด ๋จผ ๊ณณ์ผ๋ก ๊ฐ๊ธฐ์ ์๊ธ์ ๋ง์ด ๋ด์ผ ํ๋ค. ๋ ์ด๊ณณ๋ค์ ํ์ฐจํ๋ ค๋ฉด ๋จผ ๊ณณ์์ ์์ผ ํ๊ธฐ์ ๋ ์๊ธ์ ๋ง์ด ๋ด์ผ ํ๋ค. ์๊ธ๋ ๋ง๊ณ ๊ฑฐ๋ฆฌ๋ ํฌ๋ ํ๋ ์์ฐ์ค๋ ์ปค์ง๋ ๊ฒ์ด๋ค. ์๋ฌด๋๋ ๋ง๋ฅ ํ๊ณผ ์๊ธ์ด ๋ง๋ค๊ณ ์ข์ํด์๋ ์๋๋ ๊ฒ ๊ฐ๋ค. ์๊ธ, ํ์ ์ข ๋ ๋ง์ด ์ป์ผ๋ ค๋ค ์ฌ๋์ด ์๋ ๊ณณ์ผ๋ก ๊ฐ์, ๋ค์ ์๋์ ๋ชป ๋ฐ์ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
D. Fare, Tip ์์ธกํ๊ธฐ
Fare, Tip๊ณผ ๋ค๋ฅธ ๋ณ์๋ค๊ฐ์ ์๊ด๊ด๊ณ๋ ์ด๋ ์ ๋ ํ์ ํ๋ค. ์ด์ ๋จธ์ ๋ฌ๋ ๋ชจ๋ธ์ ํตํด ์์ ์์ธกํ๋ ๋ด์ ๋ง๋ค์ด๋ณด์. ์์์ ์๊ด๊ด๊ณ๋ฅผ ํ์ ํด์ ์์ธกํด ์ค ํ ๋ ๊ธฐ์ฌ๋ค์๊ฒ ์ด๋ณด๋ค ์์ํ ์์ฌ๊ฒฐ์ ๋์ฐ๋ฏธ๊ฐ ์์ ๊ฒ์ด๋ค.
๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ ๊ณผ์ ๊ณผ ๋ชจ๋ธ ํ์ดํผ ํ๋ผ๋ฏธํฐ ํ๋ ๊ณผ์ ์ ์ด์ ํฌ์คํ ์์ ๋ค๋ค์๋ค. ์ฝ๋๊ฐ ์ดํด๋์ง ์์ ๊ฒฝ์ฐ, ์ด์ ํฌ์คํ ์์ ๋ณด๊ณ ์ค๊ธธ ๋ฐ๋๋ค.
Fare ์์ธก ๋ณ์ : ์น์ฐจ ์ฅ์, ํ์ฐจ ์ฅ์, ์์ผ, ์น๊ฐ ์, ๊ฑฐ๋ฆฌ, ์น์ฐจ ์๊ฐ
Tip ์์ธก ๋ณ์ : ์น์ฐจ ์ฅ์, ํ์ฐจ ์ฅ์, ์์ผ, ์น๊ฐ ์, ๊ฑฐ๋ฆฌ, ์น์ฐจ ์๊ฐ, ์ง๋ถ ๋ฐฉ๋ฒ
# fare ์์ธก ๋ชจ๋ธ ------------------------------------------------------------
# ์ ์ฒ๋ฆฌ ํ์ดํ๋ผ์ธ
transform_stages = stages
pipeline = Pipeline(stages = transform_stages)
fitted_transformer = pipeline.fit(train_df)
vtrain_df = fitted_transformer.transform(train_df)
vtest_df = fitted_transformer.transform(test_df)
# ๋ชจ๋ธ๋ง ๋ฐ ํ์ต
model = lr.fit(vtrain_df)
# R2
model.summary.r2
๊ฒฐ๊ณผ : 0.8121402678393606
# ๋ชจ๋ธ ์ ์ฅ
model_dir = "C:/DE study/data-engineering/01-spark/data/model"
model.save(model_dir)
# tip ์์ธก ๋ชจ๋ธ ------------------------------------------------------------
# ์ ์ฒ๋ฆฌ ํ์ดํ๋ผ์ธ
transform_stages = stages
pipeline = Pipeline(stages = transform_stages)
fitted_transformer = pipeline.fit(train_df)
vtrain_df = fitted_transformer.transform(train_df)
vtest_df = fitted_transformer.transform(test_df)
# ๋ชจ๋ธ๋ง ๋ฐ ํ์ต
model2 = lr.fit(vtrain_df)
# R2
model2.summary.r2
๊ฒฐ๊ณผ : 0.46363365869062256
# ๋ชจ๋ธ ์ ์ฅ
model_dir = "C:/DE study/data-engineering/01-spark/data/model"
model2.save(model_dir)
ํ ์์ธก ๋ชจ๋ธ์ ์ฑ๋ฅ์ด ์ข ๋ฎ๋ค... ์ผ๋จ ์ฃผ์ด์ง ์นผ๋ผ์์ ์ต์ ์ผ๋ก ๋ณด์ด๋ฏ๋ก, ๋์๊ฐ์!
E. Fare, ํ ์์ธกํด์ ์ฝ ์กฐ์ธํด์ฃผ๋ API
๋๋ง์ Fare, Tip ์์ธก API๋ค. ์ ์ฒ๋ฆฌ ํ์ดํ๋ผ์ธ๊น์ง ๊ตณ์ด ์ฌ๋ฆฌ์ง ์์๋ค. ์์์ ์ค์ ํ ๋ณ์์ ๋ง์ถฐ ํ์ดํ๋ผ์ธ์ ๊ตฌ์ถํ๊ณ , ์ด์ ๋ง๋ ๋ชจ๋ธ์ ๋ถ๋ฌ์์ Fare, Tip์ ์์ธกํ๋ค.
from pyspark.sql.types import StructType,StructField, StringType, IntegerType
def fare_tip_API(pickup_id, dropoff_id, day_of_week, passenger, distance, pickup_time, p_type):
columns = ['pickup_location_id', 'dropoff_location_id', 'day_of_week',
'passenger_count', 'trip_distance', 'pickup_time', 'p_type']
data = [(pickup_id, dropoff_id, day_of_week, passenger, distance, pickup_time, p_type)]
rdd = spark.sparkContext.parallelize(data)
df = rdd.toDF(columns)
df_t = fitted_transformer.transform(df)
df_t_2 = fitted_transformer_2.transform(df)
fare_prediction = lr_model.transform(df_t)
tip_prediction = lr_model2.transform(df_t_2)
fare_prediction = fare_prediction.select(fare_prediction.prediction)
fare = fare_prediction.rdd.flatMap(list).first()
tip_prediction = tip_prediction.select(tip_prediction.prediction)
tip = tip_prediction.rdd.flatMap(list).first()
return fare, tip
์๋๋ฆฌ์ค ์ํฉ
๋ฐ๋ปํ ์ฃผ๋ง, ์ผ์์ผ ์์นจ 6์์ ๋น์ ์ ํ์๋ฅผ ์ด์ ํ๊ณ ์๋ค.
์ฝ์ด ๋ค์ด์๋ค.
์น์ฐจ ์ฅ์๋ Queens Astoria(7) ์ด๊ณ , ํ์ฐจ ์ฅ์๋ Brooklyn Bay Ridge(15)์ด๋ค. ๊ฑฐ๋ฆฌ๋ ๋๋ต 17 mile. ์น๊ฐ์ ๋ ๋ช ์ด๋ค. ๊ณ์ฐ์ ํ๊ธ์ผ๋ก ํ๊ฒ ๋ค๊ณ ํ๋ค. ์ง๊ธ ๋น์ฅ ์๊ธ๊ณผ ํ์ ์์ธกํ๋ผ!
fare, tip = fare_tip_API(7, 15, 0, 2, 17, 6, "Cash")
print(f'์์ ์๊ธ์ {fare} ์
๋๋ค.')
print(f'์์ ํ์ {tip} ์
๋๋ค.')
์์ ์๊ธ์ 42.24078328599208 ์
๋๋ค.
์์ ํ์ 3.6536566893473803 ์
๋๋ค.
์์ ์๊ธ : 42.2 ๋ฌ๋ฌ
์์ ํ: 3.65 ๋ฌ๋ฌ
์ฝ์ ๋ฐ์ ๊ฒ์ธ์ง ๋ง ๊ฒ์ธ์ง๋ ๋น์ ์ ๋ชซ์ด๋ค!
์ ๋ต 3. ํ๊ธ ๊ฒฐ์
๋๋ง์ ๋ง์ง๋ง ๊ผผ์๋ค. ์๋์ ํ์์ ๋์ ์ด์ฌํ ๋ฒ์๋ค๋ฉด, ์ธ๊ธ์ ์ต๋ํ ์๊ปด์ ์ด์๋จ์์ผ ํ๋ค.
* ๋ณธ ๋ฐ์ธ์ ๊ธ์ด์ด์ ์ถ์ ํ๋์๋ ์ฐ๊ด์์ง ์์ต๋๋ค.
์๋์ด ํ๊ธ ๊ฒฐ์ ๋ฅผ ํ ๊ฒฝ์ฐ, ์ธ๊ธ์ ํผํด๊ฐ ์ ์๋ค. ๊ทธ๋ฅ ์๋ ์ ๊ณ ๋ฅผ ์ ํ๋ฉด ๊ทธ๋ง์ด๊ธฐ ๋๋ฌธ์ด๋ค.
๋ฐ๋ผ์ ์ด๋ค ์ฅ์, ์ด๋ค ์๋์ ํ์ธ ๋ ํ๊ธ์ ๋ฐ์ ์ ์๋์ง ๋ถ์ํด๋ณด์.
[ํ๊ธ๊ณผ ์ ์ฉ์นด๋ ๊ฒฐ์ ์ ๋น๋์]
์ญ์ ์์ฆ์ ์ ์ฉ์นด๋๋ฅผ ๋ง์ด ์ด๋ค.
[ํ๊ธ๊ณผ ์ ์ฉ์นด๋์ ํ ํ๊ท ]
์์์น ๋ชปํ ์ผ์ด ๋ฐ์ํ๋ค. ํ๊ธ์ผ๋ก ํ์ ์ค ๊ฒฝ์ฐ๊ฐ ๊ฑฐ์ ์๋ค๊ณ ๋์๋ค. ์ ๋ ์์ ์๊ฐ ์๋ ์ผ์ด๋ผ ๋ฐ์ดํฐ๋ฅผ ๋ค์ ํ์ธํ๋๋ฐ ๊ณ์ ๋๊ฐ์ ๊ฒฐ๊ณผ๊ฐ ๋์๋ค. ํ ๊ฐ์ง ์ ์ถํ ๊ฒ์,
ํ๋ ์๋์ ํฌํจ๋๊ธฐ ๋๋ฌธ์, ํ๊ธ ๊ฒฐ์ ๋ฅผ ํ ๊ฒฝ์ฐ ๊ทธ๋ฅ ํ์ ๊ฟ๊บฝํ ๊ฒ ๊ฐ๋ค. ์ด์ฉ๋ฉด ๋น์ฐํ ๊ฒฐ๊ณผ๋ผ์ ๋ฉ๋์ด ๋๋ค. ์ด์ ๋ฐ๋ผ ํ๊ธ&์นด๋์ ๋ฐ๋ฅธ ํ ํฌ๊ธฐ์ ๋ณํ๋ ์ ์ ์๊ฒ ๋์๋ค. ํ ๋ง๊ณ ์๊ธ, ๊ฑฐ๋ฆฌ ์ธก๋ฉด์ ๋น์ทํ ๊ฒฐ๊ณผ๊ฐ ๋์๋ค.
์ง๊ธ๊น์ง ํ์๋ฐ์ดํฐ๋ฅผ ์ด์ฉํ์ฌ, ์ด๋ป๊ฒ ํ๋ฉด ํ์๋ก ๋์ ๋ ๋ฒ ์ ์์์ง ๊ณ ์ฐฐํด ๋ณด์๋ค. ์์ ๋ถ์๋ค์ ๊ณฑ์น์ด๋ณด๋ฉฐ ๋น์ ์ ํ์ ์ ๋ต์ ์๋กญ๊ฒ ์ธ์๋ณด๊ธธ ๋ฐ๋๋ค!
์ฌ๊ธฐ๊น์ง ์ค๋๋ผ ๊ณ ์ํ์ จ์ต๋๋ค.