Skip to content

Instantly share code, notes, and snippets.

@hiromu
Created December 24, 2013 17:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hiromu/8116146 to your computer and use it in GitHub Desktop.
Save hiromu/8116146 to your computer and use it in GitHub Desktop.
機械学習コンテスト用サンプルソース(協調フィルタリング)
#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;
}
#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