Because you have a class imbalance and very little data. Your model is essentially working off of a prior probability that disproprtionately favors the positive class, and you didn't give the model enough data to escape this prior in the learning process. Consider the following detailed output from your model:
model.score(X,Y) # 0.6666
model.coef_ # array([[ 0.36566712, 0.36566712]])
model.intercept_ # array([ 0.18517658])
model.predict_proba(X)
# array([[ 0.45383769, 0.54616231],
# [ 0.36566869, 0.63433131],
# [ 0.36566869, 0.63433131]])
Your model correctly identifies that [0,0] is more likely to be negative than either of the other observations, but the model isn't able to escape its bias towards the positive class. If you duplicate your dataset a couple of times, the model will eventually have enough "evidence" to escape this bias. Geometrically, two things will happen when we give the model more data:
- The discrimination boundary will shift towards the negative class. This will manifest as an increasingly negative intercept term.
- The slope of the logistic curve will steepen, having the effect that a unit change in the inputs will have a larger impact on the outcome. If we give the model enough perfectly separable data, the curve will approach a step function and the model will output probabilities of 0 and 1. This manifests in the magnitude of the coefficients. With just three observations, the curve is fairly flat and changing the values of the inputs doesn't have much effect on the outcome probability, so the resulting class assignment is essentially determined by the intercept alone.
Contrast the results from your original model with the what happens when we replicate your dataset 100 times:
model2 = LogisticRegression()
X2 = np.matlib.repmat(X,100,1)
Y2 = np.matlib.repmat(Y,100,1).ravel()
model2.fit(X2, Y2)
model2.score(X,Y) # 1.0
model2.coef_ # array([[ 4.95489068, 4.95489068]])
model2.intercept_ # array([-2.00091433])
model2.predict_proba(X)
# array([[ 0.88089304, 0.11910696],
# [ 0.04954891, 0.95045109],
# [ 0.04954891, 0.95045109]])