我知道这个question,但这是过时的功能。
比方说,我正在尝试根据某人已经访问过的国家和他们的收入来预测一个人是否会访问“ X”国。
我在pandas DataFrame中有一个训练数据集,格式如下。
从本质上讲,如果我的数据集中有100,000个人,那么我的数据框的尺寸为100,000 x 12
。我希望能够使用tensorflow将其正确传递到线性分类器中。但是,即使是如何处理,也不确定。
我正在尝试将数据传递到此function
estimator = LinearClassifier(
n_classes=n_classes, feature_columns=[sparse_column_a,
sparse_feature_a_x_sparse_feature_b], label_keys=label_keys)
(如果对使用哪种估算器有更好的建议,我愿意尝试。)
我将数据传递为:
df = pd.DataFrame(np.random.randint(0,2,size=(100, 12)), columns=list('ABCDEFGHIJKL'))
tf_val = tf.estimator.inputs.pandas_input_fn(X.iloc[:, 0:9], X.iloc[:, 11], shuffle=True)
但是,我不确定如何获取此输出并将其正确传递到分类器中。我是否可以正确设置问题?我不是来自数据科学领域,因此任何指导都将非常有帮助!
关注点
(赏金所需的工作代码)
答案 0 :(得分:3)
SVM是最大余量分类器,即,它使正分类与负分类的宽度或余量最大化。下面给出了二进制分类情况下线性SVM的损失函数。
它可以从下面显示的更广义的多类线性SVM损耗(也称为铰链损耗)(Δ= 1)中得出。
注意:在以上所有等式中,权重向量w
包括偏差b
有人到底是怎么想到这种损失的? 让我们深入研究吧。
上图显示了属于正类的数据点和属于负类的数据点之间通过一个分隔的超平面(显示为实线)分开的情况。但是,可以有许多这样的分离超平面。 SVM找到分离的超平面,以使超平面到最近的正数据点和最近的负数据点的距离最大(如虚线所示)。
从数学上讲,SVM找到权重向量w
(包括偏差)使得
如果+ ve类和-ve类的标签(y
)分别是+1
和-1
,则SVM会找到w
这样
•如果数据点位于超平面的正确一侧(正确分类),则
•如果数据点位于错误的一侧(未分类),则
因此,作为未命中分类的量度的数据点损失可以写为
如果权重向量w
对数据(X
进行了正确分类,则这些权重向量λw
的任意倍数,其中λ>1
也将数据正确分类(零损失)。这是因为变换λW
拉伸了所有得分幅度,因此也拉伸了它们的绝对差。 L2正则化通过将正则化损失添加到铰链损失中来惩罚较大的权重。
例如,如果x=[1,1,1,1]
和两个权重向量w1=[1,0,0,0]
,则w2=[0.25,0.25,0.25,0.25]
。然后dot(W1,x) =dot(w2,x) =1
,即两个权重向量都导致相同的点积,从而导致相同的铰链损耗。但是w1
的L2惩罚为1.0
,而w2
的L2惩罚仅为0.25
。因此,L2正则化比w2
更喜欢w1
。鼓励分类器将所有输入维考虑为少量,而不是少数几个输入维。这样可以改善模型的通用性,并减少过拟合。
L2损失导致SVM中的最大保证金属性。如果将SVM表示为优化问题,则约束二次优化问题的广义Lagrangian形式如下
现在,我们知道线性SVM的损失函数,我们可以使用梯度适当值(或其他优化器)来找到将损失最小化的权重向量。
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
# Load Data
iris = datasets.load_iris()
X = iris.data[:, :2][iris.target != 2]
y = iris.target[iris.target != 2]
# Change labels to +1 and -1
y = np.where(y==1, y, -1)
# Linear Model with L2 regularization
model = tf.keras.Sequential()
model.add(tf.keras.layers.Dense(1, activation='linear', kernel_regularizer=tf.keras.regularizers.l2()))
# Hinge loss
def hinge_loss(y_true, y_pred):
return tf.maximum(0., 1- y_true*y_pred)
# Train the model
model.compile(optimizer='adam', loss=hinge_loss)
model.fit(X, y, epochs=50000, verbose=False)
# Plot the learned decision boundary
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.01),
np.arange(y_min, y_max, 0.01))
Z = model.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
cs = plt.contourf(xx, yy, Z, cmap=plt.cm.coolwarm, alpha=0.8)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Set1)
plt.show()
SVM也可以表示为约束二次优化问题。这种表述的优点是我们可以使用内核技巧对非线性可分离数据进行分类(使用不同的内核)。 LIBSVM为内核化支持向量机(SVM)实现了顺序最小优化(SMO)算法。
from sklearn.svm import SVC
# SVM with linear kernel
clf = SVC(kernel='linear')
clf.fit(X, y)
# Plot the learned decision boundary
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.01),
np.arange(y_min, y_max, 0.01))
Z = model.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
cs = plt.contourf(xx, yy, Z, cmap=plt.cm.coolwarm, alpha=0.8)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Set1)
plt.show()
您可以将tf用于问题陈述的线性SVM模型是
# Prepare Data
# 10 Binary features
df = pd.DataFrame(np.random.randint(0,2,size=(1000, 10)))
# 1 floating value feature
df[11] = np.random.uniform(0,100000, size=(1000))
# True Label
df[12] = pd.DataFrame(np.random.randint(0, 2, size=(1000)))
# Convert data to zero mean unit variance
scalar = StandardScaler().fit(df[df.columns.drop(12)])
X = scalar.transform(df[df.columns.drop(12)])
y = np.array(df[12])
# convert label to +1 and -1. Needed for hinge loss
y = np.where(y==1, +1, -1)
# Model
model = tf.keras.Sequential()
model.add(tf.keras.layers.Dense(1, activation='linear',
kernel_regularizer=tf.keras.regularizers.l2()))
# Hinge Loss
def my_loss(y_true, y_pred):
return tf.maximum(0., 1- y_true*y_pred)
# Train model
model.compile(optimizer='adam', loss=my_loss)
model.fit(X, y, epochs=100, verbose=True)
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.model_selection import KFold
from sklearn.metrics import roc_curve, auc
# Load Data
iris = datasets.load_iris()
X = iris.data[:, :2][iris.target != 2]
y_ = iris.target[iris.target != 2]
# Change labels to +1 and -1
y = np.where(y_==1, +1, -1)
# Hinge loss
def hinge_loss(y_true, y_pred):
return tf.maximum(0., 1- y_true*y_pred)
def get_model():
# Linear Model with L2 regularization
model = tf.keras.Sequential()
model.add(tf.keras.layers.Dense(1, activation='linear', kernel_regularizer=tf.keras.regularizers.l2()))
model.compile(optimizer='adam', loss=hinge_loss)
return model
def sigmoid(x):
return 1 / (1 + np.exp(-x))
predict = lambda model, x : sigmoid(model.predict(x).reshape(-1))
predict_class = lambda model, x : np.where(predict(model, x)>0.5, 1, 0)
kf = KFold(n_splits=2, shuffle=True)
# K Fold cross validation
best = (None, -1)
for i, (train_index, test_index) in enumerate(kf.split(X)):
X_train, X_test = X[train_index], X[test_index]
y_train, y_test = y[train_index], y[test_index]
model = get_model()
model.fit(X_train, y_train, epochs=5000, verbose=False, batch_size=128)
y_pred = model.predict_classes(X_test)
val = roc_auc_score(y_test, y_pred)
print ("CV Fold {0}: AUC: {1}".format(i+1, auc))
if best[1] < val:
best = (model, val)
# ROC Curve using the best model
y_score = predict(best[0], X)
fpr, tpr, _ = roc_curve(y_, y_score)
roc_auc = auc(fpr, tpr)
print (roc_auc)
# Plot ROC
plt.figure()
lw = 2
plt.plot(fpr, tpr, color='darkorange',
lw=lw, label='ROC curve (area = %0.2f)' % roc_auc)
plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.legend(loc="lower right")
plt.show()
# Make predictions
y_score = predict_class(best[0], X)
由于模型的输出是线性的,因此我们必须将其归一化为预测的概率。如果是二进制分类,则可以使用sigmoid
;如果是多分类,则可以使用softmax
。下面的代码用于二进制分类
predict = lambda model, x : sigmoid(model.predict(x).reshape(-1))
predict_class = lambda model, x : np.where(predict(model, x)>0.5, 1, 0)
答案 1 :(得分:1)
由于所有功能都已经是数字功能,因此您可以按原样使用它们。
df = pd.DataFrame(np.random.randint(0,2,size=(100, 12)), columns=list('ABCDEFGHIJKL'))
df['K'] = np.random.random(100)
nuemric_features = [tf.feature_column.numeric_column(column) for column in df.columns[:11]]
model = tf.estimator.LinearClassifier(feature_columns=nuemric_features)
tf_val = tf.estimator.inputs.pandas_input_fn(df.iloc[:,:11], df.iloc[:,11], shuffle=True)
model.train(input_fn=tf_val, steps=1000)
print(list(model.predict(input_fn=tf_val))[0])
{'logits': array([-1.7512109], dtype=float32), 'logistic': array([0.14789453], dtype=float32), 'probabilities': array([0.8521055 , 0.14789453], dtype=float32), 'class_ids': array([0]), 'classes': array([b'0'], dtype=object)}
最有可能对预测输出的概率感兴趣。您有两种概率,一种是针对目标的Flase,另一种是True。
如果您想了解更多详细信息,请参阅有关使用TensorFlow进行二进制分类的不错的blog-post。