Python - рассчитать расстояние с разными типами данных в Python

У меня есть данные с 11 атрибутами. Я хочу рассчитать расстояние по каждому из этих атрибутов. например, его атрибут (x1, x2, ..., x11), а для x1 & x2 имеет номинальный тип, x3, x4, ... x10 имеет порядковый тип, тогда x11 имеет двоичный тип. как я могу прочитать атрибуты с помощью Python? и как различать эти атрибуты в python и как различать эти атрибуты в python, чтобы я мог рассчитать расстояние? может кто-нибудь сказать мне, что мне делать? Спасибо

данные выборки: x1 (лесное хозяйство, плантация, другое, лесное хозяйство) x2 (плантация, плантация, кустарники, лес) x3 (высокий, высокий, средний, низкий) x4 (низкий, средний, высокий, высокий) x5 (высокий, низкий, средний , высокий) x6 (средний, низкий, высокий, средний) x7 (3, 1, 0, 4) x8 (низкий, низкий, высокий, средний) x9 (297, 298, 299, 297) x10 (1, 2, 0 , 4) x11 (t, t, t, f)


person user3500153    schedule 05.04.2014    source источник
comment
Не могли бы вы предоставить образцы данных?   -  person Hyperboreus    schedule 05.04.2014
comment
сохраните эти значения в виде списка. тогда вы можете вызвать youList [0], это x1   -  person Reverend_Dude    schedule 05.04.2014
comment
это пример данных: x1 (лесное хозяйство, плантация, другое, лесное хозяйство) x2 (плантация, плантация, кустарники, лес) x3 (высокий, высокий, средний, низкий) x4 (низкий, средний, высокий, высокий) x5 (высокий, низкий, средний, высокий) x6 (средний, низкий, высокий, средний) x7 (3, 1, 0, 4) x8 (низкий, низкий, высокий, средний) x9 (297, 298, 299, 297) x10 (1, 2, 0, 4) x11 (t, t, t, f)   -  person user3500153    schedule 05.04.2014
comment
Так каково же расстояние между лесным хозяйством и плантациями?   -  person Hugh Bothwell    schedule 05.04.2014
comment
поскольку x1 и x2 являются номинальным типом, я могу рассчитать расстояние с помощью d (i, j) = (p-m) / p. p - общее количество атрибутов, а m - атрибуты для i и j в одинаковом состоянии. ex d (1,2) = (2-0) / 2 = 1.   -  person user3500153    schedule 05.04.2014
comment
@ user3500153 Значит, расстояние между x1 =(forestry,plantation,other,forestry) и x2= (plantation, plantation, shrubs, forestry) составляет 2/4 = 1/2, потому что они имеют одинаковое значение во второй и последней позиции?   -  person Stephan Kulla    schedule 05.04.2014
comment
нет, так как в данных выборки 4 строки. первый ряд (лесное хозяйство, плантация, высокий, низкий, высокий, средний, 3, низкий, 297, 1, t), строка 2 (плантация, плантация, высокий, средний, низкий, низкий, 1, низкий, 298, 2, т). поэтому d (1,2) - это расстояние между строками 1 и 2, но в 1 строке есть 3 типа данных (порядковый, номинальный, двоичный), поэтому мне пришлось вычислить расстояние в соответствии с типом данных, а затем я могу вычислить расстояние путем объединения результатов подсчета 3-х видов   -  person user3500153    schedule 05.04.2014
comment
@ user3500153 Смотрите последнее обновление моего ответа ...   -  person Stephan Kulla    schedule 05.04.2014


Ответы (2)


Вы можете сделать что-то вроде этого:

def distance(x,y):
    p = len(x)
    m = sum(map(lambda (a,b): 1 if a == b else 0, zip(x,y)))
    return float(p-m)/p

Пример:

x1 = ("forestry", "plantation", "high", "low", "high", "medium", 3, "low", 297, 1, True)
x2 = ("plantation", "plantation", "high", "medium", "low", "low", 1, "low", 298, 2, True)

print distance(x1,x2) # result: 0.636363636364 = (11-4)/7
person Stephan Kulla    schedule 05.04.2014
comment
Спасибо за вашу помощь. но расстояние можно использовать только для лесного хозяйства и плантаций. для значения high, low, medium, 3, 297 и другие - это тип порядкового номера, а для true, false - двоичный тип. так что это расстояние не может использоваться для всех данных. я должен вычислить данные порядкового типа, двоичного типа, а затем я могу получить расстояние со смешанными типами - person user3500153; 05.04.2014
comment
для двоичного типа (true, false) мы можем использовать это: d (i, j) = (r + s) / (q + r + s + t). r - это сумма переменных с i положительным и j отрицательным, s - это общая переменная с i отрицательным и j положительным, q - общая переменная с положительным i и j, t - общая переменная с отрицательным i и j - person user3500153; 05.04.2014
comment
и порядковый тип, мы должны заменить каждое значение его рангом (например, в данных low = 1, medium = 2, high = 3 и 0 = 1, 1 = 2, 2 = 3, 3 = 4, 4 = 5). затем нормализуйте рейтинг с помощью zif = (rif-1) / (mf-1). zif представляет значение для i-го объекта, рейтинг данных RIF, mf - общее количество данных (например, для низкого, среднего, высокого. mf = 3). так что последнее, что мы можем использовать, вычислить эти данные с евклидовым расстоянием - person user3500153; 05.04.2014
comment
Вы уже пробовали что-нибудь на питоне? Пожалуйста, опубликуйте свои попытки в своем вопросе. И не забудьте дать четкое и подробное описание того, как вы хотите рассчитать общее расстояние между двумя кортежами данных (я думаю, никто не будет читать эти комментарии, чтобы получить эту информацию ...). Также было бы хорошо предоставить пример двух кортежей данных и расстояние, которое вы хотите оставить в конце их. - person Stephan Kulla; 05.04.2014
comment
Я также не понял, как вы хотите рассчитать расстояние между двумя кортежами данных ... - person Stephan Kulla; 05.04.2014
comment
Я пробовал, но не могу, python - это новый язык программирования, который я изучил. Я хочу рассчитать расстояние для своего последнего задания. - person user3500153; 05.04.2014
comment
Вы имеете в виду евклидово расстояние? - person Stephan Kulla; 05.04.2014
comment
евклидово расстояние - последний шаг для порядкового типа - person user3500153; 05.04.2014
comment
Как вы хотите совместить три разных расстояния? Евклидово расстояние? Расстояние от максимальной нормы или расстояние от p-нормы? Должно ли каждое рассчитанное расстояние по типу иметь одинаковый вес для вашего окончательного расстояния? - person Stephan Kulla; 05.04.2014
comment
Я рекомендую вам сначала попробовать более простые примеры кода на Python. Если у вас с ними возникнут проблемы, вы можете разместить сообщение на этом сайте. Вы уже читали хороший учебник / книгу о питоне? (Я имею в виду прочитать подробно, пытаясь понять примеры кода) Вам также следует спросить друга, может ли он вам помочь (ваша проблема кажется слишком сложной для короткого ответа) - person Stephan Kulla; 05.04.2014
comment
спасибо @tampis за вашу помощь. Я попробую еще раз изучить Python. Я прочитал книгу о питоне, но я прочитаю еще раз подробно и попытаюсь понять код. - person user3500153; 05.04.2014

Я переписал это следующим образом:

Сначала я создаю фабрику номинального типа:

class BaseNominalType:
    name_values = {}   # <= subclass must override this

    def __init__(self, name):
        self.name = name
        self.value = self.name_values[name]

    def __str__(self):
        return self.name

    def __sub__(self, other):
        assert type(self) == type(other), "Incompatible types, subtraction is undefined"
        return self.value - other.value

# class factory function
def make_nominal_type(name_values):
    try:
        nv = dict(name_values)
    except ValueError:
        nv = {item:i for i,item in enumerate(name_values)}

    # make custom type
    class MyNominalType(BaseNominalType):
        name_values = nv
    return MyNominalType

Теперь я могу определить ваши номинальные типы,

Forest = make_nominal_type(["shrubs", "plantation", "forestry", "other"])
Level  = make_nominal_type(["low", "medium", "high"])
Bool   = make_nominal_type({"f":False, "t":True})

Затем я создаю фабрику типов MixedVector:

# base class
class BaseMixedVectorType:
    types = []          # <= subclass must
    distance_fn = None  # <=   override these

    def __init__(self, values):
        self.values = [type_(value) for type_,value in zip(self.types, values)]

    def dist(self, other):
        return self.distance_fn([abs(s - o) for s,o in zip(self.values, other.values)])

# class factory function
def make_mixed_vector_type(types, distance_fn):
    tl = list(types)
    df = distance_fn

    class MyVectorType(BaseMixedVectorType):
        types = tl
        distance_fn = df
    return MyVectorType

затем создайте свой тип данных,

# your mixed-vector type
DataItem = make_mixed_vector_type(
    [Forest, Forest, Level, Level, Level, Level, int, Level, int, int, Bool],
    ??? # have to define an appropriate distance function!
)

... но подождите, мы еще не определили функцию расстояния! Я написал класс, чтобы вы могли подключить любую функцию расстояния, которая вам нравится, в форме:

def manhattan_dist(_, vector):
    return sum(vector)

def euclidean_dist(_, vector):
    return sum(v*v for v in vector) ** 0.5

# the distance function per your description:
def fractional_match_distance(_, vector):
    return float(sum(not v for v in vector)) / len(vector)

Итак, мы закончили создание

# your mixed-vector type
DataItem = make_mixed_vector_type(
    [Forest, Forest, Level, Level, Level, Level, int, Level, int, int, Bool],
    fractional_match_distance
)

и протестировать как

def main():
    raw_data = [
        ('forestry', 'plantation', 'high', 'low', 'high', 'medium', 3, 'low', 297, 1, 't'),
        ('plantation', 'plantation', 'high', 'medium', 'low', 'low', 1, 'low', 298, 2, 't'),
        ('other', 'shrubs', 'medium', 'high', 'medium', 'high', 0, 'high', 299, 0, 't'),
        ('forestry', 'forestry', 'low', 'high', 'high', 'medium', 4, 'medium', 297, 4, 'f')
    ]

    a, b, c, d = [DataItem(d) for d in raw_data]

    print("a to b, dist = {}".format(a.dist(b)))
    print("b to c, dist = {}".format(b.dist(c)))
    print("c to d, dist = {}".format(c.dist(d)))

if __name__=="__main__":
    main()

что дает нам

a to b, dist = 0.363636363636
b to c, dist = 0.0909090909091
c to d, dist = 0.0909090909091
person Hugh Bothwell    schedule 05.04.2014