我正在尝试使用scikit-learn的SVM文档分类器来预测肺癌数据,并使用以下代码,但遇到了一些错误。我已经使用matplotlib.pyplot as plt
来绘制数据,但出现了错误。
这里我使用的是按肺癌风险因素分类的数据。
输入文件
GENDER AGE SMOKING YELLOW_FINGERS ANXIETY PEER_PRESSURE CHRONIC DISEASE FATIGUE ALLERGY WHEEZING ALCOHOL CONSUMING COUGHING SHORTNESS OF BREATH SWALLOWING DIFFICULTY CHEST PAIN LUNG_CANCERF 59 0 0 0 1 0 1 0 1 0 1 1 0 1 0F 63 0 1 0 0 0 0 0 1 0 1 1 0 0 0F 75 0 1 0 0 1 1 1 1 0 1 1 0 0 1M 69 0 1 1 0 0 1 0 1 1 1 1 1 1 1M 74 1 0 0 0 1 1 1 0 0 0 1 1 1 1M 63 1 1 1 0 0 0 0 0 1 0 0 1 1 0
脚本 SVM
# Support Vector Machine (SVM)# 导入库import numpy as npimport matplotlib.pyplot as pltimport pandas as pd# 导入数据集dataset = pd.read_csv('C:/Users/Vishnu/Desktop/Lung Cancer/lung_cancer.csv')X = dataset.iloc[:, [2,3,4,5,6,7,8,9,10,11,12,13,14]].valuesy = dataset.iloc[:, 15].values# 将数据集分成训练集和测试集from sklearn.cross_validation import train_test_splitX_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.25, random_state = 0)# 特征缩放from sklearn.preprocessing import StandardScalersc = StandardScaler()X_train = sc.fit_transform(X_train)X_test = sc.transform(X_test)# 在训练集上拟合SVMfrom sklearn.svm import SVCclassifier = SVC(kernel = 'linear', random_state = 0)classifier.fit(X_train, y_train)# 预测测试集结果y_pred = classifier.predict(X_test)# 制作混淆矩阵from sklearn.metrics import confusion_matrixcm = confusion_matrix(y_test, y_pred)# 可视化训练集结果from matplotlib.colors import ListedColormapX_set, y_set = X_train, y_trainX1, X2 = np.meshgrid(np.arange(start = X_set[:, 0].min() - 1, stop = X_set[:, 0].max() + 1, step = 0.01), np.arange(start = X_set[:, 1].min() - 1, stop = X_set[:, 1].max() + 1, step = 0.01))plt.contourf(X1, X2, classifier.predict(np.array([X1.ravel(), X2.ravel()]).T).reshape(X1.shape), alpha = 0.75, cmap = ListedColormap(('red', 'green')))plt.xlim(X1.min(), X1.max())plt.ylim(X2.min(), X2.max())for i, j in enumerate(np.unique(y_set)): plt.scatter(X_set[y_set == j, 0], X_set[y_set == j, 1], c = ListedColormap(('red', 'green'))(i), label = j)plt.title('SVM (训练集)')plt.xlabel('年龄')plt.ylabel('肺癌风险因素')plt.legend()plt.show()# 可视化测试集结果from matplotlib.colors import ListedColormapX_set, y_set = X_test, y_testX1, X2 = np.meshgrid(np.arange(start = X_set[:, 0].min() - 1, stop = X_set[:, 0].max() + 1, step = 0.01), np.arange(start = X_set[:, 1].min() - 1, stop = X_set[:, 1].max() + 1, step = 0.01))plt.contourf(X1, X2, classifier.predict(np.array([X1.ravel(), X2.ravel()]).T).reshape(X1.shape), alpha = 0.75, cmap = ListedColormap(('red', 'green')))plt.xlim(X1.min(), X1.max())plt.ylim(X2.min(), X2.max())for i, j in enumerate(np.unique(y_set)): plt.scatter(X_set[y_set == j, 0], X_set[y_set == j, 1], c = ListedColormap(('red', 'green'))(i), label = j)plt.title('SVM (测试集)')plt.xlabel('年龄')plt.ylabel('肺癌风险因素')plt.legend()plt.show()
错误
ValueError: X.shape[1] = 2 should be equal to 13, the number of features at training time
我在这行代码上遇到错误
plt.contourf(X1, X2, classifier.predict(np.array([X1.ravel(), X2.ravel()]).T).reshape(X1.shape), alpha = 0.75, cmap = ListedColormap(('red', 'green')))
为什么我会遇到这个错误,请给我一些建议。提前感谢您。
编辑_1
SVM测试集输出图
SVM训练集输出图
请问有人能告诉我这是正确的输出吗?
提前感谢您
回答:
尽管出现了异常,我认为有几个方面需要解决。
-
异常本身是因为您为
classifier.predict
提供了2个变量作为输入,而您的模型是在13个变量上训练的。如果您想在其中的两个变量上绘制轮廓图,您需要将其他11个变量设置为某个默认值。X1, X2 = np.meshgrid(np.arange(start = X_set[:, 0].min() - 1, stop = X_set[:, 0].max() + 1, step = 0.01), np.arange(start = X_set[:, 1].min() - 1, stop = X_set[:, 1].max() + 1, step = 0.01))Xpred = np.array([X1.ravel(), X2.ravel()] + [np.repeat(0, X1.ravel().size) for _ in range(11)]).T# Xpred现在有x1和x2的网格,以及x3到x13的平均值(0)pred = classifier.predict(Xpred).reshape(X1.shape) # 是一个0和1的矩阵!plt.contourf(X1, X2, pred, alpha = 0.75, cmap = ListedColormap(('red', 'green')))
这个片段将工作,但是可能不会给您想要的结果。使用一些随机的二项数据,您将得到一个类似下面的数字红绿图。
SVC.predict
的输出是一个二进制矩阵,而不是概率。 -
您可以选择绘制
decision_function
作为预测结果,它可视化了到分离超平面的距离。这可以被解释为风险因素。然而,它不是概率pred = classifier.decision_function(Xpred).reshape(X1.shape) plt.contourf(X1, X2, pred, alpha=1.0, cmap="RdYlGn", levels=np.linspace(pred.min(), pred.max(), 100))
-
我还看到您的数据集有另一个问题。它似乎有15列。然后我期望
y = dataset.iloc[:, 15].values
这行代码会引发IndexError
。如果没有,请检查您的数据集的完整性。它是否通过pd.read_csv
正确导入? -
此外,您丢弃了前两列GENDER和AGE的信息。对于性别,您可以将
F
转换为0
,将M
转换为1
,并将年龄也包含在X
中:dataset = pd.read_csv('C:/Users/Vishnu/Desktop/Lung Cancer/lung_cancer.csv')dataset.loc[dataset['GENDER'] == 'F', 'GENDER'] = 0dataset.loc[dataset['GENDER'] == 'M', 'GENDER'] = 1X = dataset.iloc[:, 0:14].valuesy = dataset.iloc[:, 14].values
希望这些建议对您有帮助。如果在解决您的问题时又有新的问题出现,并且您无法通过自己的研究找到答案,请随时提问 🙂