public static void main (String[] args) {
		new Classifier(args);
		
		try{
			File infpath = new File(infroot);
			File charVecFile = new File(infroot, infpath.getName() + ".char_vec.csv"); //infrootɂsummarizedResult̂fBNgw
			File resFile = new File(infroot, infpath.getName() + ".models." + cluster + ".csv");
			
			int vecLen = 1 + 4*ref;
			
			InputStreamReader isr = new InputStreamReader(new FileInputStream(charVecFile));
			BufferedReader br = new BufferedReader(isr);
			
			ArrayList<double[]> charVecList = new ArrayList<double[]>();		
			String line = br.readLine(); //擪s			
			while((line = br.readLine()) != null) {
				StringTokenizer st = new StringTokenizer(line, ",");
				st.nextToken();
				int index = 0;
				double[] tmpCharVec = new double[vecLen];
				while(st.hasMoreTokens()){
					tmpCharVec[index] = Double.parseDouble(st.nextToken());
					index++;
				}
				charVecList.add(tmpCharVec);
			}
			br.close();
			isr.close();
			
			double[][] charVec = new double[charVecList.size()][vecLen];
			for(int i = 0; i<charVecList.size(); i++) {
				charVec[i] = charVecList.get(i);
			}
			int size = charVec.length;
			
			double[] vecMeans = new double[vecLen];
			double[] vecDevs = new double[vecLen];
			double[][] charVecNorm = new double[size][vecLen];
			for(int j = 0; j<vecLen; j++) {
				for(int i = 0; i<size; i++) {
					vecMeans[j] += charVec[i][j];
				}
			}
			for(int j = 0; j<vecLen; j++) vecMeans[j] /= size;
			for(int j = 0; j<vecLen; j++) {
				for(int i = 0; i<size; i++) {
					double gap = charVec[i][j] - vecMeans[j];
					vecDevs[j] += Math.sqrt(gap*gap);
				}
			}
			for(int j = 0; j<vecLen; j++) vecDevs[j] /= size;
			
			double[] charVecNormMax = new double[vecLen];
			double[] charVecNormMin = new double[vecLen];
			for(int j = 0; j<vecLen; j++) {
				charVecNormMax[j] = 0.0;
				charVecNormMin[j] = Double.MAX_VALUE;
			}
			for(int j = 0; j<vecLen; j++) {
				for(int i = 0; i<size; i++) {
					charVecNorm[i][j] = (charVec[i][j] - vecMeans[j]) / vecDevs[j];
					if (charVecNorm[i][j] > charVecNormMax[j]) charVecNormMax[j] = charVecNorm[i][j];
					if (charVecNorm[i][j] < charVecNormMin[j]) charVecNormMin[j] = charVecNorm[i][j];
				}
			}
			
			double[][] classifiedModels = new double[cluster][vecLen];
			int[] clusterIndex = new int[size];
			clusterIndex = kmeans(cluster, charVecNorm, charVecNormMax, charVecNormMin, maxIter);
			
			//cluserIndexclassifiedModelsiNX^dSjo
			int[] dataNum = new int[cluster];
			for(int k=0; k<cluster; k++) {
				for(int j=0; j<vecLen; j++) {
					classifiedModels[k][j] = 0.0;
				}
			}
			for(int i=0; i<size; i++) {
				int index = clusterIndex[i];
				for(int j=0; j<vecLen; j++) {
					classifiedModels[index][j] += charVecNorm[i][j];
				}
				dataNum[index]++;
			}
			for(int k=0; k<cluster; k++) {
				for(int j=0; j<vecLen; j++) {
					classifiedModels[k][j] /= dataNum[k];
				}
			}
			
			for(int k=0; k<cluster; k++) {
				for(int j=0; j<vecLen; j++) {
					classifiedModels[k][j] = classifiedModels[k][j] * vecDevs[j] + vecMeans[j];
				}
			}
			
			//output
			resultPlotter(resFile, dataNum, classifiedModels);
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}