JavaRush /Java блогы /Random-KK /Java әзірлеушілеріне арналған машиналық оқыту, 2-бөлім

Java әзірлеушілеріне арналған машиналық оқыту, 2-бөлім

Топта жарияланған
Java әзірлеушілеріне арналған машиналық оқыту, 1 бөлім
Java әзірлеушілеріне арналған машиналық оқыту, 2 - 1 бөлім

Мақсатты функцияны бағалау

Еске салайық, мақсатты функция , сондай-ақ болжау функциясы ретінде белгілі, дайындық немесе оқыту процесінің нәтижесі болып табылады. Математикалық тұрғыдан мәселе айнымалыны кіріс ретінде қабылдайтын хжәне болжалды мәнді қайтаратын функцияны табу болып табылады у.
Java әзірлеушілеріне арналған машиналық оқыту, 2 - 2 бөлім
Машиналық оқытуда шығын функциясы (J(θ))берілген мақсаттық функцияның қате мәнін немесе «шығынын» есептеу үшін қолданылады.
Java әзірлеушілеріне арналған машиналық оқыту, 2 - 3 бөлім
Шығын функциясы модельдің оқу деректеріне қаншалықты сәйкес келетінін көрсетеді. Жоғарыда көрсетілген мақсат функциясының құнын анықтау үшін әрбір мысалдың квадрат қатесін есептеу қажет үй (i). Қате - есептелген мән мен мысалдағы үйдің унақты құны арасындағы қашықтық . yi
Java әзірлеушілеріне арналған машиналық оқыту, 2 - 4 бөлім
Мысалы, ауданы 1330 = 6 500 000 € болатын үйдің нақты бағасы . Ал оқытылған мақсат функциясы бойынша болжамды үй бағасының арасындағы айырмашылық € 7 032 478 : айырмашылық (немесе қате) € 532 478 . Бұл айырмашылықты жоғарыдағы графиктен де көруге болады. Айырмашылық (немесе қате) әрбір баға аймағының жаттығу жұбы үшін тік үзік қызыл сызықтар ретінде көрсетіледі. Үйретілген мақсат функциясының құнын есептеп, мысалдағы әрбір үй үшін квадрат қатесін қосып, негізгі мәнді есептеу керек. Баға мәні неғұрлым аз болса (J(θ)), біздің мақсаттық функциямыздың болжамдары соғұрлым дәлірек болады. 3 -тізімде кіріс ретінде мақсат функциясын, оқу деректерінің тізімін және олармен байланысты белгілерді қабылдайтын шығындар функциясының қарапайым Java іске асырылуы көрсетілген. Болжау мәндері циклде есептеледі және қате нақты баға мәнін (белгіден алынған) алып тастау арқылы есептеледі. Кейінірек қателердің квадраты қосылып, қатенің мәні есептеледі. Құны түрдегі мән ретінде қайтарылады double:

Листинг-3

public static double cost(Function<ltDouble[], Double> targetFunction,
 List<ltDouble[]> dataset,
 List<ltDouble> labels) {
 int m = dataset.size();
 double sumSquaredErrors = 0;

 // рассчет квадрата ошибки («разницы») для каждого тренировочного примера и //добавление его к сумме
 for (int i = 0; i < m; i++) {
 // получаем вектор признаков из текущего примера
 Double[] featureVector = dataset.get(i);
 // предсказываем meaning и вычисляем ошибку базируясь на реальном
 //значении (метка)
 double predicted = targetFunction.apply(featureVector);
 double label = labels.get(i);
 double gap = predicted - label;
 sumSquaredErrors += Math.pow(gap, 2);
 }

 // Вычисляем и возращаем meaning ошибки (чем меньше тем лучше)
 return (1.0 / (2 * m)) * sumSquaredErrors;
}
Java туралы оқығыңыз келе ме? Java әзірлеушілер тобына қосылыңыз !

Мақсатты функцияны үйрену

Шығын функциясы мақсатты функция мен тета параметрлерінің сапасын бағалауға көмектессе де, ең қолайлы тета параметрлерін табу керек. Ол үшін градиентті түсіру алгоритмін пайдалануға болады.

Градиенттің төмендеуі

Градиенттің төмендеуі шығындар функциясын азайтады. (J(θ))Бұл оқыту деректері негізінде ең аз құны бар тета параметрлерін табу үшін пайдаланылатынын білдіреді . Мұнда жаңа, неғұрлым сәйкес тета мәндерін есептеудің жеңілдетілген алгоритмі берілген:
Java әзірлеушілеріне арналған машиналық оқыту, 2 - 5 бөлім
Осылайша, тета векторының параметрлері алгоритмнің әрбір итерациясымен жақсарады. Оқыту коэффициенті α әрбір итерациядағы есептеулер санын көрсетеді. Бұл есептеулерді «жақсы» тета мәндері табылмайынша жүргізуге болады. Мысалы, төмендегі сызықтық регрессия функциясының үш тета параметрі бар:
Java әзірлеушілеріне арналған машиналық оқыту, 2 - 6 бөлім
Әрбір итерацияда тета параметрлерінің әрқайсысы үшін жаңа мән есептеледі: , , және . Әрбір итерациядан кейін жаңа тета векторының 0 , θ 1 , θ 2 } көмегімен жаңа, неғұрлым сәйкес іске асыруды жасауға болады . Листинг -4 градиент ыдырау алгоритмі үшін Java codeын көрсетеді. Регрессия функциясына арналған тета оқыту деректері, маркер деректері, оқу жылдамдығы арқылы оқытылады . Нәтиже тета параметрлерін қолданатын жақсартылған мақсат функциясы болады. Әдіс жаңа мақсаттық функцияны және алдыңғы есептеулерден жаңа тета параметрлерін бере отырып, қайта-қайта шақырылады. Және бұл шақырулар конфигурацияланған мақсат функциясы минималды платоға жеткенше қайталанады: θ0θ1θ2LinearRegressionFunction(α)train()

Листинг-4

public static LinearRegressionFunction train(LinearRegressionFunction targetFunction,
 List<ltDouble[]> dataset,
 List<ltDouble> labels,
 double alpha) {
 int m = dataset.size();
 double[] thetaVector = targetFunction.getThetas();
 double[] newThetaVector = new double[thetaVector.length];

 // вычисление нового значения тета для каждого element тета массива
 for (int j = 0; j < thetaVector.length; j++) {
 // сумируем разницу ошибки * признак
 double sumErrors = 0;
 for (int i = 0; i < m; i++) {
 Double[] featureVector = dataset.get(i);
 double error = targetFunction.apply(featureVector) - labels.get(i);
 sumErrors += error * featureVector[j];
 }

 //вычисляем новые значения тета
 double gradient = (1.0 / m) * sumErrors;
 newThetaVector[j] = thetaVector[j] - alpha * gradient;
 }

 return new LinearRegressionFunction(newThetaVector);
}
Шығынның үздіксіз төмендеуін қамтамасыз ету үшін J(θ)әрбір жаттығу қадамынан кейін шығындар функциясын іске қосуға болады. Әрбір итерациядан кейін шығындар азаюы керек. Егер бұл орындалмаса, бұл оқыту коэффициентінің мәні тым үлкен және алгоритм ең төменгі мәнді жіберіп алғанын білдіреді. Мұндай жағдайда градиенттің ыдырау алгоритмі сәтсіз болады. Төмендегі графиктер бастапқы тета векторынан бастап жаңа есептелген тета параметрлерін қолданатын мақсат функциясын көрсетеді {1.0, 1.0}. Сол жақ баған 50 итерациядан кейін болжау функциясының сызбасын көрсетеді; ортаңғы баған 200 қайталаудан кейін; және 1000 қайталаудан кейін оң жақ баған. Осылардан біз бағаның әрбір итерациядан кейін төмендейтінін және жаңа мақсат функциясы жақсырақ және жақсырақ сәйкес келетінін көреміз. 500-600 қайталаудан кейін тета параметрлері айтарлықтай өзгермейді, ал баға тұрақты үстіртке жетеді. Осыдан кейін мақсатты функцияның дәлдігін бұлай жақсарту мүмкін емес.
Java әзірлеушілеріне арналған машиналық оқыту, 2 - 7 бөлім
Бұл жағдайда 500-600 итерациядан кейін шығын айтарлықтай төмендемесе де, мақсат функциясы әлі де оңтайлы емес. Бұл сәйкессіздікті көрсетеді . Машиналық оқытуда «үйлесімділік» термині оқыту алгоритмі деректерде негізгі тенденцияларды таппағанын көрсету үшін қолданылады. Нақты өмір тәжірибесіне сүйене отырып, үлкенірек жылжымайтын мүлік үшін шаршы метр бағасының төмендеуі күтілуде. Бұдан біз мақсатты функцияны оқыту үдерісі үшін қолданылатын модель деректерге жеткілікті сәйкес келмейтіндігі туралы қорытынды жасауға болады. Сәйкессіздік көбінесе модельді тым жеңілдетуге байланысты. Бұл біздің жағдайда болды, мақсаттық функция тым қарапайым және талдау үшін ол бір параметрді - үйдің аумағын пайдаланады. Бірақ бұл ақпарат үйдің бағасын дәл болжауға жеткіліксіз.

Мүмкіндіктерді қосу және оларды масштабтау

Егер сіз өзіңіздің мақсаттық функцияңыз шешуге тырысып жатқан мәселеге сәйкес келмейтінін байқасаңыз, оны түзету қажет. Сәйкессіздікті түзетудің кең тараған жолы мүмкіндік векторына қосымша мүмкіндіктерді қосу болып табылады. Үйдің бағасының мысалында бөлмелердің саны немесе үйдің жасы сияқты сипаттамаларды қосуға болады. Яғни, {size}үйді сипаттау үшін бір мүмкіндік мәні бар векторды пайдаланудың орнына бірнеше мәндері бар векторды пайдалануға болады, мысалы, {size, number-of-rooms, age}. Кейбір жағдайларда қол жетімді оқу деректеріндегі мүмкіндіктер саны жеткіліксіз. Содан кейін барларын пайдаланып есептелетін көпмүшелік мүмкіндіктерді қолдануға тырысқан жөн. Мысалы, сізде үйдің бағасын анықтаудың мақсаттық функциясын кеңейту мүмкіндігі бар, сонда ол шаршы метрдің (x2) есептелген ерекшелігін қамтиды:
Java әзірлеушілеріне арналған машиналық оқыту, 2 - 8 бөлім
Бірнеше мүмкіндіктерді пайдалану әртүрлі мүмкіндіктер бойынша ауқымды стандарттау үшін пайдаланылатын мүмкіндік масштабын қажет етеді. Осылайша, өлшем 2 төлсипаты үшін мәндер ауқымы өлшем төлсипаты үшін мәндер ауқымынан айтарлықтай үлкен. Мүмкіндіктерді масштабтаусыз 2 өлшем шығын функциясына негізсіз әсер етеді. Өлшем 2 төлсипаты енгізген қате өлшем төлсипаты енгізген қатеден айтарлықтай үлкен болады. Қарапайым мүмкіндіктерді масштабтау алгоритмі төменде келтірілген:
Java әзірлеушілеріне арналған машиналық оқыту, 2 - 9 бөлім
FeaturesScalingБұл алгоритм төмендегі мысал codeындағы сыныпта жүзеге асырылады . Класс FeaturesScalingоқу деректеріне бейімделген масштабтау функциясын жасаудың коммерциялық әдісін ұсынады. Ішкі жағдайда оқыту деректерінің даналары орташа, ең төменгі және ең үлкен мәндерді есептеу үшін пайдаланылады. Алынған функция мүмкіндік векторын алып, масштабталған мүмкіндіктері бар жаңасын шығарады. Мүмкіндіктерді масштабтау төменде көрсетілгендей оқу процесі үшін де, болжау процесі үшін де қажет:
// создание массива данных
List<ltDouble[]> dataset = new ArrayList<>();
dataset.add(new Double[] { 1.0, 90.0, 8100.0 }); // feature vector of house#1
dataset.add(new Double[] { 1.0, 101.0, 10201.0 }); // feature vector of house#2
dataset.add(new Double[] { 1.0, 103.0, 10609.0 }); // ...
//...

// создание меток
List<ltDouble> labels = new ArrayList<>();
labels.add(249.0); // price label of house#1
labels.add(338.0); // price label of house#2
labels.add(304.0); // ...
//...

// создание расширенного списка признаков
Function<ltDouble[], Double[]> scalingFunc = FeaturesScaling.createFunction(dataset);
List<ltDouble[]> scaledDataset = dataset.stream().map(scalingFunc).collect(Collectors.toList());

// создаем функцию которая инициализирует теты и осуществляет обучение //используя коэффициент обучения 0.1

LinearRegressionFunction targetFunction = new LinearRegressionFunction(new double[] { 1.0, 1.0, 1.0 });
for (int i = 0; i < 10000; i++) {
 targetFunction = Learner.train(targetFunction, scaledDataset, labels, 0.1);
}

// делаем предсказание стоимости дома с площадью 600 m2
Double[] scaledFeatureVector = scalingFunc.apply(new Double[] { 1.0, 600.0, 360000.0 });
double predictedPrice = targetFunction.apply(scaledFeatureVector);
Барған сайын көбірек мүмкіндіктер қосылған сайын, мақсат функциясына сәйкестік артады, бірақ абай болыңыз. Егер сіз тым алысқа барсаңыз және тым көп мүмкіндіктерді қоссаңыз, сіз шамадан тыс мақсатты функцияны үйренуіңіз мүмкін.

Шамадан тыс сәйкестік және айқаспалы тексеру

Шамадан тыс орнату мақсаттық функция немесе үлгі жаттығу деректеріне тым жақсы сәйкес келген кезде пайда болады, сондықтан ол шу немесе жаттығу деректеріндегі кездейсоқ өзгерістерді түсіреді. Төменгі оң жақтағы графикте шамадан тыс орнату мысалы көрсетілген:
Java әзірлеушілеріне арналған машиналық оқыту, 2 - 10 бөлім
Дегенмен, шамадан тыс орнату үлгісі жаттығу деректерінде өте жақсы жұмыс істейді, бірақ нақты белгісіз деректерде нашар жұмыс істейді. Шамадан тыс жатудың бірнеше жолы бар.
  • Жаттығу үшін үлкенірек деректер жинағын пайдаланыңыз.
  • Жоғарыдағы графиктерде көрсетілгендей аз мүмкіндіктерді пайдаланыңыз.
  • Регуляризацияны ескеретін жақсартылған машиналық оқыту алгоритмін пайдаланыңыз.
Болжау алгоритмі жаттығу деректеріне сәйкес келетін болса, оның дәлдігіне пайда әкелмейтін мүмкіндіктерді жою қажет. Басқаларға қарағанда болжау дәлдігіне айтарлықтай әсер ететін мүмкіндіктерді табу қиын. Графиктерде көрсетілгендей, артық сәйкестікті графиктер арқылы визуалды түрде анықтауға болады. Бұл 2 немесе 3 координаты бар графиктер үшін жақсы жұмыс істейді, егер сіз 2-ден көп мүмкіндікті пайдалансаңыз, графикті салу және бағалау қиынға соғады. Айқас тексеруде жаттығу процесі аяқталғаннан кейін алгоритмге белгісіз деректерді пайдаланып, жаттығудан кейін үлгілерді қайта сынайсыз. Қол жетімді таңбаланған деректер 3 жинаққа бөлінуі керек:
  • оқыту деректері;
  • тексеру деректері;
  • сынақ деректері.
Бұл жағдайда үйлерді сипаттайтын таңбаланған жазбалардың 60 пайызы мақсатты алгоритмнің нұсқаларын оқыту процесінде пайдаланылуы керек. Жаттығу процесінен кейін қалған деректердің жартысы (бұрын пайдаланылмаған) оқытылған мақсатты алгоритмнің белгісіз деректерде жақсы жұмыс істейтінін тексеру үшін пайдаланылуы керек. Әдетте, пайдалану үшін басқаларға қарағанда жақсы жұмыс істейтін алгоритм таңдалады. Қалған деректер соңғы таңдалған модель үшін қате мәнін есептеу үшін пайдаланылады. k-fold сияқты басқа кросс-тексеру әдістері бар . Дегенмен, мен оларды осы мақалада сипаттамаймын.

Машиналық оқыту құралдары және Weka негізі

Көптеген фреймворктар мен кітапханалар машиналық оқыту алгоритмдерінің кең жинағын қамтамасыз етеді. Сонымен қатар, олар деректер үлгілерін оқыту, тестілеу және өңдеу үшін ыңғайлы жоғары деңгейлі интерфейсті қамтамасыз етеді. Weka - JVM үшін ең танымал фреймворктардың бірі. Weka — үлгілерді тексеруге арналған графикалық сынақтарды қамтитын практикалық Java кітапханасы. Төмендегі мысал мүмкіндіктер мен белгілерді қамтитын оқу деректер жинағын жасау үшін Weka кітапханасын пайдаланады. Әдіс setClassIndex()– белгілеу үшін. Weka тілінде белгі класс ретінде анықталады:
// определяем атрибуты для признаков и меток
ArrayList<ltAttribute> attributes = new ArrayList<>();
Attribute sizeAttribute = new Attribute("sizeFeature");
attributes.add(sizeAttribute);
Attribute squaredSizeAttribute = new Attribute("squaredSizeFeature");
attributes.add(squaredSizeAttribute);
Attribute priceAttribute = new Attribute("priceLabel");
attributes.add(priceAttribute);


// создаем и заполняем список признаков 5000 примеров
Instances trainingDataset = new Instances("trainData", attributes, 5000);
trainingDataset.setClassIndex(trainingSet.numAttributes() - 1);
Instance instance = new DenseInstance(3);

instance.setValue(sizeAttribute, 90.0);
instance.setValue(squaredSizeAttribute, Math.pow(90.0, 2));
instance.setValue(priceAttribute, 249.0);
trainingDataset.add(instance);
Instance instance = new DenseInstance(3);
instance.setValue(sizeAttribute, 101.0);
...
Деректер жинағы мен үлгі нысанын файлдан сақтауға және жүктеуге болады. Weka Weka графикалық эталондары қолдайтын ARFF (Атрибут қатынасының файл пішімі) пайдаланады. Бұл деректер жинағы Векадағы классификатор ретінде белгілі мақсат функциясын үйрету үшін пайдаланылады. Ең алдымен, сіз мақсаттық функцияны анықтауыңыз керек. Төмендегі code LinearRegressionклассификатордың данасын жасайды. Бұл классификатор көмегімен оқытылады buildClassifier(). Әдіс buildClassifier()ең жақсы мақсатты үлгіні іздеуде оқыту деректеріне негізделген тета параметрлерін таңдайды. Weka көмегімен оқу жылдамдығын немесе итерациялар санын орнату туралы алаңдамаудың қажеті жоқ. Weka сонымен қатар мүмкіндіктерді масштабтауды дербес орындайды.
Classifier targetFunction = new LinearRegression();
targetFunction.buildClassifier(trainingDataset);
Осы параметрлерді орындағаннан кейін мақсат функциясы төменде көрсетілгендей үйдің бағасын болжау үшін пайдаланылуы мүмкін:
Instances unlabeledInstances = new Instances("predictionset", attributes, 1);
unlabeledInstances.setClassIndex(trainingSet.numAttributes() - 1);
Instance unlabeled = new DenseInstance(3);
unlabeled.setValue(sizeAttribute, 1330.0);
unlabeled.setValue(squaredSizeAttribute, Math.pow(1330.0, 2));
unlabeledInstances.add(unlabeled);

double prediction = targetFunction.classifyInstance(unlabeledInstances.get(0));
EvaluationWeka дайындалған классификаторды немесе үлгіні сынау үшін сыныпты ұсынады . Төмендегі codeта жалған нәтижелерді болдырмау үшін тексеру деректерінің таңдалған массиві пайдаланылады. Өлшеу нәтижелері (қате құны) консольде көрсетіледі. Әдетте, бағалау нәтижелері әртүрлі машиналық оқыту алгоритмдері немесе олардың нұсқалары арқылы оқытылған үлгілерді салыстыру үшін пайдаланылады:
Evaluation evaluation = new Evaluation(trainingDataset);
evaluation.evaluateModel(targetFunction, validationDataset);
System.out.println(evaluation.toSummaryString("Results", false));
Жоғарыдағы мысалда кіріс мәндеріне негізделген үйдің бағасы сияқты сандық мәндерді болжайтын сызықтық регрессия қолданылады. Сызықтық регрессия үздіксіз сандық мәндерді болжауды қолдайды. Екілік мәндерді болжау үшін («Иә» және «Жоқ») басқа машиналық оқыту алгоритмдерін пайдалану керек. Мысалы, шешім ағашы, нейрондық желілер немесе логистикалық регрессия.
// использование логистической регрессии
Classifier targetFunction = new Logistic();
targetFunction.buildClassifier(trainingSet);
Сіз осы алгоритмдердің бірін пайдалана аласыз, мысалы, электрондық пошта хабарының спам екенін болжау немесе ауа-райын болжау немесе үйдің жақсы сатылатынын болжау. Алгоритміңізді ауа-райын немесе үй қаншалықты тез сатылатынын болжауға үйреткіңіз келсе, сізге басқа деректер жинағы қажет, мысалы.topseller:
// использование атрибута маркера topseller instead of атрибута маркера цена
ArrayList<string> classVal = new ArrayList<>();
classVal.add("true");
classVal.add("false");

Attribute topsellerAttribute = new Attribute("topsellerLabel", classVal);
attributes.add(topsellerAttribute);
Бұл деректер жинағы жаңа классификаторды үйрету үшін пайдаланылады topseller. Жаттығудан кейін болжау шақыруы болжанған мәнді алу үшін пайдалануға болатын таңбалауыш класының индексін қайтаруы керек.
int idx = (int) targetFunction.classifyInstance(unlabeledInstances.get(0));
String prediction = classVal.get(idx);

Қорытынды

Машиналық оқыту статистикамен тығыз байланысты және көптеген математикалық түсініктерді пайдаланғанымен, машиналық оқыту құралдарының жинағы математиканы терең білмей-ақ, бағдарламаларыңызға машиналық оқытуды біріктіруді бастауға мүмкіндік береді. Дегенмен, біз осы мақалада қарастырған сызықтық регрессия алгоритмі сияқты негізгі машиналық оқыту алгоритмдерін неғұрлым жақсы түсінсеңіз, соғұрлым дұрыс алгоритмді таңдап, оны оңтайлы өнімділік үшін реттей аласыз. Ағылшын тілінен аударма . Authorы: Грегор Рот, бағдарламалық жасақтаманың сәулетшісі, JavaWorld.
Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION