摘要:
Xcode现在提供了一个名为CreateML
的框架,该框架提供了机器学习训练功能。只能在.playground
文件中使用。
问题:
我的工作流程受到影响,因为我需要在playground
中手动重写动态值,然后在Xcode
项目中再次重写动态值。
目标:
要在我的项目中自动生成Playground文件和相应的mlmodel处理代码,从而无需在多个项目中手动进行更改
OR
以便将运动场文件包含在我的MacOS项目中,并使我的.swift
文件与我的.playground
文件进行通话。
当前失败的尝试:
open with
,但没有选择Xcode。这是我得到的错误。OR
.playground
文件与.swift
通信。代码:
public struct LogEntry: Error {
var text: StaticString
var type: OSLogType
var argument: Any?
var osLog = customLog
init(text: StaticString, argument: Any? = nil, type: OSLogType = .error, osLog: OSLog = customLog) {
self.text = text
self.type = type
self.osLog = osLog
self.argument = argument
}
func log() {
os_log(text , log: osLog, type: type, String(describing: argument))
print(String(describing: argument))
}
}
postfix operator *
extension Result where Failure == LogEntry {
@discardableResult
static postfix func *(expression: Self) -> Success? {
switch expression {
case .success(let win):
return win
case .failure(let fail):
print(fail.localizedDescription)
print(fail.text)
print(fail.argument)
return nil
}
}
}
extension String {
static func mlplaygroundcode(
_ csvaddy: String,
target: String,
modelname: String
) -> String {
"""
import Cocoa
import CreateML
guard let stockCSV = URL(string: "\(csvaddy)") else { fatalError() }
let stockData = try MLDataTable(contentsOf: stockCSV)
let (trainingData, testData) = stockData.randomSplit(by: 0.8, seed: 0)
let model = try MLRegressor(trainingData: stockData, targetColumn: "\(target)")
let metrics = model.evaluation(on: testData)
let predictions = try model.predictions(from: testData)
try model.write(to: URL(fileURLWithPath: "/Users/\(NSUserName())/Desktop/iOS/TimeFountain/TimeFountain/\(modelname).mlmodel"), metadata: nil)
"""
}
/// Creates a csv for ml string. self is the csv address.
/// - Parameters:
/// - csvaddy: The address of the csv
/// - target: the target column header text
/// - modelname:
/// - Returns: Returns the playground address.
func generateMLPlayground(
target: String = .target,
finalmodelname: String,
playgroundName: String
) -> Result<String, LogEntry> {
String.mlplaygroundcode(
self,
target: target,
modelname: finalmodelname
).createFile(
desktopPath: "iOS/TimeFountain/TimeFountain/",
name: playgroundName, //"tesst",
fileEnding: "playground"
)
}
/// creates a file locally.
/// - Parameters:
/// - desktopPath: Starts without a slash, ends with a slash. Assumes the path starts after the desktop path is established. alt: "iOS/TimeFountain/TimeFountain/"
/// - name: Pass a name ie. ticker + .currentDate
/// - fileEnding: File ending such as csv or playground. The period is not required.
/// - Returns: returns a discardeable Resullt to account for multiple possible errors.
@discardableResult internal func createFile(
desktopPath: String = "iOS/DataFrame/",
name: String,
fileEnding: String
) -> Result<String, LogEntry> {
let fileManager = FileManager.default
var fileURL: URL?
do {
let path = try fileManager.url(
for: .desktopDirectory,
in: .allDomainsMask,
appropriateFor: nil,
create: false
)
fileURL = path.appendingPathComponent(desktopPath + name + "." + fileEnding)
guard let fileURL = fileURL else {
return Result(failure: LogEntry(text: "ERROR: did Not Assign File URL"))
}
try write(
to: fileURL,
atomically: true,
encoding: .utf8
)
} catch let error {
print("error creating file", error.localizedDescription)
return Result(failure: LogEntry(text: "ERROR: error creating file"))
}
guard let url = fileURL else {
return Result(failure: LogEntry(text: "ERROR: did Not Assign File URL"))
}
print(url.absoluteString)
return Result(success: url.absoluteString)
}
}
print(
trainData.csvAddress.generateMLPlayground(
finalmodelname: "TestMe",
playgroundName: "TestMea"
)*
)