Линейная регрессия в питоне идет не так, как надо с совершенно неправильной линией регрессии - PullRequest
0 голосов
/ 31 декабря 2018

Привет всем, я практиковал линейную регрессию на наборе данных из kaggle (https://www.kaggle.com/sohier/calcofi, bottle.csv), и я пытаюсь реализовать это следующим образом:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

df = pd.read_csv("bottle.csv")
df

df1 = df.loc[:,"T_degC":"Salnty"]
df1 = df1.dropna()

from sklearn.cross_validation import train_test_split
from sklearn.linear_model import LinearRegression
X = df1["T_degC"]
y = df1["Salnty"]
X = X.values
type(X)
y = y.values
type(y)


X_train, X_test, y_train, y_test = train_test_split(X,y, test_size = 0.4)
lm = LinearRegression()

X_train = X_train.reshape(-1,1)
X_test = X_test.reshape(-1,1)
y_train = y_train.reshape(-1,1)

lm.fit(X_train, y_train)

Проблема возникает, когда я смотрю на перехваты и коэффициент:

lm.intercept_
lm.coef_

, которые оказываются 34,4 и -0,05 соответственно.Но затем рассмотрим график рассеяния переменных X и y:

plt.scatter(X_train, y_train)

Это определенно не выглядит, как отрицательно наклонная линия может быть линией регрессии этого распределения.Таким образом, мне интересно, что я мог сделать неправильно, что приводит к такому результату.

1 Ответ

0 голосов
/ 31 декабря 2018

Это очень интересный пример!

Похоже, что регрессионная линия на самом деле правильная и ваши глаза (и ваш сюжет) обманывают вас .

Диаграмма разброса, которую вы создаете, выглядит следующим образом:
Scatter plot with alpha=1

Конечно, выглядит как положительный наклон, верно?Правильно?
Ну нет.Здесь так много точек, что невозможно увидеть, где больше всего точек .Вполне может быть, что большинство точек будет показывать наклон вниз, но все они находятся друг над другом, а «несколько» других точек, которые не лежат друг над другом, показывают наклон вверх.

Лучший график: уменьшите визуальное перекрытие

Чтобы проверить это, я нанес на график точки с гораздо меньшей непрозрачностью и меньшим размером маркера (так что количество перекрытий будет уменьшено:

plt.scatter(X_train, y_train, alpha=0.002, s=1)
plt.show()

Scatter plot with less overlap
Здесь вы можете видеть, что на самом деле большинство точек показывают наклон вниз (хотя можно также утверждать, что линейная корреляция не является лучшим способом моделирования корреляцииПомните, что Линейная регрессия пытается соответствовать лучшей прямой линии, что означает, что она следует за большинством точек, но не сможет захватить более сложный паттерн, который не является прямым, если есть только несколько выбросовтам.

На самом деле коэффициент линейной корреляции также отрицателен:

df1[["T_degC", "Salnty"]].corr()
#          T_degC    Salnty
#T_degC  1.000000 -0.505266
#Salnty -0.505266  1.000000

Заключение

Короче говоря:
1. Ваша линия регрессии выглядит правильной
2. Убедитесь, что вы смотрите на правильный график - если все точки расположены друг над другом, график рассеяния может быть неоптимальным.

Редактировать: визуальное подтверждение

Еще один график: точечный график с вашей регрессией сверху: scatter plot with regression on top of it

Это кажется разумным (для прямой линии), не так ли?

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

import seaborn as sns
sns.jointplot(x='T_degC', y='Salnty', data=df1, kind='hex')

hexbin jointplot

Совместный график явно визуализирует перекрытиераскрасив части графика, где есть много точек, более сильно.Это еще раз подтверждает, что существует тенденция к снижению, но есть (относительно небольшое) количество других точек, которые идут против этой тенденции.Надеюсь, это поможет!

...