python 2 분 류 를 실현 하 는 카드 박스 예제

해결 한 문제:
1.2 분류의 카드 박스 를 실현 했다.
2.최대 그룹 한정 정지 조건 과 최소 한도 값 한정 정지 조건 을 실현 했다.
문 제 는 아직 잘 모 르 겠 습 니 다.나중에 보충 하 겠 습 니 다.
1.자유도 k,어떻게 확정 합 니까?카드 측 한도 값 의 자유 도 는 상자 수-1 이 고 유의 성 수준 은 10%,5%또는 1%를 취 할 수 있 습 니 다.
알고리즘 확장:
1.카드 측 박스 는 한도 값 으로 제약 조건 을 하 는 것 을 제외 하고 박스 수 제약 과 가장 작은 상자 가 차지 하 는 비례,나 쁜 사람 율 제약 등 도 추가 할 수 있다.
2.더 많은 분 류 를 실현 하 는 카드 박스 알고리즘 이 필요 합 니 다.
구체 적 인 코드 는 다음 과 같다.

# -*- coding: utf-8 -*-
"""
Created on Wed Nov 28 16:54:58 2018
@author: wolfly_fu
     :
1、           
2、             ,           ;
  ,
1、   k,     ?
    :
1、               ,              ,       ,      。
2、               
"""
 
import pandas as pd
import numpy as np
from scipy.stats import chi2
 
#    
df = pd.read_csv(u'test.csv')
 
#       
def cal_chi2(input_df, var_name, Y_name): ##   ,,             
  '''
  df = input_df[[var_name, Y_name]]
  var_values = sorted(list(set(df[var_name])))
  Y_values = sorted(list(set(df[Y_name])))
  #        
  chi2_result = pd.DataFrame(index=var_values, columns=Y_values)  
  for var_value in var_values:
    for Y_value in Y_values:
      chi2_result.loc[var_value][Y_value] = \
      df[(df[var_name]==var_value)&(df[Y_name]==Y_value)][var_name].count()
  '''
  input_df = input_df[[var_name, Y_name]]  #   
  all_cnt = input_df[Y_name].count() #    
  all_0_cnt = input_df[input_df[Y_name] == 0].shape[0] #         
  all_1_cnt = input_df[input_df[Y_name] == 1].shape[0]
  expect_0_ratio = all_0_cnt * 1.0 / all_cnt #      
  expect_1_ratio = all_1_cnt * 1.0 / all_cnt 
  
  #             ,    ,      
  var_values = sorted(list(set(input_df[var_name])))
  actual_0_cnt = []    # actual_0   ,   0   
  actual_1_cnt = []    # actual_1   ,   1   
  actual_all_cnt = []
  expect_0_cnt = []    # expect_0   0     
  expect_1_cnt = []    # expect_1   1      
  chi2_value = []     # chi2_value       
  
  for value in var_values:
    actual_0 = input_df[(input_df[var_name]==value)&(input_df[Y_name]==0)].shape[0] #  ,   0   
    actual_1 = input_df[(input_df[var_name]==value)&(input_df[Y_name]==1)].shape[0]
    actual_all = actual_0 + actual_1 #  
    expect_0 = actual_all * expect_0_ratio #  0       
    expect_1 = actual_all * expect_1_ratio
    
    chi2_0 = (expect_0 - actual_0)**2 / expect_0 #  0     
    chi2_1 = (expect_1 - actual_1)**2 / expect_1
    
    actual_0_cnt.append(actual_0) #   0 ,     
    actual_1_cnt.append(actual_1)
    
    actual_all_cnt.append(actual_all) #       
    expect_0_cnt.append(expect_0) #  0       
    expect_1_cnt.append(expect_1)
    
    chi2_value.append(chi2_0 + chi2_1) #        
    
  chi2_result = pd.DataFrame({'actual_0':actual_0_cnt, 'actual_1':actual_1_cnt, 'expect_0':expect_0_cnt, \
                'expect_1':expect_1_cnt, 'chi2_value':chi2_value, var_name+'_start':var_values, \
                var_name+'_end':var_values}, \
                columns=[var_name+'_start', var_name+'_end', 'actual_0', 'actual_1', 'expect_0', 'expect_1', 'chi2_value'])
  
  return chi2_result, var_name 
 
#         
def merge_area(chi2_result, var_name, idx, merge_idx):
  #  idx merge_idx    
  chi2_result.ix[idx, 'actual_0'] = chi2_result.ix[idx, 'actual_0'] + chi2_result.ix[merge_idx, 'actual_0']
  chi2_result.ix[idx, 'actual_1'] = chi2_result.ix[idx, 'actual_1'] + chi2_result.ix[merge_idx, 'actual_1']
  chi2_result.ix[idx, 'expect_0'] = chi2_result.ix[idx, 'expect_0'] + chi2_result.ix[merge_idx, 'expect_0']  
  chi2_result.ix[idx, 'expect_1'] = chi2_result.ix[idx, 'expect_1'] + chi2_result.ix[merge_idx, 'expect_1']  
  chi2_0 = (chi2_result.ix[idx, 'expect_0'] - chi2_result.ix[idx, 'actual_0'])**2 / chi2_result.ix[idx, 'expect_0']
  chi2_1 = (chi2_result.ix[idx, 'expect_1'] - chi2_result.ix[idx, 'actual_1'])**2 / chi2_result.ix[idx, 'expect_1']
 
  chi2_result.ix[idx, 'chi2_value'] = chi2_0 + chi2_1   #     
  
  #          
  if idx < merge_idx:
    chi2_result.ix[idx, var_name+'_end'] = chi2_result.ix[merge_idx, var_name+'_end'] #      
  else:
    chi2_result.ix[idx, var_name+'_start'] = chi2_result.ix[merge_idx, var_name+'_start'] ##,      
    
  chi2_result = chi2_result.drop([merge_idx]) #   
  chi2_result = chi2_result.reset_index(drop=True)
  
  return chi2_result
 
#      ,        
def chiMerge_maxInterval(chi2_result, var_name, max_interval=5): #        5 
  groups = chi2_result.shape[0] #      ,  
  while groups > max_interval:
    min_idx = chi2_result[chi2_result['chi2_value']==chi2_result['chi2_value'].min()].index.tolist()[0] #        
    if min_idx == 0:
      chi2_result = merge_area(chi2_result, var_name, min_idx, min_idx+1) #  1 2 
    elif min_idx == groups-1:  
      chi2_result = merge_area(chi2_result, var_name, min_idx, min_idx-1)
      
    else: #            
      if chi2_result.loc[min_idx-1, 'chi2_value'] > chi2_result.loc[min_idx+1, 'chi2_value']:
        chi2_result = merge_area(chi2_result, var_name, min_idx, min_idx+1)
      else:
        chi2_result = merge_area(chi2_result, var_name, min_idx, min_idx-1)
    groups = chi2_result.shape[0]
 
  return chi2_result
 
 
def chiMerge_minChiSquare(chi2_result, var_name): #(chi_result, maxInterval=5):
  '''
        --     ,,    ,    6 ,,    
  '''
  threshold = get_chiSquare_distribution(4, 0.1)
  min_chiSquare = chi2_result['chi2_value'].min()
  #min_chiSquare = chi_result['chi_square'].min()
  group_cnt = len(chi2_result)
  #                 ,                
  while(min_chiSquare < threshold and group_cnt > 6):
    min_idx = chi2_result[chi2_result['chi2_value']==chi2_result['chi2_value'].min()].index.tolist()[0] #        
    #min_index = chi_result[chi_result['chi_square']==chi_result['chi_square'].min()].index.tolist()[0]
    #          ,     
    if min_idx == 0:
      chi2_result = merge_area(chi2_result, var_name, min_idx, min_idx+1) #  1 2 
    elif min_idx == group_cnt -1:  
      chi2_result = merge_area(chi2_result, var_name, min_idx, min_idx-1)
      
    else: #            
      if chi2_result.loc[min_idx-1, 'chi2_value'] > chi2_result.loc[min_idx+1, 'chi2_value']:
        chi2_result = merge_area(chi2_result, var_name, min_idx, min_idx+1)
      else:
        chi2_result = merge_area(chi2_result, var_name, min_idx, min_idx-1)
        
    min_chiSquare = chi2_result['chi2_value'].min()
    group_cnt = len(chi2_result)
 
  return chi2_result
 
#                   ,  merge_chiSquare()        ,
#get_chiSquare_distribution()                。            4
#,    10%。         
 
def get_chiSquare_distribution(dfree=4, cf=0.1):
  '''
                    
  dfree:   k= (  -1)*(  -1),   4   #  ,   k,     ?
  cf:     ,  10%
  '''
  percents = [ 0.95, 0.90, 0.5,0.1, 0.05, 0.025, 0.01, 0.005]
  df = pd.DataFrame(np.array([chi2.isf(percents, df=i) for i in range(1, 30)]))
  df.columns = percents
  df.index = df.index+1
  #          
  pd.set_option('precision', 3)
  return df.loc[dfree, cf]
이상 의 python 이 2 분 류 를 실현 하 는 카드 측 분 상자 의 예 는 바로 소 편 이 여러분 에 게 공유 한 모든 내용 입 니 다.여러분 께 참고 가 되 고 저희 도 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기