Files
wehub-resource-sync 7254f7b4d1
Build / Build (macos-latest) (push) Has been cancelled
Build / Build (ubuntu-latest) (push) Has been cancelled
Build / Build (windows-latest) (push) Has been cancelled
Build / Analyze (javascript) (push) Has been cancelled
Build / Analyze (python) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:37:45 +08:00

292 lines
12 KiB
JavaScript

// Experimental
const sklearn = {};
sklearn.ModelFactory = class {
async match(context) {
const obj = await context.peek('pkl');
const validate = (obj, name) => {
if (obj && obj.__class__ && obj.__class__.__module__ && obj.__class__.__name__) {
const key = `${obj.__class__.__module__}.${obj.__class__.__name__}`;
return key.startsWith(name);
}
return false;
};
const formats = [
{ name: 'sklearn.', format: 'sklearn' },
{ name: 'xgboost.sklearn.', format: 'sklearn' },
{ name: 'lightgbm.sklearn.', format: 'sklearn' },
{ name: 'scipy.', format: 'scipy' },
{ name: 'hmmlearn.', format: 'hmmlearn' }
];
for (const format of formats) {
if (validate(obj, format.name)) {
return context.set(format.format, obj);
}
if (Array.isArray(obj) && obj.length > 0 && obj.every((item) => validate(item, format.name))) {
return context.set(`${format.format}.list`, obj);
}
if (Object(obj) === obj || obj instanceof Map) {
const entries = obj instanceof Map ? Array.from(obj) : Object.entries(obj);
if (entries.length > 0 && entries.every(([, value]) => validate(value, format.name))) {
return context.set(`${format.format}.map`, obj);
}
}
}
return null;
}
async open(context) {
const metadata = await context.metadata('sklearn-metadata.json');
return new sklearn.Model(metadata, context.type, context.value);
}
};
sklearn.Model = class {
constructor(metadata, type, obj) {
const formats = new Map([
['sklearn', 'scikit-learn'],
['scipy', 'SciPy'],
['hmmlearn', 'hmmlearn']
]);
this.format = formats.get(type.split('.').shift());
this.modules = [];
const version = [];
switch (type) {
case 'sklearn':
case 'scipy':
case 'hmmlearn': {
if (obj._sklearn_version) {
version.push(` v${obj._sklearn_version}`);
}
this.modules.push(new sklearn.Module(metadata, '', obj));
break;
}
case 'sklearn.list':
case 'scipy.list': {
const list = obj;
for (let i = 0; i < list.length; i++) {
const obj = list[i];
this.modules.push(new sklearn.Module(metadata, i.toString(), obj));
if (obj._sklearn_version) {
version.push(` v${obj._sklearn_version}`);
}
}
break;
}
case 'sklearn.map':
case 'scipy.map': {
const entries = obj instanceof Map ? Array.from(obj) : Object.entries(obj);
for (const [name, value] of entries) {
this.modules.push(new sklearn.Module(metadata, name, value));
if (value._sklearn_version) {
version.push(` v${value._sklearn_version}`);
}
}
break;
}
default: {
throw new sklearn.Error(`Unsupported scikit-learn format '${type}'.`);
}
}
if (version.length > 0 && version.every((value) => value === version[0])) {
this.format += version[0];
}
}
};
sklearn.Module = class {
constructor(metadata, name = '', obj = null) {
this.name = name;
this.nodes = [];
this.inputs = [];
this.outputs = [];
const node = new sklearn.Node(metadata, '', obj);
this.nodes.push(node);
}
};
sklearn.Argument = class {
constructor(name, value, type = null, visible = true) {
this.name = name;
this.value = value;
this.type = type;
this.visible = visible;
}
};
sklearn.Value = class {
constructor(name, type, initializer = null) {
if (typeof name !== 'string') {
throw new sklearn.Error(`Invalid value identifier '${JSON.stringify(name)}'.`);
}
this.name = name;
this.type = initializer ? initializer.type : type;
this.initializer = initializer;
}
};
sklearn.Node = class {
constructor(metadata, name, obj, stack) {
this.name = name || '';
const type = obj.__class__ ? `${obj.__class__.__module__}.${obj.__class__.__name__}` : 'builtins.dict';
this.type = metadata.type(type) || { name: type };
this.inputs = [];
this.outputs = [];
const isObject = (obj) => {
if (obj && typeof obj === 'object') {
const proto = Object.getPrototypeOf(obj);
return proto === Object.prototype || proto === null;
}
return false;
};
if (type === 'builtins.bytearray') {
const attribute = new sklearn.Argument('value', Array.from(obj), 'byte[]');
this.inputs.push(attribute);
} else {
const entries = Object.entries(obj);
for (const [name, value] of entries) {
if (name === '__class__') {
continue;
} else if (value && sklearn.Utility.isTensor(value)) {
const tensor = new sklearn.Tensor(value);
const argument = new sklearn.Argument(name, tensor, 'tensor');
this.inputs.push(argument);
} else if (Array.isArray(value) && value.length > 0 && value.every((obj) => sklearn.Utility.isTensor(obj))) {
const tensors = value.map((obj) => new sklearn.Tensor(obj));
const argument = new sklearn.Argument(name, tensors, 'tensor[]');
this.inputs.push(argument);
} else if (sklearn.Utility.isType(value, 'builtins.bytearray')) {
const argument = new sklearn.Argument(name, Array.from(value), 'byte[]');
this.inputs.push(argument);
} else {
stack = stack || new Set();
if (value && Array.isArray(value) && value.every((obj) => typeof obj === 'string')) {
const argument = new sklearn.Argument(name, value, 'string[]');
this.inputs.push(argument);
} else if (value && Array.isArray(value) && value.every((obj) => typeof obj === 'number')) {
const argument = new sklearn.Argument(name, value, 'attribute');
this.inputs.push(argument);
} else if (sklearn.Utility.isType(value, 'builtins.function') || sklearn.Utility.isType(value, 'builtins.type')) {
const node = new sklearn.Node(metadata, '', { __class__: value }, stack);
const argument = new sklearn.Argument(name, node, 'object');
this.inputs.push(argument);
} else if (sklearn.Utility.isType(value, 'builtins.list') && value.every((value) => Array.isArray(value) && value.length === 2 && typeof value[0] === 'string')) {
const chain = stack;
const nodes = value.map(([name, value]) => {
chain.add(value);
const node = new sklearn.Node(metadata, name, value, chain);
chain.delete(value);
return node;
});
const argument = new sklearn.Argument(name, nodes, 'object[]');
this.inputs.push(argument);
} else if (value && Array.isArray(value) && value.length > 0 && value.every((obj) => obj && (obj.__class__ || obj === Object(obj)))) {
const chain = stack;
const values = value.filter((value) => !chain.has(value));
const nodes = values.map((value) => {
chain.add(value);
const node = new sklearn.Node(metadata, '', value, null, chain);
chain.delete(value);
return node;
});
const argument = new sklearn.Argument(name, nodes, 'object[]');
this.inputs.push(argument);
} else if (value && (value.__class__ || isObject(value)) && !stack.has(value)) {
stack.add(value);
const node = new sklearn.Node(metadata, '', value, null, stack);
const argument = new sklearn.Argument(name, node, 'object');
this.inputs.push(argument);
stack.delete(value);
} else {
let type = 'attribute';
let visible = true;
const schema = metadata.attribute(type, name);
if (schema) {
if (schema.type) {
type = schema.type;
}
if (schema.visible === false || (schema.optional && value === null)) {
visible = false;
} else if (schema.default !== undefined) {
if (Array.isArray(value)) {
if (Array.isArray(schema.default)) {
visible = value.length !== schema.default || !value.every((item, index) => item === metadata.default[index]);
} else {
visible = !value.every((item) => item === schema.default);
}
} else {
visible = value !== schema.default;
}
}
}
const argument = new sklearn.Argument(name, value, type, visible);
this.inputs.push(argument);
}
}
}
}
}
};
sklearn.Tensor = class {
constructor(array) {
this.type = new sklearn.TensorType(array.dtype.__name__, new sklearn.TensorShape(array.shape));
this.stride = Array.isArray(array.strides) ? array.strides.map((stride) => stride / array.itemsize) : null;
this.encoding = this.type.dataType === 'string' || this.type.dataType === 'object' ? '|' : array.dtype.byteorder;
this.values = this.type.dataType === 'string' || this.type.dataType === 'object' || this.type.dataType === 'void' ? array.flatten().tolist() : array.tobytes();
}
};
sklearn.TensorType = class {
constructor(dataType, shape) {
this.dataType = dataType;
this.shape = shape;
}
toString() {
return this.dataType + this.shape.toString();
}
};
sklearn.TensorShape = class {
constructor(dimensions) {
this.dimensions = dimensions;
}
toString() {
return this.dimensions ? (`[${this.dimensions.map((dimension) => dimension.toString()).join(',')}]`) : '';
}
};
sklearn.Utility = class {
static isType(obj, name) {
return obj && obj.__class__ && obj.__class__.__module__ && obj.__class__.__name__ && `${obj.__class__.__module__}.${obj.__class__.__name__}` === name;
}
static isTensor = (obj) => {
return sklearn.Utility.isType(obj, 'numpy.ndarray') || sklearn.Utility.isType(obj, 'numpy.matrix');
};
};
sklearn.Error = class extends Error {
constructor(message) {
super(message);
this.name = 'Error loading scikit-learn model.';
}
};
export const ModelFactory = sklearn.ModelFactory;