forked from sheetjs/docs.sheetjs.com
		
	
		
			
	
	
		
			69 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			69 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 
								 | 
							
								const XLSX = require('xlsx');
							 | 
						||
| 
								 | 
							
								const tf = require("@tensorflow/tfjs");
							 | 
						||
| 
								 | 
							
								//const tf = require("@tensorflow/tfjs-node");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function worksheet_to_csv_url(worksheet) {
							 | 
						||
| 
								 | 
							
								  /* generate CSV */
							 | 
						||
| 
								 | 
							
								  const csv = XLSX.utils.sheet_to_csv(worksheet);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* CSV -> Uint8Array -> Blob */
							 | 
						||
| 
								 | 
							
								  const u8 = new TextEncoder().encode(csv);
							 | 
						||
| 
								 | 
							
								  const blob = new Blob([u8], { type: "text/csv" });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* generate a blob URL */
							 | 
						||
| 
								 | 
							
								  return URL.createObjectURL(blob);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(async() => { try {
							 | 
						||
| 
								 | 
							
								  /* fetch file */
							 | 
						||
| 
								 | 
							
								  const f = await fetch("https://docs.sheetjs.com/cd.xls");
							 | 
						||
| 
								 | 
							
								  const ab = await f.arrayBuffer();
							 | 
						||
| 
								 | 
							
								  /* parse file and get first worksheet */
							 | 
						||
| 
								 | 
							
								  const wb = XLSX.read(ab);
							 | 
						||
| 
								 | 
							
								  const ws = wb.Sheets[wb.SheetNames[0]];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* generate blob URL */
							 | 
						||
| 
								 | 
							
								  const url = worksheet_to_csv_url(ws);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* feed to tf.js */
							 | 
						||
| 
								 | 
							
								  const dataset = tf.data.csv(url, {
							 | 
						||
| 
								 | 
							
								    hasHeader: true,
							 | 
						||
| 
								 | 
							
								    configuredColumnsOnly: true,
							 | 
						||
| 
								 | 
							
								    columnConfigs:{
							 | 
						||
| 
								 | 
							
								      "Horsepower": {required: false, default: 0},
							 | 
						||
| 
								 | 
							
								      "Miles_per_Gallon":{required: false, default: 0, isLabel:true}
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* pre-process data */
							 | 
						||
| 
								 | 
							
								  let flat = dataset
							 | 
						||
| 
								 | 
							
								    .map(({xs,ys}) =>({xs: Object.values(xs), ys: Object.values(ys)}))
							 | 
						||
| 
								 | 
							
								    .filter(({xs,ys}) => [...xs,...ys].every(v => v>0));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* normalize manually :( */
							 | 
						||
| 
								 | 
							
								  let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
							 | 
						||
| 
								 | 
							
								  await flat.forEachAsync(({xs, ys}) => {
							 | 
						||
| 
								 | 
							
								    minX = Math.min(minX, xs[0]); maxX = Math.max(maxX, xs[0]);
							 | 
						||
| 
								 | 
							
								    minY = Math.min(minY, ys[0]); maxY = Math.max(maxY, ys[0]);
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								  flat = flat.map(({xs, ys}) => ({xs:xs.map(v => (v-minX)/(maxX - minX)),ys:ys.map(v => (v-minY)/(maxY-minY))}));
							 | 
						||
| 
								 | 
							
								  flat = flat.batch(32);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* build and train model */
							 | 
						||
| 
								 | 
							
								  const model = tf.sequential();
							 | 
						||
| 
								 | 
							
								  model.add(tf.layers.dense({inputShape: [1], units: 1}));
							 | 
						||
| 
								 | 
							
								  model.compile({ optimizer: tf.train.sgd(0.000001), loss: 'meanSquaredError' });
							 | 
						||
| 
								 | 
							
								  await model.fitDataset(flat, { epochs: 100, callbacks: { onEpochEnd: async (epoch, logs) => {
							 | 
						||
| 
								 | 
							
								    console.error(`${epoch}:${logs.loss}`);
							 | 
						||
| 
								 | 
							
								  }}});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* predict values */
							 | 
						||
| 
								 | 
							
								  const inp = tf.linspace(0, 1, 9);
							 | 
						||
| 
								 | 
							
								  const pred = model.predict(inp);
							 | 
						||
| 
								 | 
							
								  const xs = await inp.dataSync(), ys = await pred.dataSync();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (let i=0; i<xs.length; ++i) {
							 | 
						||
| 
								 | 
							
								    console.log([xs[i] * (maxX - minX) + minX, ys[i] * (maxY - minY) + minY].join(" "));
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								} catch(e) { console.error(`ERROR: ${String(e)}`); }})();
							 |