python-3.x 对于sklearn和panda的分类器算法,我得到了相同的输出

txu3uszq  于 2022-12-14  发布在  Python
关注(0)|答案(4)|浏览(115)

问题

我每次都得到相同的输出,不管输入是什么。

上下文

我有一个带有ID的.csv文件,代表一个5人团队(以前组建的团队),如下所示:

0, 1, 2, 3, 4
5, 6, 7, 3, 8
2, 5, 6, 7, 3
9, 1, 2, 6, 4
9, 0, 1, 2, 4
...

我使用下面代码的目标是能够输入4个ID并预测第5个成员应该是什么。

from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler 
from sklearn.neighbors import KNeighborsClassifier
import pandas as pd 

file = 'People.csv'

# Read dataset without a header row:
dataset = pd.read_csv(file, header=None)

# return the first 5 rows: 
dataset.head() 

# Convert input to a two-dimensional array:
X = dataset.iloc[:, :-1].values
y = dataset.iloc[:, 4].values

# Split dataset into random train and test subsets:
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20)

# Standardize - removes mean and scales to unit variance:
scaler = StandardScaler()
scaler.fit(X_train)

X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test) 

# Use the KNN classifier to fit data:
classifier = KNeighborsClassifier(n_neighbors=5)
classifier.fit(X_train, y_train) 

# Uses the classifier to predict the value of the fifth column:
y_pred = classifier.predict([[5, 6, 7, 3]])

# Print the predicted value:
print(y_pred)
5jdjgkvh

5jdjgkvh1#

主流统计机器学习假设可以根据其他观察到的属性预测对象的属性
在这里提出的问题中:没有属性。2每一行代表一个以前观察过的团队,每一列代表一个团队成员的标识符属性。3换句话说:我们将如何建立一个模型还不清楚。
不过,还有另一种方式来阐述这个问题:“* 哪些人更愿意一起工作?”或“What frequent patterns exist in this data?”或“How do we expect each person to rate one another?*”
Apriori“是一种算法,它帮助估计哪些对象(团队成员)经常一起出现,mlxtend提供了一种实现:

from mlxtend.preprocessing import TransactionEncoder
from mlxtend.frequent_patterns import apriori
import pandas as pd

data = [
    [0, 1, 2, 3, 4],
    [5, 6, 7, 3, 8],
    [2, 5, 6, 7, 3],
    [9, 1, 2, 6, 4],
    [9, 0, 1, 2, 4],
]

te = TransactionEncoder()
te_ary = te.fit(data).transform(data)
df = pd.DataFrame(te_ary, columns=te.columns_)

print(apriori(df, min_support=0.5))

输出包括itemsets和它们的support(基本上是它们一起被观察到的频率的度量)。

support   itemsets
0      0.6        (1)
1      0.8        (2)
2      0.6        (3)
3      0.6        (4)
4      0.6        (6)
5      0.6     (1, 2)
6      0.6     (1, 4)
7      0.6     (2, 4)
8      0.6  (1, 2, 4)

例如:这告诉我们用户2以前出现在80%的团队中,并且这告诉我们用户124在60%的时间内一起工作。
如果我们将来要组织团体:我们可以从以前一起工作的用户中取样,随机地添加或删除人员,直到每个人都在一个团队中。

aydmsdu9

aydmsdu92#

在我看来,你的模型没有“学习”任何东西。如果你的输出没有随着输入而改变,你可能有一个Bias problem。你应该检查的第一件事是类是如何分布的(如果它是极端imbalanced,这可能是你遇到这个问题的原因)

xfyts7mz

xfyts7mz3#

我使用了另一个模型和不同的方法来解决我的问题。使用相同的数据集,我能够得到更好的结果。以下是代码:

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPClassifier

# Load the dataset of previously formed teams and their corresponding 5th members
data = pd.read_csv("People.csv")

# Split the data into input features (4 IDs) and the target variable (5th ID)
X = data[["A1", "A2", "A3", "A4"]]
y = data["A5"]

# Split the data into training and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

# Create a neural network model
model = MLPClassifier()

# Train the model on the training data
model.fit(X_train, y_train)

# Evaluate the model on the test data
accuracy = model.score(X_test, y_test)
print("Accuracy:", accuracy)

# Use the trained model to make predictions on new teams of 4 IDs
team = [5, 6, 7, 3]
predicted_id = model.predict([team])
print("Predicted 5th member:", predicted_id)
erhoui1w

erhoui1w4#

这里有一种替代方法,我们尝试对 * 正好 * 10个用户的偏好进行建模。
这有一些缺点,我会在最后提到。
在探索过程中,我们将忽略train_test_split,并注意到用户的标识符为09,这使得这个问题包含10个类:

from io import StringIO
import numpy as np

data_file = StringIO("""0, 1, 2, 3, 4
5, 6, 7, 3, 8
2, 5, 6, 7, 3
9, 1, 2, 6, 4
9, 0, 1, 2, 4""")

data = np.loadtxt(data_file, delimiter=",")
classes = np.unique(data)
# array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])

我们还假设可以用神经网络来模拟“* 谁不见了 *”:

from sklearn.neural_network import MLPClassifier

model = MLPClassifier(hidden_layer_sizes=(20, 100, 20))

我们可以将其视为“* 忽略一个用户,并预测缺少的人。*”例如:如果我们看到[0, 1, 2, 3, _],我们想要预测4,因为我们在data中观察到[0, 1, 2, 3, 4]
但是等等:如果我们观察到:一米七三
这可能是问题的一个“不变”。预测应该在我们的输入的置换下是不变的,或者这些应该等于[0, 1, 2, 3, _] == [0, 1, 3, 2, _]。这也意味着我们需要使用更复杂的训练方法,我们沿着行置换我们的data,并执行部分拟合。对于10个用户和5人的组,有10 * 9 * 8 * 7 * 6 == 30_240可能的团队,我们可以观察,因此,我们也可以在许多随机示例上重复这个训练循环:

from numpy.random import default_rng
import matplotlib.pyplot as plt

rng = default_rng()

for _ in range(15_000):
    # Perform partial fits on batches of permuted data.

    batch = rng.permutation(data, axis=1)

    X_batch = batch[:, :4]
    y_batch = batch[:, 4]

    model.partial_fit(X_batch, y_batch, classes=classes)

plt.plot(model.loss_curve_)
plt.show()

这里选择的15_000相当随意,但损耗似乎在稳步下降:

我们现在有一个模型,应该能够预测“* 谁是失踪的人 *?”
在预测时间,我们想要回答:集合[0, 1, 2, 3]中缺少了谁?但请记住:我们训练的例子中,我们置换了输入,所以有可能通过网络传递[3, 2, 1, 0]得到不同的答案。
一种补救的方法是将测试示例排列100次,将所有测试示例通过网络,然后观察排列的“平均”结果(这些示例足够小,您可以穷尽地测试每个示例,但这无法扩展到更大的集合)。

from matplotlib.ticker import MaxNLocator

def make_predictions(team, ax=None, title=None):
    # team: np.array([[5, 6, 7, 3]])
    # Warning: mutates `team`

    predictions = []

    for _ in range(100):
        rng.shuffle(team, axis=1)
        predictions.append(model.predict_proba(team).flatten())

    predictions = np.asarray(predictions).mean(axis=0)

    ax.bar(range(10), predictions)
    ax.set_title(title)
    ax.xaxis.set_major_locator(MaxNLocator(integer=True))

    return predictions

现在我们已经写了足够多的东西来了解模型在各种输入下的预测结果,我们在输入数据中观察到了[0, 1, 2, 3, 4],但是在给定的情况下,这个模型会预测什么呢?一米十五米
我们来看看:

fig, axs = plt.subplots(1, 7, sharey=True)

for i, ax in zip([3, 4, 5, 6, 7, 8, 9], axs):
    _ = make_predictions(np.array([[0, 1, 2, i]]), ax, title=f'[0, 1, 2, {i}, _]')

plt.show()

这让我们对问题不太确定的地方有了一些了解。[0, 1, 2, 4, _]的例子表明3有大约40%,9有大约55%。这也反映了在训练数据中,我们看到了两个:x1米19英寸1x和x1米20英寸1x。

这是一个好方法吗?

可能不会。这是假设我们有10个人,我们反复为他们组成5人小组。
最后一个例子也有助于说明这个问题中存在固有的不确定性,像Apriori answer中使用的方法这样的简单方法所需的工作量要少得多,更容易解释,并且可以根据需要使用启发式背景知识进行调整。

相关问题