【问题标题】:python - scoring based on multiple data pointspython - 基于多个数据点的评分
【发布时间】:2019-09-11 07:15:51
【问题描述】:

需要有关执行此操作的最简单方法的指导。我有多个资产,每个资产都有多个数据点。我希望根据对每个数据点的决策为每个资产分配一个值。例如,每个资产是一栋房子,数据点包括窗户的数量、车库门、破损的栅栏等,每栋房子都会有一个分数。

除了数百个 if 语句和从分数中加/减之外,还有推荐的编码方式吗?

我打算如何执行此操作的示例

def score_house(house):
    # score house
    score = 0
    if (house.windows > 2): score += 10
    if (house.garage): score += 10
    if (house.fence == 'broken'): score += 80
    return score

【问题讨论】:

  • 您是否正在寻找实质性的改变?
  • 更多的只是确保什么是最有效的和pythonic。

标签: python scoring


【解决方案1】:

我认为你的方法很好,不值得尝试做其他事情。您可能想通过定义这样的函数来组织它:

def add_score(x, score): 
    score += x
    return score

还有一个像这样的dictionary

sdict = {windows: 10, garage: 10, broken_fence: 10}

这样你就可以这样调用你的函数了:

def score_house(house):
    # score house
    score = 0
    if (house.windows > 2): add_score(sdict[windows])
    if (house.garage): add_score(sdict[garage])
    if (house.fence == 'broken'): add_score(sdict[broken_fence])
    return score

并且可以轻松地从单个 dictionary 更改评分。

您也可以(现在考虑一下,可能应该)使用Enums

from enum import Enum
class Scoring(Enum):
   WINDOWS = 10
   ...

def score_house(house):
    # score house
    score = 0
    if (house.windows > 2): add_score(Scoring.WINDOWS)
    ...

【讨论】:

  • 我喜欢简洁。谢谢
【解决方案2】:

我认为您也可以在这里使用“责任链”模式:

该模式允许多个对象处理请求,而无需将发送者类耦合到接收者的具体类。该链可以在运行时与任何遵循标准处理程序接口的处理程序动态组合。

使用这种模式的好处在于,您可以在单独的模块中定义和扩展不同的记分器,并在运行时根据问题条件动态组合它们。这是你如何做到的。首先,定义一个父 scorer 类:

from functools import reduce


class BaseScorer(object):

    def __init__(self):
        self._next_scorer = None

    def set_next(self, scorer):
        self._next_scorer = scorer

        return scorer

    def _call_next(self, house, score):

        if self._next_scorer is None:
            return score

        return self._next_scorer.score(house, score)

    def score(self, house, score=0):
        raise NotImplementedError

    @staticmethod
    def chain(scorers):
        reduce(lambda x, y: x.set_next(y), scorers)

        return scorers[0]

然后,定义各种记分器类,例如:

class WindowScorer(BaseScorer):

    def score(self, house, score=0):

        if house.windows > 2:
            score = score + 10

        return self._call_next(house, score)


class GarageScorer(BaseScorer):

    def score(self, house, score=0):

        if house.garage:
            score = score + 10

        return self._call_next(house, score)


class FenceScorer(BaseScorer):

    def score(self, house, score=0):

        if house.fence == 'broken':
            score = score - 5

        return self._call_next(house, score)

这就是它的使用方法:

scorer = BaseScorer.chain([
    WindowScorer(),
    GarageScorer(),
    FenceScorer()
])

house = House(windows=4, garage=True, fence='nice')
score = scorer.score(house)

【讨论】:

  • 鉴于每个属性(比较、分数)有两个唯一计算,这是最简洁的方法。
猜你喜欢
  • 2020-09-01
  • 2017-07-23
  • 2018-08-02
  • 2012-02-19
  • 2018-04-05
  • 1970-01-01
  • 1970-01-01
  • 2023-02-16
  • 1970-01-01
相关资源
最近更新 更多