Как подготовить горячую кодировку в scikit-learn для мультиклассовой регрессии logisti c? - PullRequest
0 голосов
/ 02 апреля 2020

Я пытаюсь классифицировать 4 класса из следующего DataFrame, используя однократное кодирование в scikit-learn:

          K   T_STAR                 REGIME
15   90.929  0.95524  BoilingInducedBreakup
9   117.483  0.89386                 Splash
16   97.764  1.17972  BoilingInducedBreakup
13   76.917  0.91399  BoilingInducedBreakup
6    44.889  0.95725  BoilingInducedBreakup
20  151.662  0.56287                 Splash
12   67.155  1.22842     ReboundWithBreakup
7   114.747  0.47618                 Splash
17  121.731  0.52956                 Splash
12   29.397  0.88702             Deposition
14   31.733  0.69154             Deposition
13  119.433  0.39422                 Splash
21   97.913  1.21309     ReboundWithBreakup
10  117.544  0.18538                 Splash
27   76.957  0.52879             Deposition
22  155.842  0.17559                 Splash
3    25.620  0.18680             Deposition
30  151.773  1.23027     ReboundWithBreakup
34   91.146  0.90138             Deposition
19   58.095  0.46110             Deposition
14   85.596  0.97520  BoilingInducedBreakup
41   97.783  0.16985             Deposition
0    16.683  0.99355             Deposition
28  122.022  1.22977     ReboundWithBreakup
0    25.570  1.24686     ReboundWithBreakup
3   113.315  0.48886                 Splash
7    31.873  1.30497     ReboundWithBreakup
0   108.488  0.73423                 Splash
2    25.725  1.29953     ReboundWithBreakup
37   97.695  0.50930             Deposition

Вот пример в формате CSV:

,K,T_STAR,REGIME
15,90.929,0.95524,BoilingInducedBreakup
9,117.483,0.89386,Splash
16,97.764,1.17972,BoilingInducedBreakup
13,76.917,0.91399,BoilingInducedBreakup
6,44.889,0.95725,BoilingInducedBreakup
20,151.662,0.56287,Splash
12,67.155,1.22842,ReboundWithBreakup
7,114.747,0.47618,Splash
17,121.731,0.52956,Splash
12,29.397,0.88702,Deposition
14,31.733,0.69154,Deposition
13,119.433,0.39422,Splash
21,97.913,1.21309,ReboundWithBreakup
10,117.544,0.18538,Splash
27,76.957,0.52879,Deposition
22,155.842,0.17559,Splash
3,25.62,0.1868,Deposition
30,151.773,1.23027,ReboundWithBreakup
34,91.146,0.90138,Deposition
19,58.095,0.4611,Deposition
14,85.596,0.9752,BoilingInducedBreakup
41,97.783,0.16985,Deposition
0,16.683,0.99355,Deposition
28,122.022,1.22977,ReboundWithBreakup
0,25.57,1.24686,ReboundWithBreakup
3,113.315,0.48886,Splash
7,31.873,1.30497,ReboundWithBreakup
0,108.488,0.73423,Splash
2,25.725,1.29953,ReboundWithBreakup
37,97.695,0.5093,Deposition

Особенности вектор двумерный (K,T_STAR) и REGIMES - категории, которые не упорядочены ни в каком случае.

Это то, что я до сих пор делал для быстрого кодирования и масштабирования:

from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import MinMaxScaler 
from sklearn.preprocessing import OneHotEncoder 
num_attribs = ["K", "T_STAR"] 
cat_attribs = ["REGIME"]
preproc_pipeline = ColumnTransformer([("num", MinMaxScaler(), num_attribs),
                                      ("cat", OneHotEncoder(),  cat_attribs)])
regimes_df_prepared = preproc_pipeline.fit_transform(regimes_df)

Однако, когда я печатаю несколько первых строк regimes_df_prepared, я получаю

array([[0.73836403, 0.19766192, 0.        , 0.        , 0.        ,
        1.        ],
       [0.43284301, 0.65556065, 1.        , 0.        , 0.        ,
        0.        ],
       [0.97076007, 0.93419198, 0.        , 0.        , 1.        ,
        0.        ],
       [0.96996242, 0.34623652, 0.        , 0.        , 0.        ,
        1.        ],
       [0.10915571, 1.        , 0.        , 0.        , 1.        ,
        0.        ]])

Так что одноразовое кодирование, похоже, сработало, но проблема в том, что векторы функций упакованы вместе с кодировкой в ​​этом массиве.

Если я попытаюсь обучить модель следующим образом:

from sklearn.linear_model import LogisticRegression

logreg_ovr = LogisticRegression(solver='lbfgs', max_iter=10000, multi_class='ovr')
logreg_ovr.fit(regimes_df_prepared, regimes_df["REGIME"])
print("Model training score : %.3f" % logreg_ovr.score(regimes_df_prepared, regimes_df["REGIME"]))

Счет - 1.0, чего не может быть (переобучение?).

Теперь я хочу, чтобы модель предсказывала категорию для пары (K, T_STAR)

logreg_ovr.predict([[40,0.6]])

И я получаю ошибку

ValueError: X has 2 features per sample; expecting 6

, как и предполагалось, Модель видит всю строку regimes_df_prepared как вектор признаков. Как я могу избежать этого?

1 Ответ

1 голос
/ 02 апреля 2020

Целевые метки не должны кодироваться в горячем виде, для этого у sklearn есть LabelEncoder. В вашем случае рабочий код для предварительной обработки данных будет выглядеть примерно так:

X,y = regimes_df[num_attribs].values,regimes_df['REGIME'].values
y = LabelEncoder().fit_transform(y)

Я заметил, что вы рассчитываете баллы на тех же данных, которые использовались для обучения модели, что, естественно, приведет к переобучению. Пожалуйста, используйте что-то вроде train_test_split или cross_val_score, чтобы правильно оценить производительность вашей модели.

...