Вариант III (Challenge Dataset)

Загрузим необходимые пакеты:

import numpy as np
import pandas as pd
import patsy as pt
from sklearn import preprocessing
import sklearn.linear_model as lm
import matplotlib.pyplot as plt
from pandas.plotting import scatter_matrix
from datetime  import datetime
import quandl
from sklearn.model_selection import train_test_split

challenge_dataset.txt

Загрузим датасет challenge_dataset.txt:

df = pd.read_csv(r"challenge_dataset.txt")

Стандартизуем данные:

df = (df - df.mean()) / df.std()

Разделим данные на обучающую(80%) и тестовую(20%) выборки:

train, test = train_test_split(df, test_size=0.2)

Построим график из точек:

plt.subplot(211)
plt.plot(x, y, 'go', color = 'blue')

Построим простую линейную регрессию y от x:

  x = df.iloc[:,:-1]
  y = df.iloc[:,-1]

  pt_y, pt_x = pt.dmatrices("y ~ x", df)
  res = np.linalg.lstsq(pt_x, pt_y)
  b = res[0].ravel()

Нарисуем полученную линию:

  x2 = np.linspace(-4, 4, 100)
  f1 = b[0] + b[1] * x2 
  ax.plot(x2, f1, color = 'red')

Отдельно нарисуем нашу линию с набором тестовых данных:

plt.subplot(212)
plt.plot(x_test, y_test, 'go', color = 'blue')
f2 = b[0] + b[1] * x_test
plt.plot(x_test, f2, color = 'red')

Проверим на переобучение:

pt_y, pt_x = pt.dmatrices("y_test ~ x_test", test)
res = np.linalg.lstsq(pt_x, pt_y)
b = res[0].ravel()

x2 = np.linspace(-1, 4, 100)
f1 = b[0] + b[1] * x2 
plt.plot(x2, f1, color = 'green')

На верхнем графике: красная линия - полученная по тестовой выборке линия, синие точки - точки обучающей выборки; на нижнем: красная линия - полученная по тестовой выборке линия, синие точки - точки тестовой выбоки, зеленая линия - истинная линия для тестовой выборки.

Линии почти параллельны, значит возможно некоторое переобучение.

Чтобы поэксперементировать с методами обработки ситуации с неопределенностью значения признака, рассмотрим датасет

global_co2.csv

Загрузим датасет и стандартизуем данные:

df = pd.read_csv(r"global_co2.csv")
df = (df - df.mean()) / df.std()

Построим scatter matrix для загруженных данных:

scatter_matrix(df, alpha=0.05, figsize=(10, 10), marker ='x')

Будем предсказать параметр "Per capita" по "Year". В "Per capita" есть пропуски, сначала попробуем вычеркнуть строки с ними:

df2 = df.dropna(axis=0)
x2 = df2.iloc[:,:-1]
y2 = df2.iloc[:,-1]

Построим регрессию:

pt_y, pt_x = pt.dmatrices("PerCapita ~ Year", df2)
res = np.linalg.lstsq(pt_x, pt_y)
b0 = res[0].ravel()
print ("Cross off rows with NAN (PC ~ Year) ", b0)

Отобразим результаты:

ax = plt.subplot()
ax.plot(df2['SolidFuel'], df2['PerCapita'], 'go', color = 'blue')#x[x]
asix_x = np.linspace(0, 4, 100)
f = b0[0] + b0[1] * asix_x 
ax.plot(asix_x, f, color = 'red')

Теперь проделаем ту же работу, но попробуем заполнить пропуски средними значениями признака:

df3 = df.fillna(df['PerCapita'].mean())
x3 = df3.iloc[:,:-1]
y3 = df3.iloc[:,-1]

pt_y, pt_x = pt.dmatrices("PerCapita ~ Year", df3)
res = np.linalg.lstsq(pt_x, pt_y)
b0 = res[0].ravel()
print ("Fill NAN with median  (PC ~ Year) ", b0)

ax = plt.subplot()
ax.plot(df3['SolidFuel'], df3['PerCapita'], 'go', color = 'blue')#x[x]
asix_x = np.linspace(0, 4, 100)
f = b0[0] + b0[1] * asix_x 
ax.plot(asix_x, f, color = 'red')

Как видно, для нашего набора данных лучше вычеркивать строки с неопределенными значениями, чем заполнять средним значением. Так получается, потому что пропуски есть только в начальной части данных (для небольших Year).

Построим вектор коэфициентов линейной регрессии PerCapita от всех остальных:

pt_y, pt_x = pt.dmatrices("y2 ~ x2", df2)
res = np.linalg.lstsq(pt_x, pt_y)
b2 = res[0].ravel()
print ("Cross off rows with NAN ", b2)

pt_y, pt_x = pt.dmatrices("y3 ~ x3", df3)
res = np.linalg.lstsq(pt_x, pt_y)
b3 = res[0].ravel()
print ("Fill NAN with median ", b3)

Получим:

Cross off rows with NAN [ -4.70354648e+00 1.85368108e+00 3.64128788e+01 -6.66053900e+00 -1.45951858e+01 -1.28346405e+01 -1.81101647e+00 1.96421936e-03]

Fill NAN with median [ -4.08659474e-16 7.02343534e-02 -1.47997739e+01 -3.24039292e-01 9.11631050e+00 4.88094615e+00 2.15695575e+00 -6.66431764e-01]

WIKI/GOOGL

Загрузим датасет, удалим и заменим даты на количество дней с начала торгов и нормализуем данные:

df = quandl.get("WIKI/GOOGL")
del df['Split Ratio']

df['Date'] = pd.to_datetime(df['Date'])
df['Date'] = df['Date'] - df['Date'][0]
df['Date'] = df['Date'].dt.days
dfn = (df - df.mean()) / (df.max() - df.min())

Построим scatter_matrix, чтобы увидеть зависимости:

ax = plt.subplot()
scatter_matrix(df, alpha=0.05, figsize=(10, 10), marker ='x')

Построим линейную зависимость Close от Open:

pt_y, pt_x = pt.dmatrices("Close ~ Open", dfn)
res = np.linalg.lstsq(pt_x, pt_y)
b0 = res[0].ravel()
print ("Close ~ Open ", b0))

Построим график:

ax.plot(dfn['Close'], dfn['Open'], 'go', color = 'blue')#x[x]
axis_x = np.linspace(-1, 1, 100)
f = b0[0] + b0[1] * axis_x 
ax.plot(axis_x, f, color = 'red')

Видно что признаки сильно зависят друг от друга.

Построим линейную зависимость Close от Date:

pt_y, pt_x = pt.dmatrices("Close ~ Open", dfn)
res = np.linalg.lstsq(pt_x, pt_y)
b0 = res[0].ravel()
print ("Close ~ Open ", b0))

Построим график линейной зависимости Close от Date:

pt_y, pt_x = pt.dmatrices("Close ~ Date", dfn)
res = np.linalg.lstsq(pt_x, pt_y)
b0 = res[0].ravel()
axis_x = np.linspace(-1, 1, 100)
f = b0[0] + b0[1] * axis_x
ax.plot(axis_x, f, color = 'red')

Найдем вектор коофициентов линейной зависимости Adj. Volume от остальных признаков:

x = dfn.iloc[:,:-1]
y = dfn.iloc[:,-1]

pt_y, pt_x = pt.dmatrices("y ~ x", dfn)
res = np.linalg.lstsq(pt_x, pt_y)
b1 = res[0].ravel()
print ("Adj. Volume ~ <Others> ", b1)

Получим:

Adj. Volume ~ [ 3.79854903e-18 2.55654872e-16 -4.56014756e-15 2.82719269e-15 8.51217968e-15 -6.61824111e-15 1.00000000e+00 1.66910489e-17 1.44795200e-16 -5.41382802e-16 6.28728840e-16 -5.14155775e-16]