对元路径的理解:(本人做的是文本方向,所以就以评论者-评论数-评论者作为一条元路径啦)
元路径就是多个(大于2个)节点通过另一个类型的节点连接起来的路径,在yelp数据集中我想构建 评论—评论数量—评论 这条元路径。那就是找到相同评论数的评论,这些评论构成一个邻接矩阵。然后有不同的评论数,如142个评论数构成一个邻接矩阵,143个评论数构成一个邻接矩阵…这些小的邻接矩阵最后构成一个全节点的大邻接矩阵。最后这个矩阵就是元路径 评论—评论数量—评论 的矩阵了。
伪代码:
1.在数据集中将自己需要的两列数据摘取出来,我这里摘取了1000条数据作为练习。将评论数那一组进行排序。(后面做真正数据集的时候应该把对应的特征等也保存)
2. 读取数据成为二维数组(此处参考链接)
3.将二维数组的第一维元素变成0-1000对应的数组下标,得到narray
4.得到每次分组的结束位置,将其存入一个数组中,即遍历narray,如果第二列数的值相同,就用那些值构建邻接矩阵,每次存储在c矩阵中
5.创建一个邻接矩阵(最终维度)
通过c矩阵的下标中的元素构建邻接矩阵。
6. 将生成的邻接矩阵存储为xls文件。此处参考链接
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class getData {//读取excel指定sheet中的各行数据,存入二维数组,包括首行
public static String[][] getSheetData(XSSFSheet sheet) throws IOException {
String[][] testArray = new String[sheet.getPhysicalNumberOfRows()][];
for(int rowId =0;rowId<sheet.getPhysicalNumberOfRows();rowId++){
XSSFRow row = sheet.getRow(rowId);
List<String> testSetList = new ArrayList<String>();
for(int column=0;column<row.getPhysicalNumberOfCells();column++){
row.getCell(column).setCellType(Cell.CELL_TYPE_STRING);
testSetList.add(row.getCell(column).getStringCellValue());
}
testArray[rowId] = (String[])testSetList.
toArray(new String[testSetList.size()]);
}
return testArray;
}
//打印二维数组
public static void printDoubleArray(String[][] testArray) throws IOException{
//打印读进来的数据
for(int i =0; i<testArray.length;i++ )
{
for (int j=0; j<testArray[i].length;j++)
{
System.out.print(testArray[i][j]+" ");
}
System.out.println();
}
//创建一个二维数组,第一列的值变为0,1,2...999,第二列的值是之前原数组的值
String narray[][] = new String[testArray.length][testArray[0].length];
for(int k =0;k<testArray.length;k++){
narray[k][0]= String.valueOf(k);//第一列的值是0,1,2,
//第一列的值是0,1,2,
//第二列的值是原来数组的值
narray[k][1]=testArray[k][1];
}
//打印输出这个二维数组
for(int k =0; k<narray.length;k++ )
{
for (int j=0; j<narray[k].length;j++)
{
System.out.print(narray[k][j]+" \\ ");
}
System.out.println();
}
//创建一个邻接矩阵A
String A[][]=new String[testArray.length][testArray.length];
//遍历narray,如果第二列数的值相同,就用那些值构建邻接矩阵
int cont []= new int[10];//记录每次分组的结束位置
int k=0;
for(int l =0;l<cont.length;l++){
if(k<narray.length){
for(k =0; k<narray.length-1;k++){
if(narray[k][1]!=narray[k+1][1]) {
cont[l]=(k);
l++;
}}
}}
//输出cont数组
for(int m =0; m<cont.length;m++ )
{
System.out.println(cont[m]+" ...");
}
/* //记录第一个分组的位置
for(int k =0; k<narray.length-1;k++ )
{ count++;
if(narray[k][1]!=narray[k+1][1]) {
break;
}}
System.out.println(count+",,,");*/
// //找到评论数对应的第一列,构建一个数组c
// String c [] = new String[count];
// int i=0;
// for(int j=0;j< count;j++){
// c[i] = narray[j][0];
// i++;
// }
// //往邻接矩阵中填对应的值
// for(int k=0;k<c.length;k++){
// for(int m=0;m<c.length;m++){
// A[Integer.valueOf(c[k])][Integer.valueOf(c[m])]=String.valueOf(1);
// A[Integer.valueOf(c[m])][Integer.valueOf(c[k])]= String.valueOf(1);
// }
// }
输出此时的邻接矩阵
//
// for(int k =0; k<A.length;k++ )
// {
// for (int j=0; j<A[k].length;j++)
// {
// System.out.print(A[k][j]+" || ");
// }
// System.out.println();
// }
//找到评论数对应的第一列,构建一个数组c
int z=0;
while(cont[z]!=0){
String[] c=getData.buildc(cont,z,narray);
// String[] c = new String[cont[z]];
//
// int i=0;
// for(int j=0;j<c.length;j++){
// c[i] = narray[j][0];
// i++;
// }
// //输出c矩阵
// for(int j=0;j<c.length;j++){
// System.out.println(c[j]+" --");
// }
//往邻接矩阵中填对应的值
//此处也应该是循环中控制的是数组
for(int u=Integer.parseInt(c[0]);u<Integer.parseInt(c[c.length-1]);u++){
for (int m = Integer.parseInt(c[0]); m < Integer.parseInt(c[c.length - 1]); m++) {
A[u][m] = String.valueOf(1);
A[m][u] = String.valueOf(1);
}
}
z++;
}
输出此时的邻接矩阵
//
// for(int t =0; t<A.length;t++ )
// {
// for (int j=0; j<A[t].length;j++)
// {
// System.out.print(A[t][j]+" || ");
// }
// System.out.println();
// }
// 导出到 excel的代码
int rowNum = A.length;
int columnNum = A[0].length;
try {
FileWriter fw = new FileWriter("D:\\HomeWork\\webHomework\\getData\\MYDATA.xls");
for (int i = 0; i < rowNum; i++) {
for (int j = 0; j < columnNum; j++)
fw.write(A[i][j]+ "\t"); // tab 间隔
fw.write("\n"); // 换行
}
fw.close();
}
catch (IOException e){
e.printStackTrace();
}
}
public static String[] buildc(int[] cont, int z, String[][] narray) {
//z是数组下标
String c[];
if(z==0){
c = new String[cont[z]+1];
int i=0;
for(int j=0;j<c.length;j++){
c[i] = narray[j][0];
i++;
}}
else{
c = new String[cont[z]-cont[z-1]];
int i=0;
int j=cont[z-1]+1;
for(int k=0;k<c.length;k++){
//k用来控制循环次数是数组长度
c[i] = narray[j][0];
i++;
j++;
}
}
return c;
}
public static void main(String[] args) throws IOException {
// TODO 自动生成的方法存根
File file = new File("D:\\HomeWork\\webHomework\\getData\\1000data.xlsx");
FileInputStream fis = new FileInputStream(file);
@SuppressWarnings("resource")
XSSFWorkbook wb = new XSSFWorkbook(new BufferedInputStream(fis));
printDoubleArray(getSheetData(wb.getSheetAt(0)));
}
}
注释就不删除了,是我在编写代码时候的中间代码。
本人小白,有更好的方法可以在评论区留下足迹。
不足:
- 其实这是一个半成品,里面还有很多细节没有到位,例如第4步中生成的数组,将元素重复存储,是靠其中有0元素作为间隔才得以完成的。不过你构建的特征数量如果知道,问题也不大。
- 现在生成的矩阵在第一行和最后一行还存在问题,如0-298是一组,299-652是一组,但是在生成的矩阵中299行的位置没有值。这是因为矩阵的下标与平时习惯的行数不一致的原因。问题不大。
- 本次数据是先分组,再排序的,构建出来的邻接矩阵也就是一块一块的。到时候可以先排序,再分组。这样构建的矩阵就是比较稀疏的矩阵了。
- 构建出矩阵之后可以用matlab将其转为.mat文件
以上不足是我接下来要做的工作。到时候做出来会再贴代码的。
这是用idea的时候出现的一些问题,可参考我做的笔记:https://note.youdao.com/s/ZI2289I2