<jupyter_start><jupyter_text>Feature Distributions<jupyter_code>df = pd.read_csv('./data/cstr_rawdata.csv')

data_mat = df.values
X = data_mat[:, :-4]
X = feature_scaling(X)
y = df['Class'].values
d = df['Domain'].values
fig, ax = plt.subplots(1, 1, figsize=(9, 5))

sns.distplot(feature_scaling(X[np.where(d == 0)]).flatten(), hist=False, ax=ax, label='$0\%$')
sns.distplot(feature_scaling(X[np.where(d == 1)]).flatten(), hist=False, ax=ax, label='$10\%$')
sns.distplot(feature_scaling(X[np.where(d == 2)]).flatten(), hist=False, ax=ax, label='$15\%$')
sns.distplot(feature_scaling(X[np.where(d == 3)]).flatten(), hist=False, ax=ax, label='$20\%$')
ax.set_ylabel('$P_{D_{i}}$(X)')
ax.set_xlabel('X')
ax.legend(title='Degree of Mismatch')
plt.savefig('./Figures/Ch6/CSTR_CovariateShift.pdf')
fig, ax = plt.subplots(1, 1, figsize=(9, 5))

sns.distplot(feature_scaling(X[np.where(d == 0)]).flatten(), hist=False, ax=ax, label='$0\%$')
sns.distplot(feature_scaling(X[np.where(d == 4)]).flatten(), hist=False, ax=ax, label='$10\%$')
sns.distplot(feature_scaling(X[np.where(d == 5)]).flatten(), hist=False, ax=ax, label='$15\%$')
sns.distplot(feature_scaling(X[np.where(d == 6)]).flatten(), hist=False, ax=ax, label='$20\%$')
ax.set_ylabel('$P_{D_{i}}$(X)')
ax.set_xlabel('X')
ax.legend(title='Reaction Order')
plt.savefig('./Figures/Ch6/CSTR_CovariateShift_ReactOrder.pdf')
fig, ax = plt.subplots(1, 1, figsize=(9, 5))

barX = []
barY = []
for i, domain in enumerate(np.unique(d)[1:]):
    Xs = X[np.where(d == 0)[0]]
    Xt = X[np.where(d == domain)[0]]
    
    wdist = wasserstein_distance(Xs, Xt, norm=None, metric='cityblock')
    barX.append(i)
    barY.append(wdist)
    ax.text(i, wdist + 5, s="{}".format(np.round(wdist, 2)), ha='center')
    
ax.bar(barX, barY)
ax.set_xticklabels(['0',
                    r'$\epsilon=0.10$' + '\n' + r'$N = 1.0$',
                    r'$\epsilon=0.15$' + '\n' + r'$N = 1.0$',
                    r'$\epsilon=0.20$' + '\n' + r'$N = 1.0$',
                    r'$\epsilon=0.15$' + '\n' + r'$N = 0.5$',
                    r'$\epsilon=0.15$' + '\n' + r'$N = 1.5$',
                    r'$\epsilon=0.15$' + '\n' + r'$N = 2.0$'])
ax.set_ylabel(r'$W_{1}(\hat{P}_{S}, \hat{P}_{T})$')
ax.set_ylim([0, 230])
plt.tight_layout()

plt.savefig('./Figures/Ch6/Wdists_CSTR.pdf')<jupyter_output><empty_output><jupyter_text>Raw Features<jupyter_code>df = pd.read_csv('./data/cstr_rawdata.csv')

data_mat = df.values
X = data_mat[:, :-4]
y = df['Class'].values
d = df['Domain'].values

Xs, ys = X[np.where(d == 0)[0]], y[np.where(d == 0)[0]]

dataset = np.load('./data/DistributionalShiftData/raw_cstr_distrshift.npy')

X = dataset[:, :-3]
y = dataset[:, -3]
E = dataset[:, -2]
N = dataset[:, -1]

targets_E = [
    (eps,
     X[np.intersect1d(np.where(E == eps)[0], np.where(N == 1))],
     y[np.intersect1d(np.where(E == eps)[0], np.where(N == 1))]) for eps in [i / 10 for i in range(1, 10)]
]

targets_N = [
    (Ni,
     X[np.intersect1d(np.where(E == 0.15)[0], np.where(N == Ni))],
     y[np.intersect1d(np.where(E == 0.15)[0], np.where(N == Ni))]) for Ni in [0.25, 0.5, 0.75, 1,
                                                                              1.25, 1.75, 2.0]
]<jupyter_output><empty_output><jupyter_text>Parameters vs. Distributional Shift<jupyter_code>ErawX = []
ErawY = []
for eps, Xt, yt in targets_E:
    a = ot.unif(Xs.shape[0])
    b = ot.unif(Xt.shape[0])
    M = ot.dist(feature_normalization(Xs),
                feature_normalization(Xt), metric='sqeuclidean')
    # M /= np.max(M)
    G = ot.emd(a, b, M)
    
    ErawX.append(eps)
    ErawY.append(np.sum(M * G))
plt.figure(figsize=(9, 5))
plt.scatter(ErawX, ErawY)
plt.ylabel('Normalized Wasserstein Distance')
plt.xlabel('Degree of Parameter Mismatch')
NrawX = []
NrawY = []
for Ni, Xt, yt in targets_N:
    a = ot.unif(Xs.shape[0])
    b = ot.unif(Xt.shape[0])
    M = ot.dist(feature_normalization(Xs),
                feature_normalization(Xt),
                metric='sqeuclidean')
    # M /= np.max(M)
    G = ot.emd(a, b, M)
    
    NrawX.append(Ni)
    NrawY.append(np.sum(M * G))
plt.figure(figsize=(9, 5))
plt.plot(NrawX, NrawY)
plt.ylabel('Normalized Wasserstein Distance')
plt.xlabel('Degree of Parameter Mismatch')<jupyter_output><empty_output><jupyter_text>Distributional Shift vs. Accuracy<jupyter_code>def experiment_distributional_shift(clf, source, targets_E, targets_N):
    accs = []
    wdists = []
    Xs, ys = source
    for param, Xt, yt in targets_E + targets_N:
        """
        for _ in range(10):
            Xtr, _, ytr, _ = train_test_split(Xs, ys, train_size=0.8, stratify=ys)
            Xts, _, yts, _ = train_test_split(Xt, yt, train_size=0.8, stratify=yt)
            wdists.append(wasserstein_distance(Xtr, Xts, norm='max', metric='sqeuclidean'))
            Xtr = feature_normalization(Xtr)
            Xts = feature_normalization(Xts)
            clf.fit(Xtr, ytr)
            yp = clf.predict(Xts)
            acc = accuracy_score(yts, yp)
            accs.append(acc)
        """
        Xtr, ytr = feature_normalization(Xs), ys.copy()
        Xts, yts = feature_normalization(Xt), yt.copy()
        dist = wasserstein_distance(Xs, Xt, norm=None, metric='cityblock')
        wdists.append(dist)
        clf.fit(Xtr, ytr)
        yp = clf.predict(Xts)
        acc = accuracy_score(yts, yp)
        accs.append(acc)
        print(param, dist, acc)
    
    return wdists, 100 * np.array(accs)
clf1 = SVC(kernel='linear', max_iter=1e+6)
clf2 = SVC(kernel='rbf', max_iter=1e+6)
clf3 = MLPClassifier(hidden_layer_sizes=(100,), activation='relu', max_iter=100)
print('Running tests on clf1')
raw_wdists, raw_accs1 = experiment_distributional_shift(clf1, (Xs, ys), targets_E, targets_N)
print('Running tests on clf2')
raw_wdists, raw_accs2 = experiment_distributional_shift(clf2, (Xs, ys), targets_E, targets_N)
print('Running tests on clf3')
raw_wdists, raw_accs3 = experiment_distributional_shift(clf3, (Xs, ys), targets_E, targets_N)
fig, ax = plt.subplots(1, 1, figsize=(9, 5))
sns.regplot(raw_wdists, raw_accs1, label='Linear SVM')
sns.regplot(raw_wdists, raw_accs2, label='RBF SVM')
sns.regplot(raw_wdists, raw_accs3, label='MLP')
ax.legend(bbox_to_anchor=(1.3, 1))<jupyter_output><empty_output><jupyter_text>ACF Features<jupyter_code>df = pd.read_csv('./data/cstr_acfmeandata.csv')

data_mat = df.values
X = data_mat[:, :-4]
y = df['Class'].values
d = df['Domain'].values

Xs, ys = X[np.where(d == 0)[0]], y[np.where(d == 0)[0]]
Xs = feature_normalization(Xs)
_X = X.copy()

dataset = np.load('./data/DistributionalShiftData/acfmean_cstr_distrshift.npy')

X = dataset[:, :-3]
y = dataset[:, -3]
E = dataset[:, -2]
N = dataset[:, -1]

targets_E = [
    (eps,
     X[np.intersect1d(np.where(E == eps)[0], np.where(N == 1))],
     y[np.intersect1d(np.where(E == eps)[0], np.where(N == 1))]) for eps in [i / 10 for i in range(1, 10)]
]

targets_N = [
    (Ni,
     X[np.intersect1d(np.where(E == 0.15)[0], np.where(N == Ni))],
     y[np.intersect1d(np.where(E == 0.15)[0], np.where(N == Ni))]) for Ni in [0.25, 0.5, 0.75, 1,
                                                                              1.25, 1.75, 2.0]
]<jupyter_output><empty_output><jupyter_text>Parameters vs. Distributional Shift<jupyter_code>EacfX = []
EacfY = []
for eps, Xt, yt in targets_E:
    a = ot.unif(Xs.shape[0])
    b = ot.unif(Xt.shape[0])
    M = ot.dist(feature_normalization(Xs), feature_normalization(Xt), metric='sqeuclidean')
    #M /= np.max(M)
    G = ot.emd(a, b, M)
    
    EacfX.append(eps)
    EacfY.append(np.sum(M * G))
plt.figure(figsize=(9, 5))
plt.plot(EacfX, EacfY)
plt.ylabel('Normalized Wasserstein Distance')
plt.xlabel('Degree of Parameter Mismatch')
NacfX = []
NacfY = []
for Ni, Xt, yt in targets_N:
    a = ot.unif(Xs.shape[0])
    b = ot.unif(Xt.shape[0])
    M = ot.dist(feature_normalization(Xs), feature_normalization(Xt), metric='sqeuclidean')
    # M /= np.max(M)
    G = ot.emd(a, b, M)
    
    NacfX.append(Ni)
    NacfY.append(np.sum(M * G))
plt.figure(figsize=(9, 5))
plt.plot(NacfX, NacfY)
plt.ylabel(r'$W_{2}(\hat{P}_{S}, \hat{P}_{T})$')
plt.xlabel('Reaction Order')<jupyter_output><empty_output><jupyter_text>Distributional Shift vs. Accuracy<jupyter_code>clf1 = SVC(kernel='linear', max_iter=1e+6)
clf2 = SVC(kernel='rbf', max_iter=1e+6)
clf3 = MLPClassifier(hidden_layer_sizes=(100,), activation='relu')

acf_wdists, acf_accs1 = experiment_distributional_shift(clf1, (Xs, ys), targets_E, targets_N)
acf_wdists, acf_accs2 = experiment_distributional_shift(clf2, (Xs, ys), targets_E, targets_N)
acf_wdists, acf_accs3 = experiment_distributional_shift(clf3, (Xs, ys), targets_E, targets_N)
fig, ax = plt.subplots(1, 1, figsize=(9, 5))
sns.regplot(acf_wdists, acf_accs1, label='Linear SVM')
sns.regplot(acf_wdists, acf_accs2, label='RBF SVM')
sns.regplot(acf_wdists, acf_accs3, label='MLP')
ax.legend(title='classifier', bbox_to_anchor=(1, 1))
fig, axes = plt.subplots(1, 2, figsize=(9, 4.5))

sns.regplot(raw_wdists, 100 - raw_accs1, label='Linear SVM', ax=axes[0], scatter_kws={'alpha':0.5})
sns.regplot(raw_wdists, 100 - raw_accs2, label='RBF SVM', ax=axes[0], scatter_kws={'alpha':0.5})
sns.regplot(raw_wdists, 100 - raw_accs3, label='MLP', ax=axes[0], scatter_kws={'alpha':0.5})
axes[0].set_xlabel('$W_{2}(\hat{P}_{S}, \hat{P}_{T})$')
axes[0].set_ylabel('$\hat{\mathcal{R}}_{T}(h)$')
axes[0].set_title('Raw Features')

sns.regplot(acf_wdists, 100 - acf_accs1, label='Linear SVM', ax=axes[1], scatter_kws={'alpha':0.5})
sns.regplot(acf_wdists, 100 - acf_accs2, label='RBF SVM', ax=axes[1], scatter_kws={'alpha':0.5})
sns.regplot(acf_wdists, 100 - acf_accs3, label='MLP', ax=axes[1], scatter_kws={'alpha':0.5})
axes[1].set_xlabel('$W_{2}(\hat{P}_{S}, \hat{P}_{T})$')
axes[1].set_ylabel('$\hat{\mathcal{R}}_{T}(h)$')
axes[1].legend(title='Classifier', bbox_to_anchor=(1, 1))
axes[1].set_title('ACF Features')

plt.tight_layout()
plt.savefig('./Figures/Ch6/DistrShiftAcc.pdf')
slope1, intercept, r_value, p_value, std_err = stats.linregress(acf_wdists, 100 - acf_accs1)
print('Regression Slope Linear SVM: {}'.format(slope1))
print('R2: {}, P: {}'.format(r_value, p_value))
slope2, intercept, r_value, p_value, std_err = stats.linregress(acf_wdists, 100 - acf_accs2)
print('Regression Slope RBF SVM: {}'.format(slope2))
print('R2: {}, P: {}'.format(r_value, p_value))
slope3, intercept, r_value, p_value, std_err = stats.linregress(acf_wdists, 100 - acf_accs3)
print('Regression Slope MLP: {}'.format(slope3))
print('R2: {}, P: {}'.format(r_value, p_value))
slope1, intercept, r_value, p_value, std_err = stats.linregress(raw_wdists, 100 - raw_accs1)
print('Regression Slope Linear SVM: {}'.format(slope1 * 10 ** 4))
print('R2: {}, P: {}'.format(r_value, p_value))
slope2, intercept, r_value, p_value, std_err = stats.linregress(raw_wdists, 100 - raw_accs2)
print('Regression Slope RBF SVM: {}'.format(slope2 * 10 ** 4))
print('R2: {}, P: {}'.format(r_value, p_value))
slope3, intercept, r_value, p_value, std_err = stats.linregress(raw_wdists, 100 - raw_accs3)
print('Regression Slope MLP: {}'.format(slope3 * 10 ** 4))
print('R2: {}, P: {}'.format(r_value, p_value))
fig, axes = plt.subplots(2, 2, figsize=(12, 8))

axes[0, 1].plot(EacfX, EacfY)
axes[0, 1].set_ylabel(r'$W_{2}(\hat{P}_{S}, \hat{P}_{T})$')
axes[0, 1].set_xlabel(r'Degree of Parameter Mismatch')
axes[0, 1].set_title('ACF Features')

axes[1, 1].plot(NacfX, NacfY)
axes[1, 1].set_ylabel(r'$W_{2}(\hat{P}_{S}, \hat{P}_{T})$')
axes[1, 1].set_xlabel(r'Reaction Order')

axes[0, 0].plot(ErawX, ErawY)
axes[0, 0].set_ylabel(r'$W_{2}(\hat{P}_{S}, \hat{P}_{T})$')
axes[0, 0].set_xlabel(r'Degree of Parameter Mismatch')
axes[0, 0].set_title('Raw Features')

axes[1, 0].plot(NrawX, NrawY)
axes[1, 0].set_ylabel(r'$W_{2}(\hat{P}_{S}, \hat{P}_{T})$')
axes[1, 0].set_xlabel(r'Reaction Order')

plt.tight_layout()
plt.savefig('./Figures/Ch6/ParametersVSDistributionalShift.pdf')<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.2035034783337524, 'fraction_numerical': 0.03394518481267287, 'mean_word_length': 4.319661168078467, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '171142', 'license': 'MIT', 'n_tokens_mistral': 5397, 'n_tokens_neox': 5079, 'n_words': 849, 'path': 'Ch5 - Distributional Shift Analysis.ipynb', 'repo_name': 'eddardd/CrossDomainFaultDetection', 'size': '11931'}