Python: поиск нескольких линейных линий тренда на диаграмме рассеяния - PullRequest
0 голосов
/ 11 сентября 2018

У меня есть следующий кадр данных панд -

    Atomic Number      R         C
0             2.0   49.0  0.040306
1             3.0  205.0  0.209556
2             4.0  140.0  0.107296
3             5.0  117.0  0.124688
4             6.0   92.0  0.100020
5             7.0   75.0  0.068493
6             8.0   66.0  0.082244
7             9.0   57.0  0.071332
8            10.0   51.0  0.045725
9            11.0  223.0  0.217770
10           12.0  172.0  0.130719
11           13.0  182.0  0.179953
12           14.0  148.0  0.147929
13           15.0  123.0  0.102669
14           16.0  110.0  0.120729
15           17.0   98.0  0.106872
16           18.0   88.0  0.061996
17           19.0  277.0  0.260485
18           20.0  223.0  0.164312
19           33.0  133.0  0.111359
20           36.0  103.0  0.069348
21           37.0  298.0  0.270709
22           38.0  245.0  0.177368
23           54.0  124.0  0.079491

Тенденция между r и C, как правило, линейная.Что бы я хотел сделать, если это возможно, это найти исчерпывающий список всех возможных комбинаций из 3 или более точек и их трендов с scipy.stats.linregress, чтобы я мог найти группы точек, которые линейно подходят лучше всего.

Что в идеале выглядело бы примерно так для данных, (Источник) , но я ищу и все другие возможные тренды.

Итак, вопрос, как мне передать все 16776915 возможных комбинаций (сумма_ (i = 3) ^ 24 бинома (24, i)) из 3 или более точек в лингресс, и это даже выполнимо без тонны кода?

1 Ответ

0 голосов
/ 11 сентября 2018

Мое следующее решение основано на алгоритме RANSAC .Это метод для подгонки математической модели (например, линии) к данным с большим количеством выбросов.

RANSAC - это один конкретный метод из области устойчивая регрессия .

Мое решение ниже сначала соответствует RANSAC.Затем вы удаляете точки данных, близкие к этой строке, из своего набора данных (что соответствует сохранению выбросов), снова подбираете RANSAC, удаляете данные и т. Д., Пока не останется очень мало точек.

Такие подходы всегдаиметь параметры, которые зависят от данных (например, уровень шума или близость линий).В следующем решении MIN_SAMPLES и residual_threshold - это параметры, которые могут потребовать некоторой адаптации к структуре ваших данных:

import matplotlib.pyplot as plt
import numpy as np
from sklearn import linear_model

MIN_SAMPLES = 3

x = np.linspace(0, 2, 100)

xs, ys = [], []

# generate points for thee lines described by a and b,
# we also add some noise:
for a, b in [(1.0, 2), (0.5, 1), (1.2, -1)]:
    xs.extend(x)
    ys.extend(a * x + b + .1 * np.random.randn(len(x)))

xs = np.array(xs)
ys = np.array(ys)
plt.plot(xs, ys, "r.")

colors = "rgbky"
idx = 0

while len(xs) > MIN_SAMPLES:

    # build design matrix for linear regressor
    X = np.ones((len(xs), 2))
    X[:, 1] = xs

    ransac = linear_model.RANSACRegressor(
        residual_threshold=.3, min_samples=MIN_SAMPLES
    )

    res = ransac.fit(X, ys)

    # vector of boolean values, describes which points belong
    # to the fitted line:
    inlier_mask = ransac.inlier_mask_

    # plot point cloud:
    xinlier = xs[inlier_mask]
    yinlier = ys[inlier_mask]

    # circle through colors:
    color = colors[idx % len(colors)]
    idx += 1
    plt.plot(xinlier, yinlier, color + "*")

    # only keep the outliers:
    xs = xs[~inlier_mask]
    ys = ys[~inlier_mask]

plt.show()

На следующем графике точки, показанные в виде звезд, относятся к скоплениям, обнаруженным моимкод.Вы также видите несколько точек, изображенных в виде кружков, которые являются точками, остающимися после итераций.Несколько черных звезд образуют скопление, от которого можно избавиться, увеличив MIN_SAMPLES и / или residual_threshold.

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...