#python #scikit-learn #regression #non-linear-regression
Вопрос:
У меня есть матрица эталонных значений, и я хотел бы узнать, как Scikit-learn можно использовать для создания регрессионной модели для нее. В прошлом я выполнял несколько типов одномерных регрессий, но мне непонятно, как использовать две переменные в sklearn.
У меня есть две функции (A и B) и таблица выходных значений для определенных входных значений A/B. См.Таблицу и 3D-поверхность ниже. Я хотел бы посмотреть, как я могу перевести это в уравнение с двумя переменными, которое связывает входы A/B с выходом одного значения, как показано в таблице. Связь выглядит нелинейной, и она также может быть квадратичной, логарифмической и т. Д…
Как использовать sklearn для выполнения нелинейной регрессии на этих табличных данных?
A/B 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000
0 8.78 8.21 7.64 7.07 6.50 5.92 5.35 4.78 4.21 3.63 3.06
5 8.06 7.56 7.07 6.58 6.08 5.59 5.10 4.60 4.11 3.62 3.12
10 7.33 6.91 6.50 6.09 5.67 5.26 4.84 4.43 4.01 3.60 3.19
15 6.60 6.27 5.93 5.59 5.26 4.92 4.59 4.25 3.92 3.58 3.25
20 5.87 5.62 5.36 5.10 4.85 4.59 4.33 4.08 3.82 3.57 3.31
25 5.14 4.97 4.79 4.61 4.44 4.26 4.08 3.90 3.73 3.55 3.37
30 4.42 4.32 4.22 4.12 4.02 3.93 3.83 3.73 3.63 3.53 3.43
35 3.80 3.78 3.75 3.72 3.70 3.67 3.64 3.62 3.59 3.56 3.54
40 2.86 2.93 2.99 3.05 3.12 3.18 3.24 3.31 3.37 3.43 3.50
45 2.08 2.24 2.39 2.54 2.70 2.85 3.00 3.16 3.31 3.46 3.62
50 1.64 1.84 2.05 2.26 2.46 2.67 2.88 3.08 3.29 3.50 3.70
55 1.55 1.77 1.98 2.19 2.41 2.62 2.83 3.05 3.26 3.47 3.69
60 2.09 2.22 2.35 2.48 2.61 2.74 2.87 3.00 3.13 3.26 3.39
65 3.12 3.08 3.05 3.02 2.98 2.95 2.92 2.88 2.85 2.82 2.78
70 3.50 3.39 3.28 3.17 3.06 2.95 2.84 2.73 2.62 2.51 2.40
75 3.42 3.32 3.21 3.10 3.00 2.89 2.78 2.68 2.57 2.46 2.36
80 3.68 3.55 3.43 3.31 3.18 3.06 2.94 2.81 2.69 2.57 2.44
85 3.43 3.35 3.28 3.21 3.13 3.06 2.99 2.91 2.84 2.77 2.69
90 3.43 3.35 3.28 3.21 3.13 3.06 2.99 2.91 2.84 2.77 2.69
95 3.43 3.35 3.28 3.21 3.13 3.06 2.99 2.91 2.84 2.77 2.69
100 3.43 3.35 3.28 3.21 3.13 3.06 2.99 2.91 2.84 2.77 2.69
Комментарии:
1. Ваш вопрос не имеет для меня никакого смысла. У вас есть две независимые переменные A и B и одна зависимая переменная, которую я буду называть Z. У вас было бы Z = f(A, B), если бы это был 3D-график. Я вижу, как вы можете рассматривать это как серию одномерных графиков, где вы держите константу A или B и соответствуете другой. Это то, о чем ты просишь?
2. Да, он строится как плоскость на 3d-графике, может ли этот график быть описан одним уравнением? Я добавил изображение в верхний пост. Спасибо.
3. Что вы пытались сделать, чтобы решить эту проблему? Что вы подразумеваете под «не знал бы, как с этим справиться»? Вы пробовали научиться этому?
4. Показ вашего кода, даже для частичных проблем/решений/ошибок/и т.д., Будет иметь большое значение для того, чтобы побудить других рассмотреть ваш вопрос(ы).
5. Возможно, вы сможете выполнить линейную регрессию, используя полином более высокого порядка с включенными членами взаимодействия. Это должно быть достаточно просто. Почему бы тебе не попробовать и не посмотреть? f(x, y) = сумма(cij(x^i)(y^j) для i,j = от 0 до 5 должно быть достаточно легко сделать.
Ответ №1:
Вероятно, существует четкая нелинейная взаимосвязь между вашими A
B
значениями,, и таблицей, но без каких-либо знаний об этой системе или какого-либо сложного нелинейного моделирования, вот нелепая модель с приличным score
.
the_table = """1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000
0 8.78 8.21 7.64 7.07 6.50 5.92 5.35 4.78 4.21 3.63 3.06
5 8.06 7.56 7.07 6.58 6.08 5.59 5.10 4.60 4.11 3.62 3.12
10 7.33 6.91 6.50 6.09 5.67 5.26 4.84 4.43 4.01 3.60 3.19
15 6.60 6.27 5.93 5.59 5.26 4.92 4.59 4.25 3.92 3.58 3.25
20 5.87 5.62 5.36 5.10 4.85 4.59 4.33 4.08 3.82 3.57 3.31
25 5.14 4.97 4.79 4.61 4.44 4.26 4.08 3.90 3.73 3.55 3.37
30 4.42 4.32 4.22 4.12 4.02 3.93 3.83 3.73 3.63 3.53 3.43
35 3.80 3.78 3.75 3.72 3.70 3.67 3.64 3.62 3.59 3.56 3.54
40 2.86 2.93 2.99 3.05 3.12 3.18 3.24 3.31 3.37 3.43 3.50
45 2.08 2.24 2.39 2.54 2.70 2.85 3.00 3.16 3.31 3.46 3.62
50 1.64 1.84 2.05 2.26 2.46 2.67 2.88 3.08 3.29 3.50 3.70
55 1.55 1.77 1.98 2.19 2.41 2.62 2.83 3.05 3.26 3.47 3.69
60 2.09 2.22 2.35 2.48 2.61 2.74 2.87 3.00 3.13 3.26 3.39
65 3.12 3.08 3.05 3.02 2.98 2.95 2.92 2.88 2.85 2.82 2.78
70 3.50 3.39 3.28 3.17 3.06 2.95 2.84 2.73 2.62 2.51 2.40
75 3.42 3.32 3.21 3.10 3.00 2.89 2.78 2.68 2.57 2.46 2.36
80 3.68 3.55 3.43 3.31 3.18 3.06 2.94 2.81 2.69 2.57 2.44
85 3.43 3.35 3.28 3.21 3.13 3.06 2.99 2.91 2.84 2.77 2.69
90 3.43 3.35 3.28 3.21 3.13 3.06 2.99 2.91 2.84 2.77 2.69
95 3.43 3.35 3.28 3.21 3.13 3.06 2.99 2.91 2.84 2.77 2.69
100 3.43 3.35 3.28 3.21 3.13 3.06 2.99 2.91 2.84 2.77 2.69"""
import numpy as np
import pandas as pd
import io
df = pd.read_csv(io.StringIO(initial_value=the_table), sep="s ")
df.columns = df.columns.astype(np.uint64)
df_unstacked = df.unstack()
X = df_unstacked.index.tolist()
y = df_unstacked.to_list()
from sklearn.preprocessing import PolynomialFeatures
poly = PolynomialFeatures(6)
poly_X = poly.fit_transform(X)
from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(poly_X,y)
print(model.score(poly_X,y))
# 0.9762180339233807
Для predict
значений, заданных an A
и a B
с использованием этой модели, вам нужно преобразовать входные данные, как это было сделано для создания модели. Так, например,
model.predict(poly.transform([(1534,56)]))
# array([2.75275659])
Еще более возмутительно нелепо …
more_X = [(a,b,np.log1p(a),np.log1p(b),np.cos(np.pi*b/100)) for a,b in X]
poly = PolynomialFeatures(5)
poly_X = poly.fit_transform(more_X)
model.fit(poly_X,y)
print(model.score(poly_X,y))
# 0.9982994398684035
… и к predict
:
more_X = [(a,b,np.log1p(a),np.log1p(b),np.cos(np.pi*b/100)) for a,b in [(1534,56)]]
model.predict(poly.transform(more_X))
# array([2.74577017])
Н. Б.: Возможно, есть лучшие способы математически запрограммировать эти нелепые модели.
Комментарии:
1. Как я смогу выполнить прогнозирование по этой модели? Я попробовал model.predict((1534,56)) он просит меня запустить .изменить форму, но затем сообщает мне, что у кортежа нет атрибута с именем «изменить форму»
2. @ortunoa Входные данные должны быть преобразованы, как и для модели. Например, для первой модели:
model.predict(poly.transform([(1534,56)]))
-> >array([2.75275659])
.3. @ortunoa … и для второй модели:
more_X = [(a,b,np.log1p(a),np.log1p(b),np.cos(np.pi*b/100)) for a,b in [(1534,56)]];model.predict(poly.transform(more_X))
-> >array([2.74577017])
.4. @ortunoa Если бы вы собирались выполнять сумасшедшие (или не сумасшедшие) преобразования ввода, вам, возможно, было бы лучше организовать их с помощью конвейеров sklearn .