0711 217 2828-0 info@sdsc-bw.de
Datenanalyse Mietpreise

Dieses Jupyter Notebook stammt aus einem Vortrag von Michael Hefenbrock am “1. Smart Data und KI Tag”. Ziel ist es, Einblicke in den Analyseprozess (mit Python) zu geben.

Außerdem: Kann ich meine Daten einfach aus der Datenbank in ein Analysesystem “kippen” und bekomme sinnvolle Ergebnisse?

Ziel des Vortrags: Einblicke in den Analyseprozess (mit Python)

  • Außerdem: Kann ich meine Daten einfach aus der Datenbank in ein Analysesystem "kippen" und bekomme sinnvolle Ergebnisse ?

Usecase: Vorhersage von Preisen für Eigentumswohnungen

  1. CRIME - Kriminalitätsrate pro Block
  2. INDUSTRY - Anteil der Gewerbeflächen pro Block
  3. RIVERSIDE - Ist ein Fluss in der Nähe
  4. NOX - Stickoxidkonzentration (parts per 10 million)
  5. ROOMS - durchschnittliche Anzahl der Zimmer pro Wohnung
  6. AGE - Anteil der vor 1940 gebauten selbstgenutzten Einheiten
  7. DISTANCE - Gewichtete Entfernungen zu fünf Bostoner Arbeitsämtern
  8. AUTOBAHN - Index der Zugänglichkeit zu radialen Autobahnen
  9. TAX - Vollwertiger Grundsteuersatz pro 10.000 €
  10. EDUCATION - Schüler-Lehrer-Verhältnis nach Block
  11. LOW_STATUS - niedrigerer Status der Bevölkerung
  12. **PREIS** - Medianwert der Eigentumswohnungen in €
In [1]:
from utilities import *

Daten Laden

Nach Vorgabe:

  • .csv - Datei
  • UTF-8 codierung
  • Trennzeichen : " ; "
In [2]:
data = pd.read_csv('daten.csv', sep=';', encoding='utf-8')
---------------------------------------------------------------------------
UnicodeDecodeError                        Traceback (most recent call last)
pandas/_libs/parsers.pyx in pandas._libs.parsers.TextReader._convert_tokens()

pandas/_libs/parsers.pyx in pandas._libs.parsers.TextReader._convert_with_dtype()

pandas/_libs/parsers.pyx in pandas._libs.parsers.TextReader._string_convert()

pandas/_libs/parsers.pyx in pandas._libs.parsers._string_box_utf8()

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 6: invalid start byte

During handling of the above exception, another exception occurred:

UnicodeDecodeError                        Traceback (most recent call last)
<ipython-input-2-04b520eb6b9a> in <module>
----> 1 data = pd.read_csv('daten.csv', sep=';', encoding='utf-8')

~\Anaconda3\lib\site-packages\pandas\io\parsers.py in parser_f(filepath_or_buffer, sep, delimiter, header, names, index_col, usecols, squeeze, prefix, mangle_dupe_cols, dtype, engine, converters, true_values, false_values, skipinitialspace, skiprows, nrows, na_values, keep_default_na, na_filter, verbose, skip_blank_lines, parse_dates, infer_datetime_format, keep_date_col, date_parser, dayfirst, iterator, chunksize, compression, thousands, decimal, lineterminator, quotechar, quoting, escapechar, comment, encoding, dialect, tupleize_cols, error_bad_lines, warn_bad_lines, skipfooter, doublequote, delim_whitespace, low_memory, memory_map, float_precision)
    676                     skip_blank_lines=skip_blank_lines)
    677 
--> 678         return _read(filepath_or_buffer, kwds)
    679 
    680     parser_f.__name__ = name

~\Anaconda3\lib\site-packages\pandas\io\parsers.py in _read(filepath_or_buffer, kwds)
    444 
    445     try:
--> 446         data = parser.read(nrows)
    447     finally:
    448         parser.close()

~\Anaconda3\lib\site-packages\pandas\io\parsers.py in read(self, nrows)
   1034                 raise ValueError('skipfooter not supported for iteration')
   1035 
-> 1036         ret = self._engine.read(nrows)
   1037 
   1038         # May alter columns / col_dict

~\Anaconda3\lib\site-packages\pandas\io\parsers.py in read(self, nrows)
   1846     def read(self, nrows=None):
   1847         try:
-> 1848             data = self._reader.read(nrows)
   1849         except StopIteration:
   1850             if self._first_chunk:

pandas/_libs/parsers.pyx in pandas._libs.parsers.TextReader.read()

pandas/_libs/parsers.pyx in pandas._libs.parsers.TextReader._read_low_memory()

pandas/_libs/parsers.pyx in pandas._libs.parsers.TextReader._read_rows()

pandas/_libs/parsers.pyx in pandas._libs.parsers.TextReader._convert_column_data()

pandas/_libs/parsers.pyx in pandas._libs.parsers.TextReader._convert_tokens()

pandas/_libs/parsers.pyx in pandas._libs.parsers.TextReader._convert_with_dtype()

pandas/_libs/parsers.pyx in pandas._libs.parsers.TextReader._string_convert()

pandas/_libs/parsers.pyx in pandas._libs.parsers._string_box_utf8()

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 6: invalid start byte
In [3]:
data = pd.read_csv('daten.csv', sep=';', encoding='cp1252', decimal=',')
In [4]:
data.head()
Out[4]:
CRIME INDUSTRY RIVERSIDE NOX ROOMS AGE DISTANCE AUTOBAHN TAX EDUCATION LOW_STATUS PREIS
0 0.02055 0.74 tract bounds river 0.410 6.383 35.7 9.1876 2 313,0 € 17.3 5.77 24700.0
1 0.15086 27.74 tract bounds river 0.609 5.454 92.7 1.8209 4 711,0 € 20.1 18.06 15200.0
2 0.04301 1.91 tract bounds river 0.413 5.663 21.9 10.5857 4 334,0 € 22.0 8.05 18200.0
3 0.12757 4.93 tract bounds river 0.428 6.393 7.8 7.0355 6 300,0 € 16.6 5.19 23700.0
4 0.09849 25.65 tract bounds river 0.581 5.879 95.8 2.0063 2 188,0 € 19.1 17.58 18800.0
In [5]:
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 527 entries, 0 to 526
Data columns (total 12 columns):
CRIME         521 non-null float64
INDUSTRY      527 non-null float64
RIVERSIDE     527 non-null object
NOX           527 non-null float64
ROOMS         527 non-null float64
AGE           527 non-null float64
DISTANCE      527 non-null float64
AUTOBAHN      527 non-null int64
TAX           527 non-null object
EDUCATION     527 non-null float64
LOW_STATUS    527 non-null float64
PREIS         527 non-null float64
dtypes: float64(9), int64(1), object(2)
memory usage: 49.5+ KB
In [6]:
data['TAX'] = data.TAX.map(lambda z : z[:-2].replace(',','.')).astype(float)
In [7]:
data = pd.get_dummies(data, drop_first=True)
In [8]:
data.head()
Out[8]:
CRIME INDUSTRY NOX ROOMS AGE DISTANCE AUTOBAHN TAX EDUCATION LOW_STATUS PREIS RIVERSIDE_tract bounds river
0 0.02055 0.74 0.410 6.383 35.7 9.1876 2 313.0 17.3 5.77 24700.0 1
1 0.15086 27.74 0.609 5.454 92.7 1.8209 4 711.0 20.1 18.06 15200.0 1
2 0.04301 1.91 0.413 5.663 21.9 10.5857 4 334.0 22.0 8.05 18200.0 1
3 0.12757 4.93 0.428 6.393 7.8 7.0355 6 300.0 16.6 5.19 23700.0 1
4 0.09849 25.65 0.581 5.879 95.8 2.0063 2 188.0 19.1 17.58 18800.0 1
In [9]:
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 527 entries, 0 to 526
Data columns (total 12 columns):
CRIME                           521 non-null float64
INDUSTRY                        527 non-null float64
NOX                             527 non-null float64
ROOMS                           527 non-null float64
AGE                             527 non-null float64
DISTANCE                        527 non-null float64
AUTOBAHN                        527 non-null int64
TAX                             527 non-null float64
EDUCATION                       527 non-null float64
LOW_STATUS                      527 non-null float64
PREIS                           527 non-null float64
RIVERSIDE_tract bounds river    527 non-null uint8
dtypes: float64(10), int64(1), uint8(1)
memory usage: 45.9 KB
In [10]:
data[data.CRIME.isnull()]
Out[10]:
CRIME INDUSTRY NOX ROOMS AGE DISTANCE AUTOBAHN TAX EDUCATION LOW_STATUS PREIS RIVERSIDE_tract bounds river
156 NaN 8.56 0.520 6.405 85.4 2.7147 5 384.0 20.9 10.63 18600.0 1
179 NaN 18.10 0.693 6.343 100.0 1.5741 24 666.0 20.2 20.32 7200.0 1
215 NaN 2.18 0.458 6.998 45.8 6.0622 3 222.0 18.7 2.94 -1000.0 1
255 NaN 2.18 0.458 6.998 45.8 6.0622 3 222.0 18.7 2.94 33400.0 1
362 NaN 5.19 0.515 6.316 38.1 6.4584 5 224.0 20.2 5.68 22200.0 1
375 NaN 6.20 0.507 6.879 77.7 3.2721 8 307.0 17.4 9.93 27500.0 0
In [11]:
data = data.dropna()
In [12]:
data.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 521 entries, 0 to 526
Data columns (total 12 columns):
CRIME                           521 non-null float64
INDUSTRY                        521 non-null float64
NOX                             521 non-null float64
ROOMS                           521 non-null float64
AGE                             521 non-null float64
DISTANCE                        521 non-null float64
AUTOBAHN                        521 non-null int64
TAX                             521 non-null float64
EDUCATION                       521 non-null float64
LOW_STATUS                      521 non-null float64
PREIS                           521 non-null float64
RIVERSIDE_tract bounds river    521 non-null uint8
dtypes: float64(10), int64(1), uint8(1)
memory usage: 49.4 KB

Visualisierung

In [13]:
data.PREIS.hist();
In [14]:
data = data[data.PREIS > 0]
In [15]:
data.shape
Out[15]:
(501, 12)
In [16]:
Verteilung_der_Merkmale(data)
In [17]:
Korrelation(data)
In [18]:
Merkmale_Ziel_Korrelation(data)

Modelbildung und Evaluation

Evaluationsmetrik :

$$ MSE(Prognosen, Realwerte) = \frac{1}{n} \sum_i^n (Prognosewert_i \; - \; Realwert_i)^2$$
In [19]:
xtrain, xtest, ytrain, ytest = train_test_split(data.drop(['PREIS'], axis=1), data.PREIS, test_size=.3, random_state=1)
In [20]:
mean, std = xtrain.mean() , xtrain.std()

xtrain = (xtrain - mean)/std
xtest = (xtest - mean)/std
In [21]:
xtrain.shape
Out[21]:
(350, 11)
In [22]:
xtest.shape
Out[22]:
(151, 11)
In [23]:
model = Regressor('LR').fit_evaluate(xtrain, xtest, ytrain, ytest)
MSE Score: 26,734,346 €
In [24]:
model = Regressor('LR').fit_evaluate(xtrain, xtest, ytrain, ytest, True)
MSE Score: 26,734,346 €²
RMSE Score: 5,170 €
In [25]:
feature_importance(model, xtrain.columns);
<Figure size 720x432 with 0 Axes>
In [ ]:
 

Nutzen Sie Ihren Wettbewerbsvorteil durch den Einsatz von Big und Smart Data Analytics. Ich freue mich auf den Dialog mit Ihnen.

Dr. Andreas Wierse

[Geschäftsführer SICOS BW GmbH]

0711 217 2828-0

0711 217 2828-9

info@sdsc-bw.de

Unabhängige und kostenfreie Beratung vereinbaren: