Pandas + scikit-learn K-means 无法正常工作 - 将所有数据帧行视为一个大的多维示例
Pandas + scikit-learn K-means not working properly - treats all of dataframe rows as one big multi-dimensional example
我目前正在尝试使用存储在我的 pandas.dataframe 中(实际上在其中一列中)的数据进行一些 k 均值聚类。奇怪的是,它没有将每一行视为一个单独的示例,而是威胁所有行作为一个示例,但维度非常高。例如:
df = pd.read_csv('D:\Apps\DataSciense\Kaggle Challenges\Titanic\Source Data\train.csv', header = 0)
median_ages = np.zeros((2,3))
for i in range(0,2):
for j in range (0,3):
median_ages[i, j] =df[(df.Gender == i) &(df.Pclass == j+1)].Age.dropna().median()
df['AgeFill'] = df['Age']
for i in range(0, 2):
for j in range(0,3):
df.loc[ (df.Age.isnull()) & (df.Gender == i) & (df.Pclass == j+1), 'AgeFill'] = median_ages[i, j]
然后我检查一下它看起来不错:
df.AgeFill
Name: AgeFill, Length: 891, dtype: float64
看起来不错,891 float64 数字。我做聚类:
k_means = cluster.KMeans(n_clusters=1, init='random')
k_means.fit(df.AgeFill)
然后我检查聚类中心:
k_means.cluster_centers_
它returns我一个巨大的阵列。
此外:
k_means.labels_
给我:
array([0])
我做错了什么?为什么它认为我有一个 891 维的示例,而不是 891 个示例?
为了更好地说明,如果我尝试 2 个集群:
k_means = cluster.KMeans(n_clusters=2, init='random')
k_means.fit(df.AgeFill)
回溯(最后一次调用):
文件“”,第 1 行,位于
k_means.fit(df.AgeFill)
文件 "D:\Apps\Python\lib\site-packages\sklearn\cluster\k_means_.py",第 724 行,适合
X = self._check_fit_data(X)
文件 "D:\Apps\Python\lib\site-packages\sklearn\cluster\k_means_.py",第 693 行,在 _check_fit_data 中
X.shape[0], self.n_clusters))
ValueError: n_samples=1 应该是 >= n_clusters=2
所以你可以看到它真的认为它只是一个巨大的样本。
但是:
df.AgeFill.shape
(891,)
您正在传递一个一维数组,而 scikit 需要一个带有 samples 和 features 轴的二维数组。应该这样做:
k_means.fit(df.AgeFill.reshape(-1, 1))
之前:
>>> df.AgeFill.shape
(891,)
之后:
>>> df.AgeFill.reshape(-1, 1).shape
(891, 1)
我目前正在尝试使用存储在我的 pandas.dataframe 中(实际上在其中一列中)的数据进行一些 k 均值聚类。奇怪的是,它没有将每一行视为一个单独的示例,而是威胁所有行作为一个示例,但维度非常高。例如:
df = pd.read_csv('D:\Apps\DataSciense\Kaggle Challenges\Titanic\Source Data\train.csv', header = 0)
median_ages = np.zeros((2,3))
for i in range(0,2):
for j in range (0,3):
median_ages[i, j] =df[(df.Gender == i) &(df.Pclass == j+1)].Age.dropna().median()
df['AgeFill'] = df['Age']
for i in range(0, 2):
for j in range(0,3):
df.loc[ (df.Age.isnull()) & (df.Gender == i) & (df.Pclass == j+1), 'AgeFill'] = median_ages[i, j]
然后我检查一下它看起来不错:
df.AgeFill
Name: AgeFill, Length: 891, dtype: float64
看起来不错,891 float64 数字。我做聚类:
k_means = cluster.KMeans(n_clusters=1, init='random')
k_means.fit(df.AgeFill)
然后我检查聚类中心:
k_means.cluster_centers_
它returns我一个巨大的阵列。
此外:
k_means.labels_
给我:
array([0])
我做错了什么?为什么它认为我有一个 891 维的示例,而不是 891 个示例?
为了更好地说明,如果我尝试 2 个集群:
k_means = cluster.KMeans(n_clusters=2, init='random')
k_means.fit(df.AgeFill)
回溯(最后一次调用): 文件“”,第 1 行,位于 k_means.fit(df.AgeFill) 文件 "D:\Apps\Python\lib\site-packages\sklearn\cluster\k_means_.py",第 724 行,适合 X = self._check_fit_data(X) 文件 "D:\Apps\Python\lib\site-packages\sklearn\cluster\k_means_.py",第 693 行,在 _check_fit_data 中 X.shape[0], self.n_clusters)) ValueError: n_samples=1 应该是 >= n_clusters=2
所以你可以看到它真的认为它只是一个巨大的样本。
但是:
df.AgeFill.shape
(891,)
您正在传递一个一维数组,而 scikit 需要一个带有 samples 和 features 轴的二维数组。应该这样做:
k_means.fit(df.AgeFill.reshape(-1, 1))
之前:
>>> df.AgeFill.shape
(891,)
之后:
>>> df.AgeFill.reshape(-1, 1).shape
(891, 1)