GithubHelp home page GithubHelp logo

Bug in Class DataDAO about librec HOT 13 CLOSED

guoguibing avatar guoguibing commented on May 11, 2024
Bug in Class DataDAO

from librec.

Comments (13)

guoguibing avatar guoguibing commented on May 11, 2024

The reason why case this bug is that the columns number in trust.text is not start from 1,when the columns number start from 1 no bug found!

What does it mean? I didn't get you. In LibRec, the input ids will be mapped as the inner ids, so they are different.

from librec.

Jakye avatar Jakye commented on May 11, 2024

I know input ids will be mapped as the inner ids.If the input rating record is(1,1,5),the inner mapping record is (0,0,5).However what I got by method readData(int[] cols, double binThold) of class DataDAO was not mapping inner ids.
If there is just one trust record between users in the original trust.txt ,naming (1,2,1) meaning that user 1 trusts user 2,then according to the following codes
// inner id starting from 0
int row = userIds.containsKey(user) ? userIds.get(user) : userIds.size();
userIds.put(user, row);
int col = itemIds.containsKey(item) ? itemIds.get(item) : itemIds.size();
itemIds.put(item, col);
dataTable.put(row, col, rate);
colMap.put(col, row);
in method readData of Class DataDAO.
row =0, userIds(1,0) ,col=0,itemIds(2,0) ,dataTable(0,0,1),colMap(0,0)
The data is dataTable meaning the inner mapping trust record between user 1 and user 2 is 1 .
Actually ,the correct the inner mapping data in dataTable is (0,1,1) meaning the inner trust record between user 1 and user 2 is 1 ..
The following is my test example data in trust.txt
1 2 1
1 3 1
1 6 1
1 8 1
2 3 1
2 4 1
2 6 1
3 1 1
3 7 1
4 2 1
4 5 1
4 6 1
5 2 1
6 7 1
7 3 1
8 1 1
8 7 1
According to your original idea in method readData of Class DataDAO .The inner mapping trust relationships between users are :
0 1 1
0 2 1
0 5 1
0 7 1
1 2 1
1 3 1
1 5 1
2 0 1
2 6 1
3 1 1
3 4 1
3 5 1
4 1 1
5 6 1
6 2 1
7 0 1
7 6 1
But What I got are:
1 1 1.000000
1 2 1.000000
1 3 1.000000
1 4 1.000000
2 2 1.000000
2 3 1.000000
2 5 1.000000
3 6 1.000000
3 7 1.000000
4 1 1.000000
4 3 1.000000
4 8 1.000000
5 1 1.000000
6 7 1.000000
7 2 1.000000
8 6 1.000000
8 7 1.000000

from librec.

guoguibing avatar guoguibing commented on May 11, 2024

Did you figure out the issue?

from librec.

Jakye avatar Jakye commented on May 11, 2024

Not yet,I try to fix it!

from librec.

guoguibing avatar guoguibing commented on May 11, 2024

The issue is that the DataDAO does not know both rows and columns are users. By default, it will treat them separately. For this purpose, you need to load ratings first, so that you can build a userIds map first, and then use it as an argument to build a DataDAO object with the following constructor:

public DataDAO(String path, BiMap<String, Integer> userIds, BiMap<String, Integer> itemIds)

from librec.

guoguibing avatar guoguibing commented on May 11, 2024

You'd better read through the source code of SocialRecommender to figure it out.

from librec.

Jakye avatar Jakye commented on May 11, 2024

I create a test Class which calls the method readData(int[] cols, double binThold) of Class DataDAO to load trust values in social network.I loaded the trust information like rating information.User ids in row were treated as user id ,User ids in column were treated as item ids .I take another case as an example.
If there is just one rating record between user 1 and item 2 in the original rating.txt ,naming (1,2,3.5) meaning that the rating of user 1 for item 2 is 3.5,then according to the following codes
// inner id starting from 0
int row = userIds.containsKey(user) ? userIds.get(user) : userIds.size();
userIds.put(user, row);
int col = itemIds.containsKey(item) ? itemIds.get(item) : itemIds.size();
itemIds.put(item, col);
dataTable.put(row, col, rate);
colMap.put(col, row);
in method readData of Class DataDAO.
row =0, userIds(1,0) ,col=0,itemIds(2,0) ,dataTable(0,0,3.5),colMap(0,0)
The data is dataTable meaning the inner mapping rating record between user 1 and item 2 is 3.5 .
Actually ,the correct the inner mapping data in dataTable is (0,1,3.5) meaning the inner rating record between user 1 and item 2 is 3.5 .
dataTable(0,0,3.5) means the record between user 1 and item 1 is 3.5

from librec.

guoguibing avatar guoguibing commented on May 11, 2024

The input user id "1" is mapped to inner user id 0, while the input item id "2" is mapped to inner item id 0. The class works correctly. I didn't see why it should be (0,1, 3.5).

from librec.

guoguibing avatar guoguibing commented on May 11, 2024

You can use

String user = rateDao.getUserId(u);
String item = rateDao.getItemId(j);

to recover the original user or item ids.

from librec.

Jakye avatar Jakye commented on May 11, 2024

The method readData(int[] cols, double binThold) of Class DataDAO calls Constructor method of SparseMatrix
// build rating matrix
rateMatrix = new SparseMatrix(numRows, numCols, dataTable, colMap);
This constructor method actually calls the construct(Table<Integer, Integer, Double> dataTable, Multimap<Integer, Integer> columnStructure) method in Class SparseMatrix.

// set data
for (Cell<Integer, Integer, Double> en : dataTable.cellSet()) {
int row = en.getRowKey();
int col = en.getColumnKey();
double val = en.getValue();

        set(row, col, val);
    }

If the parameter of dataTable in method construct is(0,0,3.5) ,then set (0,0,3.5) meaning the record between user 1 and item 1 is 3.5

from librec.

guoguibing avatar guoguibing commented on May 11, 2024

This conversation is over.

from librec.

Jakye avatar Jakye commented on May 11, 2024

You will encounter this bug sooner or later !

from librec.

Jakye avatar Jakye commented on May 11, 2024

I think the code in readData(int[] cols, double binThold) of Class DataDAO should be the following
// inner id starting from 0
int row = userIds.containsKey(user) ? userIds.get(user) :(Integer.parseInt(user)-1);
userIds.put(user, row);
int col = itemIds.containsKey(item) ? itemIds.get(item) :(Integer.parseInt(item)-1);
itemIds.put(item, col);
instead of
// inner id starting from 0
int row = userIds.containsKey(user) ? userIds.get(user) : userIds.size();
userIds.put(user, row);

int col = itemIds.containsKey(item) ? itemIds.get(item) : itemIds.size();
itemIds.put(item, col);

from librec.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.