散点图抛出 TypeError

Scatter plot throws TypeError

我正在尝试以下代码:

from sklearn.cross_validation import train_test_split
from sklearn.preprocessing import StandardScaler
scaler=StandardScaler()
from sklearn.linear_model import LogisticRegression
from sklearn import linear_model
model = linear_model.LogisticRegression()
import matplotlib.pyplot as plt
from sklearn.metrics import mean_squared_error, r2_score

X=scaler.fit_transform(X)

X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.2)

model.fit(X_train,y_train)
# Make predictions using the testing set
powerOutput_y_pred = model.predict(X_test)
print (powerOutput_y_pred)
# The coefficients
print('Coefficients: \n', model.coef_)
# The mean squared error
print("Mean squared error: %.2f"
      % mean_squared_error(y_test, powerOutput_y_pred))
# Explained variance score: 1 is perfect prediction
print('Variance score: %.2f' % r2_score(y_test, powerOutput_y_pred))

plt.scatter(X_test, y_test,  color='black')
plt.plot(X_test, powerOutput_y_pred, color='blue', linewidth=3)
plt.xticks(())
plt.yticks(())
plt.show()

但我收到以下散点图错误:

ValueError: x and y must be the same size

如果我 运行 df.head(),我会关注 table:

df structure

特征X和y如下:

X=df.values[:,[0,1,2,3,4,5,7]]
y=df.values[:,6]

运行 X.shape 给出 (25,7) 并且 y.shape 给出 (25, ) 作为输出。那么如何解决这个形状不匹配问题呢?

最简单的答案

只需使用 plot 而不是 scatter:

plt.plot(X_test, y_test, ls="none", marker='.', ms=12)

这将使用同一组 y 数据绘制不同的 x 数据集。这假设 x.shape == (n,d)y.shape == (n,),如您上面的问题。

简单回答

遍历 x 值的列,并为每列调用一次 scatter

colors = plt.cm.viridis(np.linspace(0.0, 1.0, features))
for xcol,c in zip(X_test.T, colors):
    plt.scatter(xcol, y_test, c=c)

用数组 colors 设置 c 将使每个特征在散点图上绘制为不同的颜色。如果你想让它们都是黑色的,只需将上面的颜色替换为 c='black'

详情

scatter 需要一个 x 值列表和一个 y 值列表。如果 x 和 y 列表是一维的,这是最简单的。但是,如果这些数组具有匹配的形状,您也可以绘制存储在二维数组中的多组 x 和 y 数据。

来自Matplotlib docs:

Fundamentally, scatter works with 1-D arrays; x, y, s, and c may be input as 2-D arrays, but within scatter they will be flattened.

有点模糊,但是 dive into the Matplotlib source code 确认 x 和 y 的形状必须完全匹配。 plot 处理形状的代码更加灵活,因此对于该函数,您可以使用一组 y 数据来处理多组 x 数据。

通常plot绘制线而不是点,但是您可以通过设置ls(即linestyle)关闭线,并且可以通过设置[=26打开点=]. ms(即markersize)控制点的大小。

例子

您在上面发布的示例不会 运行(Xy 未定义),但这里有一个完整的输出示例:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm

from sklearn import datasets
from sklearn.model_selection import train_test_split

d = datasets.load_diabetes()
features = d.data.shape[1]

X = d.data[:50,:]
Y = d.target[:50]

sample_weight = np.random.RandomState(442).rand(Y.shape[0])

# split train, test for calibration
X_train, X_test, Y_train, Y_test, sw_train, sw_test = \
    train_test_split(X, Y, sample_weight, test_size=0.9, random_state=442)

# use the plot function instead of scatter
# plot one set of y data against several sets of x data
plt.plot(X_test, Y_test, ls="none", marker='.', ms=12)

# call .scatter() multiple times in a loop
#colors = plt.cm.viridis(np.linspace(0.0, 1.0, features))
#for xcol,c in zip(X_test.T, colors):
#    plt.scatter(xcol, Y_test, c=c)

输出: