WorkCamp # Maschinelles Lernen - ## Grundlagen - ###2018

Praktische Übung

Beispiel xx # Arbeiten mit Sensordaten ## Feature Selektion

Problemstellung:
In diesem Jupyter Notebook , werden Sie in einer Fallstudie die Aufbereitung von Daten durch Skalierung, Normalisierung, Skalenänderung und Binärisierung kennenlernen. Dies ist für einige Algorithmen für Maschinelles Lernen notwendig. Nach Abschluss dieses Notebooks sollten Sie wissen:

  • Wie man ein Vorhersagemodellierungsproblem auf Basis einer Fragestelluung zur Classification durchgehend abarbeitet.
  • Wie man bisher unbekannte Daten in panda DataFrames lädt: (csv, xlsx, xls, xml, json, hdf5 etc.).
  • Wie man unbekannte Daten mit einer deskriptiven Statistik in python analysiert.
  • Wie man unbekannte Daten mit python Bibliotheken visualisiert.
  • Wie man erzeugte Plots, speichert und dokumentiert.
  • Wie man Datentransformationen verwendet, um die Performance des Modells zu verbessern, zum Beispiel Normalisierung oder Standardisierung.
  • Wie man Algorithmus-, oder Hyperparameter-Tuning verwendet, um die Modell-Leistung zu verbessern.
  • Wie man Ensemble-Methoden verwendet und eine Abstimmung der Parameter zur Verbesserung der Modell-Performance durchführt.
  • Wie man die Kreuz-Validierung zur Beurteilung der Performance von ML-Algorithmen einsetzt.
  • Auf welcher Basis eine Beurteilung der verwendetn Classification Algorithmen stattfindet. (Classification Matrix, Confusion Matrix) </ul> Die Module und Bibliotheken stehen alle in der Anaconda scikit-learn Umgebung zum Maschinellen Lernen direkt zur Verfügung.
    Arbeiten mit Zeitreihen:
    Insbesondere beim arbeiten mit Zeitreihen (timeseries) wird, falls notwendig, statsmodels und dessen Klassen, Bibliotheken und Module nachgeladen.
    Tipp:
    Falls in Ihrer Version statsmodels nicht vorhanden ist, mit: !pip install statsmodels in einer Jupyter Zelle nachinstallieren.
    Informationen zu statsmodels finden Sie hier: http://www.statsmodels.org/
  • 
    
    In [ ]:
    
    
    ##Eventuell Strukturbild einbauen
    ##Evtl. nochmals Vorgehen als Ablaufmodell
    
    
    In [1]:
    # Laden der entsprechenden Module (kann etwas dauern !)
    # Wir laden die Module offen, damit man einmal sieht, was da alles benötigt wird
    # Allerdings aufpassen, dann werden die Module anderst angesprochen wie beim Standard
    # zum Beispiel pyplot und nicht plt
    from matplotlib import pyplot
    pyplot.rcParams["figure.figsize"] = (15,12)
    %matplotlib inline
    import numpy as np #wird allerdings nicht benötigt
    from pandas import read_csv
    from pandas import set_option
    from pandas.plotting import scatter_matrix
    from sklearn.preprocessing import StandardScaler
    from sklearn.model_selection import train_test_split
    from sklearn.model_selection import KFold
    from sklearn.model_selection import cross_val_score
    from sklearn.model_selection import GridSearchCV
    from sklearn.metrics import classification_report
    from sklearn.metrics import confusion_matrix
    from sklearn.metrics import accuracy_score
    from sklearn.pipeline import Pipeline
    from sklearn.linear_model import LogisticRegression
    from sklearn.tree import DecisionTreeClassifier
    from sklearn.neighbors import KNeighborsClassifier
    from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
    from sklearn.naive_bayes import GaussianNB
    from sklearn.svm import SVC
    from sklearn.ensemble import AdaBoostClassifier
    from sklearn.ensemble import GradientBoostingClassifier
    from sklearn.ensemble import RandomForestClassifier
    from sklearn.ensemble import ExtraTreesClassifier
    

    Problem Beschreibung:
    Der Fokus dieses Projektes liegt auf dem Datensatz "sensordaten-10.csv". Das Problem ist die Vorhersage von guten und schlechten Werkstücken aus den 10 Sensordaten. Jedes Muster ist ein Satz von 10 Zahlen. Die Sensoren decken unterschiedliche Wertebereiche ab.Das Label, das jeder Datenreihe zugeordnet ist, enthält 0 oder 1. Wenn das Werkstück die Beurteilung gut hat steht eine 1 in der Spalte Label, sonst eine 0.
    Aufgabe:
    Laden Sie die Daten und verschaffen Sie sich einen ersten Überblick

    
    
    In [2]:
    #Laden der Daten [12100 Datensätze mit 10 Sensoren und einer Spalte Label (12100x11)Matrix]
    url = 'sensordaten-10.csv'
    datensatz = read_csv(url, sep=';', header=0)
    

    Beschreibende Statistik

    
    
    In [3]:
    # Ausgabe df.shape
    print(datensatz.shape)
    
    
    
    
    (12100, 11)
    
    
    
    In [4]:
    # Ausgabe df.dtypes
    # Spalte enthält die Classifikation R oder M
    set_option('display.max_rows', 50)
    print(datensatz.dtypes)
    
    
    
    
    Sens-1     float64
    Sens-2     float64
    Sens-3     float64
    Sens-4     float64
    Sens-5     float64
    Sens-6     float64
    Sens-7     float64
    Sens-8     float64
    Sens-9     float64
    Sens-10    float64
    Label        int64
    dtype: object
    
    
    
    In [5]:
    # Ausgabe df.head mit vergösserter display width
    set_option('display.width', 100)
    print(datensatz.head(20))
    
    
    
    
        Sens-1  Sens-2  Sens-3  Sens-4  Sens-5  Sens-6  Sens-7  Sens-8  Sens-9  Sens-10  Label
    0    15.31   25.31   75.31  109.23   63.07    0.65  159.60   23.69   41.53    59.21      1
    1    16.76   26.76   76.76  115.05   77.62    1.38  181.44   47.48   77.22   118.70      1
    2    18.62   28.62   78.62  122.48   96.20    2.31  209.29   46.78   76.16   116.94      1
    3    18.52   28.52   78.52  122.08   95.21    2.26  207.82   41.68   68.52   104.20      1
    4    18.93   28.93   78.93  123.74   99.34    2.47  214.01   34.61   57.92    86.54      1
    5    17.28   27.28   77.28  117.12   82.81    1.64  189.21   46.71   76.07   116.78      1
    6    18.09   28.09   78.09  120.35   90.88    2.04  201.31   42.68   70.02   106.71      1
    7    19.00   29.00   79.00  124.00  100.00    2.50  215.00   31.19   52.78    77.96      1
    8    17.78   27.78   77.78  119.11   87.79    1.89  196.68   43.80   71.71   109.51      0
    9    17.83   27.83   77.83  119.31   88.27    1.91  197.40   47.71   77.57   119.28      1
    10   16.53   26.53   76.53  114.11   75.26    1.26  177.89   60.44   96.66   151.09      0
    11   19.23   29.23   79.23  124.90  102.26    2.61  218.39   55.07   88.60   137.67      1
    12   17.33   27.33   77.33  117.30   83.25    1.66  189.88   49.71   80.57   124.28      1
    13   16.86   26.86   76.86  115.45   78.62    1.43  182.92   38.00   63.00    94.99      1
    14   19.18   29.18   79.18  124.72  101.79    2.59  217.68   42.50   69.75   106.26      1
    15   17.10   27.10   77.10  116.41   81.02    1.55  186.53   49.83   80.75   124.58      0
    16   19.37   29.37   79.37  125.49  103.73    2.69  220.59   39.42   65.13    98.55      1
    17   17.47   27.47   77.47  117.87   84.67    1.73  192.01   44.87   73.30   112.16      1
    18   17.83   27.83   77.83  119.32   88.30    1.91  197.44   45.00   73.50   112.50      1
    19   18.46   28.46   78.46  121.85   94.62    2.23  206.93   29.64   50.45    74.09      1
    
    
    
    In [6]:
    # Ausgabe df.describe() mit 4 Nachkomma Stellen
    set_option('precision', 4)
    print(datensatz.describe())
    
    
    
    
               Sens-1      Sens-2      Sens-3      Sens-4      Sens-5      Sens-6      Sens-7  \
    count  12100.0000  12100.0000  12100.0000  12100.0000  12100.0000  12100.0000  12100.0000   
    mean      18.0005     28.0005     78.0005    120.0021     90.0052      2.0006    200.0078   
    std        1.0067      1.0067      1.0067      4.0267     10.0667      0.5028     15.1000   
    min       13.9900     23.9900     73.9900    103.9600     49.9100      0.1300    139.8600   
    25%       17.3100     27.3100     77.3100    117.2400     83.1100      1.6600    189.6600   
    50%       18.0000     28.0000     78.0000    119.9900     89.9800      2.0000    199.9650   
    75%       18.6700     28.6700     78.6700    122.6800     96.7100      2.3400    210.0600   
    max       21.7400     31.7400     81.7400    134.9700    127.4200      3.8700    256.1200   
    
               Sens-8      Sens-9     Sens-10       Label  
    count  12100.0000  12100.0000  12100.0000  12100.0000  
    mean      44.0383     72.0574    110.0942      0.9230  
    std        7.9944     11.9916     19.9872      0.2666  
    min       11.9300     23.8900     29.8100      0.0000  
    25%       38.7900     64.1875     96.9700      1.0000  
    50%       44.0400     72.0600    110.0950      1.0000  
    75%       49.3300     80.0000    123.3300      1.0000  
    max       86.9200    136.3700    217.2900      1.0000  
    
    
    
    In [7]:
    # Ausgabe der Klassen Verteilung in der Spalte 60
    print(datensatz.groupby('Label').size())
    
    
    
    
    Label
    0      932
    1    11168
    dtype: int64
    

    Visualisierung der Daten

    
    
    In [8]:
    # Ausgabe Histogramm
    pyplot.rcParams["figure.figsize"] = (15,12)
    datensatz.hist()
    pyplot.show()
    
    
    
    

    Univariate Feature Selektion

    Uum die Merkmale auszuwählen, die am stärksten mit der Ausgabevariablen verknüpft sind, können Statistische Tests verwendet werden,. Die scikit-learn Bibliothek stellt die SelectKBest Klasse zur Verfügung, die mit einer Reihe von unterschiedlichen statistischen Tests zur Auswahl der relavantesten Features eingesetzt werden kann. Das folgende Beispiel verwendet den Chi-squared (Chi2) statistischen Test für nicht-negative Merkmale, um 5 der besten Merkmale aus den Sensordaten auszuwählen.

    
    
    In [11]:
    from numpy import set_printoptions
    from sklearn.feature_selection import SelectKBest
    from sklearn.feature_selection import chi2
    # Übergabe der Dtaen
    array = datensatz.values
    X = array[:,0:10]
    Y = array[:,10]
    # Feature Extraktion
    test = SelectKBest(score_func=chi2, k=5)
    fit = test.fit(X, Y)
    # Zusammenfassung der Ergebnisse
    set_printoptions(precision=3)
    print(fit.scores_)
    features = fit.transform(X)
    # Ausgewählte Features
    print(features[0:9,:])
    
    
    
    
    [   22.164    14.249     5.115    53.205   443.309    49.989   448.859
       931.334  1280.71   2328.888]
    [[  63.07  159.6    23.69   41.53   59.21]
     [  77.62  181.44   47.48   77.22  118.7 ]
     [  96.2   209.29   46.78   76.16  116.94]
     [  95.21  207.82   41.68   68.52  104.2 ]
     [  99.34  214.01   34.61   57.92   86.54]
     [  82.81  189.21   46.71   76.07  116.78]
     [  90.88  201.31   42.68   70.02  106.71]
     [ 100.    215.     31.19   52.78   77.96]
     [  87.79  196.68   43.8    71.71  109.51]]
    

    Im Sensor Datensatz sind also die Sensoren Sens-5, Sens-7, Sens-8, Sens-9 und Sens-10 besonders relevant.

    Rekursive Feature Elimination

    Die rekursive Feature Elimination (oder RFE) funktioniert durch rekursives Entfernen von Attributen und Aufbau eines Modells auf den verbleibenden Attributen. Anhand der Modellgenauigkeit wird ermittelt, welche Attribute (und die Kombination von Attributen) tragen am meisten zur Vorhersage des Zielattributs bei. Das folgende Beispiel verwendet RFE mit dem logistischen Regressionsalgorithmus, um die 3 wichtigsten Features auszuwählen. Die Wahl des Algorithmus spielt keine Rolle, solange er geschickt und konsistent ist.

    
    
    In [14]:
    # Rekursives Feature Engineering
    # Laden des Moduls RFE
    from sklearn.feature_selection import RFE
    #Verwendung der Logistischen Regression als Algorithmus
    from sklearn.linear_model import LogisticRegression
    # Übergabe der Werte in datensatz an ein array2
    array2 = datensatz.values
    # Aufteilen des arrays in abhängige Variable Y und unabhängige Variable X
    X = array2[:,0:10]
    Y = array2[:,10]
    # feature extraction
    model = LogisticRegression()
    rfe = RFE(model, 3)
    fit = rfe.fit(X, Y)
    print("Num Features: %d" % fit.n_features_)
    print("Selected Features: %s" % fit.support_)
    print("Feature Ranking: %s" % fit.ranking_)
    
    
    
    
    Num Features: 3
    Selected Features: [False False False False  True False  True False False  True]
    Feature Ranking: [6 8 4 7 1 5 1 3 2 1]
    

    Die rekursive Feature Elimination wählt die gleichen Sensoren aus wie bei der univariaten Auswahl.

    Principal Component Analysis

    Die Principal Component Analysis (oder PCA) verwendet lineare Algebra, um den Datensatz in eine komprimierte Form zu transformieren. Im Allgemeinen wird dies als Datenreduktionstechnik bezeichnet. Eine Eigenschaft von PCA ist, dass wir die Anzahl der Dimensionen oder Hauptkomponenten im transformierten Ergebnis wählen können. Im folgenden Beispiel verwenden wir PCA und wählen 3 Hauptkomponenten aus.

    
    
    In [15]:
    # Binärisierung der Daten 
    # Laden des Moduls Binarizer aus sklearn.preprocessing
    from sklearn.decomposition import PCA
    # Übergabe der Werte in datensatz an ein array3
    array3 = datensatz.values
    # Aufteilen des arrays in abhängige Variable Y und unabhängige Variable X
    X = array3[:,0:10]
    Y = array3[:,10]
    # feature extraction
    pca = PCA(n_components=3)
    fit = pca.fit(X)
    # summarize components
    print("Explained Variance: %s" % fit.explained_variance_ratio_)
    print(fit.components_)
    
    
    
    
    Explained Variance: [  6.351e-01   3.649e-01   9.406e-06]
    [[  1.237e-04   1.237e-04   1.237e-04   4.930e-04   1.232e-03   5.152e-05
        1.848e-03   3.244e-01   4.866e-01   8.111e-01]
     [ -5.390e-02  -5.390e-02  -5.390e-02  -2.156e-01  -5.390e-01  -2.688e-02
       -8.084e-01   7.714e-04   1.160e-03   1.814e-03]
     [ -1.273e-04  -1.273e-04  -1.273e-04   4.874e-04  -2.180e-04  -3.173e-04
        1.371e-04   4.502e-01   6.747e-01  -5.849e-01]]
    

    Abschätzung der Bedeutung von Merkmalen

    Random Forest und Extra Trees können verwendet werden, um die Bedeutung von Merkmalen abzuschätzen. Im folgenden Beispiel konstruieren wir einen ExtraTreesClassifier für den Datensatz der Sonardaten.

    
    
    In [16]:
    # Abschätzung der Bedeutung von Merkmalen
    # Laden des Moduls ExtraTreesClassifier aus sklearn.ensemble
    from sklearn.ensemble import ExtraTreesClassifier
    # Übergabe der Werte in datensatz an ein array4
    array4 = datensatz.values
    # Aufteilen des arrays in abhängige Variable Y und unabhängige Variable X
    X = array4[:,0:10]
    Y = array4[:,10]
    # feature extraction
    model = ExtraTreesClassifier()
    model.fit(X, Y)
    print(model.feature_importances_)
    
    
    
    
    [ 0.059  0.061  0.054  0.091  0.111  0.054  0.103  0.167  0.153  0.146]
    

    Die Abschätzung der Bedeutung von Features wählt die gleichen Sensoren aus wie bei der univariaten Auswahl.

    Weiteres Beispiel

    
    
    In [17]:
    # Feature Importance with Extra Trees Classifier
    from sklearn.ensemble import ExtraTreesClassifier
    # Übergabe des Dateinamens an die Variable dateiname
    dateiname = 'pima-indians-diabetes.data.csv'
    # Festlegen der Spalten Namen für den DataFrame
    namen = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
    # Einlesen der Daten in einen panda DataFrame mit read_csv()
    df = read_csv(dateiname, names=namen)
    # Übergabe der Werte in df an ein array5
    array5 = df.values
    # Aufteilen des arrays in abhängige Variable Y und unabhängige Variable X - hier steht die Klasse in Spalte 9
    X = array5[:,0:8]
    Y = array5[:,8]
    # feature extraction
    model = ExtraTreesClassifier()
    model.fit(X, Y)
    print(model.feature_importances_)
    
    
    
    
    [ 0.098  0.23   0.098  0.083  0.08   0.139  0.117  0.153]
    
    
    
    In [ ]:
    
    

    Weiterführende Links:

    • https://www.stuttgart.ihk.de

    Weiterführende Literatur:

    • https://www.stuttgart.ihk.de

    Ansprechpartner IHK-Region Stuttgart:
    Dipl. Wirtsch-Ing. R. Rank

    
    
    In [ ]: