9

我有的:

  • 用户正在拍卖网站上出售 foobars。
  • 每个 foobar 都是相同的。
  • foob​​ar 的价格由用户决定。
  • 我将废弃每个价格列表以形成一个数据集,如下所示:
    $prices = ('foobar' => [12.34, 15.22, 14.18, 20.55, 9.50]);

我需要的:

  • 找到每天、每周、每月的实际平均市场价格。

我面临的问题:

  • 事实证明,异常值拒绝的实施效果不佳,因为数据存在偏差。
  • 用户极不可能将拍卖价格低于平均市场价格,因为它无法撤消。即使它远低于市场价格,这种情况也会很少发生,以至于整体平均水平不会受到影响。然而,试图抬高价格的用户更有可能发生,并且发生的频率足以影响实际的平均市场价值。

我想我会怎么做:

Daniel Collicott:

如果我理解正确,您想计算一件商品的最佳销售价值。(或者您是否正在尝试计算实际价值??)

卖家很自然地玩游戏(例如 ebay),试图最大化他们的利润。

出于这个原因,我会避免使用平均/SD 方法:它们对特定销售策略产生的异常值过于敏感。

博弈论方面,我认为聪明的卖家会通过研究他们的竞争对手和他们的历史销售产出来估计最高可能的销售价格(最大利润):找到甜蜜点。

出于这个原因,我将记录所有卖家的历史价格直方图并查看价格分布,使用接近模式的东西来确定最佳价格,即最常见的销售价格。更好的是,我会根据每个卖家的利润(与历史销量成正比)来衡量价格。

我怀疑这会更接近您的最佳市场价值;如果您正在寻找真正的市场价值,请在下方评论或在我的机器学习公司与我联系

我的问题:

  • 对@Daniel Collicott 的帖子中提到的事情的更详细解释:

    --> 最佳销售价值
    --> 实际销售价值
    --> 两者的算法

4

5 回答 5

7

使用平均值标准差,您的第一个问题非常简单:

$prices = array
(
    'bar' => array(12.34, 102.55),
    'foo' => array(12.34, 15.66, 102.55, 134.66),
    'foobar' => array(12.34, 15.22, 14.18, 20.55, 99.50, 15.88, 16.99, 102.55),
);

foreach ($prices as $item => $bids)
{
    $average = call_user_func_array('Average', $bids);
    $standardDeviation = call_user_func_array('standardDeviation', $bids);

    foreach ($bids as $key => $bid)
    {
        if (($bid < ($average - $standardDeviation)) || ($bid > ($average + $standardDeviation)))
        {
            unset($bids[$key]);
        }
    }

    $prices[$item] = $bids;
}

print_r($prices);

基本上,您只需要删除低于avg - stDev或高于avg + stDev.


和实际功能(从我的框架移植):

function Average()
{
    if (count($arguments = func_get_args()) > 0)
    {
        return array_sum($arguments) / count($arguments);
    }

    return 0;
}

function standardDeviation()
{
    if (count($arguments = func_get_args()) > 0)
    {
        $result = call_user_func_array('Average', $arguments);

        foreach ($arguments as $key => $value)
        {
            $arguments[$key] = pow($value - $result, 2);
        }

        return sqrt(call_user_func_array('Average', $arguments));
    }

    return 0;
}

输出(演示):

Array
(
    [bar] => Array
        (
            [0] => 12.34
            [1] => 102.55
        )

    [foo] => Array
        (
            [1] => 15.66
            [2] => 102.55
        )

    [foobar] => Array
        (
            [0] => 12.34
            [1] => 15.22
            [2] => 14.18
            [3] => 20.55
            [5] => 15.88
            [6] => 16.99
        )
)
于 2012-04-30T00:08:37.673 回答
3

如果您要做的只是标准化您的数据集 - 即收敛于反映均值的集合,那么您可以使用峰度偏度来表征数据集的结构以帮助识别异常值 - (计算每个点的指标使用数据集的其余部分旨在最小化 Kurtois 并保持偏度的趋势 - 拒绝极端值并重复,直到排除一个值不会显着改变指标)。

但是您的问题更有趣:

让我看看我是否正确:您对 foobar 市场的了解不完全,但您只能获得有限的具体信息。

您想使用有限的数据集来预测有关市场的隐藏信息。

您需要贝叶斯平均值(另请参阅贝叶斯推理)。

假设您每天有 1000 个价格;

对于每一天,计算:均值、众数、中位数、标准偏差、峰度和偏度 - 这给出了市场形状的句柄:

  • 均值和中位数将显示价格如何变动
  • mode & stdev 将显示市场的成熟程度(成熟市场应该有较低的 stdev)
  • 峰度将显示价格弹性 - 低值是有弹性的,高是更多的可塑性 - 也与成熟度有关
  • 偏度将显示需求趋势 - 左侧的长尾表示讨价还价,右侧的尾表示愿意支付更高的价格

比较每日价值将使您能够衡量市场的健康状况。

一旦您获得了几周的趋势数据(随着时间的推移会变得更好),您就可以开始测试真实价格。

  1. 首先,对数据集第一天的真实价格进行有根据的猜测。
  2. 使用倾斜加权价格样本计算市场的贝叶斯平均价格,但样本不超过每日集的 80% / stddev^2
  3. 这现在成为您的真实价格。
  4. 每天重复 2 到 4 次应该会给你一个缓慢移动的价格。

如果真实价格在跳跃,那么要么样本量太小,要么市场运行不正常(即一些参与者支付的价格高于价值,卖出低于价值,供应受到限制,购买价格与值等)。

我已经对二手车价格进行了建模(它们不是同质的),但我确实得到了一些合理的收敛 - +/- 10%,但这是在有限的数据集上。它似乎也适用于房价,而不是商品或足球比分。

它永远不会给你一个明确的预测答案,尤其是在拍卖环境中——但它应该让你比算术平均值更接近真实价格。

于 2012-05-16T11:58:32.110 回答
2

好的,经过大量的努力,无论异常值的最大值有多极端(或不极端),一个似乎都有效的解决方案。请记住,我的数学知识非常原始,所以请谨慎对待。

$prices = array
(
    'baz' => array(12.34, 15.66),
    'bar' => array(12.34, 102.55),
    'foo' => array(12.34, 15.66, 102.55, 134.66),
    'foobar' => array(12.34, 15.22, 14.18, 20.55, 99.50, 15.88, 16.99, 102.55),
);

foreach ($prices as $item => $bids)
{
    $average = average($bids);
    $standardDeviation = standardDeviation($bids);

    foreach ($bids as $key => $bid)
    {
        if ($bid > ($average + ($average - $standardDeviation)))
        {
            unset($bids[$key]);
        }
    }

    $prices[$item] = $bids;
}

print_r($prices);

function average($arguments)
{
    if (count($arguments) > 0)
    {
        return array_sum($arguments) / count($arguments);
    }

    return 0;
}

function standardDeviation($arguments)
{
    if (count($arguments) > 0)
    {
        $result = Average($arguments);

        foreach ($arguments as $key => $value)
        {
            $arguments[$key] = pow($value - $result, 2);
        }

        return sqrt(Average($arguments));
    }

    return 0;
}

输出(演示):

Array
(
    [baz] => Array
        (
            [0] => 12.34
            [1] => 15.66
        )

    [bar] => Array
        (
            [0] => 12.34
        )

    [foo] => Array
        (
            [0] => 12.34
            [1] => 15.66
        )

    [foobar] => Array
        (
            [0] => 12.34
            [1] => 15.22
            [2] => 14.18
            [3] => 20.55
            [5] => 15.88
            [6] => 16.99
        )
)
于 2012-04-30T01:51:41.507 回答
2

如果我理解正确,您想计算一件商品的最佳销售价值。(或者您是否正在尝试计算实际价值??)

卖家很自然地玩游戏(例如 ebay),试图最大化他们的利润。

出于这个原因,我会避免使用平均/SD 方法:它们对特定销售策略产生的异常值过于敏感。

博弈论方面,我认为聪明的卖家会通过研究他们的竞争对手和他们的历史销售产出来估计最高可能的销售价格(最大利润):找到甜蜜点。

出于这个原因,我将记录所有卖家的历史价格直方图并查看价格分布,使用接近模式的东西来确定最佳价格,即最常见的销售价格。更好的是,我会根据每个卖家的利润(与历史销量成正比)来衡量价格。

我怀疑这会更接近您的最佳市场价值;如果您正在寻找真正的市场价值,请在下方评论或在我的机器学习公司与我联系

于 2012-05-10T22:01:43.623 回答
2

丹,阅读您的评论,我开始认为您想要的东西可以非常简单地实现。这是在 C# 中,但它非常简单,应该很容易理解:

const double reasonable_price_range = 1.5;
List<double> prices = new List<double> { 50.00, 51.00, 52.00, 100.00, 101.00, 102.00, 150.00, 151.00, 152.00 };
double min = prices.Min();
var reasonable_prices = (from p in prices where p <= min * reasonable_price_range select p).ToList();

丢弃所有比最小价格大一定百分比的数字(百分比是 IMO 的最佳衡量标准),然后返回其余数字。

这应该适用于您的所有示例。1.5 常数是任意的,可能应该更高(问题是,如果我们知道价格 X 是合理的,那么价格可以涨到多高仍然被认为是合理的?)。但是,这取决于甚至没有一个低异常值 - 列表中的最低价格必须是合理的。

当然,min * 常数不一定是最优决策函数,但如果我们可以依赖 min 永远不会是异常值,问题就会变得简单得多,因为我们可以将它们与最小元素进行比较,而不是对元素进行分组。

于 2012-04-30T09:34:46.820 回答