我正在尝试用Java为某个音乐推荐系统实现kmeans算法
我生成了两个数组,playsFinal[]
(数据集中所有用户对艺术家的总播放次数)和artFinal[]
(整个数据集中唯一的艺术家)。每个artFinal[i]
的播放次数为playsFinal[i]
。对于k,我选择了kclusters=Math.sqrt(playsFinal.length)/2
。
我有一个数组clusters[kclusters][playsFinal.length]
,每个0<i<kclusters
的第一个位置clusters[i][0]
都填充了一个特定的值,这基本上是kmeans算法中的初始平均值。
int j = 0;
for (int i = 0; i < n && j < kclusters; i += kclusters) {
clusters[j][0] = weighty[j];//initial means
System.out.println(clusters[j][0]);
j++;
}
这里,weight[]
是给每个艺术家的某个分数
现在,在下面的函数中,我返回索引,即plays[i]
应该添加到哪个集群。
public static int smallestdistance(double a, double[][] clusters) {
a = (double) a;
double smallest = 0;
double d[] = new double[kclusters];
for (int i = 0; i < kclusters; i++) {
d[i] = a - clusters[i][0];
}
int index = -1;
double d1 = Double.POSITIVE_INFINITY;
for (int i = 0; i < d.length; i++)
if (d[i] < d1) {
d1 = d[i];
index = i;
}
return index;
}
如果不明显,我将在每个clusters[j][0]
中找到playsFinal[i]
和初始元素之间的最小距离,并且是最小的,我将返回其索引(kfound)。现在,在clusters[kfound][]
的索引处,我想添加playsFinal[i]
,但这是我遇到的问题。我不能像在ArrayList中那样使用.add()
函数。我想使用ArrayList会更好。我浏览了ArrayList上的大多数文章,但没有发现任何对我有帮助的东西。
如何使用多维ArrayList实现这一点?提前谢谢。我的代码组合如下:
int j = 0;
for (int i = 0; i < n && j < kclusters; i += kclusters) {
clusters[j][0] = weighty[j];//initial means
System.out.println(clusters[j][0]);
j++;
}
double[] weighty = new double[artFinal.length];
for (int i = 0; i < artFinal.length; i++) {
weighty[i] = (playsFinal[i] * 10000 / playsFinal.length);
}
n = playsFinal.length;
kclusters = (int) (Math.sqrt(n) / 2);
double[][] clusters = new double[kclusters][playsFinal.length];
int j = 0;
for (int i = 0; i < n && j < kclusters; i += kclusters) {
clusters[j][0] = weighty[j];//initial means
System.out.println(clusters[j][0]);
j++;
}
int kfound;
for (int i = 0; i < playsFinal.length; i++) {
kfound = smallestdistance(playsFinal[i], clusters);
//HERE IS WHERE I AM STUCK. I want to add playsFinal[i] to the corresponding clusters[kfound][]
}
}
public static int smallestdistance(double a, double[][] clusters) {
a = (double) a;
double smallest = 0;
double d[] = new double[kclusters];
for (int i = 0; i < kclusters; i++) {
d[i] = a - clusters[i][0];
}
int index = -1;
double d1 = Double.POSITIVE_INFINITY;
for (int i = 0; i < d.length; i++)
if (d[i] < d1) {
d1 = d[i];
index = i;
}
return index;
}
Java的"多维数组"实际上只是数组,其元素本身就是(对)数组的引用。ArrayList等效于创建一个包含其他列表的列表:
List<List<Foo>> l = new ArrayList<>(); //create outer ArrayList
for (int i = 0; i < 10; i++) //create 10 inner ArrayLists
l.add(new ArrayList<Foo>());
l.get(5).add(foo1); //add an element to the sixth inner list
l.get(5).set(0, foo2); //set that element to a different value
与数组不同,列表是空的(与任何列表一样),而不是指定数量的插槽;如果您想将它们视为多维数组的插入式替换,则必须手动填充它们。这意味着你的内部列表可以有不同的长度。(实际上,只需指定外部维度(int[][] x = new int[10][];
),然后手动初始化槽(for (int i = 0; i < x.length; ++i) x[i] = new int[i];
表示"三角形"阵列),就可以获得"粗糙"的多维阵列,但多维阵列创建的特殊语法强烈倾向于大多数程序员只考虑"矩形"阵列。)