## Regressio - hieman vaativampi esimerkki

Tämä on jatkoa aiemmalle esimerkille, jossa käytin kolmea selittävää muuttujaa. Tässä teen LSTAT-muuttujalle logaritmi-muunnoksen, jonka seurauksena selityskerroin paranee.

In [1]:
# Tuon kirjastot
import numpy as np #tätä tarvitsen logaritmimuunnokseen
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

In [2]:
# Käytän sklearn-kirjastosta löytyvää dataa Bostonin asuntojen hinnoista
from sklearn.datasets import load_boston

# boston_data sisältää valmiiksi nimettyjä osia
boston_data.keys()

Out[2]:
dict_keys(['data', 'target', 'feature_names', 'DESCR', 'filename'])
In [3]:
# boston_datan kuvaus
print(boston_data.DESCR)

.. _boston_dataset:

Boston house prices dataset
---------------------------

**Data Set Characteristics:**

:Number of Instances: 506

:Number of Attributes: 13 numeric/categorical predictive. Median Value (attribute 14) is usually the target.

:Attribute Information (in order):
- CRIM     per capita crime rate by town
- ZN       proportion of residential land zoned for lots over 25,000 sq.ft.
- INDUS    proportion of non-retail business acres per town
- CHAS     Charles River dummy variable (= 1 if tract bounds river; 0 otherwise)
- NOX      nitric oxides concentration (parts per 10 million)
- RM       average number of rooms per dwelling
- AGE      proportion of owner-occupied units built prior to 1940
- DIS      weighted distances to five Boston employment centres
- RAD      index of accessibility to radial highways
- TAX      full-value property-tax rate per $10,000 - PTRATIO pupil-teacher ratio by town - B 1000(Bk - 0.63)^2 where Bk is the proportion of blacks by town - LSTAT % lower status of the population - MEDV Median value of owner-occupied homes in$1000's

:Missing Attribute Values: None

:Creator: Harrison, D. and Rubinfeld, D.L.

This is a copy of UCI ML housing dataset.
https://archive.ics.uci.edu/ml/machine-learning-databases/housing/

This dataset was taken from the StatLib library which is maintained at Carnegie Mellon University.

The Boston house-price data of Harrison, D. and Rubinfeld, D.L. 'Hedonic
prices and the demand for clean air', J. Environ. Economics & Management,
vol.5, 81-102, 1978.   Used in Belsley, Kuh & Welsch, 'Regression diagnostics
...', Wiley, 1980.   N.B. Various transformations are used in the table on
pages 244-261 of the latter.

The Boston house-price data has been used in many machine learning papers that address regression
problems.

.. topic:: References

- Belsley, Kuh & Welsch, 'Regression diagnostics: Identifying Influential Data and Sources of Collinearity', Wiley, 1980. 244-261.
- Quinlan,R. (1993). Combining Instance-Based and Model-Based Learning. In Proceedings on the Tenth International Conference of Machine Learning, 236-243, University of Massachusetts, Amherst. Morgan Kaufmann.


In [4]:
# Data dataframeen

df = pd.DataFrame(boston_data.data, columns=boston_data.feature_names) # features

# Logaritmimuunnos
df['LSTAT2'] = np.log(df['LSTAT'])

df['MEDV'] = boston_data.target # target


Out[4]:
CRIM ZN INDUS CHAS NOX RM AGE DIS RAD TAX PTRATIO B LSTAT LSTAT2 MEDV
0 0.00632 18.0 2.31 0.0 0.538 6.575 65.2 4.0900 1.0 296.0 15.3 396.90 4.98 1.605430 24.0
1 0.02731 0.0 7.07 0.0 0.469 6.421 78.9 4.9671 2.0 242.0 17.8 396.90 9.14 2.212660 21.6
2 0.02729 0.0 7.07 0.0 0.469 7.185 61.1 4.9671 2.0 242.0 17.8 392.83 4.03 1.393766 34.7
3 0.03237 0.0 2.18 0.0 0.458 6.998 45.8 6.0622 3.0 222.0 18.7 394.63 2.94 1.078410 33.4
4 0.06905 0.0 2.18 0.0 0.458 7.147 54.2 6.0622 3.0 222.0 18.7 396.90 5.33 1.673351 36.2
In [5]:
# On aina hyvä tarkistaa, onko datassa puuttuvia tietoja
df.isnull().sum()

Out[5]:
CRIM       0
ZN         0
INDUS      0
CHAS       0
NOX        0
RM         0
AGE        0
DIS        0
TAX        0
PTRATIO    0
B          0
LSTAT      0
LSTAT2     0
MEDV       0
dtype: int64
In [6]:
# target-muuttujan (selitettävän muuttujan) jakauma
sns.distplot(df['MEDV'], bins=30)

Out[6]:
<matplotlib.axes._subplots.AxesSubplot at 0x227f6ccff98>
In [7]:
# Korrelaatiokertoimet kahden desimaalin tarkkuudella

correlation_matrix = df.corr().round(2)

# Luon kuvion, jonka sisään korrelaatiomatriisi mahtuu
plt.figure(figsize=(12,9))

# Seaborn-kirjaston heatmap lisää värimuotoilun
sns.heatmap(data=correlation_matrix, annot=True)

Out[7]:
<matplotlib.axes._subplots.AxesSubplot at 0x227f707f438>
In [8]:
# Valitsen malliin kaksi muuttujaa, joilla on korkeimmat korrelaatiot selitettävään muuttujaan
features = ['LSTAT2', 'RM', 'PTRATIO']

target = df['MEDV']

# Lisään kuvion, jonka sisään mahtuu kaksi hajontakaaviota
plt.figure(figsize=(15, 5))

# enumerate()-funktion avulla voin käydä listan läpi ja palauttaa jokaisesta listan alkiosta
# järjestysnumeron (alkaen nollasta) ja arvon
for i, feature in enumerate(features):
plt.subplot(1, len(features), i+1)
plt.scatter(df[feature], target)
plt.xlabel(feature)
plt.ylabel('MEDV')

In [9]:
# Datan valmistelu

X = df[features] # feature-matriisi
y = target # target

In [10]:
# Jaan datan opetusdataan ja testidataan (20 % datasta)

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state=5)
# random_state varmistaa, että eri kokeilukerroilla saan aina saman jaon opetus- ja testidataan

# Tarkistan syntyneiden datojen koot
print(X_train.shape)
print(X_test.shape)
print(y_train.shape)
print(y_test.shape)

(404, 3)
(102, 3)
(404,)
(102,)

In [11]:
# Sovitan lineaarisen regressiomallin opetusdataan

from sklearn.linear_model import LinearRegression

malli = LinearRegression().fit(X_train, y_train)

In [12]:
malli.coef_ # kertoimet

Out[12]:
array([-9.44146344,  2.68690888, -0.76646419])
In [13]:
malli.intercept_ # vakiotermi

Out[13]:
42.115587886873456
In [14]:
# Mallin luotettavuuteen liittyvää statistiikkaa

from sklearn.metrics import mean_absolute_error

y_train_predict = malli.predict(X_train)

mae = (mean_absolute_error(y_train, y_train_predict)) # keskimääräinen ennustevirhe

r2 = malli.score(X_train, y_train) # selityskerroin

print('Mallin sopivuus opetusdataan')
print("--------------------------------------")
print('Keskimääräinen virhe: {}'.format(mae))
print('Selityskerroin: {}'.format(r2))
print("\n")

y_test_predict = malli.predict(X_test)
mae = (mean_absolute_error(y_test, y_test_predict))
r2 = malli.score(X_test, y_test)

print('Mallin sopivuus testidataan')
print('--------------------------------------')
print('Keskimääräinen virhe: {}'.format(mae))
print('Selityskerroin: {}'.format(r2))

Mallin sopivuus opetusdataan
--------------------------------------
Keskimääräinen virhe: 3.4661238175277758
Selityskerroin: 0.7269572646730218

Mallin sopivuus testidataan
--------------------------------------
Keskimääräinen virhe: 3.3941242922975428
Selityskerroin: 0.753237887010362

In [15]:
# Vertaan testidatan havaintoja mallin antamiin ennusteisiin

# DataFramen luonti
test = pd.DataFrame()
test['y_test'] = y_test
test['y_test_predict'] = y_test_predict

# seaborn-kirjaston jointplot
sns.jointplot(data=test, x='y_test',y='y_test_predict',kind='reg')

Out[15]:
<seaborn.axisgrid.JointGrid at 0x227f77434e0>