The solution for the least squares criterion is given by $$\beta=(X'X)^{-1}X'Y$$ cf.
Eq.(2.4.2) in the book


https://www.keisoshobo.co.jp/book/b573254.html
or
Eq. (6.1.5) in the book
https://www.maruzen-publishing.co.jp/item/b303174.html



Model (1)
$$Y=a+tW+E$$

In [1]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

infl_nm = 'YWX_1.xlsx'
with pd.ExcelFile(infl_nm) as f_xlsx:  
    data_xlsx = pd.read_excel(f_xlsx)

Y = np.array(data_xlsx['Y'], dtype='float')
W = np.array(data_xlsx['W'], dtype='float')
for v in zip(Y, W): 
    print(v)

IX = np.concatenate([np.ones((len(Y), 1)), np.reshape(W, (len(Y),1))], axis=1)
beta = np.linalg.inv(IX.T @ IX) @ IX.T @ np.reshape(Y, (len(Y), 1))
print(beta)
a = beta[0][0]
t = beta[1][0]

plt.scatter(W, Y)
plt.plot([W[0], W[9]], [a + t*W[0], a + t*W[9]], label=f'Y=a+tW')
plt.plot([], color='#ffffff', label=f'a={a:.2f}\nt={t:.2f}')
plt.xticks([0, 1], [0, 1], fontsize= 16)
plt.xlabel('W: 0/control, 1/treated', fontsize=16)
plt.ylabel('Y', fontsize=18)
plt.legend(fontsize=16)
plt.tight_layout()
plt.show()
(90.0, 0.0)
(81.0, 0.0)
(70.0, 0.0)
(61.0, 0.0)
(50.0, 0.0)
(91.0, 1.0)
(80.0, 1.0)
(71.0, 1.0)
(60.0, 1.0)
(51.0, 1.0)
[[70.4]
 [ 0.2]]
No description has been provided for this image
In [ ]:
 



Model (2) $$Y=a+bX+E$$

In [2]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

infl_nm = 'YWX_1.xlsx' # input('Input data file (*xlsx) = ')
with pd.ExcelFile(infl_nm) as f_xlsx:  
    data_xlsx = pd.read_excel(f_xlsx)

Y = np.array(data_xlsx['Y'], dtype='float')
X = np.array(data_xlsx['X'], dtype='float')
for v in zip(Y, X):
    print(v)

IX = np.concatenate([np.ones((len(Y), 1)), np.reshape(X, (len(Y), 1))], axis=1)
beta = np.linalg.inv(IX.T @ IX) @ IX.T @ np.reshape(Y, (len(Y), 1))
print(beta)

a = beta[0][0]
b = beta[1][0]

plt.scatter(X, Y)
plt.plot([X[0], X[9]], [a + b*X[0], a + b*X[9]], label ='Y=a+bX')
plt.plot([], color="#ffffff", label=f'a={a:.2f}\nb={b:.2f}')
plt.xlabel('X', fontsize=16)
plt.ylabel('Y', fontsize=16)
plt.legend(fontsize=14)
plt.tight_layout()
plt.show()
(90.0, 10.0)
(81.0, 11.0)
(70.0, 12.0)
(61.0, 13.0)
(50.0, 14.0)
(91.0, 15.0)
(80.0, 16.0)
(71.0, 17.0)
(60.0, 18.0)
(51.0, 19.0)
[[105.21212121]
 [ -2.39393939]]
No description has been provided for this image
In [ ]:
 



Model (3)
$$Y=a+tW+bX+E$$

In [3]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

infl_nm = 'YWX_1.xlsx' # input('Input data file (*xlsx) = ')
with pd.ExcelFile(infl_nm) as f_xlsx:  
    data_xlsx = pd.read_excel(f_xlsx)
Y = np.array(data_xlsx['Y'], dtype='float')
W = np.array(data_xlsx['W'], dtype='float')
X = np.array(data_xlsx['X'], dtype='float')
for v in zip(Y, W, X):
    print(v)

IX = np.concatenate([np.ones((len(Y), 1)), np.reshape(W, (len(Y),1)),
                     np.reshape(X, (len(Y), 1))], axis=1)
beta = np.linalg.inv(IX.T @ IX) @ IX.T @ np.reshape(Y, (len(Y), 1))
print(beta)

a = beta[0][0]
t = beta[1][0]
b = beta[2][0]

plt.scatter(X[:5], Y[:5], color='g', label='W=0')
plt.scatter(X[5:], Y[5:], color='b', label='W=1')
plt.plot([X[0], X[9]], [a + b*X[0], a + b*X[9]],
         color='magenta', label=f'W=0,  b={b:.2f}')
plt.plot([X[0], X[9]], [a + t + b*X[0],
                        a + t + b*X[9]],
         color='orange', label=f'W=1, t={t:.2f}')
Y_imp = [a + b*v for v in X[5:]]
plt.scatter(X[5:], Y_imp, marker='*', color='r', label='W=0(imputed)')
plt.xlabel('X', fontsize=16)
plt.ylabel('Y', fontsize=16)
plt.legend(fontsize=12)
plt.show()
(90.0, 0.0, 10.0)
(81.0, 0.0, 11.0)
(70.0, 0.0, 12.0)
(61.0, 0.0, 13.0)
(50.0, 0.0, 14.0)
(91.0, 1.0, 15.0)
(80.0, 1.0, 16.0)
(71.0, 1.0, 17.0)
(60.0, 1.0, 18.0)
(51.0, 1.0, 19.0)
[[190.4]
 [ 50.2]
 [-10. ]]
No description has been provided for this image
In [ ]: