<jupyter_start><jupyter_text>FIW Databas Overview- Families In the Wild (FIW) is the largest and most comprehensive image database for automatic kinship recognition. It is made-up of 11,932 family photos that span 1,000 different families, with the data distributed fairly with average of about 12 images per family, each with at least 3 and as many as 38 members. This data supports all prior pair-wise types and also introduces grandparent-grandchild pairs (GF-GD, GF-GS, GM-GD, GM-GS). In addition of it is a public and noncommercial database.- Int this part of the project the kaggle version of the database will be used to solve the kinship verification task.<jupyter_code>import os
import glob
import base64
import zipfile
import numpy as np
import pandas as pd
from PIL import Image
from io import BytesIO
import matplotlib.pyplot as plt
from IPython.display import HTML
from collections import defaultdict<jupyter_output><empty_output><jupyter_text>Data Cleansing & Exploration__1)__  Defining some useful functions for data preprocessing and visualizations.<jupyter_code>pd.set_option('display.max_colwidth', -1)
######################################################################
###### Function that returns the thumbnail version of an image  ######
######################################################################
def get_thumbnail(path):
    if path and os.path.exists(path):
        i = Image.open(path)
        i.thumbnail((150, 150), Image.LANCZOS)
        return i
######################################################################
####### Function that returns the base64 format from an image  #######
######################################################################
def image_base64(im):
    if isinstance(im, str):
        im = get_thumbnail(im)
    with BytesIO() as buffer:
        im.save(buffer, 'jpeg')
        return base64.b64encode(buffer.getvalue()).decode()
######################################################################
############## Function that returns the image format  ###############
######################################################################
def image_formatter(im):
    return f'<img src="data:image/jpeg;base64,{image_base64(im)}">'
######################################################################
######## Function that returns the image path from it's code  ########
######################################################################
def add_image_path(x,path):
    image_path = path + x
    if os.path.exists(image_path):
        path = os.path.join(image_path, os.listdir(image_path)[0])
        return path<jupyter_output><empty_output><jupyter_text>__2)__  Loading the train_relationships file as a dataframe in the kin_data variable and exploring it's content to find out that it consists of 3598 records each record is a family and member codes for the pair of images.<jupyter_code>kin_data = pd.read_csv('kaggle/train_relationships.csv')
print(kin_data.shape)
kin_data.head()<jupyter_output>(3598, 2)<jupyter_text>__3)__ Looping in the directory that contains the training data and:    - Keep the tag (family code/member code) of all existing photos of members in the database.    - Keep the path (family code/member code/image code) of all of the existing photos at the database in the allphotos dictionary.        - Because of we using the kaggle version of the data there may be some recods that refer to unexisting members so this step will helping to make sure that this will never happen.<jupyter_code>#keeps all photos path in a dictionary
allPhotos = defaultdict(list)
for family in glob.glob("kaggle/train/*"):
    for mem in glob.glob(family + '/*'):
        for photo in glob.glob(mem + '/*'):
            allPhotos[mem].append(photo)

#list of all members with valid photo
ppl = list(allPhotos.keys())
print("number of the members with valid photo",len(ppl))
print("sample of the ppl content: ", ppl[:3])<jupyter_output>number of the members with valid photo 2316
sample of the ppl content:  ['kaggle/train/F0390/MID11', 'kaggle/train/F0390/MID5', 'kaggle/train/F0390/MID9']<jupyter_text>__4)__ Add 2 columns __p1_path & p2_path__ in the dataframe that represents the path of the member folder that contains all of his/her photos.<jupyter_code>kin_data['p1_path'] = kin_data.p1.apply(lambda x: 'kaggle/train/' + x)
kin_data['p2_path'] = kin_data.p2.apply(lambda x: 'kaggle/train/' + x)
print(kin_data.shape)
kin_data.head()<jupyter_output>(3598, 4)<jupyter_text>__5)__ Loopingon all the records and find if it's path existing in the ppl that contains all members paths or not, if not the record will be excluded.- Number of records after data cleansing is 3362 instead of 3598 records.<jupyter_code>kin_data = kin_data[((kin_data.p1_path.isin(ppl)) & (kin_data.p2_path.isin(ppl)))]
print(len(kin_data))<jupyter_output>3362<jupyter_text>__6)__<jupyter_code>sample_data = kin_data.sample(50)
sample_data['p1_path'] = sample_data.p1.apply(lambda f: add_image_path(f, 'kaggle/train/'))
sample_data['p2_path'] = sample_data.p2.apply(lambda f: add_image_path(f, 'kaggle/train/'))
sample_data['p1_thumb'] = sample_data.p1_path.map(lambda f: get_thumbnail(f))
sample_data['p2_thumb'] = sample_data.p2_path.map(lambda f: get_thumbnail(f))
print(sample_data.shape)
sample_data.head()
HTML(sample_data.head()[['p1', 'p2', 'p1_thumb', 'p2_thumb']].to_html(formatters={'p1_thumb': image_formatter, 'p2_thumb': image_formatter}, escape=False))<jupyter_output><empty_output><jupyter_text>Data Analysis__1)__ To make a more understandable analysis the 1000 family will be divided into 10 groups each have a 100 possible family on it. __2)__ Counting the number of occurence of each group in the dataframe that will be used for training our model.<jupyter_code># from the training pairs how many pairs come from a range of 100 of family codes
fam = ['F00', 'F01', 'F02', 'F03', 'F04', 'F05', 'F06', 'F07', 'F08', 'F09', 'F10']
f = {}
for family in fam:
    f[family] = kin_data.p1.str.count(family).sum() + kin_data.p2.str.count(family).sum()
    
print(f)<jupyter_output>{'F00': 520, 'F01': 782, 'F02': 662, 'F03': 604, 'F04': 590, 'F05': 602, 'F06': 786, 'F07': 794, 'F08': 748, 'F09': 592, 'F10': 44}<jupyter_text>__3)__ Counting the number of members in each group.__4)__ Counting the actual number of family codes in each group.<jupyter_code># count the number of members in the dataset per a subset of 100 of family codes
counter = {}
count = 0

for family in glob.glob("kaggle/train/*"):
    count = 0
    for mem in glob.glob(family + '/*'):
        count += 1
        counter[family] = count
    
c = pd.DataFrame.from_dict(counter, orient = 'index').reset_index().rename(columns = {'index':'family', 0:'count'})

z = {}
for famil in fam:
    z[famil] = c.family.str.count(famil).sum()
# count the number of exists families of each subset of 100 family codes
n_families = {}

for x in fam:
    count = 0
    for family in glob.glob("kaggle/train/*"):
        count += (x in family)
        n_families[x] = count<jupyter_output><empty_output><jupyter_text>__3)__ Visualize all of the above analysis.<jupyter_code>colors = ['C0', 'C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7', 'C8', 'C9', 'black']

x1 = f.keys()
x2 = z.keys()
x3 = n_families.keys()

y1 = f.values()
y2 = z.values()
y3 = n_families.values()

fig, ax = plt.subplots(3)

ax[0].bar(x1, y1, color = colors)
ax[0].set(xlabel = 'Family Code', ylabel = 'Occurrence')

ax[1].bar(x2, y2, color = colors)
ax[1].set(xlabel = 'Family Code', ylabel = 'Number of Members')

ax[2].bar(x3, y3, color = colors)
ax[2].set(xlabel = 'Family Code', ylabel = 'Actual number of families')

fig.set_figheight(15)
fig.set_figwidth(15)
plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.18955011020355245, 'fraction_numerical': 0.0328017632568391, 'mean_word_length': 5.333333333333333, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '183212', 'license': 'MIT', 'n_tokens_mistral': 2618, 'n_tokens_neox': 2428, 'n_words': 773, 'path': 'kinship verification/Data Exploration & Analysis.ipynb', 'repo_name': 'Arwa-Ibrahim/FIW_Capstone_Project', 'size': '7713'}