<jupyter_start><jupyter_text>Generating the data<jupyter_code>center=[[1,1],[-0.2,-0.2]]
data_size_0,data_size_1=100,5
data=[c+np.random.randn(data_size,2)*0.5 for data_size,c in zip([data_size_0,data_size_1],center) ]
data=np.concatenate(data)
label = np.array([0 if i<data_size_0 else 1 for i in range(data_size_0+data_size_1)])
markers = ('s', 'x', 'o', '^', 'v')
colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan')
for i in range(2):
    plt.scatter(data[:,0][label==i],data[:,1][label==i],alpha=0.8,label=i,edgecolor='black',c=colors[i],marker=markers[i])
plt.legend();<jupyter_output><empty_output><jupyter_text>Train<jupyter_code>from sklearn.metrics import f1_score
import warnings
warnings.simplefilter('ignore')
class kNearestNeighbors:
    def __init__(self,k,a_th,data_size_0,data_size_1):
        self.k=k
        self.a_th=a_th
        self.data_size_0=data_size_0
        self.data_size_1=data_size_1
        self.pi0=data_size_0/(data_size_0+data_size_1)
        self.pi1=data_size_1/(data_size_0+data_size_1)
    def distance(self,x,y):
        return ((x-y)**2).sum()
    def calc_F(self,data,label):
        self.anomaly_score=np.zeros(len(data))
        for i in range(len(data)):
            dist=np.array([ self.distance(data[i],data[j]) for j in range(len(data))])
            dist_sorted_index=np.argsort(dist)[1:self.k+1]
            n1=(label[dist_sorted_index]==1).sum()  #number of 1
            n0=(label[dist_sorted_index]==0).sum()  #number of 0
            self.anomaly_score[i]=np.log((self.pi0*n1)/(self.pi1*n0))
        label_pred=self.anomaly_score>self.a_th
        self.label_pred=label_pred
        return f1_score(label,label_pred)
#Grid Search
k_list=list(range(1,11,1))
a_th_list=list(range(1,11,1))
def search_best_model(k_list,a_th_list):
    value_holder=[0,0,0.0]
    for k in k_list:
        for a_th in a_th_list:
            knn=kNearestNeighbors(k,a_th,data_size_0,data_size_1)
            f1_score=knn.calc_F(data,label)
            if f1_score>value_holder[2]:
                value_holder=[k,a_th,f1_score]
    return value_holder
search_best_model(k_list,a_th_list)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.15613382899628253, 'fraction_numerical': 0.03438661710037175, 'mean_word_length': 4.3825, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 11, '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': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '379200', 'license': 'MIT', 'n_tokens_mistral': 900, 'n_tokens_neox': 883, 'n_words': 107, 'path': 'Chapter 4 k Nearest Neighbors.ipynb', 'repo_name': 'TakuyaMurata/Anomaly-Detection-and-Change-Detection', 'size': '2152'}