HotSpot関連規則アルゴリズム(2)--連続型と離散型データの発掘


このコードはhttp://download.csdn.net/detail/fansy1990/8502323ダウンロードします
前編「HotSpot関連規則アルゴリズム(1)--掘削離散型データ」は離散型データのHotSpot関連規則を分析しました.本稿では離散型と連続型データのHotSpot関連規則を分析します.
1.まずデータフォーマット(txtドキュメント)を見ます.
@attribute outlook {sunny, overcast, rainy}
@attribute temperature numeric
@attribute humidity numeric
@attribute windy {TRUE, FALSE}
@attribute play {yes, no}
sunny,85,85,FALSE,no
sunny,80,90,TRUE,no
overcast,83,86,FALSE,yes
rainy,70,96,FALSE,yes
rainy,68,80,FALSE,yes
rainy,65,70,TRUE,no
overcast,64,65,TRUE,yes
sunny,72,95,FALSE,no
sunny,69,70,FALSE,yes
rainy,75,80,FALSE,yes
sunny,75,70,TRUE,yes
overcast,72,90,TRUE,yes
overcast,81,75,FALSE,yes
rainy,71,91,TRUE,no
このデータはwekaが持っているデータweather.arffを参考にして、しかもデータフォーマット、たとえば@atributeなどを書いてもwekaのデータフォーマットを参考にしてきます.以下のコードで使用されるデータフォーマットは、上述したように、1)前のm行は@atributeで始まり、コードm個の属性のうち、最後の一つが目標属性である.2)属性が数値型の場合、atributeの後ろのスペースと属性名、更にスペースとnumeric;離散型であれば、atributeの後ろのスペースと属性名、またスペースは大かっこを使って離散値をまとめ、離散値はコンマで区切られます.3)目標属性は離散的でなければならない(目標属性については離散的でなければならないという要求がありますが、実は私のコードの中でこのように言っています.一般的なHotSpotアルゴリズムにはこの要求がありません.目標属性は連続型である必要があれば、lzコードに基づいて修正できます.)
2.データ読みだし
「Hot Spot関連規則アルゴリズム(1)」のデータ読み込みは離散型のデータに対して行われるので、修正が必要です.ここで修正した後は離散型のデータだけを符号化して連続型のデータを保持すればいいです.一方、ブール配列指定属性列は離散型ですか?それとも連続型ですか?そのコードの読み取りは以下の通りです.
while ((tempString = reader.readLine()) != null) {
				//         
				if (tempString.indexOf(HSUtils.FILEFORMAT) == 0) {

					String attr = "";
					String[] attrStates = null;
					if (tempString.contains("{")) {
						attr = tempString.substring(
								HSUtils.FILEFORMAT.length(),
								tempString.indexOf("{")).trim();
						attrStates = tempString.substring(
								tempString.indexOf("{") + 1,
								tempString.indexOf("}")).split(",");
						for (int i = 0; i < attrStates.length; i++) {
							attrStates[i] = attrStates[i].trim();
						}
						numericList.add(false);
						this.attributeStates.put(attr, attrStates);//        
					} else {// numeric
						if (tempString.contains("numeric")) {
							attr = tempString.substring(
									HSUtils.FILEFORMAT.length(),
									tempString.indexOf("numeric")).trim();
							numericList.add(true);
						} else {
							// error       
							throw new Exception("      ,   !");
						}

					}
					attrList.add(attr);
					line++;

					continue;
				}
				if (flag) {
					this.attributes = new String[line];
					this.isNumeric = new Boolean[line];
					attrList.toArray(this.attributes);//        
					numericList.toArray(this.isNumeric);
					flag = false;
				}
				String[] tempStrings = tempString.split(splitter);
				lists.add(strArr2IntArr(tempStrings));
			}
ここでは、whileループ内のコードのみが貼られています.ここでのコードは、前述のデータフォーマット規則に対して変数初期化を行います.(実は、ここではListを使って変換後のデータを記憶しています.普通は配列を使って保存できます.Listのデータを配列に変換すればいいです.このように後の操作でもっと速くできます.最適化するなら、この点から始めてもいいです.)
3. HotSpot関連ルールツリーのノード定義説明:
ここでは連続型属性データが追加されているので、個々のノードに対して、離散型データ状態の下ではなく、1つのブール型変数lessThanを追加する必要があります.
4.アルゴリズム疑似コード(ツリープロセス)
アルゴリズムの擬似コードの中の潜在的なノードを計算する時、連続型変数に対して異なる方法を使用し、wekaソースでの使用方法:evaluate Numericで判断します.lzのコードの中のこの部分は完全にソースコードを参照していますが、evaluate Numericというアルゴリズムを呼び出した後、ある列に並べ替えられます.全体の並べ替えを行います.この方法はwekaソースの中でInstanceのquickSort方法を使って並べ替えられています.ここでlzは直接Listを二次元配列に変えて並べ替えます.その方法は以下の通りです.
/**
	 *   attrIndex    ,attrIndex   numeric           
	 * List         ?         
	 * @param intData
	 * @param attrIndex
	 * @return
	 */
	private List<float[]> sortBasedOnAttr(List<float[]> intData, final int attrIndex) {
		
		float[][] tmpData = new float[intData.size()][];
		intData.toArray(tmpData);

		Arrays.sort(tmpData,new Comparator<float[]>(){
			@Override
			public int compare(float[] o1, float[] o2) {
				if(o1[attrIndex]==o2[attrIndex]){
					return 0;
				}
				return o1[attrIndex]>o2[attrIndex]?1:-1;
			}
			
		});
		List<float[]> returnList = new ArrayList<float[]>();
		for (int i = 0; i < tmpData.length; i++) {
			returnList.add(tmpData[i]);
		}
		return returnList;
	}
は、同時に、再帰的に子供ノードを構築する際に、ノードルールを生成する際に、数値型と離散型についても、その生成方法は以下のように異なる.
double[] newSplitVals = splitVals.clone();
			byte[] newTests = tests.clone();
			newSplitVals[attrStateSup.getAttrIndex()] = attrStateSup
					.getStateIndex() + 1;
			newTests[attrStateSup.getAttrIndex()] = isNumeric[attrStateSup.getAttrIndex()]?
				attrStateSup.isLessThan()?(byte)1:(byte)3:(byte) 2;

			HotSpotHashKey key = new HotSpotHashKey(newSplitVals, newTests);
は、再帰的に子供ノードを構築する際に、使用するサブデータセットの生成方式も調整する必要がある.
/**
	 *    splitAttributeIndex         stateIndex     
	 * 
	 * @param intData
	 * @param splitAttributeIndex
	 * @param splitValue
	 * @return
	 */
	private List<float[]> getSubData(List<float[]> intData,
			int splitAttributeIndex, float splitValue,boolean lessThan) {
		List<float[]> subData = new ArrayList<float[]>();
		for (float[] d : intData) {
			if(isNumeric[splitAttributeIndex]){
				if(lessThan){
					if (d[splitAttributeIndex] <= splitValue) {
		                subData.add(d);
		            }
				}else{
					if (d[splitAttributeIndex] > splitValue) {
		                subData.add(d);
		            }
				}
			}else{
				if (d[splitAttributeIndex] == splitValue) {
					subData.add(d);
				}
			}
		}
		return subData;
	}
ノードのtoStringメソッドは、HotSpot関連ルールツリーを印刷するために使用されます.
/**
	 *      
	 */
	public String toString(){
		String tmp = HSUtils.isNumeric(splitAttrIndex)?this.lessThan?" <= ":" > ":" = ";
		String attrState = HSUtils.isNumeric(splitAttrIndex)?String.valueOf(this.attrStateIndex):
			HSUtils.getAttrState(splitAttrIndex, (int)attrStateIndex);
 		return HSUtils.getAttr(this.splitAttrIndex)+tmp
				+attrState
				+"  ("+HSUtils.formatPercent(this.support)+" ["+this.stateCount+"/"+this.allCount+"])";
	}
関連するルールツリーを印刷する場合も、現在の属性は離散型か連続型かを判断する必要があります.
コード出力:
      ,                !
  outlook   :	[sunny-->0,overcast-->1,rainy-->2,]
  temperature   :	[numeric]
  humidity   :	[numeric]
  windy   :	[TRUE-->0,FALSE-->1,]
  play   :	[yes-->0,no-->1,]

     :

play = no  (35.71% [5/14])
|	temperature > 83.0  (100.00% [1/1])
|	humidity > 90.0  (66.67% [2/3])
|	|	temperature > 70.0  (100.00% [2/2])
|	|	humidity <= 95.0  (100.00% [2/2])
分かち合う
地道に取り組む
転載はブログの住所を明記してください.http://blog.csdn.net/fansy1990