https://www.youtube.com/watch?v=x9_BG2q7XYw&t=4258s
// CreateML => Makes Model
// CoreML => Consumes Model
import CreateML
import Foundation
// Load JSON File into MLDataTable
let data = try MLDataTable(contentsOf: URL(fileURLWithPath: "/Users/paige/Desktop/JSONMLTraining.playground/Resources/better-sleep.json"))
// 80% of my data to be trained , 20% of my data to be tested
// 80% is common value
let (trainingData, testingData) = data.randomSplit(by: 0.8)
// target column => what data to be figured out based on other columns
// Use an MLRegressor to estimate continuous values like price, time, or temperature.
/*
{
"wake": 32400,
"estimatedSleep": 5,
"coffee": 2,
"actualSleep": 20180
}
*/
let regressor = try MLRegressor(trainingData: trainingData, targetColumn: "actualSleep")
// Testing Data..
let evaluationMetrics = regressor.evaluation(on: testingData)
// How far the average is off, Mean Error
// 3, 3, 3 = 3 + 3 + 3 = 9 = sqrt(9) = 3
// 2, 3, 4 => 4, 9, 16 => 29 => sqrt(29) => 3.2, bigger the number is, bigger the weight
print(evaluationMetrics.rootMeanSquaredError) //179.64540784526716
// Evaluates how good this data is, find the biggest possible value
// Largest Difference
print(evaluationMetrics.maximumError) //698.6751010852458
// Give Metadata
let metadata = MLModelMetadata(author: "Paige Shin", shortDescription: "A model trained to predict optimum sleep times for coffee drinkers", version: "1.0")
// Crete mlmodel
try regressor.write(to: URL(fileURLWithPath: "/Users/paige/Desktop/JSONMLTraining.playground/Resources/SleepCalculator.mlmodel"), metadata: metadata)
- Drag and Drop on Xcode Project
//
// ViewController.swift
// BetterRest
//
// Created by paige on 2021/12/13.
//
import UIKit
class ViewController: UIViewController {
private var wakeUpTime: UIDatePicker!
private var sleepAmountTime: UIStepper!
private var sleepAmountLabel: UILabel!
private var coffeeAmountStepper: UIStepper!
private var coffeeAmountLabel: UILabel!
override func loadView() {
view = UIView()
view.backgroundColor = .white
let mainStackView = UIStackView()
mainStackView.axis = .vertical
mainStackView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(mainStackView)
NSLayoutConstraint.activate([
mainStackView.topAnchor.constraint(equalTo: view.layoutMarginsGuide.topAnchor, constant: 20),
mainStackView.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor),
mainStackView.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor)
])
let wakeUpTitle = UILabel()
wakeUpTitle.font = UIFont.preferredFont(forTextStyle: .headline)
wakeUpTitle.numberOfLines = 0
wakeUpTitle.text = "When do you want to wake up?"
mainStackView.addArrangedSubview(wakeUpTitle)
wakeUpTime = UIDatePicker()
wakeUpTime.datePickerMode = .time
wakeUpTime.minuteInterval = 15
wakeUpTime.preferredDatePickerStyle = .wheels
mainStackView.addArrangedSubview(wakeUpTime)
var components = Calendar.current.dateComponents([.hour, .minute], from: Date())
components.hour = 8
components.minute = 0
wakeUpTime.date = Calendar.current.date(from: components) ?? Date()
let sleepTitle = UILabel()
sleepTitle.font = UIFont.preferredFont(forTextStyle: .headline)
sleepTitle.numberOfLines = 0
sleepTitle.text = "What's the minimum amount of sleep you need?"
mainStackView.addArrangedSubview(sleepTitle)
sleepAmountTime = UIStepper()
sleepAmountTime.addTarget(self, action: #selector(sleepAmountChanged), for: .valueChanged)
sleepAmountTime.stepValue = 0.25
sleepAmountTime.value = 8
sleepAmountTime.minimumValue = 4
sleepAmountTime.maximumValue = 12
sleepAmountLabel = UILabel()
sleepAmountLabel.font = UIFont.preferredFont(forTextStyle: .body)
let sleepStackView = UIStackView()
sleepStackView.spacing = 20
sleepStackView.addArrangedSubview(sleepAmountTime)
sleepStackView.addArrangedSubview(sleepAmountLabel)
mainStackView.addArrangedSubview(sleepStackView)
let coffeeTitle = UILabel()
coffeeTitle.font = UIFont.preferredFont(forTextStyle: .headline)
coffeeTitle.numberOfLines = 0
coffeeTitle.text = "How much coffee do you drink each day?"
mainStackView.addArrangedSubview(coffeeTitle)
coffeeAmountStepper = UIStepper()
coffeeAmountStepper.addTarget(self, action: #selector(coffeeAmountChanged), for: .valueChanged)
coffeeAmountStepper.maximumValue = 1
coffeeAmountStepper.maximumValue = 20
coffeeAmountLabel = UILabel()
coffeeAmountLabel.font = UIFont.preferredFont(forTextStyle: .body)
let coffeeStackView = UIStackView()
coffeeStackView.spacing = 20
coffeeStackView.addArrangedSubview(coffeeAmountStepper)
coffeeStackView.addArrangedSubview(coffeeAmountLabel)
mainStackView.addArrangedSubview(coffeeStackView)
mainStackView.setCustomSpacing(10, after: sleepTitle)
mainStackView.setCustomSpacing(20, after: sleepStackView)
mainStackView.setCustomSpacing(10, after: coffeeTitle)
sleepAmountChanged()
coffeeAmountChanged()
}
override func viewDidLoad() {
super.viewDidLoad()
title = "Better Rest"
navigationController?.navigationBar.prefersLargeTitles = true
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Calculate", style: .plain, target: self, action: #selector(calculateBedtime))
}
@objc
private func sleepAmountChanged() {
sleepAmountLabel.text = String(format: "%g hours", sleepAmountTime.value)
}
@objc
private func coffeeAmountChanged() {
if coffeeAmountStepper.value == 1 {
coffeeAmountLabel.text = "1 cup"
} else {
coffeeAmountLabel.text = "\(Int(coffeeAmountStepper.value)) cups"
}
}
@objc
private func calculateBedtime() {
let title: String
let message: String
do {
let model = try SleepCalculator.init(configuration: .init()) // Auto generated class
let components = Calendar.current.dateComponents([.hour, .minute], from: wakeUpTime.date)
let hour = (components.hour ?? 0) * 60 * 60
let minute = (components.minute ?? 0) * 60
let prediction = try model.prediction(coffee: coffeeAmountStepper.value, estimatedSleep: sleepAmountTime.value, wake: Double(hour + minute))
let formatter = DateFormatter()
formatter.timeStyle = .short
let wakeDate = wakeUpTime.date - prediction.actualSleep
message = formatter.string(from: wakeDate)
title = "Your ideal bedtime is..."
} catch {
title = "Error"
message = "Sorry, there was a problem calculating your bedtime."
}
let ac = UIAlertController(title: title, message: message, preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "OK", style: .default))
present(ac, animated: true)
}
}