Skonfiguruj algorytm uczenia maszynowego i opracuj swoją pierwszą funkcję predykcyjną przy użyciu języka Java. Samochody autonomiczne, systemy rozpoznawania twarzy i asystenci głosowi są opracowywane przy użyciu technologii i struktur uczenia maszynowego. A to dopiero pierwsza fala. W ciągu najbliższych 10 lat nowa generacja produktów odmieni nasz świat, dając początek nowemu podejściu do rozwoju programów, produktów i aplikacji.
Jako programista Java chcesz złapać tę falę teraz, gdy firmy technologiczne zaczynają intensywnie inwestować w uczenie maszynowe. To, czego nauczysz się dzisiaj, możesz wykorzystać przez następne pięć lat. Ale od czego zacząć? Ten artykuł ma na celu odpowiedzieć na to pytanie. Pierwsze wrażenie na temat zasad uczenia maszynowego uzyskasz, postępując zgodnie z naszym krótkim przewodnikiem po wdrażaniu i przygotowywaniu algorytmu uczenia maszynowego. Po zapoznaniu się ze strukturą algorytmu uczącego się i funkcjami, których można użyć do jego uczenia, oceny i wyboru funkcji zapewniającej najlepszą dokładność przewidywania, zyskasz wiedzę, jak używać frameworku JVM (Weka) do tworzyć rozwiązania do uczenia maszynowego. W tym artykule skupiono się na nadzorowanym uczeniu maszynowym, ponieważ jest to zasada najczęściej stosowana przy tworzeniu inteligentnych aplikacji.
Uczenie maszynowe i sztuczna inteligencja
Uczenie maszynowe wyewoluowało z dziedziny sztucznej inteligencji, której celem jest tworzenie maszyn potrafiących imitować ludzką inteligencję. Choć termin „uczenie maszynowe” wywodzi się z informatyki, sztuczna inteligencja nie jest dziedziną nauki nową.
Test Turinga , opracowany przez matematyka Alana Turinga na początku lat pięćdziesiątych XX wieku, jest jednym z pierwszych testów mających na celu określenie, czy maszyna licząca ma prawdziwą inteligencję. Według testu Turinga maszyna licząca udowadnia obecność ludzkiej inteligencji poprzez podszywanie się pod osobę tak, aby ta nie zdawała sobie sprawy, że rozmawia z maszyną.
Wiele popularnych obecnie podejść do uczenia maszynowego opiera się na pomysłach sprzed kilkudziesięciu lat. Jednak ostatnia dekada w informatyce (i rozproszonych platformach obliczeniowych) przyniosła wystarczające możliwości zastosowania algorytmów uczenia maszynowego. Większość z nich wymaga ogromnej ilości mnożenia macierzy i innych obliczeń matematycznych. Dwadzieścia lat temu technologie komputerowe, które umożliwiałyby takie obliczenia, po prostu nie istniały, ale teraz stały się rzeczywistością. Algorytmy uczenia maszynowego pozwalają programom przeprowadzać proces poprawy jakości i rozszerzać swoje możliwości bez interwencji człowieka. Program stworzony przy użyciu uczenia maszynowego jest w stanie samodzielnie aktualizować lub rozszerzać własny kod.
Uczenie się nadzorowane vs uczenie się bez nadzoru
Uczenie się nadzorowane i bez nadzoru to dwa najpopularniejsze podejścia do uczenia maszynowego. Obie opcje wymagają zasilania maszyny ogromnymi ilościami rekordów danych, na których można budować relacje i uczyć się. Takie zebrane dane są zwykle nazywane
„wektorami cech” . Przykładowo mamy pewien budynek mieszkalny. W tym przypadku wektor cech może zawierać takie cechy, jak: całkowita powierzchnia domu, liczba pokoi, rok budowy domu i tak dalej.
W uczeniu nadzorowanym algorytm uczenia maszynowego jest szkolony tak, aby odpowiadał na pytania związane z wektorami cech. Aby wytrenować algorytm, zasilany jest zestaw wektorów cech i powiązanych etykiet. Powiązana etykieta jest dostarczana przez osobę (nauczyciela) i zawiera poprawną „odpowiedź” na zadane pytanie. Algorytm uczenia się analizuje wektory cech i prawidłowe etykiety, aby znaleźć wewnętrzną strukturę i relacje między nimi. W ten sposób maszyna uczy się poprawnie odpowiadać na pytania. Jako przykład możemy rozważyć pewną inteligentną aplikację do handlu nieruchomościami. Można go trenować za pomocą wektora cech, w tym rozmiaru, liczby pokoi i roku budowy dla zestawu domów. Osoba musi przypisać każdemu domowi etykietę z prawidłową ceną domu w oparciu o te czynniki. Analizując te dane, inteligentna aplikacja powinna nauczyć się odpowiadać na pytanie: „Ile pieniędzy mogę dostać za ten dom?”
Po zakończeniu procesu przygotowania nowe dane wejściowe nie są już zaznaczane. Maszyna musi być w stanie poprawnie odpowiadać na pytania, nawet w przypadku nieznanych, nieoznaczonych wektorów cech. W przypadku uczenia się bez nadzoru algorytm ma przewidywać odpowiedzi bez etykietowania przez człowieka (lub nawet bez zadawania pytań). Zamiast określać etykietę lub wynik, algorytmy uczenia się bez nadzoru wykorzystują duże zbiory danych i moc obliczeniową, aby odkryć nieznane wcześniej zależności. Na przykład w marketingu produktów konsumenckich uczenie się bez nadzoru można wykorzystać do zidentyfikowania ukrytych relacji lub grup klientów, co ostatecznie może pomóc w udoskonaleniu programu marketingowego lub utworzeniu nowego. W tym artykule skupimy się na nadzorowanym uczeniu maszynowym; jest to obecnie najczęściej stosowane podejście.
Nadzorowane uczenie maszynowe
Całe uczenie maszynowe opiera się na danych. W przypadku nadzorowanego projektu uczenia maszynowego musisz oznaczyć dane znacznikami w sposób, który zapewni sensowną odpowiedź na zadane pytanie. Poniżej, w Tabeli 1, każdy rekord informacji o domu jest oznaczony jako „cena domu”. Identyfikując związek danych rekordowych z ceną domu, algorytm powinien docelowo przewidzieć cenę rynkową domów nieuwzględnionych na podanym zestawieniu. (Uwaga: powierzchnia domu podana jest w metrach kwadratowych, a cena domu podana jest w euro).
Tabela 1. Lista domów
|
Podpisać |
Podpisać |
Podpisać |
Etykieta |
Powierzchnia domu |
Liczba pokoi |
Wiek domu |
Oczekiwana cena domu |
90 m2 |
2 pokoje |
23 lata |
249 000 euro |
101 m2 |
3 pokoje |
nie dotyczy |
338 000 euro |
1330 m2 |
11 pokoi |
12 lat |
6 500 000 € |
Na wczesnych etapach prawdopodobnie będziesz oznaczać dane ręcznie, ale ostatecznie nauczysz swój program, aby robił to samodzielnie. Prawdopodobnie widziałeś już takie podejście w przypadku klientów poczty e-mail, gdzie aby przenieść wiadomość e-mail do folderu Spam, odpowiadasz na pytanie „Czy ta wiadomość e-mail jest spamem?” Kiedy odpowiadasz, uczysz program rozpoznawania wiadomości e-mail, których nie chcesz widzieć. Filtr spamu aplikacji jest przeszkolony do oznaczania wiadomości pochodzących z tego samego źródła lub zawierających tę samą treść i zarządzania nimi zgodnie z odpowiednimi regułami. Oznaczone zbiory danych są wymagane wyłącznie do celów przygotowawczych i testowych. Po zakończeniu tego kroku algorytm uczenia maszynowego działa na danych bez etykiet. Na przykład możesz wprowadzić do algorytmu predykcji nowy, nieopisany rekord danych o domu, który powinien automatycznie przewidzieć oczekiwaną cenę domu na podstawie „wiedzy” uzyskanej z danych przygotowawczych.
Jak maszyna uczy się przewidywać
Wyzwaniem związanym z nadzorowanym uczeniem maszynowym jest znalezienie odpowiedniej funkcji predykcji dla danego pytania. Matematycznie trudność polega na znalezieniu funkcji, która przyjmuje zmienną jako dane wejściowe
х
i zwraca przewidywaną wartość
у
. Ta funkcja hipotez
(hθ)
jest wynikiem procesu przygotowawczego. Często funkcja hipotezy nazywana jest także funkcją celu lub funkcją przewidywania.
y = h θ (x)
W większości przypadków
х
jest to tablica danych. W naszym przykładzie jest to dwuwymiarowa tablica elementów definiujących dom, składająca się z liczby pomieszczeń i powierzchni domu. Tablica takich wartości jest wektorem cech. Określając konkretną funkcję celu, możemy użyć jej do przewidzenia każdego wektora cech
х
. Aby przewidzieć cenę domu, należy wywołać funkcję celu za pomocą wektora cech
{101.0, 3.0}
składającego się z powierzchni domu i liczby pokoi:
Function<Double[], Double> h = ...;
Double[] x = new Double[] { 101.0, 3.0 };
double y = h.apply(x);
W kodzie źródłowym Przykładu 1 wartości w tablicy
х
reprezentują wektor cech domu. Wartość
у
zwracana przez funkcję celu to przewidywana cena domu. Celem uczenia maszynowego jest określenie funkcji celu, która będzie działać tak dokładnie, jak to możliwe, przy nieznanych parametrach wejściowych. W uczeniu maszynowym funkcja celu
(hθ)
jest czasami nazywana modelem. Model ten jest wynikiem procesu uczenia się.
Na podstawie oznaczonych próbek szkoleniowych algorytm uczenia szuka struktur lub wzorców w danych szkoleniowych. Buduje więc model, który jest ogólnie dobry dla danych. Z reguły proces uczenia się ma charakter eksploracyjny. W większości przypadków proces ten powtarza się wielokrotnie stosując różne warianty algorytmów uczenia się i konfiguracje. W rezultacie wszystkie modele są oceniane na podstawie wskaźników wydajności, spośród których wybierany jest najlepszy. Model ten służy do obliczania szacunkowych wartości przyszłych nieoznaczonych danych.
Regresja liniowa
Aby nauczyć maszynę „myśleć”, musisz najpierw wybrać algorytm uczenia się, którego będziesz używać. Na przykład regresja liniowa. Jest to jeden z najprostszych i najpopularniejszych algorytmów nadzorowanego uczenia maszynowego. Algorytm zakłada, że związek pomiędzy cechami wejściowymi a znacznikami wyniku jest liniowy. Ogólna funkcja regresji liniowej poniżej zwraca przewidywaną wartość poprzez zsumowanie wszystkich elementów wektora cech pomnożonych przez parametr
θ
(theta) . Ten parametr jest używany podczas procesu uczenia w celu dostosowania lub „dostrojenia” funkcji regresji w oparciu o dane szkoleniowe.
h θ (x) = θ 0 * 1 + θ 1 * x 1 + ... θ n * x n
W funkcji regresji liniowej parametr theta i parametry cech są ponumerowane indeksami dolnymi. Indeks dolny określa położenie parametru
(θ)
i parametru cechy
(х)
w wektorze. Należy zauważyć, że cecha x
0 jest składnikiem stałego przesunięcia i jest istotna
1
dla celów obliczeniowych. W rezultacie indeks istotnych parametrów, takich jak powierzchnia domu, zaczyna się od x
1 . Zatem, jeśli x
1 zostanie przypisana pierwsza wartość wektora cech (powierzchnia domu), to x
2 przyjmie kolejną wartość (liczbę pokoi) i tak dalej. Przykład 2 ilustruje implementację w języku Java funkcji regresji liniowej, matematycznie oznaczanej jako h
θ (x). Dla uproszczenia obliczenia przeprowadza się za pomocą formatu
double
. W metodzie
apply()
przewidziano, że pierwszy element tablicy będzie równy 1,0 i zostanie ustawiony poza tą funkcją.
Przykład 2: Regresja liniowa w Javie
public class LinearRegressionFunction implements Function<Double[], Double> {
private final double[] thetaVector;
LinearRegressionFunction(double[] thetaVector) {
this.thetaVector = Arrays.copyOf(thetaVector, thetaVector.length);
}
public Double apply(Double[] featureVector) {
assert featureVector[0] == 1.0;
double prediction = 0;
for (int j = 0; j < thetaVector.length; j++) {
prediction += thetaVector[j] * featureVector[j];
}
return prediction;
}
public double[] getThetas() {
return Arrays.copyOf(thetaVector, thetaVector.length);
}
}
Aby utworzyć nową instancję
LinearRegressionFunction
należy określić parametr
θ
. Ten parametr lub wektor służy do dostosowania ogólnej funkcji regresji liniowej do podstawowych danych szkoleniowych. Parametr
θ
zastosowany w programie zostanie dostosowany w trakcie procesu szkoleniowego, na podstawie przykładów szkoleniowych. Jakość wyszkolonej funkcji docelowej będzie zależeć od jakości danych przygotowanych do uczenia. W poniższym przykładzie używamy
LinearRegressionFunction
prognoz cen na podstawie wielkości domu. Biorąc pod uwagę, że x
0 musi być stałą o wartości 1,0, funkcję celu inicjuje się za pomocą dwóch parametrów
θ
, gdzie są one wynikiem procesu uczenia. Po utworzeniu nowego przykładu cena domu o powierzchni 1330 m2 zostanie przeliczona w sposób pokazany poniżej:
double[] thetaVector = new double[] { 1.004579, 5.286822 };
LinearRegressionFunction targetFunction = new LinearRegressionFunction(thetaVector);
Double[] featureVector = new Double[] { 1.0, 1330.0 };
double predictedPrice = targetFunction.apply(featureVector);
Na poniższym rysunku widać wykres funkcji celu predykcji (niebieska linia). Uzyskuje się go poprzez obliczenie funkcji celu dla wszystkich wartości powierzchni domu. Wykres zawiera także pary cena-obszar wykorzystywane do treningu.
W tej chwili wykres prognoz wygląda całkiem nieźle. Współrzędne wykresu (położenie i nachylenie) wyznacza wektor
θ { 1.004579, 5.286822 }
. Ale jak określić, który
θ
wektor najlepiej pasuje do Twojej aplikacji? Czy funkcja będzie lepiej pasować jeśli zmienimy pierwszy, a może drugi parametr? Aby określić najlepiej dopasowany wektor theta, potrzebna jest funkcja użyteczności, która ocenia, jak dobrze funkcja celu spełnia swoje zadanie.
CIĄG DALSZY Tłumaczenie z języka angielskiego. Autor: Gregor Roth, architekt oprogramowania, JavaWorld.
GO TO FULL VERSION