Created
December 24, 2013 17:46
-
-
Save hiromu/8116146 to your computer and use it in GitHub Desktop.
機械学習コンテスト用サンプルソース(協調フィルタリング)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <float.h> | |
#include <math.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#define TRAINDATA 1000 | |
#define TESTDATA 1000 | |
#define PARAMETER 10 | |
int traindata[TRAINDATA][PARAMETER], testdata[PARAMETER], rank[PARAMETER]; | |
float similarities[PARAMETER], sum[PARAMETER], score[PARAMETER]; | |
int sort(const void *a, const void *b) | |
{ | |
if(score[*(int *)a] < score[*(int *)b]) | |
return -1; | |
else if(score[*(int *)a] > score[*(int *)b]) | |
return 1; | |
else | |
return 0; | |
} | |
int main(void) | |
{ | |
int i, j, k; | |
float distance, similarity; | |
FILE *learn, *test; | |
// 学習データを読み込んで配列に保存 | |
learn = fopen("train.txt", "r"); | |
for(i = 0; i < TRAINDATA; i++) { | |
for(j = 0; j < PARAMETER; j++) { | |
if(j == 0) | |
fscanf(learn, "%d", &traindata[i][j]); | |
else | |
fscanf(learn, ",%d", &traindata[i][j]); | |
} | |
} | |
fclose(learn); | |
// テストデータを1行ごとに処理 | |
test = fopen("test.txt", "r"); | |
for(i = 0; i < TESTDATA; i++) { | |
// テストデータを読み込んで配列に保存 | |
for(j = 0; j < PARAMETER; j++) { | |
if(j == 0) | |
fscanf(test, "%d", &testdata[j]); | |
else | |
fscanf(test, ",%d", &testdata[j]); | |
} | |
// 学習データのそれぞれと処理を行う | |
for(j = 0; j < TRAINDATA; j++) { | |
// ユークリッド距離を求める | |
distance = 0; | |
for(k = 0; k < PARAMETER; k++) | |
if(testdata[k] != -1) | |
distance += pow(testdata[k] - traindata[j][k], 2); | |
distance = sqrt(distance); | |
// 類似度(ユークリッド距離の逆数)を求める | |
if(distance == 0) | |
continue; | |
similarity = 1 / (1 + distance); | |
// 相手の評価 * 類似度をスコアとして記録していく | |
for(k = 0; k < PARAMETER; k++) { | |
if(testdata[k] == -1) { | |
sum[k] += traindata[j][k] * similarity; | |
similarities[k] += similarity; | |
} | |
} | |
} | |
// スコアの総和を類似度の総和で割って正規化する | |
for(k = 0; k < PARAMETER; k++) { | |
if(testdata[k] == -1) | |
score[k] = sum[k] / similarities[k]; | |
else | |
score[k] = FLT_MAX; | |
} | |
// スコアが小さい順にソートする | |
for(j = 0; j < PARAMETER; j++) | |
rank[j] = j; | |
qsort(rank, PARAMETER, sizeof(int), sort); | |
// スコアが1番小さいものの番号を出力する | |
printf("%d\n", rank[0]); | |
} | |
fclose(test); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <float.h> | |
#include <math.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#define TRAINDATA 1000 | |
#define TESTDATA 1000 | |
#define PARAMETER 10 | |
int traindata[TRAINDATA][PARAMETER], testdata[PARAMETER], rank[PARAMETER]; | |
float similarities[PARAMETER], sum[PARAMETER], score[PARAMETER]; | |
int sort(const void *a, const void *b) | |
{ | |
if(score[*(int *)a] < score[*(int *)b]) | |
return -1; | |
else if(score[*(int *)a] > score[*(int *)b]) | |
return 1; | |
else | |
return 0; | |
} | |
float dot(int a[PARAMETER], int b[PARAMETER]) | |
{ | |
int i; | |
float sum = 0; | |
for(i = 0; i < PARAMETER; i++) | |
if(a[i] != -1 && b[i] != -1) | |
sum += a[i] * b[i]; | |
return sum; | |
} | |
int main(void) | |
{ | |
int i, j, k, count; | |
float distance, similarity; | |
FILE *learn, *test; | |
// 学習データを読み込んで配列に保存 | |
learn = fopen("train.txt", "r"); | |
for(i = 0; i < TRAINDATA; i++) { | |
for(j = 0; j < PARAMETER; j++) { | |
if(j == 0) | |
fscanf(learn, "%d", &traindata[i][j]); | |
else | |
fscanf(learn, ",%d", &traindata[i][j]); | |
} | |
} | |
fclose(learn); | |
// テストデータを1行ごとに処理 | |
test = fopen("test.txt", "r"); | |
for(i = 0; i < TESTDATA; i++) { | |
// テストデータを読み込んで配列に保存 | |
for(j = 0; j < PARAMETER; j++) { | |
if(j == 0) | |
fscanf(test, "%d", &testdata[j]); | |
else | |
fscanf(test, ",%d", &testdata[j]); | |
} | |
// 学習データのそれぞれと処理を行う | |
for(j = 0; j < TRAINDATA; j++) { | |
// Jaccard相関を求める | |
distance = dot(testdata, traindata[j]); | |
distance /= (dot(testdata, testdata) + dot(traindata[j], traindata[j]) - distance); | |
similarity = 1 / distance; | |
// 相手の評価 * 類似度をスコアとして記録していく | |
for(k = 0; k < PARAMETER; k++) { | |
if(testdata[k] == -1) { | |
sum[k] += traindata[j][k] * similarity; | |
similarities[k] += similarity; | |
} | |
} | |
} | |
// スコアの総和を類似度の総和で割って正規化する | |
for(k = 0; k < PARAMETER; k++) { | |
if(testdata[k] == -1) | |
score[k] = sum[k] / similarities[k]; | |
else | |
score[k] = FLT_MAX; | |
} | |
// スコアが小さい順にソートする | |
for(j = 0; j < PARAMETER; j++) | |
rank[j] = j; | |
qsort(rank, PARAMETER, sizeof(int), sort); | |
// スコアが1番小さいものの番号を出力する | |
printf("%d\n", rank[0]); | |
} | |
fclose(test); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment