Altair LOESS 低于平均值,远低于线性回归
Altair LOESS fit below avg values, far below linear regresion
我对 Altair 比较陌生,运行 遇到了一个我似乎无法理解的问题。基本上,当我将 LOESS 拟合到我的数据时,整个 LOESS 线被绘制在样本平均值以下,低于每个时间点的平均值,并且低于我的回归拟合。
该数据是一个包含多个地区的月逮捕率(每 1,000 人第 2 部分犯罪)的面板。
这是一个包含月平均利率、线性回归拟合和我的黄土的图表。如您所见,黄土远低于所有数据:
代码是:
import pandas as pd
import altair as alt
alt.data_transformers.disable_max_rows()
# Load panel data. Monthly arrest rate (part 2 crimes per 1,000 people)
# data for number of localities.
panel = pd.read_csv(
"https://github.com/nickeubank/im_baffled/raw/main/arrest_rates.csv.zip"
)
# And if I do averages for each month, I get
# a relatively smooth downward trend.
grouped_means = panel.groupby("years_w_decimals", as_index=False)[
["arrest_rate"]
].mean()
chart_grouped = (
alt.Chart(grouped_means)
.mark_circle(opacity=0.5)
.encode(
x=alt.X("years_w_decimals", scale=alt.Scale(zero=False)),
y=alt.Y("arrest_rate", scale=alt.Scale(zero=False)),
)
)
reg = (
alt.Chart(panel)
.encode(
x=alt.X("years_w_decimals", scale=alt.Scale(zero=False)),
y=alt.Y("arrest_rate", scale=alt.Scale(zero=False)),
)
.transform_regression(
"years_w_decimals",
"arrest_rate",
method="poly",
order=1,
)
.mark_line()
)
loess = (
alt.Chart(panel)
.encode(
x=alt.X("years_w_decimals", scale=alt.Scale(zero=False)),
y=alt.Y("arrest_rate", scale=alt.Scale(zero=False)),
)
.transform_loess(on="years_w_decimals", loess="arrest_rate", bandwidth=0.3)
.mark_line()
)
reg + chart_grouped + loess
任何人都可以看到出了什么问题吗?
我 认为 发生的事情是你有一些具有极端 y 值的点比另一个更影响回归计算,当你放大图时只是分组的平均值,它看起来比你看到所有这些极值点的全部图的差异更大。
panel2= panel.sample(200, random_state=200)
chart_grouped = (
alt.Chart(panel2)
.mark_circle(opacity=0.5)
.encode(
x=alt.X("years_w_decimals", scale=alt.Scale(zero=False)),
y=alt.Y("arrest_rate", scale=alt.Scale(zero=False)),
)
)
reg = (
alt.Chart(panel2)
.encode(
x=alt.X("years_w_decimals", scale=alt.Scale(zero=False)),
y=alt.Y("arrest_rate", scale=alt.Scale(zero=False)),
)
.transform_regression(
"years_w_decimals",
"arrest_rate",
)
.mark_line()
)
loess = (
alt.Chart(panel2)
.encode(
x=alt.X("years_w_decimals", scale=alt.Scale(zero=False)),
y=alt.Y("arrest_rate", scale=alt.Scale(zero=False)),
)
.transform_loess(
"years_w_decimals",
"arrest_rate",
)
.mark_line()
)
loess + reg
看起来很糟糕,但是用原始点绘制整个范围会使它看起来更合理。
也许这里最合适的是 运行 您在散点图中显示的点的两个回归,这就是分组点的样子:
chart_grouped = (
alt.Chart(grouped_means)
.mark_circle(opacity=0.5)
.encode(
x=alt.X("years_w_decimals", scale=alt.Scale(zero=False)),
y=alt.Y("arrest_rate", scale=alt.Scale(zero=False)),
)
)
reg = chart_grouped.transform_regression(
"years_w_decimals",
"arrest_rate",
).mark_line()
loess = chart_grouped.transform_loess(
"years_w_decimals",
"arrest_rate",
).mark_line()
chart_grouped + loess + reg
好的,经过大量调查,问题是,正如@joelostblom 所建议的那样,与异常值有关。
更具体地说,看起来 Vega 使用的是不太传统的 LOESS 实现(没有大量文档 :/):https://github.com/vega/vega-lite/issues/7686
我对 Altair 比较陌生,运行 遇到了一个我似乎无法理解的问题。基本上,当我将 LOESS 拟合到我的数据时,整个 LOESS 线被绘制在样本平均值以下,低于每个时间点的平均值,并且低于我的回归拟合。
该数据是一个包含多个地区的月逮捕率(每 1,000 人第 2 部分犯罪)的面板。
这是一个包含月平均利率、线性回归拟合和我的黄土的图表。如您所见,黄土远低于所有数据:
代码是:
import pandas as pd
import altair as alt
alt.data_transformers.disable_max_rows()
# Load panel data. Monthly arrest rate (part 2 crimes per 1,000 people)
# data for number of localities.
panel = pd.read_csv(
"https://github.com/nickeubank/im_baffled/raw/main/arrest_rates.csv.zip"
)
# And if I do averages for each month, I get
# a relatively smooth downward trend.
grouped_means = panel.groupby("years_w_decimals", as_index=False)[
["arrest_rate"]
].mean()
chart_grouped = (
alt.Chart(grouped_means)
.mark_circle(opacity=0.5)
.encode(
x=alt.X("years_w_decimals", scale=alt.Scale(zero=False)),
y=alt.Y("arrest_rate", scale=alt.Scale(zero=False)),
)
)
reg = (
alt.Chart(panel)
.encode(
x=alt.X("years_w_decimals", scale=alt.Scale(zero=False)),
y=alt.Y("arrest_rate", scale=alt.Scale(zero=False)),
)
.transform_regression(
"years_w_decimals",
"arrest_rate",
method="poly",
order=1,
)
.mark_line()
)
loess = (
alt.Chart(panel)
.encode(
x=alt.X("years_w_decimals", scale=alt.Scale(zero=False)),
y=alt.Y("arrest_rate", scale=alt.Scale(zero=False)),
)
.transform_loess(on="years_w_decimals", loess="arrest_rate", bandwidth=0.3)
.mark_line()
)
reg + chart_grouped + loess
任何人都可以看到出了什么问题吗?
我 认为 发生的事情是你有一些具有极端 y 值的点比另一个更影响回归计算,当你放大图时只是分组的平均值,它看起来比你看到所有这些极值点的全部图的差异更大。
panel2= panel.sample(200, random_state=200)
chart_grouped = (
alt.Chart(panel2)
.mark_circle(opacity=0.5)
.encode(
x=alt.X("years_w_decimals", scale=alt.Scale(zero=False)),
y=alt.Y("arrest_rate", scale=alt.Scale(zero=False)),
)
)
reg = (
alt.Chart(panel2)
.encode(
x=alt.X("years_w_decimals", scale=alt.Scale(zero=False)),
y=alt.Y("arrest_rate", scale=alt.Scale(zero=False)),
)
.transform_regression(
"years_w_decimals",
"arrest_rate",
)
.mark_line()
)
loess = (
alt.Chart(panel2)
.encode(
x=alt.X("years_w_decimals", scale=alt.Scale(zero=False)),
y=alt.Y("arrest_rate", scale=alt.Scale(zero=False)),
)
.transform_loess(
"years_w_decimals",
"arrest_rate",
)
.mark_line()
)
loess + reg
看起来很糟糕,但是用原始点绘制整个范围会使它看起来更合理。
也许这里最合适的是 运行 您在散点图中显示的点的两个回归,这就是分组点的样子:
chart_grouped = (
alt.Chart(grouped_means)
.mark_circle(opacity=0.5)
.encode(
x=alt.X("years_w_decimals", scale=alt.Scale(zero=False)),
y=alt.Y("arrest_rate", scale=alt.Scale(zero=False)),
)
)
reg = chart_grouped.transform_regression(
"years_w_decimals",
"arrest_rate",
).mark_line()
loess = chart_grouped.transform_loess(
"years_w_decimals",
"arrest_rate",
).mark_line()
chart_grouped + loess + reg
好的,经过大量调查,问题是,正如@joelostblom 所建议的那样,与异常值有关。
更具体地说,看起来 Vega 使用的是不太传统的 LOESS 实现(没有大量文档 :/):https://github.com/vega/vega-lite/issues/7686