【畢設(shè)進(jìn)行時-工業(yè)大數(shù)據(jù),數(shù)據(jù)挖掘】腳本改進(jìn)件相,JDBC數(shù)據(jù)庫讀寫

正文之前

因?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)螃概,但是好吃啊鸽疾!希望以后天天有早飯吃吊洼!阿西吧!整完了制肮,吃午飯去冒窍!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市弄企,隨后出現(xiàn)的幾起案子超燃,更是在濱河造成了極大的恐慌,老刑警劉巖拘领,帶你破解...
    沈念sama閱讀 218,451評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件意乓,死亡現(xiàn)場離奇詭異,居然都是意外死亡约素,警方通過查閱死者的電腦和手機(jī)届良,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來圣猎,“玉大人士葫,你說我怎么就攤上這事∷突冢” “怎么了慢显?”我有些...
    開封第一講書人閱讀 164,782評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長欠啤。 經(jīng)常有香客問我荚藻,道長,這世上最難降的妖魔是什么洁段? 我笑而不...
    開封第一講書人閱讀 58,709評論 1 294
  • 正文 為了忘掉前任应狱,我火速辦了婚禮,結(jié)果婚禮上祠丝,老公的妹妹穿的比我還像新娘疾呻。我一直安慰自己,他們只是感情好写半,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評論 6 392
  • 文/花漫 我一把揭開白布岸蜗。 她就那樣靜靜地躺著,像睡著了一般叠蝇。 火紅的嫁衣襯著肌膚如雪璃岳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,578評論 1 305
  • 那天,我揣著相機(jī)與錄音矾睦,去河邊找鬼。 笑死炎功,一個胖子當(dāng)著我的面吹牛枚冗,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蛇损,決...
    沈念sama閱讀 40,320評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼赁温,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了淤齐?” 一聲冷哼從身側(cè)響起股囊,我...
    開封第一講書人閱讀 39,241評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎更啄,沒想到半個月后稚疹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,686評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡祭务,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評論 3 336
  • 正文 我和宋清朗相戀三年内狗,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片义锥。...
    茶點(diǎn)故事閱讀 39,992評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡柳沙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出拌倍,到底是詐尸還是另有隱情赂鲤,我是刑警寧澤,帶...
    沈念sama閱讀 35,715評論 5 346
  • 正文 年R本政府宣布柱恤,位于F島的核電站数初,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏膨更。R本人自食惡果不足惜妙真,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望荚守。 院中可真熱鬧珍德,春花似錦、人聲如沸矗漾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽敞贡。三九已至泵琳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背获列。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評論 1 270
  • 我被黑心中介騙來泰國打工谷市, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人击孩。 一個月前我還...
    沈念sama閱讀 48,173評論 3 370
  • 正文 我出身青樓迫悠,卻偏偏與公主長得像,于是被迫代替她去往敵國和親巩梢。 傳聞我的和親對象是個殘疾皇子创泄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 需要原文的可以留下郵箱我給你發(fā),這里的文章少了很多圖括蝠,懶得網(wǎng)上粘啦 1數(shù)據(jù)庫基礎(chǔ) 1.1數(shù)據(jù)庫定義 1)數(shù)據(jù)庫(D...
    極簡純粹_閱讀 7,428評論 0 46
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理鞠抑,服務(wù)發(fā)現(xiàn),斷路器忌警,智...
    卡卡羅2017閱讀 134,657評論 18 139
  • 這個世界大家都是孤獨(dú)的搁拙, 因?yàn)槲覀兊闹黧w意識只能感覺自己的想法。 在任何城市我們都是孤獨(dú)的法绵, 你走過了感混, 沒有人能...
    自知愚蠢的閱讀 97評論 0 0
  • 寫了那么多的職場文章弧满,今天我想推倒重來,我想告訴大家此熬,我寫的職場文章庭呜,其他人寫的職場文章,并不一定適用你犀忱。 1. ...
    有趣的方又方閱讀 549評論 0 1
  • 上周從EOS漲開始募谎,我大腦里面的各個村民就開始鬧騰不休。 村民A:漲了漲了阴汇,快賣了吧数冬,等低價再接回來。 村民B:不...
    喜悅富足的鳳凰于飛閱讀 265評論 0 1