python - 基于多个数据点的评分

python - scoring based on multiple data points

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

除了数百个 if 语句和 adding/subtracting 分数之外,还有推荐的编码方法吗?

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

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

我认为你的方法很好,不值得尝试做其他事情。您可能希望通过定义如下函数来更好地组织它:

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)
    ...

我想你也可以在这里使用 "chain of responsibility" 模式:

The pattern allows multiple objects to handle the request without coupling sender class to the concrete classes of the receivers. The chain can be composed dynamically at runtime with any handler that follows a standard handler interface.

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

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]

然后,定义各种得分手classes,例如:

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)