2016-04-05 1 views
4

Я использую метод scikit-learn MDS для выполнения уменьшения размерности в некоторых данных. Я хотел бы проверить значение напряжения, чтобы получить доступ к качеству сокращения. Я ожидал чего-то между 0 - 1. Однако я получил значения за пределами этого диапазона. Вот минимальный пример:Атрибут стресса - sklearn.manifold.MDS/Python

%matplotlib inline 

from sklearn.preprocessing import normalize 
from sklearn import manifold 
from matplotlib import pyplot as plt 
from matplotlib.lines import Line2D 

import numpy 


def similarity_measure(vec1, vec2): 
    vec1_x = numpy.arctan2(vec1[1], vec1[0]) 
    vec2_x = numpy.arctan2(vec2[1], vec2[0]) 
    vec1_y = numpy.sqrt(numpy.sum(vec1[0] * vec1[0] + vec1[1] * vec1[1])) 
    vec2_y = numpy.sqrt(numpy.sum(vec2[0] * vec2[0] + vec2[1] * vec2[1])) 

    dot = numpy.sum(vec1_x * vec2_x + vec1_y * vec2_y) 
    mag1 = numpy.sqrt(numpy.sum(vec1_x * vec1_x + vec1_y * vec1_y)) 
    mag2 = numpy.sqrt(numpy.sum(vec2_x * vec2_x + vec2_y * vec2_y)) 
    return dot/(mag1 * mag2) 

plt.figure(figsize=(15, 15)) 

delta = numpy.zeros((100, 100)) 
data_x = numpy.random.randint(0, 100, (100, 100)) 
data_y = numpy.random.randint(0, 100, (100, 100)) 

for j in range(100): 
    for k in range(100): 
     if j <= k: 
      dist = similarity_measure((data_x[j].flatten(), data_y[j].flatten()), (data_x[k].flatten(), data_y[k].flatten())) 
      delta[j, k] = delta[k, j] = dist 

delta = 1-((delta+1)/2) 
delta /= numpy.max(delta) 

mds = manifold.MDS(n_components=2, max_iter=3000, eps=1e-9, random_state=0, 
       dissimilarity="precomputed", n_jobs=1) 
coords = mds.fit(delta).embedding_ 
print mds.stress_ 

plt.scatter(coords[:, 0], coords[:, 1], marker='x', s=50, edgecolor='None') 
plt.tight_layout() 

Который, в моем тесте, напечатал следующее:

263,412196461

И произвел этот образ:

enter image description here

Как могу ли я проанализировать это значение без зная максимальное значение? Или как нормализовать его, чтобы он находился между 0 и 1?

спасибо.

+0

У меня такая же проблема, вы выяснили ответ? Здесь также указано, что он должен быть между 0 и 1 http://www.analytictech.com/borgatti/mds.htm – student

+0

Привет, @student. Да, я решил это. Насколько я помню, функция «стресса» этого метода не нормирована. Вы должны включить знаменатель (https://en.wikipedia.org/wiki/Multidimensional_scaling), чтобы он находился между 0 и 1. – pceccon

ответ

1

Это реализация, так как текущий scikit-узнать-х вычисляет и возвращает необработанное значение Stress (σ г) в то время как вы ждете стресс-1 (σ).

Первый не очень информативен (его высокое значение не обязательно указывает на плохое соответствие), а лучший способ передачи достоверности - рассчитать нормированное напряжение, например. Стресс-1, который согласно Kruskal (1964, стр. 3) имеет более или менее следующую интерпретацию: значение 0 указывает на идеальную подгонку, 0,025 отлично, 0,05 хорошо, 0,1 справедливо и 0,2 бедных.

Я только что осуществил расчет напряжения-1 и sent PR. В то же время можно использовать version from this branch, где используется стресс-1 и возвращается вместо необработанного напряжения, когда normalize параметр установлен в True (False по умолчанию).

Для получения дополнительной информации см. Kruskal (1964, стр. 8-9) или Борг и Гроенен (2005, стр. 41-43).

Смежные вопросы