JavaRush /Java blogi /Random-UZ /Java dasturchilari uchun mashinani o'rganish, 2-qism

Java dasturchilari uchun mashinani o'rganish, 2-qism

Guruhda nashr etilgan
Java dasturchilari uchun mashinani o'rganish, 1-qism
Java dasturchilari uchun mashinani o'rganish, 2 - 1-qism

Maqsadli funktsiyani baholash

Eslatib o'tamiz, maqsadli funktsiya , bashorat qilish funktsiyasi sifatida ham tanilgan, tayyorgarlik yoki o'qitish jarayonining natijasidir. хMatematik jihatdan muammo o'zgaruvchini kirish sifatida qabul qiladigan va taxmin qilingan qiymatni qaytaradigan funktsiyani topishdir у.
Java dasturchilari uchun mashinani o'rganish, 2 - 2 qism
Mashinani o'rganishda xarajat funktsiyasi (J(θ))berilgan maqsad funktsiyasining xato qiymatini yoki "narxini" hisoblash uchun ishlatiladi.
Java dasturchilari uchun mashinani o'rganish, 2 - 3 qism
Xarajat funktsiyasi modelning o'quv ma'lumotlariga qanchalik mos kelishini ko'rsatadi. Yuqorida ko'rsatilgan maqsad funktsiyasining narxini aniqlash uchun har bir misolning kvadrat xatosini hisoblash kerak uy (i). Xato hisoblangan qiymat va misoldan uyning уhaqiqiy qiymati o'rtasidagi masofa . yi
Java dasturchilari uchun mashinani o'rganish, 2 - 4 qism
Masalan, uyning haqiqiy narxi 1330 = 6 500 000 € . Va o'qitilgan maqsad funktsiyasi tomonidan taxmin qilingan uy narxi o'rtasidagi farq €7,032,478 : farq (yoki xato) €532,478 . Ushbu farqni yuqoridagi grafikda ham ko'rishingiz mumkin. Farq (yoki xato) har bir narx-hudud o'quv juftligi uchun vertikal chiziqli qizil chiziqlar sifatida ko'rsatilgan. O'qitilgan maqsad funktsiyasining narxini hisoblab chiqqandan so'ng, misoldagi har bir uy uchun kvadrat xatoni yig'ib, asosiy qiymatni hisoblashingiz kerak. Narx qiymati qanchalik kichik bo'lsa (J(θ)), maqsad funktsiyamizning prognozlari shunchalik aniq bo'ladi. 3 -ro'yxatda maqsad funktsiyasini, o'quv ma'lumotlari ro'yxatini va ular bilan bog'liq teglarni kiritish sifatida qabul qiladigan xarajat funktsiyasining oddiy Java dasturi ko'rsatilgan. Prognoz qiymatlari tsiklda hisoblab chiqiladi va xato haqiqiy narx qiymatini (yorliqdan olingan) ayirish yo'li bilan hisoblanadi. Keyinchalik, xatolar kvadrati yig'iladi va xato qiymati hisoblanadi. Xarajat quyidagi turdagi qiymat sifatida qaytariladi double:

Ro'yxat - 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 haqida o'qishga qiziqasizmi? Java Developer guruhiga qo'shiling !

Maqsadli funktsiyani o'rganish

Narxlar funksiyasi maqsadli funksiya va teta parametrlarining sifatini baholashga yordam bersa-da, siz hali ham eng mos teta parametrlarini topishingiz kerak. Buning uchun gradient tushish algoritmidan foydalanishingiz mumkin.

Gradient tushishi

Gradientning tushishi xarajat funktsiyasini kamaytiradi. (J(θ))Bu shuni anglatadiki, u o'quv ma'lumotlari asosida minimal narxga ega bo'lgan teta parametrlarini topish uchun ishlatiladi . Mana yangi, mosroq teta qiymatlarini hisoblash uchun soddalashtirilgan algoritm:
Java dasturchilari uchun mashinani o'rganish, 2 - 5 qism
Shunday qilib, algoritmning har bir iteratsiyasi bilan teta vektorining parametrlari yaxshilanadi. O'rganish koeffitsienti a har bir iteratsiyada hisob-kitoblar sonini belgilaydi. Ushbu hisob-kitoblar "yaxshi" teta qiymatlari topilmaguncha amalga oshirilishi mumkin. Masalan, quyidagi chiziqli regressiya funktsiyasi uchta teta parametriga ega:
Java dasturchilari uchun mashinani o'rganish, 2 - 6 qism
Har bir iteratsiyada teta parametrlarining har biri uchun yangi qiymat hisoblab chiqiladi: , , va . Har bir iteratsiyadan so'ng yangi teta vektor {th 0 , th 1 , th 2 } yordamida yangi, mosroq dastur yaratilishi mumkin . Ro'yxat -4 gradient parchalanish algoritmi uchun Java kodini ko'rsatadi. Regressiya funktsiyasi uchun teta o'quv ma'lumotlari, marker ma'lumotlari, o'rganish tezligi yordamida o'qitiladi . Natijada teta parametrlari yordamida yaxshilangan maqsad funktsiyasi bo'ladi. Usul qayta-qayta chaqiriladi, yangi maqsad funksiyasi va oldingi hisob-kitoblardan yangi teta parametrlari o'tadi. Va bu qo'ng'iroqlar sozlangan maqsad funktsiyasi minimal platoga yetguncha takrorlanadi: θ0θ1θ2LinearRegressionFunction(α)train()

Ro'yxat - 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);
}
Narx doimiy ravishda kamayib borishini ta'minlash uchun J(θ)har bir o'quv bosqichidan so'ng xarajat funksiyasini ishga tushirishingiz mumkin. Har bir iteratsiyadan keyin xarajat kamayishi kerak. Agar bu sodir bo'lmasa, bu o'rganish koeffitsientining qiymati juda katta ekanligini va algoritm minimal qiymatni o'tkazib yuborganligini anglatadi. Bunday holda, gradientni pasaytirish algoritmi muvaffaqiyatsiz bo'ladi. Quyidagi chizmalar boshlang'ich teta vektoridan boshlab yangi, hisoblangan teta parametrlaridan foydalangan holda maqsad funktsiyasini ko'rsatadi {1.0, 1.0}. Chap ustunda 50 ta takrorlashdan keyin bashorat qilish funktsiyasining syujeti ko'rsatilgan; 200 marta takrorlangandan keyin o'rta ustun; va 1000 marta takrorlangandan keyin o'ng ustun. Bulardan ko'rishimiz mumkinki, har bir iteratsiyadan keyin narx pasayadi va yangi maqsad funksiyasi yaxshiroq va yaxshiroq mos keladi. 500-600 marta takrorlangandan so'ng, teta parametrlari endi sezilarli darajada o'zgarmaydi va narx barqaror platoga etadi. Shundan so'ng, maqsadli funktsiyaning aniqligini bu tarzda yaxshilash mumkin emas.
Java dasturchilari uchun mashinani o'rganish, 2 - 7 qism
Bunday holda, 500-600 takrorlashdan keyin xarajat endi sezilarli darajada kamaymasa ham, maqsad funktsiyasi hali ham optimal emas. Bu nomuvofiqlikni ko'rsatadi . Mashinani o'rganishda "nomuvofiqlik" atamasi o'rganish algoritmi ma'lumotlarda asosiy tendentsiyalarni topa olmasligini ko'rsatish uchun ishlatiladi. Haqiqiy hayot tajribasiga asoslanib, kattaroq ob'ektlar uchun kvadrat metr uchun narxning pasayishi kutilishi mumkin. Bundan xulosa qilishimiz mumkinki, maqsadli funktsiyani o'rganish jarayoni uchun foydalanilgan model ma'lumotlarga etarlicha mos kelmaydi. Mos kelmaslik ko'pincha modelni haddan tashqari soddalashtirish bilan bog'liq. Bu bizning holatlarimizda sodir bo'ldi, maqsad funktsiyasi juda oddiy va tahlil qilish uchun u bitta parametrdan foydalanadi - uyning maydoni. Ammo bu ma'lumot uyning narxini aniq bashorat qilish uchun etarli emas.

Xususiyatlarni qo'shish va ularni masshtablash

Agar maqsad funksiyangiz siz hal qilmoqchi bo'lgan muammoga mos kelmasligini aniqlasangiz, uni tuzatish kerak. Mos kelmaslikni tuzatishning keng tarqalgan usuli bu xususiyat vektoriga qo'shimcha funktsiyalarni qo'shishdir. Uyning narxi misolida siz xonalar soni yoki uyning yoshi kabi xususiyatlarni qo'shishingiz mumkin. Ya'ni, {size}uyni tavsiflash uchun bitta xususiyat qiymatiga ega vektordan foydalanish o'rniga, bir nechta qiymatlarga ega vektordan foydalanishingiz mumkin, masalan, {size, number-of-rooms, age}. Ba'zi hollarda mavjud o'quv ma'lumotlaridagi xususiyatlar soni etarli emas. Keyin mavjud bo'lganlar yordamida hisoblangan polinom xususiyatlardan foydalanishga harakat qilish kerak. Masalan, sizda uyning narxini aniqlashning maqsad funktsiyasini kengaytirish imkoniyati mavjud bo'lib, u kvadrat metrning (x2) hisoblangan xususiyatini o'z ichiga oladi:
Java dasturchilari uchun mashinani o'rganish, 2 - 8 qism
Bir nechta xususiyatlardan foydalanish turli xil xususiyatlar bo'yicha diapazonni standartlashtirish uchun ishlatiladigan xususiyatlarni o'lchashni talab qiladi. Shunday qilib, 2 o'lchamli atribut uchun qiymatlar diapazoni o'lcham atributi qiymatlari oralig'idan sezilarli darajada kattaroqdir. Xususiyatlarni masshtablashsiz, 2 o'lcham xarajat funktsiyasiga asossiz ta'sir qiladi. 2 o'lcham atributi tomonidan kiritilgan xato o'lcham atributi tomonidan kiritilgan xatodan sezilarli darajada katta bo'ladi. Xususiyatlarni masshtablashning oddiy algoritmi quyida keltirilgan:
Java dasturchilari uchun mashinani o'rganish, 2 - 9 qism
FeaturesScalingUshbu algoritm quyidagi misol kodidagi sinfda amalga oshiriladi . Sinf FeaturesScalingo'quv ma'lumotlariga moslashtirilgan masshtablash funktsiyasini yaratish uchun tijorat usulini taqdim etadi. Ichkarida o'quv ma'lumotlari namunalari o'rtacha, minimal va maksimal qiymatlarni hisoblash uchun ishlatiladi. Olingan funksiya xususiyat vektorini oladi va masshtablangan funksiyalarga ega yangisini ishlab chiqaradi. Xususiyatlarni masshtablash quyida ko'rsatilganidek, o'quv jarayoni uchun ham, bashorat qilish jarayoni uchun ham zarur:
// создание массива данных
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);
Ko'proq va ko'proq xususiyatlar qo'shilsa, maqsad funktsiyasiga moslashish kuchayadi, lekin ehtiyot bo'ling. Agar siz juda uzoqqa borsangiz va juda ko'p xususiyatlarni qo'shsangiz, siz haddan tashqari mos keladigan ob'ektiv funktsiyani o'rganishingiz mumkin.

Haddan tashqari moslik va o'zaro tekshirish

Maqsad funktsiyasi yoki modeli mashg'ulot ma'lumotlariga juda mos kelganda, haddan tashqari moslashish sodir bo'ladi, shuning uchun u mashg'ulot ma'lumotlaridagi shovqin yoki tasodifiy o'zgarishlarni ushlaydi. Haddan tashqari o'rnatish misoli quyida eng o'ngdagi grafikda ko'rsatilgan:
Java dasturchilari uchun mashinani o'rganish, 2 - 10-qism
Biroq, haddan tashqari moslashtirilgan model o'quv ma'lumotlarida juda yaxshi ishlaydi, lekin haqiqiy noma'lum ma'lumotlarda yomon ishlaydi. Haddan tashqari moslashishdan qochishning bir necha yo'li mavjud.
  • Trening uchun kattaroq ma'lumotlar to'plamidan foydalaning.
  • Yuqoridagi grafiklarda ko'rsatilganidek, kamroq xususiyatlardan foydalaning.
  • Regulyatsiyani hisobga oladigan takomillashtirilgan mashinani o'rganish algoritmidan foydalaning.
Agar bashorat qilish algoritmi o'quv ma'lumotlariga to'g'ri kelsa, uning aniqligiga foyda keltirmaydigan xususiyatlarni yo'q qilish kerak. Qiyinchilik, boshqalarga qaraganda bashorat qilishning aniqligiga sezilarli ta'sir ko'rsatadigan xususiyatlarni topishdir. Grafiklarda ko'rsatilganidek, ortiqcha moslikni grafiklar yordamida vizual tarzda aniqlash mumkin. Bu 2 yoki 3 koordinatali grafiklar uchun yaxshi ishlaydi, agar siz 2 dan ortiq xususiyatdan foydalansangiz, grafikni tuzish va baholash qiyin bo'ladi. O'zaro tekshirishda siz o'quv jarayoni tugagandan so'ng algoritmga noma'lum ma'lumotlardan foydalangan holda treningdan so'ng modellarni qayta sinovdan o'tkazasiz. Mavjud yorliqli ma'lumotlar 3 to'plamga bo'linishi kerak:
  • o'quv ma'lumotlari;
  • tekshirish ma'lumotlari;
  • test ma'lumotlari.
Bunday holda, uylarni tavsiflovchi yorliqli yozuvlarning 60 foizi maqsadli algoritm variantlarini o'qitish jarayonida qo'llanilishi kerak. O'quv jarayonidan so'ng, qolgan ma'lumotlarning yarmi (ilgari ishlatilmagan) o'qitilgan maqsadli algoritm noma'lum ma'lumotlarda yaxshi ishlashini tekshirish uchun ishlatilishi kerak. Odatda, foydalanish uchun boshqalarga qaraganda yaxshiroq ishlaydigan algoritm tanlanadi. Qolgan ma'lumotlar oxirgi tanlangan model uchun xato qiymatini hisoblash uchun ishlatiladi. k-fold kabi boshqa o'zaro tekshirish usullari mavjud . Biroq, men ularni ushbu maqolada tasvirlamayman.

Mashinani o'rganish vositalari va Weka ramkasi

Ko'pgina ramkalar va kutubxonalar mashinani o'rganish algoritmlarining keng to'plamini taqdim etadi. Bundan tashqari, ular ma'lumotlar modellarini o'qitish, sinovdan o'tkazish va qayta ishlash uchun qulay yuqori darajadagi interfeysni ta'minlaydi. Weka JVM uchun eng mashhur ramkalardan biridir. Weka amaliy Java kutubxonasi boʻlib, unda modellarni tekshirish uchun grafik testlar mavjud. Quyidagi misolda xususiyatlar va teglarni o'z ichiga olgan o'quv ma'lumotlar to'plamini yaratish uchun Weka kutubxonasidan foydalaniladi. Usul setClassIndex()- belgilash uchun. Weka'da yorliq sinf sifatida aniqlanadi:
// определяем атрибуты для признаков и меток
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);
...
Ma'lumotlar to'plami va namuna ob'ekti fayldan saqlanishi va yuklanishi mumkin. Weka Weka grafik mezonlari tomonidan qo'llab-quvvatlanadigan ARFF (Attribute Relation File Format) dan foydalanadi. Ushbu ma'lumotlar to'plami Weka-da tasniflagich sifatida tanilgan maqsad funktsiyasini o'rgatish uchun ishlatiladi. Avvalo, siz maqsad funktsiyasini aniqlashingiz kerak. Quyidagi kod LinearRegressiontasniflagichning namunasini yaratadi. Ushbu klassifikator yordamida o'qitiladi buildClassifier(). Usul buildClassifier()eng yaxshi maqsadli modelni izlashda ta'lim ma'lumotlari asosida teta parametrlarini tanlaydi. Weka bilan siz o'rganish tezligi yoki takrorlash sonini belgilash haqida tashvishlanishingiz shart emas. Weka shuningdek, xususiyatlarni masshtablashni mustaqil ravishda amalga oshiradi.
Classifier targetFunction = new LinearRegression();
targetFunction.buildClassifier(trainingDataset);
Ushbu sozlashlar amalga oshirilgandan so'ng, maqsad funktsiyasidan quyida ko'rsatilganidek, uyning narxini taxmin qilish uchun foydalanish mumkin:
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 o'qitilgan tasniflagich yoki modelni sinab ko'rish uchun sinfni taqdim etadi . Quyidagi kodda noto'g'ri natijalarni oldini olish uchun tanlangan tekshirish ma'lumotlari to'plami ishlatiladi. O'lchov natijalari (xatolik narxi) konsolda ko'rsatiladi. Odatda, baholash natijalari turli xil mashinani o'rganish algoritmlari yoki ularning o'zgarishlari yordamida o'qitilgan modellarni solishtirish uchun ishlatiladi:
Evaluation evaluation = new Evaluation(trainingDataset);
evaluation.evaluateModel(targetFunction, validationDataset);
System.out.println(evaluation.toSummaryString("Results", false));
Yuqoridagi misolda chiziqli regressiya qo'llaniladi, u kirish qiymatlari asosida uyning narxi kabi raqamli qiymatlarni bashorat qiladi. Chiziqli regressiya doimiy raqamli qiymatlarni bashorat qilishni qo'llab-quvvatlaydi. Ikkilik qiymatlarni ("Ha" va "Yo'q") bashorat qilish uchun siz boshqa mashinani o'rganish algoritmlaridan foydalanishingiz kerak. Masalan, qarorlar daraxti, neyron tarmoqlar yoki logistik regressiya.
// использование логистической регрессии
Classifier targetFunction = new Logistic();
targetFunction.buildClassifier(trainingSet);
Siz ushbu algoritmlardan birini ishlatishingiz mumkin, masalan, elektron pochta xabari spam ekanligini yoki ob-havoni bashorat qilish yoki uy yaxshi sotilishini bashorat qilish uchun. Agar siz algoritmingizni ob-havoni yoki uy qanchalik tez sotilishini bashorat qilishni o'rgatmoqchi bo'lsangiz, sizga boshqa ma'lumotlar to'plami kerak, masalan.topseller:
// использование атрибута маркера topseller instead of атрибута маркера цена
ArrayList<string> classVal = new ArrayList<>();
classVal.add("true");
classVal.add("false");

Attribute topsellerAttribute = new Attribute("topsellerLabel", classVal);
attributes.add(topsellerAttribute);
Ushbu ma'lumotlar to'plami yangi tasniflagichni o'rgatish uchun ishlatiladi topseller. O'qitilgandan so'ng, bashorat qo'ng'irog'i bashorat qilingan qiymatni olish uchun ishlatilishi mumkin bo'lgan token klassi indeksini qaytarishi kerak.
int idx = (int) targetFunction.classifyInstance(unlabeledInstances.get(0));
String prediction = classVal.get(idx);

Xulosa

Mashinani o'rganish statistika bilan chambarchas bog'liq bo'lsa-da va ko'plab matematik tushunchalardan foydalansa-da, mashinani o'rganish asboblar to'plami matematikani chuqur bilmasdan, mashina o'rganishni dasturlaringizga integratsiyalashni boshlash imkonini beradi. Biroq, ushbu maqolada biz ko'rib chiqqan chiziqli regressiya algoritmi kabi asosiy mashinani o'rganish algoritmlarini qanchalik yaxshi tushunsangiz, shunchalik ko'p to'g'ri algoritmni tanlashingiz va uni optimal ishlash uchun sozlashingiz mumkin bo'ladi. Ingliz tilidan tarjima . Muallif: Gregor Roth, Software Architect, JavaWorld.
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION