正文之前
因?yàn)椴粩嗟臄U(kuò)充了輔助類再扭,所以改進(jìn)了下腳本,沒有原先那么巨細(xì)夜矗,但是感覺好了不少泛范。我在想要不要下次直接開一個文件來記錄上次更新的文件以及時間。然后再寫一個Java或者Python的程序來自動輸出要上傳的文件名字紊撕?感覺是個大工程“盏矗現(xiàn)在還可以,以后再說吧对扶!
正文
echo "OK!NOW I WILL UPLOAD YOUR CHANGE TO GITHUB!"
time=$(date "+%Y-%m-%d %H:%M")
echo "${time}"
cd /Users/zhangzhaobo/Documents/Graduation-Design/
sudo cp -a /Users/zhangzhaobo/IdeaProjects/Graduation_Design/src/ReadData.* /Users/zhangzhaobo/Documents/Graduation-Design/
sudo cp -a /Users/zhangzhaobo/IdeaProjects/Graduation_Design/src/ZZB_JCS.* /Users/zhangzhaobo/Documents/Graduation-Design/
sudo cp -a /Users/zhangzhaobo/IdeaProjects/Graduation_Design/src/data.txt /Users/zhangzhaobo/Documents/Graduation-Design/data.txt
sudo cp -a /Users/zhangzhaobo/IdeaProjects/Graduation_Design/src/Mysql* /Users/zhangzhaobo/Documents/Graduation-Design/
sudo cp -a /Users/zhangzhaobo/IdeaProjects/Graduation_Design/mysql* /Users/zhangzhaobo/Documents/Graduation-Design/
sudo javac /Users/zhangzhaobo/Documents/Graduation-Design/ReadData.java
sudo javac /Users/zhangzhaobo/Documents/Graduation-Design/ZZB_JCS.java
git add ReadData.* ZZB_JCS.* data.txt Mysql*
git commit -m "$time $1"
git push origin master
別的就不說了区赵,先把數(shù)據(jù)讀寫的程序丟出來。這個數(shù)據(jù)讀寫其實(shí)我是想要到時候如果有人給我一個文本浪南,那就GG惧笛,所以還要看看讀文本存進(jìn)數(shù)據(jù)庫咋搞!另外逞泄!有沒有人能告訴我患整!去哪兒找機(jī)械設(shè)備的運(yùn)行數(shù)據(jù)鞍菪А!8餮琛紧憾!我很苦惱啊啊昌渤!
數(shù)據(jù)庫連接程序
//*************************** 數(shù)據(jù)庫連接程序 ***************************
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class Mysql_Connect {
//此處查看網(wǎng)絡(luò)才知道赴穗。要求SSL,所以就醬紫咯:https://zhidao.baidu.com/question/2056521203295428667.html
private static String url = "jdbc:mysql://127.0.0.1:3306/Graduation_Design?useUnicode=true&characterEncoding=GBK&useSSL=true";
private static String user = "root";
private static String password = "zzb1184827350";
private static String Database="192.168.2.127:3306/Graduation_Design";
private Statement statement;
private Connection conn;
public void setUser(String user){
this.user=user;
}
public void setPassword(String p){
this.password=p;
}
public void setDatabase(String database){
this.Database=database;
this.url="jdbc:mysql:/"+Database+"?useUnicode=true&characterEncoding=GBK&useSSL=true";
}
public void setDatabase(){
this.url="jdbc:mysql:/192.168.2.127:3306/Shop_User?useUnicode=true&characterEncoding=GBK&useSSL=true";
}
public Statement getStatement() {
return this.statement;
}
public void Connect() {
try {
String driver = "com.mysql.jdbc.Driver";
Class.forName(driver);
conn = DriverManager.getConnection(url, user, password);
if (!conn.isClosed()){
}
else {
System.out.println("\n\nFailed to connect to the Database!");
}
this.statement = conn.createStatement();
} catch (ClassNotFoundException e) {
System.out.println("Sorry,can`t find the Driver!");
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
public void Dis_Connect() throws SQLException {
try {
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
數(shù)據(jù)庫讀寫程序膀息!
//*************************** 數(shù)據(jù)庫讀寫程序 ***************************
/* *********************
* Author : HustWolf --- 張照博
* Time : 2018.3-2018.5
* Address : HUST
* Version : 3.0
********************* */
/* *******************
* 這是從數(shù)據(jù)庫或者是文本文件讀取數(shù)據(jù)的時候用的
* 其實(shí)我覺得如果可以每一次讀一條數(shù)據(jù)般眉,然后處理一條會比較好
* 但是算了,數(shù)據(jù)量不大的話潜支,這個樣子也不會增加太多時間的甸赃!
******************* */
import java.io.*;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class ReadData {
protected Mysql_Connect mysql=new Mysql_Connect();
public void writeToDatabase(int id,Object[] data_array) {
try {
mysql.Connect();
Statement statement=mysql.getStatement();
String INSERT = "INSERT INTO watermelon(id,色澤,根蒂,敲聲,紋理,臍部,觸感,category) VALUES( " + id + " , ' " + data_array[0] + "' , ' " + data_array[1] + "' , ' " + data_array[2] + "' , ' " + data_array[3] + "' , ' " + data_array[4] + "' , ' " + data_array[5] + " ', ' " + data_array[6] + "' )";
boolean insert_ok = statement.execute(INSERT);
if (insert_ok) {
System.out.println("Insert Success!");
}
statement.close();
mysql.Dis_Connect();
} catch (SQLException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
public Object[] readFromDatabase(int id) {
Object[] DataToOut = new Object[7];
try {
mysql.Connect();
Statement statement=mysql.getStatement();
String GETDATA = "SELECT 色澤,根蒂,敲聲,紋理,臍部,觸感,category FROM watermelon WHERE id="+id;
ResultSet select_ok = statement.executeQuery(GETDATA);
if(select_ok.next()) {
DataToOut[0]=select_ok.getObject("色澤");
DataToOut[1]=select_ok.getObject("根蒂");
DataToOut[2]=select_ok.getObject("敲聲");
DataToOut[3]=select_ok.getObject("紋理");
DataToOut[4]=select_ok.getObject("臍部");
DataToOut[5]=select_ok.getObject("觸感");
DataToOut[6]=select_ok.getObject("category");
}
statement.close();
mysql.Dis_Connect();
} catch (SQLException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return DataToOut;
}
public Object[][] ReadData() throws IOException {
Object[][] rawData = new Object [][]{
{"青綠","蜷縮","濁響","清晰","凹陷","硬滑","是"},
{"烏黑","蜷縮","沉悶","清晰","凹陷","硬滑","是"},
{"烏黑","蜷縮","濁響","清晰","凹陷","硬滑","是"},
{"青綠","蜷縮","沉悶","清晰","凹陷","硬滑","是"},
{"淺白","蜷縮","濁響","清晰","凹陷","硬滑","是"},
{"青綠","稍蜷","濁響","清晰","稍凹","軟粘","是"},
{"烏黑","稍蜷","濁響","稍糊","稍凹","軟粘","是"},
{"烏黑","稍蜷","濁響","清晰","稍凹","硬滑","是"},
{"烏黑","稍蜷","沉悶","稍糊","稍凹","硬滑","否"},
{"青綠","硬挺","清脆","清晰","平坦","軟粘","否"},
{"淺白","硬挺","清脆","模糊","平坦","硬滑","否"},
{"淺白","蜷縮","濁響","模糊","平坦","軟粘","否"},
{"青綠","稍蜷","濁響","稍糊","凹陷","硬滑","否"},
{"淺白","稍蜷","沉悶","稍糊","凹陷","硬滑","否"},
{"烏黑","稍蜷","濁響","清晰","稍凹","軟粘","否"},
{"淺白","蜷縮","濁響","模糊","平坦","硬滑","否"},
{"青綠","蜷縮","沉悶","稍糊","稍凹","硬滑","否"},
// { "<30 ", "High ", "No ", "Fair ", "0" },
// { "<30 ", "High ", "No ", "Excellent", "0" },
// { "30-40", "High ", "No ", "Fair ", "1" },
// { ">40 ", "Medium", "No ", "Fair ", "1" },
// { ">40 ", "Low ", "Yes", "Fair ", "1" },
// { ">40 ", "Low ", "Yes", "Excellent", "0" },
// { "30-40", "Low ", "Yes", "Excellent", "1" },
// { "<30 ", "Medium", "No ", "Fair ", "0" },
// { "<30 ", "Low ", "Yes", "Fair ", "1" },
// { ">40 ", "Medium", "Yes", "Fair ", "1" },
// { "<30 ", "Medium", "Yes", "Excellent", "1" },
// { "30-40", "Medium", "No ", "Excellent", "1" },
// { "30-40", "High ", "Yes", "Fair ", "1" },
// { "<30 " , "Medium", "No ", "Excellent", "1" },
// { ">40 ", "Medium", "No ", "Excellent", "0" }
};
// ***************** 寫入文件式 **************
// File file = new File("data.txt"); //存放數(shù)組數(shù)據(jù)的文件
//
// FileWriter DataToTXT = new FileWriter(file); //文件寫入流
// int row=0;
// //將數(shù)組中的數(shù)據(jù)寫入到文件中。每行各數(shù)據(jù)之間TAB間隔
// for(int i=0;i<rawData.length;i++){
// for(int j=0;j<rawData[0].length;j++){
// DataToTXT.write(rawData[i][j]+"\t");
// }
// row++;
// DataToTXT.write("\r\n");
// }
// DataToTXT.close();
//
// BufferedReader in = new BufferedReader(new FileReader(file));
// String line; //一行數(shù)據(jù)
// //逐行讀取冗酿,并將每個數(shù)組放入到數(shù)組中
// Object[][] DataToOut = new Object[row][7];
// int readrow=0;
// while((line = in.readLine()) != null){
// String[] temp = line.split("\t");
// for(int j=0;j<temp.length;j++){
// DataToOut[readrow][j] = temp[j];
// }
// readrow++;
// }
// in.close();
//顯示讀取出的數(shù)組
// for(int i=0;i<DataToOut.length;i++){
// for(int j=0;j<DataToOut[0].length;j++){
// System.out.print(DataToOut[i][j]+"\t");
// }
// System.out.println();
// }
// ***************** 寫入文件式 **************
// ***************** 數(shù)據(jù)庫讀寫式 **************
int row=0;
try {
mysql.Connect();
Statement statement=mysql.getStatement();
String DELETE="delete from watermelon where id<1000";
boolean delete_ok=statement.execute(DELETE);
if (delete_ok){
System.out.println("Have Fun! Boys!\n\n");
}
statement.close();
mysql.Dis_Connect();
} catch (SQLException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
for(int i=0;i<rawData.length;i++){
writeToDatabase(row,rawData[i]);
row++;
}
Object[][] DataToOut = new Object[row][7];
for (int i=0;i<DataToOut.length;++i){
DataToOut[i]=readFromDatabase(i);
}
// ***************** 數(shù)據(jù)庫讀寫式 **************
return DataToOut;
}
}
最大頭埠对!決策樹生成程序!
主要是照搬的網(wǎng)上的啦裁替!后面再自己慢慢適合的吧项玛!大神寫的很棒啊啊弱判!
/* *********************
* Author : HustWolf --- 張照博
* Time : 2018.3-2018.5
* Address : HUST
* Version : 1.0
********************* */
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
//最外層類名
public class ZZB_JCS{
/* *********************
* Define the Class of Sample
* it is about its nature and function
********************* */
static class Sample{
//attributes means 屬性
private Map<String,Object> attributes = new HashMap<String,Object>();
//category means 類別
private Object category;
public Object getAttribute(String name){
return attributes.get(name);
}
public void setAttribute(String name,Object value){
attributes.put(name,value);
}
public void setCategory(Object category){
this.category=category;
}
public String toString(){
return attributes.toString();
}
}
/* *********************
* this is the function to read the sample
* just like decoding the data
********************* */
// 此處需要改造為讀取外部數(shù)據(jù)襟沮!并且能夠進(jìn)行分解,改造為可讀取的形式
static Map<Object,List<Sample>> readSample(String[] attribute_Names) throws IOException {
//樣本屬性及其分類昌腰,暫時先在代碼里面寫了臣嚣。后面需要數(shù)據(jù)庫或者是文件讀取
ReadData data = new ReadData();
Object[][] rawData = data.ReadData();
//最終組合出一個包含所有的樣本的Map
Map<Object,List<Sample>> sample_set = new HashMap<Object,List<Sample>>();
//讀取每一排的數(shù)據(jù)
//分解后讀取樣本屬性及其分類,然后利用這些數(shù)據(jù)構(gòu)造一個Sample對象
//然后按照樣本最后的0剥哑,1進(jìn)行二分類劃分樣本集,
for (Object[] row:rawData) {
//新建一個Sample對象淹父,沒處理一次加入Map中株婴,最后一起返回
Sample sample = new Sample();
int i=0;
//每次處理一排數(shù)據(jù),構(gòu)成一個樣本中各項(xiàng)屬性的值
for (int n=row.length-1; i<n; ++i) {
sample.setAttribute(attribute_Names[i],row[i]);
}
//為處理完的一個樣本進(jìn)行分類暑认,根據(jù)0困介,1來,此時i已經(jīng)在最后一位
sample.setCategory(row[i]);
//將解析出來的一排加入整體分類后的樣本中蘸际,row[i]此刻是指分類后的集合
List<Sample> samples = sample_set.get(row[i]);
//現(xiàn)在整體樣本集中查詢座哩,有的話就返回value,而如果這個類別還沒有樣本粮彤,那么就添加一下
if(samples == null){
samples = new LinkedList<Sample>();
sample_set.put(row[i],samples);
}
//不管是當(dāng)前分類的樣本集中是否為空根穷,都要加上把現(xiàn)在分離出來的樣本丟進(jìn)去姜骡。
//此處基本只有前幾次分類沒有完畢的時候才會進(jìn)入if,后面各個分類都有了樣本就不會為空了屿良。
samples.add(sample);
}
//最后返回的是一個每一個類別一個鏈表的Map圈澈,串著該類別的所有樣本 (類別 --> 此類樣本)
return sample_set;
}
/* *********************
* this is the class of the decision-tree
* 決策樹(非葉結(jié)點(diǎn)),決策樹中的每個非葉結(jié)點(diǎn)都引導(dǎo)了一棵決策樹
* 每個非葉結(jié)點(diǎn)包含一個分支屬性和多個分支尘惧,分支屬性的每個值對應(yīng)一個分支康栈,該分支引導(dǎo)了一棵子決策樹
********************* */
static class Tree{
private String attribute;
private Map<Object,Object> children = new HashMap<Object,Object>();
public Tree(String attribute){
this.attribute=attribute;
}
public String getAttribute(){
return attribute;
}
public Object getChild(Object attrValue){
return children.get(attrValue);
}
public void setChild(Object attrValue,Object child){
children.put(attrValue,child);
}
public Set<Object> getAttributeValues(){
return children.keySet();
}
}
/* *********************
* this is the function to choose the Best Test Attribute
* it will be used in the generateDecisionTree()
* 選取最優(yōu)測試屬性。最優(yōu)是指如果根據(jù)選取的測試屬性分支喷橙,則從各分支確定新樣本
* 的分類需要的信息熵之和最小啥么,這等價于確定新樣本的測試屬性獲得的信息增益最大
* 返回數(shù)組:選取的屬性下標(biāo)、信息熵之和贰逾、Map(屬性值->(分類->樣本列表))
********************* */
static Object[] chooseBestTestAttribute(Map<Object,List<Sample>> categoryToSamples,String[] attribute_Names){
//最優(yōu)的屬性的下標(biāo)悬荣!
int minIndex = -1;
//最小的信息熵
double minValue = Double.MAX_VALUE;
//最優(yōu)的分支方案!
Map<Object,Map<Object,List<Sample>>> minSplit = null;
//對每一個屬性似踱,都要計算信息熵隅熙,選區(qū)最小的為最優(yōu),Ent(D)
for (int attrIndex = 0;attrIndex<attribute_Names.length;++attrIndex) {
//統(tǒng)計樣本總數(shù)的計數(shù)器
int allCount = 0;
//按照當(dāng)前屬性構(gòu)建Map核芽,這個Map的層級關(guān)系根據(jù)下面的層次劃分:屬性值[Key]->(分類[Key]->樣本列表[Value]) [Value]
// curSplits就是一個某一個在當(dāng)前屬性下某一種選擇值 所對應(yīng)的所有樣本集囚戚! 所有的Dv的集合是也?轧简?待定驰坊!
Map<Object,Map<Object,List<Sample>>> curSplits = new HashMap<Object,Map<Object,List<Sample>>>();
/* 這兒的整個流程畫個圖哈~下面是對某一個屬性進(jìn)行信息增益的計算了!
拿到一個數(shù)據(jù)對哮独,【所屬類別-->樣本集】
|
V
解析數(shù)據(jù)對拳芙,分解出key和value
其中key為類別,value為此類別所有的樣本
|
V
對于Value里邊讀出來的每個樣本皮璧,分別:
讀取當(dāng)前屬性下的值舟扎,然后建立起來當(dāng)前屬性值相同的所有樣本的樣本集;
|
V
此處還要將每個樣本集拆分為分類樣本集悴务!
|
V
這一輪下來睹限,就得到關(guān)于這個屬性的不同屬性值對應(yīng)的樣本集合
而在這些集合集合中又有分類樣本集!
就好比讯檐,這一輪對年齡下手羡疗,最終得到了40歲以上的好人、壞人
30-40歲之間的好人别洪、壞人集合
30歲以下的好人叨恨、壞人的集合
最后一共得到了6個樣本集?
只不過是已Map中鍵值對的形式存在挖垛,二層包裝而已痒钝!
--正分類--> 一個Map
---屬性值1秉颗,比如是學(xué)生 ->分類兩類 |
某一屬性(這個就是curSplits這個Map的本體) --負(fù)分類--> 一個Map(此處畫圖方便重用了!)
---屬性值2午乓,比如不是學(xué)生->分類兩類 |
--正分類--> 一個Map
*/
/*
* Set<Map.Entry<K,V>> entrySet?()
* Returns: A set view of the mappings contained in this map
* Entry 這個數(shù)據(jù)類型大致等于C++中的pair站宗,也就是數(shù)據(jù)打包的意思
*/
for (Entry<Object,List<Sample>> entry : categoryToSamples.entrySet()) {
//先拿到數(shù)據(jù)的分類的名稱,我們這兒就0益愈,1
Object category = entry.getKey();
//再拿到這個類別梢灭!注意是類別,不是屬性值蒸其!類別所對應(yīng)的所有樣本敏释!
List<Sample> samples = entry.getValue();
//然后再慢慢的對每個樣本進(jìn)行操作,將其分為按照屬性值劃分的各種Dv摸袁,然后返回到curSplits
for (Sample sample : samples ) {
// 根據(jù)當(dāng)前要計算的屬性钥顽,得到當(dāng)前樣本的關(guān)于這個屬性的值
Object attrValue = sample.getAttribute(attribute_Names[attrIndex]);
// 根據(jù)前面當(dāng)前樣本getAttribute()所獲得的屬性值,來獲取這個屬性的值相同的所有的樣本的樣本集
Map<Object,List<Sample>> split = curSplits.get(attrValue);
// 考慮到一開始肯定沒法得到一個完整的Map,所以需要從無到有建立起來靠汁!
if (split == null) {
//建立一個關(guān)于這個屬性值的Map蜂大,層次關(guān)系為:屬性值->(All Sample) 見Line156
split = new HashMap<Object,List<Sample>>();
curSplits.put(attrValue,split);
}
//建立起來之后,就可以讀取這個屬性值等于某個值時對應(yīng)的分類樣本集合了蝶怔。
List<Sample> splitSamples = split.get(category);
// 如果讀不到當(dāng)前屬性對應(yīng)這個值的分類的話奶浦,那就要建立一個屬性值等于當(dāng)前樣本的屬性值,且分類相同的樣本集踢星。
if (splitSamples == null) {
splitSamples = new LinkedList<Sample>();
// 結(jié)合當(dāng)前這個屬性值澳叉,組成一個集合,放到Map--split里面去沐悦。
split.put(category,splitSamples);
}
// 最后再把當(dāng)前的這個樣本放到這個樣本集中成洗??藏否?F垦辍!可以直接這么搞的副签?%%%%%% 難道是引用傳遞遥椿?
// 是的!沒有用new自然就是一個引用傳遞继薛!臥槽!這都給忘了S薄遏考?
splitSamples.add(sample);
}
//統(tǒng)計樣本總數(shù)的計數(shù)器需要對當(dāng)前屬性下的樣本的數(shù)量進(jìn)行統(tǒng)計。
allCount += samples.size();
}
// 當(dāng)前屬性值的信息增益寄存器
double curValue = 0.0;
//讀取當(dāng)前屬性下的每一種屬性值對應(yīng)的樣本集
for (Map<Object,List<Sample>> splits : curSplits.values()) {
double perSplitCount = 0;
//讀取每個屬性值的樣本集Dv的size蓝谨,得到所有該屬性為此值的樣本總數(shù)灌具,不論類別如何
for (List<Sample> list : splits.values()) {
//累計當(dāng)前樣本的分支總數(shù)
perSplitCount += list.size();
}
//計數(shù)器青团,當(dāng)前分支的信息熵和信息增益,這兒是按出現(xiàn)頻率在算呢咖楣!
double perSplitValue = 0.0;
//計算每個屬性值對應(yīng)的信息熵
for (List<Sample> list : splits.values() ) {
//此處完全就是ID3算法的信息熵的計算公式督笆!也就是ENT(D) = -Sum(Pk*log2(Pk))見《機(jī)器學(xué)習(xí)》 P75
double p = list.size() / perSplitCount;
//貌似是因?yàn)閜無論如何都是小于1的,所以采用p -= 實(shí)際上是加了诱贿?
perSplitValue -= p*(Math.log(p)/Math.log(2));
}
//這應(yīng)該還算不上不是信息增益吧娃肿!只能算是信息熵之和了。
curValue += (perSplitCount / allCount) * perSplitValue;
}
//選擇最小的信息熵為最優(yōu)V槭料扰?
if (minValue > curValue){
minIndex = attrIndex;
minValue = curValue;
minSplit = curSplits;
}
}
//所以最終返回的就是一個信息熵之和 最小的屬性的列表索引 + 最小的信息熵之和 + 最小的信息熵之和所對應(yīng)的子樹!
return new Object[] {minIndex,minValue,minSplit};
}
/* *********************
* this is the function to output the Decision Tree to the Dashboard
********************* */
static void outputDecisionTree(Object obj,int level, Object from){
//這個到后面決定輸出多少個|----- 也就是說是決定層級的
for (int i=0; i < level ;++i){
System.out.print("|-----");
}
// 所有子節(jié)點(diǎn)專用焙蹭?除了根節(jié)點(diǎn)都要吧晒杈!
if (from != null){
System.out.printf("(%s):",from);
}
//大概是說,如果這個東西還有子節(jié)點(diǎn)孔厉,那就繼續(xù)遞歸
if (obj instanceof Tree){
Tree tree = (Tree) obj;
String attribute_Name = tree.getAttribute();
System.out.printf("[%s = ?]\n",attribute_Name);
for (Object attrValue : tree.getAttributeValues()){
Object child =tree.getChild(attrValue);
outputDecisionTree(child,level+1,attribute_Name + " = " + attrValue);
}
}else {
System.out.printf("【* CATEGORY = %s *】\n", obj);
}
}
/* *********************
* this is the function to generate the DecisionTree
* use the data which read from the files to get the Decisiontree
* the most important part I think!
********************* */
static Object generateDecisionTree(Map<Object,List<Sample>> categoryToSamples,String[] attribute_Names){
//如果只有一個樣本拯钻,那么該樣本所屬分類作為新樣本的分類
if(categoryToSamples.size() == 1)
return categoryToSamples.keySet().iterator().next();
//如果沒有提供決策的屬性(也就是沒有給你屬性名字清單),那么樣本集中具有最多樣本的分類作為新樣本的分類撰豺,也就是投票選舉出新的分類
if (attribute_Names.length == 0) {
int max = 0;
Object maxCategory = null;
// 如果沒有屬性列表的話粪般,那就直接按照分類作為K個樣本集,取數(shù)量較大的那個樣本集的類別作為本分類郑趁。
for (Entry<Object,List<Sample>> entry : categoryToSamples.entrySet() ) {
int cur = entry.getValue().size();
if (cur > max) {
max = cur;
maxCategory = entry.getKey();
}
}
return maxCategory;
}
//如果有屬性清單的話刊驴,那么就選擇測試所用的屬性了。
Object[] rst = chooseBestTestAttribute(categoryToSamples,attribute_Names);
//決策樹的根節(jié)點(diǎn)選取寡润,分支的屬性為選取的測試屬性
Tree tree = new Tree(attribute_Names[(Integer)rst[0]]);
//已用過的測試屬性不能再次被選擇為測試屬性
String[] Attr_Find_Already = new String[attribute_Names.length-1];
for (int i=0,j=0;i<attribute_Names.length ;++i ) {
if (i != (Integer)rst[0]) {
Attr_Find_Already[j++] = attribute_Names[i];
}
}
//根據(jù)分支的屬性生成新的分支
@SuppressWarnings("unchecked")
Map<Object,Map<Object,List<Sample>>> splits = (Map<Object,Map<Object,List<Sample>>>) rst[2];
for (Entry<Object,Map<Object,List<Sample>>> entry : splits.entrySet()) {
Object attrValue = entry.getKey();
Map<Object,List<Sample>> split = entry.getValue();
//又是遞歸調(diào)用捆憎?那我豈不是玩完?層數(shù)不能超過二十層梭纹!這是底線躲惰!
Object child = generateDecisionTree(split,Attr_Find_Already);
tree.setChild(attrValue,child);
}
return tree;
}
public static void main(String[] args) throws Exception{
// String[] attribute_Names = new String[] {"AGE","INCOME","STUDENT","CREDIT_RATING"};
String[] attribute_Names = new String[] {"色澤","根蒂","敲聲","紋理","臍部","觸感"};
//讀取樣本集
Map<Object,List<Sample>> samples = readSample(attribute_Names);
//生成決策樹
Object decisionTree = generateDecisionTree(samples,attribute_Names);
//輸出決策樹
outputDecisionTree(decisionTree,0,null);
}
}
另外要注意,這個因?yàn)橛玫搅藬?shù)據(jù)庫变抽,所以需要加載依賴文件包础拨!具體看這兒:
解決方案! https://blog.csdn.net/sakura_yuan/article/details/51730493
最后的結(jié)果簡直是美到爆炸绍载!好么诡宗??爆炸;骼堋塔沃!
/Library/Java/JavaVirtualMachines/jdk-9.0.1.jdk/Contents/Home/bin/java "-javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=57631:/Applications/IntelliJ IDEA.app/Contents/bin" -Dfile.encoding=UTF-8 -classpath /Users/zhangzhaobo/IdeaProjects/Graduation_Design/out/production/Graduation_Design:/Users/zhangzhaobo/IdeaProjects/Graduation_Design/mysql-connector-java-5.1.44-bin.jar ZZB_JCS
[紋理 = ?]
|-----(紋理 = 稍糊):[觸感 = ?]
|-----|-----(觸感 = 硬滑 ):【* CATEGORY = 否 *】
|-----|-----(觸感 = 軟粘 ):【* CATEGORY = 是 *】
|-----(紋理 = 模糊):【* CATEGORY = 否 *】
|-----(紋理 = 清晰):[根蒂 = ?]
|-----|-----(根蒂 = 硬挺):【* CATEGORY = 否 *】
|-----|-----(根蒂 = 蜷縮):【* CATEGORY = 是 *】
|-----|-----(根蒂 = 稍蜷):[色澤 = ?]
|-----|-----|-----(色澤 = 青綠):【* CATEGORY = 是 *】
|-----|-----|-----(色澤 = 烏黑):[觸感 = ?]
|-----|-----|-----|-----(觸感 = 硬滑 ):【* CATEGORY = 是 *】
|-----|-----|-----|-----(觸感 = 軟粘 ):【* CATEGORY = 否 *】
Process finished with exit code 0
正文之后
今天早起(八點(diǎn)半?)吃到了西邊百景園的早飯阳谍,油條和湯包蛀柴,雖然貴了點(diǎn)螃概,但是好吃啊鸽疾!希望以后天天有早飯吃吊洼!阿西吧!整完了制肮,吃午飯去冒窍!