Online Resource 1 — Reproducible analysis notebook

Modifiye Al-12Si Alaşımlarının Tornalanmasında Çift Ayrışma

Yeniden üretilebilir çözümleme defteri

Bu defter, makaledeki bütün sayısal sonuçları sıfırdan üretir.

Bağımlılık yoktur. numpy, pandas, scipy, scikit-learn kullanılmaz — F dağılımı,

en küçük kareler, bootstrap, regresyon ağacı ve rastgele orman dâhil her şey

standart kütüphaneyle kodlanmıştır. Herhangi bir Python 3 kurulumunda çalışır.

Grafik hücresi (en sonda) yalnızca matplotlib varsa çalışır; yoksa atlanır.

Hücreleri sırayla çalıştırın.

Bölüm | İçerik |

|—|—|

1 | Veri (deftere gömülü) |
2 | Yardımcı fonksiyonlar |
3 | Betimsel — grup ortalamaları |
4 | Varyans analizi (Sr / CuSn5 ayrıştırmalı) |
5 | Çift ayrışma + güven aralıkları |
6 | Çoklu karşılaştırma düzeltmesi |
7 | Duyarlılık — ihtilaflı 8 değer |
8 | Taguchi S/N |
9 | Model karşılaştırması (LOOCV) |
10 | Esnek öğreniciler: ağaç, orman, k-NN |
11 | Yığıntı talaş: κ, korelasyon, şartlı ilişki (attenuation) |
12 | Grafikler (matplotlib, isteğe bağlı) |

1. Veri

36 deney, 4 malzeme × 3 kesme hızı × 3 ilerleme. Sütunlar:

VERI = """deney,grup,Vc,f_mm,Ff_N,Fc,Fc_alt,Ra,Ra_P1,Ra_P2,Ra_P3,BUE,ihtilafli

1,A,135.0,0.08,2.9,2.2,2.2,0.86,0.8,0.72,1.06,1,0

2,A,135.0,0.16,2.4,5.4,5.4,1.753,1.7,1.8,1.76,2,0

3,A,135.0,0.32,8.6,22.7,22.7,3.16,2.7,3.45,3.33,3,0

4,A,95.0,0.08,4.2,4.7,4.7,0.711,0.613,0.7,0.82,1,0

5,A,95.0,0.16,7.0,15.2,15.2,1.563,1.6,1.5,1.59,2,0

6,A,95.0,0.32,10.0,33.9,33.9,3.89,3.96,3.69,4.02,3,0

7,A,35.0,0.08,7.1,11.2,11.2,1.49,1.58,1.26,1.63,1,0

8,A,35.0,0.16,9.7,21.8,21.8,1.85,1.87,1.8,1.88,1,0

9,A,35.0,0.32,18.7,53.2,53.2,3.553,4.13,2.97,3.56,3,0

10,B,135.0,0.08,5.8,10.7,10.7,3.527,3.52,3.58,3.48,2,0

11,B,135.0,0.16,9.1,22.1,22.1,3.227,3.68,2.47,3.53,3,0

12,B,135.0,0.32,9.9,29.4,34.4,4.337,3.9,5.49,3.62,3,1

13,B,95.0,0.08,6.4,11.6,11.6,3.367,4.0,3.24,2.86,2,0

14,B,95.0,0.16,7.3,24.7,16.4,3.38,3.9,3.58,2.66,1,1

15,B,95.0,0.32,9.5,30.8,30.8,4.047,4.34,3.78,4.02,3,0

16,B,35.0,0.08,4.9,13.5,13.5,4.247,4.41,3.94,4.39,2,0

17,B,35.0,0.16,9.8,26.2,26.2,4.46,2.67,5.49,5.22,2,0

18,B,35.0,0.32,8.7,31.6,31.6,4.283,4.5,3.51,4.84,3,0

19,C,135.0,0.08,11.8,13.3,13.3,0.798,0.8,0.744,0.85,2,0

20,C,135.0,0.16,10.3,21.9,21.9,1.71,1.68,1.72,1.73,2,0

21,C,135.0,0.32,13.4,42.4,42.4,3.647,3.21,3.31,4.42,1,0

22,C,95.0,0.08,13.0,23.0,17.1,0.96,0.97,1.05,0.86,2,1

23,C,95.0,0.16,13.1,28.4,23.0,1.837,2.05,1.75,1.71,2,1

24,C,95.0,0.32,12.4,45.6,31.4,3.853,3.93,4.03,3.6,2,1

25,C,35.0,0.08,11.7,24.8,18.8,2.378,2.03,3.044,2.06,1,1

26,C,35.0,0.16,21.5,30.7,30.7,2.265,1.996,2.83,1.97,1,0

27,C,35.0,0.32,28.7,53.8,53.8,2.973,3.67,2.65,2.6,3,0

28,D,135.0,0.08,7.4,13.7,14.7,3.183,3.1,3.26,3.19,1,1

29,D,135.0,0.16,9.6,21.9,21.9,2.82,2.84,2.61,3.01,2,0

30,D,135.0,0.32,16.0,32.4,41.0,3.501,3.73,3.593,3.18,3,1

31,D,95.0,0.08,7.7,14.1,14.1,2.743,2.6,2.906,2.723,3,0

32,D,95.0,0.16,13.2,24.7,24.7,2.94,2.95,3.54,2.33,3,0

33,D,95.0,0.32,15.6,37.7,37.7,3.875,4.511,3.903,3.21,3,0

34,D,35.0,0.08,8.0,15.3,15.3,5.143,5.52,4.83,5.08,2,0

35,D,35.0,0.16,14.4,33.0,33.0,3.426,3.555,3.696,3.027,3,0

36,D,35.0,0.32,24.7,57.3,57.3,4.69,3.87,5.37,4.83,3,0"""



import csv, io, math, random



rows = list(csv.DictReader(io.StringIO(VERI)))

for r in rows:

    for k in ('Vc','f_mm','Ff_N','Fc','Fc_alt','Ra','Ra_P1','Ra_P2','Ra_P3','BUE'):

        r[k] = float(r[k])

    r['ihtilafli'] = r['ihtilafli'] == '1'

    r['cu'] = 1.0 if r['grup'] in ('B','D') else 0.0   # CuSn5 var mi

    r['sr'] = 1.0 if r['grup'] in ('C','D') else 0.0   # Al10Sr var mi

    r['FfFc'] = r['Ff_N'] / r['Fc']



GR  = ['A','B','C','D']

AD  = {'A':'Modifiyesiz','B':'CuSn5','C':'Al10Sr','D':'Al10Sr+CuSn5'}

print(f'{len(rows)} deney yuklendi.  Ihtilafli satir: {sum(r["ihtilafli"] for r in rows)}')

print('Gruplar:', {g: sum(1 for r in rows if r['grup']==g) for g in GR})

Çıktı:

36 deney yuklendi.  Ihtilafli satir: 8
Gruplar: {'A': 9, 'B': 9, 'C': 9, 'D': 9}

2. Yardımcı fonksiyonlar

En küçük kareler (Gauss-Jordan), F dağılımı kuyruk olasılığı (eksik beta fonksiyonu ile), Spearman ve Pearson korelasyonu, LOOCV.

def ols(X, y):

    """En kucuk kareler katsayilari. X: satir listesi (sabit terim dahil)."""

    n, k = len(X), len(X[0])

    A = [[sum(X[r][i]*X[r][j] for r in range(n)) for j in range(k)] +

         [sum(X[r][i]*y[r] for r in range(n))] for i in range(k)]

    for c in range(k):

        p = max(range(c, k), key=lambda r: abs(A[r][c]))

        if abs(A[p][c]) < 1e-12: return None

        A[c], A[p] = A[p], A[c]

        pv = A[c][c]; A[c] = [v/pv for v in A[c]]

        for r in range(k):

            if r != c and A[r][c]:

                f = A[r][c]; A[r] = [a - f*b for a, b in zip(A[r], A[c])]

    return [A[i][k] for i in range(k)]



def fitted(X, y):

    b = ols(X, y)

    return [sum(c*v for c, v in zip(b, x)) for x in X]



def rss(X, y):

    b = ols(X, y)

    if b is None: return None

    return sum((yi - sum(c*x for c, x in zip(b, xi)))**2 for xi, yi in zip(X, y))



# ---- F dagilimi kuyruk olasiligi (eksik beta fonksiyonu)

def _betacf(a, b, x):

    c, d = 1.0, 1 - (a+b)*x/(a+1)

    d = 1/(d if abs(d) > 1e-300 else 1e-300); h = d

    for m in range(1, 300):

        m2 = 2*m

        aa = m*(b-m)*x/((a-1+m2)*(a+m2)); d = 1/(1+aa*d); c = 1+aa/c; h *= d*c

        aa = -(a+m)*(a+b+m)*x/((a+m2)*(a+1+m2)); d = 1/(1+aa*d); c = 1+aa/c

        de = d*c; h *= de

        if abs(de-1) < 3e-12: break

    return h



def betai(a, b, x):

    if x <= 0: return 0.0

    if x >= 1: return 1.0

    bt = math.exp(math.lgamma(a+b) - math.lgamma(a) - math.lgamma(b)

                  + a*math.log(x) + b*math.log(1-x))

    return bt*_betacf(a,b,x)/a if x < (a+1)/(a+b+2) else 1 - bt*_betacf(b,a,1-x)/b



def f_p(F, d1, d2):

    """F dagiliminda ust kuyruk olasiligi."""

    return betai(d2/2, d1/2, d2/(d2 + d1*F)) if F > 0 else 1.0



def kismi_F(Xr, Xf, y):

    """Ic ice modeller icin kismi F sinamasi. -> (F, p, df1, df2)"""

    r0, r1 = rss(Xr, y), rss(Xf, y)

    d1 = len(Xf[0]) - len(Xr[0]); d2 = len(y) - len(Xf[0])

    F = ((r0-r1)/d1) / (r1/d2)

    return F, f_p(F, d1, d2), d1, d2



def pearson(a, b):

    n = len(a); ma, mb = sum(a)/n, sum(b)/n

    num = sum((x-ma)*(y-mb) for x, y in zip(a, b))

    den = math.sqrt(sum((x-ma)**2 for x in a) * sum((y-mb)**2 for y in b))

    r = num/den

    t = r*math.sqrt((n-2)/(1-r**2)) if abs(r) < 1 else float('inf')

    return r, f_p(t*t, 1, n-2)



def spearman(a, b):

    def rank(v):

        s = sorted(range(len(v)), key=lambda i: v[i]); r = [0]*len(v); i = 0

        while i < len(s):

            j = i

            while j+1 < len(s) and v[s[j+1]] == v[s[i]]: j += 1

            avg = (i+j)/2 + 1

            for k in range(i, j+1): r[s[k]] = avg

            i = j+1

        return r

    return pearson(rank(a), rank(b))



def loocv(fit, pred, X, y):

    """Birak-birini-disarida capraz dogrulama -> RMSE"""

    tot = 0.0

    for i in range(len(y)):

        Xt = [x for j, x in enumerate(X) if j != i]

        yt = [v for j, v in enumerate(y) if j != i]

        tot += (y[i] - pred(fit(Xt, yt), X[i]))**2

    return math.sqrt(tot/len(y))



def loocv_ols(X, y):

    return loocv(lambda A, b: ols(A, b),

                 lambda m, x: sum(c*v for c, v in zip(m, x)), X, y)



def r2(X, y):

    yh = fitted(X, y); m = sum(y)/len(y)

    return 1 - sum((a-b)**2 for a, b in zip(yh, y)) / sum((v-m)**2 for v in y)



print('Yardimci fonksiyonlar hazir.')

Çıktı:

Yardimci fonksiyonlar hazir.

3. Grup ortalamaları

Makaledeki Tablo 8’in kaynağı.

print(f'{"Grup":<16}{"Fc (N)":>9}{"Ff (N)":>9}{"Ff/Fc":>9}{"Ra (um)":>10}{"BUE":>7}')

for g in GR:

    s = [r for r in rows if r['grup'] == g]; n = len(s)

    print(f'{g+" - "+AD[g]:<16}'

          f'{sum(r["Fc"] for r in s)/n:9.1f}'

          f'{sum(r["Ff_N"] for r in s)/n:9.1f}'

          f'{sum(r["FfFc"] for r in s)/n:9.3f}'

          f'{sum(r["Ra"] for r in s)/n:10.2f}'

          f'{sum(r["BUE"] for r in s)/n:7.2f}')



print()

for ad, f in [('CuSn5 var  (B,D)', lambda r: r['cu']==1), ('CuSn5 yok  (A,C)', lambda r: r['cu']==0),

              ('Sr var     (C,D)', lambda r: r['sr']==1), ('Sr yok     (A,B)', lambda r: r['sr']==0)]:

    s = [r for r in rows if f(r)]; n = len(s)

    print(f'{ad:<18} Fc={sum(r["Fc"] for r in s)/n:5.1f}   '

          f'Ra={sum(r["Ra"] for r in s)/n:5.2f}   BUE={sum(r["BUE"] for r in s)/n:.2f}')

Çıktı:

Grup               Fc (N)   Ff (N)    Ff/Fc   Ra (um)    BUE
A - Modifiyesiz      18.9      7.8    0.580      2.09   1.89
B - CuSn5            22.3      7.9    0.384      3.88   2.33
C - Al10Sr           31.5     15.1    0.520      2.27   1.78
D - Al10Sr+CuSn5     27.8     13.0    0.484      3.59   2.56

CuSn5 var  (B,D)   Fc= 25.0   Ra= 3.73   BUE=2.44
CuSn5 yok  (A,C)   Fc= 25.2   Ra= 2.18   BUE=1.83
Sr var     (C,D)   Fc= 29.7   Ra= 2.93   BUE=2.17
Sr yok     (A,B)   Fc= 20.6   Ra= 2.98   BUE=2.11

4. Varyans analizi

Malzeme faktörünün 3 serbestlik derecesi Sr, CuSn5 ve Sr×CuSn5 bileşenlerine ayrıştırılır. Tasarım dengeli olduğu için bileşenler ortogonaldir.

Deneysel birim. Her iki yanıt da koşu düzeyinde (n = 36) çözümlenir. Ra için her koşudan alınan üç okuma, aynı işlenmiş yüzeyin tekrarlı ölçümleridir — bağımsız deney tekrarı değildir. Bunları bağımsız saymak hata serbestlik derecesini şişirir ve F testlerini olduğundan hassas gösterir. Bu nedenle üç okuma önce ortalanır; hata terimi her iki yanıtta da yüksek dereceli etkileşimlerin havuzlanmasıyla elde edilir (sd = 16).

Üç okuma yalnızca ölçüm hassasiyetini nitelemek için kullanılır.

Karşılaştırma amacıyla, 108 bireysel okuma üzerinden saf hata terimiyle (sd = 72) yapılan çözümleme de hesaplanır ve yalnızca duyarlılık karşılaştırması olarak raporlanır. Makalede birincil olan koşu düzeyi çözümlemedir.

import itertools

def anova(rows, ykey, reps=None):
    """reps=None -> kosu duzeyi (n=36, havuzlanmis hata)  [BIRINCIL]
       reps=liste -> okuma duzeyi (n=108, saf hata)       [yalnizca karsilastirma]"""
    obs = [(r, r[k]) for r in rows for k in reps] if reps else [(r, r[ykey]) for r in rows]
    N = len(obs); gm = sum(o[1] for o in obs)/N
    SST = sum((o[1]-gm)**2 for o in obs)
    fak = ['sr','cu','Vc','f_mm']
    isim = {'sr':'Sr','cu':'CuSn5','Vc':'Kesme hizi','f_mm':'Ilerleme'}
    def cellSS(ks):
        c = {}
        for r, v in obs: c.setdefault(tuple(r[k] for k in ks), []).append(v)
        return sum(len(v)*(sum(v)/len(v)-gm)**2 for v in c.values()), len(c)
    terms = []; main = {}
    for f in fak:
        ss, nc = cellSS([f]); main[f] = (ss, nc-1); terms.append((isim[f], ss, nc-1))
    for a, b in itertools.combinations(fak, 2):
        ss, _ = cellSS([a, b])
        terms.append((f'{isim[a]} x {isim[b]}', ss-main[a][0]-main[b][0], main[a][1]*main[b][1]))
    if reps:
        SSE = 0.0; dfe = 0
        for r in rows:
            v = [r[k] for k in reps]; m = sum(v)/len(v)
            SSE += sum((x-m)**2 for x in v); dfe += len(v)-1
        SSmod = sum(t[1] for t in terms); dfmod = sum(t[2] for t in terms)
        terms.append(('Artik (yuksek dereceli)', SST-SSmod-SSE, N-1-dfmod-dfe))
        errSS, errdf, errad = SSE, dfe, 'Saf hata (olcum)'
    else:
        SSmod = sum(t[1] for t in terms); dfmod = sum(t[2] for t in terms)
        errSS, errdf, errad = SST-SSmod, N-1-dfmod, 'Hata (havuzlanmis)'
    MSE = errSS/errdf
    out = []
    for ad, ss, df in terms:
        if ad.startswith('Artik'):
            out.append((ad, ss, df, ss/df, None, None, 100*ss/SST)); continue
        F = (ss/df)/MSE
        out.append((ad, ss, df, ss/df, F, f_p(F, df, errdf), 100*ss/SST))
    out.append((errad, errSS, errdf, MSE, None, None, 100*errSS/SST))
    return sorted(out, key=lambda t: -t[6]), SST

def yaz(baslik, out, SST):
    print('='*88); print(baslik); print('='*88)
    print(f'{"Kaynak":<26}{"KT":>10}{"sd":>5}{"KO":>10}{"F":>9}{"p":>11}{"Toplam KT payi %":>18}')
    for a, ss, df, ms, F, p, k in out:
        print(f'{a:<26}{ss:10.2f}{df:5d}{ms:10.3f}'
              f'{(f"{F:9.2f}" if F else " "*9)}{(f"{p:11.6f}" if p is not None else " "*11)}{k:18.1f}')
    print(f'{"TOPLAM":<26}{SST:10.2f}')
    print()

# ===== BIRINCIL: her iki yanit da kosu duzeyi (makale Tablo 5 ve Tablo 6) =====
for ykey, baslik in [('Fc','KESME KUVVETI Fc (N)  -  kosu duzeyi, n=36, havuzlanmis hata sd=16   [Tablo 5]'),
                     ('Ra','YUZEY PURUZLULUGU Ra (um)  -  kosu duzeyi, n=36, havuzlanmis hata sd=16   [Tablo 6]')]:
    out, SST = anova(rows, ykey, None)
    yaz(baslik, out, SST)

# ===== OLCUM HASSASIYETI (uc okumanin tek kullanimi) =====
ic = []
for r in rows:
    v = [r['Ra_P1'], r['Ra_P2'], r['Ra_P3']]; m = sum(v)/3
    ic.append(math.sqrt(sum((x-m)**2 for x in v)/2))
ort = sum(r['Ra'] for r in rows)/len(rows)
arasi = math.sqrt(sum((r['Ra']-ort)**2 for r in rows)/(len(rows)-1))
print('OLCUM HASSASIYETI')
print(f'  Kosu ici standart sapma ortalamasi : {sum(ic)/len(ic):.3f} um')
print(f'  Kosular arasi standart sapma       : {arasi:.3f} um')
print()

# ===== DUYARLILIK KARSILASTIRMASI — makalede BIRINCIL DEGIL =====
out, SST = anova(rows, 'Ra', ['Ra_P1','Ra_P2','Ra_P3'])
yaz('[KARSILASTIRMA] Ra - 108 okuma, saf hata sd=72  ->  MAKALEDE KULLANILMAZ', out, SST)
print('NOT: Okuma duzeyi cozumleme iki ikincil etkilesimi anlamli gosterir')
print('     (CuSn5 x Kesme hizi p=0.012 ; Sr x CuSn5 p=0.020).')
print('     Kosu duzeyinde ikisi de p=0.062 olup anlamli degildir.')
print('     Makale muhafazakar olan kosu duzeyi sonucunu esas alir.')

Çıktı:

========================================================================================
KESME KUVVETI Fc (N)  -  kosu duzeyi, n=36, havuzlanmis hata sd=16   [Tablo 5]
========================================================================================
Kaynak                            KT   sd        KO        F          p  Toplam KT payi %
Ilerleme                     4156.35    2  2078.177    90.85   0.000000              63.6
Kesme hizi                    758.06    2   379.030    16.57   0.000126              11.6
Sr                            738.93    1   738.934    32.30   0.000034              11.3
Hata (havuzlanmis)            365.98   16    22.874                                   5.6
CuSn5 x Ilerleme              158.20    2    79.100     3.46   0.056471               2.4
Kesme hizi x Ilerleme         149.07    4    37.268     1.63   0.215480               2.3
Sr x CuSn5                    114.13    1   114.134     4.99   0.040125               1.7
CuSn5 x Kesme hizi             74.25    2    37.125     1.62   0.228152               1.1
Sr x Ilerleme                  22.97    2    11.487     0.50   0.614436               0.4
Sr x Kesme hizi                 1.16    2     0.580     0.03   0.974990               0.0
CuSn5                           0.34    1     0.340     0.01   0.904443               0.0
TOPLAM                       6539.46

========================================================================================
YUZEY PURUZLULUGU Ra (um)  -  kosu duzeyi, n=36, havuzlanmis hata sd=16   [Tablo 6]
========================================================================================
Kaynak                            KT   sd        KO        F          p  Toplam KT payi %
CuSn5                          21.69    1    21.692   182.52   0.000000              43.6
Ilerleme                       13.47    2     6.734    56.66   0.000000              27.0
CuSn5 x Ilerleme                5.37    2     2.687    22.61   0.000022              10.8
Kesme hizi                      3.50    2     1.748    14.71   0.000237               7.0
Kesme hizi x Ilerleme           2.13    4     0.532     4.48   0.012828               4.3
Hata (havuzlanmis)              1.90   16     0.119                                   3.8
CuSn5 x Kesme hizi              0.79    2     0.394     3.32   0.062404               1.6
Sr x CuSn5                      0.48    1     0.477     4.02   0.062316               1.0
Sr x Ilerleme                   0.23    2     0.115     0.97   0.401595               0.5
Sr x Kesme hizi                 0.22    2     0.112     0.94   0.410113               0.4
Sr                              0.03    1     0.026     0.22   0.647806               0.1
TOPLAM                         49.81

OLCUM HASSASIYETI
  Kosu ici standart sapma ortalamasi : 0.386 um
  Kosular arasi standart sapma       : 1.193 um

========================================================================================
[KARSILASTIRMA] Ra - 108 okuma, saf hata sd=72  ->  MAKALEDE KULLANILMAZ
========================================================================================
Kaynak                            KT   sd        KO        F          p  Toplam KT payi %
CuSn5                          65.06    1    65.064   256.67   0.000000              38.8
Ilerleme                       40.41    2    20.203    79.70   0.000000              24.1
Saf hata (olcum)               18.25   72     0.253                                  10.9
CuSn5 x Ilerleme               16.12    2     8.062    31.80   0.000000               9.6
Kesme hizi                     10.49    2     5.247    20.70   0.000000               6.3
Kesme hizi x Ilerleme           6.38    4     1.596     6.30   0.000211               3.8
Artik (yuksek dereceli)         5.70   16     0.357                                   3.4
CuSn5 x Kesme hizi              2.37    2     1.183     4.67   0.012442               1.4
Sr x CuSn5                      1.43    1     1.430     5.64   0.020213               0.9
Sr x Ilerleme                   0.69    2     0.345     1.36   0.262738               0.4
Sr x Kesme hizi                 0.67    2     0.336     1.33   0.271816               0.4
Sr                              0.08    1     0.077     0.30   0.583080               0.0
TOPLAM                        167.66

NOT: Okuma duzeyi cozumleme iki ikincil etkilesimi anlamli gosterir
     (CuSn5 x Kesme hizi p=0.012 ; Sr x CuSn5 p=0.020).
     Kosu duzeyinde ikisi de p=0.062 olup anlamli degildir.
     Makale muhafazakar olan kosu duzeyi sonucunu esas alir.

5. Çift ayrışma ve güven aralıkları

Makalenin ana bulgusu. İki sınama ailesi:

  1. Her etkenin her çıktı üzerindeki kısmi F sınaması

  2. Etki büyüklükleri için bootstrap %95 güven aralığı — boş etkilere üst sınır koyar

def etki_F(data, hedef, ekle):

    y = [r[hedef] for r in data]

    base = [[1, r['Vc'], r['f_mm']] for r in data]

    full = [b+[r[ekle]] for b, r in zip(base, data)]

    return kismi_F(base, full, y)



def etki_katsayi(data, hedef, which):

    X = [[1, r['Vc'], r['f_mm'], r['cu'], r['sr']] for r in data]

    b = ols(X, [r[hedef] for r in data])

    return None if b is None else b[3 if which == 'cu' else 4]



print('KISMI F SINAMALARI  (kontrol: Vc, ilerleme)')

print('-'*62)

for hedef in ('Fc','Ra','BUE'):

    for w, ad in (('sr','Sr'), ('cu','CuSn5')):

        F, p, d1, d2 = etki_F(rows, hedef, w)

        yildiz = '***' if p < 0.001 else '**' if p < 0.01 else '*' if p < 0.05 else ''

        print(f'  {ad:<6} -> {hedef:<4}  F({d1},{d2}) = {F:7.2f}   p = {p:.6f} {yildiz}')



print()

print('BOOTSTRAP %95 GUVEN ARALIKLARI  (B = 4000)')

print('-'*74)

rnd = random.Random(20260810); B = 4000

print(f'{"Cikti":<8}{"Etken":<8}{"Etki":>9}{"GA alt":>10}{"GA ust":>10}   Sifir')

GA = {}

for hedef in ('Fc','Ra','BUE'):

    for w, ad in (('sr','Sr'), ('cu','CuSn5')):

        nokta = etki_katsayi(rows, hedef, w); boot = []

        for _ in range(B):

            d = [rows[rnd.randrange(len(rows))] for _ in rows]

            v = etki_katsayi(d, hedef, w)

            if v is not None: boot.append(v)

        boot.sort()

        lo, hi = boot[int(0.025*len(boot))], boot[int(0.975*len(boot))]

        GA[(hedef, w)] = (nokta, lo, hi)

        print(f'{hedef:<8}{ad:<8}{nokta:>9.3f}{lo:>10.3f}{hi:>10.3f}   '

              f'{"DISARIDA" if lo*hi > 0 else "iceride"}')



print()

print('BOS ETKILERIN SINIRI')

print('-'*74)

for hedef, bos, gercek in (('Fc','cu','sr'), ('Ra','sr','cu'), ('BUE','sr','cu')):

    nb, lb, hb = GA[(hedef, bos)]; nv, _, _ = GA[(hedef, gercek)]

    ust = max(abs(lb), abs(hb))

    print(f'  {hedef:<4}: bos etkinin ust siniri {ust:.3f}  =  gercek etkinin %{100*ust/abs(nv):.0f}\'i')

print()

print('  -> Fc ve Ra icin bu oran %50\'nin altinda: ayrisma saglam.')

print('  -> BUE icin %78: bos sonuc sinirlandirilamiyor, ayrisma iddia edilemez.')

Çıktı:

KISMI F SINAMALARI  (kontrol: Vc, ilerleme)
--------------------------------------------------------------
  Sr     -> Fc    F(1,32) =   26.38   p = 0.000013 ***
  CuSn5  -> Fc    F(1,32) =    0.01   p = 0.935468 
  Sr     -> Ra    F(1,32) =    0.02   p = 0.877084 
  CuSn5  -> Ra    F(1,32) =   56.69   p = 0.000000 ***
  Sr     -> BUE   F(1,32) =    0.06   p = 0.808547 
  CuSn5  -> BUE   F(1,32) =    9.31   p = 0.004565 **

BOOTSTRAP %95 GUVEN ARALIKLARI  (B = 4000)
--------------------------------------------------------------------------
Cikti   Etken        Etki    GA alt    GA ust   Sifir
Fc      Sr          9.061     5.407    12.540   DISARIDA
Fc      CuSn5      -0.194    -3.733     3.646   iceride
Ra      Sr         -0.054    -0.456     0.355   iceride
Ra      CuSn5       1.552     1.122     1.983   DISARIDA
BUE     Sr          0.056    -0.338     0.474   iceride
BUE     CuSn5       0.611     0.223     1.015   DISARIDA

BOS ETKILERIN SINIRI
--------------------------------------------------------------------------
  Fc  : bos etkinin ust siniri 3.733  =  gercek etkinin %41'i
  Ra  : bos etkinin ust siniri 0.456  =  gercek etkinin %29'i
  BUE : bos etkinin ust siniri 0.474  =  gercek etkinin %78'i

  -> Fc ve Ra icin bu oran %50'nin altinda: ayrisma saglam.
  -> BUE icin %78: bos sonuc sinirlandirilamiyor, ayrisma iddia edilemez.

6. Çoklu karşılaştırma düzeltmesi

Birincil aile = 2 etken × 3 çıktı = 6 sınama.

aile = []

for hedef in ('Fc','Ra','BUE'):

    for w, ad in (('sr','Sr'), ('cu','CuSn5')):

        F, p, _, _ = etki_F(rows, hedef, w)

        aile.append((f'{ad} -> {hedef}', F, p))

m = len(aile)

print(f'{"Sinama":<16}{"F":>9}{"ham p":>12}{"Bonferroni":>13}{"BH q":>12}  Sonuc')

for i, (ad, F, p) in enumerate(sorted(aile, key=lambda t: t[2]), 1):

    bonf = min(1.0, p*m); bh = min(1.0, p*m/i)

    print(f'{ad:<16}{F:9.2f}{p:12.2e}{bonf:13.2e}{bh:12.2e}  '

          f'{"anlamli" if bonf < 0.05 else "-"}')

Çıktı:

Sinama                  F       ham p   Bonferroni        BH q  Sonuc
CuSn5 -> Ra         56.69    1.42e-08     8.53e-08    8.53e-08  anlamli
Sr -> Fc            26.38    1.34e-05     8.03e-05    4.02e-05  anlamli
CuSn5 -> BUE         9.31    4.56e-03     2.74e-02    9.13e-03  anlamli
Sr -> BUE            0.06    8.09e-01     1.00e+00    1.00e+00  -
Sr -> Ra             0.02    8.77e-01     1.00e+00    1.00e+00  -
CuSn5 -> Fc          0.01    9.35e-01     1.00e+00    9.35e-01  -

7. Duyarlılık — ihtilaflı 8 kuvvet değeri

Kesme kuvveti değerlerinden 8’i için iki farklı kayıt var. Ana bulgu üç varyantta sınanır.

varyant = [('Tez degerleri (n=36)',            rows, 'Fc'),

           ('Alternatif kayit (n=36)',         rows, 'Fc_alt'),

           ('Ihtilafli 8 nokta haric (n=28)',  [r for r in rows if not r['ihtilafli']], 'Fc')]

print(f'{"Varyant":<32}{"Sr->Fc":>9}{"p":>10}{"CuSn5->Fc":>12}{"p":>8}')

for ad, data, fk in varyant:

    d = [dict(r, Fc=r[fk]) for r in data]

    print(f'{ad:<32}{etki_katsayi(d,"Fc","sr"):>9.2f}{etki_F(d,"Fc","sr")[1]:>10.5f}'

          f'{etki_katsayi(d,"Fc","cu"):>12.2f}{etki_F(d,"Fc","cu")[1]:>8.3f}')

print()

print(f'{"Varyant":<32}{"CuSn5->Ra":>12}{"p":>11}{"Sr->Ra":>9}{"p":>8}')

for ad, data, fk in varyant:

    print(f'{ad:<32}{etki_katsayi(data,"Ra","cu"):>12.2f}{etki_F(data,"Ra","cu")[1]:>11.7f}'

          f'{etki_katsayi(data,"Ra","sr"):>9.2f}{etki_F(data,"Ra","sr")[1]:>8.3f}')

print()

print('-> Ayrisma her varyantta korunuyor.')

Çıktı:

Varyant                            Sr->Fc         p   CuSn5->Fc       p
Tez degerleri (n=36)                 9.06   0.00001       -0.19   0.935
Alternatif kayit (n=36)              8.03   0.00009        1.91   0.405
Ihtilafli 8 nokta haric (n=28)       8.92   0.00028        0.61   0.489

Varyant                            CuSn5->Ra          p   Sr->Ra       p
Tez degerleri (n=36)                    1.55  0.0000000    -0.05   0.877
Alternatif kayit (n=36)                 1.55  0.0000000    -0.05   0.877
Ihtilafli 8 nokta haric (n=28)          1.65  0.0000009    -0.12   0.759

-> Ayrisma her varyantta korunuyor.

8. Taguchi sinyal/gürültü çözümlemesi

S/N = -10 log10( ortalama(y^2) ) — kucuk daha iyi.

def sn(v): return -10*math.log10(sum(x*x for x in v)/len(v))



for hedef in ('Fc','Ra'):

    print('='*58); print(f'{hedef}'); print('='*58)

    for fad, key, sevs in [('Malzeme','grup',GR), ('Kesme hizi','Vc',[35.0,95.0,135.0]),

                           ('Ilerleme','f_mm',[0.08,0.16,0.32])]:

        vals = [(s, sum(r[hedef] for r in rows if r[key]==s)/len([r for r in rows if r[key]==s]),

                 sn([r[hedef] for r in rows if r[key]==s])) for s in sevs]

        delta = max(v[2] for v in vals) - min(v[2] for v in vals)

        best  = max(vals, key=lambda t: t[2])[0]

        print(f'  {fad:<12} delta = {delta:5.2f} dB   optimum: {best}')

        for s, m, q in vals:

            print(f'      {str(s):<8} ortalama={m:7.2f}   S/N={q:7.2f}')

    print()

Çıktı:

==========================================================
Fc
==========================================================
  Malzeme      delta =  3.12 dB   optimum: B
      A        ortalama=  18.92   S/N= -27.77
      B        ortalama=  22.29   S/N= -27.47
      C        ortalama=  31.54   S/N= -30.59
      D        ortalama=  27.79   S/N= -29.78
  Kesme hizi   delta =  3.66 dB   optimum: 135.0
      35.0     ortalama=  31.03   S/N= -30.78
      95.0     ortalama=  24.53   S/N= -28.62
      135.0    ortalama=  19.84   S/N= -27.12
  Ilerleme     delta =  8.95 dB   optimum: 0.08
      0.08     ortalama=  13.17   S/N= -23.23
      0.16     ortalama=  23.00   S/N= -27.61
      0.32     ortalama=  39.23   S/N= -32.18

==========================================================
Ra
==========================================================
  Malzeme      delta =  4.37 dB   optimum: A
      A        ortalama=   2.09   S/N=  -7.46
      B        ortalama=   3.88   S/N= -11.83
      C        ortalama=   2.27   S/N=  -7.91
      D        ortalama=   3.59   S/N= -11.31
  Kesme hizi   delta =  1.77 dB   optimum: 135.0
      35.0     ortalama=   3.40   S/N= -11.09
      95.0     ortalama=   2.76   S/N=  -9.52
      135.0    ortalama=   2.71   S/N=  -9.32
  Ilerleme     delta =  2.93 dB   optimum: 0.16
      0.08     ortalama=   2.45   S/N=  -9.06
      0.16     ortalama=   2.60   S/N=  -8.77
      0.32     ortalama=   3.82   S/N= -11.70

9. Model karşılaştırması

R² ve LOOCV birlikte. n = 36’da R² tek başına yanıltıcıdır.

def tasarim(rows, tur, ek):

    if tur == 'lin':

        X = [[1, r['Vc'], r['f_mm']] for r in rows]

    else:

        X = [[1, r['Vc'], r['f_mm'], r['Vc']**2, r['f_mm']**2, r['Vc']*r['f_mm']] for r in rows]

    for r, x in zip(rows, X):

        if 'cs'  in ek: x += [r['cu'], r['sr']]

        if 'dum' in ek: x += [1 if r['grup']==g else 0 for g in GR[1:]]

        if 'cxf' in ek: x += [r['cu']*r['f_mm']]

    return X



MOD = [('Dogrusal (V, f)',                'lin', []),

       ('Dogrusal + Sr + CuSn5',          'lin', ['cs']),

       ('Dogrusal + malzeme kuklalari',   'lin', ['dum']),

       ('Dogrusal + Sr + CuSn5 + CuSn5xf','lin', ['cs','cxf']),

       ('Ikinci derece (RSM)',            'rsm', []),

       ('RSM + Sr + CuSn5',               'rsm', ['cs']),

       ('RSM + malzeme kuklalari',        'rsm', ['dum']),

       ('RSM + Sr + CuSn5 + CuSn5xf',     'rsm', ['cs','cxf'])]



for hedef in ('Fc','Ra'):

    y = [r[hedef] for r in rows]

    print('='*72); print(f'{hedef}'); print('='*72)

    print(f'{"Model":<34}{"p":>4}{"R2":>9}{"LOOCV":>10}')

    en_iyi = None

    for ad, tur, ek in MOD:

        X = tasarim(rows, tur, ek); lo = loocv_ols(X, y)

        print(f'{ad:<34}{len(X[0]):>4}{r2(X,y):9.3f}{lo:10.3f}')

        if en_iyi is None or lo < en_iyi[1]: en_iyi = (ad, lo)

    print(f'  --> en dusuk LOOCV: {en_iyi[0]}  ({en_iyi[1]:.3f})')

    print()



print('USTEL YASA MODELLERI')

for hedef in ('Fc','Ra'):

    X = [[1, math.log(r['Vc']), math.log(r['f_mm'])] for r in rows]

    b = ols(X, [math.log(r[hedef]) for r in rows])

    print(f'  {hedef} = {math.exp(b[0]):.4g} * V^({b[1]:+.3f}) * f^({b[2]:+.3f})')

Çıktı:

========================================================================
Fc
========================================================================
Model                                p       R2     LOOCV
Dogrusal (V, f)                      3    0.750     7.442
Dogrusal + Sr + CuSn5                5    0.863     5.881
Dogrusal + malzeme kuklalari         6    0.880     5.739
Dogrusal + Sr + CuSn5 + CuSn5xf      6    0.874     5.878
Ikinci derece (RSM)                  6    0.772     7.846
RSM + Sr + CuSn5                     8    0.885     5.996
RSM + malzeme kuklalari              9    0.903     5.829
RSM + Sr + CuSn5 + CuSn5xf           9    0.896     5.963
  --> en dusuk LOOCV: Dogrusal + malzeme kuklalari  (5.739)

========================================================================
Ra
========================================================================
Model                                p       R2     LOOCV
Dogrusal (V, f)                      3    0.319     1.063
Dogrusal + Sr + CuSn5                5    0.755     0.684
Dogrusal + malzeme kuklalari         6    0.764     0.695
Dogrusal + Sr + CuSn5 + CuSn5xf      6    0.858     0.540
Ikinci derece (RSM)                  6    0.364     1.130
RSM + Sr + CuSn5                     8    0.800     0.681
RSM + malzeme kuklalari              9    0.810     0.692
RSM + Sr + CuSn5 + CuSn5xf           9    0.904     0.496
  --> en dusuk LOOCV: RSM + Sr + CuSn5 + CuSn5xf  (0.496)

USTEL YASA MODELLERI
  Fc = 524.7 * V^(-0.375) * f^(+0.871)
  Ra = 16.17 * V^(-0.220) * f^(+0.466)

10. Esnek öğreniciler

Regresyon ağacı (CART), rastgele orman ve k-en yakın komşu — hepsi sıfırdan.

Soru: n = 36’da esnek öğrenici, açık parametreli modeli geçer mi?

class Dugum:

    __slots__ = ('j','t','l','r','v')



def _sse(y):

    m = sum(y)/len(y); return sum((v-m)**2 for v in y)



def _buyut(X, y, depth, min_leaf, max_depth, feats):

    nd = Dugum()

    if depth >= max_depth or len(y) < 2*min_leaf or _sse(y) < 1e-12:

        nd.j = None; nd.v = sum(y)/len(y); return nd

    best = None

    for j in feats:

        vals = sorted(set(x[j] for x in X))

        for a, b in zip(vals, vals[1:]):

            t = (a+b)/2

            li = [i for i, x in enumerate(X) if x[j] <= t]

            ri = [i for i, x in enumerate(X) if x[j] >  t]

            if len(li) < min_leaf or len(ri) < min_leaf: continue

            s = _sse([y[i] for i in li]) + _sse([y[i] for i in ri])

            if best is None or s < best[0]: best = (s, j, t, li, ri)

    if best is None:

        nd.j = None; nd.v = sum(y)/len(y); return nd

    _, j, t, li, ri = best

    nd.j, nd.t = j, t

    nd.l = _buyut([X[i] for i in li], [y[i] for i in li], depth+1, min_leaf, max_depth, feats)

    nd.r = _buyut([X[i] for i in ri], [y[i] for i in ri], depth+1, min_leaf, max_depth, feats)

    return nd



def agac_tahmin(nd, x):

    while nd.j is not None: nd = nd.l if x[nd.j] <= nd.t else nd.r

    return nd.v



def agac_kur(X, y, min_leaf=2, max_depth=5):

    return _buyut(X, y, 0, min_leaf, max_depth, list(range(len(X[0]))))



def orman_kur(X, y, ntree=500, min_leaf=2, max_depth=6, seed=7):

    rnd = random.Random(seed); p = len(X[0]); mtry = max(1, int(round(p*0.7)))

    T = []

    for _ in range(ntree):

        idx = [rnd.randrange(len(y)) for _ in range(len(y))]

        T.append(_buyut([X[i] for i in idx], [y[i] for i in idx], 0,

                        min_leaf, max_depth, rnd.sample(range(p), mtry)))

    return T



def orman_tahmin(T, x): return sum(agac_tahmin(t, x) for t in T)/len(T)



def knn_kur(X, y, k): return (X, y, k)

def knn_tahmin(m, x):

    X, y, k = m

    rng = [max(r[j] for r in X) - min(r[j] for r in X) or 1 for j in range(len(x))]

    d = sorted(range(len(y)), key=lambda i: sum(((X[i][j]-x[j])/rng[j])**2 for j in range(len(x))))

    return sum(y[i] for i in d[:k])/k



Xraw = [[r['Vc'], r['f_mm'], r['cu'], r['sr']] for r in rows]

for hedef, birim in (('Fc','N'), ('Ra','um')):

    y = [r[hedef] for r in rows]

    Xlin = [[1, r['Vc'], r['f_mm'], r['cu'], r['sr']] for r in rows]

    Xint = tasarim(rows, 'rsm', ['cs','cxf'])

    print('='*66); print(f'{hedef} ({birim})'); print('='*66)

    print(f'{"Model":<38}{"LOOCV":>10}')

    print(f'{"Dogrusal + Sr + CuSn5 (5 par.)":<38}{loocv_ols(Xlin, y):10.3f}')

    print(f'{"RSM + Sr + CuSn5 + CuSn5xf (9 par.)":<38}{loocv_ols(Xint, y):10.3f}')

    for md_ in (3, 5):

        print(f'{f"Regresyon agaci (derinlik {md_})":<38}'

              f'{loocv(lambda A,b,md_=md_: agac_kur(A,b,2,md_), agac_tahmin, Xraw, y):10.3f}')

    print(f'{"Rastgele orman (500 agac)":<38}'

          f'{loocv(lambda A,b: orman_kur(A,b,500), orman_tahmin, Xraw, y):10.3f}')

    for k in (3, 5):

        print(f'{f"k-en yakin komsu (k={k})":<38}'

              f'{loocv(lambda A,b,k=k: knn_kur(A,b,k), knn_tahmin, Xraw, y):10.3f}')

    print()

print('Sonuc: Fc\'de dogrusal model kazaniyor. Ra\'da agac oncelikle one geciyor,')

print('ancak CuSn5 x ilerleme etkilesimi acikca modele yazildiginda fark kapaniyor.')

Çıktı:

==================================================================
Fc (N)
==================================================================
Model                                      LOOCV
Dogrusal + Sr + CuSn5 (5 par.)             5.881
RSM + Sr + CuSn5 + CuSn5xf (9 par.)        5.963
Regresyon agaci (derinlik 3)               8.823
Regresyon agaci (derinlik 5)               8.657
Rastgele orman (500 agac)                  7.522
k-en yakin komsu (k=3)                     9.300
k-en yakin komsu (k=5)                     9.200

==================================================================
Ra (um)
==================================================================
Model                                      LOOCV
Dogrusal + Sr + CuSn5 (5 par.)             0.684
RSM + Sr + CuSn5 + CuSn5xf (9 par.)        0.496
Regresyon agaci (derinlik 3)               0.561
Regresyon agaci (derinlik 5)               0.489
Rastgele orman (500 agac)                  0.634
k-en yakin komsu (k=3)                     0.698
k-en yakin komsu (k=5)                     0.793

Sonuc: Fc'de dogrusal model kazaniyor. Ra'da agac oncelikle one geciyor,
ancak CuSn5 x ilerleme etkilesimi acikca modele yazildiginda fark kapaniyor.

11. Yığıntı talaş

Gözlemci-içi uyum (κ), korelasyonlar ve şartlı ilişki / zayıflama (attenuation) sınaması.

⚠️ Bu bir formal aracılık (mediation) analizi değildir. Yığıntı talaş ile işlenmiş yüzey aynı kesme olayı içinde oluşur; aracılık analizinin gerektirdiği nedensel zaman sıralaması kurulamaz. Sınama yalnızca, CuSn5’in Ra üzerindeki ilişkisinin ölçülen BUE skoru modele girdiğinde ne kadar zayıfladığını ölçer.

κ hesabı ilk tur puanlarını gerektirir; deftere yalnızca ikinci tur gömülüdür. Aşağıdaki κ değeri makaleden alınmış referans değerdir.

print('YZ DESTEKLI ON PUANLAMA ILE UYUM (guvenilirlik olcusu DEGILDIR, makaleden)')
print('  n = 30   tam uyum = %80   Cohen kappa = 0.693   agirlikli kappa = 0.764\n  NOT: bagimsiz iki insan gozlemci arasindaki uyum DEGILDIR; kor kosullarda elde edilmemistir.')
print()
print('KORELASYONLAR  (n = 36)')
print('-'*48)
for h in ('Ra','Fc','Ff_N','FfFc','f_mm','Vc'):
    rho, p = spearman([r['BUE'] for r in rows], [r[h] for r in rows])
    yildiz = '***' if p < 0.001 else '**' if p < 0.01 else '*' if p < 0.05 else ''
    print(f'  BUE - {h:<6} rho = {rho:+.3f}   p = {p:.4f} {yildiz}')

print()
print('SARTLI ILISKI (ATTENUATION) SINAMASI — olculen BUE skoru etkiyi ne kadar zayiflatiyor?')
print('-'*68)
y  = [r['Ra'] for r in rows]
Xk = [[1, r['Fc'], r['Vc'], r['f_mm']] for r in rows]
Xc = [x+[r['cu']] for x, r in zip(Xk, rows)]
Xb = [[1, r['Fc'], r['Vc'], r['f_mm'], r['BUE']] for r in rows]
Xbc= [x+[r['cu']] for x, r in zip(Xb, rows)]
F1, p1, a1, b1 = kismi_F(Xk, Xc, y)
F2, p2, a2, b2 = kismi_F(Xb, Xbc, y)
print(f'  BUE modelde DEGILKEN : F({a1},{b1}) = {F1:6.2f}   p = {p1:.2e}')
print(f'  BUE modelde IKEN     : F({a2},{b2}) = {F2:6.2f}   p = {p2:.2e}')
print(f'  Zayiflama (attenuation): %{100*(F1-F2)/F1:.0f}')
print()
print('  -> Olculen BUE skoru, CuSn5\'in Ra uzerindeki etkisinin yalnizca kucuk bir kismini acikliyor.\n     Bu, BUE\'nin mekanizmanin hicbir parcasi olmadigini kanitlamaz.')

Çıktı:

YZ DESTEKLI ON PUANLAMA ILE UYUM (guvenilirlik olcusu DEGILDIR, makaleden)
  n = 30   tam uyum = %80   Cohen kappa = 0.693   agirlikli kappa = 0.764
  NOT: bagimsiz iki insan gozlemci arasindaki uyum DEGILDIR; kor kosullarda elde edilmemistir.

KORELASYONLAR  (n = 36)
------------------------------------------------
  BUE - Ra     rho = +0.469   p = 0.0039 **
  BUE - Fc     rho = +0.501   p = 0.0018 **
  BUE - Ff_N   rho = +0.374   p = 0.0247 *
  BUE - FfFc   rho = -0.385   p = 0.0204 *
  BUE - f_mm   rho = +0.578   p = 0.0002 ***
  BUE - Vc     rho = -0.009   p = 0.9597 

SARTLI ILISKI (ATTENUATION) SINAMASI — olculen BUE skoru etkiyi ne kadar zayiflatiyor?
--------------------------------------------------------------------
  BUE modelde DEGILKEN : F(1,31) =  55.13   p = 2.31e-08
  BUE modelde IKEN     : F(1,30) =  48.81   p = 9.21e-08
  Zayiflama (attenuation): %11

  -> Olculen BUE skoru, CuSn5'in Ra uzerindeki etkisinin yalnizca kucuk bir kismini acikliyor.
     Bu, BUE'nin mekanizmanin hicbir parcasi olmadigini kanitlamaz.

12. Grafikler (isteğe bağlı — matplotlib gerekir)

Makaledeki şekiller ayrı bir betikle (sekil_uret.py) SVG olarak üretilir. Bu hücre hızlı bir görsel kontrol sunar.

try:

    import matplotlib.pyplot as plt

except ImportError:

    print('matplotlib yok - bu hucre atlandi.  Kurmak icin:  pip install matplotlib')

else:

    fig, ax = plt.subplots(1, 3, figsize=(14, 4))

    renk = {'A':'#000000','B':'#c0392b','C':'#1f6fb4','D':'#e08214'}

    mark = {'A':'o','B':'s','C':'^','D':'D'}



    for g in GR:

        s = [r for r in rows if r['grup'] == g]

        ax[0].scatter([r['FfFc'] for r in s], [r['Ra'] for r in s],

                      c=renk[g], marker=mark[g], label=f'{g} - {AD[g]}', s=42)

    r_, p_ = pearson([r['FfFc'] for r in rows], [r['Ra'] for r in rows])

    ax[0].set_xlabel('Ff / Fc'); ax[0].set_ylabel('Ra (um)')

    ax[0].set_title(f'Kuvvet orani ve puruzluluk  (r = {r_:+.3f})')

    ax[0].legend(fontsize=8)



    feeds = [0.08, 0.16, 0.32]

    for g in GR:

        m = [sum(r['Ra'] for r in rows if r['grup']==g and r['f_mm']==f) /

             len([r for r in rows if r['grup']==g and r['f_mm']==f]) for f in feeds]

        ax[1].plot(feeds, m, marker=mark[g], color=renk[g], label=g)

    ax[1].set_xlabel('Ilerleme (mm/dev)'); ax[1].set_ylabel('Ra (um)')

    ax[1].set_title('Malzeme x ilerleme etkilesimi'); ax[1].legend(fontsize=8)



    etiket = ['Sr->Fc','CuSn5->Fc','Sr->Ra','CuSn5->Ra','Sr->BUE','CuSn5->BUE']

    veri   = [GA[k] for k in [('Fc','sr'),('Fc','cu'),('Ra','sr'),('Ra','cu'),('BUE','sr'),('BUE','cu')]]

    olcek  = [9.06, 9.06, 1.55, 1.55, 0.61, 0.61]

    for i, ((pt, lo, hi), sc) in enumerate(zip(veri, olcek)):

        anl = lo*hi > 0

        ax[2].plot([lo/sc, hi/sc], [i, i], color='#c0392b' if anl else '#9aa5ad', lw=3)

        ax[2].plot(pt/sc, i, 'o', color='#c0392b' if anl else '#9aa5ad', ms=7)

    ax[2].axvline(0, color='#888', ls='--')

    ax[2].set_yticks(range(6)); ax[2].set_yticklabels(etiket, fontsize=9)

    ax[2].set_xlabel('Etki (ilgili cikti icin olceklenmis)')

    ax[2].set_title('Cift ayrisma: etki ve %95 GA')

    plt.tight_layout(); plt.show()

Çıktı:

matplotlib yok - bu hucre atlandi.  Kurmak icin:  pip install matplotlib