Dlaczego otrzymuję drzewo decyzyjne 100% dokładności?

38

Otrzymuję 100% dokładność dla mojego drzewa decyzyjnego. Co ja robię źle?

To jest mój kod:

import pandas as pd
import json
import numpy as np
import sklearn
import matplotlib.pyplot as plt


data = np.loadtxt("/Users/Nadjla/Downloads/allInteractionsnum.csv", delimiter=',')


x = data[0:14]
y = data[-1]


from sklearn.cross_validation import train_test_split

x_train = x[0:2635]
x_test = x[0:658]
y_train = y[0:2635]
y_test = y[0:658]


from sklearn.tree import DecisionTreeClassifier
tree = DecisionTreeClassifier()
tree.fit(x_train.astype(int), y_train.astype(int))


from sklearn.metrics import accuracy_score

y_predicted = tree.predict(x_test.astype(int))
accuracy_score(y_test.astype(int), y_predicted)
Nadjla
źródło
4
Jak myślisz, dlaczego robisz coś złego? Być może twoje dane są takie, że możesz osiągnąć idealną
klasyfikację
64
Nawiasem mówiąc, +1 za zastanawianie się, czy coś jest nie tak ze 100% dokładnością. Zbyt wiele osób uważa, że ​​ich model jest świetny ...
S. Kolassa - Przywróć Monikę
1
W R znajduje się pakiet (daszek) do automatycznego dzielenia zestawu danych na dwie grupy, jedną do danych treningowych, a drugą do testowania danych. Nazywam ten proces partycją danych. Wierzę, że w Pythonie jest podobny pakiet do partycji danych.
Anastasiya-Romanova 秀
Przydatne czytanie w tle: typowe pułapki w ML
smci
3
@ Anastasiya-Romanova 秀 Prawie każda poważna biblioteka ML zawiera tę funkcjonalność, w tym również tę używaną przez OP (OP nawet zaimportowało odpowiednią funkcjonalność, a po prostu z niej nie skorzystało).
Konrad Rudolph

Odpowiedzi:

79

Twoja próbka testowa jest podzbiorem próbki treningowej:

x_train = x[0:2635]
x_test = x[0:658]
y_train = y[0:2635]
y_test = y[0:658]

Oznacza to, że oceniasz swój model na podstawie danych treningowych, tj. Przeprowadzasz ocenę w próbie. Dokładność w próbie jest notorycznie słabym wskaźnikiem dokładności poza próbą, a maksymalizacja dokładności w próbce może prowadzić do przeregulowania. Dlatego zawsze należy oceniać model na prawdziwej próbce wstrzymania, która jest całkowicie niezależna od danych treningowych.

Upewnij się, że twoje szkolenie i dane testowe są rozłączne, np.

x_train = x[659:2635]
x_test = x[0:658]
y_train = y[659:2635]
y_test = y[0:658]
S. Kolassa - Przywróć Monikę
źródło
2
Lepiej byłoby użyć, sklearn.model_selection.train_test_splitjak sugeruje Juan Ignacio Gil, ponieważ to również tasuje zestawy i pozwala uniknąć obaw, jeśli zestaw danych nie jest losowy w kolejności. Jest również jaśniejszy, ponieważ pokazuje zamiary i automatycznie obsługuje zmiany wielkości zbioru danych.
Jack Aidley
1
@JackAidley: Zgadzam się (i głosowałem odpowiedź Juana kilka dni temu). Jeszcze lepiej byłoby uczynić podział deterministycznym dla debugowania poprzez ustawienie nasion liczb losowych .
S. Kolassa - Przywróć Monikę
@StephanKolassa Cześć, ulepszyłem zestaw danych Iris, a po użyciu GridSearchCVz danymi treningowymi, do testowania dokładności dostaję 100% KNeighborsClassifier. Użyłem test_train_splitdo podziału zestawu danych. Co mogłem zrobić źle tutaj?
Sndn,
19

Otrzymujesz 100% dokładności, ponieważ do testowania używasz części danych treningowych. W czasie szkolenia drzewo decyzyjne zyskało wiedzę o tych danych, a teraz jeśli podasz te same dane, aby przewidzieć, że uzyska dokładnie taką samą wartość. Dlatego drzewo decyzyjne daje za każdym razem prawidłowe wyniki.

W przypadku każdego problemu związanego z uczeniem maszynowym zestaw danych szkoleniowych i testowych należy oddzielić. Dokładność modelu można ustalić tylko wtedy, gdy zbadamy, w jaki sposób przewiduje on nieznane wartości.

Sanjay Chandlekar
źródło
17

Jak powiedzieli ci inni użytkownicy, używasz jako zestawu testowego podzbioru zestawu pociągów, a drzewo decyzyjne jest bardzo podatne na nadmierne dopasowanie.

Prawie miałeś to podczas importu

from sklearn.cross_validation import train_test_split

Ale wtedy nie używasz tej funkcji. Powinieneś był zrobić:

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.33)

aby uzyskać losowe zestawy pociągów i testów

Juan Ignacio Gil
źródło
2

Jak wskazują @Stephan Kolassa i @Sanjay Chandlekar, wynika to z faktu, że próbka testowa jest podzbiorem próbki treningowej.

Jednak przy wyborze tych próbek losowe pobieranie próbek byłoby bardziej odpowiednie, aby zapewnić reprezentatywność obu próbek. W zależności od struktury danych możesz również rozważyć losowe próbkowanie warstwowe.

Nie mówię płynnie w Pythonie, ale każde oprogramowanie statystyczne powinno umożliwiać losowe próbkowanie; niektóre wskazówki są również dostępne w SO .

nghauran
źródło
0

Po prostu chcesz poznać intuicję, dlaczego musisz wyraźnie podzielić trening i przetestować próbki.

Jeśli masz obserwacji i dzielisz swoje dane (właściwie i być może znacznie mniej), doskonale sklasyfikujesz każdy punkt (jeśli nie jest to od razu jasne, zapisz kilka przykładów na małą skalę, np. i przekonaj się o tym).n n - 1 n = 2nnn1n=2

Nazywa się to nadmiernym dopasowaniem, ponieważ jest bardzo mało prawdopodobne, aby ten proces podziału przewidywał punkty danych istotne dla twojego problemu, ale których jeszcze nie zaobserwowałeś .

Oczywiście głównym celem budowy tych platform prognozowania jest stworzenie narzędzi, które można zastosować do nigdy wcześniej nie widzianych danych; podzielenie danych, które mamy na próbki szkoleniowe i testowe, jest próbą symulacji tego samoślepienia i uchronienia naszych modeli przed nadmiernym dopasowaniem w powyższy sposób.

MichaelChirico
źródło
0

Nie potrzebujesz 100% dokładności, aby się przeregulować. Przy wystarczającej ilości segmentów można uzyskać nieodtwarzalne wyniki (coś, co wyglądałoby okropnie poza próbą).

Zobacz ten fragment artykułu z Lancetu, opisujący metodę krojenia próbki w wiadra, które są zdecydowanie zbyt dobre. Siatka statystyczna Munchausena Jest to także podstawa do kreskówki XKCD S Znaczące

Osiągnięcie 100% dokładności to tylko krótki krok od znalezienia klasyfikatora, który działa zwodniczo dobrze.

NBF
źródło