Пример #1
0
    def match_couple_hdom(self):
        '''
        Certaines personnes se déclarent en couple avec quelqu'un ne vivant pas au domicile, on les reconstruit ici.
        Cette étape peut s'assimiler à de la fermeture de l'échantillon.
        On sélectionne les individus qui se déclarent en couple avec quelqu'un hors du domicile.
        On match mariés,pacsé d'un côté et sans contrat de l'autre. Dit autrement, si on ne trouve pas de partenaire à une personne mariée ou pacsé on change son statut de couple.
        Comme pour les liens parents-enfants, on néglige ici la possibilité que le partner soit hors champ (étrange, prison, casernes, etc).
        Calcul aussi la variable ind['nb_enf']
        '''
        ind = self.ind
        couple_hdom = ind['couple'] == 2
        # vu leur nombre, on regroupe pacsés et mariés dans le même sac
        ind.loc[(couple_hdom) & (ind['civilstate'] == 5), 'civilstate'] = 1
        # note que du coup, on cherche un partenaire de pacs parmi le sexe opposé. Il y a une petite par technique là dedans qui fait qu'on
        # ne gère pas les couples homosexuels

        ## nb d'enfant
        ind.index = ind['id']
        nb_enf_mere = DataFrame(ind.groupby('mere').size(), columns = ['nb_enf'])
        nb_enf_mere['id'] = nb_enf_mere.index.values
        nb_enf_pere = DataFrame(ind.groupby('pere').size(), columns = ['nb_enf'])
        nb_enf_pere['id'] = nb_enf_pere.index
        # On assemble le nombre d'enfants pour les peres et meres en enlevant les manquantes ( = -1)
        enf_tot = nb_enf_mere[nb_enf_mere['id'] != -1].append(nb_enf_pere[nb_enf_pere['id'] != -1]).astype(int)
        ind['nb_enf'] = 0
        ind['nb_enf'][enf_tot['id'].values] = enf_tot['nb_enf']

        men_contrat = couple_hdom & (ind['civilstate'].isin([1, 5])) & (ind['sexe'] == 0)
        women_contrat = couple_hdom & (ind['civilstate'].isin([1, 5])) & (ind['sexe'] == 1)
        men_libre = couple_hdom & (~ind['civilstate'].isin([1, 5])) & (ind['sexe'] == 0)
        women_libre = couple_hdom & (~ind['civilstate'].isin([1, 5])) & (ind['sexe'] == 1)

        ind['age'] = ind['agem']//12
        var_match = ['age', 'findet', 'nb_enf'] #,'classif', 'dip6'
        score = "- 0.4893 * other.age + 0.0131 * other.age **2 - 0.0001 * other.age **3 "\
                 " + 0.0467 * (other.age - age)  - 0.0189 * (other.age - age) **2 + 0.0003 * (other.age - age) **3 " \
                 " + 0.05   * (other.findet - findet) - 0.5 * (other.nb_enf - nb_enf) **2 "
        match_contrat = Matching(ind.loc[women_contrat, var_match], ind.loc[men_contrat, var_match], score)
        match_found = match_contrat.evaluate(orderby=None, method='cells')
        ind.loc[match_found.values,'partner'] =  match_found.index
        ind.loc[match_found.index,'partner'] =  match_found.values

        match_libre = Matching(ind.loc[women_libre, var_match], ind.loc[men_libre, var_match], score)
        match_found = match_libre.evaluate(orderby=None, method='cells')
        ind.loc[match_found.values,'partner'] =  match_found.index
        ind.loc[match_found.index,'partner'] =  match_found.values

        # TODO: on pourrait faire un match avec les restants
        # au lieu de ça, on les considère célibataire
        ind.loc[men_contrat & (ind['partner'] == -1), ['civilstate', 'couple']] = [2, 3]
        ind.loc[women_contrat & (ind['partner'] == -1), ['civilstate', 'couple']] = [2, 3]
        ind.loc[men_libre & ind['partner'] == -1, ['civilstate', 'couple']] = [2, 3]
        ind.loc[women_libre & ind['partner'] == -1, ['civilstate', 'couple']] = [2, 3]

        ind.drop(['couple', 'age'], axis = 1, inplace = True)
        self.ind = ind
Пример #2
0
    def matching_par_enf(self):
        '''
        Matching des parents et des enfants hors du domicile
        '''
        ind = self.ind
        ind = ind.fillna(-1)
        ind.index = ind['id']
        child_out_of_house = self.child_out_of_house
        ## info sur les parents hors du domicile des enfants
        cond_enf_look_par = (ind['per1e'] == 2) | (ind['mer1e'] == 2)
        enf_look_par = ind[cond_enf_look_par].copy()
        # Remarque: avant on mettait à zéro les valeurs quand on ne cherche pas le parent, maintenant
        # on part du principe qu'on fait les choses assez minutieusement
        enf_look_par['dip6'] = recode(enf_look_par['dip14'], [[30,5], [41,4], [43,3], [50,2], [60,1]] , method='geq')
        enf_look_par['classif'] = recode(enf_look_par['classif'], [ [[1,2,3],4], [[4,5],2], [[6,7],1], [[8,9], 3], [[10],0]], method='isin')
        ## nb d'enfant
        # -- Au sein du domicile
        nb_enf_mere_dom = ind.groupby('mere').size()
        nb_enf_pere_dom= ind.groupby('pere').size()
        # On assemble le nombre d'enfants pour les peres et meres en enlevant les manquantes ( = -1)
        enf_tot_dom = concat([nb_enf_mere_dom, nb_enf_pere_dom], axis=0)
        enf_tot_dom = enf_tot_dom.drop([-1])
        # -- Hors domicile
        nb_enf_mere_hdom = child_out_of_house.groupby('mere').size()
        nb_enf_pere_hdom = child_out_of_house.groupby('pere').size()
        enf_tot_hdom = concat([nb_enf_mere_hdom, nb_enf_pere_hdom], axis=0)
        enf_tot_hdom = enf_tot_hdom.drop([-1])

        enf_tot = concat([enf_tot_dom, enf_tot_hdom], axis = 1).fillna(0)
        enf_tot = enf_tot[0] + enf_tot[1]
        # Sélection des parents ayant des enfants (enf_tot) à qui on veut associer des parents (enf_look_par)
        enf_tot = (enf_tot.loc[enf_tot.index.isin(enf_look_par.index)].astype(int)).copy()
        enf_look_par.index = enf_look_par['id']
        enf_look_par['nb_enf'] = 0
        enf_look_par.loc[enf_tot.index.values, 'nb_enf'] = enf_tot
        #Note: Attention le score ne peut pas avoir n'importe quelle forme, il faut des espaces devant les mots, à la limite une parenthèse
        var_match = ['jepnais', 'situa', 'nb_enf', 'anais', 'classif', 'couple', 'dip6', 'jemnais', 'jemprof', 'sexe']
        #TODO: gerer les valeurs nulles, pour l'instant c'est très moche

        #TODO: avoir une bonne distance, on met un gros coeff sur l'age sinon, on a des parents,
        # plus vieux que leurs enfants
        score = "- 1000 * (other.anais - anais) **2 - 1.0 * (other.situa - situa) **2 " + \
        "- 0.5 * (other.sexe - sexe) **2 - 1.0 * (other.dip6 - dip6) **2 " + \
        " - 1.0 * (other.nb_enf - nb_enf) **2"

        # etape1 : deux parents vivants
        cond1_enf = (enf_look_par['per1e'] == 2) & (enf_look_par['mer1e'] == 2)
        cond1_par = (child_out_of_house['pere'] != -1) & (child_out_of_house['mere'] != -1)
        # TODO: si on fait les modif de variables plus tôt, on peut mettre directement child_out_of_house1
        #à cause du append plus haut, on prend en fait ici les premiers de child_out_of_house
        match1 = Matching(enf_look_par.loc[cond1_enf, var_match],
                          child_out_of_house.loc[cond1_par, var_match], score)
        parent_found1 = match1.evaluate(orderby=['anais'], method='cells')
        ind.loc[parent_found1.index.values, ['pere', 'mere']] = child_out_of_house.loc[parent_found1.values, ['pere', 'mere']]

        #etape 2 : seulement mère vivante
        enf_look_par.loc[parent_found1.index, ['pere', 'mere']] = child_out_of_house.loc[parent_found1, ['pere', 'mere']]
        cond2_enf = ((enf_look_par['mere'] == -1)) & (enf_look_par['mer1e'] == 2)
        cond2_par = ~child_out_of_house.index.isin(parent_found1) & (child_out_of_house['mere'] != -1)
        match2 = Matching(enf_look_par.loc[cond2_enf, var_match],
                          child_out_of_house.loc[cond2_par, var_match], score)
        parent_found2 = match2.evaluate(orderby=None, method='cells')
        ind.loc[parent_found2.index, ['mere']] = child_out_of_house.loc[parent_found2, ['mere']]

        #étape 3 : seulement père vivant
        enf_look_par.loc[parent_found2.index, ['pere', 'mere']] = child_out_of_house.loc[parent_found2, ['pere', 'mere']]
        cond3_enf = ((enf_look_par['pere'] == -1)) & (enf_look_par['per1e'] == 2)
        cond3_par = ~child_out_of_house.index.isin(parent_found1) & (child_out_of_house['pere'] != -1)

        # TODO: changer le score pour avoir un lien entre pere et mere plus évident
        match3 = Matching(enf_look_par.loc[cond3_enf, var_match],
                          child_out_of_house.loc[cond3_par, var_match], score)
        parent_found3 = match3.evaluate(orderby=None, method='cells')
        ind.loc[parent_found3.index, ['pere']] = child_out_of_house.loc[parent_found3, ['pere']]

        print(" au départ on fait " + str(len(parent_found1) + len(parent_found2) + len(parent_found3)) + " match enfant-parent hors dom")
        # on retire les match non valides
        to_check = ind[['id', 'agem', 'sexe', 'men', 'partner', 'pere', 'mere', 'lienpref']]
        tab = to_check.copy()
        for lien in ['partner', 'pere', 'mere']:
            tab = tab.merge(to_check, left_on=lien, right_on='id', suffixes=('', '_' + lien), how='left', sort=False)
        tab.index = tab['id']

        for parent in ['pere', 'mere']:
            diff_age_pere = (tab['agem_' + parent] - tab['agem'])
            cond = diff_age_pere <= 12*14
            print( "on retire " + str(sum(cond)) + " lien enfant " + parent +
                   " car l'âge n'était pas le bon")
            ind.loc[cond, parent] = -1

            cond = (tab['partner'] > -1) & (tab[parent] > -1) & \
                    (tab[parent] == tab[parent + '_partner']) & \
                    (tab['men'] != tab['men_' + parent])
            print( "on retire " + str(sum(cond)) + " lien enfant " + parent +
                   " car le partner a le même parent")
            ind.loc[(cond[cond]).index, parent] = -1

        self._check_links(ind)
        self.ind = minimal_dtype(ind)
        all = self.men.columns.tolist()
        enfants_hdom = [x for x in all if x[:3]=='hod']
        self.drop_variable({'ind':['enf', 'per1e', 'mer1e', 'grandpar'] + ['jepnais', 'jemnais', 'jemprof'], 'men':enfants_hdom})
Пример #3
0
    def matching_par_enf(self):
        '''
        Matching des parents et des enfants hors du domicile
        '''
        ind = self.ind
        ind = ind.fillna(-1)
        ind.index = ind['id']
        child_out_of_house = self.child_out_of_house
        ## info sur les parents hors du domicile des enfants
        cond_enf_look_par = (ind['per1e']==2) | (ind['mer1e']==2)
        enf_look_par = ind[cond_enf_look_par]
        # Remarque: avant on mettait à zéro les valeurs quand on ne cherche pas le parent, maintenant
        # on part du principe qu'on fait les choses assez minutieusement                                           
        
        recode(enf_look_par, 'dip14', 'dip6', [[30,5], [41,4], [43,3], [50,2], [60,1]] , method='geq')
        recode(enf_look_par, 'classif', 'classif2', [ [[1,2,3],4], [[4,5],2], [[6,7],1], [[8,9], 3], [[10],0]], method='isin')
        enf_look_par.loc[:,'classif'] = enf_look_par.loc[:,'classif2']

        ## nb d'enfant
        # -- Au sein du domicile
        nb_enf_mere_dom = ind.groupby('mere').size()
        nb_enf_pere_dom= ind.groupby('pere').size()
        # On assemble le nombre d'enfants pour les peres et meres en enlevant les manquantes ( = -1)
        enf_tot_dom = concat([nb_enf_mere_dom, nb_enf_pere_dom], axis=0)
        enf_tot_dom = enf_tot_dom.drop([-1])
        
        # -- Hors domicile
        nb_enf_mere_hdom = child_out_of_house.groupby('mere').size()
        nb_enf_pere_hdom = child_out_of_house.groupby('pere').size()
        enf_tot_hdom = concat([nb_enf_mere_hdom, nb_enf_pere_hdom], axis=0)
        enf_tot_hdom = enf_tot_hdom.drop([-1])
        
        enf_tot = concat([enf_tot_dom, enf_tot_hdom], axis = 1).fillna(0)
        enf_tot = enf_tot[0] + enf_tot[1]
        # Sélection des parents ayant des enfants (enf_tot) à qui on veut associer des parents (enf_look_par)
        enf_tot = enf_tot.ix[enf_tot.index.isin(enf_look_par.index)].astype(int)
  
        enf_look_par.index = enf_look_par['id']
        enf_look_par['nb_enf'] = 0
        enf_look_par['nb_enf'][enf_tot.index.values] = enf_tot

        #Note: Attention le score ne peut pas avoir n'importe quelle forme, il faut des espaces devant les mots, à la limite une parenthèse
        var_match = ['jepnais','situa','nb_enf','anais','classif','couple','dip6', 'jemnais','jemprof','sexe']
        #TODO: gerer les valeurs nulles, pour l'instant c'est très moche
        #TODO: avoir une bonne distance
        score = "- 1 * (other.anais - anais) **2 - 1.0 * (other.situa - situa) **2 - 0.5 * (other.sexe - sexe) **2 - 1.0 * (other.dip6 - dip6) \
         **2 - 1.0 * (other.nb_enf - nb_enf) **2"

        # etape1 : deux parents vivants
        cond1_enf = (enf_look_par['per1e'] == 2) & (enf_look_par['mer1e'] == 2)
        cond1_par = (child_out_of_house['pere'] != -1) & (child_out_of_house['mere'] != -1)
        # TODO: si on fait les modif de variables plus tôt, on peut mettre directement child_out_of_house1
        
        #à cause du append plus haut, on prend en fait ici les premiers de child_out_of_house
        match1 = Matching(enf_look_par.ix[cond1_enf, var_match], 
                          child_out_of_house.ix[cond1_par, var_match], score)
        parent_found = match1.evaluate(orderby=None, method='cells')
        ind.ix[parent_found.index.values, ['pere','mere']] = child_out_of_house.ix[parent_found.values, ['pere','mere']]
         
        #etape 2 : seulement mère vivante
        enf_look_par.ix[parent_found.index, ['pere','mere']] = child_out_of_house.ix[parent_found, ['pere','mere']]
        cond2_enf = ((enf_look_par['mere'] == -1)) & (enf_look_par['mer1e'] == 2)
        cond2_par = ~child_out_of_house.index.isin(parent_found) & (child_out_of_house['mere'] != -1)
        match2 = Matching(enf_look_par.ix[cond2_enf, var_match], 
                          child_out_of_house.ix[cond2_par, var_match], score)
        parent_found2 = match2.evaluate(orderby=None, method='cells')
        ind.ix[parent_found2.index, ['mere']] = child_out_of_house.ix[parent_found2, ['mere']]        
        
        #étape 3 : seulement père vivant
        enf_look_par.ix[parent_found2.index, ['pere','mere']] = child_out_of_house.ix[parent_found2, ['pere','mere']]
        cond3_enf = ((enf_look_par['pere'] == -1)) & (enf_look_par['per1e'] == 2)
        cond3_par = ~child_out_of_house.index.isin(parent_found) & (child_out_of_house['pere'] != -1)
        
        # TODO: changer le score pour avoir un lien entre pere et mere plus évident
        match3 = Matching(enf_look_par.ix[cond3_enf, var_match], 
                          child_out_of_house.ix[cond3_par, var_match], score)
        parent_found3 = match3.evaluate(orderby=None, method='cells')
        ind.ix[parent_found3.index, ['pere']] = child_out_of_house.ix[parent_found3, ['pere']]               

        self.ind = minimal_dtype(ind)
        all = self.men.columns.tolist()
        enfants_hdom = [x for x in all if x[:3]=='hod']
        self.drop_variable({'ind':['enf','per1e','mer1e','grandpar'] + ['jepnais','jemnais','jemprof'], 'men':enfants_hdom})