• Nie Znaleziono Wyników

Usuwanie szumu z danych treningowych

W dokumencie Index of /rozprawy2/11576 (Stron 66-70)

3. Koncepcja jakościowego modelu kodu źródłowego – SCQM 27

4.4. Usuwanie szumu z danych treningowych

Za pomocą opisanego sposobu pozyskiwania kodu źródłowego metod klas pod-dawanych refaktoryzacji zgromadzono 60764 metod. Jeszcze przed zebraniem opinii o jakości kodu od programistów (zob. opis badania w rozdziale 5), postanowiono przeanalizować zgromadzone atuomatycznie metody w celu zidentyfikowania poten-cjalnych problemów i dokładniejsze przefiltrowanie danych wejściowych dla modelu SCQM. W kolejnych podsekcjach przedstawiono wprowadzone pomysły na usunięcie szumu ze zbioru danych treningowych i modelu wraz z uzyskanymi rezultatami.

4.4.1. Ograniczenie długości metod

Aby lepiej poznać profil zgromadzonych danych, za pomocą skryptu 8_token_ lengths_histogram.php z repozytorium [92] zliczono długości zgromadzonych me-tod. To z kolei pozwoliło na naszkicowanie histogramu przedstawiającego rozkład ze-branych wartości – przedstawiono go na Rysunku 4.1.

Liczba metod

Dugo metody (liczba tokenów)

0 100 200 300 400 500 7 387 766 1.15K 1.59K 2.29K 21.38K

Rys. 4.1: Histogram długości zebranych metod (w tokenach)

Bez zaskoczenia – przeważająca większość refaktoryzowanych metod jest krótka – dużo krótsza od maksymalnej długości. Moda dla zbioru długości metod jest równa 29, mediana – 168.

W przypadku zbyt długich metod zmiany w nich przeprowadzane dotyczą często tylko jednego z wielu fragmentów kodu i nawet jeśli jest poprawiana jego jakość –

w trakcie uczenia modelu bezwzględnego model będzie źle instruowany o jakości kodu całej metody. Z tego powodu postanowiono ograniczyć długość metod, które będą składać się na zbiór treningowy.

Aby znaleźć odpowiednią maksymalną długość metody, do której powinno zo-stać ograniczone wejście, przeanalizowano jaka część zbioru danych pozostaje przy jej zmniejszaniu. W ten sposób oczyszczono zbiór danych z przykładów, które na pewno nie prezentują kodu wysokiej jakości oraz – docelowo – przyspieszono obliczenia mo-delu. Tabela 4.3 przedstawia zależność maksymalnej długości metody od liczby pró-bek, która pozostaje po nałożeniu takiego ograniczenia. Ostatecznie do obliczeń przy-jęto ograniczenie długości metody do 200 tokenów. To ograniczenie wydaje się już spore, jednakże 200 tokenów w rozbiorze syntaktycznym metody przekłada się na około 30-40 linii kodu, co według książki [5] oraz autora rozprawy i tak jest jeszcze zbyt długą metodą.

4.4.2. Zliczanie zmienionych tokenów

Analizując przypadkowo wybrane przykłady zebranych refaktoryzacji, zwrócono uwagę na powtarzające się sytuacje, których nie wzięto wcześniej pod uwagę, a które pojawiały się w danych wejściowych. Ich jakość byłaby trudna do rozstrzygnięcia nawet przez programistę bez znajomości dodatkowego kontekstu. Niektóre przykłady to:

1. metody w interfejsach, do których została dodana domyślna implementacja (jest to możliwe od Javy w wersji 8),

2. przeniesienie implementacji w górę hierarchii klas – zastąpienie metody, która dotychczas była abstrakcyjna na metodę nieabstrakcyjną posiadająca implemen-tację,

3. usunięcie całego ciała metody,

4. wykomentowanie lub usunięcie części kodu w ciele metody bez zamiany na np. wywołanie wydzielonej metody prywatnej,

5. dodanie nowego kodu w ciele metody,

6. minimalna zmiana w ciele metody, np. zmiana operatora < na <= w warunku logicznym.

Tabela 4.3: Liczba próbek pozostałych w zbiorze danych wejściowych po wprowadze-niu poszczególnych ograniczeń na maksymalną długość metody

Maksymalna długość metody Liczba pozostałych próbek Część oryginalnego zbioru wejściowego 33000 60764 100% 32000 60763 100% 30000 60763 100% 20000 60759 100% 10000 60747 100% 5000 60690 100% 2000 60087 99% 1000 57918 95% 800 56397 93% 700 55254 91% 600 53589 88% 500 51358 85% 400 47910 79% 300 42613 70% 200 34204 56% 100 20226 33% 50 10382 17%

Odkrycie takich przykładów w zebranych przykładach refaktoryzacji odsłoniło potrzebę dokładniejszego ich przefiltrowania. Oprócz ograniczenia długości metod, należy także sprawdzić czy kod wewnątrz nich rzeczywiście jest zmieniany. Należy wykluczyć przypadki, w których kod jest tylko dodawany bądź usuwany. W takiej sytuacji nie tylko programista nie byłby w stanie określić, czy kod po danej zmianie jest czytelniejszy, ale także podawanie takiego przykładu w trakcie uczenia modelu bezwględnego wprowadza go w błąd. W ten sposób przy usuwaniu ciała metody model uczy się, że metoda bez ciała jest metodą z kodem wysokiej jakości, a przy dodaniu implementacji – odwrotnie.

W celu przygotowania danych, przetworzono raz jeszcze zgromadzone rozbiory syn-taktyczne metod i na czas przetwarzania umieszczono każdy węzeł drzewa w osobnej linii (zob. skrypt 15_prepare_rnn_input_by_diff.php z repozytorium [92]). Następ-nie porównano tak przygotowane rozbiory syntaktyczne za pomocą prostej implemen-tacji porównywania zawartości ciągów znaków Diff7. Wynikiem takiego porównania jest tablica, z której każdy element jest parą wartości informującą o tym co stało się odpowiednio z danym tokenem przed i po refaktoryzacji. Informacje te zostały przekazane jako stałe:

1. Diff::UNMODIFIED jeśli token przed i po przeprowadzonej zmianie jest niezmie-niony,

2. Diff::INSERTED, jeśli token został dodany w trakcie refaktoryzacji, 3. Diff::DELETED, jeśli token został usunięty w trakcie refaktoryzacji.

W celu wyeliminowania niejednoznacznych przykładów wymienionych na początku tej sekcji, ze zbioru danych wejściowych odrzucono przykłady które w wyniku po-równania nie zwróciły obydwu stałych oznaczających dodanie lub usunięcie danego tokenu. Odfiltrowano w ten sposób przekształcenia, które tylko dodają bądź tylko usuwają kod z metody.

Ponadto, dla każdej zmiany wyznaczono liczbę zmienionych tokenów, zliczając pary zawierające wartość Diff::INSERTED lub Diff::DELETED.

4.4.3. Decyzje usprawniające przebieg uczenia

Najlepszą kombinacją reguł i parametrów opisanych w tej sekcji okazało się: • ograniczenie długości metod do 200 tokenów (do 30-40 linii kodu)

• odfiltrowanie zmian, które wyłącznie dodają lub usuwają kod

• odfiltrowanie zmian, które zmieniają mniej niż 5 lub więcej niż 100 tokenów w rozbiorze syntaktycznym

Przyjęcie nowych reguł filtrowania danych wejściowych spowodowało kolejne zmniej-szenie ich liczby. Po nałożeniu nowych warunków na dane wejściowe w zbiorze pozo-staje 9925 zmian refaktoryzacyjnych. Porównując tę liczbę do liczby wszystkich pozy-skanych metod o długości do 200 tokenów z tabeli 4.3 można stwierdzić, że nowe me-tody filtrowania odrzuciły niemal 3

4 analizowanych dotąd zmian jako niejednoznaczne.

W dokumencie Index of /rozprawy2/11576 (Stron 66-70)