Scipy Отрицательное расстояние? Какие?

У меня есть входной файл, который содержит числа с плавающей запятой до 4 знаков после запятой:

ie 13359 0.0000 0.0000 0.0001 0.0001 0.0002` 0.0003 0.0007 ... 

(первым является id). Мой класс использует метод loadVectorsFromFile который умножает его на 10000, а затем int() эти числа. Кроме того, я также просматриваю каждый вектор, чтобы убедиться, что внутри него нет отрицательных значений. Однако, когда я выполняю _hclustering , я постоянно вижу ошибку: "Linkage Z contains negative values" .

Я серьезно думаю, что это ошибка, потому что:

  1. Я проверил свои ценности,
  2. значения не равны достаточно малым или большим, чтобы приблизиться к пределам чисел с плавающей запятой и
  3. формула, которую я использовал для получения значений в файле, использует абсолютное значение (мой ввод DEFINITELY right).

Может кто-нибудь заучить меня, почему я вижу эту странную ошибку? Что происходит, это вызывает эту ошибку отрицательного расстояния?

=====

 def loadVectorsFromFile(self, limit, loc, assertAllPositive=True, inflate=True): """Inflate to prevent "negative" distance, we use 4 decimal points, so *10000 """ vectors = {} self.winfo("Each vector is set to have %d limit in length" % limit) with open( loc ) as inf: for line in filter(None, inf.read().split('\n')): l = line.split('\t') if limit: scores = map(float, l[1:limit+1]) else: scores = map(float, l[1:]) if inflate: vectors[ l[0]] = map( lambda x: int(x*10000), scores) #int might save space else: vectors[ l[0]] = scores if assertAllPositive: #Assert that it has no negative value for dirID, l in vectors.iteritems(): if reduce(operator.or_, map( lambda x: x < 0, l)): self.werror( "Vector %s has negative values!" % dirID) return vectors def main( self, inputDir, outputDir, limit=0, inFname="data.vectors.all", mappingFname='all.id.features.group.intermediate'): """ Loads vector from a file and start clustering INPUT vectors is { featureID: tfidfVector (list), } """ IDFeatureDic = loadIdFeatureGroupDicFromIntermediate( pjoin(self.configDir, mappingFname)) if not os.path.exists(outputDir): os.makedirs(outputDir) vectors = self.loadVectorsFromFile( limit, pjoin( inputDir, inFname)) for threshold in map( lambda x:float(x)/30, range(20,30)): clusters = self._hclustering(threshold, vectors) if clusters: outputLoc = pjoin(outputDir, "threshold.%s.result" % str(threshold)) with open(outputLoc, 'w') as outf: for clusterNo, cluster in clusters.iteritems(): outf.write('%s\n' % str(clusterNo)) for featureID in cluster: feature, group = IDFeatureDic[featureID] outline = "%s\t%s\n" % (feature, group) outf.write(outline.encode('utf-8')) outf.write("\n") else: continue def _hclustering(self, threshold, vectors): """function which you should call to vary the threshold vectors: { featureID: [ tfidf scores, tfidf score, .. ] """ clusters = defaultdict(list) if len(vectors) > 1: try: results = hierarchy.fclusterdata( vectors.values(), threshold, metric='cosine') except ValueError, e: self.werror("_hclustering: %s" % str(e)) return False for i, featureID in enumerate( vectors.keys()): 

5 Solutions collect form web for “Scipy Отрицательное расстояние? Какие?”

Это из-за неточности с плавающей запятой, поэтому некоторые расстояния между вашими векторами, а не 0, составляют, например, -0.000000000000000002. Используйте scipy.clip() чтобы исправить проблему. Если ваша матрица расстояний – dmatr , используйте numpy.clip(dmatr,0,1,dmatr) и вы должны быть в порядке.

Я уверен, что это потому, что вы используете косинус-метрику при вызове fclusterdata. Попробуйте использовать эвклиды и посмотрите, не исчезла ли ошибка.

Косинус-метрика может пойти отрицательно, если точечный продукт двух векторов в вашем наборе больше 1. Поскольку вы используете очень большие числа и нормализуете их, я уверен, что продукты с точкой больше 1 раза в вашем наборе данных. Если вы хотите использовать косинус-метрику, то вам нужно будет нормализовать ваши данные, чтобы точечный продукт двух векторов никогда не был больше 1. См. Формулу на этой странице, чтобы узнать, как определяется косинус-метрика, как в Scipy.

Редактировать:

Ну, посмотрев исходный код, я думаю, что формула, указанная на этой странице, на самом деле не является формулой, которую использует Scipy (что хорошо, потому что исходный код выглядит так, как будто он использует формулу правильного и правильного косинусного расстояния). Однако к тому моменту, когда оно создается для связи, по какой-либо причине, очевидно, есть некоторые отрицательные значения в связи. Попробуйте найти расстояние между вашими векторами с помощью scipy.spatial.distance.pdist () с методом = 'cosine' и проверьте отрицательные значения. Если их нет, то это связано с тем, как создается связь с использованием значений расстояния.

«Linkage Z содержит отрицательные значения». Эта ошибка также встречается в скудном иерархическом процессе кластеризации, когда каждому индексу кластеров связей в матрице привязки присваивается -1.

Согласно моим наблюдениям, любой индекс кластеров связывания присваивается -1 во время процессов объединения, когда расстояние между всеми парами кластеров или точек, которые необходимо объединить, выходит за пределы минус бесконечность. Таким образом, функция сцепления объединяет кластеры, даже если расстояние между ними – бесконечное. И назначьте один из кластерных или точечных отрицательных индексов

Резюме Итак, дело в том, что если вы используете коэффициент косинуса как метрику, и если норма или величина любой точки данных равна нулю, то эта ошибка будет возникать

Я была такая же проблема. Что вы можете сделать, так это переписать функцию косинуса. Например:

 from sklearn.metrics.pairwise import cosine_similarity def mycosine(x1, x2): x1 = x1.reshape(1,-1) x2 = x2.reshape(1,-1) ans = 1 - cosine_similarity(x1, x2) return max(ans[0][0], 0) 

 clusters = hierarchy.fclusterdata(data, threshold, criterion='distance', metric=mycosine, method='average') 

Я не могу улучшить ответ Джастина, но еще один момент – обработка данных.

Вы говорите, что вы делаете что-то вроде int( float("0.0003") * 10000 ) для чтения данных. Но если вы это сделаете, вы получите не 3 а 2.9999999999999996 . Это потому, что неточности с плавающей запятой просто умножаются.

Лучше или, по крайней мере, более точно. путь был бы путем умножения в строке. То есть, используя строковые манипуляции, чтобы получить от 0.0003 до 3.0 и так далее.

Возможно, даже там есть расширение типа данных Python, которое может читать данные такого типа без потери точности, с которой вы можете выполнить умножение перед преобразованием. Я не дома в SciPy / численном, поэтому не знаю.

РЕДАКТИРОВАТЬ

Джастин прокомментировал, что в python есть построение десятичного типа. И это может интерпретировать строки, умножать на целые числа и конвертировать в float (я тестировал это). В этом случае я бы рекомендовал обновить вашу логику следующим образом:

 factor = 1 if inflate: factor = 10000 scores = map(lambda x: float(decimal.Decimal(x) * factor), l[1:]) 

Это немного уменьшит ваши проблемы округления.

  • Как выполнить экспоненциальную и логарифмическую подгонку кривой в Python? Я нашел только полиномиальную подгонку
  • Самый простой способ решения математических уравнений в Python
  • numpy: эффективное чтение большого массива
  • scipy.sparse.linalg.spsolve удивительное поведение для больших разреженных матриц на Linux-системах
  • scipy.optimize.fmin_cg: «Желаемая ошибка не всегда достигается из-за потери точности».
  • Пиксельная анимация в Matplotlib
  • как использовать scipy.integrate, чтобы получить объем усеченной сферы?
  • Как создать радиальный кластер, как следующий пример кода в Python?
  • Уменьшить массив 1D numpy
  • Сопоставьте каждое значение списка с соответствующим процентили
  • Имеет ли объект DataFrame от панд другие альтернативы для гетерогенных типов данных?
  •  
    Interesting Posts for Van-Lav

    Линейная интерполяция – Python

    Каков новейший способ разработки апплетов панели gnome (с использованием python)

    Повернуть точку относительно другой точки в градусах python

    Получить физическое местоположение карты объекта, основанного на пользовательском вводе

    Python for Loop List Интересный результат

    Что означает значение ValueError: невозможно переиндексировать из дублированной оси?

    Как переместить Sprite в Pygame

    мой ноутбук jupyter не может последовательно импортировать модули anaconda

    Django и SaaS. Как использовать отдельную базу данных для каждого сайта Django?

    Как разрешить «cassandra.cluster.NoHostAvailable» в многопоточной программе Python

    sqlalchemy.exc.OperationalError: (OperationalError) не удалось открыть файл базы данных Нет Нет

    Почему этот метод Python пропускает память?

    Почему adbapi от Twisted не может восстановить данные из unittests?

    Как получить флажки с помощью CustomTreeCtrl

    использовать «pip install / uninstall» внутри скрипта python

    Python - лучший язык программирования в мире.